diff --git a/userspace/Makefile b/userspace/Makefile index 1c3e3fe..8a4f23f 100644 --- a/userspace/Makefile +++ b/userspace/Makefile @@ -1,3 +1,3 @@ -userccflags += -I$(src)/../include +userccflags += -I$(src)/../include -g userprogs-always-y += vendor-reset -vendor-reset-objs += vendor-reset.o \ No newline at end of file +vendor-reset-objs += vendor-reset.o ucommon.o \ No newline at end of file diff --git a/userspace/ucommon.c b/userspace/ucommon.c new file mode 100644 index 0000000..ba83daf --- /dev/null +++ b/userspace/ucommon.c @@ -0,0 +1,63 @@ +/* +Vendor Reset - Vendor Specific Reset +Copyright (C) 2020 Geoffrey McRae +Copyright (C) 2020 Adam Madsen + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include +#include "ucommon.h" + +int parse_dbdf(const char *dbdf_str, struct dbdf *out) +{ + char *dbdf, *tok; + + if (!dbdf_str || !(dbdf = strdup(dbdf_str))) + return 1; + + if (!(tok = strtok(dbdf, ":"))) + goto err; + + out->domain = 0; + out->bus = strtoul(tok, NULL, 16); + + tok = strtok(NULL, ":"); + if (strtok(NULL, ":")) + { + out->domain = out->bus; + out->bus = strtoul(tok, NULL, 16); + /* guaranteed to be okay */ + tok += strlen(tok) + 1; + } + + if (!(tok = strtok(tok, "."))) + goto err; + + out->device = strtoul(tok, NULL, 16); + + if (!(tok = strtok(NULL, "."))) + goto err; + + out->function = strtoul(tok, NULL, 16); + + free(dbdf); + return 0; + +err: + free(dbdf); + return 1; +} \ No newline at end of file diff --git a/userspace/ucommon.h b/userspace/ucommon.h new file mode 100644 index 0000000..14df46c --- /dev/null +++ b/userspace/ucommon.h @@ -0,0 +1,36 @@ +/* +Vendor Reset - Vendor Specific Reset +Copyright (C) 2020 Geoffrey McRae +Copyright (C) 2020 Adam Madsen + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef __VENDOR_RESET_UCOMMON_H__ +#define __VENDOR_RESET_UCOMMON_H__ + +struct dbdf +{ + int domain; + int bus; + int device; + int function; +}; + +/* + * parse [domain:]bus:device.fn type addresses + */ +extern int parse_dbdf(const char *dbdf_str, struct dbdf *out); + +#endif \ No newline at end of file diff --git a/userspace/vendor-reset.c b/userspace/vendor-reset.c index bafb5d6..7120191 100644 --- a/userspace/vendor-reset.c +++ b/userspace/vendor-reset.c @@ -1,6 +1,7 @@ /* Vendor Reset - Vendor Specific Reset Copyright (C) 2020 Geoffrey McRae +Copyright (C) 2020 Adam Madsen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -22,24 +23,30 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include #include #include "vendor-reset.h" +#include "ucommon.h" -int main(int argc, char * argv[]) +void help_(const char *prog); + +void help_(const char *prog) +{ + fprintf(stderr, + "Usage:\n" + " %s [domain:]bus:dev.fn\n", + prog); + exit(1); +} +#define help() help_(argv[0]) + +int main(int argc, char *argv[]) { int ret; + struct dbdf devref; - if (argc < 4) - { - fprintf(stderr, - "Usage:\n" - " %s \n", - argv[0] - ); - return -1; - } + if (argc < 2) + help(); - int domain = atoi(argv[1]); - int bus = atoi(argv[2]); - int devfn = atoi(argv[3]); + if (parse_dbdf(argv[1], &devref)) + help(); int fd = open("/dev/vendor_reset", O_RDWR); if (fd < 0) @@ -48,11 +55,10 @@ int main(int argc, char * argv[]) return fd; } - struct vendor_reset_ioctl dev = - { - .domain = domain, - .bus = bus, - .devfn = devfn + struct vendor_reset_ioctl dev = { + .domain = devref.domain, + .bus = devref.bus, + .devfn = ((devref.device & 0x1f) << 3) | (devref.function & 0x07), }; ret = ioctl(fd, VENDOR_RESET_RESET, &dev);