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) and /sos/chardev.c (Article 9.5)


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

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