fusd.h 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  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. * FUSD: the Framework for User-Space Devices
  32. *
  33. * Public header function for user-space library. This is the API
  34. * that user-space device drivers should write to.
  35. */
  36. #ifndef __FUSD_H__
  37. #define __FUSD_H__
  38. #ifndef __KERNEL__
  39. #include <sys/types.h>
  40. __BEGIN_DECLS
  41. #endif
  42. #include "fusd_msg.h"
  43. /* FUSD_NOREPLY is a special error code. If a user-space driver
  44. * implementing a system call returns -FUSD_NOREPLY (note it's
  45. * negative!), the calling application will be blocked. When
  46. * conditions enable a response to the system call (e.g. the read or
  47. * write has completed), the user-space driver must call the
  48. * fusd_return() function. */
  49. #define FUSD_NOREPLY 0x1000
  50. /* FUSD defines several bitmasks for describing which channels of
  51. * notification are being requested or signaled. These flags are
  52. * used in the arguments and return value of the notify() callback. */
  53. #define FUSD_NOTIFY_INPUT 0x1
  54. #define FUSD_NOTIFY_OUTPUT 0x2
  55. #define FUSD_NOTIFY_EXCEPT 0x4
  56. #define FUSD_KOR_HACKED_VERSION
  57. #ifndef __KERNEL__
  58. struct fusd_file_info; /* forward decl */
  59. typedef
  60. struct fusd_file_operations {
  61. int (*open) (struct fusd_file_info *file);
  62. int (*close) (struct fusd_file_info *file);
  63. ssize_t (*read) (struct fusd_file_info *file, char *buffer, size_t length,
  64. loff_t *offset);
  65. ssize_t (*write) (struct fusd_file_info *file, const char *buffer,
  66. size_t length, loff_t *offset);
  67. int (*ioctl) (struct fusd_file_info *file, int request, void *data);
  68. int (*poll_diff) (struct fusd_file_info *file, unsigned int cached_state);
  69. int (*unblock) (struct fusd_file_info *file);
  70. int (*mmap) (struct fusd_file_info *file, int offset, size_t length, int prot, int flags, void** addr, size_t* out_length);
  71. } fusd_file_operations_t;
  72. /* state-keeping structure passed to device driver callbacks */
  73. typedef
  74. struct fusd_file_info {
  75. void *device_info; /* This is set by the library to
  76. * whatever you passed to
  77. * fusd_register. Changing this in a
  78. * file_operations callback has no
  79. * effect. */
  80. void *private_data; /* File-specific data you can change
  81. * in a file_operations callback.
  82. * e.g., you can set this in an open()
  83. * callback, then get it in a
  84. * corresponding read() callback. */
  85. unsigned int flags; /* Kept synced with file->f_flags */
  86. pid_t pid; /* PID of process making the request */
  87. uid_t uid; /* UID of process making the request */
  88. gid_t gid; /* GID of process making the request */
  89. /* other info might be added later, e.g. state needed to complete
  90. operations... */
  91. pthread_mutex_t lock;
  92. /* request message associated with this call */
  93. int fd;
  94. fusd_msg_t *fusd_msg;
  95. } fusd_file_info_t;
  96. #define FILE_LOCK(__f) pthread_mutex_lock(&__f->lock)
  97. #define FILE_UNLOCK(__f) pthread_mutex_unlock(&__f->lock)
  98. /*************************** Library Functions ****************************/
  99. /* fusd_register: create a device file and register callbacks for it
  100. *
  101. * Arguments:
  102. *
  103. * name - the name of the device file, to be created wherever devfs
  104. * is mounted (usually dev). example: pass "mydevice" will create
  105. * /dev/mydevice.
  106. *
  107. * As a convenience, passing a string that starts with "/dev/" will
  108. * automatically skip over that portion of the name.
  109. *
  110. * mode - the file protections to be given to the device
  111. *
  112. * device_info - you can provide arbitrary data that will later be
  113. * passed back to your driver's callbacks in file->device_info.
  114. * value has no effect on FUSD itself.
  115. *
  116. * fops - a table of callbacks to be called for this device; see
  117. * structure above.
  118. *
  119. * Return value:
  120. * On failure, -1 is returned and errno is set to indicate the error.
  121. *
  122. * On success, a valid file descriptor is returned which represents
  123. * the control channel to your new device. You should never read
  124. * from or write to that control channel directcly, but you can
  125. * select on it to see when it needs attention (see fusd_run and
  126. * fusd_dispatch).
  127. */
  128. int fusd_register(const char *name, const char* clazz, const char* devname, mode_t mode, void *device_info,
  129. struct fusd_file_operations *fops);
  130. /* "simple" interface to fusd_register. */
  131. #define fusd_simple_register(name, clazz, devname, perms, arg, ops...) do { \
  132. struct fusd_file_operations f = { ops } ; \
  133. if (fusd_register(name, clazz, devname, perms, arg, &f) < 0) \
  134. perror("warning: fusd unavailable"); \
  135. } while(0)
  136. /* fusd_unregister: unregister a previously registered device
  137. *
  138. * Arguments:
  139. * fd - the file descriptor previously returned to you by fusd_register.
  140. *
  141. * Return value:
  142. * 0 on success.
  143. * -1 on failure with errno set to indicate the failure.
  144. */
  145. int fusd_unregister(int fd);
  146. /* fusd_return: unblock a previously blocked system call
  147. *
  148. * Arguments:
  149. * file - the file info struct that was previously blocked
  150. * retval - the return value that would have been returned by the
  151. * returning system call
  152. *
  153. * Return value:
  154. * 0 on success.
  155. * -1 on failure with errno set to indicate the failure
  156. */
  157. int fusd_return(struct fusd_file_info *file, ssize_t retval);
  158. /*
  159. * fusd_destroy destroys all state associated with a fusd_file_info
  160. * pointer. (It is implicitly called by fusd_return.) If a driver
  161. * saves a fusd_file_info pointer by calling -FUSD_NOREPLY in order to
  162. * block a read, but gets a "close" request on the file before the
  163. * pointer is returned with fusd_return, it should be thrown away
  164. * using fusd_destroy.
  165. */
  166. void fusd_destroy(struct fusd_file_info *file);
  167. /* fusd_dispatch: handles an event on a fusd file descriptor
  168. *
  169. * Arguments:
  170. * fd - the file descriptor of the device that received an event
  171. *
  172. * Return value:
  173. * None.
  174. *
  175. * Side effects:
  176. * May (but may not) call a callback function originally passed to
  177. * fusd_register.
  178. *
  179. * Prints an error to stderr in case of a dispatching error.
  180. */
  181. void fusd_dispatch(int fd);
  182. /*
  183. * fusd_run: convenience function that handles dispatch for all
  184. * fusd devices
  185. *
  186. * No return value; runs forever.
  187. */
  188. void fusd_run(void);
  189. /*
  190. * fusd_fdset_add: given an FDSET and "max", add the currently valid
  191. * FUSD fds to the set and update max accordingly.
  192. */
  193. void fusd_fdset_add(fd_set *set, int *max);
  194. /*
  195. * fusd_dispatch_fdset: given an fd_set full of descriptors, call
  196. * fusd_dispatch on every descriptor in the set which is a valid FUSD
  197. * fd.
  198. */
  199. void fusd_dispatch_fdset(fd_set *set);
  200. /********************************************************************
  201. *
  202. * Direct access API
  203. *
  204. * This API enables a driver implementation to store state about a
  205. * blocked call more easily, extracting the call arguments directly
  206. * with no need to store them separately.
  207. *
  208. ********************************************************************/
  209. /* accessors */
  210. static inline int fusd_get_call_type(struct fusd_file_info *file)
  211. { return file->fusd_msg->subcmd; }
  212. static inline char * fusd_get_read_buffer(struct fusd_file_info *file)
  213. { return file->fusd_msg->data; }
  214. static inline const char * fusd_get_write_buffer(struct fusd_file_info *file)
  215. { return (const char *)file->fusd_msg->data; }
  216. static inline size_t fusd_get_length(struct fusd_file_info *file)
  217. { return (size_t)file->fusd_msg->datalen; }
  218. static inline loff_t *fusd_get_offset(struct fusd_file_info *file)
  219. { return &(file->fusd_msg->parm.fops_msg.offset); }
  220. static inline int fusd_get_ioctl_request(struct fusd_file_info *file)
  221. { return file->fusd_msg->parm.fops_msg.cmd; }
  222. static inline unsigned long fusd_get_ioctl_arg(struct fusd_file_info *file)
  223. { return file->fusd_msg->parm.fops_msg.arg.arg; }
  224. static inline void * fusd_get_ioctl_buffer(struct fusd_file_info *file)
  225. { return (void *)file->fusd_msg->data; }
  226. static inline int fusd_get_poll_diff_cached_state(struct fusd_file_info *file)
  227. { return file->fusd_msg->parm.fops_msg.cmd; }
  228. /* returns static string representing the flagset (e.g. RWE) */
  229. char *fusd_unparse_flags(int flags);
  230. #endif /* !__KERNEL__ */
  231. #ifndef __KERNEL__
  232. __END_DECLS
  233. #endif
  234. #endif /* __FUSD_H__ */