Date: Tue, 16 Jul 1996 21:55:11 +0200 (MET DST) From: Stefan Esser <se@zpr.uni-koeln.de> To: current@freebsd.org Subject: Lance PCI driver (please test) Message-ID: <199607161955.VAA00934@x14.mi.uni-koeln.de>
next in thread | raw e-mail | index | archive | help
Well, I've finished my patches to the FreeBSD Lance driver (lnc) some time ago, but it seems I have no way of verifying that they do not break support of the non-PCI cards, nor that they do indeed work with the PCI versions ... (since I don't have access to any Lance controller at all) I sent the diffs to Paul Richards (the author of the lnc driver) for review, but he couldn't test them on a -current system. (They are not compatible with -stable, since some kernel conventions changed and the code requires the new interface. If the driver works under -current and there is sufficient interest, then I'll finish the nearly complete back-port to -stable.) Paul Richards gave me permission to check them in, if they seem to work on other people's systems. Now, I'm asking you all, who are running FreeBSD-current and who use the lnc driver, to let me know if it breaks on your system. Please give it a try, whether you have the ISA or or PCI version, since I'll commit the changes after waiting a few more days, if I do not get a single negative reply within that time! If you are the owner of a PCI Lance: The PCI card will be detected as "lnc1" (if all goes well :), since "lnc0" is reserved for the ISA version, and the ISA probe occurs after the PCI probe. Please give these patches a try! Regards, STefan Index: /sys/conf/files =================================================================== RCS file: /usr/cvs/src/sys/conf/files,v retrieving revision 1.71 diff -C2 -r1.71 files *** files 1996/06/18 05:19:45 1.71 --- files 1996/07/01 11:23:57 *************** *** 297,300 **** --- 297,301 ---- pci/if_ed_p.c optional ed device-driver pci/if_fxp.c optional fxp device-driver + pci/if_lnc_p.c optional lnc device-driver pci/if_vx.c optional vx device-driver pci/ncr.c optional ncr device-driver Index: /sys/i386/isa/if_lnc.c =================================================================== RCS file: /usr/cvs/src/sys/i386/isa/if_lnc.c,v retrieving revision 1.23 diff -C2 -r1.23 if_lnc.c *** if_lnc.c 1996/06/25 20:30:25 1.23 --- if_lnc.c 1996/07/01 12:27:10 *************** *** 61,64 **** --- 61,65 ---- */ + #include "pci.h" #include "lnc.h" #if NLNC > 0 *************** *** 132,143 **** static void lnc_setladrf __P((struct lnc_softc *sc)); #endif ! static void lnc_stop __P((int unit)); ! static void lnc_reset __P((int unit)); static void lnc_free_mbufs __P((struct lnc_softc *sc)); static int alloc_mbuf_cluster __P((struct lnc_softc *sc, struct host_ring_entry *desc)); static struct mbuf *chain_mbufs __P((struct lnc_softc *sc, int start_of_packet, int pkt_len)); static struct mbuf *mbuf_packet __P((struct lnc_softc *sc, int start_of_packet, int pkt_len)); ! static void lnc_rint __P((int unit)); ! static void lnc_tint __P((int unit)); static int lnc_probe __P((struct isa_device *isa_dev)); static int ne2100_probe __P((struct isa_device *isa_dev)); --- 133,144 ---- static void lnc_setladrf __P((struct lnc_softc *sc)); #endif ! static void lnc_stop __P((struct lnc_softc *sc)); ! static void lnc_reset __P((struct lnc_softc *sc)); static void lnc_free_mbufs __P((struct lnc_softc *sc)); static int alloc_mbuf_cluster __P((struct lnc_softc *sc, struct host_ring_entry *desc)); static struct mbuf *chain_mbufs __P((struct lnc_softc *sc, int start_of_packet, int pkt_len)); static struct mbuf *mbuf_packet __P((struct lnc_softc *sc, int start_of_packet, int pkt_len)); ! static void lnc_rint __P((struct lnc_softc *sc)); ! static void lnc_tint __P((struct lnc_softc *sc)); static int lnc_probe __P((struct isa_device *isa_dev)); static int ne2100_probe __P((struct isa_device *isa_dev)); *************** *** 147,152 **** static int lance_probe __P((int unit)); static int pcnet_probe __P((int unit)); ! static int lnc_attach __P((struct isa_device *isa_dev)); ! static void lnc_init __P((int unit)); static int mbuf_to_buffer __P((struct mbuf *m, char *buffer)); static struct mbuf *chain_to_cluster __P((struct mbuf *m)); --- 148,154 ---- static int lance_probe __P((int unit)); static int pcnet_probe __P((int unit)); ! static int lnc_attach __P((struct lnc_softc *sc, int unit)); ! static int lnc_attach_isa __P((struct isa_device *isa_dev)); ! static void lnc_init __P((struct lnc_softc *sc)); static int mbuf_to_buffer __P((struct mbuf *m, char *buffer)); static struct mbuf *chain_to_cluster __P((struct mbuf *m)); *************** *** 155,163 **** static void lnc_watchdog __P((struct ifnet *ifp)); #ifdef DEBUG ! static void lnc_dump_state __P((int unit)); static void mbuf_dump_chain __P((struct mbuf *m)); #endif ! struct isa_driver lncdriver = {lnc_probe, lnc_attach, "lnc"}; static struct kern_devconf kdc_lnc = { --- 157,170 ---- static void lnc_watchdog __P((struct ifnet *ifp)); #ifdef DEBUG ! static void lnc_dump_state __P((struct lnc_softc *sc)); static void mbuf_dump_chain __P((struct mbuf *m)); #endif ! #if NPCI > 0 ! void *lnc_attach_ne2100_pci __P((int unit, unsigned iobase)); ! #endif ! void lncintr_sc __P((struct lnc_softc *sc)); ! ! struct isa_driver lncdriver = {lnc_probe, lnc_attach_isa, "lnc"}; static struct kern_devconf kdc_lnc = { *************** *** 173,187 **** static inline void ! write_csr(int unit, u_short port, u_short val) { ! outw(lnc_softc[unit].rap, port); ! outw(lnc_softc[unit].rdp, val); } static inline u_short ! read_csr(int unit, u_short port) { ! outw(lnc_softc[unit].rap, port); ! return (inw(lnc_softc[unit].rdp)); } --- 180,194 ---- static inline void ! write_csr(struct lnc_softc *sc, u_short port, u_short val) { ! outw(sc->rap, port); ! outw(sc->rdp, val); } static inline u_short ! read_csr(struct lnc_softc *sc, u_short port) { ! outw(sc->rap, port); ! return (inw(sc->rdp)); } *************** *** 222,225 **** --- 229,235 ---- break; case PCnet_PCI: + /* + * XXX - This should never be the case ... + */ kdc->kdc_description = "PCnet-PCI Ethernet controller"; break; *************** *** 306,318 **** static void ! lnc_stop(int unit) { ! write_csr(unit, CSR0, STOP); } static void ! lnc_reset(int unit) { ! lnc_init(unit); } --- 316,328 ---- static void ! lnc_stop(struct lnc_softc *sc) { ! write_csr(sc, CSR0, STOP); } static void ! lnc_reset(struct lnc_softc *sc) { ! lnc_init(sc); } *************** *** 482,488 **** static inline void ! lnc_rint(int unit) { ! register struct lnc_softc *sc = &lnc_softc[unit]; struct host_ring_entry *next, *start; int start_of_packet; --- 492,498 ---- static inline void ! lnc_rint(struct lnc_softc *sc) { ! int unit = sc->arpcom.ac_if.if_unit; struct host_ring_entry *next, *start; int start_of_packet; *************** *** 541,545 **** if (flags & STP) { log(LOG_ERR, "lnc%d: Start of packet found before end of previous in receive ring -- Resetting\n", unit); ! lnc_reset(unit); return; } --- 551,555 ---- if (flags & STP) { log(LOG_ERR, "lnc%d: Start of packet found before end of previous in receive ring -- Resetting\n", unit); ! lnc_reset(sc); return; } *************** *** 554,558 **** } else { log(LOG_ERR, "lnc%d: End of received packet not found-- Resetting\n", unit); ! lnc_reset(unit); return; } --- 564,568 ---- } else { log(LOG_ERR, "lnc%d: End of received packet not found-- Resetting\n", unit); ! lnc_reset(sc); return; } *************** *** 672,678 **** static inline void ! lnc_tint(int unit) { ! register struct lnc_softc *sc = &lnc_softc[unit]; struct host_ring_entry *next, *start; int start_of_packet; --- 682,688 ---- static inline void ! lnc_tint(struct lnc_softc *sc) { ! int unit = sc->arpcom.ac_if.if_unit; struct host_ring_entry *next, *start; int start_of_packet; *************** *** 743,747 **** if (next->md->md1 & STP) { log(LOG_ERR, "lnc%d: Start of packet found before end of previous in transmit ring -- Resetting\n", unit); ! lnc_reset(unit); return; } --- 753,757 ---- if (next->md->md1 & STP) { log(LOG_ERR, "lnc%d: Start of packet found before end of previous in transmit ring -- Resetting\n", unit); ! lnc_reset(sc); return; } *************** *** 756,760 **** } else { log(LOG_ERR, "lnc%d: End of transmitted packet not found -- Resetting\n", unit); ! lnc_reset(unit); return; } --- 766,770 ---- } else { log(LOG_ERR, "lnc%d: End of transmitted packet not found -- Resetting\n", unit); ! lnc_reset(sc); return; } *************** *** 815,819 **** } else log(LOG_ERR, "lnc%d: Transmit underflow error -- Resetting\n", unit); ! lnc_reset(unit); return; } --- 825,829 ---- } else log(LOG_ERR, "lnc%d: Transmit underflow error -- Resetting\n", unit); ! lnc_reset(sc); return; } *************** *** 1058,1064 **** lance_probe(int unit) { ! write_csr(unit, CSR0, STOP); ! if ((inw(lnc_softc[unit].rdp) & STOP) && !(read_csr(unit, CSR3))) { /* * Check to see if it's a C-LANCE. For the LANCE the INEA bit --- 1068,1076 ---- lance_probe(int unit) { ! struct lnc_softc *sc = &lnc_softc[unit]; ! ! write_csr(sc, CSR0, STOP); ! if ((inw(sc->rdp) & STOP) && !(read_csr(sc, CSR3))) { /* * Check to see if it's a C-LANCE. For the LANCE the INEA bit *************** *** 1066,1071 **** * removed for the C-LANCE. */ ! write_csr(unit, CSR0, INEA); ! if (read_csr(unit, CSR0) & INEA) return (C_LANCE); else --- 1078,1083 ---- * removed for the C-LANCE. */ ! write_csr(sc, CSR0, INEA); ! if (read_csr(sc, CSR0) & INEA) return (C_LANCE); else *************** *** 1078,1081 **** --- 1090,1095 ---- pcnet_probe(int unit) { + struct lnc_softc *sc = &lnc_softc[unit]; + u_long chip_id; int type; *************** *** 1089,1095 **** if (type = lance_probe(unit)) { ! chip_id = read_csr(unit, CSR89); chip_id <<= 16; ! chip_id |= read_csr(unit, CSR88); if (chip_id & AMD_MASK) { chip_id >>= 12; --- 1103,1109 ---- if (type = lance_probe(unit)) { ! chip_id = read_csr(sc, CSR89); chip_id <<= 16; ! chip_id |= read_csr(sc, CSR88); if (chip_id & AMD_MASK) { chip_id >>= 12; *************** *** 1102,1106 **** return (PCnet_32); case Am79C970: ! return (PCnet_PCI); default: break; --- 1116,1120 ---- return (PCnet_32); case Am79C970: ! return (0); default: break; *************** *** 1112,1118 **** static int ! lnc_attach(struct isa_device * isa_dev) { - struct lnc_softc *sc = &lnc_softc[isa_dev->id_unit]; int lnc_mem_size; --- 1126,1131 ---- static int ! lnc_attach(struct lnc_softc *sc, int unit) { int lnc_mem_size; *************** *** 1145,1162 **** if (!sc->recv_ring) { ! log(LOG_ERR, "lnc%d: Couldn't allocate memory for NIC\n", isa_dev->id_unit); return (0); /* XXX -- attach failed -- not tested in * calling routines */ } if ((sc->nic.mem_mode != SHMEM) && (kvtop(sc->recv_ring) > 0x1000000)) { ! log(LOG_ERR, "lnc%d: Memory allocated above 16Mb limit\n", isa_dev->id_unit); ! return (0); } - if ((sc->nic.mem_mode != SHMEM) && - (sc->nic.ic != PCnet_32) && - (sc->nic.ic != PCnet_PCI)) - isa_dmacascade(isa_dev->id_drq); - /* Set default mode */ sc->nic.mode = NORMAL; --- 1158,1175 ---- if (!sc->recv_ring) { ! log(LOG_ERR, "lnc%d: Couldn't allocate memory for NIC\n", unit); return (0); /* XXX -- attach failed -- not tested in * calling routines */ } + /* + * XXX - Shouldn't this be skipped for the EISA and PCI versions ??? + * Print the message but do not return for the PCnet_PCI ! + */ if ((sc->nic.mem_mode != SHMEM) && (kvtop(sc->recv_ring) > 0x1000000)) { ! log(LOG_ERR, "lnc%d: Memory allocated above 16Mb limit\n", unit); ! if (sc->nic.ic != PCnet_PCI) ! return (0); } /* Set default mode */ sc->nic.mode = NORMAL; *************** *** 1166,1170 **** sc->arpcom.ac_if.if_softc = sc; sc->arpcom.ac_if.if_name = lncdriver.name; ! sc->arpcom.ac_if.if_unit = isa_dev->id_unit; sc->arpcom.ac_if.if_mtu = ETHERMTU; sc->arpcom.ac_if.if_flags = IFF_BROADCAST | IFF_SIMPLEX; --- 1179,1183 ---- sc->arpcom.ac_if.if_softc = sc; sc->arpcom.ac_if.if_name = lncdriver.name; ! sc->arpcom.ac_if.if_unit = unit; sc->arpcom.ac_if.if_mtu = ETHERMTU; sc->arpcom.ac_if.if_flags = IFF_BROADCAST | IFF_SIMPLEX; *************** *** 1186,1192 **** sc->kdc.kdc_state = DC_IDLE; printf("lnc%d: %s, address %6D\n", ! isa_dev->id_unit, ! sc->kdc.kdc_description, sc->arpcom.ac_enaddr, ":"); --- 1199,1208 ---- sc->kdc.kdc_state = DC_IDLE; + if (sc->kdc.kdc_description == NULL) + sc->kdc.kdc_description = "Lance Ethernet controller"; + printf("lnc%d: %s, address %6D\n", ! unit, ! sc->kdc.kdc_description, sc->arpcom.ac_enaddr, ":"); *************** *** 1198,1205 **** } ! static void ! lnc_init(int unit) { struct lnc_softc *sc = &lnc_softc[unit]; int s, i; char *lnc_mem; --- 1214,1281 ---- } ! static int ! lnc_attach_isa(struct isa_device * isa_dev) { + int unit = isa_dev->id_unit; struct lnc_softc *sc = &lnc_softc[unit]; + + int result = lnc_attach (sc, unit); + if (result == 0) + return (0); + /* + * XXX - is it safe to call isa_dmacascade() after if_attach() + * and ether_ifattach() have been called in lnc_attach() ??? + */ + if ((sc->nic.mem_mode != SHMEM) && + (sc->nic.ic != PCnet_32) && + (sc->nic.ic != PCnet_PCI)) + isa_dmacascade(isa_dev->id_drq); + + return result; + } + + #if NPCI > 0 + void * + lnc_attach_ne2100_pci(int unit, unsigned iobase) + { + struct lnc_softc *sc = malloc(sizeof *sc, M_DEVBUF, M_NOWAIT); + + if (!sc) + return sc; + + bzero (sc, sizeof *sc); + + /* + * Copied from ne2100_probe() + */ + sc->rap = iobase + PCNET_RAP; + sc->rdp = iobase + PCNET_RDP; + + sc->nic.ic = PCnet_PCI; + sc->nic.ident = NE2100; + sc->nic.mem_mode = DMA_FIXED; + + /* XXX - For now just use the defines */ + sc->nrdre = NRDRE; + sc->ntdre = NTDRE; + + /* Extract MAC address from PROM */ + { + int i; + for (i = 0; i < ETHER_ADDR_LEN; i++) + sc->arpcom.ac_enaddr[i] = inb(iobase + i); + } + + if (lnc_attach(sc, unit) == 0) { + free(sc, M_DEVBUF); + return NULL; + } + return sc; + } + #endif + + static void + lnc_init(struct lnc_softc *sc) + { int s, i; char *lnc_mem; *************** *** 1213,1217 **** s = splimp(); ! lnc_stop(unit); sc->arpcom.ac_if.if_flags |= IFF_BROADCAST | IFF_SIMPLEX; /* XXX??? */ --- 1289,1293 ---- s = splimp(); ! lnc_stop(sc); sc->arpcom.ac_if.if_flags |= IFF_BROADCAST | IFF_SIMPLEX; /* XXX??? */ *************** *** 1327,1332 **** /* Give the LANCE the physical address of the initialisation block */ ! write_csr(unit, CSR1, kvtop(sc->init_block)); ! write_csr(unit, CSR2, (kvtop(sc->init_block) >> 16) & 0xff); /* --- 1403,1408 ---- /* Give the LANCE the physical address of the initialisation block */ ! write_csr(sc, CSR1, kvtop(sc->init_block)); ! write_csr(sc, CSR2, (kvtop(sc->init_block) >> 16) & 0xff); /* *************** *** 1338,1348 **** */ ! write_csr(unit, CSR3, 0); /* Let's see if it starts */ ! write_csr(unit, CSR0, INIT); for (i = 0; i < 1000; i++) ! if (read_csr(unit, CSR0) & IDON) break; --- 1414,1424 ---- */ ! write_csr(sc, CSR3, 0); /* Let's see if it starts */ ! write_csr(sc, CSR0, INIT); for (i = 0; i < 1000; i++) ! if (read_csr(sc, CSR0) & IDON) break; *************** *** 1354,1368 **** */ ! if (read_csr(unit, CSR0) & IDON) { /* * Enable interrupts, start the LANCE, mark the interface as * running and transmit any pending packets. */ ! write_csr(unit, CSR0, STRT | INEA); sc->arpcom.ac_if.if_flags |= IFF_RUNNING; sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE; lnc_start(&sc->arpcom.ac_if); } else ! log(LOG_ERR, "lnc%d: Initialisation failed\n", unit); splx(s); --- 1430,1445 ---- */ ! if (read_csr(sc, CSR0) & IDON) { /* * Enable interrupts, start the LANCE, mark the interface as * running and transmit any pending packets. */ ! write_csr(sc, CSR0, STRT | INEA); sc->arpcom.ac_if.if_flags |= IFF_RUNNING; sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE; lnc_start(&sc->arpcom.ac_if); } else ! log(LOG_ERR, "lnc%d: Initialisation failed\n", ! sc->arpcom.ac_if.if_unit); splx(s); *************** *** 1391,1397 **** void ! lncintr(int unit) { ! struct lnc_softc *sc = &lnc_softc[unit]; u_short csr0; --- 1468,1474 ---- void ! lncintr_sc(struct lnc_softc *sc) { ! int unit = sc->arpcom.ac_if.if_unit; u_short csr0; *************** *** 1433,1437 **** log(LOG_ERR, "lnc%d: Memory error -- Resetting\n", unit); LNCSTATS(merr) ! lnc_reset(unit); continue; } --- 1510,1514 ---- log(LOG_ERR, "lnc%d: Memory error -- Resetting\n", unit); LNCSTATS(merr) ! lnc_reset(sc); continue; } *************** *** 1439,1448 **** if (csr0 & RINT) { LNCSTATS(rint) ! lnc_rint(unit); } if (csr0 & TINT) { LNCSTATS(tint) sc->arpcom.ac_if.if_timer = 0; ! lnc_tint(unit); } --- 1516,1525 ---- if (csr0 & RINT) { LNCSTATS(rint) ! lnc_rint(sc); } if (csr0 & TINT) { LNCSTATS(tint) sc->arpcom.ac_if.if_timer = 0; ! lnc_tint(sc); } *************** *** 1457,1460 **** --- 1534,1544 ---- } + void + lncintr(int unit) + { + struct lnc_softc *sc = &lnc_softc[unit]; + lncintr_sc (sc); + } + *************** *** 1543,1547 **** if (!(head = chain_to_cluster(head))) { log(LOG_ERR, "lnc%d: Couldn't get mbuf for transmit packet -- Resetting \n ",ifp->if_unit); ! lnc_reset(ifp->if_unit); return; } --- 1627,1631 ---- if (!(head = chain_to_cluster(head))) { log(LOG_ERR, "lnc%d: Couldn't get mbuf for transmit packet -- Resetting \n ",ifp->if_unit); ! lnc_reset(sc); return; } *************** *** 1677,1686 **** #ifdef INET case AF_INET: ! lnc_init(ifp->if_unit); arp_ifinit((struct arpcom *)ifp, ifa); break; #endif default: ! lnc_init(ifp->if_unit); break; } --- 1761,1770 ---- #ifdef INET case AF_INET: ! lnc_init(sc); arp_ifinit((struct arpcom *)ifp, ifa); break; #endif default: ! lnc_init(sc); break; } *************** *** 1697,1705 **** if (!(sc->nic.mode & PROM)) { sc->nic.mode |= PROM; ! lnc_init(ifp->if_unit); } } else if (sc->nic.mode & PROM) { sc->nic.mode &= ~PROM; ! lnc_init(ifp->if_unit); } if ((ifp->if_flags & IFF_UP) == 0 && --- 1781,1789 ---- if (!(sc->nic.mode & PROM)) { sc->nic.mode |= PROM; ! lnc_init(sc); } } else if (sc->nic.mode & PROM) { sc->nic.mode &= ~PROM; ! lnc_init(sc); } if ((ifp->if_flags & IFF_UP) == 0 && *************** *** 1709,1713 **** * then stop it. */ ! lnc_stop(ifp->if_unit); ifp->if_flags &= ~IFF_RUNNING; } else if ((ifp->if_flags & IFF_UP) != 0 && --- 1793,1797 ---- * then stop it. */ ! lnc_stop(sc); ifp->if_flags &= ~IFF_RUNNING; } else if ((ifp->if_flags & IFF_UP) != 0 && *************** *** 1717,1721 **** * start it. */ ! lnc_init(ifp->if_unit); } sc->kdc.kdc_state = --- 1801,1805 ---- * start it. */ ! lnc_init(sc); } sc->kdc.kdc_state = *************** *** 1757,1768 **** log(LOG_ERR, "lnc%d: Device timeout -- Resetting\n", ifp->if_unit); ifp->if_oerrors++; ! lnc_reset(ifp->if_unit); } #ifdef DEBUG static void ! lnc_dump_state(int unit) { - struct lnc_softc *sc = &lnc_softc[unit]; int i; --- 1841,1851 ---- log(LOG_ERR, "lnc%d: Device timeout -- Resetting\n", ifp->if_unit); ifp->if_oerrors++; ! lnc_reset(ifp->if_softc); } #ifdef DEBUG static void ! lnc_dump_state( struct lnc_softc *sc) { int i; *** /dev/null Sat Jun 29 02:05:26 1996 --- /sys/pci/if_lnc_p.c Mon Jul 1 13:31:53 1996 *************** *** 0 **** --- 1,97 ---- + /* + * + * Copyright (c) 1996 Stefan Esser <se@freebsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice immediately at the beginning of the file, without modification, + * this list of conditions, and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Absolutely no warranty of function or purpose is made by the author + * Stefan Esser. + * 4. Modifications may be freely made to this file if the above conditions + * are met. + * + * $Id:$ + */ + + #include "pci.h" + #if NPCI > 0 + + #include <sys/param.h> + #include <sys/systm.h> + #include <sys/malloc.h> + #include <sys/kernel.h> + #include <pci/pcireg.h> + #include <pci/pcivar.h> + #ifdef PC98 + #include <pc98/pc98/pc98_device.h> + #else + #include <i386/isa/isa_device.h> + #endif + + #include "lnc.h" + + #define PCI_DEVICE_ID_PCNet_PCI 0x20001022 + + extern void *lnc_attach_ne2100_pci __P((int unit, unsigned iobase)); + + static char* lnc_pci_probe __P((pcici_t tag, pcidi_t type)); + static void lnc_pci_attach __P((pcici_t config_id, int unit)); + + static u_long lnc_pci_count = NLNC; + + static struct pci_device lnc_pci_driver = { + "lnc", + lnc_pci_probe, + lnc_pci_attach, + &lnc_pci_count, + NULL + }; + + DATA_SET (pcidevice_set, lnc_pci_driver); + + static char* + lnc_pci_probe (pcici_t tag, pcidi_t type) + { + switch(type) { + case PCI_DEVICE_ID_PCNet_PCI: + return ("PCNet/PCI Ethernet adapter"); + break; + default: + break; + } + return (0); + } + + void lncintr_sc (void*); + + static void + lnc_pci_attach(config_id, unit) + pcici_t config_id; + int unit; + { + unsigned iobase; + void *lnc; /* device specific data for interrupt handler ... */ + + iobase = pci_conf_read(config_id, PCI_MAP_REG_START) & ~PCI_MAP_IO; + + lnc = lnc_attach_ne2100_pci(unit, iobase); + if (!lnc) + return; + + if(!(pci_map_int(config_id, lncintr_sc, (void *)lnc, &net_imask))) { + free (lnc, M_DEVBUF); + return; + } + + return; + } + + #endif /* NPCI > 0 */ +
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199607161955.VAA00934>