From a8be7d1ea3297974cb80d1dfd700510375704c67 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Sat, 6 Jan 2007 18:10:15 +0000 Subject: [PATCH] * Added some more debug output to the hub code * Report and clear yet unhandled port changes in hubs * Fixed the way devices that vanish on port reset are handled * Added a status field to the memory allocator and check it creating it git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19732 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/add-ons/kernel/bus_managers/usb/Hub.cpp | 47 ++++++++++++++++--- .../usb/PhysicalMemoryAllocator.cpp | 4 +- .../usb/PhysicalMemoryAllocator.h | 3 ++ src/add-ons/kernel/bus_managers/usb/Stack.cpp | 3 +- 4 files changed, 48 insertions(+), 9 deletions(-) diff --git a/src/add-ons/kernel/bus_managers/usb/Hub.cpp b/src/add-ons/kernel/bus_managers/usb/Hub.cpp index c1326150d2..d87a983f0e 100644 --- a/src/add-ons/kernel/bus_managers/usb/Hub.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Hub.cpp @@ -117,12 +117,6 @@ Hub::ResetPort(uint8 index) if (result < B_OK) return result; - if ((fPortStatus[index].status & PORT_STATUS_CONNECTION) == 0) { - // device disappeared, this is no error - TRACE(("USB Hub: device disappeared on reset\n")); - return B_OK; - } - if (fPortStatus[index].change & C_PORT_RESET) { // reset is done break; @@ -151,13 +145,21 @@ void Hub::Explore() { for (int32 i = 0; i < fHubDescriptor.num_ports; i++) { + if (i >= 8) { + TRACE(("USB Hub: hub supports more ports than we do (%d)\n", fHubDescriptor.num_ports)); + fHubDescriptor.num_ports = 8; + continue; + } + status_t result = UpdatePortStatus(i); if (result < B_OK) continue; #ifdef TRACE_USB - if (fPortStatus[i].change) + if (fPortStatus[i].change) { TRACE(("USB Hub: port %d: status: 0x%04x; change: 0x%04x\n", i, fPortStatus[i].status, fPortStatus[i].change)); + TRACE(("USB Hub: device at port %d: 0x%08x\n", i, fChildren[i])); + } #endif if (fPortStatus[i].change & PORT_STATUS_CONNECTION) { @@ -184,6 +186,7 @@ Hub::Explore() if ((fPortStatus[i].status & PORT_STATUS_CONNECTION) == 0) { // device has vanished after reset, ignore + TRACE(("USB Hub: device disappeared on reset\n")); continue; } @@ -211,12 +214,42 @@ Hub::Explore() // Device removed... TRACE(("USB Hub Explore(): Device removed\n")); if (fChildren[i]) { + TRACE(("USB Hub: removing device 0x%08x\n", fChildren[i])); GetStack()->NotifyDeviceChange(fChildren[i], false); delete fChildren[i]; fChildren[i] = NULL; } } } + + // other port changes we do not really handle, report and clear them + if (fPortStatus[i].change & PORT_STATUS_ENABLE) { + TRACE_ERROR(("USB Hub Explore(): port %ld %sabled\n", i, (fPortStatus[i].status & PORT_STATUS_ENABLE) ? "en" : "dis")); + DefaultPipe()->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT, + USB_REQUEST_CLEAR_FEATURE, C_PORT_ENABLE, i + 1, + 0, NULL, 0, NULL); + } + + if (fPortStatus[i].change & PORT_STATUS_SUSPEND) { + TRACE_ERROR(("USB Hub Explore(): port %ld is %ssuspended\n", i, (fPortStatus[i].status & PORT_STATUS_SUSPEND) ? "" : "not ")); + DefaultPipe()->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT, + USB_REQUEST_CLEAR_FEATURE, C_PORT_SUSPEND, i + 1, + 0, NULL, 0, NULL); + } + + if (fPortStatus[i].change & PORT_STATUS_OVER_CURRENT) { + TRACE_ERROR(("USB Hub Explore(): port %ld is %sin an over current state\n", i, (fPortStatus[i].status & PORT_STATUS_OVER_CURRENT) ? "" : "not ")); + DefaultPipe()->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT, + USB_REQUEST_CLEAR_FEATURE, C_PORT_OVER_CURRENT, i + 1, + 0, NULL, 0, NULL); + } + + if (fPortStatus[i].change & PORT_RESET) { + TRACE_ERROR(("USB Hub Explore(): port %ld was reset\n", i)); + DefaultPipe()->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT, + USB_REQUEST_CLEAR_FEATURE, C_PORT_RESET, i + 1, + 0, NULL, 0, NULL); + } } // explore down the tree if we have hubs connected diff --git a/src/add-ons/kernel/bus_managers/usb/PhysicalMemoryAllocator.cpp b/src/add-ons/kernel/bus_managers/usb/PhysicalMemoryAllocator.cpp index 249c83a2b3..047921d6e8 100644 --- a/src/add-ons/kernel/bus_managers/usb/PhysicalMemoryAllocator.cpp +++ b/src/add-ons/kernel/bus_managers/usb/PhysicalMemoryAllocator.cpp @@ -26,7 +26,8 @@ PhysicalMemoryAllocator::PhysicalMemoryAllocator(const char *name, size_t minSize, size_t maxSize, uint32 minCountPerBlock) - : fOverhead(0) + : fOverhead(0), + fStatus(B_NO_INIT) { fName = strdup(name); if (benaphore_init(&fLock, fName) < B_OK) { @@ -84,6 +85,7 @@ PhysicalMemoryAllocator::PhysicalMemoryAllocator(const char *name, } fPhysicalBase = physicalEntry.address; + fStatus = B_OK; } diff --git a/src/add-ons/kernel/bus_managers/usb/PhysicalMemoryAllocator.h b/src/add-ons/kernel/bus_managers/usb/PhysicalMemoryAllocator.h index 4ed06bf020..9dbf8ca677 100644 --- a/src/add-ons/kernel/bus_managers/usb/PhysicalMemoryAllocator.h +++ b/src/add-ons/kernel/bus_managers/usb/PhysicalMemoryAllocator.h @@ -21,6 +21,8 @@ public: uint32 minCountPerBlock); ~PhysicalMemoryAllocator(); + status_t InitCheck() { return fStatus; }; + status_t Allocate(size_t size, void **logicalAddress, void **physicalAddress); @@ -43,6 +45,7 @@ private: size_t fOverhead; size_t fManagedMemory; + status_t fStatus; benaphore fLock; area_id fArea; diff --git a/src/add-ons/kernel/bus_managers/usb/Stack.cpp b/src/add-ons/kernel/bus_managers/usb/Stack.cpp index 7ad76fbf4a..c5469fa429 100644 --- a/src/add-ons/kernel/bus_managers/usb/Stack.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Stack.cpp @@ -36,8 +36,9 @@ Stack::Stack() fAllocator = new(std::nothrow) PhysicalMemoryAllocator("USB Stack Allocator", 8, B_PAGE_SIZE * 4, 64); - if (!fAllocator) { + if (!fAllocator || fAllocator->InitCheck() < B_OK) { TRACE_ERROR(("usb stack: failed to allocate the allocator\n")); + delete fAllocator; return; }