diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-07-06 02:09:27 +0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-07-06 02:09:27 +0400 |
commit | 979eef33267ec230b820f4f76b2103e8b567fa57 (patch) | |
tree | 626d47f5c575424c90965ddf5ff35c70d09e0948 | |
parent | e765bf84d59257d3c4f948fbce426ea3565e83ad (diff) | |
parent | 2ed9127cff9a255b7671b8d3d938109f68a87961 (diff) | |
download | linux-979eef33267ec230b820f4f76b2103e8b567fa57.tar.xz |
Merge tag 'musb-for-v3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next
usb: musb: patches for v3.6 merge window
Just two patches here:
First we have a fix to disable DMA in case DMA channel
request fails.
Second, there's a fix for situations where the user
kills musb (by rmmod or any other means) while a
transfer is on the fly. In such cases, we could be
led into a NULL pointer dereference due to endpoint
being disabled and endpoint descriptor being NULL.
-rw-r--r-- | drivers/usb/musb/musb_gadget.c | 14 | ||||
-rw-r--r-- | drivers/usb/musb/musb_host.c | 6 |
2 files changed, 19 insertions, 1 deletions
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 95918dacc99a..f7194cf65aba 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -328,6 +328,13 @@ static void txstate(struct musb *musb, struct musb_request *req) musb_ep = req->ep; + /* Check if EP is disabled */ + if (!musb_ep->desc) { + dev_dbg(musb->controller, "ep:%s disabled - ignore request\n", + musb_ep->end_point.name); + return; + } + /* we shouldn't get here while DMA is active ... but we do ... */ if (dma_channel_status(musb_ep->dma) == MUSB_DMA_STATUS_BUSY) { dev_dbg(musb->controller, "dma pending...\n"); @@ -650,6 +657,13 @@ static void rxstate(struct musb *musb, struct musb_request *req) len = musb_ep->packet_sz; + /* Check if EP is disabled */ + if (!musb_ep->desc) { + dev_dbg(musb->controller, "ep:%s disabled - ignore request\n", + musb_ep->end_point.name); + return; + } + /* We shouldn't get here while DMA is active, but we do... */ if (dma_channel_status(musb_ep->dma) == MUSB_DMA_STATUS_BUSY) { dev_dbg(musb->controller, "DMA pending...\n"); diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index e090c799d87b..4bb717d0bd41 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -1746,7 +1746,11 @@ void musb_host_rx(struct musb *musb, u8 epnum) c->channel_release(dma); hw_ep->rx_channel = NULL; dma = NULL; - /* REVISIT reset CSR */ + val = musb_readw(epio, MUSB_RXCSR); + val &= ~(MUSB_RXCSR_DMAENAB + | MUSB_RXCSR_H_AUTOREQ + | MUSB_RXCSR_AUTOCLEAR); + musb_writew(epio, MUSB_RXCSR, val); } } #endif /* Mentor DMA */ |