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.

600 lines
16 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. pkt.c
  5. Abstract:
  6. ARP1394 ARP control packet management.
  7. Revision History:
  8. Who When What
  9. -------- -------- ----------------------------------------------
  10. josephj 07-01-99 Created
  11. Notes:
  12. --*/
  13. #include <precomp.h>
  14. //
  15. // File-specific debugging defaults.
  16. //
  17. #define TM_CURRENT TM_PKT
  18. //=========================================================================
  19. // L O C A L P R O T O T Y P E S
  20. //=========================================================================
  21. NDIS_STATUS
  22. arpAllocateControlPacketPool(
  23. PARP1394_INTERFACE pIF, // LOCKIN LOCKOUT
  24. UINT MaxBufferSize,
  25. PRM_STACK_RECORD pSR
  26. )
  27. /*++
  28. Routine Description:
  29. Allocate & initialize the packet pool used for allocating control packets.
  30. Control packets are used for ARP and MCAP. This routine MUST be called
  31. BEFORE the first call to arpAllocateControlPacket.
  32. Arguments:
  33. pIF - The interface in which to allocate the pool. Only one such pool
  34. is allocated per interface and it occupies a specific field of
  35. pIF.
  36. MaxBufferSize - Maximum data size of packets to be allocated using this
  37. pool. Attempts to allocate a packet
  38. (using arpAllocateControlPacket) with a size larger than
  39. MaxBufferSize will fail.
  40. Return Value:
  41. NDIS_STATUS_SUCCESS on success.
  42. Ndis error code on failure.
  43. --*/
  44. {
  45. NDIS_STATUS Status;
  46. NDIS_HANDLE PacketPool=NULL;
  47. NDIS_HANDLE BufferPool=NULL;
  48. ENTER("arpAllocateControlPacketPool", 0x71579254)
  49. RM_ASSERT_OBJLOCKED(&pIF->Hdr, pSR);
  50. ASSERT(pIF->arp.PacketPool == NULL);
  51. ASSERT(pIF->arp.BufferPool == NULL);
  52. ASSERT(pIF->arp.NumOutstandingPackets == 0);
  53. do
  54. {
  55. // Allocate the NDIS Packet Pool
  56. //
  57. NdisAllocatePacketPool(
  58. &Status,
  59. &PacketPool,
  60. ARP1394_MAX_PROTOCOL_PKTS,
  61. sizeof(struct PCCommon)
  62. );
  63. if (FAIL(Status))
  64. {
  65. PacketPool = NULL;
  66. break;
  67. }
  68. // Allocate the NDIS Buffer Pool
  69. //
  70. NdisAllocateBufferPool(
  71. &Status,
  72. &BufferPool,
  73. ARP1394_MAX_PROTOCOL_PKTS
  74. );
  75. if (FAIL(Status))
  76. {
  77. BufferPool = NULL;
  78. break;
  79. }
  80. //
  81. // We could allocate a lookaside list for the Protocol data, but we
  82. // choose to use NdisAllocateMemoryWithTag on demand instead. Protocol pkts
  83. // are not high-frequency things; plus we don't have support for lookaside
  84. // lists on win98 (although we could easily implement our own for
  85. // win98, so that's not really an excuse).
  86. //
  87. pIF->arp.MaxBufferSize = MaxBufferSize;
  88. // (DBG only) Add associations for the packet pool and buffer pool.
  89. // These associations must be removed before the interface is deallocated.
  90. //
  91. DBG_ADDASSOC(
  92. &pIF->Hdr, // pObject
  93. PacketPool, // Instance1
  94. NULL, // Instance2
  95. ARPASSOC_IF_PROTOPKTPOOL, // AssociationID
  96. " Proto Packet Pool 0x%p\n",// szFormat
  97. pSR
  98. );
  99. DBG_ADDASSOC(
  100. &pIF->Hdr, // pObject
  101. BufferPool, // Instance1
  102. NULL, // Instance2
  103. ARPASSOC_IF_PROTOBUFPOOL, // AssociationID
  104. " Proto Buffer Pool 0x%p\n",// szFormat
  105. pSR
  106. );
  107. pIF->arp.PacketPool = PacketPool;
  108. pIF->arp.BufferPool = BufferPool;
  109. PacketPool = NULL;
  110. BufferPool = NULL;
  111. } while (FALSE);
  112. if (FAIL(Status))
  113. {
  114. if (PacketPool != NULL)
  115. {
  116. NdisFreePacketPool(PacketPool);
  117. }
  118. if (BufferPool != NULL)
  119. {
  120. NdisFreeBufferPool(BufferPool);
  121. }
  122. }
  123. else
  124. {
  125. ASSERT(PacketPool == NULL && BufferPool == NULL);
  126. }
  127. return Status;
  128. }
  129. VOID
  130. arpFreeControlPacketPool(
  131. PARP1394_INTERFACE pIF, // LOCKIN LOCKOUT
  132. PRM_STACK_RECORD pSR
  133. )
  134. /*++
  135. Routine Description:
  136. Free the previously allocated control packet pool. MUST be called AFTER the last
  137. call to arpFreeControlPacket. See arpAllocateControlPacketPool for more details.
  138. Arguments:
  139. pIF - The interface in which to free the pool.
  140. --*/
  141. {
  142. NDIS_HANDLE PacketPool;
  143. NDIS_HANDLE BufferPool;
  144. ENTER("arpFreeControlPacketPool", 0x3c3acf47)
  145. // Make sure the IF is locked.
  146. //
  147. RM_ASSERT_OBJLOCKED(&pIF->Hdr, pSR);
  148. // Make sure that there are no outstanding allocated packets.
  149. //
  150. ASSERT(pIF->arp.NumOutstandingPackets == 0);
  151. PacketPool = pIF->arp.PacketPool;
  152. BufferPool = pIF->arp.BufferPool;
  153. pIF->arp.PacketPool = NULL;
  154. pIF->arp.BufferPool = NULL;
  155. // (DBG only) Remove associations for the control and packet pools.
  156. //
  157. DBG_DELASSOC(
  158. &pIF->Hdr, // pObject
  159. PacketPool, // Instance1
  160. NULL, // Instance2
  161. ARPASSOC_IF_PROTOPKTPOOL, // AssociationID
  162. pSR
  163. );
  164. DBG_DELASSOC(
  165. &pIF->Hdr, // pObject
  166. BufferPool, // Instance1
  167. NULL, // Instance2
  168. ARPASSOC_IF_PROTOBUFPOOL, // AssociationID
  169. pSR
  170. );
  171. // Free the buffer and packet pools
  172. //
  173. NdisFreeBufferPool(BufferPool);
  174. NdisFreePacketPool(PacketPool);
  175. }
  176. NDIS_STATUS
  177. arpAllocateControlPacket(
  178. IN PARP1394_INTERFACE pIF,
  179. IN UINT cbBufferSize,
  180. IN UINT PktFlags,
  181. OUT PNDIS_PACKET *ppNdisPacket,
  182. OUT PVOID *ppvData,
  183. PRM_STACK_RECORD pSR
  184. )
  185. /*++
  186. Routine Description:
  187. Allocate a control packet from the interfaces control packet pool. Also
  188. allocate and chain a SINGLE buffer of size cbBufferSize and return a pointer to
  189. this buffer in *ppvData.
  190. NOTE1: The packet and associated buffer MUST be freed
  191. by a subsequent call to arpFreeControlPacket -- do not free the packet & buffer
  192. by directly calling ndis apis.
  193. NOTE2: cbBufferSize must be <= the max-buffer-size specified when
  194. creating the pool (see arpAllocateControlPacketPool for details).
  195. Arguments:
  196. pIF - Interface whose control packet pool to use.
  197. cbBufferSize - size of the control packet.
  198. ppNdisPacket - Location to set to point to the allocated pkt.
  199. ppvData - Location to set to point to the packet data (single buffer).
  200. Return Value:
  201. NDIS_STATUS_SUCCESS on success.
  202. NDIS_STATUS_RESOURCES if buffers or pkts are currently not available.
  203. Other ndis error on other kinds of failures.
  204. --*/
  205. {
  206. NDIS_STATUS Status;
  207. PNDIS_PACKET pNdisPacket = NULL;
  208. PNDIS_BUFFER pNdisBuffer = NULL;
  209. PVOID pvData = NULL;
  210. ENTER("arpAllocateControlPacket", 0x8ccce6ea)
  211. //
  212. // NOTE: we don't care if pIF is locked or not.
  213. //
  214. pNdisPacket = NULL;
  215. pvData = NULL;
  216. do
  217. {
  218. // Allocate space for the packet data.
  219. // TODO: here is where we could use a lookaside list instead
  220. // of NdisAllocateMemoryWithTag.
  221. //
  222. {
  223. if (cbBufferSize > pIF->arp.MaxBufferSize)
  224. {
  225. ASSERT(FALSE);
  226. Status = NDIS_STATUS_RESOURCES;
  227. break;
  228. }
  229. NdisAllocateMemoryWithTag(
  230. &pvData,
  231. cbBufferSize,
  232. MTAG_PKT
  233. );
  234. if (pvData == NULL)
  235. {
  236. Status = NDIS_STATUS_RESOURCES;
  237. break;
  238. }
  239. }
  240. // Allocate a buffer.
  241. //
  242. NdisAllocateBuffer(
  243. &Status,
  244. &pNdisBuffer,
  245. pIF->arp.BufferPool,
  246. pvData,
  247. cbBufferSize
  248. );
  249. if (FAIL(Status))
  250. {
  251. pNdisBuffer = NULL;
  252. break;
  253. }
  254. // Allocate a packet
  255. //
  256. NdisAllocatePacket(
  257. &Status,
  258. &pNdisPacket,
  259. pIF->arp.PacketPool
  260. );
  261. if (FAIL(Status))
  262. {
  263. pNdisPacket = NULL;
  264. break;
  265. }
  266. // Identify the packet as belonging to us (ARP).
  267. //
  268. {
  269. struct PacketContext *PC;
  270. PC = (struct PacketContext *)pNdisPacket->ProtocolReserved;
  271. PC->pc_common.pc_owner = PACKET_OWNER_LINK;
  272. PC->pc_common.pc_flags = (UCHAR)PktFlags; // ARP1394_PACKET_FLAGS_CONTROL;
  273. }
  274. // Link the packet and buffer.
  275. //
  276. NdisChainBufferAtFront(pNdisPacket, pNdisBuffer);
  277. InterlockedIncrement(&pIF->arp.NumOutstandingPackets);
  278. *ppNdisPacket = pNdisPacket;
  279. *ppvData = pvData;
  280. pNdisPacket = NULL;
  281. pNdisBuffer = NULL;
  282. pvData = NULL;
  283. } while (FALSE);
  284. if (FAIL(Status))
  285. {
  286. if (pNdisPacket != NULL)
  287. {
  288. NdisFreePacket(pNdisPacket);
  289. }
  290. if (pNdisBuffer != NULL)
  291. {
  292. NdisFreeBuffer(pNdisBuffer);
  293. }
  294. if (pvData != NULL)
  295. {
  296. NdisFreeMemory(pvData, 0, 0);
  297. }
  298. }
  299. else
  300. {
  301. ASSERT(pNdisPacket == NULL
  302. && pNdisBuffer == NULL
  303. && pvData == NULL);
  304. }
  305. return Status;
  306. }
  307. VOID
  308. arpFreeControlPacket(
  309. PARP1394_INTERFACE pIF,
  310. PNDIS_PACKET pNdisPacket,
  311. PRM_STACK_RECORD pSR
  312. )
  313. /*++
  314. Routine Description:
  315. Free a packet previously allocated using arpAllocateControlPacket.
  316. Arguments:
  317. pIF - Interface whose control packet pool to use.
  318. --*/
  319. {
  320. PNDIS_BUFFER pNdisBuffer = NULL;
  321. PVOID pvData = NULL;
  322. ENTER("arpFreeControlPacket", 0x01e7fbc7)
  323. // (DBG only) Verify that this packet belongs to us.
  324. //
  325. #if DBG
  326. {
  327. struct PacketContext *PC;
  328. PC = (struct PacketContext *)pNdisPacket->ProtocolReserved;
  329. ASSERT(PC->pc_common.pc_owner == PACKET_OWNER_LINK);
  330. }
  331. #endif // DBG
  332. // Decrement the allocated packet count.
  333. //
  334. {
  335. LONG Count;
  336. Count = InterlockedDecrement(&pIF->arp.NumOutstandingPackets);
  337. ASSERT(Count >= 0);
  338. }
  339. // Extract the buffer and data
  340. //
  341. {
  342. UINT TotalLength;
  343. UINT BufferLength;
  344. NdisQueryPacket(
  345. pNdisPacket,
  346. NULL,
  347. NULL,
  348. &pNdisBuffer,
  349. &TotalLength
  350. );
  351. if (TotalLength > 0)
  352. {
  353. NdisQueryBuffer(
  354. pNdisBuffer,
  355. &pvData,
  356. &BufferLength
  357. );
  358. }
  359. else
  360. {
  361. BufferLength = 0;
  362. }
  363. // There should only be a single buffer!
  364. //
  365. ASSERT(TotalLength!=0 && TotalLength == BufferLength);
  366. }
  367. // Free the data
  368. //
  369. if (pvData != NULL)
  370. {
  371. NdisFreeMemory(pvData, 0, 0);
  372. }
  373. // Free the buffer
  374. //
  375. if (pNdisBuffer != NULL)
  376. {
  377. NdisFreeBuffer(pNdisBuffer);
  378. }
  379. // Free the packet
  380. //
  381. if (pNdisPacket != NULL)
  382. {
  383. NdisFreePacket(pNdisPacket);
  384. }
  385. }
  386. NDIS_STATUS
  387. arpAllocateEthernetPools(
  388. IN PARP1394_INTERFACE pIF,
  389. IN PRM_STACK_RECORD pSR
  390. )
  391. {
  392. NDIS_STATUS Status;
  393. NDIS_HANDLE PacketPool=NULL;
  394. NDIS_HANDLE BufferPool=NULL;
  395. ENTER("arpAllocateEthernetPools", 0x9dc1d759)
  396. RM_ASSERT_OBJLOCKED(&pIF->Hdr, pSR);
  397. ASSERT(pIF->ethernet.PacketPool == NULL);
  398. ASSERT(pIF->ethernet.BufferPool == NULL);
  399. do
  400. {
  401. // Allocate the NDIS Packet Pool
  402. //
  403. NdisAllocatePacketPool(
  404. &Status,
  405. &PacketPool,
  406. ARP1394_MAX_ETHERNET_PKTS,
  407. sizeof(struct PCCommon)
  408. );
  409. if (FAIL(Status))
  410. {
  411. PacketPool = NULL;
  412. break;
  413. }
  414. // Allocate the NDIS Buffer Pool
  415. //
  416. NdisAllocateBufferPool(
  417. &Status,
  418. &BufferPool,
  419. 2*ARP1394_MAX_ETHERNET_PKTS // two buffers per packet.
  420. );
  421. if (FAIL(Status))
  422. {
  423. BufferPool = NULL;
  424. break;
  425. }
  426. // (DBG only) Add associations for the ethernet packet pool and buffer pool.
  427. // These associations must be removed before the interface is deallocated.
  428. //
  429. DBG_ADDASSOC(
  430. &pIF->Hdr, // pObject
  431. PacketPool, // Instance1
  432. NULL, // Instance2
  433. ARPASSOC_IF_ETHPKTPOOL, // AssociationID
  434. " Eth Packet Pool 0x%p\n",// szFormat
  435. pSR
  436. );
  437. DBG_ADDASSOC(
  438. &pIF->Hdr, // pObject
  439. BufferPool, // Instance1
  440. NULL, // Instance2
  441. ARPASSOC_IF_ETHBUFPOOL, // AssociationID
  442. " Eth Buffer Pool 0x%p\n",// szFormat
  443. pSR
  444. );
  445. pIF->ethernet.PacketPool = PacketPool;
  446. pIF->ethernet.BufferPool = BufferPool;
  447. PacketPool = NULL;
  448. BufferPool = NULL;
  449. } while (FALSE);
  450. if (FAIL(Status))
  451. {
  452. if (PacketPool != NULL)
  453. {
  454. NdisFreePacketPool(PacketPool);
  455. }
  456. if (BufferPool != NULL)
  457. {
  458. NdisFreeBufferPool(BufferPool);
  459. }
  460. }
  461. else
  462. {
  463. ASSERT(PacketPool == NULL && BufferPool == NULL);
  464. }
  465. return Status;
  466. }
  467. VOID
  468. arpFreeEthernetPools(
  469. IN PARP1394_INTERFACE pIF,
  470. IN PRM_STACK_RECORD pSR
  471. )
  472. {
  473. NDIS_HANDLE PacketPool;
  474. NDIS_HANDLE BufferPool;
  475. ENTER("arpFreeEthernetPools", 0x3e780760)
  476. // Make sure the IF is locked.
  477. //
  478. RM_ASSERT_OBJLOCKED(&pIF->Hdr, pSR);
  479. PacketPool = pIF->ethernet.PacketPool;
  480. BufferPool = pIF->ethernet.BufferPool;
  481. pIF->ethernet.PacketPool = NULL;
  482. pIF->ethernet.BufferPool = NULL;
  483. // (DBG only) Remove associations for the control and packet pools.
  484. //
  485. DBG_DELASSOC(
  486. &pIF->Hdr, // pObject
  487. PacketPool, // Instance1
  488. NULL, // Instance2
  489. ARPASSOC_IF_ETHPKTPOOL, // AssociationID
  490. pSR
  491. );
  492. DBG_DELASSOC(
  493. &pIF->Hdr, // pObject
  494. BufferPool, // Instance1
  495. NULL, // Instance2
  496. ARPASSOC_IF_ETHBUFPOOL, // AssociationID
  497. pSR
  498. );
  499. // Free the buffer and packet pools
  500. //
  501. NdisFreeBufferPool(BufferPool);
  502. NdisFreePacketPool(PacketPool);
  503. }