Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

532 lines
13 KiB

  1. /*++
  2. Copyright (c) 1997-2000 Microsoft Corporation All Rights Reserved
  3. Module Name:
  4. adapter.cpp
  5. Abstract:
  6. Setup and miniport installation. No resources are used by msvad.
  7. --*/
  8. //
  9. // All the GUIDS for all the miniports end up in this object.
  10. //
  11. #define PUT_GUIDS_HERE
  12. #include <msvad.h>
  13. #include "common.h"
  14. //-----------------------------------------------------------------------------
  15. // Defines
  16. //-----------------------------------------------------------------------------
  17. // BUGBUG set this to number of miniports
  18. #define MAX_MINIPORTS 3 // Number of maximum miniports.
  19. //-----------------------------------------------------------------------------
  20. // Externals
  21. //-----------------------------------------------------------------------------
  22. NTSTATUS
  23. CreateMiniportWaveCyclicMSVAD
  24. (
  25. OUT PUNKNOWN *,
  26. IN REFCLSID,
  27. IN PUNKNOWN,
  28. IN POOL_TYPE
  29. );
  30. NTSTATUS
  31. CreateMiniportTopologyMSVAD
  32. (
  33. OUT PUNKNOWN *,
  34. IN REFCLSID,
  35. IN PUNKNOWN,
  36. IN POOL_TYPE
  37. );
  38. //-----------------------------------------------------------------------------
  39. // Referenced forward.
  40. //-----------------------------------------------------------------------------
  41. extern "C" NTSTATUS
  42. AddDevice
  43. (
  44. IN PDRIVER_OBJECT,
  45. IN PDEVICE_OBJECT
  46. );
  47. NTSTATUS
  48. StartDevice
  49. (
  50. IN PDEVICE_OBJECT,
  51. IN PIRP,
  52. IN PRESOURCELIST
  53. );
  54. //-----------------------------------------------------------------------------
  55. // Functions
  56. //-----------------------------------------------------------------------------
  57. //=============================================================================
  58. #pragma code_seg("INIT")
  59. extern "C" NTSTATUS
  60. DriverEntry
  61. (
  62. IN PDRIVER_OBJECT DriverObject,
  63. IN PUNICODE_STRING RegistryPathName
  64. )
  65. {
  66. /*++
  67. Routine Description:
  68. Installable driver initialization entry point.
  69. This entry point is called directly by the I/O system.
  70. All audio adapter drivers can use this code without change.
  71. Arguments:
  72. DriverObject - pointer to the driver object
  73. RegistryPath - pointer to a unicode string representing the path,
  74. to driver-specific key in the registry.
  75. Return Value:
  76. STATUS_SUCCESS if successful,
  77. STATUS_UNSUCCESSFUL otherwise.
  78. --*/
  79. PAGED_CODE();
  80. NTSTATUS ntStatus;
  81. DPF(D_TERSE, ("[DriverEntry]"));
  82. // Tell the class driver to initialize the driver.
  83. //
  84. ntStatus =
  85. PcInitializeAdapterDriver
  86. (
  87. DriverObject,
  88. RegistryPathName,
  89. AddDevice
  90. );
  91. return ntStatus;
  92. } // DriverEntry
  93. #pragma code_seg()
  94. #pragma code_seg("PAGE")
  95. //=============================================================================
  96. extern "C" NTSTATUS
  97. AddDevice
  98. (
  99. IN PDRIVER_OBJECT DriverObject,
  100. IN PDEVICE_OBJECT PhysicalDeviceObject
  101. )
  102. /*++
  103. Routine Description:
  104. The Plug & Play subsystem is handing us a brand new PDO, for which we
  105. (by means of INF registration) have been asked to provide a driver.
  106. We need to determine if we need to be in the driver stack for the device.
  107. Create a function device object to attach to the stack
  108. Initialize that device object
  109. Return status success.
  110. All audio adapter drivers can use this code without change.
  111. Set MAX_MINIPORTS depending on the number of miniports that the driver
  112. uses.
  113. Arguments:
  114. DriverObject - pointer to a driver object
  115. PhysicalDeviceObject - pointer to a device object created by the
  116. underlying bus driver.
  117. Return Value:
  118. NT status code.
  119. --*/
  120. {
  121. PAGED_CODE();
  122. NTSTATUS ntStatus;
  123. DPF(D_TERSE, ("[AddDevice]"));
  124. // Tell the class driver to add the device.
  125. //
  126. ntStatus =
  127. PcAddAdapterDevice
  128. (
  129. DriverObject,
  130. PhysicalDeviceObject,
  131. PCPFNSTARTDEVICE(StartDevice),
  132. MAX_MINIPORTS,
  133. 0
  134. );
  135. return ntStatus;
  136. } // AddDevice
  137. //=============================================================================
  138. NTSTATUS
  139. InstallSubdevice
  140. (
  141. IN PDEVICE_OBJECT DeviceObject,
  142. IN PIRP Irp,
  143. IN PWCHAR Name,
  144. IN REFGUID PortClassId,
  145. IN REFGUID MiniportClassId,
  146. IN PFNCREATEINSTANCE MiniportCreate OPTIONAL,
  147. IN PUNKNOWN UnknownAdapter OPTIONAL,
  148. IN PRESOURCELIST ResourceList,
  149. IN REFGUID PortInterfaceId,
  150. OUT PUNKNOWN * OutPortInterface OPTIONAL,
  151. OUT PUNKNOWN * OutPortUnknown OPTIONAL
  152. )
  153. {
  154. /*++
  155. Routine Description:
  156. This function creates and registers a subdevice consisting of a port
  157. driver, a minport driver and a set of resources bound together. It will
  158. also optionally place a pointer to an interface on the port driver in a
  159. specified location before initializing the port driver. This is done so
  160. that a common ISR can have access to the port driver during
  161. initialization, when the ISR might fire.
  162. Arguments:
  163. DeviceObject - pointer to the driver object
  164. Irp - pointer to the irp object.
  165. Name - name of the miniport. Passes to PcRegisterSubDevice
  166. PortClassId - port class id. Passed to PcNewPort.
  167. MiniportClassId - miniport class id. Passed to PcNewMiniport.
  168. MiniportCreate - pointer to a miniport creation function. If NULL,
  169. PcNewMiniport is used.
  170. UnknownAdapter - pointer to the adapter object.
  171. Used for initializing the port.
  172. ResourceList - pointer to the resource list.
  173. PortInterfaceId - GUID that represents the port interface.
  174. OutPortInterface - pointer to store the port interface
  175. OutPortUnknown - pointer to store the unknown port interface.
  176. Return Value:
  177. NT status code.
  178. --*/
  179. PAGED_CODE();
  180. ASSERT(DeviceObject);
  181. ASSERT(Irp);
  182. ASSERT(Name);
  183. NTSTATUS ntStatus;
  184. PPORT port = NULL;
  185. PUNKNOWN miniport = NULL;
  186. DPF_ENTER(("[InstallSubDevice %s]", Name));
  187. // Create the port driver object
  188. //
  189. ntStatus = PcNewPort(&port, PortClassId);
  190. // Create the miniport object
  191. //
  192. if (NT_SUCCESS(ntStatus))
  193. {
  194. if (MiniportCreate)
  195. {
  196. ntStatus =
  197. MiniportCreate
  198. (
  199. &miniport,
  200. MiniportClassId,
  201. NULL,
  202. NonPagedPool
  203. );
  204. }
  205. else
  206. {
  207. ntStatus =
  208. PcNewMiniport
  209. (
  210. (PMINIPORT *) &miniport,
  211. MiniportClassId
  212. );
  213. }
  214. }
  215. // Init the port driver and miniport in one go.
  216. //
  217. if (NT_SUCCESS(ntStatus))
  218. {
  219. ntStatus =
  220. port->Init
  221. (
  222. DeviceObject,
  223. Irp,
  224. miniport,
  225. UnknownAdapter,
  226. ResourceList
  227. );
  228. if (NT_SUCCESS(ntStatus))
  229. {
  230. // Register the subdevice (port/miniport combination).
  231. //
  232. ntStatus =
  233. PcRegisterSubdevice
  234. (
  235. DeviceObject,
  236. Name,
  237. port
  238. );
  239. }
  240. // We don't need the miniport any more. Either the port has it,
  241. // or we've failed, and it should be deleted.
  242. //
  243. miniport->Release();
  244. }
  245. // Deposit the port interfaces if it's needed.
  246. //
  247. if (NT_SUCCESS(ntStatus))
  248. {
  249. if (OutPortUnknown)
  250. {
  251. ntStatus =
  252. port->QueryInterface
  253. (
  254. IID_IUnknown,
  255. (PVOID *)OutPortUnknown
  256. );
  257. }
  258. if (OutPortInterface)
  259. {
  260. ntStatus =
  261. port->QueryInterface
  262. (
  263. PortInterfaceId,
  264. (PVOID *) OutPortInterface
  265. );
  266. }
  267. }
  268. if (port)
  269. {
  270. port->Release();
  271. }
  272. return ntStatus;
  273. } // InstallSubDevice
  274. //=============================================================================
  275. NTSTATUS
  276. StartDevice
  277. (
  278. IN PDEVICE_OBJECT DeviceObject,
  279. IN PIRP Irp,
  280. IN PRESOURCELIST ResourceList
  281. )
  282. {
  283. /*++
  284. Routine Description:
  285. This function is called by the operating system when the device is
  286. started.
  287. It is responsible for starting the miniports. This code is specific to
  288. the adapter because it calls out miniports for functions that are specific
  289. to the adapter.
  290. Arguments:
  291. DeviceObject - pointer to the driver object
  292. Irp - pointer to the irp
  293. ResourceList - pointer to the resource list assigned by PnP manager
  294. Return Value:
  295. NT status code.
  296. --*/
  297. PAGED_CODE();
  298. ASSERT(DeviceObject);
  299. ASSERT(Irp);
  300. ASSERT(ResourceList);
  301. NTSTATUS ntStatus = STATUS_SUCCESS;
  302. PUNKNOWN unknownTopology = NULL;
  303. PUNKNOWN unknownWave = NULL;
  304. PADAPTERCOMMON pAdapterCommon = NULL;
  305. PUNKNOWN pUnknownCommon = NULL;
  306. DPF_ENTER(("[StartDevice]"));
  307. // create a new adapter common object
  308. //
  309. ntStatus =
  310. NewAdapterCommon
  311. (
  312. &pUnknownCommon,
  313. IID_IAdapterCommon,
  314. NULL,
  315. NonPagedPool
  316. );
  317. if (NT_SUCCESS(ntStatus))
  318. {
  319. ntStatus =
  320. pUnknownCommon->QueryInterface
  321. (
  322. IID_IAdapterCommon,
  323. (PVOID *) &pAdapterCommon
  324. );
  325. if (NT_SUCCESS(ntStatus))
  326. {
  327. ntStatus =
  328. pAdapterCommon->Init(DeviceObject);
  329. if (NT_SUCCESS(ntStatus))
  330. {
  331. // register with PortCls for power-management services
  332. //
  333. ntStatus =
  334. PcRegisterAdapterPowerManagement
  335. (
  336. PUNKNOWN(pAdapterCommon),
  337. DeviceObject
  338. );
  339. }
  340. }
  341. }
  342. // install MSVAD topology miniport.
  343. //
  344. if (NT_SUCCESS(ntStatus))
  345. {
  346. ntStatus =
  347. InstallSubdevice
  348. (
  349. DeviceObject,
  350. Irp,
  351. L"Topology",
  352. CLSID_PortTopology,
  353. CLSID_PortTopology,
  354. CreateMiniportTopologyMSVAD,
  355. pAdapterCommon,
  356. NULL,
  357. IID_IPortTopology,
  358. NULL,
  359. &unknownTopology
  360. );
  361. }
  362. // install MSVAD wavecyclic miniport.
  363. //
  364. if (NT_SUCCESS(ntStatus))
  365. {
  366. ntStatus =
  367. InstallSubdevice
  368. (
  369. DeviceObject,
  370. Irp,
  371. L"Wave",
  372. CLSID_PortWaveCyclic,
  373. CLSID_PortWaveCyclic,
  374. CreateMiniportWaveCyclicMSVAD,
  375. pAdapterCommon,
  376. NULL,
  377. IID_IPortWaveCyclic,
  378. pAdapterCommon->WavePortDriverDest(),
  379. &unknownWave
  380. );
  381. }
  382. if (unknownTopology && unknownWave)
  383. {
  384. // register wave <=> topology connections
  385. // This will connect bridge pins of wavecyclic and topology
  386. // miniports.
  387. //
  388. ntStatus =
  389. PcRegisterPhysicalConnection
  390. (
  391. DeviceObject,
  392. unknownTopology,
  393. TopologyPhysicalConnections.ulTopologyOut,
  394. unknownWave,
  395. TopologyPhysicalConnections.ulWaveIn
  396. );
  397. if (NT_SUCCESS(ntStatus))
  398. {
  399. ntStatus =
  400. PcRegisterPhysicalConnection
  401. (
  402. DeviceObject,
  403. unknownWave,
  404. TopologyPhysicalConnections.ulWaveOut,
  405. unknownTopology,
  406. TopologyPhysicalConnections.ulTopologyIn
  407. );
  408. }
  409. }
  410. // Release the adapter common object. It either has other references,
  411. // or we need to delete it anyway.
  412. //
  413. if (pAdapterCommon)
  414. {
  415. pAdapterCommon->Release();
  416. }
  417. if (pUnknownCommon)
  418. {
  419. pUnknownCommon->Release();
  420. }
  421. if (unknownTopology)
  422. {
  423. unknownTopology->Release();
  424. }
  425. if (unknownWave)
  426. {
  427. unknownWave->Release();
  428. }
  429. return ntStatus;
  430. } // StartDevice
  431. #pragma code_seg()