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

📄 uhci_bb.asm

📁 dos下的USB源码(包括UHCI
💻 ASM
📖 第 1 页 / 共 4 页
字号:
; Output: 	ZR	On error
;		NZ	On success
;
; Modified:	Nothing
;
; Referrals:	UHCI_TD
;
; Notes:	This routine creates 1ms and 8ms schedules
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>

UHCIBB_StartTDSchedule	PROC NEAR PUBLIC

	pushad
	push	es

; Schedule the TDs

; Make QHControl link pointer to null
	mov	di, OFFSET QHControl
	mov	(UHCI_QH PTR [di]).LinkPointer, UHCI_TERMINATE

; Form the initial values for the loop
	push	USB_DATA
	pop	es
	xor	di, di
	mov	cx, CurrentHC.wAsyncListSize
	cld

; The TD schedule should be added in proper order otherwise the
; links will get garbled. The proper order is to add all the 1ms TDs,
; followed by 2ms, 8ms and finally 256ms TD.

UBSTS_FrameListInitLoop:

;;; Schedule the QHControl for 1ms
;;	mov	si, OFFSET QHControl
;;; ES:DI	Frame list pointer index
;;; SI	TD to add
;;	call	UHCIBB_AddTD

; Check for 8ms TD schedule
	test	cx, 007h
	jnz	UBSTS_Continue

IF	MKF_USB_BB_DEV_KBD
; Yes. Schedule the TDKeyboard for 8ms
	mov	si, OFFSET TDKeyboard
; ES:DI	Frame list pointer index
; SI		TD to add
	call	UHCIBB_AddTD
ENDIF	;; IF	MKF_USB_BB_DEV_KBD

UBSTS_Continue:
	add	di, 4
	loop	UBSTS_FrameListInitLoop

; Success. Clear the zero flag
	or	sp, sp

	pop	es
	popad
	ret
UHCIBB_StartTDSchedule	ENDP


;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	UHCIBB_AddTD
;
; Description:	This function adds a TD to the frame list
;
; Input: 	SI	Pointer to the TD to be added
;        	ES:DI	Pointer to the frame list
;
; Output: 	Nothing
;
; Modified:	Nothing
;
; Referrals:	UHCI_TD
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>

UHCIBB_AddTD		PROC NEAR 

	push	eax
	push	edx
	push	esi

; Load parameters to registers
	movzx	esi, si

; Get current frame list pointer address
	mov	edx, DWORD PTR ES:[di]

; Form the 32bit absolute TD address
	push	ds
	pop	ax
	movzx	eax, ax
	shl	eax, 4
	add	eax, esi

; Save it in the current frame list pointer
	mov	DWORD PTR ES:[di], eax

; Link the old frame list pointer address in the link pointer of TD
	mov	(UHCI_TD PTR [si]).LinkPointer, edx

	pop	esi
	pop	edx
	pop	eax
	ret
UHCIBB_AddTD		ENDP

;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	UHCIBB_ControlTransfer
;
; Description:	This function executes a control transaction on the USB. 
;		One setup packet is generated containing the device request 
;		parameters supplied by the caller.  The setup packet may be 
;		followed by data in or data out packets containing data sent 
;		from the host to the device or vice-versa. This function 
;		will not return until the request either completes 
;		successfully or completes in error (due to time out, etc.)
;
; Input:	SI	Pointer to the DeviceInfo structure
;		The device info structure has the necessary information for
;		the control transfer:
;		CntrlXfer.wRequest	Request type (low byte)
;					Bit 7   : Data direction
;						0 = Host sending data to device
;						1 = Device sending data to host
;					Bit 6-5 : Type
;						00 = Standard USB request
;						01 = Class specific
;						10 = Vendor specific
;					11 = Reserved
;					Bit 4-0 : Recipient
;						00000 = Device
;						00001 = Interface
;						00010 = Endpoint
;						00100 - 11111 = Reserved
;					Request code (high byte), a one byte 
;					code describing the actual device 
;					request to be executed (ex: Get 
;					Configuration, Set Address etc)
;		CntrlXfer.wIndex	wIndex request parameter (meaning varies)
;		CntrlXfer.wValue	wValue request parameter (meaning varies)
;		CntrlXfer.fpBuffer	Data buffer pointer
;		CntrlXfer.wLength	Number of bytes of data to be transferred
;
; Output: 	NZ	On successfull completion
;		ZR	On error
;
; Modified:	None
;
; Referrals:	DeviceInfo
;
; Notes:	Endpoint is always assumed as 0 for control transfer
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>

UHCIBB_ControlTransfer	PROC NEAR SYSCALL PUBLIC

	push	es
	pushad

; Build the device request in the data area of the control setup TD
	mov	di, OFFSET TDControlSetup.DataArea
	call	USBBB_CopyDeviceRequest

; Set the global temp variables for code size reduction
	xor	ecx, ecx
	mov	cx, (DeviceInfo PTR [si]).CntrlXfer.wLength

; EDX will contain the device address and endpoint shifted and ready to go
; into the TDs' token field.
	xor	eax, eax		; EAX[3:0] = Endpoint (00-0Fh)
;;	shl	eax, 7			; EAX[10:7] = Endpoint (00-0Fh)
	or	al, (DeviceInfo PTR [si]).bDeviceAddress
					; EAX[10:0] = Dev. Addr & Endpoint
	shl	eax, 8			; EAX[18:8] = Dev. Addr & Endpoint
	mov	edx, eax

; Fill in various fields in the control setup TD.
; The LinkPointer field will point to the control data TD if data will
; be sent/received or to the control status TD if no data is expected.
; The ControlStatus field will be set to active and interrupt on complete.
; The Token field will contain the packet size (size of DeviceRequest
;  struc), the device address, endpoint, and a setup PID.
; The BufferPointer field will point to the TD's DataArea buffer which
;  was just initialized to contain a DeviceRequest struc.
; The CSReloadValue field will contain 0 because this is a "one shot" packet.
; The pCallback will be set to point to the UHCI_ControlTDCallback routine.
; The ActiveFlag field will be set to TRUE.

	mov	di, OFFSET TDControlSetup

; Fill common control transfer fields (ControlStatus, call back routine,
; CSReloadValue and Active flag fields)
	call	UHCIBB_FillCntrlXferFields	; SI-DevInfo, DI-TD

	mov	eax, edx
		; EAX[18:8] = Device address / endpoint
	or	eax, SETUP_PACKET OR ((SIZE DeviceRequest - 1) shl 21)
		; Set PID=Setup, and MaxLen
	mov	(UHCI_TD PTR [di]).Token, eax

	mov	eax, OFFSET TDControlSetup.DataArea
	add	eax, dGlobalDataArea	;EAX = abs addr of TD's data buffer
	mov	(UHCI_TD PTR [di]).BufferPointer, eax

; Fill in various fields in the control data TD.  Enough control data TDs
; must be initialized to handle the amount of data expected.  The length
; of the data transfer is currently in wLength.
; LinkPointer field will be set to the next data TD or the status TD.
; ControlStatus field will be se to active and interrupt on complete.
; Token field will contain the data transfer size (still in wLength), device
; address (in pDevInfo), endpoint (in dTemp), and an in or out PID
; (in wReqType).
; BufferPointer field will point to the data buffer passed in by the
; caller (currently in EDX).
; CSReloadValue field will contain 0 because this is a "one shot" packet.
; pCallback will be set to point to the UHCI_ControlTDCallback routine.
; ActiveFlag field will be set to TRUE.

	or	cx, cx
	jz	UBCT_SkipDataTds		; No data to transfer

	cmp	cx, MAX_CONTROL_DATA_SIZE
	jb	UBCT_DataSizeOkay		; Data size within limit
	mov	cx, MAX_CONTROL_DATA_SIZE	; Limit the data size
UBCT_DataSizeOkay:

	mov	bx, OFFSET TDData	; BX - Pointer to control
						; data TD
; DI = PTR of TD control data
	or	ecx, BIT16		; Start with a data 1 token

UBCT_NextDataTd:

; Link the new TD to the previous TD
	movzx	eax, bx
	add	eax, dGlobalDataArea
; Set the vertical flag
	or	eax, UHCI_VERTICAL_FLAG
	mov	(UHCI_TD PTR [di]).LinkPointer, eax
	mov	di, bx
	mov	eax, (DeviceInfo PTR [si]).CntrlXfer.fpBuffer
	mov	(UHCI_TD PTR [di]).BufferPointer, eax

	movzx	eax, cx				;  Data length
	cmp	ax, (DeviceInfo PTR [si]).wEndp0MaxPacket
	jbe	UBCT_PktSizeAdjusted		; Packet size is valid
	mov	ax, (DeviceInfo PTR [si]).wEndp0MaxPacket
UBCT_PktSizeAdjusted:
	sub	cx, ax				; Adjust overall data size
	add	(DeviceInfo PTR [si]).CntrlXfer.fpBuffer, eax	; Adjust buffer pointer
	dec	ax				; AX = packet data size - 1
	shl	eax, 21

	or	eax, edx			; EAX[18:8]=Dev. addr & endp
	mov	al, OUT_PACKET			; EAX[7:0] = OUT PID
	test	(DeviceInfo PTR [si]).CntrlXfer.wRequest, BIT7
	jz	UBCT_PIDFound			; OUT PID
	mov	al, IN_PACKET			; EAX[7:0] = IN PID
UBCT_PIDFound:
	test	ecx, BIT16
	jz	UBCT_DataToggle			; DATA0 packet
	or	eax, DATA_TOGGLE		; Make packet into a data 1
UBCT_DataToggle:
	mov	(UHCI_TD PTR [di]).Token, eax

; Fill common control transfer fields (ControlStatus, call back routine,
; CSReloadValue and Active flag fields)
	call	UHCIBB_FillCntrlXferFields	; SI-DevInfo, DI-TD
; Enable short packet detect
	or	(UHCI_TD PTR [di]).ControlStatus, UHCI_TD_SHORT_PACKET_DETECT

	xor	ecx, BIT16			; Toggle between DATA1/DATA0

	add	bx, SIZE UHCI_TD		; Point BX to next TD

	or	cx, cx
	jnz	UBCT_NextDataTd			; More data TDs must be built

;; End the data TD list
	mov	(UHCI_TD PTR [di]).LinkPointer, UHCI_TERMINATE

UBCT_SkipDataTds:

; Make the next TD to point to the TD control status
	mov	eax, OFFSET TDControlStatus
	add	eax, dGlobalDataArea
	mov	(UHCI_TD PTR [di]).LinkPointer, eax

; DI = PTR of TD control status
	mov	di, OFFSET TDControlStatus
; Fill in various fields in the TD control status.
; LinkPointer field will point to TERMINATE.
; ControlStatus field will be set to active and interrupt on complete.
; Token field will contain the packet size (0), the device address,
; endpoint, and a setup PID with opposite data direction as that defined
; in the request type (wReqType).
; BufferPointer field will point to the TD's DataArea buffer even though
; we are not expecting any data transfer.
; CSReloadValue field will contain 0 because this is a "one shot" packet.
; pCallback will be set to point to the UHCI_ControlTDCallback routine.
; ActiveFlag field will be set to TRUE.
	mov	(UHCI_TD PTR [di]).LinkPointer, UHCI_TERMINATE

	mov	eax, edx		; EAX[18:8] = Device address / endpoint
	mov	al, OUT_PACKET		; EAX[7:0] = OUT PID
	test	(DeviceInfo PTR [si]).CntrlXfer.wRequest, BIT7
	jnz	UBCT_StatPIDFound	; IN PID
	mov	al, IN_PACKET		; EAX[7:0] = IN PID
UBCT_StatPIDFound:
	or	eax, (DATA_TOGGLE OR (UHCI_TD_DATA_LENGTH SHL 21))	; DATA0/DATA1
	mov	(UHCI_TD PTR [di]).Token, eax

	mov	eax, OFFSET TDControlStatus.DataArea
	add	eax, dGlobalDataArea		; EAX = abs addr of TD's data buffer
	mov	(UHCI_TD PTR [di]).BufferPointer, eax

; Fill common control transfer fields (ControlStatus, call back routine,
; CSReloadValue and Active flag fields)
	call	UHCIBB_FillCntrlXferFields	; SI-DevInfo, DI-TD

; Now put the control setup, data and status into the HC's schedule by
; pointing QhControl's element pointer to control setup TD.
; This will cause the HC to execute the transaction in the next active frame.
	mov	si, OFFSET QHControl
	mov	edi, OFFSET TDControlSetup
	add	edi, dGlobalDataArea
	mov	(UHCI_QH PTR [si]).ElementPointer, edi

; Now wait for the control status TD to complete.  When it has completed,
; the UHCI_ControlTDCallback will set its active flag to FALSE.

	mov	di, OFFSET TDControlStatus	; Control status TD pointer
	call	UHCIBB_WaitForTransferComplete

; Remove the control setup, data, and status TDs from the
; HC's schedule by pointing QhControl's link pointer to UHCI_TERMINATE.
	push	di
	mov	di, OFFSET QHControl
	mov	(UHCI_QH PTR [di]).ElementPointer, UHCI_TERMINATE
	pop	di

; Finally check for any error bits set in both the TdControlStatus.
; If the TD did not complete successfully, return errors status.
	test	(UHCI_TD PTR [di]).ControlStatus, (UHCI_TD_BITSTUFF_ERROR OR \
			UHCI_TD_CRC_TIMEOUT_ERROR OR UHCI_TD_NAK_RECEIVED OR \
			UHCI_TD_BABBLE_DETECTED OR UHCI_TD_DATA_BUFFER_ERROR OR UHCI_TD_STALLED)
	jnz	UBCT_ErrorExit		; Br if any error bits set in status

; Return success (Clear Zero flag)
	or	sp, sp	
	jmp	SHORT UBCT_Exit

UBCT_ErrorExit:

; Error! Set zero flag
	cmp	sp, sp

UBCT_Exit:
	popad
	pop	es
	ret

UHCIBB_ControlTransfer	ENDP

;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	UHCIBB_BulkTransfer
;
; Description:	This function executes a bulk transaction on the USB. The
;		transfer may be either DATA_IN or DATA_OUT packets containing
;		data sent from the host to the device or vice-versa. This
;		function wil not return until the request either completes
;		successfully or completes with error (due to time out, etc.)
;
; Input:	DL	Transfer direction
;			Bit 7	: Data direction
;				  0 Host sending data to device
;				  1 Device sending data to host
;			Bit 6-0 : Reserved
;		EDI	Buffer containing data to be sent to the device or
;			buffer to be used to receive data. Value in 32 bit
;			absolute address
;		CX	Number of bytes of data to be transferred in or out
;			of the host controller
;
; Output: 	ZR	On error
;		NZ	On success
;			AX	Amount of data transferred
;
; Modified:	EAX
;
; Notes:	Make sure that amount of bytes to transfer should not exceed 
;		MAX_UHCI_BULK_DATA_SIZE
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>

; Bulk transfer related global temporary variables
dUHCIControlStatus	DWORD		?
dUHCIToken		DWORD		?

UHCIBB_BulkTransfer	PROC NEAR SYSCALL

	push	fs
	pushad

	push	0
	pop	fs
; Check for 0 length transfer (if so, exit)
	or	cx, cx
	jz	UBBT_Success

; Get Bulk IN/OUT enpoint number, data sync value & max packet size
	call	USBMBB_GetBulkEndPointInfo
; AX	Max packet value
; BL	Endpoint number
; BH	Data sync value
; Store the appropriate max packet size and endpoint number
; in the local variables
	push	ax		; Save max packet size

; Form device address and endpoint in proper order and bit position
	movzx	eax, bl			; EAX[3:0] = Endpoint
	shl	eax, 7			; EAX[10:7] = Endpoint
	mov	esi, eax
	movzx	eax, CurrentDevice.bDeviceAddress
	or	eax, esi		; EAX[10:0] = Dev. Addr & Endpoint
	shl	eax, 8			; EAX[18:8] = Dev. Addr & Endpoint
	mov	dUHCIToken, eax

	mov	al, OUT_PACKET			; EAX[7:0] = OUT PID
	test	dl, BIT7
	jz	UBBT_PIDFound			; OUT PID
	mov	al, IN_PACKET			; EAX[7:0] = IN PID
UBBT_PIDFound:

	test	bh, 1
	jz	UBBT_DataToggle			; DATA0 packet
	or	eax, DATA_TOGGLE		; Make packet into a data 1
UBBT_DataToggle:
	or	dUHCIToken, eax

	pop	si		; Restore max packet size

; Form control status
	movzx	eax, CurrentDevice.bEndPointSpeed
	; AL = 11/01/10 for HI/LO/FULL
	and	al, 1				; Mask off MSH
	shl	eax, 26
	or	eax, (UHCI_TD_INTERRUPT_ON_COMPLETE OR UHCI_TD_THREE_ERRORS OR UHCI_TD_ACTIVE OR \
				UHCI_TD_SHORT_PACKET_DETECT)
	mov	dUHCIControlStatus, eax


; Save the buffer pointer in EBX
	mov	ebx, edi		; Buffer pointer

; Form the bulk data TDs
	mov	di, OFFSET TDData

UBBT_PrepareNextBulkTD:

; Form pointer to the next TD and link it in the current TD
	movzx	eax, di
	add	eax, SIZE UHCI_TD
	add	eax, dGlobalDataArea
; Set the vertical flag
	or	eax, UHCI_VERTICAL_FLAG
	mov	(UHCI_TD PTR [di]).LinkPointer, eax

⌨️ 快捷键说明

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