blob: caa62141921ec20e135009106611801544cc5869 [file] [log] [blame]
Isaac Dunhamfe03a1f2013-07-26 15:41:31 -05001/*
2 * lspci - written by Isaac Dunham
3
Felix Jandaf97cc9f2013-07-26 22:49:05 -05004USE_LSPCI(NEWTOY(lspci, "emkns:", TOYFLAG_USR|TOYFLAG_BIN))
Isaac Dunhamfe03a1f2013-07-26 15:41:31 -05005
6config LSPCI
7 bool "lspci"
8 default n
9 help
Felix Jandaf97cc9f2013-07-26 22:49:05 -050010 usage: lspci [-ekmn]
Isaac Dunhamfe03a1f2013-07-26 15:41:31 -050011
12 List PCI devices.
Felix Jandaf97cc9f2013-07-26 22:49:05 -050013 -e Print all 6 digits in class (like elspci)
Isaac Dunhamfe03a1f2013-07-26 15:41:31 -050014 -k Print kernel driver
15 -m Machine parseable format
16 -n Numeric output (default)
17*/
18#define FOR_lspci
19#include "toys.h"
Isaac Dunhamfe03a1f2013-07-26 15:41:31 -050020
21int do_lspci(struct dirtree *new)
22{
Felix Jandaf97cc9f2013-07-26 22:49:05 -050023 int alen = 8, dirfd;
Isaac Dunhamfe03a1f2013-07-26 15:41:31 -050024 char *dname = dirtree_path(new, &alen);
Felix Jandaf97cc9f2013-07-26 22:49:05 -050025 struct {
26 char class[16], vendor[16], device[16], module[256];
27 } *bufs = (void*)(toybuf + 2);
28
29 if (!strcmp("/sys/bus/pci/devices", dname)) return DIRTREE_RECURSE;
Isaac Dunhamfe03a1f2013-07-26 15:41:31 -050030 errno = 0;
Felix Jandaf97cc9f2013-07-26 22:49:05 -050031 dirfd = open(dname, O_RDONLY);
Isaac Dunhamfe03a1f2013-07-26 15:41:31 -050032 if (dirfd > 0) {
Felix Jandaf97cc9f2013-07-26 22:49:05 -050033 char *p, **fields = (char*[]){"class", "vendor", "device", ""};
34
35 for (p = toybuf; **fields; p+=16, fields++) {
36 int fd, size;
37
38 if ((fd = openat(dirfd, *fields, O_RDONLY)) < 0) continue;
Felix Jandae3a6c4e2013-07-27 09:45:40 +020039 size = ((toys.optflags & FLAG_e) && (p == toybuf)) ? 8 : 6;
Felix Jandaf97cc9f2013-07-26 22:49:05 -050040 p[read(fd, p, size)] = '\0';
41 close(fd);
42 }
43
Isaac Dunhamfe03a1f2013-07-26 15:41:31 -050044 close(dirfd);
45 if (!errno) {
46 char *driver = "";
Felix Jandaf97cc9f2013-07-26 22:49:05 -050047 char *fmt = toys.optflags & FLAG_m ? "%s, \"%s\" \"%s\" \"%s\" \"%s\"\n"
48 : "%s Class %s: %s:%s %s\n";
49
Isaac Dunhamfe03a1f2013-07-26 15:41:31 -050050 if (toys.optflags & FLAG_k) {
Isaac Dunhamfe03a1f2013-07-26 15:41:31 -050051 strcat(dname, "/driver");
Felix Jandaf97cc9f2013-07-26 22:49:05 -050052 if (readlink(dname, bufs->module, sizeof(bufs->module)) != -1)
53 driver = basename(bufs->module);
Isaac Dunhamfe03a1f2013-07-26 15:41:31 -050054 }
Felix Jandaf97cc9f2013-07-26 22:49:05 -050055 printf(fmt, new->name + 5, bufs->class, bufs->vendor, bufs->device,
Isaac Dunhamfe03a1f2013-07-26 15:41:31 -050056 driver);
Isaac Dunhamfe03a1f2013-07-26 15:41:31 -050057 }
58 }
Isaac Dunhamfe03a1f2013-07-26 15:41:31 -050059 return 0;
60}
61
62void lspci_main(void)
63{
Felix Jandaf97cc9f2013-07-26 22:49:05 -050064 dirtree_read("/sys/bus/pci/devices", do_lspci);
Isaac Dunhamfe03a1f2013-07-26 15:41:31 -050065}