Author: mjmartin
Date: Fri Apr 29 13:16:03 2011
New Revision: 51493

URL: http://svn.reactos.org/svn/reactos?rev=51493&view=rev
Log:
[USBEHCI_NEW]
- Fix a type causing CommitIrp to fail.
- Add a sanity check in StatusChangeEndpointCallBack to check that a pending 
SCE irp is queued.
- Start Implementing Bulk Transfers. Needs more work.



Modified:
    branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.cpp
    branches/usb-bringup/drivers/usb/usbehci_new/usb_device.cpp
    branches/usb-bringup/drivers/usb/usbehci_new/usb_request.cpp

Modified: branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.cpp
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.cpp?rev=51493&r1=51492&r2=51493&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.cpp 
[iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.cpp 
[iso-8859-1] Fri Apr 29 13:16:03 2011
@@ -761,6 +761,8 @@
     IN OUT PIRP Irp, 
     PURB Urb)
 {
+    PUSBDEVICE UsbDevice;
+    PUSB_ENDPOINT_DESCRIPTOR EndPointDesc = NULL;
     //
     // First check if the request is for the Status Change Endpoint
     //
@@ -779,13 +781,45 @@
         //
         // Else pend the IRP, to be completed when a device connects or 
disconnects.
         //
+        DPRINT1("Pending SCE Irp\n");;
         m_PendingSCEIrp = Irp;
         IoMarkIrpPending(Irp);
         return STATUS_PENDING;
     }
 
-    UNIMPLEMENTED
-    return STATUS_NOT_IMPLEMENTED;
+    //
+    // Check PipeHandle to determine if this is a Bulk or Interrupt Transfer 
Request
+    //
+    EndPointDesc = 
(PUSB_ENDPOINT_DESCRIPTOR)Urb->UrbBulkOrInterruptTransfer.PipeHandle;
+
+    switch(EndPointDesc->bmAttributes & 0x0F)
+    {
+        case USB_ENDPOINT_TYPE_CONTROL:
+            DPRINT1("Control Transfer is not expected!!!\n");
+            return STATUS_INVALID_DEVICE_REQUEST;
+        case USB_ENDPOINT_TYPE_BULK:
+            DPRINT1("Initiating Bulk Transfer\n");
+            break;
+        case USB_ENDPOINT_TYPE_ISOCHRONOUS:
+        case USB_ENDPOINT_TYPE_INTERRUPT:
+            DPRINT1("Not Supported\n");
+            break;
+        default:
+            DPRINT1("Unknown EndPoint Type!\n");
+            break;
+    }
+
+    //
+    // check if this is a valid usb device handle
+    //
+    PC_ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)));
+
+    //
+    // get device
+    //
+    UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
+
+    return UsbDevice->SubmitIrp(Irp);
 }
 
 
//-----------------------------------------------------------------------------------------
@@ -3068,13 +3102,18 @@
 
     ASSERT(This);
 
-    DPRINT1("SCE Notification!\n");
     Irp = This->m_PendingSCEIrp;
+    if (!Irp)
+    {
+        DPRINT1("There was no pending IRP for SCE. Did the usb hub 2.0 driver 
(usbhub2) load?\n");
+        return;
+    }
+
     This->m_PendingSCEIrp = NULL;
-
     This->QueryStatusChageEndpoint(Irp);
 
     Irp->IoStatus.Status = STATUS_SUCCESS;
     Irp->IoStatus.Information = 0;
+
     IoCompleteRequest(Irp, IO_NO_INCREMENT);
 }

Modified: branches/usb-bringup/drivers/usb/usbehci_new/usb_device.cpp
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci_new/usb_device.cpp?rev=51493&r1=51492&r2=51493&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbehci_new/usb_device.cpp [iso-8859-1] 
(original)
+++ branches/usb-bringup/drivers/usb/usbehci_new/usb_device.cpp [iso-8859-1] 
Fri Apr 29 13:16:03 2011
@@ -456,7 +456,7 @@
     NTSTATUS Status;
     PUSBREQUEST Request;
 
-    if (!m_Queue || m_DmaManager)
+    if (!m_Queue || !m_DmaManager)
     {
         //
         // no queue, wtf?

Modified: branches/usb-bringup/drivers/usb/usbehci_new/usb_request.cpp
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci_new/usb_request.cpp?rev=51493&r1=51492&r2=51493&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbehci_new/usb_request.cpp [iso-8859-1] 
(original)
+++ branches/usb-bringup/drivers/usb/usbehci_new/usb_request.cpp [iso-8859-1] 
Fri Apr 29 13:16:03 2011
@@ -53,6 +53,7 @@
 
     // local functions
     ULONG InternalGetTransferType();
+    UCHAR InternalGetPidDirection();
     NTSTATUS BuildControlTransferQueueHead(PQUEUE_HEAD * OutHead);
     NTSTATUS BuildBulkTransferQueueHead(PQUEUE_HEAD * OutHead);
     NTSTATUS CreateDescriptor(PQUEUE_TRANSFER_DESCRIPTOR *OutDescriptor);
@@ -205,6 +206,8 @@
     PC_ASSERT(DmaManager);
     PC_ASSERT(Irp);
 
+    m_DmaManager = DmaManager;
+
     //
     // get current irp stack location
     //
@@ -245,20 +248,49 @@
             if (Urb->UrbBulkOrInterruptTransfer.TransferBufferLength)
             {
                 //
-                // FIXME: it must have an MDL
+                // Check if there is a MDL
                 //
-                PC_ASSERT(Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL);
+                if (!Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL)
+                {
+                    //
+                    // Create one using TransferBuffer
+                    //
+                    DPRINT1("Creating Mdl from Urb Buffer\n");
+                    m_TransferBufferMDL = 
IoAllocateMdl(Urb->UrbBulkOrInterruptTransfer.TransferBuffer,
+                                                        
Urb->UrbBulkOrInterruptTransfer.TransferBufferLength,
+                                                        FALSE,
+                                                        FALSE,
+                                                        NULL);
+
+                    if (!m_TransferBufferMDL)
+                    {
+                        //
+                        // failed to allocate mdl
+                        //
+                        return STATUS_INSUFFICIENT_RESOURCES;
+                    }
+
+                    //
+                    // build mdl for non paged pool
+                    // FIXME: Does hub driver already do this when passing MDL?
+                    //
+                    MmBuildMdlForNonPagedPool(m_TransferBufferMDL);
+                }
+                else
+                {
+                    m_TransferBufferMDL = 
Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL;
+                }
+
+                //
+                // save buffer length
+                //
+                m_TransferBufferLength = 
Urb->UrbBulkOrInterruptTransfer.TransferBufferLength;
 
                 //
                 // get endpoint descriptor
                 //
                 m_EndpointDescriptor = 
(PUSB_ENDPOINT_DESCRIPTOR)Urb->UrbBulkOrInterruptTransfer.PipeHandle;
 
-                //
-                // get mdl buffer
-                //
-                m_TransferBufferMDL = 
Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL;
-                m_TransferBufferLength = 
Urb->UrbBulkOrInterruptTransfer.TransferBufferLength;
             }
             break;
         }
@@ -317,6 +349,18 @@
         Urb->UrbHeader.Status = UrbStatusCode;
 
         //
+        // Check if the MDL was created
+        //
+
+        if (!Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL)
+        {
+            //
+            // Free Mdl
+            //
+            IoFreeMdl(m_TransferBufferMDL);
+        }
+
+        //
         // check if the request was successfull
         //
         if (!NT_SUCCESS(NtStatusCode))
@@ -536,6 +580,35 @@
     return TransferType;
 }
 
+UCHAR
+CUSBRequest::InternalGetPidDirection()
+{
+    PIO_STACK_LOCATION IoStack;
+    PURB Urb;
+    PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
+
+    ASSERT(m_Irp);
+    //
+    // get stack location
+    //
+    IoStack = IoGetCurrentIrpStackLocation(m_Irp);
+
+    //
+    // get urb
+    //
+    Urb = (PURB)IoStack->Parameters.Others.Argument1;
+
+    //
+    // cast to end point
+    //
+    EndpointDescriptor = 
(PUSB_ENDPOINT_DESCRIPTOR)Urb->UrbBulkOrInterruptTransfer.PipeHandle;
+
+    //
+    // end point is defined in the low byte of bmAttributes
+    //
+    return (EndpointDescriptor->bmAttributes & USB_ENDPOINT_DIRECTION_MASK);
+}
+
 
//----------------------------------------------------------------------------------------
 NTSTATUS
 CUSBRequest::BuildControlTransferQueueHead(
@@ -705,8 +778,123 @@
 CUSBRequest::BuildBulkTransferQueueHead(
     PQUEUE_HEAD * OutHead)
 {
-    UNIMPLEMENTED
+    NTSTATUS Status;
+    ULONG NumTransferDescriptors, TransferBufferRounded, NumPages, Index, 
FailIndex;
+    PQUEUE_HEAD QueueHead;
+
+    //
+    // Allocate the queue head
+    //
+    Status = CreateQueueHead(&QueueHead);
+
+    if (!NT_SUCCESS(Status))
+    {
+        //
+        // failed to allocate queue heads
+        //
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    //
+    // sanity checks
+    //
+    PC_ASSERT(QueueHead);
+
+    //
+    // Determine number of transfer descriptors needed. Max size is 3 * 5 Pages
+    // FIXME: Do we need anything bigger?
+    //
+    TransferBufferRounded = ROUND_TO_PAGES(m_TransferBufferLength);
+    NumPages = Index = 0;
+    NumTransferDescriptors = 1;
+    while (TransferBufferRounded > 0)
+    {
+        TransferBufferRounded -= PAGE_SIZE;
+        NumPages++;
+        Index++;
+        if (Index == 5)
+        {
+            NumTransferDescriptors++;
+            Index = 0;
+        }
+    }
+
+    DPRINT1("Need TransferDescriptors %x, Pages %x\n", NumTransferDescriptors, 
NumPages);
+    DPRINT1("This is the end of the line!!!!!!!!\n");
     return STATUS_NOT_IMPLEMENTED;
+    //FIXME: Below needs work.
+
+    //
+    // FIXME: Handle transfers greater than 5 * PAGE_SIZE * 3
+    //
+    if (NumTransferDescriptors > 3) NumTransferDescriptors = 3;
+
+    //
+    // Allocated transfer descriptors
+    //
+    for (Index = 0; Index < NumTransferDescriptors; Index++)
+    {
+        Status = CreateDescriptor(&m_TransferDescriptors[Index]);
+        if (!NT_SUCCESS(Status))
+        {
+            //
+            // Failed to allocate transfer descriptors
+            //
+
+            //
+            // Free QueueHead
+            //
+            FreeQueueHead(QueueHead);
+
+            //
+            // Free Descriptors
+            // FIXME: Implement FreeDescriptors
+            //
+            //for (FailIndex = 0; FailIndex < Index; FailIndex++)
+                //FreeDescriptor(m_TransferDescriptors[FailIndex]);
+
+            return Status;
+        }
+
+        //
+        // Go ahead and link descriptors
+        //
+        if (Index > 0)
+        {
+            m_TransferDescriptors[Index - 1]->NextPointer = 
m_TransferDescriptors[Index]->PhysicalAddr;
+        }
+        
+    }
+
+    //
+    // Initialize the QueueHead
+    //
+    QueueHead->EndPointCharacteristics.DeviceAddress = GetDeviceAddress();
+    
+    if (m_EndpointDescriptor)
+    {
+        //
+        // Set endpoint address and max packet length
+        //
+        QueueHead->EndPointCharacteristics.EndPointNumber = 
m_EndpointDescriptor->bEndpointAddress & 0x0F;
+        QueueHead->EndPointCharacteristics.MaximumPacketLength = 
m_EndpointDescriptor->wMaxPacketSize;
+    }
+
+    QueueHead->Token.Bits.DataToggle = TRUE;
+    
+    //
+    // Setup descriptors
+    //
+    m_TransferDescriptors[0]->Token.Bits.PIDCode = InternalGetPidDirection();
+    //m_TransferDescriptors[0]->Token.Bits.TotalBytesToTransfer = ???
+    //m_TransferDescriptors[0]->Token.Bits.DataToggle = FALSE;
+
+    m_TransferDescriptors[Index]->Token.Bits.InterruptOnComplete = TRUE;
+
+    ASSERT(m_TransferBufferMDL);
+
+    
+    return STATUS_SUCCESS;
 }
 
 
//----------------------------------------------------------------------------------------
@@ -764,6 +952,7 @@
     // allocate queue head
     //
     Status = m_DmaManager->Allocate(sizeof(QUEUE_HEAD), (PVOID*)&QueueHead, 
&QueueHeadPhysicalAddress);
+
     if (!NT_SUCCESS(Status))
     {
         //
@@ -1225,12 +1414,12 @@
             //
             // check for serious error
             //
-            PC_ASSERT(m_TransferDescriptors[Index]->Token.Bits.Halted == 0);
+            //PC_ASSERT(m_TransferDescriptors[Index]->Token.Bits.Halted == 0);
 
             //
             // the transfer descriptor should be in the same state as the 
queue head
             //
-            PC_ASSERT(m_TransferDescriptors[Index]->Token.Bits.Active == 0);
+            //PC_ASSERT(m_TransferDescriptors[Index]->Token.Bits.Active == 0);
         }
     }
 


Reply via email to