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

📄 usbbb.asm

📁 dos下的USB源码(包括UHCI
💻 ASM
📖 第 1 页 / 共 4 页
字号:
	mov	al, (HubDescriptor ptr [di]).bNumPorts
					; AL = # of ports on hub
	mov	CurrentDevice.bHubNumPorts, al

	mov	al, (HubDescriptor ptr [di]).bPowerOnDelay
					; AL = Port power on delay
	mov	CurrentDevice.bHubPowerOnDelay, al

; Increment the hub device entry count
	inc	bCurrentHubDeviceEntry

; Port is in USB hub. Copy the device info into the free entry (already made sure
; the entry is free during hub enumeration done below)
	push	cx

; Free entry found get the offset in DI
	mov	di, OFFSET HubDeviceTable
	movzx	ax, bCurrentHubDeviceEntry
	mov	cl, SIZE DeviceInfo
	mul	cl
	add	di, ax
; Save the offset in pCurrentHub pointer
	mov	pCurrentHub, di
	
; Copy the current device information into a new hub structure
	mov	si, OFFSET CurrentDevice

	push	es

	push	ds
	pop	es
	cld
	mov	cx, SIZE DeviceInfo
	rep	movsb

	pop	es

; Set SI to the new hubs device info structure
	mov	si, pCurrentHub
; Set CL to the number of ports in the hub
	mov	cl, CurrentDevice.bHubNumPorts
; Enumerate the ports in the hub
	call	USBBB_EnumerateHubPorts
	pop	cx		; Restore the port number we are 
				; currently processing
	jnz	UBEHP_ValidDeviceFound

; No valid device found in the hub
; We are going to disable this port. Free the entry used for this device
; Decrement the hub device entry count
	dec	bCurrentHubDeviceEntry

UBEHP_DeviceInitFailed:
; Decrement device address
	dec	bCurrentDeviceAddress

; We have to set the SI with appropriate device info value.
; If this hub is connected to the root hub directly then 
; dCurrentHubDeviceEntry value will be 0FFh. Otherwise it will hold the index
; value into the hub device table that holds the device information for 
; the hub to which this hub is connected.
	mov	si, OFFSET CurrentDevice

	cmp	bCurrentHubDeviceEntry, 0FFh
	je	UBEHP_Done

	push	cx
; Get the right SI value
	mov	si, OFFSET HubDeviceTable
	movzx	ax, bCurrentHubDeviceEntry
	mov	cl, SIZE DeviceInfo
	mul	cl
	add	si, ax
	pop	cx

UBEHP_Done:
; No device found. Set the zero flag
	cmp	sp, sp
	jmp	SHORT UBEHP_Exit

UBEHP_CheckForCurrentDeviceType:

; Check the device type
	cmp	dl, CS:bCurrentDeviceType
	jne	UBEHP_DisableHubPort

; Configure the device by setting address & configuration
	call	USBBB_ConfigureUSBDevice
	jz	UBEHP_DisableHubPort

	push	CS:pDeviceInitializer
	pop	ax
	or	ax, ax
	jz	UBEHP_DisableHubPort
	call	ax
	jz	UBEHP_DisableHubPort	; Not configured

; Indicate as the device configured
UBEHP_ValidDeviceFound:
	or	sp, sp

UBEHP_Exit:
	popa
	ret
USBBB_EnumerateHubPorts		ENDP

IF	MKF_USB_BB_DEV_KBD
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	USBBB_ConfigureKeyboard
;
; Description:	This function will configure the keyboard found
;
; Input: 	DS	USB data area
;
; Output: 	ZR	Error
;		NZ	Successful completion
;
; Modified:	None
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>

USBBB_ConfigureKeyboard		PROC NEAR PUBLIC

	push	ax
	push	bx
	push	si
; Set SI to the current devices device info structure
	mov	si, OFFSET CurrentDevice

; Send the HID SET_IDLE request
; wValue = 0 (Indefinite) - Soft Model Keyboard needs this modification
; Also Windows use this value and it works for all the keyboards
	xor	ax, ax
	mov	CurrentDevice.CntrlXfer.wValue, ax
	mov	CurrentDevice.CntrlXfer.wIndex, ax
	mov	CurrentDevice.CntrlXfer.wRequest, HID_RQ_SET_IDLE
	call	USBBB_IssueControlXferWithoutData
	jz	UBCK_Exit

; Send the set protocol command
; wValue = 0 (Boot protocol)
	mov	CurrentDevice.CntrlXfer.wRequest, HID_RQ_SET_PROTOCOL
	call	USBBB_IssueControlXferWithoutData
	jz	UBCK_Exit

; Activate the polling
	mov	bx, CurrentHC.pHCDPointer
	call	(BBHCDHEADER PTR CS:[bx]).pHCDActivateKeyboardPolling
; Return status in zero flag

UBCK_Exit:
	pop	si
	pop	bx
	pop	ax
	ret
USBBB_ConfigureKeyboard		ENDP
ENDIF	;; IF		MKF_USB_BB_DEV_KBD


;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	USBBB_GetDeviceType
;
; Description:	This function will get the device descriptor from the device
;		connected and return the type of the device present
;
; Input: 	DS	USB data area
;		SI	Pointer to the device information structure
;		All the HC & device specific variables are set
;
; Output: 	ZR	Error
;		NZ	Successful completion
;			DL	Device type
;
; Modified:	DL
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>

USBBB_GetDeviceType		PROC NEAR PUBLIC

	push	eax
	push	bx
	push	cx
	push	si
	push	di
	push	edx

; Set current device type as 0
	mov	dl, 00h

; Check the validity of the HCD pointer
	mov	bx, CurrentHC.pHCDPointer 
	or	bx, bx
	jz	UBGDT_Exit

; Set SI to the CurrentDevice device info structure
	mov	si, OFFSET CurrentDevice

; Form the far buffer pointer
	mov	di, OFFSET ControlDataBuffer
	movzx	edx, di
	add	edx, dGlobalDataArea

; Send a GetDescriptor command to the device to get its Device
; Descriptor. Assume a MaxPacket size of 64 bytes (the device will use 8,
; 16, 32, or 64). Regardless of the packet size used by te device we can
; always get the real MaxPacket size that the device is using, because
; this piece of information is at offset 7 in the device descriptor.
	mov	CurrentDevice.CntrlXfer.wLength, 8
	mov	CurrentDevice.CntrlXfer.wIndex, 0
	mov	CurrentDevice.CntrlXfer.wValue, (DESC_TYPE_DEVICE SHL 8)
	mov	CurrentDevice.CntrlXfer.wRequest, USB_RQ_GET_DESCRIPTOR
	mov	CurrentDevice.CntrlXfer.fpBuffer, edx

; Issue the HCD control transfer call
	call	(BBHCDHEADER PTR CS:[bx]).pHCDControlTransfer
	jz	UBGDT_Exit

; Get and store the endpoint 0 max packet size
	movzx	ax, (DeviceDescriptor PTR [di]).bEndp0MaxPacket
	mov	CurrentDevice.wEndp0MaxPacket, ax

; Give some delay
	mov	cx, ((10 * 1000) / 15)	; 10ms delay
	call	fixed_delay_far

; Now send a GetDescriptor command to the device to get its device descriptor.
	mov	CurrentDevice.CntrlXfer.wLength, 18
	mov	CurrentDevice.CntrlXfer.fpBuffer, edx
; Issue the HCD control transfer call
	call	(BBHCDHEADER PTR CS:[bx]).pHCDControlTransfer
	jz	UBGDT_Exit

; Get the relevant information from the descriptor and store it in
; device information struture
	mov	eax, DWORD PTR (DeviceDescriptor PTR [di]).wVendorId
	mov	DWORD PTR CurrentDevice.wVendorId, eax

; Look at each of the device's ConfigDescriptors and InterfaceDescriptors
; until an InterfaceDescriptor is found with BaseClass, SubClass, and
; Protocol fields indicating boot keyboard, mouse, hub or storage support.
	mov	al, (DeviceDescriptor PTR [di]).bNumConfigs
	mov	CurrentDevice.bNumConfigs, al

; Start with configuration number 0
	mov	CurrentDevice.bConfigNum, 0

; ASSUME THAT WE ARE GOING TO HANDLE ONLY ONE CONFIGURATION
	mov	CurrentDevice.CntrlXfer.wLength, (MAX_CONTROL_DATA_SIZE - 1)
	mov	ah, DESC_TYPE_CONFIG
	mov	al, CurrentDevice.bConfigNum
	mov	CurrentDevice.CntrlXfer.wValue, ax
	mov	CurrentDevice.CntrlXfer.fpBuffer, edx
; Issue the HCD control transfer call
	call	(BBHCDHEADER PTR CS:[bx]).pHCDControlTransfer
	jz	UBGDT_Exit

; DI should now point to a ConfigDescriptor.  Verify this and then get 
; necessary information out of this descriptor.  Then point to the next 
; descriptor.
	cmp	(ConfigDescriptor PTR [di]).bDescType, DESC_TYPE_CONFIG
	jne	UBGDT_SkipConfig		; Br if device did not return config desc

	mov	al, (ConfigDescriptor PTR [di]).bConfigValue ;AL = Config value
	mov	CurrentDevice.bConfigNum, al

	mov	cx, (ConfigDescriptor PTR [di]).wTotalLength
	cmp	cx, (MAX_CONTROL_DATA_SIZE - 1)	; CX	Amount of data returned
	jb	UBGDT_NotOverFlowed
	mov	cx, (MAX_CONTROL_DATA_SIZE - 1)	; Limit size of data to what we can handle
UBGDT_NotOverFlowed:

; Convert size to end offset
	add	cx, di

	movzx	ax, (ConfigDescriptor PTR [di]).bDescLength
	add	di, ax

; DI should now point to an InterfaceDescriptor.  Verify this
; and then check its BaseClass, SubClass, and Protocol fields for
; usable devices.

UBGDT_NextInterface:
	cmp	(InterfaceDescriptor PTR [di]).bDescType, DESC_TYPE_INTERFACE
	jne	UBGDT_SkipInterface	;Br if not on an interface desc

	mov	al, (InterfaceDescriptor PTR [di]).bInterfaceNum
	mov	CurrentDevice.bInterfaceNum, al
	mov	al, (InterfaceDescriptor PTR [di]).bAltSettingNum
	mov	CurrentDevice.bAltSettingNum, al

; Check for non-compliant USB devices
	call	USBBB_CheckNonCompliantDevice

; Get the base, sub class & protocol values
	mov	eax, DWORD PTR (InterfaceDescriptor PTR [di]).bBaseClass
; Clear the top 8 bits
	and	eax, 000FFFFFFh

IF	MKF_USB_BB_DEV_KBD
	mov	dl, BIOS_DEV_TYPE_KEYBOARD		; Assume as keyboard
; First check for keyboard
	cmp	eax, (PROTOCOL_KEYBOARD SHL 16) + (SUB_CLASS_BOOT_DEVICE SHL 8) + BASE_CLASS_HID
	je	UBGDT_DeviceFound
ENDIF	;; IF	MKF_USB_BB_DEV_KBD

	mov	dl, BIOS_DEV_TYPE_HUB			; Assume as hub
; Check for hub
	cmp	al, BASE_CLASS_HUB
	je	UBGDT_DeviceFound

	mov	dl, BIOS_DEV_TYPE_STORAGE
; Check for BaseClass mass storage
	cmp	al, BASE_CLASS_MASS_STORAGE
	jne	UBGDT_SkipInterface

	ror	eax, 16
; Base class is okay. Check the protocol field for supported protocols.
; Currently we support CBI, CB and BOT protocols
	cmp	al, PROTOCOL_CBI
	je	UBGDT_DeviceFound
	cmp	al, PROTOCOL_CBI_NO_INT
	je	UBGDT_DeviceFound
	cmp	al, PROTOCOL_BOT
	je	UBGDT_DeviceFound

UBGDT_SkipInterface:

	movzx	ax, (ConfigDescriptor PTR [di]).bDescLength ;AX = next desc
	or	ax, ax
	jz	UBGDT_SkipConfig		; Br if 0 length desc (should never happen, but...)
	add	di, ax				; BX	Pointer to next desc
	cmp	di, cx
	jae	UBGDT_SkipConfig		; End of data
	jmp	SHORT UBGDT_NextInterface

UBGDT_DeviceFound:

; Store the sub class & protocol information
	mov	ax, WORD PTR (InterfaceDescriptor PTR [di]).bSubClass
	mov	stMassDeviceInfo.bSubClass, al
	mov	stMassDeviceInfo.bProtocol, ah

; Update the endpoints
; Adjust BX so that ES:DI+BX points to the next descriptor, abort if we're
; past the end of the data.
	movzx	ax, (InterfaceDescriptor PTR [di]).bDescLength
	add	di, ax			; DI	Pointer to next desc
	cmp	di, cx
	jae	UBGDT_SkipConfig

; DI should now point to an EndpointDescriptor.  If it does not, search
; down until we either find an EndpointDescriptor or go past the
; limit in wEnd.

UBGDT_CheckNextEPDesc :

; If it is interface descriptor then leave
	cmp	(InterfaceDescriptor PTR [di]).bDescType, DESC_TYPE_INTERFACE
	je	UBGDT_Success

	push	dx
	cmp	(EndpointDescriptor PTR [di]).bDescType, DESC_TYPE_ENDPOINT
	jne	UBGDT_FormNextEPDesc

	mov	al, (EndpointDescriptor PTR [di]).bEndpointAddr
	and	al, EP_DESC_ADDR_EP_NUM	; Bit 3-0: Endpoint number
	mov	bx, (EndpointDescriptor PTR [di]).wMaxPacketSize

; Check for endpoint type
	mov	dl, (EndpointDescriptor PTR [di]).bEndpointFlags
	and	dl, EP_DESC_FLAG_TYPE_BITS	; Isolate bits 1,0
	cmp	dl, EP_DESC_FLAG_TYPE_BULK	; Bit 1-0: 10 = Endpoint does bulk transfers
	je	UBGDT_BulkEndpoint

; Otherwise assume as interrupt endpoint
	mov	CurrentDevice.bEndpointNum, al
	mov	CurrentDevice.bIntEndpoint, al
	mov	CurrentDevice.wIntMaxPkt, bx
	jmp	SHORT UBGDT_FormNextEPDesc

UBGDT_BulkEndpoint:
	test	(EndpointDescriptor PTR [di]).bEndpointAddr, \
			EP_DESC_ADDR_DIR_BIT	; Bit 7: Dir. of the endpoint
						;        1/0 = In/Out
	jnz	UMCM_BulkInEndpoint

	mov	CurrentDevice.bBulkOutEndpoint, al
	mov	CurrentDevice.wBulkOutMaxPkt, bx
	jmp	SHORT UBGDT_FormNextEPDesc

UMCM_BulkInEndpoint:
; Bulk-In Endpoint found
	mov	CurrentDevice.bBulkInEndpoint, al
	mov	CurrentDevice.wBulkInMaxPkt, bx

UBGDT_FormNextEPDesc:

	pop	dx
	movzx	ax, (EndpointDescriptor PTR [di]).bDescLength
	or	ax, ax
	jz	UBGDT_Success		; If 0 length desc (should never happen, but...)
	add	di, ax			; BX = Pointer to next desc
	cmp	di, cx
	jb	UBGDT_CheckNextEPDesc	; If not past end of data

UBGDT_Success:
; Return success
	or	sp, sp
	jmp	SHORT UBGDT_Exit

UBGDT_SkipConfig:

	cmp	sp, sp		; Indicate 0	RETURN FAILURE ALWAYS
UBGDT_Exit:
	mov	al, dl
	pop	edx
	mov	dl, al
	pop	di
	pop	si
	pop	cx
	pop	bx
	pop	eax
	ret
USBBB_GetDeviceType		ENDP

;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	USBBB_ConfigureUSBDevice
;
; Description:	This function will set the device address for the USB 
;		device by sending "SET_ADDRESS" command to the device with
;		appropriate device address and also sets the configuration
;		for the device by sending "SET_CONFIGURATION" command with 
;		appropriate config number
;
; Input: 	None
;
; Output: 	ZR	Error during set address/config call
;		NZ	Set address/config are successful
;
; Modified:	Nothing
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>

USBBB_ConfigureUSBDevice	PROC NEAR PUBLIC
	push	eax
	push	si

; Set SI to the current devices device info structure
	mov	si, OFFSET CurrentDevice

; Set address for the device
	movzx	ax, bCurrentDeviceAddress
	inc	ax
	mov	CurrentDevice.CntrlXfer.wValue, ax
	mov	CurrentDevice.CntrlXfer.wIndex, 0
	mov	CurrentDevice.CntrlXfer.wRequest, USB_RQ_SET_ADDRESS
	call	USBBB_IssueControlXferWithoutData
	jz	UBCUD_Exit

; Set device address to the value set
	mov	CurrentDevice.bDeviceAddress, al
	inc	bCurrentDeviceAddress

; Set configuration for the device
	mov	CurrentDevice.CntrlXfer.wRequest, USB_RQ_SET_Configuration
	movzx	ax, CurrentDevice.bConfigNum	; ConfigNum to set
	mov	CurrentDevice.CntrlXfer.wValue, ax
	call	USBBB_IssueControlXferWithoutData

UBCUD_Exit:
	pop	si
	pop	eax
	ret
USBBB_ConfigureUSBDevice	ENDP

;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	USBBB_GetHubDescriptor
;
; Description:	This function will get the hubs descriptor structure from
;		the hub device
;
; Input: 	SI	Pointer to the device information structure
;
; Output: 	ZR	Error during get hub descriptor call
;		NZ	Get hub descriptor call is successful
;			DS:DI	Hub descriptor
;
; Modified:	Nothing
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>

USBBB_GetHubDescriptor	PROC NEAR PUBLIC
	push	eax
	push	bx

; Set buffer address & length
	mov	(DeviceInfo PTR [si]).CntrlXfer.wLength, (MAX_CONTROL_DATA_SIZE - 1)
	mov	di, OFFSET ControlDataBuffer
	movzx	eax, di
	add	eax, dGlobalDataArea
	mov	(DeviceInfo PTR [si]).CntrlXfer.fpBuffer, eax

⌨️ 快捷键说明

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