* Renamed some variables

* Reworking the interrupts endpoints tree parts
* Added spin_locker, semaphore, finisher thread and interrupt handler (not implemented)
* Made fInterruptEndpoints allocation dynamic instead of static
* Fixed Start method (it should be correct now)




git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22927 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Salvatore Benedetto
2007-11-14 13:37:41 +00:00
parent 7301a7fbdb
commit ca73cdd62f
3 changed files with 211 additions and 86 deletions
+146 -52
View File
@@ -66,13 +66,18 @@ OHCI::OHCI(pci_info *info, Stack *stack)
fPCIInfo(info), fPCIInfo(info),
fStack(stack), fStack(stack),
fRegisterArea(-1), fRegisterArea(-1),
fSpinLock(0),
fHccaArea(-1), fHccaArea(-1),
fDummyControl(NULL), fDummyControl(NULL),
fDummyBulk(NULL), fDummyBulk(NULL),
fDummyIsochronous(NULL), fDummyIsochronous(NULL),
fFirstTransfer(NULL),
fFinishTransfer(NULL),
fFinishThread(-1),
fStopFinishThread(false),
fRootHub(NULL), fRootHub(NULL),
fRootHubAddress(0), fRootHubAddress(0),
fNumPorts(0) fPortCount(0)
{ {
if (!fInitOK) { if (!fInitOK) {
TRACE_ERROR(("usb_ohci: bus manager failed to init\n")); TRACE_ERROR(("usb_ohci: bus manager failed to init\n"));
@@ -119,12 +124,13 @@ OHCI::OHCI(pci_info *info, Stack *stack)
} }
// Set up the Host Controller Communications Area // Set up the Host Controller Communications Area
// which is 256 bytes (2048 bits) and must be aligned
void *hccaPhysicalAddress; void *hccaPhysicalAddress;
fHccaArea = fStack->AllocateArea((void **)&fHcca, &hccaPhysicalAddress, fHccaArea = fStack->AllocateArea((void **)&fHcca, &hccaPhysicalAddress,
2048, "USB OHCI Host Controller Communication Area"); 2048, "USB OHCI Host Controller Communication Area");
if (fHccaArea < B_OK) { if (fHccaArea < B_OK) {
TRACE(("usb_ohci: unable to create the HCCA block area\n")); TRACE_ERROR(("usb_ohci: unable to create the HCCA block area\n"));
return; return;
} }
@@ -153,9 +159,35 @@ OHCI::OHCI(pci_info *info, Stack *stack)
fDummyIsochronous->flags |= OHCI_ENDPOINT_SKIP; fDummyIsochronous->flags |= OHCI_ENDPOINT_SKIP;
// Create the interrupt tree // Create the interrupt tree
// Algorithm kindly borrowed from NetBSD code fInterruptEndpoints = new(std::nothrow)
// TODO: Check it once again ohci_endpoint_descriptor *[OHCI_NUMBER_OF_INTERRUPTS];
ohci_endpoint_descriptor *current, *previous; if (!fInterruptEndpoints) {
TRACE_ERROR(("ohci_usb: cannot allocate memory for"
" fInterruptEndpoints array\n"));
_FreeEndpoint(fDummyControl);
_FreeEndpoint(fDummyBulk);
_FreeEndpoint(fDummyIsochronous);
return;
}
// Static endpoints that get linked in the HCCA
for (uint32 i = 0; i < OHCI_NUMBER_OF_INTERRUPTS; i++) {
fInterruptEndpoints[i] = _AllocateEndpoint();
if (!fInterruptEndpoints[i]) {
while (--i >= 0)
_FreeEndpoint(fInterruptEndpoints[i]);
_FreeEndpoint(fDummyBulk);
_FreeEndpoint(fDummyControl);
_FreeEndpoint(fDummyIsochronous);
return;
}
fInterruptEndpoints[i]->flags |= OHCI_ENDPOINT_SKIP;
fInterruptEndpoints[i]->next_physical_endpoint
= fDummyIsochronous->physical_address;
}
#if 0
ohci_endpoint_descriptor *current;
for( uint32 i = 0; i < OHCI_NUMBER_OF_ENDPOINTS; i++) { for( uint32 i = 0; i < OHCI_NUMBER_OF_ENDPOINTS; i++) {
current = _AllocateEndpoint(); current = _AllocateEndpoint();
if (!current) { if (!current) {
@@ -174,13 +206,14 @@ OHCI::OHCI(pci_info *info, Stack *stack)
else else
previous = fDummyIsochronous; previous = fDummyIsochronous;
current->next_logical_endpoint = previous; current->next_logical_endpoint = previous;
current->next_physical_endpoint = previous->this_physical; current->next_physical_endpoint = previous->physical_address;
} }
#endif
// Fill HCCA interrupt table. The bit reversal is to get // Fill HCCA interrupt table. The bit reversal is to get
// the tree set up properly to spread the interrupts. // the tree set up properly to spread the interrupts.
for (uint32 i = 0; i < OHCI_NUMBER_OF_INTERRUPTS; i++) for (uint32 i = 0; i < OHCI_NUMBER_OF_INTERRUPTS; i++)
fHcca->hcca_interrupt_table[revbits[i]] = fHcca->interrupt_table[revbits[i]] =
fInterruptEndpoints[OHCI_NUMBER_OF_ENDPOINTS - OHCI_NUMBER_OF_INTERRUPTS + i]->physical_address; fInterruptEndpoints[OHCI_NUMBER_OF_ENDPOINTS - OHCI_NUMBER_OF_INTERRUPTS + i]->physical_address;
@@ -230,8 +263,12 @@ OHCI::OHCI(pci_info *info, Stack *stack)
return; return;
} }
// The controller is now in SUSPEND state, we have 2ms to finish // The controller is now in SUSPEND state, we have 2ms to go OPERATIONAL.
// TODO: maybe add spinlock protection??? // In order to do so we need a spinlock
cpu_status former = disable_interrupts();
acquire_spinlock(&fSpinLock);
// Set up host controller register // Set up host controller register
_WriteReg(OHCI_HCCA, (uint32)hccaPhysicalAddress); _WriteReg(OHCI_HCCA, (uint32)hccaPhysicalAddress);
_WriteReg(OHCI_CONTROL_HEAD_ED, (uint32)fDummyControl->physical_address); _WriteReg(OHCI_CONTROL_HEAD_ED, (uint32)fDummyControl->physical_address);
@@ -249,6 +286,9 @@ OHCI::OHCI(pci_info *info, Stack *stack)
// And finally start the controller // And finally start the controller
_WriteReg(OHCI_CONTROL, control); _WriteReg(OHCI_CONTROL, control);
release_spinlock(&fSpinLock);
restore_interrupts(former);
// The controller is now OPERATIONAL. // The controller is now OPERATIONAL.
frameInterval = (_ReadReg(OHCI_FRAME_INTERVAL) & OHCI_FRAME_INTERVAL_TOGGLE) frameInterval = (_ReadReg(OHCI_FRAME_INTERVAL) & OHCI_FRAME_INTERVAL_TOGGLE)
^ OHCI_FRAME_INTERVAL_TOGGLE; ^ OHCI_FRAME_INTERVAL_TOGGLE;
@@ -273,11 +313,28 @@ OHCI::OHCI(pci_info *info, Stack *stack)
uint32 descriptor = _ReadReg(OHCI_RH_DESCRIPTOR_A); uint32 descriptor = _ReadReg(OHCI_RH_DESCRIPTOR_A);
numberOfPorts = OHCI_RH_GET_PORT_COUNT(descriptor); numberOfPorts = OHCI_RH_GET_PORT_COUNT(descriptor);
} }
fPortCount = numberOfPorts;
// TODO: Add Finisher Thread. // Create semaphore the finisher thread will wait for
fFinishTransfersSem = create_sem(0, "OHCI Finish Transfers");
if (fFinishTransfersSem < B_OK) {
TRACE_ERROR(("usb_ohci: failed to create semaphore\n"));
return;
}
// Create the finisher service thread
fFinishThread = spawn_kernel_thread(_FinishThread, "ohci finish thread",
B_URGENT_DISPLAY_PRIORITY, (void *)this);
resume_thread(fFinishThread);
// Install the interrupt handler
TRACE(("usb_ohci: installing interrupt handler\n"));
install_io_interrupt_handler(fPCIInfo->u.h0.interrupt_line,
_InterruptHandler, (void *)this, 0);
// TODO: Enable interrupts. Maybe disable first somewhere before :)
TRACE(("usb_ohci: OHCI Host Controller Driver constructed\n")); TRACE(("usb_ohci: OHCI Host Controller Driver constructed\n"));
fInitOK = true; fInitOK = true;
} }
@@ -296,41 +353,73 @@ OHCI::~OHCI()
_FreeEndpoint(fDummyIsochronous); _FreeEndpoint(fDummyIsochronous);
if (fRootHub) if (fRootHub)
delete fRootHub; delete fRootHub;
for (int i = 0; i < OHCI_NO_EDS; i++) for (int i = 0; i < OHCI_NUMBER_OF_INTERRUPTS; i++)
if (fInterruptEndpoints[i]) if (fInterruptEndpoints[i])
_FreeEndpoint(fInterruptEndpoints[i]); _FreeEndpoint(fInterruptEndpoints[i]);
delete [] fInterruptEndpoints;
} }
int32
OHCI::_InterruptHandler(void *data)
{
return ((OHCI *)data)->_Interrupt();
}
int32
OHCI::_Interrupt()
{
static spinlock lock = 0;
acquire_spinlock(&lock);
int32 result = B_UNHANDLED_INTERRUPT;
release_spinlock(&lock);
return result;
}
int32
OHCI::_FinishThread(void *data)
{
((OHCI *)data)->_FinishTransfer();
return B_OK;
}
void
OHCI::_FinishTransfer()
{
// TODO: block on the semaphore
}
status_t status_t
OHCI::Start() OHCI::Start()
{ {
TRACE(("usb_ohci::%s()\n", __FUNCTION__)); TRACE(("usb_ohci: starting OHCI Host Controller\n"));
if (InitCheck())
return B_ERROR;
if (!(_ReadReg(OHCI_CONTROL) & OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL)) { if (!(_ReadReg(OHCI_CONTROL) & OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL)) {
TRACE(("usb_ohci::Start(): Controller not started. TODO: find out what happens.\n")); TRACE_ERROR(("usb_ohci: Controller not started!\n"));
return B_ERROR; return B_ERROR;
} }
fRootHubAddress = AllocateAddress(); fRootHubAddress = AllocateAddress();
fNumPorts = OHCI_RH_GET_PORT_COUNT(_ReadReg(OHCI_RH_DESCRIPTOR_A));
fRootHub = new(std::nothrow) OHCIRootHub(RootObject(), fRootHubAddress); fRootHub = new(std::nothrow) OHCIRootHub(RootObject(), fRootHubAddress);
if (!fRootHub) { if (!fRootHub) {
TRACE_ERROR(("usb_ohci::Start(): no memory to allocate root hub\n")); TRACE_ERROR(("usb_ohci: no memory to allocate root hub\n"));
return B_NO_MEMORY; return B_NO_MEMORY;
} }
if (fRootHub->InitCheck() < B_OK) { if (fRootHub->InitCheck() < B_OK) {
TRACE_ERROR(("usb_ohci::Start(): root hub failed init check\n")); TRACE_ERROR(("usb_ohci: root hub failed init check\n"));
return B_ERROR; return B_ERROR;
} }
SetRootHub(fRootHub); SetRootHub(fRootHub);
TRACE(("usb_ohci::Start(): Succesful start\n")); TRACE(("usb_ohci: Host Controller started\n"));
return B_OK; return BusManager::Start();
} }
@@ -445,7 +534,7 @@ 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::%s(%ud, )\n", __FUNCTION__, index));
if (index >= fNumPorts) if (index >= fPortCount)
return B_BAD_INDEX; return B_BAD_INDEX;
status->status = status->change = 0; status->status = status->change = 0;
@@ -490,7 +579,7 @@ status_t
OHCI::SetPortFeature(uint8 index, uint16 feature) OHCI::SetPortFeature(uint8 index, uint16 feature)
{ {
TRACE(("OHCI::%s(%ud, %ud)\n", __FUNCTION__, index, feature)); TRACE(("OHCI::%s(%ud, %ud)\n", __FUNCTION__, index, feature));
if (index > fNumPorts) if (index > fPortCount)
return B_BAD_INDEX; return B_BAD_INDEX;
switch (feature) { switch (feature) {
@@ -511,7 +600,7 @@ status_t
OHCI::ClearPortFeature(uint8 index, uint16 feature) OHCI::ClearPortFeature(uint8 index, uint16 feature)
{ {
TRACE(("OHCI::%s(%ud, %ud)\n", __FUNCTION__, index, feature)); TRACE(("OHCI::%s(%ud, %ud)\n", __FUNCTION__, index, feature));
if (index > fNumPorts) if (index > fPortCount)
return B_BAD_INDEX; return B_BAD_INDEX;
switch (feature) { switch (feature) {
@@ -541,15 +630,13 @@ OHCI::_AllocateEndpoint()
return NULL; return NULL;
} }
endpoint->this_physical = (addr_t)physicalAddress; endpoint->physical_address = (addr_t)physicalAddress;
// Add an empty list by creating a general descriptor endpoint->head_physical_descriptor = NULL;
ohci_general_transfer_descriptor *descriptor = _CreateGeneralDescriptor(); endpoint->tail_physical_descriptor = NULL;
endpoint->head_physical_descriptor = descriptor->this_physical;
endpoint->tail_physical_descriptor = descriptor->this_physical;
endpoint->head_logical_descriptor = descriptor; endpoint->head_logical_descriptor = NULL;
endpoint->tail_logical_descriptor = descriptor; endpoint->tail_logical_descriptor = NULL;
return endpoint; return endpoint;
} }
@@ -558,46 +645,53 @@ OHCI::_AllocateEndpoint()
void void
OHCI::_FreeEndpoint(ohci_endpoint_descriptor *endpoint) OHCI::_FreeEndpoint(ohci_endpoint_descriptor *endpoint)
{ {
TRACE(("OHCI::%s(%p)\n", __FUNCTION__, end)); fStack->FreeChunk((void *)endpoint, (void *)endpoint->physical_address,
fStack->FreeChunk((void *)end->ed, (void *) end->physical_address, sizeof(ohci_endpoint_descriptor)); sizeof(ohci_endpoint_descriptor));
delete end;
} }
TransferDescriptor * ohci_general_descriptor*
OHCI::_AllocateTransfer() OHCI::_CreateGeneralDescriptor()
{ {
TRACE(("OHCI::%s()\n", __FUNCTION__)); ohci_general_descriptor *descriptor;
TransferDescriptor *transfer = new TransferDescriptor; void *physicalAddress;
void *phy;
if (fStack->AllocateChunk((void **)&transfer->td, &phy, sizeof(ohci_general_transfer_descriptor)) != B_OK) { if (fStack->AllocateChunk((void **)&descriptor, &physicalAddress,
TRACE(("OHCI::AllocateTransfer(): Error Allocating Transfer\n")); sizeof(ohci_general_descriptor)) != B_OK) {
return 0; TRACE_ERROR(("usb_ohci: failed to allocate general descriptor\n"));
return NULL;
} }
transfer->physical_address = (addr_t)phy;
memset((void *)transfer->td, 0, sizeof(ohci_general_transfer_descriptor)); // TODO: Finish methods
return transfer; memset((void *)descriptor, 0, sizeof(ohci_general_descriptor));
descriptor->physical_address = (addr_t)physicalAddress;
return descriptor;
} }
void void
OHCI::_FreeTransfer(TransferDescriptor *trans) OHCI::_FreeGeneralDescriptor(ohci_general_descriptor *descriptor)
{ {
TRACE(("OHCI::%s(%p)\n", __FUNCTION__, trans)); if (!descriptor)
fStack->FreeChunk((void *)trans->td, (void *) trans->physical_address, sizeof(ohci_general_transfer_descriptor)); return;
delete trans;
fStack->FreeChunk((void *)descriptor, (void *)descriptor->physical_address,
sizeof(ohci_general_descriptor));
} }
status_t status_t
OHCI::_InsertEndpointForPipe(Pipe *p) OHCI::_InsertEndpointForPipe(Pipe *p)
{ {
#if 0
TRACE(("OHCI: Inserting Endpoint for device %u function %u\n", p->DeviceAddress(), p->EndpointAddress())); TRACE(("OHCI: Inserting Endpoint for device %u function %u\n", p->DeviceAddress(), p->EndpointAddress()));
if (InitCheck()) if (InitCheck())
return B_ERROR; return B_ERROR;
Endpoint *endpoint = _AllocateEndpoint(); //Endpoint *endpoint = _AllocateEndpoint();
ohci_endpoint_descriptor *endpoint = _AllocateEndpoint();
if (!endpoint) if (!endpoint)
return B_NO_MEMORY; return B_NO_MEMORY;
@@ -677,7 +771,7 @@ OHCI::_InsertEndpointForPipe(Pipe *p)
tail = tail->next; tail = tail->next;
tail->SetNext(endpoint); tail->SetNext(endpoint);
} }
#endif
return B_OK; return B_OK;
} }
+48 -15
View File
@@ -18,13 +18,20 @@ struct pci_info;
struct pci_module_info; struct pci_module_info;
class OHCIRootHub; class OHCIRootHub;
typedef struct transfer_data_s {
Transfer *transfer;
bool incoming;
bool canceled;
transfer_data_s *link;
} transfer_data;
// -------------------------------------- // --------------------------------------
// OHCI:: Software isonchronous // OHCI:: Software isonchronous
// transfer descriptor // transfer descriptor
// -------------------------------------- // --------------------------------------
typedef struct hcd_soft_itransfer typedef struct hcd_soft_itransfer
{ {
ohci_isochronous_transfer_descriptor itd; ohci_isochronous_descriptor itd;
struct hcd_soft_itransfer *nextitd; // mirrors nexttd in ITD struct hcd_soft_itransfer *nextitd; // mirrors nexttd in ITD
struct hcd_soft_itransfer *dnext; // next in done list struct hcd_soft_itransfer *dnext; // next in done list
addr_t physaddr; // physical address to the host controller isonchronous transfer addr_t physaddr; // physical address to the host controller isonchronous transfer
@@ -51,6 +58,7 @@ public:
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);
status_t SubmitRequest(Transfer *transfer);
virtual status_t NotifyPipeChange(Pipe *pipe, virtual status_t NotifyPipeChange(Pipe *pipe,
usb_change change); usb_change change);
@@ -58,48 +66,73 @@ 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; };
status_t GetPortStatus(uint8 index, usb_port_status *status); status_t GetPortStatus(uint8 index, 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);
uint8 PortCount() { return fNumPorts; }; status_t ResetPort(uint8 index);
private: private:
// Interrupt functions
static int32 _InterruptHandler(void *data);
int32 _Interrupt();
static int32 _FinishThread(void *data);
void _FinishTransfer();
// Endpoint related methods
status_t _CreateEndpoint(Pipe *pipe, bool isIsochronous);
ohci_endpoint_descriptor *_AllocateEndpoint();
void _FreeEndpoint(
ohci_endpoint_descriptor *endpoint);
status_t _InsertEndpointForPipe(Pipe *pipe);
// Transfer descriptor related methods
ohci_general_descriptor *_CreateGeneralDescriptor();
void _FreeGeneralDescriptor(
ohci_general_descriptor *descriptor);
ohci_isochronous_descriptor *_CreateIsochronousDescriptor();
void _FreeIsochronousDescriptor(
ohci_isochronous_descriptor *descriptor);
// 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);
// Global
static pci_module_info *sPCIModule; static pci_module_info *sPCIModule;
uint32 *fOperationalRegisters;
pci_info *fPCIInfo; pci_info *fPCIInfo;
Stack *fStack; Stack *fStack;
uint32 *fOperationalRegisters;
area_id fRegisterArea; area_id fRegisterArea;
spinlock fSpinLock;
// Host Controller Communication Area related stuff // Host Controller Communication Area related stuff
area_id fHccaArea; area_id fHccaArea;
struct ohci_hcca *fHcca; ohci_hcca *fHcca;
ohci_endpoint_descriptor *fInterruptEndpoints[OHCI_NUMBER_OF_ENDPOINTS]; ohci_endpoint_descriptor **fInterruptEndpoints;
// Dummy endpoints // Dummy endpoints
ohci_endpoint_descriptor *fDummyControl; ohci_endpoint_descriptor *fDummyControl;
ohci_endpoint_descriptor *fDummyBulk; ohci_endpoint_descriptor *fDummyBulk;
ohci_endpoint_descriptor *fDummyIsochronous; ohci_endpoint_descriptor *fDummyIsochronous;
// Endpoint related methods // Maintain a linked list of transfer
ohci_endpoint_descriptor *_AllocateEndpoint(); transfer_data *fFirstTransfer;
void _FreeEndpoint(Endpoint *end); transfer_data *fFinishTransfer;
TransferDescriptor *_AllocateTransfer(); sem_id fFinishTransfersSem;
void _FreeTransfer(TransferDescriptor *trans); thread_id fFinishThread;
status_t _InsertEndpointForPipe(Pipe *p); bool fStopFinishThread;
void _SetNext(ohci_endpoint_descriptor *endpoint);
// Root Hub // Root Hub
OHCIRootHub *fRootHub; OHCIRootHub *fRootHub;
uint8 fRootHubAddress; uint8 fRootHubAddress;
uint8 fNumPorts;
// Port management
uint8 fPortCount;
}; };
+13 -15
View File
@@ -264,27 +264,24 @@
#define OHCI_PERIODIC(i) ((i) * 9 / 10) #define OHCI_PERIODIC(i) ((i) * 9 / 10)
// --------------------------------
// OHCI physical address
// --------------------------------
typedef uint32 ohci_physaddr_t;
// -------------------------------- // --------------------------------
// HCCA structure (section 4.4) // HCCA structure (section 4.4)
// 256 bytes aligned
// -------------------------------- // --------------------------------
#define OHCI_NUMBER_OF_INTERRUPTS 32 #define OHCI_NUMBER_OF_INTERRUPTS 32
typedef struct ohci_hcca typedef struct ohci_hcca
{ {
uint32 hcca_interrupt_table[OHCI_NUMBER_OF_INTERRUPTS]; uint32 interrupt_table[OHCI_NUMBER_OF_INTERRUPTS];
uint16 hcca_frame_number; uint32 current_frame_number;
uint32 hcca_done_head; uint32 done_head;
uint8 hcca_reserved_for_hc[116]; // The following is 120 instead of 116 because the spec
// only specifies 252 bytes
uint8 reserved_for_hc[120];
}; };
#define OHCI_DONE_INTRS 1 #define OHCI_DONE_INTERRUPTS 1
#define OHCI_HCCA_SIZE 256 #define OHCI_HCCA_SIZE 256
#define OHCI_HCCA_ALIGN 256 #define OHCI_HCCA_ALIGN 256
#define OHCI_PAGE_SIZE 0x1000 #define OHCI_PAGE_SIZE 0x1000
@@ -303,7 +300,8 @@ typedef struct ohci_endpoint_descriptor
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
addr_t this_physical; // Physical pointer to this address // TODO: What about type, state and interval (only interrupts) ?
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
@@ -334,7 +332,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_transfer_descriptor typedef struct ohci_general_descriptor
{ {
// Hardware part // Hardware part
uint32 flags; // Flags field uint32 flags; // Flags field
@@ -342,7 +340,7 @@ typedef struct ohci_general_transfer_descriptor
uint32 next_physical_descriptor; // Physical pointer next descriptor uint32 next_physical_descriptor; // Physical pointer next descriptor
uint32 last_physical_byte_address; // Physical pointer to buffer end uint32 last_physical_byte_address; // Physical pointer to buffer end
// Software part // Software part
addr_t this_physical; // Physical pointer to this address addr_t physical_address; // Physical pointer to this address
void *buffer_logical; // Logical pointer to the buffer void *buffer_logical; // Logical pointer to the buffer
void *next_logical_descriptor; // Logical pointer next descriptor void *next_logical_descriptor; // Logical pointer next descriptor
void *last_logical_byte_address; // Logical pointer buffer end void *last_logical_byte_address; // Logical pointer buffer end
@@ -372,7 +370,7 @@ typedef struct ohci_general_transfer_descriptor
// -------------------------------- // --------------------------------
#define OHCI_ITD_NOFFSET 8 #define OHCI_ITD_NOFFSET 8
typedef struct ohci_isochronous_transfer_descriptor typedef struct ohci_isochronous_descriptor
{ {
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