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.5)


001 /* Copyright (C) 2005      David Decotigny        001 /* Copyright (C) 2005      David Decotigny
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_new_opened_file(struct sos_fs_n    065 chardev_helper_new_opened_file(struct sos_fs_node * this,
066                                const struct so    066                                const struct sos_process * owner,
067                                sos_ui32_t open    067                                sos_ui32_t open_flags,
068                                struct sos_fs_o    068                                struct sos_fs_opened_file ** result_of);
069 static sos_ret_t                                  069 static sos_ret_t
070 chardev_helper_close_opened_file(struct sos_fs    070 chardev_helper_close_opened_file(struct sos_fs_node * this,
071                                  struct sos_fs    071                                  struct sos_fs_opened_file * of);
072 static sos_ret_t                                  072 static sos_ret_t
073 duplicate_opened_chardev(struct sos_fs_opened_    073 duplicate_opened_chardev(struct sos_fs_opened_file *this,
074                          const struct sos_proc    074                          const struct sos_process  * for_owner,
075                          struct sos_fs_opened_    075                          struct sos_fs_opened_file **result);
076                                                   076 
077                                                   077 
078 /**                                               078 /**
079  * Return the device descriptionn structure fo    079  * Return the device descriptionn structure for the corresponding
080  * device class, or NULL when none found.         080  * device class, or NULL when none found.
081  */                                               081  */
082 static struct sos_chardev_class * lookup_chard    082 static struct sos_chardev_class * lookup_chardev_class(sos_ui32_t device_class)
083 {                                                 083 {
084   struct sos_chardev_class *chardev;              084   struct sos_chardev_class *chardev;
085   int nb;                                         085   int nb;
086                                                   086 
087   list_foreach (registered_chardev_classes, ch    087   list_foreach (registered_chardev_classes, chardev, nb)
088     {                                             088     {
089       if (chardev->device_class == device_clas    089       if (chardev->device_class == device_class)
090         return chardev;                           090         return chardev;
091     }                                             091     }
092                                                   092 
093   return NULL;                                    093   return NULL;
094 }                                                 094 }
095                                                   095 
096                                                   096 
097 sos_ret_t sos_chardev_register_class (sos_ui32    097 sos_ret_t sos_chardev_register_class (sos_ui32_t device_class,
098                                       struct s    098                                       struct sos_chardev_ops *ops,
099                                       void * c    099                                       void * chardev_class_custom_data)
100 {                                                 100 {
101   struct sos_chardev_class *chardev;              101   struct sos_chardev_class *chardev;
102                                                   102 
103   /* Make sure this device class is not alread    103   /* Make sure this device class is not already registered */
104   chardev = lookup_chardev_class(device_class)    104   chardev = lookup_chardev_class(device_class);
105   if (NULL != chardev)                            105   if (NULL != chardev)
106     return -SOS_EBUSY;                            106     return -SOS_EBUSY;
107                                                   107 
108   /* Allocate and initialize a new device desc    108   /* Allocate and initialize a new device description */
109   chardev = (struct sos_chardev_class *)          109   chardev = (struct sos_chardev_class *)
110     sos_kmalloc(sizeof(struct sos_chardev_clas    110     sos_kmalloc(sizeof(struct sos_chardev_class), 0);
111   if (chardev == NULL)                            111   if (chardev == NULL)
112     return -SOS_ENOMEM;                           112     return -SOS_ENOMEM;
113                                                   113 
114   chardev->device_class = device_class;           114   chardev->device_class = device_class;
115   chardev->custom_data  = chardev_class_custom    115   chardev->custom_data  = chardev_class_custom_data;
116   chardev->ops          = ops;                    116   chardev->ops          = ops;
117   chardev->ref_cnt      = 1;                      117   chardev->ref_cnt      = 1;
118                                                   118 
119   /* insert it into the list */                   119   /* insert it into the list */
120   list_add_tail (registered_chardev_classes, c    120   list_add_tail (registered_chardev_classes, chardev);
121                                                   121 
122   return SOS_OK;                                  122   return SOS_OK;
123 }                                                 123 }
124                                                   124 
125                                                   125 
126 sos_ret_t sos_chardev_unregister_class (sos_ui    126 sos_ret_t sos_chardev_unregister_class (sos_ui32_t device_class)
127 {                                                 127 {
128   struct sos_chardev_class *chardev;              128   struct sos_chardev_class *chardev;
129                                                   129 
130   /* Make sure this device class is already re    130   /* Make sure this device class is already registered */
131   chardev = lookup_chardev_class(device_class)    131   chardev = lookup_chardev_class(device_class);
132   if (NULL == chardev)                            132   if (NULL == chardev)
133     return -SOS_ENODEV;                           133     return -SOS_ENODEV;
134                                                   134 
135   /* Make sure no files are already opened for    135   /* Make sure no files are already opened for it */
136   if (chardev->ref_cnt != 1)                      136   if (chardev->ref_cnt != 1)
137     return -SOS_EBUSY;                            137     return -SOS_EBUSY;
138                                                   138 
139   /* remove it from the list */                   139   /* remove it from the list */
140   list_delete (registered_chardev_classes, cha    140   list_delete (registered_chardev_classes, chardev);
141   return sos_kfree((sos_vaddr_t)chardev);         141   return sos_kfree((sos_vaddr_t)chardev);
142 }                                                 142 }
143                                                   143 
144                                                   144 
145                                                   145 
146 sos_ret_t sos_chardev_helper_ref_new_fsnode(st    146 sos_ret_t sos_chardev_helper_ref_new_fsnode(struct sos_fs_node * this)
147 {                                                 147 {
148   this->new_opened_file   = chardev_helper_new    148   this->new_opened_file   = chardev_helper_new_opened_file;
149   this->close_opened_file = chardev_helper_clo    149   this->close_opened_file = chardev_helper_close_opened_file;
150                                                   150 
151   return SOS_OK;                                  151   return SOS_OK;
152 }                                                 152 }
153                                                   153 
154                                                   154 
155 sos_ret_t sos_chardev_helper_release_fsnode(st    155 sos_ret_t sos_chardev_helper_release_fsnode(struct sos_fs_node * this)
156 {                                                 156 {
157   return SOS_OK;                                  157   return SOS_OK;
158 }                                                 158 }
159                                                   159 
160                                                   160 
161 /** Callback called each time an FS-node is op    161 /** Callback called each time an FS-node is opened by a user process:
162     create a new sos_chardev_opened_file objec    162     create a new sos_chardev_opened_file object associated to the
163     correct major number, and call the device     163     correct major number, and call the device driver's open method */
164 static sos_ret_t                                  164 static sos_ret_t
165 chardev_helper_new_opened_file(struct sos_fs_n    165 chardev_helper_new_opened_file(struct sos_fs_node * this,
166                                const struct so    166                                const struct sos_process * owner,
167                                sos_ui32_t open    167                                sos_ui32_t open_flags,
168                                struct sos_fs_o    168                                struct sos_fs_opened_file ** result_of)
169 {                                                 169 {
170   sos_ret_t retval;                               170   sos_ret_t retval;
171   struct sos_chardev_opened_file *chardev_of;     171   struct sos_chardev_opened_file *chardev_of;
172                                                   172 
173   /* Lookup the character device description s    173   /* Lookup the character device description structure */
174   struct sos_chardev_class * chardev              174   struct sos_chardev_class * chardev
175     = lookup_chardev_class(this->dev_id.device    175     = lookup_chardev_class(this->dev_id.device_class);
176   if (NULL == chardev)                            176   if (NULL == chardev)
177     return -SOS_ENODEV;                           177     return -SOS_ENODEV;
178                                                   178 
179   /* Alloocate the new "open file" description    179   /* Alloocate the new "open file" description structure */
180   chardev_of = (struct sos_chardev_opened_file    180   chardev_of = (struct sos_chardev_opened_file*)
181     sos_kmalloc(sizeof(struct sos_chardev_open    181     sos_kmalloc(sizeof(struct sos_chardev_opened_file), 0);
182   if (NULL == chardev_of)                         182   if (NULL == chardev_of)
183     return -SOS_ENOMEM;                           183     return -SOS_ENOMEM;
184                                                   184 
185   memset(chardev_of, 0x0, sizeof(struct sos_ch    185   memset(chardev_of, 0x0, sizeof(struct sos_chardev_opened_file));
186   chardev_of->class = chardev;                    186   chardev_of->class = chardev;
187   *result_of = & chardev_of->super;               187   *result_of = & chardev_of->super;
188                                                   188 
189   /* Increase the reference coount for that no    189   /* Increase the reference coount for that node */
190   SOS_ASSERT_FATAL(chardev->ref_cnt >= 1);        190   SOS_ASSERT_FATAL(chardev->ref_cnt >= 1);
191   chardev->ref_cnt ++;                            191   chardev->ref_cnt ++;
192                                                   192 
193   /* Initialize the read/write/seek callbacks     193   /* Initialize the read/write/seek callbacks */
194   (*result_of)->owner       = owner;              194   (*result_of)->owner       = owner;
195   (*result_of)->open_flags  = open_flags;         195   (*result_of)->open_flags  = open_flags;
196   (*result_of)->ops_file    = & chardev_ops_op    196   (*result_of)->ops_file    = & chardev_ops_opened_file;
197   (*result_of)->ops_chardev = & chardev_ops_op    197   (*result_of)->ops_chardev = & chardev_ops_opened_chardev;
198                                                   198 
199   /* Call the open callback */                    199   /* Call the open callback */
200   retval = chardev->ops->open(this, & chardev_    200   retval = chardev->ops->open(this, & chardev_of->super, chardev->custom_data);
201   if (SOS_OK != retval)                           201   if (SOS_OK != retval)
202     {                                             202     {
203       sos_kfree((sos_vaddr_t) chardev_of);        203       sos_kfree((sos_vaddr_t) chardev_of);
204       chardev->ref_cnt --;                        204       chardev->ref_cnt --;
205       *result_of = NULL;                          205       *result_of = NULL;
206       return retval;                              206       return retval;
207     }                                             207     }
208                                                   208 
209   /* Specify the duplicate method */              209   /* Specify the duplicate method */
210   (*result_of)->duplicate = duplicate_opened_c    210   (*result_of)->duplicate = duplicate_opened_chardev;
211                                                   211 
212   return retval;                                  212   return retval;
213 }                                                 213 }
214                                                   214 
215                                                   215 
216 /** Callback called each time an opened file i    216 /** Callback called each time an opened file is closed. Un-allocate
217     the associated sos_chardev_opened_file obj    217     the associated sos_chardev_opened_file object */
218 static sos_ret_t                                  218 static sos_ret_t
219 chardev_helper_close_opened_file(struct sos_fs    219 chardev_helper_close_opened_file(struct sos_fs_node * this,
220                                  struct sos_fs    220                                  struct sos_fs_opened_file * of)
221 {                                                 221 {
222   sos_ret_t retval;                               222   sos_ret_t retval;
223   struct sos_chardev_opened_file *chardev_of      223   struct sos_chardev_opened_file *chardev_of
224     = ((struct sos_chardev_opened_file*)of);      224     = ((struct sos_chardev_opened_file*)of);
225                                                   225 
226   struct sos_chardev_class * chardev = chardev    226   struct sos_chardev_class * chardev = chardev_of->class;
227   SOS_ASSERT_FATAL(NULL != chardev);              227   SOS_ASSERT_FATAL(NULL != chardev);
228                                                   228 
229   /* Free the new "open file" description stru    229   /* Free the new "open file" description structure */
230   if (NULL != chardev->ops->close)                230   if (NULL != chardev->ops->close)
231     retval = chardev->ops->close(& chardev_of-    231     retval = chardev->ops->close(& chardev_of->super, chardev->custom_data);
232   else                                            232   else
233     retval = SOS_OK;                              233     retval = SOS_OK;
234   if (SOS_OK != retval)                           234   if (SOS_OK != retval)
235     return retval;                                235     return retval;
236                                                   236 
237   /* Decrease the reference coount for that no    237   /* Decrease the reference coount for that node */
238   SOS_ASSERT_FATAL(chardev->ref_cnt > 1);         238   SOS_ASSERT_FATAL(chardev->ref_cnt > 1);
239   chardev->ref_cnt --;                            239   chardev->ref_cnt --;
240                                                   240   
241   sos_kfree((sos_vaddr_t) chardev_of);            241   sos_kfree((sos_vaddr_t) chardev_of);
242   return retval;                                  242   return retval;
243 }                                                 243 }
244                                                   244 
245                                                   245 
246 /**                                               246 /**
247  * Callback called each time a process is "for    247  * Callback called each time a process is "forked": create a new
248  * sos_chardev_opened_file for the new process    248  * sos_chardev_opened_file for the new process.
249  *                                                249  *
250  * @note Almost identical to the open callback    250  * @note Almost identical to the open callback.
251  */                                               251  */
252 static sos_ret_t                                  252 static sos_ret_t
253 duplicate_opened_chardev(struct sos_fs_opened_    253 duplicate_opened_chardev(struct sos_fs_opened_file *this,
254                          const struct sos_proc    254                          const struct sos_process  * for_owner,
255                          struct sos_fs_opened_    255                          struct sos_fs_opened_file **result)
256 {                                                 256 {
257   sos_ret_t retval;                               257   sos_ret_t retval;
258   struct sos_chardev_opened_file *chardev_of      258   struct sos_chardev_opened_file *chardev_of
259     = ((struct sos_chardev_opened_file*)this);    259     = ((struct sos_chardev_opened_file*)this);
260   struct sos_chardev_opened_file *new_chardev_    260   struct sos_chardev_opened_file *new_chardev_of;
261   struct sos_fs_node * fsnode = sos_fs_nscache    261   struct sos_fs_node * fsnode = sos_fs_nscache_get_fs_node(this->direntry);
262                                                   262 
263   *result = NULL;                                 263   *result = NULL;
264                                                   264 
265   /* Lookup the character device description s    265   /* Lookup the character device description structure */
266   struct sos_chardev_class * chardev = chardev    266   struct sos_chardev_class * chardev = chardev_of->class;
267   SOS_ASSERT_FATAL(NULL != chardev);              267   SOS_ASSERT_FATAL(NULL != chardev);
268                                                   268 
269   /* Allocate a new duplicate copy of the orig    269   /* Allocate a new duplicate copy of the original opened file */
270   new_chardev_of = (struct sos_chardev_opened_    270   new_chardev_of = (struct sos_chardev_opened_file*)
271     sos_kmalloc(sizeof(struct sos_chardev_open    271     sos_kmalloc(sizeof(struct sos_chardev_opened_file), 0);
272   if (NULL == new_chardev_of)                     272   if (NULL == new_chardev_of)
273     return -SOS_ENOMEM;                           273     return -SOS_ENOMEM;
274                                                   274 
275   memcpy(new_chardev_of, chardev_of, sizeof(*n    275   memcpy(new_chardev_of, chardev_of, sizeof(*new_chardev_of));
276   new_chardev_of->super.owner    = for_owner;     276   new_chardev_of->super.owner    = for_owner;
277   new_chardev_of->super.direntry = NULL; /* Re    277   new_chardev_of->super.direntry = NULL; /* Reset the direntry
278                                             fo    278                                             for the new opened file */
279   SOS_ASSERT_FATAL(chardev->ref_cnt > 1);         279   SOS_ASSERT_FATAL(chardev->ref_cnt > 1);
280   chardev->ref_cnt ++;                            280   chardev->ref_cnt ++;
281                                                   281 
282   retval = chardev->ops->open(fsnode,             282   retval = chardev->ops->open(fsnode,
283                               & new_chardev_of    283                               & new_chardev_of->super, chardev->custom_data);
284   if (SOS_OK != retval)                           284   if (SOS_OK != retval)
285     {                                             285     {
286       sos_kfree((sos_vaddr_t) new_chardev_of);    286       sos_kfree((sos_vaddr_t) new_chardev_of);
287       chardev->ref_cnt --;                        287       chardev->ref_cnt --;
288       return retval;                              288       return retval;
289     }                                             289     }
290                                                   290 
291   /* Make sure the required methods are overlo    291   /* Make sure the required methods are overloaded */
292   SOS_ASSERT_FATAL(NULL != new_chardev_of->sup    292   SOS_ASSERT_FATAL(NULL != new_chardev_of->super.ops_file);
293   SOS_ASSERT_FATAL(NULL != new_chardev_of->sup    293   SOS_ASSERT_FATAL(NULL != new_chardev_of->super.ops_file->seek);
294   SOS_ASSERT_FATAL(NULL != new_chardev_of->sup    294   SOS_ASSERT_FATAL(NULL != new_chardev_of->super.ops_file->read);
295                                                   295 
296   *result = & new_chardev_of->super;              296   *result = & new_chardev_of->super;
297   return retval;                                  297   return retval;
298 }                                                 298 }
299                                                   299 
300                                                   300 
301 /*                                                301 /*
302  * FS generic character device wrapper functio    302  * FS generic character device wrapper functions
303  */                                               303  */
304                                                   304 
305 /**                                               305 /**
306  * Callback called to change the position in t    306  * Callback called to change the position in the opened file: call the
307  * seek method of the device driver.              307  * seek method of the device driver.
308  */                                               308  */
309 static sos_ret_t chardev_wrap_seek(struct sos_    309 static sos_ret_t chardev_wrap_seek(struct sos_fs_opened_file *this,
310                                    sos_lsoffse    310                                    sos_lsoffset_t offset,
311                                    sos_seek_wh    311                                    sos_seek_whence_t whence,
312                                    /* out */ s    312                                    /* out */ sos_lsoffset_t * result_position)
313 {                                                 313 {
314   sos_ret_t retval = -SOS_ENOSYS;                 314   sos_ret_t retval = -SOS_ENOSYS;
315   struct sos_chardev_opened_file *chardev_of      315   struct sos_chardev_opened_file *chardev_of
316     = ((struct sos_chardev_opened_file*)this);    316     = ((struct sos_chardev_opened_file*)this);
317                                                   317 
318   struct sos_chardev_class * chardev = chardev    318   struct sos_chardev_class * chardev = chardev_of->class;
319   SOS_ASSERT_FATAL(NULL != chardev);              319   SOS_ASSERT_FATAL(NULL != chardev);
320   SOS_ASSERT_FATAL(NULL != chardev->ops);         320   SOS_ASSERT_FATAL(NULL != chardev->ops);
321                                                   321 
322   if (NULL != chardev->ops->seek)                 322   if (NULL != chardev->ops->seek)
323     retval = chardev->ops->seek(this, offset,     323     retval = chardev->ops->seek(this, offset, whence, result_position);
324                                                   324   
325   return retval;                                  325   return retval;
326 }                                                 326 }
327                                                   327 
328                                                   328 
329 /**                                               329 /**
330  * Callback called to read the contents of the    330  * Callback called to read the contents of the opened file: call the
331  * read method of the device driver.              331  * read method of the device driver.
332  */                                               332  */
333 static sos_ret_t chardev_wrap_read(struct sos_    333 static sos_ret_t chardev_wrap_read(struct sos_fs_opened_file *this,
334                                    sos_uaddr_t    334                                    sos_uaddr_t dest_buf,
335                                    sos_size_t     335                                    sos_size_t * /* in/out */len)
336 {                                                 336 {
337   sos_ret_t retval = -SOS_ENOSYS;                 337   sos_ret_t retval = -SOS_ENOSYS;
338   struct sos_chardev_opened_file *chardev_of      338   struct sos_chardev_opened_file *chardev_of
339     = ((struct sos_chardev_opened_file*)this);    339     = ((struct sos_chardev_opened_file*)this);
340                                                   340 
341   struct sos_chardev_class * chardev = chardev    341   struct sos_chardev_class * chardev = chardev_of->class;
342   SOS_ASSERT_FATAL(NULL != chardev);              342   SOS_ASSERT_FATAL(NULL != chardev);
343   SOS_ASSERT_FATAL(NULL != chardev->ops);         343   SOS_ASSERT_FATAL(NULL != chardev->ops);
344                                                   344 
345   if (NULL != chardev->ops->read)                 345   if (NULL != chardev->ops->read)
346     retval = chardev->ops->read(this, dest_buf    346     retval = chardev->ops->read(this, dest_buf, len);
347                                                   347   
348   return retval;                                  348   return retval;
349 }                                                 349 }
350                                                   350 
351                                                   351 
352 /**                                               352 /**
353  * Callback called to write bytes to the opene    353  * Callback called to write bytes to the opened file: call the write
354  * method of the device driver.                   354  * method of the device driver.
355  */                                               355  */
356 static sos_ret_t chardev_wrap_write(struct sos    356 static sos_ret_t chardev_wrap_write(struct sos_fs_opened_file *this,
357                                     sos_uaddr_    357                                     sos_uaddr_t src_buf,
358                                     sos_size_t    358                                     sos_size_t * /* in/out */len)
359 {                                                 359 {
360   sos_ret_t retval = -SOS_ENOSYS;                 360   sos_ret_t retval = -SOS_ENOSYS;
361   struct sos_chardev_opened_file *chardev_of      361   struct sos_chardev_opened_file *chardev_of
362     = ((struct sos_chardev_opened_file*)this);    362     = ((struct sos_chardev_opened_file*)this);
363                                                   363 
364   struct sos_chardev_class * chardev = chardev    364   struct sos_chardev_class * chardev = chardev_of->class;
365   SOS_ASSERT_FATAL(NULL != chardev);              365   SOS_ASSERT_FATAL(NULL != chardev);
366   SOS_ASSERT_FATAL(NULL != chardev->ops);         366   SOS_ASSERT_FATAL(NULL != chardev->ops);
367                                                   367 
368   if (NULL != chardev->ops->write)                368   if (NULL != chardev->ops->write)
369     retval = chardev->ops->write(this, src_buf    369     retval = chardev->ops->write(this, src_buf, len);
370                                                   370   
371   return retval;                                  371   return retval;
372 }                                                 372 }
373                                                   373 
374                                                   374 
375 /**                                               375 /**
376  * Callback called to map the contents of the     376  * Callback called to map the contents of the opened file: call the
377  * map method of the device driver.               377  * map method of the device driver.
378  */                                               378  */
379 static sos_ret_t chardev_wrap_mmap(struct sos_    379 static sos_ret_t chardev_wrap_mmap(struct sos_fs_opened_file *this,
380                                    sos_uaddr_t    380                                    sos_uaddr_t *uaddr, sos_size_t size,
381                                    sos_ui32_t     381                                    sos_ui32_t access_rights,
382                                    sos_ui32_t     382                                    sos_ui32_t flags,
383                                    sos_luoffse    383                                    sos_luoffset_t offset)
384 {                                                 384 {
385   sos_ret_t retval = -SOS_ENOSYS;                 385   sos_ret_t retval = -SOS_ENOSYS;
386   struct sos_chardev_opened_file *chardev_of      386   struct sos_chardev_opened_file *chardev_of
387     = ((struct sos_chardev_opened_file*)this);    387     = ((struct sos_chardev_opened_file*)this);
388                                                   388 
389   struct sos_chardev_class * chardev = chardev    389   struct sos_chardev_class * chardev = chardev_of->class;
390   SOS_ASSERT_FATAL(NULL != chardev);              390   SOS_ASSERT_FATAL(NULL != chardev);
391   SOS_ASSERT_FATAL(NULL != chardev->ops);         391   SOS_ASSERT_FATAL(NULL != chardev->ops);
392                                                   392 
393   if (NULL != chardev->ops->mmap)                 393   if (NULL != chardev->ops->mmap)
394     retval = chardev->ops->mmap(this, uaddr, s    394     retval = chardev->ops->mmap(this, uaddr, size,
395                                 access_rights,    395                                 access_rights, flags, offset);
396                                                   396   
397   return retval;                                  397   return retval;
398 }                                                 398 }
399                                                   399 
400                                                   400 
401 /**                                               401 /**
402  * Callback called to change the state of the     402  * Callback called to change the state of the opened file: call the
403  * fcntl method of the device driver.             403  * fcntl method of the device driver.
404  */                                               404  */
405 static sos_ret_t chardev_wrap_fcntl(struct sos    405 static sos_ret_t chardev_wrap_fcntl(struct sos_fs_opened_file *this,
406                                     int req_id    406                                     int req_id,
407                                     sos_ui32_t    407                                     sos_ui32_t req_arg)
408 {                                                 408 {
409   sos_ret_t retval = -SOS_ENOSYS;                 409   sos_ret_t retval = -SOS_ENOSYS;
410   struct sos_chardev_opened_file *chardev_of      410   struct sos_chardev_opened_file *chardev_of
411     = ((struct sos_chardev_opened_file*)this);    411     = ((struct sos_chardev_opened_file*)this);
412                                                   412 
413   struct sos_chardev_class * chardev = chardev    413   struct sos_chardev_class * chardev = chardev_of->class;
414   SOS_ASSERT_FATAL(NULL != chardev);              414   SOS_ASSERT_FATAL(NULL != chardev);
415   SOS_ASSERT_FATAL(NULL != chardev->ops);         415   SOS_ASSERT_FATAL(NULL != chardev->ops);
416                                                   416 
417   if (NULL != chardev->ops->fcntl)                417   if (NULL != chardev->ops->fcntl)
418     retval = chardev->ops->fcntl(this, req_id,    418     retval = chardev->ops->fcntl(this, req_id, req_arg);
419                                                   419   
420   return retval;                                  420   return retval;
421 }                                                 421 }
422                                                   422 
423                                                   423 
424 /**                                               424 /**
425  * Callback called to control the underlying d    425  * Callback called to control the underlying device: call the ioctl
426  * method of the device driver.                   426  * method of the device driver.
427  */                                               427  */
428 static sos_ret_t chardev_wrap_ioctl(struct sos    428 static sos_ret_t chardev_wrap_ioctl(struct sos_fs_opened_file *this,
429                                     int req_id    429                                     int req_id,
430                                     sos_ui32_t    430                                     sos_ui32_t req_arg)
431 {                                                 431 {
432   sos_ret_t retval = -SOS_ENOSYS;                 432   sos_ret_t retval = -SOS_ENOSYS;
433   struct sos_chardev_opened_file *chardev_of      433   struct sos_chardev_opened_file *chardev_of
434     = ((struct sos_chardev_opened_file*)this);    434     = ((struct sos_chardev_opened_file*)this);
435                                                   435 
436   struct sos_chardev_class * chardev = chardev    436   struct sos_chardev_class * chardev = chardev_of->class;
437   SOS_ASSERT_FATAL(NULL != chardev);              437   SOS_ASSERT_FATAL(NULL != chardev);
438   SOS_ASSERT_FATAL(NULL != chardev->ops);         438   SOS_ASSERT_FATAL(NULL != chardev->ops);
439                                                   439 
440   if (NULL != chardev->ops->ioctl)                440   if (NULL != chardev->ops->ioctl)
441     retval = chardev->ops->ioctl(this, req_id,    441     retval = chardev->ops->ioctl(this, req_id, req_arg);
442                                                   442   
443   return retval;                                  443   return retval;
444 }                                                 444 }
445                                                   445 
446                                                   446 
447 /**                                               447 /**
448  * Gather the callbacks for a "character devic    448  * Gather the callbacks for a "character device" opened file
449  */                                               449  */
450 static struct sos_fs_ops_opened_file chardev_o    450 static struct sos_fs_ops_opened_file chardev_ops_opened_file
451   = (struct sos_fs_ops_opened_file) {             451   = (struct sos_fs_ops_opened_file) {
452     .seek  = chardev_wrap_seek,                   452     .seek  = chardev_wrap_seek,
453     .read  = chardev_wrap_read,                   453     .read  = chardev_wrap_read,
454     .write = chardev_wrap_write,                  454     .write = chardev_wrap_write,
455     .mmap  = chardev_wrap_mmap,                   455     .mmap  = chardev_wrap_mmap,
456     .fcntl = chardev_wrap_fcntl                   456     .fcntl = chardev_wrap_fcntl
457   };                                              457   };
458                                                   458 
459                                                   459 
460 static struct sos_fs_ops_opened_chardev charde    460 static struct sos_fs_ops_opened_chardev chardev_ops_opened_chardev
461   = (struct sos_fs_ops_opened_chardev) {          461   = (struct sos_fs_ops_opened_chardev) {
462     .ioctl = chardev_wrap_ioctl                   462     .ioctl = chardev_wrap_ioctl
463   };                                              463   };
                                                      

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