Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/nick-nhusb]: src/sys/dev/usb Sync with HEAD
details: https://anonhg.NetBSD.org/src/rev/c4a4165a8b76
branches: nick-nhusb
changeset: 334560:c4a4165a8b76
user: skrll <skrll%NetBSD.org@localhost>
date: Sun Dec 11 15:10:43 2016 +0000
description:
Sync with HEAD
diffstat:
sys/dev/usb/if_athn_usb.c | 379 ++++++++++++++++++++++++++++++---------------
sys/dev/usb/if_athn_usb.h | 11 +-
2 files changed, 262 insertions(+), 128 deletions(-)
diffs (truncated from 836 to 300 lines):
diff -r df58c10b381e -r c4a4165a8b76 sys/dev/usb/if_athn_usb.c
--- a/sys/dev/usb/if_athn_usb.c Mon Dec 05 10:54:48 2016 +0000
+++ b/sys/dev/usb/if_athn_usb.c Sun Dec 11 15:10:43 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_athn_usb.c,v 1.6.8.13 2016/12/05 10:55:18 skrll Exp $ */
+/* $NetBSD: if_athn_usb.c,v 1.6.8.14 2016/12/11 15:10:43 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.13 2016/12/05 10:55:18 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_athn_usb.c,v 1.6.8.14 2016/12/11 15:10:43 skrll Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -94,6 +94,7 @@
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 @@
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 @@
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_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_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 @@
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 @@
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 @@
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 @@
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,36 +762,65 @@
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)
{
struct athn_usb_softc *usc = arg;
struct athn_usb_host_cmd_ring *ring = &usc->usc_cmdq;
struct athn_usb_host_cmd *cmd;
- int s;
DPRINTFN(DBG_FN, usc, "\n");
/* Process host commands. */
- s = splusb();
mutex_spin_enter(&usc->usc_task_mtx);
while (ring->next != ring->cur) {
cmd = &ring->cmd[ring->next];
mutex_spin_exit(&usc->usc_task_mtx);
- splx(s);
/* Invoke callback. */
if (!usc->usc_dying)
cmd->cb(usc, cmd->data);
- s = splusb();
mutex_spin_enter(&usc->usc_task_mtx);
ring->queued--;
ring->next = (ring->next + 1) % ATHN_USB_HOST_CMD_RING_COUNT;
}
mutex_spin_exit(&usc->usc_task_mtx);
- wakeup(ring);
- splx(s);
+ cv_broadcast(&usc->usc_task_cv);
}
Static void
@@ -772,14 +829,12 @@
{
struct athn_usb_host_cmd_ring *ring = &usc->usc_cmdq;
struct athn_usb_host_cmd *cmd;
- int s;
if (usc->usc_dying)
return;
DPRINTFN(DBG_FN, usc, "\n");
- s = splusb();
mutex_spin_enter(&usc->usc_task_mtx);
cmd = &ring->cmd[ring->cur];
cmd->cb = cb;
@@ -789,12 +844,9 @@
/* If there is no pending command already, schedule a task. */
if (++ring->queued == 1) {
- mutex_spin_exit(&usc->usc_task_mtx);
usb_add_task(usc->usc_udev, &usc->usc_task, USB_TASKQ_DRIVER);
}
- else
- mutex_spin_exit(&usc->usc_task_mtx);
- splx(s);
+ mutex_spin_exit(&usc->usc_task_mtx);
}
Static void
@@ -821,7 +873,7 @@
u_char *fw, *ptr;
size_t size, remain;
uint32_t addr;
- int s, mlen, error;
+ int mlen, error;
DPRINTFN(DBG_FN, sc, "\n");
@@ -832,8 +884,7 @@
name = "athn-ar7010-11";
else
name = "athn-ar7010";
- }
- else
+ } else
name = "athn-ar9271";
/* Read firmware image from the filesystem. */
@@ -893,14 +944,24 @@
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;
}
@@ -908,7 +969,7 @@
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;
@@ -917,6 +978,8 @@
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;
@@ -931,13 +994,15 @@
sizeof(*htc) + sizeof(*msg) + len,
USBD_SHORT_XFER_OK, ATHN_USB_CMD_TIMEOUT, NULL);
return usbd_sync_transfer(data->xfer);
+
Home |
Main Index |
Thread Index |
Old Index