PERFORCE change 151866 for review
Marcel Moolenaar
marcel at FreeBSD.org
Fri Oct 24 19:29:07 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=151866
Change 151866 by marcel at marcel_jnpr on 2008/10/24 19:28:37
More merge fodder.
Affected files ...
.. //depot/projects/powerpc/sys/dev/sbni/if_sbni.c#4 edit
.. //depot/projects/powerpc/sys/dev/sbni/if_sbni_isa.c#4 edit
.. //depot/projects/powerpc/sys/dev/sbni/if_sbni_pci.c#4 edit
.. //depot/projects/powerpc/sys/dev/sbni/if_sbnireg.h#3 edit
.. //depot/projects/powerpc/sys/dev/sbni/if_sbnivar.h#3 edit
Differences ...
==== //depot/projects/powerpc/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/powerpc/sys/dev/sbni/if_sbni_isa.c#4 (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/powerpc/sys/dev/sbni/if_sbni_pci.c#4 (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/powerpc/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/powerpc/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 */
More information about the p4-projects
mailing list