[PATCH] nvram - add Cobalt support

From: Tim Hockin (thockin@sun.com)
Date: Mon Aug 05 2002 - 21:50:10 EST


This patch adds support for Cobalt systems to the nvram driver. In the
process, the nvram symbols were exported, and a few other minor cleanup
went in. This iwll soon be available through bk, but I thought I'd
solicit any gripes before I push it up. :)

This is another in a series of patches trying desperately to get our
tree synced :). If it all looks ok, I'll ask Marcelo and Linus to pull it.

Tim

-- 
Tim Hockin
Systems Software Engineer
Sun Microsystems, Cobalt Server Appliances
thockin@sun.com

# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.582.2.80 -> 1.582.2.81 # include/linux/nvram.h 1.1 -> 1.3 # drivers/char/nvram.c 1.9 -> 1.11 # drivers/char/Makefile 1.18 -> 1.19 # Documentation/Configure.help 1.110 -> 1.111 # (new) -> 1.2 include/linux/cobalt-nvram.h # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 02/08/02 th122948@scl3.sfbay.sun.com 1.582.2.81 # Add Cobalt Networks support to nvram driver # export nvram interfaces # general cleanup of nvram driver # protect nvram state with a lock # fix nvram O_EXCL hack to actually work # -------------------------------------------- # diff -Nru a/Documentation/Configure.help b/Documentation/Configure.help --- a/Documentation/Configure.help Mon Aug 5 18:55:26 2002 +++ b/Documentation/Configure.help Mon Aug 5 18:55:26 2002 @@ -18187,9 +18187,10 @@ CONFIG_NVRAM If you say Y here and create a character special file /dev/nvram with major number 10 and minor number 144 using mknod ("man mknod"), - you get read and write access to the 50 bytes of non-volatile memory - in the real time clock (RTC), which is contained in every PC and - most Ataris. + you get read and write access to the extra bytes of non-volatile + memory in the real time clock (RTC), which is contained in every PC + and most Ataris. The actual number of bytes varies, depending on the + nvram in the system, but is usually 114 (128-14 for the RTC). This memory is conventionally called "CMOS RAM" on PCs and "NVRAM" on Ataris. /dev/nvram may be used to view settings there, or to diff -Nru a/drivers/char/Makefile b/drivers/char/Makefile --- a/drivers/char/Makefile Mon Aug 5 18:55:26 2002 +++ b/drivers/char/Makefile Mon Aug 5 18:55:26 2002 @@ -24,7 +24,7 @@ export-objs := busmouse.o console.o keyboard.o sysrq.o \ misc.o pty.o random.o selection.o serial.o \ sonypi.o tty_io.o tty_ioctl.o generic_serial.o \ - au1000_gpio.o + au1000_gpio.o nvram.o mod-subdirs := joystick ftape drm drm-4.0 pcmcia diff -Nru a/drivers/char/nvram.c b/drivers/char/nvram.c --- a/drivers/char/nvram.c Mon Aug 5 18:55:26 2002 +++ b/drivers/char/nvram.c Mon Aug 5 18:55:26 2002 @@ -3,6 +3,7 @@ * * Copyright (C) 1997 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> * idea by and with help from Richard Jelinek <rj@suse.de> + * Portions copyright (c) 2001,2002 Sun Microsystems (thockin@sun.com) * * This driver allows you to access the contents of the non-volatile memory in * the mc146818rtc.h real-time clock. This chip is built into all PCs and into @@ -10,9 +11,10 @@ * "NVRAM" (NV stands for non-volatile). * * The data are supplied as a (seekable) character device, /dev/nvram. The - * size of this file is 50, the number of freely available bytes in the memory - * (i.e., not used by the RTC itself). - * + * size of this file is dependant on the controller. The usual size is 114, + * the number of freely available bytes in the memory (i.e., not used by the + * RTC itself). + * * Checksums over the NVRAM contents are managed by this driver. In case of a * bad checksum, reads and writes return -EIO. The checksum can be initialized * to a sane state either by ioctl(NVRAM_INIT) (clear whole NVRAM) or @@ -28,25 +30,35 @@ * * 1.1 Cesar Barros: SMP locking fixes * added changelog + * 1.2 Erik Gilling: Cobalt Networks support + * Tim Hockin: general cleanup, Cobalt support */ -#define NVRAM_VERSION "1.1" +#define NVRAM_VERSION "1.2" #include <linux/module.h> #include <linux/config.h> #include <linux/sched.h> #include <linux/smp_lock.h> +#include <linux/nvram.h> #define PC 1 #define ATARI 2 +#define COBALT 3 /* select machine configuration */ #if defined(CONFIG_ATARI) -#define MACH ATARI +# define MACH ATARI #elif defined(__i386__) || defined(__x86_64__) || defined(__arm__) /* and others?? */ #define MACH PC +# if defined(CONFIG_COBALT) +# include <linux/cobalt-nvram.h> +# define MACH COBALT +# else +# define MACH PC +# endif #else -#error Cannot build nvram driver for this machine configuration. +# error Cannot build nvram driver for this machine configuration. #endif #if MACH == PC @@ -58,10 +70,23 @@ #define PC_CKS_RANGE_START 2 #define PC_CKS_RANGE_END 31 #define PC_CKS_LOC 32 +#define NVRAM_BYTES (128-NVRAM_FIRST_BYTE) + +#define mach_check_checksum pc_check_checksum +#define mach_set_checksum pc_set_checksum +#define mach_proc_infos pc_proc_infos + +#endif + +#if MACH == COBALT + +#define CHECK_DRIVER_INIT() 1 + +#define NVRAM_BYTES (128-NVRAM_FIRST_BYTE) -#define mach_check_checksum pc_check_checksum -#define mach_set_checksum pc_set_checksum -#define mach_proc_infos pc_proc_infos +#define mach_check_checksum cobalt_check_checksum +#define mach_set_checksum cobalt_set_checksum +#define mach_proc_infos cobalt_proc_infos #endif @@ -79,9 +104,9 @@ #define ATARI_CKS_RANGE_END 47 #define ATARI_CKS_LOC 48 -#define mach_check_checksum atari_check_checksum -#define mach_set_checksum atari_set_checksum -#define mach_proc_infos atari_proc_infos +#define mach_check_checksum atari_check_checksum +#define mach_set_checksum atari_set_checksum +#define mach_proc_infos atari_proc_infos #endif @@ -98,7 +123,6 @@ #include <linux/ioport.h> #include <linux/fcntl.h> #include <linux/mc146818rtc.h> -#include <linux/nvram.h> #include <linux/init.h> #include <linux/proc_fs.h> #include <linux/spinlock.h> @@ -107,15 +131,11 @@ #include <asm/uaccess.h> #include <asm/system.h> +static spinlock_t nvram_state_lock = SPIN_LOCK_UNLOCKED; static int nvram_open_cnt; /* #times opened */ static int nvram_open_mode; /* special open modes */ - -#define NVRAM_WRITE 1 /* opened for writing (exclusive) */ -#define NVRAM_EXCL 2 /* opened with O_EXCL */ - -#define RTC_FIRST_BYTE 14 /* RTC register number of first - * NVRAM byte */ -#define NVRAM_BYTES 128-RTC_FIRST_BYTE /* number of NVRAM bytes */ +#define NVRAM_WRITE 1 /* opened for writing (exclusive) */ +#define NVRAM_EXCL 2 /* opened with O_EXCL */ static int mach_check_checksum(void); static void mach_set_checksum(void); @@ -126,95 +146,85 @@ #endif /* - * These are the internal NVRAM access functions, which do NOT disable - * interrupts and do not check the checksum. Both tasks are left to higher - * level function, so they need to be done only once per syscall. - */ - -static __inline__ unsigned char -nvram_read_int(int i) -{ - return CMOS_READ(RTC_FIRST_BYTE + i); -} - -static __inline__ void -nvram_write_int(unsigned char c, int i) -{ - CMOS_WRITE(c, RTC_FIRST_BYTE + i); -} - -static __inline__ int -nvram_check_checksum_int(void) -{ - return mach_check_checksum(); -} - -static __inline__ void -nvram_set_checksum_int(void) -{ - mach_set_checksum(); -} - -#if MACH == ATARI - -/* - * These non-internal functions are provided to be called by other parts of + * These functions are provided to be called internally or by other parts of * the kernel. It's up to the caller to ensure correct checksum before reading * or after writing (needs to be done only once). * - * They're only built if CONFIG_ATARI is defined, because Atari drivers use - * them. For other configurations (PC), the rest of the kernel can't rely on - * them being present (this driver may not be configured at all, or as a - * module), so they access config information themselves. + * It is worth noting that these functions all access bytes of general + * purpose memory in the NVRAM - that is to say, they all add the + * NVRAM_FIRST_BYTE offset. Pass them offsets into NVRAM as if you did not + * know about the RTC cruft. */ unsigned char +__nvram_read_byte(int i) +{ + return CMOS_READ(NVRAM_FIRST_BYTE + i); +} + +unsigned char nvram_read_byte(int i) { unsigned long flags; unsigned char c; spin_lock_irqsave(&rtc_lock, flags); - c = nvram_read_int(i); + c = __nvram_read_byte(i); spin_unlock_irqrestore(&rtc_lock, flags); return c; } /* This races nicely with trying to read with checksum checking (nvram_read) */ void +__nvram_write_byte(unsigned char c, int i) +{ + CMOS_WRITE(c, NVRAM_FIRST_BYTE + i); +} + +void nvram_write_byte(unsigned char c, int i) { unsigned long flags; spin_lock_irqsave(&rtc_lock, flags); - nvram_write_int(c, i); + __nvram_write_byte(c, i); spin_unlock_irqrestore(&rtc_lock, flags); } int +__nvram_check_checksum(void) +{ + return mach_check_checksum(); +} + +int nvram_check_checksum(void) { unsigned long flags; int rv; spin_lock_irqsave(&rtc_lock, flags); - rv = nvram_check_checksum_int(); + rv = __nvram_check_checksum(); spin_unlock_irqrestore(&rtc_lock, flags); return rv; } void +__nvram_set_checksum(void) +{ + mach_set_checksum(); +} + +void nvram_set_checksum(void) { unsigned long flags; spin_lock_irqsave(&rtc_lock, flags); - nvram_set_checksum_int(); + __nvram_set_checksum(); spin_unlock_irqrestore(&rtc_lock, flags); } -#endif /* MACH == ATARI */ - /* * The are the file operation function for user access to /dev/nvram */ @@ -239,17 +249,17 @@ static ssize_t nvram_read(struct file *file, char *buf, size_t count, loff_t *ppos) { - char contents[NVRAM_BYTES]; + unsigned char contents[NVRAM_BYTES]; unsigned i = *ppos; - char *tmp; + unsigned char *tmp; spin_lock_irq(&rtc_lock); - if (!nvram_check_checksum_int()) + if (!__nvram_check_checksum()) goto checksum_err; for (tmp = contents; count-- > 0 && i < NVRAM_BYTES; ++i, ++tmp) - *tmp = nvram_read_int(i); + *tmp = __nvram_read_byte(i); spin_unlock_irq(&rtc_lock); @@ -268,23 +278,24 @@ static ssize_t nvram_write(struct file *file, const char *buf, size_t count, loff_t *ppos) { - char contents[NVRAM_BYTES]; + unsigned char contents[NVRAM_BYTES]; unsigned i = *ppos; - char *tmp; + unsigned char *tmp; + int len; - if (copy_from_user(contents, buf, (NVRAM_BYTES - i) < count ? - (NVRAM_BYTES - i) : count)) + len = (NVRAM_BYTES - i) < count ? (NVRAM_BYTES - i) : count; + if (copy_from_user(contents, buf, len)) return -EFAULT; spin_lock_irq(&rtc_lock); - if (!nvram_check_checksum_int()) + if (!__nvram_check_checksum()) goto checksum_err; for (tmp = contents; count-- > 0 && i < NVRAM_BYTES; ++i, ++tmp) - nvram_write_int(*tmp, i); + __nvram_write_byte(*tmp, i); - nvram_set_checksum_int(); + __nvram_set_checksum(); spin_unlock_irq(&rtc_lock); @@ -305,27 +316,28 @@ switch (cmd) { - case NVRAM_INIT: /* initialize NVRAM contents and checksum */ + case NVRAM_INIT: + /* initialize NVRAM contents and checksum */ if (!capable(CAP_SYS_ADMIN)) return -EACCES; spin_lock_irq(&rtc_lock); for (i = 0; i < NVRAM_BYTES; ++i) - nvram_write_int(0, i); - nvram_set_checksum_int(); + __nvram_write_byte(0, i); + __nvram_set_checksum(); spin_unlock_irq(&rtc_lock); return 0; - case NVRAM_SETCKS: /* just set checksum, contents unchanged - * (maybe useful after checksum garbaged - * somehow...) */ + case NVRAM_SETCKS: + /* just set checksum, contents unchanged (maybe useful after + * checksum garbaged somehow...) */ if (!capable(CAP_SYS_ADMIN)) return -EACCES; spin_lock_irq(&rtc_lock); - nvram_set_checksum_int(); + __nvram_set_checksum(); spin_unlock_irq(&rtc_lock); return 0; @@ -337,29 +349,40 @@ static int nvram_open(struct inode *inode, struct file *file) { + spin_lock(&nvram_state_lock); + if ((nvram_open_cnt && (file->f_flags & O_EXCL)) || (nvram_open_mode & NVRAM_EXCL) || - ((file->f_mode & 2) && (nvram_open_mode & NVRAM_WRITE))) + ((file->f_mode & 2) && (nvram_open_mode & NVRAM_WRITE))) { + spin_unlock(&nvram_state_lock); return -EBUSY; + } if (file->f_flags & O_EXCL) nvram_open_mode |= NVRAM_EXCL; if (file->f_mode & 2) nvram_open_mode |= NVRAM_WRITE; nvram_open_cnt++; + + spin_unlock(&nvram_state_lock); + return 0; } static int nvram_release(struct inode *inode, struct file *file) { - lock_kernel(); + spin_lock(&nvram_state_lock); + nvram_open_cnt--; - if (file->f_flags & O_EXCL) + + /* if only one instance is open, clear the EXCL bit */ + if (nvram_open_mode & NVRAM_EXCL) nvram_open_mode &= ~NVRAM_EXCL; if (file->f_mode & 2) nvram_open_mode &= ~NVRAM_WRITE; - unlock_kernel(); + + spin_unlock(&nvram_state_lock); return 0; } @@ -383,7 +406,7 @@ spin_lock_irq(&rtc_lock); for (i = 0; i < NVRAM_BYTES; ++i) - contents[i] = nvram_read_int(i); + contents[i] = __nvram_read_byte(i); spin_unlock_irq(&rtc_lock); *eof = mach_proc_infos(contents, buffer, &len, &begin, offset, size); @@ -397,7 +420,7 @@ /* This macro frees the machine specific function from bounds checking and * this like that... */ -#define PRINT_PROC(fmt,args...) \ +#define PRINT_PROC(fmt,args...) \ do { \ *len += sprintf(buffer+*len, fmt, ##args); \ if (*begin + *len > offset + size) \ @@ -477,11 +500,13 @@ { int i; unsigned short sum = 0; + unsigned short expect; for (i = PC_CKS_RANGE_START; i <= PC_CKS_RANGE_END; ++i) - sum += nvram_read_int(i); - return ((sum & 0xffff) == - ((nvram_read_int(PC_CKS_LOC)<<8) | nvram_read_int(PC_CKS_LOC+1))); + sum += __nvram_read_byte(i); + expect = __nvram_read_byte(PC_CKS_LOC)<<8 | + __nvram_read_byte(PC_CKS_LOC+1); + return ((sum & 0xffff) == expect); } static void @@ -491,9 +516,9 @@ unsigned short sum = 0; for (i = PC_CKS_RANGE_START; i <= PC_CKS_RANGE_END; ++i) - sum += nvram_read_int(i); - nvram_write_int(sum >> 8, PC_CKS_LOC); - nvram_write_int(sum & 0xff, PC_CKS_LOC + 1); + sum += __nvram_read_byte(i); + __nvram_write_byte(sum >> 8, PC_CKS_LOC); + __nvram_write_byte(sum & 0xff, PC_CKS_LOC + 1); } #ifdef CONFIG_PROC_FS @@ -518,7 +543,7 @@ int type; spin_lock_irq(&rtc_lock); - checksum = nvram_check_checksum_int(); + checksum = __nvram_check_checksum(); spin_unlock_irq(&rtc_lock); PRINT_PROC("Checksum status: %svalid\n", checksum ? "" : "not "); @@ -576,6 +601,177 @@ #endif /* MACH == PC */ +#if MACH == COBALT + +/* the cobalt CMOS has a wider range of it's checksum */ +static int cobalt_check_checksum(void) +{ + int i; + unsigned short sum = 0; + unsigned short expect; + + for (i = COBT_CMOS_CKS_START; i <= COBT_CMOS_CKS_END; ++i) { + if ((i == COBT_CMOS_CHECKSUM) || (i == (COBT_CMOS_CHECKSUM+1))) + continue; + + sum += __nvram_read_byte(i); + } + expect = __nvram_read_byte(COBT_CMOS_CHECKSUM) << 8 | + __nvram_read_byte(COBT_CMOS_CHECKSUM+1); + return ((sum & 0xffff) == expect); +} + +static void cobalt_set_checksum(void) +{ + int i; + unsigned short sum = 0; + + for (i = COBT_CMOS_CKS_START; i <= COBT_CMOS_CKS_END; ++i) { + if ((i == COBT_CMOS_CHECKSUM) || (i == (COBT_CMOS_CHECKSUM+1))) + continue; + + sum += __nvram_read_byte(i); + } + + __nvram_write_byte(sum >> 8, COBT_CMOS_CHECKSUM); + __nvram_write_byte(sum & 0xff, COBT_CMOS_CHECKSUM+1); +} + +#ifdef CONFIG_PROC_FS + +static int cobalt_proc_infos(unsigned char *nvram, char *buffer, int *len, + off_t *begin, off_t offset, int size) +{ + int i; + unsigned int checksum; + unsigned int flags; + char sernum[14]; + char *key = "cNoEbTaWlOtR!"; + unsigned char bto_csum; + + spin_lock_irq(&rtc_lock); + checksum = __nvram_check_checksum(); + spin_unlock_irq(&rtc_lock); + + PRINT_PROC("Checksum status: %svalid\n", checksum ? "" : "not "); + + flags = nvram[COBT_CMOS_FLAG_BYTE_0] << 8 + | nvram[COBT_CMOS_FLAG_BYTE_1]; + + PRINT_PROC("Console: %s\n", + flags & COBT_CMOS_CONSOLE_FLAG ? "on": "off"); + + PRINT_PROC("Firmware Debug Messages: %s\n", + flags & COBT_CMOS_DEBUG_FLAG ? "on": "off"); + + PRINT_PROC("Auto Prompt: %s\n", + flags & COBT_CMOS_AUTO_PROMPT_FLAG ? "on": "off"); + + PRINT_PROC("Shutdown Status: %s\n", + flags & COBT_CMOS_CLEAN_BOOT_FLAG ? "clean": "dirty"); + + PRINT_PROC("Hardware Probe: %s\n", + flags & COBT_CMOS_HW_NOPROBE_FLAG ? "partial": "full"); + + PRINT_PROC("System Fault: %sdetected\n", + flags & COBT_CMOS_SYSFAULT_FLAG ? "": "not "); + + PRINT_PROC("Panic on OOPS: %s\n", + flags & COBT_CMOS_OOPSPANIC_FLAG ? "yes": "no"); + + PRINT_PROC("Delayed Cache Initialization: %s\n", + flags & COBT_CMOS_DELAY_CACHE_FLAG ? "yes": "no"); + + PRINT_PROC("Show Logo at Boot: %s\n", + flags & COBT_CMOS_NOLOGO_FLAG ? "no": "yes"); + + PRINT_PROC("Boot Method: "); + switch (nvram[COBT_CMOS_BOOT_METHOD]) { + case COBT_CMOS_BOOT_METHOD_DISK: + PRINT_PROC("disk\n"); + break; + + case COBT_CMOS_BOOT_METHOD_ROM: + PRINT_PROC("rom\n"); + break; + + case COBT_CMOS_BOOT_METHOD_NET: + PRINT_PROC("net\n"); + break; + + default: + PRINT_PROC("unknown\n"); + break; + } + + PRINT_PROC("Primary Boot Device: %d:%d\n", + nvram[COBT_CMOS_BOOT_DEV0_MAJ], + nvram[COBT_CMOS_BOOT_DEV0_MIN] ); + PRINT_PROC("Secondary Boot Device: %d:%d\n", + nvram[COBT_CMOS_BOOT_DEV1_MAJ], + nvram[COBT_CMOS_BOOT_DEV1_MIN] ); + PRINT_PROC("Tertiary Boot Device: %d:%d\n", + nvram[COBT_CMOS_BOOT_DEV2_MAJ], + nvram[COBT_CMOS_BOOT_DEV2_MIN] ); + + PRINT_PROC("Uptime: %d\n", + nvram[COBT_CMOS_UPTIME_0] << 24 | + nvram[COBT_CMOS_UPTIME_1] << 16 | + nvram[COBT_CMOS_UPTIME_2] << 8 | + nvram[COBT_CMOS_UPTIME_3]); + + PRINT_PROC("Boot Count: %d\n", + nvram[COBT_CMOS_BOOTCOUNT_0] << 24 | + nvram[COBT_CMOS_BOOTCOUNT_1] << 16 | + nvram[COBT_CMOS_BOOTCOUNT_2] << 8 | + nvram[COBT_CMOS_BOOTCOUNT_3]); + + /* 13 bytes of serial num */ + for (i=0 ; i<13 ; i++) { + sernum[i] = nvram[COBT_CMOS_SYS_SERNUM_0 + i]; + } + sernum[13] = '\0'; + + checksum = 0; + for (i=0 ; i<13 ; i++) { + checksum += sernum[i] ^ key[i]; + } + checksum = ((checksum & 0x7f) ^ (0xd6)) & 0xff; + + PRINT_PROC("Serial Number: %s", sernum); + if (checksum != nvram[COBT_CMOS_SYS_SERNUM_CSUM]) { + PRINT_PROC(" (invalid checksum)"); + } + PRINT_PROC("\n"); + + PRINT_PROC("Rom Revison: %d.%d.%d\n", nvram[COBT_CMOS_ROM_REV_MAJ], + nvram[COBT_CMOS_ROM_REV_MIN], nvram[COBT_CMOS_ROM_REV_REV]); + + PRINT_PROC("BTO Server: %d.%d.%d.%d", nvram[COBT_CMOS_BTO_IP_0], + nvram[COBT_CMOS_BTO_IP_1], nvram[COBT_CMOS_BTO_IP_2], + nvram[COBT_CMOS_BTO_IP_3]); + bto_csum = nvram[COBT_CMOS_BTO_IP_0] + nvram[COBT_CMOS_BTO_IP_1] + + nvram[COBT_CMOS_BTO_IP_2] + nvram[COBT_CMOS_BTO_IP_3]; + if (bto_csum != nvram[COBT_CMOS_BTO_IP_CSUM]) { + PRINT_PROC(" (invalid checksum)"); + } + PRINT_PROC("\n"); + + if (flags & COBT_CMOS_VERSION_FLAG + && nvram[COBT_CMOS_VERSION] >= COBT_CMOS_VER_BTOCODE) { + PRINT_PROC("BTO Code: 0x%x\n", + nvram[COBT_CMOS_BTO_CODE_0] << 24 | + nvram[COBT_CMOS_BTO_CODE_1] << 16 | + nvram[COBT_CMOS_BTO_CODE_2] << 8 | + nvram[COBT_CMOS_BTO_CODE_3]); + } + + return 1; +} +#endif /* CONFIG_PROC_FS */ + +#endif /* MACH == COBALT */ + #if MACH == ATARI static int @@ -585,9 +781,9 @@ unsigned char sum = 0; for (i = ATARI_CKS_RANGE_START; i <= ATARI_CKS_RANGE_END; ++i) - sum += nvram_read_int(i); - return (nvram_read_int(ATARI_CKS_LOC) == (~sum & 0xff) && - nvram_read_int(ATARI_CKS_LOC + 1) == (sum & 0xff)); + sum += __nvram_read_byte(i); + return (__nvram_read_byte(ATARI_CKS_LOC) == (~sum & 0xff) && + __nvram_read_byte(ATARI_CKS_LOC + 1) == (sum & 0xff)); } static void @@ -597,9 +793,9 @@ unsigned char sum = 0; for (i = ATARI_CKS_RANGE_START; i <= ATARI_CKS_RANGE_END; ++i) - sum += nvram_read_int(i); - nvram_write_int(~sum, ATARI_CKS_LOC); - nvram_write_int(sum, ATARI_CKS_LOC + 1); + sum += __nvram_read_byte(i); + __nvram_write_byte(~sum, ATARI_CKS_LOC); + __nvram_write_byte(sum, ATARI_CKS_LOC + 1); } #ifdef CONFIG_PROC_FS @@ -716,4 +912,11 @@ MODULE_LICENSE("GPL"); -EXPORT_NO_SYMBOLS; +EXPORT_SYMBOL(__nvram_read_byte); +EXPORT_SYMBOL(nvram_read_byte); +EXPORT_SYMBOL(__nvram_write_byte); +EXPORT_SYMBOL(nvram_write_byte); +EXPORT_SYMBOL(__nvram_check_checksum); +EXPORT_SYMBOL(nvram_check_checksum); +EXPORT_SYMBOL(__nvram_set_checksum); +EXPORT_SYMBOL(nvram_set_checksum); diff -Nru a/include/linux/cobalt-nvram.h b/include/linux/cobalt-nvram.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/linux/cobalt-nvram.h Mon Aug 5 18:55:26 2002 @@ -0,0 +1,109 @@ +/* + * $Id: cobalt-nvram.h,v 1.20 2001/10/17 23:16:55 thockin Exp $ + * cobalt-nvram.h : defines for the various fields in the cobalt NVRAM + * + * Copyright 2001,2002 Sun Microsystems, Inc. + */ + +#ifndef COBALT_NVRAM_H +#define COBALT_NVRAM_H + +#include <linux/nvram.h> + +#define COBT_CMOS_INFO_MAX 0x7f /* top address allowed */ +#define COBT_CMOS_BIOS_DRIVE_INFO 0x12 /* drive info would go here */ + +#define COBT_CMOS_CKS_START NVRAM_OFFSET(0x0e) +#define COBT_CMOS_CKS_END NVRAM_OFFSET(0x7f) + +/* flag bytes - 16 flags for now, leave room for more */ +#define COBT_CMOS_FLAG_BYTE_0 NVRAM_OFFSET(0x10) +#define COBT_CMOS_FLAG_BYTE_1 NVRAM_OFFSET(0x11) + +/* flags in flag bytes - up to 16 */ +#define COBT_CMOS_FLAG_MIN 0x0001 +#define COBT_CMOS_CONSOLE_FLAG 0x0001 /* console on/off */ +#define COBT_CMOS_DEBUG_FLAG 0x0002 /* ROM debug messages */ +#define COBT_CMOS_AUTO_PROMPT_FLAG 0x0004 /* boot to ROM prompt? */ +#define COBT_CMOS_CLEAN_BOOT_FLAG 0x0008 /* set by a clean shutdown */ +#define COBT_CMOS_HW_NOPROBE_FLAG 0x0010 /* go easy on the probing */ +#define COBT_CMOS_SYSFAULT_FLAG 0x0020 /* system fault detected */ +#define COBT_CMOS_OOPSPANIC_FLAG 0x0040 /* panic on oops */ +#define COBT_CMOS_DELAY_CACHE_FLAG 0x0080 /* delay cache initialization */ +#define COBT_CMOS_NOLOGO_FLAG 0x0100 /* hide "C" logo @ boot */ +#define COBT_CMOS_VERSION_FLAG 0x0200 /* the version field is valid */ +#define COBT_CMOS_FLAG_MAX 0x0200 + +/* leave byte 0x12 blank - Linux looks for drive info here */ + +/* CMOS structure version, valid if COBT_CMOS_VERSION_FLAG is true */ +#define COBT_CMOS_VERSION NVRAM_OFFSET(0x13) +#define COBT_CMOS_VER_BTOCODE 1 /* min. version needed for btocode */ + +/* index of default boot method */ +#define COBT_CMOS_BOOT_METHOD NVRAM_OFFSET(0x20) +#define COBT_CMOS_BOOT_METHOD_DISK 0 +#define COBT_CMOS_BOOT_METHOD_ROM 1 +#define COBT_CMOS_BOOT_METHOD_NET 2 + +#define COBT_CMOS_BOOT_DEV_MIN NVRAM_OFFSET(0x21) +/* major #, minor # of first through fourth boot device */ +#define COBT_CMOS_BOOT_DEV0_MAJ NVRAM_OFFSET(0x21) +#define COBT_CMOS_BOOT_DEV0_MIN NVRAM_OFFSET(0x22) +#define COBT_CMOS_BOOT_DEV1_MAJ NVRAM_OFFSET(0x23) +#define COBT_CMOS_BOOT_DEV1_MIN NVRAM_OFFSET(0x24) +#define COBT_CMOS_BOOT_DEV2_MAJ NVRAM_OFFSET(0x25) +#define COBT_CMOS_BOOT_DEV2_MIN NVRAM_OFFSET(0x26) +#define COBT_CMOS_BOOT_DEV3_MAJ NVRAM_OFFSET(0x27) +#define COBT_CMOS_BOOT_DEV3_MIN NVRAM_OFFSET(0x28) +#define COBT_CMOS_BOOT_DEV_MAX NVRAM_OFFSET(0x28) + +/* checksum of bytes 0xe-0x7f */ +#define COBT_CMOS_CHECKSUM NVRAM_OFFSET(0x2e) + +/* running uptime counter, units of 5 minutes (32 bits =~ 41000 years) */ +#define COBT_CMOS_UPTIME_0 NVRAM_OFFSET(0x30) +#define COBT_CMOS_UPTIME_1 NVRAM_OFFSET(0x31) +#define COBT_CMOS_UPTIME_2 NVRAM_OFFSET(0x32) +#define COBT_CMOS_UPTIME_3 NVRAM_OFFSET(0x33) + +/* count of successful boots (32 bits) */ +#define COBT_CMOS_BOOTCOUNT_0 NVRAM_OFFSET(0x38) +#define COBT_CMOS_BOOTCOUNT_1 NVRAM_OFFSET(0x39) +#define COBT_CMOS_BOOTCOUNT_2 NVRAM_OFFSET(0x3a) +#define COBT_CMOS_BOOTCOUNT_3 NVRAM_OFFSET(0x3b) + +/* 13 bytes: system serial number, same as on the back of the system */ +#define COBT_CMOS_SYS_SERNUM_LEN 13 +#define COBT_CMOS_SYS_SERNUM_0 NVRAM_OFFSET(0x40) +#define COBT_CMOS_SYS_SERNUM_1 NVRAM_OFFSET(0x41) +#define COBT_CMOS_SYS_SERNUM_2 NVRAM_OFFSET(0x42) +#define COBT_CMOS_SYS_SERNUM_3 NVRAM_OFFSET(0x43) +#define COBT_CMOS_SYS_SERNUM_4 NVRAM_OFFSET(0x44) +#define COBT_CMOS_SYS_SERNUM_5 NVRAM_OFFSET(0x45) +#define COBT_CMOS_SYS_SERNUM_6 NVRAM_OFFSET(0x46) +#define COBT_CMOS_SYS_SERNUM_7 NVRAM_OFFSET(0x47) +#define COBT_CMOS_SYS_SERNUM_8 NVRAM_OFFSET(0x48) +#define COBT_CMOS_SYS_SERNUM_9 NVRAM_OFFSET(0x49) +#define COBT_CMOS_SYS_SERNUM_10 NVRAM_OFFSET(0x4a) +#define COBT_CMOS_SYS_SERNUM_11 NVRAM_OFFSET(0x4b) +#define COBT_CMOS_SYS_SERNUM_12 NVRAM_OFFSET(0x4c) +/* checksum for serial num - 1 byte */ +#define COBT_CMOS_SYS_SERNUM_CSUM NVRAM_OFFSET(0x4f) + +#define COBT_CMOS_ROM_REV_MAJ NVRAM_OFFSET(0x50) +#define COBT_CMOS_ROM_REV_MIN NVRAM_OFFSET(0x51) +#define COBT_CMOS_ROM_REV_REV NVRAM_OFFSET(0x52) + +#define COBT_CMOS_BTO_CODE_0 NVRAM_OFFSET(0x53) +#define COBT_CMOS_BTO_CODE_1 NVRAM_OFFSET(0x54) +#define COBT_CMOS_BTO_CODE_2 NVRAM_OFFSET(0x55) +#define COBT_CMOS_BTO_CODE_3 NVRAM_OFFSET(0x56) + +#define COBT_CMOS_BTO_IP_CSUM NVRAM_OFFSET(0x57) +#define COBT_CMOS_BTO_IP_0 NVRAM_OFFSET(0x58) +#define COBT_CMOS_BTO_IP_1 NVRAM_OFFSET(0x59) +#define COBT_CMOS_BTO_IP_2 NVRAM_OFFSET(0x5a) +#define COBT_CMOS_BTO_IP_3 NVRAM_OFFSET(0x5b) + +#endif /* COBALT_NVRAM_H */ diff -Nru a/include/linux/nvram.h b/include/linux/nvram.h --- a/include/linux/nvram.h Mon Aug 5 18:55:26 2002 +++ b/include/linux/nvram.h Mon Aug 5 18:55:26 2002 @@ -4,14 +4,24 @@ #include <linux/ioctl.h> /* /dev/nvram ioctls */ -#define NVRAM_INIT _IO('p', 0x40) /* initialize NVRAM and set checksum */ -#define NVRAM_SETCKS _IO('p', 0x41) /* recalculate checksum */ +#define NVRAM_INIT _IO('p', 0x40) /* initialize NVRAM and set checksum */ +#define NVRAM_SETCKS _IO('p', 0x41) /* recalculate checksum */ + +/* for all current systems, this is where NVRAM starts */ +#define NVRAM_FIRST_BYTE 14 +/* all these functions expect an NVRAM offset, not an absolute */ +#define NVRAM_OFFSET(x) ((x)-NVRAM_FIRST_BYTE) #ifdef __KERNEL__ -extern unsigned char nvram_read_byte( int i ); -extern void nvram_write_byte( unsigned char c, int i ); -extern int nvram_check_checksum( void ); -extern void nvram_set_checksum( void ); +/* __foo is foo without grabbing the rtc_lock - get it yourself */ +extern unsigned char __nvram_read_byte(int i); +extern unsigned char nvram_read_byte(int i); +extern void __nvram_write_byte(unsigned char c, int i); +extern void nvram_write_byte(unsigned char c, int i); +extern int __nvram_check_checksum(void); +extern int nvram_check_checksum(void); +extern void __nvram_set_checksum(void); +extern void nvram_set_checksum(void); #endif #endif /* _LINUX_NVRAM_H */

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Wed Aug 07 2002 - 22:00:29 EST