Ok,works for my NVIDA board. The /sys-files contain 1 at startup (matching blacklist) # find /sys | grep shutdown_quirk /sys/devices/pci0000:00/0000:00:02.0/shutdown_quirk /sys/devices/pci0000:00/0000:00:04.0/shutdown_quirk # find /sys | grep shutdown_quir | xargs cat 1 1 But I had to change a bit because I use a Ubuntu/Lucid 2.6.32 backport kernel in which kstrtoint is missing. OK this does not really check the integer value but also works for 0 or 1 as input: static ssize_t store_quirk(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct ohci_hcd *ohci = hcd_to_ohci(bus_to_hcd(dev_get_drvdata(dev))); if (*buf == '1') ohci->flags |= OHCI_QUIRK_SHUTDOWN; else if (*buf == '0') ohci->flags &= ~OHCI_QUIRK_SHUTDOWN; else return -ERANGE; return count; } Am 19.10.2011 22:21, schrieb Alan Stern: > You should use Reply-To-All so that your messages get sent to the > mailing list as well as to me. Sorry.... > > On Tue, 18 Oct 2011, Arno Augustin wrote: > >> Hi Alan, >> >> thank's for your answer :-) >> Yes, I think without having detailed information about nvidia >> controllers a sysfs attribute would be the best way to deal with the >> problem. >> But even if the kernel checks device IDs itself it would be more >> flexible to have the ability to write the ohci flags via sysfs.... > > Well, here's a patch that adds both a blacklist and a sysfs file called > shutdown_quirk in the directories for the OHCI controller devices. > > I can't test it very well because I don't have NVIDIA hardware. > > Alan Stern > > > > drivers/usb/host/ohci-pci.c | 67 ++++++++++++++++++++++++++++++++++++++++---- > 1 file changed, 61 insertions(+), 6 deletions(-) > > Index: usb-3.1/drivers/usb/host/ohci-pci.c > =================================================================== > --- usb-3.1.orig/drivers/usb/host/ohci-pci.c > +++ usb-3.1/drivers/usb/host/ohci-pci.c > @@ -175,7 +175,46 @@ static int ohci_quirk_amd700(struct usb_ > return 0; > } > > -/* nVidia controllers continue to drive Reset signalling on the bus > +/* Control the OHCI_QUIRK_SHUTDOWN setting */ > +static ssize_t show_shutdown_quirk(struct device *dev, > + struct device_attribute *attr, char *buf) > +{ > + struct ohci_hcd *ohci = hcd_to_ohci(bus_to_hcd(dev_get_drvdata(dev))); > + > + return sprintf(buf, "%d\n", !!(ohci->flags & OHCI_QUIRK_SHUTDOWN)); > +} > + > +static ssize_t store_shutdown_quirk(struct device *dev, > + struct device_attribute *attr, const char *buf, size_t count) > +{ > + struct ohci_hcd *ohci = hcd_to_ohci(bus_to_hcd(dev_get_drvdata(dev))); > + int v, rc; > + > + rc = kstrtoint(buf, 0, &v); > + if (rc) > + return rc; > + if (v == 1) > + ohci->flags |= OHCI_QUIRK_SHUTDOWN; > + else if (v == 0) > + ohci->flags &= ~OHCI_QUIRK_SHUTDOWN; > + else > + return -ERANGE; > + return count; > +} > +static DEVICE_ATTR(shutdown_quirk, 0644, show_shutdown_quirk, > + store_shutdown_quirk); > + > +/* > + * NVIDIA product IDs not identified correctly by the code below. > + * Keep this list sorted in numeric order. > + */ > +static u16 nvidia_blacklist[] = { > + 0x077b, 0x077d, /* MCP78S */ > + 0 /* Terminating entry */ > +}; > + > +/* > + * Some NVIDIA controllers continue to drive Reset signalling on the bus > * even after system shutdown, wasting power. This flag tells the > * shutdown routine to leave the controller OPERATIONAL instead of RESET. > */ > @@ -183,18 +222,28 @@ static int ohci_quirk_nvidia_shutdown(st > { > struct pci_dev *pdev = to_pci_dev(hcd->self.controller); > struct ohci_hcd *ohci = hcd_to_ohci(hcd); > + u16 *p; > > - /* Evidently nVidia fixed their later hardware; this is a guess at > + /* Evidently NVIDIA fixed their later hardware; this is a guess at > * the changeover point. > */ > #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_USB 0x026d > > - if (pdev->device < PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_USB) { > + if (pdev->device < PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_USB) > ohci->flags |= OHCI_QUIRK_SHUTDOWN; > - ohci_dbg(ohci, "enabled nVidia shutdown quirk\n"); > + > + /* Check against the blacklist */ > + for (p = nvidia_blacklist; *p; ++p) { > + if (*p == pdev->device) { > + ohci->flags ^= OHCI_QUIRK_SHUTDOWN; > + break; > + } > } > + if (ohci->flags & OHCI_QUIRK_SHUTDOWN) > + ohci_dbg(ohci, "enabled NVIDIA shutdown quirk\n"); > > - return 0; > + return device_create_file(hcd->self.controller, > + &dev_attr_shutdown_quirk); > } > > static void sb800_prefetch(struct ohci_hcd *ohci, int on) > @@ -322,6 +371,12 @@ static int __devinit ohci_pci_start (str > return ret; > } > > +static void ohci_pci_stop(struct usb_hcd *hcd) > +{ > + device_remove_file(hcd->self.controller, &dev_attr_shutdown_quirk); > + ohci_stop(hcd); > +} > + > #ifdef CONFIG_PM > > static int ohci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) > @@ -387,7 +442,7 @@ static const struct hc_driver ohci_pci_h > */ > .reset = ohci_pci_reset, > .start = ohci_pci_start, > - .stop = ohci_stop, > + .stop = ohci_pci_stop, > .shutdown = ohci_shutdown, > > #ifdef CONFIG_PM > -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html