📄 usbms_state.c
字号:
{
// 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 + -