[ros-diffs] [mjmartin] 51327: [USB\USBEHCI] - Implement ExecuteTransfer to replace SubmitTransfer. - Start implentation for BulkTransfers and needed DMA. This needs much more work to be done correctly. We will...

mjmartin at svn.reactos.org mjmartin at svn.reactos.org
Wed Apr 13 04:48:51 UTC 2011


Author: mjmartin
Date: Wed Apr 13 04:48:50 2011
New Revision: 51327

URL: http://svn.reactos.org/svn/reactos?rev=51327&view=rev
Log:
[USB\USBEHCI]
- Implement ExecuteTransfer to replace SubmitTransfer.
- Start implentation for BulkTransfers and needed DMA. This needs much more work to be done correctly. We will get to it.
- Implement URB_FUNCTION_CLASS_INTERFACE.
- Add comments.
Change 3 of 3.

Modified:
    trunk/reactos/drivers/usb/usbehci/irp.c
    trunk/reactos/drivers/usb/usbehci/pdo.c
    trunk/reactos/drivers/usb/usbehci/transfer.c
    trunk/reactos/drivers/usb/usbehci/transfer.h

Modified: trunk/reactos/drivers/usb/usbehci/irp.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/irp.c?rev=51327&r1=51326&r2=51327&view=diff
==============================================================================
--- trunk/reactos/drivers/usb/usbehci/irp.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbehci/irp.c [iso-8859-1] Wed Apr 13 04:48:50 2011
@@ -70,12 +70,16 @@
 NTSTATUS HandleUrbRequest(PPDO_DEVICE_EXTENSION PdoDeviceExtension, PIRP Irp)
 {
     NTSTATUS Status = STATUS_UNSUCCESSFUL;
+    USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
     ULONG_PTR Information = 0;
     PIO_STACK_LOCATION Stack;
     PUSB_DEVICE UsbDevice = NULL;
+    PEHCI_HOST_CONTROLLER hcd;
     URB *Urb;
     PFDO_DEVICE_EXTENSION FdoDeviceExtension;
     FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) PdoDeviceExtension->ControllerFdo->DeviceExtension;
+
+    hcd = &FdoDeviceExtension->hcd;
 
     Stack = IoGetCurrentIrpStackLocation(Irp);
     ASSERT(Stack);
@@ -105,16 +109,62 @@
     {
         case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
         {
-            DPRINT1("URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER UsbDevice %x\n", UsbDevice);
+            PUSB_ENDPOINT_DESCRIPTOR EndPointDesc;
+            int i;
+            
+            for (i = 0; i < UsbDevice->ActiveInterface->InterfaceDescriptor.bNumEndpoints; i++)
+            {
+                EndPointDesc = (PUSB_ENDPOINT_DESCRIPTOR)&UsbDevice->ActiveInterface->EndPoints[i]->EndPointDescriptor;
+                DPRINT("EndPoint %d Handle %x\n", i, &UsbDevice->ActiveInterface->EndPoints[i]->EndPointDescriptor);
+                DPRINT("bmAttributes %x\n", EndPointDesc->bmAttributes);
+                DPRINT("EndPoint is transfer type %x\n", EndPointDesc->bmAttributes & 0x0F);
+            }
+            DPRINT("UsbDevice %x, Handle %x\n", UsbDevice, Urb->UrbBulkOrInterruptTransfer.PipeHandle);
             if (&UsbDevice->ActiveInterface->EndPoints[0]->EndPointDescriptor != Urb->UrbBulkOrInterruptTransfer.PipeHandle)
             {
-                DPRINT1("Invalid Parameter, Expected EndPointDescriptor of %x, but got %x\n", &UsbDevice->ActiveInterface->EndPoints[0]->EndPointDescriptor, Urb->UrbBulkOrInterruptTransfer.PipeHandle);
-                Status = STATUS_INVALID_PARAMETER;
+                DPRINT("HubDevice %x, UsbDevice %x\n", PdoDeviceExtension->UsbDevices[0], UsbDevice);
+                if (Urb->UrbBulkOrInterruptTransfer.TransferFlags & USBD_TRANSFER_DIRECTION_IN)
+                    DPRINT1("USBD_TRANSFER_DIRECTION_IN\n");
+                if (Urb->UrbBulkOrInterruptTransfer.TransferFlags & USBD_TRANSFER_DIRECTION_OUT)
+                    DPRINT1("USBD_TRANSFER_DIRECTION_OUT\n");
+                if (Urb->UrbBulkOrInterruptTransfer.TransferFlags & USBD_SHORT_TRANSFER_OK)
+                    DPRINT1("USBD_SHORT_TRANSFER_OK\n");
+                EndPointDesc = (PUSB_ENDPOINT_DESCRIPTOR)Urb->UrbBulkOrInterruptTransfer.PipeHandle;
+                DPRINT("EndPoint is transfer type %x\n", EndPointDesc->bmAttributes & 0x0F);
+                DPRINT("Endpoint Address %x\n", EndPointDesc->bEndpointAddress & 0x0F);
+                if ((EndPointDesc->bmAttributes & 0x0F) == USB_ENDPOINT_TYPE_BULK)
+                {
+                    IoMarkIrpPending(Irp);
+                    Status = STATUS_PENDING;
+
+                    ExecuteTransfer(FdoDeviceExtension->DeviceObject,
+                                    UsbDevice,
+                                    Urb->UrbBulkOrInterruptTransfer.PipeHandle,
+                                    NULL,
+                                    Urb->UrbBulkOrInterruptTransfer.TransferFlags,
+                                    Urb->UrbBulkOrInterruptTransfer.TransferBuffer ?
+                                        Urb->UrbBulkOrInterruptTransfer.TransferBuffer : 
+                                        (PVOID)Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL,
+                                    Urb->UrbBulkOrInterruptTransfer.TransferBuffer ?
+                                        Urb->UrbBulkOrInterruptTransfer.TransferBufferLength : 0,
+                                    Irp);
+                }
+                else
+                {
+                    DPRINT1("Transfer Type not implemented yet!\n");
+                    /* FAKE IT */
+                    Status = STATUS_SUCCESS;
+                }
+
+                break;
+            }
+            if (!Urb->UrbBulkOrInterruptTransfer.TransferBuffer)
+            {
+                DPRINT1("TransferBuffer is NULL!\n");
                 ASSERT(FALSE);
                 break;
             }
 
-            ASSERT(Urb->UrbBulkOrInterruptTransfer.TransferBuffer != NULL);
             RtlZeroMemory(Urb->UrbBulkOrInterruptTransfer.TransferBuffer, Urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
 
             if (UsbDevice == PdoDeviceExtension->UsbDevices[0])
@@ -122,9 +172,9 @@
                 if (Urb->UrbBulkOrInterruptTransfer.TransferFlags & (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK))
                 {
                     LONG i;
-                    for (i = 0; i < PdoDeviceExtension->NumberOfPorts; i++)
-                    {
-                        if (PdoDeviceExtension->Ports[i].PortChange)
+                    for (i = 0; i < hcd->ECHICaps.HCSParams.PortCount; i++)
+                    {
+                        if (hcd->Ports[i].PortChange)
                         {
                             DPRINT1("Inform hub driver that port %d has changed\n", i+1);
                             ((PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] = 1 << ((i + 1) & 7);
@@ -177,10 +227,7 @@
                     }
                     if (UsbDevice == PdoDeviceExtension->UsbDevices[0])
                     {
-                        DPRINT1("ROOTHUB!\n");
                         BufPtr = (PUCHAR)Urb->UrbControlDescriptorRequest.TransferBuffer;
-
-                        DPRINT1("Length %x\n", Urb->UrbControlDescriptorRequest.TransferBufferLength);
 
                         /* Copy the Device Descriptor */
                         RtlCopyMemory(BufPtr, &UsbDevice->DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR));
@@ -193,11 +240,17 @@
                     BuildSetupPacketFromURB(&FdoDeviceExtension->hcd, Urb, &CtrlSetup);
                     IoMarkIrpPending(Irp);
                     Status = STATUS_PENDING;
-                    SubmitControlTransfer(&FdoDeviceExtension->hcd,
-                                          &CtrlSetup,
-                                          Urb->UrbControlDescriptorRequest.TransferBuffer,
-                                          Urb->UrbControlDescriptorRequest.TransferBufferLength,
-                                          Irp);
+                    ExecuteTransfer(FdoDeviceExtension->DeviceObject,
+                                    UsbDevice,
+                                    0,
+                                    &CtrlSetup,
+                                    0,
+                                    Urb->UrbControlDescriptorRequest.TransferBuffer ?
+                                        Urb->UrbControlDescriptorRequest.TransferBuffer : 
+                                        (PVOID)Urb->UrbControlDescriptorRequest.TransferBufferMDL,
+                                    Urb->UrbControlDescriptorRequest.TransferBuffer ?
+                                        Urb->UrbControlDescriptorRequest.TransferBufferLength : 0,
+                                    Irp);
                     break;
                 }
                 case USB_CONFIGURATION_DESCRIPTOR_TYPE:
@@ -270,12 +323,17 @@
                     BuildSetupPacketFromURB(&FdoDeviceExtension->hcd, Urb, &CtrlSetup);
                     IoMarkIrpPending(Irp);
                     Status = STATUS_PENDING;
-
-                    SubmitControlTransfer(&FdoDeviceExtension->hcd,
-                                          &CtrlSetup,
-                                          Urb->UrbControlDescriptorRequest.TransferBuffer,
-                                          Urb->UrbControlDescriptorRequest.TransferBufferLength,
-                                          Irp);
+                    ExecuteTransfer(FdoDeviceExtension->DeviceObject,
+                                    UsbDevice,
+                                    0,
+                                    &CtrlSetup,
+                                    0,
+                                    Urb->UrbControlDescriptorRequest.TransferBuffer ?
+                                        Urb->UrbControlDescriptorRequest.TransferBuffer : 
+                                        (PVOID)Urb->UrbControlDescriptorRequest.TransferBufferMDL,
+                                    Urb->UrbControlDescriptorRequest.TransferBuffer ?
+                                        Urb->UrbControlDescriptorRequest.TransferBufferLength : 0,
+                                    Irp);
                     break;
                 }
                 default:
@@ -290,17 +348,17 @@
             PUSBD_INTERFACE_INFORMATION InterfaceInfo;
             LONG iCount, pCount;
 
-            DPRINT1("Selecting Configuration\n");
-            DPRINT1("ConfigurationHandle %x\n",Urb->UrbSelectConfiguration.ConfigurationHandle);
+            DPRINT("Selecting Configuration\n");
+            DPRINT("ConfigurationHandle %x\n",Urb->UrbSelectConfiguration.ConfigurationHandle);
+
             if (Urb->UrbSelectConfiguration.ConfigurationDescriptor)
             {
                 Urb->UrbSelectConfiguration.ConfigurationHandle = &UsbDevice->ActiveConfig->ConfigurationDescriptor;
-                DPRINT1("ConfigHandle %x\n", Urb->UrbSelectConfiguration.ConfigurationHandle);
-                ASSERT(FALSE);
+                DPRINT("ConfigHandle %x\n", Urb->UrbSelectConfiguration.ConfigurationHandle);
                 InterfaceInfo = &Urb->UrbSelectConfiguration.Interface;
 
-                DPRINT1("Length %x\n", InterfaceInfo->Length);
-                DPRINT1("NumberOfPipes %x\n", InterfaceInfo->NumberOfPipes);
+                DPRINT("Length %x\n", InterfaceInfo->Length);
+                DPRINT("NumberOfPipes %x\n", InterfaceInfo->NumberOfPipes);
 
                 for (iCount = 0; iCount < Urb->UrbSelectConfiguration.ConfigurationDescriptor->bNumInterfaces; iCount++)
                 {
@@ -324,6 +382,29 @@
                     InterfaceInfo = (PUSBD_INTERFACE_INFORMATION)((PUCHAR)InterfaceInfo + InterfaceInfo->Length);
                     if (InterfaceInfo->Length == 0) break;
                 }
+                
+                if (UsbDevice != PdoDeviceExtension->UsbDevices[0])
+                {
+                    DPRINT("Setting Configuration!\n");
+                    BuildSetupPacketFromURB(&FdoDeviceExtension->hcd, Urb, &CtrlSetup);
+                    IoMarkIrpPending(Irp);
+                    Status = STATUS_PENDING;
+                    DPRINT1("Input Buffer %x, MDL %x\n", Urb->UrbBulkOrInterruptTransfer.TransferBuffer, (PVOID)Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL);
+
+                    ExecuteTransfer(FdoDeviceExtension->DeviceObject,
+                                    UsbDevice,
+                                    0,
+                                    &CtrlSetup,
+                                    0,
+                                    NULL,
+                                    0,
+                                    Irp);
+                    break;
+                }
+                else
+                {
+                    DPRINT1("Hub only has one configuration.\n");
+                }
             }
             else
             {
@@ -334,7 +415,6 @@
         }
         case URB_FUNCTION_SELECT_INTERFACE:
         {
-            USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
             PUSBD_INTERFACE_INFORMATION InterfaceInfo;
             int i;
 
@@ -353,12 +433,14 @@
             BuildSetupPacketFromURB(&FdoDeviceExtension->hcd, Urb, &CtrlSetup);
             IoMarkIrpPending(Irp);
             Status = STATUS_PENDING;
-
-            SubmitControlTransfer(&FdoDeviceExtension->hcd,
-                                  &CtrlSetup,
-                                  NULL,
-                                  0,
-                                  Irp);
+            ExecuteTransfer(FdoDeviceExtension->DeviceObject,
+                            UsbDevice,
+                            0,
+                            &CtrlSetup,
+                            0,
+                            NULL,
+                            0,
+                            Irp);
             break;
         }
         case URB_FUNCTION_CLASS_DEVICE:
@@ -425,7 +507,6 @@
                             }
                             else
                             {
-                                /* FIXME: Handle this correctly */
                                 UsbHubDescr->bDescriptorLength = sizeof(USB_HUB_DESCRIPTOR);
                                 UsbHubDescr->bDescriptorType = 0x29;
                                 break;
@@ -433,7 +514,7 @@
                             DPRINT1("USB_DEVICE_CLASS_HUB request\n");
                             UsbHubDescr->bDescriptorLength = sizeof(USB_HUB_DESCRIPTOR);
                             UsbHubDescr->bDescriptorType = 0x29;
-                            UsbHubDescr->bNumberOfPorts = PdoDeviceExtension->NumberOfPorts;
+                            UsbHubDescr->bNumberOfPorts = hcd->ECHICaps.HCSParams.PortCount;
                             UsbHubDescr->wHubCharacteristics = 0x0012;
                             UsbHubDescr->bPowerOnToPowerGood = 0x01;
                             UsbHubDescr->bHubControlCurrent = 0x00;
@@ -480,10 +561,10 @@
                     DPRINT("USB_REQUEST_GET_STATUS Port %d\n", Urb->UrbControlVendorClassRequest.Index);
 
                     ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer != 0);
-                    DPRINT("PortStatus %x\n", PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus);
-                    DPRINT("PortChange %x\n", PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange);
-                    ((PUSHORT)Urb->UrbControlVendorClassRequest.TransferBuffer)[0] = PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus;
-                    ((PUSHORT)Urb->UrbControlVendorClassRequest.TransferBuffer)[1] = PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange;
+                    DPRINT("PortStatus %x\n", hcd->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus);
+                    DPRINT("PortChange %x\n", hcd->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange);
+                    ((PUSHORT)Urb->UrbControlVendorClassRequest.TransferBuffer)[0] = hcd->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus;
+                    ((PUSHORT)Urb->UrbControlVendorClassRequest.TransferBuffer)[1] = hcd->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange;
                     break;
                 }
                 case USB_REQUEST_CLEAR_FEATURE:
@@ -492,12 +573,12 @@
                     {
                         case C_PORT_CONNECTION:
                             DPRINT("C_PORT_CONNECTION\n");
-                            PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange &= ~USB_PORT_STATUS_CONNECT;
+                            hcd->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange &= ~USB_PORT_STATUS_CONNECT;
                             break;
                         case C_PORT_RESET:
                             DPRINT("C_PORT_RESET\n");
-                            PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange &= ~USB_PORT_STATUS_RESET;
-                            PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus |= USB_PORT_STATUS_ENABLE;
+                            hcd->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange &= ~USB_PORT_STATUS_RESET;
+                            hcd->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus |= USB_PORT_STATUS_ENABLE;
                             break;
                         default:
                             DPRINT("Unknown Value for Clear Feature %x \n", Urb->UrbControlVendorClassRequest.Value);
@@ -507,46 +588,49 @@
                 }
                 case USB_REQUEST_SET_FEATURE:
                 {
-                    DPRINT("USB_REQUEST_SET_FEATURE Port %d, value %x\n", Urb->UrbControlVendorClassRequest.Index,
+                    DPRINT1("USB_REQUEST_SET_FEATURE Port %d, value %x\n", Urb->UrbControlVendorClassRequest.Index,
                         Urb->UrbControlVendorClassRequest.Value);
 
                     switch(Urb->UrbControlVendorClassRequest.Value)
                     {
                         case PORT_RESET:
                         {
-                            DPRINT("Port Reset %d\n", Urb->UrbControlVendorClassRequest.Index-1);
-                            PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange |= USB_PORT_STATUS_RESET;
-                            PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus &= ~USB_PORT_STATUS_ENABLE;
-                            ResetPort(&FdoDeviceExtension->hcd, Urb->UrbControlVendorClassRequest.Index-1);
+                            DPRINT1("Port Reset %d\n", Urb->UrbControlVendorClassRequest.Index-1);
+                            hcd->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange |= USB_PORT_STATUS_RESET;
+                            hcd->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus &= ~USB_PORT_STATUS_ENABLE;
+                            ResetPort(hcd, Urb->UrbControlVendorClassRequest.Index-1);
                             break;
                         }
                         case PORT_ENABLE:
                         {
-                            DPRINT("PORT_ENABLE not implemented\n");
+                            DPRINT1("PORT_ENABLE not implemented\n");
                             break;
                         }
                         case PORT_POWER:
                         {
-                            DPRINT("PORT_POWER not implemented\n");
+                            DPRINT1("PORT_POWER not implemented\n");
                             break;
                         }
                         default:
                         {
-                            DPRINT("Unknown Set Feature!\n");
-                            break;
-                        }
-                    }
-
-                    if (!(PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus & 0x8000))
+                            DPRINT1("Unknown Set Feature!\n");
+                            break;
+                        }
+                    }
+
+                    if (!(hcd->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus & 0x8000))
+                    {
+                        DPRINT1("------ PortStatus %x\n", hcd->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus);
+                        DPRINT1("Calling CompletePendingURBRequest\n");
+                        
                         CompletePendingURBRequest(PdoDeviceExtension);
-
+                    }
 
                     break;
                 }
                 case USB_REQUEST_SET_ADDRESS:
                 {
                     DPRINT1("USB_REQUEST_SET_ADDRESS\n");
-                    ASSERT(FALSE);
                     break;
                 }
                 case USB_REQUEST_GET_DESCRIPTOR:
@@ -606,7 +690,35 @@
         }
         case URB_FUNCTION_CLASS_INTERFACE:
         {
+            USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
             DPRINT1("URB_FUNCTION_CLASS_INTERFACE\n");
+            DPRINT1("TransferFlags %x\n", Urb->UrbControlVendorClassRequest.TransferFlags);
+            DPRINT1("TransferBufferLength %x\n", Urb->UrbControlVendorClassRequest.TransferBufferLength);
+            DPRINT1("TransferBuffer %x\n", Urb->UrbControlVendorClassRequest.TransferBuffer);
+            DPRINT1("TransferBufferMDL %x\n", Urb->UrbControlVendorClassRequest.TransferBufferMDL);
+            DPRINT1("RequestTypeReservedBits %x\n", Urb->UrbControlVendorClassRequest.RequestTypeReservedBits);
+            DPRINT1("Request %x\n", Urb->UrbControlVendorClassRequest.Request);
+            DPRINT1("Value %x\n", Urb->UrbControlVendorClassRequest.Value);
+            DPRINT1("Index %x\n", Urb->UrbControlVendorClassRequest.Index);
+            CtrlSetup.bmRequestType.B = 0xa1; //FIXME: Const.
+            CtrlSetup.bRequest = Urb->UrbControlVendorClassRequest.Request;
+            CtrlSetup.wValue.W = Urb->UrbControlVendorClassRequest.Value;
+            CtrlSetup.wIndex.W = Urb->UrbControlVendorClassRequest.Index;
+            CtrlSetup.wLength = Urb->UrbControlVendorClassRequest.TransferBufferLength;
+            
+            IoMarkIrpPending(Irp);
+            Status = STATUS_PENDING;
+            ExecuteTransfer(FdoDeviceExtension->DeviceObject,
+                            UsbDevice,
+                            0,
+                            &CtrlSetup,
+                            0,
+                            Urb->UrbControlVendorClassRequest.TransferBuffer ?
+                                Urb->UrbControlVendorClassRequest.TransferBuffer : 
+                                (PVOID)Urb->UrbControlVendorClassRequest.TransferBufferMDL,
+                            Urb->UrbControlVendorClassRequest.TransferBuffer ?
+                                Urb->UrbControlVendorClassRequest.TransferBufferLength : 0,
+                            Irp);
             break;
         }
         default:
@@ -632,8 +744,9 @@
 
     if (IsListEmpty(&DeviceExtension->IrpQueue))
     {
-        DPRINT1("There should have been one SCE request pending\n");
+        DPRINT1("There should have been one SCE request pending. Did the usbhub driver load?\n");
         KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, oldIrql);
+        ASSERT(FALSE);
         return;
     }
     NextIrp = RemoveHeadList(&DeviceExtension->IrpQueue);

Modified: trunk/reactos/drivers/usb/usbehci/pdo.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/pdo.c?rev=51327&r1=51326&r2=51327&view=diff
==============================================================================
--- trunk/reactos/drivers/usb/usbehci/pdo.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbehci/pdo.c [iso-8859-1] Wed Apr 13 04:48:50 2011
@@ -47,12 +47,8 @@
     0x01,       /* bNumInterfaces; (1) */
     0x23,       /* bConfigurationValue; */
     0x00,       /* iConfiguration; */
-    0x40,       /* bmAttributes; 
-    Bit 7: must be set,
-        6: Self-powered,
-        5: Remote wakeup,
-        4..0: reserved */
-    0x00       /* MaxPower; */
+    0x40,       /* bmAttributes; */
+    0x00        /* MaxPower; */
 };
 
 const UCHAR ROOTHUB2_INTERFACE_DESCRIPTOR [] =
@@ -66,7 +62,7 @@
     0x09,       /* bInterfaceClass; HUB_CLASSCODE */
     0x01,       /* bInterfaceSubClass; */
     0x00,       /* bInterfaceProtocol: */
-    0x00       /* iInterface; */
+    0x00        /* iInterface; */
 };
 
 const UCHAR ROOTHUB2_ENDPOINT_DESCRIPTOR [] =
@@ -88,12 +84,14 @@
     PIO_STACK_LOCATION Stack = NULL;
     NTSTATUS Status = STATUS_UNSUCCESSFUL;
     ULONG_PTR Information = 0;
+    PEHCI_HOST_CONTROLLER hcd;
 
     PdoDeviceExtension = (PPDO_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
     FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) PdoDeviceExtension->ControllerFdo->DeviceExtension;
 
     ASSERT(PdoDeviceExtension->Common.IsFdo == FALSE);
 
+    hcd = &FdoDeviceExtension->hcd;
     Stack =  IoGetCurrentIrpStackLocation(Irp);
 
     switch(Stack->Parameters.DeviceIoControl.IoControlCode)
@@ -108,13 +106,18 @@
 
             UsbDevice = Urb->UrbHeader.UsbdDeviceHandle;
 
+            /* If there was no device passed then this URB is for the RootHub */
             if (UsbDevice == NULL)
                 UsbDevice = PdoDeviceExtension->UsbDevices[0];
 
+            /* Check if it is a Status Change Endpoint (SCE). The Hub Driver sends this request and miniports mark the IRP pending
+               if there is no changes on any of the ports. When the DPC of miniport routine detects changes this IRP will be completed.
+               Based on XEN PV Usb Drivers */
+
             if ((Urb->UrbHeader.Function == URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER) &&
                 (UsbDevice == PdoDeviceExtension->UsbDevices[0]))
             {
-                DPRINT1("URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER on SCE\n");
+                DPRINT("URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER on SCE\n");
                 if (Urb->UrbBulkOrInterruptTransfer.PipeHandle != &UsbDevice->ActiveInterface->EndPoints[0]->EndPointDescriptor)
                 {
                     DPRINT1("PipeHandle doesnt match SCE PipeHandle\n");
@@ -123,12 +126,23 @@
                 /* Queue the Irp first */
                 QueueURBRequest(PdoDeviceExtension, Irp);
 
-                /* Check if there is any connected devices */
-                for (i = 0; i < PdoDeviceExtension->NumberOfPorts; i++)
-                {
-                    if (PdoDeviceExtension->Ports[i].PortChange == 0x01)
+                /* Check for port changes */
+                if (EnumControllerPorts(hcd) == FALSE)
+                {
+                    DPRINT("No port change\n");
+                    Status = STATUS_PENDING;
+                    IoMarkIrpPending(Irp);
+                    break;
+                }
+
+                /* If we reached this point then port status has changed, so check
+                   which port */
+                for (i = 0; i < hcd->ECHICaps.HCSParams.PortCount; i++)
+                {
+                    if (hcd->Ports[i].PortChange == 0x01)
                     {
-                        DPRINT1("Inform hub driver that port %d has changed\n", i+1);
+                        DPRINT1("On SCE request: Inform hub driver that port %d has changed\n", i+1);
+                        ASSERT(FALSE);
                         ((PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] = 1 << ((i + 1) & 7);
                         Information = 0;
                         Status = STATUS_SUCCESS;
@@ -143,15 +157,11 @@
                     }
                 }
                 if (Status == STATUS_SUCCESS) break;
-                DPRINT1("Queueing IRP\n");
+
                 IoMarkIrpPending(Irp);
                 Status = STATUS_PENDING;
                 break;
             }
-            else
-            {
-                DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_URB send to device %x\n", UsbDevice);
-            }
 
             Status = HandleUrbRequest(PdoDeviceExtension, Irp);
 
@@ -186,7 +196,7 @@
         }
         case IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE:
         {
-            DPRINT("Ehci: IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE %x\n", Stack->Parameters.Others.Argument2);
+            DPRINT1("Ehci: IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE %x\n", Stack->Parameters.Others.Argument2);
             if (Stack->Parameters.Others.Argument1)
             {
                 /* Return the root hubs devicehandle */
@@ -202,12 +212,12 @@
         }
         case IOCTL_INTERNAL_USB_GET_HUB_COUNT:
         {
-            DPRINT("Ehci: IOCTL_INTERNAL_USB_GET_HUB_COUNT %x\n", IOCTL_INTERNAL_USB_GET_HUB_COUNT);
+            DPRINT1("Ehci: IOCTL_INTERNAL_USB_GET_HUB_COUNT %x\n", IOCTL_INTERNAL_USB_GET_HUB_COUNT);
             ASSERT(Stack->Parameters.Others.Argument1 != NULL);
             if (Stack->Parameters.Others.Argument1)
             {
-                /* FIXME: Determine the number of hubs between the usb device and root hub */
-                DPRINT1("RootHubCount %x\n", *(PULONG)Stack->Parameters.Others.Argument1);
+                /* FIXME: Determine the number of hubs between the usb device and root hub. 
+                   For now we have at least one. */
                 *(PULONG)Stack->Parameters.Others.Argument1 = 1;
             }
             Status = STATUS_SUCCESS;
@@ -235,15 +245,14 @@
         }
         case IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO:
         {
-            DPRINT("Ehci: IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO Arg1 %x, Arg2 %x\n", Stack->Parameters.Others.Argument1, Stack->Parameters.Others.Argument2);
+            DPRINT("IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO\n");
+            /* DDK documents that both the PDO and FDO are returned. However, while writing the UsbHub driver it was determine
+               that this was not the case. Windows usbehci driver gives the Pdo in both Arguments. Which makes sense as upper level
+               drivers should not be communicating with FDO. */
             if (Stack->Parameters.Others.Argument1)
                 *(PVOID *)Stack->Parameters.Others.Argument1 = FdoDeviceExtension->Pdo;
-
-            /* Windows usbehci driver gives the Pdo in both Arguments. */
             if (Stack->Parameters.Others.Argument2)
-                //*(PVOID *)Stack->Parameters.Others.Argument2 = IoGetAttachedDeviceReference(FdoDeviceExtension->DeviceObject);
                 *(PVOID *)Stack->Parameters.Others.Argument2 = FdoDeviceExtension->Pdo;
-
             Information = 0;
             Status = STATUS_SUCCESS;
             break;
@@ -254,8 +263,6 @@
             DPRINT1("Ehci: 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;
@@ -300,6 +307,7 @@
         }
         case BusQueryHardwareIDs:
         {
+            /* FIXME: Build from Device Vendor and Device ID */
             Index += swprintf(&Buffer[Index], L"USB\\ROOT_HUB20&VID8086&PID265C&REV0000") + 1;
             Index += swprintf(&Buffer[Index], L"USB\\ROOT_HUB20&VID8086&PID265C") + 1;
             Index += swprintf(&Buffer[Index], L"USB\\ROOT_HUB20") + 1;
@@ -388,7 +396,6 @@
             PPDO_DEVICE_EXTENSION PdoDeviceExtension;
             PFDO_DEVICE_EXTENSION FdoDeviceExtension;
             UNICODE_STRING InterfaceSymLinkName;
-            LONG i;
 
             DPRINT1("Ehci: PDO StartDevice\n");
             PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
@@ -397,15 +404,6 @@
             /* Create the root hub */
             RootHubDevice = InternalCreateUsbDevice(1, 0, NULL, TRUE);
 
-            for (i = 0; i < PdoDeviceExtension->NumberOfPorts; i++)
-            {
-                PdoDeviceExtension->Ports[i].PortStatus = 0x8000;
-                PdoDeviceExtension->Ports[i].PortChange = 0;
-
-                if (!FdoDeviceExtension->hcd.ECHICaps.HCSParams.PortPowerControl)
-                    PdoDeviceExtension->Ports[i].PortStatus |= USB_PORT_STATUS_POWER;
-            }
-
             RtlCopyMemory(&RootHubDevice->DeviceDescriptor,
                           ROOTHUB2_DEVICE_DESCRIPTOR,
                           sizeof(ROOTHUB2_DEVICE_DESCRIPTOR));
@@ -413,7 +411,8 @@
             RootHubDevice->DeviceDescriptor.idVendor = FdoDeviceExtension->VendorId;
             RootHubDevice->DeviceDescriptor.idProduct = FdoDeviceExtension->DeviceId;
 
-            /* FIXME: Do something better below */
+            /* Here config, interfaces and descriptors are stored. This was duplicated from XEN PV Usb Drivers implementation.
+               Not sure that it is really needed as the information can be queueried from the device. */
 
             RootHubDevice->Configs = ExAllocatePoolWithTag(NonPagedPool,
                                                             sizeof(PVOID) * RootHubDevice->DeviceDescriptor.bNumConfigurations,
@@ -483,11 +482,11 @@
                     PPDO_DEVICE_EXTENSION PdoDeviceExtension;
                     PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
 
-                    DPRINT1("BusRelations!!!!!\n");
+                    DPRINT("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 */
+                       has sent 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);
@@ -531,7 +530,7 @@
             DeviceCapabilities->UINumber = 0;
             DeviceCapabilities->DeviceD2 = 1;
 
-             /* FIXME */
+             /* FIXME: Verify these settings are correct */
             DeviceCapabilities->HardwareDisabled = FALSE;
             //DeviceCapabilities->NoDisplayInUI = FALSE;
             DeviceCapabilities->DeviceState[0] = PowerDeviceD0;

Modified: trunk/reactos/drivers/usb/usbehci/transfer.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/transfer.c?rev=51327&r1=51326&r2=51327&view=diff
==============================================================================
--- trunk/reactos/drivers/usb/usbehci/transfer.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbehci/transfer.c [iso-8859-1] Wed Apr 13 04:48:50 2011
@@ -7,9 +7,20 @@
  *              Michael Martin (michael.martin at reactos.org)
  */
 
+/* All QueueHeads, Descriptors and pipe setup packets used by control transfers are allocated from common buffer.
+   The routines in physmem manages this buffer. Each allocation is aligned to 32bits, which is requirement of USB 2.0. */
+
 #include "transfer.h"
 #include <debug.h>
 
+
+typedef struct _MAPREGISTERCALLBACKINFO
+{
+    PVOID MapRegisterBase;
+    KEVENT Event;
+}MAPREGISTERCALLBACKINFO, *PMAPREGISTERCALLBACKINFO;
+
+/* Fills CtrlSetup parameter with values based on Urb */
 VOID
 BuildSetupPacketFromURB(PEHCI_HOST_CONTROLLER hcd, PURB Urb, PUSB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup)
 {
@@ -76,6 +87,7 @@
 
     /* SET CONFIG */
         case URB_FUNCTION_SELECT_CONFIGURATION:
+            DPRINT1("Bulding data for Select Config\n");
             CtrlSetup->bRequest = USB_REQUEST_SET_CONFIGURATION;
             CtrlSetup->wValue.W = Urb->UrbSelectConfiguration.ConfigurationDescriptor->bConfigurationValue;
             CtrlSetup->wIndex.W = 0;
@@ -131,18 +143,86 @@
     }
 }
 
-BOOLEAN
-SubmitControlTransfer(PEHCI_HOST_CONTROLLER hcd,
-                      PUSB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup,
-                      PVOID TransferBuffer,
-                      ULONG TransferBufferLength,
-                      PIRP IrpToComplete)
+/* Build a Bulk Transfer with a max transfer of 3 descriptors which each has 5 pointers to one page of memory, paged align of course */
+PQUEUE_HEAD
+BuildBulkTransfer(PEHCI_HOST_CONTROLLER hcd,
+                   ULONG DeviceAddress,
+                   USBD_PIPE_HANDLE PipeHandle,
+                   UCHAR PidDirection,
+                   PMDL pMdl,
+                   BOOLEAN FreeMdl)
 {
     PQUEUE_HEAD QueueHead;
     PQUEUE_TRANSFER_DESCRIPTOR Descriptor[3];
-    ULONG MdlPhysicalAddr;
-    PKEVENT Event = NULL;
-    PMDL pMdl = NULL;
+    ULONG MdlByteCount = MmGetMdlByteCount(pMdl);
+    ULONG NeededDescriptorCount = 1;
+    int i;
+
+    QueueHead = CreateQueueHead(hcd);
+    QueueHead->EndPointCharacteristics.DeviceAddress = DeviceAddress;
+
+    if (PipeHandle)
+    {
+        QueueHead->EndPointCharacteristics.EndPointNumber = ((PUSB_ENDPOINT_DESCRIPTOR)PipeHandle)->bEndpointAddress & 0x0F;
+        QueueHead->EndPointCharacteristics.MaximumPacketLength = ((PUSB_ENDPOINT_DESCRIPTOR)PipeHandle)->wMaxPacketSize;
+    }
+    
+    QueueHead->FreeMdl = FreeMdl;
+    QueueHead->Mdl = pMdl;
+
+    /* FIXME: This is totally screwed */
+    /* Calculate how many descriptors would be needed to transfer this buffer */
+    if (pMdl)
+    {
+        if (MdlByteCount < (PAGE_SIZE * 5))
+            NeededDescriptorCount = 1;
+        else if (MdlByteCount < (PAGE_SIZE * 10))
+            NeededDescriptorCount = 2;
+        else if (MdlByteCount < (PAGE_SIZE * 15))
+            NeededDescriptorCount = 3;
+        else
+            ASSERT(FALSE);
+    }
+    /* Limiter Transfers to PAGE_SIZE * 5 * 3, Three Descriptors */
+
+    QueueHead->NumberOfTransferDescriptors = NeededDescriptorCount;
+    for (i=0; i< NeededDescriptorCount;i++)
+    {
+        Descriptor[i] = CreateDescriptor(hcd,
+                                         PidDirection,
+                                         0);
+        Descriptor[i]->AlternateNextPointer = QueueHead->DeadDescriptor->PhysicalAddr;
+        
+        if (i > 0)
+        {
+            Descriptor[i-1]->NextDescriptor = Descriptor[i];
+            Descriptor[i]->PreviousDescriptor = Descriptor[i-1];
+            Descriptor[i-1]->NextPointer = Descriptor[i]->PhysicalAddr;
+        }
+    }
+
+    Descriptor[0]->Token.Bits.InterruptOnComplete = TRUE;
+
+    /* Save the first descriptor in the QueueHead */
+    QueueHead->FirstTransferDescriptor = Descriptor[0];
+    QueueHead->NextPointer = Descriptor[0]->PhysicalAddr;
+
+    return QueueHead;
+}
+
+
+/* Builds a QueueHead with 2 to 3 descriptors needed for control transfer
+   2 descriptors used for and control request that doesnt return data, such as SetAddress */
+PQUEUE_HEAD
+BuildControlTransfer(PEHCI_HOST_CONTROLLER hcd,
+                     ULONG DeviceAddress,
+                     USBD_PIPE_HANDLE PipeHandle,
+                     PUSB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup,
+                     PMDL pMdl,
+                     BOOLEAN FreeMdl)
+{
+    PQUEUE_HEAD QueueHead;
+    PQUEUE_TRANSFER_DESCRIPTOR Descriptor[3];
     PUSB_DEFAULT_PIPE_SETUP_PACKET CtrlSetupVA, CtrlPhysicalPA;
 
     CtrlSetupVA = (PUSB_DEFAULT_PIPE_SETUP_PACKET)AllocateMemory(hcd,
@@ -150,57 +230,45 @@
                                                                (ULONG*)&CtrlPhysicalPA);
 
     RtlCopyMemory(CtrlSetupVA, CtrlSetup, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
-    /* If no Irp then wait on completion */
-    if (IrpToComplete == NULL)
-    {
-        Event = ExAllocatePool(NonPagedPool, sizeof(KEVENT));
-        KeInitializeEvent(Event, NotificationEvent, FALSE);
-    }
-
-    if (TransferBuffer)
-    {
-        /* Allocate Mdl for Buffer */
-        pMdl = IoAllocateMdl(TransferBuffer,
-                             TransferBufferLength,
-                             FALSE,
-                             FALSE,
-                             NULL);
-
-        /* Lock Physical Pages */
-        MmBuildMdlForNonPagedPool(pMdl);
-        //MmProbeAndLockPages(pMdl, KernelMode, IoReadAccess);
-
-        MdlPhysicalAddr = MmGetPhysicalAddress((PVOID)TransferBuffer).LowPart;
-    }
 
     QueueHead = CreateQueueHead(hcd);
+    QueueHead->EndPointCharacteristics.DeviceAddress = DeviceAddress;
+    if (PipeHandle)
+        QueueHead->EndPointCharacteristics.EndPointNumber = ((PUSB_ENDPOINT_DESCRIPTOR)PipeHandle)->bEndpointAddress & 0x0F;
+
+    QueueHead->Token.Bits.DataToggle = TRUE;
+    QueueHead->FreeMdl = FreeMdl;
+    QueueHead->Mdl = pMdl;
 
     Descriptor[0] = CreateDescriptor(hcd,
                                      PID_CODE_SETUP_TOKEN,
                                      sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
 
-    Descriptor[0]->Token.Bits.InterruptOnComplete = FALSE;
     Descriptor[0]->Token.Bits.DataToggle = FALSE;
-
     /* Save the first descriptor */
-    QueueHead->TransferDescriptor = Descriptor[0];
-
-    if (TransferBuffer)
+    QueueHead->FirstTransferDescriptor = Descriptor[0];
+
+    if (pMdl)
     {
         Descriptor[1] = CreateDescriptor(hcd,
                                          PID_CODE_IN_TOKEN,
-                                         TransferBufferLength);        
-    }
-
-    Descriptor[2] = CreateDescriptor(hcd,
-                                     PID_CODE_OUT_TOKEN,
-                                     0);
-
-    Descriptor[1]->Token.Bits.InterruptOnComplete = FALSE;
+                                         MmGetMdlByteCount(pMdl));
+
+        Descriptor[2] = CreateDescriptor(hcd,
+                                         PID_CODE_OUT_TOKEN,
+                                         0);
+    }
+    else
+    {
+        Descriptor[2] = CreateDescriptor(hcd,
+                                         PID_CODE_IN_TOKEN,
+                                         0);
+    }
+
+    Descriptor[2]->Token.Bits.InterruptOnComplete = TRUE;
 
     /* Link the descriptors */
-
-    if (TransferBuffer)
+    if (pMdl)
     {
         Descriptor[0]->NextDescriptor = Descriptor[1];
         Descriptor[1]->NextDescriptor = Descriptor[2];
@@ -213,35 +281,267 @@
         Descriptor[2]->PreviousDescriptor = Descriptor[0];
     }
     
-    /* Assign the descritors buffers */
+    /* Assign the descriptor buffers */
     Descriptor[0]->BufferPointer[0] = (ULONG)CtrlPhysicalPA;
-
-    if (TransferBuffer)
-    {        
-        Descriptor[1]->BufferPointer[0] = MdlPhysicalAddr;
+    Descriptor[0]->BufferPointerVA[0] = (ULONG)CtrlSetupVA;
+    
+    if (pMdl)
+    {
         Descriptor[0]->NextPointer = Descriptor[1]->PhysicalAddr;
-        Descriptor[1]->NextPointer = Descriptor[2]->PhysicalAddr;   
+        Descriptor[0]->AlternateNextPointer = Descriptor[2]->PhysicalAddr;
+        Descriptor[1]->NextPointer = Descriptor[2]->PhysicalAddr;
+        Descriptor[1]->AlternateNextPointer = Descriptor[2]->PhysicalAddr;
     }
     else
     {
         Descriptor[0]->NextPointer = Descriptor[2]->PhysicalAddr;
+        Descriptor[0]->AlternateNextPointer = Descriptor[2]->PhysicalAddr;
     }
     
     QueueHead->NextPointer = Descriptor[0]->PhysicalAddr;
+    if (pMdl)
+        QueueHead->NumberOfTransferDescriptors = 3;
+    else
+        QueueHead->NumberOfTransferDescriptors = 2;
+    return QueueHead;
+}
+
+
+IO_ALLOCATION_ACTION NTAPI MapRegisterCallBack(PDEVICE_OBJECT DeviceObject,
+                                               PIRP Irp,
+                                               PVOID MapRegisterBase,
+                                               PVOID Context)
+{
+    PMAPREGISTERCALLBACKINFO CallBackInfo = (PMAPREGISTERCALLBACKINFO)Context;
+    
+    CallBackInfo->MapRegisterBase = MapRegisterBase;
+    
+    KeSetEvent(&CallBackInfo->Event, IO_NO_INCREMENT, FALSE);
+    return KeepObject;
+}
+
+
+NTSTATUS
+ExecuteTransfer(PDEVICE_OBJECT DeviceObject,
+                PUSB_DEVICE UsbDevice,
+                USBD_PIPE_HANDLE PipeHandle,
+                PUSB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup,
+                ULONG TransferFlags,
+                PVOID TransferBufferOrMdl,
+                ULONG TransferBufferLength,
+                PIRP IrpToComplete)
+{
+    PUSB_ENDPOINT_DESCRIPTOR EndPointDesc = NULL;
+    PEHCI_HOST_CONTROLLER hcd;
+    PQUEUE_HEAD QueueHead;
+    PKEVENT CompleteEvent = NULL;
+    PMAPREGISTERCALLBACKINFO CallBackInfo;
+    LARGE_INTEGER TimeOut;
+    PMDL pMdl = NULL;
+    BOOLEAN FreeMdl = FALSE;
+    PVOID VirtualAddressOfMdl;
+    ULONG NumberOfMapRegisters;
+    KIRQL OldIrql;
+    NTSTATUS Status = STATUS_SUCCESS;
+    UCHAR EndPointType,  PidDirection;
+    BOOLEAN IsReadOp = TRUE;
+    ULONG TransferBtyesOffset, CurrentTransferBytes;
+    PQUEUE_TRANSFER_DESCRIPTOR Descriptor;
+    PHYSICAL_ADDRESS PhysicalAddr;
+    int i,j;
+
+    hcd = &((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->hcd;
+
+    /* If no Irp then we will need to wait on completion */
+    if (IrpToComplete == NULL)
+    {
+        CompleteEvent = ExAllocatePool(NonPagedPool, sizeof(KEVENT));
+        KeInitializeEvent(CompleteEvent, NotificationEvent, FALSE);
+    }
+
+    CallBackInfo = ExAllocatePool(NonPagedPool, sizeof(MAPREGISTERCALLBACKINFO));
+    CallBackInfo->MapRegisterBase = 0;
+
+    KeInitializeEvent(&CallBackInfo->Event, NotificationEvent, FALSE);
+
+    /* Determine EndPoint Type */
+    if (!PipeHandle)
+    {
+        EndPointType = USB_ENDPOINT_TYPE_CONTROL;
+    }
+    else
+    {
+        EndPointDesc = (PUSB_ENDPOINT_DESCRIPTOR)PipeHandle;
+        EndPointType = EndPointDesc->bmAttributes & 0x0F;
+    }
+
+    if (TransferBufferOrMdl)
+    {
+        /* Create MDL for Buffer */
+        if (TransferBufferLength)
+        {
+            pMdl = IoAllocateMdl(TransferBufferOrMdl,
+                                 TransferBufferLength,
+                                 FALSE,
+                                 FALSE,
+                                 NULL);
+            /* UEHCI created the MDL so it needs to free it */
+            FreeMdl = TRUE;
+        }
+        else
+        {
+            pMdl = TransferBufferOrMdl;
+        }
+        MmBuildMdlForNonPagedPool(pMdl);
+    }
+
+    switch (EndPointType)
+    {
+        case USB_ENDPOINT_TYPE_CONTROL:
+        {
+            QueueHead = BuildControlTransfer(hcd,
+                                             UsbDevice->Address,
+                                             PipeHandle,
+                                             CtrlSetup,
+                                             pMdl,
+                                             FreeMdl);
+            IsReadOp = TRUE;
+            break;
+        }
+        case USB_ENDPOINT_TYPE_BULK:
+        {
+            PidDirection = EndPointDesc->bEndpointAddress >> 7;
+            if (PidDirection)
+                IsReadOp = FALSE;
+
+            QueueHead = BuildBulkTransfer(hcd,
+                                          UsbDevice->Address,
+                                          PipeHandle,
+                                          PidDirection,
+                                          pMdl,
+                                          FreeMdl);
+            
+            break;
+        }
+        case USB_ENDPOINT_TYPE_INTERRUPT:
+        {
+            DPRINT1("Interrupt Endpoints not implemented yet!\n");
+            break;
+        }
+        case USB_ENDPOINT_TYPE_ISOCHRONOUS:
+        {
+            DPRINT1("Isochronous Endpoints not implemented yet!\n");
+            break;
+        }
+        default:
+        {
+            DPRINT1("Unknown Endpoint type!!\n");
+            break;
+        }
+    }
 
     QueueHead->IrpToComplete = IrpToComplete;
-    QueueHead->MdlToFree = pMdl;
-    QueueHead->Event = Event;
-
-    /* Link in the QueueHead */
-    LinkQueueHead(hcd, QueueHead);
-
+    QueueHead->Event = CompleteEvent;
+
+    if (!pMdl)
+    {
+        ASSERT(QueueHead->NumberOfTransferDescriptors == 2);
+        LinkQueueHead(hcd, QueueHead);
+        if (IrpToComplete == NULL)
+        {
+            DPRINT1("Waiting For Completion %x!\n", CompleteEvent);
+            TimeOut.QuadPart =  -10000000;
+            KeWaitForSingleObject(CompleteEvent, Suspended, KernelMode, FALSE, NULL);//&TimeOut);
+            DPRINT1("Request Completed\n");
+            ExFreePool(CompleteEvent);
+        }
+        return Status;
+    }
+    //ASSERT(FALSE);
+
+    KeFlushIoBuffers(pMdl, IsReadOp, TRUE);
+    NumberOfMapRegisters = 15;
+
+    KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
+    hcd->pDmaAdapter->DmaOperations->AllocateAdapterChannel(hcd->pDmaAdapter,
+                                                            ((PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->ControllerFdo,
+                                                            NumberOfMapRegisters,
+                                                            MapRegisterCallBack,
+                                                            (PVOID)CallBackInfo);
+    KeLowerIrql(OldIrql);
+    DPRINT1("Waiting for AdapterChannel\n");
+    KeWaitForSingleObject(&CallBackInfo->Event, Suspended, KernelMode, FALSE, NULL);
+    DPRINT1("Dma controller ready!\n");
+    DPRINT1("Getting address for MDL %x\n", pMdl);
+    
+    VirtualAddressOfMdl = MmGetMdlVirtualAddress(pMdl);
+
+    TransferBtyesOffset = 0;
+    while (TransferBtyesOffset < MmGetMdlByteCount(pMdl))
+    {
+        CurrentTransferBytes = MmGetMdlByteCount(pMdl);
+        Descriptor = QueueHead->FirstTransferDescriptor;
+        if ((Descriptor->Token.Bits.PIDCode == PID_CODE_SETUP_TOKEN) && (QueueHead->NumberOfTransferDescriptors == 3))
+        {
+            DPRINT1("QueueHead is for endpoint 0\n");
+            DPRINT1("MapRegisterBase %x\n", CallBackInfo->MapRegisterBase);
+            DPRINT1("VirtualAddressOfMdl %x, TransferBytesOffset %x\n", VirtualAddressOfMdl, TransferBtyesOffset);
+            Descriptor = Descriptor->NextDescriptor;
+            PhysicalAddr = hcd->pDmaAdapter->DmaOperations->MapTransfer(hcd->pDmaAdapter,
+                                                                        pMdl,
+                                                                        CallBackInfo->MapRegisterBase,
+                                                                        (PVOID)((ULONG_PTR)VirtualAddressOfMdl + TransferBtyesOffset),
+                                                                        &CurrentTransferBytes,
+                                                                        !IsReadOp);
+            DPRINT1("BufferPointer[0] = %x\n", PhysicalAddr.LowPart);
+            Descriptor->BufferPointer[0] = PhysicalAddr.LowPart;
+            DPRINT1("CurrentTransferBytes %x\n", CurrentTransferBytes);
+            TransferBtyesOffset += CurrentTransferBytes;
+            LinkQueueHead(hcd, QueueHead);
+            break;
+        }
+        DPRINT1("PID_CODE_SETUP_TOKEN %x, PidDirection %x, NumDesc %x\n", PID_CODE_SETUP_TOKEN, PidDirection, QueueHead->NumberOfTransferDescriptors);
+        for (i=0; i<QueueHead->NumberOfTransferDescriptors; i++)
+        {
+            if (Descriptor->Token.Bits.PIDCode != PID_CODE_SETUP_TOKEN)
+            {
+                for (j=0; j<5; j++)
+                {
+                    PhysicalAddr = hcd->pDmaAdapter->DmaOperations->MapTransfer(hcd->pDmaAdapter,
+                                                                                pMdl,
+                                                                                CallBackInfo->MapRegisterBase,
+                                                                                (PVOID)((ULONG_PTR)VirtualAddressOfMdl + TransferBtyesOffset),
+                                                                                &CurrentTransferBytes,
+                                                                                !IsReadOp);
+                    DPRINT1("BufferPointer[%d] = %x\n", j, PhysicalAddr.LowPart);
+                    Descriptor->BufferPointer[j] = PhysicalAddr.LowPart;
+                    TransferBtyesOffset += CurrentTransferBytes;
+                    if (TransferBtyesOffset >= MmGetMdlByteCount(pMdl))
+                        break;
+                }
+            }
+            Descriptor = Descriptor->NextDescriptor;
+        }
+        LinkQueueHead(hcd, QueueHead);
+        break;
+    }
+
+    if (TransferBtyesOffset < MmGetMdlByteCount(pMdl)) ASSERT(FALSE);
     if (IrpToComplete == NULL)
     {
-        DPRINT1("Waiting For Completion %x!\n", Event);
-        KeWaitForSingleObject(Event, Suspended, KernelMode, FALSE, NULL);
-        ExFreePool(Event);
-    }
-
-    return TRUE;
+        DPRINT1("Waiting For Completion %x!\n", CompleteEvent);
+        TimeOut.QuadPart =  -10000000;
+        KeWaitForSingleObject(CompleteEvent, Suspended, KernelMode, FALSE, NULL);//&TimeOut);
+        DPRINT1("Request Completed\n");
+        ExFreePool(CompleteEvent);
+    }
+    
+    KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
+    hcd->pDmaAdapter->DmaOperations->FreeMapRegisters(hcd->pDmaAdapter,
+                                                      CallBackInfo->MapRegisterBase,
+                                                      NumberOfMapRegisters);
+
+    hcd->pDmaAdapter->DmaOperations->FreeAdapterChannel (hcd->pDmaAdapter);
+    KeLowerIrql(OldIrql);
+    return Status;
 }

Modified: trunk/reactos/drivers/usb/usbehci/transfer.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/transfer.h?rev=51327&r1=51326&r2=51327&view=diff
==============================================================================
--- trunk/reactos/drivers/usb/usbehci/transfer.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbehci/transfer.h [iso-8859-1] Wed Apr 13 04:48:50 2011
@@ -3,18 +3,37 @@
 #include "hardware.h"
 #include "hwiface.h"
 #include "physmem.h"
+#include "usbehci.h"
 #include <usb.h>
 #include <ntddk.h>
 
-BOOLEAN
-SubmitControlTransfer(PEHCI_HOST_CONTROLLER hcd,
-                      PUSB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup,
-                      PVOID TransferBuffer,
-                      ULONG TransferBufferLength,
-                      PIRP IrpToComplete);
+PQUEUE_HEAD
+BuildControlTransfer(PEHCI_HOST_CONTROLLER hcd,
+                     ULONG DeviceAddress,
+                     USBD_PIPE_HANDLE PipeHandle,
+                     PUSB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup,
+                     PMDL pMdl,
+                     BOOLEAN FreeMdl);
+
+PQUEUE_HEAD
+BuildBulkTransfer(PEHCI_HOST_CONTROLLER hcd,
+                   ULONG DeviceAddress,
+                   USBD_PIPE_HANDLE PipeHandle,
+                   UCHAR PidDirection,
+                   PMDL pMdl,
+                   BOOLEAN FreeMdl);
 
 VOID
 BuildSetupPacketFromURB(PEHCI_HOST_CONTROLLER hcd,
                         PURB Urb,
                         PUSB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup);
 
+NTSTATUS
+ExecuteTransfer(PDEVICE_OBJECT DeviceObject,
+                PUSB_DEVICE UsbDevice,
+                USBD_PIPE_HANDLE PipeHandle,
+                PUSB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup,
+                ULONG TransferFlags,
+                PVOID TransferBufferOrMdl,
+                ULONG TransferBufferLength,
+                PIRP IrpToComplete);




More information about the Ros-diffs mailing list