aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/storage/uas.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2010-12-16 13:05:06 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2010-12-16 13:05:06 -0500
commit36facadd9ea98f8415d0dbb63e0763b7ee9d3911 (patch)
tree99dea00b332ed852f2b0a4923b581dd723f03634 /drivers/usb/storage/uas.c
parent2faa83e2a519abea1055d156ce1b42b8fa57e87b (diff)
parent0b83ae960cd7d4a5ee02786ecf41ab45688999bf (diff)
Merge branch 'usb-next' into musb-merge
* usb-next: (132 commits) USB: uas: Use GFP_NOIO instead of GFP_KERNEL in I/O submission path USB: uas: Ensure we only bind to a UAS interface USB: uas: Rename sense pipe and sense urb to status pipe and status urb USB: uas: Use kzalloc instead of kmalloc USB: uas: Fix up the Sense IU usb: musb: core: kill unneeded #include's DA8xx: assign name to MUSB IRQ resource usb: gadget: g_ncm added usb: gadget: f_ncm.c added usb: gadget: u_ether: prepare for NCM usb: pch_udc: Fix setup transfers with data out usb: pch_udc: Fix compile error, warnings and checkpatch warnings usb: add ab8500 usb transceiver driver USB: gadget: Implement runtime PM for MSM bus glue driver USB: gadget: Implement runtime PM for ci13xxx gadget USB: gadget: Add USB controller driver for MSM SoC USB: gadget: Introduce ci13xxx_udc_driver struct USB: gadget: Initialize ci13xxx gadget device's coherent DMA mask USB: gadget: Fix "scheduling while atomic" bugs in ci13xxx_udc USB: gadget: Separate out PCI bus code from ci13xxx_udc ...
Diffstat (limited to 'drivers/usb/storage/uas.c')
-rw-r--r--drivers/usb/storage/uas.c82
1 files changed, 54 insertions, 28 deletions
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c
index 339fac3949df..23f0dd9c36d4 100644
--- a/drivers/usb/storage/uas.c
+++ b/drivers/usb/storage/uas.c
@@ -49,14 +49,17 @@ struct command_iu {
49 __u8 cdb[16]; /* XXX: Overflow-checking tools may misunderstand */ 49 __u8 cdb[16]; /* XXX: Overflow-checking tools may misunderstand */
50}; 50};
51 51
52/*
53 * Also used for the Read Ready and Write Ready IUs since they have the
54 * same first four bytes
55 */
52struct sense_iu { 56struct sense_iu {
53 __u8 iu_id; 57 __u8 iu_id;
54 __u8 rsvd1; 58 __u8 rsvd1;
55 __be16 tag; 59 __be16 tag;
56 __be16 status_qual; 60 __be16 status_qual;
57 __u8 status; 61 __u8 status;
58 __u8 service_response; 62 __u8 rsvd7[7];
59 __u8 rsvd8[6];
60 __be16 len; 63 __be16 len;
61 __u8 sense[SCSI_SENSE_BUFFERSIZE]; 64 __u8 sense[SCSI_SENSE_BUFFERSIZE];
62}; 65};
@@ -97,8 +100,8 @@ struct uas_dev_info {
97}; 100};
98 101
99enum { 102enum {
100 ALLOC_SENSE_URB = (1 << 0), 103 ALLOC_STATUS_URB = (1 << 0),
101 SUBMIT_SENSE_URB = (1 << 1), 104 SUBMIT_STATUS_URB = (1 << 1),
102 ALLOC_DATA_IN_URB = (1 << 2), 105 ALLOC_DATA_IN_URB = (1 << 2),
103 SUBMIT_DATA_IN_URB = (1 << 3), 106 SUBMIT_DATA_IN_URB = (1 << 3),
104 ALLOC_DATA_OUT_URB = (1 << 4), 107 ALLOC_DATA_OUT_URB = (1 << 4),
@@ -112,7 +115,7 @@ struct uas_cmd_info {
112 unsigned int state; 115 unsigned int state;
113 unsigned int stream; 116 unsigned int stream;
114 struct urb *cmd_urb; 117 struct urb *cmd_urb;
115 struct urb *sense_urb; 118 struct urb *status_urb;
116 struct urb *data_in_urb; 119 struct urb *data_in_urb;
117 struct urb *data_out_urb; 120 struct urb *data_out_urb;
118 struct list_head list; 121 struct list_head list;
@@ -138,7 +141,7 @@ static void uas_do_work(struct work_struct *work)
138 struct scsi_pointer *scp = (void *)cmdinfo; 141 struct scsi_pointer *scp = (void *)cmdinfo;
139 struct scsi_cmnd *cmnd = container_of(scp, 142 struct scsi_cmnd *cmnd = container_of(scp,
140 struct scsi_cmnd, SCp); 143 struct scsi_cmnd, SCp);
141 uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_KERNEL); 144 uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_NOIO);
142 } 145 }
143} 146}
144 147
@@ -204,7 +207,7 @@ static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd,
204 struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; 207 struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
205 int err; 208 int err;
206 209
207 cmdinfo->state = direction | SUBMIT_SENSE_URB; 210 cmdinfo->state = direction | SUBMIT_STATUS_URB;
208 err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_ATOMIC); 211 err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_ATOMIC);
209 if (err) { 212 if (err) {
210 spin_lock(&uas_work_lock); 213 spin_lock(&uas_work_lock);
@@ -294,7 +297,7 @@ static struct urb *uas_alloc_sense_urb(struct uas_dev_info *devinfo, gfp_t gfp,
294 if (!urb) 297 if (!urb)
295 goto out; 298 goto out;
296 299
297 iu = kmalloc(sizeof(*iu), gfp); 300 iu = kzalloc(sizeof(*iu), gfp);
298 if (!iu) 301 if (!iu)
299 goto free; 302 goto free;
300 303
@@ -325,7 +328,7 @@ static struct urb *uas_alloc_cmd_urb(struct uas_dev_info *devinfo, gfp_t gfp,
325 if (len < 0) 328 if (len < 0)
326 len = 0; 329 len = 0;
327 len = ALIGN(len, 4); 330 len = ALIGN(len, 4);
328 iu = kmalloc(sizeof(*iu) + len, gfp); 331 iu = kzalloc(sizeof(*iu) + len, gfp);
329 if (!iu) 332 if (!iu)
330 goto free; 333 goto free;
331 334
@@ -357,21 +360,21 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd,
357{ 360{
358 struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; 361 struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
359 362
360 if (cmdinfo->state & ALLOC_SENSE_URB) { 363 if (cmdinfo->state & ALLOC_STATUS_URB) {
361 cmdinfo->sense_urb = uas_alloc_sense_urb(devinfo, gfp, cmnd, 364 cmdinfo->status_urb = uas_alloc_sense_urb(devinfo, gfp, cmnd,
362 cmdinfo->stream); 365 cmdinfo->stream);
363 if (!cmdinfo->sense_urb) 366 if (!cmdinfo->status_urb)
364 return SCSI_MLQUEUE_DEVICE_BUSY; 367 return SCSI_MLQUEUE_DEVICE_BUSY;
365 cmdinfo->state &= ~ALLOC_SENSE_URB; 368 cmdinfo->state &= ~ALLOC_STATUS_URB;
366 } 369 }
367 370
368 if (cmdinfo->state & SUBMIT_SENSE_URB) { 371 if (cmdinfo->state & SUBMIT_STATUS_URB) {
369 if (usb_submit_urb(cmdinfo->sense_urb, gfp)) { 372 if (usb_submit_urb(cmdinfo->status_urb, gfp)) {
370 scmd_printk(KERN_INFO, cmnd, 373 scmd_printk(KERN_INFO, cmnd,
371 "sense urb submission failure\n"); 374 "sense urb submission failure\n");
372 return SCSI_MLQUEUE_DEVICE_BUSY; 375 return SCSI_MLQUEUE_DEVICE_BUSY;
373 } 376 }
374 cmdinfo->state &= ~SUBMIT_SENSE_URB; 377 cmdinfo->state &= ~SUBMIT_STATUS_URB;
375 } 378 }
376 379
377 if (cmdinfo->state & ALLOC_DATA_IN_URB) { 380 if (cmdinfo->state & ALLOC_DATA_IN_URB) {
@@ -440,7 +443,7 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd,
440 443
441 BUILD_BUG_ON(sizeof(struct uas_cmd_info) > sizeof(struct scsi_pointer)); 444 BUILD_BUG_ON(sizeof(struct uas_cmd_info) > sizeof(struct scsi_pointer));
442 445
443 if (!cmdinfo->sense_urb && sdev->current_cmnd) 446 if (!cmdinfo->status_urb && sdev->current_cmnd)
444 return SCSI_MLQUEUE_DEVICE_BUSY; 447 return SCSI_MLQUEUE_DEVICE_BUSY;
445 448
446 if (blk_rq_tagged(cmnd->request)) { 449 if (blk_rq_tagged(cmnd->request)) {
@@ -452,7 +455,7 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd,
452 455
453 cmnd->scsi_done = done; 456 cmnd->scsi_done = done;
454 457
455 cmdinfo->state = ALLOC_SENSE_URB | SUBMIT_SENSE_URB | 458 cmdinfo->state = ALLOC_STATUS_URB | SUBMIT_STATUS_URB |
456 ALLOC_CMD_URB | SUBMIT_CMD_URB; 459 ALLOC_CMD_URB | SUBMIT_CMD_URB;
457 460
458 switch (cmnd->sc_data_direction) { 461 switch (cmnd->sc_data_direction) {
@@ -475,8 +478,8 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd,
475 err = uas_submit_urbs(cmnd, devinfo, GFP_ATOMIC); 478 err = uas_submit_urbs(cmnd, devinfo, GFP_ATOMIC);
476 if (err) { 479 if (err) {
477 /* If we did nothing, give up now */ 480 /* If we did nothing, give up now */
478 if (cmdinfo->state & SUBMIT_SENSE_URB) { 481 if (cmdinfo->state & SUBMIT_STATUS_URB) {
479 usb_free_urb(cmdinfo->sense_urb); 482 usb_free_urb(cmdinfo->status_urb);
480 return SCSI_MLQUEUE_DEVICE_BUSY; 483 return SCSI_MLQUEUE_DEVICE_BUSY;
481 } 484 }
482 spin_lock(&uas_work_lock); 485 spin_lock(&uas_work_lock);
@@ -578,6 +581,34 @@ static struct usb_device_id uas_usb_ids[] = {
578}; 581};
579MODULE_DEVICE_TABLE(usb, uas_usb_ids); 582MODULE_DEVICE_TABLE(usb, uas_usb_ids);
580 583
584static int uas_is_interface(struct usb_host_interface *intf)
585{
586 return (intf->desc.bInterfaceClass == USB_CLASS_MASS_STORAGE &&
587 intf->desc.bInterfaceSubClass == USB_SC_SCSI &&
588 intf->desc.bInterfaceProtocol == USB_PR_UAS);
589}
590
591static int uas_switch_interface(struct usb_device *udev,
592 struct usb_interface *intf)
593{
594 int i;
595
596 if (uas_is_interface(intf->cur_altsetting))
597 return 0;
598
599 for (i = 0; i < intf->num_altsetting; i++) {
600 struct usb_host_interface *alt = &intf->altsetting[i];
601 if (alt == intf->cur_altsetting)
602 continue;
603 if (uas_is_interface(alt))
604 return usb_set_interface(udev,
605 alt->desc.bInterfaceNumber,
606 alt->desc.bAlternateSetting);
607 }
608
609 return -ENODEV;
610}
611
581static void uas_configure_endpoints(struct uas_dev_info *devinfo) 612static void uas_configure_endpoints(struct uas_dev_info *devinfo)
582{ 613{
583 struct usb_host_endpoint *eps[4] = { }; 614 struct usb_host_endpoint *eps[4] = { };
@@ -651,13 +682,8 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id)
651 struct uas_dev_info *devinfo; 682 struct uas_dev_info *devinfo;
652 struct usb_device *udev = interface_to_usbdev(intf); 683 struct usb_device *udev = interface_to_usbdev(intf);
653 684
654 if (id->bInterfaceProtocol == 0x50) { 685 if (uas_switch_interface(udev, intf))
655 int ifnum = intf->cur_altsetting->desc.bInterfaceNumber; 686 return -ENODEV;
656/* XXX: Shouldn't assume that 1 is the alternative we want */
657 int ret = usb_set_interface(udev, ifnum, 1);
658 if (ret)
659 return -ENODEV;
660 }
661 687
662 devinfo = kmalloc(sizeof(struct uas_dev_info), GFP_KERNEL); 688 devinfo = kmalloc(sizeof(struct uas_dev_info), GFP_KERNEL);
663 if (!devinfo) 689 if (!devinfo)