| 1 | // SPDX-License-Identifier: GPL-2.0+ | 
|---|
| 2 | /* | 
|---|
| 3 | * EHCI HCD (Host Controller Driver) PCI Bus Glue. | 
|---|
| 4 | * | 
|---|
| 5 | * Copyright (c) 2000-2004 by David Brownell | 
|---|
| 6 | */ | 
|---|
| 7 |  | 
|---|
| 8 | #include <linux/kernel.h> | 
|---|
| 9 | #include <linux/module.h> | 
|---|
| 10 | #include <linux/pci.h> | 
|---|
| 11 | #include <linux/usb.h> | 
|---|
| 12 | #include <linux/usb/hcd.h> | 
|---|
| 13 |  | 
|---|
| 14 | #include "ehci.h" | 
|---|
| 15 | #include "pci-quirks.h" | 
|---|
| 16 |  | 
|---|
| 17 | #define DRIVER_DESC "EHCI PCI platform driver" | 
|---|
| 18 |  | 
|---|
| 19 | static const char hcd_name[] = "ehci-pci"; | 
|---|
| 20 |  | 
|---|
| 21 | /* defined here to avoid adding to pci_ids.h for single instance use */ | 
|---|
| 22 | #define PCI_DEVICE_ID_INTEL_CE4100_USB	0x2e70 | 
|---|
| 23 |  | 
|---|
| 24 | #define PCI_VENDOR_ID_ASPEED		0x1a03 | 
|---|
| 25 | #define PCI_DEVICE_ID_ASPEED_EHCI	0x2603 | 
|---|
| 26 |  | 
|---|
| 27 | /*-------------------------------------------------------------------------*/ | 
|---|
| 28 | #define PCI_DEVICE_ID_INTEL_QUARK_X1000_SOC		0x0939 | 
|---|
| 29 | static inline bool is_intel_quark_x1000(struct pci_dev *pdev) | 
|---|
| 30 | { | 
|---|
| 31 | return pdev->vendor == PCI_VENDOR_ID_INTEL && | 
|---|
| 32 | pdev->device == PCI_DEVICE_ID_INTEL_QUARK_X1000_SOC; | 
|---|
| 33 | } | 
|---|
| 34 |  | 
|---|
| 35 | /* | 
|---|
| 36 | * This is the list of PCI IDs for the devices that have EHCI USB class and | 
|---|
| 37 | * specific drivers for that. One of the example is a ChipIdea device installed | 
|---|
| 38 | * on some Intel MID platforms. | 
|---|
| 39 | */ | 
|---|
| 40 | static const struct pci_device_id bypass_pci_id_table[] = { | 
|---|
| 41 | /* ChipIdea on Intel MID platform */ | 
|---|
| 42 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0811), }, | 
|---|
| 43 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0829), }, | 
|---|
| 44 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe006), }, | 
|---|
| 45 | {} | 
|---|
| 46 | }; | 
|---|
| 47 |  | 
|---|
| 48 | static inline bool is_bypassed_id(struct pci_dev *pdev) | 
|---|
| 49 | { | 
|---|
| 50 | return !!pci_match_id(ids: bypass_pci_id_table, dev: pdev); | 
|---|
| 51 | } | 
|---|
| 52 |  | 
|---|
| 53 | /* | 
|---|
| 54 | * 0x84 is the offset of in/out threshold register, | 
|---|
| 55 | * and it is the same offset as the register of 'hostpc'. | 
|---|
| 56 | */ | 
|---|
| 57 | #define	intel_quark_x1000_insnreg01	hostpc | 
|---|
| 58 |  | 
|---|
| 59 | /* Maximum usable threshold value is 0x7f dwords for both IN and OUT */ | 
|---|
| 60 | #define INTEL_QUARK_X1000_EHCI_MAX_THRESHOLD	0x007f007f | 
|---|
| 61 |  | 
|---|
| 62 | /* called after powerup, by probe or system-pm "wakeup" */ | 
|---|
| 63 | static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev) | 
|---|
| 64 | { | 
|---|
| 65 | int			retval; | 
|---|
| 66 |  | 
|---|
| 67 | /* we expect static quirk code to handle the "extended capabilities" | 
|---|
| 68 | * (currently just BIOS handoff) allowed starting with EHCI 0.96 | 
|---|
| 69 | */ | 
|---|
| 70 |  | 
|---|
| 71 | /* PCI Memory-Write-Invalidate cycle support is optional (uncommon) */ | 
|---|
| 72 | retval = pci_set_mwi(dev: pdev); | 
|---|
| 73 | if (!retval) | 
|---|
| 74 | ehci_dbg(ehci, "MWI active\n"); | 
|---|
| 75 |  | 
|---|
| 76 | /* Reset the threshold limit */ | 
|---|
| 77 | if (is_intel_quark_x1000(pdev)) { | 
|---|
| 78 | /* | 
|---|
| 79 | * For the Intel QUARK X1000, raise the I/O threshold to the | 
|---|
| 80 | * maximum usable value in order to improve performance. | 
|---|
| 81 | */ | 
|---|
| 82 | ehci_writel(ehci, INTEL_QUARK_X1000_EHCI_MAX_THRESHOLD, | 
|---|
| 83 | regs: ehci->regs->intel_quark_x1000_insnreg01); | 
|---|
| 84 | } | 
|---|
| 85 |  | 
|---|
| 86 | return 0; | 
|---|
| 87 | } | 
|---|
| 88 |  | 
|---|
| 89 | /* called during probe() after chip reset completes */ | 
|---|
| 90 | static int ehci_pci_setup(struct usb_hcd *hcd) | 
|---|
| 91 | { | 
|---|
| 92 | struct ehci_hcd		*ehci = hcd_to_ehci(hcd); | 
|---|
| 93 | struct pci_dev		*pdev = to_pci_dev(hcd->self.controller); | 
|---|
| 94 | u32			temp; | 
|---|
| 95 | int			retval; | 
|---|
| 96 |  | 
|---|
| 97 | ehci->caps = hcd->regs; | 
|---|
| 98 |  | 
|---|
| 99 | /* | 
|---|
| 100 | * ehci_init() causes memory for DMA transfers to be | 
|---|
| 101 | * allocated.  Thus, any vendor-specific workarounds based on | 
|---|
| 102 | * limiting the type of memory used for DMA transfers must | 
|---|
| 103 | * happen before ehci_setup() is called. | 
|---|
| 104 | * | 
|---|
| 105 | * Most other workarounds can be done either before or after | 
|---|
| 106 | * init and reset; they are located here too. | 
|---|
| 107 | */ | 
|---|
| 108 | switch (pdev->vendor) { | 
|---|
| 109 | case PCI_VENDOR_ID_TOSHIBA_2: | 
|---|
| 110 | /* celleb's companion chip */ | 
|---|
| 111 | if (pdev->device == 0x01b5) { | 
|---|
| 112 | #ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO | 
|---|
| 113 | ehci->big_endian_mmio = 1; | 
|---|
| 114 | #else | 
|---|
| 115 | ehci_warn(ehci, | 
|---|
| 116 | "unsupported big endian Toshiba quirk\n"); | 
|---|
| 117 | #endif | 
|---|
| 118 | } | 
|---|
| 119 | break; | 
|---|
| 120 | case PCI_VENDOR_ID_NVIDIA: | 
|---|
| 121 | /* NVidia reports that certain chips don't handle | 
|---|
| 122 | * QH, ITD, or SITD addresses above 2GB.  (But TD, | 
|---|
| 123 | * data buffer, and periodic schedule are normal.) | 
|---|
| 124 | */ | 
|---|
| 125 | switch (pdev->device) { | 
|---|
| 126 | case 0x003c:	/* MCP04 */ | 
|---|
| 127 | case 0x005b:	/* CK804 */ | 
|---|
| 128 | case 0x00d8:	/* CK8 */ | 
|---|
| 129 | case 0x00e8:	/* CK8S */ | 
|---|
| 130 | if (dma_set_coherent_mask(dev: &pdev->dev, DMA_BIT_MASK(31)) < 0) | 
|---|
| 131 | ehci_warn(ehci, "can't enable NVidia " | 
|---|
| 132 | "workaround for >2GB RAM\n"); | 
|---|
| 133 | break; | 
|---|
| 134 |  | 
|---|
| 135 | /* Some NForce2 chips have problems with selective suspend; | 
|---|
| 136 | * fixed in newer silicon. | 
|---|
| 137 | */ | 
|---|
| 138 | case 0x0068: | 
|---|
| 139 | if (pdev->revision < 0xa4) | 
|---|
| 140 | ehci->no_selective_suspend = 1; | 
|---|
| 141 | break; | 
|---|
| 142 | } | 
|---|
| 143 | break; | 
|---|
| 144 | case PCI_VENDOR_ID_INTEL: | 
|---|
| 145 | if (pdev->device == PCI_DEVICE_ID_INTEL_CE4100_USB) | 
|---|
| 146 | hcd->has_tt = 1; | 
|---|
| 147 | break; | 
|---|
| 148 | case PCI_VENDOR_ID_TDI: | 
|---|
| 149 | if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) | 
|---|
| 150 | hcd->has_tt = 1; | 
|---|
| 151 | break; | 
|---|
| 152 | case PCI_VENDOR_ID_AMD: | 
|---|
| 153 | /* AMD PLL quirk */ | 
|---|
| 154 | if (usb_amd_quirk_pll_check()) | 
|---|
| 155 | ehci->amd_pll_fix = 1; | 
|---|
| 156 | /* AMD8111 EHCI doesn't work, according to AMD errata */ | 
|---|
| 157 | if (pdev->device == 0x7463) { | 
|---|
| 158 | ehci_info(ehci, "ignoring AMD8111 (errata)\n"); | 
|---|
| 159 | retval = -EIO; | 
|---|
| 160 | goto done; | 
|---|
| 161 | } | 
|---|
| 162 |  | 
|---|
| 163 | /* | 
|---|
| 164 | * EHCI controller on AMD SB700/SB800/Hudson-2/3 platforms may | 
|---|
| 165 | * read/write memory space which does not belong to it when | 
|---|
| 166 | * there is NULL pointer with T-bit set to 1 in the frame list | 
|---|
| 167 | * table. To avoid the issue, the frame list link pointer | 
|---|
| 168 | * should always contain a valid pointer to a inactive qh. | 
|---|
| 169 | */ | 
|---|
| 170 | if (pdev->device == 0x7808) { | 
|---|
| 171 | ehci->use_dummy_qh = 1; | 
|---|
| 172 | ehci_info(ehci, "applying AMD SB700/SB800/Hudson-2/3 EHCI dummy qh workaround\n"); | 
|---|
| 173 | } | 
|---|
| 174 | break; | 
|---|
| 175 | case PCI_VENDOR_ID_VIA: | 
|---|
| 176 | if (pdev->device == 0x3104 && (pdev->revision & 0xf0) == 0x60) { | 
|---|
| 177 | u8 tmp; | 
|---|
| 178 |  | 
|---|
| 179 | /* The VT6212 defaults to a 1 usec EHCI sleep time which | 
|---|
| 180 | * hogs the PCI bus *badly*. Setting bit 5 of 0x4B makes | 
|---|
| 181 | * that sleep time use the conventional 10 usec. | 
|---|
| 182 | */ | 
|---|
| 183 | pci_read_config_byte(dev: pdev, where: 0x4b, val: &tmp); | 
|---|
| 184 | if (tmp & 0x20) | 
|---|
| 185 | break; | 
|---|
| 186 | pci_write_config_byte(dev: pdev, where: 0x4b, val: tmp | 0x20); | 
|---|
| 187 | } | 
|---|
| 188 | break; | 
|---|
| 189 | case PCI_VENDOR_ID_ATI: | 
|---|
| 190 | /* AMD PLL quirk */ | 
|---|
| 191 | if (usb_amd_quirk_pll_check()) | 
|---|
| 192 | ehci->amd_pll_fix = 1; | 
|---|
| 193 |  | 
|---|
| 194 | /* | 
|---|
| 195 | * EHCI controller on AMD SB700/SB800/Hudson-2/3 platforms may | 
|---|
| 196 | * read/write memory space which does not belong to it when | 
|---|
| 197 | * there is NULL pointer with T-bit set to 1 in the frame list | 
|---|
| 198 | * table. To avoid the issue, the frame list link pointer | 
|---|
| 199 | * should always contain a valid pointer to a inactive qh. | 
|---|
| 200 | */ | 
|---|
| 201 | if (pdev->device == 0x4396) { | 
|---|
| 202 | ehci->use_dummy_qh = 1; | 
|---|
| 203 | ehci_info(ehci, "applying AMD SB700/SB800/Hudson-2/3 EHCI dummy qh workaround\n"); | 
|---|
| 204 | } | 
|---|
| 205 | /* SB600 and old version of SB700 have a bug in EHCI controller, | 
|---|
| 206 | * which causes usb devices lose response in some cases. | 
|---|
| 207 | */ | 
|---|
| 208 | if ((pdev->device == 0x4386 || pdev->device == 0x4396) && | 
|---|
| 209 | usb_amd_hang_symptom_quirk()) { | 
|---|
| 210 | u8 tmp; | 
|---|
| 211 | ehci_info(ehci, "applying AMD SB600/SB700 USB freeze workaround\n"); | 
|---|
| 212 | pci_read_config_byte(dev: pdev, where: 0x53, val: &tmp); | 
|---|
| 213 | pci_write_config_byte(dev: pdev, where: 0x53, val: tmp | (1<<3)); | 
|---|
| 214 | } | 
|---|
| 215 | break; | 
|---|
| 216 | case PCI_VENDOR_ID_NETMOS: | 
|---|
| 217 | /* MosChip frame-index-register bug */ | 
|---|
| 218 | ehci_info(ehci, "applying MosChip frame-index workaround\n"); | 
|---|
| 219 | ehci->frame_index_bug = 1; | 
|---|
| 220 | break; | 
|---|
| 221 | case PCI_VENDOR_ID_HUAWEI: | 
|---|
| 222 | /* Synopsys HC bug */ | 
|---|
| 223 | if (pdev->device == 0xa239) { | 
|---|
| 224 | ehci_info(ehci, "applying Synopsys HC workaround\n"); | 
|---|
| 225 | ehci->has_synopsys_hc_bug = 1; | 
|---|
| 226 | } | 
|---|
| 227 | break; | 
|---|
| 228 | case PCI_VENDOR_ID_ASPEED: | 
|---|
| 229 | if (pdev->device == PCI_DEVICE_ID_ASPEED_EHCI) { | 
|---|
| 230 | ehci_info(ehci, "applying Aspeed HC workaround\n"); | 
|---|
| 231 | ehci->is_aspeed = 1; | 
|---|
| 232 | } | 
|---|
| 233 | break; | 
|---|
| 234 | case PCI_VENDOR_ID_ZHAOXIN: | 
|---|
| 235 | if (pdev->device == 0x3104 && (pdev->revision & 0xf0) == 0x90) | 
|---|
| 236 | ehci->zx_wakeup_clear_needed = 1; | 
|---|
| 237 | break; | 
|---|
| 238 | } | 
|---|
| 239 |  | 
|---|
| 240 | /* optional debug port, normally in the first BAR */ | 
|---|
| 241 | temp = pci_find_capability(dev: pdev, PCI_CAP_ID_DBG); | 
|---|
| 242 | if (temp) { | 
|---|
| 243 | pci_read_config_dword(dev: pdev, where: temp, val: &temp); | 
|---|
| 244 | temp >>= 16; | 
|---|
| 245 | if (((temp >> 13) & 7) == 1) { | 
|---|
| 246 | u32 hcs_params = ehci_readl(ehci, | 
|---|
| 247 | regs: &ehci->caps->hcs_params); | 
|---|
| 248 |  | 
|---|
| 249 | temp &= 0x1fff; | 
|---|
| 250 | ehci->debug = hcd->regs + temp; | 
|---|
| 251 | temp = ehci_readl(ehci, regs: &ehci->debug->control); | 
|---|
| 252 | ehci_info(ehci, "debug port %d%s\n", | 
|---|
| 253 | HCS_DEBUG_PORT(hcs_params), | 
|---|
| 254 | (temp & DBGP_ENABLED) ? " IN USE": ""); | 
|---|
| 255 | if (!(temp & DBGP_ENABLED)) | 
|---|
| 256 | ehci->debug = NULL; | 
|---|
| 257 | } | 
|---|
| 258 | } | 
|---|
| 259 |  | 
|---|
| 260 | retval = ehci_setup(hcd); | 
|---|
| 261 | if (retval) | 
|---|
| 262 | return retval; | 
|---|
| 263 |  | 
|---|
| 264 | /* These workarounds need to be applied after ehci_setup() */ | 
|---|
| 265 | switch (pdev->vendor) { | 
|---|
| 266 | case PCI_VENDOR_ID_NEC: | 
|---|
| 267 | case PCI_VENDOR_ID_INTEL: | 
|---|
| 268 | case PCI_VENDOR_ID_AMD: | 
|---|
| 269 | ehci->need_io_watchdog = 0; | 
|---|
| 270 | break; | 
|---|
| 271 | case PCI_VENDOR_ID_NVIDIA: | 
|---|
| 272 | switch (pdev->device) { | 
|---|
| 273 | /* MCP89 chips on the MacBookAir3,1 give EPROTO when | 
|---|
| 274 | * fetching device descriptors unless LPM is disabled. | 
|---|
| 275 | * There are also intermittent problems enumerating | 
|---|
| 276 | * devices with PPCD enabled. | 
|---|
| 277 | */ | 
|---|
| 278 | case 0x0d9d: | 
|---|
| 279 | ehci_info(ehci, "disable ppcd for nvidia mcp89\n"); | 
|---|
| 280 | ehci->has_ppcd = 0; | 
|---|
| 281 | ehci->command &= ~CMD_PPCEE; | 
|---|
| 282 | break; | 
|---|
| 283 | } | 
|---|
| 284 | break; | 
|---|
| 285 | } | 
|---|
| 286 |  | 
|---|
| 287 | /* at least the Genesys GL880S needs fixup here */ | 
|---|
| 288 | temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params); | 
|---|
| 289 | temp &= 0x0f; | 
|---|
| 290 | if (temp && HCS_N_PORTS(ehci->hcs_params) > temp) { | 
|---|
| 291 | ehci_dbg(ehci, "bogus port configuration: " | 
|---|
| 292 | "cc=%d x pcc=%d < ports=%d\n", | 
|---|
| 293 | HCS_N_CC(ehci->hcs_params), | 
|---|
| 294 | HCS_N_PCC(ehci->hcs_params), | 
|---|
| 295 | HCS_N_PORTS(ehci->hcs_params)); | 
|---|
| 296 |  | 
|---|
| 297 | switch (pdev->vendor) { | 
|---|
| 298 | case 0x17a0:		/* GENESYS */ | 
|---|
| 299 | /* GL880S: should be PORTS=2 */ | 
|---|
| 300 | temp |= (ehci->hcs_params & ~0xf); | 
|---|
| 301 | ehci->hcs_params = temp; | 
|---|
| 302 | break; | 
|---|
| 303 | case PCI_VENDOR_ID_NVIDIA: | 
|---|
| 304 | /* NF4: should be PCC=10 */ | 
|---|
| 305 | break; | 
|---|
| 306 | } | 
|---|
| 307 | } | 
|---|
| 308 |  | 
|---|
| 309 | /* Serial Bus Release Number is at PCI 0x60 offset */ | 
|---|
| 310 | if (pdev->vendor == PCI_VENDOR_ID_STMICRO | 
|---|
| 311 | && pdev->device == PCI_DEVICE_ID_STMICRO_USB_HOST) | 
|---|
| 312 | ;	/* ConneXT has no sbrn register */ | 
|---|
| 313 | else if (pdev->vendor == PCI_VENDOR_ID_HUAWEI | 
|---|
| 314 | && pdev->device == 0xa239) | 
|---|
| 315 | ;	/* HUAWEI Kunpeng920 USB EHCI has no sbrn register */ | 
|---|
| 316 | else | 
|---|
| 317 | pci_read_config_byte(dev: pdev, where: 0x60, val: &ehci->sbrn); | 
|---|
| 318 |  | 
|---|
| 319 | /* Keep this around for a while just in case some EHCI | 
|---|
| 320 | * implementation uses legacy PCI PM support.  This test | 
|---|
| 321 | * can be removed on 17 Dec 2009 if the dev_warn() hasn't | 
|---|
| 322 | * been triggered by then. | 
|---|
| 323 | */ | 
|---|
| 324 | if (!device_can_wakeup(dev: &pdev->dev)) { | 
|---|
| 325 | u16	port_wake; | 
|---|
| 326 |  | 
|---|
| 327 | pci_read_config_word(dev: pdev, where: 0x62, val: &port_wake); | 
|---|
| 328 | if (port_wake & 0x0001) { | 
|---|
| 329 | dev_warn(&pdev->dev, "Enabling legacy PCI PM\n"); | 
|---|
| 330 | device_set_wakeup_capable(dev: &pdev->dev, capable: 1); | 
|---|
| 331 | } | 
|---|
| 332 | } | 
|---|
| 333 |  | 
|---|
| 334 | #ifdef	CONFIG_PM | 
|---|
| 335 | if (ehci->no_selective_suspend && device_can_wakeup(dev: &pdev->dev)) | 
|---|
| 336 | ehci_warn(ehci, "selective suspend/wakeup unavailable\n"); | 
|---|
| 337 | #endif | 
|---|
| 338 |  | 
|---|
| 339 | retval = ehci_pci_reinit(ehci, pdev); | 
|---|
| 340 | done: | 
|---|
| 341 | return retval; | 
|---|
| 342 | } | 
|---|
| 343 |  | 
|---|
| 344 | /*-------------------------------------------------------------------------*/ | 
|---|
| 345 |  | 
|---|
| 346 | #ifdef	CONFIG_PM | 
|---|
| 347 |  | 
|---|
| 348 | /* suspend/resume, section 4.3 */ | 
|---|
| 349 |  | 
|---|
| 350 | /* These routines rely on the PCI bus glue | 
|---|
| 351 | * to handle powerdown and wakeup, and currently also on | 
|---|
| 352 | * transceivers that don't need any software attention to set up | 
|---|
| 353 | * the right sort of wakeup. | 
|---|
| 354 | * Also they depend on separate root hub suspend/resume. | 
|---|
| 355 | */ | 
|---|
| 356 |  | 
|---|
| 357 | static int ehci_pci_resume(struct usb_hcd *hcd, pm_message_t msg) | 
|---|
| 358 | { | 
|---|
| 359 | struct ehci_hcd		*ehci = hcd_to_ehci(hcd); | 
|---|
| 360 | struct pci_dev		*pdev = to_pci_dev(hcd->self.controller); | 
|---|
| 361 | bool			hibernated = (msg.event == PM_EVENT_RESTORE); | 
|---|
| 362 |  | 
|---|
| 363 | if (ehci_resume(hcd, force_reset: hibernated) != 0) | 
|---|
| 364 | (void) ehci_pci_reinit(ehci, pdev); | 
|---|
| 365 | return 0; | 
|---|
| 366 | } | 
|---|
| 367 |  | 
|---|
| 368 | #else | 
|---|
| 369 |  | 
|---|
| 370 | #define ehci_suspend		NULL | 
|---|
| 371 | #define ehci_pci_resume		NULL | 
|---|
| 372 | #endif	/* CONFIG_PM */ | 
|---|
| 373 |  | 
|---|
| 374 | static struct hc_driver __read_mostly ehci_pci_hc_driver; | 
|---|
| 375 |  | 
|---|
| 376 | static const struct ehci_driver_overrides pci_overrides __initconst = { | 
|---|
| 377 | .reset =		ehci_pci_setup, | 
|---|
| 378 | }; | 
|---|
| 379 |  | 
|---|
| 380 | /*-------------------------------------------------------------------------*/ | 
|---|
| 381 |  | 
|---|
| 382 | static int ehci_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | 
|---|
| 383 | { | 
|---|
| 384 | if (is_bypassed_id(pdev)) | 
|---|
| 385 | return -ENODEV; | 
|---|
| 386 | return usb_hcd_pci_probe(dev: pdev, driver: &ehci_pci_hc_driver); | 
|---|
| 387 | } | 
|---|
| 388 |  | 
|---|
| 389 | static void ehci_pci_remove(struct pci_dev *pdev) | 
|---|
| 390 | { | 
|---|
| 391 | pci_clear_mwi(dev: pdev); | 
|---|
| 392 | usb_hcd_pci_remove(dev: pdev); | 
|---|
| 393 | } | 
|---|
| 394 |  | 
|---|
| 395 | /* PCI driver selection metadata; PCI hotplugging uses this */ | 
|---|
| 396 | static const struct pci_device_id pci_ids [] = { { | 
|---|
| 397 | /* handle any USB 2.0 EHCI controller */ | 
|---|
| 398 | PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0), | 
|---|
| 399 | }, { | 
|---|
| 400 | PCI_VDEVICE(STMICRO, PCI_DEVICE_ID_STMICRO_USB_HOST), | 
|---|
| 401 | }, | 
|---|
| 402 | { /* end: all zeroes */ } | 
|---|
| 403 | }; | 
|---|
| 404 | MODULE_DEVICE_TABLE(pci, pci_ids); | 
|---|
| 405 |  | 
|---|
| 406 | /* pci driver glue; this is a "new style" PCI driver module */ | 
|---|
| 407 | static struct pci_driver ehci_pci_driver = { | 
|---|
| 408 | .name =		hcd_name, | 
|---|
| 409 | .id_table =	pci_ids, | 
|---|
| 410 |  | 
|---|
| 411 | .probe =	ehci_pci_probe, | 
|---|
| 412 | .remove =	ehci_pci_remove, | 
|---|
| 413 | .shutdown = 	usb_hcd_pci_shutdown, | 
|---|
| 414 |  | 
|---|
| 415 | .driver =	{ | 
|---|
| 416 | #ifdef CONFIG_PM | 
|---|
| 417 | .pm =	&usb_hcd_pci_pm_ops, | 
|---|
| 418 | #endif | 
|---|
| 419 | .probe_type = PROBE_PREFER_ASYNCHRONOUS, | 
|---|
| 420 | }, | 
|---|
| 421 | }; | 
|---|
| 422 |  | 
|---|
| 423 | static int __init ehci_pci_init(void) | 
|---|
| 424 | { | 
|---|
| 425 | if (usb_disabled()) | 
|---|
| 426 | return -ENODEV; | 
|---|
| 427 |  | 
|---|
| 428 | ehci_init_driver(drv: &ehci_pci_hc_driver, over: &pci_overrides); | 
|---|
| 429 |  | 
|---|
| 430 | /* Entries for the PCI suspend/resume callbacks are special */ | 
|---|
| 431 | ehci_pci_hc_driver.pci_suspend = ehci_suspend; | 
|---|
| 432 | ehci_pci_hc_driver.pci_resume = ehci_pci_resume; | 
|---|
| 433 |  | 
|---|
| 434 | return pci_register_driver(&ehci_pci_driver); | 
|---|
| 435 | } | 
|---|
| 436 | module_init(ehci_pci_init); | 
|---|
| 437 |  | 
|---|
| 438 | static void __exit ehci_pci_cleanup(void) | 
|---|
| 439 | { | 
|---|
| 440 | pci_unregister_driver(dev: &ehci_pci_driver); | 
|---|
| 441 | } | 
|---|
| 442 | module_exit(ehci_pci_cleanup); | 
|---|
| 443 |  | 
|---|
| 444 | MODULE_DESCRIPTION(DRIVER_DESC); | 
|---|
| 445 | MODULE_AUTHOR( "David Brownell"); | 
|---|
| 446 | MODULE_AUTHOR( "Alan Stern"); | 
|---|
| 447 | MODULE_LICENSE( "GPL"); | 
|---|
| 448 |  | 
|---|