summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--atahpt.c11
-rw-r--r--drkaiser.c11
-rw-r--r--gfxnvidia.c11
-rw-r--r--nic3com.c11
-rw-r--r--nicintel.c13
-rw-r--r--nicintel_spi.c7
-rw-r--r--nicnatsemi.c15
-rw-r--r--nicrealtek.c14
-rw-r--r--ogp_spi.c6
-rw-r--r--pcidev.c27
-rw-r--r--programmer.h36
-rw-r--r--satamv.c12
-rw-r--r--satasii.c11
13 files changed, 109 insertions, 76 deletions
diff --git a/atahpt.c b/atahpt.c
index d19cb75..f8be8c4 100644
--- a/atahpt.c
+++ b/atahpt.c
@@ -58,17 +58,22 @@ static const struct par_programmer par_programmer_atahpt = {
int atahpt_init(void)
{
+ struct pci_dev *dev = NULL;
uint32_t reg32;
if (rget_io_perms())
return 1;
- io_base_addr = pcidev_init(PCI_BASE_ADDRESS_4, ata_hpt);
+ dev = pcidev_init(ata_hpt, PCI_BASE_ADDRESS_4);
+ if (!dev)
+ return 1;
+
+ io_base_addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_4);
/* Enable flash access. */
- reg32 = pci_read_long(pcidev_dev, REG_FLASH_ACCESS);
+ reg32 = pci_read_long(dev, REG_FLASH_ACCESS);
reg32 |= (1 << 24);
- rpci_write_long(pcidev_dev, REG_FLASH_ACCESS, reg32);
+ rpci_write_long(dev, REG_FLASH_ACCESS, reg32);
register_par_programmer(&par_programmer_atahpt, BUS_PARALLEL);
diff --git a/drkaiser.c b/drkaiser.c
index a6eca1c..b94d6dd 100644
--- a/drkaiser.c
+++ b/drkaiser.c
@@ -64,17 +64,20 @@ static int drkaiser_shutdown(void *data)
int drkaiser_init(void)
{
+ struct pci_dev *dev = NULL;
uint32_t addr;
if (rget_io_perms())
return 1;
- /* No need to check for errors, pcidev_init() will not return in case of errors. */
- addr = pcidev_init(PCI_BASE_ADDRESS_2, drkaiser_pcidev);
+ dev = pcidev_init(drkaiser_pcidev, PCI_BASE_ADDRESS_2);
+ if (!dev)
+ return 1;
+
+ addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_2);
/* Write magic register to enable flash write. */
- rpci_write_word(pcidev_dev, PCI_MAGIC_DRKAISER_ADDR,
- PCI_MAGIC_DRKAISER_VALUE);
+ rpci_write_word(dev, PCI_MAGIC_DRKAISER_ADDR, PCI_MAGIC_DRKAISER_VALUE);
/* Map 128kB flash memory window. */
drkaiser_bar = physmap("Dr. Kaiser PC-Waechter flash memory",
diff --git a/gfxnvidia.c b/gfxnvidia.c
index a994d68..d0a9feb 100644
--- a/gfxnvidia.c
+++ b/gfxnvidia.c
@@ -85,14 +85,17 @@ static int gfxnvidia_shutdown(void *data)
int gfxnvidia_init(void)
{
+ struct pci_dev *dev = NULL;
uint32_t reg32;
if (rget_io_perms())
return 1;
- /* No need to check for errors, pcidev_init() will not return in case of errors. */
- io_base_addr = pcidev_init(PCI_BASE_ADDRESS_0, gfx_nvidia);
+ dev = pcidev_init(gfx_nvidia, PCI_BASE_ADDRESS_0);
+ if (!dev)
+ return 1;
+ io_base_addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_0);
io_base_addr += 0x300000;
msg_pinfo("Detected NVIDIA I/O base address: 0x%x.\n", io_base_addr);
@@ -102,9 +105,9 @@ int gfxnvidia_init(void)
return 1;
/* Allow access to flash interface (will disable screen). */
- reg32 = pci_read_long(pcidev_dev, 0x50);
+ reg32 = pci_read_long(dev, 0x50);
reg32 &= ~(1 << 0);
- rpci_write_long(pcidev_dev, 0x50, reg32);
+ rpci_write_long(dev, 0x50, reg32);
/* Write/erase doesn't work. */
programmer_may_write = 0;
diff --git a/nic3com.c b/nic3com.c
index 4ec6193..8d67b54 100644
--- a/nic3com.c
+++ b/nic3com.c
@@ -86,13 +86,18 @@ static int nic3com_shutdown(void *data)
int nic3com_init(void)
{
+ struct pci_dev *dev = NULL;
+
if (rget_io_perms())
return 1;
- /* No need to check for errors, pcidev_init() will not return in case of errors. */
- io_base_addr = pcidev_init(PCI_BASE_ADDRESS_0, nics_3com);
+ dev = pcidev_init(nics_3com, PCI_BASE_ADDRESS_0);
+ if (!dev)
+ return 1;
+
+ io_base_addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_0);
- id = pcidev_dev->device_id;
+ id = dev->device_id;
/* 3COM 3C90xB cards need a special fixup. */
if (id == 0x9055 || id == 0x9001 || id == 0x9004 || id == 0x9005
diff --git a/nicintel.c b/nicintel.c
index 8481915..56678e7 100644
--- a/nicintel.c
+++ b/nicintel.c
@@ -68,6 +68,7 @@ static int nicintel_shutdown(void *data)
int nicintel_init(void)
{
+ struct pci_dev *dev = NULL;
uintptr_t addr;
/* Needed only for PCI accesses on some platforms.
@@ -76,17 +77,17 @@ int nicintel_init(void)
if (rget_io_perms())
return 1;
- /* No need to check for errors, pcidev_init() will not return in case of errors.
- * FIXME: BAR2 is not available if the device uses the CardBus function.
- */
- addr = pcidev_init(PCI_BASE_ADDRESS_2, nics_intel);
+ /* FIXME: BAR2 is not available if the device uses the CardBus function. */
+ dev = pcidev_init(nics_intel, PCI_BASE_ADDRESS_2);
+ if (!dev)
+ return 1;
+ addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_2);
nicintel_bar = physmap("Intel NIC flash", addr, NICINTEL_MEMMAP_SIZE);
if (nicintel_bar == ERROR_PTR)
goto error_out_unmap;
- /* FIXME: Using pcidev_dev _will_ cause pretty explosions in the future. */
- addr = pcidev_readbar(pcidev_dev, PCI_BASE_ADDRESS_0);
+ addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_0);
/* FIXME: This is not an aligned mapping. Use 4k? */
nicintel_control_bar = physmap("Intel NIC control/status reg",
addr, NICINTEL_CONTROL_MEMMAP_SIZE);
diff --git a/nicintel_spi.c b/nicintel_spi.c
index f61c2b1..0045c09 100644
--- a/nicintel_spi.c
+++ b/nicintel_spi.c
@@ -166,14 +166,17 @@ static int nicintel_spi_shutdown(void *data)
int nicintel_spi_init(void)
{
+ struct pci_dev *dev = NULL;
uint32_t tmp;
if (rget_io_perms())
return 1;
- /* No need to check for errors, pcidev_init() will not return in case of errors. */
- io_base_addr = pcidev_init(PCI_BASE_ADDRESS_0, nics_intel_spi);
+ dev = pcidev_init(nics_intel_spi, PCI_BASE_ADDRESS_0);
+ if (!dev)
+ return 1;
+ io_base_addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_0);
nicintel_spibar = physmap("Intel Gigabit NIC w/ SPI flash",
io_base_addr, MEMMAP_SIZE);
/* Automatic restore of EECD on shutdown is not possible because EECD
diff --git a/nicnatsemi.c b/nicnatsemi.c
index 60d8f87..d62a73f 100644
--- a/nicnatsemi.c
+++ b/nicnatsemi.c
@@ -52,22 +52,19 @@ static const struct par_programmer par_programmer_nicnatsemi = {
.chip_writen = fallback_chip_writen,
};
-static int nicnatsemi_shutdown(void *data)
-{
- pci_cleanup(pacc);
- return 0;
-}
-
int nicnatsemi_init(void)
{
+ struct pci_dev *dev = NULL;
+
if (rget_io_perms())
return 1;
- io_base_addr = pcidev_init(PCI_BASE_ADDRESS_0, nics_natsemi);
-
- if (register_shutdown(nicnatsemi_shutdown, NULL))
+ dev = pcidev_init(nics_natsemi, PCI_BASE_ADDRESS_0);
+ if (!dev)
return 1;
+ io_base_addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_0);
+
/* The datasheet shows address lines MA0-MA16 in one place and MA0-MA15
* in another. My NIC has MA16 connected to A16 on the boot ROM socket
* so I'm assuming it is accessible. If not then next line wants to be
diff --git a/nicrealtek.c b/nicrealtek.c
index 8349b42..fb8e9e1 100644
--- a/nicrealtek.c
+++ b/nicrealtek.c
@@ -59,16 +59,19 @@ static int nicrealtek_shutdown(void *data)
int nicrealtek_init(void)
{
+ struct pci_dev *dev = NULL;
+
if (rget_io_perms())
return 1;
- /* No need to check for errors, pcidev_init() will not return in case of errors. */
- io_base_addr = pcidev_init(PCI_BASE_ADDRESS_0, nics_realtek);
- if (register_shutdown(nicrealtek_shutdown, NULL))
+ dev = pcidev_init(nics_realtek, PCI_BASE_ADDRESS_0);
+ if (!dev)
return 1;
+ io_base_addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_0);
+
/* Beware, this ignores the vendor ID! */
- switch (pcidev_dev->device_id) {
+ switch (dev->device_id) {
case 0x8139: /* RTL8139 */
case 0x1211: /* SMC 1211TX */
default:
@@ -81,6 +84,9 @@ int nicrealtek_init(void)
break;
}
+ if (register_shutdown(nicrealtek_shutdown, NULL))
+ return 1;
+
register_par_programmer(&par_programmer_nicrealtek, BUS_PARALLEL);
return 0;
diff --git a/ogp_spi.c b/ogp_spi.c
index 6fb1a77..0c09d6a 100644
--- a/ogp_spi.c
+++ b/ogp_spi.c
@@ -105,6 +105,7 @@ static int ogp_spi_shutdown(void *data)
int ogp_spi_init(void)
{
+ struct pci_dev *dev = NULL;
char *type;
type = extract_programmer_param("rom");
@@ -131,8 +132,11 @@ int ogp_spi_init(void)
if (rget_io_perms())
return 1;
- io_base_addr = pcidev_init(PCI_BASE_ADDRESS_0, ogp_spi);
+ dev = pcidev_init(ogp_spi, PCI_BASE_ADDRESS_0);
+ if (!dev)
+ return 1;
+ io_base_addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_0);
ogp_spibar = physmap("OGP registers", io_base_addr, 4096);
if (register_shutdown(ogp_spi_shutdown, NULL))
diff --git a/pcidev.c b/pcidev.c
index f2c8827..c7e9d78 100644
--- a/pcidev.c
+++ b/pcidev.c
@@ -27,7 +27,6 @@
uint32_t io_base_addr;
struct pci_access *pacc;
-struct pci_dev *pcidev_dev = NULL;
enum pci_bartype {
TYPE_MEMBAR,
@@ -156,7 +155,6 @@ uintptr_t pcidev_readbar(struct pci_dev *dev, int bar)
static int pcidev_shutdown(void *data)
{
- pcidev_dev = NULL;
if (pacc == NULL) {
msg_perr("%s: Tried to cleanup an invalid PCI context!\n"
"Please report a bug at flashrom@flashrom.org\n", __func__);
@@ -181,18 +179,24 @@ int pci_init_common(void)
return 0;
}
-uintptr_t pcidev_init(int bar, const struct dev_entry *devs)
+/* pcidev_init gets an array of allowed PCI device IDs and returns a pointer to struct pci_dev iff exactly one
+ * match was found. If the "pci=bb:dd.f" programmer parameter was specified, a match is only considered if it
+ * also matches the specified bus:device.function.
+ * For convenience, this function also registers its own undo handlers.
+ */
+struct pci_dev *pcidev_init(const struct dev_entry *devs, int bar)
{
struct pci_dev *dev;
+ struct pci_dev *found_dev = NULL;
struct pci_filter filter;
char *pcidev_bdf;
char *msg = NULL;
int found = 0;
int i;
- uintptr_t addr = 0, curaddr = 0;
+ uintptr_t addr = 0;
- if(pci_init_common() != 0)
- return 1;
+ if (pci_init_common() != 0)
+ return NULL;
pci_filter_init(pacc, &filter);
/* Filter by bb:dd.f (if supplied by the user). */
@@ -200,7 +204,7 @@ uintptr_t pcidev_init(int bar, const struct dev_entry *devs)
if (pcidev_bdf != NULL) {
if ((msg = pci_filter_parse_slot(&filter, pcidev_bdf))) {
msg_perr("Error: %s\n", msg);
- exit(1);
+ return NULL;
}
}
free(pcidev_bdf);
@@ -230,8 +234,7 @@ uintptr_t pcidev_init(int bar, const struct dev_entry *devs)
* just those with a valid BAR.
*/
if ((addr = pcidev_readbar(dev, bar)) != 0) {
- curaddr = addr;
- pcidev_dev = dev;
+ found_dev = dev;
found++;
}
}
@@ -240,14 +243,14 @@ uintptr_t pcidev_init(int bar, const struct dev_entry *devs)
/* Only continue if exactly one supported PCI dev has been found. */
if (found == 0) {
msg_perr("Error: No supported PCI device found.\n");
- exit(1);
+ return NULL;
} else if (found > 1) {
msg_perr("Error: Multiple supported PCI devices found. Use 'flashrom -p xxxx:pci=bb:dd.f' \n"
"to explicitly select the card with the given BDF (PCI bus, device, function).\n");
- exit(1);
+ return NULL;
}
- return curaddr;
+ return found_dev;
}
enum pci_write_type {
diff --git a/programmer.h b/programmer.h
index 4302809..51a8c80 100644
--- a/programmer.h
+++ b/programmer.h
@@ -160,8 +160,25 @@ struct bitbang_spi_master {
unsigned int half_period;
};
-#if CONFIG_INTERNAL == 1
+#if NEED_PCI == 1
struct pci_dev;
+
+/* pcidev.c */
+// FIXME: These need to be local, not global
+extern uint32_t io_base_addr;
+extern struct pci_access *pacc;
+int pci_init_common(void);
+uintptr_t pcidev_readbar(struct pci_dev *dev, int bar);
+struct pci_dev *pcidev_init(const struct dev_entry *devs, int bar);
+/* rpci_write_* are reversible writes. The original PCI config space register
+ * contents will be restored on shutdown.
+ */
+int rpci_write_byte(struct pci_dev *dev, int reg, uint8_t data);
+int rpci_write_word(struct pci_dev *dev, int reg, uint16_t data);
+int rpci_write_long(struct pci_dev *dev, int reg, uint32_t data);
+#endif
+
+#if CONFIG_INTERNAL == 1
struct penable {
uint16_t vendor_id;
uint16_t device_id;
@@ -232,23 +249,6 @@ void myusec_delay(int usecs);
void myusec_calibrate_delay(void);
void internal_delay(int usecs);
-#if NEED_PCI == 1
-/* pcidev.c */
-// FIXME: These need to be local, not global
-extern uint32_t io_base_addr;
-extern struct pci_access *pacc;
-extern struct pci_dev *pcidev_dev;
-int pci_init_common(void);
-uintptr_t pcidev_readbar(struct pci_dev *dev, int bar);
-uintptr_t pcidev_init(int bar, const struct dev_entry *devs);
-/* rpci_write_* are reversible writes. The original PCI config space register
- * contents will be restored on shutdown.
- */
-int rpci_write_byte(struct pci_dev *dev, int reg, uint8_t data);
-int rpci_write_word(struct pci_dev *dev, int reg, uint16_t data);
-int rpci_write_long(struct pci_dev *dev, int reg, uint32_t data);
-#endif
-
#if CONFIG_INTERNAL == 1
/* board_enable.c */
int board_parse_parameter(const char *boardstring, const char **vendor, const char **model);
diff --git a/satamv.c b/satamv.c
index 46a0e2d..c3f27e7 100644
--- a/satamv.c
+++ b/satamv.c
@@ -81,6 +81,7 @@ static int satamv_shutdown(void *data)
*/
int satamv_init(void)
{
+ struct pci_dev *dev = NULL;
uintptr_t addr;
uint32_t tmp;
@@ -88,11 +89,11 @@ int satamv_init(void)
return 1;
/* BAR0 has all internal registers memory mapped. */
- /* No need to check for errors, pcidev_init() will not return in case
- * of errors.
- */
- addr = pcidev_init(PCI_BASE_ADDRESS_0, satas_mv);
+ dev = pcidev_init(satas_mv, PCI_BASE_ADDRESS_0);
+ if (!dev)
+ return 1;
+ addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_0);
mv_bar = physmap("Marvell 88SX7042 registers", addr, 0x20000);
if (mv_bar == ERROR_PTR)
return 1;
@@ -143,8 +144,7 @@ int satamv_init(void)
pci_rmmio_writel(tmp, mv_bar + GPIO_PORT_CONTROL);
/* Get I/O BAR location. */
- tmp = pci_read_long(pcidev_dev, PCI_BASE_ADDRESS_2) &
- PCI_BASE_ADDRESS_IO_MASK;
+ tmp = pcidev_readbar(dev, PCI_BASE_ADDRESS_2);
/* Truncate to reachable range.
* FIXME: Check if the I/O BAR is actually reachable.
* This is an arch specific check.
diff --git a/satasii.c b/satasii.c
index ec65bd0..72e35e5 100644
--- a/satasii.c
+++ b/satasii.c
@@ -76,21 +76,24 @@ static uint32_t satasii_wait_done(void)
int satasii_init(void)
{
+ struct pci_dev *dev = NULL;
uint32_t addr;
uint16_t reg_offset;
if (rget_io_perms())
return 1;
- pcidev_init(PCI_BASE_ADDRESS_0, satas_sii);
+ dev = pcidev_init(satas_sii, PCI_BASE_ADDRESS_0);
+ if (!dev)
+ return 1;
- id = pcidev_dev->device_id;
+ id = dev->device_id;
if ((id == 0x3132) || (id == 0x3124)) {
- addr = pci_read_long(pcidev_dev, PCI_BASE_ADDRESS_0) & ~0x07;
+ addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_0);
reg_offset = 0x70;
} else {
- addr = pci_read_long(pcidev_dev, PCI_BASE_ADDRESS_5) & ~0x07;
+ addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_5);
reg_offset = 0x50;
}
OpenPOWER on IntegriCloud