mirror of
https://github.com/reactos/reactos.git
synced 2025-02-25 09:50:02 +00:00
Enumerate root hub connected to UHCI controller
Use Cromwell USB stack to initialize UHCI controller svn path=/trunk/; revision=15905
This commit is contained in:
parent
2e0ff75066
commit
819d60094a
10 changed files with 1226 additions and 378 deletions
28
reactos/drivers/usb/cromwell/uhci/close.c
Normal file
28
reactos/drivers/usb/cromwell/uhci/close.c
Normal file
|
@ -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;
|
||||
}
|
41
reactos/drivers/usb/cromwell/uhci/create.c
Normal file
41
reactos/drivers/usb/cromwell/uhci/create.c
Normal file
|
@ -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;
|
||||
}
|
422
reactos/drivers/usb/cromwell/uhci/fdo.c
Normal file
422
reactos/drivers/usb/cromwell/uhci/fdo.c
Normal file
|
@ -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.Type3InputBuffer;
|
||||
*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)->PhysicalDeviceObject,
|
||||
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)->HcdInterfaceName;
|
||||
|
||||
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;
|
||||
}
|
166
reactos/drivers/usb/cromwell/uhci/misc.c
Normal file
166
reactos/drivers/usb/cromwell/uhci/misc.c
Normal file
|
@ -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)->NextDeviceObject;
|
||||
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)->NextDeviceObject;
|
||||
|
||||
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;
|
||||
}
|
196
reactos/drivers/usb/cromwell/uhci/pdo.c
Normal file
196
reactos/drivers/usb/cromwell/uhci/pdo.c
Normal file
|
@ -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->DeviceExtension;
|
||||
|
||||
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;
|
||||
}
|
||||
|
297
reactos/drivers/usb/cromwell/uhci/uhci.c
Normal file
297
reactos/drivers/usb/cromwell/uhci/uhci.c
Normal file
|
@ -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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
VOID STDCALL
|
||||
DriverUnload(PDRIVER_OBJECT DriverObject)
|
||||
{
|
||||
POHCI_DEVICE_EXTENSION DeviceExtension;
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
struct pci_dev *dev;
|
||||
|
||||
DeviceObject = DriverObject->DeviceObject;
|
||||
DeviceExtension = (POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
dev = DeviceExtension->pdev;
|
||||
|
||||
DPRINT1("UHCI: DriverUnload()\n");
|
||||
|
||||
// Exit usb device
|
||||
usb_exit();
|
||||
|
||||
// Remove device (ohci_pci_driver.remove)
|
||||
uhci_pci_driver.remove(dev);
|
||||
|
||||
ExFreePool(dev->slot_name);
|
||||
ExFreePool(dev);
|
||||
|
||||
// Perform some cleanup
|
||||
uhci_hcd_cleanup();
|
||||
}
|
||||
|
||||
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
|
||||
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_DEVICE_CONTROL] = DispatchDeviceControl;
|
||||
DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
|
||||
DriverObject->MajorFunction[IRP_MJ_POWER] = DispatchPower;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
LIBRARY uhci.sys
|
||||
EXPORTS
|
69
reactos/drivers/usb/cromwell/uhci/uhci.h
Normal file
69
reactos/drivers/usb/cromwell/uhci/uhci.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
#include <ddk/ntddk.h>
|
||||
#include <ddk/usbdi.h>
|
||||
#include <ddk/usbiodef.h>
|
||||
#include <initguid.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 "../core/hcd.h"
|
||||
|
||||
#include "../host/ohci_main.h"
|
||||
|
||||
#define USB_UHCI_TAG TAG('u','s','b','u')
|
||||
|
||||
/* create.c */
|
||||
NTSTATUS STDCALL
|
||||
UhciCreate(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
/* close.c */
|
||||
NTSTATUS STDCALL
|
||||
UhciClose(
|
||||
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);
|
|
@ -1,5 +1,4 @@
|
|||
<module name="uhci" type="kernelmodedriver" installbase="system32/drivers" installname="uhci.sys" warnings="true">
|
||||
<importlibrary definition="uhci.def" />
|
||||
<module name="uhci" type="kernelmodedriver" installbase="system32/drivers" installname="usbuhci.sys" warnings="true">
|
||||
<define name="__USE_W32API" />
|
||||
<define name="DEBUG_MODE" />
|
||||
<include base="ntoskrnl">include</include>
|
||||
|
@ -8,7 +7,12 @@
|
|||
<library>ntoskrnl</library>
|
||||
<library>hal</library>
|
||||
<library>usbcore</library>
|
||||
<file>close.c</file>
|
||||
<file>create.c</file>
|
||||
<file>fdo.c</file>
|
||||
<file>misc.c</file>
|
||||
<file>pdo.c</file>
|
||||
<file>uhci.c</file>
|
||||
<file>uhci-hcd.c</file>
|
||||
<file>uhci_main.c</file>
|
||||
<file>uhci.rc</file>
|
||||
</module>
|
||||
|
|
|
@ -1,373 +0,0 @@
|
|||
/*
|
||||
ReactOS specific functions for UHCI module
|
||||
by Aleksey Bragin (aleksey@reactos.com)
|
||||
Some parts of code are inspired (or even just copied) from ReactOS Videoport driver
|
||||
*/
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
#define DEBUG
|
||||
#include <debug.h>
|
||||
|
||||
// config and include core/hcd.h, for hc_device struct
|
||||
#include "../usb_wrapper.h"
|
||||
#include "../core/hcd.h"
|
||||
|
||||
#include "../host/ohci_main.h"
|
||||
|
||||
// declare basic init funcs
|
||||
void init_wrapper(struct pci_dev *probe_dev);
|
||||
int uhci_hcd_init(void);
|
||||
void uhci_hcd_cleanup(void);
|
||||
int STDCALL usb_init(void);
|
||||
void STDCALL usb_exit(void);
|
||||
extern struct pci_driver uhci_pci_driver;
|
||||
extern struct pci_device_id uhci_pci_ids[];
|
||||
|
||||
|
||||
// This should be removed, but for testing purposes it's here
|
||||
//struct pci_dev *dev;
|
||||
//struct pci_device_id *dev_id;
|
||||
|
||||
#define USB_UHCI_TAG TAG('u','s','b','u')
|
||||
|
||||
NTSTATUS STDCALL
|
||||
AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT pdo)
|
||||
{
|
||||
PDEVICE_OBJECT fdo;
|
||||
NTSTATUS Status;
|
||||
WCHAR DeviceBuffer[20];
|
||||
UNICODE_STRING DeviceName;
|
||||
WCHAR LinkDeviceBuffer[20];
|
||||
UNICODE_STRING LinkDeviceName;
|
||||
POHCI_DRIVER_EXTENSION DriverExtension;
|
||||
POHCI_DEVICE_EXTENSION DeviceExtension;
|
||||
ULONG Size, DeviceNumber;
|
||||
|
||||
DPRINT1("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))
|
||||
{
|
||||
DPRINT1("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),
|
||||
/* + DriverExtension->InitializationData.HwDeviceExtensionSize*/
|
||||
&DeviceName,
|
||||
FILE_DEVICE_CONTROLLER,
|
||||
0,
|
||||
FALSE,
|
||||
&fdo);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("IoCreateDevice call failed with status 0x%08x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
// zerofill device extension
|
||||
DeviceExtension = (POHCI_DEVICE_EXTENSION)pdo->DeviceExtension;
|
||||
RtlZeroMemory(DeviceExtension, sizeof(OHCI_DEVICE_EXTENSION));
|
||||
DeviceExtension->NextDeviceObject = IoAttachDeviceToDeviceStack(fdo, pdo);
|
||||
|
||||
fdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||
|
||||
// Initialize device extension
|
||||
DeviceExtension->DeviceNumber = DeviceNumber;
|
||||
DeviceExtension->PhysicalDeviceObject = pdo;
|
||||
DeviceExtension->FunctionalDeviceObject = fdo;
|
||||
DeviceExtension->DriverExtension = DriverExtension;
|
||||
|
||||
swprintf(LinkDeviceBuffer, L"\\??\\HCD%lu", DeviceNumber);
|
||||
RtlInitUnicodeString(&LinkDeviceName, LinkDeviceBuffer);
|
||||
Status = IoCreateSymbolicLink(&LinkDeviceName, &DeviceName);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("IoCreateSymbolicLink call failed with status 0x%08x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Get bus number from the upper level bus driver. */
|
||||
Size = sizeof(ULONG);
|
||||
/* Status = IoGetDeviceProperty(
|
||||
pdo,
|
||||
DevicePropertyBusNumber,
|
||||
Size,
|
||||
&DeviceExtension->SystemIoBusNumber,
|
||||
&Size);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Couldn't get an information from bus driver. Panic!!!\n");
|
||||
return Status;
|
||||
}
|
||||
*/
|
||||
DPRINT1("Done AddDevice\n");
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
VOID STDCALL
|
||||
DriverUnload(PDRIVER_OBJECT DriverObject)
|
||||
{
|
||||
POHCI_DEVICE_EXTENSION DeviceExtension;
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
struct pci_dev *dev;
|
||||
|
||||
DeviceObject = DriverObject->DeviceObject;
|
||||
DeviceExtension = (POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
dev = DeviceExtension->pdev;
|
||||
|
||||
DPRINT1("DriverUnload()\n");
|
||||
|
||||
// Exit usb device
|
||||
usb_exit();
|
||||
|
||||
// Remove device (ohci_pci_driver.remove)
|
||||
uhci_pci_driver.remove(dev);
|
||||
|
||||
ExFreePool(dev->slot_name);
|
||||
ExFreePool(dev);
|
||||
|
||||
// Perform some cleanup
|
||||
uhci_hcd_cleanup();
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
InitLinuxWrapper(PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
POHCI_DEVICE_EXTENSION DeviceExtension = (POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
struct pci_dev *dev;
|
||||
|
||||
// Fill generic linux structs
|
||||
dev = ExAllocatePoolWithTag(PagedPool, sizeof(struct pci_dev), USB_UHCI_TAG);
|
||||
|
||||
/* dev->data = (struct usb_hcd hcd) used in uhci-hub.c called from uhci-hcd.c */
|
||||
DeviceExtension->pdev = dev;
|
||||
|
||||
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();
|
||||
//FIXME: Check status returned value
|
||||
|
||||
// Init core usb
|
||||
usb_init();
|
||||
|
||||
// Probe device with real id now
|
||||
uhci_pci_driver.probe(dev, uhci_pci_ids);
|
||||
|
||||
DPRINT1("InitLinuxWrapper() done\n");
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
OHCD_PnPStartDevice(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);*/
|
||||
DPRINT1("AllocRess->Count: %d, PartResList.Count: %d\n",
|
||||
AllocatedResources->Count, FullList->PartialResourceList.Count);
|
||||
|
||||
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;
|
||||
|
||||
DPRINT1("Interrupt level: 0x%x Interrupt Vector: 0x%x\n",
|
||||
DeviceExtension->InterruptLevel,
|
||||
DeviceExtension->InterruptVector);
|
||||
}
|
||||
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;
|
||||
|
||||
DPRINT1("I/O resource: start=0x%x, length=0x%x\n",
|
||||
DeviceExtension->BaseAddress.u.LowPart, DeviceExtension->BaseAddrLength);
|
||||
}
|
||||
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;
|
||||
|
||||
DPRINT1("Memory resource: start=0x%x, length=0x%x\n",
|
||||
DeviceExtension->BaseAddress.u.LowPart, DeviceExtension->BaseAddrLength);
|
||||
}
|
||||
else
|
||||
DPRINT1("Get resource type: %d, Generic start=0x%x Generic length=0x%x\n",
|
||||
Descriptor->Type, Descriptor->u.Generic.Start.u.LowPart, Descriptor->u.Generic.Length);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Init wrapper with this object
|
||||
*/
|
||||
return InitLinuxWrapper(DeviceObject);
|
||||
}
|
||||
|
||||
// Dispatch PNP
|
||||
NTSTATUS STDCALL
|
||||
DispatchPnp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION IrpSp;
|
||||
NTSTATUS Status;
|
||||
|
||||
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
switch (IrpSp->MinorFunction)
|
||||
{
|
||||
case IRP_MN_START_DEVICE:
|
||||
// Status = ForwardIrpAndWait(DeviceObject, Irp);
|
||||
// if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
|
||||
Status = OHCD_PnPStartDevice(DeviceObject, Irp);
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
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;
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
IoDeleteDevice(DeviceObject); // just delete device for now
|
||||
break;
|
||||
|
||||
case IRP_MN_QUERY_STOP_DEVICE:
|
||||
case IRP_MN_CANCEL_STOP_DEVICE:
|
||||
Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
break;
|
||||
|
||||
default:
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
DispatchPower(PDEVICE_OBJECT fido, PIRP Irp)
|
||||
{
|
||||
DbgPrint("IRP_MJ_POWER dispatch\n");
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Standard DriverEntry method.
|
||||
*/
|
||||
NTSTATUS STDCALL
|
||||
DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegPath)
|
||||
{
|
||||
|
||||
DPRINT1("******************** Cromwell UHCI ********************\n");
|
||||
|
||||
DriverObject->DriverUnload = DriverUnload;
|
||||
DriverObject->DriverExtension->AddDevice = AddDevice;
|
||||
|
||||
DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
|
||||
DriverObject->MajorFunction[IRP_MJ_POWER] = DispatchPower;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
Loading…
Reference in a new issue