Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev Pull across from nick-nhusb.



details:   https://anonhg.NetBSD.org/src/rev/01bfca31700b
branches:  trunk
changeset: 821035:01bfca31700b
user:      skrll <skrll%NetBSD.org@localhost>
date:      Sat Jan 21 12:45:22 2017 +0000

description:
Pull across from nick-nhusb.

Some locking fixing, MPification and an attach fix

diffstat:

 sys/dev/ic/athn.c         |   16 ++-
 sys/dev/usb/if_athn_usb.c |  209 +++++++++++++++++++++++++++------------------
 sys/dev/usb/if_athn_usb.h |    6 +-
 3 files changed, 138 insertions(+), 93 deletions(-)

diffs (truncated from 530 to 300 lines):

diff -r 3fc3d6b35751 -r 01bfca31700b sys/dev/ic/athn.c
--- a/sys/dev/ic/athn.c Sat Jan 21 11:07:46 2017 +0000
+++ b/sys/dev/ic/athn.c Sat Jan 21 12:45:22 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: athn.c,v 1.13 2016/05/26 05:01:12 ozaki-r Exp $        */
+/*     $NetBSD: athn.c,v 1.14 2017/01/21 12:45:22 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.13 2016/05/26 05:01:12 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: athn.c,v 1.14 2017/01/21 12:45:22 skrll Exp $");
 
 #ifndef _MODULE
 #include "athn_usb.h"          /* for NATHN_USB */
@@ -329,10 +329,14 @@
 
        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);
 
diff -r 3fc3d6b35751 -r 01bfca31700b sys/dev/usb/if_athn_usb.c
--- a/sys/dev/usb/if_athn_usb.c Sat Jan 21 11:07:46 2017 +0000
+++ b/sys/dev/usb/if_athn_usb.c Sat Jan 21 12:45:22 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_athn_usb.c,v 1.20 2016/12/24 11:51:33 skrll Exp $   */
+/*     $NetBSD: if_athn_usb.c,v 1.21 2017/01/21 12:45:22 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.20 2016/12/24 11:51:33 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_athn_usb.c,v 1.21 2017/01/21 12:45:22 skrll Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -144,7 +144,7 @@
                    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_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 *,
@@ -273,7 +272,10 @@
        sc->sc_ops.write_barrier = athn_usb_write_barrier;
 
        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");
@@ -324,7 +326,7 @@
        return;
 
  fail:
- 
+
        /* Free Tx/Rx buffers. */
        athn_usb_abort_pipes(usc);
        athn_usb_free_tx_list(usc);
@@ -337,6 +339,8 @@
        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 @@
        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 @@
                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;
+
+       /* 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) {
-               splx(s);
                return;
        }
        usc->usc_athn_attached = 1;
 
-       /* Override some operations for USB. */
-       ifp->if_init = athn_usb_init;
-       ifp->if_ioctl = athn_usb_ioctl;
-       ifp->if_start = athn_usb_start;
-       ifp->if_watchdog = athn_usb_watchdog;
-
        /* hooks for HostAP association and disassociation */
        ic->ic_newassoc = athn_usb_newassoc;
        usc->usc_node_cleanup = ic->ic_node_cleanup;
@@ -441,7 +445,6 @@
        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 @@
 {
        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 @@
        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 @@
        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 @@
 
        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 @@
        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 @@
        cfg.credits = (usc->usc_flags & ATHN_USB_FLAG_AR7010) ? 45 : 33;
 
        mutex_enter(&usc->usc_msg_mtx);
+
+       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");
+               return error;
+       }
+
+       mutex_enter(&usc->usc_msg_mtx);
        error = athn_usb_wait_msg(usc);
        if (error) {
                mutex_exit(&usc->usc_msg_mtx);
                return error;
        }



Home | Main Index | Thread Index | Old Index