diff options
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/host/uhci-hcd.c | 69 |
1 files changed, 40 insertions, 29 deletions
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 25a718eb1d0f..cec070fa8c83 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c | |||
@@ -112,6 +112,8 @@ static inline void restart_timer(struct uhci_hcd *uhci) | |||
112 | */ | 112 | */ |
113 | static void reset_hc(struct uhci_hcd *uhci) | 113 | static void reset_hc(struct uhci_hcd *uhci) |
114 | { | 114 | { |
115 | int port; | ||
116 | |||
115 | /* Turn off PIRQ enable and SMI enable. (This also turns off the | 117 | /* Turn off PIRQ enable and SMI enable. (This also turns off the |
116 | * BIOS's USB Legacy Support.) Turn off all the R/WC bits too. | 118 | * BIOS's USB Legacy Support.) Turn off all the R/WC bits too. |
117 | */ | 119 | */ |
@@ -135,6 +137,13 @@ static void reset_hc(struct uhci_hcd *uhci) | |||
135 | outw(0, uhci->io_addr + USBINTR); | 137 | outw(0, uhci->io_addr + USBINTR); |
136 | outw(0, uhci->io_addr + USBCMD); | 138 | outw(0, uhci->io_addr + USBCMD); |
137 | 139 | ||
140 | /* HCRESET doesn't affect the Suspend, Reset, and Resume Detect | ||
141 | * bits in the port status and control registers. | ||
142 | * We have to clear them by hand. | ||
143 | */ | ||
144 | for (port = 0; port < uhci->rh_numports; ++port) | ||
145 | outw(0, uhci->io_addr + USBPORTSC1 + (port * 2)); | ||
146 | |||
138 | uhci->port_c_suspend = uhci->suspended_ports = | 147 | uhci->port_c_suspend = uhci->suspended_ports = |
139 | uhci->resuming_ports = 0; | 148 | uhci->resuming_ports = 0; |
140 | uhci->rh_state = UHCI_RH_RESET; | 149 | uhci->rh_state = UHCI_RH_RESET; |
@@ -166,14 +175,14 @@ static void check_and_reset_hc(struct uhci_hcd *uhci) | |||
166 | * When restarting a suspended controller, we expect all the | 175 | * When restarting a suspended controller, we expect all the |
167 | * settings to be the same as we left them: | 176 | * settings to be the same as we left them: |
168 | * | 177 | * |
169 | * PIRQ and SMI disabled, no R/WC bits set in USBLEGSUP; | 178 | * PIRQ and SMI disabled, no R/W bits set in USBLEGSUP; |
170 | * Controller is stopped and configured with EGSM set; | 179 | * Controller is stopped and configured with EGSM set; |
171 | * No interrupts enabled except possibly Resume Detect. | 180 | * No interrupts enabled except possibly Resume Detect. |
172 | * | 181 | * |
173 | * If any of these conditions are violated we do a complete reset. | 182 | * If any of these conditions are violated we do a complete reset. |
174 | */ | 183 | */ |
175 | pci_read_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, &legsup); | 184 | pci_read_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, &legsup); |
176 | if (legsup & ~USBLEGSUP_RO) { | 185 | if (legsup & ~(USBLEGSUP_RO | USBLEGSUP_RWC)) { |
177 | dev_dbg(uhci_dev(uhci), "%s: legsup = 0x%04x\n", | 186 | dev_dbg(uhci_dev(uhci), "%s: legsup = 0x%04x\n", |
178 | __FUNCTION__, legsup); | 187 | __FUNCTION__, legsup); |
179 | goto reset_needed; | 188 | goto reset_needed; |
@@ -478,9 +487,37 @@ static void release_uhci(struct uhci_hcd *uhci) | |||
478 | static int uhci_reset(struct usb_hcd *hcd) | 487 | static int uhci_reset(struct usb_hcd *hcd) |
479 | { | 488 | { |
480 | struct uhci_hcd *uhci = hcd_to_uhci(hcd); | 489 | struct uhci_hcd *uhci = hcd_to_uhci(hcd); |
490 | unsigned io_size = (unsigned) hcd->rsrc_len; | ||
491 | int port; | ||
481 | 492 | ||
482 | uhci->io_addr = (unsigned long) hcd->rsrc_start; | 493 | uhci->io_addr = (unsigned long) hcd->rsrc_start; |
483 | 494 | ||
495 | /* The UHCI spec says devices must have 2 ports, and goes on to say | ||
496 | * they may have more but gives no way to determine how many there | ||
497 | * are. However, according to the UHCI spec, Bit 7 of the port | ||
498 | * status and control register is always set to 1. So we try to | ||
499 | * use this to our advantage. | ||
500 | */ | ||
501 | for (port = 0; port < (io_size - USBPORTSC1) / 2; port++) { | ||
502 | unsigned int portstatus; | ||
503 | |||
504 | portstatus = inw(uhci->io_addr + USBPORTSC1 + (port * 2)); | ||
505 | if (!(portstatus & 0x0080)) | ||
506 | break; | ||
507 | } | ||
508 | if (debug) | ||
509 | dev_info(uhci_dev(uhci), "detected %d ports\n", port); | ||
510 | |||
511 | /* Anything less than 2 or greater than 7 is weird, | ||
512 | * so we'll ignore it. | ||
513 | */ | ||
514 | if (port < 2 || port > UHCI_RH_MAXCHILD) { | ||
515 | dev_info(uhci_dev(uhci), "port count misdetected? " | ||
516 | "forcing to 2 ports\n"); | ||
517 | port = 2; | ||
518 | } | ||
519 | uhci->rh_numports = port; | ||
520 | |||
484 | /* Kick BIOS off this hardware and reset if the controller | 521 | /* Kick BIOS off this hardware and reset if the controller |
485 | * isn't already safely quiescent. | 522 | * isn't already safely quiescent. |
486 | */ | 523 | */ |
@@ -508,13 +545,11 @@ static int uhci_start(struct usb_hcd *hcd) | |||
508 | { | 545 | { |
509 | struct uhci_hcd *uhci = hcd_to_uhci(hcd); | 546 | struct uhci_hcd *uhci = hcd_to_uhci(hcd); |
510 | int retval = -EBUSY; | 547 | int retval = -EBUSY; |
511 | int i, port; | 548 | int i; |
512 | unsigned io_size; | ||
513 | dma_addr_t dma_handle; | 549 | dma_addr_t dma_handle; |
514 | struct usb_device *udev; | 550 | struct usb_device *udev; |
515 | struct dentry *dentry; | 551 | struct dentry *dentry; |
516 | 552 | ||
517 | io_size = (unsigned) hcd->rsrc_len; | ||
518 | hcd->uses_new_polling = 1; | 553 | hcd->uses_new_polling = 1; |
519 | if (pci_find_capability(to_pci_dev(uhci_dev(uhci)), PCI_CAP_ID_PM)) | 554 | if (pci_find_capability(to_pci_dev(uhci_dev(uhci)), PCI_CAP_ID_PM)) |
520 | hcd->can_wakeup = 1; /* Assume it supports PME# */ | 555 | hcd->can_wakeup = 1; /* Assume it supports PME# */ |
@@ -578,30 +613,6 @@ static int uhci_start(struct usb_hcd *hcd) | |||
578 | 613 | ||
579 | /* Initialize the root hub */ | 614 | /* Initialize the root hub */ |
580 | 615 | ||
581 | /* UHCI specs says devices must have 2 ports, but goes on to say */ | ||
582 | /* they may have more but give no way to determine how many they */ | ||
583 | /* have. However, according to the UHCI spec, Bit 7 is always set */ | ||
584 | /* to 1. So we try to use this to our advantage */ | ||
585 | for (port = 0; port < (io_size - 0x10) / 2; port++) { | ||
586 | unsigned int portstatus; | ||
587 | |||
588 | portstatus = inw(uhci->io_addr + 0x10 + (port * 2)); | ||
589 | if (!(portstatus & 0x0080)) | ||
590 | break; | ||
591 | } | ||
592 | if (debug) | ||
593 | dev_info(uhci_dev(uhci), "detected %d ports\n", port); | ||
594 | |||
595 | /* This is experimental so anything less than 2 or greater than 8 is */ | ||
596 | /* something weird and we'll ignore it */ | ||
597 | if (port < 2 || port > UHCI_RH_MAXCHILD) { | ||
598 | dev_info(uhci_dev(uhci), "port count misdetected? " | ||
599 | "forcing to 2 ports\n"); | ||
600 | port = 2; | ||
601 | } | ||
602 | |||
603 | uhci->rh_numports = port; | ||
604 | |||
605 | udev = usb_alloc_dev(NULL, &hcd->self, 0); | 616 | udev = usb_alloc_dev(NULL, &hcd->self, 0); |
606 | if (!udev) { | 617 | if (!udev) { |
607 | dev_err(uhci_dev(uhci), "unable to allocate root hub\n"); | 618 | dev_err(uhci_dev(uhci), "unable to allocate root hub\n"); |