MdeModulePkg/UsbBus&XhciDxe: Solve a bug that 2 or more tiers SS hubs with SS devices may have no response.

1.Port reset process may not be proper for some vendor's SS hubs. If the corresponding port shows the reset has been done by C_RESET bit we have to skip the whole reset process for attached devices.
2.Clean C_BH_RESET bit immediately to avoid usb timer entering too many times when 5 tiers hubs are connected.
3.Stop checking URB if there is an error happened.
4.Better error handling for fast hot-plug.

Signed-off-by: Feng Tian <feng.tian@intel.com>
Reviewed-by: Elvin Li <elvin.li@intel.com>


git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14889 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Feng Tian
2013-11-22 07:46:00 +00:00
committed by erictian
parent a6a2a95632
commit c3f44a7708
4 changed files with 119 additions and 53 deletions

View File

@ -1105,25 +1105,25 @@ XhcCheckUrbResult (
CheckedUrb->Result |= EFI_USB_ERR_STALL;
CheckedUrb->Finished = TRUE;
DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: STALL_ERROR! Completecode = %x\n",EvtTrb->Completecode));
break;
goto EXIT;
case TRB_COMPLETION_BABBLE_ERROR:
CheckedUrb->Result |= EFI_USB_ERR_BABBLE;
CheckedUrb->Finished = TRUE;
DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: BABBLE_ERROR! Completecode = %x\n",EvtTrb->Completecode));
break;
goto EXIT;
case TRB_COMPLETION_DATA_BUFFER_ERROR:
CheckedUrb->Result |= EFI_USB_ERR_BUFFER;
CheckedUrb->Finished = TRUE;
DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: ERR_BUFFER! Completecode = %x\n",EvtTrb->Completecode));
break;
goto EXIT;
case TRB_COMPLETION_USB_TRANSACTION_ERROR:
CheckedUrb->Result |= EFI_USB_ERR_TIMEOUT;
CheckedUrb->Finished = TRUE;
DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: TRANSACTION_ERROR! Completecode = %x\n",EvtTrb->Completecode));
break;
goto EXIT;
case TRB_COMPLETION_SHORT_PACKET:
case TRB_COMPLETION_SUCCESS:
@ -1144,7 +1144,7 @@ XhcCheckUrbResult (
DEBUG ((EFI_D_ERROR, "Transfer Default Error Occur! Completecode = 0x%x!\n",EvtTrb->Completecode));
CheckedUrb->Result |= EFI_USB_ERR_TIMEOUT;
CheckedUrb->Finished = TRUE;
break;
goto EXIT;
}
//
@ -1535,6 +1535,10 @@ XhcPollPortStatusChange (
Status = EFI_SUCCESS;
if ((PortState->PortChangeStatus & (USB_PORT_STAT_C_CONNECTION | USB_PORT_STAT_C_ENABLE | USB_PORT_STAT_C_OVERCURRENT | USB_PORT_STAT_C_RESET)) == 0) {
return EFI_SUCCESS;
}
if (ParentRouteChart.Dword == 0) {
RouteChart.Route.RouteString = 0;
RouteChart.Route.RootPortNum = Port + 1;
@ -1549,6 +1553,15 @@ XhcPollPortStatusChange (
RouteChart.Route.TierNum = ParentRouteChart.Route.TierNum + 1;
}
SlotId = XhcRouteStringToSlotId (Xhc, RouteChart);
if (SlotId != 0) {
if (Xhc->HcCParams.Data.Csz == 0) {
Status = XhcDisableSlotCmd (Xhc, SlotId);
} else {
Status = XhcDisableSlotCmd64 (Xhc, SlotId);
}
}
if (((PortState->PortStatus & USB_PORT_STAT_ENABLE) != 0) &&
((PortState->PortStatus & USB_PORT_STAT_CONNECTION) != 0)) {
//
@ -1566,26 +1579,15 @@ XhcPollPortStatusChange (
// Execute Enable_Slot cmd for attached device, initialize device context and assign device address.
//
SlotId = XhcRouteStringToSlotId (Xhc, RouteChart);
if (SlotId == 0) {
if ((SlotId == 0) && ((PortState->PortChangeStatus & USB_PORT_STAT_C_RESET) != 0)) {
if (Xhc->HcCParams.Data.Csz == 0) {
Status = XhcInitializeDeviceSlot (Xhc, ParentRouteChart, Port, RouteChart, Speed);
} else {
Status = XhcInitializeDeviceSlot64 (Xhc, ParentRouteChart, Port, RouteChart, Speed);
}
}
} else if ((PortState->PortStatus & USB_PORT_STAT_CONNECTION) == 0) {
//
// Device is detached. Disable the allocated device slot and release resource.
//
SlotId = XhcRouteStringToSlotId (Xhc, RouteChart);
if (SlotId != 0) {
if (Xhc->HcCParams.Data.Csz == 0) {
Status = XhcDisableSlotCmd (Xhc, SlotId);
} else {
Status = XhcDisableSlotCmd64 (Xhc, SlotId);
}
}
}
}
return Status;
}