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.

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