?? cmmd_ata.c
字號:
break; } /* All sectors have been read without error, exit */ Ata_p->LastExtendedErrorCode= 0x00; break; } #if ATAPI_USING_INTERRUPTS if(hal_AwaitInt(Ata_p->HalHndl,INT_TIMEOUT)) { STTBX_Print(("no interrupt 0x44\n")); Ata_p->LastExtendedErrorCode= 0x44; Error= TRUE; break; } #else WAIT400NS; if(WaitForBit(Ata_p->HalHndl,ATA_REG_ALTSTAT,BSY_BIT_MASK,0)) { Ata_p->LastExtendedErrorCode= 0x45; Error= TRUE; break; }#endif /* ATAPI_USING_INTERRUPTS */ status = hal_RegInByte(Ata_p->HalHndl, ATA_REG_STATUS); /* So was there any error? */ if ((status & (ERR_BIT_MASK | DF_BIT_MASK)) != 0) { STTBX_Print(("DF or ERR; 0x%02x; 0x41\n", status)); GetCmdStatus(Ata_p, Cmd_p->Stat.CmdStat); Ata_p->LastExtendedErrorCode = 0x41; Error = TRUE; break; } if (status & (DRQ_BIT_MASK) == 0) { STTBX_Print(("DRQ bit empty; 0x%02x; 0x42\n", status)); Ata_p->LastExtendedErrorCode = 0x42; Error = TRUE; break; } /*End of write loop*/ } /*read the output registers and store them in the cmd status structure*/ GetCmdStatus(Ata_p, Cmd_p->Stat.CmdStat); return Error; } /************************************************************************Name: ata_cmd_DmaInDescription: Executes a command with data transfer from the host to the device via DMA. The device and mode are already selected, no parameter checks are performed. Buffers are assumed to be 16-bit aligned (for DMA).Parameters: 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_cmd_DmaIn(ata_ControlBlock_t *Ata_p, ata_Cmd_t *Cmd_p){ volatile U8 status; BOOL Error=FALSE, CrcError = FALSE; U16* Data_p; while ((Error == FALSE) && (Cmd_p->SecCount > 0)) { *Cmd_p->BytesRW = 0; Data_p= (U16*) Cmd_p->DataBuffer; /* First we write the registers */ ata_cmd_WriteRegs(Ata_p, Cmd_p); if(WaitForBit(Ata_p->HalHndl,ATA_REG_ALTSTAT,DRDY_BIT_MASK,DRDY_BIT_MASK)) { Ata_p->LastExtendedErrorCode= 0x36; GetCmdStatus(Ata_p,Cmd_p->Stat.CmdStat); 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_STATUS); /* Checking if Busy =0 and DRQ=1 in order to enter into the transfer phase */ if ((status & (BSY_BIT_MASK | DRQ_BIT_MASK)) != 0) { /* Read one DRQ sector*/ Error = hal_DmaDataBlock(Ata_p->HalHndl, Cmd_p->DevCtrl, Cmd_p->DevHead, Data_p, Cmd_p->MultiCnt * SECTOR_WSIZE, Cmd_p->BufferSize, Cmd_p->BytesRW, TRUE, &CrcError); if (Error == FALSE) { Data_p += (Cmd_p->MultiCnt * SECTOR_WSIZE); Cmd_p->SecCount = Cmd_p->SecCount - Cmd_p->MultiCnt; } /* Do any tidying up required */ hal_AfterDma(Ata_p->HalHndl); } if (CrcError == TRUE) { Ata_p->LastExtendedErrorCode = EXTERROR_CRCERROR; Error = TRUE; break; } /* Now check the status*/ status = hal_RegInByte(Ata_p->HalHndl,ATA_REG_STATUS); /* So was there any error? */ if ((status & (BSY_BIT_MASK | ERR_BIT_MASK | DF_BIT_MASK))!= 0) { Ata_p->LastExtendedErrorCode= 0x31; Error = TRUE; break; } if ((status & (DRDY_BIT_MASK)) == 0) { Ata_p->LastExtendedErrorCode= 0x32; Error = TRUE; break; } if(Cmd_p->SecCount < 1) { /* Since the drive has transferred all of the requested sectors without error, the drive should not have BUSY, DEVICE FAULT, DATA REQUEST or ERROR active now.*/ WAIT400NS; status = hal_RegInByte(Ata_p->HalHndl,ATA_REG_STATUS); if (status & (BSY_BIT_MASK | ERR_BIT_MASK | DF_BIT_MASK | DRQ_BIT_MASK)) { Ata_p->LastExtendedErrorCode= 0x33; Error= TRUE; break; } /* All sectors have been read without error, exit */ Ata_p->LastExtendedErrorCode= 0x00; break; } /*End of read loop*/ } /*read the output registers and store them in the cmd status structure*/ GetCmdStatus(Ata_p, Cmd_p->Stat.CmdStat); return Error; } /************************************************************************Name: ata_cmd_DmaOutDescription: Executes a command with data transfer from the host to the device via DMA. The device and mode are already selected, no parameter checks are performed. Buffers are assumed to be 16-bit aligned (for DMA).Parameters: 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_cmd_DmaOut(ata_ControlBlock_t *Ata_p, ata_Cmd_t *Cmd_p){ volatile U8 status; BOOL Error=FALSE, CrcError = FALSE; U16* Data_p; while ((Error == FALSE) && (Cmd_p->SecCount > 0)) { *Cmd_p->BytesRW =0; Data_p= (U16*) Cmd_p->DataBuffer; /* First we write the registers */ ata_cmd_WriteRegs(Ata_p, Cmd_p); intcount = 0; if(WaitForBit(Ata_p->HalHndl, ATA_REG_ALTSTAT, DRDY_BIT_MASK | BSY_BIT_MASK, DRDY_BIT_MASK)) { Ata_p->LastExtendedErrorCode= 0x46; GetCmdStatus(Ata_p,Cmd_p->Stat.CmdStat); return TRUE; } /* Write the command */ hal_RegOutByte(Ata_p->HalHndl,ATA_REG_COMMAND, Cmd_p->CommandCode); WAIT400NS; /* Wait for BSY == 0 and DRQ == 1 */ if (WaitForBit(Ata_p->HalHndl, ATA_REG_STATUS, BSY_BIT_MASK | DRQ_BIT_MASK, DRQ_BIT_MASK)) { /* Busy signal, or drive not ready for data */ Ata_p->LastExtendedErrorCode= 0x45; return TRUE; } STTBX_Print(("DMA writing\n")); /* Transfering Data: Write Loop*/ status = hal_RegInByte(Ata_p->HalHndl, ATA_REG_STATUS); /* Check for BSY xor DRQ to continue */ if ((status & (DRQ_BIT_MASK | BSY_BIT_MASK)) != 0) { /* Write sector(s) */ Error = hal_DmaDataBlock(Ata_p->HalHndl, Cmd_p->DevCtrl, Cmd_p->DevHead, Data_p, Cmd_p->MultiCnt * SECTOR_WSIZE, Cmd_p->BufferSize, Cmd_p->BytesRW, FALSE, &CrcError); if (Error == FALSE) { Data_p += (Cmd_p->MultiCnt * SECTOR_WSIZE); Cmd_p->SecCount = Cmd_p->SecCount - Cmd_p->MultiCnt; } /* Do any tidying up that might be required */ hal_AfterDma(Ata_p->HalHndl); } if (CrcError == TRUE) { Ata_p->LastExtendedErrorCode = EXTERROR_CRCERROR; Error = TRUE; break; } /* Check the status*/ status=hal_RegInByte(Ata_p->HalHndl,ATA_REG_STATUS); if ((status & (BSY_BIT_MASK | ERR_BIT_MASK | DF_BIT_MASK)) != 0) { Ata_p->LastExtendedErrorCode = 0x41; Error = TRUE; break; } if ((status & (DRDY_BIT_MASK)) == 0) { Ata_p->LastExtendedErrorCode= 0x32; Error= TRUE; break; } if (Cmd_p->SecCount < 1) { /*Since the drive has transferred all of the requested sectors without error, the drive should not have BUSY, DEVICE FAULT, DATA REQUEST or ERROR active now.*/ WAIT400NS; status = hal_RegInByte(Ata_p->HalHndl,ATA_REG_STATUS); if(status & (BSY_BIT_MASK | ERR_BIT_MASK | DF_BIT_MASK | DRQ_BIT_MASK)) { Ata_p->LastExtendedErrorCode= 0x43; Error= TRUE; break; } /* All sectors have been read without error, exit */ Ata_p->LastExtendedErrorCode= 0x00; break; } /* Do any tidying up that might be required */ hal_AfterDma(Ata_p->HalHndl); /*End of write loop*/ } /*read the output registers and store them in the cmd status structure*/ GetCmdStatus(Ata_p, Cmd_p->Stat.CmdStat); return Error; }/************************************************************************Name: ata_cmd_ExecuteDiagnosticsDescription: Executes this special commandParameter: 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_cmd_ExecuteDiagnostics(ata_ControlBlock_t *Ata_p, ata_Cmd_t *Cmd_p){ BOOL Error=FALSE; /* First we write the registers */ #if ATAPI_USING_INTERRUPTS hal_RegOutByte(Ata_p->HalHndl,ATA_REG_CONTROL, nIEN_CLEARED);#else hal_RegOutByte(Ata_p->HalHndl,ATA_REG_CONTROL, nIEN_SET);#endif hal_RegOutByte(Ata_p->HalHndl,ATA_REG_DEVHEAD, Cmd_p->DevHead); /* Finally write the command */ hal_RegOutByte(Ata_p->HalHndl,ATA_REG_COMMAND, Cmd_p->CommandCode); #if ATAPI_USING_INTERRUPTS if(hal_AwaitInt(Ata_p->HalHndl,INT_TIMEOUT * 10)) { Ata_p->LastExtendedErrorCode= 0x24; GetCmdStatus(Ata_p,Cmd_p->Stat.CmdStat); return TRUE; }#else /* Wait t > 2msec */ task_delay(TWO_MS);#endif if (WaitForBit(Ata_p->HalHndl, ATA_REG_ALTSTAT, BSY_BIT_MASK, 0)) { Ata_p->LastExtendedErrorCode= 0x24; GetCmdStatus(Ata_p,Cmd_p->Stat.CmdStat); return TRUE; } /*read the output registers and store them in the cmd status structure*/ GetCmdStatus(Ata_p,Cmd_p->Stat.CmdStat); Ata_p->LastExtendedErrorCode= 0x00; return Error; }/************************************************************************Name: GetCmdStatusDescription: 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 GetCmdStatus(ata_ControlBlock_t *Ata_p,STATAPI_CmdStatus_t *Stat_p){ U32 Dummy; Stat_p->Status = hal_RegInByte(Ata_p->HalHndl,ATA_REG_STATUS); Stat_p->CylinderLow = hal_RegInByte(Ata_p->HalHndl,ATA_REG_CYLLOW); Stat_p->CylinderHigh = hal_RegInByte(Ata_p->HalHndl,ATA_REG_CYLHIGH); Stat_p->SectorCount = hal_RegInByte(Ata_p->HalHndl,ATA_REG_SECCOUNT); Stat_p->Head = hal_RegInByte(Ata_p->HalHndl,ATA_REG_DEVHEAD); Stat_p->Sector = hal_RegInByte(Ata_p->HalHndl,ATA_REG_SECNUM); Stat_p->Error = hal_RegInByte(Ata_p->HalHndl,ATA_REG_ERROR); Stat_p->LBA=0x00000000; Dummy = Stat_p->Sector; Stat_p->LBA |= Dummy & 0x000000FF; Dummy = Stat_p->CylinderLow; Stat_p->LBA |= (Dummy<<8) & 0x0000FF00; Dummy = Stat_p->CylinderHigh; Stat_p->LBA |= (Dummy<<16) & 0x00FF0000; Dummy = Stat_p->Head; Stat_p->LBA |= (Dummy<<24 )& 0x0F000000; if (LastCommandExtended == TRUE) { /* Get the extra values */ U32 Control, Dummy; Control = hal_RegInByte(Ata_p->HalHndl, ATA_REG_CONTROL); Control |= CONTROL_HOB; hal_RegOutByte(Ata_p->HalHndl, ATA_REG_CONTROL, Control); /* We can destroy these values, since if it's an extended command * they shouldn't be looking at them anyway. */ Stat_p->CylinderLow = hal_RegInByte(Ata_p->HalHndl, ATA_REG_CYLLOW); Stat_p->CylinderHigh = hal_RegInByte(Ata_p->HalHndl, ATA_REG_CYLHIGH); Stat_p->Sector = hal_RegInByte(Ata_p->HalHndl, ATA_REG_SECNUM); Dummy = Stat_p->Sector & 0xff; Dummy <<= 24; Stat_p->LBA |= Dummy; Dummy = Stat_p->CylinderLow & 0x00ff; Stat_p->LBAExtended = Dummy; Dummy = Stat_p->CylinderHigh & 0xff00; Dummy <<= 8; Stat_p->LBAExtended |= Dummy; /* Reset HOB bit */ Control &= ~CONTROL_HOB; hal_RegOutByte(Ata_p->HalHndl, ATA_REG_CONTROL, Control); }}/*end of cmmd_ata.c --------------------------------------------------*/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -