1 /*
2  *   arch/ppc64/kernel/rtas-proc.c
3  *   Copyright (C) 2000 Tilmann Bitterberg
4  *   (tilmann@bitterberg.de)
5  *
6  *   RTAS (Runtime Abstraction Services) stuff
7  *   Intention is to provide a clean user interface
8  *   to use the RTAS.
9  *
10  *   TODO:
11  *   Split off a header file and maybe move it to a different
12  *   location. Write Documentation on what the /proc/rtas/ entries
13  *   actually do.
14  */
15 
16 #include <linux/errno.h>
17 #include <linux/sched.h>
18 #include <linux/proc_fs.h>
19 #include <linux/stat.h>
20 #include <linux/ctype.h>
21 #include <linux/time.h>
22 #include <linux/string.h>
23 
24 #include <asm/uaccess.h>
25 #include <asm/bitops.h>
26 #include <asm/processor.h>
27 #include <asm/io.h>
28 #include <asm/prom.h>
29 #include <asm/rtas.h>
30 #include <asm/machdep.h> /* for ppc_md */
31 #include <asm/time.h>
32 
33 /* Token for Sensors */
34 #define KEY_SWITCH		0x0001
35 #define ENCLOSURE_SWITCH	0x0002
36 #define THERMAL_SENSOR		0x0003
37 #define LID_STATUS		0x0004
38 #define POWER_SOURCE		0x0005
39 #define BATTERY_VOLTAGE		0x0006
40 #define BATTERY_REMAINING	0x0007
41 #define BATTERY_PERCENTAGE	0x0008
42 #define EPOW_SENSOR		0x0009
43 #define BATTERY_CYCLESTATE	0x000a
44 #define BATTERY_CHARGING	0x000b
45 
46 /* IBM specific sensors */
47 #define IBM_SURVEILLANCE	0x2328 /* 9000 */
48 #define IBM_FANRPM		0x2329 /* 9001 */
49 #define IBM_VOLTAGE		0x232a /* 9002 */
50 #define IBM_DRCONNECTOR		0x232b /* 9003 */
51 #define IBM_POWERSUPPLY		0x232c /* 9004 */
52 #define IBM_INTQUEUE		0x232d /* 9005 */
53 
54 /* Status return values */
55 #define SENSOR_CRITICAL_HIGH	13
56 #define SENSOR_WARNING_HIGH	12
57 #define SENSOR_NORMAL		11
58 #define SENSOR_WARNING_LOW	10
59 #define SENSOR_CRITICAL_LOW	 9
60 #define SENSOR_SUCCESS		 0
61 #define SENSOR_HW_ERROR		-1
62 #define SENSOR_BUSY		-2
63 #define SENSOR_NOT_EXIST	-3
64 #define SENSOR_DR_ENTITY	-9000
65 
66 /* Location Codes */
67 #define LOC_SCSI_DEV_ADDR	'A'
68 #define LOC_SCSI_DEV_LOC	'B'
69 #define LOC_CPU			'C'
70 #define LOC_DISKETTE		'D'
71 #define LOC_ETHERNET		'E'
72 #define LOC_FAN			'F'
73 #define LOC_GRAPHICS		'G'
74 /* reserved / not used		'H' */
75 #define LOC_IO_ADAPTER		'I'
76 /* reserved / not used		'J' */
77 #define LOC_KEYBOARD		'K'
78 #define LOC_LCD			'L'
79 #define LOC_MEMORY		'M'
80 #define LOC_NV_MEMORY		'N'
81 #define LOC_MOUSE		'O'
82 #define LOC_PLANAR		'P'
83 #define LOC_OTHER_IO		'Q'
84 #define LOC_PARALLEL		'R'
85 #define LOC_SERIAL		'S'
86 #define LOC_DEAD_RING		'T'
87 #define LOC_RACKMOUNTED		'U' /* for _u_nit is rack mounted */
88 #define LOC_VOLTAGE		'V'
89 #define LOC_SWITCH_ADAPTER	'W'
90 #define LOC_OTHER		'X'
91 #define LOC_FIRMWARE		'Y'
92 #define LOC_SCSI		'Z'
93 
94 /* Tokens for indicators */
95 #define TONE_FREQUENCY		0x0001 /* 0 - 1000 (HZ)*/
96 #define TONE_VOLUME		0x0002 /* 0 - 100 (%) */
97 #define SYSTEM_POWER_STATE	0x0003
98 #define WARNING_LIGHT		0x0004
99 #define DISK_ACTIVITY_LIGHT	0x0005
100 #define HEX_DISPLAY_UNIT	0x0006
101 #define BATTERY_WARNING_TIME	0x0007
102 #define CONDITION_CYCLE_REQUEST	0x0008
103 #define SURVEILLANCE_INDICATOR	0x2328 /* 9000 */
104 #define DR_ACTION		0x2329 /* 9001 */
105 #define DR_INDICATOR		0x232a /* 9002 */
106 /* 9003 - 9004: Vendor specific */
107 #define GLOBAL_INTERRUPT_QUEUE	0x232d /* 9005 */
108 /* 9006 - 9999: Vendor specific */
109 
110 /* other */
111 #define MAX_SENSORS		 17  /* I only know of 17 sensors */
112 #define MAX_LINELENGTH          256
113 #define SENSOR_PREFIX		"ibm,sensor-"
114 #define cel_to_fahr(x)		((x*9/5)+32)
115 
116 
117 /* Globals */
118 static struct rtas_sensors sensors;
119 static struct device_node *rtas_node = NULL;
120 static unsigned long power_on_time = 0; /* Save the time the user set */
121 static char progress_led[MAX_LINELENGTH];
122 
123 static unsigned long rtas_tone_frequency = 1000;
124 static unsigned long rtas_tone_volume = 0;
125 static unsigned int open_token = 0;
126 
127 static int set_time_for_power_on = RTAS_UNKNOWN_SERVICE;
128 static int set_time_of_day = RTAS_UNKNOWN_SERVICE;
129 static int get_sensor_state = RTAS_UNKNOWN_SERVICE;
130 static int set_indicator = RTAS_UNKNOWN_SERVICE;
131 
132 extern struct proc_dir_entry *proc_ppc64_root;
133 extern struct proc_dir_entry *rtas_proc_dir;
134 extern spinlock_t proc_ppc64_lock;
135 
136 /* ****************STRUCTS******************************************* */
137 struct individual_sensor {
138 	unsigned int token;
139 	unsigned int quant;
140 };
141 
142 struct rtas_sensors {
143         struct individual_sensor sensor[MAX_SENSORS];
144 	unsigned int quant;
145 };
146 
147 /* ****************************************************************** */
148 /* Declarations */
149 static int ppc_rtas_sensor_read(char * buf, char ** start, off_t off,
150 		int count, int *eof, void *data);
151 static ssize_t ppc_rtas_clock_read(struct file * file, char * buf,
152 		size_t count, loff_t *ppos);
153 static ssize_t ppc_rtas_clock_write(struct file * file, const char * buf,
154 		size_t count, loff_t *ppos);
155 static ssize_t ppc_rtas_progress_read(struct file * file, char * buf,
156 		size_t count, loff_t *ppos);
157 static ssize_t ppc_rtas_progress_write(struct file * file, const char * buf,
158 		size_t count, loff_t *ppos);
159 static ssize_t ppc_rtas_poweron_read(struct file * file, char * buf,
160 		size_t count, loff_t *ppos);
161 static ssize_t ppc_rtas_poweron_write(struct file * file, const char * buf,
162 		size_t count, loff_t *ppos);
163 
164 static ssize_t ppc_rtas_tone_freq_write(struct file * file, const char * buf,
165 		size_t count, loff_t *ppos);
166 static ssize_t ppc_rtas_tone_freq_read(struct file * file, char * buf,
167 		size_t count, loff_t *ppos);
168 static ssize_t ppc_rtas_tone_volume_write(struct file * file, const char * buf,
169 		size_t count, loff_t *ppos);
170 static ssize_t ppc_rtas_tone_volume_read(struct file * file, char * buf,
171 		size_t count, loff_t *ppos);
172 static int ppc_rtas_errinjct_open(struct inode *inode, struct file *file);
173 static int ppc_rtas_errinjct_release(struct inode *inode, struct file *file);
174 static ssize_t ppc_rtas_errinjct_write(struct file * file, const char * buf,
175 				   size_t count, loff_t *ppos);
176 static ssize_t ppc_rtas_errinjct_read(struct file *file, char *buf,
177 				      size_t count, loff_t *ppos);
178 
179 struct file_operations ppc_rtas_poweron_operations = {
180 	.read =		ppc_rtas_poweron_read,
181 	.write =	ppc_rtas_poweron_write
182 };
183 struct file_operations ppc_rtas_progress_operations = {
184 	.read =		ppc_rtas_progress_read,
185 	.write =	ppc_rtas_progress_write
186 };
187 
188 struct file_operations ppc_rtas_clock_operations = {
189 	.read =		ppc_rtas_clock_read,
190 	.write =	ppc_rtas_clock_write
191 };
192 
193 struct file_operations ppc_rtas_tone_freq_operations = {
194 	.read =		ppc_rtas_tone_freq_read,
195 	.write =	ppc_rtas_tone_freq_write
196 };
197 struct file_operations ppc_rtas_tone_volume_operations = {
198 	.read =		ppc_rtas_tone_volume_read,
199 	.write =	ppc_rtas_tone_volume_write
200 };
201 
202 struct file_operations ppc_rtas_errinjct_operations = {
203     .open =		ppc_rtas_errinjct_open,
204     .read = 		ppc_rtas_errinjct_read,
205     .write = 		ppc_rtas_errinjct_write,
206     .release = 		ppc_rtas_errinjct_release
207 };
208 
209 int ppc_rtas_find_all_sensors (void);
210 int ppc_rtas_process_sensor(struct individual_sensor s, int state,
211 		int error, char * buf);
212 char * ppc_rtas_process_error(int error);
213 int get_location_code(struct individual_sensor s, char * buf);
214 int check_location_string (char *c, char * buf);
215 int check_location (char *c, int idx, char * buf);
216 
217 /* ****************************************************************** */
218 /* MAIN                                                               */
219 /* ****************************************************************** */
proc_rtas_init(void)220 void proc_rtas_init(void)
221 {
222 	struct proc_dir_entry *entry;
223 	int display_character;
224 	int errinjct_token;
225 
226 	rtas_node = find_devices("rtas");
227 	if ((rtas_node == NULL) || (systemcfg->platform == PLATFORM_ISERIES_LPAR)) {
228 		return;
229 	}
230 
231 	spin_lock(&proc_ppc64_lock);
232 	if (proc_ppc64_root == NULL) {
233 		proc_ppc64_root = proc_mkdir("ppc64", 0);
234 		if (!proc_ppc64_root) {
235 			spin_unlock(&proc_ppc64_lock);
236 			return;
237 		}
238 	}
239 	spin_unlock(&proc_ppc64_lock);
240 
241 	if (rtas_proc_dir == NULL) {
242 		rtas_proc_dir = proc_mkdir("rtas", proc_ppc64_root);
243 	}
244 
245 	if (rtas_proc_dir == NULL) {
246 		printk(KERN_ERR "Failed to create /proc/ppc64/rtas in rtas_init\n");
247 		return;
248 	}
249 
250 	/*
251 	 * /proc/rtas entries
252 	 * only create entries if rtas token exists for desired function
253 	 */
254 
255 	set_time_of_day = rtas_token("set-time-of-day");
256 	if (set_time_of_day != RTAS_UNKNOWN_SERVICE) {
257 		entry=create_proc_entry("clock",S_IRUGO|S_IWUSR,rtas_proc_dir);
258 		if (entry) entry->proc_fops = &ppc_rtas_clock_operations;
259 	}
260 
261 	set_time_for_power_on = rtas_token("set-time-for-power-on");
262 	if (set_time_for_power_on != RTAS_UNKNOWN_SERVICE) {
263 		entry=create_proc_entry("poweron",S_IWUSR|S_IRUGO,rtas_proc_dir);
264 		if (entry) entry->proc_fops = &ppc_rtas_poweron_operations;
265 	}
266 
267 	get_sensor_state = rtas_token("get-sensor-state");
268 	if (get_sensor_state != RTAS_UNKNOWN_SERVICE) {
269 		create_proc_read_entry("sensors", S_IRUGO, rtas_proc_dir,
270 				       ppc_rtas_sensor_read, NULL);
271 	}
272 
273 	set_indicator = rtas_token("set-indicator");
274 	if (set_indicator != RTAS_UNKNOWN_SERVICE) {
275 		entry=create_proc_entry("frequency",S_IWUSR|S_IRUGO,rtas_proc_dir);
276 		if (entry) entry->proc_fops = &ppc_rtas_tone_freq_operations;
277 
278 		entry=create_proc_entry("volume",S_IWUSR|S_IRUGO,rtas_proc_dir);
279 		if (entry) entry->proc_fops = &ppc_rtas_tone_volume_operations;
280 	}
281 
282 	display_character = rtas_token("display-character");
283 	if ((display_character != RTAS_UNKNOWN_SERVICE) ||
284 	    (set_indicator != RTAS_UNKNOWN_SERVICE)) {
285 		entry=create_proc_entry("progress",S_IRUGO|S_IWUSR,rtas_proc_dir);
286 		if (entry) entry->proc_fops = &ppc_rtas_progress_operations;
287 	}
288 
289 #ifdef CONFIG_RTAS_ERRINJCT
290 	errinjct_token = rtas_token("ibm,errinjct");
291 	if (errinjct_token != RTAS_UNKNOWN_SERVICE) {
292 		entry=create_proc_entry("errinjct",S_IWUSR|S_IRUGO,rtas_proc_dir);
293 		if (entry) entry->proc_fops = &ppc_rtas_errinjct_operations;
294 	}
295 #endif
296 
297 }
298 
299 /* ****************************************************************** */
300 /* POWER-ON-TIME                                                      */
301 /* ****************************************************************** */
ppc_rtas_poweron_write(struct file * file,const char * buf,size_t count,loff_t * ppos)302 static ssize_t ppc_rtas_poweron_write(struct file * file, const char * buf,
303 		size_t count, loff_t *ppos)
304 {
305 	char stkbuf[40];  /* its small, its on stack */
306 	struct rtc_time tm;
307 	unsigned long nowtime;
308 	char *dest;
309 	int error;
310 
311 	if (39 < count)
312 		count = 39;
313 	if (copy_from_user(stkbuf, buf, count))
314 		return -EFAULT;
315 
316 	stkbuf[count] = 0;
317 	nowtime = simple_strtoul(stkbuf, &dest, 10);
318 	if (*dest != '\0' && *dest != '\n') {
319 		printk("ppc_rtas_poweron_write: Invalid time\n");
320 		return count;
321 	}
322 	power_on_time = nowtime; /* save the time */
323 
324 	to_tm(nowtime, &tm);
325 
326 	error = rtas_call(set_time_for_power_on, 7, 1, NULL,
327 			tm.tm_year, tm.tm_mon, tm.tm_mday,
328 			tm.tm_hour, tm.tm_min, tm.tm_sec, 0 /* nano */);
329 	if (error != 0)
330 		printk(KERN_WARNING "error: setting poweron time returned: %s\n",
331 				ppc_rtas_process_error(error));
332 	return count;
333 }
334 /* ****************************************************************** */
ppc_rtas_poweron_read(struct file * file,char * buf,size_t count,loff_t * ppos)335 static ssize_t ppc_rtas_poweron_read(struct file * file, char * buf,
336 		size_t count, loff_t *ppos)
337 {
338 	char stkbuf[40];  /* its small, its on stack */
339 	int n;
340 	loff_t pos = *ppos;
341 
342 	if (power_on_time == 0)
343 		n = snprintf(stkbuf, 40, "Power on time not set\n");
344 	else
345 		n = snprintf(stkbuf, 40, "%lu\n", power_on_time);
346 
347 	int sn = strlen(stkbuf) +1;
348 	if (pos != (unsigned)pos || pos >= sn)
349 		return 0;
350 	if (n > sn - pos)
351 		n = sn - pos;
352 	if (n > count)
353 		n = count;
354 	if (copy_to_user(buf, stkbuf + pos, n))
355 		return -EFAULT;
356 	*ppos = pos + n;
357 	return n;
358 }
359 
360 /* ****************************************************************** */
361 /* PROGRESS                                                           */
362 /* ****************************************************************** */
ppc_rtas_progress_write(struct file * file,const char * buf,size_t count,loff_t * ppos)363 static ssize_t ppc_rtas_progress_write(struct file * file, const char * buf,
364 		size_t count, loff_t *ppos)
365 {
366 	unsigned long hex;
367 
368 	if (count >= MAX_LINELENGTH)
369 		count = MAX_LINELENGTH -1;
370 	if (copy_from_user(progress_led, buf, count))
371 		return -EFAULT;
372 
373 	progress_led[count] = 0;
374 
375 	/* Lets see if the user passed hexdigits */
376 	hex = simple_strtoul(progress_led, NULL, 10);
377 
378 	ppc_md.progress((char *)progress_led, hex);
379 	return count;
380 
381 	/* clear the line */ /* ppc_md.progress("                   ", 0xffff);*/
382 }
383 /* ****************************************************************** */
ppc_rtas_progress_read(struct file * file,char * buf,size_t count,loff_t * ppos)384 static ssize_t ppc_rtas_progress_read(struct file * file, char * buf,
385 		size_t count, loff_t *ppos)
386 {
387 	int n = 0, sn;
388 	loff_t pos = *ppos;
389 
390 	if (progress_led == NULL)
391 		return 0;
392 
393 	char * tmpbuf = kmalloc(MAX_LINELENGTH, GFP_KERNEL);
394 	if (!tmpbuf) {
395 		printk(KERN_ERR "error: kmalloc failed\n");
396 		return -ENOMEM;
397 	}
398 	n = sprintf (tmpbuf, "%s\n", progress_led);
399 
400 	sn = strlen (tmpbuf) +1;
401 	if (pos != (unsigned)pos || pos >= sn) {
402 		kfree(tmpbuf);
403 		return 0;
404 	}
405 	if (n > sn - pos)
406 		n = sn - pos;
407 	if (n > count)
408 		n = count;
409 	if (copy_to_user(buf, tmpbuf + pos, n)) {
410 		kfree(tmpbuf);
411 		return -EFAULT;
412 	}
413 	kfree(tmpbuf);
414 	*ppos = pos + n;
415 	return n;
416 }
417 
418 /* ****************************************************************** */
419 /* CLOCK                                                              */
420 /* ****************************************************************** */
ppc_rtas_clock_write(struct file * file,const char * buf,size_t count,loff_t * ppos)421 static ssize_t ppc_rtas_clock_write(struct file * file, const char * buf,
422 		size_t count, loff_t *ppos)
423 {
424 	char stkbuf[40];  /* its small, its on stack */
425 	struct rtc_time tm;
426 	unsigned long nowtime;
427 	char *dest;
428 	int error;
429 
430 	if (39 < count)
431 		count = 39;
432 	if (copy_from_user(stkbuf, buf, count))
433 		return -EFAULT;
434 
435 	stkbuf[count] = 0;
436 	nowtime = simple_strtoul(stkbuf, &dest, 10);
437 	if (*dest != '\0' && *dest != '\n') {
438 		printk("ppc_rtas_clock_write: Invalid time\n");
439 		return count;
440 	}
441 
442 	to_tm(nowtime, &tm);
443 	error = rtas_call(rtas_token("set-time-of-day"), 7, 1, NULL,
444 			tm.tm_year, tm.tm_mon, tm.tm_mday,
445 			tm.tm_hour, tm.tm_min, tm.tm_sec, 0);
446 	if (error != 0)
447 		printk(KERN_WARNING "error: setting the clock returned: %s\n",
448 				ppc_rtas_process_error(error));
449 	return count;
450 }
451 /* ****************************************************************** */
ppc_rtas_clock_read(struct file * file,char * buf,size_t count,loff_t * ppos)452 static ssize_t ppc_rtas_clock_read(struct file * file, char * buf,
453 		size_t count, loff_t *ppos)
454 {
455 	unsigned int year, mon, day, hour, min, sec;
456 	unsigned long *ret = kmalloc(4*8, GFP_KERNEL);
457 	int n, error;
458 	loff_t pos = *ppos;
459 
460 	error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret);
461 
462 	year = ret[0]; mon  = ret[1]; day  = ret[2];
463 	hour = ret[3]; min  = ret[4]; sec  = ret[5];
464 
465 	char stkbuf[40];  /* its small, its on stack */
466 
467 	if (error != 0){
468 		printk(KERN_WARNING "error: reading the clock returned: %s\n",
469 				ppc_rtas_process_error(error));
470 		n = snprintf(stkbuf, 40, "0");
471 	} else {
472 		n = snprintf(stkbuf, 40, "%lu\n", mktime(year, mon, day, hour, min, sec));
473 	}
474 	kfree(ret);
475 
476 	int sn = strlen(stkbuf) +1;
477 	if (pos != (unsigned)pos || pos >= sn)
478 		return 0;
479 	if (n > sn - pos)
480 		n = sn - pos;
481 	if (n > count)
482 		n = count;
483 	if (copy_to_user(buf, stkbuf + pos, n))
484 		return -EFAULT;
485 
486 	*ppos = pos + n;
487 	return n;
488 }
489 
490 /* ****************************************************************** */
491 /* SENSOR STUFF                                                       */
492 /* ****************************************************************** */
ppc_rtas_sensor_read(char * buf,char ** start,off_t off,int count,int * eof,void * data)493 static int ppc_rtas_sensor_read(char * buf, char ** start, off_t off,
494 		int count, int *eof, void *data)
495 {
496 	int i,j,n;
497 	unsigned long ret;
498 	int state, error;
499 	char *buffer;
500 
501 	if (count < 0)
502 		return -EINVAL;
503 
504 	/* May not be enough */
505 	buffer = kmalloc(MAX_LINELENGTH*MAX_SENSORS, GFP_KERNEL);
506 
507 	if (!buffer)
508 		return -ENOMEM;
509 
510 	memset(buffer, 0, MAX_LINELENGTH*MAX_SENSORS);
511 
512 	n  = sprintf ( buffer  , "RTAS (RunTime Abstraction Services) Sensor Information\n");
513 	n += sprintf ( buffer+n, "%-17s\t%-15s\t%-15s\tLocation\n", "Sensor", "Value", "Condition");
514 	n += sprintf ( buffer+n, "***************************************************************************\n");
515 
516 	if (ppc_rtas_find_all_sensors() != 0) {
517 		n += sprintf ( buffer+n, "\nNo sensors are available\n");
518 		goto return_string;
519 	}
520 
521 	for (i=0; i<sensors.quant; i++) {
522 		j = sensors.sensor[i].quant;
523 		/* A sensor may have multiple instances */
524 		while (j >= 0) {
525 
526 			error =	rtas_call(get_sensor_state, 2, 2, &ret,
527 				  	  sensors.sensor[i].token,
528 				  	  sensors.sensor[i].quant - j);
529 
530 			state = (int) ret;
531 			n += ppc_rtas_process_sensor(sensors.sensor[i], state,
532 					     	     error, buffer+n );
533 			n += sprintf (buffer+n, "\n");
534 			j--;
535 		} /* while */
536 	} /* for */
537 
538 return_string:
539 	if (off >= strlen(buffer)) {
540 		*eof = 1;
541 		kfree(buffer);
542 		return 0;
543 	}
544 	if (n > strlen(buffer) - off)
545 		n = strlen(buffer) - off;
546 	if (n > count)
547 		n = count;
548 	else
549 		*eof = 1;
550 
551 	memcpy(buf, buffer + off, n);
552 	*start = buf;
553 	kfree(buffer);
554 	return n;
555 }
556 
557 /* ****************************************************************** */
558 
ppc_rtas_find_all_sensors(void)559 int ppc_rtas_find_all_sensors (void)
560 {
561 	unsigned int *utmp;
562 	int len, i;
563 
564 	utmp = (unsigned int *) get_property(rtas_node, "rtas-sensors", &len);
565 	if (utmp == NULL) {
566 		printk (KERN_ERR "error: could not get rtas-sensors\n");
567 		return 1;
568 	}
569 
570 	sensors.quant = len / 8;      /* int + int */
571 
572 	for (i=0; i<sensors.quant; i++) {
573 		sensors.sensor[i].token = *utmp++;
574 		sensors.sensor[i].quant = *utmp++;
575 	}
576 	return 0;
577 }
578 
579 /* ****************************************************************** */
580 /*
581  * Builds a string of what rtas returned
582  */
ppc_rtas_process_error(int error)583 char * ppc_rtas_process_error(int error)
584 {
585 	switch (error) {
586 		case SENSOR_CRITICAL_HIGH:
587 			return "(critical high)";
588 		case SENSOR_WARNING_HIGH:
589 			return "(warning high)";
590 		case SENSOR_NORMAL:
591 			return "(normal)";
592 		case SENSOR_WARNING_LOW:
593 			return "(warning low)";
594 		case SENSOR_CRITICAL_LOW:
595 			return "(critical low)";
596 		case SENSOR_SUCCESS:
597 			return "(read ok)";
598 		case SENSOR_HW_ERROR:
599 			return "(hardware error)";
600 		case SENSOR_BUSY:
601 			return "(busy)";
602 		case SENSOR_NOT_EXIST:
603 			return "(non existant)";
604 		case SENSOR_DR_ENTITY:
605 			return "(dr entity removed)";
606 		default:
607 			return "(UNKNOWN)";
608 	}
609 }
610 
611 /* ****************************************************************** */
612 /*
613  * Builds a string out of what the sensor said
614  */
615 
ppc_rtas_process_sensor(struct individual_sensor s,int state,int error,char * buf)616 int ppc_rtas_process_sensor(struct individual_sensor s, int state,
617 		int error, char * buf)
618 {
619 	/* Defined return vales */
620 	const char * key_switch[]        = { "Off", "Normal", "Secure", "Maintenance" };
621 	const char * enclosure_switch[]  = { "Closed", "Open" };
622 	const char * lid_status[]        = { " ", "Open", "Closed" };
623 	const char * power_source[]      = { "AC", "Battery", "AC & Battery" };
624 	const char * battery_remaining[] = { "Very Low", "Low", "Mid", "High" };
625 	const char * epow_sensor[]       = {
626 		"EPOW Reset", "Cooling warning", "Power warning",
627 		"System shutdown", "System halt", "EPOW main enclosure",
628 		"EPOW power off" };
629 	const char * battery_cyclestate[]  = { "None", "In progress", "Requested" };
630 	const char * battery_charging[]    = { "Charging", "Discharching", "No current flow" };
631 	const char * ibm_drconnector[]     = { "Empty", "Present" };
632 	const char * ibm_intqueue[]        = { "Disabled", "Enabled" };
633 
634 	int temperature = 0;
635 	int unknown = 0;
636 	int n = 0;
637 	char *label_string = NULL;
638 	const char **value_arr = NULL;
639 	int value_arrsize = 0;
640 
641 	/* What kind of sensor do we have here? */
642 
643 	switch (s.token) {
644 		case KEY_SWITCH:
645 			label_string = "Key switch:";
646 			value_arrsize = sizeof(key_switch)/sizeof(char *);
647 			value_arr = key_switch;
648 			break;
649 		case ENCLOSURE_SWITCH:
650 			label_string = "Enclosure switch:";
651 			value_arrsize = sizeof(enclosure_switch)/sizeof(char *);
652 			value_arr = enclosure_switch;
653 			break;
654 		case THERMAL_SENSOR:
655 			label_string = "Temp. (�C/�F):";
656 			temperature = 1;
657 			break;
658 		case LID_STATUS:
659 			label_string = "Lid status:";
660 			value_arrsize = sizeof(lid_status)/sizeof(char *);
661 			value_arr = lid_status;
662 			break;
663 		case POWER_SOURCE:
664 			label_string = "Power source:";
665 			value_arrsize = sizeof(power_source)/sizeof(char *);
666 			value_arr = power_source;
667 			break;
668 		case BATTERY_VOLTAGE:
669 			label_string = "Battery voltage:";
670 			break;
671 		case BATTERY_REMAINING:
672 			label_string = "Battery remaining:";
673 			value_arrsize = sizeof(battery_remaining)/sizeof(char *);
674 			value_arr = battery_remaining;
675 			break;
676 		case BATTERY_PERCENTAGE:
677 			label_string = "Battery percentage:";
678 			break;
679 		case EPOW_SENSOR:
680 			label_string = "EPOW Sensor:";
681 			value_arrsize = sizeof(epow_sensor)/sizeof(char *);
682 			value_arr = epow_sensor;
683 			break;
684 		case BATTERY_CYCLESTATE:
685 			label_string = "Battery cyclestate:";
686 			value_arrsize = sizeof(battery_cyclestate)/sizeof(char *);
687 			value_arr = battery_cyclestate;
688 			break;
689 		case BATTERY_CHARGING:
690 			label_string = "Battery Charging:";
691 			value_arrsize = sizeof(battery_charging)/sizeof(char *);
692 			value_arr = battery_charging;
693 			break;
694 		case IBM_SURVEILLANCE:
695 			label_string = "Surveillance:";
696 			break;
697 		case IBM_FANRPM:
698 			label_string = "Fan (rpm):";
699 			break;
700 		case IBM_VOLTAGE:
701 			label_string = "Voltage (mv):";
702 			break;
703 		case IBM_DRCONNECTOR:
704 			label_string = "DR connector:";
705 			value_arrsize = sizeof(ibm_drconnector)/sizeof(char *);
706 			value_arr = ibm_drconnector;
707 			break;
708 		case IBM_POWERSUPPLY:
709 			label_string = "Powersupply:";
710 			break;
711 		case IBM_INTQUEUE:
712 			label_string = "Interrupt queue:";
713 			value_arrsize = sizeof(ibm_intqueue)/sizeof(char *);
714 			value_arr = ibm_intqueue;
715 			break;
716 		default:
717 			n += sprintf(buf+n,  "Unkown sensor (type %d), ignoring it\n",
718 					s.token);
719 			unknown = 1;
720 			break;
721 	}
722 
723 	if (label_string)
724 		n += sprintf(buf+n, "%-17s\t", label_string);
725 
726 	if (value_arr && state >= 0 && state < value_arrsize) {
727 		n += sprintf(buf+n, "%-15s\t", value_arr[state]);
728 	} else {
729 		if (temperature) {
730 			n += sprintf(buf+n, "%2d / %2d  \t", state, cel_to_fahr(state));
731 		} else
732 			n += sprintf(buf+n, "%-10d\t", state);
733 	}
734 	if (unknown == 0) {
735 		n += sprintf ( buf+n, "%-15s\t", ppc_rtas_process_error(error));
736 		n += get_location_code(s, buf+n);
737 	}
738 	return n;
739 }
740 
741 /* ****************************************************************** */
742 
check_location(char * c,int idx,char * buf)743 int check_location (char *c, int idx, char * buf)
744 {
745 	int n = 0;
746 
747 	switch (*(c+idx)) {
748 		case LOC_PLANAR:
749 			n += sprintf ( buf, "Planar #%c", *(c+idx+1));
750 			break;
751 		case LOC_CPU:
752 			n += sprintf ( buf, "CPU #%c", *(c+idx+1));
753 			break;
754 		case LOC_FAN:
755 			n += sprintf ( buf, "Fan #%c", *(c+idx+1));
756 			break;
757 		case LOC_RACKMOUNTED:
758 			n += sprintf ( buf, "Rack #%c", *(c+idx+1));
759 			break;
760 		case LOC_VOLTAGE:
761 			n += sprintf ( buf, "Voltage #%c", *(c+idx+1));
762 			break;
763 		case LOC_LCD:
764 			n += sprintf ( buf, "LCD #%c", *(c+idx+1));
765 			break;
766 		case '.':
767 			n += sprintf ( buf, "- %c", *(c+idx+1));
768 		default:
769 			n += sprintf ( buf, "Unknown location");
770 			break;
771 	}
772 	return n;
773 }
774 
775 
776 /* ****************************************************************** */
777 /*
778  * Format:
779  * ${LETTER}${NUMBER}[[-/]${LETTER}${NUMBER} [ ... ] ]
780  * the '.' may be an abbrevation
781  */
check_location_string(char * c,char * buf)782 int check_location_string (char *c, char *buf)
783 {
784 	int n=0,i=0;
785 
786 	while (c[i]) {
787 		if (isalpha(c[i]) || c[i] == '.') {
788 			 n += check_location(c, i, buf+n);
789 		}
790 		else if (c[i] == '/' || c[i] == '-')
791 			n += sprintf(buf+n, " at ");
792 		i++;
793 	}
794 	return n;
795 }
796 
797 
798 /* ****************************************************************** */
799 
get_location_code(struct individual_sensor s,char * buffer)800 int get_location_code(struct individual_sensor s, char * buffer)
801 {
802 	char rstr[512], tmp[10], tmp2[10];
803 	int n=0, i=0, llen, len;
804 	/* char *buf = kmalloc(MAX_LINELENGTH, GFP_KERNEL); */
805 	char *ret;
806 
807 	static int pos = 0; /* remember position where buffer was */
808 
809 	/* construct the sensor number like 0003 */
810 	/* fill with zeros */
811 	n = sprintf(tmp, "%d", s.token);
812 	len = strlen(tmp);
813 	while (strlen(tmp) < 4)
814 		n += sprintf (tmp+n, "0");
815 
816 	/* invert the string */
817 	while (tmp[i]) {
818 		if (i<len)
819 			tmp2[4-len+i] = tmp[i];
820 		else
821 			tmp2[3-i] = tmp[i];
822 		i++;
823 	}
824 	tmp2[4] = '\0';
825 
826 	sprintf (rstr, SENSOR_PREFIX"%s", tmp2);
827 
828 	ret = (char *) get_property(rtas_node, rstr, &llen);
829 
830 	n=0;
831 	if (ret == NULL || ret[0] == '\0') {
832 		n += sprintf ( buffer+n, "--- ");/* does not have a location */
833 	} else {
834 		char t[50];
835 		ret += pos;
836 
837 		n += check_location_string(ret, buffer + n);
838 		n += sprintf ( buffer+n, " ");
839 		/* see how many characters we have printed */
840 		snprintf( t, 50, "%s ", ret);
841 
842 		pos += strlen(t);
843 		if (pos >= llen) pos=0;
844 	}
845 	return n;
846 }
847 /* ****************************************************************** */
848 /* INDICATORS - Tone Frequency                                        */
849 /* ****************************************************************** */
ppc_rtas_tone_freq_write(struct file * file,const char * buf,size_t count,loff_t * ppos)850 static ssize_t ppc_rtas_tone_freq_write(struct file * file, const char * buf,
851 		size_t count, loff_t *ppos)
852 {
853 	char stkbuf[40];  /* its small, its on stack */
854 	unsigned long freq;
855 	char *dest;
856 	int error;
857 
858 	if (39 < count)
859 		count = 39;
860 	if (copy_from_user(stkbuf, buf, count))
861 		return -EFAULT;
862 
863 	stkbuf[count] = 0;
864 	freq = simple_strtoul(stkbuf, &dest, 10);
865 	if (*dest != '\0' && *dest != '\n') {
866 		printk("ppc_rtas_tone_freq_write: Invalid tone freqency\n");
867 		return count;
868 	}
869 	if (freq < 0) freq = 0;
870 	rtas_tone_frequency = freq; /* save it for later */
871 	error = rtas_call(set_indicator, 3, 1, NULL,
872 			TONE_FREQUENCY, 0, freq);
873 	if (error != 0)
874 		printk(KERN_WARNING "error: setting tone frequency returned: %s\n",
875 				ppc_rtas_process_error(error));
876 	return count;
877 }
878 /* ****************************************************************** */
ppc_rtas_tone_freq_read(struct file * file,char * buf,size_t count,loff_t * ppos)879 static ssize_t ppc_rtas_tone_freq_read(struct file * file, char * buf,
880 		size_t count, loff_t *ppos)
881 {
882 	int n, sn;
883 	char stkbuf[40];  /* its small, its on stack */
884 	loff_t pos = *ppos;
885 
886 	n = snprintf(stkbuf, 40, "%lu\n", rtas_tone_frequency);
887 
888 	sn = strlen(stkbuf) +1;
889 	if (pos != (unsigned)pos || pos >= sn)
890 		return 0;
891 	if (n > sn - pos)
892 		n = sn - pos;
893 	if (n > count)
894 		n = count;
895 	if (copy_to_user(buf, stkbuf + pos, n))
896 		return -EFAULT;
897 
898 	*ppos = pos + n;
899 	return n;
900 }
901 /* ****************************************************************** */
902 /* INDICATORS - Tone Volume                                           */
903 /* ****************************************************************** */
ppc_rtas_tone_volume_write(struct file * file,const char * buf,size_t count,loff_t * ppos)904 static ssize_t ppc_rtas_tone_volume_write(struct file * file, const char * buf,
905 		size_t count, loff_t *ppos)
906 {
907 	char stkbuf[40];  /* its small, its on stack */
908 	unsigned long volume;
909 	char *dest;
910 	int error;
911 
912 	if (39 < count)
913 		count = 39;
914 	if (copy_from_user(stkbuf, buf, count))
915 		return -EFAULT;
916 
917 	stkbuf[count] = 0;
918 	volume = simple_strtoul(stkbuf, &dest, 10);
919 	if (*dest != '\0' && *dest != '\n') {
920 		printk("ppc_rtas_tone_volume_write: Invalid tone volume\n");
921 		return count;
922 	}
923 	if (volume < 0) volume = 0;
924 	if (volume > 100) volume = 100;
925 
926         rtas_tone_volume = volume; /* save it for later */
927 	error = rtas_call(set_indicator, 3, 1, NULL,
928 			TONE_VOLUME, 0, volume);
929 	if (error != 0)
930 		printk(KERN_WARNING "error: setting tone volume returned: %s\n",
931 				ppc_rtas_process_error(error));
932 	return count;
933 }
934 /* ****************************************************************** */
ppc_rtas_tone_volume_read(struct file * file,char * buf,size_t count,loff_t * ppos)935 static ssize_t ppc_rtas_tone_volume_read(struct file * file, char * buf,
936 		size_t count, loff_t *ppos)
937 {
938 	int n, sn;
939 	char stkbuf[40];  /* its small, its on stack */
940 	loff_t pos = *ppos;
941 
942 	n = snprintf(stkbuf, 40, "%lu\n", rtas_tone_volume);
943 	sn = strlen(stkbuf) +1;
944 	if (pos != (unsigned)pos || pos >= sn)
945 		return 0;
946 	if (n > sn - pos)
947 		n = sn - pos;
948 	if (n > count)
949 		n = count;
950 	if (copy_to_user(buf, stkbuf + pos, n))
951 		return -EFAULT;
952 
953 	*ppos = pos + n;
954 	return n;
955 }
956 
957 /* ****************************************************************** */
958 /* ERRINJCT			                                      */
959 /* ****************************************************************** */
ppc_rtas_errinjct_open(struct inode * inode,struct file * file)960 static int ppc_rtas_errinjct_open(struct inode *inode, struct file *file)
961 {
962 	int rc;
963 
964 	/* We will only allow one process to use error inject at a
965 	   time.  Since errinjct is usually only used for testing,
966 	   this shouldn't be an issue */
967 	if (open_token) {
968 		return -EAGAIN;
969 	}
970 	rc = rtas_errinjct_open();
971 	if (rc < 0) {
972 		return -EIO;
973 	}
974 	open_token = rc;
975 
976 	return 0;
977 }
978 
ppc_rtas_errinjct_write(struct file * file,const char * buf,size_t count,loff_t * ppos)979 static ssize_t ppc_rtas_errinjct_write(struct file * file, const char * buf,
980 				       size_t count, loff_t *ppos)
981 {
982  	char * tmpbuf;
983 	char * ei_token;
984 	char * workspace = NULL;
985 	size_t max_len;
986 	int token_len;
987 	int rc;
988 
989 	/* Verify the errinjct token length */
990 	if (count < ERRINJCT_TOKEN_LEN) {
991 		max_len = count;
992 	} else {
993 		max_len = ERRINJCT_TOKEN_LEN;
994 	}
995 
996 	tmpbuf = (char *) kmalloc(max_len, GFP_KERNEL);
997 	if (!tmpbuf) {
998 		printk(KERN_WARNING "error: kmalloc failed\n");
999 		return -ENOMEM;
1000 	}
1001 	if (copy_from_user (tmpbuf, buf, max_len)) {
1002 		kfree(tmpbuf);
1003 		return -EFAULT;
1004 	}
1005 	token_len = strnlen(tmpbuf, max_len);
1006 	token_len++; /* Add one for the null termination */
1007 
1008 	ei_token = (char *)kmalloc(token_len, GFP_KERNEL);
1009 	if (!ei_token) {
1010 		printk(KERN_WARNING "error: kmalloc failed\n");
1011 		kfree(tmpbuf);
1012 		return -ENOMEM;
1013 	}
1014 
1015 	strncpy(ei_token, tmpbuf, token_len);
1016 
1017 	if (count > token_len + WORKSPACE_SIZE) {
1018 		count = token_len + WORKSPACE_SIZE;
1019 	}
1020 
1021 	buf += token_len;
1022 
1023 	/* check if there is a workspace */
1024 	if (count > token_len) {
1025 		/* Verify the workspace size */
1026 		if ((count - token_len) > WORKSPACE_SIZE) {
1027 			max_len = WORKSPACE_SIZE;
1028 		} else {
1029 			max_len = count - token_len;
1030 		}
1031 
1032 		workspace = (char *)kmalloc(max_len, GFP_KERNEL);
1033 		if (!workspace) {
1034 			printk(KERN_WARNING "error: failed kmalloc\n");
1035 			kfree(tmpbuf);
1036 			kfree(ei_token);
1037 			return -ENOMEM;
1038 		}
1039 
1040 		memcpy(workspace, tmpbuf, max_len);
1041 	}
1042 
1043 	rc = rtas_errinjct(open_token, ei_token, workspace);
1044 
1045 	if (count > token_len) {
1046 		kfree(workspace);
1047 	}
1048 	kfree(ei_token);
1049 	kfree(tmpbuf);
1050 
1051 	return rc < 0 ? rc : count;
1052 }
1053 
ppc_rtas_errinjct_release(struct inode * inode,struct file * file)1054 static int ppc_rtas_errinjct_release(struct inode *inode, struct file *file)
1055 {
1056 	int rc;
1057 
1058 	rc = rtas_errinjct_close(open_token);
1059 	if (rc) {
1060 		return rc;
1061 	}
1062 	open_token = 0;
1063 	return 0;
1064 }
1065 
ppc_rtas_errinjct_read(struct file * file,char * buf,size_t count,loff_t * ppos)1066 static ssize_t ppc_rtas_errinjct_read(struct file *file, char *buf,
1067 				      size_t count, loff_t *ppos)
1068 {
1069 	char * buffer;
1070 	int i, sn;
1071 	int n = 0;
1072 	loff_t pos = *ppos;
1073 
1074 	int m = MAX_ERRINJCT_TOKENS * (ERRINJCT_TOKEN_LEN+1);
1075 	buffer = (char *)kmalloc(m, GFP_KERNEL);
1076 	if (!buffer) {
1077 		printk(KERN_ERR "error: kmalloc failed\n");
1078 		return -ENOMEM;
1079 	}
1080 
1081 	for (i = 0; i < MAX_ERRINJCT_TOKENS && ei_token_list[i].value; i++) {
1082 		n += snprintf(buffer+n, m-n, ei_token_list[i].name);
1083 		n += snprintf(buffer+n, m-n, "\n");
1084 	}
1085 
1086 	sn = strlen(buffer) +1;
1087 	if (pos != (unsigned)pos || pos >= sn) {
1088 		kfree(buffer);
1089 		return 0;
1090 	}
1091 	if (n > sn - pos)
1092 		n = sn - pos;
1093 
1094 	if (n > count)
1095 		n = count;
1096 
1097 	if (copy_to_user(buf, buffer + pos, n)) {
1098 		kfree(buffer);
1099 		return -EFAULT;
1100 	}
1101 
1102 	*ppos = pos + n;
1103 
1104 	kfree(buffer);
1105 	return n;
1106 }
1107