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