Tvůrce webu je i pro tebe! Postav třeba web. Bez grafika. Bez kodéra. Hned.
wz

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í