aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/file_storage.c
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2011-08-18 14:29:00 -0400
committerFelipe Balbi <balbi@ti.com>2011-09-09 06:06:03 -0400
commit04eee25b1d754a837360504b7af426d1f86ffeb7 (patch)
treedbfc8c0087143db8f039c4e41887c21a3f52233f /drivers/usb/gadget/file_storage.c
parent3f565a363cee14d2ed281823196d455bfc7c4170 (diff)
USB: gadget: storage: remove alignment assumption
This patch (as1481) fixes a problem affecting g_file_storage and g_mass_storage when running at SuperSpeed. The two drivers currently assume that the bulk-out maxpacket size can evenly divide the SCSI block size, which is 512 bytes. But SuperSpeed bulk endpoints have a maxpacket size of 1024, so the assumption is no longer true. This patch removes that assumption from the drivers, by getting rid of a small optimization (they try to align VFS reads and writes on page cache boundaries). If a command's starting logical block address is 512 bytes below the end of a page, it's not okay to issue a USB command for just those 512 bytes when the maxpacket size is 1024 -- it would result in either babble (for an OUT transfer) or a short packet (for an IN transfer). Also, for backward compatibility, the test for writes extending beyond the end of the backing storage has to be changed. If the host tries to do this, we should accept the data that fits in the backing storage and ignore the rest. Because the storage's end may not align with a USB packet boundary, this means we may have to accept a USB OUT transfer that extends beyond the end of the storage and then write out only the part of the data that fits. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Acked-by: Michal Nazarewicz <mina86@mina86.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/gadget/file_storage.c')
-rw-r--r--drivers/usb/gadget/file_storage.c67
1 files changed, 27 insertions, 40 deletions
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index 59d97750cecd..c6f96a2b3110 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -1135,7 +1135,6 @@ static int do_read(struct fsg_dev *fsg)
1135 u32 amount_left; 1135 u32 amount_left;
1136 loff_t file_offset, file_offset_tmp; 1136 loff_t file_offset, file_offset_tmp;
1137 unsigned int amount; 1137 unsigned int amount;
1138 unsigned int partial_page;
1139 ssize_t nread; 1138 ssize_t nread;
1140 1139
1141 /* Get the starting Logical Block Address and check that it's 1140 /* Get the starting Logical Block Address and check that it's
@@ -1170,17 +1169,10 @@ static int do_read(struct fsg_dev *fsg)
1170 * Try to read the remaining amount. 1169 * Try to read the remaining amount.
1171 * But don't read more than the buffer size. 1170 * But don't read more than the buffer size.
1172 * And don't try to read past the end of the file. 1171 * And don't try to read past the end of the file.
1173 * Finally, if we're not at a page boundary, don't read past 1172 */
1174 * the next page.
1175 * If this means reading 0 then we were asked to read past
1176 * the end of file. */
1177 amount = min((unsigned int) amount_left, mod_data.buflen); 1173 amount = min((unsigned int) amount_left, mod_data.buflen);
1178 amount = min((loff_t) amount, 1174 amount = min((loff_t) amount,
1179 curlun->file_length - file_offset); 1175 curlun->file_length - file_offset);
1180 partial_page = file_offset & (PAGE_CACHE_SIZE - 1);
1181 if (partial_page > 0)
1182 amount = min(amount, (unsigned int) PAGE_CACHE_SIZE -
1183 partial_page);
1184 1176
1185 /* Wait for the next buffer to become available */ 1177 /* Wait for the next buffer to become available */
1186 bh = fsg->next_buffhd_to_fill; 1178 bh = fsg->next_buffhd_to_fill;
@@ -1225,6 +1217,11 @@ static int do_read(struct fsg_dev *fsg)
1225 file_offset += nread; 1217 file_offset += nread;
1226 amount_left -= nread; 1218 amount_left -= nread;
1227 fsg->residue -= nread; 1219 fsg->residue -= nread;
1220
1221 /* Except at the end of the transfer, nread will be
1222 * equal to the buffer size, which is divisible by the
1223 * bulk-in maxpacket size.
1224 */
1228 bh->inreq->length = nread; 1225 bh->inreq->length = nread;
1229 bh->state = BUF_STATE_FULL; 1226 bh->state = BUF_STATE_FULL;
1230 1227
@@ -1261,7 +1258,6 @@ static int do_write(struct fsg_dev *fsg)
1261 u32 amount_left_to_req, amount_left_to_write; 1258 u32 amount_left_to_req, amount_left_to_write;
1262 loff_t usb_offset, file_offset, file_offset_tmp; 1259 loff_t usb_offset, file_offset, file_offset_tmp;
1263 unsigned int amount; 1260 unsigned int amount;
1264 unsigned int partial_page;
1265 ssize_t nwritten; 1261 ssize_t nwritten;
1266 int rc; 1262 int rc;
1267 1263
@@ -1312,23 +1308,13 @@ static int do_write(struct fsg_dev *fsg)
1312 if (bh->state == BUF_STATE_EMPTY && get_some_more) { 1308 if (bh->state == BUF_STATE_EMPTY && get_some_more) {
1313 1309
1314 /* Figure out how much we want to get: 1310 /* Figure out how much we want to get:
1315 * Try to get the remaining amount. 1311 * Try to get the remaining amount,
1316 * But don't get more than the buffer size. 1312 * but not more than the buffer size.
1317 * And don't try to go past the end of the file. 1313 */
1318 * If we're not at a page boundary,
1319 * don't go past the next page.
1320 * If this means getting 0, then we were asked
1321 * to write past the end of file.
1322 * Finally, round down to a block boundary. */
1323 amount = min(amount_left_to_req, mod_data.buflen); 1314 amount = min(amount_left_to_req, mod_data.buflen);
1324 amount = min((loff_t) amount, curlun->file_length - 1315
1325 usb_offset); 1316 /* Beyond the end of the backing file? */
1326 partial_page = usb_offset & (PAGE_CACHE_SIZE - 1); 1317 if (usb_offset >= curlun->file_length) {
1327 if (partial_page > 0)
1328 amount = min(amount,
1329 (unsigned int) PAGE_CACHE_SIZE - partial_page);
1330
1331 if (amount == 0) {
1332 get_some_more = 0; 1318 get_some_more = 0;
1333 curlun->sense_data = 1319 curlun->sense_data =
1334 SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; 1320 SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
@@ -1336,14 +1322,6 @@ static int do_write(struct fsg_dev *fsg)
1336 curlun->info_valid = 1; 1322 curlun->info_valid = 1;
1337 continue; 1323 continue;
1338 } 1324 }
1339 amount = round_down(amount, curlun->blksize);
1340 if (amount == 0) {
1341
1342 /* Why were we were asked to transfer a
1343 * partial block? */
1344 get_some_more = 0;
1345 continue;
1346 }
1347 1325
1348 /* Get the next buffer */ 1326 /* Get the next buffer */
1349 usb_offset += amount; 1327 usb_offset += amount;
@@ -1352,8 +1330,10 @@ static int do_write(struct fsg_dev *fsg)
1352 if (amount_left_to_req == 0) 1330 if (amount_left_to_req == 0)
1353 get_some_more = 0; 1331 get_some_more = 0;
1354 1332
1355 /* amount is always divisible by 512, hence by 1333 /* Except at the end of the transfer, amount will be
1356 * the bulk-out maxpacket size */ 1334 * equal to the buffer size, which is divisible by
1335 * the bulk-out maxpacket size.
1336 */
1357 bh->outreq->length = bh->bulk_out_intended_length = 1337 bh->outreq->length = bh->bulk_out_intended_length =
1358 amount; 1338 amount;
1359 bh->outreq->short_not_ok = 1; 1339 bh->outreq->short_not_ok = 1;
@@ -1389,6 +1369,11 @@ static int do_write(struct fsg_dev *fsg)
1389 amount = curlun->file_length - file_offset; 1369 amount = curlun->file_length - file_offset;
1390 } 1370 }
1391 1371
1372 /* Don't write a partial block */
1373 amount = round_down(amount, curlun->blksize);
1374 if (amount == 0)
1375 goto empty_write;
1376
1392 /* Perform the write */ 1377 /* Perform the write */
1393 file_offset_tmp = file_offset; 1378 file_offset_tmp = file_offset;
1394 nwritten = vfs_write(curlun->filp, 1379 nwritten = vfs_write(curlun->filp,
@@ -1421,6 +1406,7 @@ static int do_write(struct fsg_dev *fsg)
1421 break; 1406 break;
1422 } 1407 }
1423 1408
1409 empty_write:
1424 /* Did the host decide to stop early? */ 1410 /* Did the host decide to stop early? */
1425 if (bh->outreq->actual != bh->outreq->length) { 1411 if (bh->outreq->actual != bh->outreq->length) {
1426 fsg->short_packet_received = 1; 1412 fsg->short_packet_received = 1;
@@ -1517,8 +1503,7 @@ static int do_verify(struct fsg_dev *fsg)
1517 * Try to read the remaining amount, but not more than 1503 * Try to read the remaining amount, but not more than
1518 * the buffer size. 1504 * the buffer size.
1519 * And don't try to read past the end of the file. 1505 * And don't try to read past the end of the file.
1520 * If this means reading 0 then we were asked to read 1506 */
1521 * past the end of file. */
1522 amount = min((unsigned int) amount_left, mod_data.buflen); 1507 amount = min((unsigned int) amount_left, mod_data.buflen);
1523 amount = min((loff_t) amount, 1508 amount = min((loff_t) amount,
1524 curlun->file_length - file_offset); 1509 curlun->file_length - file_offset);
@@ -1981,8 +1966,10 @@ static int throw_away_data(struct fsg_dev *fsg)
1981 amount = min(fsg->usb_amount_left, 1966 amount = min(fsg->usb_amount_left,
1982 (u32) mod_data.buflen); 1967 (u32) mod_data.buflen);
1983 1968
1984 /* amount is always divisible by 512, hence by 1969 /* Except at the end of the transfer, amount will be
1985 * the bulk-out maxpacket size */ 1970 * equal to the buffer size, which is divisible by
1971 * the bulk-out maxpacket size.
1972 */
1986 bh->outreq->length = bh->bulk_out_intended_length = 1973 bh->outreq->length = bh->bulk_out_intended_length =
1987 amount; 1974 amount;
1988 bh->outreq->short_not_ok = 1; 1975 bh->outreq->short_not_ok = 1;