* Make the operational register memory a uint8 * instead of a uint32 * so the
driver has at least a chance of working (it previously always used wrong offsets for register access). * Remove the hash approach for now (I'm going to explore a few other ways of doing that first). * Reorder some stuff and check for errors in some more places. * More cleanup (mostly whitespace again). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25538 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
2b9cc6d877
commit
20bbb1bf28
@ -77,8 +77,6 @@ OHCI::OHCI(pci_info *info, Stack *stack)
|
|||||||
fFinishTransfersSem(-1),
|
fFinishTransfersSem(-1),
|
||||||
fFinishThread(-1),
|
fFinishThread(-1),
|
||||||
fStopFinishThread(false),
|
fStopFinishThread(false),
|
||||||
fHashGenericTable(NULL),
|
|
||||||
fHashIsochronousTable(NULL),
|
|
||||||
fRootHub(NULL),
|
fRootHub(NULL),
|
||||||
fRootHubAddress(0),
|
fRootHubAddress(0),
|
||||||
fPortCount(0)
|
fPortCount(0)
|
||||||
@ -138,35 +136,17 @@ OHCI::OHCI(pci_info *info, Stack *stack)
|
|||||||
|
|
||||||
memset(fHcca, 0, sizeof(ohci_hcca));
|
memset(fHcca, 0, sizeof(ohci_hcca));
|
||||||
|
|
||||||
// Allocate hash tables
|
|
||||||
fHashGenericTable = (ohci_general_td **)
|
|
||||||
malloc(sizeof(ohci_general_td *) * OHCI_HASH_SIZE);
|
|
||||||
if (fHashGenericTable == NULL) {
|
|
||||||
TRACE_ERROR(("usb_ohci: unable to allocate hash generic table\n"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
fHashIsochronousTable = (ohci_isochronous_td **)
|
|
||||||
malloc(sizeof(ohci_isochronous_td *) * OHCI_HASH_SIZE);
|
|
||||||
if (fHashIsochronousTable == NULL) {
|
|
||||||
free(fHashGenericTable);
|
|
||||||
TRACE_ERROR(("usb_ohci: unable to allocate hash isochronous table\n"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set Up Host controller
|
// Set Up Host controller
|
||||||
// Dummy endpoints
|
// Dummy endpoints
|
||||||
fDummyControl = _AllocateEndpoint();
|
fDummyControl = _AllocateEndpoint();
|
||||||
if (!fDummyControl)
|
if (!fDummyControl)
|
||||||
return;
|
return;
|
||||||
fDummyControl->flags |= OHCI_ENDPOINT_SKIP;
|
|
||||||
|
|
||||||
fDummyBulk = _AllocateEndpoint();
|
fDummyBulk = _AllocateEndpoint();
|
||||||
if (!fDummyBulk) {
|
if (!fDummyBulk) {
|
||||||
_FreeEndpoint(fDummyControl);
|
_FreeEndpoint(fDummyControl);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fDummyBulk->flags |= OHCI_ENDPOINT_SKIP;
|
|
||||||
|
|
||||||
fDummyIsochronous = _AllocateEndpoint();
|
fDummyIsochronous = _AllocateEndpoint();
|
||||||
if (!fDummyIsochronous) {
|
if (!fDummyIsochronous) {
|
||||||
@ -174,7 +154,6 @@ OHCI::OHCI(pci_info *info, Stack *stack)
|
|||||||
_FreeEndpoint(fDummyBulk);
|
_FreeEndpoint(fDummyBulk);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fDummyIsochronous->flags |= OHCI_ENDPOINT_SKIP;
|
|
||||||
|
|
||||||
// Static endpoints that get linked in the HCCA
|
// Static endpoints that get linked in the HCCA
|
||||||
fInterruptEndpoints = new(std::nothrow)
|
fInterruptEndpoints = new(std::nothrow)
|
||||||
@ -202,7 +181,6 @@ OHCI::OHCI(pci_info *info, Stack *stack)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Make them point all to the dummy isochronous endpoint
|
// Make them point all to the dummy isochronous endpoint
|
||||||
fInterruptEndpoints[i]->flags |= OHCI_ENDPOINT_SKIP;
|
|
||||||
fInterruptEndpoints[i]->next_physical_endpoint
|
fInterruptEndpoints[i]->next_physical_endpoint
|
||||||
= fDummyIsochronous->physical_address;
|
= fDummyIsochronous->physical_address;
|
||||||
}
|
}
|
||||||
@ -341,9 +319,6 @@ OHCI::~OHCI()
|
|||||||
if (fRegisterArea >= B_OK)
|
if (fRegisterArea >= B_OK)
|
||||||
delete_area(fRegisterArea);
|
delete_area(fRegisterArea);
|
||||||
|
|
||||||
free(fHashGenericTable);
|
|
||||||
free(fHashIsochronousTable);
|
|
||||||
|
|
||||||
_FreeEndpoint(fDummyControl);
|
_FreeEndpoint(fDummyControl);
|
||||||
_FreeEndpoint(fDummyBulk);
|
_FreeEndpoint(fDummyBulk);
|
||||||
_FreeEndpoint(fDummyIsochronous);
|
_FreeEndpoint(fDummyIsochronous);
|
||||||
@ -365,9 +340,11 @@ OHCI::Start()
|
|||||||
{
|
{
|
||||||
TRACE(("usb_ohci: starting OHCI Host Controller\n"));
|
TRACE(("usb_ohci: starting OHCI Host Controller\n"));
|
||||||
|
|
||||||
if ((_ReadReg(OHCI_CONTROL) & OHCI_HC_FUNCTIONAL_STATE_MASK)
|
uint32 control = _ReadReg(OHCI_CONTROL);
|
||||||
|
if ((control & OHCI_HC_FUNCTIONAL_STATE_MASK)
|
||||||
!= OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL) {
|
!= OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL) {
|
||||||
TRACE_ERROR(("usb_ohci: Controller not started!\n"));
|
TRACE_ERROR(("usb_ohci: Controller not started (0x%08lx)!\n",
|
||||||
|
control));
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
} else
|
} else
|
||||||
TRACE(("usb_ohci: Controller is operational!\n"));
|
TRACE(("usb_ohci: Controller is operational!\n"));
|
||||||
@ -578,7 +555,7 @@ OHCI::AddTo(Stack *stack)
|
|||||||
status_t
|
status_t
|
||||||
OHCI::GetPortStatus(uint8 index, usb_port_status *status)
|
OHCI::GetPortStatus(uint8 index, usb_port_status *status)
|
||||||
{
|
{
|
||||||
TRACE(("usb_ohci::%s(%ud, )\n", __FUNCTION__, index));
|
TRACE(("usb_ohci: get port status %ud\n", index));
|
||||||
if (index >= fPortCount)
|
if (index >= fPortCount)
|
||||||
return B_BAD_INDEX;
|
return B_BAD_INDEX;
|
||||||
|
|
||||||
@ -857,7 +834,7 @@ OHCI::_FinishTransfers()
|
|||||||
ohci_isochronous_td *isoCurrent = NULL;
|
ohci_isochronous_td *isoCurrent = NULL;
|
||||||
ohci_isochronous_td *isoTop = NULL;
|
ohci_isochronous_td *isoTop = NULL;
|
||||||
while (doneList != 0) {
|
while (doneList != 0) {
|
||||||
current = _FindDescriptorInHash(doneList);
|
current = NULL; //_FindDescriptorInHash(doneList);
|
||||||
if (current != NULL) {
|
if (current != NULL) {
|
||||||
doneList = current->next_physical_descriptor;
|
doneList = current->next_physical_descriptor;
|
||||||
current->next_done_descriptor = (void *)top;
|
current->next_done_descriptor = (void *)top;
|
||||||
@ -865,7 +842,7 @@ OHCI::_FinishTransfers()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
isoCurrent = _FindIsoDescriptorInHash(doneList);
|
isoCurrent = NULL; //_FindIsoDescriptorInHash(doneList);
|
||||||
if (isoCurrent != NULL) {
|
if (isoCurrent != NULL) {
|
||||||
doneList = isoCurrent->next_physical_descriptor;
|
doneList = isoCurrent->next_physical_descriptor;
|
||||||
isoCurrent->next_done_descriptor = (void *)isoTop;
|
isoCurrent->next_done_descriptor = (void *)isoTop;
|
||||||
@ -1135,11 +1112,14 @@ OHCI::_AllocateEndpoint()
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
endpoint->flags = OHCI_ENDPOINT_SKIP;
|
||||||
endpoint->physical_address = (addr_t)physicalAddress;
|
endpoint->physical_address = (addr_t)physicalAddress;
|
||||||
endpoint->head_logical_descriptor = NULL;
|
endpoint->head_logical_descriptor = NULL;
|
||||||
endpoint->head_physical_descriptor = 0;
|
endpoint->head_physical_descriptor = 0;
|
||||||
endpoint->tail_logical_descriptor = NULL;
|
endpoint->tail_logical_descriptor = NULL;
|
||||||
endpoint->tail_physical_descriptor = 0;
|
endpoint->tail_physical_descriptor = 0;
|
||||||
|
endpoint->next_logical_endpoint = NULL;
|
||||||
|
endpoint->next_physical_endpoint = 0;
|
||||||
return endpoint;
|
return endpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1214,27 +1194,32 @@ OHCI::_InsertEndpointForPipe(Pipe *pipe)
|
|||||||
endpoint->flags = flags;
|
endpoint->flags = flags;
|
||||||
|
|
||||||
// Add the endpoint to the appropriate list
|
// Add the endpoint to the appropriate list
|
||||||
ohci_endpoint_descriptor *head = NULL;
|
|
||||||
uint32 type = pipe->Type();
|
uint32 type = pipe->Type();
|
||||||
|
ohci_endpoint_descriptor *head = NULL;
|
||||||
if (type & USB_OBJECT_CONTROL_PIPE)
|
if (type & USB_OBJECT_CONTROL_PIPE)
|
||||||
head = fDummyControl;
|
head = fDummyControl;
|
||||||
else if (type & USB_OBJECT_BULK_PIPE)
|
else if (type & USB_OBJECT_BULK_PIPE)
|
||||||
head = fDummyBulk;
|
head = fDummyBulk;
|
||||||
else if (type & USB_OBJECT_INTERRUPT_PIPE)
|
else if (type & USB_OBJECT_INTERRUPT_PIPE)
|
||||||
head = _FindInterruptEndpoint(pipe->Interval());
|
head = _FindInterruptEndpoint(pipe->Interval());
|
||||||
else if (type & USB_OBJECT_ISO_PIPE) {
|
else if (type & USB_OBJECT_ISO_PIPE)
|
||||||
// Set the isochronous bit format
|
|
||||||
endpoint->flags |= OHCI_ENDPOINT_ISOCHRONOUS_FORMAT;
|
|
||||||
head = fDummyIsochronous;
|
head = fDummyIsochronous;
|
||||||
} else {
|
else
|
||||||
TRACE_ERROR(("usb_ohci: unknown pipe type\n"));
|
TRACE_ERROR(("usb_ohci: unknown pipe type\n"));
|
||||||
|
|
||||||
|
if (head == NULL) {
|
||||||
|
TRACE_ERROR(("usb_ohci: no list found for endpoint\n"));
|
||||||
_FreeEndpoint(endpoint);
|
_FreeEndpoint(endpoint);
|
||||||
return B_BAD_VALUE;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create (necessary) dummy descriptor
|
// Create (necessary) dummy descriptor
|
||||||
if (pipe->Type() & USB_OBJECT_ISO_PIPE) {
|
if (pipe->Type() & USB_OBJECT_ISO_PIPE) {
|
||||||
|
// Set the isochronous bit format
|
||||||
|
endpoint->flags |= OHCI_ENDPOINT_ISOCHRONOUS_FORMAT;
|
||||||
// TODO
|
// TODO
|
||||||
|
_FreeEndpoint(endpoint);
|
||||||
|
return B_ERROR;
|
||||||
} else {
|
} else {
|
||||||
ohci_general_td *dummy = _CreateGeneralDescriptor(0);
|
ohci_general_td *dummy = _CreateGeneralDescriptor(0);
|
||||||
dummy->next_logical_descriptor = NULL;
|
dummy->next_logical_descriptor = NULL;
|
||||||
@ -1245,15 +1230,23 @@ OHCI::_InsertEndpointForPipe(Pipe *pipe)
|
|||||||
endpoint->tail_physical_descriptor = dummy->physical_address;
|
endpoint->tail_physical_descriptor = dummy->physical_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Change lock lo LockEndpoint()
|
if (!Lock()) {
|
||||||
Lock();
|
if (endpoint->head_logical_descriptor) {
|
||||||
|
_FreeGeneralDescriptor(
|
||||||
|
(ohci_general_td *)endpoint->head_logical_descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
_FreeEndpoint(endpoint);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
pipe->SetControllerCookie((void *)endpoint);
|
pipe->SetControllerCookie((void *)endpoint);
|
||||||
endpoint->next_logical_endpoint = head->next_logical_endpoint;
|
endpoint->next_logical_endpoint = head->next_logical_endpoint;
|
||||||
endpoint->next_physical_endpoint = head->next_physical_endpoint;
|
endpoint->next_physical_endpoint = head->next_physical_endpoint;
|
||||||
head->next_logical_endpoint = (void *)endpoint;
|
head->next_logical_endpoint = (void *)endpoint;
|
||||||
head->next_physical_endpoint = (uint32)endpoint->physical_address;
|
head->next_physical_endpoint = (uint32)endpoint->physical_address;
|
||||||
Unlock();
|
|
||||||
|
|
||||||
|
Unlock();
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1422,50 +1415,6 @@ OHCI::_FreeIsochronousDescriptor(ohci_isochronous_td *descriptor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
OHCI::_AddDescriptorToHash(ohci_general_td *descriptor)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
OHCI::_RemoveDescriptorFromHash(ohci_general_td *descriptor)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ohci_general_td*
|
|
||||||
OHCI::_FindDescriptorInHash(uint32 physicalAddress)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
OHCI::_AddIsoDescriptorToHash(ohci_isochronous_td *descriptor)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
OHCI::_RemoveIsoDescriptorFromHash(ohci_isochronous_td *descriptor)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ohci_isochronous_td*
|
|
||||||
OHCI::_FindIsoDescriptorInHash(uint32 physicalAddress)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
OHCI::_WriteReg(uint32 reg, uint32 value)
|
OHCI::_WriteReg(uint32 reg, uint32 value)
|
||||||
{
|
{
|
||||||
|
@ -3,8 +3,9 @@
|
|||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* Jan-Rixt Van Hoye
|
* Jan-Rixt Van Hoye
|
||||||
* Salvatore Benedetto <salvatore.benedetto@gmail.com>
|
* Salvatore Benedetto <salvatore.benedetto@gmail.com>
|
||||||
|
* Michael Lotz <mmlr@mlotz.ch>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef OHCI_H
|
#ifndef OHCI_H
|
||||||
@ -28,49 +29,14 @@ typedef struct transfer_data_s {
|
|||||||
transfer_data_s *link;
|
transfer_data_s *link;
|
||||||
} transfer_data;
|
} transfer_data;
|
||||||
|
|
||||||
// --------------------------------------
|
|
||||||
// OHCI:: Software isonchronous
|
|
||||||
// transfer descriptor
|
|
||||||
// --------------------------------------
|
|
||||||
typedef struct hcd_soft_itransfer
|
|
||||||
{
|
|
||||||
ohci_isochronous_td itd;
|
|
||||||
struct hcd_soft_itransfer *nextitd; // mirrors nexttd in ITD
|
|
||||||
struct hcd_soft_itransfer *dnext; // next in done list
|
|
||||||
addr_t physaddr; // physical address to the host controller isonchronous transfer
|
|
||||||
//LIST_ENTRY(hcd_soft_itransfer) hnext;
|
|
||||||
uint16 flags; // flags
|
|
||||||
#ifdef DIAGNOSTIC
|
|
||||||
char isdone; // is the transfer done?
|
|
||||||
#endif
|
|
||||||
}hcd_soft_itransfer;
|
|
||||||
|
|
||||||
#define OHCI_SITD_SIZE ((sizeof (struct hcd_soft_itransfer) + OHCI_ITD_ALIGN - 1) / OHCI_ITD_ALIGN * OHCI_ITD_ALIGN)
|
class OHCI : public BusManager {
|
||||||
#define OHCI_SITD_CHUNK 64
|
|
||||||
|
|
||||||
#define OHCI_NUMBER_OF_ENDPOINTS (2 * OHCI_NUMBER_OF_INTERRUPTS - 1)
|
|
||||||
|
|
||||||
// Note: the controller returns only the physical
|
|
||||||
// address of the first processed descriptor of
|
|
||||||
// an heterogeneous list (isochronous + generic). Unfortunately
|
|
||||||
// we don't have a way to know whether the descriptor is
|
|
||||||
// generic or isochronous, either way to translate the address back to
|
|
||||||
// kernel address. The physical address is used as the hash value.
|
|
||||||
// (Kindly borrowed from *BSD)
|
|
||||||
|
|
||||||
#define OHCI_HASH_SIZE 128
|
|
||||||
#define HASH(x) (((x) >> 4) % OHCI_HASH_SIZE)
|
|
||||||
|
|
||||||
|
|
||||||
class OHCI : public BusManager
|
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
OHCI(pci_info *info, Stack *stack);
|
OHCI(pci_info *info, Stack *stack);
|
||||||
~OHCI();
|
~OHCI();
|
||||||
|
|
||||||
status_t Start();
|
status_t Start();
|
||||||
virtual status_t SubmitTransfer(Transfer *transfer);
|
virtual status_t SubmitTransfer(Transfer *transfer);
|
||||||
virtual status_t CancelQueuedTransfers(Pipe *pipe,
|
virtual status_t CancelQueuedTransfers(Pipe *pipe,
|
||||||
bool force);
|
bool force);
|
||||||
|
|
||||||
@ -80,8 +46,8 @@ virtual status_t NotifyPipeChange(Pipe *pipe,
|
|||||||
static status_t AddTo(Stack *stack);
|
static status_t AddTo(Stack *stack);
|
||||||
|
|
||||||
// Port operations
|
// Port operations
|
||||||
uint8 PortCount() { return fPortCount; };
|
uint8 PortCount() { return fPortCount; };
|
||||||
status_t GetPortStatus(uint8 index,
|
status_t GetPortStatus(uint8 index,
|
||||||
usb_port_status *status);
|
usb_port_status *status);
|
||||||
status_t SetPortFeature(uint8 index, uint16 feature);
|
status_t SetPortFeature(uint8 index, uint16 feature);
|
||||||
status_t ClearPortFeature(uint8 index, uint16 feature);
|
status_t ClearPortFeature(uint8 index, uint16 feature);
|
||||||
@ -152,31 +118,15 @@ static int32 _FinishThread(void *data);
|
|||||||
void _FreeIsochronousDescriptor(
|
void _FreeIsochronousDescriptor(
|
||||||
ohci_isochronous_td *descriptor);
|
ohci_isochronous_td *descriptor);
|
||||||
|
|
||||||
// Hash tables related methods
|
|
||||||
void _AddDescriptorToHash(
|
|
||||||
ohci_general_td *descriptor);
|
|
||||||
void _RemoveDescriptorFromHash(
|
|
||||||
ohci_general_td *descriptor);
|
|
||||||
ohci_general_td *_FindDescriptorInHash(
|
|
||||||
uint32 physicalAddress);
|
|
||||||
|
|
||||||
void _AddIsoDescriptorToHash(
|
|
||||||
ohci_isochronous_td *descriptor);
|
|
||||||
void _RemoveIsoDescriptorFromHash(
|
|
||||||
ohci_isochronous_td *descriptor);
|
|
||||||
ohci_isochronous_td *_FindIsoDescriptorInHash(
|
|
||||||
uint32 physicalAddress);
|
|
||||||
|
|
||||||
|
|
||||||
// Register functions
|
// Register functions
|
||||||
inline void _WriteReg(uint32 reg, uint32 value);
|
inline void _WriteReg(uint32 reg, uint32 value);
|
||||||
inline uint32 _ReadReg(uint32 reg);
|
inline uint32 _ReadReg(uint32 reg);
|
||||||
|
|
||||||
static pci_module_info *sPCIModule;
|
static pci_module_info *sPCIModule;
|
||||||
pci_info *fPCIInfo;
|
pci_info *fPCIInfo;
|
||||||
Stack *fStack;
|
Stack *fStack;
|
||||||
|
|
||||||
uint32 *fOperationalRegisters;
|
uint8 *fOperationalRegisters;
|
||||||
area_id fRegisterArea;
|
area_id fRegisterArea;
|
||||||
|
|
||||||
// Host Controller Communication Area related stuff
|
// Host Controller Communication Area related stuff
|
||||||
@ -196,12 +146,8 @@ static pci_module_info *sPCIModule;
|
|||||||
thread_id fFinishThread;
|
thread_id fFinishThread;
|
||||||
bool fStopFinishThread;
|
bool fStopFinishThread;
|
||||||
|
|
||||||
// Hash table
|
|
||||||
ohci_general_td **fHashGenericTable;
|
|
||||||
ohci_isochronous_td **fHashIsochronousTable;
|
|
||||||
|
|
||||||
// Root Hub
|
// Root Hub
|
||||||
OHCIRootHub *fRootHub;
|
OHCIRootHub *fRootHub;
|
||||||
uint8 fRootHubAddress;
|
uint8 fRootHubAddress;
|
||||||
|
|
||||||
// Port management
|
// Port management
|
||||||
@ -214,7 +160,7 @@ public:
|
|||||||
OHCIRootHub(Object *rootObject,
|
OHCIRootHub(Object *rootObject,
|
||||||
int8 deviceAddress);
|
int8 deviceAddress);
|
||||||
|
|
||||||
static status_t ProcessTransfer(OHCI *ohci,
|
static status_t ProcessTransfer(OHCI *ohci,
|
||||||
Transfer *transfer);
|
Transfer *transfer);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
* Authors:
|
* Authors:
|
||||||
* Jan-Rixt Van Hoye
|
* Jan-Rixt Van Hoye
|
||||||
* Salvatore Benedetto <salvatore.benedetto@gmail.com>
|
* Salvatore Benedetto <salvatore.benedetto@gmail.com>
|
||||||
|
* Michael Lotz <mmlr@mlotz.ch>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef OHCI_HARDWARE_H
|
#ifndef OHCI_HARDWARE_H
|
||||||
@ -271,15 +272,14 @@
|
|||||||
|
|
||||||
#define OHCI_NUMBER_OF_INTERRUPTS 32
|
#define OHCI_NUMBER_OF_INTERRUPTS 32
|
||||||
|
|
||||||
typedef struct ohci_hcca
|
typedef struct {
|
||||||
{
|
|
||||||
uint32 interrupt_table[OHCI_NUMBER_OF_INTERRUPTS];
|
uint32 interrupt_table[OHCI_NUMBER_OF_INTERRUPTS];
|
||||||
uint32 current_frame_number;
|
uint32 current_frame_number;
|
||||||
uint32 done_head;
|
uint32 done_head;
|
||||||
// The following is 120 instead of 116 because the spec
|
// The following is 120 instead of 116 because the spec
|
||||||
// only specifies 252 bytes
|
// only specifies 252 bytes
|
||||||
uint8 reserved_for_hc[120];
|
uint8 reserved_for_hc[120];
|
||||||
};
|
} ohci_hcca;
|
||||||
|
|
||||||
#define OHCI_DONE_INTERRUPTS 1
|
#define OHCI_DONE_INTERRUPTS 1
|
||||||
#define OHCI_HCCA_SIZE 256
|
#define OHCI_HCCA_SIZE 256
|
||||||
@ -292,20 +292,18 @@ typedef struct ohci_hcca
|
|||||||
// Endpoint descriptor structure (section 4.2)
|
// Endpoint descriptor structure (section 4.2)
|
||||||
// --------------------------------
|
// --------------------------------
|
||||||
|
|
||||||
typedef struct ohci_endpoint_descriptor
|
typedef struct {
|
||||||
{
|
|
||||||
// Hardware part
|
// Hardware part
|
||||||
uint32 flags; // Flags field
|
uint32 flags; // Flags field
|
||||||
uint32 tail_physical_descriptor; // Queue tail physical pointer
|
uint32 tail_physical_descriptor; // Queue tail physical pointer
|
||||||
uint32 head_physical_descriptor; // Queue head physical pointer
|
uint32 head_physical_descriptor; // Queue head physical pointer
|
||||||
uint32 next_physical_endpoint; // Physical pointer to the next endpoint
|
uint32 next_physical_endpoint; // Physical pointer to the next endpoint
|
||||||
// Software part
|
// Software part
|
||||||
// TODO: What about type, state and interval (only interrupts) ?
|
|
||||||
addr_t physical_address; // Physical pointer to this address
|
addr_t physical_address; // Physical pointer to this address
|
||||||
void *tail_logical_descriptor; // Queue tail logical pointer
|
void *tail_logical_descriptor; // Queue tail logical pointer
|
||||||
void *head_logical_descriptor; // Queue head logical pointer
|
void *head_logical_descriptor; // Queue head logical pointer
|
||||||
void *next_logical_endpoint; // Logical pointer to the next endpoint
|
void *next_logical_endpoint; // Logical pointer to the next endpoint
|
||||||
};
|
} ohci_endpoint_descriptor;
|
||||||
|
|
||||||
#define OHCI_ENDPOINT_ADDRESS_MASK 0x0000007f
|
#define OHCI_ENDPOINT_ADDRESS_MASK 0x0000007f
|
||||||
#define OHCI_ENDPOINT_GET_DEVICE_ADDRESS(s) ((s) & 0x7f)
|
#define OHCI_ENDPOINT_GET_DEVICE_ADDRESS(s) ((s) & 0x7f)
|
||||||
@ -333,8 +331,7 @@ typedef struct ohci_endpoint_descriptor
|
|||||||
// General transfer descriptor structure (section 4.3.1)
|
// General transfer descriptor structure (section 4.3.1)
|
||||||
// --------------------------------
|
// --------------------------------
|
||||||
|
|
||||||
typedef struct ohci_general_td
|
typedef struct {
|
||||||
{
|
|
||||||
// Hardware part 16 bytes
|
// Hardware part 16 bytes
|
||||||
uint32 flags; // Flags field
|
uint32 flags; // Flags field
|
||||||
uint32 buffer_physical; // Physical buffer pointer
|
uint32 buffer_physical; // Physical buffer pointer
|
||||||
@ -348,7 +345,7 @@ typedef struct ohci_general_td
|
|||||||
size_t buffer_size; // Size of the buffer
|
size_t buffer_size; // Size of the buffer
|
||||||
void *transfer; // Pointer to the transfer_data
|
void *transfer; // Pointer to the transfer_data
|
||||||
bool is_last; // Last descriptor of the transfer
|
bool is_last; // Last descriptor of the transfer
|
||||||
};
|
} ohci_general_td;
|
||||||
|
|
||||||
#define OHCI_BUFFER_ROUNDING 0x00040000
|
#define OHCI_BUFFER_ROUNDING 0x00040000
|
||||||
#define OHCI_TD_DIRECTION_PID_MASK 0x00180000
|
#define OHCI_TD_DIRECTION_PID_MASK 0x00180000
|
||||||
@ -374,8 +371,7 @@ typedef struct ohci_general_td
|
|||||||
// --------------------------------
|
// --------------------------------
|
||||||
|
|
||||||
#define OHCI_ITD_NOFFSET 8
|
#define OHCI_ITD_NOFFSET 8
|
||||||
typedef struct ohci_isochronous_td
|
typedef struct {
|
||||||
{
|
|
||||||
// Hardware part 32 byte
|
// Hardware part 32 byte
|
||||||
uint32 flags;
|
uint32 flags;
|
||||||
uint32 buffer_page_byte_0; // Physical page number of byte 0
|
uint32 buffer_page_byte_0; // Physical page number of byte 0
|
||||||
@ -386,7 +382,7 @@ typedef struct ohci_isochronous_td
|
|||||||
addr_t physical_address; // Physical address of this descriptor
|
addr_t physical_address; // Physical address of this descriptor
|
||||||
void *next_logical_descriptor; // Logical pointer next descriptor
|
void *next_logical_descriptor; // Logical pointer next descriptor
|
||||||
void *next_done_descriptor; // Used for collision in the hash table
|
void *next_done_descriptor; // Used for collision in the hash table
|
||||||
};
|
} ohci_isochronous_td;
|
||||||
|
|
||||||
#define OHCI_ITD_GET_STARTING_FRAME(x) ((x) & 0x0000ffff)
|
#define OHCI_ITD_GET_STARTING_FRAME(x) ((x) & 0x0000ffff)
|
||||||
#define OHCI_ITD_SET_STARTING_FRAME(x) ((x) & 0xffff)
|
#define OHCI_ITD_SET_STARTING_FRAME(x) ((x) & 0xffff)
|
||||||
|
Loading…
Reference in New Issue
Block a user