From 8fedfdfcf8f931cd52a6e934a5b4e0aca565cf99 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Wed, 30 Aug 2006 17:59:23 +0000 Subject: [PATCH] * Rewrote some stack internals (again). Everything is now created using a parent object that shares the BusManager and Stack information to reduce individual constructors. * Don't inherit Device and Interface from pipes anymore. The device has a default pipe member now. * Since the parent of each Object is now known, we can send control messages using the default pipe of the device from all attached elements (pipes and interfaces). * Fixed the generic {Set|Clear}Feature() and GetStatus() calls to include the endpoint address for pipe specific requests. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18710 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/bus_managers/usb/BusManager.cpp | 67 +++++----- .../kernel/bus_managers/usb/Device.cpp | 59 ++++---- src/add-ons/kernel/bus_managers/usb/Hub.cpp | 25 ++-- .../kernel/bus_managers/usb/Interface.cpp | 10 +- .../kernel/bus_managers/usb/Object.cpp | 49 ++++++- src/add-ons/kernel/bus_managers/usb/Pipe.cpp | 126 +++++++++--------- src/add-ons/kernel/bus_managers/usb/usb.cpp | 21 +-- src/add-ons/kernel/bus_managers/usb/usb_p.h | 80 ++++++----- src/add-ons/kernel/busses/usb/ehci.cpp | 2 +- src/add-ons/kernel/busses/usb/ehci.h | 3 +- src/add-ons/kernel/busses/usb/ehci_rh.cpp | 21 ++- src/add-ons/kernel/busses/usb/ohci_rh.cpp | 2 +- src/add-ons/kernel/busses/usb/uhci.cpp | 2 +- src/add-ons/kernel/busses/usb/uhci.h | 3 +- src/add-ons/kernel/busses/usb/uhci_rh.cpp | 15 ++- 15 files changed, 275 insertions(+), 210 deletions(-) diff --git a/src/add-ons/kernel/bus_managers/usb/BusManager.cpp b/src/add-ons/kernel/bus_managers/usb/BusManager.cpp index 5e4cf364b1..5f696cb51c 100644 --- a/src/add-ons/kernel/bus_managers/usb/BusManager.cpp +++ b/src/add-ons/kernel/bus_managers/usb/BusManager.cpp @@ -15,7 +15,6 @@ BusManager::BusManager(Stack *stack) fDefaultPipe(NULL), fDefaultPipeLowSpeed(NULL), fRootHub(NULL), - fStack(stack), fExploreThread(-1) { if (benaphore_init(&fLock, "usb busmanager lock") < B_OK) { @@ -23,16 +22,22 @@ BusManager::BusManager(Stack *stack) return; } + fRootObject = new(std::nothrow) Object(stack, this); + if (!fRootObject) + return; + // Clear the device map for (int32 i = 0; i < 128; i++) fDeviceMap[i] = false; // Set up the default pipes - fDefaultPipe = new(std::nothrow) ControlPipe(this, 0, Pipe::FullSpeed, 0, 8); + fDefaultPipe = new(std::nothrow) ControlPipe(fRootObject, 0, 0, + Pipe::FullSpeed, 8); if (!fDefaultPipe) return; - fDefaultPipeLowSpeed = new(std::nothrow) ControlPipe(this, 0, Pipe::LowSpeed, 0, 8); + fDefaultPipeLowSpeed = new(std::nothrow) ControlPipe(fRootObject, 0, 0, + Pipe::LowSpeed, 8); if (!fDefaultPipeLowSpeed) return; @@ -92,8 +97,28 @@ BusManager::ExploreThread(void *data) } +int8 +BusManager::AllocateAddress() +{ + if (!Lock()) + return -1; + + int8 deviceAddress = -1; + for (int32 i = 1; i < 128; i++) { + if (fDeviceMap[i] == false) { + deviceAddress = i; + fDeviceMap[i] = true; + break; + } + } + + Unlock(); + return deviceAddress; +} + + Device * -BusManager::AllocateNewDevice(Device *parent, bool lowSpeed) +BusManager::AllocateNewDevice(Hub *parent, bool lowSpeed) { // Check if there is a free entry in the device map (for the device number) int8 deviceAddress = AllocateAddress(); @@ -103,7 +128,6 @@ BusManager::AllocateNewDevice(Device *parent, bool lowSpeed) } TRACE(("usb BusManager::AllocateNewDevice(): setting device address to %d\n", deviceAddress)); - ControlPipe *defaultPipe = (lowSpeed ? fDefaultPipeLowSpeed : fDefaultPipe); status_t result = B_ERROR; @@ -134,8 +158,8 @@ BusManager::AllocateNewDevice(Device *parent, bool lowSpeed) snooze(USB_DELAY_SET_ADDRESS); // Create a temporary pipe with the new address - ControlPipe pipe(this, deviceAddress, - lowSpeed ? Pipe::LowSpeed : Pipe::FullSpeed, 0, 8); + ControlPipe pipe(parent, deviceAddress, 0, + lowSpeed ? Pipe::LowSpeed : Pipe::FullSpeed, 8); // Get the device descriptor // Just retrieve the first 8 bytes of the descriptor -> minimum supported @@ -172,7 +196,7 @@ BusManager::AllocateNewDevice(Device *parent, bool lowSpeed) // Create a new instance based on the type (Hub or Device) if (deviceDescriptor.device_class == 0x09) { TRACE(("usb BusManager::AllocateNewDevice(): creating new hub\n")); - Hub *hub = new(std::nothrow) Hub(this, parent, deviceDescriptor, + Hub *hub = new(std::nothrow) Hub(parent, deviceDescriptor, deviceAddress, lowSpeed); if (!hub) { TRACE_ERROR(("usb BusManager::AllocateNewDevice(): no memory to allocate hub\n")); @@ -185,16 +209,11 @@ BusManager::AllocateNewDevice(Device *parent, bool lowSpeed) return NULL; } - if (parent == NULL) { - // root hub - fRootHub = hub; - } - return (Device *)hub; } TRACE(("usb BusManager::AllocateNewDevice(): creating new device\n")); - Device *device = new(std::nothrow) Device(this, parent, deviceDescriptor, + Device *device = new(std::nothrow) Device(parent, deviceDescriptor, deviceAddress, lowSpeed); if (!device) { TRACE_ERROR(("usb BusManager::AllocateNewDevice(): no memory to allocate device\n")); @@ -211,26 +230,6 @@ BusManager::AllocateNewDevice(Device *parent, bool lowSpeed) } -int8 -BusManager::AllocateAddress() -{ - if (!Lock()) - return -1; - - int8 deviceAddress = -1; - for (int32 i = 1; i < 128; i++) { - if (fDeviceMap[i] == false) { - deviceAddress = i; - fDeviceMap[i] = true; - break; - } - } - - Unlock(); - return deviceAddress; -} - - status_t BusManager::Start() { diff --git a/src/add-ons/kernel/bus_managers/usb/Device.cpp b/src/add-ons/kernel/bus_managers/usb/Device.cpp index 3c489443ec..cff1f91ac9 100644 --- a/src/add-ons/kernel/bus_managers/usb/Device.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Device.cpp @@ -10,17 +10,14 @@ #include "usb_p.h" -Device::Device(BusManager *bus, Device *parent, usb_device_descriptor &desc, - int8 deviceAddress, bool lowSpeed) - : ControlPipe(bus, deviceAddress, - lowSpeed ? Pipe::LowSpeed : Pipe::FullSpeed, 0, - desc.max_packet_size_0), +Device::Device(Object *parent, usb_device_descriptor &desc, int8 deviceAddress, + bool lowSpeed) + : Object(parent), fDeviceDescriptor(desc), + fInitOK(false), fConfigurations(NULL), fCurrentConfiguration(NULL), - fInitOK(false), fLowSpeed(lowSpeed), - fParent(parent), fDeviceAddress(deviceAddress), fLock(-1), fNotifyCookie(NULL) @@ -35,6 +32,14 @@ Device::Device(BusManager *bus, Device *parent, usb_device_descriptor &desc, set_sem_owner(fLock, B_SYSTEM_TEAM); + fDefaultPipe = new(std::nothrow) ControlPipe(this, deviceAddress, 0, + fLowSpeed ? Pipe::LowSpeed : Pipe::FullSpeed, + fDeviceDescriptor.max_packet_size_0); + if (!fDefaultPipe) { + TRACE_ERROR(("USB Device: could not allocate default pipe\n")); + return; + } + fMaxPacketIn[0] = fMaxPacketOut[0] = fDeviceDescriptor.max_packet_size_0; // Get the device descriptor @@ -146,8 +151,7 @@ Device::Device(BusManager *bus, Device *parent, usb_device_descriptor &desc, interfaceInfo->generic_count = 0; interfaceInfo->generic = NULL; - Interface *interface = new(std::nothrow) Interface(GetBusManager(), - fDeviceAddress, Speed()); + Interface *interface = new(std::nothrow) Interface(this); interfaceInfo->handle = interface->USBID(); currentInterface = interfaceInfo; @@ -182,36 +186,37 @@ Device::Device(BusManager *bus, Device *parent, usb_device_descriptor &desc, Pipe *endpoint = NULL; switch (endpointDescriptor->attributes & 0x03) { case 0x00: /* Control Endpoint */ - endpoint = new(std::nothrow) ControlPipe(GetBusManager(), - fDeviceAddress, Speed(), + endpoint = new(std::nothrow) ControlPipe(this, + fDeviceAddress, endpointDescriptor->endpoint_address & 0x0f, + fLowSpeed ? Pipe::LowSpeed : Pipe::FullSpeed, endpointDescriptor->max_packet_size); break; case 0x01: /* Isochronous Endpoint */ - endpoint = new(std::nothrow) IsochronousPipe(GetBusManager(), + endpoint = new(std::nothrow) IsochronousPipe(this, fDeviceAddress, - endpointDescriptor->endpoint_address & 0x80 > 0 ? Pipe::In : Pipe::Out, - Speed(), endpointDescriptor->endpoint_address & 0x0f, + (endpointDescriptor->endpoint_address & 0x80) > 0 ? Pipe::In : Pipe::Out, + fLowSpeed ? Pipe::LowSpeed : Pipe::FullSpeed, endpointDescriptor->max_packet_size); break; case 0x02: /* Bulk Endpoint */ - endpoint = new(std::nothrow) BulkPipe(GetBusManager(), + endpoint = new(std::nothrow) BulkPipe(this, fDeviceAddress, - endpointDescriptor->endpoint_address & 0x80 > 0 ? Pipe::In : Pipe::Out, - Speed(), endpointDescriptor->endpoint_address & 0x0f, + (endpointDescriptor->endpoint_address & 0x80) > 0 ? Pipe::In : Pipe::Out, + fLowSpeed ? Pipe::LowSpeed : Pipe::FullSpeed, endpointDescriptor->max_packet_size); break; case 0x03: /* Interrupt Endpoint */ - endpoint = new(std::nothrow) InterruptPipe(GetBusManager(), + endpoint = new(std::nothrow) InterruptPipe(this, fDeviceAddress, - endpointDescriptor->endpoint_address & 0x80 > 0 ? Pipe::In : Pipe::Out, - Speed(), endpointDescriptor->endpoint_address & 0x0f, + (endpointDescriptor->endpoint_address & 0x80) > 0 ? Pipe::In : Pipe::Out, + fLowSpeed ? Pipe::LowSpeed : Pipe::FullSpeed, endpointDescriptor->max_packet_size); break; } @@ -271,7 +276,7 @@ status_t Device::GetDescriptor(uint8 descriptorType, uint8 index, uint16 languageID, void *data, size_t dataLength, size_t *actualLength) { - return SendRequest( + return fDefaultPipe->SendRequest( USB_REQTYPE_DEVICE_IN | USB_REQTYPE_STANDARD, // type USB_REQUEST_GET_DESCRIPTOR, // request (descriptorType << 8) | index, // value @@ -318,7 +323,7 @@ Device::SetConfigurationAt(uint8 index) if (index >= fDeviceDescriptor.num_configurations) return B_BAD_VALUE; - status_t result = SendRequest( + status_t result = fDefaultPipe->SendRequest( USB_REQTYPE_DEVICE_OUT | USB_REQTYPE_STANDARD, // type USB_REQUEST_SET_CONFIGURATION, // request fConfigurations[index].descr->configuration_value, // value @@ -410,10 +415,10 @@ status_t Device::BuildDeviceName(char *string, uint32 *index, size_t bufferSize, Device *device) { - if (!fParent) + if (!Parent() || (Parent()->Type() & USB_OBJECT_HUB) == 0) return B_ERROR; - fParent->BuildDeviceName(string, index, bufferSize, this); + ((Hub *)Parent())->BuildDeviceName(string, index, bufferSize, this); return B_OK; } @@ -421,7 +426,7 @@ Device::BuildDeviceName(char *string, uint32 *index, size_t bufferSize, status_t Device::SetFeature(uint16 selector) { - return SendRequest( + return fDefaultPipe->SendRequest( USB_REQTYPE_STANDARD | USB_REQTYPE_DEVICE_OUT, USB_REQUEST_SET_FEATURE, selector, @@ -436,7 +441,7 @@ Device::SetFeature(uint16 selector) status_t Device::ClearFeature(uint16 selector) { - return SendRequest( + return fDefaultPipe->SendRequest( USB_REQTYPE_STANDARD | USB_REQTYPE_DEVICE_OUT, USB_REQUEST_CLEAR_FEATURE, selector, @@ -451,7 +456,7 @@ Device::ClearFeature(uint16 selector) status_t Device::GetStatus(uint16 *status) { - return SendRequest( + return fDefaultPipe->SendRequest( USB_REQTYPE_STANDARD | USB_REQTYPE_DEVICE_IN, USB_REQUEST_GET_STATUS, 0, diff --git a/src/add-ons/kernel/bus_managers/usb/Hub.cpp b/src/add-ons/kernel/bus_managers/usb/Hub.cpp index 7383c5e3b7..50bf169e61 100644 --- a/src/add-ons/kernel/bus_managers/usb/Hub.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Hub.cpp @@ -11,9 +11,9 @@ #include -Hub::Hub(BusManager *bus, Device *parent, usb_device_descriptor &desc, - int8 deviceAddress, bool lowSpeed) - : Device(bus, parent, desc, deviceAddress, lowSpeed) +Hub::Hub(Object *parent, usb_device_descriptor &desc, int8 deviceAddress, + bool lowSpeed) + : Device(parent, desc, deviceAddress, lowSpeed) { TRACE(("USB Hub is being initialised\n")); @@ -68,7 +68,7 @@ Hub::Hub(BusManager *bus, Device *parent, usb_device_descriptor &desc, // Enable port power on all ports for (int32 i = 0; i < fHubDescriptor.num_ports; i++) { - status = SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT, + status = DefaultPipe()->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT, USB_REQUEST_SET_FEATURE, PORT_POWER, i + 1, 0, NULL, 0, NULL); if (status < B_OK) @@ -88,7 +88,7 @@ Hub::UpdatePortStatus(uint8 index) { // get the current port status size_t actualLength = 0; - status_t result = SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_IN, + status_t result = DefaultPipe()->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_IN, USB_REQUEST_GET_STATUS, 0, index + 1, 4, (void *)&fPortStatus[index], 4, &actualLength); @@ -104,7 +104,7 @@ Hub::UpdatePortStatus(uint8 index) status_t Hub::ResetPort(uint8 index) { - status_t result = SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT, + status_t result = DefaultPipe()->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT, USB_REQUEST_SET_FEATURE, PORT_RESET, index + 1, 0, NULL, 0, NULL); if (result < B_OK) @@ -135,7 +135,7 @@ Hub::ResetPort(uint8 index) } // clear the reset change - result = SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT, + result = DefaultPipe()->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT, USB_REQUEST_CLEAR_FEATURE, C_PORT_RESET, index + 1, 0, NULL, 0, NULL); if (result < B_OK) return result; @@ -155,9 +155,7 @@ Hub::Explore() if (result < B_OK) continue; - if (DeviceAddress() > 1) - TRACE(("USB Hub (%d): port %d: status: 0x%04x; change: 0x%04x\n", DeviceAddress(), i, fPortStatus[i].status, fPortStatus[i].change)); - + TRACE(("USB Hub (%d): port %d: status: 0x%04x; change: 0x%04x\n", DeviceAddress(), i, fPortStatus[i].status, fPortStatus[i].change)); if (fPortStatus[i].change & PORT_STATUS_CONNECTION) { if (fPortStatus[i].status & PORT_STATUS_CONNECTION) { // new device attached! @@ -190,7 +188,7 @@ Hub::Explore() // the device failed to setup correctly, disable the port // so that the device doesn't get in the way of future // addressing. - SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT, + DefaultPipe()->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT, USB_REQUEST_CLEAR_FEATURE, PORT_ENABLE, i + 1, 0, NULL, 0, NULL); } @@ -199,14 +197,13 @@ Hub::Explore() TRACE(("USB Hub Explore(): Device removed\n")); if (fChildren[i]) { GetStack()->NotifyDeviceChange(fChildren[i], false); - GetStack()->PutUSBID(fChildren[i]->USBID()); delete fChildren[i]; fChildren[i] = NULL; } } // clear status change - SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT, + DefaultPipe()->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT, USB_REQUEST_CLEAR_FEATURE, C_PORT_CONNECTION, i + 1, 0, NULL, 0, NULL); } @@ -234,7 +231,7 @@ status_t Hub::GetDescriptor(uint8 descriptorType, uint8 index, uint16 languageID, void *data, size_t dataLength, size_t *actualLength) { - return SendRequest( + return DefaultPipe()->SendRequest( USB_REQTYPE_DEVICE_IN | USB_REQTYPE_CLASS, // type USB_REQUEST_GET_DESCRIPTOR, // request (descriptorType << 8) | index, // value diff --git a/src/add-ons/kernel/bus_managers/usb/Interface.cpp b/src/add-ons/kernel/bus_managers/usb/Interface.cpp index f10304a749..de97857ca1 100644 --- a/src/add-ons/kernel/bus_managers/usb/Interface.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Interface.cpp @@ -9,8 +9,8 @@ #include "usb_p.h" -Interface::Interface(BusManager *bus, int8 deviceAddress, pipeSpeed speed) - : ControlPipe(bus, deviceAddress, speed, 0, 8) +Interface::Interface(Object *parent) + : Object(parent) { } @@ -18,7 +18,7 @@ Interface::Interface(BusManager *bus, int8 deviceAddress, pipeSpeed speed) status_t Interface::SetFeature(uint16 selector) { - return SendRequest( + return ((Device *)Parent())->DefaultPipe()->SendRequest( USB_REQTYPE_STANDARD | USB_REQTYPE_INTERFACE_OUT, USB_REQUEST_SET_FEATURE, selector, @@ -33,7 +33,7 @@ Interface::SetFeature(uint16 selector) status_t Interface::ClearFeature(uint16 selector) { - return SendRequest( + return ((Device *)Parent())->DefaultPipe()->SendRequest( USB_REQTYPE_STANDARD | USB_REQTYPE_INTERFACE_OUT, USB_REQUEST_CLEAR_FEATURE, selector, @@ -48,7 +48,7 @@ Interface::ClearFeature(uint16 selector) status_t Interface::GetStatus(uint16 *status) { - return SendRequest( + return ((Device *)Parent())->DefaultPipe()->SendRequest( USB_REQTYPE_STANDARD | USB_REQTYPE_INTERFACE_IN, USB_REQUEST_GET_STATUS, 0, diff --git a/src/add-ons/kernel/bus_managers/usb/Object.cpp b/src/add-ons/kernel/bus_managers/usb/Object.cpp index 578f30c8b8..3ca1d28d89 100644 --- a/src/add-ons/kernel/bus_managers/usb/Object.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Object.cpp @@ -9,9 +9,52 @@ #include "usb_p.h" -Object::Object(BusManager *bus) - : fBusManager(bus), - fStack(bus->GetStack()), +Object::Object(Stack *stack, BusManager *bus) + : fParent(NULL), + fBusManager(bus), + fStack(stack), fUSBID(fStack->GetUSBID(this)) { } + + +Object::Object(Object *parent) + : fParent(parent), + fBusManager(parent->GetBusManager()), + fStack(parent->GetStack()), + fUSBID(fStack->GetUSBID(this)) +{ +} + + +Object::~Object() +{ + fStack->PutUSBID(fUSBID); +} + + +status_t +Object::SetFeature(uint16 selector) +{ + // to be implemented in subclasses + TRACE_ERROR(("USB Object: set feature called\n")); + return B_ERROR; +} + + +status_t +Object::ClearFeature(uint16 selector) +{ + // to be implemented in subclasses + TRACE_ERROR(("USB Object: clear feature called\n")); + return B_ERROR; +} + + +status_t +Object::GetStatus(uint16 *status) +{ + // to be implemented in subclasses + TRACE_ERROR(("USB Object: get status called\n")); + return B_ERROR; +} diff --git a/src/add-ons/kernel/bus_managers/usb/Pipe.cpp b/src/add-ons/kernel/bus_managers/usb/Pipe.cpp index 68dc48dbb7..61ac2caff4 100644 --- a/src/add-ons/kernel/bus_managers/usb/Pipe.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Pipe.cpp @@ -10,9 +10,9 @@ #include "usb_p.h" -Pipe::Pipe(BusManager *bus, int8 deviceAddress, pipeDirection direction, - pipeSpeed speed, uint8 endpointAddress, size_t maxPacketSize) - : Object(bus), +Pipe::Pipe(Object *parent, int8 deviceAddress, uint8 endpointAddress, + pipeDirection direction, pipeSpeed speed, size_t maxPacketSize) + : Object(parent), fDeviceAddress(deviceAddress), fEndpointAddress(endpointAddress), fDirection(direction), @@ -43,15 +43,60 @@ Pipe::CancelQueuedTransfers() } +status_t +Pipe::SetFeature(uint16 selector) +{ + return ((Device *)Parent())->DefaultPipe()->SendRequest( + USB_REQTYPE_STANDARD | USB_REQTYPE_ENDPOINT_OUT, + USB_REQUEST_SET_FEATURE, + selector, + fEndpointAddress, + 0, + NULL, + 0, + NULL); +} + + +status_t +Pipe::ClearFeature(uint16 selector) +{ + return ((Device *)Parent())->DefaultPipe()->SendRequest( + USB_REQTYPE_STANDARD | USB_REQTYPE_ENDPOINT_OUT, + USB_REQUEST_CLEAR_FEATURE, + selector, + fEndpointAddress, + 0, + NULL, + 0, + NULL); +} + + +status_t +Pipe::GetStatus(uint16 *status) +{ + return ((Device *)Parent())->DefaultPipe()->SendRequest( + USB_REQTYPE_STANDARD | USB_REQTYPE_ENDPOINT_IN, + USB_REQUEST_GET_STATUS, + 0, + fEndpointAddress, + 2, + (void *)status, + 2, + NULL); +} + + // // #pragma mark - // -InterruptPipe::InterruptPipe(BusManager *bus, int8 deviceAddress, - pipeDirection direction, pipeSpeed speed, uint8 endpointAddress, +InterruptPipe::InterruptPipe(Object *parent, int8 deviceAddress, + uint8 endpointAddress, pipeDirection direction, pipeSpeed speed, size_t maxPacketSize) - : Pipe(bus, deviceAddress, direction, speed, endpointAddress, + : Pipe(parent, deviceAddress, endpointAddress, direction, speed, maxPacketSize) { } @@ -80,10 +125,9 @@ InterruptPipe::QueueInterrupt(void *data, size_t dataLength, // -BulkPipe::BulkPipe(BusManager *bus, int8 deviceAddress, - pipeDirection direction, pipeSpeed speed, uint8 endpointAddress, - size_t maxPacketSize) - : Pipe(bus, deviceAddress, direction, speed, endpointAddress, +BulkPipe::BulkPipe(Object *parent, int8 deviceAddress, uint8 endpointAddress, + pipeDirection direction, pipeSpeed speed, size_t maxPacketSize) + : Pipe(parent, deviceAddress, endpointAddress, direction, speed, maxPacketSize) { } @@ -130,10 +174,10 @@ BulkPipe::QueueBulkV(iovec *vector, size_t vectorCount, // -IsochronousPipe::IsochronousPipe(BusManager *bus, int8 deviceAddress, - pipeDirection direction, pipeSpeed speed, uint8 endpointAddress, +IsochronousPipe::IsochronousPipe(Object *parent, int8 deviceAddress, + uint8 endpointAddress, pipeDirection direction, pipeSpeed speed, size_t maxPacketSize) - : Pipe(bus, deviceAddress, direction, speed, endpointAddress, + : Pipe(parent, deviceAddress, endpointAddress, direction, speed, maxPacketSize) { } @@ -154,16 +198,17 @@ IsochronousPipe::QueueIsochronous(void *data, size_t dataLength, // -struct transfer_result_data { +typedef struct transfer_result_data_s { sem_id notify_sem; uint32 status; size_t actual_length; -}; +} transfer_result_data; -ControlPipe::ControlPipe(BusManager *bus, int8 deviceAddress, pipeSpeed speed, - uint8 endpointAddress, size_t maxPacketSize) - : Pipe(bus, deviceAddress, Default, speed, endpointAddress, maxPacketSize) +ControlPipe::ControlPipe(Object *parent, int8 deviceAddress, + uint8 endpointAddress, pipeSpeed speed, size_t maxPacketSize) + : Pipe(parent, deviceAddress, endpointAddress, Default, speed, + maxPacketSize) { } @@ -241,48 +286,3 @@ ControlPipe::QueueRequest(uint8 requestType, uint8 request, uint16 value, delete transfer; return result; } - - -status_t -ControlPipe::SetFeature(uint16 selector) -{ - return SendRequest( - USB_REQTYPE_STANDARD | USB_REQTYPE_ENDPOINT_OUT, - USB_REQUEST_SET_FEATURE, - selector, - 0, - 0, - NULL, - 0, - NULL); -} - - -status_t -ControlPipe::ClearFeature(uint16 selector) -{ - return SendRequest( - USB_REQTYPE_STANDARD | USB_REQTYPE_ENDPOINT_OUT, - USB_REQUEST_CLEAR_FEATURE, - selector, - 0, - 0, - NULL, - 0, - NULL); -} - - -status_t -ControlPipe::GetStatus(uint16 *status) -{ - return SendRequest( - USB_REQTYPE_STANDARD | USB_REQTYPE_ENDPOINT_IN, - USB_REQUEST_GET_STATUS, - 0, - 0, - 2, - (void *)status, - 2, - NULL); -} diff --git a/src/add-ons/kernel/bus_managers/usb/usb.cpp b/src/add-ons/kernel/bus_managers/usb/usb.cpp index 3dc4731d28..8cc8c971da 100644 --- a/src/add-ons/kernel/bus_managers/usb/usb.cpp +++ b/src/add-ons/kernel/bus_managers/usb/usb.cpp @@ -7,6 +7,7 @@ * Niels S. Reedijk */ +#define TRACE_USB #include #include "usb_p.h" #include @@ -146,10 +147,10 @@ set_feature(usb_id handle, uint16 selector) { TRACE(("usb_module: set_feature(0x%08x, %d)\n", handle, selector)); Object *object = gUSBStack->GetObject(handle); - if (!object || (object->Type() & USB_OBJECT_CONTROL_PIPE) == 0) + if (!object) return B_BAD_VALUE; - return ((ControlPipe *)object)->SetFeature(selector); + return object->SetFeature(selector); } @@ -158,10 +159,10 @@ clear_feature(usb_id handle, uint16 selector) { TRACE(("usb_module: clear_feature(0x%08x, %d)\n", handle, selector)); Object *object = gUSBStack->GetObject(handle); - if (!object || (object->Type() & USB_OBJECT_CONTROL_PIPE) == 0) + if (!object) return B_BAD_VALUE; - return ((ControlPipe *)object)->ClearFeature(selector); + return object->ClearFeature(selector); } @@ -173,10 +174,10 @@ get_status(usb_id handle, uint16 *status) return B_BAD_VALUE; Object *object = gUSBStack->GetObject(handle); - if (!object || (object->Type() & USB_OBJECT_CONTROL_PIPE) == 0) + if (!object) return B_BAD_VALUE; - return ((ControlPipe *)object)->GetStatus(status); + return object->GetStatus(status); } @@ -203,8 +204,8 @@ send_request(usb_device device, uint8 requestType, uint8 request, if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) return B_BAD_VALUE; - return ((Device *)object)->SendRequest(requestType, request, value, index, - length, data, length, actualLength); + return ((Device *)object)->DefaultPipe()->SendRequest(requestType, request, + value, index, length, data, length, actualLength); } @@ -218,8 +219,8 @@ queue_request(usb_device device, uint8 requestType, uint8 request, if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) return B_BAD_VALUE; - return ((Device *)object)->QueueRequest(requestType, request, value, index, - length, data, length, callback, callbackCookie); + return ((Device *)object)->DefaultPipe()->QueueRequest(requestType, + request, value, index, length, data, length, callback, callbackCookie); } diff --git a/src/add-ons/kernel/bus_managers/usb/usb_p.h b/src/add-ons/kernel/bus_managers/usb/usb_p.h index dea66ce776..e7e7911a4b 100644 --- a/src/add-ons/kernel/bus_managers/usb/usb_p.h +++ b/src/add-ons/kernel/bus_managers/usb/usb_p.h @@ -138,18 +138,16 @@ virtual status_t InitCheck(); bool Lock(); void Unlock(); - Device *AllocateNewDevice(Device *parent, - bool lowSpeed); - int8 AllocateAddress(); + Device *AllocateNewDevice(Hub *parent, + bool lowSpeed); virtual status_t Start(); virtual status_t Stop(); virtual status_t SubmitTransfer(Transfer *transfer); - Stack *GetStack() { return fStack; }; - void SetStack(Stack *stack) { fStack = stack; }; + Object *RootObject() { return fRootObject; }; Hub *GetRootHub() { return fRootHub; }; void SetRootHub(Hub *hub) { fRootHub = hub; }; @@ -165,14 +163,18 @@ static int32 ExploreThread(void *data); ControlPipe *fDefaultPipe; ControlPipe *fDefaultPipeLowSpeed; Hub *fRootHub; - Stack *fStack; thread_id fExploreThread; + Object *fRootObject; }; class Object { public: - Object(BusManager *bus); + Object(Stack *stack, BusManager *bus); + Object(Object *parent); +virtual ~Object(); + + Object *Parent() { return fParent; }; BusManager *GetBusManager() { return fBusManager; }; Stack *GetStack() { return fStack; }; @@ -180,7 +182,13 @@ public: usb_id USBID() { return fUSBID; }; virtual uint32 Type() { return USB_OBJECT_NONE; }; + // Convenience functions for standard requests +virtual status_t SetFeature(uint16 selector); +virtual status_t ClearFeature(uint16 selector); +virtual status_t GetStatus(uint16 *status); + private: + Object *fParent; BusManager *fBusManager; Stack *fStack; usb_id fUSBID; @@ -196,11 +204,11 @@ public: enum pipeDirection { In, Out, Default }; enum pipeSpeed { LowSpeed, FullSpeed, HighSpeed }; - Pipe(BusManager *bus, + Pipe(Object *parent, int8 deviceAddress, + uint8 endpointAddress, pipeDirection direction, pipeSpeed speed, - uint8 endpointAddress, size_t maxPacketSize); virtual ~Pipe(); @@ -218,7 +226,12 @@ virtual void SetDataToggle(bool toggle) { fDataToggle = toggle; }; status_t SubmitTransfer(Transfer *transfer); status_t CancelQueuedTransfers(); -protected: + // Convenience functions for standard requests +virtual status_t SetFeature(uint16 selector); +virtual status_t ClearFeature(uint16 selector); +virtual status_t GetStatus(uint16 *status); + +private: int8 fDeviceAddress; uint8 fEndpointAddress; pipeDirection fDirection; @@ -230,10 +243,10 @@ protected: class ControlPipe : public Pipe { public: - ControlPipe(BusManager *bus, + ControlPipe(Object *parent, int8 deviceAddress, - pipeSpeed speed, uint8 endpointAddress, + pipeSpeed speed, size_t maxPacketSize); virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_CONTROL_PIPE; }; @@ -261,21 +274,16 @@ static void SendRequestCallback(void *cookie, void *data, size_t dataLength, usb_callback_func callback, void *callbackCookie); - - // Convenience functions for standard requests -virtual status_t SetFeature(uint16 selector); -virtual status_t ClearFeature(uint16 selector); -virtual status_t GetStatus(uint16 *status); }; class InterruptPipe : public Pipe { public: - InterruptPipe(BusManager *bus, + InterruptPipe(Object *parent, int8 deviceAddress, + uint8 endpointAddress, pipeDirection direction, pipeSpeed speed, - uint8 endpointAddress, size_t maxPacketSize); virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_INTERRUPT_PIPE; }; @@ -289,11 +297,11 @@ virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_INTERRUPT_PIPE class BulkPipe : public Pipe { public: - BulkPipe(BusManager *bus, + BulkPipe(Object *parent, int8 deviceAddress, + uint8 endpointAddress, pipeDirection direction, pipeSpeed speed, - uint8 endpointAddress, size_t maxPacketSize); virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_BULK_PIPE; }; @@ -311,11 +319,11 @@ virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_BULK_PIPE; }; class IsochronousPipe : public Pipe { public: - IsochronousPipe(BusManager *bus, + IsochronousPipe(Object *parent, int8 deviceAddress, + uint8 endpointAddress, pipeDirection direction, pipeSpeed speed, - uint8 endpointAddress, size_t maxPacketSize); virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_ISO_PIPE; }; @@ -331,13 +339,11 @@ virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_ISO_PIPE; }; }; -class Interface : public ControlPipe { +class Interface : public Object { public: - Interface(BusManager *bus, - int8 deviceAddress, - pipeSpeed speed); + Interface(Object *parent); -virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_CONTROL_PIPE | USB_OBJECT_INTERFACE; }; +virtual uint32 Type() { return USB_OBJECT_INTERFACE; }; // Convenience functions for standard requests virtual status_t SetFeature(uint16 selector); @@ -346,15 +352,17 @@ virtual status_t GetStatus(uint16 *status); }; -class Device : public ControlPipe { +class Device : public Object { public: - Device(BusManager *bus, Device *parent, + Device(Object *parent, usb_device_descriptor &desc, int8 deviceAddress, bool lowSpeed); status_t InitCheck(); -virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_CONTROL_PIPE | USB_OBJECT_DEVICE; }; +virtual uint32 Type() { return USB_OBJECT_DEVICE; }; + + ControlPipe *DefaultPipe() { return fDefaultPipe; }; virtual status_t GetDescriptor(uint8 descriptorType, uint8 index, uint16 languageID, @@ -384,26 +392,28 @@ virtual status_t GetStatus(uint16 *status); protected: usb_device_descriptor fDeviceDescriptor; + bool fInitOK; + +private: usb_configuration_info *fConfigurations; usb_configuration_info *fCurrentConfiguration; - bool fInitOK; bool fLowSpeed; - Device *fParent; int8 fDeviceAddress; size_t fMaxPacketIn[16]; size_t fMaxPacketOut[16]; sem_id fLock; void *fNotifyCookie; + ControlPipe *fDefaultPipe; }; class Hub : public Device { public: - Hub(BusManager *bus, Device *parent, + Hub(Object *parent, usb_device_descriptor &desc, int8 deviceAddress, bool lowSpeed); -virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_CONTROL_PIPE | USB_OBJECT_DEVICE | USB_OBJECT_HUB; }; +virtual uint32 Type() { return USB_OBJECT_DEVICE | USB_OBJECT_HUB; }; virtual status_t GetDescriptor(uint8 descriptorType, uint8 index, uint16 languageID, diff --git a/src/add-ons/kernel/busses/usb/ehci.cpp b/src/add-ons/kernel/busses/usb/ehci.cpp index db9f41693d..720019bb21 100644 --- a/src/add-ons/kernel/busses/usb/ehci.cpp +++ b/src/add-ons/kernel/busses/usb/ehci.cpp @@ -202,7 +202,7 @@ EHCI::Start() } fRootHubAddress = AllocateAddress(); - fRootHub = new(std::nothrow) EHCIRootHub(this, fRootHubAddress); + fRootHub = new(std::nothrow) EHCIRootHub(RootObject(), fRootHubAddress); if (!fRootHub) { TRACE_ERROR(("usb_ehci: no memory to allocate root hub\n")); return B_NO_MEMORY; diff --git a/src/add-ons/kernel/busses/usb/ehci.h b/src/add-ons/kernel/busses/usb/ehci.h index 39d1349860..e610a34060 100644 --- a/src/add-ons/kernel/busses/usb/ehci.h +++ b/src/add-ons/kernel/busses/usb/ehci.h @@ -134,7 +134,8 @@ static pci_module_info *sPCIModule; class EHCIRootHub : public Hub { public: - EHCIRootHub(EHCI *ehci, int8 deviceAddress); + EHCIRootHub(Object *rootObject, + int8 deviceAddress); static status_t ProcessTransfer(EHCI *ehci, Transfer *transfer); diff --git a/src/add-ons/kernel/busses/usb/ehci_rh.cpp b/src/add-ons/kernel/busses/usb/ehci_rh.cpp index 09ef1b9402..cc4998643f 100644 --- a/src/add-ons/kernel/busses/usb/ehci_rh.cpp +++ b/src/add-ons/kernel/busses/usb/ehci_rh.cpp @@ -95,27 +95,34 @@ static ehci_root_hub_string_s sEHCIRootHubStrings[3] = { { 4, // Descriptor length USB_DESCRIPTOR_STRING, // Descriptor type - 0x0409 // Supported language IDs (English US) + { + 0x0409 // Supported language IDs (English US) + } }, { 12, // Descriptor length USB_DESCRIPTOR_STRING, // Descriptor type - 'H', 'A', 'I', 'K', 'U', ' ', // Characters - 'I', 'n', 'c', '.' + { + 'H', 'A', 'I', 'K', 'U', // Characters + ' ', 'I', 'n', 'c', '.' + } }, { 26, // Descriptor length USB_DESCRIPTOR_STRING, // Descriptor type - 'E', 'H', 'C', 'I', ' ', 'R', // Characters - 'o', 'o', 't', 'H', 'u', 'b' + { + 'E', 'H', 'C', 'I', ' ', // Characters + 'R', 'o', 'o', 't', 'H', + 'u', 'b' + } } }; -EHCIRootHub::EHCIRootHub(EHCI *ehci, int8 deviceAddress) - : Hub(ehci, NULL, sEHCIRootHubDevice, deviceAddress, false) +EHCIRootHub::EHCIRootHub(Object *rootObject, int8 deviceAddress) + : Hub(rootObject, sEHCIRootHubDevice, deviceAddress, false) { } diff --git a/src/add-ons/kernel/busses/usb/ohci_rh.cpp b/src/add-ons/kernel/busses/usb/ohci_rh.cpp index 8346f06f35..9b47c2f00b 100644 --- a/src/add-ons/kernel/busses/usb/ohci_rh.cpp +++ b/src/add-ons/kernel/busses/usb/ohci_rh.cpp @@ -88,7 +88,7 @@ usb_hub_descriptor ohci_hubd = //Implementation OHCIRootHub::OHCIRootHub( OHCI *ohci , int8 devicenum ) - : Hub( ohci , NULL , ohci_devd , devicenum , false ) + : Hub( ohci->RootObject() , ohci_devd , devicenum , false ) { m_ohci = ohci; } diff --git a/src/add-ons/kernel/busses/usb/uhci.cpp b/src/add-ons/kernel/busses/usb/uhci.cpp index a9b0b146f5..fffff7e5a2 100644 --- a/src/add-ons/kernel/busses/usb/uhci.cpp +++ b/src/add-ons/kernel/busses/usb/uhci.cpp @@ -483,7 +483,7 @@ UHCI::Start() } fRootHubAddress = AllocateAddress(); - fRootHub = new(std::nothrow) UHCIRootHub(this, fRootHubAddress); + fRootHub = new(std::nothrow) UHCIRootHub(RootObject(), fRootHubAddress); if (!fRootHub) { TRACE_ERROR(("usb_uhci: no memory to allocate root hub\n")); return B_NO_MEMORY; diff --git a/src/add-ons/kernel/busses/usb/uhci.h b/src/add-ons/kernel/busses/usb/uhci.h index f9174a7f3d..95eb9abee0 100644 --- a/src/add-ons/kernel/busses/usb/uhci.h +++ b/src/add-ons/kernel/busses/usb/uhci.h @@ -161,7 +161,8 @@ static pci_module_info *sPCIModule; class UHCIRootHub : public Hub { public: - UHCIRootHub(UHCI *uhci, int8 deviceAddress); + UHCIRootHub(Object *rootObject, + int8 deviceAddress); static status_t ProcessTransfer(UHCI *uhci, Transfer *transfer); diff --git a/src/add-ons/kernel/busses/usb/uhci_rh.cpp b/src/add-ons/kernel/busses/usb/uhci_rh.cpp index b4e6e6a8ad..85170605d3 100644 --- a/src/add-ons/kernel/busses/usb/uhci_rh.cpp +++ b/src/add-ons/kernel/busses/usb/uhci_rh.cpp @@ -99,7 +99,7 @@ static uhci_root_hub_string_s sUHCIRootHubStrings[3] = { 4, // Descriptor length USB_DESCRIPTOR_STRING, // Descriptor type { - 0x0409 // Supported language IDs (English US) + 0x0409 // Supported language IDs (English US) } }, @@ -107,8 +107,8 @@ static uhci_root_hub_string_s sUHCIRootHubStrings[3] = { 12, // Descriptor length USB_DESCRIPTOR_STRING, // Descriptor type { - 'H', 'A', 'I', 'K', 'U', ' ', // Characters - 'I', 'n', 'c', '.' + 'H', 'A', 'I', 'K', 'U', // Characters + ' ', 'I', 'n', 'c', '.' } }, @@ -117,15 +117,16 @@ static uhci_root_hub_string_s sUHCIRootHubStrings[3] = { 26, // Descriptor length USB_DESCRIPTOR_STRING, // Descriptor type { - 'U', 'H', 'C', 'I', ' ', 'R', // Characters - 'o', 'o', 't', 'H', 'u', 'b' + 'U', 'H', 'C', 'I', ' ', // Characters + 'R', 'o', 'o', 't', 'H', + 'u', 'b' } } }; -UHCIRootHub::UHCIRootHub(UHCI *uhci, int8 deviceAddress) - : Hub(uhci, NULL, sUHCIRootHubDevice, deviceAddress, false) +UHCIRootHub::UHCIRootHub(Object *rootObject, int8 deviceAddress) + : Hub(rootObject, sUHCIRootHubDevice, deviceAddress, false) { }