* 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
This commit is contained in:
Axel Dörfler 2008-05-09 12:56:29 +00:00
parent 359f758bc4
commit 2d79691811
4 changed files with 197 additions and 131 deletions

View File

@ -7,6 +7,7 @@
#include "bus.h"
#include <KernelExport.h>
#include <PCI.h>
#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;
}

View File

@ -13,8 +13,9 @@
#include <string.h>
#include <KernelExport.h>
#include <module.h>
#include <Locker.h>
#include <module.h>
#include <PCI.h>
#include <fs/KPath.h>
#include <util/AutoLock.h>
@ -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<device_node> {
private:
status_t _RegisterFixed(uint32& registered);
bool _AlwaysRegisterDynamic();
status_t _AddPath(Stack<KPath*>& 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<KPath*>& 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<KPath*> 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}
};

View File

@ -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

View File

@ -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