* device_nodes now have a priority that is used to sort them when they are
added to their parent. Currently, only the existence of B_FIND_MULTIPLE_CHILDREN influences the priority. * This makes it possible to register/probe intelligent busses earlier than simple/generic busses. * Reenabled the ISA bus manager using the new device architecture; the ide_isa driver can and will now actually work. * device_node::Probe() now sets the global sGenericContextPath for generic nodes. This causes a special handling in _GetNextDriverPath(). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25779 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -34,7 +34,7 @@
|
||||
// (for example, the Pegasos (PPC based) also has an ISA bus)
|
||||
|
||||
|
||||
#define ISA_MODULE_NAME "bus_managers/isa/root/device_v1"
|
||||
#define ISA_MODULE_NAME "bus_managers/isa/root/driver_v1"
|
||||
|
||||
device_manager_info *pnp;
|
||||
|
||||
@@ -73,75 +73,54 @@ unlock_isa_dma_channel(long channel)
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
// #pragma mark - driver module API
|
||||
|
||||
|
||||
static status_t
|
||||
isa_init_driver(device_node_handle node, void *user_cookie, void **cookie)
|
||||
isa_init_driver(device_node *node, void **cookie)
|
||||
{
|
||||
*cookie = NULL;
|
||||
*cookie = node;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
static void
|
||||
isa_uninit_driver(void *cookie)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static float
|
||||
isa_supports_device(device_node_handle parent, bool *_noConnection)
|
||||
isa_supports_device(device_node *parent)
|
||||
{
|
||||
char *bus;
|
||||
const char *bus;
|
||||
|
||||
// make sure parent is really pnp root
|
||||
if (pnp->get_attr_string(parent, B_DRIVER_BUS, &bus, false))
|
||||
if (pnp->get_attr_string(parent, B_DEVICE_BUS, &bus, false))
|
||||
return B_ERROR;
|
||||
|
||||
if (strcmp(bus, "root")) {
|
||||
free(bus);
|
||||
if (strcmp(bus, "root"))
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
free(bus);
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
isa_register_device(device_node_handle parent)
|
||||
isa_register_device(device_node *parent)
|
||||
{
|
||||
static const device_attr attrs[] = {
|
||||
// info about ourself
|
||||
{ B_DRIVER_MODULE, B_STRING_TYPE, { string: ISA_MODULE_NAME }},
|
||||
// unique connection
|
||||
{ PNP_DRIVER_CONNECTION, B_STRING_TYPE, { string: "ISA" }},
|
||||
|
||||
// mark as being a bus
|
||||
{ PNP_BUS_IS_BUS, B_UINT8_TYPE, { ui8: 1 }},
|
||||
|
||||
// tell where to look for child devices
|
||||
{ B_DRIVER_BUS, B_STRING_TYPE, { string: "isa" }},
|
||||
{ B_DRIVER_FIND_DEVICES_ON_DEMAND, B_UINT8_TYPE, { ui8: 1 }},
|
||||
{ B_DRIVER_EXPLORE_LAST, B_UINT8_TYPE, { ui8: 1 }},
|
||||
{ NULL }
|
||||
{B_DEVICE_BUS, B_STRING_TYPE, {string: "isa" }},
|
||||
{B_DEVICE_FLAGS, B_UINT32_TYPE,
|
||||
{ui32: B_FIND_CHILD_ON_DEMAND | B_FIND_MULTIPLE_CHILDREN}},
|
||||
{}
|
||||
};
|
||||
|
||||
return pnp->register_device(parent, attrs, NULL, NULL);
|
||||
return pnp->register_node(parent, ISA_MODULE_NAME, attrs, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
isa_get_paths(const char ***_bus, const char ***_device)
|
||||
{
|
||||
static const char *kBus[] = {"root", NULL};
|
||||
|
||||
*_bus = kBus;
|
||||
*_device = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static status_t
|
||||
std_ops(int32 op, ...)
|
||||
{
|
||||
@@ -185,27 +164,19 @@ static isa_module_info isa_module = {
|
||||
&unlock_isa_dma_channel
|
||||
};
|
||||
|
||||
#if 0
|
||||
static isa2_module_info isa2_module = {
|
||||
{
|
||||
{
|
||||
{
|
||||
ISA_MODULE_NAME,
|
||||
0,
|
||||
std_ops
|
||||
},
|
||||
|
||||
isa_supports_device,
|
||||
isa_register_device,
|
||||
isa_init_driver,
|
||||
isa_uninit_driver,
|
||||
NULL, // removed device
|
||||
NULL, // cleanup device
|
||||
isa_get_paths,
|
||||
ISA_MODULE_NAME,
|
||||
0,
|
||||
std_ops
|
||||
},
|
||||
|
||||
// as ISA relies on device drivers to detect their devices themselves,
|
||||
// we don't have an universal rescan method
|
||||
isa_supports_device,
|
||||
isa_register_device,
|
||||
isa_init_driver,
|
||||
isa_uninit_driver,
|
||||
NULL, // removed device
|
||||
NULL, // register child devices
|
||||
NULL, // rescan bus
|
||||
},
|
||||
@@ -218,10 +189,9 @@ static isa2_module_info isa2_module = {
|
||||
|
||||
arch_start_isa_dma,
|
||||
};
|
||||
#endif
|
||||
|
||||
module_info *modules[] = {
|
||||
(module_info *)&isa_module,
|
||||
// (module_info *)&isa2_module,
|
||||
(module_info *)&isa2_module,
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -136,6 +136,8 @@ struct device_node : DoublyLinkedListLinkImpl<device_node> {
|
||||
device_node* FindChild(const device_attr* attributes) const;
|
||||
device_node* FindChild(const char* moduleName) const;
|
||||
|
||||
int32 Priority();
|
||||
|
||||
void Dump(int32 level = 0);
|
||||
|
||||
private:
|
||||
@@ -189,6 +191,7 @@ enum node_flags {
|
||||
|
||||
static device_node *sRootNode;
|
||||
static recursive_lock sLock;
|
||||
static const char* sGenericContextPath;
|
||||
|
||||
static uint32 sDriverUpdateCycle = 1;
|
||||
|
||||
@@ -1260,7 +1263,22 @@ device_node::AddChild(device_node* node)
|
||||
// we must not be destroyed as long as we have children
|
||||
Acquire();
|
||||
node->fParent = this;
|
||||
fChildren.Add(node);
|
||||
|
||||
int32 priority = node->Priority();
|
||||
|
||||
// Enforce an order in which the children are traversed - from most
|
||||
// specific to least specific child.
|
||||
NodeList::Iterator iterator = fChildren.GetIterator();
|
||||
device_node* before = NULL;
|
||||
while (iterator.HasNext()) {
|
||||
device_node* child = iterator.Next();
|
||||
if (child->Priority() <= priority) {
|
||||
before = child;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fChildren.Insert(before, node);
|
||||
}
|
||||
|
||||
|
||||
@@ -1411,11 +1429,16 @@ device_node::_GetNextDriverPath(void*& cookie, KPath& _path)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
StackDeleter<KPath*> stackDeleter(stack);
|
||||
|
||||
bool generic = false;
|
||||
uint16 type = 0;
|
||||
uint16 subType = 0;
|
||||
uint16 interface = 0;
|
||||
get_attr_uint16(this, B_DEVICE_TYPE, &type, false);
|
||||
get_attr_uint16(this, B_DEVICE_SUB_TYPE, &subType, false);
|
||||
if (get_attr_uint16(this, B_DEVICE_TYPE, &type, false) != B_OK
|
||||
|| get_attr_uint16(this, B_DEVICE_SUB_TYPE, &subType, false)
|
||||
!= B_OK)
|
||||
generic = true;
|
||||
|
||||
get_attr_uint16(this, B_DEVICE_INTERFACE, &interface, false);
|
||||
|
||||
// TODO: maybe make this extendible via settings file?
|
||||
@@ -1475,8 +1498,19 @@ device_node::_GetNextDriverPath(void*& cookie, KPath& _path)
|
||||
if (sRootNode == this) {
|
||||
_AddPath(*stack, "busses/pci");
|
||||
_AddPath(*stack, "bus_managers");
|
||||
} else
|
||||
} else if (!generic) {
|
||||
_AddPath(*stack, "drivers");
|
||||
} else {
|
||||
// For generic drivers, we only allow busses when the
|
||||
// request is more specified
|
||||
if (sGenericContextPath != NULL
|
||||
&& (!strcmp(sGenericContextPath, "disk")
|
||||
|| !strcmp(sGenericContextPath, "ports")
|
||||
|| !strcmp(sGenericContextPath, "bus"))) {
|
||||
_AddPath(*stack, "busses");
|
||||
}
|
||||
_AddPath(*stack, "drivers", sGenericContextPath);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1758,13 +1792,17 @@ device_node::Probe(const char* devicePath, uint32 updateCycle)
|
||||
// This driver does not support types, but still wants to its
|
||||
// children explored on demand only.
|
||||
matches = true;
|
||||
sGenericContextPath = devicePath;
|
||||
}
|
||||
|
||||
if (matches) {
|
||||
fLastUpdateCycle = updateCycle;
|
||||
// This node will be probed in this update cycle
|
||||
|
||||
return _Probe();
|
||||
status = _Probe();
|
||||
|
||||
sGenericContextPath = NULL;
|
||||
return status;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
@@ -2005,6 +2043,19 @@ device_node::FindChild(const char* moduleName) const
|
||||
}
|
||||
|
||||
|
||||
/*! This returns the priority or importance of this node. Nodes with higher
|
||||
priority are registered/probed first.
|
||||
Currently, only the B_FIND_MULITPLE_CHILDREN flag alters the priority;
|
||||
it might make sense to be able to directly set the priority via an
|
||||
attribute.
|
||||
*/
|
||||
int32
|
||||
device_node::Priority()
|
||||
{
|
||||
return (fFlags & B_FIND_MULTIPLE_CHILDREN) != 0 ? 0 : 100;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
device_node::Dump(int32 level)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user