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.

460 lines
11 KiB

  1. /*
  2. ************************************************************************
  3. *
  4. * RESOURCE.c
  5. *
  6. *
  7. * Portions Copyright (C) 1996-2001 National Semiconductor Corp.
  8. * All rights reserved.
  9. * Copyright (C) 1996-2001 Microsoft Corporation. All Rights Reserved.
  10. *
  11. *
  12. *
  13. *************************************************************************
  14. */
  15. #include "nsc.h"
  16. #include "resource.tmh"
  17. /*
  18. *************************************************************************
  19. * MyMemAlloc
  20. *************************************************************************
  21. *
  22. */
  23. PVOID NscMemAlloc(UINT size)
  24. {
  25. NDIS_STATUS stat;
  26. PVOID memptr;
  27. stat = NdisAllocateMemoryWithTag(
  28. &memptr,
  29. size,
  30. 'rIsN'
  31. );
  32. if (stat == NDIS_STATUS_SUCCESS) {
  33. NdisZeroMemory((PVOID)memptr, size);
  34. } else {
  35. DBGERR(("Memory allocation failed"));
  36. memptr = NULL;
  37. }
  38. return memptr;
  39. }
  40. /*
  41. *************************************************************************
  42. * MyMemFree
  43. *************************************************************************
  44. *
  45. */
  46. VOID NscMemFree(PVOID memptr)
  47. {
  48. NdisFreeMemory(memptr, 0, 0);
  49. }
  50. PVOID
  51. NscAllocateDmaBuffer(
  52. NDIS_HANDLE AdapterHandle,
  53. ULONG Size,
  54. PNSC_DMA_BUFFER_INFO DmaBufferInfo
  55. )
  56. {
  57. NDIS_STATUS Status;
  58. NdisZeroMemory(DmaBufferInfo,sizeof(*DmaBufferInfo));
  59. DmaBufferInfo->Length=Size;
  60. DmaBufferInfo->AdapterHandle=AdapterHandle;
  61. NdisMAllocateSharedMemory(
  62. DmaBufferInfo->AdapterHandle,
  63. DmaBufferInfo->Length,
  64. TRUE,
  65. &DmaBufferInfo->VirtualAddress,
  66. &DmaBufferInfo->PhysicalAddress
  67. );
  68. if (DmaBufferInfo->VirtualAddress == NULL) {
  69. //
  70. // new style did not work, try old style
  71. //
  72. const NDIS_PHYSICAL_ADDRESS MaxAddress = NDIS_PHYSICAL_ADDRESS_CONST(0x00ffffff, 0);
  73. #if DBG
  74. DbgPrint("NSCIRDA: NdisMAllocateSharedMemoryFailed(), calling NdisAllocateMemory() instead (ok for XP and W2K)\n");
  75. #endif
  76. Status=NdisAllocateMemory(
  77. &DmaBufferInfo->VirtualAddress,
  78. DmaBufferInfo->Length,
  79. NDIS_MEMORY_CONTIGUOUS | NDIS_MEMORY_NONCACHED,
  80. MaxAddress
  81. );
  82. if (Status != STATUS_SUCCESS) {
  83. //
  84. // old style allocation failed
  85. //
  86. NdisZeroMemory(DmaBufferInfo,sizeof(*DmaBufferInfo));
  87. } else {
  88. //
  89. // old style work, not a shared allocation
  90. //
  91. DmaBufferInfo->SharedAllocation=FALSE;
  92. }
  93. } else {
  94. //
  95. // new style worked
  96. //
  97. DmaBufferInfo->SharedAllocation=TRUE;
  98. }
  99. return DmaBufferInfo->VirtualAddress;
  100. }
  101. VOID
  102. NscFreeDmaBuffer(
  103. PNSC_DMA_BUFFER_INFO DmaBufferInfo
  104. )
  105. {
  106. if ((DmaBufferInfo->AdapterHandle == NULL) || (DmaBufferInfo->VirtualAddress == NULL)) {
  107. //
  108. // Not been allocated
  109. //
  110. ASSERT(0);
  111. return;
  112. }
  113. if (DmaBufferInfo->SharedAllocation) {
  114. //
  115. // allocated with ndis shared memory functions
  116. //
  117. NdisMFreeSharedMemory(
  118. DmaBufferInfo->AdapterHandle,
  119. DmaBufferInfo->Length,
  120. TRUE,
  121. DmaBufferInfo->VirtualAddress,
  122. DmaBufferInfo->PhysicalAddress\
  123. );
  124. } else {
  125. //
  126. // Allocated via old api
  127. //
  128. #if DBG
  129. DbgPrint("NSCIRDA: Freeing DMA buffer with NdisFreeMemory() (ok for XP and W2K)\n");
  130. #endif
  131. NdisFreeMemory(
  132. DmaBufferInfo->VirtualAddress,
  133. DmaBufferInfo->Length,
  134. NDIS_MEMORY_CONTIGUOUS | NDIS_MEMORY_NONCACHED
  135. );
  136. }
  137. NdisZeroMemory(DmaBufferInfo,sizeof(*DmaBufferInfo));
  138. return;
  139. }
  140. /*
  141. *************************************************************************
  142. * NewDevice
  143. *************************************************************************
  144. *
  145. */
  146. IrDevice *NewDevice()
  147. {
  148. IrDevice *newdev;
  149. newdev = NscMemAlloc(sizeof(IrDevice));
  150. if (newdev){
  151. InitDevice(newdev);
  152. }
  153. return newdev;
  154. }
  155. /*
  156. *************************************************************************
  157. * FreeDevice
  158. *************************************************************************
  159. *
  160. */
  161. VOID FreeDevice(IrDevice *dev)
  162. {
  163. CloseDevice(dev);
  164. NscMemFree((PVOID)dev);
  165. }
  166. /*
  167. *************************************************************************
  168. * InitDevice
  169. *************************************************************************
  170. *
  171. * Zero out the device object.
  172. *
  173. * Allocate the device object's spinlock, which will persist while
  174. * the device is opened and closed.
  175. *
  176. */
  177. VOID InitDevice(IrDevice *thisDev)
  178. {
  179. NdisZeroMemory((PVOID)thisDev, sizeof(IrDevice));
  180. NdisInitializeListHead(&thisDev->SendQueue);
  181. NdisAllocateSpinLock(&thisDev->QueueLock);
  182. NdisInitializeTimer(&thisDev->TurnaroundTimer,
  183. DelayedWrite,
  184. thisDev);
  185. NdisInitializeListHead(&thisDev->rcvBufBuf);
  186. NdisInitializeListHead(&thisDev->rcvBufFree);
  187. NdisInitializeListHead(&thisDev->rcvBufFull);
  188. NdisInitializeListHead(&thisDev->rcvBufPend);
  189. }
  190. /*
  191. *************************************************************************
  192. * OpenDevice
  193. *************************************************************************
  194. *
  195. * Allocate resources for a single device object.
  196. *
  197. * This function should be called with device lock already held.
  198. *
  199. */
  200. BOOLEAN OpenDevice(IrDevice *thisDev)
  201. {
  202. BOOLEAN result = FALSE;
  203. NDIS_STATUS stat;
  204. UINT bufIndex;
  205. DBGOUT(("OpenDevice()"));
  206. if (!thisDev){
  207. return FALSE;
  208. }
  209. /*
  210. * Allocate the NDIS packet and NDIS buffer pools
  211. * for this device's RECEIVE buffer queue.
  212. * Our receive packets must only contain one buffer apiece,
  213. * so #buffers == #packets.
  214. */
  215. NdisAllocatePacketPool(&stat, &thisDev->packetPoolHandle, NUM_RCV_BUFS, 6 * sizeof(PVOID));
  216. if (stat != NDIS_STATUS_SUCCESS){
  217. goto _openDone;
  218. }
  219. NdisAllocateBufferPool(&stat, &thisDev->bufferPoolHandle, NUM_RCV_BUFS);
  220. if (stat != NDIS_STATUS_SUCCESS){
  221. goto _openDone;
  222. }
  223. //
  224. // allocate the receive buffers used to hold receives SIR frames
  225. //
  226. for (bufIndex = 0; bufIndex < NUM_RCV_BUFS; bufIndex++){
  227. PVOID buf;
  228. buf = NscMemAlloc(RCV_BUFFER_SIZE);
  229. if (!buf){
  230. goto _openDone;
  231. }
  232. // We treat the beginning of the buffer as a LIST_ENTRY.
  233. // Normally we would use NDISSynchronizeInsertHeadList, but the
  234. // Interrupt hasn't been registered yet.
  235. InsertHeadList(&thisDev->rcvBufBuf, (PLIST_ENTRY)buf);
  236. }
  237. //
  238. // initialize the data structures that keep track of receives buffers
  239. //
  240. for (bufIndex = 0; bufIndex < NUM_RCV_BUFS; bufIndex++){
  241. rcvBuffer *rcvBuf = NscMemAlloc(sizeof(rcvBuffer));
  242. if (!rcvBuf)
  243. {
  244. goto _openDone;
  245. }
  246. rcvBuf->state = STATE_FREE;
  247. rcvBuf->isDmaBuf = FALSE;
  248. /*
  249. * Allocate a data buffer
  250. *
  251. * This buffer gets swapped with the one on comPortInfo
  252. * and must be the same size.
  253. */
  254. rcvBuf->dataBuf = NULL;
  255. /*
  256. * Allocate the NDIS_PACKET.
  257. */
  258. NdisAllocatePacket(&stat, &rcvBuf->packet, thisDev->packetPoolHandle);
  259. if (stat != NDIS_STATUS_SUCCESS){
  260. NscMemFree(rcvBuf);
  261. rcvBuf=NULL;
  262. goto _openDone;
  263. }
  264. /*
  265. * For future convenience, set the MiniportReserved portion of the packet
  266. * to the index of the rcv buffer that contains it.
  267. * This will be used in ReturnPacketHandler.
  268. */
  269. *(ULONG_PTR *)rcvBuf->packet->MiniportReserved = (ULONG_PTR)rcvBuf;
  270. rcvBuf->dataLen = 0;
  271. InsertHeadList(&thisDev->rcvBufFree, &rcvBuf->listEntry);
  272. }
  273. /*
  274. * Set mediaBusy to TRUE initially. That way, we won't
  275. * IndicateStatus to the protocol in the ISR unless the
  276. * protocol has expressed interest by clearing this flag
  277. * via MiniportSetInformation(OID_IRDA_MEDIA_BUSY).
  278. */
  279. thisDev->mediaBusy = FALSE;
  280. thisDev->haveIndicatedMediaBusy = TRUE;
  281. /*
  282. * Will set speed to 9600 baud initially.
  283. */
  284. thisDev->linkSpeedInfo = &supportedBaudRateTable[BAUDRATE_9600];
  285. thisDev->lastPacketAtOldSpeed = NULL;
  286. thisDev->setSpeedAfterCurrentSendPacket = FALSE;
  287. result = TRUE;
  288. _openDone:
  289. if (!result){
  290. /*
  291. * If we're failing, close the device to free up any resources
  292. * that were allocated for it.
  293. */
  294. CloseDevice(thisDev);
  295. DBGOUT(("OpenDevice() failed"));
  296. }
  297. else {
  298. DBGOUT(("OpenDevice() succeeded"));
  299. }
  300. return result;
  301. }
  302. /*
  303. *************************************************************************
  304. * CloseDevice
  305. *************************************************************************
  306. *
  307. * Free the indicated device's resources.
  308. *
  309. *
  310. * Called for shutdown and reset.
  311. * Don't clear ndisAdapterHandle, since we might just be resetting.
  312. * This function should be called with device lock held.
  313. *
  314. *
  315. */
  316. VOID CloseDevice(IrDevice *thisDev)
  317. {
  318. PLIST_ENTRY ListEntry;
  319. DBGOUT(("CloseDevice()"));
  320. if (!thisDev){
  321. return;
  322. }
  323. /*
  324. * Free all resources for the RECEIVE buffer queue.
  325. */
  326. while (!IsListEmpty(&thisDev->rcvBufFree))
  327. {
  328. rcvBuffer *rcvBuf;
  329. ListEntry = RemoveHeadList(&thisDev->rcvBufFree);
  330. rcvBuf = CONTAINING_RECORD(ListEntry,
  331. rcvBuffer,
  332. listEntry);
  333. if (rcvBuf->packet){
  334. NdisFreePacket(rcvBuf->packet);
  335. rcvBuf->packet = NULL;
  336. }
  337. NscMemFree(rcvBuf);
  338. }
  339. while (!IsListEmpty(&thisDev->rcvBufBuf))
  340. {
  341. ListEntry = RemoveHeadList(&thisDev->rcvBufBuf);
  342. NscMemFree(ListEntry);
  343. }
  344. /*
  345. * Free the packet and buffer pool handles for this device.
  346. */
  347. if (thisDev->packetPoolHandle){
  348. NdisFreePacketPool(thisDev->packetPoolHandle);
  349. thisDev->packetPoolHandle = NULL;
  350. }
  351. if (thisDev->bufferPoolHandle){
  352. NdisFreeBufferPool(thisDev->bufferPoolHandle);
  353. thisDev->bufferPoolHandle = NULL;
  354. }
  355. //
  356. // the send queue should be empty now
  357. //
  358. ASSERT(IsListEmpty(&thisDev->SendQueue));
  359. thisDev->mediaBusy = FALSE;
  360. thisDev->haveIndicatedMediaBusy = FALSE;
  361. thisDev->linkSpeedInfo = NULL;
  362. }