mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 09:25:10 +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 *******************************************************************/
|
||||
#include "usbehci.h"
|
||||
#include <stdio.h>
|
||||
|
||||
//#include "ntstrsafe.h"
|
||||
|
||||
VOID NTAPI
|
||||
EhciDefferedRoutine(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
|
||||
{
|
||||
PFDO_DEVICE_EXTENSION FdoDeviceExtension;
|
||||
PPDO_DEVICE_EXTENSION PdoDeviceExtension;
|
||||
ULONG CStatus;
|
||||
|
||||
FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) DeferredContext;
|
||||
PdoDeviceExtension = (PPDO_DEVICE_EXTENSION) FdoDeviceExtension->Pdo->DeviceExtension;
|
||||
|
||||
CStatus = (ULONG) SystemArgument2;
|
||||
|
||||
|
@ -39,8 +42,6 @@ EhciDefferedRoutine(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVO
|
|||
/* Check for port change on this port */
|
||||
if (tmp & 0x02)
|
||||
{
|
||||
PWORKITEM_DATA WorkItemData = NULL;
|
||||
|
||||
/* Connect or Disconnect? */
|
||||
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)));
|
||||
|
||||
DPRINT("port tmp %x\n", tmp);
|
||||
GetDeviceDescriptor(FdoDeviceExtension, 0);
|
||||
FdoDeviceExtension->ChildDeviceCount++;
|
||||
CompletePendingRequest(FdoDeviceExtension);
|
||||
|
||||
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);
|
||||
GetDeviceDescriptor(FdoDeviceExtension, 0, 0, FALSE);
|
||||
PdoDeviceExtension->ChildDeviceCount++;
|
||||
//CompletePendingURBRequest(PdoDeviceExtension);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -116,7 +95,6 @@ EhciDefferedRoutine(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVO
|
|||
tmp |= 0x02;
|
||||
WRITE_REGISTER_ULONG((PULONG) ((Base + EHCI_PORTSC) + (4 * i)), tmp);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -180,7 +158,6 @@ InterruptService(PKINTERRUPT Interrupt, PVOID ServiceContext)
|
|||
BOOLEAN
|
||||
ResetPort(PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
|
||||
/*FIXME: Implement me */
|
||||
|
||||
return TRUE;
|
||||
|
@ -310,8 +287,6 @@ StartEhci(PDEVICE_OBJECT DeviceObject)
|
|||
EHCI_USBINTR_INTE | EHCI_USBINTR_ERR | EHCI_USBINTR_ASYNC | EHCI_USBINTR_HSERR
|
||||
| EHCI_USBINTR_FLROVR | EHCI_USBINTR_PC);
|
||||
|
||||
//UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp;
|
||||
|
||||
UsbCmd->Run = 1;
|
||||
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->HCCParams = READ_REGISTER_ULONG((PULONG)(Base + 8));
|
||||
|
||||
|
||||
DPRINT("Length %d\n", PCap->Length);
|
||||
DPRINT("Reserved %d\n", PCap->Reserved);
|
||||
DPRINT("HCIVersion %x\n", PCap->HCIVersion);
|
||||
DPRINT("HCSParams %x\n", PCap->HCSParamsLong);
|
||||
DPRINT("HCCParams %x\n", PCap->HCCParams);
|
||||
|
||||
|
||||
if (PCap->HCCParams & 0x02)
|
||||
DPRINT1("Frame list size is configurable\n");
|
||||
|
||||
|
@ -412,8 +385,8 @@ StartDevice(PDEVICE_OBJECT DeviceObject, PCM_PARTIAL_RESOURCE_LIST raw, PCM_PART
|
|||
DeviceDescription.MaximumLength = EHCI_MAX_SIZE_TRANSFER;
|
||||
|
||||
FdoDeviceExtension->pDmaAdapter = IoGetDmaAdapter(FdoDeviceExtension->LowerDevice,
|
||||
&DeviceDescription,
|
||||
&FdoDeviceExtension->MapRegisters);
|
||||
&DeviceDescription,
|
||||
&FdoDeviceExtension->MapRegisters);
|
||||
|
||||
if (FdoDeviceExtension->pDmaAdapter == NULL)
|
||||
{
|
||||
|
@ -561,14 +534,16 @@ FdoQueryBusRelations(
|
|||
NTSTATUS Status;
|
||||
ULONG UsbDeviceNumber = 0;
|
||||
WCHAR CharDeviceName[64];
|
||||
|
||||
UNICODE_STRING DeviceName;
|
||||
|
||||
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
/* Create the PDO */
|
||||
|
||||
/* Create the PDO with the next available number */
|
||||
while (TRUE)
|
||||
{
|
||||
/* FIXME: Use safe string sprintf*/
|
||||
/* RtlStringCchPrintfW(CharDeviceName, 64, L"USBFDO-%d", UsbDeviceNumber); */
|
||||
/* FIXME: Use safe string */
|
||||
/* RtlStringCchPrintfW(CharDeviceName, 64, L"USBPDO-%d", UsbDeviceNumber); */
|
||||
swprintf(CharDeviceName, L"\\Device\\USBPDO-%d", UsbDeviceNumber);
|
||||
RtlInitUnicodeString(&DeviceName, CharDeviceName);
|
||||
DPRINT("DeviceName %wZ\n", &DeviceName);
|
||||
|
@ -604,20 +579,17 @@ FdoQueryBusRelations(
|
|||
PdoDeviceExtension->Common.IsFdo = FALSE;
|
||||
|
||||
PdoDeviceExtension->ControllerFdo = DeviceObject;
|
||||
PdoDeviceExtension->DeviceObject = Pdo;
|
||||
|
||||
InitializeListHead(&PdoDeviceExtension->IrpQueue);
|
||||
KeInitializeSpinLock(&PdoDeviceExtension->IrpQueueLock);
|
||||
|
||||
Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||
|
||||
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));
|
||||
|
||||
if (!DeviceRelations)
|
||||
{
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
@ -646,7 +618,7 @@ FdoDispatchPnp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
|
|||
{
|
||||
case IRP_MN_START_DEVICE:
|
||||
{
|
||||
DPRINT("START_DEVICE\n");
|
||||
DPRINT1("START_DEVICE\n");
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Status = ForwardAndWait(DeviceObject, Irp);
|
||||
|
||||
|
@ -657,7 +629,7 @@ FdoDispatchPnp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
|
|||
}
|
||||
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)
|
||||
{
|
||||
case BusRelations:
|
||||
|
@ -687,6 +659,14 @@ FdoDispatchPnp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
|
|||
{
|
||||
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:
|
||||
{
|
||||
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];
|
||||
UNICODE_STRING DeviceName;
|
||||
UNICODE_STRING SymLinkName;
|
||||
UNICODE_STRING InterfaceSymLinkName;
|
||||
ULONG BytesRead;
|
||||
PCI_COMMON_CONFIG PciConfig;
|
||||
|
||||
PFDO_DEVICE_EXTENSION FdoDeviceExtension;
|
||||
|
||||
DPRINT1("Ehci AddDevice\n");
|
||||
DPRINT("Ehci AddDevice\n");
|
||||
|
||||
/* Create the FDO */
|
||||
/* Create the FDO with next available number */
|
||||
while (TRUE)
|
||||
{
|
||||
/* FIXME: Use safe string sprintf*/
|
||||
/* RtlStringCchPrintfW(CharDeviceName, 64, L"USBFDO-%d", UsbDeviceNumber); */
|
||||
swprintf(CharDeviceName, L"\\Device\\USBFDO-%d", UsbDeviceNumber);
|
||||
RtlInitUnicodeString(&DeviceName, CharDeviceName);
|
||||
DPRINT1("DeviceName %wZ\n", &DeviceName);
|
||||
DPRINT("DeviceName %wZ\n", &DeviceName);
|
||||
|
||||
Status = IoCreateDevice(DriverObject,
|
||||
sizeof(FDO_DEVICE_EXTENSION),
|
||||
|
@ -734,8 +715,8 @@ AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT Pdo)
|
|||
FALSE,
|
||||
&Fdo);
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
break;
|
||||
if (NT_SUCCESS(Status))
|
||||
break;
|
||||
|
||||
if ((Status == STATUS_OBJECT_NAME_EXISTS) || (Status == STATUS_OBJECT_NAME_COLLISION))
|
||||
{
|
||||
|
@ -758,21 +739,17 @@ AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT Pdo)
|
|||
|
||||
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;
|
||||
RtlZeroMemory(FdoDeviceExtension, sizeof(PFDO_DEVICE_EXTENSION));
|
||||
|
||||
InitializeListHead(&FdoDeviceExtension->IrpQueue);
|
||||
KeInitializeSpinLock(&FdoDeviceExtension->IrpQueueLock);
|
||||
|
||||
FdoDeviceExtension->Common.IsFdo = TRUE;
|
||||
FdoDeviceExtension->DeviceObject = Fdo;
|
||||
|
||||
FdoDeviceExtension->LowerDevice = IoAttachDeviceToDeviceStack(Fdo, Pdo);
|
||||
|
||||
if (FdoDeviceExtension->LowerDevice == NULL)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
Status = GetBusInterface(FdoDeviceExtension->LowerDevice, &FdoDeviceExtension->BusInterface);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
|
@ -797,8 +774,6 @@ AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT Pdo)
|
|||
return Status;
|
||||
}
|
||||
|
||||
DPRINT("Context %x\n", FdoDeviceExtension->BusInterface.Context);
|
||||
|
||||
BytesRead = (*FdoDeviceExtension->BusInterface.GetBusData)(
|
||||
FdoDeviceExtension->BusInterface.Context,
|
||||
PCI_WHICHSPACE_CONFIG,
|
||||
|
@ -827,15 +802,24 @@ AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT Pdo)
|
|||
DPRINT("PCI_ENABLE_BUS_MASTER\n");
|
||||
|
||||
DPRINT("BaseAddress[0] %x\n", PciConfig.u.type0.BaseAddresses[0]);
|
||||
DPRINT("Vendor %x\n", PciConfig.VendorID);
|
||||
DPRINT("Device %x\n", PciConfig.DeviceID);
|
||||
DPRINT1("Vendor %x\n", PciConfig.VendorID);
|
||||
DPRINT1("Device %x\n", PciConfig.DeviceID);
|
||||
|
||||
FdoDeviceExtension->VendorId = PciConfig.VendorID;
|
||||
FdoDeviceExtension->DeviceId = PciConfig.DeviceID;
|
||||
|
||||
DPRINT("FdoDeviceExtension->NextLowerDevice %x\n", FdoDeviceExtension->LowerDevice);
|
||||
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;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
|
|
|
@ -10,28 +10,26 @@
|
|||
#include "usbehci.h"
|
||||
|
||||
VOID
|
||||
RequestCancel (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
RequestURBCancel (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
PPDO_DEVICE_EXTENSION PdoDeviceExtension;
|
||||
PFDO_DEVICE_EXTENSION FdoDeviceExtension;
|
||||
|
||||
PdoDeviceExtension = (PPDO_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
|
||||
FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) PdoDeviceExtension->ControllerFdo->DeviceExtension;
|
||||
|
||||
KIRQL OldIrql = Irp->CancelIrql;
|
||||
IoReleaseCancelSpinLock(DISPATCH_LEVEL);
|
||||
|
||||
KeAcquireSpinLockAtDpcLevel(&FdoDeviceExtension->IrpQueueLock);
|
||||
KeAcquireSpinLockAtDpcLevel(&PdoDeviceExtension->IrpQueueLock);
|
||||
RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
|
||||
|
||||
KeReleaseSpinLock(&FdoDeviceExtension->IrpQueueLock, OldIrql);
|
||||
KeReleaseSpinLock(&PdoDeviceExtension->IrpQueueLock, OldIrql);
|
||||
|
||||
Irp->IoStatus.Status = STATUS_CANCELLED;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
Irp->IoStatus.Status = STATUS_CANCELLED;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
}
|
||||
|
||||
VOID
|
||||
QueueRequest(PFDO_DEVICE_EXTENSION DeviceExtension, PIRP Irp)
|
||||
QueueURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension, PIRP Irp)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
|
||||
|
@ -51,10 +49,13 @@ QueueRequest(PFDO_DEVICE_EXTENSION DeviceExtension, PIRP Irp)
|
|||
}
|
||||
|
||||
VOID
|
||||
CompletePendingRequest(PFDO_DEVICE_EXTENSION DeviceExtension)
|
||||
CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
|
||||
{
|
||||
PLIST_ENTRY NextIrp = NULL;
|
||||
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
||||
ULONG_PTR Information = 0;
|
||||
PIO_STACK_LOCATION Stack;
|
||||
PUSB_DEVICE UsbDevice = NULL;
|
||||
KIRQL oldIrql;
|
||||
PIRP Irp = NULL;
|
||||
URB *Urb;
|
||||
|
@ -75,83 +76,275 @@ CompletePendingRequest(PFDO_DEVICE_EXTENSION DeviceExtension)
|
|||
Urb = (PURB) Stack->Parameters.Others.Argument1;
|
||||
ASSERT(Urb);
|
||||
|
||||
/* FIXME: Fill in information for Argument1/URB */
|
||||
Information = 0;
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
DPRINT("TransferBuffer %x\n", Urb->UrbControlDescriptorRequest.TransferBuffer);
|
||||
DPRINT("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);
|
||||
DPRINT1("TransferBuffer %x\n", Urb->UrbControlDescriptorRequest.TransferBuffer);
|
||||
DPRINT1("TransferBufferLength %x\n", Urb->UrbControlDescriptorRequest.TransferBufferLength);
|
||||
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = 0;
|
||||
UsbDevice = Urb->UrbHeader.UsbdDeviceHandle;
|
||||
/* 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);
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = Information;
|
||||
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
KeAcquireSpinLock(&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 */
|
||||
*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)->AlternateNextPointer = TERMINATE_POINTER;
|
||||
|
@ -105,10 +105,10 @@ IntializeHeadQueueForStandardRequest(PQUEUE_HEAD QueueHead,
|
|||
}
|
||||
|
||||
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;
|
||||
PSTANDARD_DEVICE_DESC CtrlData = NULL;
|
||||
PUSB_DEVICE_DESCRIPTOR CtrlData = NULL;
|
||||
PQUEUE_TRANSFER_DESCRIPTOR CtrlTD1 = NULL;
|
||||
PQUEUE_TRANSFER_DESCRIPTOR CtrlTD2 = NULL;
|
||||
PQUEUE_TRANSFER_DESCRIPTOR CtrlTD3 = NULL;
|
||||
|
@ -129,14 +129,22 @@ GetDeviceDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension, UCHAR Index)
|
|||
&CtrlTD3,
|
||||
&CtrlSetup,
|
||||
(PVOID)&CtrlData,
|
||||
sizeof(STANDARD_DEVICE_DESC));
|
||||
sizeof(USB_DEVICE_DESCRIPTOR));
|
||||
|
||||
/* FIXME: Use defines and handle other than Device Desciptors */
|
||||
CtrlSetup->bmRequestType = 0x80;
|
||||
if (Hub)
|
||||
{
|
||||
CtrlSetup->bmRequestType = 0x80;
|
||||
CtrlSetup->wValue = 0x0600;
|
||||
}
|
||||
else
|
||||
{
|
||||
CtrlSetup->bmRequestType = 0x80;
|
||||
CtrlSetup->wValue = 0x0100;
|
||||
}
|
||||
CtrlSetup->bRequest = 0x06;
|
||||
CtrlSetup->wValue = 0x0100;
|
||||
CtrlSetup->wIndex = 0;
|
||||
CtrlSetup->wLength = sizeof(STANDARD_DEVICE_DESC);
|
||||
CtrlSetup->wLength = sizeof(USB_DEVICE_DESCRIPTOR);
|
||||
|
||||
tmp = READ_REGISTER_ULONG((PULONG) (Base + EHCI_USBCMD));
|
||||
UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp;
|
||||
|
@ -182,13 +190,31 @@ GetDeviceDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension, UCHAR Index)
|
|||
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("bDescriptorType %x\n", CtrlData->bDescriptorType);
|
||||
DPRINT1("bcdUSB %x\n", CtrlData->bcdUSB);
|
||||
DPRINT1("CtrlData->bDeviceClass %x\n", CtrlData->bDeviceClass);
|
||||
DPRINT1("CtrlData->bDeviceSubClass %x\n", CtrlData->bDeviceSubClass);
|
||||
DPRINT1("CtrlData->bDeviceProtocal %x\n", CtrlData->bDeviceProtocal);
|
||||
DPRINT1("CtrlData->bMaxPacketSize %x\n", CtrlData->bMaxPacketSize);
|
||||
DPRINT1("CtrlData->bDeviceProtocal %x\n", CtrlData->bDeviceProtocol);
|
||||
DPRINT1("CtrlData->bMaxPacketSize %x\n", CtrlData->bMaxPacketSize0);
|
||||
DPRINT1("CtrlData->idVendor %x\n", CtrlData->idVendor);
|
||||
DPRINT1("CtrlData->idProduct %x\n", CtrlData->idProduct);
|
||||
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 */
|
||||
UCHAR Manufacturer = CtrlData->iManufacturer;
|
||||
UCHAR Product = CtrlData->iManufacturer;
|
||||
UCHAR Product = CtrlData->iProduct;
|
||||
UCHAR SerialNumber = CtrlData->iSerialNumber;
|
||||
|
||||
GetDeviceStringDescriptor(DeviceExtension, Manufacturer);
|
||||
|
@ -228,7 +254,7 @@ GetDeviceStringDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension, UCHAR Index)
|
|||
LONG tmp;
|
||||
|
||||
Base = (ULONG) DeviceExtension->ResourceMemory;
|
||||
DPRINT1("Index: %d\n", Index);
|
||||
|
||||
/* Set up the QUEUE HEAD in memory */
|
||||
QueueHead = (PQUEUE_HEAD) ((ULONG)DeviceExtension->AsyncListQueueHeadPtr);
|
||||
|
||||
|
|
Loading…
Reference in a new issue