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#include "pciaccess_private.h" 51 52 53static void 54print_pci_bridge( const struct pci_bridge_info * info ) 55{ 56 printf( " Bus: primary=%02"PRIx8", secondary=%02"PRIx8", subordinate=%02"PRIx8", " 57 "sec-latency=%"PRIu8"\n", 58 info->primary_bus, 59 info->secondary_bus, 60 info->subordinate_bus, 61 info->secondary_latency_timer ); 62 printf( " I/O behind bridge: %08"PRIx32"-%08"PRIx32"\n", 63 info->io_base, 64 info->io_limit ); 65 printf( " Memory behind bridge: %08"PRIx32"-%08"PRIx32"\n", 66 info->mem_base, 67 info->mem_limit ); 68 printf( " Prefetchable memory behind bridge: %08"PRIx64"-%08"PRIx64"\n", 69 info->prefetch_mem_base, 70 info->prefetch_mem_limit ); 71} 72 73static void 74print_pci_device( struct pci_device * dev, int verbose ) 75{ 76 const char * dev_name; 77 const char * vend_name; 78 79 vend_name = pci_device_get_vendor_name( dev ); 80 dev_name = pci_device_get_device_name( dev ); 81 if ( dev_name == NULL ) { 82 dev_name = "Device unknown"; 83 } 84 85 printf("\npci "); 86 if (dev->domain != 0) 87 printf("domain 0x%04x ", dev->domain); 88 printf("bus 0x%04x cardnum 0x%02x function 0x%02x:" 89 " vendor 0x%04x device 0x%04x\n", 90 dev->bus, 91 dev->dev, 92 dev->func, 93 dev->vendor_id, 94 dev->device_id ); 95 if ( vend_name != NULL ) { 96 printf( " %s %s\n", vend_name, dev_name ); 97 } 98 else { 99 printf( " %s\n", dev_name ); 100 } 101 102 if ( verbose ) { 103 unsigned i; 104 uint16_t command, status; 105 uint8_t bist; 106 uint8_t header_type; 107 uint8_t latency_timer; 108 uint8_t cache_line_size; 109 uint8_t max_latency; 110 uint8_t min_grant; 111 uint8_t int_pin; 112 113 114 vend_name = pci_device_get_subvendor_name( dev ); 115 dev_name = pci_device_get_subdevice_name( dev ); 116 if ( dev_name == NULL ) { 117 dev_name = "Card unknown"; 118 } 119 120 printf( " CardVendor 0x%04x card 0x%04x (", 121 dev->subvendor_id, 122 dev->subdevice_id ); 123 if ( vend_name != NULL ) { 124 printf( "%s, %s)\n", vend_name, dev_name ); 125 } 126 else { 127 printf( "%s)\n", dev_name ); 128 } 129 130 pci_device_cfg_read_u16( dev, & command, 4 ); 131 pci_device_cfg_read_u16( dev, & status, 6 ); 132 printf( " STATUS 0x%04x COMMAND 0x%04x\n", 133 status, 134 command ); 135 printf( " CLASS 0x%02x 0x%02x 0x%02x REVISION 0x%02x\n", 136 (dev->device_class >> 16) & 0x0ff, 137 (dev->device_class >> 8) & 0x0ff, 138 (dev->device_class >> 0) & 0x0ff, 139 dev->revision ); 140 141 pci_device_cfg_read_u8( dev, & cache_line_size, 12 ); 142 pci_device_cfg_read_u8( dev, & latency_timer, 13 ); 143 pci_device_cfg_read_u8( dev, & header_type, 14 ); 144 pci_device_cfg_read_u8( dev, & bist, 15 ); 145 146 printf( " BIST 0x%02x HEADER 0x%02x LATENCY 0x%02x CACHE 0x%02x\n", 147 bist, 148 header_type, 149 latency_timer, 150 cache_line_size ); 151 152 pci_device_probe( dev ); 153 for ( i = 0 ; i < 6 ; i++ ) { 154 if ( dev->regions[i].base_addr != 0 ) { 155 printf( " BASE%u 0x%0*"PRIxPTR" SIZE %zu %s", 156 i, 157 dev->regions[i].is_64 ? 16 : 8, 158 (intptr_t) dev->regions[i].base_addr, 159 (size_t) dev->regions[i].size, 160 (dev->regions[i].is_IO) ? "I/O" : 161 ((dev->regions[i].is_64) ? "MEM64" : "MEM")); 162 163 if ( ! dev->regions[i].is_IO ) { 164 if ( dev->regions[i].is_prefetchable ) { 165 printf( " PREFETCHABLE" ); 166 } 167 } 168 169 printf( "\n" ); 170 } 171 } 172 173 if ( dev->rom_size ) { 174 struct pci_device_private *priv = 175 (struct pci_device_private *) dev; 176 177 printf( " BASEROM 0x%08"PRIxPTR" SIZE %zu\n", 178 (intptr_t) priv->rom_base, (size_t) dev->rom_size); 179 } 180 181 pci_device_cfg_read_u8( dev, & int_pin, 61 ); 182 pci_device_cfg_read_u8( dev, & min_grant, 62 ); 183 pci_device_cfg_read_u8( dev, & max_latency, 63 ); 184 185 printf( " MAX_LAT 0x%02x MIN_GNT 0x%02x INT_PIN 0x%02x INT_LINE 0x%02x\n", 186 max_latency, 187 min_grant, 188 int_pin, 189 dev->irq ); 190 191 if ( (dev->device_class >> 16) == 0x06 ) { 192 const void * info; 193 194 if ( (info = pci_device_get_bridge_info(dev)) != NULL ) { 195 print_pci_bridge( (const struct pci_bridge_info *) info ); 196 } 197 else if ( (info = pci_device_get_pcmcia_bridge_info(dev)) != NULL ) { 198 /* Nothing yet. */ 199 } 200 } 201 } 202} 203 204 205int main( int argc, char ** argv ) 206{ 207 struct pci_device_iterator * iter; 208 struct pci_device * dev; 209 int ret; 210 int verbose = 0; 211 int c; 212 int errors = 0; 213 214 while ((c = getopt(argc, argv, "v")) != -1) { 215 switch (c) { 216 case 'v': 217 verbose = 1; 218 break; 219 case '?': 220 errors++; 221 } 222 } 223 if (errors != 0) { 224 fprintf(stderr, "usage: %s [-v]\n", argv[0]); 225 exit(2); 226 } 227 228 ret = pci_system_init(); 229 if (ret != 0) 230 err(1, "Couldn't initialize PCI system"); 231 232 iter = pci_slot_match_iterator_create( NULL ); 233 234 while ( (dev = pci_device_next( iter )) != NULL ) { 235 print_pci_device( dev, verbose ); 236 } 237 238 pci_system_cleanup(); 239 return 0; 240} 241