Project

General

Profile

Bug #1324 ยป huawei.patch

alexh, 05/06/2009 07:06 AM

View differences:

sys/dev/usbmisc/ugensa/ugensa.c
static void ugensa_get_status(void *, int, u_char *, u_char *);
static void ugensa_set(void *, int, int, int);
static void ugensa_e220_changemode(usbd_device_handle);
static int ugensa_e220_changemode(struct usb_attach_arg *);
static device_method_t ugensa_methods[] = {
/* Device interface */
......
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.
*/
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)
return ugensa_e220_changemode(uaa);
return (usb_lookup(ugensa_devs, uaa->vendor, uaa->product) != NULL) ?
UMATCH_VENDOR_IFACESUBCLASS : UMATCH_NONE;
......
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;
......
(void)usbd_do_request(sc->sc_ucom.sc_udev, &req, 0);
}
static void
ugensa_e220_changemode(usbd_device_handle dev)
static int
ugensa_e220_changemode(struct usb_attach_arg *uaa)
{
usb_device_request_t req;
usbd_device_handle dev;
//usb_interface_descriptor_t *id;
//id = usbd_get_interface_descriptor(uaa->iface);
if (uaa->nifaces > 1)
return UMATCH_VENDOR_IFACESUBCLASS;
dev = uaa->device;
req.bmRequestType = UT_WRITE_DEVICE;
req.bRequest = UR_SET_FEATURE;
......
USETW(req.wLength, 0);
usbd_do_request(dev, &req, 0);
return -1; // from NetBSD: avoid umass to reattach (UMATCH_HIGHEST)
}
    (1-1/1)