📄 usbmass.asm
字号:
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBMassCreateLogicalUnits
;
; Description: This function verifies the presence of logical units (LUN)
; in the USB mass device and creates appropriate device info
; and mass device info structures for them
;
; Input: BX Device information structure pointer
; DI Mass device information structure pointer
; AL Maximum number of logical units present (non-ZERO)
;
; Output: ZR On error
; NZ On successfull completion
;
; Modified: Nothing
;
; Referrals: DeviceInfo, MassDeviceInfo
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBMassCreateLogicalUnits PROC NEAR SYSCALL
pusha
push fs
; Store the max LUN in Cl
mov cl, al
; Save the LUN 0 device info pointer address in FS
push bx
pop fs
mov dl, 1 ; Logical device number
UMCLU_NextLUN:
; Get the proper device info structure
mov eax, DWORD PTR (DeviceInfo PTR [bx]).wVendorId
; DL LUN
call USBGetProperDeviceInfoStructure
or si, si
jz UMCLU_Exit ; No free entry was found
; Check whether this device is reconnected by checking the valid structure
; flag
test (DeviceInfo PTR [si]).bFlag, DEV_INFO_VALID_STRUC
jz UMCLU_ProceedNormally ; No. This device is different
; Indicate device as connected
or (DeviceInfo PTR [si]).bFlag, (DEV_INFO_VALID_STRUC OR DEV_INFO_DEV_PRESENT)
jmp SHORT UMCLU_CheckForNextLUN
UMCLU_ProceedNormally:
; Copy the old device info structure into the new one
; BX to SI
call USBCopyDeviceInfoStruc
; Change LUN number
mov (DeviceInfo PTR [si]).bLUN, dl
; Allocate and copy the mass device info
mov di, (DeviceInfo PTR [si]).pMassInfoPtr
call USBMassFindFreeMassDeviceInfo
or di, di
jz UMCLU_Exit
; Save the Lun0 device info pointer in the current LUN
push fs
pop (MassDeviceInfo PTR [di]).pLUN0DevInfoPtr
; Update the new device info structure
mov (DeviceInfo PTR [si]).pMassInfoPtr, di
UMCLU_CheckForNextLUN:
inc dl
cmp cl, dl
jae UMCLU_NextLUN
UMCLU_Exit:
pop fs
popa
ret
USBMassCreateLogicalUnits ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBMassConfigureStorageDevice
;
; Description: This function checks an interface descriptor of a device
; to see if it describes a USB mass device. If the device
; is a mass storage device, then it is configured
; and initialized.
;
; Input: BX Device information structure pointer
; DI Pointer to the descriptor structure
; CX End offset of the device descriptor
;
; Output: ZR On error
; NZ On success
; BX - New DeviceInfo structure
;
; Modified: BX
;
; Referrals: HCStruc
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBMassConfigureStorageDevice PROC NEAR SYSCALL PUBLIC USES BX CX DX SI DI ES
LOCAL bTemp:BYTE
; Set the BiosDeviceType field in DeviceTableEntry[0]. This serves as a flag
; that indicates a usable interface has been found in the current
; configuration. This is needed so we can check for other usable interfaces
; in the current configuration (i.e. composite device), but not try to search
; in other configurations.
mov (DeviceInfo PTR [bx]).bDeviceType, BIOS_DEV_TYPE_STORAGE
mov (DeviceInfo PTR [bx]).pPollTDPtr, 0
mov (DeviceInfo PTR [bx]).pDevDriverPtr, \
OFFSET USBMassDeviceHeader
; Indicate device as connected
or (DeviceInfo PTR [bx]).bFlag, (DEV_INFO_VALID_STRUC OR DEV_INFO_DEV_PRESENT)
; Check whether the device is already registered. If so, proceed with current
; mass info structure
test (DeviceInfo PTR [bx]).bFlag, DEV_INFO_MASS_DEV_REGD
jz UMCM_NewMassDevice
; Set DI with mass device info pointer
mov di, (DeviceInfo PTR [bx]).pMassInfoPtr
jmp UMCM_MassDeviceOkay
UMCM_NewMassDevice:
; Use DL as temp scratch register for bitmap status of first reported
; Bulk In/Out endpoints on the interface
; Initialize mass storage specific entries in MassDeviceInfo[0]
mov si, OFFSET MassDeviceInfoTable
mov bTemp, 03h ; bit 1 = Bulk In, bit 0 = Bulk Out
UMCM_ConfigNewMassEndpoint:
; DI Points to an EndpointDescriptor.
mov al, (EndpointDescriptor PTR [di]).bEndpointFlags
and al, EP_DESC_FLAG_TYPE_BITS ; Isolate bits 1,0
cmp al, EP_DESC_FLAG_TYPE_BULK ; Bit 1-0: 10 = Endpoint does bulk transfers
jnz UMCM_BulkEndpointOver
mov al, (EndpointDescriptor PTR [di]).bEndpointAddr
mov dx, (EndpointDescriptor PTR [di]).wMaxPacketSize
and al, EP_DESC_ADDR_EP_NUM ; Bit 3-0: Endpoint number
test (EndpointDescriptor PTR [di]).bEndpointAddr, \
EP_DESC_ADDR_DIR_BIT ; Bit 7: Dir. of the endpoint
; 1/0 = In/Out
jnz UMCM_BulkInEndpoint
; Bulk-Out Endpoint found
test bTemp, 01h ; If Bulk-Out endpoint already found then
; skip subsequent ones on the interface
jz UMCM_BulkEndpointOver
mov (DeviceInfo PTR [bx]).bBulkOutEndpoint, al
mov (DeviceInfo PTR [bx]).wBulkOutMaxPkt, dx
and bTemp, 0FEh ; indicate first Bulk-Out endpoint found
jmp SHORT UMCM_BulkEndpointOver
UMCM_BulkInEndpoint:
; Bulk-In Endpoint found
test bTemp, 02h ; If Bulk-In endpoint already found then
; skip subsequent ones on the interface
jz UMCM_BulkEndpointOver
mov (DeviceInfo PTR [bx]).bBulkInEndpoint, al
mov (DeviceInfo PTR [bx]).wBulkInMaxPkt, dx
and bTemp, 0FDh ; indicate first Bulk-In endpoint found
UMCM_BulkEndpointOver:
; Check for and configure Interrupt endpoint if present
mov al, (EndpointDescriptor PTR [di]).bEndpointFlags
and al, EP_DESC_FLAG_TYPE_BITS ; Isolate bits 1,0
cmp al, EP_DESC_FLAG_TYPE_INT ; Bit 1-0: 10 = Endpoint does interrupt transfers
jnz UMCM_NotAnIntEndpoint
mov al, (EndpointDescriptor PTR [di]).bEndpointAddr
and al, EP_DESC_ADDR_EP_NUM ; Bit 3-0: Endpoint number
mov (DeviceInfo PTR [bx]).bIntEndpoint, al
mov ax, (EndpointDescriptor PTR [di]).wMaxPacketSize
mov (DeviceInfo PTR [bx]).wIntMaxPkt, ax
UMCM_NotAnIntEndpoint:
movzx ax, (EndpointDescriptor PTR [di]).bDescLength
or ax, ax
jz UMCM_ConfigMassEndpointOver
; Br if 0 length desc (should never happen, but...)
add di, ax ; DI = ptr to next desc
cmp di, cx
jae UMCM_ConfigMassEndpointOver
; Branch if past or at end of data
cmp (EndpointDescriptor PTR [di]).bDescType, DESC_TYPE_ENDPOINT
je UMCM_ConfigNewMassEndpoint ;Br if on an endpoint desc
UMCM_ConfigMassEndpointOver:
mov ax, OFFSET MassDeviceInfoTable
mov (DeviceInfo PTR [bx]).pMassInfoPtr, ax
mov di, OFFSET MassDeviceInfoTable
; Find a new mass device info structure and copy the old one into the new one
; DI Pointer to old mass device info structure
call USBMassFindFreeMassDeviceInfo
; DI New mass device info structure
or di, di
jnz UMCM_Success
UMCM_Error:
; No free entry found. Return with error
mov (DeviceInfo PTR [bx]).bFlag, 0
cmp sp, sp ; Set zero flag
jmp SHORT UMCM_Done
UMCM_Success:
mov (DeviceInfo PTR [bx]).pMassInfoPtr, di
UMCM_MassDeviceOkay:
; Check the compatibility flag for LUN support
test (DeviceInfo PTR [bx]).wIncompatFlags, USB_INCMPT_SINGLE_LUN_DEVICE
jnz UMCM_LUNConfigured
; If it is a BOT device, get maximum LUN supported
cmp (MassDeviceInfo PTR [di]).bProtocol, PROTOCOL_BOT
jne UMCM_LUNConfigured
; Get MAX LUN
call USBMassBOTGetMaxLUN ; AX max LUN
; Check whether more logical units are present ?
or al, al
jz UMCM_LUNConfigured
; More logical device found
; DI MassDeviceInfo structure
; BX DeviceInfo structure
; AL Max LUN
call USBMassCreateLogicalUnits
jz UMCM_Error ; No free entries found !
UMCM_LUNConfigured:
or sp, sp ; Clear zero flag (Success)
UMCM_Done:
ret
USBMassConfigureStorageDevice Endp
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBMassDisconnectStorageDevice
;
; Description: This function disconnects the storage device
;
; Input: BX Device information structure pointer
;
; Output: Nothing
;
; Modified: Nothing
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBMassDisconnectStorageDevice PROC NEAR SYSCALL PUBLIC USES AX BX SI
; Load registers with pointers to device info & mass info structure
mov si, (DeviceInfo PTR [bx]).pMassInfoPtr
; Mark the device as disconnected
and (DeviceInfo PTR [bx]).bFlag, NOT DEV_INFO_DEV_PRESENT
; Reset the toggle bits
mov (DeviceInfo PTR [bx]).bDataSync, 0
; Check whether the device is registered
test (DeviceInfo PTR [bx]).bFlag, DEV_INFO_MASS_DEV_REGD
jnz UMDSD_Exit ; Device registered. Do not invalidate struc.
; Free the mass device info structure
mov (MassDeviceInfo PTR [si]).bPresent, FALSE
; Mark the device info as invalid
and (DeviceInfo PTR [bx]).bFlag, NOT (DEV_INFO_VALID_STRUC \
OR DEV_INFO_MASS_DEV_REGD)
UMDSD_Exit:
ret
USBMassDisconnectStorageDevice Endp
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBMassClearMassXactStruc
;
; Description: This function clears the mass transaction structure
;
; Input: Nothing
;
; Output: Nothing
;
; Modified: None
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBMassClearMassXactStruc PROC NEAR SYSCALL PUBLIC
push ax
push cx
push di
push es
push ds
pop es
mov di, OFFSET stMassXactStruc
xor ax, ax
mov cx, SIZE MASS_XACT_STRUC
rep stosb
pop es
pop di
pop cx
pop ax
ret
USBMassClearMassXactStruc ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBMassClearBulkEndpointStall
;
; Description: This function clears the bulk endpoint stall by sending
; CLEAR_FEATURE command to bulk endpoints
;
; Input: SI Pointer to DeviceInfo structure
; DI Pointer to MassDeviceInfo structure
; AL Endpoint direction
;
; Output: Nothing
;
; Modified: None
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBMassClearBulkEndpointStall PROC NEAR SYSCALL PUBLIC
push eax
push ebx
push cx
push dx
xor cx, cx
; Save AL in DL
mov dl, al
mov cl, (DeviceInfo PTR [si]).bBulkInEndpoint
or cl, BIT7
test dl, BIT7
jnz UMCBES_EndpointFound
; Bulk OUT endpoint
mov cl, (DeviceInfo PTR [si]).bBulkoutEndpoint
UMCBES_EndpointFound:
; Issue clear port feature command
; SI = DeviceInfo
push cx
push si
pop ebx ; BX+ = wIndex, BX = Device Info
mov eax, (ENDPOINT_CLEAR_PORT_FEATURE SHL 16) + ENDPOINT_HALT
call USBIssueControlTransferWithoutData
; Reset the toggle bit
mov cl, USB_BULK_IN_DATA_SYNC_SHIFT
test dl, BIT7
jnz UMCBES_InPacket
; It is an OUT transaction get appropriate size
mov cl, USB_BULK_OUT_DATA_SYNC_SHIFT
UMCBES_InPacket:
; Reset toggle bit
mov al, 1
shl al, cl
not al
and (DeviceInfo PTR [si]).bDataSync, al
cmp (MassDeviceInfo PTR [di]).pLUN0DevInfoPtr, 0
je UMCBES_ToggleBitDone
push di
mov di, (MassDeviceInfo PTR [di]).pLUN0DevInfoPtr
and (DeviceInfo PTR [di]).bDataSync, al
pop di
UMCBES_ToggleBitDone:
pop dx
pop cx
pop ebx
pop eax
ret
USBMassClearBulkEndpointStall ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBMassIssueMassTransaction
;
; Description: This function performs a mass storage transaction by
; invoking proper transaction protocol.
;
; Input: SI Pointer to DeviceInfo structure
; 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
;
; Referrals:
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBMassIssueMassTransaction PROC NEAR SYSCALL PUBLIC
push si
push di
; Get mass device info structure for this device
mov di, (DeviceInfo PTR [si]).pMassInfoPtr
; Check for CBI & CBI no interrupt protocol
cmp (MassDeviceInfo PTR [di]).bProtocol, PROTOCOL_CBI
je UMIMT_CBIProtocol
cmp (MassDeviceInfo PTR [di]).bProtocol, PROTOCOL_CBI_NO_INT
jne UMIMT_BOTProtocol
UMIMT_CBIProtocol:
; The device supports CBI protocol
call USBMassIssueCBITransaction
jmp SHORT UMIMT_Exit
UMIMT_BOTProtocol:
; Check for BOT protocol
cmp (MassDeviceInfo PTR [di]).bProtocol, PROTOCOL_BOT
jne UMIMT_Error
; The device supports BOT protocol
call USBMassIssueBOTTransaction
jmp SHORT UMIMT_Exit
UMIMT_Error:
xor eax, eax
UMIMT_Exit:
pop di
pop si
ret
USBMassIssueMassTransaction ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBMassGetDeviceParameters
;
; Description: This function gets the USB mass device parameters such as
; max cylinder, head, sector, block size and
;
; Input: SI DeviceInfo structure
;
; Output: ZR On error
; NZ On success
; DI Pointer to the temp buffer
;
; Modified: DI
;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -