Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 24 Oct 2008 20:01:52 GMT
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 151873 for review
Message-ID:  <200810242001.m9OK1qXt092635@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=151873

Change 151873 by marcel@marcel_jnpr on 2008/10/24 20:01:45

	More merge fodder (and more deja vu).

Affected files ...

.. //depot/projects/e500/sys/dev/sbni/if_sbni.c#4 edit
.. //depot/projects/e500/sys/dev/sbni/if_sbni_isa.c#3 edit
.. //depot/projects/e500/sys/dev/sbni/if_sbni_pci.c#3 edit
.. //depot/projects/e500/sys/dev/sbni/if_sbnireg.h#3 edit
.. //depot/projects/e500/sys/dev/sbni/if_sbnivar.h#3 edit

Differences ...

==== //depot/projects/e500/sys/dev/sbni/if_sbni.c#4 (text+ko) ====

@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/sbni/if_sbni.c,v 1.24 2007/07/05 07:46:33 peter Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/sbni/if_sbni.c,v 1.28 2008/09/10 18:42:19 jhb Exp $");
 
 /*
  * Device driver for Granch SBNI12 leased line adapters
@@ -62,6 +62,7 @@
  
 
 #include <sys/param.h>
+#include <sys/bus.h>
 #include <sys/systm.h>
 #include <sys/socket.h>
 #include <sys/sockio.h>
@@ -86,12 +87,11 @@
 #include <dev/sbni/if_sbnireg.h>
 #include <dev/sbni/if_sbnivar.h>
 
-#define ASM_CRC 1
-
 static void	sbni_init(void *);
+static void	sbni_init_locked(struct sbni_softc *);
 static void	sbni_start(struct ifnet *);
+static void	sbni_start_locked(struct ifnet *);
 static int	sbni_ioctl(struct ifnet *, u_long, caddr_t);
-static void	sbni_watchdog(struct ifnet *);
 static void	sbni_stop(struct sbni_softc *);
 static void	handle_channel(struct sbni_softc *);
 
@@ -125,11 +125,11 @@
 static u_int32_t crc32tab[];
 
 #ifdef SBNI_DUAL_COMPOUND
-struct sbni_softc *sbni_headlist;
+static struct mtx headlist_lock;
+MTX_SYSINIT(headlist_lock, &headlist_lock, "sbni headlist", MTX_DEF);
+static struct sbni_softc *sbni_headlist;
 #endif
 
-u_int32_t next_sbni_unit;
-
 /* -------------------------------------------------------------------------- */
 
 static __inline u_char
@@ -217,7 +217,7 @@
 /*
  * Install interface into kernel networking data structures
  */
-void
+int
 sbni_attach(struct sbni_softc *sc, int unit, struct sbni_flags flags)
 {
 	struct ifnet *ifp;
@@ -225,27 +225,27 @@
    
 	ifp = sc->ifp = if_alloc(IFT_ETHER);
 	if (ifp == NULL)
-		panic("sbni%d: can not if_alloc()", unit);
+		return (ENOMEM);
 	sbni_outb(sc, CSR0, 0);
 	set_initial_values(sc, flags);
 
-	callout_handle_init(&sc->wch);
 	/* Initialize ifnet structure */
 	ifp->if_softc	= sc;
 	if_initname(ifp, "sbni", unit);
 	ifp->if_init	= sbni_init;
 	ifp->if_start	= sbni_start;
 	ifp->if_ioctl	= sbni_ioctl;
-	ifp->if_watchdog	= sbni_watchdog;
-	ifp->if_snd.ifq_maxlen	= IFQ_MAXLEN;
+	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
 
 	/* report real baud rate */
 	csr0 = sbni_inb(sc, CSR0);
 	ifp->if_baudrate =
 		(csr0 & 0x01 ? 500000 : 2000000) / (1 << flags.rate);
 
-	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
-	    IFF_NEEDSGIANT;
+	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+
+	mtx_init(&sc->lock, ifp->if_xname, MTX_NETWORK_LOCK, MTX_DEF);
+	callout_init_mtx(&sc->wch, &sc->lock, 0);
 	ether_ifattach(ifp, sc->enaddr);
 	/* device attach does transition from UNCONFIGURED to IDLE state */
 
@@ -254,18 +254,54 @@
 		printf("auto\n");
 	else
 		printf("%d (fixed)\n", sc->cur_rxl_index);
+	return (0);
+}
+
+void
+sbni_detach(struct sbni_softc *sc)
+{
+
+	SBNI_LOCK(sc);
+	sbni_stop(sc);
+	SBNI_UNLOCK(sc);
+	callout_drain(&sc->wch);
+	ether_ifdetach(sc->ifp);
+	if (sc->irq_handle)
+		bus_teardown_intr(sc->dev, sc->irq_res, sc->irq_handle);
+	mtx_destroy(&sc->lock);
+	if_free(sc->ifp);
 }
 
+void
+sbni_release_resources(struct sbni_softc *sc)
+{
+
+	if (sc->irq_res)
+		bus_release_resource(sc->dev, SYS_RES_IRQ, sc->irq_rid,
+		    sc->irq_res);
+	if (sc->io_res && sc->io_off == 0)
+		bus_release_resource(sc->dev, SYS_RES_IOPORT, sc->io_rid,
+		    sc->io_res);
+}
+
 /* -------------------------------------------------------------------------- */
 
 static void
 sbni_init(void *xsc)
 {
 	struct sbni_softc *sc;
+
+	sc = (struct sbni_softc *)xsc;
+	SBNI_LOCK(sc);
+	sbni_init_locked(sc);
+	SBNI_UNLOCK(sc);
+}
+
+static void
+sbni_init_locked(struct sbni_softc *sc)
+{
 	struct ifnet *ifp;
-	int  s;
 
-	sc = (struct sbni_softc *)xsc;
 	ifp = sc->ifp;
 
 	/*
@@ -275,24 +311,31 @@
 	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
 		return;
 
-	s = splimp();
-	ifp->if_timer = 0;
 	card_start(sc);
-	sc->wch = timeout(sbni_timeout, sc, hz/SBNI_HZ);
+	callout_reset(&sc->wch, hz/SBNI_HZ, sbni_timeout, sc);
 
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 
 	/* attempt to start output */
-	sbni_start(ifp);
-	splx(s);
+	sbni_start_locked(ifp);
 }
 
+static void
+sbni_start(struct ifnet *ifp)
+{
+	struct sbni_softc *sc = ifp->if_softc;
 
+	SBNI_LOCK(sc);
+	sbni_start_locked(ifp);
+	SBNI_UNLOCK(sc);
+}
+
 static void
-sbni_start(struct ifnet *ifp)
+sbni_start_locked(struct ifnet *ifp)
 {
 	struct sbni_softc *sc = ifp->if_softc;
+
 	if (sc->tx_frameno == 0)
 		prepare_to_send(sc);
 }
@@ -309,8 +352,8 @@
 		sc->rx_buf_p = NULL;
 	}
 
-	untimeout(sbni_timeout, sc, sc->wch);
-	sc->wch.callout = NULL;
+	callout_stop(&sc->wch);
+	sc->ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
 }
 
 /* -------------------------------------------------------------------------- */
@@ -340,14 +383,20 @@
 
 	do {
 		repeat = 0;
+		SBNI_LOCK(sc);
 		if (sbni_inb(sc, CSR0) & (RC_RDY | TR_RDY)) {
 			handle_channel(sc);
 			repeat = 1;
 		}
-		if (sc->slave_sc && 	/* second channel present */
-		    (sbni_inb(sc->slave_sc, CSR0) & (RC_RDY | TR_RDY))) {
-			handle_channel(sc->slave_sc);
-			repeat = 1;
+		SBNI_UNLOCK(sc);
+		if (sc->slave_sc) {
+			/* second channel present */
+			SBNI_LOCK(sc->slave_sc);
+			if (sbni_inb(sc->slave_sc, CSR0) & (RC_RDY | TR_RDY)) {
+				handle_channel(sc->slave_sc);
+				repeat = 1;
+			}
+			SBNI_UNLOCK(sc->slave_sc);
 		}
 	} while (repeat);
 }
@@ -378,7 +427,7 @@
 		 */
 		csr0 = sbni_inb(sc, CSR0);
 		if ((csr0 & TR_RDY) == 0 || (csr0 & RC_RDY) != 0)
-			printf("sbni: internal error!\n");
+			if_printf(sc->ifp, "internal error!\n");
 
 		/* if state & FL_NEED_RESEND != 0 then tx_frameno != 0 */
 		if (req_ans || sc->tx_frameno != 0)
@@ -856,9 +905,11 @@
 	m = sc->rx_buf_p;
 	m->m_pkthdr.rcvif = ifp;
 	m->m_pkthdr.len   = m->m_len = sc->inppos;
+	sc->rx_buf_p = NULL;
 
+	SBNI_UNLOCK(sc);
 	(*ifp->if_input)(ifp, m);
-	sc->rx_buf_p = NULL;
+	SBNI_LOCK(sc);
 }
 
 /* -------------------------------------------------------------------------- */
@@ -872,11 +923,10 @@
 sbni_timeout(void *xsc)
 {
 	struct sbni_softc *sc;
-	int s;
 	u_char csr0;
 
 	sc = (struct sbni_softc *)xsc;
-	s = splimp();
+	SBNI_ASSERT_LOCKED(sc);
 
 	csr0 = sbni_inb(sc, CSR0);
 	if (csr0 & RC_CHK) {
@@ -895,9 +945,8 @@
 		}
 	}
 
-	sbni_outb(sc, CSR0, csr0 | RC_CHK); 
-	sc->wch = timeout(sbni_timeout, sc, hz/SBNI_HZ);
-	splx(s);
+	sbni_outb(sc, CSR0, csr0 | RC_CHK);
+	callout_reset(&sc->wch, hz/SBNI_HZ, sbni_timeout, sc);
 }
 
 /* -------------------------------------------------------------------------- */
@@ -918,19 +967,6 @@
 
 /* -------------------------------------------------------------------------- */
 
-/*
- * Device timeout/watchdog routine. Entered if the device neglects to
- *	generate an interrupt after a transmit has been started on it.
- */
-
-static void
-sbni_watchdog(struct ifnet *ifp)
-{
-	log(LOG_ERR, "%s: device timeout\n", ifp->if_xname);
-	ifp->if_oerrors++;
-}
-
-
 static u_char rxl_tab[] = {
 	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08,
 	0x0a, 0x0c, 0x0f, 0x16, 0x18, 0x1a, 0x1c, 0x1f
@@ -971,12 +1007,22 @@
 
 
 #ifdef SBNI_DUAL_COMPOUND
+void
+sbni_add(struct sbni_softc *sc)
+{
+
+	mtx_lock(&headlist_lock);
+	sc->link = sbni_headlist;
+	sbni_headlist = sc;
+	mtx_unlock(&headlist_lock);
+}
 
 struct sbni_softc *
 connect_to_master(struct sbni_softc *sc)
 {
 	struct sbni_softc *p, *p_prev;
 
+	mtx_lock(&headlist_lock);
 	for (p = sbni_headlist, p_prev = NULL; p; p_prev = p, p = p->link) {
 		if (rman_get_start(p->io_res) == rman_get_start(sc->io_res) + 4 ||
 		    rman_get_start(p->io_res) == rman_get_start(sc->io_res) - 4) {
@@ -985,9 +1031,11 @@
 				p_prev->link = p->link;
 			else
 				sbni_headlist = p->link;
+			mtx_unlock(&headlist_lock);
 			return p;
 		}
 	}
+	mtx_unlock(&headlist_lock);
 
 	return (NULL);
 }
@@ -1049,30 +1097,29 @@
 	struct thread *td;
 	struct sbni_in_stats *in_stats;
 	struct sbni_flags flags;
-	int error, s;
+	int error;
 
 	sc = ifp->if_softc;
 	ifr = (struct ifreq *)data;
 	td = curthread;
 	error = 0;
 
-	s = splimp();
-
 	switch (command) {
 	case SIOCSIFFLAGS:
 		/*
 		 * If the interface is marked up and stopped, then start it.
 		 * If it is marked down and running, then stop it.
 		 */
+		SBNI_LOCK(sc);
 		if (ifp->if_flags & IFF_UP) {
 			if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
-				sbni_init(sc);
+				sbni_init_locked(sc);
 		} else {
 			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
 				sbni_stop(sc);
-				ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 			}
 		}
+		SBNI_UNLOCK(sc);
 		break;
 
 	case SIOCADDMULTI:
@@ -1086,29 +1133,29 @@
 			error = EAFNOSUPPORT; */
 		break;
 
-	case SIOCSIFMTU:
-		if (ifr->ifr_mtu > ETHERMTU)
-			error = EINVAL;
-		else
-			ifp->if_mtu = ifr->ifr_mtu;
-		break;
-
 		/*
 		 * SBNI specific ioctl
 		 */
 	case SIOCGHWFLAGS:	/* get flags */
+		SBNI_LOCK(sc);
 		bcopy((caddr_t)IF_LLADDR(sc->ifp)+3, (caddr_t) &flags, 3);
 		flags.rxl = sc->cur_rxl_index;
 		flags.rate = sc->csr1.rate;
 		flags.fixed_rxl = (sc->delta_rxl == 0);
 		flags.fixed_rate = 1;
+		SBNI_UNLOCK(sc);
 		ifr->ifr_data = *(caddr_t*) &flags;
 		break;
 
 	case SIOCGINSTATS:
-		in_stats = (struct sbni_in_stats *)ifr->ifr_data;
-		bcopy((void *)(&(sc->in_stats)), (void *)in_stats,
-		      sizeof(struct sbni_in_stats));
+		in_stats = malloc(sizeof(struct sbni_in_stats), M_DEVBUF,
+		    M_WAITOK);
+		SBNI_LOCK(sc);
+		bcopy(&sc->in_stats, in_stats, sizeof(struct sbni_in_stats));
+		SBNI_UNLOCK(sc);
+		error = copyout(ifr->ifr_data, in_stats,
+		    sizeof(struct sbni_in_stats));
+		free(in_stats, M_DEVBUF);
 		break;
 
 	case SIOCSHWFLAGS:	/* set flags */
@@ -1117,6 +1164,7 @@
 		if (error)
 			break;
 		flags = *(struct sbni_flags*)&ifr->ifr_data;
+		SBNI_LOCK(sc);
 		if (flags.fixed_rxl) {
 			sc->delta_rxl = 0;
 			sc->cur_rxl_index = flags.rxl;
@@ -1132,11 +1180,14 @@
 
 		/* Don't be afraid... */
 		sbni_outb(sc, CSR1, *(char*)(&sc->csr1) | PR_RES);
+		SBNI_UNLOCK(sc);
 		break;
 
 	case SIOCRINSTATS:
+		SBNI_LOCK(sc);
 		if (!(error = priv_check(td, PRIV_DRIVER)))	/* root only */
 			bzero(&sc->in_stats, sizeof(struct sbni_in_stats));
+		SBNI_UNLOCK(sc);
 		break;
 
 	default:
@@ -1144,106 +1195,20 @@
 		break;
 	}
 
-	splx(s);
 	return (error);
 }
 
 /* -------------------------------------------------------------------------- */
 
-#ifdef ASM_CRC
-
 static u_int32_t
 calc_crc32(u_int32_t crc, caddr_t p, u_int len)
 {
-	register u_int32_t  _crc __asm ("ax");
-	_crc = crc;
-	
-	__asm __volatile (
-		"xorl	%%ebx, %%ebx\n"
-		"movl	%1, %%esi\n" 
-		"movl	%2, %%ecx\n" 
-		"movl	$crc32tab, %%edi\n"
-		"shrl	$2, %%ecx\n"
-		"jz	1f\n"
-
-		".align 4\n"
-	"0:\n"
-		"movb	%%al, %%bl\n"
-		"movl	(%%esi), %%edx\n"
-		"shrl	$8, %%eax\n"
-		"xorb	%%dl, %%bl\n"
-		"shrl	$8, %%edx\n"
-		"xorl	(%%edi,%%ebx,4), %%eax\n"
-
-		"movb	%%al, %%bl\n"
-		"shrl	$8, %%eax\n"
-		"xorb	%%dl, %%bl\n"
-		"shrl	$8, %%edx\n"
-		"xorl	(%%edi,%%ebx,4), %%eax\n"
-
-		"movb	%%al, %%bl\n"
-		"shrl	$8, %%eax\n"
-		"xorb	%%dl, %%bl\n"
-		"movb	%%dh, %%dl\n" 
-		"xorl	(%%edi,%%ebx,4), %%eax\n"
-
-		"movb	%%al, %%bl\n"
-		"shrl	$8, %%eax\n"
-		"xorb	%%dl, %%bl\n"
-		"addl	$4, %%esi\n"
-		"xorl	(%%edi,%%ebx,4), %%eax\n"
-
-		"decl	%%ecx\n"
-		"jnz	0b\n"
-
-	"1:\n"
-		"movl	%2, %%ecx\n"
-		"andl	$3, %%ecx\n"
-		"jz	2f\n"
-
-		"movb	%%al, %%bl\n"
-		"shrl	$8, %%eax\n"
-		"xorb	(%%esi), %%bl\n"
-		"xorl	(%%edi,%%ebx,4), %%eax\n"
-
-		"decl	%%ecx\n"
-		"jz	2f\n"
-
-		"movb	%%al, %%bl\n"
-		"shrl	$8, %%eax\n"
-		"xorb	1(%%esi), %%bl\n"
-		"xorl	(%%edi,%%ebx,4), %%eax\n"
-
-		"decl	%%ecx\n"
-		"jz	2f\n"
-
-		"movb	%%al, %%bl\n"
-		"shrl	$8, %%eax\n"
-		"xorb	2(%%esi), %%bl\n"
-		"xorl	(%%edi,%%ebx,4), %%eax\n"
-	"2:\n"
-		: "=a" (_crc)
-		: "g" (p), "g" (len)
-		: "bx", "cx", "dx", "si", "di"
-	);
-
-	return (_crc);
-}
-
-#else	/* ASM_CRC */
-
-static u_int32_t
-calc_crc32(u_int32_t crc, caddr_t p, u_int len)
-{
 	while (len--)
 		crc = CRC32(*p++, crc);
 
 	return (crc);
 }
 
-#endif	/* ASM_CRC */
-
-
 static u_int32_t crc32tab[] __aligned(8) = {
 	0xD202EF8D,  0xA505DF1B,  0x3C0C8EA1,  0x4B0BBE37,
 	0xD56F2B94,  0xA2681B02,  0x3B614AB8,  0x4C667A2E,

==== //depot/projects/e500/sys/dev/sbni/if_sbni_isa.c#3 (text+ko) ====

@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/sbni/if_sbni_isa.c,v 1.15 2007/02/23 12:18:53 piso Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/sbni/if_sbni_isa.c,v 1.18 2008/09/10 18:36:58 jhb Exp $");
 
 
 #include <sys/param.h>
@@ -85,7 +85,6 @@
 		return (error);
 
 	sc = device_get_softc(dev);
-	bzero(sc, sizeof(struct sbni_softc));
 
  	sc->io_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->io_rid,
 					0ul, ~0ul, SBNI_PORTS, RF_ACTIVE);
@@ -95,12 +94,11 @@
 	}
 
 	if (sbni_probe(sc) != 0) {
-		bus_release_resource(dev, SYS_RES_IOPORT,
-				     sc->io_rid, sc->io_res);
+		sbni_release_resources(sc);
 		return (ENXIO);
 	}
 
-	device_quiet(dev);
+	device_set_desc(dev, "Granch SBNI12/ISA adapter");
 	return (0);
 }
 
@@ -113,50 +111,32 @@
 	int error;
    
 	sc = device_get_softc(dev);
+	sc->dev = dev;
 
-	printf("sbni%d: <Granch SBNI12/ISA adapter> port 0x%lx",
-	       next_sbni_unit, rman_get_start(sc->io_res));
 	sc->irq_res = bus_alloc_resource_any(
 	    dev, SYS_RES_IRQ, &sc->irq_rid, RF_ACTIVE);
 
-	if (sc->irq_res) {
-		printf(" irq %ld\n", rman_get_start(sc->irq_res));
-		error = bus_setup_intr(
-		    dev, sc->irq_res, INTR_TYPE_NET,
-		    NULL, sbni_intr, sc, &sc->irq_handle);
-		if (error) {
-			printf("sbni%d: bus_setup_intr\n", next_sbni_unit);
-			bus_release_resource(
-			    dev, SYS_RES_IOPORT, sc->io_rid, sc->io_res);
-			bus_release_resource(
-			    dev, SYS_RES_IRQ, sc->irq_rid, sc->irq_res);
-			return (error);
-		}
-
 #ifndef SBNI_DUAL_COMPOUND
 
-	} else {
-		printf("\nsbni%d: irq conflict!\n", next_sbni_unit);
-		bus_release_resource(dev, SYS_RES_IOPORT,
-				     sc->io_rid, sc->io_res);
+	if (sc->irq_res == NULL) {
+		device_printf(dev, "irq conflict!\n");
+		sbni_release_resources(sc);
 		return (ENOENT);
 	}
 
 #else	/* SBNI_DUAL_COMPOUND */
 
-		sc->link = sbni_headlist;
-		sbni_headlist = sc;
+	if (sc->irq_res) {
+		sbni_add(sc);
 	} else {
 		struct sbni_softc  *master;
 
 		if ((master = connect_to_master(sc)) == 0) {
-			printf("\nsbni%d: failed to alloc irq\n",
-			       next_sbni_unit);
-			bus_release_resource(
-			    dev, SYS_RES_IOPORT, sc->io_rid, sc->io_res);
+			device_printf(dev, "failed to alloc irq\n");
+			sbni_release_resources(sc);
 			return (ENXIO);
 		} else {
-			printf(" shared irq with %s\n",
+			device_printf(dev, "shared irq with %s\n",
 			       master->ifp->if_xname);
 		}
 	} 
@@ -164,6 +144,24 @@
 
 	*(u_int32_t*)&flags = device_get_flags(dev);
 
-	sbni_attach(sc, next_sbni_unit++, flags);
+	error = sbni_attach(sc, device_get_unit(dev) * 2, flags);
+	if (error) {
+		device_printf(dev, "cannot initialize driver\n");
+		sbni_release_resources(sc);
+		return (error);
+	}
+
+	if (sc->irq_res) {
+		error = bus_setup_intr(
+		    dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE,
+		    NULL, sbni_intr, sc, &sc->irq_handle);
+		if (error) {
+			device_printf(dev, "bus_setup_intr\n");
+			sbni_detach(sc);
+			sbni_release_resources(sc);
+			return (error);
+		}
+	}
+
 	return (0);
 }

==== //depot/projects/e500/sys/dev/sbni/if_sbni_pci.c#3 (text+ko) ====

@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/sbni/if_sbni_pci.c,v 1.12 2007/02/23 12:18:53 piso Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/sbni/if_sbni_pci.c,v 1.15 2008/09/10 18:36:58 jhb Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -51,11 +51,13 @@
 
 static int	sbni_pci_probe(device_t);
 static int	sbni_pci_attach(device_t);
+static int	sbni_pci_detach(device_t);
 
 static device_method_t sbni_pci_methods[] = {
 	/* Device interface */
 	DEVMETHOD(device_probe,	sbni_pci_probe),
 	DEVMETHOD(device_attach, sbni_pci_attach),
+	DEVMETHOD(device_detach, sbni_pci_detach),
 	{ 0, 0 }
 };
 
@@ -75,14 +77,13 @@
 {
 	struct sbni_softc  *sc;
 	u_int32_t  ports;
-   
+ 
 	ports = SBNI_PORTS;
 	if (pci_get_vendor(dev) != SBNI_PCI_VENDOR ||
 	    pci_get_device(dev) != SBNI_PCI_DEVICE)
 		return (ENXIO);
 
 	sc = device_get_softc(dev);
-	bzero(sc, sizeof(struct sbni_softc));
 	if (pci_get_subdevice(dev) == 2) {
 		ports <<= 1;
 		sc->slave_sc = malloc(sizeof(struct sbni_softc),
@@ -97,7 +98,7 @@
  	sc->io_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->io_rid,
 					0ul, ~0ul, ports, RF_ACTIVE);
 	if (!sc->io_res) {
-		printf("sbni: cannot allocate io ports!\n");
+		device_printf(dev, "cannot allocate io ports!\n");
 		if (sc->slave_sc)
 			free(sc->slave_sc, M_DEVBUF);
 		return (ENOENT);
@@ -108,14 +109,12 @@
 		sc->slave_sc->io_off = 4;
 	}
 	if (sbni_probe(sc) != 0) {
-		bus_release_resource(dev, SYS_RES_IOPORT,
-				     sc->io_rid, sc->io_res);
+		sbni_release_resources(sc);
 		if (sc->slave_sc)
 			free(sc->slave_sc, M_DEVBUF);
 		return (ENXIO);
 	}
 
-	device_quiet(dev);
 	return (0);
 }
 
@@ -127,41 +126,66 @@
 	int error;
 
 	sc = device_get_softc(dev);
+	sc->dev = dev;
 
-	printf("sbni%d: <Granch SBNI12/PCI%sadapter> port 0x%lx",
-	       next_sbni_unit, sc->slave_sc ? " Dual " : " ",
-	       rman_get_start(sc->io_res));
 	sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid,
 					     RF_SHAREABLE);
 
-	if (sc->irq_res) {
-		printf(" irq %ld\n", rman_get_start(sc->irq_res));
-		error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET,
-				       NULL, sbni_intr, sc, &sc->irq_handle);
-		if (error) {
-			printf("sbni%d: bus_setup_intr\n", next_sbni_unit);
-			goto attach_failed;
-		}
-	} else {
-		printf("\nsbni%d: cannot claim irq!\n", next_sbni_unit);
+	if (sc->irq_res == NULL) {
+		device_printf(dev, "cannot claim irq!\n");
 		error = ENOENT;
 		goto attach_failed;
 	}
 
 	*(u_int32_t*)&flags = 0;
 
-	sbni_attach(sc, next_sbni_unit++, flags);
-	if (sc->slave_sc)
-		sbni_attach(sc->slave_sc, next_sbni_unit++, flags);
+	error = sbni_attach(sc, device_get_unit(dev) * 2, flags);
+	if (error) {
+		device_printf(dev, "cannot initialize driver\n");
+		goto attach_failed;
+	}
+	if (sc->slave_sc) {
+		error = sbni_attach(sc->slave_sc, device_get_unit(dev) * 2 + 1,
+		    flags);
+		if (error) {
+			device_printf(dev, "cannot initialize slave\n");
+			sbni_detach(sc);
+			goto attach_failed;
+		}
+	}
+
+	if (sc->irq_res) {
+		error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET |
+		    INTR_MPSAFE, NULL, sbni_intr, sc, &sc->irq_handle);
+		if (error) {
+			device_printf(dev, "bus_setup_intr\n");
+			sbni_detach(sc);
+			if (sc->slave_sc)
+				sbni_detach(sc);
+			goto attach_failed;
+		}
+	}
 	return (0);
 
 attach_failed:
-	bus_release_resource(dev, SYS_RES_IOPORT, sc->io_rid, sc->io_res);
-	if (sc->irq_res) {
-		bus_release_resource(
-		    dev, SYS_RES_IRQ, sc->irq_rid, sc->irq_res);
-	}
+	sbni_release_resources(sc);
 	if (sc->slave_sc)
 		free(sc->slave_sc, M_DEVBUF);
 	return (error);
 }
+
+static int
+sbni_pci_detach(device_t dev)
+{
+	struct sbni_softc *sc;
+
+	sc = device_get_softc(dev);
+	sbni_detach(sc);
+	if (sc->slave_sc)
+		sbni_detach(sc);
+	
+	sbni_release_resources(sc);
+	if (sc->slave_sc)
+		free(sc->slave_sc, M_DEVBUF);
+	return (0);
+}

==== //depot/projects/e500/sys/dev/sbni/if_sbnireg.h#3 (text+ko) ====

@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/dev/sbni/if_sbnireg.h,v 1.2 2005/01/06 01:43:12 imp Exp $
+ * $FreeBSD: src/sys/dev/sbni/if_sbnireg.h,v 1.4 2008/09/10 18:36:58 jhb Exp $
  */
 
 /*

==== //depot/projects/e500/sys/dev/sbni/if_sbnivar.h#3 (text+ko) ====

@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/dev/sbni/if_sbnivar.h,v 1.5 2005/06/10 16:49:14 brooks Exp $
+ * $FreeBSD: src/sys/dev/sbni/if_sbnivar.h,v 1.8 2008/09/10 18:36:58 jhb Exp $
  */
 
 /*
@@ -68,6 +68,7 @@
 
 struct sbni_softc {
 	struct	ifnet *ifp;
+	device_t dev;
 	u_char	enaddr[6];
 
 	int	io_rid;
@@ -111,7 +112,8 @@
 	struct	sbni_csr1 csr1;			/* current value of CSR1 */
 	struct	sbni_in_stats in_stats; 	/* internal statistics */ 
 
-	struct	callout_handle wch;
+	struct	callout wch;
+	struct	mtx lock;
 
 	struct	sbni_softc *slave_sc;
 
@@ -120,15 +122,20 @@
 #endif
 };
 
+#define	SBNI_LOCK(sc)		mtx_lock(&(sc)->lock)
+#define	SBNI_UNLOCK(sc)		mtx_unlock(&(sc)->lock)
+#define	SBNI_ASSERT_LOCKED(sc)	mtx_assert(&(sc)->lock, MA_OWNED)
+
 void	sbni_intr(void *);
 int	sbni_probe(struct sbni_softc *);
-void	sbni_attach(struct sbni_softc *, int, struct sbni_flags);
+int	sbni_attach(struct sbni_softc *, int, struct sbni_flags);
+void	sbni_detach(struct sbni_softc *);
+void	sbni_release_resources(struct sbni_softc *);
 
 extern u_int32_t next_sbni_unit;
 
 #ifdef SBNI_DUAL_COMPOUND
-extern struct sbni_softc *sbni_headlist;
-
+void			sbni_add(struct sbni_softc *);
 struct sbni_softc	*connect_to_master(struct sbni_softc *);
 #endif
 #endif	/* _KERNEL */



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