.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * c 2001 PPC 64 Team, IBM Corp |
---|
3 | 4 | * |
---|
4 | | - * This program is free software; you can redistribute it and/or |
---|
5 | | - * modify it under the terms of the GNU General Public License |
---|
6 | | - * as published by the Free Software Foundation; either version |
---|
7 | | - * 2 of the License, or (at your option) any later version. |
---|
8 | | - * |
---|
9 | 5 | * /dev/nvram driver for PPC64 |
---|
10 | | - * |
---|
11 | | - * This perhaps should live in drivers/char |
---|
12 | | - * |
---|
13 | | - * TODO: Split the /dev/nvram part (that one can use |
---|
14 | | - * drivers/char/generic_nvram.c) from the arch & partition |
---|
15 | | - * parsing code. |
---|
16 | 6 | */ |
---|
17 | 7 | |
---|
18 | 8 | #include <linux/types.h> |
---|
.. | .. |
---|
665 | 655 | int rc = -1; |
---|
666 | 656 | |
---|
667 | 657 | switch (reason) { |
---|
668 | | - case KMSG_DUMP_RESTART: |
---|
669 | | - case KMSG_DUMP_HALT: |
---|
670 | | - case KMSG_DUMP_POWEROFF: |
---|
| 658 | + case KMSG_DUMP_SHUTDOWN: |
---|
671 | 659 | /* These are almost always orderly shutdowns. */ |
---|
672 | 660 | return; |
---|
673 | 661 | case KMSG_DUMP_OOPS: |
---|
.. | .. |
---|
713 | 701 | |
---|
714 | 702 | spin_unlock_irqrestore(&lock, flags); |
---|
715 | 703 | } |
---|
716 | | - |
---|
717 | | -static loff_t dev_nvram_llseek(struct file *file, loff_t offset, int origin) |
---|
718 | | -{ |
---|
719 | | - if (ppc_md.nvram_size == NULL) |
---|
720 | | - return -ENODEV; |
---|
721 | | - return generic_file_llseek_size(file, offset, origin, MAX_LFS_FILESIZE, |
---|
722 | | - ppc_md.nvram_size()); |
---|
723 | | -} |
---|
724 | | - |
---|
725 | | - |
---|
726 | | -static ssize_t dev_nvram_read(struct file *file, char __user *buf, |
---|
727 | | - size_t count, loff_t *ppos) |
---|
728 | | -{ |
---|
729 | | - ssize_t ret; |
---|
730 | | - char *tmp = NULL; |
---|
731 | | - ssize_t size; |
---|
732 | | - |
---|
733 | | - if (!ppc_md.nvram_size) { |
---|
734 | | - ret = -ENODEV; |
---|
735 | | - goto out; |
---|
736 | | - } |
---|
737 | | - |
---|
738 | | - size = ppc_md.nvram_size(); |
---|
739 | | - if (size < 0) { |
---|
740 | | - ret = size; |
---|
741 | | - goto out; |
---|
742 | | - } |
---|
743 | | - |
---|
744 | | - if (*ppos >= size) { |
---|
745 | | - ret = 0; |
---|
746 | | - goto out; |
---|
747 | | - } |
---|
748 | | - |
---|
749 | | - count = min_t(size_t, count, size - *ppos); |
---|
750 | | - count = min(count, PAGE_SIZE); |
---|
751 | | - |
---|
752 | | - tmp = kmalloc(count, GFP_KERNEL); |
---|
753 | | - if (!tmp) { |
---|
754 | | - ret = -ENOMEM; |
---|
755 | | - goto out; |
---|
756 | | - } |
---|
757 | | - |
---|
758 | | - ret = ppc_md.nvram_read(tmp, count, ppos); |
---|
759 | | - if (ret <= 0) |
---|
760 | | - goto out; |
---|
761 | | - |
---|
762 | | - if (copy_to_user(buf, tmp, ret)) |
---|
763 | | - ret = -EFAULT; |
---|
764 | | - |
---|
765 | | -out: |
---|
766 | | - kfree(tmp); |
---|
767 | | - return ret; |
---|
768 | | - |
---|
769 | | -} |
---|
770 | | - |
---|
771 | | -static ssize_t dev_nvram_write(struct file *file, const char __user *buf, |
---|
772 | | - size_t count, loff_t *ppos) |
---|
773 | | -{ |
---|
774 | | - ssize_t ret; |
---|
775 | | - char *tmp = NULL; |
---|
776 | | - ssize_t size; |
---|
777 | | - |
---|
778 | | - ret = -ENODEV; |
---|
779 | | - if (!ppc_md.nvram_size) |
---|
780 | | - goto out; |
---|
781 | | - |
---|
782 | | - ret = 0; |
---|
783 | | - size = ppc_md.nvram_size(); |
---|
784 | | - if (*ppos >= size || size < 0) |
---|
785 | | - goto out; |
---|
786 | | - |
---|
787 | | - count = min_t(size_t, count, size - *ppos); |
---|
788 | | - count = min(count, PAGE_SIZE); |
---|
789 | | - |
---|
790 | | - tmp = memdup_user(buf, count); |
---|
791 | | - if (IS_ERR(tmp)) { |
---|
792 | | - ret = PTR_ERR(tmp); |
---|
793 | | - goto out; |
---|
794 | | - } |
---|
795 | | - |
---|
796 | | - ret = ppc_md.nvram_write(tmp, count, ppos); |
---|
797 | | - |
---|
798 | | - kfree(tmp); |
---|
799 | | -out: |
---|
800 | | - return ret; |
---|
801 | | -} |
---|
802 | | - |
---|
803 | | -static long dev_nvram_ioctl(struct file *file, unsigned int cmd, |
---|
804 | | - unsigned long arg) |
---|
805 | | -{ |
---|
806 | | - switch(cmd) { |
---|
807 | | -#ifdef CONFIG_PPC_PMAC |
---|
808 | | - case OBSOLETE_PMAC_NVRAM_GET_OFFSET: |
---|
809 | | - printk(KERN_WARNING "nvram: Using obsolete PMAC_NVRAM_GET_OFFSET ioctl\n"); |
---|
810 | | - case IOC_NVRAM_GET_OFFSET: { |
---|
811 | | - int part, offset; |
---|
812 | | - |
---|
813 | | - if (!machine_is(powermac)) |
---|
814 | | - return -EINVAL; |
---|
815 | | - if (copy_from_user(&part, (void __user*)arg, sizeof(part)) != 0) |
---|
816 | | - return -EFAULT; |
---|
817 | | - if (part < pmac_nvram_OF || part > pmac_nvram_NR) |
---|
818 | | - return -EINVAL; |
---|
819 | | - offset = pmac_get_partition(part); |
---|
820 | | - if (offset < 0) |
---|
821 | | - return offset; |
---|
822 | | - if (copy_to_user((void __user*)arg, &offset, sizeof(offset)) != 0) |
---|
823 | | - return -EFAULT; |
---|
824 | | - return 0; |
---|
825 | | - } |
---|
826 | | -#endif /* CONFIG_PPC_PMAC */ |
---|
827 | | - default: |
---|
828 | | - return -EINVAL; |
---|
829 | | - } |
---|
830 | | -} |
---|
831 | | - |
---|
832 | | -static const struct file_operations nvram_fops = { |
---|
833 | | - .owner = THIS_MODULE, |
---|
834 | | - .llseek = dev_nvram_llseek, |
---|
835 | | - .read = dev_nvram_read, |
---|
836 | | - .write = dev_nvram_write, |
---|
837 | | - .unlocked_ioctl = dev_nvram_ioctl, |
---|
838 | | -}; |
---|
839 | | - |
---|
840 | | -static struct miscdevice nvram_dev = { |
---|
841 | | - NVRAM_MINOR, |
---|
842 | | - "nvram", |
---|
843 | | - &nvram_fops |
---|
844 | | -}; |
---|
845 | | - |
---|
846 | 704 | |
---|
847 | 705 | #ifdef DEBUG_NVRAM |
---|
848 | 706 | static void __init nvram_print_partitions(char * label) |
---|
.. | .. |
---|
991 | 849 | long size = 0; |
---|
992 | 850 | int rc; |
---|
993 | 851 | |
---|
| 852 | + BUILD_BUG_ON(NVRAM_BLOCK_LEN != 16); |
---|
| 853 | + |
---|
994 | 854 | /* Convert sizes from bytes to blocks */ |
---|
995 | | - req_size = _ALIGN_UP(req_size, NVRAM_BLOCK_LEN) / NVRAM_BLOCK_LEN; |
---|
996 | | - min_size = _ALIGN_UP(min_size, NVRAM_BLOCK_LEN) / NVRAM_BLOCK_LEN; |
---|
| 855 | + req_size = ALIGN(req_size, NVRAM_BLOCK_LEN) / NVRAM_BLOCK_LEN; |
---|
| 856 | + min_size = ALIGN(min_size, NVRAM_BLOCK_LEN) / NVRAM_BLOCK_LEN; |
---|
997 | 857 | |
---|
998 | 858 | /* If no minimum size specified, make it the same as the |
---|
999 | 859 | * requested size |
---|
.. | .. |
---|
1191 | 1051 | kfree(header); |
---|
1192 | 1052 | return err; |
---|
1193 | 1053 | } |
---|
1194 | | - |
---|
1195 | | -static int __init nvram_init(void) |
---|
1196 | | -{ |
---|
1197 | | - int rc; |
---|
1198 | | - |
---|
1199 | | - BUILD_BUG_ON(NVRAM_BLOCK_LEN != 16); |
---|
1200 | | - |
---|
1201 | | - if (ppc_md.nvram_size == NULL || ppc_md.nvram_size() <= 0) |
---|
1202 | | - return -ENODEV; |
---|
1203 | | - |
---|
1204 | | - rc = misc_register(&nvram_dev); |
---|
1205 | | - if (rc != 0) { |
---|
1206 | | - printk(KERN_ERR "nvram_init: failed to register device\n"); |
---|
1207 | | - return rc; |
---|
1208 | | - } |
---|
1209 | | - |
---|
1210 | | - return rc; |
---|
1211 | | -} |
---|
1212 | | -device_initcall(nvram_init); |
---|