1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
|
/* codes from lspci/pciutils
* http://atrey.karlin.mff.cuni.cz/~mj/pciutils.shtml
*/
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/io.h>
#include <string.h>
#include <pci/pci.h>
#include "athcool.h"
#define die printf
struct pci_filter filter;
struct pci_access *pacc;
static int show_hex = 0;
static struct device *scan_device( struct pci_dev *p )
{
int how_much = (show_hex > 2) ? 256 : 64;
struct device *d;
if ( ! pci_filter_match(&filter, p) ) {
return (NULL);
}
/* d = xmalloc(sizeof(struct device)); */
if ( (d = malloc( sizeof(struct device) )) == NULL ) {
return (NULL);
}
bzero( d, sizeof( *d ) );
d->dev = p;
if ( !pci_read_block( p, 0, d->config, how_much ) ) {
die( "Unable to read %d bytes of configuration space.", how_much );
}
if ( how_much < 128
&& (d->config[PCI_HEADER_TYPE] & 0x7f) == PCI_HEADER_TYPE_CARDBUS ) {
/* For cardbus bridges,
we need to fetch 64 bytes more to get the full standard header... */
if ( !pci_read_block( p, 64, d->config + 64, 64 ) ) {
die( "Unable to read cardbus bridge extension data." );
}
how_much = 128;
}
d->config_cnt = how_much;
pci_setup_cache( p, d->config, d->config_cnt );
pci_fill_info( p,
PCI_FILL_IDENT | PCI_FILL_IRQ | PCI_FILL_BASES |
PCI_FILL_ROM_BASE | PCI_FILL_SIZES );
return (d);
}
struct device *scan_devices( void )
{
struct device *d;
struct device *first_dev = NULL;
struct pci_dev *p;
pci_scan_bus( pacc );
for ( p = pacc->devices; p != NULL; p = p->next ) {
if ( (d = scan_device( p )) != NULL ) {
d->next = first_dev;
first_dev = d;
}
}
return (first_dev);
}
WORD_t get_conf_word(struct device *d, unsigned int pos)
{
return d->config[pos] | (d->config[pos+1] << 8);
}
/* End Of File **************************************************************/
|