summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoan Lledó <jlledom@member.fsf.org>2020-02-15 11:52:21 +0100
committerJoan Lledó <jlledom@member.fsf.org>2020-02-23 17:47:42 +0100
commitd6ac4187fcb0bae48e421cdb265dd1636543a996 (patch)
tree7ea9a1a95f9858325cf5609f1981d924840977f9
parentb264dbd27739600955a365725f66ceae47e8a456 (diff)
pci-arbiter: Add --device command line option
Shortcut for -d, -b, -s and -f Usage: --device [<domain>:]<bus>:<slot>.<func> E.G. --device 00:05.0 is shortcut for -d 0 -b 0 -s 5 -f 0 * pci-arbiter/options.c: Implement --slot option * pci-arbiter/options.h: Add --slot to options list
-rw-r--r--pci-arbiter/options.c57
-rw-r--r--pci-arbiter/options.h2
2 files changed, 59 insertions, 0 deletions
diff --git a/pci-arbiter/options.c b/pci-arbiter/options.c
index 01686fcd9..2023fd9e2 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;
}
diff --git a/pci-arbiter/options.h b/pci-arbiter/options.h
index 9a25c6030..8e5a9da47 100644
--- a/pci-arbiter/options.h
+++ b/pci-arbiter/options.h
@@ -57,6 +57,8 @@ static const struct argp_option options[] = {
{"bus", 'b', "BUS", 0, "Device bus in hexadecimal"},
{"slot", 's', "SLOT", 0, "Device slot in hexadecimal, requires -b"},
{"func", 'f', "FUNC", 0, "Device func in hexadecimal, requires -s"},
+ {"device", 'D', "DEVICE", 0,
+ "Device address in format [<domain>:]<bus>:<slot>.<func>"},
{0, 0, 0, 0, "These apply to a given permission scope:", 2},
{"uid", 'U', "UID", 0, "User ID to give permissions to"},
{"gid", 'G', "GID", 0, "Group ID to give permissions to"},