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.

417 lines
11 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. NdisAllocatePacketPool(
  156. &status, // return status
  157. &pThisDev->hPacketPool, // handle to the packet pool
  158. NUM_RCV_BUFS, // number of packet descriptors
  159. 16 // number of bytes reserved for ProtocolReserved field
  160. );
  161. if( status != NDIS_STATUS_SUCCESS )
  162. {
  163. DEBUGMSG(DBG_ERR, (" NdisAllocatePacketPool failed. Returned 0x%.8x\n", status));
  164. goto done;
  165. }
  166. NdisAllocateBufferPool(
  167. &status, // return status
  168. &pThisDev->hBufferPool,// handle to the buffer pool
  169. NUM_RCV_BUFS // number of buffer descriptors
  170. );
  171. if( status != NDIS_STATUS_SUCCESS )
  172. {
  173. DEBUGMSG(DBG_ERR, (" NdisAllocateBufferPool failed. Returned 0x%.8x\n", status));
  174. pThisDev->BufferPoolAllocated = FALSE;
  175. goto done;
  176. }
  177. pThisDev->BufferPoolAllocated = TRUE;
  178. //
  179. // Prepare the work items
  180. //
  181. for( i = 0; i < NUM_WORK_ITEMS; i++ )
  182. {
  183. PIR_WORK_ITEM pWorkItem;
  184. pWorkItem = &(pThisDev->WorkItems[i]);
  185. pWorkItem->pIrDevice = pThisDev;
  186. pWorkItem->pInfoBuf = NULL;
  187. pWorkItem->InfoBufLen = 0;
  188. pWorkItem->fInUse = FALSE;
  189. pWorkItem->Callback = NULL;
  190. }
  191. //
  192. // Initialize each of the RECEIVE objects for this device.
  193. //
  194. for( i = 0; i < NUM_RCV_BUFS; i++ )
  195. {
  196. PNDIS_BUFFER pBuffer = NULL;
  197. PRCV_BUFFER pReceivBuffer = &pThisDev->rcvBufs[i];
  198. //
  199. // Allocate a data buffer
  200. //
  201. pReceivBuffer->pDataBuf = MyMemAlloc( MAX_RCV_DATA_SIZE );
  202. if( pReceivBuffer->pDataBuf == NULL )
  203. {
  204. status = NDIS_STATUS_RESOURCES;
  205. goto done;
  206. }
  207. NdisZeroMemory(
  208. pReceivBuffer->pDataBuf,
  209. MAX_RCV_DATA_SIZE
  210. );
  211. pReceivBuffer->pThisDev = pThisDev;
  212. pReceivBuffer->DataLen = 0;
  213. pReceivBuffer->BufferState = RCV_STATE_FREE;
  214. #if defined(WORKAROUND_MISSING_C1)
  215. pReceivBuffer->MissingC1Detected = FALSE;
  216. #endif
  217. //
  218. // Allocate the NDIS_PACKET.
  219. //
  220. NdisAllocatePacket(
  221. &status, // return status
  222. &((PNDIS_PACKET)pReceivBuffer->pPacket), // return pointer to allocated descriptor
  223. pThisDev->hPacketPool // handle to packet pool
  224. );
  225. if( status != NDIS_STATUS_SUCCESS )
  226. {
  227. DEBUGMSG(DBG_ERR, (" NdisAllocatePacket failed. Returned 0x%.8x\n", status));
  228. goto done;
  229. }
  230. }
  231. //
  232. // These are the receive objects for the USB
  233. //
  234. pThisDev->PreReadBuffer.pDataBuf = MyMemAlloc( STIR4200_FIFO_SIZE );
  235. if( pThisDev->PreReadBuffer.pDataBuf == NULL )
  236. {
  237. status = NDIS_STATUS_RESOURCES;
  238. goto done;
  239. }
  240. NdisZeroMemory(
  241. pThisDev->PreReadBuffer.pDataBuf,
  242. STIR4200_FIFO_SIZE
  243. );
  244. pThisDev->PreReadBuffer.pThisDev = pThisDev;
  245. pThisDev->PreReadBuffer.DataLen = 0;
  246. pThisDev->PreReadBuffer.BufferState = RCV_STATE_FREE;
  247. //
  248. // Synchronization events
  249. //
  250. KeInitializeEvent(
  251. &pThisDev->EventSyncUrb,
  252. NotificationEvent, // non-auto-clearing event
  253. FALSE // event initially non-signalled
  254. );
  255. KeInitializeEvent(
  256. &pThisDev->EventAsyncUrb,
  257. NotificationEvent, // non-auto-clearing event
  258. FALSE // event initially non-signalled
  259. );
  260. done:
  261. //
  262. // If we didn't complete the init successfully, then we should clean
  263. // up what we did allocate.
  264. //
  265. if( status != NDIS_STATUS_SUCCESS )
  266. {
  267. DEBUGMSG(DBG_ERR, (" InitializeDevice() FAILED\n"));
  268. DeinitializeDevice(pThisDev);
  269. }
  270. else
  271. {
  272. DEBUGMSG(DBG_OUT, (" InitializeDevice() SUCCEEDED\n"));
  273. }
  274. DEBUGMSG(DBG_FUNC|DBG_PNP, ("-InitializeDevice()\n"));
  275. return status;
  276. }
  277. /*****************************************************************************
  278. *
  279. * Function: DeinitializeDevice
  280. *
  281. * Synopsis: deallocate the resources of the IR device object
  282. *
  283. * Arguments: pThisDev - the IR device object to close
  284. *
  285. * Returns: none
  286. *
  287. *
  288. * Notes:
  289. *
  290. * Called for shutdown and reset.
  291. * Don't clear hNdisAdapter, since we might just be resetting.
  292. * This function should be called with device lock held.
  293. *
  294. *****************************************************************************/
  295. VOID
  296. DeinitializeDevice(
  297. IN OUT PIR_DEVICE pThisDev
  298. )
  299. {
  300. UINT i;
  301. DEBUGMSG( DBG_FUNC|DBG_PNP, ("+DeinitializeDevice\n"));
  302. pThisDev->linkSpeedInfo = NULL;
  303. //
  304. // Free all resources for the RECEIVE buffer queue.
  305. //
  306. for( i = 0; i < NUM_RCV_BUFS; i++ )
  307. {
  308. PNDIS_BUFFER pBuffer = NULL;
  309. PRCV_BUFFER pRcvBuf = &pThisDev->rcvBufs[i];
  310. if( pRcvBuf->pPacket != NULL )
  311. {
  312. NdisFreePacket( (PNDIS_PACKET)pRcvBuf->pPacket );
  313. pRcvBuf->pPacket = NULL;
  314. }
  315. if( pRcvBuf->pDataBuf != NULL )
  316. {
  317. MyMemFree( pRcvBuf->pDataBuf, MAX_RCV_DATA_SIZE );
  318. pRcvBuf->pDataBuf = NULL;
  319. }
  320. pRcvBuf->DataLen = 0;
  321. }
  322. //
  323. // Deallocate the USB receive buffers
  324. //
  325. if( pThisDev->PreReadBuffer.pDataBuf != NULL )
  326. MyMemFree( pThisDev->PreReadBuffer.pDataBuf, STIR4200_FIFO_SIZE );
  327. //
  328. // Free the packet and buffer pool handles for this device.
  329. //
  330. if( pThisDev->hPacketPool )
  331. {
  332. NdisFreePacketPool( pThisDev->hPacketPool );
  333. pThisDev->hPacketPool = NULL;
  334. }
  335. if( pThisDev->BufferPoolAllocated )
  336. {
  337. NdisFreeBufferPool( pThisDev->hBufferPool );
  338. pThisDev->BufferPoolAllocated = FALSE;
  339. }
  340. if( pThisDev->fDeviceStarted )
  341. {
  342. NTSTATUS ntstatus;
  343. ntstatus = IrUsb_StopDevice( pThisDev );
  344. DEBUGMSG(DBG_FUNC, (" DeinitializeDevice IrUsb_StopDevice() status = 0x%x\n",ntstatus));
  345. }
  346. InterlockedExchange( &pThisDev->fMediaBusy, FALSE );
  347. InterlockedExchange( &pThisDev->fIndicatedMediaBusy, FALSE );
  348. IrUsb_FreeSendStructures( pThisDev );
  349. DEBUGMSG(DBG_FUNC|DBG_PNP, ("-DeinitializeDevice\n"));
  350. }