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

View File

@ -3,6 +3,7 @@
* Distributed under the terms of the MIT License.
*
* Authors:
* Michael Lotz <mmlr@mlotz.ch>
* Niels S. Reedijk
*/
@ -212,7 +213,15 @@ BusManager::Stop()
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
return B_ERROR;

View File

@ -94,13 +94,14 @@ status_t
ControlPipe::SendControlMessage(usb_request_data *command, void *data,
size_t dataLength, size_t *actualLength, bigtime_t timeout)
{
// this method should build an usb packet (new class) with the needed data
Transfer *transfer = new Transfer(this, true);
// builds an usb packet with the needed data
Transfer transfer(this, true);
transfer->SetRequestData(command);
transfer->SetBuffer((uint8 *)data);
transfer->SetBufferLength(dataLength);
transfer->SetActualLength(actualLength);
transfer.SetRequestData(command);
transfer.SetBuffer((uint8 *)data);
transfer.SetBufferLength(dataLength);
transfer.SetActualLength(actualLength);
return fBus->SubmitTransfer(transfer, timeout);
fBus->SubmitTransfer(&transfer);
return transfer.WaitForFinish();
}

View File

@ -15,10 +15,10 @@ Transfer::Transfer(Pipe *pipe, bool synchronous)
fBuffer = NULL;
fBufferLength = 0;
fActualLength = NULL;
fTimeout = 0;
fStatus = B_ERROR;
fStatus = B_NO_INIT;
fSem = -1;
fHostPrivate = NULL;
fCallback = NULL;
if (synchronous) {
fSem = create_sem(0, "USB Transfer");
@ -63,9 +63,10 @@ Transfer::SetActualLength(size_t *actualLength)
void
Transfer::SetCallbackFunction(usb_callback_func callback)
Transfer::SetCallbackFunction(usb_callback_func callback, void *cookie)
{
fCallback = callback;
fCallbackCookie = cookie;
}
@ -76,26 +77,32 @@ Transfer::SetHostPrivate(hostcontroller_priv *priv)
}
void
status_t
Transfer::WaitForFinish()
{
if (fSem > B_OK)
acquire_sem(fSem);
// ToDo: and otherwise?
if (fSem < B_OK)
return fStatus;
status_t result = B_OK;
result = acquire_sem(fSem);
if (result < B_OK)
return result;
return fStatus;
}
void
Transfer::TransferDone()
Transfer::Finished(status_t result)
{
fStatus = result;
// If we are synchronous, release the sem
if (fSem > B_OK)
release_sem(fSem);
}
void Transfer::Finish()
{
// If we are synchronous, release a sem
if (fSem > B_OK)
release_sem(fSem);
// ToDo: implement callback correctly
if (fCallback)
fCallback(fCallbackCookie, fStatus, fBuffer, 0);
}

View File

@ -3,6 +3,7 @@
* Distributed under the terms of the MIT License.
*
* Authors:
* Michael Lotz <mmlr@mlotz.ch>
* Niels S. Reedijk
*/
@ -139,8 +140,8 @@ virtual status_t InitCheck();
virtual status_t Start();
virtual status_t Stop();
virtual status_t SubmitTransfer(Transfer *transfer,
bigtime_t timeout = 0);
virtual status_t SubmitTransfer(Transfer *transfer);
virtual status_t SubmitRequest(Transfer *transfer);
protected:
void SetRootHub(Hub *hub) { fRootHub = hub; };
@ -263,11 +264,12 @@ public:
void SetHostPrivate(hostcontroller_priv *priv);
hostcontroller_priv *HostPrivate() { return fHostPrivate; };
void SetCallbackFunction(usb_callback_func callback);
void SetCallbackFunction(
usb_callback_func callback,
void *cookie);
void WaitForFinish();
void TransferDone();
void Finish();
status_t WaitForFinish();
void Finished(status_t result);
private:
// Data that is related to the transfer
@ -275,10 +277,11 @@ private:
uint8 *fBuffer;
size_t fBufferLength;
size_t *fActualLength;
bigtime_t fTimeout;
status_t fStatus;
usb_callback_func fCallback;
void *fCallbackCookie;
sem_id fSem;
hostcontroller_priv *fHostPrivate;

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,7 @@
* Distributed under the terms of the MIT License.
*
* Authors:
* Michael Lotz <mmlr@mlotz.ch>
* Niels S. Reedijk
*/
@ -22,15 +23,17 @@ public:
Queue(Stack *stack);
~Queue();
bool Lock();
void Unlock();
status_t InitCheck();
status_t LinkTo(Queue *other);
status_t TerminateByStrayDescriptor();
status_t AppendDescriptor(uhci_td *descriptor);
status_t AddRequest(Transfer *transfer,
bigtime_t timeout);
status_t RemoveInactiveDescriptors();
status_t RemoveDescriptors(uhci_td *firstDescriptor,
uhci_td *lastDescriptor);
addr_t PhysicalAddress();
@ -42,32 +45,83 @@ private:
uhci_qh *fQueueHead;
uhci_td *fStrayDescriptor;
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 {
public:
UHCI(pci_info *info, Stack *stack);
~UHCI();
bool Lock();
void Unlock();
status_t Start();
status_t SubmitTransfer(Transfer *transfer,
bigtime_t timeout = 0);
virtual status_t SubmitTransfer(Transfer *transfer);
virtual status_t SubmitRequest(Transfer *transfer);
static bool AddTo(Stack &stack);
void GlobalReset();
status_t ResetController();
// port operations
// Port operations
uint16 PortStatus(int32 index);
status_t SetPortStatus(int32 index, uint16 status);
status_t ResetPort(int32 index);
private:
// Utility functions
// Controller resets
void GlobalReset();
status_t ControllerReset();
// Interrupt functions
static int32 InterruptHandler(void *data);
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
inline void WriteReg16(uint32 reg, uint16 value);
inline void WriteReg32(uint32 reg, uint32 value);
@ -80,16 +134,24 @@ static pci_module_info *sPCIModule;
pci_info *fPCIInfo;
Stack *fStack;
// Benaphore locking
sem_id fLockSem;
int32 fLockAtom;
// Frame list memory
area_id fFrameArea;
addr_t *fFrameList;
// Queues
int32 fQueueCount;
Queue *fQueues[];
Queue **fQueues;
// Maintain a list of transfers
Vector<Transfer *> fTransfers;
// Maintain a linked list of transfers
transfer_data *fFirstTransfer;
transfer_data *fLastTransfer;
bool fFinishTransfers;
thread_id fFinishThread;
bool fStopFinishThread;
// Root hub
UHCIRootHub *fRootHub;

View File

@ -1,23 +1,11 @@
//------------------------------------------------------------------------------
// Copyright (c) 2003-2004, Niels S. Reedijk
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// 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.
/*
* Copyright 2004-2006, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Michael Lotz <mmlr@mlotz.ch>
* Niels S. Reedijk
*/
#ifndef UHCI_HARDWARE_H
#define UHCI_HARDWARE_H

View File

@ -3,6 +3,7 @@
* Distributed under the terms of the MIT License.
*
* Authors:
* Michael Lotz <mmlr@mlotz.ch>
* Niels S. Reedijk
*/
@ -247,9 +248,7 @@ UHCIRootHub::SubmitTransfer(Transfer *transfer)
break;
}
// Clean up the transfer - we own it, so we clean it up
transfer->Finish();
delete transfer;
transfer->Finished(result);
return result;
}