idedrv Implement DMA reading/writing without IRQ support
This commit is contained in:
@@ -57,7 +57,9 @@ static void ide_make_device(struct proc* proc, struct reschedule_ctx* rctx,
|
||||
.ctrl = probe.ctrl,
|
||||
.devno = probe.devno,
|
||||
.irq = probe.irq,
|
||||
.bmbase = probe.bmbase,
|
||||
.irqs_support = probe.irqs_support,
|
||||
.bm_support = probe.bm_support,
|
||||
};
|
||||
|
||||
struct device* ide = device_create(DEVICE_TYPE_DRIVE, device_key, ops, lengthof(ops),
|
||||
@@ -68,7 +70,10 @@ static void ide_make_device(struct proc* proc, struct reschedule_ctx* rctx,
|
||||
bool pci_ide_init(struct proc* proc, struct reschedule_ctx* rctx, struct pci_info pci_info) {
|
||||
uint16_t pci_cmd = pci_read16(pci_info.bus, pci_info.slot, pci_info.func, PCI_COMMAND);
|
||||
|
||||
uint16_t new_cmd = (pci_cmd | (1 << 0) | (1 << 2)) & ~(1 << 10);
|
||||
uint16_t new_cmd = pci_cmd;
|
||||
new_cmd |= (1 << PCI_CMD_IOSPACE);
|
||||
new_cmd |= (1 << PCI_CMD_BUSMASTER);
|
||||
new_cmd &= ~(1 << PCI_CMD_INTRDISABLE);
|
||||
|
||||
if (pci_cmd != new_cmd) {
|
||||
pci_write16(pci_info.bus, pci_info.slot, pci_info.func, PCI_COMMAND, new_cmd);
|
||||
@@ -79,7 +84,14 @@ bool pci_ide_init(struct proc* proc, struct reschedule_ctx* rctx, struct pci_inf
|
||||
uint8_t progif = pci_read8(pci_info.bus, pci_info.slot, pci_info.func, PCI_PROG_IF);
|
||||
DEBUG("progif: %s\n", progif_msg[progif]);
|
||||
|
||||
uint16_t pcmd, pctrl, scmd, sctrl;
|
||||
uint16_t pcmd, pctrl, pbmbase, scmd, sctrl, sbmbase;
|
||||
bool irqs_support = false;
|
||||
bool bm_support = false;
|
||||
|
||||
uint32_t bar4 = pci_read32(pci_info.bus, pci_info.slot, pci_info.func, PCI_BAR4);
|
||||
uint16_t bmbase = (uint16_t)(bar4 & 0xFFFC);
|
||||
|
||||
bm_support = (bmbase != 0) && (bar4 & PCI_BAR_IO);
|
||||
|
||||
if ((progif & 0x01)) {
|
||||
uint32_t bar0 = pci_read32(pci_info.bus, pci_info.slot, pci_info.func, PCI_BAR0);
|
||||
@@ -99,6 +111,7 @@ bool pci_ide_init(struct proc* proc, struct reschedule_ctx* rctx, struct pci_inf
|
||||
pcmd = 0x1F0;
|
||||
pctrl = 0x3F6;
|
||||
}
|
||||
pbmbase = bmbase;
|
||||
|
||||
if ((progif & 0x04)) {
|
||||
uint32_t bar2 = pci_read32(pci_info.bus, pci_info.slot, pci_info.func, PCI_BAR2);
|
||||
@@ -118,8 +131,7 @@ bool pci_ide_init(struct proc* proc, struct reschedule_ctx* rctx, struct pci_inf
|
||||
scmd = 0x170;
|
||||
sctrl = 0x376;
|
||||
}
|
||||
|
||||
bool irqs_support = false;
|
||||
sbmbase = bmbase + 8;
|
||||
|
||||
if ((progif & 0x05)) {
|
||||
irqs_support = false;
|
||||
@@ -134,17 +146,18 @@ bool pci_ide_init(struct proc* proc, struct reschedule_ctx* rctx, struct pci_inf
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG("pcmd=%x, pctrl=%x\n", pcmd, pctrl);
|
||||
DEBUG("scmd=%x, sctrl=%x\n", scmd, sctrl);
|
||||
DEBUG("IRQ support=%d\n", irqs_support);
|
||||
DEBUG("pcmd=%x, pctrl=%x, pbmbase=%x\n", pcmd, pctrl, pbmbase);
|
||||
DEBUG("scmd=%x, sctrl=%x, sbmbase=%x\n", scmd, sctrl, sbmbase);
|
||||
DEBUG("IRQ support=%d, Bus mastering supported=%d\n", irqs_support, bm_support);
|
||||
|
||||
uint16_t channels[2][3] = {{pcmd, pctrl, INTR_IDE_DRIVE_PRIM},
|
||||
{scmd, sctrl, INTR_IDE_DRIVE_SCND}};
|
||||
uint16_t channels[2][4] = {{pcmd, pctrl, INTR_IDE_DRIVE_PRIM, pbmbase},
|
||||
{scmd, sctrl, INTR_IDE_DRIVE_SCND, sbmbase}};
|
||||
|
||||
for (size_t i = 0; i < lengthof(channels); i++) {
|
||||
uint16_t cmd = channels[i][0];
|
||||
uint16_t ctrl = channels[i][1];
|
||||
uint8_t irq = channels[i][2];
|
||||
uint16_t bmbase = channels[i][3];
|
||||
|
||||
for (size_t dev = 0; dev < 2; dev++) {
|
||||
ide_probe(cmd, ctrl, dev, &probe);
|
||||
@@ -153,6 +166,8 @@ bool pci_ide_init(struct proc* proc, struct reschedule_ctx* rctx, struct pci_inf
|
||||
probe.io = cmd;
|
||||
probe.irq = irq;
|
||||
probe.irqs_support = irqs_support;
|
||||
probe.bmbase = bmbase;
|
||||
probe.bm_support = bm_support;
|
||||
|
||||
if ((probe.flags & IDE_PROBE_AVAIL))
|
||||
ide_make_device(proc, rctx, probe);
|
||||
|
||||
Reference in New Issue
Block a user