* Implemented a notification method for BusManagers so that they can be notified of pipe changes (creation, destruction, changed settings).

This is necessary in OHCI and will probably be used in EHCI also to keep one endpoint construct for each pipe open instead on creating and deleting it for each transfer.
* Pseudo implemented set_pipe_policy for isochronous pipes that makes use of the new notification system.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18945 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz
2006-09-26 20:51:31 +00:00
parent 4a718fa33d
commit 00f6fab931
6 changed files with 97 additions and 2 deletions
@@ -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;
}
+38 -1
View File
@@ -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 -
//
+2 -1
View File
@@ -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);
}
@@ -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;
};
+23
View File
@@ -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)
{
+3
View File
@@ -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