Subversion Repositories Kolibri OS

Rev

Rev 3555 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3555 Serge 1
; Code for UHCI 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
; UHCI register declarations
10
UhciCommandReg     = 0
11
UhciStatusReg      = 2
12
UhciInterruptReg   = 4
13
UhciFrameNumberReg = 6
14
UhciBaseAddressReg = 8
15
UhciSOFModifyReg   = 0Ch
16
UhciPort1StatusReg = 10h
17
; possible PIDs for USB data transfers
18
USB_PID_SETUP = 2Dh
19
USB_PID_IN    = 69h
20
USB_PID_OUT   = 0E1h
21
; UHCI does not support an interrupt on root hub status change. We must poll
22
; the controller periodically. This is the period in timer ticks (10ms).
23
; We use the value 100 ms: it is valid value for USB hub poll rate (1-255 ms),
24
; small enough to be responsible to connect events and large enough to not
25
; load CPU too often.
26
UHCI_POLL_INTERVAL = 100
27
; the following constant is an invalid encoding for length fields in
28
; uhci_gtd; it is used to check whether an inactive TD has been
29
; completed (actual length of the transfer is valid) or not processed at all
30
; (actual length of the transfer is UHCI_INVALID_LENGTH).
31
; Valid values are 0-4FFh and 7FFh. We use 700h as an invalid value.
32
UHCI_INVALID_LENGTH = 700h
33
 
34
; =============================================================================
35
; ================================ Structures =================================
36
; =============================================================================
37
 
38
; UHCI-specific part of a pipe descriptor.
39
; * The structure corresponds to the Queue Head aka QH from the UHCI
40
;   specification with some additional fields.
41
; * The hardware uses first two fields (8 bytes). Next two fields are used for
42
;   software book-keeping.
43
; * The hardware requires 16-bytes alignment of the hardware part.
44
;   Since the allocator (usb_allocate_common) allocates memory sequentially
45
;   from page start (aligned on 0x1000 bytes), size of the structure must be
46
;   divisible by 16.
47
struct uhci_pipe
48
NextQH          dd      ?
49
; 1. First bit (bit 0) is Terminate bit. 1 = there is no next QH.
50
; 2. Next bit (bit 1) is QH/TD select bit. 1 = NextQH points to QH.
51
; 3. Next two bits (bits 2-3) are reserved.
52
; 4. With masked 4 lower bits, this is the physical address of the next QH in
53
;    the QH list.
54
; See also the description before NextVirt field of the usb_pipe
55
; structure. Additionally to that description, the following is specific for
56
; the UHCI controller:
57
; * n=10, N=1024. However, this number is quite large.
58
; * 1024 lists are used only for individual transfer descriptors for
59
;   Isochronous endpoints. This means that the software can sleep up to 1024 ms
60
;   before initiating the next portion of a large isochronous transfer, which
61
;   is a sufficiently large value.
62
; * We use the 32ms upper limit for interrupt endpoint polling interval.
63
;   This seems to be a reasonable value.
64
; * The "next" list for last Periodic list is the Control list.
65
; * The "next" list for Control list is Bulk list and the "next"
66
;   list for Bulk list is Control list. This loop is used for bandwidth
67
;   reclamation: the hardware traverses lists until end-of-frame.
68
HeadTD          dd      ?
69
; 1. First bit (bit 0) is Terminate bit. 1 = there is no TDs in this QH.
70
; 2. Next bit (bit 1) is QH/TD select bit. 1 = HeadTD points to QH.
71
; 3. Next two bits (bits 2-3) are reserved.
72
; 4. With masked 4 lower bits, this is the physical address of the first TD in
73
;    the TD queue for this QH.
74
Token           dd      ?
75
; This field is a template for uhci_gtd.Token field in transfer
76
; descriptors. The meaning of individual bits is the same as for
77
; uhci_gtd.Token, except that PID bitfield is always
78
; USB_PID_SETUP/IN/OUT for control/in/out pipes,
79
; the MaximumLength bitfield encodes maximum packet size,
80
; the Reserved bit 20 is LowSpeedDevice bit.
81
ErrorTD         dd      ?
82
; Usually NULL. If nonzero, it is a pointer to descriptor which was error'd
83
; and should be freed sometime in the future (the hardware could still use it).
84
SoftwarePart    rd      sizeof.usb_pipe/4
85
; Common part for all controllers, described by usb_pipe structure.
86
ends
87
 
88
if sizeof.uhci_pipe mod 16
89
.err uhci_pipe must be 16-bytes aligned
90
end if
91
 
92
; This structure describes the static head of every list of pipes.
93
; The hardware requires 16-bytes alignment of this structure.
94
; All instances of this structure are located sequentially in uhci_controller,
95
; uhci_controller is page-aligned, so it is sufficient to make this structure
96
; 16-bytes aligned and verify that the first instance is 16-bytes aligned
97
; inside uhci_controller.
98
struct uhci_static_ep
99
NextQH          dd      ?
100
; Same as uhci_pipe.NextQH.
101
HeadTD          dd      ?
102
; Same as uhci_pipe.HeadTD.
103
NextList        dd      ?
104
; Virtual address of the next list.
105
                dd      ?
106
; Not used.
107
SoftwarePart    rd      sizeof.usb_static_ep/4
108
; Common part for all controllers, described by usb_static_ep structure.
109
                dd      ?
110
; Padding for 16-byte alignment.
111
ends
112
 
113
if sizeof.uhci_static_ep mod 16
114
.err uhci_static_ep must be 16-bytes aligned
115
end if
116
 
117
; UHCI-specific part of controller data.
118
; * The structure includes two parts, the hardware part and the software part.
119
; * The hardware part consists of first 4096 bytes and corresponds to
120
;   the Frame List from UHCI specification.
121
; * The hardware requires page-alignment of the hardware part, so
122
;   the entire descriptor must be page-aligned.
123
;   This structure is allocated with kernel_alloc (see usb_init_controller),
124
;   this gives page-aligned data.
125
struct uhci_controller
126
; ------------------------------ hardware fields ------------------------------
127
FrameList       rd      1024
128
; Entry n corresponds to the head of the frame list to be executed in
3589 Serge 129
; the frames n,n+1024,n+2048,n+3072,...
3555 Serge 130
; The first bit of each entry is Terminate bit, 1 = the frame is empty.
131
; The second bit of each entry is QH/TD select bit, 1 = the entry points to
132
; QH, 0 = to TD.
133
; With masked 2 lower bits, the entry is a physical address of the first QH/TD
134
; to be executed.
135
; ------------------------------ software fields ------------------------------
136
; Every list has the static head, which is an always empty QH.
137
; The following fields are static heads, one per list:
138
; 32+16+8+4+2+1 = 63 for Periodic lists, 1 for Control list and 1 for Bulk list.
139
IntEDs          uhci_static_ep
140
                rb      62 * sizeof.uhci_static_ep
141
ControlED       uhci_static_ep
142
BulkED          uhci_static_ep
143
IOBase          dd      ?
144
; Base port in I/O space for UHCI controller.
145
; UHCI register UhciXxx is addressed as in/out to IOBase + UhciXxx,
146
; see declarations in the beginning of this source.
147
DeferredActions dd      ?
148
; Bitmask of bits from UhciStatusReg which need to be processed
149
; by uhci_process_deferred. Bit 0 = a transaction with IOC bit
150
; has completed. Bit 1 = a transaction has failed. Set by uhci_irq,
151
; cleared by uhci_process_deferred.
152
LastPollTime    dd      ?
153
; See the comment before UHCI_POLL_INTERVAL. This variable keeps the
154
; last time, in timer ticks, when the polling was done.
155
ends
156
 
157
if uhci_controller.IntEDs mod 16
158
.err Static endpoint descriptors must be 16-bytes aligned inside uhci_controller
159
end if
160
 
161
; UHCI general transfer descriptor.
162
; * The structure describes non-Isochronous data transfers
163
;   for the UHCI controller.
164
; * The structure includes two parts, the hardware part and the software part.
165
; * The hardware part consists of first 16 bytes and corresponds to the
166
;   Transfer Descriptor aka TD from UHCI specification.
167
; * The hardware requires 16-bytes alignment of the hardware part, so
168
;   the entire descriptor must be 16-bytes aligned. Since the allocator
169
;   (uhci_allocate_common) allocates memory sequentially from page start
170
;   (aligned on 0x1000 bytes), size of the structure must be divisible by 16.
171
struct uhci_gtd
172
NextTD          dd      ?
173
; 1. First bit (bit 0) is Terminate bit. 1 = there is no next TD.
174
; 2. Next bit (bit 1) is QH/TD select bit. 1 = NextTD points to QH.
175
;    This bit is always set to 0 in the implementation.
176
; 3. Next bit (bit 2) is Depth/Breadth select bit. 1 = the controller should
177
;    proceed to the NextTD after this TD is complete. 0 = the controller
178
;    should proceed to the next endpoint after this TD is complete.
179
;    The implementation sets this bit to 0 for final stages of all transactions
180
;    and to 1 for other stages.
181
; 4. Next bit (bit 3) is reserved and must be zero.
182
; 5. With masked 4 lower bits, this is the physical address of the next TD
183
;    in the TD list.
184
ControlStatus   dd      ?
185
; 1. Lower 11 bits (bits 0-10) are ActLen. This is written by the controller
186
;    at the conclusion of a USB transaction to indicate the actual number of
187
;    bytes that were transferred minus 1.
188
; 2. Next 6 bits (bits 11-16) are reserved.
189
; 3. Next bit (bit 17) signals Bitstuff error.
190
; 4. Next bit (bit 18) signals CRC/Timeout error.
191
; 5. Next bit (bit 19) signals NAK receive.
192
; 6. Next bit (bit 20) signals Babble error.
193
; 7. Next bit (bit 21) signals Data Buffer error.
194
; 8. Next bit (bit 22) signals Stall error.
195
; 9. Next bit (bit 23) is Active field. 1 = this TD should be processed.
196
; 10. Next bit (bit 24) is InterruptOnComplete bit. 1 = the controller should
197
;     issue an interrupt on completion of the frame in which this TD is
198
;     executed.
199
; 11. Next bit (bit 25) is IsochronousSelect bit. 1 = this TD is isochronous.
200
; 12. Next bit (bit 26) is LowSpeedDevice bit. 1 = this TD is for low-speed.
201
; 13. Next two bits (bits 27-28) are ErrorCounter field. This field is
202
;     decremented by the controller on every non-fatal error with this TD.
203
;     Babble and Stall are considered fatal errors and immediately deactivate
204
;     the TD without decrementing this field. 0 = no error limit,
205
;     n = deactivate the TD after n errors.
206
; 14. Next bit (bit 29) is ShortPacketDetect bit. 1 = short packet is an error.
207
;     Note: the specification defines this bit as input for the controller,
208
;     but does not specify the value written by controller.
209
;     Some controllers (e.g. Intel) keep the value, some controllers (e.g. VIA)
210
;     set the value to whether a short packet was actually detected
211
;     (or something like that).
212
;     Thus, we duplicate this bit as bit 0 of OrigBufferInfo.
213
; 15. Upper two bits (bits 30-31) are reserved.
214
Token           dd      ?
215
; 1. Lower 8 bits (bits 0-7) are PID, one of USB_PID_*.
216
; 2. Next 7 bits (bits 8-14) are DeviceAddress field. This is the address of
217
;    the target device on the USB bus.
218
; 3. Next 4 bits (bits 15-18) are Endpoint field. This is the target endpoint
219
;    number.
220
; 4. Next bit (bit 19) is DataToggle bit. n = issue/expect DATAn token.
221
; 5. Next bit (bit 20) is reserved.
222
; 6. Upper 11 bits (bits 21-31) are MaximumLength field. This field specifies
223
;    the maximum number of data bytes for the transfer minus 1 byte. Null data
224
;    packet is encoded as 0x7FF, maximum possible non-null data packet is 1280
225
;    bytes, encoded as 0x4FF.
226
Buffer          dd      ?
227
; Physical address of the data buffer for this TD.
228
OrigBufferInfo  dd      ?
229
; Usually NULL. If the original buffer crosses a page boundary, this is a
230
; pointer to the structure uhci_original_buffer for this request.
231
; bit 0: 1 = short packet is NOT allowed
232
; (before the TD is processed, it is the copy of bit 29 of ControlStatus;
233
;  some controllers modify that bit, so we need a copy in a safe place)
234
SoftwarePart    rd      sizeof.usb_gtd/4
235
; Software part, common for all controllers.
236
ends
237
 
238
if sizeof.uhci_gtd mod 16
239
.err uhci_gtd must be 16-bytes aligned
240
end if
241
 
242
; UHCI requires that the entire transfer buffer should be on one page.
243
; If the actual buffer crosses page boundary, uhci_alloc_packet
244
; allocates additional memory for buffer for hardware.
245
; This structure describes correspondence between two buffers.
246
struct uhci_original_buffer
247
OrigBuffer      dd      ?
248
UsedBuffer      dd      ?
249
ends
250
 
251
; Description of UHCI-specific data and functions for
252
; controller-independent code.
253
; Implements the structure usb_hardware_func from hccommon.inc for UHCI.
254
iglobal
255
align 4
256
uhci_hardware_func:
257
        dd      'UHCI'
258
        dd      sizeof.uhci_controller
259
        dd      uhci_init
260
        dd      uhci_process_deferred
261
        dd      uhci_set_device_address
262
        dd      uhci_get_device_address
263
        dd      uhci_port_disable
264
        dd      uhci_new_port.reset
265
        dd      uhci_set_endpoint_packet_size
266
        dd      usb1_allocate_endpoint
267
        dd      uhci_free_pipe
268
        dd      uhci_init_pipe
269
        dd      uhci_unlink_pipe
270
        dd      usb1_allocate_general_td
271
        dd      uhci_free_td
272
        dd      uhci_alloc_transfer
273
        dd      uhci_insert_transfer
274
        dd      uhci_new_device
275
endg
276
 
277
; =============================================================================
278
; =================================== Code ====================================
279
; =============================================================================
280
 
281
; Controller-specific initialization function.
282
; Called from usb_init_controller. Initializes the hardware and
283
; UHCI-specific parts of software structures.
284
; eax = pointer to uhci_controller to be initialized
285
; [ebp-4] = pcidevice
286
proc uhci_init
287
; inherit some variables from the parent (usb_init_controller)
288
.devfn   equ ebp - 4
289
.bus     equ ebp - 3
290
; 1. Store pointer to uhci_controller for further use.
291
        push    eax
292
        mov     edi, eax
293
        mov     esi, eax
294
; 2. Initialize uhci_controller.FrameList.
295
; Note that FrameList is located in the beginning of uhci_controller,
296
; so esi and edi now point to uhci_controller.FrameList.
297
; First 32 entries of FrameList contain physical addresses
298
; of first 32 Periodic static heads, further entries duplicate these.
299
; See the description of structures for full info.
300
; Note that all static heads fit in one page, so one call to
301
; get_phys_addr is sufficient.
302
if (uhci_controller.IntEDs / 0x1000) <> (uhci_controller.BulkED / 0x1000)
303
.err assertion failed
304
end if
305
; 2a. Get physical address of first static head.
306
; Note that 1) it is located in the beginning of a page
307
; and 2) all other static heads fit in the same page,
308
; so one call to get_phys_addr without correction of lower 12 bits
309
; is sufficient.
310
if (uhci_controller.IntEDs mod 0x1000) <> 0
311
.err assertion failed
312
end if
313
        add     eax, uhci_controller.IntEDs
314
        call    get_phys_addr
315
; 2b. Fill first 32 entries.
316
        inc     eax
317
        inc     eax     ; set QH bit for uhci_pipe.NextQH
318
        push    32
319
        pop     ecx
320
        mov     edx, ecx
321
@@:
322
        stosd
323
        add     eax, sizeof.uhci_static_ep
324
        loop    @b
325
; 2c. Fill the rest entries.
326
        mov     ecx, 1024 - 32
327
        rep movsd
328
; 3. Initialize static heads uhci_controller.*ED.
329
; Use the loop over groups: first group consists of first 32 Periodic
330
; descriptors, next group consists of next 16 Periodic descriptors,
331
; ..., last group consists of the last Periodic descriptor.
332
; 3a. Prepare for the loop.
333
; make esi point to the second group, other registers are already set.
334
        add     esi, 32*4 + 32*sizeof.uhci_static_ep
335
; 3b. Loop over groups. On every iteration:
336
; edx = size of group, edi = pointer to the current group,
337
; esi = pointer to the next group, eax = physical address of the next group.
338
.init_static_eds:
339
; 3c. Get the size of next group.
340
        shr     edx, 1
341
; 3d. Exit the loop if there is no next group.
342
        jz      .init_static_eds_done
343
; 3e. Initialize the first half of the current group.
344
; Advance edi to the second half.
345
        push    eax esi
346
        call    uhci_init_static_ep_group
347
        pop     esi eax
348
; 3f. Initialize the second half of the current group
349
; with the same values.
350
; Advance edi to the next group, esi/eax to the next of the next group.
351
        call    uhci_init_static_ep_group
352
        jmp     .init_static_eds
353
.init_static_eds_done:
354
; 3g. Initialize the last static head.
355
        xor     esi, esi
356
        call    uhci_init_static_endpoint
357
; 3i. Initialize the head of Control list.
358
        add     eax, sizeof.uhci_static_ep
359
        call    uhci_init_static_endpoint
360
; 3j. Initialize the head of Bulk list.
361
        sub     eax, sizeof.uhci_static_ep
362
        call    uhci_init_static_endpoint
363
; 4. Get I/O base address and size from PCI bus.
364
; 4a. Read&save PCI command state.
365
        mov     bh, [.devfn]
366
        mov     ch, [.bus]
367
        mov     cl, 1
368
        mov     eax, ecx
369
        mov     bl, 4
370
        call    pci_read_reg
371
        push    eax
372
; 4b. Disable IO access.
373
        and     al, not 1
374
        push    ecx
375
        xchg    eax, ecx
376
        call    pci_write_reg
377
        pop     ecx
378
; 4c. Read&save IO base address.
379
        mov     eax, ecx
380
        mov     bl, 20h
381
        call    pci_read_reg
382
        and     al, not 3
383
        xchg    eax, edi
384
; now edi = IO base
385
; 4d. Write 0xffff to IO base address.
386
        push    ecx
387
        xchg    eax, ecx
388
        or      ecx, -1
389
        call    pci_write_reg
390
        pop     ecx
391
; 4e. Read IO base address.
392
        mov     eax, ecx
393
        call    pci_read_reg
394
        and     al, not 3
395
        cwde
396
        not     eax
397
        inc     eax
398
        xchg    eax, esi
399
; now esi = IO size
400
; 4f. Restore IO base address.
401
        xchg    eax, ecx
402
        mov     ecx, edi
403
        push    eax
404
        call    pci_write_reg
405
        pop     eax
406
; 4g. Restore PCI command state and enable io & bus master access.
407
        pop     ecx
408
        or      ecx, 5
409
        mov     bl, 4
410
        push    eax
411
        call    pci_write_reg
412
        pop     eax
413
; 5. Reset the controller.
414
; 5e. Host reset.
415
        mov     edx, edi
416
        mov     ax, 2
417
        out     dx, ax
418
; 5f. Wait up to 10ms.
419
        push    10
420
        pop     ecx
421
@@:
422
        push    esi
423
        push    1
424
        pop     esi
425
        call    delay_ms
426
        pop     esi
427
        in      ax, dx
428
        test    al, 2
429
        loopnz  @b
430
        jz      @f
431
        dbgstr 'UHCI controller reset timeout'
432
        jmp     .fail
433
@@:
434
if 0
435
; emergency variant for tests - always wait 10 ms
436
; wait 10 ms
437
        push    esi
438
        push    10
439
        pop     esi
440
        call    delay_ms
441
        pop     esi
442
; clear reset signal
443
        xor     eax, eax
444
        out     dx, ax
445
end if
446
.resetok:
447
; 6. Get number of ports & disable all ports.
448
        add     esi, edi
449
        lea     edx, [edi+UhciPort1StatusReg]
450
.scanports:
451
        cmp     edx, esi
452
        jae     .doneports
453
        in      ax, dx
454
        cmp     ax, 0xFFFF
455
        jz      .doneports
456
        test    al, al
457
        jns     .doneports
458
        xor     eax, eax
459
        out     dx, ax
460
        inc     edx
461
        inc     edx
462
        jmp     .scanports
463
.doneports:
464
        lea     esi, [edx-UhciPort1StatusReg]
465
        sub     esi, edi
466
        shr     esi, 1  ; esi = number of ports
467
        jnz     @f
468
        dbgstr 'error: no ports on UHCI controller'
469
        jmp     .fail
470
@@:
471
; 7. Setup the rest of uhci_controller.
472
        xchg    esi, [esp]      ; restore the pointer to uhci_controller from the step 1
473
        add     esi, sizeof.uhci_controller
474
        pop     [esi+usb_controller.NumPorts]
475
        DEBUGF 1,'K : UHCI controller at %x:%x with %d ports initialized\n',[.bus]:2,[.devfn]:2,[esi+usb_controller.NumPorts]
476
        mov     [esi+uhci_controller.IOBase-sizeof.uhci_controller], edi
477
        mov     eax, [timer_ticks]
478
        mov     [esi+uhci_controller.LastPollTime-sizeof.uhci_controller], eax
479
; 8. Hook interrupt.
480
        mov     ah, [.bus]
481
        mov     al, 0
482
        mov     bh, [.devfn]
483
        mov     bl, 3Ch
484
        call    pci_read_reg
485
; al = IRQ
486
;       DEBUGF 1,'K : UHCI %x: io=%x, irq=%x\n',esi,edi,al
487
        movzx   eax, al
488
        stdcall attach_int_handler, eax, uhci_irq, esi
489
; 9. Setup controller registers.
490
        xor     eax, eax
491
        mov     edx, [esi+uhci_controller.IOBase-sizeof.uhci_controller]
492
; 9a. UhciStatusReg := 3Fh: clear all status bits
493
; (for this register 1 clears the corresponding bit, 0 does not change it).
494
        inc     edx
495
        inc     edx     ; UhciStatusReg == 2
496
        mov     al, 3Fh
497
        out     dx, ax
498
; 9b. UhciInterruptReg := 0Dh.
499
        inc     edx
500
        inc     edx     ; UhciInterruptReg == 4
501
        mov     al, 0Dh
502
        out     dx, ax
503
; 9c. UhciFrameNumberReg := 0.
504
        inc     edx
505
        inc     edx     ; UhciFrameNumberReg == 6
506
        mov     al, 0
507
        out     dx, ax
508
; 9d. UhciBaseAddressReg := physical address of uhci_controller.
509
        inc     edx
510
        inc     edx     ; UhciBaseAddressReg == 8
511
        lea     eax, [esi-sizeof.uhci_controller]
512
        call    get_phys_addr
513
        out     dx, eax
514
; 9e. UhciCommandReg := Run + Configured + (MaxPacket is 64 bytes)
515
        sub     edx, UhciBaseAddressReg ; UhciCommandReg == 0
516
        mov     ax, 0C1h        ; Run, Configured, MaxPacket = 64b
517
        out     dx, ax
518
; 10. Do initial scan of existing devices.
519
        call    uhci_poll_roothub
520
; 11. Return pointer to usb_controller.
521
        xchg    eax, esi
522
        ret
523
.fail:
524
; On error, pop the pointer saved at step 1 and return zero.
525
; Note that the main code branch restores the stack at step 7 and never fails
526
; after step 7.
527
        pop     ecx
528
        xor     eax, eax
529
        ret
530
endp
531
 
532
; Controller-specific pre-initialization function: take ownership from BIOS.
533
; UHCI has no mechanism to ask the owner politely to release ownership,
534
; so do it in inpolite way, preventing controller from any SMI activity.
535
proc uhci_kickoff_bios
536
; 1. Get the I/O address.
537
        mov     ah, [esi+PCIDEV.bus]
538
        mov     al, 1
539
        mov     bh, [esi+PCIDEV.devfn]
540
        mov     bl, 20h
541
        call    pci_read_reg
542
        and     eax, 0xFFFC
543
        xchg    eax, edx
544
; 2. Stop the controller and disable all interrupts.
545
        in      ax, dx
546
        and     al, not 1
547
        out     dx, ax
548
        add     edx, UhciInterruptReg
549
        xor     eax, eax
550
        out     dx, ax
551
; 3. Disable all bits for SMI routing, clear SMI routing status,
552
; enable master interrupt bit.
553
        mov     ah, [esi+PCIDEV.bus]
554
        mov     al, 1
555
        mov     bl, 0xC0
556
        mov     ecx, 0AF00h
557
        call    pci_write_reg
558
        ret
559
endp
560
 
561
; Helper procedure for step 3 of uhci_init.
562
; Initializes the static head of one list.
563
; eax = physical address of the "next" list, esi = pointer to the "next" list,
564
; edi = pointer to head to initialize.
565
; Advances edi to the next head, keeps eax/esi.
566
proc uhci_init_static_endpoint
567
        mov     [edi+uhci_static_ep.NextQH], eax
568
        mov     byte [edi+uhci_static_ep.HeadTD], 1
569
        mov     [edi+uhci_static_ep.NextList], esi
570
        add     edi, uhci_static_ep.SoftwarePart
571
        call    usb_init_static_endpoint
572
        add     edi, sizeof.uhci_static_ep - uhci_static_ep.SoftwarePart
573
        ret
574
endp
575
 
576
; Helper procedure for step 3 of uhci_init, see comments there.
577
; Initializes one half of group of static heads.
578
; edx = size of the next group = half of size of the group,
579
; edi = pointer to the group, eax = physical address of the next group,
580
; esi = pointer to the next group.
581
; Advances eax, esi, edi to next group, keeps edx.
582
proc uhci_init_static_ep_group
583
        push    edx
584
@@:
585
        call    uhci_init_static_endpoint
586
        add     eax, sizeof.uhci_static_ep
587
        add     esi, sizeof.uhci_static_ep
588
        dec     edx
589
        jnz     @b
590
        pop     edx
591
        ret
592
endp
593
 
594
; IRQ handler for UHCI controllers.
595
uhci_irq.noint:
596
; Not our interrupt: restore esi and return zero.
597
        pop     esi
598
        xor     eax, eax
599
        ret
600
proc uhci_irq
601
        push    esi     ; save used register to be cdecl
602
virtual at esp
603
                dd      ?       ; saved esi
604
                dd      ?       ; return address
605
.controller     dd      ?
606
end virtual
607
        mov     esi, [.controller]
608
; 1. Read UhciStatusReg.
609
        mov     edx, [esi+uhci_controller.IOBase-sizeof.uhci_controller]
610
        inc     edx
611
        inc     edx     ; UhciStatusReg == 2
612
        in      ax, dx
613
; 2. Test whether it is our interrupt; if so, at least one status bit is set.
614
        test    al, 0x1F
615
        jz      .noint
616
; 3. Clear all status bits.
617
        out     dx, ax
618
; 4. Sanity check.
619
        test    al, 0x3C
620
        jz      @f
621
        DEBUGF 1,'K : something terrible happened with UHCI (%x)\n',al
622
@@:
623
; 5. We can't do too much from an interrupt handler, e.g. we can't take
624
; any mutex locks since our code could be called when another code holds the
625
; lock and has no chance to release it. Thus, only inform the processing thread
626
; that it should scan the queue and wake it if needed.
627
        lock or byte [esi+uhci_controller.DeferredActions-sizeof.uhci_controller], al
628
        push    ebx
629
        xor     ebx, ebx
630
        inc     ebx
631
        call    usb_wakeup_if_needed
632
        pop     ebx
633
; 6. This is our interrupt; return 1.
634
        mov     al, 1
635
        pop     esi     ; restore used register to be stdcall
636
        ret
637
endp
638
 
639
; This procedure is called in the USB thread from usb_thread_proc,
640
; processes regular actions and those actions which can't be safely done
641
; from interrupt handler.
642
; Returns maximal time delta before the next call.
643
proc uhci_process_deferred
644
        push    ebx edi         ; save used registers to be stdcall
645
; 1. Initialize the return value.
646
        push    -1
647
; 2. Poll the root hub every UHCI_POLL_INTERVAL ticks.
648
; Also force polling if some transaction has completed with errors;
649
; the error can be caused by disconnect, try to detect it.
650
        test    byte [esi+uhci_controller.DeferredActions-sizeof.uhci_controller], 2
651
        jnz     .force_poll
652
        mov     eax, [timer_ticks]
653
        sub     eax, [esi+uhci_controller.LastPollTime-sizeof.uhci_controller]
654
        sub     eax, UHCI_POLL_INTERVAL
655
        jl      .nopoll
656
.force_poll:
657
        mov     eax, [timer_ticks]
658
        mov     [esi+uhci_controller.LastPollTime-sizeof.uhci_controller], eax
659
        call    uhci_poll_roothub
660
        mov     eax, -UHCI_POLL_INTERVAL
661
.nopoll:
662
        neg     eax
663
        cmp     [esp], eax
664
        jb      @f
665
        mov     [esp], eax
666
@@:
667
; 3. Process wait lists.
668
; 3a. Test whether there is a wait request.
669
        mov     eax, [esi+usb_controller.WaitPipeRequestAsync]
670
        cmp     eax, [esi+usb_controller.ReadyPipeHeadAsync]
671
        jnz     .check_removed
672
        mov     eax, [esi+usb_controller.WaitPipeRequestPeriodic]
673
        cmp     eax, [esi+usb_controller.ReadyPipeHeadPeriodic]
674
        jz      @f
675
.check_removed:
676
; 3b. Yep. Find frame and compare it with the saved one.
677
        mov     edx, [esi+uhci_controller.IOBase-sizeof.uhci_controller]
678
        add     edx, UhciFrameNumberReg
679
        in      ax, dx
680
        cmp     word [esi+usb_controller.StartWaitFrame], ax
681
        jnz     .removed
682
; 3c. The same frame; wake up in 0.01 sec.
683
        mov     dword [esp], 1
684
        jmp     @f
685
.removed:
686
; 3d. The frame is changed, old contents is guaranteed to be forgotten.
687
        mov     eax, [esi+usb_controller.WaitPipeRequestAsync]
688
        mov     [esi+usb_controller.ReadyPipeHeadAsync], eax
689
        mov     eax, [esi+usb_controller.WaitPipeRequestPeriodic]
690
        mov     [esi+usb_controller.ReadyPipeHeadPeriodic], eax
691
@@:
692
; 4. Process disconnect events. This should be done after step 2
693
; (which includes the first stage of disconnect processing).
694
        call    usb_disconnect_stage2
695
; 5. Test whether USB_CONNECT_DELAY for a connected device is over.
696
; Call uhci_new_port for all such devices.
697
        xor     ecx, ecx
698
        cmp     [esi+usb_controller.NewConnected], ecx
699
        jz      .skip_newconnected
700
.portloop:
701
        bt      [esi+usb_controller.NewConnected], ecx
702
        jnc     .noconnect
703
        mov     eax, [timer_ticks]
704
        sub     eax, [esi+usb_controller.ConnectedTime+ecx*4]
705
        sub     eax, USB_CONNECT_DELAY
706
        jge     .connected
707
        neg     eax
708
        cmp     [esp], eax
709
        jb      .nextport
710
        mov     [esp], eax
711
        jmp     .nextport
712
.connected:
713
        btr     [esi+usb_controller.NewConnected], ecx
714
        call    uhci_new_port
715
.noconnect:
716
.nextport:
717
        inc     ecx
718
        cmp     ecx, [esi+usb_controller.NumPorts]
719
        jb      .portloop
720
.skip_newconnected:
721
; 6. Test for processed packets.
722
; This should be done after step 4, so transfers which were failed due
723
; to disconnect are marked with the exact reason, not just
724
; 'device not responding'.
725
        xor     eax, eax
726
        xchg    byte [esi+uhci_controller.DeferredActions-sizeof.uhci_controller], al
727
        test    al, 3
728
        jz      .noioc
729
        call    uhci_process_updated_schedule
730
.noioc:
731
; 7. Test whether reset signalling has been started. If so,
732
; either should be stopped now (if time is over) or schedule wakeup (otherwise).
733
; This should be done after step 6, because a completed SET_ADDRESS command
734
; could result in reset of a new port.
735
.test_reset:
736
; 7a. Test whether reset signalling is active.
737
        cmp     [esi+usb_controller.ResettingStatus], 1
738
        jnz     .no_reset_in_progress
739
; 7b. Yep. Test whether it should be stopped.
740
        mov     eax, [timer_ticks]
741
        sub     eax, [esi+usb_controller.ResetTime]
742
        sub     eax, USB_RESET_TIME
743
        jge     .reset_done
744
; 7c. Not yet, but initiate wakeup in -eax ticks and exit this step.
745
        neg     eax
746
        cmp     [esp], eax
747
        jb      .skip_reset
748
        mov     [esp], eax
749
        jmp     .skip_reset
750
.reset_done:
751
; 7d. Yep, call the worker function and proceed to 7e.
752
        call    uhci_port_reset_done
753
.no_reset_in_progress:
754
; 7e. Test whether reset process is done, either successful or failed.
755
        cmp     [esi+usb_controller.ResettingStatus], 0
756
        jz      .skip_reset
757
; 7f. Yep. Test whether it should be stopped.
758
        mov     eax, [timer_ticks]
759
        sub     eax, [esi+usb_controller.ResetTime]
760
        sub     eax, USB_RESET_RECOVERY_TIME
761
        jge     .reset_recovery_done
762
; 7g. Not yet, but initiate wakeup in -eax ticks and exit this step.
763
        neg     eax
764
        cmp     [esp], eax
765
        jb      .skip_reset
766
        mov     [esp], eax
767
        jmp     .skip_reset
768
.reset_recovery_done:
769
; 7h. Yep, call the worker function. This could initiate another reset,
770
; so return to the beginning of this step.
771
        call    uhci_port_init
772
        jmp     .test_reset
773
.skip_reset:
774
; 8. Process wait-done notifications, test for new wait requests.
775
; Note: that must be done after steps 4 and 6 which could create new requests.
776
; 8a. Call the worker function.
777
        call    usb_process_wait_lists
778
; 8b. If no new requests, skip the rest of this step.
779
        test    eax, eax
780
        jz      @f
781
; 8c. UHCI is not allowed to cache anything; we don't know what is
782
; processed right now, but we can be sure that the controller will not
783
; use any removed structure starting from the next frame.
784
; Request removal of everything disconnected until now,
785
; schedule wakeup in 0.01 sec.
786
        mov     eax, [esi+usb_controller.WaitPipeListAsync]
787
        mov     [esi+usb_controller.WaitPipeRequestAsync], eax
788
        mov     eax, [esi+usb_controller.WaitPipeListPeriodic]
789
        mov     [esi+usb_controller.WaitPipeRequestPeriodic], eax
790
        mov     edx, [esi+uhci_controller.IOBase-sizeof.uhci_controller]
791
        add     edx, UhciFrameNumberReg
792
        in      ax, dx
793
        mov     word [esi+usb_controller.StartWaitFrame], ax
794
        mov     dword [esp], 1
795
@@:
796
; 9. Return the value from the top of stack.
797
        pop     eax
798
        pop     edi ebx         ; restore used registers to be stdcall.
799
        ret
800
endp
801
 
802
; This procedure is called in the USB thread from uhci_process_deferred
803
; when UHCI IRQ handler has signalled that new IOC-packet was processed.
804
; It scans all lists for completed packets and calls uhci_process_finalized_td
805
; for those packets.
806
; in: esi -> usb_controller
807
proc uhci_process_updated_schedule
808
; Important note: we cannot hold the list lock during callbacks,
809
; because callbacks sometimes open and/or close pipes and thus acquire/release
810
; the corresponding lock itself.
811
; Fortunately, pipes can be finally freed only by another step of
812
; uhci_process_deferred, so all pipes existing at the start of this function
813
; will be valid while this function is running. Some pipes can be removed
814
; from the corresponding list, some pipes can be inserted; insert/remove
815
; functions guarantee that traversing one list yields all pipes that were in
816
; that list at the beginning of the traversing (possibly with some new pipes,
817
; possibly without some new pipes, that doesn't matter).
818
; 1. Process all Periodic lists.
819
        lea     edi, [esi+uhci_controller.IntEDs.SoftwarePart-sizeof.uhci_controller]
820
        lea     ebx, [esi+uhci_controller.IntEDs.SoftwarePart+63*sizeof.uhci_static_ep-sizeof.uhci_controller]
821
@@:
822
        call    uhci_process_updated_list
823
        cmp     edi, ebx
824
        jnz     @b
825
; 2. Process the Control list.
826
        call    uhci_process_updated_list
827
; 3. Process the Bulk list.
828
        call    uhci_process_updated_list
829
; 4. Return.
830
        ret
831
endp
832
 
833
; This procedure is called from uhci_process_updated_schedule,
834
; see comments there.
835
; It processes one list, esi -> usb_controller, edi -> usb_static_ep,
836
; and advances edi to the next head.
837
proc uhci_process_updated_list
838
        push    ebx             ; save used register to be stdcall
839
; 1. Perform the external loop over all pipes.
840
        mov     ebx, [edi+usb_static_ep.NextVirt]
841
.loop:
842
        cmp     ebx, edi
843
        jz      .done
844
; store pointer to the next pipe in the stack
845
        push    [ebx+usb_static_ep.NextVirt]
846
; 2. For every pipe, perform the internal loop over all descriptors.
847
; All descriptors are organized in the queue; we process items from the start
848
; of the queue until a) the last descriptor (not the part of the queue itself)
849
; or b) an active (not yet processed by the hardware) descriptor is reached.
850
        lea     ecx, [ebx+usb_pipe.Lock]
851
        call    mutex_lock
852
        mov     ebx, [ebx+usb_pipe.LastTD]
853
        push    ebx
854
        mov     ebx, [ebx+usb_gtd.NextVirt]
855
.tdloop:
856
; 3. For every descriptor, test active flag and check for end-of-queue;
857
; if either of conditions holds, exit from the internal loop.
858
        cmp     ebx, [esp]
859
        jz      .tddone
860
        mov     eax, [ebx+uhci_gtd.ControlStatus-uhci_gtd.SoftwarePart]
861
        test    eax, 1 shl 23   ; active?
862
        jnz     .tddone
863
; Release the queue lock while processing one descriptor:
864
; callback function could (and often would) schedule another transfer.
865
        push    ecx
866
        call    mutex_unlock
867
        call    uhci_process_finalized_td
868
        pop     ecx
869
        call    mutex_lock
870
        jmp     .tdloop
871
.tddone:
872
        call    mutex_unlock
873
        pop     ebx
874
; End of internal loop, restore pointer to the next pipe
875
; and continue the external loop.
876
        pop     ebx
877
        jmp     .loop
878
.done:
879
        pop     ebx             ; restore used register to be stdcall
880
        add     edi, sizeof.uhci_static_ep
881
        ret
882
endp
883
 
884
; This procedure is called from uhci_process_updated_list, which is itself
885
; called from uhci_process_updated_schedule, see comments there.
886
; It processes one completed descriptor.
887
; in: esi -> usb_controller, ebx -> usb_gtd, out: ebx -> next usb_gtd.
888
proc uhci_process_finalized_td
889
; 1. Remove this descriptor from the list of descriptors for this pipe.
890
        call    usb_unlink_td
891
;       DEBUGF 1,'K : finalized TD:\n'
892
;       DEBUGF 1,'K : %x %x %x %x\n',[ebx-20],[ebx-16],[ebx-12],[ebx-8]
893
;       DEBUGF 1,'K : %x %x %x %x\n',[ebx-4],[ebx],[ebx+4],[ebx+8]
894
; 2. If this is IN transfer into special buffer, copy the data
895
; to target location.
896
        mov     edx, [ebx+uhci_gtd.OrigBufferInfo-uhci_gtd.SoftwarePart]
897
        and     edx, not 1      ; clear lsb (used for another goal)
898
        jz      .nocopy
899
        cmp     byte [ebx+uhci_gtd.Token-uhci_gtd.SoftwarePart], USB_PID_IN
900
        jnz     .nocopy
901
; Note: we assume that pointer to buffer is valid in the memory space of
902
; the USB thread. This means that buffer must reside in kernel memory
903
; (shared by all processes).
904
        push    esi edi
905
        mov     esi, [edx+uhci_original_buffer.UsedBuffer]
906
        mov     edi, [edx+uhci_original_buffer.OrigBuffer]
907
        mov     ecx, [ebx+uhci_gtd.ControlStatus-uhci_gtd.SoftwarePart]
908
        inc     ecx
909
        and     ecx, 7FFh
910
        mov     edx, ecx
911
        shr     ecx, 2
912
        and     edx, 3
913
        rep movsd
914
        mov     ecx, edx
915
        rep movsb
916
        pop     edi esi
917
.nocopy:
918
; 3. Calculate actual number of bytes transferred.
919
; 3a. Read the state.
920
        mov     eax, [ebx+uhci_gtd.ControlStatus-uhci_gtd.SoftwarePart]
921
        mov     ecx, [ebx+uhci_gtd.Token-uhci_gtd.SoftwarePart]
922
; 3b. Get number of bytes processed.
923
        lea     edx, [eax+1]
924
        and     edx, 7FFh
925
; 3c. Subtract number of bytes in this packet.
926
        add     ecx, 1 shl 21
927
        shr     ecx, 21
928
        sub     edx, ecx
929
; 3d. Add total length transferred so far.
930
        add     edx, [ebx+usb_gtd.Length]
931
; Actions on error and on success are slightly different.
932
; 4. Test for error. On error, proceed to step 5, otherwise go to step 6
933
; with ecx = 0 (no error).
934
; USB transaction error is always considered as such.
935
; If short packets are not allowed, UHCI controllers do not set an error bit,
936
; but stop (clear Active bit and do not advance) the queue.
937
; Short packet is considered as an error if the packet is actually short
938
; (actual length is less than maximal one) and the code creating the packet
939
; requested that behaviour (so bit 0 of OrigBufferInfo is set; this could be
940
; because the caller disallowed short packets or because the packet is not
941
; the last one in the corresponding transfer).
942
        xor     ecx, ecx
943
        test    eax, 1 shl 22
944
        jnz     .error
945
        test    byte [ebx+uhci_gtd.OrigBufferInfo-uhci_gtd.SoftwarePart], 1
946
        jz      .notify
947
        cmp     edx, [ebx+usb_gtd.Length]
948
        jz      .notify
949
.error:
950
; 5. There was an error while processing this packet.
951
; The hardware has stopped processing the queue.
952
        DEBUGF 1,'K : TD failed:\n'
953
if uhci_gtd.SoftwarePart <> 20
954
.err modify offsets for debug output
955
end if
956
        DEBUGF 1,'K : %x %x %x %x\n',[ebx-20],[ebx-16],[ebx-12],[ebx-8]
957
        DEBUGF 1,'K : %x %x %x %x\n',[ebx-4],[ebx],[ebx+4],[ebx+8]
958
; 5a. Save the status and length.
959
        push    edx
960
        push    eax
961
        mov     eax, [ebx+usb_gtd.Pipe]
962
        DEBUGF 1,'K : pipe: %x %x\n',[eax+0-uhci_pipe.SoftwarePart],[eax+4-uhci_pipe.SoftwarePart]
963
; 5b. Store the current TD as an error packet.
964
; If an error packet is already stored for this pipe,
965
; it is definitely not used already, so free the old packet.
966
        mov     eax, [eax+uhci_pipe.ErrorTD-uhci_pipe.SoftwarePart]
967
        test    eax, eax
968
        jz      @f
969
        stdcall uhci_free_td, eax
970
@@:
971
        mov     eax, [ebx+usb_gtd.Pipe]
972
        mov     [eax+uhci_pipe.ErrorTD-uhci_pipe.SoftwarePart], ebx
973
; 5c. Traverse the list of descriptors looking for the final packet
974
; for this transfer.
975
; Free and unlink non-final descriptors, except the current one.
976
; Final descriptor will be freed in step 7.
977
        call    usb_is_final_packet
978
        jnc     .found_final
979
        mov     ebx, [ebx+usb_gtd.NextVirt]
980
.look_final:
981
        call    usb_unlink_td
982
        call    usb_is_final_packet
983
        jnc     .found_final
984
        push    [ebx+usb_gtd.NextVirt]
985
        stdcall uhci_free_td, ebx
986
        pop     ebx
987
        jmp     .look_final
988
.found_final:
989
; 5d. Restore the status saved in 5a and transform it to the error code.
990
        pop     eax     ; error code
991
        shr     eax, 16
992
; Notes:
993
; * any USB transaction error results in Stalled bit; if it is not set,
994
;   but we are here, it must be due to short packet;
995
; * babble is considered a fatal USB transaction error,
996
;   other errors just lead to retrying the transaction;
997
;   if babble is detected, return the corresponding error;
998
; * if several non-fatal errors have occured during transaction retries,
999
;   all corresponding bits are set. In this case, return some error code,
1000
;   the order is quite arbitrary.
1001
        push    USB_STATUS_UNDERRUN
1002
        pop     ecx
1003
        test    al, 1 shl (22-16)       ; not Stalled?
1004
        jz      .know_error
1005
        mov     cl, USB_STATUS_OVERRUN
1006
        test    al, 1 shl (20-16)       ; Babble detected?
1007
        jnz     .know_error
1008
        mov     cl, USB_STATUS_BITSTUFF
1009
        test    al, 1 shl (17-16)       ; Bitstuff error?
1010
        jnz     .know_error
1011
        mov     cl, USB_STATUS_NORESPONSE
1012
        test    al, 1 shl (18-16)       ; CRC/TimeOut error?
1013
        jnz     .know_error
1014
        mov     cl, USB_STATUS_BUFOVERRUN
1015
        test    al, 1 shl (21-16)       ; Data Buffer error?
1016
        jnz     .know_error
1017
        mov     cl, USB_STATUS_STALL
1018
.know_error:
1019
; 5e. If error code is USB_STATUS_UNDERRUN
1020
; and the last TD allows short packets, it is not an error.
1021
; Note: all TDs except the last one in any transfer stage are marked
1022
; as short-packet-is-error to stop controller from further processing
1023
; of that stage; we need to restart processing from a TD following the last.
1024
; After that, go to step 6 with ecx = 0 (no error).
1025
        cmp     ecx, USB_STATUS_UNDERRUN
1026
        jnz     @f
1027
        test    byte [ebx+uhci_gtd.OrigBufferInfo-uhci_gtd.SoftwarePart], 1
1028
        jnz     @f
1029
; The controller has stopped this queue on the error packet.
1030
; Update uhci_pipe.HeadTD to point to the next packet in the queue.
1031
        call    uhci_fix_toggle
1032
        xor     ecx, ecx
1033
.control:
1034
        mov     eax, [ebx+uhci_gtd.NextTD-uhci_gtd.SoftwarePart]
1035
        and     al, not 0xF
1036
        mov     edx, [ebx+usb_gtd.Pipe]
1037
        mov     [edx+uhci_pipe.HeadTD-uhci_pipe.SoftwarePart], eax
1038
        pop     edx     ; length
1039
        jmp     .notify
1040
@@:
1041
; 5f. Abort the entire transfer.
1042
; There are two cases: either there is only one transfer stage
1043
; (everything except control transfers), then ebx points to the last TD and
1044
; all previous TD were unlinked and dismissed (if possible),
1045
; or there are several stages (a control transfer) and ebx points to the last
1046
; TD of Data or Status stage (usb_is_final_packet does not stop in Setup stage,
1047
; because Setup stage can not produce short packets); for Data stage, we need
1048
; to unlink and free (if possible) one more TD and advance ebx to the next one.
1049
        cmp     [ebx+usb_gtd.Callback], 0
1050
        jnz     .normal
1051
; We cannot free ErrorTD yet, it could still be used by the hardware.
1052
        push    ecx
1053
        mov     eax, [ebx+usb_gtd.Pipe]
1054
        push    [ebx+usb_gtd.NextVirt]
1055
        cmp     ebx, [eax+uhci_pipe.ErrorTD-uhci_pipe.SoftwarePart]
1056
        jz      @f
1057
        stdcall uhci_free_td, ebx
1058
@@:
1059
        pop     ebx
1060
        call    usb_unlink_td
1061
        pop     ecx
1062
.normal:
1063
; 5g. For bulk/interrupt transfers we have no choice but halt the queue,
1064
; the driver should intercede (through some API which is not written yet).
1065
; Control pipes normally recover at the next SETUP transaction (first stage
1066
; of any control transfer), so we hope on the best and just advance the queue
1067
; to the next transfer. (According to the standard, "A control pipe may also
1068
; support functional stall as well, but this is not recommended.").
1069
        mov     edx, [ebx+usb_gtd.Pipe]
1070
        cmp     [edx+usb_pipe.Type], CONTROL_PIPE
1071
        jz      .control
1072
; Bulk/interrupt transfer; halt the queue.
1073
        mov     eax, [ebx+uhci_gtd.NextTD-uhci_gtd.SoftwarePart]
1074
        and     al, not 0xF
1075
        inc     eax     ; set Halted bit
1076
        mov     [edx+uhci_pipe.HeadTD-uhci_pipe.SoftwarePart], eax
1077
        pop     edx     ; restore length saved in step 5a
1078
.notify:
1079
; 6. Either the descriptor in ebx was processed without errors,
1080
; or all necessary error actions were taken and ebx points to the last
1081
; related descriptor.
1082
; 6a. Test whether it is the last packet in the transfer
1083
; <=> it has an associated callback.
1084
        mov     eax, [ebx+usb_gtd.Callback]
1085
        test    eax, eax
1086
        jz      .nocallback
1087
; 6b. It has an associated callback; call it with corresponding parameters.
1088
        stdcall_verify eax, [ebx+usb_gtd.Pipe], ecx, \
1089
                [ebx+usb_gtd.Buffer], edx, [ebx+usb_gtd.UserData]
1090
        jmp     .callback
1091
.nocallback:
1092
; 6c. It is an intermediate packet. Add its length to the length
1093
; in the following packet.
1094
        mov     eax, [ebx+usb_gtd.NextVirt]
1095
        add     [eax+usb_gtd.Length], edx
1096
.callback:
1097
; 7. Free the current descriptor (if allowed) and return the next one.
1098
; 7a. Save pointer to the next descriptor.
1099
        push    [ebx+usb_gtd.NextVirt]
1100
; 7b. Free the descriptor, unless it is saved as ErrorTD.
1101
        mov     eax, [ebx+usb_gtd.Pipe]
1102
        cmp     [eax+uhci_pipe.ErrorTD-uhci_pipe.SoftwarePart], ebx
1103
        jz      @f
1104
        stdcall uhci_free_td, ebx
1105
@@:
1106
; 7c. Restore pointer to the next descriptor and return.
1107
        pop     ebx
1108
        ret
1109
endp
1110
 
1111
; Helper procedure for restarting transfer queue.
1112
; When transfers are queued, their toggle bit is filled assuming that
1113
; everything will go without errors. On error, some packets needs to be
1114
; skipped, so toggle bits may become incorrect.
1115
; This procedure fixes toggle bits.
1116
; in: ebx -> last packet to be skipped, ErrorTD -> last processed packet
1117
proc uhci_fix_toggle
1118
; 1. Nothing to do for control pipes: in that case,
1119
; toggle bits for different transfer stages are independent.
1120
        mov     ecx, [ebx+usb_gtd.Pipe]
1121
        cmp     [ecx+usb_pipe.Type], CONTROL_PIPE
1122
        jz      .nothing
1123
; 2. The hardware expects next packet with toggle = (ErrorTD.toggle xor 1),
1124
; the current value in next packet is (ebx.toggle xor 1).
1125
; Nothing to do if ErrorTD.toggle == ebx.toggle.
1126
        mov     eax, [ecx+uhci_pipe.ErrorTD-uhci_pipe.SoftwarePart]
1127
        mov     eax, [eax+uhci_gtd.Token-uhci_gtd.SoftwarePart]
1128
        xor     eax, [ebx+uhci_gtd.Token-uhci_gtd.SoftwarePart]
1129
        test    eax, 1 shl 19
1130
        jz      .nothing
1131
; 3. Lock the transfer queue.
1132
        add     ecx, usb_pipe.Lock
1133
        call    mutex_lock
1134
; 4. Flip the toggle bit in all packets from ebx.NextVirt to ecx.LastTD
1135
; (inclusive).
1136
        mov     eax, [ebx+usb_gtd.NextVirt]
1137
.loop:
1138
        xor     byte [eax+uhci_gtd.Token-uhci_gtd.SoftwarePart+2], 1 shl (19-16)
1139
        cmp     eax, [ecx+usb_pipe.LastTD-usb_pipe.Lock]
1140
        mov     eax, [eax+usb_gtd.NextVirt]
1141
        jnz     .loop
1142
; 5. Flip the toggle bit in uhci_pipe structure.
1143
        xor     byte [ecx+uhci_pipe.Token-uhci_pipe.SoftwarePart-usb_pipe.Lock+2], 1 shl (19-16)
1144
        or      dword [ecx+uhci_pipe.Token-uhci_pipe.SoftwarePart-usb_pipe.Lock], eax
1145
; 6. Unlock the transfer queue.
1146
        call    mutex_unlock
1147
.nothing:
1148
        ret
1149
endp
1150
 
1151
; This procedure is called in the USB thread from uhci_process_deferred
1152
; every UHCI_POLL_INTERVAL ticks. It polls the controller for
1153
; connect/disconnect events.
1154
; in: esi -> usb_controller
1155
proc uhci_poll_roothub
1156
        push    ebx     ; save used register to be stdcall
1157
; 1. Prepare for the loop for every port.
1158
        xor     ecx, ecx
1159
.portloop:
1160
; 2. Some implementations of UHCI set ConnectStatusChange bit in a response to
1161
; PortReset. Thus, we must ignore this change for port which is resetting.
1162
        cmp     cl, [esi+usb_controller.ResettingPort]
1163
        jz      .nextport
1164
; 3. Read port status.
1165
        mov     edx, [esi+uhci_controller.IOBase-sizeof.uhci_controller]
1166
        lea     edx, [edx+ecx*2+UhciPort1StatusReg]
1167
        in      ax, dx
1168
; 4. If no change bits are set, continue to the next port.
1169
        test    al, 0Ah
1170
        jz      .nextport
1171
; 5. Clear change bits and read the status again.
1172
; (It is possible, although quite unlikely, that some event occurs between
1173
; the first read and the clearing, invalidating the old status. If an event
1174
; occurs after the clearing, we will not miss it, looking in the next scan.
1175
        out     dx, ax
1176
        mov     ebx, eax
1177
        in      ax, dx
1178
; 6. Process connect change notifications.
1179
; Note: if connect status has changed, ignore enable status change;
1180
; it is normal to disable a port at disconnect event.
1181
; Some controllers set enable status change bit, some don't.
1182
        test    bl, 2
1183
        jz      .noconnectchange
1184
        DEBUGF 1,'K : [%d] UHCI %x connect status changed, %x/%x\n',[timer_ticks],esi,bx,ax
1185
; yep. Regardless of the current status, note disconnect event;
1186
; if there is something connected, store the connect time and note connect event.
1187
; In any way, do not process
1188
        bts     [esi+usb_controller.NewDisconnected], ecx
1189
        test    al, 1
1190
        jz      .disconnect
1191
        mov     eax, [timer_ticks]
1192
        mov     [esi+usb_controller.ConnectedTime+ecx*4], eax
1193
        bts     [esi+usb_controller.NewConnected], ecx
1194
        jmp     .nextport
1195
.disconnect:
1196
        btr     [esi+usb_controller.NewConnected], ecx
1197
        jmp     .nextport
1198
.noconnectchange:
1199
; 7. Process enable change notifications.
1200
; Note: that needs work.
1201
        test    bl, 8
1202
        jz      .nextport
1203
        test    al, 4
1204
        jnz     .nextport
1205
        dbgstr 'Port disabled'
1206
.nextport:
1207
; 8. Continue the loop for every port.
1208
        inc     ecx
1209
        cmp     ecx, [esi+usb_controller.NumPorts]
1210
        jb      .portloop
1211
        pop     ebx     ; restore used register to be stdcall
1212
        ret
1213
endp
1214
 
1215
; This procedure is called from uhci_process_deferred when
1216
; a new device was connected at least USB_CONNECT_DELAY ticks
1217
; and therefore is ready to be configured.
1218
; in: esi -> usb_controller, ecx = port (zero-based)
1219
proc uhci_new_port
1220
; test whether we are configuring another port
1221
; if so, postpone configuring and return
1222
        bts     [esi+usb_controller.PendingPorts], ecx
1223
        cmp     [esi+usb_controller.ResettingPort], -1
1224
        jnz     .nothing
1225
        btr     [esi+usb_controller.PendingPorts], ecx
1226
; fall through to uhci_new_port.reset
1227
 
1228
; This function is called from uhci_new_port and uhci_test_pending_port.
1229
; It starts reset signalling for the port. Note that in USB first stages
1230
; of configuration can not be done for several ports in parallel.
1231
.reset:
1232
; 1. Store information about resetting hub (roothub) and port.
1233
        and     [esi+usb_controller.ResettingHub], 0
1234
        mov     [esi+usb_controller.ResettingPort], cl
1235
; 2. Initiate reset signalling.
1236
        mov     edx, [esi+uhci_controller.IOBase-sizeof.uhci_controller]
1237
        lea     edx, [edx+ecx*2+UhciPort1StatusReg]
1238
        in      ax, dx
1239
        or      ah, 2
1240
        out     dx, ax
1241
; 3. Store the current time and set status to 1 = reset signalling active.
1242
        mov     eax, [timer_ticks]
1243
        mov     [esi+usb_controller.ResetTime], eax
1244
        mov     [esi+usb_controller.ResettingStatus], 1
1245
.nothing:
1246
        ret
1247
endp
1248
 
1249
; This procedure is called from uhci_process_deferred when
1250
; reset signalling for a port needs to be finished.
1251
proc uhci_port_reset_done
1252
; 1. Stop reset signalling.
1253
        movzx   ecx, [esi+usb_controller.ResettingPort]
1254
        mov     edx, [esi+uhci_controller.IOBase-sizeof.uhci_controller]
1255
        lea     edx, [edx+ecx*2+UhciPort1StatusReg]
1256
        in      ax, dx
1257
        DEBUGF 1,'K : [%d] UHCI %x status %x/',[timer_ticks],esi,ax
1258
        and     ah, not 2
1259
        out     dx, ax
1260
; 2. Status bits in UHCI are invalid during reset signalling.
1261
; Wait a millisecond while status bits become valid again.
1262
        push    esi
1263
        push    1
1264
        pop     esi
1265
        call    delay_ms
1266
        pop     esi
1267
; 3. ConnectStatus bit is zero during reset and becomes 1 during step 2;
1268
; some controllers interpret this as a (fake) connect event.
1269
; Enable port and clear status change notification.
1270
        in      ax, dx
1271
        DEBUGF 1,'%x\n',ax
1272
        or      al, 6   ; enable port, clear status change
1273
        out     dx, ax
1274
; 4. Store the current time and set status to 2 = reset recovery active.
1275
        mov     eax, [timer_ticks]
1276
        DEBUGF 1,'K : reset done at %d\n',[timer_ticks]
1277
        mov     [esi+usb_controller.ResetTime], eax
1278
        mov     [esi+usb_controller.ResettingStatus], 2
1279
        ret
1280
endp
1281
 
1282
; This procedure is called from uhci_process_deferred when
1283
; a new device has been reset, recovered after reset and
1284
; needs to be configured.
1285
; in: esi -> usb_controller
1286
proc uhci_port_init
1287
; 1. Read port status.
1288
        mov     [esi+usb_controller.ResettingStatus], 0
1289
        movzx   ecx, [esi+usb_controller.ResettingPort]
1290
        mov     edx, [esi+uhci_controller.IOBase-sizeof.uhci_controller]
1291
        lea     edx, [edx+ecx*2+UhciPort1StatusReg]
1292
        in      ax, dx
1293
        DEBUGF 1,'K : [%d] UHCI %x status %x\n',[timer_ticks],esi,ax
1294
; 2. If the device has been disconnected, stop the initialization.
1295
        test    al, 1
1296
        jnz     @f
1297
        dbgstr 'USB port disabled after reset'
1298
        jmp     usb_test_pending_port
1299
@@:
1300
; 3. Copy LowSpeed bit to bit 0 of eax and call the worker procedure
1301
; to notify the protocol layer about new UHCI device.
1302
        push    edx
1303
        mov     al, ah
1304
        call    uhci_new_device
1305
        pop     edx
1306
        test    eax, eax
1307
        jnz     .nothing
1308
; 4. If something at the protocol layer has failed
1309
; (no memory, no bus address), disable the port and stop the initialization.
1310
.disable_exit:
1311
        in      ax, dx
1312
        and     al, not 4
1313
        out     dx, ax  ; disable the port
1314
        jmp     usb_test_pending_port
1315
.nothing:
1316
        ret
1317
endp
1318
 
1319
; This procedure is called from uhci_port_init and from hub support code
1320
; when a new device is connected and has been reset.
1321
; It calls usb_new_device at the protocol layer with correct parameters.
1322
; in: esi -> usb_controller, eax = speed;
1323
; UHCI is USB1 device, so only low bit of eax (LowSpeed) is used.
1324
proc uhci_new_device
1325
; 1. Clear all bits of speed except bit 0.
1326
        and     eax, 1
1327
; 2. Store the speed for the protocol layer.
1328
        mov     [esi+usb_controller.ResettingSpeed], al
1329
; 3. Create pseudo-pipe in the stack.
1330
; See uhci_init_pipe: only .Controller and .Token fields are used.
1331
        push    esi     ; fill .Controller field
1332
        mov     ecx, esp
1333
        shl     eax, 20 ; bit 20 = LowSpeedDevice
1334
        push    eax     ; ignored (ErrorTD)
1335
        push    eax     ; .Token field: DeviceAddress is zero, bit 20 = LowSpeedDevice
1336
; 4. Notify the protocol layer.
1337
        call    usb_new_device
1338
; 5. Cleanup the stack after step 3 and return.
1339
        add     esp, 12
1340
        ret
1341
endp
1342
 
1343
; This procedure is called from usb_set_address_callback
1344
; and stores USB device address in the uhci_pipe structure.
1345
; in: esi -> usb_controller, ebx -> usb_pipe, cl = address
1346
proc uhci_set_device_address
1347
        mov     byte [ebx+uhci_pipe.Token+1-uhci_pipe.SoftwarePart], cl
1348
        call    usb_subscription_done
1349
        ret
1350
endp
1351
 
1352
; This procedure returns USB device address from the uhci_pipe structure.
1353
; in: esi -> usb_controller, ebx -> usb_pipe
1354
; out: eax = endpoint address
1355
proc uhci_get_device_address
1356
        mov     al, byte [ebx+uhci_pipe.Token+1-uhci_pipe.SoftwarePart]
1357
        and     eax, 7Fh
1358
        ret
1359
endp
1360
 
1361
; This procedure is called from usb_set_address_callback
1362
; if the device does not accept SET_ADDRESS command and needs
1363
; to be disabled at the port level.
1364
; in: esi -> usb_controller, ecx = port (zero-based)
1365
proc uhci_port_disable
1366
        mov     edx, [esi+uhci_controller.IOBase-sizeof.uhci_controller]
1367
        lea     edx, [edx+UhciPort1StatusReg+ecx*2]
1368
        in      ax, dx
1369
        and     al, not 4
1370
        out     dx, ax
1371
        ret
1372
endp
1373
 
1374
; This procedure is called from usb_get_descr8_callback when
1375
; the packet size for zero endpoint becomes known and
1376
; stores the packet size in uhci_pipe structure.
1377
; in: esi -> usb_controller, ebx -> usb_pipe, ecx = packet size
1378
proc uhci_set_endpoint_packet_size
1379
        dec     ecx
1380
        shl     ecx, 21
1381
        and     [ebx+uhci_pipe.Token-uhci_pipe.SoftwarePart], (1 shl 21) - 1
1382
        or      [ebx+uhci_pipe.Token-uhci_pipe.SoftwarePart], ecx
1383
; uhci_pipe.Token field is purely for software bookkeeping and does not affect
1384
; the hardware; thus, we can continue initialization immediately.
1385
        call    usb_subscription_done
1386
        ret
1387
endp
1388
 
1389
; This procedure is called from API usb_open_pipe and processes
1390
; the controller-specific part of this API. See docs.
1391
; in: edi -> usb_pipe for target, ecx -> usb_pipe for config pipe,
1392
; esi -> usb_controller, eax -> usb_gtd for the first TD,
1393
; [ebp+12] = endpoint, [ebp+16] = maxpacket, [ebp+20] = type
1394
proc uhci_init_pipe
1395
; inherit some variables from the parent usb_open_pipe
1396
virtual at ebp+8
1397
.config_pipe    dd      ?
1398
.endpoint       dd      ?
1399
.maxpacket      dd      ?
1400
.type           dd      ?
1401
.interval       dd      ?
1402
end virtual
1403
; 1. Initialize ErrorTD to zero.
1404
        and     [edi+uhci_pipe.ErrorTD-uhci_pipe.SoftwarePart], 0
1405
; 2. Initialize HeadTD to the physical address of the first TD.
1406
        push    eax     ; store pointer to the first TD for step ?
1407
        sub     eax, uhci_gtd.SoftwarePart
1408
        call    get_phys_addr
1409
        mov     [edi+uhci_pipe.HeadTD-uhci_pipe.SoftwarePart], eax
1410
; 3. Initialize Token field:
1411
; take DeviceAddress and LowSpeedDevice from the parent pipe,
1412
; take Endpoint and MaximumLength fields from API arguments,
1413
; set PID depending on pipe type and provided pipe direction,
1414
; set DataToggle to zero.
1415
        mov     eax, [ecx+uhci_pipe.Token-uhci_pipe.SoftwarePart]
1416
        and     eax, 0x107F00   ; keep DeviceAddress and LowSpeedDevice
1417
        mov     edx, [.endpoint]
1418
        and     edx, 15
1419
        shl     edx, 15
1420
        or      eax, edx
1421
        mov     edx, [.maxpacket]
1422
        dec     edx
1423
        shl     edx, 21
1424
        or      eax, edx
1425
        mov     al, USB_PID_SETUP
1426
        cmp     [.type], CONTROL_PIPE
1427
        jz      @f
1428
        mov     al, USB_PID_OUT
1429
        test    byte [.endpoint], 80h
1430
        jz      @f
1431
        mov     al, USB_PID_IN
1432
@@:
1433
        mov     [edi+uhci_pipe.Token-uhci_pipe.SoftwarePart], eax
1434
; 4. Initialize the first TD:
1435
; copy Token from uhci_pipe.Token zeroing reserved bit 20,
1436
; set ControlStatus for future transfers, bit make it inactive,
1437
; set bit 0 in NextTD = "no next TD".
1438
        pop     edx     ; restore pointer saved in step 2
1439
        mov     [edx+uhci_gtd.Token-uhci_gtd.SoftwarePart], eax
1440
        and     byte [edx+uhci_gtd.Token+2-uhci_gtd.SoftwarePart], not (1 shl (20-16))
1441
        and     eax, 1 shl 20
1442
        shl     eax, 6
1443
        or      eax, UHCI_INVALID_LENGTH + (3 shl 27)
1444
                ; not processed, inactive, allow 3 errors
1445
        mov     [edx+uhci_gtd.ControlStatus-uhci_gtd.SoftwarePart], eax
1446
        mov     [edx+uhci_gtd.NextTD-uhci_gtd.SoftwarePart], 1
1447
; 5. Select the corresponding list and insert to the list.
1448
; 5a. Use Control list for control pipes, Bulk list for bulk pipes.
1449
        lea     edx, [esi+uhci_controller.ControlED.SoftwarePart-sizeof.uhci_controller]
1450
        cmp     [.type], BULK_PIPE
1451
        jb      .insert ; control pipe
1452
        lea     edx, [esi+uhci_controller.BulkED.SoftwarePart-sizeof.uhci_controller]
1453
        jz      .insert ; bulk pipe
1454
.interrupt_pipe:
1455
; 5b. For interrupt pipes, let the scheduler select the appropriate list
1456
; based on the current bandwidth distribution and the requested bandwidth.
1457
; This could fail if the requested bandwidth is not available;
1458
; if so, return an error.
1459
        lea     edx, [esi + uhci_controller.IntEDs - sizeof.uhci_controller]
1460
        lea     eax, [esi + uhci_controller.IntEDs + 32*sizeof.uhci_static_ep - sizeof.uhci_controller]
1461
        push    64
1462
        pop     ecx
1463
        call    usb1_select_interrupt_list
1464
        test    edx, edx
1465
        jz      .return0
1466
.insert:
1467
; Insert to the head of the corresponding list.
1468
; Note: inserting to the head guarantees that the list traverse in
1469
; uhci_process_updated_schedule, once started, will not interact with new pipes.
1470
; However, we still need to ensure that links in the new pipe (edi.NextVirt)
1471
; are initialized before links to the new pipe (edx.NextVirt).
1472
; 5c. Insert in the list of virtual addresses.
1473
        mov     ecx, [edx+usb_pipe.NextVirt]
1474
        mov     [edi+usb_pipe.NextVirt], ecx
1475
        mov     [edi+usb_pipe.PrevVirt], edx
1476
        mov     [ecx+usb_pipe.PrevVirt], edi
1477
        mov     [edx+usb_pipe.NextVirt], edi
1478
; 5d. Insert in the hardware list: copy previous NextQH to the new pipe,
1479
; store the physical address of the new pipe to previous NextQH.
1480
        mov     ecx, [edx+uhci_static_ep.NextQH-uhci_static_ep.SoftwarePart]
1481
        mov     [edi+uhci_pipe.NextQH-uhci_pipe.SoftwarePart], ecx
1482
        lea     eax, [edi-uhci_pipe.SoftwarePart]
1483
        call    get_phys_addr
1484
        inc     eax
1485
        inc     eax
1486
        mov     [edx+uhci_static_ep.NextQH-uhci_static_ep.SoftwarePart], eax
1487
; 6. Return with nonzero eax.
1488
        ret
1489
.return0:
1490
        xor     eax, eax
1491
        ret
1492
endp
1493
 
1494
; This procedure is called when a pipe is closing (either due to API call
1495
; or due to disconnect); it unlinks a pipe from the corresponding list.
1496
if uhci_static_ep.SoftwarePart <> uhci_pipe.SoftwarePart
1497
.err uhci_unlink_pipe assumes that uhci_static_ep.SoftwarePart == uhci_pipe.SoftwarePart
1498
end if
1499
proc uhci_unlink_pipe
1500
        cmp     [ebx+usb_pipe.Type], INTERRUPT_PIPE
1501
        jnz     @f
1502
        mov     eax, [ebx+uhci_pipe.Token-uhci_pipe.SoftwarePart]
1503
        cmp     al, USB_PID_IN
1504
        setz    ch
1505
        bt      eax, 20
1506
        setc    cl
1507
        add     eax, 1 shl 21
1508
        shr     eax, 21
1509
        stdcall usb1_interrupt_list_unlink, eax, ecx
1510
@@:
1511
; Note: we need to ensure that NextVirt field of the pipe is not modified;
1512
; this procedure can be called while uhci_process_updated_schedule processes
1513
; the same pipe, and it needs a correct NextVirt field to continue.
1514
        mov     edx, [ebx+usb_pipe.NextVirt]
1515
        mov     eax, [ebx+usb_pipe.PrevVirt]
1516
        mov     [edx+usb_pipe.PrevVirt], eax
1517
        mov     [eax+usb_pipe.NextVirt], edx
1518
; Note: eax could be either usb_pipe or usb_static_ep;
1519
; fortunately, NextQH and SoftwarePart have same offsets in both.
1520
        mov     edx, [ebx+uhci_pipe.NextQH-uhci_pipe.SoftwarePart]
1521
        mov     [eax+uhci_pipe.NextQH-uhci_pipe.SoftwarePart], edx
1522
        ret
1523
endp
1524
 
1525
; Free memory associated with pipe.
1526
; For UHCI, this includes usb_pipe structure and ErrorTD, if present.
1527
proc uhci_free_pipe
1528
        mov     eax, [esp+4]
1529
        mov     eax, [eax+uhci_pipe.ErrorTD-uhci_pipe.SoftwarePart]
1530
        test    eax, eax
1531
        jz      @f
1532
        stdcall uhci_free_td, eax
1533
@@:
1534
        jmp     usb1_free_endpoint
1535
endp
1536
 
1537
; This procedure is called from the several places in main USB code
1538
; and allocates required packets for the given transfer stage.
1539
; ebx = pipe, other parameters are passed through the stack
1540
proc uhci_alloc_transfer stdcall uses edi, buffer:dword, size:dword, flags:dword, td:dword, direction:dword
1541
locals
1542
token           dd      ?
1543
origTD          dd      ?
1544
packetSize      dd      ?       ; must be the last variable, see usb_init_transfer
1545
endl
1546
; 1. [td] will be the first packet in the transfer.
1547
; Save it to allow unrolling if something will fail.
1548
        mov     eax, [td]
1549
        mov     [origTD], eax
1550
; In UHCI one TD describes one packet, transfers should be split into parts
1551
; with size <= endpoint max packet size.
1552
; 2. Get the maximum packet size for endpoint from uhci_pipe.Token
1553
; and generate Token field for TDs.
1554
        mov     edi, [ebx+uhci_pipe.Token-uhci_pipe.SoftwarePart]
1555
        mov     eax, edi
1556
        shr     edi, 21
1557
        inc     edi
1558
; zero packet size (it will be set for every packet individually),
1559
; zero reserved bit 20,
1560
        and     eax, (1 shl 20) - 1
1561
        mov     [packetSize], edi
1562
; set the correct PID if it is different from the pipe-wide PID
1563
; (Data and Status stages of control transfers),
1564
        mov     ecx, [direction]
1565
        and     ecx, 3
1566
        jz      @f
1567
        mov     al, USB_PID_OUT
1568
        dec     ecx
1569
        jz      @f
1570
        mov     al, USB_PID_IN
1571
@@:
1572
; set the toggle bit for control transfers,
1573
        mov     ecx, [direction]
1574
        test    cl, 1 shl 3
1575
        jz      @f
1576
        and     ecx, 1 shl 2
1577
        and     eax, not (1 shl 19)
1578
        shl     ecx, 19-2
1579
        or      eax, ecx
1580
@@:
1581
; store the resulting Token in the stack variable.
1582
        mov     [token], eax
1583
; 3. While the remaining data cannot fit in one packet,
1584
; allocate full packets (of maximal possible size).
1585
.fullpackets:
1586
        cmp     [size], edi
1587
        jbe     .lastpacket
1588
        call    uhci_alloc_packet
1589
        test    eax, eax
1590
        jz      .fail
1591
        mov     [td], eax
1592
        add     [buffer], edi
1593
        sub     [size], edi
1594
        jmp     .fullpackets
1595
.lastpacket:
1596
; 4. The remaining data can fit in one packet;
1597
; allocate the last packet with size = size of remaining data.
1598
        mov     eax, [size]
1599
        mov     [packetSize], eax
1600
        call    uhci_alloc_packet
1601
        test    eax, eax
1602
        jz      .fail
1603
; 5. Clear 'short packets are not allowed' bit for the last packet,
1604
; if the caller requested this.
1605
; Note: even if the caller says that short transfers are ok,
1606
; all packets except the last one are marked as 'must be complete':
1607
; if one of them will be short, the software intervention is needed
1608
; to skip remaining packets; uhci_process_finalized_td will handle this
1609
; transparently to the caller.
1610
        test    [flags], 1
1611
        jz      @f
1612
        and     byte [ecx+uhci_gtd.ControlStatus+3-uhci_gtd.SoftwarePart], not (1 shl (29-24))
1613
        and     byte [ecx+uhci_gtd.OrigBufferInfo-uhci_gtd.SoftwarePart], not 1
1614
@@:
1615
; 6. Update toggle bit in uhci_pipe structure from current value of [token].
1616
        mov     edx, [token]
1617
        xor     edx, [ebx+uhci_pipe.Token-uhci_pipe.SoftwarePart]
1618
        and     edx, 1 shl 19
1619
        xor     [ebx+uhci_pipe.Token-uhci_pipe.SoftwarePart], edx
1620
.nothing:
1621
        ret
1622
.fail:
1623
        mov     edi, uhci_hardware_func
1624
        mov     eax, [td]
1625
        stdcall usb_undo_tds, [origTD]
1626
        xor     eax, eax
1627
        jmp     .nothing
1628
endp
1629
 
1630
; Helper procedure for uhci_alloc_transfer. Allocates one packet.
1631
proc uhci_alloc_packet
1632
; inherit some variables from the parent uhci_alloc_transfer
1633
virtual at ebp-12
1634
.token          dd      ?
1635
.origTD         dd      ?
1636
.packetSize     dd      ?
1637
                rd      2
1638
.buffer         dd      ?
1639
.transferSize   dd      ?
1640
.Flags          dd      ?
1641
.td             dd      ?
1642
.direction      dd      ?
1643
end virtual
1644
; 1. In UHCI all data for one packet must be on the same page.
1645
; Thus, if the given buffer splits page boundary, we need a temporary buffer
1646
; and code that transfers data between the given buffer and the temporary one.
1647
; 1a. There is no buffer for zero-length packets.
1648
        xor     eax, eax
1649
        cmp     [.packetSize], eax
1650
        jz      .notempbuf
1651
; 1b. A temporary buffer is not required if the first and the last bytes
1652
; of the given buffer are the same except lower 12 bits.
1653
        mov     edx, [.buffer]
1654
        add     edx, [.packetSize]
1655
        dec     edx
1656
        xor     edx, [.buffer]
1657
        test    edx, -0x1000
1658
        jz      .notempbuf
1659
; 1c. We need a temporary buffer. Allocate [packetSize]*2 bytes, so that
1660
; there must be [packetSize] bytes on one page,
1661
; plus space for a header uhci_original_buffer.
1662
        push    ebx
1663
        mov     eax, [.packetSize]
1664
        add     eax, eax
1665
        add     eax, sizeof.uhci_original_buffer
1666
        call    malloc
1667
        pop     ebx
1668
; 1d. If failed, return zero.
1669
        test    eax, eax
1670
        jz      .nothing
1671
; 1e. Test whether [.packetSize] bytes starting from
1672
; eax + sizeof.uhci_original_buffer are in the same page.
1673
; If so, use eax + sizeof.uhci_original_buffer as a temporary buffer.
1674
; Otherwise, use the beginning of the next page as a temporary buffer
1675
; (since we have overallocated, sufficient space must remain).
1676
        lea     ecx, [eax+sizeof.uhci_original_buffer]
1677
        mov     edx, ecx
1678
        add     edx, [.packetSize]
1679
        dec     edx
1680
        xor     edx, ecx
1681
        test    edx, -0x1000
1682
        jz      @f
1683
        mov     ecx, eax
1684
        or      ecx, 0xFFF
1685
        inc     ecx
1686
@@:
1687
        mov     [eax+uhci_original_buffer.UsedBuffer], ecx
1688
        mov     ecx, [.buffer]
1689
        mov     [eax+uhci_original_buffer.OrigBuffer], ecx
1690
; 1f. For SETUP and OUT packets, copy data from the given buffer
1691
; to the temporary buffer now. For IN packets, data go in other direction
1692
; when the transaction completes.
1693
        cmp     byte [.token], USB_PID_IN
1694
        jz      .nocopy
1695
        push    esi edi
1696
        mov     esi, ecx
1697
        mov     edi, [eax+uhci_original_buffer.UsedBuffer]
1698
        mov     ecx, [.packetSize]
1699
        mov     edx, ecx
1700
        shr     ecx, 2
1701
        and     edx, 3
1702
        rep movsd
1703
        mov     ecx, edx
1704
        rep movsb
1705
        pop     edi esi
1706
.nocopy:
1707
.notempbuf:
1708
; 2. Allocate the next TD.
1709
        push    eax
1710
        call    usb1_allocate_general_td
1711
        pop     edx
1712
; If failed, free the temporary buffer (if it was allocated) and return zero.
1713
        test    eax, eax
1714
        jz      .fail
1715
; 3. Initialize controller-independent parts of both TDs.
1716
        push    edx
1717
        call    usb_init_transfer
1718
; 4. Initialize the next TD:
1719
; mark it as last one (this will be changed when further packets will be
1720
; allocated), copy Token field from uhci_pipe.Token zeroing bit 20,
1721
; generate ControlStatus field, mark as Active
1722
; (for last descriptor, this will be changed by uhci_insert_transfer).
1723
        mov     [eax+uhci_gtd.NextTD-uhci_gtd.SoftwarePart], 1  ; no next TD
1724
        mov     edx, [ebx+uhci_pipe.Token-uhci_pipe.SoftwarePart]
1725
        mov     [eax+uhci_gtd.Token-uhci_gtd.SoftwarePart], edx
1726
        and     byte [eax+uhci_gtd.Token+2-uhci_gtd.SoftwarePart], not (1 shl (20-16))
1727
        and     edx, 1 shl 20
1728
        shl     edx, 6
1729
        or      edx, UHCI_INVALID_LENGTH + (1 shl 23) + (3 shl 27)
1730
                ; not processed, active, allow 3 errors
1731
        mov     [eax+uhci_gtd.ControlStatus-uhci_gtd.SoftwarePart], edx
1732
; 5. Initialize remaining fields of the current TD.
1733
; 5a. Store pointer to the buffer allocated in step 1 (or zero).
1734
        pop     [ecx+uhci_gtd.OrigBufferInfo-uhci_gtd.SoftwarePart]
1735
; 5b. Store physical address of the next TD.
1736
        push    eax
1737
        sub     eax, uhci_gtd.SoftwarePart
1738
        call    get_phys_addr
1739
; use Depth traversal unless this is the first TD in the transfer stage;
1740
; uhci_insert_transfer will set Depth traversal for the first TD and clear
1741
; it in the last TD
1742
        cmp     ecx, [ebx+usb_pipe.LastTD]
1743
        jz      @f
1744
        or      eax, 4
1745
@@:
1746
        mov     [ecx+uhci_gtd.NextTD-uhci_gtd.SoftwarePart], eax
1747
; 5c. Store physical address of the buffer: zero if no data present,
1748
; the temporary buffer if it was allocated, the given buffer otherwise.
1749
        xor     eax, eax
1750
        cmp     [.packetSize], eax
1751
        jz      .hasphysbuf
1752
        mov     eax, [.buffer]
1753
        mov     edx, [ecx+uhci_gtd.OrigBufferInfo-uhci_gtd.SoftwarePart]
1754
        test    edx, edx
1755
        jz      @f
1756
        mov     eax, [edx+uhci_original_buffer.UsedBuffer]
1757
@@:
1758
        call    get_phys_addr
1759
.hasphysbuf:
1760
        mov     [ecx+uhci_gtd.Buffer-uhci_gtd.SoftwarePart], eax
1761
; 5d. For IN transfers, disallow short packets.
1762
; This will be overridden, if needed, by uhci_alloc_transfer.
1763
        mov     eax, [.token]
1764
        mov     edx, [.packetSize]
1765
        dec     edx
1766
        cmp     al, USB_PID_IN
1767
        jnz     @f
1768
        or      byte [ecx+uhci_gtd.ControlStatus+3-uhci_gtd.SoftwarePart], 1 shl (29-24)        ; disallow short packets
1769
        or      byte [ecx+uhci_gtd.OrigBufferInfo-uhci_gtd.SoftwarePart], 1
1770
@@:
1771
; 5e. Get Token field: combine [.token] with [.packetSize].
1772
        shl     edx, 21
1773
        or      edx, eax
1774
        mov     [ecx+uhci_gtd.Token-uhci_gtd.SoftwarePart], edx
1775
; 6. Flip toggle bit in [.token].
1776
        xor     eax, 1 shl 19
1777
        mov     [.token], eax
1778
; 7. Return pointer to the next TD.
1779
        pop     eax
1780
.nothing:
1781
        ret
1782
.fail:
1783
        xchg    eax, edx
1784
        call    free
1785
        xor     eax, eax
1786
        ret
1787
endp
1788
 
1789
; This procedure is called from the several places in main USB code
1790
; and activates the transfer which was previously allocated by
1791
; uhci_alloc_transfer.
1792
; ecx -> last descriptor for the transfer, ebx -> usb_pipe
1793
proc uhci_insert_transfer
1794
;       DEBUGF 1,'K : uhci_insert_transfer: eax=%x, ecx=%x, [esp+4]=%x\n',eax,ecx,[esp+4]
1795
        and     byte [eax+uhci_gtd.ControlStatus+2-uhci_gtd.SoftwarePart], not (1 shl (23-16))  ; clear Active bit
1796
        or      byte [ecx+uhci_gtd.ControlStatus+3-uhci_gtd.SoftwarePart], 1 shl (24-24)        ; set InterruptOnComplete bit
1797
        mov     eax, [esp+4]
1798
        or      byte [eax+uhci_gtd.ControlStatus+2-uhci_gtd.SoftwarePart], 1 shl (23-16)        ; set Active bit
1799
        or      byte [eax+uhci_gtd.NextTD-uhci_gtd.SoftwarePart], 4     ; set Depth bit
1800
        ret
1801
endp
1802
 
1803
; Free all memory associated with one TD.
1804
; For UHCI, this includes memory for uhci_gtd itself
1805
; and the temporary buffer, if present.
1806
proc uhci_free_td
1807
        mov     eax, [esp+4]
1808
        mov     eax, [eax+uhci_gtd.OrigBufferInfo-uhci_gtd.SoftwarePart]
1809
        and     eax, not 1
1810
        jz      .nobuf
1811
        push    ebx
1812
        call    free
1813
        pop     ebx
1814
.nobuf:
1815
        sub     dword [esp+4], uhci_gtd.SoftwarePart
1816
        jmp     usb_free_common
1817
endp