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/us... ============================================================================== --- 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/us... ============================================================================== --- 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/us... ============================================================================== --- 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/us... ============================================================================== --- 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/us... ============================================================================== --- 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/us... ============================================================================== --- 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"