aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/gadget/ether.c9
-rw-r--r--drivers/usb/host/ehci-sched.c12
-rw-r--r--drivers/usb/host/whci/asl.c23
-rw-r--r--drivers/usb/host/whci/pzl.c24
-rw-r--r--drivers/usb/serial/option.c4
-rw-r--r--drivers/usb/storage/transport.c17
-rw-r--r--drivers/usb/wusbcore/security.c41
7 files changed, 80 insertions, 50 deletions
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index f37de283d0ab..167cb2a8ecef 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -61,11 +61,6 @@
61 * simpler, Microsoft pushes their own approach: RNDIS. The published 61 * simpler, Microsoft pushes their own approach: RNDIS. The published
62 * RNDIS specs are ambiguous and appear to be incomplete, and are also 62 * RNDIS specs are ambiguous and appear to be incomplete, and are also
63 * needlessly complex. They borrow more from CDC ACM than CDC ECM. 63 * needlessly complex. They borrow more from CDC ACM than CDC ECM.
64 *
65 * While CDC ECM, CDC Subset, and RNDIS are designed to extend the ethernet
66 * interface to the target, CDC EEM was designed to use ethernet over the USB
67 * link between the host and target. CDC EEM is implemented as an alternative
68 * to those other protocols when that communication model is more appropriate
69 */ 64 */
70 65
71#define DRIVER_DESC "Ethernet Gadget" 66#define DRIVER_DESC "Ethernet Gadget"
@@ -157,8 +152,8 @@ static inline bool has_rndis(void)
157#define RNDIS_PRODUCT_NUM 0xa4a2 /* Ethernet/RNDIS Gadget */ 152#define RNDIS_PRODUCT_NUM 0xa4a2 /* Ethernet/RNDIS Gadget */
158 153
159/* For EEM gadgets */ 154/* For EEM gadgets */
160#define EEM_VENDOR_NUM 0x0525 /* INVALID - NEEDS TO BE ALLOCATED */ 155#define EEM_VENDOR_NUM 0x1d6b /* Linux Foundation */
161#define EEM_PRODUCT_NUM 0xa4a1 /* INVALID - NEEDS TO BE ALLOCATED */ 156#define EEM_PRODUCT_NUM 0x0102 /* EEM Gadget */
162 157
163/*-------------------------------------------------------------------------*/ 158/*-------------------------------------------------------------------------*/
164 159
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index 3efa59b18044..b25cdea93a1f 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -1400,6 +1400,10 @@ iso_stream_schedule (
1400 goto fail; 1400 goto fail;
1401 } 1401 }
1402 1402
1403 period = urb->interval;
1404 if (!stream->highspeed)
1405 period <<= 3;
1406
1403 now = ehci_readl(ehci, &ehci->regs->frame_index) % mod; 1407 now = ehci_readl(ehci, &ehci->regs->frame_index) % mod;
1404 1408
1405 /* when's the last uframe this urb could start? */ 1409 /* when's the last uframe this urb could start? */
@@ -1417,8 +1421,8 @@ iso_stream_schedule (
1417 1421
1418 /* Fell behind (by up to twice the slop amount)? */ 1422 /* Fell behind (by up to twice the slop amount)? */
1419 if (start >= max - 2 * 8 * SCHEDULE_SLOP) 1423 if (start >= max - 2 * 8 * SCHEDULE_SLOP)
1420 start += stream->interval * DIV_ROUND_UP( 1424 start += period * DIV_ROUND_UP(
1421 max - start, stream->interval) - mod; 1425 max - start, period) - mod;
1422 1426
1423 /* Tried to schedule too far into the future? */ 1427 /* Tried to schedule too far into the future? */
1424 if (unlikely((start + sched->span) >= max)) { 1428 if (unlikely((start + sched->span) >= max)) {
@@ -1441,10 +1445,6 @@ iso_stream_schedule (
1441 1445
1442 /* NOTE: assumes URB_ISO_ASAP, to limit complexity/bugs */ 1446 /* NOTE: assumes URB_ISO_ASAP, to limit complexity/bugs */
1443 1447
1444 period = urb->interval;
1445 if (!stream->highspeed)
1446 period <<= 3;
1447
1448 /* find a uframe slot with enough bandwidth */ 1448 /* find a uframe slot with enough bandwidth */
1449 for (; start < (stream->next_uframe + period); start++) { 1449 for (; start < (stream->next_uframe + period); start++) {
1450 int enough_space; 1450 int enough_space;
diff --git a/drivers/usb/host/whci/asl.c b/drivers/usb/host/whci/asl.c
index c632437c7649..562eba108816 100644
--- a/drivers/usb/host/whci/asl.c
+++ b/drivers/usb/host/whci/asl.c
@@ -115,6 +115,10 @@ static uint32_t process_qset(struct whc *whc, struct whc_qset *qset)
115 if (status & QTD_STS_HALTED) { 115 if (status & QTD_STS_HALTED) {
116 /* Ug, an error. */ 116 /* Ug, an error. */
117 process_halted_qtd(whc, qset, td); 117 process_halted_qtd(whc, qset, td);
118 /* A halted qTD always triggers an update
119 because the qset was either removed or
120 reactivated. */
121 update |= WHC_UPDATE_UPDATED;
118 goto done; 122 goto done;
119 } 123 }
120 124
@@ -305,6 +309,7 @@ int asl_urb_dequeue(struct whc *whc, struct urb *urb, int status)
305 struct whc_urb *wurb = urb->hcpriv; 309 struct whc_urb *wurb = urb->hcpriv;
306 struct whc_qset *qset = wurb->qset; 310 struct whc_qset *qset = wurb->qset;
307 struct whc_std *std, *t; 311 struct whc_std *std, *t;
312 bool has_qtd = false;
308 int ret; 313 int ret;
309 unsigned long flags; 314 unsigned long flags;
310 315
@@ -315,17 +320,21 @@ int asl_urb_dequeue(struct whc *whc, struct urb *urb, int status)
315 goto out; 320 goto out;
316 321
317 list_for_each_entry_safe(std, t, &qset->stds, list_node) { 322 list_for_each_entry_safe(std, t, &qset->stds, list_node) {
318 if (std->urb == urb) 323 if (std->urb == urb) {
324 if (std->qtd)
325 has_qtd = true;
319 qset_free_std(whc, std); 326 qset_free_std(whc, std);
320 else 327 } else
321 std->qtd = NULL; /* so this std is re-added when the qset is */ 328 std->qtd = NULL; /* so this std is re-added when the qset is */
322 } 329 }
323 330
324 asl_qset_remove(whc, qset); 331 if (has_qtd) {
325 wurb->status = status; 332 asl_qset_remove(whc, qset);
326 wurb->is_async = true; 333 wurb->status = status;
327 queue_work(whc->workqueue, &wurb->dequeue_work); 334 wurb->is_async = true;
328 335 queue_work(whc->workqueue, &wurb->dequeue_work);
336 } else
337 qset_remove_urb(whc, qset, urb, status);
329out: 338out:
330 spin_unlock_irqrestore(&whc->lock, flags); 339 spin_unlock_irqrestore(&whc->lock, flags);
331 340
diff --git a/drivers/usb/host/whci/pzl.c b/drivers/usb/host/whci/pzl.c
index a9e05bac6646..0db3fb2dc03a 100644
--- a/drivers/usb/host/whci/pzl.c
+++ b/drivers/usb/host/whci/pzl.c
@@ -121,6 +121,10 @@ static enum whc_update pzl_process_qset(struct whc *whc, struct whc_qset *qset)
121 if (status & QTD_STS_HALTED) { 121 if (status & QTD_STS_HALTED) {
122 /* Ug, an error. */ 122 /* Ug, an error. */
123 process_halted_qtd(whc, qset, td); 123 process_halted_qtd(whc, qset, td);
124 /* A halted qTD always triggers an update
125 because the qset was either removed or
126 reactivated. */
127 update |= WHC_UPDATE_UPDATED;
124 goto done; 128 goto done;
125 } 129 }
126 130
@@ -333,6 +337,7 @@ int pzl_urb_dequeue(struct whc *whc, struct urb *urb, int status)
333 struct whc_urb *wurb = urb->hcpriv; 337 struct whc_urb *wurb = urb->hcpriv;
334 struct whc_qset *qset = wurb->qset; 338 struct whc_qset *qset = wurb->qset;
335 struct whc_std *std, *t; 339 struct whc_std *std, *t;
340 bool has_qtd = false;
336 int ret; 341 int ret;
337 unsigned long flags; 342 unsigned long flags;
338 343
@@ -343,17 +348,22 @@ int pzl_urb_dequeue(struct whc *whc, struct urb *urb, int status)
343 goto out; 348 goto out;
344 349
345 list_for_each_entry_safe(std, t, &qset->stds, list_node) { 350 list_for_each_entry_safe(std, t, &qset->stds, list_node) {
346 if (std->urb == urb) 351 if (std->urb == urb) {
352 if (std->qtd)
353 has_qtd = true;
347 qset_free_std(whc, std); 354 qset_free_std(whc, std);
348 else 355 } else
349 std->qtd = NULL; /* so this std is re-added when the qset is */ 356 std->qtd = NULL; /* so this std is re-added when the qset is */
350 } 357 }
351 358
352 pzl_qset_remove(whc, qset); 359 if (has_qtd) {
353 wurb->status = status; 360 pzl_qset_remove(whc, qset);
354 wurb->is_async = false; 361 update_pzl_hw_view(whc);
355 queue_work(whc->workqueue, &wurb->dequeue_work); 362 wurb->status = status;
356 363 wurb->is_async = false;
364 queue_work(whc->workqueue, &wurb->dequeue_work);
365 } else
366 qset_remove_urb(whc, qset, urb, status);
357out: 367out:
358 spin_unlock_irqrestore(&whc->lock, flags); 368 spin_unlock_irqrestore(&whc->lock, flags);
359 369
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 43c227027560..65d96b214f95 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -328,6 +328,9 @@ static int option_resume(struct usb_serial *serial);
328#define ALCATEL_VENDOR_ID 0x1bbb 328#define ALCATEL_VENDOR_ID 0x1bbb
329#define ALCATEL_PRODUCT_X060S 0x0000 329#define ALCATEL_PRODUCT_X060S 0x0000
330 330
331/* Airplus products */
332#define AIRPLUS_VENDOR_ID 0x1011
333#define AIRPLUS_PRODUCT_MCD650 0x3198
331 334
332static struct usb_device_id option_ids[] = { 335static struct usb_device_id option_ids[] = {
333 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, 336 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
@@ -589,6 +592,7 @@ static struct usb_device_id option_ids[] = {
589 { USB_DEVICE(ALINK_VENDOR_ID, 0x9000) }, 592 { USB_DEVICE(ALINK_VENDOR_ID, 0x9000) },
590 { USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) }, 593 { USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) },
591 { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S) }, 594 { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S) },
595 { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) },
592 { } /* Terminating entry */ 596 { } /* Terminating entry */
593}; 597};
594MODULE_DEVICE_TABLE(usb, option_ids); 598MODULE_DEVICE_TABLE(usb, option_ids);
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index 3a4fb023af72..589f6b4404f0 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -696,7 +696,7 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
696 /* device supports and needs bigger sense buffer */ 696 /* device supports and needs bigger sense buffer */
697 if (us->fflags & US_FL_SANE_SENSE) 697 if (us->fflags & US_FL_SANE_SENSE)
698 sense_size = ~0; 698 sense_size = ~0;
699 699Retry_Sense:
700 US_DEBUGP("Issuing auto-REQUEST_SENSE\n"); 700 US_DEBUGP("Issuing auto-REQUEST_SENSE\n");
701 701
702 scsi_eh_prep_cmnd(srb, &ses, NULL, 0, sense_size); 702 scsi_eh_prep_cmnd(srb, &ses, NULL, 0, sense_size);
@@ -720,6 +720,21 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
720 srb->result = DID_ABORT << 16; 720 srb->result = DID_ABORT << 16;
721 goto Handle_Errors; 721 goto Handle_Errors;
722 } 722 }
723
724 /* Some devices claim to support larger sense but fail when
725 * trying to request it. When a transport failure happens
726 * using US_FS_SANE_SENSE, we always retry with a standard
727 * (small) sense request. This fixes some USB GSM modems
728 */
729 if (temp_result == USB_STOR_TRANSPORT_FAILED &&
730 (us->fflags & US_FL_SANE_SENSE) &&
731 sense_size != US_SENSE_SIZE) {
732 US_DEBUGP("-- auto-sense failure, retry small sense\n");
733 sense_size = US_SENSE_SIZE;
734 goto Retry_Sense;
735 }
736
737 /* Other failures */
723 if (temp_result != USB_STOR_TRANSPORT_GOOD) { 738 if (temp_result != USB_STOR_TRANSPORT_GOOD) {
724 US_DEBUGP("-- auto-sense failure\n"); 739 US_DEBUGP("-- auto-sense failure\n");
725 740
diff --git a/drivers/usb/wusbcore/security.c b/drivers/usb/wusbcore/security.c
index b2f149fedcc5..4516c36436e6 100644
--- a/drivers/usb/wusbcore/security.c
+++ b/drivers/usb/wusbcore/security.c
@@ -200,35 +200,40 @@ int wusb_dev_sec_add(struct wusbhc *wusbhc,
200{ 200{
201 int result, bytes, secd_size; 201 int result, bytes, secd_size;
202 struct device *dev = &usb_dev->dev; 202 struct device *dev = &usb_dev->dev;
203 struct usb_security_descriptor secd; 203 struct usb_security_descriptor *secd;
204 const struct usb_encryption_descriptor *etd, *ccm1_etd = NULL; 204 const struct usb_encryption_descriptor *etd, *ccm1_etd = NULL;
205 void *secd_buf;
206 const void *itr, *top; 205 const void *itr, *top;
207 char buf[64]; 206 char buf[64];
208 207
208 secd = kmalloc(sizeof(struct usb_security_descriptor), GFP_KERNEL);
209 if (secd == NULL) {
210 result = -ENOMEM;
211 goto out;
212 }
213
209 result = usb_get_descriptor(usb_dev, USB_DT_SECURITY, 214 result = usb_get_descriptor(usb_dev, USB_DT_SECURITY,
210 0, &secd, sizeof(secd)); 215 0, secd, sizeof(struct usb_security_descriptor));
211 if (result < sizeof(secd)) { 216 if (result < sizeof(secd)) {
212 dev_err(dev, "Can't read security descriptor or " 217 dev_err(dev, "Can't read security descriptor or "
213 "not enough data: %d\n", result); 218 "not enough data: %d\n", result);
214 goto error_secd; 219 goto out;
215 } 220 }
216 secd_size = le16_to_cpu(secd.wTotalLength); 221 secd_size = le16_to_cpu(secd->wTotalLength);
217 secd_buf = kmalloc(secd_size, GFP_KERNEL); 222 secd = krealloc(secd, secd_size, GFP_KERNEL);
218 if (secd_buf == NULL) { 223 if (secd == NULL) {
219 dev_err(dev, "Can't allocate space for security descriptors\n"); 224 dev_err(dev, "Can't allocate space for security descriptors\n");
220 goto error_secd_alloc; 225 goto out;
221 } 226 }
222 result = usb_get_descriptor(usb_dev, USB_DT_SECURITY, 227 result = usb_get_descriptor(usb_dev, USB_DT_SECURITY,
223 0, secd_buf, secd_size); 228 0, secd, secd_size);
224 if (result < secd_size) { 229 if (result < secd_size) {
225 dev_err(dev, "Can't read security descriptor or " 230 dev_err(dev, "Can't read security descriptor or "
226 "not enough data: %d\n", result); 231 "not enough data: %d\n", result);
227 goto error_secd_all; 232 goto out;
228 } 233 }
229 bytes = 0; 234 bytes = 0;
230 itr = secd_buf + sizeof(secd); 235 itr = &secd[1];
231 top = secd_buf + result; 236 top = (void *)secd + result;
232 while (itr < top) { 237 while (itr < top) {
233 etd = itr; 238 etd = itr;
234 if (top - itr < sizeof(*etd)) { 239 if (top - itr < sizeof(*etd)) {
@@ -259,24 +264,16 @@ int wusb_dev_sec_add(struct wusbhc *wusbhc,
259 dev_err(dev, "WUSB device doesn't support CCM1 encryption, " 264 dev_err(dev, "WUSB device doesn't support CCM1 encryption, "
260 "can't use!\n"); 265 "can't use!\n");
261 result = -EINVAL; 266 result = -EINVAL;
262 goto error_no_ccm1; 267 goto out;
263 } 268 }
264 wusb_dev->ccm1_etd = *ccm1_etd; 269 wusb_dev->ccm1_etd = *ccm1_etd;
265 dev_dbg(dev, "supported encryption: %s; using %s (0x%02x/%02x)\n", 270 dev_dbg(dev, "supported encryption: %s; using %s (0x%02x/%02x)\n",
266 buf, wusb_et_name(ccm1_etd->bEncryptionType), 271 buf, wusb_et_name(ccm1_etd->bEncryptionType),
267 ccm1_etd->bEncryptionValue, ccm1_etd->bAuthKeyIndex); 272 ccm1_etd->bEncryptionValue, ccm1_etd->bAuthKeyIndex);
268 result = 0; 273 result = 0;
269 kfree(secd_buf);
270out: 274out:
275 kfree(secd);
271 return result; 276 return result;
272
273
274error_no_ccm1:
275error_secd_all:
276 kfree(secd_buf);
277error_secd_alloc:
278error_secd:
279 goto out;
280} 277}
281 278
282void wusb_dev_sec_rm(struct wusb_dev *wusb_dev) 279void wusb_dev_sec_rm(struct wusb_dev *wusb_dev)