NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kern/42577: u3g driver does bogus things in the match routine
The following reply was made to PR kern/42577; it has been noted by GNATS.
From: Martin Husemann <martin%duskware.de@localhost>
To: gnats-bugs%NetBSD.org@localhost
Cc:
Subject: Re: kern/42577: u3g driver does bogus things in the match routine
Date: Mon, 4 Jan 2010 23:21:23 +0100
Here is a patch that implements this method, and also fixes a bogus
comparision in the attach function. Seems to work on a Huawei device,
I couldn't test Sierra or Novatel.
Martin
Index: u3g.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/u3g.c,v
retrieving revision 1.8
diff -u -p -r1.8 u3g.c
--- u3g.c 12 Nov 2009 19:52:14 -0000 1.8
+++ u3g.c 4 Jan 2010 22:18:14 -0000
@@ -78,17 +78,12 @@ struct ucom_methods u3g_methods = {
NULL,
};
-static const struct usb_devno u3g_devs[] = {
- /* OEM: Option N.V. */
- { USB_VENDOR_OPTIONNV, USB_PRODUCT_OPTIONNV_QUADPLUSUMTS },
- { USB_VENDOR_OPTIONNV, USB_PRODUCT_OPTIONNV_HSDPA },
- { USB_VENDOR_OPTIONNV, USB_PRODUCT_OPTIONNV_GTMAXHSUPA },
- /* OEM: Qualcomm, Inc. */
- { USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_CDMA_MSM },
+static const struct usb_devno u3g_high_devs[] = {
/* OEM: Huawei */
{ USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_MOBILE },
{ USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E220 },
/* OEM: Novatel */
+ { USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_MC950D_DRIVER },
{ USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_MERLINV620 },
{ USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_ES620 },
{ USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_MC950D },
@@ -106,10 +101,8 @@ static const struct usb_devno u3g_devs[]
#if 0
{ USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_MC950D_DRIVER },
#endif
- /* OEM: Merlin */
- { USB_VENDOR_MERLIN, USB_PRODUCT_MERLIN_V620 },
-
/* OEM: Sierra Wireless: */
+ { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_INSTALLER },
{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD580 },
{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD595 },
{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC595U },
@@ -137,6 +130,17 @@ static const struct usb_devno u3g_devs[]
{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8781 },
};
+static const struct usb_devno u3g_devs[] = {
+ /* OEM: Option N.V. */
+ { USB_VENDOR_OPTIONNV, USB_PRODUCT_OPTIONNV_QUADPLUSUMTS },
+ { USB_VENDOR_OPTIONNV, USB_PRODUCT_OPTIONNV_HSDPA },
+ { USB_VENDOR_OPTIONNV, USB_PRODUCT_OPTIONNV_GTMAXHSUPA },
+ /* OEM: Qualcomm, Inc. */
+ { USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_CDMA_MSM },
+ /* OEM: Merlin */
+ { USB_VENDOR_MERLIN, USB_PRODUCT_MERLIN_V620 },
+};
+
#ifdef U3G_DEBUG
static void
u3g_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
@@ -146,7 +150,7 @@ u3g_intr(usbd_xfer_handle xfer, usbd_pri
}
#endif
-static int
+static void
u3g_novatel_reinit(struct usb_attach_arg *uaa)
{
unsigned char cmd[31];
@@ -183,13 +187,13 @@ u3g_novatel_reinit(struct usb_attach_arg
err = usbd_set_config_index(uaa->device, 0, 0);
if (err) {
aprint_error("u3g: failed to set configuration index\n");
- return UMATCH_NONE;
+ return;
}
err = usbd_device2interface_handle(uaa->device, 0, &iface);
if (err != 0) {
aprint_error("u3g: failed to get interface\n");
- return UMATCH_NONE;
+ return;
}
id = usbd_get_interface_descriptor(iface);
@@ -205,14 +209,14 @@ u3g_novatel_reinit(struct usb_attach_arg
}
if (i == id->bNumEndpoints)
- return UMATCH_NONE;
+ return;
err = usbd_open_pipe(iface, ed->bEndpointAddress, USBD_EXCLUSIVE_USE,
&pipe);
if (err != 0) {
aprint_error("u3g: failed to open bulk transfer pipe %d\n",
ed->bEndpointAddress);
- return UMATCH_NONE;
+ return;
}
xfer = usbd_alloc_xfer(uaa->device);
@@ -231,11 +235,9 @@ u3g_novatel_reinit(struct usb_attach_arg
usbd_abort_pipe(pipe);
usbd_close_pipe(pipe);
-
- return (err == USBD_NORMAL_COMPLETION ? UMATCH_HIGHEST : UMATCH_NONE);
}
-static int
+static void
u3g_huawei_reinit(usbd_device_handle dev)
{
/* The Huawei device presents itself as a umass device with Windows
@@ -243,16 +245,6 @@ u3g_huawei_reinit(usbd_device_handle dev
* 3G serial device.
*/
usb_device_request_t req;
- usb_config_descriptor_t *cdesc;
-
- /* Get the config descriptor */
- cdesc = usbd_get_config_descriptor(dev);
- if (cdesc == NULL)
- return (UMATCH_NONE);
-
- /* One iface means umass mode, more than 1 (4 usually) means 3G mode */
- if (cdesc->bNumInterface > 1)
- return (UMATCH_VENDOR_PRODUCT);
req.bmRequestType = UT_WRITE_DEVICE;
req.bRequest = UR_SET_FEATURE;
@@ -261,12 +253,9 @@ u3g_huawei_reinit(usbd_device_handle dev
USETW(req.wLength, 0);
(void) usbd_do_request(dev, &req, 0);
-
-
- return (UMATCH_HIGHEST); /* Match to prevent umass from attaching */
}
-static int
+static void
u3g_sierra_reinit(usbd_device_handle dev)
{
/* Some Sierra devices presents themselves as a umass device with
@@ -274,12 +263,6 @@ u3g_sierra_reinit(usbd_device_handle dev
* reinits into a * 3G serial device.
*/
usb_device_request_t req;
- usb_config_descriptor_t *cdesc;
-
- /* Get the config descriptor */
- cdesc = usbd_get_config_descriptor(dev);
- if (cdesc == NULL)
- return (UMATCH_NONE);
req.bmRequestType = UT_VENDOR;
req.bRequest = UR_SET_INTERFACE;
@@ -288,8 +271,6 @@ u3g_sierra_reinit(usbd_device_handle dev
USETW(req.wLength, 0);
(void) usbd_do_request(dev, &req, 0);
-
- return (UMATCH_HIGHEST); /* Match to prevent umass from attaching */
}
static int
@@ -297,16 +278,8 @@ u3g_match(device_t parent, cfdata_t matc
{
struct usb_attach_arg *uaa = aux;
- if (uaa->vendor == USB_VENDOR_HUAWEI)
- return u3g_huawei_reinit(uaa->device);
-
- if (uaa->vendor == USB_VENDOR_NOVATEL2 &&
- uaa->product == USB_PRODUCT_NOVATEL2_MC950D_DRIVER)
- return u3g_novatel_reinit(uaa);
-
- if (uaa->vendor == USB_VENDOR_SIERRA &&
- uaa->product == USB_PRODUCT_SIERRA_INSTALLER)
- return u3g_sierra_reinit(uaa->device);
+ if (usb_lookup(u3g_high_devs, uaa->vendor, uaa->product))
+ return UMATCH_HIGHEST;
if (usb_lookup(u3g_devs, uaa->vendor, uaa->product))
return UMATCH_VENDOR_PRODUCT;
@@ -334,6 +307,7 @@ u3g_attach(device_t parent, device_t sel
uaa->product == USB_PRODUCT_NOVATEL2_MC950D_DRIVER) {
/* About to disappear... */
sc->sc_pseudodev = true;
+ u3g_novatel_reinit(uaa);
return;
}
@@ -358,9 +332,10 @@ u3g_attach(device_t parent, device_t sel
return;
}
- if (uaa->vendor == USB_VENDOR_HUAWEI && cdesc->bNumInterface > 1) {
+ if (uaa->vendor == USB_VENDOR_HUAWEI && cdesc->bNumInterface == 1) {
/* About to disappear... */
sc->sc_pseudodev = true;
+ u3g_huawei_reinit(dev);
return;
}
@@ -368,6 +343,7 @@ u3g_attach(device_t parent, device_t sel
uaa->product == USB_PRODUCT_SIERRA_INSTALLER) {
/* About to disappear... */
sc->sc_pseudodev = true;
+ u3g_sierra_reinit(dev);
return;
}
Home |
Main Index |
Thread Index |
Old Index