summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/spi/Makefile1
-rw-r--r--drivers/mtd/spi/ramtron.c319
-rw-r--r--drivers/mtd/spi/spi_flash.c8
-rw-r--r--drivers/mtd/spi/spi_flash_internal.h1
-rw-r--r--drivers/net/dc2114x.c6
-rw-r--r--drivers/net/e1000.c14
-rw-r--r--drivers/net/eepro100.c5
-rw-r--r--drivers/net/fec_mxc.c1
-rw-r--r--drivers/net/natsemi.c5
-rw-r--r--drivers/net/ns8382x.c5
-rw-r--r--drivers/net/pcnet.c5
-rw-r--r--drivers/net/rtl8139.c5
-rw-r--r--drivers/net/rtl8169.c5
-rw-r--r--drivers/net/tsi108_eth.c6
-rw-r--r--drivers/net/uli526x.c5
-rw-r--r--drivers/pci/fsl_pci_init.c12
-rw-r--r--drivers/pci/pci.c130
17 files changed, 500 insertions, 33 deletions
diff --git a/drivers/mtd/spi/Makefile b/drivers/mtd/spi/Makefile
index 4f11b36..a082ca7 100644
--- a/drivers/mtd/spi/Makefile
+++ b/drivers/mtd/spi/Makefile
@@ -32,6 +32,7 @@ COBJS-$(CONFIG_SPI_FLASH_SPANSION) += spansion.o
COBJS-$(CONFIG_SPI_FLASH_SST) += sst.o
COBJS-$(CONFIG_SPI_FLASH_STMICRO) += stmicro.o
COBJS-$(CONFIG_SPI_FLASH_WINBOND) += winbond.o
+COBJS-$(CONFIG_SPI_FRAM_RAMTRON) += ramtron.o
COBJS-$(CONFIG_SPI_M95XXX) += eeprom_m95xxx.o
COBJS := $(COBJS-y)
diff --git a/drivers/mtd/spi/ramtron.c b/drivers/mtd/spi/ramtron.c
new file mode 100644
index 0000000..171390d
--- /dev/null
+++ b/drivers/mtd/spi/ramtron.c
@@ -0,0 +1,319 @@
+/*
+ * (C) Copyright 2010
+ * Reinhard Meyer, EMK Elektronik, reinhard.meyer@emk-elektronik.de
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Note: RAMTRON SPI FRAMs are ferroelectric, nonvolatile RAMs
+ * with an interface identical to SPI flash devices.
+ * However since they behave like RAM there are no delays or
+ * busy polls required. They can sustain read or write at the
+ * allowed SPI bus speed, which can be 40 MHz for some devices.
+ *
+ * Unfortunately some RAMTRON devices do not have a means of
+ * identifying them. They will leave the SO line undriven when
+ * the READ-ID command is issued. It is therefore mandatory
+ * that the MISO line has a proper pull-up, so that READ-ID
+ * will return a row of 0xff. This 0xff pseudo-id will cause
+ * probes by all vendor specific functions that are designed
+ * to handle it. If the MISO line is not pulled up, READ-ID
+ * could return any random noise, even mimicking another
+ * device.
+ *
+ * We use CONFIG_SPI_FRAM_RAMTRON_NON_JEDEC
+ * to define which device will be assumed after a simple status
+ * register verify. This method is prone to false positive
+ * detection and should therefore be the last to be tried.
+ * Enter it in the last position in the table in spi_flash.c!
+ *
+ * The define CONFIG_SPI_FRAM_RAMTRON_NON_JEDEC both activates
+ * compilation of the special handler and defines the device
+ * to assume.
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <spi_flash.h>
+#include "spi_flash_internal.h"
+
+/* RAMTRON commands common to all devices */
+#define CMD_RAMTRON_WREN 0x06 /* Write Enable */
+#define CMD_RAMTRON_WRDI 0x04 /* Write Disable */
+#define CMD_RAMTRON_RDSR 0x05 /* Read Status Register */
+#define CMD_RAMTRON_WRSR 0x01 /* Write Status Register */
+#define CMD_RAMTRON_READ 0x03 /* Read Data Bytes */
+#define CMD_RAMTRON_WRITE 0x02 /* Write Data Bytes */
+/* not all have those: */
+#define CMD_RAMTRON_FSTRD 0x0b /* Fast Read (for compatibility - not used here) */
+#define CMD_RAMTRON_SLEEP 0xb9 /* Enter Sleep Mode */
+#define CMD_RAMTRON_RDID 0x9f /* Read ID */
+#define CMD_RAMTRON_SNR 0xc3 /* Read Serial Number */
+
+/*
+ * Properties of supported FRAMs
+ * Note: speed is currently not used because we have no method to deliver that
+ * value to the upper layers
+ */
+struct ramtron_spi_fram_params {
+ u32 size; /* size in bytes */
+ u8 addr_len; /* number of address bytes */
+ u8 merge_cmd; /* some address bits are in the command byte */
+ u8 id1; /* device ID 1 (family, density) */
+ u8 id2; /* device ID 2 (sub, rev, rsvd) */
+ u32 speed; /* max. SPI clock in Hz */
+ const char *name; /* name for display and/or matching */
+};
+
+struct ramtron_spi_fram {
+ struct spi_flash flash;
+ const struct ramtron_spi_fram_params *params;
+};
+
+static inline struct ramtron_spi_fram *to_ramtron_spi_fram(struct spi_flash
+ *flash)
+{
+ return container_of(flash, struct ramtron_spi_fram, flash);
+}
+
+/*
+ * table describing supported FRAM chips:
+ * chips without RDID command must have the values 0xff for id1 and id2
+ */
+static const struct ramtron_spi_fram_params ramtron_spi_fram_table[] = {
+ {
+ .size = 32*1024,
+ .addr_len = 2,
+ .merge_cmd = 0,
+ .id1 = 0x22,
+ .id2 = 0x00,
+ .speed = 40000000,
+ .name = "FM25V02",
+ },
+ {
+ .size = 32*1024,
+ .addr_len = 2,
+ .merge_cmd = 0,
+ .id1 = 0x22,
+ .id2 = 0x01,
+ .speed = 40000000,
+ .name = "FM25VN02",
+ },
+ {
+ .size = 64*1024,
+ .addr_len = 2,
+ .merge_cmd = 0,
+ .id1 = 0x23,
+ .id2 = 0x00,
+ .speed = 40000000,
+ .name = "FM25V05",
+ },
+ {
+ .size = 64*1024,
+ .addr_len = 2,
+ .merge_cmd = 0,
+ .id1 = 0x23,
+ .id2 = 0x01,
+ .speed = 40000000,
+ .name = "FM25VN05",
+ },
+ {
+ .size = 128*1024,
+ .addr_len = 3,
+ .merge_cmd = 0,
+ .id1 = 0x24,
+ .id2 = 0x00,
+ .speed = 40000000,
+ .name = "FM25V10",
+ },
+ {
+ .size = 128*1024,
+ .addr_len = 3,
+ .merge_cmd = 0,
+ .id1 = 0x24,
+ .id2 = 0x01,
+ .speed = 40000000,
+ .name = "FM25VN10",
+ },
+#ifdef CONFIG_SPI_FRAM_RAMTRON_NON_JEDEC
+ {
+ .size = 256*1024,
+ .addr_len = 3,
+ .merge_cmd = 0,
+ .id1 = 0xff,
+ .id2 = 0xff,
+ .speed = 40000000,
+ .name = "FM25H20",
+ },
+#endif
+};
+
+static int ramtron_common(struct spi_flash *flash,
+ u32 offset, size_t len, void *buf, u8 command)
+{
+ struct ramtron_spi_fram *sn = to_ramtron_spi_fram(flash);
+ u8 cmd[4];
+ int cmd_len;
+ int ret;
+
+ if (sn->params->addr_len == 3 && sn->params->merge_cmd == 0) {
+ cmd[0] = command;
+ cmd[1] = offset >> 16;
+ cmd[2] = offset >> 8;
+ cmd[3] = offset;
+ cmd_len = 4;
+ } else if (sn->params->addr_len == 2 && sn->params->merge_cmd == 0) {
+ cmd[0] = command;
+ cmd[1] = offset >> 8;
+ cmd[2] = offset;
+ cmd_len = 3;
+ } else {
+ printf("SF: unsupported addr_len or merge_cmd\n");
+ return -1;
+ }
+
+ /* claim the bus */
+ ret = spi_claim_bus(flash->spi);
+ if (ret) {
+ debug("SF: Unable to claim SPI bus\n");
+ return ret;
+ }
+
+ if (command == CMD_RAMTRON_WRITE) {
+ /* send WREN */
+ ret = spi_flash_cmd(flash->spi, CMD_RAMTRON_WREN, NULL, 0);
+ if (ret < 0) {
+ debug("SF: Enabling Write failed\n");
+ goto releasebus;
+ }
+ }
+
+ /* do the transaction */
+ if (command == CMD_RAMTRON_WRITE)
+ ret = spi_flash_cmd_write(flash->spi, cmd, cmd_len, buf, len);
+ else
+ ret = spi_flash_cmd_read(flash->spi, cmd, cmd_len, buf, len);
+ if (ret < 0)
+ debug("SF: Transaction failed\n");
+
+releasebus:
+ /* release the bus */
+ spi_release_bus(flash->spi);
+ return ret;
+}
+
+static int ramtron_read(struct spi_flash *flash,
+ u32 offset, size_t len, void *buf)
+{
+ return ramtron_common(flash, offset, len, buf,
+ CMD_RAMTRON_READ);
+}
+
+static int ramtron_write(struct spi_flash *flash,
+ u32 offset, size_t len, const void *buf)
+{
+ return ramtron_common(flash, offset, len, (void *)buf,
+ CMD_RAMTRON_WRITE);
+}
+
+int ramtron_erase(struct spi_flash *flash, u32 offset, size_t len)
+{
+ debug("SF: Erase of RAMTRON FRAMs is pointless\n");
+ return -1;
+}
+
+/*
+ * nore: we are called here with idcode pointing to the first non-0x7f byte
+ * already!
+ */
+struct spi_flash *spi_fram_probe_ramtron(struct spi_slave *spi, u8 *idcode)
+{
+ const struct ramtron_spi_fram_params *params;
+ struct ramtron_spi_fram *sn;
+ unsigned int i;
+#ifdef CONFIG_SPI_FRAM_RAMTRON_NON_JEDEC
+ int ret;
+ u8 sr;
+#endif
+
+ /* NOTE: the bus has been claimed before this function is called! */
+ switch (idcode[0]) {
+ case 0xc2:
+ /* JEDEC conformant RAMTRON id */
+ for (i = 0; i < ARRAY_SIZE(ramtron_spi_fram_table); i++) {
+ params = &ramtron_spi_fram_table[i];
+ if (idcode[1] == params->id1 && idcode[2] == params->id2)
+ goto found;
+ }
+ break;
+#ifdef CONFIG_SPI_FRAM_RAMTRON_NON_JEDEC
+ case 0xff:
+ /*
+ * probably open MISO line, pulled up.
+ * We COULD have a non JEDEC conformant FRAM here,
+ * read the status register to verify
+ */
+ ret = spi_flash_cmd(spi, CMD_RAMTRON_RDSR, &sr, 1);
+ if (ret)
+ return NULL;
+
+ /* Bits 5,4,0 are fixed 0 for all devices */
+ if ((sr & 0x31) != 0x00)
+ return NULL;
+ /* now find the device */
+ for (i = 0; i < ARRAY_SIZE(ramtron_spi_fram_table); i++) {
+ params = &ramtron_spi_fram_table[i];
+ if (!strcmp(params->name, CONFIG_SPI_FRAM_RAMTRON_NON_JEDEC))
+ goto found;
+ }
+ debug("SF: Unsupported non-JEDEC RAMTRON device "
+ CONFIG_SPI_FRAM_RAMTRON_NON_JEDEC "\n");
+ break;
+#endif
+ default:
+ break;
+ }
+
+ /* arriving here means no method has found a device we can handle */
+ debug("SF/ramtron: unsupported device id0=%02x id1=%02x id2=%02x\n",
+ idcode[0], idcode[1], idcode[2]);
+ return NULL;
+
+found:
+ sn = malloc(sizeof(*sn));
+ if (!sn) {
+ debug("SF: Failed to allocate memory\n");
+ return NULL;
+ }
+
+ sn->params = params;
+ sn->flash.spi = spi;
+ sn->flash.name = params->name;
+
+ sn->flash.write = ramtron_write;
+ sn->flash.read = ramtron_read;
+ sn->flash.erase = ramtron_erase;
+ sn->flash.size = params->size;
+
+ printf("SF: Detected %s with size ", params->name);
+ print_size(sn->flash.size, "\n");
+
+ return &sn->flash;
+}
diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index b4ba1dd..ab02ef3 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -146,10 +146,18 @@ static const struct {
#ifdef CONFIG_SPI_FLASH_WINBOND
{ 0, 0xef, spi_flash_probe_winbond, },
#endif
+#ifdef CONFIG_SPI_FRAM_RAMTRON
+ { 6, 0xc2, spi_fram_probe_ramtron, },
+# undef IDCODE_CONT_LEN
+# define IDCODE_CONT_LEN 6
+#endif
/* Keep it sorted by best detection */
#ifdef CONFIG_SPI_FLASH_STMICRO
{ 0, 0xff, spi_flash_probe_stmicro, },
#endif
+#ifdef CONFIG_SPI_FRAM_RAMTRON_NON_JEDEC
+ { 0, 0xff, spi_fram_probe_ramtron, },
+#endif
};
#define IDCODE_LEN (IDCODE_CONT_LEN + IDCODE_PART_LEN)
diff --git a/drivers/mtd/spi/spi_flash_internal.h b/drivers/mtd/spi/spi_flash_internal.h
index 08546fb..9bc43dd 100644
--- a/drivers/mtd/spi/spi_flash_internal.h
+++ b/drivers/mtd/spi/spi_flash_internal.h
@@ -50,3 +50,4 @@ struct spi_flash *spi_flash_probe_macronix(struct spi_slave *spi, u8 *idcode);
struct spi_flash *spi_flash_probe_sst(struct spi_slave *spi, u8 *idcode);
struct spi_flash *spi_flash_probe_stmicro(struct spi_slave *spi, u8 *idcode);
struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode);
+struct spi_flash *spi_fram_probe_ramtron(struct spi_slave *spi, u8 *idcode);
diff --git a/drivers/net/dc2114x.c b/drivers/net/dc2114x.c
index 5ae53e8..51e7c19 100644
--- a/drivers/net/dc2114x.c
+++ b/drivers/net/dc2114x.c
@@ -280,6 +280,12 @@ int dc21x4x_initialize(bd_t *bis)
dev = (struct eth_device*) malloc(sizeof *dev);
+ if (!dev) {
+ printf("Can not allocalte memory of dc21x4x\n");
+ break;
+ }
+ memset(dev, 0, sizeof(*dev));
+
#ifdef CONFIG_TULIP_FIX_DAVICOM
sprintf(dev->name, "Davicom#%d", card_number);
#else
diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c
index 2825342..18584ef 100644
--- a/drivers/net/e1000.c
+++ b/drivers/net/e1000.c
@@ -5177,7 +5177,21 @@ e1000_initialize(bd_t * bis)
}
nic = (struct eth_device *) malloc(sizeof (*nic));
+ if (!nic) {
+ printf("Error: e1000 - Can not alloc memory\n");
+ return 0;
+ }
+
hw = (struct e1000_hw *) malloc(sizeof (*hw));
+ if (!hw) {
+ free(nic);
+ printf("Error: e1000 - Can not alloc memory\n");
+ return 0;
+ }
+
+ memset(nic, 0, sizeof(*dev));
+ memset(hw, 0, sizeof(*hw));
+
hw->pdev = devno;
nic->priv = hw;
diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c
index 22e14e3..ae0e0d4 100644
--- a/drivers/net/eepro100.c
+++ b/drivers/net/eepro100.c
@@ -450,6 +450,11 @@ int eepro100_initialize (bd_t * bis)
}
dev = (struct eth_device *) malloc (sizeof *dev);
+ if (!dev) {
+ printf("eepro100: Can not allocate memory\n");
+ break;
+ }
+ memset(dev, 0, sizeof(*dev));
sprintf (dev->name, "i82559#%d", card_number);
dev->priv = (void *) devno; /* this have to come before bus_to_phys() */
diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c
index 3f09c2b..c17f937 100644
--- a/drivers/net/fec_mxc.c
+++ b/drivers/net/fec_mxc.c
@@ -710,6 +710,7 @@ static int fec_probe(bd_t *bd)
puts("fec_mxc: not enough malloc memory\n");
return -ENOMEM;
}
+ memset(edev, 0, sizeof(*edev));
edev->priv = fec;
edev->init = fec_init;
edev->send = fec_send;
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index e09da1d..14b2d35 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -321,6 +321,11 @@ natsemi_initialize(bd_t * bis)
}
dev = (struct eth_device *) malloc(sizeof *dev);
+ if (!dev) {
+ printf("natsemi: Can not allocate memory\n");
+ break;
+ }
+ memset(dev, 0, sizeof(*dev));
sprintf(dev->name, "dp83815#%d", card_number);
dev->iobase = bus_to_phys(iobase);
diff --git a/drivers/net/ns8382x.c b/drivers/net/ns8382x.c
index 198f73d..45402cc 100644
--- a/drivers/net/ns8382x.c
+++ b/drivers/net/ns8382x.c
@@ -340,6 +340,11 @@ ns8382x_initialize(bd_t * bis)
}
dev = (struct eth_device *) malloc(sizeof *dev);
+ if (!dev) {
+ printf("ns8382x: Can not allocate memory\n");
+ break;
+ }
+ memset(dev, 0, sizeof(*dev));
sprintf(dev->name, "dp8382x#%d", card_number);
dev->iobase = bus_to_phys(iobase);
diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c
index 99b6942..e994cb6 100644
--- a/drivers/net/pcnet.c
+++ b/drivers/net/pcnet.c
@@ -187,6 +187,11 @@ int pcnet_initialize (bd_t * bis)
* Allocate and pre-fill the device structure.
*/
dev = (struct eth_device *) malloc (sizeof *dev);
+ if (!dev) {
+ printf("pcnet: Can not allocate memory\n");
+ break;
+ }
+ memset(dev, 0, sizeof(*dev));
dev->priv = (void *) devbusfn;
sprintf (dev->name, "pcnet#%d", dev_nr);
diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c
index db8a727..c2779db 100644
--- a/drivers/net/rtl8139.c
+++ b/drivers/net/rtl8139.c
@@ -220,6 +220,11 @@ int rtl8139_initialize(bd_t *bis)
debug ("rtl8139: REALTEK RTL8139 @0x%x\n", iobase);
dev = (struct eth_device *)malloc(sizeof *dev);
+ if (!dev) {
+ printf("Can not allocate memory of rtl8139\n");
+ break;
+ }
+ memset(dev, 0, sizeof(*dev));
sprintf (dev->name, "RTL8139#%d", card_number);
diff --git a/drivers/net/rtl8169.c b/drivers/net/rtl8169.c
index e45d1a5..b81dcad 100644
--- a/drivers/net/rtl8169.c
+++ b/drivers/net/rtl8169.c
@@ -894,7 +894,12 @@ int rtl8169_initialize(bd_t *bis)
debug ("rtl8169: REALTEK RTL8169 @0x%x\n", iobase);
dev = (struct eth_device *)malloc(sizeof *dev);
+ if (!dev) {
+ printf("Can not allocate memory of rtl8169\n");
+ break;
+ }
+ memset(dev, 0, sizeof(*dev));
sprintf (dev->name, "RTL8169#%d", card_number);
dev->priv = (void *) devno;
diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c
index 079354a..f100ec1 100644
--- a/drivers/net/tsi108_eth.c
+++ b/drivers/net/tsi108_eth.c
@@ -731,7 +731,11 @@ int tsi108_eth_initialize (bd_t * bis)
for (index = 0; index < CONFIG_TSI108_ETH_NUM_PORTS; index++) {
dev = (struct eth_device *)malloc(sizeof(struct eth_device));
-
+ if (!dev) {
+ printf("tsi108: Can not allocate memory\n");
+ break;
+ }
+ memset(dev, 0, sizeof(*dev));
sprintf (dev->name, "TSI108_eth%d", index);
dev->iobase = ETH_BASE + (index * ETH_PORT_OFFSET);
diff --git a/drivers/net/uli526x.c b/drivers/net/uli526x.c
index d626d68..a4624e1 100644
--- a/drivers/net/uli526x.c
+++ b/drivers/net/uli526x.c
@@ -225,6 +225,11 @@ int uli526x_initialize(bd_t *bis)
iobase &= ~0xf;
dev = (struct eth_device *)malloc(sizeof *dev);
+ if (!dev) {
+ printf("uli526x: Can not allocate memory\n");
+ break;
+ }
+ memset(dev, 0, sizeof(*dev));
sprintf(dev->name, "uli526x#%d", card_number);
db = (struct uli526x_board_info *)
malloc(sizeof(struct uli526x_board_info));
diff --git a/drivers/pci/fsl_pci_init.c b/drivers/pci/fsl_pci_init.c
index 1f02103..5b34dcb 100644
--- a/drivers/pci/fsl_pci_init.c
+++ b/drivers/pci/fsl_pci_init.c
@@ -391,11 +391,11 @@ void fsl_pci_init(struct pci_controller *hose, u32 cfg_addr, u32 cfg_data)
* 1 == pci agent or pcie end-point
*/
if (!temp8) {
- printf(" Scanning PCI bus %02x\n",
+ debug(" Scanning PCI bus %02x\n",
hose->current_busno);
hose->last_busno = pci_hose_scan_bus(hose, hose->current_busno);
} else {
- debug(" Not scanning PCI bus %02x. PI=%x\n",
+ debug(" Not scanning PCI bus %02x. PI=%x\n",
hose->current_busno, temp8);
hose->last_busno = hose->current_busno;
}
@@ -441,6 +441,8 @@ int fsl_pci_init_port(struct fsl_pci_info *pci_info,
{
volatile ccsr_fsl_pci_t *pci;
struct pci_region *r;
+ pci_dev_t dev = PCI_BDF(busno,0,0);
+ u8 pcie_cap;
pci = (ccsr_fsl_pci_t *) pci_info->regs;
@@ -479,8 +481,10 @@ int fsl_pci_init_port(struct fsl_pci_info *pci_info,
hose->last_busno = hose->first_busno;
}
- printf(" PCIE%x on bus %02x - %02x\n", pci_info->pci_num,
- hose->first_busno, hose->last_busno);
+ pci_hose_read_config_byte(hose, dev, FSL_PCIE_CAP_ID, &pcie_cap);
+ printf("PCI%s%x: Bus %02x - %02x\n", pcie_cap == PCI_CAP_ID_EXP ?
+ "E" : "", pci_info->pci_num,
+ hose->first_busno, hose->last_busno);
return(hose->last_busno + 1);
}
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 848746f..702ac67 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -510,6 +510,71 @@ void pci_cfgfunc_do_nothing(struct pci_controller *hose,
extern int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev);
extern void pciauto_config_init(struct pci_controller *hose);
+#if defined(CONFIG_CMD_PCI) || defined(CONFIG_PCI_SCAN_SHOW)
+const char * pci_class_str(u8 class)
+{
+ switch (class) {
+ case PCI_CLASS_NOT_DEFINED:
+ return "Build before PCI Rev2.0";
+ break;
+ case PCI_BASE_CLASS_STORAGE:
+ return "Mass storage controller";
+ break;
+ case PCI_BASE_CLASS_NETWORK:
+ return "Network controller";
+ break;
+ case PCI_BASE_CLASS_DISPLAY:
+ return "Display controller";
+ break;
+ case PCI_BASE_CLASS_MULTIMEDIA:
+ return "Multimedia device";
+ break;
+ case PCI_BASE_CLASS_MEMORY:
+ return "Memory controller";
+ break;
+ case PCI_BASE_CLASS_BRIDGE:
+ return "Bridge device";
+ break;
+ case PCI_BASE_CLASS_COMMUNICATION:
+ return "Simple comm. controller";
+ break;
+ case PCI_BASE_CLASS_SYSTEM:
+ return "Base system peripheral";
+ break;
+ case PCI_BASE_CLASS_INPUT:
+ return "Input device";
+ break;
+ case PCI_BASE_CLASS_DOCKING:
+ return "Docking station";
+ break;
+ case PCI_BASE_CLASS_PROCESSOR:
+ return "Processor";
+ break;
+ case PCI_BASE_CLASS_SERIAL:
+ return "Serial bus controller";
+ break;
+ case PCI_BASE_CLASS_INTELLIGENT:
+ return "Intelligent controller";
+ break;
+ case PCI_BASE_CLASS_SATELLITE:
+ return "Satellite controller";
+ break;
+ case PCI_BASE_CLASS_CRYPT:
+ return "Cryptographic device";
+ break;
+ case PCI_BASE_CLASS_SIGNAL_PROCESSING:
+ return "DSP";
+ break;
+ case PCI_CLASS_OTHERS:
+ return "Does not fit any class";
+ break;
+ default:
+ return "???";
+ break;
+ };
+}
+#endif /* CONFIG_CMD_PCI || CONFIG_PCI_SCAN_SHOW */
+
int __pci_skip_dev(struct pci_controller *hose, pci_dev_t dev)
{
/*
@@ -551,6 +616,9 @@ int pci_hose_scan_bus(struct pci_controller *hose, int bus)
unsigned char header_type;
struct pci_config_table *cfg;
pci_dev_t dev;
+#ifdef CONFIG_PCI_SCAN_SHOW
+ static int indent = 0;
+#endif
sub_bus = bus;
@@ -568,44 +636,50 @@ int pci_hose_scan_bus(struct pci_controller *hose, int bus)
pci_hose_read_config_word(hose, dev, PCI_VENDOR_ID, &vendor);
- if (vendor != 0xffff && vendor != 0x0000) {
+ if (vendor == 0xffff || vendor == 0x0000)
+ continue;
+
+ if (!PCI_FUNC(dev))
+ found_multi = header_type & 0x80;
- if (!PCI_FUNC(dev))
- found_multi = header_type & 0x80;
+ debug ("PCI Scan: Found Bus %d, Device %d, Function %d\n",
+ PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev) );
- debug ("PCI Scan: Found Bus %d, Device %d, Function %d\n",
- PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev) );
+ pci_hose_read_config_word(hose, dev, PCI_DEVICE_ID, &device);
+ pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class);
- pci_hose_read_config_word(hose, dev, PCI_DEVICE_ID, &device);
- pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class);
+#ifdef CONFIG_PCI_SCAN_SHOW
+ indent++;
- cfg = pci_find_config(hose, class, vendor, device,
- PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev));
- if (cfg) {
- cfg->config_device(hose, dev, cfg);
- sub_bus = max(sub_bus, hose->current_busno);
+ /* Print leading space, including bus indentation */
+ printf("%*c", indent + 1, ' ');
+
+ if (pci_print_dev(hose, dev)) {
+ printf("%02x:%02x.%-*x - %04x:%04x - %s\n",
+ PCI_BUS(dev), PCI_DEV(dev), 6 - indent, PCI_FUNC(dev),
+ vendor, device, pci_class_str(class >> 8));
+ }
+#endif
+
+ cfg = pci_find_config(hose, class, vendor, device,
+ PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev));
+ if (cfg) {
+ cfg->config_device(hose, dev, cfg);
+ sub_bus = max(sub_bus, hose->current_busno);
#ifdef CONFIG_PCI_PNP
- } else {
- int n = pciauto_config_device(hose, dev);
+ } else {
+ int n = pciauto_config_device(hose, dev);
- sub_bus = max(sub_bus, n);
+ sub_bus = max(sub_bus, n);
#endif
- }
- if (hose->fixup_irq)
- hose->fixup_irq(hose, dev);
+ }
#ifdef CONFIG_PCI_SCAN_SHOW
- if (pci_print_dev(hose, dev)) {
- unsigned char int_line;
-
- pci_hose_read_config_byte(hose, dev, PCI_INTERRUPT_LINE,
- &int_line);
- printf(" %02x %02x %04x %04x %04x %02x\n",
- PCI_BUS(dev), PCI_DEV(dev), vendor, device, class,
- int_line);
- }
+ indent--;
#endif
- }
+
+ if (hose->fixup_irq)
+ hose->fixup_irq(hose, dev);
}
return sub_bus;