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 /drivers/zero.c (Article 9.5) and /drivers/zero.c (Article 8)


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/kmalloc.h>                          020 #include <sos/kmalloc.h>
021 #include <sos/physmem.h>                          021 #include <sos/physmem.h>
022 #include <hwcore/paging.h>                        022 #include <hwcore/paging.h>
023 #include <sos/kmem_slab.h>                        023 #include <sos/kmem_slab.h>
024 #include <sos/list.h>                             024 #include <sos/list.h>
025 #include <hwcore/paging.h>                        025 #include <hwcore/paging.h>
026 #include <sos/uaccess.h>                       << 
027 #include <sos/chardev.h>                       << 
028 #include <drivers/devices.h>                   << 
029                                                   026 
030 #include "zero.h"                                 027 #include "zero.h"
031                                                   028 
032                                                   029 
033 /**                                               030 /**
034  * A mapped page for a shared mapping of /dev/    031  * A mapped page for a shared mapping of /dev/zero
035  */                                               032  */
036 struct zero_mapped_page                           033 struct zero_mapped_page
037 {                                                 034 {
038   sos_uoffset_t page_id;                          035   sos_uoffset_t page_id;
039   sos_paddr_t   ppage_paddr;                      036   sos_paddr_t   ppage_paddr;
040                                                   037 
041   struct zero_mapped_page *prev, *next;           038   struct zero_mapped_page *prev, *next;
042 };                                                039 };
043 /** The Slab cache of shared mapped pages */      040 /** The Slab cache of shared mapped pages */
044 struct sos_kslab_cache * cache_of_zero_mapped_    041 struct sos_kslab_cache * cache_of_zero_mapped_pages;
045                                                   042 
046                                                   043 
047 /**                                               044 /**
048  * A mapped /dev/zero resource                    045  * A mapped /dev/zero resource
049  */                                               046  */
050 struct zero_mapped_resource                       047 struct zero_mapped_resource
051 {                                                 048 {
052   int ref_cnt;                                    049   int ref_cnt;
053                                                   050 
054   /**                                             051   /**
055    * For shared mappings: the list of shared p    052    * For shared mappings: the list of shared pages mapped inside one
056    * or multiple VRs                              053    * or multiple VRs
057    */                                             054    */
058   struct zero_mapped_page *list_mapped_pages;     055   struct zero_mapped_page *list_mapped_pages;
059                                                   056 
060   struct sos_umem_vmm_mapped_resource mr;         057   struct sos_umem_vmm_mapped_resource mr;
061 };                                                058 };
062                                                   059 
063                                                   060 
064 /** Forward declaration: the FS operation for  << 
065     device */                                  << 
066 static struct sos_chardev_ops dev_zero_fs_ops; << 
067                                                << 
068                                                << 
069 /** Helper function to insert the given physic    061 /** Helper function to insert the given physical page in the list of
070     physical pages used for shared anonymous m    062     physical pages used for shared anonymous mappings */
071 static sos_ret_t insert_anonymous_physpage(str    063 static sos_ret_t insert_anonymous_physpage(struct zero_mapped_resource *mr,
072                                            sos    064                                            sos_paddr_t ppage_paddr,
073                                            sos    065                                            sos_uoffset_t page_id);
074                                                   066 
075                                                   067 
076 /** Helper function to insert the given physic    068 /** Helper function to insert the given physical page in the list of
077     physical pages used for shared anonymous m    069     physical pages used for shared anonymous mappings */
078 static sos_paddr_t lookup_anonymous_physpage(s    070 static sos_paddr_t lookup_anonymous_physpage(struct zero_mapped_resource *mr,
079                                              s    071                                              sos_uoffset_t page_id);
080                                                   072 
081                                                   073 
082 sos_ret_t sos_dev_zero_subsystem_setup()          074 sos_ret_t sos_dev_zero_subsystem_setup()
083 {                                                 075 {
084   sos_ret_t retval;                            << 
085                                                << 
086   cache_of_zero_mapped_pages =                    076   cache_of_zero_mapped_pages =
087     sos_kmem_cache_create("shared anonymous ma    077     sos_kmem_cache_create("shared anonymous mappings",
088                           sizeof(struct zero_m    078                           sizeof(struct zero_mapped_page),
089                           1, 0,                   079                           1, 0,
090                           SOS_KSLAB_CREATE_MAP    080                           SOS_KSLAB_CREATE_MAP | SOS_KSLAB_CREATE_ZERO);
091   if (! cache_of_zero_mapped_pages)               081   if (! cache_of_zero_mapped_pages)
092     return -SOS_ENOMEM;                           082     return -SOS_ENOMEM;
093                                                   083 
094   retval = sos_chardev_register_class(SOS_CHAR << 
095                                       & dev_ze << 
096                                       NULL);   << 
097   if (SOS_OK != retval)                        << 
098     {                                          << 
099       sos_kmem_cache_destroy(cache_of_zero_map << 
100       return retval;                           << 
101     }                                          << 
102                                                << 
103   return SOS_OK;                                  084   return SOS_OK;
104 }                                                 085 }
105                                                   086 
106                                                   087 
107 /** Called after the virtual region has been i    088 /** Called after the virtual region has been inserted inside its
108     address space */                              089     address space */
109 static void zero_ref(struct sos_umem_vmm_vr *     090 static void zero_ref(struct sos_umem_vmm_vr * vr)
110 {                                                 091 {
111   /* Retrieve the 'zero' structure associated     092   /* Retrieve the 'zero' structure associated with the mapped resource */
112   struct zero_mapped_resource * zero_resource;    093   struct zero_mapped_resource * zero_resource;
113   zero_resource                                   094   zero_resource
114     = (struct zero_mapped_resource*)              095     = (struct zero_mapped_resource*)
115     sos_umem_vmm_get_mapped_resource_of_vr(vr)    096     sos_umem_vmm_get_mapped_resource_of_vr(vr)->custom_data;
116                                                   097   
117   /* Increment ref counter */                     098   /* Increment ref counter */
118   zero_resource->ref_cnt ++;                      099   zero_resource->ref_cnt ++;
119 }                                                 100 }
120                                                   101 
121                                                   102 
122 /** Called when the virtual region is removed     103 /** Called when the virtual region is removed from its address
123     space */                                      104     space */
124 static void zero_unref(struct sos_umem_vmm_vr     105 static void zero_unref(struct sos_umem_vmm_vr * vr)
125 {                                                 106 {
126   /* Retrieve the 'zero' structure associated     107   /* Retrieve the 'zero' structure associated with the mapped resource */
127   struct zero_mapped_resource * zero_resource;    108   struct zero_mapped_resource * zero_resource;
128   zero_resource                                   109   zero_resource
129     = (struct zero_mapped_resource*)              110     = (struct zero_mapped_resource*)
130     sos_umem_vmm_get_mapped_resource_of_vr(vr)    111     sos_umem_vmm_get_mapped_resource_of_vr(vr)->custom_data;
131                                                   112 
132   /* Decrement ref coutner */                     113   /* Decrement ref coutner */
133   SOS_ASSERT_FATAL(zero_resource->ref_cnt > 0)    114   SOS_ASSERT_FATAL(zero_resource->ref_cnt > 0);
134   zero_resource->ref_cnt --;                      115   zero_resource->ref_cnt --;
135                                                   116 
136   /* Free the resource if it becomes unused */    117   /* Free the resource if it becomes unused */
137   if (zero_resource->ref_cnt == 0)                118   if (zero_resource->ref_cnt == 0)
138     {                                             119     {
139       /* Delete the list of anonymous shared m    120       /* Delete the list of anonymous shared mappings */
140       struct zero_mapped_page *zmp;               121       struct zero_mapped_page *zmp;
141       list_collapse(zero_resource->list_mapped    122       list_collapse(zero_resource->list_mapped_pages, zmp)
142         {                                         123         {
143           /* Unreference the underlying physic    124           /* Unreference the underlying physical page */
144           sos_physmem_unref_physpage(zmp->ppag    125           sos_physmem_unref_physpage(zmp->ppage_paddr);
145           sos_kfree((sos_vaddr_t)zmp);            126           sos_kfree((sos_vaddr_t)zmp);
146         }                                         127         }
147                                                   128 
148       sos_kfree((sos_vaddr_t)zero_resource);      129       sos_kfree((sos_vaddr_t)zero_resource);
149     }                                             130     }
150 }                                                 131 }
151                                                   132 
152                                                   133 
153 /** MOST IMPORTANT callback ! Called when a th    134 /** MOST IMPORTANT callback ! Called when a thread page faults on the
154     resource's mapping */                         135     resource's mapping */
155 static sos_ret_t zero_page_in(struct sos_umem_    136 static sos_ret_t zero_page_in(struct sos_umem_vmm_vr * vr,
156                               sos_uaddr_t uadd    137                               sos_uaddr_t uaddr,
157                               sos_bool_t write    138                               sos_bool_t write_access)
158 {                                                 139 {
159   sos_ret_t retval = SOS_OK;                      140   sos_ret_t retval = SOS_OK;
160   sos_paddr_t ppage_paddr;                        141   sos_paddr_t ppage_paddr;
161   sos_uoffset_t required_page_id;                 142   sos_uoffset_t required_page_id;
162   struct zero_mapped_resource * zero_resource;    143   struct zero_mapped_resource * zero_resource;
163   sos_ui32_t vr_prot, vr_flags;                   144   sos_ui32_t vr_prot, vr_flags;
164                                                   145 
165   /* Retrieve the 'zero' structure associated     146   /* Retrieve the 'zero' structure associated with the mapped resource */
166   zero_resource                                   147   zero_resource
167     = (struct zero_mapped_resource*)              148     = (struct zero_mapped_resource*)
168     sos_umem_vmm_get_mapped_resource_of_vr(vr)    149     sos_umem_vmm_get_mapped_resource_of_vr(vr)->custom_data;
169                                                   150 
170   /* Retrieve access rights/flags of the VR */    151   /* Retrieve access rights/flags of the VR */
171   vr_prot  = sos_umem_vmm_get_prot_of_vr(vr);     152   vr_prot  = sos_umem_vmm_get_prot_of_vr(vr);
172   vr_flags = sos_umem_vmm_get_flags_of_vr(vr);    153   vr_flags = sos_umem_vmm_get_flags_of_vr(vr);
173                                                   154 
174   /* Identifies the page in the mapping that's    155   /* Identifies the page in the mapping that's being paged-in */
175   required_page_id = SOS_PAGE_ALIGN_INF(uaddr)    156   required_page_id = SOS_PAGE_ALIGN_INF(uaddr)
176     - sos_umem_vmm_get_start_of_vr(vr)            157     - sos_umem_vmm_get_start_of_vr(vr)
177     + sos_umem_vmm_get_offset_in_resource(vr);    158     + sos_umem_vmm_get_offset_in_resource(vr);
178                                                   159 
179   /* For shared mappings, check if there is a     160   /* For shared mappings, check if there is a page already mapping the
180      required address */                          161      required address */
181   if (vr_flags & SOS_VR_MAP_SHARED)               162   if (vr_flags & SOS_VR_MAP_SHARED)
182     {                                             163     {
183       ppage_paddr = lookup_anonymous_physpage(    164       ppage_paddr = lookup_anonymous_physpage(zero_resource, required_page_id);
184       if (NULL != (void*)ppage_paddr)             165       if (NULL != (void*)ppage_paddr)
185         {                                         166         {
186           retval = sos_paging_map(ppage_paddr,    167           retval = sos_paging_map(ppage_paddr,
187                                   SOS_PAGE_ALI    168                                   SOS_PAGE_ALIGN_INF(uaddr),
188                                   TRUE,           169                                   TRUE,
189                                   vr_prot);       170                                   vr_prot);
190                                                   171 
191           return retval;                          172           return retval;
192         }                                         173         }
193     }                                             174     }
194                                                   175 
195   /* For write accesses, directly maps a new p    176   /* For write accesses, directly maps a new page. For read accesses,
196      simply map in the zero_page (and wait for    177      simply map in the zero_page (and wait for COW to handle the next
197      write accesses) */                           178      write accesses) */
198   if (write_access)                               179   if (write_access)
199     {                                             180     {
200       /* Allocate a new page for the virtual a    181       /* Allocate a new page for the virtual address */
201       ppage_paddr = sos_physmem_ref_physpage_n    182       ppage_paddr = sos_physmem_ref_physpage_new(FALSE);
202       if (! ppage_paddr)                          183       if (! ppage_paddr)
203         return -SOS_ENOMEM;                       184         return -SOS_ENOMEM;
204                                                   185 
205       retval = sos_paging_map(ppage_paddr,        186       retval = sos_paging_map(ppage_paddr,
206                               SOS_PAGE_ALIGN_I    187                               SOS_PAGE_ALIGN_INF(uaddr),
207                               TRUE,               188                               TRUE,
208                               vr_prot);           189                               vr_prot);
209       if (SOS_OK != retval)                       190       if (SOS_OK != retval)
210         {                                         191         {
211           sos_physmem_unref_physpage(ppage_pad    192           sos_physmem_unref_physpage(ppage_paddr);
212           return retval;                          193           return retval;
213         }                                         194         }
214                                                   195       
215       memset((void*)SOS_PAGE_ALIGN_INF(uaddr),    196       memset((void*)SOS_PAGE_ALIGN_INF(uaddr), 0x0, SOS_PAGE_SIZE);
216                                                   197 
217       /* For shared mappings, add the page in     198       /* For shared mappings, add the page in the list of shared
218          mapped pages */                          199          mapped pages */
219       if (vr_flags & SOS_VR_MAP_SHARED)           200       if (vr_flags & SOS_VR_MAP_SHARED)
220         insert_anonymous_physpage(zero_resourc    201         insert_anonymous_physpage(zero_resource, ppage_paddr,
221                                   required_pag    202                                   required_page_id);
222                                                   203 
223       sos_physmem_unref_physpage(ppage_paddr);    204       sos_physmem_unref_physpage(ppage_paddr);
224     }                                             205     }
225   else                                            206   else
226     {                                             207     {
227       /* Map-in the zero page in READ ONLY wha    208       /* Map-in the zero page in READ ONLY whatever the access_rights
228          or the type (shared/private) of the V    209          or the type (shared/private) of the VR to activate COW */
229       retval = sos_paging_map(sos_zero_physpag !! 210       retval = sos_paging_map(sos_zero_page,
230                               SOS_PAGE_ALIGN_I    211                               SOS_PAGE_ALIGN_INF(uaddr),
231                               TRUE,               212                               TRUE,
232                               SOS_VM_MAP_PROT_    213                               SOS_VM_MAP_PROT_READ);
233     }                                             214     }
234                                                   215 
235   return retval;                                  216   return retval;
236 }                                                 217 }
237                                                   218 
238                                                   219 
239 /** The callbacks for a mapped /dev/zero resou    220 /** The callbacks for a mapped /dev/zero resource */
240 static struct sos_umem_vmm_vr_ops zero_ops = (    221 static struct sos_umem_vmm_vr_ops zero_ops = (struct sos_umem_vmm_vr_ops)
241 {                                                 222 {
242   .ref     = zero_ref,                            223   .ref     = zero_ref,
243   .unref   = zero_unref,                          224   .unref   = zero_unref,
244   .page_in = zero_page_in,                        225   .page_in = zero_page_in,
245   .unmap   = NULL                                 226   .unmap   = NULL
246 };                                                227 };
247                                                   228 
248                                                   229 
249 /** The callback that gets called when the res    230 /** The callback that gets called when the resource gets mapped */
250 static sos_ret_t zero_mmap(struct sos_umem_vmm    231 static sos_ret_t zero_mmap(struct sos_umem_vmm_vr *vr)
251 {                                                 232 {
252   return sos_umem_vmm_set_ops_of_vr(vr, &zero_    233   return sos_umem_vmm_set_ops_of_vr(vr, &zero_ops);
253 }                                                 234 }
254                                                   235 
255                                                   236 
256 /** The function responsible for mapping the /    237 /** The function responsible for mapping the /dev/zero resource in
257     user space */                                 238     user space */
258 sos_ret_t sos_dev_zero_map(struct sos_umem_vmm    239 sos_ret_t sos_dev_zero_map(struct sos_umem_vmm_as * dest_as,
259                            sos_uaddr_t *uaddr,    240                            sos_uaddr_t *uaddr,
260                            sos_size_t size,       241                            sos_size_t size,
261                            sos_ui32_t access_r    242                            sos_ui32_t access_rights,
262                            sos_ui32_t flags)      243                            sos_ui32_t flags)
263 {                                                 244 {
264   sos_ret_t retval;                               245   sos_ret_t retval;
265   struct zero_mapped_resource * zero_resource;    246   struct zero_mapped_resource * zero_resource;
266                                                   247 
267   zero_resource                                   248   zero_resource
268     = (struct zero_mapped_resource*) sos_kmall    249     = (struct zero_mapped_resource*) sos_kmalloc(sizeof(*zero_resource), 0);
269   if (! zero_resource)                            250   if (! zero_resource)
270     return -SOS_ENOMEM;                           251     return -SOS_ENOMEM;
271                                                   252 
272   memset(zero_resource, 0x0, sizeof(*zero_reso    253   memset(zero_resource, 0x0, sizeof(*zero_resource));
273   zero_resource->mr.allowed_access_rights         254   zero_resource->mr.allowed_access_rights 
274     = SOS_VM_MAP_PROT_READ                        255     = SOS_VM_MAP_PROT_READ
275     | SOS_VM_MAP_PROT_WRITE                       256     | SOS_VM_MAP_PROT_WRITE
276     | SOS_VM_MAP_PROT_EXEC;                       257     | SOS_VM_MAP_PROT_EXEC;
277   zero_resource->mr.flags         |= SOS_MAPPE    258   zero_resource->mr.flags         |= SOS_MAPPED_RESOURCE_ANONYMOUS;
278   zero_resource->mr.custom_data    = zero_reso    259   zero_resource->mr.custom_data    = zero_resource;
279   zero_resource->mr.mmap           = zero_mmap    260   zero_resource->mr.mmap           = zero_mmap;
280                                                   261 
281   retval = sos_umem_vmm_map(dest_as, uaddr, si    262   retval = sos_umem_vmm_map(dest_as, uaddr, size,
282                             access_rights, fla    263                             access_rights, flags,
283                             &zero_resource->mr    264                             &zero_resource->mr, 0);
284   if (SOS_OK != retval)                           265   if (SOS_OK != retval)
285     {                                             266     {
286       sos_kfree((sos_vaddr_t)zero_resource);      267       sos_kfree((sos_vaddr_t)zero_resource);
287       return retval;                              268       return retval;
288     }                                             269     }
289                                                   270 
290   return SOS_OK;                                  271   return SOS_OK;
291 }                                                 272 }
292                                                   273 
293                                                   274 
294 static sos_ret_t insert_anonymous_physpage(str    275 static sos_ret_t insert_anonymous_physpage(struct zero_mapped_resource *mr,
295                                            sos    276                                            sos_paddr_t ppage_paddr,
296                                            sos    277                                            sos_uoffset_t page_id)
297 {                                                 278 {
298   struct zero_mapped_page * zmp                   279   struct zero_mapped_page * zmp
299     = (struct zero_mapped_page*)sos_kmem_cache    280     = (struct zero_mapped_page*)sos_kmem_cache_alloc(cache_of_zero_mapped_pages,
300                                                   281                                                      0);
301   if (! zmp)                                      282   if (! zmp)
302     return -SOS_ENOMEM;                           283     return -SOS_ENOMEM;
303                                                   284 
304   zmp->page_id     = page_id;                     285   zmp->page_id     = page_id;
305   zmp->ppage_paddr = ppage_paddr;                 286   zmp->ppage_paddr = ppage_paddr;
306                                                   287 
307   list_add_head(mr->list_mapped_pages, zmp);      288   list_add_head(mr->list_mapped_pages, zmp);
308   sos_physmem_ref_physpage_at(ppage_paddr);       289   sos_physmem_ref_physpage_at(ppage_paddr);
309   return SOS_OK;                                  290   return SOS_OK;
310 }                                                 291 }
311                                                   292 
312                                                   293 
313 static sos_paddr_t lookup_anonymous_physpage(s    294 static sos_paddr_t lookup_anonymous_physpage(struct zero_mapped_resource *mr,
314                                              s !! 295                                             sos_uoffset_t page_id)
315 {                                                 296 {
316   struct zero_mapped_page * zmp;                  297   struct zero_mapped_page * zmp;
317   int nb_elts;                                    298   int nb_elts;
318                                                   299 
319   list_foreach_forward(mr->list_mapped_pages,     300   list_foreach_forward(mr->list_mapped_pages, zmp, nb_elts)
320     {                                             301     {
321       if (zmp->page_id == page_id)                302       if (zmp->page_id == page_id)
322         return zmp->ppage_paddr;                  303         return zmp->ppage_paddr;
323     }                                             304     }
324                                                   305   
325   return (sos_paddr_t)NULL;                       306   return (sos_paddr_t)NULL;
326 }                                                 307 }
327                                                << 
328 /*                                             << 
329  * /dev/zero character device FS operations    << 
330  */                                            << 
331                                                << 
332 static sos_ret_t dev_zero_fs_open(struct sos_f << 
333                                   struct sos_f << 
334                                   void * chard << 
335 {                                              << 
336   /* Make sure the device instance is known to << 
337   if ( (SOS_CHARDEV_NULL_MINOR != fsnode->dev_ << 
338        && (SOS_CHARDEV_ZERO_MINOR != fsnode->d << 
339     return -SOS_ENODEV;                        << 
340                                                << 
341   return SOS_OK;                               << 
342 }                                              << 
343                                                << 
344                                                << 
345 static sos_ret_t dev_zero_fs_seek(struct sos_f << 
346                                   sos_lsoffset << 
347                                   sos_seek_whe << 
348                                   /* out */ so << 
349 {                                              << 
350   /* Artificiallly update the position in the  << 
351   sos_lsoffset_t ref_offs;                     << 
352                                                << 
353   *result_position = this->position;           << 
354   switch (whence)                              << 
355     {                                          << 
356     case SOS_SEEK_SET:                         << 
357       ref_offs = 0;                            << 
358       break;                                   << 
359                                                << 
360     case SOS_SEEK_CUR:                         << 
361       ref_offs = this->position;               << 
362       break;                                   << 
363                                                << 
364     case SOS_SEEK_END:                         << 
365       return -SOS_ENOSUP;                      << 
366       break;                                   << 
367                                                << 
368     default:                                   << 
369       return -SOS_EINVAL;                      << 
370     }                                          << 
371                                                << 
372   if (offset < -ref_offs)                      << 
373     return -SOS_EINVAL;                        << 
374                                                << 
375   this->position = ref_offs + offset;          << 
376   *result_position = this->position;           << 
377   return SOS_OK;                               << 
378 }                                              << 
379                                                << 
380                                                << 
381 static sos_ret_t dev_zero_fs_read(struct sos_f << 
382                                   sos_uaddr_t  << 
383                                   sos_size_t * << 
384 {                                              << 
385   struct sos_fs_node * fsnode = sos_fs_nscache << 
386   sos_size_t offs, rdlen;                      << 
387                                                << 
388   /* Reading /dev/null returns immediately */  << 
389   if (SOS_CHARDEV_NULL_MINOR == fsnode->dev_id << 
390     {                                          << 
391       *len = 0;                                << 
392       return SOS_OK;                           << 
393     }                                          << 
394                                                << 
395   /* ZERO the destination buffer using the zer << 
396      increments) */                            << 
397   for (rdlen = offs = 0 ; offs < *len ; offs + << 
398     {                                          << 
399       sos_ret_t retval;                        << 
400       sos_size_t memcpy_len = SOS_PAGE_SIZE;   << 
401       if (offs + memcpy_len > *len)            << 
402         memcpy_len = *len - offs;              << 
403                                                << 
404       retval = sos_memcpy_to_user(dest_buf + o << 
405                                   memcpy_len); << 
406       if (retval < 0)                          << 
407         break;                                 << 
408                                                << 
409       rdlen += retval;                         << 
410       if (retval != (sos_ret_t)memcpy_len)     << 
411         break;                                 << 
412     }                                          << 
413                                                << 
414   /* Artificiallly update the position in the  << 
415   *len = rdlen;                                << 
416   this->position += rdlen;                     << 
417   return SOS_OK;                               << 
418 }                                              << 
419                                                << 
420                                                << 
421 static sos_ret_t dev_zero_fs_write(struct sos_ << 
422                                    sos_uaddr_t << 
423                                    sos_size_t  << 
424 {                                              << 
425   /* Artificiallly update the position in the  << 
426   this->position += *len;                      << 
427   return SOS_OK;                               << 
428 }                                              << 
429                                                << 
430                                                << 
431 static sos_ret_t dev_zero_fs_mmap(struct sos_f << 
432                                   sos_uaddr_t  << 
433                                   sos_ui32_t a << 
434                                   sos_ui32_t f << 
435                                   sos_luoffset << 
436 {                                              << 
437   return sos_dev_zero_map(sos_process_get_addr << 
438                           uaddr, size, access_ << 
439 }                                              << 
440                                                << 
441                                                << 
442 static struct sos_chardev_ops dev_zero_fs_ops  << 
443   = (struct sos_chardev_ops) {                 << 
444     .open  = dev_zero_fs_open,                 << 
445     .close = NULL,                             << 
446     .seek  = dev_zero_fs_seek,                 << 
447     .read  = dev_zero_fs_read,                 << 
448     .write = dev_zero_fs_write,                << 
449     .mmap  = dev_zero_fs_mmap,                 << 
450     .fcntl = NULL,                             << 
451     .ioctl = NULL                              << 
452   };                                           << 
                                                      

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