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