0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 #define NVRAM_VERSION "1.3"
0033
0034 #include <linux/module.h>
0035 #include <linux/nvram.h>
0036 #include <linux/types.h>
0037 #include <linux/errno.h>
0038 #include <linux/miscdevice.h>
0039 #include <linux/ioport.h>
0040 #include <linux/fcntl.h>
0041 #include <linux/mc146818rtc.h>
0042 #include <linux/init.h>
0043 #include <linux/proc_fs.h>
0044 #include <linux/seq_file.h>
0045 #include <linux/slab.h>
0046 #include <linux/spinlock.h>
0047 #include <linux/io.h>
0048 #include <linux/uaccess.h>
0049 #include <linux/mutex.h>
0050 #include <linux/pagemap.h>
0051
0052 #ifdef CONFIG_PPC
0053 #include <asm/nvram.h>
0054 #endif
0055
0056 static DEFINE_MUTEX(nvram_mutex);
0057 static DEFINE_SPINLOCK(nvram_state_lock);
0058 static int nvram_open_cnt;
0059 static int nvram_open_mode;
0060 static ssize_t nvram_size;
0061 #define NVRAM_WRITE 1
0062 #define NVRAM_EXCL 2
0063
0064 #ifdef CONFIG_X86
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076 #define NVRAM_BYTES (128 - NVRAM_FIRST_BYTE)
0077
0078
0079
0080
0081
0082
0083
0084 static unsigned char __nvram_read_byte(int i)
0085 {
0086 return CMOS_READ(NVRAM_FIRST_BYTE + i);
0087 }
0088
0089 static unsigned char pc_nvram_read_byte(int i)
0090 {
0091 unsigned long flags;
0092 unsigned char c;
0093
0094 spin_lock_irqsave(&rtc_lock, flags);
0095 c = __nvram_read_byte(i);
0096 spin_unlock_irqrestore(&rtc_lock, flags);
0097 return c;
0098 }
0099
0100
0101 static void __nvram_write_byte(unsigned char c, int i)
0102 {
0103 CMOS_WRITE(c, NVRAM_FIRST_BYTE + i);
0104 }
0105
0106 static void pc_nvram_write_byte(unsigned char c, int i)
0107 {
0108 unsigned long flags;
0109
0110 spin_lock_irqsave(&rtc_lock, flags);
0111 __nvram_write_byte(c, i);
0112 spin_unlock_irqrestore(&rtc_lock, flags);
0113 }
0114
0115
0116 #define PC_CKS_RANGE_START 2
0117 #define PC_CKS_RANGE_END 31
0118 #define PC_CKS_LOC 32
0119
0120 static int __nvram_check_checksum(void)
0121 {
0122 int i;
0123 unsigned short sum = 0;
0124 unsigned short expect;
0125
0126 for (i = PC_CKS_RANGE_START; i <= PC_CKS_RANGE_END; ++i)
0127 sum += __nvram_read_byte(i);
0128 expect = __nvram_read_byte(PC_CKS_LOC)<<8 |
0129 __nvram_read_byte(PC_CKS_LOC+1);
0130 return (sum & 0xffff) == expect;
0131 }
0132
0133 static void __nvram_set_checksum(void)
0134 {
0135 int i;
0136 unsigned short sum = 0;
0137
0138 for (i = PC_CKS_RANGE_START; i <= PC_CKS_RANGE_END; ++i)
0139 sum += __nvram_read_byte(i);
0140 __nvram_write_byte(sum >> 8, PC_CKS_LOC);
0141 __nvram_write_byte(sum & 0xff, PC_CKS_LOC + 1);
0142 }
0143
0144 static long pc_nvram_set_checksum(void)
0145 {
0146 spin_lock_irq(&rtc_lock);
0147 __nvram_set_checksum();
0148 spin_unlock_irq(&rtc_lock);
0149 return 0;
0150 }
0151
0152 static long pc_nvram_initialize(void)
0153 {
0154 ssize_t i;
0155
0156 spin_lock_irq(&rtc_lock);
0157 for (i = 0; i < NVRAM_BYTES; ++i)
0158 __nvram_write_byte(0, i);
0159 __nvram_set_checksum();
0160 spin_unlock_irq(&rtc_lock);
0161 return 0;
0162 }
0163
0164 static ssize_t pc_nvram_get_size(void)
0165 {
0166 return NVRAM_BYTES;
0167 }
0168
0169 static ssize_t pc_nvram_read(char *buf, size_t count, loff_t *ppos)
0170 {
0171 char *p = buf;
0172 loff_t i;
0173
0174 spin_lock_irq(&rtc_lock);
0175 if (!__nvram_check_checksum()) {
0176 spin_unlock_irq(&rtc_lock);
0177 return -EIO;
0178 }
0179 for (i = *ppos; count > 0 && i < NVRAM_BYTES; --count, ++i, ++p)
0180 *p = __nvram_read_byte(i);
0181 spin_unlock_irq(&rtc_lock);
0182
0183 *ppos = i;
0184 return p - buf;
0185 }
0186
0187 static ssize_t pc_nvram_write(char *buf, size_t count, loff_t *ppos)
0188 {
0189 char *p = buf;
0190 loff_t i;
0191
0192 spin_lock_irq(&rtc_lock);
0193 if (!__nvram_check_checksum()) {
0194 spin_unlock_irq(&rtc_lock);
0195 return -EIO;
0196 }
0197 for (i = *ppos; count > 0 && i < NVRAM_BYTES; --count, ++i, ++p)
0198 __nvram_write_byte(*p, i);
0199 __nvram_set_checksum();
0200 spin_unlock_irq(&rtc_lock);
0201
0202 *ppos = i;
0203 return p - buf;
0204 }
0205
0206 const struct nvram_ops arch_nvram_ops = {
0207 .read = pc_nvram_read,
0208 .write = pc_nvram_write,
0209 .read_byte = pc_nvram_read_byte,
0210 .write_byte = pc_nvram_write_byte,
0211 .get_size = pc_nvram_get_size,
0212 .set_checksum = pc_nvram_set_checksum,
0213 .initialize = pc_nvram_initialize,
0214 };
0215 EXPORT_SYMBOL(arch_nvram_ops);
0216 #endif
0217
0218
0219
0220
0221
0222 static loff_t nvram_misc_llseek(struct file *file, loff_t offset, int origin)
0223 {
0224 return generic_file_llseek_size(file, offset, origin, MAX_LFS_FILESIZE,
0225 nvram_size);
0226 }
0227
0228 static ssize_t nvram_misc_read(struct file *file, char __user *buf,
0229 size_t count, loff_t *ppos)
0230 {
0231 char *tmp;
0232 ssize_t ret;
0233
0234
0235 if (*ppos >= nvram_size)
0236 return 0;
0237
0238 count = min_t(size_t, count, nvram_size - *ppos);
0239 count = min_t(size_t, count, PAGE_SIZE);
0240
0241 tmp = kmalloc(count, GFP_KERNEL);
0242 if (!tmp)
0243 return -ENOMEM;
0244
0245 ret = nvram_read(tmp, count, ppos);
0246 if (ret <= 0)
0247 goto out;
0248
0249 if (copy_to_user(buf, tmp, ret)) {
0250 *ppos -= ret;
0251 ret = -EFAULT;
0252 }
0253
0254 out:
0255 kfree(tmp);
0256 return ret;
0257 }
0258
0259 static ssize_t nvram_misc_write(struct file *file, const char __user *buf,
0260 size_t count, loff_t *ppos)
0261 {
0262 char *tmp;
0263 ssize_t ret;
0264
0265 if (*ppos >= nvram_size)
0266 return 0;
0267
0268 count = min_t(size_t, count, nvram_size - *ppos);
0269 count = min_t(size_t, count, PAGE_SIZE);
0270
0271 tmp = memdup_user(buf, count);
0272 if (IS_ERR(tmp))
0273 return PTR_ERR(tmp);
0274
0275 ret = nvram_write(tmp, count, ppos);
0276 kfree(tmp);
0277 return ret;
0278 }
0279
0280 static long nvram_misc_ioctl(struct file *file, unsigned int cmd,
0281 unsigned long arg)
0282 {
0283 long ret = -ENOTTY;
0284
0285 switch (cmd) {
0286 #ifdef CONFIG_PPC
0287 case OBSOLETE_PMAC_NVRAM_GET_OFFSET:
0288 pr_warn("nvram: Using obsolete PMAC_NVRAM_GET_OFFSET ioctl\n");
0289 fallthrough;
0290 case IOC_NVRAM_GET_OFFSET:
0291 ret = -EINVAL;
0292 #ifdef CONFIG_PPC_PMAC
0293 if (machine_is(powermac)) {
0294 int part, offset;
0295
0296 if (copy_from_user(&part, (void __user *)arg,
0297 sizeof(part)) != 0)
0298 return -EFAULT;
0299 if (part < pmac_nvram_OF || part > pmac_nvram_NR)
0300 return -EINVAL;
0301 offset = pmac_get_partition(part);
0302 if (offset < 0)
0303 return -EINVAL;
0304 if (copy_to_user((void __user *)arg,
0305 &offset, sizeof(offset)) != 0)
0306 return -EFAULT;
0307 ret = 0;
0308 }
0309 #endif
0310 break;
0311 #ifdef CONFIG_PPC32
0312 case IOC_NVRAM_SYNC:
0313 if (ppc_md.nvram_sync != NULL) {
0314 mutex_lock(&nvram_mutex);
0315 ppc_md.nvram_sync();
0316 mutex_unlock(&nvram_mutex);
0317 }
0318 ret = 0;
0319 break;
0320 #endif
0321 #elif defined(CONFIG_X86) || defined(CONFIG_M68K)
0322 case NVRAM_INIT:
0323
0324 if (!capable(CAP_SYS_ADMIN))
0325 return -EACCES;
0326
0327 if (arch_nvram_ops.initialize != NULL) {
0328 mutex_lock(&nvram_mutex);
0329 ret = arch_nvram_ops.initialize();
0330 mutex_unlock(&nvram_mutex);
0331 }
0332 break;
0333 case NVRAM_SETCKS:
0334
0335
0336 if (!capable(CAP_SYS_ADMIN))
0337 return -EACCES;
0338
0339 if (arch_nvram_ops.set_checksum != NULL) {
0340 mutex_lock(&nvram_mutex);
0341 ret = arch_nvram_ops.set_checksum();
0342 mutex_unlock(&nvram_mutex);
0343 }
0344 break;
0345 #endif
0346 }
0347 return ret;
0348 }
0349
0350 static int nvram_misc_open(struct inode *inode, struct file *file)
0351 {
0352 spin_lock(&nvram_state_lock);
0353
0354
0355 if ((nvram_open_cnt && (file->f_flags & O_EXCL)) ||
0356 (nvram_open_mode & NVRAM_EXCL)) {
0357 spin_unlock(&nvram_state_lock);
0358 return -EBUSY;
0359 }
0360
0361 #if defined(CONFIG_X86) || defined(CONFIG_M68K)
0362
0363 if ((arch_nvram_ops.set_checksum != NULL) &&
0364 (file->f_mode & FMODE_WRITE) && (nvram_open_mode & NVRAM_WRITE)) {
0365 spin_unlock(&nvram_state_lock);
0366 return -EBUSY;
0367 }
0368 #endif
0369
0370 if (file->f_flags & O_EXCL)
0371 nvram_open_mode |= NVRAM_EXCL;
0372 if (file->f_mode & FMODE_WRITE)
0373 nvram_open_mode |= NVRAM_WRITE;
0374 nvram_open_cnt++;
0375
0376 spin_unlock(&nvram_state_lock);
0377
0378 return 0;
0379 }
0380
0381 static int nvram_misc_release(struct inode *inode, struct file *file)
0382 {
0383 spin_lock(&nvram_state_lock);
0384
0385 nvram_open_cnt--;
0386
0387
0388 if (nvram_open_mode & NVRAM_EXCL)
0389 nvram_open_mode &= ~NVRAM_EXCL;
0390 if (file->f_mode & FMODE_WRITE)
0391 nvram_open_mode &= ~NVRAM_WRITE;
0392
0393 spin_unlock(&nvram_state_lock);
0394
0395 return 0;
0396 }
0397
0398 #if defined(CONFIG_X86) && defined(CONFIG_PROC_FS)
0399 static const char * const floppy_types[] = {
0400 "none", "5.25'' 360k", "5.25'' 1.2M", "3.5'' 720k", "3.5'' 1.44M",
0401 "3.5'' 2.88M", "3.5'' 2.88M"
0402 };
0403
0404 static const char * const gfx_types[] = {
0405 "EGA, VGA, ... (with BIOS)",
0406 "CGA (40 cols)",
0407 "CGA (80 cols)",
0408 "monochrome",
0409 };
0410
0411 static void pc_nvram_proc_read(unsigned char *nvram, struct seq_file *seq,
0412 void *offset)
0413 {
0414 int checksum;
0415 int type;
0416
0417 spin_lock_irq(&rtc_lock);
0418 checksum = __nvram_check_checksum();
0419 spin_unlock_irq(&rtc_lock);
0420
0421 seq_printf(seq, "Checksum status: %svalid\n", checksum ? "" : "not ");
0422
0423 seq_printf(seq, "# floppies : %d\n",
0424 (nvram[6] & 1) ? (nvram[6] >> 6) + 1 : 0);
0425 seq_printf(seq, "Floppy 0 type : ");
0426 type = nvram[2] >> 4;
0427 if (type < ARRAY_SIZE(floppy_types))
0428 seq_printf(seq, "%s\n", floppy_types[type]);
0429 else
0430 seq_printf(seq, "%d (unknown)\n", type);
0431 seq_printf(seq, "Floppy 1 type : ");
0432 type = nvram[2] & 0x0f;
0433 if (type < ARRAY_SIZE(floppy_types))
0434 seq_printf(seq, "%s\n", floppy_types[type]);
0435 else
0436 seq_printf(seq, "%d (unknown)\n", type);
0437
0438 seq_printf(seq, "HD 0 type : ");
0439 type = nvram[4] >> 4;
0440 if (type)
0441 seq_printf(seq, "%02x\n", type == 0x0f ? nvram[11] : type);
0442 else
0443 seq_printf(seq, "none\n");
0444
0445 seq_printf(seq, "HD 1 type : ");
0446 type = nvram[4] & 0x0f;
0447 if (type)
0448 seq_printf(seq, "%02x\n", type == 0x0f ? nvram[12] : type);
0449 else
0450 seq_printf(seq, "none\n");
0451
0452 seq_printf(seq, "HD type 48 data: %d/%d/%d C/H/S, precomp %d, lz %d\n",
0453 nvram[18] | (nvram[19] << 8),
0454 nvram[20], nvram[25],
0455 nvram[21] | (nvram[22] << 8), nvram[23] | (nvram[24] << 8));
0456 seq_printf(seq, "HD type 49 data: %d/%d/%d C/H/S, precomp %d, lz %d\n",
0457 nvram[39] | (nvram[40] << 8),
0458 nvram[41], nvram[46],
0459 nvram[42] | (nvram[43] << 8), nvram[44] | (nvram[45] << 8));
0460
0461 seq_printf(seq, "DOS base memory: %d kB\n", nvram[7] | (nvram[8] << 8));
0462 seq_printf(seq, "Extended memory: %d kB (configured), %d kB (tested)\n",
0463 nvram[9] | (nvram[10] << 8), nvram[34] | (nvram[35] << 8));
0464
0465 seq_printf(seq, "Gfx adapter : %s\n",
0466 gfx_types[(nvram[6] >> 4) & 3]);
0467
0468 seq_printf(seq, "FPU : %sinstalled\n",
0469 (nvram[6] & 2) ? "" : "not ");
0470
0471 return;
0472 }
0473
0474 static int nvram_proc_read(struct seq_file *seq, void *offset)
0475 {
0476 unsigned char contents[NVRAM_BYTES];
0477 int i = 0;
0478
0479 spin_lock_irq(&rtc_lock);
0480 for (i = 0; i < NVRAM_BYTES; ++i)
0481 contents[i] = __nvram_read_byte(i);
0482 spin_unlock_irq(&rtc_lock);
0483
0484 pc_nvram_proc_read(contents, seq, offset);
0485
0486 return 0;
0487 }
0488 #endif
0489
0490 static const struct file_operations nvram_misc_fops = {
0491 .owner = THIS_MODULE,
0492 .llseek = nvram_misc_llseek,
0493 .read = nvram_misc_read,
0494 .write = nvram_misc_write,
0495 .unlocked_ioctl = nvram_misc_ioctl,
0496 .open = nvram_misc_open,
0497 .release = nvram_misc_release,
0498 };
0499
0500 static struct miscdevice nvram_misc = {
0501 NVRAM_MINOR,
0502 "nvram",
0503 &nvram_misc_fops,
0504 };
0505
0506 static int __init nvram_module_init(void)
0507 {
0508 int ret;
0509
0510 nvram_size = nvram_get_size();
0511 if (nvram_size < 0)
0512 return nvram_size;
0513
0514 ret = misc_register(&nvram_misc);
0515 if (ret) {
0516 pr_err("nvram: can't misc_register on minor=%d\n", NVRAM_MINOR);
0517 return ret;
0518 }
0519
0520 #if defined(CONFIG_X86) && defined(CONFIG_PROC_FS)
0521 if (!proc_create_single("driver/nvram", 0, NULL, nvram_proc_read)) {
0522 pr_err("nvram: can't create /proc/driver/nvram\n");
0523 misc_deregister(&nvram_misc);
0524 return -ENOMEM;
0525 }
0526 #endif
0527
0528 pr_info("Non-volatile memory driver v" NVRAM_VERSION "\n");
0529 return 0;
0530 }
0531
0532 static void __exit nvram_module_exit(void)
0533 {
0534 #if defined(CONFIG_X86) && defined(CONFIG_PROC_FS)
0535 remove_proc_entry("driver/nvram", NULL);
0536 #endif
0537 misc_deregister(&nvram_misc);
0538 }
0539
0540 module_init(nvram_module_init);
0541 module_exit(nvram_module_exit);
0542
0543 MODULE_LICENSE("GPL");
0544 MODULE_ALIAS_MISCDEV(NVRAM_MINOR);
0545 MODULE_ALIAS("devname:nvram");