Author: janderwald
Date: Fri Feb  3 14:47:18 2012
New Revision: 55394

URL: http://svn.reactos.org/svn/reactos?rev=55394&view=rev
Log:
[USBOHCI]
- Implement reseting pipe and clear pipe stall

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

Modified: branches/usb-bringup-trunk/drivers/usb/usbohci/hardware.h
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/usbohci/hardware.h?rev=55394&r1=55393&r2=55394&view=diff
==============================================================================
--- branches/usb-bringup-trunk/drivers/usb/usbohci/hardware.h [iso-8859-1] 
(original)
+++ branches/usb-bringup-trunk/drivers/usb/usbohci/hardware.h [iso-8859-1] Fri 
Feb  3 14:47:18 2012
@@ -229,6 +229,7 @@
 
 #define OHCI_ENDPOINT_SKIP                      0x00004000
 #define OHCI_ENDPOINT_SET_DEVICE_ADDRESS(s)     (s)
+#define OHCI_ENDPOINT_GET_DEVICE_ADDRESS(s)     ((s) & 0xFF)
 #define OHCI_ENDPOINT_GET_ENDPOINT_NUMBER(s)    (((s) >> 7) & 0xf)
 #define OHCI_ENDPOINT_SET_ENDPOINT_NUMBER(s)    ((s) << 7)
 #define OHCI_ENDPOINT_GET_MAX_PACKET_SIZE(s)    (((s) >> 16) & 0x07ff)

Modified: branches/usb-bringup-trunk/drivers/usb/usbohci/hub_controller.cpp
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/usbohci/hub_controller.cpp?rev=55394&r1=55393&r2=55394&view=diff
==============================================================================
--- branches/usb-bringup-trunk/drivers/usb/usbohci/hub_controller.cpp 
[iso-8859-1] (original)
+++ branches/usb-bringup-trunk/drivers/usb/usbohci/hub_controller.cpp 
[iso-8859-1] Fri Feb  3 14:47:18 2012
@@ -70,6 +70,9 @@
     NTSTATUS HandleClassEndpoint(IN OUT PIRP Irp, PURB Urb);
     NTSTATUS HandleBulkOrInterruptTransfer(IN OUT PIRP Irp, PURB Urb);
     NTSTATUS HandleIsochronousTransfer(IN OUT PIRP Irp, PURB Urb);
+    NTSTATUS HandleClearStall(IN OUT PIRP Irp, PURB Urb);
+    NTSTATUS HandleSyncResetAndClearStall(IN OUT PIRP Irp, PURB Urb);
+    NTSTATUS HandleAbortPipe(IN OUT PIRP Irp, PURB Urb);
 
     friend VOID StatusChangeEndpointCallBack(PVOID Context);
 
@@ -1692,6 +1695,187 @@
     return Status;
 }
 
+NTSTATUS
+CHubController::HandleSyncResetAndClearStall(
+    IN OUT PIRP Irp,
+    IN OUT PURB Urb)
+{
+    USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
+    NTSTATUS Status = STATUS_SUCCESS;
+    PUSBDEVICE UsbDevice;
+    PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
+    ULONG Type;
+
+    //
+    // sanity check
+    //
+    PC_ASSERT(Urb->UrbHeader.UsbdDeviceHandle);
+    PC_ASSERT(Urb->UrbHeader.Length == sizeof(struct _URB_PIPE_REQUEST));
+    PC_ASSERT(Urb->UrbPipeRequest.PipeHandle);
+
+    //
+    // check if this is a valid usb device handle
+    //
+    if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
+    {
+        DPRINT1("HandleAbortPipe invalid device handle %p\n", 
Urb->UrbHeader.UsbdDeviceHandle);
+
+        //
+        // invalid device handle
+        //
+        return STATUS_DEVICE_NOT_CONNECTED;
+    }
+
+    //
+    // get endpoint descriptor
+    //
+    EndpointDescriptor = 
(PUSB_ENDPOINT_DESCRIPTOR)Urb->UrbPipeRequest.PipeHandle;
+
+    //
+    // get type
+    //
+    Type = (EndpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK);
+    if (Type != USB_ENDPOINT_TYPE_ISOCHRONOUS)
+    {
+        //
+        // clear stall
+        //
+        Status = HandleClearStall(Irp, Urb);
+    }
+    DPRINT1("URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL Status %x\n", 
Status);
+
+    //
+    // FIXME reset data toggle
+    //
+
+    //
+    // done
+    //
+    return Status;
+}
+
+NTSTATUS
+CHubController::HandleAbortPipe(
+    IN OUT PIRP Irp,
+    IN OUT PURB Urb)
+{
+    USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
+    NTSTATUS Status;
+    PUSBDEVICE UsbDevice;
+    PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
+
+
+    //
+    // sanity check
+    //
+    PC_ASSERT(Urb->UrbHeader.UsbdDeviceHandle);
+    PC_ASSERT(Urb->UrbHeader.Length == sizeof(struct _URB_PIPE_REQUEST));
+    PC_ASSERT(Urb->UrbPipeRequest.PipeHandle);
+
+    //
+    // check if this is a valid usb device handle
+    //
+    if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
+    {
+        DPRINT1("HandleAbortPipe invalid device handle %p\n", 
Urb->UrbHeader.UsbdDeviceHandle);
+
+        //
+        // invalid device handle
+        //
+        return STATUS_DEVICE_NOT_CONNECTED;
+    }
+
+    //
+    // get endpoint descriptor
+    //
+    EndpointDescriptor = 
(PUSB_ENDPOINT_DESCRIPTOR)Urb->UrbPipeRequest.PipeHandle;
+
+    //
+    // get device
+    //
+    UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
+
+
+    //
+    // issue request
+    //
+    Status = UsbDevice->AbortPipe(EndpointDescriptor);
+    DPRINT1("URB_FUNCTION_ABORT_PIPE Status %x\n", Status);
+
+    //
+    // done
+    //
+    return Status;
+}
+
+
+//-----------------------------------------------------------------------------------------
+NTSTATUS
+CHubController::HandleClearStall(
+    IN OUT PIRP Irp,
+    IN OUT PURB Urb)
+{
+    USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
+    NTSTATUS Status;
+    PUSBDEVICE UsbDevice;
+    PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
+
+
+    //
+    // sanity check
+    //
+    PC_ASSERT(Urb->UrbHeader.UsbdDeviceHandle);
+    PC_ASSERT(Urb->UrbHeader.Length == sizeof(struct _URB_PIPE_REQUEST));
+    PC_ASSERT(Urb->UrbPipeRequest.PipeHandle);
+
+    //
+    // check if this is a valid usb device handle
+    //
+    if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
+    {
+        DPRINT1("HandleClearStall invalid device handle %p\n", 
Urb->UrbHeader.UsbdDeviceHandle);
+
+        //
+        // invalid device handle
+        //
+        return STATUS_DEVICE_NOT_CONNECTED;
+    }
+
+    //
+    // get endpoint descriptor
+    //
+    EndpointDescriptor = 
(PUSB_ENDPOINT_DESCRIPTOR)Urb->UrbPipeRequest.PipeHandle;
+
+    //
+    // get device
+    //
+    UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
+    DPRINT1("URB_FUNCTION_SYNC_CLEAR_STALL\n");
+
+    //
+    // initialize setup packet
+    //
+    CtrlSetup.bmRequestType.B = 0x02;
+    CtrlSetup.bRequest = USB_REQUEST_CLEAR_FEATURE;
+    CtrlSetup.wValue.W = USB_FEATURE_ENDPOINT_STALL;
+    CtrlSetup.wIndex.W = EndpointDescriptor->bEndpointAddress;
+    CtrlSetup.wLength = 0;
+    CtrlSetup.wValue.W = 0;
+
+    //
+    // issue request
+    //
+    Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, 0, 0);
+
+    DPRINT1("URB_FUNCTION_CLEAR_STALL Status %x\n", Status);
+
+    //
+    // done
+    //
+    return Status;
+}
+
+
 
//-----------------------------------------------------------------------------------------
 NTSTATUS
 CHubController::HandleClassInterface(
@@ -1813,6 +1997,16 @@
 
             switch (Urb->UrbHeader.Function)
             {
+                case URB_FUNCTION_SYNC_RESET_PIPE:
+                case URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL:
+                    Status = HandleSyncResetAndClearStall(Irp, Urb);
+                    break;
+                case URB_FUNCTION_ABORT_PIPE:
+                    Status = HandleAbortPipe(Irp, Urb);
+                    break;
+                case URB_FUNCTION_SYNC_CLEAR_STALL:
+                    Status = HandleClearStall(Irp, Urb);
+                    break;
                 case URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE:
                     Status = HandleGetDescriptorFromInterface(Irp, Urb);
                     break;

Modified: branches/usb-bringup-trunk/drivers/usb/usbohci/interfaces.h
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/usbohci/interfaces.h?rev=55394&r1=55393&r2=55394&view=diff
==============================================================================
--- branches/usb-bringup-trunk/drivers/usb/usbohci/interfaces.h [iso-8859-1] 
(original)
+++ branches/usb-bringup-trunk/drivers/usb/usbohci/interfaces.h [iso-8859-1] 
Fri Feb  3 14:47:18 2012
@@ -556,6 +556,14 @@
 
     virtual VOID TransferDescriptorCompletionCallback(ULONG 
TransferDescriptorLogicalAddress) = 0;
 
+
+//-----------------------------------------------------------------------------------------
+//
+// AbortDevicePipe
+//
+// Description: aborts all pending requsts of an device
+
+    virtual NTSTATUS AbortDevicePipe(UCHAR DeviceAddress, IN 
PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor) = 0;
 };
 
 typedef IUSBQueue *PUSBQUEUE;
@@ -809,6 +817,16 @@
 
     virtual NTSTATUS SelectInterface(IN USBD_CONFIGURATION_HANDLE 
ConfigurationHandle,
                                      IN OUT PUSBD_INTERFACE_INFORMATION 
Interface) = 0;
+
+
+//-----------------------------------------------------------------------------------------
+//
+// AbortPipe
+//
+// Description: aborts all pending requsts
+
+    virtual NTSTATUS AbortPipe(IN PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor) 
= 0;
+
 };
 
 typedef IUSBDevice *PUSBDEVICE;

Modified: branches/usb-bringup-trunk/drivers/usb/usbohci/usb_device.cpp
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/usbohci/usb_device.cpp?rev=55394&r1=55393&r2=55394&view=diff
==============================================================================
--- branches/usb-bringup-trunk/drivers/usb/usbohci/usb_device.cpp [iso-8859-1] 
(original)
+++ branches/usb-bringup-trunk/drivers/usb/usbohci/usb_device.cpp [iso-8859-1] 
Fri Feb  3 14:47:18 2012
@@ -52,6 +52,7 @@
     virtual NTSTATUS SubmitSetupPacket(IN PUSB_DEFAULT_PIPE_SETUP_PACKET 
SetupPacket, OUT ULONG BufferLength, OUT PVOID Buffer);
     virtual NTSTATUS SelectConfiguration(IN PUSB_CONFIGURATION_DESCRIPTOR 
ConfigurationDescriptor, IN PUSBD_INTERFACE_INFORMATION Interface, OUT 
USBD_CONFIGURATION_HANDLE *ConfigurationHandle);
     virtual NTSTATUS SelectInterface(IN USBD_CONFIGURATION_HANDLE 
ConfigurationHandle, IN OUT PUSBD_INTERFACE_INFORMATION Interface);
+    virtual NTSTATUS AbortPipe(IN PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor);
 
     // local function
     virtual NTSTATUS CommitIrp(PIRP Irp);
@@ -1174,6 +1175,22 @@
     return Status;
 }
 
+NTSTATUS
+CUSBDevice::AbortPipe(
+    IN PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor)
+{
+    //
+    // let it handle usb queue
+    //
+    ASSERT(m_Queue);
+    ASSERT(m_DeviceAddress);
+
+    //
+    // done
+    //
+    return m_Queue->AbortDevicePipe(m_DeviceAddress, EndpointDescriptor);
+}
+
 
//----------------------------------------------------------------------------------------
 NTSTATUS
 CreateUSBDevice(

Modified: branches/usb-bringup-trunk/drivers/usb/usbohci/usb_queue.cpp
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/usbohci/usb_queue.cpp?rev=55394&r1=55393&r2=55394&view=diff
==============================================================================
--- branches/usb-bringup-trunk/drivers/usb/usbohci/usb_queue.cpp [iso-8859-1] 
(original)
+++ branches/usb-bringup-trunk/drivers/usb/usbohci/usb_queue.cpp [iso-8859-1] 
Fri Feb  3 14:47:18 2012
@@ -40,6 +40,7 @@
     virtual NTSTATUS CancelRequests();
     virtual NTSTATUS CreateUSBRequest(IUSBRequest **OutRequest);
     virtual VOID TransferDescriptorCompletionCallback(ULONG 
TransferDescriptorLogicalAddress);
+    virtual NTSTATUS AbortDevicePipe(UCHAR DeviceAddress, IN 
PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor);
 
     // local functions
     BOOLEAN IsTransferDescriptorInEndpoint(IN POHCI_ENDPOINT_DESCRIPTOR 
EndpointDescriptor, IN ULONG TransferDescriptorLogicalAddress);
@@ -741,6 +742,115 @@
 }
 
 NTSTATUS
+CUSBQueue::AbortDevicePipe(
+    IN UCHAR DeviceAddress,
+    IN PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor)
+{
+    POHCI_ENDPOINT_DESCRIPTOR HeadDescriptor, CurrentDescriptor, 
PreviousDescriptor, TempDescriptor;
+    ULONG Type;
+    POHCI_GENERAL_TD TransferDescriptor;
+
+    //
+    // get type
+    //
+    Type = (EndpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK);
+
+    //
+    // check type
+    //
+    if (Type == USB_ENDPOINT_TYPE_BULK)
+    {
+        //
+        // get head descriptor
+        //
+        HeadDescriptor = m_BulkHeadEndpointDescriptor;
+    }
+    else if (Type == USB_ENDPOINT_TYPE_CONTROL)
+    {
+        //
+        // get head descriptor
+        //
+        HeadDescriptor = m_ControlHeadEndpointDescriptor;
+    }
+    else if (Type == USB_ENDPOINT_TYPE_INTERRUPT)
+    {
+        //
+        // get head descriptor
+        //
+        HeadDescriptor = 
FindInterruptEndpointDescriptor(EndpointDescriptor->bInterval);
+        ASSERT(HeadDescriptor);
+    }
+    else if (Type == USB_ENDPOINT_TYPE_ISOCHRONOUS)
+    {
+        UNIMPLEMENTED
+        return STATUS_NOT_IMPLEMENTED;
+    }
+
+    //
+    // FIXME should disable list processing
+    //
+
+    //
+    // now remove all endpoints
+    //
+    ASSERT(HeadDescriptor);
+    CurrentDescriptor = 
(POHCI_ENDPOINT_DESCRIPTOR)HeadDescriptor->NextDescriptor;
+    PreviousDescriptor = (POHCI_ENDPOINT_DESCRIPTOR)HeadDescriptor;
+
+    while(CurrentDescriptor)
+    {
+        if ((CurrentDescriptor->HeadPhysicalDescriptor & 
OHCI_ENDPOINT_HEAD_MASK) == CurrentDescriptor->TailPhysicalDescriptor || 
(CurrentDescriptor->HeadPhysicalDescriptor & OHCI_ENDPOINT_HALTED))
+        {
+            //
+            // cleanup endpoint
+            //
+            TempDescriptor = 
(POHCI_ENDPOINT_DESCRIPTOR)CurrentDescriptor->NextDescriptor;
+            CleanupEndpointDescriptor(CurrentDescriptor, PreviousDescriptor);
+
+            //
+            // use next descriptor
+            //
+            CurrentDescriptor = TempDescriptor;
+        }
+
+        if (!CurrentDescriptor)
+            break;
+
+        if (CurrentDescriptor->HeadPhysicalDescriptor)
+        {
+            TransferDescriptor = 
(POHCI_GENERAL_TD)CurrentDescriptor->HeadLogicalDescriptor;
+            ASSERT(TransferDescriptor);
+
+            if ((OHCI_ENDPOINT_GET_ENDPOINT_NUMBER(TransferDescriptor->Flags) 
== (EndpointDescriptor->bEndpointAddress & 0xF)) &&
+                (OHCI_ENDPOINT_GET_DEVICE_ADDRESS(TransferDescriptor->Flags) 
== DeviceAddress))
+            {
+                //
+                // cleanup endpoint
+                //
+                TempDescriptor = 
(POHCI_ENDPOINT_DESCRIPTOR)CurrentDescriptor->NextDescriptor;
+                CleanupEndpointDescriptor(CurrentDescriptor, 
PreviousDescriptor);
+                //
+                // use next descriptor
+                //
+                CurrentDescriptor = TempDescriptor;
+            }
+       }
+
+       if (!CurrentDescriptor)
+           break;
+
+       PreviousDescriptor = CurrentDescriptor;
+       CurrentDescriptor = 
(POHCI_ENDPOINT_DESCRIPTOR)CurrentDescriptor->NextDescriptor;
+    }
+
+    //
+    // done
+    //
+    return STATUS_SUCCESS;
+}
+
+
+NTSTATUS
 CreateUSBQueue(
     PUSBQUEUE *OutUsbQueue)
 {

Modified: branches/usb-bringup-trunk/drivers/usb/usbohci/usbohci.h
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/usbohci/usbohci.h?rev=55394&r1=55393&r2=55394&view=diff
==============================================================================
--- branches/usb-bringup-trunk/drivers/usb/usbohci/usbohci.h [iso-8859-1] 
(original)
+++ branches/usb-bringup-trunk/drivers/usb/usbohci/usbohci.h [iso-8859-1] Fri 
Feb  3 14:47:18 2012
@@ -7,6 +7,7 @@
 #include <hubbusif.h>
 #include <usbbusif.h>
 #include <usbioctl.h>
+#include <usb100.h>
 
 extern
 "C"


Reply via email to