forked from KolibriOS/kolibrios
kolibri-process: update
git-svn-id: svn://kolibrios.org@4587 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
1a9f7aa517
commit
15fd6b2c81
@ -258,7 +258,25 @@ end virtual
|
|||||||
call cache_lookup_write
|
call cache_lookup_write
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jnz .cache_error
|
jnz .cache_error
|
||||||
; 12d. For each sector, copy data, mark the item as not-modified copy of the disk,
|
; 12d. If the sector was already present in the cache as modified,
|
||||||
|
; data that were read at step 10 for this sector are obsolete,
|
||||||
|
; so rewrite data for the caller from the cache.
|
||||||
|
cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED
|
||||||
|
jnz .not_modified
|
||||||
|
mov esi, ecx
|
||||||
|
shl esi, 9
|
||||||
|
add esi, [ebx+DISKCACHE.data]
|
||||||
|
mov edi, [esp+4]
|
||||||
|
mov ecx, [esp]
|
||||||
|
shl ecx, 9-2
|
||||||
|
sub edi, ecx
|
||||||
|
mov ecx, 512/4
|
||||||
|
rep movsd
|
||||||
|
add [.current_buffer+8], 512
|
||||||
|
jmp .sector_done
|
||||||
|
.not_modified:
|
||||||
|
; 12e. For each not-modified sector,
|
||||||
|
; copy data, mark the item as not-modified copy of the disk,
|
||||||
; advance .current_buffer and .sector_hi:.sector_lo to the next sector.
|
; advance .current_buffer and .sector_hi:.sector_lo to the next sector.
|
||||||
mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY
|
mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY
|
||||||
mov esi, [.current_buffer+8]
|
mov esi, [.current_buffer+8]
|
||||||
@ -268,16 +286,17 @@ end virtual
|
|||||||
mov ecx, 512/4
|
mov ecx, 512/4
|
||||||
rep movsd
|
rep movsd
|
||||||
mov [.current_buffer+8], esi
|
mov [.current_buffer+8], esi
|
||||||
|
.sector_done:
|
||||||
add [.sector_lo+.local_vars2_size+8], 1
|
add [.sector_lo+.local_vars2_size+8], 1
|
||||||
adc [.sector_hi+.local_vars2_size+8], 0
|
adc [.sector_hi+.local_vars2_size+8], 0
|
||||||
; 12e. Continue the loop 12c-12d until all sectors are read.
|
; 12f. Continue the loop 12c-12e until all sectors are read.
|
||||||
dec dword [esp]
|
dec dword [esp]
|
||||||
jnz .store_to_cache
|
jnz .store_to_cache
|
||||||
.cache_error:
|
.cache_error:
|
||||||
; 12f. Restore after the loop: pop the local variable and restore edi.
|
; 12g. Restore after the loop: pop the local variable and restore edi.
|
||||||
pop ecx
|
pop ecx
|
||||||
pop edi
|
pop edi
|
||||||
; 12g. Release the lock.
|
; 12h. Release the lock.
|
||||||
mov ecx, [ebp+PARTITION.Disk]
|
mov ecx, [ebp+PARTITION.Disk]
|
||||||
add ecx, DISK.CacheLock
|
add ecx, DISK.CacheLock
|
||||||
call mutex_unlock
|
call mutex_unlock
|
||||||
@ -651,7 +670,13 @@ end virtual
|
|||||||
call cache_lookup_write
|
call cache_lookup_write
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jnz .cache_error
|
jnz .cache_error
|
||||||
; 11c. For each sector, copy data, mark the item as not-modified copy of the disk,
|
; 11c. Ignore sectors marked as modified: for them the cache is more recent that disk data.
|
||||||
|
cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED
|
||||||
|
jnz .not_modified
|
||||||
|
add [.current_buffer], 512
|
||||||
|
jmp .sector_done
|
||||||
|
.not_modified:
|
||||||
|
; 11d. For each sector, copy data, mark the item as not-modified copy of the disk,
|
||||||
; advance .current_buffer and .sector_hi:.sector_lo to the next sector.
|
; advance .current_buffer and .sector_hi:.sector_lo to the next sector.
|
||||||
mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY
|
mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY
|
||||||
mov esi, [.current_buffer]
|
mov esi, [.current_buffer]
|
||||||
@ -661,13 +686,14 @@ end virtual
|
|||||||
mov ecx, 512/4
|
mov ecx, 512/4
|
||||||
rep movsd
|
rep movsd
|
||||||
mov [.current_buffer], esi
|
mov [.current_buffer], esi
|
||||||
|
.sector_done:
|
||||||
add [.sector_lo+.local_vars2_size], 1
|
add [.sector_lo+.local_vars2_size], 1
|
||||||
adc [.sector_hi+.local_vars2_size], 0
|
adc [.sector_hi+.local_vars2_size], 0
|
||||||
; 11d. Continue the loop at 11b-11c until all sectors are processed.
|
; 11e. Continue the loop at 11b-11d until all sectors are processed.
|
||||||
dec [.num_sectors]
|
dec [.num_sectors]
|
||||||
jnz .store_to_cache
|
jnz .store_to_cache
|
||||||
.cache_error:
|
.cache_error:
|
||||||
; 11e. Release the lock.
|
; 11f. Release the lock.
|
||||||
mov ecx, [ebp+PARTITION.Disk]
|
mov ecx, [ebp+PARTITION.Disk]
|
||||||
add ecx, DISK.CacheLock
|
add ecx, DISK.CacheLock
|
||||||
call mutex_unlock
|
call mutex_unlock
|
||||||
@ -695,11 +721,9 @@ end virtual
|
|||||||
call cache_lookup_write
|
call cache_lookup_write
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jnz .floppy_cache_error
|
jnz .floppy_cache_error
|
||||||
; 14. Mark the item as empty for the case of read error.
|
|
||||||
mov [esi+CACHE_ITEM.Status], CACHE_ITEM_EMPTY
|
|
||||||
push ecx
|
push ecx
|
||||||
|
|
||||||
; 15. Call the driver to read one sector.
|
; 14. Call the driver to read one sector.
|
||||||
push 1
|
push 1
|
||||||
push esp
|
push esp
|
||||||
push edx
|
push edx
|
||||||
@ -713,7 +737,7 @@ end virtual
|
|||||||
pop ecx
|
pop ecx
|
||||||
dec ecx
|
dec ecx
|
||||||
jnz .floppy_read_error
|
jnz .floppy_read_error
|
||||||
; 16. Get the slot and pointer to the cache item,
|
; 15. Get the slot and pointer to the cache item,
|
||||||
; change the status to not-modified copy of the disk
|
; change the status to not-modified copy of the disk
|
||||||
; and go to 4c.
|
; and go to 4c.
|
||||||
pop ecx
|
pop ecx
|
||||||
@ -723,7 +747,7 @@ end virtual
|
|||||||
mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY
|
mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY
|
||||||
jmp .found_in_cache
|
jmp .found_in_cache
|
||||||
|
|
||||||
; On error at steps 13-15, release the lock
|
; On error at steps 13-14, release the lock
|
||||||
; and pass the error to the caller.
|
; and pass the error to the caller.
|
||||||
.floppy_read_error:
|
.floppy_read_error:
|
||||||
pop ecx
|
pop ecx
|
||||||
@ -849,6 +873,7 @@ proc cache_lookup_write
|
|||||||
mov [ebx+DISKCACHE.search_start], ecx
|
mov [ebx+DISKCACHE.search_start], ecx
|
||||||
popd [esi+CACHE_ITEM.SectorLo]
|
popd [esi+CACHE_ITEM.SectorLo]
|
||||||
popd [esi+CACHE_ITEM.SectorHi]
|
popd [esi+CACHE_ITEM.SectorHi]
|
||||||
|
mov [esi+CACHE_ITEM.Status], CACHE_ITEM_EMPTY
|
||||||
.return0:
|
.return0:
|
||||||
xor eax, eax ; success
|
xor eax, eax ; success
|
||||||
ret
|
ret
|
||||||
|
@ -1183,3 +1183,35 @@ IDE_BAR2_val dw ?
|
|||||||
IDE_BAR3_val dw ?
|
IDE_BAR3_val dw ?
|
||||||
endg
|
endg
|
||||||
;-----------------------------------------------------------------------------
|
;-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
proc clear_pci_ide_interrupts
|
||||||
|
mov esi, pcidev_list
|
||||||
|
.loop:
|
||||||
|
mov esi, [esi+PCIDEV.fd]
|
||||||
|
cmp esi, pcidev_list
|
||||||
|
jz .done
|
||||||
|
cmp [esi+PCIDEV.class], 0x01018F
|
||||||
|
jnz .loop
|
||||||
|
mov ah, [esi+PCIDEV.bus]
|
||||||
|
mov al, 2
|
||||||
|
mov bh, [esi+PCIDEV.devfn]
|
||||||
|
mov bl, 0x20
|
||||||
|
call pci_read_reg
|
||||||
|
and eax, 0FFFCh
|
||||||
|
mov edx, eax
|
||||||
|
add edx, 2
|
||||||
|
in al, dx
|
||||||
|
DEBUGF 1,'K : clear_pci_ide_interrupts: port[%x] = %x ',dx,al
|
||||||
|
out dx, al
|
||||||
|
in al, dx
|
||||||
|
DEBUGF 1,'-> %x; ',al
|
||||||
|
add edx, 8
|
||||||
|
in al, dx
|
||||||
|
DEBUGF 1,'port[%x] = %x ',dx,al
|
||||||
|
out dx, al
|
||||||
|
in al, dx
|
||||||
|
DEBUGF 1,'-> %x\n',al
|
||||||
|
jmp .loop
|
||||||
|
.done:
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
@ -722,3 +722,9 @@ end virtual
|
|||||||
leave
|
leave
|
||||||
ret
|
ret
|
||||||
endp
|
endp
|
||||||
|
|
||||||
|
; Export for drivers. Just returns the pointer to the pci-devices list.
|
||||||
|
proc get_pcidev_list
|
||||||
|
mov eax, pcidev_list
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
; =============================================================================
|
; =============================================================================
|
||||||
; Version of all structures related to host controllers.
|
; Version of all structures related to host controllers.
|
||||||
; Must be the same in kernel and *hci-drivers.
|
; Must be the same in kernel and *hci-drivers.
|
||||||
USBHC_VERSION = 1
|
USBHC_VERSION = 2
|
||||||
|
|
||||||
; USB device must have at least 100ms of stable power before initializing can
|
; USB device must have at least 100ms of stable power before initializing can
|
||||||
; proceed; one timer tick is 10ms, so enforce delay in 10 ticks
|
; proceed; one timer tick is 10ms, so enforce delay in 10 ticks
|
||||||
@ -46,6 +46,7 @@ USB_STATUS_BUFUNDERRUN = 13 ; underflow of internal controller buffer
|
|||||||
USB_STATUS_CLOSED = 16 ; pipe closed
|
USB_STATUS_CLOSED = 16 ; pipe closed
|
||||||
; either explicitly with USBClosePipe
|
; either explicitly with USBClosePipe
|
||||||
; or implicitly due to device disconnect
|
; or implicitly due to device disconnect
|
||||||
|
USB_STATUS_CANCELLED = 17 ; transfer cancelled with USBAbortPipe
|
||||||
|
|
||||||
; Possible speeds of USB devices
|
; Possible speeds of USB devices
|
||||||
USB_SPEED_FS = 0 ; full-speed
|
USB_SPEED_FS = 0 ; full-speed
|
||||||
@ -63,6 +64,9 @@ USB_FLAG_CAN_FREE = 2
|
|||||||
USB_FLAG_EXTRA_WAIT = 4
|
USB_FLAG_EXTRA_WAIT = 4
|
||||||
; The pipe was in wait list, while another event occured;
|
; The pipe was in wait list, while another event occured;
|
||||||
; when the first wait will be done, reinsert the pipe to wait list
|
; when the first wait will be done, reinsert the pipe to wait list
|
||||||
|
USB_FLAG_DISABLED = 8
|
||||||
|
; The pipe is temporarily disabled so that it is not visible to hardware
|
||||||
|
; but still remains in software list. Used for usb_abort_pipe.
|
||||||
USB_FLAG_CLOSED_BIT = 0 ; USB_FLAG_CLOSED = 1 shl USB_FLAG_CLOSED_BIT
|
USB_FLAG_CLOSED_BIT = 0 ; USB_FLAG_CLOSED = 1 shl USB_FLAG_CLOSED_BIT
|
||||||
|
|
||||||
; =============================================================================
|
; =============================================================================
|
||||||
@ -136,6 +140,14 @@ NewDevice dd ?
|
|||||||
; Initiate configuration of a new device (create pseudo-pipe describing that
|
; Initiate configuration of a new device (create pseudo-pipe describing that
|
||||||
; device and call usb_new_device).
|
; device and call usb_new_device).
|
||||||
; esi -> usb_controller, eax = speed (one of USB_SPEED_* constants).
|
; esi -> usb_controller, eax = speed (one of USB_SPEED_* constants).
|
||||||
|
DisablePipe dd ?
|
||||||
|
; This procedure temporarily removes the given pipe from hardware queue.
|
||||||
|
; esi -> usb_controller, ebx -> usb_pipe
|
||||||
|
EnablePipe dd ?
|
||||||
|
; This procedure reinserts the given pipe to hardware queue
|
||||||
|
; after DisablePipe, with clearing transfer queue.
|
||||||
|
; esi -> usb_controller, ebx -> usb_pipe
|
||||||
|
; edx -> current descriptor, eax -> new last descriptor
|
||||||
ends
|
ends
|
||||||
|
|
||||||
; pointers to kernel API functions that are called from *HCI-drivers
|
; pointers to kernel API functions that are called from *HCI-drivers
|
||||||
@ -307,6 +319,8 @@ NextVirt dd ?
|
|||||||
PrevVirt dd ?
|
PrevVirt dd ?
|
||||||
; Previous endpoint in the processing list.
|
; Previous endpoint in the processing list.
|
||||||
; See also NextVirt field and the description before NextVirt field.
|
; See also NextVirt field and the description before NextVirt field.
|
||||||
|
BaseList dd ?
|
||||||
|
; Pointer to head of the processing list.
|
||||||
;
|
;
|
||||||
; Every pipe has the associated transfer queue, that is, the double-linked
|
; Every pipe has the associated transfer queue, that is, the double-linked
|
||||||
; list of Transfer Descriptors aka TD. For Control, Bulk and Interrupt
|
; list of Transfer Descriptors aka TD. For Control, Bulk and Interrupt
|
||||||
@ -427,6 +441,8 @@ DeviceDescrSize db ?
|
|||||||
; Size of device descriptor.
|
; Size of device descriptor.
|
||||||
Speed db ?
|
Speed db ?
|
||||||
; Device speed, one of USB_SPEED_*.
|
; Device speed, one of USB_SPEED_*.
|
||||||
|
Timer dd ?
|
||||||
|
; Handle of timer that handles request timeout.
|
||||||
NumInterfaces dd ?
|
NumInterfaces dd ?
|
||||||
; Number of interfaces.
|
; Number of interfaces.
|
||||||
ConfigDataSize dd ?
|
ConfigDataSize dd ?
|
||||||
|
@ -114,7 +114,7 @@ proc get_phys_addr
|
|||||||
ret
|
ret
|
||||||
endp
|
endp
|
||||||
|
|
||||||
; Put the given control pipe in the wait list;
|
; Put the given control/bulk pipe in the wait list;
|
||||||
; called when the pipe structure is changed and a possible hardware cache
|
; called when the pipe structure is changed and a possible hardware cache
|
||||||
; needs to be synchronized. When it will be known that the cache is updated,
|
; needs to be synchronized. When it will be known that the cache is updated,
|
||||||
; usb_subscription_done procedure will be called.
|
; usb_subscription_done procedure will be called.
|
||||||
@ -128,6 +128,17 @@ proc usb_subscribe_control
|
|||||||
ret
|
ret
|
||||||
endp
|
endp
|
||||||
|
|
||||||
|
; Same as usb_subscribe_control, but for interrupt/isochronous pipe.
|
||||||
|
proc usb_subscribe_periodic
|
||||||
|
cmp [ebx+usb_pipe.NextWait], -1
|
||||||
|
jnz @f
|
||||||
|
mov eax, [esi+usb_controller.WaitPipeListPeriodic]
|
||||||
|
mov [ebx+usb_pipe.NextWait], eax
|
||||||
|
mov [esi+usb_controller.WaitPipeListPeriodic], ebx
|
||||||
|
@@:
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
; Called after synchronization of hardware cache with software changes.
|
; Called after synchronization of hardware cache with software changes.
|
||||||
; Continues process of device enumeration based on when it was delayed
|
; Continues process of device enumeration based on when it was delayed
|
||||||
; due to call to usb_subscribe_control.
|
; due to call to usb_subscribe_control.
|
||||||
@ -254,13 +265,18 @@ proc usb_process_one_wait_list
|
|||||||
mov [esi+usb_controller.WaitPipeListAsync+edx], ebx
|
mov [esi+usb_controller.WaitPipeListAsync+edx], ebx
|
||||||
jmp .continue
|
jmp .continue
|
||||||
.process:
|
.process:
|
||||||
; 7. Call the handler depending on USB_FLAG_CLOSED.
|
; 7. Call the handler depending on USB_FLAG_CLOSED and USB_FLAG_DISABLED.
|
||||||
or [ebx+usb_pipe.NextWait], -1
|
or [ebx+usb_pipe.NextWait], -1
|
||||||
test [ebx+usb_pipe.Flags], USB_FLAG_CLOSED
|
test [ebx+usb_pipe.Flags], USB_FLAG_CLOSED
|
||||||
jz .nodisconnect
|
jz .nodisconnect
|
||||||
call usb_pipe_closed
|
call usb_pipe_closed
|
||||||
jmp .continue
|
jmp .continue
|
||||||
.nodisconnect:
|
.nodisconnect:
|
||||||
|
test [ebx+usb_pipe.Flags], USB_FLAG_DISABLED
|
||||||
|
jz .nodisabled
|
||||||
|
call usb_pipe_disabled
|
||||||
|
jmp .continue
|
||||||
|
.nodisabled:
|
||||||
call usb_subscription_done
|
call usb_subscription_done
|
||||||
.continue:
|
.continue:
|
||||||
; 8. Restore edx and next pipe saved in step 5 and continue the loop.
|
; 8. Restore edx and next pipe saved in step 5 and continue the loop.
|
||||||
|
@ -13,6 +13,11 @@ else
|
|||||||
stdcall arg
|
stdcall arg
|
||||||
end if
|
end if
|
||||||
}
|
}
|
||||||
|
if USB_STDCALL_VERIFY
|
||||||
|
STDCALL_VERIFY_EXTRA = 20h
|
||||||
|
else
|
||||||
|
STDCALL_VERIFY_EXTRA = 0
|
||||||
|
end if
|
||||||
|
|
||||||
; Initialization of usb_static_ep structure,
|
; Initialization of usb_static_ep structure,
|
||||||
; called from controller-specific initialization; edi -> usb_static_ep
|
; called from controller-specific initialization; edi -> usb_static_ep
|
||||||
@ -238,8 +243,17 @@ proc usb_close_pipe_nolock
|
|||||||
call mutex_lock
|
call mutex_lock
|
||||||
push ecx
|
push ecx
|
||||||
; 3b. Let the controller-specific code do its job.
|
; 3b. Let the controller-specific code do its job.
|
||||||
|
test [ebx+usb_pipe.Flags], USB_FLAG_DISABLED
|
||||||
|
jnz @f
|
||||||
|
mov eax, [esi+usb_controller.HardwareFunc]
|
||||||
|
call [eax+usb_hardware_func.DisablePipe]
|
||||||
|
@@:
|
||||||
mov eax, [esi+usb_controller.HardwareFunc]
|
mov eax, [esi+usb_controller.HardwareFunc]
|
||||||
call [eax+usb_hardware_func.UnlinkPipe]
|
call [eax+usb_hardware_func.UnlinkPipe]
|
||||||
|
mov edx, [ebx+usb_pipe.NextVirt]
|
||||||
|
mov eax, [ebx+usb_pipe.PrevVirt]
|
||||||
|
mov [edx+usb_pipe.PrevVirt], eax
|
||||||
|
mov [eax+usb_pipe.NextVirt], edx
|
||||||
; 3c. Release the corresponding lock.
|
; 3c. Release the corresponding lock.
|
||||||
pop ecx
|
pop ecx
|
||||||
call mutex_unlock
|
call mutex_unlock
|
||||||
@ -262,36 +276,66 @@ proc usb_close_pipe_nolock
|
|||||||
ret
|
ret
|
||||||
endp
|
endp
|
||||||
|
|
||||||
|
; This procedure is called when all transfers are aborted
|
||||||
|
; either due to call to usb_abort_pipe or due to pipe closing.
|
||||||
|
; It notifies all callbacks and frees all transfer descriptors.
|
||||||
|
; ebx -> usb_pipe, esi -> usb_controller, edi -> usb_hardware_func
|
||||||
|
; three stack parameters: status code for callback functions
|
||||||
|
; and descriptors where to start and stop.
|
||||||
|
proc usb_pipe_aborted
|
||||||
|
virtual at esp
|
||||||
|
dd ? ; return address
|
||||||
|
.status dd ? ; USB_STATUS_CLOSED or USB_STATUS_CANCELLED
|
||||||
|
.first_td dd ?
|
||||||
|
.last_td dd ?
|
||||||
|
end virtual
|
||||||
|
; Loop over all transfers, calling the driver with the given status
|
||||||
|
; and freeing all descriptors except the last one.
|
||||||
|
.loop:
|
||||||
|
mov edx, [.first_td]
|
||||||
|
cmp edx, [.last_td]
|
||||||
|
jz .done
|
||||||
|
mov ecx, [edx+usb_gtd.Callback]
|
||||||
|
test ecx, ecx
|
||||||
|
jz .no_callback
|
||||||
|
stdcall_verify ecx, ebx, [.status+12+STDCALL_VERIFY_EXTRA], \
|
||||||
|
[edx+usb_gtd.Buffer], 0, [edx+usb_gtd.UserData]
|
||||||
|
mov edx, [.first_td]
|
||||||
|
.no_callback:
|
||||||
|
mov eax, [edx+usb_gtd.NextVirt]
|
||||||
|
mov [.first_td], eax
|
||||||
|
stdcall [edi+usb_hardware_func.FreeTD], edx
|
||||||
|
jmp .loop
|
||||||
|
.done:
|
||||||
|
ret 12
|
||||||
|
endp
|
||||||
|
|
||||||
; This procedure is called when a pipe with USB_FLAG_CLOSED is removed from the
|
; This procedure is called when a pipe with USB_FLAG_CLOSED is removed from the
|
||||||
; corresponding wait list. It means that the hardware has fully forgot about it.
|
; corresponding wait list. It means that the hardware has fully forgot about it.
|
||||||
; ebx -> usb_pipe, esi -> usb_controller
|
; ebx -> usb_pipe, esi -> usb_controller
|
||||||
proc usb_pipe_closed
|
proc usb_pipe_closed
|
||||||
push edi
|
push edi
|
||||||
mov edi, [esi+usb_controller.HardwareFunc]
|
mov edi, [esi+usb_controller.HardwareFunc]
|
||||||
; 1. Loop over all transfers, calling the driver with USB_STATUS_CLOSED
|
; 1. Notify all registered callbacks with status USB_STATUS_CLOSED, if any,
|
||||||
; and freeing all descriptors.
|
; and free all transfer descriptors, including the last one.
|
||||||
|
lea ecx, [ebx+usb_pipe.Lock]
|
||||||
|
call mutex_lock
|
||||||
mov edx, [ebx+usb_pipe.LastTD]
|
mov edx, [ebx+usb_pipe.LastTD]
|
||||||
test edx, edx
|
test edx, edx
|
||||||
jz .no_transfer
|
jz .no_transfer
|
||||||
mov edx, [edx+usb_gtd.NextVirt]
|
mov eax, [edx+usb_gtd.NextVirt]
|
||||||
.transfer_loop:
|
|
||||||
cmp edx, [ebx+usb_pipe.LastTD]
|
|
||||||
jz .transfer_done
|
|
||||||
mov ecx, [edx+usb_gtd.Callback]
|
|
||||||
test ecx, ecx
|
|
||||||
jz .no_callback
|
|
||||||
push edx
|
push edx
|
||||||
stdcall_verify ecx, ebx, USB_STATUS_CLOSED, \
|
push eax
|
||||||
[edx+usb_gtd.Buffer], 0, [edx+usb_gtd.UserData]
|
call mutex_unlock
|
||||||
pop edx
|
push USB_STATUS_CLOSED
|
||||||
.no_callback:
|
call usb_pipe_aborted
|
||||||
push [edx+usb_gtd.NextVirt]
|
; It is safe to free LastTD here:
|
||||||
stdcall [edi+usb_hardware_func.FreeTD], edx
|
; usb_*_transfer_async do not enqueue new transfers if USB_FLAG_CLOSED is set.
|
||||||
pop edx
|
stdcall [edi+usb_hardware_func.FreeTD], [ebx+usb_pipe.LastTD]
|
||||||
jmp .transfer_loop
|
jmp @f
|
||||||
.transfer_done:
|
|
||||||
stdcall [edi+usb_hardware_func.FreeTD], edx
|
|
||||||
.no_transfer:
|
.no_transfer:
|
||||||
|
call mutex_unlock
|
||||||
|
@@:
|
||||||
; 2. Decrement number of pipes for the device.
|
; 2. Decrement number of pipes for the device.
|
||||||
; If this pipe is the last pipe, go to 5.
|
; If this pipe is the last pipe, go to 5.
|
||||||
mov ecx, [ebx+usb_pipe.DeviceData]
|
mov ecx, [ebx+usb_pipe.DeviceData]
|
||||||
@ -342,14 +386,23 @@ proc usb_pipe_closed
|
|||||||
dec eax
|
dec eax
|
||||||
jnz .notify_loop
|
jnz .notify_loop
|
||||||
.notify_done:
|
.notify_done:
|
||||||
; 6. Bus address, if assigned, can now be reused.
|
; 6. Kill the timer, if active.
|
||||||
|
; (Usually not; possible if device is disconnected
|
||||||
|
; while processing SET_ADDRESS request).
|
||||||
|
mov eax, [ebx+usb_pipe.DeviceData]
|
||||||
|
cmp [eax+usb_device_data.Timer], 0
|
||||||
|
jz @f
|
||||||
|
stdcall cancel_timer_hs, [eax+usb_device_data.Timer]
|
||||||
|
mov [eax+usb_device_data.Timer], 0
|
||||||
|
@@:
|
||||||
|
; 7. Bus address, if assigned, can now be reused.
|
||||||
call [edi+usb_hardware_func.GetDeviceAddress]
|
call [edi+usb_hardware_func.GetDeviceAddress]
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz @f
|
jz @f
|
||||||
bts [esi+usb_controller.ExistingAddresses], eax
|
bts [esi+usb_controller.ExistingAddresses], eax
|
||||||
@@:
|
@@:
|
||||||
dbgstr 'USB device disconnected'
|
dbgstr 'USB device disconnected'
|
||||||
; 7. All drivers have returned from disconnect callback,
|
; 8. All drivers have returned from disconnect callback,
|
||||||
; so all drivers should not use any device-related pipes.
|
; so all drivers should not use any device-related pipes.
|
||||||
; Free the remaining pipes.
|
; Free the remaining pipes.
|
||||||
mov eax, [ebx+usb_pipe.DeviceData]
|
mov eax, [ebx+usb_pipe.DeviceData]
|
||||||
@ -366,15 +419,74 @@ proc usb_pipe_closed
|
|||||||
.free_done:
|
.free_done:
|
||||||
stdcall [edi+usb_hardware_func.FreePipe], ebx
|
stdcall [edi+usb_hardware_func.FreePipe], ebx
|
||||||
pop eax
|
pop eax
|
||||||
; 8. Free the usb_device_data structure.
|
; 9. Free the usb_device_data structure.
|
||||||
sub eax, usb_device_data.ClosedPipeList - usb_pipe.NextSibling
|
sub eax, usb_device_data.ClosedPipeList - usb_pipe.NextSibling
|
||||||
call free
|
call free
|
||||||
; 9. Return.
|
; 10. Return.
|
||||||
.nothing:
|
.nothing:
|
||||||
pop edi
|
pop edi
|
||||||
ret
|
ret
|
||||||
endp
|
endp
|
||||||
|
|
||||||
|
; This procedure is called when a pipe with USB_FLAG_DISABLED is removed from the
|
||||||
|
; corresponding wait list. It means that the hardware has fully forgot about it.
|
||||||
|
; ebx -> usb_pipe, esi -> usb_controller
|
||||||
|
proc usb_pipe_disabled
|
||||||
|
push edi
|
||||||
|
mov edi, [esi+usb_controller.HardwareFunc]
|
||||||
|
; 1. Acquire pipe lock.
|
||||||
|
lea ecx, [ebx+usb_pipe.Lock]
|
||||||
|
call mutex_lock
|
||||||
|
; 2. Clear USB_FLAG_DISABLED in pipe state.
|
||||||
|
and [ebx+usb_pipe.Flags], not USB_FLAG_DISABLED
|
||||||
|
; 3. Sanity check: ignore uninitialized pipes.
|
||||||
|
cmp [ebx+usb_pipe.LastTD], 0
|
||||||
|
jz .no_transfer
|
||||||
|
; 4. Acquire the first and last to-be-cancelled transfer descriptor,
|
||||||
|
; save them in stack for the step 6,
|
||||||
|
; ask the controller driver to enable the pipe for hardware,
|
||||||
|
; removing transfers between first and last to-be-cancelled descriptors.
|
||||||
|
lea ecx, [esi+usb_controller.ControlLock]
|
||||||
|
cmp [ebx+usb_pipe.Type], BULK_PIPE
|
||||||
|
jb @f ; control pipe
|
||||||
|
lea ecx, [esi+usb_controller.BulkLock]
|
||||||
|
jz @f ; bulk pipe
|
||||||
|
lea ecx, [esi+usb_controller.PeriodicLock]
|
||||||
|
@@:
|
||||||
|
call mutex_lock
|
||||||
|
mov eax, [ebx+usb_pipe.BaseList]
|
||||||
|
mov edx, [eax+usb_pipe.NextVirt]
|
||||||
|
mov [ebx+usb_pipe.NextVirt], edx
|
||||||
|
mov [ebx+usb_pipe.PrevVirt], eax
|
||||||
|
mov [edx+usb_pipe.PrevVirt], ebx
|
||||||
|
mov [eax+usb_pipe.NextVirt], ebx
|
||||||
|
mov eax, [ebx+usb_pipe.LastTD]
|
||||||
|
mov edx, [eax+usb_gtd.NextVirt]
|
||||||
|
mov [eax+usb_gtd.NextVirt], eax
|
||||||
|
mov [eax+usb_gtd.PrevVirt], eax
|
||||||
|
push eax
|
||||||
|
push edx
|
||||||
|
push ecx
|
||||||
|
call [edi+usb_hardware_func.EnablePipe]
|
||||||
|
pop ecx
|
||||||
|
call mutex_unlock
|
||||||
|
; 5. Release pipe lock acquired at step 1.
|
||||||
|
; Callbacks called at step 6 can insert new transfers,
|
||||||
|
; so we cannot call usb_pipe_aborted while holding pipe lock.
|
||||||
|
lea ecx, [ebx+usb_pipe.Lock]
|
||||||
|
call mutex_unlock
|
||||||
|
; 6. Notify all registered callbacks with status USB_STATUS_CANCELLED, if any.
|
||||||
|
; Two arguments describing transfers range were pushed at step 4.
|
||||||
|
push USB_STATUS_CANCELLED
|
||||||
|
call usb_pipe_aborted
|
||||||
|
pop edi
|
||||||
|
ret
|
||||||
|
.no_transfer:
|
||||||
|
call mutex_unlock
|
||||||
|
pop edi
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
; Part of API for drivers, see documentation for USBNormalTransferAsync.
|
; Part of API for drivers, see documentation for USBNormalTransferAsync.
|
||||||
proc usb_normal_transfer_async stdcall uses ebx edi,\
|
proc usb_normal_transfer_async stdcall uses ebx edi,\
|
||||||
pipe:dword, buffer:dword, size:dword, callback:dword, calldata:dword, flags:dword
|
pipe:dword, buffer:dword, size:dword, callback:dword, calldata:dword, flags:dword
|
||||||
@ -508,6 +620,69 @@ endl
|
|||||||
ret
|
ret
|
||||||
endp
|
endp
|
||||||
|
|
||||||
|
; Part of API for drivers, see documentation for USBAbortPipe.
|
||||||
|
proc usb_abort_pipe
|
||||||
|
push ebx esi ; save used registers to be stdcall
|
||||||
|
virtual at esp
|
||||||
|
rd 2 ; saved registers
|
||||||
|
dd ? ; return address
|
||||||
|
.pipe dd ?
|
||||||
|
end virtual
|
||||||
|
mov ebx, [.pipe]
|
||||||
|
; 1. Acquire pipe lock.
|
||||||
|
lea ecx, [ebx+usb_pipe.Lock]
|
||||||
|
call mutex_lock
|
||||||
|
; 2. If the pipe is already closed or abort is in progress,
|
||||||
|
; just release pipe lock and return.
|
||||||
|
test [ebx+usb_pipe.Flags], USB_FLAG_CLOSED + USB_FLAG_DISABLED
|
||||||
|
jnz .nothing
|
||||||
|
; 3. Mark the pipe as aborting.
|
||||||
|
or [ebx+usb_pipe.Flags], USB_FLAG_DISABLED
|
||||||
|
; 4. We cannot do anything except adding new transfers concurrently with hardware.
|
||||||
|
; Ask the controller driver to (temporarily) remove the pipe from hardware queue.
|
||||||
|
mov esi, [ebx+usb_pipe.Controller]
|
||||||
|
; 4a. Acquire queue lock.
|
||||||
|
lea ecx, [esi+usb_controller.ControlLock]
|
||||||
|
cmp [ebx+usb_pipe.Type], BULK_PIPE
|
||||||
|
jb @f ; control pipe
|
||||||
|
lea ecx, [esi+usb_controller.BulkLock]
|
||||||
|
jz @f ; bulk pipe
|
||||||
|
lea ecx, [esi+usb_controller.PeriodicLock]
|
||||||
|
@@:
|
||||||
|
call mutex_lock
|
||||||
|
push ecx
|
||||||
|
; 4b. Call the driver.
|
||||||
|
mov eax, [esi+usb_controller.HardwareFunc]
|
||||||
|
call [eax+usb_hardware_func.DisablePipe]
|
||||||
|
; 4c. Remove the pipe from software list.
|
||||||
|
mov eax, [ebx+usb_pipe.NextVirt]
|
||||||
|
mov edx, [ebx+usb_pipe.PrevVirt]
|
||||||
|
mov [eax+usb_pipe.PrevVirt], edx
|
||||||
|
mov [edx+usb_pipe.NextVirt], eax
|
||||||
|
; 4c. Register the pipe in corresponding wait list.
|
||||||
|
test [ebx+usb_pipe.Type], 1
|
||||||
|
jz .control_bulk
|
||||||
|
call usb_subscribe_periodic
|
||||||
|
jmp @f
|
||||||
|
.control_bulk:
|
||||||
|
call usb_subscribe_control
|
||||||
|
@@:
|
||||||
|
; 4d. Release queue lock.
|
||||||
|
pop ecx
|
||||||
|
call mutex_unlock
|
||||||
|
; 4e. Notify the USB thread about new work.
|
||||||
|
push ebx esi edi
|
||||||
|
call usb_wakeup
|
||||||
|
pop edi esi ebx
|
||||||
|
; That's all for now. To be continued in usb_pipe_disabled.
|
||||||
|
; 5. Release pipe lock acquired at step 1 and return.
|
||||||
|
.nothing:
|
||||||
|
lea ecx, [ebx+usb_pipe.Lock]
|
||||||
|
call mutex_unlock
|
||||||
|
pop esi ebx
|
||||||
|
ret 4
|
||||||
|
endp
|
||||||
|
|
||||||
; Part of API for drivers, see documentation for USBGetParam.
|
; Part of API for drivers, see documentation for USBGetParam.
|
||||||
proc usb_get_param
|
proc usb_get_param
|
||||||
virtual at esp
|
virtual at esp
|
||||||
|
@ -33,6 +33,19 @@ USB_INTERFACE_POWER_DESCR = 8
|
|||||||
; read to the debug board.
|
; read to the debug board.
|
||||||
USB_DUMP_DESCRIPTORS = 1
|
USB_DUMP_DESCRIPTORS = 1
|
||||||
|
|
||||||
|
; According to the USB specification (9.2.6.3),
|
||||||
|
; any device must response to SET_ADDRESS in 50 ms, or 5 timer ticks.
|
||||||
|
; Of course, our world is far from ideal.
|
||||||
|
; I have seen devices that just NAK everything when being reset from working
|
||||||
|
; state, but start to work after second reset.
|
||||||
|
; Our strategy is as follows: give 2 seconds for the first attempt,
|
||||||
|
; this should be enough for normal devices and not too long to detect buggy ones.
|
||||||
|
; If the device continues NAKing, reset it and retry several times,
|
||||||
|
; doubling the interval: 2s -> 4s -> 8s -> 16s. Give up after that.
|
||||||
|
; Numbers are quite arbitrary.
|
||||||
|
TIMEOUT_SET_ADDRESS_INITIAL = 200
|
||||||
|
TIMEOUT_SET_ADDRESS_LAST = 1600
|
||||||
|
|
||||||
; =============================================================================
|
; =============================================================================
|
||||||
; ================================ Structures =================================
|
; ================================ Structures =================================
|
||||||
; =============================================================================
|
; =============================================================================
|
||||||
@ -179,21 +192,36 @@ ends
|
|||||||
; out: eax = 0 <=> failed, the caller should disable the port.
|
; out: eax = 0 <=> failed, the caller should disable the port.
|
||||||
proc usb_new_device
|
proc usb_new_device
|
||||||
push ebx edi ; save used registers to be stdcall
|
push ebx edi ; save used registers to be stdcall
|
||||||
; 1. Allocate resources. Any device uses the following resources:
|
; 1. Check whether we're here because we were trying to reset
|
||||||
|
; already-registered device in hope to fix something serious.
|
||||||
|
; If so, skip allocation and go to 6.
|
||||||
|
movzx eax, [esi+usb_controller.ResettingPort]
|
||||||
|
mov edx, [esi+usb_controller.ResettingHub]
|
||||||
|
test edx, edx
|
||||||
|
jz .test_roothub
|
||||||
|
mov edx, [edx+usb_hub.ConnectedDevicesPtr]
|
||||||
|
mov ebx, [edx+eax*4]
|
||||||
|
jmp @f
|
||||||
|
.test_roothub:
|
||||||
|
mov ebx, [esi+usb_controller.DevicesByPort+eax*4]
|
||||||
|
@@:
|
||||||
|
test ebx, ebx
|
||||||
|
jnz .try_set_address
|
||||||
|
; 2. Allocate resources. Any device uses the following resources:
|
||||||
; - device address in the bus
|
; - device address in the bus
|
||||||
; - memory for device data
|
; - memory for device data
|
||||||
; - pipe for zero endpoint
|
; - pipe for zero endpoint
|
||||||
; If some allocation fails, we must undo our actions. Closing the pipe
|
; If some allocation fails, we must undo our actions. Closing the pipe
|
||||||
; is a hard task, so we avoid it and open the pipe as the last resource.
|
; is a hard task, so we avoid it and open the pipe as the last resource.
|
||||||
; The order for other two allocations is quite arbitrary.
|
; The order for other two allocations is quite arbitrary.
|
||||||
; 1a. Allocate a bus address.
|
; 2a. Allocate a bus address.
|
||||||
push ecx
|
push ecx
|
||||||
call usb_set_address_request
|
call usb_set_address_request
|
||||||
pop ecx
|
pop ecx
|
||||||
; 1b. If failed, just return zero.
|
; 2b. If failed, just return zero.
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .nothing
|
jz .nothing
|
||||||
; 1c. Allocate memory for device data.
|
; 2c. Allocate memory for device data.
|
||||||
; For now, we need sizeof.usb_device_data and extra 8 bytes for GET_DESCRIPTOR
|
; For now, we need sizeof.usb_device_data and extra 8 bytes for GET_DESCRIPTOR
|
||||||
; input and output, see usb_after_set_address. Later we will reallocate it
|
; input and output, see usb_after_set_address. Later we will reallocate it
|
||||||
; to actual size needed for descriptors.
|
; to actual size needed for descriptors.
|
||||||
@ -201,10 +229,10 @@ proc usb_new_device
|
|||||||
push ecx
|
push ecx
|
||||||
call malloc
|
call malloc
|
||||||
pop ecx
|
pop ecx
|
||||||
; 1d. If failed, free the bus address and return zero.
|
; 2d. If failed, free the bus address and return zero.
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .nomemory
|
jz .nomemory
|
||||||
; 1e. Open pipe for endpoint zero.
|
; 2e. Open pipe for endpoint zero.
|
||||||
; For now, we do not know the actual maximum packet size;
|
; For now, we do not know the actual maximum packet size;
|
||||||
; for full-speed devices it can be any of 8, 16, 32, 64 bytes,
|
; for full-speed devices it can be any of 8, 16, 32, 64 bytes,
|
||||||
; low-speed devices must have 8 bytes, high-speed devices must have 64 bytes.
|
; low-speed devices must have 8 bytes, high-speed devices must have 64 bytes.
|
||||||
@ -227,12 +255,14 @@ proc usb_new_device
|
|||||||
; Put pointer to pipe into ebx. "xchg eax,reg" is one byte, mov is two bytes.
|
; Put pointer to pipe into ebx. "xchg eax,reg" is one byte, mov is two bytes.
|
||||||
xchg eax, ebx
|
xchg eax, ebx
|
||||||
pop eax
|
pop eax
|
||||||
; 1f. If failed, free the memory, the bus address and return zero.
|
; 2f. If failed, free the memory, the bus address and return zero.
|
||||||
test ebx, ebx
|
test ebx, ebx
|
||||||
jz .freememory
|
jz .freememory
|
||||||
; 2. Store pointer to device data in the pipe structure.
|
; 3. Store pointer to device data in the pipe structure.
|
||||||
mov [ebx+usb_pipe.DeviceData], eax
|
mov [ebx+usb_pipe.DeviceData], eax
|
||||||
; 3. Init device data, using usb_controller.Resetting* variables.
|
; 4. Init device data, using usb_controller.Resetting* variables.
|
||||||
|
mov [eax+usb_device_data.Timer], edi
|
||||||
|
mov dword [eax+usb_device_data.DeviceDescriptor], TIMEOUT_SET_ADDRESS_INITIAL
|
||||||
mov [eax+usb_device_data.TTHub], edi
|
mov [eax+usb_device_data.TTHub], edi
|
||||||
mov [eax+usb_device_data.TTPort], 0
|
mov [eax+usb_device_data.TTPort], 0
|
||||||
mov [eax+usb_device_data.NumInterfaces], edi
|
mov [eax+usb_device_data.NumInterfaces], edi
|
||||||
@ -268,7 +298,7 @@ proc usb_new_device
|
|||||||
mov [eax+usb_device_data.Port], cl
|
mov [eax+usb_device_data.Port], cl
|
||||||
mov edx, [esi+usb_controller.ResettingHub]
|
mov edx, [esi+usb_controller.ResettingHub]
|
||||||
mov [eax+usb_device_data.Hub], edx
|
mov [eax+usb_device_data.Hub], edx
|
||||||
; 4. Store pointer to the config pipe in the hub data.
|
; 5. Store pointer to the config pipe in the hub data.
|
||||||
; Config pipe serves as device identifier.
|
; Config pipe serves as device identifier.
|
||||||
; Root hubs use the array inside usb_controller structure,
|
; Root hubs use the array inside usb_controller structure,
|
||||||
; non-root hubs use the array immediately after usb_hub structure.
|
; non-root hubs use the array immediately after usb_hub structure.
|
||||||
@ -281,16 +311,29 @@ proc usb_new_device
|
|||||||
mov [esi+usb_controller.DevicesByPort+ecx*4], ebx
|
mov [esi+usb_controller.DevicesByPort+ecx*4], ebx
|
||||||
@@:
|
@@:
|
||||||
call usb_reinit_pipe_list
|
call usb_reinit_pipe_list
|
||||||
; 5. Issue SET_ADDRESS control request, using buffer filled in step 1a.
|
; 6. Issue SET_ADDRESS control request, using buffer filled in step 2a.
|
||||||
; Use the return value from usb_control_async as our return value;
|
; 6a. Configure timer to force reset after timeout.
|
||||||
; if it is zero, then something has failed.
|
; Note: we can't use self-destructing timer, because we need to be able to cancel it,
|
||||||
|
; and for self-destructing timer we could have race condition in cancelling/destructing.
|
||||||
|
; DEBUGF 1,'K : pipe %x\n',ebx
|
||||||
|
.try_set_address:
|
||||||
|
xor edi, edi
|
||||||
|
mov edx, [ebx+usb_pipe.DeviceData]
|
||||||
|
stdcall timer_hs, [edx+usb_device_data.DeviceDescriptor], 7FFFFFFFh, usb_abort_pipe, ebx
|
||||||
|
test eax, eax
|
||||||
|
jz .nothing
|
||||||
|
mov edx, [ebx+usb_pipe.DeviceData]
|
||||||
|
mov [edx+usb_device_data.Timer], eax
|
||||||
|
; 6b. If it succeeded, setup timer to configure wait timeout.
|
||||||
lea eax, [esi+usb_controller.SetAddressBuffer]
|
lea eax, [esi+usb_controller.SetAddressBuffer]
|
||||||
stdcall usb_control_async, ebx, eax, edi, edi, usb_set_address_callback, edi, edi
|
stdcall usb_control_async, ebx, eax, edi, edi, usb_set_address_callback, edi, edi
|
||||||
|
; Use the return value from usb_control_async as our return value;
|
||||||
|
; if it is zero, then something has failed.
|
||||||
.nothing:
|
.nothing:
|
||||||
; 6. Return.
|
; 7. Return.
|
||||||
pop edi ebx ; restore used registers to be stdcall
|
pop edi ebx ; restore used registers to be stdcall
|
||||||
ret
|
ret
|
||||||
; Handlers of failures in steps 1b, 1d, 1f.
|
; Handlers of failures in steps 2b, 2d, 2f.
|
||||||
.freememory:
|
.freememory:
|
||||||
call free
|
call free
|
||||||
jmp .freeaddr
|
jmp .freeaddr
|
||||||
@ -349,16 +392,23 @@ endp
|
|||||||
; Note that USB stack uses esi = pointer to usb_controller.
|
; Note that USB stack uses esi = pointer to usb_controller.
|
||||||
proc usb_set_address_callback stdcall, pipe:dword, status:dword, buffer:dword, length:dword, calldata:dword
|
proc usb_set_address_callback stdcall, pipe:dword, status:dword, buffer:dword, length:dword, calldata:dword
|
||||||
push ebx ; save ebx to be stdcall
|
push ebx ; save ebx to be stdcall
|
||||||
; Load data to registers for further references.
|
|
||||||
mov ebx, [pipe]
|
mov ebx, [pipe]
|
||||||
|
; 1. In any case, cancel the timer.
|
||||||
|
mov eax, [ebx+usb_pipe.DeviceData]
|
||||||
|
stdcall cancel_timer_hs, [eax+usb_device_data.Timer]
|
||||||
|
mov eax, [ebx+usb_pipe.DeviceData]
|
||||||
|
mov [eax+usb_device_data.Timer], 0
|
||||||
|
; Load data to registers for further references.
|
||||||
mov ecx, dword [esi+usb_controller.SetAddressBuffer+2]
|
mov ecx, dword [esi+usb_controller.SetAddressBuffer+2]
|
||||||
mov eax, [esi+usb_controller.HardwareFunc]
|
mov eax, [esi+usb_controller.HardwareFunc]
|
||||||
; 1. Check whether the device has accepted new address. If so, proceed to 2.
|
; 2. Check whether the device has accepted new address. If so, proceed to 3.
|
||||||
; Otherwise, go to 3.
|
; Otherwise, go to 4 if killed by usb_set_address_timeout or to 5 otherwise.
|
||||||
|
cmp [status], USB_STATUS_CANCELLED
|
||||||
|
jz .timeout
|
||||||
cmp [status], 0
|
cmp [status], 0
|
||||||
jnz .error
|
jnz .error
|
||||||
; 2. Address accepted.
|
; 3. Address accepted.
|
||||||
; 2a. The controller-specific structure for the control pipe still uses
|
; 3a. The controller-specific structure for the control pipe still uses
|
||||||
; zero address. Call the controller-specific function to change it to
|
; zero address. Call the controller-specific function to change it to
|
||||||
; the actual address.
|
; the actual address.
|
||||||
; Note that the hardware could cache the controller-specific structure,
|
; Note that the hardware could cache the controller-specific structure,
|
||||||
@ -367,25 +417,49 @@ proc usb_set_address_callback stdcall, pipe:dword, status:dword, buffer:dword, l
|
|||||||
; be safe to continue.
|
; be safe to continue.
|
||||||
; dbgstr 'address set in device'
|
; dbgstr 'address set in device'
|
||||||
call [eax+usb_hardware_func.SetDeviceAddress]
|
call [eax+usb_hardware_func.SetDeviceAddress]
|
||||||
; 2b. If the port is in non-root hub, clear 'reset in progress' flag.
|
; 3b. If the port is in non-root hub, clear 'reset in progress' flag.
|
||||||
; In any case, proceed to 4.
|
; In any case, proceed to 6.
|
||||||
mov eax, [esi+usb_controller.ResettingHub]
|
mov eax, [esi+usb_controller.ResettingHub]
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .return
|
jz .return
|
||||||
and [eax+usb_hub.Actions], not HUB_RESET_IN_PROGRESS
|
and [eax+usb_hub.Actions], not HUB_RESET_IN_PROGRESS
|
||||||
.return:
|
.return:
|
||||||
; 4. Address configuration done, we can proceed with other ports.
|
; 6. Address configuration done, we can proceed with other ports.
|
||||||
; Call the worker function for that.
|
; Call the worker function for that.
|
||||||
call usb_test_pending_port
|
call usb_test_pending_port
|
||||||
|
.wakeup:
|
||||||
|
push esi edi
|
||||||
|
call usb_wakeup
|
||||||
|
pop edi esi
|
||||||
.nothing:
|
.nothing:
|
||||||
pop ebx ; restore ebx to be stdcall
|
pop ebx ; restore ebx to be stdcall
|
||||||
ret
|
ret
|
||||||
|
.timeout:
|
||||||
|
; 4. Device continues to NAK the request. Reset it and retry.
|
||||||
|
mov edx, [ebx+usb_pipe.DeviceData]
|
||||||
|
mov ecx, [edx+usb_device_data.DeviceDescriptor]
|
||||||
|
add ecx, ecx
|
||||||
|
cmp ecx, TIMEOUT_SET_ADDRESS_LAST
|
||||||
|
ja .error
|
||||||
|
mov [edx+usb_device_data.DeviceDescriptor], ecx
|
||||||
|
dbgstr 'Timeout in USB device initialization, trying to reset...'
|
||||||
|
cmp [esi+usb_controller.ResettingHub], 0
|
||||||
|
jz .reset_roothub
|
||||||
|
push esi
|
||||||
|
mov esi, [esi+usb_controller.ResettingHub]
|
||||||
|
call usb_hub_initiate_reset
|
||||||
|
pop esi
|
||||||
|
jmp .nothing
|
||||||
|
.reset_roothub:
|
||||||
|
movzx ecx, [esi+usb_controller.ResettingPort]
|
||||||
|
call [eax+usb_hardware_func.InitiateReset]
|
||||||
|
jmp .wakeup
|
||||||
.error:
|
.error:
|
||||||
; 3. Device error: device not responding, disconnect etc.
|
; 5. Device error: device not responding, disconnect etc.
|
||||||
DEBUGF 1,'K : error %d in SET_ADDRESS, USB device disabled\n',[status]
|
DEBUGF 1,'K : error %d in SET_ADDRESS, USB device disabled\n',[status]
|
||||||
; 3a. The address has not been accepted. Mark it as free.
|
; 5a. The address has not been accepted. Mark it as free.
|
||||||
bts dword [esi+usb_controller.ExistingAddresses], ecx
|
bts dword [esi+usb_controller.ExistingAddresses], ecx
|
||||||
; 3b. Disable the port with bad device.
|
; 5b. Disable the port with bad device.
|
||||||
; For the root hub, call the controller-specific function and go to 6.
|
; For the root hub, call the controller-specific function and go to 6.
|
||||||
; For non-root hubs, let the hub code do its work and return (the request
|
; For non-root hubs, let the hub code do its work and return (the request
|
||||||
; could take some time, the hub code is responsible for proceeding).
|
; could take some time, the hub code is responsible for proceeding).
|
||||||
|
@ -121,6 +121,8 @@ __exports:
|
|||||||
NET_ptr_to_num, 'NetPtrToNum', \
|
NET_ptr_to_num, 'NetPtrToNum', \
|
||||||
NET_link_changed, 'NetLinkChanged', \
|
NET_link_changed, 'NetLinkChanged', \
|
||||||
ETH_input, 'Eth_input', \
|
ETH_input, 'Eth_input', \
|
||||||
|
\
|
||||||
|
get_pcidev_list, 'GetPCIList', \
|
||||||
\
|
\
|
||||||
0, 'LFBAddress' ; must be the last one
|
0, 'LFBAddress' ; must be the last one
|
||||||
load kernel_exports_count dword from __exports + 24
|
load kernel_exports_count dword from __exports + 24
|
||||||
|
@ -232,12 +232,24 @@ commit_pages:
|
|||||||
mov edi, ebx
|
mov edi, ebx
|
||||||
shr edi, 12
|
shr edi, 12
|
||||||
lea edi, [page_tabs+edi*4]
|
lea edi, [page_tabs+edi*4]
|
||||||
|
|
||||||
|
if USE_FIX_FOR_INVALID_MS_VIRTUAL_PC_2007
|
||||||
|
mov edx, eax
|
||||||
|
@@:
|
||||||
|
mov eax, edx
|
||||||
|
stosd
|
||||||
|
invlpg [ebx]
|
||||||
|
add edx, 0x1000
|
||||||
|
add ebx, 0x1000
|
||||||
|
loop @B
|
||||||
|
else
|
||||||
@@:
|
@@:
|
||||||
stosd
|
stosd
|
||||||
invlpg [ebx]
|
invlpg [ebx]
|
||||||
add eax, 0x1000
|
add eax, 0x1000
|
||||||
add ebx, 0x1000
|
add ebx, 0x1000
|
||||||
loop @B
|
loop @B
|
||||||
|
end if
|
||||||
|
|
||||||
pop edi
|
pop edi
|
||||||
|
|
||||||
|
@ -465,8 +465,6 @@ cdid rd 1
|
|||||||
hdbase rd 1 ; for boot 0x1f0
|
hdbase rd 1 ; for boot 0x1f0
|
||||||
hdid rd 1
|
hdid rd 1
|
||||||
hdpos rd 1 ; for boot 0x1
|
hdpos rd 1 ; for boot 0x1
|
||||||
label known_part dword
|
|
||||||
fat32part rd 1 ; for boot 0x1
|
|
||||||
cdpos rd 1
|
cdpos rd 1
|
||||||
|
|
||||||
;CPUID information
|
;CPUID information
|
||||||
|
@ -817,12 +817,8 @@ drawwindow_I: ;////////////////////////////////////////////////////////////////
|
|||||||
jnz .exit
|
jnz .exit
|
||||||
|
|
||||||
; does client area have a positive size on screen?
|
; does client area have a positive size on screen?
|
||||||
mov edx, [esi + WDATA.box.top]
|
cmp [esi + WDATA.box.height], 21
|
||||||
add edx, 21 + 5
|
jle .exit
|
||||||
mov ebx, [esi + WDATA.box.top]
|
|
||||||
add ebx, [esi + WDATA.box.height]
|
|
||||||
cmp edx, ebx
|
|
||||||
jg .exit
|
|
||||||
|
|
||||||
; okay, let's draw it
|
; okay, let's draw it
|
||||||
mov eax, 1
|
mov eax, 1
|
||||||
|
@ -482,9 +482,12 @@ align 4
|
|||||||
proc set_mouse_data stdcall, BtnState:dword, XMoving:dword, YMoving:dword, VScroll:dword, HScroll:dword
|
proc set_mouse_data stdcall, BtnState:dword, XMoving:dword, YMoving:dword, VScroll:dword, HScroll:dword
|
||||||
|
|
||||||
mov eax, [BtnState]
|
mov eax, [BtnState]
|
||||||
|
and eax, 0x3FFFFFFF ; Top 2 bits are used to flag absolute movements
|
||||||
mov [BTN_DOWN], eax
|
mov [BTN_DOWN], eax
|
||||||
|
|
||||||
mov eax, [XMoving]
|
mov eax, [XMoving]
|
||||||
|
test [BtnState], 0x80000000
|
||||||
|
jnz @@M1
|
||||||
call mouse_acceleration
|
call mouse_acceleration
|
||||||
add ax, [MOUSE_X];[XCoordinate]
|
add ax, [MOUSE_X];[XCoordinate]
|
||||||
cmp ax, 0
|
cmp ax, 0
|
||||||
@ -503,6 +506,8 @@ align 4
|
|||||||
mov [MOUSE_X], ax;[XCoordinate]
|
mov [MOUSE_X], ax;[XCoordinate]
|
||||||
|
|
||||||
mov eax, [YMoving]
|
mov eax, [YMoving]
|
||||||
|
test [BtnState], 0x40000000
|
||||||
|
jnz @@M3
|
||||||
neg eax
|
neg eax
|
||||||
call mouse_acceleration
|
call mouse_acceleration
|
||||||
|
|
||||||
|
@ -766,7 +766,29 @@ no_mode_0x12:
|
|||||||
call unmask_timer
|
call unmask_timer
|
||||||
stdcall enable_irq, 2 ; @#$%! PIC
|
stdcall enable_irq, 2 ; @#$%! PIC
|
||||||
stdcall enable_irq, 13 ; co-processor
|
stdcall enable_irq, 13 ; co-processor
|
||||||
|
;-----------------------------------------------------------------------------
|
||||||
|
; show SVN version of kernel on the message board
|
||||||
|
;-----------------------------------------------------------------------------
|
||||||
|
mov eax, [version_inf.rev]
|
||||||
|
DEBUGF 1, "K : kernel SVN r%d\n", eax
|
||||||
|
;-----------------------------------------------------------------------------
|
||||||
|
; show CPU count on the message board
|
||||||
|
;-----------------------------------------------------------------------------
|
||||||
|
mov eax, [cpu_count]
|
||||||
|
test eax, eax
|
||||||
|
jnz @F
|
||||||
|
mov al, 1 ; at least one CPU
|
||||||
|
@@:
|
||||||
|
DEBUGF 1, "K : %d CPU detected\n", eax
|
||||||
|
;-----------------------------------------------------------------------------
|
||||||
|
; detect Floppy drives
|
||||||
|
;-----------------------------------------------------------------------------
|
||||||
|
mov esi, boot_detectfloppy
|
||||||
|
call boot_log
|
||||||
|
include 'detect/dev_fd.inc'
|
||||||
|
;-----------------------------------------------------------------------------
|
||||||
|
; START of initialisation IDE ATA code
|
||||||
|
;-----------------------------------------------------------------------------
|
||||||
cmp [IDEContrProgrammingInterface], 0
|
cmp [IDEContrProgrammingInterface], 0
|
||||||
je @f
|
je @f
|
||||||
|
|
||||||
@ -786,14 +808,15 @@ no_mode_0x12:
|
|||||||
add dx, 2 ;0x376
|
add dx, 2 ;0x376
|
||||||
out dx, al
|
out dx, al
|
||||||
@@:
|
@@:
|
||||||
|
; show base variables of IDE controller
|
||||||
|
DEBUGF 1, "K : BAR0 %x \n", [IDE_BAR0_val]:4
|
||||||
|
DEBUGF 1, "K : BAR1 %x \n", [IDE_BAR1_val]:4
|
||||||
|
DEBUGF 1, "K : BAR2 %x \n", [IDE_BAR2_val]:4
|
||||||
|
DEBUGF 1, "K : BAR3 %x \n", [IDE_BAR3_val]:4
|
||||||
|
DEBUGF 1, "K : BAR4 %x \n", [IDEContrRegsBaseAddr]:4
|
||||||
|
DEBUGF 1, "K : IDEContrProgrammingInterface %x \n", [IDEContrProgrammingInterface]:4
|
||||||
|
DEBUGF 1, "K : IDE_Interrupt %x \n", [IDE_Interrupt]:4
|
||||||
;-----------------------------------------------------------------------------
|
;-----------------------------------------------------------------------------
|
||||||
;!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
||||||
; mov esi, boot_detectdisks
|
|
||||||
; call boot_log
|
|
||||||
;include 'detect/disks.inc'
|
|
||||||
mov esi, boot_detectfloppy
|
|
||||||
call boot_log
|
|
||||||
include 'detect/dev_fd.inc'
|
|
||||||
mov esi, boot_detecthdcd
|
mov esi, boot_detecthdcd
|
||||||
call boot_log
|
call boot_log
|
||||||
include 'detect/dev_hdcd.inc'
|
include 'detect/dev_hdcd.inc'
|
||||||
@ -803,8 +826,132 @@ include 'detect/getcache.inc'
|
|||||||
mov esi, boot_detectpart
|
mov esi, boot_detectpart
|
||||||
call boot_log
|
call boot_log
|
||||||
include 'detect/sear_par.inc'
|
include 'detect/sear_par.inc'
|
||||||
;!!!!!!!!!!!!!!!!!!!!!!!!!!
|
;-----------------------------------------------------------------------------
|
||||||
|
mov dx, [IDEContrRegsBaseAddr]
|
||||||
|
; test whether it is our interrupt?
|
||||||
|
add dx, 2
|
||||||
|
in al, dx
|
||||||
|
test al, 100b
|
||||||
|
jz @f
|
||||||
|
; clear Bus Master IDE Status register
|
||||||
|
; clear Interrupt bit
|
||||||
|
out dx, al
|
||||||
|
@@:
|
||||||
|
add dx, 8
|
||||||
|
; test whether it is our interrupt?
|
||||||
|
in al, dx
|
||||||
|
test al, 100b
|
||||||
|
jz @f
|
||||||
|
; clear Bus Master IDE Status register
|
||||||
|
; clear Interrupt bit
|
||||||
|
out dx, al
|
||||||
|
@@:
|
||||||
|
; read status register and remove the interrupt request
|
||||||
|
mov dx, [IDE_BAR0_val] ;0x1F0
|
||||||
|
add dx, 0x7 ;0x1F7
|
||||||
|
in al, dx
|
||||||
|
mov dx, [IDE_BAR2_val] ;0x170
|
||||||
|
add dx, 0x7 ;0x177
|
||||||
|
in al, dx
|
||||||
|
;-----------------------------------------------------------------------------
|
||||||
|
push eax edx
|
||||||
|
mov dx, [IDEContrRegsBaseAddr]
|
||||||
|
xor eax, eax
|
||||||
|
add dx, 2
|
||||||
|
in al, dx
|
||||||
|
DEBUGF 1, "K : Primary Bus Master IDE Status Register %x\n", eax
|
||||||
|
|
||||||
|
add dx, 8
|
||||||
|
in al, dx
|
||||||
|
DEBUGF 1, "K : Secondary Bus Master IDE Status Register %x\n", eax
|
||||||
|
pop edx eax
|
||||||
|
|
||||||
|
cmp [IDEContrRegsBaseAddr], 0
|
||||||
|
setnz [dma_hdd]
|
||||||
|
|
||||||
|
cmp [IDEContrProgrammingInterface], 0
|
||||||
|
je set_interrupts_for_IDE_controllers.continue
|
||||||
|
;-----------------------------------------------------------------------------
|
||||||
|
; set interrupts for IDE Controller
|
||||||
|
;-----------------------------------------------------------------------------
|
||||||
|
mov esi, boot_set_int_IDE
|
||||||
|
call boot_log
|
||||||
|
set_interrupts_for_IDE_controllers:
|
||||||
|
mov ax, [IDEContrProgrammingInterface]
|
||||||
|
cmp ax, 0x0180
|
||||||
|
je .pata_ide
|
||||||
|
|
||||||
|
cmp ax, 0x018a
|
||||||
|
jne .sata_ide
|
||||||
|
;--------------------------------------
|
||||||
|
.pata_ide:
|
||||||
|
cmp [IDEContrRegsBaseAddr], 0
|
||||||
|
je .end_set_interrupts
|
||||||
|
|
||||||
|
stdcall attach_int_handler, 14, IDE_irq_14_handler, 0
|
||||||
|
DEBUGF 1, "K : Set IDE IRQ14 return code %x\n", eax
|
||||||
|
stdcall attach_int_handler, 15, IDE_irq_15_handler, 0
|
||||||
|
DEBUGF 1, "K : Set IDE IRQ15 return code %x\n", eax
|
||||||
|
jmp .enable_IDE_interrupt
|
||||||
|
;--------------------------------------
|
||||||
|
.sata_ide:
|
||||||
|
cmp ax, 0x0185
|
||||||
|
je .sata_ide_1
|
||||||
|
|
||||||
|
cmp ax, 0x018f
|
||||||
|
jne .end_set_interrupts
|
||||||
|
;--------------------------------------
|
||||||
|
.sata_ide_1:
|
||||||
|
cmp [IDEContrRegsBaseAddr], 0
|
||||||
|
je .end_set_interrupts
|
||||||
|
|
||||||
|
mov ax, [IDE_Interrupt]
|
||||||
|
movzx eax, al
|
||||||
|
stdcall attach_int_handler, eax, IDE_common_irq_handler, 0
|
||||||
|
DEBUGF 1, "K : Set IDE IRQ%d return code %x\n", [IDE_Interrupt]:1, eax
|
||||||
|
;--------------------------------------
|
||||||
|
.enable_IDE_interrupt:
|
||||||
|
mov esi, boot_enabling_ide
|
||||||
|
call boot_log
|
||||||
|
; Enable interrupts in IDE controller for DMA
|
||||||
|
mov al, 0
|
||||||
|
mov ah, [DRIVE_DATA+1]
|
||||||
|
test ah, 10100000b
|
||||||
|
jz @f
|
||||||
|
|
||||||
|
DEBUGF 1, "K : IDE CH1 PIO, because ATAPI drive present\n"
|
||||||
|
jmp .ch2_check
|
||||||
|
@@:
|
||||||
|
mov dx, [IDE_BAR1_val] ;0x3F4
|
||||||
|
add dx, 2 ;0x3F6
|
||||||
|
out dx, al
|
||||||
|
DEBUGF 1, "K : IDE CH1 DMA enabled\n"
|
||||||
|
.ch2_check:
|
||||||
|
test ah, 1010b
|
||||||
|
jz @f
|
||||||
|
|
||||||
|
DEBUGF 1, "K : IDE CH2 PIO, because ATAPI drive present\n"
|
||||||
|
jmp .end_set_interrupts
|
||||||
|
@@:
|
||||||
|
mov dx, [IDE_BAR3_val] ;0x374
|
||||||
|
add dx, 2 ;0x376
|
||||||
|
out dx, al
|
||||||
|
DEBUGF 1, "K : IDE CH2 DMA enabled\n"
|
||||||
|
;--------------------------------------
|
||||||
|
.end_set_interrupts:
|
||||||
|
;-----------------------------------------------------------------------------
|
||||||
|
cmp [dma_hdd], 0
|
||||||
|
je .print_pio
|
||||||
|
.print_dma:
|
||||||
|
DEBUGF 1, "K : IDE DMA mode\n"
|
||||||
|
jmp .continue
|
||||||
|
|
||||||
|
.print_pio:
|
||||||
|
DEBUGF 1, "K : IDE PIO mode\n"
|
||||||
|
.continue:
|
||||||
|
;-----------------------------------------------------------------------------
|
||||||
|
; END of initialisation IDE ATA code
|
||||||
|
;-----------------------------------------------------------------------------
|
||||||
mov esi, boot_init_sys
|
mov esi, boot_init_sys
|
||||||
call boot_log
|
call boot_log
|
||||||
call Parser_params
|
call Parser_params
|
||||||
@ -817,7 +964,6 @@ if ~ defined extended_primary_loader
|
|||||||
include 'boot/rdload.inc'
|
include 'boot/rdload.inc'
|
||||||
;!!!!!!!!!!!!!!!!!!!!!!!
|
;!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
end if
|
end if
|
||||||
; mov [dma_hdd],1
|
|
||||||
|
|
||||||
if 0
|
if 0
|
||||||
mov ax, [OS_BASE+0x10000+bx_from_load]
|
mov ax, [OS_BASE+0x10000+bx_from_load]
|
||||||
@ -871,34 +1017,8 @@ end if
|
|||||||
|
|
||||||
mov [pci_access_enabled], 1
|
mov [pci_access_enabled], 1
|
||||||
call pci_enum
|
call pci_enum
|
||||||
;-----------------------------------------------------------------------------
|
call clear_pci_ide_interrupts
|
||||||
mov dx, [IDEContrRegsBaseAddr]
|
|
||||||
; test whether it is our interrupt?
|
|
||||||
add dx, 2
|
|
||||||
in al, dx
|
|
||||||
test al, 100b
|
|
||||||
jz @f
|
|
||||||
; clear Bus Master IDE Status register
|
|
||||||
; clear Interrupt bit
|
|
||||||
out dx, al
|
|
||||||
@@:
|
|
||||||
add dx, 8
|
|
||||||
; test whether it is our interrupt?
|
|
||||||
in al, dx
|
|
||||||
test al, 100b
|
|
||||||
jz @f
|
|
||||||
; clear Bus Master IDE Status register
|
|
||||||
; clear Interrupt bit
|
|
||||||
out dx, al
|
|
||||||
@@:
|
|
||||||
; read status register and remove the interrupt request
|
|
||||||
mov dx, [IDE_BAR0_val] ;0x1F0
|
|
||||||
add dx, 0x7 ;0x1F7
|
|
||||||
in al, dx
|
|
||||||
mov dx, [IDE_BAR2_val] ;0x170
|
|
||||||
add dx, 0x7 ;0x177
|
|
||||||
in al, dx
|
|
||||||
;-----------------------------------------------------------------------------
|
|
||||||
include "detect/vortex86.inc" ; Vortex86 SoC detection code
|
include "detect/vortex86.inc" ; Vortex86 SoC detection code
|
||||||
|
|
||||||
stdcall load_driver, szVidintel
|
stdcall load_driver, szVidintel
|
||||||
@ -1069,7 +1189,7 @@ endg
|
|||||||
DEBUGF 1, "K : IRQ1 error code %x\n", eax
|
DEBUGF 1, "K : IRQ1 error code %x\n", eax
|
||||||
.no_keyboard:
|
.no_keyboard:
|
||||||
|
|
||||||
; SET MOUSE
|
; Load PS/2 mouse driver
|
||||||
|
|
||||||
stdcall load_driver, szPS2MDriver
|
stdcall load_driver, szPS2MDriver
|
||||||
; stdcall load_driver, szCOM_MDriver
|
; stdcall load_driver, szCOM_MDriver
|
||||||
@ -1079,17 +1199,20 @@ endg
|
|||||||
call setmouse
|
call setmouse
|
||||||
|
|
||||||
; Setup serial output console (if enabled)
|
; Setup serial output console (if enabled)
|
||||||
|
|
||||||
if defined debug_com_base
|
if defined debug_com_base
|
||||||
|
|
||||||
; enable Divisor latch
|
; reserve port so nobody else will use it
|
||||||
|
xor ebx, ebx
|
||||||
|
mov ecx, debug_com_base
|
||||||
|
mov edx, debug_com_base+7
|
||||||
|
call r_f_port_area
|
||||||
|
|
||||||
|
; enable Divisor latch
|
||||||
mov dx, debug_com_base+3
|
mov dx, debug_com_base+3
|
||||||
mov al, 1 shl 7
|
mov al, 1 shl 7
|
||||||
out dx, al
|
out dx, al
|
||||||
|
|
||||||
; Set speed to 115200 baud (max speed)
|
; Set speed to 115200 baud (max speed)
|
||||||
|
|
||||||
mov dx, debug_com_base
|
mov dx, debug_com_base
|
||||||
mov al, 0x01
|
mov al, 0x01
|
||||||
out dx, al
|
out dx, al
|
||||||
@ -1099,43 +1222,21 @@ if defined debug_com_base
|
|||||||
out dx, al
|
out dx, al
|
||||||
|
|
||||||
; No parity, 8bits words, one stop bit, dlab bit back to 0
|
; No parity, 8bits words, one stop bit, dlab bit back to 0
|
||||||
|
|
||||||
mov dx, debug_com_base+3
|
mov dx, debug_com_base+3
|
||||||
mov al, 3
|
mov al, 3
|
||||||
out dx, al
|
out dx, al
|
||||||
|
|
||||||
; disable interrupts
|
; disable interrupts
|
||||||
|
|
||||||
mov dx, debug_com_base+1
|
mov dx, debug_com_base+1
|
||||||
mov al, 0
|
mov al, 0
|
||||||
out dx, al
|
out dx, al
|
||||||
|
|
||||||
; clear + enable fifo (64 bits)
|
; clear + enable fifo (64 bits)
|
||||||
|
|
||||||
mov dx, debug_com_base+2
|
mov dx, debug_com_base+2
|
||||||
mov al, 0x7 + 1 shl 5
|
mov al, 0x7 + 1 shl 5
|
||||||
out dx, al
|
out dx, al
|
||||||
|
|
||||||
|
|
||||||
end if
|
end if
|
||||||
mov eax, [version_inf.rev]
|
|
||||||
DEBUGF 1, "K : kernel SVN r%d\n", eax
|
|
||||||
|
|
||||||
mov eax, [cpu_count]
|
|
||||||
test eax, eax
|
|
||||||
jnz @F
|
|
||||||
mov al, 1 ; at least one CPU
|
|
||||||
@@:
|
|
||||||
DEBUGF 1, "K : %d CPU detected\n", eax
|
|
||||||
|
|
||||||
DEBUGF 1, "K : BAR0 %x \n", [IDE_BAR0_val]:4
|
|
||||||
DEBUGF 1, "K : BAR1 %x \n", [IDE_BAR1_val]:4
|
|
||||||
DEBUGF 1, "K : BAR2 %x \n", [IDE_BAR2_val]:4
|
|
||||||
DEBUGF 1, "K : BAR3 %x \n", [IDE_BAR3_val]:4
|
|
||||||
DEBUGF 1, "K : BAR4 %x \n", [IDEContrRegsBaseAddr]:4
|
|
||||||
DEBUGF 1, "K : IDEContrProgrammingInterface %x \n", [IDEContrProgrammingInterface]:4
|
|
||||||
DEBUGF 1, "K : IDE_Interrupt %x \n", [IDE_Interrupt]:4
|
|
||||||
|
|
||||||
; START MULTITASKING
|
; START MULTITASKING
|
||||||
|
|
||||||
; A 'All set - press ESC to start' messages if need
|
; A 'All set - press ESC to start' messages if need
|
||||||
@ -1148,102 +1249,6 @@ if preboot_blogesc
|
|||||||
jne .bll1
|
jne .bll1
|
||||||
end if
|
end if
|
||||||
|
|
||||||
push eax edx
|
|
||||||
mov dx, [IDEContrRegsBaseAddr]
|
|
||||||
xor eax, eax
|
|
||||||
add dx, 2
|
|
||||||
in al, dx
|
|
||||||
DEBUGF 1, "K : Primary Bus Master IDE Status Register %x\n", eax
|
|
||||||
|
|
||||||
add dx, 8
|
|
||||||
in al, dx
|
|
||||||
DEBUGF 1, "K : Secondary Bus Master IDE Status Register %x\n", eax
|
|
||||||
pop edx eax
|
|
||||||
|
|
||||||
cmp [IDEContrRegsBaseAddr], 0
|
|
||||||
setnz [dma_hdd]
|
|
||||||
|
|
||||||
cmp [IDEContrProgrammingInterface], 0
|
|
||||||
je set_interrupts_for_IDE_controllers.continue
|
|
||||||
;-----------------------------------------------------------------------------
|
|
||||||
; set interrupts for IDE Controller
|
|
||||||
;-----------------------------------------------------------------------------
|
|
||||||
mov esi, boot_set_int_IDE
|
|
||||||
call boot_log
|
|
||||||
set_interrupts_for_IDE_controllers:
|
|
||||||
mov ax, [IDEContrProgrammingInterface]
|
|
||||||
cmp ax, 0x0180
|
|
||||||
je .pata_ide
|
|
||||||
|
|
||||||
cmp ax, 0x018a
|
|
||||||
jne .sata_ide
|
|
||||||
;--------------------------------------
|
|
||||||
.pata_ide:
|
|
||||||
cmp [IDEContrRegsBaseAddr], 0
|
|
||||||
je .end_set_interrupts
|
|
||||||
|
|
||||||
stdcall attach_int_handler, 14, IDE_irq_14_handler, 0
|
|
||||||
DEBUGF 1, "K : Set IDE IRQ14 return code %x\n", eax
|
|
||||||
stdcall attach_int_handler, 15, IDE_irq_15_handler, 0
|
|
||||||
DEBUGF 1, "K : Set IDE IRQ15 return code %x\n", eax
|
|
||||||
jmp .enable_IDE_interrupt
|
|
||||||
;--------------------------------------
|
|
||||||
.sata_ide:
|
|
||||||
cmp ax, 0x0185
|
|
||||||
je .sata_ide_1
|
|
||||||
|
|
||||||
cmp ax, 0x018f
|
|
||||||
jne .end_set_interrupts
|
|
||||||
;--------------------------------------
|
|
||||||
.sata_ide_1:
|
|
||||||
cmp [IDEContrRegsBaseAddr], 0
|
|
||||||
je .end_set_interrupts
|
|
||||||
|
|
||||||
mov ax, [IDE_Interrupt]
|
|
||||||
movzx eax, al
|
|
||||||
stdcall attach_int_handler, eax, IDE_common_irq_handler, 0
|
|
||||||
DEBUGF 1, "K : Set IDE IRQ%d return code %x\n", [IDE_Interrupt]:1, eax
|
|
||||||
;--------------------------------------
|
|
||||||
.enable_IDE_interrupt:
|
|
||||||
mov esi, boot_enabling_ide
|
|
||||||
call boot_log
|
|
||||||
; Enable interrupts in IDE controller for DMA
|
|
||||||
mov al, 0
|
|
||||||
mov ah, [DRIVE_DATA+1]
|
|
||||||
test ah, 10100000b
|
|
||||||
jz @f
|
|
||||||
|
|
||||||
DEBUGF 1, "K : IDE CH1 PIO, because ATAPI drive present\n"
|
|
||||||
jmp .ch2_check
|
|
||||||
@@:
|
|
||||||
mov dx, [IDE_BAR1_val] ;0x3F4
|
|
||||||
add dx, 2 ;0x3F6
|
|
||||||
out dx, al
|
|
||||||
DEBUGF 1, "K : IDE CH1 DMA enabled\n"
|
|
||||||
.ch2_check:
|
|
||||||
test ah, 1010b
|
|
||||||
jz @f
|
|
||||||
|
|
||||||
DEBUGF 1, "K : IDE CH2 PIO, because ATAPI drive present\n"
|
|
||||||
jmp .end_set_interrupts
|
|
||||||
@@:
|
|
||||||
mov dx, [IDE_BAR3_val] ;0x374
|
|
||||||
add dx, 2 ;0x376
|
|
||||||
out dx, al
|
|
||||||
DEBUGF 1, "K : IDE CH2 DMA enabled\n"
|
|
||||||
;--------------------------------------
|
|
||||||
.end_set_interrupts:
|
|
||||||
;-----------------------------------------------------------------------------
|
|
||||||
cmp [dma_hdd], 0
|
|
||||||
je .print_pio
|
|
||||||
.print_dma:
|
|
||||||
DEBUGF 1, "K : IDE DMA mode\n"
|
|
||||||
jmp .continue
|
|
||||||
|
|
||||||
.print_pio:
|
|
||||||
DEBUGF 1, "K : IDE PIO mode\n"
|
|
||||||
.continue:
|
|
||||||
|
|
||||||
mov [timer_ticks_enable], 1 ; for cd driver
|
mov [timer_ticks_enable], 1 ; for cd driver
|
||||||
|
|
||||||
sti
|
sti
|
||||||
@ -1946,22 +1951,8 @@ ngsyse3:
|
|||||||
mov [esp+32], eax
|
mov [esp+32], eax
|
||||||
ret
|
ret
|
||||||
ngsyse5:
|
ngsyse5:
|
||||||
; cmp eax,7
|
|
||||||
sub ebx, 2
|
|
||||||
jnz ngsyse7
|
|
||||||
xor eax, eax
|
|
||||||
mov [esp+32], eax
|
|
||||||
ret
|
|
||||||
ngsyse7:
|
|
||||||
; cmp eax,8
|
|
||||||
dec ebx
|
|
||||||
jnz ngsyse8
|
|
||||||
mov eax, [fat32part]
|
|
||||||
mov [esp+32], eax
|
|
||||||
ret
|
|
||||||
ngsyse8:
|
|
||||||
; cmp eax,9
|
; cmp eax,9
|
||||||
dec ebx
|
sub ebx, 4
|
||||||
jnz ngsyse9
|
jnz ngsyse9
|
||||||
mov eax, [timer_ticks];[0xfdf0]
|
mov eax, [timer_ticks];[0xfdf0]
|
||||||
mov [esp+32], eax
|
mov [esp+32], eax
|
||||||
@ -2216,9 +2207,6 @@ restore_default_cursor_before_killing:
|
|||||||
|
|
||||||
movzx eax, word [MOUSE_Y]
|
movzx eax, word [MOUSE_Y]
|
||||||
movzx ebx, word [MOUSE_X]
|
movzx ebx, word [MOUSE_X]
|
||||||
; mov ecx, [Screen_Max_X]
|
|
||||||
; inc ecx
|
|
||||||
; mul ecx
|
|
||||||
mov eax, [d_width_calc_area + eax*4]
|
mov eax, [d_width_calc_area + eax*4]
|
||||||
|
|
||||||
add eax, [_WinMapAddress]
|
add eax, [_WinMapAddress]
|
||||||
|
@ -1 +0,0 @@
|
|||||||
lang fix ru
|
|
@ -86,11 +86,7 @@ ETH_input:
|
|||||||
push ebx
|
push ebx
|
||||||
mov esi, esp
|
mov esi, esp
|
||||||
|
|
||||||
pushf
|
|
||||||
cli
|
|
||||||
add_to_queue ETH_queue, ETH_QUEUE_SIZE, sizeof.ETH_queue_entry, .fail
|
add_to_queue ETH_queue, ETH_QUEUE_SIZE, sizeof.ETH_queue_entry, .fail
|
||||||
popf
|
|
||||||
|
|
||||||
add esp, sizeof.ETH_queue_entry
|
add esp, sizeof.ETH_queue_entry
|
||||||
|
|
||||||
xor edx, edx
|
xor edx, edx
|
||||||
@ -102,10 +98,9 @@ ETH_input:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
.fail:
|
.fail:
|
||||||
popf
|
DEBUGF DEBUG_NETWORK_ERROR, "ETH incoming queue is full, discarding packet!\n"
|
||||||
DEBUGF DEBUG_NETWORK_VERBOSE, "ETH incoming queue is full, discarding packet!\n"
|
|
||||||
|
|
||||||
add esp, sizeof.ETH_queue_entry - 8
|
pop ebx
|
||||||
call NET_packet_free
|
call NET_packet_free
|
||||||
add esp, 4
|
add esp, 4
|
||||||
|
|
||||||
|
@ -28,7 +28,6 @@ struct queue
|
|||||||
size dd ? ; number of queued packets in this queue
|
size dd ? ; number of queued packets in this queue
|
||||||
w_ptr dd ? ; current writing pointer in queue
|
w_ptr dd ? ; current writing pointer in queue
|
||||||
r_ptr dd ? ; current reading pointer
|
r_ptr dd ? ; current reading pointer
|
||||||
mutex MUTEX
|
|
||||||
|
|
||||||
ends
|
ends
|
||||||
|
|
||||||
@ -47,18 +46,12 @@ macro add_to_queue ptr, size, entry_size, failaddr {
|
|||||||
|
|
||||||
local .ok, .no_wrap
|
local .ok, .no_wrap
|
||||||
|
|
||||||
pusha
|
spin_lock_irqsave
|
||||||
lea ecx, [ptr + queue.mutex]
|
|
||||||
call mutex_lock
|
|
||||||
popa
|
|
||||||
|
|
||||||
cmp [ptr + queue.size], size ; Check if queue isnt full
|
cmp [ptr + queue.size], size ; Check if queue isnt full
|
||||||
jb .ok
|
jb .ok
|
||||||
|
|
||||||
pusha
|
spin_unlock_irqrestore
|
||||||
lea ecx, [ptr + queue.mutex]
|
|
||||||
call mutex_unlock
|
|
||||||
popa
|
|
||||||
jmp failaddr
|
jmp failaddr
|
||||||
|
|
||||||
.ok:
|
.ok:
|
||||||
@ -76,10 +69,7 @@ local .ok, .no_wrap
|
|||||||
.no_wrap:
|
.no_wrap:
|
||||||
mov [ptr + queue.w_ptr], edi
|
mov [ptr + queue.w_ptr], edi
|
||||||
|
|
||||||
pusha
|
spin_unlock_irqrestore
|
||||||
lea ecx, [ptr + queue.mutex]
|
|
||||||
call mutex_unlock
|
|
||||||
popa
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,18 +79,12 @@ macro get_from_queue ptr, size, entry_size, failaddr {
|
|||||||
|
|
||||||
local .ok, .no_wrap
|
local .ok, .no_wrap
|
||||||
|
|
||||||
pusha
|
spin_lock_irqsave
|
||||||
lea ecx, [ptr + queue.mutex]
|
|
||||||
call mutex_lock
|
|
||||||
popa
|
|
||||||
|
|
||||||
cmp [ptr + queue.size], 0 ; any packets queued?
|
cmp [ptr + queue.size], 0 ; any packets queued?
|
||||||
ja .ok
|
ja .ok
|
||||||
|
|
||||||
pusha
|
spin_unlock_irqrestore
|
||||||
lea ecx, [ptr + queue.mutex]
|
|
||||||
call mutex_unlock
|
|
||||||
popa
|
|
||||||
jmp failaddr
|
jmp failaddr
|
||||||
|
|
||||||
.ok:
|
.ok:
|
||||||
@ -122,10 +106,7 @@ local .ok, .no_wrap
|
|||||||
|
|
||||||
pop esi
|
pop esi
|
||||||
|
|
||||||
pusha
|
spin_unlock_irqrestore
|
||||||
lea ecx, [ptr + queue.mutex]
|
|
||||||
call mutex_unlock
|
|
||||||
popa
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,6 +117,4 @@ macro init_queue ptr {
|
|||||||
mov [ptr + queue.w_ptr], edi
|
mov [ptr + queue.w_ptr], edi
|
||||||
mov [ptr + queue.r_ptr], edi
|
mov [ptr + queue.r_ptr], edi
|
||||||
|
|
||||||
lea ecx, [ptr + queue.mutex]
|
|
||||||
call mutex_init
|
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; ;;
|
;; ;;
|
||||||
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
|
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
|
||||||
;; Distributed under terms of the GNU General Public License ;;
|
;; Distributed under terms of the GNU General Public License ;;
|
||||||
;; ;;
|
;; ;;
|
||||||
;; Part of the TCP/IP network stack for KolibriOS ;;
|
;; Part of the TCP/IP network stack for KolibriOS ;;
|
||||||
@ -293,6 +293,7 @@ SOCKET_open:
|
|||||||
push ecx edx esi
|
push ecx edx esi
|
||||||
call SOCKET_alloc
|
call SOCKET_alloc
|
||||||
pop esi edx ecx
|
pop esi edx ecx
|
||||||
|
test eax, eax
|
||||||
jz .nobuffs
|
jz .nobuffs
|
||||||
|
|
||||||
mov [esp+32], edi ; return socketnumber
|
mov [esp+32], edi ; return socketnumber
|
||||||
@ -697,7 +698,7 @@ SOCKET_close:
|
|||||||
|
|
||||||
test [eax + SOCKET.state], SS_BLOCKED ; Is the socket still in blocked state?
|
test [eax + SOCKET.state], SS_BLOCKED ; Is the socket still in blocked state?
|
||||||
jz @f
|
jz @f
|
||||||
call SOCKET_notify.unblock ; Unblock it.
|
call SOCKET_notify ; Unblock it.
|
||||||
@@:
|
@@:
|
||||||
|
|
||||||
cmp [eax + SOCKET.Domain], AF_INET4
|
cmp [eax + SOCKET.Domain], AF_INET4
|
||||||
@ -1192,6 +1193,7 @@ SOCKET_pair:
|
|||||||
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_pair\n"
|
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_pair\n"
|
||||||
|
|
||||||
call SOCKET_alloc
|
call SOCKET_alloc
|
||||||
|
test eax, eax
|
||||||
jz .nomem1
|
jz .nomem1
|
||||||
mov [esp+32], edi ; application's eax
|
mov [esp+32], edi ; application's eax
|
||||||
|
|
||||||
@ -1204,6 +1206,7 @@ SOCKET_pair:
|
|||||||
mov ebx, eax
|
mov ebx, eax
|
||||||
|
|
||||||
call SOCKET_alloc
|
call SOCKET_alloc
|
||||||
|
test eax, eax
|
||||||
jz .nomem2
|
jz .nomem2
|
||||||
mov [esp+20], edi ; application's ebx
|
mov [esp+20], edi ; application's ebx
|
||||||
|
|
||||||
@ -1707,8 +1710,9 @@ SOCKET_block:
|
|||||||
|
|
||||||
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: %x\n", eax
|
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: %x\n", eax
|
||||||
|
|
||||||
pushf
|
|
||||||
push eax
|
push eax
|
||||||
|
|
||||||
|
pushf
|
||||||
cli
|
cli
|
||||||
|
|
||||||
; Set the 'socket is blocked' flag
|
; Set the 'socket is blocked' flag
|
||||||
@ -1724,12 +1728,12 @@ SOCKET_block:
|
|||||||
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: suspending thread: %u\n", edx
|
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: suspending thread: %u\n", edx
|
||||||
mov [eax + SOCKET.TID], edx
|
mov [eax + SOCKET.TID], edx
|
||||||
pop edx
|
pop edx
|
||||||
|
popf
|
||||||
|
|
||||||
call change_task
|
call change_task
|
||||||
pop eax
|
pop eax
|
||||||
popf
|
|
||||||
|
|
||||||
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: continueing\n"
|
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: continuing\n"
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -1752,70 +1756,54 @@ SOCKET_notify:
|
|||||||
call SOCKET_check
|
call SOCKET_check
|
||||||
jz .error
|
jz .error
|
||||||
|
|
||||||
test [eax + SOCKET.state], SS_BLOCKED
|
; Find the associated thread's TASK_DATA
|
||||||
jnz .unblock
|
push ebx ecx esi
|
||||||
|
mov ebx, [eax + SOCKET.TID]
|
||||||
; test [eax + SOCKET.options], SO_NONBLOCK
|
test ebx, ebx
|
||||||
; jz .error
|
jz .error2
|
||||||
|
|
||||||
push eax ecx esi
|
|
||||||
|
|
||||||
; socket exists and is of non blocking type.
|
|
||||||
; We'll try to flag an event to the thread
|
|
||||||
|
|
||||||
mov eax, [eax + SOCKET.TID]
|
|
||||||
test eax, eax
|
|
||||||
jz .done
|
|
||||||
mov ecx, 1
|
|
||||||
mov esi, TASK_DATA + TASKDATA.pid
|
|
||||||
|
|
||||||
.next_pid:
|
|
||||||
cmp [esi], eax
|
|
||||||
je .found_pid
|
|
||||||
inc ecx
|
|
||||||
add esi, 0x20
|
|
||||||
cmp ecx, [TASK_COUNT]
|
|
||||||
jbe .next_pid
|
|
||||||
; PID not found, TODO: close socket!
|
|
||||||
jmp .done
|
|
||||||
|
|
||||||
.found_pid:
|
|
||||||
shl ecx, 8
|
|
||||||
or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK
|
|
||||||
|
|
||||||
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_notify: poking thread %u!\n", eax
|
|
||||||
jmp .done
|
|
||||||
|
|
||||||
.unblock:
|
|
||||||
push eax ecx esi
|
|
||||||
; Clear the 'socket is blocked' flag
|
|
||||||
and [eax + SOCKET.state], not SS_BLOCKED
|
|
||||||
|
|
||||||
; Find the thread's TASK_DATA
|
|
||||||
mov eax, [eax + SOCKET.TID]
|
|
||||||
test eax, eax
|
|
||||||
jz .error
|
|
||||||
xor ecx, ecx
|
xor ecx, ecx
|
||||||
inc ecx
|
inc ecx
|
||||||
mov esi, TASK_DATA
|
mov esi, TASK_DATA
|
||||||
.next:
|
.next:
|
||||||
cmp [esi + TASKDATA.pid], eax
|
cmp [esi + TASKDATA.pid], ebx
|
||||||
je .found
|
je .found
|
||||||
inc ecx
|
inc ecx
|
||||||
add esi, 0x20
|
add esi, 0x20
|
||||||
cmp ecx, [TASK_COUNT]
|
cmp ecx, [TASK_COUNT]
|
||||||
jbe .next
|
jbe .next
|
||||||
jmp .error
|
|
||||||
.found:
|
|
||||||
|
|
||||||
; Run the thread
|
.error2:
|
||||||
mov [esi + TASKDATA.state], 0 ; Running
|
; PID not found, TODO: close socket!
|
||||||
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_notify: Unblocked socket!\n"
|
DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_notify: error finding thread 0x%x !\n", ebx
|
||||||
|
pop esi ecx ebx
|
||||||
.done:
|
ret
|
||||||
pop esi ecx eax
|
|
||||||
|
|
||||||
.error:
|
.error:
|
||||||
|
DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_notify: invalid socket ptr: 0x%x !\n", eax
|
||||||
|
ret
|
||||||
|
|
||||||
|
.found:
|
||||||
|
test [eax + SOCKET.state], SS_BLOCKED
|
||||||
|
jnz .un_block
|
||||||
|
|
||||||
|
; socket and thread exists and socket is of non blocking type.
|
||||||
|
; We'll try to flag an event to the thread.
|
||||||
|
shl ecx, 8
|
||||||
|
or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK
|
||||||
|
|
||||||
|
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_notify: poking thread %u!\n", eax
|
||||||
|
pop esi ecx ebx
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
.un_block:
|
||||||
|
; socket and thread exists and socket is of blocking type
|
||||||
|
; We'll try to unblock it.
|
||||||
|
and [eax + SOCKET.state], not SS_BLOCKED ; Clear the 'socket is blocked' flag
|
||||||
|
mov [esi + TASKDATA.state], 0 ; Run the thread
|
||||||
|
|
||||||
|
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_notify: Unblocked socket!\n"
|
||||||
|
pop esi ecx ebx
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
@ -1830,7 +1818,6 @@ SOCKET_notify:
|
|||||||
; IN: /
|
; IN: /
|
||||||
; OUT: eax = 0 on error, socket ptr otherwise
|
; OUT: eax = 0 on error, socket ptr otherwise
|
||||||
; edi = socket number
|
; edi = socket number
|
||||||
; ZF = cleared on error
|
|
||||||
;
|
;
|
||||||
;--------------------------------------------------------------------
|
;--------------------------------------------------------------------
|
||||||
align 4
|
align 4
|
||||||
@ -1917,7 +1904,6 @@ SOCKET_alloc:
|
|||||||
@@:
|
@@:
|
||||||
|
|
||||||
mov [net_sockets + SOCKET.NextPtr], eax
|
mov [net_sockets + SOCKET.NextPtr], eax
|
||||||
or eax, eax ; used to clear zero flag
|
|
||||||
|
|
||||||
pusha
|
pusha
|
||||||
mov ecx, socket_mutex
|
mov ecx, socket_mutex
|
||||||
@ -2022,6 +2008,7 @@ SOCKET_fork:
|
|||||||
push ebx
|
push ebx
|
||||||
call SOCKET_alloc
|
call SOCKET_alloc
|
||||||
pop ebx
|
pop ebx
|
||||||
|
test eax, eax
|
||||||
jz .fail
|
jz .fail
|
||||||
|
|
||||||
push eax
|
push eax
|
||||||
@ -2101,7 +2088,8 @@ SOCKET_num_to_ptr:
|
|||||||
call mutex_unlock
|
call mutex_unlock
|
||||||
popa
|
popa
|
||||||
|
|
||||||
DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_num_to_ptr: not found\n", eax
|
DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_num_to_ptr: socket %u not found!\n", eax
|
||||||
|
DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_num_to_ptr: caller = 0x%x\n", [esp]
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
@ -43,11 +43,7 @@ TCP_input:
|
|||||||
push ebx ecx esi edi ; mind the order
|
push ebx ecx esi edi ; mind the order
|
||||||
mov esi, esp
|
mov esi, esp
|
||||||
|
|
||||||
pushf
|
|
||||||
cli
|
|
||||||
add_to_queue TCP_queue, TCP_QUEUE_SIZE, sizeof.TCP_queue_entry, .fail
|
add_to_queue TCP_queue, TCP_QUEUE_SIZE, sizeof.TCP_queue_entry, .fail
|
||||||
popf
|
|
||||||
|
|
||||||
add esp, sizeof.TCP_queue_entry
|
add esp, sizeof.TCP_queue_entry
|
||||||
|
|
||||||
call NET_ptr_to_num4
|
call NET_ptr_to_num4
|
||||||
|
@ -186,7 +186,7 @@ TCP_connect:
|
|||||||
mov eax, [esp+4]
|
mov eax, [esp+4]
|
||||||
mov [eax + SOCKET.errorcode], ETIMEDOUT
|
mov [eax + SOCKET.errorcode], ETIMEDOUT
|
||||||
and [eax + SOCKET.state], not SS_ISCONNECTING
|
and [eax + SOCKET.state], not SS_ISCONNECTING
|
||||||
call SOCKET_notify.unblock
|
call SOCKET_notify
|
||||||
ret 4
|
ret 4
|
||||||
|
|
||||||
.fail:
|
.fail:
|
||||||
|
@ -242,8 +242,6 @@ align 4
|
|||||||
add edx, eax
|
add edx, eax
|
||||||
; pointer to pixel map
|
; pointer to pixel map
|
||||||
mov eax, [putimg.abs_cy]
|
mov eax, [putimg.abs_cy]
|
||||||
; imul eax, [Screen_Max_X]
|
|
||||||
; add eax, [putimg.abs_cy]
|
|
||||||
mov eax, [d_width_calc_area + eax*4]
|
mov eax, [d_width_calc_area + eax*4]
|
||||||
|
|
||||||
add eax, [putimg.abs_cx]
|
add eax, [putimg.abs_cx]
|
||||||
@ -688,7 +686,6 @@ __sys_putpixel:
|
|||||||
; for example drawwindow_III and drawwindow_IV
|
; for example drawwindow_III and drawwindow_IV
|
||||||
; edi = 0x00000001 force
|
; edi = 0x00000001 force
|
||||||
|
|
||||||
;;; mov [novesachecksum], dword 0
|
|
||||||
pushad
|
pushad
|
||||||
cmp [Screen_Max_X], eax
|
cmp [Screen_Max_X], eax
|
||||||
jb .exit
|
jb .exit
|
||||||
@ -882,9 +879,6 @@ align 4
|
|||||||
;-----------------------------------------------------------------------------
|
;-----------------------------------------------------------------------------
|
||||||
align 4
|
align 4
|
||||||
calculate_edi:
|
calculate_edi:
|
||||||
; mov edi, ebx
|
|
||||||
; imul edi, [Screen_Max_X]
|
|
||||||
; add edi, ebx
|
|
||||||
mov edi, [d_width_calc_area + ebx*4]
|
mov edi, [d_width_calc_area + ebx*4]
|
||||||
add edi, eax
|
add edi, eax
|
||||||
ret
|
ret
|
||||||
|
Loading…
Reference in New Issue
Block a user