diff options
Diffstat (limited to 'pci-arbiter/options.c')
-rw-r--r-- | pci-arbiter/options.c | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/pci-arbiter/options.c b/pci-arbiter/options.c index 01686fcd..2023fd9e 100644 --- a/pci-arbiter/options.c +++ b/pci-arbiter/options.c @@ -27,9 +27,13 @@ #include <argp.h> #include <argz.h> #include <error.h> +#include <regex.h> #include "pcifs.h" +#define PCI_SLOT_REGEX "^(([0-9a-fA-F]{4}):)?([0-9a-fA-F]{2}):([0-9a-fA-F]{2})\\.([0-7])$" +#define PCI_SLOT_REGEX_GROUPS 6 // 2: Domain, 3: Bus, 4: Dev, 5: Func + /* Fsysopts and command line option parsing */ /* Adds an empty interface slot to H, and sets H's current interface to it, or @@ -91,6 +95,9 @@ parse_opt (int opt, char *arg, struct argp_state *state) { error_t err = 0; struct parse_hook *h = state->hook; + regex_t slot_regex; + regmatch_t slot_regex_groups[PCI_SLOT_REGEX_GROUPS]; + char regex_group_val[5]; /* Return _ERR from this routine */ #define RETURN(_err) \ @@ -111,6 +118,11 @@ parse_opt (int opt, char *arg, struct argp_state *state) state->next++; } + /* Compile regular expression to check --slot option */ + err = regcomp (&slot_regex, PCI_SLOT_REGEX, REG_EXTENDED); + if (err) + FAIL (err, 1, err, "option parsing"); + switch (opt) { case 'C': @@ -134,6 +146,48 @@ parse_opt (int opt, char *arg, struct argp_state *state) case 'f': h->curset->func = strtol (arg, 0, 16); break; + case 'D': + err = + regexec (&slot_regex, arg, PCI_SLOT_REGEX_GROUPS, slot_regex_groups, + 0); + if (!err) + { + // Domain, 0000 by default + if (slot_regex_groups[2].rm_so >= 0) + { + strncpy (regex_group_val, arg + slot_regex_groups[2].rm_so, 4); + regex_group_val[4] = 0; + } + else + { + strncpy (regex_group_val, "0000", 5); + } + + h->curset->domain = strtol (regex_group_val, 0, 16); + + // Bus + strncpy (regex_group_val, arg + slot_regex_groups[3].rm_so, 2); + regex_group_val[2] = 0; + + h->curset->bus = strtol (regex_group_val, 0, 16); + + // Dev + strncpy (regex_group_val, arg + slot_regex_groups[4].rm_so, 2); + regex_group_val[2] = 0; + + h->curset->dev = strtol (regex_group_val, 0, 16); + + // Func + regex_group_val[0] = arg[slot_regex_groups[5].rm_so]; + regex_group_val[1] = 0; + + h->curset->func = strtol (regex_group_val, 0, 16); + } + else + { + PERR (err, "Wrong PCI slot. Format: [<domain>:]<bus>:<dev>.<func>"); + } + break; case 'U': if (h->curset->uid >= 0) parse_hook_add_set (h); @@ -227,6 +281,9 @@ parse_opt (int opt, char *arg, struct argp_state *state) return ARGP_ERR_UNKNOWN; } + /* Free allocated regular expression for the --slot option */ + regfree (&slot_regex); + return err; } |