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

📄 ohci_bb.asm

📁 dos下的USB源码(包括UHCI
💻 ASM
📖 第 1 页 / 共 4 页
字号:
; Set FS:DI to point to the memory base address of the HC
	mov	eax, MKF_USB_BB_MEM_BASE
	shr	eax, 4
	mov	fs, ax
	xor	di, di
	pop	eax
	ret
OHCIBB_SetFS_DI		ENDP

;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	OHCIBB_ResetHC
;
; Description:	This function resets the OHCI controller
;
; Input: 	FS:DI	Pointer to mem base address
;
; Output: 	None
;
; Modified:	Nothing
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>

OHCIBB_ResetHC		PROC NEAR
	push	cx

; Issue a software reset and HC go to UsbSuspend state
	mov	DWORD PTR FS:[di+OHCI_COMMAND_STATUS], HC_RESET

; Wait for ensure HC stay in UsbSuspend > 2ms
; 134*15us = 2 ms, Delay 2ms (see p42)
	mov	cx, ((2 * 1000) / 15)	; 2ms delay
	call	fixed_delay_far

; Let HC go to UsbReset state for reset Root Hub and downstream ports
	mov	DWORD PTR FS:[di+OHCI_CONTROL_REG], USBRESET

; Wait 10ms for assertion of reset
	mov	cx, ((10 * 1000) / 15)	; 10ms delay
	call	fixed_delay_far

	pop	cx
	ret
OHCIBB_ResetHC		ENDP

;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	OHCIBB_StartEDSchedule
;
; Description:	This function starts the standard ED schedules for the
;		USB host controller
;
; Input: 	FS:DI	Pointer to the memory base address
;
; Output: 	ZR	On error
;		NZ	On success
;
; Modified:	Nothing
;
; Referrals:	OHCI_TD
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>

OHCIBB_StartEDSchedule		PROC NEAR
	push	cx
	push	si
	push	di
	push	es

; Schedule the EDs

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

; The ED schedule should be added in proper order otherwise the
; links will get garbled. The proper order is to add ED for interrupt
; transfer (1ms) followed by ED for keyboard polling (8ms)

OBSES_FrameListInitLoop:

; Schedule 1ms ED for Interrupt transfer
	mov	si, OFFSET EDInterrupt
; SI - ED Pointer
; ES:DI - Far pointer to the frame list
	call	OHCIBB_AddED

; Check for 8ms ED for keyboard polling
	test	cx, 007h
	jnz	OBSES_Continue

IF	MKF_USB_BB_DEV_KBD
; Yes. Schedule 8ms TD
	mov	si, OFFSET EDKeyboard
	call	OHCIBB_AddED
ENDIF	;; IF	MKF_USB_BB_DEV_KBD
OBSES_Continue:
	add	di, 4
	loop	OBSES_FrameListInitLoop


OBSES_Exit:
	or	sp, sp		; Clear ZR flag

	pop	es
	pop	di
	pop	si
	pop	cx
	ret
OHCIBB_StartEDSchedule	ENDP


;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	OHCIBB_AddED
;
; Description:	This function adds a ED 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:	OHCI_ED
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>

OHCIBB_AddED	PROC NEAR 

	push	eax
	push	ebx
	push	esi

; Load parameters to registers
	movzx	esi, si
	or	(OHCI_ED PTR [si]).Control, ED_SKIP_TDQ	; Skip this ED
	mov	ebx, DWORD PTR ES:[di]

; Form the 32bit absolute ED 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 ED
	mov	(OHCI_ED PTR [si]).LinkPointer, ebx

	pop	esi
	pop	ebx
	pop	eax
	ret
OHCIBB_AddED		ENDP

;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	OHCIBB_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>


OHCIBB_ControlTransfer	PROC NEAR SYSCALL PUBLIC

	push	fs
	push	es
	pushad

;;; Necessary for OHCI host controllers
;;	mov	cx, ((5 * 1000) / 15)	; 5ms delay
;;	call	fixed_delay_far

; Setup the local variables
	mov	dx, (DeviceInfo PTR [si]).CntrlXfer.wLength

; Build the device request in the data area of the control setup qTD
	mov	di, OFFSET GTDControlSetup.SetupData
	call	USBBB_CopyDeviceRequest

; Prepare some registers that will be used in building the TDs below.
; wLength  contains the data length.
; fpBuffer contains the absolute address of the data buffer.
; wRequest contains the request type (bit 7 = 0/1 for Out/In).
; BX  will contain a pointer to the DeviceInfo structure for the given device.
; DI  will be left free to use as a pointer to the TD being built.
; EAX will be left free to use as a scratch register.

; Ready the EDControl for the control transfer
	mov	di, OFFSET EDControl

; The ED control field will be set so
;   Function address & Endpoint number = ESI,
;   Direction = From TD,
;   Speed = DeviceInfo.bEndpointSpeed,
;   Skip = 1, Format = 0,
;   Max packet size  = DeviceInfo.wEndp0MaxPacket
; The HeadPointer field will be set to GTDControlSetup
; The TailPointer field will be set to OHCI_TERMINATE
; The LinkPointer field will be set to OHCI_TERMINATE
	movzx	eax, (DeviceInfo PTR [si]).wEndp0MaxPacket
; Force the max packet size to 64 bytes
	cmp	ax, 40h
	jbe	OCT_EndPointOkay
	mov	ax, 40h
OCT_EndPointOkay:
	shl	eax, 16			; EAX[26:16] = device's packet size

	movzx	ax, (DeviceInfo PTR [si]).bEndpointSpeed
	; AL = 00/01/10 for HI/LO/FULL
	and	al, 1			; Mask off MSb
	shl	ax, 13			; EAX[13] = full/low speed flag
	or	al, (DeviceInfo PTR [si]).bDeviceAddress	; EAX[10:0] = Endp/Addr
	or	eax, ED_SKIP_TDQ
	mov	(OHCI_ED PTR [di]).Control, eax

	xor	eax, eax		; OHCI_TERMINATE
	mov	(OHCI_ED PTR [di]).TailPointer, eax
	mov	(OHCI_ED PTR [di]).LinkPointer, eax

; Fill in various fields in the GTDControlSetup.
	mov	di, OFFSET GTDControlSetup
					; DI - Pointer to GTDControlSetup

; The ControlStatus field will be set so
;   Buffer Rounding = 1,
;   Direction PID = GTD_SETUP_PACKET,
;   Delay Interrupt = GTD_IntD,
;   Data Toggle = GTD_SETUP_TOGGLE,
;   Error Count = GTD_NO_ERRORS,
;   Condition Code = GTD_NOT_ACCESSED
; The CurrentBufferPointer field will point to the TD's SetupData buffer
;   which was before initialized to contain a DeviceRequest struc.
; The BufferEnd field will point to the last byte of the TD's SetupData
;   buffer.
; The LinkPointer field will point to the TDControlData if data will
;   be sent/received or to the TDControlStatus if no data is expected.
; The CSReloadValue field will contain 0 because this is a "one shot" packet.
; The pCallback will be set to point to the OHCIBB_ControlTDCallback routine.
; The ActiveFlag field will be set to TRUE.
; The DeviceAddress field does not need to be set since the Control TDs do
;   not need rebinding to the EDControl.

	mov	(OHCI_TD PTR [di]).ControlStatus, GTD_BUFFER_ROUNDING OR \
				GTD_SETUP_PACKET OR GTD_SETUP_TOGGLE OR \
				GTD_NO_ERRORS OR (GTD_NOT_ACCESSED SHL 28)

	lea	ax, (OHCI_TD PTR [di]).SetupData
					; AX = ptr to TD's data buffer
	movzx	eax, ax 		; Clear upper half of EAX
	add	eax, dGlobalDataArea	; EAX = abs addr of TD's 8 byte data buffer
	mov	(OHCI_TD PTR [di]).CurrentBufferPointer, eax

	add	eax, (SIZE (OHCI_TD PTR [di]).SetupData) - 1
	mov	(OHCI_TD PTR [di]).BufferEnd, eax

	cmp	dx, 0
	jz	OCT_SkipDataTds			; No data to transfer

; Fill in various fields in the TDControlData.
	mov	di, OFFSET GTDData
					; DI - Pointer to TDData

; The ControlStatus field will be set so
;   Buffer Rounding = 1,
;   Direction PID = GTD_OUT_PACKET/GTD_IN_PACKET,
;   Delay Interrupt = GTD_IntD,
;   Data Toggle = GTD_DATA1_TOGGLE,
;   Error Count = GTD_NO_ERRORS,
;   Condition Code = GTD_NOT_ACCESSED
; The CurrentBufferPointer field will point to the caller's buffer
;   which is now in EBP.
; The BufferEnd field will point to the last byte of the caller's buffer.
; The LinkPointer field will point to the TDControlStatus.
; The CSReloadValue field will contain 0 because this is a "one shot" packet.
; The pCallback will be set to point to the OHCIBB_ControlTDCallback routine.
; The ActiveFlag field will be set to TRUE.
; The DeviceAddress field does not need to be set since the Control TDs do
;   not need rebinding to the EDControl.

	mov	eax, GTD_BUFFER_ROUNDING OR GTD_OUT_PACKET OR \
		     GTD_DATA1_TOGGLE OR GTD_NO_ERRORS OR (GTD_NOT_ACCESSED SHL 28)
	test	(DeviceInfo PTR [si]).CntrlXfer.wRequest, BIT7
	jz	OCT_OutPacket		; Br if host sending data to device (OUT)
	mov	eax, GTD_BUFFER_ROUNDING OR GTD_IN_PACKET OR GTD_IntD OR \
		     GTD_DATA1_TOGGLE OR GTD_NO_ERRORS OR (GTD_NOT_ACCESSED SHL 28)
OCT_OutPacket:
	mov	(OHCI_TD PTR [di]).ControlStatus, eax

	mov	eax, (DeviceInfo PTR [si]).CntrlXfer.fpBuffer
	mov	(OHCI_TD PTR [di]).CurrentBufferPointer, eax

	movzx	eax, dx 		; EAX = data length
	cmp	ax, MAX_CONTROL_DATA_SIZE
	jbe	OCT_BufferOkay		; Br if processed data <= buffer size
	mov	ax, MAX_CONTROL_DATA_SIZE
OCT_BufferOkay:
	add	eax, (DeviceInfo PTR [si]).CntrlXfer.fpBuffer
	dec	eax
	mov	(OHCI_TD PTR [di]).BufferEnd, eax


OCT_SkipDataTds:

; Fill in various fields in the TDControlStatus.
	mov	di, OFFSET GTDControlStatus
					; DI - Pointer to TDControlStatus

; The ControlStaus field will be set so
;   Buffer Rounding = 1,
;   Direction PID = GTD_OUT_PACKET/GTD_IN_PACKET,
;   Delay Interrupt = GTD_IntD,
;   Data Toggle = GTD_DATA1_TOGGLE,
;   Error Count = GTD_NO_ERRORS,
;   Condition Code = GTD_NOT_ACCESSED
; The CurrentBufferPointer field will point to NULL
; The BufferEnd field will point to NULL.
; The LinkPointer field will point to OHCI_TERMINATE.
; The CSReloadValue field will contain 0 because this is a "one shot" packet.
; The pCallback will be set to point to the OHCIBB_ControlTdCallback routine.
; The ActiveFlag field will be set to TRUE.
; The DeviceAddress field does not need to be set since the Control TDs do
;   not need rebinding to the EdControl.

; For OUT control transfer status should be IN and
; for IN cotrol transfer, status should be OUT
	mov	eax, GTD_BUFFER_ROUNDING OR GTD_IN_PACKET OR GTD_IntD OR \
		     GTD_DATA1_TOGGLE OR GTD_NO_ERRORS OR (GTD_NOT_ACCESSED SHL 28)
	test	(DeviceInfo PTR [si]).CntrlXfer.wRequest, BIT7
	jz	OCT_InPacket		; Br if host sending data to device (OUT)
	mov	eax, GTD_BUFFER_ROUNDING OR GTD_OUT_PACKET OR \
		     GTD_DATA1_TOGGLE OR GTD_NO_ERRORS OR \
		     (GTD_NOT_ACCESSED SHL 28)
OCT_InPacket:
	mov	(OHCI_TD PTR [di]).ControlStatus, eax

	xor	eax, eax
	mov	(OHCI_TD PTR [di]).CurrentBufferPointer, eax
	mov	(OHCI_TD PTR [di]).BufferEnd, eax
	mov	(OHCI_TD PTR [di]).LinkPointer, eax

; Link all the pointers together
	push	bx
	push	si
	mov	bx, OFFSET EDControl
	mov	si, OFFSET GTDControlSetup
	movzx	eax, si
	add	eax, dGlobalDataArea
	mov	(OHCI_ED PTR [bx]).HeadPointer, eax

	push	si
	mov	bx, OFFSET GTDData
	cmp	dx, 0
	jnz	OCT_NoData
	mov	bx, OFFSET GTDControlStatus
OCT_NoData:
	movzx	eax, bx
	add	eax, dGlobalDataArea
	mov	(OHCI_TD PTR [si]).LinkPointer, eax

	cmp	bx, OFFSET GTDData
	jne	OCT_TDLinkDone

	mov	eax, OFFSET GTDControlStatus
	push	ax
	add	eax, dGlobalDataArea
	mov	(OHCI_TD PTR [bx]).LinkPointer, eax
	pop	bx

OCT_TDLinkDone:
	xor	eax, eax
	mov	(OHCI_TD PTR [bx]).LinkPointer, eax
	pop	si

OCT_InitTD:
	mov	(OHCI_TD PTR [si]).CSReloadValue, 0
	mov	(OHCI_TD PTR [si]).pCallback, OFFSET cs:OHCIBB_ControlTDCallback
	mov	(OHCI_TD PTR [si]).ActiveFlag, TRUE
	mov	esi, (OHCI_TD PTR [si]).LinkPointer
	or	esi, esi
	jz	OCT_TDLinkReallyDone
	sub	esi, dGlobalDataArea
	jmp	SHORT OCT_InitTD
	
OCT_TDLinkReallyDone:
	pop	si
	pop	bx

; Now complete the control queue, so set ED_SKIP_TDQ=0
	mov	di, OFFSET EDControl
					; DI - Pointer to EDControl
	and	(OHCI_ED PTR [di]).Control, NOT ED_SKIP_TDQ

; Set the HcControlHeadED register to point to the EDControl.
	movzx	eax, di
	add	eax, dGlobalDataArea

; Set FS:DI to point to the memory base address of the HC
	call	OHCIBB_SetFS_DI

	mov	DWORD PTR FS:[di+OHCI_CONTROL_HEAD_ED], eax

; Now put the control setup, data and status into the HC's schedule by
; setting the ControllListFilled field of HcCommandStatus reg.
; This will cause the HC to execute the transaction in the next active frame.
	or	DWORD PTR FS:[di+OHCI_COMMAND_STATUS], CONTROL_LIST_FILLED

⌨️ 快捷键说明

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