pciconf.c revision 21935
1/* 2 * Copyright 1996 Massachusetts Institute of Technology 3 * 4 * Permission to use, copy, modify, and distribute this software and 5 * its documentation for any purpose and without fee is hereby 6 * granted, provided that both the above copyright notice and this 7 * permission notice appear in all copies, that both the above 8 * copyright notice and this permission notice appear in all 9 * supporting documentation, and that the name of M.I.T. not be used 10 * in advertising or publicity pertaining to distribution of the 11 * software without specific, written prior permission. M.I.T. makes 12 * no representations about the suitability of this software for any 13 * purpose. It is provided "as is" without express or implied 14 * warranty. 15 * 16 * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS 17 * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, 18 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT 20 * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 23 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 26 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * $ANA: pciconf.c,v 1.1.1.1 1996/09/25 21:12:57 wollman Exp $ 30 */ 31 32#include <sys/types.h> 33#include <sys/fcntl.h> 34 35#include <err.h> 36#include <stdlib.h> 37#include <stdio.h> 38#include <string.h> 39#include <unistd.h> 40 41#include <pci/pcivar.h> 42#include <pci/pci_ioctl.h> 43 44#include "pathnames.h" 45 46static void list_devs(void); 47static void readit(const char *, const char *, int); 48static void writeit(const char *, const char *, const char *, int); 49static void chkattached(const char *, int); 50 51static exitstatus = 0; 52 53static void 54usage(const char *argv0) { 55 fprintf(stderr, "usage:\n\t%s -l\n" 56 "\t%s -a sel\n" 57 "\t%s [-r|-w] [-bh] sel addr [value]\n", 58 argv0, argv0, argv0); 59 exit (1); 60} 61 62int 63main(int argc, char **argv) 64{ 65 int c; 66 int listmode, readmode, writemode, attachedmode; 67 int byte, isshort; 68 69 listmode = readmode = writemode = attachedmode = byte = isshort = 0; 70 71 while ((c = getopt(argc, argv, "alrwbh")) != EOF) { 72 switch(c) { 73 case 'a': 74 attachedmode = 1; 75 break; 76 77 case 'l': 78 listmode = 1; 79 break; 80 81 case 'r': 82 readmode = 1; 83 break; 84 85 case 'w': 86 writemode = 1; 87 break; 88 89 case 'b': 90 byte = 1; 91 break; 92 93 case 'h': 94 isshort = 1; 95 break; 96 97 default: 98 usage(argv[0]); 99 } 100 } 101 102 if ((listmode && optind != argc) 103 || (writemode && optind + 3 != argc) 104 || (readmode && optind + 2 != argc) 105 || (attachedmode && optind + 1 != argc)) 106 usage(argv[0]); 107 108 if (listmode) { 109 list_devs(); 110 } else if(attachedmode) { 111 chkattached(argv[optind], 112 byte ? 1 : isshort ? 2 : 4); 113 } else if(readmode) { 114 readit(argv[optind], argv[optind + 1], 115 byte ? 1 : isshort ? 2 : 4); 116 } else if(writemode) { 117 writeit(argv[optind], argv[optind + 1], argv[optind + 2], 118 byte ? 1 : isshort ? 2 : 4); 119 } else { 120 usage(argv[0]); 121 } 122 123 return exitstatus; 124} 125 126static void 127list_devs(void) 128{ 129 int fd; 130 struct pci_conf_io pc; 131 struct pci_conf conf[255], *p; 132 133 fd = open(_PATH_DEVPCI, O_RDONLY, 0); 134 if (fd < 0) 135 err(1, "%s", _PATH_DEVPCI); 136 137 pc.pci_len = sizeof(conf); 138 pc.pci_buf = conf; 139 140 if (ioctl(fd, PCIOCGETCONF, &pc) < 0) 141 err(1, "ioctl(PCIOCGETCONF)"); 142 143 close(fd); 144 145 for (p = conf; p < &conf[pc.pci_len / sizeof conf[0]]; p++) { 146 printf("pci%d:%d:%d:\tclass=0x%06x card=0x%08lx chip=0x%08lx rev=0x%02x hdr=0x%02x\n", 147 p->pc_sel.pc_bus, p->pc_sel.pc_dev, p->pc_sel.pc_func, 148 p->pc_class >> 8, p->pc_subid, 149 p->pc_devid, p->pc_class & 0xff, p->pc_hdr); 150 } 151} 152 153static struct pcisel 154getsel(const char *str) 155{ 156 char *ep = (char*) str; 157 struct pcisel sel; 158 159 if (strncmp(ep, "pci", 3) == 0) { 160 ep += 3; 161 sel.pc_bus = strtoul(ep, &ep, 0); 162 if (!ep || *ep++ != ':') 163 errx(1, "cannot parse selector %s", str); 164 sel.pc_dev = strtoul(ep, &ep, 0); 165 if (!ep || *ep != ':') { 166 sel.pc_func = 0; 167 } else { 168 ep++; 169 sel.pc_func = strtoul(ep, &ep, 0); 170 } 171 } 172 if (*ep == ':') 173 ep++; 174 if (*ep || ep == str) 175 errx(1, "cannot parse selector %s", str); 176 return sel; 177} 178 179static void 180readit(const char *name, const char *reg, int width) 181{ 182 int fd; 183 struct pci_io pi; 184 185 pi.pi_sel = getsel(name); 186 pi.pi_reg = strtoul(reg, (char **)0, 0); /* XXX error check */ 187 pi.pi_width = width; 188 189 fd = open(_PATH_DEVPCI, O_RDWR, 0); 190 if (fd < 0) 191 err(1, "%s", _PATH_DEVPCI); 192 193 if (ioctl(fd, PCIOCREAD, &pi) < 0) 194 err(1, "ioctl(PCIOCREAD)"); 195 196 printf("0x%08x\n", pi.pi_data); 197} 198 199static void 200writeit(const char *name, const char *reg, const char *data, int width) 201{ 202 int fd; 203 struct pci_io pi; 204 205 pi.pi_sel = getsel(name); 206 pi.pi_reg = strtoul(reg, (char **)0, 0); /* XXX error check */ 207 pi.pi_width = width; 208 pi.pi_data = strtoul(data, (char **)0, 0); /* XXX error check */ 209 210 fd = open(_PATH_DEVPCI, O_RDWR, 0); 211 if (fd < 0) 212 err(1, "%s", _PATH_DEVPCI); 213 214 if (ioctl(fd, PCIOCWRITE, &pi) < 0) 215 err(1, "ioctl(PCIOCWRITE)"); 216} 217 218static void 219chkattached (const char *name, int width) 220{ 221 int fd; 222 struct pci_io pi; 223 224 pi.pi_sel = getsel(name); 225 pi.pi_reg = 0; 226 pi.pi_width = width; 227 pi.pi_data = 0; 228 229 fd = open(_PATH_DEVPCI, O_RDWR, 0); 230 if (fd < 0) 231 err(1, "%s", _PATH_DEVPCI); 232 233 if (ioctl(fd, PCIOCATTACHED, &pi) < 0) 234 err(1, "ioctl(PCIOCATTACHED)"); 235 236 exitstatus = pi.pi_data ? 0 : 2; /* exit(2), if NOT attached */ 237 printf("%s: %s%s\n", name, pi.pi_data == 0 ? "not " : "", "attached"); 238} 239