예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
void
device_node::_ReleaseWaiting()
{
	NodeList::Iterator iterator = fChildren.GetIterator();
	while (iterator.HasNext()) {
		device_node* child = iterator.Next();

		child->fFlags &= ~NODE_FLAG_WAITING_FOR_DRIVER;
	}
}
예제 #4
0
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;
}
예제 #5
0
	PackageNode* _LookupChild(const char* name, size_t nameLength)
	{
		for (NodeList::Iterator it = fEntries.GetIterator();
				PackageNode* child = it.Next();) {
			if (strncmp(child->Name(), name, nameLength) == 0
				&& child->Name()[nameLength] == '\0') {
				return child;
			}
		}

		return NULL;
	}
예제 #6
0
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;
}
예제 #7
0
/*!	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();
}
예제 #8
0
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);
}
예제 #9
0
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;
}