From owner-svn-src-user@FreeBSD.ORG Sat Jan 31 20:47:28 2009 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 4AD8D1065827; Sat, 31 Jan 2009 20:47:28 +0000 (UTC) (envelope-from thompsa@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 3728D8FC16; Sat, 31 Jan 2009 20:47:28 +0000 (UTC) (envelope-from thompsa@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n0VKlSIp033729; Sat, 31 Jan 2009 20:47:28 GMT (envelope-from thompsa@svn.freebsd.org) Received: (from thompsa@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n0VKlSuP033725; Sat, 31 Jan 2009 20:47:28 GMT (envelope-from thompsa@svn.freebsd.org) Message-Id: <200901312047.n0VKlSuP033725@svn.freebsd.org> From: Andrew Thompson Date: Sat, 31 Jan 2009 20:47:28 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r187965 - user/thompsa/usb/sys/dev/usb2/ethernet X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 31 Jan 2009 20:47:29 -0000 Author: thompsa Date: Sat Jan 31 20:47:27 2009 New Revision: 187965 URL: http://svn.freebsd.org/changeset/base/187965 Log: Move most of the ifnet logic into the usb2_ethernet module, this includes, - make all usb ethernet interfaces named ue%d - handle all threading in usb2_ethernet - provide default ioctl handler - handle mbuf rx - provide locked callbacks for init,start,stop,etc The drivers are not much more than data pushers now. Modified: user/thompsa/usb/sys/dev/usb2/ethernet/if_aue2.c user/thompsa/usb/sys/dev/usb2/ethernet/if_auereg.h user/thompsa/usb/sys/dev/usb2/ethernet/if_axe2.c user/thompsa/usb/sys/dev/usb2/ethernet/if_axereg.h user/thompsa/usb/sys/dev/usb2/ethernet/if_cdce2.c user/thompsa/usb/sys/dev/usb2/ethernet/if_cue2.c user/thompsa/usb/sys/dev/usb2/ethernet/if_cuereg.h user/thompsa/usb/sys/dev/usb2/ethernet/if_kue2.c user/thompsa/usb/sys/dev/usb2/ethernet/if_kuereg.h user/thompsa/usb/sys/dev/usb2/ethernet/if_rue2.c user/thompsa/usb/sys/dev/usb2/ethernet/if_ruereg.h user/thompsa/usb/sys/dev/usb2/ethernet/if_udav2.c user/thompsa/usb/sys/dev/usb2/ethernet/if_udavreg.h user/thompsa/usb/sys/dev/usb2/ethernet/usb2_ethernet.c user/thompsa/usb/sys/dev/usb2/ethernet/usb2_ethernet.h Modified: user/thompsa/usb/sys/dev/usb2/ethernet/if_aue2.c ============================================================================== --- user/thompsa/usb/sys/dev/usb2/ethernet/if_aue2.c Sat Jan 31 20:46:01 2009 (r187964) +++ user/thompsa/usb/sys/dev/usb2/ethernet/if_aue2.c Sat Jan 31 20:47:27 2009 (r187965) @@ -185,13 +185,6 @@ static usb2_callback_t aue_bulk_read_cal static usb2_callback_t aue_bulk_write_clear_stall_callback; static usb2_callback_t aue_bulk_write_callback; -static usb2_task_fn_t aue_promisc_task; -static usb2_task_fn_t aue_ifmedia_task; -static usb2_task_fn_t aue_setmulti_task; -static usb2_task_fn_t aue_tick_task; - -static int aue_do_request(struct aue_softc *, - struct usb2_device_request *, void *); static uint8_t aue_csr_read_1(struct aue_softc *, uint16_t); static uint16_t aue_csr_read_2(struct aue_softc *, uint16_t); static int aue_csr_write_1(struct aue_softc *, uint16_t, uint8_t); @@ -199,19 +192,16 @@ static int aue_csr_write_2(struct aue_so static void aue_eeprom_getword(struct aue_softc *, int, uint16_t *); static void aue_read_eeprom(struct aue_softc *, uint8_t *, uint16_t, uint16_t); -static void aue_setmulti(struct aue_softc *); -static void aue_setpromisc(struct aue_softc *); static void aue_reset(struct aue_softc *); static void aue_reset_pegasus_II(struct aue_softc *); -static void aue_start(struct ifnet *); -static void aue_init(void *); -static void aue_init_locked(struct aue_softc *); -static void aue_stop(struct aue_softc *); -static void aue_start_transfers(struct aue_softc *); +static void aue_init(struct usb2_ether *); +static void aue_stop(struct usb2_ether *); +static void aue_start(struct usb2_ether *); +static void aue_tick(struct usb2_ether *); +static void aue_setmulti(struct usb2_ether *); +static void aue_setpromisc(struct usb2_ether *); static int aue_ifmedia_upd(struct ifnet *); static void aue_ifmedia_sts(struct ifnet *, struct ifmediareq *); -static int aue_ioctl(struct ifnet *, u_long, caddr_t); -static void aue_watchdog(void *); static const struct usb2_config aue_config[AUE_N_TRANSFER] = { @@ -311,18 +301,6 @@ MODULE_DEPEND(aue, usb2_core, 1, 1, 1); MODULE_DEPEND(aue, ether, 1, 1, 1); MODULE_DEPEND(aue, miibus, 1, 1, 1); -static int -aue_do_request(struct aue_softc *sc, struct usb2_device_request *req, - void *data) -{ - usb2_error_t err; - - err = usb2_do_request_flags(sc->sc_udev, &sc->sc_mtx, req, data, 0, - NULL, 1000); - - return (err); -} - #define AUE_SETBIT(sc, reg, x) \ aue_csr_write_1(sc, reg, aue_csr_read_1(sc, reg) | (x)) @@ -342,7 +320,7 @@ aue_csr_read_1(struct aue_softc *sc, uin USETW(req.wIndex, reg); USETW(req.wLength, 1); - err = aue_do_request(sc, &req, &val); + err = usb2_do_request(sc->sc_udev, &sc->sc_mtx, &req, &val); if (err) return (0); return (val); @@ -361,7 +339,7 @@ aue_csr_read_2(struct aue_softc *sc, uin USETW(req.wIndex, reg); USETW(req.wLength, 2); - err = aue_do_request(sc, &req, &val); + err = usb2_do_request(sc->sc_udev, &sc->sc_mtx, &req, &val); if (err) return (0); return (le16toh(val)); @@ -379,7 +357,7 @@ aue_csr_write_1(struct aue_softc *sc, ui USETW(req.wIndex, reg); USETW(req.wLength, 1); - return (aue_do_request(sc, &req, &val)); + return (usb2_do_request(sc->sc_udev, &sc->sc_mtx, &req, &val)); } static int @@ -395,7 +373,7 @@ aue_csr_write_2(struct aue_softc *sc, ui val = htole16(val); - return (aue_do_request(sc, &req, &val)); + return (usb2_do_request(sc->sc_udev, &sc->sc_mtx, &req, &val)); } /* @@ -440,16 +418,12 @@ static int aue_miibus_readreg(device_t dev, int phy, int reg) { struct aue_softc *sc = device_get_softc(dev); - int i, do_unlock; + int i, locked; uint16_t val = 0; - /* avoid recursive locking */ - if (mtx_owned(&sc->sc_mtx)) { - do_unlock = 0; - } else { + locked = mtx_owned(&sc->sc_mtx); + if (!locked) AUE_LOCK(sc); - do_unlock = 1; - } /* * The Am79C901 HomePNA PHY actually contains two transceivers: a 1Mbps @@ -480,7 +454,7 @@ aue_miibus_readreg(device_t dev, int phy val = aue_csr_read_2(sc, AUE_PHY_DATA); done: - if (do_unlock) + if (!locked) AUE_UNLOCK(sc); return (val); } @@ -489,18 +463,14 @@ static int aue_miibus_writereg(device_t dev, int phy, int reg, int data) { struct aue_softc *sc = device_get_softc(dev); - int i, do_unlock; + int i, locked; if (phy == 3) return (0); - /* avoid recursive locking */ - if (mtx_owned(&sc->sc_mtx)) { - do_unlock = 0; - } else { + locked = mtx_owned(&sc->sc_mtx); + if (!locked) AUE_LOCK(sc); - do_unlock = 1; - } aue_csr_write_2(sc, AUE_PHY_DATA, data); aue_csr_write_1(sc, AUE_PHY_ADDR, phy); @@ -514,7 +484,7 @@ aue_miibus_writereg(device_t dev, int ph if (i == AUE_TIMEOUT) device_printf(sc->sc_dev, "MII read timed out\n"); - if (do_unlock) + if (!locked) AUE_UNLOCK(sc); return (0); } @@ -524,15 +494,11 @@ aue_miibus_statchg(device_t dev) { struct aue_softc *sc = device_get_softc(dev); struct mii_data *mii = GET_MII(sc); - uint8_t do_unlock; + int locked; - /* avoid recursive locking */ - if (mtx_owned(&sc->sc_mtx)) { - do_unlock = 0; - } else { + locked = mtx_owned(&sc->sc_mtx); + if (!locked) AUE_LOCK(sc); - do_unlock = 1; - } AUE_CLRBIT(sc, AUE_CTL0, AUE_CTL0_RX_ENB | AUE_CTL0_TX_ENB); if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX) @@ -558,27 +524,22 @@ aue_miibus_statchg(device_t dev) auxmode = aue_miibus_readreg(dev, 0, 0x1b); aue_miibus_writereg(dev, 0, 0x1b, auxmode | 0x04); } - if (do_unlock) + if (!locked) AUE_UNLOCK(sc); } -static void -aue_setmulti_task(void *context, struct usb2_task *task) -{ - struct aue_softc *sc = context; - - aue_setmulti(sc); -} - #define AUE_BITS 6 static void -aue_setmulti(struct aue_softc *sc) +aue_setmulti(struct usb2_ether *ue) { - struct ifnet *ifp = sc->sc_ifp; + struct aue_softc *sc = usb2_ether_getsc(ue); + struct ifnet *ifp = usb2_ether_getifp(ue); struct ifmultiaddr *ifma; uint32_t h = 0, i; uint8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + AUE_LOCK_ASSERT(sc, MA_OWNED); + if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_ALLMULTI); return; @@ -692,7 +653,7 @@ aue_attach(device_t dev) { struct usb2_attach_arg *uaa = device_get_ivars(dev); struct aue_softc *sc = device_get_softc(dev); - struct ifnet *ifp; + struct usb2_ether *ue = &sc->sc_ue; uint8_t eaddr[ETHER_ADDR_LEN]; uint8_t iface_index; int error; @@ -705,14 +666,7 @@ aue_attach(device_t dev) sc->sc_flags |= AUE_FLAG_VER_2; /* XXX currently undocumented */ device_set_usb2_desc(dev); - mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF); - usb2_callout_init_mtx(&sc->sc_watchdog, &sc->sc_mtx, 0); - - USB_TASK_INIT(&sc->sc_promisc_task, aue_promisc_task, sc, &sc->sc_mtx); - USB_TASK_INIT(&sc->sc_multi_task, aue_setmulti_task, sc, &sc->sc_mtx); - USB_TASK_INIT(&sc->sc_media_task, aue_ifmedia_task, sc, &sc->sc_mtx); - USB_TASK_INIT(&sc->sc_tick_task, aue_tick_task, sc, &sc->sc_mtx); iface_index = AUE_IFACE_IDX; error = usb2_transfer_setup(uaa->device, &iface_index, @@ -722,12 +676,6 @@ aue_attach(device_t dev) device_printf(dev, "allocating USB transfers failed!\n"); goto detach; } - error = usb2_proc_create(&sc->sc_tq, USB_PRI_MED, - device_get_nameunit(dev)); - if (error) { - device_printf(dev, "could not setup config thread!\n"); - goto detach; - } AUE_LOCK(sc); /* reset the adapter */ @@ -737,45 +685,23 @@ aue_attach(device_t dev) aue_read_eeprom(sc, eaddr, 0, 3); AUE_UNLOCK(sc); - ifp = if_alloc(IFT_ETHER); - if (ifp == NULL) { - device_printf(dev, "could not if_alloc()\n"); - goto detach; - } - ifp->if_softc = sc; - if_initname(ifp, device_get_name(dev), device_get_unit(dev)); - ifp->if_mtu = ETHERMTU; - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_ioctl = aue_ioctl; - ifp->if_start = aue_start; - ifp->if_init = aue_init; - IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); - ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; - IFQ_SET_READY(&ifp->if_snd); - sc->sc_ifp = ifp; + ue->ue_sc = sc; + ue->ue_dev = dev; + ue->ue_mtx = &sc->sc_mtx; + ue->ue_start = aue_start; + ue->ue_init = aue_init; + ue->ue_stop = aue_stop; + ue->ue_tick = aue_tick; + ue->ue_setmulti = aue_setmulti; + ue->ue_setpromisc = aue_setpromisc; + ue->ue_mii_upd = aue_ifmedia_upd; + ue->ue_mii_sts = aue_ifmedia_sts; - /* - * Do MII setup. - * NOTE: Doing this causes child devices to be attached to us, - * which we would normally disconnect at in the detach routine - * using device_delete_child(). However the USB code is set up - * such that when this driver is removed, all children devices - * are removed as well. In effect, the USB code ends up detaching - * all of our children for us, so we don't have to do is ourselves - * in aue_detach(). It's important to point this out since if - * we *do* try to detach the child devices ourselves, we will - * end up getting the children deleted twice, which will crash - * the system. - */ - error = mii_phy_probe(dev, &sc->sc_miibus, - aue_ifmedia_upd, aue_ifmedia_sts); + error = usb2_ether_ifattach(ue, eaddr); if (error) { - device_printf(dev, "MII without any PHY!\n"); + device_printf(dev, "could not attach interface\n"); goto detach; } - - ether_ifattach(ifp, eaddr); - return (0); /* success */ detach: @@ -787,23 +713,15 @@ static int aue_detach(device_t dev) { struct aue_softc *sc = device_get_softc(dev); - struct ifnet *ifp = sc->sc_ifp; + struct usb2_ether *ue = &sc->sc_ue; AUE_LOCK(sc); sc->sc_flags |= AUE_FLAG_DETACH; - aue_stop(sc); + aue_stop(ue); AUE_UNLOCK(sc); usb2_transfer_unsetup(sc->sc_xfer, AUE_N_TRANSFER); - usb2_proc_free(&sc->sc_tq); - - if (sc->sc_miibus) - device_delete_child(dev, sc->sc_miibus); - if (ifp) { - ether_ifdetach(ifp); - if_free(ifp); - } - usb2_callout_drain(&sc->sc_watchdog); + usb2_ether_ifdetach(ue); mtx_destroy(&sc->sc_mtx); return (0); @@ -826,25 +744,24 @@ static void aue_intr_callback(struct usb2_xfer *xfer) { struct aue_softc *sc = xfer->priv_sc; - struct ifnet *ifp = sc->sc_ifp; + struct ifnet *ifp = usb2_ether_getifp(&sc->sc_ue); struct aue_intrpkt pkt; switch (USB_GET_STATE(xfer)) { case USB_ST_TRANSFERRED: - if (ifp && (ifp->if_drv_flags & IFF_DRV_RUNNING) && - (xfer->actlen >= sizeof(pkt))) { + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) && + xfer->actlen >= sizeof(pkt)) { usb2_copy_out(xfer->frbuffers, 0, &pkt, sizeof(pkt)); - if (pkt.aue_txstat0) { + if (pkt.aue_txstat0) ifp->if_oerrors++; - } if (pkt.aue_txstat0 & (AUE_TXSTAT0_LATECOLL & - AUE_TXSTAT0_EXCESSCOLL)) { + AUE_TXSTAT0_EXCESSCOLL)) ifp->if_collisions++; - } } + /* FALLTHROUGH */ case USB_ST_SETUP: if (sc->sc_flags & AUE_FLAG_INTR_STALL) { usb2_transfer_start(sc->sc_xfer[AUE_INTR_CS_RD]); @@ -881,8 +798,9 @@ static void aue_bulk_read_callback(struct usb2_xfer *xfer) { struct aue_softc *sc = xfer->priv_sc; - struct ifnet *ifp = sc->sc_ifp; - struct mbuf *m = NULL; + struct usb2_ether *ue = &sc->sc_ue; + struct ifnet *ifp = usb2_ether_getifp(ue); + struct aue_rxpkt stat; switch (USB_GET_STATE(xfer)) { case USB_ST_TRANSFERRED: @@ -896,41 +814,28 @@ aue_bulk_read_callback(struct usb2_xfer } } else { - if (xfer->actlen <= (4 + ETHER_CRC_LEN)) { + if (xfer->actlen <= (sizeof(stat) + ETHER_CRC_LEN)) { ifp->if_ierrors++; goto tr_setup; } - usb2_copy_out(xfer->frbuffers, xfer->actlen - 4, &sc->sc_rxpkt, - sizeof(sc->sc_rxpkt)); + usb2_copy_out(xfer->frbuffers, + xfer->actlen - sizeof(stat), &stat, sizeof(stat)); /* * turn off all the non-error bits in the rx status * word: */ - sc->sc_rxpkt.aue_rxstat &= AUE_RXSTAT_MASK; - - if (sc->sc_rxpkt.aue_rxstat) { + stat.aue_rxstat &= AUE_RXSTAT_MASK; + if (stat.aue_rxstat) { ifp->if_ierrors++; goto tr_setup; } /* No errors; receive the packet. */ - xfer->actlen -= (4 + ETHER_CRC_LEN); + xfer->actlen -= (sizeof(stat) + ETHER_CRC_LEN); } + usb2_ether_rxbuf(ue, xfer, 0, xfer->actlen); - m = usb2_ether_get_mbuf(); - - if (m == NULL) { - ifp->if_ierrors++; - goto tr_setup; - } - xfer->actlen = min(xfer->actlen, m->m_len); - - usb2_copy_out(xfer->frbuffers, 0, m->m_data, xfer->actlen); - - ifp->if_ipackets++; - m->m_pkthdr.rcvif = ifp; - m->m_pkthdr.len = m->m_len = xfer->actlen; - + /* FALLTHROUGH */ case USB_ST_SETUP: tr_setup: @@ -940,17 +845,7 @@ tr_setup: xfer->frlengths[0] = xfer->max_data_length; usb2_start_hardware(xfer); } - - /* - * At the end of a USB callback it is always safe to unlock - * the private mutex of a device! That is why we do the - * "if_input" here, and not some lines up! - */ - if (m) { - AUE_UNLOCK(sc); - (ifp->if_input) (ifp, m); - AUE_LOCK(sc); - } + usb2_ether_rxflush(ue); return; default: /* Error */ @@ -983,16 +878,16 @@ static void aue_bulk_write_callback(struct usb2_xfer *xfer) { struct aue_softc *sc = xfer->priv_sc; - struct ifnet *ifp = sc->sc_ifp; + struct ifnet *ifp = usb2_ether_getifp(&sc->sc_ue); struct mbuf *m; uint8_t buf[2]; switch (USB_GET_STATE(xfer)) { case USB_ST_TRANSFERRED: DPRINTFN(11, "transfer of %d bytes complete\n", xfer->actlen); - ifp->if_opackets++; + /* FALLTHROUGH */ case USB_ST_SETUP: if (sc->sc_flags & AUE_FLAG_WRITE_STALL) { @@ -1068,9 +963,9 @@ done: } static void -aue_tick_task(void *context, struct usb2_task *task) +aue_tick(struct usb2_ether *ue) { - struct aue_softc *sc = context; + struct aue_softc *sc = usb2_ether_getsc(ue); struct mii_data *mii = GET_MII(sc); AUE_LOCK_ASSERT(sc, MA_OWNED); @@ -1080,27 +975,14 @@ aue_tick_task(void *context, struct usb2 && mii->mii_media_status & IFM_ACTIVE && IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) { sc->sc_flags |= AUE_FLAG_LINK; - aue_start_transfers(sc); + aue_start(ue); } } static void -aue_start(struct ifnet *ifp) +aue_start(struct usb2_ether *ue) { - struct aue_softc *sc = ifp->if_softc; - - AUE_LOCK(sc); - aue_start_transfers(sc); - AUE_UNLOCK(sc); -} - -static void -aue_start_transfers(struct aue_softc *sc) -{ - struct ifnet *ifp = sc->sc_ifp; - - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) - return; + struct aue_softc *sc = usb2_ether_getsc(ue); /* * start the USB transfers, if not already started: @@ -1111,19 +993,10 @@ aue_start_transfers(struct aue_softc *sc } static void -aue_init(void *xsc) +aue_init(struct usb2_ether *ue) { - struct aue_softc *sc = xsc; - - AUE_LOCK(sc); - aue_init_locked(sc); - AUE_UNLOCK(sc); -} - -static void -aue_init_locked(struct aue_softc *sc) -{ - struct ifnet *ifp = sc->sc_ifp; + struct aue_softc *sc = usb2_ether_getsc(ue); + struct ifnet *ifp = usb2_ether_getifp(ue); int i; AUE_LOCK_ASSERT(sc, MA_OWNED); @@ -1140,10 +1013,10 @@ aue_init_locked(struct aue_softc *sc) aue_csr_write_1(sc, AUE_PAR0 + i, IF_LLADDR(ifp)[i]); /* update promiscuous setting */ - aue_setpromisc(sc); + aue_setpromisc(ue); /* Load the multicast filter. */ - aue_setmulti(sc); + aue_setmulti(ue); /* Enable RX and TX */ aue_csr_write_1(sc, AUE_CTL0, AUE_CTL0_RXSTAT_APPEND | AUE_CTL0_RX_ENB); @@ -1153,22 +1026,16 @@ aue_init_locked(struct aue_softc *sc) sc->sc_flags |= AUE_FLAG_READ_STALL | AUE_FLAG_WRITE_STALL; ifp->if_drv_flags |= IFF_DRV_RUNNING; - aue_start_transfers(sc); - usb2_callout_reset(&sc->sc_watchdog, hz, aue_watchdog, sc); + aue_start(ue); } static void -aue_promisc_task(void *context, struct usb2_task *task) +aue_setpromisc(struct usb2_ether *ue) { - struct aue_softc *sc = context; + struct aue_softc *sc = usb2_ether_getsc(ue); + struct ifnet *ifp = usb2_ether_getifp(ue); - aue_setpromisc(sc); -} - -static void -aue_setpromisc(struct aue_softc *sc) -{ - struct ifnet *ifp = sc->sc_ifp; + AUE_LOCK_ASSERT(sc, MA_OWNED); /* if we want promiscuous mode, set the allframes bit: */ if (ifp->if_flags & IFF_PROMISC) @@ -1184,17 +1051,10 @@ static int aue_ifmedia_upd(struct ifnet *ifp) { struct aue_softc *sc = ifp->if_softc; - - usb2_proc_enqueue(&sc->sc_tq, &sc->sc_media_task); - return (0); -} - -static void -aue_ifmedia_task(void *context, struct usb2_task *task) -{ - struct aue_softc *sc = context; struct mii_data *mii = GET_MII(sc); + AUE_LOCK_ASSERT(sc, MA_OWNED); + sc->sc_flags &= ~AUE_FLAG_LINK; if (mii->mii_instance) { struct mii_softc *miisc; @@ -1203,6 +1063,7 @@ aue_ifmedia_task(void *context, struct u mii_phy_reset(miisc); } mii_mediachg(mii); + return (0); } /* @@ -1221,70 +1082,21 @@ aue_ifmedia_sts(struct ifnet *ifp, struc ifmr->ifm_status = mii->mii_media_status; } -static int -aue_ioctl(struct ifnet *ifp, u_long command, caddr_t data) -{ - struct aue_softc *sc = ifp->if_softc; - struct ifreq *ifr = (struct ifreq *)data; - struct mii_data *mii; - int error = 0; - - switch (command) { - case SIOCSIFFLAGS: - AUE_LOCK(sc); - if (ifp->if_flags & IFF_UP) { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - usb2_proc_enqueue(&sc->sc_tq, - &sc->sc_promisc_task); - else - aue_init_locked(sc); - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - aue_stop(sc); - } - AUE_UNLOCK(sc); - break; - case SIOCADDMULTI: - case SIOCDELMULTI: - usb2_proc_enqueue(&sc->sc_tq, &sc->sc_multi_task); - break; - case SIOCGIFMEDIA: - case SIOCSIFMEDIA: - mii = GET_MII(sc); - error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); - break; - default: - error = ether_ioctl(ifp, command, data); - break; - } - return (error); -} - -static void -aue_watchdog(void *arg) -{ - struct aue_softc *sc = arg; - - usb2_proc_enqueue(&sc->sc_tq, &sc->sc_tick_task); - usb2_callout_reset(&sc->sc_watchdog, hz, aue_watchdog, sc); -} - /* * Stop the adapter and free any mbufs allocated to the * RX and TX lists. */ static void -aue_stop(struct aue_softc *sc) +aue_stop(struct usb2_ether *ue) { - struct ifnet *ifp = sc->sc_ifp; + struct aue_softc *sc = usb2_ether_getsc(ue); + struct ifnet *ifp = usb2_ether_getifp(ue); AUE_LOCK_ASSERT(sc, MA_OWNED); ifp->if_drv_flags &= ~IFF_DRV_RUNNING; sc->sc_flags &= ~AUE_FLAG_LINK; - usb2_callout_stop(&sc->sc_watchdog); - /* * stop all the transfers, if not already stopped: */ @@ -1308,9 +1120,10 @@ static int aue_shutdown(device_t dev) { struct aue_softc *sc = device_get_softc(dev); + struct usb2_ether *ue = &sc->sc_ue; AUE_LOCK(sc); - aue_stop(sc); + aue_stop(ue); AUE_UNLOCK(sc); return (0); } Modified: user/thompsa/usb/sys/dev/usb2/ethernet/if_auereg.h ============================================================================== --- user/thompsa/usb/sys/dev/usb2/ethernet/if_auereg.h Sat Jan 31 20:46:01 2009 (r187964) +++ user/thompsa/usb/sys/dev/usb2/ethernet/if_auereg.h Sat Jan 31 20:47:27 2009 (r187965) @@ -186,8 +186,7 @@ enum { #define AUE_RXSTAT_DRIBBLE 0x10 #define AUE_RXSTAT_MASK 0x1E -#define GET_MII(sc) ((sc)->sc_miibus ? \ - device_get_softc((sc)->sc_miibus) : NULL) +#define GET_MII(sc) usb2_ether_getmii(&(sc)->sc_ue) struct aue_intrpkt { uint8_t aue_txstat0; @@ -202,26 +201,17 @@ struct aue_intrpkt { struct aue_rxpkt { uint16_t aue_pktlen; uint8_t aue_rxstat; + uint8_t pad; } __packed; struct aue_softc { - struct ifnet *sc_ifp; - struct usb2_process sc_tq; - struct usb2_callout sc_watchdog; - struct mtx sc_mtx; - struct aue_rxpkt sc_rxpkt; - - struct usb2_device *sc_udev; - struct usb2_xfer *sc_xfer[AUE_N_TRANSFER]; - device_t sc_miibus; - device_t sc_dev; - - struct usb2_task sc_media_task; - struct usb2_task sc_multi_task; - struct usb2_task sc_promisc_task; - struct usb2_task sc_tick_task; + struct usb2_ether sc_ue; + struct mtx sc_mtx; + struct usb2_device *sc_udev; + struct usb2_xfer *sc_xfer[AUE_N_TRANSFER]; + device_t sc_dev; - uint16_t sc_flags; + int sc_flags; #define AUE_FLAG_LSYS 0x0001 /* use Linksys reset */ #define AUE_FLAG_PNA 0x0002 /* has Home PNA */ #define AUE_FLAG_PII 0x0004 /* Pegasus II chip */ Modified: user/thompsa/usb/sys/dev/usb2/ethernet/if_axe2.c ============================================================================== --- user/thompsa/usb/sys/dev/usb2/ethernet/if_axe2.c Sat Jan 31 20:46:01 2009 (r187964) +++ user/thompsa/usb/sys/dev/usb2/ethernet/if_axe2.c Sat Jan 31 20:47:27 2009 (r187965) @@ -164,21 +164,15 @@ static miibus_readreg_t axe_miibus_readr static miibus_writereg_t axe_miibus_writereg; static miibus_statchg_t axe_miibus_statchg; -static usb2_task_fn_t axe_promisc_task; -static usb2_task_fn_t axe_setmulti_task; -static usb2_task_fn_t axe_ifmedia_task; -static usb2_task_fn_t axe_tick_task; - -static int axe_ioctl(struct ifnet *, u_long, caddr_t); -static void axe_init(void *); -static void axe_init_locked(struct axe_softc *); -static void axe_stop(struct axe_softc *); -static int axe_cmd(struct axe_softc *, int, int, int, void *); +static void axe_init(struct usb2_ether *); +static void axe_stop(struct usb2_ether *); +static void axe_start(struct usb2_ether *); +static void axe_tick(struct usb2_ether *); +static void axe_setmulti(struct usb2_ether *); +static void axe_setpromisc(struct usb2_ether *); static int axe_ifmedia_upd(struct ifnet *); static void axe_ifmedia_sts(struct ifnet *, struct ifmediareq *); -static void axe_start(struct ifnet *); -static void axe_start_transfers(struct axe_softc *); -static void axe_watchdog(void *); +static int axe_cmd(struct axe_softc *, int, int, int, void *); static void axe_ax88178_init(struct axe_softc *); static void axe_ax88772_init(struct axe_softc *); static int axe_get_phyno(struct axe_softc *, int); @@ -312,20 +306,14 @@ axe_miibus_readreg(device_t dev, int phy { struct axe_softc *sc = device_get_softc(dev); uint16_t val; - int do_unlock; + int locked; - /* avoid recursive locking */ - if (mtx_owned(&sc->sc_mtx)) { - do_unlock = 0; - } else { - AXE_LOCK(sc); - do_unlock = 1; - } + if (sc->sc_phyno != phy) + return (0); - if (sc->sc_phyno != phy) { - val = 0; - goto done; - } + locked = mtx_owned(&sc->sc_mtx); + if (!locked) + AXE_LOCK(sc); axe_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL); axe_cmd(sc, AXE_CMD_MII_READ_REG, reg, phy, &val); @@ -342,8 +330,7 @@ axe_miibus_readreg(device_t dev, int phy val &= ~BMSR_EXTCAP; } -done: - if (do_unlock) + if (!locked) AXE_UNLOCK(sc); return (val); } @@ -352,29 +339,23 @@ static int axe_miibus_writereg(device_t dev, int phy, int reg, int val) { struct axe_softc *sc = device_get_softc(dev); - int do_unlock; + int locked; val = htole16(val); - /* avoid recursive locking */ - if (mtx_owned(&sc->sc_mtx)) { - do_unlock = 0; - } else { - AXE_LOCK(sc); - do_unlock = 1; - } - if (sc->sc_phyno != phy) - goto done; + return (val); + + locked = mtx_owned(&sc->sc_mtx); + if (!locked) + AXE_LOCK(sc); axe_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL); axe_cmd(sc, AXE_CMD_MII_WRITE_REG, reg, phy, &val); axe_cmd(sc, AXE_CMD_MII_OPMODE_HW, 0, 0, NULL); -done: - if (do_unlock) { + if (!locked) AXE_UNLOCK(sc); - } return (0); } @@ -384,15 +365,11 @@ axe_miibus_statchg(device_t dev) struct axe_softc *sc = device_get_softc(dev); struct mii_data *mii = GET_MII(sc); uint16_t val; - int err, do_unlock; + int err, locked; - /* avoid recursive locking */ - if (mtx_owned(&sc->sc_mtx)) { - do_unlock = 0; - } else { + locked = mtx_owned(&sc->sc_mtx); + if (!locked) AXE_LOCK(sc); - do_unlock = 1; - } val = (mii->mii_media_active & IFM_GMASK) == IFM_FDX ? AXE_MEDIA_FULL_DUPLEX : 0; @@ -415,7 +392,7 @@ axe_miibus_statchg(device_t dev) if (err) device_printf(dev, "media change failed, error %d\n", err); - if (do_unlock) + if (!locked) AXE_UNLOCK(sc); } @@ -426,17 +403,10 @@ static int axe_ifmedia_upd(struct ifnet *ifp) { struct axe_softc *sc = ifp->if_softc; - - usb2_proc_enqueue(&sc->sc_tq, &sc->sc_media_task); - return (0); -} - -static void -axe_ifmedia_task(void *context, struct usb2_task *task) -{ - struct axe_softc *sc = context; struct mii_data *mii = GET_MII(sc); + AXE_LOCK_ASSERT(sc, MA_OWNED); + sc->sc_flags &= ~AXE_FLAG_LINK; if (mii->mii_instance) { struct mii_softc *miisc; @@ -445,6 +415,7 @@ axe_ifmedia_task(void *context, struct u mii_phy_reset(miisc); } mii_mediachg(mii); + return (0); } /* @@ -464,14 +435,17 @@ axe_ifmedia_sts(struct ifnet *ifp, struc } static void -axe_setmulti(struct axe_softc *sc) +axe_setmulti(struct usb2_ether *ue) { - struct ifnet *ifp = sc->sc_ifp; + struct axe_softc *sc = usb2_ether_getsc(ue); + struct ifnet *ifp = usb2_ether_getifp(ue); struct ifmultiaddr *ifma; uint32_t h = 0; uint16_t rxmode; uint8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + AXE_LOCK_ASSERT(sc, MA_OWNED); + axe_cmd(sc, AXE_CMD_RXCTL_READ, 0, 0, &rxmode); rxmode = le16toh(rxmode); @@ -661,7 +635,7 @@ axe_attach(device_t dev) { struct usb2_attach_arg *uaa = device_get_ivars(dev); struct axe_softc *sc = device_get_softc(dev); - struct ifnet *ifp; + struct usb2_ether *ue = &sc->sc_ue; uint8_t eaddr[ETHER_ADDR_LEN]; uint8_t iface_index; int error; @@ -673,27 +647,14 @@ axe_attach(device_t dev) device_set_usb2_desc(dev); mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF); - usb2_callout_init_mtx(&sc->sc_watchdog, &sc->sc_mtx, 0); - - USB_TASK_INIT(&sc->sc_promisc_task, axe_promisc_task, sc, &sc->sc_mtx); - USB_TASK_INIT(&sc->sc_multi_task, axe_setmulti_task, sc, &sc->sc_mtx); - USB_TASK_INIT(&sc->sc_media_task, axe_ifmedia_task, sc, &sc->sc_mtx); - USB_TASK_INIT(&sc->sc_tick_task, axe_tick_task, sc, &sc->sc_mtx); iface_index = AXE_IFACE_IDX; - error = usb2_transfer_setup(uaa->device, &iface_index, - sc->sc_xfer, axe_config, AXE_N_TRANSFER, - sc, &sc->sc_mtx); + error = usb2_transfer_setup(uaa->device, &iface_index, sc->sc_xfer, + axe_config, AXE_N_TRANSFER, sc, &sc->sc_mtx); if (error) { device_printf(dev, "allocating USB transfers failed!\n"); goto detach; } - error = usb2_proc_create(&sc->sc_tq, USB_PRI_MED, - device_get_nameunit(dev)); - if (error) { - device_printf(dev, "could not setup config thread\n"); - goto detach; - } /* * Load PHY indexes first. Needed by axe_xxx_init(). @@ -732,34 +693,23 @@ axe_attach(device_t dev) axe_cmd(sc, AXE_CMD_READ_IPG012, 0, 0, sc->sc_ipgs); AXE_UNLOCK(sc); - ifp = if_alloc(IFT_ETHER); - + ue->ue_sc = sc; + ue->ue_dev = dev; + ue->ue_mtx = &sc->sc_mtx; + ue->ue_start = axe_start; + ue->ue_init = axe_init; + ue->ue_stop = axe_stop; + ue->ue_tick = axe_tick; + ue->ue_setmulti = axe_setmulti; + ue->ue_setpromisc = axe_setpromisc; + ue->ue_mii_upd = axe_ifmedia_upd; + ue->ue_mii_sts = axe_ifmedia_sts; - if (ifp == NULL) { - device_printf(dev, "could not if_alloc()\n"); - goto detach; - } - ifp->if_softc = sc; - if_initname(ifp, device_get_name(dev), device_get_unit(dev)); - ifp->if_mtu = ETHERMTU; - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_ioctl = axe_ioctl; - ifp->if_start = axe_start; - ifp->if_init = axe_init; - IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); - ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; - IFQ_SET_READY(&ifp->if_snd); - sc->sc_ifp = ifp; - - error = mii_phy_probe(dev, &sc->sc_miibus, - axe_ifmedia_upd, axe_ifmedia_sts); + error = usb2_ether_ifattach(ue, eaddr); if (error) { - device_printf(dev, "MII without any PHY!\n"); + device_printf(dev, "could not attach interface\n"); goto detach; } - - ether_ifattach(ifp, eaddr); - return (0); /* success */ detach: *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***