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