[U-Boot] [PATCH V2 1/1] IXP425: Fixing PCI access

Stefan Althoefer stefan.althoefer at web.de
Sat Dec 6 23:15:20 CET 2008


This patch fixes the PCI handling routines of the IXP port.
It seems that this hasn't been touched for quite a while and
u-boot PCI handling has changed since then (but nobody
update IXP).

Changes (list uncomplete):
   - non_prefetched_read/write now return ERROR on
     (master-) abort.
   - fixed pci configuration space access.
   - pci_read_config_XXX now return value 0xff even in
     case of error (as some callers do not check the
     return value)
   - Removed CONFIG_PCI_SCAN_SHOW, as printf is not
     possible at the time pci_scan is called initially
   - fixed some IXP initialization of memory spaces
   - fixed address and irq assignment to PCI devices
   - fixed pci_find_device
   - some reformatting

Note: I think boards should always define IXP425_PCI_SIMPLE_MAPPING

Patch was tested with Janz emPC-A400.

Signed-off-by: Stefan Althoefer <stefan.althoefer at web.de>
---
I revised the patch as I found some more errors.

 board/ixdp425/ixdp425.c              |    9 +
 cpu/ixp/pci.c                        |  407 ++++++++++++++++++++--------------
 drivers/pci/pci_indirect.c           |    4 +-
 include/asm-arm/arch-ixp/ixp425pci.h |   14 +-
 4 files changed, 260 insertions(+), 174 deletions(-)

diff --git a/board/ixdp425/ixdp425.c b/board/ixdp425/ixdp425.c
index 43ac8f6..ef2f7d5 100644
--- a/board/ixdp425/ixdp425.c
+++ b/board/ixdp425/ixdp425.c
@@ -118,9 +118,18 @@ void pci_init_board(void)

 	pci_ixp_init(&hose);
 }
+
+#include <pci.h>
+int pciTranslateIrq(pci_dev_t dev, int intPin)
+{
+	/* FIXME: This needs to be implemented by someone
+	   who onws an IXDP425 board */
+	return 0;
+}
 #endif

 int board_eth_init(bd_t *bis)
 {
 	return pci_eth_init(bis);
 }
+
diff --git a/cpu/ixp/pci.c b/cpu/ixp/pci.c
index 8c6b0b2..6586ba1 100644
--- a/cpu/ixp/pci.c
+++ b/cpu/ixp/pci.c
@@ -33,16 +33,15 @@
 #include <asm/arch/ixp425.h>
 #include <asm/arch/ixp425pci.h>

-static void non_prefetch_read (unsigned int addr, unsigned int cmd,
+static int non_prefetch_read (unsigned int addr, unsigned int cmd,
 			       unsigned int *data);
-static void non_prefetch_write (unsigned int addr, unsigned int cmd,
+static int non_prefetch_write (unsigned int addr, unsigned int cmd,
 				unsigned int data);
 static void configure_pins (void);
 static void sys_pci_gpio_clock_config (void);
-static void pci_bus_scan (void);
-static int pci_device_exists (unsigned int deviceNo);
-static void sys_pci_bar_info_get (unsigned int devnum, unsigned int bus,
-				  unsigned int dev, unsigned int func);
+void pci_bus_scan (void);
+static int pci_device_exists (pci_dev_t dev);
+static void sys_pci_bar_info_get (unsigned int devnum, pci_dev_t dev);
 static void sys_pci_device_bars_write (void);
 static void calc_bars (PciBar * Bars[], unsigned int nBars,
 		       unsigned int startAddr);
@@ -68,15 +67,36 @@ PciBar *memBars[IXP425_PCI_MAX_BAR];
 PciBar *ioBars[IXP425_PCI_MAX_BAR];
 PciDevice devices[IXP425_PCI_MAX_FUNC_ON_BUS];

+
+extern int pciTranslateIrq(pci_dev_t dev, int intPin);
+
+static int ixp4xx_config_addr(u32 *addr, pci_dev_t devfn, int where)
+{
+	if (!(PCI_BUS(devfn))) {
+		/* type 0 */
+		if (PCI_DEV(devfn) > 20)
+			return ERROR;
+		*addr = BIT(32-PCI_DEV(devfn)) | ((PCI_FUNC(devfn)) << 8)
+		    | (where & ~3);
+	} else {
+		/* type 1 */
+		*addr = (PCI_BUS(devfn) << 16) | ((PCI_DEV(devfn)) << 11)
+		    | ((PCI_FUNC(devfn)) << 8) | (where & ~3) | 1;
+	}
+	return OK;
+}
+
 int pci_read_config_dword (pci_dev_t dev, int where, unsigned int *val)
 {
 	unsigned int retval;
 	unsigned int addr;

-	/*address bits 31:28 specify the device 10:8 specify the function */
-	/*Set the address to be read */
-	addr = BIT ((31 - dev)) | (where & ~3);
-	non_prefetch_read (addr, NP_CMD_CONFIGREAD, &retval);
+	*val = 0xffffffff;
+	if (ixp4xx_config_addr(&addr, dev, where & ~3))
+		return ERROR;
+	if( non_prefetch_read(addr, NP_CMD_CONFIGREAD, &retval) != OK ){
+		return ERROR;
+	}

 	*val = retval;

@@ -90,6 +110,7 @@ int pci_read_config_word (pci_dev_t dev, int where, unsigned short *val)
 	unsigned int addr;
 	unsigned int byteEnables;

+	*val = 0xffff;
 	n = where % 4;
 	/*byte enables are 4 bits active low, the position of each
 	   bit maps to the byte that it enables */
@@ -97,10 +118,12 @@ int pci_read_config_word (pci_dev_t dev, int where, unsigned short *val)
 		(~(BIT (n) | BIT ((n + 1)))) &
 		IXP425_PCI_BOTTOM_NIBBLE_OF_LONG_MASK;
 	byteEnables = byteEnables << PCI_NP_CBE_BESL;
-	/*address bits 31:28 specify the device 10:8 specify the function */
-	/*Set the address to be read */
-	addr = BIT ((31 - dev)) | (where & ~3);
-	non_prefetch_read (addr, byteEnables | NP_CMD_CONFIGREAD, &retval);
+	if (ixp4xx_config_addr(&addr, dev, where & ~3))
+		return ERROR;
+	if( non_prefetch_read(addr, byteEnables | NP_CMD_CONFIGREAD,
+			      &retval) != OK ){
+		return ERROR;
+	}

 	/*Pick out the word we are interested in */
 	*val = (retval >> (8 * n));
@@ -115,16 +138,18 @@ int pci_read_config_byte (pci_dev_t dev, int where, unsigned char *val)
 	unsigned int byteEnables;
 	unsigned int addr;

+	*val = 0xff;
 	n = where % 4;
 	/*byte enables are 4 bits, active low, the position of each
 	   bit maps to the byte that it enables */
 	byteEnables = (~BIT (n)) & IXP425_PCI_BOTTOM_NIBBLE_OF_LONG_MASK;
 	byteEnables = byteEnables << PCI_NP_CBE_BESL;
-
-	/*address bits 31:28 specify the device, 10:8 specify the function */
-	/*Set the address to be read */
-	addr = BIT ((31 - dev)) | (where & ~3);
-	non_prefetch_read (addr, byteEnables | NP_CMD_CONFIGREAD, &retval);
+	if (ixp4xx_config_addr(&addr, dev, where & ~3))
+		return ERROR;
+	if( non_prefetch_read(addr, byteEnables | NP_CMD_CONFIGREAD,
+			      &retval) != OK ){
+		return ERROR;
+	}
 	/*Pick out the byte we are interested in */
 	*val = (retval >> (8 * n));

@@ -144,10 +169,12 @@ int pci_write_config_byte (pci_dev_t dev, int where, unsigned char val)
 	byteEnables = (~BIT (n)) & IXP425_PCI_BOTTOM_NIBBLE_OF_LONG_MASK;
 	byteEnables = byteEnables << PCI_NP_CBE_BESL;
 	ldata = val << (8 * n);
-	/*address bits 31:28 specify the device 10:8 specify the function */
-	/*Set the address to be written */
-	addr = BIT ((31 - dev)) | (where & ~3);
-	non_prefetch_write (addr, byteEnables | NP_CMD_CONFIGWRITE, ldata);
+	if (ixp4xx_config_addr(&addr, dev, where & ~3))
+		return ERROR;
+	if( non_prefetch_write(addr, byteEnables | NP_CMD_CONFIGWRITE,
+				ldata) != OK ){
+		return ERROR;
+	}

 	return (OK);
 }
@@ -167,10 +194,12 @@ int pci_write_config_word (pci_dev_t dev, int where, unsigned short val)
 		IXP425_PCI_BOTTOM_NIBBLE_OF_LONG_MASK;
 	byteEnables = byteEnables << PCI_NP_CBE_BESL;
 	ldata = val << (8 * n);
-	/*address bits 31:28 specify the device 10:8 specify the function */
-	/*Set the address to be written */
-	addr = BIT (31 - dev) | (where & ~3);
-	non_prefetch_write (addr, byteEnables | NP_CMD_CONFIGWRITE, ldata);
+	if (ixp4xx_config_addr(&addr, dev, where & ~3))
+		return ERROR;
+	if( non_prefetch_write(addr, byteEnables | NP_CMD_CONFIGWRITE,
+				ldata) != OK ){
+		return ERROR;
+	}

 	return (OK);
 }
@@ -179,31 +208,41 @@ int pci_write_config_dword (pci_dev_t dev, int where, unsigned int val)
 {
 	unsigned int addr;

-	/*address bits 31:28 specify the device 10:8 specify the function */
-	/*Set the address to be written */
-	addr = BIT (31 - dev) | (where & ~3);
-	non_prefetch_write (addr, NP_CMD_CONFIGWRITE, val);
+	if (ixp4xx_config_addr(&addr, dev, where & ~3))
+		return ERROR;
+	if( non_prefetch_write(addr, NP_CMD_CONFIGWRITE, val) != OK ){
+		return ERROR;
+	}

 	return (OK);
 }

-void non_prefetch_read (unsigned int addr,
+int non_prefetch_read (unsigned int addr,
 			unsigned int cmd, unsigned int *data)
 {
-	REG_WRITE (PCI_CSR_BASE, PCI_NP_AD_OFFSET, addr);
+	unsigned int   isr;

+	REG_WRITE (PCI_CSR_BASE, PCI_NP_AD_OFFSET, addr);
 	/*set up and execute the read */
 	REG_WRITE (PCI_CSR_BASE, PCI_NP_CBE_OFFSET, cmd);
-
 	/*The result of the read is now in np_rdata */
 	REG_READ (PCI_CSR_BASE, PCI_NP_RDATA_OFFSET, *data);

-	return;
+	/* Check for abort */
+	REG_READ(PCI_CSR_BASE, PCI_ISR_OFFSET, isr);
+	if (isr & PCI_ISR_PFE) {
+		/* clear the bit */
+		REG_WRITE (PCI_CSR_BASE, PCI_ISR_OFFSET, PCI_ISR_PFE);
+		return ERROR;
+	}
+
+	return OK;
 }

-void non_prefetch_write (unsigned int addr,
+int non_prefetch_write (unsigned int addr,
 			 unsigned int cmd, unsigned int data)
 {
+	unsigned int   isr;

 	REG_WRITE (PCI_CSR_BASE, PCI_NP_AD_OFFSET, addr);
 	/*set up the write */
@@ -211,7 +250,15 @@ void non_prefetch_write (unsigned int addr,
 	/*Execute the write by writing to NP_WDATA */
 	REG_WRITE (PCI_CSR_BASE, PCI_NP_WDATA_OFFSET, data);

-	return;
+	/* Check for abort */
+	REG_READ (PCI_CSR_BASE, PCI_ISR_OFFSET, isr);
+	if( isr & PCI_ISR_PFE ){
+		/* clear the bit */
+		REG_WRITE (PCI_CSR_BASE, PCI_ISR_OFFSET, PCI_ISR_PFE);
+		return ERROR;
+	}
+
+	return OK;
 }

 /*
@@ -226,7 +273,8 @@ void crp_read (unsigned int offset, unsigned int *data)

 void crp_write (unsigned int offset, unsigned int data)
 {
-	/*The CRP address register bit 16 indicates that we want to do a write */
+	/*The CRP address register bit 16 indicates that we want to do a
+	  write */
 	REG_WRITE (PCI_CSR_BASE, PCI_CRP_AD_CBE_OFFSET,
 		   PCI_CRP_WRITE | offset);
 	REG_WRITE (PCI_CSR_BASE, PCI_CRP_WDATA_OFFSET, data);
@@ -257,11 +305,10 @@ void pci_ixp_init (struct pci_controller *hose)

 	pci_register_hose (hose);

-/*
- ==========================================================
-		Init IXP PCI
- ==========================================================
-*/
+	/*
+	 * Init IXP PCI
+	 */
+
 	REG_READ (PCI_CSR_BASE, PCI_CSR_OFFSET, regval);
 	regval |= 1 << 2;
 	REG_WRITE (PCI_CSR_BASE, PCI_CSR_OFFSET, regval);
@@ -304,9 +351,7 @@ void pci_ixp_init (struct pci_controller *hose)
 	pci_write_config_word (0, PCI_CFG_COMMAND, INITIAL_PCI_CMD);
 	REG_WRITE (PCI_CSR_BASE, PCI_ISR_OFFSET, PCI_ISR_PSE
 		   | PCI_ISR_PFE | PCI_ISR_PPE | PCI_ISR_AHBE);
-#ifdef CONFIG_PCI_SCAN_SHOW
-	printf ("Device  bus  dev  func  deviceID  vendorID \n");
-#endif
+
 	pci_bus_scan ();
 }

@@ -347,76 +392,108 @@ void sys_pci_gpio_clock_config (void)
 	WRITE_GPIO_REG (IXP425_GPIO_GPCLKR, regval);
 }

+
 void pci_bus_scan (void)
 {
-	unsigned int bus = 0, dev, func = 0;
+	int            busno, devno, funcno;
+	int            multifunction;
+	pci_dev_t      dev;
 	unsigned short data16;
-	unsigned int data32;
-	unsigned char intPin;
+	unsigned int   data32;
+	unsigned char  intPin;
+
+	unsigned int   vendorId;
+	unsigned char  HeaderType;

 	/* Assign first device to ourselves */
-	devices[0].bus = 0;
-	devices[0].device = 0;
-	devices[0].func = 0;
+	devices[0].device = PCI_BDF(0,0,0);

 	crp_read (PCI_CFG_VENDOR_ID, &data32);

 	devices[0].vendor_id = data32 & IXP425_PCI_BOTTOM_WORD_OF_LONG_MASK;
 	devices[0].device_id = data32 >> 16;
 	devices[0].error = FALSE;
-	devices[0].bar[NO_BAR].size = 0;	/*dummy - required */
+	devices[0].bar[NO_BAR].size = 0;	/* dummy - required */

 	nDevices = 1;

 	nMBars = 0;
 	nIOBars = 0;

-	for (dev = 0; dev < IXP425_PCI_MAX_DEV; dev++) {
-
-		/*Check whether a device is present */
-		if (pci_device_exists (dev) != TRUE) {
-
-			/*Clear error bits in ISR, write 1 to clear */
-			REG_WRITE (PCI_CSR_BASE, PCI_ISR_OFFSET, PCI_ISR_PSE
-				   | PCI_ISR_PFE | PCI_ISR_PPE |
-				   PCI_ISR_AHBE);
-			continue;
-		}
-
-		/*A device is present, add an entry to the array */
-		devices[nDevices].bus = bus;
-		devices[nDevices].device = dev;
-		devices[nDevices].func = func;
-
-		pci_read_config_word (dev, PCI_CFG_VENDOR_ID, &data16);
-
-		devices[nDevices].vendor_id = data16;
-
-		pci_read_config_word (dev, PCI_CFG_DEVICE_ID, &data16);
-		devices[nDevices].device_id = data16;
-
-		/*The device is functioning correctly, set error to FALSE */
-		devices[nDevices].error = FALSE;
-
-		/*Figure out what BARs are on this device */
-		sys_pci_bar_info_get (nDevices, bus, dev, func);
-		/*Figure out what INTX# line the card uses */
-		pci_read_config_byte (dev, PCI_CFG_DEV_INT_PIN, &intPin);
-
-		/*assign the appropriate irq line */
-		if (intPin > PCI_IRQ_LINES) {
-			devices[nDevices].error = TRUE;
-		} else if (intPin != 0) {
-			/*This device uses an interrupt line */
-			/*devices[nDevices].irq = ixp425PciIntTranslate[dev][intPin-1]; */
-			devices[nDevices].irq = intPin;
+	for (busno=0; busno<2; busno++) {
+		for (devno=0; devno<PCI_MAX_PCI_DEVICES; devno++) {
+			multifunction = 0;
+			for (funcno=0; funcno<PCI_MAX_PCI_FUNCTIONS; funcno++) {
+				dev = PCI_BDF(busno,devno,funcno);
+
+				if (funcno && !multifunction)
+					break;
+
+				if (pci_read_config_dword(dev,
+							  PCI_CFG_VENDOR_ID,
+							  &vendorId)
+				    == ERROR ){
+					if (!funcno)
+						break;
+					else
+						continue;
+				}
+
+				if (vendorId == 0x0) {
+					funcno=PCI_MAX_PCI_FUNCTIONS;
+					continue;
+				}
+
+				pci_read_config_byte(dev, PCI_HEADER_TYPE,
+						     &HeaderType);
+				if (funcno == 0) {
+					if (HeaderType & 0x80) {
+						multifunction = 1;
+					}
+				}
+
+				/* A device is present, add an entry to the
+				   array */
+				devices[nDevices].device = dev;
+
+				pci_read_config_word (dev, PCI_CFG_VENDOR_ID,
+						      &data16);
+
+				devices[nDevices].vendor_id = data16;
+
+				pci_read_config_word (dev, PCI_CFG_DEVICE_ID,
+						      &data16);
+				devices[nDevices].device_id = data16;
+
+				/* The device is functioning correctly, set
+				   error to FALSE */
+				devices[nDevices].error = FALSE;
+
+				if ((HeaderType&~0x80)==0) {
+					/*Figure out what BARs are on this
+					  device */
+					sys_pci_bar_info_get (nDevices, dev);
+					/*Figure out what INTX# line the card
+					  uses */
+					pci_read_config_byte (dev,
+						      PCI_CFG_DEV_INT_PIN,
+							      &intPin);
+
+					/*assign the appropriate irq line */
+					if (intPin > PCI_IRQ_LINES) {
+						devices[nDevices].error = TRUE;
+					} else if (intPin != 0) {
+						/*This device uses an interrupt
+						  line */
+						devices[nDevices].irq =
+						    pciTranslateIrq(dev,intPin);
+					}
+				} else {
+					/* ToDo: Handle bridges */
+				}
+				nDevices++;
+			}
 		}
-#ifdef CONFIG_PCI_SCAN_SHOW
-		printf ("%06d    %03d %03d %04d  %08d      %08x\n", nDevices,
-			devices[nDevices].vendor_id);
-#endif
-		nDevices++;
-
 	}

 	calc_bars (memBars, nMBars, IXP425_PCI_BAR_MEM_BASE);
@@ -426,44 +503,46 @@ void pci_bus_scan (void)
 		   | PCI_ISR_PFE | PCI_ISR_PPE | PCI_ISR_AHBE);
 }

-void sys_pci_bar_info_get (unsigned int devnum,
-			   unsigned int bus,
-			   unsigned int dev, unsigned int func)
+
+void sys_pci_bar_info_get (unsigned int devnum, pci_dev_t dev)
 {
 	unsigned int data32;
 	unsigned int tmp;
 	unsigned int size;
+	int          bar;

-	pci_write_config_dword (devnum,
-				PCI_CFG_BASE_ADDRESS_0, IXP425_PCI_BAR_QUERY);
-	pci_read_config_dword (devnum, PCI_CFG_BASE_ADDRESS_0, &data32);
-
-	devices[devnum].bar[0].address = (data32 & 1);
+	for(bar=0; bar<=5; bar++){
+		pci_write_config_dword (dev,
+					PCI_CFG_BASE_ADDRESS_0+(4*bar),
+					IXP425_PCI_BAR_QUERY);
+		pci_read_config_dword (dev, PCI_CFG_BASE_ADDRESS_0+(4*bar),
+				       &data32);

-	if (data32 & 1) {
-		/* IO space */
-		tmp = data32 & ~0x3;
-		size = ~(tmp - 1);
-		devices[devnum].bar[0].size = size;
+		devices[devnum].bar[dev].address = (data32 & 1);

-		if (nIOBars < IXP425_PCI_MAX_BAR) {
-			ioBars[nIOBars++] = &devices[devnum].bar[0];
-		}
-	} else {
-		/* Mem space */
-		tmp = data32 & ~IXP425_PCI_BOTTOM_NIBBLE_OF_LONG_MASK;
-		size = ~(tmp - 1);
-		devices[devnum].bar[0].size = size;
+		if (data32 & 1) {
+			/* IO space */
+			tmp = data32 & ~0x3;
+			size = ~(tmp - 1);
+			devices[devnum].bar[bar].size = size;

-		if (nMBars < IXP425_PCI_MAX_BAR) {
-			memBars[nMBars++] = &devices[devnum].bar[0];
+			if (nIOBars < IXP425_PCI_MAX_BAR) {
+				ioBars[nIOBars++] = &devices[devnum].bar[bar];
+			}
 		} else {
-			devices[devnum].error = TRUE;
-		}
+			/* Mem space */
+			tmp = data32 & ~IXP425_PCI_BOTTOM_NIBBLE_OF_LONG_MASK;
+			size = ~(tmp - 1);
+			devices[devnum].bar[bar].size = size;
+
+			if (nMBars < IXP425_PCI_MAX_BAR) {
+				memBars[nMBars++] = &devices[devnum].bar[bar];
+			} else {
+				devices[devnum].error = TRUE;
+			}

+		}
 	}
-
-	devices[devnum].bar[1].size = 0;
 }

 void sortBars (PciBar * Bars[], unsigned int nBars)
@@ -497,77 +576,77 @@ void calc_bars (PciBar * Bars[], unsigned int nBars, unsigned int startAddr)
 	}

 	for (i = 0; i < nBars; i++) {
-		Bars[i]->address |= startAddr;
-		startAddr += Bars[i]->size;
+		if( Bars[i]->size > 0 ){
+			if( startAddr & ((Bars[i]->size)-1) ){
+				startAddr |= ((Bars[i]->size)-1);
+				startAddr += 1;
+			}
+			Bars[i]->address |= startAddr;
+			startAddr += Bars[i]->size;
+		}
 	}
 }

 void sys_pci_device_bars_write (void)
 {
-	unsigned int i;
-	int addr;
+	unsigned int i, bar;

 	for (i = 1; i < nDevices; i++) {
 		if (devices[i].error) {
 			continue;
 		}

-		pci_write_config_dword (devices[i].device,
-					PCI_CFG_BASE_ADDRESS_0,
-					devices[i].bar[0].address);
-		addr = BIT (31 - devices[i].device) |
-			(0 << PCI_NP_AD_FUNCSL) |
-			(PCI_CFG_BASE_ADDRESS_0 & ~3);
-		pci_write_config_dword (devices[i].device,
-					PCI_CFG_DEV_INT_LINE, devices[i].irq);
+		for(bar=0; bar<5; bar++){
+			pci_write_config_dword (devices[i].device,
+						PCI_CFG_BASE_ADDRESS_0+(4*bar),
+						devices[i].bar[bar].address);
+		}
+
+		pci_write_config_byte (devices[i].device,
+				       PCI_CFG_DEV_INT_LINE, devices[i].irq);

 		pci_write_config_word (devices[i].device,
 				       PCI_CFG_COMMAND, INITIAL_PCI_CMD);
-
 	}
 }


-int pci_device_exists (unsigned int deviceNo)
+int pci_device_exists (pci_dev_t dev)
 {
 	unsigned int vendorId;
-	unsigned int regval;

-	pci_read_config_dword (deviceNo, PCI_CFG_VENDOR_ID, &vendorId);
+	if (pci_read_config_dword(dev, PCI_CFG_VENDOR_ID,
+				   &vendorId) == ERROR) {
+		return FALSE;
+	}

-	/* There are two ways to find out an empty device.
-	 *   1. check Master Abort bit after the access.
-	 *   2. check whether the vendor id read back is 0x0.
-	 */
-	REG_READ (PCI_CSR_BASE, PCI_ISR_OFFSET, regval);
-	if ((vendorId != 0x0) && ((regval & PCI_ISR_PFE) == 0)) {
+	if ( vendorId != 0x0 ) {
 		return TRUE;
 	}
-	/*no device present, make sure that the master abort bit is reset */

-	REG_WRITE (PCI_CSR_BASE, PCI_ISR_OFFSET, PCI_ISR_PFE);
 	return FALSE;
 }

-pci_dev_t pci_find_devices (struct pci_device_id * ids, int devNo)
+pci_dev_t pci_find_devices (struct pci_device_id *ids, int devNo)
 {
-	unsigned int i;
+	unsigned int i,k;
 	unsigned int devdidvid;
 	unsigned int didvid;
-	unsigned int vendorId, deviceId;
-
-	vendorId = ids->vendor;
-	deviceId = ids->device;
-	didvid = ((deviceId << 16) & IXP425_PCI_TOP_WORD_OF_LONG_MASK) |
-		(vendorId & IXP425_PCI_BOTTOM_WORD_OF_LONG_MASK);

-	for (i = devNo + 1; i < nDevices; i++) {
-
-		pci_read_config_dword (devices[i].device, PCI_CFG_VENDOR_ID,
-				       &devdidvid);
-
-		if (devdidvid == didvid) {
-			return devices[i].device;
+	for (i = 1; i < nDevices; i++) {
+		devdidvid = (devices[i].device_id << 16)
+			+ devices[i].vendor_id;
+
+		for (k = 0; ids[k].vendor != 0; k++) {
+			didvid  = ((ids[k].device << 16)
+				   & IXP425_PCI_TOP_WORD_OF_LONG_MASK);
+			didvid |= (ids[k].vendor
+				   & IXP425_PCI_BOTTOM_WORD_OF_LONG_MASK);
+
+			if (devdidvid == didvid) {
+				if (devNo-- == 0)
+					return devices[i].device;
+			}
 		}
 	}
 	return -1;
diff --git a/drivers/pci/pci_indirect.c b/drivers/pci/pci_indirect.c
index ab51f8d..cd3a6f6 100644
--- a/drivers/pci/pci_indirect.c
+++ b/drivers/pci/pci_indirect.c
@@ -11,7 +11,7 @@

 #include <common.h>

-#if (!defined(__I386__) && !defined(CONFIG_IXDP425))
+#if (!defined(__I386__) && !defined(CONFIG_IXP425))

 #include <asm/processor.h>
 #include <asm/io.h>
@@ -133,4 +133,4 @@ void pci_setup_indirect(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data)
 	hose->cfg_data = (unsigned char *) cfg_data;
 }

-#endif	/* !__I386__ && !CONFIG_IXDP425 */
+#endif	/* !__I386__ && !CONFIG_IXP425 */
diff --git a/include/asm-arm/arch-ixp/ixp425pci.h b/include/asm-arm/arch-ixp/ixp425pci.h
index 9ea3319..e533e90 100644
--- a/include/asm-arm/arch-ixp/ixp425pci.h
+++ b/include/asm-arm/arch-ixp/ixp425pci.h
@@ -52,9 +52,7 @@ typedef struct

 typedef struct
 {
-	unsigned int bus;
-	unsigned int device;
-	unsigned int func;
+	pci_dev_t    device;
 	unsigned int irq;
 	BOOL error;
 	unsigned short vendor_id;
@@ -74,13 +72,13 @@ typedef struct

 #define IXP425_PCI_BAR_QUERY			0xffffffff

-#define IXP425_PCI_BAR_MEM_BASE 0x100000
-#define IXP425_PCI_BAR_IO_BASE	0x000000
+#define IXP425_PCI_BAR_MEM_BASE 0x48000000
+#define IXP425_PCI_BAR_IO_BASE	0x00000000    /* not supported */

 /*define the maximum number of bus segments - we support a single segment*/
-#define IXP425_PCI_MAX_BUS  1
+#define IXP425_PCI_MAX_BUS  4
 /*define the maximum number of cards per bus segment*/
-#define IXP425_PCI_MAX_DEV  4
+#define IXP425_PCI_MAX_DEV  8
 /*define the maximum number of functions per device*/
 #define IXP425_PCI_MAX_FUNC 8
 /* define the maximum number of separate functions that we can
@@ -153,7 +151,7 @@ typedef struct
 /*define the default setting of the AHB memory base reg*/
 #define IXP425_PCI_AHBMEMBASE_DEFAULT 0x00010203
 #define IXP425_PCI_AHBIOBASE_DEFAULT  0x0
-#define IXP425_PCI_PCIMEMBASE_DEFAULT 0x0
+#define IXP425_PCI_PCIMEMBASE_DEFAULT 0x48494a4b

 /*define the default settings for the controller's BARs*/
 #ifdef IXP425_PCI_SIMPLE_MAPPING
-- 
1.5.4.5



More information about the U-Boot mailing list