ReactOS  0.4.14-dev-368-gfa26425
trfsplit.c File Reference
#include "usbport.h"
#include <debug.h>
Include dependency graph for trfsplit.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

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)
 
VOID NTAPI USBPORT_SplitBulkInterruptTransfer (IN PDEVICE_OBJECT FdoDevice, IN PUSBPORT_ENDPOINT Endpoint, IN PUSBPORT_TRANSFER Transfer, IN PLIST_ENTRY List)
 
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)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 10 of file trfsplit.c.

Function Documentation

◆ USBPORT_CancelSplitTransfer()

VOID NTAPI USBPORT_CancelSplitTransfer ( IN PUSBPORT_TRANSFER  SplitTransfer)

Definition at line 314 of file trfsplit.c.

315 {
316  PUSBPORT_TRANSFER ParentTransfer;
317  PUSBPORT_ENDPOINT Endpoint;
318  KIRQL OldIrql;
319 
320  DPRINT("USBPORT_CancelSplitTransfer \n");
321 
322  Endpoint = SplitTransfer->Endpoint;
323  ParentTransfer = SplitTransfer->ParentTransfer;
324  ParentTransfer->CompletedTransferLen += SplitTransfer->CompletedTransferLen;
325 
326  KeAcquireSpinLock(&ParentTransfer->TransferSpinLock, &OldIrql);
327  RemoveEntryList(&SplitTransfer->SplitLink);
328  KeReleaseSpinLock(&ParentTransfer->TransferSpinLock, OldIrql);
329 
330  ExFreePool(SplitTransfer);
331 
332  if (IsListEmpty(&ParentTransfer->SplitTransfersList))
333  {
334  InsertTailList(&Endpoint->CancelList, &ParentTransfer->TransferLink);
335  }
336 }
#define InsertTailList(ListHead, Entry)
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
UCHAR KIRQL
Definition: env_spec_w32.h:591
struct _USBPORT_TRANSFER * ParentTransfer
Definition: usbport.h:263
void DPRINT(...)
Definition: polytest.cpp:61
LIST_ENTRY TransferLink
Definition: usbport.h:256
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
LIST_ENTRY SplitTransfersList
Definition: usbport.h:265
KSPIN_LOCK TransferSpinLock
Definition: usbport.h:264
ULONG CompletedTransferLen
Definition: usbport.h:258
LIST_ENTRY CancelList
Definition: usbport.h:228
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by USBPORT_DmaEndpointPaused().

◆ USBPORT_DoneSplitTransfer()

VOID NTAPI USBPORT_DoneSplitTransfer ( IN PUSBPORT_TRANSFER  SplitTransfer)

Definition at line 278 of file trfsplit.c.

279 {
280  PUSBPORT_TRANSFER ParentTransfer;
281  KIRQL OldIrql;
282 
283  DPRINT("USBPORT_DoneSplitTransfer: ... \n");
284 
285  ParentTransfer = SplitTransfer->ParentTransfer;
286  ParentTransfer->CompletedTransferLen += SplitTransfer->CompletedTransferLen;
287 
288  if (SplitTransfer->USBDStatus != USBD_STATUS_SUCCESS)
289  {
290  DPRINT1("USBPORT_DoneSplitTransfer: SplitTransfer->USBDStatus - %X\n",
291  SplitTransfer->USBDStatus);
292 
293  ParentTransfer->USBDStatus = SplitTransfer->USBDStatus;
294  }
295 
296  KeAcquireSpinLock(&ParentTransfer->TransferSpinLock, &OldIrql);
297 
298  RemoveEntryList(&SplitTransfer->SplitLink);
299  ExFreePoolWithTag(SplitTransfer, USB_PORT_TAG);
300 
301  if (IsListEmpty(&ParentTransfer->SplitTransfersList))
302  {
303  KeReleaseSpinLock(&ParentTransfer->TransferSpinLock, OldIrql);
304  USBPORT_DoneTransfer(ParentTransfer);
305  }
306  else
307  {
308  KeReleaseSpinLock(&ParentTransfer->TransferSpinLock, OldIrql);
309  }
310 }
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
#define USB_PORT_TAG
Definition: usbport.h:44
UCHAR KIRQL
Definition: env_spec_w32.h:591
struct _USBPORT_TRANSFER * ParentTransfer
Definition: usbport.h:263
void DPRINT(...)
Definition: polytest.cpp:61
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
VOID NTAPI USBPORT_DoneTransfer(IN PUSBPORT_TRANSFER Transfer)
Definition: usbport.c:724
#define USBD_STATUS_SUCCESS
Definition: usb.h:170
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
LIST_ENTRY SplitTransfersList
Definition: usbport.h:265
#define DPRINT1
Definition: precomp.h:8
KSPIN_LOCK TransferSpinLock
Definition: usbport.h:264
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
USBD_STATUS USBDStatus
Definition: usbport.h:257
ULONG CompletedTransferLen
Definition: usbport.h:258

Referenced by USBPORT_FlushDoneTransfers().

◆ USBPORT_MakeSplitTransfer()

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 
)

Definition at line 15 of file trfsplit.c.

23 {
24  PUSBPORT_SCATTER_GATHER_LIST SplitSgList;
27  SIZE_T SgLength;
28  SIZE_T SgRemainLen;
29 
30  DPRINT("USBPORT_MakeSplitTransfer: ... \n");
31 
32  SplitSgList = &SplitTransfer->SgList;
33  Element0 = &SplitSgList->SgElement[0];
34 
35  SgLength = Transfer->SgList.SgElement[*SgIdx].SgTransferLength - *SgOffset;
36 
37  if (SgLength > MaxTransferSize)
38  {
39  /* SgLength > MaxTransferSize */
40  SplitTransfer->SgList.SgElementCount = 1;
41 
42  Element0->SgOffset = 0;
43  Element0->SgTransferLength = MaxTransferSize;
44  Element0->SgPhysicalAddress.LowPart = Transfer->SgList.SgElement[*SgIdx].SgPhysicalAddress.LowPart + *SgOffset;
45 
46  SplitTransfer->TransferParameters.IsTransferSplited = TRUE;
47  SplitTransfer->TransferParameters.TransferBufferLength = MaxTransferSize;
48 
49  SplitTransfer->SgList.CurrentVa = Transfer->SgList.CurrentVa + TransferOffset;
50  SplitTransfer->SgList.MappedSystemVa = (PVOID)((ULONG_PTR)Transfer->SgList.MappedSystemVa + TransferOffset);
51 
52  SplitTransfer->Flags |= TRANSFER_FLAG_SPLITED;
53 
54  *SgOffset += MaxTransferSize;
55  TransferRemainLen -= MaxTransferSize;
56  return TransferRemainLen;
57  }
58 
59  /* SgLength <= MaxTransferSize */
60  SplitTransfer->SgList.SgElementCount = 1;
61  TransferRemainLen -= SgLength;
62 
63  Element0->SgOffset = 0;
64  Element0->SgTransferLength = SgLength;
65  Element0->SgPhysicalAddress.LowPart = Transfer->SgList.SgElement[*SgIdx].SgPhysicalAddress.LowPart + *SgOffset;
66 
67  SplitTransfer->TransferParameters.TransferBufferLength = SgLength;
68  SplitTransfer->TransferParameters.IsTransferSplited = TRUE;
69 
70  SplitTransfer->SgList.CurrentVa = Transfer->SgList.CurrentVa + TransferOffset;
71  SplitTransfer->SgList.MappedSystemVa = (PVOID)((ULONG_PTR)Transfer->SgList.MappedSystemVa + TransferOffset);
72 
73  SplitTransfer->Flags |= TRANSFER_FLAG_SPLITED;
74 
75  *SgOffset += SgLength;
76 
77  SgRemainLen = MaxTransferSize - SgLength;
78 
79  if (SgRemainLen > TransferRemainLen)
80  {
81  SgRemainLen = TransferRemainLen;
82  }
83 
84  if (!SgRemainLen)
85  {
86  /* SgLength == MaxTransferSize */
87  ++*SgIdx;
88  *SgOffset = 0;
89  return TransferRemainLen;
90  }
91 
92  /* SgLength < MaxTransferSize */
93 
94  DPRINT1("MakeSplitTransfer: SgRemainLen - %x\n", SgRemainLen);
95  DPRINT1("MakeSplitTransfer: SgIdx - %x\n", *SgIdx);
96  ++*SgIdx;
97 
98  *SgOffset = 0;
99  SplitTransfer->SgList.SgElementCount++;
100 
101  Element1 = &SplitSgList->SgElement[1];
102 
103  Element1->SgOffset = SgRemainLen;
104  Element1->SgTransferLength = Element0->SgTransferLength;
105  Element1->SgPhysicalAddress.LowPart = Transfer->SgList.SgElement[*SgIdx].SgPhysicalAddress.LowPart + *SgOffset;
106 
107  SplitTransfer->TransferParameters.TransferBufferLength += SgRemainLen;
108 
109  *SgOffset += SgRemainLen;
110  TransferRemainLen -= SgRemainLen;
111 
112  return TransferRemainLen;
113 }
#define TRUE
Definition: types.h:120
PHYSICAL_ADDRESS SgPhysicalAddress
Definition: usbmport.h:107
uint32_t ULONG_PTR
Definition: typedefs.h:63
void DPRINT(...)
Definition: polytest.cpp:61
void * PVOID
Definition: retypes.h:9
ULONG LowPart
Definition: typedefs.h:104
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define TRANSFER_FLAG_SPLITED
Definition: usbport.h:136
USBPORT_SCATTER_GATHER_ELEMENT SgElement[2]
Definition: usbmport.h:121
#define DPRINT1
Definition: precomp.h:8

Referenced by USBPORT_SplitBulkInterruptTransfer().

◆ USBPORT_SplitBulkInterruptTransfer()

VOID NTAPI USBPORT_SplitBulkInterruptTransfer ( IN PDEVICE_OBJECT  FdoDevice,
IN PUSBPORT_ENDPOINT  Endpoint,
IN PUSBPORT_TRANSFER  Transfer,
IN PLIST_ENTRY  List 
)

Definition at line 117 of file trfsplit.c.

121 {
122  PUSBPORT_TRANSFER SplitTransfer;
123  LIST_ENTRY tmplist;
124  ULONG NeedSplits;
125  SIZE_T TransferBufferLength;
126  SIZE_T MaxTransferSize;
127  SIZE_T TransferOffset = 0;
128  SIZE_T RemainLength;
129  ULONG ix;
130  ULONG SgIdx = 0;
131  ULONG SgOffset = 0;
132 
133  DPRINT("USBPORT_SplitBulkInterruptTransfer: ... \n");
134 
135  MaxTransferSize = Endpoint->EndpointProperties.TotalMaxPacketSize *
136  (Endpoint->EndpointProperties.MaxTransferSize /
137  Endpoint->EndpointProperties.TotalMaxPacketSize);
138 
139  if (Endpoint->EndpointProperties.MaxTransferSize > PAGE_SIZE)
140  {
141  KeBugCheckEx(BUGCODE_USB_DRIVER, 1, 0, 0, 0);
142  }
143 
144  TransferBufferLength = Transfer->TransferParameters.TransferBufferLength;
145  Transfer->Flags |= TRANSFER_FLAG_PARENT;
146 
147  NeedSplits = TransferBufferLength / MaxTransferSize + 1;
148 
149  InitializeListHead(&tmplist);
150 
151  DPRINT("USBPORT_SplitBulkInterruptTransfer: TransferBufferLength - %x, NeedSplits - %x\n",
152  TransferBufferLength, NeedSplits);
153 
154  if (!NeedSplits)
155  {
156  DPRINT1("USBPORT_SplitBulkInterruptTransfer: DbgBreakPoint \n");
157  DbgBreakPoint();
158  goto Exit;
159  }
160 
161  for (ix = 0; ix < NeedSplits; ++ix)
162  {
163  SplitTransfer = ExAllocatePoolWithTag(NonPagedPool,
164  Transfer->FullTransferLength,
165  USB_PORT_TAG);
166 
167  if (!SplitTransfer)
168  {
169  DPRINT1("USBPORT_SplitBulkInterruptTransfer: DbgBreakPoint \n");
170  DbgBreakPoint();
171  goto Exit;
172  }
173 
174  RtlCopyMemory(SplitTransfer, Transfer, Transfer->FullTransferLength);
175 
176  SplitTransfer->MiniportTransfer = (PVOID)((ULONG_PTR)SplitTransfer +
177  SplitTransfer->PortTransferLength);
178 
179  InsertTailList(&tmplist, &SplitTransfer->TransferLink);
180  }
181 
182  if (Transfer->TransferParameters.TransferBufferLength == 0)
183  {
184  goto Exit;
185  }
186 
187  RemainLength = Transfer->TransferParameters.TransferBufferLength;
188 
189  do
190  {
191  SplitTransfer = CONTAINING_RECORD(tmplist.Flink,
193  TransferLink);
194 
195  RemoveHeadList(&tmplist);
196 
197  RemainLength = USBPORT_MakeSplitTransfer(FdoDevice,
198  Transfer,
199  SplitTransfer,
200  MaxTransferSize,
201  &SgIdx,
202  &SgOffset,
203  RemainLength,
204  TransferOffset);
205 
206  TransferOffset += SplitTransfer->TransferParameters.TransferBufferLength;
207 
208  InsertTailList(List, &SplitTransfer->TransferLink);
209  InsertTailList(&Transfer->SplitTransfersList,&SplitTransfer->SplitLink);
210  }
211  while (RemainLength != 0);
212 
213 Exit:
214 
215  while (!IsListEmpty(&tmplist))
216  {
217  DPRINT("USBPORT_SplitBulkInterruptTransfer: ... \n");
218 
219  SplitTransfer = CONTAINING_RECORD(tmplist.Flink,
221  TransferLink);
222  RemoveHeadList(&tmplist);
223 
224  ExFreePoolWithTag(SplitTransfer, USB_PORT_TAG);
225  }
226 
227  return;
228 }
LIST_ENTRY SplitLink
Definition: usbport.h:266
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
USBPORT_TRANSFER_PARAMETERS TransferParameters
Definition: usbport.h:253
#define TRANSFER_FLAG_PARENT
Definition: usbport.h:138
#define InsertTailList(ListHead, Entry)
void DbgBreakPoint()
Definition: mach.c:553
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define USB_PORT_TAG
Definition: usbport.h:44
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
void DPRINT(...)
Definition: polytest.cpp:61
void * PVOID
Definition: retypes.h:9
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
SIZE_T PortTransferLength
Definition: usbport.h:250
LIST_ENTRY TransferLink
Definition: usbport.h:256
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
LIST_ENTRY List
Definition: psmgr.c:57
static void Exit(void)
Definition: sock.c:1331
PVOID MiniportTransfer
Definition: usbport.h:249
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)
Definition: trfsplit.c:15
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PAGE_SIZE
Definition: env_spec_w32.h:49
Definition: typedefs.h:117
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:107

Referenced by USBPORT_SplitTransfer().

◆ USBPORT_SplitTransfer()

VOID NTAPI USBPORT_SplitTransfer ( IN PDEVICE_OBJECT  FdoDevice,
IN PUSBPORT_ENDPOINT  Endpoint,
IN PUSBPORT_TRANSFER  Transfer,
IN PLIST_ENTRY  List 
)

Definition at line 232 of file trfsplit.c.

236 {
237  ULONG TransferType;
238 
239  DPRINT("USBPORT_SplitTransfer ... \n");
240 
242  InitializeListHead(&Transfer->SplitTransfersList);
243 
244  Transfer->USBDStatus = USBD_STATUS_SUCCESS;
245 
246  if (Transfer->TransferParameters.TransferBufferLength >
247  Endpoint->EndpointProperties.MaxTransferSize)
248  {
249  TransferType = Endpoint->EndpointProperties.TransferType;
250 
251  if (TransferType == USBPORT_TRANSFER_TYPE_BULK ||
252  TransferType == USBPORT_TRANSFER_TYPE_INTERRUPT)
253  {
255  Endpoint,
256  Transfer,
257  List);
258  }
259  else if (TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS ||
260  TransferType == USBPORT_TRANSFER_TYPE_CONTROL)
261  {
262  KeBugCheckEx(BUGCODE_USB_DRIVER, 1, 0, 0, 0);
263  }
264  else
265  {
266  DPRINT1("USBPORT_SplitTransfer: Unknown TransferType - %x\n",
267  TransferType);
268  }
269  }
270  else
271  {
272  InsertTailList(List, &Transfer->TransferLink);
273  }
274 }
#define USBPORT_TRANSFER_TYPE_BULK
Definition: usbmport.h:9
#define USBPORT_TRANSFER_TYPE_CONTROL
Definition: usbmport.h:8
#define InsertTailList(ListHead, Entry)
void DPRINT(...)
Definition: polytest.cpp:61
VOID NTAPI USBPORT_SplitBulkInterruptTransfer(IN PDEVICE_OBJECT FdoDevice, IN PUSBPORT_ENDPOINT Endpoint, IN PUSBPORT_TRANSFER Transfer, IN PLIST_ENTRY List)
Definition: trfsplit.c:117
LIST_ENTRY List
Definition: psmgr.c:57
#define USBD_STATUS_SUCCESS
Definition: usb.h:170
#define USBPORT_TRANSFER_TYPE_INTERRUPT
Definition: usbmport.h:10
#define USBPORT_TRANSFER_TYPE_ISOCHRONOUS
Definition: usbmport.h:7
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:107

Referenced by USBPORT_MapTransfer().