USB bus drivers: Return error when combining other transfers with a fragmented one.
The drivers do not support this properly at present, they would run the other transfers interspersed with fragments from the fragemented one, which is obviously the wrong thing to do. No USB device drivers seem to do this at present (it would cause data corruption if they had.) Fixes #17275.
This commit is contained in:
@@ -1547,6 +1547,19 @@ EHCI::AddPendingTransfer(Transfer *transfer, ehci_qh *queueHead,
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// We do not support queuing other transfers in tandem with a fragmented one.
|
||||
transfer_data *it = fFirstTransfer;
|
||||
while (it) {
|
||||
if (it->transfer && it->transfer->TransferPipe() == transfer->TransferPipe()
|
||||
&& it->transfer->IsFragmented()) {
|
||||
TRACE_ERROR("cannot submit transfer: a fragmented transfer is queued\n");
|
||||
|
||||
Unlock();
|
||||
delete data;
|
||||
return B_DEV_RESOURCE_CONFLICT;
|
||||
}
|
||||
}
|
||||
|
||||
if (fLastTransfer)
|
||||
fLastTransfer->link = data;
|
||||
else
|
||||
|
||||
@@ -1451,6 +1451,17 @@ OHCI::_SubmitTransfer(Transfer *transfer)
|
||||
= (ohci_endpoint_descriptor *)pipe->ControllerCookie();
|
||||
|
||||
MutexLocker endpointLocker(endpoint->lock);
|
||||
|
||||
// We do not support queuing other transfers in tandem with a fragmented one.
|
||||
transfer_data *it = fFirstTransfer;
|
||||
while (it) {
|
||||
if (it->transfer && it->transfer->TransferPipe() == pipe && it->transfer->IsFragmented()) {
|
||||
TRACE_ERROR("cannot submit transfer: a fragmented transfer is queued\n");
|
||||
_FreeDescriptorChain(firstDescriptor);
|
||||
return B_DEV_RESOURCE_CONFLICT;
|
||||
}
|
||||
}
|
||||
|
||||
result = _AddPendingTransfer(transfer, endpoint, firstDescriptor,
|
||||
firstDescriptor, lastDescriptor, directionIn);
|
||||
if (result < B_OK) {
|
||||
|
||||
@@ -1065,6 +1065,19 @@ UHCI::AddPendingTransfer(Transfer *transfer, Queue *queue,
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// We do not support queuing other transfers in tandem with a fragmented one.
|
||||
transfer_data *it = fFirstTransfer;
|
||||
while (it) {
|
||||
if (it->transfer && it->transfer->TransferPipe() == transfer->TransferPipe()
|
||||
&& it->transfer->IsFragmented()) {
|
||||
TRACE_ERROR("cannot submit transfer: a fragmented transfer is queued\n");
|
||||
|
||||
Unlock();
|
||||
delete data;
|
||||
return B_DEV_RESOURCE_CONFLICT;
|
||||
}
|
||||
}
|
||||
|
||||
if (fLastTransfer)
|
||||
fLastTransfer->link = data;
|
||||
if (!fFirstTransfer)
|
||||
|
||||
@@ -1846,6 +1846,14 @@ XHCI::_LinkDescriptorForPipe(xhci_td *descriptor, xhci_endpoint *endpoint)
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
// We do not support queuing other transfers in tandem with a fragmented one.
|
||||
if (endpoint->td_head != NULL && endpoint->td_head->transfer != NULL
|
||||
&& endpoint->td_head->transfer->IsFragmented()) {
|
||||
TRACE_ERROR("cannot submit transfer: a fragmented transfer is queued\n");
|
||||
mutex_unlock(&endpoint->lock);
|
||||
return B_DEV_RESOURCE_CONFLICT;
|
||||
}
|
||||
|
||||
endpoint->used++;
|
||||
descriptor->next = endpoint->td_head;
|
||||
endpoint->td_head = descriptor;
|
||||
|
||||
Reference in New Issue
Block a user