USB: g_file_storage: don't send padding when stall=n
This patch (as1455) removes the extra padding sent by g_file_storage and g_mass_storage when the gadget wants to send less data than requested by the host and isn't allowed to halt the bulk-IN endpoint. Although the Bulk-Only Transport specification requires the padding to be present, it isn't truly needed since the transfer will be terminated by a short packet anyway. Furthermore, many existing devices don't bother to send any padding. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Acked-By: Michal Nazarewicz <mina86@mina86.com> CC: Roger Quadros <roger.quadros@nokia.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
edf847decc
commit
ee81b3e086
|
@ -1569,37 +1569,6 @@ static int wedge_bulk_in_endpoint(struct fsg_dev *fsg)
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int pad_with_zeros(struct fsg_dev *fsg)
|
||||
{
|
||||
struct fsg_buffhd *bh = fsg->common->next_buffhd_to_fill;
|
||||
u32 nkeep = bh->inreq->length;
|
||||
u32 nsend;
|
||||
int rc;
|
||||
|
||||
bh->state = BUF_STATE_EMPTY; /* For the first iteration */
|
||||
fsg->common->usb_amount_left = nkeep + fsg->common->residue;
|
||||
while (fsg->common->usb_amount_left > 0) {
|
||||
|
||||
/* Wait for the next buffer to be free */
|
||||
while (bh->state != BUF_STATE_EMPTY) {
|
||||
rc = sleep_thread(fsg->common);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
nsend = min(fsg->common->usb_amount_left, FSG_BUFLEN);
|
||||
memset(bh->buf + nkeep, 0, nsend - nkeep);
|
||||
bh->inreq->length = nsend;
|
||||
bh->inreq->zero = 0;
|
||||
start_transfer(fsg, fsg->bulk_in, bh->inreq,
|
||||
&bh->inreq_busy, &bh->state);
|
||||
bh = fsg->common->next_buffhd_to_fill = bh->next;
|
||||
fsg->common->usb_amount_left -= nsend;
|
||||
nkeep = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int throw_away_data(struct fsg_common *common)
|
||||
{
|
||||
struct fsg_buffhd *bh;
|
||||
|
@ -1686,6 +1655,10 @@ static int finish_reply(struct fsg_common *common)
|
|||
if (common->data_size == 0) {
|
||||
/* Nothing to send */
|
||||
|
||||
/* Don't know what to do if common->fsg is NULL */
|
||||
} else if (!fsg_is_set(common)) {
|
||||
rc = -EIO;
|
||||
|
||||
/* If there's no residue, simply send the last buffer */
|
||||
} else if (common->residue == 0) {
|
||||
bh->inreq->zero = 0;
|
||||
|
@ -1694,24 +1667,19 @@ static int finish_reply(struct fsg_common *common)
|
|||
common->next_buffhd_to_fill = bh->next;
|
||||
|
||||
/*
|
||||
* For Bulk-only, if we're allowed to stall then send the
|
||||
* short packet and halt the bulk-in endpoint. If we can't
|
||||
* stall, pad out the remaining data with 0's.
|
||||
* For Bulk-only, mark the end of the data with a short
|
||||
* packet. If we are allowed to stall, halt the bulk-in
|
||||
* endpoint. (Note: This violates the Bulk-Only Transport
|
||||
* specification, which requires us to pad the data if we
|
||||
* don't halt the endpoint. Presumably nobody will mind.)
|
||||
*/
|
||||
} else if (common->can_stall) {
|
||||
} else {
|
||||
bh->inreq->zero = 1;
|
||||
if (!start_in_transfer(common, bh))
|
||||
/* Don't know what to do if
|
||||
* common->fsg is NULL */
|
||||
rc = -EIO;
|
||||
common->next_buffhd_to_fill = bh->next;
|
||||
if (common->fsg)
|
||||
if (common->can_stall)
|
||||
rc = halt_bulk_in_endpoint(common->fsg);
|
||||
} else if (fsg_is_set(common)) {
|
||||
rc = pad_with_zeros(common->fsg);
|
||||
} else {
|
||||
/* Don't know what to do if common->fsg is NULL */
|
||||
rc = -EIO;
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -1932,37 +1932,6 @@ static int wedge_bulk_in_endpoint(struct fsg_dev *fsg)
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int pad_with_zeros(struct fsg_dev *fsg)
|
||||
{
|
||||
struct fsg_buffhd *bh = fsg->next_buffhd_to_fill;
|
||||
u32 nkeep = bh->inreq->length;
|
||||
u32 nsend;
|
||||
int rc;
|
||||
|
||||
bh->state = BUF_STATE_EMPTY; // For the first iteration
|
||||
fsg->usb_amount_left = nkeep + fsg->residue;
|
||||
while (fsg->usb_amount_left > 0) {
|
||||
|
||||
/* Wait for the next buffer to be free */
|
||||
while (bh->state != BUF_STATE_EMPTY) {
|
||||
rc = sleep_thread(fsg);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
nsend = min(fsg->usb_amount_left, (u32) mod_data.buflen);
|
||||
memset(bh->buf + nkeep, 0, nsend - nkeep);
|
||||
bh->inreq->length = nsend;
|
||||
bh->inreq->zero = 0;
|
||||
start_transfer(fsg, fsg->bulk_in, bh->inreq,
|
||||
&bh->inreq_busy, &bh->state);
|
||||
bh = fsg->next_buffhd_to_fill = bh->next;
|
||||
fsg->usb_amount_left -= nsend;
|
||||
nkeep = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int throw_away_data(struct fsg_dev *fsg)
|
||||
{
|
||||
struct fsg_buffhd *bh;
|
||||
|
@ -2066,18 +2035,20 @@ static int finish_reply(struct fsg_dev *fsg)
|
|||
}
|
||||
}
|
||||
|
||||
/* For Bulk-only, if we're allowed to stall then send the
|
||||
* short packet and halt the bulk-in endpoint. If we can't
|
||||
* stall, pad out the remaining data with 0's. */
|
||||
/*
|
||||
* For Bulk-only, mark the end of the data with a short
|
||||
* packet. If we are allowed to stall, halt the bulk-in
|
||||
* endpoint. (Note: This violates the Bulk-Only Transport
|
||||
* specification, which requires us to pad the data if we
|
||||
* don't halt the endpoint. Presumably nobody will mind.)
|
||||
*/
|
||||
else {
|
||||
if (mod_data.can_stall) {
|
||||
bh->inreq->zero = 1;
|
||||
start_transfer(fsg, fsg->bulk_in, bh->inreq,
|
||||
&bh->inreq_busy, &bh->state);
|
||||
fsg->next_buffhd_to_fill = bh->next;
|
||||
bh->inreq->zero = 1;
|
||||
start_transfer(fsg, fsg->bulk_in, bh->inreq,
|
||||
&bh->inreq_busy, &bh->state);
|
||||
fsg->next_buffhd_to_fill = bh->next;
|
||||
if (mod_data.can_stall)
|
||||
rc = halt_bulk_in_endpoint(fsg);
|
||||
} else
|
||||
rc = pad_with_zeros(fsg);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
Loading…
Reference in New Issue