On Tue, 29 May 2012, Rafael J. Wysocki wrote: > > > > Therefore we really do need a quirk, probably in ehci-hcd like the > > > > original patch. If it is restricted to apply only in cases where the > > > > DMI information lists ASUSTeK as the manufacturer, perhaps that will be > > > > sufficient. (For some reason, the manufacturer field in Dâniel's BIOS > > > > isn't initialized.) > > > > > > Yeah. > > > > > > I'll have a deeper look at this later today, I think. > > > > It's easy enough to write such a check (or perhaps more reliably, check > > for a product name matching "P8Z68-V"). > > I think we should try to express it as a PCI quirk in quirks.c, though. Here's my attempt. Everybody, please try this patch with the 151b61284776 commit removed. Make sure that CONFIG_USB_DEBUG is enabled so we can check the controller's power state during suspend, and check that the "broken D3 during system sleep on ASUS" message shows up during booting. Alan Stern Index: usb-3.4/drivers/pci/pci.c =================================================================== --- usb-3.4.orig/drivers/pci/pci.c +++ usb-3.4/drivers/pci/pci.c @@ -1743,6 +1743,11 @@ int pci_prepare_to_sleep(struct pci_dev if (target_state == PCI_POWER_ERROR) return -EIO; + /* Some devices mustn't be in D3 during system sleep */ + if (target_state == PCI_D3hot && + (dev->dev_flags & PCI_DEV_FLAGS_NO_D3_DURING_SLEEP)) + return 0; + pci_enable_wake(dev, target_state, device_may_wakeup(&dev->dev)); error = pci_set_power_state(dev, target_state); Index: usb-3.4/drivers/pci/quirks.c =================================================================== --- usb-3.4.orig/drivers/pci/quirks.c +++ usb-3.4/drivers/pci/quirks.c @@ -2917,6 +2917,32 @@ static void __devinit disable_igfx_irq(s DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0102, disable_igfx_irq); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x010a, disable_igfx_irq); +/* + * The Intel 6 Series/C200 Series chipset's EHCI controllers on many + * ASUS motherboards will cause memory corruption or a system crash + * if they are in D3 while the system is put into S3 sleep. + */ +static void __devinit asus_ehci_no_d3(struct pci_dev *dev) +{ + const char *sys_info; + static const char good_Asus_board[] = "P8Z68-V"; + + if (dev->dev_flags & PCI_DEV_FLAGS_NO_D3_DURING_SLEEP) + return; + if (dev->subsystem_vendor != PCI_VENDOR_ID_ASUSTEK) + return; + sys_info = dmi_get_system_info(DMI_BOARD_NAME); + if (sys_info && memcmp(sys_info, good_Asus_board, + sizeof(good_Asus_board) - 1) == 0) + return; + + dev_info(&dev->dev, "broken D3 during system sleep on ASUS\n"); + dev->dev_flags |= PCI_DEV_FLAGS_NO_D3_DURING_SLEEP; + device_set_wakeup_capable(&dev->dev, false); +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1c26, asus_ehci_no_d3); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1c2d, asus_ehci_no_d3); + static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end) { Index: usb-3.4/include/linux/pci.h =================================================================== --- usb-3.4.orig/include/linux/pci.h +++ usb-3.4/include/linux/pci.h @@ -176,6 +176,8 @@ enum pci_dev_flags { PCI_DEV_FLAGS_NO_D3 = (__force pci_dev_flags_t) 2, /* Provide indication device is assigned by a Virtual Machine Manager */ PCI_DEV_FLAGS_ASSIGNED = (__force pci_dev_flags_t) 4, + /* Device causes system crash if in D3 during S3 sleep */ + PCI_DEV_FLAGS_NO_D3_DURING_SLEEP = (__force pci_dev_flags_t) 8, }; enum pci_irq_reroute_variant { _______________________________________________ linux-pm mailing list linux-pm@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linuxfoundation.org/mailman/listinfo/linux-pm