Author: janderwald
Date: Thu May 26 12:37:18 2011
New Revision: 51922

URL: http://svn.reactos.org/svn/reactos?rev=51922&view=rev
Log:
[USBOHCI]
- Set up periodic threshold (90 %)
- Add function to retrieve interrupt endpoints
- Add function to retrieve specific descriptors from interface. These are used 
by HID devices such as mice / keyboards
- Add function to retrieve interrupt interval
- Enqueue all endpoint descriptors at the end of the associated queue
- Only notify hardware of insertion when it is an bulk / control request
- Scan interrupt endpoint list to find the completed transfer descriptor
- Add debugging function to print out linked endpoint descriptors
- Interrupt transfers are now implemented. 
- Tested in Windows XP SP3 + Vbox 4.04 + Microsoft 5-Button Mouse. The HID 
mouse installs, initializes and starts up. Unfortunately the mouse does not 
work as expected yet

Modified:
    branches/usb-bringup/drivers/usb/usbohci/hardware.cpp
    branches/usb-bringup/drivers/usb/usbohci/hardware.h
    branches/usb-bringup/drivers/usb/usbohci/hub_controller.cpp
    branches/usb-bringup/drivers/usb/usbohci/interfaces.h
    branches/usb-bringup/drivers/usb/usbohci/usb_queue.cpp
    branches/usb-bringup/drivers/usb/usbohci/usb_request.cpp

Modified: branches/usb-bringup/drivers/usb/usbohci/hardware.cpp
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbohci/hardware.cpp?rev=51922&r1=51921&r2=51922&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbohci/hardware.cpp [iso-8859-1] 
(original)
+++ branches/usb-bringup/drivers/usb/usbohci/hardware.cpp [iso-8859-1] Thu May 
26 12:37:18 2011
@@ -61,6 +61,7 @@
     NTSTATUS GetDeviceDetails(PUSHORT VendorId, PUSHORT DeviceId, PULONG 
NumberOfPorts, PULONG Speed);
     NTSTATUS GetBulkHeadEndpointDescriptor(struct _OHCI_ENDPOINT_DESCRIPTOR ** 
OutDescriptor);
     NTSTATUS GetControlHeadEndpointDescriptor(struct _OHCI_ENDPOINT_DESCRIPTOR 
** OutDescriptor);
+    NTSTATUS GetInterruptEndpointDescriptors(struct _OHCI_ENDPOINT_DESCRIPTOR 
*** OutDescriptor);
     VOID HeadEndpointDescriptorModified(ULONG HeadType);
 
     NTSTATUS GetDMA(OUT struct IDMAMemoryManager **m_DmaManager);
@@ -113,16 +114,16 @@
     PHYSICAL_ADDRESS m_HCCAPhysicalAddress;                                    
        // hcca physical address
     POHCI_ENDPOINT_DESCRIPTOR m_ControlEndpointDescriptor;                     
        // dummy control endpoint descriptor
     POHCI_ENDPOINT_DESCRIPTOR m_BulkEndpointDescriptor;                        
        // dummy control endpoint descriptor
-    POHCI_ENDPOINT_DESCRIPTOR  m_IsoEndpointDescriptor;                        
        // iso endpoint descriptor
+    POHCI_ENDPOINT_DESCRIPTOR m_IsoEndpointDescriptor;                         
        // iso endpoint descriptor
     POHCI_ENDPOINT_DESCRIPTOR 
m_InterruptEndpoints[OHCI_STATIC_ENDPOINT_COUNT];        // endpoints for 
interrupt / iso transfers
     ULONG m_NumberOfPorts;                                                     
        // number of ports
     OHCI_PORT_STATUS m_PortStatus[OHCI_MAX_PORT_COUNT];                        
        // port change status
     PDMAMEMORYMANAGER m_MemoryManager;                                         
        // memory manager
     HD_INIT_CALLBACK* m_SCECallBack;                                           
        // status change callback routine
     PVOID m_SCEContext;                                                        
        // status change callback routine context
-    BOOLEAN m_DoorBellRingInProgress;                                          
        // door bell ring in progress
     WORK_QUEUE_ITEM m_StatusChangeWorkItem;                                    
        // work item for status change callback
     ULONG m_SyncFramePhysAddr;                                                 
        // periodic frame list physical address
+    ULONG m_IntervalValue;                                                     
        // periodic interval value
 };
 
 
//=================================================================================================
@@ -489,7 +490,7 @@
 NTSTATUS
 CUSBHardwareDevice::StartController(void)
 {
-    ULONG Control, NumberOfPorts, Index, Descriptor, FrameInterval, Periodic, 
IntervalValue;
+    ULONG Control, NumberOfPorts, Index, Descriptor, FrameInterval, Periodic;
 
     //
     // first write address of HCCA
@@ -545,16 +546,19 @@
     //
     // get frame interval
     //
-    //FrameInterval = (READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_FRAME_INTERVAL_OFFSET)) & OHCI_FRAME_INTERVAL_TOGGLE) ^ 
OHCI_FRAME_INTERVAL_TOGGLE;
-    //FrameInterval |= OHCI_FSMPS(IntervalValue) | IntervalValue;
+    FrameInterval = (READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_FRAME_INTERVAL_OFFSET)) & OHCI_FRAME_INTERVAL_TOGGLE) ^ 
OHCI_FRAME_INTERVAL_TOGGLE;
+    FrameInterval |= OHCI_FSMPS(m_IntervalValue) | m_IntervalValue;
 
     //
     // write frame interval
     //
-    //WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_FRAME_INTERVAL_OFFSET), FrameInterval);
-    // 90% periodic
-    //Periodic = OHCI_PERIODIC(intervalValue);
-    WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 0x40 
/*OHCI_PERIODIC_START_OFFSET*/), 0x3E67);
+    WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_FRAME_INTERVAL_OFFSET), FrameInterval);
+
+    //
+    // 90 % periodic
+    //
+    Periodic = OHCI_PERIODIC(m_IntervalValue);
+    WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_PERIODIC_START_OFFSET), Periodic);
 
 
     //
@@ -686,6 +690,14 @@
     return STATUS_SUCCESS;
 }
 
+NTSTATUS
+CUSBHardwareDevice::GetInterruptEndpointDescriptors(
+    struct _OHCI_ENDPOINT_DESCRIPTOR *** OutDescriptor)
+{
+    *OutDescriptor = m_InterruptEndpoints;
+    return STATUS_SUCCESS;
+}
+
 VOID
 CUSBHardwareDevice::HeadEndpointDescriptorModified(
     ULONG Type)
@@ -846,7 +858,7 @@
 CUSBHardwareDevice::StopController(void)
 {
     ULONG Control, Reset;
-    ULONG Index;
+    ULONG Index, FrameInterval;
 
     //
     // first turn off all interrupts
@@ -877,6 +889,16 @@
     // wait a bit
     //
     KeStallExecutionProcessor(100);
+
+    //
+    // read from interval
+    //
+    FrameInterval = READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_FRAME_INTERVAL_OFFSET));
+
+    //
+    // store interval value for later
+    //
+    m_IntervalValue = OHCI_GET_INTERVAL_VALUE(FrameInterval);
 
     //
     // now reset controller

Modified: branches/usb-bringup/drivers/usb/usbohci/hardware.h
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbohci/hardware.h?rev=51922&r1=51921&r2=51922&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbohci/hardware.h [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbohci/hardware.h [iso-8859-1] Thu May 26 
12:37:18 2011
@@ -90,6 +90,19 @@
 #define OHCI_RH_NO_OVER_CURRENT_PROTECTION          0x1000
 #define OHCI_RH_GET_POWER_ON_TO_POWER_GOOD_TIME(s)  ((s) >> 24)
 
+//
+//  Frame interval register (section 7.3.1)
+//
+#define OHCI_FRAME_INTERVAL_OFFSET                 0x34
+#define OHCI_GET_INTERVAL_VALUE(s)          ((s) & 0x3fff)
+#define OHCI_GET_FS_LARGEST_DATA_PACKET(s)  (((s) >> 16) & 0x7fff)
+#define OHCI_FRAME_INTERVAL_TOGGLE          0x80000000
+
+//
+// periodic start register
+//
+#define OHCI_PERIODIC_START_OFFSET             0x40
+#define OHCI_PERIODIC(i)            ((i) * 9 / 10)
 
 //
 //  Root Hub Descriptor B register (section 7.4.2)

Modified: branches/usb-bringup/drivers/usb/usbohci/hub_controller.cpp
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbohci/hub_controller.cpp?rev=51922&r1=51921&r2=51922&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbohci/hub_controller.cpp [iso-8859-1] 
(original)
+++ branches/usb-bringup/drivers/usb/usbohci/hub_controller.cpp [iso-8859-1] 
Thu May 26 12:37:18 2011
@@ -60,6 +60,7 @@
     VOID SetNotification(PVOID CallbackContext, PRH_INIT_CALLBACK 
CallbackRoutine);
     // internal ioctl routines
     NTSTATUS HandleGetDescriptor(IN OUT PIRP Irp, PURB Urb);
+    NTSTATUS HandleGetDescriptorFromInterface(IN OUT PIRP Irp, PURB Urb);
     NTSTATUS HandleClassDevice(IN OUT PIRP Irp, PURB Urb);
     NTSTATUS HandleGetStatusFromDevice(IN OUT PIRP Irp, PURB Urb);
     NTSTATUS HandleSelectConfiguration(IN OUT PIRP Irp, PURB Urb);
@@ -1223,6 +1224,55 @@
 
     return Status;
 }
+
+//-----------------------------------------------------------------------------------------
+NTSTATUS
+CHubController::HandleGetDescriptorFromInterface(
+    IN OUT PIRP Irp,
+    IN OUT PURB Urb)
+{
+    PUSBDEVICE UsbDevice;
+    USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
+    NTSTATUS Status;
+
+    //
+    // sanity check
+    //
+    ASSERT(Urb->UrbControlDescriptorRequest.TransferBufferLength);
+    ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer);
+
+    //
+    // check if this is a valid usb device handle
+    //
+    ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)));
+
+    //
+    // get device
+    //
+    UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
+
+    //
+    // generate setup packet
+    //
+    CtrlSetup.bRequest = USB_REQUEST_GET_DESCRIPTOR;
+    CtrlSetup.wValue.LowByte = Urb->UrbControlDescriptorRequest.Index;
+    CtrlSetup.wValue.HiByte = Urb->UrbControlDescriptorRequest.DescriptorType;
+    CtrlSetup.wIndex.W = Urb->UrbControlDescriptorRequest.LanguageId;
+    CtrlSetup.wLength = 
(USHORT)Urb->UrbControlDescriptorRequest.TransferBufferLength;
+    CtrlSetup.bmRequestType.B = 0x81;
+
+    //
+    // submit setup packet
+    //
+    Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, 
Urb->UrbControlDescriptorRequest.TransferBufferLength, 
Urb->UrbControlDescriptorRequest.TransferBuffer);
+    ASSERT(Status == STATUS_SUCCESS);
+
+    //
+    // done
+    //
+    return Status;
+}
+
 
//-----------------------------------------------------------------------------------------
 NTSTATUS
 CHubController::HandleGetDescriptor(
@@ -1492,8 +1542,8 @@
     //
     // sanity check
     //
-    PC_ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer);
-    PC_ASSERT(Urb->UrbControlVendorClassRequest.TransferBufferLength);
+    //ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer || 
Urb->UrbControlVendorClassRequest.TransferBufferMDL);
+    //ASSERT(Urb->UrbControlVendorClassRequest.TransferBufferLength);
     PC_ASSERT(Urb->UrbHeader.UsbdDeviceHandle);
 
     //
@@ -1520,7 +1570,7 @@
     //
     // initialize setup packet
     //
-    CtrlSetup.bmRequestType.B = 0xa1; //FIXME: Const.
+    CtrlSetup.bmRequestType.B = 0xa1;
     CtrlSetup.bRequest = Urb->UrbControlVendorClassRequest.Request;
     CtrlSetup.wValue.W = Urb->UrbControlVendorClassRequest.Value;
     CtrlSetup.wIndex.W = Urb->UrbControlVendorClassRequest.Index;
@@ -1579,6 +1629,9 @@
 
             switch (Urb->UrbHeader.Function)
             {
+                case URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE:
+                    Status = HandleGetDescriptorFromInterface(Irp, Urb);
+                    break;
                 case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
                     Status = HandleGetDescriptor(Irp, Urb);
                     break;

Modified: branches/usb-bringup/drivers/usb/usbohci/interfaces.h
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbohci/interfaces.h?rev=51922&r1=51921&r2=51922&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbohci/interfaces.h [iso-8859-1] 
(original)
+++ branches/usb-bringup/drivers/usb/usbohci/interfaces.h [iso-8859-1] Thu May 
26 12:37:18 2011
@@ -187,6 +187,14 @@
 // Description: returns the control head endpoint descriptor
 
     virtual NTSTATUS GetControlHeadEndpointDescriptor(struct 
_OHCI_ENDPOINT_DESCRIPTOR ** OutDescriptor) = 0;
+
+//-----------------------------------------------------------------------------------------
+//
+// GetInterruptEndpointDescriptors
+//
+// Description: returns interrupt endpoint descriptors
+
+    virtual NTSTATUS GetInterruptEndpointDescriptors(struct 
_OHCI_ENDPOINT_DESCRIPTOR *** OutDescriptorArray) = 0;
 
 
//-----------------------------------------------------------------------------------------
 //
@@ -451,6 +459,15 @@
 // Description: frees the associated endpoint descriptor and its general 
descriptors
 
     virtual VOID FreeEndpointDescriptor(struct _OHCI_ENDPOINT_DESCRIPTOR * 
OutDescriptor) = 0;
+
+//-----------------------------------------------------------------------------------------
+//
+// GetInterruptInterval
+//
+// Description: returns interval of the iso / interrupt
+
+    virtual UCHAR GetInterval() = 0;
+
 };
 
 

Modified: branches/usb-bringup/drivers/usb/usbohci/usb_queue.cpp
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbohci/usb_queue.cpp?rev=51922&r1=51921&r2=51922&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbohci/usb_queue.cpp [iso-8859-1] 
(original)
+++ branches/usb-bringup/drivers/usb/usbohci/usb_queue.cpp [iso-8859-1] Thu May 
26 12:37:18 2011
@@ -44,7 +44,12 @@
     // local functions
     BOOLEAN IsTransferDescriptorInEndpoint(IN POHCI_ENDPOINT_DESCRIPTOR 
EndpointDescriptor, IN ULONG TransferDescriptorLogicalAddress);
     NTSTATUS FindTransferDescriptorInEndpoint(IN POHCI_ENDPOINT_DESCRIPTOR 
EndpointDescriptor, IN ULONG TransferDescriptorLogicalAddress, OUT 
POHCI_ENDPOINT_DESCRIPTOR *OutEndpointDescriptor, OUT POHCI_ENDPOINT_DESCRIPTOR 
*OutPreviousEndpointDescriptor);
+    NTSTATUS FindTransferDescriptorInInterruptHeadEndpoints(IN ULONG 
TransferDescriptorLogicalAddress, OUT POHCI_ENDPOINT_DESCRIPTOR 
*OutEndpointDescriptor, OUT POHCI_ENDPOINT_DESCRIPTOR 
*OutPreviousEndpointDescriptor);
+
     VOID CleanupEndpointDescriptor(POHCI_ENDPOINT_DESCRIPTOR 
EndpointDescriptor, POHCI_ENDPOINT_DESCRIPTOR PreviousEndpointDescriptor);
+    POHCI_ENDPOINT_DESCRIPTOR FindInterruptEndpointDescriptor(UCHAR 
InterruptInterval);
+    VOID PrintEndpointList(POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor);
+    VOID LinkEndpoint(POHCI_ENDPOINT_DESCRIPTOR HeadEndpointDescriptor, 
POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor);
 
     // constructor / destructor
     CUSBQueue(IUnknown *OuterUnknown){}
@@ -56,6 +61,7 @@
     PUSBHARDWAREDEVICE m_Hardware;                                             
         // hardware
     POHCI_ENDPOINT_DESCRIPTOR m_BulkHeadEndpointDescriptor;                    
         // bulk head descriptor
     POHCI_ENDPOINT_DESCRIPTOR m_ControlHeadEndpointDescriptor;                 
         // control head descriptor
+    POHCI_ENDPOINT_DESCRIPTOR * m_InterruptEndpoints;
 };
 
 
//=================================================================================================
@@ -95,6 +101,11 @@
     
Hardware->GetControlHeadEndpointDescriptor(&m_ControlHeadEndpointDescriptor);
 
     //
+    // get interrupt endpoints
+    //
+    Hardware->GetInterruptEndpointDescriptors(&m_InterruptEndpoints);
+
+    //
     // initialize spinlock
     //
     KeInitializeSpinLock(&m_Lock);
@@ -116,6 +127,32 @@
     //
 
     return 0;
+}
+
+VOID
+CUSBQueue::LinkEndpoint(
+    POHCI_ENDPOINT_DESCRIPTOR HeadEndpointDescriptor,
+    POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor)
+{
+    POHCI_ENDPOINT_DESCRIPTOR CurrentEndpointDescriptor = 
HeadEndpointDescriptor;
+
+    //
+    // get last descriptor in queue
+    //
+    while(CurrentEndpointDescriptor->NextDescriptor)
+    {
+        //
+        // move to last descriptor
+        //
+        CurrentEndpointDescriptor = 
(POHCI_ENDPOINT_DESCRIPTOR)CurrentEndpointDescriptor->NextDescriptor;
+    }
+
+    //
+    // link endpoints
+    //
+    CurrentEndpointDescriptor->NextPhysicalEndpoint = 
EndpointDescriptor->PhysicalAddress.LowPart;
+    CurrentEndpointDescriptor->NextDescriptor = EndpointDescriptor;
+
 }
 
 NTSTATUS
@@ -146,10 +183,10 @@
     switch(Type)
     {
         case USB_ENDPOINT_TYPE_ISOCHRONOUS:
-        case USB_ENDPOINT_TYPE_INTERRUPT:
             /* NOT IMPLEMENTED IN QUEUE */
             Status = STATUS_NOT_SUPPORTED;
             break;
+        case USB_ENDPOINT_TYPE_INTERRUPT:
         case USB_ENDPOINT_TYPE_CONTROL:
         case USB_ENDPOINT_TYPE_BULK:
             Status = STATUS_SUCCESS;
@@ -213,31 +250,35 @@
         //
         HeadDescriptor = m_ControlHeadEndpointDescriptor;
     }
-
-    //
-    // link endpoints
-    //
-    Descriptor->NextPhysicalEndpoint = HeadDescriptor->NextPhysicalEndpoint;
-    Descriptor->NextDescriptor = HeadDescriptor->NextDescriptor;
-
-    HeadDescriptor->NextPhysicalEndpoint = Descriptor->PhysicalAddress.LowPart;
-    HeadDescriptor->NextDescriptor = Descriptor;
+    else if (Type == USB_ENDPOINT_TYPE_INTERRUPT)
+    {
+        //
+        // get head descriptor
+        //
+        HeadDescriptor = 
FindInterruptEndpointDescriptor(Request->GetInterval());
+        ASSERT(HeadDescriptor);
+    }
+
+    //
+    // insert endpoint at end
+    //
+    LinkEndpoint(HeadDescriptor, Descriptor);
 
     //
     // set descriptor active
     //
     Descriptor->Flags &= ~OHCI_ENDPOINT_SKIP;
-    //HeadDescriptor->Flags &= ~OHCI_ENDPOINT_SKIP;
 
     DPRINT("Request %x Logical %x added to queue Queue %p Logical %x\n", 
Descriptor, Descriptor->PhysicalAddress.LowPart, HeadDescriptor, 
HeadDescriptor->PhysicalAddress.LowPart);
 
 
-    //
-    // notify hardware of our request
-    //
-    m_Hardware->HeadEndpointDescriptorModified(Type);
-
-
+    if (Type == USB_ENDPOINT_TYPE_CONTROL || Type == USB_ENDPOINT_TYPE_BULK)
+    {
+        //
+        // notify hardware of our request
+        //
+        m_Hardware->HeadEndpointDescriptorModified(Type);
+    }
 
     return STATUS_SUCCESS;
 }
@@ -318,6 +359,35 @@
     return STATUS_NOT_FOUND;
 }
 
+NTSTATUS
+CUSBQueue::FindTransferDescriptorInInterruptHeadEndpoints(IN ULONG 
TransferDescriptorLogicalAddress, OUT POHCI_ENDPOINT_DESCRIPTOR 
*OutEndpointDescriptor, OUT POHCI_ENDPOINT_DESCRIPTOR 
*OutPreviousEndpointDescriptor)
+{
+    ULONG Index;
+    NTSTATUS Status;
+
+    //
+    // search descriptor in endpoint list
+    //
+    for(Index = 0; Index < OHCI_STATIC_ENDPOINT_COUNT; Index++)
+    {
+        //
+        // is it in current endpoint
+        //
+        Status = FindTransferDescriptorInEndpoint(m_InterruptEndpoints[Index], 
TransferDescriptorLogicalAddress, OutEndpointDescriptor, 
OutPreviousEndpointDescriptor);
+        if (NT_SUCCESS(Status))
+        {
+            //
+            // found transfer descriptor
+            //
+            return STATUS_SUCCESS;
+        }
+    }
+
+    //
+    // not found
+    //
+    return STATUS_NOT_FOUND;
+}
 
 BOOLEAN
 CUSBQueue::IsTransferDescriptorInEndpoint(
@@ -399,7 +469,27 @@
     Request->Release();
 
 }
-
+VOID
+CUSBQueue::PrintEndpointList(
+    POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor)
+{
+    DPRINT1("CUSBQueue::PrintEndpointList HeadEndpoint %p Logical %x\n", 
EndpointDescriptor, EndpointDescriptor->PhysicalAddress.LowPart);
+
+    //
+    // get first general transfer descriptor
+    //
+    EndpointDescriptor = 
(POHCI_ENDPOINT_DESCRIPTOR)EndpointDescriptor->NextDescriptor;
+
+    while(EndpointDescriptor)
+    {
+        DPRINT1("    CUSBQueue::PrintEndpointList Endpoint %p Logical %x\n", 
EndpointDescriptor, EndpointDescriptor->PhysicalAddress.LowPart);
+
+        //
+        // move to next
+        //
+        EndpointDescriptor = 
(POHCI_ENDPOINT_DESCRIPTOR)EndpointDescriptor->NextDescriptor;
+    }
+}
 
 VOID
 CUSBQueue::TransferDescriptorCompletionCallback(
@@ -445,13 +535,72 @@
     }
 
     //
+    // find transfer descriptor in interrupt list
+    //
+    Status = 
FindTransferDescriptorInInterruptHeadEndpoints(TransferDescriptorLogicalAddress,
 &EndpointDescriptor, &PreviousEndpointDescriptor);
+    if (NT_SUCCESS(Status))
+    {
+        //
+        // cleanup endpoint
+        //
+        CleanupEndpointDescriptor(EndpointDescriptor, 
PreviousEndpointDescriptor);
+
+        //
+        // done
+        //
+        return;
+    }
+
+
+    //
     // hardware reported dead endpoint completed
     //
-    DPRINT1("CUSBQueue::TransferDescriptorCompletionCallback invalid transfer 
descriptor %x\n", TransferDescriptorLogicalAddress);
+    DPRINT("CUSBQueue::TransferDescriptorCompletionCallback invalid transfer 
descriptor %x\n", TransferDescriptorLogicalAddress);
     ASSERT(FALSE);
 
 }
 
+POHCI_ENDPOINT_DESCRIPTOR
+CUSBQueue::FindInterruptEndpointDescriptor(
+    UCHAR InterruptInterval)
+{
+    ULONG Index = 0;
+    ULONG Power = 1;
+
+    //
+    // sanity check
+    //
+    ASSERT(InterruptInterval < OHCI_BIGGEST_INTERVAL);
+
+    //
+    // find interrupt index
+    //
+    while (Power <= OHCI_BIGGEST_INTERVAL / 2)
+    {
+        //
+        // is current interval greater
+        //
+        if (Power * 2 > InterruptInterval)
+            break;
+
+        //
+        // increment power
+        //
+        Power *= 2;
+
+        //
+        // move to next interrupt
+        //
+        Index++;
+    }
+
+    DPRINT("InterruptInterval %lu Selected InterruptIndex %lu Choosen Interval 
%lu\n", InterruptInterval, Index, Power);
+
+    //
+    // return endpoint
+    //
+    return m_InterruptEndpoints[Index];
+}
 
 NTSTATUS
 CreateUSBQueue(

Modified: branches/usb-bringup/drivers/usb/usbohci/usb_request.cpp
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbohci/usb_request.cpp?rev=51922&r1=51921&r2=51922&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbohci/usb_request.cpp [iso-8859-1] 
(original)
+++ branches/usb-bringup/drivers/usb/usbohci/usb_request.cpp [iso-8859-1] Thu 
May 26 12:37:18 2011
@@ -46,6 +46,8 @@
     virtual BOOLEAN IsQueueHeadComplete(struct _QUEUE_HEAD * QueueHead);
     virtual VOID CompletionCallback(struct _OHCI_ENDPOINT_DESCRIPTOR * 
OutDescriptor);
     virtual VOID FreeEndpointDescriptor(struct _OHCI_ENDPOINT_DESCRIPTOR * 
OutDescriptor);
+    virtual UCHAR GetInterval();
+
 
     // local functions
     ULONG InternalGetTransferType();
@@ -378,6 +380,18 @@
 }
 
 UCHAR
+CUSBRequest::GetInterval()
+{
+    ASSERT(m_EndpointDescriptor);
+    ASSERT((m_EndpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK) == 
USB_ENDPOINT_TYPE_INTERRUPT);
+
+    //
+    // return interrupt interval
+    //
+    return m_EndpointDescriptor->bInterval;
+}
+
+UCHAR
 CUSBRequest::GetEndpointAddress()
 {
     if (!m_EndpointDescriptor)
@@ -786,7 +800,7 @@
             FirstDescriptor = CurrentDescriptor;
         }
 
-        DPRINT("PreviousDescriptor %p CurrentDescriptor %p  Buffer Logical %p 
Physical %x Last Physical %x CurrentSize %lu\n", PreviousDescriptor, 
CurrentDescriptor, CurrentDescriptor->BufferLogical, 
CurrentDescriptor->BufferPhysical, CurrentDescriptor->LastPhysicalByteAddress, 
CurrentSize);
+        DPRINT("PreviousDescriptor %p CurrentDescriptor %p Logical %x  Buffer 
Logical %p Physical %x Last Physical %x CurrentSize %lu\n", PreviousDescriptor, 
CurrentDescriptor, CurrentDescriptor->PhysicalAddress.LowPart, 
CurrentDescriptor->BufferLogical, CurrentDescriptor->BufferPhysical, 
CurrentDescriptor->LastPhysicalByteAddress, CurrentSize);
 
         //
         //  set previous descriptor
@@ -847,7 +861,6 @@
     // done
     //
     return STATUS_SUCCESS;
-
 }
 
 


Reply via email to