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

View file

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