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

📄 usbms_state.c

📁 MTK平台绝密核心代码之 USB驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
{
//	USB_Ms_Dbg_Trace(USB_DBG_USBMS_CMD_INQUIRY, 0);
	USB_Ms_BuildTx((kal_uint8 *)g_UsbMS.ms_param->inquire_data, g_UsbMS.ms_param->inquire_size);
	g_UsbMS.sensePtr = (kal_uint8 *)senseOk;
	g_UsbMS.CSWStatusError = KAL_FALSE;
	g_UsbMS.nState = USBMS_ACK;
}

/* handle CBW USBMS_TEST_UNIT_READY command */
static void USB_Ms_Cmd_Test_Unit_Ready(kal_uint8 LUN, UsbMs_CBW *CBW)
{
	USB_Ms_Dbg_Trace(USB_DBG_CMD_TESTUNITREADY, LUN);
	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);
}

/* handle CBW USBMS_PREVALLOW_MEDIA_REMOVL command */
static void USB_Ms_Cmd_Prev_Media_Removal(kal_uint8 LUN, UsbMs_CBW *CBW)
{
	kal_bool msdc_status;
//	USB_Ms_Dbg_Trace(USB_DBG_USBMS_CMD_PREV_MEDIA_REMOVAL, 0);
	USB_Ms_State_Checkmedia_Exist(LUN);
	if (g_UsbMS.CSWStatusError == KAL_FALSE)
	{
		msdc_status = USB_Ms_Prevmedia_Removal(LUN, KAL_TRUE);
		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);
}

/* handle CBW USBMS_READ_CAPACITY command */
static void USB_Ms_Cmd_Read_Capacity(kal_uint8 LUN, UsbMs_CBW *CBW)
{
	kal_uint32 LBA;
	kal_uint32 len;
	kal_bool msdc_status;
	Read_Capacity_Info Capacity_Info;

	USB_Ms_Dbg_Trace(USB_DBG_USBMS_CMD_READ_CAPACITY, LUN);

	USB_Ms_State_Checkmedia_Exist(LUN);
	if (g_UsbMS.CSWStatusError == KAL_FALSE)
	{
		msdc_status = USB_Ms_Read_Capacity(LUN, &LBA, &len);
		if (msdc_status)
		{
			USB_Ms_MemInverse(&LBA, &Capacity_Info.LastBA, 4);
			USB_Ms_MemInverse(&len, &Capacity_Info.BlkLen, 4);
			USB_Ms_BuildTx(&Capacity_Info, 8);
			g_UsbMS.nState = USBMS_ACK;
			return;
		}
		else
		{
			USB_Ms_State_Checkmedia_Exist(LUN);
		}
	}

	/*Fail case*/
	LBA = 0x400000;
	len = 0x200;
	USB_Ms_MemInverse(&LBA,&Capacity_Info.LastBA, 4);
	USB_Ms_MemInverse(&len,&Capacity_Info.BlkLen, 4);
	USB_Ms_BuildTx(&Capacity_Info, 8);
	g_UsbMS.nState = USBMS_ACK;
}

/* handle CBW USBMS_READ_FORMATCAPACITY command */
static void USB_Ms_Cmd_Read_FormatCapacity(kal_uint8 LUN, UsbMs_CBW *CBW)
{
	kal_uint32 msdc_blk_no;
	kal_uint32 msdc_blk_len;
	kal_uint32 len;
//	kal_uint32 length;
//	kal_bool msdc_status;
//	kal_uint8 ReadformatCapacity_Data[20];
	kal_uint8 ReadformatCapacity_Data[12];
	kal_uint8 *CBWCB = CBW->CBWCB;

	USB_Ms_Dbg_Trace(USB_DBG_USBMS_CMD_READ_FORMATCAPACITY, LUN);

	len = (kal_uint16)CBWCB[7];
	len <<= 8;
	len |= (kal_uint16)CBWCB[8];

//	USB_Ms_State_Checkmedia_Exist(LUN);

//	if (g_UsbMS.CSWStatusError == KAL_FALSE)
//	{
//		msdc_status = USB_Ms_Read_FormatCapacity(LUN, &msdc_blk_no,&msdc_blk_len);
//		if (msdc_status == KAL_TRUE)
//		{
//			kal_mem_set(ReadformatCapacity_Data, 0x00, 20);
//			ReadformatCapacity_Data[3] = 0x10;
//			USB_Ms_MemInverse(&msdc_blk_no, &ReadformatCapacity_Data[4], 4);
//			USB_Ms_MemInverse(&msdc_blk_len, &ReadformatCapacity_Data[9], 3);
//			USB_Ms_MemInverse(&msdc_blk_no, &ReadformatCapacity_Data[12], 4);
//			USB_Ms_MemInverse(&msdc_blk_len, &ReadformatCapacity_Data[17], 3);
//			ReadformatCapacity_Data[8] = 0x02;
//			if (len >= 20)
//				USB_Ms_BuildTx(ReadformatCapacity_Data,20);
//			else
//				USB_Ms_BuildTx(ReadformatCapacity_Data,len);
//			g_UsbMS.nState = USBMS_ACK;
//			return;
//		}
//		else
//		{
//			USB_Ms_State_Checkmedia_Exist(LUN);
//		}
//	}

	kal_mem_set(ReadformatCapacity_Data, 0x00, 12);
	ReadformatCapacity_Data[3] = 0x08;
	msdc_blk_no = 0x400000;
	msdc_blk_len = 0x03000200;
	g_UsbMS.CSWStatusError = KAL_FALSE;
	USB_Ms_MemInverse(&msdc_blk_no, &ReadformatCapacity_Data[4], 4);
	USB_Ms_MemInverse(&msdc_blk_len, &ReadformatCapacity_Data[8], 4);

//			USB_Ms_MemInverse(&msdc_blk_no, &ReadformatCapacity_Data[12], 4);
//			USB_Ms_MemInverse(&msdc_blk_len, &ReadformatCapacity_Data[17], 3);
//	ReadformatCapacity_Data[8] = 0x02;
			
//	length = 8; //12-4 = 8
//	msdc_blk_no = 0x400000;
//	msdc_blk_len = 0x03000200;
//	g_UsbMS.CSWStatusError = 0;
//	USB_Ms_MemInverse(&length, &ReadformatCapacity_Data[0], 4);
//	USB_Ms_MemInverse(&msdc_blk_no, &ReadformatCapacity_Data[4], 4);
//	USB_Ms_MemInverse(&msdc_blk_len, &ReadformatCapacity_Data[8], 4);
	g_UsbMS.nState = USBMS_ACK;

	if (len >= 12)
		USB_Ms_BuildTx(ReadformatCapacity_Data, 12);
	else
		USB_Ms_BuildTx(ReadformatCapacity_Data, len);
}

/* handle CBW USBMS_REQUESTSENSE command */
static void USB_Ms_Cmd_RequestSense(UsbMs_CBW *CBW)
{
	kal_uint8 len;
	kal_uint8 *CBWCB = CBW->CBWCB;

	len = (kal_uint16)CBWCB[4];
//	USB_Ms_Dbg_Trace(USB_DBG_USBMS_CMD_REQUESTSENSE, 0);
	if (len > 18)
		USB_Ms_BuildTx(g_UsbMS.sensePtr, 18);
	else
		USB_Ms_BuildTx(g_UsbMS.sensePtr, len);

	g_UsbMS.nState = USBMS_ACK;
}

/* handle CBW USBMS_VERIFY command */
static void USB_Ms_Cmd_Verify(kal_uint8 LUN, UsbMs_CBW *CBW)
{
//	USB_Ms_Dbg_Trace(USB_DBG_USBMS_CMD_VERIFY, 0);

	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);
}

/* handle CBW USBMS_MODE_SENSE6 command */
static void USB_Ms_Cmd_ModeSense6(kal_uint8 LUN, UsbMs_CBW *CBW)
{
	kal_uint8 result;
	kal_uint8 ModeSense6_Data[4];

//	USB_Ms_Dbg_Trace(USB_DBG_USBMS_CMD_MODESENSE6, 0);
	USB_Ms_State_Checkmedia_Exist(LUN);
	result = USB_Ms_Checkmedia_Exist(LUN);

	if (result == USB_STORAGE_DEV_STATUS_WP)     
	{
		/* Write Protect */
		ModeSense6_Data[0] = 0x03;
		ModeSense6_Data[1] = 0x00;
		ModeSense6_Data[2] = 0x80;
		ModeSense6_Data[3] = 0x00;
	}
	else
	{
		ModeSense6_Data[0] = 0x03;
		ModeSense6_Data[1] = 0x00;
		ModeSense6_Data[2] = 0x00;
		ModeSense6_Data[3] = 0x00;
	}

	USB_Ms_BuildTx(ModeSense6_Data,4);
	g_UsbMS.nState = USBMS_ACK;
}

/* handle CBW unknown command */
static void USB_Ms_Cmd_Unknown(UsbMs_CBW *CBW)
{
//	USB_Ms_Dbg_Trace(USB_DBG_USBMS_UNKNOW_CMD, 0);
	g_UsbMS.sensePtr = (kal_uint8 *)senseInvalidFieldInCDB;
	g_UsbMS.CSWStatusError = KAL_TRUE;
	g_UsbMS.nState = USBMS_GETNEXTCMD;
	USB_Ms_Generate_Csw(&g_UsbMS.CSW,CBW);
	USB_Ms_BuildTx(&g_UsbMS.CSW,13);
}

/* handle CBW USBMS_READ command */
static void USB_Ms_Cmd_Read(kal_uint8 LUN, UsbMs_CBW *CBW)
{
	kal_uint8 *CBWCB = CBW->CBWCB;

	USB_Ms_State_Checkmedia_Exist(LUN);

	USB_Ms_MemInverse(&CBWCB[2], &g_UsbMS.rw_cmd.LBA, 4);
	USB_Ms_MemInverse(&CBWCB[7], &g_UsbMS.rw_cmd.BlkLen, 2);

	if (g_UsbMS.CSWStatusError == KAL_FALSE)
	{
		//USB_Ms_Dbg_Trace(USB_DBG_USBMS_CMD_READ, g_UsbMS.rw_cmd.BlkLen);
		g_UsbMS.rw_cmd.rwindex = 0;
		g_UsbMS.rw_cmd.msdc_rwindex = 0;
		g_UsbMS.rw_cmd.rw_buffer_index = 0;
		g_UsbMS.rw_cmd.rw_error_status = KAL_FALSE;

		USB_Ms_Handle_Read(LUN, CBW);
	}
	else
	{
		USB_Ms_Read_Fail_Handler(LUN, CBW);
	}
}


static void USB_Ms_Handle_Read(kal_uint8 LUN, UsbMs_CBW *CBW)
{
	static kal_bool 	read_status;
	static kal_uint32	readlen = 0;

#if 0
/* under construction !*/
/* under construction !*/
/* under construction !*/
#endif	

	if(g_UsbMS.rw_cmd.rwindex == 0)		/* the first time to read */
	{
		if ((g_UsbMS.rw_cmd.BlkLen - g_UsbMS.rw_cmd.rwindex) <= USBMS_TX_MAX_SECTOR)
			readlen = g_UsbMS.rw_cmd.BlkLen - g_UsbMS.rw_cmd.rwindex;
		else
			readlen = USBMS_TX_MAX_SECTOR;
#if 0	
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#endif		

#ifdef __P_PROPRIETARY_COPYRIGHT__
		if(USB_Ms_Check_Second_Read_Protect(LUN, 
			(g_UsbMS.rw_cmd.LBA + g_UsbMS.rw_cmd.msdc_rwindex), readlen) == KAL_TRUE)
		{
			g_UsbMS.b_read_protect = KAL_TRUE;
			USB_Ms_Read_Fail_Handler(LUN, CBW);
			return;
		}
		else
		{
			if(USB_Ms_Check_Read_Protect(LUN, 
				(g_UsbMS.rw_cmd.LBA + g_UsbMS.rw_cmd.msdc_rwindex), readlen) == KAL_TRUE)
			{
				/* fill data as 0 */
				kal_mem_set((kal_uint8*)g_UsbMS.disk_buffer->ms_buffer[g_UsbMS.rw_cmd.rw_buffer_index], 0, readlen*512);
				read_status = KAL_TRUE;
			}
			else
			{
				read_status = USB_Ms_Read(LUN, g_UsbMS.disk_buffer->ms_buffer[g_UsbMS.rw_cmd.rw_buffer_index], 
						(g_UsbMS.rw_cmd.LBA + g_UsbMS.rw_cmd.msdc_rwindex), readlen);
			}
			g_UsbMS.b_read_protect = KAL_FALSE;
		}
#else
		read_status = USB_Ms_Read(LUN, g_UsbMS.disk_buffer->ms_buffer[g_UsbMS.rw_cmd.rw_buffer_index], 
					(g_UsbMS.rw_cmd.LBA + g_UsbMS.rw_cmd.msdc_rwindex), readlen);

#endif

#if 0
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#endif
	}/*(g_UsbMS.rw_cmd.rwindex == 0)*/

	if (read_status == KAL_TRUE)
	{
		g_UsbMS.rw_cmd.msdc_rwindex += readlen;
		USB_Ms_BuildTx((void *)g_UsbMS.disk_buffer->ms_buffer[g_UsbMS.rw_cmd.rw_buffer_index], (512 * readlen));
		g_UsbMS.rw_cmd.rwindex += readlen;

		if (g_UsbMS.rw_cmd.rwindex == g_UsbMS.rw_cmd.BlkLen)
		{
			g_UsbMS.nState = USBMS_ACK;
			return;
		}
	}
	else
	{
		USB_Ms_Read_Fail_Handler(LUN, CBW);
		return;
	}

	if ((g_UsbMS.rw_cmd.BlkLen - g_UsbMS.rw_cmd.rwindex) <= USBMS_TX_MAX_SECTOR)
		readlen = g_UsbMS.rw_cmd.BlkLen - g_UsbMS.rw_cmd.rwindex;
	else
		readlen = USBMS_TX_MAX_SECTOR;

	g_UsbMS.rw_cmd.rw_buffer_index ^= 1;

#ifdef __P_PROPRIETARY_COPYRIGHT__
	if(USB_Ms_Check_Second_Read_Protect(LUN, 
		(g_UsbMS.rw_cmd.LBA + g_UsbMS.rw_cmd.msdc_rwindex), readlen) == KAL_TRUE)
	{
		g_UsbMS.b_read_protect = KAL_TRUE;
		USB_Ms_Read_Fail_Handler(LUN, CBW);
		return;
	}
	else
	{
		if(USB_Ms_Check_Read_Protect(LUN, 
			(g_UsbMS.rw_cmd.LBA + g_UsbMS.rw_cmd.msdc_rwindex), readlen) == KAL_TRUE)
		{
			/* fill data as 0 */
			kal_mem_set((kal_uint8*)g_UsbMS.disk_buffer->ms_buffer[g_UsbMS.rw_cmd.rw_buffer_index], 0, readlen*512);
			read_status = KAL_TRUE;
		}
		else
		{
			read_status = USB_Ms_Read(LUN, g_UsbMS.disk_buffer->ms_buffer[g_UsbMS.rw_cmd.rw_buffer_index], 
					(g_UsbMS.rw_cmd.LBA + g_UsbMS.rw_cmd.msdc_rwindex), readlen);
		}
		g_UsbMS.b_read_protect = KAL_FALSE;
	}
#else
	read_status = USB_Ms_Read(LUN, g_UsbMS.disk_buffer->ms_buffer[g_UsbMS.rw_cmd.rw_buffer_index], 
				(g_UsbMS.rw_cmd.LBA + g_UsbMS.rw_cmd.msdc_rwindex), readlen);
#endif
}

/* handle read error condition */
static void USB_Ms_Read_Fail_Handler(kal_uint8 LUN, UsbMs_CBW *CBW)
{
	kal_bool bEPEmpty;
	kal_uint8 count = 0;
		
	/* make sure previous packets are already sent out
	   maybe last DMA data has triggered DMA done but data are still in FIFO*/
	bEPEmpty = USB_Is_EP_Bulk_In_Empty(g_UsbMS.txpipe->byEP);
	/* If cable plug out at this time, add timeout to avoid looping here */
	while((bEPEmpty == KAL_FALSE)&&(count<100))
	{
		count++;	
		kal_sleep_task(1);	
		bEPEmpty = USB_Is_EP_Bulk_In_Empty(g_UsbMS.txpipe->byEP);
	}
	
	/* send out a NULL packet */
	USB_EPFIFOWrite (g_UsbMS.txpipe->byEP, 0, NULL);
	USB_EP_Bulk_In_Ready(g_UsbMS.txpipe->byEP);
	
	/* make sure previous NULL pkt has been sent out
	   avoid next DMA data in FIFO sent out instead of previos NULL pkt.*/
	/* To avoid "IN token received after next DMA(below part) has moved data into FIFO"
	If this happens, MTK device will send CSW of 13 bytes out to PC, 
	and it will cause PC to wait for next data(about 10 seconds) and reset USB after that.
	Disk will show on PC until this condition disappear*/
	bEPEmpty = USB_Is_EP_Bulk_In_Empty(g_UsbMS.txpipe->byEP);
	/* If cable plug out at this time, add timeout to avoid looping here */
	count = 0;
	while((bEPEmpty == KAL_FALSE)&&(count<100))
	{
		count++;	
		kal_sleep_task(1);	
		bEPEmpty = USB_Is_EP_Bulk_In_Empty(g_UsbMS.txpipe->byEP);
	}
	
#ifdef __P_PROPRIETARY_COPYRIGHT__
	if(g_UsbMS.b_read_protect==KAL_TRUE)
	{
		g_UsbMS.b_read_protect = KAL_FALSE;
		g_UsbMS.sensePtr = (kal_uint8 *)senseDataProtect;
		g_UsbMS.CSWStatusError = KAL_TRUE;
	}
	else
	{
		USB_Ms_State_Checkmedia_Exist(LUN);
	}	
#else
	USB_Ms_State_Checkmedia_Exist(LUN);
#endif	
	
	g_UsbMS.CSWDataResidue = (g_UsbMS.rw_cmd.BlkLen-g_UsbMS.rw_cmd.msdc_rwindex)*512;
	g_UsbMS.CSWStatusError = KAL_TRUE;
	USB_Ms_Dbg_Trace(USB_DBG_USBMS_CMD_Read_ERROR, g_UsbMS.CSWDataResidue);
	g_UsbMS.nState = USBMS_GETNEXTCMD;
	USB_Ms_Generate_Csw(&g_UsbMS.CSW, CBW);
	USB_Ms_BuildTx(&g_UsbMS.CSW, 13);
}

/* handle CBW USBMS_WRITE command */
static void USB_Ms_Cmd_Write(kal_uint8 LUN, UsbMs_CBW *CBW)
{
	kal_uint8   *CBWCB = CBW->CBWCB;
	kal_uint8   msdc_status;

	msdc_status = USB_Ms_Checkmedia_Exist(LUN);

	USB_Ms_MemInverse(&CBWCB[2], &g_UsbMS.rw_cmd.LBA, 4);
	USB_Ms_MemInverse(&CBWCB[7], &g_UsbMS.rw_cmd.BlkLen, 2);
	g_UsbMS.rw_cmd.rwindex = 0;
	g_UsbMS.rw_cmd.msdc_rwindex = 0;
	g_UsbMS.rw_cmd.rw_buffer_index = 0;

	if (msdc_status == USB_STORAGE_DEV_STATUS_OK)
		g_UsbMS.rw_cmd.rw_error_status = KAL_FALSE;
	else
		g_UsbMS.rw_cmd.rw_error_status = KAL_TRUE;

//	USB_Ms_Dbg_Trace(USB_DBG_USBMS_CMD_WRITE, g_UsbMS.rw_cmd.BlkLen);

	USB_Ms_Handle_Write(LUN, CBW, 0);
}

			
static void USB_Ms_Handle_Write(kal_uint8 LUN, UsbMs_CBW *CBW, kal_uint8 sector_num)
{
	kal_uint32 writelen;
	kal_bool write_status;
	kal_bool write_data = KAL_FALSE;

#if 0
/* under construction !*/
/* under construction !*/
/* under construction !*/
#endif

	/* determine if it has data to write, if yes and msdc ok then write it*/
	if((g_UsbMS.rw_cmd.rwindex != 0) && (g_UsbMS.rw_cmd.rw_error_status == KAL_FALSE))
	{
		write_data = KAL_TRUE;
	}

	/* last data*/
	if (g_UsbMS.rw_cmd.rwindex == g_UsbMS.rw_cmd.BlkLen)
	{
		/* write the last one data*/
		g_UsbMS.rw_cmd.rw_buffer_index ^= 1; 
		if(write_data == KAL_TRUE)
		{
#if 0		
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/

⌨️ 快捷键说明

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