?? cmmd_atapi.c
字號:
/************************************************************************Source file name : cmmd_atapi.cDescription: Implementation of the ATA Command Interface intermediate module following the API Design Document v0.9.0 of the ATAPI driver. COPYRIGHT (C) STMicroelectronics 2000************************************************************************//*Includes-------------------------------------------------------------*/#include <string.h>#include "stlite.h"#include "statapi.h"#include "hal_atapi.h"#include "ata.h"/*Private Types--------------------------------------------------------*//*Private Constants----------------------------------------------------*//*Private Variables----------------------------------------------------*//*Private Macros-------------------------------------------------------*/#define PACKET_TIMEOUT 0x00100000#define TAG_BIT_MASK 0xF8#define REL_BIT_MASK 0x04#define IO_BIT_MASK 0x02 #define CD_BIT_MASK 0x01#define SERV_BIT_MASK 0x10#define PACKET_INT_TIMEOUT 500000/*Private functions prototypes-----------------------------------------*/static void GetPktStatus(ata_ControlBlock_t *Ata_p,STATAPI_PktStatus_t *Stat_p);/*Functions------------------------------------------------------------*//************************************************************************Name: ata_packet_NoDataDescription: executes a non data packet. The device is already selected no parameters check is performed. We totally trust on the caller 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_NoData(ata_ControlBlock_t *Ata_p, ata_Cmd_t *Cmd_p){ DU8 Status,Reason,LowCyl,HighCyl; U32 TimeOut,i; /* 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(WaitForBit(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(WaitForBit(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 */ for(i=0;i<Ata_p->Handles[Ata_p->DeviceSelected].PktSize;i++) { hal_RegOutWord(Ata_p->HalHndl,Cmd_p->Pkt[i]); } #if ATAPI_USING_INTERRUPTS if(hal_AwaitInt(Ata_p->HalHndl,PACKET_INT_TIMEOUT)) { Ata_p->LastExtendedErrorCode= 0x53; GetPktStatus(Ata_p,Cmd_p->Stat.PktStat); return TRUE; } #else WAIT400NS; 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; } #endif /* ATAPI_USING_INTERRUPTS */ Status= hal_RegInByte(Ata_p->HalHndl,ATA_REG_STATUS); Reason= hal_RegInByte(Ata_p->HalHndl,ATA_REG_SECCOUNT); if( (Status & (BSY_BIT_MASK | DRQ_BIT_MASK |SERV_BIT_MASK| ERR_BIT_MASK)) | (Reason & REL_BIT_MASK)) { Ata_p->LastExtendedErrorCode= 0x55; GetPktStatus(Ata_p,Cmd_p->Stat.PktStat); return TRUE; } GetPktStatus(Ata_p,Cmd_p->Stat.PktStat); Ata_p->LastExtendedErrorCode= 0x00; return FALSE;}/************************************************************************Name: ata_packet_PioInDescription: executes a command with data transfer from the device to the host via PIO. The device is already selected, no parameters check is performed. We totally trust on the caller 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_PioIn(ata_ControlBlock_t *Ata_p, ata_Cmd_t *Cmd_p){ DU8 Status,Reason,LowCyl,HighCyl; U32 TimeOut,i; BOOL Error=FALSE; U32 WordCount,ByteCount; U16 *Data_p; /* 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 and 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 */ 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; while (Error==FALSE) { #if ATAPI_USING_INTERRUPTS if(hal_AwaitInt(Ata_p->HalHndl,PACKET_INT_TIMEOUT)) { Ata_p->LastExtendedErrorCode= 0x53; GetPktStatus(Ata_p,Cmd_p->Stat.PktStat); Error= TRUE; break; } #else WAIT400NS; 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; } #endif /* ATAPI_USING_INTERRUPTS */ 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; }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -