enable/disable devices behavior

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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;
}

[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux