ChangeSet 1.1504.2.25, 2003/12/09 11:46:03-08:00, stern@rowland.harvard.edu

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

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.


 drivers/usb/storage/sddr55.c |   81 ++++++++++++++++++++++++-------------------
 1 files changed, 46 insertions(+), 35 deletions(-)


diff -Nru a/drivers/usb/storage/sddr55.c b/drivers/usb/storage/sddr55.c
--- a/drivers/usb/storage/sddr55.c	Mon Dec 29 14:24:13 2003
+++ b/drivers/usb/storage/sddr55.c	Mon Dec 29 14:24:13 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;
 
