diff options
-rw-r--r-- | atahpt.c | 11 | ||||
-rw-r--r-- | drkaiser.c | 11 | ||||
-rw-r--r-- | gfxnvidia.c | 11 | ||||
-rw-r--r-- | nic3com.c | 11 | ||||
-rw-r--r-- | nicintel.c | 13 | ||||
-rw-r--r-- | nicintel_spi.c | 7 | ||||
-rw-r--r-- | nicnatsemi.c | 15 | ||||
-rw-r--r-- | nicrealtek.c | 14 | ||||
-rw-r--r-- | ogp_spi.c | 6 | ||||
-rw-r--r-- | pcidev.c | 27 | ||||
-rw-r--r-- | programmer.h | 36 | ||||
-rw-r--r-- | satamv.c | 12 | ||||
-rw-r--r-- | satasii.c | 11 |
13 files changed, 109 insertions, 76 deletions
@@ -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); @@ -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; @@ -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 @@ -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; @@ -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)) @@ -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); @@ -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. @@ -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; } |