ReactOS  0.4.15-dev-3748-g6a496c3
usbehci.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS USB EHCI Miniport Driver
3  * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE: USBEHCI main driver functions
5  * COPYRIGHT: Copyright 2017-2018 Vadim Galyant <vgal@rambler.ru>
6  */
7 
8 #include "usbehci.h"
9 
10 #define NDEBUG
11 #include <debug.h>
12 
13 #define NDEBUG_EHCI_TRACE
14 #include "dbg_ehci.h"
15 
17 
18 static const UCHAR ClassicPeriod[8] = {
27 };
28 
29 static const EHCI_PERIOD pTable[] = {
30  { ENDPOINT_INTERRUPT_1ms, 0x00, 0xFF },
31  { ENDPOINT_INTERRUPT_2ms, 0x00, 0x55 },
32  { ENDPOINT_INTERRUPT_2ms, 0x00, 0xAA },
33  { ENDPOINT_INTERRUPT_4ms, 0x00, 0x11 },
34  { ENDPOINT_INTERRUPT_4ms, 0x00, 0x44 },
35  { ENDPOINT_INTERRUPT_4ms, 0x00, 0x22 },
36  { ENDPOINT_INTERRUPT_4ms, 0x00, 0x88 },
37  { ENDPOINT_INTERRUPT_8ms, 0x00, 0x01 },
38  { ENDPOINT_INTERRUPT_8ms, 0x00, 0x10 },
39  { ENDPOINT_INTERRUPT_8ms, 0x00, 0x04 },
40  { ENDPOINT_INTERRUPT_8ms, 0x00, 0x40 },
41  { ENDPOINT_INTERRUPT_8ms, 0x00, 0x02 },
42  { ENDPOINT_INTERRUPT_8ms, 0x00, 0x20 },
43  { ENDPOINT_INTERRUPT_8ms, 0x00, 0x08 },
44  { ENDPOINT_INTERRUPT_8ms, 0x00, 0x80 },
45  { ENDPOINT_INTERRUPT_16ms, 0x01, 0x01 },
46  { ENDPOINT_INTERRUPT_16ms, 0x02, 0x01 },
47  { ENDPOINT_INTERRUPT_16ms, 0x01, 0x10 },
48  { ENDPOINT_INTERRUPT_16ms, 0x02, 0x10 },
49  { ENDPOINT_INTERRUPT_16ms, 0x01, 0x04 },
50  { ENDPOINT_INTERRUPT_16ms, 0x02, 0x04 },
51  { ENDPOINT_INTERRUPT_16ms, 0x01, 0x40 },
52  { ENDPOINT_INTERRUPT_16ms, 0x02, 0x40 },
53  { ENDPOINT_INTERRUPT_16ms, 0x01, 0x02 },
54  { ENDPOINT_INTERRUPT_16ms, 0x02, 0x02 },
55  { ENDPOINT_INTERRUPT_16ms, 0x01, 0x20 },
56  { ENDPOINT_INTERRUPT_16ms, 0x02, 0x20 },
57  { ENDPOINT_INTERRUPT_16ms, 0x01, 0x08 },
58  { ENDPOINT_INTERRUPT_16ms, 0x02, 0x08 },
59  { ENDPOINT_INTERRUPT_16ms, 0x01, 0x80 },
60  { ENDPOINT_INTERRUPT_16ms, 0x02, 0x80 },
61  { ENDPOINT_INTERRUPT_32ms, 0x03, 0x01 },
62  { ENDPOINT_INTERRUPT_32ms, 0x05, 0x01 },
63  { ENDPOINT_INTERRUPT_32ms, 0x04, 0x01 },
64  { ENDPOINT_INTERRUPT_32ms, 0x06, 0x01 },
65  { ENDPOINT_INTERRUPT_32ms, 0x03, 0x10 },
66  { ENDPOINT_INTERRUPT_32ms, 0x05, 0x10 },
67  { ENDPOINT_INTERRUPT_32ms, 0x04, 0x10 },
68  { ENDPOINT_INTERRUPT_32ms, 0x06, 0x10 },
69  { ENDPOINT_INTERRUPT_32ms, 0x03, 0x04 },
70  { ENDPOINT_INTERRUPT_32ms, 0x05, 0x04 },
71  { ENDPOINT_INTERRUPT_32ms, 0x04, 0x04 },
72  { ENDPOINT_INTERRUPT_32ms, 0x06, 0x04 },
73  { ENDPOINT_INTERRUPT_32ms, 0x03, 0x40 },
74  { ENDPOINT_INTERRUPT_32ms, 0x05, 0x40 },
75  { ENDPOINT_INTERRUPT_32ms, 0x04, 0x40 },
76  { ENDPOINT_INTERRUPT_32ms, 0x06, 0x40 },
77  { ENDPOINT_INTERRUPT_32ms, 0x03, 0x02 },
78  { ENDPOINT_INTERRUPT_32ms, 0x05, 0x02 },
79  { ENDPOINT_INTERRUPT_32ms, 0x04, 0x02 },
80  { ENDPOINT_INTERRUPT_32ms, 0x06, 0x02 },
81  { ENDPOINT_INTERRUPT_32ms, 0x03, 0x20 },
82  { ENDPOINT_INTERRUPT_32ms, 0x05, 0x20 },
83  { ENDPOINT_INTERRUPT_32ms, 0x04, 0x20 },
84  { ENDPOINT_INTERRUPT_32ms, 0x06, 0x20 },
85  { ENDPOINT_INTERRUPT_32ms, 0x03, 0x08 },
86  { ENDPOINT_INTERRUPT_32ms, 0x05, 0x08 },
87  { ENDPOINT_INTERRUPT_32ms, 0x04, 0x08 },
88  { ENDPOINT_INTERRUPT_32ms, 0x06, 0x08 },
89  { ENDPOINT_INTERRUPT_32ms, 0x03, 0x80 },
90  { ENDPOINT_INTERRUPT_32ms, 0x05, 0x80 },
91  { ENDPOINT_INTERRUPT_32ms, 0x04, 0x80 },
92  { ENDPOINT_INTERRUPT_32ms, 0x06, 0x80 },
93  { 0x00, 0x00, 0x00 }
94 };
96 
97 static const UCHAR Balance[] = {
98  0, 16, 8, 24, 4, 20, 12, 28, 2, 18, 10, 26, 6, 22, 14, 30,
99  1, 17, 9, 25, 5, 21, 13, 29, 3, 19, 11, 27, 7, 23, 15, 31
100 };
102 
103 static const UCHAR LinkTable[] = {
104  255, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,
105  10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19,
106  20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29,
107  30, 30, 0
108 };
110 
112 NTAPI
114  IN PEHCI_ENDPOINT EhciEndpoint)
115 {
116  PEHCI_HCD_TD TD;
117  ULONG ix;
118 
119  DPRINT_EHCI("EHCI_AllocTd: ... \n");
120 
121  if (EhciEndpoint->MaxTDs == 0)
122  {
123  RegPacket.UsbPortBugCheck(EhciExtension);
124  return NULL;
125  }
126 
127  TD = EhciEndpoint->FirstTD;
128 
129  for (ix = 1; TD->TdFlags & EHCI_HCD_TD_FLAG_ALLOCATED; ix++)
130  {
131  TD += 1;
132 
133  if (ix >= EhciEndpoint->MaxTDs)
134  {
135  RegPacket.UsbPortBugCheck(EhciExtension);
136  return NULL;
137  }
138  }
139 
141 
142  EhciEndpoint->RemainTDs--;
143 
144  return TD;
145 }
146 
148 NTAPI
150  IN PEHCI_ENDPOINT EhciEndpoint,
151  IN PEHCI_HCD_QH QH,
152  IN ULONG QhPA)
153 {
154  PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties;
156 
157  DPRINT_EHCI("EHCI_InitializeQH: EhciEndpoint - %p, QH - %p, QhPA - %p\n",
158  EhciEndpoint,
159  QH,
160  QhPA);
161 
162  EndpointProperties = &EhciEndpoint->EndpointProperties;
163 
164  RtlZeroMemory(QH, sizeof(EHCI_HCD_QH));
165 
166  ASSERT((QhPA & ~LINK_POINTER_MASK) == 0);
167 
168  QH->sqh.PhysicalAddress = QhPA;
169 
170  QH->sqh.HwQH.EndpointParams.DeviceAddress = EndpointProperties->DeviceAddress;
171  QH->sqh.HwQH.EndpointParams.EndpointNumber = EndpointProperties->EndpointAddress;
172 
173  DeviceSpeed = EndpointProperties->DeviceSpeed;
174 
175  switch (DeviceSpeed)
176  {
177  case UsbLowSpeed:
178  QH->sqh.HwQH.EndpointParams.EndpointSpeed = EHCI_QH_EP_LOW_SPEED;
179  break;
180 
181  case UsbFullSpeed:
182  QH->sqh.HwQH.EndpointParams.EndpointSpeed = EHCI_QH_EP_FULL_SPEED;
183  break;
184 
185  case UsbHighSpeed:
186  QH->sqh.HwQH.EndpointParams.EndpointSpeed = EHCI_QH_EP_HIGH_SPEED;
187  break;
188 
189  default:
190  DPRINT1("EHCI_InitializeQH: Unknown DeviceSpeed - %x\n", DeviceSpeed);
191  ASSERT(FALSE);
192  break;
193  }
194 
195  QH->sqh.HwQH.EndpointParams.MaximumPacketLength = EndpointProperties->MaxPacketSize;
196  QH->sqh.HwQH.EndpointCaps.PipeMultiplier = 1;
197 
198  if (DeviceSpeed == UsbHighSpeed)
199  {
200  QH->sqh.HwQH.EndpointCaps.HubAddr = 0;
201  QH->sqh.HwQH.EndpointCaps.PortNumber = 0;
202  }
203  else
204  {
205  QH->sqh.HwQH.EndpointCaps.HubAddr = EndpointProperties->HubAddr;
206  QH->sqh.HwQH.EndpointCaps.PortNumber = EndpointProperties->PortNumber;
207 
208  if (EndpointProperties->TransferType == USBPORT_TRANSFER_TYPE_CONTROL)
209  QH->sqh.HwQH.EndpointParams.ControlEndpointFlag = 1;
210  }
211 
212  QH->sqh.HwQH.NextTD = TERMINATE_POINTER;
213  QH->sqh.HwQH.AlternateNextTD = TERMINATE_POINTER;
214 
215  QH->sqh.HwQH.Token.Status &= (UCHAR)~(EHCI_TOKEN_STATUS_ACTIVE |
217 
218  return QH;
219 }
220 
221 MPSTATUS
222 NTAPI
224  IN PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties,
225  IN PEHCI_ENDPOINT EhciEndpoint,
226  IN BOOLEAN IsControl)
227 {
228  PEHCI_HCD_QH QH;
229  ULONG QhPA;
230  PEHCI_HCD_TD TdVA;
231  ULONG TdPA;
232  PEHCI_HCD_TD TD;
233  ULONG TdCount;
234  ULONG ix;
235 
236  DPRINT("EHCI_OpenBulkOrControlEndpoint: EhciEndpoint - %p, IsControl - %x\n",
237  EhciEndpoint,
238  IsControl);
239 
240  InitializeListHead(&EhciEndpoint->ListTDs);
241 
242  EhciEndpoint->DmaBufferVA = (PVOID)EndpointProperties->BufferVA;
243  EhciEndpoint->DmaBufferPA = EndpointProperties->BufferPA;
244 
245  RtlZeroMemory(EhciEndpoint->DmaBufferVA, sizeof(EHCI_HCD_TD));
246 
247  QH = (PEHCI_HCD_QH)EhciEndpoint->DmaBufferVA + 1;
248  QhPA = EhciEndpoint->DmaBufferPA + sizeof(EHCI_HCD_TD);
249 
250  EhciEndpoint->FirstTD = (PEHCI_HCD_TD)(QH + 1);
251 
252  TdCount = (EndpointProperties->BufferLength -
253  (sizeof(EHCI_HCD_TD) + sizeof(EHCI_HCD_QH))) /
254  sizeof(EHCI_HCD_TD);
255 
256  if (EndpointProperties->TransferType == USBPORT_TRANSFER_TYPE_CONTROL)
257  EhciEndpoint->EndpointStatus |= USBPORT_ENDPOINT_CONTROL;
258 
259  EhciEndpoint->MaxTDs = TdCount;
260  EhciEndpoint->RemainTDs = TdCount;
261 
262  TdVA = EhciEndpoint->FirstTD;
263  TdPA = QhPA + sizeof(EHCI_HCD_QH);
264 
265  for (ix = 0; ix < TdCount; ix++)
266  {
267  DPRINT_EHCI("EHCI_OpenBulkOrControlEndpoint: TdVA - %p, TdPA - %p\n",
268  TdVA,
269  TdPA);
270 
271  RtlZeroMemory(TdVA, sizeof(EHCI_HCD_TD));
272 
273  ASSERT((TdPA & ~LINK_POINTER_MASK) == 0);
274 
275  TdVA->PhysicalAddress = TdPA;
276  TdVA->EhciEndpoint = EhciEndpoint;
277  TdVA->EhciTransfer = NULL;
278 
279  TdPA += sizeof(EHCI_HCD_TD);
280  TdVA += 1;
281  }
282 
283  EhciEndpoint->QH = EHCI_InitializeQH(EhciExtension,
284  EhciEndpoint,
285  QH,
286  QhPA);
287 
288  if (IsControl)
289  {
291  EhciEndpoint->HcdHeadP = NULL;
292  }
293  else
294  {
296  }
297 
298  TD = EHCI_AllocTd(EhciExtension, EhciEndpoint);
299 
300  if (!TD)
301  return MP_STATUS_NO_RESOURCES;
302 
305 
308 
309  TD->NextHcdTD = NULL;
310  TD->AltNextHcdTD = NULL;
311 
312  EhciEndpoint->HcdTailP = TD;
313  EhciEndpoint->HcdHeadP = TD;
314 
315  QH->sqh.HwQH.CurrentTD = TD->PhysicalAddress;
318 
320  QH->sqh.HwQH.Token.TransferBytes = 0;
321 
322  return MP_STATUS_SUCCESS;
323 }
324 
325 MPSTATUS
326 NTAPI
328  IN PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties,
329  IN PEHCI_ENDPOINT EhciEndpoint)
330 {
331  PEHCI_HCD_QH QH;
332  ULONG QhPA;
333  PEHCI_HCD_TD FirstTD;
334  ULONG FirstTdPA;
335  PEHCI_HCD_TD TD;
336  PEHCI_HCD_TD DummyTD;
337  ULONG TdCount;
338  ULONG ix;
339  const EHCI_PERIOD * PeriodTable = NULL;
340  ULONG ScheduleOffset;
341  ULONG Idx = 0;
342  UCHAR Period;
343 
344  DPRINT("EHCI_OpenInterruptEndpoint: EhciExtension - %p, EndpointProperties - %p, EhciEndpoint - %p\n",
345  EhciExtension,
346  EndpointProperties,
347  EhciEndpoint);
348 
349  Period = EndpointProperties->Period;
350  ScheduleOffset = EndpointProperties->ScheduleOffset;
351 
353 
354  while (!(Period & 1))
355  {
356  Idx++;
357  Period >>= 1;
358  }
359 
360  ASSERT(Idx < 8);
361 
362  InitializeListHead(&EhciEndpoint->ListTDs);
363 
364  if (EhciEndpoint->EndpointProperties.DeviceSpeed == UsbHighSpeed)
365  {
366  PeriodTable = &pTable[ClassicPeriod[Idx] + ScheduleOffset];
367  EhciEndpoint->PeriodTable = PeriodTable;
368 
369  DPRINT("EHCI_OpenInterruptEndpoint: EhciEndpoint - %p, ScheduleMask - %X, Index - %X\n",
370  EhciEndpoint,
371  PeriodTable->ScheduleMask,
372  ClassicPeriod[Idx]);
373 
374  EhciEndpoint->StaticQH = EhciExtension->PeriodicHead[PeriodTable->PeriodIdx];
375  }
376  else
377  {
378  EhciEndpoint->PeriodTable = NULL;
379 
380  DPRINT("EHCI_OpenInterruptEndpoint: EhciEndpoint - %p, Index - %X\n",
381  EhciEndpoint,
382  ClassicPeriod[Idx]);
383 
384  EhciEndpoint->StaticQH = EhciExtension->PeriodicHead[ClassicPeriod[Idx] +
385  ScheduleOffset];
386  }
387 
388  EhciEndpoint->DmaBufferVA = (PVOID)EndpointProperties->BufferVA;
389  EhciEndpoint->DmaBufferPA = EndpointProperties->BufferPA;
390 
391  RtlZeroMemory((PVOID)EndpointProperties->BufferVA, sizeof(EHCI_HCD_TD));
392 
393  QH = (PEHCI_HCD_QH)(EndpointProperties->BufferVA + sizeof(EHCI_HCD_TD));
394  QhPA = EndpointProperties->BufferPA + sizeof(EHCI_HCD_TD);
395 
396  FirstTD = (PEHCI_HCD_TD)(EndpointProperties->BufferVA +
397  sizeof(EHCI_HCD_TD) +
398  sizeof(EHCI_HCD_QH));
399 
400  FirstTdPA = EndpointProperties->BufferPA +
401  sizeof(EHCI_HCD_TD) +
402  sizeof(EHCI_HCD_QH);
403 
404  TdCount = (EndpointProperties->BufferLength -
405  (sizeof(EHCI_HCD_TD) + sizeof(EHCI_HCD_QH))) /
406  sizeof(EHCI_HCD_TD);
407 
408  ASSERT(TdCount >= EHCI_MAX_INTERRUPT_TD_COUNT + 1);
409 
410  EhciEndpoint->FirstTD = FirstTD;
411  EhciEndpoint->MaxTDs = TdCount;
412 
413  for (ix = 0; ix < TdCount; ix++)
414  {
415  TD = EhciEndpoint->FirstTD + ix;
416 
417  RtlZeroMemory(TD, sizeof(EHCI_HCD_TD));
418 
419  ASSERT((FirstTdPA & ~LINK_POINTER_MASK) == 0);
420 
421  TD->PhysicalAddress = FirstTdPA;
422  TD->EhciEndpoint = EhciEndpoint;
423  TD->EhciTransfer = NULL;
424 
425  FirstTdPA += sizeof(EHCI_HCD_TD);
426  }
427 
428  EhciEndpoint->RemainTDs = TdCount;
429 
430  EhciEndpoint->QH = EHCI_InitializeQH(EhciExtension,
431  EhciEndpoint,
432  QH,
433  QhPA);
434 
435  if (EhciEndpoint->EndpointProperties.DeviceSpeed == UsbHighSpeed)
436  {
437  QH->sqh.HwQH.EndpointCaps.InterruptMask = PeriodTable->ScheduleMask;
438  }
439  else
440  {
442  EndpointProperties->InterruptScheduleMask;
443 
445  EndpointProperties->SplitCompletionMask;
446  }
447 
448  DummyTD = EHCI_AllocTd(EhciExtension, EhciEndpoint);
449 
450  DummyTD->TdFlags |= EHCI_HCD_TD_FLAG_DUMMY;
451  DummyTD->NextHcdTD = NULL;
452  DummyTD->AltNextHcdTD = NULL;
453 
455 
456  DummyTD->HwTD.NextTD = TERMINATE_POINTER;
458 
459  EhciEndpoint->HcdTailP = DummyTD;
460  EhciEndpoint->HcdHeadP = DummyTD;
461 
462  QH->sqh.HwQH.CurrentTD = DummyTD->PhysicalAddress;
465 
467  QH->sqh.HwQH.Token.TransferBytes = 0;
468 
469  return MP_STATUS_SUCCESS;
470 }
471 
472 MPSTATUS
473 NTAPI
475  IN PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties,
476  IN PEHCI_ENDPOINT EhciEndpoint)
477 {
478  DPRINT1("EHCI_OpenHsIsoEndpoint: UNIMPLEMENTED. FIXME\n");
480 }
481 
482 MPSTATUS
483 NTAPI
485  IN PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties,
486  IN PEHCI_ENDPOINT EhciEndpoint)
487 {
488  DPRINT1("EHCI_OpenIsoEndpoint: UNIMPLEMENTED. FIXME\n");
490 }
491 
492 MPSTATUS
493 NTAPI
494 EHCI_OpenEndpoint(IN PVOID ehciExtension,
495  IN PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties,
496  IN PVOID ehciEndpoint)
497 {
498  PEHCI_EXTENSION EhciExtension = ehciExtension;
499  PEHCI_ENDPOINT EhciEndpoint = ehciEndpoint;
500  ULONG TransferType;
501  MPSTATUS MPStatus;
502 
503  DPRINT("EHCI_OpenEndpoint: ... \n");
504 
505  RtlCopyMemory(&EhciEndpoint->EndpointProperties,
506  EndpointProperties,
507  sizeof(EhciEndpoint->EndpointProperties));
508 
509  TransferType = EndpointProperties->TransferType;
510 
511  switch (TransferType)
512  {
514  if (EndpointProperties->DeviceSpeed == UsbHighSpeed)
515  {
516  MPStatus = EHCI_OpenHsIsoEndpoint(EhciExtension,
517  EndpointProperties,
518  EhciEndpoint);
519  }
520  else
521  {
522  MPStatus = EHCI_OpenIsoEndpoint(EhciExtension,
523  EndpointProperties,
524  EhciEndpoint);
525  }
526 
527  break;
528 
530  MPStatus = EHCI_OpenBulkOrControlEndpoint(EhciExtension,
531  EndpointProperties,
532  EhciEndpoint,
533  TRUE);
534  break;
535 
537  MPStatus = EHCI_OpenBulkOrControlEndpoint(EhciExtension,
538  EndpointProperties,
539  EhciEndpoint,
540  FALSE);
541  break;
542 
544  MPStatus = EHCI_OpenInterruptEndpoint(EhciExtension,
545  EndpointProperties,
546  EhciEndpoint);
547  break;
548 
549  default:
550  MPStatus = MP_STATUS_NOT_SUPPORTED;
551  break;
552  }
553 
554  return MPStatus;
555 }
556 
557 MPSTATUS
558 NTAPI
560  IN PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties,
561  IN PVOID ehciEndpoint)
562 {
563  PEHCI_ENDPOINT EhciEndpoint;
564  ULONG TransferType;
565  PEHCI_HCD_QH QH;
566  MPSTATUS MPStatus;
567 
568  EhciEndpoint = ehciEndpoint;
569 
570  TransferType = EndpointProperties->TransferType;
571 
572  DPRINT("EHCI_ReopenEndpoint: EhciEndpoint - %p, TransferType - %x\n",
573  EhciEndpoint,
574  TransferType);
575 
576  switch (TransferType)
577  {
579  if (EndpointProperties->DeviceSpeed == UsbHighSpeed)
580  {
581  DPRINT1("EHCI_ReopenEndpoint: HS Iso. UNIMPLEMENTED. FIXME\n");
582  MPStatus = MP_STATUS_NOT_SUPPORTED;
583  }
584  else
585  {
586  DPRINT1("EHCI_ReopenEndpoint: Iso. UNIMPLEMENTED. FIXME\n");
587  MPStatus = MP_STATUS_NOT_SUPPORTED;
588  }
589 
590  break;
591 
595  RtlCopyMemory(&EhciEndpoint->EndpointProperties,
596  EndpointProperties,
597  sizeof(EhciEndpoint->EndpointProperties));
598 
599  QH = EhciEndpoint->QH;
600 
601  QH->sqh.HwQH.EndpointParams.DeviceAddress = EndpointProperties->DeviceAddress;
602  QH->sqh.HwQH.EndpointParams.MaximumPacketLength = EndpointProperties->MaxPacketSize;
603 
604  QH->sqh.HwQH.EndpointCaps.HubAddr = EndpointProperties->HubAddr;
605 
606  MPStatus = MP_STATUS_SUCCESS;
607  break;
608 
609  default:
610  DPRINT1("EHCI_ReopenEndpoint: Unknown TransferType\n");
611  MPStatus = MP_STATUS_SUCCESS;
612  break;
613  }
614 
615  return MPStatus;
616 }
617 
618 VOID
619 NTAPI
621  IN PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties,
622  IN PUSBPORT_ENDPOINT_REQUIREMENTS EndpointRequirements)
623 {
624  ULONG TransferType;
625 
626  DPRINT("EHCI_QueryEndpointRequirements: ... \n");
627 
628  TransferType = EndpointProperties->TransferType;
629 
630  switch (TransferType)
631  {
633  DPRINT("EHCI_QueryEndpointRequirements: IsoTransfer\n");
634 
635  if (EndpointProperties->DeviceSpeed == UsbHighSpeed)
636  {
637  EndpointRequirements->HeaderBufferSize = EHCI_MAX_HS_ISO_HEADER_BUFFER_SIZE;
638  EndpointRequirements->MaxTransferSize = EHCI_MAX_HS_ISO_TRANSFER_SIZE;
639  }
640  else
641  {
642  EndpointRequirements->HeaderBufferSize = EHCI_MAX_FS_ISO_HEADER_BUFFER_SIZE;
643  EndpointRequirements->MaxTransferSize = EHCI_MAX_FS_ISO_TRANSFER_SIZE;
644  }
645  break;
646 
648  DPRINT("EHCI_QueryEndpointRequirements: ControlTransfer\n");
649  EndpointRequirements->HeaderBufferSize = sizeof(EHCI_HCD_TD) +
650  sizeof(EHCI_HCD_QH) +
652 
653  EndpointRequirements->MaxTransferSize = EHCI_MAX_CONTROL_TRANSFER_SIZE;
654  break;
655 
657  DPRINT("EHCI_QueryEndpointRequirements: BulkTransfer\n");
658  EndpointRequirements->HeaderBufferSize = sizeof(EHCI_HCD_TD) +
659  sizeof(EHCI_HCD_QH) +
661 
662  EndpointRequirements->MaxTransferSize = EHCI_MAX_BULK_TRANSFER_SIZE;
663  break;
664 
666  DPRINT("EHCI_QueryEndpointRequirements: InterruptTransfer\n");
667  EndpointRequirements->HeaderBufferSize = sizeof(EHCI_HCD_TD) +
668  sizeof(EHCI_HCD_QH) +
670 
671  EndpointRequirements->MaxTransferSize = EHCI_MAX_INTERRUPT_TRANSFER_SIZE;
672  break;
673 
674  default:
675  DPRINT1("EHCI_QueryEndpointRequirements: Unknown TransferType - %x\n",
676  TransferType);
677  DbgBreakPoint();
678  break;
679  }
680 }
681 
682 VOID
683 NTAPI
685 {
686  PEHCI_HW_REGISTERS OperationalRegs;
688 
689  DPRINT("EHCI_DisablePeriodicList: ... \n");
690 
691  if (EhciExtension->Flags & EHCI_FLAGS_IDLE_SUPPORT)
692  {
693  OperationalRegs = EhciExtension->OperationalRegs;
694 
695  Command.AsULONG = READ_REGISTER_ULONG(&OperationalRegs->HcCommand.AsULONG);
696  Command.PeriodicEnable = 0;
697  WRITE_REGISTER_ULONG(&OperationalRegs->HcCommand.AsULONG, Command.AsULONG);
698  }
699 }
700 
701 VOID
702 NTAPI
704  IN PVOID ehciEndpoint,
705  IN BOOLEAN DisablePeriodic)
706 {
707  PEHCI_EXTENSION EhciExtension = ehciExtension;
708  PEHCI_ENDPOINT EhciEndpoint = ehciEndpoint;
709  ULONG TransferType;
710 
711  DPRINT1("EHCI_CloseEndpoint: EhciEndpoint - %p, DisablePeriodic - %X\n",
712  EhciEndpoint,
713  DisablePeriodic);
714 
715  if (DisablePeriodic)
716  {
717  TransferType = EhciEndpoint->EndpointProperties.TransferType;
718 
719  if (TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS ||
720  TransferType == USBPORT_TRANSFER_TYPE_INTERRUPT)
721  {
722  EHCI_DisablePeriodicList(EhciExtension);
723  }
724  }
725 }
726 
728 NTAPI
730  IN ULONG FrameIdx)
731 {
732  //DPRINT_EHCI("EHCI_GetQhForFrame: FrameIdx - %x, Balance[FrameIdx] - %x\n",
733  // FrameIdx,
734  // Balance[FrameIdx & 0x1F]);
735 
736  return EhciExtension->PeriodicHead[Balance[FrameIdx & (EHCI_FRAMES - 1)]];
737 }
738 
740 NTAPI
742  IN ULONG Idx)
743 {
744  return (PEHCI_HCD_QH)((ULONG_PTR)EhciExtension->IsoDummyQHListVA +
745  Idx * sizeof(EHCI_HCD_QH));
746 }
747 
748 VOID
749 NTAPI
754 {
755  ULONG PAddress;
756  ULONG NewPAddress;
757  ULONG_PTR VAddress;
758 
759  //DPRINT_EHCI("EHCI_AlignHwStructure: *PhysicalAddress - %X, *VirtualAddress - %X, Alignment - %x\n",
760  // *PhysicalAddress,
761  // *VirtualAddress,
762  // Alignment);
763 
764  PAddress = *PhysicalAddress;
765  VAddress = *VirtualAddress;
766 
767  NewPAddress = (ULONG)(ULONG_PTR)PAGE_ALIGN(*PhysicalAddress + Alignment - 1);
768 
769  if (NewPAddress != (ULONG)(ULONG_PTR)PAGE_ALIGN(*PhysicalAddress))
770  {
771  VAddress += NewPAddress - PAddress;
772  PAddress = NewPAddress;
773 
774  DPRINT("EHCI_AlignHwStructure: VAddress - %X, PAddress - %X\n",
775  VAddress,
776  PAddress);
777  }
778 
779  *VirtualAddress = VAddress;
780  *PhysicalAddress = PAddress;
781 }
782 
783 VOID
784 NTAPI
786 {
787  PEHCI_HC_RESOURCES HcResourcesVA;
788  PEHCI_HCD_QH DummyQH;
789  ULONG DummyQhPA;
790  EHCI_QH_EP_PARAMS EndpointParams;
791  EHCI_LINK_POINTER PAddress;
792  ULONG Frame;
793 
794  DPRINT("EHCI_AddDummyQueueHeads: EhciExtension - %p\n", EhciExtension);
795 
796  HcResourcesVA = EhciExtension->HcResourcesVA;
797 
798  DummyQH = EhciExtension->IsoDummyQHListVA;
799  DummyQhPA = EhciExtension->IsoDummyQHListPA;
800 
801  for (Frame = 0; Frame < EHCI_FRAME_LIST_MAX_ENTRIES; Frame++)
802  {
803  RtlZeroMemory(DummyQH, sizeof(EHCI_HCD_QH));
804 
805  PAddress.AsULONG = HcResourcesVA->PeriodicFrameList[Frame];
806 
807  DummyQH->sqh.HwQH.HorizontalLink.AsULONG = PAddress.AsULONG;
808  DummyQH->sqh.HwQH.CurrentTD = 0;
809  DummyQH->sqh.HwQH.NextTD = TERMINATE_POINTER;
811 
812  EndpointParams = DummyQH->sqh.HwQH.EndpointParams;
813  EndpointParams.DeviceAddress = 0;
814  EndpointParams.EndpointSpeed = 0;
816  DummyQH->sqh.HwQH.EndpointParams = EndpointParams;
817 
818  DummyQH->sqh.HwQH.EndpointCaps.AsULONG = 0;
819  DummyQH->sqh.HwQH.EndpointCaps.InterruptMask = 0;
821  DummyQH->sqh.HwQH.EndpointCaps.PipeMultiplier = 1;
822 
824 
825  DummyQH->sqh.PhysicalAddress = DummyQhPA;
826  DummyQH->sqh.StaticQH = EHCI_GetQhForFrame(EhciExtension, Frame);
827 
828  PAddress.AsULONG = DummyQhPA;
829  PAddress.Reserved = 0;
830  PAddress.Type = EHCI_LINK_TYPE_QH;
831 
832  HcResourcesVA->PeriodicFrameList[Frame] = PAddress.AsULONG;
833 
834  DummyQH++;
835  DummyQhPA += sizeof(EHCI_HCD_QH);
836  }
837 }
838 
839 VOID
840 NTAPI
842 {
843  PEHCI_STATIC_QH StaticQH;
844  ULONG ix;
845 
846  DPRINT("EHCI_InitializeInterruptSchedule: ... \n");
847 
848  for (ix = 0; ix < INTERRUPT_ENDPOINTs; ix++)
849  {
850  StaticQH = EhciExtension->PeriodicHead[ix];
851 
853  StaticQH->HwQH.NextTD |= TERMINATE_POINTER;
855  }
856 
857  for (ix = 1; ix < INTERRUPT_ENDPOINTs; ix++)
858  {
859  StaticQH = EhciExtension->PeriodicHead[ix];
860 
861  StaticQH->PrevHead = NULL;
862  StaticQH->NextHead = (PEHCI_HCD_QH)EhciExtension->PeriodicHead[LinkTable[ix]];
863 
864  StaticQH->HwQH.HorizontalLink.AsULONG =
865  EhciExtension->PeriodicHead[LinkTable[ix]]->PhysicalAddress;
866 
868  StaticQH->HwQH.EndpointCaps.InterruptMask = 0xFF;
869 
870  StaticQH->QhFlags |= EHCI_QH_FLAG_STATIC;
871 
872  if (ix < (ENDPOINT_INTERRUPT_8ms - 1))
873  StaticQH->QhFlags |= EHCI_QH_FLAG_STATIC_FAST;
874  }
875 
876  EhciExtension->PeriodicHead[0]->HwQH.HorizontalLink.Terminate = 1;
877 
878  EhciExtension->PeriodicHead[0]->QhFlags |= (EHCI_QH_FLAG_STATIC |
880 }
881 
882 MPSTATUS
883 NTAPI
885  IN ULONG_PTR BaseVA,
886  IN ULONG BasePA)
887 {
888  PEHCI_HW_REGISTERS OperationalRegs;
889  PEHCI_HC_RESOURCES HcResourcesVA;
890  ULONG HcResourcesPA;
891  PEHCI_STATIC_QH AsyncHead;
892  ULONG AsyncHeadPA;
893  PEHCI_STATIC_QH PeriodicHead;
894  ULONG PeriodicHeadPA;
895  PEHCI_STATIC_QH StaticQH;
896  EHCI_LINK_POINTER NextLink;
897  EHCI_LINK_POINTER StaticHeadPA;
898  ULONG Frame;
899  ULONG ix;
900 
901  DPRINT("EHCI_InitializeSchedule: BaseVA - %p, BasePA - %p\n",
902  BaseVA,
903  BasePA);
904 
905  OperationalRegs = EhciExtension->OperationalRegs;
906 
907  HcResourcesVA = (PEHCI_HC_RESOURCES)BaseVA;
908  HcResourcesPA = BasePA;
909 
910  EhciExtension->HcResourcesVA = HcResourcesVA;
911  EhciExtension->HcResourcesPA = BasePA;
912 
913  /* Asynchronous Schedule */
914 
915  AsyncHead = &HcResourcesVA->AsyncHead;
916  AsyncHeadPA = HcResourcesPA + FIELD_OFFSET(EHCI_HC_RESOURCES, AsyncHead);
917 
918  RtlZeroMemory(AsyncHead, sizeof(EHCI_STATIC_QH));
919 
920  NextLink.AsULONG = AsyncHeadPA;
921  NextLink.Type = EHCI_LINK_TYPE_QH;
922 
923  AsyncHead->HwQH.HorizontalLink = NextLink;
925  AsyncHead->HwQH.EndpointCaps.PipeMultiplier = 1;
926  AsyncHead->HwQH.NextTD |= TERMINATE_POINTER;
928 
929  AsyncHead->PhysicalAddress = AsyncHeadPA;
930  AsyncHead->PrevHead = AsyncHead->NextHead = (PEHCI_HCD_QH)AsyncHead;
931 
932  EhciExtension->AsyncHead = AsyncHead;
933 
934  /* Periodic Schedule */
935 
936  PeriodicHead = &HcResourcesVA->PeriodicHead[0];
937  PeriodicHeadPA = HcResourcesPA + FIELD_OFFSET(EHCI_HC_RESOURCES, PeriodicHead[0]);
938 
939  for (ix = 0; ix < (INTERRUPT_ENDPOINTs + 1); ix++)
940  {
941  EHCI_AlignHwStructure(EhciExtension,
942  &PeriodicHeadPA,
943  (PULONG_PTR)&PeriodicHead,
944  80);
945 
946  EhciExtension->PeriodicHead[ix] = PeriodicHead;
947  EhciExtension->PeriodicHead[ix]->PhysicalAddress = PeriodicHeadPA;
948 
949  PeriodicHead += 1;
950  PeriodicHeadPA += sizeof(EHCI_STATIC_QH);
951  }
952 
953  EHCI_InitializeInterruptSchedule(EhciExtension);
954 
955  for (Frame = 0; Frame < EHCI_FRAME_LIST_MAX_ENTRIES; Frame++)
956  {
957  StaticQH = EHCI_GetQhForFrame(EhciExtension, Frame);
958 
959  StaticHeadPA.AsULONG = StaticQH->PhysicalAddress;
960  StaticHeadPA.Type = EHCI_LINK_TYPE_QH;
961 
962  //DPRINT_EHCI("EHCI_InitializeSchedule: StaticHeadPA[%x] - %X\n",
963  // Frame,
964  // StaticHeadPA);
965 
966  HcResourcesVA->PeriodicFrameList[Frame] = StaticHeadPA.AsULONG;
967  }
968 
969  EhciExtension->IsoDummyQHListVA = &HcResourcesVA->IsoDummyQH[0];
970  EhciExtension->IsoDummyQHListPA = HcResourcesPA + FIELD_OFFSET(EHCI_HC_RESOURCES, IsoDummyQH[0]);
971 
972  EHCI_AddDummyQHs(EhciExtension);
973 
974  WRITE_REGISTER_ULONG(&OperationalRegs->PeriodicListBase,
975  EhciExtension->HcResourcesPA + FIELD_OFFSET(EHCI_HC_RESOURCES, PeriodicFrameList));
976 
977  WRITE_REGISTER_ULONG(&OperationalRegs->AsyncListBase,
978  NextLink.AsULONG);
979 
980  return MP_STATUS_SUCCESS;
981 }
982 
983 MPSTATUS
984 NTAPI
986 {
987  PEHCI_HC_CAPABILITY_REGISTERS CapabilityRegisters;
988  PEHCI_HW_REGISTERS OperationalRegs;
990  LARGE_INTEGER EndTime;
991  LARGE_INTEGER CurrentTime;
992  EHCI_HC_STRUCTURAL_PARAMS StructuralParams;
993 
994  DPRINT("EHCI_InitializeHardware: ... \n");
995 
996  OperationalRegs = EhciExtension->OperationalRegs;
997  CapabilityRegisters = EhciExtension->CapabilityRegisters;
998 
999  Command.AsULONG = READ_REGISTER_ULONG(&OperationalRegs->HcCommand.AsULONG);
1000  Command.Reset = 1;
1001  WRITE_REGISTER_ULONG(&OperationalRegs->HcCommand.AsULONG, Command.AsULONG);
1002 
1003  KeQuerySystemTime(&EndTime);
1004  EndTime.QuadPart += 100 * 10000; // 100 msec
1005 
1006  DPRINT("EHCI_InitializeHardware: Start reset ... \n");
1007 
1008  while (TRUE)
1009  {
1010  KeQuerySystemTime(&CurrentTime);
1011  Command.AsULONG = READ_REGISTER_ULONG(&OperationalRegs->HcCommand.AsULONG);
1012 
1013  if (Command.Reset != 1)
1014  break;
1015 
1016  if (CurrentTime.QuadPart >= EndTime.QuadPart)
1017  {
1018  if (Command.Reset == 1)
1019  {
1020  DPRINT1("EHCI_InitializeHardware: Reset failed!\n");
1021  return MP_STATUS_HW_ERROR;
1022  }
1023 
1024  break;
1025  }
1026  }
1027 
1028  DPRINT("EHCI_InitializeHardware: Reset - OK\n");
1029 
1030  StructuralParams.AsULONG = READ_REGISTER_ULONG(&CapabilityRegisters->StructParameters.AsULONG);
1031 
1032  EhciExtension->NumberOfPorts = StructuralParams.PortCount;
1033  EhciExtension->PortPowerControl = StructuralParams.PortPowerControl;
1034 
1035  DPRINT("EHCI_InitializeHardware: StructuralParams - %X\n", StructuralParams.AsULONG);
1036  DPRINT("EHCI_InitializeHardware: PortPowerControl - %x\n", EhciExtension->PortPowerControl);
1037  DPRINT("EHCI_InitializeHardware: N_PORTS - %x\n", EhciExtension->NumberOfPorts);
1038 
1039  WRITE_REGISTER_ULONG(&OperationalRegs->PeriodicListBase, 0);
1040  WRITE_REGISTER_ULONG(&OperationalRegs->AsyncListBase, 0);
1041 
1042  EhciExtension->InterruptMask.AsULONG = 0;
1043  EhciExtension->InterruptMask.Interrupt = 1;
1044  EhciExtension->InterruptMask.ErrorInterrupt = 1;
1045  EhciExtension->InterruptMask.PortChangeInterrupt = 0;
1046  EhciExtension->InterruptMask.FrameListRollover = 1;
1047  EhciExtension->InterruptMask.HostSystemError = 1;
1048  EhciExtension->InterruptMask.InterruptOnAsyncAdvance = 1;
1049 
1050  return MP_STATUS_SUCCESS;
1051 }
1052 
1053 UCHAR
1054 NTAPI
1056  IN UCHAR CapabilityID)
1057 {
1058  EHCI_LEGACY_EXTENDED_CAPABILITY LegacyCapability;
1059  EHCI_HC_CAPABILITY_PARAMS CapParameters;
1060  UCHAR OffsetEECP;
1061 
1062  DPRINT("EHCI_GetOffsetEECP: CapabilityID - %x\n", CapabilityID);
1063 
1064  CapParameters = EhciExtension->CapabilityRegisters->CapParameters;
1065 
1066  OffsetEECP = CapParameters.ExtCapabilitiesPointer;
1067 
1068  if (!OffsetEECP)
1069  return 0;
1070 
1071  while (TRUE)
1072  {
1073  RegPacket.UsbPortReadWriteConfigSpace(EhciExtension,
1074  TRUE,
1075  &LegacyCapability.AsULONG,
1076  OffsetEECP,
1077  sizeof(LegacyCapability));
1078 
1079  DPRINT("EHCI_GetOffsetEECP: OffsetEECP - %x\n", OffsetEECP);
1080 
1081  if (LegacyCapability.CapabilityID == CapabilityID)
1082  break;
1083 
1084  OffsetEECP = LegacyCapability.NextCapabilityPointer;
1085 
1086  if (!OffsetEECP)
1087  return 0;
1088  }
1089 
1090  return OffsetEECP;
1091 }
1092 
1093 MPSTATUS
1094 NTAPI
1096 {
1097  LARGE_INTEGER EndTime;
1098  LARGE_INTEGER CurrentTime;
1099  EHCI_LEGACY_EXTENDED_CAPABILITY LegacyCapability;
1100  UCHAR OffsetEECP;
1101 
1102  DPRINT("EHCI_TakeControlHC: EhciExtension - %p\n", EhciExtension);
1103 
1104  OffsetEECP = EHCI_GetOffsetEECP(EhciExtension, 1);
1105 
1106  if (OffsetEECP == 0)
1107  return MP_STATUS_SUCCESS;
1108 
1109  DPRINT("EHCI_TakeControlHC: OffsetEECP - %X\n", OffsetEECP);
1110 
1111  RegPacket.UsbPortReadWriteConfigSpace(EhciExtension,
1112  TRUE,
1113  &LegacyCapability.AsULONG,
1114  OffsetEECP,
1115  sizeof(LegacyCapability));
1116 
1117  if (LegacyCapability.BiosOwnedSemaphore == 0)
1118  return MP_STATUS_SUCCESS;
1119 
1120  LegacyCapability.OsOwnedSemaphore = 1;
1121 
1122  RegPacket.UsbPortReadWriteConfigSpace(EhciExtension,
1123  FALSE,
1124  &LegacyCapability.AsULONG,
1125  OffsetEECP,
1126  sizeof(LegacyCapability));
1127 
1128  KeQuerySystemTime(&EndTime);
1129  EndTime.QuadPart += 100 * 10000;
1130 
1131  do
1132  {
1133  RegPacket.UsbPortReadWriteConfigSpace(EhciExtension,
1134  TRUE,
1135  &LegacyCapability.AsULONG,
1136  OffsetEECP,
1137  sizeof(LegacyCapability));
1138  KeQuerySystemTime(&CurrentTime);
1139 
1140  if (LegacyCapability.BiosOwnedSemaphore)
1141  {
1142  DPRINT("EHCI_TakeControlHC: Ownership is ok\n");
1143  break;
1144  }
1145  }
1146  while (CurrentTime.QuadPart <= EndTime.QuadPart);
1147 
1148  return MP_STATUS_SUCCESS;
1149 }
1150 
1151 VOID
1152 NTAPI
1154 {
1155  DPRINT1("EHCI_GetRegistryParameters: UNIMPLEMENTED. FIXME\n");
1156 }
1157 
1158 MPSTATUS
1159 NTAPI
1162 {
1163  PEHCI_EXTENSION EhciExtension = ehciExtension;
1164  PEHCI_HC_CAPABILITY_REGISTERS CapabilityRegisters;
1165  PEHCI_HW_REGISTERS OperationalRegs;
1166  MPSTATUS MPStatus;
1168  UCHAR CapabilityRegLength;
1169  UCHAR Fladj;
1170 
1171  DPRINT("EHCI_StartController: ... \n");
1172 
1173  if ((Resources->ResourcesTypes & (USBPORT_RESOURCES_MEMORY | USBPORT_RESOURCES_INTERRUPT)) !=
1175  {
1176  DPRINT1("EHCI_StartController: Resources->ResourcesTypes - %x\n",
1177  Resources->ResourcesTypes);
1178 
1179  return MP_STATUS_ERROR;
1180  }
1181 
1182  CapabilityRegisters = (PEHCI_HC_CAPABILITY_REGISTERS)Resources->ResourceBase;
1183  EhciExtension->CapabilityRegisters = CapabilityRegisters;
1184 
1185  CapabilityRegLength = READ_REGISTER_UCHAR(&CapabilityRegisters->RegistersLength);
1186 
1187  OperationalRegs = (PEHCI_HW_REGISTERS)((ULONG_PTR)CapabilityRegisters +
1188  CapabilityRegLength);
1189 
1190  EhciExtension->OperationalRegs = OperationalRegs;
1191 
1192  DPRINT("EHCI_StartController: CapabilityRegisters - %p\n", CapabilityRegisters);
1193  DPRINT("EHCI_StartController: OperationalRegs - %p\n", OperationalRegs);
1194 
1195  RegPacket.UsbPortReadWriteConfigSpace(EhciExtension,
1196  TRUE,
1197  &Fladj,
1199  sizeof(Fladj));
1200 
1201  EhciExtension->FrameLengthAdjustment = Fladj;
1202 
1203  EHCI_GetRegistryParameters(EhciExtension);
1204 
1205  MPStatus = EHCI_TakeControlHC(EhciExtension);
1206 
1207  if (MPStatus)
1208  {
1209  DPRINT1("EHCI_StartController: Unsuccessful TakeControlHC()\n");
1210  return MPStatus;
1211  }
1212 
1213  MPStatus = EHCI_InitializeHardware(EhciExtension);
1214 
1215  if (MPStatus)
1216  {
1217  DPRINT1("EHCI_StartController: Unsuccessful InitializeHardware()\n");
1218  return MPStatus;
1219  }
1220 
1221  MPStatus = EHCI_InitializeSchedule(EhciExtension,
1222  Resources->StartVA,
1223  Resources->StartPA);
1224 
1225  if (MPStatus)
1226  {
1227  DPRINT1("EHCI_StartController: Unsuccessful InitializeSchedule()\n");
1228  return MPStatus;
1229  }
1230 
1231  RegPacket.UsbPortReadWriteConfigSpace(EhciExtension,
1232  TRUE,
1233  &Fladj,
1235  sizeof(Fladj));
1236 
1237  if (Fladj != EhciExtension->FrameLengthAdjustment)
1238  {
1239  Fladj = EhciExtension->FrameLengthAdjustment;
1240 
1241  RegPacket.UsbPortReadWriteConfigSpace(EhciExtension,
1242  FALSE, // write
1243  &Fladj,
1245  sizeof(Fladj));
1246  }
1247 
1248  /* Port routing control logic default-routes all ports to this HC */
1250  WRITE_REGISTER_ULONG(&OperationalRegs->ConfigFlag,
1251  EhciExtension->PortRoutingControl);
1252 
1253  Command.AsULONG = READ_REGISTER_ULONG(&OperationalRegs->HcCommand.AsULONG);
1254  Command.InterruptThreshold = 1; // one micro-frame
1255  WRITE_REGISTER_ULONG(&OperationalRegs->HcCommand.AsULONG, Command.AsULONG);
1256 
1257  Command.AsULONG = READ_REGISTER_ULONG(&OperationalRegs->HcCommand.AsULONG);
1258  Command.Run = 1; // execution of the schedule
1259  WRITE_REGISTER_ULONG(&OperationalRegs->HcCommand.AsULONG, Command.AsULONG);
1260 
1261  EhciExtension->IsStarted = TRUE;
1262 
1263  if (Resources->IsChirpHandled)
1264  {
1265  ULONG Port;
1266 
1267  for (Port = 1; Port <= EhciExtension->NumberOfPorts; Port++)
1268  {
1269  EHCI_RH_SetFeaturePortPower(EhciExtension, Port);
1270  }
1271 
1272  RegPacket.UsbPortWait(EhciExtension, 200);
1273 
1274  for (Port = 1; Port <= EhciExtension->NumberOfPorts; Port++)
1275  {
1276  EHCI_RH_ChirpRootPort(EhciExtension, Port++);
1277  }
1278  }
1279 
1280  return MPStatus;
1281 }
1282 
1283 VOID
1284 NTAPI
1286  IN BOOLEAN DisableInterrupts)
1287 {
1288  DPRINT1("EHCI_StopController: UNIMPLEMENTED. FIXME\n");
1289 }
1290 
1291 VOID
1292 NTAPI
1294 {
1295  PEHCI_EXTENSION EhciExtension = ehciExtension;
1296  PEHCI_HW_REGISTERS OperationalRegs;
1299  EHCI_INTERRUPT_ENABLE IntrEn;
1300  ULONG ix;
1301 
1302  DPRINT("EHCI_SuspendController: ... \n");
1303 
1304  OperationalRegs = EhciExtension->OperationalRegs;
1305 
1306  EhciExtension->BackupPeriodiclistbase = READ_REGISTER_ULONG(&OperationalRegs->PeriodicListBase);
1307  EhciExtension->BackupAsynclistaddr = READ_REGISTER_ULONG(&OperationalRegs->AsyncListBase);
1308  EhciExtension->BackupCtrlDSSegment = READ_REGISTER_ULONG(&OperationalRegs->SegmentSelector);
1309  EhciExtension->BackupUSBCmd = READ_REGISTER_ULONG(&OperationalRegs->HcCommand.AsULONG);
1310 
1311  Command.AsULONG = READ_REGISTER_ULONG(&OperationalRegs->HcCommand.AsULONG);
1312  Command.InterruptAdvanceDoorbell = 0;
1313  WRITE_REGISTER_ULONG(&OperationalRegs->HcCommand.AsULONG, Command.AsULONG);
1314 
1315  Command.AsULONG = READ_REGISTER_ULONG(&OperationalRegs->HcCommand.AsULONG);
1316  Command.Run = 0;
1317  WRITE_REGISTER_ULONG(&OperationalRegs->HcCommand.AsULONG, Command.AsULONG);
1318 
1320 
1321  Status.AsULONG = READ_REGISTER_ULONG(&OperationalRegs->HcStatus.AsULONG);
1322 
1323  Status.HCHalted = 0;
1324  Status.Reclamation = 0;
1325  Status.PeriodicStatus = 0;
1326  Status.AsynchronousStatus = 0;
1327 
1328  if (Status.AsULONG)
1329  WRITE_REGISTER_ULONG(&OperationalRegs->HcStatus.AsULONG, Status.AsULONG);
1330 
1331  WRITE_REGISTER_ULONG(&OperationalRegs->HcInterruptEnable.AsULONG, 0);
1332 
1333  for (ix = 0; ix < 10; ix++)
1334  {
1335  Status.AsULONG = READ_REGISTER_ULONG(&OperationalRegs->HcStatus.AsULONG);
1336 
1337  if (Status.HCHalted)
1338  break;
1339 
1340  RegPacket.UsbPortWait(EhciExtension, 1);
1341  }
1342 
1343  if (!Status.HCHalted)
1344  DbgBreakPoint();
1345 
1346  IntrEn.AsULONG = READ_REGISTER_ULONG(&OperationalRegs->HcInterruptEnable.AsULONG);
1347  IntrEn.PortChangeInterrupt = 1;
1348  WRITE_REGISTER_ULONG(&OperationalRegs->HcInterruptEnable.AsULONG, IntrEn.AsULONG);
1349 
1350  EhciExtension->Flags |= EHCI_FLAGS_CONTROLLER_SUSPEND;
1351 }
1352 
1353 MPSTATUS
1354 NTAPI
1356 {
1357  PEHCI_EXTENSION EhciExtension = ehciExtension;
1358  PEHCI_HW_REGISTERS OperationalRegs;
1359  ULONG RoutingControl;
1361 
1362  DPRINT("EHCI_ResumeController: ... \n");
1363 
1364  OperationalRegs = EhciExtension->OperationalRegs;
1365 
1366  RoutingControl = EhciExtension->PortRoutingControl;
1367 
1368  if (!(RoutingControl & EHCI_CONFIG_FLAG_CONFIGURED))
1369  {
1370  EhciExtension->PortRoutingControl = RoutingControl | EHCI_CONFIG_FLAG_CONFIGURED;
1371  WRITE_REGISTER_ULONG(&OperationalRegs->ConfigFlag,
1372  EhciExtension->PortRoutingControl);
1373 
1374  return MP_STATUS_HW_ERROR;
1375  }
1376 
1377  WRITE_REGISTER_ULONG(&OperationalRegs->SegmentSelector,
1378  EhciExtension->BackupCtrlDSSegment);
1379 
1380  WRITE_REGISTER_ULONG(&OperationalRegs->PeriodicListBase,
1381  EhciExtension->BackupPeriodiclistbase);
1382 
1383  WRITE_REGISTER_ULONG(&OperationalRegs->AsyncListBase,
1384  EhciExtension->BackupAsynclistaddr);
1385 
1386  Command.AsULONG = READ_REGISTER_ULONG(&OperationalRegs->HcCommand.AsULONG);
1387 
1388  Command.AsULONG = Command.AsULONG ^ EhciExtension->BackupUSBCmd;
1389 
1390  Command.Reset = 0;
1391  Command.FrameListSize = 0;
1392  Command.InterruptAdvanceDoorbell = 0;
1393  Command.LightResetHC = 0;
1394  Command.AsynchronousParkModeCount = 0;
1395  Command.AsynchronousParkModeEnable = 0;
1396 
1397  Command.Run = 1;
1398 
1399  WRITE_REGISTER_ULONG(&OperationalRegs->HcCommand.AsULONG,
1400  Command.AsULONG);
1401 
1403  EhciExtension->InterruptMask.AsULONG);
1404 
1405  EhciExtension->Flags &= ~EHCI_FLAGS_CONTROLLER_SUSPEND;
1406 
1407  return MP_STATUS_SUCCESS;
1408 }
1409 
1410 BOOLEAN
1411 NTAPI
1413  IN BOOLEAN IsInvalidateController)
1414 {
1415  PEHCI_HW_REGISTERS OperationalRegs = EhciExtension->OperationalRegs;
1416 
1417  if (READ_REGISTER_ULONG(&OperationalRegs->HcCommand.AsULONG) != -1)
1418  return TRUE;
1419 
1420  DPRINT1("EHCI_HardwarePresent: IsInvalidateController - %x\n",
1421  IsInvalidateController);
1422 
1423  if (!IsInvalidateController)
1424  return FALSE;
1425 
1426  RegPacket.UsbPortInvalidateController(EhciExtension,
1428  return FALSE;
1429 }
1430 
1431 BOOLEAN
1432 NTAPI
1434 {
1435  PEHCI_EXTENSION EhciExtension = ehciExtension;
1436  PEHCI_HW_REGISTERS OperationalRegs;
1437  BOOLEAN Result = FALSE;
1438  EHCI_USB_STATUS IntrSts;
1439  EHCI_INTERRUPT_ENABLE IntrEn;
1440  EHCI_INTERRUPT_ENABLE iStatus;
1442  ULONG FrameIndex;
1443 
1444  OperationalRegs = EhciExtension->OperationalRegs;
1445 
1446  DPRINT_EHCI("EHCI_InterruptService: ... \n");
1447 
1448  Result = EHCI_HardwarePresent(EhciExtension, FALSE);
1449 
1450  if (!Result)
1451  return FALSE;
1452 
1453  IntrEn.AsULONG = READ_REGISTER_ULONG(&OperationalRegs->HcInterruptEnable.AsULONG);
1454  IntrSts.AsULONG = READ_REGISTER_ULONG(&OperationalRegs->HcStatus.AsULONG);
1455 
1456  iStatus.AsULONG = (IntrEn.AsULONG & IntrSts.AsULONG) & EHCI_INTERRUPT_MASK;
1457 
1458  if (!iStatus.AsULONG)
1459  return FALSE;
1460 
1461  EhciExtension->InterruptStatus = iStatus;
1462 
1463  WRITE_REGISTER_ULONG(&OperationalRegs->HcStatus.AsULONG, iStatus.AsULONG);
1464 
1465  if (iStatus.HostSystemError)
1466  {
1467  EhciExtension->HcSystemErrors++;
1468 
1469  if (EhciExtension->HcSystemErrors < EHCI_MAX_HC_SYSTEM_ERRORS)
1470  {
1471  Command.AsULONG = READ_REGISTER_ULONG(&OperationalRegs->HcCommand.AsULONG);
1472  Command.Run = 1;
1473  WRITE_REGISTER_ULONG(&OperationalRegs->HcCommand.AsULONG, Command.AsULONG);
1474  }
1475  }
1476 
1477  FrameIndex = READ_REGISTER_ULONG(&OperationalRegs->FrameIndex) / EHCI_MICROFRAMES;
1478  FrameIndex &= EHCI_FRINDEX_FRAME_MASK;
1479 
1480  if ((FrameIndex ^ EhciExtension->FrameIndex) & EHCI_FRAME_LIST_MAX_ENTRIES)
1481  {
1482  EhciExtension->FrameHighPart += 2 * EHCI_FRAME_LIST_MAX_ENTRIES;
1483 
1484  EhciExtension->FrameHighPart -= (FrameIndex ^ EhciExtension->FrameHighPart) &
1486  }
1487 
1488  EhciExtension->FrameIndex = FrameIndex;
1489 
1490  return TRUE;
1491 }
1492 
1493 VOID
1494 NTAPI
1497 {
1498  PEHCI_EXTENSION EhciExtension = ehciExtension;
1499  PEHCI_HW_REGISTERS OperationalRegs;
1500  EHCI_INTERRUPT_ENABLE iStatus;
1501 
1502  OperationalRegs = EhciExtension->OperationalRegs;
1503 
1504  DPRINT_EHCI("EHCI_InterruptDpc: [%p] EnableInterrupts - %x\n",
1505  EhciExtension, EnableInterrupts);
1506 
1507  iStatus = EhciExtension->InterruptStatus;
1508  EhciExtension->InterruptStatus.AsULONG = 0;
1509 
1510  if (iStatus.Interrupt == 1 ||
1511  iStatus.ErrorInterrupt == 1 ||
1512  iStatus.InterruptOnAsyncAdvance == 1)
1513  {
1514  DPRINT_EHCI("EHCI_InterruptDpc: [%p] InterruptStatus - %X\n", EhciExtension, iStatus.AsULONG);
1515  RegPacket.UsbPortInvalidateEndpoint(EhciExtension, NULL);
1516  }
1517 
1518  if (iStatus.PortChangeInterrupt == 1)
1519  {
1520  DPRINT_EHCI("EHCI_InterruptDpc: [%p] PortChangeInterrupt\n", EhciExtension);
1521  RegPacket.UsbPortInvalidateRootHub(EhciExtension);
1522  }
1523 
1524  if (EnableInterrupts)
1525  {
1527  EhciExtension->InterruptMask.AsULONG);
1528  }
1529 }
1530 
1531 ULONG
1532 NTAPI
1534  IN ULONG MaxPacketSize,
1535  IN ULONG TransferedLen,
1536  IN PULONG DataToggle,
1537  IN PEHCI_TRANSFER EhciTransfer,
1538  IN PEHCI_HCD_TD TD,
1540 {
1541  PUSBPORT_TRANSFER_PARAMETERS TransferParameters;
1543  ULONG SgIdx;
1544  ULONG LengthThisTD;
1545  ULONG ix;
1546  ULONG SgRemain;
1547  ULONG DiffLength;
1548  ULONG NumPackets;
1549 
1550  DPRINT_EHCI("EHCI_MapAsyncTransferToTd: EhciTransfer - %p, TD - %p, TransferedLen - %x, MaxPacketSize - %x, DataToggle - %x\n",
1551  EhciTransfer,
1552  TD,
1553  TransferedLen,
1554  MaxPacketSize,
1555  DataToggle);
1556 
1557  TransferParameters = EhciTransfer->TransferParameters;
1558 
1559  SgElement = &SgList->SgElement[0];
1560 
1561  for (SgIdx = 0; SgIdx < SgList->SgElementCount; SgIdx++)
1562  {
1563  if (TransferedLen >= SgElement->SgOffset &&
1564  TransferedLen < SgElement->SgOffset + SgElement->SgTransferLength)
1565  {
1566  break;
1567  }
1568 
1569  SgElement += 1;
1570  }
1571 
1572  SgRemain = SgList->SgElementCount - SgIdx;
1573 
1574  if (SgRemain > EHCI_MAX_QTD_BUFFER_PAGES)
1575  {
1576  TD->HwTD.Buffer[0] = SgList->SgElement[SgIdx].SgPhysicalAddress.LowPart -
1577  SgList->SgElement[SgIdx].SgOffset +
1578  TransferedLen;
1579 
1580  LengthThisTD = EHCI_MAX_QTD_BUFFER_PAGES * PAGE_SIZE -
1581  (TD->HwTD.Buffer[0] & (PAGE_SIZE - 1));
1582 
1583  for (ix = 1; ix < EHCI_MAX_QTD_BUFFER_PAGES; ix++)
1584  {
1585  TD->HwTD.Buffer[ix] = SgList->SgElement[SgIdx + ix].SgPhysicalAddress.LowPart;
1586  }
1587 
1588  NumPackets = LengthThisTD / MaxPacketSize;
1589  DiffLength = LengthThisTD - MaxPacketSize * (LengthThisTD / MaxPacketSize);
1590 
1591  if (LengthThisTD != MaxPacketSize * (LengthThisTD / MaxPacketSize))
1592  LengthThisTD -= DiffLength;
1593 
1594  if (DataToggle && (NumPackets & 1))
1595  *DataToggle = !(*DataToggle);
1596  }
1597  else
1598  {
1599  LengthThisTD = TransferParameters->TransferBufferLength - TransferedLen;
1600 
1601  TD->HwTD.Buffer[0] = TransferedLen +
1602  SgList->SgElement[SgIdx].SgPhysicalAddress.LowPart -
1603  SgList->SgElement[SgIdx].SgOffset;
1604 
1605  for (ix = 1; ix < EHCI_MAX_QTD_BUFFER_PAGES; ix++)
1606  {
1607  if ((SgIdx + ix) >= SgList->SgElementCount)
1608  break;
1609 
1610  TD->HwTD.Buffer[ix] = SgList->SgElement[SgIdx + ix].SgPhysicalAddress.LowPart;
1611  }
1612  }
1613 
1614  TD->HwTD.Token.TransferBytes = LengthThisTD;
1615  TD->LengthThisTD = LengthThisTD;
1616 
1617  return LengthThisTD + TransferedLen;
1618 }
1619 
1620 VOID
1621 NTAPI
1623 {
1624  PEHCI_HW_REGISTERS OperationalRegs;
1625  EHCI_USB_COMMAND UsbCmd;
1626 
1627  DPRINT_EHCI("EHCI_EnableAsyncList: ... \n");
1628 
1629  OperationalRegs = EhciExtension->OperationalRegs;
1630 
1631  UsbCmd.AsULONG = READ_REGISTER_ULONG(&OperationalRegs->HcCommand.AsULONG);
1632  UsbCmd.AsynchronousEnable = 1;
1633  WRITE_REGISTER_ULONG((&OperationalRegs->HcCommand.AsULONG), UsbCmd.AsULONG);
1634 }
1635 
1636 VOID
1637 NTAPI
1639 {
1640  PEHCI_HW_REGISTERS OperationalRegs;
1641  EHCI_USB_COMMAND UsbCmd;
1642 
1643  DPRINT("EHCI_DisableAsyncList: ... \n");
1644 
1645  OperationalRegs = EhciExtension->OperationalRegs;
1646 
1647  UsbCmd.AsULONG = READ_REGISTER_ULONG(&OperationalRegs->HcCommand.AsULONG);
1648  UsbCmd.AsynchronousEnable = 0;
1649  WRITE_REGISTER_ULONG(&OperationalRegs->HcCommand.AsULONG, UsbCmd.AsULONG);
1650 }
1651 
1652 VOID
1653 NTAPI
1655 {
1656  PEHCI_HW_REGISTERS OperationalRegs;
1658 
1659  DPRINT("EHCI_EnablePeriodicList: ... \n");
1660 
1661  OperationalRegs = EhciExtension->OperationalRegs;
1662 
1663  Command.AsULONG = READ_REGISTER_ULONG(&OperationalRegs->HcCommand.AsULONG);
1664  Command.PeriodicEnable = 1;
1665  WRITE_REGISTER_ULONG(&OperationalRegs->HcCommand.AsULONG, Command.AsULONG);
1666 }
1667 
1668 VOID
1669 NTAPI
1671 {
1672  PEHCI_HW_REGISTERS OperationalRegs;
1675  LARGE_INTEGER CurrentTime;
1676  LARGE_INTEGER EndTime;
1678 
1679  DPRINT_EHCI("EHCI_FlushAsyncCache: EhciExtension - %p\n", EhciExtension);
1680 
1681  OperationalRegs = EhciExtension->OperationalRegs;
1682  Command.AsULONG = READ_REGISTER_ULONG(&OperationalRegs->HcCommand.AsULONG);
1683  Status.AsULONG = READ_REGISTER_ULONG(&OperationalRegs->HcStatus.AsULONG);
1684 
1685  if (!Status.AsynchronousStatus && !Command.AsynchronousEnable)
1686  return;
1687 
1688  if (Status.AsynchronousStatus && !Command.AsynchronousEnable)
1689  {
1690  KeQuerySystemTime(&EndTime);
1691  EndTime.QuadPart += 100 * 10000; //100 ms
1692 
1693  do
1694  {
1695  Status.AsULONG = READ_REGISTER_ULONG(&OperationalRegs->HcStatus.AsULONG);
1696  Command.AsULONG = READ_REGISTER_ULONG(&OperationalRegs->HcCommand.AsULONG);
1697  KeQuerySystemTime(&CurrentTime);
1698 
1699  if (CurrentTime.QuadPart > EndTime.QuadPart)
1700  RegPacket.UsbPortBugCheck(EhciExtension);
1701  }
1702  while (Status.AsynchronousStatus && Command.AsULONG != -1 && Command.Run);
1703 
1704  return;
1705  }
1706 
1707  if (!Status.AsynchronousStatus && Command.AsynchronousEnable)
1708  {
1709  KeQuerySystemTime(&EndTime);
1710  EndTime.QuadPart += 100 * 10000; //100 ms
1711 
1712  do
1713  {
1714  Status.AsULONG = READ_REGISTER_ULONG(&OperationalRegs->HcStatus.AsULONG);
1715  Command.AsULONG = READ_REGISTER_ULONG(&OperationalRegs->HcCommand.AsULONG);
1716  KeQuerySystemTime(&CurrentTime);
1717  }
1718  while (!Status.AsynchronousStatus && Command.AsULONG != -1 && Command.Run);
1719  }
1720 
1721  Command.InterruptAdvanceDoorbell = 1;
1722  WRITE_REGISTER_ULONG(&OperationalRegs->HcCommand.AsULONG, Command.AsULONG);
1723 
1724  KeQuerySystemTime(&EndTime);
1725  EndTime.QuadPart += 100 * 10000; //100 ms
1726 
1727  Cmd.AsULONG = READ_REGISTER_ULONG(&OperationalRegs->HcCommand.AsULONG);
1728 
1729  if (Cmd.InterruptAdvanceDoorbell)
1730  {
1731  while (Cmd.Run)
1732  {
1733  if (Cmd.AsULONG == -1)
1734  break;
1735 
1737  Command.AsULONG = READ_REGISTER_ULONG(&OperationalRegs->HcCommand.AsULONG);
1738  KeQuerySystemTime(&CurrentTime);
1739 
1740  if (!Command.InterruptAdvanceDoorbell)
1741  break;
1742 
1743  Cmd = Command;
1744  }
1745  }
1746 
1747  /* InterruptOnAsyncAdvance */
1748  WRITE_REGISTER_ULONG(&OperationalRegs->HcStatus.AsULONG, 0x20);
1749 }
1750 
1751 VOID
1752 NTAPI
1754  IN PEHCI_HCD_QH QH,
1755  IN ULONG TransferType)
1756 {
1757  PEHCI_HCD_QH PrevQH;
1758  PEHCI_HCD_QH NextQH;
1759  ULONG QhPA;
1760  ULONG FrameIndexReg;
1761  PEHCI_HW_REGISTERS OperationalRegs;
1763 
1764  DPRINT_EHCI("EHCI_LockQH: QH - %p, TransferType - %x\n",
1765  QH,
1766  TransferType);
1767 
1768  OperationalRegs = EhciExtension->OperationalRegs;
1769 
1770  ASSERT((QH->sqh.QhFlags & EHCI_QH_FLAG_UPDATING) == 0);
1771  ASSERT(EhciExtension->LockQH == NULL);
1772 
1773  PrevQH = QH->sqh.PrevHead;
1774  QH->sqh.QhFlags |= EHCI_QH_FLAG_UPDATING;
1775 
1776  ASSERT(PrevQH);
1777 
1778  NextQH = QH->sqh.NextHead;
1779 
1780  EhciExtension->PrevQH = PrevQH;
1781  EhciExtension->NextQH = NextQH;
1782  EhciExtension->LockQH = QH;
1783 
1784  if (NextQH)
1785  {
1786  QhPA = NextQH->sqh.PhysicalAddress;
1788  QhPA |= (EHCI_LINK_TYPE_QH << 1);
1789  }
1790  else
1791  {
1792  QhPA = TERMINATE_POINTER;
1793  }
1794 
1795  PrevQH->sqh.HwQH.HorizontalLink.AsULONG = QhPA;
1796 
1797  FrameIndexReg = READ_REGISTER_ULONG(&OperationalRegs->FrameIndex);
1798 
1799  if (TransferType == USBPORT_TRANSFER_TYPE_INTERRUPT)
1800  {
1801  do
1802  {
1803  Command.AsULONG = READ_REGISTER_ULONG(&OperationalRegs->HcCommand.AsULONG);
1804  }
1805  while (READ_REGISTER_ULONG(&OperationalRegs->FrameIndex) ==
1806  FrameIndexReg && (Command.AsULONG != -1) && Command.Run);
1807  }
1808  else
1809  {
1810  EHCI_FlushAsyncCache(EhciExtension);
1811  }
1812 }
1813 
1814 VOID
1815 NTAPI
1817  IN PEHCI_HCD_QH QH)
1818 {
1819  ULONG QhPA;
1820 
1821  DPRINT_EHCI("EHCI_UnlockQH: QH - %p\n", QH);
1822 
1823  ASSERT(QH->sqh.QhFlags & EHCI_QH_FLAG_UPDATING);
1824  ASSERT(EhciExtension->LockQH);
1825  ASSERT(EhciExtension->LockQH == QH);
1826 
1827  QH->sqh.QhFlags &= ~EHCI_QH_FLAG_UPDATING;
1828 
1829  EhciExtension->LockQH = NULL;
1830 
1831  QhPA = QH->sqh.PhysicalAddress;
1833  QhPA |= (EHCI_LINK_TYPE_QH << 1);
1834 
1835  EhciExtension->PrevQH->sqh.HwQH.HorizontalLink.AsULONG = QhPA;
1836 }
1837 
1838 VOID
1839 NTAPI
1841  IN PEHCI_ENDPOINT EhciEndpoint,
1842  IN PEHCI_HCD_TD NextTD)
1843 {
1844  PEHCI_HCD_QH QH;
1845  PEHCI_HCD_TD TD;
1846  PEHCI_TRANSFER Transfer;
1847  PEHCI_HCD_TD LinkTD;
1849  ULONG ix;
1850 
1851  DPRINT_EHCI("EHCI_LinkTransferToQueue: EhciEndpoint - %p, NextTD - %p\n",
1852  EhciEndpoint,
1853  NextTD);
1854 
1855  ASSERT(EhciEndpoint->HcdHeadP != NULL);
1856  IsPresent = EHCI_HardwarePresent(EhciExtension, 0);
1857 
1858  QH = EhciEndpoint->QH;
1859  TD = EhciEndpoint->HcdHeadP;
1860 
1861  if (TD == EhciEndpoint->HcdTailP)
1862  {
1863  if (IsPresent)
1864  {
1865  EHCI_LockQH(EhciExtension,
1866  QH,
1867  EhciEndpoint->EndpointProperties.TransferType);
1868  }
1869 
1870  QH->sqh.HwQH.CurrentTD = EhciEndpoint->DmaBufferPA;
1871  QH->sqh.HwQH.NextTD = NextTD->PhysicalAddress;
1872  QH->sqh.HwQH.AlternateNextTD = NextTD->HwTD.AlternateNextTD;
1873 
1876 
1877  QH->sqh.HwQH.Token.TransferBytes = 0;
1878 
1879  if (IsPresent)
1880  EHCI_UnlockQH(EhciExtension, QH);
1881 
1882  EhciEndpoint->HcdHeadP = NextTD;
1883  }
1884  else
1885  {
1886  DPRINT_EHCI("EHCI_LinkTransferToQueue: TD - %p, HcdTailP - %p\n",
1887  EhciEndpoint->HcdHeadP,
1888  EhciEndpoint->HcdTailP);
1889 
1890  LinkTD = EhciEndpoint->HcdHeadP;
1891 
1892  while (TD != EhciEndpoint->HcdTailP)
1893  {
1894  LinkTD = TD;
1895  TD = TD->NextHcdTD;
1896  }
1897 
1898  ASSERT(LinkTD != EhciEndpoint->HcdTailP);
1899 
1900  Transfer = LinkTD->EhciTransfer;
1901 
1902  TD = EhciEndpoint->FirstTD;
1903 
1904  for (ix = 0; ix < EhciEndpoint->MaxTDs; ix++)
1905  {
1906  if (TD->EhciTransfer == Transfer)
1907  {
1908  TD->AltNextHcdTD = NextTD;
1909  TD->HwTD.AlternateNextTD = NextTD->PhysicalAddress;
1910  }
1911 
1912  TD += 1;
1913  }
1914 
1915  LinkTD->HwTD.NextTD = NextTD->PhysicalAddress;
1916  LinkTD->NextHcdTD = NextTD;
1917 
1918  if (QH->sqh.HwQH.CurrentTD == LinkTD->PhysicalAddress)
1919  {
1920  QH->sqh.HwQH.NextTD = NextTD->PhysicalAddress;
1922  }
1923  }
1924 }
1925 
1926 MPSTATUS
1927 NTAPI
1929  IN PEHCI_ENDPOINT EhciEndpoint,
1930  IN PUSBPORT_TRANSFER_PARAMETERS TransferParameters,
1931  IN PEHCI_TRANSFER EhciTransfer,
1933 {
1934  PEHCI_HCD_TD FirstTD;
1935  PEHCI_HCD_TD LastTD;
1936  PEHCI_HCD_TD TD;
1937  PEHCI_HCD_TD PrevTD;
1938  PEHCI_HCD_TD LinkTD;
1939  ULONG TransferedLen = 0;
1941  ULONG DataToggle = 1;
1942 
1943  DPRINT_EHCI("EHCI_ControlTransfer: EhciEndpoint - %p, EhciTransfer - %p\n",
1944  EhciEndpoint,
1945  EhciTransfer);
1946 
1947  if (EhciEndpoint->RemainTDs < EHCI_MAX_CONTROL_TD_COUNT)
1948  return MP_STATUS_FAILURE;
1949 
1950  EhciExtension->PendingTransfers++;
1951  EhciEndpoint->PendingTDs++;
1952 
1953  EhciTransfer->TransferOnAsyncList = 1;
1954 
1955  FirstTD = EHCI_AllocTd(EhciExtension, EhciEndpoint);
1956 
1957  if (!FirstTD)
1958  {
1959  RegPacket.UsbPortBugCheck(EhciExtension);
1960  return MP_STATUS_FAILURE;
1961  }
1962 
1963  EhciTransfer->PendingTDs++;
1964 
1965  FirstTD->TdFlags |= EHCI_HCD_TD_FLAG_PROCESSED;
1966  FirstTD->EhciTransfer = EhciTransfer;
1967 
1968  FirstTD->HwTD.Buffer[0] = FirstTD->PhysicalAddress + FIELD_OFFSET(EHCI_HCD_TD, SetupPacket);
1969  FirstTD->HwTD.Buffer[1] = 0;
1970  FirstTD->HwTD.Buffer[2] = 0;
1971  FirstTD->HwTD.Buffer[3] = 0;
1972  FirstTD->HwTD.Buffer[4] = 0;
1973 
1974  FirstTD->NextHcdTD = NULL;
1975 
1976  FirstTD->HwTD.NextTD = TERMINATE_POINTER;
1978 
1979  FirstTD->HwTD.Token.AsULONG = 0;
1980  FirstTD->HwTD.Token.ErrorCounter = 3;
1983  FirstTD->HwTD.Token.TransferBytes = sizeof(FirstTD->SetupPacket);
1984 
1985  RtlCopyMemory(&FirstTD->SetupPacket,
1986  &TransferParameters->SetupPacket,
1987  sizeof(FirstTD->SetupPacket));
1988 
1989  LastTD = EHCI_AllocTd(EhciExtension, EhciEndpoint);
1990 
1991  if (!LastTD)
1992  {
1993  RegPacket.UsbPortBugCheck(EhciExtension);
1994  return MP_STATUS_FAILURE;
1995  }
1996 
1997  EhciTransfer->PendingTDs++;
1998 
2000  LastTD->EhciTransfer = EhciTransfer;
2001 
2002  LastTD->HwTD.Buffer[0] = 0;
2003  LastTD->HwTD.Buffer[1] = 0;
2004  LastTD->HwTD.Buffer[2] = 0;
2005  LastTD->HwTD.Buffer[3] = 0;
2006  LastTD->HwTD.Buffer[4] = 0;
2007 
2008  LastTD->NextHcdTD = NULL;
2009  LastTD->HwTD.NextTD = TERMINATE_POINTER;
2011 
2012  LastTD->HwTD.Token.AsULONG = 0;
2013  LastTD->HwTD.Token.ErrorCounter = 3;
2014 
2015  FirstTD->AltNextHcdTD = LastTD;
2016  FirstTD->HwTD.AlternateNextTD = LastTD->PhysicalAddress;
2017 
2018  PrevTD = FirstTD;
2019  LinkTD = FirstTD;
2020 
2021  while (TransferedLen < TransferParameters->TransferBufferLength)
2022  {
2023  TD = EHCI_AllocTd(EhciExtension, EhciEndpoint);
2024 
2025  if (!TD)
2026  {
2027  RegPacket.UsbPortBugCheck(EhciExtension);
2028  return MP_STATUS_FAILURE;
2029  }
2030 
2031  LinkTD = TD;
2032 
2033  EhciTransfer->PendingTDs++;
2034 
2036  TD->EhciTransfer = EhciTransfer;
2037 
2038  TD->HwTD.Buffer[0] = 0;
2039  TD->HwTD.Buffer[1] = 0;
2040  TD->HwTD.Buffer[2] = 0;
2041  TD->HwTD.Buffer[3] = 0;
2042  TD->HwTD.Buffer[4] = 0;
2043 
2044  TD->NextHcdTD = NULL;
2045 
2048 
2049  TD->HwTD.Token.AsULONG = 0;
2050  TD->HwTD.Token.ErrorCounter = 3;
2051 
2052  PrevTD->NextHcdTD = TD;
2053  PrevTD->HwTD.NextTD = TD->PhysicalAddress;
2054 
2055  if (TransferParameters->TransferFlags & USBD_TRANSFER_DIRECTION_IN)
2057  else
2059 
2060  TD->HwTD.Token.DataToggle = DataToggle;
2062 
2063  if (DataToggle)
2064  TD->HwTD.Token.DataToggle = 1;
2065  else
2066  TD->HwTD.Token.DataToggle = 0;
2067 
2068  TD->AltNextHcdTD = LastTD;
2069  TD->HwTD.AlternateNextTD = LastTD->PhysicalAddress;
2070 
2071  TransferedLen = EHCI_MapAsyncTransferToTd(EhciExtension,
2072  EhciEndpoint->EndpointProperties.MaxPacketSize,
2073  TransferedLen,
2074  &DataToggle,
2075  EhciTransfer,
2076  TD,
2077  SgList);
2078 
2079  PrevTD = TD;
2080  }
2081 
2082  LinkTD->NextHcdTD = LastTD;
2083  LinkTD->HwTD.NextTD = LastTD->PhysicalAddress;
2084 
2085  LastTD->HwTD.Buffer[0] = 0;
2086  LastTD->LengthThisTD = 0;
2087 
2088  Token.AsULONG = 0;
2090  Token.InterruptOnComplete = 1;
2091  Token.DataToggle = 1;
2092 
2093  if (TransferParameters->TransferFlags & USBD_TRANSFER_DIRECTION_IN)
2094  Token.PIDCode = EHCI_TD_TOKEN_PID_OUT;
2095  else
2096  Token.PIDCode = EHCI_TD_TOKEN_PID_IN;
2097 
2098  LastTD->HwTD.Token = Token;
2099 
2100  LastTD->NextHcdTD = EhciEndpoint->HcdTailP;
2101  LastTD->HwTD.NextTD = EhciEndpoint->HcdTailP->PhysicalAddress;
2102 
2103  EHCI_EnableAsyncList(EhciExtension);
2104  EHCI_LinkTransferToQueue(EhciExtension, EhciEndpoint, FirstTD);
2105 
2106  ASSERT(EhciEndpoint->HcdTailP->NextHcdTD == NULL);
2107  ASSERT(EhciEndpoint->HcdTailP->AltNextHcdTD == NULL);
2108 
2109  return MP_STATUS_SUCCESS;
2110 }
2111 
2112 MPSTATUS
2113 NTAPI
2115  IN PEHCI_ENDPOINT EhciEndpoint,
2116  IN PUSBPORT_TRANSFER_PARAMETERS TransferParameters,
2117  IN PEHCI_TRANSFER EhciTransfer,
2119 {
2120  PEHCI_HCD_TD PrevTD;
2121  PEHCI_HCD_TD FirstTD;
2122  PEHCI_HCD_TD TD;
2123  ULONG TransferedLen;
2124 
2125  DPRINT_EHCI("EHCI_BulkTransfer: EhciEndpoint - %p, EhciTransfer - %p\n",
2126  EhciEndpoint,
2127  EhciTransfer);
2128 
2129  if (((TransferParameters->TransferBufferLength /
2130  ((EHCI_MAX_QTD_BUFFER_PAGES - 1) * PAGE_SIZE)) + 1) > EhciEndpoint->RemainTDs)
2131  {
2132  DPRINT1("EHCI_BulkTransfer: return MP_STATUS_FAILURE\n");
2133  return MP_STATUS_FAILURE;
2134  }
2135 
2136  EhciExtension->PendingTransfers++;
2137  EhciEndpoint->PendingTDs++;
2138 
2139  EhciTransfer->TransferOnAsyncList = 1;
2140 
2141  TransferedLen = 0;
2142  PrevTD = NULL;
2143 
2144  if (TransferParameters->TransferBufferLength)
2145  {
2146  while (TransferedLen < TransferParameters->TransferBufferLength)
2147  {
2148  TD = EHCI_AllocTd(EhciExtension, EhciEndpoint);
2149 
2150  if (!TD)
2151  {
2152  RegPacket.UsbPortBugCheck(EhciExtension);
2153  return MP_STATUS_FAILURE;
2154  }
2155 
2156  EhciTransfer->PendingTDs++;
2157 
2159  TD->EhciTransfer = EhciTransfer;
2160 
2161  TD->HwTD.Buffer[0] = 0;
2162  TD->HwTD.Buffer[1] = 0;
2163  TD->HwTD.Buffer[2] = 0;
2164  TD->HwTD.Buffer[3] = 0;
2165  TD->HwTD.Buffer[4] = 0;
2166 
2167  TD->NextHcdTD = NULL;
2170 
2171  TD->HwTD.Token.AsULONG = 0;
2172  TD->HwTD.Token.ErrorCounter = 3;
2173 
2174  if (EhciTransfer->PendingTDs == 1)
2175  {
2176  FirstTD = TD;
2177  }
2178  else
2179  {
2180  PrevTD->HwTD.NextTD = TD->PhysicalAddress;
2181  PrevTD->NextHcdTD = TD;
2182  }
2183 
2184  TD->HwTD.AlternateNextTD = EhciEndpoint->HcdTailP->PhysicalAddress;
2185  TD->AltNextHcdTD = EhciEndpoint->HcdTailP;
2186 
2187  TD->HwTD.Token.InterruptOnComplete = 1;
2188 
2189  if (TransferParameters->TransferFlags & USBD_TRANSFER_DIRECTION_IN)
2191  else
2193 
2195  TD->HwTD.Token.DataToggle = 1;
2196 
2197  TransferedLen = EHCI_MapAsyncTransferToTd(EhciExtension,
2198  EhciEndpoint->EndpointProperties.MaxPacketSize,
2199  TransferedLen,
2200  0,
2201  EhciTransfer,
2202  TD,
2203  SgList);
2204 
2205  PrevTD = TD;
2206  }
2207  }
2208  else
2209  {
2210  TD = EHCI_AllocTd(EhciExtension, EhciEndpoint);
2211 
2212  if (!TD)
2213  {
2214  RegPacket.UsbPortBugCheck(EhciExtension);
2215  return MP_STATUS_FAILURE;
2216  }
2217 
2218  EhciTransfer->PendingTDs++;
2219 
2221  TD->EhciTransfer = EhciTransfer;
2222 
2223  TD->HwTD.Buffer[0] = 0;
2224  TD->HwTD.Buffer[1] = 0;
2225  TD->HwTD.Buffer[2] = 0;
2226  TD->HwTD.Buffer[3] = 0;
2227  TD->HwTD.Buffer[4] = 0;
2228 
2231 
2232  TD->HwTD.Token.AsULONG = 0;
2233  TD->HwTD.Token.ErrorCounter = 3;
2234 
2235  TD->NextHcdTD = NULL;
2236 
2237  ASSERT(EhciTransfer->PendingTDs == 1);
2238 
2239  FirstTD = TD;
2240 
2241  TD->HwTD.AlternateNextTD = EhciEndpoint->HcdTailP->PhysicalAddress;
2242  TD->AltNextHcdTD = EhciEndpoint->HcdTailP;
2243 
2244  TD->HwTD.Token.InterruptOnComplete = 1;
2245 
2246  if (TransferParameters->TransferFlags & USBD_TRANSFER_DIRECTION_IN)
2248  else
2250 
2251  TD->HwTD.Buffer[0] = TD->PhysicalAddress;
2252 
2254  TD->HwTD.Token.DataToggle = 1;
2255 
2256  TD->LengthThisTD = 0;
2257  }
2258 
2259  TD->HwTD.NextTD = EhciEndpoint->HcdTailP->PhysicalAddress;
2260  TD->NextHcdTD = EhciEndpoint->HcdTailP;
2261 
2262  EHCI_EnableAsyncList(EhciExtension);
2263  EHCI_LinkTransferToQueue(EhciExtension, EhciEndpoint, FirstTD);
2264 
2265  ASSERT(EhciEndpoint->HcdTailP->NextHcdTD == 0);
2266  ASSERT(EhciEndpoint->HcdTailP->AltNextHcdTD == 0);
2267 
2268  return MP_STATUS_SUCCESS;
2269 }
2270 
2271 MPSTATUS
2272 NTAPI
2274  IN PEHCI_ENDPOINT EhciEndpoint,
2275  IN PUSBPORT_TRANSFER_PARAMETERS TransferParameters,
2276  IN PEHCI_TRANSFER EhciTransfer,
2278 {
2279  PEHCI_HCD_TD TD;
2280  PEHCI_HCD_TD FirstTD;
2281  PEHCI_HCD_TD PrevTD = NULL;
2282  ULONG TransferedLen = 0;
2283 
2284  DPRINT_EHCI("EHCI_InterruptTransfer: EhciEndpoint - %p, EhciTransfer - %p\n",
2285  EhciEndpoint,
2286  EhciTransfer);
2287 
2288  if (!EhciEndpoint->RemainTDs)
2289  {
2290  DPRINT1("EHCI_InterruptTransfer: EhciEndpoint - %p\n", EhciEndpoint);
2291  DbgBreakPoint();
2292  return MP_STATUS_FAILURE;
2293  }
2294 
2295  EhciEndpoint->PendingTDs++;
2296 
2297  if (!TransferParameters->TransferBufferLength)
2298  {
2299  DPRINT1("EHCI_InterruptTransfer: EhciEndpoint - %p\n", EhciEndpoint);
2300  DbgBreakPoint();
2301  return MP_STATUS_FAILURE;
2302  }
2303 
2304  while (TransferedLen < TransferParameters->TransferBufferLength)
2305  {
2306  TD = EHCI_AllocTd(EhciExtension, EhciEndpoint);
2307 
2308  if (!TD)
2309  {
2310  DPRINT1("EHCI_InterruptTransfer: EhciEndpoint - %p\n", EhciEndpoint);
2311  RegPacket.UsbPortBugCheck(EhciExtension);
2312  return MP_STATUS_FAILURE;
2313  }
2314 
2315  EhciTransfer->PendingTDs++;
2316 
2318  TD->EhciTransfer = EhciTransfer;
2319 
2320  TD->HwTD.Buffer[0] = 0;
2321  TD->HwTD.Buffer[1] = 0;
2322  TD->HwTD.Buffer[2] = 0;
2323  TD->HwTD.Buffer[3] = 0;
2324  TD->HwTD.Buffer[4] = 0;
2325 
2328 
2329  TD->HwTD.Token.AsULONG = 0;
2330  TD->HwTD.Token.ErrorCounter = 3;
2331 
2332  TD->NextHcdTD = NULL;
2333 
2334  if (EhciTransfer->PendingTDs == 1)
2335  {
2336  FirstTD = TD;
2337  }
2338  else if (PrevTD)
2339  {
2340  PrevTD->HwTD.NextTD = TD->PhysicalAddress;
2341  PrevTD->NextHcdTD = TD;
2342  }
2343 
2344  if (TransferParameters->TransferFlags & USBD_TRANSFER_DIRECTION_IN)
2346  else
2348 
2350  TD->HwTD.Token.DataToggle = 1;
2351 
2352  TransferedLen = EHCI_MapAsyncTransferToTd(EhciExtension,
2353  EhciEndpoint->EndpointProperties.TotalMaxPacketSize,
2354  TransferedLen,
2355  NULL,
2356  EhciTransfer,
2357  TD,
2358  SgList);
2359 
2360  PrevTD = TD;
2361  }
2362 
2363  TD->HwTD.Token.InterruptOnComplete = 1;
2364 
2365  DPRINT_EHCI("EHCI_InterruptTransfer: PendingTDs - %x, TD->PhysicalAddress - %p, FirstTD - %p\n",
2366  EhciTransfer->PendingTDs,
2367  TD->PhysicalAddress,
2368  FirstTD);
2369 
2370  TD->HwTD.NextTD = EhciEndpoint->HcdTailP->PhysicalAddress;
2371  TD->NextHcdTD = EhciEndpoint->HcdTailP;
2372 
2373  EHCI_LinkTransferToQueue(EhciExtension, EhciEndpoint, FirstTD);
2374 
2375  ASSERT(EhciEndpoint->HcdTailP->NextHcdTD == NULL);
2376  ASSERT(EhciEndpoint->HcdTailP->AltNextHcdTD == NULL);
2377 
2378  EHCI_EnablePeriodicList(EhciExtension);
2379 
2380  return MP_STATUS_SUCCESS;
2381 }
2382 
2383 MPSTATUS
2384 NTAPI
2386  IN PVOID ehciEndpoint,
2387  IN PUSBPORT_TRANSFER_PARAMETERS TransferParameters,
2388  IN PVOID ehciTransfer,
2390 {
2391  PEHCI_EXTENSION EhciExtension = ehciExtension;
2392  PEHCI_ENDPOINT EhciEndpoint = ehciEndpoint;
2393  PEHCI_TRANSFER EhciTransfer = ehciTransfer;
2394  MPSTATUS MPStatus;
2395 
2396  DPRINT_EHCI("EHCI_SubmitTransfer: EhciEndpoint - %p, EhciTransfer - %p\n",
2397  EhciEndpoint,
2398  EhciTransfer);
2399 
2400  RtlZeroMemory(EhciTransfer, sizeof(EHCI_TRANSFER));
2401 
2402  EhciTransfer->TransferParameters = TransferParameters;
2403  EhciTransfer->USBDStatus = USBD_STATUS_SUCCESS;
2404  EhciTransfer->EhciEndpoint = EhciEndpoint;
2405 
2406  switch (EhciEndpoint->EndpointProperties.TransferType)
2407  {
2409  MPStatus = EHCI_ControlTransfer(EhciExtension,
2410  EhciEndpoint,
2411  TransferParameters,
2412  EhciTransfer,
2413  SgList);
2414  break;
2415 
2417  MPStatus = EHCI_BulkTransfer(EhciExtension,
2418  EhciEndpoint,
2419  TransferParameters,
2420  EhciTransfer,
2421  SgList);
2422  break;
2423 
2425  MPStatus = EHCI_InterruptTransfer(EhciExtension,
2426  EhciEndpoint,
2427  TransferParameters,
2428  EhciTransfer,
2429  SgList);
2430  break;
2431 
2432  default:
2433  DbgBreakPoint();
2434  MPStatus = MP_STATUS_NOT_SUPPORTED;
2435  break;
2436  }
2437 
2438  return MPStatus;
2439 }
2440 
2441 MPSTATUS
2442 NTAPI
2444  IN PVOID ehciEndpoint,
2445  IN PUSBPORT_TRANSFER_PARAMETERS TransferParameters,
2446  IN PVOID ehciTransfer,
2447  IN PVOID isoParameters)
2448 {
2449  DPRINT1("EHCI_SubmitIsoTransfer: UNIMPLEMENTED. FIXME\n");
2450  return MP_STATUS_SUCCESS;
2451 }
2452 
2453 VOID
2454 NTAPI
2456  IN PEHCI_ENDPOINT EhciEndpoint,
2457  IN PEHCI_TRANSFER EhciTransfer)
2458 {
2459  DPRINT1("EHCI_AbortIsoTransfer: UNIMPLEMENTED. FIXME\n");
2460 }
2461 
2462 VOID
2463 NTAPI
2465  IN PEHCI_ENDPOINT EhciEndpoint,
2466  IN PEHCI_TRANSFER EhciTransfer)
2467 {
2468  PEHCI_HCD_QH QH;
2469  PEHCI_HCD_TD TD;
2470  ULONG TransferLength;
2471  PEHCI_HCD_TD CurrentTD;
2472  PEHCI_TRANSFER CurrentTransfer;
2473  ULONG FirstTdPA;
2474  PEHCI_HCD_TD LastTD;
2475  PEHCI_HCD_TD PrevTD;
2476  ULONG NextTD;
2477 
2478  DPRINT("EHCI_AbortAsyncTransfer: EhciEndpoint - %p, EhciTransfer - %p\n",
2479  EhciEndpoint,
2480  EhciTransfer);
2481 
2482  QH = EhciEndpoint->QH;
2483  TD = EhciEndpoint->HcdHeadP;
2484 
2485  ASSERT(EhciEndpoint->PendingTDs);
2486  EhciEndpoint->PendingTDs--;
2487 
2488  if (TD->EhciTransfer == EhciTransfer)
2489  {
2490  TransferLength = 0;
2491 
2492  while (TD != EhciEndpoint->HcdTailP &&
2493  TD->EhciTransfer == EhciTransfer)
2494  {
2495  TransferLength += TD->LengthThisTD - TD->HwTD.Token.TransferBytes;
2496 
2497  TD->HwTD.NextTD = 0;
2498  TD->HwTD.AlternateNextTD = 0;
2499 
2500  TD->TdFlags = 0;
2501  TD->EhciTransfer = NULL;
2502 
2503  EhciEndpoint->RemainTDs++;
2504 
2505  TD = TD->NextHcdTD;
2506  }
2507 
2508  if (TransferLength)
2509  EhciTransfer->TransferLen += TransferLength;
2510 
2511  QH->sqh.HwQH.CurrentTD = EhciEndpoint->DmaBufferPA;
2512  QH->sqh.HwQH.NextTD = TD->PhysicalAddress;
2514 
2515  QH->sqh.HwQH.Token.TransferBytes = 0;
2518 
2519  EhciEndpoint->HcdHeadP = TD;
2520  }
2521  else
2522  {
2523  DPRINT("EHCI_AbortAsyncTransfer: TD->EhciTransfer - %p\n", TD->EhciTransfer);
2524 
2526  EhciExtension,
2527  EhciEndpoint);
2528 
2529  CurrentTransfer = CurrentTD->EhciTransfer;
2530  TD = EhciEndpoint->HcdHeadP;
2531 
2532  while (TD && TD->EhciTransfer != EhciTransfer)
2533  {
2534  PrevTD = TD;
2535  TD = TD->NextHcdTD;
2536  }
2537 
2538  FirstTdPA = TD->PhysicalAddress;
2539 
2540  while (TD && TD->EhciTransfer == EhciTransfer)
2541  {
2542  TD->HwTD.NextTD = 0;
2543  TD->HwTD.AlternateNextTD = 0;
2544 
2545  TD->TdFlags = 0;
2546  TD->EhciTransfer = NULL;
2547 
2548  EhciEndpoint->RemainTDs++;
2549 
2550  TD = TD->NextHcdTD;
2551  }
2552 
2553  LastTD = TD;
2554  NextTD = LastTD->PhysicalAddress + FIELD_OFFSET(EHCI_HCD_TD, HwTD.NextTD);
2555 
2556  PrevTD->HwTD.NextTD = LastTD->PhysicalAddress;
2557  PrevTD->HwTD.AlternateNextTD = LastTD->PhysicalAddress;
2558 
2559  PrevTD->NextHcdTD = LastTD;
2560  PrevTD->AltNextHcdTD = LastTD;
2561 
2562  if (CurrentTransfer == EhciTransfer)
2563  {
2564  QH->sqh.HwQH.CurrentTD = EhciEndpoint->DmaBufferPA;
2565 
2567  QH->sqh.HwQH.Token.TransferBytes = 0;
2568 
2569  QH->sqh.HwQH.NextTD = NextTD;
2571 
2572  return;
2573  }
2574 
2575  if (PrevTD->EhciTransfer == CurrentTransfer)
2576  {
2577  if (QH->sqh.HwQH.NextTD == FirstTdPA)
2578  QH->sqh.HwQH.NextTD = NextTD;
2579 
2580  if (QH->sqh.HwQH.AlternateNextTD == FirstTdPA)
2581  QH->sqh.HwQH.AlternateNextTD = NextTD;
2582 
2583  for (TD = EhciEndpoint->HcdHeadP;
2584  TD;
2585  TD = TD->NextHcdTD)
2586  {
2587  if (TD->EhciTransfer == CurrentTransfer)
2588  {
2589  TD->HwTD.AlternateNextTD = NextTD;
2590  TD->AltNextHcdTD = LastTD;
2591  }
2592  }
2593  }
2594  }
2595 }
2596 
2597 VOID
2598 NTAPI
2600  IN PVOID ehciEndpoint,
2601  IN PVOID ehciTransfer,
2602  IN PULONG CompletedLength)
2603 {
2604  PEHCI_EXTENSION EhciExtension = ehciExtension;
2605  PEHCI_ENDPOINT EhciEndpoint = ehciEndpoint;
2606  PEHCI_TRANSFER EhciTransfer = ehciTransfer;
2607  ULONG TransferType;
2608 
2609  DPRINT("EHCI_AbortTransfer: EhciTransfer - %p, CompletedLength - %x\n",
2610  EhciTransfer,
2611  CompletedLength);
2612 
2613  TransferType = EhciEndpoint->EndpointProperties.TransferType;
2614 
2615  if (TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS)
2616  EHCI_AbortIsoTransfer(EhciExtension, EhciEndpoint, EhciTransfer);
2617  else
2618  EHCI_AbortAsyncTransfer(EhciExtension, EhciEndpoint, EhciTransfer);
2619 }
2620 
2621 ULONG
2622 NTAPI
2624  IN PVOID ehciEndpoint)
2625 {
2626  DPRINT1("EHCI_GetEndpointState: UNIMPLEMENTED. FIXME\n");
2627  return 0;
2628 }
2629 
2630 VOID
2631 NTAPI
2633  IN PEHCI_ENDPOINT EhciEndpoint)
2634 {
2635  PEHCI_HCD_QH QH;
2636  PEHCI_HCD_QH NextHead;
2637  ULONG NextQhPA;
2638  PEHCI_HCD_QH PrevHead;
2639 
2640  QH = EhciEndpoint->QH;
2641 
2642  if (!(QH->sqh.QhFlags & EHCI_QH_FLAG_IN_SCHEDULE))
2643  return;
2644 
2645  DPRINT("EHCI_RemoveQhFromPeriodicList: EhciEndpoint - %p, QH - %X, EhciEndpoint->StaticQH - %p\n",
2646  EhciEndpoint,
2647  QH,
2648  EhciEndpoint->StaticQH);
2649 
2650  NextHead = QH->sqh.NextHead;
2651  PrevHead = QH->sqh.PrevHead;
2652 
2653  PrevHead->sqh.NextHead = NextHead;
2654 
2655  if (NextHead)
2656  {
2657  if (!(NextHead->sqh.QhFlags & EHCI_QH_FLAG_STATIC))
2658  NextHead->sqh.PrevHead = PrevHead;
2659 
2660  NextQhPA = NextHead->sqh.PhysicalAddress;
2661  NextQhPA &= LINK_POINTER_MASK + TERMINATE_POINTER;
2662  NextQhPA |= (EHCI_LINK_TYPE_QH << 1);
2663 
2664  PrevHead->sqh.HwQH.HorizontalLink.AsULONG = NextQhPA;
2665  }
2666  else
2667  {
2668  PrevHead->sqh.HwQH.HorizontalLink.Terminate = 1;
2669  }
2670 
2672 
2673  QH->sqh.NextHead = NULL;
2674  QH->sqh.PrevHead = NULL;
2675 }
2676 
2677 VOID
2678 NTAPI
2680  IN PEHCI_HCD_QH QH)
2681 {
2682  PEHCI_HCD_QH NextHead;
2683  ULONG NextHeadPA;
2684  PEHCI_HCD_QH PrevHead;
2685  PEHCI_STATIC_QH AsyncHead;
2686  ULONG AsyncHeadPA;
2687 
2688  DPRINT("EHCI_RemoveQhFromAsyncList: QH - %p\n", QH);
2689 
2690  if (QH->sqh.QhFlags & EHCI_QH_FLAG_IN_SCHEDULE)
2691  {
2692  NextHead = QH->sqh.NextHead;
2693  PrevHead = QH->sqh.PrevHead;
2694 
2695  AsyncHead = EhciExtension->AsyncHead;
2696 
2697  AsyncHeadPA = AsyncHead->PhysicalAddress;
2698  AsyncHeadPA &= LINK_POINTER_MASK + TERMINATE_POINTER;
2699  AsyncHeadPA |= (EHCI_LINK_TYPE_QH << 1);
2700 
2701  NextHeadPA = NextHead->sqh.PhysicalAddress;
2702  NextHeadPA &= LINK_POINTER_MASK + TERMINATE_POINTER;
2703  NextHeadPA |= (EHCI_LINK_TYPE_QH << 1);
2704 
2705  PrevHead->sqh.HwQH.HorizontalLink.AsULONG = NextHeadPA;
2706 
2707  PrevHead->sqh.NextHead = NextHead;
2708  NextHead->sqh.PrevHead = PrevHead;
2709 
2710  EHCI_FlushAsyncCache(EhciExtension);
2711 
2712  if (READ_REGISTER_ULONG(&EhciExtension->OperationalRegs->AsyncListBase) ==
2713  QH->sqh.PhysicalAddress)
2714  {
2715  WRITE_REGISTER_ULONG(&EhciExtension->OperationalRegs->AsyncListBase,
2716  AsyncHeadPA);
2717  }
2718 
2719  QH->sqh.QhFlags &= ~EHCI_QH_FLAG_IN_SCHEDULE;
2720  }
2721 }
2722 
2723 VOID
2724 NTAPI
2726  IN PEHCI_ENDPOINT EhciEndpoint)
2727 {
2728  PEHCI_STATIC_QH StaticQH;
2729  PEHCI_HCD_QH QH;
2730  ULONG QhPA;
2731  PEHCI_HCD_QH NextHead;
2732  PEHCI_HCD_QH PrevHead;
2733 
2734  QH = EhciEndpoint->QH;
2735  StaticQH = EhciEndpoint->StaticQH;
2736 
2738  ASSERT(StaticQH->QhFlags & EHCI_QH_FLAG_STATIC);
2739 
2740  NextHead = StaticQH->NextHead;
2741 
2742  QH->sqh.Period = EhciEndpoint->EndpointProperties.Period;
2743  QH->sqh.Ordinal = EhciEndpoint->EndpointProperties.Reserved6;
2744 
2745  DPRINT("EHCI_InsertQhInPeriodicList: EhciEndpoint - %p, QH - %X, EhciEndpoint->StaticQH - %p\n",
2746  EhciEndpoint,
2747  QH,
2748  EhciEndpoint->StaticQH);
2749 
2750  PrevHead = (PEHCI_HCD_QH)StaticQH;
2751 
2752  if ((StaticQH->QhFlags & EHCI_QH_FLAG_STATIC) &&
2753  (!NextHead || (NextHead->sqh.QhFlags & EHCI_QH_FLAG_STATIC)))
2754  {
2755  DPRINT("EHCI_InsertQhInPeriodicList: StaticQH - %p, StaticQH->NextHead - %p\n",
2756  StaticQH,
2757  StaticQH->NextHead);
2758  }
2759  else
2760  {
2761  while (NextHead &&
2762  !(NextHead->sqh.QhFlags & EHCI_QH_FLAG_STATIC) &&
2763  QH->sqh.Ordinal > NextHead->sqh.Ordinal)
2764  {
2765  PrevHead = NextHead;
2766  NextHead = NextHead->sqh.NextHead;
2767  }
2768  }
2769 
2770  QH->sqh.NextHead = NextHead;
2771  QH->sqh.PrevHead = PrevHead;
2772 
2773  if (NextHead && !(NextHead->sqh.QhFlags & EHCI_QH_FLAG_STATIC))
2774  NextHead->sqh.PrevHead = QH;
2775 
2777  QH->sqh.HwQH.HorizontalLink = PrevHead->sqh.HwQH.HorizontalLink;
2778 
2779  PrevHead->sqh.NextHead = QH;
2780 
2781  QhPA = QH->sqh.PhysicalAddress;
2783  QhPA |= (EHCI_LINK_TYPE_QH << 1);
2784 
2785  PrevHead->sqh.HwQH.HorizontalLink.AsULONG = QhPA;
2786 }
2787 
2788 VOID
2789 NTAPI
2791  IN PEHCI_HCD_QH QH)
2792 {
2793  PEHCI_STATIC_QH AsyncHead;
2794  ULONG QhPA;
2795  PEHCI_HCD_QH NextHead;
2796 
2797  DPRINT("EHCI_InsertQhInAsyncList: QH - %p\n", QH);
2798 
2799  ASSERT((QH->sqh.QhFlags & EHCI_QH_FLAG_IN_SCHEDULE) == 0);
2800  ASSERT((QH->sqh.QhFlags & EHCI_QH_FLAG_NUKED) == 0);
2801 
2802  AsyncHead = EhciExtension->AsyncHead;
2803  NextHead = AsyncHead->NextHead;
2804 
2805  QH->sqh.HwQH.HorizontalLink = AsyncHead->HwQH.HorizontalLink;
2806  QH->sqh.QhFlags |= EHCI_QH_FLAG_IN_SCHEDULE;
2807  QH->sqh.NextHead = NextHead;
2808  QH->sqh.PrevHead = (PEHCI_HCD_QH)AsyncHead;
2809 
2810  NextHead->sqh.PrevHead = QH;
2811 
2812  QhPA = QH->sqh.PhysicalAddress;
2814  QhPA |= (EHCI_LINK_TYPE_QH << 1);
2815 
2816  AsyncHead->HwQH.HorizontalLink.AsULONG = QhPA;
2817 
2818  AsyncHead->NextHead = QH;
2819 }
2820 
2821 VOID
2822 NTAPI
2824  IN PEHCI_ENDPOINT EhciEndpoint,
2825  IN ULONG EndpointState)
2826 {
2827  DPRINT1("EHCI_SetIsoEndpointState: UNIMPLEMENTED. FIXME\n");
2828 }
2829 
2830 VOID
2831 NTAPI
2833  IN PEHCI_ENDPOINT EhciEndpoint,
2834  IN ULONG EndpointState)
2835 {
2836  PEHCI_HCD_QH QH;
2837  ULONG TransferType;
2838 
2839  DPRINT("EHCI_SetAsyncEndpointState: EhciEndpoint - %p, EndpointState - %x\n",
2840  EhciEndpoint,
2841  EndpointState);
2842 
2843  QH = EhciEndpoint->QH;
2844 
2845  TransferType = EhciEndpoint->EndpointProperties.TransferType;
2846 
2847  switch (EndpointState)
2848  {
2850  if (TransferType == USBPORT_TRANSFER_TYPE_INTERRUPT)
2851  EHCI_RemoveQhFromPeriodicList(EhciExtension, EhciEndpoint);
2852  else
2853  EHCI_RemoveQhFromAsyncList(EhciExtension, EhciEndpoint->QH);
2854 
2855  break;
2856 
2858  if (TransferType == USBPORT_TRANSFER_TYPE_INTERRUPT)
2859  EHCI_InsertQhInPeriodicList(EhciExtension, EhciEndpoint);
2860  else
2861  EHCI_InsertQhInAsyncList(EhciExtension, EhciEndpoint->QH);
2862 
2863  break;
2864 
2867 
2868  if (TransferType == USBPORT_TRANSFER_TYPE_INTERRUPT)
2869  EHCI_RemoveQhFromPeriodicList(EhciExtension, EhciEndpoint);
2870  else
2871  EHCI_RemoveQhFromAsyncList(EhciExtension, EhciEndpoint->QH);
2872 
2873  break;
2874 
2875  default:
2876  DbgBreakPoint();
2877  break;
2878  }
2879 
2880  EhciEndpoint->EndpointState = EndpointState;
2881 }
2882 
2883 VOID
2884 NTAPI
2886  IN PVOID ehciEndpoint,
2887  IN ULONG EndpointState)
2888 {
2889  PEHCI_ENDPOINT EhciEndpoint;
2890  ULONG TransferType;
2891 
2892  DPRINT("EHCI_SetEndpointState: ... \n");
2893 
2894  EhciEndpoint = ehciEndpoint;
2895  TransferType = EhciEndpoint->EndpointProperties.TransferType;
2896 
2897  if (TransferType == USBPORT_TRANSFER_TYPE_CONTROL ||
2898  TransferType == USBPORT_TRANSFER_TYPE_BULK ||
2899  TransferType == USBPORT_TRANSFER_TYPE_INTERRUPT)
2900  {
2902  EhciEndpoint,
2903  EndpointState);
2904  }
2905  else if (TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS)
2906  {
2908  EhciEndpoint,
2909  EndpointState);
2910  }
2911  else
2912  {
2913  RegPacket.UsbPortBugCheck(ehciExtension);
2914  }
2915 }
2916 
2917 VOID
2918 NTAPI
2920 {
2921  PEHCI_EXTENSION EhciExtension = ehciExtension;
2922 
2923  DPRINT_EHCI("EHCI_InterruptNextSOF: ... \n");
2924 
2925  RegPacket.UsbPortInvalidateController(EhciExtension,
2927 }
2928 
2930 NTAPI
2932 {
2934 
2935  DPRINT_EHCI("EHCI_GetErrorFromTD: ... \n");
2936 
2937  ASSERT(TD->HwTD.Token.Status & EHCI_TOKEN_STATUS_HALTED);
2938 
2939  Token = TD->HwTD.Token;
2940 
2942  {
2943  DPRINT("EHCI_GetErrorFromTD: TD - %p, TRANSACTION_ERROR\n", TD);
2944  return USBD_STATUS_XACT_ERROR;
2945  }
2946 
2948  {
2949  DPRINT("EHCI_GetErrorFromTD: TD - %p, BABBLE_DETECTED\n", TD);
2951  }
2952 
2954  {
2955  DPRINT("EHCI_GetErrorFromTD: TD - %p, DATA_BUFFER_ERROR\n", TD);
2957  }
2958 
2960  {
2961  DPRINT("EHCI_GetErrorFromTD: TD - %p, MISSED_MICROFRAME\n", TD);
2962  return USBD_STATUS_XACT_ERROR;
2963  }
2964 
2965  DPRINT("EHCI_GetErrorFromTD: TD - %p, STALL_PID\n", TD);
2966  return USBD_STATUS_STALL_PID;
2967 }
2968 
2969 VOID
2970 NTAPI
2972  IN PEHCI_HCD_TD TD)
2973 {
2974  PEHCI_TRANSFER EhciTransfer;
2975  PUSBPORT_TRANSFER_PARAMETERS TransferParameters;
2976  ULONG TransferType;
2977  PEHCI_ENDPOINT EhciEndpoint;
2978  ULONG LengthTransfered;
2979  USBD_STATUS USBDStatus;
2980  PEHCI_HW_REGISTERS OperationalRegs;
2982 
2983  DPRINT_EHCI("EHCI_ProcessDoneAsyncTd: TD - %p\n", TD);
2984 
2985  EhciTransfer = TD->EhciTransfer;
2986 
2987  TransferParameters = EhciTransfer->TransferParameters;
2988  EhciTransfer->PendingTDs--;
2989 
2990  EhciEndpoint = EhciTransfer->EhciEndpoint;
2991 
2992  if (!(TD->TdFlags & EHCI_HCD_TD_FLAG_ACTIVE))
2993  {
2994 
2995  if (TD->HwTD.Token.Status & EHCI_TOKEN_STATUS_HALTED)
2996  USBDStatus = EHCI_GetErrorFromTD(TD);
2997  else
2998  USBDStatus = USBD_STATUS_SUCCESS;
2999 
3000  LengthTransfered = TD->LengthThisTD - TD->HwTD.Token.TransferBytes;
3001 
3002  if (TD->HwTD.Token.PIDCode != EHCI_TD_TOKEN_PID_SETUP)
3003  EhciTransfer->TransferLen += LengthTransfered;
3004 
3005  if (USBDStatus != USBD_STATUS_SUCCESS)
3006  EhciTransfer->USBDStatus = USBDStatus;
3007  }
3008 
3009  TD->HwTD.NextTD = 0;
3010  TD->HwTD.AlternateNextTD = 0;
3011 
3012  TD->TdFlags = 0;
3013  TD->EhciTransfer = NULL;
3014 
3015  EhciEndpoint->RemainTDs++;
3016 
3017  if (EhciTransfer->PendingTDs == 0)
3018  {
3019  EhciEndpoint->PendingTDs--;
3020 
3021  TransferType = EhciEndpoint->EndpointProperties.TransferType;
3022 
3023  if (TransferType == USBPORT_TRANSFER_TYPE_CONTROL ||
3024  TransferType == USBPORT_TRANSFER_TYPE_BULK)
3025  {
3026  EhciExtension->PendingTransfers--;
3027 
3028  if (EhciExtension->PendingTransfers == 0)
3029  {
3030  OperationalRegs = EhciExtension->OperationalRegs;
3031  Command.AsULONG = READ_REGISTER_ULONG(&OperationalRegs->HcCommand.AsULONG);
3032 
3033  if (!Command.InterruptAdvanceDoorbell &&
3034  (EhciExtension->Flags & EHCI_FLAGS_IDLE_SUPPORT))
3035  {
3036  EHCI_DisableAsyncList(EhciExtension);
3037  }
3038  }
3039  }
3040 
3041  RegPacket.UsbPortCompleteTransfer(EhciExtension,
3042  EhciEndpoint,
3043  TransferParameters,
3044  EhciTransfer->USBDStatus,
3045  EhciTransfer->TransferLen);
3046  }
3047 }
3048 
3049 VOID
3050 NTAPI
3052  IN PEHCI_ENDPOINT EhciEndpoint)
3053 {
3054  PEHCI_HCD_QH QH;
3055  PEHCI_HCD_TD TD;
3056  PEHCI_HCD_TD CurrentTD;
3057  ULONG CurrentTDPhys;
3058  BOOLEAN IsScheduled;
3059 
3060  DPRINT_EHCI("EHCI_PollActiveAsyncEndpoint: ... \n");
3061 
3062  QH = EhciEndpoint->QH;
3063 
3064  CurrentTDPhys = QH->sqh.HwQH.CurrentTD & LINK_POINTER_MASK;
3065  ASSERT(CurrentTDPhys);
3066 
3067  CurrentTD = RegPacket.UsbPortGetMappedVirtualAddress(CurrentTDPhys,
3068  EhciExtension,
3069  EhciEndpoint);
3070 
3071  if (CurrentTD == EhciEndpoint->DmaBufferVA)
3072  return;
3073 
3074  IsScheduled = QH->sqh.QhFlags & EHCI_QH_FLAG_IN_SCHEDULE;
3075 
3076  if (!EHCI_HardwarePresent(EhciExtension, 0))
3077  IsScheduled = 0;
3078 
3079  TD = EhciEndpoint->HcdHeadP;
3080 
3081  if (TD == CurrentTD)
3082  {
3083  if (TD != EhciEndpoint->HcdTailP &&
3085  {
3086  if (TD->NextHcdTD && TD->HwTD.NextTD != TD->NextHcdTD->PhysicalAddress)
3087  TD->HwTD.NextTD = TD->NextHcdTD->PhysicalAddress;
3088 
3089  if (TD->AltNextHcdTD &&
3090  TD->HwTD.AlternateNextTD != TD->AltNextHcdTD->PhysicalAddress)
3091  {
3092  TD->HwTD.AlternateNextTD = TD->AltNextHcdTD->PhysicalAddress;
3093  }
3094 
3095  if (QH->sqh.HwQH.CurrentTD == TD->PhysicalAddress &&
3097  (QH->sqh.HwQH.NextTD != TD->HwTD.NextTD ||
3099  {
3100  QH->sqh.HwQH.NextTD = TD->HwTD.NextTD;
3102  }
3103 
3104  EHCI_InterruptNextSOF(EhciExtension);
3105  }
3106  }
3107  else
3108  {
3109  while (TD != CurrentTD)
3110  {
3111  ASSERT((TD->TdFlags & EHCI_HCD_TD_FLAG_DUMMY) == 0);
3112 
3114 
3117 
3118  InsertTailList(&EhciEndpoint->ListTDs, &TD->DoneLink);
3119  TD = TD->NextHcdTD;
3120  }
3121  }
3122 
3123  if (CurrentTD->HwTD.Token.Status & EHCI_TOKEN_STATUS_ACTIVE)
3124  {
3125  ASSERT(TD != NULL);
3126  EhciEndpoint->HcdHeadP = TD;
3127  return;
3128  }
3129 
3130  if ((CurrentTD->NextHcdTD != EhciEndpoint->HcdTailP) &&
3131  (CurrentTD->AltNextHcdTD != EhciEndpoint->HcdTailP ||
3132  CurrentTD->HwTD.Token.TransferBytes == 0))
3133  {
3134  ASSERT(TD != NULL);
3135  EhciEndpoint->HcdHeadP = TD;
3136  return;
3137  }
3138 
3139  if (IsScheduled)
3140  {
3141  EHCI_LockQH(EhciExtension,
3142  QH,
3143  EhciEndpoint->EndpointProperties.TransferType);
3144  }
3145 
3146  QH->sqh.HwQH.CurrentTD = EhciEndpoint->DmaBufferPA;
3147 
3148  CurrentTD->TdFlags |= EHCI_HCD_TD_FLAG_DONE;
3149  InsertTailList(&EhciEndpoint->ListTDs, &CurrentTD->DoneLink);
3150 
3151  if (CurrentTD->HwTD.Token.TransferBytes &&
3152  CurrentTD->AltNextHcdTD == EhciEndpoint->HcdTailP)
3153  {
3154  TD = CurrentTD->NextHcdTD;
3155 
3156  while (TD != EhciEndpoint->HcdTailP)
3157  {
3159  InsertTailList(&EhciEndpoint->ListTDs, &TD->DoneLink);
3160  TD = TD->NextHcdTD;
3161  }
3162  }
3163 
3164  QH->sqh.HwQH.CurrentTD = EhciEndpoint->HcdTailP->PhysicalAddress;
3167  QH->sqh.HwQH.Token.TransferBytes = 0;
3168 
3169  EhciEndpoint->HcdHeadP = EhciEndpoint->HcdTailP;
3170 
3171  if (IsScheduled)
3172  EHCI_UnlockQH(EhciExtension, QH);
3173 }
3174 
3175 VOID
3176 NTAPI
3178  IN PEHCI_ENDPOINT EhciEndpoint)
3179 {
3180  PEHCI_HCD_QH QH;
3181  PEHCI_HCD_TD CurrentTD;
3182  ULONG CurrentTdPA;
3183  PEHCI_HCD_TD TD;
3184  PEHCI_TRANSFER Transfer;
3185  BOOLEAN IsScheduled;
3186 
3187  DPRINT("EHCI_PollHaltedAsyncEndpoint: EhciEndpoint - %p\n", EhciEndpoint);
3188 
3189  QH = EhciEndpoint->QH;
3190  EHCI_DumpHwQH(QH);
3191 
3192  CurrentTdPA = QH->sqh.HwQH.CurrentTD & LINK_POINTER_MASK;
3193  ASSERT(CurrentTdPA);
3194 
3195  IsScheduled = QH->sqh.QhFlags & EHCI_QH_FLAG_IN_SCHEDULE;
3196 
3197  if (!EHCI_HardwarePresent(EhciExtension, 0))
3198  IsScheduled = 0;
3199 
3200  CurrentTD = RegPacket.UsbPortGetMappedVirtualAddress(CurrentTdPA,
3201  EhciExtension,
3202  EhciEndpoint);
3203 
3204  DPRINT("EHCI_PollHaltedAsyncEndpoint: CurrentTD - %p\n", CurrentTD);
3205 
3206  if (CurrentTD == EhciEndpoint->DmaBufferVA)
3207  return;
3208 
3209  ASSERT(EhciEndpoint->HcdTailP != CurrentTD);
3210 
3211  if (IsScheduled)
3212  {
3213  EHCI_LockQH(EhciExtension,
3214  QH,
3215  EhciEndpoint->EndpointProperties.TransferType);
3216  }
3217 
3218  TD = EhciEndpoint->HcdHeadP;
3219 
3220  while (TD != CurrentTD)
3221  {
3222  DPRINT("EHCI_PollHaltedAsyncEndpoint: TD - %p\n", TD);
3223 
3224  ASSERT((TD->TdFlags & EHCI_HCD_TD_FLAG_DUMMY) == 0);
3225 
3228 
3230 
3231  InsertTailList(&EhciEndpoint->ListTDs, &TD->DoneLink);
3232 
3233  TD = TD->NextHcdTD;
3234  }
3235 
3236  TD = CurrentTD;
3237 
3238  Transfer = CurrentTD->EhciTransfer;
3239 
3240  do
3241  {
3242  DPRINT("EHCI_PollHaltedAsyncEndpoint: TD - %p\n", TD);
3243 
3246 
3248 
3249  InsertTailList(&EhciEndpoint->ListTDs, &TD->DoneLink);
3250 
3251  TD = TD->NextHcdTD;
3252  }
3253  while (TD->EhciTransfer == Transfer);
3254 
3255  EhciEndpoint->HcdHeadP = TD;
3256 
3257  QH->sqh.HwQH.CurrentTD = EhciEndpoint->DmaBufferPA;
3258  QH->sqh.HwQH.NextTD = TD->PhysicalAddress;
3260  QH->sqh.HwQH.Token.TransferBytes = 0;
3261 
3262  if (IsScheduled)
3263  EHCI_UnlockQH(EhciExtension, QH);
3264 
3265  if (EhciEndpoint->EndpointStatus & USBPORT_ENDPOINT_CONTROL)
3266  {
3267  EhciEndpoint->EndpointStatus &= ~USBPORT_ENDPOINT_HALT;
3268  QH->sqh.HwQH.Token.ErrorCounter = 0;
3271 
3272  }
3273 }
3274 
3275 VOID
3276 NTAPI
3278  IN PEHCI_ENDPOINT EhciEndpoint)
3279 {
3280  PEHCI_HCD_QH QH;
3281  PLIST_ENTRY DoneList;
3282  PEHCI_HCD_TD TD;
3283 
3284  //DPRINT_EHCI("EHCI_PollAsyncEndpoint: EhciEndpoint - %p\n", EhciEndpoint);
3285 
3286  if (!EhciEndpoint->PendingTDs)
3287  return;
3288 
3289  QH = EhciEndpoint->QH;
3290 
3291  if (QH->sqh.QhFlags & EHCI_QH_FLAG_CLOSED)
3292  return;
3293 
3296  {
3297  EHCI_PollActiveAsyncEndpoint(EhciExtension, EhciEndpoint);
3298  }
3299  else
3300  {
3301  EhciEndpoint->EndpointStatus |= USBPORT_ENDPOINT_HALT;
3302  EHCI_PollHaltedAsyncEndpoint(EhciExtension, EhciEndpoint);
3303  }
3304 
3305  DoneList = &EhciEndpoint->ListTDs;
3306 
3307  while (!IsListEmpty(DoneList))
3308  {
3309  TD = CONTAINING_RECORD(DoneList->Flink,
3310  EHCI_HCD_TD,
3311  DoneLink);
3312 
3313  RemoveHeadList(DoneList);
3314 
3317 
3318  EHCI_ProcessDoneAsyncTd(EhciExtension, TD);
3319  }
3320 }
3321 
3322 VOID
3323 NTAPI
3325  IN PEHCI_ENDPOINT EhciEndpoint)
3326 {
3327  DPRINT1("EHCI_PollIsoEndpoint: UNIMPLEMENTED. FIXME\n");
3328 }
3329 
3330 VOID
3331 NTAPI
3333  IN PVOID ehciEndpoint)
3334 {
3335  PEHCI_EXTENSION EhciExtension = ehciExtension;
3336  PEHCI_ENDPOINT EhciEndpoint = ehciEndpoint;
3337  ULONG TransferType;
3338 
3339  //DPRINT_EHCI("EHCI_PollEndpoint: EhciEndpoint - %p\n", EhciEndpoint);
3340 
3341  TransferType = EhciEndpoint->EndpointProperties.TransferType;
3342 
3343  if (TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS)
3344  EHCI_PollIsoEndpoint(EhciExtension, EhciEndpoint);
3345  else
3346  EHCI_PollAsyncEndpoint(EhciExtension, EhciEndpoint);
3347 }
3348 
3349 VOID
3350 NTAPI
3352 {
3353  PEHCI_EXTENSION EhciExtension = ehciExtension;
3354 
3355  //DPRINT_EHCI("EHCI_CheckController: ... \n");
3356 
3357  if (EhciExtension->IsStarted)
3358  EHCI_HardwarePresent(EhciExtension, TRUE);
3359 }
3360 
3361 ULONG
3362 NTAPI
3364 {
3365  PEHCI_EXTENSION EhciExtension = ehciExtension;
3366  ULONG FrameIdx;
3367  ULONG FrameIndex;
3368  ULONG FrameNumber;
3369 
3370  //DPRINT_EHCI("EHCI_Get32BitFrameNumber: EhciExtension - %p\n", EhciExtension);
3371 
3372  FrameIdx = EhciExtension->FrameIndex;
3373  FrameIndex = READ_REGISTER_ULONG(&EhciExtension->OperationalRegs->FrameIndex);
3374 
3375  FrameNumber = (USHORT)FrameIdx ^ ((FrameIndex / EHCI_MICROFRAMES) & EHCI_FRINDEX_FRAME_MASK);
3376  FrameNumber &= EHCI_FRAME_LIST_MAX_ENTRIES;
3377  FrameNumber += FrameIndex | ((FrameIndex / EHCI_MICROFRAMES) & EHCI_FRINDEX_INDEX_MASK);
3378 
3379  return FrameNumber;
3380 }
3381 
3382 VOID
3383 NTAPI
3385 {
3386  PEHCI_EXTENSION EhciExtension = ehciExtension;
3387 
3388  DPRINT("EHCI_EnableInterrupts: EhciExtension->InterruptMask - %x\n",
3389  EhciExtension->InterruptMask.AsULONG);
3390 
3392  EhciExtension->InterruptMask.AsULONG);
3393 }
3394 
3395 VOID
3396 NTAPI
3398 {
3399  PEHCI_EXTENSION EhciExtension = ehciExtension;
3400 
3401  DPRINT("EHCI_DisableInterrupts: ... \n");
3402 
3404  0);
3405 }
3406 
3407 VOID
3408 NTAPI
3410 {
3411  PEHCI_EXTENSION EhciExtension = ehciExtension;
3412  PEHCI_HW_REGISTERS OperationalRegs;
3413  ULONG Port;
3414  EHCI_PORT_STATUS_CONTROL PortSC;
3415 
3416  DPRINT_EHCI("EHCI_PollController: ... \n");
3417 
3418  OperationalRegs = EhciExtension->OperationalRegs;
3419 
3420  if (!(EhciExtension->Flags & EHCI_FLAGS_CONTROLLER_SUSPEND))
3421  {
3422  RegPacket.UsbPortInvalidateRootHub(EhciExtension);
3423  return;
3424  }
3425 
3426  if (EhciExtension->NumberOfPorts)
3427  {
3428  for (Port = 0; Port < EhciExtension->NumberOfPorts; Port++)
3429  {
3430  PortSC.AsULONG = READ_REGISTER_ULONG(&OperationalRegs->PortControl[Port].AsULONG);
3431 
3432  if (PortSC.ConnectStatusChange)
3433  RegPacket.UsbPortInvalidateRootHub(EhciExtension);
3434  }
3435  }
3436 }
3437 
3438 VOID
3439 NTAPI
3441  IN PVOID ehciEndpoint,
3442  IN ULONG DataToggle)
3443 {
3444  PEHCI_ENDPOINT EhciEndpoint;
3445  ULONG TransferType;
3446 
3447  EhciEndpoint = ehciEndpoint;
3448 
3449  DPRINT("EHCI_SetEndpointDataToggle: EhciEndpoint - %p, DataToggle - %x\n",
3450  EhciEndpoint,
3451  DataToggle);
3452 
3453  TransferType = EhciEndpoint->EndpointProperties.TransferType;
3454 
3455  if (TransferType == USBPORT_TRANSFER_TYPE_BULK ||
3456  TransferType == USBPORT_TRANSFER_TYPE_INTERRUPT)
3457  {
3458  EhciEndpoint->QH->sqh.HwQH.Token.DataToggle = DataToggle;
3459  }
3460 }
3461 
3462 ULONG
3463 NTAPI
3465  IN PVOID ehciEndpoint)
3466 {
3467  PEHCI_ENDPOINT EhciEndpoint;
3468  ULONG TransferType;
3469  ULONG EndpointStatus = USBPORT_ENDPOINT_RUN;
3470 
3471  EhciEndpoint = ehciEndpoint;
3472 
3473  DPRINT("EHCI_GetEndpointStatus: EhciEndpoint - %p\n", EhciEndpoint);
3474 
3475  TransferType = EhciEndpoint->EndpointProperties.TransferType;
3476 
3477  if (TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS)
3478  return EndpointStatus;
3479 
3480  if (EhciEndpoint->EndpointStatus & USBPORT_ENDPOINT_HALT)
3481  EndpointStatus = USBPORT_ENDPOINT_HALT;
3482 
3483  return EndpointStatus;
3484 }
3485 
3486 VOID
3487 NTAPI
3489  IN PVOID ehciEndpoint,
3490  IN ULONG EndpointStatus)
3491 {
3492  PEHCI_ENDPOINT EhciEndpoint;
3493  ULONG TransferType;
3494  PEHCI_HCD_QH QH;
3495 
3496  EhciEndpoint = ehciEndpoint;
3497 
3498  DPRINT("EHCI_SetEndpointStatus: EhciEndpoint - %p, EndpointStatus - %x\n",
3499  EhciEndpoint,
3500  EndpointStatus);
3501 
3502  TransferType = EhciEndpoint->EndpointProperties.TransferType;
3503 
3504  if (TransferType != USBPORT_TRANSFER_TYPE_ISOCHRONOUS)
3505  {
3506 
3507  if (EndpointStatus == USBPORT_ENDPOINT_RUN)
3508  {
3509  EhciEndpoint->EndpointStatus &= ~USBPORT_ENDPOINT_HALT;
3510 
3511  QH = EhciEndpoint->QH;
3513 
3514  return;
3515  }
3516 
3517  if (EndpointStatus == USBPORT_ENDPOINT_HALT)
3518  DbgBreakPoint();
3519  }
3520 }
3521 
3522 VOID
3523 NTAPI
3525 {
3526  DPRINT1("EHCI_ResetController: UNIMPLEMENTED. FIXME\n");
3527 }
3528 
3529 MPSTATUS
3530 NTAPI
3532  IN PVOID PacketParameters,
3533  IN PVOID Data,
3534  IN PULONG pDataLength,
3535  IN PVOID BufferVA,
3536  IN PVOID BufferPA,
3538  IN USBD_STATUS * pUSBDStatus)
3539 {
3540  DPRINT1("EHCI_StartSendOnePacket: UNIMPLEMENTED. FIXME\n");
3541  return MP_STATUS_SUCCESS;
3542 }
3543 
3544 MPSTATUS
3545 NTAPI
3547  IN PVOID PacketParameters,
3548  IN PVOID Data,
3549  IN PULONG pDataLength,
3550  IN PVOID BufferVA,
3551  IN PVOID BufferPA,
3553  IN USBD_STATUS * pUSBDStatus)
3554 {
3555  DPRINT1("EHCI_EndSendOnePacket: UNIMPLEMENTED. FIXME\n");
3556  return MP_STATUS_SUCCESS;
3557 }
3558 
3559 MPSTATUS
3560 NTAPI
3561 EHCI_PassThru(IN PVOID ehciExtension,
3562  IN PVOID passThruParameters,
3564  IN PVOID pParameters)
3565 {
3566  DPRINT1("EHCI_PassThru: UNIMPLEMENTED. FIXME\n");
3567  return MP_STATUS_SUCCESS;
3568 }
3569 
3570 VOID
3571 NTAPI
3573  IN PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties,
3574  IN PVOID ohciEndpoint)
3575 {
3576  DPRINT1("EHCI_RebalanceEndpoint: UNIMPLEMENTED. FIXME\n");
3577 }
3578 
3579 VOID
3580 NTAPI
3582 {
3583  PEHCI_EXTENSION EhciExtension = ehciExtension;
3584  PEHCI_HW_REGISTERS OperationalRegs;
3586 
3587  DPRINT("EHCI_FlushInterrupts: ... \n");
3588 
3589  OperationalRegs = EhciExtension->OperationalRegs;
3590 
3591  Status.AsULONG = READ_REGISTER_ULONG(&OperationalRegs->HcStatus.AsULONG);
3592  WRITE_REGISTER_ULONG(&OperationalRegs->HcStatus.AsULONG, Status.AsULONG);
3593 }
3594 
3595 VOID
3596 NTAPI
3598 {
3599  DPRINT1("EHCI_TakePortControl: UNIMPLEMENTED. FIXME\n");
3600 }
3601 
3602 VOID
3603 NTAPI
3605 {
3606 #if DBG
3607  DPRINT1("EHCI_Unload: Not supported\n");
3608 #endif
3609  return;
3610 }
3611 
3612 NTSTATUS
3613 NTAPI
3616 {
3617  DPRINT("DriverEntry: DriverObject - %p, RegistryPath - %wZ\n",
3618  DriverObject,
3619  RegistryPath);
3620 
3623 
3625 
3627 
3633 
3635 
3640 
3691 
3692  DriverObject->DriverUnload = EHCI_Unload;
3693 
3696  &RegPacket);
3697 }
#define USBPORT_ENDPOINT_ACTIVE
Definition: usbmport.h:15
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
ULONG MPSTATUS
Definition: usbmport.h:131
#define USBPORT_INVALIDATE_CONTROLLER_SOFT_INTERRUPT
Definition: usbmport.h:491
VOID NTAPI EHCI_EnableAsyncList(IN PEHCI_EXTENSION EhciExtension)
Definition: usbehci.c:1622
PHCI_RH_GET_STATUS RH_GetStatus
Definition: usbmport.h:586
struct _EHCI_HCD_QH * PrevHead
Definition: usbehci.h:93
#define USB_MINIPORT_FLAGS_POLLING
Definition: usbmport.h:537
PHCI_RH_GET_PORT_STATUS RH_GetPortStatus
Definition: usbmport.h:587
MPSTATUS NTAPI EHCI_ReopenEndpoint(IN PVOID ehciExtension, IN PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties, IN PVOID ehciEndpoint)
Definition: usbehci.c:559
PHCI_RH_CLEAR_FEATURE_PORT_POWER RH_ClearFeaturePortPower
Definition: usbmport.h:594
PEHCI_HC_CAPABILITY_REGISTERS CapabilityRegisters
Definition: usbehci.h:175
VOID NTAPI EHCI_SetIsoEndpointState(IN PEHCI_EXTENSION EhciExtension, IN PEHCI_ENDPOINT EhciEndpoint, IN ULONG EndpointState)
Definition: usbehci.c:2823
#define USBPORT_TRANSFER_TYPE_BULK
Definition: usbmport.h:9
VOID NTAPI EHCI_CloseEndpoint(IN PVOID ehciExtension, IN PVOID ehciEndpoint, IN BOOLEAN DisablePeriodic)
Definition: usbehci.c:703
#define EHCI_FRINDEX_INDEX_MASK
Definition: hardware.h:169
#define USB_MINIPORT_VERSION_EHCI
Definition: usbmport.h:528
#define EHCI_QH_EP_FULL_SPEED
Definition: hardware.h:371
VOID NTAPI EHCI_AbortTransfer(IN PVOID ehciExtension, IN PVOID ehciEndpoint, IN PVOID ehciTransfer, IN PULONG CompletedLength)
Definition: usbehci.c:2599
#define EHCI_MAX_FS_ISO_TRANSFER_SIZE
Definition: usbehci.h:25
EHCI_PORT_STATUS_CONTROL PortControl[15]
Definition: hardware.h:183
CPPORT Port[4]
Definition: headless.c:35
PEHCI_STATIC_QH NTAPI EHCI_GetQhForFrame(IN PEHCI_EXTENSION EhciExtension, IN ULONG FrameIdx)
Definition: usbehci.c:729
#define IN
Definition: typedefs.h:39
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3767
ULONG InterruptMask
Definition: hardware.h:394
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN IsPresent
MPSTATUS NTAPI EHCI_OpenHsIsoEndpoint(IN PEHCI_EXTENSION EhciExtension, IN PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties, IN PEHCI_ENDPOINT EhciEndpoint)
Definition: usbehci.c:474
static NTSTATUS EnableInterrupts(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR FlagsToDisable, IN UCHAR FlagsToEnable)
Definition: pnp.c:380
NTKERNELAPI VOID NTAPI WRITE_REGISTER_ULONG(IN PULONG Register, IN ULONG Value)
#define EHCI_FRAMES
Definition: usbehci.h:35
ULONG PhysicalAddress
Definition: usbehci.h:61
VOID NTAPI EHCI_AlignHwStructure(IN PEHCI_EXTENSION EhciExtension, IN PULONG PhysicalAddress, IN PULONG_PTR VirtualAddress, IN ULONG Alignment)
Definition: usbehci.c:750
ULONG USBDStatus
Definition: usbehci.h:153
PUSBPORT_TRANSFER_PARAMETERS TransferParameters
Definition: usbehci.h:152
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
static const UCHAR Balance[]
Definition: usbehci.c:97
USBPORT_REGISTRATION_PACKET RegPacket
Definition: usbehci.c:16
#define DPRINT_EHCI(...)
Definition: dbg_ehci.h:45
ULONG BackupPeriodiclistbase
Definition: usbehci.h:206
struct _EHCI_HCD_TD EHCI_HCD_TD
VOID NTAPI EHCI_TakePortControl(IN PVOID ohciExtension)
Definition: usbehci.c:3597
PHCI_SUBMIT_TRANSFER SubmitTransfer
Definition: usbmport.h:567
VOID NTAPI EHCI_RemoveQhFromAsyncList(IN PEHCI_EXTENSION EhciExtension, IN PEHCI_HCD_QH QH)
Definition: usbehci.c:2679
#define ENDPOINT_INTERRUPT_1ms
Definition: usbmport.h:25
#define EHCI_CONFIG_FLAG_CONFIGURED
Definition: hardware.h:171
#define EHCI_MAX_CONTROL_TRANSFER_SIZE
Definition: usbehci.h:22
VOID NTAPI EHCI_CheckController(IN PVOID ehciExtension)
Definition: usbehci.c:3351
#define EHCI_QH_FLAG_STATIC_FAST
Definition: usbehci.h:83
ULONG NextTD
Definition: hardware.h:361
VOID NTAPI EHCI_PollHaltedAsyncEndpoint(IN PEHCI_EXTENSION EhciExtension, IN PEHCI_ENDPOINT EhciEndpoint)
Definition: usbehci.c:3177
PHCI_RH_SET_FEATURE_PORT_ENABLE RH_SetFeaturePortEnable
Definition: usbmport.h:591
MPSTATUS NTAPI EHCI_RH_SetFeaturePortReset(IN PVOID ehciExtension, IN USHORT Port)
Definition: roothub.c:364
#define EHCI_MICROFRAMES
Definition: usbehci.h:36
EHCI_USB_COMMAND HcCommand
Definition: hardware.h:174
EHCI_QUEUE_TD HwTD
Definition: usbehci.h:59
PUSBPORT_GET_MAPPED_VIRTUAL_ADDRESS UsbPortGetMappedVirtualAddress
Definition: usbmport.h:619
#define USBPORT_ENDPOINT_RUN
Definition: usbmport.h:20
NTSTATUS NTAPI DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
Definition: usbehci.c:3614
#define TRUE
Definition: types.h:120
PHCI_RH_SET_FEATURE_PORT_POWER RH_SetFeaturePortPower
Definition: usbmport.h:590
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_opt_ WDFREQUEST _In_opt_ PWDF_REQUEST_SEND_OPTIONS _In_ PWDF_USB_CONTROL_SETUP_PACKET SetupPacket
Definition: wdfusb.h:1331
#define EHCI_MAX_HS_ISO_TRANSFER_SIZE
Definition: usbehci.h:26
MPSTATUS NTAPI EHCI_EndSendOnePacket(IN PVOID ehciExtension, IN PVOID PacketParameters, IN PVOID Data, IN PULONG pDataLength, IN PVOID BufferVA, IN PVOID BufferPA, IN ULONG BufferLength, IN USBD_STATUS *pUSBDStatus)
Definition: usbehci.c:3546
ULONG NTAPI USBPORT_GetHciMn(VOID)
Definition: usbport.c:2804
#define USBPORT_ENDPOINT_HALT
Definition: usbmport.h:21
#define EHCI_FRAME_LIST_MAX_ENTRIES
Definition: hardware.h:8
PHCI_DISABLE_INTERRUPTS DisableInterrupts
Definition: usbmport.h:577
VOID NTAPI EHCI_AddDummyQHs(IN PEHCI_EXTENSION EhciExtension)
Definition: usbehci.c:785
MPSTATUS NTAPI EHCI_RH_ClearFeaturePortOvercurrentChange(IN PVOID ehciExtension, IN USHORT Port)
Definition: roothub.c:649
ULONG TransferBytes
Definition: hardware.h:352
PUSBPORT_INVALIDATE_ENDPOINT UsbPortInvalidateEndpoint
Definition: usbmport.h:615
VOID NTAPI EHCI_DumpHwQH(IN PEHCI_HCD_QH QH)
Definition: debug.c:31
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:213
PHCI_RESUME_CONTROLLER ResumeController
Definition: usbmport.h:564
MPSTATUS NTAPI EHCI_StartSendOnePacket(IN PVOID ehciExtension, IN PVOID PacketParameters, IN PVOID Data, IN PULONG pDataLength, IN PVOID BufferVA, IN PVOID BufferPA, IN ULONG BufferLength, IN USBD_STATUS *pUSBDStatus)
Definition: usbehci.c:3531
_IRQL_requires_same_ _In_ PLSA_STRING _In_ SECURITY_LOGON_TYPE _In_ ULONG _In_ ULONG _In_opt_ PTOKEN_GROUPS _In_ PTOKEN_SOURCE _Out_ PVOID _Out_ PULONG _Inout_ PLUID _Out_ PHANDLE Token
#define USBD_TRANSFER_DIRECTION_IN
Definition: usb.h:160
MPSTATUS NTAPI EHCI_RH_ClearFeaturePortResetChange(IN PVOID ehciExtension, IN USHORT Port)
Definition: roothub.c:621
VOID NTAPI EHCI_PollController(IN PVOID ehciExtension)
Definition: usbehci.c:3409
PEHCI_HCD_QH NTAPI EHCI_InitializeQH(IN PEHCI_EXTENSION EhciExtension, IN PEHCI_ENDPOINT EhciEndpoint, IN PEHCI_HCD_QH QH, IN ULONG QhPA)
Definition: usbehci.c:149
ULONG PendingTDs
Definition: usbehci.h:156
VOID NTAPI EHCI_FlushInterrupts(IN PVOID ehciExtension)
Definition: usbehci.c:3581
MPSTATUS NTAPI EHCI_SubmitTransfer(IN PVOID ehciExtension, IN PVOID ehciEndpoint, IN PUSBPORT_TRANSFER_PARAMETERS TransferParameters, IN PVOID ehciTransfer, IN PUSBPORT_SCATTER_GATHER_LIST SgList)
Definition: usbehci.c:2385
PUSBPORT_COMPLETE_TRANSFER UsbPortCompleteTransfer
Definition: usbmport.h:616
ULONG PipeMultiplier
Definition: hardware.h:398
VOID NTAPI EHCI_PollEndpoint(IN PVOID ehciExtension, IN PVOID ehciEndpoint)
Definition: usbehci.c:3332
_In_ LARGE_INTEGER _In_ ULONG Period
Definition: kefuncs.h:1324
MPSTATUS NTAPI EHCI_OpenEndpoint(IN PVOID ehciExtension, IN PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties, IN PVOID ehciEndpoint)
Definition: usbehci.c:494
ULONG NTAPI EHCI_MapAsyncTransferToTd(IN PEHCI_EXTENSION EhciExtension, IN ULONG MaxPacketSize, IN ULONG TransferedLen, IN PULONG DataToggle, IN PEHCI_TRANSFER EhciTransfer, IN PEHCI_HCD_TD TD, IN PUSBPORT_SCATTER_GATHER_LIST SgList)
Definition: usbehci.c:1533
UCHAR NTAPI EHCI_GetOffsetEECP(IN PEHCI_EXTENSION EhciExtension, IN UCHAR CapabilityID)
Definition: usbehci.c:1055
#define EHCI_MAX_HS_ISO_HEADER_BUFFER_SIZE
Definition: usbehci.h:29
PHCI_RH_SET_FEATURE_PORT_RESET RH_SetFeaturePortReset
Definition: usbmport.h:589
VOID NTAPI EHCI_StopController(IN PVOID ehciExtension, IN BOOLEAN DisableInterrupts)
Definition: usbehci.c:1285
ULONG RemainTDs
Definition: usbehci.h:140
#define USBPORT_INVALIDATE_CONTROLLER_SURPRISE_REMOVE
Definition: usbmport.h:490
ULONG Buffer[5]
Definition: hardware.h:364
#define USBPORT_TRANSFER_TYPE_CONTROL
Definition: usbmport.h:8
MPSTATUS NTAPI EHCI_StartController(IN PVOID ehciExtension, IN PUSBPORT_RESOURCES Resources)
Definition: usbehci.c:1160
PHCI_ENABLE_INTERRUPTS EnableInterrupts
Definition: usbmport.h:576
Definition: shell.h:41
struct _EHCI_EXTENSION EHCI_EXTENSION
VOID NTAPI EHCI_InsertQhInPeriodicList(IN PEHCI_EXTENSION EhciExtension, IN PEHCI_ENDPOINT EhciEndpoint)
Definition: usbehci.c:2725
PHCI_RH_GET_ROOT_HUB_DATA RH_GetRootHubData
Definition: usbmport.h:585
#define InsertTailList(ListHead, Entry)
NTKERNELAPI ULONG NTAPI READ_REGISTER_ULONG(IN PULONG Register)
if(dx==0 &&dy==0)
Definition: linetemp.h:174
USB_DEVICE_SPEED DeviceSpeed
Definition: usbmport.h:73
ULONG EndpointStatus
Definition: usbehci.h:132
ULONG PIDCode
Definition: hardware.h:348
ULONG NTAPI EHCI_Get32BitFrameNumber(IN PVOID ehciExtension)
Definition: usbehci.c:3363
MPSTATUS NTAPI EHCI_RH_ChirpRootPort(IN PVOID ehciExtension, IN USHORT Port)
Definition: roothub.c:18
VOID NTAPI EHCI_EnableInterrupts(IN PVOID ehciExtension)
Definition: usbehci.c:3384
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
PHCI_PASS_THRU PassThru
Definition: usbmport.h:607
MPSTATUS NTAPI EHCI_RH_SetFeaturePortSuspend(IN PVOID ehciExtension, IN USHORT Port)
Definition: roothub.c:435
struct _EHCI_HW_REGISTERS * PEHCI_HW_REGISTERS
PUSBPORT_READ_WRITE_CONFIG_SPACE UsbPortReadWriteConfigSpace
Definition: usbmport.h:621
#define EHCI_QH_FLAG_UPDATING
Definition: usbehci.h:84
VOID NTAPI EHCI_EnablePeriodicList(IN PEHCI_EXTENSION EhciExtension)
Definition: usbehci.c:1654
ULONG HeadReclamationListFlag
Definition: hardware.h:382
#define EHCI_QH_FLAG_CLOSED
Definition: usbehci.h:81
#define EHCI_LINK_TYPE_QH
Definition: hardware.h:188
VOID NTAPI EHCI_LinkTransferToQueue(IN PEHCI_EXTENSION EhciExtension, IN PEHCI_ENDPOINT EhciEndpoint, IN PEHCI_HCD_TD NextTD)
Definition: usbehci.c:1840
MPSTATUS NTAPI EHCI_OpenBulkOrControlEndpoint(IN PEHCI_EXTENSION EhciExtension, IN PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties, IN PEHCI_ENDPOINT EhciEndpoint, IN BOOLEAN IsControl)
Definition: usbehci.c:223
uint32_t ULONG_PTR
Definition: typedefs.h:65
USBPORT_ENDPOINT_PROPERTIES EndpointProperties
Definition: usbehci.h:134
VOID NTAPI EHCI_SetEndpointState(IN PVOID ehciExtension, IN PVOID ehciEndpoint, IN ULONG EndpointState)
Definition: usbehci.c:2885
VOID NTAPI EHCI_PollActiveAsyncEndpoint(IN PEHCI_EXTENSION EhciExtension, IN PEHCI_ENDPOINT EhciEndpoint)
Definition: usbehci.c:3051
struct _EHCI_HCD_TD * NextHcdTD
Definition: usbehci.h:65
MPSTATUS NTAPI EHCI_RH_SetFeaturePortEnable(IN PVOID ehciExtension, IN USHORT Port)
Definition: roothub.c:425
#define ENDPOINT_INTERRUPT_4ms
Definition: usbmport.h:27
#define EHCI_TOKEN_STATUS_ACTIVE
Definition: hardware.h:331
VOID NTAPI EHCI_RH_EnableIrq(IN PVOID ehciExtension)
Definition: roothub.c:694
#define EHCI_TD_TOKEN_PID_SETUP
Definition: hardware.h:342
EHCI_STATIC_QH AsyncHead
Definition: usbehci.h:162
PEHCI_HW_REGISTERS OperationalRegs
Definition: usbehci.h:176
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
PHCI_SET_ENDPOINT_STATE SetEndpointState
Definition: usbmport.h:571
struct _EHCI_TRANSFER EHCI_TRANSFER
#define FALSE
Definition: types.h:117
PHCI_END_SEND_ONE_PACKET EndSendOnePacket
Definition: usbmport.h:606
#define USBD_STATUS_BABBLE_DETECTED
Definition: usb.h:188
VOID NTAPI EHCI_ProcessDoneAsyncTd(IN PEHCI_EXTENSION EhciExtension, IN PEHCI_HCD_TD TD)
Definition: usbehci.c:2971
VOID NTAPI DbgBreakPoint(VOID)
VOID NTAPI EHCI_QueryEndpointRequirements(IN PVOID ehciExtension, IN PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties, IN PUSBPORT_ENDPOINT_REQUIREMENTS EndpointRequirements)
Definition: usbehci.c:620
#define USB_MINIPORT_FLAGS_USB2
Definition: usbmport.h:534
USHORT HcSystemErrors
Definition: usbehci.h:179
struct _EHCI_ENDPOINT EHCI_ENDPOINT
ULONG SplitCompletionMask
Definition: hardware.h:395
#define USBPORT_RESOURCES_MEMORY
Definition: usbmport.h:42
PHCI_CLOSE_ENDPOINT CloseEndpoint
Definition: usbmport.h:560
PHCI_RH_CLEAR_FEATURE_PORT_ENABLE_CHANGE RH_ClearFeaturePortEnableChange
Definition: usbmport.h:596
#define EHCI_QH_FLAG_NUKED
Definition: usbehci.h:85
#define MP_STATUS_NO_RESOURCES
Definition: usbmport.h:136
EHCI_TD_TOKEN Token
Definition: hardware.h:412
VOID NTAPI EHCI_AbortAsyncTransfer(IN PEHCI_EXTENSION EhciExtension, IN PEHCI_ENDPOINT EhciEndpoint, IN PEHCI_TRANSFER EhciTransfer)
Definition: usbehci.c:2464
ULONG PeriodicFrameList[EHCI_FRAME_LIST_MAX_ENTRIES]
Definition: usbehci.h:161
PHCI_RH_CLEAR_FEATURE_PORT_SUSPEND_CHANGE RH_ClearFeaturePortSuspendChange
Definition: usbmport.h:599
VOID NTAPI EHCI_SetEndpointDataToggle(IN PVOID ehciExtension, IN PVOID ehciEndpoint, IN ULONG DataToggle)
Definition: usbehci.c:3440
unsigned char BOOLEAN
ULONG InterruptOnComplete
Definition: hardware.h:351
#define USBPORT_ENDPOINT_PAUSED
Definition: usbmport.h:14
MPSTATUS NTAPI EHCI_InitializeSchedule(IN PEHCI_EXTENSION EhciExtension, IN ULONG_PTR BaseVA, IN ULONG BasePA)
Definition: usbehci.c:884
#define EHCI_TD_TOKEN_PID_OUT
Definition: hardware.h:340
PHCI_START_CONTROLLER StartController
Definition: usbmport.h:561
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
EHCI_INTERRUPT_ENABLE InterruptMask
Definition: usbehci.h:183
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
PHCI_RH_GET_HUB_STATUS RH_GetHubStatus
Definition: usbmport.h:588
#define EHCI_FRINDEX_FRAME_MASK
Definition: hardware.h:168
VOID NTAPI EHCI_PollAsyncEndpoint(IN PEHCI_EXTENSION EhciExtension, IN PEHCI_ENDPOINT EhciEndpoint)
Definition: usbehci.c:3277
#define EHCI_INTERRUPT_MASK
Definition: hardware.h:120
ULONG FrameHighPart
Definition: usbehci.h:193
EHCI_LINK_POINTER HorizontalLink
Definition: hardware.h:406
_Must_inspect_result_ _In_ WDFDMATRANSACTION _In_ PFN_WDF_PROGRAM_DMA _In_ WDF_DMA_DIRECTION _In_ PMDL _In_ PVOID VirtualAddress
void * PVOID
Definition: retypes.h:9
#define EHCI_TOKEN_STATUS_MISSED_MICROFRAME
Definition: hardware.h:336
VOID NTAPI EHCI_InterruptNextSOF(IN PVOID ehciExtension)
Definition: usbehci.c:2919
PHCI_SUBMIT_ISO_TRANSFER SubmitIsoTransfer
Definition: usbmport.h:568
EHCI_QUEUE_HEAD HwQH
Definition: usbehci.h:89
PHCI_POLL_CONTROLLER PollController
Definition: usbmport.h:578
#define EHCI_HCD_TD_FLAG_DONE
Definition: usbehci.h:49
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
PHCI_RH_CLEAR_FEATURE_PORT_SUSPEND RH_ClearFeaturePortSuspend
Definition: usbmport.h:595
struct _EHCI_TRANSFER * EhciTransfer
Definition: usbehci.h:64
PHCI_INTERRUPT_SERVICE InterruptService
Definition: usbmport.h:565
#define ENDPOINT_INTERRUPT_32ms
Definition: usbmport.h:30
#define USBPORT_HCI_MN
Definition: usbmport.h:4
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
PHCI_OPEN_ENDPOINT OpenEndpoint
Definition: usbmport.h:557
struct _EHCI_HCD_TD * AltNextHcdTD
Definition: usbehci.h:66
struct _EHCI_HC_RESOURCES EHCI_HC_RESOURCES
ULONG TransferLen
Definition: usbehci.h:154
ULONG NTAPI EHCI_GetEndpointState(IN PVOID ehciExtension, IN PVOID ehciEndpoint)
Definition: usbehci.c:2623
USB_DEFAULT_PIPE_SETUP_PACKET SetupPacket
Definition: usbehci.h:67
Status
Definition: gdiplustypes.h:24
#define MP_STATUS_FAILURE
Definition: usbmport.h:135
#define ENDPOINT_INTERRUPT_8ms
Definition: usbmport.h:28
MPSTATUS NTAPI EHCI_RH_ClearFeaturePortPower(IN PVOID ehciExtension, IN USHORT Port)
Definition: roothub.c:488
PHCI_SET_ENDPOINT_STATUS SetEndpointStatus
Definition: usbmport.h:581
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
struct _EHCI_HCD_QH EHCI_HCD_QH
MPSTATUS NTAPI EHCI_RH_GetPortStatus(IN PVOID ehciExtension, IN USHORT Port, IN PUSB_PORT_STATUS_AND_CHANGE PortStatus)
Definition: roothub.c:187
PHCI_GET_ENDPOINT_STATE GetEndpointState
Definition: usbmport.h:570
#define USBD_STATUS_XACT_ERROR
Definition: usb.h:187
PHCI_RH_CLEAR_FEATURE_PORT_RESET_CHANGE RH_ClearFeaturePortResetChange
Definition: usbmport.h:598
PUSBPORT_INVALIDATE_ROOT_HUB UsbPortInvalidateRootHub
Definition: usbmport.h:614
MPSTATUS NTAPI EHCI_OpenInterruptEndpoint(IN PEHCI_EXTENSION EhciExtension, IN PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties, IN PEHCI_ENDPOINT EhciEndpoint)
Definition: usbehci.c:327
#define ASSERT(a)
Definition: mode.c:44
PHCI_ABORT_TRANSFER AbortTransfer
Definition: usbmport.h:569
#define USBPORT_RESOURCES_INTERRUPT
Definition: usbmport.h:41
#define USBD_STATUS_DATA_BUFFER_ERROR
Definition: usb.h:189
#define USBPORT_ENDPOINT_REMOVE
Definition: usbmport.h:16
struct _EHCI_STATIC_QH * StaticQH
Definition: usbehci.h:101
EHCI_USB_STATUS HcStatus
Definition: hardware.h:175
VOID NTAPI EHCI_SuspendController(IN PVOID ehciExtension)
Definition: usbehci.c:1293
VOID NTAPI EHCI_FlushAsyncCache(IN PEHCI_EXTENSION EhciExtension)
Definition: usbehci.c:1670
struct Command Command
MPSTATUS NTAPI EHCI_RH_ClearFeaturePortEnableChange(IN PVOID ehciExtension, IN USHORT Port)
Definition: roothub.c:566
MPSTATUS NTAPI EHCI_RH_ClearFeaturePortSuspendChange(IN PVOID ehciExtension, IN USHORT Port)
Definition: roothub.c:635
VOID NTAPI EHCI_InitializeInterruptSchedule(IN PEHCI_EXTENSION EhciExtension)
Definition: usbehci.c:841
struct _EHCI_HCD_QH * PEHCI_HCD_QH
#define EHCI_QH_FLAG_IN_SCHEDULE
Definition: usbehci.h:80
#define EHCI_HCD_TD_FLAG_ALLOCATED
Definition: usbehci.h:47
struct _EHCI_HC_CAPABILITY_REGISTERS * PEHCI_HC_CAPABILITY_REGISTERS
MPSTATUS NTAPI EHCI_RH_ClearFeaturePortEnable(IN PVOID ehciExtension, IN USHORT Port)
Definition: roothub.c:462
EHCI_HC_STRUCTURAL_PARAMS StructParameters
Definition: hardware.h:74
#define EHCI_TOKEN_STATUS_HALTED
Definition: hardware.h:332
#define PAGE_ALIGN(Va)
PHCI_RH_CHIRP_ROOT_PORT RH_ChirpRootPort
Definition: usbmport.h:630
#define TOTAL_USB20_BUS_BANDWIDTH
Definition: usbmport.h:542
PHCI_REBALANCE_ENDPOINT RebalanceEndpoint
Definition: usbmport.h:628
PHCI_RH_SET_FEATURE_PORT_SUSPEND RH_SetFeaturePortSuspend
Definition: usbmport.h:592
ULONG PortRoutingControl
Definition: usbehci.h:180
ULONG AlternateNextTD
Definition: hardware.h:362
static const UCHAR ClassicPeriod[8]
Definition: usbehci.c:18
ULONG MaximumPacketLength
Definition: hardware.h:383
MPSTATUS NTAPI EHCI_OpenIsoEndpoint(IN PEHCI_EXTENSION EhciExtension, IN PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties, IN PEHCI_ENDPOINT EhciEndpoint)
Definition: usbehci.c:484
UCHAR FrameLengthAdjustment
Definition: usbehci.h:177
VOID NTAPI EHCI_SetEndpointStatus(IN PVOID ehciExtension, IN PVOID ehciEndpoint, IN ULONG EndpointStatus)
Definition: usbehci.c:3488
MPSTATUS NTAPI EHCI_RH_GetHubStatus(IN PVOID ehciExtension, IN PUSB_HUB_STATUS_AND_CHANGE HubStatus)
Definition: roothub.c:269
#define USBD_STATUS_SUCCESS
Definition: usb.h:170
VOID NTAPI EHCI_InterruptDpc(IN PVOID ehciExtension, IN BOOLEAN EnableInterrupts)
Definition: usbehci.c:1495
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS PhysicalAddress
Definition: iotypes.h:1098
MPSTATUS NTAPI EHCI_SubmitIsoTransfer(IN PVOID ehciExtension, IN PVOID ehciEndpoint, IN PUSBPORT_TRANSFER_PARAMETERS TransferParameters, IN PVOID ehciTransfer, IN PVOID isoParameters)
Definition: usbehci.c:2443
PEHCI_HCD_TD NTAPI EHCI_AllocTd(IN PEHCI_EXTENSION EhciExtension, IN PEHCI_ENDPOINT EhciEndpoint)
Definition: usbehci.c:113
PUSBPORT_INVALIDATE_CONTROLLER UsbPortInvalidateController
Definition: usbmport.h:623
unsigned char UCHAR
Definition: xmlstorage.h:181
WDF_EXTERN_C_START typedef _In_ WDFDEVICE _In_ WDFCONTEXT _In_ WDF_DMA_DIRECTION _In_ PSCATTER_GATHER_LIST SgList
ULONG PeriodicListBase
Definition: hardware.h:179
VOID NTAPI EHCI_DisableInterrupts(IN PVOID ehciExtension)
Definition: usbehci.c:3397
VOID NTAPI EHCI_AbortIsoTransfer(IN PEHCI_EXTENSION EhciExtension, IN PEHCI_ENDPOINT EhciEndpoint, IN PEHCI_TRANSFER EhciTransfer)
Definition: usbehci.c:2455
MPSTATUS NTAPI EHCI_InitializeHardware(IN PEHCI_EXTENSION EhciExtension)
Definition: usbehci.c:985
ULONG AsynchronousEnable
Definition: hardware.h:85
ULONG BackupAsynclistaddr
Definition: usbehci.h:207
PHCI_CHECK_CONTROLLER CheckController
Definition: usbmport.h:573
#define USBPORT_TRANSFER_TYPE_INTERRUPT
Definition: usbmport.h:10
#define EHCI_HCD_TD_FLAG_ACTIVE
Definition: usbehci.h:50
ULONG Status
Definition: hardware.h:347
LONG USBD_STATUS
Definition: usb.h:165
Definition: sacdrv.h:278
#define MP_STATUS_ERROR
Definition: usbmport.h:138
#define EHCI_TD_TOKEN_PID_IN
Definition: hardware.h:341
NTSTATUS NTAPI USBPORT_RegisterUSBPortDriver(IN PDRIVER_OBJECT DriverObject, IN ULONG Version, IN PUSBPORT_REGISTRATION_PACKET RegPacket)
Definition: usbport.c:2811
#define MP_STATUS_HW_ERROR
Definition: usbmport.h:141
ULONG PendingTDs
Definition: usbehci.h:139
#define ENDPOINT_INTERRUPT_2ms
Definition: usbmport.h:26
PHCI_RH_DISABLE_IRQ RH_DisableIrq
Definition: usbmport.h:601
#define PAGE_SIZE
Definition: env_spec_w32.h:49
UCHAR PeriodIdx
Definition: usbehci.h:42
Definition: typedefs.h:119
_In_ ULONG ParameterLength
Definition: usbdlib.h:206
ULONG NTAPI EHCI_GetEndpointStatus(IN PVOID ehciExtension, IN PVOID ehciEndpoint)
Definition: usbehci.c:3464
VOID NTAPI EHCI_RebalanceEndpoint(IN PVOID ohciExtension, IN PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties, IN PVOID ohciEndpoint)
Definition: usbehci.c:3572
PEHCI_HCD_QH QH
Definition: usbehci.h:141
VOID NTAPI EHCI_GetRegistryParameters(IN PEHCI_EXTENSION EhciExtension)
Definition: usbehci.c:1153
ULONG FrameIndex
Definition: usbehci.h:192
#define EHCI_DUMMYQH_MAX_PACKET_LENGTH
Definition: usbehci.h:116
#define TERMINATE_POINTER
Definition: hardware.h:193
#define INTERRUPT_ENDPOINTs
Definition: usbmport.h:32
#define USBD_STATUS_STALL_PID
Definition: usb.h:175
EHCI_QH_EP_PARAMS EndpointParams
Definition: hardware.h:407
ULONG BackupCtrlDSSegment
Definition: usbehci.h:208
#define USBPORT_TRANSFER_TYPE_ISOCHRONOUS
Definition: usbmport.h:7
NTKERNELAPI UCHAR NTAPI READ_REGISTER_UCHAR(IN PUCHAR Register)
#define EHCI_FLAGS_IDLE_SUPPORT
Definition: usbehci.h:169
#define LINK_POINTER_MASK
Definition: hardware.h:195
USBD_STATUS NTAPI EHCI_GetErrorFromTD(IN PEHCI_HCD_TD TD)
Definition: usbehci.c:2931
#define EHCI_MAX_INTERRUPT_TRANSFER_SIZE
Definition: usbehci.h:23
VOID NTAPI EHCI_LockQH(IN PEHCI_EXTENSION EhciExtension, IN PEHCI_HCD_QH QH, IN ULONG TransferType)
Definition: usbehci.c:1753
PHCI_START_SEND_ONE_PACKET StartSendOnePacket
Definition: usbmport.h:605
PHCI_POLL_ENDPOINT PollEndpoint
Definition: usbmport.h:572
ULONG BackupUSBCmd
Definition: usbehci.h:209
#define USB20_MINIPORT_INTERFACE_VERSION
Definition: usbmport.h:637
PHCI_SET_ENDPOINT_DATA_TOGGLE SetEndpointDataToggle
Definition: usbmport.h:579
EHCI_INTERRUPT_ENABLE HcInterruptEnable
Definition: hardware.h:176
VOID NTAPI EHCI_PollIsoEndpoint(IN PEHCI_EXTENSION EhciExtension, IN PEHCI_ENDPOINT EhciEndpoint)
Definition: usbehci.c:3324
LIST_ENTRY DoneLink
Definition: usbehci.h:69
PHCI_TAKE_PORT_CONTROL TakePortControl
Definition: usbmport.h:631
BOOLEAN NTAPI EHCI_InterruptService(IN PVOID ehciExtension)
Definition: usbehci.c:1433
#define EHCI_MAX_FS_ISO_HEADER_BUFFER_SIZE
Definition: usbehci.h:28
#define ENDPOINT_INTERRUPT_16ms
Definition: usbmport.h:29
#define EHCI_MAX_HC_SYSTEM_ERRORS
Definition: usbehci.h:38
MPSTATUS NTAPI EHCI_ControlTransfer(IN PEHCI_EXTENSION EhciExtension, IN PEHCI_ENDPOINT EhciEndpoint, IN PUSBPORT_TRANSFER_PARAMETERS TransferParameters, IN PEHCI_TRANSFER EhciTransfer, IN PUSBPORT_SCATTER_GATHER_LIST SgList)
Definition: usbehci.c:1928
PHCI_STOP_CONTROLLER StopController
Definition: usbmport.h:562
BOOLEAN NTAPI EHCI_HardwarePresent(IN PEHCI_EXTENSION EhciExtension, IN BOOLEAN IsInvalidateController)
Definition: usbehci.c:1412
PHCI_GET_ENDPOINT_STATUS GetEndpointStatus
Definition: usbmport.h:580
PHCI_INTERRUPT_NEXT_SOF InterruptNextSOF
Definition: usbmport.h:575
PHCI_RH_CLEAR_FEATURE_PORT_ENABLE RH_ClearFeaturePortEnable
Definition: usbmport.h:593
C_ASSERT(RTL_NUMBER_OF(pTable)==INTERRUPT_ENDPOINTs+1)
unsigned short USHORT
Definition: pedump.c:61
struct _EHCI_HCD_TD * PEHCI_HCD_TD
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
PHCI_SUSPEND_CONTROLLER SuspendController
Definition: usbmport.h:563
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
MPSTATUS NTAPI EHCI_TakeControlHC(IN PEHCI_EXTENSION EhciExtension)
Definition: usbehci.c:1095
#define EHCI_MAX_BULK_TD_COUNT
Definition: usbehci.h:33
EHCI_TD_TOKEN Token
Definition: hardware.h:363
#define EHCI_QH_EP_LOW_SPEED
Definition: hardware.h:372
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
ULONG InterruptOnAsyncAdvance
Definition: hardware.h:129
PHCI_INTERRUPT_DPC InterruptDpc
Definition: usbmport.h:566
VOID NTAPI EHCI_Unload(IN PDRIVER_OBJECT DriverObject)
Definition: usbehci.c:3604
unsigned int * PULONG
Definition: retypes.h:1
#define USBPORT_ENDPOINT_CONTROL
Definition: usbmport.h:22
#define MP_STATUS_NOT_SUPPORTED
Definition: usbmport.h:140
#define NULL
Definition: types.h:112
VOID NTAPI EHCI_InsertQhInAsyncList(IN PEHCI_EXTENSION EhciExtension, IN PEHCI_HCD_QH QH)
Definition: usbehci.c:2790
EHCI_INTERRUPT_ENABLE InterruptStatus
Definition: usbehci.h:184
#define MP_STATUS_SUCCESS
Definition: usbmport.h:134
#define EHCI_FLAGS_CONTROLLER_SUSPEND
Definition: usbehci.h:168
#define EHCI_TOKEN_STATUS_TRANSACTION_ERROR
Definition: hardware.h:335
BOOLEAN IsStarted
Definition: usbehci.h:178
ULONG ErrorCounter
Definition: hardware.h:349
EHCI_HCD_QH IsoDummyQH[EHCI_FRAME_LIST_MAX_ENTRIES]
Definition: usbehci.h:165
PHCI_RH_CLEAR_FEATURE_PORT_CONNECT_CHANGE RH_ClearFeaturePortConnectChange
Definition: usbmport.h:597
VOID NTAPI EHCI_RH_GetRootHubData(IN PVOID ehciExtension, IN PVOID rootHubData)
Definition: roothub.c:132
#define DPRINT1
Definition: precomp.h:8
#define USB_MINIPORT_FLAGS_INTERRUPT
Definition: usbmport.h:531
struct _EHCI_HCD_QH * NextHead
Definition: usbehci.h:97
ULONG Period
Definition: usbehci.h:105
ULONG PhysicalAddress
Definition: usbehci.h:92
#define EHCI_FLADJ_PCI_CONFIG_OFFSET
Definition: hardware.h:21
#define USB_MINIPORT_FLAGS_MEMORY_IO
Definition: usbmport.h:533
struct _EHCI_STATIC_QH EHCI_STATIC_QH
#define EHCI_MAX_CONTROL_TD_COUNT
Definition: usbehci.h:31
#define EHCI_HCD_TD_FLAG_PROCESSED
Definition: usbehci.h:48
PHCI_QUERY_ENDPOINT_REQUIREMENTS QueryEndpointRequirements
Definition: usbmport.h:559
unsigned int ULONG
Definition: retypes.h:1
MPSTATUS NTAPI EHCI_RH_ClearFeaturePortConnectChange(IN PVOID ehciExtension, IN USHORT Port)
Definition: roothub.c:591
PHCI_RH_ENABLE_IRQ RH_EnableIrq
Definition: usbmport.h:602
PHCI_REOPEN_ENDPOINT ReopenEndpoint
Definition: usbmport.h:558
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ULONG_PTR
Definition: config.h:101
uint32_t * PULONG_PTR
Definition: typedefs.h:65
ULONG DataToggleControl
Definition: hardware.h:381
#define EHCI_TOKEN_STATUS_DATA_BUFFER_ERROR
Definition: hardware.h:333
ULONG SegmentSelector
Definition: hardware.h:178
static const EHCI_PERIOD pTable[]
Definition: usbehci.c:29
MPSTATUS NTAPI EHCI_RH_SetFeaturePortPower(IN PVOID ehciExtension, IN USHORT Port)
Definition: roothub.c:399
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
MPSTATUS NTAPI EHCI_RH_GetStatus(IN PVOID ehciExtension, IN PUSHORT Status)
Definition: roothub.c:177
MPSTATUS NTAPI EHCI_ResumeController(IN PVOID ehciExtension)
Definition: usbehci.c:1355
ULONG QhFlags
Definition: usbehci.h:91
MPSTATUS NTAPI EHCI_InterruptTransfer(IN PEHCI_EXTENSION EhciExtension, IN PEHCI_ENDPOINT EhciEndpoint, IN PUSBPORT_TRANSFER_PARAMETERS TransferParameters, IN PEHCI_TRANSFER EhciTransfer, IN PUSBPORT_SCATTER_GATHER_LIST SgList)
Definition: usbehci.c:2273
ULONG Ordinal
Definition: usbehci.h:106
EHCI_STATIC_QH sqh
Definition: usbehci.h:119
static const UCHAR LinkTable[]
Definition: usbehci.c:103
#define EHCI_MAX_QTD_BUFFER_PAGES
Definition: hardware.h:329
PUSBPORT_WAIT UsbPortWait
Definition: usbmport.h:622
#define DPRINT
Definition: sndvol32.h:71
ULONG LengthThisTD
Definition: usbehci.h:68
PHCI_GET_32BIT_FRAME_NUMBER Get32BitFrameNumber
Definition: usbmport.h:574
VOID NTAPI EHCI_RH_DisableIrq(IN PVOID ehciExtension)
Definition: roothub.c:674
#define USB_MINIPORT_FLAGS_WAKE_SUPPORT
Definition: usbmport.h:539
PUSBPORT_BUG_CHECK UsbPortBugCheck
Definition: usbmport.h:624
UCHAR ScheduleMask
Definition: usbehci.h:43
MPSTATUS NTAPI EHCI_RH_ClearFeaturePortSuspend(IN PVOID ehciExtension, IN USHORT Port)
Definition: roothub.c:538
struct _EHCI_ENDPOINT * EhciEndpoint
Definition: usbehci.h:63
MPSTATUS NTAPI EHCI_BulkTransfer(IN PEHCI_EXTENSION EhciExtension, IN PEHCI_ENDPOINT EhciEndpoint, IN PUSBPORT_TRANSFER_PARAMETERS TransferParameters, IN PEHCI_TRANSFER EhciTransfer, IN PUSBPORT_SCATTER_GATHER_LIST SgList)
Definition: usbehci.c:2114
VOID NTAPI EHCI_DisablePeriodicList(IN PEHCI_EXTENSION EhciExtension)
Definition: usbehci.c:684
EHCI_STATIC_QH PeriodicHead[64]
Definition: usbehci.h:163
#define EHCI_MAX_BULK_TRANSFER_SIZE
Definition: usbehci.h:24
PEHCI_ENDPOINT EhciEndpoint
Definition: usbehci.h:155
PHCI_FLUSH_INTERRUPTS FlushInterrupts
Definition: usbmport.h:629
ULONG TdFlags
Definition: usbehci.h:62
_In_ PUSBD_PIPE_INFORMATION _In_ USB_DEVICE_SPEED DeviceSpeed
Definition: hubbusif.h:294
ULONG AlternateNextTD
Definition: hardware.h:411
VOID NTAPI EHCI_ResetController(IN PVOID ehciExtension)
Definition: usbehci.c:3524
#define EHCI_TOKEN_STATUS_BABBLE_DETECTED
Definition: hardware.h:334
VOID NTAPI KeStallExecutionProcessor(IN ULONG MicroSeconds)
Definition: ntoskrnl.c:96
MPSTATUS NTAPI EHCI_PassThru(IN PVOID ehciExtension, IN PVOID passThruParameters, IN ULONG ParameterLength, IN PVOID pParameters)
Definition: usbehci.c:3561
PEHCI_HCD_QH NTAPI EHCI_GetDummyQhForFrame(IN PEHCI_EXTENSION EhciExtension, IN ULONG Idx)
Definition: usbehci.c:741
#define EHCI_QH_FLAG_STATIC
Definition: usbehci.h:82
VOID NTAPI EHCI_RemoveQhFromPeriodicList(IN PEHCI_EXTENSION EhciExtension, IN PEHCI_ENDPOINT EhciEndpoint)
Definition: usbehci.c:2632
ULONG AsULONG
Definition: hardware.h:355
VOID NTAPI EHCI_DisableAsyncList(IN PEHCI_EXTENSION EhciExtension)
Definition: usbehci.c:1638
USHORT NumberOfPorts
Definition: usbehci.h:181
#define EHCI_HCD_TD_FLAG_DUMMY
Definition: usbehci.h:51
VOID NTAPI EHCI_SetAsyncEndpointState(IN PEHCI_EXTENSION EhciExtension, IN PEHCI_ENDPOINT EhciEndpoint, IN ULONG EndpointState)
Definition: usbehci.c:2832
PHCI_RH_CLEAR_FEATURE_PORT_OVERCURRENT_CHANGE RH_ClearFeaturePortOvercurrentChange
Definition: usbmport.h:600
LONGLONG QuadPart
Definition: typedefs.h:114
VOID NTAPI EHCI_UnlockQH(IN PEHCI_EXTENSION EhciExtension, IN PEHCI_HCD_QH QH)
Definition: usbehci.c:1816
struct _EHCI_HC_RESOURCES * PEHCI_HC_RESOURCES
ULONG DataToggle
Definition: hardware.h:353
EHCI_QH_EP_CAPS EndpointCaps
Definition: hardware.h:408
#define EHCI_QH_EP_HIGH_SPEED
Definition: hardware.h:373
#define EHCI_MAX_INTERRUPT_TD_COUNT
Definition: usbehci.h:32