Commit ed74df12 authored by Virupax Sadashivpetimath's avatar Virupax Sadashivpetimath Committed by Felipe Balbi

usb: musb: make use_sg flag URB specific

Since highmem PIO URB handling was introduced in:

8e8a5516 usb: musb: host: Handle highmem in PIO mode

when a URB is being handled it may happen that the static use_sg flag
was set by a previous URB with buffer in highmem.  This leads to error
in handling the present URB.

Fix this by making the use_sg flag URB specific.

Cc: stable <stable@vger.kernel.org> # 3.7+
Acked-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Signed-off-by: default avatarVirupax Sadashivpetimath <virupax.sadashivpetimath@stericsson.com>
Signed-off-by: default avatarFabio Baltieri <fabio.baltieri@linaro.org>
Signed-off-by: default avatarFelipe Balbi <balbi@ti.com>
parent 5bf8fae3
......@@ -1232,7 +1232,6 @@ void musb_host_tx(struct musb *musb, u8 epnum)
void __iomem *mbase = musb->mregs;
struct dma_channel *dma;
bool transfer_pending = false;
static bool use_sg;
musb_ep_select(mbase, epnum);
tx_csr = musb_readw(epio, MUSB_TXCSR);
......@@ -1463,9 +1462,9 @@ void musb_host_tx(struct musb *musb, u8 epnum)
* NULL.
*/
if (!urb->transfer_buffer)
use_sg = true;
qh->use_sg = true;
if (use_sg) {
if (qh->use_sg) {
/* sg_miter_start is already done in musb_ep_program */
if (!sg_miter_next(&qh->sg_miter)) {
dev_err(musb->controller, "error: sg list empty\n");
......@@ -1484,9 +1483,9 @@ void musb_host_tx(struct musb *musb, u8 epnum)
qh->segsize = length;
if (use_sg) {
if (qh->use_sg) {
if (offset + length >= urb->transfer_buffer_length)
use_sg = false;
qh->use_sg = false;
}
musb_ep_select(mbase, epnum);
......@@ -1552,7 +1551,6 @@ void musb_host_rx(struct musb *musb, u8 epnum)
bool done = false;
u32 status;
struct dma_channel *dma;
static bool use_sg;
unsigned int sg_flags = SG_MITER_ATOMIC | SG_MITER_TO_SG;
musb_ep_select(mbase, epnum);
......@@ -1878,12 +1876,12 @@ void musb_host_rx(struct musb *musb, u8 epnum)
* NULL.
*/
if (!urb->transfer_buffer) {
use_sg = true;
qh->use_sg = true;
sg_miter_start(&qh->sg_miter, urb->sg, 1,
sg_flags);
}
if (use_sg) {
if (qh->use_sg) {
if (!sg_miter_next(&qh->sg_miter)) {
dev_err(musb->controller, "error: sg list empty\n");
sg_miter_stop(&qh->sg_miter);
......@@ -1913,8 +1911,8 @@ void musb_host_rx(struct musb *musb, u8 epnum)
urb->actual_length += xfer_len;
qh->offset += xfer_len;
if (done) {
if (use_sg)
use_sg = false;
if (qh->use_sg)
qh->use_sg = false;
if (urb->status == -EINPROGRESS)
urb->status = status;
......
......@@ -74,6 +74,7 @@ struct musb_qh {
u16 frame; /* for periodic schedule */
unsigned iso_idx; /* in urb->iso_frame_desc[] */
struct sg_mapping_iter sg_miter; /* for highmem in PIO mode */
bool use_sg; /* to track urb using sglist */
};
/* map from control or bulk queue head to the first qh on that ring */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment