diff options
author | Todd Poynor <toddpoynor@google.com> | 2013-03-13 17:35:08 -0700 |
---|---|---|
committer | Todd Poynor <toddpoynor@google.com> | 2013-03-13 17:35:08 -0700 |
commit | 1249d25539343d1a7fe361c8d40be7a5df5b0216 (patch) | |
tree | 770c9a33604bb00c62f44d780aefab27e4eb9379 /drivers/usb/storage/initializers.c | |
parent | 4aad13d07babf68c1d0d37ff1e5f797573c4fd2a (diff) | |
parent | 0b203ab4aacdb6e6dfb8c277aa290f0a02428e6f (diff) | |
download | kernel_samsung_tuna-1249d25539343d1a7fe361c8d40be7a5df5b0216.zip kernel_samsung_tuna-1249d25539343d1a7fe361c8d40be7a5df5b0216.tar.gz kernel_samsung_tuna-1249d25539343d1a7fe361c8d40be7a5df5b0216.tar.bz2 |
Merge branch 'android-3.0' into android-omap-3.0
Diffstat (limited to 'drivers/usb/storage/initializers.c')
-rw-r--r-- | drivers/usb/storage/initializers.c | 76 |
1 files changed, 74 insertions, 2 deletions
diff --git a/drivers/usb/storage/initializers.c b/drivers/usb/storage/initializers.c index 105d900..7ab9046 100644 --- a/drivers/usb/storage/initializers.c +++ b/drivers/usb/storage/initializers.c @@ -92,8 +92,8 @@ int usb_stor_ucr61s2b_init(struct us_data *us) return 0; } -/* This places the HUAWEI E220 devices in multi-port mode */ -int usb_stor_huawei_e220_init(struct us_data *us) +/* This places the HUAWEI usb dongles in multi-port mode */ +static int usb_stor_huawei_feature_init(struct us_data *us) { int result; @@ -104,3 +104,75 @@ int usb_stor_huawei_e220_init(struct us_data *us) US_DEBUGP("Huawei mode set result is %d\n", result); return 0; } + +/* + * It will send a scsi switch command called rewind' to huawei dongle. + * When the dongle receives this command at the first time, + * it will reboot immediately. After rebooted, it will ignore this command. + * So it is unnecessary to read its response. + */ +static int usb_stor_huawei_scsi_init(struct us_data *us) +{ + int result = 0; + int act_len = 0; + struct bulk_cb_wrap *bcbw = (struct bulk_cb_wrap *) us->iobuf; + char rewind_cmd[] = {0x11, 0x06, 0x20, 0x00, 0x00, 0x01, 0x01, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + bcbw->Signature = cpu_to_le32(US_BULK_CB_SIGN); + bcbw->Tag = 0; + bcbw->DataTransferLength = 0; + bcbw->Flags = bcbw->Lun = 0; + bcbw->Length = sizeof(rewind_cmd); + memset(bcbw->CDB, 0, sizeof(bcbw->CDB)); + memcpy(bcbw->CDB, rewind_cmd, sizeof(rewind_cmd)); + + result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcbw, + US_BULK_CB_WRAP_LEN, &act_len); + US_DEBUGP("transfer actual length=%d, result=%d\n", act_len, result); + return result; +} + +/* + * It tries to find the supported Huawei USB dongles. + * In Huawei, they assign the following product IDs + * for all of their mobile broadband dongles, + * including the new dongles in the future. + * So if the product ID is not included in this list, + * it means it is not Huawei's mobile broadband dongles. + */ +static int usb_stor_huawei_dongles_pid(struct us_data *us) +{ + struct usb_interface_descriptor *idesc; + int idProduct; + + idesc = &us->pusb_intf->cur_altsetting->desc; + idProduct = le16_to_cpu(us->pusb_dev->descriptor.idProduct); + /* The first port is CDROM, + * means the dongle in the single port mode, + * and a switch command is required to be sent. */ + if (idesc && idesc->bInterfaceNumber == 0) { + if ((idProduct == 0x1001) + || (idProduct == 0x1003) + || (idProduct == 0x1004) + || (idProduct >= 0x1401 && idProduct <= 0x1500) + || (idProduct >= 0x1505 && idProduct <= 0x1600) + || (idProduct >= 0x1c02 && idProduct <= 0x2202)) { + return 1; + } + } + return 0; +} + +int usb_stor_huawei_init(struct us_data *us) +{ + int result = 0; + + if (usb_stor_huawei_dongles_pid(us)) { + if (le16_to_cpu(us->pusb_dev->descriptor.idProduct) >= 0x1446) + result = usb_stor_huawei_scsi_init(us); + else + result = usb_stor_huawei_feature_init(us); + } + return result; +} |