[haiku-development] [PATCH][RFC] PCI device reservation for old-style drivers, v0.2

  • From: "François Revol" <revol@xxxxxxx>
  • To: haiku-development@xxxxxxxxxxxxx
  • Date: Sun, 05 Apr 2009 17:26:18 +0200 CEST

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

Other related posts:

  • » [haiku-development] [PATCH][RFC] PCI device reservation for old-style drivers, v0.2 - François Revol