* 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
@@ -12,8 +12,7 @@
BusManager::BusManager(Stack *stack) BusManager::BusManager(Stack *stack)
: fInitOK(false), : fInitOK(false),
fRootHub(NULL), fRootHub(NULL)
fExploreThread(-1)
{ {
if (benaphore_init(&fLock, "usb busmanager lock") < B_OK) { if (benaphore_init(&fLock, "usb busmanager lock") < B_OK) {
TRACE_ERROR(("usb BusManager: failed to create busmanager lock\n")); 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 int8
BusManager::AllocateAddress() BusManager::AllocateAddress()
{ {
@@ -229,23 +207,13 @@ BusManager::AllocateNewDevice(Hub *parent, usb_speed speed)
status_t status_t
BusManager::Start() BusManager::Start()
{ {
TRACE(("usb BusManager::Start()\n")); return B_OK;
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);
} }
status_t status_t
BusManager::Stop() BusManager::Stop()
{ {
// ToDo: implement (should end the explore thread)
return B_OK; return B_OK;
} }
+61 -9
View File
@@ -15,7 +15,10 @@
Stack::Stack() Stack::Stack()
: fObjectIndex(1), : fExploreThread(-1),
fFirstExploreDone(false),
fStopThreads(false),
fObjectIndex(1),
fObjectMaxCount(1024), fObjectMaxCount(1024),
fObjectArray(NULL), fObjectArray(NULL),
fDriverList(NULL) fDriverList(NULL)
@@ -58,13 +61,33 @@ Stack::Stack()
TRACE(("usb stack: module %s successfully loaded\n", moduleName)); 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; 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() Stack::~Stack()
{ {
int32 result;
fStopThreads = true;
wait_for_thread(fExploreThread, &result);
Lock(); Lock();
benaphore_destroy(&fLock); 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 void
Stack::AddBusManager(BusManager *busManager) Stack::AddBusManager(BusManager *busManager)
{ {
@@ -300,13 +347,15 @@ Stack::InstallNotify(const char *driverName, const usb_notify_hooks *hooks)
usb_driver_info *element = fDriverList; usb_driver_info *element = fDriverList;
while (element) { while (element) {
if (strcmp(element->driver_name, driverName) == 0) { 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 // inform driver about any already present devices
for (int32 i = 0; i < fBusManagers.Count(); i++) { for (int32 i = 0; i < fBusManagers.Count(); i++) {
Hub *rootHub = fBusManagers.ElementAt(i)->GetRootHub(); Hub *rootHub = fBusManagers.ElementAt(i)->GetRootHub();
if (rootHub) { if (rootHub) {
// Ensure that all devices are already recognized
rootHub->Explore();
// Report device will recurse down the whole tree // Report device will recurse down the whole tree
rootHub->ReportDevice(element->support_descriptors, rootHub->ReportDevice(element->support_descriptors,
element->support_descriptor_count, hooks, 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_added = hooks->device_added;
element->notify_hooks.device_removed = hooks->device_removed; element->notify_hooks.device_removed = hooks->device_removed;
benaphore_unlock(&fExploreLock);
return B_OK; return B_OK;
} }
@@ -330,12 +380,15 @@ status_t
Stack::UninstallNotify(const char *driverName) Stack::UninstallNotify(const char *driverName)
{ {
TRACE(("usb stack: uninstalling notify hooks for driver \"%s\"\n", driverName)); TRACE(("usb stack: uninstalling notify hooks for driver \"%s\"\n", driverName));
if (!Lock())
return B_ERROR;
usb_driver_info *element = fDriverList; usb_driver_info *element = fDriverList;
while (element) { while (element) {
if (strcmp(element->driver_name, driverName) == 0) { 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 // trigger the device removed hook
for (int32 i = 0; i < fBusManagers.Count(); i++) { for (int32 i = 0; i < fBusManagers.Count(); i++) {
Hub *rootHub = fBusManagers.ElementAt(i)->GetRootHub(); 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_added = NULL;
element->notify_hooks.device_removed = NULL; element->notify_hooks.device_removed = NULL;
Unlock(); benaphore_unlock(&fExploreLock);
return B_OK; return B_OK;
} }
element = element->link; element = element->link;
} }
Unlock();
return B_NAME_NOT_FOUND; return B_NAME_NOT_FOUND;
} }
+6 -3
View File
@@ -127,9 +127,15 @@ public:
status_t UninstallNotify(const char *driverName); status_t UninstallNotify(const char *driverName);
private: private:
static int32 ExploreThread(void *data);
Vector<BusManager *> fBusManagers; Vector<BusManager *> fBusManagers;
thread_id fExploreThread;
bool fFirstExploreDone;
bool fStopThreads;
benaphore fLock; benaphore fLock;
benaphore fExploreLock;
PhysicalMemoryAllocator *fAllocator; PhysicalMemoryAllocator *fAllocator;
uint32 fObjectIndex; uint32 fObjectIndex;
@@ -176,13 +182,10 @@ protected:
bool fInitOK; bool fInitOK;
private: private:
static int32 ExploreThread(void *data);
benaphore fLock; benaphore fLock;
bool fDeviceMap[128]; bool fDeviceMap[128];
ControlPipe *fDefaultPipes[USB_SPEED_MAX + 1]; ControlPipe *fDefaultPipes[USB_SPEED_MAX + 1];
Hub *fRootHub; Hub *fRootHub;
thread_id fExploreThread;
Object *fRootObject; Object *fRootObject;
}; };