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.
This commit is contained in:
Bill Paul 2000-10-24 22:38:54 +00:00
parent f6ee793a3c
commit f709eddf9f
7 changed files with 232 additions and 176 deletions

View file

@ -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)
AUE_LOCK(sc);
if (ifp->if_flags & IFF_RUNNING) {
AUE_UNLOCK(sc);
return;
s = splimp();
}
/*
* 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;
}

View file

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

View file

@ -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;
}

View file

@ -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)

View file

@ -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;
}

View file

@ -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)

View file

@ -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;
}