Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 4546 → Rev 4547

/drivers/usb/ehci.asm
156,8 → 156,6
; Working area for the current TD, if there is any.
; When TD is retired, it is written to that TD and Overlay is loaded
; from the new TD, if any.
BaseList dd ?
; Pointer to head of the corresponding pipe list.
ends
 
; This structure describes the static head of every list of pipes.
293,6 → 291,8
dd ehci_alloc_transfer
dd ehci_insert_transfer
dd ehci_new_device
dd ehci_disable_pipe
dd ehci_enable_pipe
ehci_name db 'EHCI',0
endg
 
998,7 → 998,7
jz .return0
mov word [edi+ehci_pipe.Flags-sizeof.ehci_pipe], ax
.insert:
mov [edi+ehci_pipe.BaseList-sizeof.ehci_pipe], edx
mov [edi+usb_pipe.BaseList], edx
; Insert to the head of the corresponding list.
; Note: inserting to the head guarantees that the list traverse in
; ehci_process_updated_schedule, once started, will not interact with new pipes.
1912,22 → 1912,61
call ehci_fs_interrupt_list_unlink
.interrupt_common:
@@:
mov edx, [ebx+usb_pipe.NextVirt]
mov eax, [ebx+usb_pipe.PrevVirt]
mov [edx+usb_pipe.PrevVirt], eax
mov [eax+usb_pipe.NextVirt], edx
ret
endp
 
; This procedure temporarily removes the given pipe from hardware queue.
; esi -> usb_controller, ebx -> usb_pipe
proc ehci_disable_pipe
mov eax, [ebx+ehci_pipe.NextQH-sizeof.ehci_pipe]
mov ecx, [ebx+usb_pipe.PrevVirt]
mov edx, esi
sub edx, eax
sub edx, ecx
cmp edx, sizeof.ehci_controller
mov edx, [ebx+ehci_pipe.NextQH-sizeof.ehci_pipe]
jb .prev_is_static
mov [eax+ehci_pipe.NextQH-sizeof.ehci_pipe], edx
mov [ecx+ehci_pipe.NextQH-sizeof.ehci_pipe], eax
ret
.prev_is_static:
mov [eax+ehci_static_ep.NextQH-ehci_static_ep.SoftwarePart], edx
mov [ecx+ehci_static_ep.NextQH-ehci_static_ep.SoftwarePart], eax
ret
endp
 
; This procedure reinserts the given pipe to hardware queue
; after ehci_disable_pipe, with clearing transfer queue.
; esi -> usb_controller, ebx -> usb_pipe
; edx -> current descriptor, eax -> new last descriptor
proc ehci_enable_pipe
; 1. Clear transfer queue.
; 1a. Clear status bits so that the controller will try to advance the queue
; without doing anything, keep DataToggle and PID bits.
and [ebx+ehci_pipe.Overlay.Token-sizeof.ehci_pipe], 80000000h
; 1b. Set [Alternate]NextTD to physical address of the new last descriptor.
sub eax, sizeof.ehci_gtd
invoke GetPhysAddr
mov [ebx+ehci_pipe.HeadTD-sizeof.ehci_pipe], eax
mov [ebx+ehci_pipe.Overlay.NextTD-sizeof.ehci_pipe], eax
mov [ebx+ehci_pipe.Overlay.AlternateNextTD-sizeof.ehci_pipe], eax
; 2. Reinsert the pipe to hardware queue.
lea eax, [ebx-sizeof.ehci_pipe]
invoke GetPhysAddr
inc eax
inc eax
mov ecx, [ebx+usb_pipe.PrevVirt]
mov edx, esi
sub edx, ecx
cmp edx, sizeof.ehci_controller
jb .prev_is_static
mov edx, [ecx+ehci_pipe.NextQH-sizeof.ehci_pipe]
mov [ebx+ehci_pipe.NextQH-sizeof.ehci_pipe], edx
mov [ecx+ehci_pipe.NextQH-sizeof.ehci_pipe], eax
ret
.prev_is_static:
mov edx, [ecx+ehci_static_ep.NextQH-ehci_static_ep.SoftwarePart]
mov [ebx+ehci_pipe.NextQH-sizeof.ehci_pipe], edx
mov [ecx+ehci_static_ep.NextQH-ehci_static_ep.SoftwarePart], eax
ret
endp
 
proc ehci_alloc_td
push ebx
mov ebx, ehci_gtd_mutex
/drivers/usb/ehci_scheduler.inc
298,7 → 298,7
imul eax, ecx
movzx ecx, byte [ebx+ehci_pipe.Flags-sizeof.ehci_pipe]
; get target list
mov edx, [ebx+ehci_pipe.BaseList-sizeof.ehci_pipe]
mov edx, [ebx+usb_pipe.BaseList]
; update bandwidth
.dec_bandwidth:
shr ecx, 1
732,7 → 732,7
mov edi, esp
call tt_fill_split_info
; get target list
mov edx, [ebx+ehci_pipe.BaseList-sizeof.ehci_pipe]
mov edx, [ebx+usb_pipe.BaseList]
; update bandwidth for Start-Split
mov eax, [edi+usb_split_info.ssplit_bandwidth]
xor ecx, ecx
/drivers/usb/ohci.asm
64,7 → 64,7
; 2. Next 4 bits (bits 7-10) are EndpointNumber. This is the USB address of
; the endpoint within the function.
; 3. Next 2 bits (bits 11-12) are Direction. This 2-bit field indicates the
; direction of data flow: 1 = IN, 2 = OUT. If neither IN nor OUT is
; direction of data flow: 1 = OUT, 2 = IN. If neither IN nor OUT is
; specified, then the direction is determined from the PID field of the TD.
; For CONTROL endpoints, the transfer direction is different
; for different transfers, so the value of this field is 0
322,6 → 322,8
dd ohci_alloc_transfer
dd ohci_insert_transfer
dd ohci_new_device
dd ohci_disable_pipe
dd ohci_enable_pipe
ohci_name db 'OHCI',0
endg
 
1014,6 → 1016,7
; Inserting to tail would work as well,
; but let's be consistent with other controllers.
.insert:
mov [edi+usb_pipe.BaseList], edx
mov ecx, [edx+usb_pipe.NextVirt]
mov [edi+usb_pipe.NextVirt], ecx
mov [edi+usb_pipe.PrevVirt], edx
1614,20 → 1617,44
mov eax, [ebx+ohci_pipe.Flags-sizeof.ohci_pipe]
bt eax, 13
setc cl
bt eax, 11
bt eax, 12
setc ch
shr eax, 16
stdcall usb1_interrupt_list_unlink, eax, ecx
@@:
mov edx, [ebx+usb_pipe.NextVirt]
mov eax, [ebx+usb_pipe.PrevVirt]
mov [edx+usb_pipe.PrevVirt], eax
mov [eax+usb_pipe.NextVirt], edx
mov edx, [ebx+ohci_pipe.NextED-sizeof.ohci_pipe]
mov [eax+ohci_pipe.NextED-sizeof.ohci_pipe], edx
ret
endp
 
; This procedure temporarily removes the given pipe from hardware queue,
; keeping it in software lists.
; esi -> usb_controller, ebx -> usb_pipe
proc ohci_disable_pipe
mov eax, [ebx+ohci_pipe.NextED-sizeof.ohci_pipe]
mov edx, [ebx+usb_pipe.PrevVirt]
mov [edx+ohci_pipe.NextED-sizeof.ohci_pipe], eax
ret
endp
 
; This procedure reinserts the given pipe from hardware queue
; after ehci_disable_pipe, with clearing transfer queue.
; esi -> usb_controller, ebx -> usb_pipe
; edx -> current descriptor, eax -> new last descriptor
proc ohci_enable_pipe
sub eax, sizeof.ohci_gtd
invoke GetPhysAddr
mov edx, [ebx+ohci_pipe.HeadP-sizeof.ohci_pipe]
and edx, 2
or eax, edx
mov [ebx+ohci_pipe.HeadP-sizeof.ohci_pipe], eax
lea eax, [ebx-sizeof.ohci_pipe]
invoke GetPhysAddr
mov edx, [ebx+usb_pipe.PrevVirt]
mov ecx, [edx+ohci_pipe.NextED-sizeof.ohci_pipe]
mov [ebx+ohci_pipe.NextED-sizeof.ohci_pipe], ecx
mov [edx+ohci_pipe.NextED-sizeof.ohci_pipe], eax
ret
endp
 
; Allocates one endpoint structure for OHCI.
; Returns pointer to software part (usb_pipe) in eax.
proc ohci_alloc_pipe
/drivers/usb/uhci.asm
274,6 → 274,8
dd uhci_alloc_transfer
dd uhci_insert_transfer
dd uhci_new_device
dd uhci_disable_pipe
dd uhci_enable_pipe
uhci_name db 'UHCI',0
endg
 
1133,7 → 1135,6
jnz .loop
; 5. Flip the toggle bit in uhci_pipe structure.
xor byte [ecx+uhci_pipe.Token-sizeof.uhci_pipe-usb_pipe.Lock+2], 1 shl (19-16)
or dword [ecx+uhci_pipe.Token-sizeof.uhci_pipe-usb_pipe.Lock], eax
; 6. Unlock the transfer queue.
invoke MutexUnlock
.nothing:
1461,6 → 1462,7
test edx, edx
jz .return0
.insert:
mov [edi+usb_pipe.BaseList], edx
; Insert to the head of the corresponding list.
; Note: inserting to the head guarantees that the list traverse in
; uhci_process_updated_schedule, once started, will not interact with new pipes.
1505,20 → 1507,47
shr eax, 21
stdcall usb1_interrupt_list_unlink, eax, ecx
@@:
; Note: we need to ensure that NextVirt field of the pipe is not modified;
; this procedure can be called while uhci_process_updated_schedule processes
; the same pipe, and it needs a correct NextVirt field to continue.
mov edx, [ebx+usb_pipe.NextVirt]
mov eax, [ebx+usb_pipe.PrevVirt]
mov [edx+usb_pipe.PrevVirt], eax
mov [eax+usb_pipe.NextVirt], edx
; Note: eax could be either usb_pipe or usb_static_ep;
ret
endp
 
; This procedure temporarily removes the given pipe from hardware queue,
; keeping it in software lists.
; esi -> usb_controller, ebx -> usb_pipe
proc uhci_disable_pipe
mov eax, [ebx+uhci_pipe.NextQH-sizeof.uhci_pipe]
mov edx, [ebx+usb_pipe.PrevVirt]
; Note: edx could be either usb_pipe or usb_static_ep;
; fortunately, NextQH and SoftwarePart have same offsets in both.
mov edx, [ebx+uhci_pipe.NextQH-sizeof.uhci_pipe]
mov [eax+uhci_pipe.NextQH-sizeof.uhci_pipe], edx
mov [edx+uhci_pipe.NextQH-sizeof.uhci_pipe], eax
ret
endp
 
; This procedure reinserts the given pipe from hardware queue
; after ehci_disable_pipe, with clearing transfer queue.
; esi -> usb_controller, ebx -> usb_pipe
; edx -> current descriptor, eax -> new last descriptor
proc uhci_enable_pipe
; 1. Copy DataToggle bit from edx to pipe.
mov ecx, [edx+uhci_gtd.Token-sizeof.uhci_gtd]
xor ecx, [ebx+uhci_pipe.Token-sizeof.uhci_pipe]
and ecx, 1 shl 19
xor [ebx+uhci_pipe.Token-sizeof.uhci_pipe], ecx
; 2. Store new last descriptor as the current HeadTD.
sub eax, sizeof.uhci_gtd
invoke GetPhysAddr
mov [ebx+uhci_pipe.HeadTD-sizeof.uhci_pipe], eax
; 3. Reinsert the pipe to hardware queue.
lea eax, [ebx-sizeof.uhci_pipe]
invoke GetPhysAddr
inc eax
inc eax
mov edx, [ebx+usb_pipe.PrevVirt]
mov ecx, [edx+uhci_pipe.NextQH-sizeof.uhci_pipe]
mov [ebx+uhci_pipe.NextQH-sizeof.uhci_pipe], ecx
mov [edx+uhci_pipe.NextQH-sizeof.uhci_pipe], eax
ret
endp
 
; This procedure is called from the several places in main USB code
; and allocates required packets for the given transfer stage.
; ebx = pipe, other parameters are passed through the stack
/drivers/usb/usb1_scheduler.inc
167,12 → 167,7
mov eax, [.maxpacket]
mov ecx, dword [.lowspeed]
call calc_usb1_bandwidth
; find list header
mov edx, ebx
@@:
mov edx, [edx+usb_pipe.NextVirt]
cmp [edx+usb_pipe.Controller], esi
jz @b
mov edx, [ebx+usb_pipe.BaseList]
; subtract pipe bandwidth
sub [edx+usb_static_ep.Bandwidth], eax
ret 8