ReactOS  0.4.15-dev-1636-gf634010
fdo.cpp
Go to the documentation of this file.
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/wdm/audio/hdaudbus/fdo.cpp
5 * PURPOSE: HDA Driver Entry
6 * PROGRAMMER: Johannes Anderwald
7 */
8 #include "hdaudbus.h"
9 
10 BOOLEAN
11 NTAPI
15 {
17  PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
18  ULONG InterruptStatus;
19  UCHAR RirbStatus, CorbStatus;
20 
21  /* get device extension */
22  DeviceObject = static_cast<PDEVICE_OBJECT>(ServiceContext);
23  DeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension);
24  ASSERT(DeviceExtension->IsFDO == TRUE);
25 
26  // Check if this interrupt is ours
27  InterruptStatus = READ_REGISTER_ULONG((PULONG)(DeviceExtension->RegBase + HDAC_INTR_STATUS));
28 
29  DPRINT1("HDA_InterruptService %lx\n", InterruptStatus);
30  if ((InterruptStatus & INTR_STATUS_GLOBAL) == 0)
31  return FALSE;
32 
33  // Controller or stream related?
34  if (InterruptStatus & INTR_STATUS_CONTROLLER) {
35  RirbStatus = READ_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_RIRB_STATUS);
36  CorbStatus = READ_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_CORB_STATUS);
37 
38  // Check for incoming responses
39  if (RirbStatus) {
40  WRITE_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_RIRB_STATUS, RirbStatus);
41 
42  if (DeviceExtension->RirbLength == 0)
43  {
44  /* HACK: spurious interrupt */
45  return FALSE;
46  }
47 
48  if ((RirbStatus & RIRB_STATUS_RESPONSE) != 0) {
50  }
51 
52  if ((RirbStatus & RIRB_STATUS_OVERRUN) != 0)
53  DPRINT1("hda: RIRB Overflow\n");
54  }
55 
56  // Check for sending errors
57  if (CorbStatus) {
58  WRITE_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_CORB_STATUS, CorbStatus);
59 
60  if ((CorbStatus & CORB_STATUS_MEMORY_ERROR) != 0)
61  DPRINT1("hda: CORB Memory Error!\n");
62  }
63  }
64 #if 0
65  if ((intrStatus & INTR_STATUS_STREAM_MASK) != 0) {
66  for (uint32 index = 0; index < HDA_MAX_STREAMS; index++) {
67  if ((intrStatus & (1 << index)) != 0) {
68  if (controller->streams[index]) {
69  if (stream_handle_interrupt(controller,
70  controller->streams[index], index)) {
71  handled = B_INVOKE_SCHEDULER;
72  }
73  }
74  else {
75  dprintf("hda: Stream interrupt for unconfigured stream "
76  "%ld!\n", index);
77  }
78  }
79  }
80  }
81 #endif
82  return TRUE;
83 }
84 
85 VOID
86 NTAPI
88  _In_ PKDPC Dpc,
92 {
93  PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
94  ULONG Response, ResponseFlags, Cad;
95  USHORT WritePos;
96  PHDA_CODEC_ENTRY Codec;
97 
98  /* get device extension */
99  DeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension);
100  ASSERT(DeviceExtension->IsFDO == TRUE);
101 
102  WritePos = (READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_RIRB_WRITE_POS)) + 1) % DeviceExtension->RirbLength;
103 
104  for (; DeviceExtension->RirbReadPos != WritePos; DeviceExtension->RirbReadPos = (DeviceExtension->RirbReadPos + 1) % DeviceExtension->RirbLength)
105  {
106  Response = DeviceExtension->RirbBase[DeviceExtension->RirbReadPos].response;
107  ResponseFlags = DeviceExtension->RirbBase[DeviceExtension->RirbReadPos].flags;
108  Cad = ResponseFlags & RESPONSE_FLAGS_CODEC_MASK;
109  DPRINT1("Response %lx ResponseFlags %lx Cad %lx\n", Response, ResponseFlags, Cad);
110 
111  /* get codec */
112  Codec = DeviceExtension->Codecs[Cad];
113  if (Codec == NULL)
114  {
115  DPRINT1("hda: response for unknown codec %x Response %x ResponseFlags %x\n", Cad, Response, ResponseFlags);
116  continue;
117  }
118 
119  /* check response count */
120  if (Codec->ResponseCount >= MAX_CODEC_RESPONSES)
121  {
122  DPRINT1("too many responses for codec %x Response %x ResponseFlags %x\n", Cad, Response, ResponseFlags);
123  continue;
124  }
125 
126  // FIXME handle unsolicited responses
127  ASSERT((ResponseFlags & RESPONSE_FLAGS_UNSOLICITED) == 0);
128 
129  /* store response */
130  Codec->Responses[Codec->ResponseCount] = Response;
131  Codec->ResponseCount++;
133  }
134 }
135 
136 
137 NTSTATUS
140  IN PHDA_CODEC_ENTRY Codec,
141  IN PULONG Verbs,
142  OUT PULONG Responses,
143  IN ULONG Count)
144 {
145  PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
146  ULONG Sent = 0, ReadPosition, WritePosition, Queued;
147 
148  /* get device extension */
149  DeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
150  ASSERT(DeviceExtension->IsFDO);
151 
152  /* reset response count */
153  Codec->ResponseCount = 0;
154 
155  while (Sent < Count) {
156  ReadPosition = READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_CORB_READ_POS));
157 
158  Queued = 0;
159 
160  while (Sent < Count) {
161  WritePosition = (DeviceExtension->CorbWritePos + 1) % DeviceExtension->CorbLength;
162 
163  if (WritePosition == ReadPosition) {
164  // There is no space left in the ring buffer; execute the
165  // queued commands and wait until
166  break;
167  }
168 
169  DeviceExtension->CorbBase[WritePosition] = Verbs[Sent++];
170  DeviceExtension->CorbWritePos = WritePosition;
171  Queued++;
172  }
173 
174  WRITE_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_CORB_WRITE_POS), DeviceExtension->CorbWritePos);
175  }
176 
177  while (Queued--)
178  {
180  Timeout.QuadPart = -1000LL * 10000; // 1 sec
181 
182  NTSTATUS waitStatus = KeWaitForSingleObject(&Codec->ResponseSemaphore,
183  Executive,
184  KernelMode,
185  FALSE,
186  &Timeout);
187 
188  if (waitStatus == STATUS_TIMEOUT)
189  {
190  DPRINT1("HDA_SendVerbs: timeout! Queued: %u\n", Queued);
192  }
193  }
194 
195  if (Responses != NULL) {
196  memcpy(Responses, Codec->Responses, Codec->ResponseCount * sizeof(ULONG));
197  }
198 
199  return STATUS_SUCCESS;
200 }
201 
202 NTSTATUS
205  IN ULONG codecAddress)
206 {
208  ULONG verbs[3];
209  PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
211  ULONG NodeId, GroupType;
213  PHDA_CODEC_AUDIO_GROUP AudioGroup;
214  PHDA_PDO_DEVICE_EXTENSION ChildDeviceExtension;
215 
216  /* lets allocate the entry */
218  if (!Entry)
219  {
220  DPRINT1("hda: failed to allocate memory");
221  return STATUS_UNSUCCESSFUL;
222  }
223 
224  /* init codec */
225  Entry->Addr = codecAddress;
226  KeInitializeSemaphore(&Entry->ResponseSemaphore, 0, MAX_CODEC_RESPONSES);
227 
228  /* get device extension */
229  DeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
230 
231  /* store codec */
232  DeviceExtension->Codecs[codecAddress] = Entry;
233 
234  verbs[0] = MAKE_VERB(codecAddress, 0, VID_GET_PARAMETER, PID_VENDOR_ID);
235  verbs[1] = MAKE_VERB(codecAddress, 0, VID_GET_PARAMETER, PID_REVISION_ID);
236  verbs[2] = MAKE_VERB(codecAddress, 0, VID_GET_PARAMETER, PID_SUB_NODE_COUNT);
237 
238  /* get basic info */
240  if (!NT_SUCCESS(Status))
241  {
242  FreeItem(Entry);
243  DeviceExtension->Codecs[codecAddress] = NULL;
244  return Status;
245  }
246 
247  /* store codec details */
248  Entry->Major = Response.major;
249  Entry->Minor = Response.minor;
250  Entry->ProductId = Response.device;
251  Entry->Revision = Response.revision;
252  Entry->Stepping = Response.stepping;
253  Entry->VendorId = Response.vendor;
254 
255  DPRINT1("hda Codec %ld Vendor: %04lx Product: %04lx, Revision: %lu.%lu.%lu.%lu NodeStart %u NodeCount %u \n", codecAddress, Response.vendor,
256  Response.device, Response.major, Response.minor, Response.revision, Response.stepping, Response.start, Response.count);
257 
258  for (NodeId = Response.start; NodeId < Response.start + Response.count; NodeId++) {
259 
260  /* get function type */
261  verbs[0] = MAKE_VERB(codecAddress, NodeId, VID_GET_PARAMETER, PID_FUNCTION_GROUP_TYPE);
262 
263  Status = HDA_SendVerbs(DeviceObject, Entry, verbs, &GroupType, 1);
264  DPRINT1("Status %x NodeId %u GroupType %x\n", Status, NodeId, GroupType);
265 
266 
267  if (NT_SUCCESS(Status) &&
269  {
270  if (Entry->AudioGroupCount >= HDA_MAX_AUDIO_GROUPS)
271  {
272  DPRINT1("Too many audio groups in node %u. Skipping.\n", NodeId);
273  break;
274  }
275 
277  if (!AudioGroup)
278  {
279  DPRINT1("hda: insufficient memory\n");
281  }
282 
283  /* init audio group */
284  AudioGroup->NodeId = NodeId;
286 
287  // Found an Audio Function Group!
288  DPRINT1("NodeId %x found an audio function group!\n", NodeId);
289 
291  if (!NT_SUCCESS(Status))
292  {
293  FreeItem(AudioGroup);
294  DPRINT1("hda failed to create device object %x\n", Status);
295  return Status;
296  }
297 
298  /* init child pdo*/
299  ChildDeviceExtension = (PHDA_PDO_DEVICE_EXTENSION)AudioGroup->ChildPDO->DeviceExtension;
300  ChildDeviceExtension->IsFDO = FALSE;
301  ChildDeviceExtension->ReportedMissing = FALSE;
302  ChildDeviceExtension->Codec = Entry;
303  ChildDeviceExtension->AudioGroup = AudioGroup;
304  ChildDeviceExtension->FDO = DeviceObject;
305 
306  /* setup flags */
307  AudioGroup->ChildPDO->Flags |= DO_POWER_PAGABLE;
308  AudioGroup->ChildPDO->Flags &= ~DO_DEVICE_INITIALIZING;
309 
310  /* add audio group*/
311  Entry->AudioGroups[Entry->AudioGroupCount] = AudioGroup;
312  Entry->AudioGroupCount++;
313  }
314  }
315  return STATUS_SUCCESS;
316 
317 }
318 
319 NTSTATUS
320 NTAPI
323 {
324  PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
325  UCHAR corbSize, value, rirbSize;
326  PHYSICAL_ADDRESS HighestPhysicalAddress, CorbPhysicalAddress;
327  ULONG Index;
328  USHORT corbReadPointer, rirbWritePointer, interruptValue, corbControl, rirbControl;
329 
330  /* get device extension */
331  DeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
332 
333  // Determine and set size of CORB
334  corbSize = READ_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_CORB_SIZE);
335  if ((corbSize & CORB_SIZE_CAP_256_ENTRIES) != 0) {
336  DeviceExtension->CorbLength = 256;
337 
340  }
341  else if (corbSize & CORB_SIZE_CAP_16_ENTRIES) {
342  DeviceExtension->CorbLength = 16;
343 
346  }
347  else if (corbSize & CORB_SIZE_CAP_2_ENTRIES) {
348  DeviceExtension->CorbLength = 2;
349 
352  }
353 
354  // Determine and set size of RIRB
355  rirbSize = READ_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_RIRB_SIZE);
356  if (rirbSize & RIRB_SIZE_CAP_256_ENTRIES) {
357  DeviceExtension->RirbLength = 256;
358 
361  }
362  else if (rirbSize & RIRB_SIZE_CAP_16_ENTRIES) {
363  DeviceExtension->RirbLength = 16;
364 
367  }
368  else if (rirbSize & RIRB_SIZE_CAP_2_ENTRIES) {
369  DeviceExtension->RirbLength = 2;
370 
373  }
374 
375  /* init corb */
376  HighestPhysicalAddress.QuadPart = 0x00000000FFFFFFFF;
377  DeviceExtension->CorbBase = (PULONG)MmAllocateContiguousMemory(PAGE_SIZE * 3, HighestPhysicalAddress);
378  ASSERT(DeviceExtension->CorbBase != NULL);
379 
380  // FIXME align rirb 128bytes
381  ASSERT(DeviceExtension->CorbLength == 256);
382  ASSERT(DeviceExtension->RirbLength == 256);
383 
384  CorbPhysicalAddress = MmGetPhysicalAddress(DeviceExtension->CorbBase);
385  ASSERT(CorbPhysicalAddress.QuadPart != 0LL);
386 
387  // Program CORB/RIRB for these locations
388  WRITE_REGISTER_ULONG((PULONG)(DeviceExtension->RegBase + HDAC_CORB_BASE_LOWER), CorbPhysicalAddress.LowPart);
389  WRITE_REGISTER_ULONG((PULONG)(DeviceExtension->RegBase + HDAC_CORB_BASE_UPPER), CorbPhysicalAddress.HighPart);
390 
391  DeviceExtension->RirbBase = (PRIRB_RESPONSE)((ULONG_PTR)DeviceExtension->CorbBase + PAGE_SIZE);
392  CorbPhysicalAddress.QuadPart += PAGE_SIZE;
393  WRITE_REGISTER_ULONG((PULONG)(DeviceExtension->RegBase + HDAC_RIRB_BASE_LOWER), CorbPhysicalAddress.LowPart);
394  WRITE_REGISTER_ULONG((PULONG)(DeviceExtension->RegBase + HDAC_RIRB_BASE_UPPER), CorbPhysicalAddress.HighPart);
395 
396  // Program DMA position update
397  DeviceExtension->StreamPositions = (PVOID)((ULONG_PTR)DeviceExtension->RirbBase + PAGE_SIZE);
398  CorbPhysicalAddress.QuadPart += PAGE_SIZE;
399  WRITE_REGISTER_ULONG((PULONG)(DeviceExtension->RegBase + HDAC_DMA_POSITION_BASE_LOWER), CorbPhysicalAddress.LowPart);
400  WRITE_REGISTER_ULONG((PULONG)(DeviceExtension->RegBase + HDAC_DMA_POSITION_BASE_UPPER), CorbPhysicalAddress.HighPart);
401 
404 
405  // Reset CORB read pointer. Preserve bits marked as RsvdP.
406  // After setting the reset bit, we must wait for the hardware
407  // to acknowledge it, then manually unset it and wait for that
408  // to be acknowledged as well.
409  corbReadPointer = READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_CORB_READ_POS));
410 
411  corbReadPointer |= CORB_READ_POS_RESET;
412  WRITE_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_CORB_READ_POS), corbReadPointer);
413 
414  for (Index = 0; Index < 10; Index++) {
416  corbReadPointer = READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_CORB_READ_POS));
417  if ((corbReadPointer & CORB_READ_POS_RESET) != 0)
418  break;
419  }
420  if ((corbReadPointer & CORB_READ_POS_RESET) == 0) {
421  DPRINT1("hda: CORB read pointer reset not acknowledged\n");
422 
423  // According to HDA spec v1.0a ch3.3.21, software must read the
424  // bit as 1 to verify that the reset completed. However, at least
425  // some nVidia HDA controllers do not update the bit after reset.
426  // Thus don't fail here on nVidia controllers.
427  //if (controller->pci_info.vendor_id != PCI_VENDOR_NVIDIA)
428  // return B_BUSY;
429  }
430 
431  corbReadPointer &= ~CORB_READ_POS_RESET;
432  WRITE_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_CORB_READ_POS), corbReadPointer);
433  for (Index = 0; Index < 10; Index++) {
435  corbReadPointer = READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_CORB_READ_POS));
436  if ((corbReadPointer & CORB_READ_POS_RESET) == 0)
437  break;
438  }
439  if ((corbReadPointer & CORB_READ_POS_RESET) != 0) {
440  DPRINT1("hda: CORB read pointer reset failed\n");
441  return STATUS_UNSUCCESSFUL;
442  }
443 
444  // Reset RIRB write pointer
445  rirbWritePointer = READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_RIRB_WRITE_POS)) & ~RIRB_WRITE_POS_RESET;
446  WRITE_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_RIRB_WRITE_POS), rirbWritePointer | RIRB_WRITE_POS_RESET);
447 
448  // Generate interrupt for every response
450  WRITE_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_RESPONSE_INTR_COUNT), interruptValue | 1);
451 
452  // Setup cached read/write indices
453  DeviceExtension->RirbReadPos = 1;
454  DeviceExtension->CorbWritePos = 0;
455 
456  // Gentlemen, start your engines...
457  corbControl = READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_CORB_CONTROL)) & ~HDAC_CORB_CONTROL_MASK;
459 
460  rirbControl = READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_RIRB_CONTROL)) & ~HDAC_RIRB_CONTROL_MASK;
462 
463  return STATUS_SUCCESS;
464 }
465 
466 NTSTATUS
467 NTAPI
470 {
471  USHORT ValCapabilities;
472  ULONG Index;
473  PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
474  ULONG InputStreams, OutputStreams, BiDirStreams, Control;
475  UCHAR corbControl, rirbControl;
476 
477  /* get device extension */
478  DeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
479 
480  /* read caps */
481  ValCapabilities = READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_GLOBAL_CAP));
482 
483  InputStreams = GLOBAL_CAP_INPUT_STREAMS(ValCapabilities);
484  OutputStreams = GLOBAL_CAP_OUTPUT_STREAMS(ValCapabilities);
485  BiDirStreams = GLOBAL_CAP_BIDIR_STREAMS(ValCapabilities);
486 
487  DPRINT1("NumInputStreams %u\n", InputStreams);
488  DPRINT1("NumOutputStreams %u\n", OutputStreams);
489  DPRINT1("NumBiDirStreams %u\n", BiDirStreams);
490 
491  /* stop all streams */
492  for (Index = 0; Index < InputStreams; Index++)
493  {
496  }
497 
498  for (Index = 0; Index < OutputStreams; Index++) {
501  }
502 
503  for (Index = 0; Index < BiDirStreams; Index++) {
504  WRITE_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_STREAM_CONTROL0 + HDAC_STREAM_BASE + HDAC_BIDIR_STREAM_OFFSET(InputStreams, OutputStreams, Index), 0);
505  WRITE_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_STREAM_STATUS + HDAC_STREAM_BASE + HDAC_BIDIR_STREAM_OFFSET(InputStreams, OutputStreams, Index), 0);
506  }
507 
508  // stop DMA
511 
514 
515  for (int timeout = 0; timeout < 10; timeout++) {
517 
518  corbControl = READ_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_CORB_CONTROL);
519  rirbControl = READ_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_RIRB_CONTROL);
520  if (corbControl == 0 && rirbControl == 0)
521  break;
522  }
523  if (corbControl != 0 || rirbControl != 0) {
524  DPRINT1("hda: unable to stop dma\n");
525  return STATUS_UNSUCCESSFUL;
526  }
527 
528  // reset DMA position buffer
531 
532  // Set reset bit - it must be asserted for at least 100us
535 
536  for (int timeout = 0; timeout < 10; timeout++) {
538 
540  if ((Control & GLOBAL_CONTROL_RESET) == 0)
541  break;
542  }
543  if ((Control & GLOBAL_CONTROL_RESET) != 0)
544  {
545  DPRINT1("hda: unable to reset controller\n");
546  return STATUS_UNSUCCESSFUL;
547  }
548 
549  // Unset reset bit
552 
553  for (int timeout = 0; timeout < 10; timeout++) {
555 
557  if ((Control & GLOBAL_CONTROL_RESET) != 0)
558  break;
559  }
560  if ((Control & GLOBAL_CONTROL_RESET) == 0) {
561  DPRINT1("hda: unable to exit reset\n");
562  return STATUS_UNSUCCESSFUL;
563  }
564 
565  // Wait for codecs to finish their own reset (apparently needs more
566  // time than documented in the specs)
568 
569  // Enable unsolicited responses
572 
573  return STATUS_SUCCESS;
574 }
575 
576 NTSTATUS
577 NTAPI
580  IN PIRP Irp)
581 {
582  PIO_STACK_LOCATION IoStack;
584  PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
586  ULONG Index;
587  USHORT Value;
588 
589  /* get device extension */
590  DeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
591  ASSERT(DeviceExtension->IsFDO == TRUE);
592 
593  /* forward irp to lower device */
594  if (!IoForwardIrpSynchronously(DeviceExtension->LowerDevice, Irp))
595  {
596  ASSERT(FALSE);
598  }
599  Status = Irp->IoStatus.Status;
600  if (!NT_SUCCESS(Status))
601  {
602  // failed to start
603  DPRINT1("HDA_StartDevice Lower device failed to start %x\n", Status);
604  return Status;
605  }
606 
607  /* get current irp stack location */
609 
610  Resources = IoStack->Parameters.StartDevice.AllocatedResourcesTranslated;
611  for (Index = 0; Index < Resources->List[0].PartialResourceList.Count; Index++)
612  {
613  PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor = &Resources->List[0].PartialResourceList.PartialDescriptors[Index];
614 
615  if (Descriptor->Type == CmResourceTypeMemory)
616  {
617  DeviceExtension->RegLength = Descriptor->u.Memory.Length;
618  DeviceExtension->RegBase = (PUCHAR)MmMapIoSpace(Descriptor->u.Memory.Start, Descriptor->u.Memory.Length, MmNonCached);
619  if (DeviceExtension->RegBase == NULL)
620  {
621  DPRINT1("[HDAB] Failed to map registers\n");
623  break;
624  }
625  }
626  else if (Descriptor->Type == CmResourceTypeInterrupt)
627  {
628  Status = IoConnectInterrupt(&DeviceExtension->Interrupt,
630  DeviceObject,
631  NULL,
632  Descriptor->u.Interrupt.Vector,
633  Descriptor->u.Interrupt.Level,
634  Descriptor->u.Interrupt.Level,
636  (Descriptor->ShareDisposition != CmResourceShareDeviceExclusive),
637  Descriptor->u.Interrupt.Affinity,
638  FALSE);
639  if (!NT_SUCCESS(Status))
640  {
641  DPRINT1("[HDAB] Failed to connect interrupt. Status=%lx\n", Status);
642  break;
643  }
644 
645  }
646  }
647 
648  if (NT_SUCCESS(Status))
649  {
650  // Get controller into valid state
652  if (!NT_SUCCESS(Status)) return Status;
653 
654  // Setup CORB/RIRB/DMA POS
656  if (!NT_SUCCESS(Status)) return Status;
657 
658 
659  // Don't enable codec state change interrupts. We don't handle
660  // them, as we want to use the STATE_STATUS register to identify
661  // available codecs. We'd have to clear that register in the interrupt
662  // handler to 'ack' the codec change.
665 
666  // Enable controller interrupts
668 
670 
672  if (!Value) {
673  DPRINT1("hda: bad codec status\n");
674  return STATUS_UNSUCCESSFUL;
675  }
677 
678  // Create codecs
679  DPRINT1("Codecs %lx\n", Value);
680  for (Index = 0; Index < HDA_MAX_CODECS; Index++) {
681  if ((Value & (1 << Index)) != 0) {
683  }
684  }
685  }
686 
687  return Status;
688 }
689 
690 NTSTATUS
691 NTAPI
694  _Inout_ PIRP Irp)
695 {
697  PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
698  ULONG CodecIndex, AFGIndex;
699  PHDA_CODEC_ENTRY CodecEntry;
700  PDEVICE_OBJECT ChildPDO;
701  PHDA_PDO_DEVICE_EXTENSION ChildDeviceExtension;
702 
703  /* get device extension */
704  DeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension);
705  ASSERT(DeviceExtension->IsFDO == TRUE);
706 
707  Irp->IoStatus.Status = STATUS_SUCCESS;
709  Status = IoCallDriver(DeviceExtension->LowerDevice, Irp);
710 
711  IoDetachDevice(DeviceExtension->LowerDevice);
712 
713  if (DeviceExtension->RegBase != NULL)
714  {
715  MmUnmapIoSpace(DeviceExtension->RegBase,
716  DeviceExtension->RegLength);
717  }
718  if (DeviceExtension->Interrupt != NULL)
719  {
720  IoDisconnectInterrupt(DeviceExtension->Interrupt);
721  }
722  if (DeviceExtension->CorbBase != NULL)
723  {
724  MmFreeContiguousMemory(DeviceExtension->CorbBase);
725  }
726 
727  for (CodecIndex = 0; CodecIndex < HDA_MAX_CODECS; CodecIndex++)
728  {
729  CodecEntry = DeviceExtension->Codecs[CodecIndex];
730  if (CodecEntry == NULL)
731  {
732  continue;
733  }
734 
736  for (AFGIndex = 0; AFGIndex < CodecEntry->AudioGroupCount; AFGIndex++)
737  {
738  ChildPDO = CodecEntry->AudioGroups[AFGIndex]->ChildPDO;
739  if (ChildPDO != NULL)
740  {
741  ChildDeviceExtension = static_cast<PHDA_PDO_DEVICE_EXTENSION>(ChildPDO->DeviceExtension);
742  ChildDeviceExtension->Codec = NULL;
743  ChildDeviceExtension->AudioGroup = NULL;
744  ChildDeviceExtension->FDO = NULL;
745  ChildDeviceExtension->ReportedMissing = TRUE;
746  HDA_PDORemoveDevice(ChildPDO);
747  }
748  FreeItem(CodecEntry->AudioGroups[AFGIndex]);
749  }
750  FreeItem(CodecEntry);
751  }
752 
754 
755  return Status;
756 }
757 
758 NTSTATUS
759 NTAPI
762  IN PIRP Irp)
763 {
764  ULONG DeviceCount, CodecIndex, AFGIndex;
765  PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
766  PHDA_CODEC_ENTRY Codec;
767  PDEVICE_RELATIONS DeviceRelations;
768 
769  /* get device extension */
770  DeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
771  ASSERT(DeviceExtension->IsFDO == TRUE);
772 
773  DeviceCount = 0;
774  for (CodecIndex = 0; CodecIndex < HDA_MAX_CODECS; CodecIndex++)
775  {
776  if (DeviceExtension->Codecs[CodecIndex] == NULL)
777  continue;
778 
779  Codec = DeviceExtension->Codecs[CodecIndex];
780  DeviceCount += Codec->AudioGroupCount;
781  }
782 
783  if (DeviceCount == 0)
784  return STATUS_UNSUCCESSFUL;
785 
786  DeviceRelations = (PDEVICE_RELATIONS)AllocateItem(NonPagedPool, sizeof(DEVICE_RELATIONS) + (DeviceCount > 1 ? sizeof(PDEVICE_OBJECT) * (DeviceCount - 1) : 0));
787  if (!DeviceRelations)
789 
790  DeviceRelations->Count = 0;
791  for (CodecIndex = 0; CodecIndex < HDA_MAX_CODECS; CodecIndex++)
792  {
793  if (DeviceExtension->Codecs[CodecIndex] == NULL)
794  continue;
795 
796  Codec = DeviceExtension->Codecs[CodecIndex];
798  for (AFGIndex = 0; AFGIndex < Codec->AudioGroupCount; AFGIndex++)
799  {
800  DeviceRelations->Objects[DeviceRelations->Count] = Codec->AudioGroups[AFGIndex]->ChildPDO;
801  ObReferenceObject(Codec->AudioGroups[AFGIndex]->ChildPDO);
802  DeviceRelations->Count++;
803  }
804  }
805 
806  /* FIXME handle existing device relations */
807  ASSERT(Irp->IoStatus.Information == 0);
808 
809  /* store device relations */
810  Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
811 
812  /* done */
813  return STATUS_SUCCESS;
814 }
815 
816 
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
#define RIRB_STATUS_RESPONSE
#define DO_POWER_PAGABLE
#define GLOBAL_CONTROL_RESET
#define HDAC_RIRB_STATUS
#define HDAC_DMA_POSITION_BASE_UPPER
#define IN
Definition: typedefs.h:39
NTKERNELAPI VOID NTAPI WRITE_REGISTER_ULONG(IN PULONG Register, IN ULONG Value)
#define HDA_MAX_AUDIO_GROUPS
Definition: driver.h:40
#define LL
Definition: tui.h:84
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
PHDA_CODEC_ENTRY Codec
Definition: hdaudbus.h:90
_Must_inspect_result_ _In_ PWDF_DPC_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFDPC * Dpc
Definition: wdfdpc.h:107
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:339
NTSTATUS HDA_SendVerbs(IN PDEVICE_OBJECT DeviceObject, IN PHDA_CODEC_ENTRY Codec, IN PULONG Verbs, OUT PULONG Responses, IN ULONG Count)
Definition: fdo.cpp:138
struct _Entry Entry
Definition: kefuncs.h:627
#define CORB_CONTROL_MEMORY_ERROR_INTR
#define HDAC_INPUT_STREAM_OFFSET(index)
Definition: hdaudbus.h:22
#define HDAC_RESPONSE_INTR_COUNT_MASK
#define INTR_STATUS_CONTROLLER
#define TRUE
Definition: types.h:120
#define PID_SUB_NODE_COUNT
#define GLOBAL_CAP_OUTPUT_STREAMS(cap)
struct _DEVICE_OBJECT * PDEVICE_OBJECT
#define HDAC_INTR_CONTROL
BOOLEAN NTAPI IoForwardIrpSynchronously(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1625
#define RESPONSE_FLAGS_CODEC_MASK
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2160
unsigned int uint32
Definition: types.h:32
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_INTERRUPT_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFINTERRUPT * Interrupt
Definition: wdfinterrupt.h:372
unsigned char * PUCHAR
Definition: retypes.h:3
PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes)
Definition: misc.c:30
struct HDA_FDO_DEVICE_EXTENSION * PHDA_FDO_DEVICE_EXTENSION
struct HDA_PDO_DEVICE_EXTENSION * PHDA_PDO_DEVICE_EXTENSION
LONG NTSTATUS
Definition: precomp.h:26
#define HDAC_STREAM_CONTROL0
#define HDAC_RIRB_SIZE_MASK
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
PDEVICE_OBJECT FDO
Definition: hdaudbus.h:92
VOID NTAPI IoDetachDevice(IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:1296
#define GLOBAL_CAP_INPUT_STREAMS(cap)
NTKERNELAPI VOID NTAPI WRITE_REGISTER_USHORT(IN PUSHORT Register, IN USHORT Value)
Definition: dhcpd.h:245
PVOID NTAPI MmMapIoSpace(IN PHYSICAL_ADDRESS PhysicalAddress, IN SIZE_T NumberOfBytes, IN MEMORY_CACHING_TYPE CacheType)
Definition: iosup.c:47
NTKERNELAPI ULONG NTAPI READ_REGISTER_ULONG(IN PULONG Register)
#define RIRB_SIZE_16_ENTRIES
NTSTATUS NTAPI HDA_ResetController(IN PDEVICE_OBJECT DeviceObject)
Definition: fdo.cpp:468
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define PID_REVISION_ID
#define HDAC_RIRB_CONTROL
VOID NTAPI MmFreeContiguousMemory(IN PVOID BaseAddress)
Definition: contmem.c:653
#define _In_opt_
Definition: no_sal2.h:212
#define INTR_STATUS_GLOBAL
NTSTATUS NTAPI HDA_FDOStartDevice(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: fdo.cpp:578
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define HDAC_RIRB_WRITE_POS
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
NTSTATUS NTAPI HDA_FDOQueryBusRelations(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: fdo.cpp:760
VOID FreeItem(IN PVOID Item)
Definition: misc.c:43
#define HDAC_STREAM_BASE
#define HDAC_INTR_STATUS
PHDA_CODEC_ENTRY Codecs[HDA_MAX_CODECS+1]
Definition: hdaudbus.h:82
#define HDAC_GLOBAL_CONTROL
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
NTSTATUS NTAPI HDA_InitCorbRirbPos(IN PDEVICE_OBJECT DeviceObject)
Definition: fdo.cpp:321
#define FALSE
Definition: types.h:117
_In_ PIRP Irp
Definition: csq.h:116
#define CORB_SIZE_2_ENTRIES
ULONG AudioGroupCount
Definition: hdaudbus.h:60
#define PID_VENDOR_ID
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
struct RIRB_RESPONSE * PRIRB_RESPONSE
#define dprintf
Definition: regdump.c:33
ULONG DeviceCount
Definition: mpu401.c:26
ULONG response
Definition: hdaudbus.h:34
#define HDAC_WAKE_ENABLE
struct HDA_CODEC_AUDIO_GROUP * PHDA_CODEC_AUDIO_GROUP
#define MAX_CODEC_RESPONSES
Definition: driver.h:43
PHDA_CODEC_AUDIO_GROUP AudioGroups[HDA_MAX_AUDIO_GROUPS]
Definition: hdaudbus.h:59
#define HDAC_RESPONSE_INTR_COUNT
#define HDAC_RIRB_SIZE
struct _DEVICE_RELATIONS * PDEVICE_RELATIONS
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
_In_ WDF_WMI_PROVIDER_CONTROL Control
Definition: wdfwmi.h:166
#define RIRB_SIZE_2_ENTRIES
enum _KINTERRUPT_MODE KINTERRUPT_MODE
VOID NTAPI IoDisconnectInterrupt(PKINTERRUPT InterruptObject)
Definition: irq.c:140
#define INTR_CONTROL_GLOBAL_ENABLE
#define HDAC_WAKE_ENABLE_MASK
WDF_EXTERN_C_START typedef _In_ WDFCMRESLIST Resources
Definition: wdfpdo.h:63
#define RIRB_SIZE_CAP_2_ENTRIES
#define GLOBAL_CONTROL_UNSOLICITED
#define CORB_SIZE_256_ENTRIES
GLuint index
Definition: glext.h:6031
void * PVOID
Definition: retypes.h:9
#define RIRB_WRITE_POS_RESET
#define FILE_AUTOGENERATED_DEVICE_NAME
Definition: iotypes.h:138
NTSTATUS HDA_InitCodec(IN PDEVICE_OBJECT DeviceObject, IN ULONG codecAddress)
Definition: fdo.cpp:203
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
#define RIRB_STATUS_OVERRUN
Status
Definition: gdiplustypes.h:24
int Count
Definition: noreturn.cpp:7
#define HDAC_RIRB_BASE_UPPER
ULONG Responses[MAX_CODEC_RESPONSES]
Definition: hdaudbus.h:55
VOID NTAPI KeInitializeSemaphore(IN PKSEMAPHORE Semaphore, IN LONG Count, IN LONG Limit)
Definition: semphobj.c:22
#define HDAC_CORB_BASE_LOWER
#define ASSERT(a)
Definition: mode.c:45
if(!(yy_init))
Definition: macro.lex.yy.c:714
VOID NTAPI HDA_DpcForIsr(_In_ PKDPC Dpc, _In_opt_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp, _In_opt_ PVOID Context)
Definition: fdo.cpp:87
NTSTATUS HDA_PDORemoveDevice(_In_ PDEVICE_OBJECT DeviceObject)
Definition: pdo.cpp:11
#define HDAC_RIRB_CONTROL_MASK
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ WDFCOLLECTION _In_ ULONG Index
FORCEINLINE VOID IoRequestDpc(_Inout_ PDEVICE_OBJECT DeviceObject, _In_opt_ PIRP Irp, _In_opt_ __drv_aliasesMem PVOID Context)
Definition: iofuncs.h:2746
#define PID_FUNCTION_GROUP_TYPE
ULONG flags
Definition: hdaudbus.h:35
#define MAKE_VERB(cad, nid, vid, payload)
#define for
Definition: utility.h:88
#define CORB_SIZE_CAP_256_ENTRIES
#define HDAC_CORB_STATUS
#define _Inout_
Definition: no_sal2.h:162
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID ServiceContext
Definition: iofuncs.h:798
#define HDAC_RIRB_BASE_LOWER
Definition: ncftp.h:89
#define HDAC_GLOBAL_CAP
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
unsigned char UCHAR
Definition: xmlstorage.h:181
#define INTR_CONTROL_CONTROLLER_ENABLE
#define RIRB_CONTROL_RESPONSE_INTR
Definition: ketypes.h:687
PDEVICE_OBJECT LowerDevice
Definition: hdaudbus.h:68
ULONG LowPart
Definition: typedefs.h:106
#define HDA_MAX_STREAMS
Definition: driver.h:42
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define HDAC_CORB_CONTROL
#define FILE_DEVICE_SOUND
Definition: winioctl.h:135
#define HDAC_STATE_STATUS
#define PAGE_SIZE
Definition: env_spec_w32.h:49
GLsizei const GLfloat * value
Definition: glext.h:6069
#define HDAC_CORB_BASE_UPPER
Definition: hdaudbus.h:45
#define HDAC_CORB_WRITE_POS_MASK
#define FUNCTION_GROUP_NODETYPE_MASK
#define VID_GET_PARAMETER
#define CORB_SIZE_16_ENTRIES
NTKERNELAPI UCHAR NTAPI READ_REGISTER_UCHAR(IN PUCHAR Register)
#define HDAC_CORB_WRITE_POS
BOOLEAN NTAPI HDA_InterruptService(IN PKINTERRUPT Interrupt, IN PVOID ServiceContext)
Definition: fdo.cpp:12
#define CORB_READ_POS_RESET
#define _In_
Definition: no_sal2.h:158
#define RIRB_SIZE_256_ENTRIES
#define HDAC_STREAM_STATUS
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
#define HDA_MAX_CODECS
Definition: driver.h:41
static ULONG Timeout
Definition: ping.c:61
struct HDA_CODEC_ENTRY * PHDA_CODEC_ENTRY
LONG NTAPI KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, IN KPRIORITY Increment, IN LONG Adjustment, IN BOOLEAN Wait)
Definition: semphobj.c:54
#define CORB_SIZE_CAP_2_ENTRIES
unsigned short USHORT
Definition: pedump.c:61
#define INTR_STATUS_STREAM_MASK
VOID NTAPI MmUnmapIoSpace(IN PVOID BaseAddress, IN SIZE_T NumberOfBytes)
Definition: iosup.c:193
#define GLOBAL_CAP_BIDIR_STREAMS(cap)
unsigned int * PULONG
Definition: retypes.h:1
#define RESPONSE_FLAGS_UNSOLICITED
#define HDAC_CORB_CONTROL_MASK
#define NULL
Definition: types.h:112
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
PHDA_CODEC_AUDIO_GROUP AudioGroup
Definition: hdaudbus.h:91
PVOID NTAPI MmAllocateContiguousMemory(IN SIZE_T NumberOfBytes, IN PHYSICAL_ADDRESS HighestAcceptableAddress)
Definition: contmem.c:626
UINT Sent
Definition: arping.c:39
#define CORB_STATUS_MEMORY_ERROR
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
#define HDAC_OUTPUT_STREAM_OFFSET(num_input_streams, index)
Definition: hdaudbus.h:24
#define CmResourceTypeInterrupt
Definition: hwresource.cpp:124
#define DPRINT1
Definition: precomp.h:8
#define CORB_CONTROL_RUN
#define RIRB_SIZE_CAP_256_ENTRIES
#define HDAC_CORB_READ_POS
#define OUT
Definition: typedefs.h:40
#define ObReferenceObject
Definition: obfuncs.h:204
#define CM_RESOURCE_INTERRUPT_LATCHED
Definition: cmtypes.h:144
PDEVICE_OBJECT ChildPDO
Definition: hdaudbus.h:40
#define HDAC_DMA_POSITION_BASE_LOWER
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:598
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
NTKERNELAPI USHORT NTAPI READ_REGISTER_USHORT(IN PUSHORT Register)
struct Response Response
#define ULONG_PTR
Definition: config.h:101
PHYSICAL_ADDRESS NTAPI MmGetPhysicalAddress(IN PVOID Address)
Definition: stubs.c:686
#define RIRB_SIZE_CAP_16_ENTRIES
#define RIRB_CONTROL_DMA_ENABLE
#define STATUS_SUCCESS
Definition: shellext.h:65
PKINTERRUPT Interrupt
Definition: hdaudbus.h:72
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3124
#define CmResourceTypeMemory
Definition: hwresource.cpp:125
#define FUNCTION_GROUP_NODETYPE_AUDIO
#define HDAC_CORB_SIZE_MASK
#define HDAC_CORB_SIZE
NTSTATUS NTAPI HDA_FDORemoveDevice(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
Definition: fdo.cpp:692
PRIRB_RESPONSE RirbBase
Definition: hdaudbus.h:77
NTKERNELAPI VOID NTAPI WRITE_REGISTER_UCHAR(IN PUCHAR Register, IN UCHAR Value)
unsigned short * PUSHORT
Definition: retypes.h:2
VOID NTAPI KeStallExecutionProcessor(IN ULONG MicroSeconds)
Definition: ntoskrnl.c:95
base of all file and directory entries
Definition: entries.h:82
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG ResponseCount
Definition: hdaudbus.h:56
#define HDAC_BIDIR_STREAM_OFFSET(num_input_streams, num_output_streams, index)
Definition: hdaudbus.h:26
#define CORB_SIZE_CAP_16_ENTRIES
#define RIRB_CONTROL_OVERRUN_INTR
KSEMAPHORE ResponseSemaphore
Definition: hdaudbus.h:57