Module Name: src
Committed By: mrg
Date: Fri Aug 9 06:38:39 UTC 2019
Modified Files:
src/sys/dev/usb: TODO files.usb if_urndis.c
Log Message:
switch urndis(4) to usbnet. thanks to maya@ for testing and helping
fix the few issues in the conversion.
To generate a diff of this commit:
cvs rdiff -u -r1.49 -r1.50 src/sys/dev/usb/TODO
cvs rdiff -u -r1.161 -r1.162 src/sys/dev/usb/files.usb
cvs rdiff -u -r1.25 -r1.26 src/sys/dev/usb/if_urndis.c
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/usb/TODO
diff -u src/sys/dev/usb/TODO:1.49 src/sys/dev/usb/TODO:1.50
--- src/sys/dev/usb/TODO:1.49 Fri Aug 9 02:56:51 2019
+++ src/sys/dev/usb/TODO Fri Aug 9 06:38:39 2019
@@ -73,7 +73,7 @@ Factor out the common code from the Ethe
if_upl - patch available
if_ure - done
if_url - patch available
- if_urndis - patch available, probably works
+ if_urndis - done
Get rid of hcpriv.
Index: src/sys/dev/usb/files.usb
diff -u src/sys/dev/usb/files.usb:1.161 src/sys/dev/usb/files.usb:1.162
--- src/sys/dev/usb/files.usb:1.161 Wed Aug 7 19:21:48 2019
+++ src/sys/dev/usb/files.usb Fri Aug 9 06:38:39 2019
@@ -1,4 +1,4 @@
-# $NetBSD: files.usb,v 1.161 2019/08/07 19:21:48 skrll Exp $
+# $NetBSD: files.usb,v 1.162 2019/08/09 06:38:39 mrg Exp $
#
# Config file and device description for machine-independent USB code.
# Included by ports that need it. Ports that use it must provide
@@ -528,7 +528,7 @@ attach uyurex at uhidbus
file dev/usb/uyurex.c uyurex
# Microsoft RNDIS
-device urndis: arp, ether, ifnet
+device urndis: arp, ether, ifnet, usbnet
attach urndis at usbifif
file dev/usb/if_urndis.c urndis
Index: src/sys/dev/usb/if_urndis.c
diff -u src/sys/dev/usb/if_urndis.c:1.25 src/sys/dev/usb/if_urndis.c:1.26
--- src/sys/dev/usb/if_urndis.c:1.25 Thu Aug 8 18:03:40 2019
+++ src/sys/dev/usb/if_urndis.c Fri Aug 9 06:38:39 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: if_urndis.c,v 1.25 2019/08/08 18:03:40 mrg Exp $ */
+/* $NetBSD: if_urndis.c,v 1.26 2019/08/09 06:38:39 mrg 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.25 2019/08/08 18:03:40 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_urndis.c,v 1.26 2019/08/09 06:38:39 mrg Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@@ -29,28 +29,10 @@ __KERNEL_RCSID(0, "$NetBSD: if_urndis.c,
#include <sys/param.h>
#include <sys/systm.h>
-#include <sys/sockio.h>
-#include <sys/rwlock.h>
-#include <sys/mbuf.h>
#include <sys/kmem.h>
#include <sys/kernel.h>
-#include <sys/proc.h>
-#include <sys/socket.h>
-#include <sys/device.h>
-#include <sys/endian.h>
-
-#include <net/if.h>
-#include <net/if_dl.h>
-#include <net/if_media.h>
-#include <net/if_ether.h>
-
-#include <net/bpf.h>
-
-#include <sys/bus.h>
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usbdivar.h>
+
+#include <dev/usb/usbnet.h>
#include <dev/usb/usbdevs.h>
#include <dev/usb/usbcdc.h>
@@ -60,48 +42,16 @@ __KERNEL_RCSID(0, "$NetBSD: if_urndis.c,
#define RNDIS_TX_LIST_CNT 1
#define RNDIS_BUFSZ 1562
-struct urndis_softc;
-
-struct urndis_chain {
- struct urndis_softc *sc_softc;
- struct usbd_xfer *sc_xfer;
- char *sc_buf;
- struct mbuf *sc_mbuf;
-};
-
-struct urndis_cdata {
- struct urndis_chain sc_rx_chain[RNDIS_RX_LIST_CNT];
- struct urndis_chain sc_tx_chain[RNDIS_TX_LIST_CNT];
- int sc_tx_cnt;
-};
-
-#define GET_IFP(sc) (&(sc)->sc_ec.ec_if)
struct urndis_softc {
- device_t sc_dev;
+ struct usbnet sc_un;
- char sc_attached;
- int sc_dying;
- struct ethercom sc_ec;
+ int sc_ifaceno_ctl;
/* RNDIS device info */
uint32_t sc_filter;
uint32_t sc_maxppt;
uint32_t sc_maxtsz;
uint32_t sc_palign;
-
- /* USB goo */
- struct usbd_device * sc_udev;
- int sc_ifaceno_ctl;
- struct usbd_interface * sc_iface_ctl;
- struct usbd_interface * sc_iface_data;
-
- struct timeval sc_rx_notice;
- int sc_bulkin_no;
- struct usbd_pipe * sc_bulkin_pipe;
- int sc_bulkout_no;
- struct usbd_pipe * sc_bulkout_pipe;
-
- struct urndis_cdata sc_data;
};
#ifdef URNDIS_DEBUG
@@ -110,69 +60,45 @@ struct urndis_softc {
#define DPRINTF(x)
#endif
-#define DEVNAME(sc) (device_xname(sc->sc_dev))
+#define DEVNAME(un) (device_xname(un->un_dev))
#define URNDIS_RESPONSE_LEN 0x400
-
-static int urndis_newbuf(struct urndis_softc *, struct urndis_chain *);
-
-static int urndis_ioctl(struct ifnet *, unsigned long, void *);
#if 0
static void urndis_watchdog(struct ifnet *);
#endif
-static void urndis_start(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 int urndis_tx_list_init(struct urndis_softc *);
-
static int urndis_init(struct ifnet *);
-static void urndis_stop(struct ifnet *);
+static void urndis_rx_loop(struct usbnet *, struct usbd_xfer *,
+ struct usbnet_chain *, uint32_t);
+static unsigned urndis_tx_prepare(struct usbnet *, struct mbuf *,
+ struct usbnet_chain *);
+
+static int urndis_init_un(struct ifnet *, struct usbnet *);
-static usbd_status urndis_ctrl_msg(struct urndis_softc *, uint8_t, uint8_t,
- uint16_t, uint16_t, void *, size_t);
-static usbd_status urndis_ctrl_send(struct urndis_softc *, void *, size_t);
-static struct rndis_comp_hdr *urndis_ctrl_recv(struct urndis_softc *);
-
-static uint32_t urndis_ctrl_handle(struct urndis_softc *,
- struct rndis_comp_hdr *, void **, size_t *);
-static uint32_t urndis_ctrl_handle_init(struct urndis_softc *,
+static uint32_t urndis_ctrl_handle_init(struct usbnet *,
const struct rndis_comp_hdr *);
-static uint32_t urndis_ctrl_handle_query(struct urndis_softc *,
+static uint32_t urndis_ctrl_handle_query(struct usbnet *,
const struct rndis_comp_hdr *, void **, size_t *);
-static uint32_t urndis_ctrl_handle_reset(struct urndis_softc *,
+static uint32_t urndis_ctrl_handle_reset(struct usbnet *,
const struct rndis_comp_hdr *);
-static uint32_t urndis_ctrl_handle_status(struct urndis_softc *,
+static uint32_t urndis_ctrl_handle_status(struct usbnet *,
const struct rndis_comp_hdr *);
-static uint32_t urndis_ctrl_init(struct urndis_softc *);
-#if 0
-static uint32_t urndis_ctrl_halt(struct urndis_softc *);
-#endif
-static uint32_t urndis_ctrl_query(struct urndis_softc *, uint32_t, void *,
- size_t, void **, size_t *);
-static uint32_t urndis_ctrl_set(struct urndis_softc *, uint32_t, void *,
+static uint32_t urndis_ctrl_set(struct usbnet *, uint32_t, void *,
size_t);
-#if 0
-static uint32_t urndis_ctrl_set_param(struct urndis_softc *, const char *,
- uint32_t, void *, size_t);
-static uint32_t urndis_ctrl_reset(struct urndis_softc *);
-static uint32_t urndis_ctrl_keepalive(struct urndis_softc *);
-#endif
-
-static int urndis_encap(struct urndis_softc *, struct mbuf *, int);
-static void urndis_decap(struct urndis_softc *, struct urndis_chain *,
- uint32_t);
static int urndis_match(device_t, cfdata_t, void *);
static void urndis_attach(device_t, device_t, void *);
-static int urndis_detach(device_t, int);
-static int urndis_activate(device_t, enum devact);
+
+static struct usbnet_ops urndis_ops = {
+ .uno_init = urndis_init,
+ .uno_tx_prepare = urndis_tx_prepare,
+ .uno_rx_loop = urndis_rx_loop,
+};
CFATTACH_DECL_NEW(urndis, sizeof(struct urndis_softc),
- urndis_match, urndis_attach, urndis_detach, urndis_activate);
+ urndis_match, urndis_attach, usbnet_detach, usbnet_activate);
/*
* Supported devices that we can't match by class IDs.
@@ -184,7 +110,7 @@ static const struct usb_devno urndis_dev
};
static usbd_status
-urndis_ctrl_msg(struct urndis_softc *sc, uint8_t rt, uint8_t r,
+urndis_ctrl_msg(struct usbnet *un, uint8_t rt, uint8_t r,
uint16_t index, uint16_t value, void *buf, size_t buflen)
{
usb_device_request_t req;
@@ -195,52 +121,57 @@ urndis_ctrl_msg(struct urndis_softc *sc,
USETW(req.wIndex, index);
USETW(req.wLength, buflen);
- return usbd_do_request(sc->sc_udev, &req, buf);
+ return usbd_do_request(un->un_udev, &req, buf);
}
static usbd_status
-urndis_ctrl_send(struct urndis_softc *sc, void *buf, size_t len)
+urndis_ctrl_send(struct usbnet *un, void *buf, size_t len)
{
+ struct urndis_softc *sc = usbnet_softc(un);
usbd_status err;
- if (sc->sc_dying)
+ if (un->un_dying)
return(0);
- err = urndis_ctrl_msg(sc, UT_WRITE_CLASS_INTERFACE, UR_GET_STATUS,
+ err = urndis_ctrl_msg(un, UT_WRITE_CLASS_INTERFACE, UR_GET_STATUS,
sc->sc_ifaceno_ctl, 0, buf, len);
if (err != USBD_NORMAL_COMPLETION)
- printf("%s: %s\n", DEVNAME(sc), usbd_errstr(err));
+ printf("%s: %s\n", DEVNAME(un), usbd_errstr(err));
return err;
}
static struct rndis_comp_hdr *
-urndis_ctrl_recv(struct urndis_softc *sc)
+urndis_ctrl_recv(struct usbnet *un)
{
+ struct urndis_softc *sc = usbnet_softc(un);
struct rndis_comp_hdr *hdr;
char *buf;
usbd_status err;
+ if (un->un_dying)
+ return(0);
+
buf = kmem_alloc(URNDIS_RESPONSE_LEN, KM_SLEEP);
- err = urndis_ctrl_msg(sc, UT_READ_CLASS_INTERFACE, UR_CLEAR_FEATURE,
+ err = urndis_ctrl_msg(un, UT_READ_CLASS_INTERFACE, UR_CLEAR_FEATURE,
sc->sc_ifaceno_ctl, 0, buf, URNDIS_RESPONSE_LEN);
if (err != USBD_NORMAL_COMPLETION && err != USBD_SHORT_XFER) {
- printf("%s: %s\n", DEVNAME(sc), usbd_errstr(err));
+ printf("%s: %s\n", DEVNAME(un), usbd_errstr(err));
kmem_free(buf, URNDIS_RESPONSE_LEN);
return NULL;
}
hdr = (struct rndis_comp_hdr *)buf;
DPRINTF(("%s: urndis_ctrl_recv: type 0x%x len %u\n",
- DEVNAME(sc),
+ DEVNAME(un),
le32toh(hdr->rm_type),
le32toh(hdr->rm_len)));
if (le32toh(hdr->rm_len) > URNDIS_RESPONSE_LEN) {
printf("%s: ctrl message error: wrong size %u > %u\n",
- DEVNAME(sc),
+ DEVNAME(un),
le32toh(hdr->rm_len),
URNDIS_RESPONSE_LEN);
kmem_free(buf, URNDIS_RESPONSE_LEN);
@@ -251,12 +182,12 @@ urndis_ctrl_recv(struct urndis_softc *sc
}
static uint32_t
-urndis_ctrl_handle(struct urndis_softc *sc, struct rndis_comp_hdr *hdr,
+urndis_ctrl_handle(struct usbnet *un, struct rndis_comp_hdr *hdr,
void **buf, size_t *bufsz)
{
uint32_t rval;
- DPRINTF(("%s: urndis_ctrl_handle\n", DEVNAME(sc)));
+ DPRINTF(("%s: urndis_ctrl_handle\n", DEVNAME(un)));
if (buf && bufsz) {
*buf = NULL;
@@ -265,15 +196,15 @@ urndis_ctrl_handle(struct urndis_softc *
switch (le32toh(hdr->rm_type)) {
case REMOTE_NDIS_INITIALIZE_CMPLT:
- rval = urndis_ctrl_handle_init(sc, hdr);
+ rval = urndis_ctrl_handle_init(un, hdr);
break;
case REMOTE_NDIS_QUERY_CMPLT:
- rval = urndis_ctrl_handle_query(sc, hdr, buf, bufsz);
+ rval = urndis_ctrl_handle_query(un, hdr, buf, bufsz);
break;
case REMOTE_NDIS_RESET_CMPLT:
- rval = urndis_ctrl_handle_reset(sc, hdr);
+ rval = urndis_ctrl_handle_reset(un, hdr);
break;
case REMOTE_NDIS_KEEPALIVE_CMPLT:
@@ -282,12 +213,12 @@ urndis_ctrl_handle(struct urndis_softc *
break;
case REMOTE_NDIS_INDICATE_STATUS_MSG:
- rval = urndis_ctrl_handle_status(sc, hdr);
+ rval = urndis_ctrl_handle_status(un, hdr);
break;
default:
printf("%s: ctrl message error: unknown event 0x%x\n",
- DEVNAME(sc), le32toh(hdr->rm_type));
+ DEVNAME(un), le32toh(hdr->rm_type));
rval = RNDIS_STATUS_FAILURE;
}
@@ -297,9 +228,9 @@ urndis_ctrl_handle(struct urndis_softc *
}
static uint32_t
-urndis_ctrl_handle_init(struct urndis_softc *sc,
- const struct rndis_comp_hdr *hdr)
+urndis_ctrl_handle_init(struct usbnet *un, const struct rndis_comp_hdr *hdr)
{
+ struct urndis_softc *sc = usbnet_softc(un);
const struct rndis_init_comp *msg;
msg = (const struct rndis_init_comp *) hdr;
@@ -307,7 +238,7 @@ urndis_ctrl_handle_init(struct urndis_so
DPRINTF(("%s: urndis_ctrl_handle_init: len %u rid %u status 0x%x "
"ver_major %u ver_minor %u devflags 0x%x medium 0x%x pktmaxcnt %u "
"pktmaxsz %u align %u aflistoffset %u aflistsz %u\n",
- DEVNAME(sc),
+ DEVNAME(un),
le32toh(msg->rm_len),
le32toh(msg->rm_rid),
le32toh(msg->rm_status),
@@ -323,7 +254,7 @@ urndis_ctrl_handle_init(struct urndis_so
if (le32toh(msg->rm_status) != RNDIS_STATUS_SUCCESS) {
printf("%s: init failed 0x%x\n",
- DEVNAME(sc),
+ DEVNAME(un),
le32toh(msg->rm_status));
return le32toh(msg->rm_status);
@@ -331,7 +262,7 @@ urndis_ctrl_handle_init(struct urndis_so
if (le32toh(msg->rm_devflags) != RNDIS_DF_CONNECTIONLESS) {
printf("%s: wrong device type (current type: 0x%x)\n",
- DEVNAME(sc),
+ DEVNAME(un),
le32toh(msg->rm_devflags));
return RNDIS_STATUS_FAILURE;
@@ -339,7 +270,7 @@ urndis_ctrl_handle_init(struct urndis_so
if (le32toh(msg->rm_medium) != RNDIS_MEDIUM_802_3) {
printf("%s: medium not 802.3 (current medium: 0x%x)\n",
- DEVNAME(sc), le32toh(msg->rm_medium));
+ DEVNAME(un), le32toh(msg->rm_medium));
return RNDIS_STATUS_FAILURE;
}
@@ -347,7 +278,7 @@ urndis_ctrl_handle_init(struct urndis_so
if (le32toh(msg->rm_ver_major) != RNDIS_MAJOR_VERSION ||
le32toh(msg->rm_ver_minor) != RNDIS_MINOR_VERSION) {
printf("%s: version not %u.%u (current version: %u.%u)\n",
- DEVNAME(sc), RNDIS_MAJOR_VERSION, RNDIS_MINOR_VERSION,
+ DEVNAME(un), RNDIS_MAJOR_VERSION, RNDIS_MINOR_VERSION,
le32toh(msg->rm_ver_major), le32toh(msg->rm_ver_minor));
return RNDIS_STATUS_FAILURE;
@@ -361,7 +292,7 @@ urndis_ctrl_handle_init(struct urndis_so
}
static uint32_t
-urndis_ctrl_handle_query(struct urndis_softc *sc,
+urndis_ctrl_handle_query(struct usbnet *un,
const struct rndis_comp_hdr *hdr, void **buf, size_t *bufsz)
{
const struct rndis_query_comp *msg;
@@ -370,7 +301,7 @@ urndis_ctrl_handle_query(struct urndis_s
DPRINTF(("%s: urndis_ctrl_handle_query: len %u rid %u status 0x%x "
"buflen %u bufoff %u\n",
- DEVNAME(sc),
+ DEVNAME(un),
le32toh(msg->rm_len),
le32toh(msg->rm_rid),
le32toh(msg->rm_status),
@@ -384,7 +315,7 @@ urndis_ctrl_handle_query(struct urndis_s
if (le32toh(msg->rm_status) != RNDIS_STATUS_SUCCESS) {
printf("%s: query failed 0x%x\n",
- DEVNAME(sc),
+ DEVNAME(un),
le32toh(msg->rm_status));
return le32toh(msg->rm_status);
@@ -395,7 +326,7 @@ urndis_ctrl_handle_query(struct urndis_s
printf("%s: ctrl message error: invalid query info "
"len/offset/end_position(%u/%u/%u) -> "
"go out of buffer limit %u\n",
- DEVNAME(sc),
+ DEVNAME(un),
le32toh(msg->rm_infobuflen),
le32toh(msg->rm_infobufoffset),
le32toh(msg->rm_infobuflen) +
@@ -419,9 +350,9 @@ urndis_ctrl_handle_query(struct urndis_s
}
static uint32_t
-urndis_ctrl_handle_reset(struct urndis_softc *sc,
- const struct rndis_comp_hdr *hdr)
+urndis_ctrl_handle_reset(struct usbnet *un, const struct rndis_comp_hdr *hdr)
{
+ struct urndis_softc *sc = usbnet_softc(un);
const struct rndis_reset_comp *msg;
uint32_t rval;
@@ -431,13 +362,13 @@ urndis_ctrl_handle_reset(struct urndis_s
DPRINTF(("%s: urndis_ctrl_handle_reset: len %u status 0x%x "
"adrreset %u\n",
- DEVNAME(sc),
+ DEVNAME(un),
le32toh(msg->rm_len),
rval,
le32toh(msg->rm_adrreset)));
if (rval != RNDIS_STATUS_SUCCESS) {
- printf("%s: reset failed 0x%x\n", DEVNAME(sc), rval);
+ printf("%s: reset failed 0x%x\n", DEVNAME(un), rval);
return rval;
}
@@ -445,11 +376,11 @@ urndis_ctrl_handle_reset(struct urndis_s
uint32_t filter;
filter = htole32(sc->sc_filter);
- rval = urndis_ctrl_set(sc, OID_GEN_CURRENT_PACKET_FILTER,
+ rval = urndis_ctrl_set(un, OID_GEN_CURRENT_PACKET_FILTER,
&filter, sizeof(filter));
if (rval != RNDIS_STATUS_SUCCESS) {
printf("%s: unable to reset data filters\n",
- DEVNAME(sc));
+ DEVNAME(un));
return rval;
}
}
@@ -458,7 +389,7 @@ urndis_ctrl_handle_reset(struct urndis_s
}
static uint32_t
-urndis_ctrl_handle_status(struct urndis_softc *sc,
+urndis_ctrl_handle_status(struct usbnet *un,
const struct rndis_comp_hdr *hdr)
{
const struct rndis_status_msg *msg;
@@ -470,7 +401,7 @@ urndis_ctrl_handle_status(struct urndis_
DPRINTF(("%s: urndis_ctrl_handle_status: len %u status 0x%x "
"stbuflen %u\n",
- DEVNAME(sc),
+ DEVNAME(un),
le32toh(msg->rm_len),
rval,
le32toh(msg->rm_stbuflen)));
@@ -483,14 +414,14 @@ urndis_ctrl_handle_status(struct urndis_
break;
default:
- printf("%s: status 0x%x\n", DEVNAME(sc), rval);
+ printf("%s: status 0x%x\n", DEVNAME(un), rval);
}
return rval;
}
static uint32_t
-urndis_ctrl_init(struct urndis_softc *sc)
+urndis_ctrl_init(struct usbnet *un)
{
struct rndis_init_req *msg;
uint32_t rval;
@@ -506,7 +437,7 @@ urndis_ctrl_init(struct urndis_softc *sc
DPRINTF(("%s: urndis_ctrl_init send: type %u len %u rid %u ver_major %u "
"ver_minor %u max_xfersz %u\n",
- DEVNAME(sc),
+ DEVNAME(un),
le32toh(msg->rm_type),
le32toh(msg->rm_len),
le32toh(msg->rm_rid),
@@ -514,26 +445,26 @@ urndis_ctrl_init(struct urndis_softc *sc
le32toh(msg->rm_ver_minor),
le32toh(msg->rm_max_xfersz)));
- rval = urndis_ctrl_send(sc, msg, sizeof(*msg));
+ rval = urndis_ctrl_send(un, msg, sizeof(*msg));
kmem_free(msg, sizeof(*msg));
if (rval != RNDIS_STATUS_SUCCESS) {
- printf("%s: init failed\n", DEVNAME(sc));
+ printf("%s: init failed\n", DEVNAME(un));
return rval;
}
- if ((hdr = urndis_ctrl_recv(sc)) == NULL) {
- printf("%s: unable to get init response\n", DEVNAME(sc));
+ if ((hdr = urndis_ctrl_recv(un)) == NULL) {
+ printf("%s: unable to get init response\n", DEVNAME(un));
return RNDIS_STATUS_FAILURE;
}
- rval = urndis_ctrl_handle(sc, hdr, NULL, NULL);
+ rval = urndis_ctrl_handle(un, hdr, NULL, NULL);
return rval;
}
#if 0
static uint32_t
-urndis_ctrl_halt(struct urndis_softc *sc)
+urndis_ctrl_halt(struct usbnet *un)
{
struct rndis_halt_req *msg;
uint32_t rval;
@@ -544,23 +475,23 @@ urndis_ctrl_halt(struct urndis_softc *sc
msg->rm_rid = 0;
DPRINTF(("%s: urndis_ctrl_halt send: type %u len %u rid %u\n",
- DEVNAME(sc),
+ DEVNAME(un),
le32toh(msg->rm_type),
le32toh(msg->rm_len),
le32toh(msg->rm_rid)));
- rval = urndis_ctrl_send(sc, msg, sizeof(*msg));
+ rval = urndis_ctrl_send(un, msg, sizeof(*msg));
kmem_free(msg, sizeof(*msg));
if (rval != RNDIS_STATUS_SUCCESS)
- printf("%s: halt failed\n", DEVNAME(sc));
+ printf("%s: halt failed\n", DEVNAME(un));
return rval;
}
#endif
static uint32_t
-urndis_ctrl_query(struct urndis_softc *sc, uint32_t oid,
+urndis_ctrl_query(struct usbnet *un, uint32_t oid,
void *qbuf, size_t qlen,
void **rbuf, size_t *rbufsz)
{
@@ -583,7 +514,7 @@ urndis_ctrl_query(struct urndis_softc *s
DPRINTF(("%s: urndis_ctrl_query send: type %u len %u rid %u oid 0x%x "
"infobuflen %u infobufoffset %u devicevchdl %u\n",
- DEVNAME(sc),
+ DEVNAME(un),
le32toh(msg->rm_type),
le32toh(msg->rm_len),
le32toh(msg->rm_rid),
@@ -592,25 +523,25 @@ urndis_ctrl_query(struct urndis_softc *s
le32toh(msg->rm_infobufoffset),
le32toh(msg->rm_devicevchdl)));
- rval = urndis_ctrl_send(sc, msg, sizeof(*msg));
+ rval = urndis_ctrl_send(un, msg, sizeof(*msg));
kmem_free(msg, sizeof(*msg) + qlen);
if (rval != RNDIS_STATUS_SUCCESS) {
- printf("%s: query failed\n", DEVNAME(sc));
+ printf("%s: query failed\n", DEVNAME(un));
return rval;
}
- if ((hdr = urndis_ctrl_recv(sc)) == NULL) {
- printf("%s: unable to get query response\n", DEVNAME(sc));
+ if ((hdr = urndis_ctrl_recv(un)) == NULL) {
+ printf("%s: unable to get query response\n", DEVNAME(un));
return RNDIS_STATUS_FAILURE;
}
- rval = urndis_ctrl_handle(sc, hdr, rbuf, rbufsz);
+ rval = urndis_ctrl_handle(un, hdr, rbuf, rbufsz);
return rval;
}
static uint32_t
-urndis_ctrl_set(struct urndis_softc *sc, uint32_t oid, void *buf, size_t len)
+urndis_ctrl_set(struct usbnet *un, uint32_t oid, void *buf, size_t len)
{
struct rndis_set_req *msg;
uint32_t rval;
@@ -631,7 +562,7 @@ urndis_ctrl_set(struct urndis_softc *sc,
DPRINTF(("%s: urndis_ctrl_set send: type %u len %u rid %u oid 0x%x "
"infobuflen %u infobufoffset %u devicevchdl %u\n",
- DEVNAME(sc),
+ DEVNAME(un),
le32toh(msg->rm_type),
le32toh(msg->rm_len),
le32toh(msg->rm_rid),
@@ -640,28 +571,28 @@ urndis_ctrl_set(struct urndis_softc *sc,
le32toh(msg->rm_infobufoffset),
le32toh(msg->rm_devicevchdl)));
- rval = urndis_ctrl_send(sc, msg, sizeof(*msg));
+ rval = urndis_ctrl_send(un, msg, sizeof(*msg));
kmem_free(msg, sizeof(*msg) + len);
if (rval != RNDIS_STATUS_SUCCESS) {
- printf("%s: set failed\n", DEVNAME(sc));
+ printf("%s: set failed\n", DEVNAME(un));
return rval;
}
- if ((hdr = urndis_ctrl_recv(sc)) == NULL) {
- printf("%s: unable to get set response\n", DEVNAME(sc));
+ if ((hdr = urndis_ctrl_recv(un)) == NULL) {
+ printf("%s: unable to get set response\n", DEVNAME(un));
return RNDIS_STATUS_FAILURE;
}
- rval = urndis_ctrl_handle(sc, hdr, NULL, NULL);
+ rval = urndis_ctrl_handle(un, hdr, NULL, NULL);
if (rval != RNDIS_STATUS_SUCCESS)
- printf("%s: set failed 0x%x\n", DEVNAME(sc), rval);
+ printf("%s: set failed 0x%x\n", DEVNAME(un), rval);
return rval;
}
#if 0
static uint32_t
-urndis_ctrl_set_param(struct urndis_softc *sc,
+urndis_ctrl_set_param(struct urndis_softc *un,
const char *name,
uint32_t type,
void *buf,
@@ -693,24 +624,24 @@ urndis_ctrl_set_param(struct urndis_soft
DPRINTF(("%s: urndis_ctrl_set_param send: nameoffset %u namelen %u "
"type 0x%x valueoffset %u valuelen %u\n",
- DEVNAME(sc),
+ DEVNAME(un),
le32toh(param->rm_nameoffset),
le32toh(param->rm_namelen),
le32toh(param->rm_type),
le32toh(param->rm_valueoffset),
le32toh(param->rm_valuelen)));
- rval = urndis_ctrl_set(sc, OID_GEN_RNDIS_CONFIG_PARAMETER, param, tlen);
+ rval = urndis_ctrl_set(un, OID_GEN_RNDIS_CONFIG_PARAMETER, param, tlen);
kmem_free(param, tlen);
if (rval != RNDIS_STATUS_SUCCESS)
- printf("%s: set param failed 0x%x\n", DEVNAME(sc), rval);
+ printf("%s: set param failed 0x%x\n", DEVNAME(un), rval);
return rval;
}
/* XXX : adrreset, get it from response */
static uint32_t
-urndis_ctrl_reset(struct urndis_softc *sc)
+urndis_ctrl_reset(struct usbnet *un)
{
struct rndis_reset_req *reset;
uint32_t rval;
@@ -722,30 +653,30 @@ urndis_ctrl_reset(struct urndis_softc *s
reset->rm_rid = 0; /* XXX rm_rid == reserved ... remove ? */
DPRINTF(("%s: urndis_ctrl_reset send: type %u len %u rid %u\n",
- DEVNAME(sc),
+ DEVNAME(un),
le32toh(reset->rm_type),
le32toh(reset->rm_len),
le32toh(reset->rm_rid)));
- rval = urndis_ctrl_send(sc, reset, sizeof(*reset));
+ rval = urndis_ctrl_send(un, reset, sizeof(*reset));
kmem_free(reset, sizeof(*reset));
if (rval != RNDIS_STATUS_SUCCESS) {
- printf("%s: reset failed\n", DEVNAME(sc));
+ printf("%s: reset failed\n", DEVNAME(un));
return rval;
}
- if ((hdr = urndis_ctrl_recv(sc)) == NULL) {
- printf("%s: unable to get reset response\n", DEVNAME(sc));
+ if ((hdr = urndis_ctrl_recv(un)) == NULL) {
+ printf("%s: unable to get reset response\n", DEVNAME(un));
return RNDIS_STATUS_FAILURE;
}
- rval = urndis_ctrl_handle(sc, hdr, NULL, NULL);
+ rval = urndis_ctrl_handle(un, hdr, NULL, NULL);
return rval;
}
static uint32_t
-urndis_ctrl_keepalive(struct urndis_softc *sc)
+urndis_ctrl_keepalive(struct usbnet *un)
{
struct rndis_keepalive_req *keep;
uint32_t rval;
@@ -757,43 +688,39 @@ urndis_ctrl_keepalive(struct urndis_soft
keep->rm_rid = 0; /* XXX rm_rid == reserved ... remove ? */
DPRINTF(("%s: urndis_ctrl_keepalive: type %u len %u rid %u\n",
- DEVNAME(sc),
+ DEVNAME(un),
le32toh(keep->rm_type),
le32toh(keep->rm_len),
le32toh(keep->rm_rid)));
- rval = urndis_ctrl_send(sc, keep, sizeof(*keep));
+ rval = urndis_ctrl_send(un, keep, sizeof(*keep));
kmem_free(keep, sizeof(*keep));
if (rval != RNDIS_STATUS_SUCCESS) {
- printf("%s: keepalive failed\n", DEVNAME(sc));
+ printf("%s: keepalive failed\n", DEVNAME(un));
return rval;
}
- if ((hdr = urndis_ctrl_recv(sc)) == NULL) {
- printf("%s: unable to get keepalive response\n", DEVNAME(sc));
+ if ((hdr = urndis_ctrl_recv(un)) == NULL) {
+ printf("%s: unable to get keepalive response\n", DEVNAME(un));
return RNDIS_STATUS_FAILURE;
}
- rval = urndis_ctrl_handle(sc, hdr, NULL, NULL);
+ rval = urndis_ctrl_handle(un, hdr, NULL, NULL);
if (rval != RNDIS_STATUS_SUCCESS) {
- printf("%s: keepalive failed 0x%x\n", DEVNAME(sc), rval);
- urndis_ctrl_reset(sc);
+ printf("%s: keepalive failed 0x%x\n", DEVNAME(un), rval);
+ urndis_ctrl_reset(un);
}
return rval;
}
#endif
-static int
-urndis_encap(struct urndis_softc *sc, struct mbuf *m, int idx)
+static unsigned
+urndis_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
{
- struct urndis_chain *c;
- usbd_status err;
struct rndis_packet_msg *msg;
- c = &sc->sc_data.sc_tx_chain[idx];
-
- msg = (struct rndis_packet_msg *)c->sc_buf;
+ msg = (struct rndis_packet_msg *)c->unc_buf;
memset(msg, 0, sizeof(*msg));
msg->rm_type = htole32(REMOTE_NDIS_PACKET_MSG);
@@ -805,61 +732,45 @@ urndis_encap(struct urndis_softc *sc, st
m_copydata(m, 0, m->m_pkthdr.len,
((char*)msg + RNDIS_DATA_OFFSET + RNDIS_HEADER_OFFSET));
- DPRINTF(("%s: urndis_encap type 0x%x len %u data(off %u len %u)\n",
- DEVNAME(sc),
+ DPRINTF(("%s: %s type 0x%x len %u data(off %u len %u)\n",
+ __func__,
+ DEVNAME(un),
le32toh(msg->rm_type),
le32toh(msg->rm_len),
le32toh(msg->rm_dataoffset),
le32toh(msg->rm_datalen)));
- c->sc_mbuf = m;
-
- usbd_setup_xfer(c->sc_xfer, c, c->sc_buf, le32toh(msg->rm_len),
- USBD_FORCE_SHORT_XFER, 10000, urndis_txeof);
-
- /* Transmit */
- err = usbd_transfer(c->sc_xfer);
- if (err != USBD_IN_PROGRESS) {
- urndis_stop(GET_IFP(sc));
- return(EIO);
- }
-
- sc->sc_data.sc_tx_cnt++;
-
- return(0);
+ return le32toh(msg->rm_len);
}
static void
-urndis_decap(struct urndis_softc *sc, struct urndis_chain *c, uint32_t len)
+urndis_rx_loop(struct usbnet * un, struct usbd_xfer *xfer,
+ struct usbnet_chain *c, uint32_t total_len)
{
- struct mbuf *m;
struct rndis_packet_msg *msg;
- struct ifnet *ifp;
- int s;
+ struct ifnet *ifp = usbnet_ifp(un);
int offset;
- ifp = GET_IFP(sc);
offset = 0;
- while (len > 1) {
- msg = (struct rndis_packet_msg *)((char*)c->sc_buf + offset);
- m = c->sc_mbuf;
+ while (total_len > 1) {
+ msg = (struct rndis_packet_msg *)((char*)c->unc_buf + offset);
- DPRINTF(("%s: urndis_decap buffer size left %u\n", DEVNAME(sc),
- len));
+ DPRINTF(("%s: %s buffer size left %u\n", DEVNAME(un), __func__,
+ total_len));
- if (len < sizeof(*msg)) {
- printf("%s: urndis_decap invalid buffer len %u < "
+ if (total_len < sizeof(*msg)) {
+ printf("%s: urndis_decap invalid buffer total_len %u < "
"minimum header %zu\n",
- DEVNAME(sc),
- len,
+ DEVNAME(un),
+ total_len,
sizeof(*msg));
return;
}
- DPRINTF(("%s: urndis_decap len %u data(off:%u len:%u) "
+ DPRINTF(("%s: urndis_decap total_len %u data(off:%u len:%u) "
"oobdata(off:%u len:%u nb:%u) perpacket(off:%u len:%u)\n",
- DEVNAME(sc),
+ DEVNAME(un),
le32toh(msg->rm_len),
le32toh(msg->rm_dataoffset),
le32toh(msg->rm_datalen),
@@ -871,24 +782,24 @@ urndis_decap(struct urndis_softc *sc, st
if (le32toh(msg->rm_type) != REMOTE_NDIS_PACKET_MSG) {
printf("%s: urndis_decap invalid type 0x%x != 0x%x\n",
- DEVNAME(sc),
+ DEVNAME(un),
le32toh(msg->rm_type),
REMOTE_NDIS_PACKET_MSG);
return;
}
if (le32toh(msg->rm_len) < sizeof(*msg)) {
printf("%s: urndis_decap invalid msg len %u < %zu\n",
- DEVNAME(sc),
+ DEVNAME(un),
le32toh(msg->rm_len),
sizeof(*msg));
return;
}
- if (le32toh(msg->rm_len) > len) {
+ if (le32toh(msg->rm_len) > total_len) {
printf("%s: urndis_decap invalid msg len %u > buffer "
- "len %u\n",
- DEVNAME(sc),
+ "total_len %u\n",
+ DEVNAME(un),
le32toh(msg->rm_len),
- len);
+ total_len);
return;
}
@@ -898,7 +809,7 @@ urndis_decap(struct urndis_softc *sc, st
printf("%s: urndis_decap invalid data "
"len/offset/end_position(%u/%u/%u) -> "
"go out of receive buffer limit %u\n",
- DEVNAME(sc),
+ DEVNAME(un),
le32toh(msg->rm_datalen),
le32toh(msg->rm_dataoffset),
le32toh(msg->rm_dataoffset) +
@@ -911,435 +822,69 @@ urndis_decap(struct urndis_softc *sc, st
ifp->if_ierrors++;
printf("%s: urndis_decap invalid ethernet size "
"%d < %zu\n",
- DEVNAME(sc),
+ DEVNAME(un),
le32toh(msg->rm_datalen),
sizeof(struct ether_header));
return;
}
- memcpy(mtod(m, char*),
+ usbnet_enqueue(un,
((char*)&msg->rm_dataoffset + le32toh(msg->rm_dataoffset)),
- le32toh(msg->rm_datalen));
- m->m_pkthdr.len = m->m_len = le32toh(msg->rm_datalen);
-
- m_set_rcvif(m, ifp);
-
- s = splnet();
-
- if (urndis_newbuf(sc, c) == ENOBUFS) {
- ifp->if_ierrors++;
- } else {
- if_percpuq_enqueue(ifp->if_percpuq, m);
- }
- splx(s);
+ le32toh(msg->rm_datalen), 0, 0, 0);
offset += le32toh(msg->rm_len);
- len -= le32toh(msg->rm_len);
- }
-}
-
-static int
-urndis_newbuf(struct urndis_softc *sc, struct urndis_chain *c)
-{
- struct mbuf *m_new = NULL;
-
- MGETHDR(m_new, M_DONTWAIT, MT_DATA);
- if (m_new == NULL) {
- printf("%s: no memory for rx list -- packet dropped!\n",
- DEVNAME(sc));
- return ENOBUFS;
- }
- MCLGET(m_new, M_DONTWAIT);
- if (!(m_new->m_flags & M_EXT)) {
- printf("%s: no memory for rx list -- packet dropped!\n",
- DEVNAME(sc));
- m_freem(m_new);
- return ENOBUFS;
- }
- m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
-
- m_adj(m_new, ETHER_ALIGN);
- c->sc_mbuf = m_new;
- return 0;
-}
-
-static int
-urndis_rx_list_init(struct urndis_softc *sc)
-{
- struct urndis_cdata *cd;
- struct urndis_chain *c;
- int i;
-
- cd = &sc->sc_data;
- for (i = 0; i < RNDIS_RX_LIST_CNT; i++) {
- c = &cd->sc_rx_chain[i];
- c->sc_softc = sc;
-
- if (urndis_newbuf(sc, c) == ENOBUFS)
- return ENOBUFS;
-
- if (c->sc_xfer == NULL) {
- int err = usbd_create_xfer(sc->sc_bulkin_pipe,
- RNDIS_BUFSZ, 0, 0, &c->sc_xfer);
- if (err)
- return err;
- c->sc_buf = usbd_get_buffer(c->sc_xfer);
- }
- }
-
- return 0;
-}
-
-static int
-urndis_tx_list_init(struct urndis_softc *sc)
-{
- struct urndis_cdata *cd;
- struct urndis_chain *c;
- int i;
-
- cd = &sc->sc_data;
- for (i = 0; i < RNDIS_TX_LIST_CNT; i++) {
- c = &cd->sc_tx_chain[i];
- c->sc_softc = sc;
- c->sc_mbuf = NULL;
- if (c->sc_xfer == NULL) {
- int err = usbd_create_xfer(sc->sc_bulkout_pipe,
- RNDIS_BUFSZ, USBD_FORCE_SHORT_XFER, 0, &c->sc_xfer);
- if (err)
- return err;
- c->sc_buf = usbd_get_buffer(c->sc_xfer);
- }
- }
- return 0;
-}
-
-static int
-urndis_ioctl(struct ifnet *ifp, unsigned long command, void *data)
-{
- struct urndis_softc *sc;
- int s, error;
-
- sc = ifp->if_softc;
- error = 0;
-
- if (sc->sc_dying)
- return EIO;
-
- 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;
+ total_len -= le32toh(msg->rm_len);
}
-
- if (error == ENETRESET)
- error = 0;
-
- splx(s);
- return error;
}
#if 0
static void
urndis_watchdog(struct ifnet *ifp)
{
- struct urndis_softc *sc;
+ struct urndis_softc *sc = usbnet_softc(un);
- sc = ifp->if_softc;
-
- if (sc->sc_dying)
+ if (un->un_dying)
return;
ifp->if_oerrors++;
- printf("%s: watchdog timeout\n", DEVNAME(sc));
+ printf("%s: watchdog timeout\n", DEVNAME(un));
- urndis_ctrl_keepalive(sc);
+ urndis_ctrl_keepalive(un);
}
#endif
static int
-urndis_init(struct ifnet *ifp)
+urndis_init_un(struct ifnet *ifp, struct usbnet *un)
{
- struct urndis_softc *sc;
- int i, s;
int err;
- usbd_status usberr;
-
- sc = ifp->if_softc;
if (ifp->if_flags & IFF_RUNNING)
return 0;
- err = urndis_ctrl_init(sc);
+ err = urndis_ctrl_init(un);
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;
- }
-
- usberr = usbd_open_pipe(sc->sc_iface_data, sc->sc_bulkout_no,
- USBD_EXCLUSIVE_USE, &sc->sc_bulkout_pipe);
- if (usberr) {
- printf("%s: open tx pipe failed: %s\n", DEVNAME(sc),
- usbd_errstr(err));
- splx(s);
- return EIO;
- }
-
- err = urndis_tx_list_init(sc);
- if (err) {
- printf("%s: tx list init failed\n",
- DEVNAME(sc));
- splx(s);
- return err;
- }
-
- err = urndis_rx_list_init(sc);
- if (err) {
- printf("%s: rx list init failed\n",
- DEVNAME(sc));
- splx(s);
- return err;
- }
-
- for (i = 0; i < RNDIS_RX_LIST_CNT; i++) {
- struct urndis_chain *c;
-
- c = &sc->sc_data.sc_rx_chain[i];
-
- usbd_setup_xfer(c->sc_xfer, c, c->sc_buf, RNDIS_BUFSZ,
- USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, urndis_rxeof);
- usbd_transfer(c->sc_xfer);
- }
-
- ifp->if_flags |= IFF_RUNNING;
- ifp->if_flags &= ~IFF_OACTIVE;
-
- splx(s);
- return 0;
-}
-
-static void
-urndis_stop(struct ifnet *ifp)
-{
- struct urndis_softc *sc;
- usbd_status err;
- int i;
-
- sc = ifp->if_softc;
-
- ifp->if_timer = 0;
- ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
-
- if (sc->sc_bulkin_pipe != NULL) {
- err = usbd_abort_pipe(sc->sc_bulkin_pipe);
- if (err)
- printf("%s: abort rx pipe failed: %s\n",
- DEVNAME(sc), usbd_errstr(err));
- }
-
- if (sc->sc_bulkout_pipe != NULL) {
- err = usbd_abort_pipe(sc->sc_bulkout_pipe);
- if (err)
- printf("%s: abort tx pipe failed: %s\n",
- 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;
- }
- }
-
- 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;
- }
- }
-
- /* Close pipes. */
- if (sc->sc_bulkin_pipe != NULL) {
- err = usbd_close_pipe(sc->sc_bulkin_pipe);
- if (err)
- printf("%s: close rx pipe failed: %s\n",
- DEVNAME(sc), usbd_errstr(err));
- sc->sc_bulkin_pipe = NULL;
+ usbnet_lock(un);
+ if (un->un_dying)
+ err = EIO;
+ else {
+ usbnet_stop(un, ifp, 1);
+ err = usbnet_init_rx_tx(un);
+ if (err == 0)
+ un->un_link = true;
}
+ usbnet_unlock(un);
- if (sc->sc_bulkout_pipe != NULL) {
- err = usbd_close_pipe(sc->sc_bulkout_pipe);
- if (err)
- printf("%s: close tx pipe failed: %s\n",
- DEVNAME(sc), usbd_errstr(err));
- sc->sc_bulkout_pipe = NULL;
- }
+ return err;
}
-static void
-urndis_start(struct ifnet *ifp)
+static int
+urndis_init(struct ifnet *ifp)
{
- struct urndis_softc *sc;
- struct mbuf *m_head = NULL;
-
- sc = ifp->if_softc;
-
- if (sc->sc_dying || (ifp->if_flags & IFF_OACTIVE))
- return;
-
- IFQ_POLL(&ifp->if_snd, m_head);
- if (m_head == NULL)
- return;
-
- if (urndis_encap(sc, m_head, 0)) {
- ifp->if_flags |= IFF_OACTIVE;
- return;
- }
- IFQ_DEQUEUE(&ifp->if_snd, m_head);
-
- /*
- * If there's a BPF listener, bounce a copy of this frame
- * to him.
- */
- bpf_mtap(ifp, m_head, BPF_D_OUT);
-
- ifp->if_flags |= IFF_OACTIVE;
-
- /*
- * Set a timeout in case the chip goes out to lunch.
- */
- ifp->if_timer = 5;
-
- return;
-}
-
-static void
-urndis_rxeof(struct usbd_xfer *xfer,
- void *priv,
- usbd_status status)
-{
- struct urndis_chain *c;
- struct urndis_softc *sc;
- struct ifnet *ifp;
- uint32_t total_len;
-
- c = priv;
- sc = c->sc_softc;
- ifp = GET_IFP(sc);
- total_len = 0;
-
- if (sc->sc_dying || !(ifp->if_flags & IFF_RUNNING))
- return;
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
- return;
- if (usbd_ratecheck(&sc->sc_rx_notice)) {
- printf("%s: usb errors on rx: %s\n",
- DEVNAME(sc), usbd_errstr(status));
- }
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall_async(sc->sc_bulkin_pipe);
-
- goto done;
- }
-
- usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
- urndis_decap(sc, c, total_len);
-
-done:
- /* Setup new transfer. */
- usbd_setup_xfer(c->sc_xfer, c, c->sc_buf, RNDIS_BUFSZ,
- USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, urndis_rxeof);
- usbd_transfer(c->sc_xfer);
-}
-
-static void
-urndis_txeof(struct usbd_xfer *xfer,
- void *priv,
- usbd_status status)
-{
- struct urndis_chain *c;
- struct urndis_softc *sc;
- struct ifnet *ifp;
- usbd_status err;
- int s;
-
- c = priv;
- sc = c->sc_softc;
- ifp = GET_IFP(sc);
+ struct usbnet *un = ifp->if_softc;
- DPRINTF(("%s: urndis_txeof\n", DEVNAME(sc)));
-
- if (sc->sc_dying)
- return;
-
- s = splnet();
-
- ifp->if_timer = 0;
- ifp->if_flags &= ~IFF_OACTIVE;
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
- splx(s);
- return;
- }
- ifp->if_oerrors++;
- printf("%s: usb error on tx: %s\n", DEVNAME(sc),
- usbd_errstr(status));
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall_async(sc->sc_bulkout_pipe);
- splx(s);
- return;
- }
-
- usbd_get_xfer_status(c->sc_xfer, NULL, NULL, NULL, &err);
-
- if (c->sc_mbuf != NULL) {
- m_freem(c->sc_mbuf);
- c->sc_mbuf = NULL;
- }
-
- if (err)
- ifp->if_oerrors++;
- else
- ifp->if_opackets++;
-
- if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
- urndis_start(ifp);
-
- splx(s);
+ return urndis_init_un(ifp, un);
}
static int
@@ -1367,43 +912,46 @@ urndis_match(device_t parent, cfdata_t m
static void
urndis_attach(device_t parent, device_t self, void *aux)
{
- struct urndis_softc *sc;
- struct usbif_attach_arg *uiaa;
- struct ifnet *ifp;
+ struct urndis_softc *sc = device_private(self);
+ struct usbnet * const un = &sc->sc_un;
+ struct usbif_attach_arg *uiaa = aux;
+ struct usbd_device *dev = uiaa->uiaa_device;
usb_interface_descriptor_t *id;
usb_endpoint_descriptor_t *ed;
usb_config_descriptor_t *cd;
+ struct usbd_interface *iface_ctl;
const usb_cdc_union_descriptor_t *ud;
const usb_cdc_header_descriptor_t *desc;
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;
uint32_t filter;
char *devinfop;
- sc = device_private(self);
- uiaa = aux;
- sc->sc_dev = self;
- sc->sc_udev = uiaa->uiaa_device;
+ /* Switch to usbnet for device_private() */
+ self->dv_private = un;
aprint_naive("\n");
aprint_normal("\n");
-
- devinfop = usbd_devinfo_alloc(uiaa->uiaa_device, 0);
+ devinfop = usbd_devinfo_alloc(dev, 0);
aprint_normal_dev(self, "%s\n", devinfop);
usbd_devinfo_free(devinfop);
- sc->sc_iface_ctl = uiaa->uiaa_iface;
- id = usbd_get_interface_descriptor(sc->sc_iface_ctl);
+ un->un_dev = self;
+ un->un_udev = dev;
+ un->un_sc = sc;
+ un->un_ops = &urndis_ops;
+
+ iface_ctl = uiaa->uiaa_iface;
+ un->un_iface = uiaa->uiaa_iface;
+ id = usbd_get_interface_descriptor(iface_ctl);
if_ctl = id->bInterfaceNumber;
sc->sc_ifaceno_ctl = if_ctl;
if_data = -1;
- usb_desc_iter_init(sc->sc_udev, &iter);
+ usb_desc_iter_init(un->un_udev, &iter);
while ((desc = (const void *)usb_desc_iter_next(&iter)) != NULL) {
if (desc->bDescriptorType != UDESC_CS_INTERFACE) {
@@ -1421,7 +969,7 @@ urndis_attach(device_t parent, device_t
if (if_data == -1) {
DPRINTF(("urndis_attach: no union interface\n"));
- sc->sc_iface_data = sc->sc_iface_ctl;
+ un->un_iface = iface_ctl;
} else {
DPRINTF(("urndis_attach: union interface: ctl %u, data %u\n",
if_ctl, if_data));
@@ -1431,104 +979,96 @@ urndis_attach(device_t parent, device_t
uiaa->uiaa_ifaces[i]);
if (id != NULL && id->bInterfaceNumber ==
if_data) {
- sc->sc_iface_data = uiaa->uiaa_ifaces[i];
+ un->un_iface = uiaa->uiaa_ifaces[i];
uiaa->uiaa_ifaces[i] = NULL;
}
}
}
}
- if (sc->sc_iface_data == NULL) {
- aprint_error("%s: no data interface\n", DEVNAME(sc));
+ if (un->un_iface == NULL) {
+ aprint_error("%s: no data interface\n", DEVNAME(un));
return;
}
- id = usbd_get_interface_descriptor(sc->sc_iface_data);
- cd = usbd_get_config_descriptor(sc->sc_udev);
+ id = usbd_get_interface_descriptor(un->un_iface);
+ cd = usbd_get_config_descriptor(un->un_udev);
altcnt = usbd_get_no_alts(cd, id->bInterfaceNumber);
for (j = 0; j < altcnt; j++) {
- if (usbd_set_interface(sc->sc_iface_data, j)) {
+ if (usbd_set_interface(un->un_iface, j)) {
aprint_error("%s: interface alternate setting %u "
- "failed\n", DEVNAME(sc), j);
+ "failed\n", DEVNAME(un), j);
return;
}
/* Find endpoints. */
- id = usbd_get_interface_descriptor(sc->sc_iface_data);
- sc->sc_bulkin_no = sc->sc_bulkout_no = -1;
+ id = usbd_get_interface_descriptor(un->un_iface);
+ un->un_ed[USBNET_ENDPT_RX] = un->un_ed[USBNET_ENDPT_TX] = 0;
for (i = 0; i < id->bNumEndpoints; i++) {
ed = usbd_interface2endpoint_descriptor(
- sc->sc_iface_data, i);
+ un->un_iface, i);
if (!ed) {
aprint_error("%s: no descriptor for bulk "
- "endpoint %u\n", DEVNAME(sc), i);
+ "endpoint %u\n", DEVNAME(un), i);
return;
}
if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- sc->sc_bulkin_no = ed->bEndpointAddress;
+ un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress;
}
else if (
UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- sc->sc_bulkout_no = ed->bEndpointAddress;
+ un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress;
}
}
- if (sc->sc_bulkin_no != -1 && sc->sc_bulkout_no != -1) {
+ if (un->un_ed[USBNET_ENDPT_RX] != 0 && un->un_ed[USBNET_ENDPT_TX] != 0) {
DPRINTF(("%s: in=0x%x, out=0x%x\n",
- DEVNAME(sc),
- sc->sc_bulkin_no,
+ DEVNAME(un),
+ un->un_ed[USBNET_ENDPT_RX],
sc->sc_bulkout_no));
- goto found;
+ break;
}
}
- if (sc->sc_bulkin_no == -1)
- aprint_error("%s: could not find data bulk in\n", DEVNAME(sc));
- if (sc->sc_bulkout_no == -1 )
- aprint_error("%s: could not find data bulk out\n",DEVNAME(sc));
- return;
-
- found:
-
- ifp = GET_IFP(sc);
- ifp->if_softc = sc;
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_start = urndis_start;
- ifp->if_ioctl = urndis_ioctl;
- ifp->if_init = urndis_init;
+ if (un->un_ed[USBNET_ENDPT_RX] == 0)
+ aprint_error("%s: could not find data bulk in\n", DEVNAME(un));
+ if (un->un_ed[USBNET_ENDPT_TX] == 0)
+ aprint_error("%s: could not find data bulk out\n",DEVNAME(un));
+ if (un->un_ed[USBNET_ENDPT_RX] == 0 || un->un_ed[USBNET_ENDPT_TX] == 0)
+ return;
+
+ struct ifnet *ifp = usbnet_ifp(un);
#if 0
ifp->if_watchdog = urndis_watchdog;
#endif
- strlcpy(ifp->if_xname, DEVNAME(sc), IFNAMSIZ);
+ usbnet_attach(un, "urndisdet", RNDIS_RX_LIST_CNT, RNDIS_TX_LIST_CNT,
+ USBD_SHORT_XFER_OK, USBD_FORCE_SHORT_XFER,
+ RNDIS_BUFSZ, RNDIS_BUFSZ);
- IFQ_SET_READY(&ifp->if_snd);
+ urndis_init_un(ifp, un);
- urndis_init(ifp);
-
- s = splnet();
-
- if (urndis_ctrl_query(sc, OID_802_3_PERMANENT_ADDRESS, NULL, 0,
+ if (urndis_ctrl_query(un, OID_802_3_PERMANENT_ADDRESS, NULL, 0,
&buf, &bufsz) != RNDIS_STATUS_SUCCESS) {
aprint_error("%s: unable to get hardware address\n",
- DEVNAME(sc));
- urndis_stop(ifp);
- splx(s);
+ DEVNAME(un));
+ usbnet_lock(un);
+ usbnet_stop(un, ifp, 1);
+ usbnet_unlock(un);
return;
}
if (bufsz == ETHER_ADDR_LEN) {
- memcpy(eaddr, buf, ETHER_ADDR_LEN);
- aprint_normal("%s: address %s\n", DEVNAME(sc),
- ether_sprintf(eaddr));
+ memcpy(un->un_eaddr, buf, ETHER_ADDR_LEN);
kmem_free(buf, bufsz);
} else {
- aprint_error("%s: invalid address\n", DEVNAME(sc));
+ aprint_error("%s: invalid address\n", DEVNAME(un));
kmem_free(buf, bufsz);
- urndis_stop(ifp);
- splx(s);
+ usbnet_lock(un);
+ usbnet_stop(un, ifp, 1);
+ usbnet_unlock(un);
return;
}
@@ -1536,65 +1076,20 @@ urndis_attach(device_t parent, device_t
sc->sc_filter = RNDIS_PACKET_TYPE_BROADCAST;
sc->sc_filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST;
filter = htole32(sc->sc_filter);
- if (urndis_ctrl_set(sc, OID_GEN_CURRENT_PACKET_FILTER, &filter,
+ if (urndis_ctrl_set(un, OID_GEN_CURRENT_PACKET_FILTER, &filter,
sizeof(filter)) != RNDIS_STATUS_SUCCESS) {
- aprint_error("%s: unable to set data filters\n", DEVNAME(sc));
- urndis_stop(ifp);
- splx(s);
+ aprint_error("%s: unable to set data filters\n", DEVNAME(un));
+ usbnet_lock(un);
+ usbnet_stop(un, ifp, 1);
+ usbnet_unlock(un);
return;
}
- if_attach(ifp);
- ether_ifattach(ifp, eaddr);
- sc->sc_attached = 1;
-
- splx(s);
-}
-
-static int
-urndis_detach(device_t self, int flags)
-{
- struct urndis_softc *sc;
- struct ifnet *ifp;
- int s;
-
- sc = device_private(self);
-
- DPRINTF(("urndis_detach: %s flags %u\n", DEVNAME(sc),
- flags));
-
- if (!sc->sc_attached)
- return 0;
-
- s = splusb();
-
- ifp = GET_IFP(sc);
-
- if (ifp->if_softc != NULL) {
- ether_ifdetach(ifp);
- if_detach(ifp);
- }
-
- urndis_stop(ifp);
- sc->sc_attached = 0;
-
- splx(s);
-
- return 0;
-}
-
-static int
-urndis_activate(device_t self, enum devact act)
-{
- struct urndis_softc *sc;
-
- sc = device_private(self);
-
- switch (act) {
- case DVACT_DEACTIVATE:
- sc->sc_dying = 1;
- return 0;
- }
+ /* Turn off again now it has been identified. */
+ usbnet_lock(un);
+ usbnet_stop(un, ifp, 1);
+ usbnet_unlock(un);
- return EOPNOTSUPP;
+ usbnet_attach_ifp(un, false, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST,
+ 0, 0);
}