]> git.ipfire.org Git - people/ms/u-boot.git/blame - common/usb_storage.c
rockchip: rk3288: Fix wrong TPL_TEXT_BASE
[people/ms/u-boot.git] / common / usb_storage.c
CommitLineData
affae2bf 1/*
460c322f
WD
2 * Most of this source has been derived from the Linux USB
3 * project:
4 * (c) 1999-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
5 * (c) 2000 David L. Brown, Jr. (usb-storage@davidb.org)
6 * (c) 1999 Michael Gee (michael@linuxspecific.com)
7 * (c) 2000 Yggdrasil Computing, Inc.
8 *
9 *
10 * Adapted for U-Boot:
11 * (C) Copyright 2001 Denis Peter, MPL AG Switzerland
acf277af
SG
12 * Driver model conversion:
13 * (C) Copyright 2015 Google, Inc
affae2bf 14 *
149dded2 15 * For BBB support (C) Copyright 2003
792a09eb 16 * Gary Jennejohn, DENX Software Engineering <garyj@denx.de>
149dded2 17 *
460c322f 18 * BBB support based on /sys/dev/usb/umass.c from
149dded2 19 * FreeBSD.
affae2bf 20 *
1a459660 21 * SPDX-License-Identifier: GPL-2.0+
affae2bf
WD
22 */
23
24/* Note:
25 * Currently only the CBI transport protocoll has been implemented, and it
26 * is only tested with a TEAC USB Floppy. Other Massstorages with CBI or CB
27 * transport protocoll may work as well.
28 */
149dded2
WD
29/*
30 * New Note:
31 * Support for USB Mass Storage Devices (BBB) has been added. It has
32 * only been tested with USB memory sticks.
149dded2 33 */
affae2bf
WD
34
35
affae2bf
WD
36#include <common.h>
37#include <command.h>
acf277af 38#include <dm.h>
91557579 39#include <errno.h>
4fd074de 40#include <inttypes.h>
05108132 41#include <mapmem.h>
cf92e05c 42#include <memalign.h>
c918261c 43#include <asm/byteorder.h>
affae2bf 44#include <asm/processor.h>
acf277af 45#include <dm/device-internal.h>
07b2b78c 46#include <dm/lists.h>
affae2bf 47
735dd97b 48#include <part.h>
affae2bf
WD
49#include <usb.h>
50
80885a9d
WD
51#undef BBB_COMDAT_TRACE
52#undef BBB_XPORT_TRACE
affae2bf 53
affae2bf
WD
54#include <scsi.h>
55/* direction table -- this indicates the direction of the data
56 * transfer for each command code -- a 1 indicates input
57 */
2ff12285 58static const unsigned char us_direction[256/8] = {
affae2bf
WD
59 0x28, 0x81, 0x14, 0x14, 0x20, 0x01, 0x90, 0x77,
60 0x0C, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
61 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01,
62 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
63};
64#define US_DIRECTION(x) ((us_direction[x>>3] >> (x & 7)) & 1)
65
b9560ad6 66static struct scsi_cmd usb_ccb __aligned(ARCH_DMA_MINALIGN);
a0cb3fc3 67static __u32 CBWTag;
149dded2 68
a0cb3fc3 69static int usb_max_devs; /* number of highest available usb device */
affae2bf 70
07b2b78c 71#ifndef CONFIG_BLK
4101f687 72static struct blk_desc usb_dev_desc[USB_MAX_STOR_DEV];
07b2b78c 73#endif
affae2bf
WD
74
75struct us_data;
b9560ad6 76typedef int (*trans_cmnd)(struct scsi_cmd *cb, struct us_data *data);
a0cb3fc3 77typedef int (*trans_reset)(struct us_data *data);
affae2bf
WD
78
79struct us_data {
a0cb3fc3
MT
80 struct usb_device *pusb_dev; /* this usb_device */
81
82 unsigned int flags; /* from filter initially */
3e8581bb 83# define USB_READY (1 << 0)
a0cb3fc3
MT
84 unsigned char ifnum; /* interface number */
85 unsigned char ep_in; /* in endpoint */
86 unsigned char ep_out; /* out ....... */
87 unsigned char ep_int; /* interrupt . */
88 unsigned char subclass; /* as in overview */
89 unsigned char protocol; /* .............. */
90 unsigned char attention_done; /* force attn on first cmd */
91 unsigned short ip_data; /* interrupt data */
92 int action; /* what to do */
93 int ip_wanted; /* needed */
94 int *irq_handle; /* for USB int requests */
95 unsigned int irqpipe; /* pipe for release_irq */
96 unsigned char irqmaxp; /* max packed for irq Pipe */
97 unsigned char irqinterval; /* Intervall for IRQ Pipe */
b9560ad6 98 struct scsi_cmd *srb; /* current srb */
a0cb3fc3
MT
99 trans_reset transport_reset; /* reset routine */
100 trans_cmnd transport; /* transport routine */
6158d0b4 101 unsigned short max_xfer_blk; /* maximum transfer blocks */
affae2bf
WD
102};
103
07b2b78c 104#ifndef CONFIG_BLK
affae2bf 105static struct us_data usb_stor[USB_MAX_STOR_DEV];
07b2b78c 106#endif
affae2bf 107
80885a9d 108#define USB_STOR_TRANSPORT_GOOD 0
affae2bf
WD
109#define USB_STOR_TRANSPORT_FAILED -1
110#define USB_STOR_TRANSPORT_ERROR -2
111
a0cb3fc3 112int usb_stor_get_info(struct usb_device *dev, struct us_data *us,
4101f687 113 struct blk_desc *dev_desc);
a0cb3fc3
MT
114int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,
115 struct us_data *ss);
07b2b78c
SG
116#ifdef CONFIG_BLK
117static unsigned long usb_stor_read(struct udevice *dev, lbaint_t blknr,
118 lbaint_t blkcnt, void *buffer);
119static unsigned long usb_stor_write(struct udevice *dev, lbaint_t blknr,
120 lbaint_t blkcnt, const void *buffer);
121#else
4101f687 122static unsigned long usb_stor_read(struct blk_desc *block_dev, lbaint_t blknr,
7c4213f6 123 lbaint_t blkcnt, void *buffer);
4101f687 124static unsigned long usb_stor_write(struct blk_desc *block_dev, lbaint_t blknr,
7c4213f6 125 lbaint_t blkcnt, const void *buffer);
07b2b78c 126#endif
affae2bf
WD
127void uhci_show_temp_int_td(void);
128
199adb60 129static void usb_show_progress(void)
affae2bf 130{
226fa9bb 131 debug(".");
affae2bf
WD
132}
133
a0cb3fc3 134/*******************************************************************************
9c998aa8
WD
135 * show info on storage devices; 'usb start/init' must be invoked earlier
136 * as we only retrieve structures populated during devices initialization
137 */
f6b44e0e 138int usb_stor_info(void)
9c998aa8 139{
9807c3b7 140 int count = 0;
07b2b78c
SG
141#ifdef CONFIG_BLK
142 struct udevice *dev;
143
144 for (blk_first_device(IF_TYPE_USB, &dev);
145 dev;
146 blk_next_device(&dev)) {
147 struct blk_desc *desc = dev_get_uclass_platdata(dev);
148
149 printf(" Device %d: ", desc->devnum);
150 dev_print(desc);
151 count++;
152 }
153#else
9c998aa8
WD
154 int i;
155
f6b44e0e 156 if (usb_max_devs > 0) {
9c998aa8 157 for (i = 0; i < usb_max_devs; i++) {
a0cb3fc3 158 printf(" Device %d: ", i);
9c998aa8
WD
159 dev_print(&usb_dev_desc[i]);
160 }
b9e749e9 161 return 0;
f6b44e0e 162 }
07b2b78c 163#endif
9807c3b7
SG
164 if (!count) {
165 printf("No storage devices, perhaps not 'usb start'ed..?\n");
166 return 1;
167 }
168
b94fc851 169 return 0;
9c998aa8
WD
170}
171
99e9ed1f
LC
172static unsigned int usb_get_max_lun(struct us_data *us)
173{
174 int len;
f5766139 175 ALLOC_CACHE_ALIGN_BUFFER(unsigned char, result, 1);
99e9ed1f
LC
176 len = usb_control_msg(us->pusb_dev,
177 usb_rcvctrlpipe(us->pusb_dev, 0),
178 US_BBB_GET_MAX_LUN,
179 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
180 0, us->ifnum,
f5766139 181 result, sizeof(char),
99e9ed1f 182 USB_CNTL_TIMEOUT * 5);
ceb4972a 183 debug("Get Max LUN -> len = %i, result = %i\n", len, (int) *result);
f5766139 184 return (len > 0) ? *result : 0;
99e9ed1f
LC
185}
186
9807c3b7 187static int usb_stor_probe_device(struct usb_device *udev)
91557579 188{
9807c3b7 189 int lun, max_lun;
07b2b78c
SG
190
191#ifdef CONFIG_BLK
192 struct us_data *data;
07b2b78c
SG
193 int ret;
194#else
9807c3b7
SG
195 int start;
196
197 if (udev == NULL)
91557579 198 return -ENOENT; /* no more devices available */
07b2b78c
SG
199#endif
200
201 debug("\n\nProbing for storage\n");
202#ifdef CONFIG_BLK
203 /*
204 * We store the us_data in the mass storage device's platdata. It
205 * is shared by all LUNs (block devices) attached to this mass storage
206 * device.
207 */
208 data = dev_get_platdata(udev->dev);
209 if (!usb_storage_probe(udev, 0, data))
210 return 0;
211 max_lun = usb_get_max_lun(data);
212 for (lun = 0; lun <= max_lun; lun++) {
213 struct blk_desc *blkdev;
214 struct udevice *dev;
9107c973 215 char str[10];
07b2b78c 216
9107c973
SG
217 snprintf(str, sizeof(str), "lun%d", lun);
218 ret = blk_create_devicef(udev->dev, "usb_storage_blk", str,
219 IF_TYPE_USB, usb_max_devs, 512, 0,
220 &dev);
07b2b78c
SG
221 if (ret) {
222 debug("Cannot bind driver\n");
223 return ret;
224 }
225
226 blkdev = dev_get_uclass_platdata(dev);
227 blkdev->target = 0xff;
228 blkdev->lun = lun;
91557579 229
07b2b78c
SG
230 ret = usb_stor_get_info(udev, data, blkdev);
231 if (ret == 1)
232 ret = blk_prepare_device(dev);
233 if (!ret) {
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
b984700c
MS
306#ifndef CONFIG_DM_USB
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 */
ceb4972a
VG
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;
a0cb3fc3 657 submit_int_msg(us->pusb_dev, us->irqpipe,
80885a9d
WD
658 (void *) &us->ip_data, us->irqmaxp, us->irqinterval);
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
BM
944{
945 unsigned short blk;
ea7fad91
BM
946 size_t __maybe_unused size;
947 int __maybe_unused ret;
6158d0b4 948
ea7fad91 949#ifndef CONFIG_DM_USB
6158d0b4
BM
950#ifdef CONFIG_USB_EHCI_HCD
951 /*
952 * The U-Boot EHCI driver can handle any transfer length as long as
953 * there is enough free heap space left, but the SCSI READ(10) and
954 * WRITE(10) commands are limited to 65535 blocks.
955 */
956 blk = USHRT_MAX;
957#else
958 blk = 20;
959#endif
ea7fad91
BM
960#else
961 ret = usb_get_max_xfer_size(udev, (size_t *)&size);
962 if (ret < 0) {
963 /* unimplemented, let's use default 20 */
964 blk = 20;
965 } else {
966 if (size > USHRT_MAX * 512)
72ac8f3f 967 size = USHRT_MAX * 512;
ea7fad91
BM
968 blk = size / 512;
969 }
970#endif
6158d0b4
BM
971
972 us->max_xfer_blk = blk;
973}
affae2bf 974
b9560ad6 975static int usb_inquiry(struct scsi_cmd *srb, struct us_data *ss)
affae2bf 976{
a0cb3fc3
MT
977 int retry, i;
978 retry = 5;
affae2bf 979 do {
a0cb3fc3
MT
980 memset(&srb->cmd[0], 0, 12);
981 srb->cmd[0] = SCSI_INQUIRY;
99e9ed1f 982 srb->cmd[1] = srb->lun << 5;
a0cb3fc3
MT
983 srb->cmd[4] = 36;
984 srb->datalen = 36;
985 srb->cmdlen = 12;
986 i = ss->transport(srb, ss);
ceb4972a 987 debug("inquiry returns %d\n", i);
a0cb3fc3 988 if (i == 0)
affae2bf 989 break;
fac71cc4 990 } while (--retry);
149dded2 991
a0cb3fc3 992 if (!retry) {
affae2bf
WD
993 printf("error in inquiry\n");
994 return -1;
995 }
996 return 0;
997}
998
b9560ad6 999static int usb_request_sense(struct scsi_cmd *srb, struct us_data *ss)
affae2bf
WD
1000{
1001 char *ptr;
80885a9d 1002
a0cb3fc3
MT
1003 ptr = (char *)srb->pdata;
1004 memset(&srb->cmd[0], 0, 12);
1005 srb->cmd[0] = SCSI_REQ_SENSE;
99e9ed1f 1006 srb->cmd[1] = srb->lun << 5;
a0cb3fc3
MT
1007 srb->cmd[4] = 18;
1008 srb->datalen = 18;
d0ff51ba 1009 srb->pdata = &srb->sense_buf[0];
a0cb3fc3
MT
1010 srb->cmdlen = 12;
1011 ss->transport(srb, ss);
ceb4972a
VG
1012 debug("Request Sense returned %02X %02X %02X\n",
1013 srb->sense_buf[2], srb->sense_buf[12],
1014 srb->sense_buf[13]);
a0cb3fc3 1015 srb->pdata = (uchar *)ptr;
affae2bf
WD
1016 return 0;
1017}
1018
b9560ad6 1019static int usb_test_unit_ready(struct scsi_cmd *srb, struct us_data *ss)
affae2bf 1020{
9c998aa8 1021 int retries = 10;
149dded2 1022
affae2bf 1023 do {
a0cb3fc3
MT
1024 memset(&srb->cmd[0], 0, 12);
1025 srb->cmd[0] = SCSI_TST_U_RDY;
99e9ed1f 1026 srb->cmd[1] = srb->lun << 5;
a0cb3fc3
MT
1027 srb->datalen = 0;
1028 srb->cmdlen = 12;
3e8581bb
BT
1029 if (ss->transport(srb, ss) == USB_STOR_TRANSPORT_GOOD) {
1030 ss->flags |= USB_READY;
affae2bf 1031 return 0;
3e8581bb 1032 }
a0cb3fc3 1033 usb_request_sense(srb, ss);
8b57e2f0
VP
1034 /*
1035 * Check the Key Code Qualifier, if it matches
1036 * "Not Ready - medium not present"
1037 * (the sense Key equals 0x2 and the ASC is 0x3a)
1038 * return immediately as the medium being absent won't change
1039 * unless there is a user action.
1040 */
1041 if ((srb->sense_buf[2] == 0x02) &&
1042 (srb->sense_buf[12] == 0x3a))
1043 return -1;
5b84dd67 1044 mdelay(100);
a0cb3fc3 1045 } while (retries--);
149dded2 1046
affae2bf
WD
1047 return -1;
1048}
1049
b9560ad6 1050static int usb_read_capacity(struct scsi_cmd *srb, struct us_data *ss)
affae2bf
WD
1051{
1052 int retry;
a0cb3fc3
MT
1053 /* XXX retries */
1054 retry = 3;
affae2bf 1055 do {
a0cb3fc3
MT
1056 memset(&srb->cmd[0], 0, 12);
1057 srb->cmd[0] = SCSI_RD_CAPAC;
99e9ed1f 1058 srb->cmd[1] = srb->lun << 5;
a0cb3fc3
MT
1059 srb->datalen = 8;
1060 srb->cmdlen = 12;
1061 if (ss->transport(srb, ss) == USB_STOR_TRANSPORT_GOOD)
affae2bf 1062 return 0;
a0cb3fc3 1063 } while (retry--);
149dded2 1064
affae2bf
WD
1065 return -1;
1066}
1067
b9560ad6
SG
1068static int usb_read_10(struct scsi_cmd *srb, struct us_data *ss,
1069 unsigned long start, unsigned short blocks)
affae2bf 1070{
a0cb3fc3
MT
1071 memset(&srb->cmd[0], 0, 12);
1072 srb->cmd[0] = SCSI_READ10;
99e9ed1f 1073 srb->cmd[1] = srb->lun << 5;
a0cb3fc3
MT
1074 srb->cmd[2] = ((unsigned char) (start >> 24)) & 0xff;
1075 srb->cmd[3] = ((unsigned char) (start >> 16)) & 0xff;
1076 srb->cmd[4] = ((unsigned char) (start >> 8)) & 0xff;
1077 srb->cmd[5] = ((unsigned char) (start)) & 0xff;
1078 srb->cmd[7] = ((unsigned char) (blocks >> 8)) & 0xff;
1079 srb->cmd[8] = (unsigned char) blocks & 0xff;
1080 srb->cmdlen = 12;
ceb4972a 1081 debug("read10: start %lx blocks %x\n", start, blocks);
a0cb3fc3 1082 return ss->transport(srb, ss);
affae2bf
WD
1083}
1084
b9560ad6
SG
1085static int usb_write_10(struct scsi_cmd *srb, struct us_data *ss,
1086 unsigned long start, unsigned short blocks)
127e1084
MJ
1087{
1088 memset(&srb->cmd[0], 0, 12);
1089 srb->cmd[0] = SCSI_WRITE10;
99e9ed1f 1090 srb->cmd[1] = srb->lun << 5;
127e1084
MJ
1091 srb->cmd[2] = ((unsigned char) (start >> 24)) & 0xff;
1092 srb->cmd[3] = ((unsigned char) (start >> 16)) & 0xff;
1093 srb->cmd[4] = ((unsigned char) (start >> 8)) & 0xff;
1094 srb->cmd[5] = ((unsigned char) (start)) & 0xff;
1095 srb->cmd[7] = ((unsigned char) (blocks >> 8)) & 0xff;
1096 srb->cmd[8] = (unsigned char) blocks & 0xff;
1097 srb->cmdlen = 12;
ceb4972a 1098 debug("write10: start %lx blocks %x\n", start, blocks);
127e1084
MJ
1099 return ss->transport(srb, ss);
1100}
1101
affae2bf 1102
ddde6b7c
BS
1103#ifdef CONFIG_USB_BIN_FIXUP
1104/*
1105 * Some USB storage devices queried for SCSI identification data respond with
1106 * binary strings, which if output to the console freeze the terminal. The
1107 * workaround is to modify the vendor and product strings read from such
1108 * device with proper values (as reported by 'usb info').
1109 *
1110 * Vendor and product length limits are taken from the definition of
4101f687 1111 * struct blk_desc in include/part.h.
ddde6b7c
BS
1112 */
1113static void usb_bin_fixup(struct usb_device_descriptor descriptor,
1114 unsigned char vendor[],
1115 unsigned char product[]) {
1116 const unsigned char max_vendor_len = 40;
1117 const unsigned char max_product_len = 20;
1118 if (descriptor.idVendor == 0x0424 && descriptor.idProduct == 0x223a) {
a0cb3fc3
MT
1119 strncpy((char *)vendor, "SMSC", max_vendor_len);
1120 strncpy((char *)product, "Flash Media Cntrller",
1121 max_product_len);
ddde6b7c
BS
1122 }
1123}
1124#endif /* CONFIG_USB_BIN_FIXUP */
1125
07b2b78c
SG
1126#ifdef CONFIG_BLK
1127static unsigned long usb_stor_read(struct udevice *dev, lbaint_t blknr,
1128 lbaint_t blkcnt, void *buffer)
1129#else
4101f687 1130static unsigned long usb_stor_read(struct blk_desc *block_dev, lbaint_t blknr,
7c4213f6 1131 lbaint_t blkcnt, void *buffer)
07b2b78c 1132#endif
affae2bf 1133{
e81e79ed
GB
1134 lbaint_t start, blks;
1135 uintptr_t buf_addr;
affae2bf 1136 unsigned short smallblks;
9807c3b7 1137 struct usb_device *udev;
5dd95cf9 1138 struct us_data *ss;
84073b6f 1139 int retry;
b9560ad6 1140 struct scsi_cmd *srb = &usb_ccb;
07b2b78c
SG
1141#ifdef CONFIG_BLK
1142 struct blk_desc *block_dev;
1143#endif
f8d813e3
WD
1144
1145 if (blkcnt == 0)
1146 return 0;
a0cb3fc3 1147 /* Setup device */
07b2b78c
SG
1148#ifdef CONFIG_BLK
1149 block_dev = dev_get_uclass_platdata(dev);
1150 udev = dev_get_parent_priv(dev_get_parent(dev));
1151 debug("\nusb_read: udev %d\n", block_dev->devnum);
1152#else
9807c3b7
SG
1153 debug("\nusb_read: udev %d\n", block_dev->devnum);
1154 udev = usb_dev_desc[block_dev->devnum].priv;
1155 if (!udev) {
84073b6f
SG
1156 debug("%s: No device\n", __func__);
1157 return 0;
affae2bf 1158 }
07b2b78c 1159#endif
9807c3b7 1160 ss = (struct us_data *)udev->privptr;
affae2bf
WD
1161
1162 usb_disable_asynch(1); /* asynch transfer not allowed */
9807c3b7 1163 srb->lun = block_dev->lun;
f6570871 1164 buf_addr = (uintptr_t)buffer;
a0cb3fc3
MT
1165 start = blknr;
1166 blks = blkcnt;
a0cb3fc3 1167
9807c3b7
SG
1168 debug("\nusb_read: dev %d startblk " LBAF ", blccnt " LBAF " buffer %"
1169 PRIxPTR "\n", block_dev->devnum, start, blks, buf_addr);
a0cb3fc3 1170
affae2bf 1171 do {
a0cb3fc3
MT
1172 /* XXX need some comment here */
1173 retry = 2;
1174 srb->pdata = (unsigned char *)buf_addr;
6158d0b4
BM
1175 if (blks > ss->max_xfer_blk)
1176 smallblks = ss->max_xfer_blk;
a0cb3fc3
MT
1177 else
1178 smallblks = (unsigned short) blks;
affae2bf 1179retry_it:
6158d0b4 1180 if (smallblks == ss->max_xfer_blk)
affae2bf 1181 usb_show_progress();
9807c3b7 1182 srb->datalen = block_dev->blksz * smallblks;
a0cb3fc3 1183 srb->pdata = (unsigned char *)buf_addr;
5dd95cf9 1184 if (usb_read_10(srb, ss, start, smallblks)) {
ceb4972a 1185 debug("Read ERROR\n");
5dd95cf9 1186 usb_request_sense(srb, ss);
a0cb3fc3 1187 if (retry--)
affae2bf 1188 goto retry_it;
a0cb3fc3 1189 blkcnt -= blks;
affae2bf
WD
1190 break;
1191 }
a0cb3fc3
MT
1192 start += smallblks;
1193 blks -= smallblks;
1194 buf_addr += srb->datalen;
1195 } while (blks != 0);
3e8581bb 1196 ss->flags &= ~USB_READY;
a0cb3fc3 1197
ceb4972a 1198 debug("usb_read: end startblk " LBAF
4fd074de 1199 ", blccnt %x buffer %" PRIxPTR "\n",
ceb4972a 1200 start, smallblks, buf_addr);
a0cb3fc3 1201
affae2bf 1202 usb_disable_asynch(0); /* asynch transfer allowed */
6158d0b4 1203 if (blkcnt >= ss->max_xfer_blk)
226fa9bb 1204 debug("\n");
a0cb3fc3 1205 return blkcnt;
affae2bf
WD
1206}
1207
07b2b78c
SG
1208#ifdef CONFIG_BLK
1209static unsigned long usb_stor_write(struct udevice *dev, lbaint_t blknr,
1210 lbaint_t blkcnt, const void *buffer)
1211#else
4101f687 1212static unsigned long usb_stor_write(struct blk_desc *block_dev, lbaint_t blknr,
7c4213f6 1213 lbaint_t blkcnt, const void *buffer)
07b2b78c 1214#endif
127e1084 1215{
e81e79ed
GB
1216 lbaint_t start, blks;
1217 uintptr_t buf_addr;
127e1084 1218 unsigned short smallblks;
9807c3b7 1219 struct usb_device *udev;
5dd95cf9 1220 struct us_data *ss;
84073b6f 1221 int retry;
b9560ad6 1222 struct scsi_cmd *srb = &usb_ccb;
07b2b78c
SG
1223#ifdef CONFIG_BLK
1224 struct blk_desc *block_dev;
1225#endif
127e1084
MJ
1226
1227 if (blkcnt == 0)
1228 return 0;
1229
127e1084 1230 /* Setup device */
07b2b78c
SG
1231#ifdef CONFIG_BLK
1232 block_dev = dev_get_uclass_platdata(dev);
1233 udev = dev_get_parent_priv(dev_get_parent(dev));
1234 debug("\nusb_read: udev %d\n", block_dev->devnum);
1235#else
9807c3b7
SG
1236 debug("\nusb_read: udev %d\n", block_dev->devnum);
1237 udev = usb_dev_desc[block_dev->devnum].priv;
1238 if (!udev) {
1239 debug("%s: No device\n", __func__);
84073b6f 1240 return 0;
9807c3b7 1241 }
07b2b78c 1242#endif
9807c3b7 1243 ss = (struct us_data *)udev->privptr;
127e1084
MJ
1244
1245 usb_disable_asynch(1); /* asynch transfer not allowed */
1246
9807c3b7 1247 srb->lun = block_dev->lun;
f6570871 1248 buf_addr = (uintptr_t)buffer;
127e1084
MJ
1249 start = blknr;
1250 blks = blkcnt;
127e1084 1251
9807c3b7
SG
1252 debug("\nusb_write: dev %d startblk " LBAF ", blccnt " LBAF " buffer %"
1253 PRIxPTR "\n", block_dev->devnum, start, blks, buf_addr);
127e1084
MJ
1254
1255 do {
1256 /* If write fails retry for max retry count else
1257 * return with number of blocks written successfully.
1258 */
1259 retry = 2;
1260 srb->pdata = (unsigned char *)buf_addr;
6158d0b4
BM
1261 if (blks > ss->max_xfer_blk)
1262 smallblks = ss->max_xfer_blk;
127e1084
MJ
1263 else
1264 smallblks = (unsigned short) blks;
1265retry_it:
6158d0b4 1266 if (smallblks == ss->max_xfer_blk)
127e1084 1267 usb_show_progress();
9807c3b7 1268 srb->datalen = block_dev->blksz * smallblks;
127e1084 1269 srb->pdata = (unsigned char *)buf_addr;
5dd95cf9 1270 if (usb_write_10(srb, ss, start, smallblks)) {
ceb4972a 1271 debug("Write ERROR\n");
5dd95cf9 1272 usb_request_sense(srb, ss);
127e1084
MJ
1273 if (retry--)
1274 goto retry_it;
1275 blkcnt -= blks;
1276 break;
1277 }
1278 start += smallblks;
1279 blks -= smallblks;
1280 buf_addr += srb->datalen;
1281 } while (blks != 0);
3e8581bb 1282 ss->flags &= ~USB_READY;
127e1084 1283
4fd074de
SG
1284 debug("usb_write: end startblk " LBAF ", blccnt %x buffer %"
1285 PRIxPTR "\n", start, smallblks, buf_addr);
127e1084
MJ
1286
1287 usb_disable_asynch(0); /* asynch transfer allowed */
6158d0b4 1288 if (blkcnt >= ss->max_xfer_blk)
226fa9bb 1289 debug("\n");
127e1084
MJ
1290 return blkcnt;
1291
1292}
affae2bf
WD
1293
1294/* Probe to see if a new device is actually a Storage device */
a0cb3fc3
MT
1295int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,
1296 struct us_data *ss)
affae2bf 1297{
8f8bd565 1298 struct usb_interface *iface;
affae2bf 1299 int i;
605bd75a 1300 struct usb_endpoint_descriptor *ep_desc;
affae2bf
WD
1301 unsigned int flags = 0;
1302
affae2bf
WD
1303 /* let's examine the device now */
1304 iface = &dev->config.if_desc[ifnum];
1305
affae2bf 1306 if (dev->descriptor.bDeviceClass != 0 ||
8f8bd565
TR
1307 iface->desc.bInterfaceClass != USB_CLASS_MASS_STORAGE ||
1308 iface->desc.bInterfaceSubClass < US_SC_MIN ||
1309 iface->desc.bInterfaceSubClass > US_SC_MAX) {
1d5827a1 1310 debug("Not mass storage\n");
affae2bf
WD
1311 /* if it's not a mass storage, we go no further */
1312 return 0;
1313 }
1314
9c998aa8
WD
1315 memset(ss, 0, sizeof(struct us_data));
1316
affae2bf 1317 /* At this point, we know we've got a live one */
ceb4972a 1318 debug("\n\nUSB Mass Storage device detected\n");
affae2bf
WD
1319
1320 /* Initialize the us_data structure with some useful info */
1321 ss->flags = flags;
1322 ss->ifnum = ifnum;
1323 ss->pusb_dev = dev;
1324 ss->attention_done = 0;
f5fb78a2
TR
1325 ss->subclass = iface->desc.bInterfaceSubClass;
1326 ss->protocol = iface->desc.bInterfaceProtocol;
affae2bf
WD
1327
1328 /* set the handler pointers based on the protocol */
ceb4972a 1329 debug("Transport: ");
affae2bf
WD
1330 switch (ss->protocol) {
1331 case US_PR_CB:
ceb4972a 1332 debug("Control/Bulk\n");
affae2bf
WD
1333 ss->transport = usb_stor_CB_transport;
1334 ss->transport_reset = usb_stor_CB_reset;
1335 break;
1336
1337 case US_PR_CBI:
ceb4972a 1338 debug("Control/Bulk/Interrupt\n");
affae2bf
WD
1339 ss->transport = usb_stor_CB_transport;
1340 ss->transport_reset = usb_stor_CB_reset;
1341 break;
149dded2 1342 case US_PR_BULK:
ceb4972a 1343 debug("Bulk/Bulk/Bulk\n");
149dded2
WD
1344 ss->transport = usb_stor_BBB_transport;
1345 ss->transport_reset = usb_stor_BBB_reset;
1346 break;
affae2bf 1347 default:
80885a9d 1348 printf("USB Storage Transport unknown / not yet implemented\n");
affae2bf
WD
1349 return 0;
1350 break;
1351 }
1352
1353 /*
1354 * We are expecting a minimum of 2 endpoints - in and out (bulk).
1355 * An optional interrupt is OK (necessary for CBI protocol).
1356 * We will ignore any others.
1357 */
8f8bd565 1358 for (i = 0; i < iface->desc.bNumEndpoints; i++) {
605bd75a 1359 ep_desc = &iface->ep_desc[i];
affae2bf 1360 /* is it an BULK endpoint? */
605bd75a 1361 if ((ep_desc->bmAttributes &
a0cb3fc3 1362 USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) {
605bd75a
VG
1363 if (ep_desc->bEndpointAddress & USB_DIR_IN)
1364 ss->ep_in = ep_desc->bEndpointAddress &
1365 USB_ENDPOINT_NUMBER_MASK;
affae2bf 1366 else
a0cb3fc3 1367 ss->ep_out =
605bd75a 1368 ep_desc->bEndpointAddress &
affae2bf
WD
1369 USB_ENDPOINT_NUMBER_MASK;
1370 }
1371
1372 /* is it an interrupt endpoint? */
605bd75a
VG
1373 if ((ep_desc->bmAttributes &
1374 USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) {
1375 ss->ep_int = ep_desc->bEndpointAddress &
1376 USB_ENDPOINT_NUMBER_MASK;
1377 ss->irqinterval = ep_desc->bInterval;
affae2bf
WD
1378 }
1379 }
ceb4972a
VG
1380 debug("Endpoints In %d Out %d Int %d\n",
1381 ss->ep_in, ss->ep_out, ss->ep_int);
affae2bf
WD
1382
1383 /* Do some basic sanity checks, and bail if we find a problem */
8f8bd565 1384 if (usb_set_interface(dev, iface->desc.bInterfaceNumber, 0) ||
affae2bf
WD
1385 !ss->ep_in || !ss->ep_out ||
1386 (ss->protocol == US_PR_CBI && ss->ep_int == 0)) {
ceb4972a 1387 debug("Problems with device\n");
affae2bf
WD
1388 return 0;
1389 }
1390 /* set class specific stuff */
149dded2
WD
1391 /* We only handle certain protocols. Currently, these are
1392 * the only ones.
80885a9d 1393 * The SFF8070 accepts the requests used in u-boot
affae2bf 1394 */
80885a9d
WD
1395 if (ss->subclass != US_SC_UFI && ss->subclass != US_SC_SCSI &&
1396 ss->subclass != US_SC_8070) {
a0cb3fc3 1397 printf("Sorry, protocol %d not yet supported.\n", ss->subclass);
affae2bf
WD
1398 return 0;
1399 }
a0cb3fc3
MT
1400 if (ss->ep_int) {
1401 /* we had found an interrupt endpoint, prepare irq pipe
1402 * set up the IRQ pipe and handler
1403 */
affae2bf
WD
1404 ss->irqinterval = (ss->irqinterval > 0) ? ss->irqinterval : 255;
1405 ss->irqpipe = usb_rcvintpipe(ss->pusb_dev, ss->ep_int);
1406 ss->irqmaxp = usb_maxpacket(dev, ss->irqpipe);
a0cb3fc3 1407 dev->irq_handle = usb_stor_irq;
affae2bf 1408 }
6158d0b4
BM
1409
1410 /* Set the maximum transfer size per host controller setting */
ea7fad91 1411 usb_stor_set_max_xfer_blk(dev, ss);
6158d0b4 1412
a0cb3fc3 1413 dev->privptr = (void *)ss;
affae2bf
WD
1414 return 1;
1415}
1416
a0cb3fc3 1417int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
4101f687 1418 struct blk_desc *dev_desc)
affae2bf 1419{
a0cb3fc3 1420 unsigned char perq, modi;
f6570871
ST
1421 ALLOC_CACHE_ALIGN_BUFFER(u32, cap, 2);
1422 ALLOC_CACHE_ALIGN_BUFFER(u8, usb_stor_buf, 36);
1423 u32 capacity, blksz;
b9560ad6 1424 struct scsi_cmd *pccb = &usb_ccb;
9c998aa8 1425
9c998aa8
WD
1426 pccb->pdata = usb_stor_buf;
1427
1428 dev_desc->target = dev->devnum;
1429 pccb->lun = dev_desc->lun;
ceb4972a 1430 debug(" address %d\n", dev_desc->target);
affae2bf 1431
1d5827a1
SG
1432 if (usb_inquiry(pccb, ss)) {
1433 debug("%s: usb_inquiry() failed\n", __func__);
affae2bf 1434 return -1;
1d5827a1 1435 }
095b8a37 1436
9c998aa8
WD
1437 perq = usb_stor_buf[0];
1438 modi = usb_stor_buf[1];
a0cb3fc3 1439
6a559bbe
SM
1440 /*
1441 * Skip unknown devices (0x1f) and enclosure service devices (0x0d),
1442 * they would not respond to test_unit_ready .
1443 */
1444 if (((perq & 0x1f) == 0x1f) || ((perq & 0x1f) == 0x0d)) {
1d5827a1 1445 debug("%s: unknown/unsupported device\n", __func__);
a0cb3fc3 1446 return 0;
affae2bf 1447 }
a0cb3fc3
MT
1448 if ((modi&0x80) == 0x80) {
1449 /* drive is removable */
9c998aa8 1450 dev_desc->removable = 1;
affae2bf 1451 }
f6570871
ST
1452 memcpy(dev_desc->vendor, (const void *)&usb_stor_buf[8], 8);
1453 memcpy(dev_desc->product, (const void *)&usb_stor_buf[16], 16);
1454 memcpy(dev_desc->revision, (const void *)&usb_stor_buf[32], 4);
9c998aa8
WD
1455 dev_desc->vendor[8] = 0;
1456 dev_desc->product[16] = 0;
1457 dev_desc->revision[4] = 0;
ddde6b7c 1458#ifdef CONFIG_USB_BIN_FIXUP
a0cb3fc3
MT
1459 usb_bin_fixup(dev->descriptor, (uchar *)dev_desc->vendor,
1460 (uchar *)dev_desc->product);
ddde6b7c 1461#endif /* CONFIG_USB_BIN_FIXUP */
ceb4972a
VG
1462 debug("ISO Vers %X, Response Data %X\n", usb_stor_buf[2],
1463 usb_stor_buf[3]);
a0cb3fc3
MT
1464 if (usb_test_unit_ready(pccb, ss)) {
1465 printf("Device NOT ready\n"
1466 " Request Sense returned %02X %02X %02X\n",
1467 pccb->sense_buf[2], pccb->sense_buf[12],
1468 pccb->sense_buf[13]);
1e5eca7d 1469 if (dev_desc->removable == 1)
9c998aa8 1470 dev_desc->type = perq;
a0cb3fc3 1471 return 0;
affae2bf 1472 }
f6570871 1473 pccb->pdata = (unsigned char *)cap;
a0cb3fc3
MT
1474 memset(pccb->pdata, 0, 8);
1475 if (usb_read_capacity(pccb, ss) != 0) {
affae2bf 1476 printf("READ_CAP ERROR\n");
9c998aa8
WD
1477 cap[0] = 2880;
1478 cap[1] = 0x200;
affae2bf 1479 }
3e8581bb 1480 ss->flags &= ~USB_READY;
f6570871 1481 debug("Read Capacity returns: 0x%08x, 0x%08x\n", cap[0], cap[1]);
affae2bf 1482#if 0
a0cb3fc3
MT
1483 if (cap[0] > (0x200000 * 10)) /* greater than 10 GByte */
1484 cap[0] >>= 16;
f6570871 1485
c918261c
CE
1486 cap[0] = cpu_to_be32(cap[0]);
1487 cap[1] = cpu_to_be32(cap[1]);
f6570871
ST
1488#endif
1489
1490 capacity = be32_to_cpu(cap[0]) + 1;
1491 blksz = be32_to_cpu(cap[1]);
c918261c 1492
f6570871
ST
1493 debug("Capacity = 0x%08x, blocksz = 0x%08x\n", capacity, blksz);
1494 dev_desc->lba = capacity;
1495 dev_desc->blksz = blksz;
0472fbfd 1496 dev_desc->log2blksz = LOG2(dev_desc->blksz);
9c998aa8 1497 dev_desc->type = perq;
ceb4972a 1498 debug(" address %d\n", dev_desc->target);
affae2bf 1499
affae2bf
WD
1500 return 1;
1501}
acf277af
SG
1502
1503#ifdef CONFIG_DM_USB
1504
1505static int usb_mass_storage_probe(struct udevice *dev)
1506{
bcbe3d15 1507 struct usb_device *udev = dev_get_parent_priv(dev);
acf277af
SG
1508 int ret;
1509
1510 usb_disable_asynch(1); /* asynch transfer not allowed */
1511 ret = usb_stor_probe_device(udev);
1512 usb_disable_asynch(0); /* asynch transfer allowed */
1513
1514 return ret;
1515}
1516
1517static const struct udevice_id usb_mass_storage_ids[] = {
1518 { .compatible = "usb-mass-storage" },
1519 { }
1520};
1521
1522U_BOOT_DRIVER(usb_mass_storage) = {
1523 .name = "usb_mass_storage",
1524 .id = UCLASS_MASS_STORAGE,
1525 .of_match = usb_mass_storage_ids,
1526 .probe = usb_mass_storage_probe,
07b2b78c
SG
1527#ifdef CONFIG_BLK
1528 .platdata_auto_alloc_size = sizeof(struct us_data),
1529#endif
acf277af
SG
1530};
1531
1532UCLASS_DRIVER(usb_mass_storage) = {
1533 .id = UCLASS_MASS_STORAGE,
1534 .name = "usb_mass_storage",
1535};
1536
1537static const struct usb_device_id mass_storage_id_table[] = {
1538 {
1539 .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
1540 .bInterfaceClass = USB_CLASS_MASS_STORAGE
1541 },
1542 { } /* Terminating entry */
1543};
1544
abb59cff 1545U_BOOT_USB_DEVICE(usb_mass_storage, mass_storage_id_table);
07b2b78c 1546#endif
acf277af 1547
07b2b78c
SG
1548#ifdef CONFIG_BLK
1549static const struct blk_ops usb_storage_ops = {
1550 .read = usb_stor_read,
1551 .write = usb_stor_write,
1552};
1553
1554U_BOOT_DRIVER(usb_storage_blk) = {
1555 .name = "usb_storage_blk",
1556 .id = UCLASS_BLK,
1557 .ops = &usb_storage_ops,
1558};
c0543bf6
SG
1559#else
1560U_BOOT_LEGACY_BLK(usb) = {
1561 .if_typename = "usb",
1562 .if_type = IF_TYPE_USB,
1563 .max_devs = USB_MAX_STOR_DEV,
1564 .desc = usb_dev_desc,
1565};
acf277af 1566#endif