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 WIP MPification
details: https://anonhg.NetBSD.org/src/rev/afb646516ed5
branches: nick-nhusb
changeset: 334577:afb646516ed5
user: skrll <skrll%NetBSD.org@localhost>
date: Tue Dec 27 11:37:36 2016 +0000
description:
WIP MPification
diffstat:
sys/dev/usb/if_urndis.c | 162 +++++++++++++++++++++++++++++------------------
1 files changed, 98 insertions(+), 64 deletions(-)
diffs (truncated from 343 to 300 lines):
diff -r 39e810a69862 -r afb646516ed5 sys/dev/usb/if_urndis.c
--- a/sys/dev/usb/if_urndis.c Tue Dec 27 10:37:52 2016 +0000
+++ b/sys/dev/usb/if_urndis.c Tue Dec 27 11:37:36 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_urndis.c,v 1.9.4.11 2016/12/05 10:55:18 skrll Exp $ */
+/* $NetBSD: if_urndis.c,v 1.9.4.12 2016/12/27 11:37:36 skrll Exp $ */
/* $OpenBSD: if_urndis.c,v 1.31 2011/07/03 15:47:17 matthew Exp $ */
/*
@@ -21,7 +21,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_urndis.c,v 1.9.4.11 2016/12/05 10:55:18 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_urndis.c,v 1.9.4.12 2016/12/27 11:37:36 skrll Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@@ -75,13 +75,18 @@
#endif
static void urndis_start(struct ifnet *);
+static void urndis_start_locked(struct ifnet *);
static void urndis_rxeof(struct usbd_xfer *, void *, usbd_status);
static void urndis_txeof(struct usbd_xfer *, void *, usbd_status);
static int urndis_rx_list_init(struct urndis_softc *);
+static void urndis_rx_list_free(struct urndis_softc *);
static int urndis_tx_list_init(struct urndis_softc *);
+static void urndis_tx_list_free(struct urndis_softc *);
static int urndis_init(struct ifnet *);
+static int urndis_init_locked(struct ifnet *);
static void urndis_stop(struct ifnet *);
+static void urndis_stop_locked(struct ifnet *);
static usbd_status urndis_ctrl_msg(struct urndis_softc *, uint8_t, uint8_t,
uint16_t, uint16_t, void *, size_t);
@@ -879,7 +884,7 @@
bpf_mtap(ifp, m);
- if_percpuq_enqueue(ifp->if_percpuq, m);
+ if_percpuq_enqueue(sc->urndis_ipq, m);
}
splx(s);
@@ -941,6 +946,21 @@
return 0;
}
+static void
+urndis_rx_list_free(struct urndis_softc *sc)
+{
+ for (int i = 0; i < RNDIS_RX_LIST_CNT; i++) {
+ if (sc->sc_data.sc_rx_chain[i].sc_mbuf != NULL) {
+ m_freem(sc->sc_data.sc_rx_chain[i].sc_mbuf);
+ sc->sc_data.sc_rx_chain[i].sc_mbuf = NULL;
+ }
+ if (sc->sc_data.sc_rx_chain[i].sc_xfer != NULL) {
+ usbd_destroy_xfer(sc->sc_data.sc_rx_chain[i].sc_xfer);
+ sc->sc_data.sc_rx_chain[i].sc_xfer = NULL;
+ }
+ }
+}
+
static int
urndis_tx_list_init(struct urndis_softc *sc)
{
@@ -965,6 +985,21 @@
return 0;
}
+static void
+urndis_tx_list_free(struct urndis_softc *sc)
+{
+ for (int i = 0; i < RNDIS_TX_LIST_CNT; i++) {
+ if (sc->sc_data.sc_tx_chain[i].sc_mbuf != NULL) {
+ m_freem(sc->sc_data.sc_tx_chain[i].sc_mbuf);
+ sc->sc_data.sc_tx_chain[i].sc_mbuf = NULL;
+ }
+ if (sc->sc_data.sc_tx_chain[i].sc_xfer != NULL) {
+ usbd_destroy_xfer(sc->sc_data.sc_tx_chain[i].sc_xfer);
+ sc->sc_data.sc_tx_chain[i].sc_xfer = NULL;
+ }
+ }
+}
+
static int
urndis_ioctl(struct ifnet *ifp, unsigned long command, void *data)
{
@@ -979,24 +1014,7 @@
s = splnet();
- switch(command) {
- case SIOCSIFFLAGS:
- if ((error = ifioctl_common(ifp, command, data)) != 0)
- break;
- if (ifp->if_flags & IFF_UP) {
- if (!(ifp->if_flags & IFF_RUNNING))
- urndis_init(ifp);
- } else {
- if (ifp->if_flags & IFF_RUNNING)
- urndis_stop(ifp);
- }
- error = 0;
- break;
-
- default:
- error = ether_ioctl(ifp, command, data);
- break;
- }
+ error = ether_ioctl(ifp, command, data);
if (error == ENETRESET)
error = 0;
@@ -1026,8 +1044,20 @@
static int
urndis_init(struct ifnet *ifp)
{
+ struct urndis_softc *sc = ifp->if_softc;
+
+ mutex_enter(&sc->urndis_lock);
+ int ret = urndis_init_locked(ifp);
+ mutex_exit(&sc->urndis_lock);
+
+ return ret;
+}
+
+static int
+urndis_init_locked(struct ifnet *ifp)
+{
struct urndis_softc *sc;
- int i, s;
+ int i;
int err;
usbd_status usberr;
@@ -1040,15 +1070,12 @@
if (err != RNDIS_STATUS_SUCCESS)
return EIO;
- s = splnet();
-
usberr = usbd_open_pipe(sc->sc_iface_data, sc->sc_bulkin_no,
USBD_EXCLUSIVE_USE, &sc->sc_bulkin_pipe);
if (usberr) {
printf("%s: open rx pipe failed: %s\n", DEVNAME(sc),
usbd_errstr(err));
- splx(s);
- return EIO;
+ goto fail;
}
usberr = usbd_open_pipe(sc->sc_iface_data, sc->sc_bulkout_no,
@@ -1056,24 +1083,21 @@
if (usberr) {
printf("%s: open tx pipe failed: %s\n", DEVNAME(sc),
usbd_errstr(err));
- splx(s);
- return EIO;
+ goto fail2;
}
err = urndis_tx_list_init(sc);
if (err) {
printf("%s: tx list init failed\n",
DEVNAME(sc));
- splx(s);
- return err;
+ goto fail3;
}
err = urndis_rx_list_init(sc);
if (err) {
printf("%s: rx list init failed\n",
DEVNAME(sc));
- splx(s);
- return err;
+ goto fail4;
}
for (i = 0; i < RNDIS_RX_LIST_CNT; i++) {
@@ -1089,16 +1113,33 @@
ifp->if_flags |= IFF_RUNNING;
ifp->if_flags &= ~IFF_OACTIVE;
- splx(s);
return 0;
+
+fail4:
+ urndis_tx_list_free(sc);
+fail3:
+ usbd_close_pipe(sc->sc_bulkout_pipe);
+fail2:
+ usbd_close_pipe(sc->sc_bulkin_pipe);
+fail:
+ return EIO;
}
static void
urndis_stop(struct ifnet *ifp)
{
+ struct urndis_softc *sc = ifp->if_softc;
+
+ mutex_enter(&sc->urndis_lock);
+ urndis_stop_locked(ifp);
+ mutex_exit(&sc->urndis_lock);
+}
+
+static void
+urndis_stop_locked(struct ifnet *ifp)
+{
struct urndis_softc *sc;
usbd_status err;
- int i;
sc = ifp->if_softc;
@@ -1119,27 +1160,9 @@
DEVNAME(sc), usbd_errstr(err));
}
- for (i = 0; i < RNDIS_RX_LIST_CNT; i++) {
- if (sc->sc_data.sc_rx_chain[i].sc_mbuf != NULL) {
- m_freem(sc->sc_data.sc_rx_chain[i].sc_mbuf);
- sc->sc_data.sc_rx_chain[i].sc_mbuf = NULL;
- }
- if (sc->sc_data.sc_rx_chain[i].sc_xfer != NULL) {
- usbd_destroy_xfer(sc->sc_data.sc_rx_chain[i].sc_xfer);
- sc->sc_data.sc_rx_chain[i].sc_xfer = NULL;
- }
- }
+ urndis_tx_list_free(sc);
- for (i = 0; i < RNDIS_TX_LIST_CNT; i++) {
- if (sc->sc_data.sc_tx_chain[i].sc_mbuf != NULL) {
- m_freem(sc->sc_data.sc_tx_chain[i].sc_mbuf);
- sc->sc_data.sc_tx_chain[i].sc_mbuf = NULL;
- }
- if (sc->sc_data.sc_tx_chain[i].sc_xfer != NULL) {
- usbd_destroy_xfer(sc->sc_data.sc_tx_chain[i].sc_xfer);
- sc->sc_data.sc_tx_chain[i].sc_xfer = NULL;
- }
- }
+ urndis_rx_list_free(sc);
/* Close pipes. */
if (sc->sc_bulkin_pipe != NULL) {
@@ -1162,6 +1185,17 @@
static void
urndis_start(struct ifnet *ifp)
{
+ struct urndis_softc *sc = ifp->if_softc;
+ KASSERT(ifp->if_extflags & IFEF_START_MPSAFE);
+
+ mutex_enter(&sc->urndis_txlock);
+ urndis_start_locked(ifp);
+ mutex_exit(&sc->urndis_txlock);
+}
+
+static void
+urndis_start_locked(struct ifnet *ifp)
+{
struct urndis_softc *sc;
struct mbuf *m_head = NULL;
@@ -1330,7 +1364,6 @@
usbd_desc_iter_t iter;
int if_ctl, if_data;
int i, j, altcnt;
- int s;
u_char eaddr[ETHER_ADDR_LEN];
void *buf;
size_t bufsz;
@@ -1355,6 +1388,10 @@
sc->sc_ifaceno_ctl = if_ctl;
if_data = -1;
+ mutex_init(&sc->urndis_lock, MUTEX_DEFAULT, IPL_NONE);
+ mutex_init(&sc->urndis_txlock, MUTEX_DEFAULT, IPL_SOFTUSB);
+ mutex_init(&sc->urndis_rxlock, MUTEX_DEFAULT, IPL_SOFTUSB);
+
usb_desc_iter_init(sc->sc_udev, &iter);
while ((desc = (const void *)usb_desc_iter_next(&iter)) != NULL) {
@@ -1442,11 +1479,12 @@
aprint_error("%s: could not find data bulk out\n",DEVNAME(sc));
return;
- found:
+found:
ifp = GET_IFP(sc);
ifp->if_softc = sc;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+ ifp->if_extflags = IFEF_START_MPSAFE;
ifp->if_start = urndis_start;
ifp->if_ioctl = urndis_ioctl;
ifp->if_init = urndis_init;
Home |
Main Index |
Thread Index |
Old Index