[USBEHCI_NEW]

- When clearing feature port reset, remove the flag from Change and if the port is hardware enabled set the enable flag in Status. 
- When checking port status, if Change has any flags set an SCE request most be completed. Verified while writing usbhub driver in xp.
- Probably fixes a case where an endless loop of completing SCE requests.

svn path=/branches/usb-bringup/; revision=51642
This commit is contained in:
Michael Martin 2011-05-08 12:42:15 +00:00
parent 3063e3bf5e
commit 741b7ea0aa
2 changed files with 30 additions and 24 deletions

View file

@ -713,7 +713,7 @@ CUSBHardwareDevice::GetPortStatus(
if (PortId > m_Capabilities.HCSParams.PortCount)
return STATUS_UNSUCCESSFUL;
//
// Get the value of the Port Status and Control Register
//
@ -799,12 +799,18 @@ CUSBHardwareDevice::ClearPortStatus(
Value &= ~EHCI_PRT_RESET;
EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId), Value);
KeStallExecutionProcessor(100);
}
//
// update port status
//
m_PortStatus[PortId].PortChange &= ~USB_PORT_STATUS_RESET;
Value = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId));
//
// update port status
//
m_PortStatus[PortId].PortChange &= ~USB_PORT_STATUS_RESET;
if (Value & EHCI_PRT_ENABLED)
m_PortStatus[PortId].PortStatus |= USB_PORT_STATUS_ENABLE;
else
{
DPRINT1("Port is not enabled.\n");
}
}
@ -843,7 +849,7 @@ CUSBHardwareDevice::SetPortFeature(
//
DPRINT1("PORT_ENABLE not supported for EHCI\n");
}
if (Feature == PORT_RESET)
{
if (Value & EHCI_PRT_SLOWSPEEDLINE)
@ -870,7 +876,7 @@ CUSBHardwareDevice::SetPortFeature(
m_SCECallBack(m_SCEContext);
}
}
if (Feature == PORT_POWER)
DPRINT1("PORT_POWER Not implemented\n");

View file

@ -67,7 +67,7 @@ public:
NTSTATUS HandleClassOther(IN OUT PIRP Irp, PURB Urb);
NTSTATUS HandleClassInterface(IN OUT PIRP Irp, PURB Urb);
NTSTATUS HandleBulkOrInterruptTransfer(IN OUT PIRP Irp, PURB Urb);
friend VOID StatusChangeEndpointCallBack(PVOID Context);
// constructor / destructor
@ -305,31 +305,30 @@ CHubController::QueryStatusChageEndpoint(
DPRINT1("SCE Request %p TransferBufferLength %lu Flags %x MDL %p\n", Urb->UrbBulkOrInterruptTransfer.TransferBuffer, Urb->UrbBulkOrInterruptTransfer.TransferBufferLength, Urb->UrbBulkOrInterruptTransfer.TransferFlags, Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL);
TransferBuffer = (PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer;
//
// Loop the ports
//
for (PortId = 0; PortId < PortCount; PortId++)
{
m_Hardware->GetPortStatus(PortId, &PortStatus, &PortChange);
DPRINT1("Port %d: Status %x, Change %x\n", PortId, PortStatus, PortChange);
//
// Loop the ports
// If theres a flag in PortChange return TRUE so the SCE Irp will be completed
//
if ((PortStatus & USB_PORT_STATUS_CONNECT) && (PortChange & USB_PORT_STATUS_CONNECT))
if (PortChange != 0)
{
DPRINT1("Device is connected on port %d\n", PortId);
DPRINT1("Change state on port %d\n", PortId);
// Set the value for the port number
*TransferBuffer = 1 << ((PortId + 1) & 7);
Changed = TRUE;
}
}
//
// If there were changes then return TRUE
//
if (Changed != 0)
return TRUE;
return FALSE;
return Changed;
}
//-----------------------------------------------------------------------------------------
@ -777,6 +776,7 @@ CHubController::HandleBulkOrInterruptTransfer(
ASSERT(m_PendingSCEIrp == NULL);
if (QueryStatusChageEndpoint(Irp))
{
StatusChangeEndpointCallBack(this);
return STATUS_SUCCESS;
}
@ -2094,7 +2094,7 @@ USBHI_InitializeUsbDevice(
if (NT_SUCCESS(Status))
break;
}while(Index++ < 3 );
}while(Index++ < 3 );
//
// check for failure
@ -2705,11 +2705,6 @@ USBHI_SetDeviceHandleData(
//
DPRINT1("USBHI_SetDeviceHandleData %p\n", UsbDevicePdo);
//
// fixup device stack voodoo part #1
//
UsbDevicePdo->StackSize++;
//
// sanity check
//
@ -3152,6 +3147,11 @@ CHubController::CreatePDO(
DPRINT1("CHubController::CreatePDO: DeviceName %wZ\n", &DeviceName);
//
// fixup device stack voodoo part #1
//
(*OutDeviceObject)->StackSize++;
/* done */
return Status;
}