From fa1823688adaaf8dc32293b3502da7257cec612c Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Tue, 12 Feb 2008 09:06:27 +0100 Subject: [PATCH] Added a simple infrastructure for setting of arbitrary parameters. --- TODO | 1 + lib/init.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++- lib/internal.h | 5 +++- lib/pci.h | 17 ++++++++++++ 4 files changed, 96 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index 9bdedbb..81053e8 100644 --- a/TODO +++ b/TODO @@ -6,6 +6,7 @@ DNS mode: - check handling of network errors - try to avoid libresolv.a - replace "Unknown device" with "Device" +- check the logic around id_load_failed Capabilities with partial decoding: - PCIe 2nd set of control/status registers (have spec) diff --git a/lib/init.c b/lib/init.c index 6366762..11a9af6 100644 --- a/lib/init.c +++ b/lib/init.c @@ -92,6 +92,15 @@ pci_mfree(void *x) free(x); } +char * +pci_strdup(struct pci_access *a, char *s) +{ + int len = strlen(s) + 1; + char *t = pci_malloc(a, len); + memcpy(t, s, len); + return t; +} + static void pci_generic_error(char *msg, ...) { @@ -130,6 +139,70 @@ pci_null_debug(char *msg UNUSED, ...) { } +char * +pci_get_param(struct pci_access *acc, char *param) +{ + struct pci_param *p; + + for (p=acc->params; p; p=p->next) + if (!strcmp(p->param, param)) + return p->value; + return NULL; +} + +void +pci_define_param(struct pci_access *acc, char *param, char *value) +{ + struct pci_param *p = pci_malloc(acc, sizeof(*p)); + + p->next = acc->params; + acc->params = p; + p->param = param; + p->value = value; + p->value_malloced = 0; +} + +int +pci_set_param(struct pci_access *acc, char *param, char *value) +{ + struct pci_param *p; + + for (p=acc->params; p; p=p->next) + if (!strcmp(p->param, param)) + { + if (p->value_malloced) + pci_mfree(p->value); + p->value_malloced = 1; + p->value = pci_strdup(acc, value); + return 0; + } + return -1; +} + +static void +pci_free_params(struct pci_access *acc) +{ + struct pci_param *p; + + while (p = acc->params) + { + acc->params = p->next; + if (p->value_malloced) + pci_mfree(p->value); + pci_mfree(p); + } +} + +struct pci_param * +pci_walk_params(struct pci_access *acc, struct pci_param *prev) +{ + /* So far, the params form a simple linked list, but this can change in the future */ + if (!prev) + return acc->params; + else + return prev->next; +} + void pci_init(struct pci_access *a) { @@ -184,9 +257,9 @@ pci_cleanup(struct pci_access *a) if (a->methods) a->methods->cleanup(a); pci_free_name_list(a); + pci_free_params(a); pci_set_name_list_path(a, NULL, 0); pci_set_net_domain(a, NULL, 0); pci_set_id_cache(a, NULL, 0); pci_mfree(a); } - diff --git a/lib/internal.h b/lib/internal.h index 925eac1..bc88f36 100644 --- a/lib/internal.h +++ b/lib/internal.h @@ -1,7 +1,7 @@ /* * The PCI Library -- Internal Stuff * - * Copyright (c) 1997--2004 Martin Mares + * Copyright (c) 1997--2008 Martin Mares * * Can be freely distributed and used under the terms of the GNU GPL. */ @@ -31,10 +31,13 @@ int pci_generic_block_write(struct pci_dev *, int pos, byte *buf, int len); void *pci_malloc(struct pci_access *, int); void pci_mfree(void *); +char *pci_strdup(struct pci_access *a, char *s); struct pci_dev *pci_alloc_dev(struct pci_access *); int pci_link_dev(struct pci_access *, struct pci_dev *); +void pci_define_param(struct pci_access *acc, char *param, char *val); + extern struct pci_methods pm_intel_conf1, pm_intel_conf2, pm_linux_proc, pm_fbsd_device, pm_aix_device, pm_nbsd_libpci, pm_obsd_device, pm_dump, pm_linux_sysfs; diff --git a/lib/pci.h b/lib/pci.h index 9bf8022..1540ee1 100644 --- a/lib/pci.h +++ b/lib/pci.h @@ -65,6 +65,7 @@ struct pci_access { /* Fields used internally: */ struct pci_methods *methods; + struct pci_param *params; struct id_entry **id_hash; /* names.c */ struct id_bucket *current_id_bucket; int id_load_failed; @@ -85,6 +86,22 @@ void pci_scan_bus(struct pci_access *acc); struct pci_dev *pci_get_dev(struct pci_access *acc, int domain, int bus, int dev, int func); /* Raw access to specified device */ void pci_free_dev(struct pci_dev *); +/* + * Named parameters + */ + +struct pci_param { + struct pci_param *next; /* Please use pci_walk_params() for traversing the list */ + char *param; /* Name of the parameter */ + char *value; /* Value of the parameter */ + int value_malloced; /* used internally */ +}; + +char *pci_get_param(struct pci_access *acc, char *param); +int pci_set_param(struct pci_access *acc, char *param, char *value); /* 0 on success, -1 if no such parameter */ +/* To traverse the list, call pci_walk_params repeatedly, first with prev=NULL, and do not modify the parameters during traversal. */ +struct pci_param *pci_walk_params(struct pci_access *acc, struct pci_param *prev); + /* * Devices */ -- 2.39.2