* Reworked device detection, we'll see how well this works...

* Reworked some of the transfer handling after reading the specs.
* Ensure that the device selection bit is set correctly for all commands.
* Generally disable interrupts and enable them only when expecting a DMA one.
* Renamed disk failure to device fault according to specs.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30248 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz
2009-04-18 20:58:33 +00:00
parent b43891053d
commit 827f849a34
6 changed files with 109 additions and 113 deletions
+2 -2
View File
@@ -215,7 +215,7 @@ enum {
// packet and dma queued result // packet and dma queued result
ATA_MASK_ERROR = 0x01, ATA_MASK_ERROR = 0x01,
ATA_MASK_IREASON = 0x02, ATA_MASK_INTERRUPT_REASON = 0x02,
ATA_MASK_DEVICE_HEAD = 0x20, ATA_MASK_DEVICE_HEAD = 0x20,
ATA_MASK_COMMAND = 0x40, ATA_MASK_COMMAND = 0x40,
@@ -243,7 +243,7 @@ enum {
ATA_STATUS_DWF = 0x20, // reserved ATA_STATUS_DWF = 0x20, // reserved
ATA_STATUS_DMA = 0x20, // reserved ATA_STATUS_DMA = 0x20, // reserved
ATA_STATUS_DMA_READY = 0x20, // packet: DMA ready ATA_STATUS_DMA_READY = 0x20, // packet: DMA ready
ATA_STATUS_DISK_FAILURE = 0x20, // packet: disk failure ATA_STATUS_DEVICE_FAULT = 0x20, // device fault
ATA_STATUS_DEVICE_READY = 0x40, // device ready ATA_STATUS_DEVICE_READY = 0x40, // device ready
ATA_STATUS_BUSY = 0x80 // busy ATA_STATUS_BUSY = 0x80 // busy
}; };
@@ -116,41 +116,34 @@ ATAChannel::SetBus(scsi_bus bus)
status_t status_t
ATAChannel::ScanBus() ATAChannel::ScanBus()
{ {
bool devicePresent[fDeviceCount]; // check if there is anything at all
if (AltStatus() == 0xff) {
TRACE_ALWAYS("illegal status value, assuming no devices connected\n");
return B_OK;
}
uint32 deviceSignature[fDeviceCount]; uint32 deviceSignature[fDeviceCount];
status_t result = Reset(devicePresent, deviceSignature); status_t result = Reset(deviceSignature);
if (result != B_OK) { if (result != B_OK) {
TRACE_ERROR("resetting the channel failed\n"); TRACE_ERROR("resetting the channel failed\n");
return result; return result;
} }
for (uint8 i = 0; i < fDeviceCount; i++) { for (uint8 i = 0; i < fDeviceCount; i++) {
if (!devicePresent[i])
continue;
ATADevice *device = NULL; ATADevice *device = NULL;
if (deviceSignature[i] == ATA_SIGNATURE_ATAPI) if (deviceSignature[i] == ATA_SIGNATURE_ATAPI)
device = new(std::nothrow) ATAPIDevice(this, i); device = new(std::nothrow) ATAPIDevice(this, i);
else else
device = new(std::nothrow) ATADevice(this, i); device = new(std::nothrow) ATADevice(this, i);
if (device == NULL) if (device == NULL) {
TRACE_ERROR("out of memory allocating device\n");
return B_NO_MEMORY; return B_NO_MEMORY;
}
TRACE("trying ATA%s device %u\n", device->IsATAPI() ? "PI" : "", i); TRACE("trying ATA%s device %u\n", device->IsATAPI() ? "PI" : "", i);
bool identified = device->Identify() == B_OK; if (device->Identify() != B_OK) {
if (!identified && !device->IsATAPI()) {
// retry as atapi
delete device;
device = new(std::nothrow) ATAPIDevice(this, i);
if (device == NULL)
return B_NO_MEMORY;
identified = device->Identify() == B_OK;
}
if (!identified) {
delete device; delete device;
continue; continue;
} }
@@ -265,9 +258,8 @@ ATAChannel::SelectDevice(uint8 device)
return B_BAD_INDEX; return B_BAD_INDEX;
ata_task_file taskFile; ata_task_file taskFile;
taskFile.chs.head = 0; taskFile.lba.mode = ATA_MODE_LBA;
taskFile.chs.mode = ATA_MODE_LBA; taskFile.lba.device = device;
taskFile.chs.device = device;
_WriteRegs(&taskFile, ATA_MASK_DEVICE_HEAD); _WriteRegs(&taskFile, ATA_MASK_DEVICE_HEAD);
_FlushAndWait(1); _FlushAndWait(1);
@@ -286,38 +278,10 @@ ATAChannel::SelectDevice(uint8 device)
} }
bool
ATAChannel::IsDevicePresent(uint8 device)
{
if (SelectDevice(device) != B_OK)
return false;
ata_task_file taskFile;
taskFile.chs.device = device;
taskFile.chs.mode = ATA_MODE_LBA;
taskFile.chs.command = ATA_COMMAND_NOP;
_WriteRegs(&taskFile, ATA_MASK_DEVICE_HEAD);
_FlushAndWait(10);
_ReadRegs(&taskFile, ATA_MASK_STATUS | ATA_MASK_ERROR);
TRACE("status: 0x%02x; error: 0x%02x\n", taskFile.read.status,
taskFile.read.error);
return (taskFile.read.status & 0xf8) != 0xf8
&& taskFile.read.status != 0xa5;
}
status_t status_t
ATAChannel::Reset(bool *presence, uint32 *signatures) ATAChannel::Reset(uint32 *signatures)
{ {
TRACE_FUNCTION("%p, %p\n", presence, signatures); TRACE_FUNCTION("\n");
bool devicePresent[fDeviceCount];
for (uint8 i = 0; i < fDeviceCount; i++) {
devicePresent[i] = IsDevicePresent(i);
TRACE("device %d: %s present\n", i, devicePresent[i] ? "might be" : "is not");
}
SelectDevice(0); SelectDevice(0);
@@ -339,14 +303,11 @@ ATAChannel::Reset(bool *presence, uint32 *signatures)
_FlushAndWait(150 * 1000); _FlushAndWait(150 * 1000);
for (uint8 i = 0; i < fDeviceCount; i++) { for (uint8 i = 0; i < fDeviceCount; i++) {
if (presence != NULL)
presence[i] = devicePresent[i];
if (!devicePresent[i])
continue;
SelectDevice(i); SelectDevice(i);
// ensure interrupts are disabled for this device
_WriteControl(ATA_DEVICE_CONTROL_DISABLE_INTS);
// wait up to 31 seconds for busy to clear // wait up to 31 seconds for busy to clear
if (Wait(0, ATA_STATUS_BUSY, 0, 31 * 1000 * 1000) != B_OK) { if (Wait(0, ATA_STATUS_BUSY, 0, 31 * 1000 * 1000) != B_OK) {
TRACE_ERROR("reset timeout\n"); TRACE_ERROR("reset timeout\n");
@@ -390,6 +351,9 @@ ATAChannel::Wait(uint8 setBits, uint8 clearedBits, uint32 flags,
bigtime_t startTime = system_time(); bigtime_t startTime = system_time();
_FlushAndWait(1); _FlushAndWait(1);
TRACE("waiting for set bits 0x%02x and cleared bits 0x%02x\n",
setBits, clearedBits);
while (true) { while (true) {
uint8 status = AltStatus(); uint8 status = AltStatus();
if ((flags & ATA_CHECK_ERROR_BIT) != 0 if ((flags & ATA_CHECK_ERROR_BIT) != 0
@@ -398,9 +362,9 @@ ATAChannel::Wait(uint8 setBits, uint8 clearedBits, uint32 flags,
return B_ERROR; return B_ERROR;
} }
if ((flags & ATA_CHECK_DISK_FAILURE) != 0 if ((flags & ATA_CHECK_DEVICE_FAULT) != 0
&& (status & ATA_STATUS_DISK_FAILURE) != 0) { && (status & ATA_STATUS_DEVICE_FAULT) != 0) {
TRACE("disk failure bit set while waiting\n"); TRACE("device fault bit set while waiting\n");
return B_ERROR; return B_ERROR;
} }
@@ -412,7 +376,7 @@ ATAChannel::Wait(uint8 setBits, uint8 clearedBits, uint32 flags,
} }
bigtime_t elapsedTime = system_time() - startTime; bigtime_t elapsedTime = system_time() - startTime;
//TRACE("wait status after %lld: %u\n", elapsedTime, status); TRACE("wait status after %lld: 0x%02x\n", elapsedTime, status);
if (elapsedTime > timeout) if (elapsedTime > timeout)
return B_TIMED_OUT; return B_TIMED_OUT;
@@ -459,6 +423,9 @@ ATAChannel::PrepareWaitingForInterrupt()
InterruptsSpinLocker locker(fInterruptLock); InterruptsSpinLocker locker(fInterruptLock);
fExpectsInterrupt = true; fExpectsInterrupt = true;
fInterruptCondition.Add(&fInterruptConditionEntry); fInterruptCondition.Add(&fInterruptConditionEntry);
// enable interrupts
_WriteControl(0);
} }
@@ -473,6 +440,9 @@ ATAChannel::WaitForInterrupt(bigtime_t timeout)
fExpectsInterrupt = false; fExpectsInterrupt = false;
locker.Unlock(); locker.Unlock();
// disable interrupts
_WriteControl(ATA_DEVICE_CONTROL_DISABLE_INTS);
if (result != B_OK) { if (result != B_OK) {
TRACE_ERROR("timeout waiting for interrupt\n"); TRACE_ERROR("timeout waiting for interrupt\n");
return B_TIMED_OUT; return B_TIMED_OUT;
@@ -485,10 +455,6 @@ ATAChannel::WaitForInterrupt(bigtime_t timeout)
status_t status_t
ATAChannel::SendRequest(ATARequest *request, uint32 flags) ATAChannel::SendRequest(ATARequest *request, uint32 flags)
{ {
// disable interrupts for PIO transfers, enable them for DMA
_WriteControl((flags & ATA_DMA_TRANSFER) != 0 ? 0
: ATA_DEVICE_CONTROL_DISABLE_INTS);
ATADevice *device = request->Device(); ATADevice *device = request->Device();
if (device->Select() != B_OK || WaitForIdle() != B_OK) { if (device->Select() != B_OK || WaitForIdle() != B_OK) {
// resetting the device here will discard current configuration, // resetting the device here will discard current configuration,
@@ -553,8 +519,8 @@ ATAChannel::FinishRequest(ATARequest *request, uint32 flags, uint8 errorMask)
} }
uint8 checkFlags = ATA_STATUS_ERROR; uint8 checkFlags = ATA_STATUS_ERROR;
if (flags & ATA_CHECK_DISK_FAILURE) if (flags & ATA_CHECK_DEVICE_FAULT)
checkFlags |= ATA_STATUS_DISK_FAILURE; checkFlags |= ATA_STATUS_DEVICE_FAULT;
if ((taskFile->read.status & checkFlags) == 0) if ((taskFile->read.status & checkFlags) == 0)
return B_OK; return B_OK;
@@ -646,13 +612,6 @@ ATAChannel::ExecutePIOTransfer(ATARequest *request)
status_t result = B_OK; status_t result = B_OK;
size_t *bytesLeft = request->BytesLeft(); size_t *bytesLeft = request->BytesLeft();
while (*bytesLeft > 0) { while (*bytesLeft > 0) {
if (Wait(ATA_STATUS_DATA_REQUEST, ATA_STATUS_BUSY, ATA_CHECK_ERROR_BIT
| ATA_CHECK_DISK_FAILURE, timeout) != B_OK) {
TRACE_ERROR("timeout waiting for device to request data\n");
result = B_TIMED_OUT;
break;
}
size_t currentLength = MIN(*bytesLeft, ATA_BLOCK_SIZE); size_t currentLength = MIN(*bytesLeft, ATA_BLOCK_SIZE);
if (request->IsWrite()) { if (request->IsWrite()) {
result = _WritePIOBlock(request, currentLength); result = _WritePIOBlock(request, currentLength);
@@ -670,9 +629,16 @@ ATAChannel::ExecutePIOTransfer(ATARequest *request)
*bytesLeft -= currentLength; *bytesLeft -= currentLength;
// wait 1 pio cycle if (*bytesLeft > 0) {
if (*bytesLeft > 0) // wait for next block to be ready
AltStatus(); if (Wait(ATA_STATUS_DATA_REQUEST, ATA_STATUS_BUSY,
ATA_CHECK_ERROR_BIT | ATA_CHECK_DEVICE_FAULT,
timeout) != B_OK) {
TRACE_ERROR("timeout waiting for device to request data\n");
result = B_TIMED_OUT;
break;
}
}
} }
if (result == B_OK && WaitDataRequest(false) != B_OK) { if (result == B_OK && WaitDataRequest(false) != B_OK) {
@@ -436,9 +436,11 @@ ATADevice::Configure()
if (fUseLBA) { if (fUseLBA) {
fTotalSectors = fInfoBlock.LBA_total_sectors; fTotalSectors = fInfoBlock.LBA_total_sectors;
fTaskFile.lba.mode = ATA_MODE_LBA; fTaskFile.lba.mode = ATA_MODE_LBA;
fTaskFile.lba.device = fIndex;
} else { } else {
fTotalSectors = chsCapacity; fTotalSectors = chsCapacity;
fTaskFile.chs.mode = ATA_MODE_CHS; fTaskFile.chs.mode = ATA_MODE_CHS;
fTaskFile.chs.device = fIndex;
} }
fUse48Bits = fInfoBlock._48_bit_addresses_supported; fUse48Bits = fInfoBlock._48_bit_addresses_supported;
@@ -485,7 +487,7 @@ ATADevice::Identify()
} }
if (fChannel->Wait(ATA_STATUS_DATA_REQUEST, ATA_STATUS_BUSY, if (fChannel->Wait(ATA_STATUS_DATA_REQUEST, ATA_STATUS_BUSY,
ATA_CHECK_ERROR_BIT | ATA_CHECK_DISK_FAILURE, IsATAPI() ATA_CHECK_ERROR_BIT | ATA_CHECK_DEVICE_FAULT, IsATAPI()
? 20 * 1000 * 1000 : 500 * 1000) != B_OK) { ? 20 * 1000 * 1000 : 500 * 1000) != B_OK) {
TRACE_ERROR("timeout waiting for identify request\n"); TRACE_ERROR("timeout waiting for identify request\n");
return B_TIMED_OUT; return B_TIMED_OUT;
@@ -525,13 +527,8 @@ ATADevice::ExecuteReadWrite(ATARequest *request, uint64 address,
return B_ERROR; return B_ERROR;
} }
uint32 flags = 0; status_t result = fChannel->SendRequest(request, IsATAPI()
if (!IsATAPI()) ? 0 : ATA_DEVICE_READY_REQUIRED);
flags |= ATA_DEVICE_READY_REQUIRED;
if (request->UseDMA())
flags |= ATA_DMA_TRANSFER;
status_t result = fChannel->SendRequest(request, flags);
if (result != B_OK) { if (result != B_OK) {
TRACE_ERROR("failed to send transfer request\n"); TRACE_ERROR("failed to send transfer request\n");
if (request->UseDMA()) if (request->UseDMA())
@@ -539,6 +536,13 @@ ATADevice::ExecuteReadWrite(ATARequest *request, uint64 address,
return result; return result;
} }
if (fChannel->Wait(ATA_STATUS_DATA_REQUEST, 0, ATA_CHECK_ERROR_BIT
| ATA_CHECK_DEVICE_FAULT, request->Timeout()) != B_OK) {
TRACE_ERROR("timeout waiting for device to request data\n");
request->SetStatus(SCSI_CMD_TIMEOUT);
return B_TIMED_OUT;
}
if (request->UseDMA()) { if (request->UseDMA()) {
fChannel->PrepareWaitingForInterrupt(); fChannel->PrepareWaitingForInterrupt();
fChannel->StartDMA(); fChannel->StartDMA();
@@ -591,6 +595,8 @@ ATADevice::_FillTaskFile(ATARequest *request, uint64 address)
}; };
uint32 sectorCount = *request->BytesLeft() / ATA_BLOCK_SIZE; uint32 sectorCount = *request->BytesLeft() / ATA_BLOCK_SIZE;
TRACE("about to transfer %lu sectors\n", sectorCount);
if (fUseLBA) { if (fUseLBA) {
if (fUse48Bits if (fUse48Bits
&& (address + sectorCount > 0xfffffff || sectorCount > 0x100)) { && (address + sectorCount > 0xfffffff || sectorCount > 0x100)) {
@@ -136,7 +136,7 @@ ata_sim_reset_bus(scsi_sim_cookie cookie)
if (channel->Bus() == NULL) if (channel->Bus() == NULL)
return SCSI_NO_HBA; return SCSI_NO_HBA;
channel->Reset(NULL, NULL); channel->Reset(NULL);
return SCSI_REQ_CMP; return SCSI_REQ_CMP;
} }
@@ -49,8 +49,7 @@ ATAPIDevice::SendPacket(ATARequest *request)
return B_ERROR; return B_ERROR;
} }
status_t result = fChannel->SendRequest(request, request->UseDMA() status_t result = fChannel->SendRequest(request, 0);
? ATA_DMA_TRANSFER : 0);
if (result != B_OK) { if (result != B_OK) {
TRACE_ERROR("failed to send packet request\n"); TRACE_ERROR("failed to send packet request\n");
if (request->UseDMA()) if (request->UseDMA())
@@ -60,7 +59,7 @@ ATAPIDevice::SendPacket(ATARequest *request)
// wait for device to get ready for packet transmission // wait for device to get ready for packet transmission
if (fChannel->Wait(ATA_STATUS_DATA_REQUEST, ATA_STATUS_BUSY, if (fChannel->Wait(ATA_STATUS_DATA_REQUEST, ATA_STATUS_BUSY,
ATA_CHECK_ERROR_BIT | ATA_CHECK_DISK_FAILURE, 100 * 1000) != B_OK) { ATA_CHECK_ERROR_BIT | ATA_CHECK_DEVICE_FAULT, 100 * 1000) != B_OK) {
TRACE_ERROR("timeout waiting for data request\n"); TRACE_ERROR("timeout waiting for data request\n");
if (request->UseDMA()) if (request->UseDMA())
fChannel->FinishDMA(); fChannel->FinishDMA();
@@ -70,7 +69,7 @@ ATAPIDevice::SendPacket(ATARequest *request)
} }
// make sure device really asks for command packet // make sure device really asks for command packet
fRegisterMask = ATA_MASK_IREASON; fRegisterMask = ATA_MASK_INTERRUPT_REASON;
fChannel->ReadRegs(this); fChannel->ReadRegs(this);
if (!fTaskFile.packet_res.cmd_or_data if (!fTaskFile.packet_res.cmd_or_data
@@ -96,6 +95,14 @@ ATAPIDevice::SendPacket(ATARequest *request)
return B_ERROR; return B_ERROR;
} }
if (!request->HasData()) {
result = fChannel->FinishRequest(request, ATA_WAIT_FINISH
| ATA_CHECK_DEVICE_FAULT, ATA_ERROR_ALL);
if (result != B_OK)
TRACE_ERROR("device indicates error after non-data command\n");
return result;
}
if (request->UseDMA()) { if (request->UseDMA()) {
fChannel->PrepareWaitingForInterrupt(); fChannel->PrepareWaitingForInterrupt();
fChannel->StartDMA(); fChannel->StartDMA();
@@ -107,7 +114,7 @@ ATAPIDevice::SendPacket(ATARequest *request)
return B_TIMED_OUT; return B_TIMED_OUT;
} }
result = fChannel->FinishRequest(request, ATA_CHECK_DISK_FAILURE, result = fChannel->FinishRequest(request, ATA_CHECK_DEVICE_FAULT,
ATA_ERROR_ALL); ATA_ERROR_ALL);
if (result != B_OK) { if (result != B_OK) {
TRACE_ERROR("device indicates transfer error after dma\n"); TRACE_ERROR("device indicates transfer error after dma\n");
@@ -133,33 +140,47 @@ ATAPIDevice::SendPacket(ATARequest *request)
return B_ERROR; return B_ERROR;
} }
// PIO data transfer
if (fChannel->Wait(ATA_STATUS_DATA_REQUEST, ATA_STATUS_BUSY, if (fChannel->Wait(ATA_STATUS_DATA_REQUEST, ATA_STATUS_BUSY,
ATA_CHECK_ERROR_BIT | ATA_CHECK_DISK_FAILURE, ATA_CHECK_ERROR_BIT | ATA_CHECK_DEVICE_FAULT,
request->Timeout()) != B_OK) { request->Timeout()) != B_OK) {
TRACE_ERROR("timeout waiting for device to request data\n"); TRACE_ERROR("timeout waiting for device to request data\n");
request->SetStatus(SCSI_CMD_TIMEOUT); request->SetStatus(SCSI_CMD_TIMEOUT);
return B_TIMED_OUT; return B_TIMED_OUT;
} }
fRegisterMask = ATA_MASK_IREASON | ATA_MASK_BYTE_COUNT; // PIO data transfer
fChannel->ReadRegs(this); while (true) {
fRegisterMask = ATA_MASK_INTERRUPT_REASON | ATA_MASK_BYTE_COUNT;
fChannel->ReadRegs(this);
if (fTaskFile.packet_res.cmd_or_data) { if (fTaskFile.packet_res.cmd_or_data) {
TRACE_ERROR("device expecting command instead of data\n"); TRACE_ERROR("device expecting command instead of data\n");
request->SetStatus(SCSI_SEQUENCE_FAIL); request->SetStatus(SCSI_SEQUENCE_FAIL);
return B_ERROR; return B_ERROR;
}
size_t length = fTaskFile.packet_res.byte_count_0_7
| ((size_t)fTaskFile.packet_res.byte_count_8_15 << 8);
TRACE("about to transfer %lu bytes\n", length);
request->SetBytesLeft(length);
fChannel->ExecutePIOTransfer(request);
if (fChannel->Wait(0, ATA_STATUS_BUSY, 0, request->Timeout()) != B_OK) {
TRACE_ERROR("timeout waiting for device to finish transfer\n");
request->SetStatus(SCSI_CMD_TIMEOUT);
return B_TIMED_OUT;
}
if ((fChannel->AltStatus() & ATA_STATUS_DATA_REQUEST) == 0) {
// transfer complete
TRACE("pio transfer complete\n");
break;
}
} }
size_t length = fTaskFile.packet_res.byte_count_0_7
| ((size_t)fTaskFile.packet_res.byte_count_8_15 << 8);
TRACE("about to transfer %lu bytes\n", length);
request->SetBytesLeft(length);
fChannel->ExecutePIOTransfer(request);
result = fChannel->FinishRequest(request, ATA_WAIT_FINISH result = fChannel->FinishRequest(request, ATA_WAIT_FINISH
| ATA_CHECK_DISK_FAILURE, ATA_ERROR_ALL); | ATA_CHECK_DEVICE_FAULT, ATA_ERROR_ALL);
if (result != B_OK) if (result != B_OK)
TRACE_ERROR("device indicates transfer error after pio\n"); TRACE_ERROR("device indicates transfer error after pio\n");
@@ -210,7 +231,7 @@ ATAPIDevice::_FillTaskFilePacket(ATARequest *request)
{ {
scsi_ccb *ccb = request->CCB(); scsi_ccb *ccb = request->CCB();
fRegisterMask = ATA_MASK_FEATURES | ATA_MASK_BYTE_COUNT; fRegisterMask = ATA_MASK_FEATURES | ATA_MASK_BYTE_COUNT;
fTaskFile.packet.dma = request->UseDMA(); fTaskFile.packet.dma = request->UseDMA() ? 1 : 0;
fTaskFile.packet.ovl = 0; fTaskFile.packet.ovl = 0;
fTaskFile.packet.byte_count_0_7 = ccb->data_length & 0xff; fTaskFile.packet.byte_count_0_7 = ccb->data_length & 0xff;
fTaskFile.packet.byte_count_8_15 = ccb->data_length >> 8; fTaskFile.packet.byte_count_8_15 = ccb->data_length >> 8;
@@ -29,7 +29,9 @@
#define ATA_MAX_DMA_FAILURES 3 #define ATA_MAX_DMA_FAILURES 3
#define ATA_STANDARD_TIMEOUT 10 * 1000 * 1000 #define ATA_STANDARD_TIMEOUT 10 * 1000 * 1000
#define ATA_RELEASE_TIMEOUT 10 * 1000 * 1000 #define ATA_RELEASE_TIMEOUT 10 * 1000 * 1000
#define ATA_SIGNATURE_ATA 0x00000101
#define ATA_SIGNATURE_ATAPI 0xeb140101 #define ATA_SIGNATURE_ATAPI 0xeb140101
#define ATA_SIGNATURE_SATA 0xc33c0101
#define ATA_SIM_MODULE_NAME "bus_managers/ata/sim/driver_v1" #define ATA_SIM_MODULE_NAME "bus_managers/ata/sim/driver_v1"
#define ATA_CHANNEL_ID_GENERATOR "ata/channel_id" #define ATA_CHANNEL_ID_GENERATOR "ata/channel_id"
#define ATA_CHANNEL_ID_ITEM "ata/channel_id" #define ATA_CHANNEL_ID_ITEM "ata/channel_id"
@@ -41,7 +43,7 @@ enum {
ATA_CHECK_ERROR_BIT = 0x08, ATA_CHECK_ERROR_BIT = 0x08,
ATA_WAIT_FINISH = 0x10, ATA_WAIT_FINISH = 0x10,
ATA_WAIT_ANY_BIT = 0x20, ATA_WAIT_ANY_BIT = 0x20,
ATA_CHECK_DISK_FAILURE = 0x40 ATA_CHECK_DEVICE_FAULT = 0x40
}; };
@@ -75,9 +77,8 @@ public:
// ATA stuff // ATA stuff
status_t SelectDevice(uint8 index); status_t SelectDevice(uint8 index);
bool IsDevicePresent(uint8 index);
status_t Reset(bool *presence, uint32 *signatures); status_t Reset(uint32 *signatures);
bool UseDMA() { return fUseDMA; }; bool UseDMA() { return fUseDMA; };
@@ -268,6 +269,8 @@ public:
void SetBytesLeft(uint32 bytesLeft); void SetBytesLeft(uint32 bytesLeft);
size_t * BytesLeft() { return &fBytesLeft; }; size_t * BytesLeft() { return &fBytesLeft; };
bool HasData() { return fCCB->data_length > 0; };
status_t Finish(bool resubmit); status_t Finish(bool resubmit);
// SCSI stuff // SCSI stuff