📄 usbmbb.asm
字号:
jz UPRS_Exit
; Form the return value
mov ax, WORD PTR [di+0Ch] ; ASC code (offset 12 & 13)
shl eax, 8
mov al, BYTE PTR [di+02h] ; Sense key (offset 002d)
mov dLastSenseData, eax
; Clear zero flag
or sp, sp
UPRS_Exit:
pop di
pop eax
ret
USBM_RequestSense ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBMassTestUnitReady
;
; Description: This function sends test unit ready command
;
; Input: None
;
; Output: ZR On error
; NZ On success
;
; Modified: Nothing
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBM_TestUnitReady PROC NEAR SYSCALL PUBLIC
push eax
push di
call USBM_ClearMassBuffers
; DI Mass command buffer
; Load command into mass command buffer
mov (CommonTestUnitReadyCommand PTR [di]).OpCode, \
COMMON_TEST_UNIT_READY_OPCODE
; Fill the mass transaction structure
mov stMassXactStruc.bCmdSize, SIZE CommonTestUnitReadyCommand
call USBM_IssueMassTransaction
jnz UMTUR_Exit
; Request sense
call USBM_RequestSense
cmp sp, sp ; Leave with error
UMTUR_Exit:
pop di
pop eax
ret
USBM_TestUnitReady ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBM_ReadCapacityCommand
;
; Description: This function sends read capacity command to the USB mass
; storage device
;
; Input: None
;
; Output: ZR On Error
; NZ On Success
;
; Modified: Nothing
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBM_ReadCapacityCommand PROC NEAR SYSCALL PUBLIC
push eax
push bx
push di
call USBM_ClearMassBuffers
; DI Mass command buffer
mov (CommonReadCapacityCommand PTR [di]).OpCode, \
COMMON_READ_CAPACITY_OPCODE
; Fill the common bulk transaction structure
mov stMassXactStruc.bCmdSize, SIZE CommonReadCapacityCommand
mov stMassXactStruc.bXferDir, BIT7 ; IN
push ds
pop ax
shl eax, 16
mov ax, OFFSET aMassDataBuffer
mov stMassXactStruc.fpBuffer, eax
mov stMassXactStruc.dwLength, 8
call USBM_IssueMassTransaction
jz UMRCC_FreeExit
cmp ax, 8 ; Data expected
jne UMRCC_FreeExit
; Set DI to the buffer pointer
mov di, OFFSET aMassDataBuffer
; Store the block size in the mass info structure
mov eax, DWORD PTR [di+4]
; Change little endian format to big endian(INTEL) format
xchg ah, al
rol eax, 16
xchg ah, al
mov stMassDeviceInfo.wBlockSize, ax
; Store the last LBA number in the mass info structure
mov eax, DWORD PTR [di]
; Change little endian format to big endian(INTEL) format
xchg ah, al
rol eax, 16
xchg ah, al
mov stMassDeviceInfo.dMaxLBA, eax
; Set the appropriate command flag
or wUSBCommandStatus, USB_CMDSTS_READ_CAPACITY_DONE
; Clear zero flag indicating success
or sp, sp
jmp SHORT UMRCC_Exit
UMRCC_FreeExit:
call USBM_RequestSense
cmp sp, sp ; Set error flag
UMRCC_Exit:
pop di
pop bx
pop eax
ret
USBM_ReadCapacityCommand ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBM_IssueMassTransaction
;
; Description: This function performs a mass storage transaction by
; invoking proper transaction protocol.
;
; Input: stMassXactStruc
; pCmdBuffer Pointer to command buffer
; bCmdSize Size of command block
; bXferDir Transfer direction
; fpBuffer Data buffer far pointer
; dwLength Amount of data to be transferred
; wPreSkip Number of bytes to skip before data
; wPostSkip Number of bytes to skip after data
;
; Output: EAX Amount of data actually transferred
;
; Modified: EAX
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBM_IssueMassTransaction PROC NEAR SYSCALL PUBLIC
; Check for CBI & CBI no interrupt protocol
cmp stMassDeviceInfo.bProtocol, PROTOCOL_CBI
je UMIMT_CBIProtocol
cmp stMassDeviceInfo.bProtocol, PROTOCOL_CBI_NO_INT
jne UMIMT_BOTProtocol
UMIMT_CBIProtocol:
; The device supports CBI protocol
call USBM_IssueCBITransaction
jmp SHORT UMIMT_Exit
UMIMT_BOTProtocol:
; Check for BOT protocol
cmp stMassDeviceInfo.bProtocol, PROTOCOL_BOT
jne UMIMT_Error
; The device supports BOT protocol
call USBM_IssueBOTTransaction
jmp SHORT UMIMT_Exit
UMIMT_Error:
xor eax, eax
UMIMT_Exit:
ret
USBM_IssueMassTransaction ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBM_IssueBOTTransaction
;
; Description: This function performs a mass storage transaction using bulk
; only transport (BOT) protocol.
;
; Input: stMassXactStruc
; pCmdBuffer Pointer to command buffer
; bCmdSize Size of command block
; bXferDir Transfer direction
; fpBuffer Data buffer far pointer
; dwLength Amount of data to be transferred
; wPreSkip Number of bytes to skip before data
; wPostSkip Number of bytes to skip after data
;
; Output: ZR On error
; NZ On successfull completion
; EAX Amount of data actually transferred
;
; Modified: EAX
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBM_IssueBOTTransaction PROC NEAR SYSCALL PUBLIC
push bx
push ecx
; Set amount of data read = 0
xor ecx, ecx
; Send the command control transfer
call USBM_SendBOTCommand
jnz UMIBT_ProcessData
; Check for stall condition
cmp bLastBulkCommandStalled, TRUE
jne UMIBT_ErrorExit ; Unknown error exit
; Perform USB BOT reset recovery
call USBM_BOTResetRecovery
UMIBT_ErrorExit:
cmp sp, sp ; Set zero flag
jmp SHORT UMIBT_Exit
UMIBT_ProcessData:
cmp stMassXactStruc.dwLength, 0
je UMIBT_CheckStatus
; Tranfer the bulk data
call USBM_ProcessBulkData
; EAX actual data size
mov ecx, eax
; Check for stall condition
cmp bLastBulkCommandStalled, TRUE
jne UMIBT_CheckStatus
; Clear endpoint
mov al, stMassXactStruc.bXferDir
call USBM_ClearBulkEndpointStall
UMIBT_CheckStatus:
; Get the status for the last transfer
call USBM_GetBOTStatus
or sp, sp ; Successful completion
UMIBT_Exit:
mov eax, ecx
pop ecx
pop bx
ret
USBM_IssueBOTTransaction ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBM_SendBOTCommand
;
; Description: This function sends the BOT command sequence using
; bulk transfer
;
; Input: stMassXactStruc
; bXferDir Transfer direction
; dwDataSize Amount of data to be transferred
; pCmdBuffer Pointer to the command buffer
; bCmdSize Size of command block
;
; Output: ZR On error
; NZ On successfull completion
;
; Modified: Nothing
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBM_SendBOTCommand PROC NEAR SYSCALL
pushad
; Set DS:BX to command buffer pointer
mov bx, stMassXactStruc.pCmdBuffer
mov di, bx
; Make enough space for BOT command block wrapper
; Move from back wards
std ; Set the direction flag
movzx cx, stMassXactStruc.bCmdSize
push cx
dec cx ; Last offset = Offset + (Size-1)
add di, cx
; DI = End of command
mov si, di
; SI = DI = End of command
add di, BOT_COMMAND_BLOCK.CBWCB
; DI = BOT_COMMAND_BLOCK + end of command
; DI = End of (buffer - command size)
inc cx ; Adjust size to move
rep movsb
cld ; Clear the direction flag
pop cx ; Command size
; Clear the BOT command block
mov di, bx
xor al, al
rep stosb
; Setup BOT command block wrapper
mov eax, BOT_CBW_SIGNATURE
mov (BOT_COMMAND_BLOCK PTR [bx]).dCbwSignature, eax
inc BOTCommandTag
mov eax, BOTCommandTag ; Get latest CBW tag value
; Update the CBW tag
mov (BOT_COMMAND_BLOCK PTR [bx]).dCbwTag, eax
mov eax, stMassXactStruc.dwLength
mov (BOT_COMMAND_BLOCK PTR [bx]).dCbwDataLength, eax
mov al, stMassXactStruc.bXferDir
mov (BOT_COMMAND_BLOCK PTR [bx]).bmCbwFlags, al
mov al, CurrentDevice.bLUN
mov (BOT_COMMAND_BLOCK PTR [bx]).bCbwLun, al
mov al, stMassXactStruc.bCmdSize
mov (BOT_COMMAND_BLOCK PTR [bx]).bCbwLength, al
; Set buffer pointer in ES:DI
mov di, bx
; Set buffer size in ECx
mov ecx, SIZE BOT_COMMAND_BLOCK
; Set transfer direction in DL
xor dl, dl ; OUT transfer
; Transfer direction is OUT & size = size of BOT command block wrapper
; SI DeviceInfo Structure
; ES:DI Pointer to the data buffer
; ECX Size of data to be tranferred
; DL Transaction direction
call USBM_IssueBulkTransfer
popad
ret
USBM_SendBOTCommand ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBM_GetBOTStatus
;
; Description: This function gets the BOT status sequence using
; bulk IN transfer
;
; Input: Nothing
;
; Output: Nothing
;
; Modified: None
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBM_GetBOTStatus PROC NEAR SYSCALL
push eax
push ecx
push dx
push di
xor dh, dh
mov di, stMassXactStruc.pCmdBuffer
UBGS_GetStatusAgain:
; ES:DI Pointer to the data buffer
mov ecx, SIZE BOT_STATUS_BLOCK
; ECX Size of data to be tranferred
mov dl, BIT7
; DL Transaction direction
call USBM_IssueBulkTransfer
inc dh
; Check the amount of data transferred
cmp ax, SIZE BOT_STATUS_BLOCK
je UBGS_CheckSignature
; Check iteration count
cmp dx, 3
ja UBGS_ErrorExit
; Check for stall condition
cmp bLastBulkCommandStalled, TRUE
jne UBGS_ErrorExit ; Unknown error
; Clear endpoint
mov al, BIT7
call USBM_ClearBulkEndpointStall
jmp SHORT UBGS_GetStatusAgain
UBGS_CheckSignature:
; Check the validity of the status signature
cmp (BOT_STATUS_BLOCK PTR [di]).dCswSignature, BOT_CSW_SIGNATURE
jnz UBGS_ErrorExit
; Check the BOT command tag validity
mov eax, BOTCommandTag ; Get latest CBW tag value
cmp (BOT_STATUS_BLOCK PTR [di]).dCswTag, eax
jne UBGS_ErrorExit ; NZ = CSW tag not matches CBW tag
; Check for meaningful CSW
cmp (BOT_STATUS_BLOCK PTR [di]).bmCswStatus, 01h
jbe UBGS_Exit
; Status = 00h or 01, check if data residue is less than or equal to
; DataTransferLength. If so then exit.
;; cmp (BOT_STATUS_BLOCK PTR [bx]).dCswDataResidue, ecx
;; ja CswMeaningfulError
UBGS_ErrorExit:
; Clear bulk IN & OUT endpoint
mov al, 0FFh
call USBM_ClearBulkEndpointStall
UBGS_Exit:
pop di
pop dx
pop ecx
pop eax
ret
USBM_GetBOTStatus ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBM_BOTResetRecovery
;
; Description: This function performs the BOT reset recovery
;
; Input: None
;
; Output: None
;
; Modified: Nothing
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBM_BOTResetRecovery PROC NEAR SYSCALL
push ax
push ebx
push dx
push si
; Set SI to the current devices device info structure
mov si, OFFSET CurrentDevice
xor ax, ax
mov CurrentDevice.CntrlXfer.wValue, ax
movzx ax, CurrentDevice.bInterfaceNum
mov CurrentDevice.CntrlXfer.wIndex, ax
mov CurrentDevice.CntrlXfer.wRequest, ADSC_OUT_REQUEST_TYPE + \
(BOT_RESET_REQUEST_CODE SHL 8)
call USBBB_IssueControlXferWithoutData
; Clear bulk IN & OUT endpoint
mov al, 0FFh
call USBM_ClearBulkEndpointStall
pop si
pop dx
pop ebx
pop ax
ret
USBM_BOTResetRecovery ENDP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -