pciconf.c revision 19817
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); 49 50 51static void 52usage(const char *argv0) { 53 fprintf(stderr, "usage:\n\t%s -l\n" 54 "\t%s [-r|-w] [-bh] sel addr [value]\n", 55 argv0, argv0); 56 exit (1); 57} 58 59int 60main(int argc, char **argv) 61{ 62 int c; 63 int listmode, readmode, writemode; 64 int byte, isshort; 65 66 listmode = readmode = writemode = byte = isshort = 0; 67 68 while ((c = getopt(argc, argv, "lrwbh")) != EOF) { 69 switch(c) { 70 case 'l': 71 listmode = 1; 72 break; 73 74 case 'r': 75 readmode = 1; 76 break; 77 78 case 'w': 79 writemode = 1; 80 break; 81 82 case 'b': 83 byte = 1; 84 break; 85 86 case 'h': 87 isshort = 1; 88 break; 89 90 default: 91 usage(argv[0]); 92 } 93 } 94 95 if ((listmode && optind != argc) 96 || (writemode && optind + 3 != argc) 97 || (readmode && optind + 2 != argc)) 98 usage(argv[0]); 99 100 if (listmode) { 101 list_devs(); 102 } else if(readmode) { 103 readit(argv[optind], argv[optind + 1], 104 byte ? 1 : isshort ? 2 : 4); 105 } else if(writemode) { 106 writeit(argv[optind], argv[optind + 1], argv[optind + 2], 107 byte ? 1 : isshort ? 2 : 4); 108 } else { 109 usage(argv[0]); 110 } 111 112 return 0; 113} 114 115static void 116list_devs(void) 117{ 118 int fd; 119 struct pci_conf_io pc; 120 struct pci_conf conf[255], *p; 121 122 fd = open(_PATH_DEVPCI, O_RDONLY, 0); 123 if (fd < 0) 124 err(1, "%s", _PATH_DEVPCI); 125 126 pc.pci_len = sizeof(conf); 127 pc.pci_buf = conf; 128 129 if (ioctl(fd, PCIOCGETCONF, &pc) < 0) 130 err(1, "ioctl(PCIOCGETCONF)"); 131 132 close(fd); 133 134 for (p = conf; p < &conf[pc.pci_len / sizeof conf[0]]; p++) { 135 printf("pci%d:%d:%d:\tclass=0x%06x card=0x%08lx chip=0x%08lx rev=0x%02x hdr=0x%02x\n", 136 p->pc_sel.pc_bus, p->pc_sel.pc_dev, p->pc_sel.pc_func, 137 p->pc_class >> 8, p->pc_subid, 138 p->pc_devid, p->pc_class & 0xff, p->pc_hdr); 139 } 140} 141 142static struct pcisel 143getsel(const char *str) 144{ 145 char *ep = (char*) str; 146 struct pcisel sel; 147 148 if (strncmp(ep, "pci", 3) == 0) { 149 ep += 3; 150 sel.pc_bus = strtoul(ep, &ep, 0); 151 if (!ep || *ep++ != ':') 152 errx(1, "cannot parse selector %s", str); 153 sel.pc_dev = strtoul(ep, &ep, 0); 154 if (!ep || *ep != ':') { 155 sel.pc_func = 0; 156 } else { 157 ep++; 158 sel.pc_func = strtoul(ep, &ep, 0); 159 } 160 } 161 if (*ep == ':') 162 ep++; 163 if (*ep || ep == str) 164 errx(1, "cannot parse selector %s", str); 165 return sel; 166} 167 168static void 169readit(const char *name, const char *reg, int width) 170{ 171 int fd; 172 struct pci_io pi; 173 174 pi.pi_sel = getsel(name); 175 pi.pi_reg = strtoul(reg, (char **)0, 0); /* XXX error check */ 176 pi.pi_width = width; 177 178 fd = open(_PATH_DEVPCI, O_RDWR, 0); 179 if (fd < 0) 180 err(1, "%s", _PATH_DEVPCI); 181 182 if (ioctl(fd, PCIOCREAD, &pi) < 0) 183 err(1, "ioctl(PCIOCREAD)"); 184 185 printf("0x%08x\n", pi.pi_data); 186} 187 188static void 189writeit(const char *name, const char *reg, const char *data, int width) 190{ 191 int fd; 192 struct pci_io pi; 193 194 pi.pi_sel = getsel(name); 195 pi.pi_reg = strtoul(reg, (char **)0, 0); /* XXX error check */ 196 pi.pi_width = width; 197 pi.pi_data = strtoul(data, (char **)0, 0); /* XXX error check */ 198 199 fd = open(_PATH_DEVPCI, O_RDWR, 0); 200 if (fd < 0) 201 err(1, "%s", _PATH_DEVPCI); 202 203 if (ioctl(fd, PCIOCWRITE, &pi) < 0) 204 err(1, "ioctl(PCIOCWRITE)"); 205} 206