aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Dharm <mdharm-usb@one-eyed-alien.net>2005-12-04 21:59:45 -0800
committerGreg Kroah-Hartman <gregkh@suse.de>2006-01-04 13:51:42 -0800
commita6c976c6c4628ce0c9277c47e7545956d9d4f441 (patch)
tree0c0f531595dac6b340c85af500cfb1dae7122bea
parent0dc08a357538de3d93305fbf99348663abdbf2cd (diff)
downloadlinux-a6c976c6c4628ce0c9277c47e7545956d9d4f441.tar.gz
[PATCH] USB Storage: more sddr09 cleanups
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 <stern@rowland.harvard.edu> Acked-by: Andries Brouwer <Andries.Brouwer@cwi.nl> Signed-off-by: Matthew Dharm <mdharm-usb@one-eyed-alien.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/storage/sddr09.c33
1 files changed, 23 insertions, 10 deletions
diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c
index 760fe9362b6d96..b8e7802c871d91 100644
--- a/drivers/usb/storage/sddr09.c
+++ b/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);