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.

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