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
pgp00000.pgp
Description: PGP signature
