Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
3520 clevermous 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