aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorPeiyu Li <peiyu.li@csr.com>2011-08-18 01:52:59 -0400
committerFelipe Balbi <balbi@ti.com>2011-09-09 06:06:02 -0400
commit3f565a363cee14d2ed281823196d455bfc7c4170 (patch)
tree57e75064f7f153a3d5069b26d8b4fe9acf0a510a /drivers/usb
parent019ac83252dc2b356cb0ca81c25a077ec90309e7 (diff)
usb: gadget: storage: adapt logic block size to bound block devices
Now the mass storage driver has fixed logic block size of 512 bytes. The mass storage gadget read/write bound devices only through VFS, so the bottom level devices actually are just RAW devices to the driver and connected PC. As a RAW, hosts can always format, read and write it right in 512 bytes logic block and don't care about the actual logic block size of devices bound to the gadget. But if we want to share the bound block device partition between target board and PC, in case the logic block size of the bound block device is 4KB, we execute the following steps: 1. connect a board with mass storage gadget to PC(the board has set one partition of on-board block device as file name of the mass storage) 2. PC format the mass storage to VFAT by default logic block size and read/write it 3. disconnect boards from PC 4. target board mount the partition as VFAT Step 4 will fail since kernel on target thinks the logic block size of the bound partition as 4KB. A typical error is "FAT: logical sector size too small for device (logical sector size = 512)" If we execute opposite steps: 1. format the partition to VFAT on target board and read/write this partition 2. connect the board to Windows PC as usb mass storage gadget, windows will think the disk is not formatted So the conclusion is that only as a gadget, the mass storage driver has no any problem. But being shared VFAT or other filesystem on PC and target board, it will fail. This patch adapts logic block size to bound block devices and fix the issue. Cc: Michal Nazarewicz <mina86@mina86.com> Acked-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Peiyu Li <peiyu.li@csr.com> Signed-off-by: Xianglong Du <xianglong.du@csr.com> Signed-off-by: Huayi Li <huayi.li@csr.com> Signed-off-by: Barry Song <Baohua.Song@csr.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/gadget/f_mass_storage.c63
-rw-r--r--drivers/usb/gadget/file_storage.c50
-rw-r--r--drivers/usb/gadget/storage_common.c23
3 files changed, 79 insertions, 57 deletions
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index 4ce3decda1db..1cdb1fa1b158 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -112,8 +112,7 @@
112 * is not loaded (an empty string as "filename" in the fsg_config 112 * is not loaded (an empty string as "filename" in the fsg_config
113 * structure causes error). The CD-ROM emulation includes a single 113 * structure causes error). The CD-ROM emulation includes a single
114 * data track and no audio tracks; hence there need be only one 114 * data track and no audio tracks; hence there need be only one
115 * backing file per LUN. Note also that the CD-ROM block length is 115 * backing file per LUN.
116 * set to 512 rather than the more common value 2048.
117 * 116 *
118 * 117 *
119 * MSF includes support for module parameters. If gadget using it 118 * MSF includes support for module parameters. If gadget using it
@@ -771,7 +770,7 @@ static int do_read(struct fsg_common *common)
771 curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; 770 curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
772 return -EINVAL; 771 return -EINVAL;
773 } 772 }
774 file_offset = ((loff_t) lba) << 9; 773 file_offset = ((loff_t) lba) << curlun->blkbits;
775 774
776 /* Carry out the file reads */ 775 /* Carry out the file reads */
777 amount_left = common->data_size_from_cmnd; 776 amount_left = common->data_size_from_cmnd;
@@ -812,7 +811,8 @@ static int do_read(struct fsg_common *common)
812 if (amount == 0) { 811 if (amount == 0) {
813 curlun->sense_data = 812 curlun->sense_data =
814 SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; 813 SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
815 curlun->sense_data_info = file_offset >> 9; 814 curlun->sense_data_info =
815 file_offset >> curlun->blkbits;
816 curlun->info_valid = 1; 816 curlun->info_valid = 1;
817 bh->inreq->length = 0; 817 bh->inreq->length = 0;
818 bh->state = BUF_STATE_FULL; 818 bh->state = BUF_STATE_FULL;
@@ -835,7 +835,7 @@ static int do_read(struct fsg_common *common)
835 } else if (nread < amount) { 835 } else if (nread < amount) {
836 LDBG(curlun, "partial file read: %d/%u\n", 836 LDBG(curlun, "partial file read: %d/%u\n",
837 (int)nread, amount); 837 (int)nread, amount);
838 nread -= (nread & 511); /* Round down to a block */ 838 nread = round_down(nread, curlun->blksize);
839 } 839 }
840 file_offset += nread; 840 file_offset += nread;
841 amount_left -= nread; 841 amount_left -= nread;
@@ -846,7 +846,8 @@ static int do_read(struct fsg_common *common)
846 /* If an error occurred, report it and its position */ 846 /* If an error occurred, report it and its position */
847 if (nread < amount) { 847 if (nread < amount) {
848 curlun->sense_data = SS_UNRECOVERED_READ_ERROR; 848 curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
849 curlun->sense_data_info = file_offset >> 9; 849 curlun->sense_data_info =
850 file_offset >> curlun->blkbits;
850 curlun->info_valid = 1; 851 curlun->info_valid = 1;
851 break; 852 break;
852 } 853 }
@@ -921,7 +922,7 @@ static int do_write(struct fsg_common *common)
921 922
922 /* Carry out the file writes */ 923 /* Carry out the file writes */
923 get_some_more = 1; 924 get_some_more = 1;
924 file_offset = usb_offset = ((loff_t) lba) << 9; 925 file_offset = usb_offset = ((loff_t) lba) << curlun->blkbits;
925 amount_left_to_req = common->data_size_from_cmnd; 926 amount_left_to_req = common->data_size_from_cmnd;
926 amount_left_to_write = common->data_size_from_cmnd; 927 amount_left_to_write = common->data_size_from_cmnd;
927 928
@@ -954,11 +955,12 @@ static int do_write(struct fsg_common *common)
954 get_some_more = 0; 955 get_some_more = 0;
955 curlun->sense_data = 956 curlun->sense_data =
956 SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; 957 SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
957 curlun->sense_data_info = usb_offset >> 9; 958 curlun->sense_data_info =
959 usb_offset >> curlun->blkbits;
958 curlun->info_valid = 1; 960 curlun->info_valid = 1;
959 continue; 961 continue;
960 } 962 }
961 amount -= amount & 511; 963 amount = round_down(amount, curlun->blksize);
962 if (amount == 0) { 964 if (amount == 0) {
963 965
964 /* 966 /*
@@ -1002,7 +1004,8 @@ static int do_write(struct fsg_common *common)
1002 /* Did something go wrong with the transfer? */ 1004 /* Did something go wrong with the transfer? */
1003 if (bh->outreq->status != 0) { 1005 if (bh->outreq->status != 0) {
1004 curlun->sense_data = SS_COMMUNICATION_FAILURE; 1006 curlun->sense_data = SS_COMMUNICATION_FAILURE;
1005 curlun->sense_data_info = file_offset >> 9; 1007 curlun->sense_data_info =
1008 file_offset >> curlun->blkbits;
1006 curlun->info_valid = 1; 1009 curlun->info_valid = 1;
1007 break; 1010 break;
1008 } 1011 }
@@ -1033,8 +1036,7 @@ static int do_write(struct fsg_common *common)
1033 } else if (nwritten < amount) { 1036 } else if (nwritten < amount) {
1034 LDBG(curlun, "partial file write: %d/%u\n", 1037 LDBG(curlun, "partial file write: %d/%u\n",
1035 (int)nwritten, amount); 1038 (int)nwritten, amount);
1036 nwritten -= (nwritten & 511); 1039 nwritten = round_down(nwritten, curlun->blksize);
1037 /* Round down to a block */
1038 } 1040 }
1039 file_offset += nwritten; 1041 file_offset += nwritten;
1040 amount_left_to_write -= nwritten; 1042 amount_left_to_write -= nwritten;
@@ -1043,7 +1045,8 @@ static int do_write(struct fsg_common *common)
1043 /* If an error occurred, report it and its position */ 1045 /* If an error occurred, report it and its position */
1044 if (nwritten < amount) { 1046 if (nwritten < amount) {
1045 curlun->sense_data = SS_WRITE_ERROR; 1047 curlun->sense_data = SS_WRITE_ERROR;
1046 curlun->sense_data_info = file_offset >> 9; 1048 curlun->sense_data_info =
1049 file_offset >> curlun->blkbits;
1047 curlun->info_valid = 1; 1050 curlun->info_valid = 1;
1048 break; 1051 break;
1049 } 1052 }
@@ -1129,8 +1132,8 @@ static int do_verify(struct fsg_common *common)
1129 return -EIO; /* No default reply */ 1132 return -EIO; /* No default reply */
1130 1133
1131 /* Prepare to carry out the file verify */ 1134 /* Prepare to carry out the file verify */
1132 amount_left = verification_length << 9; 1135 amount_left = verification_length << curlun->blkbits;
1133 file_offset = ((loff_t) lba) << 9; 1136 file_offset = ((loff_t) lba) << curlun->blkbits;
1134 1137
1135 /* Write out all the dirty buffers before invalidating them */ 1138 /* Write out all the dirty buffers before invalidating them */
1136 fsg_lun_fsync_sub(curlun); 1139 fsg_lun_fsync_sub(curlun);
@@ -1157,7 +1160,8 @@ static int do_verify(struct fsg_common *common)
1157 if (amount == 0) { 1160 if (amount == 0) {
1158 curlun->sense_data = 1161 curlun->sense_data =
1159 SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; 1162 SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
1160 curlun->sense_data_info = file_offset >> 9; 1163 curlun->sense_data_info =
1164 file_offset >> curlun->blkbits;
1161 curlun->info_valid = 1; 1165 curlun->info_valid = 1;
1162 break; 1166 break;
1163 } 1167 }
@@ -1179,11 +1183,12 @@ static int do_verify(struct fsg_common *common)
1179 } else if (nread < amount) { 1183 } else if (nread < amount) {
1180 LDBG(curlun, "partial file verify: %d/%u\n", 1184 LDBG(curlun, "partial file verify: %d/%u\n",
1181 (int)nread, amount); 1185 (int)nread, amount);
1182 nread -= nread & 511; /* Round down to a sector */ 1186 nread = round_down(nread, curlun->blksize);
1183 } 1187 }
1184 if (nread == 0) { 1188 if (nread == 0) {
1185 curlun->sense_data = SS_UNRECOVERED_READ_ERROR; 1189 curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
1186 curlun->sense_data_info = file_offset >> 9; 1190 curlun->sense_data_info =
1191 file_offset >> curlun->blkbits;
1187 curlun->info_valid = 1; 1192 curlun->info_valid = 1;
1188 break; 1193 break;
1189 } 1194 }
@@ -1289,7 +1294,7 @@ static int do_read_capacity(struct fsg_common *common, struct fsg_buffhd *bh)
1289 1294
1290 put_unaligned_be32(curlun->num_sectors - 1, &buf[0]); 1295 put_unaligned_be32(curlun->num_sectors - 1, &buf[0]);
1291 /* Max logical block */ 1296 /* Max logical block */
1292 put_unaligned_be32(512, &buf[4]); /* Block length */ 1297 put_unaligned_be32(curlun->blksize, &buf[4]);/* Block length */
1293 return 8; 1298 return 8;
1294} 1299}
1295 1300
@@ -1527,7 +1532,7 @@ static int do_read_format_capacities(struct fsg_common *common,
1527 1532
1528 put_unaligned_be32(curlun->num_sectors, &buf[0]); 1533 put_unaligned_be32(curlun->num_sectors, &buf[0]);
1529 /* Number of blocks */ 1534 /* Number of blocks */
1530 put_unaligned_be32(512, &buf[4]); /* Block length */ 1535 put_unaligned_be32(curlun->blksize, &buf[4]);/* Block length */
1531 buf[4] = 0x02; /* Current capacity */ 1536 buf[4] = 0x02; /* Current capacity */
1532 return 12; 1537 return 12;
1533} 1538}
@@ -2022,7 +2027,8 @@ static int do_scsi_command(struct fsg_common *common)
2022 2027
2023 case READ_6: 2028 case READ_6:
2024 i = common->cmnd[4]; 2029 i = common->cmnd[4];
2025 common->data_size_from_cmnd = (i == 0 ? 256 : i) << 9; 2030 common->data_size_from_cmnd = (i == 0 ? 256 : i) <<
2031 common->curlun->blkbits;
2026 reply = check_command(common, 6, DATA_DIR_TO_HOST, 2032 reply = check_command(common, 6, DATA_DIR_TO_HOST,
2027 (7<<1) | (1<<4), 1, 2033 (7<<1) | (1<<4), 1,
2028 "READ(6)"); 2034 "READ(6)");
@@ -2032,7 +2038,8 @@ static int do_scsi_command(struct fsg_common *common)
2032 2038
2033 case READ_10: 2039 case READ_10:
2034 common->data_size_from_cmnd = 2040 common->data_size_from_cmnd =
2035 get_unaligned_be16(&common->cmnd[7]) << 9; 2041 get_unaligned_be16(&common->cmnd[7]) <<
2042 common->curlun->blkbits;
2036 reply = check_command(common, 10, DATA_DIR_TO_HOST, 2043 reply = check_command(common, 10, DATA_DIR_TO_HOST,
2037 (1<<1) | (0xf<<2) | (3<<7), 1, 2044 (1<<1) | (0xf<<2) | (3<<7), 1,
2038 "READ(10)"); 2045 "READ(10)");
@@ -2042,7 +2049,8 @@ static int do_scsi_command(struct fsg_common *common)
2042 2049
2043 case READ_12: 2050 case READ_12:
2044 common->data_size_from_cmnd = 2051 common->data_size_from_cmnd =
2045 get_unaligned_be32(&common->cmnd[6]) << 9; 2052 get_unaligned_be32(&common->cmnd[6]) <<
2053 common->curlun->blkbits;
2046 reply = check_command(common, 12, DATA_DIR_TO_HOST, 2054 reply = check_command(common, 12, DATA_DIR_TO_HOST,
2047 (1<<1) | (0xf<<2) | (0xf<<6), 1, 2055 (1<<1) | (0xf<<2) | (0xf<<6), 1,
2048 "READ(12)"); 2056 "READ(12)");
@@ -2142,7 +2150,8 @@ static int do_scsi_command(struct fsg_common *common)
2142 2150
2143 case WRITE_6: 2151 case WRITE_6:
2144 i = common->cmnd[4]; 2152 i = common->cmnd[4];
2145 common->data_size_from_cmnd = (i == 0 ? 256 : i) << 9; 2153 common->data_size_from_cmnd = (i == 0 ? 256 : i) <<
2154 common->curlun->blkbits;
2146 reply = check_command(common, 6, DATA_DIR_FROM_HOST, 2155 reply = check_command(common, 6, DATA_DIR_FROM_HOST,
2147 (7<<1) | (1<<4), 1, 2156 (7<<1) | (1<<4), 1,
2148 "WRITE(6)"); 2157 "WRITE(6)");
@@ -2152,7 +2161,8 @@ static int do_scsi_command(struct fsg_common *common)
2152 2161
2153 case WRITE_10: 2162 case WRITE_10:
2154 common->data_size_from_cmnd = 2163 common->data_size_from_cmnd =
2155 get_unaligned_be16(&common->cmnd[7]) << 9; 2164 get_unaligned_be16(&common->cmnd[7]) <<
2165 common->curlun->blkbits;
2156 reply = check_command(common, 10, DATA_DIR_FROM_HOST, 2166 reply = check_command(common, 10, DATA_DIR_FROM_HOST,
2157 (1<<1) | (0xf<<2) | (3<<7), 1, 2167 (1<<1) | (0xf<<2) | (3<<7), 1,
2158 "WRITE(10)"); 2168 "WRITE(10)");
@@ -2162,7 +2172,8 @@ static int do_scsi_command(struct fsg_common *common)
2162 2172
2163 case WRITE_12: 2173 case WRITE_12:
2164 common->data_size_from_cmnd = 2174 common->data_size_from_cmnd =
2165 get_unaligned_be32(&common->cmnd[6]) << 9; 2175 get_unaligned_be32(&common->cmnd[6]) <<
2176 common->curlun->blkbits;
2166 reply = check_command(common, 12, DATA_DIR_FROM_HOST, 2177 reply = check_command(common, 12, DATA_DIR_FROM_HOST,
2167 (1<<1) | (0xf<<2) | (0xf<<6), 1, 2178 (1<<1) | (0xf<<2) | (0xf<<6), 1,
2168 "WRITE(12)"); 2179 "WRITE(12)");
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index 39ece40a045f..59d97750cecd 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -69,8 +69,7 @@
69 * each LUN would be settable independently as a disk drive or a CD-ROM 69 * each LUN would be settable independently as a disk drive or a CD-ROM
70 * drive, but currently all LUNs have to be the same type. The CD-ROM 70 * drive, but currently all LUNs have to be the same type. The CD-ROM
71 * emulation includes a single data track and no audio tracks; hence there 71 * emulation includes a single data track and no audio tracks; hence there
72 * need be only one backing file per LUN. Note also that the CD-ROM block 72 * need be only one backing file per LUN.
73 * length is set to 512 rather than the more common value 2048.
74 * 73 *
75 * Requirements are modest; only a bulk-in and a bulk-out endpoint are 74 * Requirements are modest; only a bulk-in and a bulk-out endpoint are
76 * needed (an interrupt-out endpoint is also needed for CBI). The memory 75 * needed (an interrupt-out endpoint is also needed for CBI). The memory
@@ -1158,7 +1157,7 @@ static int do_read(struct fsg_dev *fsg)
1158 curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; 1157 curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
1159 return -EINVAL; 1158 return -EINVAL;
1160 } 1159 }
1161 file_offset = ((loff_t) lba) << 9; 1160 file_offset = ((loff_t) lba) << curlun->blkbits;
1162 1161
1163 /* Carry out the file reads */ 1162 /* Carry out the file reads */
1164 amount_left = fsg->data_size_from_cmnd; 1163 amount_left = fsg->data_size_from_cmnd;
@@ -1196,7 +1195,7 @@ static int do_read(struct fsg_dev *fsg)
1196 if (amount == 0) { 1195 if (amount == 0) {
1197 curlun->sense_data = 1196 curlun->sense_data =
1198 SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; 1197 SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
1199 curlun->sense_data_info = file_offset >> 9; 1198 curlun->sense_data_info = file_offset >> curlun->blkbits;
1200 curlun->info_valid = 1; 1199 curlun->info_valid = 1;
1201 bh->inreq->length = 0; 1200 bh->inreq->length = 0;
1202 bh->state = BUF_STATE_FULL; 1201 bh->state = BUF_STATE_FULL;
@@ -1221,7 +1220,7 @@ static int do_read(struct fsg_dev *fsg)
1221 } else if (nread < amount) { 1220 } else if (nread < amount) {
1222 LDBG(curlun, "partial file read: %d/%u\n", 1221 LDBG(curlun, "partial file read: %d/%u\n",
1223 (int) nread, amount); 1222 (int) nread, amount);
1224 nread -= (nread & 511); // Round down to a block 1223 nread = round_down(nread, curlun->blksize);
1225 } 1224 }
1226 file_offset += nread; 1225 file_offset += nread;
1227 amount_left -= nread; 1226 amount_left -= nread;
@@ -1232,7 +1231,7 @@ static int do_read(struct fsg_dev *fsg)
1232 /* If an error occurred, report it and its position */ 1231 /* If an error occurred, report it and its position */
1233 if (nread < amount) { 1232 if (nread < amount) {
1234 curlun->sense_data = SS_UNRECOVERED_READ_ERROR; 1233 curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
1235 curlun->sense_data_info = file_offset >> 9; 1234 curlun->sense_data_info = file_offset >> curlun->blkbits;
1236 curlun->info_valid = 1; 1235 curlun->info_valid = 1;
1237 break; 1236 break;
1238 } 1237 }
@@ -1303,7 +1302,7 @@ static int do_write(struct fsg_dev *fsg)
1303 1302
1304 /* Carry out the file writes */ 1303 /* Carry out the file writes */
1305 get_some_more = 1; 1304 get_some_more = 1;
1306 file_offset = usb_offset = ((loff_t) lba) << 9; 1305 file_offset = usb_offset = ((loff_t) lba) << curlun->blkbits;
1307 amount_left_to_req = amount_left_to_write = fsg->data_size_from_cmnd; 1306 amount_left_to_req = amount_left_to_write = fsg->data_size_from_cmnd;
1308 1307
1309 while (amount_left_to_write > 0) { 1308 while (amount_left_to_write > 0) {
@@ -1333,11 +1332,11 @@ static int do_write(struct fsg_dev *fsg)
1333 get_some_more = 0; 1332 get_some_more = 0;
1334 curlun->sense_data = 1333 curlun->sense_data =
1335 SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; 1334 SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
1336 curlun->sense_data_info = usb_offset >> 9; 1335 curlun->sense_data_info = usb_offset >> curlun->blkbits;
1337 curlun->info_valid = 1; 1336 curlun->info_valid = 1;
1338 continue; 1337 continue;
1339 } 1338 }
1340 amount -= (amount & 511); 1339 amount = round_down(amount, curlun->blksize);
1341 if (amount == 0) { 1340 if (amount == 0) {
1342 1341
1343 /* Why were we were asked to transfer a 1342 /* Why were we were asked to transfer a
@@ -1376,7 +1375,7 @@ static int do_write(struct fsg_dev *fsg)
1376 /* Did something go wrong with the transfer? */ 1375 /* Did something go wrong with the transfer? */
1377 if (bh->outreq->status != 0) { 1376 if (bh->outreq->status != 0) {
1378 curlun->sense_data = SS_COMMUNICATION_FAILURE; 1377 curlun->sense_data = SS_COMMUNICATION_FAILURE;
1379 curlun->sense_data_info = file_offset >> 9; 1378 curlun->sense_data_info = file_offset >> curlun->blkbits;
1380 curlun->info_valid = 1; 1379 curlun->info_valid = 1;
1381 break; 1380 break;
1382 } 1381 }
@@ -1408,8 +1407,7 @@ static int do_write(struct fsg_dev *fsg)
1408 } else if (nwritten < amount) { 1407 } else if (nwritten < amount) {
1409 LDBG(curlun, "partial file write: %d/%u\n", 1408 LDBG(curlun, "partial file write: %d/%u\n",
1410 (int) nwritten, amount); 1409 (int) nwritten, amount);
1411 nwritten -= (nwritten & 511); 1410 nwritten = round_down(nwritten, curlun->blksize);
1412 // Round down to a block
1413 } 1411 }
1414 file_offset += nwritten; 1412 file_offset += nwritten;
1415 amount_left_to_write -= nwritten; 1413 amount_left_to_write -= nwritten;
@@ -1418,7 +1416,7 @@ static int do_write(struct fsg_dev *fsg)
1418 /* If an error occurred, report it and its position */ 1416 /* If an error occurred, report it and its position */
1419 if (nwritten < amount) { 1417 if (nwritten < amount) {
1420 curlun->sense_data = SS_WRITE_ERROR; 1418 curlun->sense_data = SS_WRITE_ERROR;
1421 curlun->sense_data_info = file_offset >> 9; 1419 curlun->sense_data_info = file_offset >> curlun->blkbits;
1422 curlun->info_valid = 1; 1420 curlun->info_valid = 1;
1423 break; 1421 break;
1424 } 1422 }
@@ -1500,8 +1498,8 @@ static int do_verify(struct fsg_dev *fsg)
1500 return -EIO; // No default reply 1498 return -EIO; // No default reply
1501 1499
1502 /* Prepare to carry out the file verify */ 1500 /* Prepare to carry out the file verify */
1503 amount_left = verification_length << 9; 1501 amount_left = verification_length << curlun->blkbits;
1504 file_offset = ((loff_t) lba) << 9; 1502 file_offset = ((loff_t) lba) << curlun->blkbits;
1505 1503
1506 /* Write out all the dirty buffers before invalidating them */ 1504 /* Write out all the dirty buffers before invalidating them */
1507 fsg_lun_fsync_sub(curlun); 1505 fsg_lun_fsync_sub(curlun);
@@ -1527,7 +1525,7 @@ static int do_verify(struct fsg_dev *fsg)
1527 if (amount == 0) { 1525 if (amount == 0) {
1528 curlun->sense_data = 1526 curlun->sense_data =
1529 SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; 1527 SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
1530 curlun->sense_data_info = file_offset >> 9; 1528 curlun->sense_data_info = file_offset >> curlun->blkbits;
1531 curlun->info_valid = 1; 1529 curlun->info_valid = 1;
1532 break; 1530 break;
1533 } 1531 }
@@ -1550,11 +1548,11 @@ static int do_verify(struct fsg_dev *fsg)
1550 } else if (nread < amount) { 1548 } else if (nread < amount) {
1551 LDBG(curlun, "partial file verify: %d/%u\n", 1549 LDBG(curlun, "partial file verify: %d/%u\n",
1552 (int) nread, amount); 1550 (int) nread, amount);
1553 nread -= (nread & 511); // Round down to a sector 1551 nread = round_down(nread, curlun->blksize);
1554 } 1552 }
1555 if (nread == 0) { 1553 if (nread == 0) {
1556 curlun->sense_data = SS_UNRECOVERED_READ_ERROR; 1554 curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
1557 curlun->sense_data_info = file_offset >> 9; 1555 curlun->sense_data_info = file_offset >> curlun->blkbits;
1558 curlun->info_valid = 1; 1556 curlun->info_valid = 1;
1559 break; 1557 break;
1560 } 1558 }
@@ -1668,7 +1666,7 @@ static int do_read_capacity(struct fsg_dev *fsg, struct fsg_buffhd *bh)
1668 1666
1669 put_unaligned_be32(curlun->num_sectors - 1, &buf[0]); 1667 put_unaligned_be32(curlun->num_sectors - 1, &buf[0]);
1670 /* Max logical block */ 1668 /* Max logical block */
1671 put_unaligned_be32(512, &buf[4]); /* Block length */ 1669 put_unaligned_be32(curlun->blksize, &buf[4]); /* Block length */
1672 return 8; 1670 return 8;
1673} 1671}
1674 1672
@@ -1890,7 +1888,7 @@ static int do_read_format_capacities(struct fsg_dev *fsg,
1890 1888
1891 put_unaligned_be32(curlun->num_sectors, &buf[0]); 1889 put_unaligned_be32(curlun->num_sectors, &buf[0]);
1892 /* Number of blocks */ 1890 /* Number of blocks */
1893 put_unaligned_be32(512, &buf[4]); /* Block length */ 1891 put_unaligned_be32(curlun->blksize, &buf[4]); /* Block length */
1894 buf[4] = 0x02; /* Current capacity */ 1892 buf[4] = 0x02; /* Current capacity */
1895 return 12; 1893 return 12;
1896} 1894}
@@ -2415,7 +2413,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
2415 2413
2416 case READ_6: 2414 case READ_6:
2417 i = fsg->cmnd[4]; 2415 i = fsg->cmnd[4];
2418 fsg->data_size_from_cmnd = (i == 0 ? 256 : i) << 9; 2416 fsg->data_size_from_cmnd = (i == 0 ? 256 : i) << fsg->curlun->blkbits;
2419 if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST, 2417 if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST,
2420 (7<<1) | (1<<4), 1, 2418 (7<<1) | (1<<4), 1,
2421 "READ(6)")) == 0) 2419 "READ(6)")) == 0)
@@ -2424,7 +2422,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
2424 2422
2425 case READ_10: 2423 case READ_10:
2426 fsg->data_size_from_cmnd = 2424 fsg->data_size_from_cmnd =
2427 get_unaligned_be16(&fsg->cmnd[7]) << 9; 2425 get_unaligned_be16(&fsg->cmnd[7]) << fsg->curlun->blkbits;
2428 if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, 2426 if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST,
2429 (1<<1) | (0xf<<2) | (3<<7), 1, 2427 (1<<1) | (0xf<<2) | (3<<7), 1,
2430 "READ(10)")) == 0) 2428 "READ(10)")) == 0)
@@ -2433,7 +2431,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
2433 2431
2434 case READ_12: 2432 case READ_12:
2435 fsg->data_size_from_cmnd = 2433 fsg->data_size_from_cmnd =
2436 get_unaligned_be32(&fsg->cmnd[6]) << 9; 2434 get_unaligned_be32(&fsg->cmnd[6]) << fsg->curlun->blkbits;
2437 if ((reply = check_command(fsg, 12, DATA_DIR_TO_HOST, 2435 if ((reply = check_command(fsg, 12, DATA_DIR_TO_HOST,
2438 (1<<1) | (0xf<<2) | (0xf<<6), 1, 2436 (1<<1) | (0xf<<2) | (0xf<<6), 1,
2439 "READ(12)")) == 0) 2437 "READ(12)")) == 0)
@@ -2519,7 +2517,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
2519 2517
2520 case WRITE_6: 2518 case WRITE_6:
2521 i = fsg->cmnd[4]; 2519 i = fsg->cmnd[4];
2522 fsg->data_size_from_cmnd = (i == 0 ? 256 : i) << 9; 2520 fsg->data_size_from_cmnd = (i == 0 ? 256 : i) << fsg->curlun->blkbits;
2523 if ((reply = check_command(fsg, 6, DATA_DIR_FROM_HOST, 2521 if ((reply = check_command(fsg, 6, DATA_DIR_FROM_HOST,
2524 (7<<1) | (1<<4), 1, 2522 (7<<1) | (1<<4), 1,
2525 "WRITE(6)")) == 0) 2523 "WRITE(6)")) == 0)
@@ -2528,7 +2526,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
2528 2526
2529 case WRITE_10: 2527 case WRITE_10:
2530 fsg->data_size_from_cmnd = 2528 fsg->data_size_from_cmnd =
2531 get_unaligned_be16(&fsg->cmnd[7]) << 9; 2529 get_unaligned_be16(&fsg->cmnd[7]) << fsg->curlun->blkbits;
2532 if ((reply = check_command(fsg, 10, DATA_DIR_FROM_HOST, 2530 if ((reply = check_command(fsg, 10, DATA_DIR_FROM_HOST,
2533 (1<<1) | (0xf<<2) | (3<<7), 1, 2531 (1<<1) | (0xf<<2) | (3<<7), 1,
2534 "WRITE(10)")) == 0) 2532 "WRITE(10)")) == 0)
@@ -2537,7 +2535,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
2537 2535
2538 case WRITE_12: 2536 case WRITE_12:
2539 fsg->data_size_from_cmnd = 2537 fsg->data_size_from_cmnd =
2540 get_unaligned_be32(&fsg->cmnd[6]) << 9; 2538 get_unaligned_be32(&fsg->cmnd[6]) << fsg->curlun->blkbits;
2541 if ((reply = check_command(fsg, 12, DATA_DIR_FROM_HOST, 2539 if ((reply = check_command(fsg, 12, DATA_DIR_FROM_HOST,
2542 (1<<1) | (0xf<<2) | (0xf<<6), 1, 2540 (1<<1) | (0xf<<2) | (0xf<<6), 1,
2543 "WRITE(12)")) == 0) 2541 "WRITE(12)")) == 0)
diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c
index d3dd227a2bfc..3ea70d8549ef 100644
--- a/drivers/usb/gadget/storage_common.c
+++ b/drivers/usb/gadget/storage_common.c
@@ -247,6 +247,8 @@ struct fsg_lun {
247 u32 sense_data_info; 247 u32 sense_data_info;
248 u32 unit_attention_data; 248 u32 unit_attention_data;
249 249
250 unsigned int blkbits; /* Bits of logical block size of bound block device */
251 unsigned int blksize; /* logical block size of bound block device */
250 struct device dev; 252 struct device dev;
251}; 253};
252 254
@@ -580,13 +582,24 @@ static int fsg_lun_open(struct fsg_lun *curlun, const char *filename)
580 rc = (int) size; 582 rc = (int) size;
581 goto out; 583 goto out;
582 } 584 }
583 num_sectors = size >> 9; /* File size in 512-byte blocks */ 585
586 if (curlun->cdrom) {
587 curlun->blksize = 2048;
588 curlun->blkbits = 11;
589 } else if (inode->i_bdev) {
590 curlun->blksize = bdev_logical_block_size(inode->i_bdev);
591 curlun->blkbits = blksize_bits(curlun->blksize);
592 } else {
593 curlun->blksize = 512;
594 curlun->blkbits = 9;
595 }
596
597 num_sectors = size >> curlun->blkbits; /* File size in logic-block-size blocks */
584 min_sectors = 1; 598 min_sectors = 1;
585 if (curlun->cdrom) { 599 if (curlun->cdrom) {
586 num_sectors &= ~3; /* Reduce to a multiple of 2048 */ 600 min_sectors = 300; /* Smallest track is 300 frames */
587 min_sectors = 300*4; /* Smallest track is 300 frames */ 601 if (num_sectors >= 256*60*75) {
588 if (num_sectors >= 256*60*75*4) { 602 num_sectors = 256*60*75 - 1;
589 num_sectors = (256*60*75 - 1) * 4;
590 LINFO(curlun, "file too big: %s\n", filename); 603 LINFO(curlun, "file too big: %s\n", filename);
591 LINFO(curlun, "using only first %d blocks\n", 604 LINFO(curlun, "using only first %d blocks\n",
592 (int) num_sectors); 605 (int) num_sectors);