|
@@ -711,6 +711,13 @@ sddr09_read_data(struct us_data *us,
|
|
unsigned int len, index, offset;
|
|
unsigned int len, index, offset;
|
|
int result;
|
|
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
|
|
// 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
|
|
// a bounce buffer and move the data a piece at a time between the
|
|
// bounce buffer and the actual transfer buffer.
|
|
// bounce buffer and the actual transfer buffer.
|
|
@@ -722,11 +729,6 @@ sddr09_read_data(struct us_data *us,
|
|
return -ENOMEM;
|
|
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
|
|
// This could be made much more efficient by checking for
|
|
// contiguous LBA's. Another exercise left to the student.
|
|
// contiguous LBA's. Another exercise left to the student.
|
|
|
|
|
|
@@ -928,13 +930,20 @@ sddr09_write_data(struct us_data *us,
|
|
unsigned int sectors) {
|
|
unsigned int sectors) {
|
|
|
|
|
|
struct sddr09_card_info *info = (struct sddr09_card_info *) us->extra;
|
|
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 int pagelen, blocklen;
|
|
unsigned char *blockbuffer;
|
|
unsigned char *blockbuffer;
|
|
unsigned char *buffer;
|
|
unsigned char *buffer;
|
|
unsigned int len, index, offset;
|
|
unsigned int len, index, offset;
|
|
int result;
|
|
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
|
|
// blockbuffer is used for reading in the old data, overwriting
|
|
// with the new data, and performing ECC calculations
|
|
// with the new data, and performing ECC calculations
|
|
|
|
|
|
@@ -961,10 +970,6 @@ sddr09_write_data(struct us_data *us,
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
}
|
|
}
|
|
|
|
|
|
- // Figure out the initial LBA and page
|
|
|
|
- lba = address >> info->blockshift;
|
|
|
|
- page = (address & info->blockmask);
|
|
|
|
-
|
|
|
|
result = 0;
|
|
result = 0;
|
|
index = offset = 0;
|
|
index = offset = 0;
|
|
|
|
|
|
@@ -975,6 +980,14 @@ sddr09_write_data(struct us_data *us,
|
|
pages = min(sectors, info->blocksize - page);
|
|
pages = min(sectors, info->blocksize - page);
|
|
len = (pages << info->pageshift);
|
|
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
|
|
// Get the data from the transfer buffer
|
|
usb_stor_access_xfer_buf(buffer, len, us->srb,
|
|
usb_stor_access_xfer_buf(buffer, len, us->srb,
|
|
&index, &offset, FROM_XFER_BUF);
|
|
&index, &offset, FROM_XFER_BUF);
|