Obsah / Ovladače / DEVICE / Makra všeobecného zařízení
Zdrojový kód:
INCLUDE\DRIVERS\DEVICE.INC
Makra
všeobecného zařízení
; ------------- Initialized general device descriptor
; %1 = device class, %2 = device sub-class, %3 = device index, %4 = flags,
; %5 = major version, %6 = minor version, %7 = build version,
; %8 = name prefix ###
; ###Int = interface identifier list
; ###Res0 = head of resource list
; ###Res1 = first resource
; ###ResN = last resource
; ###Name = pointer to device system name CTEXTDATA
; ###Vendor = pointer to vendor name CTEXTDATA
; ###Short = pointer to device short name CTEXTDATA
; ###Full = pointer to multi-language string array of full device name
; ###Init = initialize device
; ###Deinit = deinitialize device
%macro DEVICE 8
RBTREENODE ; device address list
HASHENTRY ; hash list
TREEHEAD ; device hierarchy list
MUTEX ; device mutex lock
SPINLOCK ; device spin-lock
%8 %+ Res0: LINKEDLIST %8 %+ Res1, %8 %+ ResN ; resource list
dd 0 ; usage reference counter
dd %8 %+ Int ; interface identifier list
db %4 ; device flags
db %3 ; device index
db %2 ; device sub-class
db %1 ; device class
dw %7 ; build number
db %6 ; minor version
db %5 ; major version
TEXTSTR %8 %+ Name ; device system name
TEXTSTR %8 %+ Vendor ; vendor name
TEXTSTR %8 %+ Short ; device short name
dd %8 %+ Full ; pointer to multi-language string
; array of full device name
dd %8 %+ Init ; initialize device
dd %8 %+ Deinit ; deinitialize device
%endmacro
|
DEVICE je makro
generující inicializovaný popisovač všeobecného
zařízení. Makro má 8 parametrů:
%1 - třída
zařízení
%2 - podtřída
zařízení
%3 - index
zařízení
%4 - příznaky
%5 - hlavní číslo
verze ovladače
%6 - vedlejší
číslo verze ovladače
%7 - číslo
překladu verze ovladače
%8 - prefix jména
### :
###Int - seznam
identifikátorů rozhraní (zakončený 0)
###Res0 - záhlaví seznamu zdrojů
###Res1 - první zdroj
###ResN - poslední zdroj
###Name - ukazatel na systémové jméno zařízení
(CTEXTDATA)
###Vendor - ukazatel na jméno poskytovatele (CTEXTDATA)
###Short - ukazatel na krátké jméno zařízení
(CTEXTDATA)
###Full - ukazatel na vícejazyčné pole dlouhého jména
zařízení
###Init - inicializace zařízení
###Deinit - deinicializace zařízení
; ------------- Macro - get total number of devices
; %1 = destination register, device list should be locked + int disabled
%macro DEVNUMBER 1
mov %1,[DevAdrList+RBR_Count] ; get number of devices
%endmacro
|
Makro DEVNUMBER
slouží ke zjištění počtu zařízení v systému. Parametrem
makra je registr, do kterého bude počet zařízení uložen.
; ------------- Macro - get parent of device (with jump)
; %1 = device descriptor, %2 = output register, %3 = jump if it has no parent
; Input and output registers may be identical.
%macro DEVPARENT 3
test byte [%1+DEV_Flags],DEV_ROOT ; is it root device?
jnz %3 ; it has no parent
mov %2,[%1+DEV_DevList+TREE_Parent] ; %2 <- parent
sub %2,DEV_DevList ; %2 <- driver head (it clears CF)
%endmacro
|
Makro DEVPARENT
zjistí rodiče zařízení. Prvním parametrem je registr (nebo
adresa) popisovače zařízení. Druhým parametrem je registr,
do kterého bude uložen ukazatel na popisovač rodiče. Třetím
parametrem je adresa skoku v případě, že zařízení nemá
rodiče (rodičem je systém).
; ------------- Macro - find first device of given class (NULL = none)
; %1 = input BYTE register with device class, %2 = output register DEV
; %3 = jump if none device. Input and output registers may be identical.
%macro DEVFINDCLASS 3
movzx %2,%1 ; %2 <- device class
mov %2,[DevHashList+%2*4] ; %2 <- first entry
or %2,%2 ; check if it is valid entry
jz %3 ; invalid entry
sub %2,DEV_Hash ; %2 <- entry (it clears CF)
%endmacro
; ------------- Macro - get next device of this class (NULL = none)
; %1 = input register DEV, %2 = output register DEV
; %3 = jump if none device. Input and output registers may be identical.
%macro DEVNEXTCLASS 3
mov %2,[%1+DEV_Hash+HASHE_Next] ; %2 <- next entry
or %2,%2 ; check if it is valid entry
jz %3 ; invalid entry
sub %2,DEV_Hash ; %2 <- entry (it clears CF)
%endmacro
|
Pomocí makra
DEVFINDCLASS lze vyhledat zařízení dané třídy. Prvním
parametrem makra je vstupní registr o rozměru BAJT obsahující
třídu zařízení. Druhým parametrem je registr, do kterého
bude uložen ukazatel na popisovač zařízení (může být
shodný se vstupním registrem). Třetím parametrem je adresa
skoku pro případ, že žádné odpovídající zařízení
nebude nalezeno.
Makro DEVNEXTCLASS
vyhledá další zařízení stejné třídy. Prvním parametrem
je adresa popisovače zařízení. Druhým parametrem je registr,
do kterého bude uložena adresa nalezeného zařízení (může
se jednat o stejný registr jako vstupní). Třetím parametrem
je adresa skoku pro případ, že žádné další zařízení
nebude nalezeno.
; ------------- Macro - lock device list
%macro DEVLSTLOCK 0
LOCK_Lock DevListLock ; lock device list
%endmacro
; ------------- Macro - unlock device list (it saves flags)
%macro DEVLSTUNLOCK 0
LOCK_Unlock DevListLock ; unlock device list
%endmacro
|
Makro DEVLSTLOCK
uzamkne přístup k seznamu zařízení (pomocí rychlého
zámku). Makrem DEVLSTUNLOCK lze seznam opět odemknout (makro
uchovává registr příznaků). Pokud mají být současně
uzamknut i rychlý nebo pomalý zámek zařízení, musí být
zámek seznamu zařízení uzamknut dříve.
; ------------- Macro - fast lock device (using spin-lock)
; EBX = pointer to device descriptor DEV
%macro DEVLOCK 0
LOCK_Lock ebx+DEV_Lock ; lock device
%endmacro
; ------------- Macro - fast try to lock device (using spin-lock)
; EBX = pointer to device descriptor DEV, returns CY = cannot lock
%macro DEVTRYLOCK 0
LOCK_TryLockC ebx+DEV_Lock ; try to lock device
%endmacro
; ------------- Macro - fast unlock device (using spin-lock, it saves flags)
; EBX = pointer to device descriptor DEV
%macro DEVUNLOCK 0
LOCK_Unlock ebx+DEV_Lock ; unlock device
%endmacro
|
Makro DEVLOCK uzamkne
zařízení rychlým zámkem. Makro DEVTRYLOCK se pokusí
zařízení uzamknout - je-li již uzamknuto, nastaví se
příznak CY. Makrem DEVUNLOCK lze zařízení opět odemknout
(makro uchovává registr příznaků). Má-li být současně
uzamknut i zámek seznamu zařízení, musí být rychlý zámek
uzamknut po seznamu zařízení. Má-li být současně uzamknut
i pomalý zámek, musí být rychlý zámek uzamknut po pomalém
zámku.
; ------------- Macro - slow lock device (using mutex)
; EBX = pointer to device descriptor DEV
%macro DEVMUTLOCK 0
add ebx,DEV_Mutex ; EBX <- mutex
call MutexLock ; lock mutex
sub ebx,DEV_Mutex ; return pointer
%endmacro
; ------------- Macro - slow try to lock device (using mutex)
; EBX = pointer to driver descriptor DRV, returns CY = already locked
%macro DEVMUTTRYLOCK 0
push ebx ; push EBX
add ebx,DEV_Mutex ; EBX <- mutex
call MutexTryLock ; try to lock mutex
pop ebx ; pop EBX
%endmacro
; ------------- Macro - slow unlock device (using mutex,it does NOT save flags)
; EBX = pointer to device descriptor DEV
%macro DEVMUTUNLOCK 0
push ebx ; push EBX
add ebx,DEV_Mutex ; EBX <- mutex
call MutexUnlock ; unlock mutex
pop ebx ; pop EBX
%endmacro
; ------------- Macro - slow unlock device (using mutex, it saves flags)
; EBX = pointer to device descriptor DEV
%macro DEVMUTUNLOCKF 0
pushf ; push flags
push ebx ; push EBX
add ebx,DEV_Mutex ; EBX <- mutex
call MutexUnlock ; unlock mutex
pop ebx ; pop EBX
popf ; pop flags
%endmacro
|
Makro DEVMUTLOCK
uzamkne zařízení pomalým zámkem. Makro DEVMUTTRYLOCK se
pokusí zařízení uzamknout - je-li již uzamknuto, nastaví se
příznak CY. Makrem DEVMUTUNLOCK lze zařízení opět odemknout
- makro neuchovává registr příznaků. Odemknutí s
uchováním registru příznaků je možné pomocí makra
DEVMUTUNLOCKF. Má-li být současně uzamknut i zámek seznamu
zařízení, musí být pomalý zámek uzamknut po seznamu
zařízení. Má-li být současně uzamknut i rychlý zámek,
musí být rychlý zámek uzamknut po pomalém zámku.
; ------------- Macro - call device interface function without lock
; EBX = pointer to device DEV, %1 = function offset
%macro DEVFNC 1
call dword [ebx+%1] ; call device function
%endmacro
; ------------- Macro - call device interface function with lock
; EBX = pointer to device DEV, %1 = function offset
%macro DEVFNCLOCK 1
pushf ; push flags
cli ; disable interrupts
DEVLOCK ; lock device
call dword [ebx+%1] ; call device function
DEVUNLOCK ; unlock device
popf ; pop flags
%endmacro
; ------------- Macro - call device function with lock and carry
; EBX = pointer to device DEV, %1 = function offset,
%macro DEVFNCLOCKC 1
clc ; clear error flag
pushf ; push flags
cli ; disable interrupts
DEVLOCK ; lock device
call dword [ebx+%1] ; call device function
adc byte [esp],0 ; set error flag (bit 0)
DEVUNLOCK ; unlock device
popf ; pop flags
%endmacro
; ------------- Macro - call device interface function with mutex lock
; EBX = pointer to device DEV, %1 = function offset
%macro DEVFNCMUTLOCK 1
DEVMUTLOCK ; mutex lock device
call dword [ebx+%1] ; call device function
DEVMUTUNLOCK ; mutex unlock device
%endmacro
; ------------- Macro - call device function with mutex lock, carry
; EBX = pointer to device DEV, %1 = function offset
%macro DEVFNCMUTLOCKC 1
DEVMUTLOCK ; mutex lock device
call dword [ebx+%1] ; call device function
DEVMUTUNLOCKF ; mutex unlock device
%endmacro
|
Pomocí makra DEVFNC
lze zavolat funkci zařízení, jejíž offset je předán jako
parametr makra. Makro DEVFNCLOCK zavolá funkci zařízení s
uzamknutím rychlého zámku a úschovou registru příznaků
(přerušení může být před voláním funkce povoleno). Makro
DEVFNCLOCKC zavolá funkcí zařízení s uzamknutím rychlého
zámku, přitom zajistí navrácení příznaku chyby CF.
Ostatní příznaky zůstanou neovlivněny. Makro DEVFNCMUTLOCK
zavolá funkci zařízení s uzamknutím pomalého zámku,
navrácený stav registru příznaků je nedefinovaný. Makro
DEVFNCMUTLOCKC zavolá funkcí zařízení s uzamknutím
pomalého zámku a navrácením příznaku chyby od zařízení.
Obsah / Ovladače / DEVICE / Makra všeobecného zařízení