Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. ; Code for EHCI controllers.
  2. ; Note: it should be moved to an external driver,
  3. ; it was convenient to have this code compiled into the kernel during initial
  4. ; development, but there are no reasons to keep it here.
  5.  
  6. ; =============================================================================
  7. ; ================================= Constants =================================
  8. ; =============================================================================
  9. ; EHCI register declarations.
  10. ; Part 1. Capability registers.
  11. ; Base is MMIO from the PCI space.
  12. EhciCapLengthReg    = 0
  13. EhciVersionReg      = 2
  14. EhciStructParamsReg = 4
  15. EhciCapParamsReg    = 8
  16. EhciPortRouteReg    = 0Ch
  17. ; Part 2. Operational registers.
  18. ; Base is (base for part 1) + (value of EhciCapLengthReg).
  19. EhciCommandReg      = 0
  20. EhciStatusReg       = 4
  21. EhciInterruptReg    = 8
  22. EhciFrameIndexReg   = 0Ch
  23. EhciCtrlDataSegReg  = 10h
  24. EhciPeriodicListReg = 14h
  25. EhciAsyncListReg    = 18h
  26. EhciConfigFlagReg   = 40h
  27. EhciPortsReg        = 44h
  28.  
  29. ; Possible values of ehci_pipe.NextQH.Type bitfield.
  30. EHCI_TYPE_ITD  = 0 ; isochronous transfer descriptor
  31. EHCI_TYPE_QH   = 1 ; queue head
  32. EHCI_TYPE_SITD = 2 ; split-transaction isochronous TD
  33. EHCI_TYPE_FSTN = 3 ; frame span traversal node
  34.  
  35. ; =============================================================================
  36. ; ================================ Structures =================================
  37. ; =============================================================================
  38.  
  39. ; Hardware part of EHCI general transfer descriptor.
  40. struct ehci_hardware_td
  41. NextTD          dd      ?
  42. ; Bit 0 is Terminate bit, 1 = there is no next TD.
  43. ; Bits 1-4 must be zero.
  44. ; With masked 5 lower bits, this is the physical address of the next TD, if any.
  45. AlternateNextTD dd      ?
  46. ; Similar to NextTD, used if the transfer terminates with a short packet.
  47. Token           dd      ?
  48. ; 1. Lower byte is Status field:
  49. ; bit 0 = ping state for USB2 endpoints, ERR handshake signal for USB1 endpoints
  50. ; bit 1 = split transaction state, meaningless for USB2 endpoints
  51. ; bit 2 = missed micro-frame
  52. ; bit 3 = transaction error
  53. ; bit 4 = babble detected
  54. ; bit 5 = data buffer error
  55. ; bit 6 = halted
  56. ; bit 7 = active
  57. ; 2. Next two bits (bits 8-9) are PID code, 0 = OUT, 1 = IN, 2 = SETUP.
  58. ; 3. Next two bits (bits 10-11) is ErrorCounter. Initialized as 3, decremented
  59. ;    on each error; if it goes to zero, transaction is stopped.
  60. ; 4. Next 3 bits (bits 12-14) are CurrentPage field.
  61. ; 5. Next bit (bit 15) is InterruptOnComplete bit.
  62. ; 6. Next 15 bits (bits 16-30) are TransferLength field,
  63. ;    number of bytes to transfer.
  64. ; 7. Upper bit (bit 31) is DataToggle bit.
  65. BufferPointers  rd      5
  66. ; The buffer to be transferred can be spanned on up to 5 physical pages.
  67. ; The first item of this array is the physical address of the first byte in
  68. ; the buffer, other items are physical addresses of next pages. Lower 12 bits
  69. ; in other items must be set to zero; ehci_pipe.Overlay reuses some of them.
  70. BufferPointersHigh      rd      5
  71. ; Upper dwords of BufferPointers for controllers with 64-bit memory access.
  72. ; Always zero.
  73. ends
  74.  
  75. ; EHCI general transfer descriptor.
  76. ; * The structure describes transfers to be performed on Control, Bulk or
  77. ;   Interrupt endpoints.
  78. ; * The structure includes two parts, the hardware part and the software part.
  79. ; * The hardware part consists of first 52 bytes and corresponds to
  80. ;   the Queue Element Transfer Descriptor from EHCI specification.
  81. ; * The hardware requires 32-bytes alignment of the hardware part, so
  82. ;   the entire descriptor must be 32-bytes aligned. Since the allocator
  83. ;   (usb_allocate_common) allocates memory sequentially from page start
  84. ;   (aligned on 0x1000 bytes), size of the structure must be divisible by 32.
  85. ; * The hardware also requires that the hardware part must not cross page
  86. ;   boundary; the allocator satisfies this automatically.
  87. struct ehci_gtd ehci_hardware_td
  88. Flags                   dd      ?
  89. ; Copy of flags from the call to usb_*_transfer_async.
  90. SoftwarePart            rd      sizeof.usb_gtd/4
  91. ; Software part, common for all controllers.
  92.                         rd      3       ; padding
  93. ends
  94.  
  95. if sizeof.ehci_gtd mod 32
  96. .err ehci_gtd must be 32-bytes aligned
  97. end if
  98.  
  99. ; EHCI-specific part of a pipe descriptor.
  100. ; * This structure corresponds to the Queue Head from the EHCI specification.
  101. ; * The hardware requires 32-bytes alignment of the hardware part.
  102. ;   Since the allocator (usb_allocate_common) allocates memory sequentially
  103. ;   from page start (aligned on 0x1000 bytes), size of the structure must be
  104. ;   divisible by 32.
  105. ; * The hardware requires also that the hardware part must not cross page
  106. ;   boundary; the allocator satisfies this automatically.
  107. struct ehci_pipe
  108. NextQH                  dd      ?
  109. ; 1. First bit (bit 0) is Terminate bit, 1 = there is no next QH.
  110. ; 2. Next two bits (bits 1-2) are Type field of the next QH,
  111. ;    one of EHCI_TYPE_* constants.
  112. ; 3. Next two bits (bits 3-4) are reserved, must be zero.
  113. ; 4. With masked 5 lower bits, this is the physical address of the next object
  114. ;    to be processed, usually next QH.
  115. Token                   dd      ?
  116. ; 1. Lower 7 bits are DeviceAddress field. This is the address of the
  117. ;    target device on the USB bus.
  118. ; 2. Next bit (bit 7) is Inactivate-on-next-transaction bit. Can be nonzero
  119. ;    only for interrupt/isochronous USB1 endpoints.
  120. ; 3. Next 4 bits (bits 8-11) are Endpoint field. This is the target endpoint
  121. ;    number.
  122. ; 4. Next 2 bits (bits 12-13) are EndpointSpeed field, one of EHCI_SPEED_*.
  123. ; 5. Next bit (bit 14) is DataToggleControl bit,
  124. ;    0 = use DataToggle bit from QH, 1 = from TD.
  125. ; 6. Next bit (bit 15) is Head-of-reclamation-list. The head of Control list
  126. ;    has 1 here, all other QHs have zero.
  127. ; 7. Next 11 bits (bits 16-26) are MaximumPacketLength field for the target
  128. ;    endpoint.
  129. ; 8. Next bit (bit 27) is ControlEndpoint bit, must be 1 for USB1 control
  130. ;    endpoints and 0 for all others.
  131. ; 9. Upper 4 bits (bits 28-31) are NakCountReload field.
  132. ;    Zero for USB1 endpoints, zero for periodic endpoints.
  133. ;    For control/bulk USB2 endpoints, the code sets it to 4,
  134. ;    which is rather arbitrary.
  135. Flags                   dd      ?
  136. ; 1. Lower byte is S-mask, each bit corresponds to one microframe per frame;
  137. ;    bit is set <=> enable transactions in this microframe.
  138. ; 2. Next byte is C-mask, each bit corresponds to one microframe per frame;
  139. ;    bit is set <=> enable complete-split transactions in this microframe.
  140. ;    Meaningful only for USB1 endpoints.
  141. ; 3. Next 14 bits give address of the target device as hub:port, bits 16-22
  142. ;    are the USB address of the hub, bits 23-29 are the port number.
  143. ;    Meaningful only for USB1 endpoints.
  144. ; 4. Upper 2 bits define number of consequetive transactions per micro-frame
  145. ;    which host is allowed to permit for this endpoint.
  146. ;    For control/bulk endpoints, it must be 1.
  147. ;    For periodic endpoints, the value is taken from the endpoint descriptor.
  148. HeadTD                  dd      ?
  149. ; The physical address of the first TD for this pipe.
  150. ; Lower 5 bits must be zero.
  151. Overlay                 ehci_hardware_td        ?
  152. ; Working area for the current TD, if there is any.
  153. ; When TD is retired, it is written to that TD and Overlay is loaded
  154. ; from the new TD, if any.
  155. BaseList                dd      ?
  156. ; Pointer to head of the corresponding pipe list.
  157. SoftwarePart            rd      sizeof.usb_pipe/4
  158. ; Software part, common for all controllers.
  159.                         rd      2       ; padding
  160. ends
  161.  
  162. if sizeof.ehci_pipe mod 32
  163. .err ehci_pipe must be 32-bytes aligned
  164. end if
  165.  
  166. ; This structure describes the static head of every list of pipes.
  167. ; The hardware requires 32-bytes alignment of this structure.
  168. ; All instances of this structure are located sequentially in ehci_controller,
  169. ; ehci_controller is page-aligned, so it is sufficient to make this structure
  170. ; 32-bytes aligned and verify that the first instance is 32-bytes aligned
  171. ; inside ehci_controller.
  172. ; The hardware also requires that 44h bytes (size of 64-bit Queue Head
  173. ; Descriptor) starting at the beginning of this structure must not cross page
  174. ; boundary. If not, most hardware still behaves correctly (in fact, the last
  175. ; dword can have any value and this structure is never written), but on some
  176. ; hardware some things just break in mysterious ways.
  177. struct ehci_static_ep
  178. ; Hardware fields are the same as in ehci_pipe.
  179. ; Only NextQH and Overlay.Token are actually used.
  180. ; NB: some emulators ignore Token.Halted bit (probably assuming that it is set
  181. ; only when device fails and emulation never fails) and always follow
  182. ; [Alternate]NextTD when they see that OverlayToken.Active bit is zero;
  183. ; so it is important to also set [Alternate]NextTD to 1.
  184. NextQH          dd      ?
  185. Token           dd      ?
  186. Flags           dd      ?
  187. HeadTD          dd      ?
  188. NextTD          dd      ?
  189. AlternateNextTD dd      ?
  190. OverlayToken    dd      ?
  191. NextList        dd      ?
  192. SoftwarePart    rd      sizeof.usb_static_ep/4
  193. Bandwidths      rw      8
  194.                 dd      ?
  195. ends
  196.  
  197. if sizeof.ehci_static_ep mod 32
  198. .err ehci_static_ep must be 32-bytes aligned
  199. end if
  200.  
  201. if ehci_static_ep.OverlayToken <> ehci_pipe.Overlay.Token
  202. .err ehci_static_ep.OverlayToken misplaced
  203. end if
  204.  
  205. ; EHCI-specific part of controller data.
  206. ; * The structure includes two parts, the hardware part and the software part.
  207. ; * The hardware part consists of first 4096 bytes and corresponds to
  208. ;   the Periodic Frame List from the EHCI specification.
  209. ; * The hardware requires page-alignment of the hardware part, so
  210. ;   the entire descriptor must be page-aligned.
  211. ;   This structure is allocated with kernel_alloc (see usb_init_controller),
  212. ;   this gives page-aligned data.
  213. ; * The controller is described by both ehci_controller and usb_controller
  214. ;   structures, for each controller there is one ehci_controller and one
  215. ;   usb_controller structure. These structures are located sequentially
  216. ;   in the memory: beginning from some page start, there is ehci_controller
  217. ;   structure - this enforces hardware alignment requirements - and then
  218. ;   usb_controller structure.
  219. ; * The code keeps pointer to usb_controller structure. The ehci_controller
  220. ;   structure is addressed as [ptr + ehci_controller.field - sizeof.ehci_controller].
  221. struct ehci_controller
  222. ; ------------------------------ hardware fields ------------------------------
  223. FrameList               rd      1024
  224. ; Entry n corresponds to the head of the frame list to be executed in
  225. ; the frames n,n+1024,n+2048,n+3096,...
  226. ; The first bit of each entry is Terminate bit, 1 = the frame is empty.
  227. ; Bits 1-2 are Type field, one of EHCI_TYPE_* constants.
  228. ; Bits 3-4 must be zero.
  229. ; With masked 5 lower bits, the entry is a physical address of the first QH/TD
  230. ; to be executed.
  231. ; ------------------------------ software fields ------------------------------
  232. ; Every list has the static head, which is an always halted QH.
  233. ; The following fields are static heads, one per list:
  234. ; 32+16+8+4+2+1 = 63 for Periodic lists, 1 for Control list and 1 for Bulk list.
  235. IntEDs                  ehci_static_ep
  236.                         rb      62 * sizeof.ehci_static_ep
  237. ; Beware.
  238. ; Two following strings ensure that 44h bytes at any static head
  239. ; do not cross page boundary. Without that, the code "works on my machine"...
  240. ; but fails on some hardware in seemingly unrelated ways.
  241. ; One hardware TD (without any software fields) fit in the rest of the page.
  242. ehci_controller.ControlDelta = 2000h - (ehci_controller.IntEDs + 63 * sizeof.ehci_static_ep)
  243. StopQueueTD             ehci_hardware_td
  244. ; Used as AlternateNextTD for transfers when short packet is considered
  245. ; as an error; short packet must stop the queue in this case, not advance
  246. ; to the next transfer.
  247.                         rb      ehci_controller.ControlDelta - sizeof.ehci_hardware_td
  248. ; Padding for page-alignment.
  249. ControlED               ehci_static_ep
  250. BulkED                  ehci_static_ep
  251. MMIOBase1               dd      ?
  252. ; Virtual address of memory-mapped area with part 1 of EHCI registers EhciXxxReg.
  253. MMIOBase2               dd      ?
  254. ; Pointer inside memory-mapped area MMIOBase1; points to part 2 of EHCI registers.
  255. StructuralParams        dd      ?
  256. ; Copy of EhciStructParamsReg value.
  257. CapabilityParams        dd      ?
  258. ; Copy of EhciCapParamsReg value.
  259. DeferredActions         dd      ?
  260. ; Bitmask of events from EhciStatusReg which were observed by the IRQ handler
  261. ; and needs to be processed in the IRQ thread.
  262. ends
  263.  
  264. if ehci_controller.IntEDs mod 32
  265. .err Static endpoint descriptors must be 32-bytes aligned inside ehci_controller
  266. end if
  267.  
  268. ; Description of #HCI-specific data and functions for
  269. ; controller-independent code.
  270. ; Implements the structure usb_hardware_func from hccommon.inc for EHCI.
  271. iglobal
  272. align 4
  273. ehci_hardware_func:
  274.         dd      'EHCI'
  275.         dd      sizeof.ehci_controller
  276.         dd      ehci_init
  277.         dd      ehci_process_deferred
  278.         dd      ehci_set_device_address
  279.         dd      ehci_get_device_address
  280.         dd      ehci_port_disable
  281.         dd      ehci_new_port.reset
  282.         dd      ehci_set_endpoint_packet_size
  283.         dd      ehci_alloc_pipe
  284.         dd      ehci_free_pipe
  285.         dd      ehci_init_pipe
  286.         dd      ehci_unlink_pipe
  287.         dd      ehci_alloc_td
  288.         dd      ehci_free_td
  289.         dd      ehci_alloc_transfer
  290.         dd      ehci_insert_transfer
  291.         dd      ehci_new_device
  292. endg
  293.  
  294. ; =============================================================================
  295. ; =================================== Code ====================================
  296. ; =============================================================================
  297.  
  298. ; Controller-specific initialization function.
  299. ; Called from usb_init_controller. Initializes the hardware and
  300. ; EHCI-specific parts of software structures.
  301. ; eax = pointer to ehci_controller to be initialized
  302. ; [ebp-4] = pcidevice
  303. proc ehci_init
  304. ; inherit some variables from the parent (usb_init_controller)
  305. .devfn   equ ebp - 4
  306. .bus     equ ebp - 3
  307. ; 1. Store pointer to ehci_controller for further use.
  308.         push    eax
  309.         mov     edi, eax
  310.         mov     esi, eax
  311. ; 2. Initialize ehci_controller.FrameList.
  312. ; Note that FrameList is located in the beginning of ehci_controller,
  313. ; so esi and edi now point to ehci_controller.FrameList.
  314. ; First 32 entries of FrameList contain physical addresses
  315. ; of first 32 Periodic static heads, further entries duplicate these.
  316. ; See the description of structures for full info.
  317. ; 2a. Get physical address of first static head.
  318. ; Note that 1) it is located in the beginning of a page
  319. ; and 2) first 32 static heads fit in the same page,
  320. ; so one call to get_phys_addr without correction of lower 12 bits
  321. ; is sufficient.
  322. if (ehci_controller.IntEDs / 0x1000) <> ((ehci_controller.IntEDs + 32 * sizeof.ehci_static_ep) / 0x1000)
  323. .err assertion failed
  324. end if
  325. if (ehci_controller.IntEDs mod 0x1000) <> 0
  326. .err assertion failed
  327. end if
  328.         add     eax, ehci_controller.IntEDs
  329.         call    get_phys_addr
  330. ; 2b. Fill first 32 entries.
  331.         inc     eax
  332.         inc     eax     ; set Type to EHCI_TYPE_QH
  333.         push    32
  334.         pop     ecx
  335.         mov     edx, ecx
  336. @@:
  337.         stosd
  338.         add     eax, sizeof.ehci_static_ep
  339.         loop    @b
  340. ; 2c. Fill the rest entries.
  341.         mov     ecx, 1024 - 32
  342.         rep movsd
  343. ; 3. Initialize static heads ehci_controller.*ED.
  344. ; Use the loop over groups: first group consists of first 32 Periodic
  345. ; descriptors, next group consists of next 16 Periodic descriptors,
  346. ; ..., last group consists of the last Periodic descriptor.
  347. ; 3a. Prepare for the loop.
  348. ; make esi point to the second group, other registers are already set.
  349.         add     esi, 32*4 + 32*sizeof.ehci_static_ep
  350. ; 3b. Loop over groups. On every iteration:
  351. ; edx = size of group, edi = pointer to the current group,
  352. ; esi = pointer to the next group.
  353. .init_static_eds:
  354. ; 3c. Get the size of next group.
  355.         shr     edx, 1
  356. ; 3d. Exit the loop if there is no next group.
  357.         jz      .init_static_eds_done
  358. ; 3e. Initialize the first half of the current group.
  359. ; Advance edi to the second half.
  360.         push    esi
  361.         call    ehci_init_static_ep_group
  362.         pop     esi
  363. ; 3f. Initialize the second half of the current group
  364. ; with the same values.
  365. ; Advance edi to the next group, esi/eax to the next of the next group.
  366.         call    ehci_init_static_ep_group
  367.         jmp     .init_static_eds
  368. .init_static_eds_done:
  369. ; 3g. Initialize the last static head.
  370.         xor     esi, esi
  371.         call    ehci_init_static_endpoint
  372. ; While we are here, initialize StopQueueTD.
  373. if (ehci_controller.StopQueueTD <> ehci_controller.IntEDs + 63 * sizeof.ehci_static_ep)
  374. .err assertion failed
  375. end if
  376.         inc     [edi+ehci_hardware_td.NextTD]   ; 0 -> 1
  377.         inc     [edi+ehci_hardware_td.AlternateNextTD]  ; 0 -> 1
  378. ; leave other fields as zero, including Active bit
  379. ; 3i. Initialize the head of Control list.
  380.         add     edi, ehci_controller.ControlDelta
  381.         lea     esi, [edi+sizeof.ehci_static_ep]
  382.         call    ehci_init_static_endpoint
  383.         or      byte [edi-sizeof.ehci_static_ep+ehci_static_ep.Token+1], 80h
  384. ; 3j. Initialize the head of Bulk list.
  385.         sub     esi, sizeof.ehci_static_ep
  386.         call    ehci_init_static_endpoint
  387. ; 4. Create a virtual memory area to talk with the controller.
  388. ; 4a. Enable memory & bus master access.
  389.         mov     ch, [.bus]
  390.         mov     cl, 1
  391.         mov     eax, ecx
  392.         mov     bh, [.devfn]
  393.         mov     bl, 4
  394.         call    pci_read_reg
  395.         or      al, 6
  396.         xchg    eax, ecx
  397.         call    pci_write_reg
  398. ; 4b. Read memory base address.
  399.         mov     ah, [.bus]
  400.         mov     al, 2
  401.         mov     bl, 10h
  402.         call    pci_read_reg
  403. ;       DEBUGF 1,'K : phys MMIO %x\n',eax
  404.         and     al, not 0Fh
  405. ; 4c. Create mapping for physical memory. 200h bytes are always sufficient.
  406.         stdcall map_io_mem, eax, 200h, PG_SW+PG_NOCACHE
  407.         test    eax, eax
  408.         jz      .fail
  409. ;       DEBUGF 1,'K : MMIO %x\n',eax
  410. if ehci_controller.MMIOBase1 <> ehci_controller.BulkED + sizeof.ehci_static_ep
  411. .err assertion failed
  412. end if
  413.         stosd   ; fill ehci_controller.MMIOBase1
  414.         movzx   ecx, byte [eax+EhciCapLengthReg]
  415.         mov     edx, [eax+EhciCapParamsReg]
  416.         mov     ebx, [eax+EhciStructParamsReg]
  417.         add     eax, ecx
  418. if ehci_controller.MMIOBase2 <> ehci_controller.MMIOBase1 + 4
  419. .err assertion failed
  420. end if
  421.         stosd   ; fill ehci_controller.MMIOBase2
  422. if ehci_controller.StructuralParams <> ehci_controller.MMIOBase2 + 4
  423. .err assertion failed
  424. end if
  425. if ehci_controller.CapabilityParams <> ehci_controller.StructuralParams + 4
  426. .err assertion failed
  427. end if
  428.         mov     [edi], ebx      ; fill ehci_controller.StructuralParams
  429.         mov     [edi+4], edx    ; fill ehci_controller.CapabilityParams
  430.         DEBUGF 1,'K : HCSPARAMS=%x, HCCPARAMS=%x\n',ebx,edx
  431.         and     ebx, 15
  432.         mov     [edi+usb_controller.NumPorts+sizeof.ehci_controller-ehci_controller.StructuralParams], ebx
  433.         mov     edi, eax
  434. ; now edi = MMIOBase2
  435. ; 6. Transfer the controller to a known state.
  436. ; 6b. Stop the controller if it is running.
  437.         push    10
  438.         pop     ecx
  439.         test    dword [edi+EhciStatusReg], 1 shl 12
  440.         jnz     .stopped
  441.         and     dword [edi+EhciCommandReg], not 1
  442. @@:
  443.         push    1
  444.         pop     esi
  445.         call    delay_ms
  446.         test    dword [edi+EhciStatusReg], 1 shl 12
  447.         jnz     .stopped
  448.         loop    @b
  449.         dbgstr 'Failed to stop EHCI controller'
  450.         jmp     .fail_unmap
  451. .stopped:
  452. ; 6c. Reset the controller. Wait up to 50 ms checking status every 1 ms.
  453.         or      dword [edi+EhciCommandReg], 2
  454.         push    50
  455.         pop     ecx
  456. @@:
  457.         push    1
  458.         pop     esi
  459.         call    delay_ms
  460.         test    dword [edi+EhciCommandReg], 2
  461.         jz      .reset_ok
  462.         loop    @b
  463.         dbgstr 'Failed to reset EHCI controller'
  464.         jmp     .fail_unmap
  465. .reset_ok:
  466. ; 7. Configure the controller.
  467.         pop     esi     ; restore the pointer saved at step 1
  468.         add     esi, sizeof.ehci_controller
  469. ; 7a. If the controller is 64-bit, say to it that all structures are located
  470. ; in first 4G.
  471.         test    byte [esi+ehci_controller.CapabilityParams-sizeof.ehci_controller], 1
  472.         jz      @f
  473.         mov     dword [edi+EhciCtrlDataSegReg], 0
  474. @@:
  475. ; 7b. Hook interrupt and enable appropriate interrupt sources.
  476.         mov     ah, [.bus]
  477.         mov     al, 0
  478.         mov     bh, [.devfn]
  479.         mov     bl, 3Ch
  480.         call    pci_read_reg
  481. ; al = IRQ
  482.         DEBUGF 1,'K : attaching to IRQ %x\n',al
  483.         movzx   eax, al
  484.         stdcall attach_int_handler, eax, ehci_irq, esi
  485. ;       mov     dword [edi+EhciStatusReg], 111111b      ; clear status
  486. ; disable Frame List Rollover interrupt, enable all other sources
  487.         mov     dword [edi+EhciInterruptReg], 110111b
  488. ; 7c. Inform the controller of the address of periodic lists head.
  489.         lea     eax, [esi-sizeof.ehci_controller]
  490.         call    get_phys_addr
  491.         mov     dword [edi+EhciPeriodicListReg], eax
  492. ; 7d. Inform the controller of the address of asynchronous lists head.
  493.         lea     eax, [esi+ehci_controller.ControlED-sizeof.ehci_controller]
  494.         call    get_phys_addr
  495.         mov     dword [edi+EhciAsyncListReg], eax
  496. ; 7e. Configure operational details and run the controller.
  497.         mov     dword [edi+EhciCommandReg], \
  498.                 (1 shl 16) + \ ; interrupt threshold = 1 microframe = 0.125ms
  499.                 (0 shl 11) + \ ; disable Async Park Mode
  500.                 (0 shl 8) +  \ ; zero Async Park Mode Count
  501.                 (1 shl 5) +  \ ; Async Schedule Enable
  502.                 (1 shl 4) +  \ ; Periodic Schedule Enable
  503.                 (0 shl 2) +  \ ; 1024 elements in FrameList
  504.                 1              ; Run
  505. ; 7f. Route all ports to this controller, not companion controllers.
  506.         mov     dword [edi+EhciConfigFlagReg], 1
  507.         DEBUGF 1,'K : EHCI controller at %x:%x with %d ports initialized\n',[.bus]:2,[.devfn]:2,[esi+usb_controller.NumPorts]
  508. ; 8. Apply port power, if needed, and disable all ports.
  509.         xor     ecx, ecx
  510. @@:
  511.         mov     dword [edi+EhciPortsReg+ecx*4], 1000h   ; Port Power enabled, all other bits disabled
  512.         inc     ecx
  513.         cmp     ecx, [esi+usb_controller.NumPorts]
  514.         jb      @b
  515.         test    byte [esi+ehci_controller.StructuralParams-sizeof.ehci_controller], 10h
  516.         jz      @f
  517.         push    esi
  518.         push    20
  519.         pop     esi
  520.         call    delay_ms
  521.         pop     esi
  522. @@:
  523.         DEBUGF 1,'K : EHCI %x: command = %x, status = %x\n',esi,[edi+EhciCommandReg],[edi+EhciStatusReg]
  524. ; 9. Return pointer to usb_controller.
  525.         xchg    eax, esi
  526.         ret
  527. ; On error, pop the pointer saved at step 1 and return zero.
  528. ; Note that the main code branch restores the stack at step 7 and never fails
  529. ; after step 7.
  530. .fail_unmap:
  531.         pop     eax
  532.         push    eax
  533.         stdcall free_kernel_space, [eax+ehci_controller.MMIOBase1]
  534. .fail:
  535.         pop     ecx
  536.         xor     eax, eax
  537.         ret
  538. endp
  539.  
  540. ; Helper procedure for step 3 of ehci_init, see comments there.
  541. ; Initializes the static head of one list.
  542. ; esi = pointer to the "next" list, edi = pointer to head to initialize.
  543. ; Advances edi to the next head, keeps esi.
  544. proc ehci_init_static_endpoint
  545.         xor     eax, eax
  546.         inc     eax     ; set Terminate bit
  547.         mov     [edi+ehci_static_ep.NextTD], eax
  548.         mov     [edi+ehci_static_ep.AlternateNextTD], eax
  549.         test    esi, esi
  550.         jz      @f
  551.         mov     eax, esi
  552.         call    get_phys_addr
  553.         inc     eax
  554.         inc     eax     ; set Type to EHCI_TYPE_QH
  555. @@:
  556.         mov     [edi+ehci_static_ep.NextQH], eax
  557.         mov     [edi+ehci_static_ep.NextList], esi
  558.         mov     byte [edi+ehci_static_ep.OverlayToken], 1 shl 6 ; halted
  559.         add     edi, ehci_static_ep.SoftwarePart
  560.         call    usb_init_static_endpoint
  561.         add     edi, sizeof.ehci_static_ep - ehci_static_ep.SoftwarePart
  562.         ret
  563. endp
  564.  
  565. ; Helper procedure for step 3 of ehci_init, see comments there.
  566. ; Initializes one half of group of static heads.
  567. ; edx = size of the next group = half of size of the group,
  568. ; edi = pointer to the group, esi = pointer to the next group.
  569. ; Advances esi, edi to next group, keeps edx.
  570. proc ehci_init_static_ep_group
  571.         push    edx
  572. @@:
  573.         call    ehci_init_static_endpoint
  574.         add     esi, sizeof.ehci_static_ep
  575.         dec     edx
  576.         jnz     @b
  577.         pop     edx
  578.         ret
  579. endp
  580.  
  581. ; Controller-specific pre-initialization function: take ownership from BIOS.
  582. ; Some BIOSes, although not all of them, use USB controllers themselves
  583. ; to support USB flash drives. In this case,
  584. ; we must notify the BIOS that we don't need that emulation and know how to
  585. ; deal with USB devices.
  586. proc ehci_kickoff_bios
  587. ; 1. Get the physical address of MMIO registers.
  588.         mov     ah, [esi+PCIDEV.bus]
  589.         mov     bh, [esi+PCIDEV.devfn]
  590.         mov     al, 2
  591.         mov     bl, 10h
  592.         call    pci_read_reg
  593.         and     al, not 0Fh
  594. ; 2. Create mapping for physical memory. 200h bytes are always sufficient.
  595.         stdcall map_io_mem, eax, 200h, PG_SW+PG_NOCACHE
  596.         test    eax, eax
  597.         jz      .nothing
  598.         push    eax     ; push argument for step 8
  599. ; 3. Some BIOSes enable controller interrupts as a result of giving
  600. ; controller away. At this point the system knows nothing about how to serve
  601. ; EHCI interrupts, so such an interrupt will send the system into an infinite
  602. ; loop handling the same IRQ again and again. Thus, we need to block EHCI
  603. ; interrupts. We can't do this at the controller level until step 5,
  604. ; because the controller is currently owned by BIOS, so we block all hardware
  605. ; interrupts on this processor until step 5.
  606.         pushf
  607.         cli
  608. ; 4. Take the ownership over the controller.
  609. ; 4a. Locate take-ownership capability in the PCI configuration space.
  610. ; Limit the loop with 100h iterations; since the entire configuration space is
  611. ; 100h bytes long, hitting this number of iterations means that something is
  612. ; corrupted.
  613. ; Use a value from MMIO as a starting point.
  614.         mov     edx, [eax+EhciCapParamsReg]
  615.         DEBUGF 1,'K : edx=%x\n',edx
  616.         movzx   edi, byte [eax+EhciCapLengthReg]
  617.         add     edi, eax
  618.         push    0
  619.         mov     bl, dh          ; get Extended Capabilities Pointer
  620.         test    bl, bl
  621.         jz      .has_ownership2
  622.         cmp     bl, 40h
  623.         jb      .no_capability
  624. .look_bios_handoff:
  625.         test    bl, 3
  626.         jnz     .no_capability
  627. ; In each iteration, read the current dword,
  628.         mov     ah, [esi+PCIDEV.bus]
  629.         mov     al, 2
  630.         mov     bh, [esi+PCIDEV.devfn]
  631.         call    pci_read_reg
  632. ; check, whether the capability ID is take-ownership ID = 1,
  633.         cmp     al, 1
  634.         jz      .found_bios_handoff
  635. ; if not, advance to next-capability link and continue loop.
  636.         dec     byte [esp]
  637.         jz      .no_capability
  638.         mov     bl, ah
  639.         cmp     bl, 40h
  640.         jae     .look_bios_handoff
  641. .no_capability:
  642.         dbgstr 'warning: cannot locate take-ownership capability'
  643.         jmp     .has_ownership2
  644. .found_bios_handoff:
  645. ; 4b. Check whether BIOS has ownership.
  646. ; Some BIOSes release ownership before loading OS, but forget to unwatch for
  647. ; change-ownership requests; they cannot handle ownership request, so
  648. ; such a request sends the system into infinite loop of handling the same SMI
  649. ; over and over. Avoid this.
  650.         inc     ebx
  651.         inc     ebx
  652.         test    eax, 0x10000
  653.         jz      .has_ownership
  654. ; 4c. Request ownership.
  655.         inc     ebx
  656.         mov     cl, 1
  657.         mov     ah, [esi+PCIDEV.bus]
  658.         mov     al, 0
  659.         call    pci_write_reg
  660. ; 4d. Some BIOSes set ownership flag, but forget to watch for change-ownership
  661. ; requests; if so, there is no sense in waiting.
  662.         inc     ebx
  663.         mov     ah, [esi+PCIDEV.bus]
  664.         mov     al, 2
  665.         call    pci_read_reg
  666.         dec     ebx
  667.         dec     ebx
  668.         test    ah, 20h
  669.         jz      .force_ownership
  670. ; 4e. Wait for result no more than 1 s, checking for status every 1 ms.
  671. ; If successful, go to 5.
  672.         mov     dword [esp], 1000
  673. @@:
  674.         mov     ah, [esi+PCIDEV.bus]
  675.         mov     al, 0
  676.         call    pci_read_reg
  677.         test    al, 1
  678.         jz      .has_ownership
  679.         push    esi
  680.         push    1
  681.         pop     esi
  682.         call    delay_ms
  683.         pop     esi
  684.         dec     dword [esp]
  685.         jnz     @b
  686.         dbgstr  'warning: taking EHCI ownership from BIOS timeout'
  687. .force_ownership:
  688. ; 4f. BIOS has not responded within the timeout.
  689. ; Let's just clear BIOS ownership flag and hope that everything will be ok.
  690.         mov     ah, [esi+PCIDEV.bus]
  691.         mov     al, 0
  692.         mov     cl, 0
  693.         call    pci_write_reg
  694. .has_ownership:
  695. ; 5. Just in case clear all SMI event sources except change-ownership.
  696.         dbgstr 'has_ownership'
  697.         inc     ebx
  698.         inc     ebx
  699.         mov     ah, [esi+PCIDEV.bus]
  700.         mov     al, 2
  701.         mov     ecx, eax
  702.         call    pci_read_reg
  703.         and     ax, 2000h
  704.         xchg    eax, ecx
  705.         call    pci_write_reg
  706. .has_ownership2:
  707.         pop     ecx
  708. ; 6. Disable all controller interrupts until the system will be ready to
  709. ; process them.
  710.         mov     dword [edi+EhciInterruptReg], 0
  711. ; 7. Now we can unblock interrupts in the processor.
  712.         popf
  713. ; 8. Release memory mapping created in step 2 and return.
  714.         call    free_kernel_space
  715. .nothing:
  716.         ret
  717. endp
  718.  
  719. ; IRQ handler for EHCI controllers.
  720. ehci_irq.noint:
  721.         spin_unlock_irqrestore [esi+usb_controller.WaitSpinlock]
  722. ; Not our interrupt: restore registers and return zero.
  723.         xor     eax, eax
  724.         pop     edi esi ebx
  725.         ret
  726.  
  727. proc ehci_irq
  728.         push    ebx esi edi     ; save registers to be cdecl
  729. virtual at esp
  730.         rd      3       ; saved registers
  731.         dd      ?       ; return address
  732. .controller     dd      ?
  733. end virtual
  734. ; 1. ebx will hold whether some deferred processing is needed,
  735. ; that cannot be done from the interrupt handler. Initialize to zero.
  736.         xor     ebx, ebx
  737. ; 2. Get the mask of events which should be processed.
  738.         mov     esi, [.controller]
  739.         mov     edi, [esi+ehci_controller.MMIOBase2-sizeof.ehci_controller]
  740.         spin_lock_irqsave [esi+usb_controller.WaitSpinlock]
  741.         mov     eax, [edi+EhciStatusReg]
  742.         mov     ecx, eax
  743. ;       DEBUGF 1,'K : [%d] EHCI status %x\n',[timer_ticks],eax
  744. ; 3. Check whether that interrupt has been generated by our controller.
  745. ; (One IRQ can be shared by several devices.)
  746.         and     eax, [edi+EhciInterruptReg]
  747.         jz      .noint
  748. ; 4. Clear the events we know of.
  749. ; Note that this should be done before processing of events:
  750. ; new events could arise while we are processing those, this way we won't lose
  751. ; them (the controller would generate another interrupt after completion
  752. ; of this one).
  753.         DEBUGF 1,'K : EHCI %x interrupt: status = %x, enable = %x\n',esi,ecx,[edi+EhciInterruptReg]
  754. ;       DEBUGF 1,'K : EHCI interrupt: status = %x\n',eax
  755.         mov     [edi+EhciStatusReg], eax
  756. ; 5. Sanity check.
  757.         test    al, 10h
  758.         jz      @f
  759.         DEBUGF 1,'K : something terrible happened with EHCI %x (%x)\n',esi,al
  760. @@:
  761. ; We can't do too much from an interrupt handler. Inform the processing thread
  762. ; that it should perform appropriate actions.
  763.         or      [esi+ehci_controller.DeferredActions-sizeof.ehci_controller], eax
  764.         spin_unlock_irqrestore [esi+usb_controller.WaitSpinlock]
  765.         inc     ebx
  766.         call    usb_wakeup_if_needed
  767. ; 6. Interrupt processed; return non-zero.
  768.         mov     al, 1
  769.         pop     edi esi ebx     ; restore used registers to be cdecl
  770.         ret
  771. endp
  772.  
  773. ; This procedure is called from usb_set_address_callback
  774. ; and stores USB device address in the ehci_pipe structure.
  775. ; in: esi -> usb_controller, ebx -> usb_pipe, cl = address
  776. proc ehci_set_device_address
  777.         mov     byte [ebx+ehci_pipe.Token-ehci_pipe.SoftwarePart], cl
  778.         call    usb_subscribe_control
  779.         ret
  780. endp
  781.  
  782. ; This procedure returns USB device address from the ehci_pipe structure.
  783. ; in: esi -> usb_controller, ebx -> usb_pipe
  784. ; out: eax = endpoint address
  785. proc ehci_get_device_address
  786.         mov     eax, [ebx+ehci_pipe.Token-ehci_pipe.SoftwarePart]
  787.         and     eax, 7Fh
  788.         ret
  789. endp
  790.  
  791. ; This procedure is called from usb_set_address_callback
  792. ; if the device does not accept SET_ADDRESS command and needs
  793. ; to be disabled at the port level.
  794. ; in: esi -> usb_controller, ecx = port (zero-based)
  795. proc ehci_port_disable
  796.         mov     eax, [esi+ehci_controller.MMIOBase2-sizeof.ehci_controller]
  797.         and     dword [eax+EhciPortsReg+ecx*4], not (4 or 2Ah)
  798.         ret
  799. endp
  800.  
  801. ; This procedure is called from usb_get_descr8_callback when
  802. ; the packet size for zero endpoint becomes known and
  803. ; stores the packet size in ehci_pipe structure.
  804. ; in: esi -> usb_controller, ebx -> usb_pipe, ecx = packet size
  805. proc ehci_set_endpoint_packet_size
  806.         mov     eax, [ebx+ehci_pipe.Token-ehci_pipe.SoftwarePart]
  807.         and     eax, not (0x7FF shl 16)
  808.         shl     ecx, 16
  809.         or      eax, ecx
  810.         mov     [ebx+ehci_pipe.Token-ehci_pipe.SoftwarePart], eax
  811. ; Wait until hardware cache is evicted.
  812.         call    usb_subscribe_control
  813.         ret
  814. endp
  815.  
  816. uglobal
  817. align 4
  818. ; Data for memory allocator, see memory.inc.
  819. ehci_ep_first_page      dd      ?
  820. ehci_ep_mutex           MUTEX
  821. ehci_gtd_first_page     dd      ?
  822. ehci_gtd_mutex          MUTEX
  823. endg
  824.  
  825. ; This procedure allocates memory for pipe.
  826. ; Both hardware+software parts must be allocated, returns pointer to usb_pipe
  827. ; (software part).
  828. proc ehci_alloc_pipe
  829.         push    ebx
  830.         mov     ebx, ehci_ep_mutex
  831.         stdcall usb_allocate_common, sizeof.ehci_pipe
  832.         test    eax, eax
  833.         jz      @f
  834.         add     eax, ehci_pipe.SoftwarePart
  835. @@:
  836.         pop     ebx
  837.         ret
  838. endp
  839.  
  840. ; This procedure frees memory for pipe allocated by ehci_alloc_pipe.
  841. ; void stdcall with one argument = pointer to usb_pipe.
  842. proc ehci_free_pipe
  843. virtual at esp
  844.         dd      ?       ; return address
  845. .ptr    dd      ?
  846. end virtual
  847.         sub     [.ptr], ehci_pipe.SoftwarePart
  848.         jmp     usb_free_common
  849. endp
  850.  
  851. ; This procedure is called from API usb_open_pipe and processes
  852. ; the controller-specific part of this API. See docs.
  853. ; in: edi -> usb_pipe for target, ecx -> usb_pipe for config pipe,
  854. ; esi -> usb_controller, eax -> usb_gtd for the first TD,
  855. ; [ebp+12] = endpoint, [ebp+16] = maxpacket, [ebp+20] = type
  856. proc ehci_init_pipe
  857. virtual at ebp+8
  858. .config_pipe    dd      ?
  859. .endpoint       dd      ?
  860. .maxpacket      dd      ?
  861. .type           dd      ?
  862. .interval       dd      ?
  863. end virtual
  864. ; 1. Zero all fields in the hardware part.
  865.         push    eax ecx
  866.         sub     edi, ehci_pipe.SoftwarePart
  867.         xor     eax, eax
  868.         push    ehci_pipe.SoftwarePart/4
  869.         pop     ecx
  870.         rep stosd
  871.         pop     ecx eax
  872. ; 2. Setup PID in the first TD and make sure that the it is not active.
  873.         xor     edx, edx
  874.         test    byte [.endpoint], 80h
  875.         setnz   dh
  876.         mov     [eax+ehci_gtd.Token-ehci_gtd.SoftwarePart], edx
  877.         mov     [eax+ehci_gtd.NextTD-ehci_gtd.SoftwarePart], 1
  878.         mov     [eax+ehci_gtd.AlternateNextTD-ehci_gtd.SoftwarePart], 1
  879. ; 3. Store physical address of the first TD.
  880.         sub     eax, ehci_gtd.SoftwarePart
  881.         call    get_phys_addr
  882.         mov     [edi+ehci_pipe.Overlay.NextTD-ehci_pipe.SoftwarePart], eax
  883. ; 4. Fill ehci_pipe.Flags except for S- and C-masks.
  884. ; Copy location from the config pipe.
  885.         mov     eax, [ecx+ehci_pipe.Flags-ehci_pipe.SoftwarePart]
  886.         and     eax, 3FFF0000h
  887. ; Use 1 requests per microframe for control/bulk endpoints,
  888. ; use value from the endpoint descriptor for periodic endpoints
  889.         push    1
  890.         pop     edx
  891.         test    [.type], 1
  892.         jz      @f
  893.         mov     edx, [.maxpacket]
  894.         shr     edx, 11
  895.         inc     edx
  896. @@:
  897.         shl     edx, 30
  898.         or      eax, edx
  899.         mov     [edi+ehci_pipe.Flags-ehci_pipe.SoftwarePart], eax
  900. ; 5. Fill ehci_pipe.Token.
  901.         mov     eax, [ecx+ehci_pipe.Token-ehci_pipe.SoftwarePart]
  902. ; copy following fields from the config pipe:
  903. ; DeviceAddress, EndpointSpeed, ControlEndpoint if new type is control
  904.         mov     ecx, eax
  905.         and     eax, 307Fh
  906.         and     ecx, 8000000h
  907.         or      ecx, 4000h
  908.         mov     edx, [.endpoint]
  909.         and     edx, 15
  910.         shl     edx, 8
  911.         or      eax, edx
  912.         mov     edx, [.maxpacket]
  913.         shl     edx, 16
  914.         or      eax, edx
  915. ; for control endpoints, use DataToggle from TD, otherwise use DataToggle from QH
  916.         cmp     [.type], CONTROL_PIPE
  917.         jnz     @f
  918.         or      eax, ecx
  919. @@:
  920. ; for control/bulk USB2 endpoints, set NakCountReload to 4
  921.         test    eax, USB_SPEED_HS shl 12
  922.         jz      .nonak
  923.         cmp     [.type], CONTROL_PIPE
  924.         jz      @f
  925.         cmp     [.type], BULK_PIPE
  926.         jnz     .nonak
  927. @@:
  928.         or      eax, 40000000h
  929. .nonak:
  930.         mov     [edi+ehci_pipe.Token-ehci_pipe.SoftwarePart], eax
  931. ; 5. Select the corresponding list and insert to the list.
  932. ; 5a. Use Control list for control pipes, Bulk list for bulk pipes.
  933.         lea     edx, [esi+ehci_controller.ControlED.SoftwarePart-sizeof.ehci_controller]
  934.         cmp     [.type], BULK_PIPE
  935.         jb      .insert ; control pipe
  936.         lea     edx, [esi+ehci_controller.BulkED.SoftwarePart-sizeof.ehci_controller]
  937.         jz      .insert ; bulk pipe
  938. .interrupt_pipe:
  939. ; 5b. For interrupt pipes, let the scheduler select the appropriate list
  940. ; and the appropriate microframe(s) (which goes to S-mask and C-mask)
  941. ; based on the current bandwidth distribution and the requested bandwidth.
  942. ; There are two schedulers, one for high-speed devices,
  943. ; another for split transactions.
  944. ; This could fail if the requested bandwidth is not available;
  945. ; if so, return an error.
  946.         test    word [edi+ehci_pipe.Flags-ehci_pipe.SoftwarePart+2], 3FFFh
  947.         jnz     .interrupt_fs
  948.         call    ehci_select_hs_interrupt_list
  949.         jmp     .interrupt_common
  950. .interrupt_fs:
  951.         call    ehci_select_fs_interrupt_list
  952. .interrupt_common:
  953.         test    edx, edx
  954.         jz      .return0
  955.         mov     word [edi+ehci_pipe.Flags-ehci_pipe.SoftwarePart], ax
  956. .insert:
  957.         mov     [edi+ehci_pipe.BaseList-ehci_pipe.SoftwarePart], edx
  958. ; Insert to the head of the corresponding list.
  959. ; Note: inserting to the head guarantees that the list traverse in
  960. ; ehci_process_updated_schedule, once started, will not interact with new pipes.
  961. ; However, we still need to ensure that links in the new pipe (edi.NextVirt)
  962. ; are initialized before links to the new pipe (edx.NextVirt).
  963. ; 5c. Insert in the list of virtual addresses.
  964.         mov     ecx, [edx+usb_pipe.NextVirt]
  965.         mov     [edi+usb_pipe.NextVirt], ecx
  966.         mov     [edi+usb_pipe.PrevVirt], edx
  967.         mov     [ecx+usb_pipe.PrevVirt], edi
  968.         mov     [edx+usb_pipe.NextVirt], edi
  969. ; 5d. Insert in the hardware list: copy previous NextQH to the new pipe,
  970. ; store the physical address of the new pipe to previous NextQH.
  971.         mov     ecx, [edx+ehci_static_ep.NextQH-ehci_static_ep.SoftwarePart]
  972.         mov     [edi+ehci_pipe.NextQH-ehci_pipe.SoftwarePart], ecx
  973.         lea     eax, [edi-ehci_pipe.SoftwarePart]
  974.         call    get_phys_addr
  975.         inc     eax
  976.         inc     eax
  977.         mov     [edx+ehci_static_ep.NextQH-ehci_static_ep.SoftwarePart], eax
  978. ; 6. Return with nonzero eax.
  979.         ret
  980. .return0:
  981.         xor     eax, eax
  982.         ret
  983. endp
  984.  
  985. ; This function is called from ehci_process_deferred when
  986. ; a new device was connected at least USB_CONNECT_DELAY ticks
  987. ; and therefore is ready to be configured.
  988. ; ecx = port, esi -> ehci_controller, edi -> EHCI MMIO
  989. proc ehci_new_port
  990. ; 1. If the device operates at low-speed, just release it to a companion.
  991.         mov     eax, [edi+EhciPortsReg+ecx*4]
  992.         DEBUGF 1,'K : [%d] EHCI %x port %d state is %x\n',[timer_ticks],esi,ecx,eax
  993.         mov     edx, eax
  994.         and     ah, 0Ch
  995.         cmp     ah, 4
  996.         jz      .low_speed
  997. ; 2. Devices operating at full-speed and high-speed must now have ah == 8.
  998. ; Some broken hardware asserts both D+ and D- even after initial decoupling;
  999. ; if so, stop initialization here, no sense in further actions.
  1000.         cmp     ah, 0Ch
  1001.         jz      .se1
  1002. ; 3. If another port is resetting right now, mark this port as 'reset pending'
  1003. ; and return.
  1004.         bts     [esi+usb_controller.PendingPorts], ecx
  1005.         cmp     [esi+usb_controller.ResettingPort], -1
  1006.         jnz     .nothing
  1007.         btr     [esi+usb_controller.PendingPorts], ecx
  1008. ; Otherwise, fall through to ohci_new_port.reset.
  1009.  
  1010. ; This function is called from ehci_new_port and usb_test_pending_port.
  1011. ; It starts reset signalling for the port. Note that in USB first stages
  1012. ; of configuration can not be done for several ports in parallel.
  1013. .reset:
  1014.         push    edi
  1015.         mov     edi, [esi+ehci_controller.MMIOBase2-sizeof.ehci_controller]
  1016.         mov     eax, [edi+EhciPortsReg+ecx*4]
  1017. ; 1. Store information about resetting hub (roothub) and port.
  1018.         and     [esi+usb_controller.ResettingHub], 0
  1019.         mov     [esi+usb_controller.ResettingPort], cl
  1020. ; 2. Initiate reset signalling.
  1021.         or      ah, 1
  1022.         and     al, not (4 or 2Ah)
  1023.         mov     [edi+EhciPortsReg+ecx*4], eax
  1024. ; 3. Store the current time and set status to 1 = reset signalling active.
  1025.         mov     eax, [timer_ticks]
  1026.         mov     [esi+usb_controller.ResetTime], eax
  1027.         mov     [esi+usb_controller.ResettingStatus], 1
  1028. ;       dbgstr 'high-speed or full-speed device, resetting'
  1029.         DEBUGF 1,'K : [%d] EHCI %x: port %d has HS or FS device, resetting\n',[timer_ticks],esi,ecx
  1030.         pop     edi
  1031. .nothing:
  1032.         ret
  1033. .low_speed:
  1034. ;       dbgstr 'low-speed device, releasing'
  1035.         DEBUGF 1,'K : [%d] EHCI %x: port %d has LS device, releasing\n',[timer_ticks],esi,ecx
  1036.         or      dh, 20h
  1037.         and     dl, not 2Ah
  1038.         mov     [edi+EhciPortsReg+ecx*4], edx
  1039.         ret
  1040. .se1:
  1041.         dbgstr 'SE1 after connect debounce. Broken hardware?'
  1042.         ret
  1043. endp
  1044.  
  1045. ; This procedure is called from several places in main USB code
  1046. ; and allocates required packets for the given transfer.
  1047. ; ebx = pipe, other parameters are passed through the stack:
  1048. ; buffer,size = data to transfer
  1049. ; flags = same as in usb_open_pipe: bit 0 = allow short transfer, other bits reserved
  1050. ; td = pointer to the current end-of-queue descriptor
  1051. ; direction =
  1052. ;   0000b for normal transfers,
  1053. ;   1000b for control SETUP transfer,
  1054. ;   1101b for control OUT transfer,
  1055. ;   1110b for control IN transfer
  1056. ; returns eax = pointer to the new end-of-queue descriptor
  1057. ; (not included in the queue itself) or 0 on error
  1058. proc ehci_alloc_transfer stdcall uses edi, \
  1059.         buffer:dword, size:dword, flags:dword, td:dword, direction:dword
  1060. locals
  1061. origTD          dd      ?
  1062. packetSize      dd      ?       ; must be last variable, see usb_init_transfer
  1063. endl
  1064. ; 1. Save original value of td:
  1065. ; it will be useful for rollback if something would fail.
  1066.         mov     eax, [td]
  1067.         mov     [origTD], eax
  1068. ; One transfer descriptor can describe up to 5 pages.
  1069. ; In the worst case (when the buffer is something*1000h+0FFFh)
  1070. ; this corresponds to 4001h bytes. If the requested size is
  1071. ; greater, we should split the transfer into several descriptors.
  1072. ; Boundaries to split must be multiples of endpoint transfer size
  1073. ; to avoid short packets except in the end of the transfer,
  1074. ; 4000h is always a good value.
  1075. ; 2. While the remaining data cannot fit in one descriptor,
  1076. ; allocate full descriptors (of maximal possible size).
  1077.         mov     edi, 4000h
  1078.         mov     [packetSize], edi
  1079. .fullpackets:
  1080.         cmp     [size], edi
  1081.         jbe     .lastpacket
  1082.         call    ehci_alloc_packet
  1083.         test    eax, eax
  1084.         jz      .fail
  1085.         mov     [td], eax
  1086.         add     [buffer], edi
  1087.         sub     [size], edi
  1088.         jmp     .fullpackets
  1089. ; 3. The remaining data can fit in one packet;
  1090. ; allocate the last descriptor with size = size of remaining data.
  1091. .lastpacket:
  1092.         mov     eax, [size]
  1093.         mov     [packetSize], eax
  1094.         call    ehci_alloc_packet
  1095.         test    eax, eax
  1096.         jz      .fail
  1097. ; 9. Update flags in the last packet.
  1098.         mov     edx, [flags]
  1099.         mov     [ecx+ehci_gtd.Flags-ehci_gtd.SoftwarePart], edx
  1100. ; 10. Fill AlternateNextTD field in all allocated TDs.
  1101. ; If the caller says that short transfer is ok, the queue must advance to
  1102. ; the next descriptor, which is in eax.
  1103. ; Otherwise, the queue should stop, so make AlternateNextTD point to
  1104. ; always-inactive descriptor StopQueueTD.
  1105.         push    eax
  1106.         test    dl, 1
  1107.         jz      .disable_short
  1108.         sub     eax, ehci_gtd.SoftwarePart
  1109.         jmp     @f
  1110. .disable_short:
  1111.         mov     eax, [ebx+usb_pipe.Controller]
  1112.         add     eax, ehci_controller.StopQueueTD - sizeof.ehci_controller
  1113. @@:
  1114.         call    get_phys_addr
  1115.         mov     edx, [origTD]
  1116. @@:
  1117.         cmp     edx, [esp]
  1118.         jz      @f
  1119.         mov     [edx+ehci_gtd.AlternateNextTD-ehci_gtd.SoftwarePart], eax
  1120.         mov     edx, [edx+usb_gtd.NextVirt]
  1121.         jmp     @b
  1122. @@:
  1123.         pop     eax
  1124.         ret
  1125. .fail:
  1126.         mov     edi, ehci_hardware_func
  1127.         mov     eax, [td]
  1128.         stdcall usb_undo_tds, [origTD]
  1129.         xor     eax, eax
  1130.         ret
  1131. endp
  1132.  
  1133. ; Helper procedure for ehci_alloc_transfer.
  1134. ; Allocates and initializes one transfer descriptor.
  1135. ; ebx = pipe, other parameters are passed through the stack;
  1136. ; fills the current last descriptor and
  1137. ; returns eax = next descriptor (not filled).
  1138. proc ehci_alloc_packet
  1139. ; inherit some variables from the parent ehci_alloc_transfer
  1140. virtual at ebp-8
  1141. .origTD         dd      ?
  1142. .packetSize     dd      ?
  1143.                 rd      2
  1144. .buffer         dd      ?
  1145. .transferSize   dd      ?
  1146. .Flags          dd      ?
  1147. .td             dd      ?
  1148. .direction      dd      ?
  1149. end virtual
  1150. ; 1. Allocate the next TD.
  1151.         call    ehci_alloc_td
  1152.         test    eax, eax
  1153.         jz      .nothing
  1154. ; 2. Initialize controller-independent parts of both TDs.
  1155.         push    eax
  1156.         call    usb_init_transfer
  1157.         pop     eax
  1158. ; 3. Copy PID to the new descriptor.
  1159.         mov     edx, [ecx+ehci_gtd.Token-ehci_gtd.SoftwarePart]
  1160.         mov     [eax+ehci_gtd.Token-ehci_gtd.SoftwarePart], edx
  1161.         mov     [eax+ehci_gtd.NextTD-ehci_gtd.SoftwarePart], 1
  1162.         mov     [eax+ehci_gtd.AlternateNextTD-ehci_gtd.SoftwarePart], 1
  1163. ; 4. Save the returned value (next descriptor).
  1164.         push    eax
  1165. ; 5. Store the physical address of the next descriptor.
  1166.         sub     eax, ehci_gtd.SoftwarePart
  1167.         call    get_phys_addr
  1168.         mov     [ecx+ehci_gtd.NextTD-ehci_gtd.SoftwarePart], eax
  1169. ; 6. For zero-length transfers, store zero in all fields for buffer addresses.
  1170. ; Otherwise, fill them with real values.
  1171.         xor     eax, eax
  1172.         mov     [ecx+ehci_gtd.Flags-ehci_gtd.SoftwarePart], eax
  1173. repeat 10
  1174.         mov     [ecx+ehci_gtd.BufferPointers-ehci_gtd.SoftwarePart+(%-1)*4], eax
  1175. end repeat
  1176.         cmp     [.packetSize], eax
  1177.         jz      @f
  1178.         mov     eax, [.buffer]
  1179.         call    get_phys_addr
  1180.         mov     [ecx+ehci_gtd.BufferPointers-ehci_gtd.SoftwarePart], eax
  1181.         and     eax, 0xFFF
  1182.         mov     edx, [.packetSize]
  1183.         add     edx, eax
  1184.         sub     edx, 0x1000
  1185.         jbe     @f
  1186.         mov     eax, [.buffer]
  1187.         add     eax, 0x1000
  1188.         call    get_pg_addr
  1189.         mov     [ecx+ehci_gtd.BufferPointers+4-ehci_gtd.SoftwarePart], eax
  1190.         sub     edx, 0x1000
  1191.         jbe     @f
  1192.         mov     eax, [.buffer]
  1193.         add     eax, 0x2000
  1194.         call    get_pg_addr
  1195.         mov     [ecx+ehci_gtd.BufferPointers+8-ehci_gtd.SoftwarePart], eax
  1196.         sub     edx, 0x1000
  1197.         jbe     @f
  1198.         mov     eax, [.buffer]
  1199.         add     eax, 0x3000
  1200.         call    get_pg_addr
  1201.         mov     [ecx+ehci_gtd.BufferPointers+12-ehci_gtd.SoftwarePart], eax
  1202.         sub     edx, 0x1000
  1203.         jbe     @f
  1204.         mov     eax, [.buffer]
  1205.         add     eax, 0x4000
  1206.         call    get_pg_addr
  1207.         mov     [ecx+ehci_gtd.BufferPointers+16-ehci_gtd.SoftwarePart], eax
  1208. @@:
  1209. ; 7. Fill Token field:
  1210. ; set Status = 0 (inactive, ehci_insert_transfer would mark everything active);
  1211. ; keep current PID if [.direction] is zero, use two lower bits of [.direction]
  1212. ; otherwise shifted as (0|1|2) -> (2|0|1);
  1213. ; set error counter to 3;
  1214. ; set current page to 0;
  1215. ; do not interrupt on complete (ehci_insert_transfer sets this bit where needed);
  1216. ; set DataToggle to bit 2 of [.direction].
  1217.         mov     eax, [ecx+ehci_gtd.Token-ehci_gtd.SoftwarePart]
  1218.         and     eax, 300h       ; keep PID code
  1219.         mov     edx, [.direction]
  1220.         test    edx, edx
  1221.         jz      .haspid
  1222.         and     edx, 3
  1223.         dec     edx
  1224.         jns     @f
  1225.         add     edx, 3
  1226. @@:
  1227.         mov     ah, dl
  1228.         mov     edx, [.direction]
  1229.         and     edx, not 3
  1230.         shl     edx, 29
  1231.         or      eax, edx
  1232. .haspid:
  1233.         or      eax, 0C00h
  1234.         mov     edx, [.packetSize]
  1235.         shl     edx, 16
  1236.         or      eax, edx
  1237.         mov     [ecx+ehci_gtd.Token-ehci_gtd.SoftwarePart], eax
  1238. ; 4. Restore the returned value saved in step 2.
  1239.         pop     eax
  1240. .nothing:
  1241.         ret
  1242. endp
  1243.  
  1244. ; This procedure is called from several places in main USB code
  1245. ; and activates the transfer which was previously allocated by
  1246. ; ehci_alloc_transfer.
  1247. ; ecx -> last descriptor for the transfer, ebx -> usb_pipe
  1248. proc ehci_insert_transfer
  1249.         or      byte [ecx+ehci_gtd.Token+1-ehci_gtd.SoftwarePart], 80h  ; set IOC bit
  1250.         mov     eax, [esp+4]
  1251. .activate:
  1252.         or      byte [eax+ehci_gtd.Token-ehci_gtd.SoftwarePart], 80h    ; set Active bit
  1253.         cmp     eax, ecx
  1254.         mov     eax, [eax+usb_gtd.NextVirt]
  1255.         jnz     .activate
  1256.         ret
  1257. endp
  1258.  
  1259. ; This function is called from ehci_process_deferred when
  1260. ; reset signalling for a new device needs to be finished.
  1261. proc ehci_port_reset_done
  1262.         movzx   ecx, [esi+usb_controller.ResettingPort]
  1263.         and     dword [edi+EhciPortsReg+ecx*4], not 12Ah
  1264.         mov     eax, [timer_ticks]
  1265.         mov     [esi+usb_controller.ResetTime], eax
  1266.         mov     [esi+usb_controller.ResettingStatus], 2
  1267.         DEBUGF 1,'K : [%d] EHCI %x: reset port %d done\n',[timer_ticks],esi,ecx
  1268.         ret
  1269. endp
  1270.  
  1271. ; This function is called from ehci_process_deferred when
  1272. ; a new device has been reset, recovered after reset and needs to be configured.
  1273. proc ehci_port_init
  1274. ; 1. Get the status and set it to zero.
  1275. ; If reset has been failed (device disconnected during reset),
  1276. ; continue to next device (if there is one).
  1277.         xor     eax, eax
  1278.         xchg    al, [esi+usb_controller.ResettingStatus]
  1279.         test    al, al
  1280.         js      usb_test_pending_port
  1281. ; 2. Get the port status. High-speed devices should be now enabled,
  1282. ; full-speed devices are left disabled;
  1283. ; if the port is disabled, release it to a companion and continue to
  1284. ; next device (if there is one).
  1285.         movzx   ecx, [esi+usb_controller.ResettingPort]
  1286.         mov     eax, [edi+EhciPortsReg+ecx*4]
  1287.         DEBUGF 1,'K : [%d] EHCI %x status of port %d is %x\n',[timer_ticks],esi,ecx,eax
  1288.         test    al, 4
  1289.         jnz     @f
  1290. ;       DEBUGF 1,'K : USB port disabled after reset, status = %x\n',eax
  1291.         dbgstr 'releasing to companion'
  1292.         or      ah, 20h
  1293.         mov     [edi+EhciPortsReg+ecx*4], eax
  1294.         jmp     usb_test_pending_port
  1295. @@:
  1296. ; 3. Call the worker procedure to notify the protocol layer
  1297. ; about new EHCI device. It is high-speed.
  1298.         push    USB_SPEED_HS
  1299.         pop     eax
  1300.         call    ehci_new_device
  1301.         test    eax, eax
  1302.         jnz     .nothing
  1303. ; 4. If something at the protocol layer has failed
  1304. ; (no memory, no bus address), disable the port and stop the initialization.
  1305. .disable_exit:
  1306.         and     dword [edi+EhciPortsReg+ecx*4], not (4 or 2Ah)
  1307.         jmp     usb_test_pending_port
  1308. .nothing:
  1309.         ret
  1310. endp
  1311.  
  1312. ; This procedure is called from ehci_port_init and from hub support code
  1313. ; when a new device is connected and has been reset.
  1314. ; It calls usb_new_device at the protocol layer with correct parameters.
  1315. ; in: esi -> usb_controller, eax = speed.
  1316. proc ehci_new_device
  1317.         push    ebx ecx ; save used registers (ecx is important for ehci_port_init)
  1318. ; 1. Store the speed for the protocol layer.
  1319.         mov     [esi+usb_controller.ResettingSpeed], al
  1320. ; 2. Shift speed bits to the proper place in ehci_pipe.Token.
  1321.         shl     eax, 12
  1322. ; 3. For high-speed devices, go to step 5 with edx = 0.
  1323.         xor     edx, edx
  1324.         cmp     ah, USB_SPEED_HS shl (12-8)
  1325.         jz      .common
  1326. ; 4. For low-speed and full-speed devices, fill address:port
  1327. ; of the last high-speed hub (the closest to the device hub)
  1328. ; for split transactions, and set ControlEndpoint bit in eax;
  1329. ; ehci_init_pipe assumes that the parent pipe is a control pipe.
  1330.         movzx   ecx, [esi+usb_controller.ResettingPort]
  1331.         mov     edx, [esi+usb_controller.ResettingHub]
  1332.         push    eax
  1333. .find_hs_hub:
  1334.         mov     eax, [edx+usb_hub.ConfigPipe]
  1335.         mov     eax, [eax+usb_pipe.DeviceData]
  1336.         cmp     [eax+usb_device_data.Speed], USB_SPEED_HS
  1337.         jz      .found_hs_hub
  1338.         movzx   ecx, [eax+usb_device_data.Port]
  1339.         mov     edx, [eax+usb_device_data.Hub]
  1340.         jmp     .find_hs_hub
  1341. .found_hs_hub:
  1342.         mov     edx, [edx+usb_hub.ConfigPipe]
  1343.         inc     ecx
  1344.         mov     edx, [edx+ehci_pipe.Token-ehci_pipe.SoftwarePart]
  1345.         shl     ecx, 23
  1346.         and     edx, 7Fh
  1347.         shl     edx, 16
  1348.         or      edx, ecx        ; ehci_pipe.Flags
  1349.         pop     eax
  1350.         or      eax, 1 shl 27   ; ehci_pipe.Token
  1351. .common:
  1352. ; 5. Create pseudo-pipe in the stack.
  1353. ; See ehci_init_pipe: only .Controller, .Token, .Flags fields are used.
  1354.         push    esi     ; ehci_pipe.SoftwarePart.Controller
  1355.         mov     ecx, esp
  1356.         sub     esp, ehci_pipe.SoftwarePart - ehci_pipe.Flags - 4
  1357.         push    edx     ; ehci_pipe.Flags
  1358.         push    eax     ; ehci_pipe.Token
  1359. ; 6. Notify the protocol layer.
  1360.         call    usb_new_device
  1361. ; 7. Cleanup the stack after step 5 and return.
  1362.         add     esp, ehci_pipe.SoftwarePart - ehci_pipe.Flags + 8
  1363.         pop     ecx ebx ; restore used registers
  1364.         ret
  1365. endp
  1366.  
  1367. ; This procedure is called in the USB thread from usb_thread_proc,
  1368. ; processes regular actions and those actions which can't be safely done
  1369. ; from interrupt handler.
  1370. ; Returns maximal time delta before the next call.
  1371. proc ehci_process_deferred
  1372.         push    ebx edi         ; save used registers to be stdcall
  1373.         mov     edi, [esi+ehci_controller.MMIOBase2-sizeof.ehci_controller]
  1374. ; 1. Get the mask of events to process.
  1375.         xor     eax, eax
  1376.         xchg    eax, [esi+ehci_controller.DeferredActions-sizeof.ehci_controller]
  1377.         push    eax
  1378. ; 2. Initialize the return value.
  1379.         push    -1
  1380. ; Handle roothub events.
  1381. ; 3a. Test whether there are such events.
  1382.         test    al, 4
  1383.         jz      .skip_roothub
  1384. ; Status of some port has changed. Loop over all ports.
  1385. ; 3b. Prepare for the loop: start from port 0.
  1386.         xor     ecx, ecx
  1387. .portloop:
  1388. ; 3c. Get the port status and changes of it.
  1389. ; If there are no changes, just continue to the next port.
  1390.         mov     eax, [edi+EhciPortsReg+ecx*4]
  1391.         test    al, 2Ah
  1392.         jz      .nextport
  1393. ; 3d. Clear change bits and read the status again.
  1394. ; (It is possible, although quite unlikely, that some event occurs between
  1395. ; the first read and the clearing, invalidating the old status. If an event
  1396. ; occurs after the clearing, we will not miss it, looking in the next scan.
  1397.         mov     [edi+EhciPortsReg+ecx*4], eax
  1398.         mov     ebx, eax
  1399.         mov     eax, [edi+EhciPortsReg+ecx*4]
  1400.         DEBUGF 1,'K : [%d] EHCI %x: status of port %d changed to %x\n',[timer_ticks],esi,ecx,ebx
  1401. ; 3e. Handle overcurrent.
  1402. ; Note: that needs work.
  1403.         test    bl, 20h ; overcurrent change
  1404.         jz      .noovercurrent
  1405.         test    al, 10h ; overcurrent active
  1406.         jz      .noovercurrent
  1407.         DEBUGF 1,'K : overcurrent at port %d\n',ecx
  1408. .noovercurrent:
  1409. ; 3f. Handle changing of connection status.
  1410.         test    bl, 2
  1411.         jz      .nocsc
  1412. ; There was a connect or disconnect event at this port.
  1413. ; 3g. Disconnect the old device on this port, if any.
  1414. ; If the port was resetting, indicate fail; later stages will process it.
  1415.         cmp     [esi+usb_controller.ResettingHub], 0
  1416.         jnz     @f
  1417.         cmp     cl, [esi+usb_controller.ResettingPort]
  1418.         jnz     @f
  1419.         mov     [esi+usb_controller.ResettingStatus], -1
  1420. @@:
  1421.         bts     [esi+usb_controller.NewDisconnected], ecx
  1422. ; 3h. Change connected status. For the connection event, also store
  1423. ; the connection time; any further processing is permitted only after
  1424. ; USB_CONNECT_DELAY ticks.
  1425.         test    al, 1
  1426.         jz      .disconnect
  1427.         mov     eax, [timer_ticks]
  1428.         mov     [esi+usb_controller.ConnectedTime+ecx*4], eax
  1429.         bts     [esi+usb_controller.NewConnected], ecx
  1430.         jmp     .nextport
  1431. .disconnect:
  1432.         btr     [esi+usb_controller.NewConnected], ecx
  1433.         jmp     .nextport
  1434. .nocsc:
  1435. ; 3i. Handle port disabling.
  1436. ; Note: that needs work.
  1437.         test    al, 8
  1438.         jz      @f
  1439.         test    al, 4
  1440.         jz      @f
  1441.         DEBUGF 1,'K : port %d disabled\n',ecx
  1442. @@:
  1443. ; 3j. Continue the loop for the next port.
  1444. .nextport:
  1445.         inc     ecx
  1446.         cmp     ecx, [esi+usb_controller.NumPorts]
  1447.         jb      .portloop
  1448. .skip_roothub:
  1449. ; 4. Process disconnect events. This should be done after step 3
  1450. ; (which includes the first stage of disconnect processing).
  1451.         call    usb_disconnect_stage2
  1452. ; 5. Check for previously connected devices.
  1453. ; If there is a connected device which was connected less than
  1454. ; USB_CONNECT_DELAY ticks ago, plan to wake up when the delay will be over.
  1455. ; Otherwise, call ehci_new_port.
  1456. ; This should be done after step 3.
  1457.         xor     ecx, ecx
  1458.         cmp     [esi+usb_controller.NewConnected], ecx
  1459.         jz      .skip_newconnected
  1460. .portloop2:
  1461.         bt      [esi+usb_controller.NewConnected], ecx
  1462.         jnc     .noconnect
  1463.         mov     eax, [timer_ticks]
  1464.         sub     eax, [esi+usb_controller.ConnectedTime+ecx*4]
  1465.         sub     eax, USB_CONNECT_DELAY
  1466.         jge     .connected
  1467.         neg     eax
  1468.         cmp     [esp], eax
  1469.         jb      .nextport2
  1470.         mov     [esp], eax
  1471.         jmp     .nextport2
  1472. .connected:
  1473.         btr     [esi+usb_controller.NewConnected], ecx
  1474.         call    ehci_new_port
  1475.         jmp     .portloop2
  1476. .noconnect:
  1477. .nextport2:
  1478.         inc     ecx
  1479.         cmp     ecx, [esi+usb_controller.NumPorts]
  1480.         jb      .portloop2
  1481. .skip_newconnected:
  1482. ; 6. Process wait lists.
  1483. ; 6a. Periodic endpoints.
  1484. ; If a request is pending >8 microframes, satisfy it.
  1485. ; If a request is pending <=8 microframes, schedule next wakeup in 0.01s.
  1486.         mov     eax, [esi+usb_controller.WaitPipeRequestPeriodic]
  1487.         cmp     eax, [esi+usb_controller.ReadyPipeHeadPeriodic]
  1488.         jz      .noperiodic
  1489.         mov     edx, [edi+EhciFrameIndexReg]
  1490.         sub     edx, [esi+usb_controller.StartWaitFrame]
  1491.         and     edx, 0x3FFF
  1492.         cmp     edx, 8
  1493.         jbe     @f
  1494.         mov     [esi+usb_controller.ReadyPipeHeadPeriodic], eax
  1495.         jmp     .noperiodic
  1496. @@:
  1497.         pop     eax
  1498.         push    1               ; wakeup in 0.01 sec for next test
  1499. .noperiodic:
  1500. ; 6b. Asynchronous endpoints.
  1501. ; Satisfy a request when InterruptOnAsyncAdvance fired.
  1502.         test    byte [esp+4], 20h
  1503.         jz      @f
  1504.         dbgstr 'async advance int'
  1505.         mov     eax, [esi+usb_controller.WaitPipeRequestAsync]
  1506.         mov     [esi+usb_controller.ReadyPipeHeadAsync], eax
  1507. @@:
  1508. ; Some hardware in some (rarely) conditions set the status bit,
  1509. ; but just does not generate the corresponding interrupt.
  1510. ; Force checking the status here.
  1511.         mov     eax, [esi+usb_controller.WaitPipeRequestAsync]
  1512.         cmp     [esi+usb_controller.ReadyPipeHeadAsync], eax
  1513.         jz      .noasync
  1514.         spin_lock_irq [esi+usb_controller.WaitSpinlock]
  1515.         mov     edx, [edi+EhciStatusReg]
  1516.         test    dl, 20h
  1517.         jz      @f
  1518.         mov     dword [edi+EhciStatusReg], 20h
  1519.         and     dword [esi+ehci_controller.DeferredActions-sizeof.ehci_controller], not 20h
  1520.         dbgstr 'warning: async advance int missed'
  1521.         mov     [esi+usb_controller.ReadyPipeHeadAsync], eax
  1522.         jmp     .async_unlock
  1523. @@:
  1524.         cmp     dword [esp], 100
  1525.         jb      .async_unlock
  1526.         mov     dword [esp], 100
  1527. .async_unlock:
  1528.         spin_unlock_irq [esi+usb_controller.WaitSpinlock]
  1529. .noasync:
  1530. ; 7. Finalize transfers processed by hardware.
  1531. ; It is better to perform this step after step 4 (disconnect events),
  1532. ; although not strictly obligatory. This way, an active transfer aborted
  1533. ; due to disconnect would be handled with more specific USB_STATUS_CLOSED,
  1534. ; not USB_STATUS_NORESPONSE.
  1535.         test    byte [esp+4], 3
  1536.         jz      @f
  1537.         call    ehci_process_updated_schedule
  1538. @@:
  1539. ; 8. Test whether reset signalling has been started and should be stopped now.
  1540. ; This must be done after step 7, because completion of some transfer could
  1541. ; result in resetting a new port.
  1542. .test_reset:
  1543. ; 8a. Test whether reset signalling is active.
  1544.         cmp     [esi+usb_controller.ResettingStatus], 1
  1545.         jnz     .no_reset_in_progress
  1546. ; 8b. Yep. Test whether it should be stopped.
  1547.         mov     eax, [timer_ticks]
  1548.         sub     eax, [esi+usb_controller.ResetTime]
  1549.         sub     eax, USB_RESET_TIME
  1550.         jge     .reset_done
  1551. ; 8c. Not yet, but initiate wakeup in -eax ticks and exit this step.
  1552.         neg     eax
  1553.         cmp     [esp], eax
  1554.         jb      .skip_reset
  1555.         mov     [esp], eax
  1556.         jmp     .skip_reset
  1557. .reset_done:
  1558. ; 8d. Yep, call the worker function and proceed to 8e.
  1559.         call    ehci_port_reset_done
  1560. .no_reset_in_progress:
  1561. ; 8e. Test whether reset process is done, either successful or failed.
  1562.         cmp     [esi+usb_controller.ResettingStatus], 0
  1563.         jz      .skip_reset
  1564. ; 8f. Yep. Test whether it should be stopped.
  1565.         mov     eax, [timer_ticks]
  1566.         sub     eax, [esi+usb_controller.ResetTime]
  1567.         sub     eax, USB_RESET_RECOVERY_TIME
  1568.         jge     .reset_recovery_done
  1569. ; 8g. Not yet, but initiate wakeup in -eax ticks and exit this step.
  1570.         neg     eax
  1571.         cmp     [esp], eax
  1572.         jb      .skip_reset
  1573.         mov     [esp], eax
  1574.         jmp     .skip_reset
  1575. .reset_recovery_done:
  1576. ; 8h. Yep, call the worker function. This could initiate another reset,
  1577. ; so return to the beginning of this step.
  1578.         call    ehci_port_init
  1579.         jmp     .test_reset
  1580. .skip_reset:
  1581. ; 9. Process wait-done notifications, test for new wait requests.
  1582. ; Note: that must be done after steps 4 and 7 which could create new requests.
  1583. ; 9a. Call the worker function.
  1584.         call    usb_process_wait_lists
  1585. ; 9b. If it reports that an asynchronous endpoint should be removed,
  1586. ; doorbell InterruptOnAsyncAdvance and schedule wakeup in 1s
  1587. ; (sometimes it just does not fire).
  1588.         test    al, 1 shl CONTROL_PIPE
  1589.         jz      @f
  1590.         mov     edx, [esi+usb_controller.WaitPipeListAsync]
  1591.         mov     [esi+usb_controller.WaitPipeRequestAsync], edx
  1592.         or      dword [edi+EhciCommandReg], 1 shl 6
  1593.         dbgstr 'async advance doorbell'
  1594.         cmp     dword [esp], 100
  1595.         jb      @f
  1596.         mov     dword [esp], 100
  1597. @@:
  1598. ; 9c. If it reports that a periodic endpoint should be removed,
  1599. ; save the current frame and schedule wakeup in 0.01 sec.
  1600.         test    al, 1 shl INTERRUPT_PIPE
  1601.         jz      @f
  1602.         mov     eax, [esi+usb_controller.WaitPipeListPeriodic]
  1603.         mov     [esi+usb_controller.WaitPipeRequestPeriodic], eax
  1604.         mov     edx, [edi+EhciFrameIndexReg]
  1605.         mov     [esi+usb_controller.StartWaitFrame], edx
  1606.         mov     dword [esp], 1  ; wakeup in 0.01 sec for next test
  1607. @@:
  1608. ; 10. Pop the return value, restore the stack after step 1 and return.
  1609.         pop     eax
  1610.         pop     ecx
  1611.         pop     edi ebx ; restore used registers to be stdcall
  1612.         ret
  1613. endp
  1614.  
  1615. ; This procedure is called in the USB thread from ehci_process_deferred
  1616. ; when EHCI IRQ handler has signalled that new IOC-packet was processed.
  1617. ; It scans all lists for completed packets and calls ehci_process_finalized_td
  1618. ; for those packets.
  1619. proc ehci_process_updated_schedule
  1620. ; Important note: we cannot hold the list lock during callbacks,
  1621. ; because callbacks sometimes open and/or close pipes and thus acquire/release
  1622. ; the corresponding lock itself.
  1623. ; Fortunately, pipes can be finally freed only by another step of
  1624. ; ehci_process_deferred, so all pipes existing at the start of this function
  1625. ; will be valid while this function is running. Some pipes can be removed
  1626. ; from the corresponding list, some pipes can be inserted; insert/remove
  1627. ; functions guarantee that traversing one list yields all pipes that were in
  1628. ; that list at the beginning of the traversing (possibly with some new pipes,
  1629. ; possibly without some new pipes, that doesn't matter).
  1630.         push    edi
  1631. ; 1. Process all Periodic lists.
  1632.         lea     edi, [esi+ehci_controller.IntEDs-sizeof.ehci_controller+ehci_static_ep.SoftwarePart]
  1633.         lea     ebx, [esi+ehci_controller.IntEDs+63*sizeof.ehci_static_ep-sizeof.ehci_controller+ehci_static_ep.SoftwarePart]
  1634. @@:
  1635.         call    ehci_process_updated_list
  1636.         cmp     edi, ebx
  1637.         jnz     @b
  1638. ; 2. Process the Control list.
  1639.         add     edi, ehci_controller.ControlDelta
  1640.         call    ehci_process_updated_list
  1641. ; 3. Process the Bulk list.
  1642.         call    ehci_process_updated_list
  1643. ; 4. Return.
  1644.         pop     edi
  1645.         ret
  1646. endp
  1647.  
  1648. ; This procedure is called from ehci_process_updated_schedule, see comments there.
  1649. ; It processes one list, esi -> usb_controller, edi -> usb_static_ep,
  1650. ; and advances edi to next head.
  1651. proc ehci_process_updated_list
  1652.         push    ebx
  1653. ; 1. Perform the external loop over all pipes.
  1654.         mov     ebx, [edi+usb_static_ep.NextVirt]
  1655. .loop:
  1656.         cmp     ebx, edi
  1657.         jz      .done
  1658. ; store pointer to the next pipe in the stack
  1659.         push    [ebx+usb_static_ep.NextVirt]
  1660. ; 2. For every pipe, perform the internal loop over all descriptors.
  1661. ; All descriptors are organized in the queue; we process items from the start
  1662. ; of the queue until a) the last descriptor (not the part of the queue itself)
  1663. ; or b) an active (not yet processed by the hardware) descriptor is reached.
  1664.         lea     ecx, [ebx+usb_pipe.Lock]
  1665.         call    mutex_lock
  1666.         mov     ebx, [ebx+usb_pipe.LastTD]
  1667.         push    ebx
  1668.         mov     ebx, [ebx+usb_gtd.NextVirt]
  1669. .tdloop:
  1670. ; 3. For every descriptor, test active flag and check for end-of-queue;
  1671. ; if either of conditions holds, exit from the internal loop.
  1672.         cmp     ebx, [esp]
  1673.         jz      .tddone
  1674.         cmp     byte [ebx+ehci_gtd.Token-ehci_gtd.SoftwarePart], 0
  1675.         js      .tddone
  1676. ; Release the queue lock while processing one descriptor:
  1677. ; callback function could (and often would) schedule another transfer.
  1678.         push    ecx
  1679.         call    mutex_unlock
  1680.         call    ehci_process_updated_td
  1681.         pop     ecx
  1682.         call    mutex_lock
  1683.         jmp     .tdloop
  1684. .tddone:
  1685.         call    mutex_unlock
  1686.         pop     ebx
  1687. ; End of internal loop, restore pointer to the next pipe
  1688. ; and continue the external loop.
  1689.         pop     ebx
  1690.         jmp     .loop
  1691. .done:
  1692.         pop     ebx
  1693.         add     edi, sizeof.ehci_static_ep
  1694.         ret
  1695. endp
  1696.  
  1697. ; This procedure is called from ehci_process_updated_list, which is itself
  1698. ; called from ehci_process_updated_schedule, see comments there.
  1699. ; It processes one completed descriptor.
  1700. ; in: ebx -> usb_gtd, out: ebx -> next usb_gtd.
  1701. proc ehci_process_updated_td
  1702. ;       mov     eax, [ebx+usb_gtd.Pipe]
  1703. ;       cmp     [eax+usb_pipe.Type], INTERRUPT_PIPE
  1704. ;       jnz     @f
  1705. ;       DEBUGF 1,'K : finalized TD for pipe %x:\n',eax
  1706. ;       lea     eax, [ebx-ehci_gtd.SoftwarePart]
  1707. ;       DEBUGF 1,'K : %x %x %x %x\n',[eax],[eax+4],[eax+8],[eax+12]
  1708. ;       DEBUGF 1,'K : %x %x %x %x\n',[eax+16],[eax+20],[eax+24],[eax+28]
  1709. ;@@:
  1710. ; 1. Remove this descriptor from the list of descriptors for this pipe.
  1711.         call    usb_unlink_td
  1712. ; 2. Calculate actual number of bytes transferred.
  1713.         mov     eax, [ebx+ehci_gtd.Token-ehci_gtd.SoftwarePart]
  1714.         lea     edx, [eax+eax]
  1715.         shr     edx, 17
  1716.         sub     edx, [ebx+usb_gtd.Length]
  1717.         neg     edx
  1718. ; 3. Check whether we need some special processing beyond notifying the driver.
  1719. ; Transfer errors require special processing.
  1720. ; Short packets require special processing if
  1721. ; a) this is not the last descriptor for transfer stage
  1722. ; (in this case we need to process subsequent descriptors for the stage too)
  1723. ; or b) the caller considers short transfers to be an error.
  1724. ; ehci_alloc_transfer sets bit 0 of ehci_gtd.Flags to 0 if short packet
  1725. ; in this descriptor requires special processing and to 1 otherwise.
  1726. ; If special processing is not needed, advance to 4 with ecx = 0.
  1727. ; Otherwise, go to 6.
  1728.         xor     ecx, ecx
  1729.         test    al, 40h
  1730.         jnz     .error
  1731.         test    byte [ebx+ehci_gtd.Flags-ehci_gtd.SoftwarePart], 1
  1732.         jnz     .notify
  1733.         cmp     edx, [ebx+usb_gtd.Length]
  1734.         jnz     .special
  1735. .notify:
  1736. ; 4. Either the descriptor in ebx was processed without errors,
  1737. ; or all necessary error actions were taken and ebx points to the last
  1738. ; related descriptor.
  1739. ; 4a. Test whether it is the last descriptor in the transfer
  1740. ; <=> it has an associated callback.
  1741.         mov     eax, [ebx+usb_gtd.Callback]
  1742.         test    eax, eax
  1743.         jz      .nocallback
  1744. ; 4b. It has an associated callback; call it with corresponding parameters.
  1745.         stdcall_verify eax, [ebx+usb_gtd.Pipe], ecx, \
  1746.                 [ebx+usb_gtd.Buffer], edx, [ebx+usb_gtd.UserData]
  1747.         jmp     .callback
  1748. .nocallback:
  1749. ; 4c. It is an intermediate descriptor. Add its length to the length
  1750. ; in the following descriptor.
  1751.         mov     eax, [ebx+usb_gtd.NextVirt]
  1752.         add     [eax+usb_gtd.Length], edx
  1753. .callback:
  1754. ; 5. Free the current descriptor and return the next one.
  1755.         push    [ebx+usb_gtd.NextVirt]
  1756.         stdcall ehci_free_td, ebx
  1757.         pop     ebx
  1758.         ret
  1759. .error:
  1760.         push    ebx
  1761.         sub     ebx, ehci_gtd.SoftwarePart
  1762.         DEBUGF 1,'K : TD failed:\n'
  1763.         DEBUGF 1,'K : %x %x %x %x\n',[ebx],[ebx+4],[ebx+8],[ebx+12]
  1764.         DEBUGF 1,'K : %x %x %x %x\n',[ebx+16],[ebx+20],[ebx+24],[ebx+28]
  1765.         pop     ebx
  1766.         DEBUGF 1,'K : pipe now:\n'
  1767.         mov     ecx, [ebx+usb_gtd.Pipe]
  1768.         sub     ecx, ehci_pipe.SoftwarePart
  1769.         DEBUGF 1,'K : %x %x %x %x\n',[ecx],[ecx+4],[ecx+8],[ecx+12]
  1770.         DEBUGF 1,'K : %x %x %x %x\n',[ecx+16],[ecx+20],[ecx+24],[ecx+28]
  1771.         DEBUGF 1,'K : %x %x %x %x\n',[ecx+32],[ecx+36],[ecx+40],[ecx+44]
  1772. .special:
  1773. ; 6. Special processing is needed.
  1774. ; 6a. Save the status and length.
  1775.         push    edx
  1776.         push    eax
  1777. ; 6b. Traverse the list of descriptors looking for the final descriptor
  1778. ; for this transfer. Free and unlink non-final descriptors.
  1779. ; Final descriptor will be freed in step 5.
  1780. .look_final:
  1781.         call    usb_is_final_packet
  1782.         jnc     .found_final
  1783.         push    [ebx+usb_gtd.NextVirt]
  1784.         stdcall ehci_free_td, ebx
  1785.         pop     ebx
  1786.         call    usb_unlink_td
  1787.         jmp     .look_final
  1788. .found_final:
  1789. ; 6c. Restore the status saved in 6a and transform it to the error code.
  1790. ; Notes:
  1791. ; * any USB transaction error results in Halted bit; if it is not set,
  1792. ;   but we are here, it must be due to short packet;
  1793. ; * babble is considered a fatal USB transaction error,
  1794. ;   other errors just lead to retrying the transaction;
  1795. ;   if babble is detected, return the corresponding error;
  1796. ; * if several non-fatal errors have occured during transaction retries,
  1797. ;   all corresponding bits are set. In this case, return some error code,
  1798. ;   the order is quite arbitrary.
  1799.         pop     eax     ; status
  1800.         push    USB_STATUS_UNDERRUN
  1801.         pop     ecx
  1802.         test    al, 40h         ; not Halted?
  1803.         jz      .know_error
  1804.         mov     cl, USB_STATUS_OVERRUN
  1805.         test    al, 10h         ; Babble detected?
  1806.         jnz     .know_error
  1807.         mov     cl, USB_STATUS_BUFOVERRUN
  1808.         test    al, 20h         ; Data Buffer error?
  1809.         jnz     .know_error
  1810.         mov     cl, USB_STATUS_NORESPONSE
  1811.         test    al, 8           ; Transaction Error?
  1812.         jnz     .know_error
  1813.         mov     cl, USB_STATUS_STALL
  1814. .know_error:
  1815. ; 6d. If error code is USB_STATUS_UNDERRUN and the last TD allows short packets,
  1816. ; it is not an error; in this case, go to 4 with ecx = 0.
  1817.         cmp     ecx, USB_STATUS_UNDERRUN
  1818.         jnz     @f
  1819.         test    byte [ebx+ehci_gtd.Flags-ehci_gtd.SoftwarePart], 1
  1820.         jz      @f
  1821.         xor     ecx, ecx
  1822.         pop     edx     ; length
  1823.         jmp     .notify
  1824. @@:
  1825. ; 6e. Abort the entire transfer.
  1826. ; There are two cases: either there is only one transfer stage
  1827. ; (everything except control transfers), then ebx points to the last TD and
  1828. ; all previous TD were unlinked and dismissed (if possible),
  1829. ; or there are several stages (a control transfer) and ebx points to the last
  1830. ; TD of Data or Status stage (usb_is_final_packet does not stop in Setup stage,
  1831. ; because Setup stage can not produce short packets); for Data stage, we need
  1832. ; to unlink and free (if possible) one more TD and advance ebx to the next one.
  1833.         cmp     [ebx+usb_gtd.Callback], 0
  1834.         jnz     .normal
  1835.         push    ecx
  1836.         push    [ebx+usb_gtd.NextVirt]
  1837.         stdcall ehci_free_td, ebx
  1838.         pop     ebx
  1839.         call    usb_unlink_td
  1840.         pop     ecx
  1841. .normal:
  1842. ; 6f. For bulk/interrupt transfers we have no choice but halt the queue,
  1843. ; the driver should intercede (through some API which is not written yet).
  1844. ; Control pipes normally recover at the next SETUP transaction (first stage
  1845. ; of any control transfer), so we hope on the best and just advance the queue
  1846. ; to the next transfer. (According to the standard, "A control pipe may also
  1847. ; support functional stall as well, but this is not recommended.").
  1848.         mov     edx, [ebx+usb_gtd.Pipe]
  1849.         mov     eax, [ebx+ehci_gtd.NextTD-ehci_gtd.SoftwarePart]
  1850.         or      al, 1
  1851.         mov     [edx+ehci_pipe.Overlay.NextTD-ehci_pipe.SoftwarePart], eax
  1852.         mov     [edx+ehci_pipe.Overlay.AlternateNextTD-ehci_pipe.SoftwarePart], eax
  1853.         cmp     [edx+usb_pipe.Type], CONTROL_PIPE
  1854.         jz      .control
  1855. ; Bulk/interrupt transfer; halt the queue.
  1856.         mov     [edx+ehci_pipe.Overlay.Token-ehci_pipe.SoftwarePart], 40h
  1857.         pop     edx
  1858.         jmp     .notify
  1859. ; Control transfer.
  1860. .control:
  1861.         and     [edx+ehci_pipe.Overlay.Token-ehci_pipe.SoftwarePart], 0
  1862.         dec     [edx+ehci_pipe.Overlay.NextTD-ehci_pipe.SoftwarePart]
  1863.         pop     edx
  1864.         jmp     .notify
  1865. endp
  1866.  
  1867. ; This procedure unlinks the pipe from the corresponding pipe list.
  1868. ; esi -> usb_controller, ebx -> usb_pipe
  1869. proc ehci_unlink_pipe
  1870.         cmp     [ebx+usb_pipe.Type], INTERRUPT_PIPE
  1871.         jnz     @f
  1872.         test    word [ebx+ehci_pipe.Flags-ehci_pipe.SoftwarePart+2], 3FFFh
  1873.         jnz     .interrupt_fs
  1874.         call    ehci_hs_interrupt_list_unlink
  1875.         jmp     .interrupt_common
  1876. .interrupt_fs:
  1877.         call    ehci_fs_interrupt_list_unlink
  1878. .interrupt_common:
  1879. @@:
  1880.         mov     edx, [ebx+usb_pipe.NextVirt]
  1881.         mov     eax, [ebx+usb_pipe.PrevVirt]
  1882.         mov     [edx+usb_pipe.PrevVirt], eax
  1883.         mov     [eax+usb_pipe.NextVirt], edx
  1884.         mov     edx, esi
  1885.         sub     edx, eax
  1886.         cmp     edx, sizeof.ehci_controller
  1887.         mov     edx, [ebx+ehci_pipe.NextQH-ehci_pipe.SoftwarePart]
  1888.         jb      .prev_is_static
  1889.         mov     [eax+ehci_pipe.NextQH-ehci_pipe.SoftwarePart], edx
  1890.         ret
  1891. .prev_is_static:
  1892.         mov     [eax+ehci_static_ep.NextQH-ehci_static_ep.SoftwarePart], edx
  1893.         ret
  1894. endp
  1895.  
  1896. proc ehci_alloc_td
  1897.         push    ebx
  1898.         mov     ebx, ehci_gtd_mutex
  1899.         stdcall usb_allocate_common, sizeof.ehci_gtd
  1900.         test    eax, eax
  1901.         jz      @f
  1902.         add     eax, ehci_gtd.SoftwarePart
  1903. @@:
  1904.         pop     ebx
  1905.         ret
  1906. endp
  1907.  
  1908. ; This procedure is called from several places from main USB code and
  1909. ; frees all additional data associated with the transfer descriptor.
  1910. ; EHCI has no additional data, so just free ehci_gtd structure.
  1911. proc ehci_free_td
  1912.         sub     dword [esp+4], ehci_gtd.SoftwarePart
  1913.         jmp     usb_free_common
  1914. endp
  1915.