⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbmass.asm

📁 dos下的USB源码(包括UHCI
💻 ASM
📖 第 1 页 / 共 5 页
字号:
;----------------------------------------------------------------------------
;<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 + -