Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0
2 : /*
3 : * linux/drivers/char/mem.c
4 : *
5 : * Copyright (C) 1991, 1992 Linus Torvalds
6 : *
7 : * Added devfs support.
8 : * Jan-11-1998, C. Scott Ananian <cananian@alumni.princeton.edu>
9 : * Shared /dev/zero mmapping support, Feb 2000, Kanoj Sarcar <kanoj@sgi.com>
10 : */
11 :
12 : #include <linux/mm.h>
13 : #include <linux/miscdevice.h>
14 : #include <linux/slab.h>
15 : #include <linux/vmalloc.h>
16 : #include <linux/mman.h>
17 : #include <linux/random.h>
18 : #include <linux/init.h>
19 : #include <linux/tty.h>
20 : #include <linux/capability.h>
21 : #include <linux/ptrace.h>
22 : #include <linux/device.h>
23 : #include <linux/highmem.h>
24 : #include <linux/backing-dev.h>
25 : #include <linux/shmem_fs.h>
26 : #include <linux/splice.h>
27 : #include <linux/pfn.h>
28 : #include <linux/export.h>
29 : #include <linux/io.h>
30 : #include <linux/uio.h>
31 : #include <linux/uaccess.h>
32 : #include <linux/security.h>
33 :
34 : #ifdef CONFIG_IA64
35 : # include <linux/efi.h>
36 : #endif
37 :
38 : #define DEVMEM_MINOR 1
39 : #define DEVPORT_MINOR 4
40 :
41 : static inline unsigned long size_inside_page(unsigned long start,
42 : unsigned long size)
43 : {
44 : unsigned long sz;
45 :
46 0 : sz = PAGE_SIZE - (start & (PAGE_SIZE - 1));
47 :
48 0 : return min(sz, size);
49 : }
50 :
51 : #ifndef ARCH_HAS_VALID_PHYS_ADDR_RANGE
52 : static inline int valid_phys_addr_range(phys_addr_t addr, size_t count)
53 : {
54 0 : return addr + count <= __pa(high_memory);
55 : }
56 :
57 : static inline int valid_mmap_phys_addr_range(unsigned long pfn, size_t size)
58 : {
59 : return 1;
60 : }
61 : #endif
62 :
63 : #ifdef CONFIG_STRICT_DEVMEM
64 : static inline int page_is_allowed(unsigned long pfn)
65 : {
66 : return devmem_is_allowed(pfn);
67 : }
68 : static inline int range_is_allowed(unsigned long pfn, unsigned long size)
69 : {
70 : u64 from = ((u64)pfn) << PAGE_SHIFT;
71 : u64 to = from + size;
72 : u64 cursor = from;
73 :
74 : while (cursor < to) {
75 : if (!devmem_is_allowed(pfn))
76 : return 0;
77 : cursor += PAGE_SIZE;
78 : pfn++;
79 : }
80 : return 1;
81 : }
82 : #else
83 : static inline int page_is_allowed(unsigned long pfn)
84 : {
85 : return 1;
86 : }
87 : static inline int range_is_allowed(unsigned long pfn, unsigned long size)
88 : {
89 : return 1;
90 : }
91 : #endif
92 :
93 0 : static inline bool should_stop_iteration(void)
94 : {
95 0 : if (need_resched())
96 0 : cond_resched();
97 0 : return signal_pending(current);
98 : }
99 :
100 : /*
101 : * This funcion reads the *physical* memory. The f_pos points directly to the
102 : * memory location.
103 : */
104 0 : static ssize_t read_mem(struct file *file, char __user *buf,
105 : size_t count, loff_t *ppos)
106 : {
107 0 : phys_addr_t p = *ppos;
108 : ssize_t read, sz;
109 : void *ptr;
110 : char *bounce;
111 : int err;
112 :
113 : if (p != *ppos)
114 : return 0;
115 :
116 0 : if (!valid_phys_addr_range(p, count))
117 : return -EFAULT;
118 0 : read = 0;
119 : #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
120 : /* we don't have page 0 mapped on sparc and m68k.. */
121 : if (p < PAGE_SIZE) {
122 : sz = size_inside_page(p, count);
123 : if (sz > 0) {
124 : if (clear_user(buf, sz))
125 : return -EFAULT;
126 : buf += sz;
127 : p += sz;
128 : count -= sz;
129 : read += sz;
130 : }
131 : }
132 : #endif
133 :
134 0 : bounce = kmalloc(PAGE_SIZE, GFP_KERNEL);
135 0 : if (!bounce)
136 : return -ENOMEM;
137 :
138 0 : while (count > 0) {
139 : unsigned long remaining;
140 : int allowed, probe;
141 :
142 0 : sz = size_inside_page(p, count);
143 :
144 0 : err = -EPERM;
145 0 : allowed = page_is_allowed(p >> PAGE_SHIFT);
146 : if (!allowed)
147 : goto failed;
148 :
149 0 : err = -EFAULT;
150 : if (allowed == 2) {
151 : /* Show zeros for restricted memory. */
152 : remaining = clear_user(buf, sz);
153 : } else {
154 : /*
155 : * On ia64 if a page has been mapped somewhere as
156 : * uncached, then it must also be accessed uncached
157 : * by the kernel or data corruption may occur.
158 : */
159 0 : ptr = xlate_dev_mem_ptr(p);
160 0 : if (!ptr)
161 : goto failed;
162 :
163 0 : probe = copy_from_kernel_nofault(bounce, ptr, sz);
164 0 : unxlate_dev_mem_ptr(p, ptr);
165 0 : if (probe)
166 : goto failed;
167 :
168 0 : remaining = copy_to_user(buf, bounce, sz);
169 : }
170 :
171 0 : if (remaining)
172 : goto failed;
173 :
174 0 : buf += sz;
175 0 : p += sz;
176 0 : count -= sz;
177 0 : read += sz;
178 0 : if (should_stop_iteration())
179 : break;
180 : }
181 0 : kfree(bounce);
182 :
183 0 : *ppos += read;
184 0 : return read;
185 :
186 : failed:
187 0 : kfree(bounce);
188 0 : return err;
189 : }
190 :
191 0 : static ssize_t write_mem(struct file *file, const char __user *buf,
192 : size_t count, loff_t *ppos)
193 : {
194 0 : phys_addr_t p = *ppos;
195 : ssize_t written, sz;
196 : unsigned long copied;
197 : void *ptr;
198 :
199 : if (p != *ppos)
200 : return -EFBIG;
201 :
202 0 : if (!valid_phys_addr_range(p, count))
203 : return -EFAULT;
204 :
205 : written = 0;
206 :
207 : #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
208 : /* we don't have page 0 mapped on sparc and m68k.. */
209 : if (p < PAGE_SIZE) {
210 : sz = size_inside_page(p, count);
211 : /* Hmm. Do something? */
212 : buf += sz;
213 : p += sz;
214 : count -= sz;
215 : written += sz;
216 : }
217 : #endif
218 :
219 0 : while (count > 0) {
220 : int allowed;
221 :
222 0 : sz = size_inside_page(p, count);
223 :
224 0 : allowed = page_is_allowed(p >> PAGE_SHIFT);
225 : if (!allowed)
226 : return -EPERM;
227 :
228 : /* Skip actual writing when a page is marked as restricted. */
229 : if (allowed == 1) {
230 : /*
231 : * On ia64 if a page has been mapped somewhere as
232 : * uncached, then it must also be accessed uncached
233 : * by the kernel or data corruption may occur.
234 : */
235 0 : ptr = xlate_dev_mem_ptr(p);
236 0 : if (!ptr) {
237 0 : if (written)
238 : break;
239 : return -EFAULT;
240 : }
241 :
242 0 : copied = copy_from_user(ptr, buf, sz);
243 0 : unxlate_dev_mem_ptr(p, ptr);
244 0 : if (copied) {
245 0 : written += sz - copied;
246 0 : if (written)
247 : break;
248 : return -EFAULT;
249 : }
250 : }
251 :
252 0 : buf += sz;
253 0 : p += sz;
254 0 : count -= sz;
255 0 : written += sz;
256 0 : if (should_stop_iteration())
257 : break;
258 : }
259 :
260 0 : *ppos += written;
261 0 : return written;
262 : }
263 :
264 0 : int __weak phys_mem_access_prot_allowed(struct file *file,
265 : unsigned long pfn, unsigned long size, pgprot_t *vma_prot)
266 : {
267 0 : return 1;
268 : }
269 :
270 : #ifndef __HAVE_PHYS_MEM_ACCESS_PROT
271 :
272 : /*
273 : * Architectures vary in how they handle caching for addresses
274 : * outside of main memory.
275 : *
276 : */
277 : #ifdef pgprot_noncached
278 : static int uncached_access(struct file *file, phys_addr_t addr)
279 : {
280 : #if defined(CONFIG_IA64)
281 : /*
282 : * On ia64, we ignore O_DSYNC because we cannot tolerate memory
283 : * attribute aliases.
284 : */
285 : return !(efi_mem_attributes(addr) & EFI_MEMORY_WB);
286 : #else
287 : /*
288 : * Accessing memory above the top the kernel knows about or through a
289 : * file pointer
290 : * that was marked O_DSYNC will be done non-cached.
291 : */
292 : if (file->f_flags & O_DSYNC)
293 : return 1;
294 : return addr >= __pa(high_memory);
295 : #endif
296 : }
297 : #endif
298 :
299 : static pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
300 : unsigned long size, pgprot_t vma_prot)
301 : {
302 : #ifdef pgprot_noncached
303 0 : phys_addr_t offset = pfn << PAGE_SHIFT;
304 :
305 0 : if (uncached_access(file, offset))
306 : return pgprot_noncached(vma_prot);
307 : #endif
308 : return vma_prot;
309 : }
310 : #endif
311 :
312 : #ifndef CONFIG_MMU
313 : static unsigned long get_unmapped_area_mem(struct file *file,
314 : unsigned long addr,
315 : unsigned long len,
316 : unsigned long pgoff,
317 : unsigned long flags)
318 : {
319 : if (!valid_mmap_phys_addr_range(pgoff, len))
320 : return (unsigned long) -EINVAL;
321 : return pgoff << PAGE_SHIFT;
322 : }
323 :
324 : /* permit direct mmap, for read, write or exec */
325 : static unsigned memory_mmap_capabilities(struct file *file)
326 : {
327 : return NOMMU_MAP_DIRECT |
328 : NOMMU_MAP_READ | NOMMU_MAP_WRITE | NOMMU_MAP_EXEC;
329 : }
330 :
331 : static unsigned zero_mmap_capabilities(struct file *file)
332 : {
333 : return NOMMU_MAP_COPY;
334 : }
335 :
336 : /* can't do an in-place private mapping if there's no MMU */
337 : static inline int private_mapping_ok(struct vm_area_struct *vma)
338 : {
339 : return is_nommu_shared_mapping(vma->vm_flags);
340 : }
341 : #else
342 :
343 : static inline int private_mapping_ok(struct vm_area_struct *vma)
344 : {
345 : return 1;
346 : }
347 : #endif
348 :
349 : static const struct vm_operations_struct mmap_mem_ops = {
350 : #ifdef CONFIG_HAVE_IOREMAP_PROT
351 : .access = generic_access_phys
352 : #endif
353 : };
354 :
355 0 : static int mmap_mem(struct file *file, struct vm_area_struct *vma)
356 : {
357 0 : size_t size = vma->vm_end - vma->vm_start;
358 0 : phys_addr_t offset = (phys_addr_t)vma->vm_pgoff << PAGE_SHIFT;
359 :
360 : /* Does it even fit in phys_addr_t? */
361 0 : if (offset >> PAGE_SHIFT != vma->vm_pgoff)
362 : return -EINVAL;
363 :
364 : /* It's illegal to wrap around the end of the physical address space. */
365 0 : if (offset + (phys_addr_t)size - 1 < offset)
366 : return -EINVAL;
367 :
368 0 : if (!valid_mmap_phys_addr_range(vma->vm_pgoff, size))
369 : return -EINVAL;
370 :
371 0 : if (!private_mapping_ok(vma))
372 : return -ENOSYS;
373 :
374 0 : if (!range_is_allowed(vma->vm_pgoff, size))
375 : return -EPERM;
376 :
377 0 : if (!phys_mem_access_prot_allowed(file, vma->vm_pgoff, size,
378 : &vma->vm_page_prot))
379 : return -EINVAL;
380 :
381 0 : vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
382 : size,
383 : vma->vm_page_prot);
384 :
385 0 : vma->vm_ops = &mmap_mem_ops;
386 :
387 : /* Remap-pfn-range will mark the range VM_IO */
388 0 : if (remap_pfn_range(vma,
389 : vma->vm_start,
390 : vma->vm_pgoff,
391 : size,
392 : vma->vm_page_prot)) {
393 : return -EAGAIN;
394 : }
395 0 : return 0;
396 : }
397 :
398 : static ssize_t read_port(struct file *file, char __user *buf,
399 : size_t count, loff_t *ppos)
400 : {
401 : unsigned long i = *ppos;
402 : char __user *tmp = buf;
403 :
404 : if (!access_ok(buf, count))
405 : return -EFAULT;
406 : while (count-- > 0 && i < 65536) {
407 : if (__put_user(inb(i), tmp) < 0)
408 : return -EFAULT;
409 : i++;
410 : tmp++;
411 : }
412 : *ppos = i;
413 : return tmp-buf;
414 : }
415 :
416 : static ssize_t write_port(struct file *file, const char __user *buf,
417 : size_t count, loff_t *ppos)
418 : {
419 : unsigned long i = *ppos;
420 : const char __user *tmp = buf;
421 :
422 : if (!access_ok(buf, count))
423 : return -EFAULT;
424 : while (count-- > 0 && i < 65536) {
425 : char c;
426 :
427 : if (__get_user(c, tmp)) {
428 : if (tmp > buf)
429 : break;
430 : return -EFAULT;
431 : }
432 : outb(c, i);
433 : i++;
434 : tmp++;
435 : }
436 : *ppos = i;
437 : return tmp-buf;
438 : }
439 :
440 0 : static ssize_t read_null(struct file *file, char __user *buf,
441 : size_t count, loff_t *ppos)
442 : {
443 0 : return 0;
444 : }
445 :
446 0 : static ssize_t write_null(struct file *file, const char __user *buf,
447 : size_t count, loff_t *ppos)
448 : {
449 0 : return count;
450 : }
451 :
452 0 : static ssize_t read_iter_null(struct kiocb *iocb, struct iov_iter *to)
453 : {
454 0 : return 0;
455 : }
456 :
457 0 : static ssize_t write_iter_null(struct kiocb *iocb, struct iov_iter *from)
458 : {
459 0 : size_t count = iov_iter_count(from);
460 0 : iov_iter_advance(from, count);
461 0 : return count;
462 : }
463 :
464 0 : static int pipe_to_null(struct pipe_inode_info *info, struct pipe_buffer *buf,
465 : struct splice_desc *sd)
466 : {
467 0 : return sd->len;
468 : }
469 :
470 0 : static ssize_t splice_write_null(struct pipe_inode_info *pipe, struct file *out,
471 : loff_t *ppos, size_t len, unsigned int flags)
472 : {
473 0 : return splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_null);
474 : }
475 :
476 0 : static int uring_cmd_null(struct io_uring_cmd *ioucmd, unsigned int issue_flags)
477 : {
478 0 : return 0;
479 : }
480 :
481 0 : static ssize_t read_iter_zero(struct kiocb *iocb, struct iov_iter *iter)
482 : {
483 0 : size_t written = 0;
484 :
485 0 : while (iov_iter_count(iter)) {
486 0 : size_t chunk = iov_iter_count(iter), n;
487 :
488 0 : if (chunk > PAGE_SIZE)
489 0 : chunk = PAGE_SIZE; /* Just for latency reasons */
490 0 : n = iov_iter_zero(chunk, iter);
491 0 : if (!n && iov_iter_count(iter))
492 0 : return written ? written : -EFAULT;
493 0 : written += n;
494 0 : if (signal_pending(current))
495 0 : return written ? written : -ERESTARTSYS;
496 0 : if (!need_resched())
497 0 : continue;
498 0 : if (iocb->ki_flags & IOCB_NOWAIT)
499 0 : return written ? written : -EAGAIN;
500 0 : cond_resched();
501 : }
502 0 : return written;
503 : }
504 :
505 0 : static ssize_t read_zero(struct file *file, char __user *buf,
506 : size_t count, loff_t *ppos)
507 : {
508 0 : size_t cleared = 0;
509 :
510 0 : while (count) {
511 0 : size_t chunk = min_t(size_t, count, PAGE_SIZE);
512 : size_t left;
513 :
514 0 : left = clear_user(buf + cleared, chunk);
515 0 : if (unlikely(left)) {
516 0 : cleared += (chunk - left);
517 0 : if (!cleared)
518 : return -EFAULT;
519 : break;
520 : }
521 0 : cleared += chunk;
522 0 : count -= chunk;
523 :
524 0 : if (signal_pending(current))
525 : break;
526 0 : cond_resched();
527 : }
528 :
529 0 : return cleared;
530 : }
531 :
532 0 : static int mmap_zero(struct file *file, struct vm_area_struct *vma)
533 : {
534 : #ifndef CONFIG_MMU
535 : return -ENOSYS;
536 : #endif
537 0 : if (vma->vm_flags & VM_SHARED)
538 0 : return shmem_zero_setup(vma);
539 0 : vma_set_anonymous(vma);
540 0 : return 0;
541 : }
542 :
543 0 : static unsigned long get_unmapped_area_zero(struct file *file,
544 : unsigned long addr, unsigned long len,
545 : unsigned long pgoff, unsigned long flags)
546 : {
547 : #ifdef CONFIG_MMU
548 0 : if (flags & MAP_SHARED) {
549 : /*
550 : * mmap_zero() will call shmem_zero_setup() to create a file,
551 : * so use shmem's get_unmapped_area in case it can be huge;
552 : * and pass NULL for file as in mmap.c's get_unmapped_area(),
553 : * so as not to confuse shmem with our handle on "/dev/zero".
554 : */
555 0 : return shmem_get_unmapped_area(NULL, addr, len, pgoff, flags);
556 : }
557 :
558 : /* Otherwise flags & MAP_PRIVATE: with no shmem object beneath it */
559 0 : return current->mm->get_unmapped_area(file, addr, len, pgoff, flags);
560 : #else
561 : return -ENOSYS;
562 : #endif
563 : }
564 :
565 0 : static ssize_t write_full(struct file *file, const char __user *buf,
566 : size_t count, loff_t *ppos)
567 : {
568 0 : return -ENOSPC;
569 : }
570 :
571 : /*
572 : * Special lseek() function for /dev/null and /dev/zero. Most notably, you
573 : * can fopen() both devices with "a" now. This was previously impossible.
574 : * -- SRB.
575 : */
576 0 : static loff_t null_lseek(struct file *file, loff_t offset, int orig)
577 : {
578 0 : return file->f_pos = 0;
579 : }
580 :
581 : /*
582 : * The memory devices use the full 32/64 bits of the offset, and so we cannot
583 : * check against negative addresses: they are ok. The return value is weird,
584 : * though, in that case (0).
585 : *
586 : * also note that seeking relative to the "end of file" isn't supported:
587 : * it has no meaning, so it returns -EINVAL.
588 : */
589 0 : static loff_t memory_lseek(struct file *file, loff_t offset, int orig)
590 : {
591 : loff_t ret;
592 :
593 0 : inode_lock(file_inode(file));
594 0 : switch (orig) {
595 : case SEEK_CUR:
596 0 : offset += file->f_pos;
597 : fallthrough;
598 : case SEEK_SET:
599 : /* to avoid userland mistaking f_pos=-9 as -EBADF=-9 */
600 0 : if ((unsigned long long)offset >= -MAX_ERRNO) {
601 : ret = -EOVERFLOW;
602 : break;
603 : }
604 0 : file->f_pos = offset;
605 0 : ret = file->f_pos;
606 : force_successful_syscall_return();
607 0 : break;
608 : default:
609 : ret = -EINVAL;
610 : }
611 0 : inode_unlock(file_inode(file));
612 0 : return ret;
613 : }
614 :
615 0 : static int open_port(struct inode *inode, struct file *filp)
616 : {
617 : int rc;
618 :
619 0 : if (!capable(CAP_SYS_RAWIO))
620 : return -EPERM;
621 :
622 0 : rc = security_locked_down(LOCKDOWN_DEV_MEM);
623 : if (rc)
624 : return rc;
625 :
626 0 : if (iminor(inode) != DEVMEM_MINOR)
627 : return 0;
628 :
629 : /*
630 : * Use a unified address space to have a single point to manage
631 : * revocations when drivers want to take over a /dev/mem mapped
632 : * range.
633 : */
634 0 : filp->f_mapping = iomem_get_mapping();
635 :
636 0 : return 0;
637 : }
638 :
639 : #define zero_lseek null_lseek
640 : #define full_lseek null_lseek
641 : #define write_zero write_null
642 : #define write_iter_zero write_iter_null
643 : #define open_mem open_port
644 :
645 : static const struct file_operations __maybe_unused mem_fops = {
646 : .llseek = memory_lseek,
647 : .read = read_mem,
648 : .write = write_mem,
649 : .mmap = mmap_mem,
650 : .open = open_mem,
651 : #ifndef CONFIG_MMU
652 : .get_unmapped_area = get_unmapped_area_mem,
653 : .mmap_capabilities = memory_mmap_capabilities,
654 : #endif
655 : };
656 :
657 : static const struct file_operations null_fops = {
658 : .llseek = null_lseek,
659 : .read = read_null,
660 : .write = write_null,
661 : .read_iter = read_iter_null,
662 : .write_iter = write_iter_null,
663 : .splice_write = splice_write_null,
664 : .uring_cmd = uring_cmd_null,
665 : };
666 :
667 : static const struct file_operations __maybe_unused port_fops = {
668 : .llseek = memory_lseek,
669 : .read = read_port,
670 : .write = write_port,
671 : .open = open_port,
672 : };
673 :
674 : static const struct file_operations zero_fops = {
675 : .llseek = zero_lseek,
676 : .write = write_zero,
677 : .read_iter = read_iter_zero,
678 : .read = read_zero,
679 : .write_iter = write_iter_zero,
680 : .mmap = mmap_zero,
681 : .get_unmapped_area = get_unmapped_area_zero,
682 : #ifndef CONFIG_MMU
683 : .mmap_capabilities = zero_mmap_capabilities,
684 : #endif
685 : };
686 :
687 : static const struct file_operations full_fops = {
688 : .llseek = full_lseek,
689 : .read_iter = read_iter_zero,
690 : .write = write_full,
691 : };
692 :
693 : static const struct memdev {
694 : const char *name;
695 : umode_t mode;
696 : const struct file_operations *fops;
697 : fmode_t fmode;
698 : } devlist[] = {
699 : #ifdef CONFIG_DEVMEM
700 : [DEVMEM_MINOR] = { "mem", 0, &mem_fops, FMODE_UNSIGNED_OFFSET },
701 : #endif
702 : [3] = { "null", 0666, &null_fops, FMODE_NOWAIT },
703 : #ifdef CONFIG_DEVPORT
704 : [4] = { "port", 0, &port_fops, 0 },
705 : #endif
706 : [5] = { "zero", 0666, &zero_fops, FMODE_NOWAIT },
707 : [7] = { "full", 0666, &full_fops, 0 },
708 : [8] = { "random", 0666, &random_fops, FMODE_NOWAIT },
709 : [9] = { "urandom", 0666, &urandom_fops, FMODE_NOWAIT },
710 : #ifdef CONFIG_PRINTK
711 : [11] = { "kmsg", 0644, &kmsg_fops, 0 },
712 : #endif
713 : };
714 :
715 0 : static int memory_open(struct inode *inode, struct file *filp)
716 : {
717 : int minor;
718 : const struct memdev *dev;
719 :
720 0 : minor = iminor(inode);
721 0 : if (minor >= ARRAY_SIZE(devlist))
722 : return -ENXIO;
723 :
724 0 : dev = &devlist[minor];
725 0 : if (!dev->fops)
726 : return -ENXIO;
727 :
728 0 : filp->f_op = dev->fops;
729 0 : filp->f_mode |= dev->fmode;
730 :
731 0 : if (dev->fops->open)
732 0 : return dev->fops->open(inode, filp);
733 :
734 : return 0;
735 : }
736 :
737 : static const struct file_operations memory_fops = {
738 : .open = memory_open,
739 : .llseek = noop_llseek,
740 : };
741 :
742 7 : static char *mem_devnode(const struct device *dev, umode_t *mode)
743 : {
744 7 : if (mode && devlist[MINOR(dev->devt)].mode)
745 6 : *mode = devlist[MINOR(dev->devt)].mode;
746 7 : return NULL;
747 : }
748 :
749 : static const struct class mem_class = {
750 : .name = "mem",
751 : .devnode = mem_devnode,
752 : };
753 :
754 1 : static int __init chr_dev_init(void)
755 : {
756 : int retval;
757 : int minor;
758 :
759 1 : if (register_chrdev(MEM_MAJOR, "mem", &memory_fops))
760 0 : printk("unable to get major %d for memory devs\n", MEM_MAJOR);
761 :
762 1 : retval = class_register(&mem_class);
763 1 : if (retval)
764 : return retval;
765 :
766 11 : for (minor = 1; minor < ARRAY_SIZE(devlist); minor++) {
767 11 : if (!devlist[minor].name)
768 4 : continue;
769 :
770 : /*
771 : * Create /dev/port?
772 : */
773 : if ((minor == DEVPORT_MINOR) && !arch_has_dev_port())
774 : continue;
775 :
776 7 : device_create(&mem_class, NULL, MKDEV(MEM_MAJOR, minor),
777 : NULL, devlist[minor].name);
778 : }
779 :
780 1 : return tty_init();
781 : }
782 :
783 : fs_initcall(chr_dev_init);
|