* Move the actual and maximum length calculation into two inline functions.
* Use those to make sure the size is retrieved correctly in all cases (which it wasn't in the short packet tests). * Don't detect short packets for control transfers as we need the status packet to finish the transfer and cannot quit earlier. * Only check for short packets when we also have the short packet flag set. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30710 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -684,8 +684,8 @@ UHCI::ProcessDebugTransfer(Transfer *transfer)
|
||||
}
|
||||
|
||||
if ((descriptor->link_phy & TD_TERMINATE)
|
||||
|| (descriptor->status & TD_STATUS_ACTLEN_MASK)
|
||||
< (descriptor->token >> TD_TOKEN_MAXLEN_SHIFT)) {
|
||||
|| uhci_td_actual_length(descriptor)
|
||||
< uhci_td_maximum_length(descriptor)) {
|
||||
transferOK = true;
|
||||
break;
|
||||
}
|
||||
@@ -1295,8 +1295,9 @@ UHCI::FinishTransfers()
|
||||
}
|
||||
|
||||
if ((descriptor->link_phy & TD_TERMINATE)
|
||||
|| (descriptor->status & TD_STATUS_ACTLEN_MASK)
|
||||
< (descriptor->token >> TD_TOKEN_MAXLEN_SHIFT)) {
|
||||
|| ((descriptor->status & TD_CONTROL_SPD) != 0
|
||||
&& uhci_td_actual_length(descriptor)
|
||||
< uhci_td_maximum_length(descriptor))) {
|
||||
// all descriptors are done, or we have a short packet
|
||||
TRACE("td (0x%08lx) ok\n", descriptor->this_phy);
|
||||
callbackStatus = B_OK;
|
||||
@@ -1903,7 +1904,8 @@ UHCI::CreateDescriptor(Pipe *pipe, uint8 direction, size_t bufferSize)
|
||||
result->status |= TD_CONTROL_ISOCHRONOUS;
|
||||
else {
|
||||
result->status |= TD_CONTROL_3_ERRORS;
|
||||
if (direction == TD_TOKEN_IN)
|
||||
if (direction == TD_TOKEN_IN
|
||||
&& (pipe->Type() & USB_OBJECT_CONTROL_PIPE) == 0)
|
||||
result->status |= TD_CONTROL_SPD;
|
||||
}
|
||||
if (pipe->Speed() == USB_SPEED_LOWSPEED)
|
||||
@@ -2086,9 +2088,7 @@ UHCI::ReadDescriptorChain(uhci_td *topDescriptor, iovec *vector,
|
||||
break;
|
||||
|
||||
dataToggle = (current->token >> TD_TOKEN_DATA_TOGGLE_SHIFT) & 0x01;
|
||||
size_t bufferSize = (current->status & TD_STATUS_ACTLEN_MASK) + 1;
|
||||
if (bufferSize == TD_STATUS_ACTLEN_NULL + 1)
|
||||
bufferSize = 0;
|
||||
size_t bufferSize = uhci_td_actual_length(current);
|
||||
|
||||
while (true) {
|
||||
size_t length = min_c(bufferSize - bufferOffset,
|
||||
@@ -2144,11 +2144,7 @@ UHCI::ReadActualLength(uhci_td *topDescriptor, uint8 *lastDataToggle)
|
||||
uint8 dataToggle = 0;
|
||||
|
||||
while (current && (current->status & TD_STATUS_ACTIVE) == 0) {
|
||||
size_t length = (current->status & TD_STATUS_ACTLEN_MASK) + 1;
|
||||
if (length == TD_STATUS_ACTLEN_NULL + 1)
|
||||
length = 0;
|
||||
|
||||
actualLength += length;
|
||||
actualLength += uhci_td_actual_length(current);
|
||||
dataToggle = (current->token >> TD_TOKEN_DATA_TOGGLE_SHIFT) & 0x01;
|
||||
|
||||
if (current->link_phy & TD_TERMINATE)
|
||||
@@ -2191,10 +2187,7 @@ UHCI::ReadIsochronousDescriptorChain(isochronous_transfer_data *transfer,
|
||||
uhci_td *current = transfer->descriptors[i];
|
||||
|
||||
size_t bufferSize = current->buffer_size;
|
||||
size_t actualLength = (current->status & TD_STATUS_ACTLEN_MASK) + 1;
|
||||
|
||||
if (actualLength == TD_STATUS_ACTLEN_NULL + 1)
|
||||
actualLength = 0;
|
||||
size_t actualLength = uhci_td_actual_length(current);
|
||||
|
||||
isochronousData->packet_descriptors[i].actual_length = actualLength;
|
||||
|
||||
|
||||
@@ -140,6 +140,26 @@ typedef struct
|
||||
#define TD_LINK_MASK 0xfffffff0
|
||||
|
||||
|
||||
static inline size_t
|
||||
uhci_td_maximum_length(uhci_td *descriptor)
|
||||
{
|
||||
size_t length = (descriptor->token >> TD_TOKEN_MAXLEN_SHIFT) + 1;
|
||||
if (length == TD_STATUS_ACTLEN_NULL + 1)
|
||||
return 0;
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
static inline size_t
|
||||
uhci_td_actual_length(uhci_td *descriptor)
|
||||
{
|
||||
size_t length = (descriptor->status & TD_STATUS_ACTLEN_MASK) + 1;
|
||||
if (length == TD_STATUS_ACTLEN_NULL + 1)
|
||||
return 0;
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
// Represents a Queue Head (QH)
|
||||
typedef struct
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user