void pci_free_dev(struct pci_dev *d) { if (d->methods->cleanup_dev) d->methods->cleanup_dev(d); pci_free_caps(d); pci_mfree(d->phy_slot); pci_mfree(d); }
void pci_free_caps(struct pci_dev *d) { struct pci_cap *cap; while (cap = d->first_cap) { d->first_cap = cap; pci_mfree(d); } }
void pci_cleanup(struct pci_access *a) { struct pci_dev *d, *e; for(d=a->devices; d; d=e) { e = d->next; pci_free_dev(d); } if (a->methods) a->methods->cleanup(a); pci_free_name_list(a); pci_mfree(a); }
void pci_cleanup(struct pci_access *a) { struct pci_dev *d, *e; for(d=a->devices; d; d=e) { e = d->next; pci_free_dev(d); } if (a->methods) { if( a->methods->cleanup != NULL ) { a->methods->cleanup(a); } //this is the bug, we don't need iopl3 cleanup in windows } pci_mfree(a); }
static char *get_cache_name(struct pci_access *a) { char *name, *buf; name = pci_get_param(a, "net.cache_name"); if (!name || !name[0]) return NULL; if (strncmp(name, "~/", 2)) return name; uid_t uid = getuid(); struct passwd *pw = getpwuid(uid); if (!pw) return name; buf = pci_malloc(a, strlen(pw->pw_dir) + strlen(name+1) + 1); sprintf(buf, "%s%s", pw->pw_dir, name+1); pci_set_param_internal(a, "net.cache_name", buf, 1); pci_mfree(buf); return pci_get_param(a, "net.cache_name"); }
void pci_id_cache_flush(struct pci_access *a) { int orig_status = a->id_cache_status; FILE *f; unsigned int h; struct id_entry *e, *e2; char hostname[256], *tmpname, *name; int this_pid; a->id_cache_status = 0; if (orig_status < 2) return; name = get_cache_name(a); if (!name) return; this_pid = getpid(); if (gethostname(hostname, sizeof(hostname)) < 0) hostname[0] = 0; else hostname[sizeof(hostname)-1] = 0; tmpname = pci_malloc(a, strlen(name) + strlen(hostname) + 64); sprintf(tmpname, "%s.tmp-%s-%d", name, hostname, this_pid); f = fopen(tmpname, "wb"); if (!f) { a->warning("Cannot write to %s: %s", name, strerror(errno)); pci_mfree(tmpname); return; } a->debug("Writing cache to %s\n", name); fprintf(f, "%s\n", cache_version); for (h=0; h<HASH_SIZE; h++) for (e=a->id_hash[h]; e; e=e->next) if (e->src == SRC_CACHE || e->src == SRC_NET) { /* Negative entries are not written */ if (!e->name[0]) continue; /* Verify that every entry is written at most once */ for (e2=a->id_hash[h]; e2 != e; e2=e2->next) if ((e2->src == SRC_CACHE || e2->src == SRC_NET) && e2->cat == e->cat && e2->id12 == e->id12 && e2->id34 == e->id34) break; if (e2 == e) fprintf(f, "%d %x %x %x %x %s\n", e->cat, pair_first(e->id12), pair_second(e->id12), pair_first(e->id34), pair_second(e->id34), e->name); } fflush(f); if (ferror(f)) a->warning("Error writing %s", name); fclose(f); if (rename(tmpname, name) < 0) { a->warning("Cannot rename %s to %s: %s", tmpname, name, strerror(errno)); unlink(tmpname); } pci_mfree(tmpname); }
static void dump_init(struct pci_access *a) { char *name = a->method_params[PCI_ACCESS_DUMP]; FILE *f; char buf[256]; struct pci_dev *dev = NULL; int len, mn, bn, dn, fn, i, j; if (!a) a->error("dump: File name not given."); if (!(f = fopen(name, "r"))) a->error("dump: Cannot open %s: %s", name, strerror(errno)); while (fgets(buf, sizeof(buf)-1, f)) { char *z = strchr(buf, '\n'); if (!z) a->error("dump: line too long or unterminated"); *z-- = 0; if (z >= buf && *z == '\r') *z-- = 0; len = z - buf + 1; mn = 0; if ((len >= 8 && buf[2] == ':' && buf[5] == '.' && buf[7] == ' ' && sscanf(buf, "%x:%x.%d ", &bn, &dn, &fn) == 3) || (len >= 13 && buf[4] == ':' && buf[7] == ':' && buf[10] == '.' && buf[12] == ' ' && sscanf(buf, "%x:%x:%x.%d", &mn, &bn, &dn, &fn) == 4)) { dev = pci_get_dev(a, mn, bn, dn, fn); dump_alloc_data(dev, 256); pci_link_dev(a, dev); } else if (!len) dev = NULL; else if (dev && (len >= 51 && buf[2] == ':' && buf[3] == ' ' || len >= 52 && buf[3] == ':' && buf[4] == ' ') && sscanf(buf, "%x: ", &i) == 1) { struct dump_data *dd = dev->aux; z = strchr(buf, ' '); while (isspace(z[0]) && isxdigit(z[1]) && isxdigit(z[2])) { z++; if (sscanf(z, "%x", &j) != 1 || i >= 256) a->error("dump: Malformed line"); if (i >= 4096) break; if (i > dd->allocated) /* Need to re-allocate the buffer */ { dump_alloc_data(dev, 4096); memcpy(((struct dump_data *) dev->aux)->data, dd->data, 256); pci_mfree(dd); dd = dev->aux; } dd->data[i++] = j; if (i > dd->len) dd->len = i; z += 2; } } } }
static void dump_init(struct pci_access *a) { char *name = pci_get_param(a, "dump.name"); FILE *f; char buf[256]; struct pci_dev *dev = NULL; int len, mn, bn, dn, fn, i, j; if (!name) a->error("dump: File name not given."); if (!(f = fopen(name, "r"))) a->error("dump: Cannot open %s: %s", name, strerror(errno)); while (fgets(buf, sizeof(buf)-1, f)) { char *z = strchr(buf, '\n'); if (!z) { fclose(f); a->error("dump: line too long or unterminated"); } *z-- = 0; if (z >= buf && *z == '\r') *z-- = 0; len = z - buf + 1; mn = 0; if ((dump_validate(buf, "##:##.# ") && sscanf(buf, "%x:%x.%d", &bn, &dn, &fn) == 3) || (dump_validate(buf, "####:##:##.# ") && sscanf(buf, "%x:%x:%x.%d", &mn, &bn, &dn, &fn) == 4)) { dev = pci_get_dev(a, mn, bn, dn, fn); dump_alloc_data(dev, 256); pci_link_dev(a, dev); } else if (!len) dev = NULL; else if (dev && (dump_validate(buf, "##: ") || dump_validate(buf, "###: ")) && sscanf(buf, "%x: ", &i) == 1) { struct dump_data *dd = dev->aux; z = strchr(buf, ' ') + 1; while (isxdigit(z[0]) && isxdigit(z[1]) && (!z[2] || z[2] == ' ') && sscanf(z, "%x", &j) == 1 && j < 256) { if (i >= 4096) { fclose(f); a->error("dump: At most 4096 bytes of config space are supported"); } if (i >= dd->allocated) /* Need to re-allocate the buffer */ { dump_alloc_data(dev, 4096); memcpy(((struct dump_data *) dev->aux)->data, dd->data, 256); pci_mfree(dd); dd = dev->aux; } dd->data[i++] = j; if (i > dd->len) dd->len = i; z += 2; if (*z) z++; } if (*z) { fclose(f); a->error("dump: Malformed line"); } } } fclose(f); }