Author: tfaber
Date: Fri Sep 8 07:17:34 2017
New Revision: 75783
URL:
http://svn.reactos.org/svn/reactos?rev=75783&view=rev
Log:
[USBPORT]
- Begin implementing split transfers. Patch by Vadim Galyant.
Added:
trunk/reactos/drivers/usb/usbport/trfsplit.c (with props)
Modified:
trunk/reactos/drivers/usb/usbport/CMakeLists.txt
trunk/reactos/drivers/usb/usbport/endpoint.c
trunk/reactos/drivers/usb/usbport/queue.c
trunk/reactos/drivers/usb/usbport/usbport.c
trunk/reactos/drivers/usb/usbport/usbport.h
trunk/reactos/sdk/include/reactos/drivers/usbport/usbmport.h
Modified: trunk/reactos/drivers/usb/usbport/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbport/CMakeL…
==============================================================================
--- trunk/reactos/drivers/usb/usbport/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbport/CMakeLists.txt [iso-8859-1] Fri Sep 8 07:17:34
2017
@@ -12,6 +12,7 @@
power.c
queue.c
roothub.c
+ trfsplit.c
urb.c
usb2.c
usbport.c
Modified: trunk/reactos/drivers/usb/usbport/endpoint.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbport/endpoi…
==============================================================================
--- trunk/reactos/drivers/usb/usbport/endpoint.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbport/endpoint.c [iso-8859-1] Fri Sep 8 07:17:34 2017
@@ -1279,8 +1279,7 @@
if (Transfer->Flags & TRANSFER_FLAG_SPLITED)
{
- DPRINT1("USBPORT_DmaEndpointActive: FIXME call
USBPORT_CancelSplitTransfer\n");
- ASSERT(FALSE); //USBPORT_CancelSplitTransfer();
+ USBPORT_CancelSplitTransfer(Transfer);
}
else
{
Modified: trunk/reactos/drivers/usb/usbport/queue.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbport/queue.…
==============================================================================
--- trunk/reactos/drivers/usb/usbport/queue.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbport/queue.c [iso-8859-1] Fri Sep 8 07:17:34 2017
@@ -529,6 +529,8 @@
PUSBPORT_TRANSFER Transfer;
PUSBPORT_ENDPOINT Endpoint;
PIRP irp;
+ PUSBPORT_TRANSFER SplitTransfer;
+ PLIST_ENTRY Entry;
KIRQL OldIrql;
DPRINT_CORE("USBPORT_CancelActiveTransferIrp: Irp - %p\n", Irp);
@@ -543,30 +545,52 @@
irp = USBPORT_FindActiveTransferIrp(FdoDevice, Irp);
- if (irp)
- {
- Urb = URB_FROM_IRP(irp);
- Transfer = Urb->UrbControlTransfer.hca.Reserved8[0];
- Endpoint = Transfer->Endpoint;
-
- DPRINT_CORE("USBPORT_CancelActiveTransferIrp: irp - %p, Urb - %p, Transfer -
%p\n",
- irp,
- Urb,
- Transfer);
-
- KeAcquireSpinLockAtDpcLevel(&Endpoint->EndpointSpinLock);
- Transfer->Flags |= TRANSFER_FLAG_CANCELED;
- KeReleaseSpinLockFromDpcLevel(&Endpoint->EndpointSpinLock);
-
+ if (!irp)
+ {
KeReleaseSpinLock(&FdoExtension->FlushTransferSpinLock, OldIrql);
-
- USBPORT_InvalidateEndpointHandler(FdoDevice,
- Endpoint,
- INVALIDATE_ENDPOINT_WORKER_THREAD);
return;
}
+ Urb = URB_FROM_IRP(irp);
+ Transfer = Urb->UrbControlTransfer.hca.Reserved8[0];
+ Endpoint = Transfer->Endpoint;
+
+ DPRINT_CORE("USBPORT_CancelActiveTransferIrp: irp - %p, Urb - %p, Transfer -
%p\n",
+ irp,
+ Urb,
+ Transfer);
+
+ KeAcquireSpinLockAtDpcLevel(&Endpoint->EndpointSpinLock);
+
+ Transfer->Flags |= TRANSFER_FLAG_CANCELED;
+
+ if (Transfer->Flags & TRANSFER_FLAG_PARENT)
+ {
+ KeAcquireSpinLockAtDpcLevel(&Transfer->TransferSpinLock);
+
+ Entry = Transfer->SplitTransfersList.Flink;
+
+ while (Entry && Entry != &Transfer->SplitTransfersList)
+ {
+ SplitTransfer = CONTAINING_RECORD(Entry,
+ USBPORT_TRANSFER,
+ SplitLink);
+
+ SplitTransfer->Flags |= TRANSFER_FLAG_CANCELED;
+
+ Entry = Entry->Flink;
+ }
+
+ KeReleaseSpinLockFromDpcLevel(&Transfer->TransferSpinLock);
+ }
+
+ KeReleaseSpinLockFromDpcLevel(&Endpoint->EndpointSpinLock);
KeReleaseSpinLock(&FdoExtension->FlushTransferSpinLock, OldIrql);
+
+ USBPORT_InvalidateEndpointHandler(FdoDevice,
+ Endpoint,
+ INVALIDATE_ENDPOINT_WORKER_THREAD);
+ return;
}
VOID
Added: trunk/reactos/drivers/usb/usbport/trfsplit.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbport/trfspl…
==============================================================================
--- trunk/reactos/drivers/usb/usbport/trfsplit.c (added)
+++ trunk/reactos/drivers/usb/usbport/trfsplit.c [iso-8859-1] Fri Sep 8 07:17:34 2017
@@ -0,0 +1,329 @@
+#include "usbport.h"
+
+#define NDEBUG
+#include <debug.h>
+
+ULONG
+NTAPI
+USBPORT_MakeSplitTransfer(IN PDEVICE_OBJECT FdoDevice,
+ IN PUSBPORT_TRANSFER Transfer,
+ IN PUSBPORT_TRANSFER SplitTransfer,
+ IN ULONG MaxTransferSize,
+ IN PULONG SgIdx,
+ IN PULONG SgOffset,
+ IN ULONG TransferRemainLen,
+ IN ULONG TransferOffset)
+{
+ PUSBPORT_SCATTER_GATHER_LIST SplitSgList;
+ PUSBPORT_SCATTER_GATHER_ELEMENT Element0;
+ PUSBPORT_SCATTER_GATHER_ELEMENT Element1;
+ SIZE_T SgLength;
+ SIZE_T SgRemainLen;
+
+ DPRINT("USBPORT_MakeSplitTransfer: ... \n");
+
+ SplitSgList = &SplitTransfer->SgList;
+ Element0 = &SplitSgList->SgElement[0];
+
+ SgLength = Transfer->SgList.SgElement[*SgIdx].SgTransferLength - *SgOffset;
+
+ if (SgLength > MaxTransferSize)
+ {
+ /* SgLength > MaxTransferSize */
+ SplitTransfer->SgList.SgElementCount = 1;
+
+ Element0->SgOffset = 0;
+ Element0->SgTransferLength = MaxTransferSize;
+ Element0->SgPhysicalAddress.LowPart =
Transfer->SgList.SgElement[*SgIdx].SgPhysicalAddress.LowPart + *SgOffset;
+
+ SplitTransfer->TransferParameters.IsTransferSplited = TRUE;
+ SplitTransfer->TransferParameters.TransferBufferLength = MaxTransferSize;
+
+ SplitTransfer->SgList.CurrentVa = Transfer->SgList.CurrentVa +
TransferOffset;
+ SplitTransfer->SgList.MappedSystemVa =
(PVOID)((ULONG_PTR)Transfer->SgList.MappedSystemVa + TransferOffset);
+
+ SplitTransfer->Flags |= TRANSFER_FLAG_SPLITED;
+
+ *SgOffset += MaxTransferSize;
+ TransferRemainLen -= MaxTransferSize;
+ return TransferRemainLen;
+ }
+
+ /* SgLength <= MaxTransferSize */
+ SplitTransfer->SgList.SgElementCount = 1;
+ TransferRemainLen -= SgLength;
+
+ Element0->SgOffset = 0;
+ Element0->SgTransferLength = SgLength;
+ Element0->SgPhysicalAddress.LowPart =
Transfer->SgList.SgElement[*SgIdx].SgPhysicalAddress.LowPart + *SgOffset;
+
+ SplitTransfer->TransferParameters.TransferBufferLength = SgLength;
+ SplitTransfer->TransferParameters.IsTransferSplited = TRUE;
+
+ SplitTransfer->SgList.CurrentVa = Transfer->SgList.CurrentVa + TransferOffset;
+ SplitTransfer->SgList.MappedSystemVa =
(PVOID)((ULONG_PTR)Transfer->SgList.MappedSystemVa + TransferOffset);
+
+ SplitTransfer->Flags |= TRANSFER_FLAG_SPLITED;
+
+ *SgOffset += SgLength;
+
+ SgRemainLen = MaxTransferSize - SgLength;
+
+ if (SgRemainLen > TransferRemainLen)
+ {
+ SgRemainLen = TransferRemainLen;
+ }
+
+ if (!SgRemainLen)
+ {
+ /* SgLength == MaxTransferSize */
+ ++*SgIdx;
+ *SgOffset = 0;
+ return TransferRemainLen;
+ }
+
+ /* SgLength < MaxTransferSize */
+
+ DPRINT1("MakeSplitTransfer: SgRemainLen - %x\n", SgRemainLen);
+ DPRINT1("MakeSplitTransfer: SgIdx - %x\n", *SgIdx);
+ ++*SgIdx;
+
+ *SgOffset = 0;
+ SplitTransfer->SgList.SgElementCount++;
+
+ Element1 = &SplitSgList->SgElement[1];
+
+ Element1->SgOffset = SgRemainLen;
+ Element1->SgTransferLength = Element0->SgTransferLength;
+ Element1->SgPhysicalAddress.LowPart =
Transfer->SgList.SgElement[*SgIdx].SgPhysicalAddress.LowPart + *SgOffset;
+
+ SplitTransfer->TransferParameters.TransferBufferLength += SgRemainLen;
+
+ *SgOffset += SgRemainLen;
+ TransferRemainLen -= SgRemainLen;
+
+ return TransferRemainLen;
+}
+
+VOID
+NTAPI
+USBPORT_SplitBulkInterruptTransfer(IN PDEVICE_OBJECT FdoDevice,
+ IN PUSBPORT_ENDPOINT Endpoint,
+ IN PUSBPORT_TRANSFER Transfer,
+ IN PLIST_ENTRY List)
+{
+ PUSBPORT_TRANSFER SplitTransfer;
+ LIST_ENTRY tmplist;
+ ULONG NeedSplits;
+ SIZE_T TransferBufferLength;
+ SIZE_T MaxTransferSize;
+ SIZE_T TransferOffset = 0;
+ SIZE_T RemainLength;
+ ULONG ix;
+ ULONG SgIdx = 0;
+ ULONG SgOffset = 0;
+
+ DPRINT("USBPORT_SplitBulkInterruptTransfer: ... \n");
+
+ MaxTransferSize = Endpoint->EndpointProperties.TotalMaxPacketSize *
+ (Endpoint->EndpointProperties.MaxTransferSize /
+ Endpoint->EndpointProperties.TotalMaxPacketSize);
+
+ if (Endpoint->EndpointProperties.MaxTransferSize > PAGE_SIZE)
+ {
+ KeBugCheckEx(BUGCODE_USB_DRIVER, 1, 0, 0, 0);
+ }
+
+ TransferBufferLength = Transfer->TransferParameters.TransferBufferLength;
+ Transfer->Flags |= TRANSFER_FLAG_PARENT;
+
+ NeedSplits = TransferBufferLength / MaxTransferSize + 1;
+
+ InitializeListHead(&tmplist);
+
+ DPRINT1("USBPORT_SplitBulkInterruptTransfer: TransferBufferLength - %x,
NeedSplits - %x\n",
+ TransferBufferLength, NeedSplits);
+
+ if (!NeedSplits)
+ {
+ DPRINT1("USBPORT_SplitBulkInterruptTransfer: DbgBreakPoint \n");
+ DbgBreakPoint();
+ goto Exit;
+ }
+
+ for (ix = 0; ix < NeedSplits; ++ix)
+ {
+ SplitTransfer = ExAllocatePoolWithTag(NonPagedPool,
+ Transfer->FullTransferLength,
+ USB_PORT_TAG);
+
+ if (!SplitTransfer)
+ {
+ DPRINT1("USBPORT_SplitBulkInterruptTransfer: DbgBreakPoint \n");
+ DbgBreakPoint();
+ goto Exit;
+ }
+
+ RtlCopyMemory(SplitTransfer, Transfer, Transfer->FullTransferLength);
+
+ SplitTransfer->MiniportTransfer = (PVOID)((ULONG_PTR)SplitTransfer +
+ SplitTransfer->PortTransferLength);
+
+ InsertTailList(&tmplist, &SplitTransfer->TransferLink);
+ }
+
+ if (Transfer->TransferParameters.TransferBufferLength == 0)
+ {
+ goto Exit;
+ }
+
+ RemainLength = Transfer->TransferParameters.TransferBufferLength;
+
+ do
+ {
+ SplitTransfer = CONTAINING_RECORD(tmplist.Flink,
+ USBPORT_TRANSFER,
+ TransferLink);
+
+ RemoveHeadList(&tmplist);
+
+ RemainLength = USBPORT_MakeSplitTransfer(FdoDevice,
+ Transfer,
+ SplitTransfer,
+ MaxTransferSize,
+ &SgIdx,
+ &SgOffset,
+ RemainLength,
+ TransferOffset);
+
+ TransferOffset += SplitTransfer->TransferParameters.TransferBufferLength;
+
+ InsertTailList(List, &SplitTransfer->TransferLink);
+
InsertTailList(&Transfer->SplitTransfersList,&SplitTransfer->SplitLink);
+ }
+ while (RemainLength != 0);
+
+Exit:
+
+ while (!IsListEmpty(&tmplist))
+ {
+ DPRINT1("USBPORT_SplitBulkInterruptTransfer: ... \n");
+
+ SplitTransfer = CONTAINING_RECORD(tmplist.Flink,
+ USBPORT_TRANSFER,
+ TransferLink);
+ RemoveHeadList(&tmplist);
+
+ ExFreePoolWithTag(SplitTransfer, USB_PORT_TAG);
+ }
+
+ return;
+}
+
+VOID
+NTAPI
+USBPORT_SplitTransfer(IN PDEVICE_OBJECT FdoDevice,
+ IN PUSBPORT_ENDPOINT Endpoint,
+ IN PUSBPORT_TRANSFER Transfer,
+ IN PLIST_ENTRY List)
+{
+ ULONG TransferType;
+
+ DPRINT("USBPORT_SplitTransfer ... \n");
+
+ InitializeListHead(List);
+ InitializeListHead(&Transfer->SplitTransfersList);
+
+ Transfer->USBDStatus = USBD_STATUS_SUCCESS;
+
+ if (Transfer->TransferParameters.TransferBufferLength >
+ Endpoint->EndpointProperties.MaxTransferSize)
+ {
+ TransferType = Endpoint->EndpointProperties.TransferType;
+
+ if (TransferType == USBPORT_TRANSFER_TYPE_BULK ||
+ TransferType == USBPORT_TRANSFER_TYPE_INTERRUPT)
+ {
+ USBPORT_SplitBulkInterruptTransfer(FdoDevice,
+ Endpoint,
+ Transfer,
+ List);
+ }
+ else if (TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS ||
+ TransferType == USBPORT_TRANSFER_TYPE_CONTROL)
+ {
+ KeBugCheckEx(BUGCODE_USB_DRIVER, 1, 0, 0, 0);
+ }
+ else
+ {
+ DPRINT1("USBPORT_SplitTransfer: Unknown TransferType - %x\n",
+ TransferType);
+ }
+ }
+ else
+ {
+ InsertTailList(List, &Transfer->TransferLink);
+ }
+}
+
+VOID
+NTAPI
+USBPORT_DoneSplitTransfer(IN PUSBPORT_TRANSFER SplitTransfer)
+{
+ PUSBPORT_TRANSFER ParentTransfer;
+ KIRQL OldIrql;
+
+ DPRINT("USBPORT_DoneSplitTransfer: ... \n");
+
+ ParentTransfer = SplitTransfer->ParentTransfer;
+ ParentTransfer->CompletedTransferLen += SplitTransfer->CompletedTransferLen;
+
+ if (SplitTransfer->USBDStatus != USBD_STATUS_SUCCESS)
+ {
+ DPRINT1("USBPORT_DoneSplitTransfer: SplitTransfer->USBDStatus -
%X\n",
+ SplitTransfer->USBDStatus);
+
+ ParentTransfer->USBDStatus = SplitTransfer->USBDStatus;
+ }
+
+ KeAcquireSpinLock(&ParentTransfer->TransferSpinLock, &OldIrql);
+
+ RemoveEntryList(&SplitTransfer->SplitLink);
+ ExFreePoolWithTag(SplitTransfer, USB_PORT_TAG);
+
+ if (IsListEmpty(&ParentTransfer->SplitTransfersList))
+ {
+ KeReleaseSpinLock(&ParentTransfer->TransferSpinLock, OldIrql);
+ USBPORT_DoneTransfer(ParentTransfer);
+ }
+ else
+ {
+ KeReleaseSpinLock(&ParentTransfer->TransferSpinLock, OldIrql);
+ }
+}
+
+VOID
+NTAPI
+USBPORT_CancelSplitTransfer(IN PUSBPORT_TRANSFER SplitTransfer)
+{
+ PUSBPORT_TRANSFER ParentTransfer;
+ PUSBPORT_ENDPOINT Endpoint;
+ KIRQL OldIrql;
+
+ DPRINT("USBPORT_CancelSplitTransfer \n");
+
+ Endpoint = SplitTransfer->Endpoint;
+ ParentTransfer = SplitTransfer->ParentTransfer;
+ ParentTransfer->CompletedTransferLen += SplitTransfer->CompletedTransferLen;
+
+ KeAcquireSpinLock(&ParentTransfer->TransferSpinLock, &OldIrql);
+ RemoveEntryList(&SplitTransfer->SplitLink);
+ KeReleaseSpinLock(&ParentTransfer->TransferSpinLock, OldIrql);
+
+ ExFreePool(SplitTransfer);
+
+ if (IsListEmpty(&ParentTransfer->SplitTransfersList))
+ {
+ InsertTailList(&Endpoint->CancelList,
&ParentTransfer->TransferLink);
+ }
+}
Propchange: trunk/reactos/drivers/usb/usbport/trfsplit.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/drivers/usb/usbport/usbport.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbport/usbpor…
==============================================================================
--- trunk/reactos/drivers/usb/usbport/usbport.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbport/usbport.c [iso-8859-1] Fri Sep 8 07:17:34 2017
@@ -789,7 +789,7 @@
if ((Transfer->Flags & TRANSFER_FLAG_SPLITED))
{
- ASSERT(FALSE);// USBPORT_DoneSplitTransfer(Transfer);
+ USBPORT_DoneSplitTransfer(Transfer);
}
else
{
@@ -1946,8 +1946,11 @@
IN ULONG TransferLength)
{
PUSBPORT_TRANSFER Transfer;
- PDEVICE_OBJECT FdoDevice;
- PUSBPORT_DEVICE_EXTENSION FdoExtension;
+ PUSBPORT_TRANSFER ParentTransfer;
+ PUSBPORT_TRANSFER SplitTransfer;
+ PLIST_ENTRY SplitHead;
+ PLIST_ENTRY Entry;
+ KIRQL OldIrql;
DPRINT_CORE("USBPORT_MiniportCompleteTransfer: USBDStatus - %x, TransferLength -
%x\n",
USBDStatus,
@@ -1957,20 +1960,47 @@
USBPORT_TRANSFER,
TransferParameters);
- FdoDevice = Transfer->Endpoint->FdoDevice;
- FdoExtension = FdoDevice->DeviceExtension;
-
+ Transfer->Flags |= TRANSFER_FLAG_COMPLETED;
Transfer->CompletedTransferLen = TransferLength;
- RemoveEntryList(&Transfer->TransferLink);
-
- Transfer->USBDStatus = USBDStatus;
-
- ExInterlockedInsertTailList(&FdoExtension->DoneTransferList,
- &Transfer->TransferLink,
- &FdoExtension->DoneTransferSpinLock);
-
- KeInsertQueueDpc(&FdoExtension->TransferFlushDpc, NULL, NULL);
+ if (((Transfer->Flags & TRANSFER_FLAG_SPLITED) == 0) ||
+ TransferLength >= Transfer->TransferParameters.TransferBufferLength)
+ {
+ goto Exit;
+ }
+
+ ParentTransfer = Transfer->ParentTransfer;
+
+ KeAcquireSpinLock(&ParentTransfer->TransferSpinLock, &OldIrql);
+
+ if (IsListEmpty(&ParentTransfer->SplitTransfersList))
+ {
+ goto Exit;
+ }
+
+ SplitHead = &ParentTransfer->SplitTransfersList;
+ Entry = SplitHead->Flink;
+
+ while (Entry && !IsListEmpty(SplitHead))
+ {
+ SplitTransfer = CONTAINING_RECORD(Entry,
+ USBPORT_TRANSFER,
+ SplitLink);
+
+ if (!(SplitTransfer->Flags & TRANSFER_FLAG_SUBMITED))
+ {
+ DPRINT1("USBPORT_MiniportCompleteTransfer: SplitTransfer->Flags -
%X\n",
+ SplitTransfer->Flags);
+ //Add TRANSFER_FLAG_xxx
+ }
+
+ Entry = Entry->Flink;
+ }
+
+ KeReleaseSpinLock(&ParentTransfer->TransferSpinLock, OldIrql);
+
+Exit:
+ USBPORT_QueueDoneTransfer(Transfer, USBDStatus);
}
VOID
@@ -2250,6 +2280,9 @@
SIZE_T ElementLength;
PUSBPORT_DEVICE_HANDLE DeviceHandle;
PDMA_OPERATIONS DmaOperations;
+ USBD_STATUS USBDStatus;
+ LIST_ENTRY List;
+ PUSBPORT_TRANSFER transfer;
DPRINT_CORE("USBPORT_MapTransfer: ... \n");
@@ -2266,12 +2299,12 @@
Mdl = Urb->UrbControlTransfer.TransferBufferMDL;
CurrentVa = (ULONG_PTR)MmGetMdlVirtualAddress(Mdl);
- Transfer->SgList.CurrentVa = CurrentVa;
- Transfer->SgList.MappedSystemVa = MmGetSystemAddressForMdlSafe(Mdl,
NormalPagePriority);
-
sgList = &Transfer->SgList;
+
sgList->Flags = 0;
-
+ sgList->CurrentVa = CurrentVa;
+ sgList->MappedSystemVa = MmGetSystemAddressForMdlSafe(Mdl,
+ NormalPagePriority);
Transfer->MapRegisterBase = MapRegisterBase;
ix = 0;
@@ -2337,15 +2370,52 @@
}
while (CurrentLength != Transfer->TransferParameters.TransferBufferLength);
- Transfer->SgList.SgElementCount = ix;
+ sgList->SgElementCount = ix;
+
+ if (Endpoint->EndpointProperties.DeviceSpeed == UsbHighSpeed)
+ {
+ Transfer->Flags |= TRANSFER_FLAG_HIGH_SPEED;
+ }
+
Transfer->Flags |= TRANSFER_FLAG_DMA_MAPPED;
- ASSERT(Transfer->TransferParameters.TransferBufferLength <=
- Endpoint->EndpointProperties.MaxTransferSize);
-
- KeAcquireSpinLock(&Endpoint->EndpointSpinLock,
&Endpoint->EndpointOldIrql);
- InsertTailList(&Endpoint->TransferList, &Transfer->TransferLink);
- KeReleaseSpinLock(&Endpoint->EndpointSpinLock, Endpoint->EndpointOldIrql);
+ if ((Transfer->Flags & TRANSFER_FLAG_ISO) == 0)
+ {
+ KeAcquireSpinLock(&Endpoint->EndpointSpinLock,
+ &Endpoint->EndpointOldIrql);
+
+ USBPORT_SplitTransfer(FdoDevice, Endpoint, Transfer, &List);
+
+ while (!IsListEmpty(&List))
+ {
+ transfer = CONTAINING_RECORD(List.Flink,
+ USBPORT_TRANSFER,
+ TransferLink);
+
+ RemoveHeadList(&List);
+ InsertTailList(&Endpoint->TransferList,
&transfer->TransferLink);
+ }
+
+ KeReleaseSpinLock(&Endpoint->EndpointSpinLock,
+ Endpoint->EndpointOldIrql);
+ }
+ else
+ {
+ USBDStatus = USBPORT_InitializeIsoTransfer(FdoDevice,
+ &Urb->UrbIsochronousTransfer,
+ Transfer);
+
+ if (USBDStatus != USBD_STATUS_SUCCESS)
+ {
+ KeAcquireSpinLock(&Endpoint->EndpointSpinLock,
+ &Endpoint->EndpointOldIrql);
+
+ USBPORT_QueueDoneTransfer(Transfer, USBDStatus);
+
+ KeReleaseSpinLock(&Endpoint->EndpointSpinLock,
+ Endpoint->EndpointOldIrql);
+ }
+ }
DeviceHandle = Urb->UrbHeader.UsbdDeviceHandle;
InterlockedDecrement(&DeviceHandle->DeviceHandleLock);
@@ -2438,6 +2508,7 @@
PUSBPORT_TRANSFER Transfer;
PUSBPORT_PIPE_HANDLE PipeHandle;
USBD_STATUS USBDStatus;
+ SIZE_T IsoBlockLen = 0;
DPRINT_CORE("USBPORT_AllocateTransfer: FdoDevice - %p, Urb - %p, DeviceHandle -
%p, Irp - %p, Event - %p\n",
FdoDevice,
@@ -2458,15 +2529,24 @@
PagesNeed = ADDRESS_AND_SIZE_TO_SPAN_PAGES(VirtualAddr,
TransferLength);
+ if (PagesNeed > 0)
+ {
+ PagesNeed--;
+ }
}
if (Urb->UrbHeader.Function == URB_FUNCTION_ISOCH_TRANSFER)
{
- DPRINT1("USBPORT_AllocateTransfer: ISOCH_TRANSFER UNIMPLEMENTED.
FIXME.\n");
+ DPRINT1("USBPORT_AllocateTransfer: ISOCH_TRANSFER UNIMPLEMENTED.
FIXME\n");
+
+ //IsoBlockLen = sizeof(USBPORT_ISO_BLOCK) +
+ // Urb->UrbIsochronousTransfer.NumberOfPackets *
+ // sizeof(USBPORT_ISO_BLOCK_PACKET);
}
PortTransferLength = sizeof(USBPORT_TRANSFER) +
- PagesNeed * sizeof(USBPORT_SCATTER_GATHER_ELEMENT);
+ PagesNeed * sizeof(USBPORT_SCATTER_GATHER_ELEMENT) +
+ IsoBlockLen;
FullTransferLength = PortTransferLength +
FdoExtension->MiniPortInterface->Packet.MiniPortTransferSize;
@@ -2475,29 +2555,42 @@
FullTransferLength,
USB_PORT_TAG);
- if (Transfer)
- {
- RtlZeroMemory(Transfer, FullTransferLength);
-
- Transfer->Irp = Irp;
- Transfer->Urb = Urb;
- Transfer->Endpoint = PipeHandle->Endpoint;
- Transfer->Event = Event;
- Transfer->PortTransferLength = PortTransferLength;
- Transfer->FullTransferLength = FullTransferLength;
-
- Transfer->MiniportTransfer = (PVOID)((ULONG_PTR)Transfer +
- PortTransferLength);
-
- Urb->UrbControlTransfer.hca.Reserved8[0] = Transfer;
- Urb->UrbHeader.UsbdFlags |= USBD_FLAG_ALLOCATED_TRANSFER;
-
- USBDStatus = USBD_STATUS_SUCCESS;
- }
- else
- {
- USBDStatus = USBD_STATUS_INSUFFICIENT_RESOURCES;
- }
+ if (!Transfer)
+ {
+ DPRINT1("USBPORT_AllocateTransfer: Transfer not allocated!\n");
+ return USBD_STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ RtlZeroMemory(Transfer, FullTransferLength);
+
+ Transfer->Irp = Irp;
+ Transfer->Urb = Urb;
+ Transfer->Endpoint = PipeHandle->Endpoint;
+ Transfer->Event = Event;
+ Transfer->PortTransferLength = PortTransferLength;
+ Transfer->FullTransferLength = FullTransferLength;
+ Transfer->IsoBlockPtr = NULL;
+ Transfer->Period = 0;
+ Transfer->ParentTransfer = Transfer;
+
+ if (IsoBlockLen)
+ {
+ Transfer->IsoBlockPtr = (PVOID)((ULONG_PTR)Transfer +
+ PortTransferLength - IsoBlockLen);
+
+ Transfer->Period = PipeHandle->Endpoint->EndpointProperties.Period;
+ Transfer->Flags |= TRANSFER_FLAG_ISO;
+ }
+
+ Transfer->MiniportTransfer = (PVOID)((ULONG_PTR)Transfer +
+ PortTransferLength);
+
+ KeInitializeSpinLock(&Transfer->TransferSpinLock);
+
+ Urb->UrbControlTransfer.hca.Reserved8[0] = Transfer;
+ Urb->UrbHeader.UsbdFlags |= USBD_FLAG_ALLOCATED_TRANSFER;
+
+ USBDStatus = USBD_STATUS_SUCCESS;
DPRINT_CORE("USBPORT_AllocateTransfer: return USBDStatus - %x\n",
USBDStatus);
Modified: trunk/reactos/drivers/usb/usbport/usbport.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbport/usbpor…
==============================================================================
--- trunk/reactos/drivers/usb/usbport/usbport.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbport/usbport.h [iso-8859-1] Fri Sep 8 07:17:34 2017
@@ -121,11 +121,14 @@
/* Transfer Flags (USBPORT_TRANSFER) */
#define TRANSFER_FLAG_CANCELED 0x00000001
#define TRANSFER_FLAG_DMA_MAPPED 0x00000002
+#define TRANSFER_FLAG_HIGH_SPEED 0x00000004
#define TRANSFER_FLAG_SUBMITED 0x00000008
#define TRANSFER_FLAG_ABORTED 0x00000010
#define TRANSFER_FLAG_ISO 0x00000020
#define TRANSFER_FLAG_DEVICE_GONE 0x00000080
#define TRANSFER_FLAG_SPLITED 0x00000100
+#define TRANSFER_FLAG_COMPLETED 0x00000200
+#define TRANSFER_FLAG_PARENT 0x00000400
extern KSPIN_LOCK USBPORT_SpinLock;
extern LIST_ENTRY USBPORT_MiniPortDrivers;
@@ -218,6 +221,8 @@
LIST_ENTRY FlushAbortLink;
} USBPORT_ENDPOINT, *PUSBPORT_ENDPOINT;
+typedef struct _USBPORT_ISO_BLOCK *PUSBPORT_ISO_BLOCK;
+
typedef struct _USBPORT_TRANSFER {
ULONG Flags;
PIRP Irp;
@@ -237,8 +242,15 @@
PVOID MapRegisterBase;
ULONG TimeOut;
LARGE_INTEGER Time;
+ struct _USBPORT_TRANSFER * ParentTransfer;
+ KSPIN_LOCK TransferSpinLock;
+ LIST_ENTRY SplitTransfersList; // for parent transfers
+ LIST_ENTRY SplitLink; // for splitted transfers
+ ULONG Period;
+ PUSBPORT_ISO_BLOCK IsoBlockPtr; // pointer on IsoBlock
// SgList should be LAST field
- USBPORT_SCATTER_GATHER_LIST SgList; // Non IsoTransfer
+ USBPORT_SCATTER_GATHER_LIST SgList; // variable length
+ //USBPORT_ISO_BLOCK IsoBlock; // variable length
} USBPORT_TRANSFER, *PUSBPORT_TRANSFER;
typedef struct _USBPORT_IRP_TABLE {
@@ -573,6 +585,11 @@
IN PDEVICE_OBJECT FdoDevice,
IN ULONG Type);
+VOID
+NTAPI
+USBPORT_DoneTransfer(
+ IN PUSBPORT_TRANSFER Transfer);
+
/* debug.c */
ULONG
NTAPI
@@ -1120,6 +1137,25 @@
USBPORT_RootHubPowerAndChirpAllCcPorts(
IN PDEVICE_OBJECT FdoDevice);
+/* trfsplit.c */
+VOID
+NTAPI
+USBPORT_SplitTransfer(
+ IN PDEVICE_OBJECT FdoDevice,
+ IN PUSBPORT_ENDPOINT Endpoint,
+ IN PUSBPORT_TRANSFER Transfer,
+ IN PLIST_ENTRY List);
+
+VOID
+NTAPI
+USBPORT_DoneSplitTransfer(
+ IN PUSBPORT_TRANSFER SplitTransfer);
+
+VOID
+NTAPI
+USBPORT_CancelSplitTransfer(
+ IN PUSBPORT_TRANSFER SplitTransfer);
+
/* urb.c */
NTSTATUS
NTAPI
Modified: trunk/reactos/sdk/include/reactos/drivers/usbport/usbmport.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/include/reactos/driver…
==============================================================================
--- trunk/reactos/sdk/include/reactos/drivers/usbport/usbmport.h [iso-8859-1] (original)
+++ trunk/reactos/sdk/include/reactos/drivers/usbport/usbmport.h [iso-8859-1] Fri Sep 8
07:17:34 2017
@@ -626,16 +626,16 @@
ULONG_PTR CurrentVa;
PVOID MappedSystemVa;
ULONG SgElementCount;
- USBPORT_SCATTER_GATHER_ELEMENT SgElement[1];
+ USBPORT_SCATTER_GATHER_ELEMENT SgElement[2];
} USBPORT_SCATTER_GATHER_LIST, *PUSBPORT_SCATTER_GATHER_LIST;
-C_ASSERT(sizeof(USBPORT_SCATTER_GATHER_LIST) == 24 + 4 * sizeof(PVOID));
+C_ASSERT(sizeof(USBPORT_SCATTER_GATHER_LIST) == 48 + 4 * sizeof(PVOID));
typedef struct _USBPORT_TRANSFER_PARAMETERS {
ULONG TransferFlags;
ULONG TransferBufferLength;
ULONG TransferCounter;
- ULONG Reserved1;
+ BOOL IsTransferSplited;
ULONG Reserved2;
USB_DEFAULT_PIPE_SETUP_PACKET SetupPacket;
} USBPORT_TRANSFER_PARAMETERS, *PUSBPORT_TRANSFER_PARAMETERS;