[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:
Michael Martin 2010-02-10 12:38:18 +00:00
parent a884062bc9
commit 3c1ec16123
3 changed files with 360 additions and 157 deletions

View file

@ -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;

View file

@ -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);
}

View file

@ -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);