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.

424 lines
12 KiB

  1. /**************************************************************************************************************************
  2. * OPENCLOS.C SigmaTel STIR4200 init/shutdown module
  3. **************************************************************************************************************************
  4. * (C) Unpublished Copyright of Sigmatel, Inc. All Rights Reserved.
  5. *
  6. *
  7. * Created: 04/06/2000
  8. * Version 0.9
  9. * Edited: 04/24/2000
  10. * Version 0.91
  11. * Edited: 04/27/2000
  12. * Version 0.92
  13. * Edited: 05/12/2000
  14. * Version 0.94
  15. * Edited: 05/19/2000
  16. * Version 0.95
  17. *
  18. *
  19. **************************************************************************************************************************/
  20. #define DOBREAKS // enable debug breaks
  21. #include <ndis.h>
  22. #include <ntddndis.h> // defines OID's
  23. #include <usbdi.h>
  24. #include <usbdlib.h>
  25. #include "debug.h"
  26. #include "ircommon.h"
  27. #include "irndis.h"
  28. /*****************************************************************************
  29. *
  30. * Function: InitializeDevice
  31. *
  32. * Synopsis: initialize resources for a single IR device object
  33. *
  34. * Arguments: pThisDev - IR device object to initialize
  35. *
  36. * Returns: NDIS_STATUS_SUCCESS - if device is successfully opened
  37. * NDIS_STATUS_RESOURCES - could not claim sufficient
  38. * resources
  39. *
  40. *
  41. * Notes:
  42. * we do a lot of stuff in this open device function
  43. * - allocate packet pool
  44. * - allocate buffer pool
  45. * - allocate packets/buffers/memory and chain together
  46. * (only one buffer per packet)
  47. * - initialize send queue
  48. *
  49. * This function should be called with device lock held.
  50. *
  51. * We don't initialize the following ir device object entries, since
  52. * these values will outlast an reset.
  53. * pUsbDevObj
  54. * hNdisAdapter
  55. * dongleCaps
  56. * fGotFilterIndication
  57. *
  58. *****************************************************************************/
  59. NDIS_STATUS
  60. InitializeDevice(
  61. IN OUT PIR_DEVICE pThisDev
  62. )
  63. {
  64. int i;
  65. NDIS_STATUS status = NDIS_STATUS_SUCCESS;
  66. DEBUGMSG(DBG_FUNC|DBG_PNP, ("+InitializeDevice\n"));
  67. IRUSB_ASSERT( pThisDev != NULL );
  68. //
  69. // Current speed is the default (9600).
  70. //
  71. pThisDev->linkSpeedInfo = &supportedBaudRateTable[BAUDRATE_9600];
  72. pThisDev->currentSpeed = DEFAULT_BAUD_RATE;
  73. //
  74. // Init statistical info.
  75. // We need to do this cause reset won't free and realloc pThisDev!
  76. //
  77. pThisDev->packetsReceived = 0;
  78. pThisDev->packetsReceivedDropped = 0;
  79. pThisDev->packetsReceivedOverflow = 0;
  80. pThisDev->packetsReceivedChecksum = 0;
  81. pThisDev->packetsReceivedRunt = 0;
  82. pThisDev->packetsReceivedNoBuffer = 0;
  83. pThisDev->packetsSent = 0;
  84. pThisDev->packetsSentDropped = 0;
  85. pThisDev->packetsSentRejected = 0;
  86. pThisDev->packetsSentInvalid = 0;
  87. pThisDev->NumDataErrors = 0;
  88. pThisDev->NumReadWriteErrors = 0;
  89. pThisDev->NumReads = 0;
  90. pThisDev->NumWrites = 0;
  91. pThisDev->NumReadWrites = 0;
  92. #if DBG
  93. pThisDev->TotalBytesReceived = 0;
  94. pThisDev->TotalBytesSent = 0;
  95. pThisDev->NumYesQueryMediaBusyOids = 0;
  96. pThisDev->NumNoQueryMediaBusyOids = 0;
  97. pThisDev->NumSetMediaBusyOids = 0;
  98. pThisDev->NumMediaBusyIndications = 0;
  99. pThisDev->packetsHeldByProtocol = 0;
  100. pThisDev->MaxPacketsHeldByProtocol = 0;
  101. pThisDev->NumPacketsSentRequiringTurnaroundTime = 0;
  102. pThisDev->NumPacketsSentNotRequiringTurnaroundTime = 0;
  103. #endif
  104. //
  105. // Variables about the state of the device
  106. //
  107. pThisDev->fDeviceStarted = FALSE;
  108. pThisDev->fGotFilterIndication = FALSE;
  109. pThisDev->fPendingHalt = FALSE;
  110. pThisDev->fPendingReadClearStall = FALSE;
  111. pThisDev->fPendingWriteClearStall = FALSE;
  112. pThisDev->fPendingReset = FALSE;
  113. pThisDev->fPendingClearTotalStall = FALSE;
  114. pThisDev->fKillPollingThread = FALSE;
  115. pThisDev->fKillPassiveLevelThread = FALSE;
  116. pThisDev->LastQueryTime.QuadPart = 0;
  117. pThisDev->LastSetTime.QuadPart = 0;
  118. pThisDev->PendingIrpCount = 0;
  119. //
  120. // OID Set/Query pending
  121. //
  122. pThisDev->fQuerypending = FALSE;
  123. pThisDev->fSetpending = FALSE;
  124. //
  125. // Diags are off
  126. //
  127. #if defined(DIAGS)
  128. pThisDev->DiagsActive = FALSE;
  129. pThisDev->DiagsPendingActivation = FALSE;
  130. #endif
  131. //
  132. // Some more state variables
  133. //
  134. InterlockedExchange( &pThisDev->fMediaBusy, FALSE );
  135. InterlockedExchange( &pThisDev->fIndicatedMediaBusy, FALSE );
  136. pThisDev->pCurrentRecBuf = NULL;
  137. pThisDev->fProcessing = FALSE;
  138. pThisDev->fCurrentlyReceiving = FALSE;
  139. pThisDev->fReadHoldingReg = FALSE;
  140. pThisDev->BaudRateMask = 0xffff; // as per Class Descriptor; may be reset in registry
  141. //
  142. // Initialize the queues.
  143. //
  144. if( TRUE != IrUsb_InitSendStructures( pThisDev ) )
  145. {
  146. DEBUGMSG(DBG_ERR, (" Failed to init WDM objects\n"));
  147. goto done;
  148. }
  149. //
  150. // Allocate the NDIS packet and NDIS buffer pools
  151. // for this device's RECEIVE buffer queue.
  152. // Our receive packets must only contain one buffer a piece,
  153. // so #buffers == #packets.
  154. //
  155. //
  156. // MS security bug #540550
  157. //
  158. pThisDev->hPacketPool = NULL;
  159. NdisAllocatePacketPool(
  160. &status, // return status
  161. &pThisDev->hPacketPool, // handle to the packet pool
  162. NUM_RCV_BUFS, // number of packet descriptors
  163. 16 // number of bytes reserved for ProtocolReserved field
  164. );
  165. if( status != NDIS_STATUS_SUCCESS )
  166. {
  167. DEBUGMSG(DBG_ERR, (" NdisAllocatePacketPool failed. Returned 0x%.8x\n", status));
  168. goto done;
  169. }
  170. NdisAllocateBufferPool(
  171. &status, // return status
  172. &pThisDev->hBufferPool,// handle to the buffer pool
  173. NUM_RCV_BUFS // number of buffer descriptors
  174. );
  175. if( status != NDIS_STATUS_SUCCESS )
  176. {
  177. DEBUGMSG(DBG_ERR, (" NdisAllocateBufferPool failed. Returned 0x%.8x\n", status));
  178. pThisDev->BufferPoolAllocated = FALSE;
  179. goto done;
  180. }
  181. pThisDev->BufferPoolAllocated = TRUE;
  182. //
  183. // Prepare the work items
  184. //
  185. for( i = 0; i < NUM_WORK_ITEMS; i++ )
  186. {
  187. PIR_WORK_ITEM pWorkItem;
  188. pWorkItem = &(pThisDev->WorkItems[i]);
  189. pWorkItem->pIrDevice = pThisDev;
  190. pWorkItem->pInfoBuf = NULL;
  191. pWorkItem->InfoBufLen = 0;
  192. pWorkItem->fInUse = FALSE;
  193. pWorkItem->Callback = NULL;
  194. }
  195. //
  196. // Initialize each of the RECEIVE objects for this device.
  197. //
  198. for( i = 0; i < NUM_RCV_BUFS; i++ )
  199. {
  200. PNDIS_BUFFER pBuffer = NULL;
  201. PRCV_BUFFER pReceivBuffer = &pThisDev->rcvBufs[i];
  202. //
  203. // Allocate a data buffer
  204. //
  205. pReceivBuffer->pDataBuf = MyMemAlloc( MAX_RCV_DATA_SIZE );
  206. if( pReceivBuffer->pDataBuf == NULL )
  207. {
  208. status = NDIS_STATUS_RESOURCES;
  209. goto done;
  210. }
  211. NdisZeroMemory(
  212. pReceivBuffer->pDataBuf,
  213. MAX_RCV_DATA_SIZE
  214. );
  215. pReceivBuffer->pThisDev = pThisDev;
  216. pReceivBuffer->DataLen = 0;
  217. pReceivBuffer->BufferState = RCV_STATE_FREE;
  218. #if defined(WORKAROUND_MISSING_C1)
  219. pReceivBuffer->MissingC1Detected = FALSE;
  220. pReceivBuffer->MissingC1Possible = FALSE;
  221. #endif
  222. //
  223. // Allocate the NDIS_PACKET.
  224. //
  225. NdisAllocatePacket(
  226. &status, // return status
  227. &((PNDIS_PACKET)pReceivBuffer->pPacket), // return pointer to allocated descriptor
  228. pThisDev->hPacketPool // handle to packet pool
  229. );
  230. if( status != NDIS_STATUS_SUCCESS )
  231. {
  232. DEBUGMSG(DBG_ERR, (" NdisAllocatePacket failed. Returned 0x%.8x\n", status));
  233. goto done;
  234. }
  235. }
  236. //
  237. // These are the receive objects for the USB
  238. //
  239. pThisDev->PreReadBuffer.pDataBuf = MyMemAlloc( STIR4200_FIFO_SIZE );
  240. if( pThisDev->PreReadBuffer.pDataBuf == NULL )
  241. {
  242. status = NDIS_STATUS_RESOURCES;
  243. goto done;
  244. }
  245. NdisZeroMemory(
  246. pThisDev->PreReadBuffer.pDataBuf,
  247. STIR4200_FIFO_SIZE
  248. );
  249. pThisDev->PreReadBuffer.pThisDev = pThisDev;
  250. pThisDev->PreReadBuffer.DataLen = 0;
  251. pThisDev->PreReadBuffer.BufferState = RCV_STATE_FREE;
  252. //
  253. // Synchronization events
  254. //
  255. KeInitializeEvent(
  256. &pThisDev->EventSyncUrb,
  257. NotificationEvent, // non-auto-clearing event
  258. FALSE // event initially non-signalled
  259. );
  260. KeInitializeEvent(
  261. &pThisDev->EventAsyncUrb,
  262. NotificationEvent, // non-auto-clearing event
  263. FALSE // event initially non-signalled
  264. );
  265. done:
  266. //
  267. // If we didn't complete the init successfully, then we should clean
  268. // up what we did allocate.
  269. //
  270. if( status != NDIS_STATUS_SUCCESS )
  271. {
  272. DEBUGMSG(DBG_ERR, (" InitializeDevice() FAILED\n"));
  273. DeinitializeDevice(pThisDev);
  274. }
  275. else
  276. {
  277. DEBUGMSG(DBG_OUT, (" InitializeDevice() SUCCEEDED\n"));
  278. }
  279. DEBUGMSG(DBG_FUNC|DBG_PNP, ("-InitializeDevice()\n"));
  280. return status;
  281. }
  282. /*****************************************************************************
  283. *
  284. * Function: DeinitializeDevice
  285. *
  286. * Synopsis: deallocate the resources of the IR device object
  287. *
  288. * Arguments: pThisDev - the IR device object to close
  289. *
  290. * Returns: none
  291. *
  292. *
  293. * Notes:
  294. *
  295. * Called for shutdown and reset.
  296. * Don't clear hNdisAdapter, since we might just be resetting.
  297. * This function should be called with device lock held.
  298. *
  299. *****************************************************************************/
  300. VOID
  301. DeinitializeDevice(
  302. IN OUT PIR_DEVICE pThisDev
  303. )
  304. {
  305. UINT i;
  306. DEBUGMSG( DBG_FUNC|DBG_PNP, ("+DeinitializeDevice\n"));
  307. pThisDev->linkSpeedInfo = NULL;
  308. //
  309. // Free all resources for the RECEIVE buffer queue.
  310. //
  311. for( i = 0; i < NUM_RCV_BUFS; i++ )
  312. {
  313. PNDIS_BUFFER pBuffer = NULL;
  314. PRCV_BUFFER pRcvBuf = &pThisDev->rcvBufs[i];
  315. if( pRcvBuf->pPacket != NULL )
  316. {
  317. NdisFreePacket( (PNDIS_PACKET)pRcvBuf->pPacket );
  318. pRcvBuf->pPacket = NULL;
  319. }
  320. if( pRcvBuf->pDataBuf != NULL )
  321. {
  322. MyMemFree( pRcvBuf->pDataBuf, MAX_RCV_DATA_SIZE );
  323. pRcvBuf->pDataBuf = NULL;
  324. }
  325. pRcvBuf->DataLen = 0;
  326. }
  327. //
  328. // Deallocate the USB receive buffers
  329. //
  330. if( pThisDev->PreReadBuffer.pDataBuf != NULL )
  331. MyMemFree( pThisDev->PreReadBuffer.pDataBuf, STIR4200_FIFO_SIZE );
  332. //
  333. // Free the packet and buffer pool handles for this device.
  334. //
  335. if( pThisDev->hPacketPool )
  336. {
  337. NdisFreePacketPool( pThisDev->hPacketPool );
  338. pThisDev->hPacketPool = NULL;
  339. }
  340. if( pThisDev->BufferPoolAllocated )
  341. {
  342. NdisFreeBufferPool( pThisDev->hBufferPool );
  343. pThisDev->BufferPoolAllocated = FALSE;
  344. }
  345. if( pThisDev->fDeviceStarted )
  346. {
  347. NTSTATUS ntstatus;
  348. ntstatus = IrUsb_StopDevice( pThisDev );
  349. DEBUGMSG(DBG_FUNC, (" DeinitializeDevice IrUsb_StopDevice() status = 0x%x\n",ntstatus));
  350. }
  351. InterlockedExchange( &pThisDev->fMediaBusy, FALSE );
  352. InterlockedExchange( &pThisDev->fIndicatedMediaBusy, FALSE );
  353. IrUsb_FreeSendStructures( pThisDev );
  354. DEBUGMSG(DBG_FUNC|DBG_PNP, ("-DeinitializeDevice\n"));
  355. }