NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kern/37723: ne* AX88190 Fast Ethernet 16-bit PC Card: where did the card go? problem



On Sun, Mar 09, 2008 at 08:15:43PM +0000, David Holland wrote:
 > The two extra tests that might apply are (1) the one marked "XXX This
 > is highly bogus" at line 675 of if_ne_pcmcia.c, and also (2) the
 > prefix of the ethernet address.

There is some (not very large) chance that the following patch, which
reverts version 1.135 of if_ne_pcmcia.c, will help. But even if it
doesn't, the extra messages I added to it should help figure out
what's going on. Do a verbose boot with the patch and look for any of
the new messages.

If it tells you "ne_pcmcia_ax88190_set_iobase: failed." then the
problem is likely the same as kern/32938 (also see kern/27299). If on
the other hand it complains about an unexpected address prefix, the
problem can probably be solved by fiddling with the table of devices.
(If it prints neither and also still doesn't work, then I have no idea
what's going on.)

Index: if_ne_pcmcia.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pcmcia/if_ne_pcmcia.c,v
retrieving revision 1.154
diff -u -r1.154 if_ne_pcmcia.c
--- if_ne_pcmcia.c      5 Apr 2008 21:31:23 -0000       1.154
+++ if_ne_pcmcia.c      13 Apr 2008 05:52:20 -0000
@@ -87,6 +87,7 @@
            u_int8_t [ETHER_ADDR_LEN]);
 u_int8_t *ne_pcmcia_dl10019_get_enaddr(struct ne_pcmcia_softc *,
            u_int8_t [ETHER_ADDR_LEN]);
+int ne_pcmcia_ax88190_set_iobase(struct ne_pcmcia_softc *);
 
 CFATTACH_DECL_NEW(ne_pcmcia, sizeof(struct ne_pcmcia_softc),
     ne_pcmcia_match, ne_pcmcia_attach, ne_pcmcia_detach, dp8390_activate);
@@ -672,8 +673,7 @@
        if ((ne_dev->flags & NE2000DVF_AX88190) != 0) {
                u_int8_t test;
 
-               /* XXX This is highly bogus. */
-               if ((pa->pf->ccr_mask & (1 << PCMCIA_CCR_IOBASE0)) == 0) {
+               if (ne_pcmcia_ax88190_set_iobase(psc)) {
                        ++i;
                        goto again;
                }
@@ -704,6 +704,14 @@
                    enaddr[1] != ne_dev->enet_vendor[1] ||
                    enaddr[2] != ne_dev->enet_vendor[2]) {
                        ++i;
+                       aprint_verbose_dev(self,
+                           "Unexpected address prefix: "
+                           "got %02x:%02x:%02x, expected %02x:%02x:%02x\n",
+                           enaddr[0], enaddr[1], enaddr[2],
+                           ne_dev->enet_vendor[0],
+                           ne_dev->enet_vendor[1],
+                           ne_dev->enet_vendor[2]);
+                                          
                        goto again;
                }
        }
@@ -771,6 +779,7 @@
 ne_pcmcia_enable(struct dp8390_softc *dsc)
 {
        struct ne_pcmcia_softc *psc = (struct ne_pcmcia_softc *)dsc;
+       struct ne2000_softc *nsc = &psc->sc_ne2000;
        int error;
 
        /* set up the interrupt */
@@ -783,6 +792,18 @@
        if (error) {
                pcmcia_intr_disestablish(psc->sc_pf, psc->sc_ih);
                psc->sc_ih = 0;
+               return (error);
+       }
+
+       if (nsc->sc_type == NE2000_TYPE_AX88190 ||
+           nsc->sc_type == NE2000_TYPE_AX88790) {
+               error = ne_pcmcia_ax88190_set_iobase(psc);
+               if (error) {
+                       pcmcia_function_disable(psc->sc_pf);
+                       pcmcia_intr_disestablish(psc->sc_pf, psc->sc_ih);
+                       psc->sc_ih = 0;
+                       return (error);
+               }
        }
 
        return (error);
@@ -854,3 +875,29 @@
 #undef PAR0
        return (myea);
 }
+
+int
+ne_pcmcia_ax88190_set_iobase(struct ne_pcmcia_softc *psc)
+{
+       struct pcmcia_function *pf = psc->sc_pf;
+       bus_addr_t iobase = pf->cfe->iospace[0].handle.addr;
+       bus_addr_t oldiobase, newiobase;
+
+       oldiobase = (pcmcia_ccr_read(pf, PCMCIA_CCR_IOBASE0) << 0) |
+                   (pcmcia_ccr_read(pf, PCMCIA_CCR_IOBASE1) << 8);
+       pcmcia_ccr_write(pf, PCMCIA_CCR_IOBASE0, (iobase >> 0) & 0xff);
+       pcmcia_ccr_write(pf, PCMCIA_CCR_IOBASE1, (iobase >> 8) & 0xff);
+       newiobase = (pcmcia_ccr_read(pf, PCMCIA_CCR_IOBASE0) << 0) |
+                   (pcmcia_ccr_read(pf, PCMCIA_CCR_IOBASE1) << 8);
+
+       aprint_verbose_dev(psc->sc_ne2000.sc_dp8390.sc_dev,
+           "iobase: found 0x%lx, wanted 0x%lx, got 0x%lx\n",
+           (unsigned long)oldiobase, (unsigned long)iobase,
+           (unsigned long)newiobase);
+
+       if (oldiobase == iobase || oldiobase != newiobase)
+               return (0);
+       aprint_verbose_dev(psc->sc_ne2000.sc_dp8390.sc_dev,
+           "ne_pcmcia_ax88190_set_iobase: failed.\n");
+       return (EIO);
+}

-- 
David A. Holland
dholland%netbsd.org@localhost


Home | Main Index | Thread Index | Old Index