scanpci.c revision cad31331
14e578869Smrg/* 24e578869Smrg * (C) Copyright IBM Corporation 2006 34e578869Smrg * All Rights Reserved. 44e578869Smrg * 54e578869Smrg * Permission is hereby granted, free of charge, to any person obtaining a 64e578869Smrg * copy of this software and associated documentation files (the "Software"), 74e578869Smrg * to deal in the Software without restriction, including without limitation 84e578869Smrg * on the rights to use, copy, modify, merge, publish, distribute, sub 94e578869Smrg * license, and/or sell copies of the Software, and to permit persons to whom 104e578869Smrg * the Software is furnished to do so, subject to the following conditions: 114e578869Smrg * 124e578869Smrg * The above copyright notice and this permission notice (including the next 134e578869Smrg * paragraph) shall be included in all copies or substantial portions of the 144e578869Smrg * Software. 154e578869Smrg * 164e578869Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 174e578869Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 184e578869Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 194e578869Smrg * IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 204e578869Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 214e578869Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 224e578869Smrg * DEALINGS IN THE SOFTWARE. 234e578869Smrg */ 244e578869Smrg 25cad31331Smrg#ifdef HAVE_CONFIG_H 26cad31331Smrg#include "config.h" 27cad31331Smrg#endif 28cad31331Smrg 294e578869Smrg#include <stdlib.h> 304e578869Smrg#include <stdio.h> 314e578869Smrg#include <unistd.h> 32cad31331Smrg#include <inttypes.h> 33cad31331Smrg 34cad31331Smrg#ifdef HAVE_ERR_H 35cad31331Smrg#include <err.h> 36cad31331Smrg#else 37cad31331Smrg# include <errno.h> 38cad31331Smrg# include <string.h> 39cad31331Smrg# define err(exitcode, format, args...) \ 40cad31331Smrg errx(exitcode, format ": %s", ## args, strerror(errno)) 41cad31331Smrg# define errx(exitcode, format, args...) \ 42cad31331Smrg { warnx(format, ## args); exit(exitcode); } 43cad31331Smrg# define warn(format, args...) \ 44cad31331Smrg warnx(format ": %s", ## args, strerror(errno)) 45cad31331Smrg# define warnx(format, args...) \ 46cad31331Smrg fprintf(stderr, format "\n", ## args) 47cad31331Smrg#endif 484e578869Smrg 494e578869Smrg#include "pciaccess.h" 504e578869Smrg 514e578869Smrg 524e578869Smrgstatic void 534e578869Smrgprint_pci_bridge( const struct pci_bridge_info * info ) 544e578869Smrg{ 55cad31331Smrg printf( " Bus: primary=%02"PRIx8", secondary=%02"PRIx8", subordinate=%02"PRIx8", " 56cad31331Smrg "sec-latency=%"PRIu8"\n", 574e578869Smrg info->primary_bus, 584e578869Smrg info->secondary_bus, 594e578869Smrg info->subordinate_bus, 604e578869Smrg info->secondary_latency_timer ); 61cad31331Smrg printf( " I/O behind bridge: %08"PRIx32"-%08"PRIx32"\n", 624e578869Smrg info->io_base, 634e578869Smrg info->io_limit ); 64cad31331Smrg printf( " Memory behind bridge: %08"PRIx32"-%08"PRIx32"\n", 654e578869Smrg info->mem_base, 664e578869Smrg info->mem_limit ); 67cad31331Smrg printf( " Prefetchable memory behind bridge: %08"PRIx64"-%08"PRIx64"\n", 684e578869Smrg info->prefetch_mem_base, 694e578869Smrg info->prefetch_mem_limit ); 704e578869Smrg} 714e578869Smrg 724e578869Smrgstatic void 734e578869Smrgprint_pci_device( struct pci_device * dev, int verbose ) 744e578869Smrg{ 754e578869Smrg const char * dev_name; 764e578869Smrg const char * vend_name; 774e578869Smrg 784e578869Smrg vend_name = pci_device_get_vendor_name( dev ); 794e578869Smrg dev_name = pci_device_get_device_name( dev ); 804e578869Smrg if ( dev_name == NULL ) { 814e578869Smrg dev_name = "Device unknown"; 824e578869Smrg } 834e578869Smrg 844e578869Smrg printf("\npci "); 854e578869Smrg if (dev->domain != 0) 864e578869Smrg printf("domain 0x%04x ", dev->domain); 874e578869Smrg printf("bus 0x%04x cardnum 0x%02x function 0x%02x:" 884e578869Smrg " vendor 0x%04x device 0x%04x\n", 894e578869Smrg dev->bus, 904e578869Smrg dev->dev, 914e578869Smrg dev->func, 924e578869Smrg dev->vendor_id, 934e578869Smrg dev->device_id ); 944e578869Smrg if ( vend_name != NULL ) { 954e578869Smrg printf( " %s %s\n", vend_name, dev_name ); 964e578869Smrg } 974e578869Smrg else { 984e578869Smrg printf( " %s\n", dev_name ); 994e578869Smrg } 1004e578869Smrg 1014e578869Smrg if ( verbose ) { 1024e578869Smrg unsigned i; 1034e578869Smrg uint16_t command, status; 1044e578869Smrg uint8_t bist; 1054e578869Smrg uint8_t header_type; 1064e578869Smrg uint8_t latency_timer; 1074e578869Smrg uint8_t cache_line_size; 1084e578869Smrg uint8_t max_latency; 1094e578869Smrg uint8_t min_grant; 1104e578869Smrg uint8_t int_pin; 1114e578869Smrg 1124e578869Smrg 1134e578869Smrg vend_name = pci_device_get_subvendor_name( dev ); 1144e578869Smrg dev_name = pci_device_get_subdevice_name( dev ); 1154e578869Smrg if ( dev_name == NULL ) { 1164e578869Smrg dev_name = "Card unknown"; 1174e578869Smrg } 1184e578869Smrg 1194e578869Smrg printf( " CardVendor 0x%04x card 0x%04x (", 1204e578869Smrg dev->subvendor_id, 1214e578869Smrg dev->subdevice_id ); 1224e578869Smrg if ( vend_name != NULL ) { 1234e578869Smrg printf( "%s, %s)\n", vend_name, dev_name ); 1244e578869Smrg } 1254e578869Smrg else { 1264e578869Smrg printf( "%s)\n", dev_name ); 1274e578869Smrg } 1284e578869Smrg 1294e578869Smrg pci_device_cfg_read_u16( dev, & command, 4 ); 1304e578869Smrg pci_device_cfg_read_u16( dev, & status, 6 ); 1314e578869Smrg printf( " STATUS 0x%04x COMMAND 0x%04x\n", 1324e578869Smrg status, 1334e578869Smrg command ); 1344e578869Smrg printf( " CLASS 0x%02x 0x%02x 0x%02x REVISION 0x%02x\n", 1354e578869Smrg (dev->device_class >> 16) & 0x0ff, 1364e578869Smrg (dev->device_class >> 8) & 0x0ff, 1374e578869Smrg (dev->device_class >> 0) & 0x0ff, 1384e578869Smrg dev->revision ); 1394e578869Smrg 1404e578869Smrg pci_device_cfg_read_u8( dev, & cache_line_size, 12 ); 1414e578869Smrg pci_device_cfg_read_u8( dev, & latency_timer, 13 ); 1424e578869Smrg pci_device_cfg_read_u8( dev, & header_type, 14 ); 1434e578869Smrg pci_device_cfg_read_u8( dev, & bist, 15 ); 1444e578869Smrg 1454e578869Smrg printf( " BIST 0x%02x HEADER 0x%02x LATENCY 0x%02x CACHE 0x%02x\n", 1464e578869Smrg bist, 1474e578869Smrg header_type, 1484e578869Smrg latency_timer, 1494e578869Smrg cache_line_size ); 1504e578869Smrg 1514e578869Smrg pci_device_probe( dev ); 1524e578869Smrg for ( i = 0 ; i < 6 ; i++ ) { 1534e578869Smrg if ( dev->regions[i].base_addr != 0 ) { 154cad31331Smrg printf( " BASE%u 0x%08"PRIxPTR" SIZE %zu %s", 1554e578869Smrg i, 1564e578869Smrg (intptr_t) dev->regions[i].base_addr, 1574e578869Smrg (size_t) dev->regions[i].size, 1584e578869Smrg (dev->regions[i].is_IO) ? "I/O" : "MEM" ); 1594e578869Smrg 1604e578869Smrg if ( ! dev->regions[i].is_IO ) { 1614e578869Smrg if ( dev->regions[i].is_prefetchable ) { 1624e578869Smrg printf( " PREFETCHABLE" ); 1634e578869Smrg } 1644e578869Smrg } 1654e578869Smrg 1664e578869Smrg printf( "\n" ); 1674e578869Smrg } 1684e578869Smrg } 1694e578869Smrg 1704e578869Smrg if ( dev->rom_size ) { 1714e578869Smrg printf( " BASEROM 0x%08x addr 0x%08x\n", 1724e578869Smrg 0, 0 ); 1734e578869Smrg } 1744e578869Smrg 1754e578869Smrg pci_device_cfg_read_u8( dev, & int_pin, 61 ); 1764e578869Smrg pci_device_cfg_read_u8( dev, & min_grant, 62 ); 1774e578869Smrg pci_device_cfg_read_u8( dev, & max_latency, 63 ); 1784e578869Smrg 1794e578869Smrg printf( " MAX_LAT 0x%02x MIN_GNT 0x%02x INT_PIN 0x%02x INT_LINE 0x%02x\n", 1804e578869Smrg max_latency, 1814e578869Smrg min_grant, 1824e578869Smrg int_pin, 1834e578869Smrg dev->irq ); 1844e578869Smrg 1854e578869Smrg if ( (dev->device_class >> 16) == 0x06 ) { 1864e578869Smrg const void * info; 1874e578869Smrg 1884e578869Smrg if ( (info = pci_device_get_bridge_info(dev)) != NULL ) { 1894e578869Smrg print_pci_bridge( (const struct pci_bridge_info *) info ); 1904e578869Smrg } 1914e578869Smrg else if ( (info = pci_device_get_pcmcia_bridge_info(dev)) != NULL ) { 1924e578869Smrg /* Nothing yet. */ 1934e578869Smrg } 1944e578869Smrg } 1954e578869Smrg } 1964e578869Smrg} 1974e578869Smrg 1984e578869Smrg 1994e578869Smrgint main( int argc, char ** argv ) 2004e578869Smrg{ 2014e578869Smrg struct pci_device_iterator * iter; 2024e578869Smrg struct pci_device * dev; 2034e578869Smrg int ret; 2044e578869Smrg int verbose = 0; 2054e578869Smrg int c; 2064e578869Smrg int errors = 0; 2074e578869Smrg 2084e578869Smrg while ((c = getopt(argc, argv, "v")) != -1) { 2094e578869Smrg switch (c) { 2104e578869Smrg case 'v': 2114e578869Smrg verbose = 1; 2124e578869Smrg break; 2134e578869Smrg case '?': 2144e578869Smrg errors++; 2154e578869Smrg } 2164e578869Smrg } 2174e578869Smrg if (errors != 0) { 2184e578869Smrg fprintf(stderr, "usage: %s [-v]\n", argv[0]); 2194e578869Smrg exit(2); 2204e578869Smrg } 2214e578869Smrg 2224e578869Smrg ret = pci_system_init(); 2234e578869Smrg if (ret != 0) 2244e578869Smrg err(1, "Couldn't initialize PCI system"); 2254e578869Smrg 2264e578869Smrg iter = pci_slot_match_iterator_create( NULL ); 2274e578869Smrg 2284e578869Smrg while ( (dev = pci_device_next( iter )) != NULL ) { 2294e578869Smrg print_pci_device( dev, verbose ); 2304e578869Smrg } 2314e578869Smrg 2324e578869Smrg pci_system_cleanup(); 2334e578869Smrg return 0; 2344e578869Smrg} 235