Move common code of USB miniport drivers into drivers/usb/miniport/common library Added: trunk/reactos/drivers/usb/miniport/common/ Added: trunk/reactos/drivers/usb/miniport/common/cleanup.c Added: trunk/reactos/drivers/usb/miniport/common/close.c Added: trunk/reactos/drivers/usb/miniport/common/common.xml Added: trunk/reactos/drivers/usb/miniport/common/create.c Added: trunk/reactos/drivers/usb/miniport/common/fdo.c Added: trunk/reactos/drivers/usb/miniport/common/misc.c Added: trunk/reactos/drivers/usb/miniport/common/pdo.c Added: trunk/reactos/drivers/usb/miniport/common/uhci.c Added: trunk/reactos/drivers/usb/miniport/common/uhci.h Modified: trunk/reactos/drivers/usb/miniport/directory.xml Deleted: trunk/reactos/drivers/usb/miniport/usbuhci/cleanup.c Deleted: trunk/reactos/drivers/usb/miniport/usbuhci/close.c Deleted: trunk/reactos/drivers/usb/miniport/usbuhci/create.c Deleted: trunk/reactos/drivers/usb/miniport/usbuhci/fdo.c Deleted: trunk/reactos/drivers/usb/miniport/usbuhci/misc.c Deleted: trunk/reactos/drivers/usb/miniport/usbuhci/pdo.c Modified: trunk/reactos/drivers/usb/miniport/usbuhci/uhci.c Deleted: trunk/reactos/drivers/usb/miniport/usbuhci/uhci.h Modified: trunk/reactos/drivers/usb/miniport/usbuhci/usbuhci.xml _____
Copied: trunk/reactos/drivers/usb/miniport/common/cleanup.c (from rev 17754, trunk/reactos/drivers/usb/miniport/usbuhci/cleanup.c) _____
Copied: trunk/reactos/drivers/usb/miniport/common/close.c (from rev 17754, trunk/reactos/drivers/usb/miniport/usbuhci/close.c) _____
Added: trunk/reactos/drivers/usb/miniport/common/common.xml --- trunk/reactos/drivers/usb/miniport/common/common.xml 2005-09-10 14:46:06 UTC (rev 17775) +++ trunk/reactos/drivers/usb/miniport/common/common.xml 2005-09-10 15:17:07 UTC (rev 17776) @@ -0,0 +1,13 @@
+<module name="usbminiportcommon" type="objectlibrary"> + <define name="__USE_W32API" /> + <define name="DEBUG_MODE" /> + <include>../linux</include> + <include base="usbport"></include> + <file>cleanup.c</file> + <file>close.c</file> + <file>create.c</file> + <file>fdo.c</file> + <file>misc.c</file> + <file>pdo.c</file> + <file>uhci.c</file> +</module> _____
Copied: trunk/reactos/drivers/usb/miniport/common/create.c (from rev 17754, trunk/reactos/drivers/usb/miniport/usbuhci/create.c) _____
Copied: trunk/reactos/drivers/usb/miniport/common/fdo.c (from rev 17754, trunk/reactos/drivers/usb/miniport/usbuhci/fdo.c) --- trunk/reactos/drivers/usb/miniport/usbuhci/fdo.c 2005-09-08 21:54:42 UTC (rev 17754) +++ trunk/reactos/drivers/usb/miniport/common/fdo.c 2005-09-10 15:17:07 UTC (rev 17776) @@ -0,0 +1,350 @@
+/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS UHCI controller driver (Cromwell type) + * FILE: drivers/usb/cromwell/uhci/fdo.c + * PURPOSE: IRP_MJ_PNP/IRP_MJ_DEVICE_CONTROL operations for FDOs + * + * PROGRAMMERS: HervÚ Poussineau (hpoussin@reactos.com), + * James Tabor (jimtabor@adsl-64-217-116-74.dsl.hstntx.swbell.net) + */ + +#define NDEBUG +#include "uhci.h" + +#define IO_METHOD_FROM_CTL_CODE(ctlCode) (ctlCode&0x00000003) + +static VOID +UhciGetUserBuffers( + IN PIRP Irp, + IN ULONG IoControlCode, + OUT PVOID* BufferIn, + OUT PVOID* BufferOut) +{ + ASSERT(Irp); + ASSERT(BufferIn); + ASSERT(BufferOut); + + switch (IO_METHOD_FROM_CTL_CODE(IoControlCode)) + { + case METHOD_BUFFERED: + *BufferIn = *BufferOut = Irp->AssociatedIrp.SystemBuffer; + break; + case METHOD_IN_DIRECT: + case METHOD_OUT_DIRECT: + *BufferIn = Irp->AssociatedIrp.SystemBuffer; + *BufferOut = MmGetSystemAddressForMdl(Irp->MdlAddress); + break; + case METHOD_NEITHER: + *BufferIn = IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.Type3Input Buffer; + *BufferOut = Irp->UserBuffer; + break; + default: + /* Should never happen */ + *BufferIn = NULL; + *BufferOut = NULL; + break; + } +} + +NTSTATUS STDCALL +UhciFdoStartDevice( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp); + PDRIVER_OBJECT DriverObject; + POHCI_DRIVER_EXTENSION DriverExtension; + POHCI_DEVICE_EXTENSION DeviceExtension; + PCM_RESOURCE_LIST AllocatedResources; + + /* + * Get the initialization data we saved in VideoPortInitialize. + */ + DriverObject = DeviceObject->DriverObject; + DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject); + DeviceExtension = (POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + /* + * Store some resources in the DeviceExtension. + */ + AllocatedResources = Stack->Parameters.StartDevice.AllocatedResources; + if (AllocatedResources != NULL) + { + CM_FULL_RESOURCE_DESCRIPTOR *FullList; + CM_PARTIAL_RESOURCE_DESCRIPTOR *Descriptor; + ULONG ResourceCount; + ULONG ResourceListSize; + + /* Save the resource list */ + ResourceCount = AllocatedResources->List[0].PartialResourceList.Count; + + ResourceListSize = FIELD_OFFSET(CM_RESOURCE_LIST, List[0].PartialResourceList. + PartialDescriptors[ResourceCount]); + + DeviceExtension->AllocatedResources = ExAllocatePool(PagedPool, ResourceListSize); + if (DeviceExtension->AllocatedResources == NULL) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + + RtlCopyMemory(DeviceExtension->AllocatedResources, + AllocatedResources, + ResourceListSize); + + /* Get the interrupt level/vector - needed by HwFindAdapter sometimes */ + for (FullList = AllocatedResources->List; + FullList < AllocatedResources->List + AllocatedResources->Count; + FullList++) + { + /* FIXME: Is this ASSERT ok for resources from the PNP manager? */ + /*ASSERT(FullList->InterfaceType == PCIBus && + FullList->BusNumber == DeviceExtension->SystemIoBusNumber && + 1 == FullList->PartialResourceList.Version && + 1 == FullList->PartialResourceList.Revision);*/ + for (Descriptor = FullList->PartialResourceList.PartialDescriptors; + Descriptor < FullList->PartialResourceList.PartialDescriptors + FullList->PartialResourceList.Count; + Descriptor++) + { + if (Descriptor->Type == CmResourceTypeInterrupt) + { + DeviceExtension->InterruptLevel = Descriptor->u.Interrupt.Level; + DeviceExtension->InterruptVector = Descriptor->u.Interrupt.Vector; + } + else if (Descriptor->Type == CmResourceTypePort) + { + DeviceExtension->BaseAddress = Descriptor->u.Port.Start; + DeviceExtension->BaseAddrLength = Descriptor->u.Port.Length; + DeviceExtension->Flags = Descriptor->Flags; + + ((struct hc_driver *)(*pci_ids)->driver_data)->flags &= ~HCD_MEMORY; + } + else if (Descriptor->Type == CmResourceTypeMemory) + { + DeviceExtension->BaseAddress = Descriptor->u.Memory.Start; + DeviceExtension->BaseAddrLength = Descriptor->u.Memory.Length; + DeviceExtension->Flags = Descriptor->Flags; + + ((struct hc_driver *)(*pci_ids)->driver_data)->flags |= HCD_MEMORY; + } + } + } + } + + /* Print assigned resources */ + DPRINT("UHCI: Interrupt Vector 0x%lx, %S base 0x%lx, Length 0x%lx\n", + DeviceExtension->InterruptVector, + ((struct hc_driver *)(*pci_ids)->driver_data)->flags & HCD_MEMORY ? L"Memory" : L"I/O", + DeviceExtension->BaseAddress, + DeviceExtension->BaseAddrLength); + + /* Init wrapper with this object */ + return InitLinuxWrapper(DeviceObject); +} + +static NTSTATUS +UhciFdoQueryBusRelations( + IN PDEVICE_OBJECT DeviceObject, + OUT PDEVICE_RELATIONS* pDeviceRelations) +{ + POHCI_DEVICE_EXTENSION DeviceExtension; + PDEVICE_RELATIONS DeviceRelations; + NTSTATUS Status = STATUS_SUCCESS; + + DeviceExtension = (POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + /* Handling this IRP is easy, as we only + * have one child: the root hub + */ + DeviceRelations = (PDEVICE_RELATIONS)ExAllocatePool( + PagedPool, + sizeof(DEVICE_RELATIONS)); + if (!DeviceRelations) + return STATUS_INSUFFICIENT_RESOURCES; + + /* Fill returned structure */ + DeviceRelations->Count = 1; + ObReferenceObject(DeviceExtension->RootHubPdo); + DeviceRelations->Objects[0] = DeviceExtension->RootHubPdo; + + *pDeviceRelations = DeviceRelations; + return Status; +} + +NTSTATUS STDCALL +UhciPnpFdo( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IrpSp; + NTSTATUS Status; + ULONG MinorFunction; + ULONG_PTR Information = 0; + + IrpSp = IoGetCurrentIrpStackLocation(Irp); + MinorFunction = IrpSp->MinorFunction; + + switch (MinorFunction) + { + case IRP_MN_START_DEVICE: + { + Status = ForwardIrpAndWait(DeviceObject, Irp); + if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status)) + Status = UhciFdoStartDevice(DeviceObject, Irp); + break; + } + + case IRP_MN_REMOVE_DEVICE: + case IRP_MN_QUERY_REMOVE_DEVICE: + case IRP_MN_CANCEL_REMOVE_DEVICE: + case IRP_MN_SURPRISE_REMOVAL: + + case IRP_MN_STOP_DEVICE: + { + Status = ForwardIrpAndWait(DeviceObject, Irp); + if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status)) + Status = STATUS_SUCCESS; + IoDeleteDevice(DeviceObject); // just delete device for now + break; + } + case IRP_MN_QUERY_STOP_DEVICE: + case IRP_MN_CANCEL_STOP_DEVICE: + { + Status = STATUS_SUCCESS; + break; + } + case IRP_MN_QUERY_DEVICE_RELATIONS: /* (optional) 0x7 */ + { + switch (IrpSp->Parameters.QueryDeviceRelations.Type) + { + case BusRelations: + { + PDEVICE_RELATIONS DeviceRelations; + DPRINT("UHCI: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n"); + Status = UhciFdoQueryBusRelations(DeviceObject, &DeviceRelations); + Information = (ULONG_PTR)DeviceRelations; + break; + } + case RemovalRelations: + { + DPRINT1("UHCI: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations\n"); + return ForwardIrpAndForget(DeviceObject, Irp); + } + default: + DPRINT1("UHCI: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n", + IrpSp->Parameters.QueryDeviceRelations.Type); + return ForwardIrpAndForget(DeviceObject, Irp); + } + break; + } + + default: + { + DPRINT1("UHCI: unknown minor function 0x%lx\n", MinorFunction); + return ForwardIrpAndForget(DeviceObject, Irp); + } + } + Irp->IoStatus.Information = Information; + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; +} + +NTSTATUS +UhciDeviceControlFdo( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION Stack; + ULONG IoControlCode; + POHCI_DEVICE_EXTENSION DeviceExtension; + ULONG LengthIn, LengthOut; + ULONG_PTR Information = 0; + PVOID BufferIn, BufferOut; + NTSTATUS Status; + + DPRINT("UHCI: UsbDeviceControlFdo() called\n"); + + Stack = IoGetCurrentIrpStackLocation(Irp); + LengthIn = Stack->Parameters.DeviceIoControl.InputBufferLength; + LengthOut = Stack->Parameters.DeviceIoControl.OutputBufferLength; + DeviceExtension = (POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + IoControlCode = Stack->Parameters.DeviceIoControl.IoControlCode; + UhciGetUserBuffers(Irp, IoControlCode, &BufferIn, &BufferOut); + + switch (IoControlCode) + { + case IOCTL_GET_HCD_DRIVERKEY_NAME: + { + DPRINT("UHCI: IOCTL_GET_HCD_DRIVERKEY_NAME\n"); + if (LengthOut < sizeof(USB_HCD_DRIVERKEY_NAME)) + Status = STATUS_BUFFER_TOO_SMALL; + else if (BufferOut == NULL) + Status = STATUS_INVALID_PARAMETER; + else + { + PUSB_HCD_DRIVERKEY_NAME StringDescriptor; + ULONG StringSize; + StringDescriptor = (PUSB_HCD_DRIVERKEY_NAME)BufferOut; + Status = IoGetDeviceProperty( + ((POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->PhysicalDeviceO bject, + DevicePropertyDriverKeyName, + LengthOut - FIELD_OFFSET(USB_HCD_DRIVERKEY_NAME, DriverKeyName), + StringDescriptor->DriverKeyName, + &StringSize); + if (NT_SUCCESS(Status) || Status == STATUS_BUFFER_TOO_SMALL) + { + StringDescriptor->ActualLength = StringSize + FIELD_OFFSET(USB_HCD_DRIVERKEY_NAME, DriverKeyName); + Information = LengthOut; + Status = STATUS_SUCCESS; + } + } + break; + } + case IOCTL_USB_GET_ROOT_HUB_NAME: + { + DPRINT("UHCI: IOCTL_USB_GET_ROOT_HUB_NAME\n"); + if (LengthOut < sizeof(USB_ROOT_HUB_NAME)) + Status = STATUS_BUFFER_TOO_SMALL; + else if (BufferOut == NULL) + Status = STATUS_INVALID_PARAMETER; + else + { + PUSB_ROOT_HUB_NAME StringDescriptor; + PUNICODE_STRING RootHubInterfaceName; + StringDescriptor = (PUSB_ROOT_HUB_NAME)BufferOut; + DeviceObject = ((POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->RootHubPdo; + RootHubInterfaceName = &((POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->HcdInterfaceNa me; + + StringDescriptor->ActualLength = RootHubInterfaceName->Length + sizeof(WCHAR) + FIELD_OFFSET(USB_ROOT_HUB_NAME, RootHubName); + if (StringDescriptor->ActualLength <= LengthOut) + { + /* Copy root hub name */ + RtlCopyMemory( + StringDescriptor->RootHubName, + RootHubInterfaceName->Buffer, + RootHubInterfaceName->Length); + StringDescriptor->RootHubName[RootHubInterfaceName->Length / sizeof(WCHAR)] = UNICODE_NULL; + DPRINT("UHCI: IOCTL_USB_GET_ROOT_HUB_NAME returns '%S'\n", StringDescriptor->RootHubName); + Information = StringDescriptor->ActualLength; + } + else + Information = sizeof(USB_ROOT_HUB_NAME); + Status = STATUS_SUCCESS; + } + break; + } + + default: + { + /* Pass Irp to lower driver */ + DPRINT1("UHCI: Unknown IOCTL code 0x%lx\n", Stack->Parameters.DeviceIoControl.IoControlCode); + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(DeviceExtension->NextDeviceObject, Irp); + } + } + + Irp->IoStatus.Information = Information; + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; +} _____
Copied: trunk/reactos/drivers/usb/miniport/common/misc.c (from rev 17754, trunk/reactos/drivers/usb/miniport/usbuhci/misc.c) --- trunk/reactos/drivers/usb/miniport/usbuhci/misc.c 2005-09-08 21:54:42 UTC (rev 17754) +++ trunk/reactos/drivers/usb/miniport/common/misc.c 2005-09-10 15:17:07 UTC (rev 17776) @@ -0,0 +1,170 @@
+/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS UHCI controller driver (Cromwell type) + * FILE: drivers/usb/cromwell/uhci/misc.c + * PURPOSE: Misceallenous operations + * + * PROGRAMMERS: HervÚ Poussineau (hpoussin@reactos.com), + */ + +#define NDEBUG +#include "uhci.h" +#include <stdarg.h> + +NTSTATUS STDCALL +ForwardIrpAndWaitCompletion( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Context) +{ + if (Irp->PendingReturned) + KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE); + return STATUS_MORE_PROCESSING_REQUIRED; +} + +NTSTATUS +ForwardIrpAndWait( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PDEVICE_OBJECT LowerDevice = ((POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObjec t; + KEVENT Event; + NTSTATUS Status; + + ASSERT(LowerDevice); + + KeInitializeEvent(&Event, NotificationEvent, FALSE); + IoCopyCurrentIrpStackLocationToNext(Irp); + + DPRINT("UHCI: Calling lower device %p [%wZ]\n", LowerDevice, &LowerDevice->DriverObject->DriverName); + IoSetCompletionRoutine(Irp, ForwardIrpAndWaitCompletion, &Event, TRUE, TRUE, TRUE); + + Status = IoCallDriver(LowerDevice, Irp); + if (Status == STATUS_PENDING) + { + Status = KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL); + if (NT_SUCCESS(Status)) + Status = Irp->IoStatus.Status; + } + + return Status; +} + +NTSTATUS STDCALL +ForwardIrpAndForget( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PDEVICE_OBJECT LowerDevice = ((POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObjec t; + + ASSERT(LowerDevice); + + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(LowerDevice, Irp); +} + +/* I really want PCSZ strings as last arguments because + * PnP ids are ANSI-encoded in PnP device string + * identification */ +NTSTATUS +UhciInitMultiSzString( + OUT PUNICODE_STRING Destination, + ... /* list of PCSZ */) +{ + va_list args; + PCSZ Source; + ANSI_STRING AnsiString; + UNICODE_STRING UnicodeString; + ULONG DestinationSize = 0; + NTSTATUS Status = STATUS_SUCCESS; + + ASSERT(Destination); + + /* Calculate length needed for destination unicode string */ + va_start(args, Destination); + Source = va_arg(args, PCSZ); + while (Source != NULL) + { + DPRINT1("Source = %s\n", Source); + RtlInitAnsiString(&AnsiString, Source); + DPRINT1("AnsiString = %Z\n", &AnsiString); + DPRINT1("NLS_MB_CODE_PAGE_TAG = %lu\n", (ULONG)NLS_MB_CODE_PAGE_TAG); + DestinationSize += RtlAnsiStringToUnicodeSize(&AnsiString) + + sizeof(WCHAR) /* final NULL */; + DPRINT1("DestinationSize = %lu\n", DestinationSize); + Source = va_arg(args, PCSZ); + } + va_end(args); + if (DestinationSize == 0) + { + RtlInitUnicodeString(Destination, NULL); + return STATUS_SUCCESS; + } + + /* Initialize destination string */ + DestinationSize += sizeof(WCHAR); // final NULL + Destination->Buffer = (PWSTR)ExAllocatePoolWithTag(PagedPool, DestinationSize, USB_UHCI_TAG); + if (!Destination->Buffer) + return STATUS_INSUFFICIENT_RESOURCES; + Destination->Length = 0; + Destination->MaximumLength = (USHORT)DestinationSize; + + /* Copy arguments to destination string */ + /* Use a temporary unicode string, which buffer is shared with + * destination string, to copy arguments */ + UnicodeString.Length = Destination->Length; + UnicodeString.MaximumLength = Destination->MaximumLength; + UnicodeString.Buffer = Destination->Buffer; + va_start(args, Destination); + Source = va_arg(args, PCSZ); + while (Source != NULL) + { + RtlInitAnsiString(&AnsiString, Source); + Status = RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, FALSE); + if (!NT_SUCCESS(Status)) + { + ExFreePoolWithTag(Destination->Buffer, USB_UHCI_TAG); + break; + } + Destination->Length += UnicodeString.Length + sizeof(WCHAR); + UnicodeString.MaximumLength -= UnicodeString.Length + sizeof(WCHAR); + UnicodeString.Buffer += UnicodeString.Length / sizeof(WCHAR) + 1; + UnicodeString.Length = 0; + Source = va_arg(args, PCSZ); + } + va_end(args); + if (NT_SUCCESS(Status)) + { + /* Finish multi-sz string */ + Destination->Buffer[Destination->Length / sizeof(WCHAR)] = L'\0'; + Destination->Length += sizeof(WCHAR); + } + return Status; +} + +NTSTATUS +UhciDuplicateUnicodeString( + OUT PUNICODE_STRING Destination, + IN PUNICODE_STRING Source, + IN POOL_TYPE PoolType) +{ + ASSERT(Destination); + + if (Source == NULL) + { + RtlInitUnicodeString(Destination, NULL); + return STATUS_SUCCESS; + } + + Destination->Buffer = ExAllocatePool(PoolType, Source->MaximumLength); + if (Destination->Buffer == NULL) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + + Destination->MaximumLength = Source->MaximumLength; + Destination->Length = Source->Length; + RtlCopyMemory(Destination->Buffer, Source->Buffer, Source->MaximumLength); + + return STATUS_SUCCESS; +} _____
Copied: trunk/reactos/drivers/usb/miniport/common/pdo.c (from rev 17754, trunk/reactos/drivers/usb/miniport/usbuhci/pdo.c) _____
Copied: trunk/reactos/drivers/usb/miniport/common/uhci.c (from rev 17754, trunk/reactos/drivers/usb/miniport/usbuhci/uhci.c) --- trunk/reactos/drivers/usb/miniport/usbuhci/uhci.c 2005-09-08 21:54:42 UTC (rev 17754) +++ trunk/reactos/drivers/usb/miniport/common/uhci.c 2005-09-10 15:17:07 UTC (rev 17776) @@ -0,0 +1,274 @@
+/* + ReactOS specific functions for UHCI module + by Aleksey Bragin (aleksey@reactos.com) + and HervÚ Poussineau (hpoussin@reactos.com) + Some parts of code are inspired (or even just copied) from ReactOS Videoport driver +*/ +#define NDEBUG +#define INITGUID +#include "uhci.h" + +static ULONG DeviceNumber = 0; /* FIXME: what is that? */ + +static NTSTATUS +CreateRootHubPdo( + IN PDRIVER_OBJECT DriverObject, + IN PDEVICE_OBJECT Fdo, + OUT PDEVICE_OBJECT* pPdo) +{ + PDEVICE_OBJECT Pdo; + POHCI_DEVICE_EXTENSION DeviceExtension; + NTSTATUS Status; + + DPRINT("UHCI: CreateRootHubPdo()\n"); + + Status = IoCreateDevice( + DriverObject, + sizeof(OHCI_DEVICE_EXTENSION), + NULL, /* DeviceName */ + FILE_DEVICE_BUS_EXTENDER, + FILE_DEVICE_SECURE_OPEN | FILE_AUTOGENERATED_DEVICE_NAME, + FALSE, + &Pdo); + if (!NT_SUCCESS(Status)) + { + DPRINT("UHCI: IoCreateDevice() call failed with status 0x%08x\n", Status); + return Status; + } + + Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE; + Pdo->Flags |= DO_POWER_PAGABLE; + + // zerofill device extension + DeviceExtension = (POHCI_DEVICE_EXTENSION)Pdo->DeviceExtension; + RtlZeroMemory(DeviceExtension, sizeof(OHCI_DEVICE_EXTENSION)); + + DeviceExtension->IsFDO = FALSE; + DeviceExtension->FunctionalDeviceObject = Fdo; + + Pdo->Flags &= ~DO_DEVICE_INITIALIZING; + + *pPdo = Pdo; + return STATUS_SUCCESS; +} + +NTSTATUS STDCALL +AddDevice( + IN PDRIVER_OBJECT DriverObject, + IN PDEVICE_OBJECT pdo) +{ + PDEVICE_OBJECT fdo; + NTSTATUS Status; + WCHAR DeviceBuffer[20]; + WCHAR LinkDeviceBuffer[20]; + UNICODE_STRING DeviceName; + UNICODE_STRING LinkDeviceName; + POHCI_DRIVER_EXTENSION DriverExtension; + POHCI_DEVICE_EXTENSION DeviceExtension; + + DPRINT("UHCI: AddDevice called\n"); + + // Allocate driver extension now + DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject); + if (DriverExtension == NULL) + { + Status = IoAllocateDriverObjectExtension( + DriverObject, + DriverObject, + sizeof(OHCI_DRIVER_EXTENSION), + (PVOID *)&DriverExtension); + + if (!NT_SUCCESS(Status)) + { + DPRINT("UHCI: Allocating DriverObjectExtension failed.\n"); + return Status; + } + } + + // Create a unicode device name +// DeviceNumber = 0; //TODO: Allocate new device number every time + swprintf(DeviceBuffer, L"\Device\USBFDO-%lu", DeviceNumber); + RtlInitUnicodeString(&DeviceName, DeviceBuffer); + + Status = IoCreateDevice(DriverObject, + sizeof(OHCI_DEVICE_EXTENSION), + &DeviceName, + FILE_DEVICE_BUS_EXTENDER, + 0, + FALSE, + &fdo); + + if (!NT_SUCCESS(Status)) + { + DPRINT("UHCI: IoCreateDevice call failed with status 0x%08lx\n", Status); + return Status; + } + + // zerofill device extension + DeviceExtension = (POHCI_DEVICE_EXTENSION)fdo->DeviceExtension; + RtlZeroMemory(DeviceExtension, sizeof(OHCI_DEVICE_EXTENSION)); + + /* Create root hub Pdo */ + Status = CreateRootHubPdo(DriverObject, fdo, &DeviceExtension->RootHubPdo); + if (!NT_SUCCESS(Status)) + { + DPRINT("UHCI: CreateRootHubPdo() failed with status 0x%08lx\n", Status); + IoDeleteDevice(fdo); + return Status; + } + + /* Register device interface for controller */ + Status = IoRegisterDeviceInterface( + pdo, + &GUID_DEVINTERFACE_USB_HOST_CONTROLLER, + NULL, + &DeviceExtension->HcdInterfaceName); + if (!NT_SUCCESS(Status)) + { + DPRINT("UHCI: IoRegisterDeviceInterface() failed with status 0x%08lx\n", Status); + IoDeleteDevice(DeviceExtension->RootHubPdo); + IoDeleteDevice(fdo); + return Status; + } + + DeviceExtension->NextDeviceObject = IoAttachDeviceToDeviceStack(fdo, pdo); + + fdo->Flags &= ~DO_DEVICE_INITIALIZING; + + // Initialize device extension + DeviceExtension->IsFDO = TRUE; + DeviceExtension->DeviceNumber = DeviceNumber; + DeviceExtension->PhysicalDeviceObject = pdo; + DeviceExtension->FunctionalDeviceObject = fdo; + DeviceExtension->DriverExtension = DriverExtension; + + /* FIXME: do a loop to find an available number */ + swprintf(LinkDeviceBuffer, L"\??\HCD%lu", 0); + + RtlInitUnicodeString(&LinkDeviceName, LinkDeviceBuffer); + + Status = IoCreateSymbolicLink(&LinkDeviceName, &DeviceName); + + if (!NT_SUCCESS(Status)) + { + DPRINT("UHCI: IoCreateSymbolicLink call failed with status 0x%08x\n", Status); + IoDeleteDevice(DeviceExtension->RootHubPdo); + IoDeleteDevice(fdo); + return Status; + } + + return STATUS_SUCCESS; +} + +NTSTATUS STDCALL +IrpStub( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + NTSTATUS Status = STATUS_NOT_SUPPORTED; + + if (((POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO) + { + DPRINT1("UHCI: FDO stub for major function 0x%lx\n", + IoGetCurrentIrpStackLocation(Irp)->MajorFunction); +#ifndef NDEBUG + DbgBreakPoint(); +#endif + return ForwardIrpAndForget(DeviceObject, Irp); + } + else + { + /* We can't forward request to the lower driver, because + * we are a Pdo, so we don't have lower driver... + */ + DPRINT1("UHCI: PDO stub for major function 0x%lx\n", + IoGetCurrentIrpStackLocation(Irp)->MajorFunction); +#ifndef NDEBUG + DbgBreakPoint(); +#endif + } + + Status = Irp->IoStatus.Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; +} + +static NTSTATUS STDCALL +DispatchCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp) +{ + if (((POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO) + return UhciCreate(DeviceObject, Irp); + else + return IrpStub(DeviceObject, Irp); +} + +static NTSTATUS STDCALL +DispatchClose(PDEVICE_OBJECT DeviceObject, PIRP Irp) +{ + if (((POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO) + return UhciClose(DeviceObject, Irp); + else + return IrpStub(DeviceObject, Irp); +} + +static NTSTATUS STDCALL +DispatchCleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp) +{ + if (((POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO) + return UhciCleanup(DeviceObject, Irp); + else + return IrpStub(DeviceObject, Irp); +} + +static NTSTATUS STDCALL +DispatchDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) +{ + if (((POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO) + return UhciDeviceControlFdo(DeviceObject, Irp); + else + return UhciDeviceControlPdo(DeviceObject, Irp); +} + +static NTSTATUS STDCALL +DispatchPnp(PDEVICE_OBJECT DeviceObject, PIRP Irp) +{ + if (((POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO) + return UhciPnpFdo(DeviceObject, Irp); + else + return UhciPnpPdo(DeviceObject, Irp); +} + +static NTSTATUS STDCALL +DispatchPower(PDEVICE_OBJECT fido, PIRP Irp) +{ + DPRINT1("UHCI: IRP_MJ_POWER unimplemented\n"); + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; +} + +/* + * Standard DriverEntry method. + */ +NTSTATUS STDCALL +DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegPath) +{ + ULONG i; + DPRINT("********* Cromwell UHCI *********\n"); + + DriverObject->DriverUnload = DriverUnload; + DriverObject->DriverExtension->AddDevice = AddDevice; + + for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) + DriverObject->MajorFunction[i] = IrpStub; + + DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreate; + DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchClose; + DriverObject->MajorFunction[IRP_MJ_CLEANUP] = DispatchCleanup; + DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl; + DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp; + DriverObject->MajorFunction[IRP_MJ_POWER] = DispatchPower; + + return STATUS_SUCCESS; +} _____
Copied: trunk/reactos/drivers/usb/miniport/common/uhci.h (from rev 17754, trunk/reactos/drivers/usb/miniport/usbuhci/uhci.h) --- trunk/reactos/drivers/usb/miniport/usbuhci/uhci.h 2005-09-08 21:54:42 UTC (rev 17754) +++ trunk/reactos/drivers/usb/miniport/common/uhci.h 2005-09-10 15:17:07 UTC (rev 17776) @@ -0,0 +1,84 @@
+//#include <ddk/ntddk.h> +// config and include core/hcd.h, for hc_device struct struct usb_interface *usb_ifnum_to_if(struct usb_device *dev, unsigned ifnum) + +#include "../usb_wrapper.h" +#include <ddk/usbdi.h> +#include <ddk/usbiodef.h> +#include <initguid.h> + +#include "hcd.h" + +#include "../usbohci/ohci_main.h" + +#define USB_UHCI_TAG TAG('u','s','b','u') + +/* cleanup.c */ +NTSTATUS STDCALL +UhciCleanup( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +/* close.c */ +NTSTATUS STDCALL +UhciClose( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +/* create.c */ +NTSTATUS STDCALL +UhciCreate( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +/* fdo.c */ +NTSTATUS STDCALL +UhciPnpFdo( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +NTSTATUS +UhciDeviceControlFdo( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +/* misc.c */ +NTSTATUS +ForwardIrpAndWait( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +NTSTATUS STDCALL +ForwardIrpAndForget( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +NTSTATUS +UhciDuplicateUnicodeString( + OUT PUNICODE_STRING Destination, + IN PUNICODE_STRING Source, + IN POOL_TYPE PoolType); + +NTSTATUS +UhciInitMultiSzString( + OUT PUNICODE_STRING Destination, + ... /* list of PCSZ */); + +/* pdo.c */ +NTSTATUS STDCALL +UhciPnpPdo( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +NTSTATUS +UhciDeviceControlPdo( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +/* Needed by this object library */ +VOID STDCALL +DriverUnload(PDRIVER_OBJECT DriverObject); + +NTSTATUS +InitLinuxWrapper(PDEVICE_OBJECT DeviceObject); + +extern struct pci_device_id** pci_ids; _____
Modified: trunk/reactos/drivers/usb/miniport/directory.xml --- trunk/reactos/drivers/usb/miniport/directory.xml 2005-09-10 14:46:06 UTC (rev 17775) +++ trunk/reactos/drivers/usb/miniport/directory.xml 2005-09-10 15:17:07 UTC (rev 17776) @@ -1,3 +1,6 @@
+<directory name="common"> + <xi:include href="common/common.xml" /> +</directory> <directory name="sys"> <xi:include href="sys/sys.xml" /> </directory> _____
Deleted: trunk/reactos/drivers/usb/miniport/usbuhci/cleanup.c --- trunk/reactos/drivers/usb/miniport/usbuhci/cleanup.c 2005-09-10 14:46:06 UTC (rev 17775) +++ trunk/reactos/drivers/usb/miniport/usbuhci/cleanup.c 2005-09-10 15:17:07 UTC (rev 17776) @@ -1,24 +0,0 @@
-/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS UHCI controller driver (Cromwell type) - * FILE: drivers/usb/cromwell/uhci/cleanup.c - * PURPOSE: IRP_MJ_CLEANUP operations - * - * PROGRAMMERS: HervÚ Poussineau (hpoussin@reactos.com) - */ - -#define NDEBUG -#include "uhci.h" - -NTSTATUS STDCALL -UhciCleanup( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - DPRINT("UHCI: IRP_MJ_CLEANUP\n"); - - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = STATUS_SUCCESS; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_SUCCESS; -} _____
Deleted: trunk/reactos/drivers/usb/miniport/usbuhci/close.c --- trunk/reactos/drivers/usb/miniport/usbuhci/close.c 2005-09-10 14:46:06 UTC (rev 17775) +++ trunk/reactos/drivers/usb/miniport/usbuhci/close.c 2005-09-10 15:17:07 UTC (rev 17776) @@ -1,28 +0,0 @@
-/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS UHCI controller driver (Cromwell type) - * FILE: drivers/usb/cromwell/uhci/close.c - * PURPOSE: IRP_MJ_CLOSE operations - * - * PROGRAMMERS: HervÚ Poussineau (hpoussin@reactos.com) - */ - -#define NDEBUG -#include "uhci.h" - -NTSTATUS STDCALL -UhciClose( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - POHCI_DEVICE_EXTENSION pDeviceExtension; - - DPRINT("UHCI: IRP_MJ_CLOSE\n"); - pDeviceExtension = (POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - InterlockedDecrement((PLONG)&pDeviceExtension->DeviceOpened); - - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = STATUS_SUCCESS; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_SUCCESS; -} _____
Deleted: trunk/reactos/drivers/usb/miniport/usbuhci/create.c --- trunk/reactos/drivers/usb/miniport/usbuhci/create.c 2005-09-10 14:46:06 UTC (rev 17775) +++ trunk/reactos/drivers/usb/miniport/usbuhci/create.c 2005-09-10 15:17:07 UTC (rev 17776) @@ -1,41 +0,0 @@
-/* - * COPYRIGHT: See COPYING in the top level directory [truncated at 1000 lines; 1350 more skipped]