]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - common/usb_storage.c
* Fix minor NAND JFFS2 related issue
[karo-tx-uboot.git] / common / usb_storage.c
1 /*
2  * (C) Copyright 2001
3  * Denis Peter, MPL AG Switzerland
4  *
5  * For BBB support (C) Copyright 2003
6  * Gary Jennejohn, DENX Software Engineering <gj@denx.de>
7  *
8  * Most of this source has been derived from the Linux USB
9  * project. BBB support based on /sys/dev/usb/umass.c from
10  * FreeBSD.
11  *
12  * See file CREDITS for list of people who contributed to this
13  * project.
14  *
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License as
17  * published by the Free Software Foundation; either version 2 of
18  * the License, or (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
28  * MA 02111-1307 USA
29  *
30  */
31
32 /* Note:
33  * Currently only the CBI transport protocoll has been implemented, and it
34  * is only tested with a TEAC USB Floppy. Other Massstorages with CBI or CB
35  * transport protocoll may work as well.
36  */
37 /*
38  * New Note:
39  * Support for USB Mass Storage Devices (BBB) has been added. It has
40  * only been tested with USB memory sticks.
41  * Nota bene: if you are using the BBB support with a little-endian
42  * CPU then you MUST define LITTLEENDIAN in the configuration file!
43  */
44
45
46 #include <common.h>
47 #include <command.h>
48 #include <asm/processor.h>
49
50
51 #if (CONFIG_COMMANDS & CFG_CMD_USB)
52 #include <usb.h>
53
54 #ifdef CONFIG_USB_STORAGE
55
56 #undef USB_STOR_DEBUG
57 #undef BBB_COMDAT_TRACE
58 #undef BBB_XPORT_TRACE
59
60 #ifdef  USB_STOR_DEBUG
61 #define USB_STOR_PRINTF(fmt,args...)    printf (fmt ,##args)
62 #else
63 #define USB_STOR_PRINTF(fmt,args...)
64 #endif
65
66 #include <scsi.h>
67 /* direction table -- this indicates the direction of the data
68  * transfer for each command code -- a 1 indicates input
69  */
70 unsigned char us_direction[256/8] = {
71         0x28, 0x81, 0x14, 0x14, 0x20, 0x01, 0x90, 0x77,
72         0x0C, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
73         0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01,
74         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
75 };
76 #define US_DIRECTION(x) ((us_direction[x>>3] >> (x & 7)) & 1)
77
78 static unsigned char usb_stor_buf[512];
79 static ccb usb_ccb;
80
81 /*
82  * CBI style
83  */
84
85 #define US_CBI_ADSC             0
86
87 /*
88  * BULK only
89  */
90 #define US_BBB_RESET            0xff
91 #define US_BBB_GET_MAX_LUN      0xfe
92
93 /* Command Block Wrapper */
94 typedef struct {
95         __u32           dCBWSignature;
96 #       define CBWSIGNATURE     0x43425355
97         __u32           dCBWTag;
98         __u32           dCBWDataTransferLength;
99         __u8            bCBWFlags;
100 #       define CBWFLAGS_OUT     0x00
101 #       define CBWFLAGS_IN      0x80
102         __u8            bCBWLUN;
103         __u8            bCDBLength;
104 #       define CBWCDBLENGTH     16
105         __u8            CBWCDB[CBWCDBLENGTH];
106 } umass_bbb_cbw_t;
107 #define UMASS_BBB_CBW_SIZE      31
108 static __u32 CBWTag = 0;
109
110 /* Command Status Wrapper */
111 typedef struct {
112         __u32           dCSWSignature;
113 #       define CSWSIGNATURE     0x53425355
114         __u32           dCSWTag;
115         __u32           dCSWDataResidue;
116         __u8            bCSWStatus;
117 #       define CSWSTATUS_GOOD   0x0
118 #       define CSWSTATUS_FAILED 0x1
119 #       define CSWSTATUS_PHASE  0x2
120 } umass_bbb_csw_t;
121 #define UMASS_BBB_CSW_SIZE      13
122
123 #define USB_MAX_STOR_DEV 5
124 static int usb_max_devs; /* number of highest available usb device */
125
126 static block_dev_desc_t usb_dev_desc[USB_MAX_STOR_DEV];
127
128 struct us_data;
129 typedef int (*trans_cmnd)(ccb*, struct us_data*);
130 typedef int (*trans_reset)(struct us_data*);
131
132 struct us_data {
133         struct usb_device       *pusb_dev;       /* this usb_device */
134         unsigned int            flags;           /* from filter initially */
135         unsigned char           ifnum;           /* interface number */
136         unsigned char           ep_in;           /* in endpoint */
137         unsigned char           ep_out;          /* out ....... */
138         unsigned char           ep_int;          /* interrupt . */
139         unsigned char           subclass;        /* as in overview */
140         unsigned char           protocol;        /* .............. */
141         unsigned char           attention_done;  /* force attn on first cmd */
142         unsigned short  ip_data;         /* interrupt data */
143         int                                                     action;          /* what to do */
144         int                                                     ip_wanted; /* needed */
145         int                                                     *irq_handle;     /* for USB int requests */
146         unsigned int            irqpipe;         /* pipe for release_irq */
147         unsigned char           irqmaxp;        /* max packed for irq Pipe */
148         unsigned char   irqinterval; /* Intervall for IRQ Pipe */
149         ccb                                                     *srb;            /* current srb */
150         trans_reset                     transport_reset; /* reset routine */
151         trans_cmnd                      transport; /* transport routine */
152 };
153
154 static struct us_data usb_stor[USB_MAX_STOR_DEV];
155
156
157 #define USB_STOR_TRANSPORT_GOOD    0
158 #define USB_STOR_TRANSPORT_FAILED -1
159 #define USB_STOR_TRANSPORT_ERROR  -2
160
161
162 int usb_stor_get_info(struct usb_device *dev, struct us_data *us, block_dev_desc_t *dev_desc);
163 int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,struct us_data *ss);
164 unsigned long usb_stor_read(int device, unsigned long blknr, unsigned long blkcnt, unsigned long *buffer);
165 struct usb_device * usb_get_dev_index(int index);
166 void uhci_show_temp_int_td(void);
167
168 block_dev_desc_t *usb_stor_get_dev(int index)
169 {
170         return &usb_dev_desc[index];
171 }
172
173
174 void usb_show_progress(void)
175 {
176         printf(".");
177 }
178
179 /*********************************************************************************
180  * (re)-scan the usb and reports device info
181  * to the user if mode = 1
182  * returns current device or -1 if no
183  */
184 int usb_stor_scan(int mode)
185 {
186         unsigned char i;
187         struct usb_device *dev;
188
189         /* GJ */
190         memset(usb_stor_buf, 0, sizeof(usb_stor_buf));
191
192         if(mode==1) {
193                 printf("       scanning bus for storage devices...\n");
194         }
195         usb_disable_asynch(1); /* asynch transfer not allowed */
196
197         for(i=0;i<USB_MAX_STOR_DEV;i++) {
198                 memset(&usb_dev_desc[i],0,sizeof(block_dev_desc_t));
199                 usb_dev_desc[i].target=0xff;
200                 usb_dev_desc[i].if_type=IF_TYPE_USB;
201                 usb_dev_desc[i].dev=i;
202                 usb_dev_desc[i].part_type=PART_TYPE_UNKNOWN;
203                 usb_dev_desc[i].block_read=usb_stor_read;
204         }
205         usb_max_devs=0;
206         for(i=0;i<USB_MAX_DEVICE;i++) {
207                 dev=usb_get_dev_index(i); /* get device */
208                 USB_STOR_PRINTF("i=%d\n",i);
209                 if(dev==NULL) {
210                         break; /* no more devices avaiable */
211                 }
212                 if(usb_storage_probe(dev,0,&usb_stor[usb_max_devs])) { /* ok, it is a storage devices */
213                         /* get info and fill it in */
214
215                         if(usb_stor_get_info(dev, &usb_stor[usb_max_devs], &usb_dev_desc[usb_max_devs])) {
216                                 if(mode==1) {
217                                         printf ("  Device %d: ", usb_max_devs);
218                                         dev_print(&usb_dev_desc[usb_max_devs]);
219                                 } /* if mode */
220                                 usb_max_devs++;
221                         } /* if get info ok */
222                 } /* if storage device */
223                 if(usb_max_devs==USB_MAX_STOR_DEV) {
224                         printf("max USB Storage Device reached: %d stopping\n",usb_max_devs);
225                         break;
226                 }
227         } /* for */
228         usb_disable_asynch(0); /* asynch transfer allowed */
229         if(usb_max_devs>0)
230                 return 0;
231         else
232                 return-1;
233 }
234
235 static int usb_stor_irq(struct usb_device *dev)
236 {
237         struct us_data *us;
238         us=(struct us_data *)dev->privptr;
239
240         if(us->ip_wanted) {
241                 us->ip_wanted=0;
242         }
243         return 0;
244 }
245
246
247 #ifdef  USB_STOR_DEBUG
248
249 static void usb_show_srb(ccb * pccb)
250 {
251         int i;
252         printf("SRB: len %d datalen 0x%lX\n ",pccb->cmdlen,pccb->datalen);
253         for(i=0;i<12;i++) {
254                 printf("%02X ",pccb->cmd[i]);
255         }
256         printf("\n");
257 }
258
259 static void display_int_status(unsigned long tmp)
260 {
261         printf("Status: %s %s %s %s %s %s %s\n",
262                 (tmp & USB_ST_ACTIVE) ? "Active" : "",
263                 (tmp & USB_ST_STALLED) ? "Stalled" : "",
264                 (tmp & USB_ST_BUF_ERR) ? "Buffer Error" : "",
265                 (tmp & USB_ST_BABBLE_DET) ? "Babble Det" : "",
266                 (tmp & USB_ST_NAK_REC) ? "NAKed" : "",
267                 (tmp & USB_ST_CRC_ERR) ? "CRC Error" : "",
268                 (tmp & USB_ST_BIT_ERR) ? "Bitstuff Error" : "");
269 }
270 #endif
271 /***********************************************************************
272  * Data transfer routines
273  ***********************************************************************/
274
275 static int us_one_transfer(struct us_data *us, int pipe, char *buf, int length)
276 {
277         int max_size;
278         int this_xfer;
279         int result;
280         int partial;
281         int maxtry;
282         int stat;
283
284         /* determine the maximum packet size for these transfers */
285         max_size = usb_maxpacket(us->pusb_dev, pipe) * 16;
286
287         /* while we have data left to transfer */
288         while (length) {
289
290                 /* calculate how long this will be -- maximum or a remainder */
291                 this_xfer = length > max_size ? max_size : length;
292                 length -= this_xfer;
293
294                 /* setup the retry counter */
295                 maxtry = 10;
296
297                 /* set up the transfer loop */
298                 do {
299                         /* transfer the data */
300                         USB_STOR_PRINTF("Bulk xfer 0x%x(%d) try #%d\n",
301                                   (unsigned int)buf, this_xfer, 11 - maxtry);
302                         result = usb_bulk_msg(us->pusb_dev, pipe, buf,
303                                               this_xfer, &partial, USB_CNTL_TIMEOUT*5);
304                         USB_STOR_PRINTF("bulk_msg returned %d xferred %d/%d\n",
305                                   result, partial, this_xfer);
306                         if(us->pusb_dev->status!=0) {
307                                 /* if we stall, we need to clear it before we go on */
308 #ifdef USB_STOR_DEBUG
309                                 display_int_status(us->pusb_dev->status);
310 #endif
311                                 if (us->pusb_dev->status & USB_ST_STALLED) {
312                                         USB_STOR_PRINTF("stalled ->clearing endpoint halt for pipe 0x%x\n", pipe);
313                                         stat = us->pusb_dev->status;
314                                         usb_clear_halt(us->pusb_dev, pipe);
315                                         us->pusb_dev->status=stat;
316                                         if(this_xfer == partial) {
317                                                 USB_STOR_PRINTF("bulk transferred with error %X, but data ok\n",us->pusb_dev->status);
318                                                 return 0;
319                                         }
320                                         else
321                                                 return result;
322                                 }
323                                 if (us->pusb_dev->status & USB_ST_NAK_REC) {
324                                         USB_STOR_PRINTF("Device NAKed bulk_msg\n");
325                                         return result;
326                                 }
327                                 if(this_xfer == partial) {
328                                         USB_STOR_PRINTF("bulk transferred with error %d, but data ok\n",us->pusb_dev->status);
329                                         return 0;
330                                 }
331                                 /* if our try counter reaches 0, bail out */
332                                 USB_STOR_PRINTF("bulk transferred with error %d, data %d\n",us->pusb_dev->status,partial);
333                                 if (!maxtry--)
334                                                 return result;
335                         }
336                         /* update to show what data was transferred */
337                         this_xfer -= partial;
338                         buf += partial;
339                         /* continue until this transfer is done */
340                 } while ( this_xfer );
341         }
342
343         /* if we get here, we're done and successful */
344         return 0;
345 }
346
347 static int usb_stor_BBB_reset(struct us_data *us)
348 {
349         int result;
350         unsigned int pipe;
351
352         /*
353          * Reset recovery (5.3.4 in Universal Serial Bus Mass Storage Class)
354          *
355          * For Reset Recovery the host shall issue in the following order:
356          * a) a Bulk-Only Mass Storage Reset
357          * b) a Clear Feature HALT to the Bulk-In endpoint
358          * c) a Clear Feature HALT to the Bulk-Out endpoint
359          *
360          * This is done in 3 steps.
361          *
362          * If the reset doesn't succeed, the device should be port reset.
363          *
364          * This comment stolen from FreeBSD's /sys/dev/usb/umass.c.
365          */
366         USB_STOR_PRINTF("BBB_reset\n");
367         result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0),
368                                  US_BBB_RESET, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
369                                  0, us->ifnum, 0, 0, USB_CNTL_TIMEOUT*5);
370         if((result < 0) && (us->pusb_dev->status & USB_ST_STALLED))
371         {
372                 USB_STOR_PRINTF("RESET:stall\n");
373                 return -1;
374         }
375         /* long wait for reset */
376         wait_ms(150);
377         USB_STOR_PRINTF("BBB_reset result %d: status %X reset\n",result,us->pusb_dev->status);
378         pipe = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
379         result = usb_clear_halt(us->pusb_dev, pipe);
380         /* long wait for reset */
381         wait_ms(150);
382         USB_STOR_PRINTF("BBB_reset result %d: status %X clearing IN endpoint\n",result,us->pusb_dev->status);
383         /* long wait for reset */
384         pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
385         result = usb_clear_halt(us->pusb_dev, pipe);
386         wait_ms(150);
387         USB_STOR_PRINTF("BBB_reset result %d: status %X clearing OUT endpoint\n",result,us->pusb_dev->status);
388         USB_STOR_PRINTF("BBB_reset done\n");
389         return 0;
390 }
391
392 /* FIXME: this reset function doesn't really reset the port, and it
393  * should. Actually it should probably do what it's doing here, and
394  * reset the port physically
395  */
396 static int usb_stor_CB_reset(struct us_data *us)
397 {
398         unsigned char cmd[12];
399         int result;
400
401         USB_STOR_PRINTF("CB_reset\n");
402         memset(cmd, 0xFF, sizeof(cmd));
403         cmd[0] = SCSI_SEND_DIAG;
404         cmd[1] = 4;
405         result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0),
406                                  US_CBI_ADSC, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
407                                  0, us->ifnum, cmd, sizeof(cmd), USB_CNTL_TIMEOUT*5);
408
409         /* long wait for reset */
410         wait_ms(1500);
411         USB_STOR_PRINTF("CB_reset result %d: status %X clearing endpoint halt\n",result,us->pusb_dev->status);
412         usb_clear_halt(us->pusb_dev, usb_rcvbulkpipe(us->pusb_dev, us->ep_in));
413         usb_clear_halt(us->pusb_dev, usb_rcvbulkpipe(us->pusb_dev, us->ep_out));
414
415         USB_STOR_PRINTF("CB_reset done\n");
416         return 0;
417 }
418
419 /*
420  * Set up the command for a BBB device. Note that the actual SCSI
421  * command is copied into cbw.CBWCDB.
422  */
423 int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
424 {
425         int result;
426         int actlen;
427         int dir_in;
428         unsigned int pipe;
429         umass_bbb_cbw_t cbw;
430
431         dir_in = US_DIRECTION(srb->cmd[0]);
432
433 #ifdef BBB_COMDAT_TRACE
434         printf("dir %d lun %d cmdlen %d cmd %p datalen %d pdata %p\n", dir_in, srb->lun, srb->cmdlen, srb->cmd, srb->datalen, srb->pdata);
435         if (srb->cmdlen) {
436                 for(result = 0;result < srb->cmdlen;result++)
437                         printf("cmd[%d] %#x ", result, srb->cmd[result]);
438                 printf("\n");
439         }
440 #endif
441         /* sanity checks */
442         if (!(srb->cmdlen <= CBWCDBLENGTH)) {
443                 USB_STOR_PRINTF("usb_stor_BBB_comdat:cmdlen too large\n");
444                 return -1;
445         }
446
447         /* always OUT to the ep */
448         pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
449
450         cbw.dCBWSignature = swap_32(CBWSIGNATURE);
451         cbw.dCBWTag = swap_32(CBWTag++);
452         cbw.dCBWDataTransferLength = swap_32(srb->datalen);
453         cbw.bCBWFlags = (dir_in? CBWFLAGS_IN : CBWFLAGS_OUT);
454         cbw.bCBWLUN = srb->lun;
455         cbw.bCDBLength = srb->cmdlen;
456         /* copy the command data into the CBW command data buffer */
457         /* DST SRC LEN!!! */
458         memcpy(cbw.CBWCDB, srb->cmd, srb->cmdlen);
459         result = usb_bulk_msg(us->pusb_dev, pipe, &cbw, UMASS_BBB_CBW_SIZE, &actlen, USB_CNTL_TIMEOUT*5);
460         if (result < 0)
461                 USB_STOR_PRINTF("usb_stor_BBB_comdat:usb_bulk_msg error\n");
462         return result;
463 }
464
465 /* FIXME: we also need a CBI_command which sets up the completion
466  * interrupt, and waits for it
467  */
468 int usb_stor_CB_comdat(ccb *srb, struct us_data *us)
469 {
470         int result;
471         int dir_in,retry;
472         unsigned int pipe;
473         unsigned long status;
474
475         retry=5;
476                 dir_in=US_DIRECTION(srb->cmd[0]);
477
478                 if(dir_in)
479                         pipe=usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
480                 else
481                         pipe=usb_sndbulkpipe(us->pusb_dev, us->ep_out);
482         while(retry--) {
483                 USB_STOR_PRINTF("CBI gets a command: Try %d\n",5-retry);
484 #ifdef USB_STOR_DEBUG
485                 usb_show_srb(srb);
486 #endif
487                 /* let's send the command via the control pipe */
488                 result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0),
489                                          US_CBI_ADSC, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
490                                          0, us->ifnum,
491                                          srb->cmd, srb->cmdlen, USB_CNTL_TIMEOUT*5);
492                 USB_STOR_PRINTF("CB_transport: control msg returned %d, status %X\n",result,us->pusb_dev->status);
493                 /* check the return code for the command */
494                 if (result < 0) {
495                         if(us->pusb_dev->status & USB_ST_STALLED) {
496                                 status=us->pusb_dev->status;
497                                 USB_STOR_PRINTF(" stall during command found, clear pipe\n");
498                                 usb_clear_halt(us->pusb_dev,  usb_sndctrlpipe(us->pusb_dev,0));
499                                 us->pusb_dev->status=status;
500                         }
501                         USB_STOR_PRINTF(" error during command %02X Stat = %X\n",srb->cmd[0],us->pusb_dev->status);
502                         return result;
503                 }
504                 /* transfer the data payload for this command, if one exists*/
505
506                 USB_STOR_PRINTF("CB_transport: control msg returned %d, direction is %s to go 0x%lx\n",result,dir_in ? "IN" : "OUT",srb->datalen);
507                 if (srb->datalen) {
508                         result = us_one_transfer(us, pipe, srb->pdata,srb->datalen);
509                         USB_STOR_PRINTF("CBI attempted to transfer data, result is %d status %lX, len %d\n", result,us->pusb_dev->status,us->pusb_dev->act_len);
510                         if(!(us->pusb_dev->status & USB_ST_NAK_REC))
511                                 break;
512                 } /* if (srb->datalen) */
513                 else
514                         break;
515         }
516         /* return result */
517
518         return result;
519 }
520
521
522 int usb_stor_CBI_get_status (ccb * srb, struct us_data *us)
523 {
524         int timeout;
525
526         us->ip_wanted = 1;
527         submit_int_msg (us->pusb_dev, us->irqpipe,
528                         (void *) &us->ip_data, us->irqmaxp, us->irqinterval);
529         timeout = 1000;
530         while (timeout--) {
531                 if ((volatile int *) us->ip_wanted == 0)
532                         break;
533                 wait_ms (10);
534         }
535         if (us->ip_wanted) {
536                 printf ("       Did not get interrupt on CBI\n");
537                 us->ip_wanted = 0;
538                 return USB_STOR_TRANSPORT_ERROR;
539         }
540         USB_STOR_PRINTF
541                 ("Got interrupt data 0x%x, transfered %d status 0x%lX\n",
542                  us->ip_data, us->pusb_dev->irq_act_len,
543                  us->pusb_dev->irq_status);
544         /* UFI gives us ASC and ASCQ, like a request sense */
545         if (us->subclass == US_SC_UFI) {
546                 if (srb->cmd[0] == SCSI_REQ_SENSE ||
547                     srb->cmd[0] == SCSI_INQUIRY)
548                         return USB_STOR_TRANSPORT_GOOD; /* Good */
549                 else if (us->ip_data)
550                         return USB_STOR_TRANSPORT_FAILED;
551                 else
552                         return USB_STOR_TRANSPORT_GOOD;
553         }
554         /* otherwise, we interpret the data normally */
555         switch (us->ip_data) {
556         case 0x0001:
557                 return USB_STOR_TRANSPORT_GOOD;
558         case 0x0002:
559                 return USB_STOR_TRANSPORT_FAILED;
560         default:
561                 return USB_STOR_TRANSPORT_ERROR;
562         }                       /* switch */
563         return USB_STOR_TRANSPORT_ERROR;
564 }
565
566 #define USB_TRANSPORT_UNKNOWN_RETRY 5
567 #define USB_TRANSPORT_NOT_READY_RETRY 10
568
569 /* clear a stall on an endpoint - special for BBB devices */
570 int usb_stor_BBB_clear_endpt_stall(struct us_data *us, __u8 endpt)
571 {
572         int result;
573
574         /* ENDPOINT_HALT = 0, so set value to 0 */
575         result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0),
576                                 USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT,
577                                 0, endpt, 0, 0, USB_CNTL_TIMEOUT*5);
578         return result;
579 }
580
581 int usb_stor_BBB_transport(ccb *srb, struct us_data *us)
582 {
583         int result, retry;
584         int dir_in;
585         int actlen, data_actlen;
586         unsigned int pipe, pipein, pipeout;
587         umass_bbb_csw_t csw;
588 #ifdef BBB_XPORT_TRACE
589         unsigned char *ptr;
590         int index;
591 #endif
592
593         dir_in = US_DIRECTION(srb->cmd[0]);
594
595         /* COMMAND phase */
596         USB_STOR_PRINTF("COMMAND phase\n");
597         result = usb_stor_BBB_comdat(srb, us);
598         if (result < 0) {
599                 USB_STOR_PRINTF("failed to send CBW status %ld\n",
600                         us->pusb_dev->status);
601                 usb_stor_BBB_reset(us);
602                 return USB_STOR_TRANSPORT_FAILED;
603         }
604         wait_ms(5);
605         pipein = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
606         pipeout = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
607         /* DATA phase + error handling */
608         data_actlen = 0;
609         /* no data, go immediately to the STATUS phase */
610         if (srb->datalen == 0)
611                 goto st;
612         USB_STOR_PRINTF("DATA phase\n");
613         if (dir_in)
614                 pipe = pipein;
615         else
616                 pipe = pipeout;
617         result = usb_bulk_msg(us->pusb_dev, pipe, srb->pdata, srb->datalen, &data_actlen, USB_CNTL_TIMEOUT*5);
618         /* special handling of STALL in DATA phase */
619         if((result < 0) && (us->pusb_dev->status & USB_ST_STALLED)) {
620                 USB_STOR_PRINTF("DATA:stall\n");
621                 /* clear the STALL on the endpoint */
622                 result = usb_stor_BBB_clear_endpt_stall(us, dir_in? us->ep_in : us->ep_out);
623                 if (result >= 0)
624                         /* continue on to STATUS phase */
625                         goto st;
626         }
627         if (result < 0) {
628                 USB_STOR_PRINTF("usb_bulk_msg error status %ld\n",
629                         us->pusb_dev->status);
630                 usb_stor_BBB_reset(us);
631                 return USB_STOR_TRANSPORT_FAILED;
632         }
633 #ifdef BBB_XPORT_TRACE
634         for (index = 0; index < data_actlen; index++)
635                 printf("pdata[%d] %#x ", index, srb->pdata[index]);
636         printf("\n");
637 #endif
638         /* STATUS phase + error handling */
639    st:
640         retry = 0;
641    again:
642         USB_STOR_PRINTF("STATUS phase\n");
643         result = usb_bulk_msg(us->pusb_dev, pipein, &csw, UMASS_BBB_CSW_SIZE, &actlen, USB_CNTL_TIMEOUT*5);
644         /* special handling of STALL in STATUS phase */
645         if((result < 0) && (retry < 1) && (us->pusb_dev->status & USB_ST_STALLED)) {
646                 USB_STOR_PRINTF("STATUS:stall\n");
647                 /* clear the STALL on the endpoint */
648                 result = usb_stor_BBB_clear_endpt_stall(us, us->ep_in);
649                 if (result >= 0 && (retry++ < 1))
650                         /* do a retry */
651                         goto again;
652         }
653         if (result < 0) {
654                 USB_STOR_PRINTF("usb_bulk_msg error status %ld\n",
655                         us->pusb_dev->status);
656                 usb_stor_BBB_reset(us);
657                 return USB_STOR_TRANSPORT_FAILED;
658         }
659 #ifdef BBB_XPORT_TRACE
660         ptr = (unsigned char *)&csw;
661         for (index = 0; index < UMASS_BBB_CSW_SIZE; index++)
662                 printf("ptr[%d] %#x ", index, ptr[index]);
663         printf("\n");
664 #endif
665         /* misuse pipe to get the residue */
666         pipe = swap_32(csw.dCSWDataResidue);
667         if (pipe == 0 && srb->datalen != 0 && srb->datalen - data_actlen != 0)
668                 pipe = srb->datalen - data_actlen;
669         if (CSWSIGNATURE != swap_32(csw.dCSWSignature)) {
670                 USB_STOR_PRINTF("!CSWSIGNATURE\n");
671                 usb_stor_BBB_reset(us);
672                 return USB_STOR_TRANSPORT_FAILED;
673         } else if ((CBWTag - 1) != swap_32(csw.dCSWTag)) {
674                 USB_STOR_PRINTF("!Tag\n");
675                 usb_stor_BBB_reset(us);
676                 return USB_STOR_TRANSPORT_FAILED;
677         } else if (csw.bCSWStatus > CSWSTATUS_PHASE) {
678                 USB_STOR_PRINTF(">PHASE\n");
679                 usb_stor_BBB_reset(us);
680                 return USB_STOR_TRANSPORT_FAILED;
681         } else if (csw.bCSWStatus == CSWSTATUS_PHASE) {
682                 USB_STOR_PRINTF("=PHASE\n");
683                 usb_stor_BBB_reset(us);
684                 return USB_STOR_TRANSPORT_FAILED;
685         } else if (data_actlen > srb->datalen) {
686                 USB_STOR_PRINTF("transferred %dB instead of %dB\n",
687                         data_actlen, srb->datalen);
688                 return USB_STOR_TRANSPORT_FAILED;
689         } else if (csw.bCSWStatus == CSWSTATUS_FAILED) {
690                 USB_STOR_PRINTF("FAILED\n");
691                 return USB_STOR_TRANSPORT_FAILED;
692         }
693
694         return result;
695 }
696
697 int usb_stor_CB_transport(ccb *srb, struct us_data *us)
698 {
699         int result,status;
700         ccb *psrb;
701         ccb reqsrb;
702         int retry,notready;
703
704         psrb=&reqsrb;
705         status=USB_STOR_TRANSPORT_GOOD;
706         retry=0;
707         notready=0;
708         /* issue the command */
709 do_retry:
710         result=usb_stor_CB_comdat(srb,us);
711         USB_STOR_PRINTF("command / Data returned %d, status %X\n",result,us->pusb_dev->status);
712         /* if this is an CBI Protocol, get IRQ */
713         if(us->protocol==US_PR_CBI) {
714                 status=usb_stor_CBI_get_status(srb,us);
715                 /* if the status is error, report it */
716                 if(status==USB_STOR_TRANSPORT_ERROR) {
717                         USB_STOR_PRINTF(" USB CBI Command Error\n");
718                         return status;
719                 }
720                 srb->sense_buf[12]=(unsigned char)(us->ip_data>>8);
721                 srb->sense_buf[13]=(unsigned char)(us->ip_data&0xff);
722                 if(!us->ip_data) {
723                 /* if the status is good, report it */
724                         if(status==USB_STOR_TRANSPORT_GOOD) {
725                                 USB_STOR_PRINTF(" USB CBI Command Good\n");
726                                 return status;
727                         }
728                 }
729         }
730         /* do we have to issue an auto request? */
731         /* HERE we have to check the result */
732         if((result<0) && !(us->pusb_dev->status & USB_ST_STALLED)) {
733                 USB_STOR_PRINTF("ERROR %X\n",us->pusb_dev->status);
734                 us->transport_reset(us);
735                 return USB_STOR_TRANSPORT_ERROR;
736         }
737         if((us->protocol==US_PR_CBI) &&
738                         ((srb->cmd[0]==SCSI_REQ_SENSE) ||
739                         (srb->cmd[0]==SCSI_INQUIRY))) { /* do not issue an autorequest after request sense */
740                 USB_STOR_PRINTF("No auto request and good\n");
741                 return USB_STOR_TRANSPORT_GOOD;
742         }
743         /* issue an request_sense */
744         memset(&psrb->cmd[0],0,12);
745         psrb->cmd[0]=SCSI_REQ_SENSE;
746         psrb->cmd[1]=srb->lun<<5;
747         psrb->cmd[4]=18;
748         psrb->datalen=18;
749         psrb->pdata=&srb->sense_buf[0];
750         psrb->cmdlen=12;
751         /* issue the command */
752         result=usb_stor_CB_comdat(psrb,us);
753         USB_STOR_PRINTF("auto request returned %d\n",result);
754         /* if this is an CBI Protocol, get IRQ */
755         if(us->protocol==US_PR_CBI) {
756                 status=usb_stor_CBI_get_status(psrb,us);
757         }
758         if((result<0)&&!(us->pusb_dev->status & USB_ST_STALLED)) {
759                 USB_STOR_PRINTF(" AUTO REQUEST ERROR %d\n",us->pusb_dev->status);
760                 return USB_STOR_TRANSPORT_ERROR;
761         }
762         USB_STOR_PRINTF("autorequest returned 0x%02X 0x%02X 0x%02X 0x%02X\n",srb->sense_buf[0],srb->sense_buf[2],srb->sense_buf[12],srb->sense_buf[13]);
763         /* Check the auto request result */
764         if((srb->sense_buf[2]==0) &&
765                  (srb->sense_buf[12]==0) &&
766                  (srb->sense_buf[13]==0)) /* ok, no sense */
767                 return USB_STOR_TRANSPORT_GOOD;
768         /* Check the auto request result */
769         switch(srb->sense_buf[2]) {
770         case 0x01: /* Recovered Error */
771                 return USB_STOR_TRANSPORT_GOOD;
772                 break;
773         case 0x02: /* Not Ready */
774                 if(notready++ > USB_TRANSPORT_NOT_READY_RETRY) {
775                         printf("cmd 0x%02X returned 0x%02X 0x%02X 0x%02X 0x%02X (NOT READY)\n",
776                                 srb->cmd[0],srb->sense_buf[0],srb->sense_buf[2],srb->sense_buf[12],srb->sense_buf[13]);
777                         return USB_STOR_TRANSPORT_FAILED;
778                 } else {
779                         wait_ms(100);
780                         goto do_retry;
781                 }
782                 break;
783         default:
784                 if(retry++ > USB_TRANSPORT_UNKNOWN_RETRY) {
785                         printf("cmd 0x%02X returned 0x%02X 0x%02X 0x%02X 0x%02X\n",
786                                 srb->cmd[0],srb->sense_buf[0],srb->sense_buf[2],srb->sense_buf[12],srb->sense_buf[13]);
787                         return USB_STOR_TRANSPORT_FAILED;
788                 } else {
789                         goto do_retry;
790                 }
791                 break;
792         }
793         return USB_STOR_TRANSPORT_FAILED;
794 }
795
796
797 static int usb_inquiry(ccb *srb,struct us_data *ss)
798 {
799         int retry,i;
800         retry=3;
801         do {
802                 memset(&srb->cmd[0],0,12);
803                 srb->cmd[0]=SCSI_INQUIRY;
804                 srb->cmd[1]=srb->lun<<5;
805                 srb->cmd[4]=36;
806                 srb->datalen=36;
807                 srb->cmdlen=12;
808                 i=ss->transport(srb,ss);
809                 USB_STOR_PRINTF("inquiry returns %d\n",i);
810                 if(i==0)
811                         break;
812         } while(retry--);
813
814         if(!retry) {
815                 printf("error in inquiry\n");
816                 return -1;
817         }
818         return 0;
819 }
820
821 static int usb_request_sense(ccb *srb,struct us_data *ss)
822 {
823         char *ptr;
824
825         ptr=srb->pdata;
826         memset(&srb->cmd[0],0,12);
827         srb->cmd[0]=SCSI_REQ_SENSE;
828         srb->cmd[1]=srb->lun<<5;
829         srb->cmd[4]=18;
830         srb->datalen=18;
831         srb->pdata=&srb->sense_buf[0];
832         srb->cmdlen=12;
833         ss->transport(srb,ss);
834         USB_STOR_PRINTF("Request Sense returned %02X %02X %02X\n",srb->sense_buf[2],srb->sense_buf[12],srb->sense_buf[13]);
835         srb->pdata=ptr;
836         return 0;
837 }
838
839 static int usb_test_unit_ready(ccb *srb,struct us_data *ss)
840 {
841         int retries=10;
842
843         do {
844                 memset(&srb->cmd[0],0,12);
845                 srb->cmd[0]=SCSI_TST_U_RDY;
846                 srb->cmd[1]=srb->lun<<5;
847                 srb->datalen=0;
848                 srb->cmdlen=12;
849                 if(ss->transport(srb,ss)==USB_STOR_TRANSPORT_GOOD) {
850                         return 0;
851                 }
852                 usb_request_sense (srb, ss);
853                 wait_ms (100);
854         } while(retries--);
855
856         return -1;
857 }
858
859 static int usb_read_capacity(ccb *srb,struct us_data *ss)
860 {
861         int retry;
862         retry=2; /* retries */
863         do {
864                 memset(&srb->cmd[0],0,12);
865                 srb->cmd[0]=SCSI_RD_CAPAC;
866                 srb->cmd[1]=srb->lun<<5;
867                 srb->datalen=8;
868                 srb->cmdlen=12;
869                 if(ss->transport(srb,ss)==USB_STOR_TRANSPORT_GOOD) {
870                         return 0;
871                 }
872         } while(retry--);
873
874         return -1;
875 }
876
877 static int usb_read_10(ccb *srb,struct us_data *ss, unsigned long start, unsigned short blocks)
878 {
879         memset(&srb->cmd[0],0,12);
880         srb->cmd[0]=SCSI_READ10;
881         srb->cmd[1]=srb->lun<<5;
882         srb->cmd[2]=((unsigned char) (start>>24))&0xff;
883         srb->cmd[3]=((unsigned char) (start>>16))&0xff;
884         srb->cmd[4]=((unsigned char) (start>>8))&0xff;
885         srb->cmd[5]=((unsigned char) (start))&0xff;
886         srb->cmd[7]=((unsigned char) (blocks>>8))&0xff;
887         srb->cmd[8]=(unsigned char) blocks & 0xff;
888         srb->cmdlen=12;
889         USB_STOR_PRINTF("read10: start %lx blocks %x\n",start,blocks);
890         return ss->transport(srb,ss);
891 }
892
893
894 #define USB_MAX_READ_BLK 20
895
896 unsigned long usb_stor_read(int device, unsigned long blknr, unsigned long blkcnt, unsigned long *buffer)
897 {
898         unsigned long start,blks, buf_addr;
899         unsigned short smallblks;
900         struct usb_device *dev;
901         int retry,i;
902         ccb *srb = &usb_ccb;
903
904         if (blkcnt == 0)
905                 return 0;
906
907         device &= 0xff;
908         /* Setup  device
909          */
910         USB_STOR_PRINTF("\nusb_read: dev %d \n",device);
911         dev=NULL;
912         for(i=0;i<USB_MAX_DEVICE;i++) {
913                 dev=usb_get_dev_index(i);
914                 if(dev==NULL) {
915                         return 0;
916                 }
917                 if(dev->devnum==usb_dev_desc[device].target)
918                         break;
919         }
920
921         usb_disable_asynch(1); /* asynch transfer not allowed */
922         srb->lun=usb_dev_desc[device].lun;
923         buf_addr=(unsigned long)buffer;
924         start=blknr;
925         blks=blkcnt;
926         if(usb_test_unit_ready(srb,(struct us_data *)dev->privptr)) {
927                 printf("Device NOT ready\n   Request Sense returned %02X %02X %02X\n",
928                         srb->sense_buf[2],srb->sense_buf[12],srb->sense_buf[13]);
929                 return 0;
930         }
931         USB_STOR_PRINTF("\nusb_read: dev %d startblk %lx, blccnt %lx buffer %lx\n",device,start,blks, buf_addr);
932         do {
933                 retry=2;
934                 srb->pdata=(unsigned char *)buf_addr;
935                 if(blks>USB_MAX_READ_BLK) {
936                         smallblks=USB_MAX_READ_BLK;
937                 } else {
938                         smallblks=(unsigned short) blks;
939                 }
940 retry_it:
941                 if(smallblks==USB_MAX_READ_BLK)
942                         usb_show_progress();
943                 srb->datalen=usb_dev_desc[device].blksz * smallblks;
944                 srb->pdata=(unsigned char *)buf_addr;
945                 if(usb_read_10(srb,(struct us_data *)dev->privptr, start, smallblks)) {
946                         USB_STOR_PRINTF("Read ERROR\n");
947                         usb_request_sense(srb,(struct us_data *)dev->privptr);
948                         if(retry--)
949                                 goto retry_it;
950                         blkcnt-=blks;
951                         break;
952                 }
953                 start+=smallblks;
954                 blks-=smallblks;
955                 buf_addr+=srb->datalen;
956         } while(blks!=0);
957         USB_STOR_PRINTF("usb_read: end startblk %lx, blccnt %x buffer %lx\n",start,smallblks,buf_addr);
958         usb_disable_asynch(0); /* asynch transfer allowed */
959         if(blkcnt>=USB_MAX_READ_BLK)
960                 printf("\n");
961         return(blkcnt);
962 }
963
964
965 /* Probe to see if a new device is actually a Storage device */
966 int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,struct us_data *ss)
967 {
968         struct usb_interface_descriptor *iface;
969         int i;
970         unsigned int flags = 0;
971
972         int protocol = 0;
973         int subclass = 0;
974
975
976         memset(ss, 0, sizeof(struct us_data));
977
978         /* let's examine the device now */
979         iface = &dev->config.if_desc[ifnum];
980
981 #if 0
982         /* this is the place to patch some storage devices */
983         USB_STOR_PRINTF("iVendor %X iProduct %X\n",dev->descriptor.idVendor,dev->descriptor.idProduct);
984         if ((dev->descriptor.idVendor) == 0x066b && (dev->descriptor.idProduct) == 0x0103) {
985                 USB_STOR_PRINTF("patched for E-USB\n");
986                 protocol = US_PR_CB;
987                 subclass = US_SC_UFI;       /* an assumption */
988         }
989 #endif
990
991         if (dev->descriptor.bDeviceClass != 0 ||
992                         iface->bInterfaceClass != USB_CLASS_MASS_STORAGE ||
993                         iface->bInterfaceSubClass < US_SC_MIN ||
994                         iface->bInterfaceSubClass > US_SC_MAX) {
995                 /* if it's not a mass storage, we go no further */
996                 return 0;
997         }
998
999         /* At this point, we know we've got a live one */
1000         USB_STOR_PRINTF("\n\nUSB Mass Storage device detected\n");
1001
1002         /* Initialize the us_data structure with some useful info */
1003         ss->flags = flags;
1004         ss->ifnum = ifnum;
1005         ss->pusb_dev = dev;
1006         ss->attention_done = 0;
1007
1008         /* If the device has subclass and protocol, then use that.  Otherwise,
1009          * take data from the specific interface.
1010          */
1011         if (subclass) {
1012                 ss->subclass = subclass;
1013                 ss->protocol = protocol;
1014         } else {
1015                 ss->subclass = iface->bInterfaceSubClass;
1016                 ss->protocol = iface->bInterfaceProtocol;
1017         }
1018
1019         /* set the handler pointers based on the protocol */
1020         USB_STOR_PRINTF("Transport: ");
1021         switch (ss->protocol) {
1022         case US_PR_CB:
1023                 USB_STOR_PRINTF("Control/Bulk\n");
1024                 ss->transport = usb_stor_CB_transport;
1025                 ss->transport_reset = usb_stor_CB_reset;
1026                 break;
1027
1028         case US_PR_CBI:
1029                 USB_STOR_PRINTF("Control/Bulk/Interrupt\n");
1030                 ss->transport = usb_stor_CB_transport;
1031                 ss->transport_reset = usb_stor_CB_reset;
1032                 break;
1033         case US_PR_BULK:
1034                 USB_STOR_PRINTF("Bulk/Bulk/Bulk\n");
1035                 ss->transport = usb_stor_BBB_transport;
1036                 ss->transport_reset = usb_stor_BBB_reset;
1037                 break;
1038         default:
1039                 printf("USB Storage Transport unknown / not yet implemented\n");
1040                 return 0;
1041                 break;
1042         }
1043
1044         /*
1045          * We are expecting a minimum of 2 endpoints - in and out (bulk).
1046          * An optional interrupt is OK (necessary for CBI protocol).
1047          * We will ignore any others.
1048          */
1049         for (i = 0; i < iface->bNumEndpoints; i++) {
1050                 /* is it an BULK endpoint? */
1051                 if ((iface->ep_desc[i].bmAttributes &  USB_ENDPOINT_XFERTYPE_MASK)
1052                     == USB_ENDPOINT_XFER_BULK) {
1053                         if (iface->ep_desc[i].bEndpointAddress & USB_DIR_IN)
1054                                 ss->ep_in = iface->ep_desc[i].bEndpointAddress &
1055                                         USB_ENDPOINT_NUMBER_MASK;
1056                         else
1057                                 ss->ep_out = iface->ep_desc[i].bEndpointAddress &
1058                                         USB_ENDPOINT_NUMBER_MASK;
1059                 }
1060
1061                 /* is it an interrupt endpoint? */
1062                 if ((iface->ep_desc[i].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
1063                     == USB_ENDPOINT_XFER_INT) {
1064                         ss->ep_int = iface->ep_desc[i].bEndpointAddress &
1065                                 USB_ENDPOINT_NUMBER_MASK;
1066                         ss->irqinterval = iface->ep_desc[i].bInterval;
1067                 }
1068         }
1069         USB_STOR_PRINTF("Endpoints In %d Out %d Int %d\n",
1070                   ss->ep_in, ss->ep_out, ss->ep_int);
1071
1072         /* Do some basic sanity checks, and bail if we find a problem */
1073         if (usb_set_interface(dev, iface->bInterfaceNumber, 0) ||
1074             !ss->ep_in || !ss->ep_out ||
1075             (ss->protocol == US_PR_CBI && ss->ep_int == 0)) {
1076                 USB_STOR_PRINTF("Problems with device\n");
1077                 return 0;
1078         }
1079         /* set class specific stuff */
1080         /* We only handle certain protocols.  Currently, these are
1081          * the only ones.
1082          * The SFF8070 accepts the requests used in u-boot
1083          */
1084         if (ss->subclass != US_SC_UFI && ss->subclass != US_SC_SCSI &&
1085             ss->subclass != US_SC_8070) {
1086                 printf("Sorry, protocol %d not yet supported.\n",ss->subclass);
1087                 return 0;
1088         }
1089         if(ss->ep_int) { /* we had found an interrupt endpoint, prepare irq pipe */
1090                 /* set up the IRQ pipe and handler */
1091
1092                 ss->irqinterval = (ss->irqinterval > 0) ? ss->irqinterval : 255;
1093                 ss->irqpipe = usb_rcvintpipe(ss->pusb_dev, ss->ep_int);
1094                 ss->irqmaxp = usb_maxpacket(dev, ss->irqpipe);
1095                 dev->irq_handle=usb_stor_irq;
1096         }
1097         dev->privptr=(void *)ss;
1098         return 1;
1099 }
1100
1101 int usb_stor_get_info(struct usb_device *dev,struct us_data *ss,block_dev_desc_t *dev_desc)
1102 {
1103         unsigned char perq,modi;
1104         unsigned long cap[2];
1105         unsigned long *capacity,*blksz;
1106         ccb *pccb=&usb_ccb;
1107
1108         /* For some mysterious reason the 256MB flash disk of Ours Technology, Inc
1109          * doesn't survive this reset */
1110         if (dev->descriptor.idVendor != 0xea0 || dev->descriptor.idProduct != 0x6828)
1111                 ss->transport_reset(ss);
1112         pccb->pdata=usb_stor_buf;
1113
1114         dev_desc->target=dev->devnum;
1115         pccb->lun=dev_desc->lun;
1116         USB_STOR_PRINTF(" address %d\n",dev_desc->target);
1117
1118         if(usb_inquiry(pccb,ss))
1119                 return -1;
1120         perq=usb_stor_buf[0];
1121         modi=usb_stor_buf[1];
1122         if((perq & 0x1f)==0x1f) {
1123                 return 0; /* skip unknown devices */
1124         }
1125         if((modi&0x80)==0x80) {/* drive is removable */
1126                 dev_desc->removable=1;
1127         }
1128         memcpy(&dev_desc->vendor[0], &usb_stor_buf[8], 8);
1129         memcpy(&dev_desc->product[0], &usb_stor_buf[16], 16);
1130         memcpy(&dev_desc->revision[0], &usb_stor_buf[32], 4);
1131         dev_desc->vendor[8]=0;
1132         dev_desc->product[16]=0;
1133         dev_desc->revision[4]=0;
1134         USB_STOR_PRINTF("ISO Vers %X, Response Data %X\n",usb_stor_buf[2],usb_stor_buf[3]);
1135         if(usb_test_unit_ready(pccb,ss)) {
1136                 printf("Device NOT ready\n   Request Sense returned %02X %02X %02X\n",pccb->sense_buf[2],pccb->sense_buf[12],pccb->sense_buf[13]);
1137                 if(dev_desc->removable==1) {
1138                         dev_desc->type=perq;
1139                         return 1;
1140                 }
1141                 else
1142                         return 0;
1143         }
1144         pccb->pdata=(unsigned char *)&cap[0];
1145         memset(pccb->pdata,0,8);
1146         if(usb_read_capacity(pccb,ss)!=0) {
1147                 printf("READ_CAP ERROR\n");
1148                 cap[0]=2880;
1149                 cap[1]=0x200;
1150         }
1151         USB_STOR_PRINTF("Read Capacity returns: 0x%lx, 0x%lx\n",cap[0],cap[1]);
1152 #if 0
1153         if(cap[0]>(0x200000 * 10)) /* greater than 10 GByte */
1154                 cap[0]>>=16;
1155 #endif
1156 #ifdef LITTLEENDIAN
1157         cap[0] = ((unsigned long)(
1158                 (((unsigned long)(cap[0]) & (unsigned long)0x000000ffUL) << 24) |
1159                 (((unsigned long)(cap[0]) & (unsigned long)0x0000ff00UL) <<  8) |
1160                 (((unsigned long)(cap[0]) & (unsigned long)0x00ff0000UL) >>  8) |
1161                 (((unsigned long)(cap[0]) & (unsigned long)0xff000000UL) >> 24) ));
1162         cap[1] = ((unsigned long)(
1163                 (((unsigned long)(cap[1]) & (unsigned long)0x000000ffUL) << 24) |
1164                 (((unsigned long)(cap[1]) & (unsigned long)0x0000ff00UL) <<  8) |
1165                 (((unsigned long)(cap[1]) & (unsigned long)0x00ff0000UL) >>  8) |
1166                 (((unsigned long)(cap[1]) & (unsigned long)0xff000000UL) >> 24) ));
1167 #endif
1168         /* this assumes bigendian! */
1169         cap[0]+=1;
1170         capacity=&cap[0];
1171         blksz=&cap[1];
1172         USB_STOR_PRINTF("Capacity = 0x%lx, blocksz = 0x%lx\n",*capacity,*blksz);
1173         dev_desc->lba=*capacity;
1174         dev_desc->blksz=*blksz;
1175         dev_desc->type=perq;
1176         USB_STOR_PRINTF(" address %d\n",dev_desc->target);
1177         USB_STOR_PRINTF("partype: %d\n",dev_desc->part_type);
1178
1179         init_part(dev_desc);
1180
1181         USB_STOR_PRINTF("partype: %d\n",dev_desc->part_type);
1182         return 1;
1183 }
1184
1185 #endif /* CONFIG_USB_STORAGE */
1186 #endif /* CFG_CMD_USB */