aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/Kconfig4
-rw-r--r--drivers/char/amiserial.c22
-rw-r--r--drivers/char/applicom.c2
-rw-r--r--drivers/char/ds1620.c3
-rw-r--r--drivers/char/ftape/compressor/zftape-compress.c4
-rw-r--r--drivers/char/hpet.c2
-rw-r--r--drivers/char/i8k.c909
-rw-r--r--drivers/char/ip2/i2cmd.c6
-rw-r--r--drivers/char/ip2/i2cmd.h12
-rw-r--r--drivers/char/ip2main.c10
-rw-r--r--drivers/char/ipmi/ipmi_devintf.c196
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c46
-rw-r--r--drivers/char/ipmi/ipmi_poweroff.c137
-rw-r--r--drivers/char/isicom.c12
-rw-r--r--drivers/char/istallion.c3
-rw-r--r--drivers/char/mem.c53
-rw-r--r--drivers/char/misc.c8
-rw-r--r--drivers/char/mwave/3780i.c6
-rw-r--r--drivers/char/mwave/3780i.h4
-rw-r--r--drivers/char/mwave/tp3780i.c14
-rw-r--r--drivers/char/n_hdlc.c2
-rw-r--r--drivers/char/n_r3964.c2
-rw-r--r--drivers/char/nvram.c6
-rw-r--r--drivers/char/rio/func.h1
-rw-r--r--drivers/char/rio/rio_linux.c5
-rw-r--r--drivers/char/rio/rioinit.c7
-rw-r--r--drivers/char/rio/riotty.c15
-rw-r--r--drivers/char/rocket.c226
-rw-r--r--drivers/char/rocket_int.h40
-rw-r--r--drivers/char/sysrq.c24
-rw-r--r--drivers/char/toshiba.c60
-rw-r--r--drivers/char/tpm/tpm.c360
-rw-r--r--drivers/char/tpm/tpm.h38
-rw-r--r--drivers/char/tpm/tpm_atmel.c63
-rw-r--r--drivers/char/tpm/tpm_nsc.c199
-rw-r--r--drivers/char/tty_io.c47
-rw-r--r--drivers/char/watchdog/Kconfig10
-rw-r--r--drivers/char/watchdog/Makefile1
-rw-r--r--drivers/char/watchdog/wdrtas.c696
39 files changed, 1984 insertions, 1271 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 7ccf871d3c9d..43d0cb19ef6a 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -940,8 +940,8 @@ config RAW_DRIVER
940 Once bound, I/O against /dev/raw/rawN uses efficient zero-copy I/O. 940 Once bound, I/O against /dev/raw/rawN uses efficient zero-copy I/O.
941 See the raw(8) manpage for more details. 941 See the raw(8) manpage for more details.
942 942
943 The raw driver is deprecated and may be removed from 2.7 943 The raw driver is deprecated and will be removed soon.
944 kernels. Applications should simply open the device (eg /dev/hda1) 944 Applications should simply open the device (eg /dev/hda1)
945 with the O_DIRECT flag. 945 with the O_DIRECT flag.
946 946
947config HPET 947config HPET
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
index 1dc4259213a6..2a36561eec68 100644
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -861,13 +861,18 @@ static void change_speed(struct async_struct *info,
861 861
862static void rs_put_char(struct tty_struct *tty, unsigned char ch) 862static void rs_put_char(struct tty_struct *tty, unsigned char ch)
863{ 863{
864 struct async_struct *info = (struct async_struct *)tty->driver_data; 864 struct async_struct *info;
865 unsigned long flags; 865 unsigned long flags;
866 866
867 if (!tty)
868 return;
869
870 info = tty->driver_data;
871
867 if (serial_paranoia_check(info, tty->name, "rs_put_char")) 872 if (serial_paranoia_check(info, tty->name, "rs_put_char"))
868 return; 873 return;
869 874
870 if (!tty || !info->xmit.buf) 875 if (!info->xmit.buf)
871 return; 876 return;
872 877
873 local_irq_save(flags); 878 local_irq_save(flags);
@@ -910,13 +915,18 @@ static void rs_flush_chars(struct tty_struct *tty)
910static int rs_write(struct tty_struct * tty, const unsigned char *buf, int count) 915static int rs_write(struct tty_struct * tty, const unsigned char *buf, int count)
911{ 916{
912 int c, ret = 0; 917 int c, ret = 0;
913 struct async_struct *info = (struct async_struct *)tty->driver_data; 918 struct async_struct *info;
914 unsigned long flags; 919 unsigned long flags;
915 920
921 if (!tty)
922 return 0;
923
924 info = tty->driver_data;
925
916 if (serial_paranoia_check(info, tty->name, "rs_write")) 926 if (serial_paranoia_check(info, tty->name, "rs_write"))
917 return 0; 927 return 0;
918 928
919 if (!tty || !info->xmit.buf || !tmp_buf) 929 if (!info->xmit.buf || !tmp_buf)
920 return 0; 930 return 0;
921 931
922 local_save_flags(flags); 932 local_save_flags(flags);
@@ -1963,10 +1973,6 @@ static _INLINE_ void show_serial_version(void)
1963} 1973}
1964 1974
1965 1975
1966int register_serial(struct serial_struct *req);
1967void unregister_serial(int line);
1968
1969
1970static struct tty_operations serial_ops = { 1976static struct tty_operations serial_ops = {
1971 .open = rs_open, 1977 .open = rs_open,
1972 .close = rs_close, 1978 .close = rs_close,
diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c
index 6bf2e27dc23a..11f9ee581124 100644
--- a/drivers/char/applicom.c
+++ b/drivers/char/applicom.c
@@ -599,7 +599,7 @@ static ssize_t ac_read (struct file *filp, char __user *buf, size_t count, loff_
599 599
600#ifdef DEBUG 600#ifdef DEBUG
601 if (loopcount++ > 2) { 601 if (loopcount++ > 2) {
602 printk("Looping in ac_read. loopcount %d\n", loopcount); 602 printk(KERN_DEBUG "Looping in ac_read. loopcount %d\n", loopcount);
603 } 603 }
604#endif 604#endif
605 } 605 }
diff --git a/drivers/char/ds1620.c b/drivers/char/ds1620.c
index 7def6ad51798..62cda25724e3 100644
--- a/drivers/char/ds1620.c
+++ b/drivers/char/ds1620.c
@@ -163,8 +163,7 @@ static void ds1620_out(int cmd, int bits, int value)
163 netwinder_ds1620_reset(); 163 netwinder_ds1620_reset();
164 netwinder_unlock(&flags); 164 netwinder_unlock(&flags);
165 165
166 set_current_state(TASK_INTERRUPTIBLE); 166 msleep(20);
167 schedule_timeout(2);
168} 167}
169 168
170static unsigned int ds1620_in(int cmd, int bits) 169static unsigned int ds1620_in(int cmd, int bits)
diff --git a/drivers/char/ftape/compressor/zftape-compress.c b/drivers/char/ftape/compressor/zftape-compress.c
index 220a227e6061..65ffc0be3df9 100644
--- a/drivers/char/ftape/compressor/zftape-compress.c
+++ b/drivers/char/ftape/compressor/zftape-compress.c
@@ -1176,8 +1176,8 @@ KERN_INFO "Compressor for zftape (lzrw3 algorithm)\n");
1176 } 1176 }
1177#else /* !MODULE */ 1177#else /* !MODULE */
1178 /* print a short no-nonsense boot message */ 1178 /* print a short no-nonsense boot message */
1179 printk("zftape compressor v1.00a 970514\n"); 1179 printk(KERN_INFO "zftape compressor v1.00a 970514\n");
1180 printk("For use with " FTAPE_VERSION "\n"); 1180 printk(KERN_INFO "For use with " FTAPE_VERSION "\n");
1181#endif /* MODULE */ 1181#endif /* MODULE */
1182 TRACE(ft_t_info, "zft_compressor_init @ 0x%p", zft_compressor_init); 1182 TRACE(ft_t_info, "zft_compressor_init @ 0x%p", zft_compressor_init);
1183 TRACE(ft_t_info, "installing compressor for zftape ..."); 1183 TRACE(ft_t_info, "installing compressor for zftape ...");
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index 5ec732e6ca92..762fa430fb5b 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -834,7 +834,7 @@ int hpet_alloc(struct hpet_data *hdp)
834 printk("\n"); 834 printk("\n");
835 835
836 ns = hpetp->hp_period; /* femptoseconds, 10^-15 */ 836 ns = hpetp->hp_period; /* femptoseconds, 10^-15 */
837 do_div(ns, 1000000); /* convert to nanoseconds, 10^-9 */ 837 ns /= 1000000; /* convert to nanoseconds, 10^-9 */
838 printk(KERN_INFO "hpet%d: %ldns tick, %d %d-bit timers\n", 838 printk(KERN_INFO "hpet%d: %ldns tick, %d %d-bit timers\n",
839 hpetp->hp_which, ns, hpetp->hp_ntimer, 839 hpetp->hp_which, ns, hpetp->hp_ntimer,
840 cap & HPET_COUNTER_SIZE_MASK ? 64 : 32); 840 cap & HPET_COUNTER_SIZE_MASK ? 64 : 32);
diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c
index a81197640283..6c4b3f986d0c 100644
--- a/drivers/char/i8k.c
+++ b/drivers/char/i8k.c
@@ -20,13 +20,14 @@
20#include <linux/types.h> 20#include <linux/types.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/proc_fs.h> 22#include <linux/proc_fs.h>
23#include <linux/apm_bios.h> 23#include <linux/seq_file.h>
24#include <linux/dmi.h>
24#include <asm/uaccess.h> 25#include <asm/uaccess.h>
25#include <asm/io.h> 26#include <asm/io.h>
26 27
27#include <linux/i8k.h> 28#include <linux/i8k.h>
28 29
29#define I8K_VERSION "1.13 14/05/2002" 30#define I8K_VERSION "1.14 21/02/2005"
30 31
31#define I8K_SMM_FN_STATUS 0x0025 32#define I8K_SMM_FN_STATUS 0x0025
32#define I8K_SMM_POWER_STATUS 0x0069 33#define I8K_SMM_POWER_STATUS 0x0069
@@ -34,7 +35,8 @@
34#define I8K_SMM_GET_FAN 0x00a3 35#define I8K_SMM_GET_FAN 0x00a3
35#define I8K_SMM_GET_SPEED 0x02a3 36#define I8K_SMM_GET_SPEED 0x02a3
36#define I8K_SMM_GET_TEMP 0x10a3 37#define I8K_SMM_GET_TEMP 0x10a3
37#define I8K_SMM_GET_DELL_SIG 0xffa3 38#define I8K_SMM_GET_DELL_SIG1 0xfea3
39#define I8K_SMM_GET_DELL_SIG2 0xffa3
38#define I8K_SMM_BIOS_VERSION 0x00a6 40#define I8K_SMM_BIOS_VERSION 0x00a6
39 41
40#define I8K_FAN_MULT 30 42#define I8K_FAN_MULT 30
@@ -52,18 +54,7 @@
52 54
53#define I8K_TEMPERATURE_BUG 1 55#define I8K_TEMPERATURE_BUG 1
54 56
55#define DELL_SIGNATURE "Dell Computer" 57static char bios_version[4];
56
57static char *supported_models[] = {
58 "Inspiron",
59 "Latitude",
60 NULL
61};
62
63static char system_vendor[48] = "?";
64static char product_name [48] = "?";
65static char bios_version [4] = "?";
66static char serial_number[16] = "?";
67 58
68MODULE_AUTHOR("Massimo Dal Zotto (dz@debian.org)"); 59MODULE_AUTHOR("Massimo Dal Zotto (dz@debian.org)");
69MODULE_DESCRIPTION("Driver for accessing SMM BIOS on Dell laptops"); 60MODULE_DESCRIPTION("Driver for accessing SMM BIOS on Dell laptops");
@@ -73,6 +64,10 @@ static int force;
73module_param(force, bool, 0); 64module_param(force, bool, 0);
74MODULE_PARM_DESC(force, "Force loading without checking for supported models"); 65MODULE_PARM_DESC(force, "Force loading without checking for supported models");
75 66
67static int ignore_dmi;
68module_param(ignore_dmi, bool, 0);
69MODULE_PARM_DESC(ignore_dmi, "Continue probing hardware even if DMI data does not match");
70
76static int restricted; 71static int restricted;
77module_param(restricted, bool, 0); 72module_param(restricted, bool, 0);
78MODULE_PARM_DESC(restricted, "Allow fan control if SYS_ADMIN capability set"); 73MODULE_PARM_DESC(restricted, "Allow fan control if SYS_ADMIN capability set");
@@ -81,69 +76,69 @@ static int power_status;
81module_param(power_status, bool, 0600); 76module_param(power_status, bool, 0600);
82MODULE_PARM_DESC(power_status, "Report power status in /proc/i8k"); 77MODULE_PARM_DESC(power_status, "Report power status in /proc/i8k");
83 78
84static ssize_t i8k_read(struct file *, char __user *, size_t, loff_t *); 79static int i8k_open_fs(struct inode *inode, struct file *file);
85static int i8k_ioctl(struct inode *, struct file *, unsigned int, 80static int i8k_ioctl(struct inode *, struct file *, unsigned int,
86 unsigned long); 81 unsigned long);
87 82
88static struct file_operations i8k_fops = { 83static struct file_operations i8k_fops = {
89 .read = i8k_read, 84 .open = i8k_open_fs,
90 .ioctl = i8k_ioctl, 85 .read = seq_read,
86 .llseek = seq_lseek,
87 .release = single_release,
88 .ioctl = i8k_ioctl,
89};
90
91struct smm_regs {
92 unsigned int eax;
93 unsigned int ebx __attribute__ ((packed));
94 unsigned int ecx __attribute__ ((packed));
95 unsigned int edx __attribute__ ((packed));
96 unsigned int esi __attribute__ ((packed));
97 unsigned int edi __attribute__ ((packed));
91}; 98};
92 99
93typedef struct { 100static inline char *i8k_get_dmi_data(int field)
94 unsigned int eax; 101{
95 unsigned int ebx __attribute__ ((packed)); 102 return dmi_get_system_info(field) ? : "N/A";
96 unsigned int ecx __attribute__ ((packed)); 103}
97 unsigned int edx __attribute__ ((packed));
98 unsigned int esi __attribute__ ((packed));
99 unsigned int edi __attribute__ ((packed));
100} SMMRegisters;
101
102typedef struct {
103 u8 type;
104 u8 length;
105 u16 handle;
106} DMIHeader;
107 104
108/* 105/*
109 * Call the System Management Mode BIOS. Code provided by Jonathan Buzzard. 106 * Call the System Management Mode BIOS. Code provided by Jonathan Buzzard.
110 */ 107 */
111static int i8k_smm(SMMRegisters *regs) 108static int i8k_smm(struct smm_regs *regs)
112{ 109{
113 int rc; 110 int rc;
114 int eax = regs->eax; 111 int eax = regs->eax;
115 112
116 asm("pushl %%eax\n\t" \ 113 asm("pushl %%eax\n\t"
117 "movl 0(%%eax),%%edx\n\t" \ 114 "movl 0(%%eax),%%edx\n\t"
118 "push %%edx\n\t" \ 115 "push %%edx\n\t"
119 "movl 4(%%eax),%%ebx\n\t" \ 116 "movl 4(%%eax),%%ebx\n\t"
120 "movl 8(%%eax),%%ecx\n\t" \ 117 "movl 8(%%eax),%%ecx\n\t"
121 "movl 12(%%eax),%%edx\n\t" \ 118 "movl 12(%%eax),%%edx\n\t"
122 "movl 16(%%eax),%%esi\n\t" \ 119 "movl 16(%%eax),%%esi\n\t"
123 "movl 20(%%eax),%%edi\n\t" \ 120 "movl 20(%%eax),%%edi\n\t"
124 "popl %%eax\n\t" \ 121 "popl %%eax\n\t"
125 "out %%al,$0xb2\n\t" \ 122 "out %%al,$0xb2\n\t"
126 "out %%al,$0x84\n\t" \ 123 "out %%al,$0x84\n\t"
127 "xchgl %%eax,(%%esp)\n\t" 124 "xchgl %%eax,(%%esp)\n\t"
128 "movl %%ebx,4(%%eax)\n\t" \ 125 "movl %%ebx,4(%%eax)\n\t"
129 "movl %%ecx,8(%%eax)\n\t" \ 126 "movl %%ecx,8(%%eax)\n\t"
130 "movl %%edx,12(%%eax)\n\t" \ 127 "movl %%edx,12(%%eax)\n\t"
131 "movl %%esi,16(%%eax)\n\t" \ 128 "movl %%esi,16(%%eax)\n\t"
132 "movl %%edi,20(%%eax)\n\t" \ 129 "movl %%edi,20(%%eax)\n\t"
133 "popl %%edx\n\t" \ 130 "popl %%edx\n\t"
134 "movl %%edx,0(%%eax)\n\t" \ 131 "movl %%edx,0(%%eax)\n\t"
135 "lahf\n\t" \ 132 "lahf\n\t"
136 "shrl $8,%%eax\n\t" \ 133 "shrl $8,%%eax\n\t"
137 "andl $1,%%eax\n" \ 134 "andl $1,%%eax\n":"=a"(rc)
138 : "=a" (rc) 135 : "a"(regs)
139 : "a" (regs) 136 : "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
140 : "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory"); 137
141 138 if (rc != 0 || (regs->eax & 0xffff) == 0xffff || regs->eax == eax)
142 if ((rc != 0) || ((regs->eax & 0xffff) == 0xffff) || (regs->eax == eax)) { 139 return -EINVAL;
143 return -EINVAL; 140
144 } 141 return 0;
145
146 return 0;
147} 142}
148 143
149/* 144/*
@@ -152,24 +147,9 @@ static int i8k_smm(SMMRegisters *regs)
152 */ 147 */
153static int i8k_get_bios_version(void) 148static int i8k_get_bios_version(void)
154{ 149{
155 SMMRegisters regs = { 0, 0, 0, 0, 0, 0 }; 150 struct smm_regs regs = { .eax = I8K_SMM_BIOS_VERSION, };
156 int rc;
157
158 regs.eax = I8K_SMM_BIOS_VERSION;
159 if ((rc=i8k_smm(&regs)) < 0) {
160 return rc;
161 }
162
163 return regs.eax;
164}
165 151
166/* 152 return i8k_smm(&regs) ? : regs.eax;
167 * Read the machine id.
168 */
169static int i8k_get_serial_number(unsigned char *buff)
170{
171 strlcpy(buff, serial_number, sizeof(serial_number));
172 return 0;
173} 153}
174 154
175/* 155/*
@@ -177,24 +157,22 @@ static int i8k_get_serial_number(unsigned char *buff)
177 */ 157 */
178static int i8k_get_fn_status(void) 158static int i8k_get_fn_status(void)
179{ 159{
180 SMMRegisters regs = { 0, 0, 0, 0, 0, 0 }; 160 struct smm_regs regs = { .eax = I8K_SMM_FN_STATUS, };
181 int rc; 161 int rc;
182 162
183 regs.eax = I8K_SMM_FN_STATUS; 163 if ((rc = i8k_smm(&regs)) < 0)
184 if ((rc=i8k_smm(&regs)) < 0) { 164 return rc;
185 return rc; 165
186 } 166 switch ((regs.eax >> I8K_FN_SHIFT) & I8K_FN_MASK) {
187 167 case I8K_FN_UP:
188 switch ((regs.eax >> I8K_FN_SHIFT) & I8K_FN_MASK) { 168 return I8K_VOL_UP;
189 case I8K_FN_UP: 169 case I8K_FN_DOWN:
190 return I8K_VOL_UP; 170 return I8K_VOL_DOWN;
191 case I8K_FN_DOWN: 171 case I8K_FN_MUTE:
192 return I8K_VOL_DOWN; 172 return I8K_VOL_MUTE;
193 case I8K_FN_MUTE: 173 default:
194 return I8K_VOL_MUTE; 174 return 0;
195 default: 175 }
196 return 0;
197 }
198} 176}
199 177
200/* 178/*
@@ -202,20 +180,13 @@ static int i8k_get_fn_status(void)
202 */ 180 */
203static int i8k_get_power_status(void) 181static int i8k_get_power_status(void)
204{ 182{
205 SMMRegisters regs = { 0, 0, 0, 0, 0, 0 }; 183 struct smm_regs regs = { .eax = I8K_SMM_POWER_STATUS, };
206 int rc; 184 int rc;
207 185
208 regs.eax = I8K_SMM_POWER_STATUS; 186 if ((rc = i8k_smm(&regs)) < 0)
209 if ((rc=i8k_smm(&regs)) < 0) { 187 return rc;
210 return rc; 188
211 } 189 return (regs.eax & 0xff) == I8K_POWER_AC ? I8K_AC : I8K_BATTERY;
212
213 switch (regs.eax & 0xff) {
214 case I8K_POWER_AC:
215 return I8K_AC;
216 default:
217 return I8K_BATTERY;
218 }
219} 190}
220 191
221/* 192/*
@@ -223,16 +194,10 @@ static int i8k_get_power_status(void)
223 */ 194 */
224static int i8k_get_fan_status(int fan) 195static int i8k_get_fan_status(int fan)
225{ 196{
226 SMMRegisters regs = { 0, 0, 0, 0, 0, 0 }; 197 struct smm_regs regs = { .eax = I8K_SMM_GET_FAN, };
227 int rc;
228
229 regs.eax = I8K_SMM_GET_FAN;
230 regs.ebx = fan & 0xff;
231 if ((rc=i8k_smm(&regs)) < 0) {
232 return rc;
233 }
234 198
235 return (regs.eax & 0xff); 199 regs.ebx = fan & 0xff;
200 return i8k_smm(&regs) ? : regs.eax & 0xff;
236} 201}
237 202
238/* 203/*
@@ -240,16 +205,10 @@ static int i8k_get_fan_status(int fan)
240 */ 205 */
241static int i8k_get_fan_speed(int fan) 206static int i8k_get_fan_speed(int fan)
242{ 207{
243 SMMRegisters regs = { 0, 0, 0, 0, 0, 0 }; 208 struct smm_regs regs = { .eax = I8K_SMM_GET_SPEED, };
244 int rc;
245 209
246 regs.eax = I8K_SMM_GET_SPEED; 210 regs.ebx = fan & 0xff;
247 regs.ebx = fan & 0xff; 211 return i8k_smm(&regs) ? : (regs.eax & 0xffff) * I8K_FAN_MULT;
248 if ((rc=i8k_smm(&regs)) < 0) {
249 return rc;
250 }
251
252 return (regs.eax & 0xffff) * I8K_FAN_MULT;
253} 212}
254 213
255/* 214/*
@@ -257,532 +216,318 @@ static int i8k_get_fan_speed(int fan)
257 */ 216 */
258static int i8k_set_fan(int fan, int speed) 217static int i8k_set_fan(int fan, int speed)
259{ 218{
260 SMMRegisters regs = { 0, 0, 0, 0, 0, 0 }; 219 struct smm_regs regs = { .eax = I8K_SMM_SET_FAN, };
261 int rc;
262
263 speed = (speed < 0) ? 0 : ((speed > I8K_FAN_MAX) ? I8K_FAN_MAX : speed);
264 220
265 regs.eax = I8K_SMM_SET_FAN; 221 speed = (speed < 0) ? 0 : ((speed > I8K_FAN_MAX) ? I8K_FAN_MAX : speed);
266 regs.ebx = (fan & 0xff) | (speed << 8); 222 regs.ebx = (fan & 0xff) | (speed << 8);
267 if ((rc=i8k_smm(&regs)) < 0) {
268 return rc;
269 }
270 223
271 return (i8k_get_fan_status(fan)); 224 return i8k_smm(&regs) ? : i8k_get_fan_status(fan);
272} 225}
273 226
274/* 227/*
275 * Read the cpu temperature. 228 * Read the cpu temperature.
276 */ 229 */
277static int i8k_get_cpu_temp(void) 230static int i8k_get_temp(int sensor)
278{ 231{
279 SMMRegisters regs = { 0, 0, 0, 0, 0, 0 }; 232 struct smm_regs regs = { .eax = I8K_SMM_GET_TEMP, };
280 int rc; 233 int rc;
281 int temp; 234 int temp;
282 235
283#ifdef I8K_TEMPERATURE_BUG 236#ifdef I8K_TEMPERATURE_BUG
284 static int prev = 0; 237 static int prev;
285#endif 238#endif
239 regs.ebx = sensor & 0xff;
240 if ((rc = i8k_smm(&regs)) < 0)
241 return rc;
286 242
287 regs.eax = I8K_SMM_GET_TEMP; 243 temp = regs.eax & 0xff;
288 if ((rc=i8k_smm(&regs)) < 0) {
289 return rc;
290 }
291 temp = regs.eax & 0xff;
292 244
293#ifdef I8K_TEMPERATURE_BUG 245#ifdef I8K_TEMPERATURE_BUG
294 /* 246 /*
295 * Sometimes the temperature sensor returns 0x99, which is out of range. 247 * Sometimes the temperature sensor returns 0x99, which is out of range.
296 * In this case we return (once) the previous cached value. For example: 248 * In this case we return (once) the previous cached value. For example:
297 # 1003655137 00000058 00005a4b 249 # 1003655137 00000058 00005a4b
298 # 1003655138 00000099 00003a80 <--- 0x99 = 153 degrees 250 # 1003655138 00000099 00003a80 <--- 0x99 = 153 degrees
299 # 1003655139 00000054 00005c52 251 # 1003655139 00000054 00005c52
300 */ 252 */
301 if (temp > I8K_MAX_TEMP) { 253 if (temp > I8K_MAX_TEMP) {
302 temp = prev; 254 temp = prev;
303 prev = I8K_MAX_TEMP; 255 prev = I8K_MAX_TEMP;
304 } else { 256 } else {
305 prev = temp; 257 prev = temp;
306 } 258 }
307#endif 259#endif
308 260
309 return temp; 261 return temp;
310} 262}
311 263
312static int i8k_get_dell_signature(void) 264static int i8k_get_dell_signature(int req_fn)
313{ 265{
314 SMMRegisters regs = { 0, 0, 0, 0, 0, 0 }; 266 struct smm_regs regs = { .eax = req_fn, };
315 int rc; 267 int rc;
316 268
317 regs.eax = I8K_SMM_GET_DELL_SIG; 269 if ((rc = i8k_smm(&regs)) < 0)
318 if ((rc=i8k_smm(&regs)) < 0) { 270 return rc;
319 return rc;
320 }
321 271
322 if ((regs.eax == 1145651527) && (regs.edx == 1145392204)) { 272 return regs.eax == 1145651527 && regs.edx == 1145392204 ? 0 : -1;
323 return 0;
324 } else {
325 return -1;
326 }
327} 273}
328 274
329static int i8k_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, 275static int i8k_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
330 unsigned long arg) 276 unsigned long arg)
331{ 277{
332 int val; 278 int val = 0;
333 int speed; 279 int speed;
334 unsigned char buff[16]; 280 unsigned char buff[16];
335 int __user *argp = (int __user *)arg; 281 int __user *argp = (int __user *)arg;
336
337 if (!argp)
338 return -EINVAL;
339
340 switch (cmd) {
341 case I8K_BIOS_VERSION:
342 val = i8k_get_bios_version();
343 break;
344
345 case I8K_MACHINE_ID:
346 memset(buff, 0, 16);
347 val = i8k_get_serial_number(buff);
348 break;
349
350 case I8K_FN_STATUS:
351 val = i8k_get_fn_status();
352 break;
353
354 case I8K_POWER_STATUS:
355 val = i8k_get_power_status();
356 break;
357
358 case I8K_GET_TEMP:
359 val = i8k_get_cpu_temp();
360 break;
361
362 case I8K_GET_SPEED:
363 if (copy_from_user(&val, argp, sizeof(int))) {
364 return -EFAULT;
365 }
366 val = i8k_get_fan_speed(val);
367 break;
368
369 case I8K_GET_FAN:
370 if (copy_from_user(&val, argp, sizeof(int))) {
371 return -EFAULT;
372 }
373 val = i8k_get_fan_status(val);
374 break;
375 282
376 case I8K_SET_FAN: 283 if (!argp)
377 if (restricted && !capable(CAP_SYS_ADMIN)) { 284 return -EINVAL;
378 return -EPERM;
379 }
380 if (copy_from_user(&val, argp, sizeof(int))) {
381 return -EFAULT;
382 }
383 if (copy_from_user(&speed, argp+1, sizeof(int))) {
384 return -EFAULT;
385 }
386 val = i8k_set_fan(val, speed);
387 break;
388 285
389 default: 286 switch (cmd) {
390 return -EINVAL; 287 case I8K_BIOS_VERSION:
391 } 288 val = i8k_get_bios_version();
289 break;
392 290
393 if (val < 0) { 291 case I8K_MACHINE_ID:
394 return val; 292 memset(buff, 0, 16);
395 } 293 strlcpy(buff, i8k_get_dmi_data(DMI_PRODUCT_SERIAL), sizeof(buff));
294 break;
396 295
397 switch (cmd) { 296 case I8K_FN_STATUS:
398 case I8K_BIOS_VERSION: 297 val = i8k_get_fn_status();
399 if (copy_to_user(argp, &val, 4)) { 298 break;
400 return -EFAULT;
401 }
402 break;
403 case I8K_MACHINE_ID:
404 if (copy_to_user(argp, buff, 16)) {
405 return -EFAULT;
406 }
407 break;
408 default:
409 if (copy_to_user(argp, &val, sizeof(int))) {
410 return -EFAULT;
411 }
412 break;
413 }
414 299
415 return 0; 300 case I8K_POWER_STATUS:
416} 301 val = i8k_get_power_status();
302 break;
417 303
418/* 304 case I8K_GET_TEMP:
419 * Print the information for /proc/i8k. 305 val = i8k_get_temp(0);
420 */ 306 break;
421static int i8k_get_info(char *buffer, char **start, off_t fpos, int length)
422{
423 int n, fn_key, cpu_temp, ac_power;
424 int left_fan, right_fan, left_speed, right_speed;
425
426 cpu_temp = i8k_get_cpu_temp(); /* 11100 µs */
427 left_fan = i8k_get_fan_status(I8K_FAN_LEFT); /* 580 µs */
428 right_fan = i8k_get_fan_status(I8K_FAN_RIGHT); /* 580 µs */
429 left_speed = i8k_get_fan_speed(I8K_FAN_LEFT); /* 580 µs */
430 right_speed = i8k_get_fan_speed(I8K_FAN_RIGHT); /* 580 µs */
431 fn_key = i8k_get_fn_status(); /* 750 µs */
432 if (power_status) {
433 ac_power = i8k_get_power_status(); /* 14700 µs */
434 } else {
435 ac_power = -1;
436 }
437
438 /*
439 * Info:
440 *
441 * 1) Format version (this will change if format changes)
442 * 2) BIOS version
443 * 3) BIOS machine ID
444 * 4) Cpu temperature
445 * 5) Left fan status
446 * 6) Right fan status
447 * 7) Left fan speed
448 * 8) Right fan speed
449 * 9) AC power
450 * 10) Fn Key status
451 */
452 n = sprintf(buffer, "%s %s %s %d %d %d %d %d %d %d\n",
453 I8K_PROC_FMT,
454 bios_version,
455 serial_number,
456 cpu_temp,
457 left_fan,
458 right_fan,
459 left_speed,
460 right_speed,
461 ac_power,
462 fn_key);
463
464 return n;
465}
466 307
467static ssize_t i8k_read(struct file *f, char __user *buffer, size_t len, loff_t *fpos) 308 case I8K_GET_SPEED:
468{ 309 if (copy_from_user(&val, argp, sizeof(int)))
469 int n; 310 return -EFAULT;
470 char info[128];
471 311
472 n = i8k_get_info(info, NULL, 0, 128); 312 val = i8k_get_fan_speed(val);
473 if (n <= 0) { 313 break;
474 return n;
475 }
476 314
477 if (*fpos >= n) { 315 case I8K_GET_FAN:
478 return 0; 316 if (copy_from_user(&val, argp, sizeof(int)))
479 } 317 return -EFAULT;
480 318
481 if ((*fpos + len) >= n) { 319 val = i8k_get_fan_status(val);
482 len = n - *fpos; 320 break;
483 }
484 321
485 if (copy_to_user(buffer, info, len) != 0) { 322 case I8K_SET_FAN:
486 return -EFAULT; 323 if (restricted && !capable(CAP_SYS_ADMIN))
487 } 324 return -EPERM;
488 325
489 *fpos += len; 326 if (copy_from_user(&val, argp, sizeof(int)))
490 return len; 327 return -EFAULT;
491}
492 328
493static char* __init string_trim(char *s, int size) 329 if (copy_from_user(&speed, argp + 1, sizeof(int)))
494{ 330 return -EFAULT;
495 int len;
496 char *p;
497 331
498 if ((len = strlen(s)) > size) { 332 val = i8k_set_fan(val, speed);
499 len = size; 333 break;
500 }
501 334
502 for (p=s+len-1; len && (*p==' '); len--,p--) { 335 default:
503 *p = '\0'; 336 return -EINVAL;
504 } 337 }
505 338
506 return s; 339 if (val < 0)
507} 340 return val;
508 341
509/* DMI code, stolen from arch/i386/kernel/dmi_scan.c */ 342 switch (cmd) {
343 case I8K_BIOS_VERSION:
344 if (copy_to_user(argp, &val, 4))
345 return -EFAULT;
510 346
511/* 347 break;
512 * |<-- dmi->length -->| 348 case I8K_MACHINE_ID:
513 * | | 349 if (copy_to_user(argp, buff, 16))
514 * |dmi header s=N | string1,\0, ..., stringN,\0, ..., \0 350 return -EFAULT;
515 * | |
516 * +-----------------------+
517 */
518static char* __init dmi_string(DMIHeader *dmi, u8 s)
519{
520 u8 *p;
521 351
522 if (!s) { 352 break;
523 return ""; 353 default:
524 } 354 if (copy_to_user(argp, &val, sizeof(int)))
525 s--; 355 return -EFAULT;
526 356
527 p = (u8 *)dmi + dmi->length; 357 break;
528 while (s > 0) { 358 }
529 p += strlen(p);
530 p++;
531 s--;
532 }
533 359
534 return p; 360 return 0;
535} 361}
536 362
537static void __init dmi_decode(DMIHeader *dmi) 363/*
364 * Print the information for /proc/i8k.
365 */
366static int i8k_proc_show(struct seq_file *seq, void *offset)
538{ 367{
539 u8 *data = (u8 *) dmi; 368 int fn_key, cpu_temp, ac_power;
540 char *p; 369 int left_fan, right_fan, left_speed, right_speed;
541 370
542#ifdef I8K_DEBUG 371 cpu_temp = i8k_get_temp(0); /* 11100 µs */
543 int i; 372 left_fan = i8k_get_fan_status(I8K_FAN_LEFT); /* 580 µs */
544 printk("%08x ", (int)data); 373 right_fan = i8k_get_fan_status(I8K_FAN_RIGHT); /* 580 µs */
545 for (i=0; i<data[1] && i<64; i++) { 374 left_speed = i8k_get_fan_speed(I8K_FAN_LEFT); /* 580 µs */
546 printk("%02x ", data[i]); 375 right_speed = i8k_get_fan_speed(I8K_FAN_RIGHT); /* 580 µs */
547 } 376 fn_key = i8k_get_fn_status(); /* 750 µs */
548 printk("\n"); 377 if (power_status)
549#endif 378 ac_power = i8k_get_power_status(); /* 14700 µs */
550 379 else
551 switch (dmi->type) { 380 ac_power = -1;
552 case 0: /* BIOS Information */
553 p = dmi_string(dmi,data[5]);
554 if (*p) {
555 strlcpy(bios_version, p, sizeof(bios_version));
556 string_trim(bios_version, sizeof(bios_version));
557 }
558 break;
559 case 1: /* System Information */
560 p = dmi_string(dmi,data[4]);
561 if (*p) {
562 strlcpy(system_vendor, p, sizeof(system_vendor));
563 string_trim(system_vendor, sizeof(system_vendor));
564 }
565 p = dmi_string(dmi,data[5]);
566 if (*p) {
567 strlcpy(product_name, p, sizeof(product_name));
568 string_trim(product_name, sizeof(product_name));
569 }
570 p = dmi_string(dmi,data[7]);
571 if (*p) {
572 strlcpy(serial_number, p, sizeof(serial_number));
573 string_trim(serial_number, sizeof(serial_number));
574 }
575 break;
576 }
577}
578 381
579static int __init dmi_table(u32 base, int len, int num, void (*fn)(DMIHeader*))
580{
581 u8 *buf;
582 u8 *data;
583 DMIHeader *dmi;
584 int i = 1;
585
586 buf = ioremap(base, len);
587 if (buf == NULL) {
588 return -1;
589 }
590 data = buf;
591
592 /*
593 * Stop when we see al the items the table claimed to have
594 * or we run off the end of the table (also happens)
595 */
596 while ((i<num) && ((data-buf) < len)) {
597 dmi = (DMIHeader *)data;
598 /*
599 * Avoid misparsing crud if the length of the last
600 * record is crap
601 */
602 if ((data-buf+dmi->length) >= len) {
603 break;
604 }
605 fn(dmi);
606 data += dmi->length;
607 /* 382 /*
608 * Don't go off the end of the data if there is 383 * Info:
609 * stuff looking like string fill past the end 384 *
385 * 1) Format version (this will change if format changes)
386 * 2) BIOS version
387 * 3) BIOS machine ID
388 * 4) Cpu temperature
389 * 5) Left fan status
390 * 6) Right fan status
391 * 7) Left fan speed
392 * 8) Right fan speed
393 * 9) AC power
394 * 10) Fn Key status
610 */ 395 */
611 while (((data-buf) < len) && (*data || data[1])) { 396 return seq_printf(seq, "%s %s %s %d %d %d %d %d %d %d\n",
612 data++; 397 I8K_PROC_FMT,
613 } 398 bios_version,
614 data += 2; 399 dmi_get_system_info(DMI_PRODUCT_SERIAL) ? : "N/A",
615 i++; 400 cpu_temp,
616 } 401 left_fan, right_fan, left_speed, right_speed,
617 iounmap(buf); 402 ac_power, fn_key);
618
619 return 0;
620} 403}
621 404
622static int __init dmi_iterate(void (*decode)(DMIHeader *)) 405static int i8k_open_fs(struct inode *inode, struct file *file)
623{ 406{
624 unsigned char buf[20]; 407 return single_open(file, i8k_proc_show, NULL);
625 void __iomem *p = ioremap(0xe0000, 0x20000), *q;
626
627 if (!p)
628 return -1;
629
630 for (q = p; q < p + 0x20000; q += 16) {
631 memcpy_fromio(buf, q, 20);
632 if (memcmp(buf, "_DMI_", 5)==0) {
633 u16 num = buf[13]<<8 | buf[12];
634 u16 len = buf [7]<<8 | buf [6];
635 u32 base = buf[11]<<24 | buf[10]<<16 | buf[9]<<8 | buf[8];
636#ifdef I8K_DEBUG
637 printk(KERN_INFO "DMI %d.%d present.\n",
638 buf[14]>>4, buf[14]&0x0F);
639 printk(KERN_INFO "%d structures occupying %d bytes.\n",
640 buf[13]<<8 | buf[12],
641 buf [7]<<8 | buf[6]);
642 printk(KERN_INFO "DMI table at 0x%08X.\n",
643 buf[11]<<24 | buf[10]<<16 | buf[9]<<8 | buf[8]);
644#endif
645 if (dmi_table(base, len, num, decode)==0) {
646 iounmap(p);
647 return 0;
648 }
649 }
650 }
651 iounmap(p);
652 return -1;
653} 408}
654/* end of DMI code */
655
656/*
657 * Get DMI information.
658 */
659static int __init i8k_dmi_probe(void)
660{
661 char **p;
662
663 if (dmi_iterate(dmi_decode) != 0) {
664 printk(KERN_INFO "i8k: unable to get DMI information\n");
665 return -ENODEV;
666 }
667
668 if (strncmp(system_vendor,DELL_SIGNATURE,strlen(DELL_SIGNATURE)) != 0) {
669 printk(KERN_INFO "i8k: not running on a Dell system\n");
670 return -ENODEV;
671 }
672
673 for (p=supported_models; ; p++) {
674 if (!*p) {
675 printk(KERN_INFO "i8k: unsupported model: %s\n", product_name);
676 return -ENODEV;
677 }
678 if (strncmp(product_name,*p,strlen(*p)) == 0) {
679 break;
680 }
681 }
682 409
683 return 0; 410static struct dmi_system_id __initdata i8k_dmi_table[] = {
684} 411 {
412 .ident = "Dell Inspiron",
413 .matches = {
414 DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer"),
415 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron"),
416 },
417 },
418 {
419 .ident = "Dell Latitude",
420 .matches = {
421 DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer"),
422 DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"),
423 },
424 },
425 {
426 .ident = "Dell Inspiron 2",
427 .matches = {
428 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
429 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron"),
430 },
431 },
432 {
433 .ident = "Dell Latitude 2",
434 .matches = {
435 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
436 DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"),
437 },
438 },
439 { }
440};
685 441
686/* 442/*
687 * Probe for the presence of a supported laptop. 443 * Probe for the presence of a supported laptop.
688 */ 444 */
689static int __init i8k_probe(void) 445static int __init i8k_probe(void)
690{ 446{
691 char buff[4]; 447 char buff[4];
692 int version; 448 int version;
693 int smm_found = 0; 449
694
695 /*
696 * Get DMI information
697 */
698 if (i8k_dmi_probe() != 0) {
699 printk(KERN_INFO "i8k: vendor=%s, model=%s, version=%s\n",
700 system_vendor, product_name, bios_version);
701 }
702
703 /*
704 * Get SMM Dell signature
705 */
706 if (i8k_get_dell_signature() != 0) {
707 printk(KERN_INFO "i8k: unable to get SMM Dell signature\n");
708 } else {
709 smm_found = 1;
710 }
711
712 /*
713 * Get SMM BIOS version.
714 */
715 version = i8k_get_bios_version();
716 if (version <= 0) {
717 printk(KERN_INFO "i8k: unable to get SMM BIOS version\n");
718 } else {
719 smm_found = 1;
720 buff[0] = (version >> 16) & 0xff;
721 buff[1] = (version >> 8) & 0xff;
722 buff[2] = (version) & 0xff;
723 buff[3] = '\0';
724 /* 450 /*
725 * If DMI BIOS version is unknown use SMM BIOS version. 451 * Get DMI information
726 */ 452 */
727 if (bios_version[0] == '?') { 453 if (!dmi_check_system(i8k_dmi_table)) {
728 strcpy(bios_version, buff); 454 if (!ignore_dmi && !force)
455 return -ENODEV;
456
457 printk(KERN_INFO "i8k: not running on a supported Dell system.\n");
458 printk(KERN_INFO "i8k: vendor=%s, model=%s, version=%s\n",
459 i8k_get_dmi_data(DMI_SYS_VENDOR),
460 i8k_get_dmi_data(DMI_PRODUCT_NAME),
461 i8k_get_dmi_data(DMI_BIOS_VERSION));
729 } 462 }
463
464 strlcpy(bios_version, i8k_get_dmi_data(DMI_BIOS_VERSION), sizeof(bios_version));
465
730 /* 466 /*
731 * Check if the two versions match. 467 * Get SMM Dell signature
732 */ 468 */
733 if (strncmp(buff,bios_version,sizeof(bios_version)) != 0) { 469 if (i8k_get_dell_signature(I8K_SMM_GET_DELL_SIG1) &&
734 printk(KERN_INFO "i8k: BIOS version mismatch: %s != %s\n", 470 i8k_get_dell_signature(I8K_SMM_GET_DELL_SIG2)) {
735 buff, bios_version); 471 printk(KERN_ERR "i8k: unable to get SMM Dell signature\n");
472 if (!force)
473 return -ENODEV;
736 } 474 }
737 }
738 475
739 if (!smm_found && !force) { 476 /*
740 return -ENODEV; 477 * Get SMM BIOS version.
741 } 478 */
479 version = i8k_get_bios_version();
480 if (version <= 0) {
481 printk(KERN_WARNING "i8k: unable to get SMM BIOS version\n");
482 } else {
483 buff[0] = (version >> 16) & 0xff;
484 buff[1] = (version >> 8) & 0xff;
485 buff[2] = (version) & 0xff;
486 buff[3] = '\0';
487 /*
488 * If DMI BIOS version is unknown use SMM BIOS version.
489 */
490 if (!dmi_get_system_info(DMI_BIOS_VERSION))
491 strlcpy(bios_version, buff, sizeof(bios_version));
492
493 /*
494 * Check if the two versions match.
495 */
496 if (strncmp(buff, bios_version, sizeof(bios_version)) != 0)
497 printk(KERN_WARNING "i8k: BIOS version mismatch: %s != %s\n",
498 buff, bios_version);
499 }
742 500
743 return 0; 501 return 0;
744} 502}
745 503
746#ifdef MODULE 504static int __init i8k_init(void)
747static
748#endif
749int __init i8k_init(void)
750{ 505{
751 struct proc_dir_entry *proc_i8k; 506 struct proc_dir_entry *proc_i8k;
752
753 /* Are we running on an supported laptop? */
754 if (i8k_probe() != 0) {
755 return -ENODEV;
756 }
757
758 /* Register the proc entry */
759 proc_i8k = create_proc_info_entry("i8k", 0, NULL, i8k_get_info);
760 if (!proc_i8k) {
761 return -ENOENT;
762 }
763 proc_i8k->proc_fops = &i8k_fops;
764 proc_i8k->owner = THIS_MODULE;
765
766 printk(KERN_INFO
767 "Dell laptop SMM driver v%s Massimo Dal Zotto (dz@debian.org)\n",
768 I8K_VERSION);
769
770 return 0;
771}
772 507
773#ifdef MODULE 508 /* Are we running on an supported laptop? */
774int init_module(void) 509 if (i8k_probe())
775{ 510 return -ENODEV;
776 return i8k_init(); 511
512 /* Register the proc entry */
513 proc_i8k = create_proc_entry("i8k", 0, NULL);
514 if (!proc_i8k)
515 return -ENOENT;
516
517 proc_i8k->proc_fops = &i8k_fops;
518 proc_i8k->owner = THIS_MODULE;
519
520 printk(KERN_INFO
521 "Dell laptop SMM driver v%s Massimo Dal Zotto (dz@debian.org)\n",
522 I8K_VERSION);
523
524 return 0;
777} 525}
778 526
779void cleanup_module(void) 527static void __exit i8k_exit(void)
780{ 528{
781 /* Remove the proc entry */ 529 remove_proc_entry("i8k", NULL);
782 remove_proc_entry("i8k", NULL);
783
784 printk(KERN_INFO "i8k: module unloaded\n");
785} 530}
786#endif
787 531
788/* end of file */ 532module_init(i8k_init);
533module_exit(i8k_exit);
diff --git a/drivers/char/ip2/i2cmd.c b/drivers/char/ip2/i2cmd.c
index fd299d6c42ac..cb8f4198e9a3 100644
--- a/drivers/char/ip2/i2cmd.c
+++ b/drivers/char/ip2/i2cmd.c
@@ -97,7 +97,7 @@ static UCHAR ct41[] = { 1, BYP, 0x29 }; // RESUME
97//static UCHAR ct44[]={ 2, BTH, 0x2C,0 }; // MS PING 97//static UCHAR ct44[]={ 2, BTH, 0x2C,0 }; // MS PING
98//static UCHAR ct45[]={ 1, BTH, 0x2D }; // HOTENAB 98//static UCHAR ct45[]={ 1, BTH, 0x2D }; // HOTENAB
99//static UCHAR ct46[]={ 1, BTH, 0x2E }; // HOTDSAB 99//static UCHAR ct46[]={ 1, BTH, 0x2E }; // HOTDSAB
100static UCHAR ct47[] = { 7, BTH, 0x2F,0,0,0,0,0,0 }; // UNIX FLAGS 100//static UCHAR ct47[]={ 7, BTH, 0x2F,0,0,0,0,0,0 }; // UNIX FLAGS
101//static UCHAR ct48[]={ 1, BTH, 0x30 }; // DSRFLOWENAB 101//static UCHAR ct48[]={ 1, BTH, 0x30 }; // DSRFLOWENAB
102//static UCHAR ct49[]={ 1, BTH, 0x31 }; // DSRFLOWDSAB 102//static UCHAR ct49[]={ 1, BTH, 0x31 }; // DSRFLOWDSAB
103//static UCHAR ct50[]={ 1, BTH, 0x32 }; // DTRFLOWENAB 103//static UCHAR ct50[]={ 1, BTH, 0x32 }; // DTRFLOWENAB
@@ -162,6 +162,7 @@ static UCHAR ct89[]={ 1, BYP, 0x59 }; // DSS_NOW
162// This routine sets the parameters of command 47 and returns a pointer to the 162// This routine sets the parameters of command 47 and returns a pointer to the
163// appropriate structure. 163// appropriate structure.
164//****************************************************************************** 164//******************************************************************************
165#if 0
165cmdSyntaxPtr 166cmdSyntaxPtr
166i2cmdUnixFlags(unsigned short iflag,unsigned short cflag,unsigned short lflag) 167i2cmdUnixFlags(unsigned short iflag,unsigned short cflag,unsigned short lflag)
167{ 168{
@@ -175,6 +176,7 @@ i2cmdUnixFlags(unsigned short iflag,unsigned short cflag,unsigned short lflag)
175 pCM->cmd[6] = (unsigned char) (lflag >> 8); 176 pCM->cmd[6] = (unsigned char) (lflag >> 8);
176 return pCM; 177 return pCM;
177} 178}
179#endif /* 0 */
178 180
179//****************************************************************************** 181//******************************************************************************
180// Function: i2cmdBaudDef(which, rate) 182// Function: i2cmdBaudDef(which, rate)
@@ -187,7 +189,7 @@ i2cmdUnixFlags(unsigned short iflag,unsigned short cflag,unsigned short lflag)
187// This routine sets the parameters of commands 54 or 55 (according to the 189// This routine sets the parameters of commands 54 or 55 (according to the
188// argument which), and returns a pointer to the appropriate structure. 190// argument which), and returns a pointer to the appropriate structure.
189//****************************************************************************** 191//******************************************************************************
190cmdSyntaxPtr 192static cmdSyntaxPtr
191i2cmdBaudDef(int which, unsigned short rate) 193i2cmdBaudDef(int which, unsigned short rate)
192{ 194{
193 cmdSyntaxPtr pCM; 195 cmdSyntaxPtr pCM;
diff --git a/drivers/char/ip2/i2cmd.h b/drivers/char/ip2/i2cmd.h
index c41728a85710..baa4e721b758 100644
--- a/drivers/char/ip2/i2cmd.h
+++ b/drivers/char/ip2/i2cmd.h
@@ -64,16 +64,6 @@ typedef struct _cmdSyntax
64 // directly from user-level 64 // directly from user-level
65#define VAR 0x10 // This command is of variable length! 65#define VAR 0x10 // This command is of variable length!
66 66
67//-----------------------------------
68// External declarations for i2cmd.c
69//-----------------------------------
70// Routine to set up parameters for the "define hot-key sequence" command. Since
71// there is more than one parameter to assign, we must use a function rather
72// than a macro (used usually).
73//
74extern cmdSyntaxPtr i2cmdUnixFlags(USHORT iflag,USHORT cflag,USHORT lflag);
75extern cmdSyntaxPtr i2cmdBaudDef(int which, USHORT rate);
76
77// Declarations for the global arrays used to bear the commands and their 67// Declarations for the global arrays used to bear the commands and their
78// arguments. 68// arguments.
79// 69//
@@ -433,6 +423,7 @@ static UCHAR cc02[];
433#define CMD_HOT_ENAB (cmdSyntaxPtr)(ct45) // Enable Hot-key checking 423#define CMD_HOT_ENAB (cmdSyntaxPtr)(ct45) // Enable Hot-key checking
434#define CMD_HOT_DSAB (cmdSyntaxPtr)(ct46) // Disable Hot-key checking 424#define CMD_HOT_DSAB (cmdSyntaxPtr)(ct46) // Disable Hot-key checking
435 425
426#if 0
436// COMMAND 47: Send Protocol info via Unix flags: 427// COMMAND 47: Send Protocol info via Unix flags:
437// iflag = Unix tty t_iflag 428// iflag = Unix tty t_iflag
438// cflag = Unix tty t_cflag 429// cflag = Unix tty t_cflag
@@ -441,6 +432,7 @@ static UCHAR cc02[];
441// within these flags 432// within these flags
442// 433//
443#define CMD_UNIX_FLAGS(iflag,cflag,lflag) i2cmdUnixFlags(iflag,cflag,lflag) 434#define CMD_UNIX_FLAGS(iflag,cflag,lflag) i2cmdUnixFlags(iflag,cflag,lflag)
435#endif /* 0 */
444 436
445#define CMD_DSRFL_ENAB (cmdSyntaxPtr)(ct48) // Enable DSR receiver ctrl 437#define CMD_DSRFL_ENAB (cmdSyntaxPtr)(ct48) // Enable DSR receiver ctrl
446#define CMD_DSRFL_DSAB (cmdSyntaxPtr)(ct49) // Disable DSR receiver ctrl 438#define CMD_DSRFL_DSAB (cmdSyntaxPtr)(ct49) // Disable DSR receiver ctrl
diff --git a/drivers/char/ip2main.c b/drivers/char/ip2main.c
index 3b8314b4249a..cf0cd58d6305 100644
--- a/drivers/char/ip2main.c
+++ b/drivers/char/ip2main.c
@@ -2691,16 +2691,6 @@ no_xon:
2691 pCh->flags |= ASYNC_CHECK_CD; 2691 pCh->flags |= ASYNC_CHECK_CD;
2692 } 2692 }
2693 2693
2694#ifdef XXX
2695do_flags_thing: // This is a test, we don't do the flags thing
2696
2697 if ( (cflag & CRTSCTS) ) {
2698 cflag |= 014000000000;
2699 }
2700 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1,
2701 CMD_UNIX_FLAGS(iflag,cflag,lflag));
2702#endif
2703
2704service_it: 2694service_it:
2705 i2DrainOutput( pCh, 100 ); 2695 i2DrainOutput( pCh, 100 );
2706} 2696}
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
index 88d1ad656e99..e0a53570fea1 100644
--- a/drivers/char/ipmi/ipmi_devintf.c
+++ b/drivers/char/ipmi/ipmi_devintf.c
@@ -45,6 +45,7 @@
45#include <asm/semaphore.h> 45#include <asm/semaphore.h>
46#include <linux/init.h> 46#include <linux/init.h>
47#include <linux/device.h> 47#include <linux/device.h>
48#include <linux/compat.h>
48 49
49#define IPMI_DEVINTF_VERSION "v33" 50#define IPMI_DEVINTF_VERSION "v33"
50 51
@@ -500,10 +501,205 @@ static int ipmi_ioctl(struct inode *inode,
500 return rv; 501 return rv;
501} 502}
502 503
504#ifdef CONFIG_COMPAT
505
506/*
507 * The following code contains code for supporting 32-bit compatible
508 * ioctls on 64-bit kernels. This allows running 32-bit apps on the
509 * 64-bit kernel
510 */
511#define COMPAT_IPMICTL_SEND_COMMAND \
512 _IOR(IPMI_IOC_MAGIC, 13, struct compat_ipmi_req)
513#define COMPAT_IPMICTL_SEND_COMMAND_SETTIME \
514 _IOR(IPMI_IOC_MAGIC, 21, struct compat_ipmi_req_settime)
515#define COMPAT_IPMICTL_RECEIVE_MSG \
516 _IOWR(IPMI_IOC_MAGIC, 12, struct compat_ipmi_recv)
517#define COMPAT_IPMICTL_RECEIVE_MSG_TRUNC \
518 _IOWR(IPMI_IOC_MAGIC, 11, struct compat_ipmi_recv)
519
520struct compat_ipmi_msg {
521 u8 netfn;
522 u8 cmd;
523 u16 data_len;
524 compat_uptr_t data;
525};
526
527struct compat_ipmi_req {
528 compat_uptr_t addr;
529 compat_uint_t addr_len;
530 compat_long_t msgid;
531 struct compat_ipmi_msg msg;
532};
533
534struct compat_ipmi_recv {
535 compat_int_t recv_type;
536 compat_uptr_t addr;
537 compat_uint_t addr_len;
538 compat_long_t msgid;
539 struct compat_ipmi_msg msg;
540};
541
542struct compat_ipmi_req_settime {
543 struct compat_ipmi_req req;
544 compat_int_t retries;
545 compat_uint_t retry_time_ms;
546};
547
548/*
549 * Define some helper functions for copying IPMI data
550 */
551static long get_compat_ipmi_msg(struct ipmi_msg *p64,
552 struct compat_ipmi_msg __user *p32)
553{
554 compat_uptr_t tmp;
555
556 if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
557 __get_user(p64->netfn, &p32->netfn) ||
558 __get_user(p64->cmd, &p32->cmd) ||
559 __get_user(p64->data_len, &p32->data_len) ||
560 __get_user(tmp, &p32->data))
561 return -EFAULT;
562 p64->data = compat_ptr(tmp);
563 return 0;
564}
565
566static long put_compat_ipmi_msg(struct ipmi_msg *p64,
567 struct compat_ipmi_msg __user *p32)
568{
569 if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) ||
570 __put_user(p64->netfn, &p32->netfn) ||
571 __put_user(p64->cmd, &p32->cmd) ||
572 __put_user(p64->data_len, &p32->data_len))
573 return -EFAULT;
574 return 0;
575}
576
577static long get_compat_ipmi_req(struct ipmi_req *p64,
578 struct compat_ipmi_req __user *p32)
579{
580
581 compat_uptr_t tmp;
582
583 if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
584 __get_user(tmp, &p32->addr) ||
585 __get_user(p64->addr_len, &p32->addr_len) ||
586 __get_user(p64->msgid, &p32->msgid) ||
587 get_compat_ipmi_msg(&p64->msg, &p32->msg))
588 return -EFAULT;
589 p64->addr = compat_ptr(tmp);
590 return 0;
591}
592
593static long get_compat_ipmi_req_settime(struct ipmi_req_settime *p64,
594 struct compat_ipmi_req_settime __user *p32)
595{
596 if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
597 get_compat_ipmi_req(&p64->req, &p32->req) ||
598 __get_user(p64->retries, &p32->retries) ||
599 __get_user(p64->retry_time_ms, &p32->retry_time_ms))
600 return -EFAULT;
601 return 0;
602}
603
604static long get_compat_ipmi_recv(struct ipmi_recv *p64,
605 struct compat_ipmi_recv __user *p32)
606{
607 compat_uptr_t tmp;
608
609 if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
610 __get_user(p64->recv_type, &p32->recv_type) ||
611 __get_user(tmp, &p32->addr) ||
612 __get_user(p64->addr_len, &p32->addr_len) ||
613 __get_user(p64->msgid, &p32->msgid) ||
614 get_compat_ipmi_msg(&p64->msg, &p32->msg))
615 return -EFAULT;
616 p64->addr = compat_ptr(tmp);
617 return 0;
618}
619
620static long put_compat_ipmi_recv(struct ipmi_recv *p64,
621 struct compat_ipmi_recv __user *p32)
622{
623 if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) ||
624 __put_user(p64->recv_type, &p32->recv_type) ||
625 __put_user(p64->addr_len, &p32->addr_len) ||
626 __put_user(p64->msgid, &p32->msgid) ||
627 put_compat_ipmi_msg(&p64->msg, &p32->msg))
628 return -EFAULT;
629 return 0;
630}
631
632/*
633 * Handle compatibility ioctls
634 */
635static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd,
636 unsigned long arg)
637{
638 int rc;
639 struct ipmi_file_private *priv = filep->private_data;
640
641 switch(cmd) {
642 case COMPAT_IPMICTL_SEND_COMMAND:
643 {
644 struct ipmi_req rp;
645
646 if (get_compat_ipmi_req(&rp, compat_ptr(arg)))
647 return -EFAULT;
648
649 return handle_send_req(priv->user, &rp,
650 priv->default_retries,
651 priv->default_retry_time_ms);
652 }
653 case COMPAT_IPMICTL_SEND_COMMAND_SETTIME:
654 {
655 struct ipmi_req_settime sp;
656
657 if (get_compat_ipmi_req_settime(&sp, compat_ptr(arg)))
658 return -EFAULT;
659
660 return handle_send_req(priv->user, &sp.req,
661 sp.retries, sp.retry_time_ms);
662 }
663 case COMPAT_IPMICTL_RECEIVE_MSG:
664 case COMPAT_IPMICTL_RECEIVE_MSG_TRUNC:
665 {
666 struct ipmi_recv *precv64, recv64;
667
668 if (get_compat_ipmi_recv(&recv64, compat_ptr(arg)))
669 return -EFAULT;
670
671 precv64 = compat_alloc_user_space(sizeof(recv64));
672 if (copy_to_user(precv64, &recv64, sizeof(recv64)))
673 return -EFAULT;
674
675 rc = ipmi_ioctl(filep->f_dentry->d_inode, filep,
676 ((cmd == COMPAT_IPMICTL_RECEIVE_MSG)
677 ? IPMICTL_RECEIVE_MSG
678 : IPMICTL_RECEIVE_MSG_TRUNC),
679 (long) precv64);
680 if (rc != 0)
681 return rc;
682
683 if (copy_from_user(&recv64, precv64, sizeof(recv64)))
684 return -EFAULT;
685
686 if (put_compat_ipmi_recv(&recv64, compat_ptr(arg)))
687 return -EFAULT;
688
689 return rc;
690 }
691 default:
692 return ipmi_ioctl(filep->f_dentry->d_inode, filep, cmd, arg);
693 }
694}
695#endif
503 696
504static struct file_operations ipmi_fops = { 697static struct file_operations ipmi_fops = {
505 .owner = THIS_MODULE, 698 .owner = THIS_MODULE,
506 .ioctl = ipmi_ioctl, 699 .ioctl = ipmi_ioctl,
700#ifdef CONFIG_COMPAT
701 .compat_ioctl = compat_ipmi_ioctl,
702#endif
507 .open = ipmi_open, 703 .open = ipmi_open,
508 .release = ipmi_release, 704 .release = ipmi_release,
509 .fasync = ipmi_fasync, 705 .fasync = ipmi_fasync,
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 0c81652eaba6..1813d0d198f1 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -54,7 +54,9 @@ static int ipmi_init_msghandler(void);
54 54
55static int initialized = 0; 55static int initialized = 0;
56 56
57static struct proc_dir_entry *proc_ipmi_root = NULL; 57#ifdef CONFIG_PROC_FS
58struct proc_dir_entry *proc_ipmi_root = NULL;
59#endif /* CONFIG_PROC_FS */
58 60
59#define MAX_EVENTS_IN_QUEUE 25 61#define MAX_EVENTS_IN_QUEUE 25
60 62
@@ -124,11 +126,13 @@ struct ipmi_channel
124 unsigned char protocol; 126 unsigned char protocol;
125}; 127};
126 128
129#ifdef CONFIG_PROC_FS
127struct ipmi_proc_entry 130struct ipmi_proc_entry
128{ 131{
129 char *name; 132 char *name;
130 struct ipmi_proc_entry *next; 133 struct ipmi_proc_entry *next;
131}; 134};
135#endif
132 136
133#define IPMI_IPMB_NUM_SEQ 64 137#define IPMI_IPMB_NUM_SEQ 64
134#define IPMI_MAX_CHANNELS 8 138#define IPMI_MAX_CHANNELS 8
@@ -156,10 +160,13 @@ struct ipmi_smi
156 struct ipmi_smi_handlers *handlers; 160 struct ipmi_smi_handlers *handlers;
157 void *send_info; 161 void *send_info;
158 162
163#ifdef CONFIG_PROC_FS
159 /* A list of proc entries for this interface. This does not 164 /* A list of proc entries for this interface. This does not
160 need a lock, only one thread creates it and only one thread 165 need a lock, only one thread creates it and only one thread
161 destroys it. */ 166 destroys it. */
167 spinlock_t proc_entry_lock;
162 struct ipmi_proc_entry *proc_entries; 168 struct ipmi_proc_entry *proc_entries;
169#endif
163 170
164 /* A table of sequence numbers for this interface. We use the 171 /* A table of sequence numbers for this interface. We use the
165 sequence numbers for IPMB messages that go out of the 172 sequence numbers for IPMB messages that go out of the
@@ -1470,8 +1477,9 @@ int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name,
1470 read_proc_t *read_proc, write_proc_t *write_proc, 1477 read_proc_t *read_proc, write_proc_t *write_proc,
1471 void *data, struct module *owner) 1478 void *data, struct module *owner)
1472{ 1479{
1473 struct proc_dir_entry *file;
1474 int rv = 0; 1480 int rv = 0;
1481#ifdef CONFIG_PROC_FS
1482 struct proc_dir_entry *file;
1475 struct ipmi_proc_entry *entry; 1483 struct ipmi_proc_entry *entry;
1476 1484
1477 /* Create a list element. */ 1485 /* Create a list element. */
@@ -1497,10 +1505,13 @@ int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name,
1497 file->write_proc = write_proc; 1505 file->write_proc = write_proc;
1498 file->owner = owner; 1506 file->owner = owner;
1499 1507
1508 spin_lock(&smi->proc_entry_lock);
1500 /* Stick it on the list. */ 1509 /* Stick it on the list. */
1501 entry->next = smi->proc_entries; 1510 entry->next = smi->proc_entries;
1502 smi->proc_entries = entry; 1511 smi->proc_entries = entry;
1512 spin_unlock(&smi->proc_entry_lock);
1503 } 1513 }
1514#endif /* CONFIG_PROC_FS */
1504 1515
1505 return rv; 1516 return rv;
1506} 1517}
@@ -1509,6 +1520,7 @@ static int add_proc_entries(ipmi_smi_t smi, int num)
1509{ 1520{
1510 int rv = 0; 1521 int rv = 0;
1511 1522
1523#ifdef CONFIG_PROC_FS
1512 sprintf(smi->proc_dir_name, "%d", num); 1524 sprintf(smi->proc_dir_name, "%d", num);
1513 smi->proc_dir = proc_mkdir(smi->proc_dir_name, proc_ipmi_root); 1525 smi->proc_dir = proc_mkdir(smi->proc_dir_name, proc_ipmi_root);
1514 if (!smi->proc_dir) 1526 if (!smi->proc_dir)
@@ -1531,14 +1543,17 @@ static int add_proc_entries(ipmi_smi_t smi, int num)
1531 rv = ipmi_smi_add_proc_entry(smi, "version", 1543 rv = ipmi_smi_add_proc_entry(smi, "version",
1532 version_file_read_proc, NULL, 1544 version_file_read_proc, NULL,
1533 smi, THIS_MODULE); 1545 smi, THIS_MODULE);
1546#endif /* CONFIG_PROC_FS */
1534 1547
1535 return rv; 1548 return rv;
1536} 1549}
1537 1550
1538static void remove_proc_entries(ipmi_smi_t smi) 1551static void remove_proc_entries(ipmi_smi_t smi)
1539{ 1552{
1553#ifdef CONFIG_PROC_FS
1540 struct ipmi_proc_entry *entry; 1554 struct ipmi_proc_entry *entry;
1541 1555
1556 spin_lock(&smi->proc_entry_lock);
1542 while (smi->proc_entries) { 1557 while (smi->proc_entries) {
1543 entry = smi->proc_entries; 1558 entry = smi->proc_entries;
1544 smi->proc_entries = entry->next; 1559 smi->proc_entries = entry->next;
@@ -1547,7 +1562,9 @@ static void remove_proc_entries(ipmi_smi_t smi)
1547 kfree(entry->name); 1562 kfree(entry->name);
1548 kfree(entry); 1563 kfree(entry);
1549 } 1564 }
1565 spin_unlock(&smi->proc_entry_lock);
1550 remove_proc_entry(smi->proc_dir_name, proc_ipmi_root); 1566 remove_proc_entry(smi->proc_dir_name, proc_ipmi_root);
1567#endif /* CONFIG_PROC_FS */
1551} 1568}
1552 1569
1553static int 1570static int
@@ -1694,6 +1711,9 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
1694 new_intf->seq_table[j].seqid = 0; 1711 new_intf->seq_table[j].seqid = 0;
1695 } 1712 }
1696 new_intf->curr_seq = 0; 1713 new_intf->curr_seq = 0;
1714#ifdef CONFIG_PROC_FS
1715 spin_lock_init(&(new_intf->proc_entry_lock));
1716#endif
1697 spin_lock_init(&(new_intf->waiting_msgs_lock)); 1717 spin_lock_init(&(new_intf->waiting_msgs_lock));
1698 INIT_LIST_HEAD(&(new_intf->waiting_msgs)); 1718 INIT_LIST_HEAD(&(new_intf->waiting_msgs));
1699 spin_lock_init(&(new_intf->events_lock)); 1719 spin_lock_init(&(new_intf->events_lock));
@@ -2747,16 +2767,13 @@ static struct timer_list ipmi_timer;
2747 the queue and this silliness can go away. */ 2767 the queue and this silliness can go away. */
2748#define IPMI_REQUEST_EV_TIME (1000 / (IPMI_TIMEOUT_TIME)) 2768#define IPMI_REQUEST_EV_TIME (1000 / (IPMI_TIMEOUT_TIME))
2749 2769
2750static volatile int stop_operation = 0; 2770static atomic_t stop_operation;
2751static volatile int timer_stopped = 0;
2752static unsigned int ticks_to_req_ev = IPMI_REQUEST_EV_TIME; 2771static unsigned int ticks_to_req_ev = IPMI_REQUEST_EV_TIME;
2753 2772
2754static void ipmi_timeout(unsigned long data) 2773static void ipmi_timeout(unsigned long data)
2755{ 2774{
2756 if (stop_operation) { 2775 if (atomic_read(&stop_operation))
2757 timer_stopped = 1;
2758 return; 2776 return;
2759 }
2760 2777
2761 ticks_to_req_ev--; 2778 ticks_to_req_ev--;
2762 if (ticks_to_req_ev == 0) { 2779 if (ticks_to_req_ev == 0) {
@@ -2766,8 +2783,7 @@ static void ipmi_timeout(unsigned long data)
2766 2783
2767 ipmi_timeout_handler(IPMI_TIMEOUT_TIME); 2784 ipmi_timeout_handler(IPMI_TIMEOUT_TIME);
2768 2785
2769 ipmi_timer.expires += IPMI_TIMEOUT_JIFFIES; 2786 mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES);
2770 add_timer(&ipmi_timer);
2771} 2787}
2772 2788
2773 2789
@@ -3089,6 +3105,7 @@ static int ipmi_init_msghandler(void)
3089 ipmi_interfaces[i] = NULL; 3105 ipmi_interfaces[i] = NULL;
3090 } 3106 }
3091 3107
3108#ifdef CONFIG_PROC_FS
3092 proc_ipmi_root = proc_mkdir("ipmi", NULL); 3109 proc_ipmi_root = proc_mkdir("ipmi", NULL);
3093 if (!proc_ipmi_root) { 3110 if (!proc_ipmi_root) {
3094 printk(KERN_ERR PFX "Unable to create IPMI proc dir"); 3111 printk(KERN_ERR PFX "Unable to create IPMI proc dir");
@@ -3096,6 +3113,7 @@ static int ipmi_init_msghandler(void)
3096 } 3113 }
3097 3114
3098 proc_ipmi_root->owner = THIS_MODULE; 3115 proc_ipmi_root->owner = THIS_MODULE;
3116#endif /* CONFIG_PROC_FS */
3099 3117
3100 init_timer(&ipmi_timer); 3118 init_timer(&ipmi_timer);
3101 ipmi_timer.data = 0; 3119 ipmi_timer.data = 0;
@@ -3130,13 +3148,12 @@ static __exit void cleanup_ipmi(void)
3130 3148
3131 /* Tell the timer to stop, then wait for it to stop. This avoids 3149 /* Tell the timer to stop, then wait for it to stop. This avoids
3132 problems with race conditions removing the timer here. */ 3150 problems with race conditions removing the timer here. */
3133 stop_operation = 1; 3151 atomic_inc(&stop_operation);
3134 while (!timer_stopped) { 3152 del_timer_sync(&ipmi_timer);
3135 set_current_state(TASK_UNINTERRUPTIBLE);
3136 schedule_timeout(1);
3137 }
3138 3153
3154#ifdef CONFIG_PROC_FS
3139 remove_proc_entry(proc_ipmi_root->name, &proc_root); 3155 remove_proc_entry(proc_ipmi_root->name, &proc_root);
3156#endif /* CONFIG_PROC_FS */
3140 3157
3141 initialized = 0; 3158 initialized = 0;
3142 3159
@@ -3177,4 +3194,5 @@ EXPORT_SYMBOL(ipmi_get_my_address);
3177EXPORT_SYMBOL(ipmi_set_my_LUN); 3194EXPORT_SYMBOL(ipmi_set_my_LUN);
3178EXPORT_SYMBOL(ipmi_get_my_LUN); 3195EXPORT_SYMBOL(ipmi_get_my_LUN);
3179EXPORT_SYMBOL(ipmi_smi_add_proc_entry); 3196EXPORT_SYMBOL(ipmi_smi_add_proc_entry);
3197EXPORT_SYMBOL(proc_ipmi_root);
3180EXPORT_SYMBOL(ipmi_user_set_run_to_completion); 3198EXPORT_SYMBOL(ipmi_user_set_run_to_completion);
diff --git a/drivers/char/ipmi/ipmi_poweroff.c b/drivers/char/ipmi/ipmi_poweroff.c
index cb5cdc6f14bf..f951c30236c9 100644
--- a/drivers/char/ipmi/ipmi_poweroff.c
+++ b/drivers/char/ipmi/ipmi_poweroff.c
@@ -31,10 +31,13 @@
31 * with this program; if not, write to the Free Software Foundation, Inc., 31 * with this program; if not, write to the Free Software Foundation, Inc.,
32 * 675 Mass Ave, Cambridge, MA 02139, USA. 32 * 675 Mass Ave, Cambridge, MA 02139, USA.
33 */ 33 */
34#include <asm/semaphore.h> 34#include <linux/config.h>
35#include <linux/kdev_t.h>
36#include <linux/module.h> 35#include <linux/module.h>
36#include <linux/moduleparam.h>
37#include <linux/proc_fs.h>
37#include <linux/string.h> 38#include <linux/string.h>
39#include <linux/completion.h>
40#include <linux/kdev_t.h>
38#include <linux/ipmi.h> 41#include <linux/ipmi.h>
39#include <linux/ipmi_smi.h> 42#include <linux/ipmi_smi.h>
40 43
@@ -44,6 +47,18 @@
44/* Where to we insert our poweroff function? */ 47/* Where to we insert our poweroff function? */
45extern void (*pm_power_off)(void); 48extern void (*pm_power_off)(void);
46 49
50/* Definitions for controlling power off (if the system supports it). It
51 * conveniently matches the IPMI chassis control values. */
52#define IPMI_CHASSIS_POWER_DOWN 0 /* power down, the default. */
53#define IPMI_CHASSIS_POWER_CYCLE 0x02 /* power cycle */
54
55/* the IPMI data command */
56static int poweroff_control = IPMI_CHASSIS_POWER_DOWN;
57
58/* parameter definition to allow user to flag power cycle */
59module_param(poweroff_control, int, IPMI_CHASSIS_POWER_DOWN);
60MODULE_PARM_DESC(poweroff_control, " Set to 2 to enable power cycle instead of power down. Power cycle is contingent on hardware support, otherwise it defaults back to power down.");
61
47/* Stuff from the get device id command. */ 62/* Stuff from the get device id command. */
48static unsigned int mfg_id; 63static unsigned int mfg_id;
49static unsigned int prod_id; 64static unsigned int prod_id;
@@ -75,10 +90,10 @@ static struct ipmi_recv_msg halt_recv_msg =
75 90
76static void receive_handler(struct ipmi_recv_msg *recv_msg, void *handler_data) 91static void receive_handler(struct ipmi_recv_msg *recv_msg, void *handler_data)
77{ 92{
78 struct semaphore *sem = recv_msg->user_msg_data; 93 struct completion *comp = recv_msg->user_msg_data;
79 94
80 if (sem) 95 if (comp)
81 up(sem); 96 complete(comp);
82} 97}
83 98
84static struct ipmi_user_hndl ipmi_poweroff_handler = 99static struct ipmi_user_hndl ipmi_poweroff_handler =
@@ -91,27 +106,27 @@ static int ipmi_request_wait_for_response(ipmi_user_t user,
91 struct ipmi_addr *addr, 106 struct ipmi_addr *addr,
92 struct kernel_ipmi_msg *send_msg) 107 struct kernel_ipmi_msg *send_msg)
93{ 108{
94 int rv; 109 int rv;
95 struct semaphore sem; 110 struct completion comp;
96 111
97 sema_init (&sem, 0); 112 init_completion(&comp);
98 113
99 rv = ipmi_request_supply_msgs(user, addr, 0, send_msg, &sem, 114 rv = ipmi_request_supply_msgs(user, addr, 0, send_msg, &comp,
100 &halt_smi_msg, &halt_recv_msg, 0); 115 &halt_smi_msg, &halt_recv_msg, 0);
101 if (rv) 116 if (rv)
102 return rv; 117 return rv;
103 118
104 down (&sem); 119 wait_for_completion(&comp);
105 120
106 return halt_recv_msg.msg.data[0]; 121 return halt_recv_msg.msg.data[0];
107} 122}
108 123
109/* We are in run-to-completion mode, no semaphore is desired. */ 124/* We are in run-to-completion mode, no completion is desired. */
110static int ipmi_request_in_rc_mode(ipmi_user_t user, 125static int ipmi_request_in_rc_mode(ipmi_user_t user,
111 struct ipmi_addr *addr, 126 struct ipmi_addr *addr,
112 struct kernel_ipmi_msg *send_msg) 127 struct kernel_ipmi_msg *send_msg)
113{ 128{
114 int rv; 129 int rv;
115 130
116 rv = ipmi_request_supply_msgs(user, addr, 0, send_msg, NULL, 131 rv = ipmi_request_supply_msgs(user, addr, 0, send_msg, NULL,
117 &halt_smi_msg, &halt_recv_msg, 0); 132 &halt_smi_msg, &halt_recv_msg, 0);
@@ -349,26 +364,38 @@ static void ipmi_poweroff_chassis (ipmi_user_t user)
349 smi_addr.channel = IPMI_BMC_CHANNEL; 364 smi_addr.channel = IPMI_BMC_CHANNEL;
350 smi_addr.lun = 0; 365 smi_addr.lun = 0;
351 366
352 printk(KERN_INFO PFX "Powering down via IPMI chassis control command\n"); 367 powercyclefailed:
368 printk(KERN_INFO PFX "Powering %s via IPMI chassis control command\n",
369 ((poweroff_control != IPMI_CHASSIS_POWER_CYCLE) ? "down" : "cycle"));
353 370
354 /* 371 /*
355 * Power down 372 * Power down
356 */ 373 */
357 send_msg.netfn = IPMI_NETFN_CHASSIS_REQUEST; 374 send_msg.netfn = IPMI_NETFN_CHASSIS_REQUEST;
358 send_msg.cmd = IPMI_CHASSIS_CONTROL_CMD; 375 send_msg.cmd = IPMI_CHASSIS_CONTROL_CMD;
359 data[0] = 0; /* Power down */ 376 data[0] = poweroff_control;
360 send_msg.data = data; 377 send_msg.data = data;
361 send_msg.data_len = sizeof(data); 378 send_msg.data_len = sizeof(data);
362 rv = ipmi_request_in_rc_mode(user, 379 rv = ipmi_request_in_rc_mode(user,
363 (struct ipmi_addr *) &smi_addr, 380 (struct ipmi_addr *) &smi_addr,
364 &send_msg); 381 &send_msg);
365 if (rv) { 382 if (rv) {
366 printk(KERN_ERR PFX "Unable to send chassis powerdown message," 383 switch (poweroff_control) {
367 " IPMI error 0x%x\n", rv); 384 case IPMI_CHASSIS_POWER_CYCLE:
368 goto out; 385 /* power cycle failed, default to power down */
386 printk(KERN_ERR PFX "Unable to send chassis power " \
387 "cycle message, IPMI error 0x%x\n", rv);
388 poweroff_control = IPMI_CHASSIS_POWER_DOWN;
389 goto powercyclefailed;
390
391 case IPMI_CHASSIS_POWER_DOWN:
392 default:
393 printk(KERN_ERR PFX "Unable to send chassis power " \
394 "down message, IPMI error 0x%x\n", rv);
395 break;
396 }
369 } 397 }
370 398
371 out:
372 return; 399 return;
373} 400}
374 401
@@ -430,7 +457,8 @@ static void ipmi_po_new_smi(int if_num)
430 if (ready) 457 if (ready)
431 return; 458 return;
432 459
433 rv = ipmi_create_user(if_num, &ipmi_poweroff_handler, NULL, &ipmi_user); 460 rv = ipmi_create_user(if_num, &ipmi_poweroff_handler, NULL,
461 &ipmi_user);
434 if (rv) { 462 if (rv) {
435 printk(KERN_ERR PFX "could not create IPMI user, error %d\n", 463 printk(KERN_ERR PFX "could not create IPMI user, error %d\n",
436 rv); 464 rv);
@@ -509,21 +537,84 @@ static struct ipmi_smi_watcher smi_watcher =
509}; 537};
510 538
511 539
540#ifdef CONFIG_PROC_FS
541/* displays properties to proc */
542static int proc_read_chassctrl(char *page, char **start, off_t off, int count,
543 int *eof, void *data)
544{
545 return sprintf(page, "%d\t[ 0=powerdown 2=powercycle ]\n",
546 poweroff_control);
547}
548
549/* process property writes from proc */
550static int proc_write_chassctrl(struct file *file, const char *buffer,
551 unsigned long count, void *data)
552{
553 int rv = count;
554 unsigned int newval = 0;
555
556 sscanf(buffer, "%d", &newval);
557 switch (newval) {
558 case IPMI_CHASSIS_POWER_CYCLE:
559 printk(KERN_INFO PFX "power cycle is now enabled\n");
560 poweroff_control = newval;
561 break;
562
563 case IPMI_CHASSIS_POWER_DOWN:
564 poweroff_control = IPMI_CHASSIS_POWER_DOWN;
565 break;
566
567 default:
568 rv = -EINVAL;
569 break;
570 }
571
572 return rv;
573}
574#endif /* CONFIG_PROC_FS */
575
512/* 576/*
513 * Startup and shutdown functions. 577 * Startup and shutdown functions.
514 */ 578 */
515static int ipmi_poweroff_init (void) 579static int ipmi_poweroff_init (void)
516{ 580{
517 int rv; 581 int rv;
582 struct proc_dir_entry *file;
518 583
519 printk ("Copyright (C) 2004 MontaVista Software -" 584 printk ("Copyright (C) 2004 MontaVista Software -"
520 " IPMI Powerdown via sys_reboot version " 585 " IPMI Powerdown via sys_reboot version "
521 IPMI_POWEROFF_VERSION ".\n"); 586 IPMI_POWEROFF_VERSION ".\n");
522 587
588 switch (poweroff_control) {
589 case IPMI_CHASSIS_POWER_CYCLE:
590 printk(KERN_INFO PFX "Power cycle is enabled.\n");
591 break;
592
593 case IPMI_CHASSIS_POWER_DOWN:
594 default:
595 poweroff_control = IPMI_CHASSIS_POWER_DOWN;
596 break;
597 }
598
523 rv = ipmi_smi_watcher_register(&smi_watcher); 599 rv = ipmi_smi_watcher_register(&smi_watcher);
524 if (rv) 600 if (rv) {
525 printk(KERN_ERR PFX "Unable to register SMI watcher: %d\n", rv); 601 printk(KERN_ERR PFX "Unable to register SMI watcher: %d\n", rv);
602 goto out_err;
603 }
604
605#ifdef CONFIG_PROC_FS
606 file = create_proc_entry("poweroff_control", 0, proc_ipmi_root);
607 if (!file) {
608 printk(KERN_ERR PFX "Unable to create proc power control\n");
609 } else {
610 file->nlink = 1;
611 file->read_proc = proc_read_chassctrl;
612 file->write_proc = proc_write_chassctrl;
613 file->owner = THIS_MODULE;
614 }
615#endif
526 616
617 out_err:
527 return rv; 618 return rv;
528} 619}
529 620
@@ -532,6 +623,10 @@ static __exit void ipmi_poweroff_cleanup(void)
532{ 623{
533 int rv; 624 int rv;
534 625
626#ifdef CONFIG_PROC_FS
627 remove_proc_entry("poweroff_control", proc_ipmi_root);
628#endif
629
535 ipmi_smi_watcher_unregister(&smi_watcher); 630 ipmi_smi_watcher_unregister(&smi_watcher);
536 631
537 if (ready) { 632 if (ready) {
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 601c7fccb4cf..1bbf507adda5 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -1756,7 +1756,7 @@ static void isicom_flush_buffer(struct tty_struct * tty)
1756} 1756}
1757 1757
1758 1758
1759static int __init register_ioregion(void) 1759static int __devinit register_ioregion(void)
1760{ 1760{
1761 int count, done=0; 1761 int count, done=0;
1762 for (count=0; count < BOARD_COUNT; count++ ) { 1762 for (count=0; count < BOARD_COUNT; count++ ) {
@@ -1771,7 +1771,7 @@ static int __init register_ioregion(void)
1771 return done; 1771 return done;
1772} 1772}
1773 1773
1774static void __exit unregister_ioregion(void) 1774static void unregister_ioregion(void)
1775{ 1775{
1776 int count; 1776 int count;
1777 for (count=0; count < BOARD_COUNT; count++ ) 1777 for (count=0; count < BOARD_COUNT; count++ )
@@ -1803,7 +1803,7 @@ static struct tty_operations isicom_ops = {
1803 .tiocmset = isicom_tiocmset, 1803 .tiocmset = isicom_tiocmset,
1804}; 1804};
1805 1805
1806static int __init register_drivers(void) 1806static int __devinit register_drivers(void)
1807{ 1807{
1808 int error; 1808 int error;
1809 1809
@@ -1834,7 +1834,7 @@ static int __init register_drivers(void)
1834 return 0; 1834 return 0;
1835} 1835}
1836 1836
1837static void __exit unregister_drivers(void) 1837static void unregister_drivers(void)
1838{ 1838{
1839 int error = tty_unregister_driver(isicom_normal); 1839 int error = tty_unregister_driver(isicom_normal);
1840 if (error) 1840 if (error)
@@ -1842,7 +1842,7 @@ static void __exit unregister_drivers(void)
1842 put_tty_driver(isicom_normal); 1842 put_tty_driver(isicom_normal);
1843} 1843}
1844 1844
1845static int __init register_isr(void) 1845static int __devinit register_isr(void)
1846{ 1846{
1847 int count, done=0; 1847 int count, done=0;
1848 unsigned long irqflags; 1848 unsigned long irqflags;
@@ -1883,7 +1883,7 @@ static void __exit unregister_isr(void)
1883 } 1883 }
1884} 1884}
1885 1885
1886static int __init isicom_init(void) 1886static int __devinit isicom_init(void)
1887{ 1887{
1888 int card, channel, base; 1888 int card, channel, base;
1889 struct isi_port * port; 1889 struct isi_port * port;
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index c02a21dbad5d..52a073eee201 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -407,7 +407,6 @@ static unsigned long stli_eisamemprobeaddrs[] = {
407}; 407};
408 408
409static int stli_eisamempsize = sizeof(stli_eisamemprobeaddrs) / sizeof(unsigned long); 409static int stli_eisamempsize = sizeof(stli_eisamemprobeaddrs) / sizeof(unsigned long);
410int stli_eisaprobe = STLI_EISAPROBE;
411 410
412/* 411/*
413 * Define the Stallion PCI vendor and device IDs. 412 * Define the Stallion PCI vendor and device IDs.
@@ -4685,7 +4684,7 @@ static int stli_initbrds(void)
4685#ifdef MODULE 4684#ifdef MODULE
4686 stli_argbrds(); 4685 stli_argbrds();
4687#endif 4686#endif
4688 if (stli_eisaprobe) 4687 if (STLI_EISAPROBE)
4689 stli_findeisabrds(); 4688 stli_findeisabrds();
4690#ifdef CONFIG_PCI 4689#ifdef CONFIG_PCI
4691 stli_findpcibrds(); 4690 stli_findpcibrds();
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index e3085b22a365..42187381506b 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -23,7 +23,10 @@
23#include <linux/devfs_fs_kernel.h> 23#include <linux/devfs_fs_kernel.h>
24#include <linux/ptrace.h> 24#include <linux/ptrace.h>
25#include <linux/device.h> 25#include <linux/device.h>
26#include <linux/highmem.h>
27#include <linux/crash_dump.h>
26#include <linux/backing-dev.h> 28#include <linux/backing-dev.h>
29#include <linux/bootmem.h>
27 30
28#include <asm/uaccess.h> 31#include <asm/uaccess.h>
29#include <asm/io.h> 32#include <asm/io.h>
@@ -273,6 +276,40 @@ static int mmap_kmem(struct file * file, struct vm_area_struct * vma)
273 return mmap_mem(file, vma); 276 return mmap_mem(file, vma);
274} 277}
275 278
279#ifdef CONFIG_CRASH_DUMP
280/*
281 * Read memory corresponding to the old kernel.
282 */
283static ssize_t read_oldmem(struct file *file, char __user *buf,
284 size_t count, loff_t *ppos)
285{
286 unsigned long pfn, offset;
287 size_t read = 0, csize;
288 int rc = 0;
289
290 while (count) {
291 pfn = *ppos / PAGE_SIZE;
292 if (pfn > saved_max_pfn)
293 return read;
294
295 offset = (unsigned long)(*ppos % PAGE_SIZE);
296 if (count > PAGE_SIZE - offset)
297 csize = PAGE_SIZE - offset;
298 else
299 csize = count;
300
301 rc = copy_oldmem_page(pfn, buf, csize, offset, 1);
302 if (rc < 0)
303 return rc;
304 buf += csize;
305 *ppos += csize;
306 read += csize;
307 count -= csize;
308 }
309 return read;
310}
311#endif
312
276extern long vread(char *buf, char *addr, unsigned long count); 313extern long vread(char *buf, char *addr, unsigned long count);
277extern long vwrite(char *buf, char *addr, unsigned long count); 314extern long vwrite(char *buf, char *addr, unsigned long count);
278 315
@@ -721,6 +758,7 @@ static int open_port(struct inode * inode, struct file * filp)
721#define read_full read_zero 758#define read_full read_zero
722#define open_mem open_port 759#define open_mem open_port
723#define open_kmem open_mem 760#define open_kmem open_mem
761#define open_oldmem open_mem
724 762
725static struct file_operations mem_fops = { 763static struct file_operations mem_fops = {
726 .llseek = memory_lseek, 764 .llseek = memory_lseek,
@@ -770,6 +808,13 @@ static struct file_operations full_fops = {
770 .write = write_full, 808 .write = write_full,
771}; 809};
772 810
811#ifdef CONFIG_CRASH_DUMP
812static struct file_operations oldmem_fops = {
813 .read = read_oldmem,
814 .open = open_oldmem,
815};
816#endif
817
773static ssize_t kmsg_write(struct file * file, const char __user * buf, 818static ssize_t kmsg_write(struct file * file, const char __user * buf,
774 size_t count, loff_t *ppos) 819 size_t count, loff_t *ppos)
775{ 820{
@@ -825,6 +870,11 @@ static int memory_open(struct inode * inode, struct file * filp)
825 case 11: 870 case 11:
826 filp->f_op = &kmsg_fops; 871 filp->f_op = &kmsg_fops;
827 break; 872 break;
873#ifdef CONFIG_CRASH_DUMP
874 case 12:
875 filp->f_op = &oldmem_fops;
876 break;
877#endif
828 default: 878 default:
829 return -ENXIO; 879 return -ENXIO;
830 } 880 }
@@ -854,6 +904,9 @@ static const struct {
854 {8, "random", S_IRUGO | S_IWUSR, &random_fops}, 904 {8, "random", S_IRUGO | S_IWUSR, &random_fops},
855 {9, "urandom", S_IRUGO | S_IWUSR, &urandom_fops}, 905 {9, "urandom", S_IRUGO | S_IWUSR, &urandom_fops},
856 {11,"kmsg", S_IRUGO | S_IWUSR, &kmsg_fops}, 906 {11,"kmsg", S_IRUGO | S_IWUSR, &kmsg_fops},
907#ifdef CONFIG_CRASH_DUMP
908 {12,"oldmem", S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops},
909#endif
857}; 910};
858 911
859static struct class *mem_class; 912static struct class *mem_class;
diff --git a/drivers/char/misc.c b/drivers/char/misc.c
index 3115d318b997..31cf84d69026 100644
--- a/drivers/char/misc.c
+++ b/drivers/char/misc.c
@@ -66,8 +66,6 @@ static unsigned char misc_minors[DYNAMIC_MINORS / 8];
66extern int rtc_DP8570A_init(void); 66extern int rtc_DP8570A_init(void);
67extern int rtc_MK48T08_init(void); 67extern int rtc_MK48T08_init(void);
68extern int pmu_device_init(void); 68extern int pmu_device_init(void);
69extern int tosh_init(void);
70extern int i8k_init(void);
71 69
72#ifdef CONFIG_PROC_FS 70#ifdef CONFIG_PROC_FS
73static void *misc_seq_start(struct seq_file *seq, loff_t *pos) 71static void *misc_seq_start(struct seq_file *seq, loff_t *pos)
@@ -314,12 +312,6 @@ static int __init misc_init(void)
314#ifdef CONFIG_PMAC_PBOOK 312#ifdef CONFIG_PMAC_PBOOK
315 pmu_device_init(); 313 pmu_device_init();
316#endif 314#endif
317#ifdef CONFIG_TOSHIBA
318 tosh_init();
319#endif
320#ifdef CONFIG_I8K
321 i8k_init();
322#endif
323 if (register_chrdev(MISC_MAJOR,"misc",&misc_fops)) { 315 if (register_chrdev(MISC_MAJOR,"misc",&misc_fops)) {
324 printk("unable to get major %d for misc devices\n", 316 printk("unable to get major %d for misc devices\n",
325 MISC_MAJOR); 317 MISC_MAJOR);
diff --git a/drivers/char/mwave/3780i.c b/drivers/char/mwave/3780i.c
index ab00f51475df..613aed9e1840 100644
--- a/drivers/char/mwave/3780i.c
+++ b/drivers/char/mwave/3780i.c
@@ -107,8 +107,8 @@ void dsp3780I_WriteMsaCfg(unsigned short usDspBaseIO,
107 spin_unlock_irqrestore(&dsp_lock, flags); 107 spin_unlock_irqrestore(&dsp_lock, flags);
108} 108}
109 109
110void dsp3780I_WriteGenCfg(unsigned short usDspBaseIO, unsigned uIndex, 110static void dsp3780I_WriteGenCfg(unsigned short usDspBaseIO, unsigned uIndex,
111 unsigned char ucValue) 111 unsigned char ucValue)
112{ 112{
113 DSP_ISA_SLAVE_CONTROL rSlaveControl; 113 DSP_ISA_SLAVE_CONTROL rSlaveControl;
114 DSP_ISA_SLAVE_CONTROL rSlaveControl_Save; 114 DSP_ISA_SLAVE_CONTROL rSlaveControl_Save;
@@ -141,6 +141,7 @@ void dsp3780I_WriteGenCfg(unsigned short usDspBaseIO, unsigned uIndex,
141 141
142} 142}
143 143
144#if 0
144unsigned char dsp3780I_ReadGenCfg(unsigned short usDspBaseIO, 145unsigned char dsp3780I_ReadGenCfg(unsigned short usDspBaseIO,
145 unsigned uIndex) 146 unsigned uIndex)
146{ 147{
@@ -167,6 +168,7 @@ unsigned char dsp3780I_ReadGenCfg(unsigned short usDspBaseIO,
167 168
168 return ucValue; 169 return ucValue;
169} 170}
171#endif /* 0 */
170 172
171int dsp3780I_EnableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings, 173int dsp3780I_EnableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings,
172 unsigned short *pIrqMap, 174 unsigned short *pIrqMap,
diff --git a/drivers/char/mwave/3780i.h b/drivers/char/mwave/3780i.h
index 3e7d020d1bf4..270431ca7dae 100644
--- a/drivers/char/mwave/3780i.h
+++ b/drivers/char/mwave/3780i.h
@@ -338,10 +338,6 @@ unsigned short dsp3780I_ReadMsaCfg(unsigned short usDspBaseIO,
338 unsigned long ulMsaAddr); 338 unsigned long ulMsaAddr);
339void dsp3780I_WriteMsaCfg(unsigned short usDspBaseIO, 339void dsp3780I_WriteMsaCfg(unsigned short usDspBaseIO,
340 unsigned long ulMsaAddr, unsigned short usValue); 340 unsigned long ulMsaAddr, unsigned short usValue);
341void dsp3780I_WriteGenCfg(unsigned short usDspBaseIO, unsigned uIndex,
342 unsigned char ucValue);
343unsigned char dsp3780I_ReadGenCfg(unsigned short usDspBaseIO,
344 unsigned uIndex);
345int dsp3780I_GetIPCSource(unsigned short usDspBaseIO, 341int dsp3780I_GetIPCSource(unsigned short usDspBaseIO,
346 unsigned short *pusIPCSource); 342 unsigned short *pusIPCSource);
347 343
diff --git a/drivers/char/mwave/tp3780i.c b/drivers/char/mwave/tp3780i.c
index ab650cd6efc0..d6c72e0934e2 100644
--- a/drivers/char/mwave/tp3780i.c
+++ b/drivers/char/mwave/tp3780i.c
@@ -242,20 +242,14 @@ int tp3780I_ClaimResources(THINKPAD_BD_DATA * pBDData)
242{ 242{
243 int retval = 0; 243 int retval = 0;
244 DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings; 244 DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings;
245#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
246 struct resource *pres; 245 struct resource *pres;
247#endif
248 246
249 PRINTK_2(TRACE_TP3780I, 247 PRINTK_2(TRACE_TP3780I,
250 "tp3780i::tp3780I_ClaimResources entry pBDData %p\n", pBDData); 248 "tp3780i::tp3780I_ClaimResources entry pBDData %p\n", pBDData);
251 249
252#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
253 pres = request_region(pSettings->usDspBaseIO, 16, "mwave_3780i"); 250 pres = request_region(pSettings->usDspBaseIO, 16, "mwave_3780i");
254 if ( pres == NULL ) retval = -EIO; 251 if ( pres == NULL ) retval = -EIO;
255#else 252
256 retval = check_region(pSettings->usDspBaseIO, 16);
257 if (!retval) request_region(pSettings->usDspBaseIO, 16, "mwave_3780i");
258#endif
259 if (retval) { 253 if (retval) {
260 PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_ClaimResources: Error: Could not claim I/O region starting at %x\n", pSettings->usDspBaseIO); 254 PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_ClaimResources: Error: Could not claim I/O region starting at %x\n", pSettings->usDspBaseIO);
261 retval = -EIO; 255 retval = -EIO;
@@ -292,7 +286,7 @@ int tp3780I_ReleaseResources(THINKPAD_BD_DATA * pBDData)
292int tp3780I_EnableDSP(THINKPAD_BD_DATA * pBDData) 286int tp3780I_EnableDSP(THINKPAD_BD_DATA * pBDData)
293{ 287{
294 DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings; 288 DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings;
295 BOOLEAN bDSPPoweredUp = FALSE, bDSPEnabled = FALSE, bInterruptAllocated = FALSE; 289 BOOLEAN bDSPPoweredUp = FALSE, bInterruptAllocated = FALSE;
296 290
297 PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_EnableDSP entry pBDData %p\n", pBDData); 291 PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_EnableDSP entry pBDData %p\n", pBDData);
298 292
@@ -397,8 +391,6 @@ int tp3780I_EnableDSP(THINKPAD_BD_DATA * pBDData)
397 if (dsp3780I_EnableDSP(pSettings, s_ausThinkpadIrqToField, s_ausThinkpadDmaToField)) { 391 if (dsp3780I_EnableDSP(pSettings, s_ausThinkpadIrqToField, s_ausThinkpadDmaToField)) {
398 PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Error: dsp7880I_EnableDSP() failed\n"); 392 PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Error: dsp7880I_EnableDSP() failed\n");
399 goto exit_cleanup; 393 goto exit_cleanup;
400 } else {
401 bDSPEnabled = TRUE;
402 } 394 }
403 395
404 EnableSRAM(pBDData); 396 EnableSRAM(pBDData);
@@ -411,8 +403,6 @@ int tp3780I_EnableDSP(THINKPAD_BD_DATA * pBDData)
411 403
412exit_cleanup: 404exit_cleanup:
413 PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Cleaning up\n"); 405 PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Cleaning up\n");
414 if (bDSPEnabled)
415 dsp3780I_DisableDSP(pSettings);
416 if (bDSPPoweredUp) 406 if (bDSPPoweredUp)
417 smapi_set_DSP_power_state(FALSE); 407 smapi_set_DSP_power_state(FALSE);
418 if (bInterruptAllocated) { 408 if (bInterruptAllocated) {
diff --git a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c
index b3dbff1cf967..5079beda69b5 100644
--- a/drivers/char/n_hdlc.c
+++ b/drivers/char/n_hdlc.c
@@ -960,7 +960,7 @@ static char hdlc_unregister_fail[] __exitdata =
960static void __exit n_hdlc_exit(void) 960static void __exit n_hdlc_exit(void)
961{ 961{
962 /* Release tty registration of line discipline */ 962 /* Release tty registration of line discipline */
963 int status = tty_register_ldisc(N_HDLC, NULL); 963 int status = tty_unregister_ldisc(N_HDLC);
964 964
965 if (status) 965 if (status)
966 printk(hdlc_unregister_fail, status); 966 printk(hdlc_unregister_fail, status);
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c
index 3883073ab48f..2291a87e8ada 100644
--- a/drivers/char/n_r3964.c
+++ b/drivers/char/n_r3964.c
@@ -200,7 +200,7 @@ static void __exit r3964_exit(void)
200 200
201 TRACE_M ("cleanup_module()"); 201 TRACE_M ("cleanup_module()");
202 202
203 status=tty_register_ldisc(N_R3964, NULL); 203 status=tty_unregister_ldisc(N_R3964);
204 204
205 if(status!=0) 205 if(status!=0)
206 { 206 {
diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c
index f63a3fd7ca6f..1af733d07321 100644
--- a/drivers/char/nvram.c
+++ b/drivers/char/nvram.c
@@ -211,12 +211,13 @@ nvram_check_checksum(void)
211 return rv; 211 return rv;
212} 212}
213 213
214void 214static void
215__nvram_set_checksum(void) 215__nvram_set_checksum(void)
216{ 216{
217 mach_set_checksum(); 217 mach_set_checksum();
218} 218}
219 219
220#if 0
220void 221void
221nvram_set_checksum(void) 222nvram_set_checksum(void)
222{ 223{
@@ -226,6 +227,7 @@ nvram_set_checksum(void)
226 __nvram_set_checksum(); 227 __nvram_set_checksum();
227 spin_unlock_irqrestore(&rtc_lock, flags); 228 spin_unlock_irqrestore(&rtc_lock, flags);
228} 229}
230#endif /* 0 */
229 231
230/* 232/*
231 * The are the file operation function for user access to /dev/nvram 233 * The are the file operation function for user access to /dev/nvram
@@ -921,6 +923,4 @@ EXPORT_SYMBOL(__nvram_write_byte);
921EXPORT_SYMBOL(nvram_write_byte); 923EXPORT_SYMBOL(nvram_write_byte);
922EXPORT_SYMBOL(__nvram_check_checksum); 924EXPORT_SYMBOL(__nvram_check_checksum);
923EXPORT_SYMBOL(nvram_check_checksum); 925EXPORT_SYMBOL(nvram_check_checksum);
924EXPORT_SYMBOL(__nvram_set_checksum);
925EXPORT_SYMBOL(nvram_set_checksum);
926MODULE_ALIAS_MISCDEV(NVRAM_MINOR); 926MODULE_ALIAS_MISCDEV(NVRAM_MINOR);
diff --git a/drivers/char/rio/func.h b/drivers/char/rio/func.h
index e8f3860f4726..01987c6dc398 100644
--- a/drivers/char/rio/func.h
+++ b/drivers/char/rio/func.h
@@ -147,7 +147,6 @@ struct rio_info * rio_info_store( int cmd, struct rio_info * p);
147extern int rio_pcicopy(char *src, char *dst, int n); 147extern int rio_pcicopy(char *src, char *dst, int n);
148extern int rio_minor (struct tty_struct *tty); 148extern int rio_minor (struct tty_struct *tty);
149extern int rio_ismodem (struct tty_struct *tty); 149extern int rio_ismodem (struct tty_struct *tty);
150extern void rio_udelay (int usecs);
151 150
152extern void rio_start_card_running (struct Host * HostP); 151extern void rio_start_card_running (struct Host * HostP);
153 152
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c
index 763893e289b3..7db3370f4972 100644
--- a/drivers/char/rio/rio_linux.c
+++ b/drivers/char/rio/rio_linux.c
@@ -354,11 +354,6 @@ int rio_ismodem(struct tty_struct *tty)
354} 354}
355 355
356 356
357void rio_udelay (int usecs)
358{
359 udelay (usecs);
360}
361
362static int rio_set_real_termios (void *ptr) 357static int rio_set_real_termios (void *ptr)
363{ 358{
364 int rv, modem; 359 int rv, modem;
diff --git a/drivers/char/rio/rioinit.c b/drivers/char/rio/rioinit.c
index dca941ed10cf..898a126ae3e6 100644
--- a/drivers/char/rio/rioinit.c
+++ b/drivers/char/rio/rioinit.c
@@ -37,6 +37,7 @@ static char *_rioinit_c_sccs_ = "@(#)rioinit.c 1.3";
37#include <linux/module.h> 37#include <linux/module.h>
38#include <linux/slab.h> 38#include <linux/slab.h>
39#include <linux/errno.h> 39#include <linux/errno.h>
40#include <linux/delay.h>
40#include <asm/io.h> 41#include <asm/io.h>
41#include <asm/system.h> 42#include <asm/system.h>
42#include <asm/string.h> 43#include <asm/string.h>
@@ -1560,14 +1561,14 @@ uint Slot;
1560 INTERRUPT_DISABLE | BYTE_OPERATION | 1561 INTERRUPT_DISABLE | BYTE_OPERATION |
1561 SLOW_LINKS | SLOW_AT_BUS); 1562 SLOW_LINKS | SLOW_AT_BUS);
1562 WBYTE(DpRamP->DpResetTpu, 0xFF); 1563 WBYTE(DpRamP->DpResetTpu, 0xFF);
1563 rio_udelay (3); 1564 udelay(3);
1564 1565
1565 rio_dprintk (RIO_DEBUG_INIT, "RIOHostReset: Don't know if it worked. Try reset again\n"); 1566 rio_dprintk (RIO_DEBUG_INIT, "RIOHostReset: Don't know if it worked. Try reset again\n");
1566 WBYTE(DpRamP->DpControl, BOOT_FROM_RAM | EXTERNAL_BUS_OFF | 1567 WBYTE(DpRamP->DpControl, BOOT_FROM_RAM | EXTERNAL_BUS_OFF |
1567 INTERRUPT_DISABLE | BYTE_OPERATION | 1568 INTERRUPT_DISABLE | BYTE_OPERATION |
1568 SLOW_LINKS | SLOW_AT_BUS); 1569 SLOW_LINKS | SLOW_AT_BUS);
1569 WBYTE(DpRamP->DpResetTpu, 0xFF); 1570 WBYTE(DpRamP->DpResetTpu, 0xFF);
1570 rio_udelay (3); 1571 udelay(3);
1571 break; 1572 break;
1572#ifdef FUTURE_RELEASE 1573#ifdef FUTURE_RELEASE
1573 case RIO_EISA: 1574 case RIO_EISA:
@@ -1599,7 +1600,7 @@ uint Slot;
1599 DpRamP->DpControl = RIO_PCI_BOOT_FROM_RAM; 1600 DpRamP->DpControl = RIO_PCI_BOOT_FROM_RAM;
1600 DpRamP->DpResetInt = 0xFF; 1601 DpRamP->DpResetInt = 0xFF;
1601 DpRamP->DpResetTpu = 0xFF; 1602 DpRamP->DpResetTpu = 0xFF;
1602 rio_udelay (100); 1603 udelay(100);
1603 /* for (i=0; i<6000; i++); */ 1604 /* for (i=0; i<6000; i++); */
1604 /* suspend( 3 ); */ 1605 /* suspend( 3 ); */
1605 break; 1606 break;
diff --git a/drivers/char/rio/riotty.c b/drivers/char/rio/riotty.c
index db655002671f..78a321afdf4f 100644
--- a/drivers/char/rio/riotty.c
+++ b/drivers/char/rio/riotty.c
@@ -524,16 +524,16 @@ riotclose(void *ptr)
524 register uint SysPort = dev; 524 register uint SysPort = dev;
525 struct ttystatics *tp; /* pointer to our ttystruct */ 525 struct ttystatics *tp; /* pointer to our ttystruct */
526#endif 526#endif
527 struct Port *PortP =ptr; /* pointer to the port structure */ 527 struct Port *PortP = ptr; /* pointer to the port structure */
528 int deleted = 0; 528 int deleted = 0;
529 int try = -1; /* Disable the timeouts by setting them to -1 */ 529 int try = -1; /* Disable the timeouts by setting them to -1 */
530 int repeat_this = -1; /* Congrats to those having 15 years of 530 int repeat_this = -1; /* Congrats to those having 15 years of
531 uptime! (You get to break the driver.) */ 531 uptime! (You get to break the driver.) */
532 long end_time; 532 unsigned long end_time;
533 struct tty_struct * tty; 533 struct tty_struct * tty;
534 unsigned long flags; 534 unsigned long flags;
535 int Modem; 535 int Modem;
536 int rv =0; 536 int rv = 0;
537 537
538 rio_dprintk (RIO_DEBUG_TTY, "port close SysPort %d\n",PortP->PortNum); 538 rio_dprintk (RIO_DEBUG_TTY, "port close SysPort %d\n",PortP->PortNum);
539 539
@@ -620,7 +620,7 @@ riotclose(void *ptr)
620 if (repeat_this -- <= 0) { 620 if (repeat_this -- <= 0) {
621 rv = -EINTR; 621 rv = -EINTR;
622 rio_dprintk (RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n"); 622 rio_dprintk (RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n");
623 RIOPreemptiveCmd(p, PortP, FCLOSE ); 623 RIOPreemptiveCmd(p, PortP, FCLOSE);
624 goto close_end; 624 goto close_end;
625 } 625 }
626 rio_dprintk (RIO_DEBUG_TTY, "Calling timeout to flush in closing\n"); 626 rio_dprintk (RIO_DEBUG_TTY, "Calling timeout to flush in closing\n");
@@ -656,14 +656,12 @@ riotclose(void *ptr)
656 goto close_end; 656 goto close_end;
657 } 657 }
658 658
659
660
661 /* Can't call RIOShortCommand with the port locked. */ 659 /* Can't call RIOShortCommand with the port locked. */
662 rio_spin_unlock_irqrestore(&PortP->portSem, flags); 660 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
663 661
664 if (RIOShortCommand(p, PortP, CLOSE, 1, 0) == RIO_FAIL) { 662 if (RIOShortCommand(p, PortP, CLOSE, 1, 0) == RIO_FAIL) {
665 RIOPreemptiveCmd(p, PortP,FCLOSE); 663 RIOPreemptiveCmd(p, PortP, FCLOSE);
666 goto close_end; 664 goto close_end;
667 } 665 }
668 666
669 if (!deleted) 667 if (!deleted)
@@ -698,7 +696,6 @@ riotclose(void *ptr)
698*/ 696*/
699 PortP->Config &= ~(RIO_CTSFLOW|RIO_RTSFLOW); 697 PortP->Config &= ~(RIO_CTSFLOW|RIO_RTSFLOW);
700 698
701
702#ifdef STATS 699#ifdef STATS
703 PortP->Stat.CloseCnt++; 700 PortP->Stat.CloseCnt++;
704#endif 701#endif
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
index 5bcbeb0cb9ae..f463d6baa685 100644
--- a/drivers/char/rocket.c
+++ b/drivers/char/rocket.c
@@ -161,6 +161,64 @@ static Word_t upci_aiop_intr_bits[AIOP_CTL_SIZE] = {
161 UPCI_AIOP_INTR_BIT_3 161 UPCI_AIOP_INTR_BIT_3
162}; 162};
163 163
164static Byte_t RData[RDATASIZE] = {
165 0x00, 0x09, 0xf6, 0x82,
166 0x02, 0x09, 0x86, 0xfb,
167 0x04, 0x09, 0x00, 0x0a,
168 0x06, 0x09, 0x01, 0x0a,
169 0x08, 0x09, 0x8a, 0x13,
170 0x0a, 0x09, 0xc5, 0x11,
171 0x0c, 0x09, 0x86, 0x85,
172 0x0e, 0x09, 0x20, 0x0a,
173 0x10, 0x09, 0x21, 0x0a,
174 0x12, 0x09, 0x41, 0xff,
175 0x14, 0x09, 0x82, 0x00,
176 0x16, 0x09, 0x82, 0x7b,
177 0x18, 0x09, 0x8a, 0x7d,
178 0x1a, 0x09, 0x88, 0x81,
179 0x1c, 0x09, 0x86, 0x7a,
180 0x1e, 0x09, 0x84, 0x81,
181 0x20, 0x09, 0x82, 0x7c,
182 0x22, 0x09, 0x0a, 0x0a
183};
184
185static Byte_t RRegData[RREGDATASIZE] = {
186 0x00, 0x09, 0xf6, 0x82, /* 00: Stop Rx processor */
187 0x08, 0x09, 0x8a, 0x13, /* 04: Tx software flow control */
188 0x0a, 0x09, 0xc5, 0x11, /* 08: XON char */
189 0x0c, 0x09, 0x86, 0x85, /* 0c: XANY */
190 0x12, 0x09, 0x41, 0xff, /* 10: Rx mask char */
191 0x14, 0x09, 0x82, 0x00, /* 14: Compare/Ignore #0 */
192 0x16, 0x09, 0x82, 0x7b, /* 18: Compare #1 */
193 0x18, 0x09, 0x8a, 0x7d, /* 1c: Compare #2 */
194 0x1a, 0x09, 0x88, 0x81, /* 20: Interrupt #1 */
195 0x1c, 0x09, 0x86, 0x7a, /* 24: Ignore/Replace #1 */
196 0x1e, 0x09, 0x84, 0x81, /* 28: Interrupt #2 */
197 0x20, 0x09, 0x82, 0x7c, /* 2c: Ignore/Replace #2 */
198 0x22, 0x09, 0x0a, 0x0a /* 30: Rx FIFO Enable */
199};
200
201static CONTROLLER_T sController[CTL_SIZE] = {
202 {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
203 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
204 {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
205 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
206 {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
207 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
208 {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
209 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}}
210};
211
212static Byte_t sBitMapClrTbl[8] = {
213 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f
214};
215
216static Byte_t sBitMapSetTbl[8] = {
217 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
218};
219
220static int sClockPrescale = 0x14;
221
164/* 222/*
165 * Line number is the ttySIx number (x), the Minor number. We 223 * Line number is the ttySIx number (x), the Minor number. We
166 * assign them sequentially, starting at zero. The following 224 * assign them sequentially, starting at zero. The following
@@ -177,6 +235,26 @@ static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model);
177static unsigned char GetLineNumber(int ctrl, int aiop, int ch); 235static unsigned char GetLineNumber(int ctrl, int aiop, int ch);
178static unsigned char SetLineNumber(int ctrl, int aiop, int ch); 236static unsigned char SetLineNumber(int ctrl, int aiop, int ch);
179static void rp_start(struct tty_struct *tty); 237static void rp_start(struct tty_struct *tty);
238static int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum,
239 int ChanNum);
240static void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode);
241static void sFlushRxFIFO(CHANNEL_T * ChP);
242static void sFlushTxFIFO(CHANNEL_T * ChP);
243static void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags);
244static void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags);
245static void sModemReset(CONTROLLER_T * CtlP, int chan, int on);
246static void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on);
247static int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data);
248static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum,
249 ByteIO_t * AiopIOList, int AiopIOListSize,
250 WordIO_t ConfigIO, int IRQNum, Byte_t Frequency,
251 int PeriodicOnly, int altChanRingIndicator,
252 int UPCIRingInd);
253static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO,
254 ByteIO_t * AiopIOList, int AiopIOListSize,
255 int IRQNum, Byte_t Frequency, int PeriodicOnly);
256static int sReadAiopID(ByteIO_t io);
257static int sReadAiopNumChan(WordIO_t io);
180 258
181#ifdef MODULE 259#ifdef MODULE
182MODULE_AUTHOR("Theodore Ts'o"); 260MODULE_AUTHOR("Theodore Ts'o");
@@ -1798,7 +1876,7 @@ static void rp_flush_buffer(struct tty_struct *tty)
1798 * init's aiopic and serial port hardware. 1876 * init's aiopic and serial port hardware.
1799 * Inputs: i is the board number (0-n) 1877 * Inputs: i is the board number (0-n)
1800 */ 1878 */
1801__init int register_PCI(int i, struct pci_dev *dev) 1879static __init int register_PCI(int i, struct pci_dev *dev)
1802{ 1880{
1803 int num_aiops, aiop, max_num_aiops, num_chan, chan; 1881 int num_aiops, aiop, max_num_aiops, num_chan, chan;
1804 unsigned int aiopio[MAX_AIOPS_PER_BOARD]; 1882 unsigned int aiopio[MAX_AIOPS_PER_BOARD];
@@ -2453,72 +2531,6 @@ static void rp_cleanup_module(void)
2453} 2531}
2454#endif 2532#endif
2455 2533
2456#ifndef TRUE
2457#define TRUE 1
2458#endif
2459
2460#ifndef FALSE
2461#define FALSE 0
2462#endif
2463
2464static Byte_t RData[RDATASIZE] = {
2465 0x00, 0x09, 0xf6, 0x82,
2466 0x02, 0x09, 0x86, 0xfb,
2467 0x04, 0x09, 0x00, 0x0a,
2468 0x06, 0x09, 0x01, 0x0a,
2469 0x08, 0x09, 0x8a, 0x13,
2470 0x0a, 0x09, 0xc5, 0x11,
2471 0x0c, 0x09, 0x86, 0x85,
2472 0x0e, 0x09, 0x20, 0x0a,
2473 0x10, 0x09, 0x21, 0x0a,
2474 0x12, 0x09, 0x41, 0xff,
2475 0x14, 0x09, 0x82, 0x00,
2476 0x16, 0x09, 0x82, 0x7b,
2477 0x18, 0x09, 0x8a, 0x7d,
2478 0x1a, 0x09, 0x88, 0x81,
2479 0x1c, 0x09, 0x86, 0x7a,
2480 0x1e, 0x09, 0x84, 0x81,
2481 0x20, 0x09, 0x82, 0x7c,
2482 0x22, 0x09, 0x0a, 0x0a
2483};
2484
2485static Byte_t RRegData[RREGDATASIZE] = {
2486 0x00, 0x09, 0xf6, 0x82, /* 00: Stop Rx processor */
2487 0x08, 0x09, 0x8a, 0x13, /* 04: Tx software flow control */
2488 0x0a, 0x09, 0xc5, 0x11, /* 08: XON char */
2489 0x0c, 0x09, 0x86, 0x85, /* 0c: XANY */
2490 0x12, 0x09, 0x41, 0xff, /* 10: Rx mask char */
2491 0x14, 0x09, 0x82, 0x00, /* 14: Compare/Ignore #0 */
2492 0x16, 0x09, 0x82, 0x7b, /* 18: Compare #1 */
2493 0x18, 0x09, 0x8a, 0x7d, /* 1c: Compare #2 */
2494 0x1a, 0x09, 0x88, 0x81, /* 20: Interrupt #1 */
2495 0x1c, 0x09, 0x86, 0x7a, /* 24: Ignore/Replace #1 */
2496 0x1e, 0x09, 0x84, 0x81, /* 28: Interrupt #2 */
2497 0x20, 0x09, 0x82, 0x7c, /* 2c: Ignore/Replace #2 */
2498 0x22, 0x09, 0x0a, 0x0a /* 30: Rx FIFO Enable */
2499};
2500
2501CONTROLLER_T sController[CTL_SIZE] = {
2502 {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
2503 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
2504 {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
2505 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
2506 {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
2507 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
2508 {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
2509 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}}
2510};
2511
2512Byte_t sBitMapClrTbl[8] = {
2513 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f
2514};
2515
2516Byte_t sBitMapSetTbl[8] = {
2517 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
2518};
2519
2520int sClockPrescale = 0x14;
2521
2522/*************************************************************************** 2534/***************************************************************************
2523Function: sInitController 2535Function: sInitController
2524Purpose: Initialization of controller global registers and controller 2536Purpose: Initialization of controller global registers and controller
@@ -2554,22 +2566,22 @@ Call: sInitController(CtlP,CtlNum,MudbacIO,AiopIOList,AiopIOListSize,
2554 FREQ_4HZ - 4 Hertz 2566 FREQ_4HZ - 4 Hertz
2555 If IRQNum is set to 0 the Frequency parameter is 2567 If IRQNum is set to 0 the Frequency parameter is
2556 overidden, it is forced to a value of FREQ_DIS. 2568 overidden, it is forced to a value of FREQ_DIS.
2557 int PeriodicOnly: TRUE if all interrupts except the periodic 2569 int PeriodicOnly: 1 if all interrupts except the periodic
2558 interrupt are to be blocked. 2570 interrupt are to be blocked.
2559 FALSE is both the periodic interrupt and 2571 0 is both the periodic interrupt and
2560 other channel interrupts are allowed. 2572 other channel interrupts are allowed.
2561 If IRQNum is set to 0 the PeriodicOnly parameter is 2573 If IRQNum is set to 0 the PeriodicOnly parameter is
2562 overidden, it is forced to a value of FALSE. 2574 overidden, it is forced to a value of 0.
2563Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller 2575Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller
2564 initialization failed. 2576 initialization failed.
2565 2577
2566Comments: 2578Comments:
2567 If periodic interrupts are to be disabled but AIOP interrupts 2579 If periodic interrupts are to be disabled but AIOP interrupts
2568 are allowed, set Frequency to FREQ_DIS and PeriodicOnly to FALSE. 2580 are allowed, set Frequency to FREQ_DIS and PeriodicOnly to 0.
2569 2581
2570 If interrupts are to be completely disabled set IRQNum to 0. 2582 If interrupts are to be completely disabled set IRQNum to 0.
2571 2583
2572 Setting Frequency to FREQ_DIS and PeriodicOnly to TRUE is an 2584 Setting Frequency to FREQ_DIS and PeriodicOnly to 1 is an
2573 invalid combination. 2585 invalid combination.
2574 2586
2575 This function performs initialization of global interrupt modes, 2587 This function performs initialization of global interrupt modes,
@@ -2589,9 +2601,9 @@ Warnings: No range checking on any of the parameters is done.
2589 After this function all AIOPs on the controller are disabled, 2601 After this function all AIOPs on the controller are disabled,
2590 they can be enabled with sEnAiop(). 2602 they can be enabled with sEnAiop().
2591*/ 2603*/
2592int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO, 2604static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO,
2593 ByteIO_t * AiopIOList, int AiopIOListSize, int IRQNum, 2605 ByteIO_t * AiopIOList, int AiopIOListSize,
2594 Byte_t Frequency, int PeriodicOnly) 2606 int IRQNum, Byte_t Frequency, int PeriodicOnly)
2595{ 2607{
2596 int i; 2608 int i;
2597 ByteIO_t io; 2609 ByteIO_t io;
@@ -2687,22 +2699,22 @@ Call: sPCIInitController(CtlP,CtlNum,AiopIOList,AiopIOListSize,
2687 FREQ_4HZ - 4 Hertz 2699 FREQ_4HZ - 4 Hertz
2688 If IRQNum is set to 0 the Frequency parameter is 2700 If IRQNum is set to 0 the Frequency parameter is
2689 overidden, it is forced to a value of FREQ_DIS. 2701 overidden, it is forced to a value of FREQ_DIS.
2690 int PeriodicOnly: TRUE if all interrupts except the periodic 2702 int PeriodicOnly: 1 if all interrupts except the periodic
2691 interrupt are to be blocked. 2703 interrupt are to be blocked.
2692 FALSE is both the periodic interrupt and 2704 0 is both the periodic interrupt and
2693 other channel interrupts are allowed. 2705 other channel interrupts are allowed.
2694 If IRQNum is set to 0 the PeriodicOnly parameter is 2706 If IRQNum is set to 0 the PeriodicOnly parameter is
2695 overidden, it is forced to a value of FALSE. 2707 overidden, it is forced to a value of 0.
2696Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller 2708Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller
2697 initialization failed. 2709 initialization failed.
2698 2710
2699Comments: 2711Comments:
2700 If periodic interrupts are to be disabled but AIOP interrupts 2712 If periodic interrupts are to be disabled but AIOP interrupts
2701 are allowed, set Frequency to FREQ_DIS and PeriodicOnly to FALSE. 2713 are allowed, set Frequency to FREQ_DIS and PeriodicOnly to 0.
2702 2714
2703 If interrupts are to be completely disabled set IRQNum to 0. 2715 If interrupts are to be completely disabled set IRQNum to 0.
2704 2716
2705 Setting Frequency to FREQ_DIS and PeriodicOnly to TRUE is an 2717 Setting Frequency to FREQ_DIS and PeriodicOnly to 1 is an
2706 invalid combination. 2718 invalid combination.
2707 2719
2708 This function performs initialization of global interrupt modes, 2720 This function performs initialization of global interrupt modes,
@@ -2722,11 +2734,11 @@ Warnings: No range checking on any of the parameters is done.
2722 After this function all AIOPs on the controller are disabled, 2734 After this function all AIOPs on the controller are disabled,
2723 they can be enabled with sEnAiop(). 2735 they can be enabled with sEnAiop().
2724*/ 2736*/
2725int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum, 2737static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum,
2726 ByteIO_t * AiopIOList, int AiopIOListSize, 2738 ByteIO_t * AiopIOList, int AiopIOListSize,
2727 WordIO_t ConfigIO, int IRQNum, Byte_t Frequency, 2739 WordIO_t ConfigIO, int IRQNum, Byte_t Frequency,
2728 int PeriodicOnly, int altChanRingIndicator, 2740 int PeriodicOnly, int altChanRingIndicator,
2729 int UPCIRingInd) 2741 int UPCIRingInd)
2730{ 2742{
2731 int i; 2743 int i;
2732 ByteIO_t io; 2744 ByteIO_t io;
@@ -2784,7 +2796,7 @@ Return: int: Flag AIOPID_XXXX if a valid AIOP is found, where X
2784Warnings: No context switches are allowed while executing this function. 2796Warnings: No context switches are allowed while executing this function.
2785 2797
2786*/ 2798*/
2787int sReadAiopID(ByteIO_t io) 2799static int sReadAiopID(ByteIO_t io)
2788{ 2800{
2789 Byte_t AiopID; /* ID byte from AIOP */ 2801 Byte_t AiopID; /* ID byte from AIOP */
2790 2802
@@ -2810,7 +2822,7 @@ Comments: The number of channels is determined by write/reads from identical
2810 AIOP, otherwise it is an 8 channel. 2822 AIOP, otherwise it is an 8 channel.
2811Warnings: No context switches are allowed while executing this function. 2823Warnings: No context switches are allowed while executing this function.
2812*/ 2824*/
2813int sReadAiopNumChan(WordIO_t io) 2825static int sReadAiopNumChan(WordIO_t io)
2814{ 2826{
2815 Word_t x; 2827 Word_t x;
2816 static Byte_t R[4] = { 0x00, 0x00, 0x34, 0x12 }; 2828 static Byte_t R[4] = { 0x00, 0x00, 0x34, 0x12 };
@@ -2834,15 +2846,15 @@ Call: sInitChan(CtlP,ChP,AiopNum,ChanNum)
2834 CHANNEL_T *ChP; Ptr to channel structure 2846 CHANNEL_T *ChP; Ptr to channel structure
2835 int AiopNum; AIOP number within controller 2847 int AiopNum; AIOP number within controller
2836 int ChanNum; Channel number within AIOP 2848 int ChanNum; Channel number within AIOP
2837Return: int: TRUE if initialization succeeded, FALSE if it fails because channel 2849Return: int: 1 if initialization succeeded, 0 if it fails because channel
2838 number exceeds number of channels available in AIOP. 2850 number exceeds number of channels available in AIOP.
2839Comments: This function must be called before a channel can be used. 2851Comments: This function must be called before a channel can be used.
2840Warnings: No range checking on any of the parameters is done. 2852Warnings: No range checking on any of the parameters is done.
2841 2853
2842 No context switches are allowed while executing this function. 2854 No context switches are allowed while executing this function.
2843*/ 2855*/
2844int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum, 2856static int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum,
2845 int ChanNum) 2857 int ChanNum)
2846{ 2858{
2847 int i; 2859 int i;
2848 WordIO_t AiopIO; 2860 WordIO_t AiopIO;
@@ -2853,7 +2865,7 @@ int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum,
2853 int brd9600; 2865 int brd9600;
2854 2866
2855 if (ChanNum >= CtlP->AiopNumChan[AiopNum]) 2867 if (ChanNum >= CtlP->AiopNumChan[AiopNum])
2856 return (FALSE); /* exceeds num chans in AIOP */ 2868 return 0; /* exceeds num chans in AIOP */
2857 2869
2858 /* Channel, AIOP, and controller identifiers */ 2870 /* Channel, AIOP, and controller identifiers */
2859 ChP->CtlP = CtlP; 2871 ChP->CtlP = CtlP;
@@ -2968,7 +2980,7 @@ int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum,
2968 ChP->TxPrioBuf = ChOff + _TXP_BUF; 2980 ChP->TxPrioBuf = ChOff + _TXP_BUF;
2969 sEnRxProcessor(ChP); /* start the Rx processor */ 2981 sEnRxProcessor(ChP); /* start the Rx processor */
2970 2982
2971 return (TRUE); 2983 return 1;
2972} 2984}
2973 2985
2974/*************************************************************************** 2986/***************************************************************************
@@ -2989,7 +3001,7 @@ Warnings: No context switches are allowed while executing this function.
2989 After calling this function a delay of 4 uS is required to ensure 3001 After calling this function a delay of 4 uS is required to ensure
2990 that the receive processor is no longer processing this channel. 3002 that the receive processor is no longer processing this channel.
2991*/ 3003*/
2992void sStopRxProcessor(CHANNEL_T * ChP) 3004static void sStopRxProcessor(CHANNEL_T * ChP)
2993{ 3005{
2994 Byte_t R[4]; 3006 Byte_t R[4];
2995 3007
@@ -3014,18 +3026,18 @@ Comments: To prevent data from being enqueued or dequeued in the Tx FIFO
3014 this function. 3026 this function.
3015Warnings: No context switches are allowed while executing this function. 3027Warnings: No context switches are allowed while executing this function.
3016*/ 3028*/
3017void sFlushRxFIFO(CHANNEL_T * ChP) 3029static void sFlushRxFIFO(CHANNEL_T * ChP)
3018{ 3030{
3019 int i; 3031 int i;
3020 Byte_t Ch; /* channel number within AIOP */ 3032 Byte_t Ch; /* channel number within AIOP */
3021 int RxFIFOEnabled; /* TRUE if Rx FIFO enabled */ 3033 int RxFIFOEnabled; /* 1 if Rx FIFO enabled */
3022 3034
3023 if (sGetRxCnt(ChP) == 0) /* Rx FIFO empty */ 3035 if (sGetRxCnt(ChP) == 0) /* Rx FIFO empty */
3024 return; /* don't need to flush */ 3036 return; /* don't need to flush */
3025 3037
3026 RxFIFOEnabled = FALSE; 3038 RxFIFOEnabled = 0;
3027 if (ChP->R[0x32] == 0x08) { /* Rx FIFO is enabled */ 3039 if (ChP->R[0x32] == 0x08) { /* Rx FIFO is enabled */
3028 RxFIFOEnabled = TRUE; 3040 RxFIFOEnabled = 1;
3029 sDisRxFIFO(ChP); /* disable it */ 3041 sDisRxFIFO(ChP); /* disable it */
3030 for (i = 0; i < 2000 / 200; i++) /* delay 2 uS to allow proc to disable FIFO */ 3042 for (i = 0; i < 2000 / 200; i++) /* delay 2 uS to allow proc to disable FIFO */
3031 sInB(ChP->IntChan); /* depends on bus i/o timing */ 3043 sInB(ChP->IntChan); /* depends on bus i/o timing */
@@ -3056,18 +3068,18 @@ Comments: To prevent data from being enqueued or dequeued in the Tx FIFO
3056 this function. 3068 this function.
3057Warnings: No context switches are allowed while executing this function. 3069Warnings: No context switches are allowed while executing this function.
3058*/ 3070*/
3059void sFlushTxFIFO(CHANNEL_T * ChP) 3071static void sFlushTxFIFO(CHANNEL_T * ChP)
3060{ 3072{
3061 int i; 3073 int i;
3062 Byte_t Ch; /* channel number within AIOP */ 3074 Byte_t Ch; /* channel number within AIOP */
3063 int TxEnabled; /* TRUE if transmitter enabled */ 3075 int TxEnabled; /* 1 if transmitter enabled */
3064 3076
3065 if (sGetTxCnt(ChP) == 0) /* Tx FIFO empty */ 3077 if (sGetTxCnt(ChP) == 0) /* Tx FIFO empty */
3066 return; /* don't need to flush */ 3078 return; /* don't need to flush */
3067 3079
3068 TxEnabled = FALSE; 3080 TxEnabled = 0;
3069 if (ChP->TxControl[3] & TX_ENABLE) { 3081 if (ChP->TxControl[3] & TX_ENABLE) {
3070 TxEnabled = TRUE; 3082 TxEnabled = 1;
3071 sDisTransmit(ChP); /* disable transmitter */ 3083 sDisTransmit(ChP); /* disable transmitter */
3072 } 3084 }
3073 sStopRxProcessor(ChP); /* stop Rx processor */ 3085 sStopRxProcessor(ChP); /* stop Rx processor */
@@ -3096,7 +3108,7 @@ Comments: The priority byte is transmitted before any data in the Tx FIFO.
3096 3108
3097Warnings: No context switches are allowed while executing this function. 3109Warnings: No context switches are allowed while executing this function.
3098*/ 3110*/
3099int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data) 3111static int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data)
3100{ 3112{
3101 Byte_t DWBuf[4]; /* buffer for double word writes */ 3113 Byte_t DWBuf[4]; /* buffer for double word writes */
3102 Word_t *WordPtr; /* must be far because Win SS != DS */ 3114 Word_t *WordPtr; /* must be far because Win SS != DS */
@@ -3158,7 +3170,7 @@ Comments: If an interrupt enable flag is set in Flags, that interrupt will be
3158 enable channel interrupts. This would allow the global interrupt 3170 enable channel interrupts. This would allow the global interrupt
3159 status register to be used to determine which AIOPs need service. 3171 status register to be used to determine which AIOPs need service.
3160*/ 3172*/
3161void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags) 3173static void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags)
3162{ 3174{
3163 Byte_t Mask; /* Interrupt Mask Register */ 3175 Byte_t Mask; /* Interrupt Mask Register */
3164 3176
@@ -3202,7 +3214,7 @@ Comments: If an interrupt flag is set in Flags, that interrupt will be
3202 this channel's bit from being set in the AIOP's Interrupt Channel 3214 this channel's bit from being set in the AIOP's Interrupt Channel
3203 Register. 3215 Register.
3204*/ 3216*/
3205void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags) 3217static void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags)
3206{ 3218{
3207 Byte_t Mask; /* Interrupt Mask Register */ 3219 Byte_t Mask; /* Interrupt Mask Register */
3208 3220
@@ -3218,7 +3230,7 @@ void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags)
3218 } 3230 }
3219} 3231}
3220 3232
3221void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode) 3233static void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode)
3222{ 3234{
3223 sOutB(ChP->CtlP->AiopIO[2], (mode & 0x18) | ChP->ChanNum); 3235 sOutB(ChP->CtlP->AiopIO[2], (mode & 0x18) | ChP->ChanNum);
3224} 3236}
@@ -3227,7 +3239,7 @@ void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode)
3227 * Not an official SSCI function, but how to reset RocketModems. 3239 * Not an official SSCI function, but how to reset RocketModems.
3228 * ISA bus version 3240 * ISA bus version
3229 */ 3241 */
3230void sModemReset(CONTROLLER_T * CtlP, int chan, int on) 3242static void sModemReset(CONTROLLER_T * CtlP, int chan, int on)
3231{ 3243{
3232 ByteIO_t addr; 3244 ByteIO_t addr;
3233 Byte_t val; 3245 Byte_t val;
@@ -3252,7 +3264,7 @@ void sModemReset(CONTROLLER_T * CtlP, int chan, int on)
3252 * Not an official SSCI function, but how to reset RocketModems. 3264 * Not an official SSCI function, but how to reset RocketModems.
3253 * PCI bus version 3265 * PCI bus version
3254 */ 3266 */
3255void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on) 3267static void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on)
3256{ 3268{
3257 ByteIO_t addr; 3269 ByteIO_t addr;
3258 3270
diff --git a/drivers/char/rocket_int.h b/drivers/char/rocket_int.h
index 802687290ee1..3a8bcc85bc14 100644
--- a/drivers/char/rocket_int.h
+++ b/drivers/char/rocket_int.h
@@ -1130,46 +1130,6 @@ Warnings: This function writes the data byte without checking to see if
1130*/ 1130*/
1131#define sWriteTxByte(IO,DATA) sOutB(IO,DATA) 1131#define sWriteTxByte(IO,DATA) sOutB(IO,DATA)
1132 1132
1133int sInitController(CONTROLLER_T * CtlP,
1134 int CtlNum,
1135 ByteIO_t MudbacIO,
1136 ByteIO_t * AiopIOList,
1137 int AiopIOListSize,
1138 int IRQNum, Byte_t Frequency, int PeriodicOnly);
1139
1140int sPCIInitController(CONTROLLER_T * CtlP,
1141 int CtlNum,
1142 ByteIO_t * AiopIOList,
1143 int AiopIOListSize,
1144 WordIO_t ConfigIO,
1145 int IRQNum,
1146 Byte_t Frequency,
1147 int PeriodicOnly,
1148 int altChanRingIndicator, int UPCIRingInd);
1149
1150int sReadAiopID(ByteIO_t io);
1151int sReadAiopNumChan(WordIO_t io);
1152int sInitChan(CONTROLLER_T * CtlP,
1153 CHANNEL_T * ChP, int AiopNum, int ChanNum);
1154Byte_t sGetRxErrStatus(CHANNEL_T * ChP);
1155void sStopRxProcessor(CHANNEL_T * ChP);
1156void sStopSWInFlowCtl(CHANNEL_T * ChP);
1157void sFlushRxFIFO(CHANNEL_T * ChP);
1158void sFlushTxFIFO(CHANNEL_T * ChP);
1159int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data);
1160void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags);
1161void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags);
1162void sModemReset(CONTROLLER_T * CtlP, int chan, int on);
1163void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on);
1164void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode);
1165
1166extern Byte_t R[RDATASIZE];
1167extern CONTROLLER_T sController[CTL_SIZE];
1168extern Byte_t sIRQMap[16];
1169extern Byte_t sBitMapClrTbl[8];
1170extern Byte_t sBitMapSetTbl[8];
1171extern int sClockPrescale;
1172
1173/* 1133/*
1174 * Begin Linux specific definitions for the Rocketport driver 1134 * Begin Linux specific definitions for the Rocketport driver
1175 * 1135 *
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index f59f7cbd525b..af79805b5576 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -35,6 +35,7 @@
35#include <linux/spinlock.h> 35#include <linux/spinlock.h>
36#include <linux/vt_kern.h> 36#include <linux/vt_kern.h>
37#include <linux/workqueue.h> 37#include <linux/workqueue.h>
38#include <linux/kexec.h>
38 39
39#include <asm/ptrace.h> 40#include <asm/ptrace.h>
40 41
@@ -94,6 +95,21 @@ static struct sysrq_key_op sysrq_unraw_op = {
94}; 95};
95#endif /* CONFIG_VT */ 96#endif /* CONFIG_VT */
96 97
98#ifdef CONFIG_KEXEC
99/* crashdump sysrq handler */
100static void sysrq_handle_crashdump(int key, struct pt_regs *pt_regs,
101 struct tty_struct *tty)
102{
103 crash_kexec(pt_regs);
104}
105static struct sysrq_key_op sysrq_crashdump_op = {
106 .handler = sysrq_handle_crashdump,
107 .help_msg = "Crashdump",
108 .action_msg = "Trigger a crashdump",
109 .enable_mask = SYSRQ_ENABLE_DUMP,
110};
111#endif
112
97/* reboot sysrq handler */ 113/* reboot sysrq handler */
98static void sysrq_handle_reboot(int key, struct pt_regs *pt_regs, 114static void sysrq_handle_reboot(int key, struct pt_regs *pt_regs,
99 struct tty_struct *tty) 115 struct tty_struct *tty)
@@ -273,8 +289,12 @@ static struct sysrq_key_op *sysrq_key_table[SYSRQ_KEY_TABLE_LENGTH] = {
273 it is handled specially on the sparc 289 it is handled specially on the sparc
274 and will never arrive */ 290 and will never arrive */
275/* b */ &sysrq_reboot_op, 291/* b */ &sysrq_reboot_op,
276/* c */ NULL, 292#ifdef CONFIG_KEXEC
277/* d */ NULL, 293/* c */ &sysrq_crashdump_op,
294#else
295/* c */ NULL,
296#endif
297/* d */ NULL,
278/* e */ &sysrq_term_op, 298/* e */ &sysrq_term_op,
279/* f */ &sysrq_moom_op, 299/* f */ &sysrq_moom_op,
280/* g */ NULL, 300/* g */ NULL,
diff --git a/drivers/char/toshiba.c b/drivers/char/toshiba.c
index 58e21fe44262..0c6f521abd0e 100644
--- a/drivers/char/toshiba.c
+++ b/drivers/char/toshiba.c
@@ -73,16 +73,20 @@
73 73
74#define TOSH_MINOR_DEV 181 74#define TOSH_MINOR_DEV 181
75 75
76static int tosh_id = 0x0000; 76MODULE_LICENSE("GPL");
77static int tosh_bios = 0x0000; 77MODULE_AUTHOR("Jonathan Buzzard <jonathan@buzzard.org.uk>");
78static int tosh_date = 0x0000; 78MODULE_DESCRIPTION("Toshiba laptop SMM driver");
79static int tosh_sci = 0x0000; 79MODULE_SUPPORTED_DEVICE("toshiba");
80static int tosh_fan = 0;
81
82static int tosh_fn = 0;
83 80
84module_param(tosh_fn, int, 0); 81static int tosh_fn;
82module_param_named(fn, tosh_fn, int, 0);
83MODULE_PARM_DESC(fn, "User specified Fn key detection port");
85 84
85static int tosh_id;
86static int tosh_bios;
87static int tosh_date;
88static int tosh_sci;
89static int tosh_fan;
86 90
87static int tosh_ioctl(struct inode *, struct file *, unsigned int, 91static int tosh_ioctl(struct inode *, struct file *, unsigned int,
88 unsigned long); 92 unsigned long);
@@ -359,7 +363,7 @@ static int tosh_get_machine_id(void)
359 unsigned long address; 363 unsigned long address;
360 364
361 id = (0x100*(int) isa_readb(0xffffe))+((int) isa_readb(0xffffa)); 365 id = (0x100*(int) isa_readb(0xffffe))+((int) isa_readb(0xffffa));
362 366
363 /* do we have a SCTTable machine identication number on our hands */ 367 /* do we have a SCTTable machine identication number on our hands */
364 368
365 if (id==0xfc2f) { 369 if (id==0xfc2f) {
@@ -424,7 +428,7 @@ static int tosh_probe(void)
424 } 428 }
425 429
426 /* call the Toshiba SCI support check routine */ 430 /* call the Toshiba SCI support check routine */
427 431
428 regs.eax = 0xf0f0; 432 regs.eax = 0xf0f0;
429 regs.ebx = 0x0000; 433 regs.ebx = 0x0000;
430 regs.ecx = 0x0000; 434 regs.ecx = 0x0000;
@@ -440,7 +444,7 @@ static int tosh_probe(void)
440 /* if we get this far then we are running on a Toshiba (probably)! */ 444 /* if we get this far then we are running on a Toshiba (probably)! */
441 445
442 tosh_sci = regs.edx & 0xffff; 446 tosh_sci = regs.edx & 0xffff;
443 447
444 /* next get the machine ID of the current laptop */ 448 /* next get the machine ID of the current laptop */
445 449
446 tosh_id = tosh_get_machine_id(); 450 tosh_id = tosh_get_machine_id();
@@ -475,16 +479,15 @@ static int tosh_probe(void)
475 return 0; 479 return 0;
476} 480}
477 481
478int __init tosh_init(void) 482static int __init toshiba_init(void)
479{ 483{
480 int retval; 484 int retval;
481 /* are we running on a Toshiba laptop */ 485 /* are we running on a Toshiba laptop */
482 486
483 if (tosh_probe()!=0) 487 if (tosh_probe())
484 return -EIO; 488 return -ENODEV;
485 489
486 printk(KERN_INFO "Toshiba System Managment Mode driver v" 490 printk(KERN_INFO "Toshiba System Managment Mode driver v" TOSH_VERSION "\n");
487 TOSH_VERSION"\n");
488 491
489 /* set the port to use for Fn status if not specified as a parameter */ 492 /* set the port to use for Fn status if not specified as a parameter */
490 if (tosh_fn==0x00) 493 if (tosh_fn==0x00)
@@ -492,12 +495,12 @@ int __init tosh_init(void)
492 495
493 /* register the device file */ 496 /* register the device file */
494 retval = misc_register(&tosh_device); 497 retval = misc_register(&tosh_device);
495 if(retval < 0) 498 if (retval < 0)
496 return retval; 499 return retval;
497 500
498#ifdef CONFIG_PROC_FS 501#ifdef CONFIG_PROC_FS
499 /* register the proc entry */ 502 /* register the proc entry */
500 if(create_proc_info_entry("toshiba", 0, NULL, tosh_get_info) == NULL){ 503 if (create_proc_info_entry("toshiba", 0, NULL, tosh_get_info) == NULL) {
501 misc_deregister(&tosh_device); 504 misc_deregister(&tosh_device);
502 return -ENOMEM; 505 return -ENOMEM;
503 } 506 }
@@ -506,27 +509,12 @@ int __init tosh_init(void)
506 return 0; 509 return 0;
507} 510}
508 511
509#ifdef MODULE 512static void __exit toshiba_exit(void)
510int init_module(void)
511{
512 return tosh_init();
513}
514
515void cleanup_module(void)
516{ 513{
517 /* remove the proc entry */
518
519 remove_proc_entry("toshiba", NULL); 514 remove_proc_entry("toshiba", NULL);
520
521 /* unregister the device file */
522
523 misc_deregister(&tosh_device); 515 misc_deregister(&tosh_device);
524} 516}
525#endif
526 517
527MODULE_LICENSE("GPL"); 518module_init(toshiba_init);
528MODULE_PARM_DESC(tosh_fn, "User specified Fn key detection port"); 519module_exit(toshiba_exit);
529MODULE_AUTHOR("Jonathan Buzzard <jonathan@buzzard.org.uk>");
530MODULE_DESCRIPTION("Toshiba laptop SMM driver");
531MODULE_SUPPORTED_DEVICE("toshiba");
532 520
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 8ce508b29865..854475c54f0e 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -19,7 +19,7 @@
19 * 19 *
20 * Note, the TPM chip is not interrupt driven (only polling) 20 * Note, the TPM chip is not interrupt driven (only polling)
21 * and can have very long timeouts (minutes!). Hence the unusual 21 * and can have very long timeouts (minutes!). Hence the unusual
22 * calls to schedule_timeout. 22 * calls to msleep.
23 * 23 *
24 */ 24 */
25 25
@@ -28,19 +28,16 @@
28#include <linux/spinlock.h> 28#include <linux/spinlock.h>
29#include "tpm.h" 29#include "tpm.h"
30 30
31#define TPM_MINOR 224 /* officially assigned */ 31enum tpm_const {
32 32 TPM_MINOR = 224, /* officially assigned */
33#define TPM_BUFSIZE 2048 33 TPM_BUFSIZE = 2048,
34 34 TPM_NUM_DEVICES = 256,
35/* PCI configuration addresses */ 35 TPM_NUM_MASK_ENTRIES = TPM_NUM_DEVICES / (8 * sizeof(int))
36#define PCI_GEN_PMCON_1 0xA0 36};
37#define PCI_GEN1_DEC 0xE4
38#define PCI_LPC_EN 0xE6
39#define PCI_GEN2_DEC 0xEC
40 37
41static LIST_HEAD(tpm_chip_list); 38static LIST_HEAD(tpm_chip_list);
42static DEFINE_SPINLOCK(driver_lock); 39static DEFINE_SPINLOCK(driver_lock);
43static int dev_mask[32]; 40static int dev_mask[TPM_NUM_MASK_ENTRIES];
44 41
45static void user_reader_timeout(unsigned long ptr) 42static void user_reader_timeout(unsigned long ptr)
46{ 43{
@@ -52,92 +49,17 @@ static void user_reader_timeout(unsigned long ptr)
52 up(&chip->buffer_mutex); 49 up(&chip->buffer_mutex);
53} 50}
54 51
55void tpm_time_expired(unsigned long ptr)
56{
57 int *exp = (int *) ptr;
58 *exp = 1;
59}
60
61EXPORT_SYMBOL_GPL(tpm_time_expired);
62
63/*
64 * Initialize the LPC bus and enable the TPM ports
65 */
66int tpm_lpc_bus_init(struct pci_dev *pci_dev, u16 base)
67{
68 u32 lpcenable, tmp;
69 int is_lpcm = 0;
70
71 switch (pci_dev->vendor) {
72 case PCI_VENDOR_ID_INTEL:
73 switch (pci_dev->device) {
74 case PCI_DEVICE_ID_INTEL_82801CA_12:
75 case PCI_DEVICE_ID_INTEL_82801DB_12:
76 is_lpcm = 1;
77 break;
78 }
79 /* init ICH (enable LPC) */
80 pci_read_config_dword(pci_dev, PCI_GEN1_DEC, &lpcenable);
81 lpcenable |= 0x20000000;
82 pci_write_config_dword(pci_dev, PCI_GEN1_DEC, lpcenable);
83
84 if (is_lpcm) {
85 pci_read_config_dword(pci_dev, PCI_GEN1_DEC,
86 &lpcenable);
87 if ((lpcenable & 0x20000000) == 0) {
88 dev_err(&pci_dev->dev,
89 "cannot enable LPC\n");
90 return -ENODEV;
91 }
92 }
93
94 /* initialize TPM registers */
95 pci_read_config_dword(pci_dev, PCI_GEN2_DEC, &tmp);
96
97 if (!is_lpcm)
98 tmp = (tmp & 0xFFFF0000) | (base & 0xFFF0);
99 else
100 tmp =
101 (tmp & 0xFFFF0000) | (base & 0xFFF0) |
102 0x00000001;
103
104 pci_write_config_dword(pci_dev, PCI_GEN2_DEC, tmp);
105
106 if (is_lpcm) {
107 pci_read_config_dword(pci_dev, PCI_GEN_PMCON_1,
108 &tmp);
109 tmp |= 0x00000004; /* enable CLKRUN */
110 pci_write_config_dword(pci_dev, PCI_GEN_PMCON_1,
111 tmp);
112 }
113 tpm_write_index(0x0D, 0x55); /* unlock 4F */
114 tpm_write_index(0x0A, 0x00); /* int disable */
115 tpm_write_index(0x08, base); /* base addr lo */
116 tpm_write_index(0x09, (base & 0xFF00) >> 8); /* base addr hi */
117 tpm_write_index(0x0D, 0xAA); /* lock 4F */
118 break;
119 case PCI_VENDOR_ID_AMD:
120 /* nothing yet */
121 break;
122 }
123
124 return 0;
125}
126
127EXPORT_SYMBOL_GPL(tpm_lpc_bus_init);
128
129/* 52/*
130 * Internal kernel interface to transmit TPM commands 53 * Internal kernel interface to transmit TPM commands
131 */ 54 */
132static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, 55static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
133 size_t bufsiz) 56 size_t bufsiz)
134{ 57{
135 ssize_t len; 58 ssize_t rc;
136 u32 count; 59 u32 count;
137 __be32 *native_size; 60 unsigned long stop;
138 61
139 native_size = (__force __be32 *) (buf + 2); 62 count = be32_to_cpu(*((__be32 *) (buf + 2)));
140 count = be32_to_cpu(*native_size);
141 63
142 if (count == 0) 64 if (count == 0)
143 return -ENODATA; 65 return -ENODATA;
@@ -149,53 +71,49 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
149 71
150 down(&chip->tpm_mutex); 72 down(&chip->tpm_mutex);
151 73
152 if ((len = chip->vendor->send(chip, (u8 *) buf, count)) < 0) { 74 if ((rc = chip->vendor->send(chip, (u8 *) buf, count)) < 0) {
153 dev_err(&chip->pci_dev->dev, 75 dev_err(&chip->pci_dev->dev,
154 "tpm_transmit: tpm_send: error %zd\n", len); 76 "tpm_transmit: tpm_send: error %zd\n", rc);
155 return len; 77 goto out;
156 } 78 }
157 79
158 down(&chip->timer_manipulation_mutex); 80 stop = jiffies + 2 * 60 * HZ;
159 chip->time_expired = 0;
160 init_timer(&chip->device_timer);
161 chip->device_timer.function = tpm_time_expired;
162 chip->device_timer.expires = jiffies + 2 * 60 * HZ;
163 chip->device_timer.data = (unsigned long) &chip->time_expired;
164 add_timer(&chip->device_timer);
165 up(&chip->timer_manipulation_mutex);
166
167 do { 81 do {
168 u8 status = inb(chip->vendor->base + 1); 82 u8 status = inb(chip->vendor->base + 1);
169 if ((status & chip->vendor->req_complete_mask) == 83 if ((status & chip->vendor->req_complete_mask) ==
170 chip->vendor->req_complete_val) { 84 chip->vendor->req_complete_val) {
171 down(&chip->timer_manipulation_mutex);
172 del_singleshot_timer_sync(&chip->device_timer);
173 up(&chip->timer_manipulation_mutex);
174 goto out_recv; 85 goto out_recv;
175 } 86 }
176 set_current_state(TASK_UNINTERRUPTIBLE); 87
177 schedule_timeout(TPM_TIMEOUT); 88 if ((status == chip->vendor->req_canceled)) {
89 dev_err(&chip->pci_dev->dev, "Operation Canceled\n");
90 rc = -ECANCELED;
91 goto out;
92 }
93
94 msleep(TPM_TIMEOUT); /* CHECK */
178 rmb(); 95 rmb();
179 } while (!chip->time_expired); 96 } while (time_before(jiffies, stop));
180 97
181 98
182 chip->vendor->cancel(chip); 99 chip->vendor->cancel(chip);
183 dev_err(&chip->pci_dev->dev, "Time expired\n"); 100 dev_err(&chip->pci_dev->dev, "Operation Timed out\n");
184 up(&chip->tpm_mutex); 101 rc = -ETIME;
185 return -EIO; 102 goto out;
186 103
187out_recv: 104out_recv:
188 len = chip->vendor->recv(chip, (u8 *) buf, bufsiz); 105 rc = chip->vendor->recv(chip, (u8 *) buf, bufsiz);
189 if (len < 0) 106 if (rc < 0)
190 dev_err(&chip->pci_dev->dev, 107 dev_err(&chip->pci_dev->dev,
191 "tpm_transmit: tpm_recv: error %zd\n", len); 108 "tpm_transmit: tpm_recv: error %zd\n", rc);
109out:
192 up(&chip->tpm_mutex); 110 up(&chip->tpm_mutex);
193 return len; 111 return rc;
194} 112}
195 113
196#define TPM_DIGEST_SIZE 20 114#define TPM_DIGEST_SIZE 20
197#define CAP_PCR_RESULT_SIZE 18 115#define CAP_PCR_RESULT_SIZE 18
198static u8 cap_pcr[] = { 116static const u8 cap_pcr[] = {
199 0, 193, /* TPM_TAG_RQU_COMMAND */ 117 0, 193, /* TPM_TAG_RQU_COMMAND */
200 0, 0, 0, 22, /* length */ 118 0, 0, 0, 22, /* length */
201 0, 0, 0, 101, /* TPM_ORD_GetCapability */ 119 0, 0, 0, 101, /* TPM_ORD_GetCapability */
@@ -205,75 +123,94 @@ static u8 cap_pcr[] = {
205}; 123};
206 124
207#define READ_PCR_RESULT_SIZE 30 125#define READ_PCR_RESULT_SIZE 30
208static u8 pcrread[] = { 126static const u8 pcrread[] = {
209 0, 193, /* TPM_TAG_RQU_COMMAND */ 127 0, 193, /* TPM_TAG_RQU_COMMAND */
210 0, 0, 0, 14, /* length */ 128 0, 0, 0, 14, /* length */
211 0, 0, 0, 21, /* TPM_ORD_PcrRead */ 129 0, 0, 0, 21, /* TPM_ORD_PcrRead */
212 0, 0, 0, 0 /* PCR index */ 130 0, 0, 0, 0 /* PCR index */
213}; 131};
214 132
215static ssize_t show_pcrs(struct device *dev, struct device_attribute *attr, char *buf) 133ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
134 char *buf)
216{ 135{
217 u8 data[READ_PCR_RESULT_SIZE]; 136 u8 data[READ_PCR_RESULT_SIZE];
218 ssize_t len; 137 ssize_t len;
219 int i, j, index, num_pcrs; 138 int i, j, num_pcrs;
139 __be32 index;
220 char *str = buf; 140 char *str = buf;
221 141
222 struct tpm_chip *chip = 142 struct tpm_chip *chip =
223 pci_get_drvdata(container_of(dev, struct pci_dev, dev)); 143 pci_get_drvdata(to_pci_dev(dev));
224 if (chip == NULL) 144 if (chip == NULL)
225 return -ENODEV; 145 return -ENODEV;
226 146
227 memcpy(data, cap_pcr, sizeof(cap_pcr)); 147 memcpy(data, cap_pcr, sizeof(cap_pcr));
228 if ((len = tpm_transmit(chip, data, sizeof(data))) 148 if ((len = tpm_transmit(chip, data, sizeof(data)))
229 < CAP_PCR_RESULT_SIZE) 149 < CAP_PCR_RESULT_SIZE) {
230 return len; 150 dev_dbg(&chip->pci_dev->dev, "A TPM error (%d) occurred "
151 "attempting to determine the number of PCRS\n",
152 be32_to_cpu(*((__be32 *) (data + 6))));
153 return 0;
154 }
231 155
232 num_pcrs = be32_to_cpu(*((__force __be32 *) (data + 14))); 156 num_pcrs = be32_to_cpu(*((__be32 *) (data + 14)));
233 157
234 for (i = 0; i < num_pcrs; i++) { 158 for (i = 0; i < num_pcrs; i++) {
235 memcpy(data, pcrread, sizeof(pcrread)); 159 memcpy(data, pcrread, sizeof(pcrread));
236 index = cpu_to_be32(i); 160 index = cpu_to_be32(i);
237 memcpy(data + 10, &index, 4); 161 memcpy(data + 10, &index, 4);
238 if ((len = tpm_transmit(chip, data, sizeof(data))) 162 if ((len = tpm_transmit(chip, data, sizeof(data)))
239 < READ_PCR_RESULT_SIZE) 163 < READ_PCR_RESULT_SIZE){
240 return len; 164 dev_dbg(&chip->pci_dev->dev, "A TPM error (%d) occurred"
165 " attempting to read PCR %d of %d\n",
166 be32_to_cpu(*((__be32 *) (data + 6))), i, num_pcrs);
167 goto out;
168 }
241 str += sprintf(str, "PCR-%02d: ", i); 169 str += sprintf(str, "PCR-%02d: ", i);
242 for (j = 0; j < TPM_DIGEST_SIZE; j++) 170 for (j = 0; j < TPM_DIGEST_SIZE; j++)
243 str += sprintf(str, "%02X ", *(data + 10 + j)); 171 str += sprintf(str, "%02X ", *(data + 10 + j));
244 str += sprintf(str, "\n"); 172 str += sprintf(str, "\n");
245 } 173 }
174out:
246 return str - buf; 175 return str - buf;
247} 176}
248 177EXPORT_SYMBOL_GPL(tpm_show_pcrs);
249static DEVICE_ATTR(pcrs, S_IRUGO, show_pcrs, NULL);
250 178
251#define READ_PUBEK_RESULT_SIZE 314 179#define READ_PUBEK_RESULT_SIZE 314
252static u8 readpubek[] = { 180static const u8 readpubek[] = {
253 0, 193, /* TPM_TAG_RQU_COMMAND */ 181 0, 193, /* TPM_TAG_RQU_COMMAND */
254 0, 0, 0, 30, /* length */ 182 0, 0, 0, 30, /* length */
255 0, 0, 0, 124, /* TPM_ORD_ReadPubek */ 183 0, 0, 0, 124, /* TPM_ORD_ReadPubek */
256}; 184};
257 185
258static ssize_t show_pubek(struct device *dev, struct device_attribute *attr, char *buf) 186ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr,
187 char *buf)
259{ 188{
260 u8 data[READ_PUBEK_RESULT_SIZE]; 189 u8 *data;
261 ssize_t len; 190 ssize_t len;
262 __be32 *native_val; 191 int i, rc;
263 int i;
264 char *str = buf; 192 char *str = buf;
265 193
266 struct tpm_chip *chip = 194 struct tpm_chip *chip =
267 pci_get_drvdata(container_of(dev, struct pci_dev, dev)); 195 pci_get_drvdata(to_pci_dev(dev));
268 if (chip == NULL) 196 if (chip == NULL)
269 return -ENODEV; 197 return -ENODEV;
270 198
199 data = kmalloc(READ_PUBEK_RESULT_SIZE, GFP_KERNEL);
200 if (!data)
201 return -ENOMEM;
202
271 memcpy(data, readpubek, sizeof(readpubek)); 203 memcpy(data, readpubek, sizeof(readpubek));
272 memset(data + sizeof(readpubek), 0, 20); /* zero nonce */ 204 memset(data + sizeof(readpubek), 0, 20); /* zero nonce */
273 205
274 if ((len = tpm_transmit(chip, data, sizeof(data))) < 206 if ((len = tpm_transmit(chip, data, READ_PUBEK_RESULT_SIZE)) <
275 READ_PUBEK_RESULT_SIZE) 207 READ_PUBEK_RESULT_SIZE) {
276 return len; 208 dev_dbg(&chip->pci_dev->dev, "A TPM error (%d) occurred "
209 "attempting to read the PUBEK\n",
210 be32_to_cpu(*((__be32 *) (data + 6))));
211 rc = 0;
212 goto out;
213 }
277 214
278 /* 215 /*
279 ignore header 10 bytes 216 ignore header 10 bytes
@@ -286,8 +223,6 @@ static ssize_t show_pubek(struct device *dev, struct device_attribute *attr, cha
286 ignore checksum 20 bytes 223 ignore checksum 20 bytes
287 */ 224 */
288 225
289 native_val = (__force __be32 *) (data + 34);
290
291 str += 226 str +=
292 sprintf(str, 227 sprintf(str,
293 "Algorithm: %02X %02X %02X %02X\nEncscheme: %02X %02X\n" 228 "Algorithm: %02X %02X %02X %02X\nEncscheme: %02X %02X\n"
@@ -298,21 +233,23 @@ static ssize_t show_pubek(struct device *dev, struct device_attribute *attr, cha
298 data[15], data[16], data[17], data[22], data[23], 233 data[15], data[16], data[17], data[22], data[23],
299 data[24], data[25], data[26], data[27], data[28], 234 data[24], data[25], data[26], data[27], data[28],
300 data[29], data[30], data[31], data[32], data[33], 235 data[29], data[30], data[31], data[32], data[33],
301 be32_to_cpu(*native_val) 236 be32_to_cpu(*((__be32 *) (data + 34))));
302 );
303 237
304 for (i = 0; i < 256; i++) { 238 for (i = 0; i < 256; i++) {
305 str += sprintf(str, "%02X ", data[i + 39]); 239 str += sprintf(str, "%02X ", data[i + 38]);
306 if ((i + 1) % 16 == 0) 240 if ((i + 1) % 16 == 0)
307 str += sprintf(str, "\n"); 241 str += sprintf(str, "\n");
308 } 242 }
309 return str - buf; 243 rc = str - buf;
244out:
245 kfree(data);
246 return rc;
310} 247}
311 248
312static DEVICE_ATTR(pubek, S_IRUGO, show_pubek, NULL); 249EXPORT_SYMBOL_GPL(tpm_show_pubek);
313 250
314#define CAP_VER_RESULT_SIZE 18 251#define CAP_VER_RESULT_SIZE 18
315static u8 cap_version[] = { 252static const u8 cap_version[] = {
316 0, 193, /* TPM_TAG_RQU_COMMAND */ 253 0, 193, /* TPM_TAG_RQU_COMMAND */
317 0, 0, 0, 18, /* length */ 254 0, 0, 0, 18, /* length */
318 0, 0, 0, 101, /* TPM_ORD_GetCapability */ 255 0, 0, 0, 101, /* TPM_ORD_GetCapability */
@@ -321,7 +258,7 @@ static u8 cap_version[] = {
321}; 258};
322 259
323#define CAP_MANUFACTURER_RESULT_SIZE 18 260#define CAP_MANUFACTURER_RESULT_SIZE 18
324static u8 cap_manufacturer[] = { 261static const u8 cap_manufacturer[] = {
325 0, 193, /* TPM_TAG_RQU_COMMAND */ 262 0, 193, /* TPM_TAG_RQU_COMMAND */
326 0, 0, 0, 22, /* length */ 263 0, 0, 0, 22, /* length */
327 0, 0, 0, 101, /* TPM_ORD_GetCapability */ 264 0, 0, 0, 101, /* TPM_ORD_GetCapability */
@@ -330,14 +267,15 @@ static u8 cap_manufacturer[] = {
330 0, 0, 1, 3 267 0, 0, 1, 3
331}; 268};
332 269
333static ssize_t show_caps(struct device *dev, struct device_attribute *attr, char *buf) 270ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
271 char *buf)
334{ 272{
335 u8 data[READ_PUBEK_RESULT_SIZE]; 273 u8 data[sizeof(cap_manufacturer)];
336 ssize_t len; 274 ssize_t len;
337 char *str = buf; 275 char *str = buf;
338 276
339 struct tpm_chip *chip = 277 struct tpm_chip *chip =
340 pci_get_drvdata(container_of(dev, struct pci_dev, dev)); 278 pci_get_drvdata(to_pci_dev(dev));
341 if (chip == NULL) 279 if (chip == NULL)
342 return -ENODEV; 280 return -ENODEV;
343 281
@@ -348,7 +286,7 @@ static ssize_t show_caps(struct device *dev, struct device_attribute *attr, char
348 return len; 286 return len;
349 287
350 str += sprintf(str, "Manufacturer: 0x%x\n", 288 str += sprintf(str, "Manufacturer: 0x%x\n",
351 be32_to_cpu(*(data + 14))); 289 be32_to_cpu(*((__be32 *) (data + 14))));
352 290
353 memcpy(data, cap_version, sizeof(cap_version)); 291 memcpy(data, cap_version, sizeof(cap_version));
354 292
@@ -363,8 +301,20 @@ static ssize_t show_caps(struct device *dev, struct device_attribute *attr, char
363 301
364 return str - buf; 302 return str - buf;
365} 303}
304EXPORT_SYMBOL_GPL(tpm_show_caps);
305
306ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr,
307 const char *buf, size_t count)
308{
309 struct tpm_chip *chip = dev_get_drvdata(dev);
310 if (chip == NULL)
311 return 0;
312
313 chip->vendor->cancel(chip);
314 return count;
315}
316EXPORT_SYMBOL_GPL(tpm_store_cancel);
366 317
367static DEVICE_ATTR(caps, S_IRUGO, show_caps, NULL);
368 318
369/* 319/*
370 * Device file system interface to the TPM 320 * Device file system interface to the TPM
@@ -422,24 +372,15 @@ EXPORT_SYMBOL_GPL(tpm_open);
422int tpm_release(struct inode *inode, struct file *file) 372int tpm_release(struct inode *inode, struct file *file)
423{ 373{
424 struct tpm_chip *chip = file->private_data; 374 struct tpm_chip *chip = file->private_data;
425
426 file->private_data = NULL;
427 375
428 spin_lock(&driver_lock); 376 spin_lock(&driver_lock);
377 file->private_data = NULL;
429 chip->num_opens--; 378 chip->num_opens--;
430 spin_unlock(&driver_lock); 379 del_singleshot_timer_sync(&chip->user_read_timer);
431
432 down(&chip->timer_manipulation_mutex);
433 if (timer_pending(&chip->user_read_timer))
434 del_singleshot_timer_sync(&chip->user_read_timer);
435 else if (timer_pending(&chip->device_timer))
436 del_singleshot_timer_sync(&chip->device_timer);
437 up(&chip->timer_manipulation_mutex);
438
439 kfree(chip->data_buffer);
440 atomic_set(&chip->data_pending, 0); 380 atomic_set(&chip->data_pending, 0);
441
442 pci_dev_put(chip->pci_dev); 381 pci_dev_put(chip->pci_dev);
382 kfree(chip->data_buffer);
383 spin_unlock(&driver_lock);
443 return 0; 384 return 0;
444} 385}
445 386
@@ -453,10 +394,8 @@ ssize_t tpm_write(struct file * file, const char __user * buf,
453 394
454 /* cannot perform a write until the read has cleared 395 /* cannot perform a write until the read has cleared
455 either via tpm_read or a user_read_timer timeout */ 396 either via tpm_read or a user_read_timer timeout */
456 while (atomic_read(&chip->data_pending) != 0) { 397 while (atomic_read(&chip->data_pending) != 0)
457 set_current_state(TASK_UNINTERRUPTIBLE); 398 msleep(TPM_TIMEOUT);
458 schedule_timeout(TPM_TIMEOUT);
459 }
460 399
461 down(&chip->buffer_mutex); 400 down(&chip->buffer_mutex);
462 401
@@ -476,13 +415,7 @@ ssize_t tpm_write(struct file * file, const char __user * buf,
476 up(&chip->buffer_mutex); 415 up(&chip->buffer_mutex);
477 416
478 /* Set a timeout by which the reader must come claim the result */ 417 /* Set a timeout by which the reader must come claim the result */
479 down(&chip->timer_manipulation_mutex); 418 mod_timer(&chip->user_read_timer, jiffies + (60 * HZ));
480 init_timer(&chip->user_read_timer);
481 chip->user_read_timer.function = user_reader_timeout;
482 chip->user_read_timer.data = (unsigned long) chip;
483 chip->user_read_timer.expires = jiffies + (60 * HZ);
484 add_timer(&chip->user_read_timer);
485 up(&chip->timer_manipulation_mutex);
486 419
487 return in_size; 420 return in_size;
488} 421}
@@ -493,29 +426,19 @@ ssize_t tpm_read(struct file * file, char __user * buf,
493 size_t size, loff_t * off) 426 size_t size, loff_t * off)
494{ 427{
495 struct tpm_chip *chip = file->private_data; 428 struct tpm_chip *chip = file->private_data;
496 int ret_size = -ENODATA; 429 int ret_size;
497 430
498 if (atomic_read(&chip->data_pending) != 0) { /* Result available */ 431 del_singleshot_timer_sync(&chip->user_read_timer);
499 down(&chip->timer_manipulation_mutex); 432 ret_size = atomic_read(&chip->data_pending);
500 del_singleshot_timer_sync(&chip->user_read_timer); 433 atomic_set(&chip->data_pending, 0);
501 up(&chip->timer_manipulation_mutex); 434 if (ret_size > 0) { /* relay data */
435 if (size < ret_size)
436 ret_size = size;
502 437
503 down(&chip->buffer_mutex); 438 down(&chip->buffer_mutex);
504 439 if (copy_to_user
505 ret_size = atomic_read(&chip->data_pending); 440 ((void __user *) buf, chip->data_buffer, ret_size))
506 atomic_set(&chip->data_pending, 0); 441 ret_size = -EFAULT;
507
508 if (ret_size == 0) /* timeout just occurred */
509 ret_size = -ETIME;
510 else if (ret_size > 0) { /* relay data */
511 if (size < ret_size)
512 ret_size = size;
513
514 if (copy_to_user((void __user *) buf,
515 chip->data_buffer, ret_size)) {
516 ret_size = -EFAULT;
517 }
518 }
519 up(&chip->buffer_mutex); 442 up(&chip->buffer_mutex);
520 } 443 }
521 444
@@ -541,14 +464,13 @@ void __devexit tpm_remove(struct pci_dev *pci_dev)
541 464
542 pci_set_drvdata(pci_dev, NULL); 465 pci_set_drvdata(pci_dev, NULL);
543 misc_deregister(&chip->vendor->miscdev); 466 misc_deregister(&chip->vendor->miscdev);
467 kfree(&chip->vendor->miscdev.name);
544 468
545 device_remove_file(&pci_dev->dev, &dev_attr_pubek); 469 sysfs_remove_group(&pci_dev->dev.kobj, chip->vendor->attr_group);
546 device_remove_file(&pci_dev->dev, &dev_attr_pcrs);
547 device_remove_file(&pci_dev->dev, &dev_attr_caps);
548 470
549 pci_disable_device(pci_dev); 471 pci_disable_device(pci_dev);
550 472
551 dev_mask[chip->dev_num / 32] &= !(1 << (chip->dev_num % 32)); 473 dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &= !(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
552 474
553 kfree(chip); 475 kfree(chip);
554 476
@@ -590,10 +512,6 @@ int tpm_pm_resume(struct pci_dev *pci_dev)
590 if (chip == NULL) 512 if (chip == NULL)
591 return -ENODEV; 513 return -ENODEV;
592 514
593 spin_lock(&driver_lock);
594 tpm_lpc_bus_init(pci_dev, chip->vendor->base);
595 spin_unlock(&driver_lock);
596
597 return 0; 515 return 0;
598} 516}
599 517
@@ -609,7 +527,9 @@ EXPORT_SYMBOL_GPL(tpm_pm_resume);
609int tpm_register_hardware(struct pci_dev *pci_dev, 527int tpm_register_hardware(struct pci_dev *pci_dev,
610 struct tpm_vendor_specific *entry) 528 struct tpm_vendor_specific *entry)
611{ 529{
612 char devname[7]; 530#define DEVNAME_SIZE 7
531
532 char *devname;
613 struct tpm_chip *chip; 533 struct tpm_chip *chip;
614 int i, j; 534 int i, j;
615 535
@@ -622,17 +542,21 @@ int tpm_register_hardware(struct pci_dev *pci_dev,
622 542
623 init_MUTEX(&chip->buffer_mutex); 543 init_MUTEX(&chip->buffer_mutex);
624 init_MUTEX(&chip->tpm_mutex); 544 init_MUTEX(&chip->tpm_mutex);
625 init_MUTEX(&chip->timer_manipulation_mutex);
626 INIT_LIST_HEAD(&chip->list); 545 INIT_LIST_HEAD(&chip->list);
627 546
547 init_timer(&chip->user_read_timer);
548 chip->user_read_timer.function = user_reader_timeout;
549 chip->user_read_timer.data = (unsigned long) chip;
550
628 chip->vendor = entry; 551 chip->vendor = entry;
629 552
630 chip->dev_num = -1; 553 chip->dev_num = -1;
631 554
632 for (i = 0; i < 32; i++) 555 for (i = 0; i < TPM_NUM_MASK_ENTRIES; i++)
633 for (j = 0; j < 8; j++) 556 for (j = 0; j < 8 * sizeof(int); j++)
634 if ((dev_mask[i] & (1 << j)) == 0) { 557 if ((dev_mask[i] & (1 << j)) == 0) {
635 chip->dev_num = i * 32 + j; 558 chip->dev_num =
559 i * TPM_NUM_MASK_ENTRIES + j;
636 dev_mask[i] |= 1 << j; 560 dev_mask[i] |= 1 << j;
637 goto dev_num_search_complete; 561 goto dev_num_search_complete;
638 } 562 }
@@ -648,7 +572,8 @@ dev_num_search_complete:
648 else 572 else
649 chip->vendor->miscdev.minor = MISC_DYNAMIC_MINOR; 573 chip->vendor->miscdev.minor = MISC_DYNAMIC_MINOR;
650 574
651 snprintf(devname, sizeof(devname), "%s%d", "tpm", chip->dev_num); 575 devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL);
576 scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num);
652 chip->vendor->miscdev.name = devname; 577 chip->vendor->miscdev.name = devname;
653 578
654 chip->vendor->miscdev.dev = &(pci_dev->dev); 579 chip->vendor->miscdev.dev = &(pci_dev->dev);
@@ -665,31 +590,20 @@ dev_num_search_complete:
665 return -ENODEV; 590 return -ENODEV;
666 } 591 }
667 592
593 spin_lock(&driver_lock);
594
668 pci_set_drvdata(pci_dev, chip); 595 pci_set_drvdata(pci_dev, chip);
669 596
670 list_add(&chip->list, &tpm_chip_list); 597 list_add(&chip->list, &tpm_chip_list);
671 598
672 device_create_file(&pci_dev->dev, &dev_attr_pubek); 599 spin_unlock(&driver_lock);
673 device_create_file(&pci_dev->dev, &dev_attr_pcrs);
674 device_create_file(&pci_dev->dev, &dev_attr_caps);
675
676 return 0;
677}
678 600
679EXPORT_SYMBOL_GPL(tpm_register_hardware); 601 sysfs_create_group(&pci_dev->dev.kobj, chip->vendor->attr_group);
680 602
681static int __init init_tpm(void)
682{
683 return 0; 603 return 0;
684} 604}
685 605
686static void __exit cleanup_tpm(void) 606EXPORT_SYMBOL_GPL(tpm_register_hardware);
687{
688
689}
690
691module_init(init_tpm);
692module_exit(cleanup_tpm);
693 607
694MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)"); 608MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
695MODULE_DESCRIPTION("TPM Driver"); 609MODULE_DESCRIPTION("TPM Driver");
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index de0c796fce80..373b41f6b460 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -25,23 +25,38 @@
25#include <linux/fs.h> 25#include <linux/fs.h>
26#include <linux/miscdevice.h> 26#include <linux/miscdevice.h>
27 27
28#define TPM_TIMEOUT msecs_to_jiffies(5) 28enum tpm_timeout {
29 TPM_TIMEOUT = 5, /* msecs */
30};
29 31
30/* TPM addresses */ 32/* TPM addresses */
31#define TPM_ADDR 0x4E 33enum tpm_addr {
32#define TPM_DATA 0x4F 34 TPM_SUPERIO_ADDR = 0x2E,
35 TPM_ADDR = 0x4E,
36};
37
38extern ssize_t tpm_show_pubek(struct device *, struct device_attribute *attr,
39 char *);
40extern ssize_t tpm_show_pcrs(struct device *, struct device_attribute *attr,
41 char *);
42extern ssize_t tpm_show_caps(struct device *, struct device_attribute *attr,
43 char *);
44extern ssize_t tpm_store_cancel(struct device *, struct device_attribute *attr,
45 const char *, size_t);
33 46
34struct tpm_chip; 47struct tpm_chip;
35 48
36struct tpm_vendor_specific { 49struct tpm_vendor_specific {
37 u8 req_complete_mask; 50 u8 req_complete_mask;
38 u8 req_complete_val; 51 u8 req_complete_val;
52 u8 req_canceled;
39 u16 base; /* TPM base address */ 53 u16 base; /* TPM base address */
40 54
41 int (*recv) (struct tpm_chip *, u8 *, size_t); 55 int (*recv) (struct tpm_chip *, u8 *, size_t);
42 int (*send) (struct tpm_chip *, u8 *, size_t); 56 int (*send) (struct tpm_chip *, u8 *, size_t);
43 void (*cancel) (struct tpm_chip *); 57 void (*cancel) (struct tpm_chip *);
44 struct miscdevice miscdev; 58 struct miscdevice miscdev;
59 struct attribute_group *attr_group;
45}; 60};
46 61
47struct tpm_chip { 62struct tpm_chip {
@@ -58,29 +73,24 @@ struct tpm_chip {
58 73
59 struct timer_list user_read_timer; /* user needs to claim result */ 74 struct timer_list user_read_timer; /* user needs to claim result */
60 struct semaphore tpm_mutex; /* tpm is processing */ 75 struct semaphore tpm_mutex; /* tpm is processing */
61 struct timer_list device_timer; /* tpm is processing */
62 struct semaphore timer_manipulation_mutex;
63 76
64 struct tpm_vendor_specific *vendor; 77 struct tpm_vendor_specific *vendor;
65 78
66 struct list_head list; 79 struct list_head list;
67}; 80};
68 81
69static inline int tpm_read_index(int index) 82static inline int tpm_read_index(int base, int index)
70{ 83{
71 outb(index, TPM_ADDR); 84 outb(index, base);
72 return inb(TPM_DATA) & 0xFF; 85 return inb(base+1) & 0xFF;
73} 86}
74 87
75static inline void tpm_write_index(int index, int value) 88static inline void tpm_write_index(int base, int index, int value)
76{ 89{
77 outb(index, TPM_ADDR); 90 outb(index, base);
78 outb(value & 0xFF, TPM_DATA); 91 outb(value & 0xFF, base+1);
79} 92}
80 93
81extern void tpm_time_expired(unsigned long);
82extern int tpm_lpc_bus_init(struct pci_dev *, u16);
83
84extern int tpm_register_hardware(struct pci_dev *, 94extern int tpm_register_hardware(struct pci_dev *,
85 struct tpm_vendor_specific *); 95 struct tpm_vendor_specific *);
86extern int tpm_open(struct inode *, struct file *); 96extern int tpm_open(struct inode *, struct file *);
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c
index f9333e729b62..cc2cc77fd174 100644
--- a/drivers/char/tpm/tpm_atmel.c
+++ b/drivers/char/tpm/tpm_atmel.c
@@ -22,17 +22,23 @@
22#include "tpm.h" 22#include "tpm.h"
23 23
24/* Atmel definitions */ 24/* Atmel definitions */
25#define TPM_ATML_BASE 0x400 25enum tpm_atmel_addr {
26 TPM_ATMEL_BASE_ADDR_LO = 0x08,
27 TPM_ATMEL_BASE_ADDR_HI = 0x09
28};
26 29
27/* write status bits */ 30/* write status bits */
28#define ATML_STATUS_ABORT 0x01 31enum tpm_atmel_write_status {
29#define ATML_STATUS_LASTBYTE 0x04 32 ATML_STATUS_ABORT = 0x01,
30 33 ATML_STATUS_LASTBYTE = 0x04
34};
31/* read status bits */ 35/* read status bits */
32#define ATML_STATUS_BUSY 0x01 36enum tpm_atmel_read_status {
33#define ATML_STATUS_DATA_AVAIL 0x02 37 ATML_STATUS_BUSY = 0x01,
34#define ATML_STATUS_REWRITE 0x04 38 ATML_STATUS_DATA_AVAIL = 0x02,
35 39 ATML_STATUS_REWRITE = 0x04,
40 ATML_STATUS_READY = 0x08
41};
36 42
37static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count) 43static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count)
38{ 44{
@@ -121,13 +127,29 @@ static struct file_operations atmel_ops = {
121 .release = tpm_release, 127 .release = tpm_release,
122}; 128};
123 129
130static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
131static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
132static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
133static DEVICE_ATTR(cancel, S_IWUSR |S_IWGRP, NULL, tpm_store_cancel);
134
135static struct attribute* atmel_attrs[] = {
136 &dev_attr_pubek.attr,
137 &dev_attr_pcrs.attr,
138 &dev_attr_caps.attr,
139 &dev_attr_cancel.attr,
140 0,
141};
142
143static struct attribute_group atmel_attr_grp = { .attrs = atmel_attrs };
144
124static struct tpm_vendor_specific tpm_atmel = { 145static struct tpm_vendor_specific tpm_atmel = {
125 .recv = tpm_atml_recv, 146 .recv = tpm_atml_recv,
126 .send = tpm_atml_send, 147 .send = tpm_atml_send,
127 .cancel = tpm_atml_cancel, 148 .cancel = tpm_atml_cancel,
128 .req_complete_mask = ATML_STATUS_BUSY | ATML_STATUS_DATA_AVAIL, 149 .req_complete_mask = ATML_STATUS_BUSY | ATML_STATUS_DATA_AVAIL,
129 .req_complete_val = ATML_STATUS_DATA_AVAIL, 150 .req_complete_val = ATML_STATUS_DATA_AVAIL,
130 .base = TPM_ATML_BASE, 151 .req_canceled = ATML_STATUS_READY,
152 .attr_group = &atmel_attr_grp,
131 .miscdev = { .fops = &atmel_ops, }, 153 .miscdev = { .fops = &atmel_ops, },
132}; 154};
133 155
@@ -136,27 +158,29 @@ static int __devinit tpm_atml_init(struct pci_dev *pci_dev,
136{ 158{
137 u8 version[4]; 159 u8 version[4];
138 int rc = 0; 160 int rc = 0;
161 int lo, hi;
139 162
140 if (pci_enable_device(pci_dev)) 163 if (pci_enable_device(pci_dev))
141 return -EIO; 164 return -EIO;
142 165
143 if (tpm_lpc_bus_init(pci_dev, TPM_ATML_BASE)) { 166 lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO);
144 rc = -ENODEV; 167 hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI);
145 goto out_err; 168
146 } 169 tpm_atmel.base = (hi<<8)|lo;
170 dev_dbg( &pci_dev->dev, "Operating with base: 0x%x\n", tpm_atmel.base);
147 171
148 /* verify that it is an Atmel part */ 172 /* verify that it is an Atmel part */
149 if (tpm_read_index(4) != 'A' || tpm_read_index(5) != 'T' 173 if (tpm_read_index(TPM_ADDR, 4) != 'A' || tpm_read_index(TPM_ADDR, 5) != 'T'
150 || tpm_read_index(6) != 'M' || tpm_read_index(7) != 'L') { 174 || tpm_read_index(TPM_ADDR, 6) != 'M' || tpm_read_index(TPM_ADDR, 7) != 'L') {
151 rc = -ENODEV; 175 rc = -ENODEV;
152 goto out_err; 176 goto out_err;
153 } 177 }
154 178
155 /* query chip for its version number */ 179 /* query chip for its version number */
156 if ((version[0] = tpm_read_index(0x00)) != 0xFF) { 180 if ((version[0] = tpm_read_index(TPM_ADDR, 0x00)) != 0xFF) {
157 version[1] = tpm_read_index(0x01); 181 version[1] = tpm_read_index(TPM_ADDR, 0x01);
158 version[2] = tpm_read_index(0x02); 182 version[2] = tpm_read_index(TPM_ADDR, 0x02);
159 version[3] = tpm_read_index(0x03); 183 version[3] = tpm_read_index(TPM_ADDR, 0x03);
160 } else { 184 } else {
161 dev_info(&pci_dev->dev, "version query failed\n"); 185 dev_info(&pci_dev->dev, "version query failed\n");
162 rc = -ENODEV; 186 rc = -ENODEV;
@@ -183,6 +207,7 @@ static struct pci_device_id tpm_pci_tbl[] __devinitdata = {
183 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)}, 207 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)},
184 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)}, 208 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)},
185 {PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)}, 209 {PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)},
210 {PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6LPC)},
186 {0,} 211 {0,}
187}; 212};
188 213
diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c
index 9cce833a0923..b4127348c063 100644
--- a/drivers/char/tpm/tpm_nsc.c
+++ b/drivers/char/tpm/tpm_nsc.c
@@ -22,43 +22,52 @@
22#include "tpm.h" 22#include "tpm.h"
23 23
24/* National definitions */ 24/* National definitions */
25#define TPM_NSC_BASE 0x360 25enum tpm_nsc_addr{
26#define TPM_NSC_IRQ 0x07 26 TPM_NSC_IRQ = 0x07,
27 TPM_NSC_BASE0_HI = 0x60,
28 TPM_NSC_BASE0_LO = 0x61,
29 TPM_NSC_BASE1_HI = 0x62,
30 TPM_NSC_BASE1_LO = 0x63
31};
27 32
28#define NSC_LDN_INDEX 0x07 33enum tpm_nsc_index {
29#define NSC_SID_INDEX 0x20 34 NSC_LDN_INDEX = 0x07,
30#define NSC_LDC_INDEX 0x30 35 NSC_SID_INDEX = 0x20,
31#define NSC_DIO_INDEX 0x60 36 NSC_LDC_INDEX = 0x30,
32#define NSC_CIO_INDEX 0x62 37 NSC_DIO_INDEX = 0x60,
33#define NSC_IRQ_INDEX 0x70 38 NSC_CIO_INDEX = 0x62,
34#define NSC_ITS_INDEX 0x71 39 NSC_IRQ_INDEX = 0x70,
40 NSC_ITS_INDEX = 0x71
41};
35 42
36#define NSC_STATUS 0x01 43enum tpm_nsc_status_loc {
37#define NSC_COMMAND 0x01 44 NSC_STATUS = 0x01,
38#define NSC_DATA 0x00 45 NSC_COMMAND = 0x01,
46 NSC_DATA = 0x00
47};
39 48
40/* status bits */ 49/* status bits */
41#define NSC_STATUS_OBF 0x01 /* output buffer full */ 50enum tpm_nsc_status {
42#define NSC_STATUS_IBF 0x02 /* input buffer full */ 51 NSC_STATUS_OBF = 0x01, /* output buffer full */
43#define NSC_STATUS_F0 0x04 /* F0 */ 52 NSC_STATUS_IBF = 0x02, /* input buffer full */
44#define NSC_STATUS_A2 0x08 /* A2 */ 53 NSC_STATUS_F0 = 0x04, /* F0 */
45#define NSC_STATUS_RDY 0x10 /* ready to receive command */ 54 NSC_STATUS_A2 = 0x08, /* A2 */
46#define NSC_STATUS_IBR 0x20 /* ready to receive data */ 55 NSC_STATUS_RDY = 0x10, /* ready to receive command */
56 NSC_STATUS_IBR = 0x20 /* ready to receive data */
57};
47 58
48/* command bits */ 59/* command bits */
49#define NSC_COMMAND_NORMAL 0x01 /* normal mode */ 60enum tpm_nsc_cmd_mode {
50#define NSC_COMMAND_EOC 0x03 61 NSC_COMMAND_NORMAL = 0x01, /* normal mode */
51#define NSC_COMMAND_CANCEL 0x22 62 NSC_COMMAND_EOC = 0x03,
52 63 NSC_COMMAND_CANCEL = 0x22
64};
53/* 65/*
54 * Wait for a certain status to appear 66 * Wait for a certain status to appear
55 */ 67 */
56static int wait_for_stat(struct tpm_chip *chip, u8 mask, u8 val, u8 * data) 68static int wait_for_stat(struct tpm_chip *chip, u8 mask, u8 val, u8 * data)
57{ 69{
58 int expired = 0; 70 unsigned long stop;
59 struct timer_list status_timer =
60 TIMER_INITIALIZER(tpm_time_expired, jiffies + 10 * HZ,
61 (unsigned long) &expired);
62 71
63 /* status immediately available check */ 72 /* status immediately available check */
64 *data = inb(chip->vendor->base + NSC_STATUS); 73 *data = inb(chip->vendor->base + NSC_STATUS);
@@ -66,17 +75,14 @@ static int wait_for_stat(struct tpm_chip *chip, u8 mask, u8 val, u8 * data)
66 return 0; 75 return 0;
67 76
68 /* wait for status */ 77 /* wait for status */
69 add_timer(&status_timer); 78 stop = jiffies + 10 * HZ;
70 do { 79 do {
71 set_current_state(TASK_UNINTERRUPTIBLE); 80 msleep(TPM_TIMEOUT);
72 schedule_timeout(TPM_TIMEOUT);
73 *data = inb(chip->vendor->base + 1); 81 *data = inb(chip->vendor->base + 1);
74 if ((*data & mask) == val) { 82 if ((*data & mask) == val)
75 del_singleshot_timer_sync(&status_timer);
76 return 0; 83 return 0;
77 }
78 } 84 }
79 while (!expired); 85 while (time_before(jiffies, stop));
80 86
81 return -EBUSY; 87 return -EBUSY;
82} 88}
@@ -84,10 +90,7 @@ static int wait_for_stat(struct tpm_chip *chip, u8 mask, u8 val, u8 * data)
84static int nsc_wait_for_ready(struct tpm_chip *chip) 90static int nsc_wait_for_ready(struct tpm_chip *chip)
85{ 91{
86 int status; 92 int status;
87 int expired = 0; 93 unsigned long stop;
88 struct timer_list status_timer =
89 TIMER_INITIALIZER(tpm_time_expired, jiffies + 100,
90 (unsigned long) &expired);
91 94
92 /* status immediately available check */ 95 /* status immediately available check */
93 status = inb(chip->vendor->base + NSC_STATUS); 96 status = inb(chip->vendor->base + NSC_STATUS);
@@ -97,19 +100,16 @@ static int nsc_wait_for_ready(struct tpm_chip *chip)
97 return 0; 100 return 0;
98 101
99 /* wait for status */ 102 /* wait for status */
100 add_timer(&status_timer); 103 stop = jiffies + 100;
101 do { 104 do {
102 set_current_state(TASK_UNINTERRUPTIBLE); 105 msleep(TPM_TIMEOUT);
103 schedule_timeout(TPM_TIMEOUT);
104 status = inb(chip->vendor->base + NSC_STATUS); 106 status = inb(chip->vendor->base + NSC_STATUS);
105 if (status & NSC_STATUS_OBF) 107 if (status & NSC_STATUS_OBF)
106 status = inb(chip->vendor->base + NSC_DATA); 108 status = inb(chip->vendor->base + NSC_DATA);
107 if (status & NSC_STATUS_RDY) { 109 if (status & NSC_STATUS_RDY)
108 del_singleshot_timer_sync(&status_timer);
109 return 0; 110 return 0;
110 }
111 } 111 }
112 while (!expired); 112 while (time_before(jiffies, stop));
113 113
114 dev_info(&chip->pci_dev->dev, "wait for ready failed\n"); 114 dev_info(&chip->pci_dev->dev, "wait for ready failed\n");
115 return -EBUSY; 115 return -EBUSY;
@@ -150,7 +150,8 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count)
150 *p = inb(chip->vendor->base + NSC_DATA); 150 *p = inb(chip->vendor->base + NSC_DATA);
151 } 151 }
152 152
153 if ((data & NSC_STATUS_F0) == 0) { 153 if ((data & NSC_STATUS_F0) == 0 &&
154 (wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0)) {
154 dev_err(&chip->pci_dev->dev, "F0 not set\n"); 155 dev_err(&chip->pci_dev->dev, "F0 not set\n");
155 return -EIO; 156 return -EIO;
156 } 157 }
@@ -228,100 +229,95 @@ static struct file_operations nsc_ops = {
228 .release = tpm_release, 229 .release = tpm_release,
229}; 230};
230 231
232static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
233static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
234static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
235static DEVICE_ATTR(cancel, S_IWUSR|S_IWGRP, NULL, tpm_store_cancel);
236
237static struct attribute * nsc_attrs[] = {
238 &dev_attr_pubek.attr,
239 &dev_attr_pcrs.attr,
240 &dev_attr_caps.attr,
241 &dev_attr_cancel.attr,
242 0,
243};
244
245static struct attribute_group nsc_attr_grp = { .attrs = nsc_attrs };
246
231static struct tpm_vendor_specific tpm_nsc = { 247static struct tpm_vendor_specific tpm_nsc = {
232 .recv = tpm_nsc_recv, 248 .recv = tpm_nsc_recv,
233 .send = tpm_nsc_send, 249 .send = tpm_nsc_send,
234 .cancel = tpm_nsc_cancel, 250 .cancel = tpm_nsc_cancel,
235 .req_complete_mask = NSC_STATUS_OBF, 251 .req_complete_mask = NSC_STATUS_OBF,
236 .req_complete_val = NSC_STATUS_OBF, 252 .req_complete_val = NSC_STATUS_OBF,
237 .base = TPM_NSC_BASE, 253 .req_canceled = NSC_STATUS_RDY,
254 .attr_group = &nsc_attr_grp,
238 .miscdev = { .fops = &nsc_ops, }, 255 .miscdev = { .fops = &nsc_ops, },
239
240}; 256};
241 257
242static int __devinit tpm_nsc_init(struct pci_dev *pci_dev, 258static int __devinit tpm_nsc_init(struct pci_dev *pci_dev,
243 const struct pci_device_id *pci_id) 259 const struct pci_device_id *pci_id)
244{ 260{
245 int rc = 0; 261 int rc = 0;
262 int lo, hi;
263 int nscAddrBase = TPM_ADDR;
264
246 265
247 if (pci_enable_device(pci_dev)) 266 if (pci_enable_device(pci_dev))
248 return -EIO; 267 return -EIO;
249 268
250 if (tpm_lpc_bus_init(pci_dev, TPM_NSC_BASE)) { 269 /* select PM channel 1 */
251 rc = -ENODEV; 270 tpm_write_index(nscAddrBase,NSC_LDN_INDEX, 0x12);
252 goto out_err;
253 }
254 271
255 /* verify that it is a National part (SID) */ 272 /* verify that it is a National part (SID) */
256 if (tpm_read_index(NSC_SID_INDEX) != 0xEF) { 273 if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) {
257 rc = -ENODEV; 274 nscAddrBase = (tpm_read_index(TPM_SUPERIO_ADDR, 0x2C)<<8)|
258 goto out_err; 275 (tpm_read_index(TPM_SUPERIO_ADDR, 0x2B)&0xFE);
276 if (tpm_read_index(nscAddrBase, NSC_SID_INDEX) != 0xF6) {
277 rc = -ENODEV;
278 goto out_err;
279 }
259 } 280 }
260 281
282 hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI);
283 lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO);
284 tpm_nsc.base = (hi<<8) | lo;
285
261 dev_dbg(&pci_dev->dev, "NSC TPM detected\n"); 286 dev_dbg(&pci_dev->dev, "NSC TPM detected\n");
262 dev_dbg(&pci_dev->dev, 287 dev_dbg(&pci_dev->dev,
263 "NSC LDN 0x%x, SID 0x%x, SRID 0x%x\n", 288 "NSC LDN 0x%x, SID 0x%x, SRID 0x%x\n",
264 tpm_read_index(0x07), tpm_read_index(0x20), 289 tpm_read_index(nscAddrBase,0x07), tpm_read_index(nscAddrBase,0x20),
265 tpm_read_index(0x27)); 290 tpm_read_index(nscAddrBase,0x27));
266 dev_dbg(&pci_dev->dev, 291 dev_dbg(&pci_dev->dev,
267 "NSC SIOCF1 0x%x SIOCF5 0x%x SIOCF6 0x%x SIOCF8 0x%x\n", 292 "NSC SIOCF1 0x%x SIOCF5 0x%x SIOCF6 0x%x SIOCF8 0x%x\n",
268 tpm_read_index(0x21), tpm_read_index(0x25), 293 tpm_read_index(nscAddrBase,0x21), tpm_read_index(nscAddrBase,0x25),
269 tpm_read_index(0x26), tpm_read_index(0x28)); 294 tpm_read_index(nscAddrBase,0x26), tpm_read_index(nscAddrBase,0x28));
270 dev_dbg(&pci_dev->dev, "NSC IO Base0 0x%x\n", 295 dev_dbg(&pci_dev->dev, "NSC IO Base0 0x%x\n",
271 (tpm_read_index(0x60) << 8) | tpm_read_index(0x61)); 296 (tpm_read_index(nscAddrBase,0x60) << 8) | tpm_read_index(nscAddrBase,0x61));
272 dev_dbg(&pci_dev->dev, "NSC IO Base1 0x%x\n", 297 dev_dbg(&pci_dev->dev, "NSC IO Base1 0x%x\n",
273 (tpm_read_index(0x62) << 8) | tpm_read_index(0x63)); 298 (tpm_read_index(nscAddrBase,0x62) << 8) | tpm_read_index(nscAddrBase,0x63));
274 dev_dbg(&pci_dev->dev, "NSC Interrupt number and wakeup 0x%x\n", 299 dev_dbg(&pci_dev->dev, "NSC Interrupt number and wakeup 0x%x\n",
275 tpm_read_index(0x70)); 300 tpm_read_index(nscAddrBase,0x70));
276 dev_dbg(&pci_dev->dev, "NSC IRQ type select 0x%x\n", 301 dev_dbg(&pci_dev->dev, "NSC IRQ type select 0x%x\n",
277 tpm_read_index(0x71)); 302 tpm_read_index(nscAddrBase,0x71));
278 dev_dbg(&pci_dev->dev, 303 dev_dbg(&pci_dev->dev,
279 "NSC DMA channel select0 0x%x, select1 0x%x\n", 304 "NSC DMA channel select0 0x%x, select1 0x%x\n",
280 tpm_read_index(0x74), tpm_read_index(0x75)); 305 tpm_read_index(nscAddrBase,0x74), tpm_read_index(nscAddrBase,0x75));
281 dev_dbg(&pci_dev->dev, 306 dev_dbg(&pci_dev->dev,
282 "NSC Config " 307 "NSC Config "
283 "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", 308 "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
284 tpm_read_index(0xF0), tpm_read_index(0xF1), 309 tpm_read_index(nscAddrBase,0xF0), tpm_read_index(nscAddrBase,0xF1),
285 tpm_read_index(0xF2), tpm_read_index(0xF3), 310 tpm_read_index(nscAddrBase,0xF2), tpm_read_index(nscAddrBase,0xF3),
286 tpm_read_index(0xF4), tpm_read_index(0xF5), 311 tpm_read_index(nscAddrBase,0xF4), tpm_read_index(nscAddrBase,0xF5),
287 tpm_read_index(0xF6), tpm_read_index(0xF7), 312 tpm_read_index(nscAddrBase,0xF6), tpm_read_index(nscAddrBase,0xF7),
288 tpm_read_index(0xF8), tpm_read_index(0xF9)); 313 tpm_read_index(nscAddrBase,0xF8), tpm_read_index(nscAddrBase,0xF9));
289 314
290 dev_info(&pci_dev->dev, 315 dev_info(&pci_dev->dev,
291 "NSC PC21100 TPM revision %d\n", 316 "NSC TPM revision %d\n",
292 tpm_read_index(0x27) & 0x1F); 317 tpm_read_index(nscAddrBase, 0x27) & 0x1F);
293
294 if (tpm_read_index(NSC_LDC_INDEX) == 0)
295 dev_info(&pci_dev->dev, ": NSC TPM not active\n");
296
297 /* select PM channel 1 */
298 tpm_write_index(NSC_LDN_INDEX, 0x12);
299 tpm_read_index(NSC_LDN_INDEX);
300
301 /* disable the DPM module */
302 tpm_write_index(NSC_LDC_INDEX, 0);
303 tpm_read_index(NSC_LDC_INDEX);
304
305 /* set the data register base addresses */
306 tpm_write_index(NSC_DIO_INDEX, TPM_NSC_BASE >> 8);
307 tpm_write_index(NSC_DIO_INDEX + 1, TPM_NSC_BASE);
308 tpm_read_index(NSC_DIO_INDEX);
309 tpm_read_index(NSC_DIO_INDEX + 1);
310
311 /* set the command register base addresses */
312 tpm_write_index(NSC_CIO_INDEX, (TPM_NSC_BASE + 1) >> 8);
313 tpm_write_index(NSC_CIO_INDEX + 1, (TPM_NSC_BASE + 1));
314 tpm_read_index(NSC_DIO_INDEX);
315 tpm_read_index(NSC_DIO_INDEX + 1);
316
317 /* set the interrupt number to be used for the host interface */
318 tpm_write_index(NSC_IRQ_INDEX, TPM_NSC_IRQ);
319 tpm_write_index(NSC_ITS_INDEX, 0x00);
320 tpm_read_index(NSC_IRQ_INDEX);
321 318
322 /* enable the DPM module */ 319 /* enable the DPM module */
323 tpm_write_index(NSC_LDC_INDEX, 0x01); 320 tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01);
324 tpm_read_index(NSC_LDC_INDEX);
325 321
326 if ((rc = tpm_register_hardware(pci_dev, &tpm_nsc)) < 0) 322 if ((rc = tpm_register_hardware(pci_dev, &tpm_nsc)) < 0)
327 goto out_err; 323 goto out_err;
@@ -339,6 +335,9 @@ static struct pci_device_id tpm_pci_tbl[] __devinitdata = {
339 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)}, 335 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)},
340 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)}, 336 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)},
341 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)}, 337 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)},
338 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0)},
339 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1)},
340 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0)},
342 {PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)}, 341 {PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)},
343 {0,} 342 {0,}
344}; 343};
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 31831030f73f..6e4be3bb2d89 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -94,6 +94,7 @@
94#include <linux/idr.h> 94#include <linux/idr.h>
95#include <linux/wait.h> 95#include <linux/wait.h>
96#include <linux/bitops.h> 96#include <linux/bitops.h>
97#include <linux/delay.h>
97 98
98#include <asm/uaccess.h> 99#include <asm/uaccess.h>
99#include <asm/system.h> 100#include <asm/system.h>
@@ -251,7 +252,7 @@ static void tty_set_termios_ldisc(struct tty_struct *tty, int num)
251 252
252static DEFINE_SPINLOCK(tty_ldisc_lock); 253static DEFINE_SPINLOCK(tty_ldisc_lock);
253static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait); 254static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait);
254static struct tty_ldisc tty_ldiscs[NR_LDISCS]; /* line disc dispatch table */ 255static struct tty_ldisc tty_ldiscs[NR_LDISCS]; /* line disc dispatch table */
255 256
256int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc) 257int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc)
257{ 258{
@@ -262,24 +263,35 @@ int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc)
262 return -EINVAL; 263 return -EINVAL;
263 264
264 spin_lock_irqsave(&tty_ldisc_lock, flags); 265 spin_lock_irqsave(&tty_ldisc_lock, flags);
265 if (new_ldisc) { 266 tty_ldiscs[disc] = *new_ldisc;
266 tty_ldiscs[disc] = *new_ldisc; 267 tty_ldiscs[disc].num = disc;
267 tty_ldiscs[disc].num = disc; 268 tty_ldiscs[disc].flags |= LDISC_FLAG_DEFINED;
268 tty_ldiscs[disc].flags |= LDISC_FLAG_DEFINED; 269 tty_ldiscs[disc].refcount = 0;
269 tty_ldiscs[disc].refcount = 0;
270 } else {
271 if(tty_ldiscs[disc].refcount)
272 ret = -EBUSY;
273 else
274 tty_ldiscs[disc].flags &= ~LDISC_FLAG_DEFINED;
275 }
276 spin_unlock_irqrestore(&tty_ldisc_lock, flags); 270 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
277 271
278 return ret; 272 return ret;
279} 273}
280
281EXPORT_SYMBOL(tty_register_ldisc); 274EXPORT_SYMBOL(tty_register_ldisc);
282 275
276int tty_unregister_ldisc(int disc)
277{
278 unsigned long flags;
279 int ret = 0;
280
281 if (disc < N_TTY || disc >= NR_LDISCS)
282 return -EINVAL;
283
284 spin_lock_irqsave(&tty_ldisc_lock, flags);
285 if (tty_ldiscs[disc].refcount)
286 ret = -EBUSY;
287 else
288 tty_ldiscs[disc].flags &= ~LDISC_FLAG_DEFINED;
289 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
290
291 return ret;
292}
293EXPORT_SYMBOL(tty_unregister_ldisc);
294
283struct tty_ldisc *tty_ldisc_get(int disc) 295struct tty_ldisc *tty_ldisc_get(int disc)
284{ 296{
285 unsigned long flags; 297 unsigned long flags;
@@ -2169,12 +2181,11 @@ static int tiocsetd(struct tty_struct *tty, int __user *p)
2169 return tty_set_ldisc(tty, ldisc); 2181 return tty_set_ldisc(tty, ldisc);
2170} 2182}
2171 2183
2172static int send_break(struct tty_struct *tty, int duration) 2184static int send_break(struct tty_struct *tty, unsigned int duration)
2173{ 2185{
2174 tty->driver->break_ctl(tty, -1); 2186 tty->driver->break_ctl(tty, -1);
2175 if (!signal_pending(current)) { 2187 if (!signal_pending(current)) {
2176 set_current_state(TASK_INTERRUPTIBLE); 2188 msleep_interruptible(duration);
2177 schedule_timeout(duration);
2178 } 2189 }
2179 tty->driver->break_ctl(tty, 0); 2190 tty->driver->break_ctl(tty, 0);
2180 if (signal_pending(current)) 2191 if (signal_pending(current))
@@ -2355,10 +2366,10 @@ int tty_ioctl(struct inode * inode, struct file * file,
2355 * all by anyone? 2366 * all by anyone?
2356 */ 2367 */
2357 if (!arg) 2368 if (!arg)
2358 return send_break(tty, HZ/4); 2369 return send_break(tty, 250);
2359 return 0; 2370 return 0;
2360 case TCSBRKP: /* support for POSIX tcsendbreak() */ 2371 case TCSBRKP: /* support for POSIX tcsendbreak() */
2361 return send_break(tty, arg ? arg*(HZ/10) : HZ/4); 2372 return send_break(tty, arg ? arg*100 : 250);
2362 2373
2363 case TIOCMGET: 2374 case TIOCMGET:
2364 return tty_tiocmget(tty, file, p); 2375 return tty_tiocmget(tty, file, p);
diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig
index 06a31da2381c..b53e2e2b5aee 100644
--- a/drivers/char/watchdog/Kconfig
+++ b/drivers/char/watchdog/Kconfig
@@ -414,6 +414,16 @@ config WATCHDOG_RIO
414 machines. The watchdog timeout period is normally one minute but 414 machines. The watchdog timeout period is normally one minute but
415 can be changed with a boot-time parameter. 415 can be changed with a boot-time parameter.
416 416
417# ppc64 RTAS watchdog
418config WATCHDOG_RTAS
419 tristate "RTAS watchdog"
420 depends on WATCHDOG && PPC_RTAS
421 help
422 This driver adds watchdog support for the RTAS watchdog.
423
424 To compile this driver as a module, choose M here. The module
425 will be called wdrtas.
426
417# 427#
418# ISA-based Watchdog Cards 428# ISA-based Watchdog Cards
419# 429#
diff --git a/drivers/char/watchdog/Makefile b/drivers/char/watchdog/Makefile
index 1cd27efa35c1..c1838834ea7f 100644
--- a/drivers/char/watchdog/Makefile
+++ b/drivers/char/watchdog/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o
33obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o 33obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o
34obj-$(CONFIG_IXP2000_WATCHDOG) += ixp2000_wdt.o 34obj-$(CONFIG_IXP2000_WATCHDOG) += ixp2000_wdt.o
35obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o 35obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o
36obj-$(CONFIG_WATCHDOG_RTAS) += wdrtas.o
36 37
37# Only one watchdog can succeed. We probe the hardware watchdog 38# Only one watchdog can succeed. We probe the hardware watchdog
38# drivers first, then the softdog driver. This means if your hardware 39# drivers first, then the softdog driver. This means if your hardware
diff --git a/drivers/char/watchdog/wdrtas.c b/drivers/char/watchdog/wdrtas.c
new file mode 100644
index 000000000000..619e2ffca33f
--- /dev/null
+++ b/drivers/char/watchdog/wdrtas.c
@@ -0,0 +1,696 @@
1/*
2 * FIXME: add wdrtas_get_status and wdrtas_get_boot_status as soon as
3 * RTAS calls are available
4 */
5
6/*
7 * RTAS watchdog driver
8 *
9 * (C) Copyright IBM Corp. 2005
10 * device driver to exploit watchdog RTAS functions
11 *
12 * Authors : Utz Bacher <utz.bacher@de.ibm.com>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2, or (at your option)
17 * any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 */
28
29#include <linux/config.h>
30#include <linux/fs.h>
31#include <linux/init.h>
32#include <linux/kernel.h>
33#include <linux/miscdevice.h>
34#include <linux/module.h>
35#include <linux/notifier.h>
36#include <linux/reboot.h>
37#include <linux/types.h>
38#include <linux/watchdog.h>
39
40#include <asm/rtas.h>
41#include <asm/uaccess.h>
42
43#define WDRTAS_MAGIC_CHAR 42
44#define WDRTAS_SUPPORTED_MASK (WDIOF_SETTIMEOUT | \
45 WDIOF_MAGICCLOSE)
46
47MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>");
48MODULE_DESCRIPTION("RTAS watchdog driver");
49MODULE_LICENSE("GPL");
50MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
51MODULE_ALIAS_MISCDEV(TEMP_MINOR);
52
53#ifdef CONFIG_WATCHDOG_NOWAYOUT
54static int wdrtas_nowayout = 1;
55#else
56static int wdrtas_nowayout = 0;
57#endif
58
59static atomic_t wdrtas_miscdev_open = ATOMIC_INIT(0);
60static char wdrtas_expect_close = 0;
61
62static int wdrtas_interval;
63
64#define WDRTAS_THERMAL_SENSOR 3
65static int wdrtas_token_get_sensor_state;
66#define WDRTAS_SURVEILLANCE_IND 9000
67static int wdrtas_token_set_indicator;
68#define WDRTAS_SP_SPI 28
69static int wdrtas_token_get_sp;
70static int wdrtas_token_event_scan;
71
72#define WDRTAS_DEFAULT_INTERVAL 300
73
74#define WDRTAS_LOGBUFFER_LEN 128
75static char wdrtas_logbuffer[WDRTAS_LOGBUFFER_LEN];
76
77
78/*** watchdog access functions */
79
80/**
81 * wdrtas_set_interval - sets the watchdog interval
82 * @interval: new interval
83 *
84 * returns 0 on success, <0 on failures
85 *
86 * wdrtas_set_interval sets the watchdog keepalive interval by calling the
87 * RTAS function set-indicator (surveillance). The unit of interval is
88 * seconds.
89 */
90static int
91wdrtas_set_interval(int interval)
92{
93 long result;
94 static int print_msg = 10;
95
96 /* rtas uses minutes */
97 interval = (interval + 59) / 60;
98
99 result = rtas_call(wdrtas_token_set_indicator, 3, 1, NULL,
100 WDRTAS_SURVEILLANCE_IND, 0, interval);
101 if ( (result < 0) && (print_msg) ) {
102 printk(KERN_ERR "wdrtas: setting the watchdog to %i "
103 "timeout failed: %li\n", interval, result);
104 print_msg--;
105 }
106
107 return result;
108}
109
110/**
111 * wdrtas_get_interval - returns the current watchdog interval
112 * @fallback_value: value (in seconds) to use, if the RTAS call fails
113 *
114 * returns the interval
115 *
116 * wdrtas_get_interval returns the current watchdog keepalive interval
117 * as reported by the RTAS function ibm,get-system-parameter. The unit
118 * of the return value is seconds.
119 */
120static int
121wdrtas_get_interval(int fallback_value)
122{
123 long result;
124 char value[4];
125
126 result = rtas_call(wdrtas_token_get_sp, 3, 1, NULL,
127 WDRTAS_SP_SPI, (void *)__pa(&value), 4);
128 if ( (value[0] != 0) || (value[1] != 2) || (value[3] != 0) ||
129 (result < 0) ) {
130 printk(KERN_WARNING "wdrtas: could not get sp_spi watchdog "
131 "timeout (%li). Continuing\n", result);
132 return fallback_value;
133 }
134
135 /* rtas uses minutes */
136 return ((int)value[2]) * 60;
137}
138
139/**
140 * wdrtas_timer_start - starts watchdog
141 *
142 * wdrtas_timer_start starts the watchdog by calling the RTAS function
143 * set-interval (surveillance)
144 */
145static void
146wdrtas_timer_start(void)
147{
148 wdrtas_set_interval(wdrtas_interval);
149}
150
151/**
152 * wdrtas_timer_stop - stops watchdog
153 *
154 * wdrtas_timer_stop stops the watchdog timer by calling the RTAS function
155 * set-interval (surveillance)
156 */
157static void
158wdrtas_timer_stop(void)
159{
160 wdrtas_set_interval(0);
161}
162
163/**
164 * wdrtas_log_scanned_event - logs an event we received during keepalive
165 *
166 * wdrtas_log_scanned_event prints a message to the log buffer dumping
167 * the results of the last event-scan call
168 */
169static void
170wdrtas_log_scanned_event(void)
171{
172 int i;
173
174 for (i = 0; i < WDRTAS_LOGBUFFER_LEN; i += 16)
175 printk(KERN_INFO "wdrtas: dumping event (line %i/%i), data = "
176 "%02x %02x %02x %02x %02x %02x %02x %02x "
177 "%02x %02x %02x %02x %02x %02x %02x %02x\n",
178 (i / 16) + 1, (WDRTAS_LOGBUFFER_LEN / 16),
179 wdrtas_logbuffer[i + 0], wdrtas_logbuffer[i + 1],
180 wdrtas_logbuffer[i + 2], wdrtas_logbuffer[i + 3],
181 wdrtas_logbuffer[i + 4], wdrtas_logbuffer[i + 5],
182 wdrtas_logbuffer[i + 6], wdrtas_logbuffer[i + 7],
183 wdrtas_logbuffer[i + 8], wdrtas_logbuffer[i + 9],
184 wdrtas_logbuffer[i + 10], wdrtas_logbuffer[i + 11],
185 wdrtas_logbuffer[i + 12], wdrtas_logbuffer[i + 13],
186 wdrtas_logbuffer[i + 14], wdrtas_logbuffer[i + 15]);
187}
188
189/**
190 * wdrtas_timer_keepalive - resets watchdog timer to keep system alive
191 *
192 * wdrtas_timer_keepalive restarts the watchdog timer by calling the
193 * RTAS function event-scan and repeats these calls as long as there are
194 * events available. All events will be dumped.
195 */
196static void
197wdrtas_timer_keepalive(void)
198{
199 long result;
200
201 do {
202 result = rtas_call(wdrtas_token_event_scan, 4, 1, NULL,
203 RTAS_EVENT_SCAN_ALL_EVENTS, 0,
204 (void *)__pa(wdrtas_logbuffer),
205 WDRTAS_LOGBUFFER_LEN);
206 if (result < 0)
207 printk(KERN_ERR "wdrtas: event-scan failed: %li\n",
208 result);
209 if (result == 0)
210 wdrtas_log_scanned_event();
211 } while (result == 0);
212}
213
214/**
215 * wdrtas_get_temperature - returns current temperature
216 *
217 * returns temperature or <0 on failures
218 *
219 * wdrtas_get_temperature returns the current temperature in Fahrenheit. It
220 * uses the RTAS call get-sensor-state, token 3 to do so
221 */
222static int
223wdrtas_get_temperature(void)
224{
225 long result;
226 int temperature = 0;
227
228 result = rtas_call(wdrtas_token_get_sensor_state, 2, 2,
229 (void *)__pa(&temperature),
230 WDRTAS_THERMAL_SENSOR, 0);
231
232 if (result < 0)
233 printk(KERN_WARNING "wdrtas: reading the thermal sensor "
234 "faild: %li\n", result);
235 else
236 temperature = ((temperature * 9) / 5) + 32; /* fahrenheit */
237
238 return temperature;
239}
240
241/**
242 * wdrtas_get_status - returns the status of the watchdog
243 *
244 * returns a bitmask of defines WDIOF_... as defined in
245 * include/linux/watchdog.h
246 */
247static int
248wdrtas_get_status(void)
249{
250 return 0; /* TODO */
251}
252
253/**
254 * wdrtas_get_boot_status - returns the reason for the last boot
255 *
256 * returns a bitmask of defines WDIOF_... as defined in
257 * include/linux/watchdog.h, indicating why the watchdog rebooted the system
258 */
259static int
260wdrtas_get_boot_status(void)
261{
262 return 0; /* TODO */
263}
264
265/*** watchdog API and operations stuff */
266
267/* wdrtas_write - called when watchdog device is written to
268 * @file: file structure
269 * @buf: user buffer with data
270 * @len: amount to data written
271 * @ppos: position in file
272 *
273 * returns the number of successfully processed characters, which is always
274 * the number of bytes passed to this function
275 *
276 * wdrtas_write processes all the data given to it and looks for the magic
277 * character 'V'. This character allows the watchdog device to be closed
278 * properly.
279 */
280static ssize_t
281wdrtas_write(struct file *file, const char __user *buf,
282 size_t len, loff_t *ppos)
283{
284 int i;
285 char c;
286
287 if (!len)
288 goto out;
289
290 if (!wdrtas_nowayout) {
291 wdrtas_expect_close = 0;
292 /* look for 'V' */
293 for (i = 0; i < len; i++) {
294 if (get_user(c, buf + i))
295 return -EFAULT;
296 /* allow to close device */
297 if (c == 'V')
298 wdrtas_expect_close = WDRTAS_MAGIC_CHAR;
299 }
300 }
301
302 wdrtas_timer_keepalive();
303
304out:
305 return len;
306}
307
308/**
309 * wdrtas_ioctl - ioctl function for the watchdog device
310 * @inode: inode structure
311 * @file: file structure
312 * @cmd: command for ioctl
313 * @arg: argument pointer
314 *
315 * returns 0 on success, <0 on failure
316 *
317 * wdrtas_ioctl implements the watchdog API ioctls
318 */
319static int
320wdrtas_ioctl(struct inode *inode, struct file *file,
321 unsigned int cmd, unsigned long arg)
322{
323 int __user *argp = (void *)arg;
324 int i;
325 static struct watchdog_info wdinfo = {
326 .options = WDRTAS_SUPPORTED_MASK,
327 .firmware_version = 0,
328 .identity = "wdrtas"
329 };
330
331 switch (cmd) {
332 case WDIOC_GETSUPPORT:
333 if (copy_to_user(argp, &wdinfo, sizeof(wdinfo)))
334 return -EFAULT;
335 return 0;
336
337 case WDIOC_GETSTATUS:
338 i = wdrtas_get_status();
339 return put_user(i, argp);
340
341 case WDIOC_GETBOOTSTATUS:
342 i = wdrtas_get_boot_status();
343 return put_user(i, argp);
344
345 case WDIOC_GETTEMP:
346 if (wdrtas_token_get_sensor_state == RTAS_UNKNOWN_SERVICE)
347 return -EOPNOTSUPP;
348
349 i = wdrtas_get_temperature();
350 return put_user(i, argp);
351
352 case WDIOC_SETOPTIONS:
353 if (get_user(i, argp))
354 return -EFAULT;
355 if (i & WDIOS_DISABLECARD)
356 wdrtas_timer_stop();
357 if (i & WDIOS_ENABLECARD) {
358 wdrtas_timer_keepalive();
359 wdrtas_timer_start();
360 }
361 if (i & WDIOS_TEMPPANIC) {
362 /* not implemented. Done by H8 */
363 }
364 return 0;
365
366 case WDIOC_KEEPALIVE:
367 wdrtas_timer_keepalive();
368 return 0;
369
370 case WDIOC_SETTIMEOUT:
371 if (get_user(i, argp))
372 return -EFAULT;
373
374 if (wdrtas_set_interval(i))
375 return -EINVAL;
376
377 wdrtas_timer_keepalive();
378
379 if (wdrtas_token_get_sp == RTAS_UNKNOWN_SERVICE)
380 wdrtas_interval = i;
381 else
382 wdrtas_interval = wdrtas_get_interval(i);
383 /* fallthrough */
384
385 case WDIOC_GETTIMEOUT:
386 return put_user(wdrtas_interval, argp);
387
388 default:
389 return -ENOIOCTLCMD;
390 }
391}
392
393/**
394 * wdrtas_open - open function of watchdog device
395 * @inode: inode structure
396 * @file: file structure
397 *
398 * returns 0 on success, -EBUSY if the file has been opened already, <0 on
399 * other failures
400 *
401 * function called when watchdog device is opened
402 */
403static int
404wdrtas_open(struct inode *inode, struct file *file)
405{
406 /* only open once */
407 if (atomic_inc_return(&wdrtas_miscdev_open) > 1) {
408 atomic_dec(&wdrtas_miscdev_open);
409 return -EBUSY;
410 }
411
412 wdrtas_timer_start();
413 wdrtas_timer_keepalive();
414
415 return nonseekable_open(inode, file);
416}
417
418/**
419 * wdrtas_close - close function of watchdog device
420 * @inode: inode structure
421 * @file: file structure
422 *
423 * returns 0 on success
424 *
425 * close function. Always succeeds
426 */
427static int
428wdrtas_close(struct inode *inode, struct file *file)
429{
430 /* only stop watchdog, if this was announced using 'V' before */
431 if (wdrtas_expect_close == WDRTAS_MAGIC_CHAR)
432 wdrtas_timer_stop();
433 else {
434 printk(KERN_WARNING "wdrtas: got unexpected close. Watchdog "
435 "not stopped.\n");
436 wdrtas_timer_keepalive();
437 }
438
439 wdrtas_expect_close = 0;
440 atomic_dec(&wdrtas_miscdev_open);
441 return 0;
442}
443
444/**
445 * wdrtas_temp_read - gives back the temperature in fahrenheit
446 * @file: file structure
447 * @buf: user buffer
448 * @count: number of bytes to be read
449 * @ppos: position in file
450 *
451 * returns always 1 or -EFAULT in case of user space copy failures, <0 on
452 * other failures
453 *
454 * wdrtas_temp_read gives the temperature to the users by copying this
455 * value as one byte into the user space buffer. The unit is Fahrenheit...
456 */
457static ssize_t
458wdrtas_temp_read(struct file *file, char __user *buf,
459 size_t count, loff_t *ppos)
460{
461 int temperature = 0;
462
463 temperature = wdrtas_get_temperature();
464 if (temperature < 0)
465 return temperature;
466
467 if (copy_to_user(buf, &temperature, 1))
468 return -EFAULT;
469
470 return 1;
471}
472
473/**
474 * wdrtas_temp_open - open function of temperature device
475 * @inode: inode structure
476 * @file: file structure
477 *
478 * returns 0 on success, <0 on failure
479 *
480 * function called when temperature device is opened
481 */
482static int
483wdrtas_temp_open(struct inode *inode, struct file *file)
484{
485 return nonseekable_open(inode, file);
486}
487
488/**
489 * wdrtas_temp_close - close function of temperature device
490 * @inode: inode structure
491 * @file: file structure
492 *
493 * returns 0 on success
494 *
495 * close function. Always succeeds
496 */
497static int
498wdrtas_temp_close(struct inode *inode, struct file *file)
499{
500 return 0;
501}
502
503/**
504 * wdrtas_reboot - reboot notifier function
505 * @nb: notifier block structure
506 * @code: reboot code
507 * @ptr: unused
508 *
509 * returns NOTIFY_DONE
510 *
511 * wdrtas_reboot stops the watchdog in case of a reboot
512 */
513static int
514wdrtas_reboot(struct notifier_block *this, unsigned long code, void *ptr)
515{
516 if ( (code==SYS_DOWN) || (code==SYS_HALT) )
517 wdrtas_timer_stop();
518
519 return NOTIFY_DONE;
520}
521
522/*** initialization stuff */
523
524static struct file_operations wdrtas_fops = {
525 .owner = THIS_MODULE,
526 .llseek = no_llseek,
527 .write = wdrtas_write,
528 .ioctl = wdrtas_ioctl,
529 .open = wdrtas_open,
530 .release = wdrtas_close,
531};
532
533static struct miscdevice wdrtas_miscdev = {
534 .minor = WATCHDOG_MINOR,
535 .name = "watchdog",
536 .fops = &wdrtas_fops,
537};
538
539static struct file_operations wdrtas_temp_fops = {
540 .owner = THIS_MODULE,
541 .llseek = no_llseek,
542 .read = wdrtas_temp_read,
543 .open = wdrtas_temp_open,
544 .release = wdrtas_temp_close,
545};
546
547static struct miscdevice wdrtas_tempdev = {
548 .minor = TEMP_MINOR,
549 .name = "temperature",
550 .fops = &wdrtas_temp_fops,
551};
552
553static struct notifier_block wdrtas_notifier = {
554 .notifier_call = wdrtas_reboot,
555};
556
557/**
558 * wdrtas_get_tokens - reads in RTAS tokens
559 *
560 * returns 0 on succes, <0 on failure
561 *
562 * wdrtas_get_tokens reads in the tokens for the RTAS calls used in
563 * this watchdog driver. It tolerates, if "get-sensor-state" and
564 * "ibm,get-system-parameter" are not available.
565 */
566static int
567wdrtas_get_tokens(void)
568{
569 wdrtas_token_get_sensor_state = rtas_token("get-sensor-state");
570 if (wdrtas_token_get_sensor_state == RTAS_UNKNOWN_SERVICE) {
571 printk(KERN_WARNING "wdrtas: couldn't get token for "
572 "get-sensor-state. Trying to continue without "
573 "temperature support.\n");
574 }
575
576 wdrtas_token_get_sp = rtas_token("ibm,get-system-parameter");
577 if (wdrtas_token_get_sp == RTAS_UNKNOWN_SERVICE) {
578 printk(KERN_WARNING "wdrtas: couldn't get token for "
579 "ibm,get-system-parameter. Trying to continue with "
580 "a default timeout value of %i seconds.\n",
581 WDRTAS_DEFAULT_INTERVAL);
582 }
583
584 wdrtas_token_set_indicator = rtas_token("set-indicator");
585 if (wdrtas_token_set_indicator == RTAS_UNKNOWN_SERVICE) {
586 printk(KERN_ERR "wdrtas: couldn't get token for "
587 "set-indicator. Terminating watchdog code.\n");
588 return -EIO;
589 }
590
591 wdrtas_token_event_scan = rtas_token("event-scan");
592 if (wdrtas_token_event_scan == RTAS_UNKNOWN_SERVICE) {
593 printk(KERN_ERR "wdrtas: couldn't get token for event-scan. "
594 "Terminating watchdog code.\n");
595 return -EIO;
596 }
597
598 return 0;
599}
600
601/**
602 * wdrtas_unregister_devs - unregisters the misc dev handlers
603 *
604 * wdrtas_register_devs unregisters the watchdog and temperature watchdog
605 * misc devs
606 */
607static void
608wdrtas_unregister_devs(void)
609{
610 misc_deregister(&wdrtas_miscdev);
611 if (wdrtas_token_get_sensor_state != RTAS_UNKNOWN_SERVICE)
612 misc_deregister(&wdrtas_tempdev);
613}
614
615/**
616 * wdrtas_register_devs - registers the misc dev handlers
617 *
618 * returns 0 on succes, <0 on failure
619 *
620 * wdrtas_register_devs registers the watchdog and temperature watchdog
621 * misc devs
622 */
623static int
624wdrtas_register_devs(void)
625{
626 int result;
627
628 result = misc_register(&wdrtas_miscdev);
629 if (result) {
630 printk(KERN_ERR "wdrtas: couldn't register watchdog misc "
631 "device. Terminating watchdog code.\n");
632 return result;
633 }
634
635 if (wdrtas_token_get_sensor_state != RTAS_UNKNOWN_SERVICE) {
636 result = misc_register(&wdrtas_tempdev);
637 if (result) {
638 printk(KERN_WARNING "wdrtas: couldn't register "
639 "watchdog temperature misc device. Continuing "
640 "without temperature support.\n");
641 wdrtas_token_get_sensor_state = RTAS_UNKNOWN_SERVICE;
642 }
643 }
644
645 return 0;
646}
647
648/**
649 * wdrtas_init - init function of the watchdog driver
650 *
651 * returns 0 on succes, <0 on failure
652 *
653 * registers the file handlers and the reboot notifier
654 */
655static int __init
656wdrtas_init(void)
657{
658 if (wdrtas_get_tokens())
659 return -ENODEV;
660
661 if (wdrtas_register_devs())
662 return -ENODEV;
663
664 if (register_reboot_notifier(&wdrtas_notifier)) {
665 printk(KERN_ERR "wdrtas: could not register reboot notifier. "
666 "Terminating watchdog code.\n");
667 wdrtas_unregister_devs();
668 return -ENODEV;
669 }
670
671 if (wdrtas_token_get_sp == RTAS_UNKNOWN_SERVICE)
672 wdrtas_interval = WDRTAS_DEFAULT_INTERVAL;
673 else
674 wdrtas_interval = wdrtas_get_interval(WDRTAS_DEFAULT_INTERVAL);
675
676 return 0;
677}
678
679/**
680 * wdrtas_exit - exit function of the watchdog driver
681 *
682 * unregisters the file handlers and the reboot notifier
683 */
684static void __exit
685wdrtas_exit(void)
686{
687 if (!wdrtas_nowayout)
688 wdrtas_timer_stop();
689
690 wdrtas_unregister_devs();
691
692 unregister_reboot_notifier(&wdrtas_notifier);
693}
694
695module_init(wdrtas_init);
696module_exit(wdrtas_exit);