[SUCCESS REPORT / PATCH] yenta_socket IRQ woes w/ NetGear WG511T ("IRQ#11: nobody cared" either, but a different one)

Mike Cumings mcumings at gmail.com
Tue May 10 17:37:26 EDT 2005


I was able to give a test run with this patch applied on top of
2.6.8.11.  Unfortunately
I had no luck getting my WG511U to work, even after adding the irqpoll argument
Dominique suggested.

Requested output dumps attached.

Mike

On 4/30/05, Daniel Ritz <daniel.ritz at gmx.ch> wrote:
> hi dominique
> 
> thanks for the report. the problem is the patch there is a quick hack which
> is wrong and breaks other stuff. could you instead try with the attached one?
> it contains all my current changes (which i really need to split up soon).
> 
> if it doesn't help please send the following:
> - output of dmesg
> - cat /proc/iomem
> - cat /proc/interrupts
> - lspci
> - lspci -vvvn
> 
> rgds
> -daniel
> 
> On Friday 29 April 2005 10:32, Dominique Quatravaux wrote:
> > Dear PCMCIA people, dear Daniel,
> >
> > I am reporting success with the patches by Daniel on the LKML a month
> > ago (see http://lkml.org/lkml/2005/3/18/218), targeted to a setup and
> > problem very similar to mine (see this message's title). FWIW I collated
> > both patches into a single one that applies against Ubuntu's (patched)
> > 2.6.10 kernel. Setting "irqpoll" on the kernel command line was also
> > necessary in my case. See details at
> > http://bugzilla.ubuntu.com/show_bug.cgi?id=10265
> >
> > I am unsure what I should do next (if anything) in order to get Daniel's
> > patch accepted into the mainstream kernel, please advise.
> >
> > Anyway thanks for your precious help Daniel, the Medion laptop I have on
> > loan for advocacy purposes is now up, running *and* surfing the Web :-)
> >
> > --
> > << Tout n'y est pas parfait, mais on y honore certainement les jardiniers >>
> >
> >                       Dominique Quatravaux <dom at kilimandjaro.dyndns.org>
> >
> >
> 
> against 2.6.12-rc1 but chances to apply on a different kernel are quite big :)
> 
> --- 1.22/drivers/pcmcia/ti113x.h        2005-03-11 21:32:12 +01:00
> +++ edited/drivers/pcmcia/ti113x.h      2005-04-21 00:12:09 +02:00
> @@ -442,6 +442,25 @@
>  }
> 
> +/* changes the irq of func1 to match that of func0 */
> +static int ti12xx_align_irqs(struct yenta_socket *socket, int *old_irq)
> +{
> +       struct pci_dev *func0;
> +
> +       /* find func0 device */
> +       func0 = pci_get_slot(socket->dev->bus, socket->dev->devfn & ~0x07);
> +       if (!func0)
> +               return 0;
> +
> +       if (old_irq)
> +               *old_irq = socket->cb_irq;
> +       socket->cb_irq = socket->dev->irq = func0->irq;
> +
> +       pci_dev_put(func0);
> +
> +       return 1;
> +}
> +
>  /*
>   * ties INTA and INTB together. also changes the devices irq to that of
>   * the function 0 device. call from func1 only.
> @@ -449,26 +468,22 @@
>   */
>  static int ti12xx_tie_interrupts(struct yenta_socket *socket, int *old_irq)
>  {
> -       struct pci_dev *func0;
>         u32 sysctl;
> +       int ret;
> 
>         sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL);
>         if (sysctl & TI122X_SCR_INTRTIE)
>                 return 0;
> 
> -       /* find func0 device */
> -       func0 = pci_get_slot(socket->dev->bus, socket->dev->devfn & ~0x07);
> -       if (!func0)
> +       /* align */
> +       ret = ti12xx_align_irqs(socket, old_irq);
> +       if (!ret)
>                 return 0;
> 
> -       /* change the interrupt to match func0, tie 'em up */
> -       *old_irq = socket->cb_irq;
> -       socket->cb_irq = socket->dev->irq = func0->irq;
> +       /* tie */
>         sysctl |= TI122X_SCR_INTRTIE;
>         config_writel(socket, TI113X_SYSTEM_CONTROL, sysctl);
> 
> -       pci_dev_put(func0);
> -
>         return 1;
>  }
> 
> @@ -489,7 +504,7 @@
>   */
>  static void ti12xx_irqroute_func1(struct yenta_socket *socket)
>  {
> -       u32 mfunc, mfunc_old, devctl;
> +       u32 mfunc, mfunc_old, devctl, sysctl;
>         int pci_irq_status;
> 
>         mfunc = mfunc_old = config_readl(socket, TI122X_MFUNC);
> @@ -497,6 +512,11 @@
>         printk(KERN_INFO "Yenta TI: socket %s, mfunc 0x%08x, devctl 0x%02x\n",
>                pci_name(socket->dev), mfunc, devctl);
> 
> +       /* if IRQs are configured as tied, align irq of func1 with func0 */
> +       sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL);
> +       if (sysctl & TI122X_SCR_INTRTIE)
> +               ti12xx_align_irqs(socket, NULL);
> +
>         /* make sure PCI interrupts are enabled before probing */
>         ti_init(socket);
> 
> @@ -590,6 +610,7 @@
>                        pci_name(socket->dev));
>         }
>  }
> +
> 
>  static int ti12xx_override(struct yenta_socket *socket)
>  {
> --- 1.71/drivers/pcmcia/yenta_socket.c  2005-03-29 00:21:41 +02:00
> +++ edited/drivers/pcmcia/yenta_socket.c        2005-04-30 00:18:46 +02:00
> @@ -32,6 +32,10 @@
>  module_param(disable_clkrun, bool, 0444);
>  MODULE_PARM_DESC(disable_clkrun, "If PC card doesn't function properly, please try this option");
> 
> +static int isa_probe = 1;
> +module_param(isa_probe, bool, 0444);
> +MODULE_PARM_DESC(isa_probe, "If set ISA interrupts are probed (default). Set to N to disable probing");
> +
>  #if 0
>  #define debug(x,args...) printk(KERN_DEBUG "%s: " x, __func__ , ##args)
>  #else
> @@ -150,15 +154,15 @@
> 
>         val  = (state & CB_3VCARD) ? SS_3VCARD : 0;
>         val |= (state & CB_XVCARD) ? SS_XVCARD : 0;
> -       val |= (state & (CB_CDETECT1 | CB_CDETECT2 | CB_5VCARD | CB_3VCARD
> -                        | CB_XVCARD | CB_YVCARD)) ? 0 : SS_PENDING;
> +       val |= (state & (CB_5VCARD | CB_3VCARD | CB_XVCARD | CB_YVCARD)) ? 0 : SS_PENDING;
> +       val |= (state & (CB_CDETECT1 | CB_CDETECT2)) ? SS_PENDING : 0;
> 
>         if (state & CB_CBCARD) {
>                 val |= SS_CARDBUS;
>                 val |= (state & CB_CARDSTS) ? SS_STSCHG : 0;
>                 val |= (state & (CB_CDETECT1 | CB_CDETECT2)) ? 0 : SS_DETECT;
>                 val |= (state & CB_PWRCYCLE) ? SS_POWERON | SS_READY : 0;
> -       } else {
> +       } else if (state & CB_16BITCARD) {
>                 u8 status = exca_readb(socket, I365_STATUS);
>                 val |= ((status & I365_CS_DETECT) == I365_CS_DETECT) ? SS_DETECT : 0;
>                 if (exca_readb(socket, I365_INTCTL) & I365_PC_IOCARD) {
> @@ -405,11 +409,13 @@
>  }
> 
> -static unsigned int yenta_events(struct yenta_socket *socket)
> +
> +static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs)
>  {
> +       unsigned int events;
> +       struct yenta_socket *socket = (struct yenta_socket *) dev_id;
>         u8 csc;
>         u32 cb_event;
> -       unsigned int events;
> 
>         /* Clear interrupt status for the event */
>         cb_event = cb_readl(socket, CB_SOCKET_EVENT);
> @@ -426,20 +432,13 @@
>                 events |= (csc & I365_CSC_BVD2) ? SS_BATWARN : 0;
>                 events |= (csc & I365_CSC_READY) ? SS_READY : 0;
>         }
> -       return events;
> -}
> -
> 
> -static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs)
> -{
> -       unsigned int events;
> -       struct yenta_socket *socket = (struct yenta_socket *) dev_id;
> -
> -       events = yenta_events(socket);
> -       if (events) {
> +       if (events)
>                 pcmcia_parse_events(&socket->socket, events);
> +
> +       if (cb_event || csc)
>                 return IRQ_HANDLED;
> -       }
> +
>         return IRQ_NONE;
>  }
> 
> @@ -470,11 +469,23 @@
>         }
>  }
> 
> +/* redoes voltage interrogation if required */
> +static void yenta_interrogate(struct yenta_socket *socket)
> +{
> +       u32 state;
> +
> +       state = cb_readl(socket, CB_SOCKET_STATE);
> +       if (!(state & (CB_5VCARD | CB_3VCARD | CB_XVCARD | CB_YVCARD)) ||
> +            (state & (CB_CDETECT1 | CB_CDETECT2 | CB_NOTACARD | CB_BADVCCREQ)) ||
> +            ((state & (CB_16BITCARD | CB_CBCARD)) == (CB_16BITCARD | CB_CBCARD)))
> +               cb_writel(socket, CB_SOCKET_FORCE, CB_CVSTEST);
> +}
> +
> +
>  /* Called at resume and initialization events */
>  static int yenta_sock_init(struct pcmcia_socket *sock)
>  {
>         struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
> -       u32 state;
>         u16 bridge;
> 
>         bridge = config_readw(socket, CB_BRIDGE_CONTROL) & ~CB_BRIDGE_INTR;
> @@ -486,10 +497,7 @@
>         exca_writeb(socket, I365_GENCTL, 0x00);
> 
>         /* Redo card voltage interrogation */
> -       state = cb_readl(socket, CB_SOCKET_STATE);
> -       if (!(state & (CB_CDETECT1 | CB_CDETECT2 | CB_5VCARD |
> -                      CB_3VCARD | CB_XVCARD | CB_YVCARD)))
> -               cb_writel(socket, CB_SOCKET_FORCE, CB_CVSTEST);
> +       yenta_interrogate(socket);
> 
>         yenta_clear_maps(socket);
> 
> @@ -749,16 +757,8 @@
>  {
>         int i;
>         unsigned long val;
> -       u16 bridge_ctrl;
>         u32 mask;
> 
> -       /* Set up ISA irq routing to probe the ISA irqs.. */
> -       bridge_ctrl = config_readw(socket, CB_BRIDGE_CONTROL);
> -       if (!(bridge_ctrl & CB_BRIDGE_INTR)) {
> -               bridge_ctrl |= CB_BRIDGE_INTR;
> -               config_writew(socket, CB_BRIDGE_CONTROL, bridge_ctrl);
> -       }
> -
>         /*
>          * Probe for usable interrupts using the force
>          * register to generate bogus card status events.
> @@ -780,9 +780,6 @@
> 
>         mask = probe_irq_mask(val) & 0xffff;
> 
> -       bridge_ctrl &= ~CB_BRIDGE_INTR;
> -       config_writew(socket, CB_BRIDGE_CONTROL, bridge_ctrl);
> -
>         return mask;
>  }
> 
> @@ -810,18 +807,11 @@
>  /* probes the PCI interrupt, use only on override functions */
>  static int yenta_probe_cb_irq(struct yenta_socket *socket)
>  {
> -       u16 bridge_ctrl;
> -
>         if (!socket->cb_irq)
>                 return -1;
> 
>         socket->probe_status = 0;
> 
> -       /* disable ISA interrupts */
> -       bridge_ctrl = config_readw(socket, CB_BRIDGE_CONTROL);
> -       bridge_ctrl &= ~CB_BRIDGE_INTR;
> -       config_writew(socket, CB_BRIDGE_CONTROL, bridge_ctrl);
> -
>         if (request_irq(socket->cb_irq, yenta_probe_handler, SA_SHIRQ, "yenta", socket)) {
>                 printk(KERN_WARNING "Yenta: request_irq() in yenta_probe_cb_irq() failed!\n");
>                 return -1;
> @@ -841,6 +831,7 @@
>         cb_writel(socket, CB_SOCKET_EVENT, -1);
>         exca_readb(socket, I365_CSC);
> 
> +       msleep(50);
>         free_irq(socket->cb_irq, socket);
> 
>         return (int) socket->probe_status;
> @@ -856,7 +847,10 @@
>         socket->socket.features |= SS_CAP_PAGE_REGS | SS_CAP_PCCARD | SS_CAP_CARDBUS;
>         socket->socket.map_size = 0x1000;
>         socket->socket.pci_irq = socket->cb_irq;
> -       socket->socket.irq_mask = yenta_probe_irq(socket, isa_irq_mask);
> +       if (isa_probe)
> +               socket->socket.irq_mask = yenta_probe_irq(socket, isa_irq_mask);
> +       else
> +               socket->socket.irq_mask = 0;
>         socket->socket.cb_dev = socket->dev;
> 
>         printk(KERN_INFO "Yenta: ISA IRQ mask 0x%04x, PCI irq %d\n",
> @@ -996,6 +990,7 @@
>         }
> 
>         /* Figure out what the dang thing can do for the PCMCIA layer... */
> +       yenta_interrogate(socket);
>         yenta_get_socket_capabilities(socket, isa_interrupts);
>         printk(KERN_INFO "Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE));
> 
> 
> _______________________________________________
> Linux PCMCIA reimplementation list
> http://lists.infradead.org/mailman/listinfo/linux-pcmcia
> 


-- 
Mike Cumings
-------------- next part --------------
A non-text attachment was scrubbed...
Name: trouble.dmesg
Type: application/octet-stream
Size: 9017 bytes
Desc: not available
Url : http://lists.infradead.org/pipermail/linux-pcmcia/attachments/20050510/5dc5c8fa/trouble-0005.obj
-------------- next part --------------
A non-text attachment was scrubbed...
Name: trouble.interrupts
Type: application/octet-stream
Size: 415 bytes
Desc: not available
Url : http://lists.infradead.org/pipermail/linux-pcmcia/attachments/20050510/5dc5c8fa/trouble-0006.obj
-------------- next part --------------
A non-text attachment was scrubbed...
Name: trouble.iomem
Type: application/octet-stream
Size: 844 bytes
Desc: not available
Url : http://lists.infradead.org/pipermail/linux-pcmcia/attachments/20050510/5dc5c8fa/trouble-0007.obj
-------------- next part --------------
A non-text attachment was scrubbed...
Name: trouble.lspci
Type: application/octet-stream
Size: 959 bytes
Desc: not available
Url : http://lists.infradead.org/pipermail/linux-pcmcia/attachments/20050510/5dc5c8fa/trouble-0008.obj
-------------- next part --------------
A non-text attachment was scrubbed...
Name: trouble.lspci-vvvn
Type: application/octet-stream
Size: 6130 bytes
Desc: not available
Url : http://lists.infradead.org/pipermail/linux-pcmcia/attachments/20050510/5dc5c8fa/trouble-0009.obj


More information about the linux-pcmcia mailing list