aboutsummaryrefslogtreecommitdiff
path: root/src/ata.c
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2011-06-19 09:43:20 -0400
committerKevin O'Connor <kevin@koconnor.net>2011-06-19 10:10:39 -0400
commit927d16e576511cf14241e850028abec7d007f203 (patch)
treee27f93324022b203cb80dc2499eedcff64e7e76d /src/ata.c
parent6e4583c4a4a72fcb5914e59c8f1c534aceafbd44 (diff)
downloadseabios-hppa-927d16e576511cf14241e850028abec7d007f203.zip
seabios-hppa-927d16e576511cf14241e850028abec7d007f203.tar.gz
seabios-hppa-927d16e576511cf14241e850028abec7d007f203.tar.bz2
Convert ATA pci scan to use pci_device_id table.
Diffstat (limited to 'src/ata.c')
-rw-r--r--src/ata.c104
1 files changed, 56 insertions, 48 deletions
diff --git a/src/ata.c b/src/ata.c
index 397e402..1540565 100644
--- a/src/ata.c
+++ b/src/ata.c
@@ -941,14 +941,15 @@ ata_detect(void *data)
// Initialize an ata controller and detect its drives.
static void
-init_controller(int chanid, int bdf, int irq, u32 port1, u32 port2, u32 master)
+init_controller(int bdf, int irq, u32 port1, u32 port2, u32 master)
{
+ static int chanid = 0;
struct ata_channel_s *chan_gf = malloc_fseg(sizeof(*chan_gf));
if (!chan_gf) {
warn_noalloc();
return;
}
- chan_gf->chanid = chanid;
+ chan_gf->chanid = chanid++;
chan_gf->irq = irq;
chan_gf->pci_bdf = bdf;
chan_gf->iobase1 = port1;
@@ -962,66 +963,73 @@ init_controller(int chanid, int bdf, int irq, u32 port1, u32 port2, u32 master)
#define IRQ_ATA1 14
#define IRQ_ATA2 15
+// Handle controllers on an ATA PCI device.
+static void
+init_pciata(u16 bdf, void *arg)
+{
+ u8 pciirq = pci_config_readb(bdf, PCI_INTERRUPT_LINE);
+ u8 prog_if = pci_config_readb(bdf, PCI_CLASS_PROG);
+ int master = 0;
+ if (CONFIG_ATA_DMA && prog_if & 0x80) {
+ // Check for bus-mastering.
+ u32 bar = pci_config_readl(bdf, PCI_BASE_ADDRESS_4);
+ if (bar & PCI_BASE_ADDRESS_SPACE_IO) {
+ master = bar & PCI_BASE_ADDRESS_IO_MASK;
+ pci_config_maskw(bdf, PCI_COMMAND, 0, PCI_COMMAND_MASTER);
+ }
+ }
+
+ u32 port1, port2, irq;
+ if (prog_if & 1) {
+ port1 = (pci_config_readl(bdf, PCI_BASE_ADDRESS_0)
+ & PCI_BASE_ADDRESS_IO_MASK);
+ port2 = (pci_config_readl(bdf, PCI_BASE_ADDRESS_1)
+ & PCI_BASE_ADDRESS_IO_MASK);
+ irq = pciirq;
+ } else {
+ port1 = PORT_ATA1_CMD_BASE;
+ port2 = PORT_ATA1_CTRL_BASE;
+ irq = IRQ_ATA1;
+ }
+ init_controller(bdf, irq, port1, port2, master);
+
+ if (prog_if & 4) {
+ port1 = (pci_config_readl(bdf, PCI_BASE_ADDRESS_2)
+ & PCI_BASE_ADDRESS_IO_MASK);
+ port2 = (pci_config_readl(bdf, PCI_BASE_ADDRESS_3)
+ & PCI_BASE_ADDRESS_IO_MASK);
+ irq = pciirq;
+ } else {
+ port1 = PORT_ATA2_CMD_BASE;
+ port2 = PORT_ATA2_CTRL_BASE;
+ irq = IRQ_ATA2;
+ }
+ init_controller(bdf, irq, port1, port2, master ? master + 8 : 0);
+}
+
+static const struct pci_device_id pci_ata_tbl[] = {
+ PCI_DEVICE_CLASS(PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE, init_pciata),
+ PCI_DEVICE_END,
+};
+
// Locate and init ata controllers.
static void
ata_init(void)
{
// Scan PCI bus for ATA adapters
- int count=0, pcicount=0;
+ int pcicount=0;
int bdf, max;
foreachpci(bdf, max) {
pcicount++;
- if (pci_config_readw(bdf, PCI_CLASS_DEVICE) != PCI_CLASS_STORAGE_IDE)
- continue;
-
- u8 pciirq = pci_config_readb(bdf, PCI_INTERRUPT_LINE);
- u8 prog_if = pci_config_readb(bdf, PCI_CLASS_PROG);
- int master = 0;
- if (CONFIG_ATA_DMA && prog_if & 0x80) {
- // Check for bus-mastering.
- u32 bar = pci_config_readl(bdf, PCI_BASE_ADDRESS_4);
- if (bar & PCI_BASE_ADDRESS_SPACE_IO) {
- master = bar & PCI_BASE_ADDRESS_IO_MASK;
- pci_config_maskw(bdf, PCI_COMMAND, 0, PCI_COMMAND_MASTER);
- }
- }
-
- u32 port1, port2, irq;
- if (prog_if & 1) {
- port1 = (pci_config_readl(bdf, PCI_BASE_ADDRESS_0)
- & PCI_BASE_ADDRESS_IO_MASK);
- port2 = (pci_config_readl(bdf, PCI_BASE_ADDRESS_1)
- & PCI_BASE_ADDRESS_IO_MASK);
- irq = pciirq;
- } else {
- port1 = PORT_ATA1_CMD_BASE;
- port2 = PORT_ATA1_CTRL_BASE;
- irq = IRQ_ATA1;
- }
- init_controller(count, bdf, irq, port1, port2, master);
- count++;
-
- if (prog_if & 4) {
- port1 = (pci_config_readl(bdf, PCI_BASE_ADDRESS_2)
- & PCI_BASE_ADDRESS_IO_MASK);
- port2 = (pci_config_readl(bdf, PCI_BASE_ADDRESS_3)
- & PCI_BASE_ADDRESS_IO_MASK);
- irq = pciirq;
- } else {
- port1 = PORT_ATA2_CMD_BASE;
- port2 = PORT_ATA2_CTRL_BASE;
- irq = IRQ_ATA2;
- }
- init_controller(count, bdf, irq, port1, port2, master ? master + 8 : 0);
- count++;
+ pci_init_device(pci_ata_tbl, bdf, NULL);
}
if (!CONFIG_COREBOOT && !pcicount) {
// No PCI devices found - probably a QEMU "-M isapc" machine.
// Try using ISA ports for ATA controllers.
- init_controller(0, -1, IRQ_ATA1
+ init_controller(-1, IRQ_ATA1
, PORT_ATA1_CMD_BASE, PORT_ATA1_CTRL_BASE, 0);
- init_controller(1, -1, IRQ_ATA2
+ init_controller(-1, IRQ_ATA2
, PORT_ATA2_CMD_BASE, PORT_ATA2_CTRL_BASE, 0);
}
}