* Added necessary dummy descriptor to every endpoint created

* Implemented _RemoveTransferFromEndpoint
* Reworked _AppendChainDescriptorsToEndpoint as now every endpoint has (must have) a dummy descriptor



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23741 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Salvatore Benedetto
2008-01-25 17:47:59 +00:00
parent 7e80cf0096
commit de1ecdaf63
2 changed files with 46 additions and 26 deletions
+44 -24
View File
@@ -524,7 +524,9 @@ OHCI::_FinishTransfer()
TRACE(("usb_ohci: transfer failed! ohci error code: %d\n", TRACE(("usb_ohci: transfer failed! ohci error code: %d\n",
conditionCode)); conditionCode));
_RemoveTransferFromEndpoint(transfer); // Remove remaining descriptors from the same transfer
if (!current->is_last)
_RemoveTransferFromEndpoint(transfer);
// TODO: Fix the following with the appropriate error // TODO: Fix the following with the appropriate error
callbackStatus = B_DEV_MULTIPLE_ERRORS; callbackStatus = B_DEV_MULTIPLE_ERRORS;
@@ -586,33 +588,25 @@ OHCI::_AppendChainDescriptorsToEndpoint(ohci_endpoint_descriptor *endpoint,
// TODO: Lock on endpoint // TODO: Lock on endpoint
ohci_general_td *head = (ohci_general_td *)endpoint->head_logical_descriptor; ohci_general_td *head = (ohci_general_td *)endpoint->head_logical_descriptor;
if (head) { ohci_general_td *tail = (ohci_general_td *)endpoint->tail_logical_descriptor;
// There is at least one descriptor to this endpoint if (head != tail) {
ohci_general_td *tail = (ohci_general_td *)endpoint->tail_logical_descriptor; // Find the last real descriptor
if (tail) { ohci_general_td *current = head;
// There is more than one descriptor while (current->next_logical_descriptor != tail)
tail->next_logical_descriptor = first; current = (ohci_general_td *)current->next_logical_descriptor;
tail->next_physical_descriptor = first->physical_address; // Append to current
} else { current->next_logical_descriptor = first;
// There is only one descriptor to this endpoint current->next_physical_descriptor = first->physical_address;
head->next_logical_descriptor = first;
head->next_physical_descriptor = first->physical_address;
}
endpoint->tail_logical_descriptor = last;
endpoint->tail_physical_descriptor = last->physical_address;
} else { } else {
// Endpoint is empty // Endpoint has only the dummy descriptor
endpoint->head_logical_descriptor = first; endpoint->head_logical_descriptor = first;
endpoint->head_physical_descriptor = first->physical_address; endpoint->head_physical_descriptor = first->physical_address;
// Update tail only if we are appending more than one descriptor
// otherwise the controller won't process the descriptor as
// head will be the same as tail.
if (first != last) {
endpoint->tail_logical_descriptor = last;
endpoint->tail_physical_descriptor = last->physical_address;
}
} }
// Make the last descriptor point to the dummy
last->next_logical_descriptor = tail;
last->next_physical_descriptor = tail->physical_address;
endpoint->flags &= ~OHCI_ENDPOINT_SKIP; endpoint->flags &= ~OHCI_ENDPOINT_SKIP;
return B_OK; return B_OK;
} }
@@ -621,7 +615,17 @@ OHCI::_AppendChainDescriptorsToEndpoint(ohci_endpoint_descriptor *endpoint,
void void
OHCI::_RemoveTransferFromEndpoint(transfer_data *transfer) OHCI::_RemoveTransferFromEndpoint(transfer_data *transfer)
{ {
// TODO // TODO: Add lock for endpoint
ohci_endpoint_descriptor *endpoint = transfer->endpoint;
ohci_general_td *next = (ohci_general_td *)endpoint->head_logical_descriptor;
// Find the first descriptor of a different transfer.
// Worst scenario we get the dummy descriptor
while ((transfer_data *)next->transfer == transfer)
next = (ohci_general_td *)next->next_logical_descriptor;
// Update head
endpoint->head_logical_descriptor = next;
endpoint->head_physical_descriptor = next->physical_address;
} }
@@ -1357,6 +1361,22 @@ OHCI::_InsertEndpointForPipe(Pipe *pipe)
return B_ERROR; return B_ERROR;
} }
// Create (necessary) dummy descriptor
if (pipe->Type() & USB_OBJECT_ISO_PIPE) {
// TODO
} else {
ohci_general_td *dummy = _CreateGeneralDescriptor(0);
dummy->next_logical_descriptor = NULL;
dummy->next_physical_descriptor = NULL;
endpoint->head_logical_descriptor
= endpoint->tail_logical_descriptor
= dummy;
endpoint->head_physical_descriptor
= endpoint->tail_physical_descriptor
= dummy->physical_address;
}
// TODO: Change lock lo LockEndpoint()
Lock(); Lock();
pipe->SetControllerCookie((void *)endpoint); pipe->SetControllerCookie((void *)endpoint);
endpoint->next_logical_endpoint = head->next_logical_endpoint; endpoint->next_logical_endpoint = head->next_logical_endpoint;
+2 -2
View File
@@ -115,6 +115,8 @@ static int32 _FinishThread(void *data);
ohci_endpoint_descriptor *endpoint, ohci_endpoint_descriptor *endpoint,
ohci_general_td *first, ohci_general_td *first,
ohci_general_td *last); ohci_general_td *last);
void _RemoveTransferFromEndpoint(
transfer_data *);
// Endpoint related methods // Endpoint related methods
ohci_endpoint_descriptor *_AllocateEndpoint(); ohci_endpoint_descriptor *_AllocateEndpoint();
@@ -122,8 +124,6 @@ static int32 _FinishThread(void *data);
ohci_endpoint_descriptor *endpoint); ohci_endpoint_descriptor *endpoint);
status_t _InsertEndpointForPipe(Pipe *pipe); status_t _InsertEndpointForPipe(Pipe *pipe);
status_t _RemoveEndpointForPipe(Pipe *pipe); status_t _RemoveEndpointForPipe(Pipe *pipe);
void _RemoveTransferFromEndpoint(
transfer_data *transfer);
ohci_endpoint_descriptor *_FindInterruptEndpoint(uint8 interval); ohci_endpoint_descriptor *_FindInterruptEndpoint(uint8 interval);
// Transfer descriptor related methods // Transfer descriptor related methods