blob: 099edd3fa6c74f47992158360f9366e81f45b0ce [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 Frysinger2ff12282010-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 */
139 unsigned char ifnum; /* interface number */
140 unsigned char ep_in; /* in endpoint */
141 unsigned char ep_out; /* out ....... */
142 unsigned char ep_int; /* interrupt . */
143 unsigned char subclass; /* as in overview */
144 unsigned char protocol; /* .............. */
145 unsigned char attention_done; /* force attn on first cmd */
146 unsigned short ip_data; /* interrupt data */
147 int action; /* what to do */
148 int ip_wanted; /* needed */
149 int *irq_handle; /* for USB int requests */
150 unsigned int irqpipe; /* pipe for release_irq */
151 unsigned char irqmaxp; /* max packed for irq Pipe */
152 unsigned char irqinterval; /* Intervall for IRQ Pipe */
153 ccb *srb; /* current srb */
154 trans_reset transport_reset; /* reset routine */
155 trans_cmnd transport; /* transport routine */
wdenkaffae2b2002-08-17 09:36:01 +0000156};
157
Benoît Thébaudeaucffcc502012-08-10 18:26:50 +0200158#ifdef CONFIG_USB_EHCI
Stefan Herbrechtsmeier1b4bd0e2012-07-09 09:52:29 +0000159/*
Benoît Thébaudeau4bee5c82012-08-10 18:23:25 +0200160 * The U-Boot EHCI driver can handle any transfer length as long as there is
161 * enough free heap space left, but the SCSI READ(10) and WRITE(10) commands are
162 * limited to 65535 blocks.
Stefan Herbrechtsmeier1b4bd0e2012-07-09 09:52:29 +0000163 */
Benoît Thébaudeau4bee5c82012-08-10 18:23:25 +0200164#define USB_MAX_XFER_BLK 65535
Benoît Thébaudeaucffcc502012-08-10 18:26:50 +0200165#else
Benoît Thébaudeau4bee5c82012-08-10 18:23:25 +0200166#define USB_MAX_XFER_BLK 20
Benoît Thébaudeaucffcc502012-08-10 18:26:50 +0200167#endif
Stefan Herbrechtsmeier1b4bd0e2012-07-09 09:52:29 +0000168
wdenkaffae2b2002-08-17 09:36:01 +0000169static struct us_data usb_stor[USB_MAX_STOR_DEV];
170
171
wdenk80885a92004-02-26 23:46:20 +0000172#define USB_STOR_TRANSPORT_GOOD 0
wdenkaffae2b2002-08-17 09:36:01 +0000173#define USB_STOR_TRANSPORT_FAILED -1
174#define USB_STOR_TRANSPORT_ERROR -2
175
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100176int usb_stor_get_info(struct usb_device *dev, struct us_data *us,
177 block_dev_desc_t *dev_desc);
178int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,
179 struct us_data *ss);
180unsigned long usb_stor_read(int device, unsigned long blknr,
181 unsigned long blkcnt, void *buffer);
Mahavir Jain127e1082009-11-03 12:22:10 +0530182unsigned long usb_stor_write(int device, unsigned long blknr,
183 unsigned long blkcnt, const void *buffer);
wdenkaffae2b2002-08-17 09:36:01 +0000184struct usb_device * usb_get_dev_index(int index);
185void uhci_show_temp_int_td(void);
186
Matthew McClintockdf3fc522011-05-24 05:31:19 +0000187#ifdef CONFIG_PARTITIONS
wdenkaffae2b2002-08-17 09:36:01 +0000188block_dev_desc_t *usb_stor_get_dev(int index)
189{
Kim B. Heinoaaad1082010-03-12 15:46:56 +0200190 return (index < usb_max_devs) ? &usb_dev_desc[index] : NULL;
wdenkaffae2b2002-08-17 09:36:01 +0000191}
Matthew McClintockdf3fc522011-05-24 05:31:19 +0000192#endif
wdenkaffae2b2002-08-17 09:36:01 +0000193
194void usb_show_progress(void)
195{
Wolfgang Denk226fa9b2010-07-19 11:36:59 +0200196 debug(".");
wdenkaffae2b2002-08-17 09:36:01 +0000197}
198
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100199/*******************************************************************************
Wolfgang Denk9c998aa2005-07-21 11:57:57 +0200200 * show info on storage devices; 'usb start/init' must be invoked earlier
201 * as we only retrieve structures populated during devices initialization
202 */
Aras Vaichasf6b44e02008-03-25 12:09:07 +1100203int usb_stor_info(void)
Wolfgang Denk9c998aa2005-07-21 11:57:57 +0200204{
205 int i;
206
Aras Vaichasf6b44e02008-03-25 12:09:07 +1100207 if (usb_max_devs > 0) {
Wolfgang Denk9c998aa2005-07-21 11:57:57 +0200208 for (i = 0; i < usb_max_devs; i++) {
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100209 printf(" Device %d: ", i);
Wolfgang Denk9c998aa2005-07-21 11:57:57 +0200210 dev_print(&usb_dev_desc[i]);
211 }
Markus Klotzbuecherb9e749e2008-03-26 18:26:43 +0100212 return 0;
Aras Vaichasf6b44e02008-03-25 12:09:07 +1100213 }
Wolfgang Denk1aeed8d2008-04-13 09:59:26 -0700214
Markus Klotzbuecherb9e749e2008-03-26 18:26:43 +0100215 printf("No storage devices, perhaps not 'usb start'ed..?\n");
216 return 1;
Wolfgang Denk9c998aa2005-07-21 11:57:57 +0200217}
218
Ludovic Courtès99e9ed12010-10-05 22:04:26 +0200219static unsigned int usb_get_max_lun(struct us_data *us)
220{
221 int len;
Puneet Saxenaf5766132012-04-03 14:56:06 +0530222 ALLOC_CACHE_ALIGN_BUFFER(unsigned char, result, 1);
Ludovic Courtès99e9ed12010-10-05 22:04:26 +0200223 len = usb_control_msg(us->pusb_dev,
224 usb_rcvctrlpipe(us->pusb_dev, 0),
225 US_BBB_GET_MAX_LUN,
226 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
227 0, us->ifnum,
Puneet Saxenaf5766132012-04-03 14:56:06 +0530228 result, sizeof(char),
Ludovic Courtès99e9ed12010-10-05 22:04:26 +0200229 USB_CNTL_TIMEOUT * 5);
230 USB_STOR_PRINTF("Get Max LUN -> len = %i, result = %i\n",
Puneet Saxenaf5766132012-04-03 14:56:06 +0530231 len, (int) *result);
232 return (len > 0) ? *result : 0;
Ludovic Courtès99e9ed12010-10-05 22:04:26 +0200233}
234
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100235/*******************************************************************************
Wolfgang Denk9c998aa2005-07-21 11:57:57 +0200236 * scan the usb and reports device info
wdenkaffae2b2002-08-17 09:36:01 +0000237 * to the user if mode = 1
238 * returns current device or -1 if no
239 */
240int usb_stor_scan(int mode)
241{
242 unsigned char i;
243 struct usb_device *dev;
244
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100245 if (mode == 1)
Wolfgang Denk9c998aa2005-07-21 11:57:57 +0200246 printf(" scanning bus for storage devices... ");
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100247
wdenkaffae2b2002-08-17 09:36:01 +0000248 usb_disable_asynch(1); /* asynch transfer not allowed */
249
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100250 for (i = 0; i < USB_MAX_STOR_DEV; i++) {
251 memset(&usb_dev_desc[i], 0, sizeof(block_dev_desc_t));
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100252 usb_dev_desc[i].if_type = IF_TYPE_USB;
253 usb_dev_desc[i].dev = i;
254 usb_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
Wolfgang Denka17c5482010-07-19 11:36:56 +0200255 usb_dev_desc[i].target = 0xff;
256 usb_dev_desc[i].type = DEV_TYPE_UNKNOWN;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100257 usb_dev_desc[i].block_read = usb_stor_read;
Mahavir Jain127e1082009-11-03 12:22:10 +0530258 usb_dev_desc[i].block_write = usb_stor_write;
wdenkaffae2b2002-08-17 09:36:01 +0000259 }
Wolfgang Denk9c998aa2005-07-21 11:57:57 +0200260
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100261 usb_max_devs = 0;
262 for (i = 0; i < USB_MAX_DEVICE; i++) {
263 dev = usb_get_dev_index(i); /* get device */
264 USB_STOR_PRINTF("i=%d\n", i);
265 if (dev == NULL)
Loïc Minier6052cba2011-02-03 22:04:26 +0100266 break; /* no more devices available */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100267
268 if (usb_storage_probe(dev, 0, &usb_stor[usb_max_devs])) {
Ludovic Courtès99e9ed12010-10-05 22:04:26 +0200269 /* OK, it's a storage device. Iterate over its LUNs
270 * and populate `usb_dev_desc'.
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100271 */
Ludovic Courtès99e9ed12010-10-05 22:04:26 +0200272 int lun, max_lun, start = usb_max_devs;
273
274 max_lun = usb_get_max_lun(&usb_stor[usb_max_devs]);
275 for (lun = 0;
276 lun <= max_lun && usb_max_devs < USB_MAX_STOR_DEV;
277 lun++) {
278 usb_dev_desc[usb_max_devs].lun = lun;
279 if (usb_stor_get_info(dev, &usb_stor[start],
280 &usb_dev_desc[usb_max_devs]) == 1) {
wdenkaffae2b2002-08-17 09:36:01 +0000281 usb_max_devs++;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100282 }
Ludovic Courtès99e9ed12010-10-05 22:04:26 +0200283 }
284 }
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100285 /* if storage device */
286 if (usb_max_devs == USB_MAX_STOR_DEV) {
287 printf("max USB Storage Device reached: %d stopping\n",
288 usb_max_devs);
wdenkaffae2b2002-08-17 09:36:01 +0000289 break;
290 }
291 } /* for */
Wolfgang Denk095b8a32005-08-02 17:06:17 +0200292
wdenkaffae2b2002-08-17 09:36:01 +0000293 usb_disable_asynch(0); /* asynch transfer allowed */
Wolfgang Denk9c998aa2005-07-21 11:57:57 +0200294 printf("%d Storage Device(s) found\n", usb_max_devs);
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100295 if (usb_max_devs > 0)
wdenkaffae2b2002-08-17 09:36:01 +0000296 return 0;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100297 return -1;
wdenkaffae2b2002-08-17 09:36:01 +0000298}
299
300static int usb_stor_irq(struct usb_device *dev)
301{
302 struct us_data *us;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100303 us = (struct us_data *)dev->privptr;
wdenkaffae2b2002-08-17 09:36:01 +0000304
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100305 if (us->ip_wanted)
306 us->ip_wanted = 0;
wdenkaffae2b2002-08-17 09:36:01 +0000307 return 0;
308}
309
310
311#ifdef USB_STOR_DEBUG
312
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100313static void usb_show_srb(ccb *pccb)
wdenkaffae2b2002-08-17 09:36:01 +0000314{
315 int i;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100316 printf("SRB: len %d datalen 0x%lX\n ", pccb->cmdlen, pccb->datalen);
317 for (i = 0; i < 12; i++)
318 printf("%02X ", pccb->cmd[i]);
wdenkaffae2b2002-08-17 09:36:01 +0000319 printf("\n");
320}
321
322static void display_int_status(unsigned long tmp)
323{
324 printf("Status: %s %s %s %s %s %s %s\n",
325 (tmp & USB_ST_ACTIVE) ? "Active" : "",
326 (tmp & USB_ST_STALLED) ? "Stalled" : "",
327 (tmp & USB_ST_BUF_ERR) ? "Buffer Error" : "",
328 (tmp & USB_ST_BABBLE_DET) ? "Babble Det" : "",
329 (tmp & USB_ST_NAK_REC) ? "NAKed" : "",
330 (tmp & USB_ST_CRC_ERR) ? "CRC Error" : "",
331 (tmp & USB_ST_BIT_ERR) ? "Bitstuff Error" : "");
332}
333#endif
334/***********************************************************************
335 * Data transfer routines
336 ***********************************************************************/
337
338static int us_one_transfer(struct us_data *us, int pipe, char *buf, int length)
339{
340 int max_size;
341 int this_xfer;
342 int result;
343 int partial;
344 int maxtry;
345 int stat;
346
347 /* determine the maximum packet size for these transfers */
348 max_size = usb_maxpacket(us->pusb_dev, pipe) * 16;
349
350 /* while we have data left to transfer */
351 while (length) {
352
353 /* calculate how long this will be -- maximum or a remainder */
354 this_xfer = length > max_size ? max_size : length;
355 length -= this_xfer;
356
357 /* setup the retry counter */
358 maxtry = 10;
359
360 /* set up the transfer loop */
361 do {
362 /* transfer the data */
363 USB_STOR_PRINTF("Bulk xfer 0x%x(%d) try #%d\n",
364 (unsigned int)buf, this_xfer, 11 - maxtry);
365 result = usb_bulk_msg(us->pusb_dev, pipe, buf,
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100366 this_xfer, &partial,
367 USB_CNTL_TIMEOUT * 5);
wdenkaffae2b2002-08-17 09:36:01 +0000368 USB_STOR_PRINTF("bulk_msg returned %d xferred %d/%d\n",
369 result, partial, this_xfer);
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100370 if (us->pusb_dev->status != 0) {
371 /* if we stall, we need to clear it before
372 * we go on
373 */
wdenkaffae2b2002-08-17 09:36:01 +0000374#ifdef USB_STOR_DEBUG
375 display_int_status(us->pusb_dev->status);
376#endif
377 if (us->pusb_dev->status & USB_ST_STALLED) {
378 USB_STOR_PRINTF("stalled ->clearing endpoint halt for pipe 0x%x\n", pipe);
379 stat = us->pusb_dev->status;
380 usb_clear_halt(us->pusb_dev, pipe);
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100381 us->pusb_dev->status = stat;
382 if (this_xfer == partial) {
Marek Vasut4b210e82011-10-25 11:39:17 +0200383 USB_STOR_PRINTF("bulk transferred with error %lX, but data ok\n", us->pusb_dev->status);
wdenkaffae2b2002-08-17 09:36:01 +0000384 return 0;
385 }
386 else
387 return result;
388 }
389 if (us->pusb_dev->status & USB_ST_NAK_REC) {
390 USB_STOR_PRINTF("Device NAKed bulk_msg\n");
391 return result;
392 }
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100393 USB_STOR_PRINTF("bulk transferred with error");
394 if (this_xfer == partial) {
Marek Vasut4b210e82011-10-25 11:39:17 +0200395 USB_STOR_PRINTF(" %ld, but data ok\n",
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100396 us->pusb_dev->status);
wdenkaffae2b2002-08-17 09:36:01 +0000397 return 0;
398 }
399 /* if our try counter reaches 0, bail out */
Marek Vasut4b210e82011-10-25 11:39:17 +0200400 USB_STOR_PRINTF(" %ld, data %d\n",
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100401 us->pusb_dev->status, partial);
wdenkaffae2b2002-08-17 09:36:01 +0000402 if (!maxtry--)
403 return result;
404 }
405 /* update to show what data was transferred */
406 this_xfer -= partial;
407 buf += partial;
408 /* continue until this transfer is done */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100409 } while (this_xfer);
wdenkaffae2b2002-08-17 09:36:01 +0000410 }
411
412 /* if we get here, we're done and successful */
413 return 0;
414}
415
wdenk149dded2003-09-10 18:20:28 +0000416static int usb_stor_BBB_reset(struct us_data *us)
417{
418 int result;
419 unsigned int pipe;
420
421 /*
422 * Reset recovery (5.3.4 in Universal Serial Bus Mass Storage Class)
423 *
424 * For Reset Recovery the host shall issue in the following order:
425 * a) a Bulk-Only Mass Storage Reset
426 * b) a Clear Feature HALT to the Bulk-In endpoint
427 * c) a Clear Feature HALT to the Bulk-Out endpoint
428 *
429 * This is done in 3 steps.
430 *
431 * If the reset doesn't succeed, the device should be port reset.
432 *
433 * This comment stolen from FreeBSD's /sys/dev/usb/umass.c.
434 */
435 USB_STOR_PRINTF("BBB_reset\n");
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100436 result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev, 0),
437 US_BBB_RESET,
438 USB_TYPE_CLASS | USB_RECIP_INTERFACE,
439 0, us->ifnum, 0, 0, USB_CNTL_TIMEOUT * 5);
Wolfgang Denk9c998aa2005-07-21 11:57:57 +0200440
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100441 if ((result < 0) && (us->pusb_dev->status & USB_ST_STALLED)) {
wdenk149dded2003-09-10 18:20:28 +0000442 USB_STOR_PRINTF("RESET:stall\n");
443 return -1;
444 }
Wolfgang Denk9c998aa2005-07-21 11:57:57 +0200445
wdenk149dded2003-09-10 18:20:28 +0000446 /* long wait for reset */
Mike Frysinger5b84dd62012-03-05 13:47:00 +0000447 mdelay(150);
Marek Vasut4b210e82011-10-25 11:39:17 +0200448 USB_STOR_PRINTF("BBB_reset result %d: status %lX reset\n", result,
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100449 us->pusb_dev->status);
wdenk149dded2003-09-10 18:20:28 +0000450 pipe = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
451 result = usb_clear_halt(us->pusb_dev, pipe);
452 /* long wait for reset */
Mike Frysinger5b84dd62012-03-05 13:47:00 +0000453 mdelay(150);
Marek Vasut4b210e82011-10-25 11:39:17 +0200454 USB_STOR_PRINTF("BBB_reset result %d: status %lX clearing IN endpoint\n",
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100455 result, us->pusb_dev->status);
wdenk149dded2003-09-10 18:20:28 +0000456 /* long wait for reset */
457 pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
458 result = usb_clear_halt(us->pusb_dev, pipe);
Mike Frysinger5b84dd62012-03-05 13:47:00 +0000459 mdelay(150);
Marek Vasut4b210e82011-10-25 11:39:17 +0200460 USB_STOR_PRINTF("BBB_reset result %d: status %lX"
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100461 " clearing OUT endpoint\n", result,
462 us->pusb_dev->status);
wdenk149dded2003-09-10 18:20:28 +0000463 USB_STOR_PRINTF("BBB_reset done\n");
464 return 0;
465}
466
wdenkaffae2b2002-08-17 09:36:01 +0000467/* FIXME: this reset function doesn't really reset the port, and it
468 * should. Actually it should probably do what it's doing here, and
469 * reset the port physically
470 */
471static int usb_stor_CB_reset(struct us_data *us)
472{
473 unsigned char cmd[12];
474 int result;
475
476 USB_STOR_PRINTF("CB_reset\n");
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100477 memset(cmd, 0xff, sizeof(cmd));
wdenkaffae2b2002-08-17 09:36:01 +0000478 cmd[0] = SCSI_SEND_DIAG;
479 cmd[1] = 4;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100480 result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev, 0),
481 US_CBI_ADSC,
482 USB_TYPE_CLASS | USB_RECIP_INTERFACE,
483 0, us->ifnum, cmd, sizeof(cmd),
484 USB_CNTL_TIMEOUT * 5);
wdenkaffae2b2002-08-17 09:36:01 +0000485
486 /* long wait for reset */
Mike Frysinger5b84dd62012-03-05 13:47:00 +0000487 mdelay(1500);
Marek Vasut4b210e82011-10-25 11:39:17 +0200488 USB_STOR_PRINTF("CB_reset result %d: status %lX"
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100489 " clearing endpoint halt\n", result,
490 us->pusb_dev->status);
wdenkaffae2b2002-08-17 09:36:01 +0000491 usb_clear_halt(us->pusb_dev, usb_rcvbulkpipe(us->pusb_dev, us->ep_in));
492 usb_clear_halt(us->pusb_dev, usb_rcvbulkpipe(us->pusb_dev, us->ep_out));
493
494 USB_STOR_PRINTF("CB_reset done\n");
495 return 0;
496}
497
wdenk149dded2003-09-10 18:20:28 +0000498/*
499 * Set up the command for a BBB device. Note that the actual SCSI
500 * command is copied into cbw.CBWCDB.
501 */
502int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
503{
504 int result;
505 int actlen;
506 int dir_in;
507 unsigned int pipe;
Puneet Saxenaf5766132012-04-03 14:56:06 +0530508 ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_cbw_t, cbw, 1);
wdenk149dded2003-09-10 18:20:28 +0000509
510 dir_in = US_DIRECTION(srb->cmd[0]);
511
512#ifdef BBB_COMDAT_TRACE
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100513 printf("dir %d lun %d cmdlen %d cmd %p datalen %d pdata %p\n",
514 dir_in, srb->lun, srb->cmdlen, srb->cmd, srb->datalen,
515 srb->pdata);
wdenk149dded2003-09-10 18:20:28 +0000516 if (srb->cmdlen) {
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100517 for (result = 0; result < srb->cmdlen; result++)
wdenk149dded2003-09-10 18:20:28 +0000518 printf("cmd[%d] %#x ", result, srb->cmd[result]);
519 printf("\n");
520 }
521#endif
522 /* sanity checks */
523 if (!(srb->cmdlen <= CBWCDBLENGTH)) {
524 USB_STOR_PRINTF("usb_stor_BBB_comdat:cmdlen too large\n");
525 return -1;
526 }
527
528 /* always OUT to the ep */
529 pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
530
Puneet Saxenaf5766132012-04-03 14:56:06 +0530531 cbw->dCBWSignature = cpu_to_le32(CBWSIGNATURE);
532 cbw->dCBWTag = cpu_to_le32(CBWTag++);
533 cbw->dCBWDataTransferLength = cpu_to_le32(srb->datalen);
534 cbw->bCBWFlags = (dir_in ? CBWFLAGS_IN : CBWFLAGS_OUT);
535 cbw->bCBWLUN = srb->lun;
536 cbw->bCDBLength = srb->cmdlen;
wdenk149dded2003-09-10 18:20:28 +0000537 /* copy the command data into the CBW command data buffer */
538 /* DST SRC LEN!!! */
Puneet Saxenaf5766132012-04-03 14:56:06 +0530539 memcpy(cbw->CBWCDB, srb->cmd, srb->cmdlen);
540 result = usb_bulk_msg(us->pusb_dev, pipe, cbw, UMASS_BBB_CBW_SIZE,
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100541 &actlen, USB_CNTL_TIMEOUT * 5);
wdenk149dded2003-09-10 18:20:28 +0000542 if (result < 0)
543 USB_STOR_PRINTF("usb_stor_BBB_comdat:usb_bulk_msg error\n");
544 return result;
545}
546
wdenkaffae2b2002-08-17 09:36:01 +0000547/* FIXME: we also need a CBI_command which sets up the completion
548 * interrupt, and waits for it
549 */
550int usb_stor_CB_comdat(ccb *srb, struct us_data *us)
551{
Wolfgang Denk77ddac92005-10-13 16:45:02 +0200552 int result = 0;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100553 int dir_in, retry;
wdenkaffae2b2002-08-17 09:36:01 +0000554 unsigned int pipe;
555 unsigned long status;
556
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100557 retry = 5;
558 dir_in = US_DIRECTION(srb->cmd[0]);
wdenkaffae2b2002-08-17 09:36:01 +0000559
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100560 if (dir_in)
561 pipe = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
562 else
563 pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
564
565 while (retry--) {
566 USB_STOR_PRINTF("CBI gets a command: Try %d\n", 5 - retry);
wdenkaffae2b2002-08-17 09:36:01 +0000567#ifdef USB_STOR_DEBUG
568 usb_show_srb(srb);
569#endif
570 /* let's send the command via the control pipe */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100571 result = usb_control_msg(us->pusb_dev,
572 usb_sndctrlpipe(us->pusb_dev , 0),
573 US_CBI_ADSC,
574 USB_TYPE_CLASS | USB_RECIP_INTERFACE,
wdenkaffae2b2002-08-17 09:36:01 +0000575 0, us->ifnum,
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100576 srb->cmd, srb->cmdlen,
577 USB_CNTL_TIMEOUT * 5);
578 USB_STOR_PRINTF("CB_transport: control msg returned %d,"
Marek Vasut4b210e82011-10-25 11:39:17 +0200579 " status %lX\n", result, us->pusb_dev->status);
wdenkaffae2b2002-08-17 09:36:01 +0000580 /* check the return code for the command */
581 if (result < 0) {
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100582 if (us->pusb_dev->status & USB_ST_STALLED) {
583 status = us->pusb_dev->status;
584 USB_STOR_PRINTF(" stall during command found,"
585 " clear pipe\n");
586 usb_clear_halt(us->pusb_dev,
587 usb_sndctrlpipe(us->pusb_dev, 0));
588 us->pusb_dev->status = status;
wdenkaffae2b2002-08-17 09:36:01 +0000589 }
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100590 USB_STOR_PRINTF(" error during command %02X"
Marek Vasut4b210e82011-10-25 11:39:17 +0200591 " Stat = %lX\n", srb->cmd[0],
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100592 us->pusb_dev->status);
wdenkaffae2b2002-08-17 09:36:01 +0000593 return result;
594 }
595 /* transfer the data payload for this command, if one exists*/
596
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100597 USB_STOR_PRINTF("CB_transport: control msg returned %d,"
598 " direction is %s to go 0x%lx\n", result,
599 dir_in ? "IN" : "OUT", srb->datalen);
wdenkaffae2b2002-08-17 09:36:01 +0000600 if (srb->datalen) {
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100601 result = us_one_transfer(us, pipe, (char *)srb->pdata,
602 srb->datalen);
603 USB_STOR_PRINTF("CBI attempted to transfer data,"
604 " result is %d status %lX, len %d\n",
605 result, us->pusb_dev->status,
606 us->pusb_dev->act_len);
607 if (!(us->pusb_dev->status & USB_ST_NAK_REC))
wdenkaffae2b2002-08-17 09:36:01 +0000608 break;
609 } /* if (srb->datalen) */
610 else
611 break;
612 }
613 /* return result */
614
615 return result;
616}
617
618
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100619int usb_stor_CBI_get_status(ccb *srb, struct us_data *us)
wdenkaffae2b2002-08-17 09:36:01 +0000620{
621 int timeout;
622
wdenk80885a92004-02-26 23:46:20 +0000623 us->ip_wanted = 1;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100624 submit_int_msg(us->pusb_dev, us->irqpipe,
wdenk80885a92004-02-26 23:46:20 +0000625 (void *) &us->ip_data, us->irqmaxp, us->irqinterval);
626 timeout = 1000;
627 while (timeout--) {
628 if ((volatile int *) us->ip_wanted == 0)
wdenkaffae2b2002-08-17 09:36:01 +0000629 break;
Mike Frysinger5b84dd62012-03-05 13:47:00 +0000630 mdelay(10);
wdenkaffae2b2002-08-17 09:36:01 +0000631 }
632 if (us->ip_wanted) {
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100633 printf(" Did not get interrupt on CBI\n");
wdenkaffae2b2002-08-17 09:36:01 +0000634 us->ip_wanted = 0;
635 return USB_STOR_TRANSPORT_ERROR;
636 }
wdenk80885a92004-02-26 23:46:20 +0000637 USB_STOR_PRINTF
638 ("Got interrupt data 0x%x, transfered %d status 0x%lX\n",
639 us->ip_data, us->pusb_dev->irq_act_len,
640 us->pusb_dev->irq_status);
wdenkaffae2b2002-08-17 09:36:01 +0000641 /* UFI gives us ASC and ASCQ, like a request sense */
642 if (us->subclass == US_SC_UFI) {
643 if (srb->cmd[0] == SCSI_REQ_SENSE ||
644 srb->cmd[0] == SCSI_INQUIRY)
645 return USB_STOR_TRANSPORT_GOOD; /* Good */
wdenk80885a92004-02-26 23:46:20 +0000646 else if (us->ip_data)
647 return USB_STOR_TRANSPORT_FAILED;
wdenkaffae2b2002-08-17 09:36:01 +0000648 else
wdenk80885a92004-02-26 23:46:20 +0000649 return USB_STOR_TRANSPORT_GOOD;
wdenkaffae2b2002-08-17 09:36:01 +0000650 }
651 /* otherwise, we interpret the data normally */
652 switch (us->ip_data) {
wdenk80885a92004-02-26 23:46:20 +0000653 case 0x0001:
654 return USB_STOR_TRANSPORT_GOOD;
655 case 0x0002:
656 return USB_STOR_TRANSPORT_FAILED;
657 default:
658 return USB_STOR_TRANSPORT_ERROR;
659 } /* switch */
wdenkaffae2b2002-08-17 09:36:01 +0000660 return USB_STOR_TRANSPORT_ERROR;
661}
662
663#define USB_TRANSPORT_UNKNOWN_RETRY 5
664#define USB_TRANSPORT_NOT_READY_RETRY 10
665
wdenk149dded2003-09-10 18:20:28 +0000666/* clear a stall on an endpoint - special for BBB devices */
667int usb_stor_BBB_clear_endpt_stall(struct us_data *us, __u8 endpt)
668{
669 int result;
670
671 /* ENDPOINT_HALT = 0, so set value to 0 */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100672 result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev, 0),
wdenk149dded2003-09-10 18:20:28 +0000673 USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT,
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100674 0, endpt, 0, 0, USB_CNTL_TIMEOUT * 5);
wdenk149dded2003-09-10 18:20:28 +0000675 return result;
676}
677
678int usb_stor_BBB_transport(ccb *srb, struct us_data *us)
679{
680 int result, retry;
681 int dir_in;
682 int actlen, data_actlen;
683 unsigned int pipe, pipein, pipeout;
Puneet Saxenaf5766132012-04-03 14:56:06 +0530684 ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_csw_t, csw, 1);
wdenk149dded2003-09-10 18:20:28 +0000685#ifdef BBB_XPORT_TRACE
686 unsigned char *ptr;
687 int index;
688#endif
689
690 dir_in = US_DIRECTION(srb->cmd[0]);
691
692 /* COMMAND phase */
693 USB_STOR_PRINTF("COMMAND phase\n");
694 result = usb_stor_BBB_comdat(srb, us);
695 if (result < 0) {
696 USB_STOR_PRINTF("failed to send CBW status %ld\n",
697 us->pusb_dev->status);
698 usb_stor_BBB_reset(us);
699 return USB_STOR_TRANSPORT_FAILED;
700 }
Mike Frysinger5b84dd62012-03-05 13:47:00 +0000701 mdelay(5);
wdenk149dded2003-09-10 18:20:28 +0000702 pipein = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
703 pipeout = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
704 /* DATA phase + error handling */
wdenk149dded2003-09-10 18:20:28 +0000705 data_actlen = 0;
706 /* no data, go immediately to the STATUS phase */
707 if (srb->datalen == 0)
708 goto st;
wdenk80885a92004-02-26 23:46:20 +0000709 USB_STOR_PRINTF("DATA phase\n");
wdenk149dded2003-09-10 18:20:28 +0000710 if (dir_in)
711 pipe = pipein;
712 else
713 pipe = pipeout;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100714 result = usb_bulk_msg(us->pusb_dev, pipe, srb->pdata, srb->datalen,
715 &data_actlen, USB_CNTL_TIMEOUT * 5);
wdenk149dded2003-09-10 18:20:28 +0000716 /* special handling of STALL in DATA phase */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100717 if ((result < 0) && (us->pusb_dev->status & USB_ST_STALLED)) {
wdenka43278a2003-09-11 19:48:06 +0000718 USB_STOR_PRINTF("DATA:stall\n");
wdenk149dded2003-09-10 18:20:28 +0000719 /* clear the STALL on the endpoint */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100720 result = usb_stor_BBB_clear_endpt_stall(us,
721 dir_in ? us->ep_in : us->ep_out);
wdenk149dded2003-09-10 18:20:28 +0000722 if (result >= 0)
723 /* continue on to STATUS phase */
724 goto st;
725 }
726 if (result < 0) {
727 USB_STOR_PRINTF("usb_bulk_msg error status %ld\n",
728 us->pusb_dev->status);
729 usb_stor_BBB_reset(us);
730 return USB_STOR_TRANSPORT_FAILED;
731 }
732#ifdef BBB_XPORT_TRACE
733 for (index = 0; index < data_actlen; index++)
734 printf("pdata[%d] %#x ", index, srb->pdata[index]);
735 printf("\n");
736#endif
737 /* STATUS phase + error handling */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100738st:
wdenk149dded2003-09-10 18:20:28 +0000739 retry = 0;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100740again:
wdenk149dded2003-09-10 18:20:28 +0000741 USB_STOR_PRINTF("STATUS phase\n");
Puneet Saxenaf5766132012-04-03 14:56:06 +0530742 result = usb_bulk_msg(us->pusb_dev, pipein, csw, UMASS_BBB_CSW_SIZE,
Wolfgang Denk9c998aa2005-07-21 11:57:57 +0200743 &actlen, USB_CNTL_TIMEOUT*5);
744
wdenk149dded2003-09-10 18:20:28 +0000745 /* special handling of STALL in STATUS phase */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100746 if ((result < 0) && (retry < 1) &&
747 (us->pusb_dev->status & USB_ST_STALLED)) {
wdenk149dded2003-09-10 18:20:28 +0000748 USB_STOR_PRINTF("STATUS:stall\n");
749 /* clear the STALL on the endpoint */
750 result = usb_stor_BBB_clear_endpt_stall(us, us->ep_in);
751 if (result >= 0 && (retry++ < 1))
752 /* do a retry */
753 goto again;
754 }
755 if (result < 0) {
756 USB_STOR_PRINTF("usb_bulk_msg error status %ld\n",
757 us->pusb_dev->status);
758 usb_stor_BBB_reset(us);
759 return USB_STOR_TRANSPORT_FAILED;
760 }
761#ifdef BBB_XPORT_TRACE
Puneet Saxenaf5766132012-04-03 14:56:06 +0530762 ptr = (unsigned char *)csw;
wdenk149dded2003-09-10 18:20:28 +0000763 for (index = 0; index < UMASS_BBB_CSW_SIZE; index++)
764 printf("ptr[%d] %#x ", index, ptr[index]);
765 printf("\n");
766#endif
767 /* misuse pipe to get the residue */
Puneet Saxenaf5766132012-04-03 14:56:06 +0530768 pipe = le32_to_cpu(csw->dCSWDataResidue);
wdenk149dded2003-09-10 18:20:28 +0000769 if (pipe == 0 && srb->datalen != 0 && srb->datalen - data_actlen != 0)
770 pipe = srb->datalen - data_actlen;
Puneet Saxenaf5766132012-04-03 14:56:06 +0530771 if (CSWSIGNATURE != le32_to_cpu(csw->dCSWSignature)) {
wdenk149dded2003-09-10 18:20:28 +0000772 USB_STOR_PRINTF("!CSWSIGNATURE\n");
773 usb_stor_BBB_reset(us);
774 return USB_STOR_TRANSPORT_FAILED;
Puneet Saxenaf5766132012-04-03 14:56:06 +0530775 } else if ((CBWTag - 1) != le32_to_cpu(csw->dCSWTag)) {
wdenk149dded2003-09-10 18:20:28 +0000776 USB_STOR_PRINTF("!Tag\n");
777 usb_stor_BBB_reset(us);
778 return USB_STOR_TRANSPORT_FAILED;
Puneet Saxenaf5766132012-04-03 14:56:06 +0530779 } else if (csw->bCSWStatus > CSWSTATUS_PHASE) {
wdenk149dded2003-09-10 18:20:28 +0000780 USB_STOR_PRINTF(">PHASE\n");
781 usb_stor_BBB_reset(us);
782 return USB_STOR_TRANSPORT_FAILED;
Puneet Saxenaf5766132012-04-03 14:56:06 +0530783 } else if (csw->bCSWStatus == CSWSTATUS_PHASE) {
wdenk149dded2003-09-10 18:20:28 +0000784 USB_STOR_PRINTF("=PHASE\n");
785 usb_stor_BBB_reset(us);
786 return USB_STOR_TRANSPORT_FAILED;
787 } else if (data_actlen > srb->datalen) {
Marek Vasut4b210e82011-10-25 11:39:17 +0200788 USB_STOR_PRINTF("transferred %dB instead of %ldB\n",
wdenk149dded2003-09-10 18:20:28 +0000789 data_actlen, srb->datalen);
790 return USB_STOR_TRANSPORT_FAILED;
Puneet Saxenaf5766132012-04-03 14:56:06 +0530791 } else if (csw->bCSWStatus == CSWSTATUS_FAILED) {
wdenk149dded2003-09-10 18:20:28 +0000792 USB_STOR_PRINTF("FAILED\n");
793 return USB_STOR_TRANSPORT_FAILED;
794 }
795
796 return result;
797}
798
wdenkaffae2b2002-08-17 09:36:01 +0000799int usb_stor_CB_transport(ccb *srb, struct us_data *us)
800{
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100801 int result, status;
wdenkaffae2b2002-08-17 09:36:01 +0000802 ccb *psrb;
803 ccb reqsrb;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100804 int retry, notready;
wdenkaffae2b2002-08-17 09:36:01 +0000805
Wolfgang Denkd0ff51b2008-07-14 15:19:07 +0200806 psrb = &reqsrb;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100807 status = USB_STOR_TRANSPORT_GOOD;
808 retry = 0;
809 notready = 0;
wdenkaffae2b2002-08-17 09:36:01 +0000810 /* issue the command */
811do_retry:
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100812 result = usb_stor_CB_comdat(srb, us);
Marek Vasut4b210e82011-10-25 11:39:17 +0200813 USB_STOR_PRINTF("command / Data returned %d, status %lX\n",
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100814 result, us->pusb_dev->status);
wdenkaffae2b2002-08-17 09:36:01 +0000815 /* if this is an CBI Protocol, get IRQ */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100816 if (us->protocol == US_PR_CBI) {
817 status = usb_stor_CBI_get_status(srb, us);
wdenkaffae2b2002-08-17 09:36:01 +0000818 /* if the status is error, report it */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100819 if (status == USB_STOR_TRANSPORT_ERROR) {
wdenkaffae2b2002-08-17 09:36:01 +0000820 USB_STOR_PRINTF(" USB CBI Command Error\n");
821 return status;
822 }
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100823 srb->sense_buf[12] = (unsigned char)(us->ip_data >> 8);
824 srb->sense_buf[13] = (unsigned char)(us->ip_data & 0xff);
825 if (!us->ip_data) {
826 /* if the status is good, report it */
827 if (status == USB_STOR_TRANSPORT_GOOD) {
wdenkaffae2b2002-08-17 09:36:01 +0000828 USB_STOR_PRINTF(" USB CBI Command Good\n");
829 return status;
830 }
831 }
832 }
833 /* do we have to issue an auto request? */
834 /* HERE we have to check the result */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100835 if ((result < 0) && !(us->pusb_dev->status & USB_ST_STALLED)) {
Marek Vasut4b210e82011-10-25 11:39:17 +0200836 USB_STOR_PRINTF("ERROR %lX\n", us->pusb_dev->status);
wdenkaffae2b2002-08-17 09:36:01 +0000837 us->transport_reset(us);
838 return USB_STOR_TRANSPORT_ERROR;
839 }
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100840 if ((us->protocol == US_PR_CBI) &&
841 ((srb->cmd[0] == SCSI_REQ_SENSE) ||
842 (srb->cmd[0] == SCSI_INQUIRY))) {
843 /* do not issue an autorequest after request sense */
wdenkaffae2b2002-08-17 09:36:01 +0000844 USB_STOR_PRINTF("No auto request and good\n");
845 return USB_STOR_TRANSPORT_GOOD;
846 }
847 /* issue an request_sense */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100848 memset(&psrb->cmd[0], 0, 12);
849 psrb->cmd[0] = SCSI_REQ_SENSE;
850 psrb->cmd[1] = srb->lun << 5;
851 psrb->cmd[4] = 18;
852 psrb->datalen = 18;
Wolfgang Denkd0ff51b2008-07-14 15:19:07 +0200853 psrb->pdata = &srb->sense_buf[0];
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100854 psrb->cmdlen = 12;
wdenkaffae2b2002-08-17 09:36:01 +0000855 /* issue the command */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100856 result = usb_stor_CB_comdat(psrb, us);
857 USB_STOR_PRINTF("auto request returned %d\n", result);
wdenkaffae2b2002-08-17 09:36:01 +0000858 /* if this is an CBI Protocol, get IRQ */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100859 if (us->protocol == US_PR_CBI)
860 status = usb_stor_CBI_get_status(psrb, us);
861
862 if ((result < 0) && !(us->pusb_dev->status & USB_ST_STALLED)) {
Marek Vasut4b210e82011-10-25 11:39:17 +0200863 USB_STOR_PRINTF(" AUTO REQUEST ERROR %ld\n",
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100864 us->pusb_dev->status);
wdenkaffae2b2002-08-17 09:36:01 +0000865 return USB_STOR_TRANSPORT_ERROR;
866 }
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100867 USB_STOR_PRINTF("autorequest returned 0x%02X 0x%02X 0x%02X 0x%02X\n",
868 srb->sense_buf[0], srb->sense_buf[2],
869 srb->sense_buf[12], srb->sense_buf[13]);
wdenkaffae2b2002-08-17 09:36:01 +0000870 /* Check the auto request result */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100871 if ((srb->sense_buf[2] == 0) &&
872 (srb->sense_buf[12] == 0) &&
873 (srb->sense_buf[13] == 0)) {
874 /* ok, no sense */
wdenkaffae2b2002-08-17 09:36:01 +0000875 return USB_STOR_TRANSPORT_GOOD;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100876 }
877
wdenkaffae2b2002-08-17 09:36:01 +0000878 /* Check the auto request result */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100879 switch (srb->sense_buf[2]) {
880 case 0x01:
881 /* Recovered Error */
wdenk149dded2003-09-10 18:20:28 +0000882 return USB_STOR_TRANSPORT_GOOD;
wdenk80885a92004-02-26 23:46:20 +0000883 break;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100884 case 0x02:
885 /* Not Ready */
886 if (notready++ > USB_TRANSPORT_NOT_READY_RETRY) {
887 printf("cmd 0x%02X returned 0x%02X 0x%02X 0x%02X"
888 " 0x%02X (NOT READY)\n", srb->cmd[0],
889 srb->sense_buf[0], srb->sense_buf[2],
890 srb->sense_buf[12], srb->sense_buf[13]);
wdenk149dded2003-09-10 18:20:28 +0000891 return USB_STOR_TRANSPORT_FAILED;
892 } else {
Mike Frysinger5b84dd62012-03-05 13:47:00 +0000893 mdelay(100);
wdenk149dded2003-09-10 18:20:28 +0000894 goto do_retry;
895 }
896 break;
897 default:
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100898 if (retry++ > USB_TRANSPORT_UNKNOWN_RETRY) {
899 printf("cmd 0x%02X returned 0x%02X 0x%02X 0x%02X"
900 " 0x%02X\n", srb->cmd[0], srb->sense_buf[0],
901 srb->sense_buf[2], srb->sense_buf[12],
902 srb->sense_buf[13]);
wdenk149dded2003-09-10 18:20:28 +0000903 return USB_STOR_TRANSPORT_FAILED;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100904 } else
wdenk149dded2003-09-10 18:20:28 +0000905 goto do_retry;
wdenk149dded2003-09-10 18:20:28 +0000906 break;
wdenkaffae2b2002-08-17 09:36:01 +0000907 }
908 return USB_STOR_TRANSPORT_FAILED;
909}
910
911
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100912static int usb_inquiry(ccb *srb, struct us_data *ss)
wdenkaffae2b2002-08-17 09:36:01 +0000913{
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100914 int retry, i;
915 retry = 5;
wdenkaffae2b2002-08-17 09:36:01 +0000916 do {
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100917 memset(&srb->cmd[0], 0, 12);
918 srb->cmd[0] = SCSI_INQUIRY;
Ludovic Courtès99e9ed12010-10-05 22:04:26 +0200919 srb->cmd[1] = srb->lun << 5;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100920 srb->cmd[4] = 36;
921 srb->datalen = 36;
922 srb->cmdlen = 12;
923 i = ss->transport(srb, ss);
924 USB_STOR_PRINTF("inquiry returns %d\n", i);
925 if (i == 0)
wdenkaffae2b2002-08-17 09:36:01 +0000926 break;
Kim B. Heinofac71cc2010-03-12 10:07:00 +0200927 } while (--retry);
wdenk149dded2003-09-10 18:20:28 +0000928
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100929 if (!retry) {
wdenkaffae2b2002-08-17 09:36:01 +0000930 printf("error in inquiry\n");
931 return -1;
932 }
933 return 0;
934}
935
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100936static int usb_request_sense(ccb *srb, struct us_data *ss)
wdenkaffae2b2002-08-17 09:36:01 +0000937{
938 char *ptr;
wdenk80885a92004-02-26 23:46:20 +0000939
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100940 ptr = (char *)srb->pdata;
941 memset(&srb->cmd[0], 0, 12);
942 srb->cmd[0] = SCSI_REQ_SENSE;
Ludovic Courtès99e9ed12010-10-05 22:04:26 +0200943 srb->cmd[1] = srb->lun << 5;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100944 srb->cmd[4] = 18;
945 srb->datalen = 18;
Wolfgang Denkd0ff51b2008-07-14 15:19:07 +0200946 srb->pdata = &srb->sense_buf[0];
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100947 srb->cmdlen = 12;
948 ss->transport(srb, ss);
949 USB_STOR_PRINTF("Request Sense returned %02X %02X %02X\n",
950 srb->sense_buf[2], srb->sense_buf[12],
951 srb->sense_buf[13]);
952 srb->pdata = (uchar *)ptr;
wdenkaffae2b2002-08-17 09:36:01 +0000953 return 0;
954}
955
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100956static int usb_test_unit_ready(ccb *srb, struct us_data *ss)
wdenkaffae2b2002-08-17 09:36:01 +0000957{
Wolfgang Denk9c998aa2005-07-21 11:57:57 +0200958 int retries = 10;
wdenk149dded2003-09-10 18:20:28 +0000959
wdenkaffae2b2002-08-17 09:36:01 +0000960 do {
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100961 memset(&srb->cmd[0], 0, 12);
962 srb->cmd[0] = SCSI_TST_U_RDY;
Ludovic Courtès99e9ed12010-10-05 22:04:26 +0200963 srb->cmd[1] = srb->lun << 5;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100964 srb->datalen = 0;
965 srb->cmdlen = 12;
966 if (ss->transport(srb, ss) == USB_STOR_TRANSPORT_GOOD)
wdenkaffae2b2002-08-17 09:36:01 +0000967 return 0;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100968 usb_request_sense(srb, ss);
Mike Frysinger5b84dd62012-03-05 13:47:00 +0000969 mdelay(100);
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100970 } while (retries--);
wdenk149dded2003-09-10 18:20:28 +0000971
wdenkaffae2b2002-08-17 09:36:01 +0000972 return -1;
973}
974
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100975static int usb_read_capacity(ccb *srb, struct us_data *ss)
wdenkaffae2b2002-08-17 09:36:01 +0000976{
977 int retry;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100978 /* XXX retries */
979 retry = 3;
wdenkaffae2b2002-08-17 09:36:01 +0000980 do {
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100981 memset(&srb->cmd[0], 0, 12);
982 srb->cmd[0] = SCSI_RD_CAPAC;
Ludovic Courtès99e9ed12010-10-05 22:04:26 +0200983 srb->cmd[1] = srb->lun << 5;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100984 srb->datalen = 8;
985 srb->cmdlen = 12;
986 if (ss->transport(srb, ss) == USB_STOR_TRANSPORT_GOOD)
wdenkaffae2b2002-08-17 09:36:01 +0000987 return 0;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100988 } while (retry--);
wdenk149dded2003-09-10 18:20:28 +0000989
wdenkaffae2b2002-08-17 09:36:01 +0000990 return -1;
991}
992
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100993static int usb_read_10(ccb *srb, struct us_data *ss, unsigned long start,
994 unsigned short blocks)
wdenkaffae2b2002-08-17 09:36:01 +0000995{
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100996 memset(&srb->cmd[0], 0, 12);
997 srb->cmd[0] = SCSI_READ10;
Ludovic Courtès99e9ed12010-10-05 22:04:26 +0200998 srb->cmd[1] = srb->lun << 5;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +0100999 srb->cmd[2] = ((unsigned char) (start >> 24)) & 0xff;
1000 srb->cmd[3] = ((unsigned char) (start >> 16)) & 0xff;
1001 srb->cmd[4] = ((unsigned char) (start >> 8)) & 0xff;
1002 srb->cmd[5] = ((unsigned char) (start)) & 0xff;
1003 srb->cmd[7] = ((unsigned char) (blocks >> 8)) & 0xff;
1004 srb->cmd[8] = (unsigned char) blocks & 0xff;
1005 srb->cmdlen = 12;
1006 USB_STOR_PRINTF("read10: start %lx blocks %x\n", start, blocks);
1007 return ss->transport(srb, ss);
wdenkaffae2b2002-08-17 09:36:01 +00001008}
1009
Mahavir Jain127e1082009-11-03 12:22:10 +05301010static int usb_write_10(ccb *srb, struct us_data *ss, unsigned long start,
1011 unsigned short blocks)
1012{
1013 memset(&srb->cmd[0], 0, 12);
1014 srb->cmd[0] = SCSI_WRITE10;
Ludovic Courtès99e9ed12010-10-05 22:04:26 +02001015 srb->cmd[1] = srb->lun << 5;
Mahavir Jain127e1082009-11-03 12:22:10 +05301016 srb->cmd[2] = ((unsigned char) (start >> 24)) & 0xff;
1017 srb->cmd[3] = ((unsigned char) (start >> 16)) & 0xff;
1018 srb->cmd[4] = ((unsigned char) (start >> 8)) & 0xff;
1019 srb->cmd[5] = ((unsigned char) (start)) & 0xff;
1020 srb->cmd[7] = ((unsigned char) (blocks >> 8)) & 0xff;
1021 srb->cmd[8] = (unsigned char) blocks & 0xff;
1022 srb->cmdlen = 12;
1023 USB_STOR_PRINTF("write10: start %lx blocks %x\n", start, blocks);
1024 return ss->transport(srb, ss);
1025}
1026
wdenkaffae2b2002-08-17 09:36:01 +00001027
Bartlomiej Siekaddde6b72006-08-22 10:38:18 +02001028#ifdef CONFIG_USB_BIN_FIXUP
1029/*
1030 * Some USB storage devices queried for SCSI identification data respond with
1031 * binary strings, which if output to the console freeze the terminal. The
1032 * workaround is to modify the vendor and product strings read from such
1033 * device with proper values (as reported by 'usb info').
1034 *
1035 * Vendor and product length limits are taken from the definition of
1036 * block_dev_desc_t in include/part.h.
1037 */
1038static void usb_bin_fixup(struct usb_device_descriptor descriptor,
1039 unsigned char vendor[],
1040 unsigned char product[]) {
1041 const unsigned char max_vendor_len = 40;
1042 const unsigned char max_product_len = 20;
1043 if (descriptor.idVendor == 0x0424 && descriptor.idProduct == 0x223a) {
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001044 strncpy((char *)vendor, "SMSC", max_vendor_len);
1045 strncpy((char *)product, "Flash Media Cntrller",
1046 max_product_len);
Bartlomiej Siekaddde6b72006-08-22 10:38:18 +02001047 }
1048}
1049#endif /* CONFIG_USB_BIN_FIXUP */
1050
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001051unsigned long usb_stor_read(int device, unsigned long blknr,
1052 unsigned long blkcnt, void *buffer)
wdenkaffae2b2002-08-17 09:36:01 +00001053{
Benoît Thébaudeau4bee5c82012-08-10 18:23:25 +02001054 unsigned long start, blks, buf_addr;
wdenkaffae2b2002-08-17 09:36:01 +00001055 unsigned short smallblks;
1056 struct usb_device *dev;
Kyle Moffett5dd95cf2011-12-21 07:08:12 +00001057 struct us_data *ss;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001058 int retry, i;
wdenkf8d813e2004-03-02 14:05:39 +00001059 ccb *srb = &usb_ccb;
1060
1061 if (blkcnt == 0)
1062 return 0;
1063
1064 device &= 0xff;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001065 /* Setup device */
1066 USB_STOR_PRINTF("\nusb_read: dev %d \n", device);
1067 dev = NULL;
1068 for (i = 0; i < USB_MAX_DEVICE; i++) {
1069 dev = usb_get_dev_index(i);
1070 if (dev == NULL)
wdenkaffae2b2002-08-17 09:36:01 +00001071 return 0;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001072 if (dev->devnum == usb_dev_desc[device].target)
wdenkaffae2b2002-08-17 09:36:01 +00001073 break;
1074 }
Kyle Moffett5dd95cf2011-12-21 07:08:12 +00001075 ss = (struct us_data *)dev->privptr;
wdenkaffae2b2002-08-17 09:36:01 +00001076
1077 usb_disable_asynch(1); /* asynch transfer not allowed */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001078 srb->lun = usb_dev_desc[device].lun;
1079 buf_addr = (unsigned long)buffer;
1080 start = blknr;
1081 blks = blkcnt;
Kyle Moffett5dd95cf2011-12-21 07:08:12 +00001082 if (usb_test_unit_ready(srb, ss)) {
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001083 printf("Device NOT ready\n Request Sense returned %02X %02X"
1084 " %02X\n", srb->sense_buf[2], srb->sense_buf[12],
1085 srb->sense_buf[13]);
wdenkaffae2b2002-08-17 09:36:01 +00001086 return 0;
1087 }
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001088
1089 USB_STOR_PRINTF("\nusb_read: dev %d startblk %lx, blccnt %lx"
1090 " buffer %lx\n", device, start, blks, buf_addr);
1091
wdenkaffae2b2002-08-17 09:36:01 +00001092 do {
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001093 /* XXX need some comment here */
1094 retry = 2;
1095 srb->pdata = (unsigned char *)buf_addr;
Benoît Thébaudeau4bee5c82012-08-10 18:23:25 +02001096 if (blks > USB_MAX_XFER_BLK)
1097 smallblks = USB_MAX_XFER_BLK;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001098 else
1099 smallblks = (unsigned short) blks;
wdenkaffae2b2002-08-17 09:36:01 +00001100retry_it:
Benoît Thébaudeau4bee5c82012-08-10 18:23:25 +02001101 if (smallblks == USB_MAX_XFER_BLK)
wdenkaffae2b2002-08-17 09:36:01 +00001102 usb_show_progress();
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001103 srb->datalen = usb_dev_desc[device].blksz * smallblks;
1104 srb->pdata = (unsigned char *)buf_addr;
Kyle Moffett5dd95cf2011-12-21 07:08:12 +00001105 if (usb_read_10(srb, ss, start, smallblks)) {
wdenkaffae2b2002-08-17 09:36:01 +00001106 USB_STOR_PRINTF("Read ERROR\n");
Kyle Moffett5dd95cf2011-12-21 07:08:12 +00001107 usb_request_sense(srb, ss);
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001108 if (retry--)
wdenkaffae2b2002-08-17 09:36:01 +00001109 goto retry_it;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001110 blkcnt -= blks;
wdenkaffae2b2002-08-17 09:36:01 +00001111 break;
1112 }
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001113 start += smallblks;
1114 blks -= smallblks;
1115 buf_addr += srb->datalen;
1116 } while (blks != 0);
1117
1118 USB_STOR_PRINTF("usb_read: end startblk %lx, blccnt %x buffer %lx\n",
1119 start, smallblks, buf_addr);
1120
wdenkaffae2b2002-08-17 09:36:01 +00001121 usb_disable_asynch(0); /* asynch transfer allowed */
Benoît Thébaudeau4bee5c82012-08-10 18:23:25 +02001122 if (blkcnt >= USB_MAX_XFER_BLK)
Wolfgang Denk226fa9b2010-07-19 11:36:59 +02001123 debug("\n");
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001124 return blkcnt;
wdenkaffae2b2002-08-17 09:36:01 +00001125}
1126
Mahavir Jain127e1082009-11-03 12:22:10 +05301127unsigned long usb_stor_write(int device, unsigned long blknr,
1128 unsigned long blkcnt, const void *buffer)
1129{
Benoît Thébaudeau4bee5c82012-08-10 18:23:25 +02001130 unsigned long start, blks, buf_addr;
Mahavir Jain127e1082009-11-03 12:22:10 +05301131 unsigned short smallblks;
1132 struct usb_device *dev;
Kyle Moffett5dd95cf2011-12-21 07:08:12 +00001133 struct us_data *ss;
Mahavir Jain127e1082009-11-03 12:22:10 +05301134 int retry, i;
1135 ccb *srb = &usb_ccb;
1136
1137 if (blkcnt == 0)
1138 return 0;
1139
1140 device &= 0xff;
1141 /* Setup device */
1142 USB_STOR_PRINTF("\nusb_write: dev %d \n", device);
1143 dev = NULL;
1144 for (i = 0; i < USB_MAX_DEVICE; i++) {
1145 dev = usb_get_dev_index(i);
1146 if (dev == NULL)
1147 return 0;
1148 if (dev->devnum == usb_dev_desc[device].target)
1149 break;
1150 }
Kyle Moffett5dd95cf2011-12-21 07:08:12 +00001151 ss = (struct us_data *)dev->privptr;
Mahavir Jain127e1082009-11-03 12:22:10 +05301152
1153 usb_disable_asynch(1); /* asynch transfer not allowed */
1154
1155 srb->lun = usb_dev_desc[device].lun;
1156 buf_addr = (unsigned long)buffer;
1157 start = blknr;
1158 blks = blkcnt;
Kyle Moffett5dd95cf2011-12-21 07:08:12 +00001159 if (usb_test_unit_ready(srb, ss)) {
Mahavir Jain127e1082009-11-03 12:22:10 +05301160 printf("Device NOT ready\n Request Sense returned %02X %02X"
1161 " %02X\n", srb->sense_buf[2], srb->sense_buf[12],
1162 srb->sense_buf[13]);
1163 return 0;
1164 }
1165
1166 USB_STOR_PRINTF("\nusb_write: dev %d startblk %lx, blccnt %lx"
1167 " buffer %lx\n", device, start, blks, buf_addr);
1168
1169 do {
1170 /* If write fails retry for max retry count else
1171 * return with number of blocks written successfully.
1172 */
1173 retry = 2;
1174 srb->pdata = (unsigned char *)buf_addr;
Benoît Thébaudeau4bee5c82012-08-10 18:23:25 +02001175 if (blks > USB_MAX_XFER_BLK)
1176 smallblks = USB_MAX_XFER_BLK;
Mahavir Jain127e1082009-11-03 12:22:10 +05301177 else
1178 smallblks = (unsigned short) blks;
1179retry_it:
Benoît Thébaudeau4bee5c82012-08-10 18:23:25 +02001180 if (smallblks == USB_MAX_XFER_BLK)
Mahavir Jain127e1082009-11-03 12:22:10 +05301181 usb_show_progress();
1182 srb->datalen = usb_dev_desc[device].blksz * smallblks;
1183 srb->pdata = (unsigned char *)buf_addr;
Kyle Moffett5dd95cf2011-12-21 07:08:12 +00001184 if (usb_write_10(srb, ss, start, smallblks)) {
Mahavir Jain127e1082009-11-03 12:22:10 +05301185 USB_STOR_PRINTF("Write ERROR\n");
Kyle Moffett5dd95cf2011-12-21 07:08:12 +00001186 usb_request_sense(srb, ss);
Mahavir Jain127e1082009-11-03 12:22:10 +05301187 if (retry--)
1188 goto retry_it;
1189 blkcnt -= blks;
1190 break;
1191 }
1192 start += smallblks;
1193 blks -= smallblks;
1194 buf_addr += srb->datalen;
1195 } while (blks != 0);
1196
1197 USB_STOR_PRINTF("usb_write: end startblk %lx, blccnt %x buffer %lx\n",
1198 start, smallblks, buf_addr);
1199
1200 usb_disable_asynch(0); /* asynch transfer allowed */
Benoît Thébaudeau4bee5c82012-08-10 18:23:25 +02001201 if (blkcnt >= USB_MAX_XFER_BLK)
Wolfgang Denk226fa9b2010-07-19 11:36:59 +02001202 debug("\n");
Mahavir Jain127e1082009-11-03 12:22:10 +05301203 return blkcnt;
1204
1205}
wdenkaffae2b2002-08-17 09:36:01 +00001206
1207/* Probe to see if a new device is actually a Storage device */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001208int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,
1209 struct us_data *ss)
wdenkaffae2b2002-08-17 09:36:01 +00001210{
Tom Rix8f8bd562009-10-31 12:37:38 -05001211 struct usb_interface *iface;
wdenkaffae2b2002-08-17 09:36:01 +00001212 int i;
1213 unsigned int flags = 0;
1214
1215 int protocol = 0;
1216 int subclass = 0;
1217
wdenkaffae2b2002-08-17 09:36:01 +00001218 /* let's examine the device now */
1219 iface = &dev->config.if_desc[ifnum];
1220
1221#if 0
1222 /* this is the place to patch some storage devices */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001223 USB_STOR_PRINTF("iVendor %X iProduct %X\n", dev->descriptor.idVendor,
1224 dev->descriptor.idProduct);
1225
1226 if ((dev->descriptor.idVendor) == 0x066b &&
1227 (dev->descriptor.idProduct) == 0x0103) {
wdenkaffae2b2002-08-17 09:36:01 +00001228 USB_STOR_PRINTF("patched for E-USB\n");
1229 protocol = US_PR_CB;
1230 subclass = US_SC_UFI; /* an assumption */
1231 }
1232#endif
1233
1234 if (dev->descriptor.bDeviceClass != 0 ||
Tom Rix8f8bd562009-10-31 12:37:38 -05001235 iface->desc.bInterfaceClass != USB_CLASS_MASS_STORAGE ||
1236 iface->desc.bInterfaceSubClass < US_SC_MIN ||
1237 iface->desc.bInterfaceSubClass > US_SC_MAX) {
wdenkaffae2b2002-08-17 09:36:01 +00001238 /* if it's not a mass storage, we go no further */
1239 return 0;
1240 }
1241
Wolfgang Denk9c998aa2005-07-21 11:57:57 +02001242 memset(ss, 0, sizeof(struct us_data));
1243
wdenkaffae2b2002-08-17 09:36:01 +00001244 /* At this point, we know we've got a live one */
1245 USB_STOR_PRINTF("\n\nUSB Mass Storage device detected\n");
1246
1247 /* Initialize the us_data structure with some useful info */
1248 ss->flags = flags;
1249 ss->ifnum = ifnum;
1250 ss->pusb_dev = dev;
1251 ss->attention_done = 0;
1252
1253 /* If the device has subclass and protocol, then use that. Otherwise,
1254 * take data from the specific interface.
1255 */
1256 if (subclass) {
1257 ss->subclass = subclass;
1258 ss->protocol = protocol;
1259 } else {
Tom Rix8f8bd562009-10-31 12:37:38 -05001260 ss->subclass = iface->desc.bInterfaceSubClass;
1261 ss->protocol = iface->desc.bInterfaceProtocol;
wdenkaffae2b2002-08-17 09:36:01 +00001262 }
1263
1264 /* set the handler pointers based on the protocol */
1265 USB_STOR_PRINTF("Transport: ");
1266 switch (ss->protocol) {
1267 case US_PR_CB:
1268 USB_STOR_PRINTF("Control/Bulk\n");
1269 ss->transport = usb_stor_CB_transport;
1270 ss->transport_reset = usb_stor_CB_reset;
1271 break;
1272
1273 case US_PR_CBI:
1274 USB_STOR_PRINTF("Control/Bulk/Interrupt\n");
1275 ss->transport = usb_stor_CB_transport;
1276 ss->transport_reset = usb_stor_CB_reset;
1277 break;
wdenk149dded2003-09-10 18:20:28 +00001278 case US_PR_BULK:
1279 USB_STOR_PRINTF("Bulk/Bulk/Bulk\n");
1280 ss->transport = usb_stor_BBB_transport;
1281 ss->transport_reset = usb_stor_BBB_reset;
1282 break;
wdenkaffae2b2002-08-17 09:36:01 +00001283 default:
wdenk80885a92004-02-26 23:46:20 +00001284 printf("USB Storage Transport unknown / not yet implemented\n");
wdenkaffae2b2002-08-17 09:36:01 +00001285 return 0;
1286 break;
1287 }
1288
1289 /*
1290 * We are expecting a minimum of 2 endpoints - in and out (bulk).
1291 * An optional interrupt is OK (necessary for CBI protocol).
1292 * We will ignore any others.
1293 */
Tom Rix8f8bd562009-10-31 12:37:38 -05001294 for (i = 0; i < iface->desc.bNumEndpoints; i++) {
wdenkaffae2b2002-08-17 09:36:01 +00001295 /* is it an BULK endpoint? */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001296 if ((iface->ep_desc[i].bmAttributes &
1297 USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) {
wdenkaffae2b2002-08-17 09:36:01 +00001298 if (iface->ep_desc[i].bEndpointAddress & USB_DIR_IN)
1299 ss->ep_in = iface->ep_desc[i].bEndpointAddress &
1300 USB_ENDPOINT_NUMBER_MASK;
1301 else
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001302 ss->ep_out =
1303 iface->ep_desc[i].bEndpointAddress &
wdenkaffae2b2002-08-17 09:36:01 +00001304 USB_ENDPOINT_NUMBER_MASK;
1305 }
1306
1307 /* is it an interrupt endpoint? */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001308 if ((iface->ep_desc[i].bmAttributes &
1309 USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) {
wdenkaffae2b2002-08-17 09:36:01 +00001310 ss->ep_int = iface->ep_desc[i].bEndpointAddress &
1311 USB_ENDPOINT_NUMBER_MASK;
1312 ss->irqinterval = iface->ep_desc[i].bInterval;
1313 }
1314 }
1315 USB_STOR_PRINTF("Endpoints In %d Out %d Int %d\n",
1316 ss->ep_in, ss->ep_out, ss->ep_int);
1317
1318 /* Do some basic sanity checks, and bail if we find a problem */
Tom Rix8f8bd562009-10-31 12:37:38 -05001319 if (usb_set_interface(dev, iface->desc.bInterfaceNumber, 0) ||
wdenkaffae2b2002-08-17 09:36:01 +00001320 !ss->ep_in || !ss->ep_out ||
1321 (ss->protocol == US_PR_CBI && ss->ep_int == 0)) {
1322 USB_STOR_PRINTF("Problems with device\n");
1323 return 0;
1324 }
1325 /* set class specific stuff */
wdenk149dded2003-09-10 18:20:28 +00001326 /* We only handle certain protocols. Currently, these are
1327 * the only ones.
wdenk80885a92004-02-26 23:46:20 +00001328 * The SFF8070 accepts the requests used in u-boot
wdenkaffae2b2002-08-17 09:36:01 +00001329 */
wdenk80885a92004-02-26 23:46:20 +00001330 if (ss->subclass != US_SC_UFI && ss->subclass != US_SC_SCSI &&
1331 ss->subclass != US_SC_8070) {
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001332 printf("Sorry, protocol %d not yet supported.\n", ss->subclass);
wdenkaffae2b2002-08-17 09:36:01 +00001333 return 0;
1334 }
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001335 if (ss->ep_int) {
1336 /* we had found an interrupt endpoint, prepare irq pipe
1337 * set up the IRQ pipe and handler
1338 */
wdenkaffae2b2002-08-17 09:36:01 +00001339 ss->irqinterval = (ss->irqinterval > 0) ? ss->irqinterval : 255;
1340 ss->irqpipe = usb_rcvintpipe(ss->pusb_dev, ss->ep_int);
1341 ss->irqmaxp = usb_maxpacket(dev, ss->irqpipe);
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001342 dev->irq_handle = usb_stor_irq;
wdenkaffae2b2002-08-17 09:36:01 +00001343 }
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001344 dev->privptr = (void *)ss;
wdenkaffae2b2002-08-17 09:36:01 +00001345 return 1;
1346}
1347
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001348int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
1349 block_dev_desc_t *dev_desc)
wdenkaffae2b2002-08-17 09:36:01 +00001350{
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001351 unsigned char perq, modi;
Puneet Saxenaf5766132012-04-03 14:56:06 +05301352 ALLOC_CACHE_ALIGN_BUFFER(unsigned long, cap, 2);
1353 ALLOC_CACHE_ALIGN_BUFFER(unsigned char, usb_stor_buf, 36);
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001354 unsigned long *capacity, *blksz;
Wolfgang Denk9c998aa2005-07-21 11:57:57 +02001355 ccb *pccb = &usb_ccb;
wdenkaffae2b2002-08-17 09:36:01 +00001356
Wolfgang Denk9c998aa2005-07-21 11:57:57 +02001357 pccb->pdata = usb_stor_buf;
1358
1359 dev_desc->target = dev->devnum;
1360 pccb->lun = dev_desc->lun;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001361 USB_STOR_PRINTF(" address %d\n", dev_desc->target);
wdenkaffae2b2002-08-17 09:36:01 +00001362
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001363 if (usb_inquiry(pccb, ss))
wdenkaffae2b2002-08-17 09:36:01 +00001364 return -1;
Wolfgang Denk095b8a32005-08-02 17:06:17 +02001365
Wolfgang Denk9c998aa2005-07-21 11:57:57 +02001366 perq = usb_stor_buf[0];
1367 modi = usb_stor_buf[1];
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001368
1369 if ((perq & 0x1f) == 0x1f) {
1370 /* skip unknown devices */
1371 return 0;
wdenkaffae2b2002-08-17 09:36:01 +00001372 }
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001373 if ((modi&0x80) == 0x80) {
1374 /* drive is removable */
Wolfgang Denk9c998aa2005-07-21 11:57:57 +02001375 dev_desc->removable = 1;
wdenkaffae2b2002-08-17 09:36:01 +00001376 }
Puneet Saxenaf5766132012-04-03 14:56:06 +05301377 memcpy(&dev_desc->vendor[0], (const void *) &usb_stor_buf[8], 8);
1378 memcpy(&dev_desc->product[0], (const void *) &usb_stor_buf[16], 16);
1379 memcpy(&dev_desc->revision[0], (const void *) &usb_stor_buf[32], 4);
Wolfgang Denk9c998aa2005-07-21 11:57:57 +02001380 dev_desc->vendor[8] = 0;
1381 dev_desc->product[16] = 0;
1382 dev_desc->revision[4] = 0;
Bartlomiej Siekaddde6b72006-08-22 10:38:18 +02001383#ifdef CONFIG_USB_BIN_FIXUP
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001384 usb_bin_fixup(dev->descriptor, (uchar *)dev_desc->vendor,
1385 (uchar *)dev_desc->product);
Bartlomiej Siekaddde6b72006-08-22 10:38:18 +02001386#endif /* CONFIG_USB_BIN_FIXUP */
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001387 USB_STOR_PRINTF("ISO Vers %X, Response Data %X\n", usb_stor_buf[2],
1388 usb_stor_buf[3]);
1389 if (usb_test_unit_ready(pccb, ss)) {
1390 printf("Device NOT ready\n"
1391 " Request Sense returned %02X %02X %02X\n",
1392 pccb->sense_buf[2], pccb->sense_buf[12],
1393 pccb->sense_buf[13]);
1394 if (dev_desc->removable == 1) {
Wolfgang Denk9c998aa2005-07-21 11:57:57 +02001395 dev_desc->type = perq;
wdenkaffae2b2002-08-17 09:36:01 +00001396 return 1;
1397 }
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001398 return 0;
wdenkaffae2b2002-08-17 09:36:01 +00001399 }
Wolfgang Denk9c998aa2005-07-21 11:57:57 +02001400 pccb->pdata = (unsigned char *)&cap[0];
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001401 memset(pccb->pdata, 0, 8);
1402 if (usb_read_capacity(pccb, ss) != 0) {
wdenkaffae2b2002-08-17 09:36:01 +00001403 printf("READ_CAP ERROR\n");
Wolfgang Denk9c998aa2005-07-21 11:57:57 +02001404 cap[0] = 2880;
1405 cap[1] = 0x200;
wdenkaffae2b2002-08-17 09:36:01 +00001406 }
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001407 USB_STOR_PRINTF("Read Capacity returns: 0x%lx, 0x%lx\n", cap[0],
1408 cap[1]);
wdenkaffae2b2002-08-17 09:36:01 +00001409#if 0
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001410 if (cap[0] > (0x200000 * 10)) /* greater than 10 GByte */
1411 cap[0] >>= 16;
wdenkaffae2b2002-08-17 09:36:01 +00001412#endif
Christian Eggersc9182612008-05-21 22:12:00 +02001413 cap[0] = cpu_to_be32(cap[0]);
1414 cap[1] = cpu_to_be32(cap[1]);
1415
wdenk149dded2003-09-10 18:20:28 +00001416 /* this assumes bigendian! */
Wolfgang Denk9c998aa2005-07-21 11:57:57 +02001417 cap[0] += 1;
1418 capacity = &cap[0];
1419 blksz = &cap[1];
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001420 USB_STOR_PRINTF("Capacity = 0x%lx, blocksz = 0x%lx\n",
1421 *capacity, *blksz);
Wolfgang Denk9c998aa2005-07-21 11:57:57 +02001422 dev_desc->lba = *capacity;
1423 dev_desc->blksz = *blksz;
1424 dev_desc->type = perq;
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001425 USB_STOR_PRINTF(" address %d\n", dev_desc->target);
1426 USB_STOR_PRINTF("partype: %d\n", dev_desc->part_type);
wdenkaffae2b2002-08-17 09:36:01 +00001427
1428 init_part(dev_desc);
1429
Michael Trimarchia0cb3fc2008-12-10 15:52:06 +01001430 USB_STOR_PRINTF("partype: %d\n", dev_desc->part_type);
wdenkaffae2b2002-08-17 09:36:01 +00001431 return 1;
1432}