diff options
Diffstat (limited to 'drivers/usb/host')
26 files changed, 1038 insertions, 830 deletions
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 350d14fc1cc9..58321d3f314c 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile | |||
@@ -1,8 +1,9 @@ | |||
1 | # | 1 | # |
2 | # Makefile for USB Host Controller Driver | 2 | # Makefile for USB Host Controller Drivers |
3 | # framework and drivers | ||
4 | # | 3 | # |
5 | 4 | ||
5 | obj-$(CONFIG_PCI) += pci-quirks.o | ||
6 | |||
6 | obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o | 7 | obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o |
7 | obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o | 8 | obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o |
8 | obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o | 9 | obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o |
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index f5eb9e7b5b18..af3c05eb86fc 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -182,6 +182,9 @@ static int ehci_halt (struct ehci_hcd *ehci) | |||
182 | { | 182 | { |
183 | u32 temp = readl (&ehci->regs->status); | 183 | u32 temp = readl (&ehci->regs->status); |
184 | 184 | ||
185 | /* disable any irqs left enabled by previous code */ | ||
186 | writel (0, &ehci->regs->intr_enable); | ||
187 | |||
185 | if ((temp & STS_HALT) != 0) | 188 | if ((temp & STS_HALT) != 0) |
186 | return 0; | 189 | return 0; |
187 | 190 | ||
@@ -297,50 +300,17 @@ static void ehci_watchdog (unsigned long param) | |||
297 | spin_unlock_irqrestore (&ehci->lock, flags); | 300 | spin_unlock_irqrestore (&ehci->lock, flags); |
298 | } | 301 | } |
299 | 302 | ||
300 | #ifdef CONFIG_PCI | 303 | /* Reboot notifiers kick in for silicon on any bus (not just pci, etc). |
301 | 304 | * This forcibly disables dma and IRQs, helping kexec and other cases | |
302 | /* EHCI 0.96 (and later) section 5.1 says how to kick BIOS/SMM/... | 305 | * where the next system software may expect clean state. |
303 | * off the controller (maybe it can boot from highspeed USB disks). | ||
304 | */ | 306 | */ |
305 | static int bios_handoff (struct ehci_hcd *ehci, int where, u32 cap) | ||
306 | { | ||
307 | struct pci_dev *pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller); | ||
308 | |||
309 | /* always say Linux will own the hardware */ | ||
310 | pci_write_config_byte(pdev, where + 3, 1); | ||
311 | |||
312 | /* maybe wait a while for BIOS to respond */ | ||
313 | if (cap & (1 << 16)) { | ||
314 | int msec = 5000; | ||
315 | |||
316 | do { | ||
317 | msleep(10); | ||
318 | msec -= 10; | ||
319 | pci_read_config_dword(pdev, where, &cap); | ||
320 | } while ((cap & (1 << 16)) && msec); | ||
321 | if (cap & (1 << 16)) { | ||
322 | ehci_err(ehci, "BIOS handoff failed (%d, %08x)\n", | ||
323 | where, cap); | ||
324 | // some BIOS versions seem buggy... | ||
325 | // return 1; | ||
326 | ehci_warn (ehci, "continuing after BIOS bug...\n"); | ||
327 | /* disable all SMIs, and clear "BIOS owns" flag */ | ||
328 | pci_write_config_dword(pdev, where + 4, 0); | ||
329 | pci_write_config_byte(pdev, where + 2, 0); | ||
330 | } else | ||
331 | ehci_dbg(ehci, "BIOS handoff succeeded\n"); | ||
332 | } | ||
333 | return 0; | ||
334 | } | ||
335 | |||
336 | #endif | ||
337 | |||
338 | static int | 307 | static int |
339 | ehci_reboot (struct notifier_block *self, unsigned long code, void *null) | 308 | ehci_reboot (struct notifier_block *self, unsigned long code, void *null) |
340 | { | 309 | { |
341 | struct ehci_hcd *ehci; | 310 | struct ehci_hcd *ehci; |
342 | 311 | ||
343 | ehci = container_of (self, struct ehci_hcd, reboot_notifier); | 312 | ehci = container_of (self, struct ehci_hcd, reboot_notifier); |
313 | (void) ehci_halt (ehci); | ||
344 | 314 | ||
345 | /* make BIOS/etc use companion controller during reboot */ | 315 | /* make BIOS/etc use companion controller during reboot */ |
346 | writel (0, &ehci->regs->configured_flag); | 316 | writel (0, &ehci->regs->configured_flag); |
@@ -363,156 +333,90 @@ static void ehci_port_power (struct ehci_hcd *ehci, int is_on) | |||
363 | msleep(20); | 333 | msleep(20); |
364 | } | 334 | } |
365 | 335 | ||
336 | /*-------------------------------------------------------------------------*/ | ||
337 | |||
338 | /* | ||
339 | * ehci_work is called from some interrupts, timers, and so on. | ||
340 | * it calls driver completion functions, after dropping ehci->lock. | ||
341 | */ | ||
342 | static void ehci_work (struct ehci_hcd *ehci, struct pt_regs *regs) | ||
343 | { | ||
344 | timer_action_done (ehci, TIMER_IO_WATCHDOG); | ||
345 | if (ehci->reclaim_ready) | ||
346 | end_unlink_async (ehci, regs); | ||
347 | |||
348 | /* another CPU may drop ehci->lock during a schedule scan while | ||
349 | * it reports urb completions. this flag guards against bogus | ||
350 | * attempts at re-entrant schedule scanning. | ||
351 | */ | ||
352 | if (ehci->scanning) | ||
353 | return; | ||
354 | ehci->scanning = 1; | ||
355 | scan_async (ehci, regs); | ||
356 | if (ehci->next_uframe != -1) | ||
357 | scan_periodic (ehci, regs); | ||
358 | ehci->scanning = 0; | ||
366 | 359 | ||
367 | /* called by khubd or root hub init threads */ | 360 | /* the IO watchdog guards against hardware or driver bugs that |
361 | * misplace IRQs, and should let us run completely without IRQs. | ||
362 | * such lossage has been observed on both VT6202 and VT8235. | ||
363 | */ | ||
364 | if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state) && | ||
365 | (ehci->async->qh_next.ptr != NULL || | ||
366 | ehci->periodic_sched != 0)) | ||
367 | timer_action (ehci, TIMER_IO_WATCHDOG); | ||
368 | } | ||
368 | 369 | ||
369 | static int ehci_hc_reset (struct usb_hcd *hcd) | 370 | static void ehci_stop (struct usb_hcd *hcd) |
370 | { | 371 | { |
371 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | 372 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
372 | u32 temp; | ||
373 | unsigned count = 256/4; | ||
374 | 373 | ||
375 | spin_lock_init (&ehci->lock); | 374 | ehci_dbg (ehci, "stop\n"); |
376 | 375 | ||
377 | ehci->caps = hcd->regs; | 376 | /* Turn off port power on all root hub ports. */ |
378 | ehci->regs = hcd->regs + HC_LENGTH (readl (&ehci->caps->hc_capbase)); | 377 | ehci_port_power (ehci, 0); |
379 | dbg_hcs_params (ehci, "reset"); | ||
380 | dbg_hcc_params (ehci, "reset"); | ||
381 | 378 | ||
382 | /* cache this readonly data; minimize chip reads */ | 379 | /* no more interrupts ... */ |
383 | ehci->hcs_params = readl (&ehci->caps->hcs_params); | 380 | del_timer_sync (&ehci->watchdog); |
384 | 381 | ||
385 | #ifdef CONFIG_PCI | 382 | spin_lock_irq(&ehci->lock); |
386 | if (hcd->self.controller->bus == &pci_bus_type) { | 383 | if (HC_IS_RUNNING (hcd->state)) |
387 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); | 384 | ehci_quiesce (ehci); |
388 | 385 | ||
389 | switch (pdev->vendor) { | 386 | ehci_reset (ehci); |
390 | case PCI_VENDOR_ID_TDI: | 387 | writel (0, &ehci->regs->intr_enable); |
391 | if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) { | 388 | spin_unlock_irq(&ehci->lock); |
392 | ehci->is_tdi_rh_tt = 1; | ||
393 | tdi_reset (ehci); | ||
394 | } | ||
395 | break; | ||
396 | case PCI_VENDOR_ID_AMD: | ||
397 | /* AMD8111 EHCI doesn't work, according to AMD errata */ | ||
398 | if (pdev->device == 0x7463) { | ||
399 | ehci_info (ehci, "ignoring AMD8111 (errata)\n"); | ||
400 | return -EIO; | ||
401 | } | ||
402 | break; | ||
403 | case PCI_VENDOR_ID_NVIDIA: | ||
404 | /* NVidia reports that certain chips don't handle | ||
405 | * QH, ITD, or SITD addresses above 2GB. (But TD, | ||
406 | * data buffer, and periodic schedule are normal.) | ||
407 | */ | ||
408 | switch (pdev->device) { | ||
409 | case 0x003c: /* MCP04 */ | ||
410 | case 0x005b: /* CK804 */ | ||
411 | case 0x00d8: /* CK8 */ | ||
412 | case 0x00e8: /* CK8S */ | ||
413 | if (pci_set_consistent_dma_mask(pdev, | ||
414 | DMA_31BIT_MASK) < 0) | ||
415 | ehci_warn (ehci, "can't enable NVidia " | ||
416 | "workaround for >2GB RAM\n"); | ||
417 | break; | ||
418 | } | ||
419 | break; | ||
420 | } | ||
421 | 389 | ||
422 | /* optional debug port, normally in the first BAR */ | 390 | /* let companion controllers work when we aren't */ |
423 | temp = pci_find_capability (pdev, 0x0a); | 391 | writel (0, &ehci->regs->configured_flag); |
424 | if (temp) { | 392 | unregister_reboot_notifier (&ehci->reboot_notifier); |
425 | pci_read_config_dword(pdev, temp, &temp); | ||
426 | temp >>= 16; | ||
427 | if ((temp & (3 << 13)) == (1 << 13)) { | ||
428 | temp &= 0x1fff; | ||
429 | ehci->debug = hcd->regs + temp; | ||
430 | temp = readl (&ehci->debug->control); | ||
431 | ehci_info (ehci, "debug port %d%s\n", | ||
432 | HCS_DEBUG_PORT(ehci->hcs_params), | ||
433 | (temp & DBGP_ENABLED) | ||
434 | ? " IN USE" | ||
435 | : ""); | ||
436 | if (!(temp & DBGP_ENABLED)) | ||
437 | ehci->debug = NULL; | ||
438 | } | ||
439 | } | ||
440 | 393 | ||
441 | temp = HCC_EXT_CAPS (readl (&ehci->caps->hcc_params)); | 394 | remove_debug_files (ehci); |
442 | } else | ||
443 | temp = 0; | ||
444 | |||
445 | /* EHCI 0.96 and later may have "extended capabilities" */ | ||
446 | while (temp && count--) { | ||
447 | u32 cap; | ||
448 | |||
449 | pci_read_config_dword (to_pci_dev(hcd->self.controller), | ||
450 | temp, &cap); | ||
451 | ehci_dbg (ehci, "capability %04x at %02x\n", cap, temp); | ||
452 | switch (cap & 0xff) { | ||
453 | case 1: /* BIOS/SMM/... handoff */ | ||
454 | if (bios_handoff (ehci, temp, cap) != 0) | ||
455 | return -EOPNOTSUPP; | ||
456 | break; | ||
457 | case 0: /* illegal reserved capability */ | ||
458 | ehci_warn (ehci, "illegal capability!\n"); | ||
459 | cap = 0; | ||
460 | /* FALLTHROUGH */ | ||
461 | default: /* unknown */ | ||
462 | break; | ||
463 | } | ||
464 | temp = (cap >> 8) & 0xff; | ||
465 | } | ||
466 | if (!count) { | ||
467 | ehci_err (ehci, "bogus capabilities ... PCI problems!\n"); | ||
468 | return -EIO; | ||
469 | } | ||
470 | if (ehci_is_TDI(ehci)) | ||
471 | ehci_reset (ehci); | ||
472 | #endif | ||
473 | 395 | ||
474 | ehci_port_power (ehci, 0); | 396 | /* root hub is shut down separately (first, when possible) */ |
397 | spin_lock_irq (&ehci->lock); | ||
398 | if (ehci->async) | ||
399 | ehci_work (ehci, NULL); | ||
400 | spin_unlock_irq (&ehci->lock); | ||
401 | ehci_mem_cleanup (ehci); | ||
475 | 402 | ||
476 | /* at least the Genesys GL880S needs fixup here */ | 403 | #ifdef EHCI_STATS |
477 | temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params); | 404 | ehci_dbg (ehci, "irq normal %ld err %ld reclaim %ld (lost %ld)\n", |
478 | temp &= 0x0f; | 405 | ehci->stats.normal, ehci->stats.error, ehci->stats.reclaim, |
479 | if (temp && HCS_N_PORTS(ehci->hcs_params) > temp) { | 406 | ehci->stats.lost_iaa); |
480 | ehci_dbg (ehci, "bogus port configuration: " | 407 | ehci_dbg (ehci, "complete %ld unlink %ld\n", |
481 | "cc=%d x pcc=%d < ports=%d\n", | 408 | ehci->stats.complete, ehci->stats.unlink); |
482 | HCS_N_CC(ehci->hcs_params), | ||
483 | HCS_N_PCC(ehci->hcs_params), | ||
484 | HCS_N_PORTS(ehci->hcs_params)); | ||
485 | |||
486 | #ifdef CONFIG_PCI | ||
487 | if (hcd->self.controller->bus == &pci_bus_type) { | ||
488 | struct pci_dev *pdev; | ||
489 | |||
490 | pdev = to_pci_dev(hcd->self.controller); | ||
491 | switch (pdev->vendor) { | ||
492 | case 0x17a0: /* GENESYS */ | ||
493 | /* GL880S: should be PORTS=2 */ | ||
494 | temp |= (ehci->hcs_params & ~0xf); | ||
495 | ehci->hcs_params = temp; | ||
496 | break; | ||
497 | case PCI_VENDOR_ID_NVIDIA: | ||
498 | /* NF4: should be PCC=10 */ | ||
499 | break; | ||
500 | } | ||
501 | } | ||
502 | #endif | 409 | #endif |
503 | } | ||
504 | 410 | ||
505 | /* force HC to halt state */ | 411 | dbg_status (ehci, "ehci_stop completed", readl (&ehci->regs->status)); |
506 | return ehci_halt (ehci); | ||
507 | } | 412 | } |
508 | 413 | ||
509 | static int ehci_start (struct usb_hcd *hcd) | 414 | static int ehci_run (struct usb_hcd *hcd) |
510 | { | 415 | { |
511 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | 416 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
512 | u32 temp; | 417 | u32 temp; |
513 | int retval; | 418 | int retval; |
514 | u32 hcc_params; | 419 | u32 hcc_params; |
515 | u8 sbrn = 0; | ||
516 | int first; | 420 | int first; |
517 | 421 | ||
518 | /* skip some things on restart paths */ | 422 | /* skip some things on restart paths */ |
@@ -551,27 +455,6 @@ static int ehci_start (struct usb_hcd *hcd) | |||
551 | } | 455 | } |
552 | writel (ehci->periodic_dma, &ehci->regs->frame_list); | 456 | writel (ehci->periodic_dma, &ehci->regs->frame_list); |
553 | 457 | ||
554 | #ifdef CONFIG_PCI | ||
555 | if (hcd->self.controller->bus == &pci_bus_type) { | ||
556 | struct pci_dev *pdev; | ||
557 | u16 port_wake; | ||
558 | |||
559 | pdev = to_pci_dev(hcd->self.controller); | ||
560 | |||
561 | /* Serial Bus Release Number is at PCI 0x60 offset */ | ||
562 | pci_read_config_byte(pdev, 0x60, &sbrn); | ||
563 | |||
564 | /* port wake capability, reported by boot firmware */ | ||
565 | pci_read_config_word(pdev, 0x62, &port_wake); | ||
566 | hcd->can_wakeup = (port_wake & 1) != 0; | ||
567 | |||
568 | /* help hc dma work well with cachelines */ | ||
569 | retval = pci_set_mwi(pdev); | ||
570 | if (retval) | ||
571 | ehci_dbg(ehci, "unable to enable MWI - not fatal.\n"); | ||
572 | } | ||
573 | #endif | ||
574 | |||
575 | /* | 458 | /* |
576 | * dedicate a qh for the async ring head, since we couldn't unlink | 459 | * dedicate a qh for the async ring head, since we couldn't unlink |
577 | * a 'real' qh without stopping the async schedule [4.8]. use it | 460 | * a 'real' qh without stopping the async schedule [4.8]. use it |
@@ -667,7 +550,7 @@ static int ehci_start (struct usb_hcd *hcd) | |||
667 | temp = HC_VERSION(readl (&ehci->caps->hc_capbase)); | 550 | temp = HC_VERSION(readl (&ehci->caps->hc_capbase)); |
668 | ehci_info (ehci, | 551 | ehci_info (ehci, |
669 | "USB %x.%x %s, EHCI %x.%02x, driver %s\n", | 552 | "USB %x.%x %s, EHCI %x.%02x, driver %s\n", |
670 | ((sbrn & 0xf0)>>4), (sbrn & 0x0f), | 553 | ((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f), |
671 | first ? "initialized" : "restarted", | 554 | first ? "initialized" : "restarted", |
672 | temp >> 8, temp & 0xff, DRIVER_VERSION); | 555 | temp >> 8, temp & 0xff, DRIVER_VERSION); |
673 | 556 | ||
@@ -679,188 +562,6 @@ static int ehci_start (struct usb_hcd *hcd) | |||
679 | return 0; | 562 | return 0; |
680 | } | 563 | } |
681 | 564 | ||
682 | /* always called by thread; normally rmmod */ | ||
683 | |||
684 | static void ehci_stop (struct usb_hcd *hcd) | ||
685 | { | ||
686 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | ||
687 | |||
688 | ehci_dbg (ehci, "stop\n"); | ||
689 | |||
690 | /* Turn off port power on all root hub ports. */ | ||
691 | ehci_port_power (ehci, 0); | ||
692 | |||
693 | /* no more interrupts ... */ | ||
694 | del_timer_sync (&ehci->watchdog); | ||
695 | |||
696 | spin_lock_irq(&ehci->lock); | ||
697 | if (HC_IS_RUNNING (hcd->state)) | ||
698 | ehci_quiesce (ehci); | ||
699 | |||
700 | ehci_reset (ehci); | ||
701 | writel (0, &ehci->regs->intr_enable); | ||
702 | spin_unlock_irq(&ehci->lock); | ||
703 | |||
704 | /* let companion controllers work when we aren't */ | ||
705 | writel (0, &ehci->regs->configured_flag); | ||
706 | unregister_reboot_notifier (&ehci->reboot_notifier); | ||
707 | |||
708 | remove_debug_files (ehci); | ||
709 | |||
710 | /* root hub is shut down separately (first, when possible) */ | ||
711 | spin_lock_irq (&ehci->lock); | ||
712 | if (ehci->async) | ||
713 | ehci_work (ehci, NULL); | ||
714 | spin_unlock_irq (&ehci->lock); | ||
715 | ehci_mem_cleanup (ehci); | ||
716 | |||
717 | #ifdef EHCI_STATS | ||
718 | ehci_dbg (ehci, "irq normal %ld err %ld reclaim %ld (lost %ld)\n", | ||
719 | ehci->stats.normal, ehci->stats.error, ehci->stats.reclaim, | ||
720 | ehci->stats.lost_iaa); | ||
721 | ehci_dbg (ehci, "complete %ld unlink %ld\n", | ||
722 | ehci->stats.complete, ehci->stats.unlink); | ||
723 | #endif | ||
724 | |||
725 | dbg_status (ehci, "ehci_stop completed", readl (&ehci->regs->status)); | ||
726 | } | ||
727 | |||
728 | static int ehci_get_frame (struct usb_hcd *hcd) | ||
729 | { | ||
730 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | ||
731 | return (readl (&ehci->regs->frame_index) >> 3) % ehci->periodic_size; | ||
732 | } | ||
733 | |||
734 | /*-------------------------------------------------------------------------*/ | ||
735 | |||
736 | #ifdef CONFIG_PM | ||
737 | |||
738 | /* suspend/resume, section 4.3 */ | ||
739 | |||
740 | /* These routines rely on the bus (pci, platform, etc) | ||
741 | * to handle powerdown and wakeup, and currently also on | ||
742 | * transceivers that don't need any software attention to set up | ||
743 | * the right sort of wakeup. | ||
744 | */ | ||
745 | |||
746 | static int ehci_suspend (struct usb_hcd *hcd, pm_message_t message) | ||
747 | { | ||
748 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | ||
749 | |||
750 | if (time_before (jiffies, ehci->next_statechange)) | ||
751 | msleep (100); | ||
752 | |||
753 | #ifdef CONFIG_USB_SUSPEND | ||
754 | (void) usb_suspend_device (hcd->self.root_hub, message); | ||
755 | #else | ||
756 | usb_lock_device (hcd->self.root_hub); | ||
757 | (void) ehci_hub_suspend (hcd); | ||
758 | usb_unlock_device (hcd->self.root_hub); | ||
759 | #endif | ||
760 | |||
761 | // save (PCI) FLADJ in case of Vaux power loss | ||
762 | // ... we'd only use it to handle clock skew | ||
763 | |||
764 | return 0; | ||
765 | } | ||
766 | |||
767 | static int ehci_resume (struct usb_hcd *hcd) | ||
768 | { | ||
769 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | ||
770 | unsigned port; | ||
771 | struct usb_device *root = hcd->self.root_hub; | ||
772 | int retval = -EINVAL; | ||
773 | |||
774 | // maybe restore (PCI) FLADJ | ||
775 | |||
776 | if (time_before (jiffies, ehci->next_statechange)) | ||
777 | msleep (100); | ||
778 | |||
779 | /* If any port is suspended (or owned by the companion), | ||
780 | * we know we can/must resume the HC (and mustn't reset it). | ||
781 | */ | ||
782 | for (port = HCS_N_PORTS (ehci->hcs_params); port > 0; ) { | ||
783 | u32 status; | ||
784 | port--; | ||
785 | status = readl (&ehci->regs->port_status [port]); | ||
786 | if (!(status & PORT_POWER)) | ||
787 | continue; | ||
788 | if (status & (PORT_SUSPEND | PORT_OWNER)) { | ||
789 | down (&hcd->self.root_hub->serialize); | ||
790 | retval = ehci_hub_resume (hcd); | ||
791 | up (&hcd->self.root_hub->serialize); | ||
792 | break; | ||
793 | } | ||
794 | if (!root->children [port]) | ||
795 | continue; | ||
796 | dbg_port (ehci, __FUNCTION__, port + 1, status); | ||
797 | usb_set_device_state (root->children[port], | ||
798 | USB_STATE_NOTATTACHED); | ||
799 | } | ||
800 | |||
801 | /* Else reset, to cope with power loss or flush-to-storage | ||
802 | * style "resume" having activated BIOS during reboot. | ||
803 | */ | ||
804 | if (port == 0) { | ||
805 | (void) ehci_halt (ehci); | ||
806 | (void) ehci_reset (ehci); | ||
807 | (void) ehci_hc_reset (hcd); | ||
808 | |||
809 | /* emptying the schedule aborts any urbs */ | ||
810 | spin_lock_irq (&ehci->lock); | ||
811 | if (ehci->reclaim) | ||
812 | ehci->reclaim_ready = 1; | ||
813 | ehci_work (ehci, NULL); | ||
814 | spin_unlock_irq (&ehci->lock); | ||
815 | |||
816 | /* restart; khubd will disconnect devices */ | ||
817 | retval = ehci_start (hcd); | ||
818 | |||
819 | /* here we "know" root ports should always stay powered; | ||
820 | * but some controllers may lose all power. | ||
821 | */ | ||
822 | ehci_port_power (ehci, 1); | ||
823 | } | ||
824 | |||
825 | return retval; | ||
826 | } | ||
827 | |||
828 | #endif | ||
829 | |||
830 | /*-------------------------------------------------------------------------*/ | ||
831 | |||
832 | /* | ||
833 | * ehci_work is called from some interrupts, timers, and so on. | ||
834 | * it calls driver completion functions, after dropping ehci->lock. | ||
835 | */ | ||
836 | static void ehci_work (struct ehci_hcd *ehci, struct pt_regs *regs) | ||
837 | { | ||
838 | timer_action_done (ehci, TIMER_IO_WATCHDOG); | ||
839 | if (ehci->reclaim_ready) | ||
840 | end_unlink_async (ehci, regs); | ||
841 | |||
842 | /* another CPU may drop ehci->lock during a schedule scan while | ||
843 | * it reports urb completions. this flag guards against bogus | ||
844 | * attempts at re-entrant schedule scanning. | ||
845 | */ | ||
846 | if (ehci->scanning) | ||
847 | return; | ||
848 | ehci->scanning = 1; | ||
849 | scan_async (ehci, regs); | ||
850 | if (ehci->next_uframe != -1) | ||
851 | scan_periodic (ehci, regs); | ||
852 | ehci->scanning = 0; | ||
853 | |||
854 | /* the IO watchdog guards against hardware or driver bugs that | ||
855 | * misplace IRQs, and should let us run completely without IRQs. | ||
856 | * such lossage has been observed on both VT6202 and VT8235. | ||
857 | */ | ||
858 | if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state) && | ||
859 | (ehci->async->qh_next.ptr != NULL || | ||
860 | ehci->periodic_sched != 0)) | ||
861 | timer_action (ehci, TIMER_IO_WATCHDOG); | ||
862 | } | ||
863 | |||
864 | /*-------------------------------------------------------------------------*/ | 565 | /*-------------------------------------------------------------------------*/ |
865 | 566 | ||
866 | static irqreturn_t ehci_irq (struct usb_hcd *hcd, struct pt_regs *regs) | 567 | static irqreturn_t ehci_irq (struct usb_hcd *hcd, struct pt_regs *regs) |
@@ -1171,106 +872,24 @@ done: | |||
1171 | return; | 872 | return; |
1172 | } | 873 | } |
1173 | 874 | ||
1174 | /*-------------------------------------------------------------------------*/ | 875 | static int ehci_get_frame (struct usb_hcd *hcd) |
1175 | 876 | { | |
1176 | static const struct hc_driver ehci_driver = { | 877 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
1177 | .description = hcd_name, | 878 | return (readl (&ehci->regs->frame_index) >> 3) % ehci->periodic_size; |
1178 | .product_desc = "EHCI Host Controller", | 879 | } |
1179 | .hcd_priv_size = sizeof(struct ehci_hcd), | ||
1180 | |||
1181 | /* | ||
1182 | * generic hardware linkage | ||
1183 | */ | ||
1184 | .irq = ehci_irq, | ||
1185 | .flags = HCD_MEMORY | HCD_USB2, | ||
1186 | |||
1187 | /* | ||
1188 | * basic lifecycle operations | ||
1189 | */ | ||
1190 | .reset = ehci_hc_reset, | ||
1191 | .start = ehci_start, | ||
1192 | #ifdef CONFIG_PM | ||
1193 | .suspend = ehci_suspend, | ||
1194 | .resume = ehci_resume, | ||
1195 | #endif | ||
1196 | .stop = ehci_stop, | ||
1197 | |||
1198 | /* | ||
1199 | * managing i/o requests and associated device resources | ||
1200 | */ | ||
1201 | .urb_enqueue = ehci_urb_enqueue, | ||
1202 | .urb_dequeue = ehci_urb_dequeue, | ||
1203 | .endpoint_disable = ehci_endpoint_disable, | ||
1204 | |||
1205 | /* | ||
1206 | * scheduling support | ||
1207 | */ | ||
1208 | .get_frame_number = ehci_get_frame, | ||
1209 | |||
1210 | /* | ||
1211 | * root hub support | ||
1212 | */ | ||
1213 | .hub_status_data = ehci_hub_status_data, | ||
1214 | .hub_control = ehci_hub_control, | ||
1215 | .hub_suspend = ehci_hub_suspend, | ||
1216 | .hub_resume = ehci_hub_resume, | ||
1217 | }; | ||
1218 | 880 | ||
1219 | /*-------------------------------------------------------------------------*/ | 881 | /*-------------------------------------------------------------------------*/ |
1220 | 882 | ||
1221 | /* EHCI 1.0 doesn't require PCI */ | ||
1222 | |||
1223 | #ifdef CONFIG_PCI | ||
1224 | |||
1225 | /* PCI driver selection metadata; PCI hotplugging uses this */ | ||
1226 | static const struct pci_device_id pci_ids [] = { { | ||
1227 | /* handle any USB 2.0 EHCI controller */ | ||
1228 | PCI_DEVICE_CLASS(((PCI_CLASS_SERIAL_USB << 8) | 0x20), ~0), | ||
1229 | .driver_data = (unsigned long) &ehci_driver, | ||
1230 | }, | ||
1231 | { /* end: all zeroes */ } | ||
1232 | }; | ||
1233 | MODULE_DEVICE_TABLE (pci, pci_ids); | ||
1234 | |||
1235 | /* pci driver glue; this is a "new style" PCI driver module */ | ||
1236 | static struct pci_driver ehci_pci_driver = { | ||
1237 | .name = (char *) hcd_name, | ||
1238 | .id_table = pci_ids, | ||
1239 | |||
1240 | .probe = usb_hcd_pci_probe, | ||
1241 | .remove = usb_hcd_pci_remove, | ||
1242 | |||
1243 | #ifdef CONFIG_PM | ||
1244 | .suspend = usb_hcd_pci_suspend, | ||
1245 | .resume = usb_hcd_pci_resume, | ||
1246 | #endif | ||
1247 | }; | ||
1248 | |||
1249 | #endif /* PCI */ | ||
1250 | |||
1251 | |||
1252 | #define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC | 883 | #define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC |
1253 | 884 | ||
1254 | MODULE_DESCRIPTION (DRIVER_INFO); | 885 | MODULE_DESCRIPTION (DRIVER_INFO); |
1255 | MODULE_AUTHOR (DRIVER_AUTHOR); | 886 | MODULE_AUTHOR (DRIVER_AUTHOR); |
1256 | MODULE_LICENSE ("GPL"); | 887 | MODULE_LICENSE ("GPL"); |
1257 | 888 | ||
1258 | static int __init init (void) | 889 | #ifdef CONFIG_PCI |
1259 | { | 890 | #include "ehci-pci.c" |
1260 | if (usb_disabled()) | 891 | #endif |
1261 | return -ENODEV; | ||
1262 | |||
1263 | pr_debug ("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n", | ||
1264 | hcd_name, | ||
1265 | sizeof (struct ehci_qh), sizeof (struct ehci_qtd), | ||
1266 | sizeof (struct ehci_itd), sizeof (struct ehci_sitd)); | ||
1267 | |||
1268 | return pci_register_driver (&ehci_pci_driver); | ||
1269 | } | ||
1270 | module_init (init); | ||
1271 | 892 | ||
1272 | static void __exit cleanup (void) | 893 | #if !defined(CONFIG_PCI) |
1273 | { | 894 | #error "missing bus glue for ehci-hcd" |
1274 | pci_unregister_driver (&ehci_pci_driver); | 895 | #endif |
1275 | } | ||
1276 | module_exit (cleanup); | ||
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 18d3f2270316..88cb4ada686e 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
@@ -30,7 +30,7 @@ | |||
30 | 30 | ||
31 | #ifdef CONFIG_PM | 31 | #ifdef CONFIG_PM |
32 | 32 | ||
33 | static int ehci_hub_suspend (struct usb_hcd *hcd) | 33 | static int ehci_bus_suspend (struct usb_hcd *hcd) |
34 | { | 34 | { |
35 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | 35 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
36 | int port; | 36 | int port; |
@@ -83,7 +83,7 @@ static int ehci_hub_suspend (struct usb_hcd *hcd) | |||
83 | 83 | ||
84 | 84 | ||
85 | /* caller has locked the root hub, and should reset/reinit on error */ | 85 | /* caller has locked the root hub, and should reset/reinit on error */ |
86 | static int ehci_hub_resume (struct usb_hcd *hcd) | 86 | static int ehci_bus_resume (struct usb_hcd *hcd) |
87 | { | 87 | { |
88 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | 88 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
89 | u32 temp; | 89 | u32 temp; |
@@ -159,8 +159,8 @@ static int ehci_hub_resume (struct usb_hcd *hcd) | |||
159 | 159 | ||
160 | #else | 160 | #else |
161 | 161 | ||
162 | #define ehci_hub_suspend NULL | 162 | #define ehci_bus_suspend NULL |
163 | #define ehci_hub_resume NULL | 163 | #define ehci_bus_resume NULL |
164 | 164 | ||
165 | #endif /* CONFIG_PM */ | 165 | #endif /* CONFIG_PM */ |
166 | 166 | ||
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c new file mode 100644 index 000000000000..145008853966 --- /dev/null +++ b/drivers/usb/host/ehci-pci.c | |||
@@ -0,0 +1,415 @@ | |||
1 | /* | ||
2 | * EHCI HCD (Host Controller Driver) PCI Bus Glue. | ||
3 | * | ||
4 | * Copyright (c) 2000-2004 by David Brownell | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||
13 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
14 | * for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software Foundation, | ||
18 | * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef CONFIG_PCI | ||
22 | #error "This file is PCI bus glue. CONFIG_PCI must be defined." | ||
23 | #endif | ||
24 | |||
25 | /*-------------------------------------------------------------------------*/ | ||
26 | |||
27 | /* EHCI 0.96 (and later) section 5.1 says how to kick BIOS/SMM/... | ||
28 | * off the controller (maybe it can boot from highspeed USB disks). | ||
29 | */ | ||
30 | static int bios_handoff (struct ehci_hcd *ehci, int where, u32 cap) | ||
31 | { | ||
32 | struct pci_dev *pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller); | ||
33 | |||
34 | /* always say Linux will own the hardware */ | ||
35 | pci_write_config_byte(pdev, where + 3, 1); | ||
36 | |||
37 | /* maybe wait a while for BIOS to respond */ | ||
38 | if (cap & (1 << 16)) { | ||
39 | int msec = 5000; | ||
40 | |||
41 | do { | ||
42 | msleep(10); | ||
43 | msec -= 10; | ||
44 | pci_read_config_dword(pdev, where, &cap); | ||
45 | } while ((cap & (1 << 16)) && msec); | ||
46 | if (cap & (1 << 16)) { | ||
47 | ehci_err(ehci, "BIOS handoff failed (%d, %08x)\n", | ||
48 | where, cap); | ||
49 | // some BIOS versions seem buggy... | ||
50 | // return 1; | ||
51 | ehci_warn (ehci, "continuing after BIOS bug...\n"); | ||
52 | /* disable all SMIs, and clear "BIOS owns" flag */ | ||
53 | pci_write_config_dword(pdev, where + 4, 0); | ||
54 | pci_write_config_byte(pdev, where + 2, 0); | ||
55 | } else | ||
56 | ehci_dbg(ehci, "BIOS handoff succeeded\n"); | ||
57 | } | ||
58 | return 0; | ||
59 | } | ||
60 | |||
61 | /* called by khubd or root hub init threads */ | ||
62 | static int ehci_pci_reset (struct usb_hcd *hcd) | ||
63 | { | ||
64 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | ||
65 | u32 temp; | ||
66 | unsigned count = 256/4; | ||
67 | |||
68 | spin_lock_init (&ehci->lock); | ||
69 | |||
70 | ehci->caps = hcd->regs; | ||
71 | ehci->regs = hcd->regs + HC_LENGTH (readl (&ehci->caps->hc_capbase)); | ||
72 | dbg_hcs_params (ehci, "reset"); | ||
73 | dbg_hcc_params (ehci, "reset"); | ||
74 | |||
75 | /* cache this readonly data; minimize chip reads */ | ||
76 | ehci->hcs_params = readl (&ehci->caps->hcs_params); | ||
77 | |||
78 | if (hcd->self.controller->bus == &pci_bus_type) { | ||
79 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); | ||
80 | |||
81 | switch (pdev->vendor) { | ||
82 | case PCI_VENDOR_ID_TDI: | ||
83 | if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) { | ||
84 | ehci->is_tdi_rh_tt = 1; | ||
85 | tdi_reset (ehci); | ||
86 | } | ||
87 | break; | ||
88 | case PCI_VENDOR_ID_AMD: | ||
89 | /* AMD8111 EHCI doesn't work, according to AMD errata */ | ||
90 | if (pdev->device == 0x7463) { | ||
91 | ehci_info (ehci, "ignoring AMD8111 (errata)\n"); | ||
92 | return -EIO; | ||
93 | } | ||
94 | break; | ||
95 | case PCI_VENDOR_ID_NVIDIA: | ||
96 | /* NVidia reports that certain chips don't handle | ||
97 | * QH, ITD, or SITD addresses above 2GB. (But TD, | ||
98 | * data buffer, and periodic schedule are normal.) | ||
99 | */ | ||
100 | switch (pdev->device) { | ||
101 | case 0x003c: /* MCP04 */ | ||
102 | case 0x005b: /* CK804 */ | ||
103 | case 0x00d8: /* CK8 */ | ||
104 | case 0x00e8: /* CK8S */ | ||
105 | if (pci_set_consistent_dma_mask(pdev, | ||
106 | DMA_31BIT_MASK) < 0) | ||
107 | ehci_warn (ehci, "can't enable NVidia " | ||
108 | "workaround for >2GB RAM\n"); | ||
109 | break; | ||
110 | } | ||
111 | break; | ||
112 | } | ||
113 | |||
114 | /* optional debug port, normally in the first BAR */ | ||
115 | temp = pci_find_capability (pdev, 0x0a); | ||
116 | if (temp) { | ||
117 | pci_read_config_dword(pdev, temp, &temp); | ||
118 | temp >>= 16; | ||
119 | if ((temp & (3 << 13)) == (1 << 13)) { | ||
120 | temp &= 0x1fff; | ||
121 | ehci->debug = hcd->regs + temp; | ||
122 | temp = readl (&ehci->debug->control); | ||
123 | ehci_info (ehci, "debug port %d%s\n", | ||
124 | HCS_DEBUG_PORT(ehci->hcs_params), | ||
125 | (temp & DBGP_ENABLED) | ||
126 | ? " IN USE" | ||
127 | : ""); | ||
128 | if (!(temp & DBGP_ENABLED)) | ||
129 | ehci->debug = NULL; | ||
130 | } | ||
131 | } | ||
132 | |||
133 | temp = HCC_EXT_CAPS (readl (&ehci->caps->hcc_params)); | ||
134 | } else | ||
135 | temp = 0; | ||
136 | |||
137 | /* EHCI 0.96 and later may have "extended capabilities" */ | ||
138 | while (temp && count--) { | ||
139 | u32 cap; | ||
140 | |||
141 | pci_read_config_dword (to_pci_dev(hcd->self.controller), | ||
142 | temp, &cap); | ||
143 | ehci_dbg (ehci, "capability %04x at %02x\n", cap, temp); | ||
144 | switch (cap & 0xff) { | ||
145 | case 1: /* BIOS/SMM/... handoff */ | ||
146 | if (bios_handoff (ehci, temp, cap) != 0) | ||
147 | return -EOPNOTSUPP; | ||
148 | break; | ||
149 | case 0: /* illegal reserved capability */ | ||
150 | ehci_warn (ehci, "illegal capability!\n"); | ||
151 | cap = 0; | ||
152 | /* FALLTHROUGH */ | ||
153 | default: /* unknown */ | ||
154 | break; | ||
155 | } | ||
156 | temp = (cap >> 8) & 0xff; | ||
157 | } | ||
158 | if (!count) { | ||
159 | ehci_err (ehci, "bogus capabilities ... PCI problems!\n"); | ||
160 | return -EIO; | ||
161 | } | ||
162 | if (ehci_is_TDI(ehci)) | ||
163 | ehci_reset (ehci); | ||
164 | |||
165 | ehci_port_power (ehci, 0); | ||
166 | |||
167 | /* at least the Genesys GL880S needs fixup here */ | ||
168 | temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params); | ||
169 | temp &= 0x0f; | ||
170 | if (temp && HCS_N_PORTS(ehci->hcs_params) > temp) { | ||
171 | ehci_dbg (ehci, "bogus port configuration: " | ||
172 | "cc=%d x pcc=%d < ports=%d\n", | ||
173 | HCS_N_CC(ehci->hcs_params), | ||
174 | HCS_N_PCC(ehci->hcs_params), | ||
175 | HCS_N_PORTS(ehci->hcs_params)); | ||
176 | |||
177 | if (hcd->self.controller->bus == &pci_bus_type) { | ||
178 | struct pci_dev *pdev; | ||
179 | |||
180 | pdev = to_pci_dev(hcd->self.controller); | ||
181 | switch (pdev->vendor) { | ||
182 | case 0x17a0: /* GENESYS */ | ||
183 | /* GL880S: should be PORTS=2 */ | ||
184 | temp |= (ehci->hcs_params & ~0xf); | ||
185 | ehci->hcs_params = temp; | ||
186 | break; | ||
187 | case PCI_VENDOR_ID_NVIDIA: | ||
188 | /* NF4: should be PCC=10 */ | ||
189 | break; | ||
190 | } | ||
191 | } | ||
192 | } | ||
193 | |||
194 | /* force HC to halt state */ | ||
195 | return ehci_halt (ehci); | ||
196 | } | ||
197 | |||
198 | static int ehci_pci_start (struct usb_hcd *hcd) | ||
199 | { | ||
200 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | ||
201 | int result = 0; | ||
202 | |||
203 | if (hcd->self.controller->bus == &pci_bus_type) { | ||
204 | struct pci_dev *pdev; | ||
205 | u16 port_wake; | ||
206 | |||
207 | pdev = to_pci_dev(hcd->self.controller); | ||
208 | |||
209 | /* Serial Bus Release Number is at PCI 0x60 offset */ | ||
210 | pci_read_config_byte(pdev, 0x60, &ehci->sbrn); | ||
211 | |||
212 | /* port wake capability, reported by boot firmware */ | ||
213 | pci_read_config_word(pdev, 0x62, &port_wake); | ||
214 | hcd->can_wakeup = (port_wake & 1) != 0; | ||
215 | |||
216 | /* help hc dma work well with cachelines */ | ||
217 | result = pci_set_mwi(pdev); | ||
218 | if (result) | ||
219 | ehci_dbg(ehci, "unable to enable MWI - not fatal.\n"); | ||
220 | } | ||
221 | |||
222 | return ehci_run (hcd); | ||
223 | } | ||
224 | |||
225 | /* always called by thread; normally rmmod */ | ||
226 | |||
227 | static void ehci_pci_stop (struct usb_hcd *hcd) | ||
228 | { | ||
229 | ehci_stop (hcd); | ||
230 | } | ||
231 | |||
232 | /*-------------------------------------------------------------------------*/ | ||
233 | |||
234 | #ifdef CONFIG_PM | ||
235 | |||
236 | /* suspend/resume, section 4.3 */ | ||
237 | |||
238 | /* These routines rely on the bus (pci, platform, etc) | ||
239 | * to handle powerdown and wakeup, and currently also on | ||
240 | * transceivers that don't need any software attention to set up | ||
241 | * the right sort of wakeup. | ||
242 | */ | ||
243 | |||
244 | static int ehci_pci_suspend (struct usb_hcd *hcd, pm_message_t message) | ||
245 | { | ||
246 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | ||
247 | |||
248 | if (time_before (jiffies, ehci->next_statechange)) | ||
249 | msleep (100); | ||
250 | |||
251 | #ifdef CONFIG_USB_SUSPEND | ||
252 | (void) usb_suspend_device (hcd->self.root_hub); | ||
253 | #else | ||
254 | usb_lock_device (hcd->self.root_hub); | ||
255 | (void) ehci_bus_suspend (hcd); | ||
256 | usb_unlock_device (hcd->self.root_hub); | ||
257 | #endif | ||
258 | |||
259 | // save (PCI) FLADJ in case of Vaux power loss | ||
260 | // ... we'd only use it to handle clock skew | ||
261 | |||
262 | return 0; | ||
263 | } | ||
264 | |||
265 | static int ehci_pci_resume (struct usb_hcd *hcd) | ||
266 | { | ||
267 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | ||
268 | unsigned port; | ||
269 | struct usb_device *root = hcd->self.root_hub; | ||
270 | int retval = -EINVAL; | ||
271 | |||
272 | // maybe restore (PCI) FLADJ | ||
273 | |||
274 | if (time_before (jiffies, ehci->next_statechange)) | ||
275 | msleep (100); | ||
276 | |||
277 | /* If any port is suspended (or owned by the companion), | ||
278 | * we know we can/must resume the HC (and mustn't reset it). | ||
279 | */ | ||
280 | for (port = HCS_N_PORTS (ehci->hcs_params); port > 0; ) { | ||
281 | u32 status; | ||
282 | port--; | ||
283 | status = readl (&ehci->regs->port_status [port]); | ||
284 | if (!(status & PORT_POWER)) | ||
285 | continue; | ||
286 | if (status & (PORT_SUSPEND | PORT_OWNER)) { | ||
287 | down (&hcd->self.root_hub->serialize); | ||
288 | retval = ehci_bus_resume (hcd); | ||
289 | up (&hcd->self.root_hub->serialize); | ||
290 | break; | ||
291 | } | ||
292 | if (!root->children [port]) | ||
293 | continue; | ||
294 | dbg_port (ehci, __FUNCTION__, port + 1, status); | ||
295 | usb_set_device_state (root->children[port], | ||
296 | USB_STATE_NOTATTACHED); | ||
297 | } | ||
298 | |||
299 | /* Else reset, to cope with power loss or flush-to-storage | ||
300 | * style "resume" having activated BIOS during reboot. | ||
301 | */ | ||
302 | if (port == 0) { | ||
303 | (void) ehci_halt (ehci); | ||
304 | (void) ehci_reset (ehci); | ||
305 | (void) ehci_pci_reset (hcd); | ||
306 | |||
307 | /* emptying the schedule aborts any urbs */ | ||
308 | spin_lock_irq (&ehci->lock); | ||
309 | if (ehci->reclaim) | ||
310 | ehci->reclaim_ready = 1; | ||
311 | ehci_work (ehci, NULL); | ||
312 | spin_unlock_irq (&ehci->lock); | ||
313 | |||
314 | /* restart; khubd will disconnect devices */ | ||
315 | retval = ehci_run (hcd); | ||
316 | |||
317 | /* here we "know" root ports should always stay powered; | ||
318 | * but some controllers may lose all power. | ||
319 | */ | ||
320 | ehci_port_power (ehci, 1); | ||
321 | } | ||
322 | |||
323 | return retval; | ||
324 | } | ||
325 | #endif | ||
326 | |||
327 | static const struct hc_driver ehci_pci_hc_driver = { | ||
328 | .description = hcd_name, | ||
329 | .product_desc = "EHCI Host Controller", | ||
330 | .hcd_priv_size = sizeof(struct ehci_hcd), | ||
331 | |||
332 | /* | ||
333 | * generic hardware linkage | ||
334 | */ | ||
335 | .irq = ehci_irq, | ||
336 | .flags = HCD_MEMORY | HCD_USB2, | ||
337 | |||
338 | /* | ||
339 | * basic lifecycle operations | ||
340 | */ | ||
341 | .reset = ehci_pci_reset, | ||
342 | .start = ehci_pci_start, | ||
343 | #ifdef CONFIG_PM | ||
344 | .suspend = ehci_pci_suspend, | ||
345 | .resume = ehci_pci_resume, | ||
346 | #endif | ||
347 | .stop = ehci_pci_stop, | ||
348 | |||
349 | /* | ||
350 | * managing i/o requests and associated device resources | ||
351 | */ | ||
352 | .urb_enqueue = ehci_urb_enqueue, | ||
353 | .urb_dequeue = ehci_urb_dequeue, | ||
354 | .endpoint_disable = ehci_endpoint_disable, | ||
355 | |||
356 | /* | ||
357 | * scheduling support | ||
358 | */ | ||
359 | .get_frame_number = ehci_get_frame, | ||
360 | |||
361 | /* | ||
362 | * root hub support | ||
363 | */ | ||
364 | .hub_status_data = ehci_hub_status_data, | ||
365 | .hub_control = ehci_hub_control, | ||
366 | .bus_suspend = ehci_bus_suspend, | ||
367 | .bus_resume = ehci_bus_resume, | ||
368 | }; | ||
369 | |||
370 | /*-------------------------------------------------------------------------*/ | ||
371 | |||
372 | /* PCI driver selection metadata; PCI hotplugging uses this */ | ||
373 | static const struct pci_device_id pci_ids [] = { { | ||
374 | /* handle any USB 2.0 EHCI controller */ | ||
375 | PCI_DEVICE_CLASS(((PCI_CLASS_SERIAL_USB << 8) | 0x20), ~0), | ||
376 | .driver_data = (unsigned long) &ehci_pci_hc_driver, | ||
377 | }, | ||
378 | { /* end: all zeroes */ } | ||
379 | }; | ||
380 | MODULE_DEVICE_TABLE (pci, pci_ids); | ||
381 | |||
382 | /* pci driver glue; this is a "new style" PCI driver module */ | ||
383 | static struct pci_driver ehci_pci_driver = { | ||
384 | .name = (char *) hcd_name, | ||
385 | .id_table = pci_ids, | ||
386 | .owner = THIS_MODULE, | ||
387 | |||
388 | .probe = usb_hcd_pci_probe, | ||
389 | .remove = usb_hcd_pci_remove, | ||
390 | |||
391 | #ifdef CONFIG_PM | ||
392 | .suspend = usb_hcd_pci_suspend, | ||
393 | .resume = usb_hcd_pci_resume, | ||
394 | #endif | ||
395 | }; | ||
396 | |||
397 | static int __init ehci_hcd_pci_init (void) | ||
398 | { | ||
399 | if (usb_disabled()) | ||
400 | return -ENODEV; | ||
401 | |||
402 | pr_debug ("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n", | ||
403 | hcd_name, | ||
404 | sizeof (struct ehci_qh), sizeof (struct ehci_qtd), | ||
405 | sizeof (struct ehci_itd), sizeof (struct ehci_sitd)); | ||
406 | |||
407 | return pci_register_driver (&ehci_pci_driver); | ||
408 | } | ||
409 | module_init (ehci_hcd_pci_init); | ||
410 | |||
411 | static void __exit ehci_hcd_pci_cleanup (void) | ||
412 | { | ||
413 | pci_unregister_driver (&ehci_pci_driver); | ||
414 | } | ||
415 | module_exit (ehci_hcd_pci_cleanup); | ||
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index f34a0516d35f..18e257c2bdb5 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h | |||
@@ -97,6 +97,7 @@ struct ehci_hcd { /* one per controller */ | |||
97 | #else | 97 | #else |
98 | # define COUNT(x) do {} while (0) | 98 | # define COUNT(x) do {} while (0) |
99 | #endif | 99 | #endif |
100 | u8 sbrn; /* packed release number */ | ||
100 | }; | 101 | }; |
101 | 102 | ||
102 | /* convert between an HCD pointer and the corresponding EHCI_HCD */ | 103 | /* convert between an HCD pointer and the corresponding EHCI_HCD */ |
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index 642f35068ce2..ddb8fc591466 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c | |||
@@ -638,7 +638,7 @@ static irqreturn_t isp116x_irq(struct usb_hcd *hcd, struct pt_regs *regs) | |||
638 | + msecs_to_jiffies(20) + 1); | 638 | + msecs_to_jiffies(20) + 1); |
639 | if (intstat & HCINT_RD) { | 639 | if (intstat & HCINT_RD) { |
640 | DBG("---- remote wakeup\n"); | 640 | DBG("---- remote wakeup\n"); |
641 | schedule_work(&isp116x->rh_resume); | 641 | usb_hcd_resume_root_hub(hcd); |
642 | ret = IRQ_HANDLED; | 642 | ret = IRQ_HANDLED; |
643 | } | 643 | } |
644 | irqstat &= ~HCuPINT_OPR; | 644 | irqstat &= ~HCuPINT_OPR; |
@@ -1160,7 +1160,7 @@ static int isp116x_hub_control(struct usb_hcd *hcd, | |||
1160 | 1160 | ||
1161 | #ifdef CONFIG_PM | 1161 | #ifdef CONFIG_PM |
1162 | 1162 | ||
1163 | static int isp116x_hub_suspend(struct usb_hcd *hcd) | 1163 | static int isp116x_bus_suspend(struct usb_hcd *hcd) |
1164 | { | 1164 | { |
1165 | struct isp116x *isp116x = hcd_to_isp116x(hcd); | 1165 | struct isp116x *isp116x = hcd_to_isp116x(hcd); |
1166 | unsigned long flags; | 1166 | unsigned long flags; |
@@ -1200,7 +1200,7 @@ static int isp116x_hub_suspend(struct usb_hcd *hcd) | |||
1200 | return ret; | 1200 | return ret; |
1201 | } | 1201 | } |
1202 | 1202 | ||
1203 | static int isp116x_hub_resume(struct usb_hcd *hcd) | 1203 | static int isp116x_bus_resume(struct usb_hcd *hcd) |
1204 | { | 1204 | { |
1205 | struct isp116x *isp116x = hcd_to_isp116x(hcd); | 1205 | struct isp116x *isp116x = hcd_to_isp116x(hcd); |
1206 | u32 val; | 1206 | u32 val; |
@@ -1263,21 +1263,11 @@ static int isp116x_hub_resume(struct usb_hcd *hcd) | |||
1263 | return 0; | 1263 | return 0; |
1264 | } | 1264 | } |
1265 | 1265 | ||
1266 | static void isp116x_rh_resume(void *_hcd) | ||
1267 | { | ||
1268 | struct usb_hcd *hcd = _hcd; | ||
1269 | |||
1270 | usb_resume_device(hcd->self.root_hub); | ||
1271 | } | ||
1272 | 1266 | ||
1273 | #else | 1267 | #else |
1274 | 1268 | ||
1275 | #define isp116x_hub_suspend NULL | 1269 | #define isp116x_bus_suspend NULL |
1276 | #define isp116x_hub_resume NULL | 1270 | #define isp116x_bus_resume NULL |
1277 | |||
1278 | static void isp116x_rh_resume(void *_hcd) | ||
1279 | { | ||
1280 | } | ||
1281 | 1271 | ||
1282 | #endif | 1272 | #endif |
1283 | 1273 | ||
@@ -1636,8 +1626,8 @@ static struct hc_driver isp116x_hc_driver = { | |||
1636 | 1626 | ||
1637 | .hub_status_data = isp116x_hub_status_data, | 1627 | .hub_status_data = isp116x_hub_status_data, |
1638 | .hub_control = isp116x_hub_control, | 1628 | .hub_control = isp116x_hub_control, |
1639 | .hub_suspend = isp116x_hub_suspend, | 1629 | .bus_suspend = isp116x_bus_suspend, |
1640 | .hub_resume = isp116x_hub_resume, | 1630 | .bus_resume = isp116x_bus_resume, |
1641 | }; | 1631 | }; |
1642 | 1632 | ||
1643 | /*----------------------------------------------------------------*/ | 1633 | /*----------------------------------------------------------------*/ |
@@ -1732,7 +1722,6 @@ static int __init isp116x_probe(struct device *dev) | |||
1732 | isp116x->addr_reg = addr_reg; | 1722 | isp116x->addr_reg = addr_reg; |
1733 | spin_lock_init(&isp116x->lock); | 1723 | spin_lock_init(&isp116x->lock); |
1734 | INIT_LIST_HEAD(&isp116x->async); | 1724 | INIT_LIST_HEAD(&isp116x->async); |
1735 | INIT_WORK(&isp116x->rh_resume, isp116x_rh_resume, hcd); | ||
1736 | isp116x->board = dev->platform_data; | 1725 | isp116x->board = dev->platform_data; |
1737 | 1726 | ||
1738 | if (!isp116x->board) { | 1727 | if (!isp116x->board) { |
@@ -1777,16 +1766,10 @@ static int __init isp116x_probe(struct device *dev) | |||
1777 | static int isp116x_suspend(struct device *dev, pm_message_t state) | 1766 | static int isp116x_suspend(struct device *dev, pm_message_t state) |
1778 | { | 1767 | { |
1779 | int ret = 0; | 1768 | int ret = 0; |
1780 | struct usb_hcd *hcd = dev_get_drvdata(dev); | ||
1781 | 1769 | ||
1782 | VDBG("%s: state %x\n", __func__, state); | 1770 | VDBG("%s: state %x\n", __func__, state); |
1783 | 1771 | ||
1784 | ret = usb_suspend_device(hcd->self.root_hub, state); | 1772 | dev->power.power_state = state; |
1785 | if (!ret) { | ||
1786 | dev->power.power_state = state; | ||
1787 | INFO("%s suspended\n", hcd_name); | ||
1788 | } else | ||
1789 | ERR("%s suspend failed\n", hcd_name); | ||
1790 | 1773 | ||
1791 | return ret; | 1774 | return ret; |
1792 | } | 1775 | } |
@@ -1797,15 +1780,11 @@ static int isp116x_suspend(struct device *dev, pm_message_t state) | |||
1797 | static int isp116x_resume(struct device *dev) | 1780 | static int isp116x_resume(struct device *dev) |
1798 | { | 1781 | { |
1799 | int ret = 0; | 1782 | int ret = 0; |
1800 | struct usb_hcd *hcd = dev_get_drvdata(dev); | ||
1801 | 1783 | ||
1802 | VDBG("%s: state %x\n", __func__, dev->power.power_state); | 1784 | VDBG("%s: state %x\n", __func__, dev->power.power_state); |
1803 | 1785 | ||
1804 | ret = usb_resume_device(hcd->self.root_hub); | 1786 | dev->power.power_state = PMSG_ON; |
1805 | if (!ret) { | 1787 | |
1806 | dev->power.power_state = PMSG_ON; | ||
1807 | VDBG("%s resumed\n", (char *)hcd_name); | ||
1808 | } | ||
1809 | return ret; | 1788 | return ret; |
1810 | } | 1789 | } |
1811 | 1790 | ||
diff --git a/drivers/usb/host/isp116x.h b/drivers/usb/host/isp116x.h index 58873470dcf5..c6fec96785fe 100644 --- a/drivers/usb/host/isp116x.h +++ b/drivers/usb/host/isp116x.h | |||
@@ -253,7 +253,6 @@ static const int cc_to_error[16] = { | |||
253 | 253 | ||
254 | struct isp116x { | 254 | struct isp116x { |
255 | spinlock_t lock; | 255 | spinlock_t lock; |
256 | struct work_struct rh_resume; | ||
257 | 256 | ||
258 | void __iomem *addr_reg; | 257 | void __iomem *addr_reg; |
259 | void __iomem *data_reg; | 258 | void __iomem *data_reg; |
diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c index 3981bf15c8c7..a277e258eb6c 100644 --- a/drivers/usb/host/ohci-au1xxx.c +++ b/drivers/usb/host/ohci-au1xxx.c | |||
@@ -214,6 +214,11 @@ static const struct hc_driver ohci_au1xxx_hc_driver = { | |||
214 | */ | 214 | */ |
215 | .hub_status_data = ohci_hub_status_data, | 215 | .hub_status_data = ohci_hub_status_data, |
216 | .hub_control = ohci_hub_control, | 216 | .hub_control = ohci_hub_control, |
217 | #ifdef CONFIG_PM | ||
218 | .bus_suspend = ohci_bus_suspend, | ||
219 | .bus_resume = ohci_bus_resume, | ||
220 | #endif | ||
221 | .start_port_reset = ohci_start_port_reset, | ||
217 | }; | 222 | }; |
218 | 223 | ||
219 | /*-------------------------------------------------------------------------*/ | 224 | /*-------------------------------------------------------------------------*/ |
@@ -259,6 +264,7 @@ static int ohci_hcd_au1xxx_drv_resume(struct device *dev) | |||
259 | 264 | ||
260 | static struct device_driver ohci_hcd_au1xxx_driver = { | 265 | static struct device_driver ohci_hcd_au1xxx_driver = { |
261 | .name = "au1xxx-ohci", | 266 | .name = "au1xxx-ohci", |
267 | .owner = THIS_MODULE, | ||
262 | .bus = &platform_bus_type, | 268 | .bus = &platform_bus_type, |
263 | .probe = ohci_hcd_au1xxx_drv_probe, | 269 | .probe = ohci_hcd_au1xxx_drv_probe, |
264 | .remove = ohci_hcd_au1xxx_drv_remove, | 270 | .remove = ohci_hcd_au1xxx_drv_remove, |
diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c index 7924c74f958e..7bfffcbbd226 100644 --- a/drivers/usb/host/ohci-dbg.c +++ b/drivers/usb/host/ohci-dbg.c | |||
@@ -193,10 +193,6 @@ ohci_dump_status (struct ohci_hcd *controller, char **next, unsigned *size) | |||
193 | 193 | ||
194 | maybe_print_eds (controller, "donehead", | 194 | maybe_print_eds (controller, "donehead", |
195 | ohci_readl (controller, ®s->donehead), next, size); | 195 | ohci_readl (controller, ®s->donehead), next, size); |
196 | |||
197 | /* broken fminterval means traffic won't flow! */ | ||
198 | ohci_dbg (controller, "fminterval %08x\n", | ||
199 | ohci_readl (controller, ®s->fminterval)); | ||
200 | } | 196 | } |
201 | 197 | ||
202 | #define dbg_port_sw(hc,num,value,next,size) \ | 198 | #define dbg_port_sw(hc,num,value,next,size) \ |
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index f8da8c7af7c6..5c0c6c8a7a82 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -723,7 +723,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs) | |||
723 | ohci_vdbg (ohci, "resume detect\n"); | 723 | ohci_vdbg (ohci, "resume detect\n"); |
724 | ohci_writel (ohci, OHCI_INTR_RD, ®s->intrstatus); | 724 | ohci_writel (ohci, OHCI_INTR_RD, ®s->intrstatus); |
725 | if (hcd->state != HC_STATE_QUIESCING) | 725 | if (hcd->state != HC_STATE_QUIESCING) |
726 | schedule_work(&ohci->rh_resume); | 726 | usb_hcd_resume_root_hub(hcd); |
727 | } | 727 | } |
728 | 728 | ||
729 | if (ints & OHCI_INTR_WDH) { | 729 | if (ints & OHCI_INTR_WDH) { |
@@ -791,7 +791,7 @@ static void ohci_stop (struct usb_hcd *hcd) | |||
791 | 791 | ||
792 | /* must not be called from interrupt context */ | 792 | /* must not be called from interrupt context */ |
793 | 793 | ||
794 | #if defined(CONFIG_USB_SUSPEND) || defined(CONFIG_PM) | 794 | #ifdef CONFIG_PM |
795 | 795 | ||
796 | static int ohci_restart (struct ohci_hcd *ohci) | 796 | static int ohci_restart (struct ohci_hcd *ohci) |
797 | { | 797 | { |
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index ce7b28da7a15..e01e77bc324b 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c | |||
@@ -36,7 +36,7 @@ | |||
36 | 36 | ||
37 | /*-------------------------------------------------------------------------*/ | 37 | /*-------------------------------------------------------------------------*/ |
38 | 38 | ||
39 | #if defined(CONFIG_USB_SUSPEND) || defined(CONFIG_PM) | 39 | #ifdef CONFIG_PM |
40 | 40 | ||
41 | #define OHCI_SCHED_ENABLES \ | 41 | #define OHCI_SCHED_ENABLES \ |
42 | (OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_PLE|OHCI_CTRL_IE) | 42 | (OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_PLE|OHCI_CTRL_IE) |
@@ -45,7 +45,7 @@ static void dl_done_list (struct ohci_hcd *, struct pt_regs *); | |||
45 | static void finish_unlinks (struct ohci_hcd *, u16 , struct pt_regs *); | 45 | static void finish_unlinks (struct ohci_hcd *, u16 , struct pt_regs *); |
46 | static int ohci_restart (struct ohci_hcd *ohci); | 46 | static int ohci_restart (struct ohci_hcd *ohci); |
47 | 47 | ||
48 | static int ohci_hub_suspend (struct usb_hcd *hcd) | 48 | static int ohci_bus_suspend (struct usb_hcd *hcd) |
49 | { | 49 | { |
50 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 50 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
51 | int status = 0; | 51 | int status = 0; |
@@ -73,7 +73,6 @@ static int ohci_hub_suspend (struct usb_hcd *hcd) | |||
73 | ohci_dbg (ohci, "suspend root hub\n"); | 73 | ohci_dbg (ohci, "suspend root hub\n"); |
74 | 74 | ||
75 | /* First stop any processing */ | 75 | /* First stop any processing */ |
76 | hcd->state = HC_STATE_QUIESCING; | ||
77 | if (ohci->hc_control & OHCI_SCHED_ENABLES) { | 76 | if (ohci->hc_control & OHCI_SCHED_ENABLES) { |
78 | int limit; | 77 | int limit; |
79 | 78 | ||
@@ -108,7 +107,9 @@ static int ohci_hub_suspend (struct usb_hcd *hcd) | |||
108 | else | 107 | else |
109 | ohci->hc_control &= ~OHCI_CTRL_RWE; | 108 | ohci->hc_control &= ~OHCI_CTRL_RWE; |
110 | 109 | ||
111 | /* Suspend hub */ | 110 | /* Suspend hub ... this is the "global (to this bus) suspend" mode, |
111 | * which doesn't imply ports will first be individually suspended. | ||
112 | */ | ||
112 | ohci->hc_control &= ~OHCI_CTRL_HCFS; | 113 | ohci->hc_control &= ~OHCI_CTRL_HCFS; |
113 | ohci->hc_control |= OHCI_USB_SUSPEND; | 114 | ohci->hc_control |= OHCI_USB_SUSPEND; |
114 | ohci_writel (ohci, ohci->hc_control, &ohci->regs->control); | 115 | ohci_writel (ohci, ohci->hc_control, &ohci->regs->control); |
@@ -118,8 +119,9 @@ static int ohci_hub_suspend (struct usb_hcd *hcd) | |||
118 | ohci->next_statechange = jiffies + msecs_to_jiffies (5); | 119 | ohci->next_statechange = jiffies + msecs_to_jiffies (5); |
119 | 120 | ||
120 | done: | 121 | done: |
122 | /* external suspend vs self autosuspend ... same effect */ | ||
121 | if (status == 0) | 123 | if (status == 0) |
122 | hcd->state = HC_STATE_SUSPENDED; | 124 | usb_hcd_suspend_root_hub(hcd); |
123 | spin_unlock_irqrestore (&ohci->lock, flags); | 125 | spin_unlock_irqrestore (&ohci->lock, flags); |
124 | return status; | 126 | return status; |
125 | } | 127 | } |
@@ -133,7 +135,7 @@ static inline struct ed *find_head (struct ed *ed) | |||
133 | } | 135 | } |
134 | 136 | ||
135 | /* caller has locked the root hub */ | 137 | /* caller has locked the root hub */ |
136 | static int ohci_hub_resume (struct usb_hcd *hcd) | 138 | static int ohci_bus_resume (struct usb_hcd *hcd) |
137 | { | 139 | { |
138 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 140 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
139 | u32 temp, enables; | 141 | u32 temp, enables; |
@@ -146,7 +148,7 @@ static int ohci_hub_resume (struct usb_hcd *hcd) | |||
146 | ohci->hc_control = ohci_readl (ohci, &ohci->regs->control); | 148 | ohci->hc_control = ohci_readl (ohci, &ohci->regs->control); |
147 | 149 | ||
148 | if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) { | 150 | if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) { |
149 | /* this can happen after suspend-to-disk */ | 151 | /* this can happen after resuming a swsusp snapshot */ |
150 | if (hcd->state == HC_STATE_RESUMING) { | 152 | if (hcd->state == HC_STATE_RESUMING) { |
151 | ohci_dbg (ohci, "BIOS/SMM active, control %03x\n", | 153 | ohci_dbg (ohci, "BIOS/SMM active, control %03x\n", |
152 | ohci->hc_control); | 154 | ohci->hc_control); |
@@ -169,11 +171,12 @@ static int ohci_hub_resume (struct usb_hcd *hcd) | |||
169 | ohci_info (ohci, "wakeup\n"); | 171 | ohci_info (ohci, "wakeup\n"); |
170 | break; | 172 | break; |
171 | case OHCI_USB_OPER: | 173 | case OHCI_USB_OPER: |
172 | ohci_dbg (ohci, "already resumed\n"); | 174 | /* this can happen after resuming a swsusp snapshot */ |
173 | status = 0; | 175 | ohci_dbg (ohci, "snapshot resume? reinit\n"); |
176 | status = -EBUSY; | ||
174 | break; | 177 | break; |
175 | default: /* RESET, we lost power */ | 178 | default: /* RESET, we lost power */ |
176 | ohci_dbg (ohci, "root hub hardware reset\n"); | 179 | ohci_dbg (ohci, "lost power\n"); |
177 | status = -EBUSY; | 180 | status = -EBUSY; |
178 | } | 181 | } |
179 | spin_unlock_irq (&ohci->lock); | 182 | spin_unlock_irq (&ohci->lock); |
@@ -198,8 +201,7 @@ static int ohci_hub_resume (struct usb_hcd *hcd) | |||
198 | } | 201 | } |
199 | 202 | ||
200 | /* Some controllers (lucent erratum) need extra-long delays */ | 203 | /* Some controllers (lucent erratum) need extra-long delays */ |
201 | hcd->state = HC_STATE_RESUMING; | 204 | msleep (20 /* usb 11.5.1.10 */ + 12 /* 32 msec counter */ + 1); |
202 | mdelay (20 /* usb 11.5.1.10 */ + 15); | ||
203 | 205 | ||
204 | temp = ohci_readl (ohci, &ohci->regs->control); | 206 | temp = ohci_readl (ohci, &ohci->regs->control); |
205 | temp &= OHCI_CTRL_HCFS; | 207 | temp &= OHCI_CTRL_HCFS; |
@@ -273,28 +275,10 @@ static int ohci_hub_resume (struct usb_hcd *hcd) | |||
273 | (void) ohci_readl (ohci, &ohci->regs->control); | 275 | (void) ohci_readl (ohci, &ohci->regs->control); |
274 | } | 276 | } |
275 | 277 | ||
276 | hcd->state = HC_STATE_RUNNING; | ||
277 | return 0; | 278 | return 0; |
278 | } | 279 | } |
279 | 280 | ||
280 | static void ohci_rh_resume (void *_hcd) | 281 | #endif /* CONFIG_PM */ |
281 | { | ||
282 | struct usb_hcd *hcd = _hcd; | ||
283 | |||
284 | usb_lock_device (hcd->self.root_hub); | ||
285 | (void) ohci_hub_resume (hcd); | ||
286 | usb_unlock_device (hcd->self.root_hub); | ||
287 | } | ||
288 | |||
289 | #else | ||
290 | |||
291 | static void ohci_rh_resume (void *_hcd) | ||
292 | { | ||
293 | struct ohci_hcd *ohci = hcd_to_ohci (_hcd); | ||
294 | ohci_dbg(ohci, "rh_resume ??\n"); | ||
295 | } | ||
296 | |||
297 | #endif /* CONFIG_USB_SUSPEND || CONFIG_PM */ | ||
298 | 282 | ||
299 | /*-------------------------------------------------------------------------*/ | 283 | /*-------------------------------------------------------------------------*/ |
300 | 284 | ||
@@ -367,7 +351,6 @@ done: | |||
367 | #ifdef CONFIG_PM | 351 | #ifdef CONFIG_PM |
368 | /* save power by suspending idle root hubs; | 352 | /* save power by suspending idle root hubs; |
369 | * INTR_RD wakes us when there's work | 353 | * INTR_RD wakes us when there's work |
370 | * NOTE: if we can do this, we don't need a root hub timer! | ||
371 | */ | 354 | */ |
372 | if (can_suspend | 355 | if (can_suspend |
373 | && !changed | 356 | && !changed |
@@ -379,8 +362,7 @@ done: | |||
379 | && usb_trylock_device (hcd->self.root_hub) | 362 | && usb_trylock_device (hcd->self.root_hub) |
380 | ) { | 363 | ) { |
381 | ohci_vdbg (ohci, "autosuspend\n"); | 364 | ohci_vdbg (ohci, "autosuspend\n"); |
382 | (void) ohci_hub_suspend (hcd); | 365 | (void) ohci_bus_suspend (hcd); |
383 | hcd->state = HC_STATE_RUNNING; | ||
384 | usb_unlock_device (hcd->self.root_hub); | 366 | usb_unlock_device (hcd->self.root_hub); |
385 | } | 367 | } |
386 | #endif | 368 | #endif |
@@ -554,7 +536,7 @@ static int ohci_hub_control ( | |||
554 | temp = RH_PS_POCI; | 536 | temp = RH_PS_POCI; |
555 | if ((ohci->hc_control & OHCI_CTRL_HCFS) | 537 | if ((ohci->hc_control & OHCI_CTRL_HCFS) |
556 | != OHCI_USB_OPER) | 538 | != OHCI_USB_OPER) |
557 | schedule_work (&ohci->rh_resume); | 539 | usb_hcd_resume_root_hub(hcd); |
558 | break; | 540 | break; |
559 | case USB_PORT_FEAT_C_SUSPEND: | 541 | case USB_PORT_FEAT_C_SUSPEND: |
560 | temp = RH_PS_PSSC; | 542 | temp = RH_PS_PSSC; |
diff --git a/drivers/usb/host/ohci-lh7a404.c b/drivers/usb/host/ohci-lh7a404.c index 859aca7be753..238fa4ade615 100644 --- a/drivers/usb/host/ohci-lh7a404.c +++ b/drivers/usb/host/ohci-lh7a404.c | |||
@@ -193,6 +193,11 @@ static const struct hc_driver ohci_lh7a404_hc_driver = { | |||
193 | */ | 193 | */ |
194 | .hub_status_data = ohci_hub_status_data, | 194 | .hub_status_data = ohci_hub_status_data, |
195 | .hub_control = ohci_hub_control, | 195 | .hub_control = ohci_hub_control, |
196 | #ifdef CONFIG_PM | ||
197 | .bus_suspend = ohci_bus_suspend, | ||
198 | .bus_resume = ohci_bus_resume, | ||
199 | #endif | ||
200 | .start_port_reset = ohci_start_port_reset, | ||
196 | }; | 201 | }; |
197 | 202 | ||
198 | /*-------------------------------------------------------------------------*/ | 203 | /*-------------------------------------------------------------------------*/ |
@@ -239,6 +244,7 @@ static int ohci_hcd_lh7a404_drv_resume(struct device *dev) | |||
239 | 244 | ||
240 | static struct device_driver ohci_hcd_lh7a404_driver = { | 245 | static struct device_driver ohci_hcd_lh7a404_driver = { |
241 | .name = "lh7a404-ohci", | 246 | .name = "lh7a404-ohci", |
247 | .owner = THIS_MODULE, | ||
242 | .bus = &platform_bus_type, | 248 | .bus = &platform_bus_type, |
243 | .probe = ohci_hcd_lh7a404_drv_probe, | 249 | .probe = ohci_hcd_lh7a404_drv_probe, |
244 | .remove = ohci_hcd_lh7a404_drv_remove, | 250 | .remove = ohci_hcd_lh7a404_drv_remove, |
diff --git a/drivers/usb/host/ohci-mem.c b/drivers/usb/host/ohci-mem.c index 9fb83dfb1eb4..bfbe328a4788 100644 --- a/drivers/usb/host/ohci-mem.c +++ b/drivers/usb/host/ohci-mem.c | |||
@@ -28,7 +28,6 @@ static void ohci_hcd_init (struct ohci_hcd *ohci) | |||
28 | ohci->next_statechange = jiffies; | 28 | ohci->next_statechange = jiffies; |
29 | spin_lock_init (&ohci->lock); | 29 | spin_lock_init (&ohci->lock); |
30 | INIT_LIST_HEAD (&ohci->pending); | 30 | INIT_LIST_HEAD (&ohci->pending); |
31 | INIT_WORK (&ohci->rh_resume, ohci_rh_resume, ohci_to_hcd(ohci)); | ||
32 | ohci->reboot_notifier.notifier_call = ohci_reboot; | 31 | ohci->reboot_notifier.notifier_call = ohci_reboot; |
33 | } | 32 | } |
34 | 33 | ||
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index a574216625a0..45efeed1fcc3 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c | |||
@@ -420,9 +420,9 @@ static const struct hc_driver ohci_omap_hc_driver = { | |||
420 | */ | 420 | */ |
421 | .hub_status_data = ohci_hub_status_data, | 421 | .hub_status_data = ohci_hub_status_data, |
422 | .hub_control = ohci_hub_control, | 422 | .hub_control = ohci_hub_control, |
423 | #ifdef CONFIG_USB_SUSPEND | 423 | #ifdef CONFIG_PM |
424 | .hub_suspend = ohci_hub_suspend, | 424 | .bus_suspend = ohci_bus_suspend, |
425 | .hub_resume = ohci_hub_resume, | 425 | .bus_resume = ohci_bus_resume, |
426 | #endif | 426 | #endif |
427 | .start_port_reset = ohci_start_port_reset, | 427 | .start_port_reset = ohci_start_port_reset, |
428 | }; | 428 | }; |
@@ -458,41 +458,29 @@ static int ohci_hcd_omap_drv_remove(struct device *dev) | |||
458 | static int ohci_omap_suspend(struct device *dev, pm_message_t message) | 458 | static int ohci_omap_suspend(struct device *dev, pm_message_t message) |
459 | { | 459 | { |
460 | struct ohci_hcd *ohci = hcd_to_ohci(dev_get_drvdata(dev)); | 460 | struct ohci_hcd *ohci = hcd_to_ohci(dev_get_drvdata(dev)); |
461 | int status = -EINVAL; | 461 | |
462 | 462 | if (time_before(jiffies, ohci->next_statechange)) | |
463 | down(&ohci_to_hcd(ohci)->self.root_hub->serialize); | 463 | msleep(5); |
464 | status = ohci_hub_suspend(ohci_to_hcd(ohci)); | 464 | ohci->next_statechange = jiffies; |
465 | if (status == 0) { | 465 | |
466 | omap_ohci_clock_power(0); | 466 | omap_ohci_clock_power(0); |
467 | ohci_to_hcd(ohci)->self.root_hub->state = | 467 | ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED; |
468 | USB_STATE_SUSPENDED; | 468 | dev->power.power_state = PMSG_SUSPEND; |
469 | ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED; | 469 | return 0; |
470 | dev->power.power_state = PMSG_SUSPEND; | ||
471 | } | ||
472 | up(&ohci_to_hcd(ohci)->self.root_hub->serialize); | ||
473 | return status; | ||
474 | } | 470 | } |
475 | 471 | ||
476 | static int ohci_omap_resume(struct device *dev) | 472 | static int ohci_omap_resume(struct device *dev) |
477 | { | 473 | { |
478 | struct ohci_hcd *ohci = hcd_to_ohci(dev_get_drvdata(dev)); | 474 | struct ohci_hcd *ohci = hcd_to_ohci(dev_get_drvdata(dev)); |
479 | int status = 0; | ||
480 | 475 | ||
481 | if (time_before(jiffies, ohci->next_statechange)) | 476 | if (time_before(jiffies, ohci->next_statechange)) |
482 | msleep(5); | 477 | msleep(5); |
483 | ohci->next_statechange = jiffies; | 478 | ohci->next_statechange = jiffies; |
479 | |||
484 | omap_ohci_clock_power(1); | 480 | omap_ohci_clock_power(1); |
485 | #ifdef CONFIG_USB_SUSPEND | 481 | dev->power.power_state = PMSG_ON; |
486 | /* get extra cleanup even if remote wakeup isn't in use */ | 482 | usb_hcd_resume_root_hub(dev_get_drvdata(dev)); |
487 | status = usb_resume_device(ohci_to_hcd(ohci)->self.root_hub); | 483 | return 0; |
488 | #else | ||
489 | down(&ohci_to_hcd(ohci)->self.root_hub->serialize); | ||
490 | status = ohci_hub_resume(ohci_to_hcd(ohci)); | ||
491 | up(&ohci_to_hcd(ohci)->self.root_hub->serialize); | ||
492 | #endif | ||
493 | if (status == 0) | ||
494 | dev->power.power_state = PMSG_ON; | ||
495 | return status; | ||
496 | } | 484 | } |
497 | 485 | ||
498 | #endif | 486 | #endif |
@@ -504,6 +492,7 @@ static int ohci_omap_resume(struct device *dev) | |||
504 | */ | 492 | */ |
505 | static struct device_driver ohci_hcd_omap_driver = { | 493 | static struct device_driver ohci_hcd_omap_driver = { |
506 | .name = "ohci", | 494 | .name = "ohci", |
495 | .owner = THIS_MODULE, | ||
507 | .bus = &platform_bus_type, | 496 | .bus = &platform_bus_type, |
508 | .probe = ohci_hcd_omap_drv_probe, | 497 | .probe = ohci_hcd_omap_drv_probe, |
509 | .remove = ohci_hcd_omap_drv_remove, | 498 | .remove = ohci_hcd_omap_drv_remove, |
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index eede6be098d2..bf1d5ab4aa3a 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c | |||
@@ -112,23 +112,13 @@ ohci_pci_start (struct usb_hcd *hcd) | |||
112 | 112 | ||
113 | static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message) | 113 | static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message) |
114 | { | 114 | { |
115 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 115 | /* root hub was already suspended */ |
116 | |||
117 | /* suspend root hub, hoping it keeps power during suspend */ | ||
118 | if (time_before (jiffies, ohci->next_statechange)) | ||
119 | msleep (100); | ||
120 | |||
121 | #ifdef CONFIG_USB_SUSPEND | ||
122 | (void) usb_suspend_device (hcd->self.root_hub, message); | ||
123 | #else | ||
124 | usb_lock_device (hcd->self.root_hub); | ||
125 | (void) ohci_hub_suspend (hcd); | ||
126 | usb_unlock_device (hcd->self.root_hub); | ||
127 | #endif | ||
128 | 116 | ||
129 | /* let things settle down a bit */ | 117 | /* FIXME these PMAC things get called in the wrong places. ASIC |
130 | msleep (100); | 118 | * clocks should be turned off AFTER entering D3, and on BEFORE |
131 | 119 | * trying to enter D0. Evidently the PCI layer doesn't currently | |
120 | * provide the right sort of platform hooks for this ... | ||
121 | */ | ||
132 | #ifdef CONFIG_PPC_PMAC | 122 | #ifdef CONFIG_PPC_PMAC |
133 | if (_machine == _MACH_Pmac) { | 123 | if (_machine == _MACH_Pmac) { |
134 | struct device_node *of_node; | 124 | struct device_node *of_node; |
@@ -145,9 +135,6 @@ static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message) | |||
145 | 135 | ||
146 | static int ohci_pci_resume (struct usb_hcd *hcd) | 136 | static int ohci_pci_resume (struct usb_hcd *hcd) |
147 | { | 137 | { |
148 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | ||
149 | int retval = 0; | ||
150 | |||
151 | #ifdef CONFIG_PPC_PMAC | 138 | #ifdef CONFIG_PPC_PMAC |
152 | if (_machine == _MACH_Pmac) { | 139 | if (_machine == _MACH_Pmac) { |
153 | struct device_node *of_node; | 140 | struct device_node *of_node; |
@@ -159,19 +146,8 @@ static int ohci_pci_resume (struct usb_hcd *hcd) | |||
159 | } | 146 | } |
160 | #endif /* CONFIG_PPC_PMAC */ | 147 | #endif /* CONFIG_PPC_PMAC */ |
161 | 148 | ||
162 | /* resume root hub */ | 149 | usb_hcd_resume_root_hub(hcd); |
163 | if (time_before (jiffies, ohci->next_statechange)) | 150 | return 0; |
164 | msleep (100); | ||
165 | #ifdef CONFIG_USB_SUSPEND | ||
166 | /* get extra cleanup even if remote wakeup isn't in use */ | ||
167 | retval = usb_resume_device (hcd->self.root_hub); | ||
168 | #else | ||
169 | usb_lock_device (hcd->self.root_hub); | ||
170 | retval = ohci_hub_resume (hcd); | ||
171 | usb_unlock_device (hcd->self.root_hub); | ||
172 | #endif | ||
173 | |||
174 | return retval; | ||
175 | } | 151 | } |
176 | 152 | ||
177 | #endif /* CONFIG_PM */ | 153 | #endif /* CONFIG_PM */ |
@@ -218,9 +194,9 @@ static const struct hc_driver ohci_pci_hc_driver = { | |||
218 | */ | 194 | */ |
219 | .hub_status_data = ohci_hub_status_data, | 195 | .hub_status_data = ohci_hub_status_data, |
220 | .hub_control = ohci_hub_control, | 196 | .hub_control = ohci_hub_control, |
221 | #ifdef CONFIG_USB_SUSPEND | 197 | #ifdef CONFIG_PM |
222 | .hub_suspend = ohci_hub_suspend, | 198 | .bus_suspend = ohci_bus_suspend, |
223 | .hub_resume = ohci_hub_resume, | 199 | .bus_resume = ohci_bus_resume, |
224 | #endif | 200 | #endif |
225 | .start_port_reset = ohci_start_port_reset, | 201 | .start_port_reset = ohci_start_port_reset, |
226 | }; | 202 | }; |
@@ -240,6 +216,7 @@ MODULE_DEVICE_TABLE (pci, pci_ids); | |||
240 | static struct pci_driver ohci_pci_driver = { | 216 | static struct pci_driver ohci_pci_driver = { |
241 | .name = (char *) hcd_name, | 217 | .name = (char *) hcd_name, |
242 | .id_table = pci_ids, | 218 | .id_table = pci_ids, |
219 | .owner = THIS_MODULE, | ||
243 | 220 | ||
244 | .probe = usb_hcd_pci_probe, | 221 | .probe = usb_hcd_pci_probe, |
245 | .remove = usb_hcd_pci_remove, | 222 | .remove = usb_hcd_pci_remove, |
diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c index 251533363028..4832e57ae579 100644 --- a/drivers/usb/host/ohci-ppc-soc.c +++ b/drivers/usb/host/ohci-ppc-soc.c | |||
@@ -163,9 +163,9 @@ static const struct hc_driver ohci_ppc_soc_hc_driver = { | |||
163 | */ | 163 | */ |
164 | .hub_status_data = ohci_hub_status_data, | 164 | .hub_status_data = ohci_hub_status_data, |
165 | .hub_control = ohci_hub_control, | 165 | .hub_control = ohci_hub_control, |
166 | #ifdef CONFIG_USB_SUSPEND | 166 | #ifdef CONFIG_PM |
167 | .hub_suspend = ohci_hub_suspend, | 167 | .bus_suspend = ohci_bus_suspend, |
168 | .hub_resume = ohci_hub_resume, | 168 | .bus_resume = ohci_bus_resume, |
169 | #endif | 169 | #endif |
170 | .start_port_reset = ohci_start_port_reset, | 170 | .start_port_reset = ohci_start_port_reset, |
171 | }; | 171 | }; |
@@ -193,10 +193,11 @@ static int ohci_hcd_ppc_soc_drv_remove(struct device *dev) | |||
193 | 193 | ||
194 | static struct device_driver ohci_hcd_ppc_soc_driver = { | 194 | static struct device_driver ohci_hcd_ppc_soc_driver = { |
195 | .name = "ppc-soc-ohci", | 195 | .name = "ppc-soc-ohci", |
196 | .owner = THIS_MODULE, | ||
196 | .bus = &platform_bus_type, | 197 | .bus = &platform_bus_type, |
197 | .probe = ohci_hcd_ppc_soc_drv_probe, | 198 | .probe = ohci_hcd_ppc_soc_drv_probe, |
198 | .remove = ohci_hcd_ppc_soc_drv_remove, | 199 | .remove = ohci_hcd_ppc_soc_drv_remove, |
199 | #if defined(CONFIG_USB_SUSPEND) || defined(CONFIG_PM) | 200 | #ifdef CONFIG_PM |
200 | /*.suspend = ohci_hcd_ppc_soc_drv_suspend,*/ | 201 | /*.suspend = ohci_hcd_ppc_soc_drv_suspend,*/ |
201 | /*.resume = ohci_hcd_ppc_soc_drv_resume,*/ | 202 | /*.resume = ohci_hcd_ppc_soc_drv_resume,*/ |
202 | #endif | 203 | #endif |
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index f042261ecb8e..d287dcccd415 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c | |||
@@ -278,10 +278,11 @@ static const struct hc_driver ohci_pxa27x_hc_driver = { | |||
278 | */ | 278 | */ |
279 | .hub_status_data = ohci_hub_status_data, | 279 | .hub_status_data = ohci_hub_status_data, |
280 | .hub_control = ohci_hub_control, | 280 | .hub_control = ohci_hub_control, |
281 | #ifdef CONFIG_USB_SUSPEND | 281 | #ifdef CONFIG_PM |
282 | .hub_suspend = ohci_hub_suspend, | 282 | .bus_suspend = ohci_bus_suspend, |
283 | .hub_resume = ohci_hub_resume, | 283 | .bus_resume = ohci_bus_resume, |
284 | #endif | 284 | #endif |
285 | .start_port_reset = ohci_start_port_reset, | ||
285 | }; | 286 | }; |
286 | 287 | ||
287 | /*-------------------------------------------------------------------------*/ | 288 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index da7d5478f74d..fab420a2ce71 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c | |||
@@ -448,11 +448,11 @@ static const struct hc_driver ohci_s3c2410_hc_driver = { | |||
448 | */ | 448 | */ |
449 | .hub_status_data = ohci_s3c2410_hub_status_data, | 449 | .hub_status_data = ohci_s3c2410_hub_status_data, |
450 | .hub_control = ohci_s3c2410_hub_control, | 450 | .hub_control = ohci_s3c2410_hub_control, |
451 | 451 | #ifdef CONFIG_PM | |
452 | #if defined(CONFIG_USB_SUSPEND) && 0 | 452 | .bus_suspend = ohci_bus_suspend, |
453 | .hub_suspend = ohci_hub_suspend, | 453 | .bus_resume = ohci_bus_resume, |
454 | .hub_resume = ohci_hub_resume, | ||
455 | #endif | 454 | #endif |
455 | .start_port_reset = ohci_start_port_reset, | ||
456 | }; | 456 | }; |
457 | 457 | ||
458 | /* device driver */ | 458 | /* device driver */ |
@@ -474,6 +474,7 @@ static int ohci_hcd_s3c2410_drv_remove(struct device *dev) | |||
474 | 474 | ||
475 | static struct device_driver ohci_hcd_s3c2410_driver = { | 475 | static struct device_driver ohci_hcd_s3c2410_driver = { |
476 | .name = "s3c2410-ohci", | 476 | .name = "s3c2410-ohci", |
477 | .owner = THIS_MODULE, | ||
477 | .bus = &platform_bus_type, | 478 | .bus = &platform_bus_type, |
478 | .probe = ohci_hcd_s3c2410_drv_probe, | 479 | .probe = ohci_hcd_s3c2410_drv_probe, |
479 | .remove = ohci_hcd_s3c2410_drv_remove, | 480 | .remove = ohci_hcd_s3c2410_drv_remove, |
diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c index 814d2be4ee7b..fb3221ebbb29 100644 --- a/drivers/usb/host/ohci-sa1111.c +++ b/drivers/usb/host/ohci-sa1111.c | |||
@@ -235,10 +235,11 @@ static const struct hc_driver ohci_sa1111_hc_driver = { | |||
235 | */ | 235 | */ |
236 | .hub_status_data = ohci_hub_status_data, | 236 | .hub_status_data = ohci_hub_status_data, |
237 | .hub_control = ohci_hub_control, | 237 | .hub_control = ohci_hub_control, |
238 | #ifdef CONFIG_USB_SUSPEND | 238 | #ifdef CONFIG_PM |
239 | .hub_suspend = ohci_hub_suspend, | 239 | .bus_suspend = ohci_bus_suspend, |
240 | .hub_resume = ohci_hub_resume, | 240 | .bus_resume = ohci_bus_resume, |
241 | #endif | 241 | #endif |
242 | .start_port_reset = ohci_start_port_reset, | ||
242 | }; | 243 | }; |
243 | 244 | ||
244 | /*-------------------------------------------------------------------------*/ | 245 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 8a9b9d9209e9..caacf14371f5 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h | |||
@@ -389,7 +389,6 @@ struct ohci_hcd { | |||
389 | unsigned long next_statechange; /* suspend/resume */ | 389 | unsigned long next_statechange; /* suspend/resume */ |
390 | u32 fminterval; /* saved register */ | 390 | u32 fminterval; /* saved register */ |
391 | 391 | ||
392 | struct work_struct rh_resume; | ||
393 | struct notifier_block reboot_notifier; | 392 | struct notifier_block reboot_notifier; |
394 | 393 | ||
395 | unsigned long flags; /* for HC bugs */ | 394 | unsigned long flags; /* for HC bugs */ |
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c new file mode 100644 index 000000000000..b7fd3f644e1e --- /dev/null +++ b/drivers/usb/host/pci-quirks.c | |||
@@ -0,0 +1,296 @@ | |||
1 | /* | ||
2 | * This file contains code to reset and initialize USB host controllers. | ||
3 | * Some of it includes work-arounds for PCI hardware and BIOS quirks. | ||
4 | * It may need to run early during booting -- before USB would normally | ||
5 | * initialize -- to ensure that Linux doesn't use any legacy modes. | ||
6 | * | ||
7 | * Copyright (c) 1999 Martin Mares <mj@ucw.cz> | ||
8 | * (and others) | ||
9 | */ | ||
10 | |||
11 | #include <linux/config.h> | ||
12 | #ifdef CONFIG_USB_DEBUG | ||
13 | #define DEBUG | ||
14 | #else | ||
15 | #undef DEBUG | ||
16 | #endif | ||
17 | |||
18 | #include <linux/types.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/pci.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <linux/acpi.h> | ||
24 | |||
25 | |||
26 | #define UHCI_USBLEGSUP 0xc0 /* legacy support */ | ||
27 | #define UHCI_USBCMD 0 /* command register */ | ||
28 | #define UHCI_USBINTR 4 /* interrupt register */ | ||
29 | #define UHCI_USBLEGSUP_RWC 0x8f00 /* the R/WC bits */ | ||
30 | #define UHCI_USBLEGSUP_RO 0x5040 /* R/O and reserved bits */ | ||
31 | #define UHCI_USBCMD_RUN 0x0001 /* RUN/STOP bit */ | ||
32 | #define UHCI_USBCMD_HCRESET 0x0002 /* Host Controller reset */ | ||
33 | #define UHCI_USBCMD_EGSM 0x0008 /* Global Suspend Mode */ | ||
34 | #define UHCI_USBCMD_CONFIGURE 0x0040 /* Config Flag */ | ||
35 | #define UHCI_USBINTR_RESUME 0x0002 /* Resume interrupt enable */ | ||
36 | |||
37 | #define OHCI_CONTROL 0x04 | ||
38 | #define OHCI_CMDSTATUS 0x08 | ||
39 | #define OHCI_INTRSTATUS 0x0c | ||
40 | #define OHCI_INTRENABLE 0x10 | ||
41 | #define OHCI_INTRDISABLE 0x14 | ||
42 | #define OHCI_OCR (1 << 3) /* ownership change request */ | ||
43 | #define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */ | ||
44 | #define OHCI_CTRL_IR (1 << 8) /* interrupt routing */ | ||
45 | #define OHCI_INTR_OC (1 << 30) /* ownership change */ | ||
46 | |||
47 | #define EHCI_HCC_PARAMS 0x08 /* extended capabilities */ | ||
48 | #define EHCI_USBCMD 0 /* command register */ | ||
49 | #define EHCI_USBCMD_RUN (1 << 0) /* RUN/STOP bit */ | ||
50 | #define EHCI_USBSTS 4 /* status register */ | ||
51 | #define EHCI_USBSTS_HALTED (1 << 12) /* HCHalted bit */ | ||
52 | #define EHCI_USBINTR 8 /* interrupt register */ | ||
53 | #define EHCI_USBLEGSUP 0 /* legacy support register */ | ||
54 | #define EHCI_USBLEGSUP_BIOS (1 << 16) /* BIOS semaphore */ | ||
55 | #define EHCI_USBLEGSUP_OS (1 << 24) /* OS semaphore */ | ||
56 | #define EHCI_USBLEGCTLSTS 4 /* legacy control/status */ | ||
57 | #define EHCI_USBLEGCTLSTS_SOOE (1 << 13) /* SMI on ownership change */ | ||
58 | |||
59 | |||
60 | /* | ||
61 | * Make sure the controller is completely inactive, unable to | ||
62 | * generate interrupts or do DMA. | ||
63 | */ | ||
64 | void uhci_reset_hc(struct pci_dev *pdev, unsigned long base) | ||
65 | { | ||
66 | /* Turn off PIRQ enable and SMI enable. (This also turns off the | ||
67 | * BIOS's USB Legacy Support.) Turn off all the R/WC bits too. | ||
68 | */ | ||
69 | pci_write_config_word(pdev, UHCI_USBLEGSUP, UHCI_USBLEGSUP_RWC); | ||
70 | |||
71 | /* Reset the HC - this will force us to get a | ||
72 | * new notification of any already connected | ||
73 | * ports due to the virtual disconnect that it | ||
74 | * implies. | ||
75 | */ | ||
76 | outw(UHCI_USBCMD_HCRESET, base + UHCI_USBCMD); | ||
77 | mb(); | ||
78 | udelay(5); | ||
79 | if (inw(base + UHCI_USBCMD) & UHCI_USBCMD_HCRESET) | ||
80 | dev_warn(&pdev->dev, "HCRESET not completed yet!\n"); | ||
81 | |||
82 | /* Just to be safe, disable interrupt requests and | ||
83 | * make sure the controller is stopped. | ||
84 | */ | ||
85 | outw(0, base + UHCI_USBINTR); | ||
86 | outw(0, base + UHCI_USBCMD); | ||
87 | } | ||
88 | EXPORT_SYMBOL_GPL(uhci_reset_hc); | ||
89 | |||
90 | /* | ||
91 | * Initialize a controller that was newly discovered or has just been | ||
92 | * resumed. In either case we can't be sure of its previous state. | ||
93 | * | ||
94 | * Returns: 1 if the controller was reset, 0 otherwise. | ||
95 | */ | ||
96 | int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base) | ||
97 | { | ||
98 | u16 legsup; | ||
99 | unsigned int cmd, intr; | ||
100 | |||
101 | /* | ||
102 | * When restarting a suspended controller, we expect all the | ||
103 | * settings to be the same as we left them: | ||
104 | * | ||
105 | * PIRQ and SMI disabled, no R/W bits set in USBLEGSUP; | ||
106 | * Controller is stopped and configured with EGSM set; | ||
107 | * No interrupts enabled except possibly Resume Detect. | ||
108 | * | ||
109 | * If any of these conditions are violated we do a complete reset. | ||
110 | */ | ||
111 | pci_read_config_word(pdev, UHCI_USBLEGSUP, &legsup); | ||
112 | if (legsup & ~(UHCI_USBLEGSUP_RO | UHCI_USBLEGSUP_RWC)) { | ||
113 | dev_dbg(&pdev->dev, "%s: legsup = 0x%04x\n", | ||
114 | __FUNCTION__, legsup); | ||
115 | goto reset_needed; | ||
116 | } | ||
117 | |||
118 | cmd = inw(base + UHCI_USBCMD); | ||
119 | if ((cmd & UHCI_USBCMD_RUN) || !(cmd & UHCI_USBCMD_CONFIGURE) || | ||
120 | !(cmd & UHCI_USBCMD_EGSM)) { | ||
121 | dev_dbg(&pdev->dev, "%s: cmd = 0x%04x\n", | ||
122 | __FUNCTION__, cmd); | ||
123 | goto reset_needed; | ||
124 | } | ||
125 | |||
126 | intr = inw(base + UHCI_USBINTR); | ||
127 | if (intr & (~UHCI_USBINTR_RESUME)) { | ||
128 | dev_dbg(&pdev->dev, "%s: intr = 0x%04x\n", | ||
129 | __FUNCTION__, intr); | ||
130 | goto reset_needed; | ||
131 | } | ||
132 | return 0; | ||
133 | |||
134 | reset_needed: | ||
135 | dev_dbg(&pdev->dev, "Performing full reset\n"); | ||
136 | uhci_reset_hc(pdev, base); | ||
137 | return 1; | ||
138 | } | ||
139 | EXPORT_SYMBOL_GPL(uhci_check_and_reset_hc); | ||
140 | |||
141 | static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev) | ||
142 | { | ||
143 | unsigned long base = 0; | ||
144 | int i; | ||
145 | |||
146 | for (i = 0; i < PCI_ROM_RESOURCE; i++) | ||
147 | if ((pci_resource_flags(pdev, i) & IORESOURCE_IO)) { | ||
148 | base = pci_resource_start(pdev, i); | ||
149 | break; | ||
150 | } | ||
151 | |||
152 | if (base) | ||
153 | uhci_check_and_reset_hc(pdev, base); | ||
154 | } | ||
155 | |||
156 | static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) | ||
157 | { | ||
158 | void __iomem *base; | ||
159 | int wait_time; | ||
160 | u32 control; | ||
161 | |||
162 | base = ioremap_nocache(pci_resource_start(pdev, 0), | ||
163 | pci_resource_len(pdev, 0)); | ||
164 | if (base == NULL) return; | ||
165 | |||
166 | /* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */ | ||
167 | #ifndef __hppa__ | ||
168 | control = readl(base + OHCI_CONTROL); | ||
169 | if (control & OHCI_CTRL_IR) { | ||
170 | wait_time = 500; /* arbitrary; 5 seconds */ | ||
171 | writel(OHCI_INTR_OC, base + OHCI_INTRENABLE); | ||
172 | writel(OHCI_OCR, base + OHCI_CMDSTATUS); | ||
173 | while (wait_time > 0 && | ||
174 | readl(base + OHCI_CONTROL) & OHCI_CTRL_IR) { | ||
175 | wait_time -= 10; | ||
176 | msleep(10); | ||
177 | } | ||
178 | if (wait_time <= 0) | ||
179 | printk(KERN_WARNING "%s %s: early BIOS handoff " | ||
180 | "failed (BIOS bug ?)\n", | ||
181 | pdev->dev.bus_id, "OHCI"); | ||
182 | |||
183 | /* reset controller, preserving RWC */ | ||
184 | writel(control & OHCI_CTRL_RWC, base + OHCI_CONTROL); | ||
185 | } | ||
186 | #endif | ||
187 | |||
188 | /* | ||
189 | * disable interrupts | ||
190 | */ | ||
191 | writel(~(u32)0, base + OHCI_INTRDISABLE); | ||
192 | writel(~(u32)0, base + OHCI_INTRSTATUS); | ||
193 | |||
194 | iounmap(base); | ||
195 | } | ||
196 | |||
197 | static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) | ||
198 | { | ||
199 | int wait_time, delta; | ||
200 | void __iomem *base, *op_reg_base; | ||
201 | u32 hcc_params, val, temp; | ||
202 | u8 cap_length; | ||
203 | |||
204 | base = ioremap_nocache(pci_resource_start(pdev, 0), | ||
205 | pci_resource_len(pdev, 0)); | ||
206 | if (base == NULL) return; | ||
207 | |||
208 | cap_length = readb(base); | ||
209 | op_reg_base = base + cap_length; | ||
210 | hcc_params = readl(base + EHCI_HCC_PARAMS); | ||
211 | hcc_params = (hcc_params >> 8) & 0xff; | ||
212 | if (hcc_params) { | ||
213 | pci_read_config_dword(pdev, | ||
214 | hcc_params + EHCI_USBLEGSUP, | ||
215 | &val); | ||
216 | if (((val & 0xff) == 1) && (val & EHCI_USBLEGSUP_BIOS)) { | ||
217 | /* | ||
218 | * Ok, BIOS is in smm mode, try to hand off... | ||
219 | */ | ||
220 | pci_read_config_dword(pdev, | ||
221 | hcc_params + EHCI_USBLEGCTLSTS, | ||
222 | &temp); | ||
223 | pci_write_config_dword(pdev, | ||
224 | hcc_params + EHCI_USBLEGCTLSTS, | ||
225 | temp | EHCI_USBLEGCTLSTS_SOOE); | ||
226 | val |= EHCI_USBLEGSUP_OS; | ||
227 | pci_write_config_dword(pdev, | ||
228 | hcc_params + EHCI_USBLEGSUP, | ||
229 | val); | ||
230 | |||
231 | wait_time = 500; | ||
232 | do { | ||
233 | msleep(10); | ||
234 | wait_time -= 10; | ||
235 | pci_read_config_dword(pdev, | ||
236 | hcc_params + EHCI_USBLEGSUP, | ||
237 | &val); | ||
238 | } while (wait_time && (val & EHCI_USBLEGSUP_BIOS)); | ||
239 | if (!wait_time) { | ||
240 | /* | ||
241 | * well, possibly buggy BIOS... | ||
242 | */ | ||
243 | printk(KERN_WARNING "%s %s: early BIOS handoff " | ||
244 | "failed (BIOS bug ?)\n", | ||
245 | pdev->dev.bus_id, "EHCI"); | ||
246 | pci_write_config_dword(pdev, | ||
247 | hcc_params + EHCI_USBLEGSUP, | ||
248 | EHCI_USBLEGSUP_OS); | ||
249 | pci_write_config_dword(pdev, | ||
250 | hcc_params + EHCI_USBLEGCTLSTS, | ||
251 | 0); | ||
252 | } | ||
253 | } | ||
254 | } | ||
255 | |||
256 | /* | ||
257 | * halt EHCI & disable its interrupts in any case | ||
258 | */ | ||
259 | val = readl(op_reg_base + EHCI_USBSTS); | ||
260 | if ((val & EHCI_USBSTS_HALTED) == 0) { | ||
261 | val = readl(op_reg_base + EHCI_USBCMD); | ||
262 | val &= ~EHCI_USBCMD_RUN; | ||
263 | writel(val, op_reg_base + EHCI_USBCMD); | ||
264 | |||
265 | wait_time = 2000; | ||
266 | delta = 100; | ||
267 | do { | ||
268 | writel(0x3f, op_reg_base + EHCI_USBSTS); | ||
269 | udelay(delta); | ||
270 | wait_time -= delta; | ||
271 | val = readl(op_reg_base + EHCI_USBSTS); | ||
272 | if ((val == ~(u32)0) || (val & EHCI_USBSTS_HALTED)) { | ||
273 | break; | ||
274 | } | ||
275 | } while (wait_time > 0); | ||
276 | } | ||
277 | writel(0, op_reg_base + EHCI_USBINTR); | ||
278 | writel(0x3f, op_reg_base + EHCI_USBSTS); | ||
279 | |||
280 | iounmap(base); | ||
281 | |||
282 | return; | ||
283 | } | ||
284 | |||
285 | |||
286 | |||
287 | static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev) | ||
288 | { | ||
289 | if (pdev->class == PCI_CLASS_SERIAL_USB_UHCI) | ||
290 | quirk_usb_handoff_uhci(pdev); | ||
291 | else if (pdev->class == PCI_CLASS_SERIAL_USB_OHCI) | ||
292 | quirk_usb_handoff_ohci(pdev); | ||
293 | else if (pdev->class == PCI_CLASS_SERIAL_USB_EHCI) | ||
294 | quirk_usb_disable_ehci(pdev); | ||
295 | } | ||
296 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff); | ||
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index b5e7a478bc01..40169d9cf2b1 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c | |||
@@ -1363,7 +1363,7 @@ error: | |||
1363 | #ifdef CONFIG_PM | 1363 | #ifdef CONFIG_PM |
1364 | 1364 | ||
1365 | static int | 1365 | static int |
1366 | sl811h_hub_suspend(struct usb_hcd *hcd) | 1366 | sl811h_bus_suspend(struct usb_hcd *hcd) |
1367 | { | 1367 | { |
1368 | // SOFs off | 1368 | // SOFs off |
1369 | DBG("%s\n", __FUNCTION__); | 1369 | DBG("%s\n", __FUNCTION__); |
@@ -1371,7 +1371,7 @@ sl811h_hub_suspend(struct usb_hcd *hcd) | |||
1371 | } | 1371 | } |
1372 | 1372 | ||
1373 | static int | 1373 | static int |
1374 | sl811h_hub_resume(struct usb_hcd *hcd) | 1374 | sl811h_bus_resume(struct usb_hcd *hcd) |
1375 | { | 1375 | { |
1376 | // SOFs on | 1376 | // SOFs on |
1377 | DBG("%s\n", __FUNCTION__); | 1377 | DBG("%s\n", __FUNCTION__); |
@@ -1380,8 +1380,8 @@ sl811h_hub_resume(struct usb_hcd *hcd) | |||
1380 | 1380 | ||
1381 | #else | 1381 | #else |
1382 | 1382 | ||
1383 | #define sl811h_hub_suspend NULL | 1383 | #define sl811h_bus_suspend NULL |
1384 | #define sl811h_hub_resume NULL | 1384 | #define sl811h_bus_resume NULL |
1385 | 1385 | ||
1386 | #endif | 1386 | #endif |
1387 | 1387 | ||
@@ -1623,8 +1623,8 @@ static struct hc_driver sl811h_hc_driver = { | |||
1623 | */ | 1623 | */ |
1624 | .hub_status_data = sl811h_hub_status_data, | 1624 | .hub_status_data = sl811h_hub_status_data, |
1625 | .hub_control = sl811h_hub_control, | 1625 | .hub_control = sl811h_hub_control, |
1626 | .hub_suspend = sl811h_hub_suspend, | 1626 | .bus_suspend = sl811h_bus_suspend, |
1627 | .hub_resume = sl811h_hub_resume, | 1627 | .bus_resume = sl811h_bus_resume, |
1628 | }; | 1628 | }; |
1629 | 1629 | ||
1630 | /*-------------------------------------------------------------------------*/ | 1630 | /*-------------------------------------------------------------------------*/ |
@@ -1791,7 +1791,7 @@ sl811h_suspend(struct device *dev, pm_message_t state) | |||
1791 | int retval = 0; | 1791 | int retval = 0; |
1792 | 1792 | ||
1793 | if (state.event == PM_EVENT_FREEZE) | 1793 | if (state.event == PM_EVENT_FREEZE) |
1794 | retval = sl811h_hub_suspend(hcd); | 1794 | retval = sl811h_bus_suspend(hcd); |
1795 | else if (state.event == PM_EVENT_SUSPEND) | 1795 | else if (state.event == PM_EVENT_SUSPEND) |
1796 | port_power(sl811, 0); | 1796 | port_power(sl811, 0); |
1797 | if (retval == 0) | 1797 | if (retval == 0) |
@@ -1816,7 +1816,7 @@ sl811h_resume(struct device *dev) | |||
1816 | } | 1816 | } |
1817 | 1817 | ||
1818 | dev->power.power_state = PMSG_ON; | 1818 | dev->power.power_state = PMSG_ON; |
1819 | return sl811h_hub_resume(hcd); | 1819 | return sl811h_bus_resume(hcd); |
1820 | } | 1820 | } |
1821 | 1821 | ||
1822 | #else | 1822 | #else |
@@ -1831,6 +1831,7 @@ sl811h_resume(struct device *dev) | |||
1831 | struct device_driver sl811h_driver = { | 1831 | struct device_driver sl811h_driver = { |
1832 | .name = (char *) hcd_name, | 1832 | .name = (char *) hcd_name, |
1833 | .bus = &platform_bus_type, | 1833 | .bus = &platform_bus_type, |
1834 | .owner = THIS_MODULE, | ||
1834 | 1835 | ||
1835 | .probe = sl811h_probe, | 1836 | .probe = sl811h_probe, |
1836 | .remove = __devexit_p(sl811h_remove), | 1837 | .remove = __devexit_p(sl811h_remove), |
diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c index 4538a98b6f9d..151154df37fa 100644 --- a/drivers/usb/host/uhci-debug.c +++ b/drivers/usb/host/uhci-debug.c | |||
@@ -348,7 +348,6 @@ static int uhci_show_urbp(struct uhci_hcd *uhci, struct urb_priv *urbp, char *bu | |||
348 | 348 | ||
349 | if (urbp->urb->status != -EINPROGRESS) | 349 | if (urbp->urb->status != -EINPROGRESS) |
350 | out += sprintf(out, "Status=%d ", urbp->urb->status); | 350 | out += sprintf(out, "Status=%d ", urbp->urb->status); |
351 | //out += sprintf(out, "Inserttime=%lx ",urbp->inserttime); | ||
352 | //out += sprintf(out, "FSBRtime=%lx ",urbp->fsbrtime); | 351 | //out += sprintf(out, "FSBRtime=%lx ",urbp->fsbrtime); |
353 | 352 | ||
354 | count = 0; | 353 | count = 0; |
@@ -446,11 +445,11 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len) | |||
446 | out += sprintf(out, "Frame List\n"); | 445 | out += sprintf(out, "Frame List\n"); |
447 | for (i = 0; i < UHCI_NUMFRAMES; ++i) { | 446 | for (i = 0; i < UHCI_NUMFRAMES; ++i) { |
448 | int shown = 0; | 447 | int shown = 0; |
449 | td = uhci->fl->frame_cpu[i]; | 448 | td = uhci->frame_cpu[i]; |
450 | if (!td) | 449 | if (!td) |
451 | continue; | 450 | continue; |
452 | 451 | ||
453 | if (td->dma_handle != (dma_addr_t)uhci->fl->frame[i]) { | 452 | if (td->dma_handle != (dma_addr_t)uhci->frame[i]) { |
454 | show_frame_num(); | 453 | show_frame_num(); |
455 | out += sprintf(out, " frame list does not match td->dma_handle!\n"); | 454 | out += sprintf(out, " frame list does not match td->dma_handle!\n"); |
456 | } | 455 | } |
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 0c024898cbea..15e0a511069b 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c | |||
@@ -101,37 +101,16 @@ static void uhci_get_current_frame_number(struct uhci_hcd *uhci); | |||
101 | #include "uhci-q.c" | 101 | #include "uhci-q.c" |
102 | #include "uhci-hub.c" | 102 | #include "uhci-hub.c" |
103 | 103 | ||
104 | extern void uhci_reset_hc(struct pci_dev *pdev, unsigned long base); | ||
105 | extern int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base); | ||
106 | |||
104 | /* | 107 | /* |
105 | * Make sure the controller is completely inactive, unable to | 108 | * Finish up a host controller reset and update the recorded state. |
106 | * generate interrupts or do DMA. | ||
107 | */ | 109 | */ |
108 | static void reset_hc(struct uhci_hcd *uhci) | 110 | static void finish_reset(struct uhci_hcd *uhci) |
109 | { | 111 | { |
110 | int port; | 112 | int port; |
111 | 113 | ||
112 | /* Turn off PIRQ enable and SMI enable. (This also turns off the | ||
113 | * BIOS's USB Legacy Support.) Turn off all the R/WC bits too. | ||
114 | */ | ||
115 | pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, | ||
116 | USBLEGSUP_RWC); | ||
117 | |||
118 | /* Reset the HC - this will force us to get a | ||
119 | * new notification of any already connected | ||
120 | * ports due to the virtual disconnect that it | ||
121 | * implies. | ||
122 | */ | ||
123 | outw(USBCMD_HCRESET, uhci->io_addr + USBCMD); | ||
124 | mb(); | ||
125 | udelay(5); | ||
126 | if (inw(uhci->io_addr + USBCMD) & USBCMD_HCRESET) | ||
127 | dev_warn(uhci_dev(uhci), "HCRESET not completed yet!\n"); | ||
128 | |||
129 | /* Just to be safe, disable interrupt requests and | ||
130 | * make sure the controller is stopped. | ||
131 | */ | ||
132 | outw(0, uhci->io_addr + USBINTR); | ||
133 | outw(0, uhci->io_addr + USBCMD); | ||
134 | |||
135 | /* HCRESET doesn't affect the Suspend, Reset, and Resume Detect | 114 | /* HCRESET doesn't affect the Suspend, Reset, and Resume Detect |
136 | * bits in the port status and control registers. | 115 | * bits in the port status and control registers. |
137 | * We have to clear them by hand. | 116 | * We have to clear them by hand. |
@@ -153,7 +132,8 @@ static void reset_hc(struct uhci_hcd *uhci) | |||
153 | */ | 132 | */ |
154 | static void hc_died(struct uhci_hcd *uhci) | 133 | static void hc_died(struct uhci_hcd *uhci) |
155 | { | 134 | { |
156 | reset_hc(uhci); | 135 | uhci_reset_hc(to_pci_dev(uhci_dev(uhci)), uhci->io_addr); |
136 | finish_reset(uhci); | ||
157 | uhci->hc_inaccessible = 1; | 137 | uhci->hc_inaccessible = 1; |
158 | } | 138 | } |
159 | 139 | ||
@@ -163,44 +143,8 @@ static void hc_died(struct uhci_hcd *uhci) | |||
163 | */ | 143 | */ |
164 | static void check_and_reset_hc(struct uhci_hcd *uhci) | 144 | static void check_and_reset_hc(struct uhci_hcd *uhci) |
165 | { | 145 | { |
166 | u16 legsup; | 146 | if (uhci_check_and_reset_hc(to_pci_dev(uhci_dev(uhci)), uhci->io_addr)) |
167 | unsigned int cmd, intr; | 147 | finish_reset(uhci); |
168 | |||
169 | /* | ||
170 | * When restarting a suspended controller, we expect all the | ||
171 | * settings to be the same as we left them: | ||
172 | * | ||
173 | * PIRQ and SMI disabled, no R/W bits set in USBLEGSUP; | ||
174 | * Controller is stopped and configured with EGSM set; | ||
175 | * No interrupts enabled except possibly Resume Detect. | ||
176 | * | ||
177 | * If any of these conditions are violated we do a complete reset. | ||
178 | */ | ||
179 | pci_read_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, &legsup); | ||
180 | if (legsup & ~(USBLEGSUP_RO | USBLEGSUP_RWC)) { | ||
181 | dev_dbg(uhci_dev(uhci), "%s: legsup = 0x%04x\n", | ||
182 | __FUNCTION__, legsup); | ||
183 | goto reset_needed; | ||
184 | } | ||
185 | |||
186 | cmd = inw(uhci->io_addr + USBCMD); | ||
187 | if ((cmd & USBCMD_RS) || !(cmd & USBCMD_CF) || !(cmd & USBCMD_EGSM)) { | ||
188 | dev_dbg(uhci_dev(uhci), "%s: cmd = 0x%04x\n", | ||
189 | __FUNCTION__, cmd); | ||
190 | goto reset_needed; | ||
191 | } | ||
192 | |||
193 | intr = inw(uhci->io_addr + USBINTR); | ||
194 | if (intr & (~USBINTR_RESUME)) { | ||
195 | dev_dbg(uhci_dev(uhci), "%s: intr = 0x%04x\n", | ||
196 | __FUNCTION__, intr); | ||
197 | goto reset_needed; | ||
198 | } | ||
199 | return; | ||
200 | |||
201 | reset_needed: | ||
202 | dev_dbg(uhci_dev(uhci), "Performing full reset\n"); | ||
203 | reset_hc(uhci); | ||
204 | } | 148 | } |
205 | 149 | ||
206 | /* | 150 | /* |
@@ -212,13 +156,13 @@ static void configure_hc(struct uhci_hcd *uhci) | |||
212 | outb(USBSOF_DEFAULT, uhci->io_addr + USBSOF); | 156 | outb(USBSOF_DEFAULT, uhci->io_addr + USBSOF); |
213 | 157 | ||
214 | /* Store the frame list base address */ | 158 | /* Store the frame list base address */ |
215 | outl(uhci->fl->dma_handle, uhci->io_addr + USBFLBASEADD); | 159 | outl(uhci->frame_dma_handle, uhci->io_addr + USBFLBASEADD); |
216 | 160 | ||
217 | /* Set the current frame number */ | 161 | /* Set the current frame number */ |
218 | outw(uhci->frame_number, uhci->io_addr + USBFRNUM); | 162 | outw(uhci->frame_number, uhci->io_addr + USBFRNUM); |
219 | 163 | ||
220 | /* Mark controller as running before we enable interrupts */ | 164 | /* Mark controller as not halted before we enable interrupts */ |
221 | uhci_to_hcd(uhci)->state = HC_STATE_RUNNING; | 165 | uhci_to_hcd(uhci)->state = HC_STATE_SUSPENDED; |
222 | mb(); | 166 | mb(); |
223 | 167 | ||
224 | /* Enable PIRQ */ | 168 | /* Enable PIRQ */ |
@@ -319,6 +263,7 @@ __acquires(uhci->lock) | |||
319 | 263 | ||
320 | static void start_rh(struct uhci_hcd *uhci) | 264 | static void start_rh(struct uhci_hcd *uhci) |
321 | { | 265 | { |
266 | uhci_to_hcd(uhci)->state = HC_STATE_RUNNING; | ||
322 | uhci->is_stopped = 0; | 267 | uhci->is_stopped = 0; |
323 | smp_wmb(); | 268 | smp_wmb(); |
324 | 269 | ||
@@ -437,36 +382,21 @@ static void release_uhci(struct uhci_hcd *uhci) | |||
437 | int i; | 382 | int i; |
438 | 383 | ||
439 | for (i = 0; i < UHCI_NUM_SKELQH; i++) | 384 | for (i = 0; i < UHCI_NUM_SKELQH; i++) |
440 | if (uhci->skelqh[i]) { | 385 | uhci_free_qh(uhci, uhci->skelqh[i]); |
441 | uhci_free_qh(uhci, uhci->skelqh[i]); | ||
442 | uhci->skelqh[i] = NULL; | ||
443 | } | ||
444 | 386 | ||
445 | if (uhci->term_td) { | 387 | uhci_free_td(uhci, uhci->term_td); |
446 | uhci_free_td(uhci, uhci->term_td); | ||
447 | uhci->term_td = NULL; | ||
448 | } | ||
449 | 388 | ||
450 | if (uhci->qh_pool) { | 389 | dma_pool_destroy(uhci->qh_pool); |
451 | dma_pool_destroy(uhci->qh_pool); | ||
452 | uhci->qh_pool = NULL; | ||
453 | } | ||
454 | 390 | ||
455 | if (uhci->td_pool) { | 391 | dma_pool_destroy(uhci->td_pool); |
456 | dma_pool_destroy(uhci->td_pool); | ||
457 | uhci->td_pool = NULL; | ||
458 | } | ||
459 | 392 | ||
460 | if (uhci->fl) { | 393 | kfree(uhci->frame_cpu); |
461 | dma_free_coherent(uhci_dev(uhci), sizeof(*uhci->fl), | ||
462 | uhci->fl, uhci->fl->dma_handle); | ||
463 | uhci->fl = NULL; | ||
464 | } | ||
465 | 394 | ||
466 | if (uhci->dentry) { | 395 | dma_free_coherent(uhci_dev(uhci), |
467 | debugfs_remove(uhci->dentry); | 396 | UHCI_NUMFRAMES * sizeof(*uhci->frame), |
468 | uhci->dentry = NULL; | 397 | uhci->frame, uhci->frame_dma_handle); |
469 | } | 398 | |
399 | debugfs_remove(uhci->dentry); | ||
470 | } | 400 | } |
471 | 401 | ||
472 | static int uhci_reset(struct usb_hcd *hcd) | 402 | static int uhci_reset(struct usb_hcd *hcd) |
@@ -545,7 +475,6 @@ static int uhci_start(struct usb_hcd *hcd) | |||
545 | struct uhci_hcd *uhci = hcd_to_uhci(hcd); | 475 | struct uhci_hcd *uhci = hcd_to_uhci(hcd); |
546 | int retval = -EBUSY; | 476 | int retval = -EBUSY; |
547 | int i; | 477 | int i; |
548 | dma_addr_t dma_handle; | ||
549 | struct dentry *dentry; | 478 | struct dentry *dentry; |
550 | 479 | ||
551 | hcd->uses_new_polling = 1; | 480 | hcd->uses_new_polling = 1; |
@@ -579,17 +508,23 @@ static int uhci_start(struct usb_hcd *hcd) | |||
579 | 508 | ||
580 | init_waitqueue_head(&uhci->waitqh); | 509 | init_waitqueue_head(&uhci->waitqh); |
581 | 510 | ||
582 | uhci->fl = dma_alloc_coherent(uhci_dev(uhci), sizeof(*uhci->fl), | 511 | uhci->frame = dma_alloc_coherent(uhci_dev(uhci), |
583 | &dma_handle, 0); | 512 | UHCI_NUMFRAMES * sizeof(*uhci->frame), |
584 | if (!uhci->fl) { | 513 | &uhci->frame_dma_handle, 0); |
514 | if (!uhci->frame) { | ||
585 | dev_err(uhci_dev(uhci), "unable to allocate " | 515 | dev_err(uhci_dev(uhci), "unable to allocate " |
586 | "consistent memory for frame list\n"); | 516 | "consistent memory for frame list\n"); |
587 | goto err_alloc_fl; | 517 | goto err_alloc_frame; |
588 | } | 518 | } |
519 | memset(uhci->frame, 0, UHCI_NUMFRAMES * sizeof(*uhci->frame)); | ||
589 | 520 | ||
590 | memset((void *)uhci->fl, 0, sizeof(*uhci->fl)); | 521 | uhci->frame_cpu = kcalloc(UHCI_NUMFRAMES, sizeof(*uhci->frame_cpu), |
591 | 522 | GFP_KERNEL); | |
592 | uhci->fl->dma_handle = dma_handle; | 523 | if (!uhci->frame_cpu) { |
524 | dev_err(uhci_dev(uhci), "unable to allocate " | ||
525 | "memory for frame pointers\n"); | ||
526 | goto err_alloc_frame_cpu; | ||
527 | } | ||
593 | 528 | ||
594 | uhci->td_pool = dma_pool_create("uhci_td", uhci_dev(uhci), | 529 | uhci->td_pool = dma_pool_create("uhci_td", uhci_dev(uhci), |
595 | sizeof(struct uhci_td), 16, 0); | 530 | sizeof(struct uhci_td), 16, 0); |
@@ -672,7 +607,7 @@ static int uhci_start(struct usb_hcd *hcd) | |||
672 | irq = 7; | 607 | irq = 7; |
673 | 608 | ||
674 | /* Only place we don't use the frame list routines */ | 609 | /* Only place we don't use the frame list routines */ |
675 | uhci->fl->frame[i] = UHCI_PTR_QH | | 610 | uhci->frame[i] = UHCI_PTR_QH | |
676 | cpu_to_le32(uhci->skelqh[irq]->dma_handle); | 611 | cpu_to_le32(uhci->skelqh[irq]->dma_handle); |
677 | } | 612 | } |
678 | 613 | ||
@@ -690,31 +625,29 @@ static int uhci_start(struct usb_hcd *hcd) | |||
690 | * error exits: | 625 | * error exits: |
691 | */ | 626 | */ |
692 | err_alloc_skelqh: | 627 | err_alloc_skelqh: |
693 | for (i = 0; i < UHCI_NUM_SKELQH; i++) | 628 | for (i = 0; i < UHCI_NUM_SKELQH; i++) { |
694 | if (uhci->skelqh[i]) { | 629 | if (uhci->skelqh[i]) |
695 | uhci_free_qh(uhci, uhci->skelqh[i]); | 630 | uhci_free_qh(uhci, uhci->skelqh[i]); |
696 | uhci->skelqh[i] = NULL; | 631 | } |
697 | } | ||
698 | 632 | ||
699 | uhci_free_td(uhci, uhci->term_td); | 633 | uhci_free_td(uhci, uhci->term_td); |
700 | uhci->term_td = NULL; | ||
701 | 634 | ||
702 | err_alloc_term_td: | 635 | err_alloc_term_td: |
703 | dma_pool_destroy(uhci->qh_pool); | 636 | dma_pool_destroy(uhci->qh_pool); |
704 | uhci->qh_pool = NULL; | ||
705 | 637 | ||
706 | err_create_qh_pool: | 638 | err_create_qh_pool: |
707 | dma_pool_destroy(uhci->td_pool); | 639 | dma_pool_destroy(uhci->td_pool); |
708 | uhci->td_pool = NULL; | ||
709 | 640 | ||
710 | err_create_td_pool: | 641 | err_create_td_pool: |
711 | dma_free_coherent(uhci_dev(uhci), sizeof(*uhci->fl), | 642 | kfree(uhci->frame_cpu); |
712 | uhci->fl, uhci->fl->dma_handle); | 643 | |
713 | uhci->fl = NULL; | 644 | err_alloc_frame_cpu: |
645 | dma_free_coherent(uhci_dev(uhci), | ||
646 | UHCI_NUMFRAMES * sizeof(*uhci->frame), | ||
647 | uhci->frame, uhci->frame_dma_handle); | ||
714 | 648 | ||
715 | err_alloc_fl: | 649 | err_alloc_frame: |
716 | debugfs_remove(uhci->dentry); | 650 | debugfs_remove(uhci->dentry); |
717 | uhci->dentry = NULL; | ||
718 | 651 | ||
719 | err_create_debug_entry: | 652 | err_create_debug_entry: |
720 | return retval; | 653 | return retval; |
@@ -726,7 +659,7 @@ static void uhci_stop(struct usb_hcd *hcd) | |||
726 | 659 | ||
727 | spin_lock_irq(&uhci->lock); | 660 | spin_lock_irq(&uhci->lock); |
728 | if (!uhci->hc_inaccessible) | 661 | if (!uhci->hc_inaccessible) |
729 | reset_hc(uhci); | 662 | hc_died(uhci); |
730 | uhci_scan_schedule(uhci, NULL); | 663 | uhci_scan_schedule(uhci, NULL); |
731 | spin_unlock_irq(&uhci->lock); | 664 | spin_unlock_irq(&uhci->lock); |
732 | 665 | ||
@@ -774,14 +707,8 @@ static int uhci_suspend(struct usb_hcd *hcd, pm_message_t message) | |||
774 | if (uhci->hc_inaccessible) /* Dead or already suspended */ | 707 | if (uhci->hc_inaccessible) /* Dead or already suspended */ |
775 | goto done; | 708 | goto done; |
776 | 709 | ||
777 | #ifndef CONFIG_USB_SUSPEND | ||
778 | /* Otherwise this would never happen */ | ||
779 | suspend_rh(uhci, UHCI_RH_SUSPENDED); | ||
780 | #endif | ||
781 | |||
782 | if (uhci->rh_state > UHCI_RH_SUSPENDED) { | 710 | if (uhci->rh_state > UHCI_RH_SUSPENDED) { |
783 | dev_warn(uhci_dev(uhci), "Root hub isn't suspended!\n"); | 711 | dev_warn(uhci_dev(uhci), "Root hub isn't suspended!\n"); |
784 | hcd->state = HC_STATE_RUNNING; | ||
785 | rc = -EBUSY; | 712 | rc = -EBUSY; |
786 | goto done; | 713 | goto done; |
787 | }; | 714 | }; |
@@ -820,10 +747,6 @@ static int uhci_resume(struct usb_hcd *hcd) | |||
820 | check_and_reset_hc(uhci); | 747 | check_and_reset_hc(uhci); |
821 | configure_hc(uhci); | 748 | configure_hc(uhci); |
822 | 749 | ||
823 | #ifndef CONFIG_USB_SUSPEND | ||
824 | /* Otherwise this would never happen */ | ||
825 | wakeup_rh(uhci); | ||
826 | #endif | ||
827 | if (uhci->rh_state == UHCI_RH_RESET) | 750 | if (uhci->rh_state == UHCI_RH_RESET) |
828 | suspend_rh(uhci, UHCI_RH_SUSPENDED); | 751 | suspend_rh(uhci, UHCI_RH_SUSPENDED); |
829 | 752 | ||
@@ -881,8 +804,8 @@ static const struct hc_driver uhci_driver = { | |||
881 | #ifdef CONFIG_PM | 804 | #ifdef CONFIG_PM |
882 | .suspend = uhci_suspend, | 805 | .suspend = uhci_suspend, |
883 | .resume = uhci_resume, | 806 | .resume = uhci_resume, |
884 | .hub_suspend = uhci_rh_suspend, | 807 | .bus_suspend = uhci_rh_suspend, |
885 | .hub_resume = uhci_rh_resume, | 808 | .bus_resume = uhci_rh_resume, |
886 | #endif | 809 | #endif |
887 | .stop = uhci_stop, | 810 | .stop = uhci_stop, |
888 | 811 | ||
@@ -908,6 +831,7 @@ MODULE_DEVICE_TABLE(pci, uhci_pci_ids); | |||
908 | static struct pci_driver uhci_pci_driver = { | 831 | static struct pci_driver uhci_pci_driver = { |
909 | .name = (char *)hcd_name, | 832 | .name = (char *)hcd_name, |
910 | .id_table = uhci_pci_ids, | 833 | .id_table = uhci_pci_ids, |
834 | .owner = THIS_MODULE, | ||
911 | 835 | ||
912 | .probe = usb_hcd_pci_probe, | 836 | .probe = usb_hcd_pci_probe, |
913 | .remove = usb_hcd_pci_remove, | 837 | .remove = usb_hcd_pci_remove, |
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h index 282f40b75881..e576db57a926 100644 --- a/drivers/usb/host/uhci-hcd.h +++ b/drivers/usb/host/uhci-hcd.h | |||
@@ -7,6 +7,7 @@ | |||
7 | #define usb_packetid(pipe) (usb_pipein(pipe) ? USB_PID_IN : USB_PID_OUT) | 7 | #define usb_packetid(pipe) (usb_pipein(pipe) ? USB_PID_IN : USB_PID_OUT) |
8 | #define PIPE_DEVEP_MASK 0x0007ff00 | 8 | #define PIPE_DEVEP_MASK 0x0007ff00 |
9 | 9 | ||
10 | |||
10 | /* | 11 | /* |
11 | * Universal Host Controller Interface data structures and defines | 12 | * Universal Host Controller Interface data structures and defines |
12 | */ | 13 | */ |
@@ -82,15 +83,10 @@ | |||
82 | #define UHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */ | 83 | #define UHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */ |
83 | #define CAN_SCHEDULE_FRAMES 1000 /* how far future frames can be scheduled */ | 84 | #define CAN_SCHEDULE_FRAMES 1000 /* how far future frames can be scheduled */ |
84 | 85 | ||
85 | struct uhci_frame_list { | ||
86 | __le32 frame[UHCI_NUMFRAMES]; | ||
87 | |||
88 | void *frame_cpu[UHCI_NUMFRAMES]; | ||
89 | |||
90 | dma_addr_t dma_handle; | ||
91 | }; | ||
92 | 86 | ||
93 | struct urb_priv; | 87 | /* |
88 | * Queue Headers | ||
89 | */ | ||
94 | 90 | ||
95 | /* | 91 | /* |
96 | * One role of a QH is to hold a queue of TDs for some endpoint. Each QH is | 92 | * One role of a QH is to hold a queue of TDs for some endpoint. Each QH is |
@@ -116,13 +112,13 @@ struct uhci_qh { | |||
116 | 112 | ||
117 | struct urb_priv *urbp; | 113 | struct urb_priv *urbp; |
118 | 114 | ||
119 | struct list_head list; /* P: uhci->frame_list_lock */ | 115 | struct list_head list; |
120 | struct list_head remove_list; /* P: uhci->remove_list_lock */ | 116 | struct list_head remove_list; |
121 | } __attribute__((aligned(16))); | 117 | } __attribute__((aligned(16))); |
122 | 118 | ||
123 | /* | 119 | /* |
124 | * We need a special accessor for the element pointer because it is | 120 | * We need a special accessor for the element pointer because it is |
125 | * subject to asynchronous updates by the controller | 121 | * subject to asynchronous updates by the controller. |
126 | */ | 122 | */ |
127 | static __le32 inline qh_element(struct uhci_qh *qh) { | 123 | static __le32 inline qh_element(struct uhci_qh *qh) { |
128 | __le32 element = qh->element; | 124 | __le32 element = qh->element; |
@@ -131,6 +127,11 @@ static __le32 inline qh_element(struct uhci_qh *qh) { | |||
131 | return element; | 127 | return element; |
132 | } | 128 | } |
133 | 129 | ||
130 | |||
131 | /* | ||
132 | * Transfer Descriptors | ||
133 | */ | ||
134 | |||
134 | /* | 135 | /* |
135 | * for TD <status>: | 136 | * for TD <status>: |
136 | */ | 137 | */ |
@@ -183,17 +184,10 @@ static __le32 inline qh_element(struct uhci_qh *qh) { | |||
183 | * | 184 | * |
184 | * That's silly, the hardware doesn't care. The hardware only cares that | 185 | * That's silly, the hardware doesn't care. The hardware only cares that |
185 | * the hardware words are 16-byte aligned, and we can have any amount of | 186 | * the hardware words are 16-byte aligned, and we can have any amount of |
186 | * sw space after the TD entry as far as I can tell. | 187 | * sw space after the TD entry. |
187 | * | ||
188 | * But let's just go with the documentation, at least for 32-bit machines. | ||
189 | * On 64-bit machines we probably want to take advantage of the fact that | ||
190 | * hw doesn't really care about the size of the sw-only area. | ||
191 | * | ||
192 | * Alas, not anymore, we have more than 4 words for software, woops. | ||
193 | * Everything still works tho, surprise! -jerdfelt | ||
194 | * | 188 | * |
195 | * td->link points to either another TD (not necessarily for the same urb or | 189 | * td->link points to either another TD (not necessarily for the same urb or |
196 | * even the same endpoint), or nothing (PTR_TERM), or a QH (for queued urbs) | 190 | * even the same endpoint), or nothing (PTR_TERM), or a QH (for queued urbs). |
197 | */ | 191 | */ |
198 | struct uhci_td { | 192 | struct uhci_td { |
199 | /* Hardware fields */ | 193 | /* Hardware fields */ |
@@ -205,18 +199,16 @@ struct uhci_td { | |||
205 | /* Software fields */ | 199 | /* Software fields */ |
206 | dma_addr_t dma_handle; | 200 | dma_addr_t dma_handle; |
207 | 201 | ||
208 | struct urb *urb; | 202 | struct list_head list; |
209 | 203 | struct list_head remove_list; | |
210 | struct list_head list; /* P: urb->lock */ | ||
211 | struct list_head remove_list; /* P: uhci->td_remove_list_lock */ | ||
212 | 204 | ||
213 | int frame; /* for iso: what frame? */ | 205 | int frame; /* for iso: what frame? */ |
214 | struct list_head fl_list; /* P: uhci->frame_list_lock */ | 206 | struct list_head fl_list; |
215 | } __attribute__((aligned(16))); | 207 | } __attribute__((aligned(16))); |
216 | 208 | ||
217 | /* | 209 | /* |
218 | * We need a special accessor for the control/status word because it is | 210 | * We need a special accessor for the control/status word because it is |
219 | * subject to asynchronous updates by the controller | 211 | * subject to asynchronous updates by the controller. |
220 | */ | 212 | */ |
221 | static u32 inline td_status(struct uhci_td *td) { | 213 | static u32 inline td_status(struct uhci_td *td) { |
222 | __le32 status = td->status; | 214 | __le32 status = td->status; |
@@ -227,6 +219,10 @@ static u32 inline td_status(struct uhci_td *td) { | |||
227 | 219 | ||
228 | 220 | ||
229 | /* | 221 | /* |
222 | * Skeleton Queue Headers | ||
223 | */ | ||
224 | |||
225 | /* | ||
230 | * The UHCI driver places Interrupt, Control and Bulk into QH's both | 226 | * The UHCI driver places Interrupt, Control and Bulk into QH's both |
231 | * to group together TD's for one transfer, and also to faciliate queuing | 227 | * to group together TD's for one transfer, and also to faciliate queuing |
232 | * of URB's. To make it easy to insert entries into the schedule, we have | 228 | * of URB's. To make it easy to insert entries into the schedule, we have |
@@ -256,15 +252,15 @@ static u32 inline td_status(struct uhci_td *td) { | |||
256 | * | 252 | * |
257 | * The terminating QH is used for 2 reasons: | 253 | * The terminating QH is used for 2 reasons: |
258 | * - To place a terminating TD which is used to workaround a PIIX bug | 254 | * - To place a terminating TD which is used to workaround a PIIX bug |
259 | * (see Intel errata for explanation) | 255 | * (see Intel errata for explanation), and |
260 | * - To loop back to the full-speed control queue for full-speed bandwidth | 256 | * - To loop back to the full-speed control queue for full-speed bandwidth |
261 | * reclamation | 257 | * reclamation. |
262 | * | 258 | * |
263 | * Isochronous transfers are stored before the start of the skeleton | 259 | * Isochronous transfers are stored before the start of the skeleton |
264 | * schedule and don't use QH's. While the UHCI spec doesn't forbid the | 260 | * schedule and don't use QH's. While the UHCI spec doesn't forbid the |
265 | * use of QH's for Isochronous, it doesn't use them either. Since we don't | 261 | * use of QH's for Isochronous, it doesn't use them either. And the spec |
266 | * need to use them either, we follow the spec diagrams in hope that it'll | 262 | * says that queues never advance on an error completion status, which |
267 | * be more compatible with future UHCI implementations. | 263 | * makes them totally unsuitable for Isochronous transfers. |
268 | */ | 264 | */ |
269 | 265 | ||
270 | #define UHCI_NUM_SKELQH 12 | 266 | #define UHCI_NUM_SKELQH 12 |
@@ -314,8 +310,13 @@ static inline int __interval_to_skel(int interval) | |||
314 | return 0; /* int128 for 128-255 ms (Max.) */ | 310 | return 0; /* int128 for 128-255 ms (Max.) */ |
315 | } | 311 | } |
316 | 312 | ||
313 | |||
314 | /* | ||
315 | * The UHCI controller and root hub | ||
316 | */ | ||
317 | |||
317 | /* | 318 | /* |
318 | * States for the root hub. | 319 | * States for the root hub: |
319 | * | 320 | * |
320 | * To prevent "bouncing" in the presence of electrical noise, | 321 | * To prevent "bouncing" in the presence of electrical noise, |
321 | * when there are no devices attached we delay for 1 second in the | 322 | * when there are no devices attached we delay for 1 second in the |
@@ -326,7 +327,7 @@ static inline int __interval_to_skel(int interval) | |||
326 | */ | 327 | */ |
327 | enum uhci_rh_state { | 328 | enum uhci_rh_state { |
328 | /* In the following states the HC must be halted. | 329 | /* In the following states the HC must be halted. |
329 | * These two must come first */ | 330 | * These two must come first. */ |
330 | UHCI_RH_RESET, | 331 | UHCI_RH_RESET, |
331 | UHCI_RH_SUSPENDED, | 332 | UHCI_RH_SUSPENDED, |
332 | 333 | ||
@@ -338,13 +339,13 @@ enum uhci_rh_state { | |||
338 | UHCI_RH_SUSPENDING, | 339 | UHCI_RH_SUSPENDING, |
339 | 340 | ||
340 | /* In the following states it's an error if the HC is halted. | 341 | /* In the following states it's an error if the HC is halted. |
341 | * These two must come last */ | 342 | * These two must come last. */ |
342 | UHCI_RH_RUNNING, /* The normal state */ | 343 | UHCI_RH_RUNNING, /* The normal state */ |
343 | UHCI_RH_RUNNING_NODEVS, /* Running with no devices attached */ | 344 | UHCI_RH_RUNNING_NODEVS, /* Running with no devices attached */ |
344 | }; | 345 | }; |
345 | 346 | ||
346 | /* | 347 | /* |
347 | * This describes the full uhci information. | 348 | * The full UHCI controller information: |
348 | */ | 349 | */ |
349 | struct uhci_hcd { | 350 | struct uhci_hcd { |
350 | 351 | ||
@@ -361,7 +362,11 @@ struct uhci_hcd { | |||
361 | struct uhci_qh *skelqh[UHCI_NUM_SKELQH]; /* Skeleton QH's */ | 362 | struct uhci_qh *skelqh[UHCI_NUM_SKELQH]; /* Skeleton QH's */ |
362 | 363 | ||
363 | spinlock_t lock; | 364 | spinlock_t lock; |
364 | struct uhci_frame_list *fl; /* P: uhci->lock */ | 365 | |
366 | dma_addr_t frame_dma_handle; /* Hardware frame list */ | ||
367 | __le32 *frame; | ||
368 | void **frame_cpu; /* CPU's frame list */ | ||
369 | |||
365 | int fsbr; /* Full-speed bandwidth reclamation */ | 370 | int fsbr; /* Full-speed bandwidth reclamation */ |
366 | unsigned long fsbrtimeout; /* FSBR delay */ | 371 | unsigned long fsbrtimeout; /* FSBR delay */ |
367 | 372 | ||
@@ -385,22 +390,22 @@ struct uhci_hcd { | |||
385 | unsigned long ports_timeout; /* Time to stop signalling */ | 390 | unsigned long ports_timeout; /* Time to stop signalling */ |
386 | 391 | ||
387 | /* Main list of URB's currently controlled by this HC */ | 392 | /* Main list of URB's currently controlled by this HC */ |
388 | struct list_head urb_list; /* P: uhci->lock */ | 393 | struct list_head urb_list; |
389 | 394 | ||
390 | /* List of QH's that are done, but waiting to be unlinked (race) */ | 395 | /* List of QH's that are done, but waiting to be unlinked (race) */ |
391 | struct list_head qh_remove_list; /* P: uhci->lock */ | 396 | struct list_head qh_remove_list; |
392 | unsigned int qh_remove_age; /* Age in frames */ | 397 | unsigned int qh_remove_age; /* Age in frames */ |
393 | 398 | ||
394 | /* List of TD's that are done, but waiting to be freed (race) */ | 399 | /* List of TD's that are done, but waiting to be freed (race) */ |
395 | struct list_head td_remove_list; /* P: uhci->lock */ | 400 | struct list_head td_remove_list; |
396 | unsigned int td_remove_age; /* Age in frames */ | 401 | unsigned int td_remove_age; /* Age in frames */ |
397 | 402 | ||
398 | /* List of asynchronously unlinked URB's */ | 403 | /* List of asynchronously unlinked URB's */ |
399 | struct list_head urb_remove_list; /* P: uhci->lock */ | 404 | struct list_head urb_remove_list; |
400 | unsigned int urb_remove_age; /* Age in frames */ | 405 | unsigned int urb_remove_age; /* Age in frames */ |
401 | 406 | ||
402 | /* List of URB's awaiting completion callback */ | 407 | /* List of URB's awaiting completion callback */ |
403 | struct list_head complete_list; /* P: uhci->lock */ | 408 | struct list_head complete_list; |
404 | 409 | ||
405 | int rh_numports; /* Number of root-hub ports */ | 410 | int rh_numports; /* Number of root-hub ports */ |
406 | 411 | ||
@@ -419,13 +424,17 @@ static inline struct usb_hcd *uhci_to_hcd(struct uhci_hcd *uhci) | |||
419 | 424 | ||
420 | #define uhci_dev(u) (uhci_to_hcd(u)->self.controller) | 425 | #define uhci_dev(u) (uhci_to_hcd(u)->self.controller) |
421 | 426 | ||
427 | |||
428 | /* | ||
429 | * Private per-URB data | ||
430 | */ | ||
422 | struct urb_priv { | 431 | struct urb_priv { |
423 | struct list_head urb_list; | 432 | struct list_head urb_list; |
424 | 433 | ||
425 | struct urb *urb; | 434 | struct urb *urb; |
426 | 435 | ||
427 | struct uhci_qh *qh; /* QH for this URB */ | 436 | struct uhci_qh *qh; /* QH for this URB */ |
428 | struct list_head td_list; /* P: urb->lock */ | 437 | struct list_head td_list; |
429 | 438 | ||
430 | unsigned fsbr : 1; /* URB turned on FSBR */ | 439 | unsigned fsbr : 1; /* URB turned on FSBR */ |
431 | unsigned fsbr_timeout : 1; /* URB timed out on FSBR */ | 440 | unsigned fsbr_timeout : 1; /* URB timed out on FSBR */ |
@@ -434,12 +443,12 @@ struct urb_priv { | |||
434 | /* a control transfer, retrigger */ | 443 | /* a control transfer, retrigger */ |
435 | /* the status phase */ | 444 | /* the status phase */ |
436 | 445 | ||
437 | unsigned long inserttime; /* In jiffies */ | ||
438 | unsigned long fsbrtime; /* In jiffies */ | 446 | unsigned long fsbrtime; /* In jiffies */ |
439 | 447 | ||
440 | struct list_head queue_list; /* P: uhci->frame_list_lock */ | 448 | struct list_head queue_list; |
441 | }; | 449 | }; |
442 | 450 | ||
451 | |||
443 | /* | 452 | /* |
444 | * Locking in uhci.c | 453 | * Locking in uhci.c |
445 | * | 454 | * |
@@ -459,6 +468,5 @@ struct urb_priv { | |||
459 | 468 | ||
460 | #define PCI_VENDOR_ID_GENESYS 0x17a0 | 469 | #define PCI_VENDOR_ID_GENESYS 0x17a0 |
461 | #define PCI_DEVICE_ID_GL880S_UHCI 0x8083 | 470 | #define PCI_DEVICE_ID_GL880S_UHCI 0x8083 |
462 | #define PCI_DEVICE_ID_GL880S_EHCI 0x8084 | ||
463 | 471 | ||
464 | #endif | 472 | #endif |
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index 4e0fbe2c1a9a..7e46887d9e12 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c | |||
@@ -89,10 +89,10 @@ static void uhci_insert_td_frame_list(struct uhci_hcd *uhci, struct uhci_td *td, | |||
89 | td->frame = framenum; | 89 | td->frame = framenum; |
90 | 90 | ||
91 | /* Is there a TD already mapped there? */ | 91 | /* Is there a TD already mapped there? */ |
92 | if (uhci->fl->frame_cpu[framenum]) { | 92 | if (uhci->frame_cpu[framenum]) { |
93 | struct uhci_td *ftd, *ltd; | 93 | struct uhci_td *ftd, *ltd; |
94 | 94 | ||
95 | ftd = uhci->fl->frame_cpu[framenum]; | 95 | ftd = uhci->frame_cpu[framenum]; |
96 | ltd = list_entry(ftd->fl_list.prev, struct uhci_td, fl_list); | 96 | ltd = list_entry(ftd->fl_list.prev, struct uhci_td, fl_list); |
97 | 97 | ||
98 | list_add_tail(&td->fl_list, &ftd->fl_list); | 98 | list_add_tail(&td->fl_list, &ftd->fl_list); |
@@ -101,29 +101,32 @@ static void uhci_insert_td_frame_list(struct uhci_hcd *uhci, struct uhci_td *td, | |||
101 | wmb(); | 101 | wmb(); |
102 | ltd->link = cpu_to_le32(td->dma_handle); | 102 | ltd->link = cpu_to_le32(td->dma_handle); |
103 | } else { | 103 | } else { |
104 | td->link = uhci->fl->frame[framenum]; | 104 | td->link = uhci->frame[framenum]; |
105 | wmb(); | 105 | wmb(); |
106 | uhci->fl->frame[framenum] = cpu_to_le32(td->dma_handle); | 106 | uhci->frame[framenum] = cpu_to_le32(td->dma_handle); |
107 | uhci->fl->frame_cpu[framenum] = td; | 107 | uhci->frame_cpu[framenum] = td; |
108 | } | 108 | } |
109 | } | 109 | } |
110 | 110 | ||
111 | static void uhci_remove_td(struct uhci_hcd *uhci, struct uhci_td *td) | 111 | static inline void uhci_remove_td_frame_list(struct uhci_hcd *uhci, |
112 | struct uhci_td *td) | ||
112 | { | 113 | { |
113 | /* If it's not inserted, don't remove it */ | 114 | /* If it's not inserted, don't remove it */ |
114 | if (td->frame == -1 && list_empty(&td->fl_list)) | 115 | if (td->frame == -1) { |
116 | WARN_ON(!list_empty(&td->fl_list)); | ||
115 | return; | 117 | return; |
118 | } | ||
116 | 119 | ||
117 | if (td->frame != -1 && uhci->fl->frame_cpu[td->frame] == td) { | 120 | if (uhci->frame_cpu[td->frame] == td) { |
118 | if (list_empty(&td->fl_list)) { | 121 | if (list_empty(&td->fl_list)) { |
119 | uhci->fl->frame[td->frame] = td->link; | 122 | uhci->frame[td->frame] = td->link; |
120 | uhci->fl->frame_cpu[td->frame] = NULL; | 123 | uhci->frame_cpu[td->frame] = NULL; |
121 | } else { | 124 | } else { |
122 | struct uhci_td *ntd; | 125 | struct uhci_td *ntd; |
123 | 126 | ||
124 | ntd = list_entry(td->fl_list.next, struct uhci_td, fl_list); | 127 | ntd = list_entry(td->fl_list.next, struct uhci_td, fl_list); |
125 | uhci->fl->frame[td->frame] = cpu_to_le32(ntd->dma_handle); | 128 | uhci->frame[td->frame] = cpu_to_le32(ntd->dma_handle); |
126 | uhci->fl->frame_cpu[td->frame] = ntd; | 129 | uhci->frame_cpu[td->frame] = ntd; |
127 | } | 130 | } |
128 | } else { | 131 | } else { |
129 | struct uhci_td *ptd; | 132 | struct uhci_td *ptd; |
@@ -132,13 +135,20 @@ static void uhci_remove_td(struct uhci_hcd *uhci, struct uhci_td *td) | |||
132 | ptd->link = td->link; | 135 | ptd->link = td->link; |
133 | } | 136 | } |
134 | 137 | ||
135 | wmb(); | ||
136 | td->link = UHCI_PTR_TERM; | ||
137 | |||
138 | list_del_init(&td->fl_list); | 138 | list_del_init(&td->fl_list); |
139 | td->frame = -1; | 139 | td->frame = -1; |
140 | } | 140 | } |
141 | 141 | ||
142 | static void unlink_isochronous_tds(struct uhci_hcd *uhci, struct urb *urb) | ||
143 | { | ||
144 | struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv; | ||
145 | struct uhci_td *td; | ||
146 | |||
147 | list_for_each_entry(td, &urbp->td_list, list) | ||
148 | uhci_remove_td_frame_list(uhci, td); | ||
149 | wmb(); | ||
150 | } | ||
151 | |||
142 | /* | 152 | /* |
143 | * Inserts a td list into qh. | 153 | * Inserts a td list into qh. |
144 | */ | 154 | */ |
@@ -443,7 +453,6 @@ static struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci, struct urb *u | |||
443 | 453 | ||
444 | memset((void *)urbp, 0, sizeof(*urbp)); | 454 | memset((void *)urbp, 0, sizeof(*urbp)); |
445 | 455 | ||
446 | urbp->inserttime = jiffies; | ||
447 | urbp->fsbrtime = jiffies; | 456 | urbp->fsbrtime = jiffies; |
448 | urbp->urb = urb; | 457 | urbp->urb = urb; |
449 | 458 | ||
@@ -462,8 +471,6 @@ static void uhci_add_td_to_urb(struct urb *urb, struct uhci_td *td) | |||
462 | { | 471 | { |
463 | struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; | 472 | struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; |
464 | 473 | ||
465 | td->urb = urb; | ||
466 | |||
467 | list_add_tail(&td->list, &urbp->td_list); | 474 | list_add_tail(&td->list, &urbp->td_list); |
468 | } | 475 | } |
469 | 476 | ||
@@ -473,8 +480,6 @@ static void uhci_remove_td_from_urb(struct uhci_td *td) | |||
473 | return; | 480 | return; |
474 | 481 | ||
475 | list_del_init(&td->list); | 482 | list_del_init(&td->list); |
476 | |||
477 | td->urb = NULL; | ||
478 | } | 483 | } |
479 | 484 | ||
480 | static void uhci_destroy_urb_priv(struct uhci_hcd *uhci, struct urb *urb) | 485 | static void uhci_destroy_urb_priv(struct uhci_hcd *uhci, struct urb *urb) |
@@ -503,7 +508,6 @@ static void uhci_destroy_urb_priv(struct uhci_hcd *uhci, struct urb *urb) | |||
503 | 508 | ||
504 | list_for_each_entry_safe(td, tmp, &urbp->td_list, list) { | 509 | list_for_each_entry_safe(td, tmp, &urbp->td_list, list) { |
505 | uhci_remove_td_from_urb(td); | 510 | uhci_remove_td_from_urb(td); |
506 | uhci_remove_td(uhci, td); | ||
507 | list_add(&td->remove_list, &uhci->td_remove_list); | 511 | list_add(&td->remove_list, &uhci->td_remove_list); |
508 | } | 512 | } |
509 | 513 | ||
@@ -1073,6 +1077,7 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb) | |||
1073 | struct uhci_td *td; | 1077 | struct uhci_td *td; |
1074 | int i, ret, frame; | 1078 | int i, ret, frame; |
1075 | int status, destination; | 1079 | int status, destination; |
1080 | struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv; | ||
1076 | 1081 | ||
1077 | status = TD_CTRL_ACTIVE | TD_CTRL_IOS; | 1082 | status = TD_CTRL_ACTIVE | TD_CTRL_IOS; |
1078 | destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe); | 1083 | destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe); |
@@ -1081,11 +1086,7 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb) | |||
1081 | if (ret) | 1086 | if (ret) |
1082 | return ret; | 1087 | return ret; |
1083 | 1088 | ||
1084 | frame = urb->start_frame; | 1089 | for (i = 0; i < urb->number_of_packets; i++) { |
1085 | for (i = 0; i < urb->number_of_packets; i++, frame += urb->interval) { | ||
1086 | if (!urb->iso_frame_desc[i].length) | ||
1087 | continue; | ||
1088 | |||
1089 | td = uhci_alloc_td(uhci); | 1090 | td = uhci_alloc_td(uhci); |
1090 | if (!td) | 1091 | if (!td) |
1091 | return -ENOMEM; | 1092 | return -ENOMEM; |
@@ -1096,8 +1097,12 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb) | |||
1096 | 1097 | ||
1097 | if (i + 1 >= urb->number_of_packets) | 1098 | if (i + 1 >= urb->number_of_packets) |
1098 | td->status |= cpu_to_le32(TD_CTRL_IOC); | 1099 | td->status |= cpu_to_le32(TD_CTRL_IOC); |
1100 | } | ||
1099 | 1101 | ||
1102 | frame = urb->start_frame; | ||
1103 | list_for_each_entry(td, &urbp->td_list, list) { | ||
1100 | uhci_insert_td_frame_list(uhci, td, frame); | 1104 | uhci_insert_td_frame_list(uhci, td, frame); |
1105 | frame += urb->interval; | ||
1101 | } | 1106 | } |
1102 | 1107 | ||
1103 | return -EINPROGRESS; | 1108 | return -EINPROGRESS; |
@@ -1110,7 +1115,7 @@ static int uhci_result_isochronous(struct uhci_hcd *uhci, struct urb *urb) | |||
1110 | int status; | 1115 | int status; |
1111 | int i, ret = 0; | 1116 | int i, ret = 0; |
1112 | 1117 | ||
1113 | urb->actual_length = 0; | 1118 | urb->actual_length = urb->error_count = 0; |
1114 | 1119 | ||
1115 | i = 0; | 1120 | i = 0; |
1116 | list_for_each_entry(td, &urbp->td_list, list) { | 1121 | list_for_each_entry(td, &urbp->td_list, list) { |
@@ -1134,6 +1139,7 @@ static int uhci_result_isochronous(struct uhci_hcd *uhci, struct urb *urb) | |||
1134 | 1139 | ||
1135 | i++; | 1140 | i++; |
1136 | } | 1141 | } |
1142 | unlink_isochronous_tds(uhci, urb); | ||
1137 | 1143 | ||
1138 | return ret; | 1144 | return ret; |
1139 | } | 1145 | } |
@@ -1366,6 +1372,8 @@ static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) | |||
1366 | goto done; | 1372 | goto done; |
1367 | list_del_init(&urbp->urb_list); | 1373 | list_del_init(&urbp->urb_list); |
1368 | 1374 | ||
1375 | if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) | ||
1376 | unlink_isochronous_tds(uhci, urb); | ||
1369 | uhci_unlink_generic(uhci, urb); | 1377 | uhci_unlink_generic(uhci, urb); |
1370 | 1378 | ||
1371 | uhci_get_current_frame_number(uhci); | 1379 | uhci_get_current_frame_number(uhci); |