On Sat, May 24, 2014 at 11:18:31AM -0400, Alan Stern wrote: > On Sat, 24 May 2014, Dr. Werner Fink wrote: > > > > > During debugging and rebooting I've seen the problem again: > > What patch were you using when you saw the problem again?
The attached one (as it does not help I've attached it;)
>
> > Sidemark ... I've tried to check the Vendor/Product indentifier but run into
> > the problem that I'd like to see the hrdware and not the driver vendor and
> > product. That is I'd like to check for the added lines:
> >
> > drivers/usb/core/quirks.c:
> >
> > /* INTEL Hub */
> > { USB_DEVICE(0x8087, 0x0024), .driver_info = USB_QUIRK_STATUS_RECL
> > },
> >
> > include/linux/usb/quirks.h:
> >
> > /* device may cause the STS_RECL status register bit in IRQ if it is
> > not used. This is a readonly bit, which is used to detect an empty
> > asynchronous schedule. */
> > #define USB_QUIRK_STATUS_RECL 0x00000080
>
> The quirk information does not belong in those files.
> drivers/usb/core/quirks.c and include/linux/usb/quirks.h are for USB
> devices, not USB host controllers.
Ahha ... that explains a lot
> PCI vendor and device IDs are stored in include/linux/pci_ids.h. But
> if you're going to use the ID in only one place (which should be
> drivers/usb/host/ehci-pci.c), there's no reason to add it to the header
> file. The quirk flag should be added to drivers/usb/host/ehci.h.
OK
> > in drivers/usb/host/ehci-hcd.c : ehci_irq() where I've added
> >
> > struct usb_device *hub;
> >
> > hub = hcd->self.root_hub;
> > if (hub->quirks & USB_QUIRK_STATUS_RECL)
> > printk_once(KERN_WARNING FW_BUG "QUIRK: INTEL hub found!");
> > printk_once(KERN_WARNING FW_BUG "EHCI Hub: Vendor %x Product %x",
> > le16_to_cpu(hub->descriptor.idVendor),
> > le16_to_cpu(hub->descriptor.idProduct));
> >
> > but then seen the Linux Foundation as Vendor and not the hardware hub.
>
> Don't print this information in ehci_irq(); print it in ehci-pci.c.
>
> And by the way, the problem is in the Intel host controller, not in an
> Intel hub.
Hmm ... I see that I'm not familiar with the netting within USB kernel :/
Werner
--
"Having a smoking section in a restaurant is like having
a peeing section in a swimming pool." -- Edward Burr
--- drivers/usb/core/quirks.c
+++ drivers/usb/core/quirks.c 2014-05-23 12:10:14.574040389 +0000
@@ -152,6 +152,9 @@ static const struct usb_device_id usb_qu
/* INTEL VALUE SSD */
{ USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME },
+ /* INTEL Hub */
+ { USB_DEVICE(0x8087, 0x0024), .driver_info = USB_QUIRK_STATUS_RECL },
+
{ } /* terminating entry must be last */
};
--- drivers/usb/host/ehci-hcd.c
+++ drivers/usb/host/ehci-hcd.c 2014-05-23 13:46:32.663713547 +0000
@@ -35,6 +35,7 @@
#include <linux/interrupt.h>
#include <linux/usb.h>
#include <linux/usb/hcd.h>
+#include <linux/usb/quirks.h>
#include <linux/moduleparam.h>
#include <linux/dma-mapping.h>
#include <linux/debugfs.h>
@@ -683,6 +684,7 @@ EXPORT_SYMBOL_GPL(ehci_setup);
static irqreturn_t ehci_irq (struct usb_hcd *hcd)
{
struct ehci_hcd *ehci = hcd_to_ehci (hcd);
+ struct usb_device *hub = hcd->self.root_hub;
u32 status, masked_status, pcd_status = 0, cmd;
int bh;
unsigned long flags;
@@ -711,6 +713,10 @@ static irqreturn_t ehci_irq (struct usb_
/* Shared IRQ? */
if (!masked_status || unlikely(ehci->rh_state == EHCI_RH_HALTED)) {
+ if (/* (hub->quirks & USB_QUIRK_STATUS_RECL) && */ (status & STS_RECL)) {
+ ehci_writel(ehci, STS_RECL, &ehci->regs->status);
+ ehci_readl(ehci, &ehci->regs->status);
+ }
spin_unlock_irqrestore(&ehci->lock, flags);
return IRQ_NONE;
}
--- include/linux/usb/quirks.h
+++ include/linux/usb/quirks.h 2014-05-23 12:10:01.546235287 +0000
@@ -30,4 +30,9 @@
descriptor */
#define USB_QUIRK_DELAY_INIT 0x00000040
+/* device may cause the STS_RECL status register bit in IRQ if it is
+ not used. This is a readonly bit, which is used to detect an empty
+ asynchronous schedule. */
+#define USB_QUIRK_STATUS_RECL 0x00000080
+
#endif /* __LINUX_USB_QUIRKS_H */
pgpgaNVbMBQRc.pgp
Description: PGP signature
