1232 lines
30 KiB
C
Executable File
1232 lines
30 KiB
C
Executable File
|
|
//#include "board.h"
|
|
#include "fuart.h"
|
|
#include "usb_update.h"
|
|
#include "debug.h"
|
|
#include "timer.h"
|
|
|
|
#define IOADDR_USB_REG_BASE (0xFF600000)
|
|
#define _THUMB2 __attribute__((target("thumb2")))
|
|
|
|
|
|
_THUMB2 void fLib_USB_Update_FW(void);
|
|
|
|
int usbrom_exit = 0;
|
|
volatile DEV *ptusbdev;
|
|
#define ptotg ((volatile OTG200 *)IOADDR_USB_REG_BASE)
|
|
|
|
#define FUSB200_MAX_EP 8 // 1..10
|
|
#define FUSB200_MAX_FIFO 4 // 0.. 9
|
|
|
|
#define mUsbEPMap(EPn, MAP) (ptusbdev->ep_map[EPn-1] = MAP)
|
|
#define mUsbEPMapRd(EPn) (ptusbdev->ep_map[EPn-1])
|
|
|
|
#define mUsbFIFOMap(FIFOn, MAP) (ptusbdev->fifo_map[FIFOn] = MAP)
|
|
#define mUsbFIFOMapRd(FIFOn) (ptusbdev->fifo_map[FIFOn])
|
|
#define mUsbFIFOConfigRd(FIFOn) (ptusbdev->fifo_cfg[FIFOn])
|
|
|
|
static USB_st tusb;
|
|
static MassStorageState eUsbMassStorageState = MS_STATE_CBW;
|
|
CBW tCBW;
|
|
CSW tCSW;
|
|
SCSISense tSCSIsense;
|
|
SCSIDeviceResp tSCSIDeviceResp;
|
|
|
|
MSDC_Verify_CB guiU2MsdcCheck_cb;
|
|
MSDC_VenDone_CB guiU2MsdcVendorDone_cb;
|
|
|
|
int trigger_done_cb = 0;
|
|
|
|
static const unsigned char u8RequestSenseData[DATA_LENGTH_REQUEST_SENSE] __attribute__((aligned(4))) =
|
|
{
|
|
0x70, // 0, response code
|
|
0x00, // 1, obsolete
|
|
0x00, // 2, sense key
|
|
0x00, // 3-6, information
|
|
|
|
0x00,
|
|
0x00,
|
|
0x00,
|
|
0x0A, // 7, additional length (n - 7), n = 17
|
|
|
|
0x00, // 8-11, information
|
|
0x00,
|
|
0x00,
|
|
0x00,
|
|
|
|
0x00, // 12, additional sense code
|
|
0x00, // 13, additional sense code qualifier
|
|
0x00, // 14, field replaceable unit code
|
|
0x00, // 15-17, sense-key specific
|
|
|
|
0x00,
|
|
0x00
|
|
};
|
|
|
|
|
|
static const unsigned char u8ModeSenseData[DATA_LENGTH_MODE_SENSE] __attribute__((aligned(4))) =
|
|
{
|
|
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
};
|
|
|
|
|
|
#define USB_BUFF_SZ 128
|
|
unsigned int u32Usb_buffer[USB_BUFF_SZ/4]; // may less than USB_BUFF_SZ
|
|
|
|
static INT32U nvtdev_opened = 1;
|
|
#define mCxType(cmd) ((cmd[0] & (BIT6 | BIT5)) >> 5)
|
|
#define mCxRequest(cmd) ((unsigned char)(cmd[0] >> 8))
|
|
#define mCxValue(cmd) ((unsigned short)(cmd[0] >> 16)) // get 3rd byte, 4th byte
|
|
#define mCxIndex(cmd) ((unsigned short)(cmd[1])) // get 5th byte, 6th byte
|
|
#define mCxLength(cmd) ((unsigned short)(cmd[1] >> 16)) // get 7th byte, 8th byte
|
|
|
|
|
|
#define mUsbRmWkupST() (ptusbdev->main_ctl & BIT0)
|
|
#define mUsbRmWkupClr() (ptusbdev->main_ctl &= ~BIT0)
|
|
#define mUsbRmWkupSet() (ptusbdev->main_ctl |= BIT0)
|
|
#define mUsbTsMdWr(item) (ptusbdev->phy_tms = item)
|
|
#define mUsbIntF2OUTDis() (ptusbdev->int_mgrp1 |= (BIT5 | BIT4))
|
|
#define mUsbIntF2OUTEn() (ptusbdev->int_mgrp1 &= ~(BIT5 | BIT4))
|
|
#define mUsbIntF0INDis() (ptusbdev->int_mgrp1 |= BIT16)
|
|
#define mUsbIntF0INEn() (ptusbdev->int_mgrp1 &= ~BIT16)
|
|
// Endpoint & FIFO Configuration
|
|
#define mUsbEPMxPtSz(EPn, dir, size) (ptusbdev->ep_xpsz[dir][EPn - 1] = size)
|
|
#define mUsbEPStallST(EPn, dir) (((ptusbdev->ep_xpsz[dir][EPn - 1]) & BIT11) >> 11)
|
|
#define mUsbEPRsTgSet(EPn, dir) (ptusbdev->ep_xpsz[dir][EPn-1] |= BIT12)
|
|
#define mUsbEPRsTgClr(EPn, dir) (ptusbdev->ep_xpsz[dir][EPn-1] &= ~BIT12)
|
|
#define mUsbEPStallClr(EPn, dir) (ptusbdev->ep_xpsz[dir][EPn-1] &= ~BIT11)
|
|
#define mUsbEPStallSet(EPn, dir) (ptusbdev->ep_xpsz[dir][EPn-1] |= BIT11)
|
|
|
|
extern void CPUflushReadCache(UINT32 uiStartAddr, UINT32 uiLength);
|
|
extern void CPUflushWriteCache(UINT32 uiStartAddr, UINT32 uiLength);
|
|
|
|
INT32S my_SCSICmd(CBW * ptcbw);
|
|
|
|
_THUMB2 signed int usb_DxFifoRdWr(unsigned char * buf, unsigned int count, unsigned int Rd)
|
|
{
|
|
signed int ret = -1; // assume fail
|
|
|
|
//#ifdef USBROM_RTOS_DBG
|
|
//debug_msg("MSG: enter usb_DxFifoRdWr\r\n");
|
|
//#endif
|
|
|
|
CPUflushWriteCache((UINT32) buf, (UINT32) count);
|
|
CPUflushReadCache((UINT32) buf, (UINT32) count);
|
|
|
|
//#ifdef __FREERTOS
|
|
//if(buf == (unsigned char *)0xFE080000)
|
|
// ptusbdev->dma_addr = (INT32U)buf;
|
|
//else
|
|
// ptusbdev->dma_addr = dma_getPhyAddr(buf);
|
|
|
|
//dma_flushWriteCache((UINT32)buf, count);
|
|
//dma_flushReadCache((UINT32)buf, count);
|
|
//#else
|
|
ptusbdev->dma_addr = (INT32U)buf;//dma_getPhyAddr(buf);
|
|
|
|
__asm__ __volatile__("dsb\n\t");
|
|
//#endif
|
|
|
|
|
|
if (Rd) {
|
|
// fifo select
|
|
ptusbdev->dma_fifo = BIT2;
|
|
// ctrl setting
|
|
ptusbdev->dma_ctl = (count << 8) | // dma byte count
|
|
(0 << 2) | // not dma io to io
|
|
(0 << 1); // fifo 2 memory
|
|
|
|
#ifdef USBROM_RTOS_DBG
|
|
debug_msg("MSG: count = %d, Read CTRL = %x\r\n", count, ptusbdev->dma_ctl);
|
|
#endif
|
|
|
|
} else {
|
|
// fifo select
|
|
ptusbdev->dma_fifo = BIT0;
|
|
// ctrl setting
|
|
ptusbdev->dma_ctl = (count << 8) | // dma byte count
|
|
(0 << 2) | // not dma io to io
|
|
(1 << 1); // memory 2 fifo
|
|
|
|
#ifdef USBROM_RTOS_DBG
|
|
debug_msg("MSG: Write count = %d, Write CTRL = %x\r\n", count, ptusbdev->dma_ctl);
|
|
#endif
|
|
}
|
|
|
|
// dma start
|
|
ptusbdev->dma_ctl |= BIT0;
|
|
|
|
while (1) {
|
|
INT32U temp;
|
|
|
|
temp = ptusbdev->int_grp2 & ~ ptusbdev->int_mgrp2;
|
|
|
|
if (temp & BIT7) { // dma completion
|
|
ret = 0; // ok
|
|
break;
|
|
}
|
|
if (temp & (BIT2 | BIT1)) { // bus condiction
|
|
// clear cx fifo
|
|
ptusbdev->cx_cf |= BIT3;
|
|
break;
|
|
}
|
|
if (temp & BIT8) { // dma error
|
|
// clear cx fifo
|
|
ptusbdev->cx_cf |= BIT3;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// clear (dma error & dma completion) interrupt
|
|
ptusbdev->int_grp2 |= (BIT8 | BIT7);
|
|
CPUflushReadCache((UINT32) buf, (UINT32) count);
|
|
|
|
//debug_msg("done\r\n");
|
|
|
|
//#ifdef __FREERTOS
|
|
//dma_flushReadCache((UINT32)buf, count);
|
|
//#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
_THUMB2 void vSCSIHWError(void)
|
|
{
|
|
tCSW.u8Status = CSW_STATUS_CMD_FAIL;
|
|
if ((tCBW.CB0_cblen_lun_flag&0xFF) == CBW_FLAG_OUT) {
|
|
mUsbEPStallSet(OUT_EP, DIRECTION_OUT);
|
|
} else {
|
|
//debug_msg("S1\r\n");
|
|
mUsbEPStallSet(IN_EP, DIRECTION_IN);
|
|
}
|
|
|
|
//#ifdef USBROM_RTOS_DBG
|
|
//DBG_DUMP("MSG: vSCSIHWError\r\n");
|
|
//#endif
|
|
|
|
tSCSIsense.u8Key = KEY_NOT_READY;
|
|
tSCSIsense.u8KeyAdd = ADDKEY_MEDIUM_NOT_PRESENT;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
_THUMB2 MassStorageState eScsiIn(void)
|
|
{
|
|
|
|
switch (tSCSIDeviceResp.u8MemIndex) {
|
|
case CARD_INDEX_SRAM:
|
|
// unit: byte
|
|
if (usb_DxFifoRdWr((INT8U *)u32Usb_buffer, tSCSIDeviceResp.u16DataResidue, 0) >= 0) {
|
|
tCSW.u32DataResidue -= tSCSIDeviceResp.u16DataResidue;
|
|
if (tCSW.u32DataResidue) {
|
|
// wait for fifo empty
|
|
while ((ptusbdev->cx_cf & (BIT8 | BIT9)) != (BIT8 | BIT9)) {
|
|
// if (VBUS == 0)
|
|
// return MS_STATE_CSW;
|
|
}
|
|
//debug_msg("S2\r\n");
|
|
//mUsbEPStallSet(IN_EP, DIRECTION_IN); // case MS13Case_5:
|
|
}
|
|
return MS_STATE_CSW;
|
|
}
|
|
break;
|
|
|
|
case CARD_INDEX_FSM_SS:
|
|
if (usb_DxFifoRdWr((INT8U *)tSCSIDeviceResp.u32IOAddr, tSCSIDeviceResp.u16DataResidue, 0) >= 0) {
|
|
tCSW.u32DataResidue -= tSCSIDeviceResp.u16DataResidue;
|
|
return MS_STATE_CSW;
|
|
} else {
|
|
mUsbEPStallSet(OUT_EP, DIRECTION_IN); // case MS13Case_11:
|
|
}
|
|
break;
|
|
|
|
|
|
default:
|
|
break;
|
|
}
|
|
vSCSIHWError();
|
|
return MS_STATE_CSW;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
_THUMB2 MassStorageState eScsiOut(void)
|
|
{
|
|
switch (tSCSIDeviceResp.u8MemIndex) {
|
|
case CARD_INDEX_SRAM:
|
|
if (usb_DxFifoRdWr((INT8U *)u32Usb_buffer, tSCSIDeviceResp.u16DataResidue, 1) >= 0) {
|
|
tCSW.u32DataResidue -= tSCSIDeviceResp.u16DataResidue;
|
|
if (tCSW.u32DataResidue)
|
|
mUsbEPStallSet(OUT_EP, DIRECTION_OUT); // case MS13Case_11:
|
|
return MS_STATE_CSW;
|
|
}
|
|
break;
|
|
|
|
case CARD_INDEX_FSM_SS:
|
|
if (usb_DxFifoRdWr((INT8U *)tSCSIDeviceResp.u32IOAddr, tSCSIDeviceResp.u16DataResidue, 1) >= 0) {
|
|
tCSW.u32DataResidue -= tSCSIDeviceResp.u16DataResidue;
|
|
return MS_STATE_CSW;
|
|
} else {
|
|
mUsbEPStallSet(OUT_EP, DIRECTION_OUT); // case MS13Case_11:
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
vSCSIHWError();
|
|
return MS_STATE_CSW;
|
|
}
|
|
|
|
typedef unsigned int size_t;
|
|
extern void *utl_memcpy(void *dest, const void *src, size_t count);
|
|
|
|
_THUMB2 void vSCSICmd_RequestSense(void)
|
|
{
|
|
// Device intend to send data
|
|
tSCSIDeviceResp.u8Flags = CBW_FLAG_IN;
|
|
tSCSIDeviceResp.u8MemIndex = CARD_INDEX_SRAM;
|
|
tSCSIDeviceResp.u16DataResidue = sizeof(u8RequestSenseData);
|
|
|
|
// copy response to sram
|
|
utl_memcpy ((UINT32 *)u32Usb_buffer, (UINT32 *)u8RequestSenseData, (UINT32)sizeof(u8RequestSenseData));
|
|
|
|
*((unsigned int *)u32Usb_buffer + (SENSE_OFFSET_KEY>>2)) += (tSCSIsense.u8Key&0xFF)<<16;
|
|
*((unsigned int *)u32Usb_buffer + (SENSE_OFFSET_ADD>>2)) += (tSCSIsense.u8KeyAdd&0xFF);
|
|
|
|
// all key disappear
|
|
tSCSIsense.u8Key = KEY_NO_SENSE;
|
|
tSCSIsense.u8KeyAdd = ADDKEY_NO_ADDITIONAL;
|
|
}
|
|
|
|
_THUMB2 void vSCSICmd_ModeSense(void)
|
|
{
|
|
|
|
//switch (tCBW.u8CB[2]) {
|
|
switch ((tCBW.CB1_CB15[0]>>8)&0xFF) {
|
|
case 0x00: // return mode parameter header and block descriptor
|
|
//debug_msg("MODE_SENSE 00\r\n");
|
|
tSCSIDeviceResp.u16DataResidue = 0x0C;
|
|
break;
|
|
case 0x3F: // all pages
|
|
//debug_msg("MODE_SENSE 3F\r\n");
|
|
tSCSIDeviceResp.u16DataResidue = sizeof(u8ModeSenseData);
|
|
break;
|
|
default:
|
|
//debug_msg("MODE_SENSE ERR\r\n");
|
|
tSCSIsense.u8Key = KEY_ILLEGAL_REQUEST;
|
|
tSCSIsense.u8KeyAdd = ADDKEY_INVALID_FIELD_IN_CMD;
|
|
tCSW.u8Status = CSW_STATUS_CMD_FAIL;
|
|
return;
|
|
}
|
|
// Device intend to send data
|
|
tSCSIDeviceResp.u8Flags = CBW_FLAG_IN;
|
|
tSCSIDeviceResp.u8MemIndex = CARD_INDEX_SRAM;
|
|
|
|
// copy response to sram
|
|
utl_memcpy((UINT32 *)u32Usb_buffer, (UINT32 *)u8ModeSenseData, (UINT32)tSCSIDeviceResp.u16DataResidue);
|
|
}
|
|
|
|
|
|
|
|
_THUMB2 void vSCSICmd_Unsupport(void)
|
|
{
|
|
// Device intend to transfer no data
|
|
tSCSIsense.u8Key = KEY_ILLEGAL_REQUEST;
|
|
tSCSIsense.u8KeyAdd = ADDKEY_INVALID_CMD_OP_CODE;
|
|
tCSW.u8Status = CSW_STATUS_CMD_FAIL;
|
|
|
|
//#ifdef DISPLAY_USB_INFORMATION
|
|
//DBG_DUMP("MSG: UnSupported SCSI Command (op code = 0x%x)\r\n", tCBW.u8CB[0]);
|
|
//#endif
|
|
}
|
|
|
|
_THUMB2 MassStorageState eMassStorage13case(void)
|
|
{
|
|
MassStorage13Case eCase = 0x0;
|
|
MassStorageState estate;
|
|
INT32U u32DeviceRespDataLength = 0x0;
|
|
|
|
switch(tSCSIDeviceResp.u8MemIndex) {
|
|
case CARD_INDEX_SRAM:
|
|
u32DeviceRespDataLength = tSCSIDeviceResp.u16DataResidue;
|
|
tSCSIDeviceResp.u32IOAddr += tSCSIDeviceResp.u16TfSzCurrent;
|
|
break;
|
|
case CARD_INDEX_FSM_SS:
|
|
u32DeviceRespDataLength = tSCSIDeviceResp.u16DataResidue;
|
|
break;
|
|
default:// SPI
|
|
u32DeviceRespDataLength = tSCSIDeviceResp.u16DataResidue * 2112;
|
|
break;
|
|
}
|
|
|
|
// Mass Storage the thirteen case
|
|
if (tCBW.u32DataTransferLength == u32DeviceRespDataLength) {
|
|
// normal case
|
|
if (tCBW.u32DataTransferLength == 0)
|
|
eCase = MS13Case_1; // MassStorage case (1)
|
|
else {
|
|
if ((tCBW.CB0_cblen_lun_flag&0xFF) == tSCSIDeviceResp.u8Flags) {
|
|
if ((tCBW.CB0_cblen_lun_flag&0xFF) == CBW_FLAG_IN)
|
|
eCase = MS13Case_6; // MassStorage case (6)
|
|
else
|
|
eCase = MS13Case_12; // MassStorage case (12)
|
|
}
|
|
}
|
|
|
|
//#ifdef DISPLAY_USB_INFORMATION
|
|
// vShowSCSI();
|
|
//#endif
|
|
|
|
} else {
|
|
if (tCBW.u32DataTransferLength == 0)
|
|
eCase = MS13Case_2_3; // MassStorage case (2)(3)
|
|
else if ((tCBW.CB0_cblen_lun_flag&0xFF) == CBW_FLAG_IN) {
|
|
if (u32DeviceRespDataLength == 0)
|
|
eCase = MS13Case_4; // MassStorage case (4)
|
|
else if (tSCSIDeviceResp.u8Flags == CBW_FLAG_IN) {
|
|
if (tCBW.u32DataTransferLength > u32DeviceRespDataLength)
|
|
eCase = MS13Case_5; // MassStorage case (5)
|
|
else
|
|
eCase = MS13Case_7_8; // MassStorage case (7)(8)
|
|
}
|
|
}
|
|
else { //tCBW.u8Flags == CBW_FLAG_OUT
|
|
if (u32DeviceRespDataLength == 0)
|
|
eCase = MS13Case_9; // MassStorage case (9)
|
|
else if (tSCSIDeviceResp.u8Flags == CBW_FLAG_OUT) {
|
|
if (tCBW.u32DataTransferLength > u32DeviceRespDataLength)
|
|
eCase = MS13Case_11; // MassStorage case (11)
|
|
else
|
|
eCase = MS13Case_10_13; // MassStorage case (10)(13)
|
|
}
|
|
}
|
|
|
|
//#ifdef DISPLAY_USB_INFORMATION
|
|
// {
|
|
//vShowUsb();
|
|
// DBG_DUMP("MSG: MS13Case = 0x%x\r\n", eCase);
|
|
// DBG_DUMP("MSG: , u32DeviceRespDataLength = 0x%x\r\n", u32DeviceRespDataLength);
|
|
// }
|
|
//#endif
|
|
|
|
}
|
|
|
|
// assume the next state is STATE_CSW
|
|
estate = MS_STATE_CSW;
|
|
switch (eCase) {
|
|
case MS13Case_2_3:
|
|
//debug_msg("S3\r\n");
|
|
mUsbEPStallSet(IN_EP, DIRECTION_IN);
|
|
tCSW.u8Status = CSW_STATUS_PHASE_ERROR;
|
|
break;
|
|
case MS13Case_4:
|
|
//debug_msg("S4\r\n");
|
|
mUsbEPStallSet(IN_EP, DIRECTION_IN);
|
|
break;
|
|
case MS13Case_5:
|
|
case MS13Case_6:
|
|
estate = eScsiIn();
|
|
break;
|
|
case MS13Case_11:
|
|
case MS13Case_12:
|
|
estate = eScsiOut();
|
|
break;
|
|
case MS13Case_7_8:
|
|
//debug_msg("S5\r\n");
|
|
mUsbEPStallSet(IN_EP, DIRECTION_IN);
|
|
tCSW.u8Status = CSW_STATUS_PHASE_ERROR;
|
|
break;
|
|
case MS13Case_9:
|
|
mUsbEPStallSet(OUT_EP, DIRECTION_OUT);
|
|
break;
|
|
case MS13Case_10_13:
|
|
mUsbEPStallSet(OUT_EP, DIRECTION_OUT);
|
|
tCSW.u8Status = CSW_STATUS_PHASE_ERROR;
|
|
//debug_msg("S6\r\n");
|
|
mUsbEPStallSet(IN_EP, DIRECTION_IN);
|
|
break;
|
|
default: // MS13Case_1;
|
|
// do nothing here
|
|
break;
|
|
}
|
|
return estate;
|
|
}
|
|
|
|
|
|
_THUMB2 MassStorageState eSCSI_CmdDecode(void) //trace, different from FUSB100-CardReader
|
|
{
|
|
//debug_msg("eSCSI_CmdDecode\r\n");
|
|
// Assume SCSI Response data length will be 0
|
|
tSCSIDeviceResp.u16DataResidue = 0;
|
|
if (((tCBW.CB0_cblen_lun_flag >> 8)&0xFF) >= CARD_TYPE_MAX_REPORT) {
|
|
tCSW.u8Status = CSW_STATUS_CMD_FAIL;
|
|
tSCSIsense.u8Key = KEY_NOT_READY;
|
|
tSCSIsense.u8KeyAdd = ADDKEY_LOGICAL_UNIT_NOT_SUPPORT;
|
|
} else {
|
|
// Parse SCSI command
|
|
//switch (tCBW.u8CB[0]) { // Operation Code
|
|
switch ((tCBW.CB0_cblen_lun_flag >> 24)&0xFF) { // Operation Code
|
|
case SCSI_OP_REQUEST_SENSE:
|
|
vSCSICmd_RequestSense();
|
|
//debug_msg("vSCSICmd_RequestSense\r\n");
|
|
break;
|
|
case SCSI_OP_MEDIUM_REMOVAL:
|
|
//vSCSICmd_MediumRemoval();
|
|
debug_msg("SCSI_OP_MEDIUM_REMOVAL\r\n");
|
|
break;
|
|
case SCSI_OP_INQUIRY:
|
|
//vSCSICmd_Inquiry();
|
|
debug_msg("SCSI_OP_INQUIRY\r\n");
|
|
break;
|
|
case SCSI_OP_MODE_SENSE:
|
|
vSCSICmd_ModeSense();
|
|
//debug_msg("SCSI_OP_MODE_SENSE 22\r\n");
|
|
break;
|
|
|
|
case SCSI_OP_TEST_UNIT_READY:
|
|
case SCSI_OP_READ_CAPACITY:
|
|
case SCSI_OP_READ_10:
|
|
case SCSI_OP_WRITE_10:
|
|
case SCSI_OP_VERIFY:
|
|
//debug_msg("SCSI_OP_TEST_UNIT_READY\r\n");
|
|
tSCSIsense.u8Key = KEY_NOT_READY;
|
|
tSCSIsense.u8KeyAdd = ADDKEY_MEDIUM_NOT_PRESENT;
|
|
tCSW.u8Status = CSW_STATUS_CMD_FAIL;
|
|
break;
|
|
|
|
default:
|
|
if (my_SCSICmd(&tCBW) < 0) {
|
|
//#ifdef USBROM_RTOS_DBG
|
|
debug_msg("MSG: SCSI cmd: UNSUPPOR\r\n");
|
|
//#endif
|
|
vSCSICmd_Unsupport();
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
return eMassStorage13case();
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_THUMB2 MassStorageState eUsbProessCBW(void)
|
|
{
|
|
usb_DxFifoRdWr((unsigned char *)&tCBW, 31, 1);
|
|
|
|
if(tCBW.u32Signature != CBW_SIGNATE) {
|
|
return MS_STATE_CBW;
|
|
} else {
|
|
// pass u32DataTransferLength to u32DataResidue
|
|
tCSW.u32DataResidue = tCBW.u32DataTransferLength;
|
|
|
|
#ifdef USBROM_RTOS_DBG
|
|
//DBG_DUMP("MSG: tCSW.u32DataResidue = %d, dir = %d\r\n", tCBW.u32DataTransferLength, tCBW.u8Flags);
|
|
#endif
|
|
|
|
// pass Tag from CBW to CSW
|
|
tCSW.u32Tag = tCBW.u32Tag;
|
|
// Assume Status is CMD_PASS
|
|
tCSW.u8Status = CSW_STATUS_CMD_PASS;
|
|
|
|
return eSCSI_CmdDecode();
|
|
}
|
|
}
|
|
|
|
_THUMB2 void vUsbUnplug(void)
|
|
{
|
|
//#ifdef USBROM_RTOS_DBG
|
|
//debug_msg("MSG: Unplug.. pls check\r\n");
|
|
//#endif
|
|
// mUsbUnPlug();
|
|
ptusbdev->phy_tms |= BIT0;
|
|
}
|
|
|
|
_THUMB2 void vUsb_BulkIntOnOff(void)
|
|
{
|
|
//#ifdef USBROM_RTOS_DBG
|
|
//DBG_DUMP("MSG: st 0x%x", eUsbMassStorageState);
|
|
//#endif
|
|
|
|
switch(eUsbMassStorageState)
|
|
{
|
|
case MS_STATE_CBW:
|
|
mUsbIntF2OUTEn();
|
|
mUsbIntF0INDis();
|
|
break;
|
|
case MS_STATE_CB_DMA_IN:
|
|
if (mUsbEPStallST (IN_EP, DIRECTION_IN)) {
|
|
// wait for clear feature, and then enable F0
|
|
}
|
|
else
|
|
mUsbIntF0INEn();
|
|
break;
|
|
case MS_STATE_CB_DMA_OUT:
|
|
mUsbIntF2OUTEn();
|
|
break;
|
|
case MS_STATE_CSW:
|
|
mUsbIntF2OUTDis();
|
|
if (mUsbEPStallST (IN_EP, DIRECTION_IN)) {
|
|
// wait for clear feature, and then enable F0
|
|
}
|
|
else {
|
|
mUsbIntF0INEn();
|
|
}
|
|
break;
|
|
case MS_STATE_BGD:
|
|
mUsbIntF2OUTDis();
|
|
mUsbIntF0INDis();
|
|
break;
|
|
default:
|
|
//#ifdef USBROM_RTOS_DBG
|
|
debug_msg("MSG: Error MS_STATE\r\n");
|
|
//#endif
|
|
vUsbUnplug();
|
|
break;
|
|
}
|
|
}
|
|
|
|
_THUMB2 void vUsb_F0_In(void)
|
|
{
|
|
switch(eUsbMassStorageState)
|
|
{
|
|
case MS_STATE_CSW:
|
|
//#ifdef USBROM_RTOS_DBG
|
|
//debug_msg("MSG: EP1 IN CSW\r\n");
|
|
//#endif
|
|
|
|
if (trigger_done_cb) {
|
|
trigger_done_cb = 0;
|
|
|
|
if (guiU2MsdcVendorDone_cb != NULL) {
|
|
if (guiU2MsdcVendorDone_cb((unsigned int)&tCBW) != 0) {
|
|
tCSW.u8Status = CSW_STATUS_CMD_FAIL;
|
|
}
|
|
}
|
|
}
|
|
|
|
usb_DxFifoRdWr((unsigned char *)&tCSW, 13, 0);
|
|
|
|
//mUsbFIFODone(FIFO0);
|
|
eUsbMassStorageState = MS_STATE_CBW;
|
|
if(usbrom_exit == 1)
|
|
usbrom_exit = 2;
|
|
break;
|
|
case MS_STATE_CB_DMA_IN:
|
|
//#ifdef USBROM_RTOS_DBG
|
|
//debug_msg("MSG: EP1 CS DMA IN\r\n");
|
|
//#endif
|
|
eUsbMassStorageState = eScsiOut();
|
|
break;
|
|
default:
|
|
//#ifdef USBROM_RTOS_DBG
|
|
debug_msg("MSG: Error FIFO0_IN interrupt.\r\n");
|
|
//#endif
|
|
|
|
break;
|
|
}
|
|
vUsb_BulkIntOnOff();
|
|
}
|
|
|
|
_THUMB2 void vUsb_F2_Out(unsigned int u32FIFOByteCount)
|
|
{
|
|
switch(eUsbMassStorageState) {
|
|
case MS_STATE_CBW:
|
|
|
|
//#ifdef USBROM_RTOS_DBG
|
|
//debug_msg("MSG: EP2 Out CBW\r\n");
|
|
//#endif
|
|
|
|
if (u32FIFOByteCount == 31) {
|
|
eUsbMassStorageState = eUsbProessCBW();
|
|
}
|
|
else{
|
|
//#ifdef USBROM_RTOS_DBG
|
|
//debug_msg("MSG: EP out STAL SET\r\n");
|
|
//#endif
|
|
|
|
mUsbEPStallSet(OUT_EP, DIRECTION_OUT);
|
|
}
|
|
break;
|
|
case MS_STATE_CB_DMA_OUT:
|
|
|
|
//#ifdef USBROM_RTOS_DBG
|
|
//debug_msg("MSG: EP2 Out CB DMA Out\r\n");
|
|
//#endif
|
|
|
|
eUsbMassStorageState = eScsiOut();
|
|
break;
|
|
default:
|
|
|
|
//#ifdef USBROM_RTOS_DBG
|
|
//debug_msg("MSG: Error FIFO2_OUT interrupt.\r\n");
|
|
//#endif
|
|
|
|
break;
|
|
}
|
|
|
|
vUsb_BulkIntOnOff();
|
|
}
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// bClear_feature()
|
|
// Description:
|
|
// 1. Send 2 bytes status to host.
|
|
// input: none
|
|
// output: TRUE or FALSE (BOOLEAN)
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
_THUMB2 signed int usb_Clear_feature(void)
|
|
{
|
|
unsigned int ep_n;
|
|
unsigned int fifo_n;
|
|
signed int bdir;
|
|
|
|
switch (mCxValue (tusb.u32UsbCmd)) { // FeatureSelector
|
|
case 0: // ENDPOINT_HALE
|
|
// Clear "Endpoint_Halt", Turn off the "STALL" bit in Endpoint Control Function Register
|
|
if(mCxIndex (tusb.u32UsbCmd) == 0x00)
|
|
tusb.bUsbEP0HaltSt = FALSE;
|
|
else {
|
|
ep_n = mCxIndex (tusb.u32UsbCmd) & 0x7F; // which ep will be clear
|
|
// over the Max. ep count ?
|
|
if (ep_n > FUSB200_MAX_EP)
|
|
return -1;
|
|
// the direction of this ep
|
|
// bdir =0 if OUT
|
|
bdir = mCxIndex (tusb.u32UsbCmd) & BIT7;;
|
|
// get the relatived FIFO number
|
|
if (bdir)
|
|
fifo_n = mUsbEPMapRd(ep_n) & 0x0F;
|
|
else
|
|
fifo_n = mUsbEPMapRd(ep_n) >> 4;
|
|
// over the Max. fifo count ?
|
|
if (fifo_n >= FUSB200_MAX_FIFO)
|
|
return -1;
|
|
|
|
// Check the FIFO had been enable ?
|
|
if ((mUsbFIFOConfigRd(fifo_n) & BIT5) == 0)
|
|
return -1;
|
|
// bdir =0 if IN, 1 if OUT
|
|
bdir = bdir ? 0: 1;
|
|
mUsbEPRsTgSet(ep_n, bdir); // Set Rst_Toggle Bit
|
|
mUsbEPRsTgClr(ep_n, bdir); // Clear Rst_Toggle Bit
|
|
mUsbEPStallClr(ep_n, bdir); // Clear Stall Bit
|
|
vUsb_BulkIntOnOff();
|
|
}
|
|
break;
|
|
case 1 : // Device Remote Wakeup
|
|
// Clear "Device_Remote_Wakeup", Turn off the"RMWKUP" bit in Main Control Register
|
|
mUsbRmWkupClr();
|
|
break;
|
|
case 2 : // Test Mode
|
|
// do not break here
|
|
default :
|
|
return -1;
|
|
}
|
|
tusb.eUsbCxAction = ACT_DONE;
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
_THUMB2 signed int usb_StandardCommand(void)
|
|
{
|
|
switch (mCxRequest (tusb.u32UsbCmd)) { // by Standard Request codes
|
|
//case 0: // get status
|
|
// return (usb_Get_status());
|
|
|
|
case 1: // clear feature
|
|
return (usb_Clear_feature());
|
|
|
|
//case 3: // set feature
|
|
// return (usb_Set_feature());
|
|
|
|
//case 5: // set address
|
|
// if (!tusb.bUsbEP0HaltSt)
|
|
// return(usb_Set_address());
|
|
// break;
|
|
|
|
//case 6: // get descriptor
|
|
// if (!tusb.bUsbEP0HaltSt)
|
|
// return(usb_Get_descriptor());
|
|
// break;
|
|
|
|
//case 8: // get configuration
|
|
// if (!tusb.bUsbEP0HaltSt)
|
|
// vGet_configuration();
|
|
// return 0;
|
|
|
|
//case 9: // set configuration
|
|
// if (!tusb.bUsbEP0HaltSt)
|
|
// return(usb_Set_configuration());
|
|
// break;
|
|
|
|
//case 10: // get interface
|
|
// if (!tusb.bUsbEP0HaltSt)
|
|
// return(usb_Get_interface());
|
|
// break;
|
|
|
|
// case 11: // set interface
|
|
// if (!tusb.bUsbEP0HaltSt)
|
|
// return(usb_Set_interface());
|
|
// break;
|
|
|
|
case 2: // Reserved for further use
|
|
case 4: // Reserved for further use
|
|
case 7: // set descriptor, not support
|
|
case 12: // synch frame, not support
|
|
default:
|
|
break;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// vUsb_ep0setup()
|
|
// Description:
|
|
// 1. Read 8-byte setup packet.
|
|
// 2. Decode command as Standard, Class, Vendor or NOT support command
|
|
// input: none
|
|
// output: none
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
_THUMB2 void vUsb_ep0setup(void)
|
|
{
|
|
/*
|
|
if(tusb.bUsbChirpFinish == 0)
|
|
{
|
|
// first ep0 command after usb reset, means we can check usb speed right now.
|
|
tusb.bUsbChirpFinish = 1;
|
|
|
|
if (ptusbdev->main_ctl & BIT6) {
|
|
tusb.bHighSpeed = 1;
|
|
//DBG_DUMP("MSG: L%x, high speed mode\r\n", tusb.u8LineCount ++);
|
|
}
|
|
else {
|
|
tusb.bHighSpeed = 0;
|
|
//DBG_DUMP("MSG: L%x, full speed mode\r\n", tusb.u8LineCount ++);
|
|
}
|
|
// Init AP
|
|
vUsbMassStorageInit();
|
|
}
|
|
*/
|
|
|
|
// select dma target fifo no.:
|
|
//ptusbdev->dma_fifo = BIT4;
|
|
|
|
// Read 8-byte setup packet from FIFO
|
|
tusb.u32UsbCmd[0] = ptusbdev->dma_data;
|
|
tusb.u32UsbCmd[1] = ptusbdev->dma_data;
|
|
|
|
#if 0//def USBROM_RTOS_DBG
|
|
DBG_DUMP("MSG: L%x, EP0Cmd: %x %x %x %x %x %x %x %x\r\n",
|
|
tusb.u8LineCount ++, (INT8U)(tusb.u32UsbCmd[0] >> 0)
|
|
, (INT8U)(tusb.u32UsbCmd[0] >> 8)
|
|
, (INT8U)(tusb.u32UsbCmd[0] >> 16)
|
|
, (INT8U)(tusb.u32UsbCmd[0] >> 24)
|
|
, (INT8U)(tusb.u32UsbCmd[1] >> 0)
|
|
, (INT8U)(tusb.u32UsbCmd[1] >> 8)
|
|
, (INT8U)(tusb.u32UsbCmd[1] >> 16)
|
|
, (INT8U)(tusb.u32UsbCmd[1] >> 24));
|
|
#endif
|
|
|
|
// Command Decode
|
|
switch (mCxType(tusb.u32UsbCmd)) {
|
|
case 0: // standard command
|
|
|
|
//#ifdef USBROM_RTOS_DBG
|
|
//DBG_DUMP("MSG: Standard command\r\n");
|
|
//#endif
|
|
|
|
if (usb_StandardCommand() < 0)
|
|
tusb.eUsbCxAction = ACT_STALL;
|
|
break;
|
|
/*
|
|
case 1: // class command
|
|
|
|
#ifdef USBROM_RTOS_DBG
|
|
DBG_DUMP("MSG: class command\r\n");
|
|
#endif
|
|
|
|
if (usb_ClassCommand() < 0)
|
|
tusb.eUsbCxAction = ACT_STALL;
|
|
break;
|
|
|
|
case 2: // vendor command
|
|
#ifdef USBROM_RTOS_DBG
|
|
DBG_DUMP("MSG: vendor command\r\n");
|
|
#endif
|
|
// if (usb_UsbVendorCommand() < 0
|
|
tusb.eUsbCxAction = ACT_STALL;
|
|
break;
|
|
*/
|
|
default:
|
|
// Invalid(bad) command, Return EP0_STALL flag
|
|
tusb.eUsbCxAction = ACT_STALL;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
_THUMB2 void vUsbInit(void)
|
|
{
|
|
ptusbdev = ((volatile DEV *)(IOADDR_USB_REG_BASE + 0x100));
|
|
|
|
// init variables
|
|
tusb.eUsbCxAction = ACT_IDLE;
|
|
tusb.bUsbChirpFinish = 0;
|
|
|
|
tusb.u16TxRxCounter = 0;
|
|
tusb.eUsbCxCommand = CMD_VOID;
|
|
tusb.u8UsbConfigValue = 0;
|
|
tusb.u8UsbInterfaceValue = 0;
|
|
tusb.u8UsbInterfaceAlternateSetting = 0;
|
|
tusb.bUsbEP0HaltSt = FALSE;
|
|
|
|
// init hardware
|
|
//vFUSB200Init();
|
|
tusb.u8LineCount = 1;
|
|
|
|
tCSW.u32Signature = CSW_SIGNATE;
|
|
eUsbMassStorageState = MS_STATE_CBW;
|
|
mUsbIntF2OUTEn ();
|
|
mUsbIntF0INDis();
|
|
|
|
}
|
|
|
|
|
|
|
|
_THUMB2 void vUsbIsr2(void)
|
|
{
|
|
INT32U level1;
|
|
INT32U level2;
|
|
|
|
level1 = ptusbdev->int_grp & ~ ptusbdev->int_mgrp;
|
|
|
|
if (0 == level1)
|
|
return;
|
|
|
|
if (level1 & BIT2) { //Group 2
|
|
|
|
level2 = ptusbdev->int_grp2 & ~ ptusbdev->int_mgrp2;
|
|
|
|
if (level2) {
|
|
|
|
//debug_msg("MSG: IntSCR2\r\n");
|
|
|
|
if (level2 & BIT0) {
|
|
//debug_msg("MSG: BUS RST\r\n");
|
|
}
|
|
|
|
if (level2 & BIT1) {
|
|
//debug_msg("MSG: BUS SUSPEND\r\n");
|
|
ptusbdev->int_grp2 |= BIT1;
|
|
}
|
|
|
|
if (level2 & BIT2) {
|
|
//debug_msg("MSG: BUS RESUME\r\n");
|
|
ptusbdev->int_grp2 |= BIT2;
|
|
}
|
|
|
|
if (level2 & BIT5) {
|
|
//debug_msg("MSG: TX0B\r\n");
|
|
|
|
ptusbdev->tx0byte |= 0;
|
|
ptusbdev->int_grp2 |= BIT5;
|
|
}
|
|
|
|
if (level2 & BIT6) {
|
|
//debug_msg("MSG: RX0B\r\n");
|
|
ptusbdev->rx0byte |= 0;
|
|
ptusbdev->int_grp2 |= BIT6;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
if (level1 & BIT0) { //Group 0
|
|
level2 = ptusbdev->int_grp0 & ~ ptusbdev->int_mgrp0;
|
|
if (level2) {
|
|
//debug_msg("MSG: IntSCR0\r\n");
|
|
|
|
if (level2 & BIT0) {
|
|
//debug_msg("MSG: USB ep0 Setup\r\n");
|
|
vUsb_ep0setup();
|
|
}
|
|
else if (level2 & BIT3) {
|
|
//debug_msg("MSG: USB ep0 end\r\n");
|
|
//vUsb_ep0end();
|
|
}
|
|
if (level2 & BIT1) {
|
|
//debug_msg("MSG: USB ep0 TX\r\n");
|
|
//vUsb_ep0tx();
|
|
}
|
|
if (level2 & BIT2) {
|
|
//#ifdef USBROM_RTOS_DBG
|
|
//debug_msg("MSG: USB ep0 RX\r\n");
|
|
//#endif
|
|
//vUsb_ep0rx();
|
|
}
|
|
if (level2 & BIT4) {
|
|
|
|
//#ifdef USBROM_RTOS_DBG
|
|
//debug_msg("MSG: USB ep0 fail\r\n");
|
|
//#endif
|
|
// stall cx: mUsbEP0StallSet();
|
|
//ptusbdev->cx_cf |= BIT2;
|
|
}
|
|
if (level2 & BIT5) {
|
|
|
|
//#ifdef USBROM_RTOS_DBG
|
|
//debug_msg("MSG: cmd abort\r\n");
|
|
//#endif
|
|
ptusbdev->int_grp0 |= BIT5;
|
|
}
|
|
}
|
|
|
|
|
|
if (tusb.eUsbCxAction == ACT_STALL) {
|
|
ptusbdev->cx_cf |= BIT2;
|
|
|
|
//#ifdef USBROM_RTOS_DBG
|
|
//DBG_DUMP("MSG: EP0 STALL\r\n");
|
|
//#endif
|
|
}
|
|
else if (tusb.eUsbCxAction == ACT_DONE) {
|
|
ptusbdev->cx_cf |= BIT0;
|
|
|
|
//#ifdef USBROM_RTOS_DBG
|
|
//DBG_DUMP("MSG: EP0 DONE\r\n");
|
|
//#endif
|
|
}
|
|
// Clear Action
|
|
tusb.eUsbCxAction = ACT_IDLE;
|
|
|
|
|
|
}
|
|
|
|
if (level1 & BIT1) { //Group Byte 1
|
|
level2 = ptusbdev->int_grp1 & ~ ptusbdev->int_mgrp1;
|
|
|
|
//#ifdef USBROM_RTOS_DBG
|
|
//debug_msg("MSG: IntSCR1\r\n");
|
|
//#endif
|
|
|
|
if (level2 & (BIT5 | BIT4)) { // F2 out (full or short)
|
|
vUsb_F2_Out(ptusbdev->fifo_bc[2]);
|
|
}
|
|
|
|
if (level2 & BIT16) // F0 in
|
|
vUsb_F0_In();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
_THUMB2 static INT32U calc_sum_v2(INT32U dat0, INT32U dat1, INT32U dat2, INT32U dat3)
|
|
{
|
|
INT32U sum=0;
|
|
|
|
sum = (dat0&0xFFFF)+((dat0>>16))+(dat1&0xFFFF)+((dat1>>16)) +
|
|
(dat2&0xFFFF)+((dat2>>16))+(dat3&0xFFFF)+((dat3>>16)) + 28;
|
|
|
|
//DBG_DUMP("SUM = 0x%08X\r\n",sum);
|
|
return sum&0xFFFF;
|
|
}
|
|
|
|
_THUMB2 INT32S my_SCSICmd(CBW * ptcbw)
|
|
{
|
|
INT32U temp1, temp2;
|
|
INT32U CDB[4];
|
|
|
|
CDB[0] = ((ptcbw->CB0_cblen_lun_flag >> 24) & 0xFF) + ((ptcbw->CB1_CB15[0]&0xFFFFFF)<<8);
|
|
CDB[1] = ((ptcbw->CB1_CB15[0] >> 24) & 0xFF) + ((ptcbw->CB1_CB15[1]&0xFFFFFF)<<8);
|
|
CDB[2] = ((ptcbw->CB1_CB15[1] >> 24) & 0xFF) + ((ptcbw->CB1_CB15[2]&0xFFFFFF)<<8);
|
|
CDB[3] = ((ptcbw->CB1_CB15[2] >> 24) & 0xFF) + ((ptcbw->CB1_CB15[3]&0xFFFFFF)<<8);
|
|
|
|
// Parse SCSI command
|
|
if (!(((CDB[0]&0xFF) == SCSI_OP_SET0)||((CDB[0]&0xFF) == SCSI_OP_SET1)||((CDB[0]&0xFF) == SCSI_OP_SET2)))
|
|
return -1;
|
|
|
|
// check sum
|
|
if(calc_sum_v2(CDB[0],CDB[1],CDB[2],CDB[3])) {
|
|
tCSW.u8Status = CSW_STATUS_CMD_FAIL;
|
|
u32Usb_buffer[0] = 0;
|
|
#ifdef USBROM_RTOS_DBG
|
|
DBG_DUMP("CHKSUM FAILED\r\n");
|
|
#endif
|
|
return -1;
|
|
}
|
|
|
|
tCSW.u8Status = CSW_STATUS_CMD_PASS;
|
|
|
|
switch (((CDB[0] >> 8) &0xFF)) {
|
|
|
|
case SCSIOP_OUT_OPEN_DEVICE: {
|
|
nvtdev_opened = 1;
|
|
#ifdef USBROM_RTOS_DBG
|
|
DBG_DUMP("SCSIOP_OUT_OPEN_DEVICE\r\n");
|
|
#endif
|
|
}
|
|
break;
|
|
|
|
case SCSIOP_IN_WAIT_DONE: {
|
|
usbrom_exit = 1;
|
|
#ifdef USBROM_RTOS_DBG
|
|
DBG_DUMP("SCSIOP_IN_WAIT_DONE\r\n");
|
|
#endif
|
|
}
|
|
break;
|
|
|
|
|
|
case SCSIOP_IN_IS_NVT: {
|
|
tSCSIDeviceResp.u8Flags = CBW_FLAG_IN;
|
|
tSCSIDeviceResp.u8MemIndex = CARD_INDEX_SRAM;
|
|
tSCSIDeviceResp.u16DataResidue = 4;
|
|
|
|
tCSW.u8Status = CSW_STATUS_CMD_PASS;
|
|
u32Usb_buffer[0] = 0x70210000;
|
|
#ifdef USBROM_RTOS_DBG
|
|
DBG_DUMP("SCSIOP_IN_IS_NVT\r\n");
|
|
#endif
|
|
}
|
|
break;
|
|
|
|
case SCSIOP_OUT_ADDR_WRITE: {
|
|
|
|
if(nvtdev_opened == 0) {
|
|
tCSW.u8Status = CSW_STATUS_CMD_FAIL;
|
|
} else {
|
|
// address
|
|
temp1 = ((CDB[0]>>16)&0xFFFF)+((CDB[1]&0xFFFF)<<16);//u8to32(&ptcbw->u8CB[2]);
|
|
// data
|
|
temp2 = ((CDB[1]>>16)&0xFFFF)+((CDB[2]&0xFFFF)<<16);//u8to32(&ptcbw->u8CB[6]);
|
|
|
|
*(INT32U *)temp1 = temp2;
|
|
__asm__ __volatile__("dsb\n\t");
|
|
|
|
#ifdef USBROM_RTOS_DBG
|
|
DBG_DUMP("SCSIOP_OUT_ADDR_WRITE 0x%08X 0x%08X\r\n", temp1, temp2);
|
|
#endif
|
|
}
|
|
}
|
|
break;
|
|
|
|
case SCSIOP_IN_ADDR_READ: {
|
|
|
|
if(nvtdev_opened == 0) {
|
|
tCSW.u8Status = CSW_STATUS_CMD_FAIL;
|
|
} else {
|
|
// address
|
|
temp1 = ((CDB[0]>>16)&0xFFFF)+((CDB[1]&0xFFFF)<<16);//u8to32(&ptcbw->u8CB[2]);
|
|
|
|
tSCSIDeviceResp.u8Flags = CBW_FLAG_IN;
|
|
tSCSIDeviceResp.u8MemIndex = CARD_INDEX_SRAM;
|
|
tSCSIDeviceResp.u16DataResidue = 8;
|
|
u32Usb_buffer[0] = temp1;
|
|
u32Usb_buffer[1] = *((INT32U *)temp1);
|
|
|
|
#ifdef USBROM_RTOS_DBG
|
|
DBG_DUMP("SCSIOP_IN_ADDR_READ 0x%08X 0x%08X\r\n", temp1, u32Usb_buffer[1]);
|
|
#endif
|
|
}
|
|
}
|
|
break;
|
|
#if 0 //only rom code support
|
|
case SCSIOP_OUT_WRLOADER: {
|
|
|
|
if(nvtdev_opened == 0) {
|
|
tCSW.u8Status = CSW_STATUS_CMD_FAIL;
|
|
} else {
|
|
// address
|
|
temp1 = ((CDB[0]>>16)&0xFFFF)+((CDB[1]&0xFFFF)<<16);//u8to32(&ptcbw->u8CB[2]);
|
|
|
|
tSCSIDeviceResp.u32IOAddr = temp1;
|
|
tSCSIDeviceResp.u8Flags = CBW_FLAG_OUT;
|
|
tSCSIDeviceResp.u8MemIndex = CARD_INDEX_FSM_SS;
|
|
tSCSIDeviceResp.u16DataResidue = ptcbw->u32DataTransferLength;
|
|
|
|
#ifdef USBROM_RTOS_DBG
|
|
DBG_DUMP("SCSIOP_OUT_WRLOADER 0x%08X 0x%08X\r\n", temp1, tSCSIDeviceResp.u16DataResidue);
|
|
#endif
|
|
|
|
}
|
|
}
|
|
break;
|
|
#endif
|
|
default: {
|
|
if(nvtdev_opened == 0) {
|
|
tCSW.u8Status = CSW_STATUS_CMD_FAIL;
|
|
} else {
|
|
int ret = -1;
|
|
unsigned int OutDataBuf=0, insize=0;
|
|
|
|
if (guiU2MsdcCheck_cb != NULL) {
|
|
ret = guiU2MsdcCheck_cb((unsigned int)ptcbw, (unsigned int *) &OutDataBuf, (unsigned int *)&insize);
|
|
} else {
|
|
ret = -1;
|
|
}
|
|
|
|
if(ret == 0) {
|
|
|
|
if (ptcbw->CB0_cblen_lun_flag & CBW_FLAG_IN) {
|
|
tSCSIDeviceResp.u32IOAddr = OutDataBuf;
|
|
tSCSIDeviceResp.u8Flags = CBW_FLAG_IN;
|
|
tSCSIDeviceResp.u8MemIndex = CARD_INDEX_FSM_SS;
|
|
tSCSIDeviceResp.u16DataResidue = insize;
|
|
|
|
} else {
|
|
tSCSIDeviceResp.u32IOAddr = OutDataBuf;
|
|
tSCSIDeviceResp.u8Flags = CBW_FLAG_OUT;
|
|
tSCSIDeviceResp.u8MemIndex = CARD_INDEX_FSM_SS;
|
|
tSCSIDeviceResp.u16DataResidue = ptcbw->u32DataTransferLength;
|
|
}
|
|
|
|
trigger_done_cb = 1;
|
|
} else {
|
|
return ret;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
_THUMB2 void fLib_USB_Update_FW(void)
|
|
{
|
|
debug_msg("USBFW UPDATE\r\n");
|
|
|
|
vUsbInit();
|
|
|
|
while (1) {
|
|
|
|
vUsbIsr2();
|
|
|
|
if(usbrom_exit > 1) {
|
|
//mdelay(300); //make sure that pc recevie scsi status
|
|
timer_delay(300000);
|
|
vUsbUnplug();
|
|
timer_delay(300000);
|
|
//mdelay(300); //make sure that pc recevie usb plug-out single
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
usbrom_exit = 0;
|
|
|
|
}
|
|
|