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