forked from Minki/linux
[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>
This commit is contained in:
parent
0dc08a3575
commit
a6c976c6c4
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user