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:
parent
edde06446f
commit
8ba81a767e
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user