* 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:
Salvatore Benedetto
2008-01-17 22:25:47 +00:00
parent 588b2cd4bf
commit acf9124f1b
3 changed files with 100 additions and 22 deletions
+89 -18
View File
@@ -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;
} }
+8 -4
View File
@@ -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)