* 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));
|
||||
|
||||
// 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
|
||||
// Dummy endpoints
|
||||
fDummyControl = _AllocateEndpoint();
|
||||
@@ -317,6 +332,10 @@ OHCI::~OHCI()
|
||||
delete_area(fHccaArea);
|
||||
if (fRegisterArea > 0)
|
||||
delete_area(fRegisterArea);
|
||||
if (fHashGenericTable)
|
||||
free(fHashGenericTable);
|
||||
if (fHashIsochronousTable)
|
||||
free(fHashIsochronousTable);
|
||||
if (fDummyControl)
|
||||
_FreeEndpoint(fDummyControl);
|
||||
if (fDummyBulk)
|
||||
@@ -437,12 +456,40 @@ OHCI::_FinishTransfer()
|
||||
|
||||
// Pull out the done list and reverse its order
|
||||
// for both general and isochronous descriptors
|
||||
addr_t done_list = fHcca->done_head & ~OHCI_DONE_INTERRUPTS;
|
||||
addr_t logical = _LogicalAddress(done_list);
|
||||
if (_IsIsochronous(logical)) {
|
||||
ohci_general_td *descriptor = (ohci_general_td *)logical;
|
||||
} else {
|
||||
ohci_isochronous_td *descriptor = (ohci_isochronous_td *)logical;
|
||||
ohci_general_td *descriptor, *top;
|
||||
ohci_isochronous_td *isoDescriptor, *isoTop;
|
||||
uint32 done_list = fHcca->done_head & ~OHCI_DONE_INTERRUPTS;
|
||||
for ( top = NULL, isoTop = NULL ; done_list != 0; ) {
|
||||
if ((descriptor = _FindDescriptorInHash(done_list))) {
|
||||
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
|
||||
@@ -453,23 +500,47 @@ OHCI::_FinishTransfer()
|
||||
}
|
||||
|
||||
|
||||
addr_t
|
||||
OHCI::_LogicalAddress(addr_t physical)
|
||||
void
|
||||
OHCI::_AddDescriptorToHash(ohci_general_td *descriptor)
|
||||
{
|
||||
// How do I implement it ?
|
||||
// 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;
|
||||
// TODO
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
OHCI::_IsIsochronous(addr_t logical)
|
||||
void
|
||||
OHCI::_RemoveDescriptorFromHash(ohci_general_td *descriptor)
|
||||
{
|
||||
// I have NO IDEA how to implement this.
|
||||
// BSD uses two hash table.
|
||||
return false;
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -143,16 +143,16 @@ static int32 _FinishThread(void *data);
|
||||
void _AddDescriptorToHash(
|
||||
ohci_general_td *descriptor);
|
||||
void _RemoveDescriptorFromHash(
|
||||
addr_t physicalAddress);
|
||||
ohci_general_td *descriptor);
|
||||
ohci_general_td *_FindDescriptorInHash(
|
||||
addr_t physicalAddress);
|
||||
uint32 physicalAddress);
|
||||
|
||||
void _AddIsoDescriptorToHash(
|
||||
ohci_isochronous_td *descriptor);
|
||||
void _RemoveIsoDescriptorFromHash(
|
||||
addr_t physicalAddress);
|
||||
ohci_isochronous_td *descriptor);
|
||||
ohci_isochronous_td *_FindIsoDescriptorInHash(
|
||||
addr_t physicalAddress);
|
||||
uint32 physicalAddress);
|
||||
|
||||
|
||||
// Register functions
|
||||
@@ -183,6 +183,10 @@ static pci_module_info *sPCIModule;
|
||||
thread_id fFinishThread;
|
||||
bool fStopFinishThread;
|
||||
|
||||
// Hash table
|
||||
ohci_general_td **fHashGenericTable;
|
||||
ohci_isochronous_td **fHashIsochronousTable;
|
||||
|
||||
// Root Hub
|
||||
OHCIRootHub *fRootHub;
|
||||
uint8 fRootHubAddress;
|
||||
|
||||
@@ -344,6 +344,7 @@ typedef struct ohci_general_td
|
||||
addr_t physical_address; // Physical address of this descriptor
|
||||
void *buffer_logical; // Logical pointer to the buffer
|
||||
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
|
||||
void *endpoint; // Necessary when there is an error
|
||||
void *transfer; // Pointer to the transfer
|
||||
@@ -384,6 +385,8 @@ typedef struct ohci_isochronous_td
|
||||
uint16 offset[OHCI_ITD_NOFFSET]; // Buffer offsets
|
||||
// Software part
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user