blob: a91b1c0d2f925eed06881d14ab85afe398eac423 [file] [log] [blame]
wdenkaffae2b2002-08-17 09:36:01 +00001/*
Wolfgang Denk460c3222005-08-04 01:14:12 +02002 * 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
Simon Glassacf277a2015-03-25 12:22:16 -060012 * Driver model conversion:
13 * (C) Copyright 2015 Google, Inc
wdenkaffae2b2002-08-17 09:36:01 +000014 *
wdenk149dded2003-09-10 18:20:28 +000015 * For BBB support (C) Copyright 2003
Detlev Zundel792a09e2009-05-13 10:54:10 +020016 * Gary Jennejohn, DENX Software Engineering <garyj@denx.de>
wdenk149dded2003-09-10 18:20:28 +000017 *
Wolfgang Denk460c3222005-08-04 01:14:12 +020018 * BBB support based on /sys/dev/usb/umass.c from
wdenk149dded2003-09-10 18:20:28 +000019 * FreeBSD.
wdenkaffae2b2002-08-17 09:36:01 +000020 *
Wolfgang Denk1a459662013-07-08 09:37:19 +020021 * SPDX-License-Identifier: GPL-2.0+
wdenkaffae2b2002-08-17 09:36:01 +000022 */
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 */
wdenk149dded2003-09-10 18:20:28 +000029/*
30 * New Note:
31 * Support for USB Mass Storage Devices (BBB) has been added. It has
32 * only been tested with USB memory sticks.
wdenk149dded2003-09-10 18:20:28 +000033 */
wdenkaffae2b2002-08-17 09:36:01 +000034
35
wdenkaffae2b2002-08-17 09:36:01 +000036#include <common.h>
37#include <command.h>
Simon Glassacf277a2015-03-25 12:22:16 -060038#include <dm.h>
Simon Glass91557572015-03-25 12:22:15 -060039#include <errno.h>
Simon Glass4fd074d2014-10-15 04:38:38 -060040#include <inttypes.h>
Simon Glass05108132015-03-25 12:22:14 -060041#include <mapmem.h>
Simon Glasscf92e052015-09-02 17:24:58 -060042#include <memalign.h>
Christian Eggersc9182612008-05-21 22:12:00 +020043#include <asm/byteorder.h>
wdenkaffae2b2002-08-17 09:36:01 +000044#include <asm/processor.h>
Simon Glassacf277a2015-03-25 12:22:16 -060045#include <dm/device-internal.h>
Simon Glass07b2b782016-02-29 15:25:58 -070046#include <dm/lists.h>
wdenkaffae2b2002-08-17 09:36:01 +000047
Grant Likely735dd972007-02-20 09:04:34 +010048#include <part.h>
wdenkaffae2b2002-08-17 09:36:01 +000049#include <usb.h>
50
wdenk80885a92004-02-26 23:46:20 +000051#undef BBB_COMDAT_TRACE
52#undef BBB_XPORT_TRACE
wdenkaffae2b2002-08-17 09:36:01 +000053
wdenkaffae2b2002-08-17 09:36:01 +000054#include <scsi.h>
55/* direction table -- this indicates the direction of the data
56 * transfer for each command code -- a 1 indicates input
57 */
Mike Frysinger2ff122852010-10-20 07:16:04 -040058static const unsigned char us_direction[256/8] = {
wdenkaffae2b2002-08-17 09:36:01 +000059 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
Simon Glassb9560ad2017-06-14 21:28:30 -060066static struct scsi_cmd usb_ccb __aligned(ARCH_DMA_MINALIGN);
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +010067static __u32 CBWTag;
wdenk149dded2003-09-10 18:20:28 +000068
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +010069static int usb_max_devs; /* number of highest available usb device */
wdenkaffae2b2002-08-17 09:36:01 +000070
Simon Glass07b2b782016-02-29 15:25:58 -070071#ifndef CONFIG_BLK
Simon Glass4101f682016-02-29 15:25:34 -070072static struct blk_desc usb_dev_desc[USB_MAX_STOR_DEV];
Simon Glass07b2b782016-02-29 15:25:58 -070073#endif
wdenkaffae2b2002-08-17 09:36:01 +000074
75struct us_data;
Simon Glassb9560ad2017-06-14 21:28:30 -060076typedef int (*trans_cmnd)(struct scsi_cmd *cb, struct us_data *data);
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +010077typedef int (*trans_reset)(struct us_data *data);
wdenkaffae2b2002-08-17 09:36:01 +000078
79struct us_data {
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +010080 struct usb_device *pusb_dev; /* this usb_device */
81
82 unsigned int flags; /* from filter initially */
Benoît Thébaudeau3e8581b2012-08-10 18:27:11 +020083# define USB_READY (1 << 0)
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +010084 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 */
Simon Glassb9560ad2017-06-14 21:28:30 -060098 struct scsi_cmd *srb; /* current srb */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +010099 trans_reset transport_reset; /* reset routine */
100 trans_cmnd transport; /* transport routine */
Bin Meng6158d0b2017-09-07 06:13:20 -0700101 unsigned short max_xfer_blk; /* maximum transfer blocks */
wdenkaffae2b2002-08-17 09:36:01 +0000102};
103
Simon Glass07b2b782016-02-29 15:25:58 -0700104#ifndef CONFIG_BLK
wdenkaffae2b2002-08-17 09:36:01 +0000105static struct us_data usb_stor[USB_MAX_STOR_DEV];
Simon Glass07b2b782016-02-29 15:25:58 -0700106#endif
wdenkaffae2b2002-08-17 09:36:01 +0000107
wdenk80885a92004-02-26 23:46:20 +0000108#define USB_STOR_TRANSPORT_GOOD 0
wdenkaffae2b2002-08-17 09:36:01 +0000109#define USB_STOR_TRANSPORT_FAILED -1
110#define USB_STOR_TRANSPORT_ERROR -2
111
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100112int usb_stor_get_info(struct usb_device *dev, struct us_data *us,
Simon Glass4101f682016-02-29 15:25:34 -0700113 struct blk_desc *dev_desc);
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100114int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,
115 struct us_data *ss);
Simon Glass07b2b782016-02-29 15:25:58 -0700116#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
Simon Glass4101f682016-02-29 15:25:34 -0700122static unsigned long usb_stor_read(struct blk_desc *block_dev, lbaint_t blknr,
Stephen Warren7c4213f2015-12-07 11:38:48 -0700123 lbaint_t blkcnt, void *buffer);
Simon Glass4101f682016-02-29 15:25:34 -0700124static unsigned long usb_stor_write(struct blk_desc *block_dev, lbaint_t blknr,
Stephen Warren7c4213f2015-12-07 11:38:48 -0700125 lbaint_t blkcnt, const void *buffer);
Simon Glass07b2b782016-02-29 15:25:58 -0700126#endif
wdenkaffae2b2002-08-17 09:36:01 +0000127void uhci_show_temp_int_td(void);
128
Kim Phillips199adb62012-10-29 13:34:32 +0000129static void usb_show_progress(void)
wdenkaffae2b2002-08-17 09:36:01 +0000130{
Wolfgang Denk226fa9b2010-07-19 11:36:59 +0200131 debug(".");
wdenkaffae2b2002-08-17 09:36:01 +0000132}
133
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100134/*******************************************************************************
Wolfgang Denk9c998aa2005-07-21 11:57:57 +0200135 * show info on storage devices; 'usb start/init' must be invoked earlier
136 * as we only retrieve structures populated during devices initialization
137 */
Aras Vaichasf6b44e02008-03-25 12:09:07 +1100138int usb_stor_info(void)
Wolfgang Denk9c998aa2005-07-21 11:57:57 +0200139{
Simon Glass9807c3b2016-02-29 15:25:54 -0700140 int count = 0;
Simon Glass07b2b782016-02-29 15:25:58 -0700141#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
Wolfgang Denk9c998aa2005-07-21 11:57:57 +0200154 int i;
155
Aras Vaichasf6b44e02008-03-25 12:09:07 +1100156 if (usb_max_devs > 0) {
Wolfgang Denk9c998aa2005-07-21 11:57:57 +0200157 for (i = 0; i < usb_max_devs; i++) {
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100158 printf(" Device %d: ", i);
Wolfgang Denk9c998aa2005-07-21 11:57:57 +0200159 dev_print(&usb_dev_desc[i]);
160 }
Markus Klotzbuecherb9e749e2008-03-26 18:26:43 +0100161 return 0;
Aras Vaichasf6b44e02008-03-25 12:09:07 +1100162 }
Simon Glass07b2b782016-02-29 15:25:58 -0700163#endif
Simon Glass9807c3b2016-02-29 15:25:54 -0700164 if (!count) {
165 printf("No storage devices, perhaps not 'usb start'ed..?\n");
166 return 1;
167 }
168
Simon Glassb94fc852016-03-16 07:45:44 -0600169 return 0;
Wolfgang Denk9c998aa2005-07-21 11:57:57 +0200170}
171
Ludovic Courtès99e9ed12010-10-05 22:04:26 +0200172static unsigned int usb_get_max_lun(struct us_data *us)
173{
174 int len;
Puneet Saxenaf5766132012-04-03 14:56:06 +0530175 ALLOC_CACHE_ALIGN_BUFFER(unsigned char, result, 1);
Ludovic Courtès99e9ed12010-10-05 22:04:26 +0200176 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,
Puneet Saxenaf5766132012-04-03 14:56:06 +0530181 result, sizeof(char),
Ludovic Courtès99e9ed12010-10-05 22:04:26 +0200182 USB_CNTL_TIMEOUT * 5);
Vivek Gautamceb49722013-04-12 16:34:33 +0530183 debug("Get Max LUN -> len = %i, result = %i\n", len, (int) *result);
Puneet Saxenaf5766132012-04-03 14:56:06 +0530184 return (len > 0) ? *result : 0;
Ludovic Courtès99e9ed12010-10-05 22:04:26 +0200185}
186
Simon Glass9807c3b2016-02-29 15:25:54 -0700187static int usb_stor_probe_device(struct usb_device *udev)
Simon Glass91557572015-03-25 12:22:15 -0600188{
Simon Glass9807c3b2016-02-29 15:25:54 -0700189 int lun, max_lun;
Simon Glass07b2b782016-02-29 15:25:58 -0700190
191#ifdef CONFIG_BLK
192 struct us_data *data;
Simon Glass07b2b782016-02-29 15:25:58 -0700193 int ret;
194#else
Simon Glass9807c3b2016-02-29 15:25:54 -0700195 int start;
196
197 if (udev == NULL)
Simon Glass91557572015-03-25 12:22:15 -0600198 return -ENOENT; /* no more devices available */
Simon Glass07b2b782016-02-29 15:25:58 -0700199#endif
Simon Glass91557572015-03-25 12:22:15 -0600200
Simon Glass07b2b782016-02-29 15:25:58 -0700201 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;
Simon Glass9107c972016-05-01 11:36:29 -0600215 char str[10];
Simon Glass07b2b782016-02-29 15:25:58 -0700216
Simon Glass9107c972016-05-01 11:36:29 -0600217 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);
Simon Glass07b2b782016-02-29 15:25:58 -0700221 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;
229
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
Simon Glassc89e79d2016-02-29 15:25:53 -0700244 /* 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
Simon Glass9807c3b2016-02-29 15:25:54 -0700251 if (!usb_storage_probe(udev, 0, &usb_stor[usb_max_devs]))
252 return 0;
Simon Glass91557572015-03-25 12:22:15 -0600253
Simon Glass9807c3b2016-02-29 15:25:54 -0700254 /*
255 * OK, it's a storage device. Iterate over its LUNs and populate
256 * usb_dev_desc'
257 */
258 start = usb_max_devs;
Simon Glass91557572015-03-25 12:22:15 -0600259
Simon Glass9807c3b2016-02-29 15:25:54 -0700260 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;
Simon Glass91557572015-03-25 12:22:15 -0600264
Simon Glass9807c3b2016-02-29 15:25:54 -0700265 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) {
Simon Glass07b2b782016-02-29 15:25:58 -0700279 debug("partype: %d\n", blkdev->part_type);
280 part_init(blkdev);
281 debug("partype: %d\n", blkdev->part_type);
Simon Glass9807c3b2016-02-29 15:25:54 -0700282 usb_max_devs++;
283 debug("%s: Found device %p\n", __func__, udev);
Simon Glass91557572015-03-25 12:22:15 -0600284 }
285 }
Simon Glass07b2b782016-02-29 15:25:58 -0700286#endif
Simon Glass91557572015-03-25 12:22:15 -0600287
Simon Glass91557572015-03-25 12:22:15 -0600288 return 0;
289}
290
291void usb_stor_reset(void)
292{
293 usb_max_devs = 0;
294}
295
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100296/*******************************************************************************
Wolfgang Denk9c998aa2005-07-21 11:57:57 +0200297 * scan the usb and reports device info
wdenkaffae2b2002-08-17 09:36:01 +0000298 * to the user if mode = 1
299 * returns current device or -1 if no
300 */
301int usb_stor_scan(int mode)
302{
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100303 if (mode == 1)
Lucas Stach93c25822012-09-26 00:14:36 +0200304 printf(" scanning usb for storage devices... ");
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100305
Michal Simekb9847002016-12-21 09:35:08 +0100306#ifndef CONFIG_DM_USB
307 unsigned char i;
308
wdenkaffae2b2002-08-17 09:36:01 +0000309 usb_disable_asynch(1); /* asynch transfer not allowed */
310
Simon Glass91557572015-03-25 12:22:15 -0600311 usb_stor_reset();
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100312 for (i = 0; i < USB_MAX_DEVICE; i++) {
Simon Glass91557572015-03-25 12:22:15 -0600313 struct usb_device *dev;
314
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100315 dev = usb_get_dev_index(i); /* get device */
Vivek Gautamceb49722013-04-12 16:34:33 +0530316 debug("i=%d\n", i);
Simon Glass91557572015-03-25 12:22:15 -0600317 if (usb_stor_probe_device(dev))
wdenkaffae2b2002-08-17 09:36:01 +0000318 break;
wdenkaffae2b2002-08-17 09:36:01 +0000319 } /* for */
Wolfgang Denk095b8a32005-08-02 17:06:17 +0200320
wdenkaffae2b2002-08-17 09:36:01 +0000321 usb_disable_asynch(0); /* asynch transfer allowed */
Michal Simekb9847002016-12-21 09:35:08 +0100322#endif
Wolfgang Denk9c998aa2005-07-21 11:57:57 +0200323 printf("%d Storage Device(s) found\n", usb_max_devs);
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100324 if (usb_max_devs > 0)
wdenkaffae2b2002-08-17 09:36:01 +0000325 return 0;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100326 return -1;
wdenkaffae2b2002-08-17 09:36:01 +0000327}
328
329static int usb_stor_irq(struct usb_device *dev)
330{
331 struct us_data *us;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100332 us = (struct us_data *)dev->privptr;
wdenkaffae2b2002-08-17 09:36:01 +0000333
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100334 if (us->ip_wanted)
335 us->ip_wanted = 0;
wdenkaffae2b2002-08-17 09:36:01 +0000336 return 0;
337}
338
339
Vivek Gautamceb49722013-04-12 16:34:33 +0530340#ifdef DEBUG
wdenkaffae2b2002-08-17 09:36:01 +0000341
Simon Glassb9560ad2017-06-14 21:28:30 -0600342static void usb_show_srb(struct scsi_cmd *pccb)
wdenkaffae2b2002-08-17 09:36:01 +0000343{
344 int i;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100345 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]);
wdenkaffae2b2002-08-17 09:36:01 +0000348 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 */
Simon Glass05108132015-03-25 12:22:14 -0600392 debug("Bulk xfer 0x%lx(%d) try #%d\n",
393 (ulong)map_to_sysmem(buf), this_xfer,
394 11 - maxtry);
wdenkaffae2b2002-08-17 09:36:01 +0000395 result = usb_bulk_msg(us->pusb_dev, pipe, buf,
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100396 this_xfer, &partial,
397 USB_CNTL_TIMEOUT * 5);
Vivek Gautamceb49722013-04-12 16:34:33 +0530398 debug("bulk_msg returned %d xferred %d/%d\n",
399 result, partial, this_xfer);
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100400 if (us->pusb_dev->status != 0) {
401 /* if we stall, we need to clear it before
402 * we go on
403 */
Vivek Gautamceb49722013-04-12 16:34:33 +0530404#ifdef DEBUG
wdenkaffae2b2002-08-17 09:36:01 +0000405 display_int_status(us->pusb_dev->status);
406#endif
407 if (us->pusb_dev->status & USB_ST_STALLED) {
Vivek Gautamceb49722013-04-12 16:34:33 +0530408 debug("stalled ->clearing endpoint" \
409 "halt for pipe 0x%x\n", pipe);
wdenkaffae2b2002-08-17 09:36:01 +0000410 stat = us->pusb_dev->status;
411 usb_clear_halt(us->pusb_dev, pipe);
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100412 us->pusb_dev->status = stat;
413 if (this_xfer == partial) {
Vivek Gautamceb49722013-04-12 16:34:33 +0530414 debug("bulk transferred" \
415 "with error %lX," \
416 " but data ok\n",
417 us->pusb_dev->status);
wdenkaffae2b2002-08-17 09:36:01 +0000418 return 0;
419 }
420 else
421 return result;
422 }
423 if (us->pusb_dev->status & USB_ST_NAK_REC) {
Vivek Gautamceb49722013-04-12 16:34:33 +0530424 debug("Device NAKed bulk_msg\n");
wdenkaffae2b2002-08-17 09:36:01 +0000425 return result;
426 }
Vivek Gautamceb49722013-04-12 16:34:33 +0530427 debug("bulk transferred with error");
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100428 if (this_xfer == partial) {
Vivek Gautamceb49722013-04-12 16:34:33 +0530429 debug(" %ld, but data ok\n",
430 us->pusb_dev->status);
wdenkaffae2b2002-08-17 09:36:01 +0000431 return 0;
432 }
433 /* if our try counter reaches 0, bail out */
Vivek Gautamceb49722013-04-12 16:34:33 +0530434 debug(" %ld, data %d\n",
435 us->pusb_dev->status, partial);
wdenkaffae2b2002-08-17 09:36:01 +0000436 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 */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100443 } while (this_xfer);
wdenkaffae2b2002-08-17 09:36:01 +0000444 }
445
446 /* if we get here, we're done and successful */
447 return 0;
448}
449
wdenk149dded2003-09-10 18:20:28 +0000450static 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 */
Vivek Gautamceb49722013-04-12 16:34:33 +0530469 debug("BBB_reset\n");
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100470 result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev, 0),
471 US_BBB_RESET,
472 USB_TYPE_CLASS | USB_RECIP_INTERFACE,
Kim Phillips199adb62012-10-29 13:34:32 +0000473 0, us->ifnum, NULL, 0, USB_CNTL_TIMEOUT * 5);
Wolfgang Denk9c998aa2005-07-21 11:57:57 +0200474
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100475 if ((result < 0) && (us->pusb_dev->status & USB_ST_STALLED)) {
Vivek Gautamceb49722013-04-12 16:34:33 +0530476 debug("RESET:stall\n");
wdenk149dded2003-09-10 18:20:28 +0000477 return -1;
478 }
Wolfgang Denk9c998aa2005-07-21 11:57:57 +0200479
wdenk149dded2003-09-10 18:20:28 +0000480 /* long wait for reset */
Mike Frysinger5b84dd62012-03-05 13:47:00 +0000481 mdelay(150);
Vivek Gautamceb49722013-04-12 16:34:33 +0530482 debug("BBB_reset result %d: status %lX reset\n",
483 result, us->pusb_dev->status);
wdenk149dded2003-09-10 18:20:28 +0000484 pipe = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
485 result = usb_clear_halt(us->pusb_dev, pipe);
486 /* long wait for reset */
Mike Frysinger5b84dd62012-03-05 13:47:00 +0000487 mdelay(150);
Vivek Gautamceb49722013-04-12 16:34:33 +0530488 debug("BBB_reset result %d: status %lX clearing IN endpoint\n",
489 result, us->pusb_dev->status);
wdenk149dded2003-09-10 18:20:28 +0000490 /* long wait for reset */
491 pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
492 result = usb_clear_halt(us->pusb_dev, pipe);
Mike Frysinger5b84dd62012-03-05 13:47:00 +0000493 mdelay(150);
Vivek Gautamceb49722013-04-12 16:34:33 +0530494 debug("BBB_reset result %d: status %lX clearing OUT endpoint\n",
495 result, us->pusb_dev->status);
496 debug("BBB_reset done\n");
wdenk149dded2003-09-10 18:20:28 +0000497 return 0;
498}
499
wdenkaffae2b2002-08-17 09:36:01 +0000500/* 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
Vivek Gautamceb49722013-04-12 16:34:33 +0530509 debug("CB_reset\n");
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100510 memset(cmd, 0xff, sizeof(cmd));
wdenkaffae2b2002-08-17 09:36:01 +0000511 cmd[0] = SCSI_SEND_DIAG;
512 cmd[1] = 4;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100513 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);
wdenkaffae2b2002-08-17 09:36:01 +0000518
519 /* long wait for reset */
Mike Frysinger5b84dd62012-03-05 13:47:00 +0000520 mdelay(1500);
Vivek Gautamceb49722013-04-12 16:34:33 +0530521 debug("CB_reset result %d: status %lX clearing endpoint halt\n",
522 result, us->pusb_dev->status);
wdenkaffae2b2002-08-17 09:36:01 +0000523 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
Vivek Gautamceb49722013-04-12 16:34:33 +0530526 debug("CB_reset done\n");
wdenkaffae2b2002-08-17 09:36:01 +0000527 return 0;
528}
529
wdenk149dded2003-09-10 18:20:28 +0000530/*
531 * Set up the command for a BBB device. Note that the actual SCSI
532 * command is copied into cbw.CBWCDB.
533 */
Simon Glassb9560ad2017-06-14 21:28:30 -0600534static int usb_stor_BBB_comdat(struct scsi_cmd *srb, struct us_data *us)
wdenk149dded2003-09-10 18:20:28 +0000535{
536 int result;
537 int actlen;
538 int dir_in;
539 unsigned int pipe;
Simon Glass2e17c872015-03-25 12:22:11 -0600540 ALLOC_CACHE_ALIGN_BUFFER(struct umass_bbb_cbw, cbw, 1);
wdenk149dded2003-09-10 18:20:28 +0000541
542 dir_in = US_DIRECTION(srb->cmd[0]);
543
544#ifdef BBB_COMDAT_TRACE
Vivek Gautam605bd752013-04-12 16:34:34 +0530545 printf("dir %d lun %d cmdlen %d cmd %p datalen %lu pdata %p\n",
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100546 dir_in, srb->lun, srb->cmdlen, srb->cmd, srb->datalen,
547 srb->pdata);
wdenk149dded2003-09-10 18:20:28 +0000548 if (srb->cmdlen) {
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100549 for (result = 0; result < srb->cmdlen; result++)
wdenk149dded2003-09-10 18:20:28 +0000550 printf("cmd[%d] %#x ", result, srb->cmd[result]);
551 printf("\n");
552 }
553#endif
554 /* sanity checks */
555 if (!(srb->cmdlen <= CBWCDBLENGTH)) {
Vivek Gautamceb49722013-04-12 16:34:33 +0530556 debug("usb_stor_BBB_comdat:cmdlen too large\n");
wdenk149dded2003-09-10 18:20:28 +0000557 return -1;
558 }
559
560 /* always OUT to the ep */
561 pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
562
Puneet Saxenaf5766132012-04-03 14:56:06 +0530563 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;
wdenk149dded2003-09-10 18:20:28 +0000569 /* copy the command data into the CBW command data buffer */
570 /* DST SRC LEN!!! */
Sergey Temerkhanovf6570872015-04-01 17:18:46 +0300571
Puneet Saxenaf5766132012-04-03 14:56:06 +0530572 memcpy(cbw->CBWCDB, srb->cmd, srb->cmdlen);
573 result = usb_bulk_msg(us->pusb_dev, pipe, cbw, UMASS_BBB_CBW_SIZE,
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100574 &actlen, USB_CNTL_TIMEOUT * 5);
wdenk149dded2003-09-10 18:20:28 +0000575 if (result < 0)
Vivek Gautamceb49722013-04-12 16:34:33 +0530576 debug("usb_stor_BBB_comdat:usb_bulk_msg error\n");
wdenk149dded2003-09-10 18:20:28 +0000577 return result;
578}
579
wdenkaffae2b2002-08-17 09:36:01 +0000580/* FIXME: we also need a CBI_command which sets up the completion
581 * interrupt, and waits for it
582 */
Simon Glassb9560ad2017-06-14 21:28:30 -0600583static int usb_stor_CB_comdat(struct scsi_cmd *srb, struct us_data *us)
wdenkaffae2b2002-08-17 09:36:01 +0000584{
Wolfgang Denk77ddac92005-10-13 16:45:02 +0200585 int result = 0;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100586 int dir_in, retry;
wdenkaffae2b2002-08-17 09:36:01 +0000587 unsigned int pipe;
588 unsigned long status;
589
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100590 retry = 5;
591 dir_in = US_DIRECTION(srb->cmd[0]);
wdenkaffae2b2002-08-17 09:36:01 +0000592
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100593 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--) {
Vivek Gautamceb49722013-04-12 16:34:33 +0530599 debug("CBI gets a command: Try %d\n", 5 - retry);
600#ifdef DEBUG
wdenkaffae2b2002-08-17 09:36:01 +0000601 usb_show_srb(srb);
602#endif
603 /* let's send the command via the control pipe */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100604 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,
wdenkaffae2b2002-08-17 09:36:01 +0000608 0, us->ifnum,
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100609 srb->cmd, srb->cmdlen,
610 USB_CNTL_TIMEOUT * 5);
Vivek Gautamceb49722013-04-12 16:34:33 +0530611 debug("CB_transport: control msg returned %d, status %lX\n",
612 result, us->pusb_dev->status);
wdenkaffae2b2002-08-17 09:36:01 +0000613 /* check the return code for the command */
614 if (result < 0) {
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100615 if (us->pusb_dev->status & USB_ST_STALLED) {
616 status = us->pusb_dev->status;
Vivek Gautamceb49722013-04-12 16:34:33 +0530617 debug(" stall during command found," \
618 " clear pipe\n");
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100619 usb_clear_halt(us->pusb_dev,
620 usb_sndctrlpipe(us->pusb_dev, 0));
621 us->pusb_dev->status = status;
wdenkaffae2b2002-08-17 09:36:01 +0000622 }
Vivek Gautamceb49722013-04-12 16:34:33 +0530623 debug(" error during command %02X" \
624 " Stat = %lX\n", srb->cmd[0],
625 us->pusb_dev->status);
wdenkaffae2b2002-08-17 09:36:01 +0000626 return result;
627 }
628 /* transfer the data payload for this command, if one exists*/
629
Vivek Gautamceb49722013-04-12 16:34:33 +0530630 debug("CB_transport: control msg returned %d," \
631 " direction is %s to go 0x%lx\n", result,
632 dir_in ? "IN" : "OUT", srb->datalen);
wdenkaffae2b2002-08-17 09:36:01 +0000633 if (srb->datalen) {
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100634 result = us_one_transfer(us, pipe, (char *)srb->pdata,
635 srb->datalen);
Vivek Gautamceb49722013-04-12 16:34:33 +0530636 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);
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100640 if (!(us->pusb_dev->status & USB_ST_NAK_REC))
wdenkaffae2b2002-08-17 09:36:01 +0000641 break;
642 } /* if (srb->datalen) */
643 else
644 break;
645 }
646 /* return result */
647
648 return result;
649}
650
651
Simon Glassb9560ad2017-06-14 21:28:30 -0600652static int usb_stor_CBI_get_status(struct scsi_cmd *srb, struct us_data *us)
wdenkaffae2b2002-08-17 09:36:01 +0000653{
654 int timeout;
655
wdenk80885a92004-02-26 23:46:20 +0000656 us->ip_wanted = 1;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100657 submit_int_msg(us->pusb_dev, us->irqpipe,
wdenk80885a92004-02-26 23:46:20 +0000658 (void *) &us->ip_data, us->irqmaxp, us->irqinterval);
659 timeout = 1000;
660 while (timeout--) {
Sergey Temerkhanovf6570872015-04-01 17:18:46 +0300661 if (us->ip_wanted == 0)
wdenkaffae2b2002-08-17 09:36:01 +0000662 break;
Mike Frysinger5b84dd62012-03-05 13:47:00 +0000663 mdelay(10);
wdenkaffae2b2002-08-17 09:36:01 +0000664 }
665 if (us->ip_wanted) {
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100666 printf(" Did not get interrupt on CBI\n");
wdenkaffae2b2002-08-17 09:36:01 +0000667 us->ip_wanted = 0;
668 return USB_STOR_TRANSPORT_ERROR;
669 }
Vagrant Cascadiana6f70a32016-03-15 12:16:39 -0700670 debug("Got interrupt data 0x%x, transferred %d status 0x%lX\n",
Vivek Gautamceb49722013-04-12 16:34:33 +0530671 us->ip_data, us->pusb_dev->irq_act_len,
672 us->pusb_dev->irq_status);
wdenkaffae2b2002-08-17 09:36:01 +0000673 /* 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 */
wdenk80885a92004-02-26 23:46:20 +0000678 else if (us->ip_data)
679 return USB_STOR_TRANSPORT_FAILED;
wdenkaffae2b2002-08-17 09:36:01 +0000680 else
wdenk80885a92004-02-26 23:46:20 +0000681 return USB_STOR_TRANSPORT_GOOD;
wdenkaffae2b2002-08-17 09:36:01 +0000682 }
683 /* otherwise, we interpret the data normally */
684 switch (us->ip_data) {
wdenk80885a92004-02-26 23:46:20 +0000685 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 */
wdenkaffae2b2002-08-17 09:36:01 +0000692 return USB_STOR_TRANSPORT_ERROR;
693}
694
695#define USB_TRANSPORT_UNKNOWN_RETRY 5
696#define USB_TRANSPORT_NOT_READY_RETRY 10
697
wdenk149dded2003-09-10 18:20:28 +0000698/* clear a stall on an endpoint - special for BBB devices */
Kim Phillips199adb62012-10-29 13:34:32 +0000699static int usb_stor_BBB_clear_endpt_stall(struct us_data *us, __u8 endpt)
wdenk149dded2003-09-10 18:20:28 +0000700{
wdenk149dded2003-09-10 18:20:28 +0000701 /* ENDPOINT_HALT = 0, so set value to 0 */
Masahiro Yamada8319aeb2016-09-06 22:17:35 +0900702 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);
wdenk149dded2003-09-10 18:20:28 +0000705}
706
Simon Glassb9560ad2017-06-14 21:28:30 -0600707static int usb_stor_BBB_transport(struct scsi_cmd *srb, struct us_data *us)
wdenk149dded2003-09-10 18:20:28 +0000708{
709 int result, retry;
710 int dir_in;
711 int actlen, data_actlen;
712 unsigned int pipe, pipein, pipeout;
Simon Glass2e17c872015-03-25 12:22:11 -0600713 ALLOC_CACHE_ALIGN_BUFFER(struct umass_bbb_csw, csw, 1);
wdenk149dded2003-09-10 18:20:28 +0000714#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 */
Vivek Gautamceb49722013-04-12 16:34:33 +0530722 debug("COMMAND phase\n");
wdenk149dded2003-09-10 18:20:28 +0000723 result = usb_stor_BBB_comdat(srb, us);
724 if (result < 0) {
Vivek Gautamceb49722013-04-12 16:34:33 +0530725 debug("failed to send CBW status %ld\n",
726 us->pusb_dev->status);
wdenk149dded2003-09-10 18:20:28 +0000727 usb_stor_BBB_reset(us);
728 return USB_STOR_TRANSPORT_FAILED;
729 }
Benoît Thébaudeau3e8581b2012-08-10 18:27:11 +0200730 if (!(us->flags & USB_READY))
731 mdelay(5);
wdenk149dded2003-09-10 18:20:28 +0000732 pipein = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
733 pipeout = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
734 /* DATA phase + error handling */
wdenk149dded2003-09-10 18:20:28 +0000735 data_actlen = 0;
736 /* no data, go immediately to the STATUS phase */
737 if (srb->datalen == 0)
738 goto st;
Vivek Gautamceb49722013-04-12 16:34:33 +0530739 debug("DATA phase\n");
wdenk149dded2003-09-10 18:20:28 +0000740 if (dir_in)
741 pipe = pipein;
742 else
743 pipe = pipeout;
Sergey Temerkhanovf6570872015-04-01 17:18:46 +0300744
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100745 result = usb_bulk_msg(us->pusb_dev, pipe, srb->pdata, srb->datalen,
746 &data_actlen, USB_CNTL_TIMEOUT * 5);
wdenk149dded2003-09-10 18:20:28 +0000747 /* special handling of STALL in DATA phase */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100748 if ((result < 0) && (us->pusb_dev->status & USB_ST_STALLED)) {
Vivek Gautamceb49722013-04-12 16:34:33 +0530749 debug("DATA:stall\n");
wdenk149dded2003-09-10 18:20:28 +0000750 /* clear the STALL on the endpoint */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100751 result = usb_stor_BBB_clear_endpt_stall(us,
752 dir_in ? us->ep_in : us->ep_out);
wdenk149dded2003-09-10 18:20:28 +0000753 if (result >= 0)
754 /* continue on to STATUS phase */
755 goto st;
756 }
757 if (result < 0) {
Vivek Gautamceb49722013-04-12 16:34:33 +0530758 debug("usb_bulk_msg error status %ld\n",
759 us->pusb_dev->status);
wdenk149dded2003-09-10 18:20:28 +0000760 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 */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100769st:
wdenk149dded2003-09-10 18:20:28 +0000770 retry = 0;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100771again:
Vivek Gautamceb49722013-04-12 16:34:33 +0530772 debug("STATUS phase\n");
Puneet Saxenaf5766132012-04-03 14:56:06 +0530773 result = usb_bulk_msg(us->pusb_dev, pipein, csw, UMASS_BBB_CSW_SIZE,
Wolfgang Denk9c998aa2005-07-21 11:57:57 +0200774 &actlen, USB_CNTL_TIMEOUT*5);
775
wdenk149dded2003-09-10 18:20:28 +0000776 /* special handling of STALL in STATUS phase */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100777 if ((result < 0) && (retry < 1) &&
778 (us->pusb_dev->status & USB_ST_STALLED)) {
Vivek Gautamceb49722013-04-12 16:34:33 +0530779 debug("STATUS:stall\n");
wdenk149dded2003-09-10 18:20:28 +0000780 /* 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) {
Vivek Gautamceb49722013-04-12 16:34:33 +0530787 debug("usb_bulk_msg error status %ld\n",
788 us->pusb_dev->status);
wdenk149dded2003-09-10 18:20:28 +0000789 usb_stor_BBB_reset(us);
790 return USB_STOR_TRANSPORT_FAILED;
791 }
792#ifdef BBB_XPORT_TRACE
Puneet Saxenaf5766132012-04-03 14:56:06 +0530793 ptr = (unsigned char *)csw;
wdenk149dded2003-09-10 18:20:28 +0000794 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 */
Puneet Saxenaf5766132012-04-03 14:56:06 +0530799 pipe = le32_to_cpu(csw->dCSWDataResidue);
wdenk149dded2003-09-10 18:20:28 +0000800 if (pipe == 0 && srb->datalen != 0 && srb->datalen - data_actlen != 0)
801 pipe = srb->datalen - data_actlen;
Puneet Saxenaf5766132012-04-03 14:56:06 +0530802 if (CSWSIGNATURE != le32_to_cpu(csw->dCSWSignature)) {
Vivek Gautamceb49722013-04-12 16:34:33 +0530803 debug("!CSWSIGNATURE\n");
wdenk149dded2003-09-10 18:20:28 +0000804 usb_stor_BBB_reset(us);
805 return USB_STOR_TRANSPORT_FAILED;
Puneet Saxenaf5766132012-04-03 14:56:06 +0530806 } else if ((CBWTag - 1) != le32_to_cpu(csw->dCSWTag)) {
Vivek Gautamceb49722013-04-12 16:34:33 +0530807 debug("!Tag\n");
wdenk149dded2003-09-10 18:20:28 +0000808 usb_stor_BBB_reset(us);
809 return USB_STOR_TRANSPORT_FAILED;
Puneet Saxenaf5766132012-04-03 14:56:06 +0530810 } else if (csw->bCSWStatus > CSWSTATUS_PHASE) {
Vivek Gautamceb49722013-04-12 16:34:33 +0530811 debug(">PHASE\n");
wdenk149dded2003-09-10 18:20:28 +0000812 usb_stor_BBB_reset(us);
813 return USB_STOR_TRANSPORT_FAILED;
Puneet Saxenaf5766132012-04-03 14:56:06 +0530814 } else if (csw->bCSWStatus == CSWSTATUS_PHASE) {
Vivek Gautamceb49722013-04-12 16:34:33 +0530815 debug("=PHASE\n");
wdenk149dded2003-09-10 18:20:28 +0000816 usb_stor_BBB_reset(us);
817 return USB_STOR_TRANSPORT_FAILED;
818 } else if (data_actlen > srb->datalen) {
Vivek Gautamceb49722013-04-12 16:34:33 +0530819 debug("transferred %dB instead of %ldB\n",
820 data_actlen, srb->datalen);
wdenk149dded2003-09-10 18:20:28 +0000821 return USB_STOR_TRANSPORT_FAILED;
Puneet Saxenaf5766132012-04-03 14:56:06 +0530822 } else if (csw->bCSWStatus == CSWSTATUS_FAILED) {
Vivek Gautamceb49722013-04-12 16:34:33 +0530823 debug("FAILED\n");
wdenk149dded2003-09-10 18:20:28 +0000824 return USB_STOR_TRANSPORT_FAILED;
825 }
826
827 return result;
828}
829
Simon Glassb9560ad2017-06-14 21:28:30 -0600830static int usb_stor_CB_transport(struct scsi_cmd *srb, struct us_data *us)
wdenkaffae2b2002-08-17 09:36:01 +0000831{
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100832 int result, status;
Simon Glassb9560ad2017-06-14 21:28:30 -0600833 struct scsi_cmd *psrb;
834 struct scsi_cmd reqsrb;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100835 int retry, notready;
wdenkaffae2b2002-08-17 09:36:01 +0000836
Wolfgang Denkd0ff51b2008-07-14 15:19:07 +0200837 psrb = &reqsrb;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100838 status = USB_STOR_TRANSPORT_GOOD;
839 retry = 0;
840 notready = 0;
wdenkaffae2b2002-08-17 09:36:01 +0000841 /* issue the command */
842do_retry:
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100843 result = usb_stor_CB_comdat(srb, us);
Vivek Gautamceb49722013-04-12 16:34:33 +0530844 debug("command / Data returned %d, status %lX\n",
845 result, us->pusb_dev->status);
wdenkaffae2b2002-08-17 09:36:01 +0000846 /* if this is an CBI Protocol, get IRQ */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100847 if (us->protocol == US_PR_CBI) {
848 status = usb_stor_CBI_get_status(srb, us);
wdenkaffae2b2002-08-17 09:36:01 +0000849 /* if the status is error, report it */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100850 if (status == USB_STOR_TRANSPORT_ERROR) {
Vivek Gautamceb49722013-04-12 16:34:33 +0530851 debug(" USB CBI Command Error\n");
wdenkaffae2b2002-08-17 09:36:01 +0000852 return status;
853 }
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100854 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) {
Vivek Gautamceb49722013-04-12 16:34:33 +0530859 debug(" USB CBI Command Good\n");
wdenkaffae2b2002-08-17 09:36:01 +0000860 return status;
861 }
862 }
863 }
864 /* do we have to issue an auto request? */
865 /* HERE we have to check the result */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100866 if ((result < 0) && !(us->pusb_dev->status & USB_ST_STALLED)) {
Vivek Gautamceb49722013-04-12 16:34:33 +0530867 debug("ERROR %lX\n", us->pusb_dev->status);
wdenkaffae2b2002-08-17 09:36:01 +0000868 us->transport_reset(us);
869 return USB_STOR_TRANSPORT_ERROR;
870 }
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100871 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 */
Vivek Gautamceb49722013-04-12 16:34:33 +0530875 debug("No auto request and good\n");
wdenkaffae2b2002-08-17 09:36:01 +0000876 return USB_STOR_TRANSPORT_GOOD;
877 }
878 /* issue an request_sense */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100879 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;
Wolfgang Denkd0ff51b2008-07-14 15:19:07 +0200884 psrb->pdata = &srb->sense_buf[0];
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100885 psrb->cmdlen = 12;
wdenkaffae2b2002-08-17 09:36:01 +0000886 /* issue the command */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100887 result = usb_stor_CB_comdat(psrb, us);
Vivek Gautamceb49722013-04-12 16:34:33 +0530888 debug("auto request returned %d\n", result);
wdenkaffae2b2002-08-17 09:36:01 +0000889 /* if this is an CBI Protocol, get IRQ */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100890 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)) {
Vivek Gautamceb49722013-04-12 16:34:33 +0530894 debug(" AUTO REQUEST ERROR %ld\n",
895 us->pusb_dev->status);
wdenkaffae2b2002-08-17 09:36:01 +0000896 return USB_STOR_TRANSPORT_ERROR;
897 }
Vivek Gautamceb49722013-04-12 16:34:33 +0530898 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]);
wdenkaffae2b2002-08-17 09:36:01 +0000901 /* Check the auto request result */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100902 if ((srb->sense_buf[2] == 0) &&
903 (srb->sense_buf[12] == 0) &&
904 (srb->sense_buf[13] == 0)) {
905 /* ok, no sense */
wdenkaffae2b2002-08-17 09:36:01 +0000906 return USB_STOR_TRANSPORT_GOOD;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100907 }
908
wdenkaffae2b2002-08-17 09:36:01 +0000909 /* Check the auto request result */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100910 switch (srb->sense_buf[2]) {
911 case 0x01:
912 /* Recovered Error */
wdenk149dded2003-09-10 18:20:28 +0000913 return USB_STOR_TRANSPORT_GOOD;
wdenk80885a92004-02-26 23:46:20 +0000914 break;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100915 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]);
wdenk149dded2003-09-10 18:20:28 +0000922 return USB_STOR_TRANSPORT_FAILED;
923 } else {
Mike Frysinger5b84dd62012-03-05 13:47:00 +0000924 mdelay(100);
wdenk149dded2003-09-10 18:20:28 +0000925 goto do_retry;
926 }
927 break;
928 default:
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100929 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]);
wdenk149dded2003-09-10 18:20:28 +0000934 return USB_STOR_TRANSPORT_FAILED;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100935 } else
wdenk149dded2003-09-10 18:20:28 +0000936 goto do_retry;
wdenk149dded2003-09-10 18:20:28 +0000937 break;
wdenkaffae2b2002-08-17 09:36:01 +0000938 }
939 return USB_STOR_TRANSPORT_FAILED;
940}
941
Bin Mengea7fad92017-09-07 06:13:21 -0700942static void usb_stor_set_max_xfer_blk(struct usb_device *udev,
943 struct us_data *us)
Bin Meng6158d0b2017-09-07 06:13:20 -0700944{
945 unsigned short blk;
Bin Mengea7fad92017-09-07 06:13:21 -0700946 size_t __maybe_unused size;
947 int __maybe_unused ret;
Bin Meng6158d0b2017-09-07 06:13:20 -0700948
Bin Mengea7fad92017-09-07 06:13:21 -0700949#ifndef CONFIG_DM_USB
Bin Meng6158d0b2017-09-07 06:13:20 -0700950#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
Bin Mengea7fad92017-09-07 06:13:21 -0700960#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)
Bin Meng72ac8f32017-09-27 21:50:07 -0700967 size = USHRT_MAX * 512;
Bin Mengea7fad92017-09-07 06:13:21 -0700968 blk = size / 512;
969 }
970#endif
Bin Meng6158d0b2017-09-07 06:13:20 -0700971
972 us->max_xfer_blk = blk;
973}
wdenkaffae2b2002-08-17 09:36:01 +0000974
Simon Glassb9560ad2017-06-14 21:28:30 -0600975static int usb_inquiry(struct scsi_cmd *srb, struct us_data *ss)
wdenkaffae2b2002-08-17 09:36:01 +0000976{
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100977 int retry, i;
978 retry = 5;
wdenkaffae2b2002-08-17 09:36:01 +0000979 do {
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100980 memset(&srb->cmd[0], 0, 12);
981 srb->cmd[0] = SCSI_INQUIRY;
Ludovic Courtès99e9ed12010-10-05 22:04:26 +0200982 srb->cmd[1] = srb->lun << 5;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100983 srb->cmd[4] = 36;
984 srb->datalen = 36;
985 srb->cmdlen = 12;
986 i = ss->transport(srb, ss);
Vivek Gautamceb49722013-04-12 16:34:33 +0530987 debug("inquiry returns %d\n", i);
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100988 if (i == 0)
wdenkaffae2b2002-08-17 09:36:01 +0000989 break;
Kim B. Heinofac71cc2010-03-12 10:07:00 +0200990 } while (--retry);
wdenk149dded2003-09-10 18:20:28 +0000991
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100992 if (!retry) {
wdenkaffae2b2002-08-17 09:36:01 +0000993 printf("error in inquiry\n");
994 return -1;
995 }
996 return 0;
997}
998
Simon Glassb9560ad2017-06-14 21:28:30 -0600999static int usb_request_sense(struct scsi_cmd *srb, struct us_data *ss)
wdenkaffae2b2002-08-17 09:36:01 +00001000{
1001 char *ptr;
wdenk80885a92004-02-26 23:46:20 +00001002
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001003 ptr = (char *)srb->pdata;
1004 memset(&srb->cmd[0], 0, 12);
1005 srb->cmd[0] = SCSI_REQ_SENSE;
Ludovic Courtès99e9ed12010-10-05 22:04:26 +02001006 srb->cmd[1] = srb->lun << 5;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001007 srb->cmd[4] = 18;
1008 srb->datalen = 18;
Wolfgang Denkd0ff51b2008-07-14 15:19:07 +02001009 srb->pdata = &srb->sense_buf[0];
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001010 srb->cmdlen = 12;
1011 ss->transport(srb, ss);
Vivek Gautamceb49722013-04-12 16:34:33 +05301012 debug("Request Sense returned %02X %02X %02X\n",
1013 srb->sense_buf[2], srb->sense_buf[12],
1014 srb->sense_buf[13]);
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001015 srb->pdata = (uchar *)ptr;
wdenkaffae2b2002-08-17 09:36:01 +00001016 return 0;
1017}
1018
Simon Glassb9560ad2017-06-14 21:28:30 -06001019static int usb_test_unit_ready(struct scsi_cmd *srb, struct us_data *ss)
wdenkaffae2b2002-08-17 09:36:01 +00001020{
Wolfgang Denk9c998aa2005-07-21 11:57:57 +02001021 int retries = 10;
wdenk149dded2003-09-10 18:20:28 +00001022
wdenkaffae2b2002-08-17 09:36:01 +00001023 do {
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001024 memset(&srb->cmd[0], 0, 12);
1025 srb->cmd[0] = SCSI_TST_U_RDY;
Ludovic Courtès99e9ed12010-10-05 22:04:26 +02001026 srb->cmd[1] = srb->lun << 5;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001027 srb->datalen = 0;
1028 srb->cmdlen = 12;
Benoît Thébaudeau3e8581b2012-08-10 18:27:11 +02001029 if (ss->transport(srb, ss) == USB_STOR_TRANSPORT_GOOD) {
1030 ss->flags |= USB_READY;
wdenkaffae2b2002-08-17 09:36:01 +00001031 return 0;
Benoît Thébaudeau3e8581b2012-08-10 18:27:11 +02001032 }
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001033 usb_request_sense(srb, ss);
Vincent Palatin8b57e2f2012-12-12 17:55:29 -08001034 /*
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;
Mike Frysinger5b84dd62012-03-05 13:47:00 +00001044 mdelay(100);
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001045 } while (retries--);
wdenk149dded2003-09-10 18:20:28 +00001046
wdenkaffae2b2002-08-17 09:36:01 +00001047 return -1;
1048}
1049
Simon Glassb9560ad2017-06-14 21:28:30 -06001050static int usb_read_capacity(struct scsi_cmd *srb, struct us_data *ss)
wdenkaffae2b2002-08-17 09:36:01 +00001051{
1052 int retry;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001053 /* XXX retries */
1054 retry = 3;
wdenkaffae2b2002-08-17 09:36:01 +00001055 do {
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001056 memset(&srb->cmd[0], 0, 12);
1057 srb->cmd[0] = SCSI_RD_CAPAC;
Ludovic Courtès99e9ed12010-10-05 22:04:26 +02001058 srb->cmd[1] = srb->lun << 5;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001059 srb->datalen = 8;
1060 srb->cmdlen = 12;
1061 if (ss->transport(srb, ss) == USB_STOR_TRANSPORT_GOOD)
wdenkaffae2b2002-08-17 09:36:01 +00001062 return 0;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001063 } while (retry--);
wdenk149dded2003-09-10 18:20:28 +00001064
wdenkaffae2b2002-08-17 09:36:01 +00001065 return -1;
1066}
1067
Simon Glassb9560ad2017-06-14 21:28:30 -06001068static int usb_read_10(struct scsi_cmd *srb, struct us_data *ss,
1069 unsigned long start, unsigned short blocks)
wdenkaffae2b2002-08-17 09:36:01 +00001070{
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001071 memset(&srb->cmd[0], 0, 12);
1072 srb->cmd[0] = SCSI_READ10;
Ludovic Courtès99e9ed12010-10-05 22:04:26 +02001073 srb->cmd[1] = srb->lun << 5;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001074 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;
Vivek Gautamceb49722013-04-12 16:34:33 +05301081 debug("read10: start %lx blocks %x\n", start, blocks);
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001082 return ss->transport(srb, ss);
wdenkaffae2b2002-08-17 09:36:01 +00001083}
1084
Simon Glassb9560ad2017-06-14 21:28:30 -06001085static int usb_write_10(struct scsi_cmd *srb, struct us_data *ss,
1086 unsigned long start, unsigned short blocks)
Mahavir Jain127e1082009-11-03 12:22:10 +05301087{
1088 memset(&srb->cmd[0], 0, 12);
1089 srb->cmd[0] = SCSI_WRITE10;
Ludovic Courtès99e9ed12010-10-05 22:04:26 +02001090 srb->cmd[1] = srb->lun << 5;
Mahavir Jain127e1082009-11-03 12:22:10 +05301091 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;
Vivek Gautamceb49722013-04-12 16:34:33 +05301098 debug("write10: start %lx blocks %x\n", start, blocks);
Mahavir Jain127e1082009-11-03 12:22:10 +05301099 return ss->transport(srb, ss);
1100}
1101
wdenkaffae2b2002-08-17 09:36:01 +00001102
Bartlomiej Siekaddde6b72006-08-22 10:38:18 +02001103#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
Simon Glass4101f682016-02-29 15:25:34 -07001111 * struct blk_desc in include/part.h.
Bartlomiej Siekaddde6b72006-08-22 10:38:18 +02001112 */
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) {
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001119 strncpy((char *)vendor, "SMSC", max_vendor_len);
1120 strncpy((char *)product, "Flash Media Cntrller",
1121 max_product_len);
Bartlomiej Siekaddde6b72006-08-22 10:38:18 +02001122 }
1123}
1124#endif /* CONFIG_USB_BIN_FIXUP */
1125
Simon Glass07b2b782016-02-29 15:25:58 -07001126#ifdef CONFIG_BLK
1127static unsigned long usb_stor_read(struct udevice *dev, lbaint_t blknr,
1128 lbaint_t blkcnt, void *buffer)
1129#else
Simon Glass4101f682016-02-29 15:25:34 -07001130static unsigned long usb_stor_read(struct blk_desc *block_dev, lbaint_t blknr,
Stephen Warren7c4213f2015-12-07 11:38:48 -07001131 lbaint_t blkcnt, void *buffer)
Simon Glass07b2b782016-02-29 15:25:58 -07001132#endif
wdenkaffae2b2002-08-17 09:36:01 +00001133{
Gabe Blacke81e79e2012-10-12 14:26:07 +00001134 lbaint_t start, blks;
1135 uintptr_t buf_addr;
wdenkaffae2b2002-08-17 09:36:01 +00001136 unsigned short smallblks;
Simon Glass9807c3b2016-02-29 15:25:54 -07001137 struct usb_device *udev;
Kyle Moffett5dd95cf2011-12-21 07:08:12 +00001138 struct us_data *ss;
Simon Glass84073b62015-03-25 12:22:13 -06001139 int retry;
Simon Glassb9560ad2017-06-14 21:28:30 -06001140 struct scsi_cmd *srb = &usb_ccb;
Simon Glass07b2b782016-02-29 15:25:58 -07001141#ifdef CONFIG_BLK
1142 struct blk_desc *block_dev;
1143#endif
wdenkf8d813e2004-03-02 14:05:39 +00001144
1145 if (blkcnt == 0)
1146 return 0;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001147 /* Setup device */
Simon Glass07b2b782016-02-29 15:25:58 -07001148#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
Simon Glass9807c3b2016-02-29 15:25:54 -07001153 debug("\nusb_read: udev %d\n", block_dev->devnum);
1154 udev = usb_dev_desc[block_dev->devnum].priv;
1155 if (!udev) {
Simon Glass84073b62015-03-25 12:22:13 -06001156 debug("%s: No device\n", __func__);
1157 return 0;
wdenkaffae2b2002-08-17 09:36:01 +00001158 }
Simon Glass07b2b782016-02-29 15:25:58 -07001159#endif
Simon Glass9807c3b2016-02-29 15:25:54 -07001160 ss = (struct us_data *)udev->privptr;
wdenkaffae2b2002-08-17 09:36:01 +00001161
1162 usb_disable_asynch(1); /* asynch transfer not allowed */
Simon Glass9807c3b2016-02-29 15:25:54 -07001163 srb->lun = block_dev->lun;
Sergey Temerkhanovf6570872015-04-01 17:18:46 +03001164 buf_addr = (uintptr_t)buffer;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001165 start = blknr;
1166 blks = blkcnt;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001167
Simon Glass9807c3b2016-02-29 15:25:54 -07001168 debug("\nusb_read: dev %d startblk " LBAF ", blccnt " LBAF " buffer %"
1169 PRIxPTR "\n", block_dev->devnum, start, blks, buf_addr);
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001170
wdenkaffae2b2002-08-17 09:36:01 +00001171 do {
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001172 /* XXX need some comment here */
1173 retry = 2;
1174 srb->pdata = (unsigned char *)buf_addr;
Bin Meng6158d0b2017-09-07 06:13:20 -07001175 if (blks > ss->max_xfer_blk)
1176 smallblks = ss->max_xfer_blk;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001177 else
1178 smallblks = (unsigned short) blks;
wdenkaffae2b2002-08-17 09:36:01 +00001179retry_it:
Bin Meng6158d0b2017-09-07 06:13:20 -07001180 if (smallblks == ss->max_xfer_blk)
wdenkaffae2b2002-08-17 09:36:01 +00001181 usb_show_progress();
Simon Glass9807c3b2016-02-29 15:25:54 -07001182 srb->datalen = block_dev->blksz * smallblks;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001183 srb->pdata = (unsigned char *)buf_addr;
Kyle Moffett5dd95cf2011-12-21 07:08:12 +00001184 if (usb_read_10(srb, ss, start, smallblks)) {
Vivek Gautamceb49722013-04-12 16:34:33 +05301185 debug("Read ERROR\n");
Kyle Moffett5dd95cf2011-12-21 07:08:12 +00001186 usb_request_sense(srb, ss);
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001187 if (retry--)
wdenkaffae2b2002-08-17 09:36:01 +00001188 goto retry_it;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001189 blkcnt -= blks;
wdenkaffae2b2002-08-17 09:36:01 +00001190 break;
1191 }
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001192 start += smallblks;
1193 blks -= smallblks;
1194 buf_addr += srb->datalen;
1195 } while (blks != 0);
Benoît Thébaudeau3e8581b2012-08-10 18:27:11 +02001196 ss->flags &= ~USB_READY;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001197
Vivek Gautamceb49722013-04-12 16:34:33 +05301198 debug("usb_read: end startblk " LBAF
Simon Glass4fd074d2014-10-15 04:38:38 -06001199 ", blccnt %x buffer %" PRIxPTR "\n",
Vivek Gautamceb49722013-04-12 16:34:33 +05301200 start, smallblks, buf_addr);
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001201
wdenkaffae2b2002-08-17 09:36:01 +00001202 usb_disable_asynch(0); /* asynch transfer allowed */
Bin Meng6158d0b2017-09-07 06:13:20 -07001203 if (blkcnt >= ss->max_xfer_blk)
Wolfgang Denk226fa9b2010-07-19 11:36:59 +02001204 debug("\n");
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001205 return blkcnt;
wdenkaffae2b2002-08-17 09:36:01 +00001206}
1207
Simon Glass07b2b782016-02-29 15:25:58 -07001208#ifdef CONFIG_BLK
1209static unsigned long usb_stor_write(struct udevice *dev, lbaint_t blknr,
1210 lbaint_t blkcnt, const void *buffer)
1211#else
Simon Glass4101f682016-02-29 15:25:34 -07001212static unsigned long usb_stor_write(struct blk_desc *block_dev, lbaint_t blknr,
Stephen Warren7c4213f2015-12-07 11:38:48 -07001213 lbaint_t blkcnt, const void *buffer)
Simon Glass07b2b782016-02-29 15:25:58 -07001214#endif
Mahavir Jain127e1082009-11-03 12:22:10 +05301215{
Gabe Blacke81e79e2012-10-12 14:26:07 +00001216 lbaint_t start, blks;
1217 uintptr_t buf_addr;
Mahavir Jain127e1082009-11-03 12:22:10 +05301218 unsigned short smallblks;
Simon Glass9807c3b2016-02-29 15:25:54 -07001219 struct usb_device *udev;
Kyle Moffett5dd95cf2011-12-21 07:08:12 +00001220 struct us_data *ss;
Simon Glass84073b62015-03-25 12:22:13 -06001221 int retry;
Simon Glassb9560ad2017-06-14 21:28:30 -06001222 struct scsi_cmd *srb = &usb_ccb;
Simon Glass07b2b782016-02-29 15:25:58 -07001223#ifdef CONFIG_BLK
1224 struct blk_desc *block_dev;
1225#endif
Mahavir Jain127e1082009-11-03 12:22:10 +05301226
1227 if (blkcnt == 0)
1228 return 0;
1229
Mahavir Jain127e1082009-11-03 12:22:10 +05301230 /* Setup device */
Simon Glass07b2b782016-02-29 15:25:58 -07001231#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
Simon Glass9807c3b2016-02-29 15:25:54 -07001236 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__);
Simon Glass84073b62015-03-25 12:22:13 -06001240 return 0;
Simon Glass9807c3b2016-02-29 15:25:54 -07001241 }
Simon Glass07b2b782016-02-29 15:25:58 -07001242#endif
Simon Glass9807c3b2016-02-29 15:25:54 -07001243 ss = (struct us_data *)udev->privptr;
Mahavir Jain127e1082009-11-03 12:22:10 +05301244
1245 usb_disable_asynch(1); /* asynch transfer not allowed */
1246
Simon Glass9807c3b2016-02-29 15:25:54 -07001247 srb->lun = block_dev->lun;
Sergey Temerkhanovf6570872015-04-01 17:18:46 +03001248 buf_addr = (uintptr_t)buffer;
Mahavir Jain127e1082009-11-03 12:22:10 +05301249 start = blknr;
1250 blks = blkcnt;
Mahavir Jain127e1082009-11-03 12:22:10 +05301251
Simon Glass9807c3b2016-02-29 15:25:54 -07001252 debug("\nusb_write: dev %d startblk " LBAF ", blccnt " LBAF " buffer %"
1253 PRIxPTR "\n", block_dev->devnum, start, blks, buf_addr);
Mahavir Jain127e1082009-11-03 12:22:10 +05301254
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;
Bin Meng6158d0b2017-09-07 06:13:20 -07001261 if (blks > ss->max_xfer_blk)
1262 smallblks = ss->max_xfer_blk;
Mahavir Jain127e1082009-11-03 12:22:10 +05301263 else
1264 smallblks = (unsigned short) blks;
1265retry_it:
Bin Meng6158d0b2017-09-07 06:13:20 -07001266 if (smallblks == ss->max_xfer_blk)
Mahavir Jain127e1082009-11-03 12:22:10 +05301267 usb_show_progress();
Simon Glass9807c3b2016-02-29 15:25:54 -07001268 srb->datalen = block_dev->blksz * smallblks;
Mahavir Jain127e1082009-11-03 12:22:10 +05301269 srb->pdata = (unsigned char *)buf_addr;
Kyle Moffett5dd95cf2011-12-21 07:08:12 +00001270 if (usb_write_10(srb, ss, start, smallblks)) {
Vivek Gautamceb49722013-04-12 16:34:33 +05301271 debug("Write ERROR\n");
Kyle Moffett5dd95cf2011-12-21 07:08:12 +00001272 usb_request_sense(srb, ss);
Mahavir Jain127e1082009-11-03 12:22:10 +05301273 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);
Benoît Thébaudeau3e8581b2012-08-10 18:27:11 +02001282 ss->flags &= ~USB_READY;
Mahavir Jain127e1082009-11-03 12:22:10 +05301283
Simon Glass4fd074d2014-10-15 04:38:38 -06001284 debug("usb_write: end startblk " LBAF ", blccnt %x buffer %"
1285 PRIxPTR "\n", start, smallblks, buf_addr);
Mahavir Jain127e1082009-11-03 12:22:10 +05301286
1287 usb_disable_asynch(0); /* asynch transfer allowed */
Bin Meng6158d0b2017-09-07 06:13:20 -07001288 if (blkcnt >= ss->max_xfer_blk)
Wolfgang Denk226fa9b2010-07-19 11:36:59 +02001289 debug("\n");
Mahavir Jain127e1082009-11-03 12:22:10 +05301290 return blkcnt;
1291
1292}
wdenkaffae2b2002-08-17 09:36:01 +00001293
1294/* Probe to see if a new device is actually a Storage device */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001295int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,
1296 struct us_data *ss)
wdenkaffae2b2002-08-17 09:36:01 +00001297{
Tom Rix8f8bd562009-10-31 12:37:38 -05001298 struct usb_interface *iface;
wdenkaffae2b2002-08-17 09:36:01 +00001299 int i;
Vivek Gautam605bd752013-04-12 16:34:34 +05301300 struct usb_endpoint_descriptor *ep_desc;
wdenkaffae2b2002-08-17 09:36:01 +00001301 unsigned int flags = 0;
1302
wdenkaffae2b2002-08-17 09:36:01 +00001303 /* let's examine the device now */
1304 iface = &dev->config.if_desc[ifnum];
1305
wdenkaffae2b2002-08-17 09:36:01 +00001306 if (dev->descriptor.bDeviceClass != 0 ||
Tom Rix8f8bd562009-10-31 12:37:38 -05001307 iface->desc.bInterfaceClass != USB_CLASS_MASS_STORAGE ||
1308 iface->desc.bInterfaceSubClass < US_SC_MIN ||
1309 iface->desc.bInterfaceSubClass > US_SC_MAX) {
Simon Glass1d5827a2015-03-25 12:22:12 -06001310 debug("Not mass storage\n");
wdenkaffae2b2002-08-17 09:36:01 +00001311 /* if it's not a mass storage, we go no further */
1312 return 0;
1313 }
1314
Wolfgang Denk9c998aa2005-07-21 11:57:57 +02001315 memset(ss, 0, sizeof(struct us_data));
1316
wdenkaffae2b2002-08-17 09:36:01 +00001317 /* At this point, we know we've got a live one */
Vivek Gautamceb49722013-04-12 16:34:33 +05301318 debug("\n\nUSB Mass Storage device detected\n");
wdenkaffae2b2002-08-17 09:36:01 +00001319
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;
Tom Rinif5fb78a2015-10-11 07:26:27 -04001325 ss->subclass = iface->desc.bInterfaceSubClass;
1326 ss->protocol = iface->desc.bInterfaceProtocol;
wdenkaffae2b2002-08-17 09:36:01 +00001327
1328 /* set the handler pointers based on the protocol */
Vivek Gautamceb49722013-04-12 16:34:33 +05301329 debug("Transport: ");
wdenkaffae2b2002-08-17 09:36:01 +00001330 switch (ss->protocol) {
1331 case US_PR_CB:
Vivek Gautamceb49722013-04-12 16:34:33 +05301332 debug("Control/Bulk\n");
wdenkaffae2b2002-08-17 09:36:01 +00001333 ss->transport = usb_stor_CB_transport;
1334 ss->transport_reset = usb_stor_CB_reset;
1335 break;
1336
1337 case US_PR_CBI:
Vivek Gautamceb49722013-04-12 16:34:33 +05301338 debug("Control/Bulk/Interrupt\n");
wdenkaffae2b2002-08-17 09:36:01 +00001339 ss->transport = usb_stor_CB_transport;
1340 ss->transport_reset = usb_stor_CB_reset;
1341 break;
wdenk149dded2003-09-10 18:20:28 +00001342 case US_PR_BULK:
Vivek Gautamceb49722013-04-12 16:34:33 +05301343 debug("Bulk/Bulk/Bulk\n");
wdenk149dded2003-09-10 18:20:28 +00001344 ss->transport = usb_stor_BBB_transport;
1345 ss->transport_reset = usb_stor_BBB_reset;
1346 break;
wdenkaffae2b2002-08-17 09:36:01 +00001347 default:
wdenk80885a92004-02-26 23:46:20 +00001348 printf("USB Storage Transport unknown / not yet implemented\n");
wdenkaffae2b2002-08-17 09:36:01 +00001349 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 */
Tom Rix8f8bd562009-10-31 12:37:38 -05001358 for (i = 0; i < iface->desc.bNumEndpoints; i++) {
Vivek Gautam605bd752013-04-12 16:34:34 +05301359 ep_desc = &iface->ep_desc[i];
wdenkaffae2b2002-08-17 09:36:01 +00001360 /* is it an BULK endpoint? */
Vivek Gautam605bd752013-04-12 16:34:34 +05301361 if ((ep_desc->bmAttributes &
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001362 USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) {
Vivek Gautam605bd752013-04-12 16:34:34 +05301363 if (ep_desc->bEndpointAddress & USB_DIR_IN)
1364 ss->ep_in = ep_desc->bEndpointAddress &
1365 USB_ENDPOINT_NUMBER_MASK;
wdenkaffae2b2002-08-17 09:36:01 +00001366 else
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001367 ss->ep_out =
Vivek Gautam605bd752013-04-12 16:34:34 +05301368 ep_desc->bEndpointAddress &
wdenkaffae2b2002-08-17 09:36:01 +00001369 USB_ENDPOINT_NUMBER_MASK;
1370 }
1371
1372 /* is it an interrupt endpoint? */
Vivek Gautam605bd752013-04-12 16:34:34 +05301373 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;
wdenkaffae2b2002-08-17 09:36:01 +00001378 }
1379 }
Vivek Gautamceb49722013-04-12 16:34:33 +05301380 debug("Endpoints In %d Out %d Int %d\n",
1381 ss->ep_in, ss->ep_out, ss->ep_int);
wdenkaffae2b2002-08-17 09:36:01 +00001382
1383 /* Do some basic sanity checks, and bail if we find a problem */
Tom Rix8f8bd562009-10-31 12:37:38 -05001384 if (usb_set_interface(dev, iface->desc.bInterfaceNumber, 0) ||
wdenkaffae2b2002-08-17 09:36:01 +00001385 !ss->ep_in || !ss->ep_out ||
1386 (ss->protocol == US_PR_CBI && ss->ep_int == 0)) {
Vivek Gautamceb49722013-04-12 16:34:33 +05301387 debug("Problems with device\n");
wdenkaffae2b2002-08-17 09:36:01 +00001388 return 0;
1389 }
1390 /* set class specific stuff */
wdenk149dded2003-09-10 18:20:28 +00001391 /* We only handle certain protocols. Currently, these are
1392 * the only ones.
wdenk80885a92004-02-26 23:46:20 +00001393 * The SFF8070 accepts the requests used in u-boot
wdenkaffae2b2002-08-17 09:36:01 +00001394 */
wdenk80885a92004-02-26 23:46:20 +00001395 if (ss->subclass != US_SC_UFI && ss->subclass != US_SC_SCSI &&
1396 ss->subclass != US_SC_8070) {
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001397 printf("Sorry, protocol %d not yet supported.\n", ss->subclass);
wdenkaffae2b2002-08-17 09:36:01 +00001398 return 0;
1399 }
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001400 if (ss->ep_int) {
1401 /* we had found an interrupt endpoint, prepare irq pipe
1402 * set up the IRQ pipe and handler
1403 */
wdenkaffae2b2002-08-17 09:36:01 +00001404 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);
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001407 dev->irq_handle = usb_stor_irq;
wdenkaffae2b2002-08-17 09:36:01 +00001408 }
Bin Meng6158d0b2017-09-07 06:13:20 -07001409
1410 /* Set the maximum transfer size per host controller setting */
Bin Mengea7fad92017-09-07 06:13:21 -07001411 usb_stor_set_max_xfer_blk(dev, ss);
Bin Meng6158d0b2017-09-07 06:13:20 -07001412
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001413 dev->privptr = (void *)ss;
wdenkaffae2b2002-08-17 09:36:01 +00001414 return 1;
1415}
1416
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001417int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
Simon Glass4101f682016-02-29 15:25:34 -07001418 struct blk_desc *dev_desc)
wdenkaffae2b2002-08-17 09:36:01 +00001419{
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001420 unsigned char perq, modi;
Sergey Temerkhanovf6570872015-04-01 17:18:46 +03001421 ALLOC_CACHE_ALIGN_BUFFER(u32, cap, 2);
1422 ALLOC_CACHE_ALIGN_BUFFER(u8, usb_stor_buf, 36);
1423 u32 capacity, blksz;
Simon Glassb9560ad2017-06-14 21:28:30 -06001424 struct scsi_cmd *pccb = &usb_ccb;
wdenkaffae2b2002-08-17 09:36:01 +00001425
Wolfgang Denk9c998aa2005-07-21 11:57:57 +02001426 pccb->pdata = usb_stor_buf;
1427
1428 dev_desc->target = dev->devnum;
1429 pccb->lun = dev_desc->lun;
Vivek Gautamceb49722013-04-12 16:34:33 +05301430 debug(" address %d\n", dev_desc->target);
wdenkaffae2b2002-08-17 09:36:01 +00001431
Simon Glass1d5827a2015-03-25 12:22:12 -06001432 if (usb_inquiry(pccb, ss)) {
1433 debug("%s: usb_inquiry() failed\n", __func__);
wdenkaffae2b2002-08-17 09:36:01 +00001434 return -1;
Simon Glass1d5827a2015-03-25 12:22:12 -06001435 }
Wolfgang Denk095b8a32005-08-02 17:06:17 +02001436
Wolfgang Denk9c998aa2005-07-21 11:57:57 +02001437 perq = usb_stor_buf[0];
1438 modi = usb_stor_buf[1];
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001439
Soeren Moch6a559bb2014-11-08 07:02:14 +01001440 /*
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)) {
Simon Glass1d5827a2015-03-25 12:22:12 -06001445 debug("%s: unknown/unsupported device\n", __func__);
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001446 return 0;
wdenkaffae2b2002-08-17 09:36:01 +00001447 }
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001448 if ((modi&0x80) == 0x80) {
1449 /* drive is removable */
Wolfgang Denk9c998aa2005-07-21 11:57:57 +02001450 dev_desc->removable = 1;
wdenkaffae2b2002-08-17 09:36:01 +00001451 }
Sergey Temerkhanovf6570872015-04-01 17:18:46 +03001452 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);
Wolfgang Denk9c998aa2005-07-21 11:57:57 +02001455 dev_desc->vendor[8] = 0;
1456 dev_desc->product[16] = 0;
1457 dev_desc->revision[4] = 0;
Bartlomiej Siekaddde6b72006-08-22 10:38:18 +02001458#ifdef CONFIG_USB_BIN_FIXUP
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001459 usb_bin_fixup(dev->descriptor, (uchar *)dev_desc->vendor,
1460 (uchar *)dev_desc->product);
Bartlomiej Siekaddde6b72006-08-22 10:38:18 +02001461#endif /* CONFIG_USB_BIN_FIXUP */
Vivek Gautamceb49722013-04-12 16:34:33 +05301462 debug("ISO Vers %X, Response Data %X\n", usb_stor_buf[2],
1463 usb_stor_buf[3]);
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001464 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]);
Troy Kisky1e5eca72017-04-10 18:23:11 -07001469 if (dev_desc->removable == 1)
Wolfgang Denk9c998aa2005-07-21 11:57:57 +02001470 dev_desc->type = perq;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001471 return 0;
wdenkaffae2b2002-08-17 09:36:01 +00001472 }
Sergey Temerkhanovf6570872015-04-01 17:18:46 +03001473 pccb->pdata = (unsigned char *)cap;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001474 memset(pccb->pdata, 0, 8);
1475 if (usb_read_capacity(pccb, ss) != 0) {
wdenkaffae2b2002-08-17 09:36:01 +00001476 printf("READ_CAP ERROR\n");
Wolfgang Denk9c998aa2005-07-21 11:57:57 +02001477 cap[0] = 2880;
1478 cap[1] = 0x200;
wdenkaffae2b2002-08-17 09:36:01 +00001479 }
Benoît Thébaudeau3e8581b2012-08-10 18:27:11 +02001480 ss->flags &= ~USB_READY;
Sergey Temerkhanovf6570872015-04-01 17:18:46 +03001481 debug("Read Capacity returns: 0x%08x, 0x%08x\n", cap[0], cap[1]);
wdenkaffae2b2002-08-17 09:36:01 +00001482#if 0
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001483 if (cap[0] > (0x200000 * 10)) /* greater than 10 GByte */
1484 cap[0] >>= 16;
Sergey Temerkhanovf6570872015-04-01 17:18:46 +03001485
Christian Eggersc9182612008-05-21 22:12:00 +02001486 cap[0] = cpu_to_be32(cap[0]);
1487 cap[1] = cpu_to_be32(cap[1]);
Sergey Temerkhanovf6570872015-04-01 17:18:46 +03001488#endif
Christian Eggersc9182612008-05-21 22:12:00 +02001489
Sergey Temerkhanovf6570872015-04-01 17:18:46 +03001490 capacity = be32_to_cpu(cap[0]) + 1;
1491 blksz = be32_to_cpu(cap[1]);
1492
1493 debug("Capacity = 0x%08x, blocksz = 0x%08x\n", capacity, blksz);
1494 dev_desc->lba = capacity;
1495 dev_desc->blksz = blksz;
Egbert Eich0472fbf2013-04-09 21:11:56 +00001496 dev_desc->log2blksz = LOG2(dev_desc->blksz);
Wolfgang Denk9c998aa2005-07-21 11:57:57 +02001497 dev_desc->type = perq;
Vivek Gautamceb49722013-04-12 16:34:33 +05301498 debug(" address %d\n", dev_desc->target);
wdenkaffae2b2002-08-17 09:36:01 +00001499
wdenkaffae2b2002-08-17 09:36:01 +00001500 return 1;
1501}
Simon Glassacf277a2015-03-25 12:22:16 -06001502
1503#ifdef CONFIG_DM_USB
1504
1505static int usb_mass_storage_probe(struct udevice *dev)
1506{
Simon Glassbcbe3d12015-09-28 23:32:01 -06001507 struct usb_device *udev = dev_get_parent_priv(dev);
Simon Glassacf277a2015-03-25 12:22:16 -06001508 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,
Simon Glass07b2b782016-02-29 15:25:58 -07001527#ifdef CONFIG_BLK
1528 .platdata_auto_alloc_size = sizeof(struct us_data),
1529#endif
Simon Glassacf277a2015-03-25 12:22:16 -06001530};
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
Simon Glassabb59cf2015-07-06 16:47:51 -06001545U_BOOT_USB_DEVICE(usb_mass_storage, mass_storage_id_table);
Simon Glass07b2b782016-02-29 15:25:58 -07001546#endif
Simon Glassacf277a2015-03-25 12:22:16 -06001547
Simon Glass07b2b782016-02-29 15:25:58 -07001548#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};
Simon Glassc0543bf2016-05-01 11:36:06 -06001559#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};
Simon Glassacf277a2015-03-25 12:22:16 -06001566#endif