diff --git a/os/include/pci_session/client.h b/os/include/pci_session/client.h index a28ea78b1..4c76c0232 100644 --- a/os/include/pci_session/client.h +++ b/os/include/pci_session/client.h @@ -24,11 +24,14 @@ namespace Pci { Session_client(Session_capability session) : Genode::Rpc_client(session) { } - Device_capability first_device() { - return call(); } + Device_capability first_device(unsigned device_class = 0, + unsigned class_mask = 0) { + return call(device_class, class_mask); } - Device_capability next_device(Device_capability prev_device) { - return call(prev_device); } + Device_capability next_device(Device_capability prev_device, + unsigned device_class = 0, + unsigned class_mask = 0) { + return call(prev_device, device_class, class_mask); } void release_device(Device_capability device) { call(device); } diff --git a/os/include/pci_session/pci_session.h b/os/include/pci_session/pci_session.h index 3cff3ae83..c85646878 100644 --- a/os/include/pci_session/pci_session.h +++ b/os/include/pci_session/pci_session.h @@ -31,7 +31,7 @@ namespace Pci { /** * Find first accessible device */ - virtual Device_capability first_device() = 0; + virtual Device_capability first_device(unsigned, unsigned) = 0; /** * Find next accessible device @@ -41,7 +41,8 @@ namespace Pci { * The 'prev_device' argument is used to iterate through all * 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 @@ -65,9 +66,10 @@ namespace Pci { ** 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, - Device_capability); + Device_capability, unsigned, unsigned); GENODE_RPC(Rpc_release_device, void, release_device, Device_capability); GENODE_RPC(Rpc_config_extended, Genode::Io_mem_dataspace_capability, config_extended, Device_capability); diff --git a/os/src/drivers/pci/pci_session_component.h b/os/src/drivers/pci/pci_session_component.h index b713c0467..f18599783 100644 --- a/os/src/drivers/pci/pci_session_component.h +++ b/os/src/drivers/pci/pci_session_component.h @@ -190,10 +190,13 @@ namespace Pci { ** PCI session interface ** ***************************/ - Device_capability first_device() { - return next_device(Device_capability()); } + Device_capability first_device(unsigned device_class, + 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. @@ -210,27 +213,32 @@ namespace Pci { * If no valid device was specified for 'prev_device', start at * the beginning. */ - int bus = 0, device = 0, function = 0; + int bus = 0, device = 0, function = -1; if (prev) { Device_config config = prev->config(); bus = config.bus_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. */ Device_config config; - if (!_find_next(bus, device, function, &config, &config_access)) - return Device_capability(); - /* get new bdf values */ - bus = config.bus_number(); - device = config.device_number(); - function = config.function_number(); + do + { + function += 1; + if (!_find_next(bus, device, function, &config, &config_access)) + return Device_capability(); + + /* get new bdf values */ + bus = config.bus_number(); + device = config.device_number(); + function = config.function_number(); + } while ((config.class_code() ^ device_class) & class_mask); /* lookup if we have a extended pci config space */ Genode::addr_t config_space = lookup_config_space(bus, device,