SimpleOS

LXR

Navigation



Site hébergé par : enix

The LXR Cross Referencer for SOS

source navigation ]
diff markup ]
identifier search ]
general search ]
 
 
Article:1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 6.5 ] [ 7 ] [ 7.5 ] [ 8 ] [ 9 ] [ 9.5 ]

Diff markup

Differences between /sos/chardev.c (Article 9.5) and /sos/chardev.c (Article 9)


001 /* Copyright (C) 2005      David Decotigny     !! 001 /* Copyright (C) 2005      David Decotigny, Thomas Petazzoni
002                                                   002 
003    This program is free software; you can redi    003    This program is free software; you can redistribute it and/or
004    modify it under the terms of the GNU Genera    004    modify it under the terms of the GNU General Public License
005    as published by the Free Software Foundatio    005    as published by the Free Software Foundation; either version 2
006    of the License, or (at your option) any lat    006    of the License, or (at your option) any later version.
007                                                   007 
008    This program is distributed in the hope tha    008    This program is distributed in the hope that it will be useful,
009    but WITHOUT ANY WARRANTY; without even the     009    but WITHOUT ANY WARRANTY; without even the implied warranty of
010    MERCHANTABILITY or FITNESS FOR A PARTICULAR    010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
011    GNU General Public License for more details    011    GNU General Public License for more details.
012                                                   012 
013    You should have received a copy of the GNU     013    You should have received a copy of the GNU General Public License
014    along with this program; if not, write to t    014    along with this program; if not, write to the Free Software
015    Foundation, Inc., 59 Temple Place - Suite 3    015    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
016    USA.                                           016    USA.
017 */                                                017 */
018                                                   018 
019 #include <sos/assert.h>                           019 #include <sos/assert.h>
020 #include <sos/types.h>                            020 #include <sos/types.h>
021 #include <sos/fs.h>                               021 #include <sos/fs.h>
022 #include <sos/list.h>                             022 #include <sos/list.h>
023 #include <sos/kmalloc.h>                          023 #include <sos/kmalloc.h>
024                                                   024 
025 #include "chardev.h"                              025 #include "chardev.h"
026                                                   026 
027 struct sos_chardev_class                          027 struct sos_chardev_class
028 {                                                 028 {
029   sos_ui32_t                device_class;         029   sos_ui32_t                device_class;
030   struct sos_chardev_ops   *ops;                  030   struct sos_chardev_ops   *ops;
031                                                   031 
032   /** This corresponds to the chardev_class_cu    032   /** This corresponds to the chardev_class_custom_data field passed
033       to open/read/etc. and to sos_chardev_reg    033       to open/read/etc. and to sos_chardev_register_class() */
034   void                     *custom_data;          034   void                     *custom_data;
035                                                   035 
036   sos_count_t               ref_cnt; /**< incr    036   sos_count_t               ref_cnt; /**< increased each time a FS
037                                           node    037                                           node is opened */
038                                                   038 
039   struct sos_chardev_class *next, *prev;          039   struct sos_chardev_class *next, *prev;
040 };                                                040 };
041                                                   041 
042                                                   042 
043 struct sos_chardev_opened_file                    043 struct sos_chardev_opened_file
044 {                                                 044 {
045   /** "normal" VFS opened file structure is av    045   /** "normal" VFS opened file structure is available in this
046       structure */                                046       structure */
047   struct sos_fs_opened_file  super;               047   struct sos_fs_opened_file  super;
048                                                   048 
049   /** Additional information for this opened f    049   /** Additional information for this opened file: the device's class
050       structure */                                050       structure */
051   struct sos_chardev_class  *class;               051   struct sos_chardev_class  *class;
052 };                                                052 };
053                                                   053 
054                                                   054 
055 /** The list of registered classes, ie the dic    055 /** The list of registered classes, ie the dictionary major number ->
056     device class description */                   056     device class description */
057 static struct sos_chardev_class *registered_ch    057 static struct sos_chardev_class *registered_chardev_classes;
058                                                   058 
059                                                   059 
060 /* Forward declarations */                        060 /* Forward declarations */
061 static struct sos_fs_ops_opened_file chardev_o    061 static struct sos_fs_ops_opened_file chardev_ops_opened_file;
062 static struct sos_fs_ops_opened_chardev charde    062 static struct sos_fs_ops_opened_chardev chardev_ops_opened_chardev;
063                                                   063 
064 static sos_ret_t                                  064 static sos_ret_t
                                                   >> 065 chardev_helper_sync(struct sos_fs_node * this);
                                                   >> 066 static sos_ret_t
065 chardev_helper_new_opened_file(struct sos_fs_n    067 chardev_helper_new_opened_file(struct sos_fs_node * this,
066                                const struct so    068                                const struct sos_process * owner,
067                                sos_ui32_t open    069                                sos_ui32_t open_flags,
068                                struct sos_fs_o    070                                struct sos_fs_opened_file ** result_of);
069 static sos_ret_t                                  071 static sos_ret_t
070 chardev_helper_close_opened_file(struct sos_fs    072 chardev_helper_close_opened_file(struct sos_fs_node * this,
071                                  struct sos_fs    073                                  struct sos_fs_opened_file * of);
072 static sos_ret_t                                  074 static sos_ret_t
073 duplicate_opened_chardev(struct sos_fs_opened_    075 duplicate_opened_chardev(struct sos_fs_opened_file *this,
074                          const struct sos_proc    076                          const struct sos_process  * for_owner,
075                          struct sos_fs_opened_    077                          struct sos_fs_opened_file **result);
076                                                   078 
077                                                   079 
078 /**                                               080 /**
079  * Return the device descriptionn structure fo    081  * Return the device descriptionn structure for the corresponding
080  * device class, or NULL when none found.         082  * device class, or NULL when none found.
081  */                                               083  */
082 static struct sos_chardev_class * lookup_chard    084 static struct sos_chardev_class * lookup_chardev_class(sos_ui32_t device_class)
083 {                                                 085 {
084   struct sos_chardev_class *chardev;              086   struct sos_chardev_class *chardev;
085   int nb;                                         087   int nb;
086                                                   088 
087   list_foreach (registered_chardev_classes, ch    089   list_foreach (registered_chardev_classes, chardev, nb)
088     {                                             090     {
089       if (chardev->device_class == device_clas    091       if (chardev->device_class == device_class)
090         return chardev;                           092         return chardev;
091     }                                             093     }
092                                                   094 
093   return NULL;                                    095   return NULL;
094 }                                                 096 }
095                                                   097 
096                                                   098 
097 sos_ret_t sos_chardev_register_class (sos_ui32    099 sos_ret_t sos_chardev_register_class (sos_ui32_t device_class,
098                                       struct s    100                                       struct sos_chardev_ops *ops,
099                                       void * c    101                                       void * chardev_class_custom_data)
100 {                                                 102 {
101   struct sos_chardev_class *chardev;              103   struct sos_chardev_class *chardev;
102                                                   104 
103   /* Make sure this device class is not alread    105   /* Make sure this device class is not already registered */
104   chardev = lookup_chardev_class(device_class)    106   chardev = lookup_chardev_class(device_class);
105   if (NULL != chardev)                            107   if (NULL != chardev)
106     return -SOS_EBUSY;                            108     return -SOS_EBUSY;
107                                                   109 
108   /* Allocate and initialize a new device desc    110   /* Allocate and initialize a new device description */
109   chardev = (struct sos_chardev_class *)          111   chardev = (struct sos_chardev_class *)
110     sos_kmalloc(sizeof(struct sos_chardev_clas    112     sos_kmalloc(sizeof(struct sos_chardev_class), 0);
111   if (chardev == NULL)                            113   if (chardev == NULL)
112     return -SOS_ENOMEM;                           114     return -SOS_ENOMEM;
113                                                   115 
114   chardev->device_class = device_class;           116   chardev->device_class = device_class;
115   chardev->custom_data  = chardev_class_custom    117   chardev->custom_data  = chardev_class_custom_data;
116   chardev->ops          = ops;                    118   chardev->ops          = ops;
117   chardev->ref_cnt      = 1;                      119   chardev->ref_cnt      = 1;
118                                                   120 
119   /* insert it into the list */                   121   /* insert it into the list */
120   list_add_tail (registered_chardev_classes, c    122   list_add_tail (registered_chardev_classes, chardev);
121                                                   123 
122   return SOS_OK;                                  124   return SOS_OK;
123 }                                                 125 }
124                                                   126 
125                                                   127 
126 sos_ret_t sos_chardev_unregister_class (sos_ui    128 sos_ret_t sos_chardev_unregister_class (sos_ui32_t device_class)
127 {                                                 129 {
128   struct sos_chardev_class *chardev;              130   struct sos_chardev_class *chardev;
129                                                   131 
130   /* Make sure this device class is already re    132   /* Make sure this device class is already registered */
131   chardev = lookup_chardev_class(device_class)    133   chardev = lookup_chardev_class(device_class);
132   if (NULL == chardev)                            134   if (NULL == chardev)
133     return -SOS_ENODEV;                           135     return -SOS_ENODEV;
134                                                   136 
135   /* Make sure no files are already opened for    137   /* Make sure no files are already opened for it */
136   if (chardev->ref_cnt != 1)                      138   if (chardev->ref_cnt != 1)
137     return -SOS_EBUSY;                            139     return -SOS_EBUSY;
138                                                   140 
139   /* remove it from the list */                   141   /* remove it from the list */
140   list_delete (registered_chardev_classes, cha    142   list_delete (registered_chardev_classes, chardev);
141   return sos_kfree((sos_vaddr_t)chardev);         143   return sos_kfree((sos_vaddr_t)chardev);
142 }                                                 144 }
143                                                   145 
144                                                   146 
145                                                   147 
146 sos_ret_t sos_chardev_helper_ref_new_fsnode(st    148 sos_ret_t sos_chardev_helper_ref_new_fsnode(struct sos_fs_node * this)
147 {                                                 149 {
                                                   >> 150   this->sync              = chardev_helper_sync;
148   this->new_opened_file   = chardev_helper_new    151   this->new_opened_file   = chardev_helper_new_opened_file;
149   this->close_opened_file = chardev_helper_clo    152   this->close_opened_file = chardev_helper_close_opened_file;
150                                                   153 
151   return SOS_OK;                                  154   return SOS_OK;
152 }                                                 155 }
153                                                   156 
154                                                   157 
155 sos_ret_t sos_chardev_helper_release_fsnode(st    158 sos_ret_t sos_chardev_helper_release_fsnode(struct sos_fs_node * this)
                                                   >> 159 {
                                                   >> 160   return SOS_OK;
                                                   >> 161 }
                                                   >> 162 
                                                   >> 163 
                                                   >> 164 /** No synchronization to anything needed for a character device */
                                                   >> 165 static sos_ret_t
                                                   >> 166 chardev_helper_sync(struct sos_fs_node * this)
156 {                                                 167 {
157   return SOS_OK;                                  168   return SOS_OK;
158 }                                                 169 }
159                                                   170 
160                                                   171 
161 /** Callback called each time an FS-node is op    172 /** Callback called each time an FS-node is opened by a user process:
162     create a new sos_chardev_opened_file objec    173     create a new sos_chardev_opened_file object associated to the
163     correct major number, and call the device     174     correct major number, and call the device driver's open method */
164 static sos_ret_t                                  175 static sos_ret_t
165 chardev_helper_new_opened_file(struct sos_fs_n    176 chardev_helper_new_opened_file(struct sos_fs_node * this,
166                                const struct so    177                                const struct sos_process * owner,
167                                sos_ui32_t open    178                                sos_ui32_t open_flags,
168                                struct sos_fs_o    179                                struct sos_fs_opened_file ** result_of)
169 {                                                 180 {
170   sos_ret_t retval;                               181   sos_ret_t retval;
171   struct sos_chardev_opened_file *chardev_of;     182   struct sos_chardev_opened_file *chardev_of;
172                                                   183 
173   /* Lookup the character device description s    184   /* Lookup the character device description structure */
174   struct sos_chardev_class * chardev              185   struct sos_chardev_class * chardev
175     = lookup_chardev_class(this->dev_id.device    186     = lookup_chardev_class(this->dev_id.device_class);
176   if (NULL == chardev)                            187   if (NULL == chardev)
177     return -SOS_ENODEV;                           188     return -SOS_ENODEV;
178                                                   189 
179   /* Alloocate the new "open file" description    190   /* Alloocate the new "open file" description structure */
180   chardev_of = (struct sos_chardev_opened_file    191   chardev_of = (struct sos_chardev_opened_file*)
181     sos_kmalloc(sizeof(struct sos_chardev_open    192     sos_kmalloc(sizeof(struct sos_chardev_opened_file), 0);
182   if (NULL == chardev_of)                         193   if (NULL == chardev_of)
183     return -SOS_ENOMEM;                           194     return -SOS_ENOMEM;
184                                                   195 
185   memset(chardev_of, 0x0, sizeof(struct sos_ch    196   memset(chardev_of, 0x0, sizeof(struct sos_chardev_opened_file));
186   chardev_of->class = chardev;                    197   chardev_of->class = chardev;
187   *result_of = & chardev_of->super;               198   *result_of = & chardev_of->super;
188                                                   199 
189   /* Increase the reference coount for that no    200   /* Increase the reference coount for that node */
190   SOS_ASSERT_FATAL(chardev->ref_cnt >= 1);        201   SOS_ASSERT_FATAL(chardev->ref_cnt >= 1);
191   chardev->ref_cnt ++;                            202   chardev->ref_cnt ++;
192                                                   203 
193   /* Initialize the read/write/seek callbacks     204   /* Initialize the read/write/seek callbacks */
194   (*result_of)->owner       = owner;              205   (*result_of)->owner       = owner;
195   (*result_of)->open_flags  = open_flags;         206   (*result_of)->open_flags  = open_flags;
196   (*result_of)->ops_file    = & chardev_ops_op    207   (*result_of)->ops_file    = & chardev_ops_opened_file;
197   (*result_of)->ops_chardev = & chardev_ops_op    208   (*result_of)->ops_chardev = & chardev_ops_opened_chardev;
198                                                   209 
199   /* Call the open callback */                    210   /* Call the open callback */
200   retval = chardev->ops->open(this, & chardev_    211   retval = chardev->ops->open(this, & chardev_of->super, chardev->custom_data);
201   if (SOS_OK != retval)                           212   if (SOS_OK != retval)
202     {                                             213     {
203       sos_kfree((sos_vaddr_t) chardev_of);        214       sos_kfree((sos_vaddr_t) chardev_of);
204       chardev->ref_cnt --;                        215       chardev->ref_cnt --;
205       *result_of = NULL;                          216       *result_of = NULL;
206       return retval;                              217       return retval;
207     }                                             218     }
208                                                   219 
209   /* Specify the duplicate method */              220   /* Specify the duplicate method */
210   (*result_of)->duplicate = duplicate_opened_c    221   (*result_of)->duplicate = duplicate_opened_chardev;
211                                                   222 
212   return retval;                                  223   return retval;
213 }                                                 224 }
214                                                   225 
215                                                   226 
216 /** Callback called each time an opened file i    227 /** Callback called each time an opened file is closed. Un-allocate
217     the associated sos_chardev_opened_file obj    228     the associated sos_chardev_opened_file object */
218 static sos_ret_t                                  229 static sos_ret_t
219 chardev_helper_close_opened_file(struct sos_fs    230 chardev_helper_close_opened_file(struct sos_fs_node * this,
220                                  struct sos_fs    231                                  struct sos_fs_opened_file * of)
221 {                                                 232 {
222   sos_ret_t retval;                               233   sos_ret_t retval;
223   struct sos_chardev_opened_file *chardev_of      234   struct sos_chardev_opened_file *chardev_of
224     = ((struct sos_chardev_opened_file*)of);      235     = ((struct sos_chardev_opened_file*)of);
225                                                   236 
226   struct sos_chardev_class * chardev = chardev    237   struct sos_chardev_class * chardev = chardev_of->class;
227   SOS_ASSERT_FATAL(NULL != chardev);              238   SOS_ASSERT_FATAL(NULL != chardev);
228                                                   239 
229   /* Free the new "open file" description stru    240   /* Free the new "open file" description structure */
230   if (NULL != chardev->ops->close)                241   if (NULL != chardev->ops->close)
231     retval = chardev->ops->close(& chardev_of-    242     retval = chardev->ops->close(& chardev_of->super, chardev->custom_data);
232   else                                            243   else
233     retval = SOS_OK;                              244     retval = SOS_OK;
234   if (SOS_OK != retval)                           245   if (SOS_OK != retval)
235     return retval;                                246     return retval;
236                                                   247 
237   /* Decrease the reference coount for that no    248   /* Decrease the reference coount for that node */
238   SOS_ASSERT_FATAL(chardev->ref_cnt > 1);         249   SOS_ASSERT_FATAL(chardev->ref_cnt > 1);
239   chardev->ref_cnt --;                            250   chardev->ref_cnt --;
240                                                   251   
241   sos_kfree((sos_vaddr_t) chardev_of);            252   sos_kfree((sos_vaddr_t) chardev_of);
242   return retval;                                  253   return retval;
243 }                                                 254 }
244                                                   255 
245                                                   256 
246 /**                                               257 /**
247  * Callback called each time a process is "for    258  * Callback called each time a process is "forked": create a new
248  * sos_chardev_opened_file for the new process    259  * sos_chardev_opened_file for the new process.
249  *                                                260  *
250  * @note Almost identical to the open callback    261  * @note Almost identical to the open callback.
251  */                                               262  */
252 static sos_ret_t                                  263 static sos_ret_t
253 duplicate_opened_chardev(struct sos_fs_opened_    264 duplicate_opened_chardev(struct sos_fs_opened_file *this,
254                          const struct sos_proc    265                          const struct sos_process  * for_owner,
255                          struct sos_fs_opened_    266                          struct sos_fs_opened_file **result)
256 {                                                 267 {
257   sos_ret_t retval;                               268   sos_ret_t retval;
258   struct sos_chardev_opened_file *chardev_of      269   struct sos_chardev_opened_file *chardev_of
259     = ((struct sos_chardev_opened_file*)this);    270     = ((struct sos_chardev_opened_file*)this);
260   struct sos_chardev_opened_file *new_chardev_    271   struct sos_chardev_opened_file *new_chardev_of;
261   struct sos_fs_node * fsnode = sos_fs_nscache    272   struct sos_fs_node * fsnode = sos_fs_nscache_get_fs_node(this->direntry);
262                                                   273 
263   *result = NULL;                                 274   *result = NULL;
264                                                   275 
265   /* Lookup the character device description s    276   /* Lookup the character device description structure */
266   struct sos_chardev_class * chardev = chardev    277   struct sos_chardev_class * chardev = chardev_of->class;
267   SOS_ASSERT_FATAL(NULL != chardev);              278   SOS_ASSERT_FATAL(NULL != chardev);
268                                                   279 
269   /* Allocate a new duplicate copy of the orig    280   /* Allocate a new duplicate copy of the original opened file */
270   new_chardev_of = (struct sos_chardev_opened_    281   new_chardev_of = (struct sos_chardev_opened_file*)
271     sos_kmalloc(sizeof(struct sos_chardev_open    282     sos_kmalloc(sizeof(struct sos_chardev_opened_file), 0);
272   if (NULL == new_chardev_of)                     283   if (NULL == new_chardev_of)
273     return -SOS_ENOMEM;                           284     return -SOS_ENOMEM;
274                                                   285 
275   memcpy(new_chardev_of, chardev_of, sizeof(*n    286   memcpy(new_chardev_of, chardev_of, sizeof(*new_chardev_of));
276   new_chardev_of->super.owner    = for_owner;     287   new_chardev_of->super.owner    = for_owner;
277   new_chardev_of->super.direntry = NULL; /* Re    288   new_chardev_of->super.direntry = NULL; /* Reset the direntry
278                                             fo    289                                             for the new opened file */
279   SOS_ASSERT_FATAL(chardev->ref_cnt > 1);         290   SOS_ASSERT_FATAL(chardev->ref_cnt > 1);
280   chardev->ref_cnt ++;                            291   chardev->ref_cnt ++;
281                                                   292 
282   retval = chardev->ops->open(fsnode,             293   retval = chardev->ops->open(fsnode,
283                               & new_chardev_of    294                               & new_chardev_of->super, chardev->custom_data);
284   if (SOS_OK != retval)                           295   if (SOS_OK != retval)
285     {                                             296     {
286       sos_kfree((sos_vaddr_t) new_chardev_of);    297       sos_kfree((sos_vaddr_t) new_chardev_of);
287       chardev->ref_cnt --;                        298       chardev->ref_cnt --;
288       return retval;                              299       return retval;
289     }                                             300     }
290                                                   301 
291   /* Make sure the required methods are overlo    302   /* Make sure the required methods are overloaded */
292   SOS_ASSERT_FATAL(NULL != new_chardev_of->sup    303   SOS_ASSERT_FATAL(NULL != new_chardev_of->super.ops_file);
293   SOS_ASSERT_FATAL(NULL != new_chardev_of->sup    304   SOS_ASSERT_FATAL(NULL != new_chardev_of->super.ops_file->seek);
294   SOS_ASSERT_FATAL(NULL != new_chardev_of->sup    305   SOS_ASSERT_FATAL(NULL != new_chardev_of->super.ops_file->read);
295                                                   306 
296   *result = & new_chardev_of->super;              307   *result = & new_chardev_of->super;
297   return retval;                                  308   return retval;
298 }                                                 309 }
299                                                   310 
300                                                   311 
301 /*                                                312 /*
302  * FS generic character device wrapper functio    313  * FS generic character device wrapper functions
303  */                                               314  */
304                                                   315 
305 /**                                               316 /**
306  * Callback called to change the position in t    317  * Callback called to change the position in the opened file: call the
307  * seek method of the device driver.              318  * seek method of the device driver.
308  */                                               319  */
309 static sos_ret_t chardev_wrap_seek(struct sos_    320 static sos_ret_t chardev_wrap_seek(struct sos_fs_opened_file *this,
310                                    sos_lsoffse    321                                    sos_lsoffset_t offset,
311                                    sos_seek_wh    322                                    sos_seek_whence_t whence,
312                                    /* out */ s    323                                    /* out */ sos_lsoffset_t * result_position)
313 {                                                 324 {
314   sos_ret_t retval = -SOS_ENOSYS;                 325   sos_ret_t retval = -SOS_ENOSYS;
315   struct sos_chardev_opened_file *chardev_of      326   struct sos_chardev_opened_file *chardev_of
316     = ((struct sos_chardev_opened_file*)this);    327     = ((struct sos_chardev_opened_file*)this);
317                                                   328 
318   struct sos_chardev_class * chardev = chardev    329   struct sos_chardev_class * chardev = chardev_of->class;
319   SOS_ASSERT_FATAL(NULL != chardev);              330   SOS_ASSERT_FATAL(NULL != chardev);
320   SOS_ASSERT_FATAL(NULL != chardev->ops);         331   SOS_ASSERT_FATAL(NULL != chardev->ops);
321                                                   332 
322   if (NULL != chardev->ops->seek)                 333   if (NULL != chardev->ops->seek)
323     retval = chardev->ops->seek(this, offset,     334     retval = chardev->ops->seek(this, offset, whence, result_position);
324                                                   335   
325   return retval;                                  336   return retval;
326 }                                                 337 }
327                                                   338 
328                                                   339 
329 /**                                               340 /**
330  * Callback called to read the contents of the    341  * Callback called to read the contents of the opened file: call the
331  * read method of the device driver.              342  * read method of the device driver.
332  */                                               343  */
333 static sos_ret_t chardev_wrap_read(struct sos_    344 static sos_ret_t chardev_wrap_read(struct sos_fs_opened_file *this,
334                                    sos_uaddr_t    345                                    sos_uaddr_t dest_buf,
335                                    sos_size_t     346                                    sos_size_t * /* in/out */len)
336 {                                                 347 {
337   sos_ret_t retval = -SOS_ENOSYS;                 348   sos_ret_t retval = -SOS_ENOSYS;
338   struct sos_chardev_opened_file *chardev_of      349   struct sos_chardev_opened_file *chardev_of
339     = ((struct sos_chardev_opened_file*)this);    350     = ((struct sos_chardev_opened_file*)this);
340                                                   351 
341   struct sos_chardev_class * chardev = chardev    352   struct sos_chardev_class * chardev = chardev_of->class;
342   SOS_ASSERT_FATAL(NULL != chardev);              353   SOS_ASSERT_FATAL(NULL != chardev);
343   SOS_ASSERT_FATAL(NULL != chardev->ops);         354   SOS_ASSERT_FATAL(NULL != chardev->ops);
344                                                   355 
345   if (NULL != chardev->ops->read)                 356   if (NULL != chardev->ops->read)
346     retval = chardev->ops->read(this, dest_buf    357     retval = chardev->ops->read(this, dest_buf, len);
347                                                   358   
348   return retval;                                  359   return retval;
349 }                                                 360 }
350                                                   361 
351                                                   362 
352 /**                                               363 /**
353  * Callback called to write bytes to the opene    364  * Callback called to write bytes to the opened file: call the write
354  * method of the device driver.                   365  * method of the device driver.
355  */                                               366  */
356 static sos_ret_t chardev_wrap_write(struct sos    367 static sos_ret_t chardev_wrap_write(struct sos_fs_opened_file *this,
357                                     sos_uaddr_    368                                     sos_uaddr_t src_buf,
358                                     sos_size_t    369                                     sos_size_t * /* in/out */len)
359 {                                                 370 {
360   sos_ret_t retval = -SOS_ENOSYS;                 371   sos_ret_t retval = -SOS_ENOSYS;
361   struct sos_chardev_opened_file *chardev_of      372   struct sos_chardev_opened_file *chardev_of
362     = ((struct sos_chardev_opened_file*)this);    373     = ((struct sos_chardev_opened_file*)this);
363                                                   374 
364   struct sos_chardev_class * chardev = chardev    375   struct sos_chardev_class * chardev = chardev_of->class;
365   SOS_ASSERT_FATAL(NULL != chardev);              376   SOS_ASSERT_FATAL(NULL != chardev);
366   SOS_ASSERT_FATAL(NULL != chardev->ops);         377   SOS_ASSERT_FATAL(NULL != chardev->ops);
367                                                   378 
368   if (NULL != chardev->ops->write)                379   if (NULL != chardev->ops->write)
369     retval = chardev->ops->write(this, src_buf    380     retval = chardev->ops->write(this, src_buf, len);
370                                                   381   
371   return retval;                                  382   return retval;
372 }                                                 383 }
373                                                   384 
374                                                   385 
375 /**                                               386 /**
376  * Callback called to map the contents of the     387  * Callback called to map the contents of the opened file: call the
377  * map method of the device driver.               388  * map method of the device driver.
378  */                                               389  */
379 static sos_ret_t chardev_wrap_mmap(struct sos_    390 static sos_ret_t chardev_wrap_mmap(struct sos_fs_opened_file *this,
380                                    sos_uaddr_t    391                                    sos_uaddr_t *uaddr, sos_size_t size,
381                                    sos_ui32_t     392                                    sos_ui32_t access_rights,
382                                    sos_ui32_t     393                                    sos_ui32_t flags,
383                                    sos_luoffse    394                                    sos_luoffset_t offset)
384 {                                                 395 {
385   sos_ret_t retval = -SOS_ENOSYS;                 396   sos_ret_t retval = -SOS_ENOSYS;
386   struct sos_chardev_opened_file *chardev_of      397   struct sos_chardev_opened_file *chardev_of
387     = ((struct sos_chardev_opened_file*)this);    398     = ((struct sos_chardev_opened_file*)this);
388                                                   399 
389   struct sos_chardev_class * chardev = chardev    400   struct sos_chardev_class * chardev = chardev_of->class;
390   SOS_ASSERT_FATAL(NULL != chardev);              401   SOS_ASSERT_FATAL(NULL != chardev);
391   SOS_ASSERT_FATAL(NULL != chardev->ops);         402   SOS_ASSERT_FATAL(NULL != chardev->ops);
392                                                   403 
393   if (NULL != chardev->ops->mmap)                 404   if (NULL != chardev->ops->mmap)
394     retval = chardev->ops->mmap(this, uaddr, s    405     retval = chardev->ops->mmap(this, uaddr, size,
395                                 access_rights,    406                                 access_rights, flags, offset);
396                                                   407   
397   return retval;                                  408   return retval;
398 }                                                 409 }
399                                                   410 
400                                                   411 
401 /**                                               412 /**
402  * Callback called to change the state of the     413  * Callback called to change the state of the opened file: call the
403  * fcntl method of the device driver.             414  * fcntl method of the device driver.
404  */                                               415  */
405 static sos_ret_t chardev_wrap_fcntl(struct sos    416 static sos_ret_t chardev_wrap_fcntl(struct sos_fs_opened_file *this,
406                                     int req_id    417                                     int req_id,
407                                     sos_ui32_t    418                                     sos_ui32_t req_arg)
408 {                                                 419 {
409   sos_ret_t retval = -SOS_ENOSYS;                 420   sos_ret_t retval = -SOS_ENOSYS;
410   struct sos_chardev_opened_file *chardev_of      421   struct sos_chardev_opened_file *chardev_of
411     = ((struct sos_chardev_opened_file*)this);    422     = ((struct sos_chardev_opened_file*)this);
412                                                   423 
413   struct sos_chardev_class * chardev = chardev    424   struct sos_chardev_class * chardev = chardev_of->class;
414   SOS_ASSERT_FATAL(NULL != chardev);              425   SOS_ASSERT_FATAL(NULL != chardev);
415   SOS_ASSERT_FATAL(NULL != chardev->ops);         426   SOS_ASSERT_FATAL(NULL != chardev->ops);
416                                                   427 
417   if (NULL != chardev->ops->fcntl)                428   if (NULL != chardev->ops->fcntl)
418     retval = chardev->ops->fcntl(this, req_id,    429     retval = chardev->ops->fcntl(this, req_id, req_arg);
419                                                   430   
420   return retval;                                  431   return retval;
421 }                                                 432 }
422                                                   433 
423                                                   434 
424 /**                                               435 /**
425  * Callback called to control the underlying d    436  * Callback called to control the underlying device: call the ioctl
426  * method of the device driver.                   437  * method of the device driver.
427  */                                               438  */
428 static sos_ret_t chardev_wrap_ioctl(struct sos    439 static sos_ret_t chardev_wrap_ioctl(struct sos_fs_opened_file *this,
429                                     int req_id    440                                     int req_id,
430                                     sos_ui32_t    441                                     sos_ui32_t req_arg)
431 {                                                 442 {
432   sos_ret_t retval = -SOS_ENOSYS;                 443   sos_ret_t retval = -SOS_ENOSYS;
433   struct sos_chardev_opened_file *chardev_of      444   struct sos_chardev_opened_file *chardev_of
434     = ((struct sos_chardev_opened_file*)this);    445     = ((struct sos_chardev_opened_file*)this);
435                                                   446 
436   struct sos_chardev_class * chardev = chardev    447   struct sos_chardev_class * chardev = chardev_of->class;
437   SOS_ASSERT_FATAL(NULL != chardev);              448   SOS_ASSERT_FATAL(NULL != chardev);
438   SOS_ASSERT_FATAL(NULL != chardev->ops);         449   SOS_ASSERT_FATAL(NULL != chardev->ops);
439                                                   450 
440   if (NULL != chardev->ops->ioctl)                451   if (NULL != chardev->ops->ioctl)
441     retval = chardev->ops->ioctl(this, req_id,    452     retval = chardev->ops->ioctl(this, req_id, req_arg);
442                                                   453   
443   return retval;                                  454   return retval;
444 }                                                 455 }
445                                                   456 
446                                                   457 
447 /**                                               458 /**
448  * Gather the callbacks for a "character devic    459  * Gather the callbacks for a "character device" opened file
449  */                                               460  */
450 static struct sos_fs_ops_opened_file chardev_o    461 static struct sos_fs_ops_opened_file chardev_ops_opened_file
451   = (struct sos_fs_ops_opened_file) {             462   = (struct sos_fs_ops_opened_file) {
452     .seek  = chardev_wrap_seek,                   463     .seek  = chardev_wrap_seek,
453     .read  = chardev_wrap_read,                   464     .read  = chardev_wrap_read,
454     .write = chardev_wrap_write,                  465     .write = chardev_wrap_write,
455     .mmap  = chardev_wrap_mmap,                   466     .mmap  = chardev_wrap_mmap,
456     .fcntl = chardev_wrap_fcntl                   467     .fcntl = chardev_wrap_fcntl
457   };                                              468   };
458                                                   469 
459                                                   470 
460 static struct sos_fs_ops_opened_chardev charde    471 static struct sos_fs_ops_opened_chardev chardev_ops_opened_chardev
461   = (struct sos_fs_ops_opened_chardev) {          472   = (struct sos_fs_ops_opened_chardev) {
462     .ioctl = chardev_wrap_ioctl                   473     .ioctl = chardev_wrap_ioctl
463   };                                              474   };
                                                      

source navigation ] diff markup ] identifier search ] general search ]