ReactOS  0.4.14-dev-114-gc8cbd56
hardware.cpp
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: drivers/usb/usbohci/hcd_controller.cpp
5  * PURPOSE: USB OHCI device driver.
6  * PROGRAMMERS:
7  * Michael Martin (michael.martin@reactos.org)
8  * Johannes Anderwald (johannes.anderwald@reactos.org)
9  */
10 
11 #include "usbohci.h"
12 
13 #define NDEBUG
14 #include <debug.h>
15 
17 
18 BOOLEAN
19 NTAPI
21  IN PKINTERRUPT Interrupt,
23 
24 VOID
25 NTAPI
27  IN PKDPC Dpc,
31 
32 VOID
33 NTAPI
35 
36 class CUSBHardwareDevice : public IOHCIHardwareDevice
37 {
38 public:
40 
42  {
44  return m_Ref;
45  }
47  {
49 
50  if (!m_Ref)
51  {
52  delete this;
53  return 0;
54  }
55  return m_Ref;
56  }
57  // com
60 
61 
62  // local
68 
69  // friend function
73  // constructor / destructor
74  CUSBHardwareDevice(IUnknown *OuterUnknown){}
75  virtual ~CUSBHardwareDevice(){}
76 
77 protected:
78  LONG m_Ref; // reference count
79  PDRIVER_OBJECT m_DriverObject; // driver object
81  PDEVICE_OBJECT m_FunctionalDeviceObject; // fdo (hcd controller)
82  PDEVICE_OBJECT m_NextDeviceObject; // lower device object
83  KSPIN_LOCK m_Lock; // hardware lock
84  PKINTERRUPT m_Interrupt; // interrupt object
85  KDPC m_IntDpcObject; // dpc object for deferred isr processing
86  PVOID VirtualBase; // virtual base for memory manager
87  PHYSICAL_ADDRESS PhysicalAddress; // physical base for memory manager
88  PULONG m_Base; // OHCI operational port base registers
89  PDMA_ADAPTER m_Adapter; // dma adapter object
90  ULONG m_MapRegisters; // map registers count
91  USHORT m_VendorID; // vendor id
92  USHORT m_DeviceID; // device id
93  POHCIQUEUE m_UsbQueue; // usb request queue
94  POHCIHCCA m_HCCA; // hcca virtual base
95  PHYSICAL_ADDRESS m_HCCAPhysicalAddress; // hcca physical address
96  POHCI_ENDPOINT_DESCRIPTOR m_ControlEndpointDescriptor; // dummy control endpoint descriptor
97  POHCI_ENDPOINT_DESCRIPTOR m_BulkEndpointDescriptor; // dummy control endpoint descriptor
99  POHCI_ENDPOINT_DESCRIPTOR m_InterruptEndpoints[OHCI_STATIC_ENDPOINT_COUNT]; // endpoints for interrupt / iso transfers
100  ULONG m_NumberOfPorts; // number of ports
101  PDMAMEMORYMANAGER m_MemoryManager; // memory manager
102  HD_INIT_CALLBACK* m_SCECallBack; // status change callback routine
103  PVOID m_SCEContext; // status change callback routine context
104  WORK_QUEUE_ITEM m_StatusChangeWorkItem; // work item for status change callback
105  volatile LONG m_StatusChangeWorkItemStatus; // work item active status
106  ULONG m_SyncFramePhysAddr; // periodic frame list physical address
107  ULONG m_IntervalValue; // periodic interval value
108 };
109 
110 //=================================================================================================
111 // COM
112 //
113 NTSTATUS
116  IN REFIID refiid,
117  OUT PVOID* Output)
118 {
119  if (IsEqualGUIDAligned(refiid, IID_IUnknown))
120  {
121  *Output = PVOID(PUNKNOWN(this));
122  PUNKNOWN(*Output)->AddRef();
123  return STATUS_SUCCESS;
124  }
125 
126  return STATUS_UNSUCCESSFUL;
127 }
128 
129 LPCSTR
131 CUSBHardwareDevice::GetUSBType()
132 {
133  return "USBOHCI";
134 }
135 
136 
137 NTSTATUS
144 {
145  BUS_INTERFACE_STANDARD BusInterface;
146  PCI_COMMON_CONFIG PciConfig;
149  PUSBQUEUE Queue;
150 
151  DPRINT("CUSBHardwareDevice::Initialize\n");
152 
153  //
154  // Create DMAMemoryManager for use with QueueHeads and Transfer Descriptors.
155  //
157  if (!NT_SUCCESS(Status))
158  {
159  DPRINT1("Failed to create DMAMemoryManager Object\n");
160  return Status;
161  }
162 
163  //
164  // Create the UsbQueue class that will handle the Asynchronous and Periodic Schedules
165  //
166  Status = CreateUSBQueue(&Queue);
167  if (!NT_SUCCESS(Status))
168  {
169  DPRINT1("Failed to create UsbQueue!\n");
170  return Status;
171  }
172 
173  // get ohci queue
174  m_UsbQueue = POHCIQUEUE(Queue);
175 
176  // sanity check
178 
179  //
180  // store device objects
181  //
186 
187  //
188  // initialize device lock
189  //
191 
192  //
193  // initialize status change work item
194  //
196 
197  m_VendorID = 0;
198  m_DeviceID = 0;
199 
200  Status = GetBusInterface(PhysicalDeviceObject, &BusInterface);
201  if (!NT_SUCCESS(Status))
202  {
203  DPRINT1("Failed to get BusInterface!\n");
204  return Status;
205  }
206 
207  BytesRead = (*BusInterface.GetBusData)(BusInterface.Context,
209  &PciConfig,
210  0,
212 
214  {
215  DPRINT1("Failed to get pci config information!\n");
216  return STATUS_SUCCESS;
217  }
218 
219  m_VendorID = PciConfig.VendorID;
220  m_DeviceID = PciConfig.DeviceID;
221 
222  return STATUS_SUCCESS;
223 }
224 
225 NTSTATUS
227 CUSBHardwareDevice::PnpStart(
228  PCM_RESOURCE_LIST RawResources,
229  PCM_RESOURCE_LIST TranslatedResources)
230 {
231  ULONG Index;
232  PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor;
234  PVOID ResourceBase;
236  ULONG Version;
237 
238  DPRINT("CUSBHardwareDevice::PnpStart\n");
239  for(Index = 0; Index < TranslatedResources->List[0].PartialResourceList.Count; Index++)
240  {
241  //
242  // get resource descriptor
243  //
244  ResourceDescriptor = &TranslatedResources->List[0].PartialResourceList.PartialDescriptors[Index];
245 
246  switch(ResourceDescriptor->Type)
247  {
249  {
252  this);
253 
256  (PVOID)this,
257  NULL,
258  ResourceDescriptor->u.Interrupt.Vector,
259  (KIRQL)ResourceDescriptor->u.Interrupt.Level,
260  (KIRQL)ResourceDescriptor->u.Interrupt.Level,
261  (KINTERRUPT_MODE)(ResourceDescriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED),
262  (ResourceDescriptor->ShareDisposition != CmResourceShareDeviceExclusive),
263  ResourceDescriptor->u.Interrupt.Affinity,
264  FALSE);
265 
266  if (!NT_SUCCESS(Status))
267  {
268  //
269  // failed to register interrupt
270  //
271  DPRINT1("IoConnect Interrupt failed with %x\n", Status);
272  return Status;
273  }
274  break;
275  }
277  {
278  //
279  // get resource base
280  //
281  ResourceBase = MmMapIoSpace(ResourceDescriptor->u.Memory.Start, ResourceDescriptor->u.Memory.Length, MmNonCached);
282  if (!ResourceBase)
283  {
284  //
285  // failed to map registers
286  //
287  DPRINT1("MmMapIoSpace failed\n");
289  }
290 
291  //
292  // Get controllers capabilities
293  //
295 
296  DPRINT("Version %x\n", Version & 0xFFFF);
297 
298  //
299  // Store Resource base
300  //
301  m_Base = (PULONG)ResourceBase;
302  break;
303  }
304  }
305  }
306 
307 
308  //
309  // zero device description
310  //
312 
313  //
314  // initialize device description
315  //
323 
324  //
325  // get dma adapter
326  //
328  if (!m_Adapter)
329  {
330  //
331  // failed to get dma adapter
332  //
333  DPRINT1("Failed to acquire dma adapter\n");
335  }
336 
337  //
338  // Create Common Buffer
339  //
340  VirtualBase = m_Adapter->DmaOperations->AllocateCommonBuffer(m_Adapter,
341  PAGE_SIZE * 4,
343  FALSE);
344  if (!VirtualBase)
345  {
346  DPRINT1("Failed to allocate a common buffer\n");
348  }
349 
350  //
351  // Initialize the DMAMemoryManager
352  //
353  Status = m_MemoryManager->Initialize(this, &m_Lock, PAGE_SIZE * 4, VirtualBase, PhysicalAddress, 32);
354  if (!NT_SUCCESS(Status))
355  {
356  DPRINT1("Failed to initialize the DMAMemoryManager\n");
357  return Status;
358  }
359 
360  //
361  // initializes the controller
362  //
364  if (!NT_SUCCESS(Status))
365  {
366  DPRINT1("Failed to Initialize the controller \n");
367  return Status;
368  }
369 
370  //
371  // Initialize the UsbQueue now that we have an AdapterObject.
372  //
373  Status = m_UsbQueue->Initialize(this, m_Adapter, m_MemoryManager, NULL);
374  if (!NT_SUCCESS(Status))
375  {
376  DPRINT1("Failed to Initialize the UsbQueue\n");
377  return Status;
378  }
379 
380  //
381  // Start the controller
382  //
383  DPRINT("Starting Controller\n");
385 
386  //
387  // done
388  //
389  return Status;
390 }
391 
392 NTSTATUS
394 CUSBHardwareDevice::PnpStop(void)
395 {
397  return STATUS_NOT_IMPLEMENTED;
398 }
399 
400 NTSTATUS
402 CUSBHardwareDevice::GetDeviceDetails(
403  OUT OPTIONAL PUSHORT VendorId,
404  OUT OPTIONAL PUSHORT DeviceId,
406  OUT OPTIONAL PULONG Speed)
407 {
408  if (VendorId)
409  {
410  //
411  // get vendor
412  //
413  *VendorId = m_VendorID;
414  }
415 
416  if (DeviceId)
417  {
418  //
419  // get device id
420  //
421  *DeviceId = m_DeviceID;
422  }
423 
424  if (NumberOfPorts)
425  {
426  //
427  // get number of ports
428  //
430  }
431 
432  if (Speed)
433  {
434  //
435  // speed is 0x100
436  //
437  *Speed = 0x100;
438  }
439 
440  return STATUS_SUCCESS;
441 }
442 
443 NTSTATUS
445 CUSBHardwareDevice::GetDMA(
446  OUT struct IDMAMemoryManager **OutDMAMemoryManager)
447 {
448  if (!m_MemoryManager)
449  return STATUS_UNSUCCESSFUL;
450  *OutDMAMemoryManager = m_MemoryManager;
451  return STATUS_SUCCESS;
452 }
453 
454 NTSTATUS
456 CUSBHardwareDevice::GetUSBQueue(
457  OUT struct IUSBQueue **OutUsbQueue)
458 {
459  if (!m_UsbQueue)
460  return STATUS_UNSUCCESSFUL;
461  *OutUsbQueue = m_UsbQueue;
462  return STATUS_SUCCESS;
463 }
464 
465 
466 NTSTATUS
468 {
469  ULONG Control, Descriptor, FrameInterval, Periodic, Port, Reset, Index;
470  ULONG NewControl, WaitInMs;
472  BOOLEAN Again = FALSE;
473 
474  //
475  // check context
476  //
478 
479  //Save this
480  NewControl = Control & OHCI_REMOTE_WAKEUP_CONNECTED;
481 
483  {
484  //
485  // change ownership
486  //
488  for(Index = 0; Index < 100; Index++)
489  {
490  //
491  // wait a bit
492  //
494 
495  //
496  // check control
497  //
500  {
501  //
502  // acquired ownership
503  //
504  break;
505  }
506  }
507 
508  //
509  // if the ownership is still not changed, perform reset
510  //
512  {
513  DPRINT1("SMM not responding\n");
514  }
515  else
516  {
517  DPRINT1("SMM has given up ownership\n");
518  }
519  }
520 
521  //
522  // read contents of control register
523  //
524 
526  DPRINT("Controller State %x\n", Control);
527 
528  switch (Control)
529  {
531  NewControl |= OHCI_HC_FUNCTIONAL_STATE_RESET;
532  WaitInMs = 50;
533  break;
534 
537  NewControl |= OHCI_HC_FUNCTIONAL_STATE_RESUME;
538  WaitInMs = 10;
539  break;
540 
541  default:
542  WaitInMs = 0;
543  break;
544  }
545 
546 retry:
547  if (WaitInMs != 0)
548  {
549  // Do the state transition
551 
552  if (!Again)
553  {
554  //
555  // delay is 100 ms
556  //
557  Timeout.QuadPart = WaitInMs;
558  DPRINT("Waiting %lu milliseconds for controller to transition state\n", Timeout.LowPart);
559 
560  //
561  // convert to 100 ns units (absolute)
562  //
563  Timeout.QuadPart *= -10000;
564 
565  //
566  // perform the wait
567  //
569  }
570  }
571 
572  //
573  // now reset controller
574  //
576 
577  //
578  // reset time is 10ms
579  //
580  for(Index = 0; Index < 100; Index++)
581  {
582  //
583  // wait a bit
584  //
586 
587  //
588  // read command status
589  //
591 
592  //
593  // was reset bit cleared
594  //
595  if ((Reset & OHCI_HOST_CONTROLLER_RESET) == 0)
596  {
597  //
598  // controller completed reset
599  //
600  break;
601  }
602  }
603 
604  if ((Reset & OHCI_HOST_CONTROLLER_RESET))
605  {
606  //
607  // failed to reset controller
608  //
609  return STATUS_UNSUCCESSFUL;
610  }
611 
612  //
613  // get frame interval
614  //
616  m_IntervalValue = OHCI_GET_INTERVAL_VALUE(FrameInterval);
617 
618  FrameInterval = ((FrameInterval & OHCI_FRAME_INTERVAL_TOGGLE) ^ OHCI_FRAME_INTERVAL_TOGGLE);
619 
620  DPRINT("FrameInterval %x IntervalValue %x\n", FrameInterval, m_IntervalValue);
621  FrameInterval |= OHCI_FSMPS(m_IntervalValue) | m_IntervalValue;
622  DPRINT("Computed FrameInterval %x\n", FrameInterval);
623 
624  //
625  // write frame interval
626  //
628 
630  DPRINT("Read FrameInterval %x\n", FrameInterval);
631 
632  //
633  // 90 % periodic
634  //
635  Periodic = OHCI_PERIODIC(m_IntervalValue);
637  DPRINT("Computed Periodic Start %x\n", Periodic);
638 
640  DPRINT("Read Periodic Start %x\n", Periodic);
641 
642  // Linux does this hack for some bad controllers
643  if (!(FrameInterval & 0x3FFF0000) ||
644  !(Periodic))
645  {
646  if (!Again)
647  {
648  DPRINT1("Trying reset again on faulty controller\n");
649  Again = TRUE;
650  goto retry;
651  }
652  else
653  {
654  DPRINT1("Second reset didn't solve the problem, failing\n");
655  return STATUS_UNSUCCESSFUL;
656  }
657  }
658 
659  //
660  // lets write physical address of dummy control endpoint descriptor
661  //
663 
664  //
665  // lets write physical address of dummy bulk endpoint descriptor
666  //
668 
669  //
670  // read descriptor A
671  //
673 
674  //
675  // get port count (in a loop due to AMD errata)
676  //
677  do
678  {
681  } while (m_NumberOfPorts == 0);
682 
683  DPRINT("NumberOfPorts %lu\n", m_NumberOfPorts);
685 
686  //
687  // no over current protection
688  //
690 
691  //
692  // power switching on
693  //
695 
696  //
697  // control each port power independently
698  //
700 
701  //
702  // write the configuration back
703  //
704  DPRINT("Descriptor A: %x\n", Descriptor);
706 
707  //
708  // read descriptor B
709  //
711 
712  //
713  // set power power control for each port to use PPS
714  //
715  for (Port = 1; Port <= m_NumberOfPorts; Port++)
716  {
717  Descriptor |= (1 << (16 + Port));
718  }
719 
720  //
721  // write the configuration back
722  //
723  DPRINT("Descriptor B: %x\n", Descriptor);
725 
726  //
727  // HCCA alignment check
728  //
733  DPRINT("HCCA: %x Alignment mask: %x\n", m_HCCAPhysicalAddress.LowPart, Control);
734 
735  //
736  // write address of HCCA
737  //
739 
740  //
741  // now enable the interrupts
742  //
744 
745  //
746  // enable all queues
747  //
749 
750  //
751  // start the controller
752  //
754  (NewControl & OHCI_REMOTE_WAKEUP_CONNECTED) |
757 
758  //
759  // wait a bit
760  //
762 
763  //
764  // is the controller started
765  //
767 
768  //
769  // assert that the controller has been started
770  //
773  DPRINT("Control %x\n", Control);
774 
775  //
776  // done
777  //
778  DPRINT("OHCI controller is operational\n");
779  return STATUS_SUCCESS;
780 }
781 
782 NTSTATUS
784  OUT POHCI_ENDPOINT_DESCRIPTOR *OutDescriptor)
785 {
787  PHYSICAL_ADDRESS DescriptorAddress;
789 
790  //
791  // allocate descriptor
792  //
793  Status = m_MemoryManager->Allocate(sizeof(OHCI_ENDPOINT_DESCRIPTOR), (PVOID*)&Descriptor, &DescriptorAddress);
794  if (!NT_SUCCESS(Status))
795  {
796  //
797  // failed to allocate descriptor
798  //
799  return Status;
800  }
801 
802  //
803  // initialize descriptor
804  //
806  Descriptor->HeadPhysicalDescriptor = 0;
807  Descriptor->NextPhysicalEndpoint = 0;
808  Descriptor->TailPhysicalDescriptor = 0;
809  Descriptor->PhysicalAddress.QuadPart = DescriptorAddress.QuadPart;
810 
811  //
812  // store result
813  //
814  *OutDescriptor = Descriptor;
815 
816  //
817  // done
818  //
819  return STATUS_SUCCESS;
820 }
821 
822 VOID
824 CUSBHardwareDevice::GetBulkHeadEndpointDescriptor(
825  struct _OHCI_ENDPOINT_DESCRIPTOR ** OutDescriptor)
826 {
827  *OutDescriptor = m_BulkEndpointDescriptor;
828 }
829 
830 VOID
832 CUSBHardwareDevice::GetInterruptEndpointDescriptors(
833  struct _OHCI_ENDPOINT_DESCRIPTOR *** OutDescriptor)
834 {
835  *OutDescriptor = m_InterruptEndpoints;
836 }
837 
838 VOID
840 CUSBHardwareDevice::GetIsochronousHeadEndpointDescriptor(
841  struct _OHCI_ENDPOINT_DESCRIPTOR ** OutDescriptor)
842 {
843  *OutDescriptor = m_IsoEndpointDescriptor;
844 }
845 
846 VOID
848 CUSBHardwareDevice::HeadEndpointDescriptorModified(
849  ULONG Type)
850 {
852  {
853  //
854  // notify controller
855  //
857  }
858  else if (Type == USB_ENDPOINT_TYPE_BULK)
859  {
860  //
861  // notify controller
862  //
864  }
865 }
866 
867 VOID
869 CUSBHardwareDevice::GetControlHeadEndpointDescriptor(
870  struct _OHCI_ENDPOINT_DESCRIPTOR ** OutDescriptor)
871 {
872  *OutDescriptor = m_ControlEndpointDescriptor;
873 }
874 
875 NTSTATUS
877 {
879  ULONG Index, Interval, IntervalIndex, InsertIndex;
881 
882  //
883  // first allocate the hcca area
884  //
886  if (!NT_SUCCESS(Status))
887  {
888  //
889  // no memory
890  //
891  return Status;
892  }
893 
894  //
895  // now allocate an endpoint for control transfers
896  // this endpoint will never be removed
897  //
899  if (!NT_SUCCESS(Status))
900  {
901  //
902  // no memory
903  //
904  return Status;
905  }
906 
907  //
908  // now allocate an endpoint for bulk transfers
909  // this endpoint will never be removed
910  //
912  if (!NT_SUCCESS(Status))
913  {
914  //
915  // no memory
916  //
917  return Status;
918  }
919 
920  //
921  // now allocate an endpoint for iso transfers
922  // this endpoint will never be removed
923  //
925  if (!NT_SUCCESS(Status))
926  {
927  //
928  // no memory
929  //
930  return Status;
931  }
932 
933  //
934  // now allocate endpoint descriptors for iso / interrupt transfers interval is 1,2,4,8,16,32
935  //
937  {
938  //
939  // allocate endpoint descriptor
940  //
942  if (!NT_SUCCESS(Status))
943  {
944  //
945  // no memory
946  //
947  return Status;
948  }
949 
950  //
951  // save in array
952  //
954  }
955 
956 
957  //
958  // now link the descriptors, taken from Haiku
959  //
961  IntervalIndex = OHCI_STATIC_ENDPOINT_COUNT - 1;
962  while (Interval > 1)
963  {
964  InsertIndex = Interval / 2;
965  while (InsertIndex < OHCI_BIGGEST_INTERVAL)
966  {
967  //
968  // assign endpoint address
969  //
970  m_HCCA->InterruptTable[InsertIndex] = m_InterruptEndpoints[IntervalIndex]->PhysicalAddress.LowPart;
971  InsertIndex += Interval;
972  }
973 
974  IntervalIndex--;
975  Interval /= 2;
976  }
977 
978  //
979  // link all endpoint descriptors to first descriptor in array
980  //
983  {
984  //
985  // link descriptor
986  //
988  }
989 
990  //
991  // Now link the first endpoint to the isochronous endpoint
992  //
994 
995  //
996  // set iso endpoint type
997  //
999 
1000  //
1001  // done
1002  //
1003  return STATUS_SUCCESS;
1004 }
1005 
1006 NTSTATUS
1008 {
1009  ASSERT(FALSE);
1010 
1011  return STATUS_UNSUCCESSFUL;
1012 }
1013 
1014 NTSTATUS
1016 CUSBHardwareDevice::ResetPort(
1017  IN ULONG PortIndex)
1018 {
1019  ASSERT(FALSE);
1020 
1021  return STATUS_SUCCESS;
1022 }
1023 
1024 NTSTATUS
1026 CUSBHardwareDevice::GetPortStatus(
1027  ULONG PortId,
1029  OUT USHORT *PortChange)
1030 {
1031  ULONG Value;
1032 
1033  if (PortId > m_NumberOfPorts)
1034  return STATUS_UNSUCCESSFUL;
1035 
1036  // init result variables
1037  *PortStatus = 0;
1038  *PortChange = 0;
1039 
1040  //
1041  // read port status
1042  //
1044  DPRINT("GetPortStatus PortId %x Value %x\n", PortId, Value);
1045 
1046  // connected
1048  {
1050 
1051  // low speed device
1054  }
1055 
1056  // did a device connect?
1058  *PortChange |= USB_PORT_STATUS_CONNECT;
1059 
1060  // port enabled
1063 
1064  // port disconnect or hardware error
1066  *PortChange |= USB_PORT_STATUS_CONNECT;
1067 
1068  // port suspend
1071 
1072  // port suspend
1074  *PortChange |= USB_PORT_STATUS_ENABLE;
1075 
1076  // port reset started
1079 
1080  // port reset ended
1082  *PortChange |= USB_PORT_STATUS_RESET;
1083 
1084  return STATUS_SUCCESS;
1085 }
1086 
1087 NTSTATUS
1089 CUSBHardwareDevice::ClearPortStatus(
1090  ULONG PortId,
1091  ULONG Status)
1092 {
1093  ULONG Value;
1094 
1095  DPRINT("CUSBHardwareDevice::ClearPortStatus PortId %x Feature %x\n", PortId, Status);
1096 
1097  if (PortId > m_NumberOfPorts)
1098  return STATUS_UNSUCCESSFUL;
1099 
1101 
1102  if (Status == C_PORT_RESET)
1103  {
1104  //
1105  // sanity checks
1106  //
1108 
1109  //
1110  // clear reset bit complete
1111  //
1113 
1114  //
1115  // sanity check
1116  //
1118  }
1119 
1121  {
1122  //
1123  // clear change bits
1124  //
1126 
1127  //
1128  // wait for port to stabilize
1129  //
1131  {
1133 
1134  //
1135  // delay is 100 ms
1136  //
1137  Timeout.QuadPart = 100;
1138  DPRINT1("Waiting %lu milliseconds for port to stabilize after connection\n", Timeout.LowPart);
1139 
1140  //
1141  // convert to 100 ns units (absolute)
1142  //
1143  Timeout.QuadPart *= -10000;
1144 
1145  //
1146  // perform the wait
1147  //
1149  }
1150  }
1151 
1152  //
1153  // re-enable root hub change
1154  //
1155  DPRINT("Enabling status change\n");
1157 
1158  return STATUS_SUCCESS;
1159 }
1160 
1161 
1162 NTSTATUS
1165  ULONG PortId,
1166  ULONG Feature)
1167 {
1168  ULONG Value;
1169 
1170  DPRINT("CUSBHardwareDevice::SetPortFeature PortId %x Feature %x\n", PortId, Feature);
1171 
1172  //
1173  // read port status
1174  //
1176 
1177 
1178  if (Feature == PORT_ENABLE)
1179  {
1180  //
1181  // enable port
1182  //
1184  return STATUS_SUCCESS;
1185  }
1186  else if (Feature == PORT_POWER)
1187  {
1189 
1190  //
1191  // enable power
1192  //
1194 
1195  //
1196  // read descriptor A for the delay data
1197  //
1199 
1200  //
1201  // compute the delay
1202  //
1204 
1205  //
1206  // delay is multiplied by 2 ms
1207  //
1208  Timeout.QuadPart *= 2;
1209  DPRINT("Waiting %lu milliseconds for port power up\n", Timeout.LowPart);
1210 
1211  //
1212  // convert to 100 ns units (absolute)
1213  //
1214  Timeout.QuadPart *= -10000;
1215 
1216  //
1217  // perform the wait
1218  //
1220 
1221  return STATUS_SUCCESS;
1222  }
1223  else if (Feature == PORT_SUSPEND)
1224  {
1225  //
1226  // enable port
1227  //
1229  return STATUS_SUCCESS;
1230  }
1231  else if (Feature == PORT_RESET)
1232  {
1233  //
1234  // assert
1235  //
1237 
1238  //
1239  // reset port
1240  //
1242 
1243  //
1244  // an interrupt signals the reset completion
1245  //
1246  return STATUS_SUCCESS;
1247  }
1248  return STATUS_SUCCESS;
1249 }
1250 
1251 
1252 
1253 VOID
1255 CUSBHardwareDevice::SetStatusChangeEndpointCallBack(
1256  PVOID CallBack,
1257  PVOID Context)
1258 {
1259  m_SCECallBack = (HD_INIT_CALLBACK*)CallBack;
1261 }
1262 
1263 VOID
1265 CUSBHardwareDevice::GetCurrentFrameNumber(
1266  PULONG FrameNumber)
1267 {
1268  ULONG Control;
1269  ULONG Number;
1270 
1271 
1273  DPRINT("FrameNumberInterval %x Frame %x\n", Number, m_HCCA->CurrentFrameNumber);
1274 
1275  //
1276  // remove reserved bits
1277  //
1278  Number &= 0xFFFF;
1279 
1280  //
1281  // store frame number
1282  //
1283  *FrameNumber = Number;
1284 
1285  //
1286  // is the controller started
1287  //
1290 
1291 
1292 }
1293 
1294 
1295 BOOLEAN
1296 NTAPI
1298  IN PKINTERRUPT Interrupt,
1300 {
1302  ULONG DoneHead, Status, Acknowledge = 0;
1303 
1304  //
1305  // get context
1306  //
1308 
1309  DPRINT("InterruptServiceRoutine\n");
1310 
1311  //
1312  // get done head
1313  //
1314  DoneHead = This->m_HCCA->DoneHead;
1315 
1316  //
1317  // check if zero
1318  //
1319  if (DoneHead == 0)
1320  {
1321  //
1322  // the interrupt was not caused by DoneHead update
1323  // check if something important happened
1324  //
1325  DPRINT("InterruptStatus %x InterruptEnable %x\n", READ_REGISTER_ULONG((PULONG)((PUCHAR)This->m_Base + OHCI_INTERRUPT_STATUS_OFFSET)),
1328  if (Status == 0)
1329  {
1330  //
1331  // nothing happened, appears to be shared interrupt
1332  //
1333  return FALSE;
1334  }
1335  }
1336  else
1337  {
1338  //
1339  // DoneHead update happened, check if there are other events too
1340  //
1342 
1343  //
1344  // since ed descriptors are 16 byte aligned, the controller sets the lower bits if there were other interrupt requests
1345  //
1346  if (DoneHead & OHCI_DONE_INTERRUPTS)
1347  {
1348  //
1349  // get other events
1350  //
1352  }
1353  }
1354 
1355  //
1356  // sanity check
1357  //
1358  ASSERT(Status != 0);
1359 
1361  {
1362  //
1363  // head completed
1364  //
1365  Acknowledge |= OHCI_WRITEBACK_DONE_HEAD;
1366  This->m_HCCA->DoneHead = 0;
1367  }
1368 
1370  {
1371  //
1372  // resume
1373  //
1374  DPRINT1("InterruptServiceRoutine> Resume\n");
1375  Acknowledge |= OHCI_RESUME_DETECTED;
1376  }
1377 
1378 
1380  {
1381  DPRINT1("InterruptServiceRoutine> Controller error\n");
1382 
1383  //
1384  // halt controller
1385  //
1386  ASSERT(FALSE);
1388  }
1389 
1391  {
1392  //
1393  // disable interrupt as it will fire untill the port has been reset
1394  //
1395  DPRINT1("Disabling status change interrupt\n");
1397  Acknowledge |= OHCI_ROOT_HUB_STATUS_CHANGE;
1398  }
1399 
1400  //
1401  // is there something to acknowledge
1402  //
1403  if (Acknowledge)
1404  {
1405  //
1406  // ack change
1407  //
1409  }
1410 
1411  //
1412  // defer processing
1413  //
1414  DPRINT("Status %x Acknowledge %x FrameNumber %x\n", Status, Acknowledge, This->m_HCCA->CurrentFrameNumber);
1415  KeInsertQueueDpc(&This->m_IntDpcObject, UlongToPtr(Status), UlongToPtr(DoneHead & ~1));
1416 
1417  //
1418  // interrupt handled
1419  //
1420  return TRUE;
1421 }
1422 
1423 VOID
1424 NTAPI
1426  IN PKDPC Dpc,
1430 {
1432  ULONG CStatus, Index, PortStatus;
1433  ULONG DoneHead, QueueSCEWorkItem;
1434 
1435  //
1436  // get parameters
1437  //
1439  CStatus = PtrToUlong(SystemArgument1);
1440  DoneHead = PtrToUlong(SystemArgument2);
1441 
1442  DPRINT("OhciDeferredRoutine Status %x DoneHead %x\n", CStatus, DoneHead);
1443 
1444  if (CStatus & OHCI_WRITEBACK_DONE_HEAD)
1445  {
1446  //
1447  // notify queue of event
1448  //
1449  This->m_UsbQueue->TransferDescriptorCompletionCallback(DoneHead);
1450  }
1451  if (CStatus & OHCI_ROOT_HUB_STATUS_CHANGE)
1452  {
1453  //
1454  // device connected, lets check which port
1455  //
1456  QueueSCEWorkItem = FALSE;
1457  for(Index = 0; Index < This->m_NumberOfPorts; Index++)
1458  {
1459  //
1460  // read port status
1461  //
1463 
1464  //
1465  // check if there is a status change
1466  //
1468  {
1469  //
1470  // did a device connect
1471  //
1473  {
1474  //
1475  // device connected
1476  //
1477  DPRINT1("New device arrival at Port %lu LowSpeed %x\n", Index, (PortStatus & OHCI_RH_PORTSTATUS_LSDA));
1478 
1479  //
1480  // enable port
1481  //
1483  }
1484  else
1485  {
1486  //
1487  // device disconnected
1488  //
1489  DPRINT1("Device disconnected at Port %x\n", Index);
1490  }
1491 
1492  //
1493  // work to do
1494  //
1495  QueueSCEWorkItem = TRUE;
1496  }
1498  {
1499  //
1500  // device disconnected or some error condition
1501  //
1503 
1504  //
1505  // work to do
1506  //
1507  QueueSCEWorkItem = TRUE;
1508  }
1510  {
1511  //
1512  // This is a port reset complete interrupt
1513  //
1514  DPRINT1("Port %lu completed reset\n", Index);
1515 
1516  //
1517  // Queue a work item
1518  //
1519  QueueSCEWorkItem = TRUE;
1520  }
1521  }
1522 
1523  //
1524  // is there a status change callback and a device connected / disconnected
1525  //
1526  if (QueueSCEWorkItem && This->m_SCECallBack != NULL)
1527  {
1528  if (InterlockedCompareExchange(&This->m_StatusChangeWorkItemStatus, 1, 0) == 0)
1529  {
1530  //
1531  // queue work item for processing
1532  //
1533  ExQueueWorkItem(&This->m_StatusChangeWorkItem, DelayedWorkQueue);
1534  }
1535  }
1536  }
1537 }
1538 
1539 VOID
1540 NTAPI
1542  PVOID Context)
1543 {
1544  //
1545  // cast to hardware object
1546  //
1548 
1549  //
1550  // is there a callback
1551  //
1552  if (This->m_SCECallBack)
1553  {
1554  //
1555  // issue callback
1556  //
1557  This->m_SCECallBack(This->m_SCEContext);
1558  }
1559 
1560  //
1561  // reset active status
1562  //
1563  InterlockedDecrement(&This->m_StatusChangeWorkItemStatus);
1564 }
1565 
1566 NTSTATUS
1567 NTAPI
1569  PUSBHARDWAREDEVICE *OutHardware)
1570 {
1572 
1574 
1575  if (!This)
1577 
1578  This->AddRef();
1579 
1580  // return result
1581  *OutHardware = (PUSBHARDWAREDEVICE)This;
1582 
1583  return STATUS_SUCCESS;
1584 }
#define USB_PORT_STATUS_LOW_SPEED
Definition: usb200.h:157
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
#define OHCI_STATIC_ENDPOINT_COUNT
Definition: hardware.h:193
CPPORT Port[4]
Definition: headless.c:34
#define IN
Definition: typedefs.h:38
#define PORT_RESET
Definition: usbhub.h:19
NTKERNELAPI VOID NTAPI WRITE_REGISTER_ULONG(IN PULONG Register, IN ULONG Value)
#define REFIID
Definition: guiddef.h:118
#define TRUE
Definition: types.h:120
IN PVOID IN PVOID IN USHORT Version
Definition: pci.h:359
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:717
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define C_PORT_CONNECTION
Definition: usbhub.h:22
IN PVOID CallBackContext
Definition: usbmport.h:466
#define USB_PORT_STATUS_ENABLE
Definition: usb200.h:152
#define IMP_IUSBOHCIHARDWAREDEVICE
Definition: interfaces.h:35
Type
Definition: Type.h:6
IUSBHardwareDevice * PUSBHARDWAREDEVICE
#define OHCI_RH_POWER_SWITCHING_MODE
Definition: hardware.h:84
_In_ BOOLEAN Release
Definition: classpnp.h:929
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
PDMA_ADAPTER NTAPI IoGetDmaAdapter(IN PDEVICE_OBJECT PhysicalDeviceObject, IN PDEVICE_DESCRIPTION DeviceDescription, IN OUT PULONG NumberOfMapRegisters)
Definition: pnpdma.c:23
#define OHCI_RH_GET_POWER_ON_TO_POWER_GOOD_TIME(s)
Definition: hardware.h:89
WORK_QUEUE_ITEM m_StatusChangeWorkItem
Definition: hardware.cpp:99
CM_FULL_RESOURCE_DESCRIPTOR List[1]
Definition: hwresource.cpp:165
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@375::@380 Memory
POHCI_ENDPOINT_DESCRIPTOR m_IsoEndpointDescriptor
Definition: hardware.cpp:98
IUnknown * PUNKNOWN
Definition: com_apitest.h:45
#define OHCI_RH_PORTSTATUS_LSDA
Definition: hardware.h:137
unsigned char * PUCHAR
Definition: retypes.h:3
BOOLEAN NTAPI KeInsertQueueDpc(IN PKDPC Dpc, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: dpc.c:724
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI CreateUSBHardware(PUSBHARDWAREDEVICE *OutHardware)
Definition: hardware.cpp:1474
VOID NTAPI OhciDeferredRoutine(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: hardware.cpp:1425
#define OHCI_RH_DESCRIPTOR_B_OFFSET
Definition: hardware.h:114
static NTSTATUS GetBusInterface(IN PFDO_DEVICE_EXTENSION DeviceExtension)
Definition: fdo.c:18
#define C_PORT_RESET
Definition: usbhub.h:26
#define InterlockedCompareExchange
Definition: interlocked.h:104
PEHCIQUEUE m_UsbQueue
Definition: hardware.cpp:94
#define OHCI_RH_PORTSTATUS_PSSC
Definition: hardware.h:140
KSPIN_LOCK m_Lock
Definition: hardware.cpp:82
VOID NTAPI StatusChangeWorkItemRoutine(PVOID Context)
Definition: hardware.cpp:1447
#define OHCI_RH_GET_PORT_COUNT(s)
Definition: hardware.h:83
#define USB_ENDPOINT_TYPE_CONTROL
Definition: usb100.h:62
PVOID NTAPI MmMapIoSpace(IN PHYSICAL_ADDRESS PhysicalAddress, IN SIZE_T NumberOfBytes, IN MEMORY_CACHING_TYPE CacheType)
Definition: iosup.c:47
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1114
NTKERNELAPI ULONG NTAPI READ_REGISTER_ULONG(IN PULONG Register)
#define USB_PORT_STATUS_SUSPEND
Definition: usb200.h:153
NTSTATUS NTAPI CreateDMAMemoryManager(PDMAMEMORYMANAGER *OutMemoryManager)
POHCI_ENDPOINT_DESCRIPTOR m_BulkEndpointDescriptor
Definition: hardware.cpp:97
struct _DMA_OPERATIONS * DmaOperations
Definition: iotypes.h:2187
#define OHCI_COMMAND_STATUS_OFFSET
Definition: hardware.h:37
NTSTATUS StopController()
Definition: hardware.cpp:832
#define DEVICE_DESCRIPTION_VERSION
Definition: iotypes.h:2020
#define OHCI_CONTROL_LIST_FILLED
Definition: hardware.h:39
#define IsEqualGUIDAligned(guid1, guid2)
Definition: wdm.template.h:233
ULONG InterruptTable[OHCI_NUMBER_OF_INTERRUPTS]
Definition: hardware.h:198
#define OHCI_GET_INTERVAL_VALUE(s)
Definition: hardware.h:95
uint32_t ULONG_PTR
Definition: typedefs.h:63
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@375::@378 Interrupt
#define PORT_SUSPEND
Definition: usbhub.h:17
#define OHCI_OWNERSHIP_CHANGE_REQUEST
Definition: hardware.h:41
#define OHCI_ROOT_HUB_STATUS_CHANGE
Definition: hardware.h:55
UCHAR KIRQL
Definition: env_spec_w32.h:591
CM_PARTIAL_RESOURCE_LIST PartialResourceList
Definition: hwresource.cpp:160
#define OHCI_RH_PORTSTATUS_CCS
Definition: hardware.h:131
#define OHCI_FSMPS(i)
Definition: hardware.h:179
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define OHCI_REVISION_OFFSET
Definition: hardware.h:7
#define OHCI_PERIODIC(i)
Definition: hardware.h:185
#define OHCI_UNRECOVERABLE_ERROR
Definition: hardware.h:53
long LONG
Definition: pedump.c:60
#define OHCI_FRAME_INTERVAL_NUMBER_OFFSET
Definition: hardware.h:102
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@375 u
NTSTATUS NTAPI IoConnectInterrupt(OUT PKINTERRUPT *InterruptObject, IN PKSERVICE_ROUTINE ServiceRoutine, IN PVOID ServiceContext, IN PKSPIN_LOCK SpinLock, IN ULONG Vector, IN KIRQL Irql, IN KIRQL SynchronizeIrql, IN KINTERRUPT_MODE InterruptMode, IN BOOLEAN ShareVector, IN KAFFINITY ProcessorEnableMask, IN BOOLEAN FloatingSave)
Definition: irq.c:22
NTSTATUS NTAPI KeDelayExecutionThread(IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Interval OPTIONAL)
Definition: wait.c:283
#define STDMETHODIMP
Definition: basetyps.h:43
#define OHCI_WRITEBACK_DONE_HEAD
Definition: hardware.h:50
#define OHCI_REMOTE_WAKEUP_CONNECTED
Definition: hardware.h:31
CUSBHardwareDevice(IUnknown *OuterUnknown)
Definition: hardware.cpp:74
friend VOID NTAPI OhciDeferredRoutine(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: hardware.cpp:1425
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:251
#define IMP_IUSBHARDWAREDEVICE
#define USB_PORT_STATUS_RESET
Definition: usb200.h:155
#define OHCI_BIGGEST_INTERVAL
Definition: hardware.h:194
unsigned char BOOLEAN
#define OHCI_CONTROL_HEAD_ED_OFFSET
Definition: hardware.h:75
HD_INIT_CALLBACK * m_SCECallBack
Definition: hardware.cpp:96
smooth NULL
Definition: ftsmooth.c:416
enum _KINTERRUPT_MODE KINTERRUPT_MODE
VOID __stdcall HD_INIT_CALLBACK(IN PVOID CallBackContext)
Definition: hardware.cpp:16
#define OHCI_RH_DESCRIPTOR_A_OFFSET
Definition: hardware.h:82
#define OHCI_HCCA_OFFSET
Definition: hardware.h:73
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
ULONG CurrentFrameNumber
Definition: hardware.h:199
#define OHCI_INTERRUPT_ROUTING
Definition: hardware.h:30
NTSTATUS InitializeController()
Definition: hardware.cpp:876
void DPRINT(...)
Definition: polytest.cpp:61
#define OHCI_RH_PORTSTATUS_PES
Definition: hardware.h:132
const char * LPCSTR
Definition: xmlstorage.h:183
void * PVOID
Definition: retypes.h:9
PDEVICE_OBJECT m_FunctionalDeviceObject
Definition: hardware.cpp:80
IMP_IUSBHARDWAREDEVICE IMP_IUSBEHCIHARDWARE BOOLEAN InterruptService()
#define OHCI_NORMAL_INTERRUPTS
Definition: hardware.h:168
#define UlongToPtr(u)
Definition: config.h:106
NTSTATUS NTAPI CreateUSBQueue(PUSBQUEUE *OutUsbQueue)
Definition: usb_queue.cpp:1204
#define OHCI_HC_FUNCTIONAL_STATE_RESET
Definition: hardware.h:26
friend VOID NTAPI StatusChangeWorkItemRoutine(PVOID Context)
Definition: hardware.cpp:1447
#define PtrToUlong(u)
Definition: config.h:107
BOOLEAN Dma32BitAddresses
Definition: iotypes.h:2030
PDMAMEMORYMANAGER m_MemoryManager
Definition: hardware.cpp:95
PDMA_ADAPTER m_Adapter
Definition: hardware.cpp:88
#define PORT_ENABLE
Definition: usbhub.h:16
DWORD Interval
Definition: netstat.c:33
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:675
_In_ UINT _In_ UINT NumberOfPorts
Definition: ndis.h:5443
_Must_inspect_result_ _In_ PDEVICE_DESCRIPTION DeviceDescription
Definition: iofuncs.h:1015
#define OHCI_MASTER_INTERRUPT_ENABLE
Definition: hardware.h:57
IN PVOID IN PVOID IN USHORT IN USHORT IN PINTERFACE Interface
Definition: pci.h:359
#define OHCI_MAX_PORT_COUNT
Definition: hardware.h:250
virtual ~CUSBHardwareDevice()
Definition: hardware.cpp:75
_In_ LARGE_INTEGER _In_opt_ PKDPC Dpc
Definition: kefuncs.h:524
#define OHCI_HC_FUNCTIONAL_STATE_RESUME
Definition: hardware.h:27
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
#define OHCI_RH_PORTSTATUS_PRSC
Definition: hardware.h:142
friend BOOLEAN NTAPI InterruptServiceRoutine(IN PKINTERRUPT Interrupt, IN PVOID ServiceContext)
Definition: hardware.cpp:1242
#define TAG_USBOHCI
Definition: usbohci.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define OHCI_ENDPOINT_SKIP
Definition: hardware.h:229
BOOLEAN ScatterGather
Definition: iotypes.h:2027
const GUID IID_IUnknown
#define OHCI_RESUME_DETECTED
Definition: hardware.h:52
static const UCHAR Index[8]
Definition: usbohci.c:18
#define STDMETHODCALLTYPE
Definition: bdasup.h:9
PKINTERRUPT m_Interrupt
Definition: hardware.cpp:83
ULONG m_SyncFramePhysAddr
Definition: hardware.cpp:101
POHCIQUEUE m_UsbQueue
Definition: hardware.cpp:93
#define __stdcall
Definition: typedefs.h:25
#define USB_PORT_STATUS_CONNECT
Definition: usb200.h:151
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID ServiceContext
Definition: iofuncs.h:798
ULONG AddRef()
DMA_WIDTH DmaWidth
Definition: iotypes.h:2037
PGET_SET_DEVICE_DATA GetBusData
Definition: iotypes.h:884
#define OHCI_BULK_LIST_FILLED
Definition: hardware.h:40
#define PCI_WHICHSPACE_CONFIG
Definition: iotypes.h:3288
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define PORT_POWER
Definition: usbhub.h:20
#define OHCI_INTERRUPT_ENABLE_OFFSET
Definition: hardware.h:63
CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1]
Definition: hwresource.cpp:119
#define OHCI_INTERRUPT_STATUS_OFFSET
Definition: hardware.h:48
#define OHCI_CONTROL_BULK_RATIO_1_4
Definition: hardware.h:20
#define C_PORT_ENABLE
Definition: usbhub.h:23
#define InterlockedDecrement
Definition: armddk.h:52
#define OHCI_RH_PORT_STATUS(n)
Definition: hardware.h:130
Definition: ketypes.h:687
#define OHCI_RH_PORTSTATUS_PPS
Definition: hardware.h:136
Definition: arc.h:85
_In_z_ PCCHAR _In_ PDEVICE_OBJECT LowerDeviceObject
Definition: classpnp.h:789
PDEVICE_OBJECT m_NextDeviceObject
Definition: hardware.cpp:81
#define OHCI_RH_NO_OVER_CURRENT_PROTECTION
Definition: hardware.h:88
#define OHCI_DONE_INTERRUPTS
Definition: hardware.h:204
ULONG LowPart
Definition: typedefs.h:104
#define OHCI_HC_FUNCTIONAL_STATE_MASK
Definition: hardware.h:25
#define OHCI_RH_PORTSTATUS_PSS
Definition: hardware.h:133
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define OHCI_RH_PORTSTATUS_PESC
Definition: hardware.h:139
#define OHCI_RH_PORTSTATUS_CSC
Definition: hardware.h:138
#define OHCI_ENABLE_LIST
Definition: hardware.h:148
#define USB_ENDPOINT_TYPE_BULK
Definition: usb100.h:64
_Outptr_ PUSB_DEVICE_HANDLE _In_ PUSB_DEVICE_HANDLE _In_ USHORT PortStatus
Definition: hubbusif.h:40
_In_opt_ PENTER_STATE_SYSTEM_HANDLER _In_opt_ PVOID _In_ LONG _In_opt_ LONG volatile * Number
Definition: ntpoapi.h:204
#define OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL
Definition: hardware.h:28
static const WCHAR Control[]
Definition: interface.c:27
Status
Definition: gdiplustypes.h:24
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:675
#define OHCI_PERIODIC_START_OFFSET
Definition: hardware.h:107
#define OHCI_CONTROL_OFFSET
Definition: hardware.h:15
#define MAXULONG
Definition: typedefs.h:250
POHCIHCCA m_HCCA
Definition: hardware.cpp:94
NTSTATUS AllocateEndpointDescriptor(OUT POHCI_ENDPOINT_DESCRIPTOR *OutDescriptor)
Definition: hardware.cpp:783
static ULONG Timeout
Definition: ping.c:61
#define InterlockedIncrement
Definition: armddk.h:53
IUSBQueue * PUSBQUEUE
PHYSICAL_ADDRESS PhysicalAddress
Definition: hardware.cpp:86
POHCI_ENDPOINT_DESCRIPTOR m_InterruptEndpoints[OHCI_STATIC_ENDPOINT_COUNT]
Definition: hardware.cpp:99
unsigned short USHORT
Definition: pedump.c:61
#define OHCI_ENDPOINT_ISOCHRONOUS_FORMAT
Definition: hardware.h:241
ULONG KSPIN_LOCK
Definition: env_spec_w32.h:72
BOOL Initialize(HINSTANCE hInstance)
Definition: msconfig.c:341
_Inout_opt_ PDEVICE_OBJECT _Inout_opt_ PDEVICE_OBJECT * FunctionalDeviceObject
Definition: ndis.h:4640
STDMETHODIMP_(ULONG) AddRef()
Definition: hardware.cpp:41
#define OHCI_INTERRUPT_DISABLE_OFFSET
Definition: hardware.h:68
unsigned int * PULONG
Definition: retypes.h:1
NTSTATUS StartController()
Definition: hardware.cpp:550
IDMAMemoryManager * PDMAMEMORYMANAGER
static ULONG WINAPI AddRef(IStream *iface)
Definition: clist.c:90
#define CmResourceTypeInterrupt
Definition: hwresource.cpp:124
#define DPRINT1
Definition: precomp.h:8
#define OHCI_FRAME_INTERVAL_TOGGLE
Definition: hardware.h:97
PHYSICAL_ADDRESS PhysicalAddress
Definition: hardware.h:221
IOHCIQueue * POHCIQUEUE
Definition: interfaces.h:130
#define OUT
Definition: typedefs.h:39
INTERFACE_TYPE InterfaceType
Definition: iotypes.h:2036
#define CM_RESOURCE_INTERRUPT_LATCHED
Definition: cmtypes.h:144
struct tagContext Context
Definition: acpixf.h:1024
STDMETHODIMP QueryInterface(REFIID InterfaceId, PVOID *Interface)
unsigned int ULONG
Definition: retypes.h:1
BOOLEAN NTAPI InterruptServiceRoutine(IN PKINTERRUPT Interrupt, IN PVOID ServiceContext)
Definition: hardware.cpp:1242
#define OHCI_RH_PORTSTATUS_PRS
Definition: hardware.h:135
#define UNIMPLEMENTED
Definition: debug.h:114
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
PDRIVER_OBJECT m_DriverObject
Definition: hardware.cpp:78
POHCI_ENDPOINT_DESCRIPTOR m_ControlEndpointDescriptor
Definition: hardware.cpp:96
#define OHCI_HC_FUNCTIONAL_STATE_SUSPEND
Definition: hardware.h:29
PHYSICAL_ADDRESS m_HCCAPhysicalAddress
Definition: hardware.cpp:95
#define CmResourceTypeMemory
Definition: hwresource.cpp:125
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:711
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define OHCI_FRAME_INTERVAL_OFFSET
Definition: hardware.h:94
PDEVICE_OBJECT m_PhysicalDeviceObject
Definition: hardware.cpp:79
unsigned short * PUSHORT
Definition: retypes.h:2
VOID NTAPI KeStallExecutionProcessor(IN ULONG MicroSeconds)
Definition: ntoskrnl.c:99
#define OHCI_HOST_CONTROLLER_RESET
Definition: hardware.h:38
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ FLT_IO_OPERATION_FLAGS _Out_opt_ PULONG BytesRead
Definition: fltkernel.h:1255
#define OHCI_RH_NO_POWER_SWITCHING
Definition: hardware.h:85
volatile LONG m_StatusChangeWorkItemStatus
Definition: hardware.cpp:100
LONGLONG QuadPart
Definition: typedefs.h:112
NTSTATUS SetPortFeature(IN PDEVICE_OBJECT RootHubDeviceObject, IN ULONG PortId, IN ULONG Feature)
Definition: fdo.c:93
#define PCI_COMMON_HDR_LENGTH
Definition: iotypes.h:3238
STDMETHODIMP_(ULONG) Release()
Definition: hardware.cpp:46
_In_ PSTORAGE_PROPERTY_ID _Outptr_ PSTORAGE_DESCRIPTOR_HEADER * Descriptor
Definition: classpnp.h:966
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
_In_opt_ PVOID DeferredContext
Definition: ketypes.h:675
#define OHCI_BULK_HEAD_ED_OFFSET
Definition: hardware.h:77