Author: janderwald
Date: Sat Feb 18 23:23:13 2012
New Revision: 55687
URL:
http://svn.reactos.org/svn/reactos?rev=55687&view=rev
Log:
[USBOHCI]
- Don't preserve command status values when notifying controller of a new bulk /
control endpoint
- Abort pipe & reset data toggle in the sync reset routine
- Allocate interface descriptors and endpoint handles when creating the configuration
descriptor
- Implement routine for allocating chained descriptors
- Implement data toggle for bulk&interrupt transfers
- Mass storage devices should now work in real hardware with OHCI controller
- Tested in real hardware with NEC Corporation USB [1033:0035] (rev 43)
Modified:
trunk/reactos/drivers/usb/usbohci/hardware.cpp
trunk/reactos/drivers/usb/usbohci/hardware.h
trunk/reactos/drivers/usb/usbohci/hub_controller.cpp
trunk/reactos/drivers/usb/usbohci/interfaces.h
trunk/reactos/drivers/usb/usbohci/usb_device.cpp
trunk/reactos/drivers/usb/usbohci/usb_queue.cpp
trunk/reactos/drivers/usb/usbohci/usb_request.cpp
trunk/reactos/drivers/usb/usbohci/usbohci.h
Modified: trunk/reactos/drivers/usb/usbohci/hardware.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbohci/hardwa…
==============================================================================
--- trunk/reactos/drivers/usb/usbohci/hardware.cpp [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbohci/hardware.cpp [iso-8859-1] Sat Feb 18 23:23:13 2012
@@ -732,21 +732,19 @@
CUSBHardwareDevice::HeadEndpointDescriptorModified(
ULONG Type)
{
- ULONG Value = READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base +
OHCI_COMMAND_STATUS_OFFSET));
-
if (Type == USB_ENDPOINT_TYPE_CONTROL)
{
//
// notify controller
//
- WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_COMMAND_STATUS_OFFSET), Value
| OHCI_CONTROL_LIST_FILLED);
+ WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_COMMAND_STATUS_OFFSET),
OHCI_CONTROL_LIST_FILLED);
}
else if (Type == USB_ENDPOINT_TYPE_BULK)
{
//
// notify controller
//
- WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_COMMAND_STATUS_OFFSET), Value
| OHCI_BULK_LIST_FILLED);
+ WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_COMMAND_STATUS_OFFSET),
OHCI_BULK_LIST_FILLED);
}
}
@@ -1579,7 +1577,7 @@
CStatus = (ULONG) SystemArgument1;
DoneHead = (ULONG)SystemArgument2;
- DPRINT("OhciDefferedRoutine Status %x\n", CStatus);
+ DPRINT("OhciDefferedRoutine Status %x DoneHead %x\n", CStatus, DoneHead);
if (CStatus & OHCI_WRITEBACK_DONE_HEAD)
{
Modified: trunk/reactos/drivers/usb/usbohci/hardware.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbohci/hardwa…
==============================================================================
--- trunk/reactos/drivers/usb/usbohci/hardware.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbohci/hardware.h [iso-8859-1] Sat Feb 18 23:23:13 2012
@@ -224,6 +224,7 @@
PVOID HeadLogicalDescriptor;
PVOID NextDescriptor;
PVOID Request;
+ LIST_ENTRY DescriptorListEntry;
}OHCI_ENDPOINT_DESCRIPTOR, *POHCI_ENDPOINT_DESCRIPTOR;
@@ -242,7 +243,9 @@
#define OHCI_ENDPOINT_ISOCHRONOUS_FORMAT 0x00008000
#define OHCI_ENDPOINT_HEAD_MASK 0xfffffffc
#define OHCI_ENDPOINT_HALTED 0x00000001
+#define OHCI_ENDPOINT_TOGGLE_CARRY 0x00000002
#define OHCI_ENDPOINT_DIRECTION_DESCRIPTOR 0x00000000
+
//
// Maximum port count set by OHCI
//
Modified: trunk/reactos/drivers/usb/usbohci/hub_controller.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbohci/hub_co…
==============================================================================
--- trunk/reactos/drivers/usb/usbohci/hub_controller.cpp [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbohci/hub_controller.cpp [iso-8859-1] Sat Feb 18 23:23:13
2012
@@ -1710,7 +1710,7 @@
IN OUT PURB Urb)
{
NTSTATUS Status = STATUS_SUCCESS;
- PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
+ PUSB_ENDPOINT EndpointDescriptor;
ULONG Type;
//
@@ -1736,12 +1736,24 @@
//
// get endpoint descriptor
//
- EndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)Urb->UrbPipeRequest.PipeHandle;
+ EndpointDescriptor = (PUSB_ENDPOINT)Urb->UrbPipeRequest.PipeHandle;
+
+ //
+ // abort pipe
+ //
+ Status = HandleAbortPipe(Irp, Urb);
+ if (!NT_SUCCESS(Status))
+ {
+ //
+ // abort pipe failed
+ //
+ DPRINT1("[USBOHCI] AbortPipe failed with %x\n", Status);
+ }
//
// get type
//
- Type = (EndpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK);
+ Type = (EndpointDescriptor->EndPointDescriptor.bmAttributes &
USB_ENDPOINT_TYPE_MASK);
if (Type != USB_ENDPOINT_TYPE_ISOCHRONOUS)
{
//
@@ -1752,8 +1764,9 @@
DPRINT1("URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL Status %x\n",
Status);
//
- // FIXME reset data toggle
- //
+ // reset data toggle
+ //
+ EndpointDescriptor->DataToggle = 0;
//
// done
Modified: trunk/reactos/drivers/usb/usbohci/interfaces.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbohci/interf…
==============================================================================
--- trunk/reactos/drivers/usb/usbohci/interfaces.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbohci/interfaces.h [iso-8859-1] Sat Feb 18 23:23:13 2012
@@ -371,6 +371,8 @@
};
typedef IDMAMemoryManager *PDMAMEMORYMANAGER;
+
+struct _USB_ENDPOINT;
//=========================================================================================
@@ -401,7 +403,7 @@
virtual NTSTATUS InitializeWithSetupPacket(IN PDMAMEMORYMANAGER DmaManager,
IN PUSB_DEFAULT_PIPE_SETUP_PACKET
SetupPacket,
IN UCHAR DeviceAddress,
- IN OPTIONAL PUSB_ENDPOINT_DESCRIPTOR
EndpointDescriptor,
+ IN OPTIONAL struct _USB_ENDPOINT*
EndpointDescriptor,
IN USB_DEVICE_SPEED DeviceSpeed,
IN OUT ULONG TransferBufferLength,
IN OUT PMDL TransferBuffer) = 0;
@@ -470,7 +472,7 @@
//
// Description: notifies request that the endpoint descriptor is complete
- virtual VOID CompletionCallback(struct _OHCI_ENDPOINT_DESCRIPTOR * OutDescriptor) =
0;
+ virtual VOID CompletionCallback() = 0;
//-----------------------------------------------------------------------------------------
//
Modified: trunk/reactos/drivers/usb/usbohci/usb_device.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbohci/usb_de…
==============================================================================
--- trunk/reactos/drivers/usb/usbohci/usb_device.cpp [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbohci/usb_device.cpp [iso-8859-1] Sat Feb 18 23:23:13
2012
@@ -54,10 +54,11 @@
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);
- virtual NTSTATUS CommitSetupPacket(PUSB_DEFAULT_PIPE_SETUP_PACKET Packet, IN OPTIONAL
PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor, IN ULONG BufferLength, IN OUT PMDL Mdl);
- virtual NTSTATUS CreateConfigurationDescriptor(ULONG ConfigurationIndex);
+ virtual NTSTATUS CommitSetupPacket(PUSB_DEFAULT_PIPE_SETUP_PACKET Packet, IN OPTIONAL
PUSB_ENDPOINT EndpointDescriptor, IN ULONG BufferLength, IN OUT PMDL Mdl);
+ virtual NTSTATUS CreateConfigurationDescriptor(UCHAR ConfigurationIndex);
virtual NTSTATUS CreateDeviceDescriptor();
virtual VOID DumpDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor);
virtual VOID DumpConfigurationDescriptor(PUSB_CONFIGURATION_DESCRIPTOR
ConfigurationDescriptor);
@@ -80,9 +81,8 @@
ULONG m_PortStatus;
PUSBQUEUE m_Queue;
PDMAMEMORYMANAGER m_DmaManager;
- PUSB_CONFIGURATION_DESCRIPTOR *m_ConfigurationDescriptors;
- LIST_ENTRY m_IrpListHead;
-
+
+ PUSB_CONFIGURATION m_ConfigurationDescriptors;
};
//----------------------------------------------------------------------------------------
@@ -121,11 +121,6 @@
KeInitializeSpinLock(&m_Lock);
//
- // initialize irp list
- //
- InitializeListHead(&m_IrpListHead);
-
- //
// no device address has been set yet
//
m_DeviceAddress = 0;
@@ -276,6 +271,7 @@
DPRINT1("CUSBDevice::GetType Unknown bcdUSB Type %x\n",
m_DeviceDescriptor.bcdUSB);
//PC_ASSERT(FALSE);
+
return Usb11Device;
}
@@ -306,7 +302,7 @@
PUSB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
NTSTATUS Status;
UCHAR OldAddress;
- ULONG Index;
+ UCHAR Index;
DPRINT1("CUSBDevice::SetDeviceAddress Address %d\n", DeviceAddress);
@@ -388,12 +384,12 @@
//
// allocate configuration descriptor
//
- m_ConfigurationDescriptors = (PUSB_CONFIGURATION_DESCRIPTOR*)
ExAllocatePoolWithTag(NonPagedPool, sizeof(PUSB_CONFIGURATION_DESCRIPTOR) *
m_DeviceDescriptor.bNumConfigurations, TAG_USBOHCI);
+ m_ConfigurationDescriptors = (PUSB_CONFIGURATION) ExAllocatePoolWithTag(NonPagedPool,
sizeof(USB_CONFIGURATION) * m_DeviceDescriptor.bNumConfigurations, TAG_USBOHCI);
//
// zero configuration descriptor
//
- RtlZeroMemory(m_ConfigurationDescriptors, sizeof(PUSB_CONFIGURATION_DESCRIPTOR) *
m_DeviceDescriptor.bNumConfigurations);
+ RtlZeroMemory(m_ConfigurationDescriptors, sizeof(USB_CONFIGURATION) *
m_DeviceDescriptor.bNumConfigurations);
//
// retrieve the configuration descriptors
@@ -525,7 +521,7 @@
NTSTATUS
CUSBDevice::CommitSetupPacket(
IN PUSB_DEFAULT_PIPE_SETUP_PACKET Packet,
- IN OPTIONAL PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor,
+ IN OPTIONAL PUSB_ENDPOINT EndpointDescriptor,
IN ULONG BufferLength,
IN OUT PMDL Mdl)
{
@@ -663,18 +659,14 @@
if (NT_SUCCESS(Status))
{
//
- // copy back device descriptor
+ // informal dbg print
//
RtlCopyMemory(&m_DeviceDescriptor, DeviceDescriptor,
sizeof(USB_DEVICE_DESCRIPTOR));
-
- //
- // informal dbg print
- //
DumpDeviceDescriptor(&m_DeviceDescriptor);
}
//
- // free item
+ // free buffer
//
ExFreePool(DeviceDescriptor);
@@ -688,13 +680,16 @@
//----------------------------------------------------------------------------------------
NTSTATUS
CUSBDevice::CreateConfigurationDescriptor(
- ULONG Index)
+ UCHAR Index)
{
PVOID Buffer;
USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
NTSTATUS Status;
PMDL Mdl;
+ ULONG InterfaceIndex, EndPointIndex;
PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
+ PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
+ PUSB_ENDPOINT_DESCRIPTOR EndPointDescriptor;
//
@@ -713,11 +708,6 @@
//
return STATUS_INSUFFICIENT_RESOURCES;
}
-
- //
- // zero buffer
- //
- RtlZeroMemory(Buffer, PAGE_SIZE);
//
// build setup packet
@@ -727,16 +717,12 @@
CtrlSetup.bmRequestType._BM.Reserved = 0;
CtrlSetup.bmRequestType._BM.Dir = BMREQUEST_DEVICE_TO_HOST;
CtrlSetup.bRequest = USB_REQUEST_GET_DESCRIPTOR;
- CtrlSetup.wValue.LowByte = 0;
+ CtrlSetup.wValue.LowByte = Index;
CtrlSetup.wValue.HiByte = USB_CONFIGURATION_DESCRIPTOR_TYPE;
CtrlSetup.wIndex.W = 0;
CtrlSetup.wLength = PAGE_SIZE;
//
- // FIXME: where put configuration index?
- //
-
- //
// now build MDL describing the buffer
//
Mdl = IoAllocateMdl(Buffer, PAGE_SIZE, FALSE, FALSE, 0);
@@ -791,9 +777,124 @@
PC_ASSERT(ConfigurationDescriptor->bNumInterfaces);
//
- // store configuration descriptor
- //
- m_ConfigurationDescriptors[Index] = ConfigurationDescriptor;
+ // request is complete, initialize configuration descriptor
+ //
+ m_ConfigurationDescriptors[Index].ConfigurationDescriptor = ConfigurationDescriptor;
+
+ //
+ // now allocate interface descriptors
+ //
+ m_ConfigurationDescriptors[Index].Interfaces =
(PUSB_INTERFACE)ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_INTERFACE) *
ConfigurationDescriptor->bNumInterfaces, TAG_USBOHCI);
+ if (!m_ConfigurationDescriptors[Index].Interfaces)
+ {
+ //
+ // failed to allocate interface descriptors
+ //
+ ExFreePool(Buffer);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ //
+ // zero interface descriptor
+ //
+ RtlZeroMemory(m_ConfigurationDescriptors[Index].Interfaces, sizeof(USB_INTERFACE) *
ConfigurationDescriptor->bNumInterfaces);
+
+ //
+ // get first interface descriptor
+ //
+ InterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR)(ConfigurationDescriptor + 1);
+
+ //
+ // setup interface descriptors
+ //
+ for(InterfaceIndex = 0; InterfaceIndex <
ConfigurationDescriptor->bNumInterfaces; InterfaceIndex++)
+ {
+ while(InterfaceDescriptor->bDescriptorType != USB_INTERFACE_DESCRIPTOR_TYPE
&& InterfaceDescriptor->bLength != sizeof(USB_INTERFACE_DESCRIPTOR))
+ {
+ //
+ // move to next descriptor
+ //
+ ASSERT(InterfaceDescriptor->bLength);
+ InterfaceDescriptor =
(PUSB_INTERFACE_DESCRIPTOR)((ULONG_PTR)InterfaceDescriptor +
InterfaceDescriptor->bLength);
+ }
+
+ //
+ // sanity checks
+ //
+ ASSERT(InterfaceDescriptor->bDescriptorType ==
USB_INTERFACE_DESCRIPTOR_TYPE);
+ ASSERT(InterfaceDescriptor->bLength == sizeof(USB_INTERFACE_DESCRIPTOR));
+ ASSERT(InterfaceDescriptor->bNumEndpoints);
+
+ //
+ // copy current interface descriptor
+ //
+
RtlCopyMemory(&m_ConfigurationDescriptors[Index].Interfaces[InterfaceIndex].InterfaceDescriptor,
InterfaceDescriptor, InterfaceDescriptor->bLength);
+
+ //
+ // allocate end point descriptors
+ //
+ m_ConfigurationDescriptors[Index].Interfaces[InterfaceIndex].EndPoints =
(PUSB_ENDPOINT)ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_ENDPOINT) *
InterfaceDescriptor->bNumEndpoints, TAG_USBOHCI);
+ if (!m_ConfigurationDescriptors[Index].Interfaces[InterfaceIndex].EndPoints)
+ {
+ //
+ // failed to allocate endpoint
+ //
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ break;
+ }
+
+ //
+ // zero memory
+ //
+
RtlZeroMemory(m_ConfigurationDescriptors[Index].Interfaces[InterfaceIndex].EndPoints,
sizeof(USB_ENDPOINT) * InterfaceDescriptor->bNumEndpoints);
+
+ //
+ // initialize end point descriptors
+ //
+ EndPointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)(InterfaceDescriptor + 1);
+
+ for(EndPointIndex = 0; EndPointIndex < InterfaceDescriptor->bNumEndpoints;
EndPointIndex++)
+ {
+ //
+ // skip other descriptors
+ //
+ while(EndPointDescriptor->bDescriptorType != USB_ENDPOINT_DESCRIPTOR_TYPE
&& EndPointDescriptor->bLength != sizeof(USB_ENDPOINT_DESCRIPTOR))
+ {
+ //
+ // assert when next interface descriptor is reached before the next
endpoint
+ //
+ ASSERT(EndPointDescriptor->bDescriptorType !=
USB_INTERFACE_DESCRIPTOR_TYPE);
+ ASSERT(EndPointDescriptor->bLength);
+
+ DPRINT1("InterfaceDescriptor bNumEndpoints %x EndpointIndex %x
Skipping Descriptor Type %x\n", InterfaceDescriptor->bNumEndpoints, EndPointIndex,
EndPointDescriptor->bDescriptorType);
+ //
+ // move to next descriptor
+ //
+ EndPointDescriptor =
(PUSB_ENDPOINT_DESCRIPTOR)((ULONG_PTR)EndPointDescriptor +
EndPointDescriptor->bLength);
+ }
+
+ //
+ // sanity check
+ //
+ ASSERT(EndPointDescriptor->bDescriptorType ==
USB_ENDPOINT_DESCRIPTOR_TYPE);
+ ASSERT(EndPointDescriptor->bLength == sizeof(USB_ENDPOINT_DESCRIPTOR));
+
+ //
+ // copy endpoint descriptor
+ //
+
RtlCopyMemory(&m_ConfigurationDescriptors[Index].Interfaces[InterfaceIndex].EndPoints[EndPointIndex].EndPointDescriptor,
EndPointDescriptor, EndPointDescriptor->bLength);
+
+ //
+ // move to next offset
+ //
+ EndPointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)((ULONG_PTR)EndPointDescriptor
+ EndPointDescriptor->bLength);
+ }
+
+ //
+ // update interface descriptor offset
+ //
+ InterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR)EndPointDescriptor;
+ }
//
// done
@@ -827,8 +928,8 @@
//
// copy configuration descriptor
//
- RtlCopyMemory(ConfigDescriptorBuffer, m_ConfigurationDescriptors[0],
min(m_ConfigurationDescriptors[0]->wTotalLength, BufferLength));
- *OutBufferLength = m_ConfigurationDescriptors[0]->wTotalLength;
+ RtlCopyMemory(ConfigDescriptorBuffer,
m_ConfigurationDescriptors[0].ConfigurationDescriptor,
min(m_ConfigurationDescriptors[0].ConfigurationDescriptor->wTotalLength,
BufferLength));
+ *OutBufferLength =
m_ConfigurationDescriptors[0].ConfigurationDescriptor->wTotalLength;
}
//----------------------------------------------------------------------------------------
@@ -839,11 +940,7 @@
// FIXME: support multiple configurations
//
PC_ASSERT(m_DeviceDescriptor.bNumConfigurations == 1);
-
- ASSERT(m_ConfigurationDescriptors[0]);
- ASSERT(m_ConfigurationDescriptors[0]->wTotalLength);
-
- return m_ConfigurationDescriptors[0]->wTotalLength;
+ return m_ConfigurationDescriptors[0].ConfigurationDescriptor->wTotalLength;
}
//----------------------------------------------------------------------------------------
VOID
@@ -897,7 +994,12 @@
//
Mdl = IoAllocateMdl(Buffer, BufferLength, FALSE, FALSE, 0);
if (!Mdl)
+ {
+ //
+ // no memory
+ //
return STATUS_INSUFFICIENT_RESOURCES;
+ }
//
// HACK HACK HACK: assume the buffer is build from non paged pool
@@ -934,25 +1036,51 @@
ULONG InterfaceIndex, PipeIndex;
USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
NTSTATUS Status;
- PUSB_CONFIGURATION_DESCRIPTOR CurrentConfigurationDescriptor;
- PUSB_INTERFACE_DESCRIPTOR CurrentInterfaceDescriptor;
- PUSB_ENDPOINT_DESCRIPTOR CurrentEndpointDescriptor;
- PVOID StartPosition;
-
- //
- // FIXME: support multiple configurations
- //
- ASSERT(m_DeviceDescriptor.bNumConfigurations == 1);
- ASSERT(m_ConfigurationDescriptors[0]);
- CurrentConfigurationDescriptor = m_ConfigurationDescriptors[0];
+
+ //
+ // sanity checks
+ //
+ ASSERT(ConfigurationDescriptor->iConfiguration <
m_DeviceDescriptor.bNumConfigurations);
+ ASSERT(ConfigurationDescriptor->iConfiguration ==
m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].ConfigurationDescriptor->iConfiguration);
//
// sanity check
//
- PC_ASSERT(ConfigurationDescriptor->iConfiguration ==
CurrentConfigurationDescriptor->iConfiguration);
- PC_ASSERT(ConfigurationDescriptor->bNumInterfaces <=
CurrentConfigurationDescriptor->bNumInterfaces);
- DPRINT1("CUSBDevice::SelectConfiguration NumInterfaces %lu\n",
ConfigurationDescriptor->bNumInterfaces);
-
+ ASSERT(ConfigurationDescriptor->bNumInterfaces <=
m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].ConfigurationDescriptor->bNumInterfaces);
+
+ //
+ // now build setup packet
+ //
+ RtlZeroMemory(&CtrlSetup, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
+ CtrlSetup.bRequest = USB_REQUEST_SET_CONFIGURATION;
+ CtrlSetup.wValue.W = ConfigurationDescriptor->bConfigurationValue;
+
+ //
+ // select configuration
+ //
+ Status = CommitSetupPacket(&CtrlSetup, 0, 0, 0);
+
+ //
+ // informal debug print
+ //
+ DPRINT1("CUsbDevice::SelectConfiguration New Configuration %x Old Configuration
%x Result %x\n", ConfigurationDescriptor->iConfiguration, m_ConfigurationIndex,
Status);
+ if (!NT_SUCCESS(Status))
+ {
+ //
+ // failed
+ //
+ return Status;
+ }
+
+ //
+ // store configuration device index
+ //
+ m_ConfigurationIndex = ConfigurationDescriptor->iConfiguration;
+
+ //
+ // store configuration handle
+ //
+ *ConfigurationHandle =
&m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration];
//
// copy interface info and pipe info
@@ -960,98 +1088,47 @@
for(InterfaceIndex = 0; InterfaceIndex <
ConfigurationDescriptor->bNumInterfaces; InterfaceIndex++)
{
//
- // find interface descriptor
- //
- CurrentInterfaceDescriptor =
USBD_ParseConfigurationDescriptor(CurrentConfigurationDescriptor,
InterfaceInfo->InterfaceNumber, InterfaceInfo->AlternateSetting);
-
- //
- // sanity check
- //
- ASSERT(CurrentInterfaceDescriptor);
- ASSERT(CurrentInterfaceDescriptor->bLength != 0);
- ASSERT(InterfaceInfo->NumberOfPipes ==
CurrentInterfaceDescriptor->bNumEndpoints);
- ASSERT(InterfaceInfo->Length != 0);
+ // sanity check: is the info pre-layed out
+ //
+ PC_ASSERT(InterfaceInfo->NumberOfPipes ==
m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].InterfaceDescriptor.bNumEndpoints);
+ PC_ASSERT(InterfaceInfo->Length != 0);
#ifdef _MSC_VER
PC_ASSERT(InterfaceInfo->Length == FIELD_OFFSET(USBD_INTERFACE_INFORMATION,
Pipes[InterfaceInfo->NumberOfPipes]));
#endif
- DPRINT1("CUSBDevice::SelectConfiguration InterfaceNumber %lu
AlternativeSetting %lu bNumEndpoints %lu\n", InterfaceInfo->InterfaceNumber,
InterfaceInfo->AlternateSetting, CurrentInterfaceDescriptor->bNumEndpoints);
-
//
// copy interface info
//
- InterfaceInfo->InterfaceHandle =
(USBD_INTERFACE_HANDLE)CurrentInterfaceDescriptor;
- InterfaceInfo->Class = CurrentInterfaceDescriptor->bInterfaceClass;
- InterfaceInfo->SubClass = CurrentInterfaceDescriptor->bInterfaceSubClass;
- InterfaceInfo->Protocol = CurrentInterfaceDescriptor->bInterfaceProtocol;
+ InterfaceInfo->InterfaceHandle =
(USBD_INTERFACE_HANDLE)&m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex];
+ InterfaceInfo->Class =
m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].InterfaceDescriptor.bInterfaceClass;
+ InterfaceInfo->SubClass =
m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].InterfaceDescriptor.bInterfaceSubClass;
+ InterfaceInfo->Protocol =
m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].InterfaceDescriptor.bInterfaceProtocol;
InterfaceInfo->Reserved = 0;
//
// copy endpoint info
//
- StartPosition = CurrentInterfaceDescriptor;
for(PipeIndex = 0; PipeIndex < InterfaceInfo->NumberOfPipes; PipeIndex++)
{
//
- // find corresponding endpoint descriptor
- //
- CurrentEndpointDescriptor =
(PUSB_ENDPOINT_DESCRIPTOR)USBD_ParseDescriptors(CurrentConfigurationDescriptor,
CurrentConfigurationDescriptor->wTotalLength, StartPosition,
USB_ENDPOINT_DESCRIPTOR_TYPE);
-
- //
- // sanity checks
- //
- ASSERT(CurrentEndpointDescriptor);
- ASSERT(CurrentEndpointDescriptor->bDescriptorType ==
USB_ENDPOINT_DESCRIPTOR_TYPE);
-
- //
// copy pipe info
//
- InterfaceInfo->Pipes[PipeIndex].MaximumPacketSize =
CurrentEndpointDescriptor->wMaxPacketSize;
- InterfaceInfo->Pipes[PipeIndex].EndpointAddress =
CurrentEndpointDescriptor->bEndpointAddress;
- InterfaceInfo->Pipes[PipeIndex].Interval =
CurrentEndpointDescriptor->bInterval;
- InterfaceInfo->Pipes[PipeIndex].PipeType =
(USBD_PIPE_TYPE)CurrentEndpointDescriptor->bmAttributes;
- InterfaceInfo->Pipes[PipeIndex].PipeHandle =
(PVOID)CurrentEndpointDescriptor;
-
- //
- // move start position beyond the current endpoint descriptor
- //
- StartPosition = (PVOID)(CurrentEndpointDescriptor + 1);
+ InterfaceInfo->Pipes[PipeIndex].MaximumPacketSize =
m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].EndPoints[PipeIndex].EndPointDescriptor.wMaxPacketSize;
+ InterfaceInfo->Pipes[PipeIndex].EndpointAddress =
m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].EndPoints[PipeIndex].EndPointDescriptor.bEndpointAddress;
+ InterfaceInfo->Pipes[PipeIndex].Interval =
m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].EndPoints[PipeIndex].EndPointDescriptor.bInterval;
+ InterfaceInfo->Pipes[PipeIndex].PipeType =
(USBD_PIPE_TYPE)m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].EndPoints[PipeIndex].EndPointDescriptor.bmAttributes;
+ InterfaceInfo->Pipes[PipeIndex].PipeHandle =
(PVOID)&m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].EndPoints[PipeIndex].EndPointDescriptor;
+
+ //
+ // data toggle is reset on configuration requests
+ //
+
m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].EndPoints[PipeIndex].DataToggle
= FALSE;
}
//
// move offset
//
InterfaceInfo =
(PUSBD_INTERFACE_INFORMATION)((ULONG_PTR)PtrToUlong(InterfaceInfo) +
InterfaceInfo->Length);
- }
-
- //
- // now build setup packet
- //
- RtlZeroMemory(&CtrlSetup, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
- CtrlSetup.bRequest = USB_REQUEST_SET_CONFIGURATION;
- CtrlSetup.wValue.W = ConfigurationDescriptor->bConfigurationValue;
-
- //
- // select configuration
- //
- Status = CommitSetupPacket(&CtrlSetup, 0, 0, 0);
-
- //
- // informal debug print
- //
- DPRINT1("CUsbDevice::SelectConfiguration New Configuration %x Old Configuration
%x Result %x\n", ConfigurationDescriptor->iConfiguration, m_ConfigurationIndex,
Status);
-
- if (NT_SUCCESS(Status))
- {
- //
- // store configuration device index
- //
- m_ConfigurationIndex = ConfigurationDescriptor->iConfiguration;
-
- //
- // store configuration handle
- //
- *ConfigurationHandle = m_ConfigurationDescriptors[0];
}
//
@@ -1066,49 +1143,31 @@
IN USBD_CONFIGURATION_HANDLE ConfigurationHandle,
IN OUT PUSBD_INTERFACE_INFORMATION InterfaceInfo)
{
- PUSB_CONFIGURATION_DESCRIPTOR Configuration;
+ PUSB_CONFIGURATION Configuration;
ULONG PipeIndex;
USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
NTSTATUS Status;
- PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
- PUSB_ENDPOINT_DESCRIPTOR CurrentEndpointDescriptor;
- PVOID StartPosition;
-
- //
- // FIXME support multiple configurations
- //
- PC_ASSERT(m_ConfigurationDescriptors[0] ==
(PUSB_CONFIGURATION_DESCRIPTOR)ConfigurationHandle);
//
// get configuration struct
//
- Configuration = (PUSB_CONFIGURATION_DESCRIPTOR)ConfigurationHandle;
-
- //
- // sanity checks
- //
- PC_ASSERT(Configuration->bNumInterfaces > InterfaceInfo->InterfaceNumber);
-#ifdef _MSC_VER
- //PC_ASSERT(InterfaceInfo->Length == FIELD_OFFSET(USBD_INTERFACE_INFORMATION,
Pipes[InterfaceInfo->NumberOfPipes]));
-#endif
-
- //
- // FIXME: check bandwidth
- //
-
- //
- // find interface number
- //
- InterfaceDescriptor = USBD_ParseConfigurationDescriptor(Configuration,
InterfaceInfo->InterfaceNumber, InterfaceInfo->AlternateSetting);
- ASSERT(InterfaceDescriptor);
+ Configuration = (PUSB_CONFIGURATION)ConfigurationHandle;
+
+ //
+ // sanity check
+ //
+ ASSERT(Configuration->ConfigurationDescriptor->bDescriptorType ==
USB_CONFIGURATION_DESCRIPTOR_TYPE);
+ ASSERT(Configuration->ConfigurationDescriptor->bLength ==
sizeof(USB_CONFIGURATION_DESCRIPTOR));
+ ASSERT(Configuration->ConfigurationDescriptor->iConfiguration <
m_DeviceDescriptor.bNumConfigurations);
+
ASSERT(&m_ConfigurationDescriptors[Configuration->ConfigurationDescriptor->iConfiguration]
== Configuration);
//
// initialize setup packet
//
RtlZeroMemory(&CtrlSetup, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
CtrlSetup.bRequest = USB_REQUEST_SET_INTERFACE;
- CtrlSetup.wValue.W = InterfaceDescriptor->bAlternateSetting;
- CtrlSetup.wIndex.W = InterfaceDescriptor->bInterfaceNumber;
+ CtrlSetup.wValue.W =
Configuration->Interfaces[InterfaceInfo->InterfaceNumber].InterfaceDescriptor.bAlternateSetting;
+ CtrlSetup.wIndex.W =
Configuration->Interfaces[InterfaceInfo->InterfaceNumber].InterfaceDescriptor.bInterfaceNumber;
CtrlSetup.bmRequestType.B = 0x01;
//
@@ -1120,55 +1179,58 @@
// informal debug print
//
DPRINT1("CUSBDevice::SelectInterface AlternateSetting %x InterfaceNumber %x
Status %x\n", InterfaceInfo->AlternateSetting, InterfaceInfo->InterfaceNumber,
Status);
- DPRINT1("CUSBDevice::SelectInterface bInterfaceNumber %u bAlternateSetting %u
NumberOfPipes %u Length %lu\n",
- InterfaceDescriptor->bInterfaceNumber,
InterfaceDescriptor->bAlternateSetting, InterfaceInfo->NumberOfPipes,
InterfaceInfo->Length);
- InterfaceInfo->InterfaceHandle = InterfaceDescriptor;
- InterfaceInfo->NumberOfPipes = InterfaceDescriptor->bNumEndpoints;
-
- //
- // are there end points
- //
- if (InterfaceDescriptor->bNumEndpoints)
- {
- //
- // sanity check
- //
- ASSERT(InterfaceInfo->Length == sizeof(USBD_INTERFACE_INFORMATION) +
(InterfaceDescriptor->bNumEndpoints > 1 ? sizeof(USBD_PIPE_INFORMATION) *
(InterfaceDescriptor->bNumEndpoints - 1) : 0));
-
- //
- // store number of pipes
- //
- InterfaceInfo->NumberOfPipes = InterfaceDescriptor->bNumEndpoints;
-
- StartPosition = InterfaceDescriptor;
- for(PipeIndex = 0; PipeIndex < InterfaceInfo->NumberOfPipes; PipeIndex++)
+ if (!NT_SUCCESS(Status))
+ {
+ //
+ // failed to select interface
+ //
+ return Status;
+ }
+
+
+ //
+ // sanity checks
+ //
+ PC_ASSERT(Configuration->ConfigurationDescriptor->bNumInterfaces >
InterfaceInfo->InterfaceNumber);
+
PC_ASSERT(Configuration->Interfaces[InterfaceInfo->InterfaceNumber].InterfaceDescriptor.bNumEndpoints
== InterfaceInfo->NumberOfPipes);
+#ifdef _MSC_VER
+ PC_ASSERT(InterfaceInfo->Length == FIELD_OFFSET(USBD_INTERFACE_INFORMATION,
Pipes[InterfaceInfo->NumberOfPipes]));
+#endif
+
+ //
+ // copy pipe handles
+ //
+ for(PipeIndex = 0; PipeIndex < InterfaceInfo->NumberOfPipes; PipeIndex++)
+ {
+ //
+ // copy pipe handle
+ //
+ DPRINT1("PipeIndex %lu\n", PipeIndex);
+ DPRINT1("EndpointAddress %x\n",
InterfaceInfo->Pipes[PipeIndex].EndpointAddress);
+ DPRINT1("Interval %d\n", InterfaceInfo->Pipes[PipeIndex].Interval);
+ DPRINT1("MaximumPacketSize %d\n",
InterfaceInfo->Pipes[PipeIndex].MaximumPacketSize);
+ DPRINT1("MaximumTransferSize %d\n",
InterfaceInfo->Pipes[PipeIndex].MaximumTransferSize);
+ DPRINT1("PipeFlags %d\n",
InterfaceInfo->Pipes[PipeIndex].PipeFlags);
+ DPRINT1("PipeType %dd\n",
InterfaceInfo->Pipes[PipeIndex].PipeType);
+ DPRINT1("UsbEndPoint %x\n",
Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor.bEndpointAddress);
+
PC_ASSERT(Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor.bEndpointAddress
== InterfaceInfo->Pipes[PipeIndex].EndpointAddress);
+
+ InterfaceInfo->Pipes[PipeIndex].PipeHandle =
&Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor;
+
+ //
+ // data toggle is reset on select interface requests
+ //
+
m_ConfigurationDescriptors[Configuration->ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].DataToggle
= FALSE;
+
+ if
(Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor.bmAttributes
& (USB_ENDPOINT_TYPE_ISOCHRONOUS | USB_ENDPOINT_TYPE_INTERRUPT))
{
//
- // find corresponding endpoint descriptor
- //
- CurrentEndpointDescriptor =
(PUSB_ENDPOINT_DESCRIPTOR)USBD_ParseDescriptors(Configuration,
Configuration->wTotalLength, StartPosition, USB_ENDPOINT_DESCRIPTOR_TYPE);
-
- //
- // sanity checks
- //
- ASSERT(CurrentEndpointDescriptor);
- ASSERT(CurrentEndpointDescriptor->bDescriptorType ==
USB_ENDPOINT_DESCRIPTOR_TYPE);
-
- //
- // copy pipe info
- //
- InterfaceInfo->Pipes[PipeIndex].MaximumPacketSize =
CurrentEndpointDescriptor->wMaxPacketSize;
- InterfaceInfo->Pipes[PipeIndex].EndpointAddress =
CurrentEndpointDescriptor->bEndpointAddress;
- InterfaceInfo->Pipes[PipeIndex].Interval =
CurrentEndpointDescriptor->bInterval;
- InterfaceInfo->Pipes[PipeIndex].PipeType =
(USBD_PIPE_TYPE)CurrentEndpointDescriptor->bmAttributes;
- InterfaceInfo->Pipes[PipeIndex].PipeHandle =
(PVOID)CurrentEndpointDescriptor;
-
- //
- // move start position beyond the current endpoint descriptor
- //
- StartPosition = (PVOID)(CurrentEndpointDescriptor + 1);
+ // FIXME: check if enough bandwidth is available
+ //
}
}
+
+
//
// done
//
@@ -1191,6 +1253,7 @@
return m_Queue->AbortDevicePipe(m_DeviceAddress, EndpointDescriptor);
}
+
//----------------------------------------------------------------------------------------
NTSTATUS
CreateUSBDevice(
Modified: trunk/reactos/drivers/usb/usbohci/usb_queue.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbohci/usb_qu…
==============================================================================
--- trunk/reactos/drivers/usb/usbohci/usb_queue.cpp [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbohci/usb_queue.cpp [iso-8859-1] Sat Feb 18 23:23:13 2012
@@ -53,6 +53,8 @@
POHCI_ENDPOINT_DESCRIPTOR FindInterruptEndpointDescriptor(UCHAR InterruptInterval);
VOID PrintEndpointList(POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor);
VOID LinkEndpoint(POHCI_ENDPOINT_DESCRIPTOR HeadEndpointDescriptor,
POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor);
+ VOID AddEndpointDescriptor(IN POHCI_ENDPOINT_DESCRIPTOR Descriptor);
+
// constructor / destructor
CUSBQueue(IUnknown *OuterUnknown){}
@@ -66,6 +68,7 @@
POHCI_ENDPOINT_DESCRIPTOR m_ControlHeadEndpointDescriptor;
// control head descriptor
POHCI_ENDPOINT_DESCRIPTOR m_IsoHeadEndpointDescriptor;
// isochronous head descriptor
POHCI_ENDPOINT_DESCRIPTOR * m_InterruptEndpoints;
+ LIST_ENTRY m_PendingRequestList;
// pending request list
};
//=================================================================================================
@@ -120,6 +123,12 @@
KeInitializeSpinLock(&m_Lock);
//
+ // init list
+ //
+ InitializeListHead(&m_PendingRequestList);
+
+
+ //
// store hardware
//
m_Hardware = Hardware;
@@ -164,17 +173,142 @@
}
+VOID
+CUSBQueue::AddEndpointDescriptor(
+ IN POHCI_ENDPOINT_DESCRIPTOR Descriptor)
+{
+ IUSBRequest *Request;
+ ULONG Type;
+ POHCI_ENDPOINT_DESCRIPTOR HeadDescriptor;
+ POHCI_ISO_TD CurrentDescriptor;
+ ULONG FrameNumber;
+ USHORT Frame;
+
+
+ //
+ // sanity check
+ //
+ ASSERT(Descriptor->Request);
+ Request = (IUSBRequest*)Descriptor->Request;
+
+ //
+ // get request type
+ //
+ Type = Request->GetTransferType();
+
+ //
+ // 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(Request->GetInterval());
+ ASSERT(HeadDescriptor);
+ }
+ else if (Type == USB_ENDPOINT_TYPE_ISOCHRONOUS)
+ {
+ //
+ // get head descriptor
+ //
+ HeadDescriptor = m_IsoHeadEndpointDescriptor;
+
+ //
+ // get current frame number
+ //
+ m_Hardware->GetCurrentFrameNumber(&FrameNumber);
+
+ //
+ // FIXME: increment frame number
+ //
+ FrameNumber += 300;
+
+ //
+ // apply frame number to iso transfer descriptors
+ //
+ CurrentDescriptor = (POHCI_ISO_TD)Descriptor->HeadLogicalDescriptor;
+
+ DPRINT("ISO: NextFrameNumber %x\n", FrameNumber);
+ Frame = (FrameNumber & 0xFFFF);
+
+ while(CurrentDescriptor)
+ {
+ //
+ // set current frame number
+ //
+ CurrentDescriptor->Flags |= OHCI_ITD_SET_STARTING_FRAME(Frame);
+
+ //
+ // move to next frame number
+ //
+ Frame += OHCI_ITD_GET_FRAME_COUNT(CurrentDescriptor->Flags);
+
+ //
+ // move to next descriptor
+ //
+ CurrentDescriptor = CurrentDescriptor->NextLogicalDescriptor;
+ }
+
+ //
+ // get current frame number
+ //
+ m_Hardware->GetCurrentFrameNumber(&FrameNumber);
+
+ DPRINT("Hardware 1ms %p Iso %p\n",m_InterruptEndpoints[0],
m_IsoHeadEndpointDescriptor);
+ ASSERT(m_InterruptEndpoints[0]->NextPhysicalEndpoint ==
m_IsoHeadEndpointDescriptor->PhysicalAddress.LowPart);
+
+ PrintEndpointList(m_IsoHeadEndpointDescriptor);
+ }
+ else
+ {
+ //
+ // bad request type
+ //
+ ASSERT(FALSE);
+ return;
+ }
+
+ //
+ // set descriptor active
+ //
+ Descriptor->Flags &= ~OHCI_ENDPOINT_SKIP;
+
+ //
+ // insert endpoint at end
+ //
+ LinkEndpoint(HeadDescriptor, Descriptor);
+
+ if (Type == USB_ENDPOINT_TYPE_CONTROL || Type == USB_ENDPOINT_TYPE_BULK)
+ {
+ //
+ // notify hardware of our request
+ //
+ m_Hardware->HeadEndpointDescriptorModified(Type);
+ }
+}
+
+
NTSTATUS
CUSBQueue::AddUSBRequest(
IUSBRequest * Request)
{
NTSTATUS Status;
- ULONG Type;
- POHCI_ENDPOINT_DESCRIPTOR HeadDescriptor;
- POHCI_ENDPOINT_DESCRIPTOR Descriptor;
- POHCI_ISO_TD CurrentDescriptor;
- ULONG FrameNumber;
- USHORT Frame;
+ IN POHCI_ENDPOINT_DESCRIPTOR Descriptor;
DPRINT("CUSBQueue::AddUSBRequest\n");
@@ -182,11 +316,6 @@
// sanity check
//
ASSERT(Request != NULL);
-
- //
- // get request type
- //
- Type = Request->GetTransferType();
//
// add extra reference which is released when the request is completed
@@ -212,110 +341,9 @@
}
//
- // 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(Request->GetInterval());
- ASSERT(HeadDescriptor);
- }
- else if (Type == USB_ENDPOINT_TYPE_ISOCHRONOUS)
- {
- //
- // get head descriptor
- //
- HeadDescriptor = m_IsoHeadEndpointDescriptor;
-
- //
- // get current frame number
- //
- m_Hardware->GetCurrentFrameNumber(&FrameNumber);
-
- //
- // FIXME: increment frame number
- //
- FrameNumber += 300;
-
- //
- // apply frame number to iso transfer descriptors
- //
- CurrentDescriptor = (POHCI_ISO_TD)Descriptor->HeadLogicalDescriptor;
-
- DPRINT("ISO: NextFrameNumber %x\n", FrameNumber);
- Frame = (FrameNumber & 0xFFFF);
-
- while(CurrentDescriptor)
- {
- //
- // set current frame number
- //
- CurrentDescriptor->Flags |= OHCI_ITD_SET_STARTING_FRAME(Frame);
-
- //
- // move to next frame number
- //
- Frame += OHCI_ITD_GET_FRAME_COUNT(CurrentDescriptor->Flags);
-
- //
- // move to next descriptor
- //
- CurrentDescriptor = CurrentDescriptor->NextLogicalDescriptor;
- }
-
- //
- // get current frame number
- //
- m_Hardware->GetCurrentFrameNumber(&FrameNumber);
-
- DPRINT("Hardware 1ms %p Iso %p\n",m_InterruptEndpoints[0],
m_IsoHeadEndpointDescriptor);
- ASSERT(m_InterruptEndpoints[0]->NextPhysicalEndpoint ==
m_IsoHeadEndpointDescriptor->PhysicalAddress.LowPart);
-
- PrintEndpointList(m_IsoHeadEndpointDescriptor);
- }
- else
- {
- //
- // bad request type
- //
- Request->Release();
- return STATUS_INVALID_PARAMETER;
- }
-
- //
- // set descriptor active
- //
- Descriptor->Flags &= ~OHCI_ENDPOINT_SKIP;
-
- //
- // insert endpoint at end
- //
- LinkEndpoint(HeadDescriptor, Descriptor);
-
- if (Type == USB_ENDPOINT_TYPE_CONTROL || Type == USB_ENDPOINT_TYPE_BULK)
- {
- //
- // notify hardware of our request
- //
- m_Hardware->HeadEndpointDescriptorModified(Type);
- }
-
+ // add the request
+ //
+ AddEndpointDescriptor(Descriptor);
return STATUS_SUCCESS;
}
@@ -562,6 +590,9 @@
POHCI_ENDPOINT_DESCRIPTOR PreviousEndpointDescriptor)
{
PUSBREQUEST Request;
+ POHCI_ENDPOINT_DESCRIPTOR NewEndpointDescriptor;
+ USBD_STATUS UrbStatus;
+ KIRQL OldLevel;
//
// FIXME: verify unlinking process
@@ -576,21 +607,90 @@
ASSERT(Request);
//
+ // check for errors
+ //
+ if (EndpointDescriptor->HeadPhysicalDescriptor & OHCI_ENDPOINT_HALTED)
+ {
+ //
+ // the real error will processed by IUSBRequest
+ //
+ UrbStatus = USBD_STATUS_STALL_PID;
+ }
+ else
+ {
+ //
+ // well done ;)
+ //
+ UrbStatus = USBD_STATUS_SUCCESS;
+ }
+
+ //
+ // Check if the transfer was completed and if UrbStatus is ok
+ //
+ if ((Request->IsRequestComplete() == FALSE) && (UrbStatus ==
USBD_STATUS_SUCCESS))
+ {
+ //
+ // request is incomplete, get new queue head
+ //
+ if (Request->GetEndpointDescriptor(&NewEndpointDescriptor) ==
STATUS_SUCCESS)
+ {
+ //
+ // notify of completion
+ //
+ Request->FreeEndpointDescriptor(EndpointDescriptor);
+
+ //
+ // first acquire request lock
+ //
+ KeAcquireSpinLock(&m_Lock, &OldLevel);
+
+ //
+ // add to pending list
+ //
+ InsertTailList(&m_PendingRequestList,
&NewEndpointDescriptor->DescriptorListEntry);
+
+ //
+ // release queue head
+ //
+ KeReleaseSpinLock(&m_Lock, OldLevel);
+
+ //
+ // Done for now
+ //
+ return;
+ }
+ DPRINT1("Unable to create a new QueueHead\n");
+ //ASSERT(FALSE);
+
+ //
+ // Else there was a problem
+ // FIXME: Find better return
+ UrbStatus = USBD_STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ if (UrbStatus != USBD_STATUS_SUCCESS)
+ {
+ DPRINT1("URB failed with status 0x%x\n", UrbStatus);
+ //PC_ASSERT(FALSE);
+ }
+
+ //
+ // free endpoint descriptor
+ //
+ Request->FreeEndpointDescriptor(EndpointDescriptor);
+
+ //
// notify of completion
//
- Request->CompletionCallback(EndpointDescriptor);
-
- //
- // free endpoint descriptor
- //
- Request->FreeEndpointDescriptor(EndpointDescriptor);
+ Request->CompletionCallback();
+
//
// release request
//
Request->Release();
-
-}
+}
+
VOID
CUSBQueue::PrintEndpointList(
POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor)
@@ -618,6 +718,7 @@
ULONG TransferDescriptorLogicalAddress)
{
POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor, PreviousEndpointDescriptor;
+ PLIST_ENTRY Entry;
NTSTATUS Status;
DPRINT("CUSBQueue::TransferDescriptorCompletionCallback transfer descriptor
%x\n", TransferDescriptorLogicalAddress);
@@ -697,15 +798,41 @@
//
// no more completed descriptors found
//
- return;
+ break;
}while(TRUE);
- //
- // hardware reported dead endpoint completed
- //
- DPRINT1("CUSBQueue::TransferDescriptorCompletionCallback invalid transfer
descriptor %x\n", TransferDescriptorLogicalAddress);
- ASSERT(FALSE);
+
+ //
+ // acquire spin lock
+ //
+ KeAcquireSpinLockAtDpcLevel(&m_Lock);
+
+ //
+ // is there a pending list item
+ //
+ if (!IsListEmpty(&m_PendingRequestList))
+ {
+ //
+ // get list entry
+ //
+ Entry = RemoveHeadList(&m_PendingRequestList);
+
+ //
+ // get entry
+ //
+ EndpointDescriptor = (POHCI_ENDPOINT_DESCRIPTOR)CONTAINING_RECORD(Entry,
OHCI_ENDPOINT_DESCRIPTOR, DescriptorListEntry);
+
+ //
+ // add entry
+ //
+ AddEndpointDescriptor(EndpointDescriptor);
+ }
+
+ //
+ // release lock
+ //
+ KeReleaseSpinLockFromDpcLevel(&m_Lock);
}
POHCI_ENDPOINT_DESCRIPTOR
@@ -789,8 +916,12 @@
HeadDescriptor =
FindInterruptEndpointDescriptor(EndpointDescriptor->bInterval);
ASSERT(HeadDescriptor);
}
- else if (Type == USB_ENDPOINT_TYPE_ISOCHRONOUS)
- {
+ else
+ {
+ //
+ // IMPLEMENT me
+ //
+ ASSERT(Type == USB_ENDPOINT_TYPE_ISOCHRONOUS);
UNIMPLEMENTED
return STATUS_NOT_IMPLEMENTED;
}
Modified: trunk/reactos/drivers/usb/usbohci/usb_request.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbohci/usb_re…
==============================================================================
--- trunk/reactos/drivers/usb/usbohci/usb_request.cpp [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbohci/usb_request.cpp [iso-8859-1] Sat Feb 18 23:23:13
2012
@@ -36,7 +36,7 @@
}
// IUSBRequest interface functions
- virtual NTSTATUS InitializeWithSetupPacket(IN PDMAMEMORYMANAGER DmaManager, IN
PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, IN UCHAR DeviceAddress, IN OPTIONAL
PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor, IN USB_DEVICE_SPEED DeviceSpeed, IN OUT ULONG
TransferBufferLength, IN OUT PMDL TransferBuffer);
+ virtual NTSTATUS InitializeWithSetupPacket(IN PDMAMEMORYMANAGER DmaManager, IN
PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, IN UCHAR DeviceAddress, IN OPTIONAL struct
_USB_ENDPOINT* EndpointDescriptor, IN USB_DEVICE_SPEED DeviceSpeed, IN OUT ULONG
TransferBufferLength, IN OUT PMDL TransferBuffer);
virtual NTSTATUS InitializeWithIrp(IN PDMAMEMORYMANAGER DmaManager, IN OUT PIRP Irp,
IN USB_DEVICE_SPEED DeviceSpeed);
virtual BOOLEAN IsRequestComplete();
virtual ULONG GetTransferType();
@@ -44,7 +44,7 @@
virtual VOID GetResultStatus(OUT OPTIONAL NTSTATUS *NtStatusCode, OUT OPTIONAL PULONG
UrbStatusCode);
virtual BOOLEAN IsRequestInitialized();
virtual BOOLEAN IsQueueHeadComplete(struct _QUEUE_HEAD * QueueHead);
- virtual VOID CompletionCallback(struct _OHCI_ENDPOINT_DESCRIPTOR * OutDescriptor);
+ virtual VOID CompletionCallback();
virtual VOID FreeEndpointDescriptor(struct _OHCI_ENDPOINT_DESCRIPTOR *
OutDescriptor);
virtual UCHAR GetInterval();
@@ -65,6 +65,8 @@
USHORT GetMaxPacketSize();
VOID CheckError(struct _OHCI_ENDPOINT_DESCRIPTOR * OutDescriptor);
VOID DumpEndpointDescriptor(struct _OHCI_ENDPOINT_DESCRIPTOR *Descriptor);
+ NTSTATUS BuildTransferDescriptorChain(IN PVOID TransferBuffer, IN ULONG
TransferBufferLength, IN UCHAR PidCode, OUT POHCI_GENERAL_TD * OutFirstDescriptor, OUT
POHCI_GENERAL_TD * OutLastDescriptor, OUT PULONG OutTransferBufferOffset);
+ VOID InitDescriptor(IN POHCI_GENERAL_TD CurrentDescriptor, IN PVOID TransferBuffer,
IN ULONG TransferBufferLength, IN UCHAR PidCode);
// constructor / destructor
@@ -120,9 +122,9 @@
UCHAR m_DeviceAddress;
//
- // store end point address
- //
- PUSB_ENDPOINT_DESCRIPTOR m_EndpointDescriptor;
+ // store endpoint descriptor
+ //
+ PUSB_ENDPOINT m_EndpointDescriptor;
//
// allocated setup packet from the DMA pool
@@ -145,6 +147,11 @@
// store urb
//
PURB m_Urb;
+
+ //
+ // base buffer
+ //
+ PVOID m_Base;
};
//----------------------------------------------------------------------------------------
@@ -163,7 +170,7 @@
IN PDMAMEMORYMANAGER DmaManager,
IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket,
IN UCHAR DeviceAddress,
- IN OPTIONAL PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor,
+ IN OPTIONAL struct _USB_ENDPOINT* EndpointDescriptor,
IN USB_DEVICE_SPEED DeviceSpeed,
IN OUT ULONG TransferBufferLength,
IN OUT PMDL TransferBuffer)
@@ -331,7 +338,7 @@
//
// get endpoint descriptor
//
- m_EndpointDescriptor =
(PUSB_ENDPOINT_DESCRIPTOR)m_Urb->UrbIsochronousTransfer.PipeHandle;
+ m_EndpointDescriptor =
(PUSB_ENDPOINT)m_Urb->UrbIsochronousTransfer.PipeHandle;
//
// completed initialization
@@ -406,7 +413,7 @@
//
// get endpoint descriptor
//
- m_EndpointDescriptor =
(PUSB_ENDPOINT_DESCRIPTOR)m_Urb->UrbBulkOrInterruptTransfer.PipeHandle;
+ m_EndpointDescriptor =
(PUSB_ENDPOINT)m_Urb->UrbBulkOrInterruptTransfer.PipeHandle;
}
break;
@@ -459,11 +466,21 @@
{
if (!m_EndpointDescriptor)
{
- //
- // FIXME: use DeviceDescriptor.bMaxPacketSize0
- // control pipe request
- //
- return 8;
+ if (m_DeviceSpeed == UsbLowSpeed)
+ {
+ //
+ // control pipes use 8 bytes packets
+ //
+ return 8;
+ }
+ else
+ {
+ //
+ // must be full speed
+ //
+ ASSERT(m_DeviceSpeed == UsbFullSpeed);
+ return 64;
+ }
}
ASSERT(m_Irp);
@@ -472,19 +489,19 @@
//
// return max packet size
//
- return m_EndpointDescriptor->wMaxPacketSize;
+ return m_EndpointDescriptor->EndPointDescriptor.wMaxPacketSize;
}
UCHAR
CUSBRequest::GetInterval()
{
ASSERT(m_EndpointDescriptor);
- ASSERT((m_EndpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK) ==
USB_ENDPOINT_TYPE_INTERRUPT);
+ ASSERT((m_EndpointDescriptor->EndPointDescriptor.bmAttributes &
USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_INTERRUPT);
//
// return interrupt interval
//
- return m_EndpointDescriptor->bInterval;
+ return m_EndpointDescriptor->EndPointDescriptor.bInterval;
}
UCHAR
@@ -504,7 +521,7 @@
//
// endpoint number is between 1-15
//
- return (m_EndpointDescriptor->bEndpointAddress & 0xF);
+ return (m_EndpointDescriptor->EndPointDescriptor.bEndpointAddress & 0xF);
}
//----------------------------------------------------------------------------------------
@@ -523,7 +540,7 @@
//
// end point is defined in the low byte of bmAttributes
//
- TransferType = (m_EndpointDescriptor->bmAttributes &
USB_ENDPOINT_TYPE_MASK);
+ TransferType = (m_EndpointDescriptor->EndPointDescriptor.bmAttributes &
USB_ENDPOINT_TYPE_MASK);
}
else
{
@@ -547,7 +564,7 @@
//
// end point direction is highest bit in bEndpointAddress
//
- return (m_EndpointDescriptor->bEndpointAddress &
USB_ENDPOINT_DIRECTION_MASK) >> 7;
+ return (m_EndpointDescriptor->EndPointDescriptor.bEndpointAddress &
USB_ENDPOINT_DIRECTION_MASK) >> 7;
}
else
{
@@ -967,7 +984,7 @@
Descriptor->Flags |= OHCI_ENDPOINT_SET_ENDPOINT_NUMBER(GetEndpointAddress());
Descriptor->Flags |= OHCI_ENDPOINT_SET_MAX_PACKET_SIZE(GetMaxPacketSize());
- DPRINT("Flags %x DeviceAddress %x EndpointAddress %x PacketSize %x\n",
Descriptor->Flags, GetDeviceAddress(), GetEndpointAddress(), GetMaxPacketSize());
+ DPRINT("Flags %x DeviceAddress %x EndpointAddress %x PacketSize %lu\n",
Descriptor->Flags, GetDeviceAddress(), GetEndpointAddress(), GetMaxPacketSize());
//
// is there an endpoint descriptor
@@ -977,7 +994,7 @@
//
// check direction
//
- if (USB_ENDPOINT_DIRECTION_OUT(m_EndpointDescriptor->bEndpointAddress))
+ if
(USB_ENDPOINT_DIRECTION_OUT(m_EndpointDescriptor->EndPointDescriptor.bEndpointAddress))
{
//
// direction out
@@ -1041,15 +1058,191 @@
return STATUS_SUCCESS;
}
+VOID
+CUSBRequest::InitDescriptor(
+ IN POHCI_GENERAL_TD CurrentDescriptor,
+ IN PVOID TransferBuffer,
+ IN ULONG TransferBufferLength,
+ IN UCHAR PidDirection)
+{
+ ULONG Direction;
+
+ if (PidDirection)
+ {
+ //
+ // input direction
+ //
+ Direction = OHCI_TD_DIRECTION_PID_IN;
+ }
+ else
+ {
+ //
+ // output direction
+ //
+ Direction = OHCI_TD_DIRECTION_PID_OUT;
+ }
+
+
+ //
+ // initialize descriptor
+ //
+ CurrentDescriptor->Flags = Direction | OHCI_TD_BUFFER_ROUNDING |
OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED) |
OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_NONE) | OHCI_TD_TOGGLE_CARRY;
+
+ //
+ // store physical address of buffer
+ //
+ CurrentDescriptor->BufferPhysical = MmGetPhysicalAddress(TransferBuffer).LowPart;
+ CurrentDescriptor->LastPhysicalByteAddress = CurrentDescriptor->BufferPhysical
+ TransferBufferLength - 1;
+
+ DPRINT("CurrentDescriptor %p Addr %x TransferBufferLength %lu\n",
CurrentDescriptor, CurrentDescriptor->PhysicalAddress.LowPart, TransferBufferLength);
+}
+
+NTSTATUS
+CUSBRequest::BuildTransferDescriptorChain(
+ IN PVOID TransferBuffer,
+ IN ULONG TransferBufferLength,
+ IN UCHAR PidDirection,
+ OUT POHCI_GENERAL_TD * OutFirstDescriptor,
+ OUT POHCI_GENERAL_TD * OutLastDescriptor,
+ OUT PULONG OutTransferBufferOffset)
+{
+ POHCI_GENERAL_TD FirstDescriptor = NULL, CurrentDescriptor, LastDescriptor = NULL;
+ NTSTATUS Status;
+ ULONG MaxLengthInPage, TransferBufferOffset = 0;
+ ULONG MaxPacketSize = 0, TransferSize, CurrentSize;
+
+ //
+ // for now use one page as maximum size
+ //
+ MaxPacketSize = PAGE_SIZE;
+
+ do
+ {
+ //
+ // allocate transfer descriptor
+ //
+ Status = CreateGeneralTransferDescriptor(&CurrentDescriptor, 0);
+ if (!NT_SUCCESS(Status))
+ {
+ //
+ // failed to allocate transfer descriptor
+ //
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ if (MaxPacketSize)
+ {
+ //
+ // transfer size is minimum available buffer or endpoint size
+ //
+ TransferSize = min(TransferBufferLength - TransferBufferOffset,
MaxPacketSize);
+ }
+ else
+ {
+ //
+ // use available buffer
+ //
+ TransferSize = TransferBufferLength - TransferBufferOffset;
+ }
+
+ //
+ // get page offset
+ //
+ MaxLengthInPage = PAGE_SIZE - BYTE_OFFSET(TransferBuffer);
+
+ //
+ // get minimum from current page size
+ //
+ CurrentSize = min(TransferSize, MaxLengthInPage);
+ ASSERT(CurrentSize);
+
+ //
+ // now init the descriptor
+ //
+ InitDescriptor(CurrentDescriptor,
+ (PVOID)((ULONG_PTR)TransferBuffer + TransferBufferOffset),
+ CurrentSize,
+ PidDirection);
+
+ //
+ // adjust offset
+ //
+ TransferBufferOffset += CurrentSize;
+
+ //
+ // is there a previous descriptor
+ //
+ if (LastDescriptor)
+ {
+ //
+ // link descriptors
+ //
+ LastDescriptor->NextLogicalDescriptor = (PVOID)CurrentDescriptor;
+ LastDescriptor->NextPhysicalDescriptor =
CurrentDescriptor->PhysicalAddress.LowPart;
+ }
+ else
+ {
+ //
+ // it is the first descriptor
+ //
+ FirstDescriptor = CurrentDescriptor;
+ }
+
+ if(TransferBufferLength == TransferBufferOffset)
+ {
+ //
+ // end reached
+ //
+ break;
+ }
+
+ }while(TRUE);
+
+ if (OutFirstDescriptor)
+ {
+ //
+ // store first descriptor
+ //
+ *OutFirstDescriptor = FirstDescriptor;
+ }
+
+ if (OutLastDescriptor)
+ {
+ //
+ // store last descriptor
+ //
+ *OutLastDescriptor = CurrentDescriptor;
+ }
+
+ if (OutTransferBufferOffset)
+ {
+ //
+ // store offset
+ //
+ *OutTransferBufferOffset = TransferBufferOffset;
+ }
+
+ //
+ // done
+ //
+ return STATUS_SUCCESS;
+}
+
+
NTSTATUS
CUSBRequest::BuildBulkInterruptEndpoint(
POHCI_ENDPOINT_DESCRIPTOR * OutEndpointDescriptor)
{
- POHCI_GENERAL_TD FirstDescriptor, PreviousDescriptor = NULL, CurrentDescriptor,
LastDescriptor;
+ POHCI_GENERAL_TD FirstDescriptor, LastDescriptor;
POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor;
- ULONG BufferSize, CurrentSize, Direction, MaxLengthInPage;
NTSTATUS Status;
- PVOID Buffer;
+ PVOID Base;
+ ULONG ChainDescriptorLength;
+
+ //
+ // sanity check
+ //
+ ASSERT(m_EndpointDescriptor);
//
// allocate endpoint descriptor
@@ -1063,142 +1256,47 @@
return Status;
}
- //
- // allocate transfer descriptor for last descriptor
- //
- Status = CreateGeneralTransferDescriptor(&LastDescriptor, 0);
- if (!NT_SUCCESS(Status))
- {
- //
- // failed to create transfer descriptor
- //
- m_DmaManager->Release(EndpointDescriptor, sizeof(OHCI_ENDPOINT_DESCRIPTOR));
- return Status;
- }
-
- //
- // get buffer size
- //
- BufferSize = m_TransferBufferLength;
- ASSERT(BufferSize);
ASSERT(m_TransferBufferMDL);
- //
- // get buffer
- //
- Buffer = MmGetSystemAddressForMdlSafe(m_TransferBufferMDL, NormalPagePriority);
- ASSERT(Buffer);
-
- if (InternalGetPidDirection())
- {
- //
- // input direction
- //
- Direction = OHCI_TD_DIRECTION_PID_IN;
- }
- else
- {
- //
- // output direction
- //
- Direction = OHCI_TD_DIRECTION_PID_OUT;
- }
-
- do
- {
- //
- // get current buffersize
- //
- CurrentSize = min(8192, BufferSize);
-
- //
- // get page offset
- //
- MaxLengthInPage = PAGE_SIZE - BYTE_OFFSET(Buffer);
-
- //
- // get minimum from current page size
- //
- CurrentSize = min(CurrentSize, MaxLengthInPage);
- ASSERT(CurrentSize);
-
- //
- // allocate transfer descriptor
- //
- Status = CreateGeneralTransferDescriptor(&CurrentDescriptor, 0);
- if (!NT_SUCCESS(Status))
- {
- //
- // failed to create transfer descriptor
- // TODO: cleanup
- //
- ASSERT(FALSE);
- m_DmaManager->Release(EndpointDescriptor,
sizeof(OHCI_ENDPOINT_DESCRIPTOR));
- FreeDescriptor(LastDescriptor);
- return Status;
- }
-
- //
- // initialize descriptor
- //
- CurrentDescriptor->Flags = Direction | OHCI_TD_BUFFER_ROUNDING |
OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED) |
OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_NONE) | OHCI_TD_TOGGLE_CARRY;
-
- //
- // store physical address of buffer
- //
- CurrentDescriptor->BufferPhysical = MmGetPhysicalAddress(Buffer).LowPart;
- CurrentDescriptor->LastPhysicalByteAddress =
CurrentDescriptor->BufferPhysical + CurrentSize - 1;
-
-#if 0
- if (m_Urb != NULL)
- {
- if (m_Urb->UrbBulkOrInterruptTransfer.TransferFlags &
USBD_SHORT_TRANSFER_OK)
- {
- //
- // indicate short packet support
- //
- CurrentDescriptor->Flags |= OHCI_TD_BUFFER_ROUNDING;
- }
- }
-#endif
-
- //
- // is there a previous descriptor
- //
- if (PreviousDescriptor)
- {
- //
- // link descriptors
- //
- PreviousDescriptor->NextLogicalDescriptor = (PVOID)CurrentDescriptor;
- PreviousDescriptor->NextPhysicalDescriptor =
CurrentDescriptor->PhysicalAddress.LowPart;
- }
- else
- {
- //
- // it is the first descriptor
- //
- FirstDescriptor = CurrentDescriptor;
- }
-
- 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
- //
- PreviousDescriptor = CurrentDescriptor;
-
- //
- // subtract buffer size
- //
- BufferSize -= CurrentSize;
-
- //
- // increment buffer offset
- //
- Buffer = (PVOID)((ULONG_PTR)Buffer + CurrentSize);
-
- }while(BufferSize);
+ if (m_Base == NULL)
+ {
+ //
+ // get buffer
+ //
+ m_Base = MmGetSystemAddressForMdlSafe(m_TransferBufferMDL, NormalPagePriority);
+ }
+
+ //
+ // Increase the size of last transfer, 0 in case this is the first
+ //
+ Base = (PVOID)((ULONG_PTR)m_Base + m_TransferBufferLengthCompleted);
+
+ //
+ // sanity checks
+ //
+ ASSERT(m_EndpointDescriptor);
+ ASSERT(Base);
+
+ //
+ // use 2 * PAGE_SIZE at max for each new request
+ //
+ ULONG MaxTransferLength = min(1 * PAGE_SIZE, m_TransferBufferLength -
m_TransferBufferLengthCompleted);
+ DPRINT("m_TransferBufferLength %lu m_TransferBufferLengthCompleted %lu
DataToggle %x\n", m_TransferBufferLength, m_TransferBufferLengthCompleted,
m_EndpointDescriptor->DataToggle);
+
+ //
+ // build bulk transfer descriptor chain
+ //
+ Status = BuildTransferDescriptorChain(Base,
+ MaxTransferLength,
+ InternalGetPidDirection(),
+ &FirstDescriptor,
+ &LastDescriptor,
+ &ChainDescriptorLength);
+
+ //
+ // move to next offset
+ //
+ m_TransferBufferLengthCompleted += ChainDescriptorLength;
//
// first descriptor has no carry bit
@@ -1206,32 +1304,32 @@
FirstDescriptor->Flags &= ~OHCI_TD_TOGGLE_CARRY;
//
- // fixme: toggle
- //
- FirstDescriptor->Flags |= OHCI_TD_TOGGLE_0;
+ // apply data toggle
+ //
+ FirstDescriptor->Flags |= (m_EndpointDescriptor->DataToggle ? OHCI_TD_TOGGLE_1
: OHCI_TD_TOGGLE_0);
//
// clear interrupt mask for last transfer descriptor
//
- CurrentDescriptor->Flags &= ~OHCI_TD_INTERRUPT_MASK;
+ LastDescriptor->Flags &= ~OHCI_TD_INTERRUPT_MASK;
+
//
// fire interrupt as soon transfer is finished
//
- CurrentDescriptor->Flags |=
OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_IMMEDIATE);
-
- //
- // link last data descriptor to last descriptor
- //
- CurrentDescriptor->NextLogicalDescriptor = LastDescriptor;
- CurrentDescriptor->NextPhysicalDescriptor =
LastDescriptor->PhysicalAddress.LowPart;
+ LastDescriptor->Flags |=
OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_IMMEDIATE);
//
// now link descriptor to endpoint
//
EndpointDescriptor->HeadPhysicalDescriptor =
FirstDescriptor->PhysicalAddress.LowPart;
- EndpointDescriptor->TailPhysicalDescriptor =
LastDescriptor->PhysicalAddress.LowPart;
+ EndpointDescriptor->TailPhysicalDescriptor = (FirstDescriptor == LastDescriptor ?
0 : LastDescriptor->PhysicalAddress.LowPart);
EndpointDescriptor->HeadLogicalDescriptor = FirstDescriptor;
+
+ //
+ // dump descriptor list
+ //
+ //DumpEndpointDescriptor(EndpointDescriptor);
//
// store result
@@ -1567,6 +1665,12 @@
DPRINT("CUSBRequest::FreeEndpointDescriptor EndpointDescriptor %p Logical
%x\n", OutDescriptor, OutDescriptor->PhysicalAddress.LowPart);
+ //
+ // check for errors
+ //
+ CheckError(OutDescriptor);
+
+
if (OutDescriptor->Flags & OHCI_ENDPOINT_ISOCHRONOUS_FORMAT)
{
//
@@ -1685,6 +1789,14 @@
// get first general transfer descriptor
//
TransferDescriptor = (POHCI_GENERAL_TD)OutDescriptor->HeadLogicalDescriptor;
+
+ if (m_EndpointDescriptor != NULL)
+ {
+ //
+ // update data toggle
+ //
+ m_EndpointDescriptor->DataToggle =
(OutDescriptor->HeadPhysicalDescriptor & OHCI_ENDPOINT_TOGGLE_CARRY);
+ }
while(TransferDescriptor)
{
@@ -1776,21 +1888,18 @@
TransferDescriptor =
(POHCI_GENERAL_TD)TransferDescriptor->NextLogicalDescriptor;
}
}
+
+
+
}
VOID
-CUSBRequest::CompletionCallback(
- struct _OHCI_ENDPOINT_DESCRIPTOR * OutDescriptor)
+CUSBRequest::CompletionCallback()
{
PIO_STACK_LOCATION IoStack;
PURB Urb;
- DPRINT("CUSBRequest::CompletionCallback Descriptor %p PhysicalAddress
%x\n", OutDescriptor, OutDescriptor->PhysicalAddress.LowPart);
-
- //
- // check for errors
- //
- CheckError(OutDescriptor);
+ DPRINT("CUSBRequest::CompletionCallback\n");
if (m_Irp)
{
@@ -1826,12 +1935,11 @@
}
//
- // FIXME: support status and calculate length
- //
-
- //
- // FIXME: check if the transfer was split
- // if yes dont complete irp yet
+ // FIXME calculate length
+ //
+
+ //
+ // complete request
//
IoCompleteRequest(m_Irp, IO_NO_INCREMENT);
}
Modified: trunk/reactos/drivers/usb/usbohci/usbohci.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbohci/usbohc…
==============================================================================
--- trunk/reactos/drivers/usb/usbohci/usbohci.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbohci/usbohci.h [iso-8859-1] Sat Feb 18 23:23:13 2012
@@ -108,4 +108,26 @@
//
NTSTATUS InternalCreateUSBRequest(PUSBREQUEST *OutRequest);
+
+typedef struct _USB_ENDPOINT
+{
+ USB_ENDPOINT_DESCRIPTOR EndPointDescriptor;
+ UCHAR HubAddress;
+ UCHAR HubPort;
+ UCHAR DataToggle;
+} USB_ENDPOINT, *PUSB_ENDPOINT;
+
+typedef struct _USB_INTERFACE
+{
+ USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
+ USB_ENDPOINT *EndPoints;
+} USB_INTERFACE, *PUSB_INTERFACE;
+
+typedef struct _USB_CONFIGURATION
+{
+ PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
+ USB_INTERFACE *Interfaces;
+} USB_CONFIGURATION, *PUSB_CONFIGURATION;
+
+
#endif