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>
