📄 ide.c
字号:
}
}
case TEST_UNIT_READY:
case VERIFY_10:
case FORMAT_UNIT:
{
// relinquish control of the bulk buffer occupied by the CBW
OUTPKTEND = 0x82;
if (dataTransferLen)
{
if (directionIn) failedIn(); else stallEP2OUT();
}
checkForMedia(1);
if (sensePtr == senseOk)
return(USBS_PASSED);
else
return(USBS_FAILED);
}
case REQUEST_SENSE:
{
// relinquish control of the bulk buffer occupied by the CBW
OUTPKTEND = 0x82;
waitForInBuffer();
AUTOPTRL2 = LSB(EP4FIFOBUF);
// First two bytes are 0x70 and 0x00
P_XAUTODAT2 = 0x70;
P_XAUTODAT2 = 0x00;
// Clear the rest of the buffer
memset16(EP4FIFOBUF+2, 0, 1);
P_XAUTODAT2 = senseArray[sensePtr][0];
AUTOPTRL2 = 7;
P_XAUTODAT2 = 18-8; // Length of data following this byte
AUTOPTRL2 = 12;
P_XAUTODAT2 = senseArray[sensePtr][1];
P_XAUTODAT2 = senseArray[sensePtr][2];
loadEP4BC(18);
sensePtr = senseOk;
return(USBS_PASSED);
}
case STOP_START_UNIT:
cmd = EP2FIFOBUF[CBW_DATA_START+4];
if ((cmd&3)==2) { bEject = 1; }
case PREVENT_ALLOW_MEDIUM_REMOVAL:
OUTPKTEND = 0x82;
return(USBS_PASSED);
case MODE_SENSE_06:
case MODE_SENSE_10:
{
BYTE pagenum;
pagenum = EP2FIFOBUF[CBW_DATA_START+2] & 0x3F; // identify page (see p.141 SCSI 2ed.)
OUTPKTEND = 0x82;
waitForInBuffer();
if((pagenum != 0x05) && (pagenum != 0x3F)
&& (pagenum != 0x01) && (pagenum != 0x08) && (pagenum != 0x1B))
{ // only respond to requests for certain pages (the mandatory ones plus page 5)
sensePtr = senseInvalidFieldInCDB;
failedIn();
return(USBS_FAILED);
}
memset16(EP4FIFOBUF, 0, 128/16);
AUTOPTRL2 = LSB(EP4FIFOBUF);
if (cmd == MODE_SENSE_10)
{
P_XAUTODAT2 = MSB(0); // Byte 0
if (pagenum == 0x3f)
P_XAUTODAT2 = LSB(8-2 + 12*4); // return 12 bytes for each page (byte 1)
else
P_XAUTODAT2 = LSB(8-2 + 12*1); // return 12 bytes for each page (byte 1)
P_XAUTODAT2 = 0; // Media type (return 0. Seems to be ignored by the host)
#ifndef NO_WP
P_XAUTODAT2 = (bWriteProtectEnable && !NAND_WP_SWITCH) ? 0x80 : 0; // Copy WP bit to the header (byte 3)
#else
P_XAUTODAT2 = 0;
#endif
AUTOPTRL2 = LSB(EP4FIFOBUF) + 8; // The rest of the header is zeroes. Start the pages at byte 8.
}
else
{
if (pagenum == 0x3f)
P_XAUTODAT2 = LSB(4-1 + 12*4); // Header is 4 bytes long, data from each page is 12 bytes.
else
P_XAUTODAT2 = LSB(4-1 + 12*1);
P_XAUTODAT2 = 0; // Next byte is 00
#ifndef NO_WP
P_XAUTODAT2 = (bWriteProtectEnable && !NAND_WP_SWITCH) ? 0x80 : 0; // Copy WP bit to the header (byte 2)
#else
P_XAUTODAT2 = 0;
#endif
AUTOPTRL2 = LSB(EP4FIFOBUF) + 4;
}
if((pagenum == 0x05) || (pagenum == 0x3F))
{
P_XAUTODAT2 = 5; // fill out the page num - fields are all 0x0
P_XAUTODAT2 = 12-2; // set individual Page Length -- return 12 for all commands
if(EZUSB_HIGHSPEED())
{
P_XAUTODAT2 = 0xFF; // HS Transfer Rate (MSB) (field limited to 65Mb/Sec)
P_XAUTODAT2 = 0xFF; // HS Transfer Rate (LSB)
}
else
{
P_XAUTODAT2 = 0x2E; // FS Transfer Rate (MSB) (12Mb/Sec)
P_XAUTODAT2 = 0xE0; // FS Transfer Rate (LSB)
}
P_XAUTODAT2 = 0x20; // #Heads
P_XAUTODAT2 = 0x10; // #SectorsPerTrack
P_XAUTODAT2 = (NAND_ATA_SECTOR_SIZE >> 8) & 0xff; // Data Bytes per sector (truncated)
P_XAUTODAT2 = (NAND_ATA_SECTOR_SIZE >> 0) & 0xff; // Data Bytes per sector
P_XAUTODAT2 = 0xff;
P_XAUTODAT2 = 0xff;
P_XAUTODAT2 = 0;
P_XAUTODAT2 = 0;
}
if(pagenum == 0x1B || pagenum == 0x3f)
{
P_XAUTODAT2 = 0x1b; // fill out the page num
P_XAUTODAT2 = 12-2; // set individual Page Length -- return 12 for all commands
P_XAUTODAT2 = 0;
P_XAUTODAT2 = 0x01; // set TLUN = 1 for page 0x1B
AUTOPTRL2 += 8; // 8 zeroes too.
}
if(pagenum == 0x1 || pagenum == 0x3f)
{
P_XAUTODAT2 = 0x1; // fill out the page num
P_XAUTODAT2 = 12-2; // set individual Page Length -- return 12 for all commands
AUTOPTRL2 += 10; // 10 zeroes too.
}
if(pagenum == 0x8 || pagenum == 0x3f)
{
P_XAUTODAT2 = 0x8; // fill out the page num
P_XAUTODAT2 = 12-2; // set individual Page Length -- return 12 for all commands
AUTOPTRL2 += 10; // 10 zeroes too.
}
loadEP4BC(AUTOPTRL2);
sensePtr = senseOk;
return(USBS_PASSED);
} // end case
///// OUT commmand
///////////////////////////////////////////////////////////
// Spoofed commands
case MODE_SELECT_06: // Note that these are in BOTH the read and write areas in case they are sent with no data
case MODE_SELECT_10:
{
// relinquish control of the bulk buffer occupied by the CBW
OUTPKTEND = 0x82;
loadEP2BC();
dataTransferLen=0;
checkForMedia(1);
if (sensePtr == senseOk)
return(USBS_PASSED);
else
return(USBS_FAILED);
}
default:
{
// relinquish control of the bulk buffer occupied by the CBW
OUTPKTEND = 0x82;
sensePtr = senseInvalidOpcode;
if (directionIn)
failedIn();
else
stallEP2OUT();
return(USBS_FAILED);
}
}
}
/////////////////////////////////////////////////////////////////////////////////
// Wait for IN buffer available from the Host
//////////////////////////////////////////////////////////////////////////////////
void waitForInBuffer()
{
while((P_EP4CS & bmEPFULL)); // Wait for an available buffer from the host
}
/////////////////////////////////////////////////////////////////////////////////
//
// Called to manually send IN data to the host once the data has already been
// placed in EP4FIFOBUF. This routine is only called on the last packet sent to
// the host. If dataTransferLen is not 0, failedIN() will STALL the IN endpoint.
//
// Input:
// EP2FIFOBUF -- Contains LBA (Logical block address)
//
// Output:
// dataTransferLen -- Reduced by the amount of data sent
// bShortPacketSent -- Set if a short packet has been sent
//
//////////////////////////////////////////////////////////////////////////////////
void loadEP4BC(WORD dataLen)
{
WORD packetLen;
bit bPaddedPacket = 0;
packetLen = min((WORD)dataTransferLen, dataLen);
// July-12-05: Add support for USBCV
// When dataTransferLen==0 just return and ready to send CSW
if (packetLen==0) return;
if (packetLen || (SHORT_PACKET_BEFORE_STALL))
{
// pad the really short responses
if (dataTransferLen <= wPacketSize)
{
bPaddedPacket = 1;
EP4BCH = MSB(dataTransferLenLSW);
EP4BCL = LSB(dataTransferLenLSW);
}
else
{
EP4BCH = MSB(packetLen);
EP4BCL = LSB(packetLen);
}
dataTransferLen -= packetLen;
}
if (packetLen & (wPacketSize - 1))
bShortPacketSent = 1;
if (!bPaddedPacket)
failedIn(); // This doesn't set status, just STALLs the IN endpoint if needed.
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -