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>
24 #include <asm/uaccess.h>
25 #include <asm/bitops.h>
26 #include <asm/processor.h>
30 #include <asm/machdep.h> /* for ppc_md */
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
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 */
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
67 #define LOC_SCSI_DEV_ADDR 'A'
68 #define LOC_SCSI_DEV_LOC 'B'
70 #define LOC_DISKETTE 'D'
71 #define LOC_ETHERNET 'E'
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'
79 #define LOC_MEMORY 'M'
80 #define LOC_NV_MEMORY 'N'
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'
91 #define LOC_FIRMWARE 'Y'
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 */
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)
118 extern struct proc_dir_entry *proc_rtas;
120 static struct rtas_sensors sensors;
121 static struct device_node *rtas_node = NULL;
122 static unsigned long power_on_time = 0; /* Save the time the user set */
123 static char progress_led[MAX_LINELENGTH];
125 static unsigned long rtas_tone_frequency = 1000;
126 static unsigned long rtas_tone_volume = 0;
128 /* ****************STRUCTS******************************************* */
129 struct individual_sensor {
134 struct rtas_sensors {
135 struct individual_sensor sensor[MAX_SENSORS];
139 /* ****************************************************************** */
141 static int ppc_rtas_sensor_read(char * buf, char ** start, off_t off,
142 int count, int *eof, void *data);
143 static ssize_t ppc_rtas_clock_read(struct file * file, char * buf,
144 size_t count, loff_t *ppos);
145 static ssize_t ppc_rtas_clock_write(struct file * file, const char * buf,
146 size_t count, loff_t *ppos);
147 static ssize_t ppc_rtas_progress_read(struct file * file, char * buf,
148 size_t count, loff_t *ppos);
149 static ssize_t ppc_rtas_progress_write(struct file * file, const char * buf,
150 size_t count, loff_t *ppos);
151 static ssize_t ppc_rtas_poweron_read(struct file * file, char * buf,
152 size_t count, loff_t *ppos);
153 static ssize_t ppc_rtas_poweron_write(struct file * file, const char * buf,
154 size_t count, loff_t *ppos);
156 static ssize_t ppc_rtas_tone_freq_write(struct file * file, const char * buf,
157 size_t count, loff_t *ppos);
158 static ssize_t ppc_rtas_tone_freq_read(struct file * file, char * buf,
159 size_t count, loff_t *ppos);
160 static ssize_t ppc_rtas_tone_volume_write(struct file * file, const char * buf,
161 size_t count, loff_t *ppos);
162 static ssize_t ppc_rtas_tone_volume_read(struct file * file, char * buf,
163 size_t count, loff_t *ppos);
165 struct file_operations ppc_rtas_poweron_operations = {
166 .read = ppc_rtas_poweron_read,
167 .write = ppc_rtas_poweron_write
169 struct file_operations ppc_rtas_progress_operations = {
170 .read = ppc_rtas_progress_read,
171 .write = ppc_rtas_progress_write
174 struct file_operations ppc_rtas_clock_operations = {
175 .read = ppc_rtas_clock_read,
176 .write = ppc_rtas_clock_write
179 struct file_operations ppc_rtas_tone_freq_operations = {
180 .read = ppc_rtas_tone_freq_read,
181 .write = ppc_rtas_tone_freq_write
183 struct file_operations ppc_rtas_tone_volume_operations = {
184 .read = ppc_rtas_tone_volume_read,
185 .write = ppc_rtas_tone_volume_write
188 int ppc_rtas_find_all_sensors (void);
189 int ppc_rtas_process_sensor(struct individual_sensor s, int state,
190 int error, char * buf);
191 char * ppc_rtas_process_error(int error);
192 int get_location_code(struct individual_sensor s, char * buf);
193 int check_location_string (char *c, char * buf);
194 int check_location (char *c, int idx, char * buf);
196 /* ****************************************************************** */
198 /* ****************************************************************** */
199 void proc_rtas_init(void)
201 struct proc_dir_entry *entry;
203 rtas_node = find_devices("rtas");
204 if ((rtas_node == NULL) || (systemcfg->platform == PLATFORM_ISERIES_LPAR)) {
208 if (proc_rtas == NULL) {
209 proc_rtas = proc_mkdir("rtas", 0);
212 if (proc_rtas == NULL) {
213 printk(KERN_ERR "Failed to create /proc/rtas in proc_rtas_init\n");
217 /* /proc/rtas entries */
219 entry = create_proc_entry("progress", S_IRUGO|S_IWUSR, proc_rtas);
220 if (entry) entry->proc_fops = &ppc_rtas_progress_operations;
222 entry = create_proc_entry("clock", S_IRUGO|S_IWUSR, proc_rtas);
223 if (entry) entry->proc_fops = &ppc_rtas_clock_operations;
225 entry = create_proc_entry("poweron", S_IWUSR|S_IRUGO, proc_rtas);
226 if (entry) entry->proc_fops = &ppc_rtas_poweron_operations;
228 create_proc_read_entry("sensors", S_IRUGO, proc_rtas,
229 ppc_rtas_sensor_read, NULL);
231 entry = create_proc_entry("frequency", S_IWUSR|S_IRUGO, proc_rtas);
232 if (entry) entry->proc_fops = &ppc_rtas_tone_freq_operations;
234 entry = create_proc_entry("volume", S_IWUSR|S_IRUGO, proc_rtas);
235 if (entry) entry->proc_fops = &ppc_rtas_tone_volume_operations;
238 /* ****************************************************************** */
240 /* ****************************************************************** */
241 static ssize_t ppc_rtas_poweron_write(struct file * file, const char * buf,
242 size_t count, loff_t *ppos)
245 unsigned long nowtime;
249 nowtime = simple_strtoul(buf, &dest, 10);
250 if (*dest != '\0' && *dest != '\n') {
251 printk("ppc_rtas_poweron_write: Invalid time\n");
254 power_on_time = nowtime; /* save the time */
258 error = rtas_call(rtas_token("set-time-for-power-on"), 7, 1, NULL,
259 tm.tm_year, tm.tm_mon, tm.tm_mday,
260 tm.tm_hour, tm.tm_min, tm.tm_sec, 0 /* nano */);
262 printk(KERN_WARNING "error: setting poweron time returned: %s\n",
263 ppc_rtas_process_error(error));
266 /* ****************************************************************** */
267 static ssize_t ppc_rtas_poweron_read(struct file * file, char * buf,
268 size_t count, loff_t *ppos)
271 if (power_on_time == 0)
272 n = sprintf(buf, "Power on time not set\n");
274 n = sprintf(buf, "%lu\n", power_on_time);
276 if (*ppos >= strlen(buf))
278 if (n > strlen(buf) - *ppos)
279 n = strlen(buf) - *ppos;
286 /* ****************************************************************** */
288 /* ****************************************************************** */
289 static ssize_t ppc_rtas_progress_write(struct file * file, const char * buf,
290 size_t count, loff_t *ppos)
294 strcpy(progress_led, buf); /* save the string */
295 /* Lets see if the user passed hexdigits */
296 hex = simple_strtoul(buf, NULL, 10);
298 ppc_md.progress ((char *)buf, hex);
301 /* clear the line */ /* ppc_md.progress(" ", 0xffff);*/
303 /* ****************************************************************** */
304 static ssize_t ppc_rtas_progress_read(struct file * file, char * buf,
305 size_t count, loff_t *ppos)
308 if (progress_led != NULL)
309 n = sprintf (buf, "%s\n", progress_led);
310 if (*ppos >= strlen(buf))
312 if (n > strlen(buf) - *ppos)
313 n = strlen(buf) - *ppos;
320 /* ****************************************************************** */
322 /* ****************************************************************** */
323 static ssize_t ppc_rtas_clock_write(struct file * file, const char * buf,
324 size_t count, loff_t *ppos)
327 unsigned long nowtime;
331 nowtime = simple_strtoul(buf, &dest, 10);
332 if (*dest != '\0' && *dest != '\n') {
333 printk("ppc_rtas_clock_write: Invalid time\n");
338 error = rtas_call(rtas_token("set-time-of-day"), 7, 1, NULL,
339 tm.tm_year, tm.tm_mon, tm.tm_mday,
340 tm.tm_hour, tm.tm_min, tm.tm_sec, 0);
342 printk(KERN_WARNING "error: setting the clock returned: %s\n",
343 ppc_rtas_process_error(error));
346 /* ****************************************************************** */
347 static ssize_t ppc_rtas_clock_read(struct file * file, char * buf,
348 size_t count, loff_t *ppos)
350 unsigned int year, mon, day, hour, min, sec;
351 unsigned long *ret = kmalloc(4*8, GFP_KERNEL);
354 error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret);
356 year = ret[0]; mon = ret[1]; day = ret[2];
357 hour = ret[3]; min = ret[4]; sec = ret[5];
360 printk(KERN_WARNING "error: reading the clock returned: %s\n",
361 ppc_rtas_process_error(error));
362 n = sprintf (buf, "0");
364 n = sprintf (buf, "%lu\n", mktime(year, mon, day, hour, min, sec));
368 if (*ppos >= strlen(buf))
370 if (n > strlen(buf) - *ppos)
371 n = strlen(buf) - *ppos;
378 /* ****************************************************************** */
380 /* ****************************************************************** */
381 static int ppc_rtas_sensor_read(char * buf, char ** start, off_t off,
382 int count, int *eof, void *data)
388 int get_sensor_state = rtas_token("get-sensor-state");
393 /* May not be enough */
394 buffer = kmalloc(MAX_LINELENGTH*MAX_SENSORS, GFP_KERNEL);
399 memset(buffer, 0, MAX_LINELENGTH*MAX_SENSORS);
401 n = sprintf ( buffer , "RTAS (RunTime Abstraction Services) Sensor Information\n");
402 n += sprintf ( buffer+n, "Sensor\t\tValue\t\tCondition\tLocation\n");
403 n += sprintf ( buffer+n, "********************************************************\n");
405 if (ppc_rtas_find_all_sensors() != 0) {
406 n += sprintf ( buffer+n, "\nNo sensors are available\n");
410 for (i=0; i<sensors.quant; i++) {
411 j = sensors.sensor[i].quant;
412 /* A sensor may have multiple instances */
415 error = rtas_call(get_sensor_state, 2, 2, &ret,
416 sensors.sensor[i].token,
417 sensors.sensor[i].quant - j);
420 n += ppc_rtas_process_sensor(sensors.sensor[i], state,
422 n += sprintf (buffer+n, "\n");
428 if (off >= strlen(buffer)) {
433 if (n > strlen(buffer) - off)
434 n = strlen(buffer) - off;
440 memcpy(buf, buffer + off, n);
446 /* ****************************************************************** */
448 int ppc_rtas_find_all_sensors (void)
453 utmp = (unsigned int *) get_property(rtas_node, "rtas-sensors", &len);
455 printk (KERN_ERR "error: could not get rtas-sensors\n");
459 sensors.quant = len / 8; /* int + int */
461 for (i=0; i<sensors.quant; i++) {
462 sensors.sensor[i].token = *utmp++;
463 sensors.sensor[i].quant = *utmp++;
468 /* ****************************************************************** */
470 * Builds a string of what rtas returned
472 char * ppc_rtas_process_error(int error)
475 case SENSOR_CRITICAL_HIGH:
476 return "(critical high)";
477 case SENSOR_WARNING_HIGH:
478 return "(warning high)";
481 case SENSOR_WARNING_LOW:
482 return "(warning low)";
483 case SENSOR_CRITICAL_LOW:
484 return "(critical low)";
487 case SENSOR_HW_ERROR:
488 return "(hardware error)";
491 case SENSOR_NOT_EXIST:
492 return "(non existant)";
493 case SENSOR_DR_ENTITY:
494 return "(dr entity removed)";
500 /* ****************************************************************** */
502 * Builds a string out of what the sensor said
505 int ppc_rtas_process_sensor(struct individual_sensor s, int state,
506 int error, char * buf)
508 /* Defined return vales */
509 const char * key_switch[] = { "Off\t", "Normal\t", "Secure\t",
511 const char * enclosure_switch[] = { "Closed", "Open" };
512 const char * lid_status[] = { " ", "Open", "Closed" };
513 const char * power_source[] = { "AC\t", "Battery",
515 const char * battery_remaining[] = { "Very Low", "Low", "Mid", "High" };
516 const char * epow_sensor[] = {
517 "EPOW Reset", "Cooling warning", "Power warning",
518 "System shutdown", "System halt", "EPOW main enclosure",
520 const char * battery_cyclestate[] = { "None", "In progress",
522 const char * battery_charging[] = { "Charging", "Discharching",
524 const char * ibm_drconnector[] = { "Empty", "Present", "Unusable",
526 const char * ibm_intqueue[] = { "Disabled", "Enabled" };
528 int have_strings = 0;
534 /* What kind of sensor do we have here? */
538 n += sprintf(buf+n, "Key switch:\t");
539 num_states = sizeof(key_switch) / sizeof(char *);
540 if (state < num_states) {
541 n += sprintf(buf+n, "%s\t", key_switch[state]);
545 case ENCLOSURE_SWITCH:
546 n += sprintf(buf+n, "Enclosure switch:\t");
547 num_states = sizeof(enclosure_switch) / sizeof(char *);
548 if (state < num_states) {
549 n += sprintf(buf+n, "%s\t",
550 enclosure_switch[state]);
555 n += sprintf(buf+n, "Temp. (°C/°F):\t");
559 n += sprintf(buf+n, "Lid status:\t");
560 num_states = sizeof(lid_status) / sizeof(char *);
561 if (state < num_states) {
562 n += sprintf(buf+n, "%s\t", lid_status[state]);
567 n += sprintf(buf+n, "Power source:\t");
568 num_states = sizeof(power_source) / sizeof(char *);
569 if (state < num_states) {
570 n += sprintf(buf+n, "%s\t",
571 power_source[state]);
575 case BATTERY_VOLTAGE:
576 n += sprintf(buf+n, "Battery voltage:\t");
578 case BATTERY_REMAINING:
579 n += sprintf(buf+n, "Battery remaining:\t");
580 num_states = sizeof(battery_remaining) / sizeof(char *);
581 if (state < num_states)
583 n += sprintf(buf+n, "%s\t",
584 battery_remaining[state]);
588 case BATTERY_PERCENTAGE:
589 n += sprintf(buf+n, "Battery percentage:\t");
592 n += sprintf(buf+n, "EPOW Sensor:\t");
593 num_states = sizeof(epow_sensor) / sizeof(char *);
594 if (state < num_states) {
595 n += sprintf(buf+n, "%s\t", epow_sensor[state]);
599 case BATTERY_CYCLESTATE:
600 n += sprintf(buf+n, "Battery cyclestate:\t");
601 num_states = sizeof(battery_cyclestate) /
603 if (state < num_states) {
604 n += sprintf(buf+n, "%s\t",
605 battery_cyclestate[state]);
609 case BATTERY_CHARGING:
610 n += sprintf(buf+n, "Battery Charging:\t");
611 num_states = sizeof(battery_charging) / sizeof(char *);
612 if (state < num_states) {
613 n += sprintf(buf+n, "%s\t",
614 battery_charging[state]);
618 case IBM_SURVEILLANCE:
619 n += sprintf(buf+n, "Surveillance:\t");
622 n += sprintf(buf+n, "Fan (rpm):\t");
625 n += sprintf(buf+n, "Voltage (mv):\t");
627 case IBM_DRCONNECTOR:
628 n += sprintf(buf+n, "DR connector:\t");
629 num_states = sizeof(ibm_drconnector) / sizeof(char *);
630 if (state < num_states) {
631 n += sprintf(buf+n, "%s\t",
632 ibm_drconnector[state]);
636 case IBM_POWERSUPPLY:
637 n += sprintf(buf+n, "Powersupply:\t");
640 n += sprintf(buf+n, "Interrupt queue:\t");
641 num_states = sizeof(ibm_intqueue) / sizeof(char *);
642 if (state < num_states) {
643 n += sprintf(buf+n, "%s\t",
644 ibm_intqueue[state]);
649 n += sprintf(buf+n, "Unkown sensor (type %d), ignoring it\n",
655 if (have_strings == 0) {
657 n += sprintf(buf+n, "%4d /%4d\t", state, cel_to_fahr(state));
659 n += sprintf(buf+n, "%10d\t", state);
662 n += sprintf ( buf+n, "%s\t", ppc_rtas_process_error(error));
663 n += get_location_code(s, buf+n);
668 /* ****************************************************************** */
670 int check_location (char *c, int idx, char * buf)
676 n += sprintf ( buf, "Planar #%c", *(c+idx+1));
679 n += sprintf ( buf, "CPU #%c", *(c+idx+1));
682 n += sprintf ( buf, "Fan #%c", *(c+idx+1));
684 case LOC_RACKMOUNTED:
685 n += sprintf ( buf, "Rack #%c", *(c+idx+1));
688 n += sprintf ( buf, "Voltage #%c", *(c+idx+1));
691 n += sprintf ( buf, "LCD #%c", *(c+idx+1));
694 n += sprintf ( buf, "- %c", *(c+idx+1));
696 n += sprintf ( buf, "Unknown location");
703 /* ****************************************************************** */
706 * ${LETTER}${NUMBER}[[-/]${LETTER}${NUMBER} [ ... ] ]
707 * the '.' may be an abbrevation
709 int check_location_string (char *c, char *buf)
714 if (isalpha(c[i]) || c[i] == '.') {
715 n += check_location(c, i, buf+n);
717 else if (c[i] == '/' || c[i] == '-')
718 n += sprintf(buf+n, " at ");
725 /* ****************************************************************** */
727 int get_location_code(struct individual_sensor s, char * buffer)
729 char rstr[512], tmp[10], tmp2[10];
730 int n=0, i=0, llen, len;
731 /* char *buf = kmalloc(MAX_LINELENGTH, GFP_KERNEL); */
734 static int pos = 0; /* remember position where buffer was */
736 /* construct the sensor number like 0003 */
737 /* fill with zeros */
738 n = sprintf(tmp, "%d", s.token);
740 while (strlen(tmp) < 4)
741 n += sprintf (tmp+n, "0");
743 /* invert the string */
746 tmp2[4-len+i] = tmp[i];
753 sprintf (rstr, SENSOR_PREFIX"%s", tmp2);
755 ret = (char *) get_property(rtas_node, rstr, &llen);
758 if (ret == NULL || ret[0] == '\0') {
759 n += sprintf ( buffer+n, "--- ");/* does not have a location */
764 n += check_location_string(ret, buffer + n);
765 n += sprintf ( buffer+n, " ");
766 /* see how many characters we have printed */
767 sprintf ( t, "%s ", ret);
770 if (pos >= llen) pos=0;
774 /* ****************************************************************** */
775 /* INDICATORS - Tone Frequency */
776 /* ****************************************************************** */
777 static ssize_t ppc_rtas_tone_freq_write(struct file * file, const char * buf,
778 size_t count, loff_t *ppos)
783 freq = simple_strtoul(buf, &dest, 10);
784 if (*dest != '\0' && *dest != '\n') {
785 printk("ppc_rtas_tone_freq_write: Invalid tone freqency\n");
788 if (freq < 0) freq = 0;
789 rtas_tone_frequency = freq; /* save it for later */
790 error = rtas_call(rtas_token("set-indicator"), 3, 1, NULL,
791 TONE_FREQUENCY, 0, freq);
793 printk(KERN_WARNING "error: setting tone frequency returned: %s\n",
794 ppc_rtas_process_error(error));
797 /* ****************************************************************** */
798 static ssize_t ppc_rtas_tone_freq_read(struct file * file, char * buf,
799 size_t count, loff_t *ppos)
802 n = sprintf(buf, "%lu\n", rtas_tone_frequency);
804 if (*ppos >= strlen(buf))
806 if (n > strlen(buf) - *ppos)
807 n = strlen(buf) - *ppos;
813 /* ****************************************************************** */
814 /* INDICATORS - Tone Volume */
815 /* ****************************************************************** */
816 static ssize_t ppc_rtas_tone_volume_write(struct file * file, const char * buf,
817 size_t count, loff_t *ppos)
819 unsigned long volume;
822 volume = simple_strtoul(buf, &dest, 10);
823 if (*dest != '\0' && *dest != '\n') {
824 printk("ppc_rtas_tone_volume_write: Invalid tone volume\n");
827 if (volume < 0) volume = 0;
828 if (volume > 100) volume = 100;
830 rtas_tone_volume = volume; /* save it for later */
831 error = rtas_call(rtas_token("set-indicator"), 3, 1, NULL,
832 TONE_VOLUME, 0, volume);
834 printk(KERN_WARNING "error: setting tone volume returned: %s\n",
835 ppc_rtas_process_error(error));
838 /* ****************************************************************** */
839 static ssize_t ppc_rtas_tone_volume_read(struct file * file, char * buf,
840 size_t count, loff_t *ppos)
843 n = sprintf(buf, "%lu\n", rtas_tone_volume);
845 if (*ppos >= strlen(buf))
847 if (n > strlen(buf) - *ppos)
848 n = strlen(buf) - *ppos;