status_t 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 = _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(); status = child->Rescan(); if (status != B_OK) return status; } return B_OK; }
void device_node::_ReleaseWaiting() { NodeList::Iterator iterator = fChildren.GetIterator(); while (iterator.HasNext()) { device_node* child = iterator.Next(); child->fFlags &= ~NODE_FLAG_WAITING_FOR_DRIVER; } }
status_t device_node::_RemoveChildren() { NodeList::Iterator iterator = fChildren.GetIterator(); while (iterator.HasNext()) { device_node* child = iterator.Next(); child->Release(); } return fChildren.IsEmpty() ? B_OK : B_BUSY; }
device_node* device_node::_FindCurrentChild() { NodeList::Iterator iterator = fChildren.GetIterator(); while (iterator.HasNext()) { device_node* child = iterator.Next(); if ((child->Flags() & NODE_FLAG_WAITING_FOR_DRIVER) == 0) return child; } return NULL; }
/*! Uninitializes all temporary references to the driver. The registration process keeps the driver initialized to optimize the startup procedure; this function gives this reference away again. */ void device_node::UninitUnusedDriver() { // First, we need to go to the leaf, and go back from there NodeList::Iterator iterator = fChildren.GetIterator(); while (iterator.HasNext()) { device_node* child = iterator.Next(); child->UninitUnusedDriver(); } if (!IsInitialized() || (fFlags & NODE_FLAG_REGISTER_INITIALIZED) == 0) return; fFlags &= ~NODE_FLAG_REGISTER_INITIALIZED; UninitDriver(); }
void device_node::AddChild(device_node* node) { // we must not be destroyed as long as we have children Acquire(); node->fParent = this; 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); }
status_t device_node::Probe(const char* devicePath, uint32 updateCycle) { if ((fFlags & NODE_FLAG_DEVICE_REMOVED) != 0 || updateCycle == fLastUpdateCycle) return B_OK; status_t status = InitDriver(); if (status < B_OK) return status; MethodDeleter<device_node, bool> uninit(this, &device_node::UninitDriver); if ((fFlags & B_FIND_CHILD_ON_DEMAND) != 0) { bool matches = false; 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; sGenericContextPath = devicePath; } if (matches) { fLastUpdateCycle = updateCycle; // This node will be probed in this update cycle status = _Probe(); sGenericContextPath = NULL; return status; } return B_OK; } NodeList::Iterator iterator = fChildren.GetIterator(); while (iterator.HasNext()) { device_node* child = iterator.Next(); status = child->Probe(devicePath, updateCycle); if (status != B_OK) return status; } return B_OK; }