提交 e07fefa6 编写于 作者: A Alan Stern 提交者: Greg Kroah-Hartman

[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: NAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: NGreg Kroah-Hartman <gregkh@suse.de>
上级 486e2df6
...@@ -495,24 +495,24 @@ static int uhci_reset(struct usb_hcd *hcd) ...@@ -495,24 +495,24 @@ static int uhci_reset(struct usb_hcd *hcd)
/* The UHCI spec says devices must have 2 ports, and goes on to say /* The UHCI spec says devices must have 2 ports, and goes on to say
* they may have more but gives no way to determine how many there * they may have more but gives no way to determine how many there
* are. However, according to the UHCI spec, Bit 7 of the port * are. However according to the UHCI spec, Bit 7 of the port
* status and control register is always set to 1. So we try to * status and control register is always set to 1. So we try to
* use this to our advantage. * use this to our advantage. Another common failure mode when
* a nonexistent register is addressed is to return all ones, so
* we test for that also.
*/ */
for (port = 0; port < (io_size - USBPORTSC1) / 2; port++) { for (port = 0; port < (io_size - USBPORTSC1) / 2; port++) {
unsigned int portstatus; unsigned int portstatus;
portstatus = inw(uhci->io_addr + USBPORTSC1 + (port * 2)); portstatus = inw(uhci->io_addr + USBPORTSC1 + (port * 2));
if (!(portstatus & 0x0080)) if (!(portstatus & 0x0080) || portstatus == 0xffff)
break; break;
} }
if (debug) if (debug)
dev_info(uhci_dev(uhci), "detected %d ports\n", port); dev_info(uhci_dev(uhci), "detected %d ports\n", port);
/* Anything less than 2 or greater than 7 is weird, /* Anything greater than 7 is weird so we'll ignore it. */
* so we'll ignore it. if (port > UHCI_RH_MAXCHILD) {
*/
if (port < 2 || port > UHCI_RH_MAXCHILD) {
dev_info(uhci_dev(uhci), "port count misdetected? " dev_info(uhci_dev(uhci), "port count misdetected? "
"forcing to 2 ports\n"); "forcing to 2 ports\n");
port = 2; port = 2;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册