📄 usbmass.c
字号:
DEV_WaitMS(ERROR_WAIT);
}
}
//#if UMO_ENABLE_MODESENSE
//if(ISERR(SCSI_ModeSense(0x3F,tBUF))){
// DEV_WaitMS(ERROR_WAIT);
//}
//#endif
for(i=0;i<2;i++)
{
DEV_WaitMS(TRY_WAIT);
if(rcscnt<READCAP_STALL_CNT_MAX){
res = SCSI_ReadCapacity(tBUF);
if(res==RES_ERR+1)rcscnt++;
if(ISERR(res)){
if(gDevAddr!=DEV_ReadReg(RH_DEV_ADDR)||0x5A!=DEV_ReadReg(RH_MASS_ADDR2)) return RES_ERR;
DEV_WaitMS(ERROR_WAIT);
}
}
DEV_WaitMS(TRY_WAIT);
if(ISOK(SCSI_TestUnit())) {
gLunFlag |= (1<<gLun);
break;
}
else {
if(gDevAddr!=DEV_ReadReg(RH_DEV_ADDR)||0x5A!=DEV_ReadReg(RH_MASS_ADDR2)) return RES_ERR;
DEV_WaitMS(ERROR_WAIT);
}
}
}
for(i=0,gLunFlag=0;i<=512;i++)
{
for(gLun=0;gLun<=gMaxLun;gLun++)
{
if(gLunMask&(1<<gLun))continue; //skip non-generic storage
if((gLunFlag&(1<<gLun))==0)
{
DEV_WaitMS(TRY_WAIT);
if(rcscnt<READCAP_STALL_CNT_MAX){
res = SCSI_ReadCapacity(tBUF);
if(res==RES_ERR+1)rcscnt++;
if(ISERR(res)){
if(gDevAddr!=DEV_ReadReg(RH_DEV_ADDR)||0x5A!=DEV_ReadReg(RH_MASS_ADDR2)) return RES_ERR;
DEV_WaitMS(ERROR_WAIT);
continue;
}
}
DEV_WaitMS(TRY_WAIT);
if(ISERR(SCSI_TestUnit())){
if(gDevAddr!=DEV_ReadReg(RH_DEV_ADDR)||0x5A!=DEV_ReadReg(RH_MASS_ADDR2)) return RES_ERR;
DEV_WaitMS(ERROR_WAIT);
continue;
}
gLunFlag |= (1<<gLun);
}
}
if(gLunFlag>0) break;
}
//select first existing LUN
gLun=0;
for(gLun=0;gLun<=gMaxLun;gLun++){
if((gLunFlag&(1<<gLun))>0) break;
}
if(gLun>gMaxLun){
if(maxTryCnt-->0)goto IML_RETRY;
gLun=0;//if no media exist...select Lun-0
return RES_ERR;
}
///pl
if(gLunSet & 0x100){
gLunSet &= 0x0ff;
gLun = gLunSet;
}
for(i=0;i<3;i++){
DEV_WaitMS(10);
if(ISERR(SCSI_TestUnit())){
if(gDevAddr!=DEV_ReadReg(RH_DEV_ADDR)||0x5A!=DEV_ReadReg(RH_MASS_ADDR2)) return RES_ERR;
DEV_WaitMS(ERROR_WAIT);
//return RES_ERR;
}
}
if(ISERR(UM_SetLun(gLun, tBUF))){
if(maxTryCnt-->0)goto IML_RETRY;
gLun=0;//if no media exist...select Lun-0
return RES_ERR;
}
/* if(ISERR(UBI9021_read_sector_lba((short*)tBUF,0,1)==0)){
if(maxTryCnt==0)return RES_ERR;
maxTryCnt--;
rcscnt=0;
goto IML_RETRY;
}*/
#if (UMO_READ_USB1_PACKET_UNIT==1)
gUsbReadUnit = (gUsbVer==USB_VER_1X)?64:512;
#else
gUsbReadUnit = 512;
#endif
return RES_OK+gMaxLun;
}
U8 ubi9021_send_read_write_cmd(int stSec, int secCnt, U8 isread)//isread=1:read,0:write
{
/* if(stSec+secCnt>gTotSecCnt){
return RES_ERR;
}*/
if(gDevAddr!=DEV_ReadReg(RH_DEV_ADDR)||0x5A!=DEV_ReadReg(RH_MASS_ADDR2)){
if(gDevAddr!=DEV_ReadReg(RH_DEV_ADDR)||0x5A!=DEV_ReadReg(RH_MASS_ADDR2)){
//EPRINTF((" error gDevAddr %d reg %d reg2 %d \n", gDevAddr, DEV_ReadReg(RH_DEV_ADDR), DEV_ReadReg(RH_MASS_ADDR2) ));
DEV_ResetChip(RST9021_FULL_RESET);
return RES_ERR;
}
}
gCBW[8]=0,gCBW[9]=(U8)(secCnt<<1),gCBW[10]=(U8)(secCnt>>7),gCBW[11]=(U8)(secCnt>>15);//byte size
gCBW[12] = (isread)?0x80:0;// 0x80=bulk-in, 0x00=bulk-out
MemFill(gCBW+13,0,31-13);
gCBW[13] = gLun;//LUN
gCBW[14] = (gIFSC==6)?0x0A:0x0C;//CBW length
gCBW[15] = (isread)?SCSI_CMD_READ10:SCSI_CMD_WRITE10;
gCBW[17] = (U8)((stSec)>>24),gCBW[18]=(U8)((stSec)>>16),gCBW[19]=(U8)((stSec)>>8),gCBW[20]=(U8)(stSec);//page address
gCBW[22] = (U8)((secCnt)>>8),gCBW[23]=(U8)(secCnt);//page count
SCSI_SendCBW();
return RES_OK;
}
/******************************************************************************
* gCBW[18]~gCBW[30]俊 CSW甫 佬绢甸烙.
*
* NOTE:
* CSW error --> do REQUEST_SENSE
*
* RETURN:
* RES_ERR: CSW error
* RES_OK: CSW ok
******************************************************************************/
U8 SCSI_GetCSW(void)
{
U8 res;
UH_SET_FIFO_SZ_EACH(0,13);
UH_FIFO_ROLLBACK_IN();
UH_IRQ_EN(UH_IRQ_READ_READY);
UH_Trigger(gEPIN);
//if(DEV_WaitForIrq(UH_IRQ_READ_READY)==0) return RES_ERR_SCSI_CSW;
res = DEV_WaitForIrq(UH_IRQ_READ_READY);
if(res==0||res==UH_IRQ_FAKE_STALL) return RES_ERR;
res = DEV_ReadRegMultiAndDiscard(RH_USB_HOST_BASE_ADDR,13);
if(0!=res){
SCSI_RequestSense();
return RES_ERR;
}
return RES_OK;
}
void UBI9021_FlushSectorRead(void)
{
//U8 i;
gSecAddr=-1;//flag for not-in-seq-read state.
UH_FIFO_ROLLBACK_IN();
while(gSecCnt>0)
{
gSecCnt--;
UH_IRQ_EN(UH_IRQ_READ_READY);
UH_Trigger(gEPIN);
if(DEV_WaitForIrq(UH_IRQ_READ_READY)==0) return;
UH_FIFO_ROLLBACK_IN();
}
gSecCnt=0;
SCSI_GetCSW();
return;
}
/******************************************************************************
* read from sequential sectors
* INPUT:
* - sec : Start Sector Address
* - secCnt: sequential sector count
* RETURN:
* RES_OK / RES_ERR
******************************************************************************/
int UBI9021_read_sector_lba(short *buf, int stSec, int secCnt)
{
U8 res;
int bytSize=0;
extern int enable_debug;
if(0==secCnt||0<gSecCnt) return 0;
gSecAddr = stSec;
gSecCnt = secCnt;
//printf("read start.\n");
if(ISERR(ubi9021_send_read_write_cmd(gSecAddr, gSecCnt, 1))) return 0; //isread=1:read
if(0==DEV_WaitForIrq(UH_IRQ_USB_PKT_DONE)) return bytSize;
//printf("cmd ok.\n");
if(0x04CB==gVID && 0x012A==gPID) DEV_WaitMS(3); //for finepix f610
UH_SET_FIFO_SZ(gUsbReadUnit);
UH_FIFO_ROLLBACK_IN();
gUsbTrgCnt = (gSecCnt*(512/gUsbReadUnit))+1;
while(gUsbTrgCnt)
{
UH_SET_FIFO_SZ(gUsbReadUnit);
UH_FIFO_ROLLBACK_IN();
UH_IRQ_EN(UH_IRQ_READ_READY);
UH_Trigger(gEPIN);
gUsbTrgCnt--;
res = DEV_WaitForIrqV(UH_IRQ_READ_READY);
if(res==0) return bytSize;
if(res==UH_IRQ_FAKE_STALL){
gSecCnt = gUsbTrgCnt = 0;
SCSI_GetCSW();
return bytSize;
}
DEV_ReadRegMulti(RH_USB_HOST_BASE_ADDR,gUsbReadUnit,(U8*)buf);
//printf("read unit ok.\n");
buf += (gUsbReadUnit/2);// coz buf is short ptr
bytSize += gUsbReadUnit;
if(0==(bytSize%512)){ //sector boundary
gSecAddr++;
gSecCnt--;
}
if(1==gUsbTrgCnt){
gUsbTrgCnt = 0;
gSecCnt = 0;
if(ISERR(SCSI_GetCSW())) return 0;
//while(1)printf("RUN11 OK.\n");
//printf("read ok.\n");
return bytSize;
}
}
return bytSize;
}
/******************************************************************************
* write to sequential sectors
* INPUT:
* - sec : Start Sector Address
* - secCnt: sequential sector count
* RETURN:
* RES_OK / RES_ERR
******************************************************************************/
U8 SCSI_WriteSectors( U8* buf,U32 stSec, U32 secCnt)
{
if(secCnt==0) return 0;
if(gSecCnt>0){
UBI9021_FlushSectorRead();
}
if(ISERR(SCSI_TestUnit()))
{
if(gDevAddr!=DEV_ReadReg(RH_DEV_ADDR)||0x5A!=DEV_ReadReg(RH_MASS_ADDR2))
return RES_ERR;
DEV_WaitMS(ERROR_WAIT);
}
if(ISERR(ubi9021_send_read_write_cmd(stSec, gSecCnt, 0))) return 0; //isread=0:write
if(DEV_WaitForIrq(UH_IRQ_SEND_READ_WRITE_CMD)==0) return RES_ERR;
UH_SET_FIFO_SZ_EACH(2,0);
while(secCnt--)
{
DEV_WriteRegMulti(RH_USB_HOST_BASE_ADDR,512,buf);
UH_IRQ_EN(UH_IRQ_WRITE_READY);
UH_Trigger(gEPOUT);
if(DEV_WaitForIrq(UH_IRQ_WRITE_READY)==0) return RES_ERR;
buf+=512;
}
return SCSI_GetCSW();
}
int USB_write_sector_lba(U8 *dest,U32 lba, U32 nblocks)
{
int ret;
ret=SCSI_WriteSectors(dest,lba,nblocks);
return ret;
}
int USB_boot_setup()
{
unsigned char gltmpbuff[64];
//int glcf_hidden_sectors;
int i=1;
UBI9021_read_sector_lba((short *)gltmpbuff,1253,1);
UBI9021_read_sector_lba((short *)gltmpbuff,1529,1);
do
{
UBI9021_read_sector_lba((short *)gltmpbuff,i,1);
i++;
}while(i<50000);
/*if(((gltmpbuff[0x0] == 0xEB) &&(gltmpbuff[0x2] == 0x90))||(gltmpbuff[0x0] == 0xE9)) {
glcf_hidden_sectors = 0;
} else {
glcf_hidden_sectors = (int)((gltmpbuff[446+8])|(gltmpbuff[446+9]<<8)|(gltmpbuff[446+10]<<16)|(gltmpbuff[446+11]<<24));
}*/
// PPRINTF((" glcf_hidden_sectors =%d ", glcf_hidden_sectors));
MemFill(gltmpbuff,0,64);
USB_write_sector_lba(gltmpbuff, 253,1);
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -