123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- /* vim: tabstop=4 shiftwidth=4 noexpandtab
- * This file is part of ToaruOS and is released under the terms
- * of the NCSA / University of Illinois License - see LICENSE.md
- * Copyright (C) 2018 K. Lange
- *
- * lspci - Print information about connected PCI devices.
- *
- */
- #include <stdio.h>
- #include <unistd.h>
- #include <errno.h>
- #include <string.h>
- struct device_class {
- char * code;
- char * name;
- } device_classes[] = {
- {"0101", "IDE interface"},
- {"0102", "Floppy disk controller"},
- {"0105", "ATA controller"},
- {"0106", "SATA controller"},
- {"0200", "Ethernet controller"},
- {"0280", "Network controller"},
- {"0300", "VGA compatible controller"},
- {"0380", "Display controller"},
- {"0401", "Multimedia audio controller"},
- {"0403", "Audio device"},
- {"0480", "Multimedia controller"},
- {"0600", "Host bridge"},
- {"0601", "ISA bridge"},
- {"0604", "PCI bridge"},
- {"0680", "Bridge"},
- {"0880", "System peripheral"},
- {NULL, NULL},
- };
- static void show_usage(char * argv[]) {
- fprintf(stderr,
- "lspci - show information about PCI devices\n"
- "\n"
- "usage: %s [-n]\n"
- "\n"
- " -n \033[3mshow numeric device codes\033[0m\n"
- " -? \033[3mshow this help text\033[0m\n"
- "\n", argv[0]);
- }
- int main(int argc, char * argv[]) {
- int numeric = 0;
- int opt;
- while ((opt = getopt(argc, argv, "n?")) != -1) {
- switch (opt) {
- case '?':
- show_usage(argv);
- return 0;
- case 'n':
- numeric = 1;
- break;
- }
- }
- FILE * f = fopen("/proc/pci","r");
- if (!f) {
- fprintf(stderr, "%s: %s: %s\n", argv[0], "/proc/pci", strerror(errno));
- return 1;
- }
- while (!feof(f)) {
- char line[1024];
- fgets(line, 1024, f);
- if (line[0] == ' ') {
- /* Skip; don't care about this information */
- continue;
- }
- /* Read bus, etc. verbatim */
- char * device_bus = line;
- /* Read device class */
- char * device_class = strstr(line," (");
- if (!device_class) {
- fprintf(stderr, "%s: parse error\n", argv[0]);
- return 1;
- }
- *device_class = '\0';
- device_class++; /* space */
- device_class++; /* ( */
- char * device_vendor = strstr(device_class, ", ");
- if (!device_vendor) {
- fprintf(stderr, "%s: parse error\n", argv[0]);
- return 1;
- }
- *device_vendor = '\0';
- device_vendor++; /* comma */
- device_vendor++; /* space */
- char * device_code = strstr(device_vendor, ":");
- if (!device_code) {
- fprintf(stderr, "%s: parse error\n", argv[0]);
- return 1;
- }
- *device_code = '\0';
- device_code++; /* colon */
- char * device_name = strstr(device_code, ") ");
- if (!device_name) {
- fprintf(stderr, "%s: parse error\n", argv[0]);
- return 1;
- }
- *device_name = '\0';
- device_name++; /* ) */
- device_name++; /* space */
- char * linefeed = strstr(device_name, "\n");
- if (linefeed) *linefeed = '\0';
- if (numeric) {
- fprintf(stdout, "%s %s: %s:%s\n", device_bus, device_class, device_vendor, device_code);
- } else {
- for (struct device_class * c = device_classes; c->code; ++c) {
- if (!strcmp(device_class, c->code)) {
- device_class = c->name;
- break;
- }
- }
- /* TODO: We should also look up vendor + device names ourselves and possibly remove them from the kernel */
- fprintf(stdout, "%s %s: %s\n", device_bus, device_class, device_name);
- }
- }
- return 0;
- }
|