ChangeSet 1.1504.2.20, 2003/12/09 11:42:16-08:00, [EMAIL PROTECTED]

[PATCH] USB storage: Convert datafab to use the new s-g routines

This patch updates the datafab driver to the new scatter-gather handling,
which makes it safe for systems with >1GByte of memory.
It has been tested by Eduard Hasenleithner.


 drivers/usb/storage/datafab.c |  119 +++++++++++++++++++-----------------------
 1 files changed, 56 insertions(+), 63 deletions(-)


diff -Nru a/drivers/usb/storage/datafab.c b/drivers/usb/storage/datafab.c
--- a/drivers/usb/storage/datafab.c     Mon Dec 29 14:24:46 2003
+++ b/drivers/usb/storage/datafab.c     Mon Dec 29 14:24:46 2003
@@ -51,7 +51,6 @@
  */
 
 #include "transport.h"
-#include "raw_bulk.h"
 #include "protocol.h"
 #include "usb.h"
 #include "debug.h"
@@ -91,16 +90,14 @@
                             struct datafab_info *info,
                             u32 sector,
                             u32 sectors, 
-                            unsigned char *dest, 
+                            unsigned char *buffer, 
                             int use_sg)
 {
        unsigned char *command = us->iobuf;
-       unsigned char *buffer = NULL;
-       unsigned char *ptr;
        unsigned char  thistime;
-       int totallen, len, result;
-       int sg_idx = 0, sg_offset = 0;
-       int rc;
+       unsigned int totallen, alloclen;
+       int len, result;
+       unsigned int sg_idx = 0, sg_offset = 0;
 
        // we're working in LBA mode.  according to the ATA spec, 
        // we can support up to 28-bit addressing.  I don't know if Datafab
@@ -111,23 +108,28 @@
                return USB_STOR_TRANSPORT_ERROR;
 
        if (info->lun == -1) {
-               rc = datafab_determine_lun(us, info);
-               if (rc != USB_STOR_TRANSPORT_GOOD)
-                       return rc;
+               result = datafab_determine_lun(us, info);
+               if (result != USB_STOR_TRANSPORT_GOOD)
+                       return result;
        }
 
        totallen = sectors * info->ssize;
 
-       do {
-               // loop, never allocate or transfer more than 64k at once
-               // (min(128k, 255*info->ssize) is the real limit)
-
-               len = min_t(int, totallen, 65536);
+       // Since we don't read more than 64 KB at a time, we have to create
+       // a bounce buffer if the transfer uses scatter-gather.
 
-               ptr = buffer = (use_sg ? kmalloc(len, GFP_NOIO) : dest);
+       alloclen = min(totallen, 65536u);
+       if (use_sg) {
+               buffer = kmalloc(alloclen, GFP_NOIO);
                if (buffer == NULL)
                        return USB_STOR_TRANSPORT_ERROR;
+       }
 
+       do {
+               // loop, never allocate or transfer more than 64k at once
+               // (min(128k, 255*info->ssize) is the real limit)
+
+               len = min(totallen, alloclen);
                thistime = (len / info->ssize) & 0xff;
 
                command[0] = 0;
@@ -135,7 +137,7 @@
                command[2] = sector & 0xFF;
                command[3] = (sector >> 8) & 0xFF;
                command[4] = (sector >> 16) & 0xFF;
-       
+
                command[5] = 0xE0 + (info->lun << 4);
                command[5] |= (sector >> 24) & 0x0F;
                command[6] = 0x20;
@@ -147,24 +149,22 @@
                        goto leave;
 
                // read the result
-               result = datafab_bulk_read(us, ptr, len);
+               result = datafab_bulk_read(us, buffer, len);
                if (result != USB_STOR_XFER_GOOD)
                        goto leave;
 
-               sectors -= thistime;
-               sector  += thistime;
-
-               if (use_sg) {
-                       us_copy_to_sgbuf(buffer, len, dest,
-                                        &sg_idx, &sg_offset, use_sg);
-                       kfree(buffer);
-               } else {
-                       dest += len;
-               }
+               if (use_sg)
+                       usb_stor_access_xfer_buf(buffer, len, us->srb,
+                                        &sg_idx, &sg_offset, TO_XFER_BUF);
+               else
+                       buffer += len;
 
+               sector += thistime;
                totallen -= len;
        } while (totallen > 0);
 
+       if (use_sg)
+               kfree(buffer);
        return USB_STOR_TRANSPORT_GOOD;
 
  leave:
@@ -178,16 +178,15 @@
                              struct datafab_info *info,
                              u32 sector,
                              u32 sectors, 
-                             unsigned char *src, 
+                             unsigned char *buffer, 
                              int use_sg)
 {
        unsigned char *command = us->iobuf;
        unsigned char *reply = us->iobuf;
-       unsigned char *buffer = NULL;
-       unsigned char *ptr;
        unsigned char thistime;
-       int totallen, len, result, rc;
-       int sg_idx = 0, sg_offset = 0;
+       unsigned int totallen, alloclen;
+       int len, result;
+       unsigned int sg_idx = 0, sg_offset = 0;
 
        // we're working in LBA mode.  according to the ATA spec, 
        // we can support up to 28-bit addressing.  I don't know if Datafab
@@ -198,38 +197,34 @@
                return USB_STOR_TRANSPORT_ERROR;
 
        if (info->lun == -1) {
-               rc = datafab_determine_lun(us, info);
-               if (rc != USB_STOR_TRANSPORT_GOOD)
-                       return rc;
+               result = datafab_determine_lun(us, info);
+               if (result != USB_STOR_TRANSPORT_GOOD)
+                       return result;
        }
 
-       // If we're using scatter-gather, we have to create a new
-       // buffer to read all of the data in first, since a
-       // scatter-gather buffer could in theory start in the middle
-       // of a page, which would be bad. A developer who wants a
-       // challenge might want to write a limited-buffer
-       // version of this code.
-
        totallen = sectors * info->ssize;
 
-       do {
-               // loop, never allocate or transfer more than 64k at once
-               // (min(128k, 255*info->ssize) is the real limit)
-
-               len = min_t(int, totallen, 65536);
-
-               // if we are using scatter-gather,
-               // first copy all to one big buffer
+       // Since we don't write more than 64 KB at a time, we have to create
+       // a bounce buffer if the transfer uses scatter-gather.
 
-               buffer = us_copy_from_sgbuf(src, len, &sg_idx,
-                                           &sg_offset, use_sg);
+       alloclen = min(totallen, 65536u);
+       if (use_sg) {
+               buffer = kmalloc(alloclen, GFP_NOIO);
                if (buffer == NULL)
                        return USB_STOR_TRANSPORT_ERROR;
+       }
 
-               ptr = buffer;
+       do {
+               // loop, never allocate or transfer more than 64k at once
+               // (min(128k, 255*info->ssize) is the real limit)
 
+               len = min(totallen, alloclen);
                thistime = (len / info->ssize) & 0xff;
 
+               if (use_sg)
+                       usb_stor_access_xfer_buf(buffer, len, us->srb,
+                                       &sg_idx, &sg_offset, FROM_XFER_BUF);
+
                command[0] = 0;
                command[1] = thistime;
                command[2] = sector & 0xFF;
@@ -247,7 +242,7 @@
                        goto leave;
 
                // send the data
-               result = datafab_bulk_write(us, ptr, len);
+               result = datafab_bulk_write(us, buffer, len);
                if (result != USB_STOR_XFER_GOOD)
                        goto leave;
 
@@ -264,17 +259,15 @@
                        goto leave;
                }
 
-               sectors -= thistime;
-               sector  += thistime;
-
-               if (use_sg)
-                       kfree(buffer);
-               else
-                       src += len;
+               if (!use_sg)
+                       buffer += len;
 
+               sector += thistime;
                totallen -= len;
        } while (totallen > 0);
 
+       if (use_sg)
+               kfree(buffer);
        return USB_STOR_TRANSPORT_GOOD;
 
  leave:
@@ -435,7 +428,7 @@
        // datafab reader doesn't present a SCSI interface so we
        // fudge the SCSI commands...
        //
-       
+
        if (sense_6)
                param_len = srb->cmnd[4];
        else



-------------------------------------------------------
This SF.net email is sponsored by: IBM Linux Tutorials.
Become an expert in LINUX or just sharpen your skills.  Sign up for IBM's
Free Linux Tutorials.  Learn everything from the bash shell to sys admin.
Click now! http://ads.osdn.com/?ad_id78&alloc_id371&op=click
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to