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

📄 ohci.asm

📁 dos下的USB源码(包括UHCI
💻 ASM
📖 第 1 页 / 共 5 页
字号:
	movzx	bx, bEndp
	shl	bx, 7
	or	ax, bx		; AX - Device address & Endpoint

; Set max packet size
	movzx	ebx, wMaxPkt
	shl	ebx, 16
	or	eax, ebx

	pop	bx		; Descriptor pointer

; Update the ED's control field with the data formed
; ASSUME ALL MASS DEVICES ARE FULL SPEED DEVICES.
	or	(OHCI_ED PTR [di]).Control, eax

; Fill the general bulk data TD with relevant information.  Set the
;  TD's control field with buffer rounding set to 1, direction PID to
;  don't care, delay interrupt to INTD, data toggle to the latest data
;  toggle value, error count to no errors and condition code to not accessed.
	mov	di, (OHCIDescriptors PTR [bx]).TDBulkData

; Set the data toggle to DATA0 (SETUP_TOGGLE)
	mov	eax, GTD_BUFFER_ROUNDING or GTD_IN_PACKET  or GTD_IntD or  \
			GTD_SETUP_TOGGLE or GTD_NO_ERRORS or \
			(GTD_NOT_ACCESSED shl 28)
	mov	(OHCI_TD PTR [di]).ControlStatus, eax

; Set the data toggle depending on the bDatToggle value
	movzx	eax, bDatToggle
	shl	eax, 24
	or	(OHCI_TD PTR [di]).ControlStatus, eax

; GTD current buffer pointer field will point to the caller's buffer which
; now in the variable fpBuffer
	mov	eax, fpBuffer
	mov	(OHCI_TD PTR [di]).CurrentBufferPointer, eax

; GTD's buffer end field will point to the last byte of the caller's buffer
	movzx	eax, cx			; Data length
	add	eax, fpBuffer		; End of the buffer
	dec	eax
	mov	(OHCI_TD PTR [di]).BufferEnd, eax

; GTD's link pointer field will be set to OHCI_TERMINATE
	mov	(OHCI_TD PTR [di]).LinkPointer, OHCI_TERMINATE

; GTD's CSReloadValue field will contain 0 because this is
; a "one shot" packet
	mov	(OHCI_TD PTR [di]).CSReloadValue, 0

; GTD's pCallback will point to the OHCI_GeneralTDCallback routine
	mov	(OHCI_TD PTR [di]).pCallback, OFFSET cs:OHCI_GeneralTDCallback

; GTD's ActiveFlag field will be set to TRUE.
	mov	(OHCI_TD PTR [di]).ActiveFlag, TRUE

; Enable the bulk queue by activating the bulk ED
	mov	di, (OHCIDescriptors PTR [bx]).EDBulk
	and	(OHCI_ED PTR [di]).Control, NOT ED_SKIP_TDQ

; Set the HCBulkHeadED register to point to the bulk ED
	movzx	eax, di
	add	eax, HcdGlobalDataArea

	push	si
	mov	si, (DeviceInfo PTR [si]).pHCStrucPtr
	SET_FS_EDI

 	USBPORT_DWORD_WRITE_MEM	si, OHCI_BULK_HEAD_ED, eax

; Clear bulk stall/time out condition flag
	and	bLastCommandStatus, NOT (USB_BULK_STALLED + USB_BULK_TIMEDOUT)

; Enable the bulk list processing
 	USBPORT_DWORD_SET_MEM	si, OHCI_COMMAND_STATUS, BULK_LIST_FILLED

	RESTORE_FS_EDI

	mov	di, (OHCIDescriptors PTR [bx]).TDBulkData
; Now wait for the bulk data TD to complete.
	call	OHCIWaitForTransferComplete

	pop	si

; Stop the HC from processing the EDBulk by setting its Skip bit.
	push	di
	mov	di, (OHCIDescriptors PTR [bx]).EDBulk
	or	(OHCI_ED PTR [di]).Control, ED_SKIP_TDQ
	pop	di

	push	cx
; Update the data toggle value into the mass info structure
	mov	eax, (OHCI_TD PTR [di]).ControlStatus
	and	eax, GTD_DATA_TOGGLE
	shr	eax, 24
	and	al, 1		; Mask off top bits
	mov	cl, al
; SI	DeviceInfo structure
; DL	Xfer direction
; CL	Data toggle value
	call	USBMiscUpdateBulkDataSync
	pop	cx

; Check for the error conditions - if possible recover from them
	mov	eax, (OHCI_TD PTR [di]).ControlStatus
	shr	eax, 28
	or	al, al
	jz	OBTS_Success

	cmp	al, GTD_DEVICE_NOT_RESPOND
	jne	OBTS_CheckStall

; Bulk time out condition is checked and cleared elsewhere
	or	bLastCommandStatus, USB_BULK_TIMEDOUT
	jmp	SHORT OBTS_ErrorExit

OBTS_CheckStall:
; Check for stall condition
	cmp	al, GTD_STALL
	jne	OBTS_ErrorExit

; Bulk stall condition is checked and cleared elsewhere
	or	bLastCommandStatus, USB_BULK_STALLED

OBTS_ErrorExit:
; Return with error
	xor	ax, ax
	jmp	SHORT OBTS_Exit

OBTS_Success:
; Get the size of data transferred

; Size transferred is calculated by subtracting end address with current
; buffer pointer and subtracting that value from the total size
	mov	ebx, (OHCI_TD PTR [di]).CurrentBufferPointer
	or	ebx, ebx
	jz	OBTS_FoundSize
	mov	eax, (OHCI_TD PTR [di]).BufferEnd
	sub	eax, ebx
	or	ax, ax
	jz	OBTS_FoundSize
	sub	cx, ax				; Size in CX
	dec	cx
OBTS_FoundSize:
	mov	ax, cx
OBTS_Exit:

	pop	di
	pop	si
	pop	cx
	pop	ebx
	ret
OHCI_BulkTransfer	ENDP


;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	OHCI_InterruptTransfer
;
; Description:	This function executes an interrupt transaction on the USB.
;		The data transfer direction is always DATA_IN. This
;		function wil not return until the request either completes
;		successfully or completes in error (due to time out, etc.)
;
; Input:	DI	Pointer to HCStruc of the host controller
;		SI	DeviceInfo structure 
;		DX	Buffer containing data to be sent to the device or
;			buffer to be used to receive data
;		CX	number of bytes of data to be transferred in
;
;
; Output: 	AX	0xFFFF SUCCESS
;		AX	0      ERROR
;
; Modified:	EAX
;
; Notes:	DO NOT TOUCH THE LINK POINTER OF THE TDInterruptData. It is
;		statically allocated and linked with other items in the
;		1ms schedule
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>

OHCI_InterruptTransfer	PROC NEAR SYSCALL PUBLIC USES EBX CX EDX SI DI

	LOCAL	wMaxPkt:WORD, bEndp:BYTE, bDatToggle:BYTE

; Change Seg:Off in fpBuffer to 32 bit absolute address
	mov	ax, ds
	movzx	eax, ax
	shl	eax, 4
	movzx	edx, dx
	add	edx, eax

; Set the SKIP bit in the EDInterrupt to avoid accidental scheduling
	mov	bx, (HCStruc PTR [di]).pDescriptorPtr

	mov	di, (OHCIDescriptors PTR [bx]).EDInterrupt
	mov	(OHCI_ED PTR [di]).Control, ED_SKIP_TDQ

; Set the ED's head pointer field to interrupt data TD and tail pointer
; field to OHCI_TERMINATE. Also set ED's link pointer to OHCI_TERMINATE.
	movzx	eax, (OHCIDescriptors PTR [bx]).TDInterruptData
	add	eax, HcdGlobalDataArea
	mov	(OHCI_ED PTR [di]).HeadPointer, eax

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

	push	si
; Get mass struc in SI

; Get maximum packet size from device info structure
	mov	ax, (DeviceInfo PTR [si]).wIntMaxPkt
	mov	wMaxPkt, ax

	mov	al, (DeviceInfo PTR [si]).bIntEndpoint
	mov	bEndp, al

	mov	al, (DeviceInfo PTR [si]).bDataSync
	and	al, USB_INT_DATA_SYNC
	shr	al, USB_INT_DATA_SYNC_SHIFT
	mov	bDatToggle, al
	pop	si

; Form the data needed for ED's control field with the available information
	mov	eax, ED_IN_PACKET

	push	bx
; Get device info pointer
	mov	al, (DeviceInfo PTR [si]).bDeviceAddress
	movzx	bx, bEndp
	shl	bx, 7
	or	ax, bx		; AX - Device address & Endpoint

; Set max packet size
	movzx	ebx, wMaxPkt
	shl	ebx, 16
	or	eax, ebx
	pop	bx

; Update the ED's control field with the data formed
; ASSUME ALL MASS DEVICES ARE FULL SPEED DEVICES.
	or	(OHCI_ED PTR [di]).Control, eax

; Fill the general interrupt data TD with relevant information.  Set the
;  TD's control field with buffer rounding set to 1, direction PID to
;  don't care, delay interrupt to INTD, data toggle to the latest data
;  toggle value, error count to no errors and condition code to not accessed.
	mov	di, (OHCIDescriptors PTR [bx]).TDInterruptData

; Set the data toggle to DATA0 (SETUP_TOGGLE)
	mov	eax, GTD_BUFFER_ROUNDING or GTD_IN_PACKET  or GTD_IntD or  \
			GTD_SETUP_TOGGLE or GTD_NO_ERRORS or \
			(GTD_NOT_ACCESSED shl 28)
	mov	(OHCI_TD PTR [di]).ControlStatus, eax

; Set the data toggle depending on the bDatToggle value
	movzx	eax, bDatToggle
	shl	eax, 24
	or	(OHCI_TD PTR [di]).ControlStatus, eax

; GTD current buffer pointer field will point to the caller's buffer 
	mov	(OHCI_TD PTR [di]).CurrentBufferPointer, edx

; GTD's buffer end field will point to the last byte of the caller's buffer
	movzx	eax, cx			; Data length
	add	eax, edx		; End of the buffer
	dec	eax
	mov	(OHCI_TD PTR [di]).BufferEnd, eax

; GTD's link pointer field will be set to OHCI_TERMINATE
	mov	(OHCI_TD PTR [di]).LinkPointer, OHCI_TERMINATE

; GTD's CSReloadValue field will contain 0 because this is
; a "one shot" packet
	mov	(OHCI_TD PTR [di]).CSReloadValue, 0

; GTD's pCallback will point to the OHCI_GeneralTDCallback routine
	mov	(OHCI_TD PTR [di]).pCallback, OFFSET cs:OHCI_GeneralTDCallback

; GTD's ActiveFlag field will be set to TRUE.
	mov	(OHCI_TD PTR [di]).ActiveFlag, TRUE

; Enable the interrupt queue by activating the interrupt ED
	mov	di, (OHCIDescriptors PTR [bx]).EDInterrupt
	and	(OHCI_ED PTR [di]).Control, NOT ED_SKIP_TDQ

	push	si
	mov	si, (DeviceInfo PTR [si]).pHCStrucPtr
	mov	di, (OHCIDescriptors PTR [bx]).TDInterruptData
; Now wait for the interrupt data TD to complete.
	call	OHCIWaitForTransferComplete
	pop	si

; Stop the HC from processing the EDInterrupt by setting its Skip bit.
	push	di
	mov	di, (OHCIDescriptors PTR [bx]).EDInterrupt
	or	(OHCI_ED PTR [di]).Control, ED_SKIP_TDQ
	pop	di

; Get appropriate data sync shift value
	mov	cl, USB_INT_DATA_SYNC_SHIFT
	push	di
	mov	di, (DeviceInfo PTR [si]).pMassInfoPtr
	cmp	(MassDeviceInfo PTR [di]).pLUN0DevInfoPtr, 0
	je	OIT_ToggleBitDone
	mov	si, (MassDeviceInfo PTR [di]).pLUN0DevInfoPtr
OIT_ToggleBitDone:
	pop	di

; Reset toggle bit
	mov	al, 1
	shl	al, cl
	not	al
	and	(DeviceInfo PTR [si]).bDataSync, al

; Set toggle bit appropriately
	mov	eax, (OHCI_TD PTR [di]).ControlStatus
	and	eax, GTD_DATA_TOGGLE
	shr	eax, 24
	and	al, 1		; Mask off top bits
	shl	al, cl
	or	(DeviceInfo PTR [si]).bDataSync, al

; Check for the error conditions - if possible recover from them
	mov	eax, (OHCI_TD PTR [di]).ControlStatus
	shr	eax, 28

	or	al, al
	mov	ax, 0FFFFh
	jz	OIT_Success

; Return with error
	xor	ax, ax
OIT_Success:
OIT_Exit:
	ret
OHCI_InterruptTransfer	ENDP


;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	OHCI_ActivatePolling
;
; Description:	This function activates the polling TD for the requested
;		device. The device may be a USB keyboard or USB hub
;
; Input: 	BX	Pointer to the device information structure
;
; Output: 	AX	0 on error, 0FFFFh on success
;
; Modified:	AX
;
; Referrals:	OHCI_TD, DeviceInfo
;
; Notes:	For the keyboard device this routine allocates TDRepeat
;		also, if it is not already allocated. This routine allocate
;		a polling TD and schedule it to 8ms schedule for keyboards
;		and to 1024ms schedule for hubs.
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>

OHCI_ActivatePolling	PROC NEAR SYSCALL PUBLIC USES BX SI EDI CX DX

; Set registers with needed value
	mov	si, (DeviceInfo PTR [bx]).pHCStrucPtr
	mov	di, (HCStruc PTR [si]).pDescriptorPtr

	mov	dl, (DeviceInfo PTR [bx]).bDeviceType

; Check whether the activate polling is for HID device
	cmp	dl, BIOS_DEV_TYPE_KEYBOARD
	je	OAP_InstallRepeatTD

	cmp	dl, BIOS_DEV_TYPE_MOUSE
	jne	OAP_RepeatTDDone

OAP_InstallRepeatTD:
; Check whether a TD is allocated for TDRepeat if not allocate one.
	cmp	(OHCIDescriptors PTR [di]).TDRepeat, 0
	jne	OAP_RepeatTDDone		; Already allocated

; Allocate a ED/TD for EDRepeat/TDRepeat
	mov	al, 2
	call	USBMem_Alloc
	jz	OAP_Exit

	push	di		; Save OHCIDescriptors

	push	ax
	mov	(OHCIDescriptors PTR [di]).EDRepeat, ax
	add	ax, SIZE OHCI_ED
	mov	(OHCIDescriptors PTR [di]).TDRepeat, ax
	pop	ax
	mov	di, ax
	add	ax, SIZE OHCI_ED

	mov	cx, ax

; Setup EDRepeat and TDRepeat.  It will run a interrupt transaction to a
; nonexistant dummy device.  This will have the effect of generating
; a periodic interrupt used to generate keyboard repeat.  This ED/TD
; is normally inactive,  and is only activated when a key is pressed.

; DI - EDRepeat
; CX - TDRepeat

	mov	(OHCI_ED PTR [di]).Control, DUMMY_DEVICE_ADDR OR \
		ED_IN_PACKET OR (DEFAULT_PACKET_LENGTH SHL 16) OR ED_SKIP_TDQ
	mov	(OHCI_ED PTR [di]).LinkPointer, OHCI_TERMINATE
	movzx	eax, cx				; TDRepeat
	add	eax, HcdGlobalDataArea
	mov	(OHCI_ED PTR [di]).HeadPointer, eax
	mov	(OHCI_ED PTR [di]).TailPointer, OHCI_TERMINATE

	push	di
	mov	di, cx				; DI = ptr to TdRepeat
	mov	eax, GTD_BUFFER_ROUNDING OR GTD_IN_PACKET OR GTD_IntD OR \
			(GTD_NOT_ACCESSED SHL 28) OR GTD_ONE_ERROR
        mov     (OHCI_TD PTR [di]).ControlStatus, eax
        mov     (OHCI_TD PTR [di]).CSReloadValue, eax

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

⌨️ 快捷键说明

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