- Streamline detach logic in wlan drivers, so that
freed memory cannot be used during detach. - Remove all panic() calls from the urtw driver because panic() is not appropriate here. - Remove redundant checks for device detached in device detach callbacks. - Use DEVMETHOD_END to mark end of device methods. MFC after: 2 weeks
This commit is contained in:
parent
f5429c7c6e
commit
8dd948244b
@ -542,6 +542,11 @@ rum_detach(device_t self)
|
||||
struct ifnet *ifp = sc->sc_ifp;
|
||||
struct ieee80211com *ic;
|
||||
|
||||
/* Prevent further ioctls */
|
||||
RUM_LOCK(sc);
|
||||
sc->sc_detached = 1;
|
||||
RUM_UNLOCK(sc);
|
||||
|
||||
/* stop all USB transfers */
|
||||
usbd_transfer_unsetup(sc->sc_xfer, RUM_N_TRANSFER);
|
||||
|
||||
@ -556,7 +561,6 @@ rum_detach(device_t self)
|
||||
if_free(ifp);
|
||||
}
|
||||
mtx_destroy(&sc->sc_mtx);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -1321,7 +1325,14 @@ rum_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
struct rum_softc *sc = ifp->if_softc;
|
||||
struct ieee80211com *ic = ifp->if_l2com;
|
||||
struct ifreq *ifr = (struct ifreq *) data;
|
||||
int error = 0, startall = 0;
|
||||
int error;
|
||||
int startall = 0;
|
||||
|
||||
RUM_LOCK(sc);
|
||||
error = sc->sc_detached ? ENXIO : 0;
|
||||
RUM_UNLOCK(sc);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
switch (cmd) {
|
||||
case SIOCSIFFLAGS:
|
||||
@ -2365,8 +2376,7 @@ static device_method_t rum_methods[] = {
|
||||
DEVMETHOD(device_probe, rum_match),
|
||||
DEVMETHOD(device_attach, rum_attach),
|
||||
DEVMETHOD(device_detach, rum_detach),
|
||||
|
||||
{ 0, 0 }
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
static driver_t rum_driver = {
|
||||
|
@ -106,6 +106,7 @@ struct rum_softc {
|
||||
uint32_t rf_regs[4];
|
||||
uint8_t txpow[44];
|
||||
uint8_t sc_bssid[6];
|
||||
uint8_t sc_detached;
|
||||
|
||||
struct {
|
||||
uint8_t val;
|
||||
|
@ -716,11 +716,14 @@ run_detach(device_t self)
|
||||
struct ieee80211com *ic;
|
||||
int i;
|
||||
|
||||
RUN_LOCK(sc);
|
||||
sc->sc_detached = 1;
|
||||
RUN_UNLOCK(sc);
|
||||
|
||||
/* stop all USB transfers */
|
||||
usbd_transfer_unsetup(sc->sc_xfer, RUN_N_XFER);
|
||||
|
||||
RUN_LOCK(sc);
|
||||
|
||||
sc->ratectl_run = RUN_RATECTL_OFF;
|
||||
sc->cmdq_run = sc->cmdq_key_set = RUN_CMDQ_ABORT;
|
||||
|
||||
@ -3441,7 +3444,13 @@ run_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
struct ieee80211com *ic = sc->sc_ifp->if_l2com;
|
||||
struct ifreq *ifr = (struct ifreq *) data;
|
||||
int startall = 0;
|
||||
int error = 0;
|
||||
int error;
|
||||
|
||||
RUN_LOCK(sc);
|
||||
error = sc->sc_detached ? ENXIO : 0;
|
||||
RUN_UNLOCK(sc);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
switch (cmd) {
|
||||
case SIOCSIFFLAGS:
|
||||
@ -4963,8 +4972,7 @@ static device_method_t run_methods[] = {
|
||||
DEVMETHOD(device_probe, run_match),
|
||||
DEVMETHOD(device_attach, run_attach),
|
||||
DEVMETHOD(device_detach, run_detach),
|
||||
|
||||
{ 0, 0 }
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
static driver_t run_driver = {
|
||||
|
@ -239,6 +239,7 @@ struct run_softc {
|
||||
uint8_t sta_running;
|
||||
uint8_t rvp_cnt;
|
||||
uint8_t rvp_bmap;
|
||||
uint8_t sc_detached;
|
||||
|
||||
union {
|
||||
struct run_rx_radiotap_header th;
|
||||
|
@ -504,29 +504,48 @@ uath_detach(device_t dev)
|
||||
struct uath_softc *sc = device_get_softc(dev);
|
||||
struct ifnet *ifp = sc->sc_ifp;
|
||||
struct ieee80211com *ic = ifp->if_l2com;
|
||||
unsigned int x;
|
||||
|
||||
if (!device_is_attached(dev))
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Prevent further allocations from RX/TX/CMD
|
||||
* data lists and ioctls
|
||||
*/
|
||||
UATH_LOCK(sc);
|
||||
sc->sc_flags |= UATH_FLAG_INVALID;
|
||||
|
||||
STAILQ_INIT(&sc->sc_rx_active);
|
||||
STAILQ_INIT(&sc->sc_rx_inactive);
|
||||
|
||||
STAILQ_INIT(&sc->sc_tx_active);
|
||||
STAILQ_INIT(&sc->sc_tx_inactive);
|
||||
STAILQ_INIT(&sc->sc_tx_pending);
|
||||
|
||||
STAILQ_INIT(&sc->sc_cmd_active);
|
||||
STAILQ_INIT(&sc->sc_cmd_pending);
|
||||
STAILQ_INIT(&sc->sc_cmd_waiting);
|
||||
STAILQ_INIT(&sc->sc_cmd_inactive);
|
||||
UATH_UNLOCK(sc);
|
||||
|
||||
ieee80211_ifdetach(ic);
|
||||
uath_stop(ifp);
|
||||
|
||||
callout_drain(&sc->stat_ch);
|
||||
callout_drain(&sc->watchdog_ch);
|
||||
|
||||
usbd_transfer_unsetup(sc->sc_xfer, UATH_N_XFERS);
|
||||
/* drain USB transfers */
|
||||
for (x = 0; x != UATH_N_XFERS; x++)
|
||||
usbd_transfer_drain(sc->sc_xfer[x]);
|
||||
|
||||
/* free buffers */
|
||||
/* free data buffers */
|
||||
UATH_LOCK(sc);
|
||||
uath_free_rx_data_list(sc);
|
||||
uath_free_tx_data_list(sc);
|
||||
uath_free_cmd_list(sc, sc->sc_cmd);
|
||||
UATH_UNLOCK(sc);
|
||||
|
||||
/* free USB transfers and some data buffers */
|
||||
usbd_transfer_unsetup(sc->sc_xfer, UATH_N_XFERS);
|
||||
|
||||
ieee80211_ifdetach(ic);
|
||||
if_free(ifp);
|
||||
mtx_destroy(&sc->sc_mtx);
|
||||
return (0);
|
||||
@ -934,10 +953,10 @@ uath_free_data_list(struct uath_softc *sc, struct uath_data data[], int ndata,
|
||||
} else {
|
||||
dp->buf = NULL;
|
||||
}
|
||||
#ifdef UATH_DEBUG
|
||||
if (dp->ni != NULL)
|
||||
device_printf(sc->sc_dev, "Node isn't NULL\n");
|
||||
#endif
|
||||
if (dp->ni != NULL) {
|
||||
ieee80211_free_node(dp->ni);
|
||||
dp->ni = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1025,10 +1044,6 @@ uath_alloc_tx_data_list(struct uath_softc *sc)
|
||||
static void
|
||||
uath_free_rx_data_list(struct uath_softc *sc)
|
||||
{
|
||||
|
||||
STAILQ_INIT(&sc->sc_rx_active);
|
||||
STAILQ_INIT(&sc->sc_rx_inactive);
|
||||
|
||||
uath_free_data_list(sc, sc->sc_rx, UATH_RX_DATA_LIST_COUNT,
|
||||
1 /* free mbufs */);
|
||||
}
|
||||
@ -1036,11 +1051,6 @@ uath_free_rx_data_list(struct uath_softc *sc)
|
||||
static void
|
||||
uath_free_tx_data_list(struct uath_softc *sc)
|
||||
{
|
||||
|
||||
STAILQ_INIT(&sc->sc_tx_active);
|
||||
STAILQ_INIT(&sc->sc_tx_inactive);
|
||||
STAILQ_INIT(&sc->sc_tx_pending);
|
||||
|
||||
uath_free_data_list(sc, sc->sc_tx, UATH_TX_DATA_LIST_COUNT,
|
||||
0 /* no mbufs */);
|
||||
}
|
||||
@ -1543,7 +1553,15 @@ uath_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
{
|
||||
struct ieee80211com *ic = ifp->if_l2com;
|
||||
struct ifreq *ifr = (struct ifreq *) data;
|
||||
int error = 0, startall = 0;
|
||||
struct uath_softc *sc = ifp->if_softc;
|
||||
int error;
|
||||
int startall = 0;
|
||||
|
||||
UATH_LOCK(sc);
|
||||
error = (sc->sc_flags & UATH_FLAG_INVALID) ? ENXIO : 0;
|
||||
UATH_UNLOCK(sc);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
switch (cmd) {
|
||||
case SIOCSIFFLAGS:
|
||||
|
@ -466,7 +466,14 @@ upgt_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
struct upgt_softc *sc = ifp->if_softc;
|
||||
struct ieee80211com *ic = ifp->if_l2com;
|
||||
struct ifreq *ifr = (struct ifreq *) data;
|
||||
int error = 0, startall = 0;
|
||||
int error;
|
||||
int startall = 0;
|
||||
|
||||
UPGT_LOCK(sc);
|
||||
error = (sc->sc_flags & UPGT_FLAG_DETACHED) ? ENXIO : 0;
|
||||
UPGT_UNLOCK(sc);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
switch (cmd) {
|
||||
case SIOCSIFFLAGS:
|
||||
@ -1976,7 +1983,6 @@ upgt_alloc_rx(struct upgt_softc *sc)
|
||||
data->buf = ((uint8_t *)sc->sc_rx_dma_buf) + (i * MCLBYTES);
|
||||
STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -1986,22 +1992,42 @@ upgt_detach(device_t dev)
|
||||
struct upgt_softc *sc = device_get_softc(dev);
|
||||
struct ifnet *ifp = sc->sc_ifp;
|
||||
struct ieee80211com *ic = ifp->if_l2com;
|
||||
unsigned int x;
|
||||
|
||||
if (!device_is_attached(dev))
|
||||
return 0;
|
||||
/*
|
||||
* Prevent further allocations from RX/TX/CMD
|
||||
* data lists and ioctls
|
||||
*/
|
||||
UPGT_LOCK(sc);
|
||||
sc->sc_flags |= UPGT_FLAG_DETACHED;
|
||||
|
||||
STAILQ_INIT(&sc->sc_tx_active);
|
||||
STAILQ_INIT(&sc->sc_tx_inactive);
|
||||
STAILQ_INIT(&sc->sc_tx_pending);
|
||||
|
||||
STAILQ_INIT(&sc->sc_rx_active);
|
||||
STAILQ_INIT(&sc->sc_rx_inactive);
|
||||
UPGT_UNLOCK(sc);
|
||||
|
||||
upgt_stop(sc);
|
||||
|
||||
callout_drain(&sc->sc_led_ch);
|
||||
callout_drain(&sc->sc_watchdog_ch);
|
||||
|
||||
ieee80211_ifdetach(ic);
|
||||
|
||||
usbd_transfer_unsetup(sc->sc_xfer, UPGT_N_XFERS);
|
||||
/* drain USB transfers */
|
||||
for (x = 0; x != UPGT_N_XFERS; x++)
|
||||
usbd_transfer_drain(sc->sc_xfer[x]);
|
||||
|
||||
/* free data buffers */
|
||||
UPGT_LOCK(sc);
|
||||
upgt_free_rx(sc);
|
||||
upgt_free_tx(sc);
|
||||
UPGT_UNLOCK(sc);
|
||||
|
||||
/* free USB transfers and some data buffers */
|
||||
usbd_transfer_unsetup(sc->sc_xfer, UPGT_N_XFERS);
|
||||
|
||||
ieee80211_ifdetach(ic);
|
||||
if_free(ifp);
|
||||
mtx_destroy(&sc->sc_mtx);
|
||||
|
||||
@ -2029,6 +2055,9 @@ upgt_free_tx(struct upgt_softc *sc)
|
||||
for (i = 0; i < UPGT_TX_MAXCOUNT; i++) {
|
||||
struct upgt_data *data = &sc->sc_tx_data[i];
|
||||
|
||||
if (data->ni != NULL)
|
||||
ieee80211_free_node(data->ni);
|
||||
|
||||
data->buf = NULL;
|
||||
data->ni = NULL;
|
||||
}
|
||||
|
@ -429,6 +429,7 @@ struct upgt_softc {
|
||||
int sc_flags;
|
||||
#define UPGT_FLAG_FWLOADED (1 << 0)
|
||||
#define UPGT_FLAG_INITDONE (1 << 1)
|
||||
#define UPGT_FLAG_DETACHED (1 << 2)
|
||||
int sc_if_flags;
|
||||
int sc_debug;
|
||||
|
||||
|
@ -385,8 +385,7 @@ static device_method_t ural_methods[] = {
|
||||
DEVMETHOD(device_probe, ural_match),
|
||||
DEVMETHOD(device_attach, ural_attach),
|
||||
DEVMETHOD(device_detach, ural_detach),
|
||||
|
||||
{ 0, 0 }
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
static driver_t ural_driver = {
|
||||
@ -528,6 +527,11 @@ ural_detach(device_t self)
|
||||
struct ifnet *ifp = sc->sc_ifp;
|
||||
struct ieee80211com *ic;
|
||||
|
||||
/* prevent further ioctls */
|
||||
RAL_LOCK(sc);
|
||||
sc->sc_detached = 1;
|
||||
RAL_UNLOCK(sc);
|
||||
|
||||
/* stop all USB transfers */
|
||||
usbd_transfer_unsetup(sc->sc_xfer, URAL_N_TRANSFER);
|
||||
|
||||
@ -1371,7 +1375,14 @@ ural_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
struct ural_softc *sc = ifp->if_softc;
|
||||
struct ieee80211com *ic = ifp->if_l2com;
|
||||
struct ifreq *ifr = (struct ifreq *) data;
|
||||
int error = 0, startall = 0;
|
||||
int error;
|
||||
int startall = 0;
|
||||
|
||||
RAL_LOCK(sc);
|
||||
error = sc->sc_detached ? ENXIO : 0;
|
||||
RAL_UNLOCK(sc);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
switch (cmd) {
|
||||
case SIOCSIFFLAGS:
|
||||
|
@ -110,6 +110,7 @@ struct ural_softc {
|
||||
uint32_t rf_regs[4];
|
||||
uint8_t txpow[14];
|
||||
uint8_t sc_bssid[6];
|
||||
uint8_t sc_detached;
|
||||
|
||||
struct {
|
||||
uint8_t val;
|
||||
|
@ -651,8 +651,8 @@ static struct ieee80211vap *urtw_vap_create(struct ieee80211com *,
|
||||
const uint8_t [IEEE80211_ADDR_LEN]);
|
||||
static void urtw_vap_delete(struct ieee80211vap *);
|
||||
static void urtw_init(void *);
|
||||
static void urtw_stop(struct ifnet *, int);
|
||||
static void urtw_stop_locked(struct ifnet *, int);
|
||||
static void urtw_stop(struct ifnet *);
|
||||
static void urtw_stop_locked(struct ifnet *);
|
||||
static int urtw_ioctl(struct ifnet *, u_long, caddr_t);
|
||||
static void urtw_start(struct ifnet *);
|
||||
static int urtw_alloc_rx_data_list(struct urtw_softc *);
|
||||
@ -933,42 +933,63 @@ urtw_detach(device_t dev)
|
||||
struct urtw_softc *sc = device_get_softc(dev);
|
||||
struct ifnet *ifp = sc->sc_ifp;
|
||||
struct ieee80211com *ic = ifp->if_l2com;
|
||||
unsigned int x;
|
||||
unsigned int n_xfers;
|
||||
|
||||
if (!device_is_attached(dev))
|
||||
return (0);
|
||||
/* Prevent further ioctls */
|
||||
URTW_LOCK(sc);
|
||||
sc->sc_flags |= URTW_DETACHED;
|
||||
URTW_UNLOCK(sc);
|
||||
|
||||
urtw_stop(ifp);
|
||||
|
||||
urtw_stop(ifp, 1);
|
||||
ieee80211_draintask(ic, &sc->sc_updateslot_task);
|
||||
ieee80211_draintask(ic, &sc->sc_led_task);
|
||||
|
||||
usb_callout_drain(&sc->sc_led_ch);
|
||||
callout_drain(&sc->sc_watchdog_ch);
|
||||
|
||||
ieee80211_ifdetach(ic);
|
||||
n_xfers = (sc->sc_flags & URTW_RTL8187B) ?
|
||||
URTW_8187B_N_XFERS : URTW_8187L_N_XFERS;
|
||||
|
||||
usbd_transfer_unsetup(sc->sc_xfer, (sc->sc_flags & URTW_RTL8187B) ?
|
||||
URTW_8187B_N_XFERS : URTW_8187L_N_XFERS);
|
||||
/* prevent further allocations from RX/TX data lists */
|
||||
URTW_LOCK(sc);
|
||||
STAILQ_INIT(&sc->sc_tx_active);
|
||||
STAILQ_INIT(&sc->sc_tx_inactive);
|
||||
STAILQ_INIT(&sc->sc_tx_pending);
|
||||
|
||||
STAILQ_INIT(&sc->sc_rx_active);
|
||||
STAILQ_INIT(&sc->sc_rx_inactive);
|
||||
URTW_UNLOCK(sc);
|
||||
|
||||
/* drain USB transfers */
|
||||
for (x = 0; x != n_xfers; x++)
|
||||
usbd_transfer_drain(sc->sc_xfer[x]);
|
||||
|
||||
/* free data buffers */
|
||||
URTW_LOCK(sc);
|
||||
urtw_free_tx_data_list(sc);
|
||||
urtw_free_rx_data_list(sc);
|
||||
URTW_UNLOCK(sc);
|
||||
|
||||
/* free USB transfers and some data buffers */
|
||||
usbd_transfer_unsetup(sc->sc_xfer, n_xfers);
|
||||
|
||||
ieee80211_ifdetach(ic);
|
||||
if_free(ifp);
|
||||
mtx_destroy(&sc->sc_mtx);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
urtw_free_tx_data_list(struct urtw_softc *sc)
|
||||
{
|
||||
|
||||
urtw_free_data_list(sc, sc->sc_tx, URTW_TX_DATA_LIST_COUNT, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
urtw_free_rx_data_list(struct urtw_softc *sc)
|
||||
{
|
||||
|
||||
urtw_free_data_list(sc, sc->sc_rx, URTW_RX_DATA_LIST_COUNT, 1);
|
||||
}
|
||||
|
||||
@ -1046,7 +1067,7 @@ urtw_init_locked(void *arg)
|
||||
usb_error_t error;
|
||||
|
||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
|
||||
urtw_stop_locked(ifp, 0);
|
||||
urtw_stop_locked(ifp);
|
||||
|
||||
error = (sc->sc_flags & URTW_RTL8187B) ? urtw_adapter_start_b(sc) :
|
||||
urtw_adapter_start(sc);
|
||||
@ -1309,13 +1330,12 @@ urtw_do_request(struct urtw_softc *sc,
|
||||
}
|
||||
|
||||
static void
|
||||
urtw_stop_locked(struct ifnet *ifp, int disable)
|
||||
urtw_stop_locked(struct ifnet *ifp)
|
||||
{
|
||||
struct urtw_softc *sc = ifp->if_softc;
|
||||
uint8_t data8;
|
||||
usb_error_t error;
|
||||
|
||||
(void)disable;
|
||||
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
|
||||
|
||||
error = urtw_intr_disable(sc);
|
||||
@ -1349,12 +1369,12 @@ urtw_stop_locked(struct ifnet *ifp, int disable)
|
||||
}
|
||||
|
||||
static void
|
||||
urtw_stop(struct ifnet *ifp, int disable)
|
||||
urtw_stop(struct ifnet *ifp)
|
||||
{
|
||||
struct urtw_softc *sc = ifp->if_softc;
|
||||
|
||||
URTW_LOCK(sc);
|
||||
urtw_stop_locked(ifp, disable);
|
||||
urtw_stop_locked(ifp);
|
||||
URTW_UNLOCK(sc);
|
||||
}
|
||||
|
||||
@ -1379,7 +1399,14 @@ urtw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
struct urtw_softc *sc = ifp->if_softc;
|
||||
struct ieee80211com *ic = ifp->if_l2com;
|
||||
struct ifreq *ifr = (struct ifreq *) data;
|
||||
int error = 0, startall = 0;
|
||||
int error;
|
||||
int startall = 0;
|
||||
|
||||
URTW_LOCK(sc);
|
||||
error = (sc->sc_flags & URTW_DETACHED) ? ENXIO : 0;
|
||||
URTW_UNLOCK(sc);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
switch (cmd) {
|
||||
case SIOCSIFFLAGS:
|
||||
@ -1394,7 +1421,7 @@ urtw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
}
|
||||
} else {
|
||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
|
||||
urtw_stop(ifp, 1);
|
||||
urtw_stop(ifp);
|
||||
}
|
||||
sc->sc_if_flags = ifp->if_flags;
|
||||
if (startall)
|
||||
@ -1410,7 +1437,6 @@ urtw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -1991,9 +2017,11 @@ urtw_update_msr(struct urtw_softc *sc)
|
||||
data |= URTW_MSR_LINK_HOSTAP;
|
||||
break;
|
||||
default:
|
||||
panic("unsupported operation mode 0x%x\n",
|
||||
DPRINTF(sc, URTW_DEBUG_STATE,
|
||||
"unsupported operation mode 0x%x\n",
|
||||
ic->ic_opmode);
|
||||
/* never reach */
|
||||
error = USB_ERR_INVAL;
|
||||
goto fail;
|
||||
}
|
||||
} else
|
||||
data |= URTW_MSR_LINK_NONE;
|
||||
@ -2424,8 +2452,10 @@ urtw_get_rfchip(struct urtw_softc *sc)
|
||||
sc->sc_rf_stop = urtw_8225_rf_stop;
|
||||
break;
|
||||
default:
|
||||
panic("unsupported RF chip %d\n", data & 0xff);
|
||||
/* never reach */
|
||||
DPRINTF(sc, URTW_DEBUG_STATE,
|
||||
"unsupported RF chip %d\n", data & 0xff);
|
||||
error = USB_ERR_INVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
device_printf(sc->sc_dev, "%s rf %s hwrev %s\n",
|
||||
@ -3605,8 +3635,10 @@ urtw_led_ctl(struct urtw_softc *sc, int mode)
|
||||
error = urtw_led_mode3(sc, mode);
|
||||
break;
|
||||
default:
|
||||
panic("unsupported LED mode %d\n", sc->sc_strategy);
|
||||
/* never reach */
|
||||
DPRINTF(sc, URTW_DEBUG_STATE,
|
||||
"unsupported LED mode %d\n", sc->sc_strategy);
|
||||
error = USB_ERR_INVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return (error);
|
||||
@ -3631,8 +3663,9 @@ urtw_led_mode0(struct urtw_softc *sc, int mode)
|
||||
sc->sc_gpio_ledstate = URTW_LED_ON;
|
||||
break;
|
||||
default:
|
||||
panic("unsupported LED mode 0x%x", mode);
|
||||
/* never reach */
|
||||
DPRINTF(sc, URTW_DEBUG_STATE,
|
||||
"unsupported LED mode 0x%x", mode);
|
||||
return (USB_ERR_INVAL);
|
||||
}
|
||||
|
||||
switch (sc->sc_gpio_ledstate) {
|
||||
@ -3655,8 +3688,9 @@ urtw_led_mode0(struct urtw_softc *sc, int mode)
|
||||
urtw_led_off(sc, URTW_LED_GPIO);
|
||||
break;
|
||||
default:
|
||||
panic("unknown LED status 0x%x", sc->sc_gpio_ledstate);
|
||||
/* never reach */
|
||||
DPRINTF(sc, URTW_DEBUG_STATE,
|
||||
"unknown LED status 0x%x", sc->sc_gpio_ledstate);
|
||||
return (USB_ERR_INVAL);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
@ -3664,21 +3698,18 @@ urtw_led_mode0(struct urtw_softc *sc, int mode)
|
||||
static usb_error_t
|
||||
urtw_led_mode1(struct urtw_softc *sc, int mode)
|
||||
{
|
||||
|
||||
return (USB_ERR_INVAL);
|
||||
}
|
||||
|
||||
static usb_error_t
|
||||
urtw_led_mode2(struct urtw_softc *sc, int mode)
|
||||
{
|
||||
|
||||
return (USB_ERR_INVAL);
|
||||
}
|
||||
|
||||
static usb_error_t
|
||||
urtw_led_mode3(struct urtw_softc *sc, int mode)
|
||||
{
|
||||
|
||||
return (USB_ERR_INVAL);
|
||||
}
|
||||
|
||||
@ -3694,13 +3725,17 @@ urtw_led_on(struct urtw_softc *sc, int type)
|
||||
urtw_write8_m(sc, URTW_GP_ENABLE, 0x00);
|
||||
break;
|
||||
default:
|
||||
panic("unsupported LED PIN type 0x%x",
|
||||
DPRINTF(sc, URTW_DEBUG_STATE,
|
||||
"unsupported LED PIN type 0x%x",
|
||||
sc->sc_gpio_ledpin);
|
||||
/* never reach */
|
||||
error = USB_ERR_INVAL;
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
panic("unsupported LED type 0x%x", type);
|
||||
/* never reach */
|
||||
DPRINTF(sc, URTW_DEBUG_STATE,
|
||||
"unsupported LED type 0x%x", type);
|
||||
error = USB_ERR_INVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
sc->sc_gpio_ledon = 1;
|
||||
@ -3721,13 +3756,17 @@ urtw_led_off(struct urtw_softc *sc, int type)
|
||||
URTW_GP_ENABLE, URTW_GP_ENABLE_DATA_MAGIC1);
|
||||
break;
|
||||
default:
|
||||
panic("unsupported LED PIN type 0x%x",
|
||||
DPRINTF(sc, URTW_DEBUG_STATE,
|
||||
"unsupported LED PIN type 0x%x",
|
||||
sc->sc_gpio_ledpin);
|
||||
/* never reach */
|
||||
error = USB_ERR_INVAL;
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
panic("unsupported LED type 0x%x", type);
|
||||
/* never reach */
|
||||
DPRINTF(sc, URTW_DEBUG_STATE,
|
||||
"unsupported LED type 0x%x", type);
|
||||
error = USB_ERR_INVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
sc->sc_gpio_ledon = 0;
|
||||
@ -3751,8 +3790,12 @@ urtw_ledtask(void *arg, int pending)
|
||||
{
|
||||
struct urtw_softc *sc = arg;
|
||||
|
||||
if (sc->sc_strategy != URTW_SW_LED_MODE0)
|
||||
panic("could not process a LED strategy 0x%x", sc->sc_strategy);
|
||||
if (sc->sc_strategy != URTW_SW_LED_MODE0) {
|
||||
DPRINTF(sc, URTW_DEBUG_STATE,
|
||||
"could not process a LED strategy 0x%x",
|
||||
sc->sc_strategy);
|
||||
return;
|
||||
}
|
||||
|
||||
URTW_LOCK(sc);
|
||||
urtw_led_blink(sc);
|
||||
@ -3799,8 +3842,10 @@ urtw_led_blink(struct urtw_softc *sc)
|
||||
usb_callout_reset(&sc->sc_led_ch, hz, urtw_led_ch, sc);
|
||||
break;
|
||||
default:
|
||||
panic("unknown LED status 0x%x", sc->sc_gpio_ledstate);
|
||||
/* never reach */
|
||||
DPRINTF(sc, URTW_DEBUG_STATE,
|
||||
"unknown LED status 0x%x",
|
||||
sc->sc_gpio_ledstate);
|
||||
return (USB_ERR_INVAL);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
@ -107,6 +107,7 @@ struct urtw_softc {
|
||||
#define URTW_RTL8187B_REV_B (1 << 3)
|
||||
#define URTW_RTL8187B_REV_D (1 << 4)
|
||||
#define URTW_RTL8187B_REV_E (1 << 5)
|
||||
#define URTW_DETACHED (1 << 6)
|
||||
enum ieee80211_state sc_state;
|
||||
|
||||
int sc_epromtype;
|
||||
|
@ -438,12 +438,29 @@ zyd_detach(device_t dev)
|
||||
struct zyd_softc *sc = device_get_softc(dev);
|
||||
struct ifnet *ifp = sc->sc_ifp;
|
||||
struct ieee80211com *ic;
|
||||
unsigned int x;
|
||||
|
||||
/* stop all USB transfers */
|
||||
usbd_transfer_unsetup(sc->sc_xfer, ZYD_N_TRANSFER);
|
||||
/*
|
||||
* Prevent further allocations from RX/TX data
|
||||
* lists and ioctls:
|
||||
*/
|
||||
ZYD_LOCK(sc);
|
||||
sc->sc_flags |= ZYD_FLAG_DETACHED;
|
||||
STAILQ_INIT(&sc->tx_q);
|
||||
STAILQ_INIT(&sc->tx_free);
|
||||
ZYD_UNLOCK(sc);
|
||||
|
||||
/* drain USB transfers */
|
||||
for (x = 0; x != ZYD_N_TRANSFER; x++)
|
||||
usbd_transfer_drain(sc->sc_xfer[x]);
|
||||
|
||||
/* free TX list, if any */
|
||||
ZYD_LOCK(sc);
|
||||
zyd_unsetup_tx_list(sc);
|
||||
ZYD_UNLOCK(sc);
|
||||
|
||||
/* free USB transfers and some data buffers */
|
||||
usbd_transfer_unsetup(sc->sc_xfer, ZYD_N_TRANSFER);
|
||||
|
||||
if (ifp) {
|
||||
ic = ifp->if_l2com;
|
||||
@ -2637,7 +2654,14 @@ zyd_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
struct zyd_softc *sc = ifp->if_softc;
|
||||
struct ieee80211com *ic = ifp->if_l2com;
|
||||
struct ifreq *ifr = (struct ifreq *) data;
|
||||
int error = 0, startall = 0;
|
||||
int error;
|
||||
int startall = 0;
|
||||
|
||||
ZYD_LOCK(sc);
|
||||
error = (sc->sc_flags & ZYD_FLAG_DETACHED) ? ENXIO : 0;
|
||||
ZYD_UNLOCK(sc);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
switch (cmd) {
|
||||
case SIOCSIFFLAGS:
|
||||
@ -2928,8 +2952,7 @@ static device_method_t zyd_methods[] = {
|
||||
DEVMETHOD(device_probe, zyd_match),
|
||||
DEVMETHOD(device_attach, zyd_attach),
|
||||
DEVMETHOD(device_detach, zyd_detach),
|
||||
|
||||
{ 0, 0 }
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
static driver_t zyd_driver = {
|
||||
|
@ -1259,6 +1259,7 @@ struct zyd_softc {
|
||||
#define ZYD_FLAG_FWLOADED (1 << 0)
|
||||
#define ZYD_FLAG_INITONCE (1 << 1)
|
||||
#define ZYD_FLAG_INITDONE (1 << 2)
|
||||
#define ZYD_FLAG_DETACHED (1 << 3)
|
||||
|
||||
struct zyd_rf sc_rf;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user