2 * arch/ppc64/kernel/rtas-proc.c
3 * Copyright (C) 2000 Tilmann Bitterberg
4 * (tilmann@bitterberg.de)
6 * RTAS (Runtime Abstraction Services) stuff
7 * Intention is to provide a clean user interface
11 * Split off a header file and maybe move it to a different
12 * location. Write Documentation on what the /proc/rtas/ entries
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 #include <linux/init.h>
25 #include <asm/uaccess.h>
26 #include <asm/bitops.h>
27 #include <asm/processor.h>
31 #include <asm/machdep.h> /* for ppc_md */
34 /* Token for Sensors */
35 #define KEY_SWITCH 0x0001
36 #define ENCLOSURE_SWITCH 0x0002
37 #define THERMAL_SENSOR 0x0003
38 #define LID_STATUS 0x0004
39 #define POWER_SOURCE 0x0005
40 #define BATTERY_VOLTAGE 0x0006
41 #define BATTERY_REMAINING 0x0007
42 #define BATTERY_PERCENTAGE 0x0008
43 #define EPOW_SENSOR 0x0009
44 #define BATTERY_CYCLESTATE 0x000a
45 #define BATTERY_CHARGING 0x000b
47 /* IBM specific sensors */
48 #define IBM_SURVEILLANCE 0x2328 /* 9000 */
49 #define IBM_FANRPM 0x2329 /* 9001 */
50 #define IBM_VOLTAGE 0x232a /* 9002 */
51 #define IBM_DRCONNECTOR 0x232b /* 9003 */
52 #define IBM_POWERSUPPLY 0x232c /* 9004 */
53 #define IBM_INTQUEUE 0x232d /* 9005 */
55 /* Status return values */
56 #define SENSOR_CRITICAL_HIGH 13
57 #define SENSOR_WARNING_HIGH 12
58 #define SENSOR_NORMAL 11
59 #define SENSOR_WARNING_LOW 10
60 #define SENSOR_CRITICAL_LOW 9
61 #define SENSOR_SUCCESS 0
62 #define SENSOR_HW_ERROR -1
63 #define SENSOR_BUSY -2
64 #define SENSOR_NOT_EXIST -3
65 #define SENSOR_DR_ENTITY -9000
68 #define LOC_SCSI_DEV_ADDR 'A'
69 #define LOC_SCSI_DEV_LOC 'B'
71 #define LOC_DISKETTE 'D'
72 #define LOC_ETHERNET 'E'
74 #define LOC_GRAPHICS 'G'
75 /* reserved / not used 'H' */
76 #define LOC_IO_ADAPTER 'I'
77 /* reserved / not used 'J' */
78 #define LOC_KEYBOARD 'K'
80 #define LOC_MEMORY 'M'
81 #define LOC_NV_MEMORY 'N'
83 #define LOC_PLANAR 'P'
84 #define LOC_OTHER_IO 'Q'
85 #define LOC_PARALLEL 'R'
86 #define LOC_SERIAL 'S'
87 #define LOC_DEAD_RING 'T'
88 #define LOC_RACKMOUNTED 'U' /* for _u_nit is rack mounted */
89 #define LOC_VOLTAGE 'V'
90 #define LOC_SWITCH_ADAPTER 'W'
92 #define LOC_FIRMWARE 'Y'
95 /* Tokens for indicators */
96 #define TONE_FREQUENCY 0x0001 /* 0 - 1000 (HZ)*/
97 #define TONE_VOLUME 0x0002 /* 0 - 100 (%) */
98 #define SYSTEM_POWER_STATE 0x0003
99 #define WARNING_LIGHT 0x0004
100 #define DISK_ACTIVITY_LIGHT 0x0005
101 #define HEX_DISPLAY_UNIT 0x0006
102 #define BATTERY_WARNING_TIME 0x0007
103 #define CONDITION_CYCLE_REQUEST 0x0008
104 #define SURVEILLANCE_INDICATOR 0x2328 /* 9000 */
105 #define DR_ACTION 0x2329 /* 9001 */
106 #define DR_INDICATOR 0x232a /* 9002 */
107 /* 9003 - 9004: Vendor specific */
108 #define GLOBAL_INTERRUPT_QUEUE 0x232d /* 9005 */
109 /* 9006 - 9999: Vendor specific */
112 #define MAX_SENSORS 17 /* I only know of 17 sensors */
113 #define MAX_LINELENGTH 256
114 #define SENSOR_PREFIX "ibm,sensor-"
115 #define cel_to_fahr(x) ((x*9/5)+32)
119 static struct rtas_sensors sensors;
120 static struct device_node *rtas_node = NULL;
121 static unsigned long power_on_time = 0; /* Save the time the user set */
122 static char progress_led[MAX_LINELENGTH];
124 static unsigned long rtas_tone_frequency = 1000;
125 static unsigned long rtas_tone_volume = 0;
127 /* ****************STRUCTS******************************************* */
128 struct individual_sensor {
133 struct rtas_sensors {
134 struct individual_sensor sensor[MAX_SENSORS];
138 /* ****************************************************************** */
140 static int ppc_rtas_sensor_read(char * buf, char ** start, off_t off,
141 int count, int *eof, void *data);
142 static ssize_t ppc_rtas_clock_read(struct file * file, char * buf,
143 size_t count, loff_t *ppos);
144 static ssize_t ppc_rtas_clock_write(struct file * file, const char * buf,
145 size_t count, loff_t *ppos);
146 static ssize_t ppc_rtas_progress_read(struct file * file, char * buf,
147 size_t count, loff_t *ppos);
148 static ssize_t ppc_rtas_progress_write(struct file * file, const char * buf,
149 size_t count, loff_t *ppos);
150 static ssize_t ppc_rtas_poweron_read(struct file * file, char * buf,
151 size_t count, loff_t *ppos);
152 static ssize_t ppc_rtas_poweron_write(struct file * file, const char * buf,
153 size_t count, loff_t *ppos);
155 static ssize_t ppc_rtas_tone_freq_write(struct file * file, const char * buf,
156 size_t count, loff_t *ppos);
157 static ssize_t ppc_rtas_tone_freq_read(struct file * file, char * buf,
158 size_t count, loff_t *ppos);
159 static ssize_t ppc_rtas_tone_volume_write(struct file * file, const char * buf,
160 size_t count, loff_t *ppos);
161 static ssize_t ppc_rtas_tone_volume_read(struct file * file, char * buf,
162 size_t count, loff_t *ppos);
163 static ssize_t ppc_rtas_rmo_buf_read(struct file *file, char *buf,
164 size_t count, loff_t *ppos);
166 struct file_operations ppc_rtas_poweron_operations = {
167 .read = ppc_rtas_poweron_read,
168 .write = ppc_rtas_poweron_write
170 struct file_operations ppc_rtas_progress_operations = {
171 .read = ppc_rtas_progress_read,
172 .write = ppc_rtas_progress_write
175 struct file_operations ppc_rtas_clock_operations = {
176 .read = ppc_rtas_clock_read,
177 .write = ppc_rtas_clock_write
180 struct file_operations ppc_rtas_tone_freq_operations = {
181 .read = ppc_rtas_tone_freq_read,
182 .write = ppc_rtas_tone_freq_write
184 struct file_operations ppc_rtas_tone_volume_operations = {
185 .read = ppc_rtas_tone_volume_read,
186 .write = ppc_rtas_tone_volume_write
189 static struct file_operations ppc_rtas_rmo_buf_ops = {
190 .read = ppc_rtas_rmo_buf_read,
193 int ppc_rtas_find_all_sensors (void);
194 int ppc_rtas_process_sensor(struct individual_sensor s, int state,
195 int error, char * buf);
196 char * ppc_rtas_process_error(int error);
197 int get_location_code(struct individual_sensor s, char * buf);
198 int check_location_string (char *c, char * buf);
199 int check_location (char *c, int idx, char * buf);
201 static int __init proc_rtas_init(void)
203 struct proc_dir_entry *entry;
205 if (!(systemcfg->platform & PLATFORM_PSERIES))
208 rtas_node = of_find_node_by_name(NULL, "rtas");
209 if (rtas_node == NULL)
212 entry = create_proc_entry("ppc64/rtas/progress", S_IRUGO|S_IWUSR, NULL);
214 entry->proc_fops = &ppc_rtas_progress_operations;
216 entry = create_proc_entry("ppc64/rtas/clock", S_IRUGO|S_IWUSR, NULL);
218 entry->proc_fops = &ppc_rtas_clock_operations;
220 entry = create_proc_entry("ppc64/rtas/poweron", S_IWUSR|S_IRUGO, NULL);
222 entry->proc_fops = &ppc_rtas_poweron_operations;
224 create_proc_read_entry("ppc64/rtas/sensors", S_IRUGO, NULL,
225 ppc_rtas_sensor_read, NULL);
227 entry = create_proc_entry("ppc64/rtas/frequency", S_IWUSR|S_IRUGO,
230 entry->proc_fops = &ppc_rtas_tone_freq_operations;
232 entry = create_proc_entry("ppc64/rtas/volume", S_IWUSR|S_IRUGO, NULL);
234 entry->proc_fops = &ppc_rtas_tone_volume_operations;
236 entry = create_proc_entry("ppc64/rtas/rmo_buffer", S_IRUSR, NULL);
238 entry->proc_fops = &ppc_rtas_rmo_buf_ops;
243 __initcall(proc_rtas_init);
245 /* ****************************************************************** */
247 /* ****************************************************************** */
248 static ssize_t ppc_rtas_poweron_write(struct file * file, const char * buf,
249 size_t count, loff_t *ppos)
251 char stkbuf[40]; /* its small, its on stack */
253 unsigned long nowtime;
257 if (39 < count) count = 39;
258 if (copy_from_user (stkbuf, buf, count)) {
262 nowtime = simple_strtoul(stkbuf, &dest, 10);
263 if (*dest != '\0' && *dest != '\n') {
264 printk("ppc_rtas_poweron_write: Invalid time\n");
267 power_on_time = nowtime; /* save the time */
271 error = rtas_call(rtas_token("set-time-for-power-on"), 7, 1, NULL,
272 tm.tm_year, tm.tm_mon, tm.tm_mday,
273 tm.tm_hour, tm.tm_min, tm.tm_sec, 0 /* nano */);
275 printk(KERN_WARNING "error: setting poweron time returned: %s\n",
276 ppc_rtas_process_error(error));
279 /* ****************************************************************** */
280 static ssize_t ppc_rtas_poweron_read(struct file * file, char * buf,
281 size_t count, loff_t *ppos)
283 char stkbuf[40]; /* its small, its on stack */
285 if (power_on_time == 0)
286 n = scnprintf(stkbuf,sizeof(stkbuf),"Power on time not set\n");
288 n = scnprintf(stkbuf,sizeof(stkbuf),"%lu\n",power_on_time);
290 sn = strlen (stkbuf) +1;
297 if (copy_to_user (buf, stkbuf + (*ppos), n)) {
304 /* ****************************************************************** */
306 /* ****************************************************************** */
307 static ssize_t ppc_rtas_progress_write(struct file * file, const char * buf,
308 size_t count, loff_t *ppos)
312 if (count >= MAX_LINELENGTH) count = MAX_LINELENGTH -1;
313 if (copy_from_user (progress_led, buf, count)) { /* save the string */
316 progress_led[count] = 0;
318 /* Lets see if the user passed hexdigits */
319 hex = simple_strtoul(progress_led, NULL, 10);
321 ppc_md.progress ((char *)progress_led, hex);
324 /* clear the line */ /* ppc_md.progress(" ", 0xffff);*/
326 /* ****************************************************************** */
327 static ssize_t ppc_rtas_progress_read(struct file * file, char * buf,
328 size_t count, loff_t *ppos)
333 if (progress_led == NULL) return 0;
335 tmpbuf = kmalloc (MAX_LINELENGTH, GFP_KERNEL);
337 printk(KERN_ERR "error: kmalloc failed\n");
340 n = sprintf (tmpbuf, "%s\n", progress_led);
342 sn = strlen (tmpbuf) +1;
351 if (copy_to_user (buf, tmpbuf + (*ppos), n)) {
360 /* ****************************************************************** */
362 /* ****************************************************************** */
363 static ssize_t ppc_rtas_clock_write(struct file * file, const char * buf,
364 size_t count, loff_t *ppos)
366 char stkbuf[40]; /* its small, its on stack */
368 unsigned long nowtime;
372 if (39 < count) count = 39;
373 if (copy_from_user (stkbuf, buf, count)) {
377 nowtime = simple_strtoul(stkbuf, &dest, 10);
378 if (*dest != '\0' && *dest != '\n') {
379 printk("ppc_rtas_clock_write: Invalid time\n");
384 error = rtas_call(rtas_token("set-time-of-day"), 7, 1, NULL,
385 tm.tm_year, tm.tm_mon, tm.tm_mday,
386 tm.tm_hour, tm.tm_min, tm.tm_sec, 0);
388 printk(KERN_WARNING "error: setting the clock returned: %s\n",
389 ppc_rtas_process_error(error));
392 /* ****************************************************************** */
393 static ssize_t ppc_rtas_clock_read(struct file * file, char * buf,
394 size_t count, loff_t *ppos)
396 unsigned int year, mon, day, hour, min, sec;
397 unsigned long *ret = kmalloc(4*8, GFP_KERNEL);
399 char stkbuf[40]; /* its small, its on stack */
401 error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret);
403 year = ret[0]; mon = ret[1]; day = ret[2];
404 hour = ret[3]; min = ret[4]; sec = ret[5];
407 printk(KERN_WARNING "error: reading the clock returned: %s\n",
408 ppc_rtas_process_error(error));
409 n = scnprintf (stkbuf, sizeof(stkbuf), "0");
411 n = scnprintf (stkbuf, sizeof(stkbuf), "%lu\n",
412 mktime(year, mon, day, hour, min, sec));
416 sn = strlen (stkbuf) +1;
423 if (copy_to_user (buf, stkbuf + (*ppos), n)) {
430 /* ****************************************************************** */
432 /* ****************************************************************** */
433 static int ppc_rtas_sensor_read(char * buf, char ** start, off_t off,
434 int count, int *eof, void *data)
440 int get_sensor_state = rtas_token("get-sensor-state");
445 /* May not be enough */
446 buffer = kmalloc(MAX_LINELENGTH*MAX_SENSORS, GFP_KERNEL);
451 memset(buffer, 0, MAX_LINELENGTH*MAX_SENSORS);
453 n = sprintf ( buffer , "RTAS (RunTime Abstraction Services) Sensor Information\n");
454 n += sprintf ( buffer+n, "Sensor\t\tValue\t\tCondition\tLocation\n");
455 n += sprintf ( buffer+n, "********************************************************\n");
457 if (ppc_rtas_find_all_sensors() != 0) {
458 n += sprintf ( buffer+n, "\nNo sensors are available\n");
462 for (i=0; i<sensors.quant; i++) {
463 j = sensors.sensor[i].quant;
464 /* A sensor may have multiple instances */
467 error = rtas_call(get_sensor_state, 2, 2, &ret,
468 sensors.sensor[i].token,
469 sensors.sensor[i].quant - j);
472 n += ppc_rtas_process_sensor(sensors.sensor[i], state,
474 n += sprintf (buffer+n, "\n");
480 if (off >= strlen(buffer)) {
485 if (n > strlen(buffer) - off)
486 n = strlen(buffer) - off;
492 memcpy(buf, buffer + off, n);
498 /* ****************************************************************** */
500 int ppc_rtas_find_all_sensors (void)
505 utmp = (unsigned int *) get_property(rtas_node, "rtas-sensors", &len);
507 printk (KERN_ERR "error: could not get rtas-sensors\n");
511 sensors.quant = len / 8; /* int + int */
513 for (i=0; i<sensors.quant; i++) {
514 sensors.sensor[i].token = *utmp++;
515 sensors.sensor[i].quant = *utmp++;
520 /* ****************************************************************** */
522 * Builds a string of what rtas returned
524 char * ppc_rtas_process_error(int error)
527 case SENSOR_CRITICAL_HIGH:
528 return "(critical high)";
529 case SENSOR_WARNING_HIGH:
530 return "(warning high)";
533 case SENSOR_WARNING_LOW:
534 return "(warning low)";
535 case SENSOR_CRITICAL_LOW:
536 return "(critical low)";
539 case SENSOR_HW_ERROR:
540 return "(hardware error)";
543 case SENSOR_NOT_EXIST:
544 return "(non existant)";
545 case SENSOR_DR_ENTITY:
546 return "(dr entity removed)";
552 /* ****************************************************************** */
554 * Builds a string out of what the sensor said
557 int ppc_rtas_process_sensor(struct individual_sensor s, int state,
558 int error, char * buf)
560 /* Defined return vales */
561 const char * key_switch[] = { "Off\t", "Normal\t", "Secure\t",
563 const char * enclosure_switch[] = { "Closed", "Open" };
564 const char * lid_status[] = { " ", "Open", "Closed" };
565 const char * power_source[] = { "AC\t", "Battery",
567 const char * battery_remaining[] = { "Very Low", "Low", "Mid", "High" };
568 const char * epow_sensor[] = {
569 "EPOW Reset", "Cooling warning", "Power warning",
570 "System shutdown", "System halt", "EPOW main enclosure",
572 const char * battery_cyclestate[] = { "None", "In progress",
574 const char * battery_charging[] = { "Charging", "Discharching",
576 const char * ibm_drconnector[] = { "Empty", "Present", "Unusable",
578 const char * ibm_intqueue[] = { "Disabled", "Enabled" };
580 int have_strings = 0;
586 /* What kind of sensor do we have here? */
590 n += sprintf(buf+n, "Key switch:\t");
591 num_states = sizeof(key_switch) / sizeof(char *);
592 if (state < num_states) {
593 n += sprintf(buf+n, "%s\t", key_switch[state]);
597 case ENCLOSURE_SWITCH:
598 n += sprintf(buf+n, "Enclosure switch:\t");
599 num_states = sizeof(enclosure_switch) / sizeof(char *);
600 if (state < num_states) {
601 n += sprintf(buf+n, "%s\t",
602 enclosure_switch[state]);
607 n += sprintf(buf+n, "Temp. (°C/°F):\t");
611 n += sprintf(buf+n, "Lid status:\t");
612 num_states = sizeof(lid_status) / sizeof(char *);
613 if (state < num_states) {
614 n += sprintf(buf+n, "%s\t", lid_status[state]);
619 n += sprintf(buf+n, "Power source:\t");
620 num_states = sizeof(power_source) / sizeof(char *);
621 if (state < num_states) {
622 n += sprintf(buf+n, "%s\t",
623 power_source[state]);
627 case BATTERY_VOLTAGE:
628 n += sprintf(buf+n, "Battery voltage:\t");
630 case BATTERY_REMAINING:
631 n += sprintf(buf+n, "Battery remaining:\t");
632 num_states = sizeof(battery_remaining) / sizeof(char *);
633 if (state < num_states)
635 n += sprintf(buf+n, "%s\t",
636 battery_remaining[state]);
640 case BATTERY_PERCENTAGE:
641 n += sprintf(buf+n, "Battery percentage:\t");
644 n += sprintf(buf+n, "EPOW Sensor:\t");
645 num_states = sizeof(epow_sensor) / sizeof(char *);
646 if (state < num_states) {
647 n += sprintf(buf+n, "%s\t", epow_sensor[state]);
651 case BATTERY_CYCLESTATE:
652 n += sprintf(buf+n, "Battery cyclestate:\t");
653 num_states = sizeof(battery_cyclestate) /
655 if (state < num_states) {
656 n += sprintf(buf+n, "%s\t",
657 battery_cyclestate[state]);
661 case BATTERY_CHARGING:
662 n += sprintf(buf+n, "Battery Charging:\t");
663 num_states = sizeof(battery_charging) / sizeof(char *);
664 if (state < num_states) {
665 n += sprintf(buf+n, "%s\t",
666 battery_charging[state]);
670 case IBM_SURVEILLANCE:
671 n += sprintf(buf+n, "Surveillance:\t");
674 n += sprintf(buf+n, "Fan (rpm):\t");
677 n += sprintf(buf+n, "Voltage (mv):\t");
679 case IBM_DRCONNECTOR:
680 n += sprintf(buf+n, "DR connector:\t");
681 num_states = sizeof(ibm_drconnector) / sizeof(char *);
682 if (state < num_states) {
683 n += sprintf(buf+n, "%s\t",
684 ibm_drconnector[state]);
688 case IBM_POWERSUPPLY:
689 n += sprintf(buf+n, "Powersupply:\t");
692 n += sprintf(buf+n, "Interrupt queue:\t");
693 num_states = sizeof(ibm_intqueue) / sizeof(char *);
694 if (state < num_states) {
695 n += sprintf(buf+n, "%s\t",
696 ibm_intqueue[state]);
701 n += sprintf(buf+n, "Unkown sensor (type %d), ignoring it\n",
707 if (have_strings == 0) {
709 n += sprintf(buf+n, "%4d /%4d\t", state, cel_to_fahr(state));
711 n += sprintf(buf+n, "%10d\t", state);
714 n += sprintf ( buf+n, "%s\t", ppc_rtas_process_error(error));
715 n += get_location_code(s, buf+n);
720 /* ****************************************************************** */
722 int check_location (char *c, int idx, char * buf)
728 n += sprintf ( buf, "Planar #%c", *(c+idx+1));
731 n += sprintf ( buf, "CPU #%c", *(c+idx+1));
734 n += sprintf ( buf, "Fan #%c", *(c+idx+1));
736 case LOC_RACKMOUNTED:
737 n += sprintf ( buf, "Rack #%c", *(c+idx+1));
740 n += sprintf ( buf, "Voltage #%c", *(c+idx+1));
743 n += sprintf ( buf, "LCD #%c", *(c+idx+1));
746 n += sprintf ( buf, "- %c", *(c+idx+1));
748 n += sprintf ( buf, "Unknown location");
755 /* ****************************************************************** */
758 * ${LETTER}${NUMBER}[[-/]${LETTER}${NUMBER} [ ... ] ]
759 * the '.' may be an abbrevation
761 int check_location_string (char *c, char *buf)
766 if (isalpha(c[i]) || c[i] == '.') {
767 n += check_location(c, i, buf+n);
769 else if (c[i] == '/' || c[i] == '-')
770 n += sprintf(buf+n, " at ");
777 /* ****************************************************************** */
779 int get_location_code(struct individual_sensor s, char * buffer)
781 char rstr[512], tmp[10], tmp2[10];
782 int n=0, i=0, llen, len;
783 /* char *buf = kmalloc(MAX_LINELENGTH, GFP_KERNEL); */
786 static int pos = 0; /* remember position where buffer was */
788 /* construct the sensor number like 0003 */
789 /* fill with zeros */
790 n = sprintf(tmp, "%d", s.token);
792 while (strlen(tmp) < 4)
793 n += sprintf (tmp+n, "0");
795 /* invert the string */
798 tmp2[4-len+i] = tmp[i];
805 sprintf (rstr, SENSOR_PREFIX"%s", tmp2);
807 ret = (char *) get_property(rtas_node, rstr, &llen);
810 if (ret == NULL || ret[0] == '\0') {
811 n += sprintf ( buffer+n, "--- ");/* does not have a location */
816 n += check_location_string(ret, buffer + n);
817 n += sprintf ( buffer+n, " ");
818 /* see how many characters we have printed */
819 scnprintf(t, sizeof(t), "%s ", ret);
822 if (pos >= llen) pos=0;
826 /* ****************************************************************** */
827 /* INDICATORS - Tone Frequency */
828 /* ****************************************************************** */
829 static ssize_t ppc_rtas_tone_freq_write(struct file * file, const char * buf,
830 size_t count, loff_t *ppos)
832 char stkbuf[40]; /* its small, its on stack */
837 if (39 < count) count = 39;
838 if (copy_from_user (stkbuf, buf, count)) {
842 freq = simple_strtoul(stkbuf, &dest, 10);
843 if (*dest != '\0' && *dest != '\n') {
844 printk("ppc_rtas_tone_freq_write: Invalid tone freqency\n");
847 if (freq < 0) freq = 0;
848 rtas_tone_frequency = freq; /* save it for later */
849 error = rtas_call(rtas_token("set-indicator"), 3, 1, NULL,
850 TONE_FREQUENCY, 0, freq);
852 printk(KERN_WARNING "error: setting tone frequency returned: %s\n",
853 ppc_rtas_process_error(error));
856 /* ****************************************************************** */
857 static ssize_t ppc_rtas_tone_freq_read(struct file * file, char * buf,
858 size_t count, loff_t *ppos)
861 char stkbuf[40]; /* its small, its on stack */
863 n = scnprintf(stkbuf, 40, "%lu\n", rtas_tone_frequency);
865 sn = strlen (stkbuf) +1;
872 if (copy_to_user (buf, stkbuf + (*ppos), n)) {
878 /* ****************************************************************** */
879 /* INDICATORS - Tone Volume */
880 /* ****************************************************************** */
881 static ssize_t ppc_rtas_tone_volume_write(struct file * file, const char * buf,
882 size_t count, loff_t *ppos)
884 char stkbuf[40]; /* its small, its on stack */
885 unsigned long volume;
889 if (39 < count) count = 39;
890 if (copy_from_user (stkbuf, buf, count)) {
894 volume = simple_strtoul(stkbuf, &dest, 10);
895 if (*dest != '\0' && *dest != '\n') {
896 printk("ppc_rtas_tone_volume_write: Invalid tone volume\n");
899 if (volume < 0) volume = 0;
900 if (volume > 100) volume = 100;
902 rtas_tone_volume = volume; /* save it for later */
903 error = rtas_call(rtas_token("set-indicator"), 3, 1, NULL,
904 TONE_VOLUME, 0, volume);
906 printk(KERN_WARNING "error: setting tone volume returned: %s\n",
907 ppc_rtas_process_error(error));
910 /* ****************************************************************** */
911 static ssize_t ppc_rtas_tone_volume_read(struct file * file, char * buf,
912 size_t count, loff_t *ppos)
915 char stkbuf[40]; /* its small, its on stack */
917 n = scnprintf(stkbuf, 40, "%lu\n", rtas_tone_volume);
919 sn = strlen (stkbuf) +1;
926 if (copy_to_user (buf, stkbuf + (*ppos), n)) {
933 #define RMO_READ_BUF_MAX 30
935 /* RTAS Userspace access */
936 static ssize_t ppc_rtas_rmo_buf_read(struct file *file, char __user *buf,
937 size_t count, loff_t *ppos)
939 char kbuf[RMO_READ_BUF_MAX];
942 n = sprintf(kbuf, "%016lx %x\n", rtas_rmo_buf, RTAS_RMOBUF_MAX);
946 if (ppos && *ppos != 0)
949 if (copy_to_user(buf, kbuf, n))