return a;
}
-void
-pci_init_internal(struct pci_access *a, int throw_errors, int skip_method)
+int
+pci_init_internal(struct pci_access *a, int skip_method)
{
if (!a->error)
a->error = pci_generic_error;
if (!a->debugging)
a->debug = pci_null_debug;
- if (a->method)
+ if (a->method != PCI_ACCESS_AUTO)
{
if (a->method >= PCI_ACCESS_MAX || !pci_methods[a->method])
- {
- if (throw_errors)
- a->error("This access method is not supported.");
- return;
- }
+ a->error("This access method is not supported.");
a->methods = pci_methods[a->method];
}
else
a->debug("...No.\n");
}
if (!a->methods)
- {
- if (throw_errors)
- a->error("Cannot find any working access method.");
- return;
- }
+ return 0;
}
a->debug("Decided to use %s\n", a->methods->name);
a->methods->init(a);
+ return 1;
}
void
pci_init_v35(struct pci_access *a)
{
- pci_init_internal(a, 1, -1);
+ if (!pci_init_internal(a, 1, -1))
+ a->error("Cannot find any working access method.");
}
STATIC_ALIAS(void pci_init(struct pci_access *a), pci_init_v35(a));
SYMBOL_VERSION(pci_init_v30, pci_init@LIBPCI_3.0);
SYMBOL_VERSION(pci_init_v35, pci_init@@LIBPCI_3.5);
+struct pci_access *
+pci_clone_access(struct pci_access *a)
+{
+ struct pci_access *b = pci_alloc();
+
+ b->writeable = a->writeable;
+ b->buscentric = a->buscentric;
+ b->debugging = a->debugging;
+ b->error = a->error;
+ b->warning = a->warning;
+ b->debug = a->debug;
+
+ return b;
+}
+
void
pci_cleanup(struct pci_access *a)
{
void *pci_malloc(struct pci_access *, int);
void pci_mfree(void *);
char *pci_strdup(struct pci_access *a, const char *s);
-void pci_init_internal(struct pci_access *a, int throw_errors, int skip_method);
+struct pci_access *pci_clone_access(struct pci_access *a);
+int pci_init_internal(struct pci_access *a, int skip_method);
void pci_init_v30(struct pci_access *a) VERSIONED_ABI;
void pci_init_v35(struct pci_access *a) VERSIONED_ABI;
if (strcmp(cfgmethod, "") == 0 ||
strcmp(cfgmethod, "auto") == 0)
{
- acfg = pci_alloc();
+ acfg = pci_clone_access(a);
acfg->method = PCI_ACCESS_AUTO;
}
- else if (strcmp(cfgmethod, "none") != 0 &&
- strcmp(cfgmethod, "win32-cfgmgr32") != 0)
- {
- int m = pci_lookup_method(cfgmethod);
- if (m < 0)
- a->error("Option win32.cfgmethod is set to unknown access method \"%s\".", cfgmethod);
- acfg = pci_alloc();
- acfg->method = m;
- }
- else
+ else if (strcmp(cfgmethod, "none") == 0 ||
+ strcmp(cfgmethod, "win32-cfgmgr32") == 0)
{
if (a->writeable)
a->error("Write access requested but option win32.cfgmethod was not set.");
return;
}
-
- acfg->writeable = a->writeable;
- acfg->buscentric = a->buscentric;
- acfg->debugging = a->debugging;
- acfg->error = a->error;
- acfg->warning = a->warning;
- acfg->debug = a->debug;
+ else
+ {
+ int m = pci_lookup_method(cfgmethod);
+ if (m < 0)
+ a->error("Option win32.cfgmethod is set to an unknown access method \"%s\".", cfgmethod);
+ acfg = pci_clone_access(a);
+ acfg->method = m;
+ }
a->debug("Loading config space access method...\n");
- pci_init_internal(acfg, 0, PCI_ACCESS_WIN32_CFGMGR32);
- if (!acfg->methods)
+ if (!pci_init_internal(acfg, PCI_ACCESS_WIN32_CFGMGR32))
{
pci_cleanup(acfg);
a->debug("Cannot find any working config space access method.\n");
if (a->writeable)
- a->error("Write access requested but no usable access method.");
+ a->error("Write access requested but no usable access method found.");
return;
}
or an empty string selects the first access method which supports access
to the config space on Windows. Value
.I win32-cfgmgr32
+or
+.I none
only builds a read-only virtual emulated config space with information from the
Configuration Manager.