aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 760fe9362b6d..b8e7802c871d 100644
--- a/drivers/usb/storage/sddr09.c
+++ b/drivers/usb/storage/sddr09.c
@@ -711,6 +711,13 @@ sddr09_read_data(struct us_data *us,
711 unsigned int len, index, offset; 711 unsigned int len, index, offset;
712 int result; 712 int result;
713 713
714 // Figure out the initial LBA and page
715 lba = address >> info->blockshift;
716 page = (address & info->blockmask);
717 maxlba = info->capacity >> (info->pageshift + info->blockshift);
718 if (lba >= maxlba)
719 return -EIO;
720
714 // Since we only read in one block at a time, we have to create 721 // Since we only read in one block at a time, we have to create
715 // a bounce buffer and move the data a piece at a time between the 722 // a bounce buffer and move the data a piece at a time between the
716 // bounce buffer and the actual transfer buffer. 723 // bounce buffer and the actual transfer buffer.
@@ -722,11 +729,6 @@ sddr09_read_data(struct us_data *us,
722 return -ENOMEM; 729 return -ENOMEM;
723 } 730 }
724 731
725 // Figure out the initial LBA and page
726 lba = address >> info->blockshift;
727 page = (address & info->blockmask);
728 maxlba = info->capacity >> (info->pageshift + info->blockshift);
729
730 // This could be made much more efficient by checking for 732 // This could be made much more efficient by checking for
731 // contiguous LBA's. Another exercise left to the student. 733 // contiguous LBA's. Another exercise left to the student.
732 734
@@ -928,13 +930,20 @@ sddr09_write_data(struct us_data *us,
928 unsigned int sectors) { 930 unsigned int sectors) {
929 931
930 struct sddr09_card_info *info = (struct sddr09_card_info *) us->extra; 932 struct sddr09_card_info *info = (struct sddr09_card_info *) us->extra;
931 unsigned int lba, page, pages; 933 unsigned int lba, maxlba, page, pages;
932 unsigned int pagelen, blocklen; 934 unsigned int pagelen, blocklen;
933 unsigned char *blockbuffer; 935 unsigned char *blockbuffer;
934 unsigned char *buffer; 936 unsigned char *buffer;
935 unsigned int len, index, offset; 937 unsigned int len, index, offset;
936 int result; 938 int result;
937 939
940 // Figure out the initial LBA and page
941 lba = address >> info->blockshift;
942 page = (address & info->blockmask);
943 maxlba = info->capacity >> (info->pageshift + info->blockshift);
944 if (lba >= maxlba)
945 return -EIO;
946
938 // blockbuffer is used for reading in the old data, overwriting 947 // blockbuffer is used for reading in the old data, overwriting
939 // with the new data, and performing ECC calculations 948 // with the new data, and performing ECC calculations
940 949
@@ -961,10 +970,6 @@ sddr09_write_data(struct us_data *us,
961 return -ENOMEM; 970 return -ENOMEM;
962 } 971 }
963 972
964 // Figure out the initial LBA and page
965 lba = address >> info->blockshift;
966 page = (address & info->blockmask);
967
968 result = 0; 973 result = 0;
969 index = offset = 0; 974 index = offset = 0;
970 975
@@ -975,6 +980,14 @@ sddr09_write_data(struct us_data *us,
975 pages = min(sectors, info->blocksize - page); 980 pages = min(sectors, info->blocksize - page);
976 len = (pages << info->pageshift); 981 len = (pages << info->pageshift);
977 982
983 /* Not overflowing capacity? */
984 if (lba >= maxlba) {
985 US_DEBUGP("Error: Requested lba %u exceeds "
986 "maximum %u\n", lba, maxlba);
987 result = -EIO;
988 break;
989 }
990
978 // Get the data from the transfer buffer 991 // Get the data from the transfer buffer
979 usb_stor_access_xfer_buf(buffer, len, us->srb, 992 usb_stor_access_xfer_buf(buffer, len, us->srb,
980 &index, &offset, FROM_XFER_BUF); 993 &index, &offset, FROM_XFER_BUF);