Loading drivers/usb/core/hcd.c +2 −0 Original line number Original line Diff line number Diff line Loading @@ -1330,6 +1330,8 @@ static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, */ */ if (usb_endpoint_xfer_control(&urb->ep->desc)) { if (usb_endpoint_xfer_control(&urb->ep->desc)) { if (hcd->self.uses_pio_for_control) return ret; if (hcd->self.uses_dma) { if (hcd->self.uses_dma) { urb->setup_dma = dma_map_single( urb->setup_dma = dma_map_single( hcd->self.controller, hcd->self.controller, Loading drivers/usb/musb/musb_core.c +3 −0 Original line number Original line Diff line number Diff line Loading @@ -2116,12 +2116,15 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) * Otherwise, wait till the gadget driver hooks up. * Otherwise, wait till the gadget driver hooks up. */ */ if (!is_otg_enabled(musb) && is_host_enabled(musb)) { if (!is_otg_enabled(musb) && is_host_enabled(musb)) { struct usb_hcd *hcd = musb_to_hcd(musb); MUSB_HST_MODE(musb); MUSB_HST_MODE(musb); musb->xceiv->default_a = 1; musb->xceiv->default_a = 1; musb->xceiv->state = OTG_STATE_A_IDLE; musb->xceiv->state = OTG_STATE_A_IDLE; status = usb_add_hcd(musb_to_hcd(musb), -1, 0); status = usb_add_hcd(musb_to_hcd(musb), -1, 0); hcd->self.uses_pio_for_control = 1; DBG(1, "%s mode, status %d, devctl %02x %c\n", DBG(1, "%s mode, status %d, devctl %02x %c\n", "HOST", status, "HOST", status, musb_readb(musb->mregs, MUSB_DEVCTL), musb_readb(musb->mregs, MUSB_DEVCTL), Loading drivers/usb/musb/musb_gadget.c +86 −38 Original line number Original line Diff line number Diff line Loading @@ -92,6 +92,59 @@ /* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */ /* Maps the buffer to dma */ static inline void map_dma_buffer(struct musb_request *request, struct musb *musb) { if (request->request.dma == DMA_ADDR_INVALID) { request->request.dma = dma_map_single( musb->controller, request->request.buf, request->request.length, request->tx ? DMA_TO_DEVICE : DMA_FROM_DEVICE); request->mapped = 1; } else { dma_sync_single_for_device(musb->controller, request->request.dma, request->request.length, request->tx ? DMA_TO_DEVICE : DMA_FROM_DEVICE); request->mapped = 0; } } /* Unmap the buffer from dma and maps it back to cpu */ static inline void unmap_dma_buffer(struct musb_request *request, struct musb *musb) { if (request->request.dma == DMA_ADDR_INVALID) { DBG(20, "not unmapping a never mapped buffer\n"); return; } if (request->mapped) { dma_unmap_single(musb->controller, request->request.dma, request->request.length, request->tx ? DMA_TO_DEVICE : DMA_FROM_DEVICE); request->request.dma = DMA_ADDR_INVALID; request->mapped = 0; } else { dma_sync_single_for_cpu(musb->controller, request->request.dma, request->request.length, request->tx ? DMA_TO_DEVICE : DMA_FROM_DEVICE); } } /* /* * Immediately complete a request. * Immediately complete a request. * * Loading Loading @@ -119,24 +172,8 @@ __acquires(ep->musb->lock) ep->busy = 1; ep->busy = 1; spin_unlock(&musb->lock); spin_unlock(&musb->lock); if (is_dma_capable()) { if (is_dma_capable() && ep->dma) if (req->mapped) { unmap_dma_buffer(req, musb); dma_unmap_single(musb->controller, req->request.dma, req->request.length, req->tx ? DMA_TO_DEVICE : DMA_FROM_DEVICE); req->request.dma = DMA_ADDR_INVALID; req->mapped = 0; } else if (req->request.dma != DMA_ADDR_INVALID) dma_sync_single_for_cpu(musb->controller, req->request.dma, req->request.length, req->tx ? DMA_TO_DEVICE : DMA_FROM_DEVICE); } if (request->status == 0) if (request->status == 0) DBG(5, "%s done request %p, %d/%d\n", DBG(5, "%s done request %p, %d/%d\n", ep->end_point.name, request, ep->end_point.name, request, Loading Loading @@ -395,6 +432,13 @@ static void txstate(struct musb *musb, struct musb_request *req) #endif #endif if (!use_dma) { if (!use_dma) { /* * Unmap the dma buffer back to cpu if dma channel * programming fails */ if (is_dma_capable() && musb_ep->dma) unmap_dma_buffer(req, musb); musb_write_fifo(musb_ep->hw_ep, fifo_count, musb_write_fifo(musb_ep->hw_ep, fifo_count, (u8 *) (request->buf + request->actual)); (u8 *) (request->buf + request->actual)); request->actual += fifo_count; request->actual += fifo_count; Loading Loading @@ -713,6 +757,21 @@ static void rxstate(struct musb *musb, struct musb_request *req) return; return; } } #endif #endif /* * Unmap the dma buffer back to cpu if dma channel * programming fails. This buffer is mapped if the * channel allocation is successful */ if (is_dma_capable() && musb_ep->dma) { unmap_dma_buffer(req, musb); /* * Clear DMAENAB and AUTOCLEAR for the * PIO mode transfer */ csr &= ~(MUSB_RXCSR_DMAENAB | MUSB_RXCSR_AUTOCLEAR); musb_writew(epio, MUSB_RXCSR, csr); } musb_read_fifo(musb_ep->hw_ep, fifo_count, (u8 *) musb_read_fifo(musb_ep->hw_ep, fifo_count, (u8 *) (request->buf + request->actual)); (request->buf + request->actual)); Loading Loading @@ -837,7 +896,9 @@ void musb_g_rx(struct musb *musb, u8 epnum) if (!request) if (!request) return; return; } } #if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_TUSB_OMAP_DMA) exit: exit: #endif /* Analyze request */ /* Analyze request */ rxstate(musb, to_musb_request(request)); rxstate(musb, to_musb_request(request)); } } Loading Loading @@ -1150,26 +1211,9 @@ static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req, request->epnum = musb_ep->current_epnum; request->epnum = musb_ep->current_epnum; request->tx = musb_ep->is_in; request->tx = musb_ep->is_in; if (is_dma_capable() && musb_ep->dma) { if (is_dma_capable() && musb_ep->dma) if (request->request.dma == DMA_ADDR_INVALID) { map_dma_buffer(request, musb); request->request.dma = dma_map_single( else musb->controller, request->request.buf, request->request.length, request->tx ? DMA_TO_DEVICE : DMA_FROM_DEVICE); request->mapped = 1; } else { dma_sync_single_for_device(musb->controller, request->request.dma, request->request.length, request->tx ? DMA_TO_DEVICE : DMA_FROM_DEVICE); request->mapped = 0; } } else request->mapped = 0; request->mapped = 0; spin_lock_irqsave(&musb->lock, lockflags); spin_lock_irqsave(&musb->lock, lockflags); Loading Loading @@ -1789,6 +1833,8 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, spin_unlock_irqrestore(&musb->lock, flags); spin_unlock_irqrestore(&musb->lock, flags); if (is_otg_enabled(musb)) { if (is_otg_enabled(musb)) { struct usb_hcd *hcd = musb_to_hcd(musb); DBG(3, "OTG startup...\n"); DBG(3, "OTG startup...\n"); /* REVISIT: funcall to other code, which also /* REVISIT: funcall to other code, which also Loading @@ -1803,6 +1849,8 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, musb->gadget_driver = NULL; musb->gadget_driver = NULL; musb->g.dev.driver = NULL; musb->g.dev.driver = NULL; spin_unlock_irqrestore(&musb->lock, flags); spin_unlock_irqrestore(&musb->lock, flags); } else { hcd->self.uses_pio_for_control = 1; } } } } } } Loading include/linux/usb.h +4 −0 Original line number Original line Diff line number Diff line Loading @@ -313,6 +313,10 @@ struct usb_bus { int busnum; /* Bus number (in order of reg) */ int busnum; /* Bus number (in order of reg) */ const char *bus_name; /* stable id (PCI slot_name etc) */ const char *bus_name; /* stable id (PCI slot_name etc) */ u8 uses_dma; /* Does the host controller use DMA? */ u8 uses_dma; /* Does the host controller use DMA? */ u8 uses_pio_for_control; /* * Does the host controller use PIO * for control transfers? */ u8 otg_port; /* 0, or number of OTG/HNP port */ u8 otg_port; /* 0, or number of OTG/HNP port */ unsigned is_b_host:1; /* true during some HNP roleswitches */ unsigned is_b_host:1; /* true during some HNP roleswitches */ unsigned b_hnp_enable:1; /* OTG: did A-Host enable HNP? */ unsigned b_hnp_enable:1; /* OTG: did A-Host enable HNP? */ Loading Loading
drivers/usb/core/hcd.c +2 −0 Original line number Original line Diff line number Diff line Loading @@ -1330,6 +1330,8 @@ static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, */ */ if (usb_endpoint_xfer_control(&urb->ep->desc)) { if (usb_endpoint_xfer_control(&urb->ep->desc)) { if (hcd->self.uses_pio_for_control) return ret; if (hcd->self.uses_dma) { if (hcd->self.uses_dma) { urb->setup_dma = dma_map_single( urb->setup_dma = dma_map_single( hcd->self.controller, hcd->self.controller, Loading
drivers/usb/musb/musb_core.c +3 −0 Original line number Original line Diff line number Diff line Loading @@ -2116,12 +2116,15 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) * Otherwise, wait till the gadget driver hooks up. * Otherwise, wait till the gadget driver hooks up. */ */ if (!is_otg_enabled(musb) && is_host_enabled(musb)) { if (!is_otg_enabled(musb) && is_host_enabled(musb)) { struct usb_hcd *hcd = musb_to_hcd(musb); MUSB_HST_MODE(musb); MUSB_HST_MODE(musb); musb->xceiv->default_a = 1; musb->xceiv->default_a = 1; musb->xceiv->state = OTG_STATE_A_IDLE; musb->xceiv->state = OTG_STATE_A_IDLE; status = usb_add_hcd(musb_to_hcd(musb), -1, 0); status = usb_add_hcd(musb_to_hcd(musb), -1, 0); hcd->self.uses_pio_for_control = 1; DBG(1, "%s mode, status %d, devctl %02x %c\n", DBG(1, "%s mode, status %d, devctl %02x %c\n", "HOST", status, "HOST", status, musb_readb(musb->mregs, MUSB_DEVCTL), musb_readb(musb->mregs, MUSB_DEVCTL), Loading
drivers/usb/musb/musb_gadget.c +86 −38 Original line number Original line Diff line number Diff line Loading @@ -92,6 +92,59 @@ /* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */ /* Maps the buffer to dma */ static inline void map_dma_buffer(struct musb_request *request, struct musb *musb) { if (request->request.dma == DMA_ADDR_INVALID) { request->request.dma = dma_map_single( musb->controller, request->request.buf, request->request.length, request->tx ? DMA_TO_DEVICE : DMA_FROM_DEVICE); request->mapped = 1; } else { dma_sync_single_for_device(musb->controller, request->request.dma, request->request.length, request->tx ? DMA_TO_DEVICE : DMA_FROM_DEVICE); request->mapped = 0; } } /* Unmap the buffer from dma and maps it back to cpu */ static inline void unmap_dma_buffer(struct musb_request *request, struct musb *musb) { if (request->request.dma == DMA_ADDR_INVALID) { DBG(20, "not unmapping a never mapped buffer\n"); return; } if (request->mapped) { dma_unmap_single(musb->controller, request->request.dma, request->request.length, request->tx ? DMA_TO_DEVICE : DMA_FROM_DEVICE); request->request.dma = DMA_ADDR_INVALID; request->mapped = 0; } else { dma_sync_single_for_cpu(musb->controller, request->request.dma, request->request.length, request->tx ? DMA_TO_DEVICE : DMA_FROM_DEVICE); } } /* /* * Immediately complete a request. * Immediately complete a request. * * Loading Loading @@ -119,24 +172,8 @@ __acquires(ep->musb->lock) ep->busy = 1; ep->busy = 1; spin_unlock(&musb->lock); spin_unlock(&musb->lock); if (is_dma_capable()) { if (is_dma_capable() && ep->dma) if (req->mapped) { unmap_dma_buffer(req, musb); dma_unmap_single(musb->controller, req->request.dma, req->request.length, req->tx ? DMA_TO_DEVICE : DMA_FROM_DEVICE); req->request.dma = DMA_ADDR_INVALID; req->mapped = 0; } else if (req->request.dma != DMA_ADDR_INVALID) dma_sync_single_for_cpu(musb->controller, req->request.dma, req->request.length, req->tx ? DMA_TO_DEVICE : DMA_FROM_DEVICE); } if (request->status == 0) if (request->status == 0) DBG(5, "%s done request %p, %d/%d\n", DBG(5, "%s done request %p, %d/%d\n", ep->end_point.name, request, ep->end_point.name, request, Loading Loading @@ -395,6 +432,13 @@ static void txstate(struct musb *musb, struct musb_request *req) #endif #endif if (!use_dma) { if (!use_dma) { /* * Unmap the dma buffer back to cpu if dma channel * programming fails */ if (is_dma_capable() && musb_ep->dma) unmap_dma_buffer(req, musb); musb_write_fifo(musb_ep->hw_ep, fifo_count, musb_write_fifo(musb_ep->hw_ep, fifo_count, (u8 *) (request->buf + request->actual)); (u8 *) (request->buf + request->actual)); request->actual += fifo_count; request->actual += fifo_count; Loading Loading @@ -713,6 +757,21 @@ static void rxstate(struct musb *musb, struct musb_request *req) return; return; } } #endif #endif /* * Unmap the dma buffer back to cpu if dma channel * programming fails. This buffer is mapped if the * channel allocation is successful */ if (is_dma_capable() && musb_ep->dma) { unmap_dma_buffer(req, musb); /* * Clear DMAENAB and AUTOCLEAR for the * PIO mode transfer */ csr &= ~(MUSB_RXCSR_DMAENAB | MUSB_RXCSR_AUTOCLEAR); musb_writew(epio, MUSB_RXCSR, csr); } musb_read_fifo(musb_ep->hw_ep, fifo_count, (u8 *) musb_read_fifo(musb_ep->hw_ep, fifo_count, (u8 *) (request->buf + request->actual)); (request->buf + request->actual)); Loading Loading @@ -837,7 +896,9 @@ void musb_g_rx(struct musb *musb, u8 epnum) if (!request) if (!request) return; return; } } #if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_TUSB_OMAP_DMA) exit: exit: #endif /* Analyze request */ /* Analyze request */ rxstate(musb, to_musb_request(request)); rxstate(musb, to_musb_request(request)); } } Loading Loading @@ -1150,26 +1211,9 @@ static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req, request->epnum = musb_ep->current_epnum; request->epnum = musb_ep->current_epnum; request->tx = musb_ep->is_in; request->tx = musb_ep->is_in; if (is_dma_capable() && musb_ep->dma) { if (is_dma_capable() && musb_ep->dma) if (request->request.dma == DMA_ADDR_INVALID) { map_dma_buffer(request, musb); request->request.dma = dma_map_single( else musb->controller, request->request.buf, request->request.length, request->tx ? DMA_TO_DEVICE : DMA_FROM_DEVICE); request->mapped = 1; } else { dma_sync_single_for_device(musb->controller, request->request.dma, request->request.length, request->tx ? DMA_TO_DEVICE : DMA_FROM_DEVICE); request->mapped = 0; } } else request->mapped = 0; request->mapped = 0; spin_lock_irqsave(&musb->lock, lockflags); spin_lock_irqsave(&musb->lock, lockflags); Loading Loading @@ -1789,6 +1833,8 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, spin_unlock_irqrestore(&musb->lock, flags); spin_unlock_irqrestore(&musb->lock, flags); if (is_otg_enabled(musb)) { if (is_otg_enabled(musb)) { struct usb_hcd *hcd = musb_to_hcd(musb); DBG(3, "OTG startup...\n"); DBG(3, "OTG startup...\n"); /* REVISIT: funcall to other code, which also /* REVISIT: funcall to other code, which also Loading @@ -1803,6 +1849,8 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, musb->gadget_driver = NULL; musb->gadget_driver = NULL; musb->g.dev.driver = NULL; musb->g.dev.driver = NULL; spin_unlock_irqrestore(&musb->lock, flags); spin_unlock_irqrestore(&musb->lock, flags); } else { hcd->self.uses_pio_for_control = 1; } } } } } } Loading
include/linux/usb.h +4 −0 Original line number Original line Diff line number Diff line Loading @@ -313,6 +313,10 @@ struct usb_bus { int busnum; /* Bus number (in order of reg) */ int busnum; /* Bus number (in order of reg) */ const char *bus_name; /* stable id (PCI slot_name etc) */ const char *bus_name; /* stable id (PCI slot_name etc) */ u8 uses_dma; /* Does the host controller use DMA? */ u8 uses_dma; /* Does the host controller use DMA? */ u8 uses_pio_for_control; /* * Does the host controller use PIO * for control transfers? */ u8 otg_port; /* 0, or number of OTG/HNP port */ u8 otg_port; /* 0, or number of OTG/HNP port */ unsigned is_b_host:1; /* true during some HNP roleswitches */ unsigned is_b_host:1; /* true during some HNP roleswitches */ unsigned b_hnp_enable:1; /* OTG: did A-Host enable HNP? */ unsigned b_hnp_enable:1; /* OTG: did A-Host enable HNP? */ Loading