[usb/usbehci]
authorMichael Martin <michael.martin@reactos.org>
Wed, 14 Apr 2010 14:46:10 +0000 (14:46 +0000)
committerMichael Martin <michael.martin@reactos.org>
Wed, 14 Apr 2010 14:46:10 +0000 (14:46 +0000)
- Remove WorkItem code yet again as its not needed.
- Set Ports PortChange to STATUS_CONNECTED when detecting insertion of new usb device.
- Change UrbWorkerThread to use timer and wait so we dont waste cpu cycles.
- Implement IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION.
- Upon receiving the IRP_MN_QUERY_DEVICE_RELATIONS with type BusRelation, stop processing the root hub IRPs,
as at this point the hub driver has been informed of everything it needs to know about the device.
The next SCE request will remain pending until another devices is connected.
- Implement ExecuteControlRequest for all control related communications to/from usb devices.
- Remove GetDeviceDescriptor and GetDeviceStringDescriptor as no longer needed.
- Fix implementation of Direct Call function CreateUsbDevice.
- Implement Direct Call functions InitializeUsbDevice and GetUsbDescriptors.
- Misc rearranging and clean up.

svn path=/trunk/; revision=46867

reactos/drivers/usb/usbehci/common.c
reactos/drivers/usb/usbehci/fdo.c
reactos/drivers/usb/usbehci/irp.c
reactos/drivers/usb/usbehci/pdo.c
reactos/drivers/usb/usbehci/urbreq.c
reactos/drivers/usb/usbehci/usbehci.c
reactos/drivers/usb/usbehci/usbehci.h
reactos/drivers/usb/usbehci/usbiffn.c
reactos/drivers/usb/usbehci/usbiffn.h

index 79ecbad..7ed7421 100644 (file)
@@ -11,8 +11,6 @@
 #include "usbehci.h"
 #include <wdmguid.h>
 #include <stdio.h>
-#define NDEBUG
-#include <debug.h>
 
 /* PUBLIC AND PRIVATE FUNCTIONS ***********************************************/
 
index b85ab4f..c42ebfd 100644 (file)
 #include "usbehci.h"
 #include <stdio.h>
 
-//#include "ntstrsafe.h"
-
-VOID NTAPI
-DeviceArrivalWorkItem(PDEVICE_OBJECT DeviceObject, PVOID Context)
-{
-    PWORKITEM_DATA WorkItemData;
-    PPDO_DEVICE_EXTENSION PdoDeviceExtension;
-
-    WorkItemData = (PWORKITEM_DATA)Context;
-    PdoDeviceExtension = (PPDO_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
-
-    if (PdoDeviceExtension->CallbackRoutine)
-        PdoDeviceExtension->CallbackRoutine(PdoDeviceExtension->CallbackContext);
-    else
-        DPRINT1("PdoDeviceExtension->CallbackRoutine is NULL!\n");
-
-    IoFreeWorkItem(WorkItemData->IoWorkItem);
-    ExFreePool(WorkItemData);
-}
-
 VOID NTAPI
 EhciDefferedRoutine(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
 {
@@ -60,7 +40,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)
                 {
@@ -100,17 +79,12 @@ EhciDefferedRoutine(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVO
 
                     tmp = READ_REGISTER_ULONG((PULONG)((Base + EHCI_PORTSC) + (4 * i)));
 
-                    GetDeviceDescriptor(FdoDeviceExtension, 0, 0, FALSE);
                     PdoDeviceExtension->ChildDeviceCount++;
-                    PdoDeviceExtension->Ports[i].PortStatus |= USB_PORT_STATUS_HIGH_SPEED | USB_PORT_STATUS_CONNECT | USB_PORT_STATUS_ENABLE;
-                    WorkItemData = ExAllocatePool(NonPagedPool, sizeof(WORKITEM_DATA));
-                    if (!WorkItemData) ASSERT(FALSE);
-                    WorkItemData->IoWorkItem = IoAllocateWorkItem(PdoDeviceExtension->DeviceObject);
-                    WorkItemData->PdoDeviceExtension = PdoDeviceExtension;
-                    IoQueueWorkItem(WorkItemData->IoWorkItem,
-                                    (PIO_WORKITEM_ROUTINE)DeviceArrivalWorkItem,
-                                    DelayedWorkQueue,
-                                    WorkItemData);
+                    PdoDeviceExtension->Ports[i].PortStatus |= USB_PORT_STATUS_HIGH_SPEED | USB_PORT_STATUS_CONNECT;
+                    PdoDeviceExtension->Ports[i].PortChange |= USB_PORT_STATUS_CONNECT;
+
+                    PdoDeviceExtension->HaltQueue = FALSE;
+                    KeSetEvent(&PdoDeviceExtension->QueueDrainedEvent, 0, FALSE);
                 }
                 else
                 {
@@ -611,6 +585,10 @@ FdoQueryBusRelations(
     InitializeListHead(&PdoDeviceExtension->IrpQueue);
     KeInitializeSpinLock(&PdoDeviceExtension->IrpQueueLock);
 
+    KeInitializeEvent(&PdoDeviceExtension->QueueDrainedEvent, SynchronizationEvent, TRUE);
+
+    ExInitializeFastMutex(&PdoDeviceExtension->ListLock);
+
     Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
 
     DeviceExtension->Pdo = Pdo;
index 54b3b97..99a601d 100644 (file)
@@ -62,26 +62,26 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
 
     KeAcquireSpinLock(&DeviceExtension->IrpQueueLock, &oldIrql);
 
-    while(!IsListEmpty(&DeviceExtension->IrpQueue))
+    while (!IsListEmpty(&DeviceExtension->IrpQueue))
     {
         NextIrp = RemoveHeadList(&DeviceExtension->IrpQueue);
         Irp = CONTAINING_RECORD(NextIrp, IRP, Tail.Overlay.ListEntry);
 
         if (!Irp)
             break;
-
         Stack = IoGetCurrentIrpStackLocation(Irp);
         ASSERT(Stack);
 
         Urb = (PURB) Stack->Parameters.Others.Argument1;
+
         ASSERT(Urb);
 
         Information = 0;
         Status = STATUS_SUCCESS;
 
-        DPRINT1("TransferBuffer %x\n", Urb->UrbControlDescriptorRequest.TransferBuffer);
-        DPRINT1("TransferBufferLength %x\n", Urb->UrbControlDescriptorRequest.TransferBufferLength);
-        DPRINT1("UsbdDeviceHandle = %x\n", Urb->UrbHeader.UsbdDeviceHandle);
+        DPRINT("TransferBuffer %x\n", Urb->UrbControlDescriptorRequest.TransferBuffer);
+        DPRINT("TransferBufferLength %x\n", Urb->UrbControlDescriptorRequest.TransferBufferLength);
+        DPRINT("UsbdDeviceHandle = %x\n", Urb->UrbHeader.UsbdDeviceHandle);
 
         UsbDevice = Urb->UrbHeader.UsbdDeviceHandle;
         /* UsbdDeviceHandle of 0 is root hub */
@@ -97,14 +97,15 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
         {
             case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
             {
-                DPRINT1("URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:\n");
-                DPRINT1("--->TransferBufferLength %x\n",Urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
-                DPRINT1("--->TransferBuffer %x\n",Urb->UrbBulkOrInterruptTransfer.TransferBuffer);
-                DPRINT1("--->PipeHandle %x\n",Urb->UrbBulkOrInterruptTransfer.PipeHandle);
-                DPRINT1("---->(PVOID)&UsbDevice->EndPointDescriptor %x\n", (PVOID)&UsbDevice->ActiveInterface->EndPoints[0]->EndPointDescriptor);
-                DPRINT1("--->TransferFlags %x\n", Urb->UrbBulkOrInterruptTransfer.TransferFlags);
-
+                DPRINT("URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:\n");
+                DPRINT("--->TransferBufferLength %x\n",Urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
+                DPRINT("--->TransferBuffer %x\n",Urb->UrbBulkOrInterruptTransfer.TransferBuffer);
+                DPRINT("--->PipeHandle %x\n",Urb->UrbBulkOrInterruptTransfer.PipeHandle);
+                DPRINT("---->(PVOID)&UsbDevice->EndPointDescriptor %x\n", (PVOID)&UsbDevice->ActiveInterface->EndPoints[0]->EndPointDescriptor);
+                DPRINT("--->TransferFlags %x\n", Urb->UrbBulkOrInterruptTransfer.TransferFlags);
+                ASSERT(Urb->UrbBulkOrInterruptTransfer.TransferBuffer != NULL);
                 RtlZeroMemory(Urb->UrbBulkOrInterruptTransfer.TransferBuffer, Urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
+
                 if (UsbDevice == DeviceExtension->UsbDevices[0])
                 {
                     if (Urb->UrbBulkOrInterruptTransfer.TransferFlags & (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK))
@@ -112,10 +113,13 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
                         LONG i;
                         for (i = 0; i < 8; i++)
                         {
+                            if (i == 0){
+                            DPRINT("PortStatus %x\n", DeviceExtension->Ports[i].PortStatus);
+                            DPRINT("PortChange %x\n", DeviceExtension->Ports[i].PortChange);}
                             if (DeviceExtension->Ports[i].PortChange)
                             {
                                 DPRINT1("Inform hub driver that port %d has changed\n", i+1);
-                                ((PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] = 1 << (i + 1);
+                                ((PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] = 1 << ((i + 1) & 7);
                             }
                         }
                     }
@@ -123,8 +127,11 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
                     {
                         Urb->UrbHeader.Status = USBD_STATUS_INVALID_PARAMETER;
                         Status = STATUS_UNSUCCESSFUL;
+                        DPRINT1("Invalid transfer flags for SCE\n");
                     }
                 }
+                else
+                    DPRINT1("Interrupt Transfer not for hub\n");
                 break;
             }
             case URB_FUNCTION_GET_STATUS_FROM_DEVICE:
@@ -132,9 +139,9 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
                 DPRINT("Get Status from Device\n");
                 DPRINT("Index : %d\n", Urb->UrbControlGetStatusRequest.Index);
 
-                /* Copied from pvdrivers */
                 if (Urb->UrbControlGetStatusRequest.Index == 0)
                 {
+                    ASSERT(Urb->UrbBulkOrInterruptTransfer.TransferBuffer != NULL);
                     *(PUSHORT)Urb->UrbControlGetStatusRequest.TransferBuffer = USB_PORT_STATUS_CONNECT | USB_PORT_STATUS_ENABLE;
                 }
                 else
@@ -142,7 +149,6 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
                     DPRINT1("Uknown identifier\n");
                     Urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
                     Status = STATUS_UNSUCCESSFUL;
-                    ASSERT(FALSE);
                 }
                 break;
             }
@@ -157,7 +163,7 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
                         {
                             Urb->UrbControlDescriptorRequest.TransferBufferLength = sizeof(USB_DEVICE_DESCRIPTOR);
                         }
-
+                        ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer != NULL);
                         RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer,
                                       &UsbDevice->DeviceDescriptor,
                                       Urb->UrbControlDescriptorRequest.TransferBufferLength);
@@ -177,9 +183,10 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
                         else
                         {
                             DPRINT1("Buffer to small!!!\n");
-                            ASSERT(FALSE);
+                            //ASSERT(FALSE);
                         }
 
+                        ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer);
                         BufPtr = (PUCHAR)Urb->UrbControlDescriptorRequest.TransferBuffer;
 
                         /* Copy the Configuration Descriptor */
@@ -339,7 +346,9 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
                                 DPRINT1("Reserved!!!\n");
                             case USB_DEVICE_CLASS_HUB:
                             {
+
                                 PUSB_HUB_DESCRIPTOR UsbHubDescr = Urb->UrbControlVendorClassRequest.TransferBuffer;
+                                ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer != 0);
                                 /* FIXME: Handle more than root hub? */
                                 if(Urb->UrbControlVendorClassRequest.TransferBufferLength >= sizeof(USB_HUB_DESCRIPTOR))
                                 {
@@ -377,6 +386,7 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
 
                         if (Urb->UrbControlVendorClassRequest.Index == 1)
                         {
+                            ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer != 0);
                             ((PULONG)Urb->UrbControlVendorClassRequest.TransferBuffer)[0] = 0;
                         }
                         break;
@@ -396,7 +406,7 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
                     case USB_REQUEST_GET_STATUS:
                     {
                         DPRINT1("OTHER: USB_REQUEST_GET_STATUS for port %d\n", Urb->UrbControlVendorClassRequest.Index);
-
+                        ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer != 0);
                         ((PUSHORT)Urb->UrbControlVendorClassRequest.TransferBuffer)[0] = DeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus;
                         ((PUSHORT)Urb->UrbControlVendorClassRequest.TransferBuffer)[1] = DeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange;
                         break;
@@ -487,7 +497,6 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
                     default:
                     {
                         DPRINT1("Unknown Function Class Unknown request\n");
-                        ASSERT(FALSE);
                         break;
                     }
                 }
@@ -497,13 +506,10 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
             {
                 DPRINT1("Unhandled URB %x\n", Urb->UrbHeader.Function);
                 Urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
-                ASSERT(FALSE);
             }
 
         }
 
-        KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, oldIrql);
-
         Irp->IoStatus.Status = Status;
         Irp->IoStatus.Information = Information;
 
@@ -514,10 +520,16 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
             Urb->UrbHeader.UsbdFlags = 0;
         }
 
+        KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, oldIrql);
         IoCompleteRequest(Irp, IO_NO_INCREMENT);
         KeAcquireSpinLock(&DeviceExtension->IrpQueueLock, &oldIrql);
+
+        if (DeviceExtension->HaltQueue)
+            break;
     }
 
     KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, oldIrql);
+    if (!DeviceExtension->HaltQueue)
+        KeSetEvent(&DeviceExtension->QueueDrainedEvent, 0, FALSE);
 }
 
index d38ca6f..cf84911 100644 (file)
@@ -8,7 +8,6 @@
  */
 
 #define INITGUID
-#define NDEBUG
 
 #include "usbehci.h"
 #include <hubbusif.h>
@@ -86,40 +85,24 @@ VOID NTAPI
 UrbWorkerThread(PVOID Context)
 {
     PPDO_DEVICE_EXTENSION PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)Context;
+    NTSTATUS Status;
+    LARGE_INTEGER DueTime;
+    PVOID PollEvents[] = { (PVOID) &PdoDeviceExtension->QueueDrainedEvent, (PVOID) &PdoDeviceExtension->Timer };
 
-    while (PdoDeviceExtension->HaltUrbHandling == FALSE)
-    {
-        CompletePendingURBRequest(PdoDeviceExtension);
-        KeStallExecutionProcessor(10);
-    }
-    DPRINT1("Thread terminated\n");
-}
-
-PVOID InternalCreateUsbDevice(UCHAR DeviceNumber, ULONG Port, PUSB_DEVICE Parent, BOOLEAN Hub)
-{
-    PUSB_DEVICE UsbDevicePointer = NULL;
-    UsbDevicePointer = ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_DEVICE), USB_POOL_TAG);
+    DueTime.QuadPart = 0;
+    KeInitializeTimerEx(&PdoDeviceExtension->Timer, SynchronizationTimer);
+    KeSetTimerEx(&PdoDeviceExtension->Timer, DueTime, 100, NULL);
 
-    if (!UsbDevicePointer)
+    while (TRUE)
     {
-        DPRINT1("Out of memory\n");
-        return NULL;
-    }
-
-    RtlZeroMemory(UsbDevicePointer, sizeof(USB_DEVICE));
+        Status = KeWaitForMultipleObjects(2, PollEvents, WaitAll, Executive, KernelMode, FALSE, NULL, NULL);
 
-    if ((Hub) && (!Parent))
-    {
-        DPRINT1("This is the root hub\n");
+        if (!PdoDeviceExtension->HaltQueue)
+            KeResetEvent(&PdoDeviceExtension->QueueDrainedEvent);
+        CompletePendingURBRequest(PdoDeviceExtension);
     }
 
-    UsbDevicePointer->Address = DeviceNumber;
-    UsbDevicePointer->Port = Port;
-    UsbDevicePointer->ParentDevice = Parent;
-
-    UsbDevicePointer->IsHub = Hub;
-
-    return UsbDevicePointer;
+    DPRINT1("Thread terminated\n");
 }
 
 NTSTATUS NTAPI
@@ -147,7 +130,6 @@ PdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
             Urb = (PURB) Stack->Parameters.Others.Argument1;
             DPRINT("Header Length %d\n", Urb->UrbHeader.Length);
             DPRINT("Header Function %d\n", Urb->UrbHeader.Function);
-
             /* Queue all request for now, kernel thread will complete them */
             QueueURBRequest(PdoDeviceExtension, Irp);
             Information = 0;
@@ -163,6 +145,8 @@ PdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
         case IOCTL_INTERNAL_USB_ENABLE_PORT:
         {
             DPRINT1("IOCTL_INTERNAL_USB_ENABLE_PORT\n");
+            Information = 0;
+            Status = STATUS_SUCCESS;
             break;
         }
         case IOCTL_INTERNAL_USB_GET_BUS_INFO:
@@ -244,7 +228,18 @@ PdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
         }
         case IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION:
         {
+            PUSB_IDLE_CALLBACK_INFO CallBackInfo;
             DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION\n");
+            /* FIXME: Set Callback for safe power down */
+            CallBackInfo = Stack->Parameters.DeviceIoControl.Type3InputBuffer;
+            DPRINT1("IdleCallback %x\n", CallBackInfo->IdleCallback);
+            DPRINT1("IdleContext %x\n", CallBackInfo->IdleContext);
+
+            PdoDeviceExtension->IdleCallback = CallBackInfo->IdleCallback;
+            PdoDeviceExtension->IdleContext = CallBackInfo->IdleContext;
+
+            Information = 0;
+            Status = STATUS_SUCCESS;
             break;
         }
         default:
@@ -392,6 +387,8 @@ PdoDispatchPnp(
             RootHubDevice->DeviceDescriptor.idVendor = FdoDeviceExtension->VendorId;
             RootHubDevice->DeviceDescriptor.idProduct = FdoDeviceExtension->DeviceId;
 
+            /* FIXME: Do something better below */
+
             RootHubDevice->Configs = ExAllocatePoolWithTag(NonPagedPool,
                                                             sizeof(PVOID) * RootHubDevice->DeviceDescriptor.bNumConfigurations,
                                                             USB_POOL_TAG);
@@ -408,14 +405,9 @@ PdoDispatchPnp(
                                                             sizeof(USB_ENDPOINT),
                                                             USB_POOL_TAG);
 
-            DPRINT1("before: ActiveConfig %x\n", RootHubDevice->ActiveConfig);
             RootHubDevice->ActiveConfig = RootHubDevice->Configs[0];
-            DPRINT1("after: ActiveConfig %x\n", RootHubDevice->ActiveConfig);
-
-            DPRINT1("before: ActiveConfig->Interfaces[0] %x\n", RootHubDevice->ActiveConfig->Interfaces[0]);
             RootHubDevice->ActiveInterface = RootHubDevice->ActiveConfig->Interfaces[0];
 
-
             RtlCopyMemory(&RootHubDevice->ActiveConfig->ConfigurationDescriptor,
                           ROOTHUB2_CONFIGURATION_DESCRIPTOR,
                           sizeof(ROOTHUB2_CONFIGURATION_DESCRIPTOR));
@@ -433,6 +425,7 @@ PdoDispatchPnp(
             PdoDeviceExtension->UsbDevices[0] = RootHubDevice;
 
             /* Create a thread to handle the URB's */
+
             Status = PsCreateSystemThread(&PdoDeviceExtension->ThreadHandle,
                                           THREAD_ALL_ACCESS,
                                           NULL,
@@ -454,7 +447,8 @@ PdoDispatchPnp(
             {
                 Status = IoSetDeviceInterfaceState(&InterfaceSymLinkName, TRUE);
                 DPRINT1("Set interface state %x\n", Status);
-                if (!NT_SUCCESS(Status)) ASSERT(FALSE);
+                if (!NT_SUCCESS(Status)) 
+                    ASSERT(FALSE);
             }
 
             Status = STATUS_SUCCESS;
@@ -472,7 +466,19 @@ PdoDispatchPnp(
                     break;
                 }
                 case BusRelations:
+                {
+                    PPDO_DEVICE_EXTENSION PdoDeviceExtension;
+                    PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
                     DPRINT1("BusRelations!!!!!\n");
+
+                    /* The hub driver has created the new device object and reported to pnp, as a result the pnp manager
+                       has resent this IRP and type, so leave the next SCE request pending until a new device arrives.
+                       Is there a better way to do this */
+                    ExAcquireFastMutex(&PdoDeviceExtension->ListLock);
+                    PdoDeviceExtension->HaltQueue = TRUE;
+                    ExReleaseFastMutex(&PdoDeviceExtension->ListLock);
+                }
                 case RemovalRelations:
                 case EjectionRelations:
                 {
@@ -553,9 +559,9 @@ PdoDispatchPnp(
                 DPRINT1("Failed to create string from GUID!\n");
             }
 
-            DPRINT1("Interface GUID requested %wZ\n", &GuidString);
-            DPRINT1("QueryInterface.Size %x\n", Stack->Parameters.QueryInterface.Size);
-            DPRINT1("QueryInterface.Version %x\n", Stack->Parameters.QueryInterface.Version);
+            DPRINT("Interface GUID requested %wZ\n", &GuidString);
+            DPRINT("QueryInterface.Size %x\n", Stack->Parameters.QueryInterface.Size);
+            DPRINT("QueryInterface.Version %x\n", Stack->Parameters.QueryInterface.Version);
 
             /* Assume success */
             Status = STATUS_SUCCESS;
@@ -606,7 +612,7 @@ PdoDispatchPnp(
                 }
                 if (Stack->Parameters.QueryInterface.Version >= 6)
                 {
-                    DPRINT1("Unknown version!\n");
+                    DPRINT1("USB_BUS_INTERFACE_HUB_GUID version not supported!\n");
                 }
                 break;
             }
@@ -638,12 +644,12 @@ PdoDispatchPnp(
 
                 if (Stack->Parameters.QueryInterface.Version >= 3)
                 {
-                    DPRINT1("Not Supported!\n");
+                    DPRINT1("SB_BUS_INTERFACE_USBDI_GUID version not supported!\n");
                 }
                 break;
             }
 
-            DPRINT1("Not Supported\n");
+            DPRINT1("GUID Not Supported\n");
             Status = Irp->IoStatus.Status;
             Information = Irp->IoStatus.Information;
 
index d9a85ba..cbd1845 100644 (file)
@@ -15,7 +15,7 @@ IntializeHeadQueueForStandardRequest(PQUEUE_HEAD QueueHead,
                                            PQUEUE_TRANSFER_DESCRIPTOR *CtrlTD1,
                                            PQUEUE_TRANSFER_DESCRIPTOR *CtrlTD2,
                                            PQUEUE_TRANSFER_DESCRIPTOR *CtrlTD3,
-                                           PEHCI_SETUP_FORMAT *CtrlSetup,
+                                           PUSB_DEFAULT_PIPE_SETUP_PACKET *CtrlSetup,
                                            PVOID *CtrlData,
                                            ULONG Size)
 {
@@ -67,15 +67,15 @@ IntializeHeadQueueForStandardRequest(PQUEUE_HEAD QueueHead,
     *CtrlTD3 = (PQUEUE_TRANSFER_DESCRIPTOR) (((ULONG)(*CtrlTD2) + sizeof(QUEUE_TRANSFER_DESCRIPTOR) + 0x1F) & ~0x1F);
 
     /* Must be Page aligned */
-    *CtrlSetup = (PEHCI_SETUP_FORMAT) (( (ULONG)(*CtrlTD3) + sizeof(QUEUE_TRANSFER_DESCRIPTOR) + 0xFFF)  & ~0xFFF);
-    *CtrlData = (PUSB_DEVICE_DESCRIPTOR) (( (ULONG)(*CtrlSetup) + sizeof(EHCI_SETUP_FORMAT) + 0xFFF)  & ~0xFFF);
+    *CtrlSetup = (PUSB_DEFAULT_PIPE_SETUP_PACKET) (( (ULONG)(*CtrlTD3) + sizeof(QUEUE_TRANSFER_DESCRIPTOR) + 0xFFF)  & ~0xFFF);
+    *CtrlData = (PVOID) (( (ULONG)(*CtrlSetup) + sizeof(USB_DEFAULT_PIPE_SETUP_PACKET) + 0xFFF)  & ~0xFFF);
 
     (*CtrlTD1)->NextPointer = TERMINATE_POINTER;
     (*CtrlTD1)->AlternateNextPointer = TERMINATE_POINTER;
     (*CtrlTD1)->BufferPointer[0] = (ULONG)MmGetPhysicalAddress((PVOID) (*CtrlSetup)).LowPart;
     (*CtrlTD1)->Token.Bits.DataToggle = FALSE;
     (*CtrlTD1)->Token.Bits.InterruptOnComplete = FALSE;
-    (*CtrlTD1)->Token.Bits.TotalBytesToTransfer = sizeof(EHCI_SETUP_FORMAT);
+    (*CtrlTD1)->Token.Bits.TotalBytesToTransfer = sizeof(USB_DEFAULT_PIPE_SETUP_PACKET);
     (*CtrlTD1)->Token.Bits.ErrorCounter = 0x03;
     (*CtrlTD1)->Token.Bits.PIDCode = PID_CODE_SETUP_TOKEN;
     (*CtrlTD1)->Token.Bits.Active = TRUE;
@@ -105,46 +105,48 @@ IntializeHeadQueueForStandardRequest(PQUEUE_HEAD QueueHead,
 }
 
 BOOLEAN
-GetDeviceDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension, UCHAR Index, PUSB_DEVICE_DESCRIPTOR OutBuffer, BOOLEAN Hub)
+ExecuteControlRequest(PFDO_DEVICE_EXTENSION DeviceExtension, PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, UCHAR Address, ULONG Port, PVOID Buffer, ULONG BufferLength)
 {
-    PEHCI_SETUP_FORMAT CtrlSetup = NULL;
-    PUSB_DEVICE_DESCRIPTOR CtrlData = NULL;
+    PUSB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup = NULL;
+    PVOID CtrlData = NULL;
     PQUEUE_TRANSFER_DESCRIPTOR CtrlTD1 = NULL;
     PQUEUE_TRANSFER_DESCRIPTOR CtrlTD2 = NULL;
     PQUEUE_TRANSFER_DESCRIPTOR CtrlTD3 = NULL;
+
     PQUEUE_HEAD QueueHead;
     PEHCI_USBCMD_CONTENT UsbCmd;
     PEHCI_USBSTS_CONTEXT UsbSts;
     LONG Base;
     LONG tmp;
 
+    DPRINT1("ExecuteControlRequest: Buffer %x, Length %x\n", Buffer, BufferLength);
+
     Base = (ULONG) DeviceExtension->ResourceMemory;
 
     /* Set up the QUEUE HEAD in memory */
     QueueHead = (PQUEUE_HEAD) ((ULONG)DeviceExtension->AsyncListQueueHeadPtr);
 
+    /* Initialize the memory pointers */
     IntializeHeadQueueForStandardRequest(QueueHead,
                                          &CtrlTD1,
                                          &CtrlTD2,
                                          &CtrlTD3,
                                          &CtrlSetup,
                                          (PVOID)&CtrlData,
-                                         sizeof(USB_DEVICE_DESCRIPTOR));
+                                         BufferLength);
 
-    /* FIXME: Use defines and handle other than Device Desciptors */
-    if (Hub)
-    {
-        CtrlSetup->bmRequestType = 0x80;
-        CtrlSetup->wValue = 0x0600;
-    }
-    else
-    {
-        CtrlSetup->bmRequestType = 0x80;
-        CtrlSetup->wValue = 0x0100;
-    }
-    CtrlSetup->bRequest = 0x06;
-    CtrlSetup->wIndex = 0;
-    CtrlSetup->wLength = sizeof(USB_DEVICE_DESCRIPTOR);
+    CtrlSetup->bmRequestType._BM.Recipient = SetupPacket->bmRequestType._BM.Recipient;
+    CtrlSetup->bmRequestType._BM.Type = SetupPacket->bmRequestType._BM.Type;
+    CtrlSetup->bmRequestType._BM.Dir = SetupPacket->bmRequestType._BM.Dir;
+    CtrlSetup->bRequest = SetupPacket->bRequest;
+    CtrlSetup->wValue.LowByte = SetupPacket->wValue.LowByte;
+    CtrlSetup->wValue.HiByte = SetupPacket->wValue.HiByte;
+    CtrlSetup->wIndex.W = SetupPacket->wIndex.W;
+    CtrlSetup->wLength = SetupPacket->wLength;
+
+
+    QueueHead->EndPointCapabilities1.DeviceAddress = Address;
+    //QueueHead->EndPointCapabilities2.PortNumber = Port;
 
     tmp = READ_REGISTER_ULONG((PULONG) (Base + EHCI_USBCMD));
     UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp;
@@ -190,136 +192,15 @@ GetDeviceDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension, UCHAR Index, PUSB_DEV
             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->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);
-    DPRINT1("CtrlData->iManufacturer %x\n", CtrlData->iManufacturer);
-    DPRINT1("CtrlData->iProduct %x\n", CtrlData->iProduct);
-    DPRINT1("CtrlData->iSerialNumber %x\n", CtrlData->iSerialNumber);
-    DPRINT1("CtrlData->bNumConfigurations %x\n", CtrlData->bNumConfigurations);
-
-    /* Temporary: Remove */
-    if (CtrlData->bLength > 0)
-    {
-        /* We got valid data, try for strings */
-        UCHAR Manufacturer = CtrlData->iManufacturer;
-        UCHAR Product = CtrlData->iProduct;
-        UCHAR SerialNumber = CtrlData->iSerialNumber;
-
-        GetDeviceStringDescriptor(DeviceExtension, Manufacturer);
-        GetDeviceStringDescriptor(DeviceExtension, Product);
-        GetDeviceStringDescriptor(DeviceExtension, SerialNumber);
-    }
-
-    return TRUE;
-}
-
-BOOLEAN
-GetDeviceStringDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension, UCHAR Index)
-{
-    PEHCI_SETUP_FORMAT CtrlSetup = NULL;
-    PSTRING_DESCRIPTOR CtrlData = NULL;
-    PQUEUE_TRANSFER_DESCRIPTOR CtrlTD1 = NULL;
-    PQUEUE_TRANSFER_DESCRIPTOR CtrlTD2 = NULL;
-    PQUEUE_TRANSFER_DESCRIPTOR CtrlTD3 = NULL;
-    PQUEUE_HEAD QueueHead;
-    PEHCI_USBCMD_CONTENT UsbCmd;
-    PEHCI_USBSTS_CONTEXT UsbSts;
-    LONG Base;
-    LONG tmp;
-
-    Base = (ULONG) DeviceExtension->ResourceMemory;
-
-    /* Set up the QUEUE HEAD in memory */
-    QueueHead = (PQUEUE_HEAD) ((ULONG)DeviceExtension->AsyncListQueueHeadPtr);
-
-    IntializeHeadQueueForStandardRequest(QueueHead,
-                                         &CtrlTD1,
-                                         &CtrlTD2,
-                                         &CtrlTD3,
-                                         &CtrlSetup,
-                                         (PVOID)&CtrlData,
-                                         sizeof(STRING_DESCRIPTOR) + 256);
-
-    /* FIXME: Use defines and handle other than Device Desciptors */
-    CtrlSetup->bmRequestType = 0x80;
-    CtrlSetup->bRequest = 0x06;
-    CtrlSetup->wValue = 0x0300 | Index;
-    CtrlSetup->wIndex = 0;
-    /* 256 pulled from thin air */
-    CtrlSetup->wLength = sizeof(STRING_DESCRIPTOR) + 256;
-
-    tmp = READ_REGISTER_ULONG((PULONG) (Base + EHCI_USBCMD));
-    UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp;
-    UsbCmd->Run = FALSE;
-    WRITE_REGISTER_ULONG((PULONG) (Base + EHCI_USBCMD), tmp);
-
-    /* Wait for the controller to halt */
-    for (;;)
+    if (CtrlSetup->bmRequestType._BM.Dir == BMREQUEST_DEVICE_TO_HOST)
     {
-        KeStallExecutionProcessor(10);
-        tmp = READ_REGISTER_ULONG((PULONG)(Base + EHCI_USBSTS));
-        UsbSts = (PEHCI_USBSTS_CONTEXT)&tmp;
-        DPRINT("Waiting for Halt, USBSTS: %x\n", READ_REGISTER_ULONG ((PULONG)(Base + EHCI_USBSTS)));
-        if (UsbSts->HCHalted)
+        if ((Buffer) && (BufferLength))
         {
-            break;
+            RtlCopyMemory(Buffer, CtrlData, BufferLength);
         }
+        else
+            DPRINT1("Unable to copy data to buffer\n");
     }
 
-    /* Set to TRUE on interrupt for async completion */
-    DeviceExtension->AsyncComplete = FALSE;
-    QueueHead->QETDPointer = (ULONG) MmGetPhysicalAddress((PVOID)(CtrlTD1)).LowPart;
-
-    tmp = READ_REGISTER_ULONG((PULONG) (Base + EHCI_USBCMD));
-    UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp;
-    UsbCmd->AsyncEnable = TRUE;
-
-    WRITE_REGISTER_ULONG((PULONG)(Base + EHCI_USBCMD), tmp);
-
-    tmp = READ_REGISTER_ULONG((PULONG) (Base + EHCI_USBCMD));
-    UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp;
-
-    /* Interrupt on Async completion */
-    UsbCmd->DoorBell = TRUE;
-    UsbCmd->Run = TRUE;
-    WRITE_REGISTER_ULONG((PULONG)(Base + EHCI_USBCMD), tmp);
-
-    for (;;)
-    {
-        KeStallExecutionProcessor(10);
-        DPRINT("Waiting for completion!\n");
-        if (DeviceExtension->AsyncComplete == TRUE)
-            break;
-    }
-
-    DPRINT1("String %S\n", &CtrlData->bString);
-
     return TRUE;
 }
-
index 1554069..0f35a31 100644 (file)
@@ -9,11 +9,6 @@
 
 /* DEFINES *******************************************************************/
 #include "usbehci.h"
-#define NDEBUG
-
-/* INCLUDES *******************************************************************/
-#include <debug.h>
-
 
 static NTSTATUS NTAPI
 IrpStub(PDEVICE_OBJECT DeviceObject, PIRP Irp)
index 6d6a570..56f03b5 100644 (file)
@@ -407,11 +407,16 @@ typedef struct _PDO_DEVICE_EXTENSION
     PIRP CurrentIrp;
     HANDLE ThreadHandle;
     ULONG ChildDeviceCount;
-    BOOLEAN HaltUrbHandling;
+    BOOLEAN HaltQueue;
     PVOID CallbackContext;
     RH_INIT_CALLBACK *CallbackRoutine;
+    USB_IDLE_CALLBACK IdleCallback;
+    PVOID IdleContext;
     ULONG NumberOfPorts;
     EHCIPORTS Ports[32];
+    KTIMER Timer;
+    KEVENT QueueDrainedEvent;
+    FAST_MUTEX ListLock;
 } PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION;
 
 typedef struct _WORKITEM_DATA
@@ -459,10 +464,7 @@ NTSTATUS NTAPI
 PdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
 
 BOOLEAN
-GetDeviceDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension, UCHAR Index, PUSB_DEVICE_DESCRIPTOR OutBuffer, BOOLEAN Hub);
-
-BOOLEAN
-GetDeviceStringDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension, UCHAR Index);
+ExecuteControlRequest(PFDO_DEVICE_EXTENSION DeviceExtension, PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, UCHAR Address, ULONG Port, PVOID Buffer, ULONG BufferLength);
 
 VOID
 QueueURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension, PIRP Irp);
index 77d4b0f..4dd98f4 100644 (file)
 #include "usbehci.h"
 #include <hubbusif.h>
 #include <usbbusif.h>
-#define NDEBUG
-#include <debug.h>
+
+PVOID InternalCreateUsbDevice(UCHAR DeviceNumber, ULONG Port, PUSB_DEVICE Parent, BOOLEAN Hub)
+{
+    PUSB_DEVICE UsbDevicePointer = NULL;
+    UsbDevicePointer = ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_DEVICE), USB_POOL_TAG);
+
+    if (!UsbDevicePointer)
+    {
+        DPRINT1("Out of memory\n");
+        return NULL;
+    }
+
+    RtlZeroMemory(UsbDevicePointer, sizeof(USB_DEVICE));
+
+    if ((Hub) && (!Parent))
+    {
+        DPRINT1("This is the root hub\n");
+    }
+
+    UsbDevicePointer->Address = DeviceNumber;
+    UsbDevicePointer->Port = Port;
+    UsbDevicePointer->ParentDevice = Parent;
+
+    UsbDevicePointer->IsHub = Hub;
+
+    return UsbDevicePointer;
+}
 
 BOOLEAN
 IsHandleValid(PVOID BusContext,
@@ -57,33 +82,158 @@ CreateUsbDevice(PVOID BusContext,
                 PUSB_DEVICE_HANDLE HubDeviceHandle,
                 USHORT PortStatus, USHORT PortNumber)
 {
-    DPRINT1("CreateUsbDevice called\n");
-    DPRINT1("PortStatus %x\n", PortStatus);
-    DPRINT1("PortNumber %x\n", PortNumber);
-    *NewDevice = ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_DEVICE), USB_POOL_TAG);
+    PPDO_DEVICE_EXTENSION PdoDeviceExtension;
+    PUSB_DEVICE UsbDevice;
+    LONG i = 0;
+    PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)BusContext)->DeviceExtension;
+    DPRINT1("CreateUsbDevice: HubDeviceHandle %x, PortStatus %x, PortNumber %x\n", HubDeviceHandle, PortStatus, PortNumber);
 
+    UsbDevice = InternalCreateUsbDevice(PdoDeviceExtension->ChildDeviceCount, PortNumber, HubDeviceHandle, FALSE);
+
+    /* Add it to the list */
+    while (TRUE)
+    {
+        if (PdoDeviceExtension->UsbDevices[i] == NULL)
+        {
+            PdoDeviceExtension->UsbDevices[i] = (PUSB_DEVICE)UsbDevice;
+            PdoDeviceExtension->UsbDevices[i]->Address = i + 1;
+            PdoDeviceExtension->UsbDevices[i]->Port = PortNumber;
+            break; 
+        }
+        i++;
+    }
+
+    /* Return it */
+    *NewDevice = UsbDevice;
     return STATUS_SUCCESS;
 }
 
+/* Called when SCE reports a change */
+/* FIXME: Do something better for memory */
 NTSTATUS
 USB_BUSIFFN
 InitializeUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE DeviceHandle)
 {
     PPDO_DEVICE_EXTENSION PdoDeviceExtension;
-    LONG i;
-    DPRINT1("InitializeUsbDevice called\n");
-
+    PFDO_DEVICE_EXTENSION FdoDeviceExtension;
+    USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
+    PUSB_CONFIGURATION_DESCRIPTOR ConfigDesc;
+    PUSB_INTERFACE_DESCRIPTOR InterfaceDesc;
+    PUSB_ENDPOINT_DESCRIPTOR EndpointDesc;
+    PUSB_DEVICE UsbDevice;
+    BOOLEAN ResultOk;
+    PVOID Buffer;
+    PUCHAR Ptr;
+    LONG i, j, k;
+
+    DPRINT1("InitializeUsbDevice called, device %x\n", DeviceHandle);
     PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)BusContext)->DeviceExtension;
-    /* Find the device handle */
-    for (i = 0; i < PdoDeviceExtension->ChildDeviceCount; i++)
+    FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)PdoDeviceExtension->ControllerFdo->DeviceExtension;
+    UsbDevice = (PUSB_DEVICE) DeviceHandle;
+
+    Buffer = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, USB_POOL_TAG);
+
+    if (!Buffer)
+    {
+        DPRINT1("Out of memory\n");
+        return STATUS_NO_MEMORY;
+    }
+
+    Ptr = Buffer;
+    /* Set the device address */
+    CtrlSetup.bmRequestType._BM.Recipient = BMREQUEST_TO_DEVICE;
+    CtrlSetup.bmRequestType._BM.Type = BMREQUEST_STANDARD;
+    CtrlSetup.bmRequestType._BM.Dir = BMREQUEST_HOST_TO_DEVICE;
+    CtrlSetup.bRequest = USB_REQUEST_SET_ADDRESS;
+    CtrlSetup.wValue.W = UsbDevice->Address;
+    CtrlSetup.wIndex.W = 0;
+    CtrlSetup.wLength = 0;
+
+    ResultOk = ExecuteControlRequest(FdoDeviceExtension, &CtrlSetup, 0, 0, NULL, 0);
+
+    /* Get the Device Descriptor */
+    CtrlSetup.bmRequestType._BM.Recipient = BMREQUEST_TO_DEVICE;
+    CtrlSetup.bmRequestType._BM.Type = BMREQUEST_STANDARD;
+    CtrlSetup.bmRequestType._BM.Dir = BMREQUEST_DEVICE_TO_HOST;
+    CtrlSetup.bRequest = USB_REQUEST_GET_DESCRIPTOR;
+    CtrlSetup.wValue.LowByte = 0;
+    CtrlSetup.wValue.HiByte = USB_DEVICE_DESCRIPTOR_TYPE;
+    CtrlSetup.wIndex.W = 0;
+    CtrlSetup.wLength = sizeof(USB_DEVICE_DESCRIPTOR);
+
+    ResultOk = ExecuteControlRequest(FdoDeviceExtension, &CtrlSetup, UsbDevice->Address, UsbDevice->Port, 
+                                     &UsbDevice->DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR));
+
+    DPRINT1("bLength %x\n", UsbDevice->DeviceDescriptor.bLength);
+    DPRINT1("bDescriptorType %x\n", UsbDevice->DeviceDescriptor.bDescriptorType);
+    DPRINT1("bNumDescriptors %x\n", UsbDevice->DeviceDescriptor.bNumConfigurations);
+
+    if (UsbDevice->DeviceDescriptor.bNumConfigurations == 0)
+        return STATUS_DEVICE_DATA_ERROR;
+
+    UsbDevice->Configs = ExAllocatePoolWithTag(NonPagedPool,
+                                               sizeof(PVOID) * UsbDevice->DeviceDescriptor.bNumConfigurations,
+                                               USB_POOL_TAG);
+
+    if (!UsbDevice->Configs)
     {
-        if (DeviceHandle == PdoDeviceExtension->UsbDevices[i])
+        DPRINT1("Out of memory\n");
+        return STATUS_NO_MEMORY;
+    }
+
+    for (i = 0; i < UsbDevice->DeviceDescriptor.bNumConfigurations; i++)
+    {
+        /* Get the Device Configuration Descriptor */
+        CtrlSetup.bmRequestType._BM.Recipient = BMREQUEST_TO_DEVICE;
+        CtrlSetup.bmRequestType._BM.Type = BMREQUEST_STANDARD;
+        CtrlSetup.bmRequestType._BM.Dir = BMREQUEST_DEVICE_TO_HOST;
+        CtrlSetup.bRequest = USB_REQUEST_GET_DESCRIPTOR;
+        CtrlSetup.wValue.LowByte = 0;
+        CtrlSetup.wValue.HiByte = USB_CONFIGURATION_DESCRIPTOR_TYPE;
+        CtrlSetup.wIndex.W = 0;
+        CtrlSetup.wLength = PAGE_SIZE;
+
+        ResultOk = ExecuteControlRequest(FdoDeviceExtension, &CtrlSetup, UsbDevice->Address, UsbDevice->Port, Buffer, PAGE_SIZE);
+
+        ConfigDesc = (PUSB_CONFIGURATION_DESCRIPTOR)Ptr;
+
+        ASSERT(ConfigDesc->wTotalLength <= PAGE_SIZE);
+
+        UsbDevice->Configs[i] = ExAllocatePoolWithTag(NonPagedPool,
+                                                      sizeof(USB_CONFIGURATION) + sizeof(PVOID) * ConfigDesc->bNumInterfaces,
+                                                      USB_POOL_TAG);
+        UsbDevice->Configs[i]->Device = UsbDevice;
+        RtlCopyMemory(&UsbDevice->Configs[0]->ConfigurationDescriptor,
+                      ConfigDesc, sizeof(USB_CONFIGURATION_DESCRIPTOR));
+        Ptr += ConfigDesc->bLength;
+
+        for (j = 0; j < ConfigDesc->bNumInterfaces; j++)
         {
-            DPRINT1("Device Handle Found!\n");
-            return STATUS_SUCCESS;
+            InterfaceDesc = (PUSB_INTERFACE_DESCRIPTOR) Ptr;
+            UsbDevice->Configs[i]->Interfaces[j] = ExAllocatePoolWithTag(NonPagedPool,
+                                                                         sizeof(USB_INTERFACE) + sizeof(PVOID) * InterfaceDesc->bNumEndpoints,
+                                                                         USB_POOL_TAG);
+            RtlCopyMemory(&UsbDevice->Configs[i]->Interfaces[j]->InterfaceDescriptor,
+                          InterfaceDesc,
+                          sizeof(USB_INTERFACE_DESCRIPTOR));
+
+            Ptr += InterfaceDesc->bLength;
+
+            for (k = 0; k < InterfaceDesc->bNumEndpoints; k++)
+            {
+                EndpointDesc = (PUSB_ENDPOINT_DESCRIPTOR)Ptr;
+                UsbDevice->Configs[i]->Interfaces[j]->EndPoints[k] = ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_ENDPOINT), USB_POOL_TAG);
+                RtlCopyMemory(&UsbDevice->Configs[i]->Interfaces[j]->EndPoints[k]->EndPointDescriptor,
+                              EndpointDesc, sizeof(USB_ENDPOINT_DESCRIPTOR));
+            }
+
         }
     }
-    return STATUS_DEVICE_DATA_ERROR;
+
+    UsbDevice->ActiveConfig = UsbDevice->Configs[0];
+    UsbDevice->ActiveInterface = UsbDevice->Configs[0]->Interfaces[0];
+
+    return STATUS_SUCCESS;
 }
 
 NTSTATUS
@@ -92,10 +242,25 @@ GetUsbDescriptors(PVOID BusContext,
                   PUSB_DEVICE_HANDLE DeviceHandle,
                   PUCHAR DeviceDescriptorBuffer,
                   PULONG DeviceDescriptorBufferLength,
-                  PUCHAR ConfigurationBuffer,
+                  PUCHAR ConfigDescriptorBuffer,
                   PULONG ConfigDescriptorBufferLength)
 {
-    DPRINT1("GetUsbDescriptor called\n");
+    PUSB_DEVICE UsbDevice;
+    DPRINT1("GetUsbDescriptor %x, %d, %x, %d\n", DeviceDescriptorBuffer, DeviceDescriptorBufferLength, ConfigDescriptorBuffer, ConfigDescriptorBufferLength);
+
+    UsbDevice = (PUSB_DEVICE) DeviceHandle;
+
+    if ((DeviceDescriptorBuffer) && (DeviceDescriptorBufferLength))
+    {
+        RtlCopyMemory(DeviceDescriptorBuffer, &UsbDevice->DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR));
+        *DeviceDescriptorBufferLength = sizeof(USB_DEVICE_DESCRIPTOR);
+    }
+    if ((ConfigDescriptorBuffer) && (ConfigDescriptorBufferLength))
+    {
+        RtlCopyMemory(ConfigDescriptorBuffer, &UsbDevice->ActiveConfig->ConfigurationDescriptor, sizeof(USB_CONFIGURATION_DESCRIPTOR));
+        *ConfigDescriptorBufferLength = sizeof(USB_CONFIGURATION_DESCRIPTOR);
+    }
+
     return STATUS_SUCCESS;
 }
 
@@ -104,7 +269,7 @@ USB_BUSIFFN
 RemoveUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE DeviceHandle, ULONG Flags)
 {
     DPRINT1("RemoveUsbDevice called\n");
-    return STATUS_NOT_SUPPORTED;
+    return STATUS_SUCCESS;
 }
 
 NTSTATUS
@@ -189,6 +354,7 @@ GetControllerInformation(PVOID BusContext,
     PUSB_CONTROLLER_INFORMATION_0 ControllerInfo;
 
     DPRINT1("GetControllerInformation called\n");
+
     ControllerInfo = ControllerInformationBuffer;
 
     if (ControllerInformationBufferLength < sizeof(USB_CONTROLLER_INFORMATION_0))
@@ -267,10 +433,10 @@ GetRootHubSymbolicName(PVOID BusContext,
 {
     DPRINT1("GetRootHubSymbolicName called\n");
 
-    if (HubSymNameBufferLength < 20)
+    if (HubSymNameBufferLength < 16)
         return STATUS_UNSUCCESSFUL;
-    RtlCopyMemory(HubSymNameBuffer, L"ROOT_HUB20", HubSymNameBufferLength);
-    *HubSymNameActualLength = 20;
+    RtlCopyMemory(HubSymNameBuffer, L"ROOT_HUB", HubSymNameBufferLength);
+    *HubSymNameActualLength = 16;
 
     return STATUS_SUCCESS;
 }
@@ -292,7 +458,6 @@ Initialize20Hub(PVOID BusContext, PUSB_DEVICE_HANDLE HubDeviceHandle, ULONG TtCo
     /* FIXME: */
     /* Create the Irp Queue for SCE */
     /* Should queue be created for each device or each enpoint??? */
-
     return STATUS_SUCCESS;
 }
 
@@ -306,6 +471,17 @@ RootHubInitNotification(PVOID BusContext, PVOID CallbackContext, PRH_INIT_CALLBA
     PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)BusContext)->DeviceExtension;
     PdoDeviceExtension->CallbackContext = CallbackContext;
     PdoDeviceExtension->CallbackRoutine = CallbackRoutine;
+    if (PdoDeviceExtension->CallbackRoutine)
+    {
+        DPRINT1("Called Callbackrountine\n");
+        PdoDeviceExtension->CallbackRoutine(PdoDeviceExtension->CallbackContext);
+        DPRINT1("Done Callbackrountine\n");
+    }
+    else
+    {
+        DPRINT1("PdoDeviceExtension->CallbackRoutine is NULL!\n");
+    }
+
     return STATUS_SUCCESS;
 }
 
@@ -377,4 +553,3 @@ EnumLogEntry(PVOID BusContext, ULONG DriverTag, ULONG EnumTag, ULONG P1, ULONG P
     DPRINT1("EnumLogEntry called\n");
     return STATUS_NOT_SUPPORTED;
 }
-
index 47f8621..eff48f0 100644 (file)
@@ -5,6 +5,9 @@
 #include <usb.h>
 #include <usbbusif.h>
 
+PVOID
+InternalCreateUsbDevice(UCHAR DeviceNumber, ULONG Port, PUSB_DEVICE Parent, BOOLEAN Hub);
+
 VOID
 USB_BUSIFFN
 InterfaceReference(PVOID BusContext);
@@ -30,7 +33,7 @@ GetUsbDescriptors(PVOID BusContext,
     PUSB_DEVICE_HANDLE DeviceHandle,
     PUCHAR DeviceDescriptorBuffer,
     PULONG DeviceDescriptorBufferLength,
-    PUCHAR ConfigurationBuffer,
+    PUCHAR ConfigDescriptorBuffer,
     PULONG ConfigDescriptorBufferLength);
 
 NTSTATUS