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