Merge branch 'for-2.6.31' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6
[pandora-kernel.git] / drivers / staging / meilhaus / memain.h
1 /*
2  * Copyright (C) 2005 Meilhaus Electronic GmbH (support@meilhaus.de)
3  *
4  * Source File : memain.h
5  * Author      : GG (Guenter Gebhardt)  <g.gebhardt@meilhaus.de>
6  */
7
8 #ifndef _MEMAIN_H_
9 #define _MEMAIN_H_
10
11 #include "meinternal.h"
12
13 #include "meids.h"
14 #include "medebug.h"
15
16 #include "medevice.h"
17 /*#include "me1000_device.h"
18 #include "me1400_device.h"
19 #include "me1600_device.h"*/
20 #include "me4600_device.h"
21 /*#include "me6000_device.h"
22 #include "me0600_device.h"
23 #include "me8100_device.h"
24 #include "me8200_device.h"
25 #include "me0900_device.h"*/
26 #include "medummy.h"
27
28 #ifdef __KERNEL__
29
30 /*=============================================================================
31   Templates
32   ===========================================================================*/
33
34 #define ME_LOCK_MULTIPLEX_TEMPLATE(NAME, TYPE, CALL, DEV_CALL, ARGS)    \
35 static int CALL(struct file *filep, TYPE *arg){ \
36         int err = 0; \
37         int k = 0; \
38         struct list_head *pos; \
39         me_device_t *device; \
40         TYPE karg; \
41         \
42         PDEBUG("executed.\n"); \
43         \
44         err = copy_from_user(&karg, arg, sizeof(TYPE)); \
45         if(err){ \
46                 PERROR("Can't copy arguments to kernel space\n"); \
47                 return -EFAULT; \
48         } \
49         \
50         down_read(&me_rwsem);   \
51         \
52         list_for_each(pos, &me_device_list){    \
53                 if(k == karg.device){   \
54                         device = list_entry(pos, me_device_t, list);    \
55                                 break;  \
56                 }       \
57                 k++;    \
58         }       \
59         \
60         if(pos == &me_device_list){ \
61                 PERROR("Invalid device number specified\n"); \
62                 karg.errno = ME_ERRNO_INVALID_DEVICE; \
63         } \
64         else{ \
65                 spin_lock(&me_lock);    \
66                 if((me_filep != NULL) && (me_filep != filep)){  \
67                         spin_unlock(&me_lock);  \
68                         PERROR("Resource is locked by another process\n");      \
69                         if(karg.lock == ME_LOCK_SET)    \
70                                 karg.errno = ME_ERRNO_LOCKED;   \
71                         else if(karg.lock == ME_LOCK_RELEASE)   \
72                                 karg.errno = ME_ERRNO_SUCCESS;  \
73                         else{   \
74                                 PERROR("Invalid lock specified\n");     \
75                                 karg.errno = ME_ERRNO_INVALID_LOCK;     \
76                         }\
77                 }       \
78                 else {  \
79                         me_count++;     \
80                         spin_unlock(&me_lock);  \
81                         \
82                         karg.errno = device->DEV_CALL ARGS;     \
83                         \
84                         spin_lock(&me_lock);    \
85                         me_count--;     \
86                         spin_unlock(&me_lock);  \
87                 }       \
88         } \
89         \
90         up_read(&me_rwsem);     \
91         \
92         err = copy_to_user(arg, &karg, sizeof(TYPE)); \
93         if(err){ \
94                 PERROR("Can't copy arguments back to user space\n"); \
95                 return -EFAULT; \
96         } \
97         \
98         return ME_ERRNO_SUCCESS; \
99 }
100
101 #define ME_IO_MULTIPLEX_TEMPLATE(NAME, TYPE, CALL, DEV_CALL, ARGS)      \
102 static int CALL(struct file *filep, TYPE *arg){ \
103         int err = 0; \
104         int k = 0; \
105         struct list_head *pos; \
106         me_device_t *device; \
107         TYPE karg; \
108         \
109         PDEBUG("executed.\n"); \
110         \
111         err = copy_from_user(&karg, arg, sizeof(TYPE)); \
112         if(err){ \
113                 PERROR("Can't copy arguments to kernel space\n"); \
114                 return -EFAULT; \
115         } \
116         \
117         down_read(&me_rwsem);   \
118         \
119         list_for_each(pos, &me_device_list){    \
120                 if(k == karg.device){   \
121                         device = list_entry(pos, me_device_t, list);    \
122                                 break;  \
123                 }       \
124                 k++;    \
125         }       \
126         \
127         if(pos == &me_device_list){ \
128                 PERROR("Invalid device number specified\n"); \
129                 karg.errno = ME_ERRNO_INVALID_DEVICE; \
130         } \
131         else{ \
132                 spin_lock(&me_lock);    \
133                 if((me_filep != NULL) && (me_filep != filep)){  \
134                         spin_unlock(&me_lock);  \
135                         PERROR("Resource is locked by another process\n");      \
136                         karg.errno = ME_ERRNO_LOCKED;   \
137                 }       \
138                 else {  \
139                         me_count++;     \
140                         spin_unlock(&me_lock);  \
141                         \
142                         karg.errno = device->DEV_CALL ARGS;     \
143                         \
144                         spin_lock(&me_lock);    \
145                         me_count--;     \
146                         spin_unlock(&me_lock);  \
147                 }       \
148         } \
149         \
150         up_read(&me_rwsem);     \
151         \
152         err = copy_to_user(arg, &karg, sizeof(TYPE)); \
153         if(err){ \
154                 PERROR("Can't copy arguments back to user space\n"); \
155                 return -EFAULT; \
156         } \
157  \
158         return ME_ERRNO_SUCCESS; \
159 }
160
161 #define ME_QUERY_MULTIPLEX_STR_TEMPLATE(NAME, TYPE, CALL, DEV_CALL, ARGS)       \
162 static int CALL(struct file *filep, TYPE *arg){ \
163         int err = 0;    \
164         int k = 0;      \
165         struct list_head *pos;  \
166         me_device_t *device;    \
167         char *msg = NULL;       \
168         TYPE karg;      \
169         \
170         PDEBUG("executed.\n"); \
171         \
172         err = copy_from_user(&karg, arg, sizeof(TYPE)); \
173         if(err){        \
174                 PERROR("Can't copy arguments to kernel space\n");       \
175                 return -EFAULT; \
176         }       \
177         \
178         down_read(&me_rwsem);   \
179         \
180         list_for_each(pos, &me_device_list){    \
181                 if(k == karg.device){   \
182                         device = list_entry(pos, me_device_t, list);    \
183                                 break;  \
184                 }       \
185                 k++;    \
186         }       \
187         \
188         if(pos == &me_device_list){     \
189                 PERROR("Invalid device number specified\n");    \
190                 karg.errno = ME_ERRNO_INVALID_DEVICE;   \
191         }       \
192         else{   \
193                 karg.errno = device->DEV_CALL ARGS;     \
194                 if(!karg.errno){        \
195                         if((strlen(msg) + 1) > karg.count){     \
196                                 PERROR("User buffer for device name is to little\n");   \
197                                 karg.errno = ME_ERRNO_USER_BUFFER_SIZE; \
198                         }       \
199                         else{   \
200                                 err = copy_to_user(karg.name, msg, strlen(msg) + 1);    \
201                                 if(err){        \
202                                         PERROR("Can't copy device name to user space\n");       \
203                                         return -EFAULT; \
204                                 }       \
205                         }       \
206                 }       \
207         }       \
208         \
209         up_read(&me_rwsem);     \
210         \
211         err = copy_to_user(arg, &karg, sizeof(TYPE));   \
212         if(err){        \
213                 PERROR("Can't copy query back to user space\n");        \
214                 return -EFAULT; \
215         }       \
216         \
217         return ME_ERRNO_SUCCESS;        \
218 }
219
220 #define ME_QUERY_MULTIPLEX_TEMPLATE(NAME, TYPE, CALL, DEV_CALL, ARGS)   \
221 static int CALL(struct file *filep, TYPE *arg){ \
222         int err = 0;    \
223         int k = 0;      \
224         struct list_head *pos;  \
225         me_device_t *device;    \
226         TYPE karg;      \
227                 \
228         PDEBUG("executed.\n"); \
229          \
230         err = copy_from_user(&karg, arg, sizeof(TYPE)); \
231         if(err){        \
232                 PERROR("Can't copy arguments from user space\n");       \
233                 return -EFAULT; \
234         }       \
235         \
236         down_read(&me_rwsem);   \
237         \
238         list_for_each(pos, &me_device_list){    \
239                 if(k == karg.device){   \
240                         device = list_entry(pos, me_device_t, list);    \
241                         break;  \
242                 }       \
243                 k++;    \
244         }       \
245                 \
246         if(pos == &me_device_list){     \
247                 PERROR("Invalid device number specified\n");    \
248                 karg.errno = ME_ERRNO_INVALID_DEVICE;   \
249         }       \
250         else{   \
251                 karg.errno = device->DEV_CALL ARGS;     \
252         }       \
253         \
254         up_read(&me_rwsem);     \
255         \
256         err = copy_to_user(arg, &karg, sizeof(TYPE));   \
257         if(err){        \
258                 PERROR("Can't copy arguments to user space\n"); \
259                 return -EFAULT; \
260         }       \
261                 \
262         return ME_ERRNO_SUCCESS;        \
263 }
264
265 #endif //__KERNEL__
266 #endif