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(a)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(a)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(a)reactos.com),
+ * James Tabor
(jimtabor(a)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(a)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(a)reactos.com),
+ * James Tabor
(jimtabor(a)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(a)reactos.com)
+ and HervÚ Poussineau (hpoussin(a)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]