This is the third of three patches to prepare the sddr09 subdriver for conversion to the Sim-SCSI framework. This patch (as596) moves the computation of the LBA to the start of the read/write routines, so that addresses completely beyond the end of the device can be detected and reported differently from transfers that are partially within the device's capacity.
Signed-off-by: Alan Stern <[EMAIL PROTECTED]>
Acked-by: Andries Brouwer <[EMAIL PROTECTED]>
Signed-off-by: Matthew Dharm <[EMAIL PROTECTED]>
Greg, please apply.
Matt
Index: usb-2.6/drivers/usb/storage/sddr09.c
===================================================================
--- usb-2.6.orig/drivers/usb/storage/sddr09.c
+++ usb-2.6/drivers/usb/storage/sddr09.c
@@ -711,6 +711,13 @@ sddr09_read_data(struct us_data *us,
unsigned int len, index, offset;
int result;
+ // Figure out the initial LBA and page
+ lba = address >> info->blockshift;
+ page = (address & info->blockmask);
+ maxlba = info->capacity >> (info->pageshift + info->blockshift);
+ if (lba >= maxlba)
+ return -EIO;
+
// Since we only read in one block at a time, 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.
@@ -722,11 +729,6 @@ sddr09_read_data(struct us_data *us,
return -ENOMEM;
}
- // Figure out the initial LBA and page
- lba = address >> info->blockshift;
- page = (address & info->blockmask);
- maxlba = info->capacity >> (info->pageshift + info->blockshift);
-
// This could be made much more efficient by checking for
// contiguous LBA's. Another exercise left to the student.
@@ -928,13 +930,20 @@ sddr09_write_data(struct us_data *us,
unsigned int sectors) {
struct sddr09_card_info *info = (struct sddr09_card_info *) us->extra;
- unsigned int lba, page, pages;
+ unsigned int lba, maxlba, page, pages;
unsigned int pagelen, blocklen;
unsigned char *blockbuffer;
unsigned char *buffer;
unsigned int len, index, offset;
int result;
+ // Figure out the initial LBA and page
+ lba = address >> info->blockshift;
+ page = (address & info->blockmask);
+ maxlba = info->capacity >> (info->pageshift + info->blockshift);
+ if (lba >= maxlba)
+ return -EIO;
+
// blockbuffer is used for reading in the old data, overwriting
// with the new data, and performing ECC calculations
@@ -961,10 +970,6 @@ sddr09_write_data(struct us_data *us,
return -ENOMEM;
}
- // Figure out the initial LBA and page
- lba = address >> info->blockshift;
- page = (address & info->blockmask);
-
result = 0;
index = offset = 0;
@@ -975,6 +980,14 @@ sddr09_write_data(struct us_data *us,
pages = min(sectors, info->blocksize - page);
len = (pages << info->pageshift);
+ /* Not overflowing capacity? */
+ if (lba >= maxlba) {
+ US_DEBUGP("Error: Requested lba %u exceeds "
+ "maximum %u\n", lba, maxlba);
+ result = -EIO;
+ break;
+ }
+
// Get the data from the transfer buffer
usb_stor_access_xfer_buf(buffer, len, us->srb,
&index, &offset, FROM_XFER_BUF);
--
Matthew Dharm Home: [EMAIL PROTECTED]
Maintainer, Linux USB Mass Storage Driver
But where are the THEMES?! How do you expect me to use an OS without
themes?!
-- Stef
User Friendly, 10/9/1998
pgpiWMFXREmNc.pgp
Description: PGP signature
