Parse PCI devices in DBDF form.

This commit is contained in:
Adam Madsen 2020-11-03 18:00:40 -06:00
parent d0b17b2bb5
commit 91ad547e08
4 changed files with 125 additions and 20 deletions

View File

@ -1,3 +1,3 @@
userccflags += -I$(src)/../include userccflags += -I$(src)/../include -g
userprogs-always-y += vendor-reset userprogs-always-y += vendor-reset
vendor-reset-objs += vendor-reset.o vendor-reset-objs += vendor-reset.o ucommon.o

63
userspace/ucommon.c Normal file
View File

@ -0,0 +1,63 @@
/*
Vendor Reset - Vendor Specific Reset
Copyright (C) 2020 Geoffrey McRae <geoff@hostfission.com>
Copyright (C) 2020 Adam Madsen <adam@ajmadsen.com>
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 <string.h>
#include <stdlib.h>
#include <stdio.h>
#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;
}

36
userspace/ucommon.h Normal file
View File

@ -0,0 +1,36 @@
/*
Vendor Reset - Vendor Specific Reset
Copyright (C) 2020 Geoffrey McRae <geoff@hostfission.com>
Copyright (C) 2020 Adam Madsen <adam@ajmadsen.com>
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

View File

@ -1,6 +1,7 @@
/* /*
Vendor Reset - Vendor Specific Reset Vendor Reset - Vendor Specific Reset
Copyright (C) 2020 Geoffrey McRae <geoff@hostfission.com> Copyright (C) 2020 Geoffrey McRae <geoff@hostfission.com>
Copyright (C) 2020 Adam Madsen <adam@ajmadsen.com>
This program is free software; you can redistribute it and/or modify it under 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 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 <fcntl.h> #include <fcntl.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include "vendor-reset.h" #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; int ret;
struct dbdf devref;
if (argc < 4) if (argc < 2)
{ help();
fprintf(stderr,
"Usage:\n"
" %s <domain> <bus> <devfn>\n",
argv[0]
);
return -1;
}
int domain = atoi(argv[1]); if (parse_dbdf(argv[1], &devref))
int bus = atoi(argv[2]); help();
int devfn = atoi(argv[3]);
int fd = open("/dev/vendor_reset", O_RDWR); int fd = open("/dev/vendor_reset", O_RDWR);
if (fd < 0) if (fd < 0)
@ -48,11 +55,10 @@ int main(int argc, char * argv[])
return fd; return fd;
} }
struct vendor_reset_ioctl dev = struct vendor_reset_ioctl dev = {
{ .domain = devref.domain,
.domain = domain, .bus = devref.bus,
.bus = bus, .devfn = ((devref.device & 0x1f) << 3) | (devref.function & 0x07),
.devfn = devfn
}; };
ret = ioctl(fd, VENDOR_RESET_RESET, &dev); ret = ioctl(fd, VENDOR_RESET_RESET, &dev);