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

📄 usb_host_ms_drv.c

📁 mtk 6225平台的usb程序! 对想了解mtk平台usb的朋友会有帮助!
💻 C
📖 第 1 页 / 共 4 页
字号:

}

/* MODE SENSE6 All mode command (1ah)*/
USB_HOST_MS_RESULT USB_Host_Ms_Mode_Sense6_All_Mode(kal_uint8 lun)
{
	kal_bool b_send_result;
	kal_uint32 event_group;
	USB_HOST_MS_MEDIA_STATE media_state = g_UsbHostMs.media_info[lun].state;

	kal_mem_set(g_usb_ms_cmd, 0, USBMS_MAX_CMD_LEN);
	g_usb_ms_cmd[0] = USBMS_MODE_SENSE6;
	g_usb_ms_cmd[2] = 0x3f;
	g_usb_ms_cmd[4] = USBMS_MODE_SENSE6_DATA_LEN;

	g_UsbHostMs.ms_cmd_data.lun = lun;
	g_UsbHostMs.ms_cmd_data.cmd_len = USBMS_MODE_SENSE6_CMD_LEN;
	g_UsbHostMs.ms_cmd_data.cmd_buff = g_usb_ms_cmd;
	g_UsbHostMs.ms_cmd_data.data_len = USBMS_MODE_SENSE6_DATA_LEN;
	g_UsbHostMs.ms_cmd_data.data_buff = g_usb_ms_data;
	g_UsbHostMs.ms_cmd_data.data_dir = USB_HOST_MS_DATA_RECV;
	
	b_send_result = USB_Host_Ms_Send_Cmd(&g_UsbHostMs.ms_cmd_data);

	if((b_send_result==KAL_TRUE)&&(g_UsbHostMs.dev_attatch == KAL_TRUE))
	{
		/* when event is retrived, result has been got in data buffer */
		kal_retrieve_eg_events(g_UsbHostMs.event_id, EVENT_USB_MS_DONE|EVENT_USB_MS_DETATCH, 
						KAL_OR_CONSUME, &event_group, KAL_SUSPEND);
	
		if(g_UsbHostMs.result == USB_HOST_MS_RESULT_OK)
		{
			/* determine it is write protect or not */
			if((g_usb_ms_data[2]&0x80)!=0)
				g_UsbHostMs.media_info[lun].state = USB_HOST_MS_MEDIA_STATE_WR_PROTECT;
			else
				g_UsbHostMs.media_info[lun].state = USB_HOST_MS_MEDIA_STATE_READY;
		}
		else if(g_UsbHostMs.result == USB_HOST_MS_RESULT_CSW_FAIL)
		{
			/* translate result to request sense result */
			/* application can treat it as result OK is request sense reault is OK */
			g_UsbHostMs.result = USB_Host_Ms_Request_Sense(lun);
		}
		/* else USB_HOST_MS_RESULT_TIMEOUT and USB_HOST_MS_RESULT_STALL do not handle it */

		if(media_state!=g_UsbHostMs.media_info[lun].state)
		{
			//g_UsbHostMs.b_state_change = KAL_TRUE;
			g_UsbHostMs.media_state_change |= (1<<lun);
		}
	}
	else
	{
		g_UsbHostMs.result = USB_HOST_MS_RESULT_TIMEOUT;
	}

	return g_UsbHostMs.result;

}

/* READ command (28h)*/
/* The received data will be stored in data parameter */
USB_HOST_MS_RESULT USB_Host_Ms_Read(kal_uint8 lun, kal_uint32 sec_start, kal_uint16 sec_num, kal_uint8* data)
{
	kal_bool b_send_result;
	kal_uint32 event_group;

	kal_mem_set(g_usb_ms_cmd, 0, USBMS_MAX_CMD_LEN);
	g_usb_ms_cmd[0] = USBMS_READ;
	g_usb_ms_cmd[2] = (sec_start>>24)&0xff;
	g_usb_ms_cmd[3] = (sec_start>>16)&0xff;
	g_usb_ms_cmd[4] = (sec_start>>8)&0xff;
	g_usb_ms_cmd[5] = sec_start&0xff;	

	g_usb_ms_cmd[7] = (sec_num>>8)&0xff;
	g_usb_ms_cmd[8] = sec_num&0xff;	

	g_UsbHostMs.ms_cmd_data.lun = lun;
	g_UsbHostMs.ms_cmd_data.cmd_len = USBMS_READ_CMD_LEN;
	g_UsbHostMs.ms_cmd_data.cmd_buff = g_usb_ms_cmd;
	g_UsbHostMs.ms_cmd_data.data_len = sec_num*g_UsbHostMs.media_info[lun].sec_size; 
	g_UsbHostMs.ms_cmd_data.data_buff = data;
	g_UsbHostMs.ms_cmd_data.data_dir = USB_HOST_MS_DATA_RECV;

	b_send_result = USB_Host_Ms_Send_Cmd(&g_UsbHostMs.ms_cmd_data);

	if((b_send_result==KAL_TRUE)&&(g_UsbHostMs.dev_attatch == KAL_TRUE))
	{
		/* when event is retrived, result has been got in data buffer */
		kal_retrieve_eg_events(g_UsbHostMs.event_id, EVENT_USB_MS_DONE|EVENT_USB_MS_DETATCH, 
						KAL_OR_CONSUME, &event_group, KAL_SUSPEND);

		g_UsbHostMs.b_rw_result = KAL_FALSE;
		if(g_UsbHostMs.result == USB_HOST_MS_RESULT_OK)
		{
			/* In the application layer, result may be OK because of next request sense result is OK */
			/* This is used to indicate whether the whole data are read back successfully */
			g_UsbHostMs.b_rw_result = KAL_TRUE;
		}
		else if(g_UsbHostMs.result == USB_HOST_MS_RESULT_CSW_FAIL)
		{
			/* translate result to request sense result */
			/* application can treat it as result OK is request sense reault is OK */
			g_UsbHostMs.result = USB_Host_Ms_Request_Sense(lun);
		}
		/* else USB_HOST_MS_RESULT_TIMEOUT and USB_HOST_MS_RESULT_STALL  do not handle it */
	}
	else
	{
		g_UsbHostMs.result = USB_HOST_MS_RESULT_TIMEOUT;
	}

	return g_UsbHostMs.result;
}

/* WRITE command (2ah)*/
/* The data parameter will be sent out */
USB_HOST_MS_RESULT USB_Host_Ms_Write(kal_uint8 lun, kal_uint32 sec_start, kal_uint16 sec_num, kal_uint8* data)
{
	kal_bool b_send_result;
	kal_uint32 event_group;

	kal_mem_set(g_usb_ms_cmd, 0, USBMS_MAX_CMD_LEN);
	g_usb_ms_cmd[0] = USBMS_WRITE;
	g_usb_ms_cmd[2] = (sec_start>>24)&0xff;
	g_usb_ms_cmd[3] = (sec_start>>16)&0xff;
	g_usb_ms_cmd[4] = (sec_start>>8)&0xff;
	g_usb_ms_cmd[5] = sec_start&0xff;	

	g_usb_ms_cmd[7] = (sec_num>>8)&0xff;
	g_usb_ms_cmd[8] = sec_num&0xff;	

	g_UsbHostMs.ms_cmd_data.lun = lun;
	g_UsbHostMs.ms_cmd_data.cmd_len = USBMS_WRITE_CMD_LEN;
	g_UsbHostMs.ms_cmd_data.cmd_buff = g_usb_ms_cmd;
	g_UsbHostMs.ms_cmd_data.data_len = sec_num*g_UsbHostMs.media_info[lun].sec_size; 
	g_UsbHostMs.ms_cmd_data.data_buff = data;
	g_UsbHostMs.ms_cmd_data.data_dir = USB_HOST_MS_DATA_SEND;

	b_send_result = USB_Host_Ms_Send_Cmd(&g_UsbHostMs.ms_cmd_data);

	if((b_send_result==KAL_TRUE)&&(g_UsbHostMs.dev_attatch == KAL_TRUE))
	{
		/* when event is retrived, result has been got in data buffer */
		kal_retrieve_eg_events(g_UsbHostMs.event_id, EVENT_USB_MS_DONE|EVENT_USB_MS_DETATCH, 
						KAL_OR_CONSUME, &event_group, KAL_SUSPEND);

		g_UsbHostMs.b_rw_result = KAL_FALSE;
		if(g_UsbHostMs.result == USB_HOST_MS_RESULT_OK)
		{
			/* In the application layer, result may be OK because of next request sense result is OK */
			/* This is used to indicate whether the whole data are written out  successfully */
			g_UsbHostMs.b_rw_result = KAL_TRUE;
		}
		else if(g_UsbHostMs.result == USB_HOST_MS_RESULT_CSW_FAIL)
		{
			/* translate result to request sense result */
			/* application can treat it as result OK is request sense reault is OK */
			g_UsbHostMs.result = USB_Host_Ms_Request_Sense(lun);
		}
		/* else USB_HOST_MS_RESULT_TIMEOUT and USB_HOST_MS_RESULT_STALL  do not handle it */
	}
	else
	{
		g_UsbHostMs.result = USB_HOST_MS_RESULT_TIMEOUT;
	}
	
	return g_UsbHostMs.result;
}

/* Construct the CBW format, and send command to scheduling queue*/ 
static kal_bool USB_Host_Ms_Send_Cmd(USBH_Ms_Cmd_Struct *ms_cmd)
{ 
	UsbMs_CBW *CBW = (UsbMs_CBW*)g_UsbHostMs.CBWdata;

	/* construct CBW according to to the aommand request */
	CBW->dCBWSignature = 0x43425355;
	CBW->dCBWTag = g_UsbHostMs.CBWdata[1] +1;  /* increment tag in each command */
	CBW->dCBWDataTransferLength = ms_cmd->data_len;
	if(ms_cmd->data_dir==USB_HOST_MS_DATA_RECV)
		CBW->bmCBWFlags = USBMS_DIR_IN;
	else
		CBW->bmCBWFlags = USBMS_DIR_OUT;
	CBW->bCBWLUN = ms_cmd->lun;
	CBW->bCBWCBLength = ms_cmd->cmd_len;
	/* the CBWCB comes from each command. ex READ, WRITE, TEST UNIT READY.*/
	/* the format is different according to each command */
	kal_mem_set(CBW->CBWCB, 0, USBMS_CBW_LENGTH);
	kal_mem_cpy(CBW->CBWCB, ms_cmd->cmd_buff, ms_cmd->cmd_len);

	/* assign the data buffer */
	/* In OUT direction, the data will be sent during transfer */
	/* In IN direction, the received data will be stored in this buffer */
	g_UsbHostMs.data = ms_cmd->data_buff;
	g_UsbHostMs.data_length = ms_cmd->data_len;
	g_UsbHostMs.data_dir = ms_cmd->data_dir;
	/* Note that in the recv direction, receive buffer must be pad to multiple of 4 */
	if((g_UsbHostMs.data_dir==USB_HOST_MS_DATA_RECV)&&(g_UsbHostMs.data_length&0x3))
	{
		g_UsbHostMs.data_length = g_UsbHostMs.data_length
							+ (4-(USBMS_REQUESTSENSE_DATA_LEN & 0x3));;
	}

	g_UsbHostMs.ms_state = USB_HOST_MS_CBW;

	/* Queue command to scheduling buffer*/
	/* Note that CBW, DATA, CSW transfer is handled in HISR level,
	    And when the transfer complete, it will retrive the event to wake up waiting task */
	return USB_HCD_Send_Req(g_UsbHostMs.ep_out_index, USBMS_CBW_LENGTH, CBW);
} 



/************************************************************
	ms class handler. Note that it is executed in OTG HIST context
*************************************************************/

/* This is callback function for both control EP and bulk EP */
/* The control EP part handles class specific EP0 command
     The bulk EP part handles CBW, DATA, CSW state machine */
static void USB_Host_Ms_Hdlr(USB_HCD_STATUS result, kal_uint32 param)
{
	if(g_UsbHostMs.ms_cmd != USB_HOST_MS_EP0_CMD_NONE)
	{
		USB_Host_Ms_Ctrl_EP_Hdlr(result, param);

	}

	else 

	{

		USB_Host_Ms_Bulk_EP_Hdlr(result, param);

	}	
}

/* handler for control endpoint */
/* It handles both standard and class specific EP0 command*/
static void USB_Host_Ms_Ctrl_EP_Hdlr(USB_HCD_STATUS result, kal_uint32 param)
{
	/* store the command because it will be chaneg immediatly*/
	USB_HOST_MS_EP0_CMD ms_cmd = g_UsbHostMs.ms_cmd;
	kal_bool tr_result;

	/* Unless another EP0 command is issued, the command should be set to NONE*/
	g_UsbHostMs.ms_cmd = USB_HOST_MS_EP0_CMD_NONE;

	if(result!=USB_HCD_OK)
	{
		/* translate the result */
		/* for EP0 error, the handler dose not do error handling,
		    the error handling is done in the upper layer state */
		if(result == USB_HCD_STALL)
			g_UsbHostMs.result = USB_HOST_MS_RESULT_STALL;
		else
			g_UsbHostMs.result = USB_HOST_MS_RESULT_TIMEOUT;
		kal_set_eg_events(g_UsbHostMs.event_id, EVENT_USB_MS_DONE, KAL_OR);		
	}		
	else
	{
		/* result is OK */
		switch(ms_cmd)
		{
		case USB_HOST_MS_EP0_CMD_RESET:

			g_UsbHostMs.result = USB_HOST_MS_RESULT_OK;

			kal_set_eg_events(g_UsbHostMs.event_id, EVENT_USB_MS_DONE, KAL_OR);		

			break;
		case USB_HOST_MS_EP0_CMD_GET_LUN:
			g_UsbHostMs.result = USB_HOST_MS_RESULT_OK;
			kal_set_eg_events(g_UsbHostMs.event_id, EVENT_USB_MS_DONE, KAL_OR);		
			break;
		case USB_HOST_MS_EP0_CMD_CLEAR_STALL_IN:
		case USB_HOST_MS_EP0_CMD_CLEAR_STALL_OUT:
			/* Clear IN or clear OUT stall are completed,
			    The next action is determined according to the previous state before STALL*/
			if(g_UsbHostMs.ms_state==USB_HOST_MS_CBW_CLEAR_STALL)

			{
				/* The CBW is stalled. Do not issue DATA or CSW any more.
				    Return STALL result and let upper layer state machine handle it */

				g_UsbHostMs.result = USB_HOST_MS_RESULT_STALL;

				kal_set_eg_events(g_UsbHostMs.event_id, EVENT_USB_MS_DONE, KAL_OR);		

			}	

			else if(g_UsbHostMs.ms_state==USB_HOST_MS_DATA_CLEAR_STALL)

			{
				/* DATA is stalled. Clear STALL and attepmt to receive CSW */

				/* Send CSW */

				tr_result = USB_HCD_Recv_Req(g_UsbHostMs.ep_in_index, sizeof(g_UsbHostMs.CSW)/sizeof(kal_uint8), &g_UsbHostMs.CSW);

				if(tr_result==KAL_TRUE)
				{
					g_UsbHostMs.ms_state = USB_HOST_MS_CSW;
				}
				else
				{
					g_UsbHostMs.result = USB_HOST_MS_RESULT_TIMEOUT;
					kal_set_eg_events(g_UsbHostMs.event_id, EVENT_USB_MS_DONE, KAL_OR);
				}

			}

			else if(g_UsbHostMs.ms_state==USB_HOST_MS_CSW_CLEAR_STALL)

			{
				/* CSW is stalled. Clear STALL and attepmt to receive CSW */

				/* send CSW */

				tr_result = USB_HCD_Recv_Req(g_UsbHostMs.ep_in_index, sizeof(g_UsbHostMs.CSW)/sizeof(kal_uint8), &g_UsbHostMs.CSW);

				if(tr_result==KAL_FALSE)
				{
					g_UsbHostMs.result = USB_HOST_MS_RESULT_TIMEOUT;
					kal_set_eg_events(g_UsbHostMs.event_id, EVENT_USB_MS_DONE, KAL_OR);
				}

			}

			else

			{
				/* In all other states, it should not come to EP0 handler */

				EXT_ASSERT(0, ms_cmd, g_UsbHostMs.ms_state, 0);

			}

			break;

		}	

	}	
}


/* handler for ctrl endpoint */
/* It handles CBW, DATA, CSW state machine */
static void USB_Host_Ms_Bulk_EP_Hdlr(USB_HCD_STATUS result, kal_uint32 param)
{
	if(g_UsbHostMs.ms_state == USB_HOST_MS_CBW)
	{
		USB_Host_Ms_CBW_Hdler(result, param);
	}
	else if(g_UsbHostMs.ms_state == USB_HOST_MS_DATA)
	{
		USB_Host_Ms_DATA_Hdler(result, param);
	}
	else if((g_UsbHostMs.ms_state == USB_HOST_MS_CSW) || (g_UsbHostMs.ms_state == USB_HOST_MS_CSW_CLEAR_STALL))
	{
		USB_Host_Ms_CSW_Hdler(result, param);
	}
	else
	{
		/* Note that in USB_HOST_MS_CBW_CLEAR_STALL and USB_HOST_MS_DATA_CLEAR_STALL state,
		    only ctrl EP handler should be called, but not enter this bulk EP handler*/
		EXT_ASSERT(0, g_UsbHostMs.ms_state, 0, 0);
	}
}


/* Ctrl EP CBW handler, handle the state mcahine */
static void USB_Host_Ms_CBW_Hdler(USB_HCD_STATUS result, kal_uint32 param)
{
	kal_bool tr_result;
		
	if(result==USB_HCD_OK)

	{

		/* chek the real sent out length */	
		if(param!=USBMS_CBW_LENGTH)

			EXT_ASSERT(0, param, 0, 0);

		

		if(g_UsbHostMs.data_length !=0)

		{
			/* DATA state should be the following state */

			/* Since data length is not zero, data direction must not NONE */

			if(g_UsbHostMs.data_dir == USB_HOST_MS_DATA_NONE)

				EXT_ASSERT(0, g_UsbHostMs.data_dir, g_UsbHostMs.data_length, 0);

				

			if(g_UsbHostMs.data_dir ==USB_HOST_MS_DATA_RECV)

			{
				/* Receive data */

				if(g_UsbHostMs.data_length > USBMS_MAX_DATA_LENGTH)

				{	
					/* DMA length has limit, so each transfer request should should have size limit */

					tr_result = USB_HCD_Recv_Req(g_UsbHostMs.ep_in_index, USBMS_MAX_DATA_LENGTH, g_UsbHostMs.data);

					if(tr_result==KAL_TRUE)
					{
						g_UsbHostMs.sending_data_length = USBMS_MAX_DATA_LENGTH;
						g_UsbHostMs.remain_data_length = g_UsbHostMs.data_length - USBMS_MAX_DATA_LENGTH;
						g_UsbHostMs.sent_data_length = 0;
					}
					else
					{
						g_UsbHostMs.result = USB_HOST_MS_RESULT_TIMEOUT;
						kal_set_eg_events(g_UsbHostMs.event_id, EVENT_USB_MS_DONE, KAL_OR);
					}	
				}

⌨️ 快捷键说明

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