ReactOS 0.4.15-dev-7953-g1f49173
fdo.cpp File Reference
#include "hdaudbus.h"
Include dependency graph for fdo.cpp:

Go to the source code of this file.

Functions

BOOLEAN NTAPI HDA_InterruptService (IN PKINTERRUPT Interrupt, IN PVOID ServiceContext)
 
VOID NTAPI HDA_DpcForIsr (_In_ PKDPC Dpc, _In_opt_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp, _In_opt_ PVOID Context)
 
NTSTATUS HDA_SendVerbs (IN PDEVICE_OBJECT DeviceObject, IN PHDA_CODEC_ENTRY Codec, IN PULONG Verbs, OUT PULONG Responses, IN ULONG Count)
 
NTSTATUS HDA_InitCodec (IN PDEVICE_OBJECT DeviceObject, IN ULONG codecAddress)
 
NTSTATUS NTAPI HDA_InitCorbRirbPos (IN PDEVICE_OBJECT DeviceObject)
 
NTSTATUS NTAPI HDA_ResetController (IN PDEVICE_OBJECT DeviceObject)
 
NTSTATUS NTAPI HDA_FDOStartDevice (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS NTAPI HDA_FDORemoveDevice (_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
 
NTSTATUS NTAPI HDA_FDOQueryBusRelations (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 

Function Documentation

◆ HDA_DpcForIsr()

VOID NTAPI HDA_DpcForIsr ( _In_ PKDPC  Dpc,
_In_opt_ PDEVICE_OBJECT  DeviceObject,
_Inout_ PIRP  Irp,
_In_opt_ PVOID  Context 
)

Definition at line 88 of file fdo.cpp.

93{
94 PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
95 ULONG Response, ResponseFlags, Cad;
96 USHORT WritePos;
97 PHDA_CODEC_ENTRY Codec;
98
99 /* get device extension */
100 DeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension);
101 ASSERT(DeviceExtension->IsFDO == TRUE);
102
103 WritePos = (READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_RIRB_WRITE_POS)) + 1) % DeviceExtension->RirbLength;
104
105 for (; DeviceExtension->RirbReadPos != WritePos; DeviceExtension->RirbReadPos = (DeviceExtension->RirbReadPos + 1) % DeviceExtension->RirbLength)
106 {
107 Response = DeviceExtension->RirbBase[DeviceExtension->RirbReadPos].response;
108 ResponseFlags = DeviceExtension->RirbBase[DeviceExtension->RirbReadPos].flags;
109 Cad = ResponseFlags & RESPONSE_FLAGS_CODEC_MASK;
110 DPRINT1("Response %lx ResponseFlags %lx Cad %lx\n", Response, ResponseFlags, Cad);
111
112 /* get codec */
113 Codec = DeviceExtension->Codecs[Cad];
114 if (Codec == NULL)
115 {
116 DPRINT1("hda: response for unknown codec %x Response %x ResponseFlags %x\n", Cad, Response, ResponseFlags);
117 continue;
118 }
119
120 /* check response count */
122 {
123 DPRINT1("too many responses for codec %x Response %x ResponseFlags %x\n", Cad, Response, ResponseFlags);
124 continue;
125 }
126
127 // FIXME handle unsolicited responses
128 ASSERT((ResponseFlags & RESPONSE_FLAGS_UNSOLICITED) == 0);
129
130 /* store response */
131 Codec->Responses[Codec->ResponseCount] = Response;
132 Codec->ResponseCount++;
134 }
135}
#define READ_REGISTER_USHORT(r)
Definition: arm.h:29
#define DPRINT1
Definition: precomp.h:8
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define MAX_CODEC_RESPONSES
Definition: driver.h:43
#define HDAC_RIRB_WRITE_POS
#define RESPONSE_FLAGS_UNSOLICITED
#define RESPONSE_FLAGS_CODEC_MASK
#define ASSERT(a)
Definition: mode.c:44
#define for
Definition: utility.h:88
unsigned short USHORT
Definition: pedump.c:61
LONG NTAPI KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, IN KPRIORITY Increment, IN LONG Adjustment, IN BOOLEAN Wait)
Definition: semphobj.c:54
Definition: hdaudbus.h:45
ULONG ResponseCount
Definition: hdaudbus.h:55
ULONG Responses[MAX_CODEC_RESPONSES]
Definition: hdaudbus.h:54
KSEMAPHORE ResponseSemaphore
Definition: hdaudbus.h:56
PRIRB_RESPONSE RirbBase
Definition: hdaudbus.h:75
PHDA_CODEC_ENTRY Codecs[HDA_MAX_CODECS+1]
Definition: hdaudbus.h:80
ULONG response
Definition: hdaudbus.h:33
ULONG flags
Definition: hdaudbus.h:34
Definition: ncftp.h:89
uint16_t * PUSHORT
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define IO_NO_INCREMENT
Definition: iotypes.h:598

◆ HDA_FDOQueryBusRelations()

NTSTATUS NTAPI HDA_FDOQueryBusRelations ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 761 of file fdo.cpp.

764{
765 ULONG DeviceCount, CodecIndex, AFGIndex;
766 PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
767 PHDA_CODEC_ENTRY Codec;
768 PDEVICE_RELATIONS DeviceRelations;
769
770 /* get device extension */
771 DeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
772 ASSERT(DeviceExtension->IsFDO == TRUE);
773
774 DeviceCount = 0;
775 for (CodecIndex = 0; CodecIndex < HDA_MAX_CODECS; CodecIndex++)
776 {
777 if (DeviceExtension->Codecs[CodecIndex] == NULL)
778 continue;
779
780 Codec = DeviceExtension->Codecs[CodecIndex];
782 }
783
784 if (DeviceCount == 0)
785 return STATUS_UNSUCCESSFUL;
786
787 DeviceRelations = (PDEVICE_RELATIONS)AllocateItem(NonPagedPool, sizeof(DEVICE_RELATIONS) + (DeviceCount > 1 ? sizeof(PDEVICE_OBJECT) * (DeviceCount - 1) : 0));
788 if (!DeviceRelations)
790
791 DeviceRelations->Count = 0;
792 for (CodecIndex = 0; CodecIndex < HDA_MAX_CODECS; CodecIndex++)
793 {
794 if (DeviceExtension->Codecs[CodecIndex] == NULL)
795 continue;
796
797 Codec = DeviceExtension->Codecs[CodecIndex];
799 for (AFGIndex = 0; AFGIndex < Codec->AudioGroupCount; AFGIndex++)
800 {
801 DeviceRelations->Objects[DeviceRelations->Count] = Codec->AudioGroups[AFGIndex]->ChildPDO;
802 ObReferenceObject(Codec->AudioGroups[AFGIndex]->ChildPDO);
803 DeviceRelations->Count++;
804 }
805 }
806
807 /* FIXME handle existing device relations */
808 ASSERT(Irp->IoStatus.Information == 0);
809
810 /* store device relations */
811 Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
812
813 /* done */
814 return STATUS_SUCCESS;
815}
_In_ PIRP Irp
Definition: csq.h:116
#define ULONG_PTR
Definition: config.h:101
#define HDA_MAX_AUDIO_GROUPS
Definition: driver.h:40
#define HDA_MAX_CODECS
Definition: driver.h:41
struct _DEVICE_OBJECT * PDEVICE_OBJECT
#define NonPagedPool
Definition: env_spec_w32.h:307
struct HDA_FDO_DEVICE_EXTENSION * PHDA_FDO_DEVICE_EXTENSION
PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes)
Definition: misc.c:29
ULONG DeviceCount
Definition: mpu401.c:26
#define STATUS_SUCCESS
Definition: shellext.h:65
PDEVICE_OBJECT ChildPDO
Definition: hdaudbus.h:39
PHDA_CODEC_AUDIO_GROUP AudioGroups[HDA_MAX_AUDIO_GROUPS]
Definition: hdaudbus.h:58
ULONG AudioGroupCount
Definition: hdaudbus.h:59
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2163
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
struct _DEVICE_RELATIONS * PDEVICE_RELATIONS
#define ObReferenceObject
Definition: obfuncs.h:204

Referenced by HDA_FdoPnp().

◆ HDA_FDORemoveDevice()

NTSTATUS NTAPI HDA_FDORemoveDevice ( _In_ PDEVICE_OBJECT  DeviceObject,
_Inout_ PIRP  Irp 
)

Definition at line 693 of file fdo.cpp.

696{
698 PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
699 ULONG CodecIndex, AFGIndex;
700 PHDA_CODEC_ENTRY CodecEntry;
701 PDEVICE_OBJECT ChildPDO;
702 PHDA_PDO_DEVICE_EXTENSION ChildDeviceExtension;
703
704 /* get device extension */
705 DeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension);
706 ASSERT(DeviceExtension->IsFDO == TRUE);
707
708 Irp->IoStatus.Status = STATUS_SUCCESS;
710 Status = IoCallDriver(DeviceExtension->LowerDevice, Irp);
711
712 IoDetachDevice(DeviceExtension->LowerDevice);
713
714 if (DeviceExtension->RegBase != NULL)
715 {
716 MmUnmapIoSpace(DeviceExtension->RegBase,
717 DeviceExtension->RegLength);
718 }
719 if (DeviceExtension->Interrupt != NULL)
720 {
721 IoDisconnectInterrupt(DeviceExtension->Interrupt);
722 }
723 if (DeviceExtension->CorbBase != NULL)
724 {
725 MmFreeContiguousMemory(DeviceExtension->CorbBase);
726 }
727
728 for (CodecIndex = 0; CodecIndex < HDA_MAX_CODECS; CodecIndex++)
729 {
730 CodecEntry = DeviceExtension->Codecs[CodecIndex];
731 if (CodecEntry == NULL)
732 {
733 continue;
734 }
735
737 for (AFGIndex = 0; AFGIndex < CodecEntry->AudioGroupCount; AFGIndex++)
738 {
739 ChildPDO = CodecEntry->AudioGroups[AFGIndex]->ChildPDO;
740 if (ChildPDO != NULL)
741 {
742 ChildDeviceExtension = static_cast<PHDA_PDO_DEVICE_EXTENSION>(ChildPDO->DeviceExtension);
743 ChildDeviceExtension->Codec = NULL;
744 ChildDeviceExtension->AudioGroup = NULL;
745 ChildDeviceExtension->FDO = NULL;
746 ChildDeviceExtension->ReportedMissing = TRUE;
747 HDA_PDORemoveDevice(ChildPDO);
748 }
749 FreeItem(CodecEntry->AudioGroups[AFGIndex]);
750 }
751 FreeItem(CodecEntry);
752 }
753
755
756 return Status;
757}
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI MmFreeContiguousMemory(IN PVOID BaseAddress)
Definition: contmem.c:653
Status
Definition: gdiplustypes.h:25
NTSTATUS HDA_PDORemoveDevice(_In_ PDEVICE_OBJECT DeviceObject)
Definition: pdo.cpp:11
VOID NTAPI MmUnmapIoSpace(IN PVOID BaseAddress, IN SIZE_T NumberOfBytes)
Definition: iosup.c:193
VOID FreeItem(IN PVOID Item)
Definition: misc.c:37
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
VOID NTAPI IoDetachDevice(IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:1296
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
#define IoCallDriver
Definition: irp.c:1225
VOID NTAPI IoDisconnectInterrupt(PKINTERRUPT InterruptObject)
Definition: irq.c:141
PDEVICE_OBJECT LowerDevice
Definition: hdaudbus.h:66
PKINTERRUPT Interrupt
Definition: hdaudbus.h:70
PHDA_CODEC_AUDIO_GROUP AudioGroup
Definition: hdaudbus.h:89
PHDA_CODEC_ENTRY Codec
Definition: hdaudbus.h:88
PDEVICE_OBJECT FDO
Definition: hdaudbus.h:90
PVOID DeviceExtension
Definition: env_spec_w32.h:418

Referenced by HDA_FdoPnp().

◆ HDA_FDOStartDevice()

NTSTATUS NTAPI HDA_FDOStartDevice ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 579 of file fdo.cpp.

582{
583 PIO_STACK_LOCATION IoStack;
585 PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
587 ULONG Index;
589
590 /* get device extension */
591 DeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
592 ASSERT(DeviceExtension->IsFDO == TRUE);
593
594 /* forward irp to lower device */
595 if (!IoForwardIrpSynchronously(DeviceExtension->LowerDevice, Irp))
596 {
597 ASSERT(FALSE);
599 }
600 Status = Irp->IoStatus.Status;
601 if (!NT_SUCCESS(Status))
602 {
603 // failed to start
604 DPRINT1("HDA_StartDevice Lower device failed to start %x\n", Status);
605 return Status;
606 }
607
608 /* get current irp stack location */
610
611 Resources = IoStack->Parameters.StartDevice.AllocatedResourcesTranslated;
612 for (Index = 0; Index < Resources->List[0].PartialResourceList.Count; Index++)
613 {
614 PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor = &Resources->List[0].PartialResourceList.PartialDescriptors[Index];
615
616 if (Descriptor->Type == CmResourceTypeMemory)
617 {
618 DeviceExtension->RegLength = Descriptor->u.Memory.Length;
619 DeviceExtension->RegBase = (PUCHAR)MmMapIoSpace(Descriptor->u.Memory.Start, Descriptor->u.Memory.Length, MmNonCached);
620 if (DeviceExtension->RegBase == NULL)
621 {
622 DPRINT1("[HDAB] Failed to map registers\n");
624 break;
625 }
626 }
627 else if (Descriptor->Type == CmResourceTypeInterrupt)
628 {
629 Status = IoConnectInterrupt(&DeviceExtension->Interrupt,
632 NULL,
633 Descriptor->u.Interrupt.Vector,
634 Descriptor->u.Interrupt.Level,
635 Descriptor->u.Interrupt.Level,
637 (Descriptor->ShareDisposition != CmResourceShareDeviceExclusive),
638 Descriptor->u.Interrupt.Affinity,
639 FALSE);
640 if (!NT_SUCCESS(Status))
641 {
642 DPRINT1("[HDAB] Failed to connect interrupt. Status=%lx\n", Status);
643 break;
644 }
645
646 }
647 }
648
649 if (NT_SUCCESS(Status))
650 {
651 // Get controller into valid state
653 if (!NT_SUCCESS(Status)) return Status;
654
655 // Setup CORB/RIRB/DMA POS
657 if (!NT_SUCCESS(Status)) return Status;
658
659
660 // Don't enable codec state change interrupts. We don't handle
661 // them, as we want to use the STATE_STATUS register to identify
662 // available codecs. We'd have to clear that register in the interrupt
663 // handler to 'ack' the codec change.
664 Value = READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_WAKE_ENABLE)) & ~HDAC_WAKE_ENABLE_MASK;
666
667 // Enable controller interrupts
669
671
673 if (!Value) {
674 DPRINT1("hda: bad codec status\n");
675 return STATUS_UNSUCCESSFUL;
676 }
678
679 // Create codecs
680 DPRINT1("Codecs %lx\n", Value);
681 for (Index = 0; Index < HDA_MAX_CODECS; Index++) {
682 if ((Value & (1 << Index)) != 0) {
684 }
685 }
686 }
687
688 return Status;
689}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define WRITE_REGISTER_USHORT(r, v)
Definition: arm.h:30
#define WRITE_REGISTER_ULONG(r, v)
Definition: arm.h:27
VOID NTAPI KeStallExecutionProcessor(IN ULONG MicroSeconds)
Definition: ntoskrnl.c:81
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI HDA_ResetController(IN PDEVICE_OBJECT DeviceObject)
Definition: fdo.cpp:469
NTSTATUS HDA_InitCodec(IN PDEVICE_OBJECT DeviceObject, IN ULONG codecAddress)
Definition: fdo.cpp:204
NTSTATUS NTAPI HDA_InitCorbRirbPos(IN PDEVICE_OBJECT DeviceObject)
Definition: fdo.cpp:322
#define HDAC_INTR_CONTROL
#define INTR_CONTROL_GLOBAL_ENABLE
#define INTR_CONTROL_CONTROLLER_ENABLE
#define HDAC_STATE_STATUS
#define HDAC_WAKE_ENABLE
KSERVICE_ROUTINE HDA_InterruptService
Definition: hdaudbus.h:118
#define CmResourceTypeMemory
Definition: hwresource.cpp:125
#define CmResourceTypeInterrupt
Definition: hwresource.cpp:124
PVOID NTAPI MmMapIoSpace(IN PHYSICAL_ADDRESS PhysicalAddress, IN SIZE_T NumberOfBytes, IN MEMORY_CACHING_TYPE CacheType)
Definition: iosup.c:47
#define CM_RESOURCE_INTERRUPT_LATCHED
Definition: cmtypes.h:144
BOOLEAN NTAPI IoForwardIrpSynchronously(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1625
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
enum _KINTERRUPT_MODE KINTERRUPT_MODE
struct _IO_STACK_LOCATION::@3978::@4015 StartDevice
union _IO_STACK_LOCATION::@1564 Parameters
uint32_t * PULONG
Definition: typedefs.h:59
unsigned char * PUCHAR
Definition: typedefs.h:53
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:342
@ CmResourceShareDeviceExclusive
Definition: cmtypes.h:241
@ MmNonCached
Definition: mmtypes.h:129

Referenced by HDA_FdoPnp().

◆ HDA_InitCodec()

NTSTATUS HDA_InitCodec ( IN PDEVICE_OBJECT  DeviceObject,
IN ULONG  codecAddress 
)

Definition at line 204 of file fdo.cpp.

207{
209 ULONG verbs[3];
210 PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
212 ULONG NodeId, GroupType;
214 PHDA_CODEC_AUDIO_GROUP AudioGroup;
215 PHDA_PDO_DEVICE_EXTENSION ChildDeviceExtension;
216
217 /* lets allocate the entry */
219 if (!Entry)
220 {
221 DPRINT1("hda: failed to allocate memory\n");
222 return STATUS_UNSUCCESSFUL;
223 }
224
225 /* init codec */
226 Entry->Addr = codecAddress;
227 KeInitializeSemaphore(&Entry->ResponseSemaphore, 0, MAX_CODEC_RESPONSES);
228
229 /* get device extension */
230 DeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
231
232 /* store codec */
233 DeviceExtension->Codecs[codecAddress] = Entry;
234
235 verbs[0] = MAKE_VERB(codecAddress, 0, VID_GET_PARAMETER, PID_VENDOR_ID);
236 verbs[1] = MAKE_VERB(codecAddress, 0, VID_GET_PARAMETER, PID_REVISION_ID);
237 verbs[2] = MAKE_VERB(codecAddress, 0, VID_GET_PARAMETER, PID_SUB_NODE_COUNT);
238
239 /* get basic info */
241 if (!NT_SUCCESS(Status))
242 {
244 DeviceExtension->Codecs[codecAddress] = NULL;
245 return Status;
246 }
247
248 /* store codec details */
249 Entry->Major = Response.major;
250 Entry->Minor = Response.minor;
251 Entry->ProductId = Response.device;
252 Entry->Revision = Response.revision;
253 Entry->Stepping = Response.stepping;
254 Entry->VendorId = Response.vendor;
255
256 DPRINT1("hda Codec %ld Vendor: %04lx Product: %04lx, Revision: %lu.%lu.%lu.%lu NodeStart %u NodeCount %u \n", codecAddress, Response.vendor,
257 Response.device, Response.major, Response.minor, Response.revision, Response.stepping, Response.start, Response.count);
258
259 for (NodeId = Response.start; NodeId < Response.start + Response.count; NodeId++) {
260
261 /* get function type */
262 verbs[0] = MAKE_VERB(codecAddress, NodeId, VID_GET_PARAMETER, PID_FUNCTION_GROUP_TYPE);
263
264 Status = HDA_SendVerbs(DeviceObject, Entry, verbs, &GroupType, 1);
265 DPRINT1("Status %x NodeId %u GroupType %x\n", Status, NodeId, GroupType);
266
267
268 if (NT_SUCCESS(Status) &&
270 {
271 if (Entry->AudioGroupCount >= HDA_MAX_AUDIO_GROUPS)
272 {
273 DPRINT1("Too many audio groups in node %u. Skipping.\n", NodeId);
274 break;
275 }
276
278 if (!AudioGroup)
279 {
280 DPRINT1("hda: insufficient memory\n");
282 }
283
284 /* init audio group */
285 AudioGroup->NodeId = NodeId;
287
288 // Found an Audio Function Group!
289 DPRINT1("NodeId %x found an audio function group!\n", NodeId);
290
292 if (!NT_SUCCESS(Status))
293 {
294 FreeItem(AudioGroup);
295 DPRINT1("hda failed to create device object %x\n", Status);
296 return Status;
297 }
298
299 /* init child pdo*/
300 ChildDeviceExtension = (PHDA_PDO_DEVICE_EXTENSION)AudioGroup->ChildPDO->DeviceExtension;
301 ChildDeviceExtension->IsFDO = FALSE;
302 ChildDeviceExtension->ReportedMissing = FALSE;
303 ChildDeviceExtension->Codec = Entry;
304 ChildDeviceExtension->AudioGroup = AudioGroup;
305 ChildDeviceExtension->FDO = DeviceObject;
306
307 /* setup flags */
308 AudioGroup->ChildPDO->Flags |= DO_POWER_PAGABLE;
309 AudioGroup->ChildPDO->Flags &= ~DO_DEVICE_INITIALIZING;
310
311 /* add audio group*/
312 Entry->AudioGroups[Entry->AudioGroupCount] = AudioGroup;
313 Entry->AudioGroupCount++;
314 }
315 }
316 return STATUS_SUCCESS;
317
318}
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
NTSTATUS HDA_SendVerbs(IN PDEVICE_OBJECT DeviceObject, IN PHDA_CODEC_ENTRY Codec, IN PULONG Verbs, OUT PULONG Responses, IN ULONG Count)
Definition: fdo.cpp:139
#define MAKE_VERB(cad, nid, vid, payload)
#define PID_VENDOR_ID
#define FUNCTION_GROUP_NODETYPE_AUDIO
#define VID_GET_PARAMETER
#define FUNCTION_GROUP_NODETYPE_MASK
#define PID_REVISION_ID
#define PID_SUB_NODE_COUNT
#define PID_FUNCTION_GROUP_TYPE
struct HDA_CODEC_AUDIO_GROUP * PHDA_CODEC_AUDIO_GROUP
struct HDA_CODEC_ENTRY * PHDA_CODEC_ENTRY
struct HDA_PDO_DEVICE_EXTENSION * PHDA_PDO_DEVICE_EXTENSION
#define FILE_AUTOGENERATED_DEVICE_NAME
Definition: iotypes.h:138
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
#define FILE_DEVICE_SOUND
Definition: winioctl.h:135
VOID NTAPI KeInitializeSemaphore(IN PKSEMAPHORE Semaphore, IN LONG Count, IN LONG Limit)
Definition: semphobj.c:22
base of all file and directory entries
Definition: entries.h:83
#define DO_POWER_PAGABLE

Referenced by HDA_FDOStartDevice().

◆ HDA_InitCorbRirbPos()

NTSTATUS NTAPI HDA_InitCorbRirbPos ( IN PDEVICE_OBJECT  DeviceObject)

Definition at line 322 of file fdo.cpp.

324{
325 PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
326 UCHAR corbSize, value, rirbSize;
327 PHYSICAL_ADDRESS HighestPhysicalAddress, CorbPhysicalAddress;
328 ULONG Index;
329 USHORT corbReadPointer, rirbWritePointer, interruptValue, corbControl, rirbControl;
330
331 /* get device extension */
332 DeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
333
334 // Determine and set size of CORB
335 corbSize = READ_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_CORB_SIZE);
336 if ((corbSize & CORB_SIZE_CAP_256_ENTRIES) != 0) {
337 DeviceExtension->CorbLength = 256;
338
339 value = READ_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_CORB_SIZE) & ~HDAC_CORB_SIZE_MASK;
341 }
342 else if (corbSize & CORB_SIZE_CAP_16_ENTRIES) {
343 DeviceExtension->CorbLength = 16;
344
345 value = READ_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_CORB_SIZE) & ~HDAC_CORB_SIZE_MASK;
347 }
348 else if (corbSize & CORB_SIZE_CAP_2_ENTRIES) {
349 DeviceExtension->CorbLength = 2;
350
351 value = READ_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_CORB_SIZE) & ~HDAC_CORB_SIZE_MASK;
353 }
354
355 // Determine and set size of RIRB
356 rirbSize = READ_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_RIRB_SIZE);
357 if (rirbSize & RIRB_SIZE_CAP_256_ENTRIES) {
358 DeviceExtension->RirbLength = 256;
359
360 value = READ_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_RIRB_SIZE) & ~HDAC_RIRB_SIZE_MASK;
362 }
363 else if (rirbSize & RIRB_SIZE_CAP_16_ENTRIES) {
364 DeviceExtension->RirbLength = 16;
365
366 value = READ_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_RIRB_SIZE) & ~HDAC_RIRB_SIZE_MASK;
368 }
369 else if (rirbSize & RIRB_SIZE_CAP_2_ENTRIES) {
370 DeviceExtension->RirbLength = 2;
371
372 value = READ_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_RIRB_SIZE) & ~HDAC_RIRB_SIZE_MASK;
374 }
375
376 /* init corb */
377 HighestPhysicalAddress.QuadPart = 0x00000000FFFFFFFF;
378 DeviceExtension->CorbBase = (PULONG)MmAllocateContiguousMemory(PAGE_SIZE * 3, HighestPhysicalAddress);
379 ASSERT(DeviceExtension->CorbBase != NULL);
380
381 // FIXME align rirb 128bytes
382 ASSERT(DeviceExtension->CorbLength == 256);
383 ASSERT(DeviceExtension->RirbLength == 256);
384
385 CorbPhysicalAddress = MmGetPhysicalAddress(DeviceExtension->CorbBase);
386 ASSERT(CorbPhysicalAddress.QuadPart != 0LL);
387
388 // Program CORB/RIRB for these locations
389 WRITE_REGISTER_ULONG((PULONG)(DeviceExtension->RegBase + HDAC_CORB_BASE_LOWER), CorbPhysicalAddress.LowPart);
390 WRITE_REGISTER_ULONG((PULONG)(DeviceExtension->RegBase + HDAC_CORB_BASE_UPPER), CorbPhysicalAddress.HighPart);
391
392 DeviceExtension->RirbBase = (PRIRB_RESPONSE)((ULONG_PTR)DeviceExtension->CorbBase + PAGE_SIZE);
393 CorbPhysicalAddress.QuadPart += PAGE_SIZE;
394 WRITE_REGISTER_ULONG((PULONG)(DeviceExtension->RegBase + HDAC_RIRB_BASE_LOWER), CorbPhysicalAddress.LowPart);
395 WRITE_REGISTER_ULONG((PULONG)(DeviceExtension->RegBase + HDAC_RIRB_BASE_UPPER), CorbPhysicalAddress.HighPart);
396
397 // Program DMA position update
398 DeviceExtension->StreamPositions = (PVOID)((ULONG_PTR)DeviceExtension->RirbBase + PAGE_SIZE);
399 CorbPhysicalAddress.QuadPart += PAGE_SIZE;
400 WRITE_REGISTER_ULONG((PULONG)(DeviceExtension->RegBase + HDAC_DMA_POSITION_BASE_LOWER), CorbPhysicalAddress.LowPart);
401 WRITE_REGISTER_ULONG((PULONG)(DeviceExtension->RegBase + HDAC_DMA_POSITION_BASE_UPPER), CorbPhysicalAddress.HighPart);
402
403 value = READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_CORB_WRITE_POS)) & ~HDAC_CORB_WRITE_POS_MASK;
405
406 // Reset CORB read pointer. Preserve bits marked as RsvdP.
407 // After setting the reset bit, we must wait for the hardware
408 // to acknowledge it, then manually unset it and wait for that
409 // to be acknowledged as well.
410 corbReadPointer = READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_CORB_READ_POS));
411
412 corbReadPointer |= CORB_READ_POS_RESET;
413 WRITE_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_CORB_READ_POS), corbReadPointer);
414
415 for (Index = 0; Index < 10; Index++) {
417 corbReadPointer = READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_CORB_READ_POS));
418 if ((corbReadPointer & CORB_READ_POS_RESET) != 0)
419 break;
420 }
421 if ((corbReadPointer & CORB_READ_POS_RESET) == 0) {
422 DPRINT1("hda: CORB read pointer reset not acknowledged\n");
423
424 // According to HDA spec v1.0a ch3.3.21, software must read the
425 // bit as 1 to verify that the reset completed. However, at least
426 // some nVidia HDA controllers do not update the bit after reset.
427 // Thus don't fail here on nVidia controllers.
428 //if (controller->pci_info.vendor_id != PCI_VENDOR_NVIDIA)
429 // return B_BUSY;
430 }
431
432 corbReadPointer &= ~CORB_READ_POS_RESET;
433 WRITE_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_CORB_READ_POS), corbReadPointer);
434 for (Index = 0; Index < 10; Index++) {
436 corbReadPointer = READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_CORB_READ_POS));
437 if ((corbReadPointer & CORB_READ_POS_RESET) == 0)
438 break;
439 }
440 if ((corbReadPointer & CORB_READ_POS_RESET) != 0) {
441 DPRINT1("hda: CORB read pointer reset failed\n");
442 return STATUS_UNSUCCESSFUL;
443 }
444
445 // Reset RIRB write pointer
446 rirbWritePointer = READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_RIRB_WRITE_POS)) & ~RIRB_WRITE_POS_RESET;
447 WRITE_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_RIRB_WRITE_POS), rirbWritePointer | RIRB_WRITE_POS_RESET);
448
449 // Generate interrupt for every response
450 interruptValue = READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_RESPONSE_INTR_COUNT)) & ~HDAC_RESPONSE_INTR_COUNT_MASK;
451 WRITE_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_RESPONSE_INTR_COUNT), interruptValue | 1);
452
453 // Setup cached read/write indices
454 DeviceExtension->RirbReadPos = 1;
455 DeviceExtension->CorbWritePos = 0;
456
457 // Gentlemen, start your engines...
458 corbControl = READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_CORB_CONTROL)) & ~HDAC_CORB_CONTROL_MASK;
460
461 rirbControl = READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_RIRB_CONTROL)) & ~HDAC_RIRB_CONTROL_MASK;
463
464 return STATUS_SUCCESS;
465}
PVOID NTAPI MmAllocateContiguousMemory(IN SIZE_T NumberOfBytes, IN PHYSICAL_ADDRESS HighestAcceptableAddress)
Definition: contmem.c:626
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define RIRB_WRITE_POS_RESET
#define CORB_SIZE_16_ENTRIES
#define CORB_SIZE_CAP_2_ENTRIES
#define CORB_SIZE_CAP_16_ENTRIES
#define RIRB_SIZE_2_ENTRIES
#define CORB_CONTROL_MEMORY_ERROR_INTR
#define HDAC_RESPONSE_INTR_COUNT
#define RIRB_SIZE_CAP_2_ENTRIES
#define HDAC_RIRB_SIZE
#define CORB_READ_POS_RESET
#define HDAC_RIRB_BASE_LOWER
#define RIRB_SIZE_256_ENTRIES
#define RIRB_SIZE_16_ENTRIES
#define HDAC_CORB_CONTROL
#define CORB_SIZE_256_ENTRIES
#define RIRB_SIZE_CAP_16_ENTRIES
#define RIRB_CONTROL_DMA_ENABLE
#define HDAC_CORB_READ_POS
#define RIRB_SIZE_CAP_256_ENTRIES
#define RIRB_CONTROL_OVERRUN_INTR
#define HDAC_RIRB_CONTROL
#define CORB_SIZE_CAP_256_ENTRIES
#define CORB_SIZE_2_ENTRIES
#define HDAC_DMA_POSITION_BASE_UPPER
#define HDAC_RIRB_BASE_UPPER
#define HDAC_DMA_POSITION_BASE_LOWER
#define HDAC_CORB_BASE_LOWER
#define CORB_CONTROL_RUN
#define HDAC_CORB_SIZE
#define HDAC_CORB_WRITE_POS
#define RIRB_CONTROL_RESPONSE_INTR
#define HDAC_CORB_BASE_UPPER
struct RIRB_RESPONSE * PRIRB_RESPONSE
PHYSICAL_ADDRESS NTAPI MmGetPhysicalAddress(IN PVOID Address)
Definition: stubs.c:685
#define LL
Definition: tui.h:167
void * PVOID
Definition: typedefs.h:50
uint32_t ULONG_PTR
Definition: typedefs.h:65
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG LowPart
Definition: typedefs.h:106
Definition: pdh_main.c:94
NTKERNELAPI VOID NTAPI WRITE_REGISTER_UCHAR(IN PUCHAR Register, IN UCHAR Value)
NTKERNELAPI UCHAR NTAPI READ_REGISTER_UCHAR(IN PUCHAR Register)
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by HDA_FDOStartDevice().

◆ HDA_InterruptService()

BOOLEAN NTAPI HDA_InterruptService ( IN PKINTERRUPT  Interrupt,
IN PVOID  ServiceContext 
)

Definition at line 13 of file fdo.cpp.

16{
18 PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
19 ULONG InterruptStatus;
20 UCHAR RirbStatus, CorbStatus;
21
22 /* get device extension */
24 DeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension);
25 ASSERT(DeviceExtension->IsFDO == TRUE);
26
27 // Check if this interrupt is ours
28 InterruptStatus = READ_REGISTER_ULONG((PULONG)(DeviceExtension->RegBase + HDAC_INTR_STATUS));
29
30 DPRINT("HDA_InterruptService %lx\n", InterruptStatus);
31 if ((InterruptStatus & INTR_STATUS_GLOBAL) == 0)
32 return FALSE;
33
34 // Controller or stream related?
35 if (InterruptStatus & INTR_STATUS_CONTROLLER) {
36 RirbStatus = READ_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_RIRB_STATUS);
37 CorbStatus = READ_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_CORB_STATUS);
38
39 // Check for incoming responses
40 if (RirbStatus) {
41 WRITE_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_RIRB_STATUS, RirbStatus);
42
43 if (DeviceExtension->RirbLength == 0)
44 {
45 /* HACK: spurious interrupt */
46 return FALSE;
47 }
48
49 if ((RirbStatus & RIRB_STATUS_RESPONSE) != 0) {
51 }
52
53 if ((RirbStatus & RIRB_STATUS_OVERRUN) != 0)
54 DPRINT1("hda: RIRB Overflow\n");
55 }
56
57 // Check for sending errors
58 if (CorbStatus) {
59 WRITE_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_CORB_STATUS, CorbStatus);
60
61 if ((CorbStatus & CORB_STATUS_MEMORY_ERROR) != 0)
62 DPRINT1("hda: CORB Memory Error!\n");
63 }
64 }
65#if 0
66 if ((intrStatus & INTR_STATUS_STREAM_MASK) != 0) {
67 for (uint32 index = 0; index < HDA_MAX_STREAMS; index++) {
68 if ((intrStatus & (1 << index)) != 0) {
69 if (controller->streams[index]) {
70 if (stream_handle_interrupt(controller,
71 controller->streams[index], index)) {
72 handled = B_INVOKE_SCHEDULER;
73 }
74 }
75 else {
76 dprintf("hda: Stream interrupt for unconfigured stream "
77 "%ld!\n", index);
78 }
79 }
80 }
81 }
82#endif
83 return TRUE;
84}
#define READ_REGISTER_ULONG(r)
Definition: arm.h:26
unsigned int uint32
Definition: types.h:32
#define HDA_MAX_STREAMS
Definition: driver.h:42
GLuint index
Definition: glext.h:6031
#define INTR_STATUS_STREAM_MASK
#define HDAC_CORB_STATUS
#define RIRB_STATUS_RESPONSE
#define INTR_STATUS_CONTROLLER
#define HDAC_INTR_STATUS
#define HDAC_RIRB_STATUS
#define INTR_STATUS_GLOBAL
#define RIRB_STATUS_OVERRUN
#define CORB_STATUS_MEMORY_ERROR
#define dprintf
Definition: regdump.c:33
#define DPRINT
Definition: sndvol32.h:71
FORCEINLINE VOID IoRequestDpc(_Inout_ PDEVICE_OBJECT DeviceObject, _In_opt_ PIRP Irp, _In_opt_ __drv_aliasesMem PVOID Context)
Definition: iofuncs.h:2750
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID ServiceContext
Definition: iofuncs.h:801

◆ HDA_ResetController()

NTSTATUS NTAPI HDA_ResetController ( IN PDEVICE_OBJECT  DeviceObject)

Definition at line 469 of file fdo.cpp.

471{
472 USHORT ValCapabilities;
473 ULONG Index;
474 PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
475 ULONG InputStreams, OutputStreams, BiDirStreams, Control;
476 UCHAR corbControl, rirbControl;
477
478 /* get device extension */
479 DeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
480
481 /* read caps */
482 ValCapabilities = READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_GLOBAL_CAP));
483
484 InputStreams = GLOBAL_CAP_INPUT_STREAMS(ValCapabilities);
485 OutputStreams = GLOBAL_CAP_OUTPUT_STREAMS(ValCapabilities);
486 BiDirStreams = GLOBAL_CAP_BIDIR_STREAMS(ValCapabilities);
487
488 DPRINT1("NumInputStreams %u\n", InputStreams);
489 DPRINT1("NumOutputStreams %u\n", OutputStreams);
490 DPRINT1("NumBiDirStreams %u\n", BiDirStreams);
491
492 /* stop all streams */
493 for (Index = 0; Index < InputStreams; Index++)
494 {
497 }
498
499 for (Index = 0; Index < OutputStreams; Index++) {
502 }
503
504 for (Index = 0; Index < BiDirStreams; Index++) {
505 WRITE_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_STREAM_CONTROL0 + HDAC_STREAM_BASE + HDAC_BIDIR_STREAM_OFFSET(InputStreams, OutputStreams, Index), 0);
506 WRITE_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_STREAM_STATUS + HDAC_STREAM_BASE + HDAC_BIDIR_STREAM_OFFSET(InputStreams, OutputStreams, Index), 0);
507 }
508
509 // stop DMA
510 Control = READ_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_CORB_CONTROL) & ~HDAC_CORB_CONTROL_MASK;
512
513 Control = READ_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_RIRB_CONTROL) & ~HDAC_RIRB_CONTROL_MASK;
515
516 for (int timeout = 0; timeout < 10; timeout++) {
518
519 corbControl = READ_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_CORB_CONTROL);
520 rirbControl = READ_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_RIRB_CONTROL);
521 if (corbControl == 0 && rirbControl == 0)
522 break;
523 }
524 if (corbControl != 0 || rirbControl != 0) {
525 DPRINT1("hda: unable to stop dma\n");
526 return STATUS_UNSUCCESSFUL;
527 }
528
529 // reset DMA position buffer
532
533 // Set reset bit - it must be asserted for at least 100us
536
537 for (int timeout = 0; timeout < 10; timeout++) {
539
541 if ((Control & GLOBAL_CONTROL_RESET) == 0)
542 break;
543 }
544 if ((Control & GLOBAL_CONTROL_RESET) != 0)
545 {
546 DPRINT1("hda: unable to reset controller\n");
547 return STATUS_UNSUCCESSFUL;
548 }
549
550 // Unset reset bit
553
554 for (int timeout = 0; timeout < 10; timeout++) {
556
558 if ((Control & GLOBAL_CONTROL_RESET) != 0)
559 break;
560 }
561 if ((Control & GLOBAL_CONTROL_RESET) == 0) {
562 DPRINT1("hda: unable to exit reset\n");
563 return STATUS_UNSUCCESSFUL;
564 }
565
566 // Wait for codecs to finish their own reset (apparently needs more
567 // time than documented in the specs)
569
570 // Enable unsolicited responses
573
574 return STATUS_SUCCESS;
575}
#define HDAC_STREAM_STATUS
#define GLOBAL_CAP_INPUT_STREAMS(cap)
#define GLOBAL_CAP_OUTPUT_STREAMS(cap)
#define GLOBAL_CONTROL_UNSOLICITED
#define HDAC_GLOBAL_CAP
#define GLOBAL_CONTROL_RESET
#define HDAC_GLOBAL_CONTROL
#define HDAC_STREAM_BASE
#define HDAC_STREAM_CONTROL0
#define GLOBAL_CAP_BIDIR_STREAMS(cap)
#define HDAC_INPUT_STREAM_OFFSET(index)
Definition: hdaudbus.h:22
#define HDAC_OUTPUT_STREAM_OFFSET(num_input_streams, index)
Definition: hdaudbus.h:24
#define HDAC_BIDIR_STREAM_OFFSET(num_input_streams, num_output_streams, index)
Definition: hdaudbus.h:26
Definition: dhcpd.h:245
_In_ WDF_WMI_PROVIDER_CONTROL Control
Definition: wdfwmi.h:166

Referenced by HDA_FDOStartDevice().

◆ HDA_SendVerbs()

NTSTATUS HDA_SendVerbs ( IN PDEVICE_OBJECT  DeviceObject,
IN PHDA_CODEC_ENTRY  Codec,
IN PULONG  Verbs,
OUT PULONG  Responses,
IN ULONG  Count 
)

Definition at line 139 of file fdo.cpp.

145{
146 PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
147 ULONG Sent = 0, ReadPosition, WritePosition, Queued;
148
149 /* get device extension */
150 DeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
151 ASSERT(DeviceExtension->IsFDO);
152
153 /* reset response count */
154 Codec->ResponseCount = 0;
155
156 while (Sent < Count) {
157 ReadPosition = READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_CORB_READ_POS));
158
159 Queued = 0;
160
161 while (Sent < Count) {
162 WritePosition = (DeviceExtension->CorbWritePos + 1) % DeviceExtension->CorbLength;
163
164 if (WritePosition == ReadPosition) {
165 // There is no space left in the ring buffer; execute the
166 // queued commands and wait until
167 break;
168 }
169
170 DeviceExtension->CorbBase[WritePosition] = Verbs[Sent++];
171 DeviceExtension->CorbWritePos = WritePosition;
172 Queued++;
173 }
174
175 WRITE_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_CORB_WRITE_POS), DeviceExtension->CorbWritePos);
176 }
177
178 while (Queued--)
179 {
181 Timeout.QuadPart = -1000LL * 10000; // 1 sec
182
183 NTSTATUS waitStatus = KeWaitForSingleObject(&Codec->ResponseSemaphore,
184 Executive,
186 FALSE,
187 &Timeout);
188
189 if (waitStatus == STATUS_TIMEOUT)
190 {
191 DPRINT1("HDA_SendVerbs: timeout! Queued: %u\n", Queued);
193 }
194 }
195
196 if (Responses != NULL) {
197 memcpy(Responses, Codec->Responses, Codec->ResponseCount * sizeof(ULONG));
198 }
199
200 return STATUS_SUCCESS;
201}
UINT Sent
Definition: arping.c:39
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
if(dx< 0)
Definition: linetemp.h:194
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define KernelMode
Definition: asm.h:34
int Count
Definition: noreturn.cpp:7
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
static ULONG Timeout
Definition: ping.c:61
@ Executive
Definition: ketypes.h:415

Referenced by HDA_InitCodec(), and HDA_TransferCodecVerbs().