aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/uhci-hcd.c
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2005-04-22 14:39:12 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2005-06-27 17:43:44 -0400
commitc074b416b94c0aa4a371f24bf6cc13d8cf1fab59 (patch)
tree51cfe6ca9293b9484108ed757ec3c43eb5328474 /drivers/usb/host/uhci-hcd.c
parent6c1b445c226dd82d0961725dec8051b95003723a (diff)
[PATCH] USB UHCI: improved reset handling
This patch improves the strategy uhci-hcd uses for performing controller resets and checking whether they are needed. The HCRESET command doesn't affect the Suspend, Resume, or Reset bits in the port status & control registers, so the driver must clear them by itself. This means the code to figure out how many ports there are has to be moved to an earlier spot in the driver. The R/WC bits in the USBLEGSUP register can be set by the hardware even in the absence of BIOS meddling with legacy support features. Hence it's not a good idea to check them while trying to determine whether the BIOS has altered the controller's state. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/uhci-hcd.c')
-rw-r--r--drivers/usb/host/uhci-hcd.c69
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 */
113static void reset_hc(struct uhci_hcd *uhci) 113static 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)
478static int uhci_reset(struct usb_hcd *hcd) 487static 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");