aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/i8k.c149
-rw-r--r--drivers/char/misc.c4
2 files changed, 47 insertions, 106 deletions
diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c
index 1599456bdb65..584e9a4a6f18 100644
--- a/drivers/char/i8k.c
+++ b/drivers/char/i8k.c
@@ -87,14 +87,14 @@ static struct file_operations i8k_fops = {
87 .ioctl = i8k_ioctl, 87 .ioctl = i8k_ioctl,
88}; 88};
89 89
90typedef struct { 90struct smm_regs {
91 unsigned int eax; 91 unsigned int eax;
92 unsigned int ebx __attribute__ ((packed)); 92 unsigned int ebx __attribute__ ((packed));
93 unsigned int ecx __attribute__ ((packed)); 93 unsigned int ecx __attribute__ ((packed));
94 unsigned int edx __attribute__ ((packed)); 94 unsigned int edx __attribute__ ((packed));
95 unsigned int esi __attribute__ ((packed)); 95 unsigned int esi __attribute__ ((packed));
96 unsigned int edi __attribute__ ((packed)); 96 unsigned int edi __attribute__ ((packed));
97} SMMRegisters; 97};
98 98
99static inline char *i8k_get_dmi_data(int field) 99static inline char *i8k_get_dmi_data(int field)
100{ 100{
@@ -104,7 +104,7 @@ static inline char *i8k_get_dmi_data(int field)
104/* 104/*
105 * Call the System Management Mode BIOS. Code provided by Jonathan Buzzard. 105 * Call the System Management Mode BIOS. Code provided by Jonathan Buzzard.
106 */ 106 */
107static int i8k_smm(SMMRegisters * regs) 107static int i8k_smm(struct smm_regs *regs)
108{ 108{
109 int rc; 109 int rc;
110 int eax = regs->eax; 110 int eax = regs->eax;
@@ -134,9 +134,8 @@ static int i8k_smm(SMMRegisters * regs)
134 : "a"(regs) 134 : "a"(regs)
135 : "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory"); 135 : "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
136 136
137 if ((rc != 0) || ((regs->eax & 0xffff) == 0xffff) || (regs->eax == eax)) { 137 if (rc != 0 || (regs->eax & 0xffff) == 0xffff || regs->eax == eax)
138 return -EINVAL; 138 return -EINVAL;
139 }
140 139
141 return 0; 140 return 0;
142} 141}
@@ -147,15 +146,9 @@ static int i8k_smm(SMMRegisters * regs)
147 */ 146 */
148static int i8k_get_bios_version(void) 147static int i8k_get_bios_version(void)
149{ 148{
150 SMMRegisters regs = { 0, 0, 0, 0, 0, 0 }; 149 struct smm_regs regs = { .eax = I8K_SMM_BIOS_VERSION, };
151 int rc;
152
153 regs.eax = I8K_SMM_BIOS_VERSION;
154 if ((rc = i8k_smm(&regs)) < 0) {
155 return rc;
156 }
157 150
158 return regs.eax; 151 return i8k_smm(&regs) ? : regs.eax;
159} 152}
160 153
161/* 154/*
@@ -163,13 +156,11 @@ static int i8k_get_bios_version(void)
163 */ 156 */
164static int i8k_get_fn_status(void) 157static int i8k_get_fn_status(void)
165{ 158{
166 SMMRegisters regs = { 0, 0, 0, 0, 0, 0 }; 159 struct smm_regs regs = { .eax = I8K_SMM_FN_STATUS, };
167 int rc; 160 int rc;
168 161
169 regs.eax = I8K_SMM_FN_STATUS; 162 if ((rc = i8k_smm(&regs)) < 0)
170 if ((rc = i8k_smm(&regs)) < 0) {
171 return rc; 163 return rc;
172 }
173 164
174 switch ((regs.eax >> I8K_FN_SHIFT) & I8K_FN_MASK) { 165 switch ((regs.eax >> I8K_FN_SHIFT) & I8K_FN_MASK) {
175 case I8K_FN_UP: 166 case I8K_FN_UP:
@@ -188,20 +179,13 @@ static int i8k_get_fn_status(void)
188 */ 179 */
189static int i8k_get_power_status(void) 180static int i8k_get_power_status(void)
190{ 181{
191 SMMRegisters regs = { 0, 0, 0, 0, 0, 0 }; 182 struct smm_regs regs = { .eax = I8K_SMM_POWER_STATUS, };
192 int rc; 183 int rc;
193 184
194 regs.eax = I8K_SMM_POWER_STATUS; 185 if ((rc = i8k_smm(&regs)) < 0)
195 if ((rc = i8k_smm(&regs)) < 0) {
196 return rc; 186 return rc;
197 }
198 187
199 switch (regs.eax & 0xff) { 188 return (regs.eax & 0xff) == I8K_POWER_AC ? I8K_AC : I8K_BATTERY;
200 case I8K_POWER_AC:
201 return I8K_AC;
202 default:
203 return I8K_BATTERY;
204 }
205} 189}
206 190
207/* 191/*
@@ -209,16 +193,10 @@ static int i8k_get_power_status(void)
209 */ 193 */
210static int i8k_get_fan_status(int fan) 194static int i8k_get_fan_status(int fan)
211{ 195{
212 SMMRegisters regs = { 0, 0, 0, 0, 0, 0 }; 196 struct smm_regs regs = { .eax = I8K_SMM_GET_FAN, };
213 int rc;
214 197
215 regs.eax = I8K_SMM_GET_FAN;
216 regs.ebx = fan & 0xff; 198 regs.ebx = fan & 0xff;
217 if ((rc = i8k_smm(&regs)) < 0) { 199 return i8k_smm(&regs) ? : regs.eax & 0xff;
218 return rc;
219 }
220
221 return (regs.eax & 0xff);
222} 200}
223 201
224/* 202/*
@@ -226,16 +204,10 @@ static int i8k_get_fan_status(int fan)
226 */ 204 */
227static int i8k_get_fan_speed(int fan) 205static int i8k_get_fan_speed(int fan)
228{ 206{
229 SMMRegisters regs = { 0, 0, 0, 0, 0, 0 }; 207 struct smm_regs regs = { .eax = I8K_SMM_GET_SPEED, };
230 int rc;
231 208
232 regs.eax = I8K_SMM_GET_SPEED;
233 regs.ebx = fan & 0xff; 209 regs.ebx = fan & 0xff;
234 if ((rc = i8k_smm(&regs)) < 0) { 210 return i8k_smm(&regs) ? : (regs.eax & 0xffff) * I8K_FAN_MULT;
235 return rc;
236 }
237
238 return (regs.eax & 0xffff) * I8K_FAN_MULT;
239} 211}
240 212
241/* 213/*
@@ -243,18 +215,12 @@ static int i8k_get_fan_speed(int fan)
243 */ 215 */
244static int i8k_set_fan(int fan, int speed) 216static int i8k_set_fan(int fan, int speed)
245{ 217{
246 SMMRegisters regs = { 0, 0, 0, 0, 0, 0 }; 218 struct smm_regs regs = { .eax = I8K_SMM_SET_FAN, };
247 int rc;
248 219
249 speed = (speed < 0) ? 0 : ((speed > I8K_FAN_MAX) ? I8K_FAN_MAX : speed); 220 speed = (speed < 0) ? 0 : ((speed > I8K_FAN_MAX) ? I8K_FAN_MAX : speed);
250
251 regs.eax = I8K_SMM_SET_FAN;
252 regs.ebx = (fan & 0xff) | (speed << 8); 221 regs.ebx = (fan & 0xff) | (speed << 8);
253 if ((rc = i8k_smm(&regs)) < 0) {
254 return rc;
255 }
256 222
257 return (i8k_get_fan_status(fan)); 223 return i8k_smm(&regs) ? : i8k_get_fan_status(fan);
258} 224}
259 225
260/* 226/*
@@ -262,18 +228,17 @@ static int i8k_set_fan(int fan, int speed)
262 */ 228 */
263static int i8k_get_cpu_temp(void) 229static int i8k_get_cpu_temp(void)
264{ 230{
265 SMMRegisters regs = { 0, 0, 0, 0, 0, 0 }; 231 struct smm_regs regs = { .eax = I8K_SMM_GET_TEMP, };
266 int rc; 232 int rc;
267 int temp; 233 int temp;
268 234
269#ifdef I8K_TEMPERATURE_BUG 235#ifdef I8K_TEMPERATURE_BUG
270 static int prev = 0; 236 static int prev;
271#endif 237#endif
272 238
273 regs.eax = I8K_SMM_GET_TEMP; 239 if ((rc = i8k_smm(&regs)) < 0)
274 if ((rc = i8k_smm(&regs)) < 0) {
275 return rc; 240 return rc;
276 } 241
277 temp = regs.eax & 0xff; 242 temp = regs.eax & 0xff;
278 243
279#ifdef I8K_TEMPERATURE_BUG 244#ifdef I8K_TEMPERATURE_BUG
@@ -297,19 +262,13 @@ static int i8k_get_cpu_temp(void)
297 262
298static int i8k_get_dell_signature(void) 263static int i8k_get_dell_signature(void)
299{ 264{
300 SMMRegisters regs = { 0, 0, 0, 0, 0, 0 }; 265 struct smm_regs regs = { .eax = I8K_SMM_GET_DELL_SIG, };
301 int rc; 266 int rc;
302 267
303 regs.eax = I8K_SMM_GET_DELL_SIG; 268 if ((rc = i8k_smm(&regs)) < 0)
304 if ((rc = i8k_smm(&regs)) < 0) {
305 return rc; 269 return rc;
306 }
307 270
308 if ((regs.eax == 1145651527) && (regs.edx == 1145392204)) { 271 return regs.eax == 1145651527 && regs.edx == 1145392204 ? 0 : -1;
309 return 0;
310 } else {
311 return -1;
312 }
313} 272}
314 273
315static int i8k_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, 274static int i8k_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
@@ -346,29 +305,29 @@ static int i8k_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
346 break; 305 break;
347 306
348 case I8K_GET_SPEED: 307 case I8K_GET_SPEED:
349 if (copy_from_user(&val, argp, sizeof(int))) { 308 if (copy_from_user(&val, argp, sizeof(int)))
350 return -EFAULT; 309 return -EFAULT;
351 } 310
352 val = i8k_get_fan_speed(val); 311 val = i8k_get_fan_speed(val);
353 break; 312 break;
354 313
355 case I8K_GET_FAN: 314 case I8K_GET_FAN:
356 if (copy_from_user(&val, argp, sizeof(int))) { 315 if (copy_from_user(&val, argp, sizeof(int)))
357 return -EFAULT; 316 return -EFAULT;
358 } 317
359 val = i8k_get_fan_status(val); 318 val = i8k_get_fan_status(val);
360 break; 319 break;
361 320
362 case I8K_SET_FAN: 321 case I8K_SET_FAN:
363 if (restricted && !capable(CAP_SYS_ADMIN)) { 322 if (restricted && !capable(CAP_SYS_ADMIN))
364 return -EPERM; 323 return -EPERM;
365 } 324
366 if (copy_from_user(&val, argp, sizeof(int))) { 325 if (copy_from_user(&val, argp, sizeof(int)))
367 return -EFAULT; 326 return -EFAULT;
368 } 327
369 if (copy_from_user(&speed, argp + 1, sizeof(int))) { 328 if (copy_from_user(&speed, argp + 1, sizeof(int)))
370 return -EFAULT; 329 return -EFAULT;
371 } 330
372 val = i8k_set_fan(val, speed); 331 val = i8k_set_fan(val, speed);
373 break; 332 break;
374 333
@@ -376,25 +335,24 @@ static int i8k_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
376 return -EINVAL; 335 return -EINVAL;
377 } 336 }
378 337
379 if (val < 0) { 338 if (val < 0)
380 return val; 339 return val;
381 }
382 340
383 switch (cmd) { 341 switch (cmd) {
384 case I8K_BIOS_VERSION: 342 case I8K_BIOS_VERSION:
385 if (copy_to_user(argp, &val, 4)) { 343 if (copy_to_user(argp, &val, 4))
386 return -EFAULT; 344 return -EFAULT;
387 } 345
388 break; 346 break;
389 case I8K_MACHINE_ID: 347 case I8K_MACHINE_ID:
390 if (copy_to_user(argp, buff, 16)) { 348 if (copy_to_user(argp, buff, 16))
391 return -EFAULT; 349 return -EFAULT;
392 } 350
393 break; 351 break;
394 default: 352 default:
395 if (copy_to_user(argp, &val, sizeof(int))) { 353 if (copy_to_user(argp, &val, sizeof(int)))
396 return -EFAULT; 354 return -EFAULT;
397 } 355
398 break; 356 break;
399 } 357 }
400 358
@@ -415,11 +373,10 @@ static int i8k_proc_show(struct seq_file *seq, void *offset)
415 left_speed = i8k_get_fan_speed(I8K_FAN_LEFT); /* 580 µs */ 373 left_speed = i8k_get_fan_speed(I8K_FAN_LEFT); /* 580 µs */
416 right_speed = i8k_get_fan_speed(I8K_FAN_RIGHT); /* 580 µs */ 374 right_speed = i8k_get_fan_speed(I8K_FAN_RIGHT); /* 580 µs */
417 fn_key = i8k_get_fn_status(); /* 750 µs */ 375 fn_key = i8k_get_fn_status(); /* 750 µs */
418 if (power_status) { 376 if (power_status)
419 ac_power = i8k_get_power_status(); /* 14700 µs */ 377 ac_power = i8k_get_power_status(); /* 14700 µs */
420 } else { 378 else
421 ac_power = -1; 379 ac_power = -1;
422 }
423 380
424 /* 381 /*
425 * Info: 382 * Info:
@@ -528,10 +485,7 @@ static int __init i8k_probe(void)
528 return 0; 485 return 0;
529} 486}
530 487
531#ifdef MODULE 488static int __init i8k_init(void)
532static
533#endif
534int __init i8k_init(void)
535{ 489{
536 struct proc_dir_entry *proc_i8k; 490 struct proc_dir_entry *proc_i8k;
537 491
@@ -554,19 +508,10 @@ int __init i8k_init(void)
554 return 0; 508 return 0;
555} 509}
556 510
557#ifdef MODULE 511static void __exit i8k_exit(void)
558int init_module(void)
559{ 512{
560 return i8k_init();
561}
562
563void cleanup_module(void)
564{
565 /* Remove the proc entry */
566 remove_proc_entry("i8k", NULL); 513 remove_proc_entry("i8k", NULL);
567
568 printk(KERN_INFO "i8k: module unloaded\n");
569} 514}
570#endif
571 515
572/* end of file */ 516module_init(i8k_init);
517module_exit(i8k_exit);
diff --git a/drivers/char/misc.c b/drivers/char/misc.c
index f7e838eae19c..31cf84d69026 100644
--- a/drivers/char/misc.c
+++ b/drivers/char/misc.c
@@ -66,7 +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 i8k_init(void);
70 69
71#ifdef CONFIG_PROC_FS 70#ifdef CONFIG_PROC_FS
72static void *misc_seq_start(struct seq_file *seq, loff_t *pos) 71static void *misc_seq_start(struct seq_file *seq, loff_t *pos)
@@ -313,9 +312,6 @@ static int __init misc_init(void)
313#ifdef CONFIG_PMAC_PBOOK 312#ifdef CONFIG_PMAC_PBOOK
314 pmu_device_init(); 313 pmu_device_init();
315#endif 314#endif
316#ifdef CONFIG_I8K
317 i8k_init();
318#endif
319 if (register_chrdev(MISC_MAJOR,"misc",&misc_fops)) { 315 if (register_chrdev(MISC_MAJOR,"misc",&misc_fops)) {
320 printk("unable to get major %d for misc devices\n", 316 printk("unable to get major %d for misc devices\n",
321 MISC_MAJOR); 317 MISC_MAJOR);