ReactOS  0.4.13-dev-259-g5ca9c9c
usb_request.cpp
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: drivers/usb/usbehci/usb_request.cpp
5  * PURPOSE: USB EHCI device driver.
6  * PROGRAMMERS:
7  * Michael Martin (michael.martin@reactos.org)
8  * Johannes Anderwald (johannes.anderwald@reactos.org)
9  */
10 
11 #include "usbehci.h"
12 
13 #define NDEBUG
14 #include <debug.h>
15 
16 class CUSBRequest : public IEHCIRequest
17 {
18 public:
20 
22  {
24  return m_Ref;
25  }
27  {
29 
30  if (!m_Ref)
31  {
32  delete this;
33  return 0;
34  }
35  return m_Ref;
36  }
37 
38  // IUSBRequest interface functions
40  // IEHCI Request interface functions
42 
43  // local functions
49  NTSTATUS CreateQueueHead(PQUEUE_HEAD *OutQueueHead);
54  NTSTATUS STDMETHODCALLTYPE BuildTransferDescriptorChain(IN PQUEUE_HEAD QueueHead, IN PVOID TransferBuffer, IN ULONG TransferBufferLength, IN UCHAR PidCode, IN UCHAR InitialDataToggle, OUT PQUEUE_TRANSFER_DESCRIPTOR * OutFirstDescriptor, OUT PQUEUE_TRANSFER_DESCRIPTOR * OutLastDescriptor, OUT PUCHAR OutDataToggle, OUT PULONG OutTransferBufferOffset);
55  VOID STDMETHODCALLTYPE InitDescriptor(IN PQUEUE_TRANSFER_DESCRIPTOR CurrentDescriptor, IN PVOID TransferBuffer, IN ULONG TransferBufferLength, IN UCHAR PidCode, IN UCHAR DataToggle, OUT PULONG OutDescriptorLength);
56  VOID DumpQueueHead(IN PQUEUE_HEAD QueueHead);
57 
58  // constructor / destructor
59  CUSBRequest(IUnknown *OuterUnknown);
60  virtual ~CUSBRequest();
61 
62 protected:
64 
65  //
66  // memory manager for allocating setup packet / queue head / transfer descriptors
67  //
69 
70  //
71  // caller provided irp packet containing URB request
72  //
74 
75  //
76  // transfer buffer length
77  //
79 
80  //
81  // current transfer length
82  //
84 
85  //
86  // Total Transfer Length
87  //
89 
90  //
91  // transfer buffer MDL
92  //
94 
95  //
96  // caller provided setup packet
97  //
99 
100  //
101  // completion event for callers who initialized request with setup packet
102  //
104 
105  //
106  // device address for callers who initialized it with device address
107  //
109 
110  //
111  // store end point address
112  //
114 
115  //
116  // DMA queue head
117  //
119 
120  //
121  // allocated setup packet from the DMA pool
122  //
125 
126  //
127  // stores the result of the operation
128  //
131 
132  // buffer base address
134 
135  // device speed
137 
138 };
139 
140 //----------------------------------------------------------------------------------------
142  m_CompletionEvent(NULL)
143 {
144  UNREFERENCED_PARAMETER(OuterUnknown);
145 }
146 
147 //----------------------------------------------------------------------------------------
149 {
150  if (m_CompletionEvent != NULL)
151  {
153  }
154 }
155 
156 //----------------------------------------------------------------------------------------
157 NTSTATUS
160  IN REFIID refiid,
161  OUT PVOID* Output)
162 {
163  return STATUS_UNSUCCESSFUL;
164 }
165 
166 //----------------------------------------------------------------------------------------
167 NTSTATUS
169 CUSBRequest::InitializeWithSetupPacket(
170  IN PDMAMEMORYMANAGER DmaManager,
173  IN OPTIONAL PUSB_ENDPOINT EndpointDescriptor,
174  IN OUT ULONG TransferBufferLength,
175  IN OUT PMDL TransferBuffer)
176 {
177  //
178  // sanity checks
179  //
180  PC_ASSERT(DmaManager);
181  PC_ASSERT(SetupPacket);
182 
183  //
184  // initialize packet
185  //
186  m_DmaManager = DmaManager;
187  m_SetupPacket = SetupPacket;
188  m_TransferBufferLength = TransferBufferLength;
189  m_TransferBufferMDL = TransferBuffer;
190  m_DeviceAddress = Device->GetDeviceAddress();
191  m_Speed = Device->GetSpeed();
192  m_EndpointDescriptor = EndpointDescriptor;
194 
195  //
196  // Set Length Completed to 0
197  //
199 
200  //
201  // allocate completion event
202  //
204  if (!m_CompletionEvent)
205  {
206  //
207  // failed to allocate completion event
208  //
210  }
211 
212  //
213  // initialize completion event
214  //
216 
217  //
218  // done
219  //
220  return STATUS_SUCCESS;
221 }
222 //----------------------------------------------------------------------------------------
223 NTSTATUS
225 CUSBRequest::InitializeWithIrp(
226  IN PDMAMEMORYMANAGER DmaManager,
228  IN OUT PIRP Irp)
229 {
230  PIO_STACK_LOCATION IoStack;
231  PURB Urb;
232 
233  //
234  // sanity checks
235  //
236  PC_ASSERT(DmaManager);
237  PC_ASSERT(Irp);
238 
239  m_DmaManager = DmaManager;
241  m_Speed = Device->GetSpeed();
242 
243  //
244  // get current irp stack location
245  //
247 
248  //
249  // sanity check
250  //
252  PC_ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_USB_SUBMIT_URB);
253  PC_ASSERT(IoStack->Parameters.Others.Argument1 != 0);
254 
255  //
256  // get urb
257  //
258  Urb = (PURB)IoStack->Parameters.Others.Argument1;
259 
260  //
261  // store irp
262  //
263  m_Irp = Irp;
264 
265  //
266  // check function type
267  //
268  switch (Urb->UrbHeader.Function)
269  {
270  //
271  // luckily those request have the same structure layout
272  //
276  {
277  //
278  // bulk interrupt transfer
279  //
280  if (Urb->UrbBulkOrInterruptTransfer.TransferBufferLength)
281  {
282  //
283  // Check if there is a MDL
284  //
285  if (!Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL)
286  {
287  //
288  // sanity check
289  //
290  PC_ASSERT(Urb->UrbBulkOrInterruptTransfer.TransferBuffer);
291 
292  //
293  // Create one using TransferBuffer
294  //
295  DPRINT("Creating Mdl from Urb Buffer %p Length %lu\n", Urb->UrbBulkOrInterruptTransfer.TransferBuffer, Urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
297  Urb->UrbBulkOrInterruptTransfer.TransferBufferLength,
298  FALSE,
299  FALSE,
300  NULL);
301 
302  if (!m_TransferBufferMDL)
303  {
304  //
305  // failed to allocate mdl
306  //
308  }
309 
310  //
311  // build mdl for non paged pool
312  // FIXME: Does hub driver already do this when passing MDL?
313  //
315 
316  //
317  // Keep that ehci created the MDL and needs to free it.
318  //
319  }
320  else
321  {
322  m_TransferBufferMDL = Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL;
323  }
324 
325  //
326  // save buffer length
327  //
328  m_TransferBufferLength = Urb->UrbBulkOrInterruptTransfer.TransferBufferLength;
329 
330  //
331  // Set Length Completed to 0
332  //
334 
335  //
336  // get endpoint descriptor
337  //
339 
340  }
341  break;
342  }
343  default:
344  DPRINT1("URB Function: not supported %x\n", Urb->UrbHeader.Function);
345  //ASSERT(FALSE);
346  }
347 
348  //
349  // done
350  //
351  return STATUS_SUCCESS;
352 
353 }
354 
355 //----------------------------------------------------------------------------------------
356 VOID
359  IN NTSTATUS NtStatusCode,
360  IN ULONG UrbStatusCode,
361  IN struct _QUEUE_HEAD *QueueHead)
362 {
363  PIO_STACK_LOCATION IoStack;
364  PURB Urb;
365 
366  //
367  // FIXME: support linked queue heads
368  //
369 
370  //
371  // store completion code
372  //
373  m_NtStatusCode = NtStatusCode;
374  m_UrbStatusCode = UrbStatusCode;
375 
376  if (m_Irp)
377  {
378  //
379  // set irp completion status
380  //
381  m_Irp->IoStatus.Status = NtStatusCode;
382 
383  //
384  // get current irp stack location
385  //
387 
388  //
389  // get urb
390  //
391  Urb = (PURB)IoStack->Parameters.Others.Argument1;
392 
393  //
394  // store urb status
395  //
396  Urb->UrbHeader.Status = UrbStatusCode;
397 
398  //
399  // Check if the MDL was created
400  //
401  if (!Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL)
402  {
403  //
404  // Free Mdl
405  //
407  }
408 
409  //
410  // check if the request was successful
411  //
412  if (!NT_SUCCESS(NtStatusCode))
413  {
414  //
415  // set returned length to zero in case of error
416  //
417  Urb->UrbHeader.Length = 0;
418  }
419  else
420  {
421  //
422  // calculate transfer length
423  //
424  Urb->UrbBulkOrInterruptTransfer.TransferBufferLength = InternalCalculateTransferLength();
425  }
426 
427  DPRINT("Request %p Completing Irp %p NtStatusCode %x UrbStatusCode %x Transferred Length %lu\n", this, m_Irp, NtStatusCode, UrbStatusCode, Urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
428 
429  //
430  // FIXME: check if the transfer was split
431  // if yes dont complete irp yet
432  //
434  }
435  else
436  {
437  //
438  // signal completion event
439  //
442  }
443 }
444 
445 //----------------------------------------------------------------------------------------
446 NTSTATUS
448 CUSBRequest::GetQueueHead(
449  struct _QUEUE_HEAD ** OutHead)
450 {
451  ULONG TransferType;
453 
454  //
455  // first get transfer type
456  //
457  TransferType = InternalGetTransferType();
458 
459  //
460  // build request depending on type
461  //
462  switch(TransferType)
463  {
466  break;
470  break;
472  DPRINT1("USB_ENDPOINT_TYPE_ISOCHRONOUS not implemented\n");
474  break;
475  default:
476  PC_ASSERT(FALSE);
478  break;
479  }
480 
481  if (NT_SUCCESS(Status))
482  {
483  //
484  // store queue head
485  //
486  m_QueueHead = *OutHead;
487 
488  //
489  // store request object
490  //
491  (*OutHead)->Request = PVOID(this);
492  }
493 
494  //
495  // done
496  //
497  return Status;
498 }
499 
500 //----------------------------------------------------------------------------------------
501 BOOLEAN
503 CUSBRequest::IsRequestComplete()
504 {
505  //
506  // FIXME: check if request was split
507  //
508 
509  //
510  // Check if the transfer was completed, only valid for Bulk Transfers
511  //
513  && (GetTransferType() == USB_ENDPOINT_TYPE_BULK))
514  {
515  //
516  // Transfer not completed
517  //
518  return FALSE;
519  }
520  return TRUE;
521 }
522 //----------------------------------------------------------------------------------------
523 ULONG
525 CUSBRequest::GetTransferType()
526 {
527  //
528  // call internal implementation
529  //
530  return InternalGetTransferType();
531 }
532 
533 //----------------------------------------------------------------------------------------
534 ULONG
536 {
537  ULONG TransferType;
538 
539  //
540  // check if an irp is provided
541  //
542  if (m_Irp)
543  {
545 
546  //
547  // end point is defined in the low byte of bmAttributes
548  //
550  }
551  else
552  {
553  //
554  // initialized with setup packet, must be a control transfer
555  //
556  TransferType = USB_ENDPOINT_TYPE_CONTROL;
558  }
559 
560  //
561  // done
562  //
563  return TransferType;
564 }
565 
566 UCHAR
568 {
570  {
571  //
572  // end point direction is highest bit in bEndpointAddress
573  //
575  }
576  else
577  {
578  //
579  // request arrives on the control pipe, extract direction from setup packet
580  //
582  return (m_DescriptorPacket->bmRequestType.B >> 7);
583  }
584 }
585 
586 VOID
589  IN PQUEUE_TRANSFER_DESCRIPTOR CurrentDescriptor,
590  IN PVOID TransferBuffer,
591  IN ULONG TransferBufferLength,
592  IN UCHAR PidCode,
593  IN UCHAR DataToggle,
594  OUT PULONG OutDescriptorLength)
595 {
596  ULONG Index, Length = 0, PageOffset, BufferLength;
598 
599  //
600  // init transfer descriptor
601  //
602  CurrentDescriptor->Token.Bits.PIDCode = PidCode;
603  CurrentDescriptor->Token.Bits.TotalBytesToTransfer = 0;
604  CurrentDescriptor->Token.Bits.DataToggle = DataToggle;
605 
606  //
607  // sanity check
608  //
609  ASSERT(TransferBufferLength);
610 
611  //
612  // store buffers
613  //
614  Index = 0;
615  do
616  {
617  //
618  // get address (HACK)
619  //
620  *(volatile char *)TransferBuffer;
621  Address = MmGetPhysicalAddress(TransferBuffer);
622 
623  //
624  // use physical address
625  //
626  CurrentDescriptor->BufferPointer[Index] = Address.LowPart;
627  CurrentDescriptor->ExtendedBufferPointer[Index] = Address.HighPart;
628 
629  //
630  // Get the offset from page size
631  //
632  PageOffset = BYTE_OFFSET(CurrentDescriptor->BufferPointer[Index]);
633  if (PageOffset != 0)
634  {
635  //
636  // move to next page
637  //
638  TransferBuffer = (PVOID)ROUND_TO_PAGES(TransferBuffer);
639  }
640  else
641  {
642  //
643  // move to next page
644  //
645  TransferBuffer = (PVOID)((ULONG_PTR)TransferBuffer + PAGE_SIZE);
646  }
647 
648  //
649  // calculate buffer length
650  //
651  BufferLength = min(TransferBufferLength, PAGE_SIZE - PageOffset);
652 
653  //
654  // increment transfer bytes
655  //
656  CurrentDescriptor->Token.Bits.TotalBytesToTransfer += BufferLength;
657  CurrentDescriptor->TotalBytesToTransfer += BufferLength;
658  Length += BufferLength;
659  DPRINT("Index %lu TransferBufferLength %lu PageOffset %x BufferLength %lu Buffer Phy %p TransferBuffer %p\n", Index, TransferBufferLength, PageOffset, BufferLength, CurrentDescriptor->BufferPointer[Index], TransferBuffer);
660 
661  //
662  // decrement available byte count
663  //
664  TransferBufferLength -= BufferLength;
665  if (TransferBufferLength == 0)
666  {
667  //
668  // end reached
669  //
670  break;
671  }
672 
673  //
674  // sanity check
675  //
676  if (Index > 1)
677  {
678  //
679  // no equal buffers
680  //
681  ASSERT(CurrentDescriptor->BufferPointer[Index] != CurrentDescriptor->BufferPointer[Index-1]);
682  }
683 
684  //
685  // next descriptor index
686  //
687  Index++;
688  }while(Index < 5);
689 
690  //
691  // store result
692  //
693  *OutDescriptorLength = Length;
694 }
695 
696 NTSTATUS
699  IN PQUEUE_HEAD QueueHead,
700  IN PVOID TransferBuffer,
701  IN ULONG TransferBufferLength,
702  IN UCHAR PidCode,
703  IN UCHAR InitialDataToggle,
704  OUT PQUEUE_TRANSFER_DESCRIPTOR * OutFirstDescriptor,
705  OUT PQUEUE_TRANSFER_DESCRIPTOR * OutLastDescriptor,
706  OUT PUCHAR OutDataToggle,
707  OUT PULONG OutTransferBufferOffset)
708 {
709  PQUEUE_TRANSFER_DESCRIPTOR FirstDescriptor = NULL, CurrentDescriptor, LastDescriptor = NULL;
711  ULONG DescriptorLength, TransferBufferOffset = 0;
712  ULONG MaxPacketSize = 0, TransferSize;
713 
714  //
715  // is there an endpoint descriptor
716  //
718  {
719  //
720  // use endpoint packet size
721  //
723  }
724 
725  do
726  {
727  //
728  // allocate transfer descriptor
729  //
730  Status = CreateDescriptor(&CurrentDescriptor);
731  if (!NT_SUCCESS(Status))
732  {
733  //
734  // failed to allocate transfer descriptor
735  //
737  }
738 
739  if (MaxPacketSize)
740  {
741  //
742  // transfer size is minimum available buffer or endpoint size
743  //
744  TransferSize = min(TransferBufferLength - TransferBufferOffset, MaxPacketSize);
745  }
746  else
747  {
748  //
749  // use available buffer
750  //
751  TransferSize = TransferBufferLength - TransferBufferOffset;
752  }
753 
754  //
755  // now init the descriptor
756  //
757  InitDescriptor(CurrentDescriptor,
758  (PVOID)((ULONG_PTR)TransferBuffer + TransferBufferOffset),
759  TransferSize,
760  PidCode,
761  InitialDataToggle,
762  &DescriptorLength);
763 
764  //
765  // insert into queue head
766  //
767  InsertTailList(&QueueHead->TransferDescriptorListHead, &CurrentDescriptor->DescriptorEntry);
768 
769  //
770  // adjust offset
771  //
772  TransferBufferOffset += DescriptorLength;
773 
774  if (LastDescriptor)
775  {
776  //
777  // link to current descriptor
778  //
779  LastDescriptor->NextPointer = CurrentDescriptor->PhysicalAddr;
780  LastDescriptor = CurrentDescriptor;
781  }
782  else
783  {
784  //
785  // first descriptor in chain
786  //
787  LastDescriptor = FirstDescriptor = CurrentDescriptor;
788  }
789 
790  //
791  // flip data toggle
792  //
793  InitialDataToggle = !InitialDataToggle;
794 
795  if(TransferBufferLength == TransferBufferOffset)
796  {
797  //
798  // end reached
799  //
800  break;
801  }
802 
803  }while(TRUE);
804 
805  if (OutFirstDescriptor)
806  {
807  //
808  // store first descriptor
809  //
810  *OutFirstDescriptor = FirstDescriptor;
811  }
812 
813  if (OutLastDescriptor)
814  {
815  //
816  // store last descriptor
817  //
818  *OutLastDescriptor = CurrentDescriptor;
819  }
820 
821  if (OutDataToggle)
822  {
823  //
824  // store result data toggle
825  //
826  *OutDataToggle = InitialDataToggle;
827  }
828 
829  if (OutTransferBufferOffset)
830  {
831  //
832  // store offset
833  //
834  *OutTransferBufferOffset = TransferBufferOffset;
835  }
836 
837  //
838  // done
839  //
840  return STATUS_SUCCESS;
841 }
842 
843 //----------------------------------------------------------------------------------------
844 NTSTATUS
846  PQUEUE_HEAD * OutHead)
847 {
849  ULONG DescriptorChainLength;
850  PQUEUE_HEAD QueueHead;
851  PQUEUE_TRANSFER_DESCRIPTOR SetupDescriptor, StatusDescriptor, FirstDescriptor, LastDescriptor;
852 
853  //
854  // first allocate the queue head
855  //
856  Status = CreateQueueHead(&QueueHead);
857  if (!NT_SUCCESS(Status))
858  {
859  //
860  // failed to allocate queue head
861  //
862  DPRINT1("[EHCI] Failed to create queue head\n");
863  return Status;
864  }
865 
866  //
867  // sanity check
868  //
869  PC_ASSERT(QueueHead);
870 
871  //
872  // create setup packet
873  //
875  if (!NT_SUCCESS(Status))
876  {
877  // failed to create setup packet
878  DPRINT1("[EHCI] Failed to create setup packet\n");
879 
880  // release queue head
881  m_DmaManager->Release(QueueHead, sizeof(QUEUE_HEAD));
882  return Status;
883  }
884 
885  //
886  // create setup descriptor
887  //
888  Status = CreateDescriptor(&SetupDescriptor);
889  if (!NT_SUCCESS(Status))
890  {
891  // failed to create setup transfer descriptor
892  DPRINT1("[EHCI] Failed to create setup descriptor\n");
893 
894  if (m_DescriptorPacket)
895  {
896  // release packet descriptor
898  }
899 
900  // release queue head
901  m_DmaManager->Release(QueueHead, sizeof(QUEUE_HEAD));
902  return Status;
903  }
904 
905  //
906  // create status descriptor
907  //
908  Status = CreateDescriptor(&StatusDescriptor);
909  if (!NT_SUCCESS(Status))
910  {
911  // failed to create status transfer descriptor
912  DPRINT1("[EHCI] Failed to create status descriptor\n");
913 
914  // release setup transfer descriptor
915  m_DmaManager->Release(SetupDescriptor, sizeof(QUEUE_TRANSFER_DESCRIPTOR));
916 
917  if (m_DescriptorPacket)
918  {
919  // release packet descriptor
921  }
922 
923  // release queue head
924  m_DmaManager->Release(QueueHead, sizeof(QUEUE_HEAD));
925  return Status;
926  }
927 
928  //
929  // now initialize the queue head
930  //
932 
934 
935  //
936  // init setup descriptor
937  //
938  SetupDescriptor->Token.Bits.PIDCode = PID_CODE_SETUP_TOKEN;
940  SetupDescriptor->Token.Bits.DataToggle = FALSE;
941  SetupDescriptor->BufferPointer[0] = m_DescriptorSetupPacket.LowPart;
943  InsertTailList(&QueueHead->TransferDescriptorListHead, &SetupDescriptor->DescriptorEntry);
944 
945 
946  //
947  // init status descriptor
948  //
949  StatusDescriptor->Token.Bits.TotalBytesToTransfer = 0;
950  StatusDescriptor->Token.Bits.DataToggle = TRUE;
951  StatusDescriptor->Token.Bits.InterruptOnComplete = TRUE;
952 
953  //
954  // is there data
955  //
957  {
962  TRUE,
963  &FirstDescriptor,
964  &LastDescriptor,
965  NULL,
966  &DescriptorChainLength);
967  if (!NT_SUCCESS(Status))
968  {
969  // failed to create descriptor chain
970  DPRINT1("[EHCI] Failed to create descriptor chain\n");
971 
972  // release status transfer descriptor
973  m_DmaManager->Release(StatusDescriptor, sizeof(QUEUE_TRANSFER_DESCRIPTOR));
974 
975  // release setup transfer descriptor
976  m_DmaManager->Release(SetupDescriptor, sizeof(QUEUE_TRANSFER_DESCRIPTOR));
977 
978  if (m_DescriptorPacket)
979  {
980  // release packet descriptor
982  }
983 
984  // release queue head
985  m_DmaManager->Release(QueueHead, sizeof(QUEUE_HEAD));
986  return Status;
987  }
988 
989  if (m_TransferBufferLength != DescriptorChainLength)
990  {
991  DPRINT1("DescriptorChainLength %x\n", DescriptorChainLength);
992  DPRINT1("m_TransferBufferLength %x\n", m_TransferBufferLength);
993  ASSERT(FALSE);
994  }
995 
996  //
997  // now link the descriptors
998  //
999  SetupDescriptor->NextPointer = FirstDescriptor->PhysicalAddr;
1000  SetupDescriptor->AlternateNextPointer = FirstDescriptor->PhysicalAddr;
1001  LastDescriptor->NextPointer = StatusDescriptor->PhysicalAddr;
1002  LastDescriptor->AlternateNextPointer = StatusDescriptor->PhysicalAddr;
1003 
1004 
1005  //
1006  // pid code is flipped for ops with data stage
1007  //
1008  StatusDescriptor->Token.Bits.PIDCode = !InternalGetPidDirection();
1009  }
1010  else
1011  {
1012  //
1013  // direct link
1014  //
1015  SetupDescriptor->NextPointer = StatusDescriptor->PhysicalAddr;
1016  SetupDescriptor->AlternateNextPointer = StatusDescriptor->PhysicalAddr;
1017 
1018  //
1019  // retrieve result of operation
1020  //
1021  StatusDescriptor->Token.Bits.PIDCode = PID_CODE_IN_TOKEN;
1022  }
1023 
1024  //
1025  // insert status descriptor
1026  //
1027  InsertTailList(&QueueHead->TransferDescriptorListHead, &StatusDescriptor->DescriptorEntry);
1028 
1029 
1030  //
1031  // link transfer descriptors to queue head
1032  //
1033  QueueHead->NextPointer = SetupDescriptor->PhysicalAddr;
1034 
1035  //
1036  // store result
1037  //
1038  *OutHead = QueueHead;
1039 
1040  //
1041  // displays the current request
1042  //
1043  //DumpQueueHead(QueueHead);
1044 
1045  DPRINT("BuildControlTransferQueueHead done\n");
1046  //
1047  // done
1048  //
1049  return STATUS_SUCCESS;
1050 }
1051 
1052 VOID
1054  IN PQUEUE_HEAD QueueHead)
1055 {
1058  ULONG Index = 0;
1059 
1060  DPRINT1("QueueHead %p Addr %x\n", QueueHead, QueueHead->PhysicalAddr);
1061  DPRINT1("QueueHead AlternateNextPointer %x\n", QueueHead->AlternateNextPointer);
1062  DPRINT1("QueueHead NextPointer %x\n", QueueHead->NextPointer);
1063 
1064  DPRINT1("QueueHead HubAddr %x\n", QueueHead->EndPointCharacteristics.ControlEndPointFlag);
1065  DPRINT1("QueueHead DeviceAddress %x\n", QueueHead->EndPointCharacteristics.DeviceAddress);
1066  DPRINT1("QueueHead EndPointNumber %x\n", QueueHead->EndPointCharacteristics.EndPointNumber);
1067  DPRINT1("QueueHead EndPointSpeed %x\n", QueueHead->EndPointCharacteristics.EndPointSpeed);
1068  DPRINT1("QueueHead HeadOfReclamation %x\n", QueueHead->EndPointCharacteristics.HeadOfReclamation);
1069  DPRINT1("QueueHead InactiveOnNextTransaction %x\n", QueueHead->EndPointCharacteristics.InactiveOnNextTransaction);
1070  DPRINT1("QueueHead MaximumPacketLength %x\n", QueueHead->EndPointCharacteristics.MaximumPacketLength);
1071  DPRINT1("QueueHead NakCountReload %x\n", QueueHead->EndPointCharacteristics.NakCountReload);
1072  DPRINT1("QueueHead QEDTDataToggleControl %x\n", QueueHead->EndPointCharacteristics.QEDTDataToggleControl);
1073  DPRINT1("QueueHead HubAddr %x\n", QueueHead->EndPointCapabilities.HubAddr);
1074  DPRINT1("QueueHead InterruptScheduleMask %x\n", QueueHead->EndPointCapabilities.InterruptScheduleMask);
1075  DPRINT1("QueueHead NumberOfTransactionPerFrame %x\n", QueueHead->EndPointCapabilities.NumberOfTransactionPerFrame);
1076  DPRINT1("QueueHead PortNumber %x\n", QueueHead->EndPointCapabilities.PortNumber);
1077  DPRINT1("QueueHead SplitCompletionMask %x\n", QueueHead->EndPointCapabilities.SplitCompletionMask);
1078 
1079  Entry = QueueHead->TransferDescriptorListHead.Flink;
1080  while(Entry != &QueueHead->TransferDescriptorListHead)
1081  {
1082  //
1083  // get transfer descriptor
1084  //
1086 
1087  DPRINT1("TransferDescriptor %lu Addr %x\n", Index, Descriptor->PhysicalAddr);
1088  DPRINT1("TransferDescriptor %lu Next %x\n", Index, Descriptor->NextPointer);
1089  DPRINT1("TransferDescriptor %lu AlternateNextPointer %x\n", Index, Descriptor->AlternateNextPointer);
1090  DPRINT1("TransferDescriptor %lu Active %lu\n", Index, Descriptor->Token.Bits.Active);
1091  DPRINT1("TransferDescriptor %lu BabbleDetected %lu\n", Index, Descriptor->Token.Bits.BabbleDetected);
1092  DPRINT1("TransferDescriptor %lu CurrentPage %lu\n", Index, Descriptor->Token.Bits.CurrentPage);
1093  DPRINT1("TransferDescriptor %lu DataBufferError %lu\n", Index, Descriptor->Token.Bits.DataBufferError);
1094  DPRINT1("TransferDescriptor %lu DataToggle %lu\n", Index, Descriptor->Token.Bits.DataToggle);
1095  DPRINT1("TransferDescriptor %lu ErrorCounter %lu\n", Index, Descriptor->Token.Bits.ErrorCounter);
1096  DPRINT1("TransferDescriptor %lu Halted %lu\n", Index, Descriptor->Token.Bits.Halted);
1097  DPRINT1("TransferDescriptor %lu InterruptOnComplete %x\n", Index, Descriptor->Token.Bits.InterruptOnComplete);
1098  DPRINT1("TransferDescriptor %lu MissedMicroFrame %lu\n", Index, Descriptor->Token.Bits.MissedMicroFrame);
1099  DPRINT1("TransferDescriptor %lu PIDCode %lu\n", Index, Descriptor->Token.Bits.PIDCode);
1100  DPRINT1("TransferDescriptor %lu PingState %lu\n", Index, Descriptor->Token.Bits.PingState);
1101  DPRINT1("TransferDescriptor %lu SplitTransactionState %lu\n", Index, Descriptor->Token.Bits.SplitTransactionState);
1102  DPRINT1("TransferDescriptor %lu TotalBytesToTransfer %lu\n", Index, Descriptor->Token.Bits.TotalBytesToTransfer);
1103  DPRINT1("TransferDescriptor %lu TransactionError %lu\n", Index, Descriptor->Token.Bits.TransactionError);
1104 
1105  DPRINT1("TransferDescriptor %lu Buffer Pointer 0 %x\n", Index, Descriptor->BufferPointer[0]);
1106  DPRINT1("TransferDescriptor %lu Buffer Pointer 1 %x\n", Index, Descriptor->BufferPointer[1]);
1107  DPRINT1("TransferDescriptor %lu Buffer Pointer 2 %x\n", Index, Descriptor->BufferPointer[2]);
1108  DPRINT1("TransferDescriptor %lu Buffer Pointer 3 %x\n", Index, Descriptor->BufferPointer[3]);
1109  DPRINT1("TransferDescriptor %lu Buffer Pointer 4 %x\n", Index, Descriptor->BufferPointer[4]);
1110  Entry = Entry->Flink;
1111  Index++;
1112  }
1113 }
1114 
1115 
1116 //----------------------------------------------------------------------------------------
1117 NTSTATUS
1119  PQUEUE_HEAD * OutHead)
1120 {
1121  NTSTATUS Status;
1122  PQUEUE_HEAD QueueHead;
1123  PVOID Base;
1124  ULONG ChainDescriptorLength;
1125  PQUEUE_TRANSFER_DESCRIPTOR FirstDescriptor, LastDescriptor;
1126 
1127  //
1128  // Allocate the queue head
1129  //
1130  Status = CreateQueueHead(&QueueHead);
1131  if (!NT_SUCCESS(Status))
1132  {
1133  //
1134  // failed to allocate queue head
1135  //
1136  DPRINT1("[EHCI] Failed to create queue head\n");
1137  return Status;
1138  }
1139 
1140  //
1141  // sanity checks
1142  //
1143  PC_ASSERT(QueueHead);
1145 
1146  if (!m_Base)
1147  {
1148  //
1149  // get virtual base of mdl
1150  //
1152  }
1153 
1154  //
1155  // Increase the size of last transfer, 0 in case this is the first
1156  //
1158 
1160  PC_ASSERT(Base);
1161 
1162  //
1163  // sanity check
1164  //
1166 
1167  //
1168  // use 4 * PAGE_SIZE at max for each new request
1169  //
1171 
1172  //
1173  // build bulk transfer descriptor chain
1174  //
1176  Base,
1177  MaxTransferLength,
1180  &FirstDescriptor,
1181  &LastDescriptor,
1183  &ChainDescriptorLength);
1184  if (!NT_SUCCESS(Status))
1185  {
1186  //
1187  // failed to build transfer descriptor chain
1188  //
1189  DPRINT1("[EHCI] Failed to create descriptor chain\n");
1190  m_DmaManager->Release(QueueHead, sizeof(QUEUE_HEAD));
1191  return Status;
1192  }
1193 
1194  //
1195  // move to next offset
1196  //
1197  m_TransferBufferLengthCompleted += ChainDescriptorLength;
1198 
1199  //
1200  // init queue head
1201  //
1205  QueueHead->NextPointer = FirstDescriptor->PhysicalAddr;
1206  QueueHead->CurrentLinkPointer = FirstDescriptor->PhysicalAddr;
1208 
1212  ASSERT(QueueHead->NextPointer);
1213 
1214  //
1215  // interrupt on last descriptor
1216  //
1217  LastDescriptor->Token.Bits.InterruptOnComplete = TRUE;
1218 
1219  //
1220  // store result
1221  //
1222  *OutHead = QueueHead;
1223 
1224  //
1225  // dump status
1226  //
1227  //DumpQueueHead(QueueHead);
1228 
1229  //
1230  // done
1231  //
1232  return STATUS_SUCCESS;
1233 }
1234 
1235 //----------------------------------------------------------------------------------------
1236 NTSTATUS
1239  PQUEUE_TRANSFER_DESCRIPTOR *OutDescriptor)
1240 {
1242  NTSTATUS Status;
1243  PHYSICAL_ADDRESS TransferDescriptorPhysicalAddress;
1244 
1245  //
1246  // allocate descriptor
1247  //
1248  Status = m_DmaManager->Allocate(sizeof(QUEUE_TRANSFER_DESCRIPTOR), (PVOID*)&Descriptor, &TransferDescriptorPhysicalAddress);
1249  if (!NT_SUCCESS(Status))
1250  {
1251  //
1252  // failed to allocate transfer descriptor
1253  //
1255  }
1256 
1257  //
1258  // initialize transfer descriptor
1259  //
1260  Descriptor->NextPointer = TERMINATE_POINTER;
1261  Descriptor->AlternateNextPointer = TERMINATE_POINTER;
1262  Descriptor->Token.Bits.DataToggle = TRUE;
1263  Descriptor->Token.Bits.ErrorCounter = 0x03;
1264  Descriptor->Token.Bits.Active = TRUE;
1265  Descriptor->PhysicalAddr = TransferDescriptorPhysicalAddress.LowPart;
1266 
1267  //
1268  // store result
1269  //
1270  *OutDescriptor = Descriptor;
1271 
1272  //
1273  // done
1274  //
1275  return Status;
1276 }
1277 
1278 //----------------------------------------------------------------------------------------
1279 NTSTATUS
1281  PQUEUE_HEAD *OutQueueHead)
1282 {
1283  PQUEUE_HEAD QueueHead;
1284  PHYSICAL_ADDRESS QueueHeadPhysicalAddress;
1285  NTSTATUS Status;
1286 
1287  //
1288  // allocate queue head
1289  //
1290  Status = m_DmaManager->Allocate(sizeof(QUEUE_HEAD), (PVOID*)&QueueHead, &QueueHeadPhysicalAddress);
1291  if (!NT_SUCCESS(Status))
1292  {
1293  //
1294  // failed to allocate queue head
1295  //
1297  }
1298 
1299  //
1300  // initialize queue head
1301  //
1302  QueueHead->HorizontalLinkPointer = TERMINATE_POINTER;
1303  QueueHead->AlternateNextPointer = TERMINATE_POINTER;
1304  QueueHead->NextPointer = TERMINATE_POINTER;
1305  InitializeListHead(&QueueHead->TransferDescriptorListHead);
1306 
1307  //
1308  // 1 for non high speed, 0 for high speed device
1309  //
1310  QueueHead->EndPointCharacteristics.ControlEndPointFlag = 0;
1311  QueueHead->EndPointCharacteristics.HeadOfReclamation = FALSE;
1312  QueueHead->EndPointCharacteristics.MaximumPacketLength = 64;
1313 
1314  //
1315  // Set NakCountReload to max value possible
1316  //
1317  QueueHead->EndPointCharacteristics.NakCountReload = 0x3;
1318 
1319  //
1320  // Get the Initial Data Toggle from the QEDT
1321  //
1322  QueueHead->EndPointCharacteristics.QEDTDataToggleControl = TRUE;
1323 
1324  //
1325  // FIXME: check if High Speed Device
1326  //
1327  QueueHead->EndPointCharacteristics.EndPointSpeed = QH_ENDPOINT_HIGHSPEED;
1328  QueueHead->EndPointCapabilities.NumberOfTransactionPerFrame = 0x01;
1329  QueueHead->Token.DWord = 0;
1330  QueueHead->Token.Bits.InterruptOnComplete = FALSE;
1331 
1332  //
1333  // store address
1334  //
1335  QueueHead->PhysicalAddr = QueueHeadPhysicalAddress.LowPart;
1336 
1337  //
1338  // output queue head
1339  //
1340  *OutQueueHead = QueueHead;
1341 
1342  //
1343  // done
1344  //
1345  return STATUS_SUCCESS;
1346 }
1347 
1348 //----------------------------------------------------------------------------------------
1349 UCHAR
1352 {
1353  PIO_STACK_LOCATION IoStack;
1354  PURB Urb;
1355  PUSBDEVICE UsbDevice;
1356 
1357  //
1358  // check if there is an irp provided
1359  //
1360  if (!m_Irp)
1361  {
1362  //
1363  // used provided address
1364  //
1365  return m_DeviceAddress;
1366  }
1367 
1368  //
1369  // get current stack location
1370  //
1372 
1373  //
1374  // get contained urb
1375  //
1376  Urb = (PURB)IoStack->Parameters.Others.Argument1;
1377 
1378  //
1379  // check if there is a pipe handle provided
1380  //
1381  if (Urb->UrbHeader.UsbdDeviceHandle)
1382  {
1383  //
1384  // there is a device handle provided
1385  //
1386  UsbDevice = (PUSBDEVICE)Urb->UrbHeader.UsbdDeviceHandle;
1387 
1388  //
1389  // return device address
1390  //
1391  return UsbDevice->GetDeviceAddress();
1392  }
1393 
1394  //
1395  // no device handle provided, it is the host root bus
1396  //
1397  return 0;
1398 }
1399 
1400 //----------------------------------------------------------------------------------------
1401 NTSTATUS
1403 {
1404  NTSTATUS Status;
1405 
1406  //
1407  // allocate common buffer setup packet
1408  //
1410  if (!NT_SUCCESS(Status))
1411  {
1412  //
1413  // no memory
1414  //
1415  return Status;
1416  }
1417 
1418  if (m_SetupPacket)
1419  {
1420  //
1421  // copy setup packet
1422  //
1424  }
1425  else
1426  {
1427  //
1428  // build setup packet from urb
1429  //
1431  }
1432 
1433  //
1434  // done
1435  //
1436  return Status;
1437 }
1438 
1439 
1440 NTSTATUS
1442 {
1443  PIO_STACK_LOCATION IoStack;
1444  PURB Urb;
1446 
1447  //
1448  // sanity checks
1449  //
1450  PC_ASSERT(m_Irp);
1452 
1453  //
1454  // get stack location
1455  //
1457 
1458  //
1459  // get urb
1460  //
1461  Urb = (PURB)IoStack->Parameters.Others.Argument1;
1462 
1463  //
1464  // zero descriptor packet
1465  //
1467 
1468 
1469  switch (Urb->UrbHeader.Function)
1470  {
1471  /* CLEAR FEATURE */
1475  UNIMPLEMENTED;
1476  break;
1477 
1478  /* GET CONFIG */
1483  break;
1484 
1485  /* GET DESCRIPTOR */
1491  m_DescriptorPacket->wLength = (USHORT)Urb->UrbControlDescriptorRequest.TransferBufferLength;
1493  break;
1494 
1495  /* GET INTERFACE */
1501  break;
1502 
1503  /* GET STATUS */
1506  ASSERT(Urb->UrbControlGetStatusRequest.Index == 0);
1510  break;
1511 
1514  ASSERT(Urb->UrbControlGetStatusRequest.Index != 0);
1518  break;
1519 
1522  ASSERT(Urb->UrbControlGetStatusRequest.Index != 0);
1526  break;
1527 
1528  /* SET ADDRESS */
1529 
1530  /* SET CONFIG */
1533  m_DescriptorPacket->wValue.W = Urb->UrbSelectConfiguration.ConfigurationDescriptor->bConfigurationValue;
1537  break;
1538 
1539  /* SET DESCRIPTOR */
1543  UNIMPLEMENTED;
1544  break;
1545 
1546  /* SET FEATURE */
1549  ASSERT(Urb->UrbControlGetStatusRequest.Index == 0);
1552  break;
1553 
1556  ASSERT(Urb->UrbControlGetStatusRequest.Index == 0);
1559  break;
1560 
1563  ASSERT(Urb->UrbControlGetStatusRequest.Index == 0);
1566  break;
1567 
1568  /* SET INTERFACE*/
1571  m_DescriptorPacket->wValue.W = Urb->UrbSelectInterface.Interface.AlternateSetting;
1572  m_DescriptorPacket->wIndex.W = Urb->UrbSelectInterface.Interface.InterfaceNumber;
1575  break;
1576 
1577  /* SYNC FRAME */
1579  UNIMPLEMENTED;
1580  break;
1581  default:
1582  UNIMPLEMENTED;
1583  break;
1584  }
1585 
1586  return Status;
1587 }
1588 
1589 //----------------------------------------------------------------------------------------
1590 VOID
1592 CUSBRequest::GetResultStatus(
1593  OUT OPTIONAL NTSTATUS * NtStatusCode,
1594  OUT OPTIONAL PULONG UrbStatusCode)
1595 {
1596  //
1597  // sanity check
1598  //
1600 
1601  //
1602  // wait for the operation to complete
1603  //
1605 
1606  //
1607  // copy status
1608  //
1609  if (NtStatusCode)
1610  {
1611  *NtStatusCode = m_NtStatusCode;
1612  }
1613 
1614  //
1615  // copy urb status
1616  //
1617  if (UrbStatusCode)
1618  {
1619  *UrbStatusCode = m_UrbStatusCode;
1620  }
1621 
1622 }
1623 
1624 //-----------------------------------------------------------------------------------------
1625 BOOLEAN
1627 CUSBRequest::ShouldReleaseRequestAfterCompletion()
1628 {
1629  if (m_Irp)
1630  {
1631  //
1632  // the request is completed, release it
1633  //
1634  return TRUE;
1635  }
1636  else
1637  {
1638  //
1639  // created with an setup packet, don't release
1640  //
1641  return FALSE;
1642  }
1643 }
1644 
1645 //-----------------------------------------------------------------------------------------
1646 VOID
1648 CUSBRequest::FreeQueueHead(
1649  IN struct _QUEUE_HEAD * QueueHead)
1650 {
1653 
1654  //
1655  // sanity checks
1656  //
1658  ASSERT(QueueHead);
1659  ASSERT(!IsListEmpty(&QueueHead->TransferDescriptorListHead));
1660 
1661  do
1662  {
1663  //
1664  // get transfer descriptors
1665  //
1666  Entry = RemoveHeadList(&QueueHead->TransferDescriptorListHead);
1667  ASSERT(Entry);
1668 
1669  //
1670  // obtain descriptor from entry
1671  //
1673  ASSERT(Descriptor);
1674 
1675  //
1676  // add transfer count
1677  //
1678  m_TotalBytesTransferred += (Descriptor->TotalBytesToTransfer - Descriptor->Token.Bits.TotalBytesToTransfer);
1679  DPRINT("TotalBytes Transferred in Descriptor %p Phys Addr %x TotalBytesSoftware %lu Length %lu\n", Descriptor, Descriptor->PhysicalAddr, Descriptor->TotalBytesToTransfer, Descriptor->TotalBytesToTransfer - Descriptor->Token.Bits.TotalBytesToTransfer);
1680 
1681  //
1682  // release transfer descriptors
1683  //
1685 
1686  }while(!IsListEmpty(&QueueHead->TransferDescriptorListHead));
1687 
1688  if (m_DescriptorPacket)
1689  {
1690  //
1691  // release packet descriptor
1692  //
1694  }
1695 
1696  //
1697  // release queue head
1698  //
1699  m_DmaManager->Release(QueueHead, sizeof(QUEUE_HEAD));
1700 
1701  //
1702  // nullify pointers
1703  //
1704  m_QueueHead = 0;
1705  m_DescriptorPacket = 0;
1706 }
1707 
1708 //-----------------------------------------------------------------------------------------
1709 BOOLEAN
1711 CUSBRequest::IsQueueHeadComplete(
1712  struct _QUEUE_HEAD * QueueHead)
1713 {
1716 
1717  //
1718  // first check - is the queue head currently active
1719  //
1720  if (QueueHead->Token.Bits.Active)
1721  {
1722  //
1723  // queue head is active (currently processed)
1724  //
1725  return FALSE;
1726  }
1727 
1728  if (QueueHead->Token.Bits.Halted)
1729  {
1730  //
1731  // error occured
1732  //
1733  DPRINT1("Found halted queue head %p\n", QueueHead);
1734  DumpQueueHead(QueueHead);
1735  //ASSERT(FALSE);
1736  return TRUE;
1737  }
1738 
1739  //
1740  // loop list and see if there are any active descriptors
1741  //
1742  Entry = QueueHead->TransferDescriptorListHead.Flink;
1743  while(Entry != &QueueHead->TransferDescriptorListHead)
1744  {
1745  //
1746  // obtain descriptor from entry
1747  //
1749  ASSERT(Descriptor);
1750  if (Descriptor->Token.Bits.Active)
1751  {
1752  //
1753  // descriptor is still active
1754  //
1755  return FALSE;
1756  }
1757 
1758  //
1759  // move to next entry
1760  //
1761  Entry = Entry->Flink;
1762  }
1763 
1764  DPRINT("QueueHead %p Addr %x is complete\n", QueueHead, QueueHead->PhysicalAddr);
1765 
1766  //
1767  // no active descriptors found, queue head is finished
1768  //
1769  return TRUE;
1770 }
1771 
1772 //-----------------------------------------------------------------------------------------
1773 ULONG
1775 {
1776  if (!m_Irp)
1777  {
1778  //
1779  // FIXME: get length for control request
1780  //
1781  return m_TransferBufferLength;
1782  }
1783 
1784  //
1785  // sanity check
1786  //
1789  {
1790  //
1791  // bulk in request
1792  // HACK: Properly determine transfer length
1793  //
1794  return m_TransferBufferLength;//m_TotalBytesTransferred;
1795  }
1796 
1797  //
1798  // bulk out transfer
1799  //
1800  return m_TransferBufferLength;
1801 }
1802 
1804 CUSBRequest::GetSpeed()
1805 {
1806  return m_Speed;
1807 }
1808 
1809 UCHAR
1810 CUSBRequest::GetInterval()
1811 {
1812  if (!m_EndpointDescriptor)
1813  return 0;
1814 
1816 }
1817 
1818 //-----------------------------------------------------------------------------------------
1819 NTSTATUS
1820 NTAPI
1822  PUSBREQUEST *OutRequest)
1823 {
1824  PUSBREQUEST This;
1825 
1826  //
1827  // allocate requests
1828  //
1830  if (!This)
1831  {
1832  //
1833  // failed to allocate
1834  //
1836  }
1837 
1838  //
1839  // add reference count
1840  //
1841  This->AddRef();
1842 
1843  //
1844  // return result
1845  //
1846  *OutRequest = (PUSBREQUEST)This;
1847 
1848  //
1849  // done
1850  //
1851  return STATUS_SUCCESS;
1852 }
ULONG m_TransferBufferLength
Definition: usb_request.cpp:78
PUSB_ENDPOINT m_EndpointDescriptor
ULONG m_TransferBufferLengthCompleted
Definition: usb_request.cpp:83
IMP_IUSBREQUEST IMP_IEHCIREQUEST ULONG InternalGetTransferType()
NTSTATUS BuildSetupPacketFromURB()
ULONG AlternateNextPointer
Definition: hardware.h:208
#define IN
Definition: typedefs.h:38
STDMETHODIMP_(ULONG) AddRef()
Definition: usb_request.cpp:21
#define PID_CODE_IN_TOKEN
Definition: hardware.h:97
#define REFIID
Definition: guiddef.h:113
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
struct _KEVENT * PKEVENT
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define PC_ASSERT(exp)
Definition: usbehci.h:17
_In_ PIRP _In_ PDEVICE_OBJECT Device
Definition: fatprocs.h:2020
#define USB_ENDPOINT_DIRECTION_IN(x)
Definition: usb100.h:76
#define URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE
Definition: usb.h:103
struct _Entry Entry
Definition: kefuncs.h:640
#define IOCTL_INTERNAL_USB_SUBMIT_URB
Definition: usbioctl.h:32
_In_ BOOLEAN Release
Definition: classpnp.h:929
NTSTATUS STDMETHODCALLTYPE BuildTransferDescriptorChain(IN PQUEUE_HEAD QueueHead, IN PVOID TransferBuffer, IN ULONG TransferBufferLength, IN UCHAR PidCode, IN UCHAR InitialDataToggle, OUT PQUEUE_TRANSFER_DESCRIPTOR *OutFirstDescriptor, OUT PQUEUE_TRANSFER_DESCRIPTOR *OutLastDescriptor, OUT PUCHAR OutDataToggle, OUT PULONG OutTransferBufferOffset)
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
#define MmGetMdlVirtualAddress(_Mdl)
VOID STDMETHODCALLTYPE InitDescriptor(IN PQUEUE_TRANSFER_DESCRIPTOR CurrentDescriptor, IN PVOID TransferBuffer, IN ULONG TransferBufferLength, IN UCHAR PidCode, IN UCHAR DataToggle, OUT PULONG OutDescriptorLength)
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
ULONG NextPointer
Definition: hardware.h:206
#define USB_REQUEST_SET_INTERFACE
Definition: usb100.h:87
END_POINT_CHARACTERISTICS EndPointCharacteristics
Definition: hardware.h:201
unsigned char * PUCHAR
Definition: retypes.h:3
union _USB_DEFAULT_PIPE_SETUP_PACKET::_wIndex wIndex
USB_ENDPOINT_DESCRIPTOR EndPointDescriptor
VOID NTAPI MmBuildMdlForNonPagedPool(IN PMDL Mdl)
Definition: mdlsup.c:428
PVOID Request
Definition: hardware.h:223
LONG NTSTATUS
Definition: precomp.h:26
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2327
NTSTATUS BuildSetupPacket()
UCHAR STDMETHODCALLTYPE GetDeviceAddress()
QETD_TOKEN_BITS Bits
Definition: hardware.h:212
struct _QUEUE_TRANSFER_DESCRIPTOR * PQUEUE_TRANSFER_DESCRIPTOR
#define USB_ENDPOINT_TYPE_CONTROL
Definition: usb100.h:62
union _QUEUE_TRANSFER_DESCRIPTOR::@1276 Token
#define InsertTailList(ListHead, Entry)
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define IMP_IEHCIREQUEST
Definition: interfaces.h:91
#define USB_REQUEST_GET_CONFIGURATION
Definition: usb100.h:84
#define USB_ENDPOINT_DIRECTION_MASK
Definition: usb100.h:73
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
LIST_ENTRY DescriptorEntry
Definition: hardware.h:152
union _QUEUE_HEAD::@1277 Token
uint32_t ULONG_PTR
Definition: typedefs.h:63
IUSBDevice * PUSBDEVICE
#define IMP_IUSBREQUEST
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT
Definition: usb.h:104
long LONG
Definition: pedump.c:60
CUSBRequest(IUnknown *OuterUnknown)
VOID DumpQueueHead(IN PQUEUE_HEAD QueueHead)
_In_ ULONG BufferLength
Definition: usbdlib.h:225
ULONG InterruptOnComplete
Definition: hardware.h:129
#define URB_FUNCTION_GET_INTERFACE
Definition: usb.h:125
PKEVENT m_CompletionEvent
#define STDMETHODIMP
Definition: basetyps.h:43
#define QH_ENDPOINT_HIGHSPEED
Definition: hardware.h:163
unsigned char BOOLEAN
PHYSICAL_ADDRESS m_DescriptorSetupPacket
smooth NULL
Definition: ftsmooth.c:416
static WCHAR Address[46]
Definition: ping.c:68
#define IoCompleteRequest
Definition: irp.c:1240
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
UCHAR InternalGetPidDirection()
void DPRINT(...)
Definition: polytest.cpp:61
#define URB_FUNCTION_SET_FEATURE_TO_ENDPOINT
Definition: usb.h:101
#define URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE
Definition: usb.h:127
#define URB_FUNCTION_SET_FEATURE_TO_DEVICE
Definition: usb.h:99
switch(r->id)
Definition: btrfs.c:2711
void * PVOID
Definition: retypes.h:9
PDMAMEMORYMANAGER m_DmaManager
Definition: usb_request.cpp:68
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
#define URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL
Definition: usb.h:116
#define URB_FUNCTION_GET_STATUS_FROM_INTERFACE
Definition: usb.h:106
enum _USB_DEVICE_SPEED USB_DEVICE_SPEED
#define USB_REQUEST_SET_CONFIGURATION
Definition: usb100.h:85
STDMETHODIMP QueryInterface(REFIID InterfaceId, PVOID *Interface)
LIST_ENTRY TransferDescriptorListHead
Definition: hardware.h:221
#define USB_ENDPOINT_TYPE_MASK
Definition: usb100.h:61
PUSB_DEFAULT_PIPE_SETUP_PACKET m_DescriptorPacket
struct _URB_HEADER UrbHeader
Definition: usb.h:531
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
IN PVOID IN PVOID IN USHORT IN USHORT IN PINTERFACE Interface
Definition: pci.h:359
struct _USB_ENDPOINT * PUSB_ENDPOINT
ULONG ExtendedBufferPointer[5]
Definition: hardware.h:148
if(!(yy_init))
Definition: macro.lex.yy.c:714
ULONG TotalBytesToTransfer
Definition: hardware.h:130
NTSTATUS BuildControlTransferQueueHead(PQUEUE_HEAD *OutHead)
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS BuildBulkInterruptTransferQueueHead(PQUEUE_HEAD *OutHead)
#define URB_FUNCTION_GET_STATUS_FROM_ENDPOINT
Definition: usb.h:107
NTSTATUS STDMETHODCALLTYPE CreateDescriptor(PQUEUE_TRANSFER_DESCRIPTOR *OutDescriptor)
static const UCHAR Index[8]
Definition: usbohci.c:18
#define STDMETHODCALLTYPE
Definition: bdasup.h:9
#define URB_FUNCTION_GET_CONFIGURATION
Definition: usb.h:124
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
struct _USB_DEFAULT_PIPE_SETUP_PACKET USB_DEFAULT_PIPE_SETUP_PACKET
#define USB_ENDPOINT_TYPE_ISOCHRONOUS
Definition: usb100.h:63
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
PUSB_DEFAULT_PIPE_SETUP_PACKET m_SetupPacket
Definition: usb_request.cpp:98
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define USB_REQUEST_GET_DESCRIPTOR
Definition: usb100.h:82
unsigned char UCHAR
Definition: xmlstorage.h:181
NTSTATUS CreateQueueHead(PQUEUE_HEAD *OutQueueHead)
#define URB_FUNCTION_SELECT_CONFIGURATION
Definition: usb.h:86
#define InterlockedDecrement
Definition: armddk.h:52
Definition: arc.h:85
ULONG PhysicalAddr
Definition: hardware.h:219
#define PID_CODE_SETUP_TOKEN
Definition: hardware.h:98
ULONG LowPart
Definition: typedefs.h:104
ULONG DataToggle
Definition: hardware.h:131
#define PAGE_SIZE
Definition: env_spec_w32.h:49
Definition: typedefs.h:117
#define URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE
Definition: usb.h:97
#define USB_ENDPOINT_TYPE_BULK
Definition: usb100.h:64
#define TERMINATE_POINTER
Definition: hardware.h:87
PQUEUE_HEAD m_QueueHead
#define URB_FUNCTION_SELECT_INTERFACE
Definition: usb.h:87
struct _URB * PURB
PMDL m_TransferBufferMDL
Definition: usb_request.cpp:93
#define TAG_USBEHCI
Definition: usbehci.h:12
Status
Definition: gdiplustypes.h:24
UCHAR m_DeviceAddress
PMDL NTAPI IoAllocateMdl(IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN PIRP Irp)
Definition: iomdl.c:22
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
struct _URB_SELECT_CONFIGURATION UrbSelectConfiguration
Definition: usb.h:533
#define USB_REQUEST_GET_STATUS
Definition: usb100.h:78
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
ULONG InternalCalculateTransferLength()
#define InterlockedIncrement
Definition: armddk.h:53
USB_DEVICE_SPEED m_Speed
#define URB_FUNCTION_SET_FEATURE_TO_INTERFACE
Definition: usb.h:100
Definition: usb.h:529
#define ROUND_TO_PAGES(Size)
unsigned short USHORT
Definition: pedump.c:61
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
IUSBRequest * PUSBREQUEST
#define URB_FUNCTION_CLASS_INTERFACE
Definition: usb.h:113
#define URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT
Definition: usb.h:123
STDMETHODIMP_(ULONG) Release()
Definition: usb_request.cpp:26
#define USB_REQUEST_SET_FEATURE
Definition: usb100.h:80
ULONG m_TotalBytesTransferred
Definition: usb_request.cpp:88
unsigned int * PULONG
Definition: retypes.h:1
#define min(a, b)
Definition: monoChain.cc:55
#define URB_FUNCTION_GET_STATUS_FROM_DEVICE
Definition: usb.h:105
IDMAMemoryManager * PDMAMEMORYMANAGER
static ULONG WINAPI AddRef(IStream *iface)
Definition: clist.c:90
#define DPRINT1
Definition: precomp.h:8
virtual ~CUSBRequest()
NTSTATUS NTAPI InternalCreateUSBRequest(PUSBREQUEST *OutRequest)
union _USB_DEFAULT_PIPE_SETUP_PACKET::_wValue wValue
#define OUT
Definition: typedefs.h:39
NTSTATUS m_NtStatusCode
struct _URB_BULK_OR_INTERRUPT_TRANSFER UrbBulkOrInterruptTransfer
Definition: usb.h:543
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:565
#define URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE
Definition: usb.h:98
#define UNIMPLEMENTED
Definition: debug.h:114
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
PHYSICAL_ADDRESS NTAPI MmGetPhysicalAddress(IN PVOID Address)
Definition: stubs.c:682
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
struct _URB_CONTROL_DESCRIPTOR_REQUEST UrbControlDescriptorRequest
Definition: usb.h:545
const TCHAR * CompletionCallback(unsigned __int64 &rnIndex, const BOOL *pblnForward, const TCHAR *pszContext, const TCHAR *pszBegin)
Definition: Completion.cpp:439
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
#define URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE
Definition: usb.h:102
return STATUS_SUCCESS
Definition: btrfs.c:2745
BM_REQUEST_TYPE bmRequestType
Definition: usb200.h:72
ULONG CurrentLinkPointer
Definition: hardware.h:204
ULONG m_UrbStatusCode
struct _URB_CONTROL_GET_STATUS_REQUEST UrbControlGetStatusRequest
Definition: usb.h:546
#define BYTE_OFFSET(Va)
base of all file and directory entries
Definition: entries.h:82
QETD_TOKEN_BITS Bits
Definition: hardware.h:144
#define URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER
Definition: usb.h:95
struct _URB_SELECT_INTERFACE UrbSelectInterface
Definition: usb.h:532
#define USB_ENDPOINT_TYPE_INTERRUPT
Definition: usb100.h:65
_In_ PSTORAGE_PROPERTY_ID _Outptr_ PSTORAGE_DESCRIPTOR_HEADER * Descriptor
Definition: classpnp.h:966
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68