* Added definition for the hash related methods (not implemented)
* Continue working in the _FinishTransfer thread * added next_done_descriptor in ohci_[general|isochronous]_td structure in order to handle collisions. * added next_logical_descriptor to ohci_isochronous_td structure git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23594 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -135,6 +135,21 @@ OHCI::OHCI(pci_info *info, Stack *stack)
|
|||||||
|
|
||||||
memset((void *)fHcca, 0, sizeof(ohci_hcca));
|
memset((void *)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();
|
||||||
@@ -317,6 +332,10 @@ OHCI::~OHCI()
|
|||||||
delete_area(fHccaArea);
|
delete_area(fHccaArea);
|
||||||
if (fRegisterArea > 0)
|
if (fRegisterArea > 0)
|
||||||
delete_area(fRegisterArea);
|
delete_area(fRegisterArea);
|
||||||
|
if (fHashGenericTable)
|
||||||
|
free(fHashGenericTable);
|
||||||
|
if (fHashIsochronousTable)
|
||||||
|
free(fHashIsochronousTable);
|
||||||
if (fDummyControl)
|
if (fDummyControl)
|
||||||
_FreeEndpoint(fDummyControl);
|
_FreeEndpoint(fDummyControl);
|
||||||
if (fDummyBulk)
|
if (fDummyBulk)
|
||||||
@@ -437,12 +456,40 @@ OHCI::_FinishTransfer()
|
|||||||
|
|
||||||
// Pull out the done list and reverse its order
|
// Pull out the done list and reverse its order
|
||||||
// for both general and isochronous descriptors
|
// for both general and isochronous descriptors
|
||||||
addr_t done_list = fHcca->done_head & ~OHCI_DONE_INTERRUPTS;
|
ohci_general_td *descriptor, *top;
|
||||||
addr_t logical = _LogicalAddress(done_list);
|
ohci_isochronous_td *isoDescriptor, *isoTop;
|
||||||
if (_IsIsochronous(logical)) {
|
uint32 done_list = fHcca->done_head & ~OHCI_DONE_INTERRUPTS;
|
||||||
ohci_general_td *descriptor = (ohci_general_td *)logical;
|
for ( top = NULL, isoTop = NULL ; done_list != 0; ) {
|
||||||
} else {
|
if ((descriptor = _FindDescriptorInHash(done_list))) {
|
||||||
ohci_isochronous_td *descriptor = (ohci_isochronous_td *)logical;
|
done_list = descriptor->next_physical_descriptor;
|
||||||
|
descriptor->next_logical_descriptor = (void *)top;
|
||||||
|
top = descriptor;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((isoDescriptor = _FindIsoDescriptorInHash(done_list))) {
|
||||||
|
done_list = isoDescriptor->next_physical_descriptor;
|
||||||
|
isoDescriptor->next_logical_descriptor = (void *)isoTop;
|
||||||
|
isoTop = isoDescriptor;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// TODO: Should I panic here? :)
|
||||||
|
TRACE_ERROR(("usb_ohci: address 0x%08lx not found!\n",done_list));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process the list
|
||||||
|
for (isoDescriptor = isoTop; isoDescriptor != NULL; isoDescriptor
|
||||||
|
= (ohci_isochronous_td *)isoDescriptor->next_logical_descriptor) {
|
||||||
|
// TODO: Process isochronous descriptors
|
||||||
|
}
|
||||||
|
for (descriptor = top; descriptor != NULL; descriptor
|
||||||
|
= (ohci_general_td *)descriptor->next_logical_descriptor) {
|
||||||
|
// TODO: Process general descriptors
|
||||||
|
if (OHCI_TD_GET_CONDITION_CODE(descriptor->flags) == OHCI_NO_ERROR) {
|
||||||
|
if (descriptor->is_last) {
|
||||||
|
// Trasfer completed
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Acknowledge the interrupt
|
// Acknowledge the interrupt
|
||||||
@@ -453,23 +500,47 @@ OHCI::_FinishTransfer()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
addr_t
|
void
|
||||||
OHCI::_LogicalAddress(addr_t physical)
|
OHCI::_AddDescriptorToHash(ohci_general_td *descriptor)
|
||||||
{
|
{
|
||||||
// How do I implement it ?
|
// TODO
|
||||||
// 1 - Hash function like others (*BSD, Linux)
|
|
||||||
// 2 - Adding a method to our slab allocator (
|
|
||||||
// offset from the base are the same for phys and logic)
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
void
|
||||||
OHCI::_IsIsochronous(addr_t logical)
|
OHCI::_RemoveDescriptorFromHash(ohci_general_td *descriptor)
|
||||||
{
|
{
|
||||||
// I have NO IDEA how to implement this.
|
// TODO
|
||||||
// BSD uses two hash table.
|
}
|
||||||
return false;
|
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -143,16 +143,16 @@ static int32 _FinishThread(void *data);
|
|||||||
void _AddDescriptorToHash(
|
void _AddDescriptorToHash(
|
||||||
ohci_general_td *descriptor);
|
ohci_general_td *descriptor);
|
||||||
void _RemoveDescriptorFromHash(
|
void _RemoveDescriptorFromHash(
|
||||||
addr_t physicalAddress);
|
ohci_general_td *descriptor);
|
||||||
ohci_general_td *_FindDescriptorInHash(
|
ohci_general_td *_FindDescriptorInHash(
|
||||||
addr_t physicalAddress);
|
uint32 physicalAddress);
|
||||||
|
|
||||||
void _AddIsoDescriptorToHash(
|
void _AddIsoDescriptorToHash(
|
||||||
ohci_isochronous_td *descriptor);
|
ohci_isochronous_td *descriptor);
|
||||||
void _RemoveIsoDescriptorFromHash(
|
void _RemoveIsoDescriptorFromHash(
|
||||||
addr_t physicalAddress);
|
ohci_isochronous_td *descriptor);
|
||||||
ohci_isochronous_td *_FindIsoDescriptorInHash(
|
ohci_isochronous_td *_FindIsoDescriptorInHash(
|
||||||
addr_t physicalAddress);
|
uint32 physicalAddress);
|
||||||
|
|
||||||
|
|
||||||
// Register functions
|
// Register functions
|
||||||
@@ -183,6 +183,10 @@ 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;
|
||||||
|
|||||||
@@ -344,6 +344,7 @@ typedef struct ohci_general_td
|
|||||||
addr_t physical_address; // Physical address of this descriptor
|
addr_t physical_address; // Physical address of this descriptor
|
||||||
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 *next_done_descriprtor; // Used for collision in the hash table
|
||||||
size_t buffer_size; // Size of the buffer
|
size_t buffer_size; // Size of the buffer
|
||||||
void *endpoint; // Necessary when there is an error
|
void *endpoint; // Necessary when there is an error
|
||||||
void *transfer; // Pointer to the transfer
|
void *transfer; // Pointer to the transfer
|
||||||
@@ -384,6 +385,8 @@ typedef struct ohci_isochronous_td
|
|||||||
uint16 offset[OHCI_ITD_NOFFSET]; // Buffer offsets
|
uint16 offset[OHCI_ITD_NOFFSET]; // Buffer offsets
|
||||||
// Software part
|
// Software part
|
||||||
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_done_descriptor; // Used for collision in the hash table
|
||||||
};
|
};
|
||||||
|
|
||||||
#define OHCI_ITD_GET_STARTING_FRAME(x) ((x) & 0x0000ffff)
|
#define OHCI_ITD_GET_STARTING_FRAME(x) ((x) & 0x0000ffff)
|
||||||
|
|||||||
Reference in New Issue
Block a user