[USBEHCI_NEW]

- Change VendorId and DeviceId to the same size as PciConfig members, PUSHORT.
- Add support function GetBusInterface.
- Implement GetDeviceDetails and ResetPort.

svn path=/branches/usb-bringup/; revision=51367
This commit is contained in:
Michael Martin 2011-04-16 06:59:45 +00:00
parent acbd41ebf5
commit b8c05840fb
4 changed files with 152 additions and 27 deletions

View file

@ -51,7 +51,7 @@ public:
NTSTATUS PnpStart(PCM_RESOURCE_LIST RawResources, PCM_RESOURCE_LIST TranslatedResources);
NTSTATUS PnpStop(void);
NTSTATUS HandlePower(PIRP Irp);
NTSTATUS GetDeviceDetails(PULONG VendorId, PULONG DeviceId, PULONG NumberOfPorts, PULONG Speed);
NTSTATUS GetDeviceDetails(PUSHORT VendorId, PUSHORT DeviceId, PULONG NumberOfPorts, PULONG Speed);
NTSTATUS GetDmaMemoryManager(OUT struct IDMAMemoryManager **OutMemoryManager);
NTSTATUS GetUSBQueue(OUT struct IUSBQueue **OutUsbQueue);
NTSTATUS StartController();
@ -85,6 +85,8 @@ protected:
ULONG m_MapRegisters;
PQUEUE_HEAD m_AsyncListQueueHead;
EHCI_CAPS m_Capabilities;
USHORT m_VendorID;
USHORT m_DeviceID;
VOID SetCommandRegister(PEHCI_USBCMD_CONTENT UsbCmd);
VOID GetCommandRegister(PEHCI_USBCMD_CONTENT UsbCmd);
@ -118,6 +120,10 @@ CUSBHardwareDevice::Initialize(
PDEVICE_OBJECT PhysicalDeviceObject,
PDEVICE_OBJECT LowerDeviceObject)
{
BUS_INTERFACE_STANDARD BusInterface;
PCI_COMMON_CONFIG PciConfig;
NTSTATUS Status;
ULONG BytesRead;
DPRINT1("CUSBHardwareDevice::Initialize\n");
@ -134,6 +140,36 @@ CUSBHardwareDevice::Initialize(
//
KeInitializeSpinLock(&m_Lock);
m_VendorID = 0;
m_DeviceID = 0;
Status = GetBusInterface(PhysicalDeviceObject, &BusInterface);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to get BusInteface!\n");
return Status;
}
BytesRead = (*BusInterface.GetBusData)(BusInterface.Context,
PCI_WHICHSPACE_CONFIG,
&PciConfig,
0,
PCI_COMMON_HDR_LENGTH);
if (BytesRead != PCI_COMMON_HDR_LENGTH)
{
DPRINT1("Failed to get pci config information!\n");
return STATUS_SUCCESS;
}
if (!(PciConfig.Command & PCI_ENABLE_BUS_MASTER))
{
DPRINT1("PCI Configuration shows this as a non Bus Mastering device!\n");
}
m_VendorID = PciConfig.VendorID;
m_DeviceID = PciConfig.DeviceID;
return STATUS_SUCCESS;
}
@ -314,16 +350,19 @@ CUSBHardwareDevice::HandlePower(
NTSTATUS
CUSBHardwareDevice::GetDeviceDetails(
OUT OPTIONAL PULONG VendorId,
OUT OPTIONAL PULONG DeviceId,
OUT OPTIONAL PUSHORT VendorId,
OUT OPTIONAL PUSHORT DeviceId,
OUT OPTIONAL PULONG NumberOfPorts,
OUT OPTIONAL PULONG Speed)
{
UNIMPLEMENTED
return STATUS_NOT_IMPLEMENTED;
*VendorId = m_VendorID;
*DeviceId = m_DeviceID;
*NumberOfPorts = m_Capabilities.HCSParams.PortCount;
//FIXME: What to returned here?
*Speed = 0;
return STATUS_SUCCESS;
}
NTSTATUS
CUSBHardwareDevice::GetDmaMemoryManager(
OUT struct IDMAMemoryManager **OutMemoryManager)
@ -332,7 +371,6 @@ CUSBHardwareDevice::GetDmaMemoryManager(
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
CUSBHardwareDevice::GetUSBQueue(
OUT struct IUSBQueue **OutUsbQueue)
@ -485,8 +523,44 @@ NTSTATUS
CUSBHardwareDevice::ResetPort(
IN ULONG PortIndex)
{
UNIMPLEMENTED
return STATUS_NOT_IMPLEMENTED;
ULONG PortStatus;
PortStatus = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortIndex));
if (PortStatus & EHCI_PRT_SLOWSPEEDLINE)
{
DPRINT1("Non HighSpeed device. Releasing Ownership\n");
EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * PortIndex), EHCI_PRT_RELEASEOWNERSHIP);
return STATUS_DEVICE_NOT_CONNECTED;
}
//
// Reset and clean enable
//
PortStatus |= EHCI_PRT_RESET;
PortStatus &= ~EHCI_PRT_ENABLED;
EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * PortIndex), PortStatus);
KeStallExecutionProcessor(100);
//
// Clear reset
//
PortStatus = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortIndex));
PortStatus &= ~EHCI_PRT_RESET;
EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * PortIndex), PortStatus);
KeStallExecutionProcessor(100);
//
// Check that the port reset
//
PortStatus = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortIndex));
if (PortStatus & EHCI_PRT_RESET)
{
DPRINT1("Port did not reset\n");
return STATUS_RETRY;
}
return STATUS_SUCCESS;
}
KIRQL

View file

@ -157,8 +157,8 @@ DECLARE_INTERFACE_(IUSBHardwareDevice, IUnknown)
//
// Description: returns the device details such as vendor id, device id, number of ports and speed
virtual NTSTATUS GetDeviceDetails(OUT OPTIONAL PULONG VendorId,
OUT OPTIONAL PULONG DeviceId,
virtual NTSTATUS GetDeviceDetails(OUT OPTIONAL PUSHORT VendorId,
OUT OPTIONAL PUSHORT DeviceId,
OUT OPTIONAL PULONG NumberOfPorts,
OUT OPTIONAL PULONG Speed) = 0;

View file

@ -80,3 +80,52 @@ SyncForwardIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
return Status;
}
NTSTATUS NTAPI
GetBusInterface(PDEVICE_OBJECT DeviceObject, PBUS_INTERFACE_STANDARD busInterface)
{
KEVENT Event;
NTSTATUS Status;
PIRP Irp;
IO_STATUS_BLOCK IoStatus;
PIO_STACK_LOCATION Stack;
if ((!DeviceObject) || (!busInterface))
return STATUS_UNSUCCESSFUL;
KeInitializeEvent(&Event, NotificationEvent, FALSE);
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
DeviceObject,
NULL,
0,
NULL,
&Event,
&IoStatus);
if (Irp == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
Stack=IoGetNextIrpStackLocation(Irp);
Stack->MajorFunction = IRP_MJ_PNP;
Stack->MinorFunction = IRP_MN_QUERY_INTERFACE;
Stack->Parameters.QueryInterface.Size = sizeof(BUS_INTERFACE_STANDARD);
Stack->Parameters.QueryInterface.InterfaceType = (LPGUID)&GUID_BUS_INTERFACE_STANDARD;
Stack->Parameters.QueryInterface.Version = 1;
Stack->Parameters.QueryInterface.Interface = (PINTERFACE)busInterface;
Stack->Parameters.QueryInterface.InterfaceSpecificData = NULL;
Irp->IoStatus.Status=STATUS_NOT_SUPPORTED ;
Status=IoCallDriver(DeviceObject, Irp);
if (Status == STATUS_PENDING)
{
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
Status=IoStatus.Status;
}
return Status;
}

View file

@ -55,6 +55,8 @@ NTSTATUS CreateUSBHardware(PUSBHARDWAREDEVICE *OutHardware);
//
NTSTATUS NTAPI SyncForwardIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS NTAPI GetBusInterface(PDEVICE_OBJECT DeviceObject, PBUS_INTERFACE_STANDARD busInterface);
//
// root_hub_controller.cpp
//