reactos/drivers/usb/usbhub_new/pdo.c
Michael Martin 3063e3bf5e [USBHUB_NEW]
- Implement constructing CompatibleIds string using device descriptor. However, if the Class of the device descriptor is 0, then Class, SubClass and Prot which make up this string must come from the Interface.
- Change Ids and Descriptions to Unicode Strings. 
- Move the creating of Id strings to one place, CreateDeviceIds, and called it at device creation.

svn path=/branches/usb-bringup/; revision=51641
2011-05-08 12:24:26 +00:00

336 lines
10 KiB
C

/*
* PROJECT: ReactOS Universal Serial Bus Hub Driver
* LICENSE: GPL - See COPYING in the top level directory
* FILE: drivers/usb/usbhub/fdo.c
* PURPOSE: Handle PDO
* PROGRAMMERS:
* Hervé Poussineau (hpoussin@reactos.org)
* Michael Martin (michael.martin@reactos.org)
* Johannes Anderwald (johannes.anderwald@reactos.org)
*/
#define NDEBUG
#include "usbhub.h"
#define IO_METHOD_FROM_CTL_CODE(ctlCode) (ctlCode&0x00000003)
NTSTATUS
USBHUB_PdoHandleInternalDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PIO_STACK_LOCATION Stack;
ULONG_PTR Information = 0;
NTSTATUS Status;
DPRINT1("UsbhubInternalDeviceControlPdo(%x) called\n", DeviceObject);
Stack = IoGetCurrentIrpStackLocation(Irp);
Status = Irp->IoStatus.Status;
switch (Stack->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO:
{
PHUB_DEVICE_EXTENSION DeviceExtension;
DPRINT1("IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO\n");
if (Irp->AssociatedIrp.SystemBuffer == NULL
|| Stack->Parameters.DeviceIoControl.OutputBufferLength != sizeof(PVOID))
{
Status = STATUS_INVALID_PARAMETER;
}
else
{
PVOID* pHubPointer;
DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
pHubPointer = (PVOID*)Irp->AssociatedIrp.SystemBuffer;
// FIXME
*pHubPointer = NULL;
Information = sizeof(PVOID);
Status = STATUS_SUCCESS;
}
break;
}
default:
{
DPRINT1("Unknown IOCTL code 0x%lx\n", Stack->Parameters.DeviceIoControl.IoControlCode);
Information = Irp->IoStatus.Information;
Status = Irp->IoStatus.Status;
}
}
Irp->IoStatus.Information = Information;
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
NTSTATUS
USBHUB_PdoStartDevice(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension;
//NTSTATUS Status;
DPRINT1("USBHUB_PdoStartDevice %x\n", DeviceObject);
ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
//
// This should be a PDO
//
ASSERT(ChildDeviceExtension->Common.IsFDO == FALSE);
//
// FIXME: Fow now assume success
//
UNIMPLEMENTED
return STATUS_SUCCESS;
}
NTSTATUS
USBHUB_PdoQueryId(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
OUT ULONG_PTR* Information)
{
PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension;
ULONG IdType;
PUNICODE_STRING SourceString = NULL;
PWCHAR ReturnString = NULL;
NTSTATUS Status = STATUS_SUCCESS;
IdType = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryId.IdType;
ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
switch (IdType)
{
case BusQueryDeviceID:
{
DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n");
SourceString = &ChildDeviceExtension->usDeviceId;
break;
}
case BusQueryHardwareIDs:
{
DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryHardwareIDs\n");
SourceString = &ChildDeviceExtension->usHardwareIds;
break;
}
case BusQueryCompatibleIDs:
{
DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryCompatibleIDs\n");
SourceString = &ChildDeviceExtension->usCompatibleIds;
break;
}
case BusQueryInstanceID:
{
DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryInstanceID\n");
SourceString = &ChildDeviceExtension->usInstanceId;
break;
}
default:
DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n", IdType);
return STATUS_NOT_SUPPORTED;
}
if (SourceString)
{
ReturnString = ExAllocatePool(PagedPool, SourceString->Length);
RtlCopyMemory(ReturnString, SourceString->Buffer, SourceString->Length);
DPRINT1("%S\n", ReturnString);
}
*Information = (ULONG_PTR)ReturnString;
return Status;
}
NTSTATUS
USBHUB_PdoQueryDeviceText(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
OUT ULONG_PTR* Information)
{
PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension;
DEVICE_TEXT_TYPE DeviceTextType;
PUNICODE_STRING SourceString = NULL;
PWCHAR ReturnString = NULL;
NTSTATUS Status = STATUS_SUCCESS;
LCID LocaleId;
DeviceTextType = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryDeviceText.DeviceTextType;
LocaleId = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryDeviceText.LocaleId;
ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
//
// FIXME: LocaleId
//
switch (DeviceTextType)
{
case DeviceTextDescription:
case DeviceTextLocationInformation:
{
DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextDescription\n");
SourceString = &ChildDeviceExtension->usTextDescription;
break;
}
default:
{
DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / unknown device text type 0x%lx\n", DeviceTextType);
Status = STATUS_NOT_SUPPORTED;
break;
}
}
if (SourceString)
{
ReturnString = ExAllocatePool(PagedPool, SourceString->Length);
RtlCopyMemory(ReturnString, SourceString->Buffer, SourceString->Length);
DPRINT1("%S\n", ReturnString);
*Information = (ULONG_PTR)ReturnString;
}
return Status;
}
NTSTATUS
USBHUB_PdoHandlePnp(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
ULONG MinorFunction;
PIO_STACK_LOCATION Stack;
ULONG_PTR Information = 0;
NTSTATUS Status;
Stack = IoGetCurrentIrpStackLocation(Irp);
MinorFunction = Stack->MinorFunction;
switch (MinorFunction)
{
case IRP_MN_START_DEVICE:
{
DPRINT1("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
Status = USBHUB_PdoStartDevice(DeviceObject, Irp);
break;
}
case IRP_MN_QUERY_CAPABILITIES:
{
PDEVICE_CAPABILITIES DeviceCapabilities;
ULONG i;
DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_CAPABILITIES\n");
DeviceCapabilities = (PDEVICE_CAPABILITIES)Stack->Parameters.DeviceCapabilities.Capabilities;
// FIXME: capabilities can change with connected device
DeviceCapabilities->LockSupported = TRUE;
DeviceCapabilities->EjectSupported = TRUE;
DeviceCapabilities->Removable = TRUE;
DeviceCapabilities->DockDevice = FALSE;
DeviceCapabilities->UniqueID = TRUE;
DeviceCapabilities->SilentInstall = TRUE;
DeviceCapabilities->RawDeviceOK = FALSE;
DeviceCapabilities->SurpriseRemovalOK = TRUE;
DeviceCapabilities->HardwareDisabled = FALSE;
//DeviceCapabilities->NoDisplayInUI = FALSE;
DeviceCapabilities->DeviceState[0] = PowerDeviceD0;
for (i = 0; i < PowerSystemMaximum; i++)
DeviceCapabilities->DeviceState[i] = PowerDeviceD3;
//DeviceCapabilities->DeviceWake = PowerDeviceUndefined;
DeviceCapabilities->D1Latency = 0;
DeviceCapabilities->D2Latency = 0;
DeviceCapabilities->D3Latency = 0;
Status = STATUS_SUCCESS;
break;
}
case IRP_MN_QUERY_RESOURCES:
{
PCM_RESOURCE_LIST ResourceList;
DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCES\n");
ResourceList = ExAllocatePool(PagedPool, sizeof(CM_RESOURCE_LIST));
if (!ResourceList)
{
DPRINT1("ExAllocatePool() failed\n");
Status = STATUS_INSUFFICIENT_RESOURCES;
}
else
{
ResourceList->Count = 0;
Information = (ULONG_PTR)ResourceList;
Status = STATUS_SUCCESS;
}
break;
}
case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
{
PIO_RESOURCE_REQUIREMENTS_LIST ResourceList;
DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
ResourceList = ExAllocatePool(PagedPool, sizeof(IO_RESOURCE_REQUIREMENTS_LIST));
if (!ResourceList)
{
DPRINT1("ExAllocatePool() failed\n");
Status = STATUS_INSUFFICIENT_RESOURCES;
}
else
{
RtlZeroMemory(ResourceList, sizeof(IO_RESOURCE_REQUIREMENTS_LIST));
ResourceList->ListSize = sizeof(IO_RESOURCE_REQUIREMENTS_LIST);
ResourceList->AlternativeLists = 1;
ResourceList->List->Version = 1;
ResourceList->List->Revision = 1;
ResourceList->List->Count = 0;
Information = (ULONG_PTR)ResourceList;
Status = STATUS_SUCCESS;
}
break;
}
case IRP_MN_QUERY_DEVICE_TEXT:
{
Status = USBHUB_PdoQueryDeviceText(DeviceObject, Irp, &Information);
break;
}
case IRP_MN_QUERY_ID:
{
Status = USBHUB_PdoQueryId(DeviceObject, Irp, &Information);
break;
}
case IRP_MN_QUERY_BUS_INFORMATION:
{
PPNP_BUS_INFORMATION BusInfo;
BusInfo = (PPNP_BUS_INFORMATION)ExAllocatePool(PagedPool, sizeof(PNP_BUS_INFORMATION));
RtlCopyMemory(&BusInfo->BusTypeGuid,
&GUID_BUS_TYPE_USB,
sizeof(BusInfo->BusTypeGuid));
BusInfo->LegacyBusType = PNPBus;
// FIXME
BusInfo->BusNumber = 0;
Information = (ULONG_PTR)BusInfo;
Status = STATUS_SUCCESS;
break;
}
case IRP_MN_REMOVE_DEVICE:
{
//
// FIXME
//
Status = STATUS_SUCCESS;
}
default:
{
DPRINT1("PDO IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction);
Information = Irp->IoStatus.Information;
Status = Irp->IoStatus.Status;
}
}
Irp->IoStatus.Information = Information;
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}