aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2005-05-31 16:33:21 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2005-06-27 17:44:00 -0400
commite07fefa6b212f43c40fdbc1a62de690d91a4b617 (patch)
tree8426cdb4a4b8c7b9a0ce2cc360beebf9499d9572 /drivers
parent486e2df6ce213d0c776befdf3fe5ffc61dd61688 (diff)
[PATCH] USB UHCI: Detect invalid ports
This patch changes the way uhci-hcd detects valid ports. The specification doesn't mention any way to find out how many ports a controller has, so the driver has to use some heuristics, reading the port status and control register and deciding whether the value makes sense. With this patch the driver will recognize a typical failure mode (all bits set to one) for nonexistent ports and won't assume there are always at least 2 ports -- such an assumption seems silly if the heuristics have already shown that the ports don't exist. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/host/uhci-hcd.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index fdf54295da73..0d5d2545bf07 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -495,24 +495,24 @@ static int uhci_reset(struct usb_hcd *hcd)
495 495
496 /* The UHCI spec says devices must have 2 ports, and goes on to say 496 /* The UHCI spec says devices must have 2 ports, and goes on to say
497 * they may have more but gives no way to determine how many there 497 * they may have more but gives no way to determine how many there
498 * are. However, according to the UHCI spec, Bit 7 of the port 498 * are. However according to the UHCI spec, Bit 7 of the port
499 * status and control register is always set to 1. So we try to 499 * status and control register is always set to 1. So we try to
500 * use this to our advantage. 500 * use this to our advantage. Another common failure mode when
501 * a nonexistent register is addressed is to return all ones, so
502 * we test for that also.
501 */ 503 */
502 for (port = 0; port < (io_size - USBPORTSC1) / 2; port++) { 504 for (port = 0; port < (io_size - USBPORTSC1) / 2; port++) {
503 unsigned int portstatus; 505 unsigned int portstatus;
504 506
505 portstatus = inw(uhci->io_addr + USBPORTSC1 + (port * 2)); 507 portstatus = inw(uhci->io_addr + USBPORTSC1 + (port * 2));
506 if (!(portstatus & 0x0080)) 508 if (!(portstatus & 0x0080) || portstatus == 0xffff)
507 break; 509 break;
508 } 510 }
509 if (debug) 511 if (debug)
510 dev_info(uhci_dev(uhci), "detected %d ports\n", port); 512 dev_info(uhci_dev(uhci), "detected %d ports\n", port);
511 513
512 /* Anything less than 2 or greater than 7 is weird, 514 /* Anything greater than 7 is weird so we'll ignore it. */
513 * so we'll ignore it. 515 if (port > UHCI_RH_MAXCHILD) {
514 */
515 if (port < 2 || port > UHCI_RH_MAXCHILD) {
516 dev_info(uhci_dev(uhci), "port count misdetected? " 516 dev_info(uhci_dev(uhci), "port count misdetected? "
517 "forcing to 2 ports\n"); 517 "forcing to 2 ports\n");
518 port = 2; 518 port = 2;