* As Korli pointed out, I got a bit confused with Rescan() vs. Probe().
* Therefore, device_manager::rescan_node() now actually causes the driver::rescan_child_devices() function to be called, instead of probing again. * Added a device_node::Reprobe() method that does what Rescan() did previously. * Probe() should now also work with "dumb" busses that don't support type information - it will now probe all of these nodes. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25778 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -117,6 +117,7 @@ struct device_node : DoublyLinkedListLinkImpl<device_node> {
|
||||
|
||||
status_t Register(device_node* parent);
|
||||
status_t Probe(const char* devicePath, uint32 updateCycle);
|
||||
status_t Reprobe();
|
||||
status_t Rescan();
|
||||
|
||||
bool IsRegistered() const { return fRegistered; }
|
||||
@@ -153,7 +154,7 @@ private:
|
||||
status_t _RegisterDynamic(device_node* previous = NULL);
|
||||
status_t _RemoveChildren();
|
||||
device_node* _FindCurrentChild();
|
||||
status_t _Rescan();
|
||||
status_t _Probe();
|
||||
void _ReleaseWaiting();
|
||||
|
||||
device_node* fParent;
|
||||
@@ -1695,7 +1696,7 @@ device_node::_FindCurrentChild()
|
||||
|
||||
|
||||
status_t
|
||||
device_node::_Rescan()
|
||||
device_node::_Probe()
|
||||
{
|
||||
device_node* previous = NULL;
|
||||
|
||||
@@ -1733,31 +1734,37 @@ device_node::Probe(const char* devicePath, uint32 updateCycle)
|
||||
MethodDeleter<device_node, bool> uninit(this,
|
||||
&device_node::UninitDriver);
|
||||
|
||||
uint16 type = 0;
|
||||
uint16 subType = 0;
|
||||
if (get_attr_uint16(this, B_DEVICE_TYPE, &type, false) == B_OK
|
||||
&& get_attr_uint16(this, B_DEVICE_SUB_TYPE, &subType, false) == B_OK) {
|
||||
// Check if this node matches the device path
|
||||
// TODO: maybe make this extendible via settings file?
|
||||
if ((fFlags & B_FIND_CHILD_ON_DEMAND) != 0) {
|
||||
bool matches = false;
|
||||
if (!strcmp(devicePath, "disk")) {
|
||||
matches = type == PCI_mass_storage;
|
||||
} else if (!strcmp(devicePath, "audio")) {
|
||||
matches = type == PCI_multimedia
|
||||
&& (subType == PCI_audio || subType == PCI_hd_audio);
|
||||
} else if (!strcmp(devicePath, "net")) {
|
||||
matches = type == PCI_network;
|
||||
} else if (!strcmp(devicePath, "graphics")) {
|
||||
matches = type == PCI_display;
|
||||
} else if (!strcmp(devicePath, "video")) {
|
||||
matches = type == PCI_multimedia && subType == PCI_video;
|
||||
uint16 type = 0;
|
||||
uint16 subType = 0;
|
||||
if (get_attr_uint16(this, B_DEVICE_SUB_TYPE, &subType, false) == B_OK
|
||||
&& get_attr_uint16(this, B_DEVICE_TYPE, &type, false) == B_OK) {
|
||||
// Check if this node matches the device path
|
||||
// TODO: maybe make this extendible via settings file?
|
||||
if (!strcmp(devicePath, "disk")) {
|
||||
matches = type == PCI_mass_storage;
|
||||
} else if (!strcmp(devicePath, "audio")) {
|
||||
matches = type == PCI_multimedia
|
||||
&& (subType == PCI_audio || subType == PCI_hd_audio);
|
||||
} else if (!strcmp(devicePath, "net")) {
|
||||
matches = type == PCI_network;
|
||||
} else if (!strcmp(devicePath, "graphics")) {
|
||||
matches = type == PCI_display;
|
||||
} else if (!strcmp(devicePath, "video")) {
|
||||
matches = type == PCI_multimedia && subType == PCI_video;
|
||||
}
|
||||
} else {
|
||||
// This driver does not support types, but still wants to its
|
||||
// children explored on demand only.
|
||||
matches = true;
|
||||
}
|
||||
|
||||
if (matches) {
|
||||
fLastUpdateCycle = updateCycle;
|
||||
// This node will be probed in this update cycle
|
||||
|
||||
return _Rescan();
|
||||
return _Probe();
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
@@ -1777,13 +1784,49 @@ device_node::Probe(const char* devicePath, uint32 updateCycle)
|
||||
|
||||
|
||||
status_t
|
||||
device_node::Rescan()
|
||||
device_node::Reprobe()
|
||||
{
|
||||
status_t status = InitDriver();
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
MethodDeleter<device_node, bool> uninit(this,
|
||||
&device_node::UninitDriver);
|
||||
|
||||
// If this child has been probed already, probe it again
|
||||
status_t status = _Rescan();
|
||||
status = _Probe();
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
NodeList::Iterator iterator = fChildren.GetIterator();
|
||||
while (iterator.HasNext()) {
|
||||
device_node* child = iterator.Next();
|
||||
|
||||
status = child->Reprobe();
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
device_node::Rescan()
|
||||
{
|
||||
status_t status = InitDriver();
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
MethodDeleter<device_node, bool> uninit(this,
|
||||
&device_node::UninitDriver);
|
||||
|
||||
if (DriverModule()->rescan_child_devices != NULL) {
|
||||
status = DriverModule()->rescan_child_devices(DriverData());
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
}
|
||||
|
||||
NodeList::Iterator iterator = fChildren.GetIterator();
|
||||
while (iterator.HasNext()) {
|
||||
device_node* child = iterator.Next();
|
||||
@@ -2062,6 +2105,7 @@ device_manager_init(struct kernel_args* args)
|
||||
status_t
|
||||
device_manager_init_post_modules(struct kernel_args* args)
|
||||
{
|
||||
return sRootNode->Rescan();
|
||||
RecursiveLocker _(sLock);
|
||||
return sRootNode->Reprobe();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user