Module Name: src
Committed By: skrll
Date: Wed Dec 28 19:41:41 UTC 2016
Modified Files:
src/sys/dev/ic [nick-nhusb]: athn.c
src/sys/dev/usb [nick-nhusb]: if_athn_usb.c if_athn_usb.h
Log Message:
Various improvements
- override the method before calling athn_attach -> if_attach -> interface
announce
- locking fixes for htc/wmi
- some MPificaton
To generate a diff of this commit:
cvs rdiff -u -r1.10.4.2 -r1.10.4.3 src/sys/dev/ic/athn.c
cvs rdiff -u -r1.6.8.17 -r1.6.8.18 src/sys/dev/usb/if_athn_usb.c
cvs rdiff -u -r1.2.16.4 -r1.2.16.5 src/sys/dev/usb/if_athn_usb.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/ic/athn.c
diff -u src/sys/dev/ic/athn.c:1.10.4.2 src/sys/dev/ic/athn.c:1.10.4.3
--- src/sys/dev/ic/athn.c:1.10.4.2 Sun May 29 08:44:21 2016
+++ src/sys/dev/ic/athn.c Wed Dec 28 19:41:41 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: athn.c,v 1.10.4.2 2016/05/29 08:44:21 skrll Exp $ */
+/* $NetBSD: athn.c,v 1.10.4.3 2016/12/28 19:41:41 skrll Exp $ */
/* $OpenBSD: athn.c,v 1.83 2014/07/22 13:12:11 mpi Exp $ */
/*-
@@ -23,7 +23,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: athn.c,v 1.10.4.2 2016/05/29 08:44:21 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: athn.c,v 1.10.4.3 2016/12/28 19:41:41 skrll Exp $");
#ifndef _MODULE
#include "athn_usb.h" /* for NATHN_USB */
@@ -329,10 +329,14 @@ athn_attach(struct athn_softc *sc)
ifp->if_softc = sc;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_init = athn_init;
- ifp->if_ioctl = athn_ioctl;
- ifp->if_start = athn_start;
- ifp->if_watchdog = athn_watchdog;
+ if (!ifp->if_init)
+ ifp->if_init = athn_init;
+ if (!ifp->if_ioctl)
+ ifp->if_ioctl = athn_ioctl;
+ if (!ifp->if_start)
+ ifp->if_start = athn_start;
+ if (!ifp->if_watchdog)
+ ifp->if_watchdog = athn_watchdog;
IFQ_SET_READY(&ifp->if_snd);
memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
Index: src/sys/dev/usb/if_athn_usb.c
diff -u src/sys/dev/usb/if_athn_usb.c:1.6.8.17 src/sys/dev/usb/if_athn_usb.c:1.6.8.18
--- src/sys/dev/usb/if_athn_usb.c:1.6.8.17 Wed Dec 28 19:36:03 2016
+++ src/sys/dev/usb/if_athn_usb.c Wed Dec 28 19:41:41 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: if_athn_usb.c,v 1.6.8.17 2016/12/28 19:36:03 skrll Exp $ */
+/* $NetBSD: if_athn_usb.c,v 1.6.8.18 2016/12/28 19:41:41 skrll Exp $ */
/* $OpenBSD: if_athn_usb.c,v 1.12 2013/01/14 09:50:31 jsing Exp $ */
/*-
@@ -22,7 +22,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_athn_usb.c,v 1.6.8.17 2016/12/28 19:36:03 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_athn_usb.c,v 1.6.8.18 2016/12/28 19:41:41 skrll Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -144,7 +144,7 @@ Static void athn_usb_rxeof(struct usbd_x
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(struct ifnet *, int disable);
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 *,
@@ -157,7 +157,6 @@ Static void athn_usb_txeof(struct usbd_x
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 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 *,
@@ -274,6 +273,9 @@ athn_usb_attach(device_t parent, device_
mutex_init(&usc->usc_lock, MUTEX_DEFAULT, IPL_NONE);
+ cv_init(&usc->usc_wmi_cv, "athnwmi");
+ cv_init(&usc->usc_htc_cv, "athnhtc");
+
cv_init(&usc->usc_cmd_cv, "athncmd");
mutex_init(&usc->usc_cmd_mtx, MUTEX_DEFAULT, IPL_SOFTUSB);
cv_init(&usc->usc_msg_cv, "athnmsg");
@@ -337,6 +339,8 @@ athn_usb_attach(device_t parent, device_
cv_destroy(&usc->usc_cmd_cv);
cv_destroy(&usc->usc_msg_cv);
+ cv_destroy(&usc->usc_wmi_cv);
+ cv_destroy(&usc->usc_htc_cv);
mutex_destroy(&usc->usc_lock);
mutex_destroy(&usc->usc_cmd_mtx);
@@ -385,7 +389,7 @@ athn_usb_attachhook(device_t arg)
struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = &sc->sc_if;
size_t i;
- int s, error;
+ int error;
if (usc->usc_dying)
return;
@@ -406,24 +410,24 @@ athn_usb_attachhook(device_t arg)
return;
/* We're now ready to attach the bus agnostic driver. */
- s = splnet();
ic->ic_ifp = ifp;
ic->ic_updateslot = athn_usb_updateslot;
sc->sc_max_aid = AR_USB_MAX_STA; /* Firmware is limited to 8 STA */
sc->sc_media_change = athn_usb_media_change;
- error = athn_attach(sc);
- if (error != 0) {
- splx(s);
- return;
- }
- usc->usc_athn_attached = 1;
/* Override some operations for USB. */
ifp->if_init = athn_usb_init;
+ ifp->if_stop = athn_usb_stop;
ifp->if_ioctl = athn_usb_ioctl;
ifp->if_start = athn_usb_start;
ifp->if_watchdog = athn_usb_watchdog;
+ error = athn_attach(sc);
+ if (error != 0) {
+ return;
+ }
+ usc->usc_athn_attached = 1;
+
/* hooks for HostAP association and disassociation */
ic->ic_newassoc = athn_usb_newassoc;
usc->usc_node_cleanup = ic->ic_node_cleanup;
@@ -441,7 +445,6 @@ athn_usb_attachhook(device_t arg)
ic->ic_newstate = athn_usb_newstate;
ops->rx_enable = athn_usb_rx_enable;
- splx(s);
/* Reset HW key cache entries. */
for (i = 0; i < sc->sc_kc_entries; i++)
@@ -465,30 +468,47 @@ athn_usb_detach(device_t self, int flags
{
struct athn_usb_softc *usc = device_private(self);
struct athn_softc *sc = &usc->usc_sc;
- int s;
+ int error;
DPRINTFN(DBG_FN, usc, "\n");
- s = splusb();
+ mutex_enter(&usc->usc_lock);
usc->usc_dying = 1;
+ mutex_exit(&usc->usc_lock);
mutex_enter(&usc->usc_cmd_mtx);
- athn_usb_wait_cmd(usc);
+ while (usc->usc_wmiactive) {
+ error = cv_timedwait(&usc->usc_wmi_cv, &usc->usc_cmd_mtx, hz);
+
+ if (error) {
+ mutex_exit(&usc->usc_cmd_mtx);
+ return error;
+ }
+ }
mutex_exit(&usc->usc_cmd_mtx);
+
mutex_enter(&usc->usc_msg_mtx);
- athn_usb_wait_msg(usc);
+ while (usc->usc_htcactive) {
+ error = cv_timedwait(&usc->usc_htc_cv, &usc->usc_msg_mtx, hz);
+
+ if (error) {
+ mutex_exit(&usc->usc_msg_mtx);
+ return error;
+ }
+ }
mutex_exit(&usc->usc_msg_mtx);
+
athn_usb_wait_async(usc);
usb_rem_task(usc->usc_udev, &usc->usc_task);
+ /* Abort Tx/Rx pipes. */
+ athn_usb_abort_pipes(usc);
+
if (usc->usc_athn_attached) {
usc->usc_athn_attached = 0;
athn_detach(sc);
}
- /* Abort Tx/Rx pipes. */
- athn_usb_abort_pipes(usc);
- splx(s);
/* Free Tx/Rx buffers. */
athn_usb_free_rx_list(usc);
@@ -507,6 +527,7 @@ athn_usb_detach(device_t self, int flags
mutex_destroy(&usc->usc_msg_mtx);
cv_destroy(&usc->usc_msg_cv);
+ cv_destroy(&usc->usc_wmi_cv);
mutex_destroy(&usc->usc_lock);
usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, usc->usc_udev, sc->sc_dev);
@@ -952,19 +973,30 @@ athn_usb_load_firmware(struct athn_usb_s
USETW(req.wLength, 0);
mutex_enter(&usc->usc_msg_mtx);
- error = athn_usb_wait_msg(usc);
- if (error) {
- mutex_exit(&usc->usc_msg_mtx);
- return error;
+ while (usc->usc_htcactive) {
+ error = cv_timedwait(&usc->usc_htc_cv, &usc->usc_msg_mtx, hz);
+
+ if (error) {
+ mutex_exit(&usc->usc_msg_mtx);
+ return error;
+ }
}
+ usc->usc_htcactive = true;
+
+ KASSERT(usc->usc_wait_msg_id == 0);
usc->usc_wait_msg_id = AR_HTC_MSG_READY;
+ mutex_exit(&usc->usc_msg_mtx);
+
error = usbd_do_request(usc->usc_udev, &req, NULL);
+ mutex_enter(&usc->usc_msg_mtx);
/* Wait at most 1 second for firmware to boot. */
if (error == 0)
error = athn_usb_wait_msg(usc);
+ usc->usc_htcactive = false;
+ cv_broadcast(&usc->usc_htc_cv);
mutex_exit(&usc->usc_msg_mtx);
DPRINTFN(DBG_FN, sc, "return %d\n", error);
@@ -985,8 +1017,6 @@ athn_usb_htc_msg(struct athn_usb_softc *
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;
@@ -1011,6 +1041,18 @@ athn_usb_htc_setup(struct athn_usb_softc
struct ar_htc_msg_config_pipe cfg;
int error;
+ mutex_enter(&usc->usc_msg_mtx);
+ while (usc->usc_htcactive) {
+ error = cv_timedwait(&usc->usc_htc_cv, &usc->usc_msg_mtx, hz);
+
+ if (error) {
+ mutex_exit(&usc->usc_msg_mtx);
+ return error;
+ }
+ }
+ usc->usc_htcactive = true;
+ mutex_exit(&usc->usc_msg_mtx);
+
/*
* Connect WMI services to USB pipes.
*/
@@ -1057,38 +1099,40 @@ athn_usb_htc_setup(struct athn_usb_softc
cfg.credits = (usc->usc_flags & ATHN_USB_FLAG_AR7010) ? 45 : 33;
mutex_enter(&usc->usc_msg_mtx);
- error = athn_usb_wait_msg(usc);
- if (error) {
- mutex_exit(&usc->usc_msg_mtx);
- return error;
- }
+ KASSERT(usc->usc_wait_msg_id == 0);
usc->usc_wait_msg_id = AR_HTC_MSG_CONF_PIPE_RSP;
+ mutex_exit(&usc->usc_msg_mtx);
+
error = athn_usb_htc_msg(usc, AR_HTC_MSG_CONF_PIPE, &cfg, sizeof(cfg));
if (error != 0) {
aprint_error_dev(usc->usc_dev, "could not request pipe configurations\n");
- mutex_exit(&usc->usc_msg_mtx);
return error;
}
+
+ mutex_enter(&usc->usc_msg_mtx);
error = athn_usb_wait_msg(usc);
if (error) {
mutex_exit(&usc->usc_msg_mtx);
return error;
}
+ mutex_exit(&usc->usc_msg_mtx);
error = athn_usb_htc_msg(usc, AR_HTC_MSG_SETUP_COMPLETE, NULL, 0);
if (error != 0) {
aprint_error_dev(usc->usc_dev, "could not request complete setup\n");
- mutex_exit(&usc->usc_msg_mtx);
return error;
}
+ mutex_enter(&usc->usc_msg_mtx);
error = athn_usb_wait_msg(usc);
if (error) {
mutex_exit(&usc->usc_msg_mtx);
return error;
}
+ usc->usc_htcactive = false;
+ cv_broadcast(&usc->usc_htc_cv);
mutex_exit(&usc->usc_msg_mtx);
return 0;
@@ -1110,12 +1154,14 @@ athn_usb_htc_connect_svc(struct athn_usb
msg.ul_pipeid = UE_GET_ADDR(ul_pipe);
mutex_enter(&usc->usc_msg_mtx);
- athn_usb_wait_msg(usc);
-
+ KASSERT(usc->usc_wait_msg_id == 0);
usc->usc_msg_conn_svc_rsp = &rsp;
-
usc->usc_wait_msg_id = AR_HTC_MSG_CONN_SVC_RSP;
+ mutex_exit(&usc->usc_msg_mtx);
+
error = athn_usb_htc_msg(usc, AR_HTC_MSG_CONN_SVC, &msg, sizeof(msg));
+
+ mutex_enter(&usc->usc_msg_mtx);
if (error == 0)
error = athn_usb_wait_msg(usc);
@@ -1155,29 +1201,13 @@ athn_usb_wait_msg(struct athn_usb_softc
return error;
}
-Static int
-athn_usb_wait_cmd(struct athn_usb_softc *usc)
-{
-
- 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;
-
-}
-
Static void
athn_usb_wmieof(struct usbd_xfer *xfer, void * priv,
usbd_status status)
{
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);
@@ -1190,21 +1220,13 @@ athn_usb_wmi_xcmd(struct athn_usb_softc
struct athn_usb_tx_data *data = &usc->usc_tx_cmd;
struct ar_htc_frame_hdr *htc;
struct ar_wmi_cmd_hdr *wmi;
- int error;
+ int error = 0;
if (usc->usc_dying)
return EIO;
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));
htc->endpoint_id = usc->usc_ep_ctrl;
@@ -1222,23 +1244,38 @@ athn_usb_wmi_xcmd(struct athn_usb_softc
USBD_SHORT_XFER_OK, ATHN_USB_CMD_TIMEOUT,
athn_usb_wmieof);
+ mutex_enter(&usc->usc_cmd_mtx);
+ while (usc->usc_wmiactive) {
+ error = cv_timedwait(&usc->usc_wmi_cv, &usc->usc_cmd_mtx, hz);
+
+ if (error) {
+ mutex_exit(&usc->usc_cmd_mtx);
+ return error;
+ }
+ }
+ usc->usc_wmiactive = true;
+
+ KASSERT(usc->usc_wait_cmd_id == 0);
usc->usc_wait_cmd_id = cmd_id;
usc->usc_obuf = obuf;
+ mutex_exit(&usc->usc_cmd_mtx);
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;
}
- error = athn_usb_wait_cmd(usc);
+ mutex_enter(&usc->usc_cmd_mtx);
+ while (usc->usc_wait_cmd_id)
+ error = cv_timedwait(&usc->usc_cmd_cv, &usc->usc_cmd_mtx, hz);
+ usc->usc_wmiactive = false;
+ cv_broadcast(&usc->usc_wmi_cv);
mutex_exit(&usc->usc_cmd_mtx);
- return error;
+ return 0;
}
#ifdef unused
@@ -1346,7 +1383,7 @@ athn_usb_media_change(struct ifnet *ifp)
error = ieee80211_media_change(ifp);
if (error == ENETRESET && IS_UP_AND_RUNNING(ifp)) {
- athn_usb_stop(ifp);
+ athn_usb_stop(ifp, 0);
error = athn_usb_init(ifp);
}
return error;
@@ -2641,7 +2678,7 @@ athn_usb_ioctl(struct ifnet *ifp, u_long
error = athn_usb_init(ifp);
break;
case IFF_RUNNING:
- athn_usb_stop(ifp);
+ athn_usb_stop(ifp, 0);
break;
case 0:
default:
@@ -2861,12 +2898,12 @@ athn_usb_init_locked(struct ifnet *ifp)
athn_usb_wait_async(usc);
return 0;
fail:
- athn_usb_stop(ifp);
+ athn_usb_stop(ifp, 0);
return error;
}
Static void
-athn_usb_stop(struct ifnet *ifp)
+athn_usb_stop(struct ifnet *ifp, int disable)
{
struct athn_softc *sc = ifp->if_softc;
struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc);
Index: src/sys/dev/usb/if_athn_usb.h
diff -u src/sys/dev/usb/if_athn_usb.h:1.2.16.4 src/sys/dev/usb/if_athn_usb.h:1.2.16.5
--- src/sys/dev/usb/if_athn_usb.h:1.2.16.4 Sun Dec 11 15:10:43 2016
+++ src/sys/dev/usb/if_athn_usb.h Wed Dec 28 19:41:41 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: if_athn_usb.h,v 1.2.16.4 2016/12/11 15:10:43 skrll Exp $ */
+/* $NetBSD: if_athn_usb.h,v 1.2.16.5 2016/12/28 19:41:41 skrll Exp $ */
/* $OpenBSD: if_athn_usb.h,v 1.3 2012/11/10 14:35:06 mikeb Exp $ */
/*-
@@ -444,6 +444,8 @@ struct athn_usb_softc {
int usc_athn_attached;
kmutex_t usc_lock;
+ kcondvar_t usc_wmi_cv;
+ kcondvar_t usc_htc_cv;
kmutex_t usc_msg_mtx;
kcondvar_t usc_msg_cv;
@@ -476,6 +478,8 @@ struct athn_usb_softc {
struct ar_wmi_cmd_reg_write usc_wbuf[AR_MAX_WRITE_COUNT];
int usc_wcount;
+ bool usc_wmiactive;
+ bool usc_htcactive;
uint16_t usc_wmi_seq_no;
uint16_t usc_wait_cmd_id;
uint16_t usc_wait_msg_id;