diff options
Diffstat (limited to 'drivers/usb/storage/initializers.c')
-rw-r--r-- | drivers/usb/storage/initializers.c | 76 |
1 files changed, 2 insertions, 74 deletions
diff --git a/drivers/usb/storage/initializers.c b/drivers/usb/storage/initializers.c index 7ab9046ae0ec..105d900150c1 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) | |||
92 | return 0; | 92 | return 0; |
93 | } | 93 | } |
94 | 94 | ||
95 | /* This places the HUAWEI usb dongles in multi-port mode */ | 95 | /* This places the HUAWEI E220 devices in multi-port mode */ |
96 | static int usb_stor_huawei_feature_init(struct us_data *us) | 96 | int usb_stor_huawei_e220_init(struct us_data *us) |
97 | { | 97 | { |
98 | int result; | 98 | int result; |
99 | 99 | ||
@@ -104,75 +104,3 @@ static int usb_stor_huawei_feature_init(struct us_data *us) | |||
104 | US_DEBUGP("Huawei mode set result is %d\n", result); | 104 | US_DEBUGP("Huawei mode set result is %d\n", result); |
105 | return 0; | 105 | return 0; |
106 | } | 106 | } |
107 | |||
108 | /* | ||
109 | * It will send a scsi switch command called rewind' to huawei dongle. | ||
110 | * When the dongle receives this command at the first time, | ||
111 | * it will reboot immediately. After rebooted, it will ignore this command. | ||
112 | * So it is unnecessary to read its response. | ||
113 | */ | ||
114 | static int usb_stor_huawei_scsi_init(struct us_data *us) | ||
115 | { | ||
116 | int result = 0; | ||
117 | int act_len = 0; | ||
118 | struct bulk_cb_wrap *bcbw = (struct bulk_cb_wrap *) us->iobuf; | ||
119 | char rewind_cmd[] = {0x11, 0x06, 0x20, 0x00, 0x00, 0x01, 0x01, 0x00, | ||
120 | 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; | ||
121 | |||
122 | bcbw->Signature = cpu_to_le32(US_BULK_CB_SIGN); | ||
123 | bcbw->Tag = 0; | ||
124 | bcbw->DataTransferLength = 0; | ||
125 | bcbw->Flags = bcbw->Lun = 0; | ||
126 | bcbw->Length = sizeof(rewind_cmd); | ||
127 | memset(bcbw->CDB, 0, sizeof(bcbw->CDB)); | ||
128 | memcpy(bcbw->CDB, rewind_cmd, sizeof(rewind_cmd)); | ||
129 | |||
130 | result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcbw, | ||
131 | US_BULK_CB_WRAP_LEN, &act_len); | ||
132 | US_DEBUGP("transfer actual length=%d, result=%d\n", act_len, result); | ||
133 | return result; | ||
134 | } | ||
135 | |||
136 | /* | ||
137 | * It tries to find the supported Huawei USB dongles. | ||
138 | * In Huawei, they assign the following product IDs | ||
139 | * for all of their mobile broadband dongles, | ||
140 | * including the new dongles in the future. | ||
141 | * So if the product ID is not included in this list, | ||
142 | * it means it is not Huawei's mobile broadband dongles. | ||
143 | */ | ||
144 | static int usb_stor_huawei_dongles_pid(struct us_data *us) | ||
145 | { | ||
146 | struct usb_interface_descriptor *idesc; | ||
147 | int idProduct; | ||
148 | |||
149 | idesc = &us->pusb_intf->cur_altsetting->desc; | ||
150 | idProduct = le16_to_cpu(us->pusb_dev->descriptor.idProduct); | ||
151 | /* The first port is CDROM, | ||
152 | * means the dongle in the single port mode, | ||
153 | * and a switch command is required to be sent. */ | ||
154 | if (idesc && idesc->bInterfaceNumber == 0) { | ||
155 | if ((idProduct == 0x1001) | ||
156 | || (idProduct == 0x1003) | ||
157 | || (idProduct == 0x1004) | ||
158 | || (idProduct >= 0x1401 && idProduct <= 0x1500) | ||
159 | || (idProduct >= 0x1505 && idProduct <= 0x1600) | ||
160 | || (idProduct >= 0x1c02 && idProduct <= 0x2202)) { | ||
161 | return 1; | ||
162 | } | ||
163 | } | ||
164 | return 0; | ||
165 | } | ||
166 | |||
167 | int usb_stor_huawei_init(struct us_data *us) | ||
168 | { | ||
169 | int result = 0; | ||
170 | |||
171 | if (usb_stor_huawei_dongles_pid(us)) { | ||
172 | if (le16_to_cpu(us->pusb_dev->descriptor.idProduct) >= 0x1446) | ||
173 | result = usb_stor_huawei_scsi_init(us); | ||
174 | else | ||
175 | result = usb_stor_huawei_feature_init(us); | ||
176 | } | ||
177 | return result; | ||
178 | } | ||