summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorwpaul <wpaul@FreeBSD.org>2000-10-24 22:38:54 +0000
committerwpaul <wpaul@FreeBSD.org>2000-10-24 22:38:54 +0000
commitdeefde18d945622194e19ab0449141b879104d9b (patch)
tree27821821a225a50037f2e42bb26e3efea97acf15 /sys
parent46334203c117eda9e89c8f885354dfc350035a21 (diff)
downloadFreeBSD-src-deefde18d945622194e19ab0449141b879104d9b.zip
FreeBSD-src-deefde18d945622194e19ab0449141b879104d9b.tar.gz
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.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/usb/if_aue.c147
-rw-r--r--sys/dev/usb/if_auereg.h4
-rw-r--r--sys/dev/usb/if_cue.c127
-rw-r--r--sys/dev/usb/if_cuereg.h4
-rw-r--r--sys/dev/usb/if_kue.c93
-rw-r--r--sys/dev/usb/if_kuereg.h4
-rw-r--r--sys/dev/usb/usb_ethersubr.c29
7 files changed, 232 insertions, 176 deletions
diff --git a/sys/dev/usb/if_aue.c b/sys/dev/usb/if_aue.c
index e88962b..0c58f2a 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 9e4d546..5558b50 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 a55b01a..c62a0d7 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 ca90383..5d043e4 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 0b5f9fb..d0e27df 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 5a315b1..49cd235 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 da2328c..c02ed7d 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;
}
OpenPOWER on IntegriCloud