summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfgsch <fgsch@openbsd.org>2012-06-20 10:51:27 +0000
committerfgsch <fgsch@openbsd.org>2012-06-20 10:51:27 +0000
commit003f632115b45296e460545de5735b2724c1c9a8 (patch)
treecb5398d55a1324f30a85b3ad909aa64582cd687e
parentReflect the changes made by RFC 3542 (diff)
downloadwireguard-openbsd-003f632115b45296e460545de5735b2724c1c9a8.tar.xz
wireguard-openbsd-003f632115b45296e460545de5735b2724c1c9a8.zip
- urndis_match() should support multiple interface descriptors.
- in urndis_attach() use the first interface descriptor that's different from the control interface as the data interface. from armani's colleague with some tweaks by me. kettenis@ sthen@ ok
-rw-r--r--sys/dev/usb/if_urndis.c71
-rw-r--r--sys/dev/usb/if_urndisreg.h3
-rw-r--r--sys/dev/usb/usb.h6
3 files changed, 33 insertions, 47 deletions
diff --git a/sys/dev/usb/if_urndis.c b/sys/dev/usb/if_urndis.c
index fe1acd8ef35..4c9432eaf06 100644
--- a/sys/dev/usb/if_urndis.c
+++ b/sys/dev/usb/if_urndis.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_urndis.c,v 1.33 2012/03/24 08:33:08 fgsch Exp $ */
+/* $OpenBSD: if_urndis.c,v 1.34 2012/06/20 10:51:27 fgsch Exp $ */
/*
* Copyright (c) 2010 Jonathan Armani <armani@openbsd.org>
@@ -131,14 +131,23 @@ struct cfattach urndis_ca = {
urndis_activate,
};
+struct urndis_class {
+ u_int8_t class;
+ u_int8_t subclass;
+ u_int8_t protocol;
+} urndis_class[] = {
+ { UICLASS_CDC, UISUBCLASS_ABSTRACT_CONTROL_MODEL, 0xff },
+ { UICLASS_WIRELESS, UISUBCLASS_RF, UIPROTO_RNDIS },
+ { UICLASS_MISC, UISUBCLASS_SYNC, UIPROTO_ACTIVESYNC }
+};
+
/*
* Supported devices that we can't match by class IDs.
*/
static const struct usb_devno urndis_devs[] = {
{ USB_VENDOR_HTC, USB_PRODUCT_HTC_ANDROID },
{ USB_VENDOR_SAMSUNG2, USB_PRODUCT_SAMSUNG2_ANDROID },
- { USB_VENDOR_SAMSUNG2, USB_PRODUCT_SAMSUNG2_ANDROID2 },
- { USB_VENDOR_ZTE, USB_PRODUCT_ZTE_HSUSB }
+ { USB_VENDOR_SAMSUNG2, USB_PRODUCT_SAMSUNG2_ANDROID2 }
};
usbd_status
@@ -1320,6 +1329,7 @@ urndis_match(struct device *parent, void *match, void *aux)
{
struct usb_attach_arg *uaa;
usb_interface_descriptor_t *id;
+ int i;
uaa = aux;
@@ -1330,10 +1340,12 @@ urndis_match(struct device *parent, void *match, void *aux)
if (id == NULL)
return (UMATCH_NONE);
- if (id->bInterfaceClass == UICLASS_WIRELESS &&
- id->bInterfaceSubClass == UISUBCLASS_RF &&
- id->bInterfaceProtocol == UIPROTO_RNDIS)
- return (UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO);
+ for (i = 0; i < nitems(urndis_class); i++) {
+ if (urndis_class[i].class == id->bInterfaceClass &&
+ urndis_class[i].subclass == id->bInterfaceSubClass &&
+ urndis_class[i].protocol == id->bInterfaceProtocol)
+ return (UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO);
+ }
return (usb_lookup(urndis_devs, uaa->vendor, uaa->product) != NULL) ?
UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
@@ -1348,10 +1360,6 @@ urndis_attach(struct device *parent, struct device *self, void *aux)
usb_interface_descriptor_t *id;
usb_endpoint_descriptor_t *ed;
usb_config_descriptor_t *cd;
- usb_cdc_union_descriptor_t *ud;
- const usb_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];
@@ -1363,42 +1371,17 @@ urndis_attach(struct device *parent, struct device *self, void *aux)
uaa = aux;
sc->sc_udev = uaa->device;
- sc->sc_iface_ctl = uaa->iface;
- id = usbd_get_interface_descriptor(sc->sc_iface_ctl);
- if_ctl = id->bInterfaceNumber;
- sc->sc_ifaceno_ctl = if_ctl;
- if_data = -1;
-
- usb_desc_iter_init(sc->sc_udev, &iter);
- while ((desc = usb_desc_iter_next(&iter)) != NULL) {
+ id = usbd_get_interface_descriptor(uaa->iface);
+ sc->sc_ifaceno_ctl = id->bInterfaceNumber;
- if (desc->bDescriptorType != UDESC_CS_INTERFACE) {
+ for (i = 0; i < uaa->nifaces; i++) {
+ if (usbd_iface_claimed(sc->sc_udev, i))
continue;
- }
- switch (desc->bDescriptorSubtype) {
- case UDESCSUB_CDC_UNION:
- ud = (usb_cdc_union_descriptor_t *)desc;
- /* XXX bail out when found first? */
- if (if_data == -1)
- if_data = ud->bSlaveInterface[0];
- break;
- }
- }
- if (if_data == -1) {
- DPRINTF(("urndis_attach: no union interface\n"));
- sc->sc_iface_data = sc->sc_iface_ctl;
- } else {
- DPRINTF(("urndis_attach: union interface: ctl %u, data %u\n",
- if_ctl, if_data));
- for (i = 0; i < uaa->nifaces; i++) {
- if (usbd_iface_claimed(sc->sc_udev, i))
- continue;
- id = usbd_get_interface_descriptor(uaa->ifaces[i]);
- if (id && id->bInterfaceNumber == if_data) {
- sc->sc_iface_data = uaa->ifaces[i];
- usbd_claim_iface(sc->sc_udev, i);
- }
+ if (uaa->ifaces[i] != uaa->iface) {
+ sc->sc_iface_data = uaa->ifaces[i];
+ usbd_claim_iface(sc->sc_udev, i);
+ break;
}
}
diff --git a/sys/dev/usb/if_urndisreg.h b/sys/dev/usb/if_urndisreg.h
index 1a519844b79..d1eae6808ba 100644
--- a/sys/dev/usb/if_urndisreg.h
+++ b/sys/dev/usb/if_urndisreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_urndisreg.h,v 1.14 2010/07/08 18:22:01 ckuethe Exp $ */
+/* $OpenBSD: if_urndisreg.h,v 1.15 2012/06/20 10:51:27 fgsch Exp $ */
/*
* Copyright (c) 2010 Jonathan Armani <armani@openbsd.org>
@@ -52,7 +52,6 @@ struct urndis_softc {
/* USB goo */
usbd_device_handle sc_udev;
int sc_ifaceno_ctl;
- usbd_interface_handle sc_iface_ctl;
usbd_interface_handle sc_iface_data;
struct timeval sc_rx_notice;
diff --git a/sys/dev/usb/usb.h b/sys/dev/usb/usb.h
index c9e2e774c77..bec14753811 100644
--- a/sys/dev/usb/usb.h
+++ b/sys/dev/usb/usb.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: usb.h,v 1.40 2012/06/10 10:20:02 mpi Exp $ */
+/* $OpenBSD: usb.h,v 1.41 2012/06/20 10:51:27 fgsch Exp $ */
/* $NetBSD: usb.h,v 1.69 2002/09/22 23:20:50 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/usb.h,v 1.14 1999/11/17 22:33:46 n_hibma Exp $ */
@@ -481,6 +481,10 @@ typedef struct {
#define UIPROTO_BLUETOOTH 0x01
#define UIPROTO_RNDIS 0x03
+#define UICLASS_MISC 0xef
+#define UISUBCLASS_SYNC 0x01
+#define UIPROTO_ACTIVESYNC 0x01
+
#define UICLASS_APPL_SPEC 0xfe
#define UISUBCLASS_FIRMWARE_DOWNLOAD 1
#define UISUBCLASS_IRDA 2