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/CMakeLi... ============================================================================== --- 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/endpoin... ============================================================================== --- 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.c... ============================================================================== --- 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/trfspli... ============================================================================== --- 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/usbport... ============================================================================== --- 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/usbport... ============================================================================== --- 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/drivers... ============================================================================== --- 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;