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;
}