diff --git a/src/add-ons/kernel/bus_managers/usb/BusManager.cpp b/src/add-ons/kernel/bus_managers/usb/BusManager.cpp index 87762cd3d0..19dab22d72 100644 --- a/src/add-ons/kernel/bus_managers/usb/BusManager.cpp +++ b/src/add-ons/kernel/bus_managers/usb/BusManager.cpp @@ -256,3 +256,11 @@ BusManager::SubmitTransfer(Transfer *transfer) // virtual function to be overridden return B_ERROR; } + + +status_t +BusManager::NotifyPipeChange(Pipe *pipe, usb_change change) +{ + // virtual function to be overridden + 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 cc6fa91736..e77b9abd68 100644 --- a/src/add-ons/kernel/bus_managers/usb/Pipe.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Pipe.cpp @@ -20,11 +20,13 @@ Pipe::Pipe(Object *parent, int8 deviceAddress, uint8 endpointAddress, fMaxPacketSize(maxPacketSize), fDataToggle(false) { + GetBusManager()->NotifyPipeChange(this, USB_CHANGE_CREATED); } Pipe::~Pipe() { + GetBusManager()->NotifyPipeChange(this, USB_CHANGE_DESTROYED); } @@ -183,7 +185,10 @@ IsochronousPipe::IsochronousPipe(Object *parent, int8 deviceAddress, uint8 endpointAddress, pipeDirection direction, usb_speed speed, size_t maxPacketSize) : Pipe(parent, deviceAddress, endpointAddress, direction, speed, - maxPacketSize) + maxPacketSize), + fMaxQueuedPackets(0), + fMaxBufferDuration(0), + fSampleSize(0) { } @@ -198,6 +203,38 @@ IsochronousPipe::QueueIsochronous(void *data, size_t dataLength, } +status_t +IsochronousPipe::SetPipePolicy(uint8 maxQueuedPackets, + uint16 maxBufferDurationMS, uint16 sampleSize) +{ + if (maxQueuedPackets == fMaxQueuedPackets + || maxBufferDurationMS == fMaxBufferDuration + || sampleSize == fSampleSize) + return B_OK; + + fMaxQueuedPackets = maxQueuedPackets; + fMaxBufferDuration = maxBufferDurationMS; + fSampleSize = sampleSize; + + GetBusManager()->NotifyPipeChange(this, USB_CHANGE_PIPE_POLICY_CHANGED); + return B_OK; +} + + +status_t +IsochronousPipe::GetPipePolicy(uint8 *maxQueuedPackets, + uint16 *maxBufferDurationMS, uint16 *sampleSize) +{ + if (maxQueuedPackets) + *maxQueuedPackets = fMaxQueuedPackets; + if (maxBufferDurationMS) + *maxBufferDurationMS = fMaxBufferDuration; + if (sampleSize) + *sampleSize = fSampleSize; + return B_OK; +} + + // // #pragma mark - // diff --git a/src/add-ons/kernel/bus_managers/usb/usb.cpp b/src/add-ons/kernel/bus_managers/usb/usb.cpp index ab55d9202b..221ccdf730 100644 --- a/src/add-ons/kernel/bus_managers/usb/usb.cpp +++ b/src/add-ons/kernel/bus_managers/usb/usb.cpp @@ -291,7 +291,8 @@ set_pipe_policy(usb_pipe pipe, uint8 maxQueuedPackets, if (!object || (object->Type() & USB_OBJECT_ISO_PIPE) == 0) return B_DEV_INVALID_PIPE; - return B_ERROR; + return ((IsochronousPipe *)object)->SetPipePolicy(maxQueuedPackets, + maxBufferDurationMS, sampleSize); } 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 34a5e4aac0..ebd66ffc64 100644 --- a/src/add-ons/kernel/bus_managers/usb/usb_p.h +++ b/src/add-ons/kernel/bus_managers/usb/usb_p.h @@ -30,6 +30,7 @@ class Stack; class Device; class Transfer; class BusManager; +class Pipe; class ControlPipe; class Object; class PhysicalMemoryAllocator; @@ -68,6 +69,13 @@ typedef enum { } usb_speed; +typedef enum { + USB_CHANGE_CREATED = 0, + USB_CHANGE_DESTROYED, + USB_CHANGE_PIPE_POLICY_CHANGED +} usb_change; + + #define USB_OBJECT_NONE 0x00000000 #define USB_OBJECT_PIPE 0x00000001 #define USB_OBJECT_CONTROL_PIPE 0x00000002 @@ -156,6 +164,9 @@ virtual status_t Stop(); virtual status_t SubmitTransfer(Transfer *transfer); +virtual status_t NotifyPipeChange(Pipe *pipe, + usb_change change); + Object *RootObject() { return fRootObject; }; Hub *GetRootHub() { return fRootHub; }; @@ -343,6 +354,18 @@ virtual uint32 Type() { return USB_OBJECT_PIPE | USB_OBJECT_ISO_PIPE; }; uint32 flags, usb_callback_func callback, void *callbackCookie); + + status_t SetPipePolicy(uint8 maxQueuedPackets, + uint16 maxBufferDurationMS, + uint16 sampleSize); + status_t GetPipePolicy(uint8 *maxQueuedPackets, + uint16 *maxBufferDurationMS, + uint16 *sampleSize); + +private: + uint8 fMaxQueuedPackets; + uint16 fMaxBufferDuration; + uint16 fSampleSize; }; diff --git a/src/add-ons/kernel/busses/usb/ehci.cpp b/src/add-ons/kernel/busses/usb/ehci.cpp index e4d09c6cf2..8b3a645dda 100644 --- a/src/add-ons/kernel/busses/usb/ehci.cpp +++ b/src/add-ons/kernel/busses/usb/ehci.cpp @@ -462,6 +462,29 @@ EHCI::SubmitPeriodicTransfer(Transfer *transfer) } +status_t +EHCI::NotifyPipeChange(Pipe *pipe, usb_change change) +{ + TRACE_ERROR(("usb_ehci: pipe change %d for pipe 0x%08lx\n", change, (uint32)pipe)); + switch (change) { + case USB_CHANGE_CREATED: + case USB_CHANGE_DESTROYED: { + // ToDo: we should create and keep a single queue head + // for all transfers to/from this pipe + break; + } + + case USB_CHANGE_PIPE_POLICY_CHANGED: { + // ToDo: for isochronous pipes we might need to adapt to new + // pipe policy settings here + break; + } + } + + return B_OK; +} + + status_t EHCI::AddTo(Stack *stack) { diff --git a/src/add-ons/kernel/busses/usb/ehci.h b/src/add-ons/kernel/busses/usb/ehci.h index 034ccfc094..7c5f3c63fe 100644 --- a/src/add-ons/kernel/busses/usb/ehci.h +++ b/src/add-ons/kernel/busses/usb/ehci.h @@ -38,6 +38,9 @@ virtual status_t SubmitTransfer(Transfer *transfer); status_t SubmitPeriodicTransfer(Transfer *transfer); status_t SubmitAsyncTransfer(Transfer *transfer); +virtual status_t NotifyPipeChange(Pipe *pipe, + usb_change change); + static status_t AddTo(Stack *stack); // Port operations for root hub