From 7ffe1f6754372419182d1b1ab761af18a6d28090 Mon Sep 17 00:00:00 2001 From: Sascha Wildner Date: Sun, 31 May 2009 12:07:36 +0200 Subject: [PATCH] ugensa(4): Fix handling of Huawei modems. Basically move the calling of the reattach code to get the Huawei modem out of mass storage mode into the _match() routine and simplify the logic behind when calling it and when not. Now it is called for any Huawei modem if it has only one interface, probably only a mass storage interface. Normally this mass-storage interface is used under windows as it carries the windows-drivers for the device. As we don't need it, we just tell the box that we want the modem interface and not mass storage. Dragonfly-bug: Submitted-by: Alex Hornung Tested-by: Brendan Kosowski Approved-by: hasso --- sys/dev/usbmisc/ugensa/ugensa.c | 48 +++++++++++++++------------------ 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/sys/dev/usbmisc/ugensa/ugensa.c b/sys/dev/usbmisc/ugensa/ugensa.c index 23cb373047..d06c931636 100644 --- a/sys/dev/usbmisc/ugensa/ugensa.c +++ b/sys/dev/usbmisc/ugensa/ugensa.c @@ -86,7 +86,7 @@ static device_method_t ugensa_methods[] = { { 0, 0 } }; -static driver_t ugensa_driver = { +static driver_t ugensa_driver = { "ucom", ugensa_methods, sizeof (struct ugensa_softc) @@ -169,31 +169,32 @@ static int ugensa_match(device_t self) { struct usb_attach_arg *uaa = device_get_ivars(self); - usb_interface_descriptor_t *id; if (uaa->iface == NULL) return UMATCH_NONE; /* - * Some devices have massstorage interfaces - don't claim ownership - * of these ... in general. - * - * Some devices (most notably Huawei E220) need special handling - * though. These come up with single umass interface, waiting for - * magic sent to it, detach and attach again with three interfaces. - * We have to claim such mass storage interface to send a magic to - * it. + * Some devices have mass storage interfaces. What we do with these + * is telling them that we don't need the mass storage and then + * just treat them the way we should. + * + * These devices, most notably Huawei (vendor id 0x12d1) have only + * one interface in mass storage, and after sending them magic, + * they have more than one and are in the correct operating mode. */ - id = usbd_get_interface_descriptor(uaa->iface); - if (id == NULL || id->bInterfaceClass == UICLASS_MASS) { - if ((uaa->vendor == 0x12d1 && uaa->product == 0x1003) || - (uaa->vendor == 0x12d1 && uaa->product == 0x1004)) { - if (uaa->nifaces == 1) - return UMATCH_VENDOR_IFACESUBCLASS; - else - return UMATCH_NONE; - } else - return UMATCH_NONE; + + if (uaa->vendor == 0x12d1) { + if (uaa->nifaces > 1) { + /* + * XXX: we might want to let the normal lookup handle + * these cases. Right now we just claim we know the + * device if it isn't in mass storage mode anymore. + */ + return UMATCH_VENDOR_IFACESUBCLASS; + } else { + ugensa_e220_changemode(uaa->device); + return -1; // avoid umass to reattach (UMATCH_HIGHEST) + } } return (usb_lookup(ugensa_devs, uaa->vendor, uaa->product) != NULL) ? @@ -218,13 +219,6 @@ ugensa_attach(device_t self) ucom->sc_iface = uaa->iface; id = usbd_get_interface_descriptor(ucom->sc_iface); - if (id == NULL || id->bInterfaceClass == UICLASS_MASS) { - if ((uaa->vendor == 0x12d1 && uaa->product == 0x1003) || - (uaa->vendor == 0x12d1 && uaa->product == 0x1004)) { - ugensa_e220_changemode(uaa->device); - } - return ENXIO; - } sc->sc_iface_no = id->bInterfaceNumber; ucom->sc_bulkin_no = ucom->sc_bulkout_no = -1; -- 2.41.0