Leaked source code of windows server 2003
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.

339 lines
12 KiB

  1. //==========================================================================;
  2. //
  3. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  4. // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  5. // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  6. // PURPOSE.
  7. //
  8. // Copyright (c) 1992 - 1996 Microsoft Corporation. All Rights Reserved.
  9. //
  10. // ATITVSnd.CPP
  11. // WDM TV Audio MiniDriver.
  12. // AllInWonder/AllInWonderPro development platform.
  13. // Main Source Module.
  14. //
  15. // $Date: 01 Apr 1998 13:29:14 $
  16. // $Revision: 1.1 $
  17. // $Author: KLEBANOV $
  18. //
  19. //==========================================================================;
  20. extern "C"
  21. {
  22. #include "strmini.h"
  23. #include "ksmedia.h"
  24. #include "wdmdebug.h"
  25. }
  26. #include "atitvsnd.h"
  27. #include "wdmdrv.h"
  28. /*^^*
  29. * DriverEntry()
  30. * Purpose : Called when an SRB_INITIALIZE_DEVICE request is received
  31. *
  32. * Inputs : PVOID Arg1, PVOID Arg2
  33. *
  34. * Outputs : result of StreamClassregisterAdapter()
  35. * Author : IKLEBANOV
  36. *^^*/
  37. extern "C"
  38. ULONG DriverEntry ( IN PDRIVER_OBJECT pDriverObject,
  39. IN PUNICODE_STRING pRegistryPath )
  40. {
  41. HW_INITIALIZATION_DATA HwInitData;
  42. SetMiniDriverDebugLevel( pRegistryPath);
  43. OutputDebugTrace(( "ATITVSnd: DriverEntry\n"));
  44. RtlZeroMemory( &HwInitData, sizeof( HwInitData));
  45. HwInitData.HwInitializationDataSize = sizeof(HwInitData);
  46. // Entry points for Port Driver
  47. HwInitData.HwInterrupt = NULL; // HwInterrupt;
  48. HwInitData.HwReceivePacket = TVAudioReceivePacket;
  49. HwInitData.HwCancelPacket = TVAudioCancelPacket;
  50. HwInitData.HwRequestTimeoutHandler = TVAudioTimeoutPacket;
  51. HwInitData.DeviceExtensionSize = sizeof( ADAPTER_DATA_EXTENSION);
  52. HwInitData.PerRequestExtensionSize = sizeof( SRB_DATA_EXTENSION);
  53. HwInitData.FilterInstanceExtensionSize = 0;
  54. HwInitData.PerStreamExtensionSize = 0;
  55. HwInitData.BusMasterDMA = FALSE;
  56. HwInitData.Dma24BitAddresses = FALSE;
  57. HwInitData.BufferAlignment = 3;
  58. // HwInitData.TurnOffSynchronization = FALSE;
  59. // we turn the synchronization ON. StreamClass is expected to call the MiniDriver
  60. // at passive level only
  61. HwInitData.TurnOffSynchronization = TRUE;
  62. HwInitData.DmaBufferSize = 0;
  63. OutputDebugTrace(( "ATITVSnd: StreamClassRegisterAdapter\n"));
  64. return( StreamClassRegisterAdapter( pDriverObject, pRegistryPath, &HwInitData));
  65. }
  66. /*^^*
  67. * TVAudioReceivePacket()
  68. * Purpose : Main entry point for receiving adapter based request SRBs from the Class Driver.
  69. * Will always be called at passive level, because the drivers
  70. * turned the synchronization ON.
  71. * Note : This is an asyncronous entry point. The request only completes when a
  72. * StreamClassDeviceNotification on this SRB, of type DeviceRequestComplete,
  73. * is issued. As soon we're running at passive level, we can do everything
  74. * synchronously during the response to the SRBs with no worry
  75. * to block somebody else for a long timer during I2C access
  76. *
  77. * Inputs : PHW_STREAM_REQUEST_BLOCK pSrb : pointer to the current Srb
  78. *
  79. * Outputs : none
  80. * Author : IKLEBANOV
  81. *^^*/
  82. extern "C"
  83. void STREAMAPI TVAudioReceivePacket( IN OUT PHW_STREAM_REQUEST_BLOCK pSrb)
  84. {
  85. CWDMTVAudio * pCTVAudio;
  86. KIRQL irqlCurrent;
  87. PADAPTER_DATA_EXTENSION pPrivateData = ( PADAPTER_DATA_EXTENSION)( pSrb->HwDeviceExtension);
  88. PSRB_DATA_EXTENSION pSrbPrivate = ( PSRB_DATA_EXTENSION)( pSrb->SRBExtension);
  89. // check the device extension pointer
  90. if(( pPrivateData == NULL) || ( pSrbPrivate == NULL))
  91. {
  92. TRAP;
  93. pSrb->Status = STATUS_INVALID_PARAMETER;
  94. StreamClassDeviceNotification( DeviceRequestComplete, pSrb->HwDeviceExtension, pSrb);
  95. }
  96. OutputDebugInfo(( "ATITVSnd: TVAudioReceivePacket() SRB = %x\n", pSrb));
  97. if( pSrb->Command == SRB_INITIALIZE_DEVICE)
  98. {
  99. // this is the special case for SRB_INITIALIZE_DEVICE, because
  100. // no Queue has been initialized yet. Everything we need later on
  101. // is initialized during this SRB response
  102. TVAudioAdapterInitialize( pSrb);
  103. StreamClassDeviceNotification( DeviceRequestComplete, pSrb->HwDeviceExtension, pSrb);
  104. return;
  105. }
  106. // the rest of the SRBs are coming after SpinLock and SRBQueue have been initialized
  107. // during DRB_INITIALIZE_DEVICE SRB response.
  108. // I'll insert the SRB in the Queue first of all. The processing SRB from the Queue
  109. // can be triggered by finishing processing and SRB, or by the fact there is no SRB
  110. // is in process down here
  111. pSrbPrivate->pSrb = pSrb;
  112. // Everything we're doing with the Queue has to be protected from being interrupted
  113. KeAcquireSpinLock( &pPrivateData->adapterSpinLock, &irqlCurrent);
  114. InsertTailList( &pPrivateData->adapterSrbQueueHead, &pSrbPrivate->srbListEntry);
  115. if( pPrivateData->bSrbInProcess)
  116. {
  117. // there is another SRB being processed, and the new one will be picked up from
  118. // the Queue when it's its turn.
  119. KeReleaseSpinLock( &pPrivateData->adapterSpinLock, irqlCurrent);
  120. return;
  121. }
  122. while( !IsListEmpty( &pPrivateData->adapterSrbQueueHead))
  123. {
  124. // turn on the semaphore for the others coming after
  125. pPrivateData->bSrbInProcess = TRUE;
  126. // be carefull here, if you've changed the place where srbListEntry is defined
  127. // within the SRB_DATA_EXTENSION structure
  128. pSrbPrivate = ( PSRB_DATA_EXTENSION)RemoveHeadList( &pPrivateData->adapterSrbQueueHead);
  129. KeReleaseSpinLock( &pPrivateData->adapterSpinLock, irqlCurrent);
  130. // here is the place to process the SRB we have retrieved from the Queue
  131. pSrb = pSrbPrivate->pSrb;
  132. pPrivateData = ( PADAPTER_DATA_EXTENSION)( pSrb->HwDeviceExtension);
  133. pCTVAudio = &pPrivateData->CTVAudio;
  134. ASSERT( pSrb->Status != STATUS_CANCELLED);
  135. switch( pSrb->Command)
  136. {
  137. case SRB_INITIALIZATION_COMPLETE:
  138. // StreamClass has completed the initialization
  139. pSrb->Status = pCTVAudio->AdapterCompleteInitialization( pSrb);
  140. break;
  141. case SRB_UNINITIALIZE_DEVICE:
  142. // close the device.
  143. pCTVAudio->AdapterUnInitialize( pSrb);
  144. break;
  145. case SRB_OPEN_STREAM:
  146. case SRB_CLOSE_STREAM:
  147. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  148. break;
  149. case SRB_GET_STREAM_INFO:
  150. // return a block describing STREAM_INFO_HEADER and all the streams supported
  151. pCTVAudio->AdapterGetStreamInfo( pSrb);
  152. break;
  153. case SRB_CHANGE_POWER_STATE:
  154. pSrb->Status = pCTVAudio->AdapterSetPowerState( pSrb);
  155. break;
  156. case SRB_GET_DEVICE_PROPERTY:
  157. if( pCTVAudio->AdapterGetProperty( pSrb))
  158. pSrb->Status = STATUS_SUCCESS;
  159. else
  160. pSrb->Status = STATUS_INVALID_PARAMETER;
  161. break;
  162. case SRB_SET_DEVICE_PROPERTY:
  163. if( pCTVAudio->AdapterSetProperty( pSrb))
  164. pSrb->Status = STATUS_SUCCESS;
  165. else
  166. pSrb->Status = STATUS_INVALID_PARAMETER;
  167. break;
  168. // We should never get the following since this is a single instance device
  169. case SRB_OPEN_DEVICE_INSTANCE:
  170. case SRB_CLOSE_DEVICE_INSTANCE:
  171. TRAP
  172. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  173. break;
  174. case SRB_UNKNOWN_DEVICE_COMMAND:
  175. // we know we're getting some of these. Why should we?
  176. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  177. break;
  178. default:
  179. // TRAP
  180. // this is a request that we do not understand. Indicate invalid command and complete the request
  181. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  182. }
  183. StreamClassDeviceNotification( DeviceRequestComplete, pPrivateData, pSrb);
  184. KeAcquireSpinLock( &pPrivateData->adapterSpinLock, &irqlCurrent);
  185. }
  186. // turn off the semaphore to enable the others coming after
  187. pPrivateData->bSrbInProcess = FALSE;
  188. KeReleaseSpinLock( &pPrivateData->adapterSpinLock, irqlCurrent);
  189. // there is no other SRB being processed at this time, let's start processing
  190. }
  191. extern "C"
  192. void STREAMAPI TVAudioCancelPacket( IN OUT PHW_STREAM_REQUEST_BLOCK pSrb)
  193. {
  194. pSrb->Status = STATUS_CANCELLED;
  195. }
  196. extern "C"
  197. void STREAMAPI TVAudioTimeoutPacket( IN OUT PHW_STREAM_REQUEST_BLOCK pSrb)
  198. {
  199. // not sure what to do here.
  200. }
  201. /*^^*
  202. * TVAudioAdapterInitialize()
  203. * Purpose : Called when SRB_INITIALIZE_DEVICE SRB is received.
  204. * Performs checking of the hardware presence and I2C provider availability.
  205. * Sets the hardware in an initial state.
  206. * Note : The request does not completed unless we know everything
  207. * about the hardware and we are sure it is capable to work in the current configuration.
  208. * The hardware Caps are also aquised at this point. As soon this
  209. * function is called at passive level, do everything synchronously
  210. *
  211. * Inputs : PHW_STREAM_REQUEST_BLOCK pSrb : pointer to the current Srb
  212. *
  213. * Outputs : none
  214. * Author : IKLEBANOV
  215. *^^*/
  216. void TVAudioAdapterInitialize( IN OUT PHW_STREAM_REQUEST_BLOCK pSrb)
  217. {
  218. PPORT_CONFIGURATION_INFORMATION pConfigInfo = pSrb->CommandData.ConfigInfo;
  219. PADAPTER_DATA_EXTENSION pPrivateData = ( PADAPTER_DATA_EXTENSION)( pConfigInfo->HwDeviceExtension);
  220. NTSTATUS ntStatus = STATUS_NO_SUCH_DEVICE;
  221. CWDMTVAudio * pCTVAudio;
  222. CI2CScript * pCScript = NULL;
  223. UINT nErrorCode;
  224. OutputDebugTrace(( "ATITVSnd: TVAudioAdapterInitialize()\n"));
  225. ENSURE
  226. {
  227. if( pConfigInfo->NumberOfAccessRanges != 0)
  228. {
  229. OutputDebugError(( "ATITVSnd: illegal NumberOfAccessRanges = %lx\n", pConfigInfo->NumberOfAccessRanges));
  230. FAIL;
  231. }
  232. // if we have I2CProvider implemented inside the MiniVDD, we have to
  233. // get a pointer to I2CInterface from the Provider.
  234. // There is an overloaded operator new provided for the CI2CScript Class.
  235. pCScript = ( CI2CScript *)new(( PVOID)&pPrivateData->CScript)
  236. CI2CScript( pConfigInfo, &nErrorCode);
  237. if( nErrorCode != WDMMINI_NOERROR)
  238. {
  239. OutputDebugError(( "ATITVSnd: CI2CScript creation failure = %lx\n", nErrorCode));
  240. FAIL;
  241. }
  242. // The CI2CScript object was created successfully.
  243. // We'll try to allocate I2CProvider here for future possible I2C
  244. // operations needed at Initialization time.
  245. if( !pCScript->LockI2CProviderEx())
  246. {
  247. OutputDebugError(( "ATITVSnd: unable to lock I2CProvider"));
  248. FAIL;
  249. }
  250. // we did lock the provider.
  251. // There is an overloaded operator new provided for the CWDMTVAudio Class.
  252. pCTVAudio = ( CWDMTVAudio *)new(( PVOID)&pPrivateData->CTVAudio) CWDMTVAudio( pConfigInfo, pCScript, &nErrorCode);
  253. if( nErrorCode)
  254. {
  255. OutputDebugError(( "ATITVSnd: CWDMTVAudio constructor failure = %lx\n", nErrorCode));
  256. FAIL;
  257. }
  258. InitializeListHead ( &pPrivateData->adapterSrbQueueHead);
  259. KeInitializeSpinLock ( &pPrivateData->adapterSpinLock);
  260. pPrivateData->PhysicalDeviceObject = pConfigInfo->RealPhysicalDeviceObject;
  261. // no streams are supported
  262. pConfigInfo->StreamDescriptorSize = sizeof( HW_STREAM_HEADER);
  263. OutputDebugTrace(( "TVAudioAdapterInitialize(): exit\n"));
  264. ntStatus = STATUS_SUCCESS;
  265. } END_ENSURE;
  266. if (pCScript)
  267. pCScript->ReleaseI2CProvider();
  268. pSrb->Status = ntStatus;
  269. return;
  270. }