Adding ATAPI support to the new ATA bus_manager. Only tested in QEMU.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30080 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -14,7 +14,7 @@ ATAChannel::ATAChannel(device_node *node)
|
||||
fChannelID(0),
|
||||
fController(NULL),
|
||||
fCookie(NULL),
|
||||
fExpectsDMATransfer(false),
|
||||
fExpectsInterrupt(false),
|
||||
fStatus(B_NO_INIT),
|
||||
fSCSIBus(NULL),
|
||||
fDeviceCount(0),
|
||||
@@ -23,8 +23,8 @@ ATAChannel::ATAChannel(device_node *node)
|
||||
fRequest(NULL)
|
||||
{
|
||||
mutex_init(&fExecutionLock, "ata io execution");
|
||||
B_INITIALIZE_SPINLOCK(&fDMATransferLock);
|
||||
fDMATransferCondition.Init(this, "ata dma transfer");
|
||||
B_INITIALIZE_SPINLOCK(&fInterruptLock);
|
||||
fInterruptCondition.Init(this, "ata dma transfer");
|
||||
|
||||
gDeviceManager->get_attr_uint32(node, ATA_CHANNEL_ID_ITEM, &fChannelID,
|
||||
true);
|
||||
@@ -234,6 +234,9 @@ ATAChannel::ExecuteIO(scsi_ccb *ccb)
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// we aren't a check sense request, clear sense data for new request
|
||||
fRequest->ClearSense();
|
||||
|
||||
if (ccb->target_id >= fDeviceCount) {
|
||||
TRACE_ERROR("invalid target device\n");
|
||||
fRequest->SetStatus(SCSI_SEL_TIMEOUT);
|
||||
@@ -393,7 +396,7 @@ ATAChannel::Wait(uint8 setBits, uint8 clearedBits, uint32 flags,
|
||||
_FlushAndWait(1);
|
||||
|
||||
while (true) {
|
||||
uint8 status = _AltStatus();
|
||||
uint8 status = AltStatus();
|
||||
if ((flags & ATA_CHECK_ERROR_BIT) != 0
|
||||
&& (status & ATA_STATUS_ERROR) != 0)
|
||||
return B_ERROR;
|
||||
@@ -443,7 +446,37 @@ ATAChannel::WaitDeviceReady()
|
||||
status_t
|
||||
ATAChannel::WaitForIdle()
|
||||
{
|
||||
return Wait(0, ATA_STATUS_BUSY | ATA_STATUS_DATA_REQUEST, 0, 20 * 1000);
|
||||
return Wait(0, ATA_STATUS_BUSY | ATA_STATUS_DATA_REQUEST, 0, 50 * 1000);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ATAChannel::PrepareWaitingForInterrupt()
|
||||
{
|
||||
TRACE_FUNCTION("\n");
|
||||
InterruptsSpinLocker locker(fInterruptLock);
|
||||
fExpectsInterrupt = true;
|
||||
fInterruptCondition.Add(&fInterruptConditionEntry);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ATAChannel::WaitForInterrupt(bigtime_t timeout)
|
||||
{
|
||||
TRACE_FUNCTION("timeout: %lld\n", timeout);
|
||||
status_t result = fInterruptConditionEntry.Wait(B_RELATIVE_TIMEOUT,
|
||||
timeout);
|
||||
|
||||
InterruptsSpinLocker locker(fInterruptLock);
|
||||
fExpectsInterrupt = false;
|
||||
locker.Unlock();
|
||||
|
||||
if (result != B_OK) {
|
||||
TRACE_ERROR("timeout waiting for interrupt\n");
|
||||
return B_TIMED_OUT;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -464,7 +497,7 @@ ATAChannel::SendRequest(ATARequest *request, uint32 flags)
|
||||
}
|
||||
|
||||
if ((flags & ATA_DEVICE_READY_REQUIRED) != 0
|
||||
&& (_AltStatus() & ATA_STATUS_DEVICE_READY) == 0) {
|
||||
&& (AltStatus() & ATA_STATUS_DEVICE_READY) == 0) {
|
||||
TRACE_ERROR("device ready not set\n");
|
||||
request->SetStatus(SCSI_SEQUENCE_FAIL);
|
||||
return B_ERROR;
|
||||
@@ -583,35 +616,16 @@ ATAChannel::PrepareDMA(ATARequest *request)
|
||||
|
||||
|
||||
status_t
|
||||
ATAChannel::FinishDMA()
|
||||
ATAChannel::StartDMA()
|
||||
{
|
||||
return fController->finish_dma(fCookie);
|
||||
return fController->start_dma(fCookie);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ATAChannel::ExecuteDMATransfer(ATARequest *request)
|
||||
ATAChannel::FinishDMA()
|
||||
{
|
||||
InterruptsSpinLocker locker(fDMATransferLock);
|
||||
fExpectsDMATransfer = true;
|
||||
ConditionVariableEntry entry;
|
||||
fDMATransferCondition.Add(&entry);
|
||||
locker.Unlock();
|
||||
|
||||
fController->start_dma(fCookie);
|
||||
bigtime_t timeout = system_time() + request->Timeout();
|
||||
status_t waitResult = entry.Wait(B_ABSOLUTE_TIMEOUT, timeout);
|
||||
|
||||
locker.Lock();
|
||||
fExpectsDMATransfer = false;
|
||||
locker.Unlock();
|
||||
|
||||
if (waitResult != B_OK) {
|
||||
TRACE_ERROR("timeout waiting for DMA transfer\n");
|
||||
return B_TIMED_OUT;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
return fController->finish_dma(fCookie);
|
||||
}
|
||||
|
||||
|
||||
@@ -646,7 +660,7 @@ ATAChannel::ExecutePIOTransfer(ATARequest *request)
|
||||
|
||||
// wait 1 pio cycle
|
||||
if (*blocksLeft > 0)
|
||||
_AltStatus();
|
||||
AltStatus();
|
||||
}
|
||||
|
||||
if (result == B_OK && WaitDataRequest(false) != B_OK) {
|
||||
@@ -658,6 +672,20 @@ ATAChannel::ExecutePIOTransfer(ATARequest *request)
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ATAChannel::ReadRegs(ATADevice *device)
|
||||
{
|
||||
return _ReadRegs(device->TaskFile(), device->RegisterMask());
|
||||
}
|
||||
|
||||
|
||||
uint8
|
||||
ATAChannel::AltStatus()
|
||||
{
|
||||
return fController->get_altstatus(fCookie);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ATAChannel::ReadPIO(uint8 *buffer, size_t length)
|
||||
{
|
||||
@@ -666,11 +694,19 @@ ATAChannel::ReadPIO(uint8 *buffer, size_t length)
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ATAChannel::WritePIO(uint8 *buffer, size_t length)
|
||||
{
|
||||
return fController->write_pio(fCookie, (uint16 *)buffer,
|
||||
length / sizeof(uint16), true);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ATAChannel::Interrupt(uint8 status)
|
||||
{
|
||||
SpinLocker locker(fDMATransferLock);
|
||||
if (!fExpectsDMATransfer) {
|
||||
SpinLocker locker(fInterruptLock);
|
||||
if (!fExpectsInterrupt) {
|
||||
TRACE_ERROR("interrupt when not expecting transfer\n");
|
||||
return;
|
||||
}
|
||||
@@ -680,7 +716,7 @@ ATAChannel::Interrupt(uint8 status)
|
||||
return;
|
||||
}
|
||||
|
||||
fDMATransferCondition.NotifyAll();
|
||||
fInterruptCondition.NotifyAll();
|
||||
}
|
||||
|
||||
|
||||
@@ -706,17 +742,10 @@ ATAChannel::_WriteControl(uint8 value)
|
||||
}
|
||||
|
||||
|
||||
uint8
|
||||
ATAChannel::_AltStatus()
|
||||
{
|
||||
return fController->get_altstatus(fCookie);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ATAChannel::_FlushAndWait(bigtime_t waitTime)
|
||||
{
|
||||
_AltStatus();
|
||||
AltStatus();
|
||||
if (waitTime > 100)
|
||||
snooze(waitTime);
|
||||
else
|
||||
@@ -749,7 +778,7 @@ ATAChannel::_ReadPIOBlock(ATARequest *request, size_t length)
|
||||
if (transferred >= length)
|
||||
return B_OK;
|
||||
|
||||
TRACE_ERROR("pio read: discarding after %lu bytes", transferred);
|
||||
TRACE_ERROR("pio read: discarding after %lu bytes\n", transferred);
|
||||
|
||||
uint8 buffer[32];
|
||||
length -= transferred;
|
||||
@@ -799,7 +828,7 @@ ATAChannel::_WritePIOBlock(ATARequest *request, size_t length)
|
||||
// only solution is to send zero bytes, though it's BAD
|
||||
static const uint8 buffer[32] = {};
|
||||
|
||||
TRACE_ERROR("pio write: discarding after %lu bytes", transferred);
|
||||
TRACE_ERROR("pio write: discarding after %lu bytes\n", transferred);
|
||||
|
||||
length -= transferred;
|
||||
while (length > 0) {
|
||||
|
||||
@@ -12,14 +12,14 @@
|
||||
|
||||
ATADevice::ATADevice(ATAChannel *channel, uint8 index)
|
||||
: fChannel(channel),
|
||||
fIndex(index),
|
||||
fUseLBA(false),
|
||||
fUse48Bits(false),
|
||||
fRegisterMask(0),
|
||||
fUseDMA(channel->UseDMA()),
|
||||
fDMAMode(0),
|
||||
fDMAFailures(0),
|
||||
fTotalSectors(0),
|
||||
fRegisterMask(0)
|
||||
fIndex(index),
|
||||
fUseLBA(false),
|
||||
fUse48Bits(false),
|
||||
fTotalSectors(0)
|
||||
{
|
||||
memset(&fInfoBlock, 0, sizeof(fInfoBlock));
|
||||
memset(&fTaskFile, 0, sizeof(fTaskFile));
|
||||
@@ -202,7 +202,6 @@ ATADevice::ExecuteIO(ATARequest *request)
|
||||
|
||||
TRACE("request: 0x%02x\n", ccb->cdb[0]);
|
||||
|
||||
request->ClearSense();
|
||||
switch (ccb->cdb[0]) {
|
||||
case SCSI_OP_TEST_UNIT_READY:
|
||||
return TestUnitReady(request);
|
||||
@@ -541,7 +540,10 @@ ATADevice::ExecuteReadWrite(ATARequest *request, uint64 address,
|
||||
}
|
||||
|
||||
if (request->UseDMA()) {
|
||||
result = fChannel->ExecuteDMATransfer(request);
|
||||
fChannel->PrepareWaitingForInterrupt();
|
||||
fChannel->StartDMA();
|
||||
|
||||
result = fChannel->WaitForInterrupt(request->Timeout());
|
||||
status_t dmaResult = fChannel->FinishDMA();
|
||||
if (result == B_OK && dmaResult == B_OK) {
|
||||
fDMAFailures = 0;
|
||||
|
||||
@@ -10,8 +10,7 @@
|
||||
#include "ATAPrivate.h"
|
||||
|
||||
ATAPIDevice::ATAPIDevice(ATAChannel *channel, uint8 index)
|
||||
: ATADevice(channel, index),
|
||||
fLastLun(1)
|
||||
: ATADevice(channel, index)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -21,10 +20,204 @@ ATAPIDevice::~ATAPIDevice()
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ATAPIDevice::SendPacket(ATARequest *request)
|
||||
{
|
||||
TRACE_FUNCTION("%p\n", request);
|
||||
|
||||
// only READ/WRITE commands can use DMA
|
||||
// (the device may support it always, but IDE controllers don't
|
||||
// report how much data is transmitted, and this information is
|
||||
// crucial for the SCSI protocol)
|
||||
// special offer: let READ_CD commands use DMA too
|
||||
uint8 command = fPacket[0];
|
||||
request->SetUseDMA(UseDMA()
|
||||
&& (command == SCSI_OP_READ_6 || command == SCSI_OP_WRITE_6
|
||||
|| command == SCSI_OP_READ_10 || command == SCSI_OP_WRITE_10
|
||||
|| command == SCSI_OP_READ_12 || command == SCSI_OP_WRITE_12
|
||||
|| command == SCSI_OP_READ_CD)
|
||||
&& fChannel->PrepareDMA(request) == B_OK);
|
||||
TRACE("using dma: %s\n", request->UseDMA() ? "yes" : "no");
|
||||
|
||||
if (!request->UseDMA())
|
||||
request->PrepareSGInfo();
|
||||
|
||||
if (_FillTaskFilePacket(request) != B_OK) {
|
||||
TRACE_ERROR("failed to setup transfer request\n");
|
||||
if (request->UseDMA())
|
||||
fChannel->FinishDMA();
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
if (fInterruptsForPacket)
|
||||
fChannel->PrepareWaitingForInterrupt();
|
||||
|
||||
status_t result = fChannel->SendRequest(request, ATA_DMA_TRANSFER);
|
||||
if (result != B_OK) {
|
||||
TRACE_ERROR("failed to send packet request\n");
|
||||
if (request->UseDMA())
|
||||
fChannel->FinishDMA();
|
||||
return result;
|
||||
}
|
||||
|
||||
// wait for device to get ready for packet transmission
|
||||
bool timedOut = false;
|
||||
if (fInterruptsForPacket)
|
||||
timedOut = fChannel->WaitForInterrupt(request->Timeout()) != B_OK;
|
||||
else {
|
||||
timedOut = fChannel->Wait(ATA_STATUS_DATA_REQUEST, ATA_STATUS_BUSY, 0,
|
||||
100 * 1000) != B_OK;
|
||||
}
|
||||
|
||||
if (timedOut) {
|
||||
TRACE_ERROR("timeout waiting for data request\n");
|
||||
if (request->UseDMA())
|
||||
fChannel->FinishDMA();
|
||||
|
||||
request->SetStatus(SCSI_SEQUENCE_FAIL);
|
||||
return B_TIMED_OUT;
|
||||
}
|
||||
|
||||
// make sure device really asks for command packet
|
||||
fRegisterMask = ATA_MASK_IREASON;
|
||||
fChannel->ReadRegs(this);
|
||||
|
||||
if (!fTaskFile.packet_res.cmd_or_data
|
||||
|| fTaskFile.packet_res.input_or_output) {
|
||||
TRACE_ERROR("device doesn't ask for packet\n");
|
||||
if (request->UseDMA())
|
||||
fChannel->FinishDMA();
|
||||
|
||||
request->SetStatus(SCSI_SEQUENCE_FAIL);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// some old drives need a delay before submitting the packet
|
||||
spin(10);
|
||||
|
||||
fChannel->PrepareWaitingForInterrupt();
|
||||
|
||||
// write packet
|
||||
if (fChannel->WritePIO(fPacket, sizeof(fPacket)) != B_OK) {
|
||||
TRACE_ERROR("failed to write packet\n");
|
||||
if (request->UseDMA())
|
||||
fChannel->FinishDMA();
|
||||
|
||||
request->SetStatus(SCSI_HBA_ERR);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
if (request->UseDMA()) {
|
||||
fChannel->StartDMA();
|
||||
result = fChannel->WaitForInterrupt(request->Timeout());
|
||||
status_t dmaResult = fChannel->FinishDMA();
|
||||
if (result == B_OK && dmaResult == B_OK) {
|
||||
fDMAFailures = 0;
|
||||
request->CCB()->data_resid = 0;
|
||||
} else {
|
||||
if (dmaResult != B_OK) {
|
||||
request->SetSense(SCSIS_KEY_HARDWARE_ERROR,
|
||||
SCSIS_ASC_LUN_COM_FAILURE);
|
||||
fDMAFailures++;
|
||||
if (fDMAFailures >= ATA_MAX_DMA_FAILURES) {
|
||||
TRACE_ALWAYS("disabling DMA after %u failures\n",
|
||||
fDMAFailures);
|
||||
fUseDMA = false;
|
||||
}
|
||||
} else {
|
||||
// timeout
|
||||
request->SetStatus(SCSI_CMD_TIMEOUT);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
result = fChannel->WaitForInterrupt(request->Timeout());
|
||||
if (result != B_OK) {
|
||||
TRACE_ERROR("timeout waiting for device to request data\n");
|
||||
request->SetStatus(SCSI_SEQUENCE_FAIL);
|
||||
return B_TIMED_OUT;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
uint8 altStatus = fChannel->AltStatus();
|
||||
if ((altStatus & ATA_STATUS_DATA_REQUEST) == 0)
|
||||
break;
|
||||
|
||||
fRegisterMask = ATA_MASK_ERROR | ATA_MASK_IREASON;
|
||||
fChannel->ReadRegs(this);
|
||||
|
||||
if (fTaskFile.packet_res.cmd_or_data) {
|
||||
TRACE_ERROR("device expecting command instead of data\n");
|
||||
request->SetStatus(SCSI_SEQUENCE_FAIL);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
fRegisterMask = ATA_MASK_BYTE_COUNT;
|
||||
fChannel->ReadRegs(this);
|
||||
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->SetBlocksLeft((length + 511) / 512);
|
||||
if (fChannel->ExecutePIOTransfer(request) != B_OK) {
|
||||
TRACE_ERROR("failed to transfer data\n");
|
||||
request->SetStatus(SCSI_SEQUENCE_FAIL);
|
||||
return B_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fChannel->FinishRequest(request, ATA_WAIT_FINISH, ATA_ERROR_ABORTED);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ATAPIDevice::ExecuteIO(ATARequest *request)
|
||||
{
|
||||
request->SetStatus(SCSI_SEL_TIMEOUT);
|
||||
request->SetSense(SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_CDB_FIELD);
|
||||
return B_ERROR;
|
||||
scsi_ccb *ccb = request->CCB();
|
||||
if (ccb->target_lun > fInfoBlock.last_lun) {
|
||||
TRACE_ERROR("invalid target lun %d, last lun is %d\n", ccb->target_lun,
|
||||
fInfoBlock.last_lun);
|
||||
request->SetStatus(SCSI_SEL_TIMEOUT);
|
||||
return B_BAD_INDEX;
|
||||
}
|
||||
|
||||
// ATAPI command packets are 12 bytes long;
|
||||
// if the command is shorter, remaining bytes must be padded with zeros
|
||||
memset(fPacket, 0, sizeof(fPacket));
|
||||
memcpy(fPacket, ccb->cdb, ccb->cdb_length);
|
||||
|
||||
request->SetDevice(this);
|
||||
request->SetIsWrite((ccb->flags & SCSI_DIR_MASK) == SCSI_DIR_OUT);
|
||||
return SendPacket(request);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ATAPIDevice::Configure()
|
||||
{
|
||||
if (fInfoBlock._0.atapi.ATAPI != 2)
|
||||
return B_ERROR;
|
||||
|
||||
fTaskFile.packet.lun = 0;
|
||||
fInterruptsForPacket = fInfoBlock._0.atapi.drq_speed == 1;
|
||||
|
||||
status_t result = ConfigureDMA();
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ATAPIDevice::_FillTaskFilePacket(ATARequest *request)
|
||||
{
|
||||
scsi_ccb *ccb = request->CCB();
|
||||
fRegisterMask = ATA_MASK_FEATURES | ATA_MASK_BYTE_COUNT;
|
||||
fTaskFile.packet.dma = request->UseDMA();
|
||||
fTaskFile.packet.ovl = 0;
|
||||
fTaskFile.packet.byte_count_0_7 = ccb->data_length & 0xff;
|
||||
fTaskFile.packet.byte_count_8_15 = ccb->data_length >> 8;
|
||||
fTaskFile.packet.command = ATA_COMMAND_PACKET;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -85,6 +85,9 @@ public:
|
||||
status_t WaitDeviceReady();
|
||||
status_t WaitForIdle();
|
||||
|
||||
void PrepareWaitingForInterrupt();
|
||||
status_t WaitForInterrupt(bigtime_t timeout);
|
||||
|
||||
// request handling
|
||||
status_t SendRequest(ATARequest *request,
|
||||
uint32 flags);
|
||||
@@ -93,12 +96,16 @@ public:
|
||||
|
||||
// data transfers
|
||||
status_t PrepareDMA(ATARequest *request);
|
||||
status_t StartDMA();
|
||||
status_t FinishDMA();
|
||||
|
||||
status_t ExecuteDMATransfer(ATARequest *request);
|
||||
status_t ExecutePIOTransfer(ATARequest *request);
|
||||
|
||||
status_t ReadRegs(ATADevice *device);
|
||||
uint8 AltStatus();
|
||||
|
||||
status_t ReadPIO(uint8 *buffer, size_t length);
|
||||
status_t WritePIO(uint8 *buffer, size_t length);
|
||||
|
||||
void Interrupt(uint8 status);
|
||||
|
||||
@@ -109,7 +116,6 @@ private:
|
||||
ata_reg_mask mask);
|
||||
status_t _WriteControl(uint8 value);
|
||||
|
||||
uint8 _AltStatus();
|
||||
void _FlushAndWait(bigtime_t waitTime);
|
||||
|
||||
status_t _ReadPIOBlock(ATARequest *request,
|
||||
@@ -133,9 +139,10 @@ private:
|
||||
void * fCookie;
|
||||
|
||||
mutex fExecutionLock;
|
||||
spinlock fDMATransferLock;
|
||||
ConditionVariable fDMATransferCondition;
|
||||
bool fExpectsDMATransfer;
|
||||
spinlock fInterruptLock;
|
||||
ConditionVariable fInterruptCondition;
|
||||
ConditionVariableEntry fInterruptConditionEntry;
|
||||
bool fExpectsInterrupt;
|
||||
|
||||
status_t fStatus;
|
||||
scsi_bus fSCSIBus;
|
||||
@@ -179,29 +186,32 @@ virtual bool IsATAPI() { return false; };
|
||||
status_t DisableCommandQueueing();
|
||||
status_t ConfigureDMA();
|
||||
|
||||
status_t Configure();
|
||||
virtual status_t Configure();
|
||||
status_t Identify();
|
||||
|
||||
status_t ExecuteReadWrite(ATARequest *request,
|
||||
uint64 address, uint32 sectorCount);
|
||||
|
||||
protected:
|
||||
const char * _DebugContext() { return fDebugContext; };
|
||||
|
||||
ATAChannel * fChannel;
|
||||
ata_device_infoblock fInfoBlock;
|
||||
ata_task_file fTaskFile;
|
||||
ata_reg_mask fRegisterMask;
|
||||
|
||||
bool fUseDMA;
|
||||
uint8 fDMAMode;
|
||||
uint8 fDMAFailures;
|
||||
|
||||
private:
|
||||
status_t _FillTaskFile(ATARequest *request,
|
||||
uint64 address);
|
||||
|
||||
const char * _DebugContext() { return fDebugContext; };
|
||||
|
||||
ATAChannel * fChannel;
|
||||
uint8 fIndex;
|
||||
bool fUseLBA;
|
||||
bool fUse48Bits;
|
||||
bool fUseDMA;
|
||||
uint8 fDMAMode;
|
||||
uint8 fDMAFailures;
|
||||
uint64 fTotalSectors;
|
||||
ata_device_infoblock fInfoBlock;
|
||||
ata_task_file fTaskFile;
|
||||
ata_reg_mask fRegisterMask;
|
||||
|
||||
char fDebugContext[16];
|
||||
};
|
||||
@@ -213,12 +223,18 @@ public:
|
||||
uint8 index);
|
||||
virtual ~ATAPIDevice();
|
||||
|
||||
status_t SendPacket(ATARequest *request);
|
||||
virtual status_t ExecuteIO(ATARequest *request);
|
||||
|
||||
virtual bool IsATAPI() { return true; };
|
||||
|
||||
virtual status_t Configure();
|
||||
|
||||
private:
|
||||
uint8 fLastLun;
|
||||
status_t _FillTaskFilePacket(ATARequest *request);
|
||||
|
||||
bool fInterruptsForPacket;
|
||||
uint8 fPacket[12];
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user