Hi,
AFAIK, the existing interface in libpciaccess to enable a device
(pci_device_enable) deals always with I/O _and_ memory resources. But
I'm confused with the behavior of such interface because it's not
working as I expected. For me it has to be equivalent to do the
following, in the regs configuration space:
ctrl = (PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
pci_device_cfg_write_u32(dev, ctrl, PCI_COMMAND);
Isn't it? But it's not happening that. When I call pci_device_enable (or
just `echo 1 > enable` in device) the kernel sometimes sets only the
PCI_COMMAND_MEMORY bit or simply does nothing. What am I missing here?
Attached, I'm sending a code that I'm using to play with this.
Cheers,
Tiago
#include <stdlib.h>
#include <stdio.h>
#include <err.h>
#include <unistd.h>
#include <linux/pci_regs.h>
#include "pciaccess.h"
#define IS_VGA(c) (((c) & 0x00ffff00) \
== ((0x03 << 16) | (0x00 << 8)))
static void
print_pci_device_command( struct pci_device * dev)
{
const char * dev_name;
const char * vend_name;
uint16_t command;
vend_name = pci_device_get_vendor_name( dev );
dev_name = pci_device_get_device_name( dev );
if ( dev_name == NULL ) {
dev_name = "Device unknown";
}
printf("\npci ");
printf(" %04x:%02x:%02x.%01x ",
dev->domain,
dev->bus,
dev->dev,
dev->func);
if ( vend_name != NULL ) {
printf( " %s %s\n", vend_name, dev_name );
}
else {
printf( " %s\n", dev_name );
}
vend_name = pci_device_get_subvendor_name( dev );
dev_name = pci_device_get_subdevice_name( dev );
if ( dev_name == NULL ) {
dev_name = "Card unknown";
}
pci_device_cfg_read_u16( dev, &command, PCI_COMMAND);
printf( "COMMAND 0x%04x\n", command );
}
int main( int argc, char ** argv )
{
struct pci_device_iterator * iter;
struct pci_device * dev;
int ret;
ret = pci_system_init();
if (ret != 0)
err(1, "Couldn't initialize PCI system");
iter = pci_slot_match_iterator_create( NULL );
fprintf(stderr, "=====before=====");
while ( (dev = pci_device_next( iter )) != NULL ) {
if (IS_VGA(dev->device_class))
print_pci_device_command(dev);
}
/* comment the following */
iter = pci_slot_match_iterator_create( NULL );
while ((dev = pci_device_next( iter )) != NULL ) {
if (IS_VGA(dev->device_class))
pci_device_enable(dev);
}
iter = pci_slot_match_iterator_create( NULL );
fprintf(stderr, "\n\n=====after=====");
while ( (dev = pci_device_next( iter )) != NULL ) {
if (IS_VGA(dev->device_class))
print_pci_device_command(dev);
}
pci_system_cleanup();
return 0;
}