I had another try at a way to reserve PCI devices from BeOS-style drivers, this time using the device_manager itself, by registering a fake node as child, so a new-style driver or another registration-aware BeOS-style driver would bail out. At least this should ensure mutual exclusion of OSS and native audio drivers. It's untested but builds. The part in legacy_driver stuff isn't finished. Ideally we would delegate the registration to it to make it easier to call from other bus managers (USB ? config_manager ?) The cookie passed might also be used later to get those drivers tell the device_manager which thing they publish refer to which device, though the interest is probably limited to just having a full device-tree. Comments ? François.
Index: src/system/kernel/device_manager/legacy_drivers.cpp =================================================================== --- src/system/kernel/device_manager/legacy_drivers.cpp (révision 29935) +++ src/system/kernel/device_manager/legacy_drivers.cpp (copie de travail) @@ -1376,3 +1376,17 @@ return B_OK; } + + +status_t +legacy_driver_register(device_node *parent, const char *driverName, void *nodeCookie) +{ + return B_OK; +} + +status_t +legacy_driver_unregister(device_node *parent, const char *driverName, void *nodeCookie) +{ + return B_OK; +} + Index: src/system/kernel/device_manager/legacy_drivers.h =================================================================== --- src/system/kernel/device_manager/legacy_drivers.h (révision 29935) +++ src/system/kernel/device_manager/legacy_drivers.h (copie de travail) @@ -18,6 +18,8 @@ status_t legacy_driver_rescan(const char* driverName); status_t legacy_driver_probe(const char* path); status_t legacy_driver_init(void); +//status_t legacy_driver_register(device_node *parent, const char *driverName, void *nodeCookie); +//status_t legacy_driver_unregister(device_node *parent, const char *driverName, void *nodeCookie); #ifdef __cplusplus } Index: src/add-ons/kernel/bus_managers/pci/pci_module.c =================================================================== --- src/add-ons/kernel/bus_managers/pci/pci_module.c (révision 29935) +++ src/add-ons/kernel/bus_managers/pci/pci_module.c (copie de travail) @@ -64,17 +64,51 @@ &pci_read_config, &pci_write_config, &pci_ram_address, - &pci_find_capability + &pci_find_capability, + &pci_reserve_device, + &pci_unreserve_device }; +static struct pci_module_info sOldR5PCIModule = { + { + { + "bus_managers/pci/v1", + B_KEEP_LOADED, + pci_old_module_std_ops + }, + NULL + }, + &pci_read_io_8, + &pci_write_io_8, + &pci_read_io_16, + &pci_write_io_16, + &pci_read_io_32, + &pci_write_io_32, + &pci_get_nth_pci_info, + &pci_read_config, + &pci_write_config, + &pci_ram_address +}; + module_dependency module_dependencies[] = { {B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&gDeviceManager}, {} }; +driver_module_info gPCILegacyDriverModule = { + { + PCI_LEGACY_DRIVER_MODULE_NAME, + 0, + NULL, + }, + NULL +}; + module_info *modules[] = { (module_info *)&sOldPCIModule, + (module_info *)&sOldR5PCIModule, (module_info *)&gPCIRootModule, (module_info *)&gPCIDeviceModule, + (module_info *)&gPCILegacyDriverModule, NULL }; Index: src/add-ons/kernel/bus_managers/pci/pci_private.h =================================================================== --- src/add-ons/kernel/bus_managers/pci/pci_private.h (révision 29935) +++ src/add-ons/kernel/bus_managers/pci/pci_private.h (copie de travail) @@ -12,6 +12,8 @@ #include <device_manager.h> #include <bus/PCI.h> +// name of PCI legacy driver endpoint module +#define PCI_LEGACY_DRIVER_MODULE_NAME "bus_managers/pci/legacy_v1" // name of PCI device modules #define PCI_DEVICE_MODULE_NAME "bus_managers/pci/driver_v1" @@ -46,6 +48,11 @@ status_t pci_find_capability(uchar bus, uchar device, uchar function, uchar cap_id, uchar *offset); +status_t pci_reserve_device(uchar virtualBus, uchar device, uchar function, + const char *driverName, void *nodeCookie); +status_t pci_unreserve_device(uchar virtualBus, uchar device, uchar function, + const char *driverName, void *nodeCookie); + status_t pci_io_init(void); uint8 pci_read_io_8(int mapped_io_addr); void pci_write_io_8(int mapped_io_addr, uint8 value); Index: src/add-ons/kernel/bus_managers/pci/pci.cpp =================================================================== --- src/add-ons/kernel/bus_managers/pci/pci.cpp (révision 29935) +++ src/add-ons/kernel/bus_managers/pci/pci.cpp (copie de travail) @@ -86,6 +86,96 @@ } +status_t +pci_reserve_device(uchar virtualBus, uchar device, uchar function, + const char *driverName, void *nodeCookie) +{ + status_t status; + uint8 bus; + int domain; + if (gPCI->ResolveVirtualBus(virtualBus, &domain, &bus) != B_OK) + return B_ERROR; + device_attr matchThis[] = { + // info about device + {B_DEVICE_BUS, B_STRING_TYPE, {string: "pci"}}, + + // location on PCI bus + {B_PCI_DEVICE_DOMAIN, B_UINT32_TYPE, {ui8: domain}}, + {B_PCI_DEVICE_BUS, B_UINT8_TYPE, {ui8: bus}}, + {B_PCI_DEVICE_DEVICE, B_UINT8_TYPE, {ui8: device}}, + {B_PCI_DEVICE_FUNCTION, B_UINT8_TYPE, {ui8: function}} + }; + + device_node *node; + if (gDeviceManager->get_next_child_node(gDeviceManager->get_root_node(), + matchThis, &node) < B_OK) + return B_ERROR; + + // common API for all legacy modules ? + //return legacy_driver_register(node, driverName, nodeCookie); + + device_attr attrsModel[] = { + // info about device + {B_DEVICE_BUS, B_STRING_TYPE, {string: "legacy_driver"}}, + {"legacy_driver", B_STRING_TYPE, {string: NULL}}, + {"legacy_driver_cookie", B_UINT64_TYPE, {ui64: (uint64)nodeCookie}} + }; + status = B_NO_MEMORY; + device_attr *attrs = (device_attr *)malloc(sizeof(attrsModel) + strlen(driverName) + 1); + if (attrs == NULL) + goto err0; + + memcpy(attrs, attrsModel, sizeof(attrsModel)); + attrs[1].value.string = ((const char *)attrs) + sizeof(attrsModel); + strcpy((char *)attrs[1].value.string, driverName); + + status = gDeviceManager->register_node(node, PCI_LEGACY_DRIVER_MODULE_NAME, + attrs, NULL, NULL); + if (status < B_OK) + goto err1; + gDeviceManager->put_node(node); + return B_OK; + +err1: + free(attrs); +err0: + gDeviceManager->put_node(node); + return status; +} + + +status_t +pci_unreserve_device(uchar virtualBus, uchar device, uchar function, + const char *driverName, void *nodeCookie) +{ + status_t status; + device_attr matchThis[] = { + // info about device + {B_DEVICE_BUS, B_STRING_TYPE, {string: "legacy_driver"}}, + {"legacy_driver", B_STRING_TYPE, {string: driverName}}, + {"legacy_driver_cookie", B_UINT64_TYPE, {ui64: (uint64)nodeCookie}} + }; + + device_node *node; + if (gDeviceManager->get_next_child_node(gDeviceManager->get_root_node(), + matchThis, &node) < B_OK) + return B_ERROR; + + device_attr *attrs = NULL; + status = gDeviceManager->get_next_attr(node, &attrs); + + status = gDeviceManager->unregister_node(node); + // don't risk freeing in-use mem + if (status < B_OK) + return status; + + free(attrs); + + //return legacy_driver_unregister(node, driverName, nodeCookie); + return B_OK; +} + + // used by pci_info.cpp print_info_basic() void __pci_resolve_virtual_bus(uint8 virtualBus, int *domain, uint8 *bus) Index: headers/os/drivers/PCI.h =================================================================== --- headers/os/drivers/PCI.h (révision 29935) +++ headers/os/drivers/PCI.h (copie de travail) @@ -155,9 +155,21 @@ uchar cap_id, uchar *offset ); + status_t (*pci_reserve_device) ( + uchar bus, + uchar device, + uchar function, + const char *driver_name, + void *cookie); + status_t (*pci_unreserve_device) ( + uchar bus, + uchar device, + uchar function, + const char *driver_name, + void *cookie); }; -#define B_PCI_MODULE_NAME "bus_managers/pci/v1" +#define B_PCI_MODULE_NAME "bus_managers/pci/v1.1" /* --- offsets in PCI configuration space to the elements of the predefined