[USBOHCI]
authorJohannes Anderwald <johannes.anderwald@reactos.org>
Mon, 13 Feb 2012 13:39:20 +0000 (13:39 +0000)
committerJohannes Anderwald <johannes.anderwald@reactos.org>
Mon, 13 Feb 2012 13:39:20 +0000 (13:39 +0000)
- Set endpoint direction indicator for control transfers
- Mask Version bits when printing out version
- Implement function for dumping endpoint descriptor
- Implement retrieving pid direction from setup packet
- Flip the pid direction for the status descriptor when data is transferred
- Return packet size 8 when using the control pipe
- OHCI control transfer hang is gone
- OHCI control should now work and attached HID devices finish initialization

svn path=/trunk/; revision=55574

reactos/drivers/usb/usbohci/hardware.cpp
reactos/drivers/usb/usbohci/hardware.h
reactos/drivers/usb/usbohci/usb_queue.cpp
reactos/drivers/usb/usbohci/usb_request.cpp

index 87eb79f..4bf6ccf 100644 (file)
@@ -329,7 +329,7 @@ CUSBHardwareDevice::PnpStart(
                 //
                 Version = READ_REGISTER_ULONG((PULONG)((ULONG_PTR)ResourceBase + OHCI_REVISION_OFFSET));
 
-                DPRINT("Version %x\n", Version);
+                DPRINT("Version %x\n", Version & 0xFFFF);
 
                 //
                 // Store Resource base
index e88c094..ec9a3cd 100644 (file)
@@ -241,7 +241,8 @@ typedef struct _OHCI_ENDPOINT_DESCRIPTOR
 #define OHCI_ENDPOINT_GENERAL_FORMAT            0x00000000
 #define OHCI_ENDPOINT_ISOCHRONOUS_FORMAT        0x00008000
 #define        OHCI_ENDPOINT_HEAD_MASK                 0xfffffffc
-#define        OHCI_ENDPOINT_HALTED                                    0x00000001
+#define        OHCI_ENDPOINT_HALTED                    0x00000001
+#define        OHCI_ENDPOINT_DIRECTION_DESCRIPTOR      0x00000000
 //
 // Maximum port count set by OHCI
 //
index 2132bec..a5a79c2 100644 (file)
@@ -285,7 +285,7 @@ CUSBQueue::AddUSBRequest(
         m_Hardware->GetCurrentFrameNumber(&FrameNumber);
 
         DPRINT("Hardware 1ms %p Iso %p\n",m_InterruptEndpoints[0], m_IsoHeadEndpointDescriptor);
-               ASSERT(m_InterruptEndpoints[0]->NextPhysicalEndpoint == m_IsoHeadEndpointDescriptor->PhysicalAddress.LowPart);
+        ASSERT(m_InterruptEndpoints[0]->NextPhysicalEndpoint == m_IsoHeadEndpointDescriptor->PhysicalAddress.LowPart);
 
         PrintEndpointList(m_IsoHeadEndpointDescriptor);
     }
index b667554..2ebc80f 100644 (file)
@@ -48,7 +48,6 @@ public:
     virtual VOID FreeEndpointDescriptor(struct _OHCI_ENDPOINT_DESCRIPTOR * OutDescriptor);
     virtual UCHAR GetInterval();
 
-
     // local functions
     ULONG InternalGetTransferType();
     UCHAR InternalGetPidDirection();
@@ -65,6 +64,7 @@ public:
     UCHAR GetEndpointAddress();
     USHORT GetMaxPacketSize();
     VOID CheckError(struct _OHCI_ENDPOINT_DESCRIPTOR * OutDescriptor);
+    VOID DumpEndpointDescriptor(struct _OHCI_ENDPOINT_DESCRIPTOR *Descriptor);
 
 
     // constructor / destructor
@@ -460,9 +460,10 @@ CUSBRequest::GetMaxPacketSize()
     if (!m_EndpointDescriptor)
     {
         //
-        // control request
+        // FIXME: use DeviceDescriptor.bMaxPacketSize0
+        // control pipe request
         //
-        return 0;
+        return 8;
     }
 
     ASSERT(m_Irp);
@@ -541,16 +542,23 @@ CUSBRequest::InternalGetTransferType()
 UCHAR
 CUSBRequest::InternalGetPidDirection()
 {
-    ASSERT(m_Irp);
-    ASSERT(m_EndpointDescriptor);
-
-    //
-    // end point is defined in the low byte of bEndpointAddress
-    //
-    return (m_EndpointDescriptor->bEndpointAddress & USB_ENDPOINT_DIRECTION_MASK) >> 7;
+    if (m_EndpointDescriptor)
+    {
+        //
+        // end point direction is highest bit in bEndpointAddress
+        //
+        return (m_EndpointDescriptor->bEndpointAddress & USB_ENDPOINT_DIRECTION_MASK) >> 7;
+    }
+    else
+    {
+        //
+        // request arrives on the control pipe, extract direction from setup packet
+        //
+        ASSERT(m_SetupPacket);
+        return (m_SetupPacket->bmRequestType.B >> 7);
+    }
 }
 
-
 //----------------------------------------------------------------------------------------
 UCHAR
 CUSBRequest::GetDeviceAddress()
@@ -983,7 +991,13 @@ CUSBRequest::AllocateEndpointDescriptor(
             //
             Descriptor->Flags |= OHCI_ENDPOINT_DIRECTION_IN;
         }
-
+    }
+    else
+    {
+        //
+        // get it from transfer descriptor
+        //
+        Descriptor->Flags |= OHCI_ENDPOINT_DIRECTION_DESCRIPTOR;
     }
 
     //
@@ -1230,6 +1244,35 @@ CUSBRequest::BuildBulkInterruptEndpoint(
     return STATUS_SUCCESS;
 }
 
+VOID
+CUSBRequest::DumpEndpointDescriptor(
+    POHCI_ENDPOINT_DESCRIPTOR Descriptor)
+{
+    ULONG Count = 0;
+    POHCI_GENERAL_TD GeneralDescriptor;
+
+    DPRINT1("EndpointDescriptor %p Addr %x\n", Descriptor, Descriptor->PhysicalAddress.LowPart);
+    DPRINT1("EndpointDescriptor HeadPhysicalDescriptor %x HeadLogicalDescriptor %p\n", Descriptor->HeadPhysicalDescriptor, Descriptor->HeadLogicalDescriptor);
+    DPRINT1("EndpointDescriptor TailPhysicalDescriptor %x\n", Descriptor->TailPhysicalDescriptor);
+    DPRINT1("EndpointDescriptor NextDescriptor %x\n", Descriptor->NextDescriptor);
+    DPRINT1("EndpointDescriptor NextPhysicalEndpoint %x\n", Descriptor->NextPhysicalEndpoint);
+    DPRINT1("EndpointDescriptor Flags %x\n", Descriptor->Flags);
+
+
+    GeneralDescriptor = (POHCI_GENERAL_TD)Descriptor->HeadLogicalDescriptor;
+    while(GeneralDescriptor)
+    {
+        DPRINT1("Descriptor %d Address %p Addr %x\n", Count, GeneralDescriptor, GeneralDescriptor->PhysicalAddress);
+        DPRINT1("Descriptor %d BufferLogical %p BufferPhysical %x\n", Count, GeneralDescriptor->BufferLogical, GeneralDescriptor->BufferPhysical);
+        DPRINT1("Descriptor %d BufferSize %d\n", Count, GeneralDescriptor->BufferSize);
+        DPRINT1("Descriptor %d LastPhysicalByteAddress %x\n", Count, GeneralDescriptor->LastPhysicalByteAddress);
+        DPRINT1("Descriptor %d Flags %x\n", Count, GeneralDescriptor->Flags);
+        DPRINT1("Descriptor %d NextLogicalDescriptor %p NextPhysicalDescriptor %x\n", Count, GeneralDescriptor->NextLogicalDescriptor, GeneralDescriptor->NextPhysicalDescriptor);
+
+        Count++;
+        GeneralDescriptor = (POHCI_GENERAL_TD)GeneralDescriptor->NextLogicalDescriptor;
+    }
+}
 
 NTSTATUS
 CUSBRequest::BuildControlTransferDescriptor(
@@ -1293,6 +1336,31 @@ CUSBRequest::BuildControlTransferDescriptor(
         return Status;
     }
 
+    //
+    // initialize setup descriptor
+    //
+    SetupDescriptor->Flags = OHCI_TD_BUFFER_ROUNDING | OHCI_TD_DIRECTION_PID_SETUP | OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED) | OHCI_TD_TOGGLE_0 | OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_NONE);
+
+    //
+    // initialize status descriptor
+    //
+    StatusDescriptor->Flags = OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED) | OHCI_TD_TOGGLE_1 | OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_IMMEDIATE);
+
+    if (m_SetupPacket)
+    {
+        //
+        // copy setup packet
+        //
+        RtlCopyMemory(SetupDescriptor->BufferLogical, m_SetupPacket, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
+    }
+    else
+    {
+        //
+        // generate setup packet from urb
+        //
+        ASSERT(FALSE);
+    }
+
     if (m_TransferBufferLength)
     {
         //
@@ -1312,7 +1380,6 @@ CUSBRequest::BuildControlTransferDescriptor(
             m_DmaManager->Release(EndpointDescriptor, sizeof(OHCI_ENDPOINT_DESCRIPTOR));
             FreeDescriptor(SetupDescriptor);
             FreeDescriptor(StatusDescriptor);
-            FreeDescriptor(LastDescriptor);
             return Status;
         }
 
@@ -1321,30 +1388,10 @@ CUSBRequest::BuildControlTransferDescriptor(
         //
         DataDescriptor->Flags = OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED) | OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_NONE) | OHCI_TD_TOGGLE_CARRY | OHCI_TD_TOGGLE_1;
 
-        if (m_EndpointDescriptor)
-        {
-            if (USB_ENDPOINT_DIRECTION_OUT(m_EndpointDescriptor->bEndpointAddress))
-            {
-                //
-                // direction out
-                //
-                DataDescriptor->Flags |= OHCI_TD_DIRECTION_PID_OUT;
-            }
-            else
-            {
-                //
-                // direction in
-                //
-                DataDescriptor->Flags |= OHCI_TD_DIRECTION_PID_IN;
-            }
-        }
-        else
-        {
-            //
-            // no end point address provided - assume its an in direction
-            //
-            DataDescriptor->Flags |= OHCI_TD_DIRECTION_PID_IN;
-        }
+        //
+        // setup pid direction
+        //
+        DataDescriptor->Flags |= InternalGetPidDirection() == TRUE ? OHCI_TD_DIRECTION_PID_IN : OHCI_TD_DIRECTION_PID_OUT;
 
         //
         // use short packets
@@ -1355,53 +1402,13 @@ CUSBRequest::BuildControlTransferDescriptor(
         // store physical address of buffer
         //
         DataDescriptor->BufferPhysical = MmGetPhysicalAddress(MmGetMdlVirtualAddress(m_TransferBufferMDL)).LowPart;
-        DataDescriptor->LastPhysicalByteAddress = DataDescriptor->BufferPhysical + m_TransferBufferLength - 1; 
-    }
-
-    //
-    // initialize setup descriptor
-    //
-    SetupDescriptor->Flags = OHCI_TD_BUFFER_ROUNDING | OHCI_TD_DIRECTION_PID_SETUP | OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED) | OHCI_TD_TOGGLE_0 | OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_NONE);
-
-    if (m_SetupPacket)
-    {
-        //
-        // copy setup packet
-        //
-        RtlCopyMemory(SetupDescriptor->BufferLogical, m_SetupPacket, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
-    }
-    else
-    {
-        //
-        // generate setup packet from urb
-        //
-        ASSERT(FALSE);
-    }
+        DataDescriptor->LastPhysicalByteAddress = DataDescriptor->BufferPhysical + m_TransferBufferLength - 1;
 
-    //
-    // initialize status descriptor
-    //
-    StatusDescriptor->Flags = OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED) | OHCI_TD_TOGGLE_1 | OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_IMMEDIATE);
-    if (m_TransferBufferLength == 0)
-    {
-        //
-        // input direction is flipped for the status descriptor
-        //
-        StatusDescriptor->Flags |= OHCI_TD_DIRECTION_PID_IN;
-    }
-    else
-    {
         //
-        // output direction is flipped for the status descriptor
+        // flip status pid direction
         //
-        StatusDescriptor->Flags |= OHCI_TD_DIRECTION_PID_OUT;
-    }
+        StatusDescriptor->Flags |= InternalGetPidDirection() == TRUE ? OHCI_TD_DIRECTION_PID_OUT : OHCI_TD_DIRECTION_PID_IN;
 
-    //
-    // now link the descriptors
-    //
-    if (m_TransferBufferLength)
-    {
          //
          // link setup descriptor to data descriptor
          //
@@ -1423,12 +1430,16 @@ CUSBRequest::BuildControlTransferDescriptor(
     }
     else
     {
+        //
+        // status descriptor is always in
+        //
+        StatusDescriptor->Flags |= OHCI_TD_DIRECTION_PID_IN;
+
          //
          // link setup descriptor to status descriptor
          //
          SetupDescriptor->NextPhysicalDescriptor = StatusDescriptor->PhysicalAddress.LowPart;
          SetupDescriptor->NextLogicalDescriptor = StatusDescriptor;
-
          //
          // link status descriptor to last descriptor
          //
@@ -1448,6 +1459,11 @@ CUSBRequest::BuildControlTransferDescriptor(
     //
     *OutEndpointDescriptor = EndpointDescriptor;
 
+    //
+    // dump descriptor
+    //
+    //DumpEndpointDescriptor(EndpointDescriptor);
+
     //
     // done
     //