diff --git a/kernel/branches/kolibri-process/blkdev/disk_cache.inc b/kernel/branches/kolibri-process/blkdev/disk_cache.inc index 7cd21da002..ba1e785d76 100644 --- a/kernel/branches/kolibri-process/blkdev/disk_cache.inc +++ b/kernel/branches/kolibri-process/blkdev/disk_cache.inc @@ -258,7 +258,25 @@ end virtual call cache_lookup_write test eax, eax 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. mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY mov esi, [.current_buffer+8] @@ -268,16 +286,17 @@ end virtual mov ecx, 512/4 rep movsd mov [.current_buffer+8], esi +.sector_done: add [.sector_lo+.local_vars2_size+8], 1 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] jnz .store_to_cache .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 edi -; 12g. Release the lock. +; 12h. Release the lock. mov ecx, [ebp+PARTITION.Disk] add ecx, DISK.CacheLock call mutex_unlock @@ -651,7 +670,13 @@ end virtual call cache_lookup_write test eax, eax 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. mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY mov esi, [.current_buffer] @@ -661,13 +686,14 @@ end virtual mov ecx, 512/4 rep movsd mov [.current_buffer], esi +.sector_done: add [.sector_lo+.local_vars2_size], 1 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] jnz .store_to_cache .cache_error: -; 11e. Release the lock. +; 11f. Release the lock. mov ecx, [ebp+PARTITION.Disk] add ecx, DISK.CacheLock call mutex_unlock @@ -695,11 +721,9 @@ end virtual call cache_lookup_write test eax, eax 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 -; 15. Call the driver to read one sector. +; 14. Call the driver to read one sector. push 1 push esp push edx @@ -713,7 +737,7 @@ end virtual pop ecx dec ecx 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 ; and go to 4c. pop ecx @@ -723,7 +747,7 @@ end virtual mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY 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. .floppy_read_error: pop ecx @@ -849,6 +873,7 @@ proc cache_lookup_write mov [ebx+DISKCACHE.search_start], ecx popd [esi+CACHE_ITEM.SectorLo] popd [esi+CACHE_ITEM.SectorHi] + mov [esi+CACHE_ITEM.Status], CACHE_ITEM_EMPTY .return0: xor eax, eax ; success ret diff --git a/kernel/branches/kolibri-process/blkdev/hd_drv.inc b/kernel/branches/kolibri-process/blkdev/hd_drv.inc index 5d767735be..af5dc59d0c 100644 --- a/kernel/branches/kolibri-process/blkdev/hd_drv.inc +++ b/kernel/branches/kolibri-process/blkdev/hd_drv.inc @@ -1183,3 +1183,35 @@ IDE_BAR2_val dw ? IDE_BAR3_val dw ? 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 diff --git a/kernel/branches/kolibri-process/bus/pci/pci32.inc b/kernel/branches/kolibri-process/bus/pci/pci32.inc index b23abd6359..5596c9bf06 100644 --- a/kernel/branches/kolibri-process/bus/pci/pci32.inc +++ b/kernel/branches/kolibri-process/bus/pci/pci32.inc @@ -722,3 +722,9 @@ end virtual leave ret endp + +; Export for drivers. Just returns the pointer to the pci-devices list. +proc get_pcidev_list + mov eax, pcidev_list + ret +endp diff --git a/kernel/branches/kolibri-process/bus/usb/common.inc b/kernel/branches/kolibri-process/bus/usb/common.inc index d77e687a46..a425f6ee1f 100644 --- a/kernel/branches/kolibri-process/bus/usb/common.inc +++ b/kernel/branches/kolibri-process/bus/usb/common.inc @@ -6,7 +6,7 @@ ; ============================================================================= ; Version of all structures related to host controllers. ; 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 ; 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 ; either explicitly with USBClosePipe ; or implicitly due to device disconnect +USB_STATUS_CANCELLED = 17 ; transfer cancelled with USBAbortPipe ; Possible speeds of USB devices USB_SPEED_FS = 0 ; full-speed @@ -63,6 +64,9 @@ USB_FLAG_CAN_FREE = 2 USB_FLAG_EXTRA_WAIT = 4 ; The pipe was in wait list, while another event occured; ; 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 ; ============================================================================= @@ -136,6 +140,14 @@ NewDevice dd ? ; Initiate configuration of a new device (create pseudo-pipe describing that ; device and call usb_new_device). ; 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 ; pointers to kernel API functions that are called from *HCI-drivers @@ -307,6 +319,8 @@ NextVirt dd ? PrevVirt dd ? ; Previous endpoint in the processing list. ; 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 ; list of Transfer Descriptors aka TD. For Control, Bulk and Interrupt @@ -427,6 +441,8 @@ DeviceDescrSize db ? ; Size of device descriptor. Speed db ? ; Device speed, one of USB_SPEED_*. +Timer dd ? +; Handle of timer that handles request timeout. NumInterfaces dd ? ; Number of interfaces. ConfigDataSize dd ? diff --git a/kernel/branches/kolibri-process/bus/usb/hccommon.inc b/kernel/branches/kolibri-process/bus/usb/hccommon.inc index 4a066859a3..b017085190 100644 --- a/kernel/branches/kolibri-process/bus/usb/hccommon.inc +++ b/kernel/branches/kolibri-process/bus/usb/hccommon.inc @@ -114,7 +114,7 @@ proc get_phys_addr ret 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 ; needs to be synchronized. When it will be known that the cache is updated, ; usb_subscription_done procedure will be called. @@ -128,6 +128,17 @@ proc usb_subscribe_control ret 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. ; Continues process of device enumeration based on when it was delayed ; due to call to usb_subscribe_control. @@ -254,13 +265,18 @@ proc usb_process_one_wait_list mov [esi+usb_controller.WaitPipeListAsync+edx], ebx jmp .continue .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 test [ebx+usb_pipe.Flags], USB_FLAG_CLOSED jz .nodisconnect call usb_pipe_closed jmp .continue .nodisconnect: + test [ebx+usb_pipe.Flags], USB_FLAG_DISABLED + jz .nodisabled + call usb_pipe_disabled + jmp .continue +.nodisabled: call usb_subscription_done .continue: ; 8. Restore edx and next pipe saved in step 5 and continue the loop. diff --git a/kernel/branches/kolibri-process/bus/usb/pipe.inc b/kernel/branches/kolibri-process/bus/usb/pipe.inc index ab249d9675..1a8c7b7d20 100644 --- a/kernel/branches/kolibri-process/bus/usb/pipe.inc +++ b/kernel/branches/kolibri-process/bus/usb/pipe.inc @@ -13,6 +13,11 @@ else stdcall arg end if } +if USB_STDCALL_VERIFY +STDCALL_VERIFY_EXTRA = 20h +else +STDCALL_VERIFY_EXTRA = 0 +end if ; Initialization of usb_static_ep structure, ; called from controller-specific initialization; edi -> usb_static_ep @@ -238,8 +243,17 @@ proc usb_close_pipe_nolock call mutex_lock push ecx ; 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] 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. pop ecx call mutex_unlock @@ -262,36 +276,66 @@ proc usb_close_pipe_nolock ret 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 ; corresponding wait list. It means that the hardware has fully forgot about it. ; ebx -> usb_pipe, esi -> usb_controller proc usb_pipe_closed push edi mov edi, [esi+usb_controller.HardwareFunc] -; 1. Loop over all transfers, calling the driver with USB_STATUS_CLOSED -; and freeing all descriptors. +; 1. Notify all registered callbacks with status USB_STATUS_CLOSED, if any, +; and free all transfer descriptors, including the last one. + lea ecx, [ebx+usb_pipe.Lock] + call mutex_lock mov edx, [ebx+usb_pipe.LastTD] test edx, edx jz .no_transfer - mov edx, [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 + mov eax, [edx+usb_gtd.NextVirt] push edx - stdcall_verify ecx, ebx, USB_STATUS_CLOSED, \ - [edx+usb_gtd.Buffer], 0, [edx+usb_gtd.UserData] - pop edx -.no_callback: - push [edx+usb_gtd.NextVirt] - stdcall [edi+usb_hardware_func.FreeTD], edx - pop edx - jmp .transfer_loop -.transfer_done: - stdcall [edi+usb_hardware_func.FreeTD], edx + push eax + call mutex_unlock + push USB_STATUS_CLOSED + call usb_pipe_aborted +; It is safe to free LastTD here: +; usb_*_transfer_async do not enqueue new transfers if USB_FLAG_CLOSED is set. + stdcall [edi+usb_hardware_func.FreeTD], [ebx+usb_pipe.LastTD] + jmp @f .no_transfer: + call mutex_unlock +@@: ; 2. Decrement number of pipes for the device. ; If this pipe is the last pipe, go to 5. mov ecx, [ebx+usb_pipe.DeviceData] @@ -342,14 +386,23 @@ proc usb_pipe_closed dec eax jnz .notify_loop .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] test eax, eax jz @f bts [esi+usb_controller.ExistingAddresses], eax @@: 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. ; Free the remaining pipes. mov eax, [ebx+usb_pipe.DeviceData] @@ -366,15 +419,74 @@ proc usb_pipe_closed .free_done: stdcall [edi+usb_hardware_func.FreePipe], ebx 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 call free -; 9. Return. +; 10. Return. .nothing: pop edi ret 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. proc usb_normal_transfer_async stdcall uses ebx edi,\ pipe:dword, buffer:dword, size:dword, callback:dword, calldata:dword, flags:dword @@ -508,6 +620,69 @@ endl ret 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. proc usb_get_param virtual at esp diff --git a/kernel/branches/kolibri-process/bus/usb/protocol.inc b/kernel/branches/kolibri-process/bus/usb/protocol.inc index 6d720e380b..5240f3a211 100644 --- a/kernel/branches/kolibri-process/bus/usb/protocol.inc +++ b/kernel/branches/kolibri-process/bus/usb/protocol.inc @@ -33,6 +33,19 @@ USB_INTERFACE_POWER_DESCR = 8 ; read to the debug board. 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 ================================= ; ============================================================================= @@ -179,21 +192,36 @@ ends ; out: eax = 0 <=> failed, the caller should disable the port. proc usb_new_device 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 ; - memory for device data ; - pipe for zero endpoint ; 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. ; The order for other two allocations is quite arbitrary. -; 1a. Allocate a bus address. +; 2a. Allocate a bus address. push ecx call usb_set_address_request pop ecx -; 1b. If failed, just return zero. +; 2b. If failed, just return zero. test eax, eax 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 ; input and output, see usb_after_set_address. Later we will reallocate it ; to actual size needed for descriptors. @@ -201,10 +229,10 @@ proc usb_new_device push ecx call malloc 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 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 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. @@ -227,12 +255,14 @@ proc usb_new_device ; Put pointer to pipe into ebx. "xchg eax,reg" is one byte, mov is two bytes. xchg eax, ebx 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 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 -; 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.TTPort], 0 mov [eax+usb_device_data.NumInterfaces], edi @@ -268,7 +298,7 @@ proc usb_new_device mov [eax+usb_device_data.Port], cl mov edx, [esi+usb_controller.ResettingHub] 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. ; Root hubs use the array inside usb_controller 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 @@: call usb_reinit_pipe_list -; 5. Issue SET_ADDRESS control request, using buffer filled in step 1a. -; Use the return value from usb_control_async as our return value; -; if it is zero, then something has failed. +; 6. Issue SET_ADDRESS control request, using buffer filled in step 2a. +; 6a. Configure timer to force reset after timeout. +; 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] 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: -; 6. Return. +; 7. Return. pop edi ebx ; restore used registers to be stdcall ret -; Handlers of failures in steps 1b, 1d, 1f. +; Handlers of failures in steps 2b, 2d, 2f. .freememory: call free jmp .freeaddr @@ -349,16 +392,23 @@ endp ; 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 push ebx ; save ebx to be stdcall -; Load data to registers for further references. 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 eax, [esi+usb_controller.HardwareFunc] -; 1. Check whether the device has accepted new address. If so, proceed to 2. -; Otherwise, go to 3. +; 2. Check whether the device has accepted new address. If so, proceed 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 jnz .error -; 2. Address accepted. -; 2a. The controller-specific structure for the control pipe still uses +; 3. Address accepted. +; 3a. The controller-specific structure for the control pipe still uses ; zero address. Call the controller-specific function to change it to ; the actual address. ; 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. ; dbgstr 'address set in device' call [eax+usb_hardware_func.SetDeviceAddress] -; 2b. If the port is in non-root hub, clear 'reset in progress' flag. -; In any case, proceed to 4. +; 3b. If the port is in non-root hub, clear 'reset in progress' flag. +; In any case, proceed to 6. mov eax, [esi+usb_controller.ResettingHub] test eax, eax jz .return and [eax+usb_hub.Actions], not HUB_RESET_IN_PROGRESS .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 usb_test_pending_port +.wakeup: + push esi edi + call usb_wakeup + pop edi esi .nothing: pop ebx ; restore ebx to be stdcall 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: -; 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] -; 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 -; 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 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). diff --git a/kernel/branches/kolibri-process/core/exports.inc b/kernel/branches/kolibri-process/core/exports.inc index 2d80a3368c..0eb8cd3131 100644 --- a/kernel/branches/kolibri-process/core/exports.inc +++ b/kernel/branches/kolibri-process/core/exports.inc @@ -121,6 +121,8 @@ __exports: NET_ptr_to_num, 'NetPtrToNum', \ NET_link_changed, 'NetLinkChanged', \ ETH_input, 'Eth_input', \ +\ + get_pcidev_list, 'GetPCIList', \ \ 0, 'LFBAddress' ; must be the last one load kernel_exports_count dword from __exports + 24 diff --git a/kernel/branches/kolibri-process/core/memory.inc b/kernel/branches/kolibri-process/core/memory.inc index 78ce295873..0982d845c0 100644 --- a/kernel/branches/kolibri-process/core/memory.inc +++ b/kernel/branches/kolibri-process/core/memory.inc @@ -232,12 +232,24 @@ commit_pages: mov edi, ebx shr edi, 12 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 invlpg [ebx] add eax, 0x1000 add ebx, 0x1000 loop @B +end if pop edi diff --git a/kernel/branches/kolibri-process/data32.inc b/kernel/branches/kolibri-process/data32.inc index c9bf656103..b0f735293a 100644 --- a/kernel/branches/kolibri-process/data32.inc +++ b/kernel/branches/kolibri-process/data32.inc @@ -465,8 +465,6 @@ cdid rd 1 hdbase rd 1 ; for boot 0x1f0 hdid rd 1 hdpos rd 1 ; for boot 0x1 -label known_part dword -fat32part rd 1 ; for boot 0x1 cdpos rd 1 ;CPUID information diff --git a/kernel/branches/kolibri-process/gui/window.inc b/kernel/branches/kolibri-process/gui/window.inc index 7f2594f789..3e6aebd13e 100644 --- a/kernel/branches/kolibri-process/gui/window.inc +++ b/kernel/branches/kolibri-process/gui/window.inc @@ -817,12 +817,8 @@ drawwindow_I: ;//////////////////////////////////////////////////////////////// jnz .exit ; does client area have a positive size on screen? - mov edx, [esi + WDATA.box.top] - add edx, 21 + 5 - mov ebx, [esi + WDATA.box.top] - add ebx, [esi + WDATA.box.height] - cmp edx, ebx - jg .exit + cmp [esi + WDATA.box.height], 21 + jle .exit ; okay, let's draw it mov eax, 1 diff --git a/kernel/branches/kolibri-process/hid/mousedrv.inc b/kernel/branches/kolibri-process/hid/mousedrv.inc index 9dbabe70b4..6ec760bf04 100644 --- a/kernel/branches/kolibri-process/hid/mousedrv.inc +++ b/kernel/branches/kolibri-process/hid/mousedrv.inc @@ -482,9 +482,12 @@ align 4 proc set_mouse_data stdcall, BtnState:dword, XMoving:dword, YMoving:dword, VScroll:dword, HScroll:dword mov eax, [BtnState] + and eax, 0x3FFFFFFF ; Top 2 bits are used to flag absolute movements mov [BTN_DOWN], eax mov eax, [XMoving] + test [BtnState], 0x80000000 + jnz @@M1 call mouse_acceleration add ax, [MOUSE_X];[XCoordinate] cmp ax, 0 @@ -503,6 +506,8 @@ align 4 mov [MOUSE_X], ax;[XCoordinate] mov eax, [YMoving] + test [BtnState], 0x40000000 + jnz @@M3 neg eax call mouse_acceleration diff --git a/kernel/branches/kolibri-process/kernel.asm b/kernel/branches/kolibri-process/kernel.asm index 2e0f2fd302..5da7c39691 100644 --- a/kernel/branches/kolibri-process/kernel.asm +++ b/kernel/branches/kolibri-process/kernel.asm @@ -766,7 +766,29 @@ no_mode_0x12: call unmask_timer stdcall enable_irq, 2 ; @#$%! PIC 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 je @f @@ -786,14 +808,15 @@ no_mode_0x12: add dx, 2 ;0x376 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 call boot_log include 'detect/dev_hdcd.inc' @@ -803,8 +826,132 @@ include 'detect/getcache.inc' mov esi, boot_detectpart call boot_log 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 call boot_log call Parser_params @@ -817,7 +964,6 @@ if ~ defined extended_primary_loader include 'boot/rdload.inc' ;!!!!!!!!!!!!!!!!!!!!!!! end if -; mov [dma_hdd],1 if 0 mov ax, [OS_BASE+0x10000+bx_from_load] @@ -871,34 +1017,8 @@ end if mov [pci_access_enabled], 1 call pci_enum -;----------------------------------------------------------------------------- - 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 -;----------------------------------------------------------------------------- + call clear_pci_ide_interrupts + include "detect/vortex86.inc" ; Vortex86 SoC detection code stdcall load_driver, szVidintel @@ -1069,7 +1189,7 @@ endg DEBUGF 1, "K : IRQ1 error code %x\n", eax .no_keyboard: -; SET MOUSE +; Load PS/2 mouse driver stdcall load_driver, szPS2MDriver ; stdcall load_driver, szCOM_MDriver @@ -1079,17 +1199,20 @@ endg call setmouse ; Setup serial output console (if enabled) - 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 al, 1 shl 7 out dx, al ; Set speed to 115200 baud (max speed) - mov dx, debug_com_base mov al, 0x01 out dx, al @@ -1099,43 +1222,21 @@ if defined debug_com_base out dx, al ; No parity, 8bits words, one stop bit, dlab bit back to 0 - mov dx, debug_com_base+3 mov al, 3 out dx, al ; disable interrupts - mov dx, debug_com_base+1 mov al, 0 out dx, al ; clear + enable fifo (64 bits) - mov dx, debug_com_base+2 mov al, 0x7 + 1 shl 5 out dx, al - 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 ; A 'All set - press ESC to start' messages if need @@ -1148,102 +1249,6 @@ if preboot_blogesc jne .bll1 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 sti @@ -1946,22 +1951,8 @@ ngsyse3: mov [esp+32], eax ret 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 - dec ebx + sub ebx, 4 jnz ngsyse9 mov eax, [timer_ticks];[0xfdf0] mov [esp+32], eax @@ -2216,9 +2207,6 @@ restore_default_cursor_before_killing: movzx eax, word [MOUSE_Y] movzx ebx, word [MOUSE_X] -; mov ecx, [Screen_Max_X] -; inc ecx -; mul ecx mov eax, [d_width_calc_area + eax*4] add eax, [_WinMapAddress] diff --git a/kernel/branches/kolibri-process/lang.inc b/kernel/branches/kolibri-process/lang.inc deleted file mode 100644 index 6ae37e1048..0000000000 --- a/kernel/branches/kolibri-process/lang.inc +++ /dev/null @@ -1 +0,0 @@ -lang fix ru diff --git a/kernel/branches/kolibri-process/network/ethernet.inc b/kernel/branches/kolibri-process/network/ethernet.inc index 05fa7e6484..fbc63929a4 100644 --- a/kernel/branches/kolibri-process/network/ethernet.inc +++ b/kernel/branches/kolibri-process/network/ethernet.inc @@ -86,11 +86,7 @@ ETH_input: push ebx mov esi, esp - pushf - cli add_to_queue ETH_queue, ETH_QUEUE_SIZE, sizeof.ETH_queue_entry, .fail - popf - add esp, sizeof.ETH_queue_entry xor edx, edx @@ -102,10 +98,9 @@ ETH_input: ret .fail: - popf - DEBUGF DEBUG_NETWORK_VERBOSE, "ETH incoming queue is full, discarding packet!\n" + DEBUGF DEBUG_NETWORK_ERROR, "ETH incoming queue is full, discarding packet!\n" - add esp, sizeof.ETH_queue_entry - 8 + pop ebx call NET_packet_free add esp, 4 diff --git a/kernel/branches/kolibri-process/network/queue.inc b/kernel/branches/kolibri-process/network/queue.inc index 9d7a557b50..4f17cb4dde 100644 --- a/kernel/branches/kolibri-process/network/queue.inc +++ b/kernel/branches/kolibri-process/network/queue.inc @@ -28,7 +28,6 @@ struct queue size dd ? ; number of queued packets in this queue w_ptr dd ? ; current writing pointer in queue r_ptr dd ? ; current reading pointer - mutex MUTEX ends @@ -47,18 +46,12 @@ macro add_to_queue ptr, size, entry_size, failaddr { local .ok, .no_wrap - pusha - lea ecx, [ptr + queue.mutex] - call mutex_lock - popa + spin_lock_irqsave cmp [ptr + queue.size], size ; Check if queue isnt full jb .ok - pusha - lea ecx, [ptr + queue.mutex] - call mutex_unlock - popa + spin_unlock_irqrestore jmp failaddr .ok: @@ -76,10 +69,7 @@ local .ok, .no_wrap .no_wrap: mov [ptr + queue.w_ptr], edi - pusha - lea ecx, [ptr + queue.mutex] - call mutex_unlock - popa + spin_unlock_irqrestore } @@ -89,18 +79,12 @@ macro get_from_queue ptr, size, entry_size, failaddr { local .ok, .no_wrap - pusha - lea ecx, [ptr + queue.mutex] - call mutex_lock - popa + spin_lock_irqsave cmp [ptr + queue.size], 0 ; any packets queued? ja .ok - pusha - lea ecx, [ptr + queue.mutex] - call mutex_unlock - popa + spin_unlock_irqrestore jmp failaddr .ok: @@ -122,10 +106,7 @@ local .ok, .no_wrap pop esi - pusha - lea ecx, [ptr + queue.mutex] - call mutex_unlock - popa + spin_unlock_irqrestore } @@ -136,6 +117,4 @@ macro init_queue ptr { mov [ptr + queue.w_ptr], edi mov [ptr + queue.r_ptr], edi - lea ecx, [ptr + queue.mutex] - call mutex_init } \ No newline at end of file diff --git a/kernel/branches/kolibri-process/network/socket.inc b/kernel/branches/kolibri-process/network/socket.inc index 57f4663ff1..390427d2ae 100644 --- a/kernel/branches/kolibri-process/network/socket.inc +++ b/kernel/branches/kolibri-process/network/socket.inc @@ -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 ;; ;; ;; ;; Part of the TCP/IP network stack for KolibriOS ;; @@ -293,6 +293,7 @@ SOCKET_open: push ecx edx esi call SOCKET_alloc pop esi edx ecx + test eax, eax jz .nobuffs 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? jz @f - call SOCKET_notify.unblock ; Unblock it. + call SOCKET_notify ; Unblock it. @@: cmp [eax + SOCKET.Domain], AF_INET4 @@ -1192,6 +1193,7 @@ SOCKET_pair: DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_pair\n" call SOCKET_alloc + test eax, eax jz .nomem1 mov [esp+32], edi ; application's eax @@ -1204,6 +1206,7 @@ SOCKET_pair: mov ebx, eax call SOCKET_alloc + test eax, eax jz .nomem2 mov [esp+20], edi ; application's ebx @@ -1707,8 +1710,9 @@ SOCKET_block: DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: %x\n", eax - pushf push eax + + pushf cli ; Set the 'socket is blocked' flag @@ -1724,12 +1728,12 @@ SOCKET_block: DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: suspending thread: %u\n", edx mov [eax + SOCKET.TID], edx pop edx + popf call change_task pop eax - popf - DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: continueing\n" + DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: continuing\n" ret @@ -1752,70 +1756,54 @@ SOCKET_notify: call SOCKET_check jz .error - test [eax + SOCKET.state], SS_BLOCKED - jnz .unblock - -; test [eax + SOCKET.options], SO_NONBLOCK -; jz .error - - 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 +; Find the associated thread's TASK_DATA + push ebx ecx esi + mov ebx, [eax + SOCKET.TID] + test ebx, ebx + jz .error2 xor ecx, ecx inc ecx mov esi, TASK_DATA .next: - cmp [esi + TASKDATA.pid], eax + cmp [esi + TASKDATA.pid], ebx je .found inc ecx add esi, 0x20 cmp ecx, [TASK_COUNT] jbe .next - jmp .error - .found: - ; Run the thread - mov [esi + TASKDATA.state], 0 ; Running - DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_notify: Unblocked socket!\n" - - .done: - pop esi ecx eax + .error2: +; PID not found, TODO: close socket! + DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_notify: error finding thread 0x%x !\n", ebx + pop esi ecx ebx + ret .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 @@ -1830,7 +1818,6 @@ SOCKET_notify: ; IN: / ; OUT: eax = 0 on error, socket ptr otherwise ; edi = socket number -; ZF = cleared on error ; ;-------------------------------------------------------------------- align 4 @@ -1917,7 +1904,6 @@ SOCKET_alloc: @@: mov [net_sockets + SOCKET.NextPtr], eax - or eax, eax ; used to clear zero flag pusha mov ecx, socket_mutex @@ -2022,6 +2008,7 @@ SOCKET_fork: push ebx call SOCKET_alloc pop ebx + test eax, eax jz .fail push eax @@ -2101,7 +2088,8 @@ SOCKET_num_to_ptr: call mutex_unlock 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 diff --git a/kernel/branches/kolibri-process/network/tcp_input.inc b/kernel/branches/kolibri-process/network/tcp_input.inc index d618461912..1b74690aad 100644 --- a/kernel/branches/kolibri-process/network/tcp_input.inc +++ b/kernel/branches/kolibri-process/network/tcp_input.inc @@ -43,11 +43,7 @@ TCP_input: push ebx ecx esi edi ; mind the order mov esi, esp - pushf - cli add_to_queue TCP_queue, TCP_QUEUE_SIZE, sizeof.TCP_queue_entry, .fail - popf - add esp, sizeof.TCP_queue_entry call NET_ptr_to_num4 diff --git a/kernel/branches/kolibri-process/network/tcp_usreq.inc b/kernel/branches/kolibri-process/network/tcp_usreq.inc index 65128da742..a33a416151 100644 --- a/kernel/branches/kolibri-process/network/tcp_usreq.inc +++ b/kernel/branches/kolibri-process/network/tcp_usreq.inc @@ -186,7 +186,7 @@ TCP_connect: mov eax, [esp+4] mov [eax + SOCKET.errorcode], ETIMEDOUT and [eax + SOCKET.state], not SS_ISCONNECTING - call SOCKET_notify.unblock + call SOCKET_notify ret 4 .fail: diff --git a/kernel/branches/kolibri-process/video/vesa20.inc b/kernel/branches/kolibri-process/video/vesa20.inc index 5f5b6774fb..62f20f0825 100644 --- a/kernel/branches/kolibri-process/video/vesa20.inc +++ b/kernel/branches/kolibri-process/video/vesa20.inc @@ -242,8 +242,6 @@ align 4 add edx, eax ; pointer to pixel map mov eax, [putimg.abs_cy] -; imul eax, [Screen_Max_X] -; add eax, [putimg.abs_cy] mov eax, [d_width_calc_area + eax*4] add eax, [putimg.abs_cx] @@ -688,7 +686,6 @@ __sys_putpixel: ; for example drawwindow_III and drawwindow_IV ; edi = 0x00000001 force -;;; mov [novesachecksum], dword 0 pushad cmp [Screen_Max_X], eax jb .exit @@ -882,9 +879,6 @@ align 4 ;----------------------------------------------------------------------------- align 4 calculate_edi: -; mov edi, ebx -; imul edi, [Screen_Max_X] -; add edi, ebx mov edi, [d_width_calc_area + ebx*4] add edi, eax ret