blob: fb322b4015fe0ba2ea72d82a1f7171ae7bfee2e3 [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
wdenkaffae2b2002-08-17 09:36:01 +000012 *
wdenk149dded2003-09-10 18:20:28 +000013 * For BBB support (C) Copyright 2003
Detlev Zundel792a09e2009-05-13 10:54:10 +020014 * Gary Jennejohn, DENX Software Engineering <garyj@denx.de>
wdenk149dded2003-09-10 18:20:28 +000015 *
Wolfgang Denk460c3222005-08-04 01:14:12 +020016 * BBB support based on /sys/dev/usb/umass.c from
wdenk149dded2003-09-10 18:20:28 +000017 * FreeBSD.
wdenkaffae2b2002-08-17 09:36:01 +000018 *
19 * See file CREDITS for list of people who contributed to this
20 * project.
21 *
22 * This program is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU General Public License as
24 * published by the Free Software Foundation; either version 2 of
25 * the License, or (at your option) any later version.
26 *
27 * This program is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
wdenk80885a92004-02-26 23:46:20 +000029 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
wdenkaffae2b2002-08-17 09:36:01 +000030 * GNU General Public License for more details.
31 *
32 * You should have received a copy of the GNU General Public License
33 * along with this program; if not, write to the Free Software
34 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
35 * MA 02111-1307 USA
36 *
37 */
38
39/* Note:
40 * Currently only the CBI transport protocoll has been implemented, and it
41 * is only tested with a TEAC USB Floppy. Other Massstorages with CBI or CB
42 * transport protocoll may work as well.
43 */
wdenk149dded2003-09-10 18:20:28 +000044/*
45 * New Note:
46 * Support for USB Mass Storage Devices (BBB) has been added. It has
47 * only been tested with USB memory sticks.
wdenk149dded2003-09-10 18:20:28 +000048 */
wdenkaffae2b2002-08-17 09:36:01 +000049
50
wdenkaffae2b2002-08-17 09:36:01 +000051#include <common.h>
52#include <command.h>
Christian Eggersc9182612008-05-21 22:12:00 +020053#include <asm/byteorder.h>
wdenkaffae2b2002-08-17 09:36:01 +000054#include <asm/processor.h>
55
Grant Likely735dd972007-02-20 09:04:34 +010056#include <part.h>
wdenkaffae2b2002-08-17 09:36:01 +000057#include <usb.h>
58
wdenk80885a92004-02-26 23:46:20 +000059#undef BBB_COMDAT_TRACE
60#undef BBB_XPORT_TRACE
wdenkaffae2b2002-08-17 09:36:01 +000061
62#ifdef USB_STOR_DEBUG
Marek Vasut86bd3ff2011-10-25 11:39:16 +020063#define USB_BLK_DEBUG 1
wdenkaffae2b2002-08-17 09:36:01 +000064#else
Marek Vasut86bd3ff2011-10-25 11:39:16 +020065#define USB_BLK_DEBUG 0
wdenkaffae2b2002-08-17 09:36:01 +000066#endif
67
Marek Vasut86bd3ff2011-10-25 11:39:16 +020068#define USB_STOR_PRINTF(fmt, args...) debug_cond(USB_BLK_DEBUG, fmt, ##args)
69
wdenkaffae2b2002-08-17 09:36:01 +000070#include <scsi.h>
71/* direction table -- this indicates the direction of the data
72 * transfer for each command code -- a 1 indicates input
73 */
Mike Frysinger2ff122852010-10-20 07:16:04 -040074static const unsigned char us_direction[256/8] = {
wdenkaffae2b2002-08-17 09:36:01 +000075 0x28, 0x81, 0x14, 0x14, 0x20, 0x01, 0x90, 0x77,
76 0x0C, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
77 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01,
78 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
79};
80#define US_DIRECTION(x) ((us_direction[x>>3] >> (x & 7)) & 1)
81
Puneet Saxenaf5766132012-04-03 14:56:06 +053082static ccb usb_ccb __attribute__((aligned(ARCH_DMA_MINALIGN)));
wdenkaffae2b2002-08-17 09:36:01 +000083
84/*
85 * CBI style
86 */
87
88#define US_CBI_ADSC 0
89
wdenk149dded2003-09-10 18:20:28 +000090/*
91 * BULK only
92 */
93#define US_BBB_RESET 0xff
94#define US_BBB_GET_MAX_LUN 0xfe
95
96/* Command Block Wrapper */
97typedef struct {
98 __u32 dCBWSignature;
99# define CBWSIGNATURE 0x43425355
100 __u32 dCBWTag;
101 __u32 dCBWDataTransferLength;
102 __u8 bCBWFlags;
103# define CBWFLAGS_OUT 0x00
104# define CBWFLAGS_IN 0x80
105 __u8 bCBWLUN;
106 __u8 bCDBLength;
107# define CBWCDBLENGTH 16
108 __u8 CBWCDB[CBWCDBLENGTH];
109} umass_bbb_cbw_t;
wdenk80885a92004-02-26 23:46:20 +0000110#define UMASS_BBB_CBW_SIZE 31
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100111static __u32 CBWTag;
wdenk149dded2003-09-10 18:20:28 +0000112
113/* Command Status Wrapper */
114typedef struct {
115 __u32 dCSWSignature;
116# define CSWSIGNATURE 0x53425355
117 __u32 dCSWTag;
118 __u32 dCSWDataResidue;
119 __u8 bCSWStatus;
120# define CSWSTATUS_GOOD 0x0
wdenk80885a92004-02-26 23:46:20 +0000121# define CSWSTATUS_FAILED 0x1
wdenk149dded2003-09-10 18:20:28 +0000122# define CSWSTATUS_PHASE 0x2
123} umass_bbb_csw_t;
wdenk80885a92004-02-26 23:46:20 +0000124#define UMASS_BBB_CSW_SIZE 13
wdenkaffae2b2002-08-17 09:36:01 +0000125
126#define USB_MAX_STOR_DEV 5
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100127static int usb_max_devs; /* number of highest available usb device */
wdenkaffae2b2002-08-17 09:36:01 +0000128
129static block_dev_desc_t usb_dev_desc[USB_MAX_STOR_DEV];
130
131struct us_data;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100132typedef int (*trans_cmnd)(ccb *cb, struct us_data *data);
133typedef int (*trans_reset)(struct us_data *data);
wdenkaffae2b2002-08-17 09:36:01 +0000134
135struct us_data {
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100136 struct usb_device *pusb_dev; /* this usb_device */
137
138 unsigned int flags; /* from filter initially */
Benoît Thébaudeau3e8581b2012-08-10 18:27:11 +0200139# define USB_READY (1 << 0)
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100140 unsigned char ifnum; /* interface number */
141 unsigned char ep_in; /* in endpoint */
142 unsigned char ep_out; /* out ....... */
143 unsigned char ep_int; /* interrupt . */
144 unsigned char subclass; /* as in overview */
145 unsigned char protocol; /* .............. */
146 unsigned char attention_done; /* force attn on first cmd */
147 unsigned short ip_data; /* interrupt data */
148 int action; /* what to do */
149 int ip_wanted; /* needed */
150 int *irq_handle; /* for USB int requests */
151 unsigned int irqpipe; /* pipe for release_irq */
152 unsigned char irqmaxp; /* max packed for irq Pipe */
153 unsigned char irqinterval; /* Intervall for IRQ Pipe */
154 ccb *srb; /* current srb */
155 trans_reset transport_reset; /* reset routine */
156 trans_cmnd transport; /* transport routine */
wdenkaffae2b2002-08-17 09:36:01 +0000157};
158
Benoît Thébaudeaucffcc502012-08-10 18:26:50 +0200159#ifdef CONFIG_USB_EHCI
Stefan Herbrechtsmeier1b4bd0e2012-07-09 09:52:29 +0000160/*
Benoît Thébaudeau4bee5c82012-08-10 18:23:25 +0200161 * The U-Boot EHCI driver can handle any transfer length as long as there is
162 * enough free heap space left, but the SCSI READ(10) and WRITE(10) commands are
163 * limited to 65535 blocks.
Stefan Herbrechtsmeier1b4bd0e2012-07-09 09:52:29 +0000164 */
Benoît Thébaudeau4bee5c82012-08-10 18:23:25 +0200165#define USB_MAX_XFER_BLK 65535
Benoît Thébaudeaucffcc502012-08-10 18:26:50 +0200166#else
Benoît Thébaudeau4bee5c82012-08-10 18:23:25 +0200167#define USB_MAX_XFER_BLK 20
Benoît Thébaudeaucffcc502012-08-10 18:26:50 +0200168#endif
Stefan Herbrechtsmeier1b4bd0e2012-07-09 09:52:29 +0000169
wdenkaffae2b2002-08-17 09:36:01 +0000170static struct us_data usb_stor[USB_MAX_STOR_DEV];
171
172
wdenk80885a92004-02-26 23:46:20 +0000173#define USB_STOR_TRANSPORT_GOOD 0
wdenkaffae2b2002-08-17 09:36:01 +0000174#define USB_STOR_TRANSPORT_FAILED -1
175#define USB_STOR_TRANSPORT_ERROR -2
176
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100177int usb_stor_get_info(struct usb_device *dev, struct us_data *us,
178 block_dev_desc_t *dev_desc);
179int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,
180 struct us_data *ss);
181unsigned long usb_stor_read(int device, unsigned long blknr,
Gabe Blacke81e79e2012-10-12 14:26:07 +0000182 lbaint_t blkcnt, void *buffer);
Mahavir Jain127e1082009-11-03 12:22:10 +0530183unsigned long usb_stor_write(int device, unsigned long blknr,
Gabe Blacke81e79e2012-10-12 14:26:07 +0000184 lbaint_t blkcnt, const void *buffer);
wdenkaffae2b2002-08-17 09:36:01 +0000185struct usb_device * usb_get_dev_index(int index);
186void uhci_show_temp_int_td(void);
187
Matthew McClintockdf3fc522011-05-24 05:31:19 +0000188#ifdef CONFIG_PARTITIONS
wdenkaffae2b2002-08-17 09:36:01 +0000189block_dev_desc_t *usb_stor_get_dev(int index)
190{
Kim B. Heinoaaad1082010-03-12 15:46:56 +0200191 return (index < usb_max_devs) ? &usb_dev_desc[index] : NULL;
wdenkaffae2b2002-08-17 09:36:01 +0000192}
Matthew McClintockdf3fc522011-05-24 05:31:19 +0000193#endif
wdenkaffae2b2002-08-17 09:36:01 +0000194
Kim Phillips199adb62012-10-29 13:34:32 +0000195static void usb_show_progress(void)
wdenkaffae2b2002-08-17 09:36:01 +0000196{
Wolfgang Denk226fa9b2010-07-19 11:36:59 +0200197 debug(".");
wdenkaffae2b2002-08-17 09:36:01 +0000198}
199
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100200/*******************************************************************************
Wolfgang Denk9c998aa2005-07-21 11:57:57 +0200201 * show info on storage devices; 'usb start/init' must be invoked earlier
202 * as we only retrieve structures populated during devices initialization
203 */
Aras Vaichasf6b44e02008-03-25 12:09:07 +1100204int usb_stor_info(void)
Wolfgang Denk9c998aa2005-07-21 11:57:57 +0200205{
206 int i;
207
Aras Vaichasf6b44e02008-03-25 12:09:07 +1100208 if (usb_max_devs > 0) {
Wolfgang Denk9c998aa2005-07-21 11:57:57 +0200209 for (i = 0; i < usb_max_devs; i++) {
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100210 printf(" Device %d: ", i);
Wolfgang Denk9c998aa2005-07-21 11:57:57 +0200211 dev_print(&usb_dev_desc[i]);
212 }
Markus Klotzbuecherb9e749e2008-03-26 18:26:43 +0100213 return 0;
Aras Vaichasf6b44e02008-03-25 12:09:07 +1100214 }
Wolfgang Denk1aeed8d2008-04-13 09:59:26 -0700215
Markus Klotzbuecherb9e749e2008-03-26 18:26:43 +0100216 printf("No storage devices, perhaps not 'usb start'ed..?\n");
217 return 1;
Wolfgang Denk9c998aa2005-07-21 11:57:57 +0200218}
219
Ludovic Courtès99e9ed12010-10-05 22:04:26 +0200220static unsigned int usb_get_max_lun(struct us_data *us)
221{
222 int len;
Puneet Saxenaf5766132012-04-03 14:56:06 +0530223 ALLOC_CACHE_ALIGN_BUFFER(unsigned char, result, 1);
Ludovic Courtès99e9ed12010-10-05 22:04:26 +0200224 len = usb_control_msg(us->pusb_dev,
225 usb_rcvctrlpipe(us->pusb_dev, 0),
226 US_BBB_GET_MAX_LUN,
227 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
228 0, us->ifnum,
Puneet Saxenaf5766132012-04-03 14:56:06 +0530229 result, sizeof(char),
Ludovic Courtès99e9ed12010-10-05 22:04:26 +0200230 USB_CNTL_TIMEOUT * 5);
231 USB_STOR_PRINTF("Get Max LUN -> len = %i, result = %i\n",
Puneet Saxenaf5766132012-04-03 14:56:06 +0530232 len, (int) *result);
233 return (len > 0) ? *result : 0;
Ludovic Courtès99e9ed12010-10-05 22:04:26 +0200234}
235
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100236/*******************************************************************************
Wolfgang Denk9c998aa2005-07-21 11:57:57 +0200237 * scan the usb and reports device info
wdenkaffae2b2002-08-17 09:36:01 +0000238 * to the user if mode = 1
239 * returns current device or -1 if no
240 */
241int usb_stor_scan(int mode)
242{
243 unsigned char i;
244 struct usb_device *dev;
245
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100246 if (mode == 1)
Lucas Stach93c25822012-09-26 00:14:36 +0200247 printf(" scanning usb for storage devices... ");
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100248
wdenkaffae2b2002-08-17 09:36:01 +0000249 usb_disable_asynch(1); /* asynch transfer not allowed */
250
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100251 for (i = 0; i < USB_MAX_STOR_DEV; i++) {
252 memset(&usb_dev_desc[i], 0, sizeof(block_dev_desc_t));
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100253 usb_dev_desc[i].if_type = IF_TYPE_USB;
254 usb_dev_desc[i].dev = i;
255 usb_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
Wolfgang Denka17c5482010-07-19 11:36:56 +0200256 usb_dev_desc[i].target = 0xff;
257 usb_dev_desc[i].type = DEV_TYPE_UNKNOWN;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100258 usb_dev_desc[i].block_read = usb_stor_read;
Mahavir Jain127e1082009-11-03 12:22:10 +0530259 usb_dev_desc[i].block_write = usb_stor_write;
wdenkaffae2b2002-08-17 09:36:01 +0000260 }
Wolfgang Denk9c998aa2005-07-21 11:57:57 +0200261
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100262 usb_max_devs = 0;
263 for (i = 0; i < USB_MAX_DEVICE; i++) {
264 dev = usb_get_dev_index(i); /* get device */
265 USB_STOR_PRINTF("i=%d\n", i);
266 if (dev == NULL)
Loïc Minier6052cba2011-02-03 22:04:26 +0100267 break; /* no more devices available */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100268
269 if (usb_storage_probe(dev, 0, &usb_stor[usb_max_devs])) {
Ludovic Courtès99e9ed12010-10-05 22:04:26 +0200270 /* OK, it's a storage device. Iterate over its LUNs
271 * and populate `usb_dev_desc'.
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100272 */
Ludovic Courtès99e9ed12010-10-05 22:04:26 +0200273 int lun, max_lun, start = usb_max_devs;
274
275 max_lun = usb_get_max_lun(&usb_stor[usb_max_devs]);
276 for (lun = 0;
277 lun <= max_lun && usb_max_devs < USB_MAX_STOR_DEV;
278 lun++) {
279 usb_dev_desc[usb_max_devs].lun = lun;
280 if (usb_stor_get_info(dev, &usb_stor[start],
281 &usb_dev_desc[usb_max_devs]) == 1) {
wdenkaffae2b2002-08-17 09:36:01 +0000282 usb_max_devs++;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100283 }
Ludovic Courtès99e9ed12010-10-05 22:04:26 +0200284 }
285 }
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100286 /* if storage device */
287 if (usb_max_devs == USB_MAX_STOR_DEV) {
288 printf("max USB Storage Device reached: %d stopping\n",
289 usb_max_devs);
wdenkaffae2b2002-08-17 09:36:01 +0000290 break;
291 }
292 } /* for */
Wolfgang Denk095b8a32005-08-02 17:06:17 +0200293
wdenkaffae2b2002-08-17 09:36:01 +0000294 usb_disable_asynch(0); /* asynch transfer allowed */
Wolfgang Denk9c998aa2005-07-21 11:57:57 +0200295 printf("%d Storage Device(s) found\n", usb_max_devs);
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100296 if (usb_max_devs > 0)
wdenkaffae2b2002-08-17 09:36:01 +0000297 return 0;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100298 return -1;
wdenkaffae2b2002-08-17 09:36:01 +0000299}
300
301static int usb_stor_irq(struct usb_device *dev)
302{
303 struct us_data *us;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100304 us = (struct us_data *)dev->privptr;
wdenkaffae2b2002-08-17 09:36:01 +0000305
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100306 if (us->ip_wanted)
307 us->ip_wanted = 0;
wdenkaffae2b2002-08-17 09:36:01 +0000308 return 0;
309}
310
311
312#ifdef USB_STOR_DEBUG
313
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100314static void usb_show_srb(ccb *pccb)
wdenkaffae2b2002-08-17 09:36:01 +0000315{
316 int i;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100317 printf("SRB: len %d datalen 0x%lX\n ", pccb->cmdlen, pccb->datalen);
318 for (i = 0; i < 12; i++)
319 printf("%02X ", pccb->cmd[i]);
wdenkaffae2b2002-08-17 09:36:01 +0000320 printf("\n");
321}
322
323static void display_int_status(unsigned long tmp)
324{
325 printf("Status: %s %s %s %s %s %s %s\n",
326 (tmp & USB_ST_ACTIVE) ? "Active" : "",
327 (tmp & USB_ST_STALLED) ? "Stalled" : "",
328 (tmp & USB_ST_BUF_ERR) ? "Buffer Error" : "",
329 (tmp & USB_ST_BABBLE_DET) ? "Babble Det" : "",
330 (tmp & USB_ST_NAK_REC) ? "NAKed" : "",
331 (tmp & USB_ST_CRC_ERR) ? "CRC Error" : "",
332 (tmp & USB_ST_BIT_ERR) ? "Bitstuff Error" : "");
333}
334#endif
335/***********************************************************************
336 * Data transfer routines
337 ***********************************************************************/
338
339static int us_one_transfer(struct us_data *us, int pipe, char *buf, int length)
340{
341 int max_size;
342 int this_xfer;
343 int result;
344 int partial;
345 int maxtry;
346 int stat;
347
348 /* determine the maximum packet size for these transfers */
349 max_size = usb_maxpacket(us->pusb_dev, pipe) * 16;
350
351 /* while we have data left to transfer */
352 while (length) {
353
354 /* calculate how long this will be -- maximum or a remainder */
355 this_xfer = length > max_size ? max_size : length;
356 length -= this_xfer;
357
358 /* setup the retry counter */
359 maxtry = 10;
360
361 /* set up the transfer loop */
362 do {
363 /* transfer the data */
364 USB_STOR_PRINTF("Bulk xfer 0x%x(%d) try #%d\n",
365 (unsigned int)buf, this_xfer, 11 - maxtry);
366 result = usb_bulk_msg(us->pusb_dev, pipe, buf,
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100367 this_xfer, &partial,
368 USB_CNTL_TIMEOUT * 5);
wdenkaffae2b2002-08-17 09:36:01 +0000369 USB_STOR_PRINTF("bulk_msg returned %d xferred %d/%d\n",
370 result, partial, this_xfer);
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100371 if (us->pusb_dev->status != 0) {
372 /* if we stall, we need to clear it before
373 * we go on
374 */
wdenkaffae2b2002-08-17 09:36:01 +0000375#ifdef USB_STOR_DEBUG
376 display_int_status(us->pusb_dev->status);
377#endif
378 if (us->pusb_dev->status & USB_ST_STALLED) {
379 USB_STOR_PRINTF("stalled ->clearing endpoint halt for pipe 0x%x\n", pipe);
380 stat = us->pusb_dev->status;
381 usb_clear_halt(us->pusb_dev, pipe);
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100382 us->pusb_dev->status = stat;
383 if (this_xfer == partial) {
Marek Vasut4b210e82011-10-25 11:39:17 +0200384 USB_STOR_PRINTF("bulk transferred with error %lX, but data ok\n", us->pusb_dev->status);
wdenkaffae2b2002-08-17 09:36:01 +0000385 return 0;
386 }
387 else
388 return result;
389 }
390 if (us->pusb_dev->status & USB_ST_NAK_REC) {
391 USB_STOR_PRINTF("Device NAKed bulk_msg\n");
392 return result;
393 }
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100394 USB_STOR_PRINTF("bulk transferred with error");
395 if (this_xfer == partial) {
Marek Vasut4b210e82011-10-25 11:39:17 +0200396 USB_STOR_PRINTF(" %ld, but data ok\n",
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100397 us->pusb_dev->status);
wdenkaffae2b2002-08-17 09:36:01 +0000398 return 0;
399 }
400 /* if our try counter reaches 0, bail out */
Marek Vasut4b210e82011-10-25 11:39:17 +0200401 USB_STOR_PRINTF(" %ld, data %d\n",
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100402 us->pusb_dev->status, partial);
wdenkaffae2b2002-08-17 09:36:01 +0000403 if (!maxtry--)
404 return result;
405 }
406 /* update to show what data was transferred */
407 this_xfer -= partial;
408 buf += partial;
409 /* continue until this transfer is done */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100410 } while (this_xfer);
wdenkaffae2b2002-08-17 09:36:01 +0000411 }
412
413 /* if we get here, we're done and successful */
414 return 0;
415}
416
wdenk149dded2003-09-10 18:20:28 +0000417static int usb_stor_BBB_reset(struct us_data *us)
418{
419 int result;
420 unsigned int pipe;
421
422 /*
423 * Reset recovery (5.3.4 in Universal Serial Bus Mass Storage Class)
424 *
425 * For Reset Recovery the host shall issue in the following order:
426 * a) a Bulk-Only Mass Storage Reset
427 * b) a Clear Feature HALT to the Bulk-In endpoint
428 * c) a Clear Feature HALT to the Bulk-Out endpoint
429 *
430 * This is done in 3 steps.
431 *
432 * If the reset doesn't succeed, the device should be port reset.
433 *
434 * This comment stolen from FreeBSD's /sys/dev/usb/umass.c.
435 */
436 USB_STOR_PRINTF("BBB_reset\n");
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100437 result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev, 0),
438 US_BBB_RESET,
439 USB_TYPE_CLASS | USB_RECIP_INTERFACE,
Kim Phillips199adb62012-10-29 13:34:32 +0000440 0, us->ifnum, NULL, 0, USB_CNTL_TIMEOUT * 5);
Wolfgang Denk9c998aa2005-07-21 11:57:57 +0200441
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100442 if ((result < 0) && (us->pusb_dev->status & USB_ST_STALLED)) {
wdenk149dded2003-09-10 18:20:28 +0000443 USB_STOR_PRINTF("RESET:stall\n");
444 return -1;
445 }
Wolfgang Denk9c998aa2005-07-21 11:57:57 +0200446
wdenk149dded2003-09-10 18:20:28 +0000447 /* long wait for reset */
Mike Frysinger5b84dd62012-03-05 13:47:00 +0000448 mdelay(150);
Marek Vasut4b210e82011-10-25 11:39:17 +0200449 USB_STOR_PRINTF("BBB_reset result %d: status %lX reset\n", result,
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100450 us->pusb_dev->status);
wdenk149dded2003-09-10 18:20:28 +0000451 pipe = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
452 result = usb_clear_halt(us->pusb_dev, pipe);
453 /* long wait for reset */
Mike Frysinger5b84dd62012-03-05 13:47:00 +0000454 mdelay(150);
Marek Vasut4b210e82011-10-25 11:39:17 +0200455 USB_STOR_PRINTF("BBB_reset result %d: status %lX clearing IN endpoint\n",
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100456 result, us->pusb_dev->status);
wdenk149dded2003-09-10 18:20:28 +0000457 /* long wait for reset */
458 pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
459 result = usb_clear_halt(us->pusb_dev, pipe);
Mike Frysinger5b84dd62012-03-05 13:47:00 +0000460 mdelay(150);
Marek Vasut4b210e82011-10-25 11:39:17 +0200461 USB_STOR_PRINTF("BBB_reset result %d: status %lX"
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100462 " clearing OUT endpoint\n", result,
463 us->pusb_dev->status);
wdenk149dded2003-09-10 18:20:28 +0000464 USB_STOR_PRINTF("BBB_reset done\n");
465 return 0;
466}
467
wdenkaffae2b2002-08-17 09:36:01 +0000468/* FIXME: this reset function doesn't really reset the port, and it
469 * should. Actually it should probably do what it's doing here, and
470 * reset the port physically
471 */
472static int usb_stor_CB_reset(struct us_data *us)
473{
474 unsigned char cmd[12];
475 int result;
476
477 USB_STOR_PRINTF("CB_reset\n");
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100478 memset(cmd, 0xff, sizeof(cmd));
wdenkaffae2b2002-08-17 09:36:01 +0000479 cmd[0] = SCSI_SEND_DIAG;
480 cmd[1] = 4;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100481 result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev, 0),
482 US_CBI_ADSC,
483 USB_TYPE_CLASS | USB_RECIP_INTERFACE,
484 0, us->ifnum, cmd, sizeof(cmd),
485 USB_CNTL_TIMEOUT * 5);
wdenkaffae2b2002-08-17 09:36:01 +0000486
487 /* long wait for reset */
Mike Frysinger5b84dd62012-03-05 13:47:00 +0000488 mdelay(1500);
Marek Vasut4b210e82011-10-25 11:39:17 +0200489 USB_STOR_PRINTF("CB_reset result %d: status %lX"
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100490 " clearing endpoint halt\n", result,
491 us->pusb_dev->status);
wdenkaffae2b2002-08-17 09:36:01 +0000492 usb_clear_halt(us->pusb_dev, usb_rcvbulkpipe(us->pusb_dev, us->ep_in));
493 usb_clear_halt(us->pusb_dev, usb_rcvbulkpipe(us->pusb_dev, us->ep_out));
494
495 USB_STOR_PRINTF("CB_reset done\n");
496 return 0;
497}
498
wdenk149dded2003-09-10 18:20:28 +0000499/*
500 * Set up the command for a BBB device. Note that the actual SCSI
501 * command is copied into cbw.CBWCDB.
502 */
Kim Phillips199adb62012-10-29 13:34:32 +0000503static int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
wdenk149dded2003-09-10 18:20:28 +0000504{
505 int result;
506 int actlen;
507 int dir_in;
508 unsigned int pipe;
Puneet Saxenaf5766132012-04-03 14:56:06 +0530509 ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_cbw_t, cbw, 1);
wdenk149dded2003-09-10 18:20:28 +0000510
511 dir_in = US_DIRECTION(srb->cmd[0]);
512
513#ifdef BBB_COMDAT_TRACE
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100514 printf("dir %d lun %d cmdlen %d cmd %p datalen %d pdata %p\n",
515 dir_in, srb->lun, srb->cmdlen, srb->cmd, srb->datalen,
516 srb->pdata);
wdenk149dded2003-09-10 18:20:28 +0000517 if (srb->cmdlen) {
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100518 for (result = 0; result < srb->cmdlen; result++)
wdenk149dded2003-09-10 18:20:28 +0000519 printf("cmd[%d] %#x ", result, srb->cmd[result]);
520 printf("\n");
521 }
522#endif
523 /* sanity checks */
524 if (!(srb->cmdlen <= CBWCDBLENGTH)) {
525 USB_STOR_PRINTF("usb_stor_BBB_comdat:cmdlen too large\n");
526 return -1;
527 }
528
529 /* always OUT to the ep */
530 pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
531
Puneet Saxenaf5766132012-04-03 14:56:06 +0530532 cbw->dCBWSignature = cpu_to_le32(CBWSIGNATURE);
533 cbw->dCBWTag = cpu_to_le32(CBWTag++);
534 cbw->dCBWDataTransferLength = cpu_to_le32(srb->datalen);
535 cbw->bCBWFlags = (dir_in ? CBWFLAGS_IN : CBWFLAGS_OUT);
536 cbw->bCBWLUN = srb->lun;
537 cbw->bCDBLength = srb->cmdlen;
wdenk149dded2003-09-10 18:20:28 +0000538 /* copy the command data into the CBW command data buffer */
539 /* DST SRC LEN!!! */
Puneet Saxenaf5766132012-04-03 14:56:06 +0530540 memcpy(cbw->CBWCDB, srb->cmd, srb->cmdlen);
541 result = usb_bulk_msg(us->pusb_dev, pipe, cbw, UMASS_BBB_CBW_SIZE,
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100542 &actlen, USB_CNTL_TIMEOUT * 5);
wdenk149dded2003-09-10 18:20:28 +0000543 if (result < 0)
544 USB_STOR_PRINTF("usb_stor_BBB_comdat:usb_bulk_msg error\n");
545 return result;
546}
547
wdenkaffae2b2002-08-17 09:36:01 +0000548/* FIXME: we also need a CBI_command which sets up the completion
549 * interrupt, and waits for it
550 */
Kim Phillips199adb62012-10-29 13:34:32 +0000551static int usb_stor_CB_comdat(ccb *srb, struct us_data *us)
wdenkaffae2b2002-08-17 09:36:01 +0000552{
Wolfgang Denk77ddac92005-10-13 16:45:02 +0200553 int result = 0;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100554 int dir_in, retry;
wdenkaffae2b2002-08-17 09:36:01 +0000555 unsigned int pipe;
556 unsigned long status;
557
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100558 retry = 5;
559 dir_in = US_DIRECTION(srb->cmd[0]);
wdenkaffae2b2002-08-17 09:36:01 +0000560
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100561 if (dir_in)
562 pipe = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
563 else
564 pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
565
566 while (retry--) {
567 USB_STOR_PRINTF("CBI gets a command: Try %d\n", 5 - retry);
wdenkaffae2b2002-08-17 09:36:01 +0000568#ifdef USB_STOR_DEBUG
569 usb_show_srb(srb);
570#endif
571 /* let's send the command via the control pipe */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100572 result = usb_control_msg(us->pusb_dev,
573 usb_sndctrlpipe(us->pusb_dev , 0),
574 US_CBI_ADSC,
575 USB_TYPE_CLASS | USB_RECIP_INTERFACE,
wdenkaffae2b2002-08-17 09:36:01 +0000576 0, us->ifnum,
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100577 srb->cmd, srb->cmdlen,
578 USB_CNTL_TIMEOUT * 5);
579 USB_STOR_PRINTF("CB_transport: control msg returned %d,"
Marek Vasut4b210e82011-10-25 11:39:17 +0200580 " status %lX\n", result, us->pusb_dev->status);
wdenkaffae2b2002-08-17 09:36:01 +0000581 /* check the return code for the command */
582 if (result < 0) {
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100583 if (us->pusb_dev->status & USB_ST_STALLED) {
584 status = us->pusb_dev->status;
585 USB_STOR_PRINTF(" stall during command found,"
586 " clear pipe\n");
587 usb_clear_halt(us->pusb_dev,
588 usb_sndctrlpipe(us->pusb_dev, 0));
589 us->pusb_dev->status = status;
wdenkaffae2b2002-08-17 09:36:01 +0000590 }
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100591 USB_STOR_PRINTF(" error during command %02X"
Marek Vasut4b210e82011-10-25 11:39:17 +0200592 " Stat = %lX\n", srb->cmd[0],
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100593 us->pusb_dev->status);
wdenkaffae2b2002-08-17 09:36:01 +0000594 return result;
595 }
596 /* transfer the data payload for this command, if one exists*/
597
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100598 USB_STOR_PRINTF("CB_transport: control msg returned %d,"
599 " direction is %s to go 0x%lx\n", result,
600 dir_in ? "IN" : "OUT", srb->datalen);
wdenkaffae2b2002-08-17 09:36:01 +0000601 if (srb->datalen) {
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100602 result = us_one_transfer(us, pipe, (char *)srb->pdata,
603 srb->datalen);
604 USB_STOR_PRINTF("CBI attempted to transfer data,"
605 " result is %d status %lX, len %d\n",
606 result, us->pusb_dev->status,
607 us->pusb_dev->act_len);
608 if (!(us->pusb_dev->status & USB_ST_NAK_REC))
wdenkaffae2b2002-08-17 09:36:01 +0000609 break;
610 } /* if (srb->datalen) */
611 else
612 break;
613 }
614 /* return result */
615
616 return result;
617}
618
619
Kim Phillips199adb62012-10-29 13:34:32 +0000620static int usb_stor_CBI_get_status(ccb *srb, struct us_data *us)
wdenkaffae2b2002-08-17 09:36:01 +0000621{
622 int timeout;
623
wdenk80885a92004-02-26 23:46:20 +0000624 us->ip_wanted = 1;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100625 submit_int_msg(us->pusb_dev, us->irqpipe,
wdenk80885a92004-02-26 23:46:20 +0000626 (void *) &us->ip_data, us->irqmaxp, us->irqinterval);
627 timeout = 1000;
628 while (timeout--) {
Kim Phillips199adb62012-10-29 13:34:32 +0000629 if ((volatile int *) us->ip_wanted == NULL)
wdenkaffae2b2002-08-17 09:36:01 +0000630 break;
Mike Frysinger5b84dd62012-03-05 13:47:00 +0000631 mdelay(10);
wdenkaffae2b2002-08-17 09:36:01 +0000632 }
633 if (us->ip_wanted) {
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100634 printf(" Did not get interrupt on CBI\n");
wdenkaffae2b2002-08-17 09:36:01 +0000635 us->ip_wanted = 0;
636 return USB_STOR_TRANSPORT_ERROR;
637 }
wdenk80885a92004-02-26 23:46:20 +0000638 USB_STOR_PRINTF
639 ("Got interrupt data 0x%x, transfered %d status 0x%lX\n",
640 us->ip_data, us->pusb_dev->irq_act_len,
641 us->pusb_dev->irq_status);
wdenkaffae2b2002-08-17 09:36:01 +0000642 /* UFI gives us ASC and ASCQ, like a request sense */
643 if (us->subclass == US_SC_UFI) {
644 if (srb->cmd[0] == SCSI_REQ_SENSE ||
645 srb->cmd[0] == SCSI_INQUIRY)
646 return USB_STOR_TRANSPORT_GOOD; /* Good */
wdenk80885a92004-02-26 23:46:20 +0000647 else if (us->ip_data)
648 return USB_STOR_TRANSPORT_FAILED;
wdenkaffae2b2002-08-17 09:36:01 +0000649 else
wdenk80885a92004-02-26 23:46:20 +0000650 return USB_STOR_TRANSPORT_GOOD;
wdenkaffae2b2002-08-17 09:36:01 +0000651 }
652 /* otherwise, we interpret the data normally */
653 switch (us->ip_data) {
wdenk80885a92004-02-26 23:46:20 +0000654 case 0x0001:
655 return USB_STOR_TRANSPORT_GOOD;
656 case 0x0002:
657 return USB_STOR_TRANSPORT_FAILED;
658 default:
659 return USB_STOR_TRANSPORT_ERROR;
660 } /* switch */
wdenkaffae2b2002-08-17 09:36:01 +0000661 return USB_STOR_TRANSPORT_ERROR;
662}
663
664#define USB_TRANSPORT_UNKNOWN_RETRY 5
665#define USB_TRANSPORT_NOT_READY_RETRY 10
666
wdenk149dded2003-09-10 18:20:28 +0000667/* clear a stall on an endpoint - special for BBB devices */
Kim Phillips199adb62012-10-29 13:34:32 +0000668static int usb_stor_BBB_clear_endpt_stall(struct us_data *us, __u8 endpt)
wdenk149dded2003-09-10 18:20:28 +0000669{
670 int result;
671
672 /* ENDPOINT_HALT = 0, so set value to 0 */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100673 result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev, 0),
wdenk149dded2003-09-10 18:20:28 +0000674 USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT,
Kim Phillips199adb62012-10-29 13:34:32 +0000675 0, endpt, NULL, 0, USB_CNTL_TIMEOUT * 5);
wdenk149dded2003-09-10 18:20:28 +0000676 return result;
677}
678
Kim Phillips199adb62012-10-29 13:34:32 +0000679static int usb_stor_BBB_transport(ccb *srb, struct us_data *us)
wdenk149dded2003-09-10 18:20:28 +0000680{
681 int result, retry;
682 int dir_in;
683 int actlen, data_actlen;
684 unsigned int pipe, pipein, pipeout;
Puneet Saxenaf5766132012-04-03 14:56:06 +0530685 ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_csw_t, csw, 1);
wdenk149dded2003-09-10 18:20:28 +0000686#ifdef BBB_XPORT_TRACE
687 unsigned char *ptr;
688 int index;
689#endif
690
691 dir_in = US_DIRECTION(srb->cmd[0]);
692
693 /* COMMAND phase */
694 USB_STOR_PRINTF("COMMAND phase\n");
695 result = usb_stor_BBB_comdat(srb, us);
696 if (result < 0) {
697 USB_STOR_PRINTF("failed to send CBW status %ld\n",
698 us->pusb_dev->status);
699 usb_stor_BBB_reset(us);
700 return USB_STOR_TRANSPORT_FAILED;
701 }
Benoît Thébaudeau3e8581b2012-08-10 18:27:11 +0200702 if (!(us->flags & USB_READY))
703 mdelay(5);
wdenk149dded2003-09-10 18:20:28 +0000704 pipein = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
705 pipeout = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
706 /* DATA phase + error handling */
wdenk149dded2003-09-10 18:20:28 +0000707 data_actlen = 0;
708 /* no data, go immediately to the STATUS phase */
709 if (srb->datalen == 0)
710 goto st;
wdenk80885a92004-02-26 23:46:20 +0000711 USB_STOR_PRINTF("DATA phase\n");
wdenk149dded2003-09-10 18:20:28 +0000712 if (dir_in)
713 pipe = pipein;
714 else
715 pipe = pipeout;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100716 result = usb_bulk_msg(us->pusb_dev, pipe, srb->pdata, srb->datalen,
717 &data_actlen, USB_CNTL_TIMEOUT * 5);
wdenk149dded2003-09-10 18:20:28 +0000718 /* special handling of STALL in DATA phase */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100719 if ((result < 0) && (us->pusb_dev->status & USB_ST_STALLED)) {
wdenka43278a2003-09-11 19:48:06 +0000720 USB_STOR_PRINTF("DATA:stall\n");
wdenk149dded2003-09-10 18:20:28 +0000721 /* clear the STALL on the endpoint */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100722 result = usb_stor_BBB_clear_endpt_stall(us,
723 dir_in ? us->ep_in : us->ep_out);
wdenk149dded2003-09-10 18:20:28 +0000724 if (result >= 0)
725 /* continue on to STATUS phase */
726 goto st;
727 }
728 if (result < 0) {
729 USB_STOR_PRINTF("usb_bulk_msg error status %ld\n",
730 us->pusb_dev->status);
731 usb_stor_BBB_reset(us);
732 return USB_STOR_TRANSPORT_FAILED;
733 }
734#ifdef BBB_XPORT_TRACE
735 for (index = 0; index < data_actlen; index++)
736 printf("pdata[%d] %#x ", index, srb->pdata[index]);
737 printf("\n");
738#endif
739 /* STATUS phase + error handling */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100740st:
wdenk149dded2003-09-10 18:20:28 +0000741 retry = 0;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100742again:
wdenk149dded2003-09-10 18:20:28 +0000743 USB_STOR_PRINTF("STATUS phase\n");
Puneet Saxenaf5766132012-04-03 14:56:06 +0530744 result = usb_bulk_msg(us->pusb_dev, pipein, csw, UMASS_BBB_CSW_SIZE,
Wolfgang Denk9c998aa2005-07-21 11:57:57 +0200745 &actlen, USB_CNTL_TIMEOUT*5);
746
wdenk149dded2003-09-10 18:20:28 +0000747 /* special handling of STALL in STATUS phase */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100748 if ((result < 0) && (retry < 1) &&
749 (us->pusb_dev->status & USB_ST_STALLED)) {
wdenk149dded2003-09-10 18:20:28 +0000750 USB_STOR_PRINTF("STATUS:stall\n");
751 /* clear the STALL on the endpoint */
752 result = usb_stor_BBB_clear_endpt_stall(us, us->ep_in);
753 if (result >= 0 && (retry++ < 1))
754 /* do a retry */
755 goto again;
756 }
757 if (result < 0) {
758 USB_STOR_PRINTF("usb_bulk_msg error status %ld\n",
759 us->pusb_dev->status);
760 usb_stor_BBB_reset(us);
761 return USB_STOR_TRANSPORT_FAILED;
762 }
763#ifdef BBB_XPORT_TRACE
Puneet Saxenaf5766132012-04-03 14:56:06 +0530764 ptr = (unsigned char *)csw;
wdenk149dded2003-09-10 18:20:28 +0000765 for (index = 0; index < UMASS_BBB_CSW_SIZE; index++)
766 printf("ptr[%d] %#x ", index, ptr[index]);
767 printf("\n");
768#endif
769 /* misuse pipe to get the residue */
Puneet Saxenaf5766132012-04-03 14:56:06 +0530770 pipe = le32_to_cpu(csw->dCSWDataResidue);
wdenk149dded2003-09-10 18:20:28 +0000771 if (pipe == 0 && srb->datalen != 0 && srb->datalen - data_actlen != 0)
772 pipe = srb->datalen - data_actlen;
Puneet Saxenaf5766132012-04-03 14:56:06 +0530773 if (CSWSIGNATURE != le32_to_cpu(csw->dCSWSignature)) {
wdenk149dded2003-09-10 18:20:28 +0000774 USB_STOR_PRINTF("!CSWSIGNATURE\n");
775 usb_stor_BBB_reset(us);
776 return USB_STOR_TRANSPORT_FAILED;
Puneet Saxenaf5766132012-04-03 14:56:06 +0530777 } else if ((CBWTag - 1) != le32_to_cpu(csw->dCSWTag)) {
wdenk149dded2003-09-10 18:20:28 +0000778 USB_STOR_PRINTF("!Tag\n");
779 usb_stor_BBB_reset(us);
780 return USB_STOR_TRANSPORT_FAILED;
Puneet Saxenaf5766132012-04-03 14:56:06 +0530781 } else if (csw->bCSWStatus > CSWSTATUS_PHASE) {
wdenk149dded2003-09-10 18:20:28 +0000782 USB_STOR_PRINTF(">PHASE\n");
783 usb_stor_BBB_reset(us);
784 return USB_STOR_TRANSPORT_FAILED;
Puneet Saxenaf5766132012-04-03 14:56:06 +0530785 } else if (csw->bCSWStatus == CSWSTATUS_PHASE) {
wdenk149dded2003-09-10 18:20:28 +0000786 USB_STOR_PRINTF("=PHASE\n");
787 usb_stor_BBB_reset(us);
788 return USB_STOR_TRANSPORT_FAILED;
789 } else if (data_actlen > srb->datalen) {
Marek Vasut4b210e82011-10-25 11:39:17 +0200790 USB_STOR_PRINTF("transferred %dB instead of %ldB\n",
wdenk149dded2003-09-10 18:20:28 +0000791 data_actlen, srb->datalen);
792 return USB_STOR_TRANSPORT_FAILED;
Puneet Saxenaf5766132012-04-03 14:56:06 +0530793 } else if (csw->bCSWStatus == CSWSTATUS_FAILED) {
wdenk149dded2003-09-10 18:20:28 +0000794 USB_STOR_PRINTF("FAILED\n");
795 return USB_STOR_TRANSPORT_FAILED;
796 }
797
798 return result;
799}
800
Kim Phillips199adb62012-10-29 13:34:32 +0000801static int usb_stor_CB_transport(ccb *srb, struct us_data *us)
wdenkaffae2b2002-08-17 09:36:01 +0000802{
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100803 int result, status;
wdenkaffae2b2002-08-17 09:36:01 +0000804 ccb *psrb;
805 ccb reqsrb;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100806 int retry, notready;
wdenkaffae2b2002-08-17 09:36:01 +0000807
Wolfgang Denkd0ff51b2008-07-14 15:19:07 +0200808 psrb = &reqsrb;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100809 status = USB_STOR_TRANSPORT_GOOD;
810 retry = 0;
811 notready = 0;
wdenkaffae2b2002-08-17 09:36:01 +0000812 /* issue the command */
813do_retry:
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100814 result = usb_stor_CB_comdat(srb, us);
Marek Vasut4b210e82011-10-25 11:39:17 +0200815 USB_STOR_PRINTF("command / Data returned %d, status %lX\n",
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100816 result, us->pusb_dev->status);
wdenkaffae2b2002-08-17 09:36:01 +0000817 /* if this is an CBI Protocol, get IRQ */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100818 if (us->protocol == US_PR_CBI) {
819 status = usb_stor_CBI_get_status(srb, us);
wdenkaffae2b2002-08-17 09:36:01 +0000820 /* if the status is error, report it */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100821 if (status == USB_STOR_TRANSPORT_ERROR) {
wdenkaffae2b2002-08-17 09:36:01 +0000822 USB_STOR_PRINTF(" USB CBI Command Error\n");
823 return status;
824 }
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100825 srb->sense_buf[12] = (unsigned char)(us->ip_data >> 8);
826 srb->sense_buf[13] = (unsigned char)(us->ip_data & 0xff);
827 if (!us->ip_data) {
828 /* if the status is good, report it */
829 if (status == USB_STOR_TRANSPORT_GOOD) {
wdenkaffae2b2002-08-17 09:36:01 +0000830 USB_STOR_PRINTF(" USB CBI Command Good\n");
831 return status;
832 }
833 }
834 }
835 /* do we have to issue an auto request? */
836 /* HERE we have to check the result */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100837 if ((result < 0) && !(us->pusb_dev->status & USB_ST_STALLED)) {
Marek Vasut4b210e82011-10-25 11:39:17 +0200838 USB_STOR_PRINTF("ERROR %lX\n", us->pusb_dev->status);
wdenkaffae2b2002-08-17 09:36:01 +0000839 us->transport_reset(us);
840 return USB_STOR_TRANSPORT_ERROR;
841 }
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100842 if ((us->protocol == US_PR_CBI) &&
843 ((srb->cmd[0] == SCSI_REQ_SENSE) ||
844 (srb->cmd[0] == SCSI_INQUIRY))) {
845 /* do not issue an autorequest after request sense */
wdenkaffae2b2002-08-17 09:36:01 +0000846 USB_STOR_PRINTF("No auto request and good\n");
847 return USB_STOR_TRANSPORT_GOOD;
848 }
849 /* issue an request_sense */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100850 memset(&psrb->cmd[0], 0, 12);
851 psrb->cmd[0] = SCSI_REQ_SENSE;
852 psrb->cmd[1] = srb->lun << 5;
853 psrb->cmd[4] = 18;
854 psrb->datalen = 18;
Wolfgang Denkd0ff51b2008-07-14 15:19:07 +0200855 psrb->pdata = &srb->sense_buf[0];
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100856 psrb->cmdlen = 12;
wdenkaffae2b2002-08-17 09:36:01 +0000857 /* issue the command */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100858 result = usb_stor_CB_comdat(psrb, us);
859 USB_STOR_PRINTF("auto request returned %d\n", result);
wdenkaffae2b2002-08-17 09:36:01 +0000860 /* if this is an CBI Protocol, get IRQ */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100861 if (us->protocol == US_PR_CBI)
862 status = usb_stor_CBI_get_status(psrb, us);
863
864 if ((result < 0) && !(us->pusb_dev->status & USB_ST_STALLED)) {
Marek Vasut4b210e82011-10-25 11:39:17 +0200865 USB_STOR_PRINTF(" AUTO REQUEST ERROR %ld\n",
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100866 us->pusb_dev->status);
wdenkaffae2b2002-08-17 09:36:01 +0000867 return USB_STOR_TRANSPORT_ERROR;
868 }
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100869 USB_STOR_PRINTF("autorequest returned 0x%02X 0x%02X 0x%02X 0x%02X\n",
870 srb->sense_buf[0], srb->sense_buf[2],
871 srb->sense_buf[12], srb->sense_buf[13]);
wdenkaffae2b2002-08-17 09:36:01 +0000872 /* Check the auto request result */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100873 if ((srb->sense_buf[2] == 0) &&
874 (srb->sense_buf[12] == 0) &&
875 (srb->sense_buf[13] == 0)) {
876 /* ok, no sense */
wdenkaffae2b2002-08-17 09:36:01 +0000877 return USB_STOR_TRANSPORT_GOOD;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100878 }
879
wdenkaffae2b2002-08-17 09:36:01 +0000880 /* Check the auto request result */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100881 switch (srb->sense_buf[2]) {
882 case 0x01:
883 /* Recovered Error */
wdenk149dded2003-09-10 18:20:28 +0000884 return USB_STOR_TRANSPORT_GOOD;
wdenk80885a92004-02-26 23:46:20 +0000885 break;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100886 case 0x02:
887 /* Not Ready */
888 if (notready++ > USB_TRANSPORT_NOT_READY_RETRY) {
889 printf("cmd 0x%02X returned 0x%02X 0x%02X 0x%02X"
890 " 0x%02X (NOT READY)\n", srb->cmd[0],
891 srb->sense_buf[0], srb->sense_buf[2],
892 srb->sense_buf[12], srb->sense_buf[13]);
wdenk149dded2003-09-10 18:20:28 +0000893 return USB_STOR_TRANSPORT_FAILED;
894 } else {
Mike Frysinger5b84dd62012-03-05 13:47:00 +0000895 mdelay(100);
wdenk149dded2003-09-10 18:20:28 +0000896 goto do_retry;
897 }
898 break;
899 default:
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100900 if (retry++ > USB_TRANSPORT_UNKNOWN_RETRY) {
901 printf("cmd 0x%02X returned 0x%02X 0x%02X 0x%02X"
902 " 0x%02X\n", srb->cmd[0], srb->sense_buf[0],
903 srb->sense_buf[2], srb->sense_buf[12],
904 srb->sense_buf[13]);
wdenk149dded2003-09-10 18:20:28 +0000905 return USB_STOR_TRANSPORT_FAILED;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100906 } else
wdenk149dded2003-09-10 18:20:28 +0000907 goto do_retry;
wdenk149dded2003-09-10 18:20:28 +0000908 break;
wdenkaffae2b2002-08-17 09:36:01 +0000909 }
910 return USB_STOR_TRANSPORT_FAILED;
911}
912
913
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100914static int usb_inquiry(ccb *srb, struct us_data *ss)
wdenkaffae2b2002-08-17 09:36:01 +0000915{
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100916 int retry, i;
917 retry = 5;
wdenkaffae2b2002-08-17 09:36:01 +0000918 do {
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100919 memset(&srb->cmd[0], 0, 12);
920 srb->cmd[0] = SCSI_INQUIRY;
Ludovic Courtès99e9ed12010-10-05 22:04:26 +0200921 srb->cmd[1] = srb->lun << 5;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100922 srb->cmd[4] = 36;
923 srb->datalen = 36;
924 srb->cmdlen = 12;
925 i = ss->transport(srb, ss);
926 USB_STOR_PRINTF("inquiry returns %d\n", i);
927 if (i == 0)
wdenkaffae2b2002-08-17 09:36:01 +0000928 break;
Kim B. Heinofac71cc2010-03-12 10:07:00 +0200929 } while (--retry);
wdenk149dded2003-09-10 18:20:28 +0000930
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100931 if (!retry) {
wdenkaffae2b2002-08-17 09:36:01 +0000932 printf("error in inquiry\n");
933 return -1;
934 }
935 return 0;
936}
937
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100938static int usb_request_sense(ccb *srb, struct us_data *ss)
wdenkaffae2b2002-08-17 09:36:01 +0000939{
940 char *ptr;
wdenk80885a92004-02-26 23:46:20 +0000941
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100942 ptr = (char *)srb->pdata;
943 memset(&srb->cmd[0], 0, 12);
944 srb->cmd[0] = SCSI_REQ_SENSE;
Ludovic Courtès99e9ed12010-10-05 22:04:26 +0200945 srb->cmd[1] = srb->lun << 5;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100946 srb->cmd[4] = 18;
947 srb->datalen = 18;
Wolfgang Denkd0ff51b2008-07-14 15:19:07 +0200948 srb->pdata = &srb->sense_buf[0];
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100949 srb->cmdlen = 12;
950 ss->transport(srb, ss);
951 USB_STOR_PRINTF("Request Sense returned %02X %02X %02X\n",
952 srb->sense_buf[2], srb->sense_buf[12],
953 srb->sense_buf[13]);
954 srb->pdata = (uchar *)ptr;
wdenkaffae2b2002-08-17 09:36:01 +0000955 return 0;
956}
957
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100958static int usb_test_unit_ready(ccb *srb, struct us_data *ss)
wdenkaffae2b2002-08-17 09:36:01 +0000959{
Wolfgang Denk9c998aa2005-07-21 11:57:57 +0200960 int retries = 10;
wdenk149dded2003-09-10 18:20:28 +0000961
wdenkaffae2b2002-08-17 09:36:01 +0000962 do {
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100963 memset(&srb->cmd[0], 0, 12);
964 srb->cmd[0] = SCSI_TST_U_RDY;
Ludovic Courtès99e9ed12010-10-05 22:04:26 +0200965 srb->cmd[1] = srb->lun << 5;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100966 srb->datalen = 0;
967 srb->cmdlen = 12;
Benoît Thébaudeau3e8581b2012-08-10 18:27:11 +0200968 if (ss->transport(srb, ss) == USB_STOR_TRANSPORT_GOOD) {
969 ss->flags |= USB_READY;
wdenkaffae2b2002-08-17 09:36:01 +0000970 return 0;
Benoît Thébaudeau3e8581b2012-08-10 18:27:11 +0200971 }
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100972 usb_request_sense(srb, ss);
Vincent Palatin8b57e2f2012-12-12 17:55:29 -0800973 /*
974 * Check the Key Code Qualifier, if it matches
975 * "Not Ready - medium not present"
976 * (the sense Key equals 0x2 and the ASC is 0x3a)
977 * return immediately as the medium being absent won't change
978 * unless there is a user action.
979 */
980 if ((srb->sense_buf[2] == 0x02) &&
981 (srb->sense_buf[12] == 0x3a))
982 return -1;
Mike Frysinger5b84dd62012-03-05 13:47:00 +0000983 mdelay(100);
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100984 } while (retries--);
wdenk149dded2003-09-10 18:20:28 +0000985
wdenkaffae2b2002-08-17 09:36:01 +0000986 return -1;
987}
988
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100989static int usb_read_capacity(ccb *srb, struct us_data *ss)
wdenkaffae2b2002-08-17 09:36:01 +0000990{
991 int retry;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100992 /* XXX retries */
993 retry = 3;
wdenkaffae2b2002-08-17 09:36:01 +0000994 do {
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100995 memset(&srb->cmd[0], 0, 12);
996 srb->cmd[0] = SCSI_RD_CAPAC;
Ludovic Courtès99e9ed12010-10-05 22:04:26 +0200997 srb->cmd[1] = srb->lun << 5;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100998 srb->datalen = 8;
999 srb->cmdlen = 12;
1000 if (ss->transport(srb, ss) == USB_STOR_TRANSPORT_GOOD)
wdenkaffae2b2002-08-17 09:36:01 +00001001 return 0;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001002 } while (retry--);
wdenk149dded2003-09-10 18:20:28 +00001003
wdenkaffae2b2002-08-17 09:36:01 +00001004 return -1;
1005}
1006
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001007static int usb_read_10(ccb *srb, struct us_data *ss, unsigned long start,
1008 unsigned short blocks)
wdenkaffae2b2002-08-17 09:36:01 +00001009{
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001010 memset(&srb->cmd[0], 0, 12);
1011 srb->cmd[0] = SCSI_READ10;
Ludovic Courtès99e9ed12010-10-05 22:04:26 +02001012 srb->cmd[1] = srb->lun << 5;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001013 srb->cmd[2] = ((unsigned char) (start >> 24)) & 0xff;
1014 srb->cmd[3] = ((unsigned char) (start >> 16)) & 0xff;
1015 srb->cmd[4] = ((unsigned char) (start >> 8)) & 0xff;
1016 srb->cmd[5] = ((unsigned char) (start)) & 0xff;
1017 srb->cmd[7] = ((unsigned char) (blocks >> 8)) & 0xff;
1018 srb->cmd[8] = (unsigned char) blocks & 0xff;
1019 srb->cmdlen = 12;
1020 USB_STOR_PRINTF("read10: start %lx blocks %x\n", start, blocks);
1021 return ss->transport(srb, ss);
wdenkaffae2b2002-08-17 09:36:01 +00001022}
1023
Mahavir Jain127e1082009-11-03 12:22:10 +05301024static int usb_write_10(ccb *srb, struct us_data *ss, unsigned long start,
1025 unsigned short blocks)
1026{
1027 memset(&srb->cmd[0], 0, 12);
1028 srb->cmd[0] = SCSI_WRITE10;
Ludovic Courtès99e9ed12010-10-05 22:04:26 +02001029 srb->cmd[1] = srb->lun << 5;
Mahavir Jain127e1082009-11-03 12:22:10 +05301030 srb->cmd[2] = ((unsigned char) (start >> 24)) & 0xff;
1031 srb->cmd[3] = ((unsigned char) (start >> 16)) & 0xff;
1032 srb->cmd[4] = ((unsigned char) (start >> 8)) & 0xff;
1033 srb->cmd[5] = ((unsigned char) (start)) & 0xff;
1034 srb->cmd[7] = ((unsigned char) (blocks >> 8)) & 0xff;
1035 srb->cmd[8] = (unsigned char) blocks & 0xff;
1036 srb->cmdlen = 12;
1037 USB_STOR_PRINTF("write10: start %lx blocks %x\n", start, blocks);
1038 return ss->transport(srb, ss);
1039}
1040
wdenkaffae2b2002-08-17 09:36:01 +00001041
Bartlomiej Siekaddde6b72006-08-22 10:38:18 +02001042#ifdef CONFIG_USB_BIN_FIXUP
1043/*
1044 * Some USB storage devices queried for SCSI identification data respond with
1045 * binary strings, which if output to the console freeze the terminal. The
1046 * workaround is to modify the vendor and product strings read from such
1047 * device with proper values (as reported by 'usb info').
1048 *
1049 * Vendor and product length limits are taken from the definition of
1050 * block_dev_desc_t in include/part.h.
1051 */
1052static void usb_bin_fixup(struct usb_device_descriptor descriptor,
1053 unsigned char vendor[],
1054 unsigned char product[]) {
1055 const unsigned char max_vendor_len = 40;
1056 const unsigned char max_product_len = 20;
1057 if (descriptor.idVendor == 0x0424 && descriptor.idProduct == 0x223a) {
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001058 strncpy((char *)vendor, "SMSC", max_vendor_len);
1059 strncpy((char *)product, "Flash Media Cntrller",
1060 max_product_len);
Bartlomiej Siekaddde6b72006-08-22 10:38:18 +02001061 }
1062}
1063#endif /* CONFIG_USB_BIN_FIXUP */
1064
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001065unsigned long usb_stor_read(int device, unsigned long blknr,
Gabe Blacke81e79e2012-10-12 14:26:07 +00001066 lbaint_t blkcnt, void *buffer)
wdenkaffae2b2002-08-17 09:36:01 +00001067{
Gabe Blacke81e79e2012-10-12 14:26:07 +00001068 lbaint_t start, blks;
1069 uintptr_t buf_addr;
wdenkaffae2b2002-08-17 09:36:01 +00001070 unsigned short smallblks;
1071 struct usb_device *dev;
Kyle Moffett5dd95cf2011-12-21 07:08:12 +00001072 struct us_data *ss;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001073 int retry, i;
wdenkf8d813e2004-03-02 14:05:39 +00001074 ccb *srb = &usb_ccb;
1075
1076 if (blkcnt == 0)
1077 return 0;
1078
1079 device &= 0xff;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001080 /* Setup device */
1081 USB_STOR_PRINTF("\nusb_read: dev %d \n", device);
1082 dev = NULL;
1083 for (i = 0; i < USB_MAX_DEVICE; i++) {
1084 dev = usb_get_dev_index(i);
1085 if (dev == NULL)
wdenkaffae2b2002-08-17 09:36:01 +00001086 return 0;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001087 if (dev->devnum == usb_dev_desc[device].target)
wdenkaffae2b2002-08-17 09:36:01 +00001088 break;
1089 }
Kyle Moffett5dd95cf2011-12-21 07:08:12 +00001090 ss = (struct us_data *)dev->privptr;
wdenkaffae2b2002-08-17 09:36:01 +00001091
1092 usb_disable_asynch(1); /* asynch transfer not allowed */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001093 srb->lun = usb_dev_desc[device].lun;
1094 buf_addr = (unsigned long)buffer;
1095 start = blknr;
1096 blks = blkcnt;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001097
Gabe Blacke81e79e2012-10-12 14:26:07 +00001098 USB_STOR_PRINTF("\nusb_read: dev %d startblk " LBAF ", blccnt " LBAF
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001099 " buffer %lx\n", device, start, blks, buf_addr);
1100
wdenkaffae2b2002-08-17 09:36:01 +00001101 do {
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001102 /* XXX need some comment here */
1103 retry = 2;
1104 srb->pdata = (unsigned char *)buf_addr;
Benoît Thébaudeau4bee5c82012-08-10 18:23:25 +02001105 if (blks > USB_MAX_XFER_BLK)
1106 smallblks = USB_MAX_XFER_BLK;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001107 else
1108 smallblks = (unsigned short) blks;
wdenkaffae2b2002-08-17 09:36:01 +00001109retry_it:
Benoît Thébaudeau4bee5c82012-08-10 18:23:25 +02001110 if (smallblks == USB_MAX_XFER_BLK)
wdenkaffae2b2002-08-17 09:36:01 +00001111 usb_show_progress();
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001112 srb->datalen = usb_dev_desc[device].blksz * smallblks;
1113 srb->pdata = (unsigned char *)buf_addr;
Kyle Moffett5dd95cf2011-12-21 07:08:12 +00001114 if (usb_read_10(srb, ss, start, smallblks)) {
wdenkaffae2b2002-08-17 09:36:01 +00001115 USB_STOR_PRINTF("Read ERROR\n");
Kyle Moffett5dd95cf2011-12-21 07:08:12 +00001116 usb_request_sense(srb, ss);
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001117 if (retry--)
wdenkaffae2b2002-08-17 09:36:01 +00001118 goto retry_it;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001119 blkcnt -= blks;
wdenkaffae2b2002-08-17 09:36:01 +00001120 break;
1121 }
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001122 start += smallblks;
1123 blks -= smallblks;
1124 buf_addr += srb->datalen;
1125 } while (blks != 0);
Benoît Thébaudeau3e8581b2012-08-10 18:27:11 +02001126 ss->flags &= ~USB_READY;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001127
Gabe Blacke81e79e2012-10-12 14:26:07 +00001128 USB_STOR_PRINTF("usb_read: end startblk " LBAF
1129 ", blccnt %x buffer %lx\n",
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001130 start, smallblks, buf_addr);
1131
wdenkaffae2b2002-08-17 09:36:01 +00001132 usb_disable_asynch(0); /* asynch transfer allowed */
Benoît Thébaudeau4bee5c82012-08-10 18:23:25 +02001133 if (blkcnt >= USB_MAX_XFER_BLK)
Wolfgang Denk226fa9b2010-07-19 11:36:59 +02001134 debug("\n");
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001135 return blkcnt;
wdenkaffae2b2002-08-17 09:36:01 +00001136}
1137
Mahavir Jain127e1082009-11-03 12:22:10 +05301138unsigned long usb_stor_write(int device, unsigned long blknr,
Gabe Blacke81e79e2012-10-12 14:26:07 +00001139 lbaint_t blkcnt, const void *buffer)
Mahavir Jain127e1082009-11-03 12:22:10 +05301140{
Gabe Blacke81e79e2012-10-12 14:26:07 +00001141 lbaint_t start, blks;
1142 uintptr_t buf_addr;
Mahavir Jain127e1082009-11-03 12:22:10 +05301143 unsigned short smallblks;
1144 struct usb_device *dev;
Kyle Moffett5dd95cf2011-12-21 07:08:12 +00001145 struct us_data *ss;
Mahavir Jain127e1082009-11-03 12:22:10 +05301146 int retry, i;
1147 ccb *srb = &usb_ccb;
1148
1149 if (blkcnt == 0)
1150 return 0;
1151
1152 device &= 0xff;
1153 /* Setup device */
1154 USB_STOR_PRINTF("\nusb_write: dev %d \n", device);
1155 dev = NULL;
1156 for (i = 0; i < USB_MAX_DEVICE; i++) {
1157 dev = usb_get_dev_index(i);
1158 if (dev == NULL)
1159 return 0;
1160 if (dev->devnum == usb_dev_desc[device].target)
1161 break;
1162 }
Kyle Moffett5dd95cf2011-12-21 07:08:12 +00001163 ss = (struct us_data *)dev->privptr;
Mahavir Jain127e1082009-11-03 12:22:10 +05301164
1165 usb_disable_asynch(1); /* asynch transfer not allowed */
1166
1167 srb->lun = usb_dev_desc[device].lun;
1168 buf_addr = (unsigned long)buffer;
1169 start = blknr;
1170 blks = blkcnt;
Mahavir Jain127e1082009-11-03 12:22:10 +05301171
Gabe Blacke81e79e2012-10-12 14:26:07 +00001172 USB_STOR_PRINTF("\nusb_write: dev %d startblk " LBAF ", blccnt " LBAF
Mahavir Jain127e1082009-11-03 12:22:10 +05301173 " buffer %lx\n", device, start, blks, buf_addr);
1174
1175 do {
1176 /* If write fails retry for max retry count else
1177 * return with number of blocks written successfully.
1178 */
1179 retry = 2;
1180 srb->pdata = (unsigned char *)buf_addr;
Benoît Thébaudeau4bee5c82012-08-10 18:23:25 +02001181 if (blks > USB_MAX_XFER_BLK)
1182 smallblks = USB_MAX_XFER_BLK;
Mahavir Jain127e1082009-11-03 12:22:10 +05301183 else
1184 smallblks = (unsigned short) blks;
1185retry_it:
Benoît Thébaudeau4bee5c82012-08-10 18:23:25 +02001186 if (smallblks == USB_MAX_XFER_BLK)
Mahavir Jain127e1082009-11-03 12:22:10 +05301187 usb_show_progress();
1188 srb->datalen = usb_dev_desc[device].blksz * smallblks;
1189 srb->pdata = (unsigned char *)buf_addr;
Kyle Moffett5dd95cf2011-12-21 07:08:12 +00001190 if (usb_write_10(srb, ss, start, smallblks)) {
Mahavir Jain127e1082009-11-03 12:22:10 +05301191 USB_STOR_PRINTF("Write ERROR\n");
Kyle Moffett5dd95cf2011-12-21 07:08:12 +00001192 usb_request_sense(srb, ss);
Mahavir Jain127e1082009-11-03 12:22:10 +05301193 if (retry--)
1194 goto retry_it;
1195 blkcnt -= blks;
1196 break;
1197 }
1198 start += smallblks;
1199 blks -= smallblks;
1200 buf_addr += srb->datalen;
1201 } while (blks != 0);
Benoît Thébaudeau3e8581b2012-08-10 18:27:11 +02001202 ss->flags &= ~USB_READY;
Mahavir Jain127e1082009-11-03 12:22:10 +05301203
Gabe Blacke81e79e2012-10-12 14:26:07 +00001204 USB_STOR_PRINTF("usb_write: end startblk " LBAF
1205 ", blccnt %x buffer %lx\n",
Mahavir Jain127e1082009-11-03 12:22:10 +05301206 start, smallblks, buf_addr);
1207
1208 usb_disable_asynch(0); /* asynch transfer allowed */
Benoît Thébaudeau4bee5c82012-08-10 18:23:25 +02001209 if (blkcnt >= USB_MAX_XFER_BLK)
Wolfgang Denk226fa9b2010-07-19 11:36:59 +02001210 debug("\n");
Mahavir Jain127e1082009-11-03 12:22:10 +05301211 return blkcnt;
1212
1213}
wdenkaffae2b2002-08-17 09:36:01 +00001214
1215/* Probe to see if a new device is actually a Storage device */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001216int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,
1217 struct us_data *ss)
wdenkaffae2b2002-08-17 09:36:01 +00001218{
Tom Rix8f8bd562009-10-31 12:37:38 -05001219 struct usb_interface *iface;
wdenkaffae2b2002-08-17 09:36:01 +00001220 int i;
1221 unsigned int flags = 0;
1222
1223 int protocol = 0;
1224 int subclass = 0;
1225
wdenkaffae2b2002-08-17 09:36:01 +00001226 /* let's examine the device now */
1227 iface = &dev->config.if_desc[ifnum];
1228
1229#if 0
1230 /* this is the place to patch some storage devices */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001231 USB_STOR_PRINTF("iVendor %X iProduct %X\n", dev->descriptor.idVendor,
1232 dev->descriptor.idProduct);
1233
1234 if ((dev->descriptor.idVendor) == 0x066b &&
1235 (dev->descriptor.idProduct) == 0x0103) {
wdenkaffae2b2002-08-17 09:36:01 +00001236 USB_STOR_PRINTF("patched for E-USB\n");
1237 protocol = US_PR_CB;
1238 subclass = US_SC_UFI; /* an assumption */
1239 }
1240#endif
1241
1242 if (dev->descriptor.bDeviceClass != 0 ||
Tom Rix8f8bd562009-10-31 12:37:38 -05001243 iface->desc.bInterfaceClass != USB_CLASS_MASS_STORAGE ||
1244 iface->desc.bInterfaceSubClass < US_SC_MIN ||
1245 iface->desc.bInterfaceSubClass > US_SC_MAX) {
wdenkaffae2b2002-08-17 09:36:01 +00001246 /* if it's not a mass storage, we go no further */
1247 return 0;
1248 }
1249
Wolfgang Denk9c998aa2005-07-21 11:57:57 +02001250 memset(ss, 0, sizeof(struct us_data));
1251
wdenkaffae2b2002-08-17 09:36:01 +00001252 /* At this point, we know we've got a live one */
1253 USB_STOR_PRINTF("\n\nUSB Mass Storage device detected\n");
1254
1255 /* Initialize the us_data structure with some useful info */
1256 ss->flags = flags;
1257 ss->ifnum = ifnum;
1258 ss->pusb_dev = dev;
1259 ss->attention_done = 0;
1260
1261 /* If the device has subclass and protocol, then use that. Otherwise,
1262 * take data from the specific interface.
1263 */
1264 if (subclass) {
1265 ss->subclass = subclass;
1266 ss->protocol = protocol;
1267 } else {
Tom Rix8f8bd562009-10-31 12:37:38 -05001268 ss->subclass = iface->desc.bInterfaceSubClass;
1269 ss->protocol = iface->desc.bInterfaceProtocol;
wdenkaffae2b2002-08-17 09:36:01 +00001270 }
1271
1272 /* set the handler pointers based on the protocol */
1273 USB_STOR_PRINTF("Transport: ");
1274 switch (ss->protocol) {
1275 case US_PR_CB:
1276 USB_STOR_PRINTF("Control/Bulk\n");
1277 ss->transport = usb_stor_CB_transport;
1278 ss->transport_reset = usb_stor_CB_reset;
1279 break;
1280
1281 case US_PR_CBI:
1282 USB_STOR_PRINTF("Control/Bulk/Interrupt\n");
1283 ss->transport = usb_stor_CB_transport;
1284 ss->transport_reset = usb_stor_CB_reset;
1285 break;
wdenk149dded2003-09-10 18:20:28 +00001286 case US_PR_BULK:
1287 USB_STOR_PRINTF("Bulk/Bulk/Bulk\n");
1288 ss->transport = usb_stor_BBB_transport;
1289 ss->transport_reset = usb_stor_BBB_reset;
1290 break;
wdenkaffae2b2002-08-17 09:36:01 +00001291 default:
wdenk80885a92004-02-26 23:46:20 +00001292 printf("USB Storage Transport unknown / not yet implemented\n");
wdenkaffae2b2002-08-17 09:36:01 +00001293 return 0;
1294 break;
1295 }
1296
1297 /*
1298 * We are expecting a minimum of 2 endpoints - in and out (bulk).
1299 * An optional interrupt is OK (necessary for CBI protocol).
1300 * We will ignore any others.
1301 */
Tom Rix8f8bd562009-10-31 12:37:38 -05001302 for (i = 0; i < iface->desc.bNumEndpoints; i++) {
wdenkaffae2b2002-08-17 09:36:01 +00001303 /* is it an BULK endpoint? */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001304 if ((iface->ep_desc[i].bmAttributes &
1305 USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) {
wdenkaffae2b2002-08-17 09:36:01 +00001306 if (iface->ep_desc[i].bEndpointAddress & USB_DIR_IN)
1307 ss->ep_in = iface->ep_desc[i].bEndpointAddress &
1308 USB_ENDPOINT_NUMBER_MASK;
1309 else
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001310 ss->ep_out =
1311 iface->ep_desc[i].bEndpointAddress &
wdenkaffae2b2002-08-17 09:36:01 +00001312 USB_ENDPOINT_NUMBER_MASK;
1313 }
1314
1315 /* is it an interrupt endpoint? */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001316 if ((iface->ep_desc[i].bmAttributes &
1317 USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) {
wdenkaffae2b2002-08-17 09:36:01 +00001318 ss->ep_int = iface->ep_desc[i].bEndpointAddress &
1319 USB_ENDPOINT_NUMBER_MASK;
1320 ss->irqinterval = iface->ep_desc[i].bInterval;
1321 }
1322 }
1323 USB_STOR_PRINTF("Endpoints In %d Out %d Int %d\n",
1324 ss->ep_in, ss->ep_out, ss->ep_int);
1325
1326 /* Do some basic sanity checks, and bail if we find a problem */
Tom Rix8f8bd562009-10-31 12:37:38 -05001327 if (usb_set_interface(dev, iface->desc.bInterfaceNumber, 0) ||
wdenkaffae2b2002-08-17 09:36:01 +00001328 !ss->ep_in || !ss->ep_out ||
1329 (ss->protocol == US_PR_CBI && ss->ep_int == 0)) {
1330 USB_STOR_PRINTF("Problems with device\n");
1331 return 0;
1332 }
1333 /* set class specific stuff */
wdenk149dded2003-09-10 18:20:28 +00001334 /* We only handle certain protocols. Currently, these are
1335 * the only ones.
wdenk80885a92004-02-26 23:46:20 +00001336 * The SFF8070 accepts the requests used in u-boot
wdenkaffae2b2002-08-17 09:36:01 +00001337 */
wdenk80885a92004-02-26 23:46:20 +00001338 if (ss->subclass != US_SC_UFI && ss->subclass != US_SC_SCSI &&
1339 ss->subclass != US_SC_8070) {
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001340 printf("Sorry, protocol %d not yet supported.\n", ss->subclass);
wdenkaffae2b2002-08-17 09:36:01 +00001341 return 0;
1342 }
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001343 if (ss->ep_int) {
1344 /* we had found an interrupt endpoint, prepare irq pipe
1345 * set up the IRQ pipe and handler
1346 */
wdenkaffae2b2002-08-17 09:36:01 +00001347 ss->irqinterval = (ss->irqinterval > 0) ? ss->irqinterval : 255;
1348 ss->irqpipe = usb_rcvintpipe(ss->pusb_dev, ss->ep_int);
1349 ss->irqmaxp = usb_maxpacket(dev, ss->irqpipe);
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001350 dev->irq_handle = usb_stor_irq;
wdenkaffae2b2002-08-17 09:36:01 +00001351 }
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001352 dev->privptr = (void *)ss;
wdenkaffae2b2002-08-17 09:36:01 +00001353 return 1;
1354}
1355
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001356int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
1357 block_dev_desc_t *dev_desc)
wdenkaffae2b2002-08-17 09:36:01 +00001358{
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001359 unsigned char perq, modi;
Puneet Saxenaf5766132012-04-03 14:56:06 +05301360 ALLOC_CACHE_ALIGN_BUFFER(unsigned long, cap, 2);
1361 ALLOC_CACHE_ALIGN_BUFFER(unsigned char, usb_stor_buf, 36);
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001362 unsigned long *capacity, *blksz;
Wolfgang Denk9c998aa2005-07-21 11:57:57 +02001363 ccb *pccb = &usb_ccb;
wdenkaffae2b2002-08-17 09:36:01 +00001364
Wolfgang Denk9c998aa2005-07-21 11:57:57 +02001365 pccb->pdata = usb_stor_buf;
1366
1367 dev_desc->target = dev->devnum;
1368 pccb->lun = dev_desc->lun;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001369 USB_STOR_PRINTF(" address %d\n", dev_desc->target);
wdenkaffae2b2002-08-17 09:36:01 +00001370
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001371 if (usb_inquiry(pccb, ss))
wdenkaffae2b2002-08-17 09:36:01 +00001372 return -1;
Wolfgang Denk095b8a32005-08-02 17:06:17 +02001373
Wolfgang Denk9c998aa2005-07-21 11:57:57 +02001374 perq = usb_stor_buf[0];
1375 modi = usb_stor_buf[1];
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001376
1377 if ((perq & 0x1f) == 0x1f) {
1378 /* skip unknown devices */
1379 return 0;
wdenkaffae2b2002-08-17 09:36:01 +00001380 }
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001381 if ((modi&0x80) == 0x80) {
1382 /* drive is removable */
Wolfgang Denk9c998aa2005-07-21 11:57:57 +02001383 dev_desc->removable = 1;
wdenkaffae2b2002-08-17 09:36:01 +00001384 }
Puneet Saxenaf5766132012-04-03 14:56:06 +05301385 memcpy(&dev_desc->vendor[0], (const void *) &usb_stor_buf[8], 8);
1386 memcpy(&dev_desc->product[0], (const void *) &usb_stor_buf[16], 16);
1387 memcpy(&dev_desc->revision[0], (const void *) &usb_stor_buf[32], 4);
Wolfgang Denk9c998aa2005-07-21 11:57:57 +02001388 dev_desc->vendor[8] = 0;
1389 dev_desc->product[16] = 0;
1390 dev_desc->revision[4] = 0;
Bartlomiej Siekaddde6b72006-08-22 10:38:18 +02001391#ifdef CONFIG_USB_BIN_FIXUP
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001392 usb_bin_fixup(dev->descriptor, (uchar *)dev_desc->vendor,
1393 (uchar *)dev_desc->product);
Bartlomiej Siekaddde6b72006-08-22 10:38:18 +02001394#endif /* CONFIG_USB_BIN_FIXUP */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001395 USB_STOR_PRINTF("ISO Vers %X, Response Data %X\n", usb_stor_buf[2],
1396 usb_stor_buf[3]);
1397 if (usb_test_unit_ready(pccb, ss)) {
1398 printf("Device NOT ready\n"
1399 " Request Sense returned %02X %02X %02X\n",
1400 pccb->sense_buf[2], pccb->sense_buf[12],
1401 pccb->sense_buf[13]);
1402 if (dev_desc->removable == 1) {
Wolfgang Denk9c998aa2005-07-21 11:57:57 +02001403 dev_desc->type = perq;
wdenkaffae2b2002-08-17 09:36:01 +00001404 return 1;
1405 }
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001406 return 0;
wdenkaffae2b2002-08-17 09:36:01 +00001407 }
Wolfgang Denk9c998aa2005-07-21 11:57:57 +02001408 pccb->pdata = (unsigned char *)&cap[0];
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001409 memset(pccb->pdata, 0, 8);
1410 if (usb_read_capacity(pccb, ss) != 0) {
wdenkaffae2b2002-08-17 09:36:01 +00001411 printf("READ_CAP ERROR\n");
Wolfgang Denk9c998aa2005-07-21 11:57:57 +02001412 cap[0] = 2880;
1413 cap[1] = 0x200;
wdenkaffae2b2002-08-17 09:36:01 +00001414 }
Benoît Thébaudeau3e8581b2012-08-10 18:27:11 +02001415 ss->flags &= ~USB_READY;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001416 USB_STOR_PRINTF("Read Capacity returns: 0x%lx, 0x%lx\n", cap[0],
1417 cap[1]);
wdenkaffae2b2002-08-17 09:36:01 +00001418#if 0
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001419 if (cap[0] > (0x200000 * 10)) /* greater than 10 GByte */
1420 cap[0] >>= 16;
wdenkaffae2b2002-08-17 09:36:01 +00001421#endif
Christian Eggersc9182612008-05-21 22:12:00 +02001422 cap[0] = cpu_to_be32(cap[0]);
1423 cap[1] = cpu_to_be32(cap[1]);
1424
wdenk149dded2003-09-10 18:20:28 +00001425 /* this assumes bigendian! */
Wolfgang Denk9c998aa2005-07-21 11:57:57 +02001426 cap[0] += 1;
1427 capacity = &cap[0];
1428 blksz = &cap[1];
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001429 USB_STOR_PRINTF("Capacity = 0x%lx, blocksz = 0x%lx\n",
1430 *capacity, *blksz);
Wolfgang Denk9c998aa2005-07-21 11:57:57 +02001431 dev_desc->lba = *capacity;
1432 dev_desc->blksz = *blksz;
1433 dev_desc->type = perq;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001434 USB_STOR_PRINTF(" address %d\n", dev_desc->target);
1435 USB_STOR_PRINTF("partype: %d\n", dev_desc->part_type);
wdenkaffae2b2002-08-17 09:36:01 +00001436
1437 init_part(dev_desc);
1438
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001439 USB_STOR_PRINTF("partype: %d\n", dev_desc->part_type);
wdenkaffae2b2002-08-17 09:36:01 +00001440 return 1;
1441}