Recognizes if input is ogg or not.
[xiph/unicode.git] / fusd / include / kfusd.h
blob9c01d89b71d6d4dc74014917e081fd120d13463a
1 /*
3 * Copyright (c) 2003 The Regents of the University of California. All
4 * rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
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.
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.
33 * FUSD: the Framework for User-Space Devices
35 * Jeremy Elson <jelson@circlemud.org>
36 * Copyright (c) Sensoria Corporation 2001
38 * Private header file used by the Linux Kernel Module
40 * $Id$
43 #ifndef __KFUSD_H__
44 #define __KFUSD_H__
46 #include "fusd_msg.h"
48 /* magic numbers for structure checking; unique w.r.t
49 * /usr/src/linux/Documentation/magic-number.txt */
50 #define FUSD_DEV_MAGIC 0x8b43a123
51 #define FUSD_FILE_MAGIC 0x613aa8fe
53 /* number of devices that can be created with fusd */
54 #define MAX_FUSD_DEVICES 128
56 /* number of times each device can be opened simultaneously */
57 #define MIN_FILEARRAY_SIZE 8 /* initialize allocation */
58 #define MAX_FILEARRAY_SIZE 1024 /* maximum it can grow to */
60 /* maximum read/write size we're willing to service */
61 #define MAX_RW_SIZE (1024*128)
64 /********************** Structure Definitions *******************************/
66 /* Container for a fusd msg */
67 typedef struct fusd_msgC_s_t fusd_msgC_t;
69 struct fusd_msgC_s_t {
70 fusd_msg_t fusd_msg; /* the message itself */
71 fusd_msgC_t *next; /* pointer to next one in the list */
73 /* 1-bit flags */
74 unsigned int peeked:1; /* has the first half of this been read? */
77 struct fusd_transaction
79 struct list_head list;
80 long transid;
81 int subcmd;
82 int pid;
83 int size;
84 fusd_msg_t* msg_in;
87 /* magical forward declarations to break the circular dependency */
88 struct fusd_dev_t_s;
89 typedef struct fusd_dev_t_s fusd_dev_t;
90 struct CLASS;
91 struct class_device;
93 /* state kept per opened file (i.e., an instance of a device) */
94 typedef struct {
95 /* general state management */
96 int magic; /* magic number for sanity checking */
97 fusd_dev_t *fusd_dev; /* fusd device associated with this file */
98 long fusd_dev_version; /* version number of fusd device */
99 void *private_data; /* the user's private data (we ignore it) */
100 struct file *file; /* kernel's file pointer for this file */
101 int index; /* our index in our device's file array */
102 struct semaphore file_sem; /* Semaphore for file structure */
103 int cached_poll_state; /* Latest result from a poll diff req */
104 int last_poll_sent; /* Last polldiff request we sent */
106 /* structures used for messaging */
107 wait_queue_head_t file_wait; /* Wait on this for a user->kernel msg */
108 wait_queue_head_t poll_wait; /* Given to kernel for poll() queue */
109 struct list_head transactions;
110 struct semaphore transactions_sem;
112 } fusd_file_t;
115 /* state kept per device registered under fusd */
116 struct fusd_dev_t_s {
117 int magic; /* Magic number for sanity checking */
118 long version; /* Instance number of this device */
119 int zombie; /* Is the device dead? */
120 pid_t pid; /* PID of device driver */
121 struct task_struct* task;
123 char *name; /* Name of the device under devfs (/dev) */
124 char *class_name;
125 char *dev_name;
126 struct CLASS *clazz;
127 int owns_class;
128 struct class_device *class_device;
130 void *private_data; /* User's private data */
131 struct cdev* handle;
132 dev_t dev_id;
134 fusd_file_t **files; /* Array of this device's open files */
135 int array_size; /* Size of the array pointed to by 'files' */
136 int num_files; /* Number of array entries that are valid */
137 int open_in_progress; /* File is referencing this struct,
138 but not yet part of the file array */
139 /* messaging */
140 fusd_msgC_t *msg_head; /* linked list head for message queue */
141 fusd_msgC_t *msg_tail; /* linked list tail for message queue */
143 /* synchronization */
144 wait_queue_head_t dev_wait; /* Wait queue for kernel->user msgs */
145 struct semaphore dev_sem; /* Sempahore for device structure */
147 /* pointer to allow a dev to be placed on a dev_list */
148 struct list_head devlist;
152 /**** Function Prototypes ****/
154 STATIC int maybe_free_fusd_dev(fusd_dev_t *fusd_dev);
156 STATIC int find_fusd_file(fusd_dev_t *fusd_dev, fusd_file_t *fusd_file);
157 STATIC int free_fusd_file(fusd_dev_t *fusd_dev, fusd_file_t *fusd_file);
159 STATIC int fusd_fops_call_send(fusd_file_t *fusd_file_arg,
160 fusd_msg_t *fusd_msg, struct fusd_transaction** transaction);
161 STATIC int fusd_fops_call_wait(fusd_file_t *fusd_file_arg,
162 fusd_msg_t **fusd_msg_reply, struct fusd_transaction* transaction);
163 STATIC void fusd_fops_call_done(fusd_file_t *fusd_file);
165 STATIC void fusd_forge_close(fusd_msg_t *msg, fusd_dev_t *fusd_dev);
167 STATIC int fusd_add_transaction(fusd_file_t *fusd_file, int transid, int subcmd, int size, struct fusd_transaction** out_transaction);
168 STATIC void fusd_cleanup_transaction(fusd_file_t *fusd_file, struct fusd_transaction* transaction);
169 STATIC void fusd_remove_transaction(fusd_file_t *fusd_file, struct fusd_transaction* transaction);
170 STATIC struct fusd_transaction* fusd_find_transaction(fusd_file_t *fusd_file, int transid);
171 STATIC struct fusd_transaction* fusd_find_transaction_by_pid(fusd_file_t *fusd_file, int pid);
175 /**** Utility functions & macros ****/
177 #ifdef CONFIG_FUSD_USE_WAKEUPSYNC
178 #define WAKE_UP_INTERRUPTIBLE_SYNC(x) wake_up_interruptible_sync(x)
179 #else
180 #define WAKE_UP_INTERRUPTIBLE_SYNC(x) wake_up_interruptible(x)
181 #endif /* CONFIG_FUSD_USE_WAKEUPSYNC */
183 #ifdef CONFIG_FUSD_DEBUG
184 static void rdebug_real(char *fmt, ...)
185 __attribute__ ((format (printf, 1, 2)));
187 #define RDEBUG(message_level, args...) do { \
188 if (fusd_debug_level >= message_level) rdebug_real(args); \
189 } while(0)
190 #else
191 #define RDEBUG(message_level, args...)
192 #endif /* CONFIG_FUSD_DEBUG */
195 #define ZOMBIE(fusd_dev) ((fusd_dev)->zombie)
198 #define GET_FUSD_DEV(candidate, fusd_dev) do { \
199 fusd_dev = candidate; \
200 if (fusd_dev == NULL || fusd_dev->magic != FUSD_DEV_MAGIC) \
201 goto invalid_dev; \
202 } while (0)
204 #define GET_FUSD_FILE_AND_DEV(candidate, fusd_file, fusd_dev) do { \
205 fusd_file = candidate; \
206 if (fusd_file == NULL || fusd_file->magic != FUSD_FILE_MAGIC) \
207 goto invalid_file; \
208 GET_FUSD_DEV(fusd_file->fusd_dev, fusd_dev); \
209 if (fusd_dev->version != fusd_file->fusd_dev_version) \
210 goto invalid_file; \
211 } while (0)
214 #define LOCK_FUSD_DEV(fusd_dev) \
215 do { down(&fusd_dev->dev_sem); \
216 if (ZOMBIE(fusd_dev)) { up(&fusd_dev->dev_sem); goto zombie_dev; } \
217 } while (0)
219 /* rawlock does not do a zombie check */
220 #define RAWLOCK_FUSD_DEV(fusd_dev) \
221 do { down(&fusd_dev->dev_sem); } while (0)
223 #define UNLOCK_FUSD_DEV(fusd_dev) \
224 do { up(&fusd_dev->dev_sem); } while (0)
227 #define LOCK_FUSD_FILE(fusd_file) \
228 do { down(&fusd_file->file_sem); \
229 } while (0)
231 #define UNLOCK_FUSD_FILE(fusd_file) \
232 do { up(&fusd_file->file_sem); } while (0)
234 #define FREE_FUSD_MSGC(fusd_msgc) do { \
235 if ((fusd_msgc)->fusd_msg.data != NULL) VFREE(fusd_msgc->fusd_msg.data); \
236 KFREE(fusd_msgc); \
237 } while (0)
239 #define NAME(fusd_dev) ((fusd_dev)->name == NULL ? \
240 "<noname>" : (fusd_dev)->name)
242 #ifdef CONFIG_FUSD_MEMDEBUG
243 static int fusd_mem_init(void);
244 static void fusd_mem_cleanup(void);
245 static void fusd_mem_add(void *ptr, int line, int size);
246 static void fusd_mem_del(void *ptr);
247 static void *fusd_kmalloc(size_t size, int type, int line);
248 static void fusd_kfree(void *ptr);
249 static void *fusd_vmalloc(size_t size, int line);
250 static void fusd_vfree(void *ptr);
251 # define KMALLOC(size, type) fusd_kmalloc(size, type, __LINE__)
252 # define KFREE(ptr) fusd_kfree(ptr)
253 # define VMALLOC(size) fusd_vmalloc(size, __LINE__)
254 # define VFREE(ptr) fusd_vfree(ptr)
255 #else /* no memory debugging */
256 # define KMALLOC(size, type) kmalloc(size, type)
257 # define KFREE(ptr) kfree(ptr)
258 /*# define VMALLOC(size) vmalloc(size)*/
259 # define VMALLOC(size) kmalloc(size, GFP_KERNEL)
260 # define VFREE(ptr) kfree(ptr)
261 #endif /* CONFIG_FUSD_MEMDEBUG */
265 /* Functions like this should be in the kernel, but they are not. Sigh. */
266 #ifdef CONFIG_SMP
268 DECLARE_MUTEX(atomic_ops);
270 static __inline__ int atomic_inc_and_ret(int *i)
272 int val;
274 down(&atomic_ops);
275 val = (++(*i));
276 up(&atomic_ops);
277 return val;
279 #else
280 static __inline__ int atomic_inc_and_ret(int *i)
282 return (++(*i));
284 #endif
287 #endif /* __KFUSD_H__ */