37 Urb->Signature = XHC_URB_SIG;
39 Urb->Ring = &Xhc->CmdRing;
42 Urb->TrbStart = Urb->Ring->RingEnqueue;
44 Urb->TrbStart->CycleBit = Urb->Ring->RingPCS & BIT0;
45 Urb->TrbEnd = Urb->TrbStart;
80 if ((Xhc ==
NULL) || (CmdTrb ==
NULL)) {
81 return EFI_INVALID_PARAMETER;
84 Status = EFI_DEVICE_ERROR;
87 DEBUG ((DEBUG_ERROR,
"XhcCmdTransfer: HC is halted\n"));
97 DEBUG ((DEBUG_ERROR,
"XhcCmdTransfer: failed to create URB\n"));
98 Status = EFI_OUT_OF_RESOURCES;
103 *EvtTrb = Urb->EvtTrb;
105 if (Urb->Result == EFI_USB_NOERROR) {
157 Urb->Signature = XHC_URB_SIG;
161 Ep->BusAddr = BusAddr;
162 Ep->EpAddr = (UINT8)(EpAddr & 0x0F);
163 Ep->Direction = ((EpAddr & 0x80) != 0) ? EfiUsbDataIn : EfiUsbDataOut;
164 Ep->DevSpeed = DevSpeed;
165 Ep->MaxPacket = MaxPacket;
168 Urb->Request = Request;
170 Urb->DataLen = DataLen;
171 Urb->Callback = Callback;
172 Urb->Context = Context;
175 if (EFI_ERROR (Status)) {
176 DEBUG ((DEBUG_ERROR,
"XhcCreateUrb: XhcCreateTransferTrb Failed, Status = %r\n", Status));
197 if ((Xhc ==
NULL) || (Urb ==
NULL)) {
201 if (Urb->DataMap !=
NULL) {
202 Xhc->PciIo->Unmap (Xhc->PciIo, Urb->DataMap);
239 return EFI_DEVICE_ERROR;
242 Urb->Finished =
FALSE;
243 Urb->StartDone =
FALSE;
244 Urb->EndDone =
FALSE;
246 Urb->Result = EFI_USB_NOERROR;
250 EPRing = (
TRANSFER_RING *)(
UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1];
251 if (EPRing ==
NULL) {
252 return EFI_OUT_OF_RESOURCES;
256 OutputContext = Xhc->UsbDevContext[SlotId].OutputContext;
257 if (Xhc->HcCParams.Data.Csz == 0) {
258 EPType = (UINT8)((
DEVICE_CONTEXT *)OutputContext)->EP[Dci-1].EPType;
266 if ((Urb->Data !=
NULL) && (Urb->DataMap ==
NULL)) {
267 if (((UINT8)(Urb->Ep.Direction)) == EfiUsbDataIn) {
274 Status = Xhc->PciIo->Map (Xhc->PciIo, MapOp, Urb->Data, &Len, &PhyAddr, &Map);
276 if (EFI_ERROR (Status) || (Len != Urb->DataLen)) {
277 DEBUG ((DEBUG_ERROR,
"XhcCreateTransferTrb: Fail to map Urb->Data.\n"));
278 return EFI_OUT_OF_RESOURCES;
281 Urb->DataPhy = (VOID *)((
UINTN)PhyAddr);
289 Urb->TrbStart = EPRing->RingEnqueue;
291 case ED_CONTROL_BIDIR:
295 TrbStart = (
TRB *)(
UINTN)EPRing->RingEnqueue;
296 TrbStart->TrbCtrSetup.bmRequestType = Urb->Request->RequestType;
297 TrbStart->TrbCtrSetup.bRequest = Urb->Request->Request;
298 TrbStart->TrbCtrSetup.wValue = Urb->Request->Value;
299 TrbStart->TrbCtrSetup.wIndex = Urb->Request->Index;
300 TrbStart->TrbCtrSetup.wLength = Urb->Request->Length;
301 TrbStart->TrbCtrSetup.Length = 8;
302 TrbStart->TrbCtrSetup.IntTarget = 0;
303 TrbStart->TrbCtrSetup.IOC = 1;
304 TrbStart->TrbCtrSetup.IDT = 1;
305 TrbStart->TrbCtrSetup.Type = TRB_TYPE_SETUP_STAGE;
306 if (Urb->DataLen > 0) {
307 if (Urb->Ep.Direction == EfiUsbDataIn) {
308 TrbStart->TrbCtrSetup.TRT = 3;
309 }
else if (Urb->Ep.Direction == EfiUsbDataOut) {
310 TrbStart->TrbCtrSetup.TRT = 2;
312 DEBUG ((DEBUG_ERROR,
"XhcCreateTransferTrb: Direction sholud be IN or OUT when Data exists!\n"));
316 TrbStart->TrbCtrSetup.TRT = 0;
322 TrbStart->TrbCtrSetup.CycleBit = EPRing->RingPCS & BIT0;
328 if (Urb->DataLen > 0) {
330 TrbStart = (
TRB *)(
UINTN)EPRing->RingEnqueue;
331 TrbStart->TrbCtrData.TRBPtrLo = XHC_LOW_32BIT (Urb->DataPhy);
332 TrbStart->TrbCtrData.TRBPtrHi = XHC_HIGH_32BIT (Urb->DataPhy);
333 TrbStart->TrbCtrData.Length = (UINT32)Urb->DataLen;
334 TrbStart->TrbCtrData.TDSize = 0;
335 TrbStart->TrbCtrData.IntTarget = 0;
336 TrbStart->TrbCtrData.ISP = 1;
337 TrbStart->TrbCtrData.IOC = 1;
338 TrbStart->TrbCtrData.IDT = 0;
339 TrbStart->TrbCtrData.CH = 0;
340 TrbStart->TrbCtrData.Type = TRB_TYPE_DATA_STAGE;
341 if (Urb->Ep.Direction == EfiUsbDataIn) {
342 TrbStart->TrbCtrData.DIR = 1;
343 }
else if (Urb->Ep.Direction == EfiUsbDataOut) {
344 TrbStart->TrbCtrData.DIR = 0;
346 TrbStart->TrbCtrData.DIR = 0;
352 TrbStart->TrbCtrData.CycleBit = EPRing->RingPCS & BIT0;
361 TrbStart = (
TRB *)(
UINTN)EPRing->RingEnqueue;
362 TrbStart->TrbCtrStatus.IntTarget = 0;
363 TrbStart->TrbCtrStatus.IOC = 1;
364 TrbStart->TrbCtrStatus.CH = 0;
365 TrbStart->TrbCtrStatus.Type = TRB_TYPE_STATUS_STAGE;
366 if (Urb->Ep.Direction == EfiUsbDataIn) {
367 TrbStart->TrbCtrStatus.DIR = 0;
368 }
else if (Urb->Ep.Direction == EfiUsbDataOut) {
369 TrbStart->TrbCtrStatus.DIR = 1;
371 TrbStart->TrbCtrStatus.DIR = 0;
377 TrbStart->TrbCtrStatus.CycleBit = EPRing->RingPCS & BIT0;
392 TrbStart = (
TRB *)(
UINTN)EPRing->RingEnqueue;
393 while (TotalLen < Urb->DataLen) {
394 if ((TotalLen + 0x10000) >= Urb->DataLen) {
395 Len = Urb->DataLen - TotalLen;
400 TrbStart = (
TRB *)(
UINTN)EPRing->RingEnqueue;
401 TrbStart->TrbNormal.TRBPtrLo = XHC_LOW_32BIT ((UINT8 *)Urb->DataPhy + TotalLen);
402 TrbStart->TrbNormal.TRBPtrHi = XHC_HIGH_32BIT ((UINT8 *)Urb->DataPhy + TotalLen);
403 TrbStart->TrbNormal.Length = (UINT32)Len;
404 TrbStart->TrbNormal.TDSize = 0;
405 TrbStart->TrbNormal.IntTarget = 0;
406 TrbStart->TrbNormal.ISP = 1;
407 TrbStart->TrbNormal.IOC = 1;
408 TrbStart->TrbNormal.Type = TRB_TYPE_NORMAL;
412 TrbStart->TrbNormal.CycleBit = EPRing->RingPCS & BIT0;
419 Urb->TrbNum = TrbNum;
423 case ED_INTERRUPT_OUT:
424 case ED_INTERRUPT_IN:
428 TrbStart = (
TRB *)(
UINTN)EPRing->RingEnqueue;
429 while (TotalLen < Urb->DataLen) {
430 if ((TotalLen + 0x10000) >= Urb->DataLen) {
431 Len = Urb->DataLen - TotalLen;
436 TrbStart = (
TRB *)(
UINTN)EPRing->RingEnqueue;
437 TrbStart->TrbNormal.TRBPtrLo = XHC_LOW_32BIT ((UINT8 *)Urb->DataPhy + TotalLen);
438 TrbStart->TrbNormal.TRBPtrHi = XHC_HIGH_32BIT ((UINT8 *)Urb->DataPhy + TotalLen);
439 TrbStart->TrbNormal.Length = (UINT32)Len;
440 TrbStart->TrbNormal.TDSize = 0;
441 TrbStart->TrbNormal.IntTarget = 0;
442 TrbStart->TrbNormal.ISP = 1;
443 TrbStart->TrbNormal.IOC = 1;
444 TrbStart->TrbNormal.Type = TRB_TYPE_NORMAL;
448 TrbStart->TrbNormal.CycleBit = EPRing->RingPCS & BIT0;
455 Urb->TrbNum = TrbNum;
460 DEBUG ((DEBUG_INFO,
"Not supported EPType 0x%x!\n", EPType));
484 UINT32 MaxScratchpadBufs;
487 UINT64 *ScratchEntry;
490 UINTN *ScratchEntryMap;
497 ASSERT (Xhc->MemPool !=
NULL);
503 Xhc->MaxSlotsEn = Xhc->HcSParams1.Data.MaxSlots;
504 ASSERT (Xhc->MaxSlotsEn >= 1 && Xhc->MaxSlotsEn <= 255);
513 Entries = (Xhc->MaxSlotsEn + 1) *
sizeof (UINT64);
515 ASSERT (Dcbaa !=
NULL);
523 MaxScratchpadBufs = ((Xhc->HcSParams2.Data.ScratchBufHi) << 5) | (Xhc->HcSParams2.Data.ScratchBufLo);
524 Xhc->MaxScratchpadBufs = MaxScratchpadBufs;
525 ASSERT (MaxScratchpadBufs <= 1023);
526 if (MaxScratchpadBufs != 0) {
531 ASSERT (ScratchEntryMap !=
NULL);
532 Xhc->ScratchEntryMap = ScratchEntryMap;
538 ASSERT (ScratchEntry !=
NULL);
539 Xhc->ScratchEntry = ScratchEntry;
546 (VOID **)&ScratchBuf,
552 ZeroMem (ScratchBuf, MaxScratchpadBufs *
sizeof (UINT64));
553 Xhc->ScratchBuf = ScratchBuf;
558 for (Index = 0; Index < MaxScratchpadBufs; Index++) {
564 (VOID **)&ScratchEntry[Index],
566 (VOID **)&ScratchEntryMap[Index]
569 ZeroMem ((VOID *)(
UINTN)ScratchEntry[Index], Xhc->PageSize);
573 *ScratchBuf++ = ScratchEntryPhy;
580 *(UINT64 *)Dcbaa = (UINT64)(
UINTN)ScratchPhy;
587 Xhc->DCBAA = (UINT64 *)(
UINTN)Dcbaa;
593 XhcWriteOpReg (Xhc, XHC_DCBAAP_OFFSET, XHC_LOW_32BIT (DcbaaPhy));
594 XhcWriteOpReg (Xhc, XHC_DCBAAP_OFFSET + 4, XHC_HIGH_32BIT (DcbaaPhy));
596 DEBUG ((DEBUG_INFO,
"XhcInitSched:DCBAA=0x%x\n", (UINT64)(
UINTN)Xhc->DCBAA));
610 CmdRing = (UINT64)(
UINTN)Xhc->CmdRing.RingSeg0;
612 ASSERT ((CmdRingPhy & 0x3F) == 0);
613 CmdRingPhy |= XHC_CRCR_RCS;
618 XhcWriteOpReg (Xhc, XHC_CRCR_OFFSET, XHC_LOW_32BIT (CmdRingPhy));
619 XhcWriteOpReg (Xhc, XHC_CRCR_OFFSET + 4, XHC_HIGH_32BIT (CmdRingPhy));
626 for (Index = 0; Index < (UINT16)(Xhc->HcSParams1.Data.MaxIntrs); Index++) {
637 "XhcInitSched: Created CMD ring [%p~%p) EVENT ring [%p~%p)\n",
638 Xhc->CmdRing.RingSeg0,
640 Xhc->EventRing.EventRingSeg0,
641 (
UINTN)Xhc->EventRing.EventRingSeg0 + sizeof (
TRB_TEMPLATE) * EVENT_RING_TRB_NUMBER
673 return EFI_DEVICE_ERROR;
679 DEBUG ((DEBUG_INFO,
"Recovery Halted Slot = %x,Dci = %x\n", SlotId, Dci));
685 if (EFI_ERROR (Status)) {
686 DEBUG ((DEBUG_ERROR,
"XhcRecoverHaltedEndpoint: Reset Endpoint Failed, Status = %r\n", Status));
694 if (EFI_ERROR (Status)) {
695 DEBUG ((DEBUG_ERROR,
"XhcRecoverHaltedEndpoint: Set Transfer Ring Dequeue Pointer Failed, Status = %r\n", Status));
736 return EFI_DEVICE_ERROR;
742 DEBUG ((DEBUG_VERBOSE,
"Stop Slot = %x,Dci = %x\n", SlotId, Dci));
748 if (EFI_ERROR (Status)) {
749 DEBUG ((DEBUG_ERROR,
"XhcDequeueTrbFromEndpoint: Stop Endpoint Failed, Status = %r\n", Status));
756 if (Urb->Finished && (Urb->Result == EFI_USB_NOERROR)) {
762 Status = EFI_ALREADY_STARTED;
763 DEBUG ((DEBUG_INFO,
"XhcDequeueTrbFromEndpoint: Pending URB is finished: Length Actual/Expect = %d/%d!\n", Urb->Completed, Urb->DataLen));
766 if (EFI_ERROR (Status)) {
767 DEBUG ((DEBUG_ERROR,
"XhcDequeueTrbFromEndpoint: Set Transfer Ring Dequeue Pointer Failed, Status = %r\n", Status));
800 ASSERT (EventRing !=
NULL);
804 ASSERT (Buf !=
NULL);
805 ASSERT (((
UINTN)Buf & 0x3F) == 0);
808 EventRing->EventRingSeg0 = Buf;
809 EventRing->TrbNumber = EVENT_RING_TRB_NUMBER;
810 EventRing->EventRingDequeue = (
TRB_TEMPLATE *)EventRing->EventRingSeg0;
811 EventRing->EventRingEnqueue = (
TRB_TEMPLATE *)EventRing->EventRingSeg0;
819 EventRing->EventRingCCS = 1;
823 ASSERT (Buf !=
NULL);
824 ASSERT (((
UINTN)Buf & 0x3F) == 0);
828 EventRing->ERSTBase = ERSTBase;
829 ERSTBase->PtrLo = XHC_LOW_32BIT (DequeuePhy);
830 ERSTBase->PtrHi = XHC_HIGH_32BIT (DequeuePhy);
831 ERSTBase->RingTrbSize = EVENT_RING_TRB_NUMBER;
852 XHC_LOW_32BIT ((UINT64)(
UINTN)DequeuePhy)
857 XHC_HIGH_32BIT ((UINT64)(
UINTN)DequeuePhy)
868 XHC_LOW_32BIT ((UINT64)(
UINTN)ERSTPhy)
872 XHC_ERSTBA_OFFSET + 4,
873 XHC_HIGH_32BIT ((UINT64)(
UINTN)ERSTPhy)
901 ASSERT (Buf !=
NULL);
902 ASSERT (((
UINTN)Buf & 0x3F) == 0);
905 TransferRing->RingSeg0 = Buf;
906 TransferRing->TrbNumber = TrbNum;
907 TransferRing->RingEnqueue = (
TRB_TEMPLATE *)TransferRing->RingSeg0;
908 TransferRing->RingDequeue = (
TRB_TEMPLATE *)TransferRing->RingSeg0;
909 TransferRing->RingPCS = 1;
916 EndTrb->Type = TRB_TYPE_LINK;
918 EndTrb->PtrLo = XHC_LOW_32BIT (PhyAddr);
919 EndTrb->PtrHi = XHC_HIGH_32BIT (PhyAddr);
927 EndTrb->CycleBit = 0;
944 if (EventRing->EventRingSeg0 ==
NULL) {
972 UINT64 *ScratchEntry;
974 if (Xhc->ScratchBuf !=
NULL) {
975 ScratchEntry = Xhc->ScratchEntry;
976 for (Index = 0; Index < Xhc->MaxScratchpadBufs; Index++) {
991 if (Xhc->CmdRing.RingSeg0 !=
NULL) {
993 Xhc->CmdRing.RingSeg0 =
NULL;
998 if (Xhc->DCBAA !=
NULL) {
999 UsbHcFreeMem (Xhc->MemPool, Xhc->DCBAA, (Xhc->MaxSlotsEn + 1) * sizeof (UINT64));
1006 if (Xhc->MemPool !=
NULL) {
1008 Xhc->MemPool =
NULL;
1035 CheckedTrb = Urb->TrbStart;
1036 for (Index = 0; Index < Urb->TrbNum; Index++) {
1037 if (Trb == CheckedTrb) {
1046 if (CheckedTrb->Type == TRB_TYPE_LINK) {
1050 ASSERT (CheckedTrb == Urb->Ring->RingSeg0);
1080 CheckedUrb = EFI_LIST_CONTAINER (Entry,
URB, UrbList);
1118 ASSERT ((Xhc !=
NULL) && (Urb !=
NULL));
1123 if (Urb->Finished) {
1130 Urb->Result |= EFI_USB_ERR_SYSTEM;
1138 for (Index = 0; Index < Xhc->EventRing.TrbNumber; Index++) {
1140 if (Status == EFI_NOT_READY) {
1150 if ((EvtTrb->Type != TRB_TYPE_COMMAND_COMPLT_EVENT) && (EvtTrb->Type != TRB_TYPE_TRANS_EVENT)) {
1167 CheckedUrb = Xhc->PendingUrb;
1171 CheckedUrb = AsyncUrb;
1176 switch (EvtTrb->Completecode) {
1177 case TRB_COMPLETION_STALL_ERROR:
1178 CheckedUrb->Result |= EFI_USB_ERR_STALL;
1179 CheckedUrb->Finished =
TRUE;
1180 DEBUG ((DEBUG_ERROR,
"XhcCheckUrbResult: STALL_ERROR! Completecode = %x\n", EvtTrb->Completecode));
1183 case TRB_COMPLETION_BABBLE_ERROR:
1184 CheckedUrb->Result |= EFI_USB_ERR_BABBLE;
1185 CheckedUrb->Finished =
TRUE;
1186 DEBUG ((DEBUG_ERROR,
"XhcCheckUrbResult: BABBLE_ERROR! Completecode = %x\n", EvtTrb->Completecode));
1189 case TRB_COMPLETION_DATA_BUFFER_ERROR:
1190 CheckedUrb->Result |= EFI_USB_ERR_BUFFER;
1191 CheckedUrb->Finished =
TRUE;
1192 DEBUG ((DEBUG_ERROR,
"XhcCheckUrbResult: ERR_BUFFER! Completecode = %x\n", EvtTrb->Completecode));
1198 case TRB_COMPLETION_USB_TRANSACTION_ERROR:
1199 CheckedUrb->Result |= EDKII_USB_ERR_TRANSACTION;
1200 CheckedUrb->Finished =
TRUE;
1201 DEBUG ((DEBUG_ERROR,
"XhcCheckUrbResult: TRANSACTION_ERROR! Completecode = %x\n", EvtTrb->Completecode));
1204 case TRB_COMPLETION_STOPPED:
1205 case TRB_COMPLETION_STOPPED_LENGTH_INVALID:
1206 CheckedUrb->Result |= EFI_USB_ERR_TIMEOUT;
1207 CheckedUrb->Finished =
TRUE;
1214 case TRB_COMPLETION_SHORT_PACKET:
1215 case TRB_COMPLETION_SUCCESS:
1216 if (EvtTrb->Completecode == TRB_COMPLETION_SHORT_PACKET) {
1217 DEBUG ((DEBUG_VERBOSE,
"XhcCheckUrbResult: short packet happens!\n"));
1220 TRBType = (UINT8)(TRBPtr->Type);
1221 if ((TRBType == TRB_TYPE_DATA_STAGE) ||
1222 (TRBType == TRB_TYPE_NORMAL) ||
1223 (TRBType == TRB_TYPE_ISOCH))
1231 DEBUG ((DEBUG_ERROR,
"Transfer Default Error Occur! Completecode = 0x%x!\n", EvtTrb->Completecode));
1232 CheckedUrb->Result |= EFI_USB_ERR_TIMEOUT;
1233 CheckedUrb->Finished =
TRUE;
1240 if (TRBPtr == CheckedUrb->TrbStart) {
1241 CheckedUrb->StartDone =
TRUE;
1244 if (TRBPtr == CheckedUrb->TrbEnd) {
1245 CheckedUrb->EndDone =
TRUE;
1248 if (CheckedUrb->StartDone && CheckedUrb->EndDone) {
1249 CheckedUrb->Finished =
TRUE;
1264 XhcDequeue = (UINT64)(
LShiftU64 ((UINT64)High, 32) | Low);
1268 if ((XhcDequeue & (~0x0F)) != (PhyAddr & (~0x0F))) {
1277 return Urb->Finished;
1296 IN BOOLEAN CmdTransfer,
1305 UINT64 TimeoutTicks;
1306 UINT64 ElapsedTicks;
1309 BOOLEAN IndefiniteTimeout;
1313 IndefiniteTimeout =
FALSE;
1321 return EFI_DEVICE_ERROR;
1329 IndefiniteTimeout =
TRUE;
1335 XHC_MICROSECOND_TO_NANOSECOND (
1336 Timeout * XHC_1_MILLISECOND
1348 gBS->Stall (XHC_1_MICROSECOND);
1351 if (TicksDelta == 0) {
1355 ElapsedTicks += TicksDelta;
1356 }
while (IndefiniteTimeout || ElapsedTicks < TimeoutTicks);
1359 Urb->Result = EFI_USB_ERR_TIMEOUT;
1360 Status = EFI_TIMEOUT;
1361 }
else if (Urb->Result != EFI_USB_NOERROR) {
1362 Status = EFI_DEVICE_ERROR;
1393 Direction = ((EpNum & 0x80) != 0) ? EfiUsbDataIn : EfiUsbDataOut;
1399 Urb = EFI_LIST_CONTAINER (Entry,
URB, UrbList);
1400 if ((Urb->Ep.BusAddr == BusAddr) &&
1401 (Urb->Ep.EpAddr == EpNum) &&
1402 (Urb->Ep.Direction == Direction))
1409 if (EFI_ERROR (Status)) {
1410 DEBUG ((DEBUG_ERROR,
"XhciDelAsyncIntTransfer: XhcDequeueTrbFromEndpoint failed\n"));
1420 return EFI_NOT_FOUND;
1440 Urb = EFI_LIST_CONTAINER (Entry,
URB, UrbList);
1447 if (EFI_ERROR (Status)) {
1448 DEBUG ((DEBUG_ERROR,
"XhciDelAllAsyncIntTransfers: XhcDequeueTrbFromEndpoint failed\n"));
1490 DEBUG ((DEBUG_ERROR,
"%a: failed to allocate buffer\n", __func__));
1500 XHC_INT_TRANSFER_ASYNC,
1508 DEBUG ((DEBUG_ERROR,
"%a: failed to create URB\n", __func__));
1537 if (Urb->Result == EFI_USB_NOERROR) {
1539 if (EFI_ERROR (Status)) {
1544 if (EFI_ERROR (Status)) {
1577 if (Urb->Ep.Direction == EfiUsbDataIn) {
1583 if (Urb->DataMap !=
NULL) {
1584 Status = PciIo->Unmap (PciIo, Urb->DataMap);
1585 if (EFI_ERROR (Status)) {
1590 Urb->DataMap =
NULL;
1592 Status = PciIo->Map (PciIo, MapOp, Urb->Data, &Len, &PhyAddr, &Map);
1593 if (EFI_ERROR (Status) || (Len != Urb->DataLen)) {
1597 Urb->DataPhy = (VOID *)((
UINTN)PhyAddr);
1602 return EFI_DEVICE_ERROR;
1628 OldTpl =
gBS->RaiseTPL (XHC_TPL);
1633 Urb = EFI_LIST_CONTAINER (Entry,
URB, UrbList);
1649 if (!Urb->Finished) {
1658 if (EFI_ERROR (Status)) {
1659 DEBUG ((DEBUG_ERROR,
"XhcMonitorAsyncRequests: Fail to Flush AsyncInt Mapped Memeory\n"));
1668 if (Urb->Result == EFI_USB_NOERROR) {
1672 if (Urb->Completed <= Urb->DataLen) {
1676 if (ProcBuf ==
NULL) {
1681 CopyMem (ProcBuf, Urb->Data, Urb->Completed);
1694 if (Urb->Callback !=
NULL) {
1699 gBS->RestoreTPL (OldTpl);
1700 (Urb->Callback)(ProcBuf, Urb->Completed, Urb->Context, Urb->Result);
1701 OldTpl =
gBS->RaiseTPL (XHC_TPL);
1704 if (ProcBuf !=
NULL) {
1705 gBS->FreePool (ProcBuf);
1710 gBS->RestoreTPL (OldTpl);
1741 Retries = XHC_INIT_DEVICE_SLOT_RETRIES;
1743 if ((PortState->PortChangeStatus & (
USB_PORT_STAT_C_CONNECTION | USB_PORT_STAT_C_ENABLE | USB_PORT_STAT_C_OVERCURRENT | USB_PORT_STAT_C_RESET)) == 0) {
1747 if (ParentRouteChart.Dword == 0) {
1748 RouteChart.Route.RouteString = 0;
1749 RouteChart.Route.RootPortNum = Port + 1;
1750 RouteChart.Route.TierNum = 1;
1753 RouteChart.Route.RouteString = ParentRouteChart.Route.RouteString | (Port << (4 * (ParentRouteChart.Route.TierNum - 1)));
1755 RouteChart.Route.RouteString = ParentRouteChart.Route.RouteString | (15 << (4 * (ParentRouteChart.Route.TierNum - 1)));
1758 RouteChart.Route.RootPortNum = ParentRouteChart.Route.RootPortNum;
1759 RouteChart.Route.TierNum = ParentRouteChart.Route.TierNum + 1;
1764 if (Xhc->HcCParams.Data.Csz == 0) {
1771 if (((PortState->PortStatus & USB_PORT_STAT_ENABLE) != 0) &&
1777 Speed = EFI_USB_SPEED_FULL;
1778 if ((PortState->PortStatus & USB_PORT_STAT_LOW_SPEED) != 0) {
1779 Speed = EFI_USB_SPEED_LOW;
1780 }
else if ((PortState->PortStatus & USB_PORT_STAT_HIGH_SPEED) != 0) {
1781 Speed = EFI_USB_SPEED_HIGH;
1782 }
else if ((PortState->PortStatus & USB_PORT_STAT_SUPER_SPEED) != 0) {
1791 if ((SlotId == 0) && ((PortState->PortChangeStatus & USB_PORT_STAT_C_RESET) != 0)) {
1792 if (Xhc->HcCParams.Data.Csz == 0) {
1807 }
while ((Status == EFI_DEVICE_ERROR) && (Retries-- != 0));
1833 Index = (UINT8)(2 * EpAddr);
1834 if (Direction == EfiUsbDataIn) {
1860 for (Index = 0; Index < 255; Index++) {
1861 if (Xhc->UsbDevContext[Index + 1].Enabled &&
1862 (Xhc->UsbDevContext[Index + 1].SlotId != 0) &&
1863 (Xhc->UsbDevContext[Index + 1].BusDevAddr == BusDevAddr))
1873 return Xhc->UsbDevContext[Index + 1].SlotId;
1894 for (Index = 0; Index < 255; Index++) {
1895 if (Xhc->UsbDevContext[Index + 1].Enabled &&
1896 (Xhc->UsbDevContext[Index + 1].SlotId != 0) &&
1897 (Xhc->UsbDevContext[Index + 1].RouteString.Dword == RouteString.Dword))
1907 return Xhc->UsbDevContext[Index + 1].SlotId;
1929 ASSERT (EvtRing !=
NULL);
1935 EvtTrb1 = EvtRing->EventRingDequeue;
1937 for (Index = 0; Index < EvtRing->TrbNumber; Index++) {
1938 if (EvtTrb1->CycleBit != EvtRing->EventRingCCS) {
1945 EvtTrb1 = EvtRing->EventRingSeg0;
1946 EvtRing->EventRingCCS = (EvtRing->EventRingCCS) ? 0 : 1;
1950 if (Index < EvtRing->TrbNumber) {
1951 EvtRing->EventRingEnqueue = EvtTrb1;
1978 ASSERT (TrsRing !=
NULL);
1982 TrsTrb = TrsRing->RingEnqueue;
1983 ASSERT (TrsTrb !=
NULL);
1985 for (Index = 0; Index < TrsRing->TrbNumber; Index++) {
1986 if (TrsTrb->CycleBit != (TrsRing->RingPCS & BIT0)) {
1991 if ((UINT8)TrsTrb->Type == TRB_TYPE_LINK) {
1992 ASSERT (((
LINK_TRB *)TrsTrb)->TC != 0);
1996 ((
LINK_TRB *)TrsTrb)->CycleBit = TrsRing->RingPCS & BIT0;
2000 TrsRing->RingPCS = (TrsRing->RingPCS & BIT0) ? 0 : 1;
2005 ASSERT (Index != TrsRing->TrbNumber);
2007 if (TrsTrb != TrsRing->RingEnqueue) {
2008 TrsRing->RingEnqueue = TrsTrb;
2014 TrsTrb->Parameter1 = 0;
2015 TrsTrb->Parameter2 = 0;
2019 TrsTrb->Control = 0;
2043 ASSERT (EvtRing !=
NULL);
2045 *NewEvtTrb = EvtRing->EventRingDequeue;
2047 if (EvtRing->EventRingDequeue == EvtRing->EventRingEnqueue) {
2048 return EFI_NOT_READY;
2051 EvtRing->EventRingDequeue++;
2055 if ((
UINTN)EvtRing->EventRingDequeue >= ((
UINTN)EvtRing->EventRingSeg0 + sizeof (
TRB_TEMPLATE) * EvtRing->TrbNumber)) {
2056 EvtRing->EventRingDequeue = EvtRing->EventRingSeg0;
2129 DEBUG ((DEBUG_INFO,
"Command Ring Control set Command Abort, SlotId: %d\n", SlotId));
2150 IN UINT16 ParentPort,
2152 IN UINT8 DeviceSpeed
2161 UINT8 DeviceAddress;
2170 CmdTrb.CycleBit = 1;
2171 CmdTrb.Type = TRB_TYPE_EN_SLOT;
2176 XHC_GENERIC_TIMEOUT,
2179 if (EFI_ERROR (Status) || (EvtTrb ==
NULL)) {
2180 DEBUG ((DEBUG_ERROR,
"XhcInitializeDeviceSlot: Enable Slot Failed, Status = %r\n", Status));
2184 ASSERT (EvtTrb->SlotId <= Xhc->MaxSlotsEn);
2185 DEBUG ((DEBUG_INFO,
"Enable Slot Successfully, The Slot ID = 0x%x\n", EvtTrb->SlotId));
2186 SlotId = (UINT8)EvtTrb->SlotId;
2187 ASSERT (SlotId != 0);
2190 Xhc->UsbDevContext[SlotId].Enabled =
TRUE;
2191 Xhc->UsbDevContext[SlotId].SlotId = SlotId;
2192 Xhc->UsbDevContext[SlotId].RouteString.Dword = RouteChart.Dword;
2193 Xhc->UsbDevContext[SlotId].ParentRouteString.Dword = ParentRouteChart.Dword;
2200 ASSERT (InputContext !=
NULL);
2201 ASSERT (((
UINTN)InputContext & 0x3F) == 0);
2204 Xhc->UsbDevContext[SlotId].InputContext = (VOID *)InputContext;
2211 InputContext->InputControlContext.Dword2 |= (BIT0 | BIT1);
2216 InputContext->Slot.RouteString = RouteChart.Route.RouteString;
2217 InputContext->Slot.Speed = DeviceSpeed + 1;
2218 InputContext->Slot.ContextEntries = 1;
2219 InputContext->Slot.RootHubPortNum = RouteChart.Route.RootPortNum;
2221 if (RouteChart.Route.RouteString) {
2226 ASSERT (ParentSlotId != 0);
2230 ParentDeviceContext = (
DEVICE_CONTEXT *)Xhc->UsbDevContext[ParentSlotId].OutputContext;
2231 if ((ParentDeviceContext->Slot.TTPortNum == 0) &&
2232 (ParentDeviceContext->Slot.TTHubSlotId == 0))
2234 if ((ParentDeviceContext->Slot.Speed == (EFI_USB_SPEED_HIGH + 1)) && (DeviceSpeed < EFI_USB_SPEED_HIGH)) {
2239 InputContext->Slot.TTPortNum = ParentPort;
2240 InputContext->Slot.TTHubSlotId = ParentSlotId;
2246 InputContext->Slot.TTPortNum = ParentDeviceContext->Slot.TTPortNum;
2247 InputContext->Slot.TTHubSlotId = ParentDeviceContext->Slot.TTHubSlotId;
2251 if (DeviceSpeed == EFI_USB_SPEED_HIGH) {
2252 InputContext->Slot.Speed = ParentDeviceContext->Slot.Speed;
2261 Xhc->UsbDevContext[SlotId].EndpointTransferRing[0] = EndpointTransferRing;
2266 InputContext->EP[0].EPType = ED_CONTROL_BIDIR;
2269 InputContext->EP[0].MaxPacketSize = 512;
2270 }
else if (DeviceSpeed == EFI_USB_SPEED_HIGH) {
2271 InputContext->EP[0].MaxPacketSize = 64;
2273 InputContext->EP[0].MaxPacketSize = 8;
2280 InputContext->EP[0].AverageTRBLength = 8;
2281 InputContext->EP[0].MaxBurstSize = 0;
2282 InputContext->EP[0].Interval = 0;
2283 InputContext->EP[0].MaxPStreams = 0;
2284 InputContext->EP[0].Mult = 0;
2285 InputContext->EP[0].CErr = 3;
2292 ((
TRANSFER_RING *)(
UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[0])->RingSeg0,
2296 InputContext->EP[0].PtrLo = XHC_LOW_32BIT (PhyAddr) | BIT0;
2297 InputContext->EP[0].PtrHi = XHC_HIGH_32BIT (PhyAddr);
2303 ASSERT (OutputContext !=
NULL);
2304 ASSERT (((
UINTN)OutputContext & 0x3F) == 0);
2307 Xhc->UsbDevContext[SlotId].OutputContext = OutputContext;
2316 Xhc->DCBAA[SlotId] = (UINT64)(
UINTN)PhyAddr;
2325 gBS->Stall (XHC_RESET_RECOVERY_DELAY);
2326 ZeroMem (&CmdTrbAddr,
sizeof (CmdTrbAddr));
2328 CmdTrbAddr.PtrLo = XHC_LOW_32BIT (PhyAddr);
2329 CmdTrbAddr.PtrHi = XHC_HIGH_32BIT (PhyAddr);
2330 CmdTrbAddr.CycleBit = 1;
2331 CmdTrbAddr.Type = TRB_TYPE_ADDRESS_DEV;
2332 CmdTrbAddr.SlotId = Xhc->UsbDevContext[SlotId].SlotId;
2336 XHC_GENERIC_TIMEOUT,
2339 if (!EFI_ERROR (Status)) {
2340 DeviceAddress = (UINT8)((
DEVICE_CONTEXT *)OutputContext)->Slot.DeviceAddress;
2341 DEBUG ((DEBUG_INFO,
" Address %d assigned successfully\n", DeviceAddress));
2342 Xhc->UsbDevContext[SlotId].XhciDevAddr = DeviceAddress;
2344 DEBUG ((DEBUG_ERROR,
" Slot %d address not assigned successfully. Status = %r\n", SlotId, Status));
2349 if (Status == EFI_TIMEOUT) {
2376 IN UINT16 ParentPort,
2378 IN UINT8 DeviceSpeed
2387 UINT8 DeviceAddress;
2396 CmdTrb.CycleBit = 1;
2397 CmdTrb.Type = TRB_TYPE_EN_SLOT;
2402 XHC_GENERIC_TIMEOUT,
2405 if (EFI_ERROR (Status) || (EvtTrb ==
NULL)) {
2406 DEBUG ((DEBUG_ERROR,
"XhcInitializeDeviceSlot64: Enable Slot Failed, Status = %r\n", Status));
2410 ASSERT (EvtTrb->SlotId <= Xhc->MaxSlotsEn);
2411 DEBUG ((DEBUG_INFO,
"Enable Slot Successfully, The Slot ID = 0x%x\n", EvtTrb->SlotId));
2412 SlotId = (UINT8)EvtTrb->SlotId;
2413 ASSERT (SlotId != 0);
2416 Xhc->UsbDevContext[SlotId].Enabled =
TRUE;
2417 Xhc->UsbDevContext[SlotId].SlotId = SlotId;
2418 Xhc->UsbDevContext[SlotId].RouteString.Dword = RouteChart.Dword;
2419 Xhc->UsbDevContext[SlotId].ParentRouteString.Dword = ParentRouteChart.Dword;
2426 ASSERT (InputContext !=
NULL);
2427 ASSERT (((
UINTN)InputContext & 0x3F) == 0);
2430 Xhc->UsbDevContext[SlotId].InputContext = (VOID *)InputContext;
2437 InputContext->InputControlContext.Dword2 |= (BIT0 | BIT1);
2442 InputContext->Slot.RouteString = RouteChart.Route.RouteString;
2443 InputContext->Slot.Speed = DeviceSpeed + 1;
2444 InputContext->Slot.ContextEntries = 1;
2445 InputContext->Slot.RootHubPortNum = RouteChart.Route.RootPortNum;
2447 if (RouteChart.Route.RouteString) {
2452 ASSERT (ParentSlotId != 0);
2456 ParentDeviceContext = (
DEVICE_CONTEXT_64 *)Xhc->UsbDevContext[ParentSlotId].OutputContext;
2457 if ((ParentDeviceContext->Slot.TTPortNum == 0) &&
2458 (ParentDeviceContext->Slot.TTHubSlotId == 0))
2460 if ((ParentDeviceContext->Slot.Speed == (EFI_USB_SPEED_HIGH + 1)) && (DeviceSpeed < EFI_USB_SPEED_HIGH)) {
2465 InputContext->Slot.TTPortNum = ParentPort;
2466 InputContext->Slot.TTHubSlotId = ParentSlotId;
2472 InputContext->Slot.TTPortNum = ParentDeviceContext->Slot.TTPortNum;
2473 InputContext->Slot.TTHubSlotId = ParentDeviceContext->Slot.TTHubSlotId;
2477 if (DeviceSpeed == EFI_USB_SPEED_HIGH) {
2478 InputContext->Slot.Speed = ParentDeviceContext->Slot.Speed;
2487 Xhc->UsbDevContext[SlotId].EndpointTransferRing[0] = EndpointTransferRing;
2492 InputContext->EP[0].EPType = ED_CONTROL_BIDIR;
2495 InputContext->EP[0].MaxPacketSize = 512;
2496 }
else if (DeviceSpeed == EFI_USB_SPEED_HIGH) {
2497 InputContext->EP[0].MaxPacketSize = 64;
2499 InputContext->EP[0].MaxPacketSize = 8;
2506 InputContext->EP[0].AverageTRBLength = 8;
2507 InputContext->EP[0].MaxBurstSize = 0;
2508 InputContext->EP[0].Interval = 0;
2509 InputContext->EP[0].MaxPStreams = 0;
2510 InputContext->EP[0].Mult = 0;
2511 InputContext->EP[0].CErr = 3;
2518 ((
TRANSFER_RING *)(
UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[0])->RingSeg0,
2522 InputContext->EP[0].PtrLo = XHC_LOW_32BIT (PhyAddr) | BIT0;
2523 InputContext->EP[0].PtrHi = XHC_HIGH_32BIT (PhyAddr);
2529 ASSERT (OutputContext !=
NULL);
2530 ASSERT (((
UINTN)OutputContext & 0x3F) == 0);
2533 Xhc->UsbDevContext[SlotId].OutputContext = OutputContext;
2542 Xhc->DCBAA[SlotId] = (UINT64)(
UINTN)PhyAddr;
2551 gBS->Stall (XHC_RESET_RECOVERY_DELAY);
2552 ZeroMem (&CmdTrbAddr,
sizeof (CmdTrbAddr));
2554 CmdTrbAddr.PtrLo = XHC_LOW_32BIT (PhyAddr);
2555 CmdTrbAddr.PtrHi = XHC_HIGH_32BIT (PhyAddr);
2556 CmdTrbAddr.CycleBit = 1;
2557 CmdTrbAddr.Type = TRB_TYPE_ADDRESS_DEV;
2558 CmdTrbAddr.SlotId = Xhc->UsbDevContext[SlotId].SlotId;
2562 XHC_GENERIC_TIMEOUT,
2565 if (!EFI_ERROR (Status)) {
2566 DeviceAddress = (UINT8)((
DEVICE_CONTEXT_64 *)OutputContext)->Slot.DeviceAddress;
2567 DEBUG ((DEBUG_INFO,
" Address %d assigned successfully\n", DeviceAddress));
2568 Xhc->UsbDevContext[SlotId].XhciDevAddr = DeviceAddress;
2570 DEBUG ((DEBUG_ERROR,
" Slot %d address not assigned successfully. Status = %r\n", SlotId, Status));
2575 if (Status == EFI_TIMEOUT) {
2613 for (Index = 0; Index < 255; Index++) {
2614 if (!Xhc->UsbDevContext[Index + 1].Enabled ||
2615 (Xhc->UsbDevContext[Index + 1].SlotId == 0) ||
2616 (Xhc->UsbDevContext[Index + 1].ParentRouteString.Dword != Xhc->UsbDevContext[SlotId].RouteString.Dword))
2623 if (EFI_ERROR (Status)) {
2624 DEBUG ((DEBUG_ERROR,
"XhcDisableSlotCmd: failed to disable child, ignore error\n"));
2625 Xhc->UsbDevContext[Index + 1].SlotId = 0;
2632 DEBUG ((DEBUG_INFO,
"Disable device slot %d!\n", SlotId));
2634 ZeroMem (&CmdTrbDisSlot,
sizeof (CmdTrbDisSlot));
2635 CmdTrbDisSlot.CycleBit = 1;
2636 CmdTrbDisSlot.Type = TRB_TYPE_DIS_SLOT;
2637 CmdTrbDisSlot.SlotId = SlotId;
2641 XHC_GENERIC_TIMEOUT,
2644 if (EFI_ERROR (Status) || (EvtTrb ==
NULL)) {
2645 DEBUG ((DEBUG_ERROR,
"XhcDisableSlotCmd: Disable Slot Command Failed, Status = %r\n", Status));
2652 Xhc->DCBAA[SlotId] = 0;
2657 for (Index = 0; Index < 31; Index++) {
2658 if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index] !=
NULL) {
2659 RingSeg = ((
TRANSFER_RING *)(
UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index])->RingSeg0;
2660 if (RingSeg !=
NULL) {
2664 FreePool (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index]);
2665 Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index] =
NULL;
2669 for (Index = 0; Index < Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations; Index++) {
2670 if (Xhc->UsbDevContext[SlotId].ConfDesc[Index] !=
NULL) {
2671 FreePool (Xhc->UsbDevContext[SlotId].ConfDesc[Index]);
2675 if (Xhc->UsbDevContext[SlotId].ActiveAlternateSetting !=
NULL) {
2676 FreePool (Xhc->UsbDevContext[SlotId].ActiveAlternateSetting);
2679 if (Xhc->UsbDevContext[SlotId].InputContext !=
NULL) {
2683 if (Xhc->UsbDevContext[SlotId].OutputContext !=
NULL) {
2692 Xhc->UsbDevContext[SlotId].Enabled =
FALSE;
2693 Xhc->UsbDevContext[SlotId].SlotId = 0;
2726 for (Index = 0; Index < 255; Index++) {
2727 if (!Xhc->UsbDevContext[Index + 1].Enabled ||
2728 (Xhc->UsbDevContext[Index + 1].SlotId == 0) ||
2729 (Xhc->UsbDevContext[Index + 1].ParentRouteString.Dword != Xhc->UsbDevContext[SlotId].RouteString.Dword))
2736 if (EFI_ERROR (Status)) {
2737 DEBUG ((DEBUG_ERROR,
"XhcDisableSlotCmd: failed to disable child, ignore error\n"));
2738 Xhc->UsbDevContext[Index + 1].SlotId = 0;
2745 DEBUG ((DEBUG_INFO,
"Disable device slot %d!\n", SlotId));
2747 ZeroMem (&CmdTrbDisSlot,
sizeof (CmdTrbDisSlot));
2748 CmdTrbDisSlot.CycleBit = 1;
2749 CmdTrbDisSlot.Type = TRB_TYPE_DIS_SLOT;
2750 CmdTrbDisSlot.SlotId = SlotId;
2754 XHC_GENERIC_TIMEOUT,
2757 if (EFI_ERROR (Status) || (EvtTrb ==
NULL)) {
2758 DEBUG ((DEBUG_ERROR,
"XhcDisableSlotCmd: Disable Slot Command Failed, Status = %r\n", Status));
2765 Xhc->DCBAA[SlotId] = 0;
2770 for (Index = 0; Index < 31; Index++) {
2771 if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index] !=
NULL) {
2772 RingSeg = ((
TRANSFER_RING *)(
UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index])->RingSeg0;
2773 if (RingSeg !=
NULL) {
2777 FreePool (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index]);
2778 Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index] =
NULL;
2782 for (Index = 0; Index < Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations; Index++) {
2783 if (Xhc->UsbDevContext[SlotId].ConfDesc[Index] !=
NULL) {
2784 FreePool (Xhc->UsbDevContext[SlotId].ConfDesc[Index]);
2788 if (Xhc->UsbDevContext[SlotId].ActiveAlternateSetting !=
NULL) {
2789 FreePool (Xhc->UsbDevContext[SlotId].ActiveAlternateSetting);
2792 if (Xhc->UsbDevContext[SlotId].InputContext !=
NULL) {
2796 if (Xhc->UsbDevContext[SlotId].OutputContext !=
NULL) {
2805 Xhc->UsbDevContext[SlotId].Enabled =
FALSE;
2806 Xhc->UsbDevContext[SlotId].SlotId = 0;
2828 IN UINT8 DeviceSpeed,
2846 NumEp = IfDesc->NumEndpoints;
2852 for (EpIndex = 0; EpIndex < NumEp; EpIndex++) {
2853 while (EpDesc->DescriptorType != USB_DESC_TYPE_ENDPOINT) {
2862 EpAddr = (UINT8)(EpDesc->EndpointAddress & 0x0F);
2863 Direction = (UINT8)((EpDesc->EndpointAddress & 0x80) ? EfiUsbDataIn : EfiUsbDataOut);
2871 InputContext->InputControlContext.Dword2 |= (BIT0 << Dci);
2872 InputContext->EP[Dci-1].MaxPacketSize = EpDesc->MaxPacketSize;
2878 InputContext->EP[Dci-1].MaxBurstSize = 0x0;
2880 InputContext->EP[Dci-1].MaxBurstSize = 0x0;
2883 switch (EpDesc->Attributes & USB_ENDPOINT_TYPE_MASK) {
2884 case USB_ENDPOINT_BULK:
2885 if (Direction == EfiUsbDataIn) {
2886 InputContext->EP[Dci-1].CErr = 3;
2887 InputContext->EP[Dci-1].EPType = ED_BULK_IN;
2889 InputContext->EP[Dci-1].CErr = 3;
2890 InputContext->EP[Dci-1].EPType = ED_BULK_OUT;
2893 InputContext->EP[Dci-1].AverageTRBLength = 0x1000;
2894 if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] ==
NULL) {
2896 Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *)EndpointTransferRing;
2900 "Endpoint[%x]: Created BULK ring [%p~%p)\n",
2901 EpDesc->EndpointAddress,
2902 EndpointTransferRing->RingSeg0,
2903 (
UINTN)EndpointTransferRing->RingSeg0 + TR_RING_TRB_NUMBER * sizeof (
TRB_TEMPLATE)
2908 case USB_ENDPOINT_ISO:
2909 if (Direction == EfiUsbDataIn) {
2910 InputContext->EP[Dci-1].CErr = 0;
2911 InputContext->EP[Dci-1].EPType = ED_ISOCH_IN;
2913 InputContext->EP[Dci-1].CErr = 0;
2914 InputContext->EP[Dci-1].EPType = ED_ISOCH_OUT;
2921 if (DeviceSpeed == EFI_USB_SPEED_FULL) {
2922 Interval = EpDesc->Interval;
2923 ASSERT (Interval >= 1 && Interval <= 16);
2924 InputContext->EP[Dci-1].Interval = Interval + 2;
2926 Interval = EpDesc->Interval;
2927 ASSERT (Interval >= 1 && Interval <= 16);
2928 InputContext->EP[Dci-1].Interval = Interval - 1;
2934 DEBUG ((DEBUG_INFO,
"XhcInitializeEndpointContext: Unsupport ISO EP found, Transfer ring is not allocated.\n"));
2937 case USB_ENDPOINT_INTERRUPT:
2938 if (Direction == EfiUsbDataIn) {
2939 InputContext->EP[Dci-1].CErr = 3;
2940 InputContext->EP[Dci-1].EPType = ED_INTERRUPT_IN;
2942 InputContext->EP[Dci-1].CErr = 3;
2943 InputContext->EP[Dci-1].EPType = ED_INTERRUPT_OUT;
2946 InputContext->EP[Dci-1].AverageTRBLength = 0x1000;
2947 InputContext->EP[Dci-1].MaxESITPayload = EpDesc->MaxPacketSize;
2951 if ((DeviceSpeed == EFI_USB_SPEED_FULL) || (DeviceSpeed == EFI_USB_SPEED_LOW)) {
2952 Interval = EpDesc->Interval;
2956 ASSERT (Interval != 0);
2957 InputContext->EP[Dci-1].Interval = (UINT32)
HighBitSet32 ((UINT32)Interval) + 3;
2959 Interval = EpDesc->Interval;
2960 ASSERT (Interval >= 1 && Interval <= 16);
2964 InputContext->EP[Dci-1].Interval = Interval - 1;
2965 InputContext->EP[Dci-1].AverageTRBLength = 0x1000;
2966 InputContext->EP[Dci-1].MaxESITPayload = 0x0002;
2967 InputContext->EP[Dci-1].MaxBurstSize = 0x0;
2968 InputContext->EP[Dci-1].CErr = 3;
2971 if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] ==
NULL) {
2973 Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *)EndpointTransferRing;
2977 "Endpoint[%x]: Created INT ring [%p~%p)\n",
2978 EpDesc->EndpointAddress,
2979 EndpointTransferRing->RingSeg0,
2980 (
UINTN)EndpointTransferRing->RingSeg0 + TR_RING_TRB_NUMBER * sizeof (
TRB_TEMPLATE)
2986 case USB_ENDPOINT_CONTROL:
2990 DEBUG ((DEBUG_INFO,
"XhcInitializeEndpointContext: Unsupport Control EP found, Transfer ring is not allocated.\n"));
2992 DEBUG ((DEBUG_INFO,
"XhcInitializeEndpointContext: Unknown EP found, Transfer ring is not allocated.\n"));
2999 ((
TRANSFER_RING *)(
UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingSeg0,
3005 InputContext->EP[Dci-1].PtrLo = XHC_LOW_32BIT (PhyAddr);
3006 InputContext->EP[Dci-1].PtrHi = XHC_HIGH_32BIT (PhyAddr);
3031 IN UINT8 DeviceSpeed,
3049 NumEp = IfDesc->NumEndpoints;
3055 for (EpIndex = 0; EpIndex < NumEp; EpIndex++) {
3056 while (EpDesc->DescriptorType != USB_DESC_TYPE_ENDPOINT) {
3065 EpAddr = (UINT8)(EpDesc->EndpointAddress & 0x0F);
3066 Direction = (UINT8)((EpDesc->EndpointAddress & 0x80) ? EfiUsbDataIn : EfiUsbDataOut);
3074 InputContext->InputControlContext.Dword2 |= (BIT0 << Dci);
3075 InputContext->EP[Dci-1].MaxPacketSize = EpDesc->MaxPacketSize;
3081 InputContext->EP[Dci-1].MaxBurstSize = 0x0;
3083 InputContext->EP[Dci-1].MaxBurstSize = 0x0;
3086 switch (EpDesc->Attributes & USB_ENDPOINT_TYPE_MASK) {
3087 case USB_ENDPOINT_BULK:
3088 if (Direction == EfiUsbDataIn) {
3089 InputContext->EP[Dci-1].CErr = 3;
3090 InputContext->EP[Dci-1].EPType = ED_BULK_IN;
3092 InputContext->EP[Dci-1].CErr = 3;
3093 InputContext->EP[Dci-1].EPType = ED_BULK_OUT;
3096 InputContext->EP[Dci-1].AverageTRBLength = 0x1000;
3097 if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] ==
NULL) {
3099 Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *)EndpointTransferRing;
3103 "Endpoint64[%x]: Created BULK ring [%p~%p)\n",
3104 EpDesc->EndpointAddress,
3105 EndpointTransferRing->RingSeg0,
3106 (
UINTN)EndpointTransferRing->RingSeg0 + TR_RING_TRB_NUMBER * sizeof (
TRB_TEMPLATE)
3111 case USB_ENDPOINT_ISO:
3112 if (Direction == EfiUsbDataIn) {
3113 InputContext->EP[Dci-1].CErr = 0;
3114 InputContext->EP[Dci-1].EPType = ED_ISOCH_IN;
3116 InputContext->EP[Dci-1].CErr = 0;
3117 InputContext->EP[Dci-1].EPType = ED_ISOCH_OUT;
3124 if (DeviceSpeed == EFI_USB_SPEED_FULL) {
3125 Interval = EpDesc->Interval;
3126 ASSERT (Interval >= 1 && Interval <= 16);
3127 InputContext->EP[Dci-1].Interval = Interval + 2;
3129 Interval = EpDesc->Interval;
3130 ASSERT (Interval >= 1 && Interval <= 16);
3131 InputContext->EP[Dci-1].Interval = Interval - 1;
3137 DEBUG ((DEBUG_INFO,
"XhcInitializeEndpointContext64: Unsupport ISO EP found, Transfer ring is not allocated.\n"));
3140 case USB_ENDPOINT_INTERRUPT:
3141 if (Direction == EfiUsbDataIn) {
3142 InputContext->EP[Dci-1].CErr = 3;
3143 InputContext->EP[Dci-1].EPType = ED_INTERRUPT_IN;
3145 InputContext->EP[Dci-1].CErr = 3;
3146 InputContext->EP[Dci-1].EPType = ED_INTERRUPT_OUT;
3149 InputContext->EP[Dci-1].AverageTRBLength = 0x1000;
3150 InputContext->EP[Dci-1].MaxESITPayload = EpDesc->MaxPacketSize;
3154 if ((DeviceSpeed == EFI_USB_SPEED_FULL) || (DeviceSpeed == EFI_USB_SPEED_LOW)) {
3155 Interval = EpDesc->Interval;
3159 ASSERT (Interval != 0);
3160 InputContext->EP[Dci-1].Interval = (UINT32)
HighBitSet32 ((UINT32)Interval) + 3;
3162 Interval = EpDesc->Interval;
3163 ASSERT (Interval >= 1 && Interval <= 16);
3167 InputContext->EP[Dci-1].Interval = Interval - 1;
3168 InputContext->EP[Dci-1].AverageTRBLength = 0x1000;
3169 InputContext->EP[Dci-1].MaxESITPayload = 0x0002;
3170 InputContext->EP[Dci-1].MaxBurstSize = 0x0;
3171 InputContext->EP[Dci-1].CErr = 3;
3174 if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] ==
NULL) {
3176 Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *)EndpointTransferRing;
3180 "Endpoint64[%x]: Created INT ring [%p~%p)\n",
3181 EpDesc->EndpointAddress,
3182 EndpointTransferRing->RingSeg0,
3183 (
UINTN)EndpointTransferRing->RingSeg0 + TR_RING_TRB_NUMBER * sizeof (
TRB_TEMPLATE)
3189 case USB_ENDPOINT_CONTROL:
3193 DEBUG ((DEBUG_INFO,
"XhcInitializeEndpointContext64: Unsupport Control EP found, Transfer ring is not allocated.\n"));
3195 DEBUG ((DEBUG_INFO,
"XhcInitializeEndpointContext64: Unknown EP found, Transfer ring is not allocated.\n"));
3202 ((
TRANSFER_RING *)(
UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingSeg0,
3208 InputContext->EP[Dci-1].PtrLo = XHC_LOW_32BIT (PhyAddr);
3209 InputContext->EP[Dci-1].PtrHi = XHC_HIGH_32BIT (PhyAddr);
3233 IN UINT8 DeviceSpeed,
3254 InputContext = Xhc->UsbDevContext[SlotId].InputContext;
3255 OutputContext = Xhc->UsbDevContext[SlotId].OutputContext;
3259 ASSERT (ConfigDesc !=
NULL);
3264 for (Index = 0; Index < ConfigDesc->NumInterfaces; Index++) {
3265 while ((IfDesc->DescriptorType != USB_DESC_TYPE_INTERFACE) || (IfDesc->AlternateSetting != 0)) {
3282 InputContext->InputControlContext.Dword2 |= BIT0;
3283 InputContext->Slot.ContextEntries = MaxDci;
3287 ZeroMem (&CmdTrbCfgEP,
sizeof (CmdTrbCfgEP));
3289 CmdTrbCfgEP.PtrLo = XHC_LOW_32BIT (PhyAddr);
3290 CmdTrbCfgEP.PtrHi = XHC_HIGH_32BIT (PhyAddr);
3291 CmdTrbCfgEP.CycleBit = 1;
3292 CmdTrbCfgEP.Type = TRB_TYPE_CON_ENDPOINT;
3293 CmdTrbCfgEP.SlotId = Xhc->UsbDevContext[SlotId].SlotId;
3294 DEBUG ((DEBUG_INFO,
"Configure Endpoint\n"));
3298 XHC_GENERIC_TIMEOUT,
3301 if (EFI_ERROR (Status) || (EvtTrb ==
NULL)) {
3302 DEBUG ((DEBUG_ERROR,
"XhcSetConfigCmd: Config Endpoint Failed, Status = %r\n", Status));
3304 Xhc->UsbDevContext[SlotId].ActiveConfiguration = ConfigDesc->ConfigurationValue;
3326 IN UINT8 DeviceSpeed,
3347 InputContext = Xhc->UsbDevContext[SlotId].InputContext;
3348 OutputContext = Xhc->UsbDevContext[SlotId].OutputContext;
3352 ASSERT (ConfigDesc !=
NULL);
3357 for (Index = 0; Index < ConfigDesc->NumInterfaces; Index++) {
3358 while ((IfDesc->DescriptorType != USB_DESC_TYPE_INTERFACE) || (IfDesc->AlternateSetting != 0)) {
3375 InputContext->InputControlContext.Dword2 |= BIT0;
3376 InputContext->Slot.ContextEntries = MaxDci;
3380 ZeroMem (&CmdTrbCfgEP,
sizeof (CmdTrbCfgEP));
3382 CmdTrbCfgEP.PtrLo = XHC_LOW_32BIT (PhyAddr);
3383 CmdTrbCfgEP.PtrHi = XHC_HIGH_32BIT (PhyAddr);
3384 CmdTrbCfgEP.CycleBit = 1;
3385 CmdTrbCfgEP.Type = TRB_TYPE_CON_ENDPOINT;
3386 CmdTrbCfgEP.SlotId = Xhc->UsbDevContext[SlotId].SlotId;
3387 DEBUG ((DEBUG_INFO,
"Configure Endpoint\n"));
3391 XHC_GENERIC_TIMEOUT,
3394 if (EFI_ERROR (Status) || (EvtTrb ==
NULL)) {
3395 DEBUG ((DEBUG_ERROR,
"XhcSetConfigCmd64: Config Endpoint Failed, Status = %r\n", Status));
3397 Xhc->UsbDevContext[SlotId].ActiveConfiguration = ConfigDesc->ConfigurationValue;
3421 IN URB *PendingUrb OPTIONAL
3428 DEBUG ((DEBUG_VERBOSE,
"XhcStopEndpoint: Slot = 0x%x, Dci = 0x%x\n", SlotId, Dci));
3443 ASSERT (Xhc->PendingUrb ==
NULL);
3444 Xhc->PendingUrb = PendingUrb;
3451 if (PendingUrb !=
NULL) {
3452 PendingUrb->Result = EFI_USB_NOERROR;
3458 ZeroMem (&CmdTrbStopED,
sizeof (CmdTrbStopED));
3459 CmdTrbStopED.CycleBit = 1;
3460 CmdTrbStopED.Type = TRB_TYPE_STOP_ENDPOINT;
3461 CmdTrbStopED.EDID = Dci;
3462 CmdTrbStopED.SlotId = SlotId;
3466 XHC_GENERIC_TIMEOUT,
3469 if (EFI_ERROR (Status) || (EvtTrb ==
NULL)) {
3470 DEBUG ((DEBUG_ERROR,
"XhcStopEndpoint: Stop Endpoint Failed, Status = %r\n", Status));
3473 Xhc->PendingUrb =
NULL;
3501 DEBUG ((DEBUG_INFO,
"XhcResetEndpoint: Slot = 0x%x, Dci = 0x%x\n", SlotId, Dci));
3508 ZeroMem (&CmdTrbResetED,
sizeof (CmdTrbResetED));
3509 CmdTrbResetED.CycleBit = 1;
3510 CmdTrbResetED.Type = TRB_TYPE_RESET_ENDPOINT;
3511 CmdTrbResetED.EDID = Dci;
3512 CmdTrbResetED.SlotId = SlotId;
3516 XHC_GENERIC_TIMEOUT,
3519 if (EFI_ERROR (Status) || (EvtTrb ==
NULL)) {
3520 DEBUG ((DEBUG_ERROR,
"XhcResetEndpoint: Reset Endpoint Failed, Status = %r\n", Status));
3553 DEBUG ((DEBUG_VERBOSE,
"XhcSetTrDequeuePointer: Slot = 0x%x, Dci = 0x%x, Urb = 0x%x\n", SlotId, Dci, Urb));
3560 ZeroMem (&CmdSetTRDeq,
sizeof (CmdSetTRDeq));
3562 CmdSetTRDeq.PtrLo = XHC_LOW_32BIT (PhyAddr) | Urb->Ring->RingPCS;
3563 CmdSetTRDeq.PtrHi = XHC_HIGH_32BIT (PhyAddr);
3564 CmdSetTRDeq.CycleBit = 1;
3565 CmdSetTRDeq.Type = TRB_TYPE_SET_TR_DEQUE;
3566 CmdSetTRDeq.Endpoint = Dci;
3567 CmdSetTRDeq.SlotId = SlotId;
3571 XHC_GENERIC_TIMEOUT,
3574 if (EFI_ERROR (Status) || (EvtTrb ==
NULL)) {
3575 DEBUG ((DEBUG_ERROR,
"XhcSetTrDequeuePointer: Set TR Dequeue Pointer Failed, Status = %r\n", Status));
3598 IN UINT8 DeviceSpeed,
3625 InputContext = Xhc->UsbDevContext[SlotId].InputContext;
3626 OutputContext = Xhc->UsbDevContext[SlotId].OutputContext;
3640 ASSERT (ConfigDesc !=
NULL);
3644 IfDescActive =
NULL;
3648 while ((
UINTN)IfDesc < ((
UINTN)ConfigDesc + ConfigDesc->TotalLength)) {
3649 if ((IfDesc->DescriptorType == USB_DESC_TYPE_INTERFACE) && (IfDesc->Length >=
sizeof (
USB_INTERFACE_DESCRIPTOR))) {
3650 if (IfDesc->InterfaceNumber == (UINT8)Request->Index) {
3651 if (IfDesc->AlternateSetting == Xhc->UsbDevContext[SlotId].ActiveAlternateSetting[IfDesc->InterfaceNumber]) {
3655 IfDescActive = IfDesc;
3656 }
else if (IfDesc->AlternateSetting == (UINT8)Request->Value) {
3682 if ((IfDescActive !=
NULL) && (IfDescSet !=
NULL)) {
3683 NumEp = IfDescActive->NumEndpoints;
3685 for (EpIndex = 0; EpIndex < NumEp; EpIndex++) {
3686 while (EpDesc->DescriptorType != USB_DESC_TYPE_ENDPOINT) {
3695 EpAddr = (UINT8)(EpDesc->EndpointAddress & 0x0F);
3696 Direction = (UINT8)((EpDesc->EndpointAddress & 0x80) ? EfiUsbDataIn : EfiUsbDataOut);
3709 if (EFI_ERROR (Status)) {
3717 if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1] !=
NULL) {
3718 RingSeg = ((
TRANSFER_RING *)(
UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1])->RingSeg0;
3719 if (RingSeg !=
NULL) {
3723 FreePool (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1]);
3724 Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1] =
NULL;
3730 InputContext->InputControlContext.Dword1 |= (BIT0 << Dci);
3755 InputContext->InputControlContext.Dword2 |= BIT0;
3756 InputContext->Slot.ContextEntries = MaxDci;
3761 ZeroMem (&CmdTrbCfgEP,
sizeof (CmdTrbCfgEP));
3763 CmdTrbCfgEP.PtrLo = XHC_LOW_32BIT (PhyAddr);
3764 CmdTrbCfgEP.PtrHi = XHC_HIGH_32BIT (PhyAddr);
3765 CmdTrbCfgEP.CycleBit = 1;
3766 CmdTrbCfgEP.Type = TRB_TYPE_CON_ENDPOINT;
3767 CmdTrbCfgEP.SlotId = Xhc->UsbDevContext[SlotId].SlotId;
3768 DEBUG ((DEBUG_INFO,
"SetInterface: Configure Endpoint\n"));
3772 XHC_GENERIC_TIMEOUT,
3775 if (EFI_ERROR (Status) || (EvtTrb ==
NULL)) {
3776 DEBUG ((DEBUG_ERROR,
"SetInterface: Config Endpoint Failed, Status = %r\n", Status));
3781 Xhc->UsbDevContext[SlotId].ActiveAlternateSetting[(UINT8)Request->Index] = (UINT8)Request->Value;
3805 IN UINT8 DeviceSpeed,
3832 InputContext = Xhc->UsbDevContext[SlotId].InputContext;
3833 OutputContext = Xhc->UsbDevContext[SlotId].OutputContext;
3847 ASSERT (ConfigDesc !=
NULL);
3851 IfDescActive =
NULL;
3855 while ((
UINTN)IfDesc < ((
UINTN)ConfigDesc + ConfigDesc->TotalLength)) {
3856 if ((IfDesc->DescriptorType == USB_DESC_TYPE_INTERFACE) && (IfDesc->Length >=
sizeof (
USB_INTERFACE_DESCRIPTOR))) {
3857 if (IfDesc->InterfaceNumber == (UINT8)Request->Index) {
3858 if (IfDesc->AlternateSetting == Xhc->UsbDevContext[SlotId].ActiveAlternateSetting[IfDesc->InterfaceNumber]) {
3862 IfDescActive = IfDesc;
3863 }
else if (IfDesc->AlternateSetting == (UINT8)Request->Value) {
3889 if ((IfDescActive !=
NULL) && (IfDescSet !=
NULL)) {
3890 NumEp = IfDescActive->NumEndpoints;
3892 for (EpIndex = 0; EpIndex < NumEp; EpIndex++) {
3893 while (EpDesc->DescriptorType != USB_DESC_TYPE_ENDPOINT) {
3902 EpAddr = (UINT8)(EpDesc->EndpointAddress & 0x0F);
3903 Direction = (UINT8)((EpDesc->EndpointAddress & 0x80) ? EfiUsbDataIn : EfiUsbDataOut);
3916 if (EFI_ERROR (Status)) {
3924 if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1] !=
NULL) {
3925 RingSeg = ((
TRANSFER_RING *)(
UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1])->RingSeg0;
3926 if (RingSeg !=
NULL) {
3930 FreePool (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1]);
3931 Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1] =
NULL;
3937 InputContext->InputControlContext.Dword1 |= (BIT0 << Dci);
3962 InputContext->InputControlContext.Dword2 |= BIT0;
3963 InputContext->Slot.ContextEntries = MaxDci;
3968 ZeroMem (&CmdTrbCfgEP,
sizeof (CmdTrbCfgEP));
3970 CmdTrbCfgEP.PtrLo = XHC_LOW_32BIT (PhyAddr);
3971 CmdTrbCfgEP.PtrHi = XHC_HIGH_32BIT (PhyAddr);
3972 CmdTrbCfgEP.CycleBit = 1;
3973 CmdTrbCfgEP.Type = TRB_TYPE_CON_ENDPOINT;
3974 CmdTrbCfgEP.SlotId = Xhc->UsbDevContext[SlotId].SlotId;
3975 DEBUG ((DEBUG_INFO,
"SetInterface64: Configure Endpoint\n"));
3979 XHC_GENERIC_TIMEOUT,
3982 if (EFI_ERROR (Status) || (EvtTrb ==
NULL)) {
3983 DEBUG ((DEBUG_ERROR,
"SetInterface64: Config Endpoint Failed, Status = %r\n", Status));
3988 Xhc->UsbDevContext[SlotId].ActiveAlternateSetting[(UINT8)Request->Index] = (UINT8)Request->Value;
4010 IN UINT32 MaxPacketSize
4020 ASSERT (Xhc->UsbDevContext[SlotId].SlotId != 0);
4027 InputContext = Xhc->UsbDevContext[SlotId].InputContext;
4028 OutputContext = Xhc->UsbDevContext[SlotId].OutputContext;
4033 InputContext->InputControlContext.Dword2 |= BIT1;
4034 InputContext->EP[0].MaxPacketSize = MaxPacketSize;
4035 InputContext->EP[0].EPState = 0;
4037 ZeroMem (&CmdTrbEvalu,
sizeof (CmdTrbEvalu));
4039 CmdTrbEvalu.PtrLo = XHC_LOW_32BIT (PhyAddr);
4040 CmdTrbEvalu.PtrHi = XHC_HIGH_32BIT (PhyAddr);
4041 CmdTrbEvalu.CycleBit = 1;
4042 CmdTrbEvalu.Type = TRB_TYPE_EVALU_CONTXT;
4043 CmdTrbEvalu.SlotId = Xhc->UsbDevContext[SlotId].SlotId;
4044 DEBUG ((DEBUG_INFO,
"Evaluate context\n"));
4048 XHC_GENERIC_TIMEOUT,
4051 if (EFI_ERROR (Status) || (EvtTrb ==
NULL)) {
4052 DEBUG ((DEBUG_ERROR,
"XhcEvaluateContext: Evaluate Context Failed, Status = %r\n", Status));
4073 IN UINT32 MaxPacketSize
4083 ASSERT (Xhc->UsbDevContext[SlotId].SlotId != 0);
4090 InputContext = Xhc->UsbDevContext[SlotId].InputContext;
4091 OutputContext = Xhc->UsbDevContext[SlotId].OutputContext;
4096 InputContext->InputControlContext.Dword2 |= BIT1;
4097 InputContext->EP[0].MaxPacketSize = MaxPacketSize;
4098 InputContext->EP[0].EPState = 0;
4100 ZeroMem (&CmdTrbEvalu,
sizeof (CmdTrbEvalu));
4102 CmdTrbEvalu.PtrLo = XHC_LOW_32BIT (PhyAddr);
4103 CmdTrbEvalu.PtrHi = XHC_HIGH_32BIT (PhyAddr);
4104 CmdTrbEvalu.CycleBit = 1;
4105 CmdTrbEvalu.Type = TRB_TYPE_EVALU_CONTXT;
4106 CmdTrbEvalu.SlotId = Xhc->UsbDevContext[SlotId].SlotId;
4107 DEBUG ((DEBUG_INFO,
"Evaluate context\n"));
4111 XHC_GENERIC_TIMEOUT,
4114 if (EFI_ERROR (Status) || (EvtTrb ==
NULL)) {
4115 DEBUG ((DEBUG_ERROR,
"XhcEvaluateContext64: Evaluate Context Failed, Status = %r\n", Status));
4149 ASSERT (Xhc->UsbDevContext[SlotId].SlotId != 0);
4151 InputContext = Xhc->UsbDevContext[SlotId].InputContext;
4152 OutputContext = Xhc->UsbDevContext[SlotId].OutputContext;
4159 InputContext->InputControlContext.Dword2 |= BIT0;
4165 InputContext->Slot.Hub = 1;
4166 InputContext->Slot.PortNum = PortNum;
4167 InputContext->Slot.TTT = TTT;
4168 InputContext->Slot.MTT = MTT;
4170 ZeroMem (&CmdTrbCfgEP,
sizeof (CmdTrbCfgEP));
4172 CmdTrbCfgEP.PtrLo = XHC_LOW_32BIT (PhyAddr);
4173 CmdTrbCfgEP.PtrHi = XHC_HIGH_32BIT (PhyAddr);
4174 CmdTrbCfgEP.CycleBit = 1;
4175 CmdTrbCfgEP.Type = TRB_TYPE_CON_ENDPOINT;
4176 CmdTrbCfgEP.SlotId = Xhc->UsbDevContext[SlotId].SlotId;
4177 DEBUG ((DEBUG_INFO,
"Configure Hub Slot Context\n"));
4181 XHC_GENERIC_TIMEOUT,
4184 if (EFI_ERROR (Status) || (EvtTrb ==
NULL)) {
4185 DEBUG ((DEBUG_ERROR,
"XhcConfigHubContext: Config Endpoint Failed, Status = %r\n", Status));
4219 ASSERT (Xhc->UsbDevContext[SlotId].SlotId != 0);
4220 InputContext = Xhc->UsbDevContext[SlotId].InputContext;
4221 OutputContext = Xhc->UsbDevContext[SlotId].OutputContext;
4228 InputContext->InputControlContext.Dword2 |= BIT0;
4234 InputContext->Slot.Hub = 1;
4235 InputContext->Slot.PortNum = PortNum;
4236 InputContext->Slot.TTT = TTT;
4237 InputContext->Slot.MTT = MTT;
4239 ZeroMem (&CmdTrbCfgEP,
sizeof (CmdTrbCfgEP));
4241 CmdTrbCfgEP.PtrLo = XHC_LOW_32BIT (PhyAddr);
4242 CmdTrbCfgEP.PtrHi = XHC_HIGH_32BIT (PhyAddr);
4243 CmdTrbCfgEP.CycleBit = 1;
4244 CmdTrbCfgEP.Type = TRB_TYPE_CON_ENDPOINT;
4245 CmdTrbCfgEP.SlotId = Xhc->UsbDevContext[SlotId].SlotId;
4246 DEBUG ((DEBUG_INFO,
"Configure Hub Slot Context\n"));
4250 XHC_GENERIC_TIMEOUT,
4253 if (EFI_ERROR (Status)) {
4254 DEBUG ((DEBUG_ERROR,
"XhcConfigHubContext64: Config Endpoint Failed, Status = %r\n", Status));
UINT64 EFIAPI GetPerformanceCounter(VOID)
LIST_ENTRY *EFIAPI InsertHeadList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
#define BASE_LIST_FOR_EACH_SAFE(Entry, NextEntry, ListHead)
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
INTN EFIAPI HighBitSet32(IN UINT32 Operand)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_STATUS UsbHcFreeMemPool(IN USBHC_MEM_POOL *Pool)
VOID UsbHcFreeMem(IN USBHC_MEM_POOL *Pool, IN VOID *Mem, IN UINTN Size)
VOID * UsbHcAllocateMem(IN USBHC_MEM_POOL *Pool, IN UINTN Size)
USBHC_MEM_POOL * UsbHcInitMemPool(IN EFI_PCI_IO_PROTOCOL *PciIo, IN BOOLEAN Check4G, IN UINT32 Which4G)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define ASSERT_EFI_ERROR(StatusParameter)
#define DEBUG(Expression)
EFI_PCI_IO_PROTOCOL_OPERATION
@ EfiPciIoOperationBusMasterWrite
@ EfiPciIoOperationBusMasterRead
#define USB_PORT_STAT_C_CONNECTION
#define EFI_USB_SPEED_SUPER
4.8 Gb/s, USB 3.0 XHCI HC.
#define USB_PORT_STAT_CONNECTION
EFI_STATUS(EFIAPI * EFI_ASYNC_USB_TRANSFER_CALLBACK)(IN VOID *Data, IN UINTN DataLength, IN VOID *Context, IN UINT32 Status)
UINT64 EFI_PHYSICAL_ADDRESS
#define EFI_SIZE_TO_PAGES(Size)
UINT64 XhcGetElapsedTicks(IN OUT UINT64 *PreviousTick)
UINT64 XhcConvertTimeToTicks(IN UINT64 Time)
EFI_PHYSICAL_ADDRESS UsbHcGetPciAddrForHostAddr(IN USBHC_MEM_POOL *Pool, IN VOID *Mem, IN UINTN Size, IN BOOLEAN Alignment)
EFI_STATUS UsbHcAllocateAlignedPages(IN EFI_PCI_IO_PROTOCOL *PciIo, IN UINTN Pages, IN UINTN Alignment, OUT VOID **HostAddress, OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, OUT VOID **Mapping)
EFI_PHYSICAL_ADDRESS UsbHcGetHostAddrForPciAddr(IN USBHC_MEM_POOL *Pool, IN VOID *Mem, IN UINTN Size, IN BOOLEAN Alignment)
VOID UsbHcFreeAlignedPages(IN EFI_PCI_IO_PROTOCOL *PciIo, IN VOID *HostAddress, IN UINTN Pages, VOID *Mapping)
EFI_STATUS EFIAPI XhcSetConfigCmd64(IN USB_XHCI_INSTANCE *Xhc, IN UINT8 SlotId, IN UINT8 DeviceSpeed, IN USB_CONFIG_DESCRIPTOR *ConfigDesc)
URB * XhciInsertAsyncIntTransfer(IN USB_XHCI_INSTANCE *Xhc, IN UINT8 BusAddr, IN UINT8 EpAddr, IN UINT8 DevSpeed, IN UINTN MaxPacket, IN UINTN DataLen, IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback, IN VOID *Context)
BOOLEAN IsTransferRingTrb(IN USB_XHCI_INSTANCE *Xhc, IN TRB_TEMPLATE *Trb, IN URB *Urb)
EFI_STATUS EFIAPI XhcDisableSlotCmd(IN USB_XHCI_INSTANCE *Xhc, IN UINT8 SlotId)
EFI_STATUS EFIAPI XhcInitializeDeviceSlot64(IN USB_XHCI_INSTANCE *Xhc, IN USB_DEV_ROUTE ParentRouteChart, IN UINT16 ParentPort, IN USB_DEV_ROUTE RouteChart, IN UINT8 DeviceSpeed)
VOID XhciDelAllAsyncIntTransfers(IN USB_XHCI_INSTANCE *Xhc)
EFI_STATUS XhcFlushAsyncIntMap(IN USB_XHCI_INSTANCE *Xhc, IN URB *Urb)
VOID XhcUpdateAsyncRequest(IN USB_XHCI_INSTANCE *Xhc, IN URB *Urb)
UINT8 EFIAPI XhcInitializeEndpointContext(IN USB_XHCI_INSTANCE *Xhc, IN UINT8 SlotId, IN UINT8 DeviceSpeed, IN INPUT_CONTEXT *InputContext, IN USB_INTERFACE_DESCRIPTOR *IfDesc)
UINT8 EFIAPI XhcInitializeEndpointContext64(IN USB_XHCI_INSTANCE *Xhc, IN UINT8 SlotId, IN UINT8 DeviceSpeed, IN INPUT_CONTEXT_64 *InputContext, IN USB_INTERFACE_DESCRIPTOR *IfDesc)
VOID CreateEventRing(IN USB_XHCI_INSTANCE *Xhc, OUT EVENT_RING *EventRing)
VOID XhcFreeUrb(IN USB_XHCI_INSTANCE *Xhc, IN URB *Urb)
EFI_STATUS EFIAPI XhcSetTrDequeuePointer(IN USB_XHCI_INSTANCE *Xhc, IN UINT8 SlotId, IN UINT8 Dci, IN URB *Urb)
EFI_STATUS EFIAPI XhcResetEndpoint(IN USB_XHCI_INSTANCE *Xhc, IN UINT8 SlotId, IN UINT8 Dci)
BOOLEAN IsAsyncIntTrb(IN USB_XHCI_INSTANCE *Xhc, IN TRB_TEMPLATE *Trb, OUT URB **Urb)
EFI_STATUS XhciDelAsyncIntTransfer(IN USB_XHCI_INSTANCE *Xhc, IN UINT8 BusAddr, IN UINT8 EpNum)
EFI_STATUS XhcConfigHubContext64(IN USB_XHCI_INSTANCE *Xhc, IN UINT8 SlotId, IN UINT8 PortNum, IN UINT8 TTT, IN UINT8 MTT)
BOOLEAN XhcCheckUrbResult(IN USB_XHCI_INSTANCE *Xhc, IN URB *Urb)
VOID XhcFreeSched(IN USB_XHCI_INSTANCE *Xhc)
EFI_STATUS EFIAPI XhcSetInterface64(IN USB_XHCI_INSTANCE *Xhc, IN UINT8 SlotId, IN UINT8 DeviceSpeed, IN USB_CONFIG_DESCRIPTOR *ConfigDesc, IN EFI_USB_DEVICE_REQUEST *Request)
EFI_STATUS EFIAPI XhcCheckNewEvent(IN USB_XHCI_INSTANCE *Xhc, IN EVENT_RING *EvtRing, OUT TRB_TEMPLATE **NewEvtTrb)
EFI_STATUS EFIAPI XhcRecoverHaltedEndpoint(IN USB_XHCI_INSTANCE *Xhc, IN URB *Urb)
VOID EFIAPI XhcMonitorAsyncRequests(IN EFI_EVENT Event, IN VOID *Context)
VOID CreateTransferRing(IN USB_XHCI_INSTANCE *Xhc, IN UINTN TrbNum, OUT TRANSFER_RING *TransferRing)
EFI_STATUS EFIAPI XhcCmdTransfer(IN USB_XHCI_INSTANCE *Xhc, IN TRB_TEMPLATE *CmdTrb, IN UINTN Timeout, OUT TRB_TEMPLATE **EvtTrb)
EFI_STATUS EFIAPI XhcFreeEventRing(IN USB_XHCI_INSTANCE *Xhc, IN EVENT_RING *EventRing)
URB * XhcCreateCmdTrb(IN USB_XHCI_INSTANCE *Xhc, IN TRB_TEMPLATE *CmdTrb)
EFI_STATUS XhcCreateTransferTrb(IN USB_XHCI_INSTANCE *Xhc, IN URB *Urb)
EFI_STATUS EFIAPI XhcDequeueTrbFromEndpoint(IN USB_XHCI_INSTANCE *Xhc, IN URB *Urb)
UINT8 XhcEndpointToDci(IN UINT8 EpAddr, IN UINT8 Direction)
EFI_STATUS EFIAPI XhcEvaluateContext64(IN USB_XHCI_INSTANCE *Xhc, IN UINT8 SlotId, IN UINT32 MaxPacketSize)
EFI_STATUS EFIAPI XhcSyncTrsRing(IN USB_XHCI_INSTANCE *Xhc, IN TRANSFER_RING *TrsRing)
URB * XhcCreateUrb(IN USB_XHCI_INSTANCE *Xhc, IN UINT8 BusAddr, IN UINT8 EpAddr, IN UINT8 DevSpeed, IN UINTN MaxPacket, IN UINTN Type, IN EFI_USB_DEVICE_REQUEST *Request, IN VOID *Data, IN UINTN DataLen, IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback, IN VOID *Context)
VOID XhcInitSched(IN USB_XHCI_INSTANCE *Xhc)
EFI_STATUS RingIntTransferDoorBell(IN USB_XHCI_INSTANCE *Xhc, IN URB *Urb)
EFI_STATUS EFIAPI XhcRingDoorBell(IN USB_XHCI_INSTANCE *Xhc, IN UINT8 SlotId, IN UINT8 Dci)
EFI_STATUS XhcConfigHubContext(IN USB_XHCI_INSTANCE *Xhc, IN UINT8 SlotId, IN UINT8 PortNum, IN UINT8 TTT, IN UINT8 MTT)
EFI_STATUS EFIAPI XhcEvaluateContext(IN USB_XHCI_INSTANCE *Xhc, IN UINT8 SlotId, IN UINT32 MaxPacketSize)
EFI_STATUS EFIAPI XhcStopEndpoint(IN USB_XHCI_INSTANCE *Xhc, IN UINT8 SlotId, IN UINT8 Dci, IN URB *PendingUrb OPTIONAL)
EFI_STATUS XhcExecTransfer(IN USB_XHCI_INSTANCE *Xhc, IN BOOLEAN CmdTransfer, IN URB *Urb, IN UINTN Timeout)
EFI_STATUS EFIAPI XhcSyncEventRing(IN USB_XHCI_INSTANCE *Xhc, IN EVENT_RING *EvtRing)
VOID XhcCmdRingCmdAbort(IN USB_XHCI_INSTANCE *Xhc, IN UINT8 SlotId)
EFI_STATUS EFIAPI XhcSetConfigCmd(IN USB_XHCI_INSTANCE *Xhc, IN UINT8 SlotId, IN UINT8 DeviceSpeed, IN USB_CONFIG_DESCRIPTOR *ConfigDesc)
EFI_STATUS EFIAPI XhcInitializeDeviceSlot(IN USB_XHCI_INSTANCE *Xhc, IN USB_DEV_ROUTE ParentRouteChart, IN UINT16 ParentPort, IN USB_DEV_ROUTE RouteChart, IN UINT8 DeviceSpeed)
UINT8 EFIAPI XhcRouteStringToSlotId(IN USB_XHCI_INSTANCE *Xhc, IN USB_DEV_ROUTE RouteString)
EFI_STATUS EFIAPI XhcDisableSlotCmd64(IN USB_XHCI_INSTANCE *Xhc, IN UINT8 SlotId)
UINT8 EFIAPI XhcBusDevAddrToSlotId(IN USB_XHCI_INSTANCE *Xhc, IN UINT8 BusDevAddr)
EFI_STATUS EFIAPI XhcPollPortStatusChange(IN USB_XHCI_INSTANCE *Xhc, IN USB_DEV_ROUTE ParentRouteChart, IN UINT8 Port, IN EFI_USB_PORT_STATUS *PortState)
EFI_STATUS EFIAPI XhcSetInterface(IN USB_XHCI_INSTANCE *Xhc, IN UINT8 SlotId, IN UINT8 DeviceSpeed, IN USB_CONFIG_DESCRIPTOR *ConfigDesc, IN EFI_USB_DEVICE_REQUEST *Request)
VOID XhcSetRuntimeRegBit(IN USB_XHCI_INSTANCE *Xhc, IN UINT32 Offset, IN UINT32 Bit)
BOOLEAN XhcIsSysError(IN USB_XHCI_INSTANCE *Xhc)
UINT32 XhcReadRuntimeReg(IN USB_XHCI_INSTANCE *Xhc, IN UINT32 Offset)
VOID XhcClearRuntimeRegBit(IN USB_XHCI_INSTANCE *Xhc, IN UINT32 Offset, IN UINT32 Bit)
VOID XhcWriteRuntimeReg(IN USB_XHCI_INSTANCE *Xhc, IN UINT32 Offset, IN UINT32 Data)
VOID XhcClearOpRegBit(IN USB_XHCI_INSTANCE *Xhc, IN UINT32 Offset, IN UINT32 Bit)
VOID XhcWriteOpReg(IN USB_XHCI_INSTANCE *Xhc, IN UINT32 Offset, IN UINT32 Data)
VOID XhcSetOpRegBit(IN USB_XHCI_INSTANCE *Xhc, IN UINT32 Offset, IN UINT32 Bit)
VOID XhcWriteDoorBellReg(IN USB_XHCI_INSTANCE *Xhc, IN UINT32 Offset, IN UINT32 Data)
BOOLEAN XhcIsHalt(IN USB_XHCI_INSTANCE *Xhc)