/***************************************************************************** * StartDevice ***************************************************************************** * This function is called by the operating system when the device is started. * It is responsible for starting the miniports. This code is specific to * the adapter because it calls out miniports for functions that are specific * to the adapter. */ NTSTATUS StartDevice ( IN PDEVICE_OBJECT DeviceObject, // Device object. IN PIRP Irp, // IO request packet. IN PRESOURCELIST ResourceList // List of hardware resources. ) { PAGED_CODE (); ASSERT (DeviceObject); ASSERT (Irp); ASSERT (ResourceList); NTSTATUS ntStatus; DOUT (DBG_PRINT, ("[StartDevice]")); // // Determine which version of the OS we are running under. We don't want // to run under Win98G. // // create a wave cyclic port PPORT pPort = 0; ntStatus = PcNewPort (&pPort,CLSID_PortWaveCyclic); // check error code if (NT_SUCCESS (ntStatus)) { // query for the event interface which is not supported in Win98 gold. PPORTEVENTS pPortEvents = 0; ntStatus = pPort->QueryInterface (IID_IPortEvents, (PVOID *)&pPortEvents); if (!NT_SUCCESS (ntStatus)) { DOUT (DBG_ERROR, ("This driver is not for Win98 Gold!")); ntStatus = STATUS_UNSUCCESSFUL; // change error code. } else { pPortEvents->Release (); } pPort->Release (); } // now return in case it was Win98 Gold. if (!NT_SUCCESS (ntStatus)) return ntStatus; // // Validate the resources. // We don't have to split the resources into several resource lists cause // the topology miniport doesn't need a resource list, the wave pci miniport // needs all resources like the adapter common object. // ntStatus = ValidateResources (ResourceList); // // return immediately in case of an error // if (!NT_SUCCESS (ntStatus)) return ntStatus; // // If the adapter has the right resources... // PADAPTERCOMMON pAdapterCommon = NULL; PUNKNOWN pUnknownCommon; // create a new adapter common object ntStatus = NewAdapterCommon (&pUnknownCommon, IID_IAC97AdapterCommon, NULL, NonPagedPool); if (NT_SUCCESS (ntStatus)) { // query for the IAC97AdapterCommon interface ntStatus = pUnknownCommon->QueryInterface (IID_IAC97AdapterCommon, (PVOID *)&pAdapterCommon); if (NT_SUCCESS (ntStatus)) { // Initialize the object ntStatus = pAdapterCommon->Init (ResourceList, DeviceObject); if (NT_SUCCESS (ntStatus)) { // register with PortCls for power-management services ntStatus = PcRegisterAdapterPowerManagement ((PUNKNOWN)pAdapterCommon, DeviceObject); } } // release the IID_IAC97AdapterCommon on adapter common pUnknownCommon->Release (); } // print error message. if (!NT_SUCCESS (ntStatus)) { DOUT (DBG_ERROR, ("Could not create or query AdapterCommon.")); } // // These are the port driver pointers we are keeping around for registering // physical connections. // PMINIPORT miniTopology = NULL; PUNKNOWN unknownWave = NULL; PUNKNOWN unknownTopology = NULL; PAC97MINIPORTTOPOLOGY pMiniportTopology = NULL; // // Start the topology miniport. // if (NT_SUCCESS (ntStatus)) { ntStatus = InstallSubdevice (DeviceObject, Irp, L"Topology", CLSID_PortTopology, CLSID_PortTopology, // not used CreateAC97MiniportTopology, pAdapterCommon, NULL, GUID_NULL, &miniTopology, &unknownTopology); if (NT_SUCCESS (ntStatus)) { // query for the IAC97MiniportTopology interface ntStatus = miniTopology->QueryInterface (IID_IAC97MiniportTopology, (PVOID *)&pMiniportTopology); miniTopology->Release (); miniTopology = NULL; } // print error message. if (!NT_SUCCESS (ntStatus)) { DOUT (DBG_ERROR, ("Could not create or query TopologyICH")); } } // // Start the wave miniport. // if (NT_SUCCESS (ntStatus)) { #if (NTDDI_VERSION >= NTDDI_VISTA) ntStatus = InstallSubdevice (DeviceObject, Irp, L"Wave", CLSID_PortWaveRT, CLSID_PortWaveRT, // not used CreateAC97MiniportWaveRT, pAdapterCommon, ResourceList, IID_IPortWaveRT, NULL, &unknownWave); if (!NT_SUCCESS (ntStatus)) { #endif // // If creation of the RT port failed we can fall back to the WavePCI // or WaveCyc port of portcls. In this case, we try the WavePCI port. // ntStatus = InstallSubdevice (DeviceObject, Irp, L"Wave", CLSID_PortWavePci, CLSID_PortWavePci, // not used CreateAC97MiniportWavePCI, pAdapterCommon, ResourceList, IID_IPortWavePci, NULL, &unknownWave); #if (NTDDI_VERSION >= NTDDI_VISTA) } #endif // print error message. if (!NT_SUCCESS (ntStatus)) { DOUT (DBG_ERROR, ("WaveRT and WavePCI miniport installation failed!")); } } // // Establish physical connections between filters as shown. // // +------+ +------+ // | Wave | | Topo | // Capture <---|2 3|<===|x |<--- CD // | | | | // Render --->|0 1|===>|y |<--- Line In // | | | | // Mic <---|4 5|<===|z |<--- Mic // +------+ | | // | |---> Line Out // +------+ // // Note that the pin numbers for the nodes to be connected // vary depending on the hardware/codec configuration. // Also, the mic input may or may not be present. // // So, // Do a QI on unknownTopology to get an interface to call // a method on to get the topology miniport pin IDs. if (NT_SUCCESS (ntStatus)) { ULONG ulWaveOut, ulWaveIn, ulMicIn; // get the pin numbers. DOUT (DBG_PRINT, ("Connecting topo and wave.")); ntStatus = pMiniportTopology->GetPhysicalConnectionPins (&ulWaveOut, &ulWaveIn, &ulMicIn); // register wave render connection if (NT_SUCCESS (ntStatus)) { ntStatus = PcRegisterPhysicalConnection (DeviceObject, unknownWave, PIN_WAVEOUT_BRIDGE, unknownTopology, ulWaveOut); // print error message. if (!NT_SUCCESS (ntStatus)) { DOUT (DBG_ERROR, ("Cannot connect topology and wave miniport" " (render)!")); } } if (NT_SUCCESS (ntStatus)) { // register wave capture connection ntStatus = PcRegisterPhysicalConnection (DeviceObject, unknownTopology, ulWaveIn, unknownWave, PIN_WAVEIN_BRIDGE); // print error message. if (!NT_SUCCESS (ntStatus)) { DOUT (DBG_ERROR, ("Cannot connect topology and wave miniport" " (capture)!")); } } if (NT_SUCCESS (ntStatus)) { // register mic capture connection if (pAdapterCommon->GetPinConfig (PINC_MICIN_PRESENT)) { ntStatus = PcRegisterPhysicalConnection (DeviceObject, unknownTopology, ulMicIn, unknownWave, PIN_MICIN_BRIDGE); // print error message. if (!NT_SUCCESS (ntStatus)) { DOUT (DBG_ERROR, ("Cannot connect topology and wave miniport" " (MIC)!")); } } } } // // Release the adapter common object. It either has other references, // or we need to delete it anyway. // if (pAdapterCommon) pAdapterCommon->Release (); // // Release the unknowns. // if (unknownTopology) unknownTopology->Release (); if (unknownWave) unknownWave->Release (); // and the AC97 miniport. if (pMiniportTopology) pMiniportTopology->Release (); return ntStatus; // whatever this is ... }
/***************************************************************************** * StartDevice() ***************************************************************************** * * This function is called by the operating system when the device is started. * It is responsible for starting the miniports. This code is specific to * the adapter because it calls out miniports for functions that are specific * to the adapter. A list of no resources is not the same as a NULL list ptr. * */ NTSTATUS StartDevice ( IN PDEVICE_OBJECT pDeviceObject, // Context for the class driver. IN PIRP pIrp, // Context for the class driver. IN PRESOURCELIST ResourceList // List of hardware resources. ) { PAGED_CODE(); _DbgPrintF(DEBUGLVL_VERBOSE, ("StartDevice")); ASSERT(ResourceList); if (!ResourceList) { return STATUS_INVALID_PARAMETER; } PPORT port; NTSTATUS ntStatus = PcNewPort(&port, CLSID_PortDMus); if (!NT_SUCCESS(ntStatus)) { _DbgPrintF(DEBUGLVL_TERSE,("StartDevice PcNewPort failed (0x%08x)", ntStatus)); return ntStatus; } ASSERT(port); PUNKNOWN miniport; #ifdef USE_OBSOLETE_FUNCS ntStatus = CreateMiniportDmSynth(&miniport, NULL, NonPagedPool); #else ntStatus = CreateMiniportDmSynth(&miniport, NULL, NonPagedPool, pDeviceObject); #endif if (!NT_SUCCESS(ntStatus)) { _DbgPrintF(DEBUGLVL_TERSE,("StartDevice CreateMiniportDmSynth failed (0x%08x)", ntStatus)); port->Release(); return ntStatus; } ASSERT(miniport); ntStatus = port->Init ( pDeviceObject, pIrp, miniport, NULL, ResourceList ); if (!NT_SUCCESS(ntStatus)) { _DbgPrintF(DEBUGLVL_TERSE,("StartDevice port Init failed (0x%08x)", ntStatus)); port->Release(); miniport->Release(); return ntStatus; } ntStatus = PcRegisterSubdevice( pDeviceObject, L"DDKSynth", port); if (!NT_SUCCESS(ntStatus)) { _DbgPrintF(DEBUGLVL_TERSE,("StartDevice PcRegisterSubdevice failed (0x%08x)", ntStatus)); } // // We don't need the miniport any more. Either the port has it, // or we've failed, and it should be deleted. // miniport->Release(); // // Release the reference which existed when PcNewPort() gave us the // pointer in the first place. This is the right thing to do // regardless of the outcome. // port->Release(); return ntStatus; }