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;