diff options
Diffstat (limited to 'drivers/char/nvram.c')
| -rw-r--r-- | drivers/char/nvram.c | 110 |
1 files changed, 109 insertions, 1 deletions
diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c index 1af733d07321..9e24bbd4090c 100644 --- a/drivers/char/nvram.c +++ b/drivers/char/nvram.c | |||
| @@ -32,9 +32,11 @@ | |||
| 32 | * added changelog | 32 | * added changelog |
| 33 | * 1.2 Erik Gilling: Cobalt Networks support | 33 | * 1.2 Erik Gilling: Cobalt Networks support |
| 34 | * Tim Hockin: general cleanup, Cobalt support | 34 | * Tim Hockin: general cleanup, Cobalt support |
| 35 | * 1.3 Jon Ringle: Comdial MP1000 support | ||
| 36 | * | ||
| 35 | */ | 37 | */ |
| 36 | 38 | ||
| 37 | #define NVRAM_VERSION "1.2" | 39 | #define NVRAM_VERSION "1.3" |
| 38 | 40 | ||
| 39 | #include <linux/module.h> | 41 | #include <linux/module.h> |
| 40 | #include <linux/config.h> | 42 | #include <linux/config.h> |
| @@ -45,6 +47,7 @@ | |||
| 45 | #define PC 1 | 47 | #define PC 1 |
| 46 | #define ATARI 2 | 48 | #define ATARI 2 |
| 47 | #define COBALT 3 | 49 | #define COBALT 3 |
| 50 | #define MP1000 4 | ||
| 48 | 51 | ||
| 49 | /* select machine configuration */ | 52 | /* select machine configuration */ |
| 50 | #if defined(CONFIG_ATARI) | 53 | #if defined(CONFIG_ATARI) |
| @@ -54,6 +57,9 @@ | |||
| 54 | # if defined(CONFIG_COBALT) | 57 | # if defined(CONFIG_COBALT) |
| 55 | # include <linux/cobalt-nvram.h> | 58 | # include <linux/cobalt-nvram.h> |
| 56 | # define MACH COBALT | 59 | # define MACH COBALT |
| 60 | # elif defined(CONFIG_MACH_MP1000) | ||
| 61 | # undef MACH | ||
| 62 | # define MACH MP1000 | ||
| 57 | # else | 63 | # else |
| 58 | # define MACH PC | 64 | # define MACH PC |
| 59 | # endif | 65 | # endif |
| @@ -112,6 +118,23 @@ | |||
| 112 | 118 | ||
| 113 | #endif | 119 | #endif |
| 114 | 120 | ||
| 121 | #if MACH == MP1000 | ||
| 122 | |||
| 123 | /* RTC in a MP1000 */ | ||
| 124 | #define CHECK_DRIVER_INIT() 1 | ||
| 125 | |||
| 126 | #define MP1000_CKS_RANGE_START 0 | ||
| 127 | #define MP1000_CKS_RANGE_END 111 | ||
| 128 | #define MP1000_CKS_LOC 112 | ||
| 129 | |||
| 130 | #define NVRAM_BYTES (128-NVRAM_FIRST_BYTE) | ||
| 131 | |||
| 132 | #define mach_check_checksum mp1000_check_checksum | ||
| 133 | #define mach_set_checksum mp1000_set_checksum | ||
| 134 | #define mach_proc_infos mp1000_proc_infos | ||
| 135 | |||
| 136 | #endif | ||
| 137 | |||
| 115 | /* Note that *all* calls to CMOS_READ and CMOS_WRITE must be done with | 138 | /* Note that *all* calls to CMOS_READ and CMOS_WRITE must be done with |
| 116 | * rtc_lock held. Due to the index-port/data-port design of the RTC, we | 139 | * rtc_lock held. Due to the index-port/data-port design of the RTC, we |
| 117 | * don't want two different things trying to get to it at once. (e.g. the | 140 | * don't want two different things trying to get to it at once. (e.g. the |
| @@ -915,6 +938,91 @@ atari_proc_infos(unsigned char *nvram, char *buffer, int *len, | |||
| 915 | 938 | ||
| 916 | #endif /* MACH == ATARI */ | 939 | #endif /* MACH == ATARI */ |
| 917 | 940 | ||
| 941 | #if MACH == MP1000 | ||
| 942 | |||
| 943 | static int | ||
| 944 | mp1000_check_checksum(void) | ||
| 945 | { | ||
| 946 | int i; | ||
| 947 | unsigned short sum = 0; | ||
| 948 | unsigned short expect; | ||
| 949 | |||
| 950 | for (i = MP1000_CKS_RANGE_START; i <= MP1000_CKS_RANGE_END; ++i) | ||
| 951 | sum += __nvram_read_byte(i); | ||
| 952 | |||
| 953 | expect = __nvram_read_byte(MP1000_CKS_LOC+1)<<8 | | ||
| 954 | __nvram_read_byte(MP1000_CKS_LOC); | ||
| 955 | return ((sum & 0xffff) == expect); | ||
| 956 | } | ||
| 957 | |||
| 958 | static void | ||
| 959 | mp1000_set_checksum(void) | ||
| 960 | { | ||
| 961 | int i; | ||
| 962 | unsigned short sum = 0; | ||
| 963 | |||
| 964 | for (i = MP1000_CKS_RANGE_START; i <= MP1000_CKS_RANGE_END; ++i) | ||
| 965 | sum += __nvram_read_byte(i); | ||
| 966 | __nvram_write_byte(sum >> 8, MP1000_CKS_LOC + 1); | ||
| 967 | __nvram_write_byte(sum & 0xff, MP1000_CKS_LOC); | ||
| 968 | } | ||
| 969 | |||
| 970 | #ifdef CONFIG_PROC_FS | ||
| 971 | |||
| 972 | #define SERVER_N_LEN 32 | ||
| 973 | #define PATH_N_LEN 32 | ||
| 974 | #define FILE_N_LEN 32 | ||
| 975 | #define NVRAM_MAGIC_SIG 0xdead | ||
| 976 | |||
| 977 | typedef struct NvRamImage | ||
| 978 | { | ||
| 979 | unsigned short int magic; | ||
| 980 | unsigned short int mode; | ||
| 981 | char fname[FILE_N_LEN]; | ||
| 982 | char path[PATH_N_LEN]; | ||
| 983 | char server[SERVER_N_LEN]; | ||
| 984 | char pad[12]; | ||
| 985 | } NvRam; | ||
| 986 | |||
| 987 | static int | ||
| 988 | mp1000_proc_infos(unsigned char *nvram, char *buffer, int *len, | ||
| 989 | off_t *begin, off_t offset, int size) | ||
| 990 | { | ||
| 991 | int checksum; | ||
| 992 | NvRam* nv = (NvRam*)nvram; | ||
| 993 | |||
| 994 | spin_lock_irq(&rtc_lock); | ||
| 995 | checksum = __nvram_check_checksum(); | ||
| 996 | spin_unlock_irq(&rtc_lock); | ||
| 997 | |||
| 998 | PRINT_PROC("Checksum status: %svalid\n", checksum ? "" : "not "); | ||
| 999 | |||
| 1000 | switch( nv->mode ) | ||
| 1001 | { | ||
| 1002 | case 0 : | ||
| 1003 | PRINT_PROC( "\tMode 0, tftp prompt\n" ); | ||
| 1004 | break; | ||
| 1005 | case 1 : | ||
| 1006 | PRINT_PROC( "\tMode 1, booting from disk\n" ); | ||
| 1007 | break; | ||
| 1008 | case 2 : | ||
| 1009 | PRINT_PROC( "\tMode 2, Alternate boot from disk /boot/%s\n", nv->fname ); | ||
| 1010 | break; | ||
| 1011 | case 3 : | ||
| 1012 | PRINT_PROC( "\tMode 3, Booting from net:\n" ); | ||
| 1013 | PRINT_PROC( "\t\t%s:%s%s\n",nv->server, nv->path, nv->fname ); | ||
| 1014 | break; | ||
| 1015 | default: | ||
| 1016 | PRINT_PROC( "\tInconsistant nvram?\n" ); | ||
| 1017 | break; | ||
| 1018 | } | ||
| 1019 | |||
| 1020 | return 1; | ||
| 1021 | } | ||
| 1022 | #endif | ||
| 1023 | |||
| 1024 | #endif /* MACH == MP1000 */ | ||
| 1025 | |||
| 918 | MODULE_LICENSE("GPL"); | 1026 | MODULE_LICENSE("GPL"); |
| 919 | 1027 | ||
| 920 | EXPORT_SYMBOL(__nvram_read_byte); | 1028 | EXPORT_SYMBOL(__nvram_read_byte); |
