scanpci.c revision cad31331
1/* 2 * (C) Copyright IBM Corporation 2006 3 * All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * on the rights to use, copy, modify, merge, publish, distribute, sub 9 * license, and/or sell copies of the Software, and to permit persons to whom 10 * the Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19 * IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 */ 24 25#ifdef HAVE_CONFIG_H 26#include "config.h" 27#endif 28 29#include <stdlib.h> 30#include <stdio.h> 31#include <unistd.h> 32#include <inttypes.h> 33 34#ifdef HAVE_ERR_H 35#include <err.h> 36#else 37# include <errno.h> 38# include <string.h> 39# define err(exitcode, format, args...) \ 40 errx(exitcode, format ": %s", ## args, strerror(errno)) 41# define errx(exitcode, format, args...) \ 42 { warnx(format, ## args); exit(exitcode); } 43# define warn(format, args...) \ 44 warnx(format ": %s", ## args, strerror(errno)) 45# define warnx(format, args...) \ 46 fprintf(stderr, format "\n", ## args) 47#endif 48 49#include "pciaccess.h" 50 51 52static void 53print_pci_bridge( const struct pci_bridge_info * info ) 54{ 55 printf( " Bus: primary=%02"PRIx8", secondary=%02"PRIx8", subordinate=%02"PRIx8", " 56 "sec-latency=%"PRIu8"\n", 57 info->primary_bus, 58 info->secondary_bus, 59 info->subordinate_bus, 60 info->secondary_latency_timer ); 61 printf( " I/O behind bridge: %08"PRIx32"-%08"PRIx32"\n", 62 info->io_base, 63 info->io_limit ); 64 printf( " Memory behind bridge: %08"PRIx32"-%08"PRIx32"\n", 65 info->mem_base, 66 info->mem_limit ); 67 printf( " Prefetchable memory behind bridge: %08"PRIx64"-%08"PRIx64"\n", 68 info->prefetch_mem_base, 69 info->prefetch_mem_limit ); 70} 71 72static void 73print_pci_device( struct pci_device * dev, int verbose ) 74{ 75 const char * dev_name; 76 const char * vend_name; 77 78 vend_name = pci_device_get_vendor_name( dev ); 79 dev_name = pci_device_get_device_name( dev ); 80 if ( dev_name == NULL ) { 81 dev_name = "Device unknown"; 82 } 83 84 printf("\npci "); 85 if (dev->domain != 0) 86 printf("domain 0x%04x ", dev->domain); 87 printf("bus 0x%04x cardnum 0x%02x function 0x%02x:" 88 " vendor 0x%04x device 0x%04x\n", 89 dev->bus, 90 dev->dev, 91 dev->func, 92 dev->vendor_id, 93 dev->device_id ); 94 if ( vend_name != NULL ) { 95 printf( " %s %s\n", vend_name, dev_name ); 96 } 97 else { 98 printf( " %s\n", dev_name ); 99 } 100 101 if ( verbose ) { 102 unsigned i; 103 uint16_t command, status; 104 uint8_t bist; 105 uint8_t header_type; 106 uint8_t latency_timer; 107 uint8_t cache_line_size; 108 uint8_t max_latency; 109 uint8_t min_grant; 110 uint8_t int_pin; 111 112 113 vend_name = pci_device_get_subvendor_name( dev ); 114 dev_name = pci_device_get_subdevice_name( dev ); 115 if ( dev_name == NULL ) { 116 dev_name = "Card unknown"; 117 } 118 119 printf( " CardVendor 0x%04x card 0x%04x (", 120 dev->subvendor_id, 121 dev->subdevice_id ); 122 if ( vend_name != NULL ) { 123 printf( "%s, %s)\n", vend_name, dev_name ); 124 } 125 else { 126 printf( "%s)\n", dev_name ); 127 } 128 129 pci_device_cfg_read_u16( dev, & command, 4 ); 130 pci_device_cfg_read_u16( dev, & status, 6 ); 131 printf( " STATUS 0x%04x COMMAND 0x%04x\n", 132 status, 133 command ); 134 printf( " CLASS 0x%02x 0x%02x 0x%02x REVISION 0x%02x\n", 135 (dev->device_class >> 16) & 0x0ff, 136 (dev->device_class >> 8) & 0x0ff, 137 (dev->device_class >> 0) & 0x0ff, 138 dev->revision ); 139 140 pci_device_cfg_read_u8( dev, & cache_line_size, 12 ); 141 pci_device_cfg_read_u8( dev, & latency_timer, 13 ); 142 pci_device_cfg_read_u8( dev, & header_type, 14 ); 143 pci_device_cfg_read_u8( dev, & bist, 15 ); 144 145 printf( " BIST 0x%02x HEADER 0x%02x LATENCY 0x%02x CACHE 0x%02x\n", 146 bist, 147 header_type, 148 latency_timer, 149 cache_line_size ); 150 151 pci_device_probe( dev ); 152 for ( i = 0 ; i < 6 ; i++ ) { 153 if ( dev->regions[i].base_addr != 0 ) { 154 printf( " BASE%u 0x%08"PRIxPTR" SIZE %zu %s", 155 i, 156 (intptr_t) dev->regions[i].base_addr, 157 (size_t) dev->regions[i].size, 158 (dev->regions[i].is_IO) ? "I/O" : "MEM" ); 159 160 if ( ! dev->regions[i].is_IO ) { 161 if ( dev->regions[i].is_prefetchable ) { 162 printf( " PREFETCHABLE" ); 163 } 164 } 165 166 printf( "\n" ); 167 } 168 } 169 170 if ( dev->rom_size ) { 171 printf( " BASEROM 0x%08x addr 0x%08x\n", 172 0, 0 ); 173 } 174 175 pci_device_cfg_read_u8( dev, & int_pin, 61 ); 176 pci_device_cfg_read_u8( dev, & min_grant, 62 ); 177 pci_device_cfg_read_u8( dev, & max_latency, 63 ); 178 179 printf( " MAX_LAT 0x%02x MIN_GNT 0x%02x INT_PIN 0x%02x INT_LINE 0x%02x\n", 180 max_latency, 181 min_grant, 182 int_pin, 183 dev->irq ); 184 185 if ( (dev->device_class >> 16) == 0x06 ) { 186 const void * info; 187 188 if ( (info = pci_device_get_bridge_info(dev)) != NULL ) { 189 print_pci_bridge( (const struct pci_bridge_info *) info ); 190 } 191 else if ( (info = pci_device_get_pcmcia_bridge_info(dev)) != NULL ) { 192 /* Nothing yet. */ 193 } 194 } 195 } 196} 197 198 199int main( int argc, char ** argv ) 200{ 201 struct pci_device_iterator * iter; 202 struct pci_device * dev; 203 int ret; 204 int verbose = 0; 205 int c; 206 int errors = 0; 207 208 while ((c = getopt(argc, argv, "v")) != -1) { 209 switch (c) { 210 case 'v': 211 verbose = 1; 212 break; 213 case '?': 214 errors++; 215 } 216 } 217 if (errors != 0) { 218 fprintf(stderr, "usage: %s [-v]\n", argv[0]); 219 exit(2); 220 } 221 222 ret = pci_system_init(); 223 if (ret != 0) 224 err(1, "Couldn't initialize PCI system"); 225 226 iter = pci_slot_match_iterator_create( NULL ); 227 228 while ( (dev = pci_device_next( iter )) != NULL ) { 229 print_pci_device( dev, verbose ); 230 } 231 232 pci_system_cleanup(); 233 return 0; 234} 235