Some more changes towards a working prototype:
* The "net" driver is now also loaded. * The node tree is now dumped. * If registering fails, the node is now removed from its parent again (for now, correct would be to release it). * device_node::_RegisterDynamic() now also checks for the driver path. * _RegisterFixed() no longer calls supports_device() - since it has been directly specified, we will assume the user knows what he is doing. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25112 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
#include "bus.h"
|
#include "bus.h"
|
||||||
|
|
||||||
|
#include <KernelExport.h>
|
||||||
|
|
||||||
|
|
||||||
#define BUS_MODULE_NAME "bus_managers/sample_bus/driver_v1"
|
#define BUS_MODULE_NAME "bus_managers/sample_bus/driver_v1"
|
||||||
|
|
||||||
@@ -34,7 +36,7 @@ register_device(device_node *parent)
|
|||||||
device_attr attrs[] = {
|
device_attr attrs[] = {
|
||||||
{B_DRIVER_PRETTY_NAME, B_STRING_TYPE, {string: "My Bus"}},
|
{B_DRIVER_PRETTY_NAME, B_STRING_TYPE, {string: "My Bus"}},
|
||||||
{B_DRIVER_BUS, B_STRING_TYPE, {string: BUS_NAME}},
|
{B_DRIVER_BUS, B_STRING_TYPE, {string: BUS_NAME}},
|
||||||
{B_DRIVER_IS_BUS, B_INT8_TYPE, {ui8: true}},
|
{B_DRIVER_IS_BUS, B_UINT8_TYPE, {ui8: true}},
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -46,6 +48,7 @@ register_device(device_node *parent)
|
|||||||
static status_t
|
static status_t
|
||||||
init_driver(device_node *node, void **_cookie)
|
init_driver(device_node *node, void **_cookie)
|
||||||
{
|
{
|
||||||
|
*_cookie = node;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,18 +77,28 @@ register_child_devices(device_node *node)
|
|||||||
for (uint32 i = 0; i < kNumDevices; i++) {
|
for (uint32 i = 0; i < kNumDevices; i++) {
|
||||||
device_attr attrs[] = {
|
device_attr attrs[] = {
|
||||||
// info about the device
|
// info about the device
|
||||||
{ "bus/vendor", B_UINT16_TYPE, { ui16: kDevices[i].vendor }},
|
{"bus/vendor", B_UINT16_TYPE, {ui16: kDevices[i].vendor}},
|
||||||
{ "bus/device", B_UINT16_TYPE, { ui16: kDevices[i].device }},
|
{"bus/device", B_UINT16_TYPE, {ui16: kDevices[i].device}},
|
||||||
|
|
||||||
{ B_DRIVER_BUS, B_STRING_TYPE, { string: "pci" }},
|
{B_DRIVER_BUS, B_STRING_TYPE, {string: BUS_NAME}},
|
||||||
{ B_DRIVER_DEVICE_TYPE, B_STRING_TYPE, { string: kDevices[i].type}},
|
{B_DRIVER_DEVICE_TYPE, B_STRING_TYPE, {string: kDevices[i].type}},
|
||||||
{ NULL }
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
gDeviceManager->register_device(node, BUS_DEVICE_NAME, attrs, NULL,
|
gDeviceManager->register_device(node, BUS_FOR_DRIVER_NAME, attrs, NULL,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
device_attr attrs[] = {
|
||||||
|
{B_DRIVER_FIXED_CHILD, B_STRING_TYPE, {string: "non_existing/driver_v1"}},
|
||||||
|
{NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
// this is supposed to fail
|
||||||
|
dprintf("non-existing child: %ld\n", gDeviceManager->register_device(node,
|
||||||
|
BUS_FOR_DRIVER_NAME, attrs, NULL, NULL));
|
||||||
|
#endif
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,6 +116,20 @@ device_removed(device_node *node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - for driver
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
get_bus_info(void* cookie, bus_info* info)
|
||||||
|
{
|
||||||
|
gDeviceManager->get_attr_uint16((device_node*)cookie, "bus/vendor",
|
||||||
|
&info->vendor_id, false);
|
||||||
|
gDeviceManager->get_attr_uint16((device_node*)cookie, "bus/device",
|
||||||
|
&info->device_id, false);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
@@ -123,19 +150,19 @@ struct driver_module_info gBusModuleInfo = {
|
|||||||
device_removed,
|
device_removed,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct driver_module_info gBusDriverModuleInfo = {
|
struct bus_for_driver_module_info gBusDriverModuleInfo = {
|
||||||
{
|
{
|
||||||
BUS_DEVICE_NAME,
|
{
|
||||||
0,
|
BUS_FOR_DRIVER_NAME,
|
||||||
NULL,
|
0,
|
||||||
},
|
NULL,
|
||||||
|
},
|
||||||
|
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
|
||||||
NULL,
|
init_driver,
|
||||||
NULL,
|
},
|
||||||
NULL,
|
get_bus_info
|
||||||
NULL,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -14,13 +14,13 @@ struct bus_info {
|
|||||||
uint16 device_id;
|
uint16 device_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bus_device_module_info {
|
struct bus_for_driver_module_info {
|
||||||
driver_module_info info;
|
driver_module_info info;
|
||||||
|
|
||||||
status_t (*get_bus_info)(void* cookie, bus_info* info);
|
status_t (*get_bus_info)(void* cookie, bus_info* info);
|
||||||
};
|
};
|
||||||
|
|
||||||
#define BUS_DEVICE_NAME "bus_managers/sample_bus/device/driver_v1"
|
#define BUS_FOR_DRIVER_NAME "bus_managers/sample_bus/device/driver_v1"
|
||||||
#define BUS_NAME "mybus"
|
#define BUS_NAME "mybus"
|
||||||
|
|
||||||
#endif // BUS_H
|
#endif // BUS_H
|
||||||
|
|||||||
@@ -34,10 +34,13 @@ extern "C" status_t _get_builtin_dependencies(void);
|
|||||||
extern bool gDebugOutputEnabled;
|
extern bool gDebugOutputEnabled;
|
||||||
// from libkernelland_emu.so
|
// 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,
|
status_t dm_get_attr_uint32(device_node* node, const char* name, uint32* _value,
|
||||||
bool recursive);
|
bool recursive);
|
||||||
|
status_t dm_get_attr_string(device_node* node, const char* name,
|
||||||
|
const char** _value, bool recursive);
|
||||||
|
|
||||||
device_manager_info *gDeviceManager;
|
|
||||||
|
|
||||||
struct device_attr_private : device_attr,
|
struct device_attr_private : device_attr,
|
||||||
DoublyLinkedListLinkImpl<device_attr_private> {
|
DoublyLinkedListLinkImpl<device_attr_private> {
|
||||||
@@ -85,6 +88,7 @@ struct device_node : DoublyLinkedListLinkImpl<device_node> {
|
|||||||
const char* ModuleName() const { return fModuleName; }
|
const char* ModuleName() const { return fModuleName; }
|
||||||
device_node* Parent() const { return fParent; }
|
device_node* Parent() const { return fParent; }
|
||||||
AttributeList& Attributes() { return fAttributes; }
|
AttributeList& Attributes() { return fAttributes; }
|
||||||
|
const AttributeList& Attributes() const { return fAttributes; }
|
||||||
|
|
||||||
status_t InitDriver();
|
status_t InitDriver();
|
||||||
void UninitDriver();
|
void UninitDriver();
|
||||||
@@ -95,6 +99,8 @@ struct device_node : DoublyLinkedListLinkImpl<device_node> {
|
|||||||
void* DriverData() const { return fDriverData; }
|
void* DriverData() const { return fDriverData; }
|
||||||
|
|
||||||
void AddChild(device_node *node);
|
void AddChild(device_node *node);
|
||||||
|
void RemoveChild(device_node *node);
|
||||||
|
const NodeList& Children() const { return fChildren; }
|
||||||
|
|
||||||
status_t Register();
|
status_t Register();
|
||||||
bool IsRegistered() const { return fRegistered; }
|
bool IsRegistered() const { return fRegistered; }
|
||||||
@@ -102,6 +108,7 @@ struct device_node : DoublyLinkedListLinkImpl<device_node> {
|
|||||||
private:
|
private:
|
||||||
status_t _RegisterFixed(uint32& registered);
|
status_t _RegisterFixed(uint32& registered);
|
||||||
status_t _RegisterDynamic();
|
status_t _RegisterDynamic();
|
||||||
|
bool _IsBus() const;
|
||||||
|
|
||||||
device_node* fParent;
|
device_node* fParent;
|
||||||
NodeList fChildren;
|
NodeList fChildren;
|
||||||
@@ -117,6 +124,8 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
device_manager_info *gDeviceManager;
|
||||||
|
|
||||||
static device_node *sRootNode;
|
static device_node *sRootNode;
|
||||||
|
|
||||||
|
|
||||||
@@ -258,11 +267,12 @@ device_attr_private::Compare(const device_attr* attrA, const device_attr *attrB)
|
|||||||
|
|
||||||
|
|
||||||
device_attr_private*
|
device_attr_private*
|
||||||
dm_find_attr(device_node* node, const char* name, bool recursive,
|
dm_find_attr(const device_node* node, const char* name, bool recursive,
|
||||||
type_code type)
|
type_code type)
|
||||||
{
|
{
|
||||||
do {
|
do {
|
||||||
AttributeList::Iterator iterator = node->Attributes().GetIterator();
|
AttributeList::ConstIterator iterator
|
||||||
|
= node->Attributes().GetIterator();
|
||||||
|
|
||||||
while (iterator.HasNext()) {
|
while (iterator.HasNext()) {
|
||||||
device_attr_private* attr = iterator.Next();
|
device_attr_private* attr = iterator.Next();
|
||||||
@@ -281,14 +291,78 @@ dm_find_attr(device_node* node, const char* name, bool recursive,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
put_level(int32 level)
|
||||||
|
{
|
||||||
|
while (level-- > 0)
|
||||||
|
dprintf(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
dump_attribute(device_attr* attr, int32 level)
|
||||||
|
{
|
||||||
|
if (attr == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
put_level(level + 2);
|
||||||
|
dprintf("\"%s\" : ", attr->name);
|
||||||
|
switch (attr->type) {
|
||||||
|
case B_STRING_TYPE:
|
||||||
|
dprintf("string : \"%s\"", attr->value.string);
|
||||||
|
break;
|
||||||
|
case B_INT8_TYPE:
|
||||||
|
case B_UINT8_TYPE:
|
||||||
|
dprintf("uint8 : %u (%#x)", attr->value.ui8, attr->value.ui8);
|
||||||
|
break;
|
||||||
|
case B_INT16_TYPE:
|
||||||
|
case B_UINT16_TYPE:
|
||||||
|
dprintf("uint16 : %u (%#x)", attr->value.ui16, attr->value.ui16);
|
||||||
|
break;
|
||||||
|
case B_INT32_TYPE:
|
||||||
|
case B_UINT32_TYPE:
|
||||||
|
dprintf("uint32 : %lu (%#lx)", attr->value.ui32, attr->value.ui32);
|
||||||
|
break;
|
||||||
|
case B_INT64_TYPE:
|
||||||
|
case B_UINT64_TYPE:
|
||||||
|
dprintf("uint64 : %Lu (%#Lx)", attr->value.ui64, attr->value.ui64);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dprintf("raw data");
|
||||||
|
}
|
||||||
|
dprintf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
dm_dump_node(device_node* node, int32 level)
|
||||||
|
{
|
||||||
|
if (node == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
put_level(level);
|
||||||
|
dprintf("(%ld) @%p \"%s\"\n", level, node, node->ModuleName());
|
||||||
|
|
||||||
|
AttributeList::Iterator attribute = node->Attributes().GetIterator();
|
||||||
|
while (attribute.HasNext()) {
|
||||||
|
dump_attribute(attribute.Next(), level);
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeList::ConstIterator iterator = node->Children().GetIterator();
|
||||||
|
while (iterator.HasNext()) {
|
||||||
|
dm_dump_node(iterator.Next(), level + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
/*! Allocate device node info structure;
|
/*! Allocate device node info structure;
|
||||||
initially, ref_count is one to make sure node won't get destroyed by mistake
|
initially, ref_count is one to make sure node won't get destroyed by mistake
|
||||||
*/
|
*/
|
||||||
device_node::device_node(const char *moduleName, const device_attr *attrs,
|
device_node::device_node(const char* moduleName, const device_attr* attrs,
|
||||||
const io_resource *resources)
|
const io_resource* resources)
|
||||||
{
|
{
|
||||||
fModuleName = strdup(moduleName);
|
fModuleName = strdup(moduleName);
|
||||||
if (fModuleName == NULL)
|
if (fModuleName == NULL)
|
||||||
@@ -373,7 +447,7 @@ device_node::UninitDriver()
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
device_node::AddChild(device_node *node)
|
device_node::AddChild(device_node* node)
|
||||||
{
|
{
|
||||||
// we must not be destroyed as long as we have children
|
// we must not be destroyed as long as we have children
|
||||||
fRefCount++;
|
fRefCount++;
|
||||||
@@ -382,6 +456,16 @@ device_node::AddChild(device_node *node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
device_node::RemoveChild(device_node* node)
|
||||||
|
{
|
||||||
|
fRefCount--;
|
||||||
|
// TODO: we may need to destruct ourselves here!
|
||||||
|
node->fParent = NULL;
|
||||||
|
fChildren.Remove(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
device_node::Register()
|
device_node::Register()
|
||||||
{
|
{
|
||||||
@@ -396,24 +480,38 @@ device_node::Register()
|
|||||||
|
|
||||||
// Register the children the driver wants
|
// Register the children the driver wants
|
||||||
|
|
||||||
if (DriverModule()->register_child_devices != NULL)
|
if (DriverModule()->register_child_devices != NULL) {
|
||||||
DriverModule()->register_child_devices(this);
|
status = DriverModule()->register_child_devices(this);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
if (!fChildren.IsEmpty())
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
// Register all possible child device nodes
|
// Register all possible child device nodes
|
||||||
|
|
||||||
uint32 findFlags;
|
uint32 findFlags = 0;
|
||||||
if (dm_get_attr_uint32(this, B_DRIVER_FIND_CHILD_FLAGS, &findFlags, false) != B_OK)
|
dm_get_attr_uint32(this, B_DRIVER_FIND_CHILD_FLAGS, &findFlags, false);
|
||||||
return B_OK;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
if ((findFlags & B_FIND_CHILD_ON_DEMAND) != 0)
|
if ((findFlags & B_FIND_CHILD_ON_DEMAND) != 0)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
#endif
|
|
||||||
|
|
||||||
return _RegisterDynamic();
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! Registers any children that are identified via the B_DRIVER_FIXED_CHILD
|
/*! Registers any children that are identified via the B_DRIVER_FIXED_CHILD
|
||||||
attribute.
|
attribute.
|
||||||
If any of these children cannot be registered, this call will fail (we
|
If any of these children cannot be registered, this call will fail (we
|
||||||
@@ -436,14 +534,8 @@ device_node::_RegisterFixed(uint32& registered)
|
|||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
if (driver->supports_device != NULL
|
if (driver->register_device != NULL) {
|
||||||
&& driver->register_device != NULL) {
|
status = driver->register_device(this);
|
||||||
float support = driver->supports_device(this);
|
|
||||||
if (support <= 0.0)
|
|
||||||
status = B_ERROR;
|
|
||||||
|
|
||||||
if (status == B_OK)
|
|
||||||
status = driver->register_device(this);
|
|
||||||
if (status == B_OK)
|
if (status == B_OK)
|
||||||
registered++;
|
registered++;
|
||||||
}
|
}
|
||||||
@@ -469,7 +561,23 @@ device_node::_RegisterDynamic()
|
|||||||
driver_module_info* bestDriver = NULL;
|
driver_module_info* bestDriver = NULL;
|
||||||
float best = 0.0;
|
float best = 0.0;
|
||||||
|
|
||||||
void* list = open_module_list_etc("bus", "driver_v1");
|
char path[64];
|
||||||
|
if (!_IsBus()) {
|
||||||
|
strlcpy(path, "drivers", sizeof(path));
|
||||||
|
|
||||||
|
const char *type;
|
||||||
|
if (dm_get_attr_string(this, B_DRIVER_DEVICE_TYPE, &type, false)
|
||||||
|
== B_OK) {
|
||||||
|
strlcat(path, "/", sizeof(path));
|
||||||
|
strlcat(path, type, sizeof(path));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// TODO: we might want to allow bus* specifiers as well, ie.
|
||||||
|
// busses/usb
|
||||||
|
strlcpy(path, "bus", sizeof(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
void* list = open_module_list_etc(path, "driver_v1");
|
||||||
while (true) {
|
while (true) {
|
||||||
char name[B_FILE_NAME_LENGTH];
|
char name[B_FILE_NAME_LENGTH];
|
||||||
size_t nameLength = sizeof(name);
|
size_t nameLength = sizeof(name);
|
||||||
@@ -525,21 +633,20 @@ printf(" register best module \"%s\", support %f\n", bestDriver->info.name, bes
|
|||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
rescan_device(device_node *node)
|
rescan_device(device_node* node)
|
||||||
{
|
{
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
register_device(device_node *parent, const char *moduleName,
|
register_device(device_node* parent, const char* moduleName,
|
||||||
const device_attr *attrs, const io_resource *ioResources,
|
const device_attr* attrs, const io_resource* ioResources,
|
||||||
device_node **_node)
|
device_node** _node)
|
||||||
{
|
{
|
||||||
if ((parent == NULL && sRootNode != NULL) || moduleName == NULL)
|
if ((parent == NULL && sRootNode != NULL) || moduleName == NULL)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
TRACE(("register device \"%s\", parent %p\n", moduleName, parent));
|
|
||||||
// TODO: handle I/O resources!
|
// TODO: handle I/O resources!
|
||||||
|
|
||||||
device_node *newNode = new(std::nothrow) device_node(moduleName, attrs,
|
device_node *newNode = new(std::nothrow) device_node(moduleName, attrs,
|
||||||
@@ -547,6 +654,9 @@ register_device(device_node *parent, const char *moduleName,
|
|||||||
if (newNode == NULL)
|
if (newNode == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
TRACE(("%p: register device \"%s\", parent %p\n", newNode, moduleName,
|
||||||
|
parent));
|
||||||
|
|
||||||
status_t status = newNode->InitCheck();
|
status_t status = newNode->InitCheck();
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
goto err1;
|
goto err1;
|
||||||
@@ -576,8 +686,10 @@ register_device(device_node *parent, const char *moduleName,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
status = newNode->Register();
|
status = newNode->Register();
|
||||||
if (status < B_OK)
|
if (status < B_OK) {
|
||||||
return status;
|
parent->RemoveChild(newNode);
|
||||||
|
goto err1;
|
||||||
|
}
|
||||||
|
|
||||||
if (_node)
|
if (_node)
|
||||||
*_node = newNode;
|
*_node = newNode;
|
||||||
@@ -591,27 +703,27 @@ err1:
|
|||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
unregister_device(device_node *node)
|
unregister_device(device_node* node)
|
||||||
{
|
{
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static driver_module_info*
|
static driver_module_info*
|
||||||
driver_module(device_node *node)
|
driver_module(device_node* node)
|
||||||
{
|
{
|
||||||
return node->DriverModule();
|
return node->DriverModule();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void*
|
static void*
|
||||||
driver_data(device_node *node)
|
driver_data(device_node* node)
|
||||||
{
|
{
|
||||||
return node->DriverData();
|
return node->DriverData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static device_node *
|
static device_node*
|
||||||
device_root(void)
|
device_root(void)
|
||||||
{
|
{
|
||||||
return sRootNode;
|
return sRootNode;
|
||||||
@@ -619,31 +731,31 @@ device_root(void)
|
|||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
get_next_child_device(device_node *parent, device_node *_node,
|
get_next_child_device(device_node* parent, device_node* _node,
|
||||||
const device_attr *attrs)
|
const device_attr* attrs)
|
||||||
{
|
{
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static device_node *
|
static device_node*
|
||||||
get_parent(device_node *node)
|
get_parent(device_node* node)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
put_device_node(device_node *node)
|
put_device_node(device_node* node)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
dm_get_attr_uint8(device_node* node, const char* name, uint8* _value,
|
dm_get_attr_uint8(const device_node* node, const char* name, uint8* _value,
|
||||||
bool recursive)
|
bool recursive)
|
||||||
{
|
{
|
||||||
if (name == NULL || _value == NULL)
|
if (node == NULL || name == NULL || _value == NULL)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
device_attr_private* attr = dm_find_attr(node, name, recursive,
|
device_attr_private* attr = dm_find_attr(node, name, recursive,
|
||||||
@@ -660,7 +772,7 @@ status_t
|
|||||||
dm_get_attr_uint16(device_node* node, const char* name, uint16* _value,
|
dm_get_attr_uint16(device_node* node, const char* name, uint16* _value,
|
||||||
bool recursive)
|
bool recursive)
|
||||||
{
|
{
|
||||||
if (name == NULL || _value == NULL)
|
if (node == NULL || name == NULL || _value == NULL)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
device_attr_private* attr = dm_find_attr(node, name, recursive,
|
device_attr_private* attr = dm_find_attr(node, name, recursive,
|
||||||
@@ -677,7 +789,7 @@ status_t
|
|||||||
dm_get_attr_uint32(device_node* node, const char* name, uint32* _value,
|
dm_get_attr_uint32(device_node* node, const char* name, uint32* _value,
|
||||||
bool recursive)
|
bool recursive)
|
||||||
{
|
{
|
||||||
if (name == NULL || _value == NULL)
|
if (node == NULL || name == NULL || _value == NULL)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
device_attr_private* attr = dm_find_attr(node, name, recursive,
|
device_attr_private* attr = dm_find_attr(node, name, recursive,
|
||||||
@@ -694,7 +806,7 @@ status_t
|
|||||||
dm_get_attr_uint64(device_node* node, const char* name,
|
dm_get_attr_uint64(device_node* node, const char* name,
|
||||||
uint64* _value, bool recursive)
|
uint64* _value, bool recursive)
|
||||||
{
|
{
|
||||||
if (name == NULL || _value == NULL)
|
if (node == NULL || name == NULL || _value == NULL)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
device_attr_private* attr = dm_find_attr(node, name, recursive,
|
device_attr_private* attr = dm_find_attr(node, name, recursive,
|
||||||
@@ -711,7 +823,7 @@ status_t
|
|||||||
dm_get_attr_string(device_node* node, const char* name, const char** _value,
|
dm_get_attr_string(device_node* node, const char* name, const char** _value,
|
||||||
bool recursive)
|
bool recursive)
|
||||||
{
|
{
|
||||||
if (name == NULL || _value == NULL)
|
if (node == NULL || name == NULL || _value == NULL)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
device_attr_private* attr = dm_find_attr(node, name, recursive,
|
device_attr_private* attr = dm_find_attr(node, name, recursive,
|
||||||
@@ -728,7 +840,7 @@ status_t
|
|||||||
dm_get_attr_raw(device_node* node, const char* name, const void** _data,
|
dm_get_attr_raw(device_node* node, const char* name, const void** _data,
|
||||||
size_t* _length, bool recursive)
|
size_t* _length, bool recursive)
|
||||||
{
|
{
|
||||||
if (name == NULL || (_data == NULL && _length == NULL))
|
if (node == NULL || name == NULL || (_data == NULL && _length == NULL))
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
device_attr_private* attr = dm_find_attr(node, name, recursive, B_RAW_TYPE);
|
device_attr_private* attr = dm_find_attr(node, name, recursive, B_RAW_TYPE);
|
||||||
@@ -746,6 +858,9 @@ dm_get_attr_raw(device_node* node, const char* name, const void** _data,
|
|||||||
status_t
|
status_t
|
||||||
dm_get_next_attr(device_node* node, device_attr** _attr)
|
dm_get_next_attr(device_node* node, device_attr** _attr)
|
||||||
{
|
{
|
||||||
|
if (node == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
device_attr_private* next;
|
device_attr_private* next;
|
||||||
device_attr_private* attr = *(device_attr_private**)_attr;
|
device_attr_private* attr = *(device_attr_private**)_attr;
|
||||||
|
|
||||||
@@ -800,6 +915,7 @@ dm_init_root_node(void)
|
|||||||
{
|
{
|
||||||
device_attr attrs[] = {
|
device_attr attrs[] = {
|
||||||
{B_DRIVER_PRETTY_NAME, B_STRING_TYPE, {string: "Devices Root"}},
|
{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_BUS, B_STRING_TYPE, {string: "root"}},
|
||||||
{B_DRIVER_FIND_CHILD_FLAGS, B_UINT32_TYPE,
|
{B_DRIVER_FIND_CHILD_FLAGS, B_UINT32_TYPE,
|
||||||
{ui32: B_FIND_MULTIPLE_CHILDREN}},
|
{ui32: B_FIND_MULTIPLE_CHILDREN}},
|
||||||
@@ -829,12 +945,12 @@ static driver_module_info sDeviceRootModule = {
|
|||||||
int
|
int
|
||||||
main(int argc, char** argv)
|
main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
_add_builtin_module((module_info *)&sDeviceManagerModule);
|
_add_builtin_module((module_info*)&sDeviceManagerModule);
|
||||||
_add_builtin_module((module_info *)&sDeviceRootModule);
|
_add_builtin_module((module_info*)&sDeviceRootModule);
|
||||||
_add_builtin_module((module_info *)&gDeviceModuleInfo);
|
_add_builtin_module((module_info*)&gDeviceModuleInfo);
|
||||||
_add_builtin_module((module_info *)&gDriverModuleInfo);
|
_add_builtin_module((module_info*)&gDriverModuleInfo);
|
||||||
_add_builtin_module((module_info *)&gBusModuleInfo);
|
_add_builtin_module((module_info*)&gBusModuleInfo);
|
||||||
_add_builtin_module((module_info *)&gBusDriverModuleInfo);
|
_add_builtin_module((module_info*)&gBusDriverModuleInfo);
|
||||||
|
|
||||||
gDeviceManager = &sDeviceManagerModule;
|
gDeviceManager = &sDeviceManagerModule;
|
||||||
|
|
||||||
@@ -846,6 +962,7 @@ main(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
dm_init_root_node();
|
dm_init_root_node();
|
||||||
|
dm_dump_node(sRootNode, 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,11 @@
|
|||||||
|
|
||||||
#include "bus.h"
|
#include "bus.h"
|
||||||
|
|
||||||
|
#include <KernelExport.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define DRIVER_MODULE_NAME "drivers/net/sample_driver/driver_v1"
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - driver
|
// #pragma mark - driver
|
||||||
|
|
||||||
@@ -13,6 +18,7 @@
|
|||||||
static float
|
static float
|
||||||
supports_device(device_node *parent)
|
supports_device(device_node *parent)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
const char* bus;
|
const char* bus;
|
||||||
if (gDeviceManager->get_attr_string(parent, B_DRIVER_BUS, &bus, false)
|
if (gDeviceManager->get_attr_string(parent, B_DRIVER_BUS, &bus, false)
|
||||||
!= B_OK)
|
!= B_OK)
|
||||||
@@ -20,9 +26,13 @@ supports_device(device_node *parent)
|
|||||||
|
|
||||||
if (bus == NULL || strcmp(bus, BUS_NAME))
|
if (bus == NULL || strcmp(bus, BUS_NAME))
|
||||||
return -1;
|
return -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bus_for_driver_module_info* module
|
||||||
|
= (bus_for_driver_module_info*)gDeviceManager->driver_module(parent);
|
||||||
|
if (strcmp(module->info.info.name, BUS_FOR_DRIVER_NAME))
|
||||||
|
return -1;
|
||||||
|
|
||||||
bus_device_module_info* module
|
|
||||||
= (bus_device_module_info*)gDeviceManager->driver_module(parent);
|
|
||||||
void* data = gDeviceManager->driver_data(parent);
|
void* data = gDeviceManager->driver_data(parent);
|
||||||
|
|
||||||
bus_info info;
|
bus_info info;
|
||||||
@@ -38,7 +48,8 @@ supports_device(device_node *parent)
|
|||||||
static status_t
|
static status_t
|
||||||
register_device(device_node *parent)
|
register_device(device_node *parent)
|
||||||
{
|
{
|
||||||
return B_ERROR;
|
return gDeviceManager->register_device(parent, DRIVER_MODULE_NAME, NULL,
|
||||||
|
NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -46,7 +57,7 @@ static status_t
|
|||||||
init_driver(device_node *node, void **_cookie)
|
init_driver(device_node *node, void **_cookie)
|
||||||
{
|
{
|
||||||
// also publishes any devices/nodes with dedicated calls
|
// also publishes any devices/nodes with dedicated calls
|
||||||
return B_ERROR;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -144,7 +155,7 @@ device_io(void *cookie, io_request *request)
|
|||||||
|
|
||||||
struct driver_module_info gDriverModuleInfo = {
|
struct driver_module_info gDriverModuleInfo = {
|
||||||
{
|
{
|
||||||
"sample_driver/driver_v1",
|
DRIVER_MODULE_NAME,
|
||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
},
|
},
|
||||||
@@ -160,7 +171,7 @@ struct driver_module_info gDriverModuleInfo = {
|
|||||||
|
|
||||||
struct device_module_info gDeviceModuleInfo = {
|
struct device_module_info gDeviceModuleInfo = {
|
||||||
{
|
{
|
||||||
"sample_driver/device_v1",
|
"drivers/net/sample_driver/device_v1",
|
||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user