diff options
author | Stephen Hemminger <shemminger@vyatta.com> | 2012-03-16 15:41:29 -0700 |
---|---|---|
committer | Stephen Hemminger <shemminger@vyatta.com> | 2012-03-16 15:41:29 -0700 |
commit | 3dcf4140386b3e63955790d87093521f021bedee (patch) | |
tree | 1d1eeb5723da2b0a9c6cc1e848824010c16fc6bb | |
parent | 868f348533d99b05782cd8bfedb18b9f91b393bc (diff) | |
download | vyatta-biosdevname-3dcf4140386b3e63955790d87093521f021bedee.tar.gz vyatta-biosdevname-3dcf4140386b3e63955790d87093521f021bedee.zip |
Add option to search for device based on pci-id
To support case where device is not in kernel (userspace networking)
need a method for finding device by pci-id. Biosdevname was already
building the table, this just adds an alternative lookup algorithm.
-rw-r--r-- | src/bios_dev_name.c | 43 | ||||
-rw-r--r-- | src/bios_dev_name.h | 2 | ||||
-rw-r--r-- | src/bios_device.c | 32 | ||||
-rw-r--r-- | src/libbiosdevname.h | 1 | ||||
-rw-r--r-- | src/pci.c | 2 | ||||
-rw-r--r-- | src/pci.h | 1 |
6 files changed, 66 insertions, 15 deletions
diff --git a/src/bios_dev_name.c b/src/bios_dev_name.c index dd47fc3..ae994ab 100644 --- a/src/bios_dev_name.c +++ b/src/bios_dev_name.c @@ -24,6 +24,7 @@ static void usage(void) fprintf(stderr, "Usage: biosdevname [options] [args]...\n"); fprintf(stderr, " Options:\n"); fprintf(stderr, " -i or --interface treat [args] as ethernet devs\n"); + fprintf(stderr, " --pci-spec treat [args] as PCI specification\n"); fprintf(stderr, " -d or --debug enable debugging\n"); fprintf(stderr, " --policy [physical | all_ethN ]\n"); fprintf(stderr, " --prefix [string] string use for embedded NICs (default='em')\n"); @@ -36,6 +37,12 @@ static void usage(void) fprintf(stderr, " You must be root to run this, as it must read from /dev/mem.\n"); } +static void conflict(void) +{ + fprintf(stderr, "can't use both interface and pci options\n"); + exit(1); +} + static int set_policy(const char *arg) { @@ -65,6 +72,7 @@ parse_opts(int argc, char **argv) {"nopirq", no_argument, 0, 'x'}, {"invm", no_argument, 0, 'V'}, {"smbios", required_argument, 0, 's'}, + {"pci-spec", no_argument, 0, 'S'}, {0, 0, 0, 0} }; c = getopt_long(argc, argv, @@ -77,8 +85,15 @@ parse_opts(int argc, char **argv) opts.debug = 1; break; case 'i': + if (opts.usepci) + conflict(); opts.interface = 1; break; + case 'S': + if (opts.interface) + conflict(); + opts.usepci = 1; + break; case 'p': opts.namingpolicy = set_policy(optarg); break; @@ -172,21 +187,29 @@ int main(int argc, char *argv[]) goto out_cleanup; } - - if (!opts.interface) { + if (opts.interface) { + for (i=0; i<opts.argc; i++) { + name = kern_to_bios(cookie, opts.argv[i]); + if (name) + printf("%s\n", name); + else + rc |= 2; /* one or more given devices weren't found */ + } + } else if(opts.usepci) { + for (i=0; i<opts.argc; i++) { + name = pci_to_bios(cookie, opts.argv[i]); + if (name) + printf("%s\n", name); + else + rc |= 2; + } + } else { fprintf(stderr, "Unknown device type, try passing an option like -i\n"); rc = 1; goto out_usage; } - for (i=0; i<opts.argc; i++) { - name = kern_to_bios(cookie, opts.argv[i]); - if (name) { - printf("%s\n", name); - } - else - rc |= 2; /* one or more given devices weren't found */ - } + goto out_cleanup; out_usage: diff --git a/src/bios_dev_name.h b/src/bios_dev_name.h index 636c5e1..98197d4 100644 --- a/src/bios_dev_name.h +++ b/src/bios_dev_name.h @@ -15,6 +15,6 @@ struct bios_dev_name_opts { const char *prefix; unsigned int debug:1; unsigned int interface:1; + unsigned int usepci:1; }; - #endif /* GLUE_H_INCLUDED */ diff --git a/src/bios_device.c b/src/bios_device.c index 24b0a77..e04c5b9 100644 --- a/src/bios_device.c +++ b/src/bios_device.c @@ -89,6 +89,33 @@ char * kern_to_bios(void *cookie, return NULL; } +char * pci_to_bios(void *cookie, const char *s) +{ + struct libbiosdevname_state *state = cookie; + struct bios_device *dev; + int domain=0, bus=0, device=0, func=0; + + if (parse_pci_name(s, &domain, &bus, &device, &func)) { + fprintf(stderr, "%s is not a valid pci device name\n", s); + return NULL; + } + + if (!state) + return NULL; + + list_for_each_entry(dev, &state->bios_devices, node) { + const struct pci_device *pci = dev->pcidev; + + if(pci && + pci->pci_dev->domain == domain && + pci->pci_dev->bus == bus && + pci->pci_dev->dev == device && + pci->pci_dev->func == func) + return dev->bios_name; + } + return NULL; +} + void unparse_bios_device_list(void *cookie) { struct libbiosdevname_state *state = cookie; @@ -220,8 +247,6 @@ static void match_eth_and_pci_devs(struct libbiosdevname_state *state) unparse_pci_name(pci_name, sizeof(pci_name), p->pci_dev); n = find_net_device_by_bus_info(state, pci_name); - if (!n) - continue; b = malloc(sizeof(*b)); if (!b) @@ -230,7 +255,8 @@ static void match_eth_and_pci_devs(struct libbiosdevname_state *state) INIT_LIST_HEAD(&b->node); b->pcidev = p; b->netdev = n; - claim_netdev(b->netdev); + if (n) + claim_netdev(b->netdev); list_add(&b->node, &state->bios_devices); } } diff --git a/src/libbiosdevname.h b/src/libbiosdevname.h index 37eccb1..505b234 100644 --- a/src/libbiosdevname.h +++ b/src/libbiosdevname.h @@ -14,6 +14,7 @@ enum namingpolicy { extern void * setup_bios_devices(int namingpolicy, const char *prefix); extern void cleanup_bios_devices(void *cookie); extern char * kern_to_bios(void *cookie, const char *devname); +extern char * pci_to_bios(void *cookie, const char *spec); extern void unparse_bios_devices(void *cookie); extern void unparse_bios_device_by_name(void *cookie, const char *name); @@ -365,7 +365,7 @@ static int read_virtfn_index(unsigned int *index, const struct pci_dev *pdev) return rc; } -static int parse_pci_name(const char *s, int *domain, int *bus, int *dev, int *func) +int parse_pci_name(const char *s, int *domain, int *bus, int *dev, int *func) { int err; /* The domain part was added in 2.6 kernels. Test for that first. */ @@ -57,6 +57,7 @@ extern void free_pci_devices(struct libbiosdevname_state *state); extern struct pci_device * find_dev_by_pci(const struct libbiosdevname_state *state, const struct pci_dev *p); extern struct pci_device * find_pci_dev_by_pci_addr(const struct libbiosdevname_state *state, const int domain, const int bus, const int device, const int func); extern struct pci_device * find_dev_by_pci_name(const struct libbiosdevname_state *state, const char *s); +extern int parse_pci_name(const char *s, int *domain, int *bus, int *dev, int *func); extern int unparse_pci_device(char *buf, const int size, const struct pci_device *p); extern int unparse_pci_name(char *buf, int size, const struct pci_dev *pdev); |