Enumerate root hub connected to UHCI controller Use Cromwell USB stack to initialize UHCI controller Added: trunk/reactos/drivers/usb/cromwell/uhci/close.c Added: trunk/reactos/drivers/usb/cromwell/uhci/create.c Added: trunk/reactos/drivers/usb/cromwell/uhci/fdo.c Added: trunk/reactos/drivers/usb/cromwell/uhci/misc.c Added: trunk/reactos/drivers/usb/cromwell/uhci/pdo.c Added: trunk/reactos/drivers/usb/cromwell/uhci/uhci.c Deleted: trunk/reactos/drivers/usb/cromwell/uhci/uhci.def Added: trunk/reactos/drivers/usb/cromwell/uhci/uhci.h Modified: trunk/reactos/drivers/usb/cromwell/uhci/uhci.xml Deleted: trunk/reactos/drivers/usb/cromwell/uhci/uhci_main.c _____
Added: trunk/reactos/drivers/usb/cromwell/uhci/close.c --- trunk/reactos/drivers/usb/cromwell/uhci/close.c 2005-06-14 03:35:23 UTC (rev 15904) +++ trunk/reactos/drivers/usb/cromwell/uhci/close.c 2005-06-14 12:31:51 UTC (rev 15905) @@ -0,0 +1,28 @@
+/* + * 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; +} Property changes on: trunk/reactos/drivers/usb/cromwell/uhci/close.c ___________________________________________________________________ Name: svn:eol-style + native _____
Added: trunk/reactos/drivers/usb/cromwell/uhci/create.c --- trunk/reactos/drivers/usb/cromwell/uhci/create.c 2005-06-14 03:35:23 UTC (rev 15904) +++ trunk/reactos/drivers/usb/cromwell/uhci/create.c 2005-06-14 12:31:51 UTC (rev 15905) @@ -0,0 +1,41 @@
+/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS UHCI controller driver (Cromwell type) + * FILE: drivers/usb/cromwell/uhci/create.c + * PURPOSE: IRP_MJ_CREATE operations + * + * PROGRAMMERS: HervÚ Poussineau (hpoussin@reactos.com) + */ + +#define NDEBUG +#include "uhci.h" + +NTSTATUS STDCALL +UhciCreate( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION Stack; + POHCI_DEVICE_EXTENSION DeviceExtension; + NTSTATUS Status; + + DPRINT("UHCI: IRP_MJ_CREATE\n"); + Stack = IoGetCurrentIrpStackLocation(Irp); + DeviceExtension = (POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + if (Stack->Parameters.Create.Options & FILE_DIRECTORY_FILE) + { + CHECKPOINT; + Status = STATUS_NOT_A_DIRECTORY; + goto ByeBye; + } + + InterlockedIncrement((PLONG)&DeviceExtension->DeviceOpened); + Status = STATUS_SUCCESS; + +ByeBye: + Irp->IoStatus.Status = Status; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; +} Property changes on: trunk/reactos/drivers/usb/cromwell/uhci/create.c ___________________________________________________________________ Name: svn:eol-style + native _____
Added: trunk/reactos/drivers/usb/cromwell/uhci/fdo.c --- trunk/reactos/drivers/usb/cromwell/uhci/fdo.c 2005-06-14 03:35:23 UTC (rev 15904) +++ trunk/reactos/drivers/usb/cromwell/uhci/fdo.c 2005-06-14 12:31:51 UTC (rev 15905) @@ -0,0 +1,422 @@
+/* + * 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" + +/* declare basic init functions and structures */ +int uhci_hcd_init(void); +int STDCALL usb_init(void); + +extern struct pci_driver uhci_pci_driver; +extern struct pci_device_id uhci_pci_ids[]; + +static NTSTATUS +InitLinuxWrapper(PDEVICE_OBJECT DeviceObject) +{ + NTSTATUS Status = STATUS_SUCCESS; + + POHCI_DEVICE_EXTENSION DeviceExtension = (POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + /* Create generic linux structure */ + struct pci_dev *dev; + dev = ExAllocatePoolWithTag(PagedPool, sizeof(struct pci_dev), USB_UHCI_TAG); + DeviceExtension->pdev = dev; + + /* Initialize generic linux structure */ + init_wrapper(dev); + dev->irq = DeviceExtension->InterruptVector; + dev->dev_ext = (PVOID)DeviceExtension; + dev->slot_name = ExAllocatePoolWithTag(NonPagedPool, 128, USB_UHCI_TAG); // 128 max len for slot name + + strcpy(dev->dev.name, "UnivHCI PCI-USB Controller"); + strcpy(dev->slot_name, "UHCD PCI Slot"); + + /* Init the OHCI HCD. Probe will be called automatically, but will fail because id=NULL */ + Status = uhci_hcd_init(); + if (!NT_SUCCESS(Status)) + { + DPRINT("UHCI: uhci_hcd_init() failed with status 0x%08lx\n", Status); + /* FIXME: deinitialize linux wrapper */ + ExFreePoolWithTag(dev, USB_UHCI_TAG); + return Status; + } + + /* Init core usb */ + usb_init(); + + /* Probe device with real id now */ + uhci_pci_driver.probe(dev, uhci_pci_ids); + +// DPRINT1("UHCI :SysIoBusNumA %d\n",DeviceExtension->SystemIoBusNumber); +// DeviceExtension->SystemIoBusNumber = dev->bus->number; +// DPRINT1("UHCI: SysIoBusNumB %d\n",DeviceExtension->SystemIoBusNumber); + + return Status; +} + +#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 *)uhci_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 *)uhci_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 *)uhci_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: + { + DPRINT1("UHCI: IOCTL_GET_HCD_DRIVERKEY_NAME does not return correct string\n"); + /* FIXME: should return sth like {36FC9E60-C465-11CF-8056-444553540000}\0000 */ + if (LengthOut < sizeof(USB_HCD_DRIVERKEY_NAME)) + { + Status = STATUS_BUFFER_TOO_SMALL; + } + else + { + PUSB_HCD_DRIVERKEY_NAME StringDescriptor; + ULONG StringSize; + StringDescriptor = (PUSB_HCD_DRIVERKEY_NAME)BufferOut; + Status = IoGetDeviceProperty( + ((POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->PhysicalDeviceO bject, + DevicePropertyDeviceDescription, + LengthOut - FIELD_OFFSET(USB_HCD_DRIVERKEY_NAME, DriverKeyName), + StringDescriptor->DriverKeyName, + &StringSize); + if (NT_SUCCESS(Status) || Status == STATUS_BUFFER_TOO_SMALL) + { + DPRINT("UHCI: IOCTL_GET_HCD_DRIVERKEY_NAME returns '%S'\n", StringDescriptor->DriverKeyName); + 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_HCD_DRIVERKEY_NAME)) + { + Status = STATUS_BUFFER_TOO_SMALL; + } + else + { + PUSB_HCD_DRIVERKEY_NAME StringDescriptor; + PUNICODE_STRING RootHubInterfaceName; + StringDescriptor = (PUSB_HCD_DRIVERKEY_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_HCD_DRIVERKEY_NAME, DriverKeyName); + if (StringDescriptor->ActualLength <= LengthOut) + { + /* Copy root hub name */ + RtlCopyMemory( + StringDescriptor->DriverKeyName, + RootHubInterfaceName->Buffer, + RootHubInterfaceName->Length); + StringDescriptor->DriverKeyName[RootHubInterfaceName->Length / sizeof(WCHAR)] = '\0'; + DPRINT("UHCI: IOCTL_USB_GET_ROOT_HUB_NAME returns '%S'\n", StringDescriptor->DriverKeyName); + Information = StringDescriptor->ActualLength; + } + else + Information = sizeof(USB_HCD_DRIVERKEY_NAME); + Status = STATUS_SUCCESS; + } + break; + } + + /*case IOCTL_USB_GET_NODE_INFORMATION: + { + DPRINT1("UHCI: IOCTL_USB_GET_NODE_INFORMATION\n"); + Status = STATUS_NOT_IMPLEMENTED; + break; + }*/ + case IOCTL_USB_GET_NODE_CONNECTION_INFORMATION: + { + DPRINT1("UHCI: IOCTL_USB_GET_NODE_CONNECTION_INFORMATION\n"); + Status = STATUS_NOT_IMPLEMENTED; + break; + } + case IOCTL_USB_GET_NODE_CONNECTION_NAME: + { + DPRINT1("UHCI: IOCTL_USB_GET_NODE_CONNECTION_NAME\n"); + Status = STATUS_NOT_IMPLEMENTED; + 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; +} Property changes on: trunk/reactos/drivers/usb/cromwell/uhci/fdo.c ___________________________________________________________________ Name: svn:eol-style + native _____
Added: trunk/reactos/drivers/usb/cromwell/uhci/misc.c --- trunk/reactos/drivers/usb/cromwell/uhci/misc.c 2005-06-14 03:35:23 UTC (rev 15904) +++ trunk/reactos/drivers/usb/cromwell/uhci/misc.c 2005-06-14 12:31:51 UTC (rev 15905) @@ -0,0 +1,166 @@
+/* + * 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) + { + RtlInitAnsiString(&AnsiString, Source); + DestinationSize += RtlAnsiStringToUnicodeSize(&AnsiString) + + sizeof(WCHAR) /* final NULL */; + 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; +} Property changes on: trunk/reactos/drivers/usb/cromwell/uhci/misc.c ___________________________________________________________________ Name: svn:eol-style + native _____
Added: trunk/reactos/drivers/usb/cromwell/uhci/pdo.c --- trunk/reactos/drivers/usb/cromwell/uhci/pdo.c 2005-06-14 03:35:23 UTC (rev 15904) +++ trunk/reactos/drivers/usb/cromwell/uhci/pdo.c 2005-06-14 12:31:51 UTC (rev 15905) @@ -0,0 +1,196 @@
+/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS UHCI controller driver (Cromwell type) + * FILE: drivers/usb/cromwell/uhci/pdo.c + * PURPOSE: IRP_MJ_PNP/IRP_MJ_DEVICE_CONTROL operations for PDOs + * + * PROGRAMMERS: HervÚ Poussineau (hpoussin@reactos.com), + * James Tabor (jimtabor@adsl-64-217-116-74.dsl.hstntx.swbell.net) + */ + +#define NDEBUG +#include "uhci.h" + +extern struct usb_driver hub_driver; + +#define IO_METHOD_FROM_CTL_CODE(ctlCode) (ctlCode&0x00000003) + +NTSTATUS +UhciDeviceControlPdo( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION Stack; + ULONG_PTR Information = 0; + NTSTATUS Status; + + DPRINT("UHCI: UhciDeviceControlPdo() called\n"); + + Stack = IoGetCurrentIrpStackLocation(Irp); + Status = Irp->IoStatus.Status; + + switch (Stack->Parameters.DeviceIoControl.IoControlCode) + { + case IOCTL_INTERNAL_USB_GET_ROOT_USB_DEVICE: + { + POHCI_DEVICE_EXTENSION DeviceExtension; + + DPRINT("UHCI: IOCTL_INTERNAL_USB_GET_ROOT_USB_DEVICE\n"); + if (Irp->AssociatedIrp.SystemBuffer == NULL + || Stack->Parameters.DeviceIoControl.OutputBufferLength != sizeof(PVOID)) + { + Status = STATUS_INVALID_PARAMETER; + } + else + { + PVOID* pRootHubPointer; + DeviceExtension = (POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + DeviceExtension = (POHCI_DEVICE_EXTENSION)DeviceExtension->FunctionalDeviceObject->DeviceE xtension; + + pRootHubPointer = (PVOID*)Irp->AssociatedIrp.SystemBuffer; + *pRootHubPointer = (PVOID)DeviceExtension->pdev->bus; /* struct usb_device* */ + Information = sizeof(PVOID); + Status = STATUS_SUCCESS; + } + break; + } + default: + { + DPRINT1("UHCI: 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; +} + +static NTSTATUS +UhciPdoQueryId( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + OUT ULONG_PTR* Information) +{ + POHCI_DEVICE_EXTENSION DeviceExtension; + ULONG IdType; + UNICODE_STRING SourceString; + UNICODE_STRING String; + NTSTATUS Status; + + IdType = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryId.IdType; + DeviceExtension = (POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + RtlInitUnicodeString(&String, NULL); + + switch (IdType) + { + case BusQueryDeviceID: + { + DPRINT("UHCI: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n"); + RtlInitUnicodeString(&SourceString, L"USB\ROOT_HUB"); + break; + } + case BusQueryHardwareIDs: + { + DPRINT("UHCI: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryHardwareIDs\n"); + /* FIXME: Should return + USB\ROOT_HUB&VID????&PID????&REV???? + USB\ROOT_HUB&VID????&PID???? + USB\ROOT_HUB + */ + UhciInitMultiSzString(&SourceString, "USB\ROOT_HUB", NULL); + break; + } + case BusQueryCompatibleIDs: + DPRINT("UHCI: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryCompatibleIDs\n"); + /* No compatible ID */ + *Information = 0; + return STATUS_NOT_SUPPORTED; + case BusQueryInstanceID: + { + DPRINT("UHCI: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryInstanceID\n"); + RtlInitUnicodeString(&SourceString, L"0000"); /* FIXME */ + break; + } + default: + DPRINT1("UHCI: IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n", IdType); + return STATUS_NOT_SUPPORTED; + } + + Status = UhciDuplicateUnicodeString( + &String, + &SourceString, + PagedPool); + *Information = (ULONG_PTR)String.Buffer; + return Status; +} + +static NTSTATUS +UhciPnpStartDevice( + IN PDEVICE_OBJECT DeviceObject) +{ + POHCI_DEVICE_EXTENSION DeviceExtension; + NTSTATUS Status; + + DeviceExtension = (POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + /* Register device interface for root hub */ + Status = IoRegisterDeviceInterface( + DeviceObject, + &GUID_DEVINTERFACE_USB_HUB, + NULL, + &DeviceExtension->HcdInterfaceName); + if (!NT_SUCCESS(Status)) + { + DPRINT("UHCI: IoRegisterDeviceInterface() failed with status 0x%08lx\n", Status); + return Status; + } + + return Status; +} + +NTSTATUS STDCALL +UhciPnpPdo( + 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: /* 0x00 */ + { + DPRINT("UHCI: IRP_MJ_PNP/IRP_MN_START_DEVICE\n"); + Status = UhciPnpStartDevice(DeviceObject); + break; + } + case IRP_MN_QUERY_ID: /* 0x13 */ + { + Status = UhciPdoQueryId(DeviceObject, Irp, &Information); + break; + } + default: + { + /* We can't forward request to the lower driver, because + * we are a Pdo, so we don't have lower driver... + */ + DPRINT1("UHCI: 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; +} + Property changes on: trunk/reactos/drivers/usb/cromwell/uhci/pdo.c ___________________________________________________________________ Name: svn:eol-style + native _____
Added: trunk/reactos/drivers/usb/cromwell/uhci/uhci.c --- trunk/reactos/drivers/usb/cromwell/uhci/uhci.c 2005-06-14 03:35:23 UTC (rev 15904) +++ trunk/reactos/drivers/usb/cromwell/uhci/uhci.c 2005-06-14 12:31:51 UTC (rev 15905) @@ -0,0 +1,297 @@
+/* + 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" + +/* declare basic init functions and structures */ +void uhci_hcd_cleanup(void); +void STDCALL usb_exit(void); + +extern struct pci_driver uhci_pci_driver; + +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); [truncated at 1000 lines; 696 more skipped]