BYTE MSDReadHandler(void) { static BYTE MSDReadState = MSD_READ10_WAIT; switch(MSDReadState) { case MSD_READ10_WAIT: LBA.v[3]=gblCBW.CBWCB[2]; LBA.v[2]=gblCBW.CBWCB[3]; LBA.v[1]=gblCBW.CBWCB[4]; LBA.v[0]=gblCBW.CBWCB[5]; TransferLength.v[1]=gblCBW.CBWCB[7]; TransferLength.v[0]=gblCBW.CBWCB[8]; msd_csw.bCSWStatus=0x0; msd_csw.dCSWDataResidue=0x0; MSDReadState = MSD_READ10_BLOCK; //Fall through to MSD_READ_BLOCK case MSD_READ10_BLOCK: if(TransferLength.Val == 0) { MSDReadState = MSD_READ10_WAIT; break; } TransferLength.Val--; // we have read 1 LBA MSDReadState = MSD_READ10_SECTOR; //Fall through to MSD_READ10_SECTOR case MSD_READ10_SECTOR: //if the old data isn't completely sent yet if(USBHandleBusy(USBMSDInHandle) != 0) { break; } if(LUNSectorRead(LBA.Val, (BYTE*)&msd_buffer[0]) != TRUE) { msd_csw.bCSWStatus=0x01; // Error 0x01 Refer page#18 // of BOT specifications /* Don't read any more data*/ msd_csw.dCSWDataResidue=0x0; MSD_State = MSD_DATA_IN; break; } LBA.Val++; msd_csw.bCSWStatus=0x00; // success msd_csw.dCSWDataResidue=BLOCKLEN_512;//in order to send the //512 bytes of data read ptrNextData=(BYTE *)&msd_buffer[0]; MSDReadState = MSD_READ10_TX_SECTOR; //Fall through to MSD_READ10_TX_SECTOR case MSD_READ10_TX_SECTOR: if(msd_csw.dCSWDataResidue == 0) { MSDReadState = MSD_READ10_BLOCK; break; } MSDReadState = MSD_READ10_TX_PACKET; //Fall through to MSD_READ10_TX_PACKET case MSD_READ10_TX_PACKET: if ((msd_csw.bCSWStatus==0x00)&&(msd_csw.dCSWDataResidue>=MSD_IN_EP_SIZE)) { /* Write next chunk of data to EP Buffer and send */ if(USBHandleBusy(USBMSDInHandle)) { break; } USBMSDInHandle = USBTxOnePacket(MSD_DATA_IN_EP,ptrNextData,MSD_IN_EP_SIZE); MSDReadState = MSD_READ10_TX_SECTOR; gblCBW.dCBWDataTransferLength-= MSD_IN_EP_SIZE; msd_csw.dCSWDataResidue-=MSD_IN_EP_SIZE; ptrNextData+=MSD_IN_EP_SIZE; } break; } return MSDReadState; }
BYTE MSDReadHandler(void) { switch(MSDReadState) { case MSD_READ10_WAIT: LBA.v[3]=gblCBW.CBWCB[2]; LBA.v[2]=gblCBW.CBWCB[3]; LBA.v[1]=gblCBW.CBWCB[4]; LBA.v[0]=gblCBW.CBWCB[5]; TransferLength.v[1]=gblCBW.CBWCB[7]; TransferLength.v[0]=gblCBW.CBWCB[8]; //Assume success initially, msd_csw.bCSWStatus will get set to 0x01 //or 0x02 later if an error is detected during the actual read sequence. msd_csw.bCSWStatus=0x0; msd_csw.dCSWDataResidue=0x0; MSDReadState = MSD_READ10_BLOCK; //Fall through to MSD_READ_BLOCK case MSD_READ10_BLOCK: if(TransferLength.Val == 0) { MSDReadState = MSD_READ10_WAIT; break; } TransferLength.Val--; // we have read 1 LBA MSDReadState = MSD_READ10_SECTOR; //Fall through to MSD_READ10_SECTOR case MSD_READ10_SECTOR: //if the old data isn't completely sent yet if(USBHandleBusy(USBMSDInHandle) != 0) { break; } //Try to read a sector worth of data from the media, but check for //possible errors. if(LUNSectorRead(LBA.Val, (BYTE*)&msd_buffer[0]) != TRUE) { if(MSDRetryAttempt < MSD_FAILED_READ_MAX_ATTEMPTS) { MSDRetryAttempt++; break; } else { //Too many consecutive failed reads have occurred. Need to //give up and abandon the sector read attempt; something must //be wrong and we don't want to get stuck in an infinite loop. //Need to indicate to the host that a device error occurred. //However, we can't send the CSW immediately, since the host //still expects to receive sector read data on the IN endpoint //first. Therefore, we still send dummy bytes, before //we send the CSW with the failed status in it. msd_csw.bCSWStatus=0x01; // Error 0x01 Refer page#18 // of BOT specifications //Set error status sense keys, so the host can check them later //to determine how to proceed. gblSenseData[LUN_INDEX].SenseKey=S_MEDIUM_ERROR; gblSenseData[LUN_INDEX].ASC=ASC_NO_ADDITIONAL_SENSE_INFORMATION; gblSenseData[LUN_INDEX].ASCQ=ASCQ_NO_ADDITIONAL_SENSE_INFORMATION; } }//else we successfully read a sector worth of data from our media LBA.Val++; msd_csw.dCSWDataResidue=BLOCKLEN_512;//in order to send the //512 bytes of data read ptrNextData=(BYTE *)&msd_buffer[0]; MSDReadState = MSD_READ10_TX_SECTOR; //Fall through to MSD_READ10_TX_SECTOR case MSD_READ10_TX_SECTOR: if(msd_csw.dCSWDataResidue == 0) { MSDReadState = MSD_READ10_BLOCK; break; } MSDReadState = MSD_READ10_TX_PACKET; //Fall through to MSD_READ10_TX_PACKET case MSD_READ10_TX_PACKET: /* Write next chunk of data to EP Buffer and send */ //Make sure the endpoint is available before using it. if(USBHandleBusy(USBMSDInHandle)) { break; } //Prepare the USB module to send an IN transaction worth of data to the host. USBMSDInHandle = USBTxOnePacket(MSD_DATA_IN_EP,ptrNextData,MSD_IN_EP_SIZE); MSDReadState = MSD_READ10_TX_SECTOR; gblCBW.dCBWDataTransferLength-= MSD_IN_EP_SIZE; msd_csw.dCSWDataResidue-=MSD_IN_EP_SIZE; ptrNextData+=MSD_IN_EP_SIZE; break; default: //Illegal condition, should never occur. In the event that it ever //did occur anyway, try to notify the host of the error. msd_csw.bCSWStatus=0x02; //indicate "Phase Error" //Advance state machine MSDReadState = MSD_READ10_WAIT; } return MSDReadState; }