* 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:
Axel Dörfler
2008-06-03 09:13:04 +00:00
parent 7830589f02
commit 2ecef3acbe
@@ -117,6 +117,7 @@ struct device_node : DoublyLinkedListLinkImpl<device_node> {
status_t Register(device_node* parent); status_t Register(device_node* parent);
status_t Probe(const char* devicePath, uint32 updateCycle); status_t Probe(const char* devicePath, uint32 updateCycle);
status_t Reprobe();
status_t Rescan(); status_t Rescan();
bool IsRegistered() const { return fRegistered; } bool IsRegistered() const { return fRegistered; }
@@ -153,7 +154,7 @@ private:
status_t _RegisterDynamic(device_node* previous = NULL); status_t _RegisterDynamic(device_node* previous = NULL);
status_t _RemoveChildren(); status_t _RemoveChildren();
device_node* _FindCurrentChild(); device_node* _FindCurrentChild();
status_t _Rescan(); status_t _Probe();
void _ReleaseWaiting(); void _ReleaseWaiting();
device_node* fParent; device_node* fParent;
@@ -1695,7 +1696,7 @@ device_node::_FindCurrentChild()
status_t status_t
device_node::_Rescan() device_node::_Probe()
{ {
device_node* previous = NULL; device_node* previous = NULL;
@@ -1733,31 +1734,37 @@ device_node::Probe(const char* devicePath, uint32 updateCycle)
MethodDeleter<device_node, bool> uninit(this, MethodDeleter<device_node, bool> uninit(this,
&device_node::UninitDriver); &device_node::UninitDriver);
uint16 type = 0; if ((fFlags & B_FIND_CHILD_ON_DEMAND) != 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?
bool matches = false; bool matches = false;
if (!strcmp(devicePath, "disk")) { uint16 type = 0;
matches = type == PCI_mass_storage; uint16 subType = 0;
} else if (!strcmp(devicePath, "audio")) { if (get_attr_uint16(this, B_DEVICE_SUB_TYPE, &subType, false) == B_OK
matches = type == PCI_multimedia && get_attr_uint16(this, B_DEVICE_TYPE, &type, false) == B_OK) {
&& (subType == PCI_audio || subType == PCI_hd_audio); // Check if this node matches the device path
} else if (!strcmp(devicePath, "net")) { // TODO: maybe make this extendible via settings file?
matches = type == PCI_network; if (!strcmp(devicePath, "disk")) {
} else if (!strcmp(devicePath, "graphics")) { matches = type == PCI_mass_storage;
matches = type == PCI_display; } else if (!strcmp(devicePath, "audio")) {
} else if (!strcmp(devicePath, "video")) { matches = type == PCI_multimedia
matches = type == PCI_multimedia && subType == PCI_video; && (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) { if (matches) {
fLastUpdateCycle = updateCycle; fLastUpdateCycle = updateCycle;
// This node will be probed in this update cycle // This node will be probed in this update cycle
return _Rescan(); return _Probe();
} }
return B_OK; return B_OK;
@@ -1777,13 +1784,49 @@ device_node::Probe(const char* devicePath, uint32 updateCycle)
status_t 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 // If this child has been probed already, probe it again
status_t status = _Rescan(); status = _Probe();
if (status != B_OK) if (status != B_OK)
return status; 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(); NodeList::Iterator iterator = fChildren.GetIterator();
while (iterator.HasNext()) { while (iterator.HasNext()) {
device_node* child = iterator.Next(); device_node* child = iterator.Next();
@@ -2062,6 +2105,7 @@ device_manager_init(struct kernel_args* args)
status_t status_t
device_manager_init_post_modules(struct kernel_args* args) device_manager_init_post_modules(struct kernel_args* args)
{ {
return sRootNode->Rescan(); RecursiveLocker _(sLock);
return sRootNode->Reprobe();
} }