From owner-p4-projects@FreeBSD.ORG Fri Oct 24 20:01:52 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id BA96D1065699; Fri, 24 Oct 2008 20:01:52 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 4A4161065674 for ; Fri, 24 Oct 2008 20:01:52 +0000 (UTC) (envelope-from marcel@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 3730C8FC14 for ; Fri, 24 Oct 2008 20:01:52 +0000 (UTC) (envelope-from marcel@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id m9OK1qQi092637 for ; Fri, 24 Oct 2008 20:01:52 GMT (envelope-from marcel@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id m9OK1qXt092635 for perforce@freebsd.org; Fri, 24 Oct 2008 20:01:52 GMT (envelope-from marcel@freebsd.org) Date: Fri, 24 Oct 2008 20:01:52 GMT Message-Id: <200810242001.m9OK1qXt092635@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to marcel@freebsd.org using -f From: Marcel Moolenaar To: Perforce Change Reviews Cc: Subject: PERFORCE change 151873 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 24 Oct 2008 20:01:53 -0000 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 -__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 +#include #include #include #include @@ -86,12 +87,11 @@ #include #include -#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 -__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 @@ -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: 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 -__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 #include @@ -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: 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 */