[ros-diffs] [janderwald] 51501: [USBEHCI_NEW] - Port URB_FUNCTION_CLASS_INTERFACE from mjmartin usbehci driver - Fix typo in interface declaration - Disable assert for now - Return irp status pending when irp ...

janderwald at svn.reactos.org janderwald at svn.reactos.org
Sat Apr 30 08:04:37 UTC 2011


Author: janderwald
Date: Sat Apr 30 08:04:35 2011
New Revision: 51501

URL: http://svn.reactos.org/svn/reactos?rev=51501&view=rev
Log:
[USBEHCI_NEW]
- Port URB_FUNCTION_CLASS_INTERFACE from mjmartin usbehci driver
- Fix typo in interface declaration
- Disable assert for now
- Return irp status pending when irp is added to the queue
- Fix bug in InternalGetPidDirection
- More work on the bulk transfers, not yet working

Modified:
    branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.cpp
    branches/usb-bringup/drivers/usb/usbehci_new/interfaces.h
    branches/usb-bringup/drivers/usb/usbehci_new/memory_manager.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=51501&r1=51500&r2=51501&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] Sat Apr 30 08:04:35 2011
@@ -65,6 +65,7 @@
     NTSTATUS HandleSelectConfiguration(IN OUT PIRP Irp, PURB Urb);
     NTSTATUS HandleSelectInterface(IN OUT PIRP Irp, PURB Urb);
     NTSTATUS HandleClassOther(IN OUT PIRP Irp, PURB Urb);
+    NTSTATUS HandleClassInterface(IN OUT PIRP Irp, PURB Urb);
     NTSTATUS HandleBulkOrInterruptTransfer(IN OUT PIRP Irp, PURB Urb);
     
     friend VOID StatusChangeEndpointCallBack(PVOID Context);
@@ -1355,6 +1356,70 @@
             DPRINT1("CHubController::HandleGetDescriptor DescriptorType %x unimplemented\n", Urb->UrbControlDescriptorRequest.DescriptorType);
             break;
     }
+
+    //
+    // done
+    //
+    return Status;
+}
+
+//-----------------------------------------------------------------------------------------
+NTSTATUS
+CHubController::HandleClassInterface(
+    IN OUT PIRP Irp,
+    IN OUT PURB Urb)
+{
+    USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
+    NTSTATUS Status;
+    PUSBDEVICE UsbDevice;
+
+    //
+    // sanity check
+    //
+    PC_ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer);
+    PC_ASSERT(Urb->UrbControlVendorClassRequest.TransferBufferLength);
+    PC_ASSERT(Urb->UrbHeader.UsbdDeviceHandle);
+
+    //
+    // check if this is a valid usb device handle
+    //
+    PC_ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)));
+
+    //
+    // get device
+    //
+    UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
+
+
+    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);
+
+    //
+    // initialize setup packet
+    //
+    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;
+
+    //
+    // issue request
+    //
+    Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, Urb->UrbControlVendorClassRequest.TransferBufferLength, Urb->UrbControlVendorClassRequest.TransferBuffer);
+
+    //
+    // assert on failure
+    //
+    PC_ASSERT(NT_SUCCESS(Status));
+
 
     //
     // done
@@ -1419,6 +1484,9 @@
                 case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
                     Status = HandleBulkOrInterruptTransfer(Irp, Urb);
                     break;
+                case URB_FUNCTION_CLASS_INTERFACE:
+                    Status = HandleClassInterface(Irp, Urb);
+                    break;
                 default:
                     DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_URB Function %x NOT IMPLEMENTED\n", Urb->UrbHeader.Function);
                     break;

Modified: branches/usb-bringup/drivers/usb/usbehci_new/interfaces.h
URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci_new/interfaces.h?rev=51501&r1=51500&r2=51501&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbehci_new/interfaces.h [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbehci_new/interfaces.h [iso-8859-1] Sat Apr 30 08:04:35 2011
@@ -785,7 +785,7 @@
 //
 // Description: submits an irp containing an urb
 
-    virtual NTSTATUS SubmitIrp(PIRP Urb) = 0;
+    virtual NTSTATUS SubmitIrp(PIRP Irp) = 0;
 
 //-----------------------------------------------------------------------------------------
 //

Modified: branches/usb-bringup/drivers/usb/usbehci_new/memory_manager.cpp
URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci_new/memory_manager.cpp?rev=51501&r1=51500&r2=51501&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbehci_new/memory_manager.cpp [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbehci_new/memory_manager.cpp [iso-8859-1] Sat Apr 30 08:04:35 2011
@@ -136,7 +136,7 @@
     // sanity checks
     //
     ASSERT(Size < PAGE_SIZE);
-    ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
+    //ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
 
     //
     // align request

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=51501&r1=51500&r2=51501&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] Sat Apr 30 08:04:35 2011
@@ -484,6 +484,11 @@
     Status = Request->InitializeWithIrp(m_DmaManager, Irp);
 
     //
+    // mark irp as pending
+    //
+    IoMarkIrpPending(Irp);
+
+    //
     // now add the request
     //
     Status = m_Queue->AddUSBRequest(Request);
@@ -500,7 +505,7 @@
     //
     // done
     //
-    return Status;
+    return STATUS_PENDING;
 }
 
 //----------------------------------------------------------------------------------------
@@ -1199,6 +1204,16 @@
         //
         // copy pipe handle
         //
+        DPRINT1("PipeIndex %lu\n", PipeIndex);
+        DPRINT1("EndpointAddress %x\n", InterfaceInfo->Pipes[PipeIndex].EndpointAddress);
+        DPRINT1("Interval %d\n", InterfaceInfo->Pipes[PipeIndex].Interval);
+        DPRINT1("MaximumPacketSize %d\n", InterfaceInfo->Pipes[PipeIndex].MaximumPacketSize);
+        DPRINT1("MaximumTransferSize %d\n", InterfaceInfo->Pipes[PipeIndex].MaximumTransferSize);
+        DPRINT1("PipeFlags %d\n", InterfaceInfo->Pipes[PipeIndex].PipeFlags);
+        DPRINT1("PipeType %dd\n", InterfaceInfo->Pipes[PipeIndex].PipeType);
+        DPRINT1("UsbEndPoint %x\n", Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor.bEndpointAddress);
+        PC_ASSERT(Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor.bEndpointAddress == InterfaceInfo->Pipes[PipeIndex].EndpointAddress);
+
         InterfaceInfo->Pipes[PipeIndex].PipeHandle = &Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor;
 
         if (Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor.bmAttributes & (USB_ENDPOINT_TYPE_ISOCHRONOUS | USB_ENDPOINT_TYPE_INTERRUPT))

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=51501&r1=51500&r2=51501&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] Sat Apr 30 08:04:35 2011
@@ -371,6 +371,8 @@
             Urb->UrbHeader.Length = 0;
         }
 
+        DPRINT1("Request %p Completing Irp %p NtStatusCode %x UrbStatusCode %x\n", this, m_Irp, NtStatusCode, UrbStatusCode);
+
         //
         // FIXME: check if the transfer was split
         // if yes dont complete irp yet
@@ -604,9 +606,9 @@
     EndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)Urb->UrbBulkOrInterruptTransfer.PipeHandle;
 
     //
-    // end point is defined in the low byte of bmAttributes
-    //
-    return (EndpointDescriptor->bmAttributes & USB_ENDPOINT_DIRECTION_MASK);
+    // end point is defined in the low byte of bEndpointAddress
+    //
+    return (EndpointDescriptor->bEndpointAddress & USB_ENDPOINT_DIRECTION_MASK) >> 7;
 }
 
 //----------------------------------------------------------------------------------------
@@ -779,8 +781,11 @@
     PQUEUE_HEAD * OutHead)
 {
     NTSTATUS Status;
-    ULONG NumTransferDescriptors, TransferBufferRounded, NumPages, Index, FailIndex;
     PQUEUE_HEAD QueueHead;
+    ULONG TransferDescriptorCount, Index;
+    ULONG BytesAvailable, BufferIndex;
+    PVOID Base;
+    ULONG PageOffset;
 
     //
     // Allocate the queue head
@@ -801,38 +806,33 @@
     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;
+    // FIXME: support more than one descriptor
+    //
+    PC_ASSERT(m_TransferBufferLength < PAGE_SIZE * 5);
+    PC_ASSERT(m_TransferBufferLength);
+
+    TransferDescriptorCount = 1;
+
+    //
+    // get virtual base of mdl
+    //
+    Base = MmGetMdlVirtualAddress(m_TransferBufferMDL);
+    BytesAvailable = m_TransferBufferLength;
+
+    PC_ASSERT(m_EndpointDescriptor);
+
+    DPRINT1("EndPointAddress %x\n", m_EndpointDescriptor->bEndpointAddress);
+    DPRINT1("EndPointDirection %x\n", USB_ENDPOINT_DIRECTION_IN(m_EndpointDescriptor->bEndpointAddress));
+
+    DPRINT1("Request %p Base Address %p TransferBytesLength %lu\n", this, Base, BytesAvailable);
+    DPRINT1("InternalGetPidDirection() %d EndPointAddress %x\n", InternalGetPidDirection(), m_EndpointDescriptor->bEndpointAddress & 0x0F);
+
+    //PC_ASSERT(InternalGetPidDirection() == USB_ENDPOINT_DIRECTION_IN(m_EndpointDescriptor->bEndpointAddress));
 
     //
     // Allocated transfer descriptors
     //
-    for (Index = 0; Index < NumTransferDescriptors; Index++)
+    for (Index = 0; Index < TransferDescriptorCount; Index++)
     {
         Status = CreateDescriptor(&m_TransferDescriptors[Index]);
         if (!NT_SUCCESS(Status))
@@ -850,10 +850,130 @@
             // Free Descriptors
             // FIXME: Implement FreeDescriptors
             //
-            //for (FailIndex = 0; FailIndex < Index; FailIndex++)
-                //FreeDescriptor(m_TransferDescriptors[FailIndex]);
-
             return Status;
+        }
+
+        //
+        // sanity check
+        //
+        PC_ASSERT(BytesAvailable);
+
+        //
+        // now setup transfer buffers
+        //
+        for(BufferIndex = 0; BufferIndex < 5; BufferIndex++)
+        {
+            //
+            // setup buffer
+            //
+            if (BufferIndex == 0)
+            {
+                //
+                // use physical address
+                //
+                m_TransferDescriptors[Index]->BufferPointer[0] = MmGetPhysicalAddress(Base).LowPart;
+
+                //
+                // get offset within page
+                //
+                PageOffset = BYTE_OFFSET(m_TransferDescriptors[Index]->BufferPointer[0]);
+
+                //
+                // check if request fills another page
+                //
+                if (PageOffset + BytesAvailable >= PAGE_SIZE)
+                {
+                    //
+                    // move to next page
+                    //
+                    Base = (PVOID)ROUND_TO_PAGES(Base);
+
+                    //
+                    // increment transfer bytes
+                    //
+                    m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer = PAGE_SIZE - PageOffset;
+
+                    //
+                    // decrement available byte count
+                    //
+                    BytesAvailable -= m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer;
+
+                    DPRINT1("TransferDescriptor %p BufferPointer %p BufferIndex %lu TotalBytes %lu Remaining %lu\n", m_TransferDescriptors[Index], m_TransferDescriptors[Index]->BufferPointer[BufferIndex],
+                        BufferIndex, m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer, BytesAvailable);
+               }
+               else
+               {
+                   //
+                   // request ends on the first buffer page
+                   //
+                   m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer = BytesAvailable;
+                   BytesAvailable = 0;
+
+                   DPRINT1("TransferDescriptor %p BufferPointer %p BufferIndex %lu TotalBytes %lu Remaining %lu\n", m_TransferDescriptors[Index], m_TransferDescriptors[Index]->BufferPointer[BufferIndex],
+                       BufferIndex, m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer, BytesAvailable);
+                   break;
+               }
+            }
+            else
+            {
+                //
+                // the following pages always start on byte zero of each page
+                //
+                PC_ASSERT(((ULONG_PTR)Base & (PAGE_SIZE-1)) == 0);
+
+                if (BytesAvailable >= PAGE_SIZE)
+                {
+                    //
+                    // store address
+                    //
+                    m_TransferDescriptors[Index]->BufferPointer[BufferIndex] = MmGetPhysicalAddress(Base).LowPart;
+
+                    //
+                    // move to next page
+                    //
+                    Base = (PVOID)((ULONG_PTR)Base + PAGE_SIZE);
+
+                    //
+                    // increment transfer descriptor bytes
+                    //
+                    m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer += PAGE_SIZE;
+
+                    //
+                    // decrement available byte count
+                    //
+                    BytesAvailable -= PAGE_SIZE;
+
+                    DPRINT1("TransferDescriptor %p BufferPointer %p BufferIndex %lu TotalBytes %lu Remaining %lu\n", m_TransferDescriptors[Index], m_TransferDescriptors[Index]->BufferPointer[BufferIndex],
+                            BufferIndex, m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer, BytesAvailable);
+                }
+                else
+                {
+                    PC_ASSERT(BytesAvailable);
+
+                    //
+                    // store address
+                    //
+                    m_TransferDescriptors[Index]->BufferPointer[BufferIndex] = MmGetPhysicalAddress(Base).LowPart;
+
+                    //
+                    // increment transfer descriptor bytes
+                    //
+                    m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer += BytesAvailable;
+
+                    //
+                    // decrement available byte count
+                    //
+                    BytesAvailable -= BytesAvailable;
+
+                    //
+                    // done
+                    //
+                    DPRINT1("TransferDescriptor %p BufferPointer %p BufferIndex %lu TotalBytes %lu Remaining %lu\n", m_TransferDescriptors[Index], m_TransferDescriptors[Index]->BufferPointer[BufferIndex],
+                            BufferIndex, m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer, BytesAvailable);
+
+                    break;
+                }
+            }
         }
 
         //
@@ -863,8 +983,26 @@
         {
             m_TransferDescriptors[Index - 1]->NextPointer = m_TransferDescriptors[Index]->PhysicalAddr;
         }
-        
-    }
+
+        //
+        // setup direction
+        //
+        m_TransferDescriptors[Index]->Token.Bits.PIDCode = InternalGetPidDirection();
+
+        //
+        // FIXME: performance penality?
+        //
+        m_TransferDescriptors[Index]->Token.Bits.InterruptOnComplete = TRUE;
+
+        //
+        // FIXME need dead queue transfer descriptor?
+        //
+    }
+
+    //
+    // all bytes should have been consumed
+    //
+    PC_ASSERT(BytesAvailable == 0);
 
     //
     // Initialize the QueueHead
@@ -881,19 +1019,20 @@
     }
 
     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);
-
-    
+
+    //
+    // link descriptor with queue head
+    //
+    QueueHead->NextPointer = m_TransferDescriptors[0]->PhysicalAddr;
+
+    //
+    // store result
+    //
+    *OutHead = QueueHead;
+
+    //
+    // done
+    //
     return STATUS_SUCCESS;
 }
 
@@ -1351,6 +1490,7 @@
         //
         // release transfer descriptors
         //
+        DPRINT1("m_TransferDescriptor[0] Length %lu\n", m_TransferDescriptors[0]->Token.Bits.TotalBytesToTransfer);
         m_DmaManager->Release(m_TransferDescriptors[0], sizeof(QUEUE_TRANSFER_DESCRIPTOR));
         m_TransferDescriptors[0] = 0;
     }




More information about the Ros-diffs mailing list