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