?? cmmd_atapi.c
字號:
LowCyl= hal_RegInByte(Ata_p->HalHndl,ATA_REG_CYLLOW); HighCyl= hal_RegInByte(Ata_p->HalHndl,ATA_REG_CYLHIGH); /* Command packet transfer.... check status must have BSY=0 DRQ-1 */ if((Status & (BSY_BIT_MASK | DRQ_BIT_MASK))!= DRQ_BIT_MASK) { Ata_p->LastExtendedErrorCode= 0x52; GetPktStatus(Ata_p,Cmd_p->Stat.PktStat); return TRUE; } /* Transfer the packet in PIO mode */ for(i = 0; i < Ata_p->Handles[Ata_p->DeviceSelected].PktSize; i++) { hal_RegOutWord(Ata_p->HalHndl, ((U16 *)Cmd_p->Pkt)[i]); } WAIT400NS; /* --------------- Transfer Loop--------------- */ *Cmd_p->BytesRW=0; Data_p =(U16*) Cmd_p->DataBuffer; if(WaitForBitPkt(Ata_p->HalHndl,ATA_REG_ALTSTAT,BSY_BIT_MASK,0)) { Ata_p->LastExtendedErrorCode= 0x54; GetPktStatus(Ata_p,Cmd_p->Stat.PktStat); Error= TRUE; break; } Status= hal_RegInByte(Ata_p->HalHndl,ATA_REG_STATUS); Reason= hal_RegInByte(Ata_p->HalHndl,ATA_REG_SECCOUNT); LowCyl= hal_RegInByte(Ata_p->HalHndl,ATA_REG_CYLLOW); HighCyl= hal_RegInByte(Ata_p->HalHndl,ATA_REG_CYLHIGH); if( (Status & (BSY_BIT_MASK | DRQ_BIT_MASK)) == 0) { /* end of transfer lets quit*/ Ata_p->LastExtendedErrorCode= 0x00; GetPktStatus(Ata_p,Cmd_p->Stat.PktStat); Error=FALSE; break; } if( (Status & (BSY_BIT_MASK | DRQ_BIT_MASK)) != DRQ_BIT_MASK) { Ata_p->LastExtendedErrorCode= 0x55; GetPktStatus(Ata_p,Cmd_p->Stat.PktStat); Error=TRUE; break; } if( (Reason & (TAG_BIT_MASK | REL_BIT_MASK)) || (Reason & CD_BIT_MASK)) { Ata_p->LastExtendedErrorCode= 0x5C; GetPktStatus(Ata_p,Cmd_p->Stat.PktStat); Error=TRUE; break; } if( (Reason & IO_BIT_MASK )==0) { /* Wrong direction, we expect a IO = 1 */ Ata_p->LastExtendedErrorCode= 0x5D; GetPktStatus(Ata_p,Cmd_p->Stat.PktStat); Error=TRUE; break; } /* Data Transfer Loop.... get the byte count and check for zero */ ByteCount= (HighCyl<<8) | LowCyl; if(ByteCount<1) { Ata_p->LastExtendedErrorCode= 0x60; GetPktStatus(Ata_p,Cmd_p->Stat.PktStat); Error=TRUE; break; } /* Data Transfer Loop.... Check for buffer overrun */ if((*Cmd_p->BytesRW)+ByteCount > Cmd_p->BufferSize ) { Ata_p->LastExtendedErrorCode= 0x59; GetPktStatus(Ata_p,Cmd_p->Stat.PktStat); Error=TRUE; break; } WordCount = ( ByteCount >> 1 ) + ( ByteCount & 0x0001 ); /* Data Transfer .... */ *Cmd_p->BytesRW+= (WordCount << 1); /* Data Transfer .... */ Error = hal_DmaDataBlock(Ata_p->HalHndl, Cmd_p->DevCtrl, Cmd_p->DevHead, Data_p, WordCount, Cmd_p->BufferSize, Cmd_p->BytesRW, TRUE, &CrcError); if (Error == FALSE) Data_p += WordCount; /* On CRC errors, we do a retry (up to max), not abort */ if (CrcError == TRUE) Error = FALSE; WAIT400NS; } /* End of transfer loop */ if(Error == FALSE) { Status= hal_RegInByte(Ata_p->HalHndl,ATA_REG_STATUS); Reason= hal_RegInByte(Ata_p->HalHndl,ATA_REG_SECCOUNT); LowCyl= hal_RegInByte(Ata_p->HalHndl,ATA_REG_CYLLOW); HighCyl= hal_RegInByte(Ata_p->HalHndl,ATA_REG_CYLHIGH); /* Final Status check */ if( Status & (BSY_BIT_MASK | DRQ_BIT_MASK | ERR_BIT_MASK)) { Ata_p->LastExtendedErrorCode= 0x58; GetPktStatus(Ata_p,Cmd_p->Stat.PktStat); return TRUE; } Ata_p->LastExtendedErrorCode= 0x00; } /*read the output registers and store them in the pkt status structure*/ GetPktStatus(Ata_p,Cmd_p->Stat.PktStat); return Error; } /************************************************************************Name: ata_packet_DmaOutDescription: executes a command with data transfer from the host to the device via DMA. The device is already selected, no parameters check is performed. Parameters: Two params: Ata_p : Pointer to the ATA control block Cmd_p : Pointer to a command structureReturn: TRUE: Extended error is set FALSE: No error ************************************************************************/BOOL ata_packet_DmaOut(ata_ControlBlock_t *Ata_p, ata_Cmd_t *Cmd_p){ DU8 Status,Reason,LowCyl,HighCyl; U32 TimeOut,i; BOOL Error=FALSE, CrcError = FALSE; U32 WordCount,ByteCount; U16 *Data_p; U8 Retries = 4; while ((Error==FALSE) && (Retries > 0)) { /* First we write the registers */ hal_RegOutByte(Ata_p->HalHndl,ATA_REG_FEATURE, Cmd_p->Feature); hal_RegOutByte(Ata_p->HalHndl,ATA_REG_SECCOUNT, Cmd_p->SecCount); hal_RegOutByte(Ata_p->HalHndl,ATA_REG_SECNUM, Cmd_p->SecNum); hal_RegOutByte(Ata_p->HalHndl,ATA_REG_CYLLOW, Cmd_p->CylLow); hal_RegOutByte(Ata_p->HalHndl,ATA_REG_CYLHIGH, Cmd_p->CylHigh); hal_RegOutByte(Ata_p->HalHndl,ATA_REG_DEVHEAD, Cmd_p->DevHead); if(WaitForBitPkt(Ata_p->HalHndl,ATA_REG_ALTSTAT,DRDY_BIT_MASK,DRDY_BIT_MASK)) { Ata_p->LastExtendedErrorCode= 0x5B; GetPktStatus(Ata_p,Cmd_p->Stat.PktStat); return TRUE; } /* Finally write the command */ hal_RegOutByte(Ata_p->HalHndl,ATA_REG_COMMAND, Cmd_p->CommandCode); WAIT400NS; /* Now Check the Status */ Status= hal_RegInByte(Ata_p->HalHndl,ATA_REG_ALTSTAT); /* Command packet transfer...*/ /* Check for protocol failures, the device should have BSY=1 now, but a number of strange things can happen: 1) the device may not set BSY=1 or DRQ=1 for a while 2) the device may go directly to DRQ status, 3) the device may reject the command (maybe is not really an ATAPI device or has some error) */ TimeOut= PACKET_TIMEOUT; while(TRUE) { if(Status & BSY_BIT_MASK) { break; /* BSY=1 that's OK! */ } else { if( Status & DRQ_BIT_MASK ) { break; /* BSY=0 & DRQ=1 That's OK */ } if( Status & ERR_BIT_MASK) { /* Error,that's not OK */ break; } } if(TimeOut==0) { /* Error */ break; } TimeOut--; Status= hal_RegInByte(Ata_p->HalHndl,ATA_REG_ALTSTAT); } /* Command packet transfer.... */ /* Poll Alternate Status for BSY=0 */ if(WaitForBitPkt(Ata_p->HalHndl,ATA_REG_ALTSTAT,BSY_BIT_MASK,0)) { Ata_p->LastExtendedErrorCode= 0x51; GetPktStatus(Ata_p,Cmd_p->Stat.PktStat); return TRUE; } /* Command packet transfer.... */ /* Check for protocol failures.. clear interrupts */ hal_ClearInterrupt(Ata_p->HalHndl); /* Command packet transfer.... Read the primary status register abd other ATAPI registers */ Status= hal_RegInByte(Ata_p->HalHndl,ATA_REG_STATUS); Reason= hal_RegInByte(Ata_p->HalHndl,ATA_REG_SECCOUNT); LowCyl= hal_RegInByte(Ata_p->HalHndl,ATA_REG_CYLLOW); HighCyl= hal_RegInByte(Ata_p->HalHndl,ATA_REG_CYLHIGH); /* Command packet transfer.... check status must have BSY=0 DRQ-1 */ if((Status & (BSY_BIT_MASK | DRQ_BIT_MASK))!= DRQ_BIT_MASK) { Ata_p->LastExtendedErrorCode= 0x52; GetPktStatus(Ata_p,Cmd_p->Stat.PktStat); return TRUE; } /* Transfer the packet - PIO mode */ for(i=0;i<Ata_p->Handles[Ata_p->DeviceSelected].PktSize;i++) { hal_RegOutWord(Ata_p->HalHndl,Cmd_p->Pkt[i]); } WAIT400NS; /* --------------- Transfer Loop--------------- */ *Cmd_p->BytesRW=0; Data_p =(U16*) Cmd_p->DataBuffer; if(WaitForBitPkt(Ata_p->HalHndl, ATA_REG_ALTSTAT, BSY_BIT_MASK, 0)) { Ata_p->LastExtendedErrorCode= 0x54; GetPktStatus(Ata_p,Cmd_p->Stat.PktStat); return TRUE; } Status= hal_RegInByte(Ata_p->HalHndl,ATA_REG_STATUS); Reason= hal_RegInByte(Ata_p->HalHndl,ATA_REG_SECCOUNT); LowCyl= hal_RegInByte(Ata_p->HalHndl,ATA_REG_CYLLOW); HighCyl= hal_RegInByte(Ata_p->HalHndl,ATA_REG_CYLHIGH); if( (Status & (BSY_BIT_MASK | DRQ_BIT_MASK)) == 0) { /* end of transfer lets quit*/ Ata_p->LastExtendedErrorCode= 0x00; GetPktStatus(Ata_p,Cmd_p->Stat.PktStat); Error=FALSE; break; } if( (Status & (BSY_BIT_MASK | DRQ_BIT_MASK)) != DRQ_BIT_MASK) { Ata_p->LastExtendedErrorCode= 0x55; GetPktStatus(Ata_p,Cmd_p->Stat.PktStat); Error=TRUE; break; } if( (Reason & (TAG_BIT_MASK | REL_BIT_MASK)) || (Reason & CD_BIT_MASK)) { Ata_p->LastExtendedErrorCode= 0x5C; GetPktStatus(Ata_p,Cmd_p->Stat.PktStat); Error=TRUE; break; } if( (Reason & IO_BIT_MASK )==0) { /* Wrong direction, we expect a IO = 1 */ Ata_p->LastExtendedErrorCode= 0x5D; GetPktStatus(Ata_p,Cmd_p->Stat.PktStat); Error=TRUE; break; } /* Data Transfer Loop.... get the byte count and check for zero */ ByteCount= (HighCyl<<8) | LowCyl; if(ByteCount<1) { Ata_p->LastExtendedErrorCode= 0x60; GetPktStatus(Ata_p,Cmd_p->Stat.PktStat); Error=TRUE; break; } /* Data Transfer Loop.... Check for buffer overrun */ if((*Cmd_p->BytesRW)+ByteCount > Cmd_p->BufferSize ) { Ata_p->LastExtendedErrorCode= 0x59; GetPktStatus(Ata_p,Cmd_p->Stat.PktStat); Error=TRUE; break; } WordCount = ( ByteCount >> 1 ) + ( ByteCount & 0x0001 ); /* Data Transfer .... */ Error = hal_DmaDataBlock(Ata_p->HalHndl, Cmd_p->DevCtrl, Cmd_p->DevHead, Data_p, WordCount, Cmd_p->BufferSize, Cmd_p->BytesRW, TRUE, &CrcError); if (Error == FALSE) { *Cmd_p->BytesRW+= (WordCount << 1); Data_p+=WordCount; } /* Retry on CRC error, not abort */ if (CrcError == TRUE) Error = FALSE; WAIT400NS; } if(Error == FALSE) { Status= hal_RegInByte(Ata_p->HalHndl,ATA_REG_STATUS); Reason= hal_RegInByte(Ata_p->HalHndl,ATA_REG_SECCOUNT); LowCyl= hal_RegInByte(Ata_p->HalHndl,ATA_REG_CYLLOW); HighCyl= hal_RegInByte(Ata_p->HalHndl,ATA_REG_CYLHIGH); /* Final Status check */ if( Status & (BSY_BIT_MASK | DRQ_BIT_MASK | ERR_BIT_MASK)) { Ata_p->LastExtendedErrorCode= 0x58; GetPktStatus(Ata_p,Cmd_p->Stat.PktStat); return TRUE; } Ata_p->LastExtendedErrorCode= 0x00; } /*read the output registers and store them in the pkt status structure*/ GetPktStatus(Ata_p,Cmd_p->Stat.PktStat); return Error; } /************************************************************************Name: GetPktStatusDescription: Retrieves the command block registers and store them in the structure previosly allocated Parameters: Two params: Ata_p : Pointer to the ATA control block Cmd_p : Pointer to a command status structure ************************************************************************/void GetPktStatus(ata_ControlBlock_t *Ata_p,STATAPI_PktStatus_t *Stat_p){ Stat_p->Status = hal_RegInByte(Ata_p->HalHndl,ATA_REG_STATUS); Stat_p->InterruptReason = hal_RegInByte(Ata_p->HalHndl,ATA_REG_SECCOUNT); Stat_p->Error = hal_RegInByte(Ata_p->HalHndl,ATA_REG_ERROR); }/*end of cmmd_ata.c --------------------------------------------------*/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -