--- ubsa.c.70stable 2008-10-07 21:00:11.000000000 +0200 +++ ubsa.c 2008-10-08 06:34:20.000000000 +0200 @@ -106,7 +106,7 @@ #define UBSA_MODVER 1 /* module version */ -#define UBSA_CONFIG_INDEX 1 +#define UBSA_CONFIG_INDEX 0 #define UBSA_IFACE_INDEX 0 #define UBSA_INTR_INTERVAL 100 /* ms */ @@ -161,6 +161,8 @@ struct ubsa_softc { struct ucom_softc sc_ucom; + int sc_huawei; + int sc_iface_number; /* interface number */ usbd_interface_handle sc_intr_iface; /* interrupt interface */ @@ -236,6 +238,7 @@ { USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3GPLUS }, /* Huawei Mobile */ { USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_MOBILE }, + { USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E270 }, /* Sierra Wireless LENOVO UMTS card */ { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755_3 }, /* Qualcomm, Inc. ZTE CDMA */ @@ -266,6 +269,65 @@ MODULE_DEPEND(ubsa, ucom, UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER); MODULE_VERSION(ubsa, UBSA_MODVER); +/* + * Huawei Exxx radio devices have a built in flash disk which is their + * default power up configuration. This allows the device to carry its + * own installation software. + * + * Instead of following the USB spec, and create multiple configuration + * descriptors for this, the devices expects the driver to send + * UF_DEVICE_REMOTE_WAKEUP to endpoint 2 to reset the device, so it + * reprobes, now with the radio exposed. + */ + +static usbd_status +ubsa_huawei(device_t self, struct usb_attach_arg *uaa) { + usb_device_request_t req; usbd_device_handle dev; + usb_config_descriptor_t *cdesc; + + if (self == NULL) + return (UMATCH_NONE); + if (uaa == NULL) + return (UMATCH_NONE); + dev = uaa->device; + if (dev == NULL) + return (UMATCH_NONE); + /* get the config descriptor */ + cdesc = usbd_get_config_descriptor(dev); + if (cdesc == NULL) + return (UMATCH_NONE); + + /* Most likely we need to diffentiate between Mobile and E220/E270 models */ + switch (uaa->product) { + case USB_PRODUCT_HUAWEI_MOBILE: + if (cdesc->bNumInterface == 2) /* PUT CORRECT VALUE HERE - NEED DEVICE FOR TESTING */ + return (0); + break; + case USB_PRODUCT_HUAWEI_E270: + if (cdesc->bNumInterface == 4) + return (0); + break; + default: + /* We don't know how to handle this - so leave it to ubsa and hope the best */ + device_printf(self, "Unknown Huawei product (%u) - disabling whack\n", uaa->product); + return (0); + } + + /* Bend it like Beckham */ + device_printf(self, "Kicking Huawei device into radio mode\n"); + memset(&req, 0, sizeof req); + req.bmRequestType = UT_WRITE_DEVICE; + req.bRequest = UR_SET_FEATURE; + USETW(req.wValue, UF_DEVICE_REMOTE_WAKEUP); + USETW(req.wIndex, 2); + USETW(req.wLength, 0); + + /* We get error return, but it works */ + (void)usbd_do_request(dev, &req, 0); + return (UMATCH_NONE); +} + + static int ubsa_match(device_t self) { @@ -278,6 +340,9 @@ for (i = 0; ubsa_products[i].vendor != 0; i++) { if (ubsa_products[i].vendor == uaa->vendor && ubsa_products[i].product == uaa->product) { + if (uaa->vendor == USB_VENDOR_HUAWEI && + ubsa_huawei(self, uaa)) + break; return (UMATCH_VENDOR_PRODUCT); } } @@ -300,6 +365,9 @@ dev = uaa->device; ucom = &sc->sc_ucom; + if (uaa->vendor == USB_VENDOR_HUAWEI) + sc->sc_huawei = 1; + /* * initialize rts, dtr variables to something * different from boolean 0, 1 @@ -400,6 +468,8 @@ ucom->sc_parent = sc; ucom->sc_portno = UCOM_UNK_PORTNO; /* bulkin, bulkout set above */ + ucom->sc_ibufsize = 1024; + ucom->sc_obufsize = 1024; ucom->sc_ibufsizepad = ucom->sc_ibufsize; ucom->sc_opkthdrlen = 0; ucom->sc_callback = &ubsa_callback; @@ -445,6 +515,9 @@ usb_device_request_t req; usbd_status err; + /* The huawei Exxx devices support none of these tricks */ + if (sc->sc_huawei) + return (0); req.bmRequestType = UT_WRITE_VENDOR_DEVICE; req.bRequest = request; USETW(req.wValue, value); @@ -453,8 +526,8 @@ err = usbd_do_request(sc->sc_ucom.sc_udev, &req, 0); if (err) - device_printf(sc->sc_ucom.sc_dev, "ubsa_request: %s\n", - usbd_errstr(err)); + device_printf(sc->sc_ucom.sc_dev, "ubsa_request(%x, %x): %s\n", + request, value, usbd_errstr(err)); return (err); } --- usbdevs.orig 2008-10-07 21:52:35.000000000 +0200 +++ usbdevs 2008-10-07 21:53:55.000000000 +0200 @@ -1403,6 +1403,7 @@ /* HUAWEI products */ product HUAWEI MOBILE 0x1001 Huawei Mobile +product HUAWEI E270 0x1003 Huawei HSPA modem /* HUAWEI 3com products */ product HUAWEI3COM WUB320G 0x0009 Aolynk WUB320g