summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/gadget/f_mass_storage.c24
-rw-r--r--drivers/usb/gadget/file_storage.c28
-rw-r--r--drivers/usb/gadget/storage_common.c7
3 files changed, 49 insertions, 10 deletions
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index 7d95a2cf58a3..01ae27b60d4c 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -474,6 +474,20 @@ static int exception_in_progress(struct fsg_common *common)
return common->state > FSG_STATE_IDLE;
}
+/* Make bulk-out requests be divisible by the maxpacket size */
+static void set_bulk_out_req_length(struct fsg_common *common,
+ struct fsg_buffhd *bh, unsigned int length)
+{
+ unsigned int rem;
+
+ bh->bulk_out_intended_length = length;
+ rem = length % common->bulk_out_maxpacket;
+ if (rem > 0)
+ length += common->bulk_out_maxpacket - rem;
+ bh->outreq->length = length;
+}
+
+
/*-------------------------------------------------------------------------*/
static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep)
@@ -572,9 +586,9 @@ static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req)
struct fsg_buffhd *bh = req->context;
dump_msg(common, "bulk-out", req->buf, req->actual);
- if (req->status || req->actual != req->length)
+ if (req->status || req->actual != bh->bulk_out_intended_length)
DBG(common, "%s --> %d, %u/%u\n", __func__,
- req->status, req->actual, req->length);
+ req->status, req->actual, bh->bulk_out_intended_length);
if (req->status == -ECONNRESET) /* Request was cancelled */
usb_ep_fifo_flush(ep);
@@ -966,6 +980,7 @@ static int do_write(struct fsg_common *common)
* the bulk-out maxpacket size
*/
bh->outreq->length = amount;
+ bh->bulk_out_intended_length = amount;
bh->outreq->short_not_ok = 1;
if (!start_out_transfer(common, bh))
/* Dunno what to do if common->fsg is NULL */
@@ -1611,6 +1626,7 @@ static int throw_away_data(struct fsg_common *common)
* the bulk-out maxpacket size.
*/
bh->outreq->length = amount;
+ bh->bulk_out_intended_length = amount;
bh->outreq->short_not_ok = 1;
if (!start_out_transfer(common, bh))
/* Dunno what to do if common->fsg is NULL */
@@ -2279,8 +2295,8 @@ static int get_next_command(struct fsg_common *common)
}
/* Queue a request to read a Bulk-only CBW */
- bh->outreq->length = USB_BULK_CB_WRAP_LEN;
- bh->outreq->short_not_ok = 0;
+ set_bulk_out_req_length(common, bh, USB_BULK_CB_WRAP_LEN);
+ bh->outreq->short_not_ok = 1;
if (!start_out_transfer(common, bh))
/* Don't know what to do if common->fsg is NULL */
return -EIO;
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index aebfb81f3ba4..fcfc77c7ad70 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -497,6 +497,19 @@ static int exception_in_progress(struct fsg_dev *fsg)
return (fsg->state > FSG_STATE_IDLE);
}
+/* Make bulk-out requests be divisible by the maxpacket size */
+static void set_bulk_out_req_length(struct fsg_dev *fsg,
+ struct fsg_buffhd *bh, unsigned int length)
+{
+ unsigned int rem;
+
+ bh->bulk_out_intended_length = length;
+ rem = length % fsg->bulk_out_maxpacket;
+ if (rem > 0)
+ length += fsg->bulk_out_maxpacket - rem;
+ bh->outreq->length = length;
+}
+
static struct fsg_dev *the_fsg;
static struct usb_gadget_driver fsg_driver;
@@ -717,9 +730,10 @@ static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req)
struct fsg_buffhd *bh = req->context;
dump_msg(fsg, "bulk-out", req->buf, req->actual);
- if (req->status || req->actual != req->length)
+ if (req->status || req->actual != bh->bulk_out_intended_length)
DBG(fsg, "%s --> %d, %u/%u\n", __func__,
- req->status, req->actual, req->length);
+ req->status, req->actual,
+ bh->bulk_out_intended_length);
if (req->status == -ECONNRESET) // Request was cancelled
usb_ep_fifo_flush(ep);
@@ -1335,7 +1349,8 @@ static int do_write(struct fsg_dev *fsg)
/* amount is always divisible by 512, hence by
* the bulk-out maxpacket size */
- bh->outreq->length = amount;
+ bh->outreq->length = bh->bulk_out_intended_length =
+ amount;
bh->outreq->short_not_ok = 1;
start_transfer(fsg, fsg->bulk_out, bh->outreq,
&bh->outreq_busy, &bh->state);
@@ -1964,7 +1979,8 @@ static int throw_away_data(struct fsg_dev *fsg)
/* amount is always divisible by 512, hence by
* the bulk-out maxpacket size */
- bh->outreq->length = amount;
+ bh->outreq->length = bh->bulk_out_intended_length =
+ amount;
bh->outreq->short_not_ok = 1;
start_transfer(fsg, fsg->bulk_out, bh->outreq,
&bh->outreq_busy, &bh->state);
@@ -2643,8 +2659,8 @@ static int get_next_command(struct fsg_dev *fsg)
}
/* Queue a request to read a Bulk-only CBW */
- bh->outreq->length = USB_BULK_CB_WRAP_LEN;
- bh->outreq->short_not_ok = 0;
+ set_bulk_out_req_length(fsg, bh, USB_BULK_CB_WRAP_LEN);
+ bh->outreq->short_not_ok = 1;
start_transfer(fsg, fsg->bulk_out, bh->outreq,
&bh->outreq_busy, &bh->state);
diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c
index 86fcebd89abe..109635a84888 100644
--- a/drivers/usb/gadget/storage_common.c
+++ b/drivers/usb/gadget/storage_common.c
@@ -286,6 +286,13 @@ struct fsg_buffhd {
enum fsg_buffer_state state;
struct fsg_buffhd *next;
+ /*
+ * The NetChip 2280 is faster, and handles some protocol faults
+ * better, if we don't submit any short bulk-out read requests.
+ * So we will record the intended request length here.
+ */
+ unsigned int bulk_out_intended_length;
+
struct usb_request *inreq;
int inreq_busy;
struct usb_request *outreq;