⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usb.asm

📁 AMI 主板的BIOS源码
💻 ASM
📖 第 1 页 / 共 5 页
字号:
	pusha
	push	es

	mov	bx, USB_RQ_SET_CONFIGURATION ;Request type is "Set Address"
	xor	dx, dx			;DX = wIndex parameter = 0
	xor	si, si			;SI = wLength parameter = 0
	xor	di, di			;ES:DI = data buf ptr = NULL
	mov	es, di

	call	UsbDeviceRequest	;Execute the device request, returns CF

	pop	es
	popa
	ret
_UsbSetConfiguration endp


;---------------------------------------;
; _UsbHidSetProtocol                    ;
;---------------------------------------;--------------------------------------;
; This function executes a Set Protocol command to the given USB HID device    ;
; and endpoint.                                                                ;
;                                                                              ;
; Input: AL = USB device address of device to receive the command              ;
;        AH = Endpoint number within the USB device                            ;
;        CL = New protocol for device                                          ;
;               00h = HID boot protocol                                        ;
;               01h = HID entity protocol                                      ;
;               02h-FFh = Reserved                                             ;
;        CH = Endpoint number (from EndpointDescriptor.EndpointAddr)           ;
;                                                                              ;
; Output: CF = Clear if the command completed successfully                     ;
;              Set if the command failed                                       ;
;                                                                              ;
; Destroys: Nothing                                                            ;
;------------------------------------------------------------------------------;
;;;;_UsbHidSetProtocol  proc near
;;;;    pusha
;;;;    push    es
;;;;
;;;;    mov     bx, HID_RQ_SET_PROTOCOL ;Request type is "Set Protocol"
;;;;    movzx   dx, ch                  ;DX = wIndex = Interface number
;;;;    xor     ch, ch                  ;CX = wValue = Protocol code
;;;;    xor     si, si                  ;SI = wLength parameter = 0
;;;;    xor     di, di                  ;ES:DI = data buf ptr = NULL
;;;;    mov     es, di
;;;;
;;;;    call    UsbDeviceRequest        ;Execute the device request, returns CF
;;;;
;;;;    pop     es
;;;;    popa
;;;;    ret
;;;;_UsbHidSetProtocol  endp


;---------------------------------------;
; UsbHubPortChange                      ;
;---------------------------------------;--------------------------------------;
; This function is called when a change in connect status is detected on any   ;
; port of any hub (including the root hub).  Connect status changes are caused ;
; by devices being plugged in or removed from the USB.  This routine calls     ;
; ProcessSingleHubPortChange to handle the change and then checks for new hubs ;
; on the bus that need to be enumerated.                                       ;
;                                                                              ;
; Input: AL = USB Device address of hub whose status has changed               ;
;             00 - 7F = Device address of hub on the USB                       ;
;             80 - FE = Reserved                                               ;
;             FF      = Root hub                                               ;
;        AH = Port number within hub whose status has changed                  ;
;                                                                              ;
; Output: Nothing                                                              ;
;                                                                              ;
; Destroys: Nothing                                                            ;
;------------------------------------------------------------------------------;
UsbHubPortChange	proc near
	pusha

	mov	bh, 01h			;Do not ignore connect status change
	call	ProcessSingleHubPortChange

; Now check iteratively to see if any external hubs have been found.  For any
; new external hub that has been found, check each of its ports for a new device
; attached.  Since any hub port may have another external hub attached, we
; must iteratively check for new hubs until no new hub is found.  An external
; hub that has been found, but has not had its ports scanned is indicated by
; its HubEnumFlag field in its DeviceTableEntry containing a value of FALSE.

HubChangeEnumNextHub:
	mov	si, offset DeviceTable	;SI = ptr to DeviceTable[0]
	add	si, size DeviceTableEntry ;SI = ptr to DeviceTable[1]
	xor	bl, bl			;BL = Flag: 0 if all hubs have enumerated

HubChangeNextDTE:
	cmp	(DeviceTableEntry ptr [si]).Present, TRUE
	jne	HubChangeSkipDTE	;Br if this DeviceTableEntry is not in use
	cmp	(DeviceTableEntry ptr [si]).BiosDeviceType, BIOS_DEV_TYPE_HUB
	jne	HubChangeSkipDTE	;Br if this DeviceTableEntry is not a hub
	cmp	(DeviceTableEntry ptr [si]).HubEnumFlag, TRUE
	je	HubChangeSkipDTE	;Br if this hub has already been enumerated

	mov	bl, 1			;Indicate that not all hubs have been enumerated
	mov	al, (DeviceTableEntry ptr [si]).DeviceAddress ;AL = Device address of hub
	mov	ah, 1			;AH will count ports on hub (1..n)
HubChangeNextPort:
	mov	bh, 00h			;Ignore connect status change bit
	call	ProcessSingleHubPortChange ;Handle change on hub/port AL/AH
	inc	ah
	cmp	ah, (DeviceTableEntry ptr [si]).HubNumPorts
	jbe	HubChangeNextPort	;Br if more ports on hub to check

	mov	(DeviceTableEntry ptr [si]).HubEnumFlag, TRUE ;Flag hub's ports as enumerated

HubChangeSkipDTE:
	add	si, size DeviceTableEntry
	cmp	si, offset DeviceTableEnd
	jb	HubChangeNextDTE	;Br if more entries to check

	or	bl, bl
	jnz	HubChangeEnumNextHub	;Br if all hubs are not yet enumerated

	popa
	ret
UsbHubPortChange	endp


;---------------------------------------;
; ProcessSingleHubPortChange            ;
;---------------------------------------;--------------------------------------;
; This function is called when a change in connect status is detected on any   ;
; port of any hub (including the root hub).  Connect status changes are caused ;
; by devices being plugged in or removed from the USB.  This routine handles   ;
; the addtion or subtraction of new devices.                                   ;
;                                                                              ;
; Input: AL = USB Device address of hub whose status has changed               ;
;             00 - 7F = Device address of hub on the USB                       ;
;             80 - FE = Reserved                                               ;
;             FF      = Root hub                                               ;
;        AH = Port number within hub whose status has changed                  ;
;        BH = 00: This hub port is being checked for the first time so ignore  ;
;                 the hub's connect status change bit (enumerate the port even ;
;                 if the hub says that the connect status has not changed)     ;
;             01: This hub port has been checked before, do not ignore the     ;
;                 connect status change bit                                    ;
;                                                                              ;
; Output: Nothing                                                              ;
;                                                                              ;
; Destroys: Nothing                                                            ;
;------------------------------------------------------------------------------;
ProcessSingleHubPortChange	proc near
	pusha
	push	ds
	push	es

	test	InitializationFlags, INIT_FLAG_ENUM_DISABLE
	jnz	PortChangeDone		;Br if USB enum is disabled

	call	UsbGetHubPortStatus	;Returns BL=Flags, CF
	jc	PortChangeDone		;Br if error or no change in connect status

	or	bh, bh
	jz	@f			;Br if connect change bit should be ignored
	test	bl, 00000100b		;Test connect status change bit
	jz	PortChangeDone		;Br if connect status has not changed
@@:

	test	bl, 00000001b		;Test device connected bit
	jz	PortChangeDisconnect	;Br if device has been disconnected

	call	UsbDetectNewDevice	;Handle attachment of a new device
	jmp	short PortChangeDone

; A device has been disconnected from the USB.  First disable the hub port
; that the device was plugged into.  Then free up the device's entry in the
; DeviceTable.  If there an error occurs while disabling the port, assume
; that the device is still present an leave its DeviceTable entry in place.

PortChangeDisconnect:
	call	UsbDisableHubPort
	jc	PortChangeDone

	call	ShutdownDevice		;Shutdown device and any children

	mov	ah, 8			;Issue disconnect beep (low & short)
	mov	cx, 1000h
	call	SpeakerBeep

PortChangeDone:
	pop	es
	pop	ds
	popa
	ret
ProcessSingleHubPortChange	endp


;---------------------------------------;
; ShutdownDevice                        ;
;---------------------------------------;--------------------------------------;
; This function is called when a device disconnect is detected.  This routine  ;
; stops polling on the device, frees its DeviceTable entry, and notifies the   ;
; keyboard/mouse code that the device is gone.  This routine also recursively  ;
; processes any childs devices if a hub is disconnected.                       ;
;                                                                              ;
; Input: AL = USB Device address of hub that detected the diconnect            ;
;             00 - 7F = Device address of hub on the USB                       ;
;             80 - FE = Reserved                                               ;
;             FF      = Root hub                                               ;
;        AH = Port number within hub that detected the diconnect               ;
;                                                                              ;
; Output: Nothing                                                              ;
;                                                                              ;
; Destroys: Nothing                                                            ;
;------------------------------------------------------------------------------;
ShutdownDevice proc near
	push	si

	mov	si, offset DeviceTable	;SI = ptr to DeviceTableEntry[0]
	add	si, size DeviceTableEntry ;Point to DeviceTableEntry[1]

DisCheckNextEntry:
	cmp	(DeviceTableEntry ptr [si]).Present, TRUE
	jne	SkipEntry		;Br if unused entry
	cmp	word ptr ((DeviceTableEntry ptr [si]).HubDeviceNumber), ax
	jne	SkipEntry		;Br if this entry not for this hub/port

	cmp	(DeviceTableEntry ptr [si]).BiosDeviceType, BIOS_DEV_TYPE_HUB
	jne	DisconnectChildrenDone	;Br if device is not a hub

; A hub device is being disconnected.  For each of the hub's ports disconnect
; any child device connected.

	push	ax
	mov	al, (DeviceTableEntry ptr [si]).DeviceAddress ;AL = device address
	mov	ah, 1			;AH will count through hub ports

DisconnectNextPort:
	call	ShutdownDevice		;Disconnect device and any children
	inc	ah
	cmp	ah, (DeviceTableEntry ptr [si]).HubNumPorts
	jbe	DisconnectNextPort	;Br if still more ports to disconnect
	pop	ax

; Now free the device table entry for this device, stop polling for this device,
; and notify the keyboard/mouse code that the device is gone (if the device is
; a keyboard or mouse).

DisconnectChildrenDone:	
	mov	(DeviceTableEntry ptr [si]).Present, FALSE ;Mark entry as unused
	call	_UsbDeactivatePolling	;Stop polling for DeviceTableEntry[SI]

	cmp	(DeviceTableEntry ptr [si]).BiosDeviceType, BIOS_DEV_TYPE_KEYBOARD
	je	@F			;Br if disconnected device is keyboard
	cmp	(DeviceTableEntry ptr [si]).BiosDeviceType, BIOS_DEV_TYPE_MOUSE
	jne	SkipEntry		;Br if disconnected device is not mouse
@@:
	push	ax
	mov	al, (DeviceTableEntry ptr [si]).DeviceAddress ;AL = device address
	mov	ah, (DeviceTableEntry ptr [si]).BiosDeviceType	
	call	DisconnectDevice	;Notify keyboard/mouse code of disconnect
	pop	ax

SkipEntry:
	add	si, size DeviceTableEntry ;Point to next DeviceTableEntry
	cmp	si, offset DeviceTableEnd
	jb	DisCheckNextEntry		;Br if more entries in DeviceTable

	pop	si
	ret
ShutdownDevice	endp


;---------------------------------------;
; UsbDetectNewDevice                    ;
;---------------------------------------;--------------------------------------;
; This function is called when a new device is plugged into a port on a hub.   ;
; The hub may be a normal USB hub or the root hub.  This function does the     ;
; following:                                                                   ;
;                                                                              ;
; 1. Set the DeviceTable entry for device 0 to be the same speed as the        ;
;    new device                                                                ;
; 2. Find a free entry in the DeviceTable (the position in the DeviceTable     ;
;    array is the same as the new device address for the device)               ;
; 3. Enable the port on the hub                                                ;
; 4. Send a GetDescriptor (Device Descriptor) command to the device using an   ;
;    assumed MaxPacket size of 128 bytes, and make note of the actual MaxPacket;
;    size returned in the descriptor data                                      ;
; 5. Reset th hub port to handle any noncompliant devices                      ;
; 6. Send a SetAddress command to the device to set it to its new address      ;
; 7. Send a GetDescriptor command to the device to get its Device descriptor   ;
; 8. Use GetConfiguration commands to search for a configuration that includes ;
;    an interface type that the BIOS can use (keyboard, mouse, or hub).        ;
; 9. Use the data returned in the Device descriptor to fill in the DeviceTable ;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -