scanpci.c revision 4e578869
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 254e578869Smrg#include <stdlib.h> 264e578869Smrg#include <stdio.h> 274e578869Smrg#include <err.h> 284e578869Smrg#include <unistd.h> 294e578869Smrg 304e578869Smrg#include "pciaccess.h" 314e578869Smrg 324e578869Smrg 334e578869Smrgstatic void 344e578869Smrgprint_pci_bridge( const struct pci_bridge_info * info ) 354e578869Smrg{ 364e578869Smrg printf( " Bus: primary=%02x, secondary=%02x, subordinate=%02x, " 374e578869Smrg "sec-latency=%u\n", 384e578869Smrg info->primary_bus, 394e578869Smrg info->secondary_bus, 404e578869Smrg info->subordinate_bus, 414e578869Smrg info->secondary_latency_timer ); 424e578869Smrg printf( " I/O behind bridge: %08x-%08x\n", 434e578869Smrg info->io_base, 444e578869Smrg info->io_limit ); 454e578869Smrg printf( " Memory behind bridge: %08x-%08x\n", 464e578869Smrg info->mem_base, 474e578869Smrg info->mem_limit ); 484e578869Smrg printf( " Prefetchable memory behind bridge: %08llx-%08llx\n", 494e578869Smrg info->prefetch_mem_base, 504e578869Smrg info->prefetch_mem_limit ); 514e578869Smrg} 524e578869Smrg 534e578869Smrgstatic void 544e578869Smrgprint_pci_device( struct pci_device * dev, int verbose ) 554e578869Smrg{ 564e578869Smrg const char * dev_name; 574e578869Smrg const char * vend_name; 584e578869Smrg 594e578869Smrg vend_name = pci_device_get_vendor_name( dev ); 604e578869Smrg dev_name = pci_device_get_device_name( dev ); 614e578869Smrg if ( dev_name == NULL ) { 624e578869Smrg dev_name = "Device unknown"; 634e578869Smrg } 644e578869Smrg 654e578869Smrg printf("\npci "); 664e578869Smrg if (dev->domain != 0) 674e578869Smrg printf("domain 0x%04x ", dev->domain); 684e578869Smrg printf("bus 0x%04x cardnum 0x%02x function 0x%02x:" 694e578869Smrg " vendor 0x%04x device 0x%04x\n", 704e578869Smrg dev->bus, 714e578869Smrg dev->dev, 724e578869Smrg dev->func, 734e578869Smrg dev->vendor_id, 744e578869Smrg dev->device_id ); 754e578869Smrg if ( vend_name != NULL ) { 764e578869Smrg printf( " %s %s\n", vend_name, dev_name ); 774e578869Smrg } 784e578869Smrg else { 794e578869Smrg printf( " %s\n", dev_name ); 804e578869Smrg } 814e578869Smrg 824e578869Smrg if ( verbose ) { 834e578869Smrg unsigned i; 844e578869Smrg uint16_t command, status; 854e578869Smrg uint8_t bist; 864e578869Smrg uint8_t header_type; 874e578869Smrg uint8_t latency_timer; 884e578869Smrg uint8_t cache_line_size; 894e578869Smrg uint8_t max_latency; 904e578869Smrg uint8_t min_grant; 914e578869Smrg uint8_t int_pin; 924e578869Smrg 934e578869Smrg 944e578869Smrg vend_name = pci_device_get_subvendor_name( dev ); 954e578869Smrg dev_name = pci_device_get_subdevice_name( dev ); 964e578869Smrg if ( dev_name == NULL ) { 974e578869Smrg dev_name = "Card unknown"; 984e578869Smrg } 994e578869Smrg 1004e578869Smrg printf( " CardVendor 0x%04x card 0x%04x (", 1014e578869Smrg dev->subvendor_id, 1024e578869Smrg dev->subdevice_id ); 1034e578869Smrg if ( vend_name != NULL ) { 1044e578869Smrg printf( "%s, %s)\n", vend_name, dev_name ); 1054e578869Smrg } 1064e578869Smrg else { 1074e578869Smrg printf( "%s)\n", dev_name ); 1084e578869Smrg } 1094e578869Smrg 1104e578869Smrg pci_device_cfg_read_u16( dev, & command, 4 ); 1114e578869Smrg pci_device_cfg_read_u16( dev, & status, 6 ); 1124e578869Smrg printf( " STATUS 0x%04x COMMAND 0x%04x\n", 1134e578869Smrg status, 1144e578869Smrg command ); 1154e578869Smrg printf( " CLASS 0x%02x 0x%02x 0x%02x REVISION 0x%02x\n", 1164e578869Smrg (dev->device_class >> 16) & 0x0ff, 1174e578869Smrg (dev->device_class >> 8) & 0x0ff, 1184e578869Smrg (dev->device_class >> 0) & 0x0ff, 1194e578869Smrg dev->revision ); 1204e578869Smrg 1214e578869Smrg pci_device_cfg_read_u8( dev, & cache_line_size, 12 ); 1224e578869Smrg pci_device_cfg_read_u8( dev, & latency_timer, 13 ); 1234e578869Smrg pci_device_cfg_read_u8( dev, & header_type, 14 ); 1244e578869Smrg pci_device_cfg_read_u8( dev, & bist, 15 ); 1254e578869Smrg 1264e578869Smrg printf( " BIST 0x%02x HEADER 0x%02x LATENCY 0x%02x CACHE 0x%02x\n", 1274e578869Smrg bist, 1284e578869Smrg header_type, 1294e578869Smrg latency_timer, 1304e578869Smrg cache_line_size ); 1314e578869Smrg 1324e578869Smrg pci_device_probe( dev ); 1334e578869Smrg for ( i = 0 ; i < 6 ; i++ ) { 1344e578869Smrg if ( dev->regions[i].base_addr != 0 ) { 1354e578869Smrg printf( " BASE%u 0x%08x SIZE %d %s", 1364e578869Smrg i, 1374e578869Smrg (intptr_t) dev->regions[i].base_addr, 1384e578869Smrg (size_t) dev->regions[i].size, 1394e578869Smrg (dev->regions[i].is_IO) ? "I/O" : "MEM" ); 1404e578869Smrg 1414e578869Smrg if ( ! dev->regions[i].is_IO ) { 1424e578869Smrg if ( dev->regions[i].is_prefetchable ) { 1434e578869Smrg printf( " PREFETCHABLE" ); 1444e578869Smrg } 1454e578869Smrg } 1464e578869Smrg 1474e578869Smrg printf( "\n" ); 1484e578869Smrg } 1494e578869Smrg } 1504e578869Smrg 1514e578869Smrg if ( dev->rom_size ) { 1524e578869Smrg printf( " BASEROM 0x%08x addr 0x%08x\n", 1534e578869Smrg 0, 0 ); 1544e578869Smrg } 1554e578869Smrg 1564e578869Smrg pci_device_cfg_read_u8( dev, & int_pin, 61 ); 1574e578869Smrg pci_device_cfg_read_u8( dev, & min_grant, 62 ); 1584e578869Smrg pci_device_cfg_read_u8( dev, & max_latency, 63 ); 1594e578869Smrg 1604e578869Smrg printf( " MAX_LAT 0x%02x MIN_GNT 0x%02x INT_PIN 0x%02x INT_LINE 0x%02x\n", 1614e578869Smrg max_latency, 1624e578869Smrg min_grant, 1634e578869Smrg int_pin, 1644e578869Smrg dev->irq ); 1654e578869Smrg 1664e578869Smrg if ( (dev->device_class >> 16) == 0x06 ) { 1674e578869Smrg const void * info; 1684e578869Smrg 1694e578869Smrg if ( (info = pci_device_get_bridge_info(dev)) != NULL ) { 1704e578869Smrg print_pci_bridge( (const struct pci_bridge_info *) info ); 1714e578869Smrg } 1724e578869Smrg else if ( (info = pci_device_get_pcmcia_bridge_info(dev)) != NULL ) { 1734e578869Smrg /* Nothing yet. */ 1744e578869Smrg } 1754e578869Smrg } 1764e578869Smrg } 1774e578869Smrg} 1784e578869Smrg 1794e578869Smrg 1804e578869Smrgint main( int argc, char ** argv ) 1814e578869Smrg{ 1824e578869Smrg struct pci_device_iterator * iter; 1834e578869Smrg struct pci_device * dev; 1844e578869Smrg int ret; 1854e578869Smrg int verbose = 0; 1864e578869Smrg int c; 1874e578869Smrg int errors = 0; 1884e578869Smrg 1894e578869Smrg while ((c = getopt(argc, argv, "v")) != -1) { 1904e578869Smrg switch (c) { 1914e578869Smrg case 'v': 1924e578869Smrg verbose = 1; 1934e578869Smrg break; 1944e578869Smrg case '?': 1954e578869Smrg errors++; 1964e578869Smrg } 1974e578869Smrg } 1984e578869Smrg if (errors != 0) { 1994e578869Smrg fprintf(stderr, "usage: %s [-v]\n", argv[0]); 2004e578869Smrg exit(2); 2014e578869Smrg } 2024e578869Smrg 2034e578869Smrg ret = pci_system_init(); 2044e578869Smrg if (ret != 0) 2054e578869Smrg err(1, "Couldn't initialize PCI system"); 2064e578869Smrg 2074e578869Smrg iter = pci_slot_match_iterator_create( NULL ); 2084e578869Smrg 2094e578869Smrg while ( (dev = pci_device_next( iter )) != NULL ) { 2104e578869Smrg print_pci_device( dev, verbose ); 2114e578869Smrg } 2124e578869Smrg 2134e578869Smrg pci_system_cleanup(); 2144e578869Smrg return 0; 2154e578869Smrg} 216