]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - common/usb_storage.c
imx: Return gpio_set_value in gpio_direction_output
[karo-tx-uboot.git] / common / usb_storage.c
index d9a2585d5800af782698e784f8c108f5e22f5133..12083337b01e74610be23b94c467ee8ef3eb0d64 100644 (file)
@@ -151,6 +151,7 @@ struct us_data {
        unsigned int    irqpipe;                /* pipe for release_irq */
        unsigned char   irqmaxp;                /* max packed for irq Pipe */
        unsigned char   irqinterval;            /* Intervall for IRQ Pipe */
+       unsigned long   max_xfer_blk;           /* Max blocks per xfer */
        ccb             *srb;                   /* current srb */
        trans_reset     transport_reset;        /* reset routine */
        trans_cmnd      transport;              /* transport routine */
@@ -437,19 +438,19 @@ static int usb_stor_BBB_reset(struct us_data *us)
        }
 
        /* long wait for reset */
-       wait_ms(150);
+       mdelay(150);
        USB_STOR_PRINTF("BBB_reset result %d: status %lX reset\n", result,
                        us->pusb_dev->status);
        pipe = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
        result = usb_clear_halt(us->pusb_dev, pipe);
        /* long wait for reset */
-       wait_ms(150);
+       mdelay(150);
        USB_STOR_PRINTF("BBB_reset result %d: status %lX clearing IN endpoint\n",
                        result, us->pusb_dev->status);
        /* long wait for reset */
        pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
        result = usb_clear_halt(us->pusb_dev, pipe);
-       wait_ms(150);
+       mdelay(150);
        USB_STOR_PRINTF("BBB_reset result %d: status %lX"
                        " clearing OUT endpoint\n", result,
                        us->pusb_dev->status);
@@ -477,7 +478,7 @@ static int usb_stor_CB_reset(struct us_data *us)
                                 USB_CNTL_TIMEOUT * 5);
 
        /* long wait for reset */
-       wait_ms(1500);
+       mdelay(1500);
        USB_STOR_PRINTF("CB_reset result %d: status %lX"
                        " clearing endpoint halt\n", result,
                        us->pusb_dev->status);
@@ -620,7 +621,7 @@ int usb_stor_CBI_get_status(ccb *srb, struct us_data *us)
        while (timeout--) {
                if ((volatile int *) us->ip_wanted == 0)
                        break;
-               wait_ms(10);
+               mdelay(10);
        }
        if (us->ip_wanted) {
                printf("        Did not get interrupt on CBI\n");
@@ -691,7 +692,7 @@ int usb_stor_BBB_transport(ccb *srb, struct us_data *us)
                usb_stor_BBB_reset(us);
                return USB_STOR_TRANSPORT_FAILED;
        }
-       wait_ms(5);
+       mdelay(5);
        pipein = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
        pipeout = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
        /* DATA phase + error handling */
@@ -883,7 +884,7 @@ do_retry:
                                srb->sense_buf[12], srb->sense_buf[13]);
                        return USB_STOR_TRANSPORT_FAILED;
                } else {
-                       wait_ms(100);
+                       mdelay(100);
                        goto do_retry;
                }
                break;
@@ -959,7 +960,7 @@ static int usb_test_unit_ready(ccb *srb, struct us_data *ss)
                if (ss->transport(srb, ss) == USB_STOR_TRANSPORT_GOOD)
                        return 0;
                usb_request_sense(srb, ss);
-               wait_ms(100);
+               mdelay(100);
        } while (retries--);
 
        return -1;
@@ -1041,14 +1042,13 @@ static void usb_bin_fixup(struct usb_device_descriptor descriptor,
 }
 #endif /* CONFIG_USB_BIN_FIXUP */
 
-#define USB_MAX_READ_BLK 20
-
 unsigned long usb_stor_read(int device, unsigned long blknr,
                            unsigned long blkcnt, void *buffer)
 {
        unsigned long start, blks, buf_addr;
        unsigned short smallblks;
        struct usb_device *dev;
+       struct us_data *ss;
        int retry, i;
        ccb *srb = &usb_ccb;
 
@@ -1066,13 +1066,14 @@ unsigned long usb_stor_read(int device, unsigned long blknr,
                if (dev->devnum == usb_dev_desc[device].target)
                        break;
        }
+       ss = (struct us_data *)dev->privptr;
 
        usb_disable_asynch(1); /* asynch transfer not allowed */
        srb->lun = usb_dev_desc[device].lun;
        buf_addr = (unsigned long)buffer;
        start = blknr;
        blks = blkcnt;
-       if (usb_test_unit_ready(srb, (struct us_data *)dev->privptr)) {
+       if (usb_test_unit_ready(srb, ss)) {
                printf("Device NOT ready\n   Request Sense returned %02X %02X"
                       " %02X\n", srb->sense_buf[2], srb->sense_buf[12],
                       srb->sense_buf[13]);
@@ -1086,19 +1087,18 @@ unsigned long usb_stor_read(int device, unsigned long blknr,
                /* XXX need some comment here */
                retry = 2;
                srb->pdata = (unsigned char *)buf_addr;
-               if (blks > USB_MAX_READ_BLK)
-                       smallblks = USB_MAX_READ_BLK;
+               if (blks > ss->max_xfer_blk)
+                       smallblks = ss->max_xfer_blk;
                else
                        smallblks = (unsigned short) blks;
 retry_it:
-               if (smallblks == USB_MAX_READ_BLK)
+               if (smallblks == ss->max_xfer_blk)
                        usb_show_progress();
                srb->datalen = usb_dev_desc[device].blksz * smallblks;
                srb->pdata = (unsigned char *)buf_addr;
-               if (usb_read_10(srb, (struct us_data *)dev->privptr, start,
-                   smallblks)) {
+               if (usb_read_10(srb, ss, start, smallblks)) {
                        USB_STOR_PRINTF("Read ERROR\n");
-                       usb_request_sense(srb, (struct us_data *)dev->privptr);
+                       usb_request_sense(srb, ss);
                        if (retry--)
                                goto retry_it;
                        blkcnt -= blks;
@@ -1113,19 +1113,18 @@ retry_it:
                        start, smallblks, buf_addr);
 
        usb_disable_asynch(0); /* asynch transfer allowed */
-       if (blkcnt >= USB_MAX_READ_BLK)
+       if (blkcnt >= ss->max_xfer_blk)
                debug("\n");
        return blkcnt;
 }
 
-#define USB_MAX_WRITE_BLK 20
-
 unsigned long usb_stor_write(int device, unsigned long blknr,
                                unsigned long blkcnt, const void *buffer)
 {
        unsigned long start, blks, buf_addr;
        unsigned short smallblks;
        struct usb_device *dev;
+       struct us_data *ss;
        int retry, i;
        ccb *srb = &usb_ccb;
 
@@ -1143,6 +1142,7 @@ unsigned long usb_stor_write(int device, unsigned long blknr,
                if (dev->devnum == usb_dev_desc[device].target)
                        break;
        }
+       ss = (struct us_data *)dev->privptr;
 
        usb_disable_asynch(1); /* asynch transfer not allowed */
 
@@ -1150,7 +1150,7 @@ unsigned long usb_stor_write(int device, unsigned long blknr,
        buf_addr = (unsigned long)buffer;
        start = blknr;
        blks = blkcnt;
-       if (usb_test_unit_ready(srb, (struct us_data *)dev->privptr)) {
+       if (usb_test_unit_ready(srb, ss)) {
                printf("Device NOT ready\n   Request Sense returned %02X %02X"
                       " %02X\n", srb->sense_buf[2], srb->sense_buf[12],
                        srb->sense_buf[13]);
@@ -1166,19 +1166,18 @@ unsigned long usb_stor_write(int device, unsigned long blknr,
                 */
                retry = 2;
                srb->pdata = (unsigned char *)buf_addr;
-               if (blks > USB_MAX_WRITE_BLK)
-                       smallblks = USB_MAX_WRITE_BLK;
+               if (blks > ss->max_xfer_blk)
+                       smallblks = ss->max_xfer_blk;
                else
                        smallblks = (unsigned short) blks;
 retry_it:
-               if (smallblks == USB_MAX_WRITE_BLK)
+               if (smallblks == ss->max_xfer_blk)
                        usb_show_progress();
                srb->datalen = usb_dev_desc[device].blksz * smallblks;
                srb->pdata = (unsigned char *)buf_addr;
-               if (usb_write_10(srb, (struct us_data *)dev->privptr, start,
-                   smallblks)) {
+               if (usb_write_10(srb, ss, start, smallblks)) {
                        USB_STOR_PRINTF("Write ERROR\n");
-                       usb_request_sense(srb, (struct us_data *)dev->privptr);
+                       usb_request_sense(srb, ss);
                        if (retry--)
                                goto retry_it;
                        blkcnt -= blks;
@@ -1193,7 +1192,7 @@ retry_it:
                        start, smallblks, buf_addr);
 
        usb_disable_asynch(0); /* asynch transfer allowed */
-       if (blkcnt >= USB_MAX_WRITE_BLK)
+       if (blkcnt >= ss->max_xfer_blk)
                debug("\n");
        return blkcnt;
 
@@ -1419,6 +1418,12 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
        USB_STOR_PRINTF(" address %d\n", dev_desc->target);
        USB_STOR_PRINTF("partype: %d\n", dev_desc->part_type);
 
+       /*
+        * The U-Boot EHCI driver cannot handle more than 4096 * 5 bytes in a
+        * transfer without running itself out of qt_buffers.
+        */
+       ss->max_xfer_blk = (4096 * 5) / dev_desc->blksz;
+
        init_part(dev_desc);
 
        USB_STOR_PRINTF("partype: %d\n", dev_desc->part_type);