diff options
author | Bill Paul <wpaul@FreeBSD.org> | 2000-10-24 22:38:54 +0000 |
---|---|---|
committer | Bill Paul <wpaul@FreeBSD.org> | 2000-10-24 22:38:54 +0000 |
commit | f709eddf9f659d547c5b75b659863bf98e422ba8 (patch) | |
tree | d45d37c7e54d8abe8101129adfaedb70ab43ae11 /sys/dev | |
parent | f6ee793a3c33d4aaaaff00dd22abc63deab6426e (diff) | |
download | src-f709eddf9f659d547c5b75b659863bf98e422ba8.tar.gz src-f709eddf9f659d547c5b75b659863bf98e422ba8.zip |
Convert the USB ethernet drivers to use mutexes. Also convert
usb_ethersubr.c. This module maintains two queues for packets which
are each protected with one mutex. These are all the changes I can
do for now. Removing the USBD_NO_TSLEEP flag doesn't work yet: when
I tried it, the system would usually freeze up after a NIC had been
operating for a while. The usb_ethersubr module itself ought to
go away; this is the next thing I need to test.
Notes
Notes:
svn path=/head/; revision=67530
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/usb/if_aue.c | 147 | ||||
-rw-r--r-- | sys/dev/usb/if_auereg.h | 4 | ||||
-rw-r--r-- | sys/dev/usb/if_cue.c | 127 | ||||
-rw-r--r-- | sys/dev/usb/if_cuereg.h | 4 | ||||
-rw-r--r-- | sys/dev/usb/if_kue.c | 93 | ||||
-rw-r--r-- | sys/dev/usb/if_kuereg.h | 4 | ||||
-rw-r--r-- | sys/dev/usb/usb_ethersubr.c | 29 |
7 files changed, 232 insertions, 176 deletions
diff --git a/sys/dev/usb/if_aue.c b/sys/dev/usb/if_aue.c index e88962b1660c..0c58f2a546db 100644 --- a/sys/dev/usb/if_aue.c +++ b/sys/dev/usb/if_aue.c @@ -208,12 +208,11 @@ Static int csr_read_1(sc, reg) usb_device_request_t req; usbd_status err; u_int8_t val = 0; - int s; if (sc->aue_gone) return(0); - s = splusb(); + AUE_LOCK(sc); req.bmRequestType = UT_READ_VENDOR_DEVICE; req.bRequest = AUE_UR_READREG; @@ -224,7 +223,7 @@ Static int csr_read_1(sc, reg) err = usbd_do_request_flags(sc->aue_udev, &req, &val, USBD_NO_TSLEEP, NULL); - splx(s); + AUE_UNLOCK(sc); if (err) return(0); @@ -239,12 +238,11 @@ Static int csr_read_2(sc, reg) usb_device_request_t req; usbd_status err; u_int16_t val = 0; - int s; if (sc->aue_gone) return(0); - s = splusb(); + AUE_LOCK(sc); req.bmRequestType = UT_READ_VENDOR_DEVICE; req.bRequest = AUE_UR_READREG; @@ -255,7 +253,7 @@ Static int csr_read_2(sc, reg) err = usbd_do_request_flags(sc->aue_udev, &req, &val, USBD_NO_TSLEEP, NULL); - splx(s); + AUE_UNLOCK(sc); if (err) return(0); @@ -269,12 +267,11 @@ Static int csr_write_1(sc, reg, val) { usb_device_request_t req; usbd_status err; - int s; if (sc->aue_gone) return(0); - s = splusb(); + AUE_LOCK(sc); req.bmRequestType = UT_WRITE_VENDOR_DEVICE; req.bRequest = AUE_UR_WRITEREG; @@ -285,7 +282,7 @@ Static int csr_write_1(sc, reg, val) err = usbd_do_request_flags(sc->aue_udev, &req, &val, USBD_NO_TSLEEP, NULL); - splx(s); + AUE_UNLOCK(sc); if (err) return(-1); @@ -299,12 +296,11 @@ Static int csr_write_2(sc, reg, val) { usb_device_request_t req; usbd_status err; - int s; if (sc->aue_gone) return(0); - s = splusb(); + AUE_LOCK(sc); req.bmRequestType = UT_WRITE_VENDOR_DEVICE; req.bRequest = AUE_UR_WRITEREG; @@ -315,7 +311,7 @@ Static int csr_write_2(sc, reg, val) err = usbd_do_request_flags(sc->aue_udev, &req, &val, USBD_NO_TSLEEP, NULL); - splx(s); + AUE_UNLOCK(sc); if (err) return(-1); @@ -631,7 +627,6 @@ USB_ATTACH(aue) { USB_ATTACH_START(aue, sc, uaa); char devinfo[1024]; - int s; u_char eaddr[ETHER_ADDR_LEN]; struct ifnet *ifp; usb_interface_descriptor_t *id; @@ -639,8 +634,6 @@ USB_ATTACH(aue) int i; struct aue_type *t; - s = splimp(); - bzero(sc, sizeof(struct aue_softc)); sc->aue_iface = uaa->iface; sc->aue_udev = uaa->device; @@ -649,7 +642,6 @@ USB_ATTACH(aue) if (usbd_set_config_no(sc->aue_udev, AUE_CONFIG_NO, 0)) { printf("aue%d: getting interface handle failed\n", sc->aue_unit); - splx(s); USB_ATTACH_ERROR_RETURN; } @@ -675,7 +667,6 @@ USB_ATTACH(aue) if (!ed) { printf("aue%d: couldn't get ep %d\n", sc->aue_unit, i); - splx(s); USB_ATTACH_ERROR_RETURN; } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && @@ -690,6 +681,9 @@ USB_ATTACH(aue) } } + mtx_init(&sc->aue_mtx, device_get_nameunit(self), MTX_DEF); + AUE_LOCK(sc); + /* Reset the adapter. */ aue_reset(sc); @@ -735,7 +729,8 @@ USB_ATTACH(aue) if (mii_phy_probe(self, &sc->aue_miibus, aue_ifmedia_upd, aue_ifmedia_sts)) { printf("aue%d: MII without any PHY!\n", sc->aue_unit); - splx(s); + AUE_UNLOCK(sc); + mtx_destroy(&sc->aue_mtx); USB_ATTACH_ERROR_RETURN; } @@ -750,7 +745,7 @@ USB_ATTACH(aue) usb_register_netisr(); sc->aue_gone = 0; - splx(s); + AUE_UNLOCK(sc); USB_ATTACH_SUCCESS_RETURN; } @@ -759,11 +754,9 @@ Static int aue_detach(dev) { struct aue_softc *sc; struct ifnet *ifp; - int s; - - s = splusb(); sc = device_get_softc(dev); + AUE_LOCK(sc); ifp = &sc->arpcom.ac_if; sc->aue_gone = 1; @@ -778,7 +771,9 @@ Static int aue_detach(dev) if (sc->aue_ep[AUE_ENDPT_INTR] != NULL) usbd_abort_pipe(sc->aue_ep[AUE_ENDPT_INTR]); #endif - splx(s); + + AUE_UNLOCK(sc); + mtx_destroy(&sc->aue_mtx); return(0); } @@ -880,28 +875,26 @@ Static void aue_intr(xfer, priv, status) struct aue_softc *sc; struct ifnet *ifp; struct aue_intrpkt *p; - int s; - - s = splimp(); sc = priv; + AUE_LOCK(sc); ifp = &sc->arpcom.ac_if; if (!(ifp->if_flags & IFF_RUNNING)) { - splx(s); + AUE_UNLOCK(sc); return; } if (status != USBD_NORMAL_COMPLETION) { if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { - splx(s); + AUE_UNLOCK(sc); return; } printf("aue%d: usb error on intr: %s\n", sc->aue_unit, usbd_errstr(status)); if (status == USBD_STALLED) usbd_clear_endpoint_stall(sc->aue_ep[AUE_ENDPT_RX]); - splx(s); + AUE_UNLOCK(sc); return; } @@ -913,7 +906,7 @@ Static void aue_intr(xfer, priv, status) if (p->aue_txstat0 & (AUE_TXSTAT0_LATECOLL & AUE_TXSTAT0_EXCESSCOLL)) ifp->if_collisions++; - splx(s); + AUE_UNLOCK(sc); return; } #endif @@ -925,10 +918,12 @@ Static void aue_rxstart(ifp) struct aue_chain *c; sc = ifp->if_softc; + AUE_LOCK(sc); c = &sc->aue_cdata.aue_rx_chain[sc->aue_cdata.aue_rx_prod]; if (aue_newbuf(sc, c, NULL) == ENOBUFS) { ifp->if_ierrors++; + AUE_UNLOCK(sc); return; } @@ -938,6 +933,7 @@ Static void aue_rxstart(ifp) USBD_NO_TIMEOUT, aue_rxeof); usbd_transfer(c->aue_xfer); + AUE_UNLOCK(sc); return; } @@ -959,14 +955,21 @@ Static void aue_rxeof(xfer, priv, status) c = priv; sc = c->aue_sc; + if (sc->aue_gone) + return; + AUE_LOCK(sc); ifp = &sc->arpcom.ac_if; - if (!(ifp->if_flags & IFF_RUNNING)) + if (!(ifp->if_flags & IFF_RUNNING)) { + AUE_UNLOCK(sc); return; + } if (status != USBD_NORMAL_COMPLETION) { - if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) + if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { + AUE_UNLOCK(sc); return; + } printf("aue%d: usb error on rx: %s\n", sc->aue_unit, usbd_errstr(status)); if (status == USBD_STALLED) @@ -1001,7 +1004,7 @@ Static void aue_rxeof(xfer, priv, status) /* Put the packet on the special USB input queue. */ usb_ether_input(m); - + AUE_UNLOCK(sc); return; done: @@ -1011,6 +1014,7 @@ done: USBD_NO_TIMEOUT, aue_rxeof); usbd_transfer(xfer); + AUE_UNLOCK(sc); return; } @@ -1028,24 +1032,22 @@ Static void aue_txeof(xfer, priv, status) struct aue_chain *c; struct ifnet *ifp; usbd_status err; - int s; - - s = splimp(); c = priv; sc = c->aue_sc; + AUE_LOCK(sc); ifp = &sc->arpcom.ac_if; if (status != USBD_NORMAL_COMPLETION) { if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { - splx(s); + AUE_UNLOCK(sc); return; } printf("aue%d: usb error on tx: %s\n", sc->aue_unit, usbd_errstr(status)); if (status == USBD_STALLED) usbd_clear_endpoint_stall(sc->aue_ep[AUE_ENDPT_TX]); - splx(s); + AUE_UNLOCK(sc); return; } @@ -1064,7 +1066,7 @@ Static void aue_txeof(xfer, priv, status) else ifp->if_opackets++; - splx(s); + AUE_UNLOCK(sc); return; } @@ -1075,21 +1077,18 @@ Static void aue_tick(xsc) struct aue_softc *sc; struct ifnet *ifp; struct mii_data *mii; - int s; - - s = splimp(); sc = xsc; - if (sc == NULL) { - splx(s); + if (sc == NULL) return; - } + + AUE_LOCK(sc); ifp = &sc->arpcom.ac_if; mii = device_get_softc(sc->aue_miibus); if (mii == NULL) { - splx(s); + AUE_UNLOCK(sc); return; } @@ -1105,7 +1104,7 @@ Static void aue_tick(xsc) sc->aue_stat_ch = timeout(aue_tick, sc, hz); - splx(s); + AUE_UNLOCK(sc); return; } @@ -1162,20 +1161,28 @@ Static void aue_start(ifp) struct mbuf *m_head = NULL; sc = ifp->if_softc; + AUE_LOCK(sc); - if (!sc->aue_link) + if (!sc->aue_link) { + AUE_UNLOCK(sc); return; + } - if (ifp->if_flags & IFF_OACTIVE) + if (ifp->if_flags & IFF_OACTIVE) { + AUE_UNLOCK(sc); return; + } IF_DEQUEUE(&ifp->if_snd, m_head); - if (m_head == NULL) + if (m_head == NULL) { + AUE_UNLOCK(sc); return; + } if (aue_encap(sc, m_head, 0)) { IF_PREPEND(&ifp->if_snd, m_head); ifp->if_flags |= IFF_OACTIVE; + AUE_UNLOCK(sc); return; } @@ -1192,6 +1199,7 @@ Static void aue_start(ifp) * Set a timeout in case the chip goes out to lunch. */ ifp->if_timer = 5; + AUE_UNLOCK(sc); return; } @@ -1204,12 +1212,14 @@ Static void aue_init(xsc) struct mii_data *mii; struct aue_chain *c; usbd_status err; - int i, s; + int i; - if (ifp->if_flags & IFF_RUNNING) - return; + AUE_LOCK(sc); - s = splimp(); + if (ifp->if_flags & IFF_RUNNING) { + AUE_UNLOCK(sc); + return; + } /* * Cancel pending I/O and free all RX/TX buffers. @@ -1232,14 +1242,14 @@ Static void aue_init(xsc) /* Init TX ring. */ if (aue_tx_list_init(sc) == ENOBUFS) { printf("aue%d: tx list init failed\n", sc->aue_unit); - splx(s); + AUE_UNLOCK(sc); return; } /* Init RX ring. */ if (aue_rx_list_init(sc) == ENOBUFS) { printf("aue%d: rx list init failed\n", sc->aue_unit); - splx(s); + AUE_UNLOCK(sc); return; } @@ -1262,7 +1272,7 @@ Static void aue_init(xsc) if (err) { printf("aue%d: open rx pipe failed: %s\n", sc->aue_unit, usbd_errstr(err)); - splx(s); + AUE_UNLOCK(sc); return; } err = usbd_open_pipe(sc->aue_iface, sc->aue_ed[AUE_ENDPT_TX], @@ -1270,7 +1280,7 @@ Static void aue_init(xsc) if (err) { printf("aue%d: open tx pipe failed: %s\n", sc->aue_unit, usbd_errstr(err)); - splx(s); + AUE_UNLOCK(sc); return; } @@ -1282,7 +1292,7 @@ Static void aue_init(xsc) if (err) { printf("aue%d: open intr pipe failed: %s\n", sc->aue_unit, usbd_errstr(err)); - splx(s); + AUE_UNLOCK(sc); return; } #endif @@ -1299,10 +1309,10 @@ Static void aue_init(xsc) ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; - (void)splx(s); - sc->aue_stat_ch = timeout(aue_tick, sc, hz); + AUE_UNLOCK(sc); + return; } @@ -1358,9 +1368,9 @@ Static int aue_ioctl(ifp, command, data) struct aue_softc *sc = ifp->if_softc; struct ifreq *ifr = (struct ifreq *) data; struct mii_data *mii; - int s, error = 0; + int error = 0; - s = splimp(); + AUE_LOCK(sc); switch(command) { case SIOCSIFADDR: @@ -1402,7 +1412,7 @@ Static int aue_ioctl(ifp, command, data) break; } - (void)splx(s); + AUE_UNLOCK(sc); return(error); } @@ -1415,6 +1425,7 @@ Static void aue_watchdog(ifp) usbd_status stat; sc = ifp->if_softc; + AUE_LOCK(sc); ifp->if_oerrors++; printf("aue%d: watchdog timeout\n", sc->aue_unit); @@ -1425,7 +1436,7 @@ Static void aue_watchdog(ifp) if (ifp->if_snd.ifq_head != NULL) aue_start(ifp); - + AUE_UNLOCK(sc); return; } @@ -1440,6 +1451,7 @@ Static void aue_stop(sc) struct ifnet *ifp; int i; + AUE_LOCK(sc); ifp = &sc->arpcom.ac_if; ifp->if_timer = 0; @@ -1533,6 +1545,7 @@ Static void aue_stop(sc) sc->aue_link = 0; ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); + AUE_UNLOCK(sc); return; } @@ -1547,9 +1560,11 @@ Static void aue_shutdown(dev) struct aue_softc *sc; sc = device_get_softc(dev); - + sc->aue_gone++; + AUE_LOCK(sc); aue_reset(sc); aue_stop(sc); + AUE_UNLOCK(sc); return; } diff --git a/sys/dev/usb/if_auereg.h b/sys/dev/usb/if_auereg.h index 9e4d5467798a..5558b503c759 100644 --- a/sys/dev/usb/if_auereg.h +++ b/sys/dev/usb/if_auereg.h @@ -246,8 +246,12 @@ struct aue_softc { int aue_if_flags; struct aue_cdata aue_cdata; struct callout_handle aue_stat_ch; + struct mtx aue_mtx; }; +#define AUE_LOCK(_sc) mtx_enter(&(_sc)->aue_mtx, MTX_DEF) +#define AUE_UNLOCK(_sc) mtx_exit(&(_sc)->aue_mtx, MTX_DEF) + #define AUE_TIMEOUT 1000 #define ETHER_ALIGN 2 #define AUE_BUFSZ 1536 diff --git a/sys/dev/usb/if_cue.c b/sys/dev/usb/if_cue.c index a55b01a9d5c9..c62a0d708e72 100644 --- a/sys/dev/usb/if_cue.c +++ b/sys/dev/usb/if_cue.c @@ -162,12 +162,11 @@ Static int csr_read_1(sc, reg) usb_device_request_t req; usbd_status err; u_int8_t val = 0; - int s; if (sc->cue_gone) return(0); - s = splusb(); + CUE_LOCK(sc); req.bmRequestType = UT_READ_VENDOR_DEVICE; req.bRequest = CUE_CMD_READREG; @@ -178,7 +177,7 @@ Static int csr_read_1(sc, reg) err = usbd_do_request_flags(sc->cue_udev, &req, &val, USBD_NO_TSLEEP, NULL); - splx(s); + CUE_UNLOCK(sc); if (err) return(0); @@ -193,12 +192,11 @@ Static int csr_read_2(sc, reg) usb_device_request_t req; usbd_status err; u_int16_t val = 0; - int s; if (sc->cue_gone) return(0); - s = splusb(); + CUE_LOCK(sc); req.bmRequestType = UT_READ_VENDOR_DEVICE; req.bRequest = CUE_CMD_READREG; @@ -209,7 +207,7 @@ Static int csr_read_2(sc, reg) err = usbd_do_request_flags(sc->cue_udev, &req, &val, USBD_NO_TSLEEP, NULL); - splx(s); + CUE_UNLOCK(sc); if (err) return(0); @@ -223,12 +221,11 @@ Static int csr_write_1(sc, reg, val) { usb_device_request_t req; usbd_status err; - int s; if (sc->cue_gone) return(0); - s = splusb(); + CUE_LOCK(sc); req.bmRequestType = UT_WRITE_VENDOR_DEVICE; req.bRequest = CUE_CMD_WRITEREG; @@ -239,7 +236,7 @@ Static int csr_write_1(sc, reg, val) err = usbd_do_request_flags(sc->cue_udev, &req, &val, USBD_NO_TSLEEP, NULL); - splx(s); + CUE_UNLOCK(sc); if (err) return(-1); @@ -254,12 +251,11 @@ Static int csr_write_2(sc, reg, val) { usb_device_request_t req; usbd_status err; - int s; if (sc->cue_gone) return(0); - s = splusb(); + CUE_LOCK(sc); req.bmRequestType = UT_WRITE_VENDOR_DEVICE; req.bRequest = CUE_CMD_WRITEREG; @@ -270,7 +266,7 @@ Static int csr_write_2(sc, reg, val) err = usbd_do_request_flags(sc->cue_udev, &req, &val, USBD_NO_TSLEEP, NULL); - splx(s); + CUE_UNLOCK(sc); if (err) return(-1); @@ -288,12 +284,11 @@ Static int cue_mem(sc, cmd, addr, buf, len) { usb_device_request_t req; usbd_status err; - int s; if (sc->cue_gone) return(0); - s = splusb(); + CUE_LOCK(sc); if (cmd == CUE_CMD_READSRAM) req.bmRequestType = UT_READ_VENDOR_DEVICE; @@ -307,7 +302,7 @@ Static int cue_mem(sc, cmd, addr, buf, len) err = usbd_do_request_flags(sc->cue_udev, &req, &buf, USBD_NO_TSLEEP, NULL); - splx(s); + CUE_UNLOCK(sc); if (err) return(-1); @@ -321,12 +316,11 @@ Static int cue_getmac(sc, buf) { usb_device_request_t req; usbd_status err; - int s; if (sc->cue_gone) return(0); - s = splusb(); + CUE_LOCK(sc); req.bmRequestType = UT_READ_VENDOR_DEVICE; req.bRequest = CUE_CMD_GET_MACADDR; @@ -337,7 +331,7 @@ Static int cue_getmac(sc, buf) err = usbd_do_request_flags(sc->cue_udev, &req, buf, USBD_NO_TSLEEP, NULL); - splx(s); + CUE_UNLOCK(sc); if (err) { printf("cue%d: read MAC address failed\n", sc->cue_unit); @@ -416,13 +410,10 @@ Static void cue_reset(sc) { usb_device_request_t req; usbd_status err; - int s; if (sc->cue_gone) return; - s = splusb(); - req.bmRequestType = UT_WRITE_VENDOR_DEVICE; req.bRequest = CUE_CMD_RESET; USETW(req.wValue, 0); @@ -431,8 +422,6 @@ Static void cue_reset(sc) err = usbd_do_request_flags(sc->cue_udev, &req, NULL, USBD_NO_TSLEEP, NULL); - splx(s); - if (err) printf("cue%d: reset failed\n", sc->cue_unit); @@ -472,15 +461,12 @@ USB_ATTACH(cue) { USB_ATTACH_START(cue, sc, uaa); char devinfo[1024]; - int s; u_char eaddr[ETHER_ADDR_LEN]; struct ifnet *ifp; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; int i; - s = splimp(); - bzero(sc, sizeof(struct cue_softc)); sc->cue_iface = uaa->iface; sc->cue_udev = uaa->device; @@ -489,7 +475,6 @@ USB_ATTACH(cue) if (usbd_set_config_no(sc->cue_udev, CUE_CONFIG_NO, 0)) { printf("cue%d: getting interface handle failed\n", sc->cue_unit); - splx(s); USB_ATTACH_ERROR_RETURN; } @@ -505,7 +490,6 @@ USB_ATTACH(cue) if (!ed) { printf("cue%d: couldn't get ep %d\n", sc->cue_unit, i); - splx(s); USB_ATTACH_ERROR_RETURN; } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && @@ -520,6 +504,9 @@ USB_ATTACH(cue) } } + mtx_init(&sc->cue_mtx, device_get_nameunit(self), MTX_DEF); + CUE_LOCK(sc); + #ifdef notdef /* Reset the adapter. */ cue_reset(sc); @@ -561,7 +548,7 @@ USB_ATTACH(cue) usb_register_netisr(); sc->cue_gone = 0; - splx(s); + CUE_UNLOCK(sc); USB_ATTACH_SUCCESS_RETURN; } @@ -570,11 +557,9 @@ Static int cue_detach(dev) { struct cue_softc *sc; struct ifnet *ifp; - int s; - - s = splusb(); sc = device_get_softc(dev); + CUE_LOCK(sc); ifp = &sc->arpcom.ac_if; sc->cue_gone = 1; @@ -588,7 +573,8 @@ Static int cue_detach(dev) if (sc->cue_ep[CUE_ENDPT_INTR] != NULL) usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_INTR]); - splx(s); + CUE_UNLOCK(sc); + mtx_destroy(&sc->cue_mtx); return(0); } @@ -688,10 +674,12 @@ Static void cue_rxstart(ifp) struct cue_chain *c; sc = ifp->if_softc; + CUE_LOCK(sc); c = &sc->cue_cdata.cue_rx_chain[sc->cue_cdata.cue_rx_prod]; if (cue_newbuf(sc, c, NULL) == ENOBUFS) { ifp->if_ierrors++; + CUE_UNLOCK(sc); return; } @@ -700,6 +688,7 @@ Static void cue_rxstart(ifp) c, mtod(c->cue_mbuf, char *), CUE_BUFSZ, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, cue_rxeof); usbd_transfer(c->cue_xfer); + CUE_UNLOCK(sc); return; } @@ -722,14 +711,19 @@ Static void cue_rxeof(xfer, priv, status) c = priv; sc = c->cue_sc; + CUE_LOCK(sc); ifp = &sc->arpcom.ac_if; - if (!(ifp->if_flags & IFF_RUNNING)) + if (!(ifp->if_flags & IFF_RUNNING)) { + CUE_UNLOCK(sc); return; + } if (status != USBD_NORMAL_COMPLETION) { - if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) + if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { + CUE_UNLOCK(sc); return; + } printf("cue%d: usb error on rx: %s\n", sc->cue_unit, usbd_errstr(status)); if (status == USBD_STALLED) @@ -757,6 +751,7 @@ Static void cue_rxeof(xfer, priv, status) /* Put the packet on the special USB input queue. */ usb_ether_input(m); + CUE_UNLOCK(sc); return; done: @@ -765,6 +760,7 @@ done: c, mtod(c->cue_mbuf, char *), CUE_BUFSZ, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, cue_rxeof); usbd_transfer(c->cue_xfer); + CUE_UNLOCK(sc); return; } @@ -783,24 +779,22 @@ Static void cue_txeof(xfer, priv, status) struct cue_chain *c; struct ifnet *ifp; usbd_status err; - int s; - - s = splimp(); c = priv; sc = c->cue_sc; + CUE_LOCK(sc); ifp = &sc->arpcom.ac_if; if (status != USBD_NORMAL_COMPLETION) { if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { - splx(s); + CUE_UNLOCK(sc); return; } printf("cue%d: usb error on tx: %s\n", sc->cue_unit, usbd_errstr(status)); if (status == USBD_STALLED) usbd_clear_endpoint_stall(sc->cue_ep[CUE_ENDPT_TX]); - splx(s); + CUE_UNLOCK(sc); return; } @@ -819,7 +813,7 @@ Static void cue_txeof(xfer, priv, status) else ifp->if_opackets++; - splx(s); + CUE_UNLOCK(sc); return; } @@ -829,16 +823,13 @@ Static void cue_tick(xsc) { struct cue_softc *sc; struct ifnet *ifp; - int s; - - s = splimp(); sc = xsc; - if (sc == NULL) { - splx(s); + if (sc == NULL) return; - } + + CUE_LOCK(sc); ifp = &sc->arpcom.ac_if; @@ -851,7 +842,7 @@ Static void cue_tick(xsc) sc->cue_stat_ch = timeout(cue_tick, sc, hz); - splx(s); + CUE_UNLOCK(sc); return; } @@ -902,17 +893,23 @@ Static void cue_start(ifp) struct mbuf *m_head = NULL; sc = ifp->if_softc; + CUE_LOCK(sc); - if (ifp->if_flags & IFF_OACTIVE) + if (ifp->if_flags & IFF_OACTIVE) { + CUE_UNLOCK(sc); return; + } IF_DEQUEUE(&ifp->if_snd, m_head); - if (m_head == NULL) + if (m_head == NULL) { + CUE_UNLOCK(sc); return; + } if (cue_encap(sc, m_head, 0)) { IF_PREPEND(&ifp->if_snd, m_head); ifp->if_flags |= IFF_OACTIVE; + CUE_UNLOCK(sc); return; } @@ -929,6 +926,7 @@ Static void cue_start(ifp) * Set a timeout in case the chip goes out to lunch. */ ifp->if_timer = 5; + CUE_UNLOCK(sc); return; } @@ -940,12 +938,12 @@ Static void cue_init(xsc) struct ifnet *ifp = &sc->arpcom.ac_if; struct cue_chain *c; usbd_status err; - int i, s; + int i; if (ifp->if_flags & IFF_RUNNING) return; - s = splimp(); + CUE_LOCK(sc); /* * Cancel pending I/O and free all RX/TX buffers. @@ -971,14 +969,14 @@ Static void cue_init(xsc) /* Init TX ring. */ if (cue_tx_list_init(sc) == ENOBUFS) { printf("cue%d: tx list init failed\n", sc->cue_unit); - splx(s); + CUE_UNLOCK(sc); return; } /* Init RX ring. */ if (cue_rx_list_init(sc) == ENOBUFS) { printf("cue%d: rx list init failed\n", sc->cue_unit); - splx(s); + CUE_UNLOCK(sc); return; } @@ -1005,7 +1003,7 @@ Static void cue_init(xsc) if (err) { printf("cue%d: open rx pipe failed: %s\n", sc->cue_unit, usbd_errstr(err)); - splx(s); + CUE_UNLOCK(sc); return; } err = usbd_open_pipe(sc->cue_iface, sc->cue_ed[CUE_ENDPT_TX], @@ -1013,7 +1011,7 @@ Static void cue_init(xsc) if (err) { printf("cue%d: open tx pipe failed: %s\n", sc->cue_unit, usbd_errstr(err)); - splx(s); + CUE_UNLOCK(sc); return; } @@ -1029,7 +1027,7 @@ Static void cue_init(xsc) ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; - (void)splx(s); + CUE_UNLOCK(sc); sc->cue_stat_ch = timeout(cue_tick, sc, hz); @@ -1042,9 +1040,9 @@ Static int cue_ioctl(ifp, command, data) caddr_t data; { struct cue_softc *sc = ifp->if_softc; - int s, error = 0; + int error = 0; - s = splimp(); + CUE_LOCK(sc); switch(command) { case SIOCSIFADDR: @@ -1083,7 +1081,7 @@ Static int cue_ioctl(ifp, command, data) break; } - (void)splx(s); + CUE_UNLOCK(sc); return(error); } @@ -1093,9 +1091,10 @@ Static void cue_watchdog(ifp) { struct cue_softc *sc; struct cue_chain *c; - usbd_status stat; + sc = ifp->if_softc; + CUE_LOCK(sc); ifp->if_oerrors++; printf("cue%d: watchdog timeout\n", sc->cue_unit); @@ -1106,6 +1105,7 @@ Static void cue_watchdog(ifp) if (ifp->if_snd.ifq_head != NULL) cue_start(ifp); + CUE_UNLOCK(sc); return; } @@ -1121,6 +1121,8 @@ Static void cue_stop(sc) struct ifnet *ifp; int i; + CUE_LOCK(sc); + ifp = &sc->arpcom.ac_if; ifp->if_timer = 0; @@ -1204,6 +1206,7 @@ Static void cue_stop(sc) } ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); + CUE_UNLOCK(sc); return; } @@ -1219,8 +1222,10 @@ Static void cue_shutdown(dev) sc = device_get_softc(dev); + CUE_LOCK(sc); cue_reset(sc); cue_stop(sc); + CUE_UNLOCK(sc); return; } diff --git a/sys/dev/usb/if_cuereg.h b/sys/dev/usb/if_cuereg.h index ca90383ccf49..5d043e4d7ad8 100644 --- a/sys/dev/usb/if_cuereg.h +++ b/sys/dev/usb/if_cuereg.h @@ -179,4 +179,8 @@ struct cue_softc { u_int16_t cue_rxfilt; struct cue_cdata cue_cdata; struct callout_handle cue_stat_ch; + struct mtx cue_mtx; }; + +#define CUE_LOCK(_sc) mtx_enter(&(_sc)->cue_mtx, MTX_DEF) +#define CUE_UNLOCK(_sc) mtx_exit(&(_sc)->cue_mtx, MTX_DEF) diff --git a/sys/dev/usb/if_kue.c b/sys/dev/usb/if_kue.c index 0b5f9fb2b339..d0e27df39eff 100644 --- a/sys/dev/usb/if_kue.c +++ b/sys/dev/usb/if_kue.c @@ -203,14 +203,13 @@ Static usbd_status kue_setword(sc, breq, word) usbd_device_handle dev; usb_device_request_t req; usbd_status err; - int s; if (sc->kue_gone) return(USBD_NORMAL_COMPLETION); dev = sc->kue_udev; - s = splusb(); + KUE_LOCK(sc); req.bmRequestType = UT_WRITE_VENDOR_DEVICE; @@ -221,7 +220,7 @@ Static usbd_status kue_setword(sc, breq, word) err = kue_do_request(dev, &req, NULL); - splx(s); + KUE_UNLOCK(sc); return(err); } @@ -237,14 +236,13 @@ Static usbd_status kue_ctl(sc, rw, breq, val, data, len) usbd_device_handle dev; usb_device_request_t req; usbd_status err; - int s; dev = sc->kue_udev; if (sc->kue_gone) return(USBD_NORMAL_COMPLETION); - s = splusb(); + KUE_LOCK(sc); if (rw == KUE_CTL_WRITE) req.bmRequestType = UT_WRITE_VENDOR_DEVICE; @@ -258,7 +256,7 @@ Static usbd_status kue_ctl(sc, rw, breq, val, data, len) err = kue_do_request(dev, &req, data); - splx(s); + KUE_UNLOCK(sc); return(err); } @@ -415,15 +413,12 @@ USB_ATTACH(kue) { USB_ATTACH_START(kue, sc, uaa); char devinfo[1024]; - int s; struct ifnet *ifp; usbd_status err; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; int i; - s = splimp(); - bzero(sc, sizeof(struct kue_softc)); sc->kue_iface = uaa->iface; sc->kue_udev = uaa->device; @@ -441,7 +436,6 @@ USB_ATTACH(kue) if (!ed) { printf("kue%d: couldn't get ep %d\n", sc->kue_unit, i); - splx(s); USB_ATTACH_ERROR_RETURN; } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && @@ -456,9 +450,13 @@ USB_ATTACH(kue) } } + mtx_init(&sc->kue_mtx, device_get_nameunit(self), MTX_DEF); + KUE_LOCK(sc); + /* Load the firmware into the NIC. */ if (kue_load_fw(sc)) { - splx(s); + KUE_UNLOCK(sc); + mtx_destroy(&sc->kue_mtx); USB_ATTACH_ERROR_RETURN; } @@ -505,7 +503,8 @@ USB_ATTACH(kue) usb_register_netisr(); sc->kue_gone = 0; - splx(s); + KUE_UNLOCK(sc); + USB_ATTACH_SUCCESS_RETURN; } @@ -514,11 +513,9 @@ Static int kue_detach(dev) { struct kue_softc *sc; struct ifnet *ifp; - int s; - - s = splusb(); sc = device_get_softc(dev); + KUE_LOCK(sc); ifp = &sc->arpcom.ac_if; sc->kue_gone = 1; @@ -536,7 +533,8 @@ Static int kue_detach(dev) if (sc->kue_mcfilters != NULL) free(sc->kue_mcfilters, M_USBDEV); - splx(s); + KUE_UNLOCK(sc); + mtx_destroy(&sc->kue_mtx); return(0); } @@ -635,6 +633,7 @@ Static void kue_rxstart(ifp) struct kue_chain *c; sc = ifp->if_softc; + KUE_LOCK(sc); c = &sc->kue_cdata.kue_rx_chain[sc->kue_cdata.kue_rx_prod]; if (kue_newbuf(sc, c, NULL) == ENOBUFS) { @@ -648,6 +647,8 @@ Static void kue_rxstart(ifp) USBD_NO_TIMEOUT, kue_rxeof); usbd_transfer(c->kue_xfer); + KUE_UNLOCK(sc); + return; } @@ -669,14 +670,19 @@ Static void kue_rxeof(xfer, priv, status) c = priv; sc = c->kue_sc; + KUE_LOCK(sc); ifp = &sc->arpcom.ac_if; - if (!(ifp->if_flags & IFF_RUNNING)) + if (!(ifp->if_flags & IFF_RUNNING)) { + KUE_UNLOCK(sc); return; + } if (status != USBD_NORMAL_COMPLETION) { - if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) + if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { + KUE_UNLOCK(sc); return; + } printf("kue%d: usb error on rx: %s\n", sc->kue_unit, usbd_errstr(status)); if (status == USBD_STALLED) @@ -706,6 +712,7 @@ Static void kue_rxeof(xfer, priv, status) /* Put the packet on the special USB input queue. */ usb_ether_input(m); + KUE_UNLOCK(sc); return; done: @@ -715,6 +722,7 @@ done: c, mtod(c->kue_mbuf, char *), KUE_BUFSZ, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, kue_rxeof); usbd_transfer(c->kue_xfer); + KUE_UNLOCK(sc); return; } @@ -733,26 +741,25 @@ Static void kue_txeof(xfer, priv, status) struct kue_chain *c; struct ifnet *ifp; usbd_status err; - int s; - - s = splimp(); c = priv; sc = c->kue_sc; + KUE_LOCK(sc); + ifp = &sc->arpcom.ac_if; ifp->if_timer = 0; ifp->if_flags &= ~IFF_OACTIVE; if (status != USBD_NORMAL_COMPLETION) { if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { - splx(s); + KUE_UNLOCK(sc); return; } printf("kue%d: usb error on tx: %s\n", sc->kue_unit, usbd_errstr(status)); if (status == USBD_STALLED) usbd_clear_endpoint_stall(sc->kue_ep[KUE_ENDPT_TX]); - splx(s); + KUE_UNLOCK(sc); return; } @@ -769,7 +776,7 @@ Static void kue_txeof(xfer, priv, status) else ifp->if_opackets++; - splx(s); + KUE_UNLOCK(sc); return; } @@ -821,17 +828,23 @@ Static void kue_start(ifp) struct mbuf *m_head = NULL; sc = ifp->if_softc; + KUE_LOCK(sc); - if (ifp->if_flags & IFF_OACTIVE) + if (ifp->if_flags & IFF_OACTIVE) { + KUE_UNLOCK(sc); return; + } IF_DEQUEUE(&ifp->if_snd, m_head); - if (m_head == NULL) + if (m_head == NULL) { + KUE_UNLOCK(sc); return; + } if (kue_encap(sc, m_head, 0)) { IF_PREPEND(&ifp->if_snd, m_head); ifp->if_flags |= IFF_OACTIVE; + KUE_UNLOCK(sc); return; } @@ -848,6 +861,7 @@ Static void kue_start(ifp) * Set a timeout in case the chip goes out to lunch. */ ifp->if_timer = 5; + KUE_UNLOCK(sc); return; } @@ -859,13 +873,13 @@ Static void kue_init(xsc) struct ifnet *ifp = &sc->arpcom.ac_if; struct kue_chain *c; usbd_status err; - int i, s; + int i; + + KUE_LOCK(sc); if (ifp->if_flags & IFF_RUNNING) return; - s = splimp(); - /* Set MAC address */ kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SET_MAC, 0, sc->arpcom.ac_enaddr, ETHER_ADDR_LEN); @@ -891,14 +905,14 @@ Static void kue_init(xsc) /* Init TX ring. */ if (kue_tx_list_init(sc) == ENOBUFS) { printf("kue%d: tx list init failed\n", sc->kue_unit); - splx(s); + KUE_UNLOCK(sc); return; } /* Init RX ring. */ if (kue_rx_list_init(sc) == ENOBUFS) { printf("kue%d: rx list init failed\n", sc->kue_unit); - splx(s); + KUE_UNLOCK(sc); return; } @@ -911,7 +925,7 @@ Static void kue_init(xsc) if (err) { printf("kue%d: open rx pipe failed: %s\n", sc->kue_unit, usbd_errstr(err)); - splx(s); + KUE_UNLOCK(sc); return; } @@ -920,7 +934,7 @@ Static void kue_init(xsc) if (err) { printf("kue%d: open tx pipe failed: %s\n", sc->kue_unit, usbd_errstr(err)); - splx(s); + KUE_UNLOCK(sc); return; } @@ -936,7 +950,7 @@ Static void kue_init(xsc) ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; - (void)splx(s); + KUE_UNLOCK(sc); return; } @@ -947,9 +961,9 @@ Static int kue_ioctl(ifp, command, data) caddr_t data; { struct kue_softc *sc = ifp->if_softc; - int s, error = 0; + int error = 0; - s = splimp(); + KUE_LOCK(sc); switch(command) { case SIOCSIFADDR: @@ -990,7 +1004,7 @@ Static int kue_ioctl(ifp, command, data) break; } - (void)splx(s); + KUE_UNLOCK(sc); return(error); } @@ -1003,7 +1017,7 @@ Static void kue_watchdog(ifp) usbd_status stat; sc = ifp->if_softc; - + KUE_LOCK(sc); ifp->if_oerrors++; printf("kue%d: watchdog timeout\n", sc->kue_unit); @@ -1013,6 +1027,7 @@ Static void kue_watchdog(ifp) if (ifp->if_snd.ifq_head != NULL) kue_start(ifp); + KUE_UNLOCK(sc); return; } @@ -1028,6 +1043,7 @@ Static void kue_stop(sc) struct ifnet *ifp; int i; + KUE_LOCK(sc); ifp = &sc->arpcom.ac_if; ifp->if_timer = 0; @@ -1107,6 +1123,7 @@ Static void kue_stop(sc) } ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); + KUE_UNLOCK(sc); return; } diff --git a/sys/dev/usb/if_kuereg.h b/sys/dev/usb/if_kuereg.h index 5a315b172d62..49cd23565c64 100644 --- a/sys/dev/usb/if_kuereg.h +++ b/sys/dev/usb/if_kuereg.h @@ -170,4 +170,8 @@ struct kue_softc { u_int16_t kue_rxfilt; u_int8_t *kue_mcfilters; struct kue_cdata kue_cdata; + struct mtx kue_mtx; }; + +#define KUE_LOCK(_sc) mtx_enter(&(_sc)->kue_mtx, MTX_DEF) +#define KUE_UNLOCK(_sc) mtx_exit(&(_sc)->kue_mtx, MTX_DEF) diff --git a/sys/dev/usb/usb_ethersubr.c b/sys/dev/usb/usb_ethersubr.c index da2328c37186..c02ed7dd0cb7 100644 --- a/sys/dev/usb/usb_ethersubr.c +++ b/sys/dev/usb/usb_ethersubr.c @@ -73,7 +73,10 @@ Static const char rcsid[] = #endif Static struct ifqueue usbq_rx; +Static struct mtx usbq_rx_mtx; Static struct ifqueue usbq_tx; +Static struct mtx usbq_tx_mtx; +Static int mtx_inited = 0; Static void usbintr __P((void)); @@ -83,13 +86,12 @@ Static void usbintr() struct mbuf *m; struct usb_qdat *q; struct ifnet *ifp; - int s; - - s = splimp(); /* Check the RX queue */ while(1) { + mtx_enter(&usbq_rx_mtx, MTX_DEF); IF_DEQUEUE(&usbq_rx, m); + mtx_exit(&usbq_rx_mtx, MTX_DEF); if (m == NULL) break; eh = mtod(m, struct ether_header *); @@ -107,7 +109,9 @@ Static void usbintr() /* Check the TX queue */ while(1) { + mtx_enter(&usbq_tx_mtx, MTX_DEF); IF_DEQUEUE(&usbq_tx, m); + mtx_exit(&usbq_tx_mtx, MTX_DEF); if (m == NULL) break; ifp = m->m_pkthdr.rcvif; @@ -116,14 +120,17 @@ Static void usbintr() (*ifp->if_start)(ifp); } - splx(s); - return; } void usb_register_netisr() { + if (mtx_inited) + return; register_netisr(NETISR_USB, usbintr); + mtx_init(&usbq_tx_mtx, "usbq_tx_mtx", MTX_DEF); + mtx_init(&usbq_rx_mtx, "usbq_rx_mtx", MTX_DEF); + mtx_inited++; return; } @@ -134,21 +141,21 @@ void usb_register_netisr() void usb_ether_input(m) struct mbuf *m; { - int s; - s = splimp(); + mtx_enter(&usbq_rx_mtx, MTX_DEF); IF_ENQUEUE(&usbq_rx, m); + mtx_exit(&usbq_rx_mtx, MTX_DEF); schednetisr(NETISR_USB); - splx(s); + return; } void usb_tx_done(m) struct mbuf *m; { - int s; - s = splimp(); + mtx_enter(&usbq_tx_mtx, MTX_DEF); IF_ENQUEUE(&usbq_tx, m); + mtx_exit(&usbq_tx_mtx, MTX_DEF); schednetisr(NETISR_USB); - splx(s); + return; } |