From 124bf05832147c9964c4693401ac5fd51d0537c7 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Fri, 2 Jan 2009 15:05:57 +0000 Subject: [PATCH] - Store PhysicalDeviceObject in device extension - initialize ISubdevice list - improve PcRegisterSubdevice - implement IDmaChannelSlave_fnAllocateBuffer, IDmaChannelSlave_fnFreeBuffer - partly implement IPortFilterWaveCyclic interface - add IClsVersion interface to IPortDMus, IPortTopology, IPortWavePci - check for IPinCount, IPowerNotify interface during IPortWaveCyclic initialization - implement IPortWaveCyclic_fnNewRegistryKey - first hack version of creating IPortWaveCyclic_fnNewSlaveDmaChannel - implement ISubdevice interface for IPortWaveCyclic svn path=/trunk/; revision=38507 --- .../wdm/audio/backpln/portcls/adapter.c | 78 ++++- .../wdm/audio/backpln/portcls/dma_slave.c | 77 ++++- .../audio/backpln/portcls/filter_wavecyclic.c | 277 +++++++++++++++++ .../wdm/audio/backpln/portcls/port_dmus.c | 5 + .../wdm/audio/backpln/portcls/port_topology.c | 26 ++ .../audio/backpln/portcls/port_wavecyclic.c | 293 +++++++++++++++++- .../wdm/audio/backpln/portcls/port_wavepci.c | 4 + .../wdm/audio/backpln/portcls/portcls.rbuild | 1 + .../wdm/audio/backpln/portcls/private.h | 24 ++ .../wdm/audio/backpln/portcls/version.c | 2 +- 10 files changed, 765 insertions(+), 22 deletions(-) create mode 100644 reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c diff --git a/reactos/drivers/wdm/audio/backpln/portcls/adapter.c b/reactos/drivers/wdm/audio/backpln/portcls/adapter.c index ecca86c182c..e0b1686dc48 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/adapter.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/adapter.c @@ -10,7 +10,11 @@ */ #include "private.h" +#include #include + +const GUID IID_ISubdevice; + /* This is called from DriverEntry so that PortCls can take care of some IRPs and map some others to the main KS driver. In most cases this will @@ -162,7 +166,9 @@ PcAddAdapterDevice( /* Initialize */ RtlZeroMemory(portcls_ext, sizeof(PCExtension)); + portcls_ext->PhysicalDeviceObject = PhysicalDeviceObject; portcls_ext->StartDevice = StartDevice; + InitializeListHead(&portcls_ext->SubDeviceList); status = KsAllocateDeviceHeader(&portcls_ext->KsDeviceHeader, 0, NULL); if (!NT_SUCCESS(status)) @@ -182,9 +188,44 @@ PciDriverDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { + NTSTATUS Status; + + ISubdevice * SubDevice; + PCExtension* DeviceExt; + SUBDEVICE_ENTRY * Entry; + KSDISPATCH_TABLE DispatchTable; + DPRINT1("PortClsSysControl called\n"); - /* TODO */ + SubDevice = (ISubdevice*)Irp->Tail.Overlay.DriverContext[3]; + DeviceExt = (PCExtension*)DeviceObject->DeviceExtension; + + if (!SubDevice || !DeviceExt) + { + return STATUS_UNSUCCESSFUL; + } + + Entry = ExAllocatePoolWithTag(NonPagedPool, sizeof(SUBDEVICE_ENTRY), TAG_PORTCLASS); + if (!Entry) + return STATUS_INSUFFICIENT_RESOURCES; + + /* initialize DispatchTable */ + RtlZeroMemory(&DispatchTable, sizeof(KSDISPATCH_TABLE)); + /* FIXME + * initialize DispatchTable pointer + * which call in turn ISubDevice + */ + + + Status = KsAllocateObjectHeader(&Entry->ObjectHeader, 1, NULL, Irp, &DispatchTable); + if (!NT_SUCCESS(Status)) + { + ExFreePoolWithTag(Entry, TAG_PORTCLASS); + return Status; + } + + + InsertTailList(&DeviceExt->SubDeviceList, &Entry->Entry); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; @@ -201,6 +242,10 @@ PcRegisterSubdevice( { PCExtension* DeviceExt; NTSTATUS Status; + ISubdevice *SubDevice; + UNICODE_STRING ReferenceString; + UNICODE_STRING SymbolicLinkName; + if (!DeviceObject || !Name || !Unknown) return STATUS_INVALID_PARAMETER; @@ -209,8 +254,35 @@ PcRegisterSubdevice( if (!DeviceExt) return STATUS_UNSUCCESSFUL; - Status = KsAddObjectCreateItemToDeviceHeader(DeviceExt->KsDeviceHeader, PciDriverDispatch, (PVOID)Unknown, Name, NULL); + Status = Unknown->lpVtbl->QueryInterface(Unknown, &IID_ISubdevice, (LPVOID)&SubDevice); + if (!NT_SUCCESS(Status)) + { + /* the provided port driver doesnt support ISubdevice */ + return STATUS_INVALID_PARAMETER; + } + + Status = KsAddObjectCreateItemToDeviceHeader(DeviceExt->KsDeviceHeader, PciDriverDispatch, (PVOID)SubDevice, Name, NULL); + if (!NT_SUCCESS(Status)) + { + /* failed to attach */ + SubDevice->lpVtbl->Release(SubDevice); + return Status; + } + + /* FIXME retrieve guid from subdescriptor */ + + RtlInitUnicodeString(&ReferenceString, Name); + /* register device interface */ + Status = IoRegisterDeviceInterface(DeviceExt->PhysicalDeviceObject, + &GUID_DEVCLASS_SOUND, //FIXME + &ReferenceString, + &SymbolicLinkName); + if (NT_SUCCESS(Status)) + { + Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); + RtlFreeUnicodeString(&SymbolicLinkName); + } - return STATUS_UNSUCCESSFUL; + return Status; } diff --git a/reactos/drivers/wdm/audio/backpln/portcls/dma_slave.c b/reactos/drivers/wdm/audio/backpln/portcls/dma_slave.c index 2fbce7a8a71..c785262c1d3 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/dma_slave.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/dma_slave.c @@ -7,8 +7,13 @@ typedef struct LONG ref; + ULONG MaxMapRegisters; + ULONG AllocatedBufferSize; ULONG BufferSize; + PDMA_ADAPTER pAdapter; PHYSICAL_ADDRESS Address; + PVOID Buffer; + PMDL Mdl; }IDmaChannelSlaveImpl; @@ -54,6 +59,7 @@ IDmaChannelSlave_fnRelease( if (This->ref == 0) { + This->pAdapter->DmaOperations->PutDmaAdapter(This->pAdapter); ExFreePoolWithTag(This, TAG_PORTCLASS); return 0; } @@ -78,12 +84,26 @@ IDmaChannelSlave_fnAllocateBuffer( DPRINT("IDmaChannelSlave_AllocateBuffer: This %p BufferSize %u\n", This, BufferSize); /* Did the caller already allocate a buffer ?*/ - if (This->BufferSize) return STATUS_UNSUCCESSFUL; + if (This->Buffer) + { + DPRINT1("IDmaChannelSlave_AllocateBuffer free common buffer first \n"); + return STATUS_UNSUCCESSFUL; + } - /* FIXME */ - //This->BufferSize = BufferSize; + This->Buffer = This->pAdapter->DmaOperations->AllocateCommonBuffer(This->pAdapter, BufferSize, &This->Address, TRUE); + if (!This->Buffer) + { + DPRINT1("IDmaChannelSlave_AllocateBuffer fAllocateCommonBuffer failed \n"); + return STATUS_UNSUCCESSFUL; + } - return STATUS_UNSUCCESSFUL; + This->Mdl = IoAllocateMdl(This->Buffer, BufferSize, FALSE, FALSE, NULL); + if (This->Mdl) + MmBuildMdlForNonPagedPool(This->Mdl); + + This->BufferSize = BufferSize; + This->AllocatedBufferSize = BufferSize; + return STATUS_SUCCESS; } ULONG @@ -94,7 +114,7 @@ IDmaChannelSlave_fnAllocatedBufferSize( IDmaChannelSlaveImpl * This = (IDmaChannelSlaveImpl*)iface; DPRINT("IDmaChannelSlave_AllocatedBufferSize: This %p BufferSize %u\n", This, This->BufferSize); - return This->BufferSize; + return This->AllocatedBufferSize; } VOID @@ -133,6 +153,16 @@ IDmaChannelSlave_fnFreeBuffer( IDmaChannelSlaveImpl * This = (IDmaChannelSlaveImpl*)iface; DPRINT("IDmaChannelSlave_FreeBuffer: This %p\n", This); + + if (!This->Buffer) + { + DPRINT1("IDmaChannelSlave_FreeBuffer allocate common buffer first \n"); + return; + } + + This->pAdapter->DmaOperations->FreeCommonBuffer(This->pAdapter, This->AllocatedBufferSize, This->Address, This->Buffer, TRUE); + This->Buffer = NULL; + This->AllocatedBufferSize = 0; } PADAPTER_OBJECT @@ -143,7 +173,7 @@ IDmaChannelSlave_fnGetAdapterObject( IDmaChannelSlaveImpl * This = (IDmaChannelSlaveImpl*)iface; DPRINT("IDmaChannelSlave_GetAdapterObject: This %p\n", This); - return NULL; + return (PADAPTER_OBJECT)This->pAdapter; } ULONG @@ -177,6 +207,7 @@ IDmaChannelSlave_fnSetBufferSize( IDmaChannelSlaveImpl * This = (IDmaChannelSlaveImpl*)iface; DPRINT("IDmaChannelSlave_SetBufferSize: This %p\n", This); + This->BufferSize = BufferSize; } @@ -185,7 +216,9 @@ NTAPI IDmaChannelSlave_fnBufferSize( IN IDmaChannelSlave * iface) { - return 0; + IDmaChannelSlaveImpl * This = (IDmaChannelSlaveImpl*)iface; + + return This->BufferSize; } @@ -197,7 +230,7 @@ IDmaChannelSlave_fnSystemAddress( IDmaChannelSlaveImpl * This = (IDmaChannelSlaveImpl*)iface; DPRINT("IDmaChannelSlave_SystemAddress: This %p\n", This); - return NULL; + return This->Buffer; } ULONG @@ -219,6 +252,7 @@ IDmaChannelSlave_fnReadCounter( IDmaChannelSlaveImpl * This = (IDmaChannelSlaveImpl*)iface; DPRINT("IDmaChannelSlave_ReadCounter: This %p\n", This); + return 0; } @@ -285,3 +319,30 @@ IDmaChannelSlaveVtbl vt_IDmaChannelSlaveVtbl = IDmaChannelSlave_fnWaitForTC }; + +NTSTATUS NewDmaChannelSlave( + IN PDEVICE_DESCRIPTION DeviceDesc, + IN PDMA_ADAPTER Adapter, + IN ULONG MapRegisters, + OUT PDMACHANNELSLAVE* DmaChannel) +{ + IDmaChannelSlaveImpl * This; + + This = ExAllocatePoolWithTag(NonPagedPool, sizeof(IDmaChannelSlaveImpl), TAG_PORTCLASS); + if (!This) + { + Adapter->DmaOperations->PutDmaAdapter(Adapter); + return STATUS_INSUFFICIENT_RESOURCES; + } + + RtlZeroMemory(This, sizeof(IDmaChannelSlaveImpl)); + This->ref = 1; + This->lpVtbl = &vt_IDmaChannelSlaveVtbl; + This->pAdapter = Adapter; + This->MaxMapRegisters = MapRegisters; + *DmaChannel = (PVOID)(&This->lpVtbl); + + return STATUS_SUCCESS; + +} + diff --git a/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c b/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c new file mode 100644 index 00000000000..3e9b09ceca7 --- /dev/null +++ b/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c @@ -0,0 +1,277 @@ +#include "private.h" + +typedef struct +{ + IPortFilterWaveCyclicVtbl *lpVtbl; + + LONG ref; + +}IPortFilterWaveCyclicImpl; + +/* + * @implemented + */ +NTSTATUS +NTAPI +IPortFilterWaveCyclic_fnQueryInterface( + IPortFilterWaveCyclic* iface, + IN REFIID refiid, + OUT PVOID* Output) +{ + IPortFilterWaveCyclicImpl * This = (IPortFilterWaveCyclicImpl*)iface; + + if (IsEqualGUIDAligned(refiid, &IID_IIrpTarget) || + //IsEqualGUIDAligned(refiid, &IID_IPortFilterWaveCyclic) || + IsEqualGUIDAligned(refiid, &IID_IUnknown)) + { + *Output = &This->lpVtbl; + InterlockedIncrement(&This->ref); + return STATUS_SUCCESS; + } + + return STATUS_UNSUCCESSFUL; +} + +/* + * @implemented + */ +ULONG +NTAPI +IPortFilterWaveCyclic_fnAddRef( + IPortFilterWaveCyclic* iface) +{ + IPortFilterWaveCyclicImpl * This = (IPortFilterWaveCyclicImpl*)iface; + + return InterlockedIncrement(&This->ref); +} + +/* + * @implemented + */ +ULONG +NTAPI +IPortFilterWaveCyclic_fnRelease( + IPortFilterWaveCyclic* iface) +{ + IPortFilterWaveCyclicImpl * This = (IPortFilterWaveCyclicImpl*)iface; + + InterlockedDecrement(&This->ref); + + if (This->ref == 0) + { + ExFreePoolWithTag(This, TAG_PORTCLASS); + return 0; + } + return This->ref; +} + +/* + * @unimplemented + */ +NTSTATUS +NTAPI +IPortFilterWaveCyclic_fnNewIrpTarget( + IN IPortFilterWaveCyclic* iface, + OUT struct IIrpTarget **OutTarget, + IN WCHAR * Name, + IN PUNKNOWN Unknown, + IN POOL_TYPE PoolType, + IN PDEVICE_OBJECT * DeviceObject, + IN PIRP Irp, + IN KSOBJECT_CREATE *CreateObject) +{ + + return STATUS_UNSUCCESSFUL; +} + +/* + * @unimplemented + */ +NTSTATUS +NTAPI +IPortFilterWaveCyclic_fnDeviceIoControl( + IN IPortFilterWaveCyclic* iface, + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + + return STATUS_UNSUCCESSFUL; +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +IPortFilterWaveCyclic_fnRead( + IN IPortFilterWaveCyclic* iface, + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +IPortFilterWaveCyclic_fnWrite( + IN IPortFilterWaveCyclic* iface, + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +IPortFilterWaveCyclic_fnFlush( + IN IPortFilterWaveCyclic* iface, + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +/* + * @unimplemented + */ +NTSTATUS +NTAPI +IPortFilterWaveCyclic_fnClose( + IN IPortFilterWaveCyclic* iface, + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + + return STATUS_UNSUCCESSFUL; +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +IPortFilterWaveCyclic_fnQuerySecurity( + IN IPortFilterWaveCyclic* iface, + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +IPortFilterWaveCyclic_fnSetSecurity( + IN IPortFilterWaveCyclic* iface, + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +IPortFilterWaveCyclic_fnFastDeviceIoControl( + IN IPortFilterWaveCyclic* iface, + IN PFILE_OBJECT FileObject, + IN BOOLEAN Wait, + IN PVOID InputBuffer, + IN ULONG InputBufferLength, + OUT PVOID OutputBuffer, + IN ULONG OutputBufferLength, + IN ULONG IoControlCode, + OUT PIO_STATUS_BLOCK StatusBlock, + IN PDEVICE_OBJECT DeviceObject) +{ + + return STATUS_SUCCESS; +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +IPortFilterWaveCyclic_fnFastRead( + IN IPortFilterWaveCyclic* iface, + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN BOOLEAN Wait, + IN ULONG LockKey, + IN PVOID Buffer, + OUT PIO_STATUS_BLOCK StatusBlock, + IN PDEVICE_OBJECT DeviceObject) +{ + return STATUS_SUCCESS; +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +IPortFilterWaveCyclic_fnFastWrite( + IN IPortFilterWaveCyclic* iface, + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN BOOLEAN Wait, + IN ULONG LockKey, + IN PVOID Buffer, + OUT PIO_STATUS_BLOCK StatusBlock, + IN PDEVICE_OBJECT DeviceObject) +{ + return STATUS_SUCCESS; +} + +static IPortFilterWaveCyclicVtbl vt_IPortFilterWaveCyclic = +{ + IPortFilterWaveCyclic_fnQueryInterface, + IPortFilterWaveCyclic_fnAddRef, + IPortFilterWaveCyclic_fnRelease, + IPortFilterWaveCyclic_fnNewIrpTarget, + IPortFilterWaveCyclic_fnDeviceIoControl, + IPortFilterWaveCyclic_fnRead, + IPortFilterWaveCyclic_fnWrite, + IPortFilterWaveCyclic_fnFlush, + IPortFilterWaveCyclic_fnClose, + IPortFilterWaveCyclic_fnQuerySecurity, + IPortFilterWaveCyclic_fnSetSecurity, + IPortFilterWaveCyclic_fnFastDeviceIoControl, + IPortFilterWaveCyclic_fnFastRead, + IPortFilterWaveCyclic_fnFastWrite +}; + + +NTSTATUS NewPortFilterWaveCyclic( + OUT IPortFilterWaveCyclic ** OutFilter) +{ + IPortFilterWaveCyclicImpl * This; + + This = ExAllocatePoolWithTag(NonPagedPool, sizeof(IPortFilterWaveCyclicImpl), TAG_PORTCLASS); + if (!This) + return STATUS_INSUFFICIENT_RESOURCES; + + /* initialize IPortFilterWaveCyclic */ + This->ref = 1; + This->lpVtbl = &vt_IPortFilterWaveCyclic; + + /* return result */ + *OutFilter = (IPortFilterWaveCyclic*)&This->lpVtbl; + + return STATUS_SUCCESS; +} + + diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.c b/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.c index d29c26e6193..3ceb756981b 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.c @@ -33,6 +33,11 @@ IPortDMus_fnQueryInterface( _InterlockedIncrement(&This->ref); return STATUS_SUCCESS; } + else if (IsEqualGUIDAligned(refiid, &IID_IPortClsVersion)) + { + return NewPortClsVersion((PPORTCLSVERSION*)Output); + } + return STATUS_UNSUCCESSFUL; } diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c b/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c index 3a35ed5fb2d..49ca49d28ea 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c @@ -15,6 +15,28 @@ typedef struct const GUID IID_IMiniportTopology; const GUID IID_IPortTopology; +#if 0 +static +KSPROPERTY_SET PinPropertySet = +{ + &KSPROPSETID_Pin, + 0, + NULL, + 0, + NULL +}; + +static +KSPROPERTY_SET TopologyPropertySet = +{ + &KSPROPSETID_Topology, + 4, + NULL, + 0, + NULL +}; +#endif + //--------------------------------------------------------------- // IUnknown interface functions @@ -36,6 +58,10 @@ IPortTopology_fnQueryInterface( _InterlockedIncrement(&This->ref); return STATUS_SUCCESS; } + else if (IsEqualGUIDAligned(refiid, &IID_IPortClsVersion)) + { + return NewPortClsVersion((PPORTCLSVERSION*)Output); + } return STATUS_UNSUCCESSFUL; } diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c b/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c index d459b360d8e..6d3e159910f 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c @@ -3,23 +3,31 @@ typedef struct { IPortWaveCyclicVtbl *lpVtbl; - IPortClsVersion *lpVtblPortClsVersion; -#if 0 - IUnregisterSubdevice *lpVtblUnregisterSubDevice; -#endif + IPortEventsVtbl *lpVbtlPortEvents; + IUnregisterSubdeviceVtbl *lpVtblUnregisterSubdevice; + IUnregisterPhysicalConnectionVtbl *lpVtblPhysicalConnection; + ISubdeviceVtbl *lpVtblSubDevice; LONG ref; BOOL bInitialized; PDEVICE_OBJECT pDeviceObject; PMINIPORTWAVECYCLIC pMiniport; + PRESOURCELIST pResourceList; + PPINCOUNT pPinCount; + PPOWERNOTIFY pPowerNotify; + PPCFILTER_DESCRIPTOR pDescriptor; }IPortWaveCyclicImpl; const GUID IID_IMiniportWaveCyclic; const GUID IID_IPortWaveCyclic; const GUID IID_IUnknown; +const GUID IID_IIrpTarget; +const GUID IID_IPinCount; +const GUID IID_IPowerNotify; +const GUID GUID_DEVCLASS_SOUND; //FIXME //--------------------------------------------------------------- // IUnknown interface functions // @@ -36,9 +44,25 @@ IPortWaveCyclic_fnQueryInterface( IsEqualGUIDAligned(refiid, &IID_IUnknown)) { *Output = &This->lpVtbl; - _InterlockedIncrement(&This->ref); + InterlockedIncrement(&This->ref); return STATUS_SUCCESS; } + else if (IsEqualGUIDAligned(refiid, &IID_ISubdevice)) + { + *Output = &This->lpVtblSubDevice; + InterlockedIncrement(&This->ref); + return STATUS_SUCCESS; + } + else if (IsEqualGUIDAligned(refiid, &IID_IPortClsVersion)) + { + return NewPortClsVersion((PPORTCLSVERSION*)Output); + } + else if (IsEqualGUIDAligned(refiid, &IID_IDrmPort) || + IsEqualGUIDAligned(refiid, &IID_IDrmPort2)) + { + return NewIDrmPort((PDRMPORT2*)Output); + } + return STATUS_UNSUCCESSFUL; } @@ -49,7 +73,7 @@ IPortWaveCyclic_fnAddRef( { IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)iface; - return _InterlockedIncrement(&This->ref); + return InterlockedIncrement(&This->ref); } ULONG @@ -59,7 +83,7 @@ IPortWaveCyclic_fnRelease( { IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)iface; - _InterlockedDecrement(&This->ref); + InterlockedDecrement(&This->ref); if (This->ref == 0) { @@ -67,6 +91,12 @@ IPortWaveCyclic_fnRelease( { This->pMiniport->lpVtbl->Release(This->pMiniport); } + if (This->pPinCount) + This->pPinCount->lpVtbl->Release(This->pPinCount); + + if (This->pPowerNotify) + This->pPowerNotify->lpVtbl->Release(This->pPowerNotify); + ExFreePoolWithTag(This, TAG_PORTCLASS); return 0; } @@ -111,6 +141,8 @@ IPortWaveCyclic_fnInit( { IMiniportWaveCyclic * Miniport; NTSTATUS Status; + PPINCOUNT PinCount; + PPOWERNOTIFY PowerNotify; IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)iface; if (This->bInitialized) @@ -130,16 +162,49 @@ IPortWaveCyclic_fnInit( if (!NT_SUCCESS(Status)) { DPRINT("IMiniportWaveCyclic_Init failed with %x\n", Status); + Miniport->lpVtbl->Release(Miniport); return Status; } + /* check if it supports IPinCount interface */ + Status = UnknownMiniport->lpVtbl->QueryInterface(UnknownMiniport, &IID_IPinCount, (PVOID*)&PinCount); + if (NT_SUCCESS(Status)) + { + This->pPinCount = PinCount; + This->pDescriptor = NULL; + } + else + { + Status = Miniport->lpVtbl->GetDescription(Miniport, &This->pDescriptor); + if (!NT_SUCCESS(Status)) + { + Miniport->lpVtbl->Release(Miniport); + return Status; + } + This->pPinCount = NULL; + } + + Status = UnknownMiniport->lpVtbl->QueryInterface(UnknownMiniport, &IID_IPowerNotify, (PVOID*)&PowerNotify); + if (NT_SUCCESS(Status)) + { + This->pPowerNotify = PowerNotify; + } + else + { + This->pPowerNotify = NULL; + } + + /* Initialize port object */ This->pMiniport = Miniport; This->pDeviceObject = DeviceObject; This->bInitialized = TRUE; + This->pResourceList = ResourceList; /* increment reference on miniport adapter */ Miniport->lpVtbl->AddRef(Miniport); + /* increment reference on resource list */ + ResourceList->lpVtbl->AddRef(ResourceList); return STATUS_SUCCESS; } @@ -164,7 +229,7 @@ IPortWaveCyclic_fnNewRegistryKey( DPRINT("IPortWaveCyclic_fnNewRegistryKey called w/o initialized\n"); return STATUS_UNSUCCESSFUL; } - return STATUS_UNSUCCESSFUL; + return PcNewRegistryKey(OutRegistryKey, OuterUnknown, RegistryKeyType, DesiredAccess, This->pDeviceObject, NULL /*FIXME*/, ObjectAttributes, CreateOptions, Disposition); } @@ -200,6 +265,48 @@ IPortWaveCyclic_fnNewSlaveDmaChannel( IN BOOL DemandMode, IN DMA_SPEED DmaSpeed) { + DEVICE_DESCRIPTION DeviceDesc; + INTERFACE_TYPE BusType; + ULONG ResultLength; + NTSTATUS Status; + ULONG MapRegisters; + PDMA_ADAPTER Adapter; + + IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)iface; + + if (!This->bInitialized) + { + DPRINT("IPortWaveCyclic_fnNewSlaveDmaChannel called w/o initialized\n"); + return STATUS_UNSUCCESSFUL; + } + + Status = IoGetDeviceProperty(This->pDeviceObject, DevicePropertyLegacyBusType, sizeof(BusType), (PVOID)&BusType, &ResultLength); + if (!NT_SUCCESS(Status)) + { + DPRINT("IoGetDeviceProperty failed with %x\n", Status); + return Status; + } + + RtlZeroMemory(&DeviceDesc, sizeof(DeviceDesc)); + DeviceDesc.Version = DEVICE_DESCRIPTION_VERSION; + DeviceDesc.Master = FALSE; + DeviceDesc.InterfaceType = BusType; + DeviceDesc.MaximumLength = MaximumLength; + DeviceDesc.DemandMode = DemandMode; + DeviceDesc.DmaSpeed = DmaSpeed; + DeviceDesc.DmaChannel = DmaIndex; + + Adapter = IoGetDmaAdapter(This->pDeviceObject, &DeviceDesc, &MapRegisters); + if (!Adapter) + { + DPRINT("IoGetDmaAdapter failed\n"); + return STATUS_INSUFFICIENT_RESOURCES; + } + + return NewDmaChannelSlave(&DeviceDesc, Adapter, MapRegisters, DmaChannel); + + + return STATUS_UNSUCCESSFUL; } @@ -209,9 +316,9 @@ IPortWaveCyclic_fnNotify( IN IPortWaveCyclic * iface, IN PSERVICEGROUP ServiceGroup) { + ServiceGroup->lpVtbl->RequestService (ServiceGroup); } - static const IPortWaveCyclicVtbl vt_IPortWaveCyclicVtbl = { IPortWaveCyclic_fnQueryInterface, @@ -225,6 +332,171 @@ static const IPortWaveCyclicVtbl vt_IPortWaveCyclicVtbl = IPortWaveCyclic_fnNewSlaveDmaChannel, }; +//--------------------------------------------------------------- +// ISubdevice interface +// + +static +NTSTATUS +NTAPI +ISubDevice_fnQueryInterface( + IN ISubdevice *iface, + IN REFIID InterfaceId, + IN PVOID* Interface) +{ + IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortWaveCyclicImpl, lpVtblSubDevice); + + return IPortWaveCyclic_fnQueryInterface((IPortWaveCyclic*)This, InterfaceId, Interface); +} + +static +ULONG +NTAPI +ISubDevice_fnAddRef( + IN ISubdevice *iface) +{ + IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortWaveCyclicImpl, lpVtblSubDevice); + + return IPortWaveCyclic_fnAddRef((IPortWaveCyclic*)This); +} + +static +ULONG +NTAPI +ISubDevice_fnRelease( + IN ISubdevice *iface) +{ + IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortWaveCyclicImpl, lpVtblSubDevice); + + return IPortWaveCyclic_fnRelease((IPortWaveCyclic*)This); +} + +static +NTSTATUS +NTAPI +ISubDevice_fnNewIrpTarget( + IN ISubdevice *iface, + OUT struct IIrpTarget **OutTarget, + IN WCHAR * Name, + IN PUNKNOWN Unknown, + IN POOL_TYPE PoolType, + IN PDEVICE_OBJECT * DeviceObject, + IN PIRP Irp, + IN KSOBJECT_CREATE *CreateObject) +{ + IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortWaveCyclicImpl, lpVtblSubDevice); + + DPRINT1("ISubDevice_NewIrpTarget this %p\n", This); + return STATUS_UNSUCCESSFUL; +} + +static +NTSTATUS +NTAPI +ISubDevice_fnReleaseChildren( + IN ISubdevice *iface) +{ + IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortWaveCyclicImpl, lpVtblSubDevice); + + DPRINT1("ISubDevice_ReleaseChildren this %p\n", This); + return STATUS_UNSUCCESSFUL; +} + +static +NTSTATUS +NTAPI +ISubDevice_fnGetDescriptor( + IN ISubdevice *iface, + IN struct SUBDEVICE_DESCRIPTOR ** Descriptor) +{ + IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortWaveCyclicImpl, lpVtblSubDevice); + + DPRINT1("ISubDevice_GetDescriptor this %p\n", This); + return STATUS_UNSUCCESSFUL; +} + +static +NTSTATUS +NTAPI +ISubDevice_fnDataRangeIntersection( + IN ISubdevice *iface, + IN ULONG PinId, + IN PKSDATARANGE DataRange, + IN PKSDATARANGE MatchingDataRange, + IN ULONG OutputBufferLength, + OUT PVOID ResultantFormat OPTIONAL, + OUT PULONG ResultantFormatLength) +{ + IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortWaveCyclicImpl, lpVtblSubDevice); + + DPRINT("ISubDevice_DataRangeIntersection this %p\n", This); + + if (This->pMiniport) + { + return This->pMiniport->lpVtbl->DataRangeIntersection (This->pMiniport, PinId, DataRange, MatchingDataRange, OutputBufferLength, ResultantFormat, ResultantFormatLength); + } + + return STATUS_UNSUCCESSFUL; +} + +static +NTSTATUS +NTAPI +ISubDevice_fnPowerChangeNotify( + IN ISubdevice *iface, + IN POWER_STATE PowerState) +{ + IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortWaveCyclicImpl, lpVtblSubDevice); + + if (This->pPowerNotify) + { + This->pPowerNotify->lpVtbl->PowerChangeNotify(This->pPowerNotify, PowerState); + } + + return STATUS_SUCCESS; +} + +static +NTSTATUS +NTAPI +ISubDevice_fnPinCount( + IN ISubdevice *iface, + IN ULONG PinId, + IN OUT PULONG FilterNecessary, + IN OUT PULONG FilterCurrent, + IN OUT PULONG FilterPossible, + IN OUT PULONG GlobalCurrent, + IN OUT PULONG GlobalPossible) +{ + IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortWaveCyclicImpl, lpVtblSubDevice); + + if (This->pPinCount) + { + This->pPinCount->lpVtbl->PinCount(This->pPinCount, PinId, FilterNecessary, FilterCurrent, FilterPossible, GlobalCurrent, GlobalPossible); + return STATUS_SUCCESS; + } + + /* FIXME + * scan filter descriptor + */ + return STATUS_UNSUCCESSFUL; +} + +static ISubdeviceVtbl vt_ISubdeviceVtbl = +{ + ISubDevice_fnQueryInterface, + ISubDevice_fnAddRef, + ISubDevice_fnRelease, + ISubDevice_fnNewIrpTarget, + ISubDevice_fnReleaseChildren, + ISubDevice_fnGetDescriptor, + ISubDevice_fnDataRangeIntersection, + ISubDevice_fnPowerChangeNotify, + ISubDevice_fnPinCount +}; + + + //--------------------------------------------------------------- // IPortWaveCyclic constructor // @@ -239,9 +511,10 @@ NewPortWaveCyclic( if (!This) return STATUS_INSUFFICIENT_RESOURCES; + RtlZeroMemory(This, sizeof(IPortWaveCyclicImpl)); This->lpVtbl = (IPortWaveCyclicVtbl*)&vt_IPortWaveCyclicVtbl; + This->lpVtblSubDevice = (ISubdeviceVtbl*)&vt_ISubdeviceVtbl; This->ref = 1; - This->bInitialized = FALSE; *OutPort = (PPORT)(&This->lpVtbl); return STATUS_SUCCESS; diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c b/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c index b9f1dd16817..f04c39b164c 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c @@ -124,6 +124,10 @@ IPortWavePci_fnQueryInterface( InterlockedIncrement(&This->ref); return STATUS_SUCCESS; } + else if (IsEqualGUIDAligned(refiid, &IID_IPortClsVersion)) + { + return NewPortClsVersion((PPORTCLSVERSION*)Output); + } return STATUS_UNSUCCESSFUL; } diff --git a/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild b/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild index c19d8d7605d..0632edeaf5d 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild +++ b/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild @@ -15,6 +15,7 @@ dma_slave.c drm_port.c adapter.c + filter_wavecyclic.c irp.c interrupt.c drm.c diff --git a/reactos/drivers/wdm/audio/backpln/portcls/private.h b/reactos/drivers/wdm/audio/backpln/portcls/private.h index 7a008af21e2..677f438d8bd 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/private.h +++ b/reactos/drivers/wdm/audio/backpln/portcls/private.h @@ -14,6 +14,8 @@ #include #include +#include "interfaces.h" + #define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24)) #define TAG_PORTCLASS TAG('P', 'C', 'L', 'S') @@ -72,18 +74,40 @@ NTSTATUS NewPortWavePci( NTSTATUS NewDmaChannelSlave( IN PDEVICE_DESCRIPTION DeviceDesc, IN PDMA_ADAPTER Adapter, + IN ULONG MapRegisters, OUT PDMACHANNELSLAVE* DmaChannel); NTSTATUS NewIDrmPort( OUT PDRMPORT2 *OutPort); +NTSTATUS NewPortClsVersion( + OUT PPORTCLSVERSION * OutVersion); + +NTSTATUS NewPortFilterWaveCyclic( + OUT IPortFilterWaveCyclic ** OutFilter); + typedef struct { + LIST_ENTRY Entry; + KSOBJECT_HEADER ObjectHeader; +}SUBDEVICE_ENTRY; + + +typedef struct +{ + PDEVICE_OBJECT PhysicalDeviceObject; PCPFNSTARTDEVICE StartDevice; KSDEVICE_HEADER KsDeviceHeader; IAdapterPowerManagement * AdapterPowerManagement; IResourceList* resources; + LIST_ENTRY SubDeviceList; + } PCExtension; + + + + + #endif diff --git a/reactos/drivers/wdm/audio/backpln/portcls/version.c b/reactos/drivers/wdm/audio/backpln/portcls/version.c index 92ea1a9a740..2d63b9bff4b 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/version.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/version.c @@ -1,7 +1,7 @@ #include "private.h" -typedef struct CResourceList +typedef struct { IPortClsVersionVtbl *lpVtbl; LONG ref;