On Fri, Jun 20, 2008 at 11:55:54PM -0500, bari wrote:
> Peter Stuge wrote:
> > Found a bug in the debug() calls. Fixed in the attached version.
>
> It works!
Great! I'm looking forward to more test results. Here's a properly
signed-off patch with some small debug message fixes and better
explanation.
Anyone else who has a board with a SATA PCI device before the
PATA/IDE device, please test booting from PATA using this patch.
It would also be interesting to boot this patch on a board with only
PATA/IDE devices - ie. no SATA or native mode PATA.
//Peter
FILO: find_ide_controller_compat(): Skip over PCI devices in native mode
find_ide_controller_compat() would assume that all controllers were using
legacy ports, even SATA and IDE controllers in native PCI mode.
On a system with these PCI ids:
pci_init: 00:0f.0 1106:3149 0101 8f /* SATA native with 2 channels */
pci_init: 00:0f.1 1106:0571 0101 8a /* PATA legacy with 2 channels */
The SATA device has io resources above 0x1000.
The PATA device is without proper io resources, but is configured to listen
on the first and second legacy IDE ports 0x1f0 and 0x170.
find_ide_controller_compat() would incorrectly assume that the SATA device
used ports 0x1f0 and 0x170, and that the PATA device used 0x1e8 and 0x168.
This teaches find_ide_controller_compat() to skip devices in native mode.
Signed-off-by: Peter Stuge <[EMAIL PROTECTED]>
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,31 @@
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 (IDE/other storage really) device */
+ dev = pci_find_ata_device(-1, -1, -1, i);
+ if (!dev)
+ break;
+ /* only IDE can be in compat mode so skip all others */
+ if (0x0101 != dev->devclass) {
+ /* other storage (SATA) always has two channels */
+ skip += 2;
+ continue;
+ }
+ /* primary in native mode? then skip it. */
+ if (1 == (dev->prog_if & 1))
+ skip++;
+ /* secondary in native mode? then skip it. */
+ if (index && 4 == (dev->prog_if & 4))
+ skip++;
+ }
+ index = skip <= index ? index - skip : 0;
+ debug("skipping %d native PCI controllers, new index=%d\n", skip, index);
+ if (index >= IDE_MAX_CONTROLLERS)
+ return -1;
+#endif
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