Unify PCI init and let pcidev clean itself up
Previously the internal programmer used its own code to initialize pcilib.
This patch extracts the common code from the internal programmer and
pcidev_init() into pcidev_init_common().
This fixes the non-existent PCI cleanup of the internal programmer and adds
an additional safety by checking for an already existing PCI context.
We got a nice shutdown function registration infrastructure, but did not use it
very wisely. Instead we added shutdown functions to a myriad of programmers
unnecessarily. In this patch we get rid of those that do only call pci_cleanup(pacc)
by adding a shutdown function the pcidev.c itself that gets registered by
pcidev_init().
Corresponding to flashrom svn r1642.
Signed-off-by: Stefan Tauner <stefan.tauner@alumni.tuwien.ac.at>
Acked-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>
diff --git a/pcidev.c b/pcidev.c
index 1a26e99..f2c8827 100644
--- a/pcidev.c
+++ b/pcidev.c
@@ -154,6 +154,33 @@
return (uintptr_t)addr;
}
+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__);
+ return 1;
+ }
+ pci_cleanup(pacc);
+ return 0;
+}
+
+int pci_init_common(void)
+{
+ if (pacc != NULL) {
+ msg_perr("%s: Tried to allocate a new PCI context, but there is still an old one!\n"
+ "Please report a bug at flashrom@flashrom.org\n", __func__);
+ return 1;
+ }
+ pacc = pci_alloc(); /* Get the pci_access structure */
+ pci_init(pacc); /* Initialize the PCI library */
+ if (register_shutdown(pcidev_shutdown, NULL))
+ return 1;
+ pci_scan_bus(pacc); /* We want to get the list of devices */
+ return 0;
+}
+
uintptr_t pcidev_init(int bar, const struct dev_entry *devs)
{
struct pci_dev *dev;
@@ -164,9 +191,8 @@
int i;
uintptr_t addr = 0, curaddr = 0;
- pacc = pci_alloc(); /* Get the pci_access structure */
- pci_init(pacc); /* Initialize the PCI library */
- pci_scan_bus(pacc); /* We want to get the list of devices */
+ if(pci_init_common() != 0)
+ return 1;
pci_filter_init(pacc, &filter);
/* Filter by bb:dd.f (if supplied by the user). */
@@ -244,6 +270,11 @@
int undo_pci_write(void *p)
{
struct undo_pci_write_data *data = p;
+ if (pacc == NULL) {
+ msg_perr("%s: Tried to undo PCI writes without a valid PCI context!\n"
+ "Please report a bug at flashrom@flashrom.org\n", __func__);
+ return 1;
+ }
msg_pdbg("Restoring PCI config space for %02x:%02x:%01x reg 0x%02x\n",
data->dev.bus, data->dev.dev, data->dev.func, data->reg);
switch (data->type) {