Obsah / Ovladače / DEVICE / Funkce všeobecného zařízení
Zdrojový kód:
DRIVERS\DEVICE.ASM
Funkce
všeobecného zařízení
; ------------- List of all installed devices
align 8, db 0
DevAdrList: RBTREE ; device address list
DevListLock: SPINLOCK ; device list lock
DevDevList: TREEHEAD ; device hierarchy list
; ------------- hash list of devices (base index = device class) (size 1 KB)
DevHashList: resd DEVHASH_SIZE
|
DevAdrList je
záhlaví seznamu zařízení tříděných podle adresy. Tento
seznam slouží k rychlému vyhledání
zařízení podle adresy, která je přijata od uživatelského
programu při přístupu k zařízení.
DevListLock je zámek k
uzamknutí seznamu zařízení při manipulaci se seznamem
zařízení (přidání nebo odebrání zařízení). Zařízení
je možné odebrat ze systému pouze pokud není nikým
používáno (referenční čítač je 0 a zámky jsou
odemknuty). Při současném uzamknutí seznamu zařízen a
zámků zařízení je nutné uzamknout nejdříve zámek seznamu
zařízení, potom pomalý zámek zařízení a nakonec rychlý
zámek zařízení - tento postup použije i funkce sloužící k
odebrání zařízení ze systému.
DevDevList je hierarchický
seznam zařízení (typu stromový seznam).
Zařízení jsou organizována podle vzájemné funkční
závislosti.
DevHashList je hashovaný seznam zařízení s klíčem odvozeným z třídy
zařízení. Seznam slouží k rychlému vyhledání zařízení,
je-li adresováno pomocí třídy a podtřídy.
; -----------------------------------------------------------------------------
; Get total number of devices
; -----------------------------------------------------------------------------
; OUTPUT: EAX = number of devices
; -----------------------------------------------------------------------------
DevNumber: DEVNUMBER eax ; EAX <- number of devices
ret
|
Funkce DevNumber
navrací v registru EAX počet zařízení v systému.
; -----------------------------------------------------------------------------
; Check device descriptor address validity (test if it is in the device list)
; -----------------------------------------------------------------------------
; INPUT: EBX = device descriptor DEV
; OUTPUT: CY = entry not found
; NOTES: Device list should be locked and interrupts should be disabled.
; -----------------------------------------------------------------------------
DevCheck: push edx ; push EDX
mov edx,DevAdrList ; EDX <- device address list
xchg eax,ebx ; EAX <- entry
call RBTreeSrcAddr ; search entry
xchg eax,ebx ; EBX <- entry
pop edx ; pop EDX
ret
|
Funkce DevCheck
ověří, zda registr EAX obsahuje platnou adresu popisovače
zařízení. Nejedná-li se o platnou adresu, navrátí se
příznak chyby CY. Funkce vyžaduje, aby byl seznam zařízení
uzamknut a přerušení aby bylo zakázáno.
; -----------------------------------------------------------------------------
; Get parent of device
; -----------------------------------------------------------------------------
; INPUT: EBX = device descriptor DEV (must be valid)
; OUTPUT: EAX = parent device descriptor DEV (or NULL = it has no parent)
; CY = device has no parent (EAX = NULL)
; -----------------------------------------------------------------------------
DevParent: DEVPARENT ebx,eax,short DevParent2 ; get parent of device
ret
DevParent2: xor eax,eax ; EAX <- no parent
DevParent4: stc ; set error flag, no parent
ret
|
Funkce DevParent
zjistí rodiče zařízení. Na vstupu funkce obsahuje registr
EBX adresu popisovače zařízení. Na výstupu navrací v
registru EAX adresu popisovače rodiče. Pokud zařízení nemá
rodiče (rodičem je systém), navrací se příznak chyby CY a
obsah registru EAX je NULL.
; -----------------------------------------------------------------------------
; Find first device of given class
; -----------------------------------------------------------------------------
; INPUT: AL = device class
; OUTPUT: EBX = device descriptor DEV (or NULL if no such device)
; CY = no device found (EBX = NULL)
; NOTES: Device list should be locked and interrupts should be disabled.
; -----------------------------------------------------------------------------
DevFindClass: DEVFINDCLASS al,ebx,short DevParent4 ; find first device
ret
|
Funkce DevFindClass
vyhledá zařízení dané třídy. Na vstupu funkce obsahuje
registr AL třídu zařízení. Funkce navrací v registru EBX
popisovač nalezeného zařízení. Není-li odpovídající
zařízení nalezeno, navrátí se příznak chyby CY a obsah
registru EBX je NULL. Funkce vyžaduje, aby byl seznam
zařízení uzamknut a přerušení aby bylo zakázáno.
; -----------------------------------------------------------------------------
; Find next device of this class
; -----------------------------------------------------------------------------
; INPUT: EBX = device descriptor DEV
; OUTPUT: EBX = device descriptor DEV (or NULL if no next device)
; CY = no next device found (EBX = NULL)
; NOTES: Device list should be locked and interrupts should be disabled.
; -----------------------------------------------------------------------------
DevNextClass: DEVNEXTCLASS ebx,ebx,short DevParent4 ; find next device
ret
|
Funkce DevNextClass
vyhledá další zařízení stejné třídy. Na vstupu funkce
obsahuje registr EBX adresu popisovače zařízení. Funkce
navrátí v registru EBX popisovač nalezeného zařízení.
Není-li odpovídající zařízení nalezeno, navrátí se
příznak chyby CY a obsah registru EBX je NULL. Funkce
vyžaduje, aby byl seznam zařízení uzamknut a přerušení aby
bylo zakázáno.
; -----------------------------------------------------------------------------
; Find first device of given class and sub-class
; -----------------------------------------------------------------------------
; INPUT: AH = device class
; AL = device sub-class
; OUTPUT: EBX = device descriptor DEV (or NULL if no such device)
; CY = no device found (EBX = NULL)
; NOTES: Input can be EAX = class*256 + subclass.
; Device list should be locked and interrupts should be disabled.
; -----------------------------------------------------------------------------
DevFindSubCls: movzx ebx,ah ; EBX <- device class
lea ebx,[DevHashList+ebx*4] ; EBX <- hash list head
DevFindSubCls2: mov ebx,[ebx+HASHE_Next] ; EBX <- next entry
or ebx,ebx ; check if it is valid entry
jz short DevParent4 ; invalid entry
cmp byte [ebx-DEV_Hash+DEV_SubClass],al ; check sub-class
jne DevFindSubCls2 ; get next device
sub ebx,DEV_Hash ; EBX <- entry (it clears CF)
ret
|
Funkce DevFindSubCls
vyhledá zařízení dané třídy a podtřídy. Na vstupu funkce
obsahuje registr AH třídu zařízení a registr AL podtřídu
zařízení. Funkce navrací v registru EBX popisovač
nalezeného zařízení. Není-li odpovídající zařízení
nalezeno, navrátí se příznak chyby CY a obsah registru EBX je
NULL. Funkce vyžaduje, aby byl seznam zařízení uzamknut a
přerušení aby bylo zakázáno.
; -----------------------------------------------------------------------------
; Find next device of this class and sub-class
; -----------------------------------------------------------------------------
; INPUT: EBX = device descriptor DEV
; OUTPUT: EBX = device descriptor DEV (or NULL if no other device)
; CY = no other device found (EBX = NULL)
; NOTES: Device list should be locked and interrupts should be disabled.
; -----------------------------------------------------------------------------
DevNextSubCls: push eax ; push EAX
add ebx,DEV_Hash ; EBX <- hash entry
mov al,[ebx-DEV_Hash+DEV_SubClass] ; AL <- get sub-class
DevNextSubCls2: mov ebx,[ebx+HASHE_Next] ; EBX <- next entry
or ebx,ebx ; check if it is valid entry
jz short DevNextSubCls4 ; invalid entry
cmp byte [ebx-DEV_Hash+DEV_SubClass],al ; check sub-class
jne DevNextSubCls2 ; get next device
sub ebx,DEV_Hash ; EBX <- entry (it clears CF)
pop eax ; pop EAX
ret
DevNextSubCls4: stc ; set error flag
pop eax ; pop EAX
ret
|
Funkce DevNextSubCls
vyhledá další zařízení stejné třídy a podtřídy. Na
vstupu funkce obsahuje registr EBX ukazatel na popisovač
zařízení. Funkce navrací v registru EBX popisovač
nalezeného zařízení. Není-li odpovídající zařízení
nalezeno, navrátí se příznak chyby CY a obsah registru EBX je
NULL. Funkce vyžaduje, aby byl seznam zařízení uzamknut a
přerušení aby bylo zakázáno.
; -----------------------------------------------------------------------------
; Find device of given class, sub-class and index
; -----------------------------------------------------------------------------
; INPUT: AH = device class
; AL = device sub-class
; CL = device index (0 to 255)
; OUTPUT: EBX = device descriptor DEV (or NULL if no such device)
; CY = no device found (EBX = NULL)
; NOTES: Input can be EAX = class*256 + subclass.
; Device list should be locked and interrupts should be disabled.
; -----------------------------------------------------------------------------
DevFindIndex: push eax ; push EAX
movzx ebx,ah ; EBX <- device class
mov ah,al ; AH <- sub-class
lea ebx,[DevHashList+ebx*4] ; EBX <- hash list head
mov al,cl ; AL <- index
DevFindIndex2: mov ebx,[ebx+HASHE_Next] ; EBX <- next entry
or ebx,ebx ; check if it is valid entry
jz short DevNextSubCls4 ; invalid entry
cmp word [ebx-DEV_Hash+DEV_InxSubW],ax ; check inx/cls
jne DevFindIndex2 ; get next device
sub ebx,DEV_Hash ; EBX <- entry (it clears CF)
pop eax ; pop EAX
ret
|
Funkce DevFindIndex
vyhledá zařízení dané třídy, podtřídy a indexu. Na
vstupu funkce obsahuje registr AH třídu zařízení, registr AL
podtřídu zařízení a registr CL index zařízení. Funkce
navrací v registru EBX popisovač nalezeného zařízení.
Není-li odpovídající zařízení nalezeno, navrátí se
příznak chyby CY a obsah registru EBX je NULL. Funkce
vyžaduje, aby byl seznam zařízení uzamknut a přerušení aby
bylo zakázáno.
; -----------------------------------------------------------------------------
; Register device (add device into device list)
; -----------------------------------------------------------------------------
; INPUT: EBX = device descriptor DEV (must be valid)
; ECX = parent device descriptor (must be valid or NULL = system)
; OUTPUT: CY = error, entry already exists in the list
; NOTES: It locks device list lock.
; It sets-up DEV_ROOT flag if needed.
; -----------------------------------------------------------------------------
; ------------- Push registers
DevRegister: clc ; clear error flag
pushf ; push flags
cli ; disable interrupts
push eax ; push EAX
push edx ; push EDX
; ------------- Lock device list
DEVLSTLOCK ; lock device list
; ------------- Insert entry into driver list
mov edx,DevAdrList ; EDX <- list of al drivers
xchg eax,ebx ; EAX <- new entry
call RBTreeInsAddr ; insert entry into list
jc DevRegister7 ; entry already exists
; ------------- Add entry into hash list
movzx ebx,byte [eax+DEV_Class] ; EBX <- device class
lea ebx,[DevHashList+ebx*4] ; EBX <- hash list head
add eax,DEV_Hash ; EAX <- hash list entry
call HashAdd ; add new entry into hash list
; ------------- Add entry into hierarchy list
mov ebx,ecx ; EBX <- parent
and byte [eax-DEV_Hash+DEV_Flags],~DEV_ROOT;clear root flag
or ecx,ecx ; is it root device?
jnz DevRegister2 ; it is not root device
mov ebx,DevDevList-DEV_DevList ; ECX <- list head
or byte [eax-DEV_Hash+DEV_Flags],DEV_ROOT ; set root flag
DevRegister2: add ebx,DEV_DevList ; EBX <- device hierarchy list entry
add eax,DEV_DevList-DEV_Hash ; EAX <- device list entry
call TreeAdd ; add entry into list
sub eax,DEV_DevList ; EAX <- new entry
; ------------- Register standard system devices
mov bx,[eax+DEV_SubClsW] ; BX <- class and sub-class
cmp bh,DEVCLASS_SYS ; system device?
jne DevRegister6 ; not system device
cmp byte [eax+DEV_Index],0 ; first device?
jne DevRegister6 ; not first device
; ------------- SYS device
cmp bl,DEV_SYS_SYS ; SYS device?
jne DevRegister4 ; not SYS device
mov [SYSDevice],eax ; register SYS device
; ------------- DMA device
DevRegister4: cmp bl,DEV_SYS_DMA ; DMA device?
jne DevRegister5 ; not DMA device
mov [DMADevice],eax ; register DMA device
; ------------- IRQ device
DevRegister5: cmp bl,DEV_SYS_IRQ ; IRQ device?
jne DevRegister6 ; not IRQ device
mov [IRQDevice],eax ; register IRQ device
; ------------- Unlock device list (it saves flags, CY=error)
DevRegister6: clc ; clear error flag
DevRegister7: xchg eax,ebx ; EBX <- new entry
DEVLSTUNLOCK ; unlock device list
; ------------- Pop registers
pop edx ; pop EDX
pop eax ; pop EAX
; ------------- Pop flags
adc byte [esp],0 ; set error flag (bit 0)
popf ; enable interrupts
ret
|
Funkce DevRegister
zaregistruje zařízení a přidá jeho popisovač do seznamu
zařízení. Na vstupu funkce obsahuje registr EBX platný
ukazatel na popisovač zařízení a registr ECX ukazatel na
popisovač zařízení rodiče. Je-li popisovač rodiče NULL, je
rodičem systém. Na výstupu vrací funkce případ chyby CY v
případě, že zařízení je v systému již zaregistrováno.
Funkce uzamyká zámek seznamu zařízení a případně
nastavuje příznak DEV_ROOT zařízení.
Po úschově
registrů a zákazu přerušení se uzamkne zámek seznamu
zařízení. Zařízení se vloží do seznamu zařízení
DevAdrList, tříděného podle adresy. Pokud zařízení s touto
adresou již v seznamu existuje, funkce se ukončí s
navrácením příznaku chyby.
Zařízení se
vloží do hashovaného seznamu DevHashList, jehož klíčem je
třída zařízení. Dále se vloží do hierarchického
stromového seznamu DevDevList - a to buď připojením k rodiči
nebo připojením k záhlaví seznamu (pokud zařízení nemá
rodiče).
Některá standardní
často používaná systémová zařízení se zaregistrují do
systému - uschová se ukazatel na ně.
Na závěr se odemkne
seznam zařízení a navrátí se registry.
; -----------------------------------------------------------------------------
; Unregister device (remove device from device list)
; -----------------------------------------------------------------------------
; INPUT: EBX = device descriptor DEV (it must be valid entry)
; OUTPUT: CY = cannot unregister, it is used
; NOTES: Device descriptor DEV is not destroyed, it is only detached.
; Reference counter must be zero and it must have no children.
; -----------------------------------------------------------------------------
; ------------- Disable interrupts
DevUnregister: pushf ; push flags
cli ; disable interrupts
; ------------- Lock device list
DEVLSTLOCK ; lock device list
;-------------- Check reference counter and children
cmp dword [ebx+DEV_Ref],0 ; check reference counter
jne DevUnregister8 ; cannot unregister
cmp dword [ebx+DEV_DevList+TREE_Child],0 ; children?
jne DevUnregister8 ; cannot unregister
; ------------- Push registers
push eax ; push EAX
push ebx ; push EBX
push edx ; push EDX
; ------------- Delete entry from driver list
mov edx,DevAdrList ; EDX <- device address list
call RBTreeDelete ; delete entry from the list
; ------------- Delete entry from hash list
lea eax,[ebx+DEV_Hash] ; EAX <- hash entry
call HashDel ; delete entry from hash list
; ------------- Delete entry from hierarchy list
lea eax,[ebx+DEV_DevList] ; EAX <- tree entry
mov ebx,[eax+TREE_Parent] ; EBX <- parent
call TreeDel ; delete entry
; ------------- Pop registers
pop edx ; pop EDX
pop ebx ; pop EBX
pop eax ; pop EAX
; ------------- Unlock device list
DEVLSTUNLOCK ; unlock device list
; ------------- OK
popf ; enable interrupts
clc ; clear error flag
ret
; ------------- Unlock device list
DevUnregister8: DEVLSTUNLOCK ; unlock device list
; ------------- ERROR
popf ; enable interrupts
stc ; set error flag
ret
|
Pomocí funkce
DevUnregister je zařízení odregistrováno ze systému. Na
vstupu funkce obsahuje registr EBX platný ukazatel na popisovač
zařízení. Pokud je zařízení používáno (referenční
čítač musí být 0 a zařízení nesmí mít žádné
závislé potomky), funkce navrátí příznak chyby CY a
odregistrování zařízení se neprovede.
Po uzamknutí seznamu
zařízení se provede kontrola referenčního čítače (zda je
0) a zda zařízení neobsahuje žádné závislé potomky. Je-li
zařízení používáno, funkce se předčasně ukončí s
navrácením chyby CY.
V případě platné
odregistrace se zařízení vyjme ze seznamu zařízení
DevAdrList, z hashovaného seznamu DevHashList a z
hierarchického seznamu DevDevList. Nakonec se seznamy odemknou a
funkce se ukončí s vynulovaným příznakem chyby.
; -----------------------------------------------------------------------------
; Add new resource to device descriptor
; -----------------------------------------------------------------------------
; INPUT: AL = type of resource (DEVRES_IRQ, DEVRES_DMA,...)
; EBX = device descriptor DEV
; ECX = start of resource
; EDX = end of resource
; ESI = pointer to name of resource TEXTDATA
; OUTPUT: CY = memory error
; NOTES: It does not check if such resource already exists.
; -----------------------------------------------------------------------------
; ------------- Push registers
DevResAdd: push eax ; push EAX
push edi ; push EDI
; ------------- Prepare flags and type (-> EDI)
movzx edi,al ; EDI <- type of resource
; ------------- Create resource descriptor
mov eax,DEVRES_size ; EAX <- size of resource descriptor
call SysMemAlloc ; get system memory block
jc DevResAdd8 ; memory error
; ------------- Initialize resource descriptor
mov [eax+DEVRES_Start],ecx ; start of resource
mov [eax+DEVRES_End],edx ; end of resource
mov [eax+DEVRES_TypeFlagDW],edi ; type and flags
; ------------- Name of resource
mov edi,ebx ; EDI <- save device descriptor
lea ebx,[eax+DEVRES_Name] ; EBX <- name of resource
xchg eax,esi ; EAX <- name, ESI <- resource
call TextAttach ; attach text string
xchg eax,esi ; EAX <- resource, ESI <- name
; ------------- Add resource descriptor into driver parameter block
lea ebx,[edi+DEV_Resource] ; EBX <- resource list
call ListLast ; add resource descriptor into list
sub ebx,DEV_Resource ; EBX <- device DEV (it clears CF)
; ------------- Pop registers
DevResAdd8: pop edi ; pop EDI
pop eax ; pop EAX
ret
|
Funkce DevResAdd
přidá k zařízení nový systémový zdroj. Na vstupu funkce
obsahuje registr AL typ zdroje, EBX ukazatel na popisovač
zařízení, registr ECX počátek zdroje, registr EDX konec
zdroje a registr ESI ukazatel na jméno zdroje ve tvaru TEXDATA. V případě chyby paměti vrátí funkce
příznak chyby CY.
Na začátku funkce
se nejdříve alokuje blok systémové paměti pro nový
popisovač zdroje. V případě chyby paměti se funkce ukončí
s příznakem chyby CY. Položky popisovače zdroje se naplní z
registrů, připojí se textový řetězec jména zdroje a
popisovač se přidá do seznamu popisovačů zdrojů
zařízení.
; -----------------------------------------------------------------------------
; Add resource descriptor to driver descriptor
; -----------------------------------------------------------------------------
; INPUT: EAX = resource descriptor DEVRES
; EBX = device descriptor DEV
; NOTES: Use DEVRES_STATIC flag to specify static descriptor.
; -----------------------------------------------------------------------------
DevResDescAdd: push ebx ; push EBX
add ebx,DEV_Resource ; EBX <- resource list
call ListLast ; add resource descriptor into list
pop ebx ; pop EBX
ret
|
Funkce DevResDescAdd
přidá k zařízení popisovač systémového zdroje. Na vstupu
funkce obsahuje registr EAX ukazatel na popisovač systémového
zdroje a registr EBX ukazatel na popisovač zařízení.
; -----------------------------------------------------------------------------
; Delete one resource from the device descriptor
; -----------------------------------------------------------------------------
; INPUT: AL = type of resource (DEVRES_IRQ, DEVRES_DMA,...)
; EBX = device descriptor DEV
; ECX = start of resource
; OUTPUT: CY = no such resource found
; NOTES: Resource flags and resource size are not compared.
; Resource descriptor is destroyed if it is not static.
; -----------------------------------------------------------------------------
; ------------- Push registers
DevResDel: push ebx ; push EBX
push esi ; push ESI
; ------------- Get next resource descriptor (-> ESI)
add ebx,DEV_Resource ; EBX <- resource list head
mov esi,ebx ; ESI <- resource list head
DevResDel2: mov esi,[esi+LIST_Next] ; ESI <- next resource descriptor
cmp esi,ebx ; any other resource descriptor?
stc ; set error flag, no such resource
je DevResDel8 ; no other resource descriptor
; ------------- Check if it is required resource
cmp al,[esi+DEVRES_Type] ; check resource type
jne DevResDel2 ; resource type is not valid
cmp ecx,[esi+DEVRES_Start] ; check start address
jne DevResDel2 ; start address is not valid
; ------------- Delete resource descriptor from the list
xchg eax,esi ; EAX <- descriptor, ESI <- type
call ListDel ; delete resource descriptor from list
; ------------- Check if resource descriptor may be destroyed
test byte [eax+DEVRES_Flags],DEVRES_STATIC ; static?
jnz DevResDel8 ; cannot delete static descriptor
; ------------- Detach resource name
lea ebx,[eax+DEVRES_Name] ; EBX <- name of resource
call TextDetach ; detach text of resource name
; ------------- Destroy block of memory
call SysMemFree ; destroy resource descriptor
xchg eax,esi ; EAX <- type
clc ; clear error flag
; ------------- Pop registers
DevResDel8: pop esi ; pop ESI
pop ebx ; pop EBX
ret
|
Funkce DevResDel
zruší jeden popisovač systémového zdroje ze zařízení. Na
vstupu funkce obsahuje registr AL typ systémového zdroje,
registr EBX ukazatel na popisovač zařízení a registr ECX
počátek systémového zdroje. Pokud zařízení takový
systémový zdroj nevlastní, navrátí se příznak chyby CY.
Funkce vyhledá v
seznamu systémových zdrojů zařízení systémový zdroj
uvedeného typu a s uvedeným počátkem. Pokud nalezne
popisovač takového systémového zdroje (musí souhlasit typ i
počátek), odpojí popisovač ze seznamu systémových zdrojů
zařízení a pokud se nejedná o statický popisovač, uvolní
textový řetězec jména zdroje a paměťový blok popisovače.
; -----------------------------------------------------------------------------
; Delete all resources of the driver
; -----------------------------------------------------------------------------
; INPUT: EBX = device descriptor DEV
; -----------------------------------------------------------------------------
; ------------- Push registers
DevResDelAll: push eax ; push EAX
push ebx ; push EBX
push ecx ; push ECX
; ------------- Get next resource descriptor (-> EAX)
lea ecx,[ebx+DEV_Resource] ; ECX <- resource list head
DevResDelAll4: mov eax,[ecx+LIST_Next] ; EAX <- next resource descriptor
cmp eax,ecx ; any other resource descriptor?
je DevResDelAll8 ; no other resource descriptor
; ------------- Detach resource descriptor from the list
call ListDel ; detach resource descriptor from list
; ------------- Check if resource descriptor may be destroyed
test byte [eax+DEVRES_Flags],DEVRES_STATIC ; static?
jnz DevResDelAll4 ; cannot delete static descriptor
; ------------- Detach resource name
lea ebx,[eax+DEVRES_Name] ; EBX <- name of resource
call TextDetach ; detach text of resource name
; ------------- Destroy block of memory
call SysMemFree ; destroy resource descriptor
jmp DevResDelAll4 ; next descriptor
; ------------- Pop registers
DevResDelAll8: pop ecx ; pop ECX
pop ebx ; pop EBX
pop eax ; pop EAX
ret
|
Funkce DevResDelAll
zruší všechny popisovače systémových zdrojů zařízení.
Na vstupu funkce obsahuje registr EBX ukazatel na popisovač
zařízení. Funkce prochází seznam systémových zdrojů
zařízení, každý popisovač odpojí ze seznamu a pokud se
nejedná o statický popisovač, odpojí jméno zdroje a uvolní
paměťový blok popisovače.
; -----------------------------------------------------------------------------
; Initialize all not-initialized devices
; -----------------------------------------------------------------------------
; ------------- Push registers
DevInitAll: push ebx ; push EBX
; ------------- Disable interrupts
DevInitAll2: pushf ; push flags
cli ; disable interrupts
; ------------- Lock device list
DEVLSTLOCK ; lock device list
; ------------- Get first device in the list (-> EBX)
push edx ; push EDX
mov edx,DevAdrList ; EDX <- list of all drivers
call RBTreeFirst ; get first device in the list
pop edx ; pop EDX
jc DevInitAll8 ; no device found
; ------------- Check if this device is initialized
DevInitAll4: test byte [ebx+DEV_Flags],DEV_INIT ; is device initialized?
jnz DevInitAll6 ; device is already initialized
; ------------- Unlock device list
DEVLSTUNLOCK ; unlock device list
; ------------- Enable interrupts
popf ; enable interrupts
; ------------- Initialize device
call DevInit ; initialize device
jmp short DevInitAll2 ; try next device
; ------------- Get next device
DevInitAll6: call RBTreeNext ; get next device
jnc DevInitAll4 ; check next device
; ------------- Unlock device list
DevInitAll8: DEVLSTUNLOCK ; unlock device list
; ------------- Enable interrupts
popf ; enable interrupts
; ------------- Pop registers
pop ebx ; pop EBX
ret
|
Funkce DevInitAll
inicializuje všechna neinicializovaná zařízení. Funkce je
volána po přidání nových zařízení do systému. Po
uzamknutí seznamu zařízení prochází seznam zařízení
(podle adresového seznamu) a pokud narazí na neinicializované
zařízení, odemkne seznam zařízení a zavolá inicializaci
zařízení. Poté opakuje prohledávání seznamu.
; -----------------------------------------------------------------------------
; Initialize device
; -----------------------------------------------------------------------------
; INPUT: EBX = device descriptor DEV
; OUTPUT: CY = error or already initialized
; NOTES: Function does not lock device.
; -----------------------------------------------------------------------------
DevInit: bts dword [ebx+DEV_Flags],DEV_INIT_BIT ; initialized?
jc DevInit8 ; already initialized
DEVFNC DEV_Init ; initialize device
DevInit8: ret
|
Funkce DevInit
inicializuje zařízení, jehož popisovač je funkci předán v
registru EBX. Zařízení se inizializuje pouze v případě, že
nebylo dosud inicializováno. Funkce neuzamyká přístup k
zařízení a vrací příznak chyby CY v případě, že
zařízení bylo již inicializováno nebo se inicializace
nepovedla.
; -----------------------------------------------------------------------------
; Deinitialize device
; -----------------------------------------------------------------------------
; INPUT: EBX = device descriptor DEV
; OUTPUT: CY = error or not initialized
; NOTES: Function does not lock device.
; -----------------------------------------------------------------------------
DevDeinit: btr dword [ebx+DEV_Flags],DEV_INIT_BIT ; initialized?
cmc ; invert error flag
jc DevDeinit8 ; not initialized
DEVFNC DEV_Deinit ; deinitialize device
DevDeinit8: ret
|
Funkce DevDeinit
deinicializuje zařízení, jehož popisovač je funkci předán
v registru EBX. Zařízení se deinizializuje pouze v případě,
že bylo inicializováno. Funkce neuzamyká přístup k
zařízení a vrací příznak chyby CY v případě, že
zařízení nebylo inicializováno nebo se deinicializace
nepovedla.
Obsah / Ovladače / DEVICE / Funkce všeobecného zařízení