1 /*
2 * PROJECT: ReactOS USB Port Driver
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: USBPort endpoint functions
5 * COPYRIGHT: Copyright 2017 Vadim Galyant <vgal@rambler.ru>
6 */
7
8 #include "usbport.h"
9
10 #define NDEBUG
11 #include <debug.h>
12
13 #define NDEBUG_USBPORT_CORE
14 #include "usbdebug.h"
15
16 ULONG
17 NTAPI
USBPORT_CalculateUsbBandwidth(IN PDEVICE_OBJECT FdoDevice,IN PUSBPORT_ENDPOINT Endpoint)18 USBPORT_CalculateUsbBandwidth(IN PDEVICE_OBJECT FdoDevice,
19 IN PUSBPORT_ENDPOINT Endpoint)
20 {
21 PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties;
22 ULONG Bandwidth;
23 ULONG Overhead;
24
25 DPRINT("USBPORT_CalculateUsbBandwidth ... \n");
26
27 EndpointProperties = &Endpoint->EndpointProperties;
28
29 switch (EndpointProperties->TransferType)
30 {
31 case USBPORT_TRANSFER_TYPE_ISOCHRONOUS:
32 Overhead = USB2_FS_ISOCHRONOUS_OVERHEAD;
33 break;
34
35 case USBPORT_TRANSFER_TYPE_INTERRUPT:
36 Overhead = USB2_FS_INTERRUPT_OVERHEAD;
37 break;
38
39 default: //USBPORT_TRANSFER_TYPE_CONTROL or USBPORT_TRANSFER_TYPE_BULK
40 Overhead = 0;
41 break;
42 }
43
44 if (Overhead == 0)
45 {
46 Bandwidth = 0;
47 }
48 else
49 {
50 Bandwidth = (EndpointProperties->TotalMaxPacketSize + Overhead) * USB2_BIT_STUFFING_OVERHEAD;
51 }
52
53 if (EndpointProperties->DeviceSpeed == UsbLowSpeed)
54 {
55 Bandwidth *= 8;
56 }
57
58 return Bandwidth;
59 }
60
61 BOOLEAN
62 NTAPI
USBPORT_AllocateBandwidth(IN PDEVICE_OBJECT FdoDevice,IN PUSBPORT_ENDPOINT Endpoint)63 USBPORT_AllocateBandwidth(IN PDEVICE_OBJECT FdoDevice,
64 IN PUSBPORT_ENDPOINT Endpoint)
65 {
66 PUSBPORT_DEVICE_EXTENSION FdoExtension;
67 PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties;
68 ULONG TransferType;
69 ULONG TotalBusBandwidth;
70 ULONG EndpointBandwidth;
71 ULONG MinBandwidth;
72 PULONG Bandwidth;
73 ULONG MaxBandwidth = 0;
74 ULONG ix;
75 ULONG Offset;
76 LONG ScheduleOffset = -1;
77 ULONG Period;
78 ULONG Factor;
79 UCHAR Bit;
80
81 DPRINT("USBPORT_AllocateBandwidth: FdoDevice - %p, Endpoint - %p\n",
82 FdoDevice,
83 Endpoint);
84
85 FdoExtension = FdoDevice->DeviceExtension;
86 EndpointProperties = &Endpoint->EndpointProperties;
87 TransferType = EndpointProperties->TransferType;
88
89 if (TransferType == USBPORT_TRANSFER_TYPE_BULK ||
90 TransferType == USBPORT_TRANSFER_TYPE_CONTROL ||
91 Endpoint->Flags & ENDPOINT_FLAG_ROOTHUB_EP0)
92 {
93 EndpointProperties->ScheduleOffset = 0;
94 return TRUE;
95 }
96
97 TotalBusBandwidth = FdoExtension->TotalBusBandwidth;
98 EndpointBandwidth = EndpointProperties->UsbBandwidth;
99
100 Period = EndpointProperties->Period;
101 ASSERT(Period != 0);
102 Factor = USB2_FRAMES / Period;
103
104 for (Offset = 0; Offset < Period; Offset++)
105 {
106 MinBandwidth = TotalBusBandwidth;
107 Bandwidth = &FdoExtension->Bandwidth[Offset * Factor];
108
109 for (ix = 1; *Bandwidth >= EndpointBandwidth; ix++)
110 {
111 MinBandwidth = min(MinBandwidth, *Bandwidth);
112
113 Bandwidth++;
114
115 if (Factor <= ix)
116 {
117 if (MinBandwidth > MaxBandwidth)
118 {
119 MaxBandwidth = MinBandwidth;
120 ScheduleOffset = Offset;
121
122 DPRINT("USBPORT_AllocateBandwidth: ScheduleOffset - %X\n",
123 ScheduleOffset);
124 }
125
126 break;
127 }
128 }
129 }
130
131 DPRINT("USBPORT_AllocateBandwidth: ScheduleOffset - %X\n", ScheduleOffset);
132
133 if (ScheduleOffset != -1)
134 {
135 EndpointProperties->ScheduleOffset = ScheduleOffset;
136
137 Bandwidth = &FdoExtension->Bandwidth[ScheduleOffset * Factor];
138
139 for (Factor = USB2_FRAMES / Period; Factor; Factor--)
140 {
141 FdoExtension->Bandwidth[ScheduleOffset * Factor] -= EndpointBandwidth;
142 }
143
144 if (TransferType == USBPORT_TRANSFER_TYPE_INTERRUPT)
145 {
146 for (Bit = 0x80; Bit != 0; Bit >>= 1)
147 {
148 if ((Period & Bit) != 0)
149 {
150 Period = Bit;
151 break;
152 }
153 }
154
155 DPRINT("USBPORT_AllocateBandwidth: FIXME AllocatedInterrupt_XXms\n");
156 }
157 else
158 {
159 DPRINT("USBPORT_AllocateBandwidth: FIXME AllocatedIso\n");
160 }
161 }
162
163 DPRINT("USBPORT_AllocateBandwidth: FIXME USBPORT_UpdateAllocatedBw\n");
164
165 DPRINT("USBPORT_AllocateBandwidth: ScheduleOffset - %X\n", ScheduleOffset);
166 return ScheduleOffset != -1;
167 }
168
169 VOID
170 NTAPI
USBPORT_FreeBandwidth(IN PDEVICE_OBJECT FdoDevice,IN PUSBPORT_ENDPOINT Endpoint)171 USBPORT_FreeBandwidth(IN PDEVICE_OBJECT FdoDevice,
172 IN PUSBPORT_ENDPOINT Endpoint)
173 {
174 PUSBPORT_DEVICE_EXTENSION FdoExtension;
175 PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties;
176 ULONG TransferType;
177 ULONG Offset;
178 ULONG EndpointBandwidth;
179 ULONG Period;
180 ULONG Factor;
181 UCHAR Bit;
182
183 DPRINT("USBPORT_FreeBandwidth: FdoDevice - %p, Endpoint - %p\n",
184 FdoDevice,
185 Endpoint);
186
187 FdoExtension = FdoDevice->DeviceExtension;
188
189 EndpointProperties = &Endpoint->EndpointProperties;
190 TransferType = EndpointProperties->TransferType;
191
192 if (TransferType == USBPORT_TRANSFER_TYPE_BULK ||
193 TransferType == USBPORT_TRANSFER_TYPE_CONTROL ||
194 (Endpoint->Flags & ENDPOINT_FLAG_ROOTHUB_EP0))
195 {
196 return;
197 }
198
199 Offset = Endpoint->EndpointProperties.ScheduleOffset;
200 EndpointBandwidth = Endpoint->EndpointProperties.UsbBandwidth;
201
202 Period = Endpoint->EndpointProperties.Period;
203 ASSERT(Period != 0);
204
205 for (Factor = USB2_FRAMES / Period; Factor; Factor--)
206 {
207 FdoExtension->Bandwidth[Offset * Factor] += EndpointBandwidth;
208 }
209
210 if (TransferType == USBPORT_TRANSFER_TYPE_INTERRUPT)
211 {
212 for (Bit = 0x80; Bit != 0; Bit >>= 1)
213 {
214 if ((Period & Bit) != 0)
215 {
216 Period = Bit;
217 break;
218 }
219 }
220
221 ASSERT(Period != 0);
222
223 DPRINT("USBPORT_AllocateBandwidth: FIXME AllocatedInterrupt_XXms\n");
224 }
225 else
226 {
227 DPRINT("USBPORT_AllocateBandwidth: FIXME AllocatedIso\n");
228 }
229
230 DPRINT1("USBPORT_FreeBandwidth: FIXME USBPORT_UpdateAllocatedBw\n");
231 }
232
233 UCHAR
234 NTAPI
USBPORT_NormalizeHsInterval(UCHAR Interval)235 USBPORT_NormalizeHsInterval(UCHAR Interval)
236 {
237 UCHAR interval;
238
239 DPRINT("USBPORT_NormalizeHsInterval: Interval - %x\n", Interval);
240
241 interval = Interval;
242
243 if (Interval)
244 interval = Interval - 1;
245
246 if (interval > 5)
247 interval = 5;
248
249 return 1 << interval;
250 }
251
252 BOOLEAN
253 NTAPI
USBPORT_EndpointHasQueuedTransfers(IN PDEVICE_OBJECT FdoDevice,IN PUSBPORT_ENDPOINT Endpoint,IN PULONG TransferCount)254 USBPORT_EndpointHasQueuedTransfers(IN PDEVICE_OBJECT FdoDevice,
255 IN PUSBPORT_ENDPOINT Endpoint,
256 IN PULONG TransferCount)
257 {
258 PLIST_ENTRY Entry;
259 PUSBPORT_TRANSFER Transfer;
260 BOOLEAN Result = FALSE;
261
262 DPRINT_CORE("USBPORT_EndpointHasQueuedTransfers: ... \n");
263
264 KeAcquireSpinLock(&Endpoint->EndpointSpinLock, &Endpoint->EndpointOldIrql);
265
266 if (!IsListEmpty(&Endpoint->PendingTransferList))
267 Result = TRUE;
268
269 if (!IsListEmpty(&Endpoint->TransferList))
270 {
271 Result = TRUE;
272
273 if (TransferCount)
274 {
275 *TransferCount = 0;
276
277 for (Entry = Endpoint->TransferList.Flink;
278 Entry && Entry != &Endpoint->TransferList;
279 Entry = Transfer->TransferLink.Flink)
280 {
281 Transfer = CONTAINING_RECORD(Entry,
282 USBPORT_TRANSFER,
283 TransferLink);
284
285 if (Transfer->Flags & TRANSFER_FLAG_SUBMITED)
286 {
287 ++*TransferCount;
288 }
289 }
290 }
291 }
292
293 KeReleaseSpinLock(&Endpoint->EndpointSpinLock, Endpoint->EndpointOldIrql);
294
295 return Result;
296 }
297
298 VOID
299 NTAPI
USBPORT_NukeAllEndpoints(IN PDEVICE_OBJECT FdoDevice)300 USBPORT_NukeAllEndpoints(IN PDEVICE_OBJECT FdoDevice)
301 {
302 PUSBPORT_DEVICE_EXTENSION FdoExtension;
303 PLIST_ENTRY EndpointList;
304 PUSBPORT_ENDPOINT Endpoint;
305 KIRQL OldIrql;
306
307 DPRINT("USBPORT_NukeAllEndpoints \n");
308
309 FdoExtension = FdoDevice->DeviceExtension;
310
311 KeAcquireSpinLock(&FdoExtension->EndpointListSpinLock, &OldIrql);
312
313 EndpointList = FdoExtension->EndpointList.Flink;
314
315 while (EndpointList && (EndpointList != &FdoExtension->EndpointList))
316 {
317 Endpoint = CONTAINING_RECORD(EndpointList,
318 USBPORT_ENDPOINT,
319 EndpointLink);
320
321 if (!(Endpoint->Flags & ENDPOINT_FLAG_ROOTHUB_EP0))
322 Endpoint->Flags |= ENDPOINT_FLAG_NUKE;
323
324 EndpointList = Endpoint->EndpointLink.Flink;
325 }
326
327 KeReleaseSpinLock(&FdoExtension->EndpointListSpinLock, OldIrql);
328 }
329
330 ULONG
331 NTAPI
USBPORT_GetEndpointState(IN PUSBPORT_ENDPOINT Endpoint)332 USBPORT_GetEndpointState(IN PUSBPORT_ENDPOINT Endpoint)
333 {
334 ULONG State;
335
336 //DPRINT("USBPORT_GetEndpointState \n");
337
338 KeAcquireSpinLockAtDpcLevel(&Endpoint->StateChangeSpinLock);
339
340 if (Endpoint->StateLast != Endpoint->StateNext)
341 {
342 State = USBPORT_ENDPOINT_UNKNOWN;
343 }
344 else
345 {
346 State = Endpoint->StateLast;
347 }
348
349 KeReleaseSpinLockFromDpcLevel(&Endpoint->StateChangeSpinLock);
350
351 if (State != USBPORT_ENDPOINT_ACTIVE)
352 {
353 DPRINT("USBPORT_GetEndpointState: Endpoint - %p, State - %x\n",
354 Endpoint,
355 State);
356 }
357
358 return State;
359 }
360
361 VOID
362 NTAPI
USBPORT_SetEndpointState(IN PUSBPORT_ENDPOINT Endpoint,IN ULONG State)363 USBPORT_SetEndpointState(IN PUSBPORT_ENDPOINT Endpoint,
364 IN ULONG State)
365 {
366 PDEVICE_OBJECT FdoDevice;
367 PUSBPORT_DEVICE_EXTENSION FdoExtension;
368 PUSBPORT_REGISTRATION_PACKET Packet;
369 KIRQL OldIrql;
370
371 DPRINT("USBPORT_SetEndpointState: Endpoint - %p, State - %x\n",
372 Endpoint,
373 State);
374
375 FdoDevice = Endpoint->FdoDevice;
376 FdoExtension = FdoDevice->DeviceExtension;
377 Packet = &FdoExtension->MiniPortInterface->Packet;
378
379 KeAcquireSpinLock(&Endpoint->StateChangeSpinLock,
380 &Endpoint->EndpointStateOldIrql);
381
382 if (!(Endpoint->Flags & ENDPOINT_FLAG_ROOTHUB_EP0))
383 {
384 if (Endpoint->Flags & ENDPOINT_FLAG_NUKE)
385 {
386 Endpoint->StateLast = State;
387 Endpoint->StateNext = State;
388
389 KeReleaseSpinLock(&Endpoint->StateChangeSpinLock,
390 Endpoint->EndpointStateOldIrql);
391
392 USBPORT_InvalidateEndpointHandler(FdoDevice,
393 Endpoint,
394 INVALIDATE_ENDPOINT_WORKER_THREAD);
395 return;
396 }
397
398 KeReleaseSpinLock(&Endpoint->StateChangeSpinLock,
399 Endpoint->EndpointStateOldIrql);
400
401 KeAcquireSpinLock(&FdoExtension->MiniportSpinLock, &OldIrql);
402 Packet->SetEndpointState(FdoExtension->MiniPortExt,
403 Endpoint + 1,
404 State);
405 KeReleaseSpinLock(&FdoExtension->MiniportSpinLock, OldIrql);
406
407 Endpoint->StateNext = State;
408
409 KeAcquireSpinLock(&FdoExtension->MiniportSpinLock, &OldIrql);
410 Endpoint->FrameNumber = Packet->Get32BitFrameNumber(FdoExtension->MiniPortExt);
411 KeReleaseSpinLock(&FdoExtension->MiniportSpinLock, OldIrql);
412
413 ExInterlockedInsertTailList(&FdoExtension->EpStateChangeList,
414 &Endpoint->StateChangeLink,
415 &FdoExtension->EpStateChangeSpinLock);
416
417 KeAcquireSpinLock(&FdoExtension->MiniportSpinLock, &OldIrql);
418 Packet->InterruptNextSOF(FdoExtension->MiniPortExt);
419 KeReleaseSpinLock(&FdoExtension->MiniportSpinLock, OldIrql);
420 }
421 else
422 {
423 Endpoint->StateLast = State;
424 Endpoint->StateNext = State;
425
426 if (State == USBPORT_ENDPOINT_REMOVE)
427 {
428 KeReleaseSpinLock(&Endpoint->StateChangeSpinLock,
429 Endpoint->EndpointStateOldIrql);
430
431 USBPORT_InvalidateEndpointHandler(FdoDevice,
432 Endpoint,
433 INVALIDATE_ENDPOINT_WORKER_THREAD);
434 return;
435 }
436
437 KeReleaseSpinLock(&Endpoint->StateChangeSpinLock,
438 Endpoint->EndpointStateOldIrql);
439 }
440 }
441
442 VOID
443 NTAPI
USBPORT_AddPipeHandle(IN PUSBPORT_DEVICE_HANDLE DeviceHandle,IN PUSBPORT_PIPE_HANDLE PipeHandle)444 USBPORT_AddPipeHandle(IN PUSBPORT_DEVICE_HANDLE DeviceHandle,
445 IN PUSBPORT_PIPE_HANDLE PipeHandle)
446 {
447 DPRINT("USBPORT_AddPipeHandle: DeviceHandle - %p, PipeHandle - %p\n",
448 DeviceHandle,
449 PipeHandle);
450
451 InsertTailList(&DeviceHandle->PipeHandleList, &PipeHandle->PipeLink);
452 }
453
454 VOID
455 NTAPI
USBPORT_RemovePipeHandle(IN PUSBPORT_DEVICE_HANDLE DeviceHandle,IN PUSBPORT_PIPE_HANDLE PipeHandle)456 USBPORT_RemovePipeHandle(IN PUSBPORT_DEVICE_HANDLE DeviceHandle,
457 IN PUSBPORT_PIPE_HANDLE PipeHandle)
458 {
459 DPRINT("USBPORT_RemovePipeHandle: PipeHandle - %p\n", PipeHandle);
460
461 RemoveEntryList(&PipeHandle->PipeLink);
462
463 PipeHandle->PipeLink.Flink = NULL;
464 PipeHandle->PipeLink.Blink = NULL;
465 }
466
467 BOOLEAN
468 NTAPI
USBPORT_ValidatePipeHandle(IN PUSBPORT_DEVICE_HANDLE DeviceHandle,IN PUSBPORT_PIPE_HANDLE PipeHandle)469 USBPORT_ValidatePipeHandle(IN PUSBPORT_DEVICE_HANDLE DeviceHandle,
470 IN PUSBPORT_PIPE_HANDLE PipeHandle)
471 {
472 PLIST_ENTRY HandleList;
473 PUSBPORT_PIPE_HANDLE CurrentHandle;
474
475 //DPRINT("USBPORT_ValidatePipeHandle: DeviceHandle - %p, PipeHandle - %p\n",
476 // DeviceHandle,
477 // PipeHandle);
478
479 HandleList = DeviceHandle->PipeHandleList.Flink;
480
481 while (HandleList != &DeviceHandle->PipeHandleList)
482 {
483 CurrentHandle = CONTAINING_RECORD(HandleList,
484 USBPORT_PIPE_HANDLE,
485 PipeLink);
486
487 HandleList = HandleList->Flink;
488
489 if (CurrentHandle == PipeHandle)
490 return TRUE;
491 }
492
493 return FALSE;
494 }
495
496 BOOLEAN
497 NTAPI
USBPORT_DeleteEndpoint(IN PDEVICE_OBJECT FdoDevice,IN PUSBPORT_ENDPOINT Endpoint)498 USBPORT_DeleteEndpoint(IN PDEVICE_OBJECT FdoDevice,
499 IN PUSBPORT_ENDPOINT Endpoint)
500 {
501 PUSBPORT_DEVICE_EXTENSION FdoExtension;
502 BOOLEAN Result;
503 KIRQL OldIrql;
504
505 DPRINT1("USBPORT_DeleteEndpoint: Endpoint - %p\n", Endpoint);
506
507 FdoExtension = FdoDevice->DeviceExtension;
508
509 if ((Endpoint->WorkerLink.Flink && Endpoint->WorkerLink.Blink) ||
510 Endpoint->LockCounter != -1)
511 {
512 KeAcquireSpinLock(&FdoExtension->EndpointListSpinLock, &OldIrql);
513
514 ExInterlockedInsertTailList(&FdoExtension->EndpointClosedList,
515 &Endpoint->CloseLink,
516 &FdoExtension->EndpointClosedSpinLock);
517
518 KeReleaseSpinLock(&FdoExtension->EndpointListSpinLock, OldIrql);
519
520 Result = FALSE;
521 }
522 else
523 {
524 KeAcquireSpinLock(&FdoExtension->EndpointListSpinLock, &OldIrql);
525
526 RemoveEntryList(&Endpoint->EndpointLink);
527 Endpoint->EndpointLink.Flink = NULL;
528 Endpoint->EndpointLink.Blink = NULL;
529
530 KeReleaseSpinLock(&FdoExtension->EndpointListSpinLock, OldIrql);
531
532 MiniportCloseEndpoint(FdoDevice, Endpoint);
533
534 if (Endpoint->HeaderBuffer)
535 {
536 USBPORT_FreeCommonBuffer(FdoDevice, Endpoint->HeaderBuffer);
537 }
538
539 ExFreePoolWithTag(Endpoint, USB_PORT_TAG);
540
541 Result = TRUE;
542 }
543
544 return Result;
545 }
546
547 VOID
548 NTAPI
MiniportCloseEndpoint(IN PDEVICE_OBJECT FdoDevice,IN PUSBPORT_ENDPOINT Endpoint)549 MiniportCloseEndpoint(IN PDEVICE_OBJECT FdoDevice,
550 IN PUSBPORT_ENDPOINT Endpoint)
551 {
552 PUSBPORT_DEVICE_EXTENSION FdoExtension;
553 PUSBPORT_REGISTRATION_PACKET Packet;
554 BOOLEAN IsDoDisablePeriodic;
555 ULONG TransferType;
556 KIRQL OldIrql;
557
558 DPRINT("MiniportCloseEndpoint: Endpoint - %p\n", Endpoint);
559
560 FdoExtension = FdoDevice->DeviceExtension;
561 Packet = &FdoExtension->MiniPortInterface->Packet;
562
563 KeAcquireSpinLock(&FdoExtension->MiniportSpinLock, &OldIrql);
564
565 if (Endpoint->Flags & ENDPOINT_FLAG_OPENED)
566 {
567 TransferType = Endpoint->EndpointProperties.TransferType;
568
569 if (TransferType == USBPORT_TRANSFER_TYPE_INTERRUPT ||
570 TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS)
571 {
572 --FdoExtension->PeriodicEndpoints;
573 }
574
575 IsDoDisablePeriodic = FdoExtension->PeriodicEndpoints == 0;
576
577 Packet->CloseEndpoint(FdoExtension->MiniPortExt,
578 Endpoint + 1,
579 IsDoDisablePeriodic);
580
581 Endpoint->Flags &= ~ENDPOINT_FLAG_OPENED;
582 Endpoint->Flags |= ENDPOINT_FLAG_CLOSED;
583 }
584
585 KeReleaseSpinLock(&FdoExtension->MiniportSpinLock, OldIrql);
586 }
587
588 VOID
589 NTAPI
USBPORT_ClosePipe(IN PUSBPORT_DEVICE_HANDLE DeviceHandle,IN PDEVICE_OBJECT FdoDevice,IN PUSBPORT_PIPE_HANDLE PipeHandle)590 USBPORT_ClosePipe(IN PUSBPORT_DEVICE_HANDLE DeviceHandle,
591 IN PDEVICE_OBJECT FdoDevice,
592 IN PUSBPORT_PIPE_HANDLE PipeHandle)
593 {
594 PUSBPORT_DEVICE_EXTENSION FdoExtension;
595 PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
596 PUSBPORT_ENDPOINT Endpoint;
597 PUSBPORT_REGISTRATION_PACKET Packet;
598 PUSB2_TT_EXTENSION TtExtension;
599 ULONG ix;
600 BOOLEAN IsReady;
601 KIRQL OldIrql;
602
603 DPRINT1("USBPORT_ClosePipe \n");
604
605 FdoExtension = FdoDevice->DeviceExtension;
606
607 if (PipeHandle->Flags & PIPE_HANDLE_FLAG_CLOSED)
608 return;
609
610 USBPORT_RemovePipeHandle(DeviceHandle, PipeHandle);
611
612 PipeHandle->Flags |= PIPE_HANDLE_FLAG_CLOSED;
613
614 if (PipeHandle->Flags & PIPE_HANDLE_FLAG_NULL_PACKET_SIZE)
615 {
616 PipeHandle->Flags &= ~PIPE_HANDLE_FLAG_NULL_PACKET_SIZE;
617 return;
618 }
619
620 Endpoint = PipeHandle->Endpoint;
621
622 KeAcquireSpinLock(&FdoExtension->EndpointListSpinLock, &OldIrql);
623
624 if ((Endpoint->Flags & ENDPOINT_FLAG_ROOTHUB_EP0) &&
625 (Endpoint->EndpointProperties.TransferType == USBPORT_TRANSFER_TYPE_INTERRUPT))
626 {
627 PdoExtension = FdoExtension->RootHubPdo->DeviceExtension;
628 PdoExtension->Endpoint = NULL;
629 }
630
631 KeReleaseSpinLock(&FdoExtension->EndpointListSpinLock, OldIrql);
632
633 while (TRUE)
634 {
635 IsReady = TRUE;
636
637 KeAcquireSpinLock(&Endpoint->EndpointSpinLock,
638 &Endpoint->EndpointOldIrql);
639
640 if (!IsListEmpty(&Endpoint->PendingTransferList))
641 IsReady = FALSE;
642
643 if (!IsListEmpty(&Endpoint->TransferList))
644 IsReady = FALSE;
645
646 if (!IsListEmpty(&Endpoint->CancelList))
647 IsReady = FALSE;
648
649 if (!IsListEmpty(&Endpoint->AbortList))
650 IsReady = FALSE;
651
652 KeAcquireSpinLockAtDpcLevel(&Endpoint->StateChangeSpinLock);
653 if (Endpoint->StateLast != Endpoint->StateNext)
654 IsReady = FALSE;
655 KeReleaseSpinLockFromDpcLevel(&Endpoint->StateChangeSpinLock);
656
657 KeReleaseSpinLock(&Endpoint->EndpointSpinLock,
658 Endpoint->EndpointOldIrql);
659
660 if (InterlockedIncrement(&Endpoint->LockCounter))
661 IsReady = FALSE;
662 InterlockedDecrement(&Endpoint->LockCounter);
663
664 if (IsReady == TRUE)
665 break;
666
667 USBPORT_Wait(FdoDevice, 1);
668 }
669
670 Endpoint->DeviceHandle = NULL;
671 Packet = &FdoExtension->MiniPortInterface->Packet;
672
673 if (Packet->MiniPortFlags & USB_MINIPORT_FLAGS_USB2)
674 {
675 USBPORT_FreeBandwidthUSB2(FdoDevice, Endpoint);
676
677 KeAcquireSpinLock(&FdoExtension->TtSpinLock, &OldIrql);
678
679 TtExtension = Endpoint->TtExtension;
680 DPRINT1("USBPORT_ClosePipe: TtExtension - %p\n", TtExtension);
681
682 if (TtExtension)
683 {
684 RemoveEntryList(&Endpoint->TtLink);
685
686 Endpoint->TtLink.Flink = NULL;
687 Endpoint->TtLink.Blink = NULL;
688
689 if (TtExtension->Flags & USB2_TT_EXTENSION_FLAG_DELETED)
690 {
691 if (IsListEmpty(&TtExtension->EndpointList))
692 {
693 USBPORT_UpdateAllocatedBwTt(TtExtension);
694
695 for (ix = 0; ix < USB2_FRAMES; ix++)
696 {
697 FdoExtension->Bandwidth[ix] += TtExtension->MaxBandwidth;
698 }
699
700 DPRINT1("USBPORT_ClosePipe: ExFreePoolWithTag TtExtension - %p\n", TtExtension);
701 ExFreePoolWithTag(TtExtension, USB_PORT_TAG);
702 }
703 }
704 }
705
706 KeReleaseSpinLock(&FdoExtension->TtSpinLock, OldIrql);
707 }
708 else
709 {
710 USBPORT_FreeBandwidth(FdoDevice, Endpoint);
711 }
712
713 KeAcquireSpinLock(&Endpoint->EndpointSpinLock, &Endpoint->EndpointOldIrql);
714 USBPORT_SetEndpointState(Endpoint, USBPORT_ENDPOINT_REMOVE);
715 KeReleaseSpinLock(&Endpoint->EndpointSpinLock, Endpoint->EndpointOldIrql);
716
717 USBPORT_SignalWorkerThread(FdoDevice);
718 }
719
720 MPSTATUS
721 NTAPI
MiniportOpenEndpoint(IN PDEVICE_OBJECT FdoDevice,IN PUSBPORT_ENDPOINT Endpoint)722 MiniportOpenEndpoint(IN PDEVICE_OBJECT FdoDevice,
723 IN PUSBPORT_ENDPOINT Endpoint)
724 {
725 PUSBPORT_DEVICE_EXTENSION FdoExtension;
726 PUSBPORT_REGISTRATION_PACKET Packet;
727 KIRQL OldIrql;
728 ULONG TransferType;
729 MPSTATUS MpStatus;
730
731 DPRINT("MiniportOpenEndpoint: Endpoint - %p\n", Endpoint);
732
733 FdoExtension = FdoDevice->DeviceExtension;
734 Packet = &FdoExtension->MiniPortInterface->Packet;
735
736 KeAcquireSpinLock(&FdoExtension->MiniportSpinLock, &OldIrql);
737
738 Endpoint->Flags &= ~ENDPOINT_FLAG_CLOSED;
739
740 MpStatus = Packet->OpenEndpoint(FdoExtension->MiniPortExt,
741 &Endpoint->EndpointProperties,
742 Endpoint + 1);
743
744 if (!MpStatus)
745 {
746 TransferType = Endpoint->EndpointProperties.TransferType;
747
748 if (TransferType == USBPORT_TRANSFER_TYPE_INTERRUPT ||
749 TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS)
750 {
751 ++FdoExtension->PeriodicEndpoints;
752 }
753
754 Endpoint->Flags |= ENDPOINT_FLAG_OPENED;
755 }
756
757 KeReleaseSpinLock(&FdoExtension->MiniportSpinLock, OldIrql);
758 return MpStatus;
759 }
760
761 NTSTATUS
762 NTAPI
USBPORT_OpenPipe(IN PDEVICE_OBJECT FdoDevice,IN PUSBPORT_DEVICE_HANDLE DeviceHandle,IN PUSBPORT_PIPE_HANDLE PipeHandle,IN OUT PUSBD_STATUS UsbdStatus)763 USBPORT_OpenPipe(IN PDEVICE_OBJECT FdoDevice,
764 IN PUSBPORT_DEVICE_HANDLE DeviceHandle,
765 IN PUSBPORT_PIPE_HANDLE PipeHandle,
766 IN OUT PUSBD_STATUS UsbdStatus)
767 {
768 PUSBPORT_DEVICE_EXTENSION FdoExtension;
769 PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
770 PUSBPORT_REGISTRATION_PACKET Packet;
771 SIZE_T EndpointSize;
772 PUSBPORT_ENDPOINT Endpoint;
773 PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties;
774 PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
775 UCHAR Direction;
776 UCHAR Interval;
777 UCHAR Period;
778 USBPORT_ENDPOINT_REQUIREMENTS EndpointRequirements = {0};
779 PUSBPORT_COMMON_BUFFER_HEADER HeaderBuffer;
780 MPSTATUS MpStatus;
781 USBD_STATUS USBDStatus;
782 NTSTATUS Status;
783 KIRQL OldIrql;
784 USHORT MaxPacketSize;
785 USHORT AdditionalTransaction;
786 BOOLEAN IsAllocatedBandwidth;
787
788 DPRINT1("USBPORT_OpenPipe: DeviceHandle - %p, FdoDevice - %p, PipeHandle - %p\n",
789 DeviceHandle,
790 FdoDevice,
791 PipeHandle);
792
793 FdoExtension = FdoDevice->DeviceExtension;
794 Packet = &FdoExtension->MiniPortInterface->Packet;
795
796 EndpointSize = sizeof(USBPORT_ENDPOINT) + Packet->MiniPortEndpointSize;
797
798 if (Packet->MiniPortFlags & USB_MINIPORT_FLAGS_USB2)
799 {
800 EndpointSize += sizeof(USB2_TT_ENDPOINT);
801 }
802
803 if (PipeHandle->EndpointDescriptor.wMaxPacketSize == 0)
804 {
805 USBPORT_AddPipeHandle(DeviceHandle, PipeHandle);
806
807 PipeHandle->Flags = (PipeHandle->Flags & ~PIPE_HANDLE_FLAG_CLOSED) |
808 PIPE_HANDLE_FLAG_NULL_PACKET_SIZE;
809
810 PipeHandle->Endpoint = (PUSBPORT_ENDPOINT)-1;
811
812 return STATUS_SUCCESS;
813 }
814
815 Endpoint = ExAllocatePoolWithTag(NonPagedPool, EndpointSize, USB_PORT_TAG);
816
817 if (!Endpoint)
818 {
819 DPRINT1("USBPORT_OpenPipe: Not allocated Endpoint!\n");
820 Status = STATUS_INSUFFICIENT_RESOURCES;
821 return Status;
822 }
823
824 RtlZeroMemory(Endpoint, EndpointSize);
825
826 Endpoint->FdoDevice = FdoDevice;
827 Endpoint->DeviceHandle = DeviceHandle;
828 Endpoint->LockCounter = -1;
829
830 Endpoint->TtExtension = DeviceHandle->TtExtension;
831
832 if (DeviceHandle->TtExtension)
833 {
834 ExInterlockedInsertTailList(&DeviceHandle->TtExtension->EndpointList,
835 &Endpoint->TtLink,
836 &FdoExtension->TtSpinLock);
837 }
838
839 if (Packet->MiniPortFlags & USB_MINIPORT_FLAGS_USB2)
840 {
841 Endpoint->TtEndpoint = (PUSB2_TT_ENDPOINT)((ULONG_PTR)Endpoint +
842 sizeof(USBPORT_ENDPOINT) +
843 Packet->MiniPortEndpointSize);
844 }
845 else
846 {
847 Endpoint->TtEndpoint = NULL;
848 }
849
850 KeInitializeSpinLock(&Endpoint->EndpointSpinLock);
851 KeInitializeSpinLock(&Endpoint->StateChangeSpinLock);
852
853 InitializeListHead(&Endpoint->PendingTransferList);
854 InitializeListHead(&Endpoint->TransferList);
855 InitializeListHead(&Endpoint->CancelList);
856 InitializeListHead(&Endpoint->AbortList);
857
858 EndpointProperties = &Endpoint->EndpointProperties;
859 EndpointDescriptor = &PipeHandle->EndpointDescriptor;
860
861 MaxPacketSize = EndpointDescriptor->wMaxPacketSize & 0x7FF;
862 AdditionalTransaction = (EndpointDescriptor->wMaxPacketSize >> 11) & 3;
863
864 EndpointProperties->DeviceAddress = DeviceHandle->DeviceAddress;
865 EndpointProperties->DeviceSpeed = DeviceHandle->DeviceSpeed;
866 EndpointProperties->Period = 0;
867 EndpointProperties->EndpointAddress = EndpointDescriptor->bEndpointAddress;
868 EndpointProperties->TransactionPerMicroframe = AdditionalTransaction + 1;
869 EndpointProperties->MaxPacketSize = MaxPacketSize;
870 EndpointProperties->TotalMaxPacketSize = MaxPacketSize *
871 (AdditionalTransaction + 1);
872
873 if (Endpoint->TtExtension)
874 {
875 EndpointProperties->HubAddr = Endpoint->TtExtension->DeviceAddress;
876 }
877 else
878 {
879 EndpointProperties->HubAddr = -1;
880 }
881
882 EndpointProperties->PortNumber = DeviceHandle->PortNumber;
883
884 switch (EndpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK)
885 {
886 case USB_ENDPOINT_TYPE_CONTROL:
887 EndpointProperties->TransferType = USBPORT_TRANSFER_TYPE_CONTROL;
888
889 if (EndpointProperties->EndpointAddress == 0)
890 {
891 EndpointProperties->MaxTransferSize = 0x1000; // OUT Ep0
892 }
893 else
894 {
895 EndpointProperties->MaxTransferSize = 0x10000;
896 }
897
898 break;
899
900 case USB_ENDPOINT_TYPE_ISOCHRONOUS:
901 DPRINT1("USBPORT_OpenPipe: USB_ENDPOINT_TYPE_ISOCHRONOUS UNIMPLEMENTED. FIXME. \n");
902 EndpointProperties->TransferType = USBPORT_TRANSFER_TYPE_ISOCHRONOUS;
903 EndpointProperties->MaxTransferSize = 0x1000000;
904 break;
905
906 case USB_ENDPOINT_TYPE_BULK:
907 EndpointProperties->TransferType = USBPORT_TRANSFER_TYPE_BULK;
908 EndpointProperties->MaxTransferSize = 0x10000;
909 break;
910
911 case USB_ENDPOINT_TYPE_INTERRUPT:
912 EndpointProperties->TransferType = USBPORT_TRANSFER_TYPE_INTERRUPT;
913 EndpointProperties->MaxTransferSize = 0x400;
914 break;
915 }
916
917 if (EndpointProperties->TransferType == USBPORT_TRANSFER_TYPE_INTERRUPT)
918 {
919 if (EndpointProperties->DeviceSpeed == UsbHighSpeed)
920 {
921 Interval = USBPORT_NormalizeHsInterval(EndpointDescriptor->bInterval);
922 }
923 else
924 {
925 Interval = EndpointDescriptor->bInterval;
926 }
927
928 EndpointProperties->Period = ENDPOINT_INTERRUPT_32ms;
929
930 if (Interval && (Interval < USB2_FRAMES))
931 {
932 if ((EndpointProperties->DeviceSpeed != UsbLowSpeed) ||
933 (Interval >= ENDPOINT_INTERRUPT_8ms))
934 {
935 if (!(Interval & ENDPOINT_INTERRUPT_32ms))
936 {
937 Period = EndpointProperties->Period;
938
939 do
940 {
941 Period >>= 1;
942 }
943 while (!(Period & Interval));
944
945 EndpointProperties->Period = Period;
946 }
947 }
948 else
949 {
950 EndpointProperties->Period = ENDPOINT_INTERRUPT_8ms;
951 }
952 }
953 }
954
955 if (EndpointProperties->TransferType == USB_ENDPOINT_TYPE_ISOCHRONOUS)
956 {
957 if (EndpointProperties->DeviceSpeed == UsbHighSpeed)
958 {
959 EndpointProperties->Period =
960 USBPORT_NormalizeHsInterval(EndpointDescriptor->bInterval);
961 }
962 else
963 {
964 EndpointProperties->Period = ENDPOINT_INTERRUPT_1ms;
965 }
966 }
967
968 if ((DeviceHandle->Flags & DEVICE_HANDLE_FLAG_ROOTHUB) != 0)
969 {
970 Endpoint->Flags |= ENDPOINT_FLAG_ROOTHUB_EP0;
971 }
972
973 if (Packet->MiniPortFlags & USB_MINIPORT_FLAGS_USB2)
974 {
975 IsAllocatedBandwidth = USBPORT_AllocateBandwidthUSB2(FdoDevice, Endpoint);
976 }
977 else
978 {
979 EndpointProperties->UsbBandwidth = USBPORT_CalculateUsbBandwidth(FdoDevice,
980 Endpoint);
981
982 IsAllocatedBandwidth = USBPORT_AllocateBandwidth(FdoDevice, Endpoint);
983 }
984
985 if (!IsAllocatedBandwidth)
986 {
987 Status = USBPORT_USBDStatusToNtStatus(NULL, USBD_STATUS_NO_BANDWIDTH);
988
989 if (UsbdStatus)
990 {
991 *UsbdStatus = USBD_STATUS_NO_BANDWIDTH;
992 }
993
994 goto ExitWithError;
995 }
996
997 Direction = USB_ENDPOINT_DIRECTION_OUT(EndpointDescriptor->bEndpointAddress);
998 EndpointProperties->Direction = Direction;
999
1000 if (DeviceHandle->IsRootHub)
1001 {
1002 Endpoint->EndpointWorker = 0; // USBPORT_RootHubEndpointWorker;
1003
1004 Endpoint->Flags |= ENDPOINT_FLAG_ROOTHUB_EP0;
1005
1006 Endpoint->StateLast = USBPORT_ENDPOINT_ACTIVE;
1007 Endpoint->StateNext = USBPORT_ENDPOINT_ACTIVE;
1008
1009 PdoExtension = FdoExtension->RootHubPdo->DeviceExtension;
1010
1011 if (EndpointProperties->TransferType == USBPORT_TRANSFER_TYPE_INTERRUPT)
1012 {
1013 PdoExtension->Endpoint = Endpoint;
1014 }
1015
1016 USBDStatus = USBD_STATUS_SUCCESS;
1017 }
1018 else
1019 {
1020 Endpoint->EndpointWorker = 1; // USBPORT_DmaEndpointWorker;
1021
1022 KeAcquireSpinLock(&FdoExtension->MiniportSpinLock, &OldIrql);
1023
1024 Packet->QueryEndpointRequirements(FdoExtension->MiniPortExt,
1025 &Endpoint->EndpointProperties,
1026 &EndpointRequirements);
1027
1028 KeReleaseSpinLock(&FdoExtension->MiniportSpinLock, OldIrql);
1029
1030 if ((EndpointProperties->TransferType == USBPORT_TRANSFER_TYPE_BULK) ||
1031 (EndpointProperties->TransferType == USBPORT_TRANSFER_TYPE_INTERRUPT))
1032 {
1033 EndpointProperties->MaxTransferSize = EndpointRequirements.MaxTransferSize;
1034 }
1035
1036 if (EndpointRequirements.HeaderBufferSize)
1037 {
1038 HeaderBuffer = USBPORT_AllocateCommonBuffer(FdoDevice,
1039 EndpointRequirements.HeaderBufferSize);
1040 }
1041 else
1042 {
1043 HeaderBuffer = NULL;
1044 }
1045
1046 if (HeaderBuffer || (EndpointRequirements.HeaderBufferSize == 0))
1047 {
1048 Endpoint->HeaderBuffer = HeaderBuffer;
1049
1050 if (HeaderBuffer)
1051 {
1052 EndpointProperties->BufferVA = HeaderBuffer->VirtualAddress;
1053 EndpointProperties->BufferPA = HeaderBuffer->PhysicalAddress;
1054 EndpointProperties->BufferLength = HeaderBuffer->BufferLength; // BufferLength + LengthPadded;
1055 }
1056
1057 MpStatus = MiniportOpenEndpoint(FdoDevice, Endpoint);
1058
1059 Endpoint->Flags |= ENDPOINT_FLAG_DMA_TYPE;
1060 Endpoint->Flags |= ENDPOINT_FLAG_QUEUENE_EMPTY;
1061
1062 if (MpStatus == 0)
1063 {
1064 ULONG State;
1065
1066 KeAcquireSpinLock(&Endpoint->EndpointSpinLock,
1067 &Endpoint->EndpointOldIrql);
1068
1069 Endpoint->StateLast = USBPORT_ENDPOINT_PAUSED;
1070 Endpoint->StateNext = USBPORT_ENDPOINT_PAUSED;
1071
1072 USBPORT_SetEndpointState(Endpoint, USBPORT_ENDPOINT_ACTIVE);
1073
1074 KeReleaseSpinLock(&Endpoint->EndpointSpinLock,
1075 Endpoint->EndpointOldIrql);
1076
1077 while (TRUE)
1078 {
1079 KeAcquireSpinLock(&Endpoint->EndpointSpinLock,
1080 &Endpoint->EndpointOldIrql);
1081
1082 State = USBPORT_GetEndpointState(Endpoint);
1083
1084 KeReleaseSpinLock(&Endpoint->EndpointSpinLock,
1085 Endpoint->EndpointOldIrql);
1086
1087 if (State == USBPORT_ENDPOINT_ACTIVE)
1088 {
1089 break;
1090 }
1091
1092 USBPORT_Wait(FdoDevice, 1); // 1 msec.
1093 }
1094 }
1095 }
1096 else
1097 {
1098 MpStatus = MP_STATUS_NO_RESOURCES;
1099 Endpoint->HeaderBuffer = NULL;
1100 }
1101
1102 if (MpStatus)
1103 {
1104 USBDStatus = USBD_STATUS_INSUFFICIENT_RESOURCES;
1105 }
1106 else
1107 {
1108 USBDStatus = USBD_STATUS_SUCCESS;
1109 }
1110 }
1111
1112 if (UsbdStatus)
1113 {
1114 *UsbdStatus = USBDStatus;
1115 }
1116
1117 Status = USBPORT_USBDStatusToNtStatus(NULL, USBDStatus);
1118
1119 if (NT_SUCCESS(Status))
1120 {
1121 USBPORT_AddPipeHandle(DeviceHandle, PipeHandle);
1122
1123 ExInterlockedInsertTailList(&FdoExtension->EndpointList,
1124 &Endpoint->EndpointLink,
1125 &FdoExtension->EndpointListSpinLock);
1126
1127 PipeHandle->Endpoint = Endpoint;
1128 PipeHandle->Flags &= ~PIPE_HANDLE_FLAG_CLOSED;
1129
1130 return Status;
1131 }
1132
1133 ExitWithError:
1134
1135 if (Endpoint)
1136 {
1137 if (IsAllocatedBandwidth)
1138 {
1139 if (Packet->MiniPortFlags & USB_MINIPORT_FLAGS_USB2)
1140 {
1141 USBPORT_FreeBandwidthUSB2(FdoDevice, Endpoint);
1142 }
1143 else
1144 {
1145 USBPORT_FreeBandwidth(FdoDevice, Endpoint);
1146 }
1147 }
1148
1149 if (Endpoint->TtExtension)
1150 {
1151 KeAcquireSpinLock(&FdoExtension->TtSpinLock, &OldIrql);
1152 RemoveEntryList(&Endpoint->TtLink);
1153 KeReleaseSpinLock(&FdoExtension->TtSpinLock, OldIrql);
1154 }
1155
1156 ExFreePoolWithTag(Endpoint, USB_PORT_TAG);
1157 }
1158
1159 DPRINT1("USBPORT_OpenPipe: Status - %lx\n", Status);
1160 return Status;
1161 }
1162
1163 NTSTATUS
1164 NTAPI
USBPORT_ReopenPipe(IN PDEVICE_OBJECT FdoDevice,IN PUSBPORT_ENDPOINT Endpoint)1165 USBPORT_ReopenPipe(IN PDEVICE_OBJECT FdoDevice,
1166 IN PUSBPORT_ENDPOINT Endpoint)
1167 {
1168 PUSBPORT_DEVICE_EXTENSION FdoExtension;
1169 PUSBPORT_COMMON_BUFFER_HEADER HeaderBuffer;
1170 USBPORT_ENDPOINT_REQUIREMENTS EndpointRequirements = {0};
1171 PUSBPORT_REGISTRATION_PACKET Packet;
1172 KIRQL MiniportOldIrql;
1173 NTSTATUS Status;
1174
1175 DPRINT1("USBPORT_ReopenPipe ... \n");
1176
1177 FdoExtension = FdoDevice->DeviceExtension;
1178 Packet = &FdoExtension->MiniPortInterface->Packet;
1179
1180 while (TRUE)
1181 {
1182 if (!InterlockedIncrement(&Endpoint->LockCounter))
1183 break;
1184
1185 InterlockedDecrement(&Endpoint->LockCounter);
1186 USBPORT_Wait(FdoDevice, 1);
1187 }
1188
1189 KeAcquireSpinLock(&Endpoint->EndpointSpinLock, &Endpoint->EndpointOldIrql);
1190 KeAcquireSpinLockAtDpcLevel(&FdoExtension->MiniportSpinLock);
1191
1192 Packet->SetEndpointState(FdoExtension->MiniPortExt,
1193 Endpoint + 1,
1194 USBPORT_ENDPOINT_REMOVE);
1195
1196 KeReleaseSpinLockFromDpcLevel(&FdoExtension->MiniportSpinLock);
1197 KeReleaseSpinLock(&Endpoint->EndpointSpinLock, Endpoint->EndpointOldIrql);
1198
1199 USBPORT_Wait(FdoDevice, 2);
1200
1201 MiniportCloseEndpoint(FdoDevice, Endpoint);
1202
1203 RtlZeroMemory(Endpoint + 1,
1204 Packet->MiniPortEndpointSize);
1205
1206 if (Endpoint->HeaderBuffer)
1207 {
1208 USBPORT_FreeCommonBuffer(FdoDevice, Endpoint->HeaderBuffer);
1209 Endpoint->HeaderBuffer = NULL;
1210 }
1211
1212 KeAcquireSpinLock(&FdoExtension->MiniportSpinLock, &MiniportOldIrql);
1213
1214 Packet->QueryEndpointRequirements(FdoExtension->MiniPortExt,
1215 &Endpoint->EndpointProperties,
1216 &EndpointRequirements);
1217
1218 KeReleaseSpinLock(&FdoExtension->MiniportSpinLock, MiniportOldIrql);
1219
1220 if (EndpointRequirements.HeaderBufferSize)
1221 {
1222 HeaderBuffer = USBPORT_AllocateCommonBuffer(FdoDevice,
1223 EndpointRequirements.HeaderBufferSize);
1224 }
1225 else
1226 {
1227 HeaderBuffer = NULL;
1228 }
1229
1230 if (HeaderBuffer || EndpointRequirements.HeaderBufferSize == 0)
1231 {
1232 Endpoint->HeaderBuffer = HeaderBuffer;
1233 Status = STATUS_SUCCESS;
1234 }
1235 else
1236 {
1237 Endpoint->HeaderBuffer = 0;
1238 Status = STATUS_INSUFFICIENT_RESOURCES;
1239 }
1240
1241 if (Endpoint->HeaderBuffer && HeaderBuffer)
1242 {
1243 Endpoint->EndpointProperties.BufferVA = HeaderBuffer->VirtualAddress;
1244 Endpoint->EndpointProperties.BufferPA = HeaderBuffer->PhysicalAddress;
1245 Endpoint->EndpointProperties.BufferLength = HeaderBuffer->BufferLength;
1246 }
1247
1248 if (NT_SUCCESS(Status))
1249 {
1250 MiniportOpenEndpoint(FdoDevice, Endpoint);
1251
1252 KeAcquireSpinLock(&Endpoint->EndpointSpinLock, &Endpoint->EndpointOldIrql);
1253 KeAcquireSpinLockAtDpcLevel(&Endpoint->StateChangeSpinLock);
1254
1255 if (Endpoint->StateLast == USBPORT_ENDPOINT_ACTIVE)
1256 {
1257 KeReleaseSpinLockFromDpcLevel(&Endpoint->StateChangeSpinLock);
1258 KeAcquireSpinLockAtDpcLevel(&FdoExtension->MiniportSpinLock);
1259
1260 Packet->SetEndpointState(FdoExtension->MiniPortExt,
1261 Endpoint + 1,
1262 USBPORT_ENDPOINT_ACTIVE);
1263
1264 KeReleaseSpinLockFromDpcLevel(&FdoExtension->MiniportSpinLock);
1265 }
1266 else
1267 {
1268 KeReleaseSpinLockFromDpcLevel(&Endpoint->StateChangeSpinLock);
1269 }
1270
1271 KeReleaseSpinLock(&Endpoint->EndpointSpinLock, Endpoint->EndpointOldIrql);
1272 }
1273
1274 InterlockedDecrement(&Endpoint->LockCounter);
1275
1276 return Status;
1277 }
1278
1279 VOID
1280 NTAPI
USBPORT_FlushClosedEndpointList(IN PDEVICE_OBJECT FdoDevice)1281 USBPORT_FlushClosedEndpointList(IN PDEVICE_OBJECT FdoDevice)
1282 {
1283 PUSBPORT_DEVICE_EXTENSION FdoExtension;
1284 KIRQL OldIrql;
1285 PLIST_ENTRY ClosedList;
1286 PUSBPORT_ENDPOINT Endpoint;
1287
1288 DPRINT_CORE("USBPORT_FlushClosedEndpointList: ... \n");
1289
1290 FdoExtension = FdoDevice->DeviceExtension;
1291
1292 KeAcquireSpinLock(&FdoExtension->EndpointClosedSpinLock, &OldIrql);
1293 ClosedList = &FdoExtension->EndpointClosedList;
1294
1295 while (!IsListEmpty(ClosedList))
1296 {
1297 Endpoint = CONTAINING_RECORD(ClosedList->Flink,
1298 USBPORT_ENDPOINT,
1299 CloseLink);
1300
1301 RemoveHeadList(ClosedList);
1302 Endpoint->CloseLink.Flink = NULL;
1303 Endpoint->CloseLink.Blink = NULL;
1304
1305 KeReleaseSpinLock(&FdoExtension->EndpointClosedSpinLock, OldIrql);
1306
1307 USBPORT_DeleteEndpoint(FdoDevice, Endpoint);
1308
1309 KeAcquireSpinLock(&FdoExtension->EndpointClosedSpinLock, &OldIrql);
1310 }
1311
1312 KeReleaseSpinLock(&FdoExtension->EndpointClosedSpinLock, OldIrql);
1313 }
1314
1315 VOID
1316 NTAPI
USBPORT_InvalidateEndpointHandler(IN PDEVICE_OBJECT FdoDevice,IN PUSBPORT_ENDPOINT Endpoint,IN ULONG Type)1317 USBPORT_InvalidateEndpointHandler(IN PDEVICE_OBJECT FdoDevice,
1318 IN PUSBPORT_ENDPOINT Endpoint,
1319 IN ULONG Type)
1320 {
1321 PUSBPORT_DEVICE_EXTENSION FdoExtension;
1322 PUSBPORT_REGISTRATION_PACKET Packet;
1323 PLIST_ENTRY Entry;
1324 PLIST_ENTRY WorkerLink;
1325 PUSBPORT_ENDPOINT endpoint;
1326 KIRQL OldIrql;
1327 BOOLEAN IsAddEntry = FALSE;
1328
1329 DPRINT_CORE("USBPORT_InvalidateEndpointHandler: Endpoint - %p, Type - %x\n",
1330 Endpoint,
1331 Type);
1332
1333 FdoExtension = FdoDevice->DeviceExtension;
1334 Packet = &FdoExtension->MiniPortInterface->Packet;
1335
1336 if (Endpoint)
1337 {
1338 WorkerLink = &Endpoint->WorkerLink;
1339 KeAcquireSpinLock(&FdoExtension->EndpointListSpinLock, &OldIrql);
1340 DPRINT_CORE("USBPORT_InvalidateEndpointHandler: KeAcquireSpinLock \n");
1341
1342 if ((!WorkerLink->Flink || !WorkerLink->Blink) &&
1343 !(Endpoint->Flags & ENDPOINT_FLAG_IDLE) &&
1344 USBPORT_GetEndpointState(Endpoint) != USBPORT_ENDPOINT_CLOSED)
1345 {
1346 DPRINT_CORE("USBPORT_InvalidateEndpointHandler: InsertTailList \n");
1347 InsertTailList(&FdoExtension->WorkerList, WorkerLink);
1348 IsAddEntry = TRUE;
1349 }
1350
1351 KeReleaseSpinLock(&FdoExtension->EndpointListSpinLock, OldIrql);
1352
1353 if (Endpoint->Flags & ENDPOINT_FLAG_ROOTHUB_EP0)
1354 Type = INVALIDATE_ENDPOINT_WORKER_THREAD;
1355 }
1356 else
1357 {
1358 KeAcquireSpinLock(&FdoExtension->EndpointListSpinLock, &OldIrql);
1359
1360 for (Entry = FdoExtension->EndpointList.Flink;
1361 Entry && Entry != &FdoExtension->EndpointList;
1362 Entry = Entry->Flink)
1363 {
1364 endpoint = CONTAINING_RECORD(Entry,
1365 USBPORT_ENDPOINT,
1366 EndpointLink);
1367
1368 if (!endpoint->WorkerLink.Flink || !endpoint->WorkerLink.Blink)
1369 {
1370 if (!(endpoint->Flags & ENDPOINT_FLAG_IDLE) &&
1371 !(endpoint->Flags & ENDPOINT_FLAG_ROOTHUB_EP0) &&
1372 USBPORT_GetEndpointState(endpoint) != USBPORT_ENDPOINT_CLOSED)
1373 {
1374 DPRINT_CORE("USBPORT_InvalidateEndpointHandler: InsertTailList \n");
1375 InsertTailList(&FdoExtension->WorkerList, &endpoint->WorkerLink);
1376 IsAddEntry = TRUE;
1377 }
1378 }
1379 }
1380
1381 KeReleaseSpinLock(&FdoExtension->EndpointListSpinLock, OldIrql);
1382 }
1383
1384 if (FdoExtension->Flags & USBPORT_FLAG_HC_SUSPEND)
1385 {
1386 Type = INVALIDATE_ENDPOINT_WORKER_THREAD;
1387 }
1388 else if (IsAddEntry == FALSE && Type == INVALIDATE_ENDPOINT_INT_NEXT_SOF)
1389 {
1390 Type = INVALIDATE_ENDPOINT_ONLY;
1391 }
1392
1393 switch (Type)
1394 {
1395 case INVALIDATE_ENDPOINT_WORKER_THREAD:
1396 USBPORT_SignalWorkerThread(FdoDevice);
1397 break;
1398
1399 case INVALIDATE_ENDPOINT_WORKER_DPC:
1400 KeInsertQueueDpc(&FdoExtension->WorkerRequestDpc, NULL, NULL);
1401 break;
1402
1403 case INVALIDATE_ENDPOINT_INT_NEXT_SOF:
1404 KeAcquireSpinLock(&FdoExtension->MiniportSpinLock, &OldIrql);
1405 Packet->InterruptNextSOF(FdoExtension->MiniPortExt);
1406 KeReleaseSpinLock(&FdoExtension->MiniportSpinLock, OldIrql);
1407 break;
1408 }
1409 }
1410
1411 ULONG
1412 NTAPI
USBPORT_DmaEndpointPaused(IN PDEVICE_OBJECT FdoDevice,IN PUSBPORT_ENDPOINT Endpoint)1413 USBPORT_DmaEndpointPaused(IN PDEVICE_OBJECT FdoDevice,
1414 IN PUSBPORT_ENDPOINT Endpoint)
1415 {
1416 PUSBPORT_DEVICE_EXTENSION FdoExtension;
1417 PUSBPORT_REGISTRATION_PACKET Packet;
1418 PLIST_ENTRY Entry;
1419 PUSBPORT_TRANSFER Transfer;
1420 PURB Urb;
1421 ULONG Frame;
1422 ULONG CurrentFrame;
1423 ULONG CompletedLen = 0;
1424 KIRQL OldIrql;
1425
1426 DPRINT_CORE("USBPORT_DmaEndpointPaused \n");
1427
1428 FdoExtension = FdoDevice->DeviceExtension;
1429 Packet = &FdoExtension->MiniPortInterface->Packet;
1430
1431 Entry = Endpoint->TransferList.Flink;
1432
1433 if (Entry == &Endpoint->TransferList)
1434 return USBPORT_ENDPOINT_ACTIVE;
1435
1436 while (Entry && Entry != &Endpoint->TransferList)
1437 {
1438 Transfer = CONTAINING_RECORD(Entry,
1439 USBPORT_TRANSFER,
1440 TransferLink);
1441
1442 if (Transfer->Flags & (TRANSFER_FLAG_CANCELED | TRANSFER_FLAG_ABORTED))
1443 {
1444 if (Transfer->Flags & TRANSFER_FLAG_ISO &&
1445 Transfer->Flags & TRANSFER_FLAG_SUBMITED &&
1446 !(Endpoint->Flags & ENDPOINT_FLAG_NUKE))
1447 {
1448 Urb = Transfer->Urb;
1449
1450 Frame = Urb->UrbIsochronousTransfer.StartFrame +
1451 Urb->UrbIsochronousTransfer.NumberOfPackets;
1452
1453 KeAcquireSpinLock(&FdoExtension->MiniportSpinLock, &OldIrql);
1454 CurrentFrame = Packet->Get32BitFrameNumber(FdoExtension->MiniPortExt);
1455 KeReleaseSpinLock(&FdoExtension->MiniportSpinLock, OldIrql);
1456
1457 if (Frame + 1 > CurrentFrame)
1458 {
1459 return USBPORT_GetEndpointState(Endpoint);
1460 }
1461 }
1462
1463 if ((Transfer->Flags & TRANSFER_FLAG_SUBMITED) &&
1464 !(Endpoint->Flags & ENDPOINT_FLAG_NUKE))
1465 {
1466 KeAcquireSpinLock(&FdoExtension->MiniportSpinLock, &OldIrql);
1467
1468 Packet->AbortTransfer(FdoExtension->MiniPortExt,
1469 Endpoint + 1,
1470 Transfer->MiniportTransfer,
1471 &CompletedLen);
1472
1473 KeReleaseSpinLock(&FdoExtension->MiniportSpinLock, OldIrql);
1474
1475 if (Transfer->Flags & TRANSFER_FLAG_ISO)
1476 {
1477 DPRINT1("USBPORT_DmaEndpointActive: FIXME call USBPORT_FlushIsoTransfer\n");
1478 ASSERT(FALSE); //USBPORT_FlushIsoTransfer();
1479 }
1480 else
1481 {
1482 Transfer->CompletedTransferLen = CompletedLen;
1483 }
1484 }
1485
1486 RemoveEntryList(&Transfer->TransferLink);
1487 Entry = Transfer->TransferLink.Flink;
1488
1489 if (Transfer->Flags & TRANSFER_FLAG_SPLITED)
1490 {
1491 USBPORT_CancelSplitTransfer(Transfer);
1492 }
1493 else
1494 {
1495 InsertTailList(&Endpoint->CancelList, &Transfer->TransferLink);
1496 }
1497 }
1498 else
1499 {
1500 Entry = Transfer->TransferLink.Flink;
1501 }
1502 }
1503
1504 return USBPORT_ENDPOINT_ACTIVE;
1505 }
1506
1507 ULONG
1508 NTAPI
USBPORT_DmaEndpointActive(IN PDEVICE_OBJECT FdoDevice,IN PUSBPORT_ENDPOINT Endpoint)1509 USBPORT_DmaEndpointActive(IN PDEVICE_OBJECT FdoDevice,
1510 IN PUSBPORT_ENDPOINT Endpoint)
1511 {
1512 PUSBPORT_DEVICE_EXTENSION FdoExtension;
1513 PUSBPORT_REGISTRATION_PACKET Packet;
1514 PLIST_ENTRY Entry;
1515 PUSBPORT_TRANSFER Transfer;
1516 LARGE_INTEGER TimeOut;
1517 MPSTATUS MpStatus;
1518 KIRQL OldIrql;
1519
1520 DPRINT_CORE("USBPORT_DmaEndpointActive \n");
1521
1522 FdoExtension = FdoDevice->DeviceExtension;
1523
1524 Entry = Endpoint->TransferList.Flink;
1525
1526 while (Entry && Entry != &Endpoint->TransferList)
1527 {
1528 Transfer = CONTAINING_RECORD(Entry,
1529 USBPORT_TRANSFER,
1530 TransferLink);
1531
1532 if (!(Transfer->Flags & TRANSFER_FLAG_SUBMITED) &&
1533 !(Endpoint->Flags & ENDPOINT_FLAG_NUKE))
1534 {
1535 KeAcquireSpinLock(&FdoExtension->MiniportSpinLock, &OldIrql);
1536
1537 Packet = &FdoExtension->MiniPortInterface->Packet;
1538
1539 if (Transfer->Flags & TRANSFER_FLAG_ISO)
1540 {
1541 DPRINT1("USBPORT_DmaEndpointActive: FIXME call SubmitIsoTransfer\n");
1542
1543 MpStatus = Packet->SubmitIsoTransfer(FdoExtension->MiniPortExt,
1544 Endpoint + 1,
1545 &Transfer->TransferParameters,
1546 Transfer->MiniportTransfer,
1547 NULL);//&Transfer->IsoTransferParameters);
1548 }
1549 else
1550 {
1551 MpStatus = Packet->SubmitTransfer(FdoExtension->MiniPortExt,
1552 Endpoint + 1,
1553 &Transfer->TransferParameters,
1554 Transfer->MiniportTransfer,
1555 &Transfer->SgList);
1556 }
1557
1558 KeReleaseSpinLock(&FdoExtension->MiniportSpinLock, OldIrql);
1559
1560 if (MpStatus)
1561 {
1562 if ((MpStatus != MP_STATUS_FAILURE) && Transfer->Flags & TRANSFER_FLAG_ISO)
1563 {
1564 DPRINT1("USBPORT_DmaEndpointActive: FIXME call USBPORT_ErrorCompleteIsoTransfer\n");
1565 ASSERT(FALSE); //USBPORT_ErrorCompleteIsoTransfer();
1566 }
1567
1568 return USBPORT_ENDPOINT_ACTIVE;
1569 }
1570
1571 Transfer->Flags |= TRANSFER_FLAG_SUBMITED;
1572 KeQuerySystemTime(&Transfer->Time);
1573
1574 TimeOut.QuadPart = 10000 * Transfer->TimeOut;
1575 Transfer->Time.QuadPart += TimeOut.QuadPart;
1576 }
1577
1578 if (Transfer->Flags & (TRANSFER_FLAG_CANCELED | TRANSFER_FLAG_ABORTED))
1579 {
1580 return USBPORT_ENDPOINT_PAUSED;
1581 }
1582
1583 Entry = Transfer->TransferLink.Flink;
1584 }
1585
1586 return USBPORT_ENDPOINT_ACTIVE;
1587 }
1588
1589 VOID
1590 NTAPI
USBPORT_DmaEndpointWorker(IN PUSBPORT_ENDPOINT Endpoint)1591 USBPORT_DmaEndpointWorker(IN PUSBPORT_ENDPOINT Endpoint)
1592 {
1593 PDEVICE_OBJECT FdoDevice;
1594 ULONG PrevState;
1595 ULONG EndpointState;
1596 BOOLEAN IsPaused = FALSE;
1597
1598 DPRINT_CORE("USBPORT_DmaEndpointWorker ... \n");
1599
1600 FdoDevice = Endpoint->FdoDevice;
1601
1602 KeAcquireSpinLock(&Endpoint->EndpointSpinLock, &Endpoint->EndpointOldIrql);
1603
1604 PrevState = USBPORT_GetEndpointState(Endpoint);
1605
1606 if (PrevState == USBPORT_ENDPOINT_PAUSED)
1607 {
1608 EndpointState = USBPORT_DmaEndpointPaused(FdoDevice, Endpoint);
1609 }
1610 else if (PrevState == USBPORT_ENDPOINT_ACTIVE)
1611 {
1612 EndpointState = USBPORT_DmaEndpointActive(FdoDevice, Endpoint);
1613 }
1614 else
1615 {
1616 #ifndef NDEBUG_USBPORT_CORE
1617 DPRINT1("USBPORT_DmaEndpointWorker: DbgBreakPoint. EndpointState - %x\n",
1618 EndpointState);
1619 DbgBreakPoint();
1620 #endif
1621 EndpointState = USBPORT_ENDPOINT_UNKNOWN;
1622 }
1623
1624 KeReleaseSpinLock(&Endpoint->EndpointSpinLock, Endpoint->EndpointOldIrql);
1625
1626 USBPORT_FlushCancelList(Endpoint);
1627
1628 KeAcquireSpinLock(&Endpoint->EndpointSpinLock, &Endpoint->EndpointOldIrql);
1629
1630 if (EndpointState == PrevState)
1631 {
1632 if (EndpointState == USBPORT_ENDPOINT_PAUSED)
1633 {
1634 IsPaused = TRUE;
1635 }
1636 }
1637 else
1638 {
1639 USBPORT_SetEndpointState(Endpoint, EndpointState);
1640 }
1641
1642 KeReleaseSpinLock(&Endpoint->EndpointSpinLock, Endpoint->EndpointOldIrql);
1643
1644 if (IsPaused)
1645 {
1646 USBPORT_InvalidateEndpointHandler(FdoDevice,
1647 Endpoint,
1648 INVALIDATE_ENDPOINT_WORKER_THREAD);
1649 }
1650
1651 DPRINT_CORE("USBPORT_DmaEndpointWorker exit \n");
1652 }
1653
1654 BOOLEAN
1655 NTAPI
USBPORT_EndpointWorker(IN PUSBPORT_ENDPOINT Endpoint,IN BOOLEAN LockNotChecked)1656 USBPORT_EndpointWorker(IN PUSBPORT_ENDPOINT Endpoint,
1657 IN BOOLEAN LockNotChecked)
1658 {
1659 PDEVICE_OBJECT FdoDevice;
1660 PUSBPORT_DEVICE_EXTENSION FdoExtension;
1661 PUSBPORT_REGISTRATION_PACKET Packet;
1662 ULONG EndpointState;
1663
1664 DPRINT_CORE("USBPORT_EndpointWorker: Endpoint - %p, LockNotChecked - %x\n",
1665 Endpoint,
1666 LockNotChecked);
1667
1668 FdoDevice = Endpoint->FdoDevice;
1669 FdoExtension = FdoDevice->DeviceExtension;
1670 Packet = &FdoExtension->MiniPortInterface->Packet;
1671
1672 if (LockNotChecked == FALSE)
1673 {
1674 if (InterlockedIncrement(&Endpoint->LockCounter))
1675 {
1676 InterlockedDecrement(&Endpoint->LockCounter);
1677 DPRINT_CORE("USBPORT_EndpointWorker: LockCounter > 0\n");
1678 return TRUE;
1679 }
1680 }
1681
1682 ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
1683
1684 KeAcquireSpinLockAtDpcLevel(&Endpoint->EndpointSpinLock);
1685
1686 if (USBPORT_GetEndpointState(Endpoint) == USBPORT_ENDPOINT_CLOSED)
1687 {
1688 KeReleaseSpinLockFromDpcLevel(&Endpoint->EndpointSpinLock);
1689 InterlockedDecrement(&Endpoint->LockCounter);
1690 DPRINT_CORE("USBPORT_EndpointWorker: State == USBPORT_ENDPOINT_CLOSED. return FALSE\n");
1691 return FALSE;
1692 }
1693
1694 if ((Endpoint->Flags & (ENDPOINT_FLAG_ROOTHUB_EP0 | ENDPOINT_FLAG_NUKE)) == 0)
1695 {
1696 KeAcquireSpinLockAtDpcLevel(&FdoExtension->MiniportSpinLock);
1697 Packet->PollEndpoint(FdoExtension->MiniPortExt, Endpoint + 1);
1698 KeReleaseSpinLockFromDpcLevel(&FdoExtension->MiniportSpinLock);
1699 }
1700
1701 EndpointState = USBPORT_GetEndpointState(Endpoint);
1702
1703 if (EndpointState == USBPORT_ENDPOINT_REMOVE)
1704 {
1705 KeAcquireSpinLockAtDpcLevel(&Endpoint->StateChangeSpinLock);
1706 Endpoint->StateLast = USBPORT_ENDPOINT_CLOSED;
1707 Endpoint->StateNext = USBPORT_ENDPOINT_CLOSED;
1708 KeReleaseSpinLockFromDpcLevel(&Endpoint->StateChangeSpinLock);
1709
1710 KeReleaseSpinLockFromDpcLevel(&Endpoint->EndpointSpinLock);
1711
1712 KeAcquireSpinLockAtDpcLevel(&FdoExtension->EndpointListSpinLock);
1713
1714 ExInterlockedInsertTailList(&FdoExtension->EndpointClosedList,
1715 &Endpoint->CloseLink,
1716 &FdoExtension->EndpointClosedSpinLock);
1717
1718 KeReleaseSpinLockFromDpcLevel(&FdoExtension->EndpointListSpinLock);
1719
1720 InterlockedDecrement(&Endpoint->LockCounter);
1721 DPRINT_CORE("USBPORT_EndpointWorker: State == USBPORT_ENDPOINT_REMOVE. return FALSE\n");
1722 return FALSE;
1723 }
1724
1725 if (!IsListEmpty(&Endpoint->PendingTransferList) ||
1726 !IsListEmpty(&Endpoint->TransferList) ||
1727 !IsListEmpty(&Endpoint->CancelList))
1728 {
1729 KeReleaseSpinLockFromDpcLevel(&Endpoint->EndpointSpinLock);
1730
1731 EndpointState = USBPORT_GetEndpointState(Endpoint);
1732
1733 KeAcquireSpinLockAtDpcLevel(&Endpoint->StateChangeSpinLock);
1734 if (EndpointState == Endpoint->StateNext)
1735 {
1736 KeReleaseSpinLockFromDpcLevel(&Endpoint->StateChangeSpinLock);
1737
1738 if (Endpoint->EndpointWorker)
1739 {
1740 USBPORT_DmaEndpointWorker(Endpoint);
1741 }
1742 else
1743 {
1744 USBPORT_RootHubEndpointWorker(Endpoint);
1745 }
1746
1747 USBPORT_FlushAbortList(Endpoint);
1748
1749 InterlockedDecrement(&Endpoint->LockCounter);
1750 DPRINT_CORE("USBPORT_EndpointWorker: return FALSE\n");
1751 return FALSE;
1752 }
1753
1754 KeReleaseSpinLockFromDpcLevel(&Endpoint->StateChangeSpinLock);
1755 InterlockedDecrement(&Endpoint->LockCounter);
1756
1757 DPRINT_CORE("USBPORT_EndpointWorker: return TRUE\n");
1758 return TRUE;
1759 }
1760
1761 KeReleaseSpinLockFromDpcLevel(&Endpoint->EndpointSpinLock);
1762
1763 USBPORT_FlushAbortList(Endpoint);
1764
1765 InterlockedDecrement(&Endpoint->LockCounter);
1766 DPRINT_CORE("USBPORT_EndpointWorker: return FALSE\n");
1767 return FALSE;
1768 }
1769