1 /*
2 *
3 * Copyright (c) 2003 The Regents of the University of California. All
4 * rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * - Neither the name of the University nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS''
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
21 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
25 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 */
30
31
32 /*
33 * FUSD: the Framework for User-Space Devices
34 *
35 * Public header function for user-space library. This is the API
36 * that user-space device drivers should write to.
37 */
38
39 #ifndef __FUSD_H__
40 #define __FUSD_H__
41
42 #ifndef __KERNEL__
43 #include <sys/types.h>
44 #include <sys/cdefs.h>
45 #include "cygwin_compat.h"
46 __BEGIN_DECLS
47 #endif
48
49 #include "fusd_msg.h"
50
51 /* FUSD_NOREPLY is a special error code. If a user-space driver
52 * implementing a system call returns -FUSD_NOREPLY (note it's
53 * negative!), the calling application will be blocked. When
54 * conditions enable a response to the system call (e.g. the read or
55 * write has completed), the user-space driver must call the
56 * fusd_return() function. */
57 #define FUSD_NOREPLY 0x1000
58
59 /* FUSD defines several bitmasks for describing which channels of
60 * notification are being requested or signaled. These flags are
61 * used in the arguments and return value of the notify() callback. */
62 #define FUSD_NOTIFY_INPUT 0x1
63 #define FUSD_NOTIFY_OUTPUT 0x2
64 #define FUSD_NOTIFY_EXCEPT 0x4
65
66
67 struct fusd_file_info; /* forward decl */
68
69 typedef
70 struct fusd_file_operations {
71 int (*open) (struct fusd_file_info *file);
72 int (*close) (struct fusd_file_info *file);
73 ssize_t (*read) (struct fusd_file_info *file, char *buffer, size_t length,
74 loff_t *offset);
75 ssize_t (*write) (struct fusd_file_info *file, const char *buffer,
76 size_t length, loff_t *offset);
77 int (*ioctl) (struct fusd_file_info *file, int request, void *data);
78 int (*poll_diff) (struct fusd_file_info *file, unsigned int cached_state);
79 int (*unblock) (struct fusd_file_info *file);
80 } fusd_file_operations_t;
81
82
83 /* state-keeping structure passed to device driver callbacks */
84 typedef
85 struct fusd_file_info {
86 void *device_info; /* This is set by the library to
87 * whatever you passed to
88 * fusd_register. Changing this in a
89 * file_operations callback has no
90 * effect. */
91
92 void *private_data; /* File-specific data you can change
93 * in a file_operations callback.
94 * e.g., you can set this in an open()
95 * callback, then get it in a
96 * corresponding read() callback. */
97
98 unsigned int flags; /* Kept synced with file->f_flags */
99 pid_t pid; /* PID of process making the request */
100 uid_t uid; /* UID of process making the request */
101 gid_t gid; /* GID of process making the request */
102
103 /* other info might be added later, e.g. state needed to complete
104 operations... */
105
106 /* request message associated with this call */
107 int fd;
108 fusd_msg_t *fusd_msg;
109
110 /* fusdnet specific fields: no not disturb! */
111 void *remote_client;
112 void *local_client;
113 void **local_device_info;
114 } fusd_file_info_t;
115
116
117
118
119 /*************************** Library Functions ****************************/
120
121 /* fusd_register: create a device file and register callbacks for it
122 *
123 * Arguments:
124 *
125 * name - the name of the device file, to be created wherever devfs
126 * is mounted (usually dev). example: pass "mydevice" will create
127 * /dev/mydevice.
128 *
129 * As a convenience, passing a string that starts with "/dev/" will
130 * automatically skip over that portion of the name.
131 *
132 * mode - the file protections to be given to the device
133 *
134 * device_info - you can provide arbitrary data that will later be
135 * passed back to your driver's callbacks in file->device_info.
136 * value has no effect on FUSD itself.
137 *
138 * fops - a table of callbacks to be called for this device; see
139 * structure above.
140 *
141 * Return value:
142 * On failure, -1 is returned and errno is set to indicate the error.
143 *
144 * On success, a valid file descriptor is returned which represents
145 * the control channel to your new device. You should never read
146 * from or write to that control channel directcly, but you can
147 * select on it to see when it needs attention (see fusd_run and
148 * fusd_dispatch).
149 */
150
151 int fusd_register(const char *name, mode_t mode, void *device_info,
152 struct fusd_file_operations *fops);
153
154
155
156 /* "simple" interface to fusd_register. */
157 #define fusd_simple_register(name, perms, arg, ops...) do { \
158 struct fusd_file_operations f = { ops } ; \
159 if (fusd_register(name, perms, arg, &f) < 0) \
160 perror("warning: fusd unavailable"); \
161 } while(0)
162
163 /* fusd_unregister: unregister a previously registered device
164 *
165 * Arguments:
166 * fd - the file descriptor previously returned to you by fusd_register.
167 *
168 * Return value:
169 * 0 on success.
170 * -1 on failure with errno set to indicate the failure.
171 */
172 int fusd_unregister(int fd);
173
174
175 /* fusd_return: unblock a previously blocked system call
176 *
177 * Arguments:
178 * file - the file info struct that was previously blocked
179 * retval - the return value that would have been returned by the
180 * returning system call
181 *
182 * Return value:
183 * 0 on success.
184 * -1 on failure with errno set to indicate the failure
185 */
186 int fusd_return(struct fusd_file_info *file, ssize_t retval);
187
188
189 /*
190 * fusd_destroy destroys all state associated with a fusd_file_info
191 * pointer. (It is implicitly called by fusd_return.) If a driver
192 * saves a fusd_file_info pointer by calling -FUSD_NOREPLY in order to
193 * block a read, but gets a "close" request on the file before the
194 * pointer is returned with fusd_return, it should be thrown away
195 * using fusd_destroy.
196 */
197 void fusd_destroy(struct fusd_file_info *file);
198
199
200 /* fusd_dispatch: handles an event on a fusd file descriptor
201 *
202 * Arguments:
203 * fd - the file descriptor of the device that received an event
204 *
205 * Return value:
206 * None.
207 *
208 * Side effects:
209 * May (but may not) call a callback function originally passed to
210 * fusd_register.
211 *
212 * Prints an error to stderr in case of a dispatching error.
213 */
214 void fusd_dispatch(int fd);
215
216
217 /*
218 * fusd_run: convenience function that handles dispatch for all
219 * fusd devices
220 *
221 * No return value; runs forever.
222 */
223 void fusd_run(void);
224
225
226 /*
227 * fusd_fdset_add: given an FDSET and "max", add the currently valid
228 * FUSD fds to the set and update max accordingly.
229 */
230 void fusd_fdset_add(fd_set *set, int *max);
231
232
233 /*
234 * fusd_dispatch_fdset: given an fd_set full of descriptors, call
235 * fusd_dispatch on every descriptor in the set which is a valid FUSD
236 * fd.
237 */
238 void fusd_dispatch_fdset(fd_set *set);
239
240 /*
241 * FUSD status handling
242 */
243
244 typedef int (* fusd_status_handler_cb)(fusd_status_t *fs, int count, void *private_data);
245 typedef int (* fusd_status_notify_cb)(void *private_data);
246
247 typedef struct fusd_status_context {
248 char buf[4096];
249 int len; /* initialize to 0! */
250 int fd;
251 int verbose:1;
252 int full_mode:1; /* initialize to 0! */
253 fusd_status_handler_cb new_data_cb;
254 fusd_status_notify_cb begin_full_cb;
255 fusd_status_notify_cb end_full_cb;
256 void *private_data;
257 } fusd_status_context_t;
258
259 #define STATUS_OK 0
260 #define STATUS_DONE 1
261 #define STATUS_ERR 2
262 #define STATUS_FOUND 3
263
264 int fusd_status_process(fusd_status_context_t *ctx);
265 int fusd_status_wait(fusd_status_context_t *ctx);
266
267
268 /********************************************************************
269 *
270 * Direct access API
271 *
272 * This API enables a driver implementation to store state about a
273 * blocked call more easily, extracting the call arguments directly
274 * with no need to store them separately.
275 *
276 ********************************************************************/
277
278 /* accessors */
279 static inline int fusd_get_call_type(struct fusd_file_info *file)
280 { return file->fusd_msg->subcmd; }
281
282 static inline char * fusd_get_read_buffer(struct fusd_file_info *file)
283 { return file->fusd_msg->data; }
284
285 static inline const char * fusd_get_write_buffer(struct fusd_file_info *file)
286 { return (const char *)file->fusd_msg->data; }
287
288 static inline size_t fusd_get_length(struct fusd_file_info *file)
289 { return (size_t)file->fusd_msg->datalen; }
290
291 static inline loff_t *fusd_get_offset(struct fusd_file_info *file)
292 { return &(file->fusd_msg->parm.fops_msg.offset); }
293
294 static inline int fusd_get_ioctl_request(struct fusd_file_info *file)
295 { return file->fusd_msg->parm.fops_msg.cmd; }
296
297 static inline int fusd_get_ioctl_arg(struct fusd_file_info *file)
298 { return file->fusd_msg->parm.fops_msg.arg; }
299
300 static inline void * fusd_get_ioctl_buffer(struct fusd_file_info *file)
301 { return (void *)file->fusd_msg->data; }
302
303 static inline int fusd_get_poll_diff_cached_state(struct fusd_file_info *file)
304 { return file->fusd_msg->parm.fops_msg.cmd; }
305
306 /* returns static string representing the flagset (e.g. RWE) */
307 char *fusd_unparse_flags(int flags);
308
309
310 /*
311 * Low-level FUSD Library Helpers, used by the glib interface
312 */
313
314 int fusd_open_control(void);
315 int fusd_build_reg_msg(fusd_msg_t *message, const char *name, mode_t mode, void *device_info);
316 int fusd_postreg_block(const char *name);
317 void fusd_dispatch_aux(int fd, int from_net, fusd_file_operations_t *use_fops, void **local_device_info);
318
319 #ifndef __KERNEL__
320 __END_DECLS
321 #endif
322
323
324 /*
325 * FUSDNet
326 */
327
328 /* global flag (set in misc_init) that determines whether devices
329 * will be exposed via FUSDnet by default. Defaults to OFF.
330 * Can be overridden by bits in device_opts */
331 extern int fusdnet_export_devs;
332
333 /*
334 * Client library for connecting to remote FUSD devices via FUSDnet
335 */
336
337 typedef struct fnc_fd fusdd_client_context_t;
338
339 void fusdd_proxy_destroy(fusdd_client_context_t *ref);
340 int fusdd_parse_url(char **remote_host, char **remote_device,
341 char **local_device, const char *url);
342 int fusdd_proxy_connect(char *remote_host, char *remote_device, char *local_device,
343 fusdd_client_context_t **ref);
344 int fusdd_proxy_connect_url(char *url, fusdd_client_context_t **ref);
345 char *fusdd_proxy_get_url(fusdd_client_context_t *ref);
346
347 #endif /* __FUSD_H__ */
348
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.