Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 25 Mar 2000 17:17:33 -0800 (PST)
From:      brooks@one-eyed-alien.net
To:        FreeBSD-gnats-submit@freebsd.org
Cc:        semen@iclub.nsu.ru
Subject:   kern/17601: newbus patch for if_tx
Message-ID:  <200003260117.RAA00496@minya.sea.one-eyed-alien.net>

next in thread | raw e-mail | index | archive | help

>Number:         17601
>Category:       kern
>Synopsis:       newbus patch for if_tx
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Sat Mar 25 17:20:01 PST 2000
>Closed-Date:
>Last-Modified:
>Originator:     Brooks Davis
>Release:        FreeBSD 5.0-CURRENT i386
>Organization:
The Aerospace Corporation
>Environment:

FreeBSD minya 5.0-CURRENT FreeBSD 5.0-CURRENT #6: Sat Mar 25 16:13:12 PST 2000     root@minya:/usr/src/sys/compile/MINYA  i386

>Description:

The tx driver needs newbus attachment code.  This patch provides it.

>How-To-Repeat:

Try compiling with tx enabled without COMPAT_OLDPCI.

>Fix:

The following match adds newbus attachment, unconditionalized bpf,
bus_space support and use of device_printf.  It removes the unused
iospace support.  It works for me, but this is my first attempt at
driver hacking so review before comitting would be wise. ;-)  I'm not
sure if it will work on an alpha or not since I don't have one.  If
someone wants to attack that problem I could probably loan them a card
as there should be a pile of them at work that got replaced with fxp's.
The detach function should be better, but I don't really know what I
should be freeing.  It should be a bit more friendly then the old
at_shutdown once was, but it would probably leak resources if it were
hot plugged, not that we support that yet.

The patch has been tested on my laptop with docking station running 5.0.
If you remove the bpfdetach call from epic_freebsd_detach it compiles on
a 4.0 system as well.  I haven't tested it under 4.0 as the only machine
I have with a tx card is my laptop's docking station running -current.

This patch is closly based on patches made to the fxp driver.
Specificaly:

1.67	new-bus
1.75	if_ naming
1.76	unconditional bpf support
1.77	bus_space

Index: if_tx.c
===================================================================
RCS file: /home/ncvs/src/sys/pci/if_tx.c,v
retrieving revision 1.34
diff -u -r1.34 if_tx.c
--- if_tx.c	1999/12/21 11:14:10	1.34
+++ if_tx.c	2000/03/26 00:58:25
@@ -43,7 +43,6 @@
 
 /* We should define compile time options before if_txvar.h included */
 /*#define	EPIC_NOIFMEDIA	1*/
-/*#define	EPIC_USEIOSPACE	1*/
 #define	EARLY_RX	1
 /*#define	EPIC_DEBUG	1*/
 
@@ -65,7 +64,11 @@
 	  } \
 	}
 
+#if defined(__FreeBSD__)
+#define NBPF 1
+#else
 #include "bpf.h"
+#endif
 #include "opt_bdg.h"
 
 #include <sys/param.h>
@@ -123,6 +126,11 @@
 
 #include <dev/pci/if_txvar.h>
 #else /* __FreeBSD__ */
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <machine/resource.h>
+
 #include <sys/eventhandler.h>
 #include <net/if_mib.h>
 #include <netinet/in.h>
@@ -132,6 +140,7 @@
 #include <machine/clock.h>
 
 #include <pci/pcivar.h>
+#include <pci/pcireg.h>
 #include <pci/if_txvar.h>
 
 #ifdef BRIDGE
@@ -375,70 +384,41 @@
 #else /* __FreeBSD__ */
 /* -----------------------------FreeBSD------------------------------------- */
 
+/*
 static const char* epic_freebsd_probe __P((pcici_t, pcidi_t));
 static void epic_freebsd_attach __P((pcici_t, int));
-static void epic_shutdown __P((void *, int));
-
-/* Global variables */
-static u_long epic_pci_count;
-static struct pci_device txdevice = { 
-	"tx",
-	epic_freebsd_probe,
-	epic_freebsd_attach,
-	&epic_pci_count,
-	NULL
-};
-
-/* Append this driver to pci drivers list */
-COMPAT_PCI_DRIVER (tx, txdevice);
+static void epic_shutdown __P((void *));
+*/
 
 /* Synopsis: Check if device id corresponds with SMC83C170 id.  */
-static const char*
-epic_freebsd_probe(
-    pcici_t config_id,
-    pcidi_t device_id)
+static int
+epic_freebsd_probe(device_t dev)
 {
-	if( PCI_VENDORID(device_id) != SMC_VENDORID )
-		return NULL;
-
-	if( PCI_CHIPID(device_id) == CHIPID_83C170 )
-		return "SMC 83c170";
+	if ((pci_get_vendor(dev) == SMC_VENDORID) &&
+	    (pci_get_device(dev) == CHIPID_83C170)) {
+		device_set_desc(dev, "SMC 83c170");
+		return 0;
+	}
 
-	return NULL;
+	return ENXIO;
 }
 
 /*
  * Do FreeBSD-specific attach routine, like map registers, alloc softc
  * structure and etc.
  */
-static void
-epic_freebsd_attach(
-    pcici_t config_id,
-    int unit)
+static int
+epic_freebsd_attach(device_t dev)
 {
 	struct ifnet *ifp;
-	epic_softc_t *sc;
-#if defined(EPIC_USEIOSPACE)
-	u_int32_t iobase;
-#else
-	caddr_t	pmembase;
-#endif
+	epic_softc_t *sc = device_get_softc(dev);
 	u_int32_t command;
 	int i,s,tmp;
+	int rid;
 
-	printf("tx%d",unit);
-
-	/* Allocate memory for softc, hardware descriptors and frag lists */
-	sc = (epic_softc_t *) malloc( sizeof(epic_softc_t), M_DEVBUF, M_NOWAIT);
-	if (sc == NULL)	return;
-
-	/* Preinitialize softc structure */
-    	bzero(sc, sizeof(epic_softc_t));		
-	sc->unit = unit;
-
 	/* Fill ifnet structure */
 	ifp = &sc->sc_if;
-	ifp->if_unit = unit;
+	ifp->if_unit = device_get_unit(dev);
 	ifp->if_name = "tx";
 	ifp->if_softc = sc;
 	ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST;
@@ -449,56 +429,32 @@
 	ifp->if_timer = 0;
 	ifp->if_output = ether_output;
 	ifp->if_snd.ifq_maxlen = TX_RING_SIZE;
-
-	/* Get iobase or membase */
-#if defined(EPIC_USEIOSPACE)
-	command = PCI_CONF_READ(PCI_CFCS);
-	command |= PCI_CFCS_IOEN;
-	PCI_CONF_WRITE(PCI_CFCS, command);
-	command = PCI_CONF_READ(PCI_CFCS);
-
-	if (!(command & PCI_CFCS_IOEN)) {
-		printf(": failed to enable memory mapping!\n");
-		free(sc, M_DEVBUF);
-		return;
-	}
 
-	if (!pci_map_port(config_id, PCI_CBIO,(u_short *) &(sc->iobase))) {
-		printf(": cannot map port\n");
-		free(sc, M_DEVBUF);
-		return;
-	}
-#else
-	command = PCI_CONF_READ(PCI_CFCS);
-	command |= PCI_CFCS_MAEN;
-	PCI_CONF_WRITE(PCI_CFCS, command);
-	command = PCI_CONF_READ(PCI_CFCS);
-
-	if (!(command & PCI_CFCS_MAEN)) {
-		printf(": failed to enable memory mapping!\n");
-		free(sc, M_DEVBUF);
-		return;
+	/* Get membase */
+	command = pci_read_config(dev, PCIR_COMMAND, 2);
+	command |= PCIM_CMD_MEMEN;
+	pci_write_config(dev, PCIR_COMMAND, command, 2);
+
+	rid = PCI_CBMA;
+	sc->mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
+				     0, ~0, 1, RF_ACTIVE);
+	if(!sc->mem) {
+		device_printf(dev, "cannot map memory\n");
+		return ENXIO;
 	}
+	sc->sc_st = rman_get_bustag(sc->mem);
+	sc->sc_sh = rman_get_bushandle(sc->mem);
 
-	if (!pci_map_mem(config_id, PCI_CBMA,(vm_offset_t *) &(sc->csr),(vm_offset_t *) &pmembase)) {
-		printf(": cannot map memory\n"); 
-		free(sc, M_DEVBUF);
-		return;
-	}
-#endif
-
 	/* Do OS independent part, including chip wakeup and reset */
-	if( epic_common_attach(sc) ) return;
+	if( epic_common_attach(sc) ) return ENXIO;
 
 	/* Enable BusMaster'ing */
-	command = PCI_CONF_READ(PCI_CFCS);
-	command |= PCI_CFCS_BMEN;
-	PCI_CONF_WRITE(PCI_CFCS, command);
+	command = pci_read_config(dev, PCIR_COMMAND, 2);
+	command |= PCIM_CMD_BUSMASTEREN;
+	pci_write_config(dev, PCIR_COMMAND, command, 2);
 
 	/* Display ethernet address ,... */
-	printf(": address %02x:%02x:%02x:%02x:%02x:%02x,",
-		sc->sc_macaddr[0],sc->sc_macaddr[1],sc->sc_macaddr[2],
-		sc->sc_macaddr[3],sc->sc_macaddr[4],sc->sc_macaddr[5]);
+	device_printf(dev, "address %6D,", sc->sc_macaddr, ":");
 
 	/* board type and ... */
 	printf(" type ");
@@ -567,39 +523,94 @@
 	s = splimp();
 
 	/* Map interrupt */
-	if( !pci_map_int(config_id, epic_intr, (void*)sc, &net_imask) ) {
-		printf(": couldn't map interrupt\n");
-		free(sc, M_DEVBUF);
-		return;
+	rid = 0;
+	sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
+				     RF_SHAREABLE | RF_ACTIVE);
+	if (sc->irq == NULL) {
+		device_printf(dev, "couldn't map iterrupt\n");
+		splx(s);
+		return ENXIO;
+	}
+	tmp = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET,
+			     epic_intr, sc, &sc->sc_ih);
+	if (tmp) {
+		device_printf(dev, "couldn't setup irq\n");
+		splx(s);
+		return tmp;
 	}
 
-	/* Set shut down routine to stop DMA processes on reboot */
-	EVENTHANDLER_REGISTER(shutdown_post_sync, epic_shutdown, sc,
-			      SHUTDOWN_PRI_DEFAULT);
-
 	/*  Attach to if manager */
 	if_attach(ifp);
 	ether_ifattach(ifp);
-
-#if NBPF > 0
 	bpfattach(ifp,DLT_EN10MB, sizeof(struct ether_header));
-#endif
 
 	splx(s);
 
 	printf("\n");
 
-	return;
+	return 0;
 }
 
-static void
-epic_shutdown(
-    void *sc,
-    int howto)
+static int
+epic_freebsd_detach(device_t dev)
 {
+	epic_softc_t *sc = device_get_softc(dev);
+	int s;
+
+	s = splimp();
+
+	/*
+	 * Close down routes etc.
+	 */
+	bpfdetach(&sc->arpcom.ac_if);
+	if_detach(&sc->arpcom.ac_if);
+
+	/*
+	 * Stop DMA and drop transmit queue.
+	 */
 	epic_stop(sc);
+
+	/*
+	 * Dellocate resources.
+	 */
+	bus_teardown_intr(dev, sc->irq, sc->sc_ih);
+	bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
+	bus_release_resource(dev, SYS_RES_MEMORY, PCI_CBMA, sc->mem);
+
+	/*
+	 * XXX free more resources.
+	 */
+	
+	return 0;
+}
+
+static int
+epic_shutdown(device_t dev)
+{
+	epic_stop((epic_softc_t *) device_get_softc(dev));
+	return 0;
 }
 
+static device_method_t epic_methods[] = {
+	/* Device iterface */
+	DEVMETHOD(device_probe,		epic_freebsd_probe),
+	DEVMETHOD(device_attach,	epic_freebsd_attach),
+	DEVMETHOD(device_detach,	epic_freebsd_detach),
+	DEVMETHOD(device_shutdown,	epic_shutdown),
+
+	{ 0, 0 }
+};
+
+static driver_t epic_driver = {
+	"tx",
+	epic_methods,
+	sizeof(epic_softc_t),
+};
+
+static devclass_t epic_devclass;
+
+DRIVER_MODULE(if_tx, pci, epic_driver, epic_devclass, 0, 0);
+
 #endif /* __OpenBSD__ */
 
 /* ------------------------------------------------------------------------
@@ -879,11 +890,7 @@
 
 #if NBPF > 0
 		if( ifp->if_bpf ) 
-#if defined(__FreeBSD__)
-			bpf_mtap( ifp, m0 );
-#else /* __OpenBSD__ */
-			bpf_mtap( ifp->if_bpf, m0 );
-#endif /* __FreeBSD__ */
+			bpf_mtap( EPIC_BPFTAP_ARG(ifp), m0 );
 #endif
 	}
 
@@ -947,14 +954,10 @@
 		m->m_pkthdr.rcvif = &(sc->sc_if);
 		m->m_pkthdr.len = m->m_len = len;
 
-#if NBPF > 0
 		/* Give mbuf to BPF */
+#if NBPF > 0
 		if( sc->sc_if.if_bpf ) 
-#if defined(__FreeBSD__)
-			bpf_mtap( &sc->sc_if, m );
-#else /* __OpenBSD__ */
-			bpf_mtap( sc->sc_if.if_bpf, m );
-#endif /* __FreeBSD__ */
+			bpf_mtap( EPIC_BPFTAP_ARG(&sc->sc_if), m );
 #endif /* NBPF */
 
 #ifdef BRIDGE
Index: if_txvar.h
===================================================================
RCS file: /home/ncvs/src/sys/pci/if_txvar.h,v
retrieving revision 1.5
diff -u -r1.5 if_txvar.h
--- if_txvar.h	1999/10/29 09:56:52	1.5
+++ if_txvar.h	2000/03/26 00:58:26
@@ -330,16 +330,13 @@
 	struct arpcom		arpcom;
 #if defined(__OpenBSD__)
 	struct device		sc_dev;
+#else /* __FreeBSD__ */
+	struct resource		*mem;
+	struct resource		*irq;
+#endif
 	void			*sc_ih;
 	bus_space_tag_t		sc_st;
 	bus_space_handle_t	sc_sh;
-#else /* __FreeBSD__ */
-#if defined(EPIC_USEIOSPACE)
-	u_int32_t		iobase;
-#else
-	caddr_t			csr;
-#endif
-#endif
 #if !defined(EPIC_NOIFMEDIA)
 	struct ifmedia 		ifmedia;
 #endif
@@ -366,40 +363,16 @@
 #if defined(__FreeBSD__)
 #define EPIC_FORMAT	"tx%d"
 #define EPIC_ARGS(sc)	(sc->unit)
+#define EPIC_BPFTAP_ARG(ifp)	ifp
 #define sc_if arpcom.ac_if
 #define sc_macaddr arpcom.ac_enaddr
-#if defined(EPIC_USEIOSPACE)
-#define CSR_WRITE_4(sc,reg,val) 					\
-	outl( (sc)->iobase + (u_int32_t)(reg), (val) )
-#define CSR_WRITE_2(sc,reg,val) 					\
-	outw( (sc)->iobase + (u_int32_t)(reg), (val) )
-#define CSR_WRITE_1(sc,reg,val) 					\
-	outb( (sc)->iobase + (u_int32_t)(reg), (val) )
-#define CSR_READ_4(sc,reg) 						\
-	inl( (sc)->iobase + (u_int32_t)(reg) )
-#define CSR_READ_2(sc,reg) 						\
-	inw( (sc)->iobase + (u_int32_t)(reg) )
-#define CSR_READ_1(sc,reg) 						\
-	inb( (sc)->iobase + (u_int32_t)(reg) )
-#else
-#define CSR_WRITE_1(sc,reg,val) 					\
-	((*(volatile u_int8_t*)((sc)->csr + (u_int32_t)(reg))) = (u_int8_t)(val))
-#define CSR_WRITE_2(sc,reg,val) 					\
-	((*(volatile u_int16_t*)((sc)->csr + (u_int32_t)(reg))) = (u_int16_t)(val))
-#define CSR_WRITE_4(sc,reg,val) 					\
-	((*(volatile u_int32_t*)((sc)->csr + (u_int32_t)(reg))) = (u_int32_t)(val))
-#define CSR_READ_1(sc,reg) 						\
-	(*(volatile u_int8_t*)((sc)->csr + (u_int32_t)(reg)))
-#define CSR_READ_2(sc,reg) 						\
-	(*(volatile u_int16_t*)((sc)->csr + (u_int32_t)(reg)))
-#define CSR_READ_4(sc,reg) 						\
-	(*(volatile u_int32_t*)((sc)->csr + (u_int32_t)(reg)))
-#endif
 #else /* __OpenBSD__ */
 #define EPIC_FORMAT	"%s"
 #define EPIC_ARGS(sc)	(sc->sc_dev.dv_xname)
+#define EPIC_BPFTAP_ARG(ifp)	(ifp)->if_bpf
 #define sc_if	arpcom.ac_if
 #define sc_macaddr arpcom.ac_enaddr
+#endif
 #define CSR_WRITE_4(sc,reg,val) 					\
 	bus_space_write_4( (sc)->sc_st, (sc)->sc_sh, (reg), (val) )
 #define CSR_WRITE_2(sc,reg,val) 					\
@@ -412,7 +385,6 @@
 	bus_space_read_2( (sc)->sc_st, (sc)->sc_sh, (reg) )
 #define CSR_READ_1(sc,reg) 						\
 	bus_space_read_1( (sc)->sc_st, (sc)->sc_sh, (reg) )
-#endif
 
 #define	PHY_READ_2(sc,reg)	epic_read_phy_register(sc,reg)
 #define PHY_WRITE_2(sc,reg,val)	epic_write_phy_register(sc,reg,val)

>Release-Note:
>Audit-Trail:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200003260117.RAA00496>