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.

898 lines
24 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. atp.h
  5. Abstract:
  6. This module contains definitions for the ATP code.
  7. Author:
  8. Jameel Hyder (jameelh@microsoft.com)
  9. Nikhil Kamkolkar (nikhilk@microsoft.com)
  10. Revision History:
  11. 19 Jun 1992 Initial Version
  12. Notes: Tab stop: 4
  13. --*/
  14. #ifndef _ATP_
  15. #define _ATP_
  16. // Command/control bit masks.
  17. #define ATP_REL_TIMER_MASK 0x07
  18. #define ATP_STS_MASK 0x08
  19. #define ATP_EOM_MASK 0x10
  20. #define ATP_XO_MASK 0x20
  21. // Values for function code
  22. #define ATP_REQUEST 0x40
  23. #define ATP_RESPONSE 0x80
  24. #define ATP_RELEASE 0xC0
  25. #define ATP_FUNC_MASK 0xC0
  26. #define ATP_CMD_CONTROL_OFF 0
  27. #define ATP_BITMAP_OFF 1
  28. #define ATP_SEQ_NUM_OFF 1
  29. #define ATP_TRANS_ID_OFF 2
  30. #define ATP_USER_BYTES_OFF 4
  31. #define ATP_DATA_OFF 8
  32. #define ATP_MAX_RESP_PKTS 8
  33. #define ATP_USERBYTES_SIZE 4
  34. #define ATP_HEADER_SIZE 8
  35. // NOTE: Event handler routines- ATP has no event handling support
  36. // ATP Address Object
  37. #define ATP_DEF_MAX_SINGLE_PKT_SIZE 578
  38. #define ATP_MAX_TOTAL_RESPONSE_SIZE (ATP_MAX_RESP_PKTS * ATP_DEF_MAX_SINGLE_PKT_SIZE)
  39. #define ATP_DEF_SEND_USER_BYTES_ALL ((BOOLEAN)FALSE)
  40. #define ATP_DEF_RETRY_INTERVAL 20 // 2 seconds in 100ms units
  41. #define ATP_INFINITE_RETRIES -1
  42. #define ATP_REQ_HASH_SIZE 29
  43. #define ATP_RESP_HASH_SIZE 37
  44. // Values for the release timer (.5, 1, 2, 4, 8 minutes).
  45. typedef LONG RELEASE_TIMERVALUE;
  46. #define FIRSTVALID_TIMER 0
  47. #define THIRTY_SEC_TIMER 0
  48. #define ONE_MINUTE_TIMER 1
  49. #define TWO_MINUTE_TIMER 2
  50. #define FOUR_MINUTE_TIMER 3
  51. #define EIGHT_MINUTE_TIMER 4
  52. #define LAST_VALID_TIMER 4
  53. #define MAX_VALID_TIMERS 5
  54. // Different subtypes for ATP indication type.
  55. #define ATP_ALLOC_BUF 0
  56. #define ATP_USER_BUF 1
  57. #define ATP_USER_BUFX 2 // Do not indicate the packet to Atp with this.
  58. struct _ATP_RESP;
  59. typedef VOID (*ATPAO_CLOSECOMPLETION)(
  60. IN ATALK_ERROR CloseResult,
  61. IN PVOID CloseContext
  62. );
  63. typedef VOID (*ATP_REQ_HANDLER)(
  64. IN ATALK_ERROR Error,
  65. IN PVOID CompletionContext,
  66. IN struct _ATP_RESP * pAtpResp,
  67. IN PATALK_ADDR SourceAddress,
  68. IN USHORT RequestLength,
  69. IN PBYTE RequestPacket,
  70. IN PBYTE RequestUserBytes // 4 bytes of user bytes
  71. );
  72. typedef VOID (*ATP_RESP_HANDLER)(
  73. IN ATALK_ERROR Error,
  74. IN PVOID CompletionContext,
  75. IN PAMDL RequestBuffer,
  76. IN PAMDL ResponseBuffer,
  77. IN USHORT ResponseSize,
  78. IN PBYTE ResponseUserBytes // 4 bytes of user bytes
  79. );
  80. typedef VOID (FASTCALL *ATP_REL_HANDLER)(
  81. IN ATALK_ERROR Error,
  82. IN PVOID CompletionContext
  83. );
  84. // ATP ADDRESS OBJECT STATES
  85. #define ATPAO_OPEN 0x00000001
  86. #define ATPAO_SENDUSERBYTESALL 0x00000002
  87. #define ATPAO_CACHED 0x00000004
  88. #define ATPAO_TIMERS 0x00000008
  89. #define ATPAO_CLEANUP 0x40000000
  90. #define ATPAO_CLOSING 0x80000000
  91. #define ATPAO_SIGNATURE (*(PULONG)"ATPA")
  92. #if DBG
  93. #define VALID_ATPAO(pAtpAddr) (((pAtpAddr) != NULL) && \
  94. ((pAtpAddr)->atpao_Signature == ATPAO_SIGNATURE))
  95. #else
  96. #define VALID_ATPAO(pAtpAddr) ((pAtpAddr) != NULL)
  97. #endif
  98. typedef struct _ATP_ADDROBJ
  99. {
  100. #if DBG
  101. ULONG atpao_Signature;
  102. #endif
  103. LONG atpao_RefCount;
  104. // State of the address object
  105. ULONG atpao_Flags;
  106. // We pass a pointer to the ATP Address object to the upper layers to
  107. // use as the endpoint, and this same pointer is passed to DDP Open
  108. // Address as the ATP address handler context.
  109. // Linkage list for all responses to AtLeastOnce (ALO) transactions.
  110. // These are not kept in the resp hash table for efficiency. These
  111. // happen very infrequently and only exist on the list until the
  112. // SENDs complete.
  113. struct _ATP_RESP * atpao_AloRespLinkage;
  114. // next Transaction id to be used
  115. USHORT atpao_NextTid;
  116. // Maximum single packet size to be used (PAP needs this to be 512)
  117. USHORT atpao_MaxSinglePktSize;
  118. // Pointer to the DDP address object that this will create
  119. PDDP_ADDROBJ atpao_DdpAddr;
  120. // Completion routine to be called when socket is closed
  121. ATPAO_CLOSECOMPLETION atpao_CloseComp;
  122. PVOID atpao_CloseCtx;
  123. // Hash table of pending ATP PostReq
  124. struct _ATP_REQ * atpao_ReqHash[ATP_REQ_HASH_SIZE];
  125. LIST_ENTRY atpao_ReqList; // List of requests for retry timer
  126. TIMERLIST atpao_RetryTimer; // Retry timer for ALL requests
  127. // Hash table of pending ATP PostResponses
  128. struct _ATP_RESP * atpao_RespHash[ATP_RESP_HASH_SIZE];
  129. LIST_ENTRY atpao_RespList; // List of requests for release timer
  130. TIMERLIST atpao_RelTimer; // Release timer for ALL XO responses
  131. // handler and corres. contexts for requests
  132. ATP_REQ_HANDLER atpao_ReqHandler;
  133. PVOID atpao_ReqCtx;
  134. PATALK_DEV_CTX atpao_DevCtx;
  135. ATALK_SPIN_LOCK atpao_Lock;
  136. } ATP_ADDROBJ, *PATP_ADDROBJ;
  137. #define ATP_REQ_EXACTLY_ONCE 0x0001
  138. #define ATP_REQ_RETRY_TIMER 0x0002
  139. #define ATP_REQ_REMOTE 0x0004
  140. #define ATP_REQ_RESPONSE_COMPLETE 0x0008
  141. #define ATP_REQ_CLOSING 0x8000
  142. #define ATP_REQ_SIGNATURE (*(PULONG)"ATRQ")
  143. #if DBG
  144. #define VALID_ATPRQ(pAtpReq) (((pAtpReq) != NULL) && \
  145. ((pAtpReq)->req_Signature == ATP_REQ_SIGNATURE))
  146. #else
  147. #define VALID_ATPRQ(pAtpReq) ((pAtpReq) != NULL)
  148. #endif
  149. typedef struct _ATP_REQ
  150. {
  151. #if DBG
  152. ULONG req_Signature;
  153. #endif
  154. LONG req_RefCount;
  155. // Linkage of requests on this address object (hash overflow)
  156. struct _ATP_REQ * req_Next;
  157. struct _ATP_REQ ** req_Prev;
  158. LIST_ENTRY req_List; // List of requests for retry timer
  159. // BackPointer to the ATP address object. Need for reference/Dereference.
  160. PATP_ADDROBJ req_pAtpAddr;
  161. // State of the request
  162. USHORT req_Flags;
  163. // ATP Bitmap showing the response packets we are waiting for/expect.
  164. BYTE req_Bitmap;
  165. BYTE req_RecdBitmap;
  166. // Destination of this request
  167. ATALK_ADDR req_Dest;
  168. // Request buffer for retransmission
  169. PAMDL req_Buf;
  170. USHORT req_BufLen;
  171. // Transaction id
  172. USHORT req_Tid;
  173. union
  174. {
  175. BYTE req_UserBytes[ATP_USERBYTES_SIZE];
  176. DWORD req_dwUserBytes;
  177. };
  178. // User's response buffer
  179. PAMDL req_RespBuf;
  180. // Buffer descriptors for parts of the resp buf.
  181. PNDIS_BUFFER req_NdisBuf[ATP_MAX_RESP_PKTS];
  182. USHORT req_RespBufLen;
  183. // Received response length
  184. USHORT req_RespRecdLen;
  185. BYTE req_RespUserBytes[ATP_USERBYTES_SIZE];
  186. LONG req_RetryInterval;
  187. LONG req_RetryCnt;
  188. // Release timer value to send to the remote end.
  189. RELEASE_TIMERVALUE req_RelTimerValue;
  190. // Retry time stamp, time at which the request will be retried if no response
  191. LONG req_RetryTimeStamp;
  192. // Completion routine to be called when request is done
  193. ATALK_ERROR req_CompStatus;
  194. ATP_RESP_HANDLER req_Comp;
  195. PVOID req_Ctx;
  196. ATALK_SPIN_LOCK req_Lock;
  197. } ATP_REQ, *PATP_REQ;
  198. // ATP_RESP_REMOTE indicates that the response is not to a local socket in which
  199. // case we can avoid trying to deliver to our sockets
  200. #define ATP_RESP_EXACTLY_ONCE 0x0001
  201. #define ATP_RESP_ONLY_USER_BYTES 0x0002
  202. #define ATP_RESP_REL_TIMER 0x0004
  203. #define ATP_RESP_VALID_RESP 0x0008
  204. #define ATP_RESP_SENT 0x0010
  205. #define ATP_RESP_TRANSMITTING 0x0020
  206. #define ATP_RESP_REMOTE 0x0040
  207. #define ATP_RESP_HANDLER_NOTIFIED 0x0080
  208. #define ATP_RESP_CANCELLED 0x0100
  209. #define ATP_RESP_RELEASE_RECD 0x0200
  210. #define ATP_RESP_CLOSING 0x8000
  211. #define ATP_RESP_SIGNATURE (*(PULONG)"ATRS")
  212. #if DBG
  213. #define VALID_ATPRS(pAtpResp) (((pAtpResp) != NULL) && \
  214. ((pAtpResp)->resp_Signature == ATP_RESP_SIGNATURE))
  215. #else
  216. #define VALID_ATPRS(pAtpResp) ((pAtpResp) != NULL)
  217. #endif
  218. typedef struct _ATP_RESP
  219. {
  220. #if DBG
  221. ULONG resp_Signature;
  222. #endif
  223. LONG resp_RefCount;
  224. // Linkage of responses on this address object (hash overflow)
  225. struct _ATP_RESP * resp_Next;
  226. struct _ATP_RESP ** resp_Prev;
  227. LIST_ENTRY resp_List; // List of resp for release timer
  228. // BackPointer to the ATP address object
  229. PATP_ADDROBJ resp_pAtpAddr;
  230. // Transaction id
  231. USHORT resp_Tid;
  232. // ATP Bitmap from corresponding request
  233. BYTE resp_Bitmap;
  234. BYTE resp_UserBytesOnly;
  235. // Destination of this request
  236. ATALK_ADDR resp_Dest;
  237. // State of the response
  238. USHORT resp_Flags;
  239. // User's response buffer
  240. USHORT resp_BufLen;
  241. PAMDL resp_Buf;
  242. union
  243. {
  244. BYTE resp_UserBytes[ATP_USERBYTES_SIZE];
  245. DWORD resp_dwUserBytes;
  246. };
  247. // Release timer value, How long do we wait before release.
  248. LONG resp_RelTimerTicks;
  249. // Release time stamp, time at which the request arrived.
  250. LONG resp_RelTimeStamp;
  251. // Routine to call when release comes in, or release timer expires
  252. ATALK_ERROR resp_CompStatus;
  253. ATP_REL_HANDLER resp_Comp;
  254. PVOID resp_Ctx;
  255. ATALK_SPIN_LOCK resp_Lock;
  256. } ATP_RESP, *PATP_RESP;
  257. #define ATP_RETRY_TIMER_INTERVAL 10 // 1 second in 100ms units
  258. // NOTE: This will essentially put dampers on
  259. // the RT stuff. Thats not too bad since
  260. // we are guaranteed to try every second atleast
  261. #define ATP_RELEASE_TIMER_INTERVAL 300 // 30 seconds in 100ms units
  262. // Values for the 0.5, 1, 2, 4, 8 minute timer in ATP_RELEASE_TIMER_INTERVAL units.
  263. extern SHORT AtalkAtpRelTimerTicks[MAX_VALID_TIMERS];
  264. // Bitmaps for the sequence numbers in response packets.
  265. extern BYTE AtpBitmapForSeqNum[ATP_MAX_RESP_PKTS];
  266. extern BYTE AtpEomBitmapForSeqNum[ATP_MAX_RESP_PKTS];
  267. typedef struct
  268. {
  269. BYTE atph_CmdCtrl;
  270. union
  271. {
  272. BYTE atph_SeqNum;
  273. BYTE atph_Bitmap;
  274. };
  275. USHORT atph_Tid;
  276. union
  277. {
  278. BYTE atph_UserBytes[ATP_USERBYTES_SIZE];
  279. DWORD atph_dwUserBytes;
  280. };
  281. } ATP_HEADER, *PATP_HEADER;
  282. // Exported prototypes
  283. #define AtalkAtpGetDdpAddress(pAtpAddr) ((pAtpAddr)->atpao_DdpAddr)
  284. extern
  285. ATALK_ERROR
  286. AtalkAtpOpenAddress(
  287. IN PPORT_DESCRIPTOR pPort,
  288. IN BYTE Socket,
  289. IN OUT PATALK_NODEADDR pDesiredNode OPTIONAL,
  290. IN USHORT MaxSinglePktSize,
  291. IN BOOLEAN SendUserBytesAll,
  292. IN PATALK_DEV_CTX pDevCtx OPTIONAL,
  293. IN BOOLEAN CacheSocket,
  294. OUT PATP_ADDROBJ * ppAtpAddr);
  295. extern
  296. ATALK_ERROR
  297. AtalkAtpCleanupAddress(
  298. IN PATP_ADDROBJ pAtpAddr);
  299. extern
  300. ATALK_ERROR
  301. AtalkAtpCloseAddress(
  302. IN PATP_ADDROBJ pAddr,
  303. IN ATPAO_CLOSECOMPLETION pCloseCmp OPTIONAL,
  304. IN PVOID pCloseCtx OPTIONAL);
  305. extern
  306. ATALK_ERROR
  307. AtalkAtpPostReq(
  308. IN PATP_ADDROBJ pAddr,
  309. IN PATALK_ADDR pDest,
  310. OUT PUSHORT pTid,
  311. IN USHORT Flags,
  312. IN PAMDL pReq,
  313. IN USHORT ReqLen,
  314. IN PBYTE pUserBytes OPTIONAL,
  315. IN OUT PAMDL pResp OPTIONAL,
  316. IN USHORT RespLen,
  317. IN SHORT RetryCnt,
  318. IN LONG RetryInterval,
  319. IN RELEASE_TIMERVALUE timerVal,
  320. IN ATP_RESP_HANDLER pCmpRoutine OPTIONAL,
  321. IN PVOID pCtx OPTIONAL);
  322. extern
  323. VOID
  324. AtalkAtpSetReqHandler(
  325. IN PATP_ADDROBJ pAddr,
  326. IN ATP_REQ_HANDLER ReqHandler,
  327. IN PVOID ReqCtx OPTIONAL);
  328. extern
  329. ATALK_ERROR
  330. AtalkAtpPostResp(
  331. IN PATP_RESP pAtpResp,
  332. IN PATALK_ADDR pDest,
  333. IN OUT PAMDL pResp,
  334. IN USHORT RespLen,
  335. IN PBYTE pUbytes OPTIONAL,
  336. IN ATP_REL_HANDLER pCmpRoutine,
  337. IN PVOID pCtx OPTIONAL);
  338. extern
  339. ATALK_ERROR
  340. AtalkAtpCancelReq(
  341. IN PATP_ADDROBJ pAtpAddr,
  342. IN USHORT Tid,
  343. IN PATALK_ADDR pDest);
  344. extern
  345. BOOLEAN
  346. AtalkAtpIsReqComplete(
  347. IN PATP_ADDROBJ pAtpAddr,
  348. IN USHORT Tid,
  349. IN PATALK_ADDR pDest);
  350. extern
  351. ATALK_ERROR
  352. AtalkAtpCancelResp(
  353. IN PATP_RESP pAtpResp);
  354. extern
  355. ATALK_ERROR
  356. AtalkAtpCancelRespByTid(
  357. IN PATP_ADDROBJ pAtpAddr,
  358. IN PATALK_ADDR pDest,
  359. IN USHORT Tid);
  360. extern
  361. VOID
  362. AtalkAtpPacketIn(
  363. IN PPORT_DESCRIPTOR pPortDesc,
  364. IN PDDP_ADDROBJ pDdpAddr,
  365. IN PBYTE pPkt,
  366. IN USHORT PktLen,
  367. IN PATALK_ADDR pSrcAddr,
  368. IN PATALK_ADDR pDstAddr,
  369. IN ATALK_ERROR ErrorCode,
  370. IN BYTE DdpType,
  371. IN PATP_ADDROBJ pAtpAddr,
  372. IN BOOLEAN OptimizePath,
  373. IN PVOID OptimizeCtx);
  374. #define AtalkAtpAddrReference(_pAtpAddr, _pError) \
  375. { \
  376. KIRQL OldIrql; \
  377. \
  378. ACQUIRE_SPIN_LOCK(&(_pAtpAddr)->atpao_Lock, &OldIrql); \
  379. atalkAtpAddrRefNonInterlock((_pAtpAddr), _pError); \
  380. RELEASE_SPIN_LOCK(&(_pAtpAddr)->atpao_Lock, OldIrql); \
  381. }
  382. #define AtalkAtpAddrReferenceDpc(_pAtpAddr, _pError) \
  383. { \
  384. ACQUIRE_SPIN_LOCK_DPC(&(_pAtpAddr)->atpao_Lock); \
  385. atalkAtpAddrRefNonInterlock((_pAtpAddr), _pError); \
  386. RELEASE_SPIN_LOCK_DPC(&(_pAtpAddr)->atpao_Lock); \
  387. }
  388. #define atalkAtpAddrRefNonInterlock(_pAtpAddr, _pError) \
  389. { \
  390. *(_pError) = ATALK_NO_ERROR; \
  391. if (((_pAtpAddr)->atpao_Flags & (ATPAO_CLOSING|ATPAO_OPEN))==ATPAO_OPEN)\
  392. { \
  393. ASSERT((_pAtpAddr)->atpao_RefCount >= 1); \
  394. (_pAtpAddr)->atpao_RefCount++; \
  395. } \
  396. else \
  397. { \
  398. *(_pError) = ATALK_ATP_CLOSING; \
  399. DBGPRINT(DBG_COMP_ATP, DBG_LEVEL_WARN, \
  400. ("atalkAtpAddrRefNonInterlock: %lx %s (%ld) Failure\n", \
  401. _pAtpAddr, __FILE__, __LINE__)); \
  402. } \
  403. }
  404. VOID FASTCALL
  405. AtalkAtpAddrDeref(
  406. IN OUT PATP_ADDROBJ pAtpAddr,
  407. IN BOOLEAN AtDpc);
  408. #define AtalkAtpAddrDereference(_pAtpAddr) \
  409. AtalkAtpAddrDeref(_pAtpAddr, FALSE)
  410. #define AtalkAtpAddrDereferenceDpc(_pAtpAddr) \
  411. AtalkAtpAddrDeref(_pAtpAddr, TRUE)
  412. VOID FASTCALL
  413. AtalkAtpRespDeref(
  414. IN PATP_RESP pAtpResp,
  415. IN BOOLEAN AtDpc);
  416. #define AtalkAtpRespDereference(_pAtrpResp) \
  417. AtalkAtpRespDeref(_pAtrpResp, FALSE)
  418. #define AtalkAtpRespDereferenceDpc(_pAtrpResp) \
  419. AtalkAtpRespDeref(_pAtrpResp, TRUE)
  420. #define AtalkAtpRespReferenceByPtr(_pAtpResp, _pError) \
  421. { \
  422. KIRQL OldIrql; \
  423. \
  424. *(_pError) = ATALK_NO_ERROR; \
  425. \
  426. ACQUIRE_SPIN_LOCK(&(_pAtpResp)->resp_Lock, &OldIrql); \
  427. if (((_pAtpResp)->resp_Flags & ATP_RESP_CLOSING) == 0) \
  428. { \
  429. (_pAtpResp)->resp_RefCount++; \
  430. } \
  431. else \
  432. { \
  433. DBGPRINT(DBG_COMP_ATP, DBG_LEVEL_WARN, \
  434. ("AtalkAtpRespReferenceByPtr: %lx %s (%ld) Failure\n", \
  435. _pAtpResp, __FILE__, __LINE__)); \
  436. *(_pError) = ATALK_ATP_RESP_CLOSING; \
  437. } \
  438. RELEASE_SPIN_LOCK(&(_pAtpResp)->resp_Lock, OldIrql); \
  439. }
  440. #define AtalkAtpRespReferenceByPtrDpc(_pAtpResp, _pError) \
  441. { \
  442. *(_pError) = ATALK_NO_ERROR; \
  443. \
  444. ACQUIRE_SPIN_LOCK_DPC(&(_pAtpResp)->resp_Lock); \
  445. if (((_pAtpResp)->resp_Flags & ATP_RESP_CLOSING) == 0) \
  446. { \
  447. (_pAtpResp)->resp_RefCount++; \
  448. } \
  449. else \
  450. { \
  451. *(_pError) = ATALK_ATP_RESP_CLOSING; \
  452. DBGPRINT(DBG_COMP_ATP, DBG_LEVEL_WARN, \
  453. ("atalkAtpRespRefByPtrDpc: %lx %s (%ld) Failure\n", \
  454. _pAtpResp, __FILE__, __LINE__)); \
  455. } \
  456. RELEASE_SPIN_LOCK_DPC(&(_pAtpResp)->resp_Lock); \
  457. }
  458. ATALK_ERROR
  459. AtalkIndAtpPkt(
  460. IN PPORT_DESCRIPTOR pPortDesc,
  461. IN PBYTE pLookahead,
  462. IN USHORT PktLen,
  463. IN OUT PUINT pXferOffset,
  464. IN PBYTE pLinkHdr,
  465. IN BOOLEAN ShortDdpHdr,
  466. OUT PBYTE SubType,
  467. OUT PBYTE * ppPacket,
  468. OUT PNDIS_PACKET * pNdisPkt);
  469. ATALK_ERROR
  470. AtalkIndAtpCacheSocket(
  471. IN struct _ATP_ADDROBJ * pAtpAddr,
  472. IN PPORT_DESCRIPTOR pPortDesc);
  473. VOID
  474. AtalkIndAtpUnCacheSocket(
  475. IN struct _ATP_ADDROBJ * pAtpAddr);
  476. VOID FASTCALL
  477. AtalkAtpGenericRespComplete(
  478. IN ATALK_ERROR ErrorCode,
  479. IN PATP_RESP pAtpResp
  480. );
  481. VOID FASTCALL
  482. AtalkIndAtpSetupNdisBuffer(
  483. IN OUT PATP_REQ pAtpReq,
  484. IN ULONG MaxSinglePktSize
  485. );
  486. VOID FASTCALL
  487. AtalkIndAtpReleaseNdisBuffer(
  488. IN OUT PATP_REQ pAtpReq
  489. );
  490. // ATALK_ERROR
  491. // AtalkIndAtpCacheLkUpSocket(
  492. // IN PATALK_ADDR pDestAddr,
  493. // OUT struct _ATP_ADDROBJ ** ppAtpAddr,
  494. // OUT ATALK_ERROR * pError);
  495. //
  496. #define AtalkIndAtpCacheLkUpSocket(pDestAddr, ppAtpAddr, pError) \
  497. { \
  498. USHORT i; \
  499. struct ATALK_CACHED_SKT *pCachedSkt; \
  500. \
  501. *(pError) = ATALK_FAILURE; \
  502. \
  503. if (((pDestAddr)->ata_Network == AtalkSktCache.ac_Network) && \
  504. ((pDestAddr)->ata_Node == AtalkSktCache.ac_Node)) \
  505. { \
  506. ACQUIRE_SPIN_LOCK_DPC(&AtalkSktCacheLock); \
  507. \
  508. for (i = 0, pCachedSkt = &AtalkSktCache.ac_Cache[0]; \
  509. i < ATALK_CACHE_SKTMAX; \
  510. i++, pCachedSkt++) \
  511. { \
  512. if ((pCachedSkt->Type == (ATALK_CACHE_INUSE | ATALK_CACHE_ATPSKT)) && \
  513. (pCachedSkt->Socket == (pDestAddr)->ata_Socket))\
  514. { \
  515. AtalkAtpAddrReferenceDpc(pCachedSkt->u.pAtpAddr,\
  516. pError); \
  517. \
  518. if (ATALK_SUCCESS(*pError)) \
  519. { \
  520. *(ppAtpAddr) = pCachedSkt->u.pAtpAddr; \
  521. } \
  522. break; \
  523. } \
  524. } \
  525. \
  526. RELEASE_SPIN_LOCK_DPC(&AtalkSktCacheLock); \
  527. } \
  528. }
  529. VOID FASTCALL
  530. atalkAtpReqDeref(
  531. IN PATP_REQ pAtpReq,
  532. IN BOOLEAN AtDpc);
  533. // MACROS
  534. // Top byte of network number is pretty static so we get rid of it and add
  535. // in the tid.
  536. #define ATP_HASH_TID_DESTADDR(_tid, _pAddr, _BucketSize) \
  537. (((_pAddr)->ata_Node+((_pAddr)->ata_Network & 0xFF)+_tid)%(_BucketSize))
  538. #define atalkAtpReqReferenceByAddrTidDpc(_pAtpAddr, _pAddr, _Tid, _ppAtpReq, _pErr) \
  539. { \
  540. PATP_REQ __p; \
  541. ULONG __i; \
  542. \
  543. DBGPRINT(DBG_COMP_ATP, DBG_LEVEL_INFO, \
  544. ("atalkAtpReqRefByAddrTid: %lx.%lx.%lx tid %lx\n", \
  545. (_pAddr)->ata_Network, (_pAddr)->ata_Node, \
  546. (_pAddr)->ata_Socket, (_Tid))); \
  547. \
  548. __i = ATP_HASH_TID_DESTADDR((_Tid), (_pAddr), ATP_REQ_HASH_SIZE); \
  549. for (__p = (_pAtpAddr)->atpao_ReqHash[(__i)]; \
  550. __p != NULL; \
  551. __p = __p->req_Next) \
  552. { \
  553. if ((ATALK_ADDRS_EQUAL(&__p->req_Dest, (_pAddr))) && \
  554. (__p->req_Tid == (_Tid))) \
  555. { \
  556. AtalkAtpReqReferenceByPtrDpc(__p, _pErr); \
  557. if (ATALK_SUCCESS(*(_pErr))) \
  558. { \
  559. *(_ppAtpReq) = __p; \
  560. DBGPRINT(DBG_COMP_ATP, DBG_LEVEL_INFO, \
  561. ("atalkAtpReqRefByAddrTid: FOUND %lx\n", __p)); \
  562. } \
  563. break; \
  564. } \
  565. } \
  566. if (__p == NULL) \
  567. *(_pErr) = ATALK_ATP_NOT_FOUND; \
  568. }
  569. #define AtalkAtpReqReferenceByPtr(_pAtpReq, _pErr) \
  570. { \
  571. KIRQL OldIrql; \
  572. \
  573. *(_pErr) = ATALK_NO_ERROR; \
  574. \
  575. ACQUIRE_SPIN_LOCK(&(_pAtpReq)->req_Lock, &OldIrql); \
  576. if (((_pAtpReq)->req_Flags & ATP_REQ_CLOSING) == 0) \
  577. { \
  578. (_pAtpReq)->req_RefCount++; \
  579. } \
  580. else \
  581. { \
  582. DBGPRINT(DBG_COMP_ATP, DBG_LEVEL_WARN, \
  583. ("AtalkAtpReqReferenceByPtr: %lx %s (%ld) Failure\n", \
  584. _pAtpReq, __FILE__, __LINE__)); \
  585. *(_pErr) = ATALK_ATP_REQ_CLOSING; \
  586. } \
  587. RELEASE_SPIN_LOCK(&(_pAtpReq)->req_Lock, OldIrql); \
  588. }
  589. #define AtalkAtpReqReferenceByPtrDpc(_pAtpReq, _pErr) \
  590. { \
  591. *(_pErr) = ATALK_NO_ERROR; \
  592. \
  593. ACQUIRE_SPIN_LOCK_DPC(&(_pAtpReq)->req_Lock); \
  594. if (((_pAtpReq)->req_Flags & ATP_REQ_CLOSING) == 0) \
  595. { \
  596. (_pAtpReq)->req_RefCount++; \
  597. } \
  598. else \
  599. { \
  600. *(_pErr) = ATALK_ATP_REQ_CLOSING; \
  601. DBGPRINT(DBG_COMP_ATP, DBG_LEVEL_WARN, \
  602. ("AtalkAtpReqReferenceByPtrDpc: %lx %s (%ld) Failure\n", \
  603. _pAtpReq, __FILE__, __LINE__)); \
  604. } \
  605. RELEASE_SPIN_LOCK_DPC(&(_pAtpReq)->req_Lock); \
  606. }
  607. #define atalkAtpRespReferenceNDpc(_pAtpResp, _N, _pError) \
  608. { \
  609. *(_pError) = ATALK_NO_ERROR; \
  610. ACQUIRE_SPIN_LOCK_DPC(&(_pAtpResp)->resp_Lock); \
  611. if (((_pAtpResp)->resp_Flags & ATP_RESP_CLOSING) == 0) \
  612. { \
  613. (_pAtpResp)->resp_RefCount += _N; \
  614. } \
  615. else \
  616. { \
  617. *(_pError) = ATALK_ATP_RESP_CLOSING; \
  618. DBGPRINT(DBG_COMP_ATP, DBG_LEVEL_WARN, \
  619. ("atalkAtpRespReferenceNDpc: %lx %d %s (%ld) Failure\n", \
  620. _pAtpResp, _N, __FILE__, __LINE__)); \
  621. } \
  622. RELEASE_SPIN_LOCK_DPC(&(_pAtpResp)->resp_Lock); \
  623. }
  624. // THIS SHOULD BE CALLED WITH ADDRESS LOCK HELD !!!
  625. #define atalkAtpRespReferenceByAddrTidDpc(_pAtpAddr, _pAddr, _Tid, _ppAtpResp, _pErr)\
  626. { \
  627. PATP_RESP __p; \
  628. ULONG __i; \
  629. \
  630. __i = ATP_HASH_TID_DESTADDR((_Tid), (_pAddr), ATP_RESP_HASH_SIZE); \
  631. \
  632. DBGPRINT(DBG_COMP_ATP, DBG_LEVEL_INFO, \
  633. ("atalkAtpRespRefByAddrTid: %lx.%lx.%lx tid %lx\n", \
  634. (_pAddr)->ata_Network, (_pAddr)->ata_Node, \
  635. (_pAddr)->ata_Socket, (_Tid))); \
  636. \
  637. for (__p = (_pAtpAddr)->atpao_RespHash[__i]; \
  638. __p != NULL; \
  639. __p = __p->resp_Next) \
  640. { \
  641. if (ATALK_ADDRS_EQUAL(&__p->resp_Dest, _pAddr) && \
  642. (__p->resp_Tid == (_Tid))) \
  643. { \
  644. AtalkAtpRespReferenceByPtrDpc(__p, _pErr); \
  645. if (ATALK_SUCCESS((*(_pErr)))) \
  646. { \
  647. *(_ppAtpResp) = __p; \
  648. DBGPRINT(DBG_COMP_ATP, DBG_LEVEL_INFO, \
  649. ("atalkAtpRespRefByAddrTid: FOUND %lx\n", __p)); \
  650. } \
  651. break; \
  652. } \
  653. } \
  654. if (__p == NULL) \
  655. *(_pErr) = ATALK_ATP_NOT_FOUND; \
  656. }
  657. #define AtalkAtpReqDereference(_pAtpReq) \
  658. atalkAtpReqDeref(_pAtpReq, FALSE)
  659. #define AtalkAtpReqDereferenceDpc(_pAtpReq) \
  660. atalkAtpReqDeref(_pAtpReq, TRUE)
  661. VOID FASTCALL
  662. atalkAtpTransmitReq(
  663. IN PATP_REQ pAtpReq);
  664. VOID FASTCALL
  665. atalkAtpTransmitResp(
  666. IN PATP_RESP pAtpResp);
  667. VOID FASTCALL
  668. atalkAtpTransmitRel(
  669. IN PATP_REQ pAtpReq);
  670. VOID
  671. atalkAtpGetNextTidForAddr(
  672. IN PATP_ADDROBJ pAtpAddr,
  673. IN PATALK_ADDR pRemoteAddr,
  674. OUT PUSHORT pTid,
  675. OUT PULONG pIndex);
  676. LOCAL LONG FASTCALL
  677. atalkAtpReqTimer(
  678. IN PTIMERLIST pTimer,
  679. IN BOOLEAN TimerShuttingDown);
  680. LOCAL LONG FASTCALL
  681. atalkAtpRelTimer(
  682. IN PTIMERLIST pTimer,
  683. IN BOOLEAN TimerShuttingDown);
  684. #define atalkAtpBufferSizeToBitmap(_Bitmap, _BufSize, _SinglePktSize) \
  685. { \
  686. SHORT __bufSize = (_BufSize); \
  687. \
  688. (_Bitmap) = 0; \
  689. while(__bufSize > 0) \
  690. { \
  691. (_Bitmap) = ((_Bitmap) <<= 1) | 1; \
  692. __bufSize -= (_SinglePktSize); \
  693. } \
  694. }
  695. #define atalkAtpBitmapToBufferSize(_Size, _Bitmap, _SinglePktSize) \
  696. { \
  697. BYTE __bitmap = (_Bitmap); \
  698. BOOLEAN __bitOn; \
  699. \
  700. _Size = 0; \
  701. while (__bitmap) \
  702. { \
  703. __bitOn = (__bitmap & 1); \
  704. __bitmap >>= 1; \
  705. if (__bitOn) \
  706. { \
  707. (_Size) += (_SinglePktSize); \
  708. } \
  709. else \
  710. { \
  711. if (__bitmap) \
  712. { \
  713. (_Size) = -1; \
  714. } \
  715. break; \
  716. } \
  717. } \
  718. }
  719. VOID FASTCALL
  720. atalkAtpSendReqComplete(
  721. IN NDIS_STATUS Status,
  722. IN PSEND_COMPL_INFO pSendInfo);
  723. VOID FASTCALL
  724. atalkAtpSendRespComplete(
  725. IN NDIS_STATUS Status,
  726. IN PSEND_COMPL_INFO pSendInfo);
  727. VOID FASTCALL
  728. atalkAtpSendRelComplete(
  729. IN NDIS_STATUS Status,
  730. IN PSEND_COMPL_INFO pSendInfo);
  731. VOID
  732. atalkAtpRespRefNextNc(
  733. IN PATP_RESP pAtpResp,
  734. OUT PATP_RESP * ppNextNcResp,
  735. OUT PATALK_ERROR pError);
  736. VOID
  737. atalkAtpReqRefNextNc(
  738. IN PATP_REQ pAtpReq,
  739. OUT PATP_REQ * pNextNcReq,
  740. OUT PATALK_ERROR pError);
  741. VOID FASTCALL
  742. atalkAtpRespComplete(
  743. IN OUT PATP_RESP pAtpResp,
  744. IN ATALK_ERROR CompletionStatus);
  745. VOID FASTCALL
  746. atalkAtpReqComplete(
  747. IN OUT PATP_REQ pAtpReq,
  748. IN ATALK_ERROR CompletionStatus);
  749. #endif // _ATP_
  750.