Merge branch 'for-greg' of git://gitorious.org/usb/usb into work
This commit is contained in:
Коммит
b7a5100bc2
|
@ -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,
|
||||||
|
|
|
@ -2116,12 +2116,15 @@ bad_config:
|
||||||
* 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),
|
||||||
|
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
|
@ -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));
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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? */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче