From 2d79691811caf4a57330c3e829da598b55e52525 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Fri, 9 May 2008 12:56:29 +0000 Subject: [PATCH] * Changed how the driver paths are found: now, the bus can add type/sub-type/ interface information (in the PCI notion) to a node, and the possible paths of a device driver are generated from that information by the device manager. * Removed the "is bus" attribute - the device manager now decides wether or not a device always loads its children (as opposed to on demand loading only), even if the B_FIND_CHILD_ON_DEMAND flag is specified. * device_node::Register() now correctly maintains the fRegistered member field. * Replaced the driver_module() and driver_data() methods with a get_driver() method that retrieves all information at once. * Cleaned attribute names. * Some other cleanup, adding const where it makes sense. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25394 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/device_manager/playground/bus.cpp | 42 ++-- .../playground/device_manager.cpp | 225 +++++++++++------- .../playground/device_manager.h | 53 ++--- .../device_manager/playground/driver.cpp | 8 +- 4 files changed, 197 insertions(+), 131 deletions(-) diff --git a/src/tests/system/kernel/device_manager/playground/bus.cpp b/src/tests/system/kernel/device_manager/playground/bus.cpp index b7f5aa6801..5ae28c91fe 100644 --- a/src/tests/system/kernel/device_manager/playground/bus.cpp +++ b/src/tests/system/kernel/device_manager/playground/bus.cpp @@ -7,6 +7,7 @@ #include "bus.h" #include +#include #define BUS_MODULE_NAME "bus_managers/sample_bus/driver_v1" @@ -19,7 +20,7 @@ static float supports_device(device_node *parent) { const char* bus; - if (gDeviceManager->get_attr_string(parent, B_DRIVER_BUS, &bus, false) + if (gDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false) != B_OK) return -1; @@ -34,9 +35,8 @@ static status_t register_device(device_node *parent) { device_attr attrs[] = { - {B_DRIVER_PRETTY_NAME, B_STRING_TYPE, {string: "My Bus"}}, - {B_DRIVER_BUS, B_STRING_TYPE, {string: BUS_NAME}}, - {B_DRIVER_IS_BUS, B_UINT8_TYPE, {ui8: true}}, + {B_DEVICE_PRETTY_NAME, B_STRING_TYPE, {string: "My Bus"}}, + {B_DEVICE_BUS, B_STRING_TYPE, {string: BUS_NAME}}, {NULL} }; @@ -65,23 +65,32 @@ register_child_devices(device_node *node) const struct device_info { uint16 vendor; uint16 device; - const char *type; + uint16 type; + uint16 sub_type; + uint16 interface; } kDevices[] = { - {0x1000, 0x0001, B_DISK_DRIVER_TYPE}, - {0x1001, 0x0001, B_NETWORK_DRIVER_TYPE}, - {0x1002, 0x0001, B_AUDIO_DRIVER_TYPE}, - {0x1002, 0x0002, B_BUS_DRIVER_TYPE}, + {0x1000, 0x0001, PCI_mass_storage, PCI_sata, PCI_sata_ahci}, + {0x1001, 0x0001, PCI_network, PCI_ethernet, 0}, + {0x1002, 0x0001, PCI_multimedia, PCI_audio, 0}, + {0x1002, 0x0002, PCI_serial_bus, PCI_usb, PCI_usb_ehci}, }; const size_t kNumDevices = sizeof(kDevices) / sizeof(kDevices[0]); for (uint32 i = 0; i < kNumDevices; i++) { device_attr attrs[] = { // info about the device - {"bus/vendor", B_UINT16_TYPE, {ui16: kDevices[i].vendor}}, - {"bus/device", B_UINT16_TYPE, {ui16: kDevices[i].device}}, + {B_DEVICE_VENDOR_ID, B_UINT16_TYPE, {ui16: kDevices[i].vendor}}, + {B_DEVICE_ID, B_UINT16_TYPE, {ui16: kDevices[i].device}}, - {B_DRIVER_BUS, B_STRING_TYPE, {string: BUS_NAME}}, - {B_DRIVER_DEVICE_TYPE, B_STRING_TYPE, {string: kDevices[i].type}}, + {B_DEVICE_BUS, B_STRING_TYPE, {string: BUS_NAME}}, + {B_DEVICE_TYPE, B_UINT16_TYPE, {ui16: kDevices[i].type}}, + {B_DEVICE_SUB_TYPE, B_UINT16_TYPE, + {ui16: kDevices[i].sub_type}}, + {B_DEVICE_INTERFACE, B_UINT16_TYPE, + {ui16: kDevices[i].interface}}, + + {B_DEVICE_FIND_CHILD_FLAGS, B_UINT32_TYPE, + {ui32: B_FIND_CHILD_ON_DEMAND}}, {NULL} }; @@ -90,7 +99,8 @@ register_child_devices(device_node *node) } device_attr attrs[] = { - {B_DRIVER_FIXED_CHILD, B_STRING_TYPE, {string: "non_existing/driver_v1"}}, + {B_DEVICE_FIXED_CHILD, B_STRING_TYPE, + {string: "non_existing/driver_v1"}}, {NULL} }; @@ -122,9 +132,9 @@ device_removed(device_node *node) static status_t get_bus_info(void* cookie, bus_info* info) { - gDeviceManager->get_attr_uint16((device_node*)cookie, "bus/vendor", + gDeviceManager->get_attr_uint16((device_node*)cookie, B_DEVICE_VENDOR_ID, &info->vendor_id, false); - gDeviceManager->get_attr_uint16((device_node*)cookie, "bus/device", + gDeviceManager->get_attr_uint16((device_node*)cookie, B_DEVICE_ID, &info->device_id, false); return B_OK; } diff --git a/src/tests/system/kernel/device_manager/playground/device_manager.cpp b/src/tests/system/kernel/device_manager/playground/device_manager.cpp index 1c9aa4ba5e..fbe38931c7 100644 --- a/src/tests/system/kernel/device_manager/playground/device_manager.cpp +++ b/src/tests/system/kernel/device_manager/playground/device_manager.cpp @@ -13,8 +13,9 @@ #include #include -#include #include +#include +#include #include #include @@ -36,11 +37,13 @@ extern "C" status_t _get_builtin_dependencies(void); extern bool gDebugOutputEnabled; // from libkernelland_emu.so -status_t dm_get_attr_uint8(const device_node* node, const char* name, uint8* _value, - bool recursive); -status_t dm_get_attr_uint32(device_node* node, const char* name, uint32* _value, - bool recursive); -status_t dm_get_attr_string(device_node* node, const char* name, +status_t dm_get_attr_uint8(const device_node* node, const char* name, + uint8* _value, bool recursive); +status_t dm_get_attr_uint16(const device_node* node, const char* name, + uint16* _value, bool recursive); +status_t dm_get_attr_uint32(const device_node* node, const char* name, + uint32* _value, bool recursive); +status_t dm_get_attr_string(const device_node* node, const char* name, const char** _value, bool recursive); @@ -109,6 +112,9 @@ struct device_node : DoublyLinkedListLinkImpl { private: status_t _RegisterFixed(uint32& registered); + bool _AlwaysRegisterDynamic(); + status_t _AddPath(Stack& stack, const char* path, + const char* subPath = NULL); status_t _GetNextDriverPath(void*& cookie, KPath& _path); status_t _GetNextDriver(void* list, driver_module_info*& driver); @@ -117,7 +123,6 @@ private: float& bestSupport); status_t _RegisterPath(const char* path); status_t _RegisterDynamic(); - bool _IsBus() const; device_node* fParent; NodeList fChildren; @@ -496,30 +501,19 @@ device_node::Register() if (status != B_OK) return status; - if (!fChildren.IsEmpty()) + if (!fChildren.IsEmpty()) { + fRegistered = true; return B_OK; + } } // Register all possible child device nodes - uint32 findFlags = 0; - dm_get_attr_uint32(this, B_DRIVER_FIND_CHILD_FLAGS, &findFlags, false); + status = _RegisterDynamic(); + if (status == B_OK) + fRegistered = true; - if ((findFlags & B_FIND_CHILD_ON_DEMAND) != 0) - return B_OK; - - return _RegisterDynamic(); -} - - -bool -device_node::_IsBus() const -{ - uint8 isBus; - if (dm_get_attr_uint8(this, B_DRIVER_IS_BUS, &isBus, false) != B_OK) - return false; - - return isBus; + return status; } @@ -536,7 +530,7 @@ device_node::_RegisterFixed(uint32& registered) while (iterator.HasNext()) { device_attr_private* attr = iterator.Next(); - if (strcmp(attr->name, B_DRIVER_FIXED_CHILD)) + if (strcmp(attr->name, B_DEVICE_FIXED_CHILD)) continue; driver_module_info* driver; @@ -561,6 +555,27 @@ device_node::_RegisterFixed(uint32& registered) } +status_t +device_node::_AddPath(Stack& stack, const char* basePath, + const char* subPath) +{ + KPath* path = new(std::nothrow) KPath; + if (path == NULL) + return B_NO_MEMORY; + + status_t status = path->SetTo(basePath); + if (status == B_OK && subPath != NULL && subPath[0]) + status = path->Append(subPath); + if (status == B_OK) + status = stack.Push(path); + + if (status != B_OK) + delete path; + + return status; +} + + status_t device_node::_GetNextDriverPath(void*& cookie, KPath& _path) { @@ -573,40 +588,73 @@ device_node::_GetNextDriverPath(void*& cookie, KPath& _path) return B_NO_MEMORY; StackDeleter stackDeleter(stack); + uint16 type = 0; + uint16 subType = 0; + uint16 interface = 0; + dm_get_attr_uint16(this, B_DEVICE_TYPE, &type, false); + dm_get_attr_uint16(this, B_DEVICE_SUB_TYPE, &subType, false); + dm_get_attr_uint16(this, B_DEVICE_INTERFACE, &interface, false); - if (!_IsBus()) { - // add driver paths - KPath* path = new(std::nothrow) KPath; - if (path == NULL) - return B_NO_MEMORY; - - status_t status = path->SetTo("drivers"); - if (status != B_OK) { - delete path; - return status; - } - - // TODO: this might be more than one path! - const char *type; - if (dm_get_attr_string(this, B_DRIVER_DEVICE_TYPE, &type, false) - == B_OK) - path->Append(type); - - stack->Push(path); + // TODO: maybe make this extendible via settings file? + switch (type) { + case PCI_mass_storage: + switch (subType) { + case PCI_scsi: + _AddPath(*stack, "busses", "scsi"); + break; + case PCI_ide: + _AddPath(*stack, "busses", "ide"); + break; + case PCI_sata: + _AddPath(*stack, "busses", "sata"); + break; + default: + _AddPath(*stack, "busses", "disk"); + break; + } + break; + case PCI_serial_bus: + switch (subType) { + case PCI_firewire: + _AddPath(*stack, "busses", "firewire"); + break; + case PCI_usb: + _AddPath(*stack, "busses", "usb"); + break; + default: + _AddPath(*stack, "busses"); + break; + } + break; + case PCI_network: + _AddPath(*stack, "drivers", "net"); + break; + case PCI_display: + _AddPath(*stack, "drivers", "graphics"); + break; + case PCI_multimedia: + switch (subType) { + case PCI_audio: + case PCI_hd_audio: + _AddPath(*stack, "drivers", "audio"); + break; + case PCI_video: + _AddPath(*stack, "drivers", "video"); + break; + default: + _AddPath(*stack, "drivers"); + break; + } + break; + default: + if (sRootNode == this) { + _AddPath(*stack, "busses/pci"); + _AddPath(*stack, "bus_managers"); + } else + _AddPath(*stack, "drivers"); + break; } - // add bus paths - KPath* path = new(std::nothrow) KPath; - if (path == NULL) - return B_NO_MEMORY; - - status_t status = path->SetTo("bus"); - if (status != B_OK) { - delete path; - return status; - } - - stack->Push(path); stackDeleter.Detach(); cookie = (void*)stack; @@ -705,13 +753,30 @@ printf(" register module \"%s\", support %f\n", driver->info.name, support); } +bool +device_node::_AlwaysRegisterDynamic() +{ + uint16 type = 0; + uint16 subType = 0; + dm_get_attr_uint16(this, B_DEVICE_TYPE, &type, false); + dm_get_attr_uint16(this, B_DEVICE_SUB_TYPE, &subType, false); + + return type == PCI_serial_bus || type == PCI_bridge; + // TODO: we may want to be a bit more specific in the future +} + + status_t device_node::_RegisterDynamic() { - uint32 findFlags; - if (dm_get_attr_uint32(this, B_DRIVER_FIND_CHILD_FLAGS, &findFlags, false) - != B_OK) - findFlags = 0; + uint32 findFlags = 0; + dm_get_attr_uint32(this, B_DEVICE_FIND_CHILD_FLAGS, &findFlags, false); + + // If this is our initial registration, we honour the B_FIND_CHILD_ON_DEMAND + // requirements + if (!fRegistered && (findFlags & B_FIND_CHILD_ON_DEMAND) != 0 + && !_AlwaysRegisterDynamic()) + return B_OK; KPath path; @@ -825,17 +890,13 @@ unregister_device(device_node* node) } -static driver_module_info* -driver_module(device_node* node) +static void +get_driver(device_node* node, driver_module_info** _module, void** _data) { - return node->DriverModule(); -} - - -static void* -driver_data(device_node* node) -{ - return node->DriverData(); + if (_module != NULL) + *_module = node->DriverModule(); + if (_data != NULL) + *_data = node->DriverData(); } @@ -885,7 +946,7 @@ dm_get_attr_uint8(const device_node* node, const char* name, uint8* _value, status_t -dm_get_attr_uint16(device_node* node, const char* name, uint16* _value, +dm_get_attr_uint16(const device_node* node, const char* name, uint16* _value, bool recursive) { if (node == NULL || name == NULL || _value == NULL) @@ -902,7 +963,7 @@ dm_get_attr_uint16(device_node* node, const char* name, uint16* _value, status_t -dm_get_attr_uint32(device_node* node, const char* name, uint32* _value, +dm_get_attr_uint32(const device_node* node, const char* name, uint32* _value, bool recursive) { if (node == NULL || name == NULL || _value == NULL) @@ -919,7 +980,7 @@ dm_get_attr_uint32(device_node* node, const char* name, uint32* _value, status_t -dm_get_attr_uint64(device_node* node, const char* name, +dm_get_attr_uint64(const device_node* node, const char* name, uint64* _value, bool recursive) { if (node == NULL || name == NULL || _value == NULL) @@ -936,8 +997,8 @@ dm_get_attr_uint64(device_node* node, const char* name, status_t -dm_get_attr_string(device_node* node, const char* name, const char** _value, - bool recursive) +dm_get_attr_string(const device_node* node, const char* name, + const char** _value, bool recursive) { if (node == NULL || name == NULL || _value == NULL) return B_BAD_VALUE; @@ -953,7 +1014,7 @@ dm_get_attr_string(device_node* node, const char* name, const char** _value, status_t -dm_get_attr_raw(device_node* node, const char* name, const void** _data, +dm_get_attr_raw(const device_node* node, const char* name, const void** _data, size_t* _length, bool recursive) { if (node == NULL || name == NULL || (_data == NULL && _length == NULL)) @@ -1005,8 +1066,7 @@ static struct device_manager_info sDeviceManagerModule = { rescan_device, register_device, unregister_device, - driver_module, - driver_data, + get_driver, device_root, get_next_child_device, get_parent, @@ -1030,10 +1090,9 @@ void dm_init_root_node(void) { device_attr attrs[] = { - {B_DRIVER_PRETTY_NAME, B_STRING_TYPE, {string: "Devices Root"}}, - {B_DRIVER_IS_BUS, B_UINT8_TYPE, {ui8: true}}, - {B_DRIVER_BUS, B_STRING_TYPE, {string: "root"}}, - {B_DRIVER_FIND_CHILD_FLAGS, B_UINT32_TYPE, + {B_DEVICE_PRETTY_NAME, B_STRING_TYPE, {string: "Devices Root"}}, + {B_DEVICE_BUS, B_STRING_TYPE, {string: "root"}}, + {B_DEVICE_FIND_CHILD_FLAGS, B_UINT32_TYPE, {ui32: B_FIND_MULTIPLE_CHILDREN}}, {NULL} }; diff --git a/src/tests/system/kernel/device_manager/playground/device_manager.h b/src/tests/system/kernel/device_manager/playground/device_manager.h index 2e0c88c7de..f61fb82636 100644 --- a/src/tests/system/kernel/device_manager/playground/device_manager.h +++ b/src/tests/system/kernel/device_manager/playground/device_manager.h @@ -69,8 +69,8 @@ typedef struct device_manager_info { device_node **_node); status_t (*unregister_device)(device_node *node); - driver_module_info *(*driver_module)(device_node *node); - void *(*driver_data)(device_node *node); + void (*get_driver)(device_node *node, driver_module_info **_module, + void **_cookie); device_node *(*root_device)(); status_t (*get_next_child_device)(device_node *parent, device_node *node, @@ -86,17 +86,17 @@ typedef struct device_manager_info { status_t (*free_id)(const char *generator, uint32 id); #endif - status_t (*get_attr_uint8)(device_node *node, const char *name, + status_t (*get_attr_uint8)(const device_node *node, const char *name, uint8 *value, bool recursive); - status_t (*get_attr_uint16)(device_node *node, const char *name, + status_t (*get_attr_uint16)(const device_node *node, const char *name, uint16 *value, bool recursive); - status_t (*get_attr_uint32)(device_node *node, const char *name, + status_t (*get_attr_uint32)(const device_node *node, const char *name, uint32 *value, bool recursive); - status_t (*get_attr_uint64)(device_node *node, const char *name, + status_t (*get_attr_uint64)(const device_node *node, const char *name, uint64 *value, bool recursive); - status_t (*get_attr_string)(device_node *node, const char *name, + status_t (*get_attr_string)(const device_node *node, const char *name, const char **_value, bool recursive); - status_t (*get_attr_raw)(device_node *node, const char *name, + status_t (*get_attr_raw)(const device_node *node, const char *name, const void **_data, size_t *_size, bool recursive); status_t (*get_next_attr)(device_node *node, device_attr **_attr); @@ -122,32 +122,29 @@ struct driver_module_info { }; -// standard device node attributes +/* standard device node attributes */ -#define B_DRIVER_PRETTY_NAME "driver/pretty name" // string -#define B_DRIVER_MAPPING "driver/mapping" // string -#define B_DRIVER_IS_BUS "driver/is_bus" // uint8 -#define B_DRIVER_BUS "driver/bus" // string -#define B_DRIVER_FIXED_CHILD "fixed child" // string -#define B_DRIVER_FIND_CHILD_FLAGS "find child flags" // uint32 -#define B_DRIVER_UNIQUE_DEVICE_ID "unique id" // string -#define B_DRIVER_DEVICE_TYPE "device type" // string +#define B_DEVICE_PRETTY_NAME "device/pretty name" /* string */ +#define B_DEVICE_MAPPING "device/mapping" /* string */ +#define B_DEVICE_BUS "device/bus" /* string */ +#define B_DEVICE_FIXED_CHILD "device/fixed child" /* string */ +#define B_DEVICE_FIND_CHILD_FLAGS "device/find child flags" /* uint32 */ + +#define B_DEVICE_VENDOR_ID "device/vendor" /* uint16 */ +#define B_DEVICE_ID "device/id" /* uint16 */ +#define B_DEVICE_TYPE "device/type" + /* uint16, PCI base class */ +#define B_DEVICE_SUB_TYPE "device/subtype" + /* uint16, PCI sub type */ +#define B_DEVICE_INTERFACE "device/interface" + /* uint16, PCI class API */ + +#define B_DEVICE_UNIQUE_ID "device/unique id" /* string */ // find child flags #define B_FIND_CHILD_ON_DEMAND 0x01 #define B_FIND_MULTIPLE_CHILDREN 0x02 -// driver types -#define B_AUDIO_DRIVER_TYPE "audio" -#define B_BUS_DRIVER_TYPE "bus" -#define B_DISK_DRIVER_TYPE "disk" -#define B_GRAPHICS_DRIVER_TYPE "graphics" -#define B_INPUT_DRIVER_TYPE "input" -#define B_MISC_DRIVER_TYPE "misc" -#define B_NETWORK_DRIVER_TYPE "net" -#define B_VIDEO_DRIVER_TYPE "video" -#define B_INTERRUPT_CONTROLLER_DRIVER_TYPE "interrupt controller" - // interface of device diff --git a/src/tests/system/kernel/device_manager/playground/driver.cpp b/src/tests/system/kernel/device_manager/playground/driver.cpp index f1f00d6fec..455d6328b7 100644 --- a/src/tests/system/kernel/device_manager/playground/driver.cpp +++ b/src/tests/system/kernel/device_manager/playground/driver.cpp @@ -28,13 +28,13 @@ supports_device(device_node *parent) return -1; #endif - bus_for_driver_module_info* module - = (bus_for_driver_module_info*)gDeviceManager->driver_module(parent); + bus_for_driver_module_info* module; + void* data; + gDeviceManager->get_driver(parent, (driver_module_info**)&module, &data); + if (strcmp(module->info.info.name, BUS_FOR_DRIVER_NAME)) return -1; - void* data = gDeviceManager->driver_data(parent); - bus_info info; if (module->get_bus_info(data, &info) == B_OK && info.vendor_id == 0x1001