44 m_pCommandRegs(nullptr),
45 m_pControlRegs(nullptr),
46 m_PciControllerType(UnknownController),
49 m_nController(nController) {
58 m_PciControllerType = PIIX;
62 m_PciControllerType = PIIX3;
66 m_PciControllerType = PIIX4;
70 m_PciControllerType = ICH;
74 m_PciControllerType = ICH0;
79 m_PciControllerType = ICH2;
84 m_PciControllerType = ICH3;
89 m_PciControllerType = ICH4;
93 m_PciControllerType = ICH5;
97 m_PciControllerType = UnknownController;
101 str +=
" PCI IDE controller found";
102 NOTICE(
static_cast<const char*
>(str));
104 if (m_PciControllerType == UnknownController)
109 for (
size_t i = 0; i <
addresses().count(); i++) {
110 if (!StringCompare(
static_cast<const char*
>(
addresses()[i]->m_Name),
"bar4"))
119 uint32_t busMasterIfaceAddr = PciBus::instance().
readConfigSpace(pDev, 8);
120 busMasterIfaceAddr &= 0xFFFF000F;
121 busMasterIfaceAddr |= bar4->
m_Address & 0xFFF0;
122 NOTICE(
" - Bus master interface base register at " << bar4->
m_Address);
129 commandReg = (commandReg & ~(0x7)) | 0x7;
135 uint32_t ideTiming = 0xB3FF;
137 ideTiming |= (ideTiming << 16);
142 if (m_PciControllerType == PIIX) {
155 if (m_PciControllerType == PIIX4) {
163 uint16_t target_timings = 0x2 * 0x3333;
164 timings = (timings & 0xFFFF) | target_timings;
173 NOTICE(
" - This is a DMA capable controller");
177#if !KERNEL_PROCESSOR_NO_PORT_IO
178 IoPort* masterCommand =
new IoPort(
"pci-ide-master-cmd");
180 IoPort* masterControl =
new IoPort(
"pci-ide-master-ctl");
196 bar4_a =
new IoPort(
"pci-ide-busmaster-primary");
198 ERROR(
"Couldn't allocate primary BusMaster ports");
203 bar4_b =
new IoPort(
"pci-ide-busmaster-secondary");
204 if (!bar4_b->
allocate(addr + 8, 8)) {
205 ERROR(
"Couldn't allocate secondary BusMaster ports");
214 ERROR(
"Couldn't initialise primary BusMaster IDE interface");
215 delete primaryBusMaster;
218 primaryBusMaster = 0;
223 if (!secondaryBusMaster->
initialise(bar4_b)) {
224 ERROR(
"Couldn't initialise secondary BusMaster IDE interface");
225 delete secondaryBusMaster;
228 secondaryBusMaster = 0;
235 if (!masterCommand->
allocate(0x1F0, 8))
236 ERROR(
"Couldn't allocate master command ports");
237 if (!masterControl->
allocate(0x3F4, 4))
238 ERROR(
"Couldn't allocate master control ports");
239 if (!slaveCommand->
allocate(0x170, 8))
240 ERROR(
"Couldn't allocate slave command ports");
241 if (!slaveControl->
allocate(0x374, 4))
242 ERROR(
"Couldn't allocate slave control ports");
245 AtaStatus masterStatus = ataWait(masterCommand, masterControl);
246 AtaStatus slaveStatus = ataWait(slaveCommand, slaveControl);
248 delete masterCommand;
249 delete masterControl;
262 masterControl->
write8(0x6, 2);
265 masterControl->
write8(0x2, 2);
268 slaveControl->
write8(0x6, 2);
270 slaveControl->
write8(0x2, 2);
273 Time::delay(2 * Time::Multiplier::Millisecond);
276 ataWait(masterCommand, masterControl);
278 ataWait(slaveCommand, slaveControl);
283 static_cast<IrqHandler*
>(
this),
this, IrqPolicy::pciIntxThreaded());
285 m_IrqIds[m_IrqCount++] = irqId;
290 size_t primaryIrq = 14, secondaryIrq = 15;
293 primaryIrq,
static_cast<IrqHandler*
>(
this), IrqPolicy::edgeThreaded());
295 m_IrqIds[m_IrqCount++] = irqId;
300 secondaryIrq,
static_cast<IrqHandler*
>(
this), IrqPolicy::edgeThreaded());
302 m_IrqIds[m_IrqCount++] = irqId;
308 diskHelper(
true, masterCommand, masterControl, primaryBusMaster, primaryIrq);
309 diskHelper(
false, masterCommand, masterControl, primaryBusMaster, primaryIrq);
313 diskHelper(
true, slaveCommand, slaveControl, secondaryBusMaster, secondaryIrq);
314 diskHelper(
false, slaveCommand, slaveControl, secondaryBusMaster, secondaryIrq);
317 ERROR(
"PCI ATA: no good, this machine has no port I/O");
382 uint64_t p5, uint64_t p6, uint64_t p7, uint64_t p8) {
384 if (p1 == SCSI_REQUEST_PAGING) {
386 request->result = pDisk->doPagingTransfer(request->operation, request->offset, request->page);
387 return request->result == PagingStatus::Success;
389 if (p1 == SCSI_REQUEST_READ)
391 else if (p1 == SCSI_REQUEST_WRITE)
393 else if (p1 == SCSI_REQUEST_WRITE_DIRECT)
395 else if (p1 == SCSI_REQUEST_SYNC)
396 return pDisk->doSync(p3);