📄 statapi.c
字号:
if(Dev->Opened==FALSE) { return ST_ERROR_INVALID_HANDLE; } if (Dev->IsModeSet==FALSE) { return STATAPI_ERROR_MODE_NOT_SET; } if(Dev== &ATAHandle->Handles[0]) { DevNo= DEVICE_0; }else { DevNo= DEVICE_1; } /* Acquire the bus */ if(ata_bus_Acquire(ATAHandle)) { return ST_ERROR_DEVICE_BUSY; } Dev->Notify= TRUE; Dev->Abort= FALSE; if (Dev->CmdType == 0) { /* Host/device do not support the transport implied by the command */ ata_bus_Release(ATAHandle); return STATAPI_ERROR_PROTOCOL_NOT_SUPPORTED; } /* Set the Cmd structure */ Dev->CmdToSend.Feature= Cmd->Features; Dev->CmdToSend.Stat.CmdStat= CmdStatus; Dev->CmdToSend.CommandCode= CmdCodes[Cmd->CmdCode]; Dev->CmdType = ChooseProtocolCmd(Cmd->CmdCode, Dev); Dev->CmdToSend.CmdType = Dev->CmdType; if ((Cmd->UseLBA) && ((Dev->CmdType & ATA_EXT_BIT) == 0)) { Dev->CmdToSend.SecCount= Cmd->SectorCount; /* Need to chop and set the bit */ Dummy32= Cmd->LBA; Dev->CmdToSend.SecNum= Dummy32 & 0x000000FF; Dummy32= Dummy32 >> 8; Dev->CmdToSend.CylLow= Dummy32 & 0x000000FF; Dummy32= Dummy32 >> 8; Dev->CmdToSend.CylHigh= Dummy32 & 0x000000FF; Dummy32= Dummy32 >> 8; Dummy8= Dummy32 & 0x0000000F; Dev->CmdToSend.DevHead= Dummy8 | LBA_SET_BIT; } else if ((Cmd->UseLBA) && ((Dev->CmdType & ATA_EXT_BIT) != 0)) { /* Split the sector count */ Dev->CmdToSend.SecCount = (Cmd->SectorCount & 0xff00) >> 8; Dev->CmdToSend.SecCount2 = (Cmd->SectorCount & 0x00ff); /* Now split the LBA, higher bits first into the registers. */ Dev->CmdToSend.CylHigh = (Cmd->LBAExtended & 0xff00) >> 8; Dev->CmdToSend.CylLow = (Cmd->LBAExtended & 0x00ff); Dev->CmdToSend.SecNum = (Cmd->LBA & 0xff000000) >> 24; Dev->CmdToSend.CylHigh2 = (Cmd->LBA & 0x00ff0000) >> 16; Dev->CmdToSend.CylLow2 = (Cmd->LBA & 0x0000ff00) >> 8; Dev->CmdToSend.SecNum2 = (Cmd->LBA & 0x000000ff); /* Bits 5,7 obsolete; 3:0 reserved; LBA bit must be on, DEV bit must * be set appropriately. */ Dev->CmdToSend.DevHead = LBA_SET_BIT; if (DevNo == DEVICE_0) Dev->CmdToSend.DevHead |= DEVHEAD_DEV0; else Dev->CmdToSend.DevHead |= DEVHEAD_DEV1; } else { Dev->CmdToSend.SecCount= Cmd->SectorCount; Dev->CmdToSend.CylLow= Cmd->CylinderLow; Dev->CmdToSend.CylHigh= Cmd->CylinderHigh; Dev->CmdToSend.DevHead= Cmd->Head & 0x0F; Dev->CmdToSend.SecNum= Cmd->Sector; } /* Add device select bit */ if(DevNo== DEVICE_1) { Dev->CmdToSend.DevHead |= DEVICE_SELECT_1_MASK ; } ATAHandle->DeviceSelected= DevNo; semaphore_signal(&ATAHandle->BATSemaphore); return ST_NO_ERROR;}/****************************************************************************Name : STATAPI CmdIn()Description : Issues a command to read data from the deviceParameters : STATAPI_Handle_t Handle Handle to ATA/ATAPI device on host bus. STATAPI_PIOMode_t Mode PIO mode to invoke. U8 * Data Pointer to the buffer allocated to store the data U32 BufferSize Size of the buffer U32 * NumberRead Pointer to a variable to be updated with the number of bytes actually read Return Value : ST_NO_ERROR No error. ST_ERROR_INVALID_HANDLE Device handle is invalid. ST_ERROR_BAD_PARAMETER ST_ERROR_DEVICE_BUSY The command can not be executed as the BSY bit is set in the status register, indicating the device is busy. STATAPI_ERROR_CMD_ABORT The ABRT bit is set in the error register indicating that the command failed to complete e.g., a bad parameter or unsupported command. STATAPI_ERROR_CMD_ERROR A command-specific error has occured and the user should interrogate the error. STATAPI_ERROR_USER_ABORT The command or operation has been explicitly aborted by the user. STATAPI_ERROR_MODE_NOT_SET Mode not set yet ****************************************************************************/ST_ErrorCode_t STATAPI_CmdIn(STATAPI_Handle_t Handle,const STATAPI_Cmd_t *Cmd, U8 *Data, U32 BufferSize, U32 *NumberRead, STATAPI_CmdStatus_t *CmdStatus) { ata_DevCtrlBlock_t *Dev; U32 Dummy32= 0; U8 Dummy8=0; U8 DevNo; Dev=(ata_DevCtrlBlock_t*) Handle; /* Check Parameters */ if((Dev!= &ATAHandle->Handles[0]) & (Dev!= &ATAHandle->Handles[1])) { return ST_ERROR_INVALID_HANDLE; } if((Cmd==NULL)|(CmdStatus==NULL)| (NumberRead==NULL)) { return ST_ERROR_BAD_PARAMETER; } /* Internal protocol checkings */ if(Dev->Opened==FALSE) { return ST_ERROR_INVALID_HANDLE; } if (Dev->IsModeSet==FALSE) { return STATAPI_ERROR_MODE_NOT_SET; } /* Parameters coherence checking */ if ((BufferSize < (Cmd->SectorCount * SECTOR_BSIZE)) | (Data==NULL)) { return ST_ERROR_BAD_PARAMETER; } /* Specific command checkings */ if(Cmd->CmdCode==STATAPI_CMD_READ_MULTIPLE) { Dev->CmdToSend.MultiCnt= Dev->MultiCnt; } else { Dev->CmdToSend.MultiCnt=1; } /*------------------------All OK Let's do it-----------------------------*/ if(Dev== &ATAHandle->Handles[0]) { DevNo= DEVICE_0; } else { DevNo= DEVICE_1; } /* Acquire the bus */ if(ata_bus_Acquire(ATAHandle)) { return ST_ERROR_DEVICE_BUSY; } Dev->Notify= TRUE; Dev->Abort= FALSE; Dev->CmdType = ChooseProtocolCmd(Cmd->CmdCode, Dev); if (Dev->CmdType == 0) { /* Host/device do not support the transport implied by the command */ ata_bus_Release(ATAHandle); return STATAPI_ERROR_PROTOCOL_NOT_SUPPORTED; } if ((Dev->CmdType == ATA_CMD_DMAIN) || (Dev->CmdType == ATA_CMD_DMAIN_EXT)) { /* Check buffer alignment; 5514 requirement, may be different for * other chips */ if ( (((U32)Data / 128) * 128) != (U32)Data ) { ata_bus_Release(ATAHandle); return ST_ERROR_BAD_PARAMETER; } /* Has a 256-sector limit (0 == 256); caller should know this. */ Dev->CmdToSend.MultiCnt = Cmd->SectorCount & 0xff; } /*------- Set the Cmd structure -----*/ Dev->CmdToSend.Feature= Cmd->Features; Dev->CmdToSend.Stat.CmdStat= CmdStatus; Dev->CmdToSend.CommandCode= CmdCodes[Cmd->CmdCode]; Dev->CmdToSend.DataBuffer= Data; Dev->CmdToSend.BytesRW= NumberRead; Dev->CmdToSend.CmdType = Dev->CmdType; Dev->CmdToSend.UseDMA = TRUE; /* Most times we'll want this */ if ((Cmd->UseLBA) && ((Dev->CmdType & ATA_EXT_BIT) == 0)) { Dev->CmdToSend.SecCount= Cmd->SectorCount; /* Need to chop and set the bit */ Dummy32= Cmd->LBA; Dev->CmdToSend.SecNum= Dummy32 & 0x000000FF; Dummy32= Dummy32 >> 8; Dev->CmdToSend.CylLow= Dummy32 & 0x000000FF; Dummy32= Dummy32 >> 8; Dev->CmdToSend.CylHigh= Dummy32 & 0x000000FF; Dummy32= Dummy32 >> 8; Dummy8= Dummy32 & 0x0000000F; Dev->CmdToSend.DevHead= Dummy8 | LBA_SET_BIT; } else if ((Cmd->UseLBA) && ((Dev->CmdType & ATA_EXT_BIT) != 0)) { /* Split the sector count */ Dev->CmdToSend.SecCount = (Cmd->SectorCount & 0xff00) >> 8; Dev->CmdToSend.SecCount2 = (Cmd->SectorCount & 0x00ff); /* Now split the LBA, higher bits first into the registers. */ Dev->CmdToSend.CylHigh = (Cmd->LBAExtended & 0xff00) >> 8; Dev->CmdToSend.CylLow = (Cmd->LBAExtended & 0x00ff); Dev->CmdToSend.SecNum = (Cmd->LBA & 0xff000000) >> 24; Dev->CmdToSend.CylHigh2 = (Cmd->LBA & 0x00ff0000) >> 16; Dev->CmdToSend.CylLow2 = (Cmd->LBA & 0x0000ff00) >> 8; Dev->CmdToSend.SecNum2 = (Cmd->LBA & 0x000000ff); /* Bits 5,7 obsolete; 3:0 reserved; LBA bit must be on, DEV bit must * be set appropriately. */ Dev->CmdToSend.DevHead = LBA_SET_BIT; if (DevNo == DEVICE_0) Dev->CmdToSend.DevHead |= DEVHEAD_DEV0; else Dev->CmdToSend.DevHead |= DEVHEAD_DEV1; } else { Dev->CmdToSend.SecCount= Cmd->SectorCount; Dev->CmdToSend.CylLow= Cmd->CylinderLow; Dev->CmdToSend.CylHigh= Cmd->CylinderHigh; Dev->CmdToSend.DevHead= Cmd->Head & 0x0F; Dev->CmdToSend.SecNum= Cmd->Sector; } /* Add device select bit */ if(DevNo== DEVICE_1) { Dev->CmdToSend.DevHead |= DEVICE_SELECT_1_MASK ; } ATAHandle->DeviceSelected= DevNo; semaphore_signal(&ATAHandle->BATSemaphore); return ST_NO_ERROR;}/****************************************************************************Name : STATAPI CmdOut()Description : Performs a command that implies a data transfer to the diskParameters : STATAPI_Handle_t Handle Handle to ATA/ATAPI device on host bus. STATAPI_PIOMode_t Mode PIO mode to invoke. Return Value : ST_NO_ERROR No error. ST_ERROR_INVALID_HANDLE Device handle is invalid. ST_ERROR_BAD_PARAMETER ST_ERROR_DEVICE_BUSY The command can not be executed as the BSY bit is set in the status register, indicating the device is busy. STATAPI_ERROR_CMD_ABORT The ABRT bit is set in the error register indicating that the command failed to complete e.g., a bad parameter or unsupported command. STATAPI_ERROR_CMD_ERROR A command-specific error has occured and the user should interrogate the error. STATAPI_ERROR_USER_ABORT The command or operation has been explicitly aborted by the user. STATAPI_ERROR_MODE_NOT_SET Mode not set yet ****************************************************************************/ST_ErrorCode_t STATAPI_CmdOut(STATAPI_Handle_t Handle,const STATAPI_Cmd_t *Cmd, const U8 *Data, U32 BufferSize, U32 *NumberRead, STATAPI_CmdStatus_t *CmdStatus) { ata_DevCtrlBlock_t *Dev; U32 Dummy32= 0; U8 Dummy8=0; U8 DevNo; Dev = (ata_DevCtrlBlock_t*) Handle; /* Check Parameters */ if ((Dev != &ATAHandle->Handles[0]) && (Dev != &ATAHandle->Handles[1])) { return ST_ERROR_INVALID_HANDLE; } if ((Cmd == NULL) || (CmdStatus == NULL) || (NumberRead == NULL)) { return ST_ERROR_BAD_PARAMETER; } /* Internal protocol checkings */ if (Dev->Opened == FALSE) { return ST_ERROR_INVALID_HANDLE; } if (Dev->IsModeSet == FALSE) { return STATAPI_ERROR_MODE_NOT_SET; } /* Parameter checking */ if ((BufferSize < (Cmd->SectorCount * SECTOR_BSIZE)) || (Data == NULL)) { return ST_ERROR_BAD_PARAMETER; } /* Specific command checking */ if (Cmd->CmdCode == STATAPI_CMD_WRITE_MULTIPLE) { Dev->CmdToSend.MultiCnt = Dev->MultiCnt; } else { Dev->CmdToSend.MultiCnt = 1; } /*------------------------All OK Let's do it-----------------------------*/ if(Dev == &ATAHandle->Handles[0]) { DevNo = DEVICE_0; } else { DevNo = DEVICE_1; } /* Acquire the bus */ if(ata_bus_Acquire(ATAHandle)) { return ST_ERROR_DEVICE_BUSY; } Dev->Notify= TRUE; Dev->Abort= FALSE; Dev->CmdType = ChooseProtocolCmd(Cmd->CmdCode, Dev); if (Dev->CmdType == 0) { /* Either host or device does not support the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -