* Moved and unified the explore threads from the BusManager to the Stack

Now there is only one explore thread instead of one per BusManager.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18981 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz 2006-09-29 19:33:03 +00:00
parent 50b6109c5f
commit 4e9efbcf24
3 changed files with 69 additions and 46 deletions

View File

@ -12,8 +12,7 @@
BusManager::BusManager(Stack *stack)
: fInitOK(false),
fRootHub(NULL),
fExploreThread(-1)
fRootHub(NULL)
{
if (benaphore_init(&fLock, "usb busmanager lock") < B_OK) {
TRACE_ERROR(("usb BusManager: failed to create busmanager lock\n"));
@ -73,27 +72,6 @@ BusManager::Unlock()
}
/*
This is the 'main' function of the explore thread, which keeps track of
the hub states.
*/
int32
BusManager::ExploreThread(void *data)
{
Hub *rootHub = (Hub *)data;
if (!rootHub)
return B_ERROR;
snooze(USB_DELAY_FIRST_EXPLORE);
while (true) {
rootHub->Explore();
snooze(USB_DELAY_HUB_EXPLORE);
}
return B_OK;
}
int8
BusManager::AllocateAddress()
{
@ -229,23 +207,13 @@ BusManager::AllocateNewDevice(Hub *parent, usb_speed speed)
status_t
BusManager::Start()
{
TRACE(("usb BusManager::Start()\n"));
if (InitCheck() != B_OK)
return InitCheck();
if (fExploreThread < 0) {
fExploreThread = spawn_kernel_thread(ExploreThread,
"usb busmanager explore", B_LOW_PRIORITY, (void *)fRootHub);
}
return resume_thread(fExploreThread);
return B_OK;
}
status_t
BusManager::Stop()
{
// ToDo: implement (should end the explore thread)
return B_OK;
}

View File

@ -15,7 +15,10 @@
Stack::Stack()
: fObjectIndex(1),
: fExploreThread(-1),
fFirstExploreDone(false),
fStopThreads(false),
fObjectIndex(1),
fObjectMaxCount(1024),
fObjectArray(NULL),
fDriverList(NULL)
@ -58,13 +61,33 @@ Stack::Stack()
TRACE(("usb stack: module %s successfully loaded\n", moduleName));
}
if (fBusManagers.Count() == 0)
if (fBusManagers.Count() == 0) {
TRACE_ERROR(("usb stack: no bus managers available\n"));
return;
}
if (benaphore_init(&fExploreLock, "usb explore lock") < B_OK) {
TRACE_ERROR(("usb stack: failed to create benaphore explore lock\n"));
return;
}
fExploreThread = spawn_kernel_thread(ExploreThread, "usb explore",
B_LOW_PRIORITY, this);
resume_thread(fExploreThread);
// wait for the first explore to complete
// this ensures that we get all initial devices under InstallNotify
while (!fFirstExploreDone)
snooze(1000);
}
Stack::~Stack()
{
int32 result;
fStopThreads = true;
wait_for_thread(fExploreThread, &result);
Lock();
benaphore_destroy(&fLock);
@ -157,6 +180,30 @@ Stack::GetObject(usb_id id)
}
int32
Stack::ExploreThread(void *data)
{
Stack *stack = (Stack *)data;
while (!stack->fStopThreads) {
if (benaphore_lock(&stack->fExploreLock) != B_OK)
continue;
for (int32 i = 0; i < stack->fBusManagers.Count(); i++) {
Hub *rootHub = stack->fBusManagers.ElementAt(i)->GetRootHub();
if (rootHub)
rootHub->Explore();
}
stack->fFirstExploreDone = true;
benaphore_unlock(&stack->fExploreLock);
snooze(USB_DELAY_HUB_EXPLORE);
}
return B_OK;
}
void
Stack::AddBusManager(BusManager *busManager)
{
@ -300,13 +347,15 @@ Stack::InstallNotify(const char *driverName, const usb_notify_hooks *hooks)
usb_driver_info *element = fDriverList;
while (element) {
if (strcmp(element->driver_name, driverName) == 0) {
// ensure that no devices are added/removed while we are
// reporting devices
if (benaphore_lock(&fExploreLock) != B_OK)
return B_ERROR;
// inform driver about any already present devices
for (int32 i = 0; i < fBusManagers.Count(); i++) {
Hub *rootHub = fBusManagers.ElementAt(i)->GetRootHub();
if (rootHub) {
// Ensure that all devices are already recognized
rootHub->Explore();
// Report device will recurse down the whole tree
rootHub->ReportDevice(element->support_descriptors,
element->support_descriptor_count, hooks,
@ -316,6 +365,7 @@ Stack::InstallNotify(const char *driverName, const usb_notify_hooks *hooks)
element->notify_hooks.device_added = hooks->device_added;
element->notify_hooks.device_removed = hooks->device_removed;
benaphore_unlock(&fExploreLock);
return B_OK;
}
@ -330,12 +380,15 @@ status_t
Stack::UninstallNotify(const char *driverName)
{
TRACE(("usb stack: uninstalling notify hooks for driver \"%s\"\n", driverName));
if (!Lock())
return B_ERROR;
usb_driver_info *element = fDriverList;
while (element) {
if (strcmp(element->driver_name, driverName) == 0) {
// ensure that no devices are added/removed while we are
// reporting devices
if (benaphore_lock(&fExploreLock) != B_OK)
return B_ERROR;
// trigger the device removed hook
for (int32 i = 0; i < fBusManagers.Count(); i++) {
Hub *rootHub = fBusManagers.ElementAt(i)->GetRootHub();
@ -347,13 +400,12 @@ Stack::UninstallNotify(const char *driverName)
element->notify_hooks.device_added = NULL;
element->notify_hooks.device_removed = NULL;
Unlock();
benaphore_unlock(&fExploreLock);
return B_OK;
}
element = element->link;
}
Unlock();
return B_NAME_NOT_FOUND;
}

View File

@ -127,9 +127,15 @@ public:
status_t UninstallNotify(const char *driverName);
private:
static int32 ExploreThread(void *data);
Vector<BusManager *> fBusManagers;
thread_id fExploreThread;
bool fFirstExploreDone;
bool fStopThreads;
benaphore fLock;
benaphore fExploreLock;
PhysicalMemoryAllocator *fAllocator;
uint32 fObjectIndex;
@ -176,13 +182,10 @@ protected:
bool fInitOK;
private:
static int32 ExploreThread(void *data);
benaphore fLock;
bool fDeviceMap[128];
ControlPipe *fDefaultPipes[USB_SPEED_MAX + 1];
Hub *fRootHub;
thread_id fExploreThread;
Object *fRootObject;
};