This patch updates the sdd55 driver to be scatter-gather safe.

Greg, please apply.

Matt

----- Forwarded message from Alan Stern <[EMAIL PROTECTED]> -----

Date: Mon, 1 Dec 2003 10:55:46 -0500 (EST)
From: Alan Stern <[EMAIL PROTECTED]>
Subject: PATCH: (as148)  Convert sddr55 to use the new s-g routines
To: Matthew Dharm <[EMAIL PROTECTED]>
cc: Andries Brouwer <[EMAIL PROTECTED]>,
   USB Storage List <[EMAIL PROTECTED]>
X-Spam-Status: No, hits=0.9 required=5.0
        tests=AWL,PATCH_UNIFIED_DIFF,RCVD_IN_OSIRUSOFT_COM,
              SPAM_PHRASE_00_01,USER_AGENT_PINE,X_OSIRU_OPEN_RELAY
        version=2.44

Matt:

This patch changes the sddr55 driver to make it use the new scatter-gather
routines.  It has not been tested, but perhaps Andries Brouwer will be
able to try it out.

Alan Stern


===== sddr55.c 1.13 vs edited =====
--- 1.13/drivers/usb/storage/sddr55.c   Mon Jul 28 14:29:05 2003
+++ edited/drivers/usb/storage/sddr55.c Mon Dec  1 10:40:25 2003
@@ -25,7 +25,6 @@
  */
 
 #include "transport.h"
-#include "raw_bulk.h"
 #include "protocol.h"
 #include "usb.h"
 #include "debug.h"
@@ -155,7 +154,7 @@
                unsigned int lba,
                unsigned int page,
                unsigned short sectors,
-               unsigned char *content,
+               unsigned char *buffer,
                int use_sg) {
 
        int result = USB_STOR_TRANSPORT_GOOD;
@@ -167,17 +166,20 @@
        unsigned long address;
 
        unsigned short pages;
-       unsigned char *buffer = NULL;
-       unsigned char *ptr;
-       int len;
+       unsigned int len, index, offset;
 
-       len = sectors * PAGESIZE;
+       // Since we only read in one block at a time, we have to create
+       // a bounce buffer if the transfer uses scatter-gather.
 
-       buffer = (use_sg ? kmalloc(len, GFP_NOIO) : content);
-       if (buffer == NULL)
-               return USB_STOR_TRANSPORT_ERROR; /* out of memory */
-
-       ptr = buffer;
+       if (use_sg) {
+               len = min((unsigned int) sectors,
+                               (unsigned int) info->blocksize >>
+                                       info->smallpageshift) * PAGESIZE;
+               buffer = kmalloc(len, GFP_NOIO);
+               if (buffer == NULL)
+                       return USB_STOR_TRANSPORT_ERROR; /* out of memory */
+       }
+       index = offset = 0;
 
        while (sectors>0) {
 
@@ -189,9 +191,9 @@
 
                // Read as many sectors as possible in this block
 
-               pages = info->blocksize - page;
-               if (pages > (sectors << info->smallpageshift))
-                       pages = (sectors << info->smallpageshift);
+               pages = min((unsigned int) sectors << info->smallpageshift,
+                               info->blocksize - page);
+               len = pages << info->pageshift;
 
                US_DEBUGP("Read %02X pages, from PBA %04X"
                        " (LBA %04X) page %02X\n",
@@ -199,7 +201,7 @@
 
                if (pba == NOT_ALLOCATED) {
                        /* no pba for this lba, fill with zeroes */
-                       memset (ptr, 0, pages << info->pageshift);
+                       memset (buffer, 0, len);
                } else {
 
                        address = (pba << info->blockshift) + page;
@@ -228,8 +230,7 @@
 
                        /* read data */
                        result = sddr55_bulk_transport(us,
-                               SCSI_DATA_READ, ptr,
-                               pages<<info->pageshift);
+                               SCSI_DATA_READ, buffer, len);
 
                        if (result != USB_STOR_XFER_GOOD) {
                                result = USB_STOR_TRANSPORT_ERROR;
@@ -252,14 +253,17 @@
                                goto leave;
                        }
                }
+               if (use_sg)
+                       usb_stor_access_xfer_buf(buffer, len, us->srb,
+                                       &index, &offset, TO_XFER_BUF);
+               else
+                       buffer += len;
 
                page = 0;
                lba++;
                sectors -= pages >> info->smallpageshift;
-               ptr += (pages << info->pageshift);
        }
 
-       us_copy_to_sgbuf_all(buffer, len, content, use_sg);
        result = USB_STOR_TRANSPORT_GOOD;
 
 leave:
@@ -273,7 +277,7 @@
                unsigned int lba,
                unsigned int page,
                unsigned short sectors,
-               unsigned char *content,
+               unsigned char *buffer,
                int use_sg) {
 
        int result = USB_STOR_TRANSPORT_GOOD;
@@ -286,9 +290,8 @@
        unsigned long address;
 
        unsigned short pages;
-       unsigned char *buffer = NULL;
-       unsigned char *ptr;
-       int i, len;
+       int i;
+       unsigned int len, index, offset;
 
        /* check if we are allowed to write */
        if (info->read_only || info->force_read_only) {
@@ -296,13 +299,18 @@
                return USB_STOR_TRANSPORT_FAILED;
        }
 
-       len = sectors * PAGESIZE;
+       // Since we only write one block at a time, we have to create
+       // a bounce buffer if the transfer uses scatter-gather.
 
-       buffer = us_copy_from_sgbuf_all(content, len, use_sg);
-       if (buffer == NULL)
-               return USB_STOR_TRANSPORT_ERROR;
-
-       ptr = buffer;
+       if (use_sg) {
+               len = min((unsigned int) sectors,
+                               (unsigned int) info->blocksize >>
+                                       info->smallpageshift) * PAGESIZE;
+               buffer = kmalloc(len, GFP_NOIO);
+               if (buffer == NULL)
+                       return USB_STOR_TRANSPORT_ERROR;
+       }
+       index = offset = 0;
 
        while (sectors > 0) {
 
@@ -314,9 +322,12 @@
 
                // Write as many sectors as possible in this block
 
-               pages = info->blocksize - page;
-               if (pages > (sectors << info->smallpageshift))
-                       pages = (sectors << info->smallpageshift);
+               pages = min((unsigned int) sectors << info->smallpageshift,
+                               info->blocksize - page);
+               len = pages << info->pageshift;
+               if (use_sg)
+                       usb_stor_access_xfer_buf(buffer, len, us->srb,
+                                       &index, &offset, FROM_XFER_BUF);
 
                US_DEBUGP("Write %02X pages, to PBA %04X"
                        " (LBA %04X) page %02X\n",
@@ -400,8 +411,7 @@
 
                /* send the data */
                result = sddr55_bulk_transport(us,
-                       SCSI_DATA_WRITE, ptr,
-                       pages<<info->pageshift);
+                       SCSI_DATA_WRITE, buffer, len);
 
                if (result != USB_STOR_XFER_GOOD) {
                        US_DEBUGP("Result for send_data in write_data %d\n",
@@ -458,10 +468,11 @@
                /* update the pba<->lba maps for new_pba */
                info->pba_to_lba[new_pba] = lba % 1000;
 
+               if (!use_sg)
+                       buffer += len;
                page = 0;
                lba++;
                sectors -= pages >> info->smallpageshift;
-               ptr += (pages << info->pageshift);
        }
        result = USB_STOR_TRANSPORT_GOOD;
 

----- End forwarded message -----

-- 
Matthew Dharm                              Home: [EMAIL PROTECTED] 
Maintainer, Linux USB Mass Storage Driver

It was a new hope.
                                        -- Dust Puppy
User Friendly, 12/25/1998

Attachment: pgp00000.pgp
Description: PGP signature

Reply via email to