From 3c2315de2f2d30d17df6dfce6618f42d0eb2469d Mon Sep 17 00:00:00 2001 From: skrll Date: Sun, 11 Dec 2016 15:01:37 +0000 Subject: [PATCH] Fix some bugs introduced by the nick-nhusb merge and related to the Tx Interrupt pipe transfer handling While I'm here make some other changes moving towards MPification PR/51151: athn panic on attach PR/51458: usb athn panic --- sys/dev/usb/if_athn_usb.c | 309 +++++++++++++++++++++++++++----------- sys/dev/usb/if_athn_usb.h | 11 +- 2 files changed, 231 insertions(+), 89 deletions(-) diff --git a/sys/dev/usb/if_athn_usb.c b/sys/dev/usb/if_athn_usb.c index 6a2fd847257d..93f0bf3094a3 100644 --- a/sys/dev/usb/if_athn_usb.c +++ b/sys/dev/usb/if_athn_usb.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_athn_usb.c,v 1.17 2016/12/11 08:30:39 skrll Exp $ */ +/* $NetBSD: if_athn_usb.c,v 1.18 2016/12/11 15:01:37 skrll Exp $ */ /* $OpenBSD: if_athn_usb.c,v 1.12 2013/01/14 09:50:31 jsing Exp $ */ /*- @@ -22,7 +22,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: if_athn_usb.c,v 1.17 2016/12/11 08:30:39 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_athn_usb.c,v 1.18 2016/12/11 15:01:37 skrll Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -94,6 +94,7 @@ CFATTACH_DECL_NEW(athn_usb, sizeof(struct athn_usb_softc), athn_usb_match, Static int athn_usb_alloc_rx_list(struct athn_usb_softc *); Static int athn_usb_alloc_tx_cmd(struct athn_usb_softc *); +Static int athn_usb_alloc_tx_msg(struct athn_usb_softc *); Static int athn_usb_alloc_tx_list(struct athn_usb_softc *); Static void athn_usb_attachhook(device_t); Static void athn_usb_bcneof(struct usbd_xfer *, void *, @@ -108,6 +109,7 @@ Static void athn_usb_do_async(struct athn_usb_softc *, void (*)(struct athn_usb_softc *, void *), void *, int); Static void athn_usb_free_rx_list(struct athn_usb_softc *); Static void athn_usb_free_tx_cmd(struct athn_usb_softc *); +Static void athn_usb_free_tx_msg(struct athn_usb_softc *); Static void athn_usb_free_tx_list(struct athn_usb_softc *); Static int athn_usb_htc_connect_svc(struct athn_usb_softc *, uint16_t, uint8_t, uint8_t, uint8_t *); @@ -115,6 +117,7 @@ Static int athn_usb_htc_msg(struct athn_usb_softc *, uint16_t, void *, int); Static int athn_usb_htc_setup(struct athn_usb_softc *); Static int athn_usb_init(struct ifnet *); +Static int athn_usb_init_locked(struct ifnet *); Static void athn_usb_intr(struct usbd_xfer *, void *, usbd_status); Static int athn_usb_ioctl(struct ifnet *, u_long, void *); @@ -140,7 +143,9 @@ Static void athn_usb_rx_wmi_ctrl(struct athn_usb_softc *, uint8_t *, size_t); Static void athn_usb_rxeof(struct usbd_xfer *, void *, usbd_status); Static void athn_usb_start(struct ifnet *); +//Static void athn_usb_start_locked(struct ifnet *); Static void athn_usb_stop(struct ifnet *); +Static void athn_usb_stop_locked(struct ifnet *); Static void athn_usb_swba(struct athn_usb_softc *); Static int athn_usb_switch_chan(struct athn_softc *, struct ieee80211_channel *, struct ieee80211_channel *); @@ -152,9 +157,8 @@ Static void athn_usb_txeof(struct usbd_xfer *, void *, Static void athn_usb_updateslot(struct ifnet *); Static void athn_usb_updateslot_cb(struct athn_usb_softc *, void *); Static void athn_usb_wait_async(struct athn_usb_softc *); -Static void athn_usb_wait_cmd(struct athn_usb_softc *); -Static void athn_usb_wait_msg(struct athn_usb_softc *); -Static void athn_usb_wait_wmi(struct athn_usb_softc *); +Static int athn_usb_wait_cmd(struct athn_usb_softc *); +Static int athn_usb_wait_msg(struct athn_usb_softc *); Static void athn_usb_watchdog(struct ifnet *); Static int athn_usb_wmi_xcmd(struct athn_usb_softc *, uint16_t, void *, int, void *); @@ -268,6 +272,13 @@ athn_usb_attach(device_t parent, device_t self, void *aux) sc->sc_ops.write = athn_usb_write; sc->sc_ops.write_barrier = athn_usb_write_barrier; + mutex_init(&usc->usc_lock, MUTEX_DEFAULT, IPL_NONE); + + cv_init(&usc->usc_cmd_cv, "athncmd"); + mutex_init(&usc->usc_cmd_mtx, MUTEX_DEFAULT, IPL_SOFTUSB); + cv_init(&usc->usc_msg_cv, "athnmsg"); + mutex_init(&usc->usc_msg_mtx, MUTEX_DEFAULT, IPL_SOFTUSB); + cv_init(&usc->usc_task_cv, "athntsk"); mutex_init(&usc->usc_task_mtx, MUTEX_DEFAULT, IPL_NET); mutex_init(&usc->usc_tx_mtx, MUTEX_DEFAULT, IPL_NONE); @@ -295,6 +306,10 @@ athn_usb_attach(device_t parent, device_t self, void *aux) if (athn_usb_alloc_tx_cmd(usc) != 0) goto fail; + /* Allocate xfer for firmware commands. */ + if (athn_usb_alloc_tx_msg(usc) != 0) + goto fail; + /* Allocate Tx/Rx buffers. */ error = athn_usb_alloc_rx_list(usc); if (error != 0) @@ -309,13 +324,23 @@ athn_usb_attach(device_t parent, device_t self, void *aux) return; fail: + /* Free Tx/Rx buffers. */ athn_usb_abort_pipes(usc); athn_usb_free_tx_list(usc); athn_usb_free_rx_list(usc); athn_usb_free_tx_cmd(usc); + athn_usb_free_tx_msg(usc); athn_usb_close_pipes(usc); usb_rem_task(usc->usc_udev, &usc->usc_task); + + cv_destroy(&usc->usc_cmd_cv); + cv_destroy(&usc->usc_msg_cv); + + mutex_destroy(&usc->usc_lock); + + mutex_destroy(&usc->usc_cmd_mtx); + mutex_destroy(&usc->usc_msg_mtx); mutex_destroy(&usc->usc_tx_mtx); mutex_destroy(&usc->usc_task_mtx); } @@ -447,9 +472,12 @@ athn_usb_detach(device_t self, int flags) s = splusb(); usc->usc_dying = 1; - athn_usb_wait_wmi(usc); + mutex_enter(&usc->usc_cmd_mtx); athn_usb_wait_cmd(usc); + mutex_exit(&usc->usc_cmd_mtx); + mutex_enter(&usc->usc_msg_mtx); athn_usb_wait_msg(usc); + mutex_exit(&usc->usc_msg_mtx); athn_usb_wait_async(usc); usb_rem_task(usc->usc_udev, &usc->usc_task); @@ -734,6 +762,40 @@ athn_usb_free_tx_cmd(struct athn_usb_softc *usc) usbd_destroy_xfer(xfer); } +Static int +athn_usb_alloc_tx_msg(struct athn_usb_softc *usc) +{ + struct athn_usb_tx_data *data = &usc->usc_tx_msg; + + DPRINTFN(DBG_FN, usc, "\n"); + + data->sc = usc; /* Backpointer for callbacks. */ + + int err = usbd_create_xfer(usc->usc_tx_intr_pipe, ATHN_USB_TXCMDSZ, + 0, 0, &data->xfer); + if (err) { + aprint_error_dev(usc->usc_dev, + "could not allocate command xfer\n"); + return err; + } + data->buf = usbd_get_buffer(data->xfer); + + return 0; +} + +Static void +athn_usb_free_tx_msg(struct athn_usb_softc *usc) +{ + struct usbd_xfer *xfer; + + DPRINTFN(DBG_FN, usc, "\n"); + + CTASSERT(sizeof(xfer) == sizeof(void *)); + xfer = atomic_swap_ptr(&usc->usc_tx_msg.xfer, NULL); + if (xfer != NULL) + usbd_destroy_xfer(xfer); +} + Static void athn_usb_task(void *arg) { @@ -811,7 +873,7 @@ athn_usb_load_firmware(struct athn_usb_softc *usc) u_char *fw, *ptr; size_t size, remain; uint32_t addr; - int s, mlen, error; + int mlen, error; DPRINTFN(DBG_FN, sc, "\n"); @@ -882,14 +944,24 @@ athn_usb_load_firmware(struct athn_usb_softc *usc) USETW(req.wValue, addr); USETW(req.wLength, 0); - s = splusb(); + mutex_enter(&usc->usc_msg_mtx); + error = athn_usb_wait_msg(usc); + if (error) { + mutex_exit(&usc->usc_msg_mtx); + return error; + } + usc->usc_wait_msg_id = AR_HTC_MSG_READY; error = usbd_do_request(usc->usc_udev, &req, NULL); + /* Wait at most 1 second for firmware to boot. */ - if (error == 0 && usc->usc_wait_msg_id != 0) - error = tsleep(&usc->usc_wait_msg_id, 0, "athnfw", hz); - usc->usc_wait_msg_id = 0; - splx(s); + if (error == 0) + error = athn_usb_wait_msg(usc); + + mutex_exit(&usc->usc_msg_mtx); + + DPRINTFN(DBG_FN, sc, "return %d\n", error); + return error; } @@ -897,7 +969,7 @@ Static int athn_usb_htc_msg(struct athn_usb_softc *usc, uint16_t msg_id, void *buf, int len) { - struct athn_usb_tx_data *data = &usc->usc_tx_cmd; + struct athn_usb_tx_data *data = &usc->usc_tx_msg; struct ar_htc_frame_hdr *htc; struct ar_htc_msg_hdr *msg; @@ -906,6 +978,8 @@ athn_usb_htc_msg(struct athn_usb_softc *usc, uint16_t msg_id, void *buf, DPRINTFN(DBG_FN, usc, "\n"); + KASSERT(mutex_owned(&usc->usc_msg_mtx)); + htc = (struct ar_htc_frame_hdr *)data->buf; memset(htc, 0, sizeof(*htc)); htc->endpoint_id = 0; @@ -920,13 +994,15 @@ athn_usb_htc_msg(struct athn_usb_softc *usc, uint16_t msg_id, void *buf, sizeof(*htc) + sizeof(*msg) + len, USBD_SHORT_XFER_OK, ATHN_USB_CMD_TIMEOUT, NULL); return usbd_sync_transfer(data->xfer); + + } Static int athn_usb_htc_setup(struct athn_usb_softc *usc) { struct ar_htc_msg_config_pipe cfg; - int s, error; + int error; /* * Connect WMI services to USB pipes. @@ -973,26 +1049,41 @@ athn_usb_htc_setup(struct athn_usb_softc *usc) cfg.pipe_id = UE_GET_ADDR(AR_PIPE_TX_DATA); cfg.credits = (usc->usc_flags & ATHN_USB_FLAG_AR7010) ? 45 : 33; - s = splusb(); + mutex_enter(&usc->usc_msg_mtx); + error = athn_usb_wait_msg(usc); + if (error) { + mutex_exit(&usc->usc_msg_mtx); + return error; + } usc->usc_wait_msg_id = AR_HTC_MSG_CONF_PIPE_RSP; error = athn_usb_htc_msg(usc, AR_HTC_MSG_CONF_PIPE, &cfg, sizeof(cfg)); - if (error == 0 && usc->usc_wait_msg_id != 0) - error = tsleep(&usc->usc_wait_msg_id, 0, "athnhtc", hz); - usc->usc_wait_msg_id = 0; - - splx(s); if (error != 0) { - aprint_error_dev(usc->usc_dev, "could not configure pipe\n"); + aprint_error_dev(usc->usc_dev, "could not request pipe configurations\n"); + mutex_exit(&usc->usc_msg_mtx); + return error; + } + error = athn_usb_wait_msg(usc); + if (error) { + mutex_exit(&usc->usc_msg_mtx); return error; } error = athn_usb_htc_msg(usc, AR_HTC_MSG_SETUP_COMPLETE, NULL, 0); if (error != 0) { - aprint_error_dev(usc->usc_dev, "could not complete setup\n"); + aprint_error_dev(usc->usc_dev, "could not request complete setup\n"); + mutex_exit(&usc->usc_msg_mtx); return error; } + error = athn_usb_wait_msg(usc); + if (error) { + mutex_exit(&usc->usc_msg_mtx); + return error; + } + + mutex_exit(&usc->usc_msg_mtx); + return 0; } @@ -1002,7 +1093,7 @@ athn_usb_htc_connect_svc(struct athn_usb_softc *usc, uint16_t svc_id, { struct ar_htc_msg_conn_svc msg; struct ar_htc_msg_conn_svc_rsp rsp; - int s, error; + int error; DPRINTFN(DBG_FN, usc, "\n"); @@ -1010,17 +1101,19 @@ athn_usb_htc_connect_svc(struct athn_usb_softc *usc, uint16_t svc_id, msg.svc_id = htobe16(svc_id); msg.dl_pipeid = UE_GET_ADDR(dl_pipe); msg.ul_pipeid = UE_GET_ADDR(ul_pipe); - s = splusb(); + + mutex_enter(&usc->usc_msg_mtx); + athn_usb_wait_msg(usc); usc->usc_msg_conn_svc_rsp = &rsp; usc->usc_wait_msg_id = AR_HTC_MSG_CONN_SVC_RSP; error = athn_usb_htc_msg(usc, AR_HTC_MSG_CONN_SVC, &msg, sizeof(msg)); - if (error == 0 && usc->usc_wait_msg_id != 0) - error = tsleep(&usc->usc_wait_msg_id, 0, "athnhtc", hz); - usc->usc_wait_msg_id = 0; + if (error == 0) + error = athn_usb_wait_msg(usc); + + mutex_exit(&usc->usc_msg_mtx); - splx(s); if (error != 0) { aprint_error_dev(usc->usc_dev, "error waiting for service %d connection\n", svc_id); @@ -1041,24 +1134,34 @@ athn_usb_htc_connect_svc(struct athn_usb_softc *usc, uint16_t svc_id, return 0; } -Static void +Static int athn_usb_wait_msg(struct athn_usb_softc *usc) { + DPRINTFN(DBG_FN, usc, "\n"); - DPRINTFN(DBG_FN, usc, "\n"); + KASSERT(mutex_owned(&usc->usc_msg_mtx)); - while (__predict_false(usc->usc_wait_msg_id)) - tsleep(&usc->usc_wait_msg_id, 0, "athnmsg", hz); + int error = 0; + while (usc->usc_wait_msg_id) + error = cv_timedwait(&usc->usc_msg_cv, &usc->usc_msg_mtx, hz); + + return error; } -Static void +Static int athn_usb_wait_cmd(struct athn_usb_softc *usc) { - DPRINTFN(DBG_FN, usc, "\n"); + DPRINTFN(DBG_FN, usc, "\n"); + + KASSERT(mutex_owned(&usc->usc_cmd_mtx)); + + int error = 0; + while (usc->usc_wait_cmd_id) + error = cv_timedwait(&usc->usc_cmd_cv, &usc->usc_cmd_mtx, hz); + + return error; - while (__predict_false(usc->usc_wait_cmd_id)) - tsleep(&usc->usc_wait_cmd_id, 0, "athncmd", hz); } Static void @@ -1067,13 +1170,10 @@ athn_usb_wmieof(struct usbd_xfer *xfer, void * priv, { struct athn_usb_softc *usc = priv; - DPRINTFN(DBG_FN, usc, "\n"); + DPRINTFN(DBG_FN, usc, "\n"); if (__predict_false(status == USBD_STALLED)) usbd_clear_endpoint_stall_async(usc->usc_tx_intr_pipe); - - usc->usc_wmi_done = 1; - wakeup(&usc->usc_wmi_done); } Static int @@ -1083,12 +1183,20 @@ athn_usb_wmi_xcmd(struct athn_usb_softc *usc, uint16_t cmd_id, void *ibuf, struct athn_usb_tx_data *data = &usc->usc_tx_cmd; struct ar_htc_frame_hdr *htc; struct ar_wmi_cmd_hdr *wmi; - int s, error; + int error; if (usc->usc_dying) return EIO; - DPRINTFN(DBG_FN, usc, "\n"); + DPRINTFN(DBG_FN, usc, "cmd_id %#x\n", cmd_id); + + mutex_enter(&usc->usc_cmd_mtx); + error = athn_usb_wait_cmd(usc); + + if (error) { + mutex_exit(&usc->usc_cmd_mtx); + return error; + } htc = (struct ar_htc_frame_hdr *)data->buf; memset(htc, 0, sizeof(*htc)); @@ -1107,32 +1215,25 @@ athn_usb_wmi_xcmd(struct athn_usb_softc *usc, uint16_t cmd_id, void *ibuf, USBD_SHORT_XFER_OK, ATHN_USB_CMD_TIMEOUT, athn_usb_wmieof); - s = splusb(); - usc->usc_wmi_done = 0; usc->usc_wait_cmd_id = cmd_id; - error = usbd_transfer(data->xfer); - if (__predict_true(error == 0 || error == USBD_IN_PROGRESS)) { - usc->usc_obuf = obuf; + usc->usc_obuf = obuf; - /* Wait for WMI command to complete. */ - error = tsleep(&usc->usc_wait_cmd_id, 0, "athnwmi", hz); - usc->usc_wait_cmd_id = 0; - athn_usb_wait_wmi(usc); + error = usbd_sync_transfer(data->xfer); + if (error) { + DPRINTFN(DBG_FN, usc, "transfer error %d\n", error); + + mutex_exit(&usc->usc_cmd_mtx); + + return error; } - splx(s); + + error = athn_usb_wait_cmd(usc); + + mutex_exit(&usc->usc_cmd_mtx); + return error; } -Static void -athn_usb_wait_wmi(struct athn_usb_softc *usc) -{ - - DPRINTFN(DBG_FN, usc, "\n"); - - while (__predict_false(!usc->usc_wmi_done)) - tsleep(&usc->usc_wmi_done, 0, "athnwmi", 0); -} - #ifdef unused Static int athn_usb_read_rom(struct athn_softc *sc) @@ -1869,15 +1970,18 @@ athn_usb_rx_wmi_ctrl(struct athn_usb_softc *usc, uint8_t *buf, size_t len) cmd_id = be16toh(wmi->cmd_id); if (!(cmd_id & AR_WMI_EVT_FLAG)) { - if (usc->usc_wait_cmd_id != cmd_id) - return; /* Unexpected reply. */ - if (usc->usc_obuf != NULL) { - /* Copy answer into caller supplied buffer. */ - memcpy(usc->usc_obuf, &wmi[1], len - sizeof(*wmi)); + mutex_enter(&usc->usc_cmd_mtx); + if (usc->usc_wait_cmd_id == cmd_id) { + + if (usc->usc_obuf != NULL) { + /* Copy answer into caller supplied buffer. */ + memcpy(usc->usc_obuf, &wmi[1], len - sizeof(*wmi)); + } + /* Notify caller of completion. */ + usc->usc_wait_cmd_id = 0; + cv_broadcast(&usc->usc_cmd_cv); } - /* Notify caller of completion. */ - usc->usc_wait_cmd_id = 0; - wakeup(&usc->usc_wait_cmd_id); + mutex_exit(&usc->usc_cmd_mtx); return; } /* @@ -1971,20 +2075,28 @@ athn_usb_intr(struct usbd_xfer *xfer, void * priv, switch (msg_id) { case AR_HTC_MSG_READY: case AR_HTC_MSG_CONF_PIPE_RSP: - if (usc->usc_wait_msg_id != msg_id) - break; - usc->usc_wait_msg_id = 0; - wakeup(&usc->usc_wait_msg_id); + mutex_enter(&usc->usc_msg_mtx); + DPRINTFN(DBG_RX, usc, "AR_HTC_MSG_READY: %d vs %d\n", + usc->usc_wait_msg_id, msg_id); + if (usc->usc_wait_msg_id == msg_id) { + usc->usc_wait_msg_id = 0; + cv_broadcast(&usc->usc_msg_cv); + } + mutex_exit(&usc->usc_msg_mtx); break; case AR_HTC_MSG_CONN_SVC_RSP: - if (usc->usc_wait_msg_id != msg_id) - break; - if (usc->usc_msg_conn_svc_rsp != NULL) { - memcpy(usc->usc_msg_conn_svc_rsp, &msg[1], - sizeof(*usc->usc_msg_conn_svc_rsp)); + mutex_enter(&usc->usc_msg_mtx); + DPRINTFN(DBG_RX, usc, "AR_HTC_MSG_CONN_SVC_RSP: %d vs %d\n", + usc->usc_wait_msg_id, msg_id); + if (usc->usc_wait_msg_id == msg_id) { + if (usc->usc_msg_conn_svc_rsp != NULL) { + memcpy(usc->usc_msg_conn_svc_rsp, &msg[1], + sizeof(*usc->usc_msg_conn_svc_rsp)); + } + usc->usc_wait_msg_id = 0; + cv_broadcast(&usc->usc_msg_cv); } - usc->usc_wait_msg_id = 0; - wakeup(&usc->usc_wait_msg_id); + mutex_exit(&usc->usc_msg_mtx); break; default: DPRINTFN(DBG_RX, usc, "HTC message %d ignored\n", msg_id); @@ -2556,8 +2668,10 @@ athn_usb_ioctl(struct ifnet *ifp, u_long cmd, void *data) error = 0; if (IS_UP_AND_RUNNING(ifp) && ic->ic_roaming != IEEE80211_ROAMING_MANUAL) { - athn_usb_stop(ifp); - error = athn_usb_init(ifp); + mutex_enter(&usc->usc_lock); + athn_usb_stop_locked(ifp); + error = athn_usb_init_locked(ifp); + mutex_exit(&usc->usc_lock); } } splx(s); @@ -2566,6 +2680,19 @@ athn_usb_ioctl(struct ifnet *ifp, u_long cmd, void *data) Static int athn_usb_init(struct ifnet *ifp) +{ + struct athn_softc *sc = ifp->if_softc; + struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); + + mutex_enter(&usc->usc_lock); + int ret = athn_usb_init_locked(ifp); + mutex_exit(&usc->usc_lock); + + return ret; +} + +Static int +athn_usb_init_locked(struct ifnet *ifp) { struct athn_softc *sc = ifp->if_softc; struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); @@ -2692,6 +2819,7 @@ athn_usb_init(struct ifnet *ifp) if (error != 0) goto fail; + /* Queue Rx xfers. */ for (i = 0; i < ATHN_USB_RX_LIST_COUNT; i++) { data = &usc->usc_rx_data[i]; @@ -2732,6 +2860,17 @@ athn_usb_init(struct ifnet *ifp) Static void athn_usb_stop(struct ifnet *ifp) +{ + struct athn_softc *sc = ifp->if_softc; + struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); + + mutex_enter(&usc->usc_lock); + athn_usb_stop_locked(ifp); + mutex_exit(&usc->usc_lock); +} + +Static void +athn_usb_stop_locked(struct ifnet *ifp) { struct athn_softc *sc = ifp->if_softc; struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); @@ -2759,10 +2898,6 @@ athn_usb_stop(struct ifnet *ifp) usbd_abort_pipe(usc->usc_tx_data_pipe); usbd_abort_pipe(usc->usc_rx_data_pipe); - /* Free Tx/Rx buffers. */ - athn_usb_free_tx_list(usc); - athn_usb_free_rx_list(usc); - /* Flush Rx stream. */ CTASSERT(sizeof(m) == sizeof(void *)); m = atomic_swap_ptr(&usc->usc_rx_stream.m, NULL); diff --git a/sys/dev/usb/if_athn_usb.h b/sys/dev/usb/if_athn_usb.h index 68fb3e77860e..fadbfc0298ea 100644 --- a/sys/dev/usb/if_athn_usb.h +++ b/sys/dev/usb/if_athn_usb.h @@ -1,4 +1,4 @@ -/* $NetBSD: if_athn_usb.h,v 1.3 2016/04/23 10:15:31 skrll Exp $ */ +/* $NetBSD: if_athn_usb.h,v 1.4 2016/12/11 15:01:37 skrll Exp $ */ /* $OpenBSD: if_athn_usb.h,v 1.3 2012/11/10 14:35:06 mikeb Exp $ */ /*- @@ -443,6 +443,13 @@ struct athn_usb_softc { int usc_athn_attached; + kmutex_t usc_lock; + + kmutex_t usc_msg_mtx; + kcondvar_t usc_msg_cv; + kmutex_t usc_cmd_mtx; + kcondvar_t usc_cmd_cv; + kcondvar_t usc_task_cv; kmutex_t usc_task_mtx; kmutex_t usc_tx_mtx; @@ -469,7 +476,6 @@ struct athn_usb_softc { struct ar_wmi_cmd_reg_write usc_wbuf[AR_MAX_WRITE_COUNT]; int usc_wcount; - int usc_wmi_done; uint16_t usc_wmi_seq_no; uint16_t usc_wait_cmd_id; uint16_t usc_wait_msg_id; @@ -481,6 +487,7 @@ struct athn_usb_softc { struct athn_usb_tx_data usc_tx_data[ATHN_USB_TX_LIST_COUNT]; TAILQ_HEAD(, athn_usb_tx_data) usc_tx_free_list; struct athn_usb_tx_data usc_tx_cmd; + struct athn_usb_tx_data usc_tx_msg; struct athn_usb_tx_data *usc_tx_bcn; uint8_t usc_ep_ctrl;