svn commit: r187965 - user/thompsa/usb/sys/dev/usb2/ethernet

Andrew Thompson thompsa at FreeBSD.org
Sat Jan 31 12:47:29 PST 2009


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 ***


More information about the svn-src-user mailing list