forked from Minki/linux
usb: musb: make use_sg flag URB specific
Since highmem PIO URB handling was introduced in:
8e8a551
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: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Virupax Sadashivpetimath <virupax.sadashivpetimath@stericsson.com>
Signed-off-by: Fabio Baltieri <fabio.baltieri@linaro.org>
Signed-off-by: Felipe Balbi <balbi@ti.com>
This commit is contained in:
parent
5bf8fae33d
commit
ed74df12dc
@ -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 @@ done:
|
||||
* 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 @@ done:
|
||||
|
||||
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 @@ finish:
|
||||
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 */
|
||||
|
Loading…
Reference in New Issue
Block a user