📄 uhci_bb.asm
字号:
; Description: This function fills the data needed for the control transfer
; in the TD provided
;
; Input: DI Pointer to the TD
; SI Pointer to the device info structure
;
; Output: Nothing
;
; Modified: None
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
UHCIBB_FillCntrlXferFields PROC NEAR
push eax
movzx eax, (DeviceInfo PTR [si]).bEndPointSpeed
; AL = 00/01/10 for HI/LO/FULL
and al, 1 ; Mask off MSb
shl eax, 26
or eax, (UHCI_TD_INTERRUPT_ON_COMPLETE OR UHCI_TD_THREE_ERRORS OR UHCI_TD_ACTIVE)
mov (UHCI_TD PTR [di]).ControlStatus, eax
xor eax, eax
mov (UHCI_TD PTR [di]).CSReloadValue, eax
mov (UHCI_TD PTR [di]).pCallback, OFFSET CS:UHCIBB_ControlTDCallback
mov (UHCI_TD PTR [di]).ActiveFlag, TRUE
pop eax
ret
UHCIBB_FillCntrlXferFields ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: UHCIBB_WaitForTransferComplete
;
; Description: This function executes a device request command transaction
;
; Input: DI Pointer to the TD which has to be completed
;
; Output: Nothing
;
; Modified: None
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
UHCIBB_WaitForTransferComplete PROC NEAR SYSCALL
push ax
push ebx
push cx
mov ebx, 60000d ; Check status change loop iteration
UBWFTC_WaitForComplete:
call UHCIBB_ProcessInterrupt ; SI - HCStruc pointer
cmp (UHCI_TD PTR [di]).ActiveFlag, FALSE
je UBWFTC_Complete ; TD completed
mov cx, 5 ; 75microsec
call fixed_delay_far
dec ebx
jnz UBWFTC_WaitForComplete
or (UHCI_TD PTR [di]).ControlStatus, UHCI_TD_CRC_TIMEOUT_ERROR
UBWFTC_Complete:
pop cx
pop ebx
pop ax
ret
UHCIBB_WaitForTransferComplete ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: UHCIBB_ProcessQH
;
; Description: This function will parse through the queue heads element
; pointer and process the completion status for all the TDs
;
; Input: DI Pointer to the QH
;
; Output: Nothing
;
; Modified: Nothing
;
; Referrals: UHCI_TD, UHCI_QH
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
UHCIBB_ProcessQH PROC NEAR SYSCALL
push edi
; Parse through the TDs present in the QH
mov eax, (UHCI_QH PTR [di]).ElementPointer
UBPQ_CheckNextTD:
test eax, UHCI_TERMINATE
jnz UBPQ_Done ; No TD present in the QH
sub eax, dGlobalDataArea
mov di, ax
call UHCIBB_ProcessTD
mov eax, (UHCI_TD PTR [di]).LinkPointer
jmp SHORT UBPQ_CheckNextTD
UBPQ_Done:
pop edi
ret
UHCIBB_ProcessQH ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: UHCIBB_ProcessTD
;
; Description: This function will check whether the TD is completed
; if so, it will call the call back routine associated with
; this TD
;
; Input: DI Pointer to the TD
;
; Output: Nothing
;
; Modified: Nothing
;
; Referrals: UHCI_TD
;
; Notes: For any TD whose ActiveFlag is TRUE and its ControlStatus
; bit 23 is clear (completed), process the TD by calling
; its call back routine, if one is present.
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
UHCIBB_ProcessTD PROC NEAR SYSCALL PUBLIC
; Check for NULL TD
or di, di
jz UBPT_Done ; Null pointer
; Check whether TD is active
cmp (UHCI_TD PTR [di]).ActiveFlag, TRUE
jne UBPT_Done ; TD is not active
; Check whether TD is completed
test (UHCI_TD PTR [di]).ControlStatus, UHCI_TD_ACTIVE
jnz UBPT_Done ; TD is not completed
; Check whether call back function is present
cmp (UHCI_TD PTR [di]).pCallback, 0
jz UBPT_Done ; No callback associated
; If callback function present invoke it
; DI TD pointer
call (UHCI_TD PTR [di]).pCallback
UBPT_Done:
ret
UHCIBB_ProcessTD ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: UHCIBB_ParseAndProcessTD
;
; Description: This function will parse through the TDs (link pointers too)
; and process the TD if it is completed
;
; Input: DI Pointer to the TD
;
; Output: Nothing
;
; Modified: Nothing
;
; Referrals: UHCI_TD, UHCI_QH
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
UHCIBB_ParseAndProcessTD PROC NEAR SYSCALL
push eax
push di
UBPAPT_CheckNextTD:
or di, di
jz UBPAPT_Done
call UHCIBB_ProcessTD
; Get the next TD
mov eax, (UHCI_TD PTR [di]).LinkPointer
test eax, UHCI_TERMINATE
jnz UBPAPT_Done
and eax, NOT (UHCI_QUEUE_HEAD OR UHCI_VERTICAL_FLAG)
sub eax, dGlobalDataArea
mov di, ax
jmp SHORT UBPAPT_CheckNextTD
UBPAPT_Done:
pop di
pop eax
ret
UHCIBB_ParseAndProcessTD ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: UHCIBB_ControlTDCallback
;
; Description: This function is called when the control transfer scheduled
; is completed.
;
; Input: DI Pointer to the TD that completed
;
; Output: Nothing
;
; Modified: Nothing
;
; Referrals: UHCI_TD
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
UHCIBB_ControlTDCallback PROC NEAR SYSCALL
push eax
push ebx
push di
; Check to see if the TD that just completed has any error bits set. If
; any of the control TDs (Setup, Data, or Status) complete with an error, set
; ActiveFlag of the control status TD and copy the error information from the
; TD that just completed into the control status TD.
mov eax, (UHCI_TD PTR [di]).ControlStatus
test eax, UHCI_TD_STATUS_FIELD
jz UBCTC_NoError ; TD completed without an error
mov bx, OFFSET TDControlStatus
mov (UHCI_TD PTR [bx]).ControlStatus, eax
mov (UHCI_TD PTR [bx]).ActiveFlag, FALSE
jmp SHORT UBCTC_Done
; Check the amount of data tranferred by the TD that just completed. If
; less than a full packet was transferred, then the device has no more
; data to send. In this case we should point the QHControl's
; ElementPointer field to the control status TD because that the
; remaining control data TDs are not needed.
UBCTC_NoError:
mov eax, (UHCI_TD PTR [di]).ControlStatus
and ax, UHCI_TD_DATA_LENGTH ;AX = actual byte count - 1
mov ebx, (UHCI_TD PTR [di]).Token
shr ebx, 21 ;BX = expected byte count - 1
cmp ax, bx
je UBCTC_Done ;Br if actual = expected count
mov eax, OFFSET TDControlStatus
add eax, dGlobalDataArea ; EAX = seg containing TDs
mov bx, OFFSET QHControl
mov (UHCI_QH PTR [bx]).ElementPointer, eax
; Make the TD that just completed inactive. It may be the control setup TD,
; one of the control data TDs, or the control status TD.
UBCTC_Done:
mov (UHCI_TD PTR [di]).ActiveFlag, FALSE
pop di
pop ebx
pop eax
ret
UHCIBB_ControlTDCallback ENDP
IF MKF_USB_BB_DEV_KBD
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: UHCIBB_KeyboardPollingCallback
;
; Description: This function is called when the keyboard polling TD
; completes an interrupt transaction to its assigned device.
; This routine should process any data in the TD's data buffer,
; handle any errors, and then copy the TD's CSReloadValue
; field into its control status field to put the TD back
; into service.
;
; Input: DI Pointer to the TD that completed
;
; Output: None
;
; Modified: Nothing
;
; Referrals: UHCI_TD
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
UHCIBB_KeyboardPollingCallback PROC NEAR PUBLIC
push eax
push di
; Deactivate the TD
mov (UHCI_TD PTR [di]).ActiveFlag, FALSE
; Check for error condition
test (UHCI_TD PTR [di]).ControlStatus, UHCI_TD_STATUS_FIELD
jnz UPTCB_TDError ;Br if any error bit is set in status
push di ; Save pTD
lea ax, (UHCI_TD PTR [di]).DataArea
mov di, ax
; Invoke the call back function
; DI Pointer to the data buffer
call USBBB_ProcessKeyboardData
pop di ; Restore pTD
UPTCB_TDError:
xor (UHCI_TD PTR [di]).Token, DATA_TOGGLE
mov eax, (UHCI_TD PTR [di]).CSReloadValue
mov (UHCI_TD PTR [di]).ControlStatus, eax
mov (UHCI_TD PTR [di]).ActiveFlag, TRUE
pop di
pop eax
ret
UHCIBB_KeyboardPollingCallback ENDP
ENDIF ;; IF MKF_USB_BB_DEV_KBD
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: UHCIBB_BulkTDCallback
;
; Description: This function is called when the bulk data transfer scheduled
; are completed.
;
; Input: DI Pointer to the TD that completed
;
; Output: Nothing
;
; Modified: Nothing
;
; Referrals: UHCI_TD
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
UHCIBB_BulkTDCallback PROC NEAR PUBLIC
push eax
push ebx
push di
; Check to see if the TD that just completed has any error bits set. If
; any of the bulk TDs complete with an error, set ActiveFlag of the
; remaining bulk data TD to FALSE and copy the error information from the
; TD that just completed into last TD.
mov eax, (UHCI_TD PTR [di]).ControlStatus
test eax, UHCI_TD_STATUS_FIELD
jz UBTCB_NoError ; Br if the TD completed with no error
; Error ! Update the last TD to proper error message
jmp SHORT UBTCB_UpdateStatus
; Check the amount of data tranferred by the TD that just completed. If
; less than a full packet was transferred, then the device has no more
; data to send. In this case we should point the QhBulk's
; ElementPointer field to TERMINATE and set remaining TdBulkData TDs
; ACTIVE flag to FALSE.
UBTCB_NoError:
mov eax, (UHCI_TD PTR [di]).ControlStatus
and ax, UHCI_TD_DATA_LENGTH ; AX = actual byte count - 1
mov ebx, (UHCI_TD PTR [di]).Token
shr ebx, 21 ; BX = expected byte count - 1
cmp ax, bx
je UBTCB_Done ; Br if actual = expected count
mov bx, OFFSET QHControl
mov (UHCI_QH PTR [bx]).ElementPointer, UHCI_TERMINATE
mov eax, (UHCI_TD PTR [di]).ControlStatus
UBTCB_UpdateStatus:
push di
mov di, OFFSET TDData
UBTCB_NextTD:
mov (UHCI_TD PTR [di]).ActiveFlag, FALSE
mov ebx, (UHCI_TD PTR [di]).LinkPointer
; Check and update length
push eax
mov eax, (UHCI_TD PTR [di]).ControlStatus
and eax, UHCI_TD_DATA_LENGTH
or ax, ax
jnz UBTCB_SkipLengthAdjustment
; Set the length to 0
or (UHCI_TD PTR [di]).ControlStatus, UHCI_TD_DATA_LENGTH
UBTCB_SkipLengthAdjustment:
pop eax
test ebx, UHCI_TERMINATE
jnz UBTCB_EndLoop
; Mask off low order bits
and bl, NOT UHCI_VERTICAL_FLAG
sub ebx, dGlobalDataArea ; Point to next TD
mov di, bx
jmp SHORT UBTCB_NextTD
UBTCB_EndLoop:
; Set the last TD with the error condition we got from previous TD except
; for the size
and eax, NOT UHCI_TD_DATA_LENGTH
mov (UHCI_TD PTR [di]).ControlStatus, eax
pop di
; Make the TD that just completed inactive.
UBTCB_Done:
mov (UHCI_TD PTR [di]).ActiveFlag, FALSE
pop di
pop ebx
pop eax
ret
UHCIBB_BulkTDCallback ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: UHCIBB_InterruptTDCallback
;
; Description: This function is called when the interrupt data transfer
; scheduled had been completed.
;
; Input: DI Pointer to the TD that completed
;
; Output: Nothing
;
; Modified: Nothing
;
; Referrals: UHCI_TD
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
UHCIBB_InterruptTDCallback PROC NEAR PUBLIC
; Set the done flag for interrupt data TD
mov (UHCI_TD PTR [di]).ActiveFlag, FALSE
; Clear the IOC bit in the control TD
and (UHCI_TD PTR [di]).ControlStatus, NOT UHCI_TD_INTERRUPT_ON_COMPLETE
ret
UHCIBB_InterruptTDCallback ENDP
PUBLIC _UHCI_BB_ASM_END
_UHCI_BB_ASM_END LABEL BYTE
USB_CSEG ENDS
END
;*****************************************************************;
;*****************************************************************;
;** **;
;** (C)Copyright 1985-2002, American Megatrends, Inc. **;
;** **;
;** All Rights Reserved. **;
;** **;
;** 6145-F Northbelt Pkwy, Norcross, GA 30071 **;
;** **;
;** Phone (770)-246-8600 **;
;** **;
;*****************************************************************;
;*****************************************************************;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -