📄 usbmbb.asm
字号:
call USBM_IssueMassTransaction
UMRD_Exit:
pop edx
pop si
pop eax
ret
USBM_ReadDevice ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBM_UpdateCHSFromBootRecord
;
; Description: This function parses the boot record and extract the CHS
; information of the formatted media from the boot record.
; This routine checks for DOS & NTFS formats only
;
; Input: DS:DI Boot record of the device
;
; Output: ZR If the boot record is un-recognizable and CHS info
; is not extracted
; NZ If the boot record is recognizable and CHS info
; is extracted. CHS information is updated in the
; mass device info structure
;
; Modified: None
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBM_UpdateCHSFromBootRecord PROC NEAR SYSCALL
push eax
push ecx
push dx
; Check for valid MSDOS/MSWIN/NTFS boot record
mov eax, DWORD PTR [di+3]
cmp eax, 'ODSM' ; MSDO..
je UMGFT_GetCHSFromBootRecord
cmp eax, 'IWSM' ; MSWI..
je UMGFT_GetCHSFromBootRecord
; Check for valid FAT,FAT16 boot records
mov BYTE PTR [di+39h], 20h
cmp DWORD PTR [di+36h], ' TAF' ; FAT
je UMGFT_GetCHSFromBootRecord
;;; It may be FAT32, check that too
;; cmp DWORD PTR [di+52h], '3TAF' ; FAT3
;; je UMGFT_GetCHSFromBootRecord
; Invalid boot record. Return with error.
cmp sp, sp
jmp SHORT UMUCFBR_Exit
UMGFT_GetCHSFromBootRecord:
; Check what information we got from the device.
; If the device supports ReadCapacity command then we have only the last LBA
; value and the block size. So calculate cylinder value from the last LBA &
; head & sector value found in the boot record
; If the device supports ModeSense command then we have CHS information and
; block size value but not the last LBA value. So calculate last LBA from the
; CHS information
test wUSBCommandStatus, USB_CMDSTS_READ_CAPACITY_DONE
jz UMGFT_CheckForModeSense
; Calculate cylinder value
xor ax, ax
mov al, BYTE PTR [di+18h] ; Sectors/track
mov stMassDeviceInfo.bSectors, al
mov al, BYTE PTR [di+1Ah] ; heads
mov stMassDeviceInfo.bHeads, al
mul stMassDeviceInfo.bSectors
mov ecx, stMassDeviceInfo.dMaxLBA
xchg eax, ecx
push eax
pop ax
pop dx
div cx
mov stMassDeviceInfo.wCylinders, ax
jmp SHORT UMUCFBR_Done
UMGFT_CheckForModeSense:
test wUSBCommandStatus, USB_CMDSTS_MODE_SENSE_DONE
jz UMUCFBR_Done
; Calculate last LBA value
xor ax, ax
mov al, stMassDeviceInfo.bSectors
mul stMassDeviceInfo.bHeads
xor dx, dx
mul stMassDeviceInfo.wCylinders
push dx
push ax
pop eax
dec eax
mov stMassDeviceInfo.dMaxLBA, eax
UMUCFBR_Done:
or sp, sp
UMUCFBR_Exit:
pop dx
pop ecx
pop eax
ret
USBM_UpdateCHSFromBootRecord ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBM_GetFormatType
;
; Description: This function reads the first sector from the mass storage
; device and identifies the formatted type.
;
; Input: None
;
; Output: ZR If could not identify the formatted type
; NZ If formatted type is identified
;
; Modified: Nothing
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBM_GetFormatType PROC NEAR PUBLIC
push eax
push ebx
push cx
push dx
push edi
; Read the first sector of the device
; Set the LBA number to 0
xor eax, eax
push ds
push OFFSET ControlDataBuffer
pop edi
mov cx, 1 ; Number of blocks
xor ebx, ebx ; Pre/post skip bytes
call USBM_ReadDevice
jz UMGFT_Exit
; Check for validity of the partition table/boot record
cmp WORD PTR [di+1FEh], 0AA55h
jne UMGFT_SkipNotSuccess
; Check whether it has valid partition table
add di, 1BEh ; Start offset of partition table
xor ax, ax
mov dx, ax
; DX Contains first valid partition table entry
mov ecx, stMassDeviceInfo.dMaxLBA
UMGFT_VerifyPartitionTable:
cmp DWORD PTR [di+8], 0
jz UMGFT_CheckNextEntry
cmp DWORD PTR [di+8], ecx
ja UMGFT_InvalidPartitionTable ; FDD
inc ah
or dx, dx
jnz UMGFT_CheckNextEntry
mov dx, di
UMGFT_CheckNextEntry:
add di, 10h ; Point to next partition table entry
inc al
cmp al, 4
jb UMGFT_VerifyPartitionTable
; Check for valid partition table
cmp ah, 1
jb UMGFT_InvalidPartitionTable
; Valid partition table found. Check number of entries in the partition table
mov ax, dx ; Offset to the valid partition table entry
; Assume emulation as Forced FDD.
mov dx, (USB_EMU_FORCED_FDD SHL 8) + USB_MASS_DEV_ARMD
; Read boot sector
; Set the LBA number to boot record LBA number
mov di, OFFSET ControlDataBuffer
push di
mov di, ax
mov eax, DWORD PTR [di+8]
pop di
; Save hidden sector value
mov stMassDeviceInfo.bHiddenSectors, al
push ds
push di
pop edi
mov cx, 1 ; Number of blocks
xor ebx, ebx ; Pre/post skip bytes
call USBM_ReadDevice
jz UMGFT_Exit
UMGFT_VerifyBootRecord:
mov di, OFFSET ControlDataBuffer
; DS:DI Boot record
call USBM_UpdateCHSFromBootRecord
jz UMGFT_Exit ; Unrecognizable media
jmp SHORT UMGFT_EmulationFound
UMGFT_InvalidPartitionTable:
; Assume the emulation as floppy
mov dx, (USB_EMU_FLOPPY_ONLY SHL 8) + USB_MASS_DEV_ARMD
jmp SHORT UMGFT_VerifyBootRecord
UMGFT_EmulationFound:
; Set the emulation type
mov stMassDeviceInfo.bDevType, dl
mov stMassDeviceInfo.bEmuType, dh
; Clear the carry flag indicating success
or sp, sp ;
jmp SHORT UMGFT_Exit
UMGFT_SkipNotSuccess:
; Set zero flag
cmp sp, sp
UMGFT_Exit:
pop edi
pop dx
pop cx
pop ebx
pop eax
ret
USBM_GetFormatType ENDP
Comment ~
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBM_InquiryCommand
;
; Description: This function sends inquiry command to the USB mass storage
; device
;
; Input: None
;
; Output: ZR On error
; NZ On successfull completion
; bDevType Device type information
;
; Modified: None
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBM_InquiryCommand PROC NEAR SYSCALL PUBLIC
push eax
push ebx
push di
xor eax, eax
; Clear the common bulk transaction structure
call USBM_ClearMassBuffers
; DI Mass command buffer
mov (CommonInquiryCommand PTR [di]).OpCode, COMMON_INQUIRY_OPCODE
mov (CommonInquiryCommand PTR [di]).AllocLength, 024h
; Fill the common bulk transaction structure
mov stMassXactStruc.bCmdSize, SIZE CommonInquiryCommand
mov stMassXactStruc.bXferDir, BIT7 ; IN
push ds
pop ax
shl eax, 16
mov ax, OFFSET aMassDataBuffer
mov stMassXactStruc.fpBuffer, eax
; Allocation Length = 36 bytes
mov stMassXactStruc.dwLength, 024h
call USBM_IssueMassTransaction
jz UMIC_Exit
; Clear the cached block size
mov stMassDeviceInfo.wBlockSize, 0FFFFh
; Check for CDROM
mov di, OFFSET aMassDataBuffer
; Set the type as CDROM and emulation as HDD or FDD
mov al, USB_MASS_DEV_CDROM
cmp BYTE PTR DS:[di], 5
je UMIC_Done
xor ax, ax
UMIC_Done:
mov stMassDeviceInfo.bDevType, al
; Mark as success
or sp, sp
UMIC_Exit:
pop di
pop ebx
pop eax
ret
USBM_InquiryCommand ENDP
EndComment ~
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBM_StartUnitCommand
;
; Description: This function sends the start unit command to the mass device
;
; Input: None
;
; Output: ZR On failed completion
; NZ On successful completion
;
; Modified: Nothing
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBM_StartUnitCommand PROC NEAR SYSCALL PUBLIC
push di
; Check the compatibility flag for start unit command not supported
test CurrentDevice.wIncompatFlags, USB_INCMPT_START_UNIT_NOT_SUPPORTED
jnz UMSUC_Exit
call USBM_ClearMassBuffers
; DI Mass command buffer
mov (CommonStartStopUnitCommand PTR [di]).OpCode, \
COMMON_START_STOP_UNIT_OPCODE
mov (CommonStartStopUnitCommand PTR [di]).Start, 1
; Fill the common bulk transaction structure
mov stMassXactStruc.bCmdSize, SIZE CommonStartStopUnitCommand
call USBM_IssueMassTransaction
jnz UMSUC_Exit
; No data to read/write. So do not process return code.
; Request sense
call USBM_RequestSense
cmp sp, sp ; Return error
UMSUC_Exit:
pop bx
ret
USBM_StartUnitCommand ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBM_ModeSense
;
; Description: This function requests the mode sense data page number 5 from
; the USB mass storage device
;
; Input: None
;
; Output: ZR On failed command completion
; NZ On successful command completion
;
; Modified: Nothing
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBM_ModeSense PROC NEAR SYSCALL PUBLIC
push eax
push di
; Set return value as failure
xor ax, ax
call USBM_ClearMassBuffers
; DI Mass command buffer
; Load command into (just allocated) mass command buffer
mov (CommonModeSense10Command PTR [di]).OpCode, \
COMMON_MODE_SENSE_10_OPCODE
; Allocation Length = 40 bytes
mov ah, 028h ; MSB in low byte
mov (CommonModeSense10Command PTR [di]).AllocLength, ax
; Page code
mov (CommonModeSense10Command PTR [di]).PageCode, 5
; Fill the common bulk transaction structure
mov stMassXactStruc.bCmdSize, SIZE CommonModeSense10Command
mov stMassXactStruc.bXferDir, BIT7
push ds
pop ax
shl eax, 16
mov ax, OFFSET aMassDataBuffer
mov stMassXactStruc.fpBuffer, eax
mov stMassXactStruc.dwLength, 028h
call USBM_IssueMassTransaction
jz UMPMS_FreeExit
mov di, OFFSET aMassDataBuffer
; Store media type byte
mov al, (MODE_SENSE_10_HEADER PTR [di]).bMediaType
mov stMassDeviceInfo.bMediaType, al
; Position DI to the correct page code starting location
mov ax, (MODE_SENSE_10_HEADER PTR [di]).wBlkDescSize
add ax, SIZE MODE_SENSE_10_HEADER
add di, ax
; DI Points to the page code 5 data
; Validate mode sense data
cmp (PAGE_CODE_5 PTR [di]).bPageCode, 5
je UMPMS_ValidPageCode
cmp sp, sp ; Set zero flag
UMPMS_FreeExit:
; Request sense
call USBM_RequestSense
jmp SHORT UMPMS_Exit
UMPMS_ValidPageCode:
; Store bytes per sector
mov ax, (PAGE_CODE_5 PTR [di]).wBlockSize
xchg ah, al ; Change to big endian
mov stMassDeviceInfo.wBlockSize, ax
; Store heads/sector information
; Heads/sectors
mov ax, WORD PTR (PAGE_CODE_5 PTR [di]).bHeads
mov stMassDeviceInfo.bSectors, ah
mov stMassDeviceInfo.bHeads, al
mov ax, (PAGE_CODE_5 PTR [di]).wCylinders
xchg ah, al ; Change to big endian
mov stMassDeviceInfo.wCylinders, ax
; Set the appropriate command flag
or wUSBCommandStatus, USB_CMDSTS_MODE_SENSE_DONE
; Mark as success
or sp, sp ; Clear zero flag
UMPMS_Exit:
pop di
pop eax
ret
USBM_ModeSense ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBM_RequestSense
;
; Description: This function sends request sense command and returns
; the sense key information
;
; Input: None
;
; Output: ZR On error
; NZ On successful completion
;
; Modified: Nothing
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBM_RequestSense PROC NEAR SYSCALL PUBLIC
push eax
push di
xor eax, eax
dec eax
mov dLastSenseData, eax
call USBM_ClearMassBuffers
; DI Mass command buffer
mov (CommonRequestSenseCommand PTR [di]).OpCode, COMMON_REQUEST_SENSE_OPCODE
; Length of transfer
mov (CommonRequestSenseCommand PTR [di]).AllocLength, 12h
; Fill the common bulk transaction structure
mov stMassXactStruc.bCmdSize, SIZE CommonRequestSenseCommand
mov stMassXactStruc.bXferDir, BIT7
push ds
pop ax
shl eax, 16
mov ax, di
mov stMassXactStruc.fpBuffer, eax
mov stMassXactStruc.dwLength, 012h
call USBM_IssueMassTransaction
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -