Common use of Pause Clause in Contracts

Pause. When a Transfer Descriptor is retired with an error or when the upper layers of software desire to cancel a transfer request, all Transfer Descriptors associated with the same request must be removed from the queue of transfers on the endpoint. To do this, processing of the endpoint by the Host Controller must be paused before the Host Controller Driver can remove or otherwise alter the Transfer Descriptors on the endpoint’s queue. There are two ways that this is accomplished, depending on the reason for pausing the endpoint: ?? When the Host Controller retires a Transfer Descriptor with an error, it automatically pauses processing for that endpoint by setting the Halt bit in HC_ENDPOINT_DESCRIPTOR.HeadP. ?? When the upper layers of software initiate a cancel of a request, Host Controller Driver must set the HC_ENDPOINT_DESCRIPTOR.Control.sKip bit and then ensure that the Host Controller is not processing that endpoint. After setting the bit, Host Controller Driver must wait for the next frame before the endpoint is paused. VOID PauseED( IN PCHD_ENDPOINT Endpoint ) { PHCD_DEVICE_DATA DeviceData; PHCD_ENDPOINT_DESCRIPTOR ED; DeviceData = Endpoint->DeviceData; ED = Endpoint->HcdED; ED->HcED.Control.sKip = TRUE; if (ED->PausedFlag) return; // already awaiting pause processing if ( !(ED->HcED.HeadP & HcEDHeadP_HALT) ) { // // Endpoint is active in Host Controller, wait for SOF before processing the endpoint. // ED->PausedFlag = TRUE; DeviceData->HC->HcInterruptStatus = HC_INT_SOF; // clear SOF interrupt pending ED->ReclaimationFrame = Get32BitFrameNumber(DeviceData) + 1; InsertTailList (&DeviceData->PausedEDRestart, &ED->PausedLink); DeviceData->HC-> HcInterruptEnable = HC_INT_SOF; // interrupt on next SOF return; } // // Endpoint already paused, do processing now // ProcessPausedED(ED); } VOID ProcessPausedED ( PHCD_ENDPOINT_DESCRIPTOR ED ) { PHCD_ENDPOINT endpoint; PUSBD_REQUEST request; PHCD_TRANSFER_DESCRIPTOR td, last = NULL, *previous; BOOLEAN B4Head = TRUE; endpoint = ED->Endpoint; if (endpoint == NULL) return; td = endpoint->HcdHeadP; previous = &endpoint->HcdHeadP; while (td != endpoint->HcdTailP) { if ((ED->HcED.HeadP & ~0xF) == td->PhysicalAddress) B4Head = FALSE; if (ED->ListIndex == ED_EOF || td->CancelPending) { // cancel TD request = td->UsbdRequest; RemoveListEntry(&td->RequestList); if (IsListEmpty(&request->HcdList) { request->Status = USBD_CANCELED; CompleteUsbdRequest(request); } *previous = td->NextHcdTD; // point around TD if (last != NULL) last->HcED.NextTD = td->HcED.NextTD; if (B4Head) // TD on delayed Done List td->Status = TD_CANCELED; else FreeTransferDescriptor(td); } else { // don’t cancel TD previous = &td->NextHcdTD; if (!B4Head) last = td; } td = *previous; } ED->HcED.HeadP = endpoint->HcdHeadP->PhysicalAddress | (ED->HcED.HeadP & HcEDHeadP_CARRY); ED->HcED.Control.sKip = FALSE;

Appears in 1 contract

Sources: Adopter’s Agreement for Open Host Controller Interface Reciprocal Covenant

Pause. When a Transfer Descriptor is retired with an error or when the upper layers of software desire to cancel a transfer request, all Transfer Descriptors associated with the same request must be removed from the queue of transfers on the endpoint. To do this, processing of the endpoint by the Host Controller must be paused before the Host Controller Driver can remove or otherwise alter the Transfer Descriptors on the endpoint’s queue. There are two ways that this is accomplished, depending on the reason for pausing the endpoint: ?? When the Host Controller retires a Transfer Descriptor with an error, it automatically pauses processing for that endpoint by setting the Halt bit in HC_ENDPOINT_DESCRIPTOR.HeadP. ?? When the upper layers of software initiate a cancel of a request, Host Controller Driver must set the HC_ENDPOINT_DESCRIPTOR.Control.sKip bit and then ensure that the Host Controller is not processing that endpoint. After setting the bit, Host Controller Driver must wait for the next frame before the endpoint is paused. VOID PauseED( IN PCHD_ENDPOINT Endpoint ) { PHCD_DEVICE_DATA DeviceData; PHCD_ENDPOINT_DESCRIPTOR ED; DeviceData = Endpoint->DeviceData; ED = Endpoint->HcdED; ED->HcED.Control.sKip = TRUE; if (ED->PausedFlag) return; // already awaiting pause processing if ( !(ED->HcED.HeadP & HcEDHeadP_HALT) ) { // // Endpoint is active in Host Controller, wait for SOF before processing the endpoint. // ED->PausedFlag = TRUE; DeviceData->HC->HcInterruptStatus = HC_INT_SOF; // HC_INT_SOF;// clear SOF interrupt pending ED->ReclaimationFrame = Get32BitFrameNumber(DeviceData) + 1; InsertTailList (&DeviceData->PausedEDRestart, &ED->PausedLink); DeviceData->HC-> HcInterruptEnable = HC_INT_SOF; // HC_INT_SOF;// interrupt on next SOF return; } // // Endpoint already paused, do processing now // ProcessPausedED(ED); } VOID ProcessPausedED ( PHCD_ENDPOINT_DESCRIPTOR ED ) { PHCD_ENDPOINT endpoint; PUSBD_REQUEST request; PHCD_TRANSFER_DESCRIPTOR td, last = NULL, *previous; BOOLEAN B4Head = TRUE; endpoint = ED->Endpoint; if (endpoint == NULL) return; td = endpoint->HcdHeadP; previous = &endpoint->HcdHeadP; while (td != endpoint->HcdTailP) { if ((ED->HcED.HeadP & ~0xF) == td->PhysicalAddress) B4Head = FALSE; if (ED->ListIndex == ED_EOF || td->CancelPending) { {// cancel TD request = td->UsbdRequest; RemoveListEntry(&td->RequestList); if (IsListEmpty(&request->HcdList) { request->Status = USBD_CANCELED; CompleteUsbdRequest(request); } *previous = td->NextHcdTD; // point around TD if (last != NULL) last->HcED.NextTD = td->HcED.NextTD; if (B4Head) // TD on delayed Done List td->Status = TD_CANCELED; else FreeTransferDescriptor(td); } else { // don’t cancel TD previous = &td->NextHcdTD; if (!B4Head) last = td; } td = *previous; } ED->HcED.HeadP = endpoint->HcdHeadP->PhysicalAddress | (ED->HcED.HeadP & HcEDHeadP_CARRY); ED->HcED.Control.sKip = FALSE;

Appears in 1 contract

Sources: Adopter’s Agreement for Open Host Controller Interface Reciprocal Covenant