Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenport_wavepci.cpp
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS Kernel Streaming 00004 * FILE: drivers/wdm/audio/backpln/portcls/port_wavepci.cpp 00005 * PURPOSE: Wave PCI Port driver 00006 * PROGRAMMER: Johannes Anderwald 00007 */ 00008 00009 #include "private.hpp" 00010 00011 class CPortWavePci : public IPortWavePci, 00012 public IPortEvents, 00013 public ISubdevice, 00014 public IServiceSink 00015 { 00016 public: 00017 STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); 00018 00019 STDMETHODIMP_(ULONG) AddRef() 00020 { 00021 InterlockedIncrement(&m_Ref); 00022 return m_Ref; 00023 } 00024 STDMETHODIMP_(ULONG) Release() 00025 { 00026 InterlockedDecrement(&m_Ref); 00027 00028 if (!m_Ref) 00029 { 00030 delete this; 00031 return 0; 00032 } 00033 return m_Ref; 00034 } 00035 IMP_IPortWavePci; 00036 IMP_ISubdevice; 00037 IMP_IPortEvents; 00038 IMP_IServiceSink; 00039 CPortWavePci(IUnknown *OuterUnknown){} 00040 virtual ~CPortWavePci() {} 00041 00042 protected: 00043 00044 PMINIPORTWAVEPCI m_Miniport; 00045 PDEVICE_OBJECT m_pDeviceObject; 00046 PSERVICEGROUP m_ServiceGroup; 00047 PPINCOUNT m_pPinCount; 00048 PPOWERNOTIFY m_pPowerNotify; 00049 PPCFILTER_DESCRIPTOR m_pDescriptor; 00050 PSUBDEVICE_DESCRIPTOR m_SubDeviceDescriptor; 00051 IPortFilterWavePci * m_Filter; 00052 00053 LIST_ENTRY m_EventList; 00054 KSPIN_LOCK m_EventListLock; 00055 00056 LONG m_Ref; 00057 00058 friend PDEVICE_OBJECT GetDeviceObjectFromPortWavePci(IPortWavePci* iface); 00059 friend PMINIPORTWAVEPCI GetWavePciMiniport(PPORTWAVEPCI iface); 00060 00061 }; 00062 00063 static GUID InterfaceGuids[3] = 00064 { 00065 { 00067 0x6994AD04, 0x93EF, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96} 00068 }, 00069 { 00071 0x65E8773EL, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96} 00072 }, 00073 { 00075 0x65E8773DL, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96} 00076 } 00077 }; 00078 00079 DEFINE_KSPROPERTY_TOPOLOGYSET(PortFilterWavePciTopologySet, TopologyPropertyHandler); 00080 DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PortFilterWavePciPinSet, PinPropertyHandler, PinPropertyHandler, PinPropertyHandler); 00081 00082 KSPROPERTY_SET WavePciPropertySet[] = 00083 { 00084 { 00085 &KSPROPSETID_Topology, 00086 sizeof(PortFilterWavePciTopologySet) / sizeof(KSPROPERTY_ITEM), 00087 (const KSPROPERTY_ITEM*)&PortFilterWavePciTopologySet, 00088 0, 00089 NULL 00090 }, 00091 { 00092 &KSPROPSETID_Pin, 00093 sizeof(PortFilterWavePciPinSet) / sizeof(KSPROPERTY_ITEM), 00094 (const KSPROPERTY_ITEM*)&PortFilterWavePciPinSet, 00095 0, 00096 NULL 00097 } 00098 }; 00099 00100 00101 //--------------------------------------------------------------- 00102 // IPortEvents 00103 // 00104 00105 void 00106 NTAPI 00107 CPortWavePci::AddEventToEventList( 00108 IN PKSEVENT_ENTRY EventEntry) 00109 { 00110 KIRQL OldIrql; 00111 00112 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); 00113 00114 KeAcquireSpinLock(&m_EventListLock, &OldIrql); 00115 InsertTailList(&m_EventList, &EventEntry->ListEntry); 00116 KeReleaseSpinLock(&m_EventListLock, OldIrql); 00117 } 00118 00119 00120 00121 void 00122 NTAPI 00123 CPortWavePci::GenerateEventList( 00124 IN GUID* Set OPTIONAL, 00125 IN ULONG EventId, 00126 IN BOOL PinEvent, 00127 IN ULONG PinId, 00128 IN BOOL NodeEvent, 00129 IN ULONG NodeId) 00130 { 00131 UNIMPLEMENTED 00132 } 00133 //--------------------------------------------------------------- 00134 // IServiceSink 00135 // 00136 00137 VOID 00138 NTAPI 00139 CPortWavePci::RequestService() 00140 { 00141 //DPRINT("IServiceSink_fnRequestService entered\n"); 00142 if (m_Miniport) 00143 { 00144 m_Miniport->Service(); 00145 } 00146 } 00147 00148 //--------------------------------------------------------------- 00149 // IPortWavePci 00150 // 00151 00152 NTSTATUS 00153 NTAPI 00154 CPortWavePci::QueryInterface( 00155 IN REFIID refiid, 00156 OUT PVOID* Output) 00157 { 00158 UNICODE_STRING GuidString; 00159 00160 DPRINT("IPortWavePci_fnQueryInterface entered\n"); 00161 00162 if (IsEqualGUIDAligned(refiid, IID_IPortWavePci) || 00163 IsEqualGUIDAligned(refiid, IID_IUnknown) || 00164 IsEqualGUIDAligned(refiid, IID_IPort)) 00165 { 00166 *Output = PVOID(PPORTWAVEPCI(this)); 00167 PUNKNOWN(*Output)->AddRef(); 00168 return STATUS_SUCCESS; 00169 } 00170 else if (IsEqualGUIDAligned(refiid, IID_IServiceSink)) 00171 { 00172 *Output = PVOID(PSERVICESINK(this)); 00173 PUNKNOWN(*Output)->AddRef(); 00174 return STATUS_SUCCESS; 00175 } 00176 else if (IsEqualGUIDAligned(refiid, IID_IPortEvents)) 00177 { 00178 *Output = PVOID(PPORTEVENTS(this)); 00179 PUNKNOWN(*Output)->AddRef(); 00180 return STATUS_SUCCESS; 00181 } 00182 else if (IsEqualGUIDAligned(refiid, IID_ISubdevice)) 00183 { 00184 *Output = PVOID(PSUBDEVICE(this)); 00185 PUNKNOWN(*Output)->AddRef(); 00186 return STATUS_SUCCESS; 00187 } 00188 else if (IsEqualGUIDAligned(refiid, IID_IDrmPort) || 00189 IsEqualGUIDAligned(refiid, IID_IDrmPort2)) 00190 { 00191 return NewIDrmPort((PDRMPORT2*)Output); 00192 } 00193 else if (IsEqualGUIDAligned(refiid, IID_IPortClsVersion)) 00194 { 00195 return NewPortClsVersion((PPORTCLSVERSION*)Output); 00196 } 00197 else if (IsEqualGUIDAligned(refiid, IID_IUnregisterSubdevice)) 00198 { 00199 return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output); 00200 } 00201 else if (IsEqualGUIDAligned(refiid, IID_IUnregisterPhysicalConnection)) 00202 { 00203 return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION*)Output); 00204 } 00205 00206 if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS) 00207 { 00208 DPRINT("IPortWavePci_fnQueryInterface no interface!!! iface %S\n", GuidString.Buffer); 00209 RtlFreeUnicodeString(&GuidString); 00210 } 00211 00212 return STATUS_UNSUCCESSFUL; 00213 } 00214 00215 NTSTATUS 00216 NTAPI 00217 CPortWavePci::Init( 00218 IN PDEVICE_OBJECT DeviceObject, 00219 IN PIRP Irp, 00220 IN PUNKNOWN UnknownMiniport, 00221 IN PUNKNOWN UnknownAdapter OPTIONAL, 00222 IN PRESOURCELIST ResourceList) 00223 { 00224 IMiniportWavePci * Miniport; 00225 PSERVICEGROUP ServiceGroup; 00226 NTSTATUS Status; 00227 PPINCOUNT PinCount; 00228 PPOWERNOTIFY PowerNotify; 00229 00230 DPRINT("IPortWavePci_fnInit entered with This %p, DeviceObject %p Irp %p UnknownMiniport %p, UnknownAdapter %p ResourceList %p\n", 00231 this, DeviceObject, Irp, UnknownMiniport, UnknownAdapter, ResourceList); 00232 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); 00233 00234 Status = UnknownMiniport->QueryInterface(IID_IMiniportWavePci, (PVOID*)&Miniport); 00235 if (!NT_SUCCESS(Status)) 00236 { 00237 DPRINT("IPortWavePci_fnInit called with invalid IMiniport adapter\n"); 00238 return STATUS_INVALID_PARAMETER; 00239 } 00240 00241 // Initialize port object 00242 m_Miniport = Miniport; 00243 m_pDeviceObject = DeviceObject; 00244 00245 InitializeListHead(&m_EventList); 00246 KeInitializeSpinLock(&m_EventListLock); 00247 00248 // increment reference on miniport adapter 00249 Miniport->AddRef(); 00250 00251 Status = Miniport->Init(UnknownAdapter, ResourceList, this, &ServiceGroup); 00252 if (!NT_SUCCESS(Status)) 00253 { 00254 DPRINT("IPortWavePci_fnInit failed with %x\n", Status); 00255 00256 // release reference on miniport adapter 00257 Miniport->Release(); 00258 return Status; 00259 } 00260 00261 // check if the miniport adapter provides a valid device descriptor 00262 Status = Miniport->GetDescription(&m_pDescriptor); 00263 if (!NT_SUCCESS(Status)) 00264 { 00265 DPRINT("failed to get description\n"); 00266 Miniport->Release(); 00267 return Status; 00268 } 00269 00270 // create the subdevice descriptor 00271 Status = PcCreateSubdeviceDescriptor(&m_SubDeviceDescriptor, 00272 3, 00273 InterfaceGuids, 00274 0, 00275 NULL, 00276 2, 00277 WavePciPropertySet, 00278 0, 00279 0, 00280 0, 00281 NULL, 00282 0, 00283 NULL, 00284 m_pDescriptor); 00285 00286 00287 if (!NT_SUCCESS(Status)) 00288 { 00289 DPRINT("PcCreateSubdeviceDescriptor failed with %x\n", Status); 00290 Miniport->Release(); 00291 return Status; 00292 } 00293 00294 // did we get a service group 00295 if (ServiceGroup) 00296 { 00297 // store service group in context 00298 m_ServiceGroup = ServiceGroup; 00299 00300 // add ourselves to service group which is called when miniport receives an isr 00301 m_ServiceGroup->AddMember(PSERVICESINK(this)); 00302 00303 // increment reference on service group 00304 m_ServiceGroup->AddRef(); 00305 } 00306 00307 // store for node property requests 00308 m_SubDeviceDescriptor->UnknownMiniport = UnknownMiniport; 00309 00310 // check if it supports IPinCount interface 00311 Status = UnknownMiniport->QueryInterface(IID_IPinCount, (PVOID*)&PinCount); 00312 if (NT_SUCCESS(Status)) 00313 { 00314 // store IPinCount interface 00315 m_pPinCount = PinCount; 00316 } 00317 00318 // does the Miniport adapter support IPowerNotify interface*/ 00319 Status = UnknownMiniport->QueryInterface(IID_IPowerNotify, (PVOID*)&PowerNotify); 00320 if (NT_SUCCESS(Status)) 00321 { 00322 // store reference 00323 m_pPowerNotify = PowerNotify; 00324 } 00325 00326 DPRINT("IPortWavePci_Init sucessfully initialized\n"); 00327 return STATUS_SUCCESS; 00328 } 00329 00330 NTSTATUS 00331 NTAPI 00332 CPortWavePci::NewRegistryKey( 00333 OUT PREGISTRYKEY *OutRegistryKey, 00334 IN PUNKNOWN OuterUnknown OPTIONAL, 00335 IN ULONG RegistryKeyType, 00336 IN ACCESS_MASK DesiredAccess, 00337 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, 00338 IN ULONG CreateOptions OPTIONAL, 00339 OUT PULONG Disposition OPTIONAL) 00340 { 00341 DPRINT("IPortWavePci_fnNewRegistryKey entered\n"); 00342 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); 00343 00344 return PcNewRegistryKey(OutRegistryKey, 00345 OuterUnknown, 00346 RegistryKeyType, 00347 DesiredAccess, 00348 m_pDeviceObject, 00349 (ISubdevice*)this, 00350 ObjectAttributes, 00351 CreateOptions, 00352 Disposition); 00353 } 00354 00355 NTSTATUS 00356 NTAPI 00357 CPortWavePci::GetDeviceProperty( 00358 IN DEVICE_REGISTRY_PROPERTY DeviceRegistryProperty, 00359 IN ULONG BufferLength, 00360 OUT PVOID PropertyBuffer, 00361 OUT PULONG ReturnLength) 00362 { 00363 DPRINT("IPortWavePci_fnGetDeviceProperty entered\n"); 00364 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); 00365 00366 return IoGetDeviceProperty(m_pDeviceObject, DeviceRegistryProperty, BufferLength, PropertyBuffer, ReturnLength); 00367 } 00368 00369 NTSTATUS 00370 NTAPI 00371 CPortWavePci::NewMasterDmaChannel( 00372 OUT PDMACHANNEL *DmaChannel, 00373 IN PUNKNOWN OuterUnknown OPTIONAL, 00374 IN POOL_TYPE PoolType, 00375 IN PRESOURCELIST ResourceList OPTIONAL, 00376 IN BOOLEAN ScatterGather, 00377 IN BOOLEAN Dma32BitAddresses, 00378 IN BOOLEAN Dma64BitAddresses, 00379 IN BOOLEAN IgnoreCount, 00380 IN DMA_WIDTH DmaWidth, 00381 IN DMA_SPEED DmaSpeed, 00382 IN ULONG MaximumLength, 00383 IN ULONG DmaPort) 00384 { 00385 NTSTATUS Status; 00386 DEVICE_DESCRIPTION DeviceDescription; 00387 00388 DPRINT("IPortWavePci_fnNewMasterDmaChannel This %p entered\n", this); 00389 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); 00390 00391 Status = PcDmaMasterDescription(ResourceList, ScatterGather, Dma32BitAddresses, IgnoreCount, Dma64BitAddresses, DmaWidth, DmaSpeed, MaximumLength, DmaPort, &DeviceDescription); 00392 if (NT_SUCCESS(Status)) 00393 { 00394 return PcNewDmaChannel(DmaChannel, OuterUnknown, PoolType, &DeviceDescription, m_pDeviceObject); 00395 } 00396 00397 return Status; 00398 } 00399 00400 VOID 00401 NTAPI 00402 CPortWavePci::Notify( 00403 IN PSERVICEGROUP ServiceGroup) 00404 { 00405 //DPRINT("IPortWavePci_fnNotify entered %p, ServiceGroup %p\n", This, ServiceGroup); 00406 00407 if (ServiceGroup) 00408 { 00409 ServiceGroup->RequestService (); 00410 } 00411 } 00412 00413 //--------------------------------------------------------------- 00414 // ISubdevice interface 00415 // 00416 00417 NTSTATUS 00418 NTAPI 00419 CPortWavePci::NewIrpTarget( 00420 OUT struct IIrpTarget **OutTarget, 00421 IN PCWSTR Name, 00422 IN PUNKNOWN Unknown, 00423 IN POOL_TYPE PoolType, 00424 IN PDEVICE_OBJECT DeviceObject, 00425 IN PIRP Irp, 00426 IN KSOBJECT_CREATE *CreateObject) 00427 { 00428 NTSTATUS Status; 00429 IPortFilterWavePci * Filter; 00430 00431 DPRINT("ISubDevice_NewIrpTarget this %p\n", this); 00432 00433 if (m_Filter) 00434 { 00435 *OutTarget = (IIrpTarget*)m_Filter; 00436 return STATUS_SUCCESS; 00437 } 00438 00439 Status = NewPortFilterWavePci(&Filter); 00440 if (!NT_SUCCESS(Status)) 00441 { 00442 return Status; 00443 } 00444 00445 Status = Filter->Init((IPortWavePci*)this); 00446 if (!NT_SUCCESS(Status)) 00447 { 00448 Filter->Release(); 00449 return Status; 00450 } 00451 00452 *OutTarget = (IIrpTarget*)Filter; 00453 m_Filter = Filter; 00454 return Status; 00455 } 00456 00457 NTSTATUS 00458 NTAPI 00459 CPortWavePci::ReleaseChildren() 00460 { 00461 UNIMPLEMENTED 00462 return STATUS_UNSUCCESSFUL; 00463 } 00464 00465 NTSTATUS 00466 NTAPI 00467 CPortWavePci::GetDescriptor( 00468 IN SUBDEVICE_DESCRIPTOR ** Descriptor) 00469 { 00470 DPRINT("ISubDevice_GetDescriptor this %p\n", this); 00471 *Descriptor = m_SubDeviceDescriptor; 00472 return STATUS_SUCCESS; 00473 } 00474 00475 NTSTATUS 00476 NTAPI 00477 CPortWavePci::DataRangeIntersection( 00478 IN ULONG PinId, 00479 IN PKSDATARANGE DataRange, 00480 IN PKSDATARANGE MatchingDataRange, 00481 IN ULONG OutputBufferLength, 00482 OUT PVOID ResultantFormat OPTIONAL, 00483 OUT PULONG ResultantFormatLength) 00484 { 00485 DPRINT("ISubDevice_DataRangeIntersection this %p\n", this); 00486 00487 if (m_Miniport) 00488 { 00489 return m_Miniport->DataRangeIntersection (PinId, DataRange, MatchingDataRange, OutputBufferLength, ResultantFormat, ResultantFormatLength); 00490 } 00491 00492 return STATUS_UNSUCCESSFUL; 00493 } 00494 00495 NTSTATUS 00496 NTAPI 00497 CPortWavePci::PowerChangeNotify( 00498 IN POWER_STATE PowerState) 00499 { 00500 if (m_pPowerNotify) 00501 { 00502 m_pPowerNotify->PowerChangeNotify(PowerState); 00503 } 00504 00505 return STATUS_SUCCESS; 00506 } 00507 00508 NTSTATUS 00509 NTAPI 00510 CPortWavePci::PinCount( 00511 IN ULONG PinId, 00512 IN OUT PULONG FilterNecessary, 00513 IN OUT PULONG FilterCurrent, 00514 IN OUT PULONG FilterPossible, 00515 IN OUT PULONG GlobalCurrent, 00516 IN OUT PULONG GlobalPossible) 00517 { 00518 if (m_pPinCount) 00519 { 00520 m_pPinCount->PinCount(PinId, FilterNecessary, FilterCurrent, FilterPossible, GlobalCurrent, GlobalPossible); 00521 return STATUS_SUCCESS; 00522 } 00523 00524 // FIXME 00525 // scan filter descriptor 00526 00527 return STATUS_UNSUCCESSFUL; 00528 } 00529 00530 00531 NTSTATUS 00532 NewPortWavePci( 00533 OUT PPORT* OutPort) 00534 { 00535 CPortWavePci * Port; 00536 NTSTATUS Status; 00537 00538 Port = new(NonPagedPool, TAG_PORTCLASS) CPortWavePci(NULL); 00539 if (!Port) 00540 return STATUS_INSUFFICIENT_RESOURCES; 00541 00542 Status = Port->QueryInterface(IID_IPort, (PVOID*)OutPort); 00543 00544 if (!NT_SUCCESS(Status)) 00545 { 00546 delete Port; 00547 } 00548 00549 DPRINT("NewPortWavePci %p Status %u\n", Port, Status); 00550 return Status; 00551 00552 } 00553 00554 00555 PDEVICE_OBJECT 00556 GetDeviceObjectFromPortWavePci( 00557 IPortWavePci* iface) 00558 { 00559 CPortWavePci * This = (CPortWavePci*)iface; 00560 return This->m_pDeviceObject; 00561 } 00562 00563 PMINIPORTWAVEPCI 00564 GetWavePciMiniport( 00565 PPORTWAVEPCI iface) 00566 { 00567 CPortWavePci * This = (CPortWavePci*)iface; 00568 return This->m_Miniport; 00569 } Generated on Sun May 27 2012 04:28:36 for ReactOS by
1.7.6.1
|