|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* ! 23: * ! 24: * ORIGINS: 82 ! 25: * ! 26: * (C) COPYRIGHT Apple Computer, Inc. 1992-1996 ! 27: * All Rights Reserved ! 28: * ! 29: */ ! 30: ! 31: /* Definitions for ATP protocol and streams module, per ! 32: * AppleTalk Transaction Protocol documentation from ! 33: * `Inside AppleTalk', July 14, 1986. ! 34: */ ! 35: ! 36: /* ! 37: * Copyright (c) 1988, 1989 Apple Computer, Inc. ! 38: * ! 39: * The information contained herein is subject to change without ! 40: * notice and should not be construed as a commitment by Apple ! 41: * Computer, Inc. Apple Computer, Inc. assumes no responsibility ! 42: * for any errors that may appear. ! 43: * ! 44: * Confidential and Proprietary to Apple Computer, Inc. ! 45: */ ! 46: ! 47: #ifndef _NETAT_ATP_H_ ! 48: #define _NETAT_ATP_H_ ! 49: ! 50: /* ATP function codes */ ! 51: ! 52: #define ATP_CMD_TREQ 0x01 /* TRequest packet */ ! 53: #define ATP_CMD_TRESP 0x02 /* TResponse packet */ ! 54: #define ATP_CMD_TREL 0x03 /* TRelease packet */ ! 55: ! 56: /* Miscellaneous definitions */ ! 57: ! 58: #define ATP_DEF_RETRIES 8 /* Default for maximum retry count */ ! 59: #define ATP_DEF_INTERVAL 2 /* Default for retry interval in seconds */ ! 60: ! 61: #define ATP_TRESP_MAX 8 /* Maximum number of Tresp pkts */ ! 62: ! 63: #define ATP_HDR_SIZE 8 /* Size of the ATP header */ ! 64: #define ATP_DATA_SIZE 578 /* Maximum size of the ATP data area */ ! 65: ! 66: /* Consts for asynch support */ ! 67: #define ATP_ASYNCH_REQ 1 ! 68: #define ATP_ASYNCH_RESP 2 ! 69: ! 70: /* Timer values for XO release timers */ ! 71: #define ATP_XO_DEF_REL_TIME 0 ! 72: #define ATP_XO_30SEC 0 ! 73: #define ATP_XO_1MIN 1 ! 74: #define ATP_XO_2MIN 2 ! 75: #define ATP_XO_4MIN 3 ! 76: #define ATP_XO_8MIN 4 ! 77: ! 78: typedef struct { ! 79: unsigned cmd : 2, ! 80: xo : 1, ! 81: eom : 1, ! 82: sts : 1, ! 83: xo_relt : 3; ! 84: u_char bitmap; ! 85: ua_short tid; ! 86: ua_long user_bytes; ! 87: u_char data[ATP_DATA_SIZE]; ! 88: } at_atp_t; ! 89: ! 90: #define ATP_ATP_HDR(c) ((at_atp_t *)(&((at_ddp_t *)(c))->data[0])) ! 91: ! 92: #define TOTAL_ATP_HDR_SIZE (ATP_HDR_SIZE+DDP_X_HDR_SIZE) ! 93: #define ATP_CLEAR_CONTROL(c) (*(char *)(c) = 0) ! 94: ! 95: /* ATP ioctl interface */ ! 96: ! 97: /* Structure for the atp_set_default call */ ! 98: ! 99: #define ATP_INFINITE_RETRIES 0xffffffff /* means retry forever ! 100: * in the def_retries field ! 101: */ ! 102: ! 103: struct atp_set_default { ! 104: u_int def_retries; /* number of retries for a request */ ! 105: u_int def_rate; /* retry rate (in seconds/100) NB: the ! 106: * system may not be able to resolve ! 107: * delays of 100th of a second but will ! 108: * instead make a 'best effort' ! 109: */ ! 110: struct atpBDS *def_bdsp; /* BDS structure associated with this req */ ! 111: u_int def_BDSlen; /* size of BDS structure */ ! 112: }; ! 113: ! 114: ! 115: /* Return header from requests */ ! 116: ! 117: struct atp_result { ! 118: u_short count; /* the number of packets */ ! 119: u_short hdr; /* offset to header in buffer */ ! 120: u_short offset[8]; /* offset to the Nth packet in the buffer */ ! 121: u_short len[8]; /* length of the Nth packet */ ! 122: }; ! 123: ! 124: struct atpBDS { ! 125: ua_short bdsBuffSz; ! 126: ua_long bdsBuffAddr; ! 127: ua_short bdsDataSz; ! 128: unsigned char bdsUserData[4]; ! 129: }; ! 130: ! 131: ! 132: typedef struct { ! 133: u_short at_atpreq_type; ! 134: at_inet_t at_atpreq_to; ! 135: u_char at_atpreq_treq_user_bytes[4]; ! 136: u_char *at_atpreq_treq_data; ! 137: u_short at_atpreq_treq_length; ! 138: u_char at_atpreq_treq_bitmap; ! 139: u_char at_atpreq_xo; ! 140: u_char at_atpreq_xo_relt; ! 141: u_short at_atpreq_retry_timeout; ! 142: u_short at_atpreq_maximum_retries; ! 143: u_char at_atpreq_tresp_user_bytes[ATP_TRESP_MAX][4]; ! 144: u_char *at_atpreq_tresp_data[ATP_TRESP_MAX]; ! 145: u_short at_atpreq_tresp_lengths[ATP_TRESP_MAX]; ! 146: u_long at_atpreq_debug[4]; ! 147: u_short at_atpreq_tid; ! 148: u_char at_atpreq_tresp_bitmap; ! 149: u_char at_atpreq_tresp_eom_seqno; ! 150: u_char at_atpreq_got_trel; ! 151: } at_atpreq; ! 152: ! 153: ! 154: /* The ATP module ioctl commands */ ! 155: ! 156: #define AT_ATP_CANCEL_REQUEST (('|'<<8)|1) ! 157: #define AT_ATP_ISSUE_REQUEST (('|'<<8)|2) /* ALO */ ! 158: #define AT_ATP_ISSUE_REQUEST_DEF (('|'<<8)|3) /* XO */ ! 159: #define AT_ATP_ISSUE_REQUEST_DEF_NOTE (('|'<<8)|4) /* XO & nowait -- not needed*/ ! 160: #define AT_ATP_ISSUE_REQUEST_NOTE (('|'<<8)|5) /* ALO & nowait */ ! 161: #define AT_ATP_GET_POLL (('|'<<8)|6) ! 162: #define AT_ATP_RELEASE_RESPONSE (('|'<<8)|7) ! 163: #define AT_ATP_REQUEST_COMPLETE (('|'<<8)|8) ! 164: #define AT_ATP_SEND_FULL_RESPONSE (('|'<<8)|9) /* not used */ ! 165: #define AT_ATP_BIND_REQ (('|'<<8)|10) ! 166: #define AT_ATP_GET_CHANID (('|'<<8)|11) ! 167: #define AT_ATP_PEEK (('|'<<8)|12) ! 168: #define AT_ATP_ISSUE_REQUEST_TICKLE (('|'<<8)|13) /* ALO & nowait */ ! 169: ! 170: /* These macros don't really depend here, but since they're used only by the ! 171: * old ATP and old PAP, they're put here. Unisoft PAP includes this file. ! 172: */ ! 173: #define R16(x) UAS_VALUE(x) ! 174: #define W16(x,v) UAS_ASSIGN(x, v) ! 175: #define C16(x,v) UAS_UAS(x, v) ! 176: ! 177: /* ! 178: * these are the dispatch codes for ! 179: * the new atp_control system call ! 180: */ ! 181: #define ATP_SENDREQUEST 0 ! 182: #define ATP_GETRESPONSE 1 ! 183: #define ATP_SENDRESPONSE 2 ! 184: #define ATP_GETREQUEST 3 ! 185: ! 186: #ifdef KERNEL ! 187: ! 188: ! 189: ! 190: /* ! 191: * Stuff for accessing protocol headers ! 192: */ ! 193: #define AT_DDP_HDR(m) ((at_ddp_t *)(gbuf_rptr(m))) ! 194: #define AT_ATP_HDR(m) ((at_atp_t *)(&((at_ddp_t *)(gbuf_rptr(m)))->data[0])) ! 195: ! 196: /* ! 197: * Masks for accessing/manipulating the bitmap field in atp headers ! 198: */ ! 199: ! 200: #ifdef ATP_DECLARE ! 201: unsigned char atp_mask [] = { ! 202: 0x01, 0x02, 0x04, 0x08, ! 203: 0x10, 0x20, 0x40, 0x80, ! 204: }; ! 205: ! 206: unsigned char atp_lomask [] = { ! 207: 0x00, 0x01, 0x03, 0x07, ! 208: 0x0f, 0x1f, 0x3f, 0x7f, ! 209: 0xff ! 210: }; ! 211: #else ! 212: extern unsigned char atp_mask []; ! 213: extern unsigned char atp_lomask []; ! 214: #endif /* ATP_DECLARE */ ! 215: ! 216: /* ! 217: * doubly linked queue types and primitives ! 218: */ ! 219: ! 220: #define ATP_Q_ENTER(hdr, object, entry) { \ ! 221: if ((hdr).head) { \ ! 222: (hdr).head->entry.prev = (object); \ ! 223: (object)->entry.next = (hdr).head; \ ! 224: } else { \ ! 225: (hdr).tail = (object); \ ! 226: (object)->entry.next = NULL; \ ! 227: } \ ! 228: (object)->entry.prev = NULL; \ ! 229: (hdr).head = (object); \ ! 230: } ! 231: ! 232: #define ATP_Q_APPEND(hdr, object, entry) { \ ! 233: if ((hdr).head) { \ ! 234: (hdr).tail->entry.next = (object); \ ! 235: (object)->entry.prev = (hdr).tail; \ ! 236: } else { \ ! 237: (hdr).head = (object); \ ! 238: (object)->entry.prev = NULL; \ ! 239: } \ ! 240: (object)->entry.next = NULL; \ ! 241: (hdr).tail = (object); \ ! 242: } ! 243: ! 244: #define ATP_Q_REMOVE(hdr, object, entry) { \ ! 245: if ((object)->entry.prev) { \ ! 246: (object)->entry.prev->entry.next = (object)->entry.next;\ ! 247: } else { \ ! 248: (hdr).head = (object)->entry.next; \ ! 249: } \ ! 250: if ((object)->entry.next) { \ ! 251: (object)->entry.next->entry.prev = (object)->entry.prev;\ ! 252: } else { \ ! 253: (hdr).tail = (object)->entry.prev; \ ! 254: } \ ! 255: } ! 256: ! 257: struct atp_rcb_qhead { ! 258: struct atp_rcb *head; ! 259: struct atp_rcb *tail; ! 260: }; ! 261: ! 262: struct atp_rcb_q { ! 263: struct atp_rcb *prev; ! 264: struct atp_rcb *next; ! 265: }; ! 266: ! 267: struct atp_trans_qhead { ! 268: struct atp_trans *head; ! 269: struct atp_trans *tail; ! 270: }; ! 271: ! 272: struct atp_trans_q { ! 273: struct atp_trans *prev; ! 274: struct atp_trans *next; ! 275: }; ! 276: ! 277: /* ! 278: * Locally saved remote node address ! 279: */ ! 280: ! 281: struct atp_socket { ! 282: u_short net; ! 283: at_node node; ! 284: at_socket socket; ! 285: }; ! 286: ! 287: /* ! 288: * transaction control block (local context at requester end) ! 289: */ ! 290: ! 291: struct atp_trans { ! 292: struct atp_trans_q tr_list; /* trans list */ ! 293: struct atp_state *tr_queue; /* state data structure */ ! 294: gbuf_t *tr_xmt; /* message being sent */ ! 295: gbuf_t *tr_rcv[8]; /* message being rcvd */ ! 296: unsigned int tr_retry; /* # retries left */ ! 297: unsigned int tr_timeout; /* timer interval */ ! 298: char tr_state; /* current state */ ! 299: char tr_rsp_wait; /* waiting for transaction response */ ! 300: char filler[2]; ! 301: unsigned char tr_xo; /* execute once transaction */ ! 302: unsigned char tr_bitmap; /* requested bitmask */ ! 303: unsigned short tr_tid; /* transaction id */ ! 304: struct atp_socket tr_socket; /* the remote socket id */ ! 305: struct atp_trans_q tr_snd_wait; /* list of transactions waiting ! 306: for space to send a msg */ ! 307: at_socket tr_local_socket; ! 308: at_node tr_local_node; ! 309: at_net tr_local_net; ! 310: gbuf_t *tr_bdsp; /* bds structure pointer */ ! 311: unsigned int tr_tmo_delta; ! 312: void (*tr_tmo_func)(); ! 313: struct atp_trans *tr_tmo_next; ! 314: struct atp_trans *tr_tmo_prev; ! 315: atlock_t tr_lock; ! 316: atevent_t tr_event; ! 317: }; ! 318: ! 319: #define TRANS_TIMEOUT 0 /* waiting for a reply */ ! 320: #define TRANS_REQUEST 1 /* waiting to send a request */ ! 321: #define TRANS_RELEASE 2 /* waiting to send a release */ ! 322: #define TRANS_DONE 3 /* done - waiting for poll to complete */ ! 323: #define TRANS_FAILED 4 /* done - waiting for poll to report failure */ ! 324: ! 325: /* ! 326: * reply control block (local context at repling end) ! 327: */ ! 328: ! 329: struct atp_rcb { ! 330: struct atp_rcb_q rc_list; /* rcb list */ ! 331: struct atp_rcb_q rc_tlist; ! 332: struct atp_state *rc_queue; /* state data structure */ ! 333: gbuf_t *rc_xmt; /* replys being sent */ ! 334: gbuf_t *rc_ioctl; /* waiting ioctl */ ! 335: char rc_snd[8]; /* replys actually to be sent */ ! 336: int rc_pktcnt; /* no of pkts in this trans */ ! 337: short rc_state; /* current state */ ! 338: unsigned char rc_xo; /* execute once transaction */ ! 339: at_node rc_local_node; ! 340: at_net rc_local_net; ! 341: short rc_rep_waiting; /* in the reply wait list */ ! 342: int rc_timestamp; /* reply timer */ ! 343: unsigned char rc_bitmap; /* replied bitmask */ ! 344: unsigned char rc_not_sent_bitmap; /* replied bitmask */ ! 345: unsigned short rc_tid; /* transaction id */ ! 346: struct atp_socket rc_socket; /* the remote socket id */ ! 347: }; ! 348: ! 349: #define RCB_UNQUEUED 0 /* newly allocated, not q'd */ ! 350: #define RCB_RESPONDING 2 /* waiting all of response from process*/ ! 351: #define RCB_RESPONSE_FULL 3 /* got all of response */ ! 352: #define RCB_RELEASED 4 /* got our release */ ! 353: #define RCB_PENDING 5 /* a no wait rcb is full */ ! 354: #define RCB_NOTIFIED 6 ! 355: #define RCB_SENDING 7 /* we're currently xmitting this trans */ ! 356: ! 357: /* ! 358: * socket state (per module data structure) ! 359: */ ! 360: ! 361: struct atp_state { ! 362: gref_t *atp_gref; /* must be the first entry */ ! 363: int atp_pid; /* process id, must be the second entry */ ! 364: gbuf_t *atp_msgq; /* data msg, must be the third entry */ ! 365: unsigned char dflag; /* structure flag, must be the fourth entry */ ! 366: unsigned char filler; ! 367: short atp_socket_no; ! 368: short atp_flags; /* general flags */ ! 369: struct atp_trans_qhead atp_trans_wait; /* pending transaction list */ ! 370: struct atp_state *atp_trans_waiting; /* list of atps waiting for a ! 371: free transaction */ ! 372: unsigned int atp_retry; /* retry count */ ! 373: unsigned int atp_timeout; /* retry timeout */ ! 374: struct atp_state *atp_rcb_waiting; ! 375: struct atp_rcb_qhead atp_rcb; /* active rcbs */ ! 376: struct atp_rcb_qhead atp_attached; /* rcb's waiting to be read */ ! 377: atlock_t atp_lock; ! 378: atevent_t atp_event; ! 379: atlock_t atp_delay_lock; ! 380: atevent_t atp_delay_event; ! 381: }; ! 382: ! 383: ! 384: /* ! 385: * atp_state flag definitions ! 386: */ ! 387: #define ATP_CLOSING 0x08 /* atp stream in process of closing */ ! 388: ! 389: ! 390: /* ! 391: * tcb/rcb/state allocation queues ! 392: */ ! 393: ! 394: /* ! 395: * Size defines; must be outside following #ifdef to permit ! 396: * debugging code to reference independent of ATP_DECLARE ! 397: */ ! 398: #define NATP_RCB 512 /* the number of ATP RCBs at once */ ! 399: #define NATP_STATE 192 /* the number of ATP sockets open at once */ ! 400: /* note: I made NATP_STATE == NSOCKETS */ ! 401: ! 402: #ifdef ATP_DECLARE ! 403: struct atp_trans *atp_trans_free_list = NULL; /* free transactions */ ! 404: struct atp_rcb *atp_rcb_free_list = NULL; /* free rcbs */ ! 405: static struct atp_state *atp_free_list = NULL; /* free atp states */ ! 406: static struct atp_rcb atp_rcb_data[NATP_RCB]; ! 407: static struct atp_state atp_state_data[NATP_STATE]; ! 408: ! 409: #else ! 410: extern struct atp_trans *atp_trans_free_list; /* free transactions */ ! 411: extern struct atp_rcb *atp_rcb_free_list; /* free rcbs */ ! 412: extern struct atp_state *atp_free_list; /* free atp states */ ! 413: extern struct atp_rcb atp_rcb_data[]; ! 414: extern struct atp_state atp_state_data[]; ! 415: ! 416: extern void atp_req_timeout(); ! 417: extern void atp_rcb_timer(); ! 418: extern void atp_x_done(); ! 419: extern struct atp_rcb *atp_rcb_alloc(); ! 420: extern struct atp_trans *atp_trans_alloc(); ! 421: #endif /* ATP_DECLARE */ ! 422: ! 423: /* prototypes */ ! 424: void atp_send_req(gref_t *, gbuf_t *); ! 425: void atp_drop_req(gref_t *, gbuf_t *); ! 426: void atp_send_rsp(gref_t *, gbuf_t *, int); ! 427: void atp_wput(gref_t *, gbuf_t *); ! 428: void atp_rput(gref_t *, gbuf_t *); ! 429: void atp_retry_req(gbuf_t *); ! 430: void atp_stop(gbuf_t *, int); ! 431: void atp_cancel_req(gref_t *, unsigned short); ! 432: int atp_open(gref_t *, int); ! 433: int atp_bind(gref_t *, unsigned int, unsigned char *); ! 434: int atp_close(gref_t *, int); ! 435: gbuf_t *atp_build_release(struct atp_trans *); ! 436: void atp_req_timeout(struct atp_trans *); ! 437: void atp_free(struct atp_trans *); ! 438: void atp_x_done(struct atp_trans *); ! 439: void atp_send(struct atp_trans *); ! 440: void atp_rsp_ind(struct atp_trans *, gbuf_t *); ! 441: void atp_trans_free(struct atp_trans *); ! 442: void atp_reply(struct atp_rcb *); ! 443: void atp_rcb_free(struct atp_rcb *); ! 444: void atp_send_replies(struct atp_state *, struct atp_rcb *); ! 445: void atp_dequeue_atp(struct atp_state *); ! 446: int atp_iocack(struct atp_state *, gbuf_t *); ! 447: void atp_req_ind(struct atp_state *, gbuf_t *); ! 448: int atp_iocnak(struct atp_state *, gbuf_t *, int); ! 449: void atp_trp_timer(void *, int); ! 450: void atp_timout(void (*func)(), struct atp_trans *, int); ! 451: void atp_untimout(void (*func)(), struct atp_trans *); ! 452: int atp_tid(struct atp_state *); ! 453: ! 454: #endif /* KERNEL */ ! 455: #endif /* _NETAT_ATP_H_ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.