- 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
This commit is contained in:
Johannes Anderwald 2009-01-02 15:05:57 +00:00
parent 4d8ae40ee4
commit 124bf05832
10 changed files with 765 additions and 22 deletions

View file

@ -10,7 +10,11 @@
*/ */
#include "private.h" #include "private.h"
#include <devguid.h>
#include <initguid.h> #include <initguid.h>
const GUID IID_ISubdevice;
/* /*
This is called from DriverEntry so that PortCls can take care of some 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 IRPs and map some others to the main KS driver. In most cases this will
@ -162,7 +166,9 @@ PcAddAdapterDevice(
/* Initialize */ /* Initialize */
RtlZeroMemory(portcls_ext, sizeof(PCExtension)); RtlZeroMemory(portcls_ext, sizeof(PCExtension));
portcls_ext->PhysicalDeviceObject = PhysicalDeviceObject;
portcls_ext->StartDevice = StartDevice; portcls_ext->StartDevice = StartDevice;
InitializeListHead(&portcls_ext->SubDeviceList);
status = KsAllocateDeviceHeader(&portcls_ext->KsDeviceHeader, 0, NULL); status = KsAllocateDeviceHeader(&portcls_ext->KsDeviceHeader, 0, NULL);
if (!NT_SUCCESS(status)) if (!NT_SUCCESS(status))
@ -182,9 +188,44 @@ PciDriverDispatch(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp) IN PIRP Irp)
{ {
NTSTATUS Status;
ISubdevice * SubDevice;
PCExtension* DeviceExt;
SUBDEVICE_ENTRY * Entry;
KSDISPATCH_TABLE DispatchTable;
DPRINT1("PortClsSysControl called\n"); 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.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
@ -201,6 +242,10 @@ PcRegisterSubdevice(
{ {
PCExtension* DeviceExt; PCExtension* DeviceExt;
NTSTATUS Status; NTSTATUS Status;
ISubdevice *SubDevice;
UNICODE_STRING ReferenceString;
UNICODE_STRING SymbolicLinkName;
if (!DeviceObject || !Name || !Unknown) if (!DeviceObject || !Name || !Unknown)
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
@ -209,8 +254,35 @@ PcRegisterSubdevice(
if (!DeviceExt) if (!DeviceExt)
return STATUS_UNSUCCESSFUL; 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;
} }

View file

@ -7,8 +7,13 @@ typedef struct
LONG ref; LONG ref;
ULONG MaxMapRegisters;
ULONG AllocatedBufferSize;
ULONG BufferSize; ULONG BufferSize;
PDMA_ADAPTER pAdapter;
PHYSICAL_ADDRESS Address; PHYSICAL_ADDRESS Address;
PVOID Buffer;
PMDL Mdl;
}IDmaChannelSlaveImpl; }IDmaChannelSlaveImpl;
@ -54,6 +59,7 @@ IDmaChannelSlave_fnRelease(
if (This->ref == 0) if (This->ref == 0)
{ {
This->pAdapter->DmaOperations->PutDmaAdapter(This->pAdapter);
ExFreePoolWithTag(This, TAG_PORTCLASS); ExFreePoolWithTag(This, TAG_PORTCLASS);
return 0; return 0;
} }
@ -78,12 +84,26 @@ IDmaChannelSlave_fnAllocateBuffer(
DPRINT("IDmaChannelSlave_AllocateBuffer: This %p BufferSize %u\n", This, BufferSize); DPRINT("IDmaChannelSlave_AllocateBuffer: This %p BufferSize %u\n", This, BufferSize);
/* Did the caller already allocate a buffer ?*/ /* 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->Buffer = This->pAdapter->DmaOperations->AllocateCommonBuffer(This->pAdapter, BufferSize, &This->Address, TRUE);
//This->BufferSize = BufferSize; 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 ULONG
@ -94,7 +114,7 @@ IDmaChannelSlave_fnAllocatedBufferSize(
IDmaChannelSlaveImpl * This = (IDmaChannelSlaveImpl*)iface; IDmaChannelSlaveImpl * This = (IDmaChannelSlaveImpl*)iface;
DPRINT("IDmaChannelSlave_AllocatedBufferSize: This %p BufferSize %u\n", This, This->BufferSize); DPRINT("IDmaChannelSlave_AllocatedBufferSize: This %p BufferSize %u\n", This, This->BufferSize);
return This->BufferSize; return This->AllocatedBufferSize;
} }
VOID VOID
@ -133,6 +153,16 @@ IDmaChannelSlave_fnFreeBuffer(
IDmaChannelSlaveImpl * This = (IDmaChannelSlaveImpl*)iface; IDmaChannelSlaveImpl * This = (IDmaChannelSlaveImpl*)iface;
DPRINT("IDmaChannelSlave_FreeBuffer: This %p\n", This); 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 PADAPTER_OBJECT
@ -143,7 +173,7 @@ IDmaChannelSlave_fnGetAdapterObject(
IDmaChannelSlaveImpl * This = (IDmaChannelSlaveImpl*)iface; IDmaChannelSlaveImpl * This = (IDmaChannelSlaveImpl*)iface;
DPRINT("IDmaChannelSlave_GetAdapterObject: This %p\n", This); DPRINT("IDmaChannelSlave_GetAdapterObject: This %p\n", This);
return NULL; return (PADAPTER_OBJECT)This->pAdapter;
} }
ULONG ULONG
@ -177,6 +207,7 @@ IDmaChannelSlave_fnSetBufferSize(
IDmaChannelSlaveImpl * This = (IDmaChannelSlaveImpl*)iface; IDmaChannelSlaveImpl * This = (IDmaChannelSlaveImpl*)iface;
DPRINT("IDmaChannelSlave_SetBufferSize: This %p\n", This); DPRINT("IDmaChannelSlave_SetBufferSize: This %p\n", This);
This->BufferSize = BufferSize;
} }
@ -185,7 +216,9 @@ NTAPI
IDmaChannelSlave_fnBufferSize( IDmaChannelSlave_fnBufferSize(
IN IDmaChannelSlave * iface) IN IDmaChannelSlave * iface)
{ {
return 0; IDmaChannelSlaveImpl * This = (IDmaChannelSlaveImpl*)iface;
return This->BufferSize;
} }
@ -197,7 +230,7 @@ IDmaChannelSlave_fnSystemAddress(
IDmaChannelSlaveImpl * This = (IDmaChannelSlaveImpl*)iface; IDmaChannelSlaveImpl * This = (IDmaChannelSlaveImpl*)iface;
DPRINT("IDmaChannelSlave_SystemAddress: This %p\n", This); DPRINT("IDmaChannelSlave_SystemAddress: This %p\n", This);
return NULL; return This->Buffer;
} }
ULONG ULONG
@ -219,6 +252,7 @@ IDmaChannelSlave_fnReadCounter(
IDmaChannelSlaveImpl * This = (IDmaChannelSlaveImpl*)iface; IDmaChannelSlaveImpl * This = (IDmaChannelSlaveImpl*)iface;
DPRINT("IDmaChannelSlave_ReadCounter: This %p\n", This); DPRINT("IDmaChannelSlave_ReadCounter: This %p\n", This);
return 0; return 0;
} }
@ -285,3 +319,30 @@ IDmaChannelSlaveVtbl vt_IDmaChannelSlaveVtbl =
IDmaChannelSlave_fnWaitForTC 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;
}

View file

@ -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;
}

View file

@ -33,6 +33,11 @@ IPortDMus_fnQueryInterface(
_InterlockedIncrement(&This->ref); _InterlockedIncrement(&This->ref);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
else if (IsEqualGUIDAligned(refiid, &IID_IPortClsVersion))
{
return NewPortClsVersion((PPORTCLSVERSION*)Output);
}
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }

View file

@ -15,6 +15,28 @@ typedef struct
const GUID IID_IMiniportTopology; const GUID IID_IMiniportTopology;
const GUID IID_IPortTopology; 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 // IUnknown interface functions
@ -36,6 +58,10 @@ IPortTopology_fnQueryInterface(
_InterlockedIncrement(&This->ref); _InterlockedIncrement(&This->ref);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
else if (IsEqualGUIDAligned(refiid, &IID_IPortClsVersion))
{
return NewPortClsVersion((PPORTCLSVERSION*)Output);
}
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }

View file

@ -3,23 +3,31 @@
typedef struct typedef struct
{ {
IPortWaveCyclicVtbl *lpVtbl; IPortWaveCyclicVtbl *lpVtbl;
IPortClsVersion *lpVtblPortClsVersion; IPortEventsVtbl *lpVbtlPortEvents;
#if 0 IUnregisterSubdeviceVtbl *lpVtblUnregisterSubdevice;
IUnregisterSubdevice *lpVtblUnregisterSubDevice; IUnregisterPhysicalConnectionVtbl *lpVtblPhysicalConnection;
#endif ISubdeviceVtbl *lpVtblSubDevice;
LONG ref; LONG ref;
BOOL bInitialized; BOOL bInitialized;
PDEVICE_OBJECT pDeviceObject; PDEVICE_OBJECT pDeviceObject;
PMINIPORTWAVECYCLIC pMiniport; PMINIPORTWAVECYCLIC pMiniport;
PRESOURCELIST pResourceList;
PPINCOUNT pPinCount;
PPOWERNOTIFY pPowerNotify;
PPCFILTER_DESCRIPTOR pDescriptor;
}IPortWaveCyclicImpl; }IPortWaveCyclicImpl;
const GUID IID_IMiniportWaveCyclic; const GUID IID_IMiniportWaveCyclic;
const GUID IID_IPortWaveCyclic; const GUID IID_IPortWaveCyclic;
const GUID IID_IUnknown; 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 // IUnknown interface functions
// //
@ -36,9 +44,25 @@ IPortWaveCyclic_fnQueryInterface(
IsEqualGUIDAligned(refiid, &IID_IUnknown)) IsEqualGUIDAligned(refiid, &IID_IUnknown))
{ {
*Output = &This->lpVtbl; *Output = &This->lpVtbl;
_InterlockedIncrement(&This->ref); InterlockedIncrement(&This->ref);
return STATUS_SUCCESS; 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; return STATUS_UNSUCCESSFUL;
} }
@ -49,7 +73,7 @@ IPortWaveCyclic_fnAddRef(
{ {
IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)iface; IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)iface;
return _InterlockedIncrement(&This->ref); return InterlockedIncrement(&This->ref);
} }
ULONG ULONG
@ -59,7 +83,7 @@ IPortWaveCyclic_fnRelease(
{ {
IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)iface; IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)iface;
_InterlockedDecrement(&This->ref); InterlockedDecrement(&This->ref);
if (This->ref == 0) if (This->ref == 0)
{ {
@ -67,6 +91,12 @@ IPortWaveCyclic_fnRelease(
{ {
This->pMiniport->lpVtbl->Release(This->pMiniport); 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); ExFreePoolWithTag(This, TAG_PORTCLASS);
return 0; return 0;
} }
@ -111,6 +141,8 @@ IPortWaveCyclic_fnInit(
{ {
IMiniportWaveCyclic * Miniport; IMiniportWaveCyclic * Miniport;
NTSTATUS Status; NTSTATUS Status;
PPINCOUNT PinCount;
PPOWERNOTIFY PowerNotify;
IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)iface; IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)iface;
if (This->bInitialized) if (This->bInitialized)
@ -130,16 +162,49 @@ IPortWaveCyclic_fnInit(
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("IMiniportWaveCyclic_Init failed with %x\n", Status); DPRINT("IMiniportWaveCyclic_Init failed with %x\n", Status);
Miniport->lpVtbl->Release(Miniport);
return Status; 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 */ /* Initialize port object */
This->pMiniport = Miniport; This->pMiniport = Miniport;
This->pDeviceObject = DeviceObject; This->pDeviceObject = DeviceObject;
This->bInitialized = TRUE; This->bInitialized = TRUE;
This->pResourceList = ResourceList;
/* increment reference on miniport adapter */ /* increment reference on miniport adapter */
Miniport->lpVtbl->AddRef(Miniport); Miniport->lpVtbl->AddRef(Miniport);
/* increment reference on resource list */
ResourceList->lpVtbl->AddRef(ResourceList);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -164,7 +229,7 @@ IPortWaveCyclic_fnNewRegistryKey(
DPRINT("IPortWaveCyclic_fnNewRegistryKey called w/o initialized\n"); DPRINT("IPortWaveCyclic_fnNewRegistryKey called w/o initialized\n");
return STATUS_UNSUCCESSFUL; 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 BOOL DemandMode,
IN DMA_SPEED DmaSpeed) 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; return STATUS_UNSUCCESSFUL;
} }
@ -209,9 +316,9 @@ IPortWaveCyclic_fnNotify(
IN IPortWaveCyclic * iface, IN IPortWaveCyclic * iface,
IN PSERVICEGROUP ServiceGroup) IN PSERVICEGROUP ServiceGroup)
{ {
ServiceGroup->lpVtbl->RequestService (ServiceGroup);
} }
static const IPortWaveCyclicVtbl vt_IPortWaveCyclicVtbl = static const IPortWaveCyclicVtbl vt_IPortWaveCyclicVtbl =
{ {
IPortWaveCyclic_fnQueryInterface, IPortWaveCyclic_fnQueryInterface,
@ -225,6 +332,171 @@ static const IPortWaveCyclicVtbl vt_IPortWaveCyclicVtbl =
IPortWaveCyclic_fnNewSlaveDmaChannel, 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 // IPortWaveCyclic constructor
// //
@ -239,9 +511,10 @@ NewPortWaveCyclic(
if (!This) if (!This)
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
RtlZeroMemory(This, sizeof(IPortWaveCyclicImpl));
This->lpVtbl = (IPortWaveCyclicVtbl*)&vt_IPortWaveCyclicVtbl; This->lpVtbl = (IPortWaveCyclicVtbl*)&vt_IPortWaveCyclicVtbl;
This->lpVtblSubDevice = (ISubdeviceVtbl*)&vt_ISubdeviceVtbl;
This->ref = 1; This->ref = 1;
This->bInitialized = FALSE;
*OutPort = (PPORT)(&This->lpVtbl); *OutPort = (PPORT)(&This->lpVtbl);
return STATUS_SUCCESS; return STATUS_SUCCESS;

View file

@ -124,6 +124,10 @@ IPortWavePci_fnQueryInterface(
InterlockedIncrement(&This->ref); InterlockedIncrement(&This->ref);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
else if (IsEqualGUIDAligned(refiid, &IID_IPortClsVersion))
{
return NewPortClsVersion((PPORTCLSVERSION*)Output);
}
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }

View file

@ -15,6 +15,7 @@
<file>dma_slave.c</file> <file>dma_slave.c</file>
<file>drm_port.c</file> <file>drm_port.c</file>
<file>adapter.c</file> <file>adapter.c</file>
<file>filter_wavecyclic.c</file>
<file>irp.c</file> <file>irp.c</file>
<file>interrupt.c</file> <file>interrupt.c</file>
<file>drm.c</file> <file>drm.c</file>

View file

@ -14,6 +14,8 @@
#include <portcls.h> #include <portcls.h>
#include <dmusicks.h> #include <dmusicks.h>
#include "interfaces.h"
#define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24)) #define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
#define TAG_PORTCLASS TAG('P', 'C', 'L', 'S') #define TAG_PORTCLASS TAG('P', 'C', 'L', 'S')
@ -72,18 +74,40 @@ NTSTATUS NewPortWavePci(
NTSTATUS NewDmaChannelSlave( NTSTATUS NewDmaChannelSlave(
IN PDEVICE_DESCRIPTION DeviceDesc, IN PDEVICE_DESCRIPTION DeviceDesc,
IN PDMA_ADAPTER Adapter, IN PDMA_ADAPTER Adapter,
IN ULONG MapRegisters,
OUT PDMACHANNELSLAVE* DmaChannel); OUT PDMACHANNELSLAVE* DmaChannel);
NTSTATUS NewIDrmPort( NTSTATUS NewIDrmPort(
OUT PDRMPORT2 *OutPort); OUT PDRMPORT2 *OutPort);
NTSTATUS NewPortClsVersion(
OUT PPORTCLSVERSION * OutVersion);
NTSTATUS NewPortFilterWaveCyclic(
OUT IPortFilterWaveCyclic ** OutFilter);
typedef struct typedef struct
{ {
LIST_ENTRY Entry;
KSOBJECT_HEADER ObjectHeader;
}SUBDEVICE_ENTRY;
typedef struct
{
PDEVICE_OBJECT PhysicalDeviceObject;
PCPFNSTARTDEVICE StartDevice; PCPFNSTARTDEVICE StartDevice;
KSDEVICE_HEADER KsDeviceHeader; KSDEVICE_HEADER KsDeviceHeader;
IAdapterPowerManagement * AdapterPowerManagement; IAdapterPowerManagement * AdapterPowerManagement;
IResourceList* resources; IResourceList* resources;
LIST_ENTRY SubDeviceList;
} PCExtension; } PCExtension;
#endif #endif

View file

@ -1,7 +1,7 @@
#include "private.h" #include "private.h"
typedef struct CResourceList typedef struct
{ {
IPortClsVersionVtbl *lpVtbl; IPortClsVersionVtbl *lpVtbl;
LONG ref; LONG ref;