0046-fiq_fsm-Implement-hack-for-Split-Interrupt-transacti.patch 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. From 099581aeb11b7eafbca02c9e69f6e6c8de0c57ec Mon Sep 17 00:00:00 2001
  2. From: P33M <P33M@github.com>
  3. Date: Fri, 20 Jun 2014 17:23:20 +0100
  4. Subject: [PATCH 046/114] fiq_fsm: Implement hack for Split Interrupt
  5. transactions
  6. Hubs aren't too picky about which endpoint we send Control type split
  7. transactions to. By treating Interrupt transfers as Control, it is
  8. possible to use the non-periodic queue in the OTG core as well as the
  9. non-periodic FIFOs in the hub itself. This massively reduces the
  10. microframe exclusivity/contention that periodic split transactions
  11. otherwise have to enforce.
  12. It goes without saying that this is a fairly egregious USB specification
  13. violation, but it works.
  14. Original idea by Hans Petter Selasky @ FreeBSD.org.
  15. ---
  16. drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 32 ++++++++++++++++++++++++++------
  17. 1 file changed, 26 insertions(+), 6 deletions(-)
  18. --- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
  19. +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
  20. @@ -1055,10 +1055,11 @@ int dwc_otg_hcd_init(dwc_otg_hcd_t * hcd
  21. for (i=0; i < hcd->core_if->core_params->host_channels; i++) {
  22. dwc_otg_cleanup_fiq_channel(hcd, i);
  23. }
  24. - DWC_PRINTF("FIQ FSM acceleration enabled for :\n%s%s%s",
  25. + DWC_PRINTF("FIQ FSM acceleration enabled for :\n%s%s%s%s",
  26. (fiq_fsm_mask & 0x1) ? "Non-periodic Split Transactions\n" : "",
  27. (fiq_fsm_mask & 0x2) ? "Periodic Split Transactions\n" : "",
  28. - (fiq_fsm_mask & 0x4) ? "High-Speed Isochronous Endpoints\n" : "");
  29. + (fiq_fsm_mask & 0x4) ? "High-Speed Isochronous Endpoints\n" : "",
  30. + (fiq_fsm_mask & 0x8) ? "Interrupt/Control Split Transaction hack enabled\n" : "");
  31. }
  32. }
  33. @@ -1789,6 +1790,20 @@ int fiq_fsm_queue_split_transaction(dwc_
  34. st->hcintmsk_copy.b.chhltd = 1;
  35. st->hcintmsk_copy.b.ahberr = 1;
  36. + /* Hack courtesy of FreeBSD: apparently forcing Interrupt Split transactions
  37. + * as Control puts the transfer into the non-periodic request queue and the
  38. + * non-periodic handler in the hub. Makes things lots easier.
  39. + */
  40. + if ((fiq_fsm_mask & 0x8) && hc->ep_type == UE_INTERRUPT) {
  41. + st->hcchar_copy.b.multicnt = 0;
  42. + st->hcchar_copy.b.oddfrm = 0;
  43. + st->hcchar_copy.b.eptype = UE_CONTROL;
  44. + if (hc->align_buff) {
  45. + st->hcdma_copy.d32 = hc->align_buff;
  46. + } else {
  47. + st->hcdma_copy.d32 = ((unsigned long) hc->xfer_buff & 0xFFFFFFFF);
  48. + }
  49. + }
  50. DWC_WRITE_REG32(&hc_regs->hcdma, st->hcdma_copy.d32);
  51. DWC_WRITE_REG32(&hc_regs->hctsiz, st->hctsiz_copy.d32);
  52. DWC_WRITE_REG32(&hc_regs->hcsplt, st->hcsplt_copy.d32);
  53. @@ -1842,6 +1857,9 @@ int fiq_fsm_queue_split_transaction(dwc_
  54. }
  55. }
  56. }
  57. + if ((fiq_fsm_mask & 0x8) && hc->ep_type == UE_INTERRUPT)
  58. + start_immediate = 1;
  59. +
  60. fiq_print(FIQDBG_INT, hcd->fiq_state, "FSMQ %01d %01d", hc->hc_num, start_immediate);
  61. fiq_print(FIQDBG_INT, hcd->fiq_state, "%08d", hfnum.b.frrem);
  62. //fiq_print(FIQDBG_INT, hcd->fiq_state, "H:%02dP:%02d", hub_addr, port_addr);
  63. @@ -1873,11 +1891,13 @@ int fiq_fsm_queue_split_transaction(dwc_
  64. }
  65. break;
  66. case UE_INTERRUPT:
  67. - if (start_immediate) {
  68. + if (fiq_fsm_mask & 0x8) {
  69. + st->fsm = FIQ_NP_SSPLIT_STARTED;
  70. + } else if (start_immediate) {
  71. st->fsm = FIQ_PER_SSPLIT_STARTED;
  72. - } else {
  73. - st->fsm = FIQ_PER_SSPLIT_QUEUED;
  74. - }
  75. + } else {
  76. + st->fsm = FIQ_PER_SSPLIT_QUEUED;
  77. + }
  78. default:
  79. break;
  80. }