diff options
Diffstat (limited to 'include/xen/interface/io')
-rw-r--r-- | include/xen/interface/io/blkif.h | 94 | ||||
-rw-r--r-- | include/xen/interface/io/console.h | 23 | ||||
-rw-r--r-- | include/xen/interface/io/netif.h | 158 | ||||
-rw-r--r-- | include/xen/interface/io/ring.h | 260 | ||||
-rw-r--r-- | include/xen/interface/io/xenbus.h | 44 | ||||
-rw-r--r-- | include/xen/interface/io/xs_wire.h | 87 |
6 files changed, 666 insertions, 0 deletions
diff --git a/include/xen/interface/io/blkif.h b/include/xen/interface/io/blkif.h new file mode 100644 index 000000000000..c2d1fa4dc1ee --- /dev/null +++ b/include/xen/interface/io/blkif.h | |||
@@ -0,0 +1,94 @@ | |||
1 | /****************************************************************************** | ||
2 | * blkif.h | ||
3 | * | ||
4 | * Unified block-device I/O interface for Xen guest OSes. | ||
5 | * | ||
6 | * Copyright (c) 2003-2004, Keir Fraser | ||
7 | */ | ||
8 | |||
9 | #ifndef __XEN_PUBLIC_IO_BLKIF_H__ | ||
10 | #define __XEN_PUBLIC_IO_BLKIF_H__ | ||
11 | |||
12 | #include "ring.h" | ||
13 | #include "../grant_table.h" | ||
14 | |||
15 | /* | ||
16 | * Front->back notifications: When enqueuing a new request, sending a | ||
17 | * notification can be made conditional on req_event (i.e., the generic | ||
18 | * hold-off mechanism provided by the ring macros). Backends must set | ||
19 | * req_event appropriately (e.g., using RING_FINAL_CHECK_FOR_REQUESTS()). | ||
20 | * | ||
21 | * Back->front notifications: When enqueuing a new response, sending a | ||
22 | * notification can be made conditional on rsp_event (i.e., the generic | ||
23 | * hold-off mechanism provided by the ring macros). Frontends must set | ||
24 | * rsp_event appropriately (e.g., using RING_FINAL_CHECK_FOR_RESPONSES()). | ||
25 | */ | ||
26 | |||
27 | typedef uint16_t blkif_vdev_t; | ||
28 | typedef uint64_t blkif_sector_t; | ||
29 | |||
30 | /* | ||
31 | * REQUEST CODES. | ||
32 | */ | ||
33 | #define BLKIF_OP_READ 0 | ||
34 | #define BLKIF_OP_WRITE 1 | ||
35 | /* | ||
36 | * Recognised only if "feature-barrier" is present in backend xenbus info. | ||
37 | * The "feature_barrier" node contains a boolean indicating whether barrier | ||
38 | * requests are likely to succeed or fail. Either way, a barrier request | ||
39 | * may fail at any time with BLKIF_RSP_EOPNOTSUPP if it is unsupported by | ||
40 | * the underlying block-device hardware. The boolean simply indicates whether | ||
41 | * or not it is worthwhile for the frontend to attempt barrier requests. | ||
42 | * If a backend does not recognise BLKIF_OP_WRITE_BARRIER, it should *not* | ||
43 | * create the "feature-barrier" node! | ||
44 | */ | ||
45 | #define BLKIF_OP_WRITE_BARRIER 2 | ||
46 | |||
47 | /* | ||
48 | * Maximum scatter/gather segments per request. | ||
49 | * This is carefully chosen so that sizeof(struct blkif_ring) <= PAGE_SIZE. | ||
50 | * NB. This could be 12 if the ring indexes weren't stored in the same page. | ||
51 | */ | ||
52 | #define BLKIF_MAX_SEGMENTS_PER_REQUEST 11 | ||
53 | |||
54 | struct blkif_request { | ||
55 | uint8_t operation; /* BLKIF_OP_??? */ | ||
56 | uint8_t nr_segments; /* number of segments */ | ||
57 | blkif_vdev_t handle; /* only for read/write requests */ | ||
58 | uint64_t id; /* private guest value, echoed in resp */ | ||
59 | blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */ | ||
60 | struct blkif_request_segment { | ||
61 | grant_ref_t gref; /* reference to I/O buffer frame */ | ||
62 | /* @first_sect: first sector in frame to transfer (inclusive). */ | ||
63 | /* @last_sect: last sector in frame to transfer (inclusive). */ | ||
64 | uint8_t first_sect, last_sect; | ||
65 | } seg[BLKIF_MAX_SEGMENTS_PER_REQUEST]; | ||
66 | }; | ||
67 | |||
68 | struct blkif_response { | ||
69 | uint64_t id; /* copied from request */ | ||
70 | uint8_t operation; /* copied from request */ | ||
71 | int16_t status; /* BLKIF_RSP_??? */ | ||
72 | }; | ||
73 | |||
74 | /* | ||
75 | * STATUS RETURN CODES. | ||
76 | */ | ||
77 | /* Operation not supported (only happens on barrier writes). */ | ||
78 | #define BLKIF_RSP_EOPNOTSUPP -2 | ||
79 | /* Operation failed for some unspecified reason (-EIO). */ | ||
80 | #define BLKIF_RSP_ERROR -1 | ||
81 | /* Operation completed successfully. */ | ||
82 | #define BLKIF_RSP_OKAY 0 | ||
83 | |||
84 | /* | ||
85 | * Generate blkif ring structures and types. | ||
86 | */ | ||
87 | |||
88 | DEFINE_RING_TYPES(blkif, struct blkif_request, struct blkif_response); | ||
89 | |||
90 | #define VDISK_CDROM 0x1 | ||
91 | #define VDISK_REMOVABLE 0x2 | ||
92 | #define VDISK_READONLY 0x4 | ||
93 | |||
94 | #endif /* __XEN_PUBLIC_IO_BLKIF_H__ */ | ||
diff --git a/include/xen/interface/io/console.h b/include/xen/interface/io/console.h new file mode 100644 index 000000000000..e563de70f784 --- /dev/null +++ b/include/xen/interface/io/console.h | |||
@@ -0,0 +1,23 @@ | |||
1 | /****************************************************************************** | ||
2 | * console.h | ||
3 | * | ||
4 | * Console I/O interface for Xen guest OSes. | ||
5 | * | ||
6 | * Copyright (c) 2005, Keir Fraser | ||
7 | */ | ||
8 | |||
9 | #ifndef __XEN_PUBLIC_IO_CONSOLE_H__ | ||
10 | #define __XEN_PUBLIC_IO_CONSOLE_H__ | ||
11 | |||
12 | typedef uint32_t XENCONS_RING_IDX; | ||
13 | |||
14 | #define MASK_XENCONS_IDX(idx, ring) ((idx) & (sizeof(ring)-1)) | ||
15 | |||
16 | struct xencons_interface { | ||
17 | char in[1024]; | ||
18 | char out[2048]; | ||
19 | XENCONS_RING_IDX in_cons, in_prod; | ||
20 | XENCONS_RING_IDX out_cons, out_prod; | ||
21 | }; | ||
22 | |||
23 | #endif /* __XEN_PUBLIC_IO_CONSOLE_H__ */ | ||
diff --git a/include/xen/interface/io/netif.h b/include/xen/interface/io/netif.h new file mode 100644 index 000000000000..518481c95f18 --- /dev/null +++ b/include/xen/interface/io/netif.h | |||
@@ -0,0 +1,158 @@ | |||
1 | /****************************************************************************** | ||
2 | * netif.h | ||
3 | * | ||
4 | * Unified network-device I/O interface for Xen guest OSes. | ||
5 | * | ||
6 | * Copyright (c) 2003-2004, Keir Fraser | ||
7 | */ | ||
8 | |||
9 | #ifndef __XEN_PUBLIC_IO_NETIF_H__ | ||
10 | #define __XEN_PUBLIC_IO_NETIF_H__ | ||
11 | |||
12 | #include "ring.h" | ||
13 | #include "../grant_table.h" | ||
14 | |||
15 | /* | ||
16 | * Notifications after enqueuing any type of message should be conditional on | ||
17 | * the appropriate req_event or rsp_event field in the shared ring. | ||
18 | * If the client sends notification for rx requests then it should specify | ||
19 | * feature 'feature-rx-notify' via xenbus. Otherwise the backend will assume | ||
20 | * that it cannot safely queue packets (as it may not be kicked to send them). | ||
21 | */ | ||
22 | |||
23 | /* | ||
24 | * This is the 'wire' format for packets: | ||
25 | * Request 1: netif_tx_request -- NETTXF_* (any flags) | ||
26 | * [Request 2: netif_tx_extra] (only if request 1 has NETTXF_extra_info) | ||
27 | * [Request 3: netif_tx_extra] (only if request 2 has XEN_NETIF_EXTRA_MORE) | ||
28 | * Request 4: netif_tx_request -- NETTXF_more_data | ||
29 | * Request 5: netif_tx_request -- NETTXF_more_data | ||
30 | * ... | ||
31 | * Request N: netif_tx_request -- 0 | ||
32 | */ | ||
33 | |||
34 | /* Protocol checksum field is blank in the packet (hardware offload)? */ | ||
35 | #define _NETTXF_csum_blank (0) | ||
36 | #define NETTXF_csum_blank (1U<<_NETTXF_csum_blank) | ||
37 | |||
38 | /* Packet data has been validated against protocol checksum. */ | ||
39 | #define _NETTXF_data_validated (1) | ||
40 | #define NETTXF_data_validated (1U<<_NETTXF_data_validated) | ||
41 | |||
42 | /* Packet continues in the next request descriptor. */ | ||
43 | #define _NETTXF_more_data (2) | ||
44 | #define NETTXF_more_data (1U<<_NETTXF_more_data) | ||
45 | |||
46 | /* Packet to be followed by extra descriptor(s). */ | ||
47 | #define _NETTXF_extra_info (3) | ||
48 | #define NETTXF_extra_info (1U<<_NETTXF_extra_info) | ||
49 | |||
50 | struct xen_netif_tx_request { | ||
51 | grant_ref_t gref; /* Reference to buffer page */ | ||
52 | uint16_t offset; /* Offset within buffer page */ | ||
53 | uint16_t flags; /* NETTXF_* */ | ||
54 | uint16_t id; /* Echoed in response message. */ | ||
55 | uint16_t size; /* Packet size in bytes. */ | ||
56 | }; | ||
57 | |||
58 | /* Types of netif_extra_info descriptors. */ | ||
59 | #define XEN_NETIF_EXTRA_TYPE_NONE (0) /* Never used - invalid */ | ||
60 | #define XEN_NETIF_EXTRA_TYPE_GSO (1) /* u.gso */ | ||
61 | #define XEN_NETIF_EXTRA_TYPE_MAX (2) | ||
62 | |||
63 | /* netif_extra_info flags. */ | ||
64 | #define _XEN_NETIF_EXTRA_FLAG_MORE (0) | ||
65 | #define XEN_NETIF_EXTRA_FLAG_MORE (1U<<_XEN_NETIF_EXTRA_FLAG_MORE) | ||
66 | |||
67 | /* GSO types - only TCPv4 currently supported. */ | ||
68 | #define XEN_NETIF_GSO_TYPE_TCPV4 (1) | ||
69 | |||
70 | /* | ||
71 | * This structure needs to fit within both netif_tx_request and | ||
72 | * netif_rx_response for compatibility. | ||
73 | */ | ||
74 | struct xen_netif_extra_info { | ||
75 | uint8_t type; /* XEN_NETIF_EXTRA_TYPE_* */ | ||
76 | uint8_t flags; /* XEN_NETIF_EXTRA_FLAG_* */ | ||
77 | |||
78 | union { | ||
79 | struct { | ||
80 | /* | ||
81 | * Maximum payload size of each segment. For | ||
82 | * example, for TCP this is just the path MSS. | ||
83 | */ | ||
84 | uint16_t size; | ||
85 | |||
86 | /* | ||
87 | * GSO type. This determines the protocol of | ||
88 | * the packet and any extra features required | ||
89 | * to segment the packet properly. | ||
90 | */ | ||
91 | uint8_t type; /* XEN_NETIF_GSO_TYPE_* */ | ||
92 | |||
93 | /* Future expansion. */ | ||
94 | uint8_t pad; | ||
95 | |||
96 | /* | ||
97 | * GSO features. This specifies any extra GSO | ||
98 | * features required to process this packet, | ||
99 | * such as ECN support for TCPv4. | ||
100 | */ | ||
101 | uint16_t features; /* XEN_NETIF_GSO_FEAT_* */ | ||
102 | } gso; | ||
103 | |||
104 | uint16_t pad[3]; | ||
105 | } u; | ||
106 | }; | ||
107 | |||
108 | struct xen_netif_tx_response { | ||
109 | uint16_t id; | ||
110 | int16_t status; /* NETIF_RSP_* */ | ||
111 | }; | ||
112 | |||
113 | struct xen_netif_rx_request { | ||
114 | uint16_t id; /* Echoed in response message. */ | ||
115 | grant_ref_t gref; /* Reference to incoming granted frame */ | ||
116 | }; | ||
117 | |||
118 | /* Packet data has been validated against protocol checksum. */ | ||
119 | #define _NETRXF_data_validated (0) | ||
120 | #define NETRXF_data_validated (1U<<_NETRXF_data_validated) | ||
121 | |||
122 | /* Protocol checksum field is blank in the packet (hardware offload)? */ | ||
123 | #define _NETRXF_csum_blank (1) | ||
124 | #define NETRXF_csum_blank (1U<<_NETRXF_csum_blank) | ||
125 | |||
126 | /* Packet continues in the next request descriptor. */ | ||
127 | #define _NETRXF_more_data (2) | ||
128 | #define NETRXF_more_data (1U<<_NETRXF_more_data) | ||
129 | |||
130 | /* Packet to be followed by extra descriptor(s). */ | ||
131 | #define _NETRXF_extra_info (3) | ||
132 | #define NETRXF_extra_info (1U<<_NETRXF_extra_info) | ||
133 | |||
134 | struct xen_netif_rx_response { | ||
135 | uint16_t id; | ||
136 | uint16_t offset; /* Offset in page of start of received packet */ | ||
137 | uint16_t flags; /* NETRXF_* */ | ||
138 | int16_t status; /* -ve: BLKIF_RSP_* ; +ve: Rx'ed pkt size. */ | ||
139 | }; | ||
140 | |||
141 | /* | ||
142 | * Generate netif ring structures and types. | ||
143 | */ | ||
144 | |||
145 | DEFINE_RING_TYPES(xen_netif_tx, | ||
146 | struct xen_netif_tx_request, | ||
147 | struct xen_netif_tx_response); | ||
148 | DEFINE_RING_TYPES(xen_netif_rx, | ||
149 | struct xen_netif_rx_request, | ||
150 | struct xen_netif_rx_response); | ||
151 | |||
152 | #define NETIF_RSP_DROPPED -2 | ||
153 | #define NETIF_RSP_ERROR -1 | ||
154 | #define NETIF_RSP_OKAY 0 | ||
155 | /* No response: used for auxiliary requests (e.g., netif_tx_extra). */ | ||
156 | #define NETIF_RSP_NULL 1 | ||
157 | |||
158 | #endif | ||
diff --git a/include/xen/interface/io/ring.h b/include/xen/interface/io/ring.h new file mode 100644 index 000000000000..e8cbf431c8cc --- /dev/null +++ b/include/xen/interface/io/ring.h | |||
@@ -0,0 +1,260 @@ | |||
1 | /****************************************************************************** | ||
2 | * ring.h | ||
3 | * | ||
4 | * Shared producer-consumer ring macros. | ||
5 | * | ||
6 | * Tim Deegan and Andrew Warfield November 2004. | ||
7 | */ | ||
8 | |||
9 | #ifndef __XEN_PUBLIC_IO_RING_H__ | ||
10 | #define __XEN_PUBLIC_IO_RING_H__ | ||
11 | |||
12 | typedef unsigned int RING_IDX; | ||
13 | |||
14 | /* Round a 32-bit unsigned constant down to the nearest power of two. */ | ||
15 | #define __RD2(_x) (((_x) & 0x00000002) ? 0x2 : ((_x) & 0x1)) | ||
16 | #define __RD4(_x) (((_x) & 0x0000000c) ? __RD2((_x)>>2)<<2 : __RD2(_x)) | ||
17 | #define __RD8(_x) (((_x) & 0x000000f0) ? __RD4((_x)>>4)<<4 : __RD4(_x)) | ||
18 | #define __RD16(_x) (((_x) & 0x0000ff00) ? __RD8((_x)>>8)<<8 : __RD8(_x)) | ||
19 | #define __RD32(_x) (((_x) & 0xffff0000) ? __RD16((_x)>>16)<<16 : __RD16(_x)) | ||
20 | |||
21 | /* | ||
22 | * Calculate size of a shared ring, given the total available space for the | ||
23 | * ring and indexes (_sz), and the name tag of the request/response structure. | ||
24 | * A ring contains as many entries as will fit, rounded down to the nearest | ||
25 | * power of two (so we can mask with (size-1) to loop around). | ||
26 | */ | ||
27 | #define __RING_SIZE(_s, _sz) \ | ||
28 | (__RD32(((_sz) - (long)&(_s)->ring + (long)(_s)) / sizeof((_s)->ring[0]))) | ||
29 | |||
30 | /* | ||
31 | * Macros to make the correct C datatypes for a new kind of ring. | ||
32 | * | ||
33 | * To make a new ring datatype, you need to have two message structures, | ||
34 | * let's say struct request, and struct response already defined. | ||
35 | * | ||
36 | * In a header where you want the ring datatype declared, you then do: | ||
37 | * | ||
38 | * DEFINE_RING_TYPES(mytag, struct request, struct response); | ||
39 | * | ||
40 | * These expand out to give you a set of types, as you can see below. | ||
41 | * The most important of these are: | ||
42 | * | ||
43 | * struct mytag_sring - The shared ring. | ||
44 | * struct mytag_front_ring - The 'front' half of the ring. | ||
45 | * struct mytag_back_ring - The 'back' half of the ring. | ||
46 | * | ||
47 | * To initialize a ring in your code you need to know the location and size | ||
48 | * of the shared memory area (PAGE_SIZE, for instance). To initialise | ||
49 | * the front half: | ||
50 | * | ||
51 | * struct mytag_front_ring front_ring; | ||
52 | * SHARED_RING_INIT((struct mytag_sring *)shared_page); | ||
53 | * FRONT_RING_INIT(&front_ring, (struct mytag_sring *)shared_page, | ||
54 | * PAGE_SIZE); | ||
55 | * | ||
56 | * Initializing the back follows similarly (note that only the front | ||
57 | * initializes the shared ring): | ||
58 | * | ||
59 | * struct mytag_back_ring back_ring; | ||
60 | * BACK_RING_INIT(&back_ring, (struct mytag_sring *)shared_page, | ||
61 | * PAGE_SIZE); | ||
62 | */ | ||
63 | |||
64 | #define DEFINE_RING_TYPES(__name, __req_t, __rsp_t) \ | ||
65 | \ | ||
66 | /* Shared ring entry */ \ | ||
67 | union __name##_sring_entry { \ | ||
68 | __req_t req; \ | ||
69 | __rsp_t rsp; \ | ||
70 | }; \ | ||
71 | \ | ||
72 | /* Shared ring page */ \ | ||
73 | struct __name##_sring { \ | ||
74 | RING_IDX req_prod, req_event; \ | ||
75 | RING_IDX rsp_prod, rsp_event; \ | ||
76 | uint8_t pad[48]; \ | ||
77 | union __name##_sring_entry ring[1]; /* variable-length */ \ | ||
78 | }; \ | ||
79 | \ | ||
80 | /* "Front" end's private variables */ \ | ||
81 | struct __name##_front_ring { \ | ||
82 | RING_IDX req_prod_pvt; \ | ||
83 | RING_IDX rsp_cons; \ | ||
84 | unsigned int nr_ents; \ | ||
85 | struct __name##_sring *sring; \ | ||
86 | }; \ | ||
87 | \ | ||
88 | /* "Back" end's private variables */ \ | ||
89 | struct __name##_back_ring { \ | ||
90 | RING_IDX rsp_prod_pvt; \ | ||
91 | RING_IDX req_cons; \ | ||
92 | unsigned int nr_ents; \ | ||
93 | struct __name##_sring *sring; \ | ||
94 | }; | ||
95 | |||
96 | /* | ||
97 | * Macros for manipulating rings. | ||
98 | * | ||
99 | * FRONT_RING_whatever works on the "front end" of a ring: here | ||
100 | * requests are pushed on to the ring and responses taken off it. | ||
101 | * | ||
102 | * BACK_RING_whatever works on the "back end" of a ring: here | ||
103 | * requests are taken off the ring and responses put on. | ||
104 | * | ||
105 | * N.B. these macros do NO INTERLOCKS OR FLOW CONTROL. | ||
106 | * This is OK in 1-for-1 request-response situations where the | ||
107 | * requestor (front end) never has more than RING_SIZE()-1 | ||
108 | * outstanding requests. | ||
109 | */ | ||
110 | |||
111 | /* Initialising empty rings */ | ||
112 | #define SHARED_RING_INIT(_s) do { \ | ||
113 | (_s)->req_prod = (_s)->rsp_prod = 0; \ | ||
114 | (_s)->req_event = (_s)->rsp_event = 1; \ | ||
115 | memset((_s)->pad, 0, sizeof((_s)->pad)); \ | ||
116 | } while(0) | ||
117 | |||
118 | #define FRONT_RING_INIT(_r, _s, __size) do { \ | ||
119 | (_r)->req_prod_pvt = 0; \ | ||
120 | (_r)->rsp_cons = 0; \ | ||
121 | (_r)->nr_ents = __RING_SIZE(_s, __size); \ | ||
122 | (_r)->sring = (_s); \ | ||
123 | } while (0) | ||
124 | |||
125 | #define BACK_RING_INIT(_r, _s, __size) do { \ | ||
126 | (_r)->rsp_prod_pvt = 0; \ | ||
127 | (_r)->req_cons = 0; \ | ||
128 | (_r)->nr_ents = __RING_SIZE(_s, __size); \ | ||
129 | (_r)->sring = (_s); \ | ||
130 | } while (0) | ||
131 | |||
132 | /* Initialize to existing shared indexes -- for recovery */ | ||
133 | #define FRONT_RING_ATTACH(_r, _s, __size) do { \ | ||
134 | (_r)->sring = (_s); \ | ||
135 | (_r)->req_prod_pvt = (_s)->req_prod; \ | ||
136 | (_r)->rsp_cons = (_s)->rsp_prod; \ | ||
137 | (_r)->nr_ents = __RING_SIZE(_s, __size); \ | ||
138 | } while (0) | ||
139 | |||
140 | #define BACK_RING_ATTACH(_r, _s, __size) do { \ | ||
141 | (_r)->sring = (_s); \ | ||
142 | (_r)->rsp_prod_pvt = (_s)->rsp_prod; \ | ||
143 | (_r)->req_cons = (_s)->req_prod; \ | ||
144 | (_r)->nr_ents = __RING_SIZE(_s, __size); \ | ||
145 | } while (0) | ||
146 | |||
147 | /* How big is this ring? */ | ||
148 | #define RING_SIZE(_r) \ | ||
149 | ((_r)->nr_ents) | ||
150 | |||
151 | /* Number of free requests (for use on front side only). */ | ||
152 | #define RING_FREE_REQUESTS(_r) \ | ||
153 | (RING_SIZE(_r) - ((_r)->req_prod_pvt - (_r)->rsp_cons)) | ||
154 | |||
155 | /* Test if there is an empty slot available on the front ring. | ||
156 | * (This is only meaningful from the front. ) | ||
157 | */ | ||
158 | #define RING_FULL(_r) \ | ||
159 | (RING_FREE_REQUESTS(_r) == 0) | ||
160 | |||
161 | /* Test if there are outstanding messages to be processed on a ring. */ | ||
162 | #define RING_HAS_UNCONSUMED_RESPONSES(_r) \ | ||
163 | ((_r)->sring->rsp_prod - (_r)->rsp_cons) | ||
164 | |||
165 | #define RING_HAS_UNCONSUMED_REQUESTS(_r) \ | ||
166 | ({ \ | ||
167 | unsigned int req = (_r)->sring->req_prod - (_r)->req_cons; \ | ||
168 | unsigned int rsp = RING_SIZE(_r) - \ | ||
169 | ((_r)->req_cons - (_r)->rsp_prod_pvt); \ | ||
170 | req < rsp ? req : rsp; \ | ||
171 | }) | ||
172 | |||
173 | /* Direct access to individual ring elements, by index. */ | ||
174 | #define RING_GET_REQUEST(_r, _idx) \ | ||
175 | (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].req)) | ||
176 | |||
177 | #define RING_GET_RESPONSE(_r, _idx) \ | ||
178 | (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].rsp)) | ||
179 | |||
180 | /* Loop termination condition: Would the specified index overflow the ring? */ | ||
181 | #define RING_REQUEST_CONS_OVERFLOW(_r, _cons) \ | ||
182 | (((_cons) - (_r)->rsp_prod_pvt) >= RING_SIZE(_r)) | ||
183 | |||
184 | #define RING_PUSH_REQUESTS(_r) do { \ | ||
185 | wmb(); /* back sees requests /before/ updated producer index */ \ | ||
186 | (_r)->sring->req_prod = (_r)->req_prod_pvt; \ | ||
187 | } while (0) | ||
188 | |||
189 | #define RING_PUSH_RESPONSES(_r) do { \ | ||
190 | wmb(); /* front sees responses /before/ updated producer index */ \ | ||
191 | (_r)->sring->rsp_prod = (_r)->rsp_prod_pvt; \ | ||
192 | } while (0) | ||
193 | |||
194 | /* | ||
195 | * Notification hold-off (req_event and rsp_event): | ||
196 | * | ||
197 | * When queueing requests or responses on a shared ring, it may not always be | ||
198 | * necessary to notify the remote end. For example, if requests are in flight | ||
199 | * in a backend, the front may be able to queue further requests without | ||
200 | * notifying the back (if the back checks for new requests when it queues | ||
201 | * responses). | ||
202 | * | ||
203 | * When enqueuing requests or responses: | ||
204 | * | ||
205 | * Use RING_PUSH_{REQUESTS,RESPONSES}_AND_CHECK_NOTIFY(). The second argument | ||
206 | * is a boolean return value. True indicates that the receiver requires an | ||
207 | * asynchronous notification. | ||
208 | * | ||
209 | * After dequeuing requests or responses (before sleeping the connection): | ||
210 | * | ||
211 | * Use RING_FINAL_CHECK_FOR_REQUESTS() or RING_FINAL_CHECK_FOR_RESPONSES(). | ||
212 | * The second argument is a boolean return value. True indicates that there | ||
213 | * are pending messages on the ring (i.e., the connection should not be put | ||
214 | * to sleep). | ||
215 | * | ||
216 | * These macros will set the req_event/rsp_event field to trigger a | ||
217 | * notification on the very next message that is enqueued. If you want to | ||
218 | * create batches of work (i.e., only receive a notification after several | ||
219 | * messages have been enqueued) then you will need to create a customised | ||
220 | * version of the FINAL_CHECK macro in your own code, which sets the event | ||
221 | * field appropriately. | ||
222 | */ | ||
223 | |||
224 | #define RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(_r, _notify) do { \ | ||
225 | RING_IDX __old = (_r)->sring->req_prod; \ | ||
226 | RING_IDX __new = (_r)->req_prod_pvt; \ | ||
227 | wmb(); /* back sees requests /before/ updated producer index */ \ | ||
228 | (_r)->sring->req_prod = __new; \ | ||
229 | mb(); /* back sees new requests /before/ we check req_event */ \ | ||
230 | (_notify) = ((RING_IDX)(__new - (_r)->sring->req_event) < \ | ||
231 | (RING_IDX)(__new - __old)); \ | ||
232 | } while (0) | ||
233 | |||
234 | #define RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(_r, _notify) do { \ | ||
235 | RING_IDX __old = (_r)->sring->rsp_prod; \ | ||
236 | RING_IDX __new = (_r)->rsp_prod_pvt; \ | ||
237 | wmb(); /* front sees responses /before/ updated producer index */ \ | ||
238 | (_r)->sring->rsp_prod = __new; \ | ||
239 | mb(); /* front sees new responses /before/ we check rsp_event */ \ | ||
240 | (_notify) = ((RING_IDX)(__new - (_r)->sring->rsp_event) < \ | ||
241 | (RING_IDX)(__new - __old)); \ | ||
242 | } while (0) | ||
243 | |||
244 | #define RING_FINAL_CHECK_FOR_REQUESTS(_r, _work_to_do) do { \ | ||
245 | (_work_to_do) = RING_HAS_UNCONSUMED_REQUESTS(_r); \ | ||
246 | if (_work_to_do) break; \ | ||
247 | (_r)->sring->req_event = (_r)->req_cons + 1; \ | ||
248 | mb(); \ | ||
249 | (_work_to_do) = RING_HAS_UNCONSUMED_REQUESTS(_r); \ | ||
250 | } while (0) | ||
251 | |||
252 | #define RING_FINAL_CHECK_FOR_RESPONSES(_r, _work_to_do) do { \ | ||
253 | (_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r); \ | ||
254 | if (_work_to_do) break; \ | ||
255 | (_r)->sring->rsp_event = (_r)->rsp_cons + 1; \ | ||
256 | mb(); \ | ||
257 | (_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r); \ | ||
258 | } while (0) | ||
259 | |||
260 | #endif /* __XEN_PUBLIC_IO_RING_H__ */ | ||
diff --git a/include/xen/interface/io/xenbus.h b/include/xen/interface/io/xenbus.h new file mode 100644 index 000000000000..46508c7fa399 --- /dev/null +++ b/include/xen/interface/io/xenbus.h | |||
@@ -0,0 +1,44 @@ | |||
1 | /***************************************************************************** | ||
2 | * xenbus.h | ||
3 | * | ||
4 | * Xenbus protocol details. | ||
5 | * | ||
6 | * Copyright (C) 2005 XenSource Ltd. | ||
7 | */ | ||
8 | |||
9 | #ifndef _XEN_PUBLIC_IO_XENBUS_H | ||
10 | #define _XEN_PUBLIC_IO_XENBUS_H | ||
11 | |||
12 | /* The state of either end of the Xenbus, i.e. the current communication | ||
13 | status of initialisation across the bus. States here imply nothing about | ||
14 | the state of the connection between the driver and the kernel's device | ||
15 | layers. */ | ||
16 | enum xenbus_state | ||
17 | { | ||
18 | XenbusStateUnknown = 0, | ||
19 | XenbusStateInitialising = 1, | ||
20 | XenbusStateInitWait = 2, /* Finished early | ||
21 | initialisation, but waiting | ||
22 | for information from the peer | ||
23 | or hotplug scripts. */ | ||
24 | XenbusStateInitialised = 3, /* Initialised and waiting for a | ||
25 | connection from the peer. */ | ||
26 | XenbusStateConnected = 4, | ||
27 | XenbusStateClosing = 5, /* The device is being closed | ||
28 | due to an error or an unplug | ||
29 | event. */ | ||
30 | XenbusStateClosed = 6 | ||
31 | |||
32 | }; | ||
33 | |||
34 | #endif /* _XEN_PUBLIC_IO_XENBUS_H */ | ||
35 | |||
36 | /* | ||
37 | * Local variables: | ||
38 | * c-file-style: "linux" | ||
39 | * indent-tabs-mode: t | ||
40 | * c-indent-level: 8 | ||
41 | * c-basic-offset: 8 | ||
42 | * tab-width: 8 | ||
43 | * End: | ||
44 | */ | ||
diff --git a/include/xen/interface/io/xs_wire.h b/include/xen/interface/io/xs_wire.h new file mode 100644 index 000000000000..99fcffb372d1 --- /dev/null +++ b/include/xen/interface/io/xs_wire.h | |||
@@ -0,0 +1,87 @@ | |||
1 | /* | ||
2 | * Details of the "wire" protocol between Xen Store Daemon and client | ||
3 | * library or guest kernel. | ||
4 | * Copyright (C) 2005 Rusty Russell IBM Corporation | ||
5 | */ | ||
6 | |||
7 | #ifndef _XS_WIRE_H | ||
8 | #define _XS_WIRE_H | ||
9 | |||
10 | enum xsd_sockmsg_type | ||
11 | { | ||
12 | XS_DEBUG, | ||
13 | XS_DIRECTORY, | ||
14 | XS_READ, | ||
15 | XS_GET_PERMS, | ||
16 | XS_WATCH, | ||
17 | XS_UNWATCH, | ||
18 | XS_TRANSACTION_START, | ||
19 | XS_TRANSACTION_END, | ||
20 | XS_INTRODUCE, | ||
21 | XS_RELEASE, | ||
22 | XS_GET_DOMAIN_PATH, | ||
23 | XS_WRITE, | ||
24 | XS_MKDIR, | ||
25 | XS_RM, | ||
26 | XS_SET_PERMS, | ||
27 | XS_WATCH_EVENT, | ||
28 | XS_ERROR, | ||
29 | XS_IS_DOMAIN_INTRODUCED | ||
30 | }; | ||
31 | |||
32 | #define XS_WRITE_NONE "NONE" | ||
33 | #define XS_WRITE_CREATE "CREATE" | ||
34 | #define XS_WRITE_CREATE_EXCL "CREATE|EXCL" | ||
35 | |||
36 | /* We hand errors as strings, for portability. */ | ||
37 | struct xsd_errors | ||
38 | { | ||
39 | int errnum; | ||
40 | const char *errstring; | ||
41 | }; | ||
42 | #define XSD_ERROR(x) { x, #x } | ||
43 | static struct xsd_errors xsd_errors[] __attribute__((unused)) = { | ||
44 | XSD_ERROR(EINVAL), | ||
45 | XSD_ERROR(EACCES), | ||
46 | XSD_ERROR(EEXIST), | ||
47 | XSD_ERROR(EISDIR), | ||
48 | XSD_ERROR(ENOENT), | ||
49 | XSD_ERROR(ENOMEM), | ||
50 | XSD_ERROR(ENOSPC), | ||
51 | XSD_ERROR(EIO), | ||
52 | XSD_ERROR(ENOTEMPTY), | ||
53 | XSD_ERROR(ENOSYS), | ||
54 | XSD_ERROR(EROFS), | ||
55 | XSD_ERROR(EBUSY), | ||
56 | XSD_ERROR(EAGAIN), | ||
57 | XSD_ERROR(EISCONN) | ||
58 | }; | ||
59 | |||
60 | struct xsd_sockmsg | ||
61 | { | ||
62 | uint32_t type; /* XS_??? */ | ||
63 | uint32_t req_id;/* Request identifier, echoed in daemon's response. */ | ||
64 | uint32_t tx_id; /* Transaction id (0 if not related to a transaction). */ | ||
65 | uint32_t len; /* Length of data following this. */ | ||
66 | |||
67 | /* Generally followed by nul-terminated string(s). */ | ||
68 | }; | ||
69 | |||
70 | enum xs_watch_type | ||
71 | { | ||
72 | XS_WATCH_PATH = 0, | ||
73 | XS_WATCH_TOKEN | ||
74 | }; | ||
75 | |||
76 | /* Inter-domain shared memory communications. */ | ||
77 | #define XENSTORE_RING_SIZE 1024 | ||
78 | typedef uint32_t XENSTORE_RING_IDX; | ||
79 | #define MASK_XENSTORE_IDX(idx) ((idx) & (XENSTORE_RING_SIZE-1)) | ||
80 | struct xenstore_domain_interface { | ||
81 | char req[XENSTORE_RING_SIZE]; /* Requests to xenstore daemon. */ | ||
82 | char rsp[XENSTORE_RING_SIZE]; /* Replies and async watch events. */ | ||
83 | XENSTORE_RING_IDX req_cons, req_prod; | ||
84 | XENSTORE_RING_IDX rsp_cons, rsp_prod; | ||
85 | }; | ||
86 | |||
87 | #endif /* _XS_WIRE_H */ | ||