Subversion Repositories Kolibri OS

Rev

Rev 3816 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3816 Rev 4418
Line 1... Line 1...
1
; Code for OHCI controllers.
1
; Code for OHCI controllers.
-
 
2
 
-
 
3
; Standard driver stuff
-
 
4
format PE DLL native
-
 
5
entry start
-
 
6
__DEBUG__ equ 1
-
 
7
__DEBUG_LEVEL__ equ 1
2
; Note: it should be moved to an external driver,
8
section '.reloc' data readable discardable fixups
3
; it was convenient to have this code compiled into the kernel during initial
9
section '.text' code readable executable
-
 
10
include '../proc32.inc'
-
 
11
include '../struct.inc'
-
 
12
include '../macros.inc'
-
 
13
include '../fdo.inc'
4
; development, but there are no reasons to keep it here.
14
include '../../kernel/trunk/bus/usb/common.inc'
Line 5... Line 15...
5
 
15
 
6
; =============================================================================
16
; =============================================================================
7
; ================================= Constants =================================
17
; ================================= Constants =================================
8
; =============================================================================
18
; =============================================================================
Line 181... Line 191...
181
; to be finalized.
191
; to be finalized.
182
DoneListEndPtr  dd      ?
192
DoneListEndPtr  dd      ?
183
; Pointer to dword which should receive a pointer to the next item in DoneList.
193
; Pointer to dword which should receive a pointer to the next item in DoneList.
184
; If DoneList is empty, this is a pointer to DoneList itself;
194
; If DoneList is empty, this is a pointer to DoneList itself;
185
; otherwise, this is a pointer to NextTD field of the last item in DoneList.
195
; otherwise, this is a pointer to NextTD field of the last item in DoneList.
-
 
196
EhciCompanion   dd      ?
-
 
197
; Pointer to usb_controller for EHCI companion, if any, or NULL.
186
ends
198
ends
Line 187... Line 199...
187
 
199
 
188
if ohci_controller.IntEDs mod 16
200
if ohci_controller.IntEDs mod 16
189
.err Static endpoint descriptors must be 16-bytes aligned inside ohci_controller
201
.err Static endpoint descriptors must be 16-bytes aligned inside ohci_controller
Line 288... Line 300...
288
; controller-independent code.
300
; controller-independent code.
289
; Implements the structure usb_hardware_func from hccommon.inc for OHCI.
301
; Implements the structure usb_hardware_func from hccommon.inc for OHCI.
290
iglobal
302
iglobal
291
align 4
303
align 4
292
ohci_hardware_func:
304
ohci_hardware_func:
-
 
305
        dd      USBHC_VERSION
293
        dd      'OHCI'
306
        dd      'OHCI'
294
        dd      sizeof.ohci_controller
307
        dd      sizeof.ohci_controller
-
 
308
        dd      ohci_kickoff_bios
295
        dd      ohci_init
309
        dd      ohci_init
296
        dd      ohci_process_deferred
310
        dd      ohci_process_deferred
297
        dd      ohci_set_device_address
311
        dd      ohci_set_device_address
298
        dd      ohci_get_device_address
312
        dd      ohci_get_device_address
299
        dd      ohci_port_disable
313
        dd      ohci_port_disable
300
        dd      ohci_new_port.reset
314
        dd      ohci_new_port.reset
301
        dd      ohci_set_endpoint_packet_size
315
        dd      ohci_set_endpoint_packet_size
302
        dd      usb1_allocate_endpoint
316
        dd      ohci_alloc_pipe
303
        dd      usb1_free_endpoint
317
        dd      ohci_free_pipe
304
        dd      ohci_init_pipe
318
        dd      ohci_init_pipe
305
        dd      ohci_unlink_pipe
319
        dd      ohci_unlink_pipe
306
        dd      usb1_allocate_general_td
320
        dd      ohci_alloc_gtd
307
        dd      usb1_free_general_td
321
        dd      ohci_free_gtd
308
        dd      ohci_alloc_transfer
322
        dd      ohci_alloc_transfer
309
        dd      ohci_insert_transfer
323
        dd      ohci_insert_transfer
310
        dd      ohci_new_device
324
        dd      ohci_new_device
-
 
325
ohci_name db    'OHCI',0
311
endg
326
endg
Line 312... Line 327...
312
 
327
 
313
; =============================================================================
328
; =============================================================================
314
; =================================== Code ====================================
329
; =================================== Code ====================================
Line -... Line 330...
-
 
330
; =============================================================================
-
 
331
 
-
 
332
; Called once when driver is loading and once at shutdown.
-
 
333
; When loading, must initialize itself, register itself in the system
-
 
334
; and return eax = value obtained when registering.
-
 
335
proc start
-
 
336
virtual at esp
-
 
337
                dd      ? ; return address
-
 
338
.reason         dd      ? ; DRV_ENTRY or DRV_EXIT
-
 
339
.cmdline        dd      ? ; normally NULL
-
 
340
end virtual
-
 
341
        cmp     [.reason], DRV_ENTRY
-
 
342
        jnz     .nothing
-
 
343
        mov     ecx, ohci_ep_mutex
-
 
344
        and     dword [ecx-4], 0
-
 
345
        invoke  MutexInit
-
 
346
        mov     ecx, ohci_gtd_mutex
-
 
347
        and     dword [ecx-4], 0
-
 
348
        invoke  MutexInit
-
 
349
        push    esi edi
-
 
350
        mov     esi, [USBHCFunc]
-
 
351
        mov     edi, usbhc_api
-
 
352
        movi    ecx, sizeof.usbhc_func/4
-
 
353
        rep movsd
-
 
354
        pop     edi esi
-
 
355
        invoke  RegUSBDriver, ohci_name, 0, ohci_hardware_func
-
 
356
.nothing:
-
 
357
        ret
315
; =============================================================================
358
endp
316
 
359
 
317
; Controller-specific initialization function.
360
; Controller-specific initialization function.
318
; Called from usb_init_controller. Initializes the hardware and
361
; Called from usb_init_controller. Initializes the hardware and
319
; OHCI-specific parts of software structures.
362
; OHCI-specific parts of software structures.
Line 336... Line 379...
336
end if
379
end if
337
if ohci_controller.IntEDs >= 0x1000
380
if ohci_controller.IntEDs >= 0x1000
338
.err assertion failed
381
.err assertion failed
339
end if
382
end if
340
        lea     esi, [eax+ohci_controller.IntEDs+32*sizeof.ohci_static_ep]
383
        lea     esi, [eax+ohci_controller.IntEDs+32*sizeof.ohci_static_ep]
341
        call    get_pg_addr
384
        invoke  GetPgAddr
342
        add     eax, ohci_controller.IntEDs
385
        add     eax, ohci_controller.IntEDs
343
        movi    ecx, 32
386
        movi    ecx, 32
344
        mov     edx, ecx
387
        mov     edx, ecx
345
@@:
388
@@:
346
        stosd
389
        stosd
Line 381... Line 424...
381
; 3i. Initialize the heads of Control and Bulk lists.
424
; 3i. Initialize the heads of Control and Bulk lists.
382
        call    ohci_init_static_endpoint
425
        call    ohci_init_static_endpoint
383
        call    ohci_init_static_endpoint
426
        call    ohci_init_static_endpoint
384
; 4. Create a virtual memory area to talk with the controller.
427
; 4. Create a virtual memory area to talk with the controller.
385
; 4a. Enable memory & bus master access.
428
; 4a. Enable memory & bus master access.
386
        mov     ch, [.bus]
-
 
387
        mov     cl, 0
-
 
388
        mov     eax, ecx
-
 
389
        mov     bh, [.devfn]
429
        invoke  PciRead16, dword [.bus], dword [.devfn], 4
390
        mov     bl, 4
-
 
391
        call    pci_read_reg
-
 
392
        or      al, 6
430
        or      al, 6
393
        xchg    eax, ecx
-
 
394
        call    pci_write_reg
431
        invoke  PciWrite16, dword [.bus], dword [.devfn], 4, eax
395
; 4b. Read memory base address.
432
; 4b. Read memory base address.
396
        mov     ah, [.bus]
433
        invoke  PciRead32, dword [.bus], dword [.devfn], 10h
397
        mov     al, 2
-
 
398
        mov     bl, 10h
-
 
399
        call    pci_read_reg
-
 
400
        and     al, not 0Fh
434
        and     al, not 0Fh
401
; 4c. Create mapping for physical memory. 256 bytes are sufficient.
435
; 4c. Create mapping for physical memory. 256 bytes are sufficient.
402
        stdcall map_io_mem, eax, 100h, PG_SW+PG_NOCACHE
436
        invoke  MapIoMem, eax, 100h, PG_SW+PG_NOCACHE
403
        test    eax, eax
437
        test    eax, eax
404
        jz      .fail
438
        jz      .fail
405
        stosd   ; fill ohci_controller.MMIOBase
439
        stosd   ; fill ohci_controller.MMIOBase
406
        xchg    eax, edi
440
        xchg    eax, edi
407
; now edi = MMIOBase
441
; now edi = MMIOBase
Line 420... Line 454...
420
        movi    ecx, 1
454
        movi    ecx, 1
421
        movi    edx, 10
455
        movi    edx, 10
422
        mov     [edi+OhciCommandStatusReg], ecx
456
        mov     [edi+OhciCommandStatusReg], ecx
423
@@:
457
@@:
424
        mov     esi, ecx
458
        mov     esi, ecx
425
        call    delay_ms
459
        invoke  Sleep
426
        test    [edi+OhciCommandStatusReg], ecx
460
        test    [edi+OhciCommandStatusReg], ecx
427
        jz      .resetdone
461
        jz      .resetdone
428
        dec     edx
462
        dec     edx
429
        jnz     @b
463
        jnz     @b
430
        pop     eax
464
        pop     eax
Line 452... Line 486...
452
.operational:
486
.operational:
453
; 6. Setup controller registers.
487
; 6. Setup controller registers.
454
        pop     esi     ; restore pointer to ohci_controller saved in step 1
488
        pop     esi     ; restore pointer to ohci_controller saved in step 1
455
; 6a. Physical address of HCCA.
489
; 6a. Physical address of HCCA.
456
        mov     eax, esi
490
        mov     eax, esi
457
        call    get_pg_addr
491
        invoke  GetPgAddr
458
        mov     [edi+OhciHCCAReg], eax
492
        mov     [edi+OhciHCCAReg], eax
459
; 6b. Transition to operational state and clear all Enable bits.
493
; 6b. Transition to operational state and clear all Enable bits.
460
        mov     cl, 2 shl 6
494
        mov     cl, 2 shl 6
461
        mov     [edi+OhciControlReg], ecx
495
        mov     [edi+OhciControlReg], ecx
462
; 6c. Physical addresses of head of Control and Bulk lists.
496
; 6c. Physical addresses of head of Control and Bulk lists.
Line 473... Line 507...
473
        mov     [edi+OhciControlCurrentEDReg], eax
507
        mov     [edi+OhciControlCurrentEDReg], eax
474
        mov     [edi+OhciBulkCurrentEDReg], eax
508
        mov     [edi+OhciBulkCurrentEDReg], eax
475
;       mov     [edi+OhciDoneHeadReg], eax
509
;       mov     [edi+OhciDoneHeadReg], eax
476
; 6e. Enable processing of all lists with control:bulk ratio = 1:1.
510
; 6e. Enable processing of all lists with control:bulk ratio = 1:1.
477
        mov     dword [edi+OhciControlReg], 10111100b
511
        mov     dword [edi+OhciControlReg], 10111100b
478
; 7. Get number of ports.
512
; 7. Find the EHCI companion.
-
 
513
; Note: this assumes that EHCI is initialized before USB1 companions.
479
        add     esi, sizeof.ohci_controller
514
        add     esi, sizeof.ohci_controller
-
 
515
        mov     ebx, dword [.devfn]
-
 
516
        invoke  usbhc_api.usb_find_ehci_companion
-
 
517
        mov     [esi+ohci_controller.EhciCompanion-sizeof.ohci_controller], eax
-
 
518
; 8. Get number of ports.
480
        mov     eax, [edi+OhciRhDescriptorAReg]
519
        mov     eax, [edi+OhciRhDescriptorAReg]
481
        and     eax, 0xF
520
        and     eax, 0xF
482
        mov     [esi+usb_controller.NumPorts], eax
521
        mov     [esi+usb_controller.NumPorts], eax
483
; 8. Initialize DoneListEndPtr to point to DoneList.
522
; 9. Initialize DoneListEndPtr to point to DoneList.
484
        lea     eax, [esi+ohci_controller.DoneList-sizeof.ohci_controller]
523
        lea     eax, [esi+ohci_controller.DoneList-sizeof.ohci_controller]
485
        mov     [esi+ohci_controller.DoneListEndPtr-sizeof.ohci_controller], eax
524
        mov     [esi+ohci_controller.DoneListEndPtr-sizeof.ohci_controller], eax
486
; 9. Hook interrupt.
525
; 10. Hook interrupt.
487
        mov     ah, [.bus]
-
 
488
        mov     al, 0
-
 
489
        mov     bh, [.devfn]
526
        invoke  PciRead8, dword [.bus], dword [.devfn], 3Ch
490
        mov     bl, 3Ch
-
 
491
        call    pci_read_reg
-
 
492
; al = IRQ
527
; al = IRQ
493
        movzx   eax, al
528
        movzx   eax, al
494
        stdcall attach_int_handler, eax, ohci_irq, esi
529
        invoke  AttachIntHandler, eax, ohci_irq, esi
495
; 10. Enable controller interrupt on HcDoneHead writeback and RootHubStatusChange.
530
; 11. Enable controller interrupt on HcDoneHead writeback and RootHubStatusChange.
496
        mov     dword [edi+OhciInterruptEnableReg], 80000042h
531
        mov     dword [edi+OhciInterruptEnableReg], 80000042h
497
        DEBUGF 1,'K : OHCI controller at %x:%x with %d ports initialized\n',[.bus]:2,[.devfn]:2,[esi+usb_controller.NumPorts]
532
        DEBUGF 1,'K : OHCI controller at %x:%x with %d ports initialized\n',[.bus]:2,[.devfn]:2,[esi+usb_controller.NumPorts]
498
; 11. Initialize ports of the controller.
533
; 12. Initialize ports of the controller.
499
; 11a. Initiate power up, disable all ports, clear all "changed" bits.
534
; 12a. Initiate power up, disable all ports, clear all "changed" bits.
500
        mov     dword [edi+OhciRhStatusReg], 10000h     ; SetGlobalPower
535
        mov     dword [edi+OhciRhStatusReg], 10000h     ; SetGlobalPower
501
        xor     ecx, ecx
536
        xor     ecx, ecx
502
@@:
537
@@:
503
        mov     dword [edi+OhciRhPortStatusReg+ecx*4], 1F0101h  ; SetPortPower+ClearPortEnable+clear "changed" bits
538
        mov     dword [edi+OhciRhPortStatusReg+ecx*4], 1F0101h  ; SetPortPower+ClearPortEnable+clear "changed" bits
504
        inc     ecx
539
        inc     ecx
505
        cmp     ecx, [esi+usb_controller.NumPorts]
540
        cmp     ecx, [esi+usb_controller.NumPorts]
506
        jb      @b
541
        jb      @b
507
; 11b. Wait for power up.
542
; 12b. Wait for power up.
508
; VirtualBox has AReg == 0, delay_ms doesn't like zero value; ignore zero delay
543
; VirtualBox has AReg == 0, delay_ms doesn't like zero value; ignore zero delay
509
        push    esi
544
        push    esi
510
        mov     esi, [edi+OhciRhDescriptorAReg]
545
        mov     esi, [edi+OhciRhDescriptorAReg]
511
        shr     esi, 24
546
        shr     esi, 24
512
        add     esi, esi
547
        add     esi, esi
513
        jz      @f
548
        jz      @f
514
        call    delay_ms
549
        invoke  Sleep
515
@@:
550
@@:
516
        pop     esi
551
        pop     esi
517
; 11c. Ports are powered up; now it is ok to process connect/disconnect events.
552
; 12c. Ports are powered up; now it is ok to process connect/disconnect events.
518
        mov     [esi+ohci_controller.PoweredUp-sizeof.ohci_controller], 1
553
        mov     [esi+ohci_controller.PoweredUp-sizeof.ohci_controller], 1
519
                ; IRQ handler doesn't accept connect/disconnect events before this point
554
                ; IRQ handler doesn't accept connect/disconnect events before this point
520
; 11d. We could miss some events while waiting for powering up;
555
; 12d. We could miss some events while waiting for powering up;
521
; scan all ports manually and check for connected devices.
556
; scan all ports manually and check for connected devices.
522
        xor     ecx, ecx
557
        xor     ecx, ecx
523
.port_loop:
558
.port_loop:
524
        test    dword [edi+OhciRhPortStatusReg+ecx*4], 1
559
        test    dword [edi+OhciRhPortStatusReg+ecx*4], 1
525
        jz      .next_port
560
        jz      .next_port
526
; There is a connected device; mark the port as 'connected'
561
; There is a connected device; mark the port as 'connected'
527
; and save the connected time.
562
; and save the connected time.
528
; Note that ConnectedTime must be set before 'connected' mark,
563
; Note that ConnectedTime must be set before 'connected' mark,
529
; otherwise the code in ohci_process_deferred could use incorrect time.
564
; otherwise the code in ohci_process_deferred could use incorrect time.
530
        mov     eax, [timer_ticks]
565
        invoke  GetTimerTicks
531
        mov     [esi+usb_controller.ConnectedTime+ecx*4], eax
566
        mov     [esi+usb_controller.ConnectedTime+ecx*4], eax
532
        lock bts [esi+usb_controller.NewConnected], ecx
567
        lock bts [esi+usb_controller.NewConnected], ecx
533
.next_port:
568
.next_port:
534
        inc     ecx
569
        inc     ecx
535
        cmp     ecx, [esi+usb_controller.NumPorts]
570
        cmp     ecx, [esi+usb_controller.NumPorts]
536
        jb      .port_loop
571
        jb      .port_loop
537
; 12. Return pointer to usb_controller.
572
; 13. Return pointer to usb_controller.
538
        xchg    eax, esi
573
        xchg    eax, esi
539
        ret
574
        ret
540
.fail_unmap:
575
.fail_unmap:
541
; On error after step 4, release the virtual memory area.
576
; On error after step 5, release the virtual memory area.
542
        stdcall free_kernel_space, edi
577
        invoke  FreeKernelSpace, edi
543
.fail:
578
.fail:
544
; On error, free the ohci_controller structure and return zero.
579
; On error, free the ohci_controller structure and return zero.
545
; Note that the pointer was placed in the stack at step 1.
580
; Note that the pointer was placed in the stack at step 1.
546
; Note also that there can be no errors after step 8,
581
; Note also that there can be no errors after step 6,
547
; where that pointer is popped from the stack.
582
; where that pointer is popped from the stack.
548
        pop     ecx
583
        pop     ecx
549
.nothing:
584
.nothing:
550
        xor     eax, eax
585
        xor     eax, eax
551
        ret
586
        ret
Line 559... Line 594...
559
proc ohci_init_static_endpoint
594
proc ohci_init_static_endpoint
560
        mov     byte [edi+ohci_static_ep.Flags+1], 1 shl (14 - 8)       ; sKip this endpoint
595
        mov     byte [edi+ohci_static_ep.Flags+1], 1 shl (14 - 8)       ; sKip this endpoint
561
        mov     [edi+ohci_static_ep.NextED], eax
596
        mov     [edi+ohci_static_ep.NextED], eax
562
        mov     [edi+ohci_static_ep.NextList], esi
597
        mov     [edi+ohci_static_ep.NextList], esi
563
        add     edi, ohci_static_ep.SoftwarePart
598
        add     edi, ohci_static_ep.SoftwarePart
564
        call    usb_init_static_endpoint
599
        invoke  usbhc_api.usb_init_static_endpoint
565
        add     edi, sizeof.ohci_static_ep - ohci_static_ep.SoftwarePart
600
        add     edi, sizeof.ohci_static_ep - ohci_static_ep.SoftwarePart
566
        ret
601
        ret
567
endp
602
endp
Line 568... Line 603...
568
 
603
 
Line 589... Line 624...
589
; for USB keyboard and/or mice as PS/2-devices. In this case,
624
; for USB keyboard and/or mice as PS/2-devices. In this case,
590
; we must notify the BIOS that we don't need that emulation and know how to
625
; we must notify the BIOS that we don't need that emulation and know how to
591
; deal with USB devices.
626
; deal with USB devices.
592
proc ohci_kickoff_bios
627
proc ohci_kickoff_bios
593
; 1. Get the physical address of MMIO registers.
628
; 1. Get the physical address of MMIO registers.
594
        mov     ah, [esi+PCIDEV.bus]
-
 
595
        mov     bh, [esi+PCIDEV.devfn]
629
        invoke  PciRead32, dword [esi+PCIDEV.bus], dword [esi+PCIDEV.devfn], 10h
596
        mov     al, 2
-
 
597
        mov     bl, 10h
-
 
598
        call    pci_read_reg
-
 
599
        and     al, not 0Fh
630
        and     al, not 0Fh
600
; 2. Create mapping for physical memory. 256 bytes are sufficient.
631
; 2. Create mapping for physical memory. 256 bytes are sufficient.
601
        stdcall map_io_mem, eax, 100h, PG_SW+PG_NOCACHE
632
        invoke  MapIoMem, eax, 100h, PG_SW+PG_NOCACHE
602
        test    eax, eax
633
        test    eax, eax
603
        jz      .nothing
634
        jz      .nothing
604
; 3. Some BIOSes enable controller interrupts as a result of giving
635
; 3. Some BIOSes enable controller interrupts as a result of giving
605
; controller away. At this point the system knows nothing about how to serve
636
; controller away. At this point the system knows nothing about how to serve
606
; OHCI interrupts, so such an interrupt will send the system into an infinite
637
; OHCI interrupts, so such an interrupt will send the system into an infinite
Line 623... Line 654...
623
@@:
654
@@:
624
        test    dword [eax+OhciControlReg], edx
655
        test    dword [eax+OhciControlReg], edx
625
        jz      .has_ownership
656
        jz      .has_ownership
626
        push    esi
657
        push    esi
627
        movi    esi, 1
658
        movi    esi, 1
628
        call    delay_ms
659
        invoke  Sleep
629
        pop     esi
660
        pop     esi
630
        loop    @b
661
        loop    @b
631
        dbgstr 'warning: taking OHCI ownership from BIOS timeout'
662
        dbgstr 'warning: taking OHCI ownership from BIOS timeout'
632
.has_ownership:
663
.has_ownership:
633
; 5. Disable all controller interrupts until the system will be ready to
664
; 5. Disable all controller interrupts until the system will be ready to
634
; process them.
665
; process them.
635
        mov     dword [eax+OhciInterruptDisableReg], 0C000007Fh
666
        mov     dword [eax+OhciInterruptDisableReg], 0C000007Fh
636
; 6. Now we can unblock interrupts in the processor.
667
; 6. Now we can unblock interrupts in the processor.
637
        popf
668
        popf
638
; 7. Release memory mapping created in step 2 and return.
669
; 7. Release memory mapping created in step 2 and return.
639
        stdcall free_kernel_space, eax
670
        invoke  FreeKernelSpace, eax
640
.nothing:
671
.nothing:
641
        ret
672
        ret
642
endp
673
endp
Line 643... Line 674...
643
 
674
 
Line 701... Line 732...
701
; 7b. Prepare for the reversing loop.
732
; 7b. Prepare for the reversing loop.
702
        push    ebx
733
        push    ebx
703
        xor     ebx, ebx
734
        xor     ebx, ebx
704
        test    ecx, ecx
735
        test    ecx, ecx
705
        jz      .tddone
736
        jz      .tddone
-
 
737
        mov     eax, [ohci_gtd_first_page]
706
        call    usb_td_to_virt
738
        invoke  usbhc_api.usb_td_to_virt
707
        test    eax, eax
739
        test    eax, eax
708
        jz      .tddone
740
        jz      .tddone
709
        lea     edx, [eax+ohci_gtd.NextTD]
741
        lea     edx, [eax+ohci_gtd.NextTD]
710
; 7c. Reverse the list, converting physical to virtual. On every iteration:
742
; 7c. Reverse the list, converting physical to virtual. On every iteration:
711
; ecx = physical address of the current item
743
; ecx = physical address of the current item
Line 716... Line 748...
716
        mov     ecx, [eax+ohci_gtd.NextTD]
748
        mov     ecx, [eax+ohci_gtd.NextTD]
717
        mov     [eax+ohci_gtd.NextTD], ebx
749
        mov     [eax+ohci_gtd.NextTD], ebx
718
        lea     ebx, [eax+sizeof.ohci_gtd]
750
        lea     ebx, [eax+sizeof.ohci_gtd]
719
        test    ecx, ecx
751
        test    ecx, ecx
720
        jz      .tddone
752
        jz      .tddone
-
 
753
        mov     eax, [ohci_gtd_first_page]
721
        call    usb_td_to_virt
754
        invoke  usbhc_api.usb_td_to_virt
722
        test    eax, eax
755
        test    eax, eax
723
        jnz     .tdloop
756
        jnz     .tdloop
724
.tddone:
757
.tddone:
725
        mov     ecx, ebx
758
        mov     ecx, ebx
726
        pop     ebx
759
        pop     ebx
Line 843... Line 876...
843
; after USB_CONNECT_DELAY ticks.
876
; after USB_CONNECT_DELAY ticks.
844
        test    al, 1
877
        test    al, 1
845
        jz      .disconnect
878
        jz      .disconnect
846
; Note: ConnectedTime must be stored before setting the 'connected' bit,
879
; Note: ConnectedTime must be stored before setting the 'connected' bit,
847
; otherwise ohci_process_deferred could use an old time.
880
; otherwise ohci_process_deferred could use an old time.
848
        mov     eax, [timer_ticks]
881
        invoke  GetTimerTicks
849
        mov     [esi+usb_controller.ConnectedTime+ecx*4], eax
882
        mov     [esi+usb_controller.ConnectedTime+ecx*4], eax
850
        lock bts [esi+usb_controller.NewConnected], ecx
883
        lock bts [esi+usb_controller.NewConnected], ecx
851
        jmp     .nextport
884
        jmp     .nextport
852
.disconnect:
885
.disconnect:
853
        lock btr [esi+usb_controller.NewConnected], ecx
886
        lock btr [esi+usb_controller.NewConnected], ecx
Line 856... Line 889...
856
; 11f. Process 'reset done' events.
889
; 11f. Process 'reset done' events.
857
        test    eax, 100000h
890
        test    eax, 100000h
858
        jz      .nextport
891
        jz      .nextport
859
        test    al, 10h
892
        test    al, 10h
860
        jnz     .nextport
893
        jnz     .nextport
861
        mov     edx, [timer_ticks]
894
        invoke  GetTimerTicks
862
        mov     [esi+usb_controller.ResetTime], edx
895
        mov     [esi+usb_controller.ResetTime], eax
863
        mov     [esi+usb_controller.ResettingStatus], 2
896
        mov     [esi+usb_controller.ResettingStatus], 2
864
        inc     ebx
897
        inc     ebx
865
.nextport:
898
.nextport:
866
; 11g. Continue the loop for the next port.
899
; 11g. Continue the loop for the next port.
867
        inc     ecx
900
        inc     ecx
Line 869... Line 902...
869
        jb      .portloop
902
        jb      .portloop
870
.skip_roothub:
903
.skip_roothub:
871
; 12. Restore the stack after step 6.
904
; 12. Restore the stack after step 6.
872
        pop     eax
905
        pop     eax
873
; 13. Notify the USB thread if some deferred processing is required.
906
; 13. Notify the USB thread if some deferred processing is required.
874
        call    usb_wakeup_if_needed
907
        invoke  usbhc_api.usb_wakeup_if_needed
875
; 14. Interrupt processed; return something non-zero.
908
; 14. Interrupt processed; return something non-zero.
876
        mov     al, 1
909
        mov     al, 1
877
        pop     edi esi ebx     ; restore used registers to be stdcall
910
        pop     edi esi ebx     ; restore used registers to be stdcall
878
        ret
911
        ret
879
endp
912
endp
Line 882... Line 915...
882
; and stores USB device address in the ohci_pipe structure.
915
; and stores USB device address in the ohci_pipe structure.
883
; in: esi -> usb_controller, ebx -> usb_pipe, cl = address
916
; in: esi -> usb_controller, ebx -> usb_pipe, cl = address
884
proc ohci_set_device_address
917
proc ohci_set_device_address
885
        mov     byte [ebx+ohci_pipe.Flags-sizeof.ohci_pipe], cl
918
        mov     byte [ebx+ohci_pipe.Flags-sizeof.ohci_pipe], cl
886
; Wait until the hardware will forget the old value.
919
; Wait until the hardware will forget the old value.
887
        call    usb_subscribe_control
920
        jmp     [usbhc_api.usb_subscribe_control]
888
        ret
-
 
889
endp
921
endp
Line 890... Line 922...
890
 
922
 
891
; This procedure returns USB device address from the usb_pipe structure.
923
; This procedure returns USB device address from the usb_pipe structure.
892
; in: esi -> usb_controller, ebx -> usb_pipe
924
; in: esi -> usb_controller, ebx -> usb_pipe
Line 912... Line 944...
912
; stores the packet size in ohci_pipe structure.
944
; stores the packet size in ohci_pipe structure.
913
; in: esi -> usb_controller, ebx -> usb_pipe, ecx = packet size
945
; in: esi -> usb_controller, ebx -> usb_pipe, ecx = packet size
914
proc ohci_set_endpoint_packet_size
946
proc ohci_set_endpoint_packet_size
915
        mov     byte [ebx+ohci_pipe.Flags+2-sizeof.ohci_pipe], cl
947
        mov     byte [ebx+ohci_pipe.Flags+2-sizeof.ohci_pipe], cl
916
; Wait until the hardware will forget the old value.
948
; Wait until the hardware will forget the old value.
917
        call    usb_subscribe_control
949
        jmp     [usbhc_api.usb_subscribe_control]
918
        ret
-
 
919
endp
950
endp
Line 920... Line 951...
920
 
951
 
921
; This procedure is called from API usb_open_pipe and processes
952
; This procedure is called from API usb_open_pipe and processes
922
; the controller-specific part of this API. See docs.
953
; the controller-specific part of this API. See docs.
Line 936... Line 967...
936
.type           dd      ?
967
.type           dd      ?
937
.interval       dd      ?
968
.interval       dd      ?
938
end virtual
969
end virtual
939
; 1. Initialize the queue of transfer descriptors: empty.
970
; 1. Initialize the queue of transfer descriptors: empty.
940
        sub     eax, sizeof.ohci_gtd
971
        sub     eax, sizeof.ohci_gtd
941
        call    get_phys_addr
972
        invoke  GetPhysAddr
942
        mov     [edi+ohci_pipe.TailP-sizeof.ohci_pipe], eax
973
        mov     [edi+ohci_pipe.TailP-sizeof.ohci_pipe], eax
943
        mov     [edi+ohci_pipe.HeadP-sizeof.ohci_pipe], eax
974
        mov     [edi+ohci_pipe.HeadP-sizeof.ohci_pipe], eax
944
; 2. Generate ohci_pipe.Flags, see the description in ohci_pipe.
975
; 2. Generate ohci_pipe.Flags, see the description in ohci_pipe.
945
        mov     eax, [ecx+ohci_pipe.Flags-sizeof.ohci_pipe]
976
        mov     eax, [ecx+ohci_pipe.Flags-sizeof.ohci_pipe]
946
        and     eax, 0x207F     ; keep Speed bit and FunctionAddress
977
        and     eax, 0x207F     ; keep Speed bit and FunctionAddress
Line 989... Line 1020...
989
        mov     [ecx+usb_pipe.PrevVirt], edi
1020
        mov     [ecx+usb_pipe.PrevVirt], edi
990
        mov     [edx+usb_pipe.NextVirt], edi
1021
        mov     [edx+usb_pipe.NextVirt], edi
991
        mov     ecx, [edx+ohci_pipe.NextED-sizeof.ohci_pipe]
1022
        mov     ecx, [edx+ohci_pipe.NextED-sizeof.ohci_pipe]
992
        mov     [edi+ohci_pipe.NextED-sizeof.ohci_pipe], ecx
1023
        mov     [edi+ohci_pipe.NextED-sizeof.ohci_pipe], ecx
993
        lea     eax, [edi-sizeof.ohci_pipe]
1024
        lea     eax, [edi-sizeof.ohci_pipe]
994
        call    get_phys_addr
1025
        invoke  GetPhysAddr
995
        mov     [edx+ohci_pipe.NextED-sizeof.ohci_pipe], eax
1026
        mov     [edx+ohci_pipe.NextED-sizeof.ohci_pipe], eax
996
; 4. Return something non-zero.
1027
; 4. Return something non-zero.
997
        ret
1028
        ret
998
.return0:
1029
.return0:
999
        xor     eax, eax
1030
        xor     eax, eax
Line 1112... Line 1143...
1112
@@:
1143
@@:
1113
        ret
1144
        ret
1114
.fail:
1145
.fail:
1115
        mov     edi, ohci_hardware_func
1146
        mov     edi, ohci_hardware_func
1116
        mov     eax, [td]
1147
        mov     eax, [td]
1117
        stdcall usb_undo_tds, [origTD]
1148
        invoke  usbhc_api.usb_undo_tds, [origTD]
1118
        xor     eax, eax
1149
        xor     eax, eax
1119
        ret
1150
        ret
1120
endp
1151
endp
Line 1121... Line 1152...
1121
 
1152
 
Line 1135... Line 1166...
1135
.Flags          dd      ?
1166
.Flags          dd      ?
1136
.td             dd      ?
1167
.td             dd      ?
1137
.direction      dd      ?
1168
.direction      dd      ?
1138
end virtual
1169
end virtual
1139
; 1. Allocate the next TD.
1170
; 1. Allocate the next TD.
1140
        call    usb1_allocate_general_td
1171
        call    ohci_alloc_gtd
1141
        test    eax, eax
1172
        test    eax, eax
1142
        jz      .nothing
1173
        jz      .nothing
1143
; 2. Initialize controller-independent parts of both TDs.
1174
; 2. Initialize controller-independent parts of both TDs.
1144
        push    eax
1175
        push    eax
1145
        call    usb_init_transfer
1176
        invoke  usbhc_api.usb_init_transfer
1146
        pop     eax
1177
        pop     eax
1147
; 3. Save the returned value (next descriptor).
1178
; 3. Save the returned value (next descriptor).
1148
        push    eax
1179
        push    eax
1149
; 4. Store the physical address of the next descriptor.
1180
; 4. Store the physical address of the next descriptor.
1150
        sub     eax, sizeof.ohci_gtd
1181
        sub     eax, sizeof.ohci_gtd
1151
        call    get_phys_addr
1182
        invoke  GetPhysAddr
1152
        mov     [ecx+ohci_gtd.NextTD-sizeof.ohci_gtd], eax
1183
        mov     [ecx+ohci_gtd.NextTD-sizeof.ohci_gtd], eax
1153
; 5. For zero-length transfers, store zero in both fields for buffer addresses.
1184
; 5. For zero-length transfers, store zero in both fields for buffer addresses.
1154
; Otherwise, fill them with real values.
1185
; Otherwise, fill them with real values.
1155
        xor     eax, eax
1186
        xor     eax, eax
1156
        mov     [ecx+ohci_gtd.CurBufPtr-sizeof.ohci_gtd], eax
1187
        mov     [ecx+ohci_gtd.CurBufPtr-sizeof.ohci_gtd], eax
1157
        mov     [ecx+ohci_gtd.BufEnd-sizeof.ohci_gtd], eax
1188
        mov     [ecx+ohci_gtd.BufEnd-sizeof.ohci_gtd], eax
1158
        cmp     [.packetSize], eax
1189
        cmp     [.packetSize], eax
1159
        jz      @f
1190
        jz      @f
1160
        mov     eax, [.buffer]
1191
        mov     eax, [.buffer]
1161
        call    get_phys_addr
1192
        invoke  GetPhysAddr
1162
        mov     [ecx+ohci_gtd.CurBufPtr-sizeof.ohci_gtd], eax
1193
        mov     [ecx+ohci_gtd.CurBufPtr-sizeof.ohci_gtd], eax
1163
        mov     eax, [.buffer]
1194
        mov     eax, [.buffer]
1164
        add     eax, [.packetSize]
1195
        add     eax, [.packetSize]
1165
        dec     eax
1196
        dec     eax
1166
        call    get_phys_addr
1197
        invoke  GetPhysAddr
1167
        mov     [ecx+ohci_gtd.BufEnd-sizeof.ohci_gtd], eax
1198
        mov     [ecx+ohci_gtd.BufEnd-sizeof.ohci_gtd], eax
1168
@@:
1199
@@:
1169
; 6. Generate Flags field:
1200
; 6. Generate Flags field:
1170
; - set bufferRounding (bit 18) to zero = disallow short transfers;
1201
; - set bufferRounding (bit 18) to zero = disallow short transfers;
1171
;   for the last transfer in a row, ohci_alloc_transfer would set the real value;
1202
;   for the last transfer in a row, ohci_alloc_transfer would set the real value;
Line 1223... Line 1254...
1223
; If reset has been failed (device disconnected during reset),
1254
; If reset has been failed (device disconnected during reset),
1224
; continue to next device (if there is one).
1255
; continue to next device (if there is one).
1225
        xor     eax, eax
1256
        xor     eax, eax
1226
        xchg    al, [esi+usb_controller.ResettingStatus]
1257
        xchg    al, [esi+usb_controller.ResettingStatus]
1227
        test    al, al
1258
        test    al, al
-
 
1259
        jns     @f
1228
        js      usb_test_pending_port
1260
        jmp     [usbhc_api.usb_test_pending_port]
-
 
1261
@@:
1229
; If the controller has disabled the port (e.g. overcurrent),
1262
; If the controller has disabled the port (e.g. overcurrent),
1230
; continue to next device (if there is one).
1263
; continue to next device (if there is one).
1231
        movzx   ecx, [esi+usb_controller.ResettingPort]
1264
        movzx   ecx, [esi+usb_controller.ResettingPort]
1232
        mov     eax, [edi+OhciRhPortStatusReg+ecx*4]
1265
        mov     eax, [edi+OhciRhPortStatusReg+ecx*4]
1233
        test    al, 2
1266
        test    al, 2
1234
        jnz     @f
1267
        jnz     @f
1235
        DEBUGF 1,'K : USB port disabled after reset, status=%x\n',eax
1268
        DEBUGF 1,'K : USB port disabled after reset, status=%x\n',eax
1236
        jmp     usb_test_pending_port
1269
        jmp     [usbhc_api.usb_test_pending_port]
1237
@@:
1270
@@:
1238
        push    ecx
1271
        push    ecx
1239
; 2. Get LowSpeed bit to bit 0 of eax and call the worker procedure
1272
; 2. Get LowSpeed bit to bit 0 of eax and call the worker procedure
1240
; to notify the protocol layer about new OHCI device.
1273
; to notify the protocol layer about new OHCI device.
1241
        mov     eax, [edi+OhciRhPortStatusReg+ecx*4]
1274
        mov     eax, [edi+OhciRhPortStatusReg+ecx*4]
1242
        DEBUGF 1,'K : port_after_reset [%d] status of port %d is %x\n',[timer_ticks],ecx,eax
1275
        DEBUGF 1,'K : port_after_reset, status of port %d is %x\n',ecx,eax
1243
        shr     eax, 9
1276
        shr     eax, 9
1244
        call    ohci_new_device
1277
        call    ohci_new_device
1245
        pop     ecx
1278
        pop     ecx
1246
; 3. If something at the protocol layer has failed
1279
; 3. If something at the protocol layer has failed
1247
; (no memory, no bus address), disable the port and stop the initialization.
1280
; (no memory, no bus address), disable the port and stop the initialization.
1248
        test    eax, eax
1281
        test    eax, eax
1249
        jnz     .nothing
1282
        jnz     .nothing
1250
.disable_exit:
1283
.disable_exit:
1251
        mov     dword [edi+OhciRhPortStatusReg+ecx*4], 1
1284
        mov     dword [edi+OhciRhPortStatusReg+ecx*4], 1
1252
        jmp     usb_test_pending_port
1285
        jmp     [usbhc_api.usb_test_pending_port]
1253
.nothing:
1286
.nothing:
1254
        ret
1287
        ret
1255
endp
1288
endp
Line 1256... Line 1289...
1256
 
1289
 
Line 1270... Line 1303...
1270
        push    esi     ; .Controller
1303
        push    esi     ; .Controller
1271
        mov     ecx, esp
1304
        mov     ecx, esp
1272
        sub     esp, 12 ; ignored fields
1305
        sub     esp, 12 ; ignored fields
1273
        push    eax     ; .Flags
1306
        push    eax     ; .Flags
1274
; 4. Notify the protocol layer.
1307
; 4. Notify the protocol layer.
1275
        call    usb_new_device
1308
        invoke  usbhc_api.usb_new_device
1276
; 5. Cleanup the stack after step 3 and return.
1309
; 5. Cleanup the stack after step 3 and return.
1277
        add     esp, 20
1310
        add     esp, 20
1278
        ret
1311
        ret
1279
endp
1312
endp
Line 1285... Line 1318...
1285
proc ohci_process_deferred
1318
proc ohci_process_deferred
1286
        push    ebx edi         ; save used registers to be stdcall
1319
        push    ebx edi         ; save used registers to be stdcall
1287
; 1. Initialize the return value.
1320
; 1. Initialize the return value.
1288
        push    -1
1321
        push    -1
1289
; 2. Process disconnect events.
1322
; 2. Process disconnect events.
1290
        call    usb_disconnect_stage2
1323
        invoke  usbhc_api.usb_disconnect_stage2
1291
; 3. Check for connected devices.
1324
; 3. Check for connected devices.
1292
; If there is a connected device which was connected less than
1325
; If there is a connected device which was connected less than
1293
; USB_CONNECT_DELAY ticks ago, plan to wake up when the delay will be over.
1326
; USB_CONNECT_DELAY ticks ago, plan to wake up when the delay will be over.
1294
; Otherwise, call ohci_new_port.
1327
; Otherwise, call ohci_new_port.
1295
        mov     edi, [esi+ohci_controller.MMIOBase-sizeof.ohci_controller]
1328
        mov     edi, [esi+ohci_controller.MMIOBase-sizeof.ohci_controller]
Line 1297... Line 1330...
1297
        cmp     [esi+usb_controller.NewConnected], ecx
1330
        cmp     [esi+usb_controller.NewConnected], ecx
1298
        jz      .skip_newconnected
1331
        jz      .skip_newconnected
1299
.portloop:
1332
.portloop:
1300
        bt      [esi+usb_controller.NewConnected], ecx
1333
        bt      [esi+usb_controller.NewConnected], ecx
1301
        jnc     .noconnect
1334
        jnc     .noconnect
-
 
1335
; If this port is shared with the EHCI companion and we see the connect event,
-
 
1336
; then the device is USB1 dropped by EHCI,
-
 
1337
; so EHCI has already waited for debounce delay, we can proceed immediately.
-
 
1338
        cmp     [esi+ohci_controller.EhciCompanion-sizeof.ohci_controller], 0
-
 
1339
        jz      .portloop.test_time
-
 
1340
        dbgstr 'port is shared with EHCI, skipping initial debounce'
-
 
1341
        jmp     .connected
-
 
1342
.portloop.test_time:
1302
        mov     eax, [timer_ticks]
1343
        invoke  GetTimerTicks
1303
        sub     eax, [esi+usb_controller.ConnectedTime+ecx*4]
1344
        sub     eax, [esi+usb_controller.ConnectedTime+ecx*4]
1304
        sub     eax, USB_CONNECT_DELAY
1345
        sub     eax, USB_CONNECT_DELAY
1305
        jge     .connected
1346
        jge     .connected
1306
        neg     eax
1347
        neg     eax
1307
        cmp     [esp], eax
1348
        cmp     [esp], eax
Line 1319... Line 1360...
1319
        jb      .portloop
1360
        jb      .portloop
1320
.skip_newconnected:
1361
.skip_newconnected:
1321
; 4. Check for end of reset signalling. If so, call ohci_port_after_reset.
1362
; 4. Check for end of reset signalling. If so, call ohci_port_after_reset.
1322
        cmp     [esi+usb_controller.ResettingStatus], 2
1363
        cmp     [esi+usb_controller.ResettingStatus], 2
1323
        jnz     .no_reset_recovery
1364
        jnz     .no_reset_recovery
1324
        mov     eax, [timer_ticks]
1365
        invoke  GetTimerTicks
1325
        sub     eax, [esi+usb_controller.ResetTime]
1366
        sub     eax, [esi+usb_controller.ResetTime]
1326
        sub     eax, USB_RESET_RECOVERY_TIME
1367
        sub     eax, USB_RESET_RECOVERY_TIME
1327
        jge     .reset_done
1368
        jge     .reset_done
1328
        neg     eax
1369
        neg     eax
1329
        cmp     [esp], eax
1370
        cmp     [esp], eax
Line 1351... Line 1392...
1351
        jmp     .tdloop
1392
        jmp     .tdloop
1352
.tddone:
1393
.tddone:
1353
; 6. Process wait-done notifications, test for new wait requests.
1394
; 6. Process wait-done notifications, test for new wait requests.
1354
; Note: that must be done after steps 2 and 5 which could create new requests.
1395
; Note: that must be done after steps 2 and 5 which could create new requests.
1355
; 6a. Call the worker function from main USB code.
1396
; 6a. Call the worker function from main USB code.
1356
        call    usb_process_wait_lists
1397
        invoke  usbhc_api.usb_process_wait_lists
1357
; 6b. If no new requests, skip the rest of this step.
1398
; 6b. If no new requests, skip the rest of this step.
1358
        test    eax, eax
1399
        test    eax, eax
1359
        jz      @f
1400
        jz      @f
1360
; 6c. OHCI is not allowed to cache anything; we don't know what is
1401
; 6c. OHCI is not allowed to cache anything; we don't know what is
1361
; processed right now, but we can be sure that the controller will not
1402
; processed right now, but we can be sure that the controller will not
Line 1400... Line 1441...
1400
        lea     eax, [ebx+ohci_gtd.NextTD-sizeof.ohci_gtd]
1441
        lea     eax, [ebx+ohci_gtd.NextTD-sizeof.ohci_gtd]
1401
        xor     ebx, ebx
1442
        xor     ebx, ebx
1402
        jmp     .next_td2
1443
        jmp     .next_td2
1403
@@:
1444
@@:
1404
; 2. Remove the descriptor from the descriptors queue.
1445
; 2. Remove the descriptor from the descriptors queue.
1405
        call    usb_unlink_td
1446
        invoke  usbhc_api.usb_unlink_td
1406
; 3. Get number of bytes that remain to be transferred.
1447
; 3. Get number of bytes that remain to be transferred.
1407
; If CurBufPtr is zero, everything was transferred.
1448
; If CurBufPtr is zero, everything was transferred.
1408
        xor     edx, edx
1449
        xor     edx, edx
1409
        cmp     [ebx+ohci_gtd.CurBufPtr-sizeof.ohci_gtd], edx
1450
        cmp     [ebx+ohci_gtd.CurBufPtr-sizeof.ohci_gtd], edx
1410
        jz      .gotlen
1451
        jz      .gotlen
Line 1427... Line 1468...
1427
; The actual length is Length - (remaining length).
1468
; The actual length is Length - (remaining length).
1428
        sub     edx, [ebx+usb_gtd.Length]
1469
        sub     edx, [ebx+usb_gtd.Length]
1429
        neg     edx
1470
        neg     edx
1430
; 4. Check for error. If so, go to 7.
1471
; 4. Check for error. If so, go to 7.
1431
        push    ebx
1472
        push    ebx
1432
        mov     eax, [ebx+ohci_gtd.Flags-sizeof.ohci_gtd]
1473
        mov     ecx, [ebx+ohci_gtd.Flags-sizeof.ohci_gtd]
1433
        shr     eax, 28
1474
        shr     ecx, 28
1434
        jnz     .error
1475
        jnz     .error
1435
.notify:
1476
.notify:
1436
; 5. Successful completion.
1477
; 5. Successful completion.
1437
; 5a. Check whether this descriptor has an associated callback.
-
 
1438
        mov     ecx, [ebx+usb_gtd.Callback]
-
 
1439
        test    ecx, ecx
-
 
1440
        jz      .ok_nocallback
-
 
1441
; 5b. If so, call the callback.
-
 
1442
        stdcall_verify ecx, [ebx+usb_gtd.Pipe], eax, \
-
 
1443
                [ebx+usb_gtd.Buffer], edx, [ebx+usb_gtd.UserData]
-
 
1444
        jmp     .next_td
-
 
1445
.ok_nocallback:
-
 
1446
; 5c. Otherwise, add length of the current descriptor to the next descriptor.
-
 
1447
        mov     eax, [ebx+usb_gtd.NextVirt]
1478
        invoke  usbhc_api.usb_process_gtd
1448
        add     [eax+usb_gtd.Length], edx
-
 
1449
.next_td:
1479
.next_td:
1450
; 6. Free the current descriptor and advance to the next item.
1480
; 6. Free the current descriptor and advance to the next item.
1451
; If the current item is the last in the list,
1481
; If the current item is the last in the list,
1452
; set DoneListEndPtr to pointer to DoneList.
1482
; set DoneListEndPtr to pointer to DoneList.
1453
        cmp     ebx, [esp]
1483
        cmp     ebx, [esp]
1454
        jz      @f
1484
        jz      @f
1455
        stdcall usb1_free_general_td, ebx
1485
        stdcall ohci_free_gtd, ebx
1456
@@:
1486
@@:
1457
        pop     ebx
1487
        pop     ebx
1458
        lea     eax, [ebx+ohci_gtd.NextTD-sizeof.ohci_gtd]
1488
        lea     eax, [ebx+ohci_gtd.NextTD-sizeof.ohci_gtd]
1459
.next_td2:
1489
.next_td2:
1460
        push    ebx
1490
        push    ebx
Line 1475... Line 1505...
1475
; ecx = the next item
1505
; ecx = the next item
1476
        push    ecx
1506
        push    ecx
1477
; Free the current item, set ebx to the next item, continue to 5a.
1507
; Free the current item, set ebx to the next item, continue to 5a.
1478
        test    ebx, ebx
1508
        test    ebx, ebx
1479
        jz      @f
1509
        jz      @f
1480
        stdcall usb1_free_general_td, ebx
1510
        stdcall ohci_free_gtd, ebx
1481
@@:
1511
@@:
1482
        pop     ebx
1512
        pop     ebx
1483
        ret
1513
        ret
1484
.error:
1514
.error:
1485
; 7. There was an error while processing this descriptor.
1515
; 7. There was an error while processing this descriptor.
1486
; The hardware has stopped processing the queue.
1516
; The hardware has stopped processing the queue.
1487
; 7a. Save status and length.
1517
; 7a. Save status and length.
1488
        push    eax
1518
        push    ecx
1489
        push    edx
1519
        push    edx
1490
;       DEBUGF 1,'K : TD failed:\n'
1520
;       DEBUGF 1,'K : TD failed:\n'
1491
;       DEBUGF 1,'K : %x %x %x %x\n',[ebx-sizeof.ohci_gtd],[ebx-sizeof.ohci_gtd+4],[ebx-sizeof.ohci_gtd+8],[ebx-sizeof.ohci_gtd+12]
1521
;       DEBUGF 1,'K : %x %x %x %x\n',[ebx-sizeof.ohci_gtd],[ebx-sizeof.ohci_gtd+4],[ebx-sizeof.ohci_gtd+8],[ebx-sizeof.ohci_gtd+12]
1492
;       DEBUGF 1,'K : %x %x %x %x\n',[ebx-sizeof.ohci_gtd+16],[ebx-sizeof.ohci_gtd+20],[ebx-sizeof.ohci_gtd+24],[ebx-sizeof.ohci_gtd+28]
1522
;       DEBUGF 1,'K : %x %x %x %x\n',[ebx-sizeof.ohci_gtd+16],[ebx-sizeof.ohci_gtd+20],[ebx-sizeof.ohci_gtd+24],[ebx-sizeof.ohci_gtd+28]
1493
;       mov     eax, [ebx+usb_gtd.Pipe]
1523
;       mov     eax, [ebx+usb_gtd.Pipe]
1494
;       DEBUGF 1,'K : pipe: %x %x %x %x\n',[eax-sizeof.ohci_pipe],[eax-sizeof.ohci_pipe+4],[eax-sizeof.ohci_pipe+8],[eax-sizeof.ohci_pipe+12]
1524
;       DEBUGF 1,'K : pipe: %x %x %x %x\n',[eax-sizeof.ohci_pipe],[eax-sizeof.ohci_pipe+4],[eax-sizeof.ohci_pipe+8],[eax-sizeof.ohci_pipe+12]
1495
; 7b. Traverse the list of descriptors looking for the final packet
1525
; 7b. Traverse the list of descriptors looking for the final packet
1496
; for this transfer.
1526
; for this transfer.
1497
; Free and unlink non-final descriptors, except the current one.
1527
; Free and unlink non-final descriptors, except the current one.
1498
; Final descriptor will be freed in step 6.
1528
; Final descriptor will be freed in step 6.
1499
        call    usb_is_final_packet
1529
        invoke  usbhc_api.usb_is_final_packet
1500
        jnc     .found_final
1530
        jnc     .found_final
1501
        mov     ebx, [ebx+usb_gtd.NextVirt]
1531
        mov     ebx, [ebx+usb_gtd.NextVirt]
1502
virtual at esp
1532
virtual at esp
1503
.length         dd      ?
1533
.length         dd      ?
1504
.error_code     dd      ?
1534
.error_code     dd      ?
1505
.current_item   dd      ?
1535
.current_item   dd      ?
1506
end virtual
1536
end virtual
1507
.look_final:
1537
.look_final:
1508
        call    usb_unlink_td
1538
        invoke  usbhc_api.usb_unlink_td
1509
        call    usb_is_final_packet
1539
        invoke  usbhc_api.usb_is_final_packet
1510
        jnc     .found_final
1540
        jnc     .found_final
1511
        push    [ebx+usb_gtd.NextVirt]
1541
        push    [ebx+usb_gtd.NextVirt]
1512
        stdcall usb1_free_general_td, ebx
1542
        stdcall ohci_free_gtd, ebx
1513
        pop     ebx
1543
        pop     ebx
1514
        jmp     .look_final
1544
        jmp     .look_final
1515
.found_final:
1545
.found_final:
1516
; 7c. If error code is USB_STATUS_UNDERRUN and the last TD allows short packets,
1546
; 7c. If error code is USB_STATUS_UNDERRUN and the last TD allows short packets,
1517
; it is not an error.
1547
; it is not an error.
Line 1528... Line 1558...
1528
        mov     edx, [ecx+ohci_pipe.HeadP-sizeof.ohci_pipe]
1558
        mov     edx, [ecx+ohci_pipe.HeadP-sizeof.ohci_pipe]
1529
        and     edx, 2
1559
        and     edx, 2
1530
.advance_queue:
1560
.advance_queue:
1531
        mov     eax, [ebx+usb_gtd.NextVirt]
1561
        mov     eax, [ebx+usb_gtd.NextVirt]
1532
        sub     eax, sizeof.ohci_gtd
1562
        sub     eax, sizeof.ohci_gtd
1533
        call    get_phys_addr
1563
        invoke  GetPhysAddr
1534
        or      eax, edx
1564
        or      eax, edx
1535
        mov     [ecx+ohci_pipe.HeadP-sizeof.ohci_pipe], eax
1565
        mov     [ecx+ohci_pipe.HeadP-sizeof.ohci_pipe], eax
1536
        push    ebx
1566
        push    ebx
1537
        mov     ebx, ecx
1567
        mov     ebx, ecx
1538
        call    ohci_notify_new_work
1568
        call    ohci_notify_new_work
1539
        pop     ebx
1569
        pop     ebx
1540
        pop     edx eax
1570
        pop     edx ecx
1541
        jmp     .notify
1571
        jmp     .notify
1542
; 7d. Abort the entire transfer.
1572
; 7d. Abort the entire transfer.
1543
; There are two cases: either there is only one transfer stage
1573
; There are two cases: either there is only one transfer stage
1544
; (everything except control transfers), then ebx points to the last TD and
1574
; (everything except control transfers), then ebx points to the last TD and
1545
; all previous TD were unlinked and dismissed (if possible),
1575
; all previous TD were unlinked and dismissed (if possible),
Line 1551... Line 1581...
1551
        cmp     [ebx+usb_gtd.Callback], 0
1581
        cmp     [ebx+usb_gtd.Callback], 0
1552
        jnz     .halted
1582
        jnz     .halted
1553
        cmp     ebx, [.current_item]
1583
        cmp     ebx, [.current_item]
1554
        push    [ebx+usb_gtd.NextVirt]
1584
        push    [ebx+usb_gtd.NextVirt]
1555
        jz      @f
1585
        jz      @f
1556
        stdcall usb1_free_general_td, ebx
1586
        stdcall ohci_free_gtd, ebx
1557
@@:
1587
@@:
1558
        pop     ebx
1588
        pop     ebx
1559
        call    usb_unlink_td
1589
        invoke  usbhc_api.usb_unlink_td
1560
.halted:
1590
.halted:
1561
; 7e. For bulk/interrupt transfers we have no choice but halt the queue,
1591
; 7e. For bulk/interrupt transfers we have no choice but halt the queue,
1562
; the driver should intercede (through some API which is not written yet).
1592
; the driver should intercede (through some API which is not written yet).
1563
; Control pipes normally recover at the next SETUP transaction (first stage
1593
; Control pipes normally recover at the next SETUP transaction (first stage
1564
; of any control transfer), so we hope on the best and just advance the queue
1594
; of any control transfer), so we hope on the best and just advance the queue
Line 1595... Line 1625...
1595
        mov     [eax+usb_pipe.NextVirt], edx
1625
        mov     [eax+usb_pipe.NextVirt], edx
1596
        mov     edx, [ebx+ohci_pipe.NextED-sizeof.ohci_pipe]
1626
        mov     edx, [ebx+ohci_pipe.NextED-sizeof.ohci_pipe]
1597
        mov     [eax+ohci_pipe.NextED-sizeof.ohci_pipe], edx
1627
        mov     [eax+ohci_pipe.NextED-sizeof.ohci_pipe], edx
1598
        ret
1628
        ret
1599
endp
1629
endp
-
 
1630
 
-
 
1631
; Allocates one endpoint structure for OHCI.
-
 
1632
; Returns pointer to software part (usb_pipe) in eax.
-
 
1633
proc ohci_alloc_pipe
-
 
1634
        push    ebx
-
 
1635
        mov     ebx, ohci_ep_mutex
-
 
1636
        invoke  usbhc_api.usb_allocate_common, (sizeof.ohci_pipe + sizeof.usb_pipe + 0Fh) and not 0Fh
-
 
1637
        test    eax, eax
-
 
1638
        jz      @f
-
 
1639
        add     eax, sizeof.ohci_pipe
-
 
1640
@@:
-
 
1641
        pop     ebx
-
 
1642
        ret
-
 
1643
endp
-
 
1644
 
-
 
1645
; Free one endpoint structure for OHCI.
-
 
1646
; Stdcall with one argument, pointer to software part (usb_pipe).
-
 
1647
proc ohci_free_pipe
-
 
1648
        sub     dword [esp+4], sizeof.ohci_pipe
-
 
1649
        jmp     [usbhc_api.usb_free_common]
-
 
1650
endp
-
 
1651
 
-
 
1652
; Allocates one general transfer descriptor structure for OHCI.
-
 
1653
; Returns pointer to software part (usb_gtd) in eax.
-
 
1654
proc ohci_alloc_gtd
-
 
1655
        push    ebx
-
 
1656
        mov     ebx, ohci_gtd_mutex
-
 
1657
        invoke  usbhc_api.usb_allocate_common, (sizeof.ohci_gtd + sizeof.usb_gtd + 0Fh) and not 0Fh
-
 
1658
        test    eax, eax
-
 
1659
        jz      @f
-
 
1660
        add     eax, sizeof.ohci_gtd
-
 
1661
@@:
-
 
1662
        pop     ebx
-
 
1663
        ret
-
 
1664
endp
-
 
1665
 
-
 
1666
; Free one general transfer descriptor structure for OHCI.
-
 
1667
; Stdcall with one argument, pointer to software part (usb_gtd).
-
 
1668
proc ohci_free_gtd
-
 
1669
        sub     dword [esp+4], sizeof.ohci_gtd
-
 
1670
        jmp     [usbhc_api.usb_free_common]
-
 
1671
endp
-
 
1672
 
-
 
1673
include 'usb1_scheduler.inc'
-
 
1674
define_controller_name ohci
-
 
1675
 
-
 
1676
section '.data' readable writable
-
 
1677
include '../peimport.inc'
-
 
1678
include_debug_strings
-
 
1679
IncludeIGlobals
-
 
1680
IncludeUGlobals
-
 
1681
align 4
-
 
1682
usbhc_api usbhc_func
-
 
1683
ohci_ep_first_page      dd      ?
-
 
1684
ohci_ep_mutex           MUTEX
-
 
1685
ohci_gtd_first_page     dd      ?
-
 
1686
ohci_gtd_mutex          MUTEX