mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 01:15:43 +00:00
[usb/usbehci]
- Remove WorkItem code as its not needed. UsbHub driver polls the hubs for device connects. - Register USB Host Controller Device Interface during AddDevice.- Implement more URB's USB_DEVICE_DESCRIPTOR_TYPE, USB_CONFIGURATION_DESCRIPTOR_TYPE, URB_FUNCTION_SELECT_CONFIGURATION, URB_FUNCTION_CLASS_DEVICE/USB_DEVICE_CLASS_HUB. - Implement returning generic UsbdDeviceHandle in URB struct. svn path=/trunk/; revision=45554
This commit is contained in:
parent
a884062bc9
commit
3c1ec16123
3 changed files with 360 additions and 157 deletions
|
@ -10,15 +10,18 @@
|
||||||
/* INCLUDES *******************************************************************/
|
/* INCLUDES *******************************************************************/
|
||||||
#include "usbehci.h"
|
#include "usbehci.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
//#include "ntstrsafe.h"
|
//#include "ntstrsafe.h"
|
||||||
|
|
||||||
VOID NTAPI
|
VOID NTAPI
|
||||||
EhciDefferedRoutine(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
|
EhciDefferedRoutine(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
|
||||||
{
|
{
|
||||||
PFDO_DEVICE_EXTENSION FdoDeviceExtension;
|
PFDO_DEVICE_EXTENSION FdoDeviceExtension;
|
||||||
|
PPDO_DEVICE_EXTENSION PdoDeviceExtension;
|
||||||
ULONG CStatus;
|
ULONG CStatus;
|
||||||
|
|
||||||
FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) DeferredContext;
|
FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) DeferredContext;
|
||||||
|
PdoDeviceExtension = (PPDO_DEVICE_EXTENSION) FdoDeviceExtension->Pdo->DeviceExtension;
|
||||||
|
|
||||||
CStatus = (ULONG) SystemArgument2;
|
CStatus = (ULONG) SystemArgument2;
|
||||||
|
|
||||||
|
@ -39,8 +42,6 @@ EhciDefferedRoutine(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVO
|
||||||
/* Check for port change on this port */
|
/* Check for port change on this port */
|
||||||
if (tmp & 0x02)
|
if (tmp & 0x02)
|
||||||
{
|
{
|
||||||
PWORKITEM_DATA WorkItemData = NULL;
|
|
||||||
|
|
||||||
/* Connect or Disconnect? */
|
/* Connect or Disconnect? */
|
||||||
if (tmp & 0x01)
|
if (tmp & 0x01)
|
||||||
{
|
{
|
||||||
|
@ -81,31 +82,9 @@ EhciDefferedRoutine(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVO
|
||||||
tmp = READ_REGISTER_ULONG((PULONG)((Base + EHCI_PORTSC) + (4 * i)));
|
tmp = READ_REGISTER_ULONG((PULONG)((Base + EHCI_PORTSC) + (4 * i)));
|
||||||
|
|
||||||
DPRINT("port tmp %x\n", tmp);
|
DPRINT("port tmp %x\n", tmp);
|
||||||
GetDeviceDescriptor(FdoDeviceExtension, 0);
|
GetDeviceDescriptor(FdoDeviceExtension, 0, 0, FALSE);
|
||||||
FdoDeviceExtension->ChildDeviceCount++;
|
PdoDeviceExtension->ChildDeviceCount++;
|
||||||
CompletePendingRequest(FdoDeviceExtension);
|
//CompletePendingURBRequest(PdoDeviceExtension);
|
||||||
|
|
||||||
WorkItemData = ExAllocatePool(NonPagedPool, sizeof(WORKITEM_DATA));
|
|
||||||
if (!WorkItemData)
|
|
||||||
{
|
|
||||||
DPRINT1("No memory\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
WorkItemData->IoWorkItem = IoAllocateWorkItem(FdoDeviceExtension->Pdo);
|
|
||||||
if (!WorkItemData->IoWorkItem)
|
|
||||||
{
|
|
||||||
DPRINT1("WorkItem allocation failed!\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
WorkItemData->FdoDeviceExtension = FdoDeviceExtension;
|
|
||||||
|
|
||||||
IoQueueWorkItem(WorkItemData->IoWorkItem,
|
|
||||||
(PIO_WORKITEM_ROUTINE)DeviceArrivalWorkItem,
|
|
||||||
DelayedWorkQueue,
|
|
||||||
WorkItemData);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -116,7 +95,6 @@ EhciDefferedRoutine(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVO
|
||||||
tmp |= 0x02;
|
tmp |= 0x02;
|
||||||
WRITE_REGISTER_ULONG((PULONG) ((Base + EHCI_PORTSC) + (4 * i)), tmp);
|
WRITE_REGISTER_ULONG((PULONG) ((Base + EHCI_PORTSC) + (4 * i)), tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -180,7 +158,6 @@ InterruptService(PKINTERRUPT Interrupt, PVOID ServiceContext)
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
ResetPort(PDEVICE_OBJECT DeviceObject)
|
ResetPort(PDEVICE_OBJECT DeviceObject)
|
||||||
{
|
{
|
||||||
|
|
||||||
/*FIXME: Implement me */
|
/*FIXME: Implement me */
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -310,8 +287,6 @@ StartEhci(PDEVICE_OBJECT DeviceObject)
|
||||||
EHCI_USBINTR_INTE | EHCI_USBINTR_ERR | EHCI_USBINTR_ASYNC | EHCI_USBINTR_HSERR
|
EHCI_USBINTR_INTE | EHCI_USBINTR_ERR | EHCI_USBINTR_ASYNC | EHCI_USBINTR_HSERR
|
||||||
| EHCI_USBINTR_FLROVR | EHCI_USBINTR_PC);
|
| EHCI_USBINTR_FLROVR | EHCI_USBINTR_PC);
|
||||||
|
|
||||||
//UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp;
|
|
||||||
|
|
||||||
UsbCmd->Run = 1;
|
UsbCmd->Run = 1;
|
||||||
WRITE_REGISTER_ULONG((PULONG)(base + EHCI_USBCMD), tmp);
|
WRITE_REGISTER_ULONG((PULONG)(base + EHCI_USBCMD), tmp);
|
||||||
|
|
||||||
|
@ -351,14 +326,12 @@ GetCapabilities(PFDO_DEVICE_EXTENSION DeviceExtension, ULONG Base)
|
||||||
PCap->HCSParamsLong = READ_REGISTER_ULONG((PULONG)(Base + 4));
|
PCap->HCSParamsLong = READ_REGISTER_ULONG((PULONG)(Base + 4));
|
||||||
PCap->HCCParams = READ_REGISTER_ULONG((PULONG)(Base + 8));
|
PCap->HCCParams = READ_REGISTER_ULONG((PULONG)(Base + 8));
|
||||||
|
|
||||||
|
|
||||||
DPRINT("Length %d\n", PCap->Length);
|
DPRINT("Length %d\n", PCap->Length);
|
||||||
DPRINT("Reserved %d\n", PCap->Reserved);
|
DPRINT("Reserved %d\n", PCap->Reserved);
|
||||||
DPRINT("HCIVersion %x\n", PCap->HCIVersion);
|
DPRINT("HCIVersion %x\n", PCap->HCIVersion);
|
||||||
DPRINT("HCSParams %x\n", PCap->HCSParamsLong);
|
DPRINT("HCSParams %x\n", PCap->HCSParamsLong);
|
||||||
DPRINT("HCCParams %x\n", PCap->HCCParams);
|
DPRINT("HCCParams %x\n", PCap->HCCParams);
|
||||||
|
|
||||||
|
|
||||||
if (PCap->HCCParams & 0x02)
|
if (PCap->HCCParams & 0x02)
|
||||||
DPRINT1("Frame list size is configurable\n");
|
DPRINT1("Frame list size is configurable\n");
|
||||||
|
|
||||||
|
@ -561,14 +534,16 @@ FdoQueryBusRelations(
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG UsbDeviceNumber = 0;
|
ULONG UsbDeviceNumber = 0;
|
||||||
WCHAR CharDeviceName[64];
|
WCHAR CharDeviceName[64];
|
||||||
|
|
||||||
UNICODE_STRING DeviceName;
|
UNICODE_STRING DeviceName;
|
||||||
|
|
||||||
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
/* Create the PDO */
|
|
||||||
|
/* Create the PDO with the next available number */
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
/* FIXME: Use safe string sprintf*/
|
/* FIXME: Use safe string */
|
||||||
/* RtlStringCchPrintfW(CharDeviceName, 64, L"USBFDO-%d", UsbDeviceNumber); */
|
/* RtlStringCchPrintfW(CharDeviceName, 64, L"USBPDO-%d", UsbDeviceNumber); */
|
||||||
swprintf(CharDeviceName, L"\\Device\\USBPDO-%d", UsbDeviceNumber);
|
swprintf(CharDeviceName, L"\\Device\\USBPDO-%d", UsbDeviceNumber);
|
||||||
RtlInitUnicodeString(&DeviceName, CharDeviceName);
|
RtlInitUnicodeString(&DeviceName, CharDeviceName);
|
||||||
DPRINT("DeviceName %wZ\n", &DeviceName);
|
DPRINT("DeviceName %wZ\n", &DeviceName);
|
||||||
|
@ -604,20 +579,17 @@ FdoQueryBusRelations(
|
||||||
PdoDeviceExtension->Common.IsFdo = FALSE;
|
PdoDeviceExtension->Common.IsFdo = FALSE;
|
||||||
|
|
||||||
PdoDeviceExtension->ControllerFdo = DeviceObject;
|
PdoDeviceExtension->ControllerFdo = DeviceObject;
|
||||||
|
PdoDeviceExtension->DeviceObject = Pdo;
|
||||||
|
|
||||||
|
InitializeListHead(&PdoDeviceExtension->IrpQueue);
|
||||||
|
KeInitializeSpinLock(&PdoDeviceExtension->IrpQueueLock);
|
||||||
|
|
||||||
Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||||
|
|
||||||
DeviceExtension->Pdo = Pdo;
|
DeviceExtension->Pdo = Pdo;
|
||||||
|
|
||||||
/*swprintf(CharSymLinkName, L"\\Device\\HCD%d", UsbDeviceNumber);
|
|
||||||
RtlInitUnicodeString(&SymLinkName, CharSymLinkName);
|
|
||||||
Status = IoCreateSymbolicLink(&SymLinkName, &DeviceName);
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("Warning: Unable to create symbolic link for ehci usb device!\n");
|
|
||||||
}*/
|
|
||||||
|
|
||||||
DeviceRelations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, sizeof(DEVICE_RELATIONS));
|
DeviceRelations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, sizeof(DEVICE_RELATIONS));
|
||||||
|
|
||||||
if (!DeviceRelations)
|
if (!DeviceRelations)
|
||||||
{
|
{
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
@ -646,7 +618,7 @@ FdoDispatchPnp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
|
||||||
{
|
{
|
||||||
case IRP_MN_START_DEVICE:
|
case IRP_MN_START_DEVICE:
|
||||||
{
|
{
|
||||||
DPRINT("START_DEVICE\n");
|
DPRINT1("START_DEVICE\n");
|
||||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
Status = ForwardAndWait(DeviceObject, Irp);
|
Status = ForwardAndWait(DeviceObject, Irp);
|
||||||
|
|
||||||
|
@ -657,7 +629,7 @@ FdoDispatchPnp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
|
||||||
}
|
}
|
||||||
case IRP_MN_QUERY_DEVICE_RELATIONS:
|
case IRP_MN_QUERY_DEVICE_RELATIONS:
|
||||||
{
|
{
|
||||||
DPRINT("IRP_MN_QUERY_DEVICE_RELATIONS\n");
|
DPRINT1("IRP_MN_QUERY_DEVICE_RELATIONS\n");
|
||||||
switch(Stack->Parameters.QueryDeviceRelations.Type)
|
switch(Stack->Parameters.QueryDeviceRelations.Type)
|
||||||
{
|
{
|
||||||
case BusRelations:
|
case BusRelations:
|
||||||
|
@ -687,6 +659,14 @@ FdoDispatchPnp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
|
||||||
{
|
{
|
||||||
DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
|
DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
|
||||||
}
|
}
|
||||||
|
case IRP_MN_QUERY_INTERFACE:
|
||||||
|
{
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
Information = 0;
|
||||||
|
Status = ForwardIrpAndForget(DeviceObject, Irp);
|
||||||
|
return Status;
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
DPRINT1("IRP_MJ_PNP / Unhandled minor function 0x%lx\n", Stack->MinorFunction);
|
DPRINT1("IRP_MJ_PNP / Unhandled minor function 0x%lx\n", Stack->MinorFunction);
|
||||||
|
@ -710,21 +690,22 @@ AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT Pdo)
|
||||||
WCHAR CharSymLinkName[64];
|
WCHAR CharSymLinkName[64];
|
||||||
UNICODE_STRING DeviceName;
|
UNICODE_STRING DeviceName;
|
||||||
UNICODE_STRING SymLinkName;
|
UNICODE_STRING SymLinkName;
|
||||||
|
UNICODE_STRING InterfaceSymLinkName;
|
||||||
ULONG BytesRead;
|
ULONG BytesRead;
|
||||||
PCI_COMMON_CONFIG PciConfig;
|
PCI_COMMON_CONFIG PciConfig;
|
||||||
|
|
||||||
PFDO_DEVICE_EXTENSION FdoDeviceExtension;
|
PFDO_DEVICE_EXTENSION FdoDeviceExtension;
|
||||||
|
|
||||||
DPRINT1("Ehci AddDevice\n");
|
DPRINT("Ehci AddDevice\n");
|
||||||
|
|
||||||
/* Create the FDO */
|
/* Create the FDO with next available number */
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
/* FIXME: Use safe string sprintf*/
|
/* FIXME: Use safe string sprintf*/
|
||||||
/* RtlStringCchPrintfW(CharDeviceName, 64, L"USBFDO-%d", UsbDeviceNumber); */
|
/* RtlStringCchPrintfW(CharDeviceName, 64, L"USBFDO-%d", UsbDeviceNumber); */
|
||||||
swprintf(CharDeviceName, L"\\Device\\USBFDO-%d", UsbDeviceNumber);
|
swprintf(CharDeviceName, L"\\Device\\USBFDO-%d", UsbDeviceNumber);
|
||||||
RtlInitUnicodeString(&DeviceName, CharDeviceName);
|
RtlInitUnicodeString(&DeviceName, CharDeviceName);
|
||||||
DPRINT1("DeviceName %wZ\n", &DeviceName);
|
DPRINT("DeviceName %wZ\n", &DeviceName);
|
||||||
|
|
||||||
Status = IoCreateDevice(DriverObject,
|
Status = IoCreateDevice(DriverObject,
|
||||||
sizeof(FDO_DEVICE_EXTENSION),
|
sizeof(FDO_DEVICE_EXTENSION),
|
||||||
|
@ -758,21 +739,17 @@ AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT Pdo)
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Warning: Unable to create symbolic link for ehci usb device!\n");
|
DPRINT1("Warning: Unable to create symbolic link for ehci host controller!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("Attaching created device %x to %x\n", Fdo, Pdo);
|
|
||||||
|
|
||||||
FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) Fdo->DeviceExtension;
|
FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) Fdo->DeviceExtension;
|
||||||
RtlZeroMemory(FdoDeviceExtension, sizeof(PFDO_DEVICE_EXTENSION));
|
RtlZeroMemory(FdoDeviceExtension, sizeof(PFDO_DEVICE_EXTENSION));
|
||||||
|
|
||||||
InitializeListHead(&FdoDeviceExtension->IrpQueue);
|
|
||||||
KeInitializeSpinLock(&FdoDeviceExtension->IrpQueueLock);
|
|
||||||
|
|
||||||
FdoDeviceExtension->Common.IsFdo = TRUE;
|
FdoDeviceExtension->Common.IsFdo = TRUE;
|
||||||
FdoDeviceExtension->DeviceObject = Fdo;
|
FdoDeviceExtension->DeviceObject = Fdo;
|
||||||
|
|
||||||
FdoDeviceExtension->LowerDevice = IoAttachDeviceToDeviceStack(Fdo, Pdo);
|
FdoDeviceExtension->LowerDevice = IoAttachDeviceToDeviceStack(Fdo, Pdo);
|
||||||
|
|
||||||
if (FdoDeviceExtension->LowerDevice == NULL)
|
if (FdoDeviceExtension->LowerDevice == NULL)
|
||||||
{
|
{
|
||||||
DPRINT1("UsbEhci: Failed to attach to device stack!\n");
|
DPRINT1("UsbEhci: Failed to attach to device stack!\n");
|
||||||
|
@ -782,10 +759,10 @@ AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT Pdo)
|
||||||
return STATUS_NO_SUCH_DEVICE;
|
return STATUS_NO_SUCH_DEVICE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Fdo->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;
|
Fdo->Flags |= DO_BUFFERED_IO;// | DO_POWER_PAGABLE;
|
||||||
|
|
||||||
DPRINT("Attached %x!\n", FdoDeviceExtension->LowerDevice);
|
|
||||||
ASSERT(FdoDeviceExtension->LowerDevice == Pdo);
|
ASSERT(FdoDeviceExtension->LowerDevice == Pdo);
|
||||||
|
|
||||||
Status = GetBusInterface(FdoDeviceExtension->LowerDevice, &FdoDeviceExtension->BusInterface);
|
Status = GetBusInterface(FdoDeviceExtension->LowerDevice, &FdoDeviceExtension->BusInterface);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -797,8 +774,6 @@ AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT Pdo)
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("Context %x\n", FdoDeviceExtension->BusInterface.Context);
|
|
||||||
|
|
||||||
BytesRead = (*FdoDeviceExtension->BusInterface.GetBusData)(
|
BytesRead = (*FdoDeviceExtension->BusInterface.GetBusData)(
|
||||||
FdoDeviceExtension->BusInterface.Context,
|
FdoDeviceExtension->BusInterface.Context,
|
||||||
PCI_WHICHSPACE_CONFIG,
|
PCI_WHICHSPACE_CONFIG,
|
||||||
|
@ -827,15 +802,24 @@ AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT Pdo)
|
||||||
DPRINT("PCI_ENABLE_BUS_MASTER\n");
|
DPRINT("PCI_ENABLE_BUS_MASTER\n");
|
||||||
|
|
||||||
DPRINT("BaseAddress[0] %x\n", PciConfig.u.type0.BaseAddresses[0]);
|
DPRINT("BaseAddress[0] %x\n", PciConfig.u.type0.BaseAddresses[0]);
|
||||||
DPRINT("Vendor %x\n", PciConfig.VendorID);
|
DPRINT1("Vendor %x\n", PciConfig.VendorID);
|
||||||
DPRINT("Device %x\n", PciConfig.DeviceID);
|
DPRINT1("Device %x\n", PciConfig.DeviceID);
|
||||||
|
|
||||||
FdoDeviceExtension->VendorId = PciConfig.VendorID;
|
FdoDeviceExtension->VendorId = PciConfig.VendorID;
|
||||||
FdoDeviceExtension->DeviceId = PciConfig.DeviceID;
|
FdoDeviceExtension->DeviceId = PciConfig.DeviceID;
|
||||||
|
|
||||||
DPRINT("FdoDeviceExtension->NextLowerDevice %x\n", FdoDeviceExtension->LowerDevice);
|
|
||||||
FdoDeviceExtension->DeviceState = DEVICEINTIALIZED;
|
FdoDeviceExtension->DeviceState = DEVICEINTIALIZED;
|
||||||
|
|
||||||
|
Status = IoRegisterDeviceInterface(Pdo, &GUID_DEVINTERFACE_USB_HOST_CONTROLLER, NULL, &InterfaceSymLinkName);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Unable to register device interface!\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Status = IoSetDeviceInterfaceState(&InterfaceSymLinkName, TRUE);
|
||||||
|
DPRINT1("SetInterfaceState %x\n", Status);
|
||||||
|
}
|
||||||
Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
|
|
@ -10,28 +10,26 @@
|
||||||
#include "usbehci.h"
|
#include "usbehci.h"
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
RequestCancel (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
RequestURBCancel (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
{
|
{
|
||||||
PPDO_DEVICE_EXTENSION PdoDeviceExtension;
|
PPDO_DEVICE_EXTENSION PdoDeviceExtension;
|
||||||
PFDO_DEVICE_EXTENSION FdoDeviceExtension;
|
|
||||||
|
|
||||||
PdoDeviceExtension = (PPDO_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
|
PdoDeviceExtension = (PPDO_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
|
||||||
FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) PdoDeviceExtension->ControllerFdo->DeviceExtension;
|
|
||||||
|
|
||||||
KIRQL OldIrql = Irp->CancelIrql;
|
KIRQL OldIrql = Irp->CancelIrql;
|
||||||
IoReleaseCancelSpinLock(DISPATCH_LEVEL);
|
IoReleaseCancelSpinLock(DISPATCH_LEVEL);
|
||||||
|
|
||||||
KeAcquireSpinLockAtDpcLevel(&FdoDeviceExtension->IrpQueueLock);
|
KeAcquireSpinLockAtDpcLevel(&PdoDeviceExtension->IrpQueueLock);
|
||||||
RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
|
RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
|
||||||
|
|
||||||
KeReleaseSpinLock(&FdoDeviceExtension->IrpQueueLock, OldIrql);
|
KeReleaseSpinLock(&PdoDeviceExtension->IrpQueueLock, OldIrql);
|
||||||
|
|
||||||
Irp->IoStatus.Status = STATUS_CANCELLED;
|
Irp->IoStatus.Status = STATUS_CANCELLED;
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
QueueRequest(PFDO_DEVICE_EXTENSION DeviceExtension, PIRP Irp)
|
QueueURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension, PIRP Irp)
|
||||||
{
|
{
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
|
|
||||||
|
@ -51,10 +49,13 @@ QueueRequest(PFDO_DEVICE_EXTENSION DeviceExtension, PIRP Irp)
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
CompletePendingRequest(PFDO_DEVICE_EXTENSION DeviceExtension)
|
CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY NextIrp = NULL;
|
PLIST_ENTRY NextIrp = NULL;
|
||||||
|
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
||||||
|
ULONG_PTR Information = 0;
|
||||||
PIO_STACK_LOCATION Stack;
|
PIO_STACK_LOCATION Stack;
|
||||||
|
PUSB_DEVICE UsbDevice = NULL;
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
PIRP Irp = NULL;
|
PIRP Irp = NULL;
|
||||||
URB *Urb;
|
URB *Urb;
|
||||||
|
@ -75,83 +76,275 @@ CompletePendingRequest(PFDO_DEVICE_EXTENSION DeviceExtension)
|
||||||
Urb = (PURB) Stack->Parameters.Others.Argument1;
|
Urb = (PURB) Stack->Parameters.Others.Argument1;
|
||||||
ASSERT(Urb);
|
ASSERT(Urb);
|
||||||
|
|
||||||
/* FIXME: Fill in information for Argument1/URB */
|
Information = 0;
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
DPRINT("TransferBuffer %x\n", Urb->UrbControlDescriptorRequest.TransferBuffer);
|
DPRINT1("TransferBuffer %x\n", Urb->UrbControlDescriptorRequest.TransferBuffer);
|
||||||
DPRINT("TransferBufferLength %x\n", Urb->UrbControlDescriptorRequest.TransferBufferLength);
|
DPRINT1("TransferBufferLength %x\n", Urb->UrbControlDescriptorRequest.TransferBufferLength);
|
||||||
DPRINT("Index %x\n", Urb->UrbControlDescriptorRequest.Index);
|
|
||||||
DPRINT("DescriptorType %x\n", Urb->UrbControlDescriptorRequest.DescriptorType);
|
|
||||||
DPRINT("LanguageId %x\n", Urb->UrbControlDescriptorRequest.LanguageId);
|
|
||||||
|
|
||||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
UsbDevice = Urb->UrbHeader.UsbdDeviceHandle;
|
||||||
Irp->IoStatus.Information = 0;
|
/* UsbdDeviceHandle of 0 is root hub */
|
||||||
|
if (UsbDevice == NULL)
|
||||||
|
UsbDevice = DeviceExtension->UsbDevices[0];
|
||||||
|
|
||||||
|
switch (Urb->UrbHeader.Function)
|
||||||
|
{
|
||||||
|
case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
|
||||||
|
{
|
||||||
|
/* We should not get here yet! */
|
||||||
|
ASSERT(FALSE);
|
||||||
|
}
|
||||||
|
case URB_FUNCTION_GET_STATUS_FROM_DEVICE:
|
||||||
|
{
|
||||||
|
DPRINT1("Get Status from Device\n");
|
||||||
|
}
|
||||||
|
case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
|
||||||
|
{
|
||||||
|
Urb->UrbHeader.Function = 0x08;
|
||||||
|
Urb->UrbHeader.UsbdFlags = 0;
|
||||||
|
Urb->UrbHeader.UsbdDeviceHandle = UsbDevice;
|
||||||
|
|
||||||
|
switch(Urb->UrbControlDescriptorRequest.DescriptorType)
|
||||||
|
{
|
||||||
|
case USB_DEVICE_DESCRIPTOR_TYPE:
|
||||||
|
{
|
||||||
|
DPRINT1("USB DEVICE DESC\n");
|
||||||
|
if (Urb->UrbControlDescriptorRequest.TransferBufferLength >= sizeof(USB_DEVICE_DESCRIPTOR))
|
||||||
|
{
|
||||||
|
Urb->UrbControlDescriptorRequest.TransferBufferLength = sizeof(USB_DEVICE_DESCRIPTOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer,
|
||||||
|
&UsbDevice->DeviceDescriptor,
|
||||||
|
Urb->UrbControlDescriptorRequest.TransferBufferLength);
|
||||||
|
|
||||||
|
Urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case USB_CONFIGURATION_DESCRIPTOR_TYPE:
|
||||||
|
{
|
||||||
|
DPRINT1("USB CONFIG DESC\n");
|
||||||
|
ULONG FullDescriptorLength = sizeof(USB_CONFIGURATION_DESCRIPTOR) +
|
||||||
|
sizeof(USB_INTERFACE_DESCRIPTOR) +
|
||||||
|
sizeof(USB_ENDPOINT_DESCRIPTOR);
|
||||||
|
|
||||||
|
if (Urb->UrbControlDescriptorRequest.TransferBufferLength >= FullDescriptorLength)
|
||||||
|
{
|
||||||
|
Urb->UrbControlDescriptorRequest.TransferBufferLength = FullDescriptorLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer,
|
||||||
|
&UsbDevice->ConfigurationDescriptor,
|
||||||
|
Urb->UrbControlDescriptorRequest.TransferBufferLength);
|
||||||
|
|
||||||
|
Urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case USB_STRING_DESCRIPTOR_TYPE:
|
||||||
|
{
|
||||||
|
DPRINT1("Usb String Descriptor not implemented\n");
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
DPRINT1("Descriptor Type %x not supported!\n", Urb->UrbControlDescriptorRequest.DescriptorType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case URB_FUNCTION_SELECT_CONFIGURATION:
|
||||||
|
{
|
||||||
|
PUSBD_INTERFACE_INFORMATION InterfaceInfo;
|
||||||
|
LONG iCount, pCount;
|
||||||
|
|
||||||
|
DPRINT("Selecting Configuration\n");
|
||||||
|
DPRINT("Length %x\n", Urb->UrbHeader.Length);
|
||||||
|
DPRINT("Urb->UrbSelectConfiguration.ConfigurationHandle %x\n",Urb->UrbSelectConfiguration.ConfigurationHandle);
|
||||||
|
|
||||||
|
if (Urb->UrbSelectConfiguration.ConfigurationDescriptor)
|
||||||
|
{
|
||||||
|
DPRINT("ConfigurationDescriptor = %p\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor);
|
||||||
|
DPRINT(" bLength = %d\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor->bLength);
|
||||||
|
DPRINT(" bDescriptorType = %d\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor->bDescriptorType);
|
||||||
|
DPRINT(" wTotalLength = %d\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor->wTotalLength);
|
||||||
|
DPRINT(" bNumInterfaces = %d\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor->bNumInterfaces);
|
||||||
|
DPRINT(" bConfigurationValue = %d\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor->bConfigurationValue);
|
||||||
|
DPRINT(" iConfiguration = %d\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor->iConfiguration);
|
||||||
|
DPRINT(" bmAttributes = %04x\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor->bmAttributes);
|
||||||
|
DPRINT(" MaxPower = %d\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor->MaxPower);
|
||||||
|
|
||||||
|
|
||||||
|
Urb->UrbSelectConfiguration.ConfigurationHandle = (PVOID)&DeviceExtension->UsbDevices[0]->ConfigurationDescriptor;
|
||||||
|
DPRINT("ConfigHandle %x\n", Urb->UrbSelectConfiguration.ConfigurationHandle);
|
||||||
|
InterfaceInfo = &Urb->UrbSelectConfiguration.Interface;
|
||||||
|
|
||||||
|
for (iCount = 0; iCount < Urb->UrbSelectConfiguration.ConfigurationDescriptor->bNumInterfaces; iCount++)
|
||||||
|
{
|
||||||
|
DPRINT("InterfaceInformation[%d]\n", iCount);
|
||||||
|
DPRINT(" Length = %d\n", InterfaceInfo->Length);
|
||||||
|
DPRINT(" InterfaceNumber = %d\n", InterfaceInfo->InterfaceNumber);
|
||||||
|
DPRINT(" AlternateSetting = %d\n", InterfaceInfo->AlternateSetting);
|
||||||
|
DPRINT(" Class = %02x\n", (ULONG)InterfaceInfo->Class);
|
||||||
|
DPRINT(" SubClass = %02x\n", (ULONG)InterfaceInfo->SubClass);
|
||||||
|
DPRINT(" Protocol = %02x\n", (ULONG)InterfaceInfo->Protocol);
|
||||||
|
DPRINT(" Reserved = %02x\n", (ULONG)InterfaceInfo->Reserved);
|
||||||
|
DPRINT(" InterfaceHandle = %p\n", InterfaceInfo->InterfaceHandle);
|
||||||
|
DPRINT(" NumberOfPipes = %d\n", InterfaceInfo->NumberOfPipes);
|
||||||
|
InterfaceInfo->InterfaceHandle = (PVOID)&UsbDevice->InterfaceDescriptor;
|
||||||
|
InterfaceInfo->Class = UsbDevice->InterfaceDescriptor.bInterfaceClass;
|
||||||
|
InterfaceInfo->SubClass = UsbDevice->InterfaceDescriptor.bInterfaceSubClass;
|
||||||
|
InterfaceInfo->Protocol = UsbDevice->InterfaceDescriptor.bInterfaceProtocol;
|
||||||
|
InterfaceInfo->Reserved = 0;
|
||||||
|
|
||||||
|
for (pCount = 0; pCount < InterfaceInfo->NumberOfPipes; pCount++)
|
||||||
|
{
|
||||||
|
DPRINT("Pipe[%d]\n", pCount);
|
||||||
|
DPRINT(" MaximumPacketSize = %d\n", InterfaceInfo->Pipes[pCount].MaximumPacketSize);
|
||||||
|
DPRINT(" EndpointAddress = %d\n", InterfaceInfo->Pipes[pCount].EndpointAddress);
|
||||||
|
DPRINT(" Interval = %d\n", InterfaceInfo->Pipes[pCount].Interval);
|
||||||
|
DPRINT(" PipeType = %d\n", InterfaceInfo->Pipes[pCount].PipeType);
|
||||||
|
DPRINT(" PipeHandle = %x\n", InterfaceInfo->Pipes[pCount].PipeHandle);
|
||||||
|
DPRINT(" MaximumTransferSize = %d\n", InterfaceInfo->Pipes[pCount].MaximumTransferSize);
|
||||||
|
DPRINT(" PipeFlags = %08x\n", InterfaceInfo->Pipes[pCount].PipeFlags);
|
||||||
|
InterfaceInfo->Pipes[pCount].MaximumPacketSize = UsbDevice->EndPointDescriptor.wMaxPacketSize;
|
||||||
|
InterfaceInfo->Pipes[pCount].EndpointAddress = UsbDevice->EndPointDescriptor.bEndpointAddress;
|
||||||
|
InterfaceInfo->Pipes[pCount].Interval = UsbDevice->EndPointDescriptor.bInterval;
|
||||||
|
InterfaceInfo->Pipes[pCount].PipeType = UsbdPipeTypeInterrupt;
|
||||||
|
InterfaceInfo->Pipes[pCount].PipeHandle = (PVOID)&UsbDevice->EndPointDescriptor;
|
||||||
|
if (InterfaceInfo->Pipes[pCount].MaximumTransferSize == 0)
|
||||||
|
InterfaceInfo->Pipes[pCount].MaximumTransferSize = 4096;
|
||||||
|
/* InterfaceInfo->Pipes[j].PipeFlags = 0; */
|
||||||
|
}
|
||||||
|
InterfaceInfo = (PUSBD_INTERFACE_INFORMATION)((PUCHAR)InterfaceInfo + InterfaceInfo->Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
Urb->UrbHeader.UsbdDeviceHandle = UsbDevice;
|
||||||
|
Urb->UrbHeader.UsbdFlags = 0;
|
||||||
|
Urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* FIXME: Set device to unconfigured state */
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case URB_FUNCTION_CLASS_DEVICE:
|
||||||
|
{
|
||||||
|
switch (Urb->UrbControlVendorClassRequest.Request)
|
||||||
|
{
|
||||||
|
case USB_REQUEST_GET_DESCRIPTOR:
|
||||||
|
{
|
||||||
|
DPRINT1("TransferFlags %x\n", Urb->UrbControlVendorClassRequest.TransferFlags);
|
||||||
|
DPRINT1("Urb->UrbControlVendorClassRequest.Value %x\n", Urb->UrbControlVendorClassRequest.Value);
|
||||||
|
|
||||||
|
|
||||||
|
switch (Urb->UrbControlVendorClassRequest.Value >> 8)
|
||||||
|
{
|
||||||
|
case USB_DEVICE_CLASS_AUDIO:
|
||||||
|
{
|
||||||
|
DPRINT1("USB_DEVICE_CLASS_AUDIO\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case USB_DEVICE_CLASS_COMMUNICATIONS:
|
||||||
|
{
|
||||||
|
DPRINT1("USB_DEVICE_CLASS_COMMUNICATIONS\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case USB_DEVICE_CLASS_HUMAN_INTERFACE:
|
||||||
|
{
|
||||||
|
DPRINT1("USB_DEVICE_CLASS_HUMAN_INTERFACE\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case USB_DEVICE_CLASS_MONITOR:
|
||||||
|
{
|
||||||
|
DPRINT1("USB_DEVICE_CLASS_MONITOR\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case USB_DEVICE_CLASS_PHYSICAL_INTERFACE:
|
||||||
|
{
|
||||||
|
DPRINT1("USB_DEVICE_CLASS_PHYSICAL_INTERFACE\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case USB_DEVICE_CLASS_POWER:
|
||||||
|
{
|
||||||
|
DPRINT1("USB_DEVICE_CLASS_POWER\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case USB_DEVICE_CLASS_PRINTER:
|
||||||
|
{
|
||||||
|
DPRINT1("USB_DEVICE_CLASS_PRINTER\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case USB_DEVICE_CLASS_STORAGE:
|
||||||
|
{
|
||||||
|
DPRINT1("USB_DEVICE_CLASS_STORAGE\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case USB_DEVICE_CLASS_RESERVED:
|
||||||
|
case USB_DEVICE_CLASS_HUB:
|
||||||
|
{
|
||||||
|
PUSB_HUB_DESCRIPTOR UsbHubDescr = Urb->UrbControlVendorClassRequest.TransferBuffer;
|
||||||
|
/* FIXME: Handle more than root hub? */
|
||||||
|
if(Urb->UrbControlVendorClassRequest.TransferBufferLength >= sizeof(USB_HUB_DESCRIPTOR))
|
||||||
|
{
|
||||||
|
Urb->UrbControlVendorClassRequest.TransferBufferLength = sizeof(USB_HUB_DESCRIPTOR);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* FIXME: Handle this correctly */
|
||||||
|
UsbHubDescr->bDescriptorLength = sizeof(USB_HUB_DESCRIPTOR);
|
||||||
|
UsbHubDescr->bDescriptorType = 0x29;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
DPRINT1("USB_DEVICE_CLASS_HUB request\n");
|
||||||
|
UsbHubDescr->bDescriptorLength = sizeof(USB_HUB_DESCRIPTOR);
|
||||||
|
UsbHubDescr->bDescriptorType = 0x29;
|
||||||
|
UsbHubDescr->bNumberOfPorts = 0x08;
|
||||||
|
UsbHubDescr->wHubCharacteristics = 0x0012;
|
||||||
|
UsbHubDescr->bPowerOnToPowerGood = 0x01;
|
||||||
|
UsbHubDescr->bHubControlCurrent = 0x00;
|
||||||
|
UsbHubDescr->bRemoveAndPowerMask[0] = 0x00;
|
||||||
|
UsbHubDescr->bRemoveAndPowerMask[1] = 0x00;
|
||||||
|
UsbHubDescr->bRemoveAndPowerMask[2] = 0xff;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
DPRINT1("Unknown UrbControlVendorClassRequest Value\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Urb->UrbHeader.Function = 0x08;
|
||||||
|
Urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
|
||||||
|
Urb->UrbHeader.UsbdDeviceHandle = UsbDevice;
|
||||||
|
Urb->UrbHeader.UsbdFlags = 0;
|
||||||
|
/* Stop handling the URBs now as its not coded yet */
|
||||||
|
DeviceExtension->HaltUrbHandling = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
DPRINT1("Unhandled URB request for class device\n");
|
||||||
|
Urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
DPRINT1("Unhandled URB %x\n", Urb->UrbHeader.Function);
|
||||||
|
Urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, oldIrql);
|
KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, oldIrql);
|
||||||
|
|
||||||
|
Irp->IoStatus.Status = Status;
|
||||||
|
Irp->IoStatus.Information = Information;
|
||||||
|
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
KeAcquireSpinLock(&DeviceExtension->IrpQueueLock, &oldIrql);
|
KeAcquireSpinLock(&DeviceExtension->IrpQueueLock, &oldIrql);
|
||||||
}
|
}
|
||||||
|
|
||||||
KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, oldIrql);
|
KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, oldIrql);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
NTAPI
|
|
||||||
ArrivalNotificationCompletion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID PContext)
|
|
||||||
{
|
|
||||||
PDEVICE_OBJECT PortDeviceObject = (PDEVICE_OBJECT) PContext;
|
|
||||||
IoFreeIrp(Irp);
|
|
||||||
ObDereferenceObject(PortDeviceObject);
|
|
||||||
return STATUS_MORE_PROCESSING_REQUIRED;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
DeviceArrivalWorkItem(PDEVICE_OBJECT DeviceObject, PVOID Context)
|
|
||||||
{
|
|
||||||
PWORKITEM_DATA WorkItemData;
|
|
||||||
PIO_STACK_LOCATION IrpStack = NULL;
|
|
||||||
PDEVICE_OBJECT PortDeviceObject = NULL;
|
|
||||||
PIRP Irp = NULL;
|
|
||||||
|
|
||||||
WorkItemData = (PWORKITEM_DATA)Context;
|
|
||||||
|
|
||||||
PortDeviceObject = IoGetAttachedDeviceReference(WorkItemData->FdoDeviceExtension->Pdo);
|
|
||||||
|
|
||||||
if (!PortDeviceObject)
|
|
||||||
{
|
|
||||||
DPRINT1("Unable to notify Pdos parent of device arrival.\n");
|
|
||||||
goto Cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PortDeviceObject == DeviceObject)
|
|
||||||
{
|
|
||||||
/* Piontless to send query relations to ourself */
|
|
||||||
ObDereferenceObject(PortDeviceObject);
|
|
||||||
goto Cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
Irp = IoAllocateIrp(PortDeviceObject->StackSize, FALSE);
|
|
||||||
|
|
||||||
if (!Irp)
|
|
||||||
{
|
|
||||||
DPRINT1("Unable to allocate IRP\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
IoSetCompletionRoutine(Irp,
|
|
||||||
(PIO_COMPLETION_ROUTINE)ArrivalNotificationCompletion,
|
|
||||||
(PVOID) PortDeviceObject,
|
|
||||||
TRUE,
|
|
||||||
TRUE,
|
|
||||||
TRUE);
|
|
||||||
|
|
||||||
IrpStack = IoGetNextIrpStackLocation(Irp);
|
|
||||||
IrpStack->Parameters.QueryDeviceRelations.Type = TargetDeviceRelation;
|
|
||||||
IrpStack->MajorFunction = IRP_MJ_PNP;
|
|
||||||
IrpStack->MinorFunction = IRP_MN_QUERY_DEVICE_RELATIONS;
|
|
||||||
|
|
||||||
IoCallDriver(PortDeviceObject, Irp);
|
|
||||||
|
|
||||||
Cleanup:
|
|
||||||
IoFreeWorkItem(WorkItemData->IoWorkItem);
|
|
||||||
ExFreePool(WorkItemData);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ IntializeHeadQueueForStandardRequest(PQUEUE_HEAD QueueHead,
|
||||||
|
|
||||||
/* Must be Page aligned */
|
/* Must be Page aligned */
|
||||||
*CtrlSetup = (PEHCI_SETUP_FORMAT) (( (ULONG)(*CtrlTD3) + sizeof(QUEUE_TRANSFER_DESCRIPTOR) + 0xFFF) & ~0xFFF);
|
*CtrlSetup = (PEHCI_SETUP_FORMAT) (( (ULONG)(*CtrlTD3) + sizeof(QUEUE_TRANSFER_DESCRIPTOR) + 0xFFF) & ~0xFFF);
|
||||||
*CtrlData = (PSTANDARD_DEVICE_DESC) (( (ULONG)(*CtrlSetup) + sizeof(EHCI_SETUP_FORMAT) + 0xFFF) & ~0xFFF);
|
*CtrlData = (PUSB_DEVICE_DESCRIPTOR) (( (ULONG)(*CtrlSetup) + sizeof(EHCI_SETUP_FORMAT) + 0xFFF) & ~0xFFF);
|
||||||
|
|
||||||
(*CtrlTD1)->NextPointer = TERMINATE_POINTER;
|
(*CtrlTD1)->NextPointer = TERMINATE_POINTER;
|
||||||
(*CtrlTD1)->AlternateNextPointer = TERMINATE_POINTER;
|
(*CtrlTD1)->AlternateNextPointer = TERMINATE_POINTER;
|
||||||
|
@ -105,10 +105,10 @@ IntializeHeadQueueForStandardRequest(PQUEUE_HEAD QueueHead,
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
GetDeviceDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension, UCHAR Index)
|
GetDeviceDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension, UCHAR Index, PUSB_DEVICE_DESCRIPTOR OutBuffer, BOOLEAN Hub)
|
||||||
{
|
{
|
||||||
PEHCI_SETUP_FORMAT CtrlSetup = NULL;
|
PEHCI_SETUP_FORMAT CtrlSetup = NULL;
|
||||||
PSTANDARD_DEVICE_DESC CtrlData = NULL;
|
PUSB_DEVICE_DESCRIPTOR CtrlData = NULL;
|
||||||
PQUEUE_TRANSFER_DESCRIPTOR CtrlTD1 = NULL;
|
PQUEUE_TRANSFER_DESCRIPTOR CtrlTD1 = NULL;
|
||||||
PQUEUE_TRANSFER_DESCRIPTOR CtrlTD2 = NULL;
|
PQUEUE_TRANSFER_DESCRIPTOR CtrlTD2 = NULL;
|
||||||
PQUEUE_TRANSFER_DESCRIPTOR CtrlTD3 = NULL;
|
PQUEUE_TRANSFER_DESCRIPTOR CtrlTD3 = NULL;
|
||||||
|
@ -129,14 +129,22 @@ GetDeviceDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension, UCHAR Index)
|
||||||
&CtrlTD3,
|
&CtrlTD3,
|
||||||
&CtrlSetup,
|
&CtrlSetup,
|
||||||
(PVOID)&CtrlData,
|
(PVOID)&CtrlData,
|
||||||
sizeof(STANDARD_DEVICE_DESC));
|
sizeof(USB_DEVICE_DESCRIPTOR));
|
||||||
|
|
||||||
/* FIXME: Use defines and handle other than Device Desciptors */
|
/* FIXME: Use defines and handle other than Device Desciptors */
|
||||||
|
if (Hub)
|
||||||
|
{
|
||||||
|
CtrlSetup->bmRequestType = 0x80;
|
||||||
|
CtrlSetup->wValue = 0x0600;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
CtrlSetup->bmRequestType = 0x80;
|
CtrlSetup->bmRequestType = 0x80;
|
||||||
CtrlSetup->bRequest = 0x06;
|
|
||||||
CtrlSetup->wValue = 0x0100;
|
CtrlSetup->wValue = 0x0100;
|
||||||
|
}
|
||||||
|
CtrlSetup->bRequest = 0x06;
|
||||||
CtrlSetup->wIndex = 0;
|
CtrlSetup->wIndex = 0;
|
||||||
CtrlSetup->wLength = sizeof(STANDARD_DEVICE_DESC);
|
CtrlSetup->wLength = sizeof(USB_DEVICE_DESCRIPTOR);
|
||||||
|
|
||||||
tmp = READ_REGISTER_ULONG((PULONG) (Base + EHCI_USBCMD));
|
tmp = READ_REGISTER_ULONG((PULONG) (Base + EHCI_USBCMD));
|
||||||
UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp;
|
UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp;
|
||||||
|
@ -182,13 +190,31 @@ GetDeviceDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension, UCHAR Index)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (OutBuffer != NULL)
|
||||||
|
{
|
||||||
|
OutBuffer->bLength = CtrlData->bLength;
|
||||||
|
OutBuffer->bDescriptorType = CtrlData->bDescriptorType;
|
||||||
|
OutBuffer->bcdUSB = CtrlData->bcdUSB;
|
||||||
|
OutBuffer->bDeviceClass = CtrlData->bDeviceClass;
|
||||||
|
OutBuffer->bDeviceSubClass = CtrlData->bDeviceSubClass;
|
||||||
|
OutBuffer->bDeviceProtocol = CtrlData->bDeviceProtocol;
|
||||||
|
OutBuffer->bMaxPacketSize0 = CtrlData->bMaxPacketSize0;
|
||||||
|
OutBuffer->idVendor = CtrlData->idVendor;
|
||||||
|
OutBuffer->idProduct = CtrlData->idProduct;
|
||||||
|
OutBuffer->bcdDevice = CtrlData->bcdDevice;
|
||||||
|
OutBuffer->iManufacturer = CtrlData->iManufacturer;
|
||||||
|
OutBuffer->iProduct = CtrlData->iProduct;
|
||||||
|
OutBuffer->iSerialNumber = CtrlData->iSerialNumber;
|
||||||
|
OutBuffer->bNumConfigurations = CtrlData->bNumConfigurations;
|
||||||
|
}
|
||||||
|
|
||||||
DPRINT1("bLength %d\n", CtrlData->bLength);
|
DPRINT1("bLength %d\n", CtrlData->bLength);
|
||||||
DPRINT1("bDescriptorType %x\n", CtrlData->bDescriptorType);
|
DPRINT1("bDescriptorType %x\n", CtrlData->bDescriptorType);
|
||||||
DPRINT1("bcdUSB %x\n", CtrlData->bcdUSB);
|
DPRINT1("bcdUSB %x\n", CtrlData->bcdUSB);
|
||||||
DPRINT1("CtrlData->bDeviceClass %x\n", CtrlData->bDeviceClass);
|
DPRINT1("CtrlData->bDeviceClass %x\n", CtrlData->bDeviceClass);
|
||||||
DPRINT1("CtrlData->bDeviceSubClass %x\n", CtrlData->bDeviceSubClass);
|
DPRINT1("CtrlData->bDeviceSubClass %x\n", CtrlData->bDeviceSubClass);
|
||||||
DPRINT1("CtrlData->bDeviceProtocal %x\n", CtrlData->bDeviceProtocal);
|
DPRINT1("CtrlData->bDeviceProtocal %x\n", CtrlData->bDeviceProtocol);
|
||||||
DPRINT1("CtrlData->bMaxPacketSize %x\n", CtrlData->bMaxPacketSize);
|
DPRINT1("CtrlData->bMaxPacketSize %x\n", CtrlData->bMaxPacketSize0);
|
||||||
DPRINT1("CtrlData->idVendor %x\n", CtrlData->idVendor);
|
DPRINT1("CtrlData->idVendor %x\n", CtrlData->idVendor);
|
||||||
DPRINT1("CtrlData->idProduct %x\n", CtrlData->idProduct);
|
DPRINT1("CtrlData->idProduct %x\n", CtrlData->idProduct);
|
||||||
DPRINT1("CtrlData->bcdDevice %x\n", CtrlData->bcdDevice);
|
DPRINT1("CtrlData->bcdDevice %x\n", CtrlData->bcdDevice);
|
||||||
|
@ -202,7 +228,7 @@ GetDeviceDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension, UCHAR Index)
|
||||||
{
|
{
|
||||||
/* We got valid data, try for strings */
|
/* We got valid data, try for strings */
|
||||||
UCHAR Manufacturer = CtrlData->iManufacturer;
|
UCHAR Manufacturer = CtrlData->iManufacturer;
|
||||||
UCHAR Product = CtrlData->iManufacturer;
|
UCHAR Product = CtrlData->iProduct;
|
||||||
UCHAR SerialNumber = CtrlData->iSerialNumber;
|
UCHAR SerialNumber = CtrlData->iSerialNumber;
|
||||||
|
|
||||||
GetDeviceStringDescriptor(DeviceExtension, Manufacturer);
|
GetDeviceStringDescriptor(DeviceExtension, Manufacturer);
|
||||||
|
@ -228,7 +254,7 @@ GetDeviceStringDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension, UCHAR Index)
|
||||||
LONG tmp;
|
LONG tmp;
|
||||||
|
|
||||||
Base = (ULONG) DeviceExtension->ResourceMemory;
|
Base = (ULONG) DeviceExtension->ResourceMemory;
|
||||||
DPRINT1("Index: %d\n", Index);
|
|
||||||
/* Set up the QUEUE HEAD in memory */
|
/* Set up the QUEUE HEAD in memory */
|
||||||
QueueHead = (PQUEUE_HEAD) ((ULONG)DeviceExtension->AsyncListQueueHeadPtr);
|
QueueHead = (PQUEUE_HEAD) ((ULONG)DeviceExtension->AsyncListQueueHeadPtr);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue