- 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)
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, ...)
{
{
}
+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)
{
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);
}
-
/*
* The PCI Library -- Internal Stuff
*
- * Copyright (c) 1997--2004 Martin Mares <mj@ucw.cz>
+ * Copyright (c) 1997--2008 Martin Mares <mj@ucw.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
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;
/* 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;
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
*/