mirror of
https://github.com/reactos/reactos.git
synced 2024-07-28 23:29:19 +00:00
[USBEHCI]
- Merge hub controller from usbohci - Partly implement AbortPipe request - Implement resetting data toggle in HandleSyncResetAndClearStall svn path=/branches/usb-bringup-trunk/; revision=55490
This commit is contained in:
parent
133cb2712c
commit
d1da088aa8
|
@ -70,6 +70,9 @@ public:
|
|||
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);
|
||||
|
||||
|
@ -1675,12 +1678,21 @@ CHubController::HandleClassEndpoint(
|
|||
//
|
||||
// initialize setup packet
|
||||
//
|
||||
CtrlSetup.bmRequestType.B = 0xa2; //FIXME: Const.
|
||||
CtrlSetup.bmRequestType.B = 0x22; //FIXME: Const.
|
||||
CtrlSetup.bRequest = Urb->UrbControlVendorClassRequest.Request;
|
||||
CtrlSetup.wValue.W = Urb->UrbControlVendorClassRequest.Value;
|
||||
CtrlSetup.wIndex.W = Urb->UrbControlVendorClassRequest.Index;
|
||||
CtrlSetup.wLength = Urb->UrbControlVendorClassRequest.TransferBufferLength;
|
||||
|
||||
if (Urb->UrbControlVendorClassRequest.TransferFlags & USBD_TRANSFER_DIRECTION_IN)
|
||||
{
|
||||
//
|
||||
// data direction is device to host
|
||||
//
|
||||
CtrlSetup.bmRequestType.B |= 0x80;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// issue request
|
||||
//
|
||||
|
@ -1698,6 +1710,185 @@ CHubController::HandleClassEndpoint(
|
|||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
CHubController::HandleSyncResetAndClearStall(
|
||||
IN OUT PIRP Irp,
|
||||
IN OUT PURB Urb)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PUSB_ENDPOINT 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)Urb->UrbPipeRequest.PipeHandle;
|
||||
|
||||
//
|
||||
// get type
|
||||
//
|
||||
Type = (EndpointDescriptor->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);
|
||||
|
||||
//
|
||||
// reset data toggle
|
||||
//
|
||||
ASSERT(NT_SUCCESS(Status));
|
||||
EndpointDescriptor->DataToggle = 0x0;
|
||||
|
||||
//
|
||||
// done
|
||||
//
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
CHubController::HandleAbortPipe(
|
||||
IN OUT PIRP Irp,
|
||||
IN OUT PURB Urb)
|
||||
{
|
||||
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(
|
||||
|
@ -1747,12 +1938,20 @@ CHubController::HandleClassInterface(
|
|||
//
|
||||
// initialize setup packet
|
||||
//
|
||||
CtrlSetup.bmRequestType.B = 0xa1; //FIXME: Const.
|
||||
CtrlSetup.bmRequestType.B = 0x21;
|
||||
CtrlSetup.bRequest = Urb->UrbControlVendorClassRequest.Request;
|
||||
CtrlSetup.wValue.W = Urb->UrbControlVendorClassRequest.Value;
|
||||
CtrlSetup.wIndex.W = Urb->UrbControlVendorClassRequest.Index;
|
||||
CtrlSetup.wLength = Urb->UrbControlVendorClassRequest.TransferBufferLength;
|
||||
|
||||
if (Urb->UrbControlVendorClassRequest.TransferFlags & USBD_TRANSFER_DIRECTION_IN)
|
||||
{
|
||||
//
|
||||
// data direction is device to host
|
||||
//
|
||||
CtrlSetup.bmRequestType.B |= 0x80;
|
||||
}
|
||||
|
||||
//
|
||||
// issue request
|
||||
//
|
||||
|
@ -1761,8 +1960,13 @@ CHubController::HandleClassInterface(
|
|||
//
|
||||
// assert on failure
|
||||
//
|
||||
PC_ASSERT(NT_SUCCESS(Status));
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// display error
|
||||
//
|
||||
DPRINT1("URB_FUNCTION_CLASS_INTERFACE failed with Urb Status %x\n", Urb->UrbHeader.Status);
|
||||
}
|
||||
|
||||
//
|
||||
// done
|
||||
|
@ -1806,6 +2010,16 @@ CHubController::HandleDeviceControl(
|
|||
|
||||
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;
|
||||
|
|
|
@ -589,6 +589,15 @@ DECLARE_INTERFACE_(IUSBQueue, IUnknown)
|
|||
// This function gets called by IUSBHardware after it the Interrupt on Async Advance bit has been set
|
||||
|
||||
virtual VOID CompleteAsyncRequests() = 0;
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
//
|
||||
// AbortDevicePipe
|
||||
//
|
||||
// Description: aborts all pending requsts of an device
|
||||
|
||||
virtual NTSTATUS AbortDevicePipe(UCHAR DeviceAddress, IN PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor) = 0;
|
||||
|
||||
};
|
||||
|
||||
typedef IUSBQueue *PUSBQUEUE;
|
||||
|
@ -842,6 +851,15 @@ DECLARE_INTERFACE_(IUSBDevice, IUnknown)
|
|||
|
||||
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;
|
||||
|
|
|
@ -52,6 +52,8 @@ public:
|
|||
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);
|
||||
|
@ -1255,6 +1257,23 @@ CUSBDevice::SelectInterface(
|
|||
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(
|
||||
|
|
|
@ -41,6 +41,8 @@ public:
|
|||
virtual NTSTATUS CreateUSBRequest(IUSBRequest **OutRequest);
|
||||
virtual VOID InterruptCallback(IN NTSTATUS Status, OUT PULONG ShouldRingDoorBell);
|
||||
virtual VOID CompleteAsyncRequests();
|
||||
virtual NTSTATUS AbortDevicePipe(UCHAR DeviceAddress, IN PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor);
|
||||
|
||||
|
||||
// constructor / destructor
|
||||
CUSBQueue(IUnknown *OuterUnknown){}
|
||||
|
@ -924,6 +926,16 @@ CUSBQueue::CompleteAsyncRequests()
|
|||
KeReleaseSpinLock(m_Lock, OldLevel);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
CUSBQueue::AbortDevicePipe(
|
||||
IN UCHAR DeviceAddress,
|
||||
IN PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
CreateUSBQueue(
|
||||
PUSBQUEUE *OutUsbQueue)
|
||||
|
@ -957,3 +969,4 @@ CreateUSBQueue(
|
|||
//
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue