xref: /illumos-gate/usr/src/uts/common/io/usb/hcd/ehci/ehci.c (revision 3ceb94da)
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 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 /*
29  * EHCI Host Controller Driver (EHCI)
30  *
31  * The EHCI driver is a software driver which interfaces to the Universal
32  * Serial Bus layer (USBA) and the Host Controller (HC). The interface to
33  * the Host Controller is defined by the EHCI Host Controller Interface.
34  *
35  * This file contains code for Auto-configuration and HCDI entry points.
36  *
37  * NOTE:
38  *
39  * Currently EHCI driver does not support the following features
40  *
41  * - Alternate QTD for short xfer condition is only used in Bulk xfers.
42  * - Frame Span Traversal Nodes (FSTN).
43  * - Bandwidth allocation scheme needs to be updated for FSTN and USB2.0
44  *   or High speed hub with multiple TT implementation. Currently bandwidth
45  *   allocation scheme assumes one TT per USB2.0 or High speed hub.
46  * - 64 bit addressing capability.
47  * - Programmable periodic frame list size like 256, 512, 1024.
48  *   It supports only 1024 periodic frame list size.
49  */
50 
51 #include <sys/usb/hcd/ehci/ehcid.h>
52 #include <sys/usb/hcd/ehci/ehci_xfer.h>
53 #include <sys/usb/hcd/ehci/ehci_intr.h>
54 #include <sys/usb/hcd/ehci/ehci_util.h>
55 #include <sys/usb/hcd/ehci/ehci_isoch.h>
56 
57 /* Pointer to the state structure */
58 void *ehci_statep;
59 
60 /* Number of instances */
61 #define	EHCI_INSTS	1
62 
63 /* Debugging information */
64 uint_t ehci_errmask	= (uint_t)PRINT_MASK_ALL;
65 uint_t ehci_errlevel	= USB_LOG_L2;
66 uint_t ehci_instance_debug = (uint_t)-1;
67 
68 /*
69  * Tunable to ensure host controller goes off even if a keyboard is attached.
70  */
71 int force_ehci_off = 1;
72 
73 /* Enable all workarounds for VIA VT62x2 */
74 uint_t ehci_vt62x2_workaround = EHCI_VIA_WORKAROUNDS;
75 
76 /*
77  * EHCI Auto-configuration entry points.
78  *
79  * Device operations (dev_ops) entries function prototypes.
80  *
81  * We use the hub cbops since all nexus ioctl operations defined so far will
82  * be executed by the root hub. The following are the Host Controller Driver
83  * (HCD) entry points.
84  *
85  * the open/close/ioctl functions call the corresponding usba_hubdi_*
86  * calls after looking up the dip thru the dev_t.
87  */
88 static int	ehci_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
89 static int	ehci_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
90 static int	ehci_reset(dev_info_t *dip, ddi_reset_cmd_t cmd);
91 static int	ehci_info(dev_info_t *dip, ddi_info_cmd_t infocmd,
92 				void *arg, void **result);
93 
94 static int	ehci_open(dev_t	*devp, int flags, int otyp, cred_t *credp);
95 static int	ehci_close(dev_t dev, int flag, int otyp, cred_t *credp);
96 static int	ehci_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
97     cred_t *credp, int *rvalp);
98 
99 int		usba_hubdi_root_hub_power(dev_info_t *dip, int comp, int level);
100 
101 static struct cb_ops ehci_cb_ops = {
102 	ehci_open,			/* EHCI */
103 	ehci_close,			/* Close */
104 	nodev,				/* Strategy */
105 	nodev,				/* Print */
106 	nodev,				/* Dump */
107 	nodev,				/* Read */
108 	nodev,				/* Write */
109 	ehci_ioctl,			/* Ioctl */
110 	nodev,				/* Devmap */
111 	nodev,				/* Mmap */
112 	nodev,				/* Segmap */
113 	nochpoll,			/* Poll */
114 	ddi_prop_op,			/* cb_prop_op */
115 	NULL,				/* Streamtab */
116 	D_NEW | D_MP | D_HOTPLUG	/* Driver compatibility flag */
117 };
118 
119 static struct dev_ops ehci_ops = {
120 	DEVO_REV,			/* Devo_rev */
121 	0,				/* Refcnt */
122 	ehci_info,			/* Info */
123 	nulldev,			/* Identify */
124 	nulldev,			/* Probe */
125 	ehci_attach,			/* Attach */
126 	ehci_detach,			/* Detach */
127 	ehci_reset,			/* Reset */
128 	&ehci_cb_ops,			/* Driver operations */
129 	&usba_hubdi_busops,		/* Bus operations */
130 	usba_hubdi_root_hub_power	/* Power */
131 };
132 
133 /*
134  * The USBA library must be loaded for this driver.
135  */
136 static struct modldrv modldrv = {
137 	&mod_driverops, 	/* Type of module. This one is a driver */
138 	"USB EHCI Driver", /* Name of the module. */
139 	&ehci_ops,		/* Driver ops */
140 };
141 
142 static struct modlinkage modlinkage = {
143 	MODREV_1, (void *)&modldrv, NULL
144 };
145 
146 
147 int
148 _init(void)
149 {
150 	int error;
151 
152 	/* Initialize the soft state structures */
153 	if ((error = ddi_soft_state_init(&ehci_statep, sizeof (ehci_state_t),
154 	    EHCI_INSTS)) != 0) {
155 		return (error);
156 	}
157 
158 	/* Install the loadable module */
159 	if ((error = mod_install(&modlinkage)) != 0) {
160 		ddi_soft_state_fini(&ehci_statep);
161 	}
162 
163 	return (error);
164 }
165 
166 
167 int
168 _info(struct modinfo *modinfop)
169 {
170 	return (mod_info(&modlinkage, modinfop));
171 }
172 
173 
174 int
175 _fini(void)
176 {
177 	int error;
178 
179 	if ((error = mod_remove(&modlinkage)) == 0) {
180 
181 		/* Release per module resources */
182 		ddi_soft_state_fini(&ehci_statep);
183 	}
184 
185 	return (error);
186 }
187 
188 
189 /*
190  * EHCI Auto configuration entry points.
191  */
192 
193 /*
194  * ehci_attach:
195  *
196  * Description: Attach entry point is called by the Kernel.
197  *		Allocates resources for each EHCI host controller instance.
198  *		Initializes the EHCI Host Controller.
199  *
200  * Return     : DDI_SUCCESS / DDI_FAILURE.
201  */
202 static int
203 ehci_attach(dev_info_t		*dip,
204 	ddi_attach_cmd_t	cmd)
205 {
206 	int			instance;
207 	ehci_state_t		*ehcip = NULL;
208 	usba_hcdi_register_args_t hcdi_args;
209 
210 	switch (cmd) {
211 	case DDI_ATTACH:
212 		break;
213 	case DDI_RESUME:
214 		ehcip = ehci_obtain_state(dip);
215 
216 		return (ehci_cpr_resume(ehcip));
217 	default:
218 		return (DDI_FAILURE);
219 	}
220 
221 	/* Get the instance and create soft state */
222 	instance = ddi_get_instance(dip);
223 
224 	if (ddi_soft_state_zalloc(ehci_statep, instance) != 0) {
225 
226 		return (DDI_FAILURE);
227 	}
228 
229 	ehcip = ddi_get_soft_state(ehci_statep, instance);
230 	if (ehcip == NULL) {
231 
232 		return (DDI_FAILURE);
233 	}
234 
235 	ehcip->ehci_flags = EHCI_ATTACH;
236 
237 	ehcip->ehci_log_hdl = usb_alloc_log_hdl(dip, "ehci", &ehci_errlevel,
238 	    &ehci_errmask, &ehci_instance_debug, 0);
239 
240 	ehcip->ehci_flags |= EHCI_ZALLOC;
241 
242 	/* Set host controller soft state to initialization */
243 	ehcip->ehci_hc_soft_state = EHCI_CTLR_INIT_STATE;
244 
245 	USB_DPRINTF_L4(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
246 	    "ehcip = 0x%p", (void *)ehcip);
247 
248 	/* Save the dip and instance */
249 	ehcip->ehci_dip = dip;
250 	ehcip->ehci_instance = instance;
251 
252 	/* Map the registers */
253 	if (ehci_map_regs(ehcip) != DDI_SUCCESS) {
254 		(void) ehci_cleanup(ehcip);
255 
256 		return (DDI_FAILURE);
257 	}
258 
259 	/* Get the ehci chip vendor and device id */
260 	ehcip->ehci_vendor_id = pci_config_get16(
261 	    ehcip->ehci_config_handle, PCI_CONF_VENID);
262 	ehcip->ehci_device_id = pci_config_get16(
263 	    ehcip->ehci_config_handle, PCI_CONF_DEVID);
264 	ehcip->ehci_rev_id = pci_config_get8(
265 	    ehcip->ehci_config_handle, PCI_CONF_REVID);
266 
267 	/* Initialize the DMA attributes */
268 	ehci_set_dma_attributes(ehcip);
269 
270 	/* Initialize kstat structures */
271 	ehci_create_stats(ehcip);
272 
273 	/* Create the qtd and qh pools */
274 	if (ehci_allocate_pools(ehcip) != DDI_SUCCESS) {
275 		(void) ehci_cleanup(ehcip);
276 
277 		return (DDI_FAILURE);
278 	}
279 
280 	/* Initialize the isochronous resources */
281 	if (ehci_isoc_init(ehcip) != DDI_SUCCESS) {
282 		(void) ehci_cleanup(ehcip);
283 
284 		return (DDI_FAILURE);
285 	}
286 
287 	/* Register interrupts */
288 	if (ehci_register_intrs_and_init_mutex(ehcip) != DDI_SUCCESS) {
289 		(void) ehci_cleanup(ehcip);
290 
291 		return (DDI_FAILURE);
292 	}
293 
294 	mutex_enter(&ehcip->ehci_int_mutex);
295 
296 	/* Initialize the controller */
297 	if (ehci_init_ctlr(ehcip, EHCI_NORMAL_INITIALIZATION) != DDI_SUCCESS) {
298 		mutex_exit(&ehcip->ehci_int_mutex);
299 		(void) ehci_cleanup(ehcip);
300 
301 		return (DDI_FAILURE);
302 	}
303 
304 	/*
305 	 * At this point, the hardware will be okay.
306 	 * Initialize the usba_hcdi structure
307 	 */
308 	ehcip->ehci_hcdi_ops = ehci_alloc_hcdi_ops(ehcip);
309 
310 	mutex_exit(&ehcip->ehci_int_mutex);
311 
312 	/*
313 	 * Make this HCD instance known to USBA
314 	 * (dma_attr must be passed for USBA busctl's)
315 	 */
316 	hcdi_args.usba_hcdi_register_version = HCDI_REGISTER_VERSION;
317 	hcdi_args.usba_hcdi_register_dip = dip;
318 	hcdi_args.usba_hcdi_register_ops = ehcip->ehci_hcdi_ops;
319 	hcdi_args.usba_hcdi_register_dma_attr = &ehcip->ehci_dma_attr;
320 
321 	/*
322 	 * Priority and iblock_cookie are one and the same
323 	 * (However, retaining hcdi_soft_iblock_cookie for now
324 	 * assigning it w/ priority. In future all iblock_cookie
325 	 * could just go)
326 	 */
327 	hcdi_args.usba_hcdi_register_iblock_cookie =
328 	    (ddi_iblock_cookie_t)(uintptr_t)ehcip->ehci_intr_pri;
329 
330 	if (usba_hcdi_register(&hcdi_args, 0) != DDI_SUCCESS) {
331 		(void) ehci_cleanup(ehcip);
332 
333 		return (DDI_FAILURE);
334 	}
335 
336 	ehcip->ehci_flags |= EHCI_USBAREG;
337 
338 	mutex_enter(&ehcip->ehci_int_mutex);
339 
340 	if ((ehci_init_root_hub(ehcip)) != USB_SUCCESS) {
341 		mutex_exit(&ehcip->ehci_int_mutex);
342 		(void) ehci_cleanup(ehcip);
343 
344 		return (DDI_FAILURE);
345 	}
346 
347 	mutex_exit(&ehcip->ehci_int_mutex);
348 
349 	/* Finally load the root hub driver */
350 	if (ehci_load_root_hub_driver(ehcip) != USB_SUCCESS) {
351 		(void) ehci_cleanup(ehcip);
352 
353 		return (DDI_FAILURE);
354 	}
355 	ehcip->ehci_flags |= EHCI_RHREG;
356 
357 	/* Display information in the banner */
358 	ddi_report_dev(dip);
359 
360 	mutex_enter(&ehcip->ehci_int_mutex);
361 
362 	/* Reset the ehci initialization flag */
363 	ehcip->ehci_flags &= ~EHCI_ATTACH;
364 
365 	/* Print the Host Control's Operational registers */
366 	ehci_print_caps(ehcip);
367 	ehci_print_regs(ehcip);
368 
369 	(void) pci_report_pmcap(dip, PCI_PM_IDLESPEED, (void *)4000);
370 
371 	mutex_exit(&ehcip->ehci_int_mutex);
372 
373 	USB_DPRINTF_L4(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
374 	    "ehci_attach: dip = 0x%p done", (void *)dip);
375 
376 	return (DDI_SUCCESS);
377 }
378 
379 
380 /*
381  * ehci_detach:
382  *
383  * Description: Detach entry point is called by the Kernel.
384  *		Deallocates all resource allocated.
385  *		Unregisters the interrupt handler.
386  *
387  * Return     : DDI_SUCCESS / DDI_FAILURE
388  */
389 int
390 ehci_detach(dev_info_t		*dip,
391 	ddi_detach_cmd_t	cmd)
392 {
393 	ehci_state_t		*ehcip = ehci_obtain_state(dip);
394 
395 	USB_DPRINTF_L4(PRINT_MASK_ATTA, ehcip->ehci_log_hdl, "ehci_detach:");
396 
397 	switch (cmd) {
398 	case DDI_DETACH:
399 
400 		return (ehci_cleanup(ehcip));
401 	case DDI_SUSPEND:
402 
403 		return (ehci_cpr_suspend(ehcip));
404 	default:
405 
406 		return (DDI_FAILURE);
407 	}
408 }
409 
410 /*
411  * ehci_reset:
412  *
413  * Description:	Reset entry point - called by the Kernel
414  *		on the way down.
415  *		Toshiba Tecra laptop has been observed to hang
416  *		on soft reboot. The resetting ehci on the way
417  *		down solves the problem.
418  *
419  * Return	: DDI_SUCCESS / DDI_FAILURE
420  */
421 /* ARGSUSED */
422 static int
423 ehci_reset(dev_info_t *dip, ddi_reset_cmd_t cmd)
424 {
425 #if defined(__sparc)
426 	/*
427 	 * Don't reset the host controller on SPARC, for OBP needs Solaris
428 	 * to continue to provide keyboard support after shutdown of SPARC,
429 	 * or the keyboard connected to a USB 2.0 port will not work after
430 	 * that. The incomplete reset problem on Toshiba Tecra laptop is
431 	 * specific to Tecra laptop or BIOS, not present on SPARC. The SPARC
432 	 * OBP guarantees good reset behavior during startup.
433 	 */
434 	return (DDI_SUCCESS);
435 #else
436 	ehci_state_t		*ehcip = ehci_obtain_state(dip);
437 
438 	mutex_enter(&ehcip->ehci_int_mutex);
439 
440 	/*
441 	 * To reset the host controller, the HCRESET bit should be set to one.
442 	 * Software should not set this bit to a one when the HCHalted bit in
443 	 * the USBSTS register is a zero. Attempting to reset an actively
444 	 * running host controller will result in undefined behavior.
445 	 * see EHCI SPEC. for more information.
446 	 */
447 	if (!(Get_OpReg(ehci_status) & EHCI_STS_HOST_CTRL_HALTED)) {
448 
449 		/* Stop the EHCI host controller */
450 		Set_OpReg(ehci_command,
451 		    Get_OpReg(ehci_command) & ~EHCI_CMD_HOST_CTRL_RUN);
452 		/*
453 		 * When this bit is set to 0, the Host Controller completes the
454 		 * current and any actively pipelined transactions on the USB
455 		 * and then halts. The Host Controller must halt within 16
456 		 * micro-frames after software clears the Run bit.
457 		 * The HC Halted bit in the status register indicates when the
458 		 * Host Controller has finished its pending pipelined
459 		 * transactions and has entered the stopped state.
460 		 */
461 		drv_usecwait(EHCI_RESET_TIMEWAIT);
462 	}
463 
464 	/* Reset the EHCI host controller */
465 	Set_OpReg(ehci_command,
466 	    Get_OpReg(ehci_command) | EHCI_CMD_HOST_CTRL_RESET);
467 
468 	mutex_exit(&ehcip->ehci_int_mutex);
469 
470 	return (DDI_SUCCESS);
471 #endif
472 }
473 
474 /*
475  * ehci_info:
476  */
477 /* ARGSUSED */
478 static int
479 ehci_info(dev_info_t		*dip,
480 	ddi_info_cmd_t		infocmd,
481 	void			*arg,
482 	void			**result)
483 {
484 	dev_t			dev;
485 	ehci_state_t		*ehcip;
486 	int			instance;
487 	int			error = DDI_FAILURE;
488 
489 	switch (infocmd) {
490 	case DDI_INFO_DEVT2DEVINFO:
491 		dev = (dev_t)arg;
492 		instance = EHCI_UNIT(dev);
493 		ehcip = ddi_get_soft_state(ehci_statep, instance);
494 		if (ehcip != NULL) {
495 			*result = (void *)ehcip->ehci_dip;
496 			if (*result != NULL) {
497 				error = DDI_SUCCESS;
498 			}
499 		} else {
500 			*result = NULL;
501 		}
502 
503 		break;
504 	case DDI_INFO_DEVT2INSTANCE:
505 		dev = (dev_t)arg;
506 		instance = EHCI_UNIT(dev);
507 		*result = (void *)(uintptr_t)instance;
508 		error = DDI_SUCCESS;
509 		break;
510 	default:
511 		break;
512 	}
513 
514 	return (error);
515 }
516 
517 
518 /*
519  * EHCI CB_OPS entry points.
520  */
521 static dev_info_t *
522 ehci_get_dip(dev_t	dev)
523 {
524 	int		instance = EHCI_UNIT(dev);
525 	ehci_state_t	*ehcip = ddi_get_soft_state(ehci_statep, instance);
526 
527 	if (ehcip) {
528 
529 		return (ehcip->ehci_dip);
530 	} else {
531 
532 		return (NULL);
533 	}
534 }
535 
536 
537 static int
538 ehci_open(dev_t		*devp,
539 	int		flags,
540 	int		otyp,
541 	cred_t		*credp)
542 {
543 	dev_info_t	*dip = ehci_get_dip(*devp);
544 
545 	return (usba_hubdi_open(dip, devp, flags, otyp, credp));
546 }
547 
548 
549 static int
550 ehci_close(dev_t	dev,
551 	int		flag,
552 	int		otyp,
553 	cred_t		*credp)
554 {
555 	dev_info_t	*dip = ehci_get_dip(dev);
556 
557 	return (usba_hubdi_close(dip, dev, flag, otyp, credp));
558 }
559 
560 
561 static int
562 ehci_ioctl(dev_t	dev,
563 	int		cmd,
564 	intptr_t	arg,
565 	int		mode,
566 	cred_t		*credp,
567 	int		*rvalp)
568 {
569 	dev_info_t	*dip = ehci_get_dip(dev);
570 
571 	return (usba_hubdi_ioctl(dip,
572 	    dev, cmd, arg, mode, credp, rvalp));
573 }
574 
575 /*
576  * EHCI Interrupt Handler entry point.
577  */
578 
579 /*
580  * ehci_intr:
581  *
582  * EHCI (EHCI) interrupt handling routine.
583  */
584 uint_t
585 ehci_intr(caddr_t arg1, caddr_t arg2)
586 {
587 	uint_t			intr;
588 	ehci_state_t		*ehcip = (ehci_state_t *)arg1;
589 
590 	USB_DPRINTF_L4(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
591 	    "ehci_intr: Interrupt occurred, arg1 0x%p arg2 0x%p",
592 	    (void *)arg1, (void *)arg2);
593 
594 	/* Get the ehci global mutex */
595 	mutex_enter(&ehcip->ehci_int_mutex);
596 
597 	/* Any interrupt is not handled for the suspended device. */
598 	if (ehcip->ehci_hc_soft_state == EHCI_CTLR_SUSPEND_STATE) {
599 		mutex_exit(&ehcip->ehci_int_mutex);
600 
601 		return (DDI_INTR_UNCLAIMED);
602 	}
603 
604 	/*
605 	 * Now process the actual ehci interrupt events  that caused
606 	 * invocation of this ehci interrupt handler.
607 	 */
608 	intr = (Get_OpReg(ehci_status) & Get_OpReg(ehci_interrupt));
609 
610 	/* Update kstat values */
611 	ehci_do_intrs_stats(ehcip, intr);
612 
613 	/*
614 	 * We could have gotten a spurious interrupts. If so, do not
615 	 * claim it.  This is quite  possible on some  architectures
616 	 * where more than one PCI slots share the IRQs.  If so, the
617 	 * associated driver's interrupt routine may get called even
618 	 * if the interrupt is not meant for them.
619 	 *
620 	 * By unclaiming the interrupt, the other driver gets chance
621 	 * to service its interrupt.
622 	 */
623 	if (!intr) {
624 		mutex_exit(&ehcip->ehci_int_mutex);
625 
626 		return (DDI_INTR_UNCLAIMED);
627 	}
628 
629 	/* Acknowledge the interrupt */
630 	Set_OpReg(ehci_status, intr);
631 
632 	if (ehcip->ehci_hc_soft_state == EHCI_CTLR_ERROR_STATE) {
633 		mutex_exit(&ehcip->ehci_int_mutex);
634 
635 		return (DDI_INTR_CLAIMED);
636 	}
637 
638 	USB_DPRINTF_L3(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
639 	    "Interrupt status 0x%x", intr);
640 
641 	/*
642 	 * If necessary broadcast that an interrupt has occured.  This
643 	 * is only necessary during controller init.
644 	 */
645 	if (ehcip->ehci_flags & EHCI_CV_INTR) {
646 		ehcip->ehci_flags &= ~EHCI_CV_INTR;
647 		cv_broadcast(&ehcip->ehci_async_schedule_advance_cv);
648 	}
649 
650 	/* Check for Frame List Rollover */
651 	if (intr & EHCI_INTR_FRAME_LIST_ROLLOVER) {
652 		USB_DPRINTF_L3(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
653 		    "ehci_intr: Frame List Rollover");
654 
655 		ehci_handle_frame_list_rollover(ehcip);
656 
657 		/* VIA VT6202 looses EHCI_INTR_USB interrupts, workaround. */
658 		if ((ehcip->ehci_vendor_id == PCI_VENDOR_VIA) &&
659 		    (ehci_vt62x2_workaround & EHCI_VIA_LOST_INTERRUPTS)) {
660 			ehcip->ehci_missed_intr_sts |= EHCI_INTR_USB;
661 		}
662 	}
663 
664 	/* Check for Advance on Asynchronous Schedule */
665 	if (intr & EHCI_INTR_ASYNC_ADVANCE) {
666 		USB_DPRINTF_L3(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
667 		    "ehci_intr: Asynchronous Schedule Advance Notification");
668 
669 		/* Disable async list advance interrupt */
670 		Set_OpReg(ehci_interrupt,
671 		    (Get_OpReg(ehci_interrupt) & ~EHCI_INTR_ASYNC_ADVANCE));
672 
673 		/*
674 		 * Call cv_broadcast on every this interrupt to wakeup
675 		 * all the threads that are waiting the async list advance
676 		 * event.
677 		 */
678 		cv_broadcast(&ehcip->ehci_async_schedule_advance_cv);
679 	}
680 
681 	/* Always process completed itds */
682 	ehci_traverse_active_isoc_list(ehcip);
683 
684 	/*
685 	 * Check for any USB transaction completion notification. Also
686 	 * process any missed USB transaction completion interrupts.
687 	 */
688 	if ((intr & EHCI_INTR_USB) || (intr & EHCI_INTR_USB_ERROR) ||
689 	    (ehcip->ehci_missed_intr_sts & EHCI_INTR_USB) ||
690 	    (ehcip->ehci_missed_intr_sts & EHCI_INTR_USB_ERROR)) {
691 
692 		USB_DPRINTF_L3(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
693 		    "ehci_intr: USB Transaction Completion Notification");
694 
695 		/* Clear missed interrupts */
696 		if (ehcip->ehci_missed_intr_sts) {
697 			ehcip->ehci_missed_intr_sts = 0;
698 		}
699 
700 		/* Process completed qtds */
701 		ehci_traverse_active_qtd_list(ehcip);
702 	}
703 
704 	/* Process endpoint reclamation list */
705 	if (ehcip->ehci_reclaim_list) {
706 		ehci_handle_endpoint_reclaimation(ehcip);
707 	}
708 
709 	/* Check for Host System Error */
710 	if (intr & EHCI_INTR_HOST_SYSTEM_ERROR) {
711 		USB_DPRINTF_L2(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
712 		    "ehci_intr: Unrecoverable error");
713 
714 		ehci_handle_ue(ehcip);
715 	}
716 
717 	/*
718 	 * Read interrupt status register to make sure that any PIO
719 	 * store to clear the ISR has made it on the PCI bus before
720 	 * returning from its interrupt handler.
721 	 */
722 	(void) Get_OpReg(ehci_status);
723 
724 	/* Release the ehci global mutex */
725 	mutex_exit(&ehcip->ehci_int_mutex);
726 
727 	USB_DPRINTF_L4(PRINT_MASK_INTR,  ehcip->ehci_log_hdl,
728 	    "Interrupt handling completed");
729 
730 	return (DDI_INTR_CLAIMED);
731 }
732 
733 
734 /*
735  * EHCI HCDI entry points
736  *
737  * The Host Controller Driver Interfaces (HCDI) are the software interfaces
738  * between the Universal Serial Bus Layer (USBA) and the Host Controller
739  * Driver (HCD). The HCDI interfaces or entry points are subject to change.
740  */
741 
742 /*
743  * ehci_hcdi_pipe_open:
744  *
745  * Member of HCD Ops structure and called during client specific pipe open
746  * Add the pipe to the data structure representing the device and allocate
747  * bandwidth for the pipe if it is a interrupt or isochronous endpoint.
748  */
749 int
750 ehci_hcdi_pipe_open(
751 	usba_pipe_handle_data_t	*ph,
752 	usb_flags_t		flags)
753 {
754 	ehci_state_t		*ehcip = ehci_obtain_state(
755 	    ph->p_usba_device->usb_root_hub_dip);
756 	usb_ep_descr_t		*epdt = &ph->p_ep;
757 	int			rval, error = USB_SUCCESS;
758 	int			kmflag = (flags & USB_FLAGS_SLEEP) ?
759 	    KM_SLEEP : KM_NOSLEEP;
760 	uchar_t			smask = 0;
761 	uchar_t			cmask = 0;
762 	uint_t			pnode = 0;
763 	ehci_pipe_private_t	*pp;
764 
765 	USB_DPRINTF_L4(PRINT_MASK_HCDI, ehcip->ehci_log_hdl,
766 	    "ehci_hcdi_pipe_open: addr = 0x%x, ep%d",
767 	    ph->p_usba_device->usb_addr,
768 	    epdt->bEndpointAddress & USB_EP_NUM_MASK);
769 
770 	mutex_enter(&ehcip->ehci_int_mutex);
771 	rval = ehci_state_is_operational(ehcip);
772 	mutex_exit(&ehcip->ehci_int_mutex);
773 
774 	if (rval != USB_SUCCESS) {
775 
776 		return (rval);
777 	}
778 
779 	/*
780 	 * Check and handle root hub pipe open.
781 	 */
782 	if (ph->p_usba_device->usb_addr == ROOT_HUB_ADDR) {
783 
784 		mutex_enter(&ehcip->ehci_int_mutex);
785 		error = ehci_handle_root_hub_pipe_open(ph, flags);
786 		mutex_exit(&ehcip->ehci_int_mutex);
787 
788 		return (error);
789 	}
790 
791 	/*
792 	 * Opening of other pipes excluding root hub pipe are
793 	 * handled below. Check whether pipe is already opened.
794 	 */
795 	if (ph->p_hcd_private) {
796 		USB_DPRINTF_L2(PRINT_MASK_HCDI, ehcip->ehci_log_hdl,
797 		    "ehci_hcdi_pipe_open: Pipe is already opened");
798 
799 		return (USB_FAILURE);
800 	}
801 
802 	/*
803 	 * A portion of the bandwidth is reserved for the non-periodic
804 	 * transfers, i.e control and bulk transfers in each of one
805 	 * millisecond frame period & usually it will be 20% of frame
806 	 * period. Hence there is no need to check for the available
807 	 * bandwidth before adding the control or bulk endpoints.
808 	 *
809 	 * There is a need to check for the available bandwidth before
810 	 * adding the periodic transfers, i.e interrupt & isochronous,
811 	 * since all these periodic transfers are guaranteed transfers.
812 	 * Usually 80% of the total frame time is reserved for periodic
813 	 * transfers.
814 	 */
815 	if (EHCI_PERIODIC_ENDPOINT(epdt)) {
816 
817 		mutex_enter(&ehcip->ehci_int_mutex);
818 		mutex_enter(&ph->p_mutex);
819 
820 		error = ehci_allocate_bandwidth(ehcip,
821 		    ph, &pnode, &smask, &cmask);
822 
823 		if (error != USB_SUCCESS) {
824 
825 			USB_DPRINTF_L2(PRINT_MASK_HCDI, ehcip->ehci_log_hdl,
826 			    "ehci_hcdi_pipe_open: Bandwidth allocation failed");
827 
828 			mutex_exit(&ph->p_mutex);
829 			mutex_exit(&ehcip->ehci_int_mutex);
830 
831 			return (error);
832 		}
833 
834 		mutex_exit(&ph->p_mutex);
835 		mutex_exit(&ehcip->ehci_int_mutex);
836 	}
837 
838 	/* Create the HCD pipe private structure */
839 	pp = kmem_zalloc(sizeof (ehci_pipe_private_t), kmflag);
840 
841 	/*
842 	 * Return failure if ehci pipe private
843 	 * structure allocation fails.
844 	 */
845 	if (pp == NULL) {
846 
847 		mutex_enter(&ehcip->ehci_int_mutex);
848 
849 		/* Deallocate bandwidth */
850 		if (EHCI_PERIODIC_ENDPOINT(epdt)) {
851 
852 			mutex_enter(&ph->p_mutex);
853 			ehci_deallocate_bandwidth(ehcip,
854 			    ph, pnode, smask, cmask);
855 			mutex_exit(&ph->p_mutex);
856 		}
857 
858 		mutex_exit(&ehcip->ehci_int_mutex);
859 
860 		return (USB_NO_RESOURCES);
861 	}
862 
863 	mutex_enter(&ehcip->ehci_int_mutex);
864 
865 	/* Save periodic nodes */
866 	pp->pp_pnode = pnode;
867 
868 	/* Save start and complete split mask values */
869 	pp->pp_smask = smask;
870 	pp->pp_cmask = cmask;
871 
872 	/* Create prototype for xfer completion condition variable */
873 	cv_init(&pp->pp_xfer_cmpl_cv, NULL, CV_DRIVER, NULL);
874 
875 	/* Set the state of pipe as idle */
876 	pp->pp_state = EHCI_PIPE_STATE_IDLE;
877 
878 	/* Store a pointer to the pipe handle */
879 	pp->pp_pipe_handle = ph;
880 
881 	mutex_enter(&ph->p_mutex);
882 
883 	/* Store the pointer in the pipe handle */
884 	ph->p_hcd_private = (usb_opaque_t)pp;
885 
886 	/* Store a copy of the pipe policy */
887 	bcopy(&ph->p_policy, &pp->pp_policy, sizeof (usb_pipe_policy_t));
888 
889 	mutex_exit(&ph->p_mutex);
890 
891 	/* Allocate the host controller endpoint descriptor */
892 	pp->pp_qh = ehci_alloc_qh(ehcip, ph, NULL);
893 
894 	/* Initialize the halting flag */
895 	pp->pp_halt_state = EHCI_HALT_STATE_FREE;
896 
897 	/* Create prototype for halt completion condition variable */
898 	cv_init(&pp->pp_halt_cmpl_cv, NULL, CV_DRIVER, NULL);
899 
900 	/* Isoch does not use QH, so ignore this */
901 	if ((pp->pp_qh == NULL) && !(EHCI_ISOC_ENDPOINT(epdt))) {
902 		ASSERT(pp->pp_qh == NULL);
903 
904 		USB_DPRINTF_L2(PRINT_MASK_HCDI, ehcip->ehci_log_hdl,
905 		    "ehci_hcdi_pipe_open: QH allocation failed");
906 
907 		mutex_enter(&ph->p_mutex);
908 
909 		/* Deallocate bandwidth */
910 		if (EHCI_PERIODIC_ENDPOINT(epdt)) {
911 
912 			ehci_deallocate_bandwidth(ehcip,
913 			    ph, pnode, smask, cmask);
914 		}
915 
916 		/* Destroy the xfer completion condition variable */
917 		cv_destroy(&pp->pp_xfer_cmpl_cv);
918 
919 		/*
920 		 * Deallocate the hcd private portion
921 		 * of the pipe handle.
922 		 */
923 		kmem_free(ph->p_hcd_private, sizeof (ehci_pipe_private_t));
924 
925 		/*
926 		 * Set the private structure in the
927 		 * pipe handle equal to NULL.
928 		 */
929 		ph->p_hcd_private = NULL;
930 
931 		mutex_exit(&ph->p_mutex);
932 		mutex_exit(&ehcip->ehci_int_mutex);
933 
934 		return (USB_NO_RESOURCES);
935 	}
936 
937 	/*
938 	 * Isoch does not use QH so no need to
939 	 * restore data toggle or insert QH
940 	 */
941 	if (!(EHCI_ISOC_ENDPOINT(epdt))) {
942 		/* Restore the data toggle information */
943 		ehci_restore_data_toggle(ehcip, ph);
944 	}
945 
946 	/*
947 	 * Insert the endpoint onto the host controller's
948 	 * appropriate endpoint list. The host controller
949 	 * will not schedule this endpoint and will not have
950 	 * any QTD's to process.  It will also update the pipe count.
951 	 */
952 	ehci_insert_qh(ehcip, ph);
953 
954 	USB_DPRINTF_L4(PRINT_MASK_HCDI, ehcip->ehci_log_hdl,
955 	    "ehci_hcdi_pipe_open: ph = 0x%p", (void *)ph);
956 
957 	ehcip->ehci_open_pipe_count++;
958 
959 	mutex_exit(&ehcip->ehci_int_mutex);
960 
961 	return (USB_SUCCESS);
962 }
963 
964 
965 /*
966  * ehci_hcdi_pipe_close:
967  *
968  * Member of HCD Ops structure and called during the client  specific pipe
969  * close. Remove the pipe and the data structure representing the device.
970  * Deallocate  bandwidth for the pipe if it is a interrupt or isochronous
971  * endpoint.
972  */
973 /* ARGSUSED */
974 int
975 ehci_hcdi_pipe_close(
976 	usba_pipe_handle_data_t	*ph,
977 	usb_flags_t		flags)
978 {
979 	ehci_state_t		*ehcip = ehci_obtain_state(
980 	    ph->p_usba_device->usb_root_hub_dip);
981 	ehci_pipe_private_t	*pp = (ehci_pipe_private_t *)ph->p_hcd_private;
982 	usb_ep_descr_t		*eptd = &ph->p_ep;
983 	int			error = USB_SUCCESS;
984 
985 	USB_DPRINTF_L4(PRINT_MASK_HCDI, ehcip->ehci_log_hdl,
986 	    "ehci_hcdi_pipe_close: addr = 0x%x, ep%d",
987 	    ph->p_usba_device->usb_addr,
988 	    eptd->bEndpointAddress & USB_EP_NUM_MASK);
989 
990 	/* Check and handle root hub pipe close */
991 	if (ph->p_usba_device->usb_addr == ROOT_HUB_ADDR) {
992 
993 		mutex_enter(&ehcip->ehci_int_mutex);
994 		error = ehci_handle_root_hub_pipe_close(ph);
995 		mutex_exit(&ehcip->ehci_int_mutex);
996 
997 		return (error);
998 	}
999 
1000 	ASSERT(ph->p_hcd_private != NULL);
1001 
1002 	mutex_enter(&ehcip->ehci_int_mutex);
1003 
1004 	/* Set pipe state to pipe close */
1005 	pp->pp_state = EHCI_PIPE_STATE_CLOSE;
1006 
1007 	ehci_pipe_cleanup(ehcip, ph);
1008 
1009 	/*
1010 	 * Remove the endpoint descriptor from Host
1011 	 * Controller's appropriate endpoint list.
1012 	 */
1013 	ehci_remove_qh(ehcip, pp, B_TRUE);
1014 
1015 	/* Deallocate bandwidth */
1016 	if (EHCI_PERIODIC_ENDPOINT(eptd)) {
1017 
1018 		mutex_enter(&ph->p_mutex);
1019 		ehci_deallocate_bandwidth(ehcip, ph, pp->pp_pnode,
1020 		    pp->pp_smask, pp->pp_cmask);
1021 		mutex_exit(&ph->p_mutex);
1022 	}
1023 
1024 	mutex_enter(&ph->p_mutex);
1025 
1026 	/* Destroy the xfer completion condition variable */
1027 	cv_destroy(&pp->pp_xfer_cmpl_cv);
1028 
1029 
1030 	/* Destory halt completion condition variable */
1031 	cv_destroy(&pp->pp_halt_cmpl_cv);
1032 
1033 	/*
1034 	 * Deallocate the hcd private portion
1035 	 * of the pipe handle.
1036 	 */
1037 	kmem_free(ph->p_hcd_private, sizeof (ehci_pipe_private_t));
1038 	ph->p_hcd_private = NULL;
1039 
1040 	mutex_exit(&ph->p_mutex);
1041 
1042 	USB_DPRINTF_L4(PRINT_MASK_HCDI, ehcip->ehci_log_hdl,
1043 	    "ehci_hcdi_pipe_close: ph = 0x%p", (void *)ph);
1044 
1045 	ehcip->ehci_open_pipe_count--;
1046 
1047 	mutex_exit(&ehcip->ehci_int_mutex);
1048 
1049 	return (error);
1050 }
1051 
1052 
1053 /*
1054  * ehci_hcdi_pipe_reset:
1055  */
1056 /* ARGSUSED */
1057 int
1058 ehci_hcdi_pipe_reset(
1059 	usba_pipe_handle_data_t	*ph,
1060 	usb_flags_t		usb_flags)
1061 {
1062 	ehci_state_t		*ehcip = ehci_obtain_state(
1063 	    ph->p_usba_device->usb_root_hub_dip);
1064 	ehci_pipe_private_t	*pp = (ehci_pipe_private_t *)ph->p_hcd_private;
1065 	int			error = USB_SUCCESS;
1066 
1067 	USB_DPRINTF_L4(PRINT_MASK_HCDI, ehcip->ehci_log_hdl,
1068 	    "ehci_hcdi_pipe_reset:");
1069 
1070 	/*
1071 	 * Check and handle root hub pipe reset.
1072 	 */
1073 	if (ph->p_usba_device->usb_addr == ROOT_HUB_ADDR) {
1074 
1075 		error = ehci_handle_root_hub_pipe_reset(ph, usb_flags);
1076 		return (error);
1077 	}
1078 
1079 	mutex_enter(&ehcip->ehci_int_mutex);
1080 
1081 	/* Set pipe state to pipe reset */
1082 	pp->pp_state = EHCI_PIPE_STATE_RESET;
1083 
1084 	ehci_pipe_cleanup(ehcip, ph);
1085 
1086 	mutex_exit(&ehcip->ehci_int_mutex);
1087 
1088 	return (error);
1089 }
1090 
1091 /*
1092  * ehci_hcdi_pipe_ctrl_xfer:
1093  */
1094 int
1095 ehci_hcdi_pipe_ctrl_xfer(
1096 	usba_pipe_handle_data_t	*ph,
1097 	usb_ctrl_req_t		*ctrl_reqp,
1098 	usb_flags_t		usb_flags)
1099 {
1100 	ehci_state_t		*ehcip = ehci_obtain_state(
1101 	    ph->p_usba_device->usb_root_hub_dip);
1102 	ehci_pipe_private_t	*pp = (ehci_pipe_private_t *)ph->p_hcd_private;
1103 	int			rval;
1104 	int			error = USB_SUCCESS;
1105 	ehci_trans_wrapper_t	*tw;
1106 
1107 	USB_DPRINTF_L4(PRINT_MASK_HCDI, ehcip->ehci_log_hdl,
1108 	    "ehci_hcdi_pipe_ctrl_xfer: ph = 0x%p reqp = 0x%p flags = %x",
1109 	    (void *)ph, (void *)ctrl_reqp, usb_flags);
1110 
1111 	mutex_enter(&ehcip->ehci_int_mutex);
1112 	rval = ehci_state_is_operational(ehcip);
1113 	mutex_exit(&ehcip->ehci_int_mutex);
1114 
1115 	if (rval != USB_SUCCESS) {
1116 
1117 		return (rval);
1118 	}
1119 
1120 	/*
1121 	 * Check and handle root hub control request.
1122 	 */
1123 	if (ph->p_usba_device->usb_addr == ROOT_HUB_ADDR) {
1124 
1125 		error = ehci_handle_root_hub_request(ehcip, ph, ctrl_reqp);
1126 
1127 		return (error);
1128 	}
1129 
1130 	mutex_enter(&ehcip->ehci_int_mutex);
1131 
1132 	/*
1133 	 *  Check whether pipe is in halted state.
1134 	 */
1135 	if (pp->pp_state == EHCI_PIPE_STATE_ERROR) {
1136 
1137 		USB_DPRINTF_L2(PRINT_MASK_HCDI, ehcip->ehci_log_hdl,
1138 		    "ehci_hcdi_pipe_ctrl_xfer: "
1139 		    "Pipe is in error state, need pipe reset to continue");
1140 
1141 		mutex_exit(&ehcip->ehci_int_mutex);
1142 
1143 		return (USB_FAILURE);
1144 	}
1145 
1146 	/* Allocate a transfer wrapper */
1147 	if ((tw = ehci_allocate_ctrl_resources(ehcip, pp, ctrl_reqp,
1148 	    usb_flags)) == NULL) {
1149 
1150 		error = USB_NO_RESOURCES;
1151 	} else {
1152 		/* Insert the qtd's on the endpoint */
1153 		ehci_insert_ctrl_req(ehcip, ph, ctrl_reqp, tw, usb_flags);
1154 	}
1155 
1156 	mutex_exit(&ehcip->ehci_int_mutex);
1157 
1158 	return (error);
1159 }
1160 
1161 
1162 /*
1163  * ehci_hcdi_bulk_transfer_size:
1164  *
1165  * Return maximum bulk transfer size
1166  */
1167 
1168 /* ARGSUSED */
1169 int
1170 ehci_hcdi_bulk_transfer_size(
1171 	usba_device_t	*usba_device,
1172 	size_t		*size)
1173 {
1174 	ehci_state_t	*ehcip = ehci_obtain_state(
1175 	    usba_device->usb_root_hub_dip);
1176 	int		rval;
1177 
1178 	USB_DPRINTF_L4(PRINT_MASK_HCDI, ehcip->ehci_log_hdl,
1179 	    "ehci_hcdi_bulk_transfer_size:");
1180 
1181 	mutex_enter(&ehcip->ehci_int_mutex);
1182 	rval = ehci_state_is_operational(ehcip);
1183 	mutex_exit(&ehcip->ehci_int_mutex);
1184 
1185 	if (rval != USB_SUCCESS) {
1186 
1187 		return (rval);
1188 	}
1189 
1190 	/* VIA VT6202 may not handle bigger xfers well, workaround. */
1191 	if ((ehcip->ehci_vendor_id == PCI_VENDOR_VIA) &&
1192 	    (ehci_vt62x2_workaround & EHCI_VIA_REDUCED_MAX_BULK_XFER_SIZE)) {
1193 		*size = EHCI_VIA_MAX_BULK_XFER_SIZE;
1194 	} else {
1195 		*size = EHCI_MAX_BULK_XFER_SIZE;
1196 	}
1197 
1198 	return (USB_SUCCESS);
1199 }
1200 
1201 
1202 /*
1203  * ehci_hcdi_pipe_bulk_xfer:
1204  */
1205 int
1206 ehci_hcdi_pipe_bulk_xfer(
1207 	usba_pipe_handle_data_t	*ph,
1208 	usb_bulk_req_t		*bulk_reqp,
1209 	usb_flags_t		usb_flags)
1210 {
1211 	ehci_state_t		*ehcip = ehci_obtain_state(
1212 	    ph->p_usba_device->usb_root_hub_dip);
1213 	ehci_pipe_private_t	*pp = (ehci_pipe_private_t *)ph->p_hcd_private;
1214 	int			rval, error = USB_SUCCESS;
1215 	ehci_trans_wrapper_t	*tw;
1216 
1217 	USB_DPRINTF_L4(PRINT_MASK_HCDI, ehcip->ehci_log_hdl,
1218 	    "ehci_hcdi_pipe_bulk_xfer: ph = 0x%p reqp = 0x%p flags = %x",
1219 	    (void *)ph, (void *)bulk_reqp, usb_flags);
1220 
1221 	mutex_enter(&ehcip->ehci_int_mutex);
1222 	rval = ehci_state_is_operational(ehcip);
1223 
1224 	if (rval != USB_SUCCESS) {
1225 		mutex_exit(&ehcip->ehci_int_mutex);
1226 
1227 		return (rval);
1228 	}
1229 
1230 	/*
1231 	 *  Check whether pipe is in halted state.
1232 	 */
1233 	if (pp->pp_state == EHCI_PIPE_STATE_ERROR) {
1234 
1235 		USB_DPRINTF_L2(PRINT_MASK_HCDI, ehcip->ehci_log_hdl,
1236 		    "ehci_hcdi_pipe_bulk_xfer:"
1237 		    "Pipe is in error state, need pipe reset to continue");
1238 
1239 		mutex_exit(&ehcip->ehci_int_mutex);
1240 
1241 		return (USB_FAILURE);
1242 	}
1243 
1244 	/* Allocate a transfer wrapper */
1245 	if ((tw = ehci_allocate_bulk_resources(ehcip, pp, bulk_reqp,
1246 	    usb_flags)) == NULL) {
1247 
1248 		error = USB_NO_RESOURCES;
1249 	} else {
1250 		/* Add the QTD into the Host Controller's bulk list */
1251 		ehci_insert_bulk_req(ehcip, ph, bulk_reqp, tw, usb_flags);
1252 	}
1253 
1254 	mutex_exit(&ehcip->ehci_int_mutex);
1255 
1256 	return (error);
1257 }
1258 
1259 
1260 /*
1261  * ehci_hcdi_pipe_intr_xfer:
1262  */
1263 int
1264 ehci_hcdi_pipe_intr_xfer(
1265 	usba_pipe_handle_data_t	*ph,
1266 	usb_intr_req_t		*intr_reqp,
1267 	usb_flags_t		usb_flags)
1268 {
1269 	ehci_state_t		*ehcip = ehci_obtain_state(
1270 	    ph->p_usba_device->usb_root_hub_dip);
1271 	int			pipe_dir, rval, error = USB_SUCCESS;
1272 	ehci_trans_wrapper_t	*tw;
1273 
1274 	USB_DPRINTF_L4(PRINT_MASK_HCDI, ehcip->ehci_log_hdl,
1275 	    "ehci_hcdi_pipe_intr_xfer: ph = 0x%p reqp = 0x%p flags = %x",
1276 	    (void *)ph, (void *)intr_reqp, usb_flags);
1277 
1278 	mutex_enter(&ehcip->ehci_int_mutex);
1279 	rval = ehci_state_is_operational(ehcip);
1280 
1281 	if (rval != USB_SUCCESS) {
1282 		mutex_exit(&ehcip->ehci_int_mutex);
1283 
1284 		return (rval);
1285 	}
1286 
1287 	/* Get the pipe direction */
1288 	pipe_dir = ph->p_ep.bEndpointAddress & USB_EP_DIR_MASK;
1289 
1290 	if (pipe_dir == USB_EP_DIR_IN) {
1291 		error = ehci_start_periodic_pipe_polling(ehcip, ph,
1292 		    (usb_opaque_t)intr_reqp, usb_flags);
1293 	} else {
1294 		/* Allocate transaction resources */
1295 		if ((tw = ehci_allocate_intr_resources(ehcip, ph,
1296 		    intr_reqp, usb_flags)) == NULL) {
1297 
1298 			error = USB_NO_RESOURCES;
1299 		} else {
1300 			ehci_insert_intr_req(ehcip,
1301 			    (ehci_pipe_private_t *)ph->p_hcd_private,
1302 			    tw, usb_flags);
1303 		}
1304 	}
1305 
1306 	mutex_exit(&ehcip->ehci_int_mutex);
1307 
1308 	return (error);
1309 }
1310 
1311 /*
1312  * ehci_hcdi_pipe_stop_intr_polling()
1313  */
1314 int
1315 ehci_hcdi_pipe_stop_intr_polling(
1316 	usba_pipe_handle_data_t	*ph,
1317 	usb_flags_t		flags)
1318 {
1319 	ehci_state_t		*ehcip = ehci_obtain_state(
1320 	    ph->p_usba_device->usb_root_hub_dip);
1321 	int			error = USB_SUCCESS;
1322 
1323 	USB_DPRINTF_L4(PRINT_MASK_HCDI, ehcip->ehci_log_hdl,
1324 	    "ehci_hcdi_pipe_stop_intr_polling: ph = 0x%p fl = 0x%x",
1325 	    (void *)ph, flags);
1326 
1327 	mutex_enter(&ehcip->ehci_int_mutex);
1328 
1329 	error = ehci_stop_periodic_pipe_polling(ehcip, ph, flags);
1330 
1331 	mutex_exit(&ehcip->ehci_int_mutex);
1332 
1333 	return (error);
1334 }
1335 
1336 
1337 /*
1338  * ehci_hcdi_get_current_frame_number:
1339  *
1340  * Get the current usb frame number.
1341  * Return whether the request is handled successfully.
1342  */
1343 int
1344 ehci_hcdi_get_current_frame_number(
1345 	usba_device_t		*usba_device,
1346 	usb_frame_number_t	*frame_number)
1347 {
1348 	ehci_state_t		*ehcip = ehci_obtain_state(
1349 	    usba_device->usb_root_hub_dip);
1350 	int			rval;
1351 
1352 	ehcip = ehci_obtain_state(usba_device->usb_root_hub_dip);
1353 
1354 	mutex_enter(&ehcip->ehci_int_mutex);
1355 	rval = ehci_state_is_operational(ehcip);
1356 
1357 	if (rval != USB_SUCCESS) {
1358 		mutex_exit(&ehcip->ehci_int_mutex);
1359 
1360 		return (rval);
1361 	}
1362 
1363 	*frame_number = ehci_get_current_frame_number(ehcip);
1364 
1365 	mutex_exit(&ehcip->ehci_int_mutex);
1366 
1367 	USB_DPRINTF_L4(PRINT_MASK_HCDI, ehcip->ehci_log_hdl,
1368 	    "ehci_hcdi_get_current_frame_number: "
1369 	    "Current frame number 0x%llx", (unsigned long long)(*frame_number));
1370 
1371 	return (rval);
1372 }
1373 
1374 
1375 /*
1376  * ehci_hcdi_get_max_isoc_pkts:
1377  *
1378  * Get maximum isochronous packets per usb isochronous request.
1379  * Return whether the request is handled successfully.
1380  */
1381 int
1382 ehci_hcdi_get_max_isoc_pkts(
1383 	usba_device_t	*usba_device,
1384 	uint_t		*max_isoc_pkts_per_request)
1385 {
1386 	ehci_state_t		*ehcip = ehci_obtain_state(
1387 	    usba_device->usb_root_hub_dip);
1388 	int			rval;
1389 
1390 	mutex_enter(&ehcip->ehci_int_mutex);
1391 	rval = ehci_state_is_operational(ehcip);
1392 	mutex_exit(&ehcip->ehci_int_mutex);
1393 
1394 	if (rval != USB_SUCCESS) {
1395 
1396 		return (rval);
1397 	}
1398 
1399 	*max_isoc_pkts_per_request = EHCI_MAX_ISOC_PKTS_PER_XFER;
1400 
1401 	USB_DPRINTF_L4(PRINT_MASK_HCDI, ehcip->ehci_log_hdl,
1402 	    "ehci_hcdi_get_max_isoc_pkts: maximum isochronous"
1403 	    "packets per usb isochronous request = 0x%x",
1404 	    *max_isoc_pkts_per_request);
1405 
1406 	return (rval);
1407 }
1408 
1409 
1410 /*
1411  * ehci_hcdi_pipe_isoc_xfer:
1412  */
1413 int
1414 ehci_hcdi_pipe_isoc_xfer(
1415 	usba_pipe_handle_data_t	*ph,
1416 	usb_isoc_req_t		*isoc_reqp,
1417 	usb_flags_t		usb_flags)
1418 {
1419 	ehci_state_t		*ehcip = ehci_obtain_state(
1420 	    ph->p_usba_device->usb_root_hub_dip);
1421 
1422 	int			pipe_dir, rval;
1423 	ehci_isoc_xwrapper_t	*itw;
1424 
1425 	USB_DPRINTF_L4(PRINT_MASK_HCDI, ehcip->ehci_log_hdl,
1426 	    "ehci_hcdi_pipe_isoc_xfer: ph = 0x%p reqp = 0x%p flags = 0x%x",
1427 	    (void *)ph, (void *)isoc_reqp, usb_flags);
1428 
1429 	mutex_enter(&ehcip->ehci_int_mutex);
1430 	rval = ehci_state_is_operational(ehcip);
1431 
1432 	if (rval != USB_SUCCESS) {
1433 		mutex_exit(&ehcip->ehci_int_mutex);
1434 
1435 		return (rval);
1436 	}
1437 
1438 	/* Get the isochronous pipe direction */
1439 	pipe_dir = ph->p_ep.bEndpointAddress & USB_EP_DIR_MASK;
1440 
1441 	if (pipe_dir == USB_EP_DIR_IN) {
1442 		rval = ehci_start_periodic_pipe_polling(ehcip, ph,
1443 		    (usb_opaque_t)isoc_reqp, usb_flags);
1444 	} else {
1445 		/* Allocate transaction resources */
1446 		if ((itw = ehci_allocate_isoc_resources(ehcip, ph,
1447 		    isoc_reqp, usb_flags)) == NULL) {
1448 			rval = USB_NO_RESOURCES;
1449 		} else {
1450 			rval = ehci_insert_isoc_req(ehcip,
1451 			    (ehci_pipe_private_t *)ph->p_hcd_private,
1452 			    itw, usb_flags);
1453 		}
1454 	}
1455 
1456 	mutex_exit(&ehcip->ehci_int_mutex);
1457 
1458 	return (rval);
1459 }
1460 
1461 
1462 /*
1463  * ehci_hcdi_pipe_stop_isoc_polling()
1464  */
1465 /*ARGSUSED*/
1466 int
1467 ehci_hcdi_pipe_stop_isoc_polling(
1468 	usba_pipe_handle_data_t	*ph,
1469 	usb_flags_t		flags)
1470 {
1471 	ehci_state_t		*ehcip = ehci_obtain_state(
1472 	    ph->p_usba_device->usb_root_hub_dip);
1473 	int			rval;
1474 
1475 	USB_DPRINTF_L4(PRINT_MASK_HCDI, ehcip->ehci_log_hdl,
1476 	    "ehci_hcdi_pipe_stop_isoc_polling: ph = 0x%p fl = 0x%x",
1477 	    (void *)ph, flags);
1478 
1479 	mutex_enter(&ehcip->ehci_int_mutex);
1480 	rval = ehci_state_is_operational(ehcip);
1481 
1482 	if (rval != USB_SUCCESS) {
1483 		mutex_exit(&ehcip->ehci_int_mutex);
1484 
1485 		return (rval);
1486 	}
1487 
1488 	rval = ehci_stop_periodic_pipe_polling(ehcip, ph, flags);
1489 
1490 	mutex_exit(&ehcip->ehci_int_mutex);
1491 
1492 	return (rval);
1493 }
1494