20#include "IsaAtaController.h"
21#include "pedigree/kernel/Log.h"
22#include "pedigree/kernel/machine/Device.h"
23#include "pedigree/kernel/machine/IrqManager.h"
24#include "pedigree/kernel/machine/Machine.h"
25#include "pedigree/kernel/processor/IoBase.h"
26#include "pedigree/kernel/time/Time.h"
27#include "pedigree/kernel/utilities/Vector.h"
28#include "pedigree/kernel/utilities/new"
31#include "modules/drivers/common/scsi/ScsiController.h"
35IsaAtaController::IsaAtaController(
Controller* pDev,
int nController)
40 bool bPortsFound =
false;
41 for (
unsigned int i = 0; i <
m_Addresses.count(); i++) {
53 ERROR(
"ISA ATA: No addresses found for this controller");
58 if (m_pControlRegs->read8(6) == 0xFF || m_pCommandRegs->read8(7) == 0xFF) {
69 m_pControlRegs->write8(0x04, 6);
70 Time::delay(5 * Time::Multiplier::Millisecond);
72 m_pControlRegs->write8(0, 6);
73 Time::delay(5 * Time::Multiplier::Millisecond);
77 const AtaStatus status = ataWait(m_pCommandRegs, m_pControlRegs);
78 if (status.reg.err || status.reg.bsy) {
79 NOTICE(
"Error during ATA software reset, status = " << status.__reg_contents);
84 AtaDisk* pMaster =
new AtaDisk(
this,
true, m_pCommandRegs, m_pControlRegs);
85 AtaDisk* pSlave =
new AtaDisk(
this,
false, m_pCommandRegs, m_pControlRegs);
96 bool masterInitialised = pMaster->
initialise(masterN);
97 bool slaveInitialised = pSlave->
initialise(slaveN);
102 if (!masterInitialised) {
107 if (!slaveInitialised) {
113IsaAtaController::~IsaAtaController() {
118 if (!beginShutdown()) {
126 if (m_IrqId && !Machine::instance().getIrqManager()->unregisterHandler(
128 FATAL(
"ISA ATA controller could not drain its IRQ handler");
135bool IsaAtaController::sendCommand(
size_t nUnit, uintptr_t pCommand, uint8_t nCommandSize,
136 uintptr_t pRespBuffer, uint16_t nRespBytes,
bool bWrite) {
139 ERROR(
"ISA ATA: sendCommand called with a bad unit number.");
144 return pDisk->sendCommand(nUnit, pCommand, nCommandSize, pRespBuffer, nRespBytes, bWrite);
148 uint64_t p5, uint64_t p6, uint64_t p7, uint64_t p8) {
150 if (p1 == SCSI_REQUEST_READ)
152 else if (p1 == SCSI_REQUEST_WRITE)
154 else if (p1 == SCSI_REQUEST_WRITE_DIRECT)
156 else if (p1 == SCSI_REQUEST_SYNC)
157 return pDisk->doSync(p3);
168 return IrqDisposition::Handled;
void maskDiskInterrupts()
virtual MUST_USE_RESULT uint64_t doWriteDirect(uint64_t location, uintptr_t page)
virtual uint64_t doWrite(uint64_t location)
bool initialise(size_t nUnit=~0)
virtual uint64_t doRead(uint64_t location)
virtual void irqReceived()
Device * getChild(size_t n)
virtual void setInterruptNumber(uintptr_t n)
void addChild(Device *pDevice)
virtual void setSpecificType(String str)
Vector< Address * > m_Addresses
Vector< Device * > m_Children
virtual uintptr_t getInterruptNumber()
void removeChild(size_t n)
virtual irq_id_t registerIsaIrqHandler(uint8_t irq, IrqHandler *handler, const IrqPolicy &policy)=0
virtual IrqDisposition irq(irq_id_t number)
virtual uint64_t executeRequest(uint64_t p1, uint64_t p2, uint64_t p3, uint64_t p4, uint64_t p5, uint64_t p6, uint64_t p7, uint64_t p8)
void shutdownDiskCaches(bool deviceAvailable=true)
void clear(bool freeMem=false)