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/u…
==============================================================================
--- 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/u…
==============================================================================
--- 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/u…
==============================================================================
--- 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/u…
==============================================================================
--- 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/u…
==============================================================================
--- 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/u…
==============================================================================
--- 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"