Patch not signed off since I haven't tested this at all.

I would appreciate test results from using this patch on boards which
have both SATA controller(s) and one or more PATA controllers in
compatibility (AKA legacy) mode.

Previously it was not possible to boot from a drive on a PATA
controller in compat mode when there were PCI devices in native
mode (SATA always are) on lower devfn numbers. Native mode devices
were basically still assumed to use the legacy IO ports in the code
looking up IO ports for compat devices.

Please set DEBUG_IDE=1 in Config and send output to me or the list.

Thanks!


//Peter
Index: include/pci.h
===================================================================
--- include/pci.h	(revision 48)
+++ include/pci.h	(working copy)
@@ -32,5 +32,6 @@
 
 void pci_init(void);
 struct pci_dev *pci_find_device(int vendor, int device, int devclass, int prog_if, int index);
+struct pci_dev *pci_find_ata_device(int vendor, int device, int prog_if, int index);
 
 #endif /* PCI_H */
Index: main/pci.c
===================================================================
--- main/pci.c	(revision 48)
+++ main/pci.c	(working copy)
@@ -107,3 +107,20 @@
     }
     return NULL;
 }
+
+struct pci_dev *pci_find_ata_device(int vendor, int device, int prog_if, int index)
+{
+    struct pci_dev *dev;
+
+    for (dev = dev_list; dev < dev_list + n_devs; dev++) {
+	if (vendor < 0 || vendor==dev->vendor)
+	    if (device < 0 || device==dev->device)
+		if (0x0180 == dev->devclass || 0x0101 == dev->devclass)
+		    if (prog_if < 0 || prog_if==dev->prog_if) {
+			if (index == 0)
+			    return dev;
+			index--;
+		    }
+    }
+    return NULL;
+}
Index: drivers/ide.c
===================================================================
--- drivers/ide.c	(revision 48)
+++ drivers/ide.c	(working copy)
@@ -1078,8 +1078,13 @@
 
 static int find_ide_controller_compat(struct controller *ctrl, int index)
 {
+#ifdef SUPPORT_PCI
+	int skip, i, pci_index = index / 2;
+	struct pci_dev *dev;
+#else
 	if (index >= IDE_MAX_CONTROLLERS)
 		return -1;
+#endif
 #ifdef PCMCIA_CF
 	if (index == 2) {
 		ctrl->cmd_base = 0x1e0;
@@ -1087,6 +1092,33 @@
 		return 0;
 	}
 #endif
+#ifdef SUPPORT_PCI
+	/* skip any SATA and PATA PCI controllers in native mode */
+	for (skip = i = 0; i < pci_index && index; i++) {
+		/* look for i:th ata (well storage really) device */
+		dev = pci_find_ata_device(-1, -1, -1, i);
+		/* stop if none is found */
+		if (!dev)
+			break;
+		/* only IDE/PATA can be in compat mode so skip all others */
+		if (0x0101 != dev->devclass) {
+			skip += 2;
+			continue;
+		}
+		/* master in native mode? then don't count it. */
+		if (1 == (dev->prog_if & 1))
+			skip++;
+		/* slave in native mode? then don't count it. */
+		if (index && 4 == (dev->prog_if & 4))
+			skip++;
+	}
+	debug("%s: skipping %d native PCI ATA controllers\n", __func__, skip);
+	index = skip <= index ? index - skip : 0;
+	debug("%s: new index = %d\n", index);
+	if (index >= IDE_MAX_CONTROLLERS)
+		return -1;
+#endif
+	debug("%s: using ide_base[%d] = 0x%x\n", index, ide_base[index]);
 	ctrl->cmd_base  = ide_base[index];
 	ctrl->ctrl_base = ide_base[index] + IDE_REG_EXTENDED_OFFSET;
 	return 0;
-- 
coreboot mailing list
[email protected]
http://www.coreboot.org/mailman/listinfo/coreboot

Reply via email to