]> Git Repo - J-u-boot.git/blame - common/usb_storage.c
WS cleanup: remove SPACE(s) followed by TAB
[J-u-boot.git] / common / usb_storage.c
CommitLineData
83d290c5 1// SPDX-License-Identifier: GPL-2.0+
affae2bf 2/*
460c322f
WD
3 * Most of this source has been derived from the Linux USB
4 * project:
5 * (c) 1999-2002 Matthew Dharm ([email protected])
6 * (c) 2000 David L. Brown, Jr. ([email protected])
7 * (c) 1999 Michael Gee ([email protected])
8 * (c) 2000 Yggdrasil Computing, Inc.
9 *
10 *
11 * Adapted for U-Boot:
12 * (C) Copyright 2001 Denis Peter, MPL AG Switzerland
acf277af
SG
13 * Driver model conversion:
14 * (C) Copyright 2015 Google, Inc
affae2bf 15 *
149dded2 16 * For BBB support (C) Copyright 2003
792a09eb 17 * Gary Jennejohn, DENX Software Engineering <[email protected]>
149dded2 18 *
460c322f 19 * BBB support based on /sys/dev/usb/umass.c from
149dded2 20 * FreeBSD.
affae2bf
WD
21 */
22
23/* Note:
24 * Currently only the CBI transport protocoll has been implemented, and it
25 * is only tested with a TEAC USB Floppy. Other Massstorages with CBI or CB
26 * transport protocoll may work as well.
27 */
149dded2
WD
28/*
29 * New Note:
30 * Support for USB Mass Storage Devices (BBB) has been added. It has
31 * only been tested with USB memory sticks.
149dded2 32 */
affae2bf
WD
33
34
affae2bf 35#include <common.h>
e6f6f9e6 36#include <blk.h>
affae2bf 37#include <command.h>
acf277af 38#include <dm.h>
91557579 39#include <errno.h>
f7ae49fc 40#include <log.h>
05108132 41#include <mapmem.h>
cf92e05c 42#include <memalign.h>
c918261c 43#include <asm/byteorder.h>
90526e9f 44#include <asm/cache.h>
affae2bf 45#include <asm/processor.h>
acf277af 46#include <dm/device-internal.h>
07b2b78c 47#include <dm/lists.h>
c05ed00a 48#include <linux/delay.h>
affae2bf 49
735dd97b 50#include <part.h>
affae2bf
WD
51#include <usb.h>
52
80885a9d
WD
53#undef BBB_COMDAT_TRACE
54#undef BBB_XPORT_TRACE
affae2bf 55
affae2bf
WD
56#include <scsi.h>
57/* direction table -- this indicates the direction of the data
58 * transfer for each command code -- a 1 indicates input
59 */
2ff12285 60static const unsigned char us_direction[256/8] = {
affae2bf
WD
61 0x28, 0x81, 0x14, 0x14, 0x20, 0x01, 0x90, 0x77,
62 0x0C, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
63 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01,
64 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
65};
66#define US_DIRECTION(x) ((us_direction[x>>3] >> (x & 7)) & 1)
67
b9560ad6 68static struct scsi_cmd usb_ccb __aligned(ARCH_DMA_MINALIGN);
a0cb3fc3 69static __u32 CBWTag;
149dded2 70
a0cb3fc3 71static int usb_max_devs; /* number of highest available usb device */
affae2bf 72
1af9bfd3 73#if !CONFIG_IS_ENABLED(BLK)
4101f687 74static struct blk_desc usb_dev_desc[USB_MAX_STOR_DEV];
07b2b78c 75#endif
affae2bf
WD
76
77struct us_data;
b9560ad6 78typedef int (*trans_cmnd)(struct scsi_cmd *cb, struct us_data *data);
a0cb3fc3 79typedef int (*trans_reset)(struct us_data *data);
affae2bf
WD
80
81struct us_data {
a0cb3fc3
MT
82 struct usb_device *pusb_dev; /* this usb_device */
83
84 unsigned int flags; /* from filter initially */
3e8581bb 85# define USB_READY (1 << 0)
a0cb3fc3
MT
86 unsigned char ifnum; /* interface number */
87 unsigned char ep_in; /* in endpoint */
88 unsigned char ep_out; /* out ....... */
89 unsigned char ep_int; /* interrupt . */
90 unsigned char subclass; /* as in overview */
91 unsigned char protocol; /* .............. */
92 unsigned char attention_done; /* force attn on first cmd */
93 unsigned short ip_data; /* interrupt data */
94 int action; /* what to do */
95 int ip_wanted; /* needed */
96 int *irq_handle; /* for USB int requests */
0cf207ec 97 unsigned int irqpipe; /* pipe for release_irq */
a0cb3fc3
MT
98 unsigned char irqmaxp; /* max packed for irq Pipe */
99 unsigned char irqinterval; /* Intervall for IRQ Pipe */
b9560ad6 100 struct scsi_cmd *srb; /* current srb */
a0cb3fc3
MT
101 trans_reset transport_reset; /* reset routine */
102 trans_cmnd transport; /* transport routine */
6158d0b4 103 unsigned short max_xfer_blk; /* maximum transfer blocks */
affae2bf
WD
104};
105
1af9bfd3 106#if !CONFIG_IS_ENABLED(BLK)
affae2bf 107static struct us_data usb_stor[USB_MAX_STOR_DEV];
07b2b78c 108#endif
affae2bf 109
80885a9d 110#define USB_STOR_TRANSPORT_GOOD 0
affae2bf
WD
111#define USB_STOR_TRANSPORT_FAILED -1
112#define USB_STOR_TRANSPORT_ERROR -2
113
a0cb3fc3 114int usb_stor_get_info(struct usb_device *dev, struct us_data *us,
4101f687 115 struct blk_desc *dev_desc);
a0cb3fc3
MT
116int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,
117 struct us_data *ss);
1af9bfd3 118#if CONFIG_IS_ENABLED(BLK)
07b2b78c
SG
119static unsigned long usb_stor_read(struct udevice *dev, lbaint_t blknr,
120 lbaint_t blkcnt, void *buffer);
121static unsigned long usb_stor_write(struct udevice *dev, lbaint_t blknr,
122 lbaint_t blkcnt, const void *buffer);
123#else
4101f687 124static unsigned long usb_stor_read(struct blk_desc *block_dev, lbaint_t blknr,
7c4213f6 125 lbaint_t blkcnt, void *buffer);
4101f687 126static unsigned long usb_stor_write(struct blk_desc *block_dev, lbaint_t blknr,
7c4213f6 127 lbaint_t blkcnt, const void *buffer);
07b2b78c 128#endif
affae2bf
WD
129void uhci_show_temp_int_td(void);
130
199adb60 131static void usb_show_progress(void)
affae2bf 132{
226fa9bb 133 debug(".");
affae2bf
WD
134}
135
a0cb3fc3 136/*******************************************************************************
9c998aa8
WD
137 * show info on storage devices; 'usb start/init' must be invoked earlier
138 * as we only retrieve structures populated during devices initialization
139 */
f6b44e0e 140int usb_stor_info(void)
9c998aa8 141{
9807c3b7 142 int count = 0;
1af9bfd3 143#if CONFIG_IS_ENABLED(BLK)
07b2b78c
SG
144 struct udevice *dev;
145
146 for (blk_first_device(IF_TYPE_USB, &dev);
147 dev;
148 blk_next_device(&dev)) {
caa4daa2 149 struct blk_desc *desc = dev_get_uclass_plat(dev);
07b2b78c
SG
150
151 printf(" Device %d: ", desc->devnum);
152 dev_print(desc);
153 count++;
154 }
155#else
9c998aa8
WD
156 int i;
157
f6b44e0e 158 if (usb_max_devs > 0) {
9c998aa8 159 for (i = 0; i < usb_max_devs; i++) {
a0cb3fc3 160 printf(" Device %d: ", i);
9c998aa8
WD
161 dev_print(&usb_dev_desc[i]);
162 }
b9e749e9 163 return 0;
f6b44e0e 164 }
07b2b78c 165#endif
9807c3b7
SG
166 if (!count) {
167 printf("No storage devices, perhaps not 'usb start'ed..?\n");
168 return 1;
169 }
170
b94fc851 171 return 0;
9c998aa8
WD
172}
173
99e9ed1f
LC
174static unsigned int usb_get_max_lun(struct us_data *us)
175{
176 int len;
f5766139 177 ALLOC_CACHE_ALIGN_BUFFER(unsigned char, result, 1);
99e9ed1f
LC
178 len = usb_control_msg(us->pusb_dev,
179 usb_rcvctrlpipe(us->pusb_dev, 0),
180 US_BBB_GET_MAX_LUN,
181 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
182 0, us->ifnum,
f5766139 183 result, sizeof(char),
99e9ed1f 184 USB_CNTL_TIMEOUT * 5);
ceb4972a 185 debug("Get Max LUN -> len = %i, result = %i\n", len, (int) *result);
f5766139 186 return (len > 0) ? *result : 0;
99e9ed1f
LC
187}
188
9807c3b7 189static int usb_stor_probe_device(struct usb_device *udev)
91557579 190{
9807c3b7 191 int lun, max_lun;
07b2b78c 192
1af9bfd3 193#if CONFIG_IS_ENABLED(BLK)
07b2b78c 194 struct us_data *data;
07b2b78c
SG
195 int ret;
196#else
9807c3b7
SG
197 int start;
198
199 if (udev == NULL)
91557579 200 return -ENOENT; /* no more devices available */
07b2b78c
SG
201#endif
202
203 debug("\n\nProbing for storage\n");
1af9bfd3 204#if CONFIG_IS_ENABLED(BLK)
07b2b78c 205 /*
caa4daa2 206 * We store the us_data in the mass storage device's plat. It
07b2b78c
SG
207 * is shared by all LUNs (block devices) attached to this mass storage
208 * device.
209 */
c69cda25 210 data = dev_get_plat(udev->dev);
07b2b78c
SG
211 if (!usb_storage_probe(udev, 0, data))
212 return 0;
213 max_lun = usb_get_max_lun(data);
214 for (lun = 0; lun <= max_lun; lun++) {
215 struct blk_desc *blkdev;
216 struct udevice *dev;
9107c973 217 char str[10];
07b2b78c 218
9107c973
SG
219 snprintf(str, sizeof(str), "lun%d", lun);
220 ret = blk_create_devicef(udev->dev, "usb_storage_blk", str,
221 IF_TYPE_USB, usb_max_devs, 512, 0,
222 &dev);
07b2b78c
SG
223 if (ret) {
224 debug("Cannot bind driver\n");
225 return ret;
226 }
227
caa4daa2 228 blkdev = dev_get_uclass_plat(dev);
07b2b78c
SG
229 blkdev->target = 0xff;
230 blkdev->lun = lun;
91557579 231
07b2b78c 232 ret = usb_stor_get_info(udev, data, blkdev);
d0851c89 233 if (ret == 1) {
07b2b78c
SG
234 usb_max_devs++;
235 debug("%s: Found device %p\n", __func__, udev);
236 } else {
237 debug("usb_stor_get_info: Invalid device\n");
238 ret = device_unbind(dev);
239 if (ret)
240 return ret;
241 }
242 }
243#else
c89e79d4
SG
244 /* We don't have space to even probe if we hit the maximum */
245 if (usb_max_devs == USB_MAX_STOR_DEV) {
246 printf("max USB Storage Device reached: %d stopping\n",
247 usb_max_devs);
248 return -ENOSPC;
249 }
250
9807c3b7
SG
251 if (!usb_storage_probe(udev, 0, &usb_stor[usb_max_devs]))
252 return 0;
253
254 /*
255 * OK, it's a storage device. Iterate over its LUNs and populate
256 * usb_dev_desc'
257 */
258 start = usb_max_devs;
259
260 max_lun = usb_get_max_lun(&usb_stor[usb_max_devs]);
261 for (lun = 0; lun <= max_lun && usb_max_devs < USB_MAX_STOR_DEV;
262 lun++) {
263 struct blk_desc *blkdev;
264
265 blkdev = &usb_dev_desc[usb_max_devs];
266 memset(blkdev, '\0', sizeof(struct blk_desc));
267 blkdev->if_type = IF_TYPE_USB;
268 blkdev->devnum = usb_max_devs;
269 blkdev->part_type = PART_TYPE_UNKNOWN;
270 blkdev->target = 0xff;
271 blkdev->type = DEV_TYPE_UNKNOWN;
272 blkdev->block_read = usb_stor_read;
273 blkdev->block_write = usb_stor_write;
274 blkdev->lun = lun;
275 blkdev->priv = udev;
276
277 if (usb_stor_get_info(udev, &usb_stor[start],
278 &usb_dev_desc[usb_max_devs]) == 1) {
07b2b78c
SG
279 debug("partype: %d\n", blkdev->part_type);
280 part_init(blkdev);
281 debug("partype: %d\n", blkdev->part_type);
9807c3b7
SG
282 usb_max_devs++;
283 debug("%s: Found device %p\n", __func__, udev);
91557579
SG
284 }
285 }
07b2b78c 286#endif
91557579 287
91557579
SG
288 return 0;
289}
290
291void usb_stor_reset(void)
292{
293 usb_max_devs = 0;
294}
295
a0cb3fc3 296/*******************************************************************************
9c998aa8 297 * scan the usb and reports device info
affae2bf
WD
298 * to the user if mode = 1
299 * returns current device or -1 if no
300 */
301int usb_stor_scan(int mode)
302{
a0cb3fc3 303 if (mode == 1)
93c2582f 304 printf(" scanning usb for storage devices... ");
a0cb3fc3 305
fd09c205 306#if !CONFIG_IS_ENABLED(DM_USB)
b984700c
MS
307 unsigned char i;
308
affae2bf
WD
309 usb_disable_asynch(1); /* asynch transfer not allowed */
310
91557579 311 usb_stor_reset();
a0cb3fc3 312 for (i = 0; i < USB_MAX_DEVICE; i++) {
91557579
SG
313 struct usb_device *dev;
314
a0cb3fc3 315 dev = usb_get_dev_index(i); /* get device */
ceb4972a 316 debug("i=%d\n", i);
91557579 317 if (usb_stor_probe_device(dev))
affae2bf 318 break;
affae2bf 319 } /* for */
095b8a37 320
affae2bf 321 usb_disable_asynch(0); /* asynch transfer allowed */
b984700c 322#endif
9c998aa8 323 printf("%d Storage Device(s) found\n", usb_max_devs);
a0cb3fc3 324 if (usb_max_devs > 0)
affae2bf 325 return 0;
a0cb3fc3 326 return -1;
affae2bf
WD
327}
328
329static int usb_stor_irq(struct usb_device *dev)
330{
331 struct us_data *us;
a0cb3fc3 332 us = (struct us_data *)dev->privptr;
affae2bf 333
a0cb3fc3
MT
334 if (us->ip_wanted)
335 us->ip_wanted = 0;
affae2bf
WD
336 return 0;
337}
338
339
ceb4972a 340#ifdef DEBUG
affae2bf 341
b9560ad6 342static void usb_show_srb(struct scsi_cmd *pccb)
affae2bf
WD
343{
344 int i;
a0cb3fc3
MT
345 printf("SRB: len %d datalen 0x%lX\n ", pccb->cmdlen, pccb->datalen);
346 for (i = 0; i < 12; i++)
347 printf("%02X ", pccb->cmd[i]);
affae2bf
WD
348 printf("\n");
349}
350
351static void display_int_status(unsigned long tmp)
352{
353 printf("Status: %s %s %s %s %s %s %s\n",
354 (tmp & USB_ST_ACTIVE) ? "Active" : "",
355 (tmp & USB_ST_STALLED) ? "Stalled" : "",
356 (tmp & USB_ST_BUF_ERR) ? "Buffer Error" : "",
357 (tmp & USB_ST_BABBLE_DET) ? "Babble Det" : "",
358 (tmp & USB_ST_NAK_REC) ? "NAKed" : "",
359 (tmp & USB_ST_CRC_ERR) ? "CRC Error" : "",
360 (tmp & USB_ST_BIT_ERR) ? "Bitstuff Error" : "");
361}
362#endif
363/***********************************************************************
364 * Data transfer routines
365 ***********************************************************************/
366
367static int us_one_transfer(struct us_data *us, int pipe, char *buf, int length)
368{
369 int max_size;
370 int this_xfer;
371 int result;
372 int partial;
373 int maxtry;
374 int stat;
375
376 /* determine the maximum packet size for these transfers */
377 max_size = usb_maxpacket(us->pusb_dev, pipe) * 16;
378
379 /* while we have data left to transfer */
380 while (length) {
381
382 /* calculate how long this will be -- maximum or a remainder */
383 this_xfer = length > max_size ? max_size : length;
384 length -= this_xfer;
385
386 /* setup the retry counter */
387 maxtry = 10;
388
389 /* set up the transfer loop */
390 do {
391 /* transfer the data */
05108132
SG
392 debug("Bulk xfer 0x%lx(%d) try #%d\n",
393 (ulong)map_to_sysmem(buf), this_xfer,
394 11 - maxtry);
affae2bf 395 result = usb_bulk_msg(us->pusb_dev, pipe, buf,
a0cb3fc3
MT
396 this_xfer, &partial,
397 USB_CNTL_TIMEOUT * 5);
ceb4972a
VG
398 debug("bulk_msg returned %d xferred %d/%d\n",
399 result, partial, this_xfer);
a0cb3fc3
MT
400 if (us->pusb_dev->status != 0) {
401 /* if we stall, we need to clear it before
402 * we go on
403 */
ceb4972a 404#ifdef DEBUG
affae2bf
WD
405 display_int_status(us->pusb_dev->status);
406#endif
407 if (us->pusb_dev->status & USB_ST_STALLED) {
ceb4972a
VG
408 debug("stalled ->clearing endpoint" \
409 "halt for pipe 0x%x\n", pipe);
affae2bf
WD
410 stat = us->pusb_dev->status;
411 usb_clear_halt(us->pusb_dev, pipe);
a0cb3fc3
MT
412 us->pusb_dev->status = stat;
413 if (this_xfer == partial) {
ceb4972a
VG
414 debug("bulk transferred" \
415 "with error %lX," \
416 " but data ok\n",
417 us->pusb_dev->status);
affae2bf
WD
418 return 0;
419 }
420 else
421 return result;
422 }
423 if (us->pusb_dev->status & USB_ST_NAK_REC) {
ceb4972a 424 debug("Device NAKed bulk_msg\n");
affae2bf
WD
425 return result;
426 }
ceb4972a 427 debug("bulk transferred with error");
a0cb3fc3 428 if (this_xfer == partial) {
ceb4972a
VG
429 debug(" %ld, but data ok\n",
430 us->pusb_dev->status);
affae2bf
WD
431 return 0;
432 }
433 /* if our try counter reaches 0, bail out */
d91a652c
MS
434 debug(" %ld, data %d\n",
435 us->pusb_dev->status, partial);
affae2bf
WD
436 if (!maxtry--)
437 return result;
438 }
439 /* update to show what data was transferred */
440 this_xfer -= partial;
441 buf += partial;
442 /* continue until this transfer is done */
a0cb3fc3 443 } while (this_xfer);
affae2bf
WD
444 }
445
446 /* if we get here, we're done and successful */
447 return 0;
448}
449
149dded2
WD
450static int usb_stor_BBB_reset(struct us_data *us)
451{
452 int result;
453 unsigned int pipe;
454
455 /*
456 * Reset recovery (5.3.4 in Universal Serial Bus Mass Storage Class)
457 *
458 * For Reset Recovery the host shall issue in the following order:
459 * a) a Bulk-Only Mass Storage Reset
460 * b) a Clear Feature HALT to the Bulk-In endpoint
461 * c) a Clear Feature HALT to the Bulk-Out endpoint
462 *
463 * This is done in 3 steps.
464 *
465 * If the reset doesn't succeed, the device should be port reset.
466 *
467 * This comment stolen from FreeBSD's /sys/dev/usb/umass.c.
468 */
ceb4972a 469 debug("BBB_reset\n");
a0cb3fc3
MT
470 result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev, 0),
471 US_BBB_RESET,
472 USB_TYPE_CLASS | USB_RECIP_INTERFACE,
199adb60 473 0, us->ifnum, NULL, 0, USB_CNTL_TIMEOUT * 5);
9c998aa8 474
a0cb3fc3 475 if ((result < 0) && (us->pusb_dev->status & USB_ST_STALLED)) {
ceb4972a 476 debug("RESET:stall\n");
149dded2
WD
477 return -1;
478 }
9c998aa8 479
149dded2 480 /* long wait for reset */
5b84dd67 481 mdelay(150);
ceb4972a
VG
482 debug("BBB_reset result %d: status %lX reset\n",
483 result, us->pusb_dev->status);
149dded2
WD
484 pipe = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
485 result = usb_clear_halt(us->pusb_dev, pipe);
486 /* long wait for reset */
5b84dd67 487 mdelay(150);
ceb4972a
VG
488 debug("BBB_reset result %d: status %lX clearing IN endpoint\n",
489 result, us->pusb_dev->status);
149dded2
WD
490 /* long wait for reset */
491 pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
492 result = usb_clear_halt(us->pusb_dev, pipe);
5b84dd67 493 mdelay(150);
ceb4972a
VG
494 debug("BBB_reset result %d: status %lX clearing OUT endpoint\n",
495 result, us->pusb_dev->status);
496 debug("BBB_reset done\n");
149dded2
WD
497 return 0;
498}
499
affae2bf
WD
500/* FIXME: this reset function doesn't really reset the port, and it
501 * should. Actually it should probably do what it's doing here, and
502 * reset the port physically
503 */
504static int usb_stor_CB_reset(struct us_data *us)
505{
506 unsigned char cmd[12];
507 int result;
508
ceb4972a 509 debug("CB_reset\n");
a0cb3fc3 510 memset(cmd, 0xff, sizeof(cmd));
affae2bf
WD
511 cmd[0] = SCSI_SEND_DIAG;
512 cmd[1] = 4;
a0cb3fc3
MT
513 result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev, 0),
514 US_CBI_ADSC,
515 USB_TYPE_CLASS | USB_RECIP_INTERFACE,
516 0, us->ifnum, cmd, sizeof(cmd),
517 USB_CNTL_TIMEOUT * 5);
affae2bf
WD
518
519 /* long wait for reset */
5b84dd67 520 mdelay(1500);
ceb4972a
VG
521 debug("CB_reset result %d: status %lX clearing endpoint halt\n",
522 result, us->pusb_dev->status);
affae2bf
WD
523 usb_clear_halt(us->pusb_dev, usb_rcvbulkpipe(us->pusb_dev, us->ep_in));
524 usb_clear_halt(us->pusb_dev, usb_rcvbulkpipe(us->pusb_dev, us->ep_out));
525
ceb4972a 526 debug("CB_reset done\n");
affae2bf
WD
527 return 0;
528}
529
149dded2
WD
530/*
531 * Set up the command for a BBB device. Note that the actual SCSI
532 * command is copied into cbw.CBWCDB.
533 */
b9560ad6 534static int usb_stor_BBB_comdat(struct scsi_cmd *srb, struct us_data *us)
149dded2
WD
535{
536 int result;
537 int actlen;
538 int dir_in;
539 unsigned int pipe;
2e17c87e 540 ALLOC_CACHE_ALIGN_BUFFER(struct umass_bbb_cbw, cbw, 1);
149dded2
WD
541
542 dir_in = US_DIRECTION(srb->cmd[0]);
543
544#ifdef BBB_COMDAT_TRACE
605bd75a 545 printf("dir %d lun %d cmdlen %d cmd %p datalen %lu pdata %p\n",
a0cb3fc3
MT
546 dir_in, srb->lun, srb->cmdlen, srb->cmd, srb->datalen,
547 srb->pdata);
149dded2 548 if (srb->cmdlen) {
a0cb3fc3 549 for (result = 0; result < srb->cmdlen; result++)
149dded2
WD
550 printf("cmd[%d] %#x ", result, srb->cmd[result]);
551 printf("\n");
552 }
553#endif
554 /* sanity checks */
555 if (!(srb->cmdlen <= CBWCDBLENGTH)) {
ceb4972a 556 debug("usb_stor_BBB_comdat:cmdlen too large\n");
149dded2
WD
557 return -1;
558 }
559
560 /* always OUT to the ep */
561 pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
562
f5766139
PS
563 cbw->dCBWSignature = cpu_to_le32(CBWSIGNATURE);
564 cbw->dCBWTag = cpu_to_le32(CBWTag++);
565 cbw->dCBWDataTransferLength = cpu_to_le32(srb->datalen);
566 cbw->bCBWFlags = (dir_in ? CBWFLAGS_IN : CBWFLAGS_OUT);
567 cbw->bCBWLUN = srb->lun;
568 cbw->bCDBLength = srb->cmdlen;
149dded2
WD
569 /* copy the command data into the CBW command data buffer */
570 /* DST SRC LEN!!! */
f6570871 571
f5766139
PS
572 memcpy(cbw->CBWCDB, srb->cmd, srb->cmdlen);
573 result = usb_bulk_msg(us->pusb_dev, pipe, cbw, UMASS_BBB_CBW_SIZE,
a0cb3fc3 574 &actlen, USB_CNTL_TIMEOUT * 5);
149dded2 575 if (result < 0)
ceb4972a 576 debug("usb_stor_BBB_comdat:usb_bulk_msg error\n");
149dded2
WD
577 return result;
578}
579
affae2bf
WD
580/* FIXME: we also need a CBI_command which sets up the completion
581 * interrupt, and waits for it
582 */
b9560ad6 583static int usb_stor_CB_comdat(struct scsi_cmd *srb, struct us_data *us)
affae2bf 584{
77ddac94 585 int result = 0;
a0cb3fc3 586 int dir_in, retry;
affae2bf
WD
587 unsigned int pipe;
588 unsigned long status;
589
a0cb3fc3
MT
590 retry = 5;
591 dir_in = US_DIRECTION(srb->cmd[0]);
affae2bf 592
a0cb3fc3
MT
593 if (dir_in)
594 pipe = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
595 else
596 pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
597
598 while (retry--) {
ceb4972a
VG
599 debug("CBI gets a command: Try %d\n", 5 - retry);
600#ifdef DEBUG
affae2bf
WD
601 usb_show_srb(srb);
602#endif
603 /* let's send the command via the control pipe */
a0cb3fc3
MT
604 result = usb_control_msg(us->pusb_dev,
605 usb_sndctrlpipe(us->pusb_dev , 0),
606 US_CBI_ADSC,
607 USB_TYPE_CLASS | USB_RECIP_INTERFACE,
affae2bf 608 0, us->ifnum,
a0cb3fc3
MT
609 srb->cmd, srb->cmdlen,
610 USB_CNTL_TIMEOUT * 5);
ceb4972a
VG
611 debug("CB_transport: control msg returned %d, status %lX\n",
612 result, us->pusb_dev->status);
affae2bf
WD
613 /* check the return code for the command */
614 if (result < 0) {
a0cb3fc3
MT
615 if (us->pusb_dev->status & USB_ST_STALLED) {
616 status = us->pusb_dev->status;
ceb4972a
VG
617 debug(" stall during command found," \
618 " clear pipe\n");
a0cb3fc3
MT
619 usb_clear_halt(us->pusb_dev,
620 usb_sndctrlpipe(us->pusb_dev, 0));
621 us->pusb_dev->status = status;
affae2bf 622 }
ceb4972a
VG
623 debug(" error during command %02X" \
624 " Stat = %lX\n", srb->cmd[0],
625 us->pusb_dev->status);
affae2bf
WD
626 return result;
627 }
628 /* transfer the data payload for this command, if one exists*/
629
ceb4972a
VG
630 debug("CB_transport: control msg returned %d," \
631 " direction is %s to go 0x%lx\n", result,
632 dir_in ? "IN" : "OUT", srb->datalen);
affae2bf 633 if (srb->datalen) {
a0cb3fc3
MT
634 result = us_one_transfer(us, pipe, (char *)srb->pdata,
635 srb->datalen);
ceb4972a
VG
636 debug("CBI attempted to transfer data," \
637 " result is %d status %lX, len %d\n",
638 result, us->pusb_dev->status,
639 us->pusb_dev->act_len);
a0cb3fc3 640 if (!(us->pusb_dev->status & USB_ST_NAK_REC))
affae2bf
WD
641 break;
642 } /* if (srb->datalen) */
643 else
644 break;
645 }
646 /* return result */
647
648 return result;
649}
650
651
b9560ad6 652static int usb_stor_CBI_get_status(struct scsi_cmd *srb, struct us_data *us)
affae2bf
WD
653{
654 int timeout;
655
80885a9d 656 us->ip_wanted = 1;
50dce8fb 657 usb_int_msg(us->pusb_dev, us->irqpipe,
3437121c 658 (void *)&us->ip_data, us->irqmaxp, us->irqinterval, false);
80885a9d
WD
659 timeout = 1000;
660 while (timeout--) {
f6570871 661 if (us->ip_wanted == 0)
affae2bf 662 break;
5b84dd67 663 mdelay(10);
affae2bf
WD
664 }
665 if (us->ip_wanted) {
a0cb3fc3 666 printf(" Did not get interrupt on CBI\n");
affae2bf
WD
667 us->ip_wanted = 0;
668 return USB_STOR_TRANSPORT_ERROR;
669 }
a6f70a3d 670 debug("Got interrupt data 0x%x, transferred %d status 0x%lX\n",
ceb4972a
VG
671 us->ip_data, us->pusb_dev->irq_act_len,
672 us->pusb_dev->irq_status);
affae2bf
WD
673 /* UFI gives us ASC and ASCQ, like a request sense */
674 if (us->subclass == US_SC_UFI) {
675 if (srb->cmd[0] == SCSI_REQ_SENSE ||
676 srb->cmd[0] == SCSI_INQUIRY)
677 return USB_STOR_TRANSPORT_GOOD; /* Good */
80885a9d
WD
678 else if (us->ip_data)
679 return USB_STOR_TRANSPORT_FAILED;
affae2bf 680 else
80885a9d 681 return USB_STOR_TRANSPORT_GOOD;
affae2bf
WD
682 }
683 /* otherwise, we interpret the data normally */
684 switch (us->ip_data) {
80885a9d
WD
685 case 0x0001:
686 return USB_STOR_TRANSPORT_GOOD;
687 case 0x0002:
688 return USB_STOR_TRANSPORT_FAILED;
689 default:
690 return USB_STOR_TRANSPORT_ERROR;
691 } /* switch */
affae2bf
WD
692 return USB_STOR_TRANSPORT_ERROR;
693}
694
695#define USB_TRANSPORT_UNKNOWN_RETRY 5
696#define USB_TRANSPORT_NOT_READY_RETRY 10
697
149dded2 698/* clear a stall on an endpoint - special for BBB devices */
199adb60 699static int usb_stor_BBB_clear_endpt_stall(struct us_data *us, __u8 endpt)
149dded2 700{
149dded2 701 /* ENDPOINT_HALT = 0, so set value to 0 */
8319aeb1
MY
702 return usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev, 0),
703 USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT, 0,
704 endpt, NULL, 0, USB_CNTL_TIMEOUT * 5);
149dded2
WD
705}
706
b9560ad6 707static int usb_stor_BBB_transport(struct scsi_cmd *srb, struct us_data *us)
149dded2
WD
708{
709 int result, retry;
710 int dir_in;
711 int actlen, data_actlen;
712 unsigned int pipe, pipein, pipeout;
2e17c87e 713 ALLOC_CACHE_ALIGN_BUFFER(struct umass_bbb_csw, csw, 1);
149dded2
WD
714#ifdef BBB_XPORT_TRACE
715 unsigned char *ptr;
716 int index;
717#endif
718
719 dir_in = US_DIRECTION(srb->cmd[0]);
720
721 /* COMMAND phase */
ceb4972a 722 debug("COMMAND phase\n");
149dded2
WD
723 result = usb_stor_BBB_comdat(srb, us);
724 if (result < 0) {
ceb4972a
VG
725 debug("failed to send CBW status %ld\n",
726 us->pusb_dev->status);
149dded2
WD
727 usb_stor_BBB_reset(us);
728 return USB_STOR_TRANSPORT_FAILED;
729 }
3e8581bb
BT
730 if (!(us->flags & USB_READY))
731 mdelay(5);
149dded2
WD
732 pipein = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
733 pipeout = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
734 /* DATA phase + error handling */
149dded2
WD
735 data_actlen = 0;
736 /* no data, go immediately to the STATUS phase */
737 if (srb->datalen == 0)
738 goto st;
ceb4972a 739 debug("DATA phase\n");
149dded2
WD
740 if (dir_in)
741 pipe = pipein;
742 else
743 pipe = pipeout;
f6570871 744
a0cb3fc3
MT
745 result = usb_bulk_msg(us->pusb_dev, pipe, srb->pdata, srb->datalen,
746 &data_actlen, USB_CNTL_TIMEOUT * 5);
149dded2 747 /* special handling of STALL in DATA phase */
a0cb3fc3 748 if ((result < 0) && (us->pusb_dev->status & USB_ST_STALLED)) {
ceb4972a 749 debug("DATA:stall\n");
149dded2 750 /* clear the STALL on the endpoint */
a0cb3fc3
MT
751 result = usb_stor_BBB_clear_endpt_stall(us,
752 dir_in ? us->ep_in : us->ep_out);
149dded2
WD
753 if (result >= 0)
754 /* continue on to STATUS phase */
755 goto st;
756 }
757 if (result < 0) {
ceb4972a
VG
758 debug("usb_bulk_msg error status %ld\n",
759 us->pusb_dev->status);
149dded2
WD
760 usb_stor_BBB_reset(us);
761 return USB_STOR_TRANSPORT_FAILED;
762 }
763#ifdef BBB_XPORT_TRACE
764 for (index = 0; index < data_actlen; index++)
765 printf("pdata[%d] %#x ", index, srb->pdata[index]);
766 printf("\n");
767#endif
768 /* STATUS phase + error handling */
a0cb3fc3 769st:
149dded2 770 retry = 0;
a0cb3fc3 771again:
ceb4972a 772 debug("STATUS phase\n");
f5766139 773 result = usb_bulk_msg(us->pusb_dev, pipein, csw, UMASS_BBB_CSW_SIZE,
9c998aa8
WD
774 &actlen, USB_CNTL_TIMEOUT*5);
775
149dded2 776 /* special handling of STALL in STATUS phase */
a0cb3fc3
MT
777 if ((result < 0) && (retry < 1) &&
778 (us->pusb_dev->status & USB_ST_STALLED)) {
ceb4972a 779 debug("STATUS:stall\n");
149dded2
WD
780 /* clear the STALL on the endpoint */
781 result = usb_stor_BBB_clear_endpt_stall(us, us->ep_in);
782 if (result >= 0 && (retry++ < 1))
783 /* do a retry */
784 goto again;
785 }
786 if (result < 0) {
ceb4972a
VG
787 debug("usb_bulk_msg error status %ld\n",
788 us->pusb_dev->status);
149dded2
WD
789 usb_stor_BBB_reset(us);
790 return USB_STOR_TRANSPORT_FAILED;
791 }
792#ifdef BBB_XPORT_TRACE
f5766139 793 ptr = (unsigned char *)csw;
149dded2
WD
794 for (index = 0; index < UMASS_BBB_CSW_SIZE; index++)
795 printf("ptr[%d] %#x ", index, ptr[index]);
796 printf("\n");
797#endif
798 /* misuse pipe to get the residue */
f5766139 799 pipe = le32_to_cpu(csw->dCSWDataResidue);
149dded2
WD
800 if (pipe == 0 && srb->datalen != 0 && srb->datalen - data_actlen != 0)
801 pipe = srb->datalen - data_actlen;
f5766139 802 if (CSWSIGNATURE != le32_to_cpu(csw->dCSWSignature)) {
ceb4972a 803 debug("!CSWSIGNATURE\n");
149dded2
WD
804 usb_stor_BBB_reset(us);
805 return USB_STOR_TRANSPORT_FAILED;
f5766139 806 } else if ((CBWTag - 1) != le32_to_cpu(csw->dCSWTag)) {
ceb4972a 807 debug("!Tag\n");
149dded2
WD
808 usb_stor_BBB_reset(us);
809 return USB_STOR_TRANSPORT_FAILED;
f5766139 810 } else if (csw->bCSWStatus > CSWSTATUS_PHASE) {
ceb4972a 811 debug(">PHASE\n");
149dded2
WD
812 usb_stor_BBB_reset(us);
813 return USB_STOR_TRANSPORT_FAILED;
f5766139 814 } else if (csw->bCSWStatus == CSWSTATUS_PHASE) {
ceb4972a 815 debug("=PHASE\n");
149dded2
WD
816 usb_stor_BBB_reset(us);
817 return USB_STOR_TRANSPORT_FAILED;
818 } else if (data_actlen > srb->datalen) {
ceb4972a
VG
819 debug("transferred %dB instead of %ldB\n",
820 data_actlen, srb->datalen);
149dded2 821 return USB_STOR_TRANSPORT_FAILED;
f5766139 822 } else if (csw->bCSWStatus == CSWSTATUS_FAILED) {
ceb4972a 823 debug("FAILED\n");
149dded2
WD
824 return USB_STOR_TRANSPORT_FAILED;
825 }
826
827 return result;
828}
829
b9560ad6 830static int usb_stor_CB_transport(struct scsi_cmd *srb, struct us_data *us)
affae2bf 831{
a0cb3fc3 832 int result, status;
b9560ad6
SG
833 struct scsi_cmd *psrb;
834 struct scsi_cmd reqsrb;
a0cb3fc3 835 int retry, notready;
affae2bf 836
d0ff51ba 837 psrb = &reqsrb;
a0cb3fc3
MT
838 status = USB_STOR_TRANSPORT_GOOD;
839 retry = 0;
840 notready = 0;
affae2bf
WD
841 /* issue the command */
842do_retry:
a0cb3fc3 843 result = usb_stor_CB_comdat(srb, us);
ceb4972a
VG
844 debug("command / Data returned %d, status %lX\n",
845 result, us->pusb_dev->status);
affae2bf 846 /* if this is an CBI Protocol, get IRQ */
a0cb3fc3
MT
847 if (us->protocol == US_PR_CBI) {
848 status = usb_stor_CBI_get_status(srb, us);
affae2bf 849 /* if the status is error, report it */
a0cb3fc3 850 if (status == USB_STOR_TRANSPORT_ERROR) {
ceb4972a 851 debug(" USB CBI Command Error\n");
affae2bf
WD
852 return status;
853 }
a0cb3fc3
MT
854 srb->sense_buf[12] = (unsigned char)(us->ip_data >> 8);
855 srb->sense_buf[13] = (unsigned char)(us->ip_data & 0xff);
856 if (!us->ip_data) {
857 /* if the status is good, report it */
858 if (status == USB_STOR_TRANSPORT_GOOD) {
ceb4972a 859 debug(" USB CBI Command Good\n");
affae2bf
WD
860 return status;
861 }
862 }
863 }
864 /* do we have to issue an auto request? */
865 /* HERE we have to check the result */
a0cb3fc3 866 if ((result < 0) && !(us->pusb_dev->status & USB_ST_STALLED)) {
ceb4972a 867 debug("ERROR %lX\n", us->pusb_dev->status);
affae2bf
WD
868 us->transport_reset(us);
869 return USB_STOR_TRANSPORT_ERROR;
870 }
a0cb3fc3
MT
871 if ((us->protocol == US_PR_CBI) &&
872 ((srb->cmd[0] == SCSI_REQ_SENSE) ||
873 (srb->cmd[0] == SCSI_INQUIRY))) {
874 /* do not issue an autorequest after request sense */
ceb4972a 875 debug("No auto request and good\n");
affae2bf
WD
876 return USB_STOR_TRANSPORT_GOOD;
877 }
878 /* issue an request_sense */
a0cb3fc3
MT
879 memset(&psrb->cmd[0], 0, 12);
880 psrb->cmd[0] = SCSI_REQ_SENSE;
881 psrb->cmd[1] = srb->lun << 5;
882 psrb->cmd[4] = 18;
883 psrb->datalen = 18;
d0ff51ba 884 psrb->pdata = &srb->sense_buf[0];
a0cb3fc3 885 psrb->cmdlen = 12;
affae2bf 886 /* issue the command */
a0cb3fc3 887 result = usb_stor_CB_comdat(psrb, us);
ceb4972a 888 debug("auto request returned %d\n", result);
affae2bf 889 /* if this is an CBI Protocol, get IRQ */
a0cb3fc3
MT
890 if (us->protocol == US_PR_CBI)
891 status = usb_stor_CBI_get_status(psrb, us);
892
893 if ((result < 0) && !(us->pusb_dev->status & USB_ST_STALLED)) {
ceb4972a
VG
894 debug(" AUTO REQUEST ERROR %ld\n",
895 us->pusb_dev->status);
affae2bf
WD
896 return USB_STOR_TRANSPORT_ERROR;
897 }
ceb4972a
VG
898 debug("autorequest returned 0x%02X 0x%02X 0x%02X 0x%02X\n",
899 srb->sense_buf[0], srb->sense_buf[2],
900 srb->sense_buf[12], srb->sense_buf[13]);
affae2bf 901 /* Check the auto request result */
a0cb3fc3
MT
902 if ((srb->sense_buf[2] == 0) &&
903 (srb->sense_buf[12] == 0) &&
904 (srb->sense_buf[13] == 0)) {
905 /* ok, no sense */
affae2bf 906 return USB_STOR_TRANSPORT_GOOD;
a0cb3fc3
MT
907 }
908
affae2bf 909 /* Check the auto request result */
a0cb3fc3
MT
910 switch (srb->sense_buf[2]) {
911 case 0x01:
912 /* Recovered Error */
149dded2 913 return USB_STOR_TRANSPORT_GOOD;
80885a9d 914 break;
a0cb3fc3
MT
915 case 0x02:
916 /* Not Ready */
917 if (notready++ > USB_TRANSPORT_NOT_READY_RETRY) {
918 printf("cmd 0x%02X returned 0x%02X 0x%02X 0x%02X"
919 " 0x%02X (NOT READY)\n", srb->cmd[0],
920 srb->sense_buf[0], srb->sense_buf[2],
921 srb->sense_buf[12], srb->sense_buf[13]);
149dded2
WD
922 return USB_STOR_TRANSPORT_FAILED;
923 } else {
5b84dd67 924 mdelay(100);
149dded2
WD
925 goto do_retry;
926 }
927 break;
928 default:
a0cb3fc3
MT
929 if (retry++ > USB_TRANSPORT_UNKNOWN_RETRY) {
930 printf("cmd 0x%02X returned 0x%02X 0x%02X 0x%02X"
931 " 0x%02X\n", srb->cmd[0], srb->sense_buf[0],
932 srb->sense_buf[2], srb->sense_buf[12],
933 srb->sense_buf[13]);
149dded2 934 return USB_STOR_TRANSPORT_FAILED;
a0cb3fc3 935 } else
149dded2 936 goto do_retry;
149dded2 937 break;
affae2bf
WD
938 }
939 return USB_STOR_TRANSPORT_FAILED;
940}
941
ea7fad91
BM
942static void usb_stor_set_max_xfer_blk(struct usb_device *udev,
943 struct us_data *us)
6158d0b4 944{
6158d0b4 945 /*
7d6fd7f0
MV
946 * Limit the total size of a transfer to 120 KB.
947 *
948 * Some devices are known to choke with anything larger. It seems like
949 * the problem stems from the fact that original IDE controllers had
950 * only an 8-bit register to hold the number of sectors in one transfer
951 * and even those couldn't handle a full 256 sectors.
952 *
953 * Because we want to make sure we interoperate with as many devices as
954 * possible, we will maintain a 240 sector transfer size limit for USB
955 * Mass Storage devices.
956 *
957 * Tests show that other operating have similar limits with Microsoft
958 * Windows 7 limiting transfers to 128 sectors for both USB2 and USB3
959 * and Apple Mac OS X 10.11 limiting transfers to 256 sectors for USB2
960 * and 2048 for USB3 devices.
6158d0b4 961 */
7d6fd7f0
MV
962 unsigned short blk = 240;
963
964#if CONFIG_IS_ENABLED(DM_USB)
965 size_t size;
966 int ret;
967
ea7fad91 968 ret = usb_get_max_xfer_size(udev, (size_t *)&size);
7d6fd7f0 969 if ((ret >= 0) && (size < blk * 512))
ea7fad91 970 blk = size / 512;
ea7fad91 971#endif
6158d0b4
BM
972
973 us->max_xfer_blk = blk;
974}
affae2bf 975
b9560ad6 976static int usb_inquiry(struct scsi_cmd *srb, struct us_data *ss)
affae2bf 977{
a0cb3fc3
MT
978 int retry, i;
979 retry = 5;
affae2bf 980 do {
a0cb3fc3
MT
981 memset(&srb->cmd[0], 0, 12);
982 srb->cmd[0] = SCSI_INQUIRY;
99e9ed1f 983 srb->cmd[1] = srb->lun << 5;
a0cb3fc3
MT
984 srb->cmd[4] = 36;
985 srb->datalen = 36;
986 srb->cmdlen = 12;
987 i = ss->transport(srb, ss);
ceb4972a 988 debug("inquiry returns %d\n", i);
a0cb3fc3 989 if (i == 0)
affae2bf 990 break;
fac71cc4 991 } while (--retry);
149dded2 992
a0cb3fc3 993 if (!retry) {
affae2bf
WD
994 printf("error in inquiry\n");
995 return -1;
996 }
997 return 0;
998}
999
b9560ad6 1000static int usb_request_sense(struct scsi_cmd *srb, struct us_data *ss)
affae2bf
WD
1001{
1002 char *ptr;
80885a9d 1003
a0cb3fc3
MT
1004 ptr = (char *)srb->pdata;
1005 memset(&srb->cmd[0], 0, 12);
1006 srb->cmd[0] = SCSI_REQ_SENSE;
99e9ed1f 1007 srb->cmd[1] = srb->lun << 5;
a0cb3fc3
MT
1008 srb->cmd[4] = 18;
1009 srb->datalen = 18;
d0ff51ba 1010 srb->pdata = &srb->sense_buf[0];
a0cb3fc3
MT
1011 srb->cmdlen = 12;
1012 ss->transport(srb, ss);
ceb4972a
VG
1013 debug("Request Sense returned %02X %02X %02X\n",
1014 srb->sense_buf[2], srb->sense_buf[12],
1015 srb->sense_buf[13]);
a0cb3fc3 1016 srb->pdata = (uchar *)ptr;
affae2bf
WD
1017 return 0;
1018}
1019
b9560ad6 1020static int usb_test_unit_ready(struct scsi_cmd *srb, struct us_data *ss)
affae2bf 1021{
9c998aa8 1022 int retries = 10;
149dded2 1023
affae2bf 1024 do {
a0cb3fc3
MT
1025 memset(&srb->cmd[0], 0, 12);
1026 srb->cmd[0] = SCSI_TST_U_RDY;
99e9ed1f 1027 srb->cmd[1] = srb->lun << 5;
a0cb3fc3
MT
1028 srb->datalen = 0;
1029 srb->cmdlen = 12;
3e8581bb
BT
1030 if (ss->transport(srb, ss) == USB_STOR_TRANSPORT_GOOD) {
1031 ss->flags |= USB_READY;
affae2bf 1032 return 0;
3e8581bb 1033 }
a0cb3fc3 1034 usb_request_sense(srb, ss);
8b57e2f0
VP
1035 /*
1036 * Check the Key Code Qualifier, if it matches
1037 * "Not Ready - medium not present"
1038 * (the sense Key equals 0x2 and the ASC is 0x3a)
1039 * return immediately as the medium being absent won't change
1040 * unless there is a user action.
1041 */
1042 if ((srb->sense_buf[2] == 0x02) &&
1043 (srb->sense_buf[12] == 0x3a))
1044 return -1;
5b84dd67 1045 mdelay(100);
a0cb3fc3 1046 } while (retries--);
149dded2 1047
affae2bf
WD
1048 return -1;
1049}
1050
b9560ad6 1051static int usb_read_capacity(struct scsi_cmd *srb, struct us_data *ss)
affae2bf
WD
1052{
1053 int retry;
a0cb3fc3
MT
1054 /* XXX retries */
1055 retry = 3;
affae2bf 1056 do {
a0cb3fc3
MT
1057 memset(&srb->cmd[0], 0, 12);
1058 srb->cmd[0] = SCSI_RD_CAPAC;
99e9ed1f 1059 srb->cmd[1] = srb->lun << 5;
a0cb3fc3
MT
1060 srb->datalen = 8;
1061 srb->cmdlen = 12;
1062 if (ss->transport(srb, ss) == USB_STOR_TRANSPORT_GOOD)
affae2bf 1063 return 0;
a0cb3fc3 1064 } while (retry--);
149dded2 1065
affae2bf
WD
1066 return -1;
1067}
1068
b9560ad6
SG
1069static int usb_read_10(struct scsi_cmd *srb, struct us_data *ss,
1070 unsigned long start, unsigned short blocks)
affae2bf 1071{
a0cb3fc3
MT
1072 memset(&srb->cmd[0], 0, 12);
1073 srb->cmd[0] = SCSI_READ10;
99e9ed1f 1074 srb->cmd[1] = srb->lun << 5;
a0cb3fc3
MT
1075 srb->cmd[2] = ((unsigned char) (start >> 24)) & 0xff;
1076 srb->cmd[3] = ((unsigned char) (start >> 16)) & 0xff;
1077 srb->cmd[4] = ((unsigned char) (start >> 8)) & 0xff;
1078 srb->cmd[5] = ((unsigned char) (start)) & 0xff;
1079 srb->cmd[7] = ((unsigned char) (blocks >> 8)) & 0xff;
1080 srb->cmd[8] = (unsigned char) blocks & 0xff;
1081 srb->cmdlen = 12;
ceb4972a 1082 debug("read10: start %lx blocks %x\n", start, blocks);
a0cb3fc3 1083 return ss->transport(srb, ss);
affae2bf
WD
1084}
1085
b9560ad6
SG
1086static int usb_write_10(struct scsi_cmd *srb, struct us_data *ss,
1087 unsigned long start, unsigned short blocks)
127e1084
MJ
1088{
1089 memset(&srb->cmd[0], 0, 12);
1090 srb->cmd[0] = SCSI_WRITE10;
99e9ed1f 1091 srb->cmd[1] = srb->lun << 5;
127e1084
MJ
1092 srb->cmd[2] = ((unsigned char) (start >> 24)) & 0xff;
1093 srb->cmd[3] = ((unsigned char) (start >> 16)) & 0xff;
1094 srb->cmd[4] = ((unsigned char) (start >> 8)) & 0xff;
1095 srb->cmd[5] = ((unsigned char) (start)) & 0xff;
1096 srb->cmd[7] = ((unsigned char) (blocks >> 8)) & 0xff;
1097 srb->cmd[8] = (unsigned char) blocks & 0xff;
1098 srb->cmdlen = 12;
ceb4972a 1099 debug("write10: start %lx blocks %x\n", start, blocks);
127e1084
MJ
1100 return ss->transport(srb, ss);
1101}
1102
affae2bf 1103
ddde6b7c
BS
1104#ifdef CONFIG_USB_BIN_FIXUP
1105/*
1106 * Some USB storage devices queried for SCSI identification data respond with
1107 * binary strings, which if output to the console freeze the terminal. The
1108 * workaround is to modify the vendor and product strings read from such
1109 * device with proper values (as reported by 'usb info').
1110 *
1111 * Vendor and product length limits are taken from the definition of
4101f687 1112 * struct blk_desc in include/part.h.
ddde6b7c
BS
1113 */
1114static void usb_bin_fixup(struct usb_device_descriptor descriptor,
1115 unsigned char vendor[],
1116 unsigned char product[]) {
1117 const unsigned char max_vendor_len = 40;
1118 const unsigned char max_product_len = 20;
1119 if (descriptor.idVendor == 0x0424 && descriptor.idProduct == 0x223a) {
a0cb3fc3
MT
1120 strncpy((char *)vendor, "SMSC", max_vendor_len);
1121 strncpy((char *)product, "Flash Media Cntrller",
1122 max_product_len);
ddde6b7c
BS
1123 }
1124}
1125#endif /* CONFIG_USB_BIN_FIXUP */
1126
1af9bfd3 1127#if CONFIG_IS_ENABLED(BLK)
07b2b78c
SG
1128static unsigned long usb_stor_read(struct udevice *dev, lbaint_t blknr,
1129 lbaint_t blkcnt, void *buffer)
1130#else
4101f687 1131static unsigned long usb_stor_read(struct blk_desc *block_dev, lbaint_t blknr,
7c4213f6 1132 lbaint_t blkcnt, void *buffer)
07b2b78c 1133#endif
affae2bf 1134{
e81e79ed
GB
1135 lbaint_t start, blks;
1136 uintptr_t buf_addr;
affae2bf 1137 unsigned short smallblks;
9807c3b7 1138 struct usb_device *udev;
5dd95cf9 1139 struct us_data *ss;
84073b6f 1140 int retry;
b9560ad6 1141 struct scsi_cmd *srb = &usb_ccb;
1af9bfd3 1142#if CONFIG_IS_ENABLED(BLK)
07b2b78c
SG
1143 struct blk_desc *block_dev;
1144#endif
f8d813e3
WD
1145
1146 if (blkcnt == 0)
1147 return 0;
a0cb3fc3 1148 /* Setup device */
1af9bfd3 1149#if CONFIG_IS_ENABLED(BLK)
caa4daa2 1150 block_dev = dev_get_uclass_plat(dev);
07b2b78c
SG
1151 udev = dev_get_parent_priv(dev_get_parent(dev));
1152 debug("\nusb_read: udev %d\n", block_dev->devnum);
1153#else
9807c3b7
SG
1154 debug("\nusb_read: udev %d\n", block_dev->devnum);
1155 udev = usb_dev_desc[block_dev->devnum].priv;
1156 if (!udev) {
84073b6f
SG
1157 debug("%s: No device\n", __func__);
1158 return 0;
affae2bf 1159 }
07b2b78c 1160#endif
9807c3b7 1161 ss = (struct us_data *)udev->privptr;
affae2bf
WD
1162
1163 usb_disable_asynch(1); /* asynch transfer not allowed */
31232de0 1164 usb_lock_async(udev, 1);
9807c3b7 1165 srb->lun = block_dev->lun;
f6570871 1166 buf_addr = (uintptr_t)buffer;
a0cb3fc3
MT
1167 start = blknr;
1168 blks = blkcnt;
a0cb3fc3 1169
dee37fc9
MY
1170 debug("\nusb_read: dev %d startblk " LBAF ", blccnt " LBAF " buffer %lx\n",
1171 block_dev->devnum, start, blks, buf_addr);
a0cb3fc3 1172
affae2bf 1173 do {
a0cb3fc3
MT
1174 /* XXX need some comment here */
1175 retry = 2;
1176 srb->pdata = (unsigned char *)buf_addr;
6158d0b4
BM
1177 if (blks > ss->max_xfer_blk)
1178 smallblks = ss->max_xfer_blk;
a0cb3fc3
MT
1179 else
1180 smallblks = (unsigned short) blks;
affae2bf 1181retry_it:
6158d0b4 1182 if (smallblks == ss->max_xfer_blk)
affae2bf 1183 usb_show_progress();
9807c3b7 1184 srb->datalen = block_dev->blksz * smallblks;
a0cb3fc3 1185 srb->pdata = (unsigned char *)buf_addr;
5dd95cf9 1186 if (usb_read_10(srb, ss, start, smallblks)) {
ceb4972a 1187 debug("Read ERROR\n");
da3d1c49 1188 ss->flags &= ~USB_READY;
5dd95cf9 1189 usb_request_sense(srb, ss);
a0cb3fc3 1190 if (retry--)
affae2bf 1191 goto retry_it;
a0cb3fc3 1192 blkcnt -= blks;
affae2bf
WD
1193 break;
1194 }
a0cb3fc3
MT
1195 start += smallblks;
1196 blks -= smallblks;
1197 buf_addr += srb->datalen;
1198 } while (blks != 0);
1199
dee37fc9 1200 debug("usb_read: end startblk " LBAF ", blccnt %x buffer %lx\n",
ceb4972a 1201 start, smallblks, buf_addr);
a0cb3fc3 1202
31232de0 1203 usb_lock_async(udev, 0);
affae2bf 1204 usb_disable_asynch(0); /* asynch transfer allowed */
6158d0b4 1205 if (blkcnt >= ss->max_xfer_blk)
226fa9bb 1206 debug("\n");
a0cb3fc3 1207 return blkcnt;
affae2bf
WD
1208}
1209
1af9bfd3 1210#if CONFIG_IS_ENABLED(BLK)
07b2b78c
SG
1211static unsigned long usb_stor_write(struct udevice *dev, lbaint_t blknr,
1212 lbaint_t blkcnt, const void *buffer)
1213#else
4101f687 1214static unsigned long usb_stor_write(struct blk_desc *block_dev, lbaint_t blknr,
7c4213f6 1215 lbaint_t blkcnt, const void *buffer)
07b2b78c 1216#endif
127e1084 1217{
e81e79ed
GB
1218 lbaint_t start, blks;
1219 uintptr_t buf_addr;
127e1084 1220 unsigned short smallblks;
9807c3b7 1221 struct usb_device *udev;
5dd95cf9 1222 struct us_data *ss;
84073b6f 1223 int retry;
b9560ad6 1224 struct scsi_cmd *srb = &usb_ccb;
1af9bfd3 1225#if CONFIG_IS_ENABLED(BLK)
07b2b78c
SG
1226 struct blk_desc *block_dev;
1227#endif
127e1084
MJ
1228
1229 if (blkcnt == 0)
1230 return 0;
1231
127e1084 1232 /* Setup device */
1af9bfd3 1233#if CONFIG_IS_ENABLED(BLK)
caa4daa2 1234 block_dev = dev_get_uclass_plat(dev);
07b2b78c
SG
1235 udev = dev_get_parent_priv(dev_get_parent(dev));
1236 debug("\nusb_read: udev %d\n", block_dev->devnum);
1237#else
9807c3b7
SG
1238 debug("\nusb_read: udev %d\n", block_dev->devnum);
1239 udev = usb_dev_desc[block_dev->devnum].priv;
1240 if (!udev) {
1241 debug("%s: No device\n", __func__);
84073b6f 1242 return 0;
9807c3b7 1243 }
07b2b78c 1244#endif
9807c3b7 1245 ss = (struct us_data *)udev->privptr;
127e1084
MJ
1246
1247 usb_disable_asynch(1); /* asynch transfer not allowed */
31232de0 1248 usb_lock_async(udev, 1);
127e1084 1249
9807c3b7 1250 srb->lun = block_dev->lun;
f6570871 1251 buf_addr = (uintptr_t)buffer;
127e1084
MJ
1252 start = blknr;
1253 blks = blkcnt;
127e1084 1254
dee37fc9
MY
1255 debug("\nusb_write: dev %d startblk " LBAF ", blccnt " LBAF " buffer %lx\n",
1256 block_dev->devnum, start, blks, buf_addr);
127e1084
MJ
1257
1258 do {
1259 /* If write fails retry for max retry count else
1260 * return with number of blocks written successfully.
1261 */
1262 retry = 2;
1263 srb->pdata = (unsigned char *)buf_addr;
6158d0b4
BM
1264 if (blks > ss->max_xfer_blk)
1265 smallblks = ss->max_xfer_blk;
127e1084
MJ
1266 else
1267 smallblks = (unsigned short) blks;
1268retry_it:
6158d0b4 1269 if (smallblks == ss->max_xfer_blk)
127e1084 1270 usb_show_progress();
9807c3b7 1271 srb->datalen = block_dev->blksz * smallblks;
127e1084 1272 srb->pdata = (unsigned char *)buf_addr;
5dd95cf9 1273 if (usb_write_10(srb, ss, start, smallblks)) {
ceb4972a 1274 debug("Write ERROR\n");
da3d1c49 1275 ss->flags &= ~USB_READY;
5dd95cf9 1276 usb_request_sense(srb, ss);
127e1084
MJ
1277 if (retry--)
1278 goto retry_it;
1279 blkcnt -= blks;
1280 break;
1281 }
1282 start += smallblks;
1283 blks -= smallblks;
1284 buf_addr += srb->datalen;
1285 } while (blks != 0);
1286
dee37fc9
MY
1287 debug("usb_write: end startblk " LBAF ", blccnt %x buffer %lx\n",
1288 start, smallblks, buf_addr);
127e1084 1289
31232de0 1290 usb_lock_async(udev, 0);
127e1084 1291 usb_disable_asynch(0); /* asynch transfer allowed */
6158d0b4 1292 if (blkcnt >= ss->max_xfer_blk)
226fa9bb 1293 debug("\n");
127e1084
MJ
1294 return blkcnt;
1295
1296}
affae2bf
WD
1297
1298/* Probe to see if a new device is actually a Storage device */
a0cb3fc3
MT
1299int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,
1300 struct us_data *ss)
affae2bf 1301{
8f8bd565 1302 struct usb_interface *iface;
affae2bf 1303 int i;
605bd75a 1304 struct usb_endpoint_descriptor *ep_desc;
affae2bf
WD
1305 unsigned int flags = 0;
1306
affae2bf
WD
1307 /* let's examine the device now */
1308 iface = &dev->config.if_desc[ifnum];
1309
affae2bf 1310 if (dev->descriptor.bDeviceClass != 0 ||
8f8bd565
TR
1311 iface->desc.bInterfaceClass != USB_CLASS_MASS_STORAGE ||
1312 iface->desc.bInterfaceSubClass < US_SC_MIN ||
1313 iface->desc.bInterfaceSubClass > US_SC_MAX) {
1d5827a1 1314 debug("Not mass storage\n");
affae2bf
WD
1315 /* if it's not a mass storage, we go no further */
1316 return 0;
1317 }
1318
9c998aa8
WD
1319 memset(ss, 0, sizeof(struct us_data));
1320
affae2bf 1321 /* At this point, we know we've got a live one */
ceb4972a 1322 debug("\n\nUSB Mass Storage device detected\n");
affae2bf
WD
1323
1324 /* Initialize the us_data structure with some useful info */
1325 ss->flags = flags;
1326 ss->ifnum = ifnum;
1327 ss->pusb_dev = dev;
1328 ss->attention_done = 0;
f5fb78a2
TR
1329 ss->subclass = iface->desc.bInterfaceSubClass;
1330 ss->protocol = iface->desc.bInterfaceProtocol;
affae2bf
WD
1331
1332 /* set the handler pointers based on the protocol */
ceb4972a 1333 debug("Transport: ");
affae2bf
WD
1334 switch (ss->protocol) {
1335 case US_PR_CB:
ceb4972a 1336 debug("Control/Bulk\n");
affae2bf
WD
1337 ss->transport = usb_stor_CB_transport;
1338 ss->transport_reset = usb_stor_CB_reset;
1339 break;
1340
1341 case US_PR_CBI:
ceb4972a 1342 debug("Control/Bulk/Interrupt\n");
affae2bf
WD
1343 ss->transport = usb_stor_CB_transport;
1344 ss->transport_reset = usb_stor_CB_reset;
1345 break;
149dded2 1346 case US_PR_BULK:
ceb4972a 1347 debug("Bulk/Bulk/Bulk\n");
149dded2
WD
1348 ss->transport = usb_stor_BBB_transport;
1349 ss->transport_reset = usb_stor_BBB_reset;
1350 break;
affae2bf 1351 default:
80885a9d 1352 printf("USB Storage Transport unknown / not yet implemented\n");
affae2bf
WD
1353 return 0;
1354 break;
1355 }
1356
1357 /*
1358 * We are expecting a minimum of 2 endpoints - in and out (bulk).
1359 * An optional interrupt is OK (necessary for CBI protocol).
1360 * We will ignore any others.
1361 */
8f8bd565 1362 for (i = 0; i < iface->desc.bNumEndpoints; i++) {
605bd75a 1363 ep_desc = &iface->ep_desc[i];
affae2bf 1364 /* is it an BULK endpoint? */
605bd75a 1365 if ((ep_desc->bmAttributes &
a0cb3fc3 1366 USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) {
605bd75a
VG
1367 if (ep_desc->bEndpointAddress & USB_DIR_IN)
1368 ss->ep_in = ep_desc->bEndpointAddress &
1369 USB_ENDPOINT_NUMBER_MASK;
affae2bf 1370 else
a0cb3fc3 1371 ss->ep_out =
605bd75a 1372 ep_desc->bEndpointAddress &
affae2bf
WD
1373 USB_ENDPOINT_NUMBER_MASK;
1374 }
1375
1376 /* is it an interrupt endpoint? */
605bd75a
VG
1377 if ((ep_desc->bmAttributes &
1378 USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) {
1379 ss->ep_int = ep_desc->bEndpointAddress &
1380 USB_ENDPOINT_NUMBER_MASK;
1381 ss->irqinterval = ep_desc->bInterval;
affae2bf
WD
1382 }
1383 }
ceb4972a
VG
1384 debug("Endpoints In %d Out %d Int %d\n",
1385 ss->ep_in, ss->ep_out, ss->ep_int);
affae2bf
WD
1386
1387 /* Do some basic sanity checks, and bail if we find a problem */
8f8bd565 1388 if (usb_set_interface(dev, iface->desc.bInterfaceNumber, 0) ||
affae2bf
WD
1389 !ss->ep_in || !ss->ep_out ||
1390 (ss->protocol == US_PR_CBI && ss->ep_int == 0)) {
ceb4972a 1391 debug("Problems with device\n");
affae2bf
WD
1392 return 0;
1393 }
1394 /* set class specific stuff */
149dded2
WD
1395 /* We only handle certain protocols. Currently, these are
1396 * the only ones.
80885a9d 1397 * The SFF8070 accepts the requests used in u-boot
affae2bf 1398 */
80885a9d
WD
1399 if (ss->subclass != US_SC_UFI && ss->subclass != US_SC_SCSI &&
1400 ss->subclass != US_SC_8070) {
a0cb3fc3 1401 printf("Sorry, protocol %d not yet supported.\n", ss->subclass);
affae2bf
WD
1402 return 0;
1403 }
a0cb3fc3
MT
1404 if (ss->ep_int) {
1405 /* we had found an interrupt endpoint, prepare irq pipe
1406 * set up the IRQ pipe and handler
1407 */
affae2bf
WD
1408 ss->irqinterval = (ss->irqinterval > 0) ? ss->irqinterval : 255;
1409 ss->irqpipe = usb_rcvintpipe(ss->pusb_dev, ss->ep_int);
1410 ss->irqmaxp = usb_maxpacket(dev, ss->irqpipe);
a0cb3fc3 1411 dev->irq_handle = usb_stor_irq;
affae2bf 1412 }
6158d0b4
BM
1413
1414 /* Set the maximum transfer size per host controller setting */
ea7fad91 1415 usb_stor_set_max_xfer_blk(dev, ss);
6158d0b4 1416
a0cb3fc3 1417 dev->privptr = (void *)ss;
affae2bf
WD
1418 return 1;
1419}
1420
a0cb3fc3 1421int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
4101f687 1422 struct blk_desc *dev_desc)
affae2bf 1423{
a0cb3fc3 1424 unsigned char perq, modi;
f6570871
ST
1425 ALLOC_CACHE_ALIGN_BUFFER(u32, cap, 2);
1426 ALLOC_CACHE_ALIGN_BUFFER(u8, usb_stor_buf, 36);
1427 u32 capacity, blksz;
b9560ad6 1428 struct scsi_cmd *pccb = &usb_ccb;
9c998aa8 1429
9c998aa8
WD
1430 pccb->pdata = usb_stor_buf;
1431
1432 dev_desc->target = dev->devnum;
1433 pccb->lun = dev_desc->lun;
ceb4972a 1434 debug(" address %d\n", dev_desc->target);
affae2bf 1435
1d5827a1
SG
1436 if (usb_inquiry(pccb, ss)) {
1437 debug("%s: usb_inquiry() failed\n", __func__);
affae2bf 1438 return -1;
1d5827a1 1439 }
095b8a37 1440
9c998aa8
WD
1441 perq = usb_stor_buf[0];
1442 modi = usb_stor_buf[1];
a0cb3fc3 1443
6a559bbe
SM
1444 /*
1445 * Skip unknown devices (0x1f) and enclosure service devices (0x0d),
1446 * they would not respond to test_unit_ready .
1447 */
1448 if (((perq & 0x1f) == 0x1f) || ((perq & 0x1f) == 0x0d)) {
1d5827a1 1449 debug("%s: unknown/unsupported device\n", __func__);
a0cb3fc3 1450 return 0;
affae2bf 1451 }
a0cb3fc3
MT
1452 if ((modi&0x80) == 0x80) {
1453 /* drive is removable */
9c998aa8 1454 dev_desc->removable = 1;
affae2bf 1455 }
f6570871
ST
1456 memcpy(dev_desc->vendor, (const void *)&usb_stor_buf[8], 8);
1457 memcpy(dev_desc->product, (const void *)&usb_stor_buf[16], 16);
1458 memcpy(dev_desc->revision, (const void *)&usb_stor_buf[32], 4);
9c998aa8
WD
1459 dev_desc->vendor[8] = 0;
1460 dev_desc->product[16] = 0;
1461 dev_desc->revision[4] = 0;
ddde6b7c 1462#ifdef CONFIG_USB_BIN_FIXUP
a0cb3fc3
MT
1463 usb_bin_fixup(dev->descriptor, (uchar *)dev_desc->vendor,
1464 (uchar *)dev_desc->product);
ddde6b7c 1465#endif /* CONFIG_USB_BIN_FIXUP */
ceb4972a
VG
1466 debug("ISO Vers %X, Response Data %X\n", usb_stor_buf[2],
1467 usb_stor_buf[3]);
a0cb3fc3
MT
1468 if (usb_test_unit_ready(pccb, ss)) {
1469 printf("Device NOT ready\n"
1470 " Request Sense returned %02X %02X %02X\n",
1471 pccb->sense_buf[2], pccb->sense_buf[12],
1472 pccb->sense_buf[13]);
1e5eca7d 1473 if (dev_desc->removable == 1)
9c998aa8 1474 dev_desc->type = perq;
a0cb3fc3 1475 return 0;
affae2bf 1476 }
f6570871 1477 pccb->pdata = (unsigned char *)cap;
a0cb3fc3
MT
1478 memset(pccb->pdata, 0, 8);
1479 if (usb_read_capacity(pccb, ss) != 0) {
affae2bf 1480 printf("READ_CAP ERROR\n");
da3d1c49 1481 ss->flags &= ~USB_READY;
9c998aa8
WD
1482 cap[0] = 2880;
1483 cap[1] = 0x200;
affae2bf 1484 }
f6570871 1485 debug("Read Capacity returns: 0x%08x, 0x%08x\n", cap[0], cap[1]);
affae2bf 1486#if 0
a0cb3fc3
MT
1487 if (cap[0] > (0x200000 * 10)) /* greater than 10 GByte */
1488 cap[0] >>= 16;
f6570871 1489
c918261c
CE
1490 cap[0] = cpu_to_be32(cap[0]);
1491 cap[1] = cpu_to_be32(cap[1]);
f6570871
ST
1492#endif
1493
1494 capacity = be32_to_cpu(cap[0]) + 1;
1495 blksz = be32_to_cpu(cap[1]);
c918261c 1496
f6570871
ST
1497 debug("Capacity = 0x%08x, blocksz = 0x%08x\n", capacity, blksz);
1498 dev_desc->lba = capacity;
1499 dev_desc->blksz = blksz;
0472fbfd 1500 dev_desc->log2blksz = LOG2(dev_desc->blksz);
9c998aa8 1501 dev_desc->type = perq;
ceb4972a 1502 debug(" address %d\n", dev_desc->target);
affae2bf 1503
affae2bf
WD
1504 return 1;
1505}
acf277af 1506
fd09c205 1507#if CONFIG_IS_ENABLED(DM_USB)
acf277af
SG
1508
1509static int usb_mass_storage_probe(struct udevice *dev)
1510{
bcbe3d15 1511 struct usb_device *udev = dev_get_parent_priv(dev);
acf277af
SG
1512 int ret;
1513
1514 usb_disable_asynch(1); /* asynch transfer not allowed */
1515 ret = usb_stor_probe_device(udev);
1516 usb_disable_asynch(0); /* asynch transfer allowed */
1517
1518 return ret;
1519}
1520
1521static const struct udevice_id usb_mass_storage_ids[] = {
1522 { .compatible = "usb-mass-storage" },
1523 { }
1524};
1525
1526U_BOOT_DRIVER(usb_mass_storage) = {
1527 .name = "usb_mass_storage",
1528 .id = UCLASS_MASS_STORAGE,
1529 .of_match = usb_mass_storage_ids,
1530 .probe = usb_mass_storage_probe,
1af9bfd3 1531#if CONFIG_IS_ENABLED(BLK)
caa4daa2 1532 .plat_auto = sizeof(struct us_data),
07b2b78c 1533#endif
acf277af
SG
1534};
1535
1536UCLASS_DRIVER(usb_mass_storage) = {
1537 .id = UCLASS_MASS_STORAGE,
1538 .name = "usb_mass_storage",
1539};
1540
1541static const struct usb_device_id mass_storage_id_table[] = {
1542 {
1543 .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
1544 .bInterfaceClass = USB_CLASS_MASS_STORAGE
1545 },
1546 { } /* Terminating entry */
1547};
1548
abb59cff 1549U_BOOT_USB_DEVICE(usb_mass_storage, mass_storage_id_table);
07b2b78c 1550#endif
acf277af 1551
1af9bfd3 1552#if CONFIG_IS_ENABLED(BLK)
07b2b78c
SG
1553static const struct blk_ops usb_storage_ops = {
1554 .read = usb_stor_read,
1555 .write = usb_stor_write,
1556};
1557
1558U_BOOT_DRIVER(usb_storage_blk) = {
1559 .name = "usb_storage_blk",
1560 .id = UCLASS_BLK,
1561 .ops = &usb_storage_ops,
1562};
c0543bf6
SG
1563#else
1564U_BOOT_LEGACY_BLK(usb) = {
1565 .if_typename = "usb",
1566 .if_type = IF_TYPE_USB,
1567 .max_devs = USB_MAX_STOR_DEV,
1568 .desc = usb_dev_desc,
1569};
acf277af 1570#endif
This page took 0.773181 seconds and 4 git commands to generate.