1/* 2 * Copyright (c) 2013 ETH Zurich. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a copy 5 * of this software and associated documentation files (the "Software"), to deal 6 * in the Software without restriction, including without limitation the rights 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 * copies of the Software, and to permit persons to whom the Software is 9 * furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 * THE SOFTWARE. 21 */ 22 23#include <stdio.h> 24#include <stdlib.h> 25#include <string.h> 26#include <octopus/octopus.h> 27#include <barrelfish/barrelfish.h> 28#include <barrelfish/nameservice_client.h> 29 30#define OPT_HELP 0 31#define OPT_LIST_PCI 1 32#define OPT_LIST_HW 2 33#define OPT_LIST_ALL 3 34#define OPT_LIST_PATTERN 4 35 36 37struct opt_t { 38 const char *option; 39 const char *pattern; 40 const char *help; 41 int option_number; 42}; 43 44/* 45 * Program options and help text. 46 */ 47static struct opt_t option[] = { 48 { "-pci", "r'hw\\.pci.'", "List all available PCI devices.", OPT_LIST_PCI }, 49 { "-hw", "r'hw\\.'", "List all found hardware.", OPT_LIST_HW }, 50 { "-all", "r'.*'", "List all registered types.", OPT_LIST_ALL }, 51 { "-free", 0, "Use free search pattern.", OPT_LIST_PATTERN }, 52 { "-help", 0, "Print this help.", OPT_HELP }, 53 { 0, 0, 0, 0 } 54}; 55 56/** 57 * 58 */ 59static int exit_help(const char *name) 60{ 61 fprintf(stderr, "Usage: %s <[option] | [pattern]>\n", name); 62 fprintf(stderr, "options: \n"); 63 64 for (int i = 0; option[i].option != 0; i++) 65 fprintf(stderr, " %s %s\n", option[i].option, option[i].help); 66 67 exit(1); 68} 69 70/** 71 * 72 */ 73static void print_pci(const char *data) 74{ 75 int pci, bus, class, device, device_id, function, prog_if, subclass, vendor; 76 int i = 0, retval = 0; 77 78 const char *supported_fmt[][2] = { 79 { /* PCI */ 80 "hw.pci.device.%u { " 81 "bus: %u, class: %u, device: %u, " 82 "device_id: %u, function: %u, prog_if: %u, " 83 "subclass: %u, vendor: %u }", "pci" 84 },{ /* PCIe */ 85 "hw.pcie.device.%u { " 86 "bus: %u, class: %u, device: %u, " 87 "device_id: %u, function: %u, prog_if: %u, " 88 "subclass: %u, vendor: %u }", "pcie" 89 },{ /* terminator */ 90 0, 0 91 } 92 }; 93 94 /* parse octopus device listing */ 95 while (supported_fmt[i][0] != 0 && retval < 9) { 96 retval = sscanf(data, supported_fmt[i][0], 97 &pci, &bus, &class, &device, &device_id, 98 &function, &prog_if, &subclass, &vendor); 99 if (retval < 9) 100 i++; 101 } 102 103 if (retval >= 9) { 104 printf("hw.%s.device.%u { " 105 "bus: %u, class: 0x%x, device: 0x%x, " 106 "device_id: 0x%x, function: 0x%x, prog_if: %u, " 107 "subclass: 0x%x, vendor: 0x%x }\n", 108 supported_fmt[i][1], pci, bus, class, device, device_id, 109 function, prog_if, subclass, vendor); 110 } else { 111 printf("%s\n", data); 112 } 113} 114 115/** 116 * 117 */ 118int main(int argc, char **argv) 119{ 120 const char *pattern; 121 char **names; 122 errval_t err; 123 size_t size; 124 iref_t iref; 125 int opt = 0; 126 127 if (argc > 1) { 128 /* Get selected option */ 129 for (opt = 0; option[opt].option != 0; opt++) { 130 if (strcmp(option[opt].option, argv[1]) == 0) 131 break; 132 } 133 } 134 135 if (option[opt].option_number == OPT_HELP) 136 exit_help(argv[0]); 137 138 pattern = option[opt].pattern; 139 140 if (option[opt].option_number == OPT_LIST_PATTERN) { 141 if (argc < 3) 142 exit_help(argv[0]); 143 144 pattern = argv[2]; 145 } 146 147 err = nameservice_blocking_lookup("pci_discovery_done", &iref); 148 if (err_is_fail(err)) { 149 fprintf(stderr, 150 "Error: nameservice_blocking_lookup failed for pci_discovery_done.\n"); 151 exit(err); 152 } 153 154 err = oct_init(); 155 if (err_is_fail(err)) { 156 fprintf(stderr, "Error: oct_init failed.\n"); 157 exit(err); 158 } 159 160 err = oct_get_names(&names, &size, pattern); 161 if (err) { 162 fprintf(stderr, "Error: oct_get_names failed.\n"); 163 exit(err); 164 } 165 166 for (int i = 0; i < size; i++) { 167 char *data; 168 169 err = oct_get(&data, names[i]); 170 if (err) { 171 fprintf(stderr, "Error: oct_get failed.\n"); 172 exit(err); 173 } 174 175 if (option[opt].option_number == OPT_LIST_PCI) 176 print_pci(data); 177 else 178 printf("%s\n", data); 179 180 free(data); 181 } 182 183 if (size) 184 oct_free_names(names, size); 185 186 return 0; 187} 188