/kernel/trunk/bus/usb/ehci.inc |
---|
1045,15 → 1045,21 |
; this corresponds to 4001h bytes. If the requested size is |
; greater, we should split the transfer into several descriptors. |
; Boundaries to split must be multiples of endpoint transfer size |
; to avoid short packets except in the end of the transfer, |
; 4000h is always a good value. |
; to avoid short packets except in the end of the transfer. |
cmp [size], 4001h |
jbe .lastpacket |
; 2. While the remaining data cannot fit in one descriptor, |
; allocate full descriptors (of maximal possible size). |
mov edi, 4000h |
; 2a. Calculate size of one descriptor: must be a multiple of transfer size |
; and must be not greater than 4001h. |
movzx ecx, word [ebx+ohci_pipe.Flags+2-sizeof.ohci_pipe] |
mov eax, 4001h |
xor edx, edx |
mov edi, eax |
div ecx |
sub edi, edx |
mov [packetSize], edi |
.fullpackets: |
cmp [size], edi |
jbe .lastpacket |
call ehci_alloc_packet |
test eax, eax |
jz .fail |
1060,7 → 1066,8 |
mov [td], eax |
add [buffer], edi |
sub [size], edi |
jmp .fullpackets |
cmp [size], 4001h |
ja .fullpackets |
; 3. The remaining data can fit in one packet; |
; allocate the last descriptor with size = size of remaining data. |
.lastpacket: |
/kernel/trunk/bus/usb/ohci.inc |
---|
1058,15 → 1058,22 |
; this corresponds to 1001h bytes. If the requested size is |
; greater, we should split the transfer into several descriptors. |
; Boundaries to split must be multiples of endpoint transfer size |
; to avoid short packets except in the end of the transfer, |
; 1000h is always a good value. |
; to avoid short packets except in the end of the transfer. |
cmp [size], 1001h |
jbe .lastpacket |
; 2. While the remaining data cannot fit in one packet, |
; allocate page-sized descriptors. |
mov edi, 1000h |
; allocate full-sized descriptors. |
; 2a. Calculate size of one descriptor: must be a multiple of transfer size |
; and must be not greater than 1001h. |
movzx ecx, word [ebx+ohci_pipe.Flags+2-sizeof.ohci_pipe] |
mov eax, 1001h |
xor edx, edx |
mov edi, eax |
div ecx |
sub edi, edx |
; 2b. Allocate in loop. |
mov [packetSize], edi |
.fullpackets: |
cmp [size], edi |
jbe .lastpacket |
call ohci_alloc_packet |
test eax, eax |
jz .fail |
1073,7 → 1080,8 |
mov [td], eax |
add [buffer], edi |
sub [size], edi |
jmp .fullpackets |
cmp [size], 1001h |
ja .fullpackets |
; 3. The remaining data can fit in one descriptor; |
; allocate the last descriptor with size = size of remaining data. |
.lastpacket: |
/kernel/trunk/bus/usb/uhci.inc |
---|
20,9 → 20,8 |
USB_PID_OUT = 0E1h |
; UHCI does not support an interrupt on root hub status change. We must poll |
; the controller periodically. This is the period in timer ticks (10ms). |
; We use the value 100 ms: it is valid value for USB hub poll rate (1-255 ms), |
; small enough to be responsible to connect events and large enough to not |
; load CPU too often. |
; We use the value 100 ticks: it is small enough to be responsible to connect |
; events and large enough to not load CPU too often. |
UHCI_POLL_INTERVAL = 100 |
; the following constant is an invalid encoding for length fields in |
; uhci_gtd; it is used to check whether an inactive TD has been |
1718,9 → 1717,12 |
push eax |
sub eax, sizeof.uhci_gtd |
call get_phys_addr |
; use Depth traversal unless this is the first TD in the transfer stage; |
; for Control/Bulk pipes, use Depth traversal unless this is the first TD |
; in the transfer stage; |
; uhci_insert_transfer will set Depth traversal for the first TD and clear |
; it in the last TD |
test [ebx+usb_pipe.Type], 1 |
jnz @f |
cmp ecx, [ebx+usb_pipe.LastTD] |
jz @f |
or eax, 4 |
1778,7 → 1780,10 |
or byte [ecx+uhci_gtd.ControlStatus+3-sizeof.uhci_gtd], 1 shl (24-24) ; set InterruptOnComplete bit |
mov eax, [esp+4] |
or byte [eax+uhci_gtd.ControlStatus+2-sizeof.uhci_gtd], 1 shl (23-16) ; set Active bit |
test [ebx+usb_pipe.Type], 1 |
jnz @f |
or byte [eax+uhci_gtd.NextTD-sizeof.uhci_gtd], 4 ; set Depth bit |
@@: |
ret |
endp |