nvram.c (437ace3777abc15d013d04e6644b100040bc613d) | nvram.c (cb8d8006d43f22924e000c730d18862587a824ff) |
---|---|
1/* 2 * CMOS/NV-RAM driver for Linux 3 * 4 * Copyright (C) 1997 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> 5 * idea by and with help from Richard Jelinek <rj@suse.de> 6 * Portions copyright (c) 2001,2002 Sun Microsystems (thockin@sun.com) 7 * 8 * This driver allows you to access the contents of the non-volatile memory in --- 41 unchanged lines hidden (view full) --- 50 51static DEFINE_MUTEX(nvram_mutex); 52static DEFINE_SPINLOCK(nvram_state_lock); 53static int nvram_open_cnt; /* #times opened */ 54static int nvram_open_mode; /* special open modes */ 55#define NVRAM_WRITE 1 /* opened for writing (exclusive) */ 56#define NVRAM_EXCL 2 /* opened with O_EXCL */ 57 | 1/* 2 * CMOS/NV-RAM driver for Linux 3 * 4 * Copyright (C) 1997 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> 5 * idea by and with help from Richard Jelinek <rj@suse.de> 6 * Portions copyright (c) 2001,2002 Sun Microsystems (thockin@sun.com) 7 * 8 * This driver allows you to access the contents of the non-volatile memory in --- 41 unchanged lines hidden (view full) --- 50 51static DEFINE_MUTEX(nvram_mutex); 52static DEFINE_SPINLOCK(nvram_state_lock); 53static int nvram_open_cnt; /* #times opened */ 54static int nvram_open_mode; /* special open modes */ 55#define NVRAM_WRITE 1 /* opened for writing (exclusive) */ 56#define NVRAM_EXCL 2 /* opened with O_EXCL */ 57 |
58#ifdef CONFIG_PROC_FS 59static void pc_nvram_proc_read(unsigned char *contents, struct seq_file *seq, 60 void *offset); 61#endif 62 | |
63/* 64 * These functions are provided to be called internally or by other parts of 65 * the kernel. It's up to the caller to ensure correct checksum before reading 66 * or after writing (needs to be done only once). 67 * 68 * It is worth noting that these functions all access bytes of general 69 * purpose memory in the NVRAM - that is to say, they all add the 70 * NVRAM_FIRST_BYTE offset. Pass them offsets into NVRAM as if you did not --- 95 unchanged lines hidden (view full) --- 166 spin_unlock_irqrestore(&rtc_lock, flags); 167} 168#endif /* 0 */ 169 170/* 171 * The are the file operation function for user access to /dev/nvram 172 */ 173 | 58/* 59 * These functions are provided to be called internally or by other parts of 60 * the kernel. It's up to the caller to ensure correct checksum before reading 61 * or after writing (needs to be done only once). 62 * 63 * It is worth noting that these functions all access bytes of general 64 * purpose memory in the NVRAM - that is to say, they all add the 65 * NVRAM_FIRST_BYTE offset. Pass them offsets into NVRAM as if you did not --- 95 unchanged lines hidden (view full) --- 161 spin_unlock_irqrestore(&rtc_lock, flags); 162} 163#endif /* 0 */ 164 165/* 166 * The are the file operation function for user access to /dev/nvram 167 */ 168 |
174static loff_t nvram_llseek(struct file *file, loff_t offset, int origin) | 169static loff_t nvram_misc_llseek(struct file *file, loff_t offset, int origin) |
175{ 176 return generic_file_llseek_size(file, offset, origin, MAX_LFS_FILESIZE, 177 NVRAM_BYTES); 178} 179 | 170{ 171 return generic_file_llseek_size(file, offset, origin, MAX_LFS_FILESIZE, 172 NVRAM_BYTES); 173} 174 |
180static ssize_t nvram_read(struct file *file, char __user *buf, 181 size_t count, loff_t *ppos) | 175static ssize_t nvram_misc_read(struct file *file, char __user *buf, 176 size_t count, loff_t *ppos) |
182{ 183 unsigned char contents[NVRAM_BYTES]; 184 unsigned i = *ppos; 185 unsigned char *tmp; 186 187 spin_lock_irq(&rtc_lock); 188 189 if (!__nvram_check_checksum()) --- 11 unchanged lines hidden (view full) --- 201 202 return tmp - contents; 203 204checksum_err: 205 spin_unlock_irq(&rtc_lock); 206 return -EIO; 207} 208 | 177{ 178 unsigned char contents[NVRAM_BYTES]; 179 unsigned i = *ppos; 180 unsigned char *tmp; 181 182 spin_lock_irq(&rtc_lock); 183 184 if (!__nvram_check_checksum()) --- 11 unchanged lines hidden (view full) --- 196 197 return tmp - contents; 198 199checksum_err: 200 spin_unlock_irq(&rtc_lock); 201 return -EIO; 202} 203 |
209static ssize_t nvram_write(struct file *file, const char __user *buf, 210 size_t count, loff_t *ppos) | 204static ssize_t nvram_misc_write(struct file *file, const char __user *buf, 205 size_t count, loff_t *ppos) |
211{ 212 unsigned char contents[NVRAM_BYTES]; 213 unsigned i = *ppos; 214 unsigned char *tmp; 215 216 if (i >= NVRAM_BYTES) 217 return 0; /* Past EOF */ 218 --- 21 unchanged lines hidden (view full) --- 240 241 return tmp - contents; 242 243checksum_err: 244 spin_unlock_irq(&rtc_lock); 245 return -EIO; 246} 247 | 206{ 207 unsigned char contents[NVRAM_BYTES]; 208 unsigned i = *ppos; 209 unsigned char *tmp; 210 211 if (i >= NVRAM_BYTES) 212 return 0; /* Past EOF */ 213 --- 21 unchanged lines hidden (view full) --- 235 236 return tmp - contents; 237 238checksum_err: 239 spin_unlock_irq(&rtc_lock); 240 return -EIO; 241} 242 |
248static long nvram_ioctl(struct file *file, unsigned int cmd, 249 unsigned long arg) | 243static long nvram_misc_ioctl(struct file *file, unsigned int cmd, 244 unsigned long arg) |
250{ 251 int i; 252 253 switch (cmd) { 254 255 case NVRAM_INIT: 256 /* initialize NVRAM contents and checksum */ 257 if (!capable(CAP_SYS_ADMIN)) --- 23 unchanged lines hidden (view full) --- 281 mutex_unlock(&nvram_mutex); 282 return 0; 283 284 default: 285 return -ENOTTY; 286 } 287} 288 | 245{ 246 int i; 247 248 switch (cmd) { 249 250 case NVRAM_INIT: 251 /* initialize NVRAM contents and checksum */ 252 if (!capable(CAP_SYS_ADMIN)) --- 23 unchanged lines hidden (view full) --- 276 mutex_unlock(&nvram_mutex); 277 return 0; 278 279 default: 280 return -ENOTTY; 281 } 282} 283 |
289static int nvram_open(struct inode *inode, struct file *file) | 284static int nvram_misc_open(struct inode *inode, struct file *file) |
290{ 291 spin_lock(&nvram_state_lock); 292 293 if ((nvram_open_cnt && (file->f_flags & O_EXCL)) || 294 (nvram_open_mode & NVRAM_EXCL) || 295 ((file->f_mode & FMODE_WRITE) && (nvram_open_mode & NVRAM_WRITE))) { 296 spin_unlock(&nvram_state_lock); 297 return -EBUSY; --- 5 unchanged lines hidden (view full) --- 303 nvram_open_mode |= NVRAM_WRITE; 304 nvram_open_cnt++; 305 306 spin_unlock(&nvram_state_lock); 307 308 return 0; 309} 310 | 285{ 286 spin_lock(&nvram_state_lock); 287 288 if ((nvram_open_cnt && (file->f_flags & O_EXCL)) || 289 (nvram_open_mode & NVRAM_EXCL) || 290 ((file->f_mode & FMODE_WRITE) && (nvram_open_mode & NVRAM_WRITE))) { 291 spin_unlock(&nvram_state_lock); 292 return -EBUSY; --- 5 unchanged lines hidden (view full) --- 298 nvram_open_mode |= NVRAM_WRITE; 299 nvram_open_cnt++; 300 301 spin_unlock(&nvram_state_lock); 302 303 return 0; 304} 305 |
311static int nvram_release(struct inode *inode, struct file *file) | 306static int nvram_misc_release(struct inode *inode, struct file *file) |
312{ 313 spin_lock(&nvram_state_lock); 314 315 nvram_open_cnt--; 316 317 /* if only one instance is open, clear the EXCL bit */ 318 if (nvram_open_mode & NVRAM_EXCL) 319 nvram_open_mode &= ~NVRAM_EXCL; 320 if (file->f_mode & FMODE_WRITE) 321 nvram_open_mode &= ~NVRAM_WRITE; 322 323 spin_unlock(&nvram_state_lock); 324 325 return 0; 326} 327 | 307{ 308 spin_lock(&nvram_state_lock); 309 310 nvram_open_cnt--; 311 312 /* if only one instance is open, clear the EXCL bit */ 313 if (nvram_open_mode & NVRAM_EXCL) 314 nvram_open_mode &= ~NVRAM_EXCL; 315 if (file->f_mode & FMODE_WRITE) 316 nvram_open_mode &= ~NVRAM_WRITE; 317 318 spin_unlock(&nvram_state_lock); 319 320 return 0; 321} 322 |
328#ifndef CONFIG_PROC_FS 329static int nvram_add_proc_fs(void) 330{ 331 return 0; 332} 333 334#else 335 336static int nvram_proc_read(struct seq_file *seq, void *offset) 337{ 338 unsigned char contents[NVRAM_BYTES]; 339 int i = 0; 340 341 spin_lock_irq(&rtc_lock); 342 for (i = 0; i < NVRAM_BYTES; ++i) 343 contents[i] = __nvram_read_byte(i); 344 spin_unlock_irq(&rtc_lock); 345 346 pc_nvram_proc_read(contents, seq, offset); 347 348 return 0; 349} 350 351static int nvram_add_proc_fs(void) 352{ 353 if (!proc_create_single("driver/nvram", 0, NULL, nvram_proc_read)) 354 return -ENOMEM; 355 return 0; 356} 357 358#endif /* CONFIG_PROC_FS */ 359 360static const struct file_operations nvram_fops = { 361 .owner = THIS_MODULE, 362 .llseek = nvram_llseek, 363 .read = nvram_read, 364 .write = nvram_write, 365 .unlocked_ioctl = nvram_ioctl, 366 .open = nvram_open, 367 .release = nvram_release, 368}; 369 370static struct miscdevice nvram_dev = { 371 NVRAM_MINOR, 372 "nvram", 373 &nvram_fops 374}; 375 376static int __init nvram_init(void) 377{ 378 int ret; 379 380 ret = misc_register(&nvram_dev); 381 if (ret) { 382 printk(KERN_ERR "nvram: can't misc_register on minor=%d\n", 383 NVRAM_MINOR); 384 goto out; 385 } 386 ret = nvram_add_proc_fs(); 387 if (ret) { 388 printk(KERN_ERR "nvram: can't create /proc/driver/nvram\n"); 389 goto outmisc; 390 } 391 ret = 0; 392 printk(KERN_INFO "Non-volatile memory driver v" NVRAM_VERSION "\n"); 393out: 394 return ret; 395outmisc: 396 misc_deregister(&nvram_dev); 397 goto out; 398} 399 400static void __exit nvram_cleanup_module(void) 401{ 402 remove_proc_entry("driver/nvram", NULL); 403 misc_deregister(&nvram_dev); 404} 405 406module_init(nvram_init); 407module_exit(nvram_cleanup_module); 408 | |
409#ifdef CONFIG_PROC_FS 410 411static const char * const floppy_types[] = { 412 "none", "5.25'' 360k", "5.25'' 1.2M", "3.5'' 720k", "3.5'' 1.44M", 413 "3.5'' 2.88M", "3.5'' 2.88M" 414}; 415 416static const char * const gfx_types[] = { --- 61 unchanged lines hidden (view full) --- 478 gfx_types[(nvram[6] >> 4) & 3]); 479 480 seq_printf(seq, "FPU : %sinstalled\n", 481 (nvram[6] & 2) ? "" : "not "); 482 483 return; 484} 485 | 323#ifdef CONFIG_PROC_FS 324 325static const char * const floppy_types[] = { 326 "none", "5.25'' 360k", "5.25'' 1.2M", "3.5'' 720k", "3.5'' 1.44M", 327 "3.5'' 2.88M", "3.5'' 2.88M" 328}; 329 330static const char * const gfx_types[] = { --- 61 unchanged lines hidden (view full) --- 392 gfx_types[(nvram[6] >> 4) & 3]); 393 394 seq_printf(seq, "FPU : %sinstalled\n", 395 (nvram[6] & 2) ? "" : "not "); 396 397 return; 398} 399 |
400static int nvram_proc_read(struct seq_file *seq, void *offset) 401{ 402 unsigned char contents[NVRAM_BYTES]; 403 int i = 0; 404 405 spin_lock_irq(&rtc_lock); 406 for (i = 0; i < NVRAM_BYTES; ++i) 407 contents[i] = __nvram_read_byte(i); 408 spin_unlock_irq(&rtc_lock); 409 410 pc_nvram_proc_read(contents, seq, offset); 411 412 return 0; 413} |
|
486#endif /* CONFIG_PROC_FS */ 487 | 414#endif /* CONFIG_PROC_FS */ 415 |
416static const struct file_operations nvram_misc_fops = { 417 .owner = THIS_MODULE, 418 .llseek = nvram_misc_llseek, 419 .read = nvram_misc_read, 420 .write = nvram_misc_write, 421 .unlocked_ioctl = nvram_misc_ioctl, 422 .open = nvram_misc_open, 423 .release = nvram_misc_release, 424}; 425 426static struct miscdevice nvram_misc = { 427 NVRAM_MINOR, 428 "nvram", 429 &nvram_misc_fops, 430}; 431 432static int __init nvram_module_init(void) 433{ 434 int ret; 435 436 ret = misc_register(&nvram_misc); 437 if (ret) { 438 pr_err("nvram: can't misc_register on minor=%d\n", NVRAM_MINOR); 439 return ret; 440 } 441 442#ifdef CONFIG_PROC_FS 443 if (!proc_create_single("driver/nvram", 0, NULL, nvram_proc_read)) { 444 pr_err("nvram: can't create /proc/driver/nvram\n"); 445 misc_deregister(&nvram_misc); 446 return -ENOMEM; 447 } 448#endif 449 450 pr_info("Non-volatile memory driver v" NVRAM_VERSION "\n"); 451 return 0; 452} 453 454static void __exit nvram_module_exit(void) 455{ 456#ifdef CONFIG_PROC_FS 457 remove_proc_entry("driver/nvram", NULL); 458#endif 459 misc_deregister(&nvram_misc); 460} 461 462module_init(nvram_module_init); 463module_exit(nvram_module_exit); 464 |
|
488MODULE_LICENSE("GPL"); 489MODULE_ALIAS_MISCDEV(NVRAM_MINOR); | 465MODULE_LICENSE("GPL"); 466MODULE_ALIAS_MISCDEV(NVRAM_MINOR); |