mirror of
https://github.com/reactos/reactos.git
synced 2024-09-10 21:04:26 +00:00
262 lines
6.9 KiB
C++
262 lines
6.9 KiB
C++
/*
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: ReactOS Kernel Streaming
|
|
* FILE: drivers/wdm/audio/hdaudbus/hdaudbus.cpp
|
|
* PURPOSE: HDA Driver Entry
|
|
* PROGRAMMER: Johannes Anderwald
|
|
*/
|
|
#include "hdaudbus.h"
|
|
|
|
|
|
PVOID
|
|
AllocateItem(
|
|
IN POOL_TYPE PoolType,
|
|
IN SIZE_T NumberOfBytes)
|
|
{
|
|
PVOID Item = ExAllocatePoolWithTag(PoolType, NumberOfBytes, TAG_HDA);
|
|
if (!Item)
|
|
return Item;
|
|
|
|
RtlZeroMemory(Item, NumberOfBytes);
|
|
return Item;
|
|
}
|
|
|
|
VOID
|
|
FreeItem(
|
|
IN PVOID Item)
|
|
{
|
|
ExFreePool(Item);
|
|
}
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
HDA_SyncForwardIrpCompletionRoutine(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp,
|
|
IN PVOID Context)
|
|
{
|
|
if (Irp->PendingReturned)
|
|
{
|
|
KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE);
|
|
}
|
|
return STATUS_MORE_PROCESSING_REQUIRED;
|
|
}
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
HDA_SyncForwardIrp(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp)
|
|
{
|
|
KEVENT Event;
|
|
NTSTATUS Status;
|
|
|
|
/* Initialize event */
|
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
|
|
|
/* Copy irp stack location */
|
|
IoCopyCurrentIrpStackLocationToNext(Irp);
|
|
|
|
/* Set completion routine */
|
|
IoSetCompletionRoutine(Irp,
|
|
HDA_SyncForwardIrpCompletionRoutine,
|
|
&Event,
|
|
TRUE,
|
|
TRUE,
|
|
TRUE);
|
|
|
|
/* Call driver */
|
|
Status = IoCallDriver(DeviceObject, Irp);
|
|
|
|
/* Check if pending */
|
|
if (Status == STATUS_PENDING)
|
|
{
|
|
/* Wait for the request to finish */
|
|
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
|
|
|
/* Copy status code */
|
|
Status = Irp->IoStatus.Status;
|
|
}
|
|
|
|
/* Done */
|
|
return Status;
|
|
}
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
HDA_Pnp(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp)
|
|
{
|
|
NTSTATUS Status = STATUS_NOT_SUPPORTED;
|
|
PIO_STACK_LOCATION IoStack;
|
|
PDEVICE_RELATIONS DeviceRelation;
|
|
PHDA_FDO_DEVICE_EXTENSION FDODeviceExtension;
|
|
//PHDA_PDO_DEVICE_EXTENSION ChildDeviceExtension;
|
|
|
|
FDODeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
|
//ChildDeviceExtension = (PHDA_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
|
|
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
|
if (FDODeviceExtension->IsFDO)
|
|
{
|
|
if (IoStack->MinorFunction == IRP_MN_START_DEVICE)
|
|
{
|
|
Status = HDA_FDOStartDevice(DeviceObject, Irp);
|
|
}
|
|
else if (IoStack->MinorFunction == IRP_MN_QUERY_DEVICE_RELATIONS)
|
|
{
|
|
/* handle bus device relations */
|
|
if (IoStack->Parameters.QueryDeviceRelations.Type == BusRelations)
|
|
{
|
|
Status = HDA_FDOQueryBusRelations(DeviceObject, Irp);
|
|
}
|
|
else
|
|
{
|
|
Status = Irp->IoStatus.Status;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* get default status */
|
|
Status = Irp->IoStatus.Status;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (IoStack->MinorFunction == IRP_MN_START_DEVICE)
|
|
{
|
|
/* no op for pdo */
|
|
Status = STATUS_SUCCESS;
|
|
}
|
|
else if (IoStack->MinorFunction == IRP_MN_QUERY_BUS_INFORMATION)
|
|
{
|
|
/* query bus information */
|
|
Status = HDA_PDOQueryBusInformation(Irp);
|
|
}
|
|
else if (IoStack->MinorFunction == IRP_MN_QUERY_PNP_DEVICE_STATE)
|
|
{
|
|
/* query pnp state */
|
|
Status = HDA_PDOQueryBusDevicePnpState(Irp);
|
|
}
|
|
else if (IoStack->MinorFunction == IRP_MN_QUERY_DEVICE_RELATIONS)
|
|
{
|
|
if (IoStack->Parameters.QueryDeviceRelations.Type == TargetDeviceRelation)
|
|
{
|
|
/* handle target device relations */
|
|
ASSERT(IoStack->Parameters.QueryDeviceRelations.Type == TargetDeviceRelation);
|
|
ASSERT(Irp->IoStatus.Information == 0);
|
|
|
|
/* allocate device relation */
|
|
DeviceRelation = (PDEVICE_RELATIONS)AllocateItem(PagedPool, sizeof(DEVICE_RELATIONS));
|
|
if (DeviceRelation)
|
|
{
|
|
DeviceRelation->Count = 1;
|
|
DeviceRelation->Objects[0] = DeviceObject;
|
|
|
|
/* reference self */
|
|
ObReferenceObject(DeviceObject);
|
|
|
|
/* store result */
|
|
Irp->IoStatus.Information = (ULONG_PTR)DeviceRelation;
|
|
|
|
/* done */
|
|
Status = STATUS_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
/* no memory */
|
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
}
|
|
}
|
|
else if (IoStack->MinorFunction == IRP_MN_QUERY_CAPABILITIES)
|
|
{
|
|
/* query capabilities */
|
|
Status = HDA_PDOQueryBusDeviceCapabilities(Irp);
|
|
}
|
|
else if (IoStack->MinorFunction == IRP_MN_QUERY_RESOURCE_REQUIREMENTS)
|
|
{
|
|
/* no op */
|
|
Status = STATUS_SUCCESS;
|
|
}
|
|
else if (IoStack->MinorFunction == IRP_MN_QUERY_RESOURCES)
|
|
{
|
|
/* no op */
|
|
Status = STATUS_SUCCESS;
|
|
}
|
|
else if (IoStack->MinorFunction == IRP_MN_QUERY_ID)
|
|
{
|
|
Status = HDA_PDOQueryId(DeviceObject, Irp);
|
|
}
|
|
else if (IoStack->MinorFunction == IRP_MN_QUERY_DEVICE_TEXT)
|
|
{
|
|
Status = HDA_PDOHandleQueryDeviceText(Irp);
|
|
}
|
|
else if (IoStack->MinorFunction == IRP_MN_QUERY_INTERFACE)
|
|
{
|
|
Status = HDA_PDOHandleQueryInterface(DeviceObject, Irp);
|
|
}
|
|
else
|
|
{
|
|
/* get default status */
|
|
Status = Irp->IoStatus.Status;
|
|
}
|
|
}
|
|
|
|
Irp->IoStatus.Status = Status;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
//PDRIVER_ADD_DEVICE HDA_AddDevice;
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
HDA_AddDevice(
|
|
IN PDRIVER_OBJECT DriverObject,
|
|
IN PDEVICE_OBJECT PhysicalDeviceObject)
|
|
{
|
|
PDEVICE_OBJECT DeviceObject;
|
|
PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
|
|
NTSTATUS Status;
|
|
|
|
/* create device object */
|
|
Status = IoCreateDevice(DriverObject, sizeof(HDA_FDO_DEVICE_EXTENSION), NULL, FILE_DEVICE_BUS_EXTENDER, 0, FALSE, &DeviceObject);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
/* failed */
|
|
return Status;
|
|
}
|
|
|
|
/* get device extension*/
|
|
DeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
|
|
|
/* init device extension*/
|
|
DeviceExtension->IsFDO = TRUE;
|
|
DeviceExtension->LowerDevice = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
|
|
RtlZeroMemory(DeviceExtension->Codecs, sizeof(PHDA_CODEC_ENTRY) * (HDA_MAX_CODECS + 1));
|
|
|
|
/* set device flags */
|
|
DeviceObject->Flags |= DO_POWER_PAGABLE;
|
|
|
|
return Status;
|
|
}
|
|
extern "C"
|
|
{
|
|
NTSTATUS
|
|
NTAPI
|
|
DriverEntry(
|
|
IN PDRIVER_OBJECT DriverObject,
|
|
IN PUNICODE_STRING RegistryPathName)
|
|
{
|
|
DriverObject->DriverExtension->AddDevice = HDA_AddDevice;
|
|
DriverObject->MajorFunction[IRP_MJ_PNP] = HDA_Pnp;
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
} |