]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - common/usb_storage.c
Patch by Guillaume Alexandre,, 04 Nov 2002:
[karo-tx-uboot.git] / common / usb_storage.c
1 /*
2  * (C) Copyright 2001
3  * Denis Peter, MPL AG Switzerland
4  *
5  * Most of this source has been derived from the Linux USB
6  * project.
7  *
8  * See file CREDITS for list of people who contributed to this
9  * project.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License as
13  * published by the Free Software Foundation; either version 2 of
14  * the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
24  * MA 02111-1307 USA
25  *
26  */
27
28 /* Note:
29  * Currently only the CBI transport protocoll has been implemented, and it
30  * is only tested with a TEAC USB Floppy. Other Massstorages with CBI or CB
31  * transport protocoll may work as well.
32  */
33
34
35
36 #include <common.h>
37 #include <command.h>
38 #include <asm/processor.h>
39
40
41 #if (CONFIG_COMMANDS & CFG_CMD_USB)
42 #include <usb.h>
43
44 #ifdef CONFIG_USB_STORAGE
45
46 #undef  USB_STOR_DEBUG
47
48 #ifdef  USB_STOR_DEBUG
49 #define USB_STOR_PRINTF(fmt,args...)    printf (fmt ,##args)
50 #else
51 #define USB_STOR_PRINTF(fmt,args...)
52 #endif
53
54 #include <scsi.h>
55 /* direction table -- this indicates the direction of the data
56  * transfer for each command code -- a 1 indicates input
57  */
58 unsigned char us_direction[256/8] = {
59         0x28, 0x81, 0x14, 0x14, 0x20, 0x01, 0x90, 0x77,
60         0x0C, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
61         0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01,
62         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
63 };
64 #define US_DIRECTION(x) ((us_direction[x>>3] >> (x & 7)) & 1)
65
66 static unsigned char usb_stor_buf[512];
67 static ccb usb_ccb;
68
69 /*
70  * CBI style
71  */
72
73 #define US_CBI_ADSC             0
74
75
76 #define USB_MAX_STOR_DEV 5
77 static int usb_max_devs; /* number of highest available usb device */
78
79 static block_dev_desc_t usb_dev_desc[USB_MAX_STOR_DEV];
80
81 struct us_data;
82 typedef int (*trans_cmnd)(ccb*, struct us_data*);
83 typedef int (*trans_reset)(struct us_data*);
84
85 struct us_data {
86         struct usb_device       *pusb_dev;       /* this usb_device */
87         unsigned int            flags;           /* from filter initially */
88         unsigned char           ifnum;           /* interface number */
89         unsigned char           ep_in;           /* in endpoint */
90         unsigned char           ep_out;          /* out ....... */
91         unsigned char           ep_int;          /* interrupt . */
92         unsigned char           subclass;        /* as in overview */
93         unsigned char           protocol;        /* .............. */
94         unsigned char           attention_done;  /* force attn on first cmd */
95         unsigned short  ip_data;         /* interrupt data */
96         int                                                     action;          /* what to do */
97         int                                                     ip_wanted; /* needed */
98         int                                                     *irq_handle;     /* for USB int requests */
99         unsigned int            irqpipe;         /* pipe for release_irq */
100         unsigned char           irqmaxp;        /* max packed for irq Pipe */
101         unsigned char   irqinterval; /* Intervall for IRQ Pipe */
102         ccb                                                     *srb;            /* current srb */
103         trans_reset                     transport_reset; /* reset routine */
104         trans_cmnd                      transport; /* transport routine */
105 };
106
107 static struct us_data usb_stor[USB_MAX_STOR_DEV];
108
109
110
111 #define USB_STOR_TRANSPORT_GOOD    0
112 #define USB_STOR_TRANSPORT_FAILED -1
113 #define USB_STOR_TRANSPORT_ERROR  -2
114
115
116
117
118
119
120 int usb_stor_get_info(struct usb_device *dev, struct us_data *us, block_dev_desc_t *dev_desc);
121 int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,struct us_data *ss);
122 unsigned long usb_stor_read(int device, unsigned long blknr, unsigned long blkcnt, unsigned long *buffer);
123 struct usb_device * usb_get_dev_index(int index);
124 void uhci_show_temp_int_td(void);
125
126 block_dev_desc_t *usb_stor_get_dev(int index)
127 {
128         return &usb_dev_desc[index];
129 }
130
131
132 void usb_show_progress(void)
133 {
134         printf(".");
135 }
136
137 /*********************************************************************************
138  * (re)-scan the usb and reports device info
139  * to the user if mode = 1
140  * returns current device or -1 if no
141  */
142 int usb_stor_scan(int mode)
143 {
144         unsigned char i;
145         struct usb_device *dev;
146
147         if(mode==1) {
148                 printf("scanning bus for storage devices...\n");
149         }
150         usb_disable_asynch(1); /* asynch transfer not allowed */
151
152         for(i=0;i<USB_MAX_STOR_DEV;i++) {
153                 memset(&usb_dev_desc[i],0,sizeof(block_dev_desc_t));
154                 usb_dev_desc[i].target=0xff;
155                 usb_dev_desc[i].if_type=IF_TYPE_USB;
156                 usb_dev_desc[i].dev=i;
157                 usb_dev_desc[i].part_type=PART_TYPE_UNKNOWN;
158                 usb_dev_desc[i].block_read=usb_stor_read;
159         }
160         usb_max_devs=0;
161         for(i=0;i<USB_MAX_DEVICE;i++) {
162                 dev=usb_get_dev_index(i); /* get device */
163                 USB_STOR_PRINTF("i=%d\n",i);
164                 if(dev==NULL) {
165                         break; /* no more devices avaiable */
166                 }
167                 if(usb_storage_probe(dev,0,&usb_stor[usb_max_devs])) { /* ok, it is a storage devices */
168                         /* get info and fill it in */
169
170                         if(usb_stor_get_info(dev, &usb_stor[usb_max_devs], &usb_dev_desc[usb_max_devs])) {
171                                 if(mode==1) {
172                                         printf ("  Device %d: ", usb_max_devs);
173                                         dev_print(&usb_dev_desc[usb_max_devs]);
174                                 } /* if mode */
175                                 usb_max_devs++;
176                         } /* if get info ok */
177                 } /* if storage device */
178                 if(usb_max_devs==USB_MAX_STOR_DEV) {
179                         printf("max USB Storage Device reached: %d stopping\n",usb_max_devs);
180                         break;
181                 }
182         } /* for */
183         usb_disable_asynch(0); /* asynch transfer allowed */
184         if(usb_max_devs>0)
185                 return 0;
186         else
187                 return-1;
188 }
189
190 static int usb_stor_irq(struct usb_device *dev)
191 {
192         struct us_data *us;
193         us=(struct us_data *)dev->privptr;
194
195         if(us->ip_wanted) {
196                 us->ip_wanted=0;
197         }
198         return 0;
199 }
200
201
202 #ifdef  USB_STOR_DEBUG
203
204 static void usb_show_srb(ccb * pccb)
205 {
206         int i;
207         printf("SRB: len %d datalen 0x%lX\n ",pccb->cmdlen,pccb->datalen);
208         for(i=0;i<12;i++) {
209                 printf("%02X ",pccb->cmd[i]);
210         }
211         printf("\n");
212 }
213
214 static void display_int_status(unsigned long tmp)
215 {
216         printf("Status: %s %s %s %s %s %s %s\n",
217                 (tmp & USB_ST_ACTIVE) ? "Active" : "",
218                 (tmp & USB_ST_STALLED) ? "Stalled" : "",
219                 (tmp & USB_ST_BUF_ERR) ? "Buffer Error" : "",
220                 (tmp & USB_ST_BABBLE_DET) ? "Babble Det" : "",
221                 (tmp & USB_ST_NAK_REC) ? "NAKed" : "",
222                 (tmp & USB_ST_CRC_ERR) ? "CRC Error" : "",
223                 (tmp & USB_ST_BIT_ERR) ? "Bitstuff Error" : "");
224 }
225 #endif
226 /***********************************************************************
227  * Data transfer routines
228  ***********************************************************************/
229
230 static int us_one_transfer(struct us_data *us, int pipe, char *buf, int length)
231 {
232         int max_size;
233         int this_xfer;
234         int result;
235         int partial;
236         int maxtry;
237         int stat;
238
239         /* determine the maximum packet size for these transfers */
240         max_size = usb_maxpacket(us->pusb_dev, pipe) * 16;
241
242         /* while we have data left to transfer */
243         while (length) {
244
245                 /* calculate how long this will be -- maximum or a remainder */
246                 this_xfer = length > max_size ? max_size : length;
247                 length -= this_xfer;
248
249                 /* setup the retry counter */
250                 maxtry = 10;
251
252                 /* set up the transfer loop */
253                 do {
254                         /* transfer the data */
255                         USB_STOR_PRINTF("Bulk xfer 0x%x(%d) try #%d\n",
256                                   (unsigned int)buf, this_xfer, 11 - maxtry);
257                         result = usb_bulk_msg(us->pusb_dev, pipe, buf,
258                                               this_xfer, &partial, USB_CNTL_TIMEOUT*5);
259                         USB_STOR_PRINTF("bulk_msg returned %d xferred %d/%d\n",
260                                   result, partial, this_xfer);
261                         if(us->pusb_dev->status!=0) {
262                                 /* if we stall, we need to clear it before we go on */
263 #ifdef USB_STOR_DEBUG
264                                 display_int_status(us->pusb_dev->status);
265 #endif
266                                 if (us->pusb_dev->status & USB_ST_STALLED) {
267                                         USB_STOR_PRINTF("stalled ->clearing endpoint halt for pipe 0x%x\n", pipe);
268                                         stat = us->pusb_dev->status;
269                                         usb_clear_halt(us->pusb_dev, pipe);
270                                         us->pusb_dev->status=stat;
271                                         if(this_xfer == partial) {
272                                                 USB_STOR_PRINTF("bulk transferred with error %X, but data ok\n",us->pusb_dev->status);
273                                                 return 0;
274                                         }
275                                         else
276                                                 return result;
277                                 }
278                                 if (us->pusb_dev->status & USB_ST_NAK_REC) {
279                                         USB_STOR_PRINTF("Device NAKed bulk_msg\n");
280                                         return result;
281                                 }
282                                 if(this_xfer == partial) {
283                                         USB_STOR_PRINTF("bulk transferred with error %d, but data ok\n",us->pusb_dev->status);
284                                         return 0;
285                                 }
286                                 /* if our try counter reaches 0, bail out */
287                                 USB_STOR_PRINTF("bulk transferred with error %d, data %d\n",us->pusb_dev->status,partial);
288                                 if (!maxtry--)
289                                                 return result;
290                         }
291                         /* update to show what data was transferred */
292                         this_xfer -= partial;
293                         buf += partial;
294                         /* continue until this transfer is done */
295                 } while ( this_xfer );
296         }
297
298         /* if we get here, we're done and successful */
299         return 0;
300 }
301
302 /* FIXME: this reset function doesn't really reset the port, and it
303  * should. Actually it should probably do what it's doing here, and
304  * reset the port physically
305  */
306 static int usb_stor_CB_reset(struct us_data *us)
307 {
308         unsigned char cmd[12];
309         int result;
310
311         USB_STOR_PRINTF("CB_reset\n");
312         memset(cmd, 0xFF, sizeof(cmd));
313         cmd[0] = SCSI_SEND_DIAG;
314         cmd[1] = 4;
315         result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0),
316                                  US_CBI_ADSC, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
317                                  0, us->ifnum, cmd, sizeof(cmd), USB_CNTL_TIMEOUT*5);
318
319         /* long wait for reset */
320         wait_ms(1500);
321         USB_STOR_PRINTF("CB_reset result %d: status %X clearing endpoint halt\n",result,us->pusb_dev->status);
322         usb_clear_halt(us->pusb_dev, usb_rcvbulkpipe(us->pusb_dev, us->ep_in));
323         usb_clear_halt(us->pusb_dev, usb_rcvbulkpipe(us->pusb_dev, us->ep_out));
324
325         USB_STOR_PRINTF("CB_reset done\n");
326         return 0;
327 }
328
329 /* FIXME: we also need a CBI_command which sets up the completion
330  * interrupt, and waits for it
331  */
332 int usb_stor_CB_comdat(ccb *srb, struct us_data *us)
333 {
334         int result;
335         int dir_in,retry;
336         unsigned int pipe;
337         unsigned long status;
338
339         retry=5;
340                 dir_in=US_DIRECTION(srb->cmd[0]);
341
342                 if(dir_in)
343                         pipe=usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
344                 else
345                         pipe=usb_sndbulkpipe(us->pusb_dev, us->ep_out);
346         while(retry--) {
347                 USB_STOR_PRINTF("CBI gets a command: Try %d\n",5-retry);
348 #ifdef USB_STOR_DEBUG
349                 usb_show_srb(srb);
350 #endif
351                 /* let's send the command via the control pipe */
352                 result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0),
353                                          US_CBI_ADSC, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
354                                          0, us->ifnum,
355                                          srb->cmd, srb->cmdlen, USB_CNTL_TIMEOUT*5);
356                 USB_STOR_PRINTF("CB_transport: control msg returned %d, status %X\n",result,us->pusb_dev->status);
357                 /* check the return code for the command */
358                 if (result < 0) {
359                         if(us->pusb_dev->status & USB_ST_STALLED) {
360                                 status=us->pusb_dev->status;
361                                 USB_STOR_PRINTF(" stall during command found, clear pipe\n");
362                                 usb_clear_halt(us->pusb_dev,  usb_sndctrlpipe(us->pusb_dev,0));
363                                 us->pusb_dev->status=status;
364                         }
365                         USB_STOR_PRINTF(" error during command %02X Stat = %X\n",srb->cmd[0],us->pusb_dev->status);
366                         return result;
367                 }
368                 /* transfer the data payload for this command, if one exists*/
369
370                 USB_STOR_PRINTF("CB_transport: control msg returned %d, direction is %s to go 0x%lx\n",result,dir_in ? "IN" : "OUT",srb->datalen);
371                 if (srb->datalen) {
372                         result = us_one_transfer(us, pipe, srb->pdata,srb->datalen);
373                         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);
374                         if(!(us->pusb_dev->status & USB_ST_NAK_REC))
375                                 break;
376                 } /* if (srb->datalen) */
377                 else
378                         break;
379         }
380         /* return result */
381
382         return result;
383 }
384
385
386 int usb_stor_CBI_get_status(ccb *srb, struct us_data *us)
387 {
388         int timeout;
389
390         us->ip_wanted=1;
391         submit_int_msg(us->pusb_dev,us->irqpipe,
392                         (void *)&us->ip_data,us->irqmaxp ,us->irqinterval);
393   timeout=1000;
394   while(timeout--) {
395         if((volatile int *)us->ip_wanted==0)
396                         break;
397                 wait_ms(10);
398         }
399         if (us->ip_wanted) {
400                 printf("       Did not get interrupt on CBI\n");
401                 us->ip_wanted = 0;
402                 return USB_STOR_TRANSPORT_ERROR;
403         }
404         USB_STOR_PRINTF("Got interrupt data 0x%x, transfered %d status 0x%lX\n", us->ip_data,us->pusb_dev->irq_act_len,us->pusb_dev->irq_status);
405         /* UFI gives us ASC and ASCQ, like a request sense */
406         if (us->subclass == US_SC_UFI) {
407                 if (srb->cmd[0] == SCSI_REQ_SENSE ||
408                     srb->cmd[0] == SCSI_INQUIRY)
409                         return USB_STOR_TRANSPORT_GOOD; /* Good */
410                 else
411                         if (us->ip_data)
412                                 return USB_STOR_TRANSPORT_FAILED;
413                         else
414                                 return USB_STOR_TRANSPORT_GOOD;
415         }
416         /* otherwise, we interpret the data normally */
417         switch (us->ip_data) {
418                 case 0x0001:
419                         return USB_STOR_TRANSPORT_GOOD;
420                 case 0x0002:
421                         return USB_STOR_TRANSPORT_FAILED;
422                 default:
423                         return USB_STOR_TRANSPORT_ERROR;
424         } /* switch */
425         return USB_STOR_TRANSPORT_ERROR;
426 }
427
428 #define USB_TRANSPORT_UNKNOWN_RETRY 5
429 #define USB_TRANSPORT_NOT_READY_RETRY 10
430
431 int usb_stor_CB_transport(ccb *srb, struct us_data *us)
432 {
433         int result,status;
434         ccb *psrb;
435         ccb reqsrb;
436         int retry,notready;
437
438         psrb=&reqsrb;
439         status=USB_STOR_TRANSPORT_GOOD;
440         retry=0;
441         notready=0;
442         /* issue the command */
443 do_retry:
444         result=usb_stor_CB_comdat(srb,us);
445         USB_STOR_PRINTF("command / Data returned %d, status %X\n",result,us->pusb_dev->status);
446         /* if this is an CBI Protocol, get IRQ */
447         if(us->protocol==US_PR_CBI) {
448                 status=usb_stor_CBI_get_status(srb,us);
449                 /* if the status is error, report it */
450                 if(status==USB_STOR_TRANSPORT_ERROR) {
451                         USB_STOR_PRINTF(" USB CBI Command Error\n");
452                         return status;
453                 }
454                 srb->sense_buf[12]=(unsigned char)(us->ip_data>>8);
455                 srb->sense_buf[13]=(unsigned char)(us->ip_data&0xff);
456                 if(!us->ip_data) {
457                 /* if the status is good, report it */
458                         if(status==USB_STOR_TRANSPORT_GOOD) {
459                                 USB_STOR_PRINTF(" USB CBI Command Good\n");
460                                 return status;
461                         }
462                 }
463         }
464         /* do we have to issue an auto request? */
465         /* HERE we have to check the result */
466         if((result<0) && !(us->pusb_dev->status & USB_ST_STALLED)) {
467                 USB_STOR_PRINTF("ERROR %X\n",us->pusb_dev->status);
468                 us->transport_reset(us);
469                 return USB_STOR_TRANSPORT_ERROR;
470         }
471         if((us->protocol==US_PR_CBI) &&
472                         ((srb->cmd[0]==SCSI_REQ_SENSE) ||
473                         (srb->cmd[0]==SCSI_INQUIRY))) { /* do not issue an autorequest after request sense */
474                 USB_STOR_PRINTF("No auto request and good\n");
475                 return USB_STOR_TRANSPORT_GOOD;
476         }
477         /* issue an request_sense */
478         memset(&psrb->cmd[0],0,12);
479         psrb->cmd[0]=SCSI_REQ_SENSE;
480         psrb->cmd[1]=srb->lun<<5;
481         psrb->cmd[4]=18;
482         psrb->datalen=18;
483         psrb->pdata=&srb->sense_buf[0];
484         psrb->cmdlen=12;
485         /* issue the command */
486         result=usb_stor_CB_comdat(psrb,us);
487         USB_STOR_PRINTF("auto request returned %d\n",result);
488         /* if this is an CBI Protocol, get IRQ */
489         if(us->protocol==US_PR_CBI) {
490                 status=usb_stor_CBI_get_status(psrb,us);
491         }
492         if((result<0)&&!(us->pusb_dev->status & USB_ST_STALLED)) {
493                 USB_STOR_PRINTF(" AUTO REQUEST ERROR %d\n",us->pusb_dev->status);
494                 return USB_STOR_TRANSPORT_ERROR;
495         }
496         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]);
497         /* Check the auto request result */
498         if((srb->sense_buf[2]==0) &&
499                  (srb->sense_buf[12]==0) &&
500                  (srb->sense_buf[13]==0)) /* ok, no sense */
501                 return USB_STOR_TRANSPORT_GOOD;
502         /* Check the auto request result */
503         switch(srb->sense_buf[2]) {
504                 case 0x01: /* Recovered Error */
505                         return USB_STOR_TRANSPORT_GOOD;
506                         break;
507                 case 0x02: /* Not Ready */
508                         if(notready++ > USB_TRANSPORT_NOT_READY_RETRY) {
509                                 printf("cmd 0x%02X returned 0x%02X 0x%02X 0x%02X 0x%02X (NOT READY)\n",
510                                         srb->cmd[0],srb->sense_buf[0],srb->sense_buf[2],srb->sense_buf[12],srb->sense_buf[13]);
511                                 return USB_STOR_TRANSPORT_FAILED;
512                         }
513                         else {
514                                 wait_ms(100);
515                                 goto do_retry;
516                         }
517                         break;
518                 default:
519                         if(retry++ > USB_TRANSPORT_UNKNOWN_RETRY) {
520                                 printf("cmd 0x%02X returned 0x%02X 0x%02X 0x%02X 0x%02X\n",
521                                         srb->cmd[0],srb->sense_buf[0],srb->sense_buf[2],srb->sense_buf[12],srb->sense_buf[13]);
522                                 return USB_STOR_TRANSPORT_FAILED;
523                         }
524                         else
525                                 goto do_retry;
526                         break;
527         }
528         return USB_STOR_TRANSPORT_FAILED;
529 }
530
531
532
533 static int usb_inquiry(ccb *srb,struct us_data *ss)
534 {
535         int retry,i;
536         retry=3;
537         do {
538                 memset(&srb->cmd[0],0,12);
539                 srb->cmd[0]=SCSI_INQUIRY;
540                 srb->cmd[1]=srb->lun<<5;
541                 srb->cmd[4]=36;
542                 srb->datalen=36;
543                 srb->cmdlen=12;
544                 i=ss->transport(srb,ss);
545                 USB_STOR_PRINTF("inquiry returns %d\n",i);
546                 if(i==0)
547                         break;
548         }while(retry--);
549         if(!retry) {
550                 printf("error in inquiry\n");
551                 return -1;
552         }
553         return 0;
554 }
555
556 static int usb_request_sense(ccb *srb,struct us_data *ss)
557 {
558         char *ptr;
559         return 0;
560         ptr=srb->pdata;
561         memset(&srb->cmd[0],0,12);
562         srb->cmd[0]=SCSI_REQ_SENSE;
563         srb->cmd[1]=srb->lun<<5;
564         srb->cmd[4]=18;
565         srb->datalen=18;
566         srb->pdata=&srb->sense_buf[0];
567         srb->cmdlen=12;
568         ss->transport(srb,ss);
569         USB_STOR_PRINTF("Request Sense returned %02X %02X %02X\n",srb->sense_buf[2],srb->sense_buf[12],srb->sense_buf[13]);
570         srb->pdata=ptr;
571         return 0;
572 }
573
574 static int usb_test_unit_ready(ccb *srb,struct us_data *ss)
575 {
576         int retries=10;
577         do {
578                 memset(&srb->cmd[0],0,12);
579                 srb->cmd[0]=SCSI_TST_U_RDY;
580                 srb->cmd[1]=srb->lun<<5;
581                 srb->datalen=0;
582                 srb->cmdlen=12;
583                 if(ss->transport(srb,ss)==USB_STOR_TRANSPORT_GOOD)
584                 {
585                         return 0;
586                 }
587         } while(retries--);
588         return -1;
589 }
590
591 static int usb_read_capacity(ccb *srb,struct us_data *ss)
592 {
593         int retry;
594         retry=2; /* retries */
595         do {
596                 memset(&srb->cmd[0],0,12);
597                 srb->cmd[0]=SCSI_RD_CAPAC;
598                 srb->cmd[1]=srb->lun<<5;
599                 srb->datalen=8;
600                 srb->cmdlen=12;
601                 if(ss->transport(srb,ss)==USB_STOR_TRANSPORT_GOOD) {
602                         return 0;
603                 }
604         }while(retry--);
605         return -1;
606 }
607
608 static int usb_read_10(ccb *srb,struct us_data *ss, unsigned long start, unsigned short blocks)
609 {
610         memset(&srb->cmd[0],0,12);
611         srb->cmd[0]=SCSI_READ10;
612         srb->cmd[1]=srb->lun<<5;
613         srb->cmd[2]=((unsigned char) (start>>24))&0xff;
614         srb->cmd[3]=((unsigned char) (start>>16))&0xff;
615         srb->cmd[4]=((unsigned char) (start>>8))&0xff;
616         srb->cmd[5]=((unsigned char) (start))&0xff;
617         srb->cmd[7]=((unsigned char) (blocks>>8))&0xff;
618         srb->cmd[8]=(unsigned char) blocks & 0xff;
619         srb->cmdlen=12;
620         USB_STOR_PRINTF("read10: start %lx blocks %x\n",start,blocks);
621         return ss->transport(srb,ss);
622 }
623
624
625 #define USB_MAX_READ_BLK 20
626
627 unsigned long usb_stor_read(int device, unsigned long blknr, unsigned long blkcnt, unsigned long *buffer)
628 {
629         unsigned long start,blks, buf_addr;
630         unsigned short smallblks;
631         struct usb_device *dev;
632         int retry,i;
633         ccb *srb=&usb_ccb;
634         device&=0xff;
635         /* Setup  device
636          */
637         USB_STOR_PRINTF("\nusb_read: dev %d \n",device);
638         dev=NULL;
639         for(i=0;i<USB_MAX_DEVICE;i++) {
640                 dev=usb_get_dev_index(i);
641                 if(dev==NULL) {
642                         return 0;
643                 }
644                 if(dev->devnum==usb_dev_desc[device].target)
645                         break;
646         }
647
648         usb_disable_asynch(1); /* asynch transfer not allowed */
649         srb->lun=usb_dev_desc[device].lun;
650         buf_addr=(unsigned long)buffer;
651         start=blknr;
652         blks=blkcnt;
653         if(usb_test_unit_ready(srb,(struct us_data *)dev->privptr)) {
654                 printf("Device NOT ready\n   Request Sense returned %02X %02X %02X\n",
655                         srb->sense_buf[2],srb->sense_buf[12],srb->sense_buf[13]);
656                 return 0;
657         }
658         USB_STOR_PRINTF("\nusb_read: dev %d startblk %lx, blccnt %lx buffer %lx\n",device,start,blks, buf_addr);
659         do {
660                 retry=2;
661                 srb->pdata=(unsigned char *)buf_addr;
662                 if(blks>USB_MAX_READ_BLK) {
663                         smallblks=USB_MAX_READ_BLK;
664                 }
665                 else {
666                         smallblks=(unsigned short) blks;
667                 }
668 retry_it:
669                 if(smallblks==USB_MAX_READ_BLK)
670                         usb_show_progress();
671                 srb->datalen=usb_dev_desc[device].blksz * smallblks;
672                 srb->pdata=(unsigned char *)buf_addr;
673                 if(usb_read_10(srb,(struct us_data *)dev->privptr, start, smallblks)) {
674                         USB_STOR_PRINTF("Read ERROR\n");
675                         usb_request_sense(srb,(struct us_data *)dev->privptr);
676                         if(retry--)
677                                 goto retry_it;
678                         blkcnt-=blks;
679                         break;
680                 }
681                 start+=smallblks;
682                 blks-=smallblks;
683                 buf_addr+=srb->datalen;
684         } while(blks!=0);
685         USB_STOR_PRINTF("usb_read: end startblk %lx, blccnt %x buffer %lx\n",start,smallblks,buf_addr);
686         usb_disable_asynch(0); /* asynch transfer allowed */
687         if(blkcnt>=USB_MAX_READ_BLK)
688                 printf("\n");
689         return(blkcnt);
690 }
691
692
693 /* Probe to see if a new device is actually a Storage device */
694 int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,struct us_data *ss)
695 {
696         struct usb_interface_descriptor *iface;
697         int i;
698         unsigned int flags = 0;
699
700         int protocol = 0;
701         int subclass = 0;
702
703
704         memset(ss, 0, sizeof(struct us_data));
705
706         /* let's examine the device now */
707         iface = &dev->config.if_desc[ifnum];
708
709 #if 0
710         /* this is the place to patch some storage devices */
711         USB_STOR_PRINTF("iVendor %X iProduct %X\n",dev->descriptor.idVendor,dev->descriptor.idProduct);
712         if ((dev->descriptor.idVendor) == 0x066b && (dev->descriptor.idProduct) == 0x0103) {
713                 USB_STOR_PRINTF("patched for E-USB\n");
714                 protocol = US_PR_CB;
715                 subclass = US_SC_UFI;       /* an assumption */
716         }
717 #endif
718
719         if (dev->descriptor.bDeviceClass != 0 ||
720                         iface->bInterfaceClass != USB_CLASS_MASS_STORAGE ||
721                         iface->bInterfaceSubClass < US_SC_MIN ||
722                         iface->bInterfaceSubClass > US_SC_MAX) {
723                 /* if it's not a mass storage, we go no further */
724                 return 0;
725         }
726
727         /* At this point, we know we've got a live one */
728         USB_STOR_PRINTF("\n\nUSB Mass Storage device detected\n");
729
730         /* Initialize the us_data structure with some useful info */
731         ss->flags = flags;
732         ss->ifnum = ifnum;
733         ss->pusb_dev = dev;
734         ss->attention_done = 0;
735
736         /* If the device has subclass and protocol, then use that.  Otherwise,
737          * take data from the specific interface.
738          */
739         if (subclass) {
740                 ss->subclass = subclass;
741                 ss->protocol = protocol;
742         } else {
743                 ss->subclass = iface->bInterfaceSubClass;
744                 ss->protocol = iface->bInterfaceProtocol;
745         }
746
747         /* set the handler pointers based on the protocol */
748         USB_STOR_PRINTF("Transport: ");
749         switch (ss->protocol) {
750         case US_PR_CB:
751                 USB_STOR_PRINTF("Control/Bulk\n");
752                 ss->transport = usb_stor_CB_transport;
753                 ss->transport_reset = usb_stor_CB_reset;
754                 break;
755
756         case US_PR_CBI:
757                 USB_STOR_PRINTF("Control/Bulk/Interrupt\n");
758                 ss->transport = usb_stor_CB_transport;
759                 ss->transport_reset = usb_stor_CB_reset;
760                 break;
761         default:
762                 printf("USB Starage Transport unknown / not yet implemented\n");
763                 return 0;
764                 break;
765         }
766
767         /*
768          * We are expecting a minimum of 2 endpoints - in and out (bulk).
769          * An optional interrupt is OK (necessary for CBI protocol).
770          * We will ignore any others.
771          */
772         for (i = 0; i < iface->bNumEndpoints; i++) {
773                 /* is it an BULK endpoint? */
774                 if ((iface->ep_desc[i].bmAttributes &  USB_ENDPOINT_XFERTYPE_MASK)
775                     == USB_ENDPOINT_XFER_BULK) {
776                         if (iface->ep_desc[i].bEndpointAddress & USB_DIR_IN)
777                                 ss->ep_in = iface->ep_desc[i].bEndpointAddress &
778                                         USB_ENDPOINT_NUMBER_MASK;
779                         else
780                                 ss->ep_out = iface->ep_desc[i].bEndpointAddress &
781                                         USB_ENDPOINT_NUMBER_MASK;
782                 }
783
784                 /* is it an interrupt endpoint? */
785                 if ((iface->ep_desc[i].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
786                     == USB_ENDPOINT_XFER_INT) {
787                         ss->ep_int = iface->ep_desc[i].bEndpointAddress &
788                                 USB_ENDPOINT_NUMBER_MASK;
789                         ss->irqinterval = iface->ep_desc[i].bInterval;
790                 }
791         }
792         USB_STOR_PRINTF("Endpoints In %d Out %d Int %d\n",
793                   ss->ep_in, ss->ep_out, ss->ep_int);
794
795         /* Do some basic sanity checks, and bail if we find a problem */
796         if (usb_set_interface(dev, iface->bInterfaceNumber, 0) ||
797             !ss->ep_in || !ss->ep_out ||
798             (ss->protocol == US_PR_CBI && ss->ep_int == 0)) {
799                 USB_STOR_PRINTF("Problems with device\n");
800                 return 0;
801         }
802         /* set class specific stuff */
803         /* We only handle certain protocols.  Currently, this is
804          * the only one.
805          */
806         if (ss->subclass != US_SC_UFI) {
807                 printf("Sorry, protocol %d not yet supported.\n",ss->subclass);
808                 return 0;
809         }
810         if(ss->ep_int) /* we had found an interrupt endpoint, prepare irq pipe */
811         {
812                 /* set up the IRQ pipe and handler */
813
814                 ss->irqinterval = (ss->irqinterval > 0) ? ss->irqinterval : 255;
815                 ss->irqpipe = usb_rcvintpipe(ss->pusb_dev, ss->ep_int);
816                 ss->irqmaxp = usb_maxpacket(dev, ss->irqpipe);
817                 dev->irq_handle=usb_stor_irq;
818                 dev->privptr=(void *)ss;
819         }
820         return 1;
821 }
822
823 int usb_stor_get_info(struct usb_device *dev,struct us_data *ss,block_dev_desc_t *dev_desc)
824 {
825         unsigned char perq,modi;
826         unsigned long cap[2];
827         unsigned long *capacity,*blksz;
828         ccb *pccb=&usb_ccb;
829
830         ss->transport_reset(ss);
831         pccb->pdata=usb_stor_buf;
832
833         dev_desc->target=dev->devnum;
834         pccb->lun=dev_desc->lun;
835         USB_STOR_PRINTF(" address %d\n",dev_desc->target);
836
837         if(usb_inquiry(pccb,ss))
838                 return -1;
839         perq=usb_stor_buf[0];
840         modi=usb_stor_buf[1];
841         if((perq & 0x1f)==0x1f) {
842                 return 0; /* skip unknown devices */
843         }
844         if((modi&0x80)==0x80) {/* drive is removable */
845                 dev_desc->removable=1;
846         }
847         memcpy(&dev_desc->vendor[0], &usb_stor_buf[8], 8);
848         memcpy(&dev_desc->product[0], &usb_stor_buf[16], 16);
849         memcpy(&dev_desc->revision[0], &usb_stor_buf[32], 4);
850         dev_desc->vendor[8]=0;
851         dev_desc->product[16]=0;
852         dev_desc->revision[4]=0;
853         USB_STOR_PRINTF("ISO Vers %X, Response Data %X\n",usb_stor_buf[2],usb_stor_buf[3]);
854         if(usb_test_unit_ready(pccb,ss)) {
855                 printf("Device NOT ready\n   Request Sense returned %02X %02X %02X\n",pccb->sense_buf[2],pccb->sense_buf[12],pccb->sense_buf[13]);
856                 if(dev_desc->removable==1) {
857                         dev_desc->type=perq;
858                         return 1;
859                 }
860                 else
861                         return 0;
862         }
863         pccb->pdata=(unsigned char *)&cap[0];
864         memset(pccb->pdata,0,8);
865         if(usb_read_capacity(pccb,ss)!=0) {
866                 printf("READ_CAP ERROR\n");
867                 cap[0]=2880;
868                 cap[1]=0x200;
869         }
870         USB_STOR_PRINTF("Read Capacity returns: 0x%lx, 0x%lx\n",cap[0],cap[1]);
871 #if 0
872         if(cap[0]>(0x200000 * 10)) /* greater than 10 GByte */
873                 cap[0]>>=16;
874 #endif
875         cap[0]+=1;
876         capacity=&cap[0];
877         blksz=&cap[1];
878         USB_STOR_PRINTF("Capacity = 0x%lx, blocksz = 0x%lx\n",*capacity,*blksz);
879         dev_desc->lba=*capacity;
880         dev_desc->blksz=*blksz;
881         dev_desc->type=perq;
882         USB_STOR_PRINTF(" address %d\n",dev_desc->target);
883         USB_STOR_PRINTF("partype: %d\n",dev_desc->part_type);
884
885         init_part(dev_desc);
886
887         USB_STOR_PRINTF("partype: %d\n",dev_desc->part_type);
888         return 1;
889 }
890
891 #endif
892 #endif /* CONFIG_USB_STORAGE */
893
894
895