📄 usbmass.asm
字号:
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBMassGetDeviceParameters PROC NEAR SYSCALL
push bx
; Issue inquiry command
; SI DeviceInfo
call USBMassInquiryCommand
; ZR on error, NZ on success
jz umgdp_Exit
; DI pointer to the inquiry data
mov bx, (DeviceInfo PTR [si]).pMassInfoPtr
; Clear the cached block size
mov (MassDeviceInfo PTR [bx]).wBlockSize, 0FFFFh
; Find the device type and update the device type structure accordingly
; SI DeviceInfo
; DI Pointer to temp buffer
call USBMassIdentifyDeviceType
; Success. Clear the zero flag
or sp, sp
umgdp_Exit:
pop bx
ret
USBMassGetDeviceParameters ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBMassGetDeviceInfo
;
; Description: This function fills and returns the mass get device info
; structure
;
; Input: ES:BX Pointer to the mass get info struc
; bDevAddr USB device address of the device
;
; Output: AX Return value
; ES:BX Pointer to the mass get info struc
; dSenseData Sense data of the last command
; bDevType Device type byte (HDD, CD, Removable)
; bEmuType Emulation type used
; fpDevId Far pointer to the device ID
;
; Modified: AX
;
; Referrals: MASS_GET_DEV_INFO
;
; Notes: Initially the bDevAddr should be set to 0 as input. This
; function returns the information regarding the first mass
; storage device (if no device found it returns bDevAddr as
; 0FFh) and also updates bDevAddr to the device address of
; the current mass storage device. If no other mass storage
; device is found then the routine sets the bit7 to 1
; indicating current information is valid but no more mass
; device found in the system. The caller can get the next
; device info if bDevAddr is not 0FFh and bit7 is not set
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBMassGetDeviceInfo PROC NEAR SYSCALL PUBLIC
push cx
push dx
push si
push di
; Load the registers with input parameters
mov dl, (MASS_GET_DEV_INFO PTR ES:[bx]).bDevAddr
; Set function as failure
mov dh, USB_ERROR
; Check for device address validity
test dl, BIT7
jnz UMGDI_Exit
mov al, SIZE DeviceInfo
mul dl
add ax, OFFSET DeviceInfoTable
mov si, ax
xor ax, ax
mov al, dl
;; mov si, OFFSET DeviceInfoTable
UMGDI_CheckNextEntry:
inc al ; Structure number 1-based
add si, SIZE DeviceInfo ; Skip first entry
cmp si, OFFSET DeviceInfoTableEnd ; Check for end condition
jae UMGDI_EntryNotFound
test (DeviceInfo PTR [si]).bFlag, DEV_INFO_VALID_STRUC
jz UMGDI_CheckNextEntry ; Free entry skip it
cmp (DeviceInfo PTR [si]).bDeviceType, BIOS_DEV_TYPE_STORAGE
jne UMGDI_CheckNextEntry ; Device address mismatch
; Valid entry found
or ah, ah
jnz UMGDI_EntryFound
; This is the entry we want save it in AH
mov ah, al
mov cx, si
; Proceed to see if more of this type device is present
jmp SHORT UMGDI_CheckNextEntry
UMGDI_EntryFound:
; Entry number is in AH and there is one more entry
mov dl, ah
jmp SHORT UMGDI_GetStruc
UMGDI_EntryNotFound:
; If AH = 0 then entry not found
mov dl, 0FFh
or ah, ah
jz UMGDI_NoMoreMassDevice
; If AH <> 0 then entry found but no more entries present
mov dl, ah
or dl, BIT7
UMGDI_GetStruc:
; Get device address structure pointer in SI
mov si, cx
; Issue inquiry command
; SI DeviceInfo
call USBMassGetDeviceParameters
; ZR on error, NZ on success
jz UMGDI_Exit
; DI Pointer to temp buffer
; ES:BX Far pointer to inquiry data
push si
mov si, (DeviceInfo PTR [si]).pMassInfoPtr
; Update mass info structure with device and emulation type
mov al, (MassDeviceInfo PTR [si]).bDevType
mov (MASS_INQUIRY PTR ES:[bx]).bDevType, al
mov ah, (MassDeviceInfo PTR [si]).bEmuType
mov (MASS_INQUIRY PTR ES:[bx]).bEmuType, ah
pop si
add di, 8 ; Offset into the vendor string
; DS:DI Pointer to the device name string
push bx
xor eax, eax
mov ax, ds
shl eax, 4
movzx ebx, di
call USBMassAdjustIdString
add eax, ebx
pop bx
UMGDI_SetName:
mov (MASS_INQUIRY PTR ES:[bx]).fpDevId, eax
UMGDI_NoMoreMassDevice:
mov (MASS_GET_DEV_INFO PTR ES:[bx]).bDevAddr, dl
; Set function as success
mov dh, USB_SUCCESS
UMGDI_Exit:
movzx ax, dh
pop di
pop si
pop dx
pop cx
ret
USBMassGetDeviceInfo ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBMassCmdPassThru
;
; Description: This function issues the command/data sequence provided
; as input. This function can be used to send raw data
; to the USB mass storage device
;
; Input: SI DeviceInfo structure pointer
; ES: BX Pointer to the mass command pass through structure
; bDevAddr USB device address of the device
; dSenseData Sense data of the last command
; fpCmdBuffer Far pointer to the command buffer
; wCmdLength Command length
; fpDataBuffer Far pointer for data buffer
; wDataLength Data length
; bXferDir Data transfer direction
;
; Output: AX Return value
; dSenseData Sense data of the last command
; fpDataBuffer Updated with returned data if the transfer
; is an IN transaction
;
; Modified: AX
;
; Referrals:
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBMassCmdPassThru PROC NEAR SYSCALL PUBLIC
push bx
push dx
push di
; Initialize the variables
mov dh, USB_ERROR ; Failure
xor di, di ; Command buffer
; Allocate memory for the command buffer
mov ax, (MASS_CMD_PASS_THRU PTR ES:[bx]).wCmdLength
add ax, (USB_MEM_BLK_SIZE - 1) ; For proper rounding
shr ax, USB_MEM_BLK_SIZE_SHIFT
mov dl, al
; Check whether the drive is ready for read TOC command
; SI - DeviceInfo structure
call USBMassCheckDeviceReady
UMCPT_RetryCommand:
; Allocate memory for the command buffer
mov al, dl
call USBMem_Alloc
jz UMCPT_Exit
mov di, ax ; Command buffer
; Copy the command into (just allocated) mass command buffer
; Set DS:SI to the source buffer
push ds
push es
push si
push di
; Save DS
push ds
lds si, (MASS_CMD_PASS_THRU PTR ES:[bx]).fpCmdBuffer
; Set CX to the command buffer length
mov cx, (MASS_CMD_PASS_THRU PTR ES:[bx]).wCmdLength
; Load ES with original DS
pop es
cld
rep movsb
pop di
pop si
pop es
pop ds
; Clear the common bulk transaction structure
call USBMassClearMassXactStruc
; Fill the common bulk transaction structure
mov stMassXactStruc.pCmdBuffer, di
mov ax, (MASS_CMD_PASS_THRU PTR ES:[bx]).wCmdLength
mov stMassXactStruc.bCmdSize, al
mov al, (MASS_CMD_PASS_THRU PTR ES:[bx]).bXferDir
mov stMassXactStruc.bXferDir, al
mov eax, (MASS_CMD_PASS_THRU PTR ES:[bx]).fpDataBuffer
mov stMassXactStruc.fpBuffer, eax
movzx eax, (MASS_CMD_PASS_THRU PTR ES:[bx]).wDataLength
mov stMassXactStruc.dwLength, eax
call USBMassIssueMassTransaction
; Update the actual data length processed/returned
mov (MASS_CMD_PASS_THRU PTR ES:[bx]).wDataLength, ax
; Request sense
call USBMassRequestSense ; SI - pDevInfo
mov (MASS_CMD_PASS_THRU PTR ES:[bx]).dSenseData, eax
; Check and free command buffer
mov al, dl
mov bx, di
call USBMem_Free
; Set function as success
mov dh, USB_SUCCESS
UMCPT_Exit:
movzx ax, dh
pop di
pop dx
pop bx
ret
USBMassCmdPassThru ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBMassReadCapacityCommand
;
; Description: This function sends read capacity command to the USB mass
; storage device
;
; Input: SI Pointer to DeviceInfo structure
;
; Output: ZR On Error
; NZ On Success
;
; Modified: None
;
; Notes: This routine will update the MassDeviceInfo structure
; with the block size & last LBA values obtained from the
; device
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBMassReadCapacityCommand PROC NEAR SYSCALL PUBLIC
push eax
push bx
push di
; Allocate memory for the command buffer
call USBMem_AllocOne
jz UMRCC_Exit
; Load command into (just allocated) mass command buffer
mov di, ax
mov (CommonReadCapacityCommand PTR [di]).OpCode, \
COMMON_READ_CAPACITY_OPCODE
; Clear the common bulk transaction structure
call USBMassClearMassXactStruc
; Fill the common bulk transaction structure
mov stMassXactStruc.pCmdBuffer, di
mov stMassXactStruc.bCmdSize, SIZE CommonReadCapacityCommand
mov stMassXactStruc.bXferDir, BIT7 ; IN
push ds
pop ax
shl eax, 16
mov ax, pUSBTempBuffer
mov stMassXactStruc.fpBuffer, eax
mov stMassXactStruc.dwLength, 8
call USBMassIssueMassTransaction
or eax, eax
jz UMRCC_FreeExit
mov bx, (DeviceInfo PTR [si]).pMassInfoPtr
push di
; Set DI to the buffer pointer
mov di, pUSBTempBuffer
; 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 (MassDeviceInfo PTR [bx]).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
; Convert Last LBA to total LBA (0 based to 1 based)
inc eax
mov (MassDeviceInfo PTR [bx]).dMaxLBA, eax
pop di
; Clear zero flag indicating success
or sp, sp
UMRCC_FreeExit:
pushf
; Check and free command buffer
mov bx, di
call USBMem_FreeOne
popf
UMRCC_Exit:
pop di
pop bx
pop eax
ret
USBMassReadCapacityCommand ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBMassReadFormatCapacity
;
; Description: This function sends read format capacity command to the USB
; mass storage device
;
; Input: SI Pointer to DeviceInfo structure
;
; Output: ZR On Error
; NZ On Success
;
; Modified: None
;
; Notes: This routine will update the MassDeviceInfo structure
; with the block size & last LBA values obtained from the
; device
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBMassReadFormatCapacity PROC NEAR SYSCALL PUBLIC
push eax
push bx
push di
; Allocate memory for the command buffer
call USBMem_AllocOne
jz UMRFC_Exit
; Load command into (just allocated) mass command buffer
mov di, ax
mov (CommonReadFormatCapacity PTR [di]).OpCode, \
COMMON_READ_FORMAT_CAPACITY_OPCODE
mov ax, MAX_TEMP_BUFFER_SIZE
xchg ah, al
mov (CommonReadFormatCapacity PTR [di]).AllocLength, ax
; Clear the common bulk transaction structure
call USBMassClearMassXactStruc
; Fill the common bulk transaction structure
mov stMassXactStruc.pCmdBuffer, di
mov stMassXactStruc.bCmdSize, SIZE CommonReadFormatCapacity
mov stMassXactStruc.bXferDir, BIT7 ; IN
push ds
pop ax
shl eax, 16
mov ax, pUSBTempBuffer
mov stMassXactStruc.fpBuffer, eax
mov stMassXactStruc.dwLength, MAX_TEMP_BUFFER_SIZE
call USBMassIssueMassTransaction
;; or eax, eax
;; jz UMRFC_FreeExit
; The amount of data obtained should be atleast of read format capacity structure size
cmp eax, SIZE READ_FMT_CAPACITY
jae UMRFC_CmdSuccess
; Set zero flag
cmp sp, sp
jmp SHORT UMRFC_FreeExit
UMRFC_CmdSuccess:
mov bx, (DeviceInfo PTR [si]).pMassInfoPtr
push di
; Set DI to the buffer pointer
mov di, pUSBTempBuffer
mov eax, DWORD PTR [di+0]
xchg ah, al
rol eax, 16
xchg ah, al
cmp ax, 8
jb UMRFC_FreeExit ; Error
mov ax, WORD PTR [di+10]
xchg ah, al
mov (MassDeviceInfo PTR [bx]).wBlockSize, ax
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -