blob: b012738196927244bf5cf2868b9d08f793637d7a [file] [log] [blame]
Matthew Wilcox115bb1f2010-10-07 13:05:23 +02001/*
2 * USB Attached SCSI
3 * Note that this is not the same as the USB Mass Storage driver
4 *
5 * Copyright Matthew Wilcox for Intel Corp, 2010
6 * Copyright Sarah Sharp for Intel Corp, 2010
7 *
8 * Distributed under the terms of the GNU GPL, version two.
9 */
10
11#include <linux/blkdev.h>
12#include <linux/slab.h>
13#include <linux/types.h>
Paul Gortmaker6eb0de82011-07-03 16:09:31 -040014#include <linux/module.h>
Matthew Wilcox115bb1f2010-10-07 13:05:23 +020015#include <linux/usb.h>
Sebastian Andrzej Siewiorc898add2012-01-11 12:42:32 +010016#include <linux/usb/hcd.h>
Matthew Wilcox115bb1f2010-10-07 13:05:23 +020017#include <linux/usb/storage.h>
Sebastian Andrzej Siewior348748b2012-01-11 12:45:56 +010018#include <linux/usb/uas.h>
Matthew Wilcox115bb1f2010-10-07 13:05:23 +020019
20#include <scsi/scsi.h>
21#include <scsi/scsi_dbg.h>
22#include <scsi/scsi_cmnd.h>
23#include <scsi/scsi_device.h>
24#include <scsi/scsi_host.h>
25#include <scsi/scsi_tcq.h>
26
Matthew Wilcox115bb1f2010-10-07 13:05:23 +020027/*
28 * The r00-r01c specs define this version of the SENSE IU data structure.
29 * It's still in use by several different firmware releases.
30 */
31struct sense_iu_old {
32 __u8 iu_id;
33 __u8 rsvd1;
34 __be16 tag;
35 __be16 len;
36 __u8 status;
37 __u8 service_response;
38 __u8 sense[SCSI_SENSE_BUFFERSIZE];
39};
40
Matthew Wilcox115bb1f2010-10-07 13:05:23 +020041struct uas_dev_info {
42 struct usb_interface *intf;
43 struct usb_device *udev;
44 int qdepth;
45 unsigned cmd_pipe, status_pipe, data_in_pipe, data_out_pipe;
46 unsigned use_streams:1;
47 unsigned uas_sense_old:1;
Sebastian Andrzej Siewior22188f42011-12-19 20:22:39 +010048 struct scsi_cmnd *cmnd;
Matthew Wilcox115bb1f2010-10-07 13:05:23 +020049};
50
51enum {
Matthew Wilcox92a3f762010-12-15 15:44:04 -050052 SUBMIT_STATUS_URB = (1 << 1),
Matthew Wilcox115bb1f2010-10-07 13:05:23 +020053 ALLOC_DATA_IN_URB = (1 << 2),
54 SUBMIT_DATA_IN_URB = (1 << 3),
55 ALLOC_DATA_OUT_URB = (1 << 4),
56 SUBMIT_DATA_OUT_URB = (1 << 5),
57 ALLOC_CMD_URB = (1 << 6),
58 SUBMIT_CMD_URB = (1 << 7),
59};
60
61/* Overrides scsi_pointer */
62struct uas_cmd_info {
63 unsigned int state;
64 unsigned int stream;
65 struct urb *cmd_urb;
Matthew Wilcox115bb1f2010-10-07 13:05:23 +020066 struct urb *data_in_urb;
67 struct urb *data_out_urb;
68 struct list_head list;
69};
70
71/* I hate forward declarations, but I actually have a loop */
72static int uas_submit_urbs(struct scsi_cmnd *cmnd,
73 struct uas_dev_info *devinfo, gfp_t gfp);
Sarah Sharpea9da1c2011-12-02 11:55:44 -080074static void uas_do_work(struct work_struct *work);
Matthew Wilcox115bb1f2010-10-07 13:05:23 +020075
Sarah Sharpea9da1c2011-12-02 11:55:44 -080076static DECLARE_WORK(uas_work, uas_do_work);
Matthew Wilcox115bb1f2010-10-07 13:05:23 +020077static DEFINE_SPINLOCK(uas_work_lock);
78static LIST_HEAD(uas_work_list);
79
80static void uas_do_work(struct work_struct *work)
81{
82 struct uas_cmd_info *cmdinfo;
Sarah Sharpea9da1c2011-12-02 11:55:44 -080083 struct uas_cmd_info *temp;
Matthew Wilcox115bb1f2010-10-07 13:05:23 +020084 struct list_head list;
Sarah Sharpea9da1c2011-12-02 11:55:44 -080085 int err;
Matthew Wilcox115bb1f2010-10-07 13:05:23 +020086
87 spin_lock_irq(&uas_work_lock);
88 list_replace_init(&uas_work_list, &list);
89 spin_unlock_irq(&uas_work_lock);
90
Sarah Sharpea9da1c2011-12-02 11:55:44 -080091 list_for_each_entry_safe(cmdinfo, temp, &list, list) {
Matthew Wilcox115bb1f2010-10-07 13:05:23 +020092 struct scsi_pointer *scp = (void *)cmdinfo;
93 struct scsi_cmnd *cmnd = container_of(scp,
94 struct scsi_cmnd, SCp);
Sarah Sharpea9da1c2011-12-02 11:55:44 -080095 err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_NOIO);
96 if (err) {
97 list_del(&cmdinfo->list);
98 spin_lock_irq(&uas_work_lock);
99 list_add_tail(&cmdinfo->list, &uas_work_list);
100 spin_unlock_irq(&uas_work_lock);
101 schedule_work(&uas_work);
102 }
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200103 }
104}
105
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200106static void uas_sense(struct urb *urb, struct scsi_cmnd *cmnd)
107{
108 struct sense_iu *sense_iu = urb->transfer_buffer;
109 struct scsi_device *sdev = cmnd->device;
110
111 if (urb->actual_length > 16) {
112 unsigned len = be16_to_cpup(&sense_iu->len);
113 if (len + 16 != urb->actual_length) {
114 int newlen = min(len + 16, urb->actual_length) - 16;
115 if (newlen < 0)
116 newlen = 0;
117 sdev_printk(KERN_INFO, sdev, "%s: urb length %d "
118 "disagrees with IU sense data length %d, "
119 "using %d bytes of sense data\n", __func__,
120 urb->actual_length, len, newlen);
121 len = newlen;
122 }
123 memcpy(cmnd->sense_buffer, sense_iu->sense, len);
124 }
125
126 cmnd->result = sense_iu->status;
Gerd Hoffmannc621a812012-06-19 09:54:48 +0200127 cmnd->scsi_done(cmnd);
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200128}
129
130static void uas_sense_old(struct urb *urb, struct scsi_cmnd *cmnd)
131{
132 struct sense_iu_old *sense_iu = urb->transfer_buffer;
133 struct scsi_device *sdev = cmnd->device;
134
135 if (urb->actual_length > 8) {
136 unsigned len = be16_to_cpup(&sense_iu->len) - 2;
137 if (len + 8 != urb->actual_length) {
138 int newlen = min(len + 8, urb->actual_length) - 8;
139 if (newlen < 0)
140 newlen = 0;
141 sdev_printk(KERN_INFO, sdev, "%s: urb length %d "
142 "disagrees with IU sense data length %d, "
143 "using %d bytes of sense data\n", __func__,
144 urb->actual_length, len, newlen);
145 len = newlen;
146 }
147 memcpy(cmnd->sense_buffer, sense_iu->sense, len);
148 }
149
150 cmnd->result = sense_iu->status;
Gerd Hoffmannc621a812012-06-19 09:54:48 +0200151 cmnd->scsi_done(cmnd);
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200152}
153
154static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd,
155 unsigned direction)
156{
157 struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
158 int err;
159
Gerd Hoffmanndb32de12012-06-19 09:54:49 +0200160 cmdinfo->state = direction | SUBMIT_STATUS_URB;
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200161 err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_ATOMIC);
162 if (err) {
163 spin_lock(&uas_work_lock);
164 list_add_tail(&cmdinfo->list, &uas_work_list);
165 spin_unlock(&uas_work_lock);
166 schedule_work(&uas_work);
167 }
168}
169
170static void uas_stat_cmplt(struct urb *urb)
171{
172 struct iu *iu = urb->transfer_buffer;
Sebastian Andrzej Siewior22188f42011-12-19 20:22:39 +0100173 struct Scsi_Host *shost = urb->context;
174 struct uas_dev_info *devinfo = (void *)shost->hostdata[0];
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200175 struct scsi_cmnd *cmnd;
176 u16 tag;
177
178 if (urb->status) {
179 dev_err(&urb->dev->dev, "URB BAD STATUS %d\n", urb->status);
Gerd Hoffmanndb32de12012-06-19 09:54:49 +0200180 usb_free_urb(urb);
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200181 return;
182 }
183
184 tag = be16_to_cpup(&iu->tag) - 1;
Sebastian Andrzej Siewior22188f42011-12-19 20:22:39 +0100185 if (tag == 0)
186 cmnd = devinfo->cmnd;
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200187 else
Sebastian Andrzej Siewior22188f42011-12-19 20:22:39 +0100188 cmnd = scsi_host_find_tag(shost, tag - 1);
Sarah Sharp96c1eb92011-12-02 11:55:48 -0800189 if (!cmnd) {
Gerd Hoffmanndb32de12012-06-19 09:54:49 +0200190 usb_free_urb(urb);
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200191 return;
Sarah Sharp96c1eb92011-12-02 11:55:48 -0800192 }
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200193
194 switch (iu->iu_id) {
195 case IU_ID_STATUS:
Sebastian Andrzej Siewior22188f42011-12-19 20:22:39 +0100196 if (devinfo->cmnd == cmnd)
197 devinfo->cmnd = NULL;
198
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200199 if (urb->actual_length < 16)
200 devinfo->uas_sense_old = 1;
201 if (devinfo->uas_sense_old)
202 uas_sense_old(urb, cmnd);
203 else
204 uas_sense(urb, cmnd);
205 break;
206 case IU_ID_READ_READY:
207 uas_xfer_data(urb, cmnd, SUBMIT_DATA_IN_URB);
208 break;
209 case IU_ID_WRITE_READY:
210 uas_xfer_data(urb, cmnd, SUBMIT_DATA_OUT_URB);
211 break;
212 default:
213 scmd_printk(KERN_ERR, cmnd,
214 "Bogus IU (%d) received on status pipe\n", iu->iu_id);
215 }
Gerd Hoffmanne9bd7e12012-06-19 09:54:50 +0200216 usb_free_urb(urb);
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200217}
218
Gerd Hoffmannc621a812012-06-19 09:54:48 +0200219static void uas_data_cmplt(struct urb *urb)
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200220{
Gerd Hoffmannc621a812012-06-19 09:54:48 +0200221 struct scsi_data_buffer *sdb = urb->context;
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200222 sdb->resid = sdb->length - urb->actual_length;
223 usb_free_urb(urb);
224}
225
226static struct urb *uas_alloc_data_urb(struct uas_dev_info *devinfo, gfp_t gfp,
Gerd Hoffmannc621a812012-06-19 09:54:48 +0200227 unsigned int pipe, u16 stream_id,
228 struct scsi_data_buffer *sdb,
229 enum dma_data_direction dir)
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200230{
231 struct usb_device *udev = devinfo->udev;
232 struct urb *urb = usb_alloc_urb(0, gfp);
233
234 if (!urb)
235 goto out;
Gerd Hoffmannc621a812012-06-19 09:54:48 +0200236 usb_fill_bulk_urb(urb, udev, pipe, NULL, sdb->length, uas_data_cmplt,
237 sdb);
238 if (devinfo->use_streams)
239 urb->stream_id = stream_id;
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200240 urb->num_sgs = udev->bus->sg_tablesize ? sdb->table.nents : 0;
241 urb->sg = sdb->table.sgl;
242 out:
243 return urb;
244}
245
246static struct urb *uas_alloc_sense_urb(struct uas_dev_info *devinfo, gfp_t gfp,
Gerd Hoffmanne9bd7e12012-06-19 09:54:50 +0200247 struct Scsi_Host *shost, u16 stream_id)
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200248{
249 struct usb_device *udev = devinfo->udev;
250 struct urb *urb = usb_alloc_urb(0, gfp);
251 struct sense_iu *iu;
252
253 if (!urb)
254 goto out;
255
Matthew Wilcoxac563cf2010-12-15 15:44:03 -0500256 iu = kzalloc(sizeof(*iu), gfp);
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200257 if (!iu)
258 goto free;
259
260 usb_fill_bulk_urb(urb, udev, devinfo->status_pipe, iu, sizeof(*iu),
Gerd Hoffmanne9bd7e12012-06-19 09:54:50 +0200261 uas_stat_cmplt, shost);
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200262 urb->stream_id = stream_id;
263 urb->transfer_flags |= URB_FREE_BUFFER;
264 out:
265 return urb;
266 free:
267 usb_free_urb(urb);
268 return NULL;
269}
270
271static struct urb *uas_alloc_cmd_urb(struct uas_dev_info *devinfo, gfp_t gfp,
272 struct scsi_cmnd *cmnd, u16 stream_id)
273{
274 struct usb_device *udev = devinfo->udev;
275 struct scsi_device *sdev = cmnd->device;
276 struct urb *urb = usb_alloc_urb(0, gfp);
277 struct command_iu *iu;
278 int len;
279
280 if (!urb)
281 goto out;
282
283 len = cmnd->cmd_len - 16;
284 if (len < 0)
285 len = 0;
286 len = ALIGN(len, 4);
Matthew Wilcoxac563cf2010-12-15 15:44:03 -0500287 iu = kzalloc(sizeof(*iu) + len, gfp);
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200288 if (!iu)
289 goto free;
290
291 iu->iu_id = IU_ID_COMMAND;
Sarah Sharp9eb44542011-12-02 11:55:46 -0800292 if (blk_rq_tagged(cmnd->request))
Sebastian Andrzej Siewior22188f42011-12-19 20:22:39 +0100293 iu->tag = cpu_to_be16(cmnd->request->tag + 2);
Sarah Sharp9eb44542011-12-02 11:55:46 -0800294 else
295 iu->tag = cpu_to_be16(1);
Christoph Hellwig02e031c2010-11-10 14:54:09 +0100296 iu->prio_attr = UAS_SIMPLE_TAG;
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200297 iu->len = len;
298 int_to_scsilun(sdev->lun, &iu->lun);
299 memcpy(iu->cdb, cmnd->cmnd, cmnd->cmd_len);
300
301 usb_fill_bulk_urb(urb, udev, devinfo->cmd_pipe, iu, sizeof(*iu) + len,
302 usb_free_urb, NULL);
303 urb->transfer_flags |= URB_FREE_BUFFER;
304 out:
305 return urb;
306 free:
307 usb_free_urb(urb);
308 return NULL;
309}
310
311/*
312 * Why should I request the Status IU before sending the Command IU? Spec
313 * says to, but also says the device may receive them in any order. Seems
314 * daft to me.
315 */
316
Gerd Hoffmanne9bd7e12012-06-19 09:54:50 +0200317static int uas_submit_sense_urb(struct Scsi_Host *shost,
318 gfp_t gfp, unsigned int stream)
319{
320 struct uas_dev_info *devinfo = (void *)shost->hostdata[0];
321 struct urb *urb;
322
323 urb = uas_alloc_sense_urb(devinfo, gfp, shost, stream);
324 if (!urb)
325 return SCSI_MLQUEUE_DEVICE_BUSY;
326 if (usb_submit_urb(urb, gfp)) {
327 shost_printk(KERN_INFO, shost,
328 "sense urb submission failure\n");
329 usb_free_urb(urb);
330 return SCSI_MLQUEUE_DEVICE_BUSY;
331 }
332 return 0;
333}
334
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200335static int uas_submit_urbs(struct scsi_cmnd *cmnd,
Gerd Hoffmanne9bd7e12012-06-19 09:54:50 +0200336 struct uas_dev_info *devinfo, gfp_t gfp)
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200337{
338 struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
Gerd Hoffmanne9bd7e12012-06-19 09:54:50 +0200339 int err;
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200340
Matthew Wilcox92a3f762010-12-15 15:44:04 -0500341 if (cmdinfo->state & SUBMIT_STATUS_URB) {
Gerd Hoffmanne9bd7e12012-06-19 09:54:50 +0200342 err = uas_submit_sense_urb(cmnd->device->host, gfp,
343 cmdinfo->stream);
344 if (err) {
345 return err;
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200346 }
Matthew Wilcox92a3f762010-12-15 15:44:04 -0500347 cmdinfo->state &= ~SUBMIT_STATUS_URB;
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200348 }
349
350 if (cmdinfo->state & ALLOC_DATA_IN_URB) {
351 cmdinfo->data_in_urb = uas_alloc_data_urb(devinfo, gfp,
Gerd Hoffmannc621a812012-06-19 09:54:48 +0200352 devinfo->data_in_pipe, cmdinfo->stream,
353 scsi_in(cmnd), DMA_FROM_DEVICE);
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200354 if (!cmdinfo->data_in_urb)
355 return SCSI_MLQUEUE_DEVICE_BUSY;
356 cmdinfo->state &= ~ALLOC_DATA_IN_URB;
357 }
358
359 if (cmdinfo->state & SUBMIT_DATA_IN_URB) {
360 if (usb_submit_urb(cmdinfo->data_in_urb, gfp)) {
361 scmd_printk(KERN_INFO, cmnd,
362 "data in urb submission failure\n");
363 return SCSI_MLQUEUE_DEVICE_BUSY;
364 }
365 cmdinfo->state &= ~SUBMIT_DATA_IN_URB;
366 }
367
368 if (cmdinfo->state & ALLOC_DATA_OUT_URB) {
369 cmdinfo->data_out_urb = uas_alloc_data_urb(devinfo, gfp,
Gerd Hoffmannc621a812012-06-19 09:54:48 +0200370 devinfo->data_out_pipe, cmdinfo->stream,
371 scsi_out(cmnd), DMA_TO_DEVICE);
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200372 if (!cmdinfo->data_out_urb)
373 return SCSI_MLQUEUE_DEVICE_BUSY;
374 cmdinfo->state &= ~ALLOC_DATA_OUT_URB;
375 }
376
377 if (cmdinfo->state & SUBMIT_DATA_OUT_URB) {
378 if (usb_submit_urb(cmdinfo->data_out_urb, gfp)) {
379 scmd_printk(KERN_INFO, cmnd,
380 "data out urb submission failure\n");
381 return SCSI_MLQUEUE_DEVICE_BUSY;
382 }
383 cmdinfo->state &= ~SUBMIT_DATA_OUT_URB;
384 }
385
386 if (cmdinfo->state & ALLOC_CMD_URB) {
387 cmdinfo->cmd_urb = uas_alloc_cmd_urb(devinfo, gfp, cmnd,
388 cmdinfo->stream);
389 if (!cmdinfo->cmd_urb)
390 return SCSI_MLQUEUE_DEVICE_BUSY;
391 cmdinfo->state &= ~ALLOC_CMD_URB;
392 }
393
394 if (cmdinfo->state & SUBMIT_CMD_URB) {
395 if (usb_submit_urb(cmdinfo->cmd_urb, gfp)) {
396 scmd_printk(KERN_INFO, cmnd,
397 "cmd urb submission failure\n");
398 return SCSI_MLQUEUE_DEVICE_BUSY;
399 }
400 cmdinfo->state &= ~SUBMIT_CMD_URB;
401 }
402
403 return 0;
404}
405
Jeff Garzikf2812332010-11-16 02:10:29 -0500406static int uas_queuecommand_lck(struct scsi_cmnd *cmnd,
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200407 void (*done)(struct scsi_cmnd *))
408{
409 struct scsi_device *sdev = cmnd->device;
410 struct uas_dev_info *devinfo = sdev->hostdata;
411 struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
412 int err;
413
414 BUILD_BUG_ON(sizeof(struct uas_cmd_info) > sizeof(struct scsi_pointer));
415
Sebastian Andrzej Siewior22188f42011-12-19 20:22:39 +0100416 if (devinfo->cmnd)
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200417 return SCSI_MLQUEUE_DEVICE_BUSY;
418
419 if (blk_rq_tagged(cmnd->request)) {
Sebastian Andrzej Siewior22188f42011-12-19 20:22:39 +0100420 cmdinfo->stream = cmnd->request->tag + 2;
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200421 } else {
Sebastian Andrzej Siewior22188f42011-12-19 20:22:39 +0100422 devinfo->cmnd = cmnd;
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200423 cmdinfo->stream = 1;
424 }
425
426 cmnd->scsi_done = done;
427
Gerd Hoffmanne9bd7e12012-06-19 09:54:50 +0200428 cmdinfo->state = SUBMIT_STATUS_URB |
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200429 ALLOC_CMD_URB | SUBMIT_CMD_URB;
430
431 switch (cmnd->sc_data_direction) {
432 case DMA_FROM_DEVICE:
433 cmdinfo->state |= ALLOC_DATA_IN_URB | SUBMIT_DATA_IN_URB;
434 break;
435 case DMA_BIDIRECTIONAL:
436 cmdinfo->state |= ALLOC_DATA_IN_URB | SUBMIT_DATA_IN_URB;
437 case DMA_TO_DEVICE:
438 cmdinfo->state |= ALLOC_DATA_OUT_URB | SUBMIT_DATA_OUT_URB;
439 case DMA_NONE:
440 break;
441 }
442
443 if (!devinfo->use_streams) {
Gerd Hoffmanndb32de12012-06-19 09:54:49 +0200444 cmdinfo->state &= ~(SUBMIT_DATA_IN_URB | SUBMIT_DATA_OUT_URB);
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200445 cmdinfo->stream = 0;
446 }
447
448 err = uas_submit_urbs(cmnd, devinfo, GFP_ATOMIC);
449 if (err) {
450 /* If we did nothing, give up now */
Matthew Wilcox92a3f762010-12-15 15:44:04 -0500451 if (cmdinfo->state & SUBMIT_STATUS_URB) {
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200452 return SCSI_MLQUEUE_DEVICE_BUSY;
453 }
454 spin_lock(&uas_work_lock);
455 list_add_tail(&cmdinfo->list, &uas_work_list);
456 spin_unlock(&uas_work_lock);
457 schedule_work(&uas_work);
458 }
459
460 return 0;
461}
462
Jeff Garzikf2812332010-11-16 02:10:29 -0500463static DEF_SCSI_QCMD(uas_queuecommand)
464
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200465static int uas_eh_abort_handler(struct scsi_cmnd *cmnd)
466{
467 struct scsi_device *sdev = cmnd->device;
468 sdev_printk(KERN_INFO, sdev, "%s tag %d\n", __func__,
469 cmnd->request->tag);
470
471/* XXX: Send ABORT TASK Task Management command */
472 return FAILED;
473}
474
475static int uas_eh_device_reset_handler(struct scsi_cmnd *cmnd)
476{
477 struct scsi_device *sdev = cmnd->device;
478 sdev_printk(KERN_INFO, sdev, "%s tag %d\n", __func__,
479 cmnd->request->tag);
480
481/* XXX: Send LOGICAL UNIT RESET Task Management command */
482 return FAILED;
483}
484
485static int uas_eh_target_reset_handler(struct scsi_cmnd *cmnd)
486{
487 struct scsi_device *sdev = cmnd->device;
488 sdev_printk(KERN_INFO, sdev, "%s tag %d\n", __func__,
489 cmnd->request->tag);
490
491/* XXX: Can we reset just the one USB interface?
492 * Would calling usb_set_interface() have the right effect?
493 */
494 return FAILED;
495}
496
497static int uas_eh_bus_reset_handler(struct scsi_cmnd *cmnd)
498{
499 struct scsi_device *sdev = cmnd->device;
500 struct uas_dev_info *devinfo = sdev->hostdata;
501 struct usb_device *udev = devinfo->udev;
502
503 sdev_printk(KERN_INFO, sdev, "%s tag %d\n", __func__,
504 cmnd->request->tag);
505
506 if (usb_reset_device(udev))
507 return SUCCESS;
508
509 return FAILED;
510}
511
512static int uas_slave_alloc(struct scsi_device *sdev)
513{
514 sdev->hostdata = (void *)sdev->host->hostdata[0];
515 return 0;
516}
517
518static int uas_slave_configure(struct scsi_device *sdev)
519{
520 struct uas_dev_info *devinfo = sdev->hostdata;
521 scsi_set_tag_type(sdev, MSG_ORDERED_TAG);
Sebastian Andrzej Siewior22188f42011-12-19 20:22:39 +0100522 scsi_activate_tcq(sdev, devinfo->qdepth - 2);
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200523 return 0;
524}
525
526static struct scsi_host_template uas_host_template = {
527 .module = THIS_MODULE,
528 .name = "uas",
529 .queuecommand = uas_queuecommand,
530 .slave_alloc = uas_slave_alloc,
531 .slave_configure = uas_slave_configure,
532 .eh_abort_handler = uas_eh_abort_handler,
533 .eh_device_reset_handler = uas_eh_device_reset_handler,
534 .eh_target_reset_handler = uas_eh_target_reset_handler,
535 .eh_bus_reset_handler = uas_eh_bus_reset_handler,
536 .can_queue = 65536, /* Is there a limit on the _host_ ? */
537 .this_id = -1,
538 .sg_tablesize = SG_NONE,
539 .cmd_per_lun = 1, /* until we override it */
540 .skip_settle_delay = 1,
541 .ordered_tag = 1,
542};
543
544static struct usb_device_id uas_usb_ids[] = {
545 { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, USB_SC_SCSI, USB_PR_BULK) },
546 { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, USB_SC_SCSI, USB_PR_UAS) },
547 /* 0xaa is a prototype device I happen to have access to */
548 { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, USB_SC_SCSI, 0xaa) },
549 { }
550};
551MODULE_DEVICE_TABLE(usb, uas_usb_ids);
552
Matthew Wilcox89dc2902010-12-15 15:44:05 -0500553static int uas_is_interface(struct usb_host_interface *intf)
554{
555 return (intf->desc.bInterfaceClass == USB_CLASS_MASS_STORAGE &&
556 intf->desc.bInterfaceSubClass == USB_SC_SCSI &&
557 intf->desc.bInterfaceProtocol == USB_PR_UAS);
558}
559
Sebastian Andrzej Siewiorc898add2012-01-11 12:42:32 +0100560static int uas_isnt_supported(struct usb_device *udev)
561{
562 struct usb_hcd *hcd = bus_to_hcd(udev->bus);
563
564 dev_warn(&udev->dev, "The driver for the USB controller %s does not "
565 "support scatter-gather which is\n",
566 hcd->driver->description);
567 dev_warn(&udev->dev, "required by the UAS driver. Please try an"
568 "alternative USB controller if you wish to use UAS.\n");
569 return -ENODEV;
570}
571
Matthew Wilcox89dc2902010-12-15 15:44:05 -0500572static int uas_switch_interface(struct usb_device *udev,
573 struct usb_interface *intf)
574{
575 int i;
Sebastian Andrzej Siewiorc898add2012-01-11 12:42:32 +0100576 int sg_supported = udev->bus->sg_tablesize != 0;
Matthew Wilcox89dc2902010-12-15 15:44:05 -0500577
578 for (i = 0; i < intf->num_altsetting; i++) {
579 struct usb_host_interface *alt = &intf->altsetting[i];
Sebastian Andrzej Siewiorc898add2012-01-11 12:42:32 +0100580
581 if (uas_is_interface(alt)) {
582 if (!sg_supported)
583 return uas_isnt_supported(udev);
Matthew Wilcox89dc2902010-12-15 15:44:05 -0500584 return usb_set_interface(udev,
585 alt->desc.bInterfaceNumber,
586 alt->desc.bAlternateSetting);
Sebastian Andrzej Siewiorc898add2012-01-11 12:42:32 +0100587 }
Matthew Wilcox89dc2902010-12-15 15:44:05 -0500588 }
589
590 return -ENODEV;
591}
592
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200593static void uas_configure_endpoints(struct uas_dev_info *devinfo)
594{
595 struct usb_host_endpoint *eps[4] = { };
596 struct usb_interface *intf = devinfo->intf;
597 struct usb_device *udev = devinfo->udev;
598 struct usb_host_endpoint *endpoint = intf->cur_altsetting->endpoint;
599 unsigned i, n_endpoints = intf->cur_altsetting->desc.bNumEndpoints;
600
601 devinfo->uas_sense_old = 0;
Sebastian Andrzej Siewior22188f42011-12-19 20:22:39 +0100602 devinfo->cmnd = NULL;
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200603
604 for (i = 0; i < n_endpoints; i++) {
605 unsigned char *extra = endpoint[i].extra;
606 int len = endpoint[i].extralen;
607 while (len > 1) {
608 if (extra[1] == USB_DT_PIPE_USAGE) {
609 unsigned pipe_id = extra[2];
610 if (pipe_id > 0 && pipe_id < 5)
611 eps[pipe_id - 1] = &endpoint[i];
612 break;
613 }
614 len -= extra[0];
615 extra += extra[0];
616 }
617 }
618
619 /*
620 * Assume that if we didn't find a control pipe descriptor, we're
621 * using a device with old firmware that happens to be set up like
622 * this.
623 */
624 if (!eps[0]) {
625 devinfo->cmd_pipe = usb_sndbulkpipe(udev, 1);
626 devinfo->status_pipe = usb_rcvbulkpipe(udev, 1);
627 devinfo->data_in_pipe = usb_rcvbulkpipe(udev, 2);
628 devinfo->data_out_pipe = usb_sndbulkpipe(udev, 2);
629
630 eps[1] = usb_pipe_endpoint(udev, devinfo->status_pipe);
631 eps[2] = usb_pipe_endpoint(udev, devinfo->data_in_pipe);
632 eps[3] = usb_pipe_endpoint(udev, devinfo->data_out_pipe);
633 } else {
634 devinfo->cmd_pipe = usb_sndbulkpipe(udev,
635 eps[0]->desc.bEndpointAddress);
636 devinfo->status_pipe = usb_rcvbulkpipe(udev,
637 eps[1]->desc.bEndpointAddress);
638 devinfo->data_in_pipe = usb_rcvbulkpipe(udev,
639 eps[2]->desc.bEndpointAddress);
640 devinfo->data_out_pipe = usb_sndbulkpipe(udev,
641 eps[3]->desc.bEndpointAddress);
642 }
643
644 devinfo->qdepth = usb_alloc_streams(devinfo->intf, eps + 1, 3, 256,
645 GFP_KERNEL);
646 if (devinfo->qdepth < 0) {
647 devinfo->qdepth = 256;
648 devinfo->use_streams = 0;
649 } else {
650 devinfo->use_streams = 1;
651 }
652}
653
Sebastian Andrzej Siewiordae51542011-12-19 17:06:08 +0100654static void uas_free_streams(struct uas_dev_info *devinfo)
655{
656 struct usb_device *udev = devinfo->udev;
657 struct usb_host_endpoint *eps[3];
658
659 eps[0] = usb_pipe_endpoint(udev, devinfo->status_pipe);
660 eps[1] = usb_pipe_endpoint(udev, devinfo->data_in_pipe);
661 eps[2] = usb_pipe_endpoint(udev, devinfo->data_out_pipe);
662 usb_free_streams(devinfo->intf, eps, 3, GFP_KERNEL);
663}
664
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200665/*
666 * XXX: What I'd like to do here is register a SCSI host for each USB host in
667 * the system. Follow usb-storage's design of registering a SCSI host for
668 * each USB device for the moment. Can implement this by walking up the
669 * USB hierarchy until we find a USB host.
670 */
671static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id)
672{
673 int result;
674 struct Scsi_Host *shost;
675 struct uas_dev_info *devinfo;
676 struct usb_device *udev = interface_to_usbdev(intf);
677
Matthew Wilcox89dc2902010-12-15 15:44:05 -0500678 if (uas_switch_interface(udev, intf))
679 return -ENODEV;
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200680
681 devinfo = kmalloc(sizeof(struct uas_dev_info), GFP_KERNEL);
682 if (!devinfo)
683 return -ENOMEM;
684
685 result = -ENOMEM;
686 shost = scsi_host_alloc(&uas_host_template, sizeof(void *));
687 if (!shost)
688 goto free;
689
690 shost->max_cmd_len = 16 + 252;
691 shost->max_id = 1;
692 shost->sg_tablesize = udev->bus->sg_tablesize;
693
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200694 devinfo->intf = intf;
695 devinfo->udev = udev;
696 uas_configure_endpoints(devinfo);
697
Sebastian Andrzej Siewior22188f42011-12-19 20:22:39 +0100698 result = scsi_init_shared_tag_map(shost, devinfo->qdepth - 2);
Sebastian Andrzej Siewiordae51542011-12-19 17:06:08 +0100699 if (result)
700 goto free;
701
702 result = scsi_add_host(shost, &intf->dev);
703 if (result)
704 goto deconfig_eps;
705
706 shost->hostdata[0] = (unsigned long)devinfo;
707
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200708 scsi_scan_host(shost);
709 usb_set_intfdata(intf, shost);
710 return result;
Sebastian Andrzej Siewiordae51542011-12-19 17:06:08 +0100711
712deconfig_eps:
713 uas_free_streams(devinfo);
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200714 free:
715 kfree(devinfo);
716 if (shost)
717 scsi_host_put(shost);
718 return result;
719}
720
721static int uas_pre_reset(struct usb_interface *intf)
722{
723/* XXX: Need to return 1 if it's not our device in error handling */
724 return 0;
725}
726
727static int uas_post_reset(struct usb_interface *intf)
728{
729/* XXX: Need to return 1 if it's not our device in error handling */
730 return 0;
731}
732
733static void uas_disconnect(struct usb_interface *intf)
734{
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200735 struct Scsi_Host *shost = usb_get_intfdata(intf);
736 struct uas_dev_info *devinfo = (void *)shost->hostdata[0];
737
738 scsi_remove_host(shost);
Sebastian Andrzej Siewiordae51542011-12-19 17:06:08 +0100739 uas_free_streams(devinfo);
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200740 kfree(devinfo);
741}
742
743/*
744 * XXX: Should this plug into libusual so we can auto-upgrade devices from
745 * Bulk-Only to UAS?
746 */
747static struct usb_driver uas_driver = {
748 .name = "uas",
749 .probe = uas_probe,
750 .disconnect = uas_disconnect,
751 .pre_reset = uas_pre_reset,
752 .post_reset = uas_post_reset,
753 .id_table = uas_usb_ids,
754};
755
Greg Kroah-Hartman65db4302011-11-18 09:34:02 -0800756module_usb_driver(uas_driver);
Matthew Wilcox115bb1f2010-10-07 13:05:23 +0200757
758MODULE_LICENSE("GPL");
759MODULE_AUTHOR("Matthew Wilcox and Sarah Sharp");