diff options
Diffstat (limited to 'drivers/usb/musb/musb_gadget.c')
-rw-r--r-- | drivers/usb/musb/musb_gadget.c | 222 |
1 files changed, 123 insertions, 99 deletions
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 74073f9a43f0..6fca870e957e 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <linux/moduleparam.h> | 43 | #include <linux/moduleparam.h> |
44 | #include <linux/stat.h> | 44 | #include <linux/stat.h> |
45 | #include <linux/dma-mapping.h> | 45 | #include <linux/dma-mapping.h> |
46 | #include <linux/slab.h> | ||
46 | 47 | ||
47 | #include "musb_core.h" | 48 | #include "musb_core.h" |
48 | 49 | ||
@@ -309,7 +310,7 @@ static void txstate(struct musb *musb, struct musb_request *req) | |||
309 | size_t request_size; | 310 | size_t request_size; |
310 | 311 | ||
311 | /* setup DMA, then program endpoint CSR */ | 312 | /* setup DMA, then program endpoint CSR */ |
312 | request_size = min(request->length, | 313 | request_size = min_t(size_t, request->length, |
313 | musb_ep->dma->max_len); | 314 | musb_ep->dma->max_len); |
314 | if (request_size < musb_ep->packet_sz) | 315 | if (request_size < musb_ep->packet_sz) |
315 | musb_ep->dma->desired_mode = 0; | 316 | musb_ep->dma->desired_mode = 0; |
@@ -319,7 +320,7 @@ static void txstate(struct musb *musb, struct musb_request *req) | |||
319 | use_dma = use_dma && c->channel_program( | 320 | use_dma = use_dma && c->channel_program( |
320 | musb_ep->dma, musb_ep->packet_sz, | 321 | musb_ep->dma, musb_ep->packet_sz, |
321 | musb_ep->dma->desired_mode, | 322 | musb_ep->dma->desired_mode, |
322 | request->dma, request_size); | 323 | request->dma + request->actual, request_size); |
323 | if (use_dma) { | 324 | if (use_dma) { |
324 | if (musb_ep->dma->desired_mode == 0) { | 325 | if (musb_ep->dma->desired_mode == 0) { |
325 | /* | 326 | /* |
@@ -429,112 +430,102 @@ void musb_g_tx(struct musb *musb, u8 epnum) | |||
429 | DBG(4, "<== %s, txcsr %04x\n", musb_ep->end_point.name, csr); | 430 | DBG(4, "<== %s, txcsr %04x\n", musb_ep->end_point.name, csr); |
430 | 431 | ||
431 | dma = is_dma_capable() ? musb_ep->dma : NULL; | 432 | dma = is_dma_capable() ? musb_ep->dma : NULL; |
432 | do { | 433 | |
433 | /* REVISIT for high bandwidth, MUSB_TXCSR_P_INCOMPTX | 434 | /* |
434 | * probably rates reporting as a host error | 435 | * REVISIT: for high bandwidth, MUSB_TXCSR_P_INCOMPTX |
436 | * probably rates reporting as a host error. | ||
437 | */ | ||
438 | if (csr & MUSB_TXCSR_P_SENTSTALL) { | ||
439 | csr |= MUSB_TXCSR_P_WZC_BITS; | ||
440 | csr &= ~MUSB_TXCSR_P_SENTSTALL; | ||
441 | musb_writew(epio, MUSB_TXCSR, csr); | ||
442 | return; | ||
443 | } | ||
444 | |||
445 | if (csr & MUSB_TXCSR_P_UNDERRUN) { | ||
446 | /* We NAKed, no big deal... little reason to care. */ | ||
447 | csr |= MUSB_TXCSR_P_WZC_BITS; | ||
448 | csr &= ~(MUSB_TXCSR_P_UNDERRUN | MUSB_TXCSR_TXPKTRDY); | ||
449 | musb_writew(epio, MUSB_TXCSR, csr); | ||
450 | DBG(20, "underrun on ep%d, req %p\n", epnum, request); | ||
451 | } | ||
452 | |||
453 | if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) { | ||
454 | /* | ||
455 | * SHOULD NOT HAPPEN... has with CPPI though, after | ||
456 | * changing SENDSTALL (and other cases); harmless? | ||
435 | */ | 457 | */ |
436 | if (csr & MUSB_TXCSR_P_SENTSTALL) { | 458 | DBG(5, "%s dma still busy?\n", musb_ep->end_point.name); |
437 | csr |= MUSB_TXCSR_P_WZC_BITS; | 459 | return; |
438 | csr &= ~MUSB_TXCSR_P_SENTSTALL; | 460 | } |
439 | musb_writew(epio, MUSB_TXCSR, csr); | 461 | |
440 | break; | 462 | if (request) { |
441 | } | 463 | u8 is_dma = 0; |
442 | 464 | ||
443 | if (csr & MUSB_TXCSR_P_UNDERRUN) { | 465 | if (dma && (csr & MUSB_TXCSR_DMAENAB)) { |
444 | /* we NAKed, no big deal ... little reason to care */ | 466 | is_dma = 1; |
445 | csr |= MUSB_TXCSR_P_WZC_BITS; | 467 | csr |= MUSB_TXCSR_P_WZC_BITS; |
446 | csr &= ~(MUSB_TXCSR_P_UNDERRUN | 468 | csr &= ~(MUSB_TXCSR_DMAENAB | MUSB_TXCSR_P_UNDERRUN | |
447 | | MUSB_TXCSR_TXPKTRDY); | 469 | MUSB_TXCSR_TXPKTRDY); |
448 | musb_writew(epio, MUSB_TXCSR, csr); | 470 | musb_writew(epio, MUSB_TXCSR, csr); |
449 | DBG(20, "underrun on ep%d, req %p\n", epnum, request); | 471 | /* Ensure writebuffer is empty. */ |
472 | csr = musb_readw(epio, MUSB_TXCSR); | ||
473 | request->actual += musb_ep->dma->actual_len; | ||
474 | DBG(4, "TXCSR%d %04x, DMA off, len %zu, req %p\n", | ||
475 | epnum, csr, musb_ep->dma->actual_len, request); | ||
450 | } | 476 | } |
451 | 477 | ||
452 | if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) { | 478 | if (is_dma || request->actual == request->length) { |
453 | /* SHOULD NOT HAPPEN ... has with cppi though, after | 479 | /* |
454 | * changing SENDSTALL (and other cases); harmless? | 480 | * First, maybe a terminating short packet. Some DMA |
481 | * engines might handle this by themselves. | ||
455 | */ | 482 | */ |
456 | DBG(5, "%s dma still busy?\n", musb_ep->end_point.name); | 483 | if ((request->zero && request->length |
457 | break; | 484 | && request->length % musb_ep->packet_sz == 0) |
458 | } | 485 | #ifdef CONFIG_USB_INVENTRA_DMA |
459 | 486 | || (is_dma && (!dma->desired_mode || | |
460 | if (request) { | 487 | (request->actual & |
461 | u8 is_dma = 0; | 488 | (musb_ep->packet_sz - 1)))) |
489 | #endif | ||
490 | ) { | ||
491 | /* | ||
492 | * On DMA completion, FIFO may not be | ||
493 | * available yet... | ||
494 | */ | ||
495 | if (csr & MUSB_TXCSR_TXPKTRDY) | ||
496 | return; | ||
462 | 497 | ||
463 | if (dma && (csr & MUSB_TXCSR_DMAENAB)) { | 498 | DBG(4, "sending zero pkt\n"); |
464 | is_dma = 1; | 499 | musb_writew(epio, MUSB_TXCSR, MUSB_TXCSR_MODE |
465 | csr |= MUSB_TXCSR_P_WZC_BITS; | ||
466 | csr &= ~(MUSB_TXCSR_DMAENAB | ||
467 | | MUSB_TXCSR_P_UNDERRUN | ||
468 | | MUSB_TXCSR_TXPKTRDY); | 500 | | MUSB_TXCSR_TXPKTRDY); |
469 | musb_writew(epio, MUSB_TXCSR, csr); | 501 | request->zero = 0; |
470 | /* ensure writebuffer is empty */ | ||
471 | csr = musb_readw(epio, MUSB_TXCSR); | ||
472 | request->actual += musb_ep->dma->actual_len; | ||
473 | DBG(4, "TXCSR%d %04x, dma off, " | ||
474 | "len %zu, req %p\n", | ||
475 | epnum, csr, | ||
476 | musb_ep->dma->actual_len, | ||
477 | request); | ||
478 | } | 502 | } |
479 | 503 | ||
480 | if (is_dma || request->actual == request->length) { | 504 | /* ... or if not, then complete it. */ |
481 | 505 | musb_g_giveback(musb_ep, request, 0); | |
482 | /* First, maybe a terminating short packet. | ||
483 | * Some DMA engines might handle this by | ||
484 | * themselves. | ||
485 | */ | ||
486 | if ((request->zero | ||
487 | && request->length | ||
488 | && (request->length | ||
489 | % musb_ep->packet_sz) | ||
490 | == 0) | ||
491 | #ifdef CONFIG_USB_INVENTRA_DMA | ||
492 | || (is_dma && | ||
493 | ((!dma->desired_mode) || | ||
494 | (request->actual & | ||
495 | (musb_ep->packet_sz - 1)))) | ||
496 | #endif | ||
497 | ) { | ||
498 | /* on dma completion, fifo may not | ||
499 | * be available yet ... | ||
500 | */ | ||
501 | if (csr & MUSB_TXCSR_TXPKTRDY) | ||
502 | break; | ||
503 | |||
504 | DBG(4, "sending zero pkt\n"); | ||
505 | musb_writew(epio, MUSB_TXCSR, | ||
506 | MUSB_TXCSR_MODE | ||
507 | | MUSB_TXCSR_TXPKTRDY); | ||
508 | request->zero = 0; | ||
509 | } | ||
510 | |||
511 | /* ... or if not, then complete it */ | ||
512 | musb_g_giveback(musb_ep, request, 0); | ||
513 | 506 | ||
514 | /* kickstart next transfer if appropriate; | 507 | /* |
515 | * the packet that just completed might not | 508 | * Kickstart next transfer if appropriate; |
516 | * be transmitted for hours or days. | 509 | * the packet that just completed might not |
517 | * REVISIT for double buffering... | 510 | * be transmitted for hours or days. |
518 | * FIXME revisit for stalls too... | 511 | * REVISIT for double buffering... |
519 | */ | 512 | * FIXME revisit for stalls too... |
520 | musb_ep_select(mbase, epnum); | 513 | */ |
521 | csr = musb_readw(epio, MUSB_TXCSR); | 514 | musb_ep_select(mbase, epnum); |
522 | if (csr & MUSB_TXCSR_FIFONOTEMPTY) | 515 | csr = musb_readw(epio, MUSB_TXCSR); |
523 | break; | 516 | if (csr & MUSB_TXCSR_FIFONOTEMPTY) |
524 | request = musb_ep->desc | 517 | return; |
525 | ? next_request(musb_ep) | 518 | |
526 | : NULL; | 519 | request = musb_ep->desc ? next_request(musb_ep) : NULL; |
527 | if (!request) { | 520 | if (!request) { |
528 | DBG(4, "%s idle now\n", | 521 | DBG(4, "%s idle now\n", |
529 | musb_ep->end_point.name); | 522 | musb_ep->end_point.name); |
530 | break; | 523 | return; |
531 | } | ||
532 | } | 524 | } |
533 | |||
534 | txstate(musb, to_musb_request(request)); | ||
535 | } | 525 | } |
536 | 526 | ||
537 | } while (0); | 527 | txstate(musb, to_musb_request(request)); |
528 | } | ||
538 | } | 529 | } |
539 | 530 | ||
540 | /* ------------------------------------------------------------ */ | 531 | /* ------------------------------------------------------------ */ |
@@ -756,6 +747,8 @@ void musb_g_rx(struct musb *musb, u8 epnum) | |||
756 | musb_ep_select(mbase, epnum); | 747 | musb_ep_select(mbase, epnum); |
757 | 748 | ||
758 | request = next_request(musb_ep); | 749 | request = next_request(musb_ep); |
750 | if (!request) | ||
751 | return; | ||
759 | 752 | ||
760 | csr = musb_readw(epio, MUSB_RXCSR); | 753 | csr = musb_readw(epio, MUSB_RXCSR); |
761 | dma = is_dma_capable() ? musb_ep->dma : NULL; | 754 | dma = is_dma_capable() ? musb_ep->dma : NULL; |
@@ -903,7 +896,14 @@ static int musb_gadget_enable(struct usb_ep *ep, | |||
903 | /* REVISIT if can_bulk_split(), use by updating "tmp"; | 896 | /* REVISIT if can_bulk_split(), use by updating "tmp"; |
904 | * likewise high bandwidth periodic tx | 897 | * likewise high bandwidth periodic tx |
905 | */ | 898 | */ |
906 | musb_writew(regs, MUSB_TXMAXP, tmp); | 899 | /* Set TXMAXP with the FIFO size of the endpoint |
900 | * to disable double buffering mode. Currently, It seems that double | ||
901 | * buffering has problem if musb RTL revision number < 2.0. | ||
902 | */ | ||
903 | if (musb->hwvers < MUSB_HWVERS_2000) | ||
904 | musb_writew(regs, MUSB_TXMAXP, hw_ep->max_packet_sz_tx); | ||
905 | else | ||
906 | musb_writew(regs, MUSB_TXMAXP, tmp); | ||
907 | 907 | ||
908 | csr = MUSB_TXCSR_MODE | MUSB_TXCSR_CLRDATATOG; | 908 | csr = MUSB_TXCSR_MODE | MUSB_TXCSR_CLRDATATOG; |
909 | if (musb_readw(regs, MUSB_TXCSR) | 909 | if (musb_readw(regs, MUSB_TXCSR) |
@@ -933,7 +933,13 @@ static int musb_gadget_enable(struct usb_ep *ep, | |||
933 | /* REVISIT if can_bulk_combine() use by updating "tmp" | 933 | /* REVISIT if can_bulk_combine() use by updating "tmp" |
934 | * likewise high bandwidth periodic rx | 934 | * likewise high bandwidth periodic rx |
935 | */ | 935 | */ |
936 | musb_writew(regs, MUSB_RXMAXP, tmp); | 936 | /* Set RXMAXP with the FIFO size of the endpoint |
937 | * to disable double buffering mode. | ||
938 | */ | ||
939 | if (musb->hwvers < MUSB_HWVERS_2000) | ||
940 | musb_writew(regs, MUSB_RXMAXP, hw_ep->max_packet_sz_rx); | ||
941 | else | ||
942 | musb_writew(regs, MUSB_RXMAXP, tmp); | ||
937 | 943 | ||
938 | /* force shared fifo to OUT-only mode */ | 944 | /* force shared fifo to OUT-only mode */ |
939 | if (hw_ep->is_shared_fifo) { | 945 | if (hw_ep->is_shared_fifo) { |
@@ -966,6 +972,7 @@ static int musb_gadget_enable(struct usb_ep *ep, | |||
966 | 972 | ||
967 | musb_ep->desc = desc; | 973 | musb_ep->desc = desc; |
968 | musb_ep->busy = 0; | 974 | musb_ep->busy = 0; |
975 | musb_ep->wedged = 0; | ||
969 | status = 0; | 976 | status = 0; |
970 | 977 | ||
971 | pr_debug("%s periph: enabled %s for %s %s, %smaxpacket %d\n", | 978 | pr_debug("%s periph: enabled %s for %s %s, %smaxpacket %d\n", |
@@ -1220,7 +1227,7 @@ done: | |||
1220 | * | 1227 | * |
1221 | * exported to ep0 code | 1228 | * exported to ep0 code |
1222 | */ | 1229 | */ |
1223 | int musb_gadget_set_halt(struct usb_ep *ep, int value) | 1230 | static int musb_gadget_set_halt(struct usb_ep *ep, int value) |
1224 | { | 1231 | { |
1225 | struct musb_ep *musb_ep = to_musb_ep(ep); | 1232 | struct musb_ep *musb_ep = to_musb_ep(ep); |
1226 | u8 epnum = musb_ep->current_epnum; | 1233 | u8 epnum = musb_ep->current_epnum; |
@@ -1262,7 +1269,8 @@ int musb_gadget_set_halt(struct usb_ep *ep, int value) | |||
1262 | goto done; | 1269 | goto done; |
1263 | } | 1270 | } |
1264 | } | 1271 | } |
1265 | } | 1272 | } else |
1273 | musb_ep->wedged = 0; | ||
1266 | 1274 | ||
1267 | /* set/clear the stall and toggle bits */ | 1275 | /* set/clear the stall and toggle bits */ |
1268 | DBG(2, "%s: %s stall\n", ep->name, value ? "set" : "clear"); | 1276 | DBG(2, "%s: %s stall\n", ep->name, value ? "set" : "clear"); |
@@ -1301,6 +1309,21 @@ done: | |||
1301 | return status; | 1309 | return status; |
1302 | } | 1310 | } |
1303 | 1311 | ||
1312 | /* | ||
1313 | * Sets the halt feature with the clear requests ignored | ||
1314 | */ | ||
1315 | static int musb_gadget_set_wedge(struct usb_ep *ep) | ||
1316 | { | ||
1317 | struct musb_ep *musb_ep = to_musb_ep(ep); | ||
1318 | |||
1319 | if (!ep) | ||
1320 | return -EINVAL; | ||
1321 | |||
1322 | musb_ep->wedged = 1; | ||
1323 | |||
1324 | return usb_ep_set_halt(ep); | ||
1325 | } | ||
1326 | |||
1304 | static int musb_gadget_fifo_status(struct usb_ep *ep) | 1327 | static int musb_gadget_fifo_status(struct usb_ep *ep) |
1305 | { | 1328 | { |
1306 | struct musb_ep *musb_ep = to_musb_ep(ep); | 1329 | struct musb_ep *musb_ep = to_musb_ep(ep); |
@@ -1371,6 +1394,7 @@ static const struct usb_ep_ops musb_ep_ops = { | |||
1371 | .queue = musb_gadget_queue, | 1394 | .queue = musb_gadget_queue, |
1372 | .dequeue = musb_gadget_dequeue, | 1395 | .dequeue = musb_gadget_dequeue, |
1373 | .set_halt = musb_gadget_set_halt, | 1396 | .set_halt = musb_gadget_set_halt, |
1397 | .set_wedge = musb_gadget_set_wedge, | ||
1374 | .fifo_status = musb_gadget_fifo_status, | 1398 | .fifo_status = musb_gadget_fifo_status, |
1375 | .fifo_flush = musb_gadget_fifo_flush | 1399 | .fifo_flush = musb_gadget_fifo_flush |
1376 | }; | 1400 | }; |
@@ -1687,8 +1711,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
1687 | return -EINVAL; | 1711 | return -EINVAL; |
1688 | 1712 | ||
1689 | /* driver must be initialized to support peripheral mode */ | 1713 | /* driver must be initialized to support peripheral mode */ |
1690 | if (!musb || !(musb->board_mode == MUSB_OTG | 1714 | if (!musb) { |
1691 | || musb->board_mode != MUSB_OTG)) { | ||
1692 | DBG(1, "%s, no dev??\n", __func__); | 1715 | DBG(1, "%s, no dev??\n", __func__); |
1693 | return -ENODEV; | 1716 | return -ENODEV; |
1694 | } | 1717 | } |
@@ -1723,6 +1746,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
1723 | spin_lock_irqsave(&musb->lock, flags); | 1746 | spin_lock_irqsave(&musb->lock, flags); |
1724 | 1747 | ||
1725 | otg_set_peripheral(musb->xceiv, &musb->g); | 1748 | otg_set_peripheral(musb->xceiv, &musb->g); |
1749 | musb->xceiv->state = OTG_STATE_B_IDLE; | ||
1726 | musb->is_active = 1; | 1750 | musb->is_active = 1; |
1727 | 1751 | ||
1728 | /* FIXME this ignores the softconnect flag. Drivers are | 1752 | /* FIXME this ignores the softconnect flag. Drivers are |