Patch by Salvatore Benedetto:
Code readability; portability fixes. Added unimplemented SubmitIsochronous(). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21259 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -367,6 +367,7 @@ UHCI::UHCI(pci_info *info, Stack *stack)
|
|||||||
// 1: low speed control transfers
|
// 1: low speed control transfers
|
||||||
// 2: full speed control transfers
|
// 2: full speed control transfers
|
||||||
// 3: bulk transfers
|
// 3: bulk transfers
|
||||||
|
// TODO: 4: bandwidth reclamation queue
|
||||||
fQueueCount = 4;
|
fQueueCount = 4;
|
||||||
fQueues = new(std::nothrow) Queue *[fQueueCount];
|
fQueues = new(std::nothrow) Queue *[fQueueCount];
|
||||||
if (!fQueues) {
|
if (!fQueues) {
|
||||||
@@ -389,8 +390,14 @@ UHCI::UHCI(pci_info *info, Stack *stack)
|
|||||||
// Make sure the last queue terminates
|
// Make sure the last queue terminates
|
||||||
fQueues[fQueueCount - 1]->TerminateByStrayDescriptor();
|
fQueues[fQueueCount - 1]->TerminateByStrayDescriptor();
|
||||||
|
|
||||||
for (int32 i = 0; i < 1024; i++)
|
// Create the array that will keep bandwidth information
|
||||||
fFrameList[i] = fQueues[0]->PhysicalAddress() | FRAMELIST_NEXT_IS_QH;
|
fFrameBandwidth = new(std::nothrow) int32[NUMBER_OF_FRAMES];
|
||||||
|
|
||||||
|
for (int32 i = 0; i < NUMBER_OF_FRAMES; i++) {
|
||||||
|
fFrameList[i] = fQueues[UHCI_INTERRUPT_QUEUE]->PhysicalAddress()
|
||||||
|
| FRAMELIST_NEXT_IS_QH;
|
||||||
|
fFrameBandwidth[i] = MAX_AVAILABLE_BANDWIDTH;
|
||||||
|
}
|
||||||
|
|
||||||
// create semaphore the finisher thread will wait for
|
// create semaphore the finisher thread will wait for
|
||||||
fFinishTransfersSem = create_sem(0, "UHCI Finish Transfers");
|
fFinishTransfersSem = create_sem(0, "UHCI Finish Transfers");
|
||||||
@@ -437,6 +444,7 @@ UHCI::~UHCI()
|
|||||||
delete fQueues[i];
|
delete fQueues[i];
|
||||||
|
|
||||||
delete [] fQueues;
|
delete [] fQueues;
|
||||||
|
delete [] fFrameBandwidth;
|
||||||
delete fRootHub;
|
delete fRootHub;
|
||||||
delete_area(fFrameArea);
|
delete_area(fFrameArea);
|
||||||
|
|
||||||
@@ -506,6 +514,10 @@ UHCI::SubmitTransfer(Transfer *transfer)
|
|||||||
if (transfer->TransferPipe()->Type() & USB_OBJECT_CONTROL_PIPE)
|
if (transfer->TransferPipe()->Type() & USB_OBJECT_CONTROL_PIPE)
|
||||||
return SubmitRequest(transfer);
|
return SubmitRequest(transfer);
|
||||||
|
|
||||||
|
// Process isochronous transfers
|
||||||
|
if (transfer->TransferPipe()->Type() & USB_OBJECT_ISO_PIPE)
|
||||||
|
return SubmitIsochronous(transfer);
|
||||||
|
|
||||||
uhci_td *firstDescriptor = NULL;
|
uhci_td *firstDescriptor = NULL;
|
||||||
uhci_qh *transferQueue = NULL;
|
uhci_qh *transferQueue = NULL;
|
||||||
status_t result = CreateFilledTransfer(transfer, &firstDescriptor,
|
status_t result = CreateFilledTransfer(transfer, &firstDescriptor,
|
||||||
@@ -516,11 +528,9 @@ UHCI::SubmitTransfer(Transfer *transfer)
|
|||||||
Queue *queue = NULL;
|
Queue *queue = NULL;
|
||||||
Pipe *pipe = transfer->TransferPipe();
|
Pipe *pipe = transfer->TransferPipe();
|
||||||
if (pipe->Type() & USB_OBJECT_INTERRUPT_PIPE) {
|
if (pipe->Type() & USB_OBJECT_INTERRUPT_PIPE) {
|
||||||
// use interrupt queue
|
queue = fQueues[UHCI_INTERRUPT_QUEUE];
|
||||||
queue = fQueues[0];
|
|
||||||
} else {
|
} else {
|
||||||
// use bulk queue
|
queue = fQueues[UHCI_BULK_QUEUE];
|
||||||
queue = fQueues[3];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool directionIn = (pipe->Direction() == Pipe::In);
|
bool directionIn = (pipe->Direction() == Pipe::In);
|
||||||
@@ -634,11 +644,9 @@ UHCI::SubmitRequest(Transfer *transfer)
|
|||||||
|
|
||||||
Queue *queue = NULL;
|
Queue *queue = NULL;
|
||||||
if (pipe->Speed() == USB_SPEED_LOWSPEED) {
|
if (pipe->Speed() == USB_SPEED_LOWSPEED) {
|
||||||
// use the low speed control queue
|
queue = fQueues[UHCI_LOW_SPEED_CONTROL_QUEUE];
|
||||||
queue = fQueues[1];
|
|
||||||
} else {
|
} else {
|
||||||
// use the full speed control queue
|
queue = fQueues[UHCI_FULL_SPEED_CONTROL_QUEUE];
|
||||||
queue = fQueues[2];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uhci_qh *transferQueue = CreateTransferQueue(setupDescriptor);
|
uhci_qh *transferQueue = CreateTransferQueue(setupDescriptor);
|
||||||
@@ -697,6 +705,26 @@ UHCI::AddPendingTransfer(Transfer *transfer, Queue *queue,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
UHCI::SubmitIsochronous(Transfer *transfer)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* This is the main isochronous method.
|
||||||
|
* Here we attach one Transfer Descriptor (TD) per frame by starting
|
||||||
|
* at the position specified by StartingFrameNumber. If there is
|
||||||
|
* not enought bandwidth at that entry number, we find the next
|
||||||
|
* available one.
|
||||||
|
* The TD is obviously appended to the latest existing isochronous
|
||||||
|
* TD (if any) in that frame.
|
||||||
|
* Everytime a TD is added, fFrameBandiwidth[i] is decremented by
|
||||||
|
* the TD bandwidth, while it is incremented once the TD has been
|
||||||
|
* processed by the controller
|
||||||
|
*/
|
||||||
|
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int32
|
int32
|
||||||
UHCI::FinishThread(void *data)
|
UHCI::FinishThread(void *data)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -14,6 +14,12 @@
|
|||||||
#include "uhci_hardware.h"
|
#include "uhci_hardware.h"
|
||||||
#include <lock.h>
|
#include <lock.h>
|
||||||
|
|
||||||
|
#define UHCI_INTERRUPT_QUEUE 0
|
||||||
|
#define UHCI_LOW_SPEED_CONTROL_QUEUE 1
|
||||||
|
#define UHCI_FULL_SPEED_CONTROL_QUEUE 2
|
||||||
|
#define UHCI_BULK_QUEUE 3
|
||||||
|
#define UHCI_BANDWIDTH_RECLAMATION_QUEUE 4
|
||||||
|
|
||||||
struct pci_info;
|
struct pci_info;
|
||||||
struct pci_module_info;
|
struct pci_module_info;
|
||||||
class UHCIRootHub;
|
class UHCIRootHub;
|
||||||
@@ -70,6 +76,7 @@ public:
|
|||||||
virtual status_t SubmitTransfer(Transfer *transfer);
|
virtual status_t SubmitTransfer(Transfer *transfer);
|
||||||
virtual status_t CancelQueuedTransfers(Pipe *pipe);
|
virtual status_t CancelQueuedTransfers(Pipe *pipe);
|
||||||
status_t SubmitRequest(Transfer *transfer);
|
status_t SubmitRequest(Transfer *transfer);
|
||||||
|
status_t SubmitIsochronous(Transfer *transfer);
|
||||||
|
|
||||||
static status_t AddTo(Stack *stack);
|
static status_t AddTo(Stack *stack);
|
||||||
|
|
||||||
@@ -149,6 +156,10 @@ static pci_module_info *sPCIModule;
|
|||||||
area_id fFrameArea;
|
area_id fFrameArea;
|
||||||
addr_t *fFrameList;
|
addr_t *fFrameList;
|
||||||
|
|
||||||
|
// fFrameBandwidth[n] holds the available bandwidth
|
||||||
|
// of the nth frame in microseconds
|
||||||
|
int32 *fFrameBandwidth;
|
||||||
|
|
||||||
// Queues
|
// Queues
|
||||||
int32 fQueueCount;
|
int32 fQueueCount;
|
||||||
Queue **fQueues;
|
Queue **fQueues;
|
||||||
|
|||||||
@@ -79,15 +79,18 @@
|
|||||||
#define FRAMELIST_TERMINATE 0x1
|
#define FRAMELIST_TERMINATE 0x1
|
||||||
#define FRAMELIST_NEXT_IS_QH 0x2
|
#define FRAMELIST_NEXT_IS_QH 0x2
|
||||||
|
|
||||||
|
// Number of frames
|
||||||
|
#define NUMBER_OF_FRAMES 1024
|
||||||
|
#define MAX_AVAILABLE_BANDWIDTH 900 // Microseconds
|
||||||
|
|
||||||
// Represents a Transfer Descriptor (TD)
|
// Represents a Transfer Descriptor (TD)
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
// Hardware part
|
// Hardware part
|
||||||
addr_t link_phy; // Link to the next TD/QH
|
uint32 link_phy; // Link to the next TD/QH
|
||||||
uint32 status; // Status field
|
uint32 status; // Status field
|
||||||
uint32 token; // Contains the packet header (where it needs to be sent)
|
uint32 token; // Contains the packet header (where it needs to be sent)
|
||||||
void *buffer_phy; // A pointer to the buffer with the actual packet
|
uint32 buffer_phy; // A pointer to the buffer with the actual packet
|
||||||
// Software part
|
// Software part
|
||||||
addr_t this_phy; // A physical pointer to this address
|
addr_t this_phy; // A physical pointer to this address
|
||||||
void *link_log; // Pointer to the next logical TD/QT
|
void *link_log; // Pointer to the next logical TD/QT
|
||||||
@@ -139,8 +142,8 @@ typedef struct
|
|||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
// Hardware part
|
// Hardware part
|
||||||
addr_t link_phy; // Link to the next TD/QH
|
uint32 link_phy; // Link to the next TD/QH
|
||||||
addr_t element_phy; // Pointer to the first element in the queue
|
uint32 element_phy; // Pointer to the first element in the queue
|
||||||
// Software part
|
// Software part
|
||||||
addr_t this_phy; // The physical pointer to this address
|
addr_t this_phy; // The physical pointer to this address
|
||||||
void *link_log; // Pointer to the next logical TD/QH
|
void *link_log; // Pointer to the next logical TD/QH
|
||||||
|
|||||||
Reference in New Issue
Block a user