* 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 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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user