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