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

📄 usbh_storage_if.c

📁 epson usb2.0 控制芯片 S1R72V05 固件程序。
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
 * description: USBH Mass Storage Class Interface
 * Maker	  : Shuichi Yanagihara
 * Copyright  : (C)2005,SEIKO EPSON Corp. All Rights Reserved.
 */

#include "SPRDEF.h"
#include "SPRSTS.h"
#include "OSCall.h"
#include "drvacs.h"
#include "usbh_SampleTask.h"
#include "usbh_storage_api.h"
#include "usbh_storage_if.h"
#include "usbh_usbd_api.h"
#include "usbh_hcd.h"
#include "usbh_hcds_common.h"
#include <DebugTask.h>

/*****************************************
 * Constants define
 *****************************************/

/* Command Status */
#define NO_OP							0x00							/* Command No Operation */
#define URB_LINK						0x01							/* Register USB */
#define WAIT_START						0x02							/* waiting for start with DirectCopy Mode.	*/
#define CBW_CMP							0x03							/* CBW transfer complete */
#define DATA_CMP						0x04							/* Daata transfer complete */
#define CSW_CMP							0x05							/* CSW transfer complete */

#define CLEAR_EP_IN						0x00
#define CLEAR_EP_OUT					0x01

#define MASK_EP_NUMBER					(0x7F)

/*****************************************
 * structures declaration
 *****************************************/
/* BulkOnly Transport CBW */
typedef struct tagUSBH_STRG_CBW{
	ULONG	signature;
	ULONG	tag;
	ULONG	transferLength;
	UCHAR	flag;
	UCHAR	lun;
	UCHAR	cbdLength;
	UCHAR	cbd[16];
}USBH_STRG_CBW;

/* BulkOnly Transport CSW */
typedef struct tagUSBH_STRG_CSW{
	ULONG	signature;
	ULONG	tag;
	ULONG	dataResidue;
	UCHAR	status;
}USBH_STRG_CSW;

/* Control transfer,Setup packet */
typedef struct tagUSBH_STRG_CTL_SETUP{
	UCHAR	bmRequestType;
	UCHAR	bRequest;
	USHORT	wValue;
	USHORT	wIndex;
	USHORT	wLength;
}USBH_STRG_CTL_SETUP;

/*****************************************
 * Function prototype declaration
 *****************************************/
static LONG USBH_STRG_PutCmd( USHORT deviceNo, DRIVEACCESS_FUNCCMDPARA *pCmdBlock, UCHAR opCode);
static LONG USBH_STRG_MakeStorageURB( USHORT deviceNo, UCHAR transferMode, DRIVEACCESS_FUNCCMDPARA *pCmdBlock, DRIVEACCESS_FUNCTRANPARA *pTranPara, USBH_USBD_URB *pUrb );
static LONG USBH_STRG_MakeCtlURB( USHORT deviceNo, USBH_STRG_CTL_SETUP *pSetup, UCHAR *pTranData, USBH_USBD_URB *pUrb );
static LONG USBH_STRG_ResetRecovery( USHORT deviceNo );
static void USBH_STRG_USBDInitCallback( ULONG event, ULONG param1, void *pParam );
static void USBH_STRG_DeviceCallback( ULONG event, ULONG param1, void *pParam );
static void USBH_STRG_ReturnValueCallback( ULONG event, ULONG param1, void *pParam );
static void USBH_STRG_SetConfigCallback( ULONG event, ULONG param1, void *pParam );
static void USBH_STRG_ResetCallback( ULONG event, ULONG param1, void *pParam );
static void USBH_STRG_SubmitURBCallback( ULONG event, ULONG param1, void *pParam );
static void USBH_STRG_UnlinkURBCallback( ULONG event, ULONG param1, void *pParam );
static void USBH_STRG_CBWCompCallback( USBH_USBD_URB *pUrb);
static void USBH_STRG_DataCompCallback( USBH_USBD_URB *pUrb);
static void USBH_STRG_CSWCompCallback( USBH_USBD_URB *pUrb);
static void USBH_STRG_CtlCompCallback( USBH_USBD_URB *pUrb);

/*****************************************
 * Macros definition
 *****************************************/

/*****************************************
 * Variables definition
 *****************************************/
static DRIVEACCESS_FUNCDEVICELIST	DeviceList;										/* Device list (device type & the number of devices connected.) */
static DRIVEACCESS_FUNCDEVICELIST	*pDeviceList;									/* Device list (device type & the number of devices connected.) */
static UCHAR						classid;										/* Class ID number */
static USBH_STRG_CTL_SETUP			setupData[USBH_STRG_MAX_DEVICE];
static USBH_USBD_URB				ctlUrb[USBH_STRG_MAX_DEVICE],					/* Storage Class Control URB */
									cbwUrb[USBH_STRG_MAX_DEVICE],					/* Storage Class CBW URB */
									dataUrb[USBH_STRG_MAX_DEVICE],				/* Storage Class Data URB */
									cswUrb[USBH_STRG_MAX_DEVICE];					/* Storage Class CSW URB */
static USBH_STRG_CBW				bulkCbw[USBH_STRG_MAX_DEVICE];				/* CBW Data */
static USBH_STRG_CSW				bulkCsw[USBH_STRG_MAX_DEVICE];				/* CSW Data */
static USBH_STRG_DEVICE_PARA		devicePara[USBH_STRG_MAX_DEVICE];				/* Device Information Parameter */
static CALLBACK_PROC				USBH_STRG_IFDMACompCBR[USBH_STRG_MAX_DEVICE];	/* DMA Complete CALLBACK TABLE */
static CALLBACK_PROC				USBH_STRG_IFIntrqCompCBR[USBH_STRG_MAX_DEVICE];	/* Intrq Complete CALLBACK TABLE */
static USBH_STRG_CALLBACK_PARA		callbackPara;									/* The cyccle handler parameter that passed from the Callback */
static USBH_STRG_CYCHDR_PARA		cychdrPara;										/* the parameter that used for internal information of cycle handler  */


/*=============================================================================================
// Function_Name: USBH_STRG_IFReset
//
// description	: Initialize this module
//
//				  Initialize the internal variables used in this module.
//
// argument 	: void
//
// return		: STATUS_SUCCESS					Completed successfully
//				  STATUS_UNSUCCESSFUL				Completed with error
//
// global		: classid							The class ID number

===============================================================================================*/
LONG USBH_STRG_IFReset( void )
{
	USHORT		i, j;
	LONG		result;
	OS_FLGPTN	flgPtn;


	pDeviceList = &DeviceList;
	for(i = 0; i < USBH_STRG_MAX_DEVICE; i++){
		/* DeviceParameter Initialize */
		devicePara[i].devAdr = 0;
		devicePara[i].subClass = 0;
		devicePara[i].lun = 0;
		devicePara[i].commandStatus = NO_OP;
		devicePara[i].deviceStatus = DRV_FUNC_CMD_COMP;
		/* Request Sensd Data Initialize */
		for(j = 0; j < REQSENSE_LENGTH; j++) {
			devicePara[i].reqSenseData[j] = 0;
		}
		devicePara[i].reqSenseData[2] = MEDIUM_ERROR;
		/* Identify Data Initialize */
		for(j = 0; j < IDENTIFY_LENGTH; j++) {
			devicePara[i].identifyData[j] = 0;
		}
		/* DeviceList Initialize */
		pDeviceList->deviceType[i] = NO_DEVICE;
		/* CBW Initialize */
		bulkCbw[i].signature = CBW_SIGNATURE;
		bulkCbw[i].tag = 0;
	}
	pDeviceList->deviceCount = USBH_STRG_MAX_DEVICE;
	/* Clear the status of the cycle handler. */
	cychdrPara.ctlPass = EVENT_NONE;

	/* USBD initialization */
	result = USBH_USBD_Init(USBH_STRG_USBDInitCallback);
	if( result != USBH_USBD_STATUS_SUCCESS ){
		return STATUS_UNSUCCESSFUL;
	}

	/* Waiting for the completion of the USBD initialization */
	OS_WaiFlg(FLGID_USBH_SAMPLE, FLG_EVENT_USBDINIT_CMP_USBH_SAMPLE, OS_TWF_ORW, &flgPtn);
	OS_ClrFlg(FLGID_USBH_SAMPLE, ~(FLG_EVENT_USBDINIT_CMP_USBH_SAMPLE));

	/* Register to USBD */
	result = USBH_USBD_EntryClass(STRG_CLASS_CODE, &classid, USBH_STRG_ReturnValueCallback, USBH_STRG_DeviceCallback);
	if( result != USBH_USBD_STATUS_SUCCESS ){
		return STATUS_UNSUCCESSFUL;
	}

	/* Waiting for the completion of the USBD registration. */
	OS_WaiFlg(FLGID_USBH_SAMPLE, FLG_EVENT_USBDENTRY_CMP_USBH_SAMPLE, OS_TWF_ORW, &flgPtn);
	OS_ClrFlg(FLGID_USBH_SAMPLE, ~(FLG_EVENT_USBDENTRY_CMP_USBH_SAMPLE));

	if(callbackPara.event != USBH_USBD_MSG_ENTRYC_NG ) {
		return STATUS_UNSUCCESSFUL;
	}

	return result;
}

/*=============================================================================================
// Function_Name: USBH_STRG_IFDeviceReset
//
// description	: Reset the specified device
//
//				  The reset demand of the specified device is lodged to the subordinate position module.
//				  When processing it to the device, that processing is interrupted.
//
// argument 	: deviceNo							(in)Device No.
//
// return		: STATUS_SUCCESS					Completed successfully
//				  STATUS_UNSUCCESSFUL				Completed with error
//
// flag			: OpenFlag							Indicates if the module is usable
//
// global		: classid							The class ID number


===============================================================================================*/
LONG USBH_STRG_IFDeviceReset( USHORT deviceNo )
{
	LONG		result;
	OS_FLGPTN	flgPtn;

	/* If the URB is in registering, cancel it. */
	switch(devicePara[deviceNo].commandStatus) {
		case URB_LINK:
			USBH_USBD_UnlinkURB(&cbwUrb[deviceNo], classid, USBH_STRG_UnlinkURBCallback);
			break;
		case CBW_CMP:
			USBH_USBD_UnlinkURB(&cbwUrb[deviceNo], classid, USBH_STRG_UnlinkURBCallback);
			break;
		case DATA_CMP:
			USBH_USBD_UnlinkURB(&cbwUrb[deviceNo], classid, USBH_STRG_UnlinkURBCallback);
			break;
		case CSW_CMP:
			devicePara[deviceNo].commandStatus = NO_OP;
			break;
	}

	if(devicePara[deviceNo].commandStatus != NO_OP) {
		/* Waiting for the completion of UnlinkURB */
		OS_WaiFlg(FLGID_USBH_SAMPLE, FLG_EVENT_UNLINKURB_CMP_USBH_SAMPLE, OS_TWF_ORW, &flgPtn);
		OS_ClrFlg(FLGID_USBH_SAMPLE, ~(FLG_EVENT_UNLINKURB_CMP_USBH_SAMPLE));
		if(callbackPara.event != USBH_USBD_MSG_UNLINK_OK) {
			return STATUS_UNSUCCESSFUL;
		} else {
			devicePara[deviceNo].commandStatus = NO_OP;
		}
	}

	/* Reset demand for specified device */
	result = USBH_USBD_Reset(classid, devicePara[deviceNo].devAdr, USBH_STRG_ResetCallback);
	if(result != STATUS_SUCCESS) {
		return result;
	}

	/* Waiting for the URB Reset Complete */
	OS_WaiFlg(FLGID_USBH_SAMPLE, FLG_EVENT_USBRESET_CMP_USBH_SAMPLE, OS_TWF_ORW, &flgPtn);
	OS_ClrFlg(FLGID_USBH_SAMPLE, ~(FLG_EVENT_USBRESET_CMP_USBH_SAMPLE));

	devicePara[deviceNo].deviceStatus = DRV_FUNC_CMD_COMP;

	return STATUS_SUCCESS;
}

/*=============================================================================================
// Function_Name: USBH_STRG_IFGetDeviceList
//
// description	: It informs the upper layer of the number of connected devices and each device type.

//
//				  It informs the upper layer of the number of connected devices and each device type.
//
// argument 	: *pList							(in)the pointer that points to the device list.
//
// return		: STATUS_SUCCESS					Completed successfully
//				  STATUS_UNSUCCESSFUL				Completed with error
===============================================================================================*/
LONG USBH_STRG_IFGetDeviceList( UCHAR *pList )
{
	UCHAR	i;


	/* Change pDeviceList to pList */
	((DRIVEACCESS_FUNCDEVICELIST *)pList)->deviceCount = pDeviceList->deviceCount;
	for(i=0; i < USBH_STRG_MAX_DEVICE; i++){
		if( pDeviceList->deviceType[i] == NO_DEVICE ){
			((DRIVEACCESS_FUNCDEVICELIST *)pList)->deviceType[i] = DRV_FUNC_CF;
		} else {
			((DRIVEACCESS_FUNCDEVICELIST *)pList)->deviceType[i] = pDeviceList->deviceType[i];
		}
	}

	return STATUS_SUCCESS;
}

/*=============================================================================================
// Function_Name: USBH_STRG_IFGetDeviceParameter
//
// description	: It informs the upper layer of the detailed information of the connected device.
//
//				  It informs the upper layer of the detailed information of the connected device.
//				  Device information is 256 word data that can be acquired with Identify(Packet) Device.

//
// argument 	: deviceNo							(in)Device No.
//				  *pDataPtr							(out)The pointer that points to thedevice information.
//
// return		: STATUS_SUCCESS					Completed successfully
//				  STATUS_UNSUCCESSFUL				Completed with error
===============================================================================================*/
LONG USBH_STRG_IFGetDeviceParameter( USHORT deviceNo, UCHAR *pDataPtr)
{
	UCHAR						senseKey = 0x00, inqData[INQUIRY_LENGTH], rdCapaData[8], rdFormCapaData[20];
	USHORT						i;
	LONG						result;
	ULONG						status;
	DRIVEACCESS_FUNCCMDPARA		cmdBlock;
	DRIVEACCESS_FUNCTRANPARA	tranPara;


	/* Get the device information in the case that the device infornmation unacquisited */
	if(devicePara[deviceNo].identifyData[1] == 0x00) {
		/* Execute TEST UNIT READY */
		result = USBH_STRG_PutCmd(deviceNo, &cmdBlock, TEST_UNIT_READY);
		if(result != STATUS_SUCCESS) {
			return STATUS_UNSUCCESSFUL;
		}
		tranPara.dataSize = 0;
		/* When error occure,it retry untill becoming No Sense. */
		do {
			result = USBH_STRG_IFSyncCommand(deviceNo, (UCHAR)devicePara[deviceNo].commandMode, &cmdBlock, &tranPara, &status, devicePara[deviceNo].reqSenseData);
			if(result == STATUS_UNSUCCESSFUL) {
				senseKey = devicePara[deviceNo].reqSenseData[2] & 0x0F;
				/* When error ocured,check the Sense Key */
				if(senseKey == HARDWARE_ERROR) {
					return STATUS_UNSUCCESSFUL;
				}
			}
		} while(senseKey != NO_SENSE);

		/* Execute INQUIRY */
		result = USBH_STRG_PutCmd(deviceNo, &cmdBlock, INQUIRY);
		if(result != STATUS_SUCCESS) {
			return STATUS_UNSUCCESSFUL;
		}
		tranPara.dataPointer = (ULONG) &inqData[0];
		result = USBH_STRG_IFSyncCommand(deviceNo, (UCHAR)devicePara[deviceNo].commandMode, &cmdBlock, &tranPara, &status, devicePara[deviceNo].reqSenseData);
		if(result != STATUS_SUCCESS) {
			return STATUS_UNSUCCESSFUL;
		}
		/*** Generate the Identify Data ***/
		/* Device Type Set */
		devicePara[deviceNo].identifyData[0] = inqData[0] & 0x1F;
		/* Update the DeviceTypeof DeviceList */
		switch(devicePara[deviceNo].identifyData[0]) {
			case DIRECT_DEV:
				pDeviceList->deviceType[deviceNo] = DRV_FUNC_HDD;
				break;
			case WRONCE_DEV:
			case CDROM_DEV:
				pDeviceList->deviceType[deviceNo] = DRV_FUNC_CD;
				break;
			case OPTICAL_DEV:
				pDeviceList->deviceType[deviceNo] = DRV_FUNC_MO;
				break;
			default:
				break;
		}
		/* Removable Set */
		if( (inqData[1] & 0x80) != 0) {
			devicePara[deviceNo].identifyData[1] = inqData[1];
		} else {
			/* Turned on the Non-Removal Bit at non-Removable device. */
			devicePara[deviceNo].identifyData[1] = (~inqData[1]) & 0x40;
		}
		/* Vendor ID Set */
		devicePara[deviceNo].identifyData[54] = inqData[8];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -