2 * NVRAM variable manipulation (Linux kernel half)
4 * Copyright 2006, Broadcom Corporation
7 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
8 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
9 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
10 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
14 #include <linux/config.h>
15 #include <linux/init.h>
16 #include <linux/module.h>
17 #include <linux/kernel.h>
18 #include <linux/string.h>
19 #include <linux/interrupt.h>
20 #include <linux/spinlock.h>
21 #include <linux/slab.h>
22 #include <linux/bootmem.h>
24 #include <linux/miscdevice.h>
25 #include <linux/mtd/mtd.h>
26 #include <asm/addrspace.h>
28 #include <asm/uaccess.h>
32 #include <bcmendian.h>
37 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
40 #include <linux/wrapper.h>
45 #include <linux/vmalloc.h>
47 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
48 #include <asm/cacheflush.h>
51 #include <linux/nls.h>
53 /* This isn't right, but I can't figure out how to make the link error go away. */
54 #define flush_cache_all() do { hndcrc8(nvram_buf, sizeof(nvram_buf), 0); hndcrc8(nvram_buf, sizeof(nvram_buf), 0); } while (0)
58 MODULE_LICENSE("GPL");
62 static int hdr_valid(struct nvram_header
*header
, int max
);
64 /* In BSS to minimize text size and page aligned so it can be mmap()-ed */
66 * In early... as nvram (read) staging buffer.
67 * In normal.. to hold the values of items.
69 char nvram_buf
[NVRAM_VAL_SIZE
] __attribute__((aligned(PAGE_SIZE
)));
71 /* This is the staging buffer for data going to/from the flash.
72 * Also as work buffer for compactify.
73 * It is large enough to hold all the NVRAM data and is 1 or more EBs is size.
74 * The first chunk (before the nvram areaa) in the flash eb is preserved. */
75 unsigned char *nvram_commit_buf
= NULL
;
76 static int erasesize
; /* The size of flash eraseblock & commit_buf.
77 * 32KB rounded up to mtd->erasesise. (64KB or 128KB) */
79 int oflow_area_present
= 0;
81 /* The nvram area is the last 32KB (or 60kb for E3000) of the last eraseblock of the flash chip.
82 * Normally this is the mtdN partition named "nvram".
83 * Normally this paritition is the entire last eraseblock. Do "cat /proc/mtd" to see this.
84 * The first part of the last EB, from the start up to the NVRAM area, is
85 * not used by pmon/cfe.
86 * We use the next-to-last 32kb for overflow (extended) nvram area. On a
87 * smallish flash chip these 2 areas are the entire EB. Some larger routers
88 * have 128KB EB size, and on these the 1st 64KB of the last EB is unused.
90 * The implementation of this code is one main area of 32KB and one oflow area
91 * of 32KB, for a total available nvram of 64KB.
94 * Some routers have pmon/cfe that uses 60KB for nvram. On these, there is no
95 * overflow area. The total nvram area of these is 60kb.
99 #if NVRAM_SPACE != (32 * 1024)
100 #error Attempt to redefine NVRAM_SPACE to something other than 32K.
103 /* This is the size of pmon/cfe (and for us: "main") nvram area.
104 * Normally 32kb, but a few routers it is 60kb.
106 int nvram_space
= NVRAM_32K
; /* Determined at probe time. */
108 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
109 #define MTD_ERASE(mtd, args...) (*(mtd->erase))(mtd, args)
110 #define MTD_READ(mtd, args...) (*(mtd->read))(mtd, args)
111 #define MTD_WRITE(mtd, args...) (*(mtd->write))(mtd, args)
113 #define mem_map_reserve(a) SetPageReserved(a)
114 #define mem_map_unreserve(a) ClearPageReserved(a)
116 #define bcm947xx_sbh bcm947xx_sih
117 extern void *bcm947xx_sih
;
119 #define sb_setcore si_setcore
120 #define SB_CC CC_CORE_ID
121 #define SB_FLASH2_SZ SI_FLASH2_SZ
122 #define SB_FLASH1_SZ SI_FLASH1_SZ
123 #define SB_FLASH1 SI_FLASH1
124 #define SB_FLASH2 SI_FLASH2
125 #define SB_BUS SI_BUS
126 #define sb_setosh si_setosh
127 #define sb_memc_get_ncdl si_memc_get_ncdl
129 #define sih bcm947xx_sih
134 nvram_valid(struct nvram_header
*header
)
137 header
->magic
== NVRAM_MAGIC
&&
138 header
->len
>= sizeof(struct nvram_header
) &&
139 header
->len
<= NVRAM_SPACE
&&
141 1; /* oleg -- no crc check for now */
143 (header
->crc_ver_init
& 255) ==
144 hndcrc8((char *) header
+ NVRAM_CRC_START_POSITION
,
145 header
->len
- NVRAM_CRC_START_POSITION
, CRC8_INIT_VALUE
);
152 #define early_nvram_get(name) nvram_get(name)
153 #define early_nvram_getall(name,c) _nvram_getall(name,c)
154 extern void *bcm947xx_sbh
;
155 #define sbh bcm947xx_sbh
156 #define sbh_lock bcm947xx_sbh_lock
158 #define NVR_DEVNAME "nvram2"
162 #define NVR_DEVNAME "nvram"
165 /* Global SB handle */
166 extern void *bcm947xx_sbh
;
167 extern spinlock_t bcm947xx_sbh_lock
;
170 #define sbh bcm947xx_sbh
171 #define sbh_lock bcm947xx_sbh_lock
173 /* Early (before mm or mtd) read-only access to NVRAM */
174 /* Probe for NVRAM header */
176 early_nvram_init(void)
178 struct nvram_header
*header
;
180 struct sflash
*info
= NULL
;
183 uint32 base
, off
, lim
;
186 if ((cc
= sb_setcore(sbh
, SB_CC
, 0)) != NULL
) {
187 base
= KSEG1ADDR(SB_FLASH2
);
188 switch (readl(&cc
->capabilities
) & CC_CAP_FLASH_MASK
) {
195 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
196 if ((info
= sflash_init(sih
, cc
)) == NULL
)
199 if ((info
= sflash_init(cc
)) == NULL
)
210 /* extif assumed, Stop at 4 MB */
211 base
= KSEG1ADDR(SB_FLASH1
);
215 /* XXX: hack for supporting the CFE environment stuff on WGT634U */
216 src
= (u32
*) KSEG1ADDR(base
+ 8 * 1024 * 1024 - 0x2000);
217 dst
= (u32
*) nvram_buf
;
218 if ((lim
== 0x02000000) && ((*src
& 0xff00ff) == 0x000001)) {
219 printk("early_nvram_init: WGT634U NVRAM found.\n");
221 for (i
= 0; i
< 0x1ff0; i
++) {
222 if (*src
== 0xFFFFFFFF)
231 /* Windowed flash access */
233 header
= (struct nvram_header
*) KSEG1ADDR(base
+ off
- NVRAM_32K
);
234 if (hdr_valid(header
, NVRAM_32K
))
237 header
= (struct nvram_header
*) KSEG1ADDR(base
+ off
- (NVRAM_32K
+ 28 KB
));
238 if (hdr_valid(header
, NVRAM_32K
+ 28 KB
))
243 printk("Probing didn't find nvram, assuming 32K.\n");
245 /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */
246 header
= (struct nvram_header
*) KSEG1ADDR(base
+ 4 KB
);
247 if (header
->magic
== NVRAM_MAGIC
)
250 header
= (struct nvram_header
*) KSEG1ADDR(base
+ 1 KB
);
251 if (header
->magic
== NVRAM_MAGIC
)
254 printk("early_nvram_init: NVRAM not found\n");
258 src
= (u32
*) header
;
259 dst
= (u32
*) nvram_buf
;
260 nvram_space
= 64 KB
- j
;
261 printk("early_nvram_init detected %d KB NVRAM area\n", nvram_space
/1024);
262 bzero(nvram_buf
, sizeof(nvram_buf
));
263 for (i
= 0; i
< sizeof(struct nvram_header
); i
+= 4)
265 for (; i
< header
->len
&& i
< nvram_space
; i
+= 4)
269 /* Early (before mm or mtd) read-only access to NVRAM */
271 early_nvram_get(const char *name
)
273 char *var
, *value
, *end
, *eq
;
285 /* Look for name=value and return value */
286 var
= &nvram_buf
[sizeof(struct nvram_header
)];
287 end
= nvram_buf
+ sizeof(nvram_buf
) - 2;
288 end
[0] = end
[1] = '\0';
289 for (; *var
; var
= value
+ strlen(value
) + 1) {
290 if (!(eq
= strchr(var
, '=')))
293 if ((eq
- var
) == strlen(name
) && strncmp(var
, name
, (eq
- var
)) == 0)
301 early_nvram_getall(char *buf
, int count
)
315 /* Write name=value\0 ... \0\0 */
316 var
= &nvram_buf
[sizeof(struct nvram_header
)];
317 end
= nvram_buf
+ sizeof(nvram_buf
) - 2;
318 end
[0] = end
[1] = '\0';
319 for (; *var
; var
+= strlen(var
) + 1) {
320 if ((count
- len
) <= (strlen(var
) + 1))
322 len
+= sprintf(buf
+ len
, "%s", var
) + 1;
329 extern char * _nvram_get(const char *name
);
330 extern int _nvram_set(const char *name
, const char *value
);
331 extern int _nvram_unset(const char *name
);
332 extern int _nvram_getall(char *buf
, int count
);
333 extern int _nvram_commit(struct nvram_header
*header
);
334 extern int _nvram_init(void *sbh
);
335 extern void _nvram_exit(void);
338 static spinlock_t nvram_lock
= SPIN_LOCK_UNLOCKED
;
339 static struct semaphore nvram_sem
;
340 static int nvram_major
= -1;
341 static struct mtd_info
*nvram_mtd
= NULL
;
342 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
343 static struct class *nvram_class
= NULL
;
345 static devfs_handle_t nvram_handle
= NULL
;
349 hdr_valid(struct nvram_header
*header
, int max
)
351 return (header
->magic
== NVRAM_MAGIC
&&
352 header
->len
>= sizeof(struct nvram_header
) &&
353 header
->len
<= max
&&
354 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
355 (nvram_calc_crc(header
) == (uint8
) header
->crc_ver_init
));
357 (header
->crc_ver_init
& 255) ==
358 hndcrc8((char *) header
+ NVRAM_CRC_START_POSITION
,
359 header
->len
- NVRAM_CRC_START_POSITION
, CRC8_INIT_VALUE
);
365 _nvram_read(char *buf
)
367 struct nvram_header
*header
= (struct nvram_header
*) buf
;
371 MTD_READ(nvram_mtd
, nvram_mtd
->size
- nvram_space
, nvram_space
, &len
, buf
) ||
372 len
!= nvram_space
||
373 !nvram_valid(header
)) {
374 printk("_nvram_read: invalid nvram image\n");
375 /* Maybe we can recover some data from early initialization */
376 memcpy(buf
, nvram_buf
, nvram_space
);
383 /* Read the entire /dev/nvram block. Works only if EB is >= 32KB.
384 * Uses the beginning of commit_buf.
385 * Returns: < 0 for error.
386 * >= 0 -- offset into nvram_commit_buf of the NVRAM header.
387 * N.B., nvram_commit_buf[] has the last 64KB of the flash nvram partition.
390 _nvram_init_read(void)
395 struct nvram_header
*header
;
396 u_int32_t offset
; /* fseek position of the last EB in the /mtd/nvram partition. */
400 printk("nvram_init: NVRAM not found\n");
404 oflow_area_present
= 0;
405 if (erasesize
< 2 * NVRAM_32K
)
409 /* seek offset to the last 64KB. Normally 0. 64k on 128k EB size. */
410 offset
= nvram_mtd
->size
- i
;
412 /* Read the last 64kb of flash */
413 ret
= MTD_READ(nvram_mtd
, offset
, i
, &len
, nvram_commit_buf
);
414 if (ret
|| len
!= i
) {
415 printk("nvram_init: read error ret = %d, len = %d/%d\n", ret
, len
, i
);
418 /* Probe various spots to find the header. Every 4K down from 32K from the end.*/
419 for (j
= 32 KB
; j
>= 0 ; j
-= 4 KB
) {
420 header
= (struct nvram_header
*)(nvram_commit_buf
+ j
);
421 if (hdr_valid(header
, 64 KB
- j
))
425 printk("Probing found nvram header at %dK, size %dK\n", (j
)/1024, (64 KB
- j
)/1024);
427 printk("Probing didn't find nvram header. Assuming 32K\n");
430 nvram_space
= 64 KB
- j
;
435 /* Called in early initialization. */
437 nvram_init(void *sbh
)
443 nvram_set(const char *name
, const char *value
)
448 spin_lock_irqsave(&nvram_lock
, flags
);
449 ret
= _nvram_set(name
, value
);
450 spin_unlock_irqrestore(&nvram_lock
, flags
);
456 real_nvram_get(const char *name
)
461 spin_lock_irqsave(&nvram_lock
, flags
);
462 value
= _nvram_get(name
);
463 spin_unlock_irqrestore(&nvram_lock
, flags
);
469 nvram_get(const char *name
)
471 if (nvram_major
>= 0)
472 return real_nvram_get(name
);
474 return early_nvram_get(name
);
478 nvram_unset(const char *name
)
483 spin_lock_irqsave(&nvram_lock
, flags
);
484 ret
= _nvram_unset(name
);
485 spin_unlock_irqrestore(&nvram_lock
, flags
);
491 erase_callback(struct erase_info
*done
)
493 wait_queue_head_t
*wait_q
= (wait_queue_head_t
*) done
->priv
;
500 size_t erasesize
, len
, magic_len
;
503 struct nvram_header
*header
;
506 DECLARE_WAITQUEUE(wait
, current
);
507 wait_queue_head_t wait_q
;
508 struct erase_info erase
;
509 u_int32_t magic_offset
= 0; /* Offset for writing MAGIC # */
512 printk("nvram_commit: NVRAM not found\n");
516 if (in_interrupt()) {
517 printk("nvram_commit: not committing in interrupt\n");
521 /* Backup sector blocks to be erased */
522 erasesize
= ROUNDUP(nvram_space
, nvram_mtd
->erasesize
);
526 //_nvram_commit(nvram_commit_buf); ret = -ENODEV; goto done; //temp!!!
528 if ((i
= erasesize
- nvram_space
) > 0) {
529 offset
= nvram_mtd
->size
- erasesize
;
531 ret
= MTD_READ(nvram_mtd
, offset
, i
, &len
, nvram_commit_buf
);
532 if (ret
|| len
!= i
) {
533 printk("nvram_commit: read error ret = %d, len = %d/%d\n", ret
, len
, i
);
539 offset
= nvram_mtd
->size
- nvram_space
;
542 header
= (struct nvram_header
*)(nvram_commit_buf
+ i
);
543 magic_offset
= i
+ offsetof(struct nvram_header
, magic
);
545 /* clear the existing magic # to mark the NVRAM as unusable
546 * we can pull MAGIC bits low without erase
548 header
->magic
= NVRAM_CLEAR_MAGIC
; /* All zeros magic */
550 /* Unlock sector blocks (for Intel 28F320C3B flash) , 20060309 */
551 if (nvram_mtd
->unlock
)
552 nvram_mtd
->unlock(nvram_mtd
, offset
, nvram_mtd
->erasesize
);
554 ret
= MTD_WRITE(nvram_mtd
, offset
+ magic_offset
, sizeof(header
->magic
),
555 &magic_len
, (char *)&header
->magic
);
556 if (ret
|| magic_len
!= sizeof(header
->magic
)) {
557 printk("nvram_commit: clear MAGIC error\n");
562 /* reset MAGIC before we regenerate the NVRAM,
563 * otherwise we'll have an incorrect CRC
565 header
->magic
= NVRAM_MAGIC
;
566 /* Regenerate NVRAM */
567 spin_lock_irqsave(&nvram_lock
, flags
);
568 ret
= _nvram_commit(header
);
569 spin_unlock_irqrestore(&nvram_lock
, flags
);
573 /* Erase sector blocks */
574 init_waitqueue_head(&wait_q
);
575 for (; offset
< nvram_mtd
->size
- nvram_space
+ header
->len
; offset
+= nvram_mtd
->erasesize
) {
576 erase
.mtd
= nvram_mtd
;
578 erase
.len
= nvram_mtd
->erasesize
;
579 erase
.callback
= erase_callback
;
580 erase
.priv
= (u_long
) &wait_q
;
582 set_current_state(TASK_INTERRUPTIBLE
);
583 add_wait_queue(&wait_q
, &wait
);
585 /* Unlock sector blocks */
586 if (nvram_mtd
->unlock
)
587 nvram_mtd
->unlock(nvram_mtd
, offset
, nvram_mtd
->erasesize
);
589 if ((ret
= MTD_ERASE(nvram_mtd
, &erase
))) {
590 set_current_state(TASK_RUNNING
);
591 remove_wait_queue(&wait_q
, &wait
);
592 printk("nvram_commit: erase error\n");
596 /* Wait for erase to finish */
598 remove_wait_queue(&wait_q
, &wait
);
601 /* Write partition up to end of data area */
602 header
->magic
= NVRAM_INVALID_MAGIC
; /* All ones magic */
603 offset
= nvram_mtd
->size
- erasesize
;
604 i
= erasesize
- nvram_space
+ header
->len
;
605 ret
= MTD_WRITE(nvram_mtd
, offset
, i
, &len
, nvram_commit_buf
);
606 if (ret
|| len
!= i
) {
607 printk("nvram_commit: write error\n");
612 /* Now mark the NVRAM in flash as "valid" by setting the correct MAGIC # */
613 header
->magic
= NVRAM_MAGIC
;
614 ret
= MTD_WRITE(nvram_mtd
, offset
+ magic_offset
, sizeof(header
->magic
),
615 &magic_len
, (char *)&header
->magic
);
616 if (ret
|| magic_len
!= sizeof(header
->magic
)) {
617 printk("nvram_commit: write MAGIC error\n");
623 * Reading a few bytes back here will put the device
624 * back to the correct mode on certain flashes
626 offset
= nvram_mtd
->size
- erasesize
;
627 ret
= MTD_READ(nvram_mtd
, offset
, 4, &len
, nvram_commit_buf
);
635 nvram_getall(char *buf
, int count
)
640 spin_lock_irqsave(&nvram_lock
, flags
);
641 if (nvram_major
>= 0)
642 ret
= _nvram_getall(buf
, count
);
644 ret
= early_nvram_getall(buf
, count
);
645 spin_unlock_irqrestore(&nvram_lock
, flags
);
651 EXPORT_SYMBOL(nvram_get
);
652 EXPORT_SYMBOL(nvram_getall
);
653 EXPORT_SYMBOL(nvram_set
);
654 EXPORT_SYMBOL(nvram_unset
);
655 EXPORT_SYMBOL(nvram_commit
);
658 /* User mode interface below */
661 dev_nvram_read(struct file
*file
, char *buf
, size_t count
, loff_t
*ppos
)
663 char tmp
[100], *name
= tmp
, *value
;
667 if (count
> sizeof(tmp
)) {
668 if (!(name
= kmalloc(count
, GFP_KERNEL
)))
672 if (copy_from_user(name
, buf
, count
)) {
678 /* Get all variables */
679 ret
= nvram_getall(name
, count
);
681 if (copy_to_user(buf
, name
, count
)) {
688 if (!(value
= nvram_get(name
))) {
693 /* Provide the offset into mmap() space */
694 off
= (unsigned long) value
- (unsigned long) nvram_buf
;
696 if (put_user(off
, (unsigned long *) buf
)) {
701 ret
= sizeof(char *);
714 dev_nvram_write(struct file
*file
, const char *buf
, size_t count
, loff_t
*ppos
)
716 char tmp
[100], *name
= tmp
, *value
;
719 if (count
> sizeof(tmp
)) {
720 if (!(name
= kmalloc(count
, GFP_KERNEL
)))
724 if (copy_from_user(name
, buf
, count
)) {
730 name
= strsep(&value
, "=");
732 ret
= nvram_set(name
, value
) ? : count
;
734 ret
= nvram_unset(name
) ? : count
;
744 dev_nvram_ioctl(struct inode
*inode
, struct file
*file
, unsigned int cmd
, unsigned long arg
)
746 if (cmd
!= NVRAM_MAGIC
)
749 return nvram_commit();
753 /* This maps the vmalloced module buffer to user space. */
755 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
756 static int do_vm_mmap(struct vm_area_struct
*vma
, char *adr
, unsigned long siz
)
758 unsigned int start
= vma
->vm_start
;
763 pfn
= vmalloc_to_pfn(adr
);
764 if ((ret
= remap_pfn_range(vma
, start
, pfn
, PAGE_SIZE
, PAGE_READONLY
)) < 0) {
776 /* From bttv-driver.c
777 * Here we want the physical address of the memory.
778 * This is used when initializing the contents of the
779 * area and marking the pages as reserved.
781 static inline unsigned long kvirt_to_pa(unsigned long adr
)
785 kva
= (unsigned long)page_address(vmalloc_to_page((void *)adr
));
786 kva
|= adr
& (PAGE_SIZE
-1); /* restore the offset */
790 static int do_vm_mmap(struct vm_area_struct
*vma
, char *adr
, unsigned long siz
)
792 unsigned int start
= vma
->vm_start
;
796 page
= kvirt_to_pa((unsigned long)adr
);
797 if (remap_page_range(start
, page
, PAGE_SIZE
, PAGE_READONLY
))
809 dev_nvram_mmap(struct file
*file
, struct vm_area_struct
*vma
)
811 unsigned long siz
= vma
->vm_end
- vma
->vm_start
;
813 if (siz
> NVRAM_VAL_SIZE
) siz
= NVRAM_VAL_SIZE
;
815 return (do_vm_mmap(vma
, nvram_buf
, siz
));
817 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
818 if (remap_pfn_range(vma
, vma
->vm_start
,
819 __pa(nvram_buf
) >> PAGE_SHIFT
,
820 siz
, vma
->vm_page_prot
))
823 if (remap_page_range(vma
->vm_start
, virt_to_phys(nvram_buf
),
824 siz
, vma
->vm_page_prot
))
832 dev_nvram_open(struct inode
*inode
, struct file
* file
)
839 dev_nvram_release(struct inode
*inode
, struct file
* file
)
845 static struct file_operations dev_nvram_fops
= {
847 open
: dev_nvram_open
,
848 release
: dev_nvram_release
,
849 read
: dev_nvram_read
,
850 write
: dev_nvram_write
,
851 ioctl
: dev_nvram_ioctl
,
860 struct page
*page
, *end
;
862 char *adr
= nvram_buf
;
863 int size
= NVRAM_VAL_SIZE
;
866 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
868 devfs_unregister(nvram_handle
);
870 if (nvram_major
>= 0)
871 devfs_unregister_chrdev(nvram_major
, NVR_DEVNAME
);
874 class_device_destroy(nvram_class
, MKDEV(nvram_major
, NVR_DEVNUM
));
875 class_destroy(nvram_class
);
878 if (nvram_major
>= 0)
879 unregister_chrdev(nvram_major
, NVR_DEVNAME
);
882 put_mtd_device(nvram_mtd
);
885 while ((PAGE_SIZE
<< order
) < NVRAM_VAL_SIZE
)
887 end
= virt_to_page(nvram_buf
+ (PAGE_SIZE
<< order
) - 1);
888 for (page
= virt_to_page(nvram_buf
); page
<= end
; page
++)
889 mem_map_unreserve(page
);
892 mem_map_unreserve(vmalloc_to_page((void *)adr
));
898 vfree(nvram_commit_buf
);
909 struct page
*page
, *end
;
911 char *adr
= nvram_buf
;
912 int size
= NVRAM_VAL_SIZE
;
915 //printk("---------------------------------------------------------\n");
916 printk("----nvram loading -----" __DATE__
" " __TIME__
" --------\n");
918 /* Allocate and reserve memory to mmap() */
919 while ((PAGE_SIZE
<< order
) < NVRAM_VAL_SIZE
)
921 end
= virt_to_page(nvram_buf
+ (PAGE_SIZE
<< order
) - 1);
922 for (page
= virt_to_page(nvram_buf
); page
<= end
; page
++)
923 mem_map_reserve(page
);
926 mem_map_reserve(vmalloc_to_page((void *)adr
));
932 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
934 /* Find associated MTD device */
935 for (i
= 0; i
< MAX_MTD_DEVICES
; i
++) {
936 nvram_mtd
= get_mtd_device(NULL
, i
);
938 if (!strcmp(nvram_mtd
->name
, "nvram") &&
939 nvram_mtd
->size
>= NVRAM_32K
)
941 put_mtd_device(nvram_mtd
);
944 if (i
>= MAX_MTD_DEVICES
)
948 /* Initialize hash table lock */
949 spin_lock_init(&nvram_lock
);
951 /* Initialize commit semaphore */
952 init_MUTEX(&nvram_sem
);
954 /* Register char device */
955 if ((nvram_major
= devfs_register_chrdev(0, NVR_DEVNAME
, &dev_nvram_fops
)) < 0) {
960 if (sb_osh(sbh
) == NULL
) {
961 osh
= osl_attach(NULL
, SB_BUS
, FALSE
);
963 printk("Error allocating osh\n");
969 /* Create /dev/nvram handle */
970 nvram_handle
= devfs_register(NULL
, NVR_DEVNAME
, DEVFS_FL_NONE
, nvram_major
, NVR_DEVNUM
,
971 S_IFCHR
| S_IRUSR
| S_IWUSR
| S_IRGRP
, &dev_nvram_fops
, NULL
);
974 #if defined(CONFIG_MTD) || defined(CONFIG_MTD_MODULE)
975 /* Find associated MTD device */
976 for (i
= 0; i
< MAX_MTD_DEVICES
; i
++) {
977 nvram_mtd
= get_mtd_device(NULL
, i
);
978 if (!IS_ERR(nvram_mtd
)) {
979 if (!strcmp(nvram_mtd
->name
, "nvram") &&
980 nvram_mtd
->size
>= NVRAM_32K
) {
983 put_mtd_device(nvram_mtd
);
986 if (i
>= MAX_MTD_DEVICES
)
990 /* Initialize hash table lock */
991 spin_lock_init(&nvram_lock
);
993 /* Initialize commit semaphore */
994 init_MUTEX(&nvram_sem
);
996 /* Register char device */
997 if ((nvram_major
= register_chrdev(0, NVR_DEVNAME
, &dev_nvram_fops
)) < 0) {
1002 if (si_osh(sih
) == NULL
) {
1003 osh
= osl_attach(NULL
, SI_BUS
, FALSE
);
1005 printk("Error allocating osh\n");
1006 unregister_chrdev(nvram_major
, NVR_DEVNAME
);
1009 si_setosh(sih
, osh
);
1012 /* Create /dev/nvram handle */
1013 nvram_class
= class_create(THIS_MODULE
, NVR_DEVNAME
);
1014 if (IS_ERR(nvram_class
)) {
1015 printk("Error creating nvram class\n");
1019 /* Add the device nvram0 */
1020 class_device_create(nvram_class
, NULL
, MKDEV(nvram_major
, NVR_DEVNUM
), NULL
, NVR_DEVNAME
);
1023 /* reserve commit read buffer */
1024 /* Backup sector blocks to be erased */
1025 erasesize
= ROUNDUP(NVRAM_VAL_SIZE
, nvram_mtd
->erasesize
);
1026 if (!(nvram_commit_buf
= vmalloc(erasesize
))) {
1027 printk("dev_nvram_init: nvram_commit_buf out of memory\n");
1031 /* Initialize the in-memory database */
1034 /* Set the SDRAM NCDL value into NVRAM if not already done */
1035 if (getintvar(NULL
, "sdram_ncdl") == 0) {
1039 if ((ncdl
= sb_memc_get_ncdl(sbh
))) {
1040 sprintf(buf
, "0x%08x", ncdl
);
1041 nvram_set("sdram_ncdl", buf
);
1052 module_init(dev_nvram_init
);
1053 module_exit(dev_nvram_exit
);
1055 /* For the emacs code formatting