summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb/if_aue.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/usb/if_aue.c')
-rw-r--r--sys/dev/usb/if_aue.c147
1 files changed, 81 insertions, 66 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;
}
OpenPOWER on IntegriCloud