ChangeSet 1.1474.81.29, 2004/01/16 17:11:16-08:00, stern@rowland.harvard.edu

[PATCH] USB Storage: Remove non s-g pathway from subdriver READ/WRITE

This patch does what you suggested.  The read/write routines from the
updated subdrivers are changed so they don't bother to differentiate
between transfers that do or do not use scatter-gather.  The low-level
usb_stor_access_xfer_buf routine will Do The Right Thing regardless, and
there probably won't ever be more than a few non s-g calls.  (What about
filesystem I/O requests to access metadata?)

It turns out that in addition to removing some comments and a few tests,
this change allowed me to remove the buffer and use_sg arguments passed to
the read/write routines as well.  So the simplification ended up being a
bit bigger than I expected.

While writing this patch, I noticed spots in several drivers that still
need to be changed -- they slipped past me before.  These drivers handle
things like READ-CAPACITY or REQUEST-SENSE by copying the data directly to
srb->request_buffer, which is obviously wrong if s-g is being used.  I'll
send in changes next week that convert them to use the
usb_stor_set_xfer_buf function.  Like you said, it's going to be handy in
more places than originally intended!


 drivers/usb/storage/datafab.c       |   80 +++++++++++----------------------
 drivers/usb/storage/jumpshot.c      |   80 +++++++++++----------------------
 drivers/usb/storage/sddr09.c        |   87 ++++++++++++------------------------
 drivers/usb/storage/sddr55.c        |   83 ++++++++++++----------------------
 drivers/usb/storage/shuttle_usbat.c |   28 +++--------
 5 files changed, 126 insertions(+), 232 deletions(-)


diff -Nru a/drivers/usb/storage/datafab.c b/drivers/usb/storage/datafab.c
--- a/drivers/usb/storage/datafab.c	Tue Jan 20 17:34:50 2004
+++ b/drivers/usb/storage/datafab.c	Tue Jan 20 17:34:50 2004
@@ -89,11 +89,10 @@
 static int datafab_read_data(struct us_data *us,
 			     struct datafab_info *info,
 			     u32 sector,
-			     u32 sectors, 
-			     unsigned char *buffer, 
-			     int use_sg)
+			     u32 sectors)
 {
 	unsigned char *command = us->iobuf;
+	unsigned char *buffer;
 	unsigned char  thistime;
 	unsigned int totallen, alloclen;
 	int len, result;
@@ -116,18 +115,13 @@
 	totallen = sectors * info->ssize;
 
 	// 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.  We will
-	// move the data a piece at a time between the bounce buffer and
-	// the actual transfer buffer.  If we're not using scatter-gather,
-	// we can simply update the transfer buffer pointer to get the
-	// same effect.
+	// a bounce buffer and move the data a piece at a time between the
+	// bounce buffer and the actual transfer buffer.
 
 	alloclen = min(totallen, 65536u);
-	if (use_sg) {
-		buffer = kmalloc(alloclen, GFP_NOIO);
-		if (buffer == NULL)
-			return USB_STOR_TRANSPORT_ERROR;
-	}
+	buffer = kmalloc(alloclen, GFP_NOIO);
+	if (buffer == NULL)
+		return USB_STOR_TRANSPORT_ERROR;
 
 	do {
 		// loop, never allocate or transfer more than 64k at once
@@ -157,24 +151,19 @@
 		if (result != USB_STOR_XFER_GOOD)
 			goto leave;
 
-		// Store the data (s-g) or update the pointer (!s-g)
-		if (use_sg)
-			usb_stor_access_xfer_buf(buffer, len, us->srb,
-					 &sg_idx, &sg_offset, TO_XFER_BUF);
-		else
-			buffer += len;
+		// Store the data in the transfer buffer
+		usb_stor_access_xfer_buf(buffer, len, us->srb,
+				 &sg_idx, &sg_offset, TO_XFER_BUF);
 
 		sector += thistime;
 		totallen -= len;
 	} while (totallen > 0);
 
-	if (use_sg)
-		kfree(buffer);
+	kfree(buffer);
 	return USB_STOR_TRANSPORT_GOOD;
 
  leave:
-	if (use_sg)
-		kfree(buffer);
+	kfree(buffer);
 	return USB_STOR_TRANSPORT_ERROR;
 }
 
@@ -182,12 +171,11 @@
 static int datafab_write_data(struct us_data *us,
 			      struct datafab_info *info,
 			      u32 sector,
-			      u32 sectors, 
-			      unsigned char *buffer, 
-			      int use_sg)
+			      u32 sectors)
 {
 	unsigned char *command = us->iobuf;
 	unsigned char *reply = us->iobuf;
+	unsigned char *buffer;
 	unsigned char thistime;
 	unsigned int totallen, alloclen;
 	int len, result;
@@ -210,18 +198,13 @@
 	totallen = sectors * info->ssize;
 
 	// 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.  We will
-	// move the data a piece at a time between the bounce buffer and
-	// the actual transfer buffer.  If we're not using scatter-gather,
-	// we can simply update the transfer buffer pointer to get the
-	// same effect.
+	// a bounce buffer and move the data a piece at a time between the
+	// bounce buffer and the actual transfer buffer.
 
 	alloclen = min(totallen, 65536u);
-	if (use_sg) {
-		buffer = kmalloc(alloclen, GFP_NOIO);
-		if (buffer == NULL)
-			return USB_STOR_TRANSPORT_ERROR;
-	}
+	buffer = kmalloc(alloclen, GFP_NOIO);
+	if (buffer == NULL)
+		return USB_STOR_TRANSPORT_ERROR;
 
 	do {
 		// loop, never allocate or transfer more than 64k at once
@@ -230,10 +213,9 @@
 		len = min(totallen, alloclen);
 		thistime = (len / info->ssize) & 0xff;
 
-		// Get the data from the transfer buffer (s-g)
-		if (use_sg)
-			usb_stor_access_xfer_buf(buffer, len, us->srb,
-					&sg_idx, &sg_offset, FROM_XFER_BUF);
+		// Get the data from the transfer buffer
+		usb_stor_access_xfer_buf(buffer, len, us->srb,
+				&sg_idx, &sg_offset, FROM_XFER_BUF);
 
 		command[0] = 0;
 		command[1] = thistime;
@@ -269,21 +251,15 @@
 			goto leave;
 		}
 
-		// Update the transfer buffer pointer (!s-g)
-		if (!use_sg)
-			buffer += len;
-
 		sector += thistime;
 		totallen -= len;
 	} while (totallen > 0);
 
-	if (use_sg)
-		kfree(buffer);
+	kfree(buffer);
 	return USB_STOR_TRANSPORT_GOOD;
 
  leave:
-	if (use_sg)
-		kfree(buffer);
+	kfree(buffer);
 	return USB_STOR_TRANSPORT_ERROR;
 }
 
@@ -615,7 +591,7 @@
 		blocks = ((u32)(srb->cmnd[7]) << 8) | ((u32)(srb->cmnd[8]));
 
 		US_DEBUGP("datafab_transport:  READ_10: read block 0x%04lx  count %ld\n", block, blocks);
-		return datafab_read_data(us, info, block, blocks, ptr, srb->use_sg);
+		return datafab_read_data(us, info, block, blocks);
 	}
 
 	if (srb->cmnd[0] == READ_12) {
@@ -628,7 +604,7 @@
 			 ((u32)(srb->cmnd[8]) <<  8) | ((u32)(srb->cmnd[9]));
 
 		US_DEBUGP("datafab_transport:  READ_12: read block 0x%04lx  count %ld\n", block, blocks);
-		return datafab_read_data(us, info, block, blocks, ptr, srb->use_sg);
+		return datafab_read_data(us, info, block, blocks);
 	}
 
 	if (srb->cmnd[0] == WRITE_10) {
@@ -638,7 +614,7 @@
 		blocks = ((u32)(srb->cmnd[7]) << 8) | ((u32)(srb->cmnd[8]));
 
 		US_DEBUGP("datafab_transport:  WRITE_10: write block 0x%04lx  count %ld\n", block, blocks);
-		return datafab_write_data(us, info, block, blocks, ptr, srb->use_sg);
+		return datafab_write_data(us, info, block, blocks);
 	}
 
 	if (srb->cmnd[0] == WRITE_12) {
@@ -651,7 +627,7 @@
 			 ((u32)(srb->cmnd[8]) <<  8) | ((u32)(srb->cmnd[9]));
 
 		US_DEBUGP("datafab_transport:  WRITE_12: write block 0x%04lx  count %ld\n", block, blocks);
-		return datafab_write_data(us, info, block, blocks, ptr, srb->use_sg);
+		return datafab_write_data(us, info, block, blocks);
 	}
 
 	if (srb->cmnd[0] == TEST_UNIT_READY) {
diff -Nru a/drivers/usb/storage/jumpshot.c b/drivers/usb/storage/jumpshot.c
--- a/drivers/usb/storage/jumpshot.c	Tue Jan 20 17:34:50 2004
+++ b/drivers/usb/storage/jumpshot.c	Tue Jan 20 17:34:50 2004
@@ -109,11 +109,10 @@
 static int jumpshot_read_data(struct us_data *us,
 			      struct jumpshot_info *info,
 			      u32 sector,
-			      u32 sectors, 
-			      unsigned char *buffer, 
-			      int use_sg)
+			      u32 sectors)
 {
 	unsigned char *command = us->iobuf;
+	unsigned char *buffer;
 	unsigned char  thistime;
 	unsigned int totallen, alloclen;
 	int len, result;
@@ -130,18 +129,13 @@
 	totallen = sectors * info->ssize;
 
 	// 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.  We will
-	// move the data a piece at a time between the bounce buffer and
-	// the actual transfer buffer.  If we're not using scatter-gather,
-	// we can simply update the transfer buffer pointer to get the
-	// same effect.
+	// a bounce buffer and move the data a piece at a time between the
+	// bounce buffer and the actual transfer buffer.
 
 	alloclen = min(totallen, 65536u);
-	if (use_sg) {
-		buffer = kmalloc(alloclen, GFP_NOIO);
-		if (buffer == NULL)
-			return USB_STOR_TRANSPORT_ERROR;
-	}
+	buffer = kmalloc(alloclen, GFP_NOIO);
+	if (buffer == NULL)
+		return USB_STOR_TRANSPORT_ERROR;
 
 	do {
 		// loop, never allocate or transfer more than 64k at once
@@ -171,24 +165,19 @@
 
 		US_DEBUGP("jumpshot_read_data:  %d bytes\n", len);
 
-		// Store the data (s-g) or update the pointer (!s-g)
-		if (use_sg)
-			usb_stor_access_xfer_buf(buffer, len, us->srb,
-					 &sg_idx, &sg_offset, TO_XFER_BUF);
-		else
-			buffer += len;
+		// Store the data in the transfer buffer
+		usb_stor_access_xfer_buf(buffer, len, us->srb,
+				 &sg_idx, &sg_offset, TO_XFER_BUF);
 
 		sector += thistime;
 		totallen -= len;
 	} while (totallen > 0);
 
-	if (use_sg)
-		kfree(buffer);
+	kfree(buffer);
 	return USB_STOR_TRANSPORT_GOOD;
 
  leave:
-	if (use_sg)
-		kfree(buffer);
+	kfree(buffer);
 	return USB_STOR_TRANSPORT_ERROR;
 }
 
@@ -196,11 +185,10 @@
 static int jumpshot_write_data(struct us_data *us,
 			       struct jumpshot_info *info,
 			       u32 sector,
-			       u32 sectors, 
-			       unsigned char *buffer, 
-			       int use_sg)
+			       u32 sectors)
 {
 	unsigned char *command = us->iobuf;
+	unsigned char *buffer;
 	unsigned char  thistime;
 	unsigned int totallen, alloclen;
 	int len, result, waitcount;
@@ -217,18 +205,13 @@
 	totallen = sectors * info->ssize;
 
 	// 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.  We will
-	// move the data a piece at a time between the bounce buffer and
-	// the actual transfer buffer.  If we're not using scatter-gather,
-	// we can simply update the transfer buffer pointer to get the
-	// same effect.
+	// a bounce buffer and move the data a piece at a time between the
+	// bounce buffer and the actual transfer buffer.
 
 	alloclen = min(totallen, 65536u);
-	if (use_sg) {
-		buffer = kmalloc(alloclen, GFP_NOIO);
-		if (buffer == NULL)
-			return USB_STOR_TRANSPORT_ERROR;
-	}
+	buffer = kmalloc(alloclen, GFP_NOIO);
+	if (buffer == NULL)
+		return USB_STOR_TRANSPORT_ERROR;
 
 	do {
 		// loop, never allocate or transfer more than 64k at once
@@ -237,10 +220,9 @@
 		len = min(totallen, alloclen);
 		thistime = (len / info->ssize) & 0xff;
 
-		// Get the data from the transfer buffer (s-g)
-		if (use_sg)
-			usb_stor_access_xfer_buf(buffer, len, us->srb,
-					&sg_idx, &sg_offset, FROM_XFER_BUF);
+		// Get the data from the transfer buffer
+		usb_stor_access_xfer_buf(buffer, len, us->srb,
+				&sg_idx, &sg_offset, FROM_XFER_BUF);
 
 		command[0] = 0;
 		command[1] = thistime;
@@ -278,21 +260,15 @@
 		if (result != USB_STOR_TRANSPORT_GOOD)
 			US_DEBUGP("jumpshot_write_data:  Gah!  Waitcount = 10.  Bad write!?\n");
 
-		// Update the transfer buffer pointer (!s-g)
-		if (!use_sg)
-			buffer += len;
-
 		sector += thistime;
 		totallen -= len;
 	} while (totallen > 0);
 
-	if (use_sg)
-		kfree(buffer);
+	kfree(buffer);
 	return result;
 
  leave:
-	if (use_sg)
-		kfree(buffer);
+	kfree(buffer);
 	return USB_STOR_TRANSPORT_ERROR;
 }
 
@@ -546,7 +522,7 @@
 		blocks = ((u32)(srb->cmnd[7]) << 8) | ((u32)(srb->cmnd[8]));
 
 		US_DEBUGP("jumpshot_transport:  READ_10: read block 0x%04lx  count %ld\n", block, blocks);
-		return jumpshot_read_data(us, info, block, blocks, ptr, srb->use_sg);
+		return jumpshot_read_data(us, info, block, blocks);
 	}
 
 	if (srb->cmnd[0] == READ_12) {
@@ -559,7 +535,7 @@
 			 ((u32)(srb->cmnd[8]) <<  8) | ((u32)(srb->cmnd[9]));
 
 		US_DEBUGP("jumpshot_transport:  READ_12: read block 0x%04lx  count %ld\n", block, blocks);
-		return jumpshot_read_data(us, info, block, blocks, ptr, srb->use_sg);
+		return jumpshot_read_data(us, info, block, blocks);
 	}
 
 	if (srb->cmnd[0] == WRITE_10) {
@@ -569,7 +545,7 @@
 		blocks = ((u32)(srb->cmnd[7]) << 8) | ((u32)(srb->cmnd[8]));
 
 		US_DEBUGP("jumpshot_transport:  WRITE_10: write block 0x%04lx  count %ld\n", block, blocks);
-		return jumpshot_write_data(us, info, block, blocks, ptr, srb->use_sg);
+		return jumpshot_write_data(us, info, block, blocks);
 	}
 
 	if (srb->cmnd[0] == WRITE_12) {
@@ -582,7 +558,7 @@
 			 ((u32)(srb->cmnd[8]) <<  8) | ((u32)(srb->cmnd[9]));
 
 		US_DEBUGP("jumpshot_transport:  WRITE_12: write block 0x%04lx  count %ld\n", block, blocks);
-		return jumpshot_write_data(us, info, block, blocks, ptr, srb->use_sg);
+		return jumpshot_write_data(us, info, block, blocks);
 	}
 
 
diff -Nru a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c
--- a/drivers/usb/storage/sddr09.c	Tue Jan 20 17:34:50 2004
+++ b/drivers/usb/storage/sddr09.c	Tue Jan 20 17:34:50 2004
@@ -662,31 +662,24 @@
 static int
 sddr09_read_data(struct us_data *us,
 		 unsigned long address,
-		 unsigned int sectors,
-		 unsigned char *buffer,
-		 int use_sg) {
+		 unsigned int sectors) {
 
 	struct sddr09_card_info *info = (struct sddr09_card_info *) us->extra;
+	unsigned char *buffer;
 	unsigned int lba, maxlba, pba;
 	unsigned int page, pages;
 	unsigned int len, index, offset;
 	int result;
 
 	// Since we only read in one block at a time, we have to create
-	// a bounce buffer if the transfer uses scatter-gather.  We will
-	// move the data a piece at a time between the bounce buffer and
-	// the actual transfer buffer.  If we're not using scatter-gather,
-	// we can simply update the transfer buffer pointer to get the
-	// same effect.
-
-	if (use_sg) {
-		len = min(sectors, (unsigned int) info->blocksize) *
-				info->pagesize;
-		buffer = kmalloc(len, GFP_NOIO);
-		if (buffer == NULL) {
-			printk("sddr09_read_data: Out of memory\n");
-			return USB_STOR_TRANSPORT_ERROR;
-		}
+	// a bounce buffer and move the data a piece at a time between the
+	// bounce buffer and the actual transfer buffer.
+
+	len = min(sectors, (unsigned int) info->blocksize) * info->pagesize;
+	buffer = kmalloc(len, GFP_NOIO);
+	if (buffer == NULL) {
+		printk("sddr09_read_data: Out of memory\n");
+		return USB_STOR_TRANSPORT_ERROR;
 	}
 
 	// Figure out the initial LBA and page
@@ -743,21 +736,16 @@
 				break;
 		}
 
-		// Store the data (s-g) or update the pointer (!s-g)
-		if (use_sg)
-			usb_stor_access_xfer_buf(buffer, len, us->srb,
-					&index, &offset, TO_XFER_BUF);
-		else
-			buffer += len;
+		// Store the data in the transfer buffer
+		usb_stor_access_xfer_buf(buffer, len, us->srb,
+				&index, &offset, TO_XFER_BUF);
 
 		page = 0;
 		lba++;
 		sectors -= pages;
 	}
 
-	if (use_sg)
-		kfree(buffer);
-
+	kfree(buffer);
 	return result;
 }
 
@@ -897,14 +885,13 @@
 static int
 sddr09_write_data(struct us_data *us,
 		  unsigned long address,
-		  unsigned int sectors,
-		  unsigned char *buffer,
-		  int use_sg) {
+		  unsigned int sectors) {
 
 	struct sddr09_card_info *info = (struct sddr09_card_info *) us->extra;
 	unsigned int lba, page, pages;
 	unsigned int pagelen, blocklen;
 	unsigned char *blockbuffer;
+	unsigned char *buffer;
 	unsigned int len, index, offset;
 	int result;
 
@@ -923,21 +910,15 @@
 	}
 
 	// Since we don't write the user data directly to the device,
-	// we have to create a bounce buffer if the transfer uses
-	// scatter-gather.  We will move the data a piece at a time
-	// between the bounce buffer and the actual transfer buffer.
-	// If we're not using scatter-gather, we can simply update
-	// the transfer buffer pointer to get the same effect.
-
-	if (use_sg) {
-		len = min(sectors, (unsigned int) info->blocksize) *
-				info->pagesize;
-		buffer = kmalloc(len, GFP_NOIO);
-		if (buffer == NULL) {
-			printk("sddr09_write_data: Out of memory\n");
-			kfree(blockbuffer);
-			return USB_STOR_TRANSPORT_ERROR;
-		}
+	// we have to create a bounce buffer and move the data a piece
+	// at a time between the bounce buffer and the actual transfer buffer.
+
+	len = min(sectors, (unsigned int) info->blocksize) * info->pagesize;
+	buffer = kmalloc(len, GFP_NOIO);
+	if (buffer == NULL) {
+		printk("sddr09_write_data: Out of memory\n");
+		kfree(blockbuffer);
+		return USB_STOR_TRANSPORT_ERROR;
 	}
 
 	// Figure out the initial LBA and page
@@ -954,27 +935,21 @@
 		pages = min(sectors, info->blocksize - page);
 		len = (pages << info->pageshift);
 
-		// Get the data from the transfer buffer (s-g)
-		if (use_sg)
-			usb_stor_access_xfer_buf(buffer, len, us->srb,
-					&index, &offset, FROM_XFER_BUF);
+		// Get the data from the transfer buffer
+		usb_stor_access_xfer_buf(buffer, len, us->srb,
+				&index, &offset, FROM_XFER_BUF);
 
 		result = sddr09_write_lba(us, lba, page, pages,
 				buffer, blockbuffer);
 		if (result != USB_STOR_TRANSPORT_GOOD)
 			break;
 
-		// Update the transfer buffer pointer (!s-g)
-		if (!use_sg)
-			buffer += len;
-
 		page = 0;
 		lba++;
 		sectors -= pages;
 	}
 
-	if (use_sg)
-		kfree(buffer);
+	kfree(buffer);
 	kfree(blockbuffer);
 
 	return result;
@@ -1546,7 +1521,7 @@
 		US_DEBUGP("READ_10: read page %d pagect %d\n",
 			  page, pages);
 
-		return sddr09_read_data(us, page, pages, ptr, srb->use_sg);
+		return sddr09_read_data(us, page, pages);
 	}
 
 	if (srb->cmnd[0] == WRITE_10) {
@@ -1559,7 +1534,7 @@
 		US_DEBUGP("WRITE_10: write page %d pagect %d\n",
 			  page, pages);
 
-		return sddr09_write_data(us, page, pages, ptr, srb->use_sg);
+		return sddr09_write_data(us, page, pages);
 	}
 
 	// Pass TEST_UNIT_READY and REQUEST_SENSE through
diff -Nru a/drivers/usb/storage/sddr55.c b/drivers/usb/storage/sddr55.c
--- a/drivers/usb/storage/sddr55.c	Tue Jan 20 17:34:50 2004
+++ b/drivers/usb/storage/sddr55.c	Tue Jan 20 17:34:50 2004
@@ -153,14 +153,13 @@
 static int sddr55_read_data(struct us_data *us,
 		unsigned int lba,
 		unsigned int page,
-		unsigned short sectors,
-		unsigned char *buffer,
-		int use_sg) {
+		unsigned short sectors) {
 
 	int result = USB_STOR_TRANSPORT_GOOD;
 	unsigned char *command = us->iobuf;
 	unsigned char *status = us->iobuf;
 	struct sddr55_card_info *info = (struct sddr55_card_info *)us->extra;
+	unsigned char *buffer;
 
 	unsigned int pba;
 	unsigned long address;
@@ -169,20 +168,14 @@
 	unsigned int len, index, offset;
 
 	// Since we only read in one block at a time, we have to create
-	// a bounce buffer if the transfer uses scatter-gather.  We will
-	// move the data a piece at a time between the bounce buffer and
-	// the actual transfer buffer.  If we're not using scatter-gather,
-	// we can simply update the transfer buffer pointer to get the
-	// same effect.
-
-	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 */
-	}
+	// a bounce buffer and move the data a piece at a time between the
+	// bounce buffer and the actual transfer buffer.
+
+	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) {
@@ -258,12 +251,9 @@
 			}
 		}
 
-		// Store the data (s-g) or update the pointer (!s-g)
-		if (use_sg)
-			usb_stor_access_xfer_buf(buffer, len, us->srb,
-					&index, &offset, TO_XFER_BUF);
-		else
-			buffer += len;
+		// Store the data in the transfer buffer
+		usb_stor_access_xfer_buf(buffer, len, us->srb,
+				&index, &offset, TO_XFER_BUF);
 
 		page = 0;
 		lba++;
@@ -273,8 +263,7 @@
 	result = USB_STOR_TRANSPORT_GOOD;
 
 leave:
-	if (use_sg)
-		kfree(buffer);
+	kfree(buffer);
 
 	return result;
 }
@@ -282,14 +271,13 @@
 static int sddr55_write_data(struct us_data *us,
 		unsigned int lba,
 		unsigned int page,
-		unsigned short sectors,
-		unsigned char *buffer,
-		int use_sg) {
+		unsigned short sectors) {
 
 	int result = USB_STOR_TRANSPORT_GOOD;
 	unsigned char *command = us->iobuf;
 	unsigned char *status = us->iobuf;
 	struct sddr55_card_info *info = (struct sddr55_card_info *)us->extra;
+	unsigned char *buffer;
 
 	unsigned int pba;
 	unsigned int new_pba;
@@ -306,20 +294,14 @@
 	}
 
 	// Since we only write one block at a time, we have to create
-	// a bounce buffer if the transfer uses scatter-gather.  We will
-	// move the data a piece at a time between the bounce buffer and
-	// the actual transfer buffer.  If we're not using scatter-gather,
-	// we can simply update the transfer buffer pointer to get the
-	// same effect.
-
-	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;
-	}
+	// a bounce buffer and move the data a piece at a time between the
+	// bounce buffer and the actual transfer buffer.
+
+	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) {
@@ -336,10 +318,9 @@
 				info->blocksize - page);
 		len = pages << info->pageshift;
 
-		// Get the data from the transfer buffer (s-g)
-		if (use_sg)
-			usb_stor_access_xfer_buf(buffer, len, us->srb,
-					&index, &offset, FROM_XFER_BUF);
+		// Get the data from the transfer buffer
+		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",
@@ -480,9 +461,6 @@
 		/* update the pba<->lba maps for new_pba */
 		info->pba_to_lba[new_pba] = lba % 1000;
 
-		// Update the transfer buffer pointer (!s-g)
-		if (!use_sg)
-			buffer += len;
 		page = 0;
 		lba++;
 		sectors -= pages >> info->smallpageshift;
@@ -490,8 +468,7 @@
 	result = USB_STOR_TRANSPORT_GOOD;
 
  leave:
-	if (use_sg)
-		kfree(buffer);
+	kfree(buffer);
 	return result;
 }
 
@@ -963,13 +940,13 @@
 				" pages %d\n",
 				pba, lba, page, pages);
 
-			return sddr55_write_data(us, lba, page, pages, ptr, srb->use_sg);
+			return sddr55_write_data(us, lba, page, pages);
 		} else {
 			US_DEBUGP("READ_10: read block %04X (LBA %04X) page %01X"
 				" pages %d\n",
 				pba, lba, page, pages);
 
-			return sddr55_read_data(us, lba, page, pages, ptr, srb->use_sg);
+			return sddr55_read_data(us, lba, page, pages);
 		}
 	}
 
diff -Nru a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c
--- a/drivers/usb/storage/shuttle_usbat.c	Tue Jan 20 17:34:50 2004
+++ b/drivers/usb/storage/shuttle_usbat.c	Tue Jan 20 17:34:50 2004
@@ -569,21 +569,15 @@
 	}
 
 	// Since we only read in one block at a time, we have to create
-	// a bounce buffer if the transfer uses scatter-gather.  We will
-	// move the data a piece at a time between the bounce buffer and
-	// the actual transfer buffer.  If we're not using scatter-gather,
-	// we can simply update the transfer buffer pointer to get the
-	// same effect.
+	// a bounce buffer and move the data a piece at a time between the
+	// bounce buffer and the actual transfer buffer.
 
 	len = (65535/srb->transfersize) * srb->transfersize;
 	US_DEBUGP("Max read is %d bytes\n", len);
 	len = min(len, srb->request_bufflen);
-	if (srb->use_sg) {
-		buffer = kmalloc(len, GFP_NOIO);
-		if (buffer == NULL) // bloody hell!
-			return USB_STOR_TRANSPORT_FAILED;
-	} else
-		buffer = srb->request_buffer;
+	buffer = kmalloc(len, GFP_NOIO);
+	if (buffer == NULL) // bloody hell!
+		return USB_STOR_TRANSPORT_FAILED;
 	sector = short_pack(data[7+3], data[7+2]);
 	sector <<= 16;
 	sector |= short_pack(data[7+5], data[7+4]);
@@ -621,12 +615,9 @@
 		if (result != USB_STOR_TRANSPORT_GOOD)
 			break;
 
-		// Store the data (s-g) or update the pointer (!s-g)
-		if (srb->use_sg)
-			usb_stor_access_xfer_buf(buffer, len, srb,
-					 &sg_segment, &sg_offset, TO_XFER_BUF);
-		else
-			buffer += len;
+		// Store the data in the transfer buffer
+		usb_stor_access_xfer_buf(buffer, len, srb,
+				 &sg_segment, &sg_offset, TO_XFER_BUF);
 
 		// Update the amount transferred and the sector number
 
@@ -635,8 +626,7 @@
 
 	} // while transferred != srb->request_bufflen
 
-	if (srb->use_sg)
-		kfree(buffer);
+	kfree(buffer);
 	return result;
 }
 
