mirror of
https://github.com/opnsense/src.git
synced 2026-06-09 00:32:25 -04:00
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:
parent
f6ee793a3c
commit
f709eddf9f
7 changed files with 232 additions and 176 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue