UHCI patch
"Salvatore Benedetto" <[email protected]> Sun, 27 May 2007 19:01:15 +0200
| Newsgroups | gmane.os.openbeos.kernel.devel |
|---|---|
| Message-ID | <[email protected]> |
Hi, I've attached a patch, that has already been reviewed by Michael Lotz. It's a simple patch that adds some macro to improve readability of the code, plus some fixes about portability. A method that should handle the isochronous transfer is also added, but not implemented yet. Salvo -- Salvatore Benedetto (a.k.a. emitrax) Student of Computer and Telecommunications Engineering University of Messina (Italy) www.messinalug.org skype:emitrax icq:299985329 No to global warming! http://www.climatecrisis.net/ http://www.stopglobalwarming.org/ Siti di vera informazione Italiana www.beppegrillo.it Please do not send me any word, excel or power point file http://www.gnu.org/philosophy/no-word-attachments.html ------------------------------------------------------------------------- This SF.net email is sponsored by DB2 Express Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now. http://sourceforge.net/powerbar/db2/ _______________________________________________ Open-beos-kernel-devel mailing list Open-beos-kernel-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org https://lists.sourceforge.net/lists/listinfo/open-beos-kernel-devel
uhci.patch
(text/x-patch, 5.6 KB)
Index: src/add-ons/kernel/busses/usb/uhci_hardware.h
===================================================================
--- src/add-ons/kernel/busses/usb/uhci_hardware.h (revision 21253)
+++ src/add-ons/kernel/busses/usb/uhci_hardware.h (working copy)
@@ -79,15 +79,18 @@
#define FRAMELIST_TERMINATE 0x1
#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)
typedef struct
{
// 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 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
addr_t this_phy; // A physical pointer to this address
void *link_log; // Pointer to the next logical TD/QT
@@ -139,8 +142,8 @@
typedef struct
{
// Hardware part
- addr_t link_phy; // Link to the next TD/QH
- addr_t element_phy; // Pointer to the first element in the queue
+ uint32 link_phy; // Link to the next TD/QH
+ uint32 element_phy; // Pointer to the first element in the queue
// Software part
addr_t this_phy; // The physical pointer to this address
void *link_log; // Pointer to the next logical TD/QH
Index: src/add-ons/kernel/busses/usb/uhci.cpp
===================================================================
--- src/add-ons/kernel/busses/usb/uhci.cpp (revision 21253)
+++ src/add-ons/kernel/busses/usb/uhci.cpp (working copy)
@@ -367,6 +367,7 @@
// 1: low speed control transfers
// 2: full speed control transfers
// 3: bulk transfers
+ // TODO: 4: bandwidth reclamation queue
fQueueCount = 4;
fQueues = new(std::nothrow) Queue *[fQueueCount];
if (!fQueues) {
@@ -389,9 +390,15 @@
// Make sure the last queue terminates
fQueues[fQueueCount - 1]->TerminateByStrayDescriptor();
- for (int32 i = 0; i < 1024; i++)
- fFrameList[i] = fQueues[0]->PhysicalAddress() | FRAMELIST_NEXT_IS_QH;
+ // Create the array that will keep bandwidth information
+ 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
fFinishTransfersSem = create_sem(0, "UHCI Finish Transfers");
if (fFinishTransfersSem < B_OK) {
@@ -437,6 +444,7 @@
delete fQueues[i];
delete [] fQueues;
+ delete [] fFrameBandwidth;
delete fRootHub;
delete_area(fFrameArea);
@@ -506,6 +514,10 @@
if (transfer->TransferPipe()->Type() & USB_OBJECT_CONTROL_PIPE)
return SubmitRequest(transfer);
+ // Process isochronous transfers
+ if (transfer->TransferPipe()->Type() & USB_OBJECT_ISO_PIPE)
+ return SubmitIsochronous(transfer);
+
uhci_td *firstDescriptor = NULL;
uhci_qh *transferQueue = NULL;
status_t result = CreateFilledTransfer(transfer, &firstDescriptor,
@@ -516,11 +528,9 @@
Queue *queue = NULL;
Pipe *pipe = transfer->TransferPipe();
if (pipe->Type() & USB_OBJECT_INTERRUPT_PIPE) {
- // use interrupt queue
- queue = fQueues[0];
+ queue = fQueues[UHCI_INTERRUPT_QUEUE];
} else {
- // use bulk queue
- queue = fQueues[3];
+ queue = fQueues[UHCI_BULK_QUEUE];
}
bool directionIn = (pipe->Direction() == Pipe::In);
@@ -634,11 +644,9 @@
Queue *queue = NULL;
if (pipe->Speed() == USB_SPEED_LOWSPEED) {
- // use the low speed control queue
- queue = fQueues[1];
+ queue = fQueues[UHCI_LOW_SPEED_CONTROL_QUEUE];
} else {
- // use the full speed control queue
- queue = fQueues[2];
+ queue = fQueues[UHCI_FULL_SPEED_CONTROL_QUEUE];
}
uhci_qh *transferQueue = CreateTransferQueue(setupDescriptor);
@@ -697,6 +705,26 @@
}
+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
UHCI::FinishThread(void *data)
{
Index: src/add-ons/kernel/busses/usb/uhci.h
===================================================================
--- src/add-ons/kernel/busses/usb/uhci.h (revision 21253)
+++ src/add-ons/kernel/busses/usb/uhci.h (working copy)
@@ -14,6 +14,12 @@
#include "uhci_hardware.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_module_info;
class UHCIRootHub;
@@ -70,6 +76,7 @@
virtual status_t SubmitTransfer(Transfer *transfer);
virtual status_t CancelQueuedTransfers(Pipe *pipe);
status_t SubmitRequest(Transfer *transfer);
+ status_t SubmitIsochronous(Transfer *transfer);
static status_t AddTo(Stack *stack);
@@ -149,6 +156,10 @@
area_id fFrameArea;
addr_t *fFrameList;
+ // fFrameBandwidth[n] holds the available bandwidth
+ // of the nth frame in microseconds
+ int32 *fFrameBandwidth;
+
// Queues
int32 fQueueCount;
Queue **fQueues;