xref: /illumos-gate/usr/src/uts/common/io/usb/hcd/uhci/uhci.c (revision dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 
27 /*
28  * Universal Host Controller Driver (UHCI)
29  *
30  * The UHCI driver is a driver which interfaces to the Universal
31  * Serial Bus Architecture (USBA) and the Host Controller (HC). The interface to
32  * the Host Controller is defined by the Universal Host Controller Interface.
33  * This file contains code for auto-configuration entry points and interrupt
34  * handling.
35  */
36 #include <sys/usb/hcd/uhci/uhcid.h>
37 #include <sys/usb/hcd/uhci/uhcihub.h>
38 #include <sys/usb/hcd/uhci/uhciutil.h>
39 
40 /*
41  * Prototype Declarations for cb_ops and dev_ops
42  */
43 static	int uhci_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
44 static	int uhci_add_intrs(uhci_state_t *uhcip, int	intr_type);
45 static	int uhci_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
46 static void uhci_rem_intrs(uhci_state_t	*uhcip);
47 static	int uhci_open(dev_t *devp, int flags, int otyp, cred_t *credp);
48 static	int uhci_close(dev_t dev, int flag, int otyp, cred_t *credp);
49 static	int uhci_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
50 		cred_t *credp, int *rvalp);
51 static	int uhci_reset(dev_info_t *dip, ddi_reset_cmd_t cmd);
52 static	int uhci_quiesce(dev_info_t *dip);
53 static	int uhci_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
54 		void **result);
55 
56 /* extern */
57 int usba_hubdi_root_hub_power(dev_info_t *dip, int comp, int level);
58 
59 static struct cb_ops uhci_cb_ops = {
60 	uhci_open,			/* Open */
61 	uhci_close,			/* Close */
62 	nodev,				/* Strategy */
63 	nodev,				/* Print */
64 	nodev,				/* Dump */
65 	nodev,				/* Read */
66 	nodev,				/* Write */
67 	uhci_ioctl,			/* Ioctl */
68 	nodev,				/* Devmap */
69 	nodev,				/* Mmap */
70 	nodev,				/* Segmap */
71 	nochpoll,			/* Poll */
72 	ddi_prop_op,			/* cb_prop_op */
73 	NULL,				/* Streamtab */
74 	D_MP				/* Driver compatibility flag */
75 };
76 
77 static struct dev_ops uhci_ops = {
78 	DEVO_REV,			/* Devo_rev */
79 	0,				/* Refcnt */
80 	uhci_info,			/* Info */
81 	nulldev,			/* Identify */
82 	nulldev,			/* Probe */
83 	uhci_attach,			/* Attach */
84 	uhci_detach,			/* Detach */
85 	uhci_reset,			/* Reset */
86 	&uhci_cb_ops,			/* Driver operations */
87 	&usba_hubdi_busops,		/* Bus operations */
88 	usba_hubdi_root_hub_power,	/* Power */
89 	uhci_quiesce			/* quiesce */
90 };
91 
92 static struct modldrv modldrv = {
93 	&mod_driverops,		/* Type of module. This one is a driver */
94 	"USB UHCI Controller Driver",	/* Name of the module. */
95 	&uhci_ops,		/* Driver ops */
96 };
97 
98 static struct modlinkage modlinkage = {
99 	MODREV_1, (void *)&modldrv, NULL
100 };
101 
102 /*
103  *  Globals
104  */
105 void		*uhci_statep;
106 uint_t		uhci_errlevel = USB_LOG_L2;
107 uint_t		uhci_errmask = PRINT_MASK_ALL;
108 uint_t		uhci_instance_debug = (uint_t)-1;
109 
110 uint_t		uhci_td_pool_size = 256;			/* Num TDs */
111 uint_t		uhci_qh_pool_size = 130;			/* Num QHs */
112 ushort_t	uhci_tree_bottom_nodes[NUM_FRAME_LST_ENTRIES];
113 
114 
115 /*
116  * UHCI MSI tunable:
117  *
118  * By default MSI is enabled on all supported platforms.
119  */
120 boolean_t uhci_enable_msi = B_TRUE;
121 
122 /*
123  * tunable, delay during attach in seconds
124  */
125 int		uhci_attach_wait = 0;
126 
127 /* function prototypes */
128 static void	uhci_handle_intr_td_errors(uhci_state_t *uhcip, uhci_td_t *td,
129 			uhci_trans_wrapper_t *tw, uhci_pipe_private_t *pp);
130 static void	uhci_handle_one_xfer_completion(uhci_state_t *uhcip,
131 			usb_cr_t usb_err, uhci_td_t *td);
132 static uint_t	uhci_intr(caddr_t arg1, caddr_t arg2);
133 static int	uhci_cleanup(uhci_state_t *uhcip);
134 static int	uhci_cpr_suspend(uhci_state_t *uhcip);
135 static int	uhci_cpr_resume(uhci_state_t *uhcip);
136 
137 
138 int
139 _init(void)
140 {
141 	int error;
142 	ushort_t i, j, k, *temp, num_of_nodes;
143 
144 	/* Initialize the soft state structures */
145 	if ((error = ddi_soft_state_init(&uhci_statep, sizeof (uhci_state_t),
146 	    UHCI_MAX_INSTS)) != 0) {
147 
148 		return (error);
149 	}
150 
151 	/* Install the loadable module */
152 	if ((error = mod_install(&modlinkage)) != 0) {
153 		ddi_soft_state_fini(&uhci_statep);
154 
155 		return (error);
156 	}
157 
158 	/*
159 	 *  Build the tree bottom shared by all instances
160 	 */
161 	temp = kmem_zalloc(NUM_FRAME_LST_ENTRIES * 2, KM_SLEEP);
162 
163 	num_of_nodes = 1;
164 	for (i = 0; i < log_2(NUM_FRAME_LST_ENTRIES); i++) {
165 		for (j = 0, k = 0; k < num_of_nodes; k++, j++) {
166 			uhci_tree_bottom_nodes[j++] = temp[k];
167 			uhci_tree_bottom_nodes[j]   = temp[k] + pow_2(i);
168 		}
169 
170 		num_of_nodes *= 2;
171 		for (k = 0; k < num_of_nodes; k++)
172 			temp[k] = uhci_tree_bottom_nodes[k];
173 
174 	}
175 	kmem_free(temp, (NUM_FRAME_LST_ENTRIES*2));
176 
177 
178 	return (error);
179 }
180 
181 
182 int
183 _info(struct modinfo *modinfop)
184 {
185 	return (mod_info(&modlinkage, modinfop));
186 }
187 
188 
189 int
190 _fini(void)
191 {
192 	int error;
193 
194 	error = mod_remove(&modlinkage);
195 
196 	if (error == 0) {
197 		/* Release per module resources */
198 		ddi_soft_state_fini(&uhci_statep);
199 	}
200 
201 	return (error);
202 }
203 
204 /*
205  * The following simulated polling is for debugging purposes only.
206  * It is activated on x86 by setting usb-polling=true in GRUB or uhci.conf.
207  */
208 static int
209 uhci_is_polled(dev_info_t *dip)
210 {
211 	int ret;
212 	char *propval;
213 
214 	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, 0,
215 	    "usb-polling", &propval) != DDI_SUCCESS)
216 
217 		return (0);
218 
219 	ret = (strcmp(propval, "true") == 0);
220 	ddi_prop_free(propval);
221 
222 	return (ret);
223 }
224 
225 static void
226 uhci_poll_intr(void *arg)
227 {
228 	/* poll every msec */
229 	for (;;) {
230 		(void) uhci_intr(arg, NULL);
231 		delay(drv_usectohz(1000));
232 	}
233 }
234 
235 /*
236  * Host Controller Driver (HCD) Auto configuration entry points
237  */
238 
239 /*
240  * Function Name  :  uhci_attach:
241  * Description	  :  Attach entry point - called by the Kernel.
242  *		     Allocates of per controller data structure.
243  *		     Initializes the controller.
244  * Output	  :  DDI_SUCCESS / DDI_FAILURE
245  */
246 static int
247 uhci_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
248 {
249 	int				instance, polled;
250 	int				i, intr_types;
251 	uhci_state_t			*uhcip = NULL;
252 	usba_hcdi_register_args_t	hcdi_args;
253 
254 	USB_DPRINTF_L4(PRINT_MASK_ATTA, NULL, "uhci_attach:");
255 
256 	switch (cmd) {
257 	case DDI_ATTACH:
258 		break;
259 	case DDI_RESUME:
260 		uhcip = uhci_obtain_state(dip);
261 
262 		return (uhci_cpr_resume(uhcip));
263 	default:
264 
265 		return (DDI_FAILURE);
266 	}
267 
268 	/* Get the instance and create soft state */
269 	instance = ddi_get_instance(dip);
270 
271 	/* Allocate the soft state structure for this instance of the driver */
272 	if (ddi_soft_state_zalloc(uhci_statep, instance) != 0) {
273 
274 		return (DDI_FAILURE);
275 	}
276 
277 	if ((uhcip = ddi_get_soft_state(uhci_statep, instance)) == NULL) {
278 
279 		return (DDI_FAILURE);
280 	}
281 
282 	uhcip->uhci_log_hdl = usb_alloc_log_hdl(dip, "uhci", &uhci_errlevel,
283 	    &uhci_errmask, &uhci_instance_debug, 0);
284 
285 	/* Set host controller soft state to initialization */
286 	uhcip->uhci_hc_soft_state = UHCI_CTLR_INIT_STATE;
287 
288 	/* Save the dip and instance */
289 	uhcip->uhci_dip		= dip;
290 	uhcip->uhci_instance	= instance;
291 
292 	polled = uhci_is_polled(dip);
293 	if (polled)
294 
295 		goto skip_intr;
296 
297 	/* Get supported interrupt types */
298 	if (ddi_intr_get_supported_types(uhcip->uhci_dip,
299 	    &intr_types) != DDI_SUCCESS) {
300 		USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl,
301 		    "uhci_attach: ddi_intr_get_supported_types failed");
302 
303 		usb_free_log_hdl(uhcip->uhci_log_hdl);
304 		ddi_soft_state_free(uhci_statep, instance);
305 
306 		return (DDI_FAILURE);
307 	}
308 
309 	USB_DPRINTF_L3(PRINT_MASK_ATTA, uhcip->uhci_log_hdl,
310 	    "uhci_attach: supported interrupt types 0x%x", intr_types);
311 
312 	if ((intr_types & DDI_INTR_TYPE_MSI) && uhci_enable_msi) {
313 		if (uhci_add_intrs(uhcip, DDI_INTR_TYPE_MSI)
314 		    != DDI_SUCCESS) {
315 			USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl,
316 			    "uhci_attach: MSI registration failed, "
317 			    "trying FIXED interrupt \n");
318 		} else {
319 			USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl,
320 			    "uhci_attach: Using MSI interrupt type\n");
321 
322 			uhcip->uhci_intr_type = DDI_INTR_TYPE_MSI;
323 		}
324 	}
325 
326 	if (!(uhcip->uhci_htable) && (intr_types & DDI_INTR_TYPE_FIXED)) {
327 		if (uhci_add_intrs(uhcip, DDI_INTR_TYPE_FIXED)
328 		    != DDI_SUCCESS) {
329 			USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl,
330 			    "uhci_attach: FIXED interrupt registration "
331 			    "failed\n");
332 
333 			usb_free_log_hdl(uhcip->uhci_log_hdl);
334 			ddi_soft_state_free(uhci_statep, instance);
335 
336 			return (DDI_FAILURE);
337 		}
338 
339 		USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl,
340 		    "uhci_attach: Using FIXED interrupt type\n");
341 
342 		uhcip->uhci_intr_type = DDI_INTR_TYPE_FIXED;
343 	}
344 
345 skip_intr:
346 	/* Semaphore to serialize opens and closes */
347 	sema_init(&uhcip->uhci_ocsem, 1, NULL, SEMA_DRIVER, NULL);
348 
349 	/* Create prototype condition variable */
350 	cv_init(&uhcip->uhci_cv_SOF, NULL, CV_DRIVER, NULL);
351 
352 	/* Initialize the DMA attributes */
353 	uhci_set_dma_attributes(uhcip);
354 
355 	/* Initialize the kstat structures */
356 	uhci_create_stats(uhcip);
357 
358 	/* Create the td and ed pools */
359 	if (uhci_allocate_pools(uhcip) != USB_SUCCESS) {
360 
361 		goto fail;
362 	}
363 
364 	/* Map the registers */
365 	if (uhci_map_regs(uhcip) != USB_SUCCESS) {
366 
367 		goto fail;
368 	}
369 
370 	/* Enable all interrupts */
371 	if (polled) {
372 		extern pri_t maxclsyspri;
373 
374 		USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl,
375 		    "uhci_attach: running in simulated polled mode.");
376 
377 		/* create thread to poll */
378 		(void) thread_create(NULL, 0, uhci_poll_intr, uhcip, 0, &p0,
379 		    TS_RUN, maxclsyspri);
380 	} else if (uhcip->uhci_intr_cap & DDI_INTR_FLAG_BLOCK) {
381 		/* Call ddi_intr_block_enable() for MSI interrupts */
382 		(void) ddi_intr_block_enable(uhcip->uhci_htable,
383 		    uhcip->uhci_intr_cnt);
384 	} else {
385 		/* Call ddi_intr_enable for MSI or FIXED interrupts */
386 		for (i = 0; i < uhcip->uhci_intr_cnt; i++)
387 			(void) ddi_intr_enable(uhcip->uhci_htable[i]);
388 	}
389 
390 
391 	/* Initialize the controller */
392 	if (uhci_init_ctlr(uhcip) != USB_SUCCESS) {
393 
394 		goto fail;
395 	}
396 
397 	/*
398 	 * At this point, the hardware will be okay.
399 	 * Initialize the usba_hcdi structure
400 	 */
401 	uhcip->uhci_hcdi_ops = uhci_alloc_hcdi_ops(uhcip);
402 
403 	/*
404 	 * Make this HCD instance known to USBA
405 	 * (dma_attr must be passed for USBA busctl's)
406 	 */
407 	hcdi_args.usba_hcdi_register_version = HCDI_REGISTER_VERSION;
408 	hcdi_args.usba_hcdi_register_dip = dip;
409 	hcdi_args.usba_hcdi_register_ops = uhcip->uhci_hcdi_ops;
410 	hcdi_args.usba_hcdi_register_dma_attr = &uhcip->uhci_dma_attr;
411 	hcdi_args.usba_hcdi_register_iblock_cookie =
412 	    (ddi_iblock_cookie_t)(uintptr_t)uhcip->uhci_intr_pri;
413 
414 	if (usba_hcdi_register(&hcdi_args, 0) != USB_SUCCESS) {
415 
416 		goto fail;
417 	}
418 
419 #ifndef __sparc
420 	/*
421 	 * On NCR system,  the driver seen  failure of some commands
422 	 * while booting. This delay mysteriously solved the problem.
423 	 */
424 	delay(drv_usectohz(uhci_attach_wait*1000000));
425 #endif
426 
427 	/*
428 	 * Create another timeout handler to check whether any
429 	 * control/bulk/interrupt commands failed.
430 	 * This gets called every second.
431 	 */
432 	uhcip->uhci_cmd_timeout_id = timeout(uhci_cmd_timeout_hdlr,
433 	    (void *)uhcip, UHCI_ONE_SECOND);
434 
435 	mutex_enter(&uhcip->uhci_int_mutex);
436 
437 	/*
438 	 * Set HcInterruptEnable to enable all interrupts except Root
439 	 * Hub Status change and SOF interrupts.
440 	 */
441 	Set_OpReg16(USBINTR, ENABLE_ALL_INTRS);
442 
443 	/* Test the SOF interrupt */
444 	if (uhci_wait_for_sof(uhcip) != USB_SUCCESS) {
445 		USB_DPRINTF_L0(PRINT_MASK_ATTA, uhcip->uhci_log_hdl,
446 		    "No SOF interrupts have been received, this USB UHCI host"
447 		    " controller is unusable");
448 		mutex_exit(&uhcip->uhci_int_mutex);
449 
450 		goto fail;
451 	}
452 
453 	mutex_exit(&uhcip->uhci_int_mutex);
454 
455 	/* This should be the last step which might fail during attaching */
456 	if (uhci_init_root_hub(uhcip) != USB_SUCCESS) {
457 
458 		goto fail;
459 	}
460 
461 	/* Display information in the banner */
462 	ddi_report_dev(dip);
463 
464 	USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl,
465 	    "uhci_attach successful");
466 
467 	return (DDI_SUCCESS);
468 
469 fail:
470 	USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl,
471 	    "failed to attach");
472 
473 	(void) uhci_cleanup(uhcip);
474 
475 	return (DDI_FAILURE);
476 }
477 
478 
479 /*
480  * uhci_add_intrs:
481  *
482  * Register FIXED or MSI interrupts.
483  */
484 static int
485 uhci_add_intrs(uhci_state_t	*uhcip,
486 		int		intr_type)
487 {
488 	int	actual, avail, intr_size, count = 0;
489 	int	i, flag, ret;
490 
491 	USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl,
492 	    "uhci_add_intrs: interrupt type 0x%x", intr_type);
493 
494 	/* Get number of interrupts */
495 	ret = ddi_intr_get_nintrs(uhcip->uhci_dip, intr_type, &count);
496 	if ((ret != DDI_SUCCESS) || (count == 0)) {
497 		USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl,
498 		    "uhci_add_intrs: ddi_intr_get_nintrs() failure, "
499 		    "ret: %d, count: %d", ret, count);
500 
501 		return (DDI_FAILURE);
502 	}
503 
504 	/* Get number of available interrupts */
505 	ret = ddi_intr_get_navail(uhcip->uhci_dip, intr_type, &avail);
506 	if ((ret != DDI_SUCCESS) || (avail == 0)) {
507 		USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl,
508 		    "uhci_add_intrs: ddi_intr_get_navail() failure, "
509 		    "ret: %d, count: %d", ret, count);
510 
511 		return (DDI_FAILURE);
512 	}
513 
514 	if (avail < count) {
515 		USB_DPRINTF_L3(PRINT_MASK_ATTA, uhcip->uhci_log_hdl,
516 		    "uhci_add_intrs: uhci_add_intrs: nintrs () "
517 		    "returned %d, navail returned %d\n", count, avail);
518 	}
519 
520 	/* Allocate an array of interrupt handles */
521 	intr_size = count * sizeof (ddi_intr_handle_t);
522 	uhcip->uhci_htable = kmem_zalloc(intr_size, KM_SLEEP);
523 
524 	flag = (intr_type == DDI_INTR_TYPE_MSI) ?
525 	    DDI_INTR_ALLOC_STRICT:DDI_INTR_ALLOC_NORMAL;
526 
527 	/* call ddi_intr_alloc() */
528 	ret = ddi_intr_alloc(uhcip->uhci_dip, uhcip->uhci_htable,
529 	    intr_type, 0, count, &actual, flag);
530 
531 	if ((ret != DDI_SUCCESS) || (actual == 0)) {
532 		USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl,
533 		    "uhci_add_intrs: ddi_intr_alloc() failed %d", ret);
534 
535 		kmem_free(uhcip->uhci_htable, intr_size);
536 
537 		return (DDI_FAILURE);
538 	}
539 
540 	if (actual < count) {
541 		USB_DPRINTF_L3(PRINT_MASK_ATTA, uhcip->uhci_log_hdl,
542 		    "uhci_add_intrs: Requested: %d, Received: %d\n",
543 		    count, actual);
544 
545 		for (i = 0; i < actual; i++)
546 			(void) ddi_intr_free(uhcip->uhci_htable[i]);
547 
548 		kmem_free(uhcip->uhci_htable, intr_size);
549 
550 		return (DDI_FAILURE);
551 	}
552 
553 	uhcip->uhci_intr_cnt = actual;
554 
555 	if ((ret = ddi_intr_get_pri(uhcip->uhci_htable[0],
556 	    &uhcip->uhci_intr_pri)) != DDI_SUCCESS) {
557 		USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl,
558 		    "uhci_add_intrs: ddi_intr_get_pri() failed %d", ret);
559 
560 		for (i = 0; i < actual; i++)
561 			(void) ddi_intr_free(uhcip->uhci_htable[i]);
562 
563 		kmem_free(uhcip->uhci_htable, intr_size);
564 
565 		return (DDI_FAILURE);
566 	}
567 
568 	USB_DPRINTF_L3(PRINT_MASK_ATTA, uhcip->uhci_log_hdl,
569 	    "uhci_add_intrs: Supported Interrupt priority 0x%x",
570 	    uhcip->uhci_intr_pri);
571 
572 	/* Test for high level mutex */
573 	if (uhcip->uhci_intr_pri >= ddi_intr_get_hilevel_pri()) {
574 		USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl,
575 		    "uhci_add_intrs: Hi level interrupt not supported");
576 
577 		for (i = 0; i < actual; i++)
578 			(void) ddi_intr_free(uhcip->uhci_htable[i]);
579 
580 		kmem_free(uhcip->uhci_htable, intr_size);
581 
582 		return (DDI_FAILURE);
583 	}
584 
585 	/* Initialize the mutex */
586 	mutex_init(&uhcip->uhci_int_mutex, NULL, MUTEX_DRIVER,
587 	    DDI_INTR_PRI(uhcip->uhci_intr_pri));
588 
589 	/* Call ddi_intr_add_handler() */
590 	for (i = 0; i < actual; i++) {
591 		if ((ret = ddi_intr_add_handler(uhcip->uhci_htable[i],
592 		    uhci_intr, (caddr_t)uhcip,
593 		    (caddr_t)(uintptr_t)i)) != DDI_SUCCESS) {
594 			USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl,
595 			    "uhci_add_intrs: ddi_intr_add_handler() "
596 			    "failed %d", ret);
597 
598 			for (i = 0; i < actual; i++)
599 				(void) ddi_intr_free(uhcip->uhci_htable[i]);
600 
601 			mutex_destroy(&uhcip->uhci_int_mutex);
602 			kmem_free(uhcip->uhci_htable, intr_size);
603 
604 			return (DDI_FAILURE);
605 		}
606 	}
607 
608 	if ((ret = ddi_intr_get_cap(uhcip->uhci_htable[0],
609 	    &uhcip->uhci_intr_cap)) != DDI_SUCCESS) {
610 		USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl,
611 		    "uhci_add_intrs: ddi_intr_get_cap() failed %d", ret);
612 
613 		for (i = 0; i < actual; i++) {
614 			(void) ddi_intr_remove_handler(uhcip->uhci_htable[i]);
615 			(void) ddi_intr_free(uhcip->uhci_htable[i]);
616 		}
617 
618 		mutex_destroy(&uhcip->uhci_int_mutex);
619 		kmem_free(uhcip->uhci_htable, intr_size);
620 
621 		return (DDI_FAILURE);
622 	}
623 
624 	return (DDI_SUCCESS);
625 }
626 
627 
628 /*
629  * Function Name:	uhci_detach
630  * Description:		Detach entry point - called by the Kernel.
631  *			Deallocates all the memory
632  *			Unregisters the interrupt handle and other resources.
633  * Output:		DDI_SUCCESS / DDI_FAILURE
634  */
635 static int
636 uhci_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
637 {
638 	uhci_state_t	*uhcip = uhci_obtain_state(dip);
639 
640 	USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl,
641 	    "uhci_detach:");
642 
643 	switch (cmd) {
644 	case DDI_DETACH:
645 
646 		return (uhci_cleanup(uhcip) == USB_SUCCESS ?
647 		    DDI_SUCCESS : DDI_FAILURE);
648 	case DDI_SUSPEND:
649 
650 		return (uhci_cpr_suspend(uhcip));
651 	default:
652 
653 		return (DDI_FAILURE);
654 	}
655 }
656 
657 
658 /*
659  * uhci_rem_intrs:
660  *
661  * Unregister FIXED or MSI interrupts
662  */
663 static void
664 uhci_rem_intrs(uhci_state_t	*uhcip)
665 {
666 	int	i;
667 
668 	USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl,
669 	    "uhci_rem_intrs: interrupt type 0x%x", uhcip->uhci_intr_type);
670 
671 	/* Disable all interrupts */
672 	if (uhcip->uhci_intr_cap & DDI_INTR_FLAG_BLOCK) {
673 		(void) ddi_intr_block_disable(uhcip->uhci_htable,
674 		    uhcip->uhci_intr_cnt);
675 	} else {
676 		for (i = 0; i < uhcip->uhci_intr_cnt; i++) {
677 			(void) ddi_intr_disable(uhcip->uhci_htable[i]);
678 		}
679 	}
680 
681 	/* Call ddi_intr_remove_handler() */
682 	for (i = 0; i < uhcip->uhci_intr_cnt; i++) {
683 		(void) ddi_intr_remove_handler(uhcip->uhci_htable[i]);
684 		(void) ddi_intr_free(uhcip->uhci_htable[i]);
685 	}
686 
687 	kmem_free(uhcip->uhci_htable,
688 	    uhcip->uhci_intr_cnt * sizeof (ddi_intr_handle_t));
689 }
690 
691 
692 /*
693  * Function Name:	uhci_reset
694  * Description:		Reset entry point - called by the Kernel
695  *			on the way down.
696  *			The Toshiba laptop has been observed to	hang
697  *			on reboot when BIOS is set to suspend/resume.
698  *			The resetting uhci on the way down solves the
699  *			problem.
700  * Output:		DDI_SUCCESS / DDI_FAILURE
701  */
702 /* ARGSUSED */
703 static int
704 uhci_reset(dev_info_t *dip, ddi_reset_cmd_t cmd)
705 {
706 	uhci_state_t	*uhcip = uhci_obtain_state(dip);
707 
708 	/* Disable all HC ED list processing */
709 	Set_OpReg16(USBINTR, DISABLE_ALL_INTRS);
710 	Set_OpReg16(USBCMD, 0);
711 
712 	return (DDI_SUCCESS);
713 }
714 
715 /*
716  * quiesce(9E) entry point.
717  *
718  * This function is called when the system is single-threaded at high
719  * PIL with preemption disabled. Therefore, this function must not be
720  * blocked.
721  *
722  * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
723  * DDI_FAILURE indicates an error condition and should almost never happen.
724  */
725 static int
726 uhci_quiesce(dev_info_t *dip)
727 {
728 	uhci_state_t	*uhcip = uhci_obtain_state(dip);
729 
730 	if (uhcip == NULL)
731 		return (DDI_FAILURE);
732 
733 	/* Disable interrupts */
734 	Set_OpReg16(USBINTR, DISABLE_ALL_INTRS);
735 
736 	/* Stop the Host Controller */
737 	Set_OpReg16(USBCMD, 0);
738 
739 	/* Clear all status bits */
740 	Set_OpReg16(USBSTS, Get_OpReg16(USBSTS) & UHCI_INTR_MASK);
741 
742 	return (DDI_SUCCESS);
743 }
744 
745 
746 /*
747  * uhci_info:
748  */
749 /* ARGSUSED */
750 static int
751 uhci_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
752 {
753 	dev_t		dev;
754 	int		instance;
755 	int		error = DDI_FAILURE;
756 	uhci_state_t	*uhcip;
757 
758 	switch (infocmd) {
759 	case DDI_INFO_DEVT2DEVINFO:
760 		dev = (dev_t)arg;
761 		instance = UHCI_UNIT(dev);
762 		uhcip = ddi_get_soft_state(uhci_statep, instance);
763 		if (uhcip != NULL) {
764 			*result = (void *)uhcip->uhci_dip;
765 			if (*result != NULL) {
766 				error = DDI_SUCCESS;
767 			}
768 		} else {
769 			*result = NULL;
770 		}
771 
772 		break;
773 	case DDI_INFO_DEVT2INSTANCE:
774 		dev = (dev_t)arg;
775 		instance = UHCI_UNIT(dev);
776 		*result = (void *)(uintptr_t)instance;
777 		error = DDI_SUCCESS;
778 
779 		break;
780 	default:
781 		break;
782 	}
783 
784 	return (error);
785 }
786 
787 
788 /*
789  * uhci_cleanup:
790  *	Cleanup on attach failure or detach
791  */
792 static int
793 uhci_cleanup(uhci_state_t *uhcip)
794 {
795 	USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, "uhci_cleanup:");
796 
797 	if (usba_hubdi_unbind_root_hub(uhcip->uhci_dip) != USB_SUCCESS) {
798 
799 		return (USB_FAILURE);
800 	}
801 
802 	mutex_enter(&uhcip->uhci_int_mutex);
803 
804 	if (uhcip->uhci_cmd_timeout_id) {
805 		timeout_id_t timeout_id = uhcip->uhci_cmd_timeout_id;
806 		uhcip->uhci_cmd_timeout_id = 0;
807 		mutex_exit(&uhcip->uhci_int_mutex);
808 		(void) untimeout(timeout_id);
809 		mutex_enter(&uhcip->uhci_int_mutex);
810 	}
811 
812 	uhci_uninit_ctlr(uhcip);
813 
814 	mutex_exit(&uhcip->uhci_int_mutex);
815 
816 	/* do interrupt cleanup */
817 	if (uhcip->uhci_htable) {
818 		uhci_rem_intrs(uhcip);
819 	}
820 
821 	mutex_enter(&uhcip->uhci_int_mutex);
822 
823 	usba_hcdi_unregister(uhcip->uhci_dip);
824 
825 	uhci_unmap_regs(uhcip);
826 
827 	uhci_free_pools(uhcip);
828 
829 	mutex_exit(&uhcip->uhci_int_mutex);
830 
831 	mutex_destroy(&uhcip->uhci_int_mutex);
832 	cv_destroy(&uhcip->uhci_cv_SOF);
833 	sema_destroy(&uhcip->uhci_ocsem);
834 
835 	/* cleanup kstat structures */
836 	uhci_destroy_stats(uhcip);
837 
838 	usba_free_hcdi_ops(uhcip->uhci_hcdi_ops);
839 	usb_free_log_hdl(uhcip->uhci_log_hdl);
840 	ddi_prop_remove_all(uhcip->uhci_dip);
841 	ddi_soft_state_free(uhci_statep, uhcip->uhci_instance);
842 
843 	return (USB_SUCCESS);
844 }
845 
846 
847 /*
848  * uhci_cpr_suspend
849  */
850 static int
851 uhci_cpr_suspend(uhci_state_t	*uhcip)
852 {
853 	uint16_t	cmd_reg;
854 	int		i;
855 
856 	USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl,
857 	    "uhci_cpr_suspend:");
858 
859 	/* Call into the root hub and suspend it */
860 	if (usba_hubdi_detach(uhcip->uhci_dip, DDI_SUSPEND) != DDI_SUCCESS) {
861 
862 		return (DDI_FAILURE);
863 	}
864 
865 	mutex_enter(&uhcip->uhci_int_mutex);
866 
867 	/* Stop the Host Controller */
868 	cmd_reg = Get_OpReg16(USBCMD);
869 	cmd_reg &= ~USBCMD_REG_HC_RUN;
870 	Set_OpReg16(USBCMD, cmd_reg);
871 
872 	/*
873 	 * Wait for the duration of an SOF period until the host controller
874 	 * reaches the stopped state, indicated by the HCHalted bit in the
875 	 * USB status register.
876 	 */
877 	for (i = 0; i <= UHCI_TIMEWAIT / 1000; i++) {
878 		if (Get_OpReg16(USBSTS) & USBSTS_REG_HC_HALTED)
879 			break;
880 		drv_usecwait(1000);
881 	}
882 
883 	USB_DPRINTF_L3(PRINT_MASK_ATTA, uhcip->uhci_log_hdl,
884 	    "uhci_cpr_suspend: waited %d milliseconds for hc to halt", i);
885 
886 	/* Disable interrupts */
887 	Set_OpReg16(USBINTR, DISABLE_ALL_INTRS);
888 
889 	/* Clear any scheduled pending interrupts */
890 	Set_OpReg16(USBSTS, USBSTS_REG_HC_HALTED |
891 	    USBSTS_REG_HC_PROCESS_ERR | USBSTS_REG_HOST_SYS_ERR |
892 	    USBSTS_REG_RESUME_DETECT | USBSTS_REG_USB_ERR_INTR |
893 	    USBSTS_REG_USB_INTR);
894 
895 	/* Set Global Suspend bit */
896 	Set_OpReg16(USBCMD, USBCMD_REG_ENTER_GBL_SUSPEND);
897 
898 	/* Set host controller soft state to suspend */
899 	uhcip->uhci_hc_soft_state = UHCI_CTLR_SUSPEND_STATE;
900 
901 	/* Reset the host controller. This can poweroff downstream ports */
902 	Set_OpReg16(USBCMD, USBCMD_REG_GBL_RESET);
903 
904 	/* Wait 10ms for reset to complete */
905 	mutex_exit(&uhcip->uhci_int_mutex);
906 	delay(drv_usectohz(UHCI_RESET_DELAY));
907 	mutex_enter(&uhcip->uhci_int_mutex);
908 
909 	Set_OpReg16(USBCMD, 0);
910 
911 	mutex_exit(&uhcip->uhci_int_mutex);
912 
913 	return (USB_SUCCESS);
914 }
915 
916 
917 /*
918  * uhci_cpr_cleanup:
919  *
920  * Cleanup uhci specific information across resuming.
921  */
922 static void
923 uhci_cpr_cleanup(uhci_state_t	*uhcip)
924 {
925 	ASSERT(mutex_owned(&uhcip->uhci_int_mutex));
926 
927 	/* Reset software part of usb frame number */
928 	uhcip->uhci_sw_frnum = 0;
929 }
930 
931 
932 /*
933  * uhci_cpr_resume
934  */
935 static int
936 uhci_cpr_resume(uhci_state_t	*uhcip)
937 {
938 	USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl,
939 	    "uhci_cpr_resume: Restart the controller");
940 
941 	mutex_enter(&uhcip->uhci_int_mutex);
942 
943 	/* Cleanup uhci specific information across cpr */
944 	uhci_cpr_cleanup(uhcip);
945 
946 	mutex_exit(&uhcip->uhci_int_mutex);
947 
948 	/* Restart the controller */
949 	if (uhci_init_ctlr(uhcip) != DDI_SUCCESS) {
950 
951 		USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl,
952 		    "uhci_cpr_resume: uhci host controller resume failed ");
953 
954 		return (DDI_FAILURE);
955 	}
956 
957 	mutex_enter(&uhcip->uhci_int_mutex);
958 
959 	/*
960 	 * Set HcInterruptEnable to enable all interrupts except Root
961 	 * Hub Status change and SOF interrupts.
962 	 */
963 	Set_OpReg16(USBINTR, ENABLE_ALL_INTRS);
964 
965 	mutex_exit(&uhcip->uhci_int_mutex);
966 
967 	/* Now resume the root hub */
968 	if (usba_hubdi_attach(uhcip->uhci_dip, DDI_RESUME) != DDI_SUCCESS) {
969 
970 		return (DDI_FAILURE);
971 	}
972 
973 	return (DDI_SUCCESS);
974 }
975 
976 
977 /*
978  * uhci_intr:
979  *	uhci interrupt handling routine.
980  */
981 static uint_t
982 uhci_intr(caddr_t arg1, caddr_t arg2)
983 {
984 	ushort_t	intr_status, cmd_reg, intr_reg;
985 	uhci_state_t	*uhcip = (uhci_state_t *)arg1;
986 
987 	USB_DPRINTF_L4(PRINT_MASK_INTR, uhcip->uhci_log_hdl,
988 	    "uhci_intr: Interrupt occurred, arg1 0x%p arg2 0x%p",
989 	    (void *)arg1, (void *)arg2);
990 
991 	mutex_enter(&uhcip->uhci_int_mutex);
992 
993 	/* Any interrupt is not handled for the suspended device. */
994 	if (uhcip->uhci_hc_soft_state == UHCI_CTLR_SUSPEND_STATE) {
995 		mutex_exit(&uhcip->uhci_int_mutex);
996 
997 		return (DDI_INTR_UNCLAIMED);
998 	}
999 
1000 	/* Get the status of the interrupts */
1001 	intr_status = Get_OpReg16(USBSTS);
1002 	intr_reg = Get_OpReg16(USBINTR);
1003 
1004 	USB_DPRINTF_L3(PRINT_MASK_INTR, uhcip->uhci_log_hdl,
1005 	    "uhci_intr: intr_status = %x, intr_reg = %x",
1006 	    intr_status, intr_reg);
1007 
1008 	/*
1009 	 * If uhci interrupts are all disabled, the driver should return
1010 	 * unclaimed.
1011 	 * HC Process Error and Host System Error interrupts cannot be
1012 	 * disabled by intr register, and need to be judged separately.
1013 	 */
1014 	if (((intr_reg & ENABLE_ALL_INTRS) == 0) &&
1015 	    ((intr_status & USBSTS_REG_HC_PROCESS_ERR) == 0) &&
1016 	    ((intr_status & USBSTS_REG_HOST_SYS_ERR) == 0)) {
1017 
1018 		USB_DPRINTF_L3(PRINT_MASK_INTR, uhcip->uhci_log_hdl,
1019 		    "uhci_intr: interrupts disabled, unclaim");
1020 		mutex_exit(&uhcip->uhci_int_mutex);
1021 
1022 		return (DDI_INTR_UNCLAIMED);
1023 	}
1024 
1025 	/*
1026 	 * If the intr is not from our controller, just return unclaimed.
1027 	 * HCHalted status bit cannot generate interrupts and should be
1028 	 * ignored.
1029 	 */
1030 	if (!(intr_status & UHCI_INTR_MASK)) {
1031 
1032 		USB_DPRINTF_L3(PRINT_MASK_INTR, uhcip->uhci_log_hdl,
1033 		    "uhci_intr: no interrupt status set, unclaim");
1034 		mutex_exit(&uhcip->uhci_int_mutex);
1035 
1036 		return (DDI_INTR_UNCLAIMED);
1037 	}
1038 
1039 	/* Update kstat values */
1040 	uhci_do_intrs_stats(uhcip, intr_status);
1041 
1042 	/* Acknowledge the interrupt */
1043 	Set_OpReg16(USBSTS, intr_status);
1044 
1045 	/*
1046 	 * If uhci controller has not been initialized, just clear the
1047 	 * interrupter status and return claimed.
1048 	 */
1049 	if (uhcip->uhci_hc_soft_state != UHCI_CTLR_OPERATIONAL_STATE) {
1050 
1051 		USB_DPRINTF_L2(PRINT_MASK_INTR, uhcip->uhci_log_hdl,
1052 		    "uhci_intr: uhci controller is not in the operational "
1053 		    "state");
1054 		mutex_exit(&uhcip->uhci_int_mutex);
1055 
1056 		return (DDI_INTR_CLAIMED);
1057 	}
1058 
1059 	/*
1060 	 * We configured the hw incorrectly, disable future interrupts.
1061 	 */
1062 	if ((intr_status & USBSTS_REG_HOST_SYS_ERR)) {
1063 		USB_DPRINTF_L2(PRINT_MASK_INTR, uhcip->uhci_log_hdl,
1064 		    "uhci_intr: Sys Err Disabling Interrupt");
1065 		Set_OpReg16(USBINTR, DISABLE_ALL_INTRS);
1066 		uhcip->uhci_hc_soft_state = UHCI_CTLR_ERROR_STATE;
1067 
1068 		mutex_exit(&uhcip->uhci_int_mutex);
1069 
1070 		return (DDI_INTR_CLAIMED);
1071 	}
1072 
1073 	/*
1074 	 * Check whether a frame number overflow occurred.
1075 	 * if so, update the sw frame number.
1076 	 */
1077 	uhci_isoc_update_sw_frame_number(uhcip);
1078 
1079 	/*
1080 	 * Check whether any commands got completed. If so, process them.
1081 	 */
1082 	uhci_process_submitted_td_queue(uhcip);
1083 
1084 	/*
1085 	 * This should not occur. It occurs only if a HC controller
1086 	 * experiences internal problem.
1087 	 */
1088 	if (intr_status & USBSTS_REG_HC_HALTED) {
1089 		USB_DPRINTF_L2(PRINT_MASK_INTR, uhcip->uhci_log_hdl,
1090 		    "uhci_intr: Controller halted");
1091 		cmd_reg = Get_OpReg16(USBCMD);
1092 		Set_OpReg16(USBCMD, (cmd_reg | USBCMD_REG_HC_RUN));
1093 	}
1094 
1095 	/*
1096 	 * Wake up all the threads which are waiting for the Start of Frame
1097 	 */
1098 	if (uhcip->uhci_cv_signal == B_TRUE) {
1099 		cv_broadcast(&uhcip->uhci_cv_SOF);
1100 		uhcip->uhci_cv_signal = B_FALSE;
1101 	}
1102 
1103 	mutex_exit(&uhcip->uhci_int_mutex);
1104 
1105 	return (DDI_INTR_CLAIMED);
1106 }
1107 
1108 
1109 /*
1110  * uhci_process_submitted_td_queue:
1111  *    Traverse thru the submitted queue and process the completed ones.
1112  */
1113 void
1114 uhci_process_submitted_td_queue(uhci_state_t *uhcip)
1115 {
1116 	uhci_td_t		*head = uhcip->uhci_outst_tds_head;
1117 	uhci_trans_wrapper_t	*tw;
1118 
1119 	while (head != NULL) {
1120 		if ((!(GetTD_status(uhcip, head) & UHCI_TD_ACTIVE)) &&
1121 		    (head->tw->tw_claim == UHCI_NOT_CLAIMED)) {
1122 			tw = head->tw;
1123 
1124 			/*
1125 			 * Call the corresponding handle_td routine
1126 			 */
1127 			(*tw->tw_handle_td)(uhcip, head);
1128 
1129 			/* restart at the beginning again */
1130 			head = uhcip->uhci_outst_tds_head;
1131 		} else {
1132 			head = head->outst_td_next;
1133 		}
1134 	}
1135 }
1136 
1137 
1138 /*
1139  * uhci_handle_intr_td:
1140  *     handles the completed interrupt transfer TD's.
1141  */
1142 void
1143 uhci_handle_intr_td(uhci_state_t *uhcip, uhci_td_t *td)
1144 {
1145 	usb_req_attrs_t		attrs;
1146 	uint_t			bytes_xfered;
1147 	usb_cr_t		usb_err;
1148 	uhci_trans_wrapper_t	*tw = td->tw;
1149 	uhci_pipe_private_t	*pp = tw->tw_pipe_private;
1150 	usb_intr_req_t		*intr_reqp =
1151 	    (usb_intr_req_t *)tw->tw_curr_xfer_reqp;
1152 	usba_pipe_handle_data_t	*ph = pp->pp_pipe_handle;
1153 
1154 	USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl,
1155 	    "uhci_handle_intr_td: intr_reqp = 0x%p", (void *)intr_reqp);
1156 
1157 	ASSERT(mutex_owned(&uhcip->uhci_int_mutex));
1158 
1159 	/* set tw->tw_claim flag, so that nobody else works on this td. */
1160 	tw->tw_claim = UHCI_INTR_HDLR_CLAIMED;
1161 
1162 	/* Interrupt OUT */
1163 	if (UHCI_XFER_DIR(&ph->p_ep) == USB_EP_DIR_OUT) {
1164 
1165 		/* process errors first */
1166 		usb_err = uhci_parse_td_error(uhcip, pp, td);
1167 
1168 		/* get the actual xfered data size */
1169 		bytes_xfered = GetTD_alen(uhcip, td);
1170 
1171 		/* check data underrun error */
1172 		if ((usb_err == USB_CR_OK) && (bytes_xfered !=
1173 		    GetTD_mlen(uhcip, td))) {
1174 
1175 			USB_DPRINTF_L2(PRINT_MASK_LISTS,
1176 			    uhcip->uhci_log_hdl, "uhci_handle_intr_td:"
1177 			    " Intr out pipe, data underrun occurred");
1178 
1179 			usb_err = USB_CR_DATA_UNDERRUN;
1180 
1181 		}
1182 
1183 		bytes_xfered = (bytes_xfered == ZERO_LENGTH) ?
1184 		    0 : bytes_xfered+1;
1185 		tw->tw_bytes_xfered += bytes_xfered;
1186 		uhci_do_byte_stats(uhcip, tw->tw_bytes_xfered,
1187 		    ph->p_ep.bmAttributes, ph->p_ep.bEndpointAddress);
1188 
1189 
1190 		/*
1191 		 * If error occurred or all data xfered, delete the current td,
1192 		 * free tw, do the callback. Otherwise wait for the next td.
1193 		 */
1194 		if (usb_err != USB_CR_OK) {
1195 
1196 			USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl,
1197 			    "uhci_handle_intr_td: Intr out pipe error");
1198 
1199 			/* update the element pointer */
1200 			SetQH32(uhcip, pp->pp_qh->element_ptr, GetTD32(
1201 			    uhcip, tw->tw_hctd_tail->link_ptr));
1202 
1203 
1204 		} else if (tw->tw_bytes_xfered == tw->tw_length) {
1205 
1206 			/* all data xfered */
1207 			USB_DPRINTF_L3(PRINT_MASK_LISTS, uhcip->uhci_log_hdl,
1208 			    "uhci_handle_intr_td: Intr out pipe,"
1209 			    " all data xfered");
1210 
1211 		} else {
1212 
1213 			/* remove the current td and wait for the next one. */
1214 			uhci_delete_td(uhcip, td);
1215 			tw->tw_claim = UHCI_NOT_CLAIMED;
1216 
1217 			return;
1218 		}
1219 
1220 		uhci_delete_td(uhcip, td);
1221 		uhci_hcdi_callback(uhcip, pp, ph, tw, usb_err);
1222 		uhci_deallocate_tw(uhcip, tw->tw_pipe_private, tw);
1223 
1224 		return;
1225 	}
1226 
1227 	/* Interrupt IN */
1228 
1229 	/* Get the actual received data size */
1230 	tw->tw_bytes_xfered = GetTD_alen(uhcip, td);
1231 	if (tw->tw_bytes_xfered == ZERO_LENGTH) {
1232 		tw->tw_bytes_xfered = 0;
1233 	} else {
1234 		tw->tw_bytes_xfered++;
1235 	}
1236 
1237 	/* process errors first */
1238 	if (GetTD_status(uhcip, td) & TD_STATUS_MASK) {
1239 		SetQH32(uhcip, pp->pp_qh->element_ptr,
1240 		    GetTD32(uhcip, td->link_ptr));
1241 
1242 		uhci_handle_intr_td_errors(uhcip, td, tw, pp);
1243 
1244 		return;
1245 	}
1246 
1247 	/*
1248 	 * Check for data underruns.
1249 	 * For data underrun case, the host controller does not update
1250 	 * element pointer. So, we update here.
1251 	 */
1252 	if (GetTD_alen(uhcip, td) != GetTD_mlen(uhcip, td)) {
1253 		SetQH32(uhcip, pp->pp_qh->element_ptr,
1254 		    GetTD32(uhcip, td->link_ptr));
1255 	}
1256 
1257 	/*
1258 	 * Call uhci_sendup_td_message to send message upstream.
1259 	 * The function uhci_sendup_td_message returns USB_NO_RESOURCES
1260 	 * if allocb fails and also sends error message to upstream by
1261 	 * calling USBA callback function. Under error conditions just
1262 	 * drop the current message.
1263 	 */
1264 
1265 	/* Get the interrupt xfer attributes */
1266 	attrs = intr_reqp->intr_attributes;
1267 
1268 	/*
1269 	 * Check usb flag whether USB_FLAGS_ONE_XFER flag is set
1270 	 * and if so, free duplicate request.
1271 	 */
1272 	if (attrs & USB_ATTRS_ONE_XFER) {
1273 		uhci_handle_one_xfer_completion(uhcip, USB_CR_OK, td);
1274 
1275 		return;
1276 	}
1277 
1278 	/* save it temporarily */
1279 	if (tw->tw_bytes_xfered != 0) {
1280 		uhci_sendup_td_message(uhcip, USB_CR_OK, tw);
1281 	}
1282 
1283 	/* Clear the tw->tw_claim flag */
1284 	tw->tw_claim = UHCI_NOT_CLAIMED;
1285 
1286 	uhci_delete_td(uhcip, td);
1287 
1288 	/* allocate another interrupt periodic resource */
1289 	if (pp->pp_state == UHCI_PIPE_STATE_ACTIVE) {
1290 		if (uhci_allocate_periodic_in_resource(uhcip, pp, tw, 0) !=
1291 		    USB_SUCCESS) {
1292 			USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl,
1293 			    "uhci_insert_intr_req: Interrupt request structure"
1294 			    "allocation failed");
1295 
1296 			uhci_hcdi_callback(uhcip, pp, ph,
1297 			    tw, USB_CR_NO_RESOURCES);
1298 
1299 			return;
1300 		}
1301 
1302 		/* Insert another interrupt TD */
1303 		if (uhci_insert_hc_td(uhcip, 0,
1304 		    tw->tw_length, pp, tw, PID_IN, attrs) != USB_SUCCESS) {
1305 
1306 			uhci_deallocate_periodic_in_resource(uhcip, pp, tw);
1307 
1308 			USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl,
1309 			    "uhci_handle_intr_td: TD exhausted");
1310 
1311 			uhci_hcdi_callback(uhcip, pp, ph,
1312 			    tw, USB_CR_NO_RESOURCES);
1313 		}
1314 	}
1315 }
1316 
1317 
1318 /*
1319  * uhci_sendup_td_message:
1320  *
1321  * Get a message block and send the received message upstream.
1322  */
1323 void
1324 uhci_sendup_td_message(
1325 	uhci_state_t		*uhcip,
1326 	usb_cr_t		usb_err,
1327 	uhci_trans_wrapper_t	*tw)
1328 {
1329 	mblk_t			*mp = NULL;
1330 	size_t			length = 0;
1331 	size_t			skip_len = 0;
1332 	uchar_t			*buf;
1333 	usb_opaque_t		curr_xfer_reqp = tw->tw_curr_xfer_reqp;
1334 	uhci_pipe_private_t	*pp = tw->tw_pipe_private;
1335 	usb_ep_descr_t		*ept = &pp->pp_pipe_handle->p_ep;
1336 
1337 	ASSERT(mutex_owned(&uhcip->uhci_int_mutex));
1338 
1339 	USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl,
1340 	    "uhci_sendup_td_message: bytes transferred=0x%x, "
1341 	    "bytes pending=0x%x",
1342 	    tw->tw_bytes_xfered, tw->tw_bytes_pending);
1343 
1344 	length = tw->tw_bytes_xfered;
1345 
1346 	switch (UHCI_XFER_TYPE(ept)) {
1347 	case USB_EP_ATTR_CONTROL:
1348 		skip_len = UHCI_CTRL_EPT_MAX_SIZE; /* length to skip */
1349 		mp = ((usb_ctrl_req_t *)curr_xfer_reqp)->ctrl_data;
1350 		break;
1351 	case USB_EP_ATTR_INTR:
1352 		mp = ((usb_intr_req_t *)curr_xfer_reqp)->intr_data;
1353 		break;
1354 	case USB_EP_ATTR_BULK:
1355 		mp = ((usb_bulk_req_t *)curr_xfer_reqp)->bulk_data;
1356 		break;
1357 	case USB_EP_ATTR_ISOCH:
1358 		length = tw->tw_length;
1359 		mp = ((usb_isoc_req_t *)curr_xfer_reqp)->isoc_data;
1360 		break;
1361 	default:
1362 		break;
1363 	}
1364 
1365 	/* Copy the data into the mblk_t */
1366 	buf = (uchar_t *)tw->tw_buf + skip_len;
1367 
1368 	ASSERT(mp != NULL);
1369 
1370 	/*
1371 	 * Update kstat byte counts
1372 	 * The control endpoints don't have direction bits so in
1373 	 * order for control stats to be counted correctly an IN
1374 	 * bit must be faked on a control read.
1375 	 */
1376 	uhci_do_byte_stats(uhcip, length, ept->bmAttributes,
1377 	    (UHCI_XFER_TYPE(ept) == USB_EP_ATTR_CONTROL) ?
1378 	    USB_EP_DIR_IN : ept->bEndpointAddress);
1379 
1380 	if (length) {
1381 		int rval, i;
1382 		uchar_t *p = mp->b_rptr;
1383 
1384 		if (UHCI_XFER_TYPE(ept) == USB_EP_ATTR_ISOCH) {
1385 			/* Deal with isoc data by packets */
1386 			for (i = 0; i < tw->tw_ncookies; i++) {
1387 				rval = ddi_dma_sync(
1388 				    tw->tw_isoc_bufs[i].dma_handle, 0,
1389 				    tw->tw_isoc_bufs[i].length,
1390 				    DDI_DMA_SYNC_FORCPU);
1391 				ASSERT(rval == DDI_SUCCESS);
1392 
1393 				ddi_rep_get8(tw->tw_isoc_bufs[i].mem_handle,
1394 				    p, (uint8_t *)tw->tw_isoc_bufs[i].buf_addr,
1395 				    tw->tw_isoc_bufs[i].length,
1396 				    DDI_DEV_AUTOINCR);
1397 				p += tw->tw_isoc_bufs[i].length;
1398 			}
1399 		} else {
1400 			/* Sync the streaming buffer */
1401 			rval = ddi_dma_sync(tw->tw_dmahandle, 0,
1402 			    (skip_len + length), DDI_DMA_SYNC_FORCPU);
1403 			ASSERT(rval == DDI_SUCCESS);
1404 
1405 			/* Copy the data into the message */
1406 			ddi_rep_get8(tw->tw_accesshandle,
1407 			    mp->b_rptr, buf, length, DDI_DEV_AUTOINCR);
1408 		}
1409 
1410 		/* Increment the write pointer */
1411 		mp->b_wptr += length;
1412 	} else {
1413 		USB_DPRINTF_L3(PRINT_MASK_LISTS, uhcip->uhci_log_hdl,
1414 		    "uhci_sendup_td_message: Zero length packet");
1415 	}
1416 
1417 	/* Do the callback */
1418 	uhci_hcdi_callback(uhcip, pp, pp->pp_pipe_handle, tw, usb_err);
1419 }
1420 
1421 
1422 /*
1423  * uhci_handle_ctrl_td:
1424  *	Handle a control Transfer Descriptor (TD).
1425  */
1426 void
1427 uhci_handle_ctrl_td(uhci_state_t *uhcip, uhci_td_t *td)
1428 {
1429 	ushort_t		direction;
1430 	ushort_t		bytes_for_xfer;
1431 	ushort_t		bytes_xfered;
1432 	ushort_t		MaxPacketSize;
1433 	usb_cr_t		error;
1434 	uhci_trans_wrapper_t	*tw = td->tw;
1435 	uhci_pipe_private_t	*pp = tw->tw_pipe_private;
1436 	usba_pipe_handle_data_t	*usb_pp = pp->pp_pipe_handle;
1437 	usb_ep_descr_t		*eptd = &usb_pp->p_ep;
1438 	usb_ctrl_req_t		*reqp = (usb_ctrl_req_t *)tw->tw_curr_xfer_reqp;
1439 
1440 	USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl,
1441 	    "uhci_handle_ctrl_td: pp = 0x%p tw = 0x%p td = 0x%p "
1442 	    "state = 0x%x len = 0x%lx", (void *)pp, (void *)tw,
1443 	    (void *)td, tw->tw_ctrl_state, tw->tw_length);
1444 
1445 	ASSERT(mutex_owned(&uhcip->uhci_int_mutex));
1446 
1447 	error = uhci_parse_td_error(uhcip, pp, td);
1448 
1449 	/*
1450 	 * In case of control transfers, the device can send NAK when it
1451 	 * is busy. If a NAK is received, then send the status TD again.
1452 	 */
1453 	if (error != USB_CR_OK) {
1454 		USB_DPRINTF_L3(PRINT_MASK_LISTS, uhcip->uhci_log_hdl,
1455 		    "uhci_handle_ctrl_td: Ctrl cmd failed, error = %x", error);
1456 
1457 		SetQH32(uhcip, pp->pp_qh->element_ptr,
1458 		    GetTD32(uhcip, td->link_ptr));
1459 		uhci_delete_td(uhcip, td);
1460 
1461 		/* Return number of bytes xfered */
1462 		if (GetTD_alen(uhcip, td) != ZERO_LENGTH) {
1463 			tw->tw_bytes_xfered = GetTD_alen(uhcip, td) + 1;
1464 		}
1465 
1466 		USB_DPRINTF_L3(PRINT_MASK_LISTS, uhcip->uhci_log_hdl,
1467 		    "uhci_handle_ctrl_td: Bytes transferred = %x",
1468 		    tw->tw_bytes_xfered);
1469 
1470 		if ((tw->tw_ctrl_state == DATA) &&
1471 		    (tw->tw_direction == PID_IN)) {
1472 			uhci_sendup_td_message(uhcip, error, tw);
1473 		} else {
1474 			uhci_hcdi_callback(uhcip, pp, usb_pp, tw, error);
1475 
1476 			uhci_deallocate_tw(uhcip, pp, tw);
1477 		}
1478 
1479 		return;
1480 	}
1481 
1482 	/*
1483 	 * A control transfer consists of three phases:
1484 	 *	- Setup
1485 	 *	- Data (optional)
1486 	 *	- Status
1487 	 *
1488 	 * There is a TD per phase. A TD for a given phase isn't
1489 	 * enqueued until the previous phase is finished.
1490 	 */
1491 	switch (tw->tw_ctrl_state) {
1492 	case SETUP:
1493 		/*
1494 		 * Enqueue either the data or the status
1495 		 * phase depending on the length.
1496 		 */
1497 		pp->pp_data_toggle = 1;
1498 		uhci_delete_td(uhcip, td);
1499 
1500 		/*
1501 		 * If the length is 0, move to the status.
1502 		 * If length is not 0, then we have some data
1503 		 * to move on the bus to device either IN or OUT.
1504 		 */
1505 		if ((tw->tw_length - SETUP_SIZE) == 0) {
1506 			/*
1507 			 * There is no data stage,  then
1508 			 * initiate status phase from the host.
1509 			 */
1510 			if ((uhci_insert_hc_td(uhcip, 0, 0, pp, tw, PID_IN,
1511 			    reqp->ctrl_attributes)) != USB_SUCCESS) {
1512 				USB_DPRINTF_L2(PRINT_MASK_LISTS,
1513 				    uhcip->uhci_log_hdl,
1514 				    "uhci_handle_ctrl_td: No resources");
1515 
1516 				uhci_hcdi_callback(uhcip, pp, usb_pp, tw,
1517 				    USB_CR_NO_RESOURCES);
1518 
1519 				return;
1520 			}
1521 
1522 			tw->tw_ctrl_state = STATUS;
1523 		} else {
1524 			uint_t xx;
1525 
1526 			/*
1527 			 * Each USB device can send/receive 8/16/32/64
1528 			 * depending on wMaxPacketSize's implementation.
1529 			 * We need to insert 'N = Number of byte/
1530 			 * MaxpktSize" TD's in the lattice to send/
1531 			 * receive the data. Though the USB protocol
1532 			 * allows to insert more than one TD in the same
1533 			 * frame, we are inserting only one TD in one
1534 			 * frame. This is bcos OHCI has seen some problem
1535 			 * when multiple TD's are inserted at the same time.
1536 			 */
1537 			tw->tw_length -= UHCI_CTRL_EPT_MAX_SIZE;
1538 			MaxPacketSize = eptd->wMaxPacketSize;
1539 
1540 			/*
1541 			 * We dont know the maximum packet size that
1542 			 * the device can handle(MaxPAcketSize=0).
1543 			 * In that case insert a data phase with
1544 			 * eight bytes or less.
1545 			 */
1546 			if (MaxPacketSize == 0) {
1547 				xx = (tw->tw_length > 8) ? 8 : tw->tw_length;
1548 			} else {
1549 				xx = (tw->tw_length > MaxPacketSize) ?
1550 				    MaxPacketSize : tw->tw_length;
1551 			}
1552 
1553 			tw->tw_tmp = xx;
1554 
1555 			/*
1556 			 * Create the TD.  If this is an OUT
1557 			 * transaction,  the data is already
1558 			 * in the buffer of the TW.
1559 			 * Get first 8 bytes of the command only.
1560 			 */
1561 			if ((uhci_insert_hc_td(uhcip,
1562 			    UHCI_CTRL_EPT_MAX_SIZE, xx,
1563 			    pp, tw, tw->tw_direction,
1564 			    reqp->ctrl_attributes)) != USB_SUCCESS) {
1565 
1566 				USB_DPRINTF_L2(PRINT_MASK_LISTS,
1567 				    uhcip->uhci_log_hdl,
1568 				    "uhci_handle_ctrl_td: No resources");
1569 
1570 				uhci_hcdi_callback(uhcip, pp, usb_pp, tw,
1571 				    USB_CR_NO_RESOURCES);
1572 
1573 				return;
1574 			}
1575 
1576 			tw->tw_ctrl_state = DATA;
1577 		}
1578 
1579 		USB_DPRINTF_L3(PRINT_MASK_LISTS, uhcip->uhci_log_hdl,
1580 		    "Setup complete: pp 0x%p td 0x%p", (void *)pp, (void *)td);
1581 
1582 		break;
1583 	case DATA:
1584 		uhci_delete_td(uhcip, td);
1585 
1586 		MaxPacketSize = eptd->wMaxPacketSize;
1587 
1588 		/*
1589 		 * Decrement pending bytes and increment the total
1590 		 * number bytes transferred by the actual number of bytes
1591 		 * transferred in this TD. If the number of bytes transferred
1592 		 * is less than requested, that means an underrun has
1593 		 * occurred. Set the tw_tmp varible to indicate UNDER run.
1594 		 */
1595 		bytes_xfered = GetTD_alen(uhcip, td);
1596 		if (bytes_xfered == ZERO_LENGTH) {
1597 			bytes_xfered = 0;
1598 		} else {
1599 			bytes_xfered++;
1600 		}
1601 
1602 		tw->tw_bytes_pending -= bytes_xfered;
1603 		tw->tw_bytes_xfered += bytes_xfered;
1604 
1605 		if (bytes_xfered < tw->tw_tmp) {
1606 			tw->tw_bytes_pending = 0;
1607 			tw->tw_tmp = UHCI_UNDERRUN_OCCURRED;
1608 
1609 			/*
1610 			 * Controller does not update the queue head
1611 			 * element pointer when a data underrun occurs.
1612 			 */
1613 			SetQH32(uhcip, pp->pp_qh->element_ptr,
1614 			    GetTD32(uhcip, td->link_ptr));
1615 		}
1616 
1617 		if (bytes_xfered > tw->tw_tmp) {
1618 			tw->tw_bytes_pending = 0;
1619 			tw->tw_tmp = UHCI_OVERRUN_OCCURRED;
1620 		}
1621 
1622 		/*
1623 		 * If no more bytes are pending, insert status
1624 		 * phase. Otherwise insert data phase.
1625 		 */
1626 		if (tw->tw_bytes_pending) {
1627 			bytes_for_xfer = (tw->tw_bytes_pending >
1628 			    MaxPacketSize) ? MaxPacketSize :
1629 			    tw->tw_bytes_pending;
1630 
1631 			tw->tw_tmp = bytes_for_xfer;
1632 
1633 			if ((uhci_insert_hc_td(uhcip,
1634 			    UHCI_CTRL_EPT_MAX_SIZE + tw->tw_bytes_xfered,
1635 			    bytes_for_xfer, pp, tw,
1636 			    tw->tw_direction,
1637 			    reqp->ctrl_attributes)) != USB_SUCCESS) {
1638 				USB_DPRINTF_L2(PRINT_MASK_LISTS,
1639 				    uhcip->uhci_log_hdl,
1640 				    "uhci_handle_ctrl_td: No TD");
1641 
1642 				uhci_hcdi_callback(uhcip, pp, usb_pp,
1643 				    tw, USB_NO_RESOURCES);
1644 
1645 				return;
1646 			}
1647 
1648 			tw->tw_ctrl_state = DATA;
1649 
1650 			break;
1651 		}
1652 
1653 		pp->pp_data_toggle = 1;
1654 		direction = (tw->tw_direction == PID_IN) ? PID_OUT : PID_IN;
1655 
1656 		if ((uhci_insert_hc_td(uhcip, 0, 0, pp, tw, direction,
1657 		    reqp->ctrl_attributes)) != USB_SUCCESS) {
1658 			USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl,
1659 			    "uhci_handle_ctrl_td: TD exhausted");
1660 
1661 			uhci_hcdi_callback(uhcip, pp, usb_pp, tw,
1662 			    USB_NO_RESOURCES);
1663 
1664 			return;
1665 		}
1666 
1667 		tw->tw_ctrl_state = STATUS;
1668 		USB_DPRINTF_L3(PRINT_MASK_LISTS, uhcip->uhci_log_hdl,
1669 		    "Data complete: pp 0x%p td 0x%p", (void *)pp, (void *)td);
1670 
1671 		break;
1672 	case STATUS:
1673 		/*
1674 		 * Send the data to the client if it is a DATA IN,
1675 		 * else send just return status for DATA OUT commnads.
1676 		 * And set the tw_claim flag.
1677 		 */
1678 		tw->tw_claim = UHCI_INTR_HDLR_CLAIMED;
1679 
1680 		if ((tw->tw_length != 0) && (tw->tw_direction == PID_IN)) {
1681 			usb_req_attrs_t	attrs = ((usb_ctrl_req_t *)
1682 			    tw->tw_curr_xfer_reqp)->ctrl_attributes;
1683 			/*
1684 			 * Call uhci_sendup_td_message to send message
1685 			 * upstream. The function uhci_sendup_td_message
1686 			 * returns USB_NO_RESOURCES if allocb fails and
1687 			 * also sends error message to upstream by calling
1688 			 * USBA callback function.
1689 			 *
1690 			 * Under error conditions just drop the current msg.
1691 			 */
1692 			if ((tw->tw_tmp == UHCI_UNDERRUN_OCCURRED) &&
1693 			    (!(attrs & USB_ATTRS_SHORT_XFER_OK))) {
1694 				error = USB_CR_DATA_UNDERRUN;
1695 			} else if (tw->tw_tmp == UHCI_OVERRUN_OCCURRED) {
1696 				error = USB_CR_DATA_OVERRUN;
1697 			}
1698 			uhci_sendup_td_message(uhcip, error, tw);
1699 
1700 		} else {
1701 			uhci_do_byte_stats(uhcip, tw->tw_length,
1702 			    eptd->bmAttributes, eptd->bEndpointAddress);
1703 
1704 			uhci_hcdi_callback(uhcip, pp, usb_pp, tw, USB_CR_OK);
1705 		}
1706 
1707 		USB_DPRINTF_L3(PRINT_MASK_LISTS, uhcip->uhci_log_hdl,
1708 		    "Status complete: pp 0x%p td 0x%p", (void *)pp, (void *)td);
1709 
1710 		uhci_delete_td(uhcip, td);
1711 		uhci_deallocate_tw(uhcip, pp, tw);
1712 
1713 		break;
1714 	default:
1715 		USB_DPRINTF_L2(PRINT_MASK_INTR, uhcip->uhci_log_hdl,
1716 		    "uhci_handle_ctrl_td: Bad control state");
1717 
1718 		uhci_hcdi_callback(uhcip, pp, usb_pp, tw,
1719 		    USB_CR_UNSPECIFIED_ERR);
1720 	}
1721 }
1722 
1723 
1724 /*
1725  * uhci_handle_intr_td_errors:
1726  *	Handles the errors encountered for the interrupt transfers.
1727  */
1728 static void
1729 uhci_handle_intr_td_errors(uhci_state_t *uhcip, uhci_td_t *td,
1730     uhci_trans_wrapper_t *tw, uhci_pipe_private_t *pp)
1731 {
1732 	usb_cr_t		usb_err;
1733 	usb_intr_req_t		*intr_reqp =
1734 	    (usb_intr_req_t *)tw->tw_curr_xfer_reqp;
1735 
1736 	USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl,
1737 	    "uhci_handle_intr_td_errors: td = 0x%p tw = 0x%p",
1738 	    (void *)td, (void *)tw);
1739 
1740 	usb_err = uhci_parse_td_error(uhcip, pp, td);
1741 
1742 	if (intr_reqp->intr_attributes & USB_ATTRS_ONE_XFER) {
1743 		uhci_handle_one_xfer_completion(uhcip, usb_err, td);
1744 
1745 		return;
1746 	}
1747 
1748 	uhci_delete_td(uhcip, td);
1749 	uhci_sendup_td_message(uhcip, usb_err, tw);
1750 	uhci_deallocate_tw(uhcip, tw->tw_pipe_private, tw);
1751 }
1752 
1753 
1754 /*
1755  * uhci_handle_one_xfer_completion:
1756  */
1757 static void
1758 uhci_handle_one_xfer_completion(
1759 	uhci_state_t		*uhcip,
1760 	usb_cr_t		usb_err,
1761 	uhci_td_t		*td)
1762 {
1763 	uhci_trans_wrapper_t	*tw = td->tw;
1764 	uhci_pipe_private_t	*pp = tw->tw_pipe_private;
1765 	usba_pipe_handle_data_t	*ph = pp->pp_pipe_handle;
1766 	usb_intr_req_t		*intr_reqp =
1767 	    (usb_intr_req_t *)tw->tw_curr_xfer_reqp;
1768 
1769 	USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl,
1770 	    "uhci_handle_one_xfer_completion: td = 0x%p", (void *)td);
1771 
1772 	ASSERT(intr_reqp->intr_attributes & USB_ATTRS_ONE_XFER);
1773 
1774 	/* set state to idle */
1775 	pp->pp_state = UHCI_PIPE_STATE_IDLE;
1776 
1777 	((usb_intr_req_t *)(pp->pp_client_periodic_in_reqp))->
1778 	    intr_data = ((usb_intr_req_t *)(tw->tw_curr_xfer_reqp))->intr_data;
1779 
1780 	((usb_intr_req_t *)tw->tw_curr_xfer_reqp)->intr_data = NULL;
1781 
1782 	/* now free duplicate current request */
1783 	usb_free_intr_req((usb_intr_req_t *)tw->tw_curr_xfer_reqp);
1784 	mutex_enter(&ph->p_mutex);
1785 	ph->p_req_count--;
1786 	mutex_exit(&ph->p_mutex);
1787 
1788 	/* make client's request the current request */
1789 	tw->tw_curr_xfer_reqp = pp->pp_client_periodic_in_reqp;
1790 	pp->pp_client_periodic_in_reqp = NULL;
1791 
1792 	uhci_sendup_td_message(uhcip, usb_err, tw);
1793 	/* Clear the tw->tw_claim flag */
1794 	tw->tw_claim = UHCI_NOT_CLAIMED;
1795 
1796 	uhci_delete_td(uhcip, td);
1797 	uhci_deallocate_tw(uhcip, pp, tw);
1798 }
1799 
1800 
1801 /*
1802  * uhci_parse_td_error
1803  *	Parses the Transfer Descriptors error
1804  */
1805 usb_cr_t
1806 uhci_parse_td_error(uhci_state_t *uhcip, uhci_pipe_private_t *pp, uhci_td_t *td)
1807 {
1808 	uint_t	status;
1809 
1810 	status = GetTD_status(uhcip, td) & TD_STATUS_MASK;
1811 
1812 	USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl,
1813 	    "uhci_parse_td_error: status_bits=0x%x", status);
1814 
1815 	if (UHCI_XFER_TYPE(&pp->pp_pipe_handle->p_ep) == USB_EP_ATTR_ISOCH) {
1816 
1817 		return (USB_CR_OK);
1818 	}
1819 
1820 	if (!status) {
1821 
1822 		return (USB_CR_OK);
1823 	}
1824 
1825 	USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl,
1826 	    "uhci_parse_td_error: status_bits=0x%x", status);
1827 
1828 
1829 	if (status & UHCI_TD_BITSTUFF_ERR) {
1830 
1831 		return (USB_CR_BITSTUFFING);
1832 	}
1833 
1834 	if (status & UHCI_TD_CRC_TIMEOUT) {
1835 		pp->pp_data_toggle = GetTD_dtogg(uhcip, td);
1836 
1837 		USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl,
1838 		    "uhci_parse_td_error: timeout & data toggle reset; "
1839 		    "data toggle: %x", pp->pp_data_toggle);
1840 
1841 		return ((GetTD_PID(uhcip, td) == PID_IN) ? USB_CR_DEV_NOT_RESP :
1842 		    USB_CR_TIMEOUT);
1843 	}
1844 
1845 	if (status & UHCI_TD_BABBLE_ERR) {
1846 		USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl,
1847 		    "babble error");
1848 
1849 		return (USB_CR_UNSPECIFIED_ERR);
1850 	}
1851 
1852 	if (status & UHCI_TD_DATA_BUFFER_ERR) {
1853 		USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl,
1854 		    "buffer error");
1855 
1856 		return ((GetTD_PID(uhcip, td) == PID_IN) ?
1857 		    USB_CR_BUFFER_OVERRUN : USB_CR_BUFFER_UNDERRUN);
1858 	}
1859 
1860 	if (status & UHCI_TD_STALLED) {
1861 		pp->pp_data_toggle = 0;
1862 		USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl,
1863 		    "uhci_parse_td_error: stall; data toggle reset; "
1864 		    "data toggle: %x", pp->pp_data_toggle);
1865 
1866 		return (USB_CR_STALL);
1867 	}
1868 
1869 	if (status) {
1870 		USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl,
1871 		    "unspecified error=0x%x", status);
1872 	}
1873 
1874 	return (USB_CR_OK);
1875 }
1876 
1877 
1878 static dev_info_t *
1879 uhci_get_dip(dev_t dev)
1880 {
1881 	int instance = UHCI_UNIT(dev);
1882 	uhci_state_t *uhcip = ddi_get_soft_state(uhci_statep, instance);
1883 
1884 	return (uhcip ? uhcip->uhci_dip : NULL);
1885 }
1886 
1887 
1888 /*
1889  * cb_ops entry points
1890  */
1891 static int
1892 uhci_open(dev_t *devp, int flags, int otyp, cred_t *credp)
1893 {
1894 	dev_info_t *dip = uhci_get_dip(*devp);
1895 
1896 	return (usba_hubdi_open(dip, devp, flags, otyp, credp));
1897 }
1898 
1899 
1900 static int
1901 uhci_close(dev_t dev, int flag, int otyp, cred_t *credp)
1902 {
1903 	dev_info_t *dip = uhci_get_dip(dev);
1904 
1905 	return (usba_hubdi_close(dip, dev, flag, otyp, credp));
1906 }
1907 
1908 
1909 static int
1910 uhci_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
1911     cred_t *credp, int *rvalp)
1912 {
1913 	dev_info_t *dip = uhci_get_dip(dev);
1914 
1915 	return (usba_hubdi_ioctl(dip, dev, cmd, arg, mode, credp, rvalp));
1916 }
1917