On Thu, 27 Mar 2014, Peter Münster wrote: > Hi Alan, > > These are my commands: > > echo 8 >/proc/sys/kernel/printk > echo on >/sys/bus/usb/devices/4-2/power/control > sleep 1 > echo 0 >/sys/bus/usb/devices/4-2/bConfigurationValue > sleep 1 > echo auto >/sys/bus/pci/devices/0000:00:12.1/power/control > sleep 1 > echo auto >/sys/bus/usb/devices/4-2/power/control > sleep 10 > echo on >/sys/bus/usb/devices/4-2/power/control > > Please find attached the kernel messages and the content of the > registers file once per second. This just raises more questions. It looks like it worked almost okay, but not quite. Certainly it didn't hang, so it isn't an exact reproduction of the problem. Can you run the same test again, and then at the end, do: echo 1 >/sys/bus/usb/devices/4-2/bConfigurationValue (Actually this 1 should be whatever was in the file before you started the test -- it probably was 1 but it might be something else.) After that, the mouse should be working properly. Check it and see, and post the kernel log. (Don't bother to check the frame number values, since we already know they are changing.) Back when you ran the system suspend test under the 3.9 kernel with CONFIG_USB_SUSPEND turned off, you said the system was okay after the resume. Does that mean the mouse and keyboard were working normally? One more thing... The bad commit should have no effect on devices enabled for wakeup -- and keyboards generally _are_ enabled for wakeup. Can you check this? Under 3.12.x with no patches or reversions, plug the mouse into a front port and the keyboard into its usual rear port. Before going into suspend, make sure that the keyboard's power/wakeup file (/sys/bus/usb/devices/4-3/power/wakeup) contains "enabled". (Write it to the file if the file says "disabled".) Then test if the suspend and resume work okay -- capture the log with netconsole and let's see what it says. Finally, I'd like to get more information about what causes the system to hang when things go wrong. Below is a diagnostic patch for the 3.12 kernel -- you can keep the previous patch or remove it, it doesn't matter. This patch is intended to print information to the console every 10 seconds while the system is hung, so if it works then we should get some useful clues. Plug the mouse into the rear port and see what happens after a suspend. Alan Stern Index: usb-3.14/drivers/usb/host/ohci-hcd.c =================================================================== --- usb-3.14.orig/drivers/usb/host/ohci-hcd.c +++ usb-3.14/drivers/usb/host/ohci-hcd.c @@ -79,6 +79,19 @@ static const char hcd_name [] = "ohci_hc static void ohci_dump (struct ohci_hcd *ohci, int verbose); static void ohci_stop (struct usb_hcd *hcd); +static void alantimer_func(unsigned long _ohci) +{ + struct ohci_hcd *ohci = (struct ohci_hcd *) _ohci; + + ohci_info(ohci, "Timer: count %d intr-en %x intr-stat %x frame %x\n", + ohci->alancount, + ohci_readl(ohci, &ohci->regs->intrenable), + ohci_readl(ohci, &ohci->regs->intrstatus), + ohci_frame_no(ohci)); + if (ohci->alancount > 0) + mod_timer(&ohci->alantimer, jiffies + HZ*10); +} + #include "ohci-hub.c" #include "ohci-dbg.c" #include "ohci-mem.c" @@ -289,6 +302,10 @@ static int ohci_urb_dequeue(struct usb_h * handed to us, flag it for unlink and giveback, and force * some upcoming INTR_SF to call finish_unlinks() */ + if (ohci->alancount == 0) + mod_timer(&ohci->alantimer, jiffies + HZ*10); + ohci_info(ohci, "Dequeue: %p count %d\n", urb, + ++ohci->alancount); urb_priv = urb->hcpriv; if (urb_priv) { if (urb_priv->ed->state == ED_OPER) @@ -299,6 +316,8 @@ static int ohci_urb_dequeue(struct usb_h * with HC dead, we won't respect hc queue pointers * any more ... just clean up every urb's memory. */ + ohci_info(ohci, "Dequeue: %p count %d\n", urb, + ++ohci->alancount); if (urb->hcpriv) finish_urb(ohci, urb, status); } @@ -745,6 +764,7 @@ retry: } ohci_dump (ohci, 1); + setup_timer(&ohci->alantimer, alantimer_func, (unsigned long) ohci); return 0; } @@ -801,6 +821,12 @@ static irqreturn_t ohci_irq (struct usb_ return IRQ_HANDLED; } + if (ohci->alancount > 0) + ohci_info(ohci, "IRQ: count %d intr-en %x intr-stat %x frame %x\n", + ohci->alancount, + ohci_readl(ohci, ®s->intrenable), ints, + ohci_frame_no(ohci)); + /* We only care about interrupts that are enabled */ ints &= ohci_readl(ohci, ®s->intrenable); Index: usb-3.14/drivers/usb/host/ohci-q.c =================================================================== --- usb-3.14.orig/drivers/usb/host/ohci-q.c +++ usb-3.14/drivers/usb/host/ohci-q.c @@ -69,6 +69,14 @@ __acquires(ohci->lock) } /* urb->complete() can reenter this HCD */ + if (urb->unlinked) { + ohci_info(ohci, "Giveback: %p count %d\n", + urb, ohci->alancount); + if (ohci->alancount > 0) + --ohci->alancount; + if (ohci->alancount == 0) + del_timer(&ohci->alantimer); + } usb_hcd_unlink_urb_from_ep(ohci_to_hcd(ohci), urb); spin_unlock (&ohci->lock); usb_hcd_giveback_urb(ohci_to_hcd(ohci), urb, status); Index: usb-3.14/drivers/usb/host/ohci.h =================================================================== --- usb-3.14.orig/drivers/usb/host/ohci.h +++ usb-3.14/drivers/usb/host/ohci.h @@ -409,6 +409,9 @@ struct ohci_hcd { struct work_struct nec_work; /* Worker for NEC quirk */ + struct timer_list alantimer; + int alancount; + /* Needed for ZF Micro quirk */ struct timer_list unlink_watchdog; unsigned eds_scheduled; -- 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