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:
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user