Continuing work on the USB stack and UHCI driver.

* Moved the transfer descriptor management into the UHCI class
* Added locking to the driver and the queues
* Added service thread for finished transfers (to be implemented correctly)
* Cleaned up some headers and added myself as author

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18245 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz
2006-07-23 22:21:34 +00:00
parent edde06446f
commit 8ba81a767e
8 changed files with 687 additions and 361 deletions
@@ -3,6 +3,7 @@
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Michael Lotz <[email protected]>
* Niels S. Reedijk * Niels S. Reedijk
*/ */
@@ -212,7 +213,15 @@ BusManager::Stop()
status_t status_t
BusManager::SubmitTransfer(Transfer *transfer, bigtime_t timeout) BusManager::SubmitTransfer(Transfer *transfer)
{
// virtual function to be overridden
return B_ERROR;
}
status_t
BusManager::SubmitRequest(Transfer *transfer)
{ {
// virtual function to be overridden // virtual function to be overridden
return B_ERROR; return B_ERROR;
+8 -7
View File
@@ -94,13 +94,14 @@ status_t
ControlPipe::SendControlMessage(usb_request_data *command, void *data, ControlPipe::SendControlMessage(usb_request_data *command, void *data,
size_t dataLength, size_t *actualLength, bigtime_t timeout) size_t dataLength, size_t *actualLength, bigtime_t timeout)
{ {
// this method should build an usb packet (new class) with the needed data // builds an usb packet with the needed data
Transfer *transfer = new Transfer(this, true); Transfer transfer(this, true);
transfer->SetRequestData(command); transfer.SetRequestData(command);
transfer->SetBuffer((uint8 *)data); transfer.SetBuffer((uint8 *)data);
transfer->SetBufferLength(dataLength); transfer.SetBufferLength(dataLength);
transfer->SetActualLength(actualLength); transfer.SetActualLength(actualLength);
return fBus->SubmitTransfer(transfer, timeout); fBus->SubmitTransfer(&transfer);
return transfer.WaitForFinish();
} }
@@ -15,10 +15,10 @@ Transfer::Transfer(Pipe *pipe, bool synchronous)
fBuffer = NULL; fBuffer = NULL;
fBufferLength = 0; fBufferLength = 0;
fActualLength = NULL; fActualLength = NULL;
fTimeout = 0; fStatus = B_NO_INIT;
fStatus = B_ERROR;
fSem = -1; fSem = -1;
fHostPrivate = NULL; fHostPrivate = NULL;
fCallback = NULL;
if (synchronous) { if (synchronous) {
fSem = create_sem(0, "USB Transfer"); fSem = create_sem(0, "USB Transfer");
@@ -63,9 +63,10 @@ Transfer::SetActualLength(size_t *actualLength)
void void
Transfer::SetCallbackFunction(usb_callback_func callback) Transfer::SetCallbackFunction(usb_callback_func callback, void *cookie)
{ {
fCallback = callback; fCallback = callback;
fCallbackCookie = cookie;
} }
@@ -76,26 +77,32 @@ Transfer::SetHostPrivate(hostcontroller_priv *priv)
} }
void status_t
Transfer::WaitForFinish() Transfer::WaitForFinish()
{ {
if (fSem > B_OK) if (fSem < B_OK)
acquire_sem(fSem); return fStatus;
// ToDo: and otherwise?
status_t result = B_OK;
result = acquire_sem(fSem);
if (result < B_OK)
return result;
return fStatus;
} }
void void
Transfer::TransferDone() Transfer::Finished(status_t result)
{ {
fStatus = result;
// If we are synchronous, release the sem
if (fSem > B_OK) if (fSem > B_OK)
release_sem(fSem); release_sem(fSem);
}
// ToDo: implement callback correctly
void Transfer::Finish() if (fCallback)
{ fCallback(fCallbackCookie, fStatus, fBuffer, 0);
// If we are synchronous, release a sem
if (fSem > B_OK)
release_sem(fSem);
} }
+10 -7
View File
@@ -3,6 +3,7 @@
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Michael Lotz <[email protected]>
* Niels S. Reedijk * Niels S. Reedijk
*/ */
@@ -139,8 +140,8 @@ virtual status_t InitCheck();
virtual status_t Start(); virtual status_t Start();
virtual status_t Stop(); virtual status_t Stop();
virtual status_t SubmitTransfer(Transfer *transfer, virtual status_t SubmitTransfer(Transfer *transfer);
bigtime_t timeout = 0); virtual status_t SubmitRequest(Transfer *transfer);
protected: protected:
void SetRootHub(Hub *hub) { fRootHub = hub; }; void SetRootHub(Hub *hub) { fRootHub = hub; };
@@ -263,11 +264,12 @@ public:
void SetHostPrivate(hostcontroller_priv *priv); void SetHostPrivate(hostcontroller_priv *priv);
hostcontroller_priv *HostPrivate() { return fHostPrivate; }; hostcontroller_priv *HostPrivate() { return fHostPrivate; };
void SetCallbackFunction(usb_callback_func callback); void SetCallbackFunction(
usb_callback_func callback,
void *cookie);
void WaitForFinish(); status_t WaitForFinish();
void TransferDone(); void Finished(status_t result);
void Finish();
private: private:
// Data that is related to the transfer // Data that is related to the transfer
@@ -275,10 +277,11 @@ private:
uint8 *fBuffer; uint8 *fBuffer;
size_t fBufferLength; size_t fBufferLength;
size_t *fActualLength; size_t *fActualLength;
bigtime_t fTimeout;
status_t fStatus; status_t fStatus;
usb_callback_func fCallback; usb_callback_func fCallback;
void *fCallbackCookie;
sem_id fSem; sem_id fSem;
hostcontroller_priv *fHostPrivate; hostcontroller_priv *fHostPrivate;
File diff suppressed because it is too large Load Diff
+75 -13
View File
@@ -3,6 +3,7 @@
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Michael Lotz <[email protected]>
* Niels S. Reedijk * Niels S. Reedijk
*/ */
@@ -22,15 +23,17 @@ public:
Queue(Stack *stack); Queue(Stack *stack);
~Queue(); ~Queue();
bool Lock();
void Unlock();
status_t InitCheck(); status_t InitCheck();
status_t LinkTo(Queue *other); status_t LinkTo(Queue *other);
status_t TerminateByStrayDescriptor(); status_t TerminateByStrayDescriptor();
status_t AppendDescriptor(uhci_td *descriptor); status_t AppendDescriptor(uhci_td *descriptor);
status_t AddRequest(Transfer *transfer, status_t RemoveDescriptors(uhci_td *firstDescriptor,
bigtime_t timeout); uhci_td *lastDescriptor);
status_t RemoveInactiveDescriptors();
addr_t PhysicalAddress(); addr_t PhysicalAddress();
@@ -42,32 +45,83 @@ private:
uhci_qh *fQueueHead; uhci_qh *fQueueHead;
uhci_td *fStrayDescriptor; uhci_td *fStrayDescriptor;
uhci_td *fQueueTop; uhci_td *fQueueTop;
// Benaphore locking
sem_id fLockSem;
int32 fLockAtom;
}; };
typedef struct transfer_data_s {
Transfer *transfer;
Queue *queue;
uhci_td *first_descriptor;
uhci_td *data_descriptor;
uhci_td *last_descriptor;
bool incoming;
transfer_data_s *link;
} transfer_data;
class UHCI : public BusManager { class UHCI : public BusManager {
public: public:
UHCI(pci_info *info, Stack *stack); UHCI(pci_info *info, Stack *stack);
~UHCI();
bool Lock();
void Unlock();
status_t Start(); status_t Start();
status_t SubmitTransfer(Transfer *transfer, virtual status_t SubmitTransfer(Transfer *transfer);
bigtime_t timeout = 0); virtual status_t SubmitRequest(Transfer *transfer);
static bool AddTo(Stack &stack); static bool AddTo(Stack &stack);
void GlobalReset(); // Port operations
status_t ResetController();
// port operations
uint16 PortStatus(int32 index); uint16 PortStatus(int32 index);
status_t SetPortStatus(int32 index, uint16 status); status_t SetPortStatus(int32 index, uint16 status);
status_t ResetPort(int32 index); status_t ResetPort(int32 index);
private: private:
// Utility functions // Controller resets
void GlobalReset();
status_t ControllerReset();
// Interrupt functions
static int32 InterruptHandler(void *data); static int32 InterruptHandler(void *data);
int32 Interrupt(); int32 Interrupt();
// Transfer functions
status_t AddPendingTransfer(Transfer *transfer,
Queue *queue,
uhci_td *firstDescriptor,
uhci_td *dataDescriptor,
uhci_td *lastDescriptor,
bool directionIn);
static int32 FinishThread(void *data);
void FinishTransfers();
// Descriptor functions
uhci_td *CreateDescriptor(Pipe *pipe,
uint8 direction,
int32 bufferSizeToAllocate);
status_t CreateDescriptorChain(Pipe *pipe,
uhci_td **firstDescriptor,
uhci_td **lastDescriptor,
uint8 direction,
int32 bufferSizeToAllocate);
void FreeDescriptor(uhci_td *descriptor);
void FreeDescriptorChain(uhci_td *topDescriptor);
void LinkDescriptors(uhci_td *first,
uhci_td *second);
size_t WriteDescriptorChain(uhci_td *topDescriptor,
const uint8 *buffer, int32 bufferSize);
size_t ReadDescriptorChain(uhci_td *topDescriptor,
uint8 *buffer, int32 bufferSize);
// Register functions // Register functions
inline void WriteReg16(uint32 reg, uint16 value); inline void WriteReg16(uint32 reg, uint16 value);
inline void WriteReg32(uint32 reg, uint32 value); inline void WriteReg32(uint32 reg, uint32 value);
@@ -80,16 +134,24 @@ static pci_module_info *sPCIModule;
pci_info *fPCIInfo; pci_info *fPCIInfo;
Stack *fStack; Stack *fStack;
// Benaphore locking
sem_id fLockSem;
int32 fLockAtom;
// Frame list memory // Frame list memory
area_id fFrameArea; area_id fFrameArea;
addr_t *fFrameList; addr_t *fFrameList;
// Queues // Queues
int32 fQueueCount; int32 fQueueCount;
Queue *fQueues[]; Queue **fQueues;
// Maintain a list of transfers // Maintain a linked list of transfers
Vector<Transfer *> fTransfers; transfer_data *fFirstTransfer;
transfer_data *fLastTransfer;
bool fFinishTransfers;
thread_id fFinishThread;
bool fStopFinishThread;
// Root hub // Root hub
UHCIRootHub *fRootHub; UHCIRootHub *fRootHub;
+8 -20
View File
@@ -1,23 +1,11 @@
//------------------------------------------------------------------------------ /*
// Copyright (c) 2003-2004, Niels S. Reedijk * Copyright 2004-2006, Haiku Inc. All rights reserved.
// * Distributed under the terms of the MIT License.
// Permission is hereby granted, free of charge, to any person obtaining a *
// copy of this software and associated documentation files (the "Software"), * Authors:
// to deal in the Software without restriction, including without limitation * Michael Lotz <[email protected]>
// the rights to use, copy, modify, merge, publish, distribute, sublicense, * Niels S. Reedijk
// and/or sell copies of the Software, and to permit persons to whom the */
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef UHCI_HARDWARE_H #ifndef UHCI_HARDWARE_H
#define UHCI_HARDWARE_H #define UHCI_HARDWARE_H
+2 -3
View File
@@ -3,6 +3,7 @@
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Michael Lotz <[email protected]>
* Niels S. Reedijk * Niels S. Reedijk
*/ */
@@ -247,9 +248,7 @@ UHCIRootHub::SubmitTransfer(Transfer *transfer)
break; break;
} }
// Clean up the transfer - we own it, so we clean it up transfer->Finished(result);
transfer->Finish();
delete transfer;
return result; return result;
} }