xhci: Check endpoint state before stop
* As per the spec, the only exit from an endpoint in a halt state is to issue a restart command. (restart puts the endpoint into a stop state.. it's named poorly) Change-Id: I4a1a556374ad7f564a562d995d1a2e29230a50c3 Reviewed-on: https://review.haiku-os.org/c/haiku/+/3959 Reviewed-by: Alex von Gluck IV <kallisti5@unixzen.com>
This commit is contained in:
parent
bd6434b663
commit
53d0323422
@ -968,8 +968,7 @@ XHCI::CancelQueuedTransfers(Pipe *pipe, bool force)
|
||||
// complete, one of the queued transfers posts a completion event, so in
|
||||
// order to avoid a deadlock, we must unlock the endpoint.
|
||||
endpointLocker.Unlock();
|
||||
status_t status = StopEndpoint(false, endpoint->id + 1,
|
||||
endpoint->device->slot);
|
||||
status_t status = StopEndpoint(false, endpoint);
|
||||
endpointLocker.Lock();
|
||||
|
||||
// Detach the head TD from the endpoint.
|
||||
@ -1776,7 +1775,7 @@ XHCI::_RemoveEndpointForPipe(Pipe *pipe)
|
||||
if (endpoint->id > 0) {
|
||||
xhci_device *device = endpoint->device;
|
||||
uint8 epNumber = endpoint->id + 1;
|
||||
StopEndpoint(true, epNumber, device->slot);
|
||||
StopEndpoint(true, endpoint);
|
||||
|
||||
mutex_lock(&endpoint->lock);
|
||||
|
||||
@ -2686,14 +2685,15 @@ XHCI::EvaluateContext(uint64 inputContext, uint8 slot)
|
||||
|
||||
|
||||
status_t
|
||||
XHCI::ResetEndpoint(bool preserve, uint8 endpoint, uint8 slot)
|
||||
XHCI::ResetEndpoint(bool preserve, xhci_endpoint* endpoint)
|
||||
{
|
||||
TRACE("Reset Endpoint\n");
|
||||
|
||||
xhci_trb trb;
|
||||
trb.address = 0;
|
||||
trb.status = 0;
|
||||
trb.flags = TRB_3_TYPE(TRB_TYPE_RESET_ENDPOINT)
|
||||
| TRB_3_SLOT(slot) | TRB_3_ENDPOINT(endpoint);
|
||||
| TRB_3_SLOT(endpoint->device->slot) | TRB_3_ENDPOINT(endpoint->id + 1);
|
||||
if (preserve)
|
||||
trb.flags |= TRB_3_PRSV_BIT;
|
||||
|
||||
@ -2702,14 +2702,29 @@ XHCI::ResetEndpoint(bool preserve, uint8 endpoint, uint8 slot)
|
||||
|
||||
|
||||
status_t
|
||||
XHCI::StopEndpoint(bool suspend, uint8 endpoint, uint8 slot)
|
||||
XHCI::StopEndpoint(bool suspend, xhci_endpoint* endpoint)
|
||||
{
|
||||
TRACE("Stop Endpoint\n");
|
||||
struct xhci_device_ctx* device_ctx = endpoint->device->device_ctx;
|
||||
|
||||
// XHCI 1.2, 4.8.3 Endpoint State Diagram
|
||||
// Only exit from a HALTED state is a reset which will also stop the ep
|
||||
switch (ENDPOINT_0_STATE_GET(_ReadContext(
|
||||
&device_ctx->endpoints[endpoint->id].dwendpoint0))) {
|
||||
case ENDPOINT_STATE_HALTED:
|
||||
TRACE("Detected XHCI endpoint in halted state. Calling reset.");
|
||||
return ResetEndpoint(false, endpoint);
|
||||
case ENDPOINT_STATE_STOPPED:
|
||||
return B_OK;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
xhci_trb trb;
|
||||
trb.address = 0;
|
||||
trb.status = 0;
|
||||
trb.flags = TRB_3_TYPE(TRB_TYPE_STOP_ENDPOINT)
|
||||
| TRB_3_SLOT(slot) | TRB_3_ENDPOINT(endpoint);
|
||||
| TRB_3_SLOT(endpoint->device->slot) | TRB_3_ENDPOINT(endpoint->id + 1);
|
||||
if (suspend)
|
||||
trb.flags |= TRB_3_SUSPEND_ENDPOINT_BIT;
|
||||
|
||||
|
@ -185,10 +185,8 @@ private:
|
||||
bool deconfigure, uint8 slot);
|
||||
status_t EvaluateContext(uint64 inputContext,
|
||||
uint8 slot);
|
||||
status_t ResetEndpoint(bool preserve, uint8 endpoint,
|
||||
uint8 slot);
|
||||
status_t StopEndpoint(bool suspend, uint8 endpoint,
|
||||
uint8 slot);
|
||||
status_t ResetEndpoint(bool preserve, xhci_endpoint* endpoint);
|
||||
status_t StopEndpoint(bool suspend, xhci_endpoint* endpoint);
|
||||
status_t SetTRDequeue(uint64 dequeue, uint16 stream,
|
||||
uint8 endpoint, uint8 slot);
|
||||
status_t ResetDevice(uint8 slot);
|
||||
|
@ -385,8 +385,8 @@ struct xhci_endpoint_ctx {
|
||||
};
|
||||
|
||||
|
||||
#define ENDPOINT_0_STATE(x) ((x) & 0x3)
|
||||
#define ENDPOINT_0_STATE_GET(x) ((x) & 0x3)
|
||||
#define ENDPOINT_0_STATE(x) ((x) & 0x7)
|
||||
#define ENDPOINT_0_STATE_GET(x) ((x) & 0x7)
|
||||
#define ENDPOINT_0_MULT(x) (((x) & 0x3) << 8)
|
||||
#define ENDPOINT_0_MULT_GET(x) (((x) >> 8) & 0x3)
|
||||
#define ENDPOINT_0_MAXPSTREAMS(x) (((x) & 0x1F) << 10)
|
||||
@ -412,6 +412,14 @@ struct xhci_endpoint_ctx {
|
||||
#define ENDPOINT_4_MAXESITPAYLOAD(x) (((x) & 0xFFFF) << 16)
|
||||
#define ENDPOINT_4_MAXESITPAYLOAD_GET(x) (((x) >> 16) & 0xFFFF)
|
||||
|
||||
#define ENDPOINT_STATE_DISABLED 0
|
||||
#define ENDPOINT_STATE_RUNNING 1
|
||||
#define ENDPOINT_STATE_HALTED 2
|
||||
#define ENDPOINT_STATE_STOPPED 3
|
||||
#define ENDPOINT_STATE_ERROR 4
|
||||
#define ENDPOINT_STATE_RESERVED_5 5
|
||||
#define ENDPOINT_STATE_RESERVED_6 6
|
||||
#define ENDPOINT_STATE_RESERVED_7 7
|
||||
|
||||
struct xhci_stream_ctx {
|
||||
uint64 qwstream0;
|
||||
|
Loading…
Reference in New Issue
Block a user