Commit 5f8364b7d63acdc2216ca0f7d0a8557c318479ea
Committed by
Greg Kroah-Hartman
1 parent
fe1ec341df
Exists in
master
and in
7 other branches
UHCI: module parameter to ignore overcurrent changes
Certain boards seem to like to issue false overcurrent notifications, for example on ports that don't have anything connected to them. This looks like a hardware error, at the level of noise to those ports' overcurrent input signals (or non-debounced VBUS comparators). This surfaces to users as truly massive amounts of syslog spam from khubd (which is appropriate for real hardware problems, except for the volume from multiple ports). Using this new "ignore_oc" flag helps such systems work more sanely, by preventing such indications from getting to khubd (and spamming syslog). The downside is of course that true overcurrent errors will be masked; they'll appear as spontaneous disconnects, without the diagnostics that will let users troubleshoot issues like short-circuited cables. In addition, controllers with no devices attached will be forced to poll for new devices rather than relying on interrupts, since each overcurrent event would generate a new interrupt. This patch (as826) is essentially a copy of David Brownell's ignore_oc patch for ehci-hcd, ported to uhci-hcd. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Showing 3 changed files with 32 additions and 3 deletions Side-by-side Diff
Documentation/kernel-parameters.txt
... | ... | @@ -1714,6 +1714,14 @@ |
1714 | 1714 | uart6850= [HW,OSS] |
1715 | 1715 | Format: <io>,<irq> |
1716 | 1716 | |
1717 | + uhci-hcd.ignore_oc= | |
1718 | + [USB] Ignore overcurrent events (default N). | |
1719 | + Some badly-designed motherboards generate lots of | |
1720 | + bogus events, for ports that aren't wired to | |
1721 | + anything. Set this parameter to avoid log spamming. | |
1722 | + Note that genuine overcurrent events won't be | |
1723 | + reported either. | |
1724 | + | |
1717 | 1725 | usbhid.mousepoll= |
1718 | 1726 | [USBHID] The interval which mice are to be polled at. |
1719 | 1727 |
drivers/usb/host/uhci-hcd.c
... | ... | @@ -60,6 +60,11 @@ |
60 | 60 | Alan Stern" |
61 | 61 | #define DRIVER_DESC "USB Universal Host Controller Interface driver" |
62 | 62 | |
63 | +/* for flakey hardware, ignore overcurrent indicators */ | |
64 | +static int ignore_oc; | |
65 | +module_param(ignore_oc, bool, S_IRUGO); | |
66 | +MODULE_PARM_DESC(ignore_oc, "ignore hardware overcurrent indications"); | |
67 | + | |
63 | 68 | /* |
64 | 69 | * debug = 0, no debugging messages |
65 | 70 | * debug = 1, dump failed URBs except for stalls |
... | ... | @@ -169,6 +174,11 @@ |
169 | 174 | { |
170 | 175 | int port; |
171 | 176 | |
177 | + /* If we have to ignore overcurrent events then almost by definition | |
178 | + * we can't depend on resume-detect interrupts. */ | |
179 | + if (ignore_oc) | |
180 | + return 1; | |
181 | + | |
172 | 182 | switch (to_pci_dev(uhci_dev(uhci))->vendor) { |
173 | 183 | default: |
174 | 184 | break; |
... | ... | @@ -921,7 +931,8 @@ |
921 | 931 | { |
922 | 932 | int retval = -ENOMEM; |
923 | 933 | |
924 | - printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION "\n"); | |
934 | + printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION "%s\n", | |
935 | + ignore_oc ? ", overcurrent ignored" : ""); | |
925 | 936 | |
926 | 937 | if (usb_disabled()) |
927 | 938 | return -ENODEV; |
drivers/usb/host/uhci-hub.c
... | ... | @@ -52,10 +52,20 @@ |
52 | 52 | static inline int get_hub_status_data(struct uhci_hcd *uhci, char *buf) |
53 | 53 | { |
54 | 54 | int port; |
55 | + int mask = RWC_BITS; | |
55 | 56 | |
57 | + /* Some boards (both VIA and Intel apparently) report bogus | |
58 | + * overcurrent indications, causing massive log spam unless | |
59 | + * we completely ignore them. This doesn't seem to be a problem | |
60 | + * with the chipset so much as with the way it is connected on | |
61 | + * the motherboard; if the overcurrent input is left to float | |
62 | + * then it may constantly register false positives. */ | |
63 | + if (ignore_oc) | |
64 | + mask &= ~USBPORTSC_OCC; | |
65 | + | |
56 | 66 | *buf = 0; |
57 | 67 | for (port = 0; port < uhci->rh_numports; ++port) { |
58 | - if ((inw(uhci->io_addr + USBPORTSC1 + port * 2) & RWC_BITS) || | |
68 | + if ((inw(uhci->io_addr + USBPORTSC1 + port * 2) & mask) || | |
59 | 69 | test_bit(port, &uhci->port_c_suspend)) |
60 | 70 | *buf |= (1 << (port + 1)); |
61 | 71 | } |
... | ... | @@ -263,7 +273,7 @@ |
263 | 273 | wPortChange |= USB_PORT_STAT_C_CONNECTION; |
264 | 274 | if (status & USBPORTSC_PEC) |
265 | 275 | wPortChange |= USB_PORT_STAT_C_ENABLE; |
266 | - if (status & USBPORTSC_OCC) | |
276 | + if ((status & USBPORTSC_OCC) && !ignore_oc) | |
267 | 277 | wPortChange |= USB_PORT_STAT_C_OVERCURRENT; |
268 | 278 | |
269 | 279 | if (test_bit(port, &uhci->port_c_suspend)) { |