pci: support to lookup dev via class code/mask

This commit is contained in:
Alexander Boettcher 2013-02-18 11:20:15 +01:00 committed by Norman Feske
parent e05adecfab
commit 3a85d16597
3 changed files with 33 additions and 20 deletions

View File

@ -24,11 +24,14 @@ namespace Pci {
Session_client(Session_capability session) Session_client(Session_capability session)
: Genode::Rpc_client<Session>(session) { } : Genode::Rpc_client<Session>(session) { }
Device_capability first_device() { Device_capability first_device(unsigned device_class = 0,
return call<Rpc_first_device>(); } unsigned class_mask = 0) {
return call<Rpc_first_device>(device_class, class_mask); }
Device_capability next_device(Device_capability prev_device) { Device_capability next_device(Device_capability prev_device,
return call<Rpc_next_device>(prev_device); } unsigned device_class = 0,
unsigned class_mask = 0) {
return call<Rpc_next_device>(prev_device, device_class, class_mask); }
void release_device(Device_capability device) { void release_device(Device_capability device) {
call<Rpc_release_device>(device); } call<Rpc_release_device>(device); }

View File

@ -31,7 +31,7 @@ namespace Pci {
/** /**
* Find first accessible device * Find first accessible device
*/ */
virtual Device_capability first_device() = 0; virtual Device_capability first_device(unsigned, unsigned) = 0;
/** /**
* Find next accessible device * Find next accessible device
@ -41,7 +41,8 @@ namespace Pci {
* The 'prev_device' argument is used to iterate through all * The 'prev_device' argument is used to iterate through all
* devices. * devices.
*/ */
virtual Device_capability next_device(Device_capability prev_device) = 0; virtual Device_capability next_device(Device_capability prev_device,
unsigned, unsigned) = 0;
/** /**
* Free server-internal data structures representing the device * Free server-internal data structures representing the device
@ -65,9 +66,10 @@ namespace Pci {
** RPC declaration ** ** RPC declaration **
*********************/ *********************/
GENODE_RPC(Rpc_first_device, Device_capability, first_device); GENODE_RPC(Rpc_first_device, Device_capability, first_device,
unsigned, unsigned);
GENODE_RPC(Rpc_next_device, Device_capability, next_device, GENODE_RPC(Rpc_next_device, Device_capability, next_device,
Device_capability); Device_capability, unsigned, unsigned);
GENODE_RPC(Rpc_release_device, void, release_device, Device_capability); GENODE_RPC(Rpc_release_device, void, release_device, Device_capability);
GENODE_RPC(Rpc_config_extended, Genode::Io_mem_dataspace_capability, GENODE_RPC(Rpc_config_extended, Genode::Io_mem_dataspace_capability,
config_extended, Device_capability); config_extended, Device_capability);

View File

@ -190,10 +190,13 @@ namespace Pci {
** PCI session interface ** ** PCI session interface **
***************************/ ***************************/
Device_capability first_device() { Device_capability first_device(unsigned device_class,
return next_device(Device_capability()); } unsigned class_mask) {
return next_device(Device_capability(), device_class, class_mask); }
Device_capability next_device(Device_capability prev_device) Device_capability next_device(Device_capability prev_device,
unsigned device_class,
unsigned class_mask)
{ {
/* /*
* Create the interface to the PCI config space. * Create the interface to the PCI config space.
@ -210,20 +213,24 @@ namespace Pci {
* If no valid device was specified for 'prev_device', start at * If no valid device was specified for 'prev_device', start at
* the beginning. * the beginning.
*/ */
int bus = 0, device = 0, function = 0; int bus = 0, device = 0, function = -1;
if (prev) { if (prev) {
Device_config config = prev->config(); Device_config config = prev->config();
bus = config.bus_number(); bus = config.bus_number();
device = config.device_number(); device = config.device_number();
function = config.function_number() + 1; function = config.function_number();
} }
/* /*
* Scan busses for devices. * Scan buses for devices.
* If no device is found, return an invalid capability. * If no device is found, return an invalid capability.
*/ */
Device_config config; Device_config config;
do
{
function += 1;
if (!_find_next(bus, device, function, &config, &config_access)) if (!_find_next(bus, device, function, &config, &config_access))
return Device_capability(); return Device_capability();
@ -231,6 +238,7 @@ namespace Pci {
bus = config.bus_number(); bus = config.bus_number();
device = config.device_number(); device = config.device_number();
function = config.function_number(); function = config.function_number();
} while ((config.class_code() ^ device_class) & class_mask);
/* lookup if we have a extended pci config space */ /* lookup if we have a extended pci config space */
Genode::addr_t config_space = lookup_config_space(bus, device, Genode::addr_t config_space = lookup_config_space(bus, device,