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

📄 usbms_state.c

📁 MTK平台绝密核心代码之 USB驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
/*****************************************************************************
*  Copyright Statement:
*  --------------------
*  This software is protected by Copyright and the information contained
*  herein is confidential. The software may not be copied and the information
*  contained herein may not be used or disclosed except with the written
*  permission of MediaTek Inc. (C) 2005
*
*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
*
*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. 
*
*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
*
*****************************************************************************/

/*****************************************************************************
 *
 * Filename:
 * ---------
 *    usbms_state.c
 *
 * Project:
 * --------
 *   Maui_Software
 *
 * Description:
 * ------------
 *    This file implements usb mass storage state machine
 *
 * Author:
 * -------
 * -------
 * -------
 *
 *============================================================================
 *             HISTORY
 * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
 *------------------------------------------------------------------------------
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 *------------------------------------------------------------------------------
 * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
 *============================================================================
 ****************************************************************************/
 
#include "drv_comm.h"
#include "stack_common.h"  
#include "stack_msgs.h"
#include "app_ltlcom.h"  
#include "drvsignals.h"

#include "usb_comm.h"
#include "usb_drv.h"
#include "usb.h"
#include "usbms_utils.h"
#include "usbms_drv.h"
#include "usbms_adap.h"
#include "usbms_state.h"
#include "usb_custom.h"

/* sense code */
static const kal_uint8 senseOk[] = {0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static const kal_uint8 senseNoMedia[] = {0x70, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 
						0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x00, 0x00};
static const kal_uint8 senseMediaChanged[] = {0x70, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 
						0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00};
static const kal_uint8 senseInvalidFieldInCDB[] = {0x70, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 
							0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00};
#ifdef __P_PROPRIETARY_COPYRIGHT__
static const kal_uint8 senseDataProtect[] = {0x70, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 
							0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
#endif							

static USB_MS_ERROR USB_Ms_Recv_Data(local_para_struct *buf);
static USB_MS_ERROR USB_Ms_Transmit_Data(local_para_struct *buf);

static void USB_Ms_Generate_Csw(UsbMs_CSW *CSW, UsbMs_CBW *CBW);
static void USB_Ms_MemInverse(void *src, void *dst, kal_uint16 len);
static void USB_Ms_Cmd(void *data);
static void USB_Ms_Cmd_Format(kal_uint8 LUN, UsbMs_CBW *CBW);
static void USB_Ms_State_Checkmedia_Exist(kal_uint8 LUN);
static void USB_Ms_Cmd_Inquiry(UsbMs_CBW *CBW);
static void USB_Ms_Cmd_Test_Unit_Ready(kal_uint8 LUN, UsbMs_CBW *CBW);
static void USB_Ms_Cmd_Prev_Media_Removal(kal_uint8 LUN, UsbMs_CBW *CBW);
static void USB_Ms_Cmd_Read_Capacity(kal_uint8 LUN, UsbMs_CBW *CBW);
static void USB_Ms_Cmd_Read_FormatCapacity(kal_uint8 LUN, UsbMs_CBW *CBW);
static void USB_Ms_Cmd_RequestSense(UsbMs_CBW *CBW);
static void USB_Ms_Cmd_Verify(kal_uint8 LUN, UsbMs_CBW *CBW);
static void USB_Ms_Cmd_ModeSense6(kal_uint8 LUN, UsbMs_CBW *CBW);
static void USB_Ms_Cmd_Unknown(UsbMs_CBW *CBW);
static void USB_Ms_Cmd_Read(kal_uint8 LUN, UsbMs_CBW *CBW);
static void USB_Ms_Handle_Read(kal_uint8 LUN, UsbMs_CBW *CBW);
static void USB_Ms_Read_Fail_Handler(kal_uint8 LUN, UsbMs_CBW *CBW);
static void USB_Ms_Cmd_Write(kal_uint8 LUN, UsbMs_CBW *CBW);
static void USB_Ms_Handle_Write(kal_uint8 LUN, UsbMs_CBW *CBW, kal_uint8 sector_num);

#ifdef __P_PROPRIETARY_COPYRIGHT__
static kal_bool	USB_Ms_Search_Item(kal_uint32* data_items, kal_uint32 data_size, kal_uint32 search_value, kal_uint32 *p_index);
static void USB_Ms_Sort_Index_Items(kal_uint32* items, kal_uint32 num);
static kal_bool	USB_Ms_Check_Read_Protect(kal_uint8 LUN, kal_uint32 LBA, kal_uint32 sec_num);
static kal_bool	USB_Ms_Check_Second_Read_Protect(kal_uint8 LUN, kal_uint32 LBA, kal_uint32 sec_num);
static void USB_Ms_Update_Read_Protect(kal_uint8 LUN, kal_uint32 LBA, kal_uint32 sec_num);
#endif

/************************************************************
        Tx/Rx path state machine functions
*************************************************************/
void USB_Ms_State_Main(ilm_struct *p_recv_ilm)
{
	USB_MS_ERROR ms_error;
	
	switch(p_recv_ilm->msg_id)
	{
	case MSG_ID_USB_MSDRV_REC_DONE_CONF:
		/* receive data from DMA callback*/
		ms_error = USB_Ms_Recv_Data(p_recv_ilm->local_para_ptr);
		if(ms_error != USB_MS_ERROR_OK)
		{
			EXT_ASSERT(0, (kal_uint32)ms_error, 0, 0 );
		}
		break;
		
	case MSG_ID_USB_MSDRV_TRX_DONE_CONF:
		/* transmitted data from DMA callback*/
		ms_error =USB_Ms_Transmit_Data(p_recv_ilm->local_para_ptr);
		if(ms_error != USB_MS_ERROR_OK)
		{
			EXT_ASSERT(0, (kal_uint32)ms_error, 0, 0);
		}
		break;
		
	case MSG_ID_USB_RESET_IND:
		/* reset from reset signal or class specific EP0 RESET command*/
		g_UsbMS.nState = USBMS_IDLE;
		USB_Ms_BuildRx(g_UsbMS.CBWdata, 31);
		g_UsbMS.is_send_usb_reset_ilm = KAL_TRUE;
		break;
	}
}




/*receive path state machine*/
static USB_MS_ERROR USB_Ms_Recv_Data(local_para_struct *buf)
{
	UsbMs_CBW   *CBW;
	kal_uint8   *CBWCB;
	kal_uint8   sector_num;
	usb_ms_rec_done_conf_struct *ptr=(usb_ms_rec_done_conf_struct *)buf;
	USB_MS_ERROR re_value = USB_MS_ERROR_OK;

	switch(g_UsbMS.nState)
	{
	case USBMS_IDLE:
		if (ptr->nBytesRecv != 31)
		{
			EXT_ASSERT(0, ptr->nBytesRecv, 0, 0);
		}
		USB_Ms_Cmd(g_UsbMS.CBWdata);
		break;
	case USBMS_RX:
		CBW = (UsbMs_CBW*)g_UsbMS.CBWdata;
		CBWCB = (kal_uint8 *)CBW->CBWCB;
		if (CBWCB[0] == USBMS_WRITE)
		{
			sector_num = ptr->nBytesRecv/512;	
			USB_Ms_Handle_Write(g_UsbMS.current_LUN, CBW, sector_num);		
		}
		else  /*if (CBWCB[0] == USBMS_CMD_Write)*/
		{
			EXT_ASSERT(0, (kal_uint32)CBW->CBWCB[0], 0, 0);
		}
		break;
	case USBMS_GETNEXTCMD:
		re_value = USB_MS_ERROR_RX_GETNEXTCMD;
		break;
	case USBMS_ACK:
		re_value = USB_MS_ERROR_RX_ACK;
		break;	
	case USBMS_TX:
		re_value = USB_MS_ERROR_RX_TX;
		break;
	default:
		EXT_ASSERT(0, (kal_uint32)g_UsbMS.nState, 0, 0);
		break;
	}

	return re_value;
}

/*transmit path state machine*/
static USB_MS_ERROR USB_Ms_Transmit_Data(local_para_struct *buf)
{
	UsbMs_CBW *CBW = (UsbMs_CBW*)g_UsbMS.CBWdata;
	USB_MS_ERROR re_value = USB_MS_ERROR_OK;

	switch(g_UsbMS.nState)
	{
	case USBMS_GETNEXTCMD:
		g_UsbMS.nState = USBMS_IDLE;
		USB_Ms_BuildRx(g_UsbMS.CBWdata, 31);
		break;
	case USBMS_ACK:
		/*Send CSW*/
		g_UsbMS.nState = USBMS_GETNEXTCMD;
		USB_Ms_Generate_Csw(&g_UsbMS.CSW, CBW);
		USB_Ms_BuildTx(&g_UsbMS.CSW, 13);
		break;
	case USBMS_TX:
		if (CBW->CBWCB[0] == USBMS_READ)
		{
			USB_Ms_Handle_Read(g_UsbMS.current_LUN, CBW);
		}
		else
		{
			EXT_ASSERT(0, (kal_uint32)CBW->CBWCB[0], 0, 0);
		}
		break;
	case USBMS_IDLE:
		re_value = USB_MS_ERROR_TX_IDLE;
		break;
	case USBMS_RX:
		re_value = USB_MS_ERROR_TX_RX;
		break;
	default:
		EXT_ASSERT(0, (kal_uint32)g_UsbMS.nState, 0, 0);
		break;
	}

	return re_value;
}


/************************************************************
        utility functions
*************************************************************/

/* generate CSW element according to CBW and kept status */
static void USB_Ms_Generate_Csw(UsbMs_CSW *CSW, UsbMs_CBW *CBW)
{
//	USB_Ms_Dbg_Trace(USB_DBG_GENERATE_CSW, 0);
	CSW->dCSWSignature = 0x53425355;
	CSW->dCSWTag = CBW->dCBWTag;
	CSW->dCSWDataResidue = g_UsbMS.CSWDataResidue;
	CSW->bmCSWStatus = g_UsbMS.CSWStatusError;
	g_UsbMS.CSWStatusError = KAL_FALSE;
	g_UsbMS.CSWDataResidue = 0;
}

/* inverse scr to dst, total len*/
static void USB_Ms_MemInverse(void *src, void *dst, kal_uint16 len)
{
	kal_uint8 index;
	kal_uint8 *li_data = (kal_uint8 *)src;
	kal_uint8 *bi_data = (kal_uint8 *)dst;
	li_data+=(len-1);
	for(index =0; index<len; index++)
		*(bi_data+index) = *(li_data-index);
}


/************************************************************
        CBW parse command functions
*************************************************************/

/* parse CBW command */
static void USB_Ms_Cmd(void *data)
{
	UsbMs_CBW *CBW = (UsbMs_CBW *)data;
	kal_uint8   *CBWCB;

	CBWCB = (kal_uint8*)CBW->CBWCB;

	if( (CBW->dCBWSignature != 0x43425355) || (CBW->bCBWLUN > g_UsbMS.max_LUN) )
	{
		USB_CtrlEPStall(g_UsbMS.txpipe->byEP, USB_IN_EP_TYPE, KAL_TRUE, USB_CTRL_STALL_ENTRY_3);
		USB_CtrlEPStall(g_UsbMS.rxpipe->byEP, USB_OUT_EP_TYPE, KAL_TRUE, USB_CTRL_STALL_ENTRY_3);
		g_UsbMS.nState = USBMS_IDLE;
		return;
	}

	/* keep current LUN */
	g_UsbMS.current_LUN = CBW->bCBWLUN;

	/* determine state */
	if (CBW->dCBWDataTransferLength!=0)
	{
		if (CBW->bmCBWFlags & USBMS_DIR_IN)
			g_UsbMS.nState = USBMS_TX;
		else
			g_UsbMS.nState = USBMS_RX;
	}

//	USB_Ms_Dbg_Trace(USB_DBG_CMD, CBWCB[0]);

	/* parse command */
	switch(CBWCB[0])
	{
	case USBMS_FORMAT_UNIT:
		USB_Ms_Cmd_Format(CBW->bCBWLUN, CBW);
		break;
	case USBMS_INQUIRY:
		USB_Ms_Cmd_Inquiry(CBW);
		break;
	case USBMS_TEST_UNIT_READY:
		USB_Ms_Cmd_Test_Unit_Ready(CBW->bCBWLUN, CBW);
		break;
	case USBMS_PREVALLOW_MEDIA_REMOVL:
		USB_Ms_Cmd_Prev_Media_Removal(CBW->bCBWLUN, CBW);
		break;
	case USBMS_WRITE:
		USB_Ms_Cmd_Write(CBW->bCBWLUN,CBW);
		break;
	case USBMS_READ:
		USB_Ms_Cmd_Read(CBW->bCBWLUN,CBW);
		break;
	case USBMS_READ_CAPACITY:
		USB_Ms_Cmd_Read_Capacity(CBW->bCBWLUN, CBW);
		break;
	case USBMS_READ_FORMATCAPACITY:
		USB_Ms_Cmd_Read_FormatCapacity(CBW->bCBWLUN, CBW);
		break;
	case USBMS_REQUESTSENSE:
		USB_Ms_Cmd_RequestSense(CBW);
		break;
	case USBMS_VERIFY:
		USB_Ms_Cmd_Verify(CBW->bCBWLUN, CBW);
		break;
	case USBMS_MODE_SENSE6:      /*Mode Sense*/
		USB_Ms_Cmd_ModeSense6(CBW->bCBWLUN, CBW);
		break;
	case USBMS_START_STOP_UNIT:
	case USBMS_MODE_SENSE:
	case USBMS_MODE_SELECT6:
	default:
		USB_Ms_Cmd_Unknown(CBW);
		break;
	}
}


/* handle CBW USBMS_FORMAT_UNIT command */
static void USB_Ms_Cmd_Format(kal_uint8 LUN, UsbMs_CBW *CBW)
{
	kal_bool msdc_status;
//	USB_Ms_Dbg_Trace(USB_DBG_USBMS_CMD_FORMAT, 0);

	USB_Ms_State_Checkmedia_Exist(LUN);
	if (g_UsbMS.CSWStatusError == KAL_FALSE)
	{
		msdc_status = USB_Ms_Format(LUN);
		if (msdc_status == KAL_FALSE)
			USB_Ms_State_Checkmedia_Exist(LUN);
	}
	g_UsbMS.nState = USBMS_GETNEXTCMD;
	USB_Ms_Generate_Csw(&g_UsbMS.CSW,CBW);
	USB_Ms_BuildTx(&g_UsbMS.CSW, 13);
}

/* check media status and generate correspongind status for CSW */
static void USB_Ms_State_Checkmedia_Exist(kal_uint8 LUN)
{
	kal_uint8   msdc_status;

//	USB_Ms_Dbg_Trace(USB_DBG_CHECKMEDIA_EXIST, 0);
	msdc_status = USB_Ms_Checkmedia_Exist(LUN);

	switch(msdc_status)
	{
	case USB_STORAGE_DEV_STATUS_OK:
	case USB_STORAGE_DEV_STATUS_WP:
		g_UsbMS.sensePtr = (kal_uint8 *)senseOk;
		g_UsbMS.CSWStatusError = KAL_FALSE;
		break;
	case USB_STORAGE_DEV_STATUS_MEDIA_CHANGE:
		g_UsbMS.sensePtr = (kal_uint8 *)senseMediaChanged;
		g_UsbMS.CSWStatusError = KAL_TRUE;
		break;
	case USB_STORAGE_DEV_STATUS_NOMEDIA:
		g_UsbMS.sensePtr = (kal_uint8 *)senseNoMedia;
		g_UsbMS.CSWStatusError = KAL_TRUE;
		break;
	default:
		ASSERT(0);
		g_UsbMS.sensePtr = (kal_uint8 *)senseNoMedia;
		g_UsbMS.CSWStatusError = KAL_TRUE;
		break;
	}
}

/* handle CBW USBMS_INQUIRY command */
static void USB_Ms_Cmd_Inquiry(UsbMs_CBW *CBW)

⌨️ 快捷键说明

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