aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Zimmerman <Paul.Zimmerman@synopsys.com>2011-09-30 18:26:06 -0400
committerFelipe Balbi <balbi@ti.com>2011-10-13 13:39:52 -0400
commitfe69676530f182bbb1fe0edd027e18751a1a2595 (patch)
treed509a1b7ba5f147909cfb9f379996644249db74b
parentc8933c3f79568263c90a46f06cf80419e6c63c97 (diff)
usb: gadget: storage: fix mass storage gadgets to work with Synopsys UDC
The Synopsys USB device controller requires all OUT transfer request lengths to be aligned to max packet size. The mass storage gadgets do not meet this requirement for Super Speed. The gadgets already have a function which performs this alignment for CBW packets, so use it for data packets too. The alternative would be to implement bounce buffers in the DWC3 driver, but that could have a significant impact on performance. This version is based upon a more-correct patch written by Alan Stern. Signed-off-by: Paul Zimmerman <paulz@synopsys.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
-rw-r--r--drivers/usb/gadget/f_mass_storage.c18
-rw-r--r--drivers/usb/gadget/file_storage.c18
2 files changed, 18 insertions, 18 deletions
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index 756941473148..927ee88278bd 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -958,9 +958,7 @@ static int do_write(struct fsg_common *common)
958 * equal to the buffer size, which is divisible by 958 * equal to the buffer size, which is divisible by
959 * the bulk-out maxpacket size. 959 * the bulk-out maxpacket size.
960 */ 960 */
961 bh->outreq->length = amount; 961 set_bulk_out_req_length(common, bh, amount);
962 bh->bulk_out_intended_length = amount;
963 bh->outreq->short_not_ok = 1;
964 if (!start_out_transfer(common, bh)) 962 if (!start_out_transfer(common, bh))
965 /* Dunno what to do if common->fsg is NULL */ 963 /* Dunno what to do if common->fsg is NULL */
966 return -EIO; 964 return -EIO;
@@ -995,6 +993,11 @@ static int do_write(struct fsg_common *common)
995 amount = curlun->file_length - file_offset; 993 amount = curlun->file_length - file_offset;
996 } 994 }
997 995
996 /* Don't accept excess data. The spec doesn't say
997 * what to do in this case. We'll ignore the error.
998 */
999 amount = min(amount, bh->bulk_out_intended_length);
1000
998 /* Don't write a partial block */ 1001 /* Don't write a partial block */
999 amount = round_down(amount, curlun->blksize); 1002 amount = round_down(amount, curlun->blksize);
1000 if (amount == 0) 1003 if (amount == 0)
@@ -1034,7 +1037,7 @@ static int do_write(struct fsg_common *common)
1034 1037
1035 empty_write: 1038 empty_write:
1036 /* Did the host decide to stop early? */ 1039 /* Did the host decide to stop early? */
1037 if (bh->outreq->actual != bh->outreq->length) { 1040 if (bh->outreq->actual < bh->bulk_out_intended_length) {
1038 common->short_packet_received = 1; 1041 common->short_packet_received = 1;
1039 break; 1042 break;
1040 } 1043 }
@@ -1592,7 +1595,7 @@ static int throw_away_data(struct fsg_common *common)
1592 common->next_buffhd_to_drain = bh->next; 1595 common->next_buffhd_to_drain = bh->next;
1593 1596
1594 /* A short packet or an error ends everything */ 1597 /* A short packet or an error ends everything */
1595 if (bh->outreq->actual != bh->outreq->length || 1598 if (bh->outreq->actual < bh->bulk_out_intended_length ||
1596 bh->outreq->status != 0) { 1599 bh->outreq->status != 0) {
1597 raise_exception(common, 1600 raise_exception(common,
1598 FSG_STATE_ABORT_BULK_OUT); 1601 FSG_STATE_ABORT_BULK_OUT);
@@ -1612,9 +1615,7 @@ static int throw_away_data(struct fsg_common *common)
1612 * equal to the buffer size, which is divisible by 1615 * equal to the buffer size, which is divisible by
1613 * the bulk-out maxpacket size. 1616 * the bulk-out maxpacket size.
1614 */ 1617 */
1615 bh->outreq->length = amount; 1618 set_bulk_out_req_length(common, bh, amount);
1616 bh->bulk_out_intended_length = amount;
1617 bh->outreq->short_not_ok = 1;
1618 if (!start_out_transfer(common, bh)) 1619 if (!start_out_transfer(common, bh))
1619 /* Dunno what to do if common->fsg is NULL */ 1620 /* Dunno what to do if common->fsg is NULL */
1620 return -EIO; 1621 return -EIO;
@@ -2289,7 +2290,6 @@ static int get_next_command(struct fsg_common *common)
2289 2290
2290 /* Queue a request to read a Bulk-only CBW */ 2291 /* Queue a request to read a Bulk-only CBW */
2291 set_bulk_out_req_length(common, bh, USB_BULK_CB_WRAP_LEN); 2292 set_bulk_out_req_length(common, bh, USB_BULK_CB_WRAP_LEN);
2292 bh->outreq->short_not_ok = 1;
2293 if (!start_out_transfer(common, bh)) 2293 if (!start_out_transfer(common, bh))
2294 /* Don't know what to do if common->fsg is NULL */ 2294 /* Don't know what to do if common->fsg is NULL */
2295 return -EIO; 2295 return -EIO;
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index 12ac30b21ba6..a230009db734 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -1335,9 +1335,7 @@ static int do_write(struct fsg_dev *fsg)
1335 * equal to the buffer size, which is divisible by 1335 * equal to the buffer size, which is divisible by
1336 * the bulk-out maxpacket size. 1336 * the bulk-out maxpacket size.
1337 */ 1337 */
1338 bh->outreq->length = bh->bulk_out_intended_length = 1338 set_bulk_out_req_length(fsg, bh, amount);
1339 amount;
1340 bh->outreq->short_not_ok = 1;
1341 start_transfer(fsg, fsg->bulk_out, bh->outreq, 1339 start_transfer(fsg, fsg->bulk_out, bh->outreq,
1342 &bh->outreq_busy, &bh->state); 1340 &bh->outreq_busy, &bh->state);
1343 fsg->next_buffhd_to_fill = bh->next; 1341 fsg->next_buffhd_to_fill = bh->next;
@@ -1370,6 +1368,11 @@ static int do_write(struct fsg_dev *fsg)
1370 amount = curlun->file_length - file_offset; 1368 amount = curlun->file_length - file_offset;
1371 } 1369 }
1372 1370
1371 /* Don't accept excess data. The spec doesn't say
1372 * what to do in this case. We'll ignore the error.
1373 */
1374 amount = min(amount, bh->bulk_out_intended_length);
1375
1373 /* Don't write a partial block */ 1376 /* Don't write a partial block */
1374 amount = round_down(amount, curlun->blksize); 1377 amount = round_down(amount, curlun->blksize);
1375 if (amount == 0) 1378 if (amount == 0)
@@ -1409,7 +1412,7 @@ static int do_write(struct fsg_dev *fsg)
1409 1412
1410 empty_write: 1413 empty_write:
1411 /* Did the host decide to stop early? */ 1414 /* Did the host decide to stop early? */
1412 if (bh->outreq->actual != bh->outreq->length) { 1415 if (bh->outreq->actual < bh->bulk_out_intended_length) {
1413 fsg->short_packet_received = 1; 1416 fsg->short_packet_received = 1;
1414 break; 1417 break;
1415 } 1418 }
@@ -1953,7 +1956,7 @@ static int throw_away_data(struct fsg_dev *fsg)
1953 fsg->next_buffhd_to_drain = bh->next; 1956 fsg->next_buffhd_to_drain = bh->next;
1954 1957
1955 /* A short packet or an error ends everything */ 1958 /* A short packet or an error ends everything */
1956 if (bh->outreq->actual != bh->outreq->length || 1959 if (bh->outreq->actual < bh->bulk_out_intended_length ||
1957 bh->outreq->status != 0) { 1960 bh->outreq->status != 0) {
1958 raise_exception(fsg, FSG_STATE_ABORT_BULK_OUT); 1961 raise_exception(fsg, FSG_STATE_ABORT_BULK_OUT);
1959 return -EINTR; 1962 return -EINTR;
@@ -1971,9 +1974,7 @@ static int throw_away_data(struct fsg_dev *fsg)
1971 * equal to the buffer size, which is divisible by 1974 * equal to the buffer size, which is divisible by
1972 * the bulk-out maxpacket size. 1975 * the bulk-out maxpacket size.
1973 */ 1976 */
1974 bh->outreq->length = bh->bulk_out_intended_length = 1977 set_bulk_out_req_length(fsg, bh, amount);
1975 amount;
1976 bh->outreq->short_not_ok = 1;
1977 start_transfer(fsg, fsg->bulk_out, bh->outreq, 1978 start_transfer(fsg, fsg->bulk_out, bh->outreq,
1978 &bh->outreq_busy, &bh->state); 1979 &bh->outreq_busy, &bh->state);
1979 fsg->next_buffhd_to_fill = bh->next; 1980 fsg->next_buffhd_to_fill = bh->next;
@@ -2652,7 +2653,6 @@ static int get_next_command(struct fsg_dev *fsg)
2652 2653
2653 /* Queue a request to read a Bulk-only CBW */ 2654 /* Queue a request to read a Bulk-only CBW */
2654 set_bulk_out_req_length(fsg, bh, USB_BULK_CB_WRAP_LEN); 2655 set_bulk_out_req_length(fsg, bh, USB_BULK_CB_WRAP_LEN);
2655 bh->outreq->short_not_ok = 1;
2656 start_transfer(fsg, fsg->bulk_out, bh->outreq, 2656 start_transfer(fsg, fsg->bulk_out, bh->outreq,
2657 &bh->outreq_busy, &bh->state); 2657 &bh->outreq_busy, &bh->state);
2658 2658