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