More syslink messaging work. Now basically done except for the I/O 'DMA'
[dragonfly.git] / sys / sys / syslink_msg2.h
1 /*
2  * Copyright (c) 2004-2007 The DragonFly Project.  All rights reserved.
3  * 
4  * This code is derived from software contributed to The DragonFly Project
5  * by Matthew Dillon <dillon@backplane.com>
6  * 
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  * 3. Neither the name of The DragonFly Project nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific, prior written permission.
20  * 
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  * $DragonFly: src/sys/sys/syslink_msg2.h,v 1.3 2007/06/17 21:31:07 dillon Exp $
35  */
36 /*
37  * Helper inlines and macros for syslink message generation
38  */
39
40 #ifndef _SYS_SYSLINK_MSG2_H_
41 #define _SYS_SYSLINK_MSG2_H_
42
43 #ifndef _SYS_SYSLINK_H_
44 #include <sys/syslink.h>
45 #endif
46 #ifndef _SYS_SYSLINK_MSG_H_
47 #include <sys/syslink_msg.h>
48 #endif
49
50 static __inline
51 struct syslink_elm *
52 sl_msg_init_cmd(struct syslink_msg *msg, sl_proto_t proto, sl_cmd_t cmd)
53 {
54         msg->sm_proto = proto;
55         msg->sm_bytes = 0;
56         /* rlabel will be filled in by the transport layer */
57         /* msgid will be filled in by the transport layer */
58         msg->sm_head.se_cmd = cmd;
59         msg->sm_head.se_bytes = sizeof(struct syslink_elm);
60         msg->sm_head.se_aux = 0;
61         return(&msg->sm_head);
62 }
63
64 static __inline
65 struct syslink_elm *
66 sl_msg_init_reply(struct syslink_msg *msg, struct syslink_msg *rep,
67                   int32_t error)
68 {
69         rep->sm_proto = msg->sm_proto | SM_PROTO_REPLY;
70         rep->sm_bytes = 0;
71         rep->sm_rlabel = msg->sm_rlabel;
72         rep->sm_msgid = msg->sm_msgid;
73         rep->sm_head.se_cmd = msg->sm_head.se_cmd | SE_CMDF_REPLY;
74         rep->sm_head.se_bytes = sizeof(struct syslink_elm);
75         rep->sm_head.se_aux = error;
76         return(&rep->sm_head);
77 }
78
79 static __inline
80 void
81 sl_msg_fini(struct syslink_msg *msg)
82 {
83         msg->sm_bytes = offsetof(struct syslink_msg, sm_head) +
84                                  SL_MSG_ALIGN(msg->sm_head.se_bytes);
85 }
86
87 static __inline
88 struct syslink_elm *
89 sl_elm_make(struct syslink_elm *par, sl_cmd_t cmd, int bytes)
90 {
91         struct syslink_elm *elm = (void *)((char *)par + par->se_bytes);
92
93         KKASSERT((cmd & SE_CMDF_STRUCTURED) == 0);
94         elm->se_cmd = cmd;
95         elm->se_bytes = sizeof(*elm) + bytes;
96         elm->se_aux = 0;
97
98         par->se_bytes += SL_MSG_ALIGN(elm->se_bytes);
99         return(elm);
100 }
101
102 /*
103  * Push a new element given the current element, creating a recursion
104  * under the current element.
105  */
106 static __inline
107 struct syslink_elm *
108 sl_elm_push(struct syslink_elm *par, sl_cmd_t cmd)
109 {
110         struct syslink_elm *elm = (void *)((char *)par + par->se_bytes);
111
112         KKASSERT(cmd & SE_CMDF_STRUCTURED);
113         elm->se_cmd = cmd;
114         elm->se_bytes = sizeof(struct syslink_elm);
115         elm->se_aux = 0;
116
117         return(elm);
118 }
119
120 /*
121  * Pop a previously pushed element.  Additional array elements may be
122  * added to the parent by continuing to push/pop using the parent.
123  */
124 static __inline
125 void
126 sl_elm_pop(struct syslink_elm *par, struct syslink_elm *elm)
127 {
128         par->se_bytes = (char *)elm - (char *)par + elm->se_bytes;
129 }
130
131 #define SL_FOREACH_ELEMENT(par, elm)                                    \
132         for (elm = par + 1; (char *)elm < (char *)par + par->se_bytes;  \
133              elm = (void *)((char *)elm + SL_MSG_ALIGN(elm->se_bytes)))
134
135 #endif
136