diff options
author | Matthew Dharm <mdharm-usb@one-eyed-alien.net> | 2005-12-05 00:59:45 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-01-04 16:51:42 -0500 |
commit | a6c976c6c4628ce0c9277c47e7545956d9d4f441 (patch) | |
tree | 0c0f531595dac6b340c85af500cfb1dae7122bea /drivers/usb/storage/sddr09.c | |
parent | 0dc08a357538de3d93305fbf99348663abdbf2cd (diff) |
[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>
Diffstat (limited to 'drivers/usb/storage/sddr09.c')
-rw-r--r-- | drivers/usb/storage/sddr09.c | 33 |
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); |