aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/parisc/led.c
diff options
context:
space:
mode:
authorAlexey Dobriyan <adobriyan@gmail.com>2009-11-27 01:51:12 -0500
committerKyle McMartin <kyle@mcmartin.ca>2009-12-15 22:48:55 -0500
commit217bfb5190813d97e6003f7692f8014655ffc02a (patch)
treeb5eef7041fc0b3137be20505f9d07c2abaa3bfd5 /drivers/parisc/led.c
parent05920797ca4c55b3c0629bc0eeb6fe634c196952 (diff)
parisc: convert /proc/pdc/{lcd,led} to seq_file
Convert code away from ->read_proc/->write_proc interfaces. Switch to proc_create()/proc_create_data() which make addition of proc entries reliable wrt NULL ->proc_fops, NULL ->data and so on. Problem with ->read_proc et al is described here commit 786d7e1612f0b0adb6046f19b906609e4fe8b1ba "Fix rmmod/read/write races in /proc entries" Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com> Reviewed-by: Grant Grundler <grundler@parisc-linux.org> Signed-off-by: Kyle McMartin <kyle@mcmartin.ca>
Diffstat (limited to 'drivers/parisc/led.c')
-rw-r--r--drivers/parisc/led.c59
1 files changed, 29 insertions, 30 deletions
diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c
index 79caf1ca4a29..188bc8496a26 100644
--- a/drivers/parisc/led.c
+++ b/drivers/parisc/led.c
@@ -38,6 +38,7 @@
38#include <linux/kernel_stat.h> 38#include <linux/kernel_stat.h>
39#include <linux/reboot.h> 39#include <linux/reboot.h>
40#include <linux/proc_fs.h> 40#include <linux/proc_fs.h>
41#include <linux/seq_file.h>
41#include <linux/ctype.h> 42#include <linux/ctype.h>
42#include <linux/blkdev.h> 43#include <linux/blkdev.h>
43#include <linux/workqueue.h> 44#include <linux/workqueue.h>
@@ -147,41 +148,34 @@ device_initcall(start_task);
147static void (*led_func_ptr) (unsigned char) __read_mostly; 148static void (*led_func_ptr) (unsigned char) __read_mostly;
148 149
149#ifdef CONFIG_PROC_FS 150#ifdef CONFIG_PROC_FS
150static int led_proc_read(char *page, char **start, off_t off, int count, 151static int led_proc_show(struct seq_file *m, void *v)
151 int *eof, void *data)
152{ 152{
153 char *out = page; 153 switch ((long)m->private)
154 int len;
155
156 switch ((long)data)
157 { 154 {
158 case LED_NOLCD: 155 case LED_NOLCD:
159 out += sprintf(out, "Heartbeat: %d\n", led_heartbeat); 156 seq_printf(m, "Heartbeat: %d\n", led_heartbeat);
160 out += sprintf(out, "Disk IO: %d\n", led_diskio); 157 seq_printf(m, "Disk IO: %d\n", led_diskio);
161 out += sprintf(out, "LAN Rx/Tx: %d\n", led_lanrxtx); 158 seq_printf(m, "LAN Rx/Tx: %d\n", led_lanrxtx);
162 break; 159 break;
163 case LED_HASLCD: 160 case LED_HASLCD:
164 out += sprintf(out, "%s\n", lcd_text); 161 seq_printf(m, "%s\n", lcd_text);
165 break; 162 break;
166 default: 163 default:
167 *eof = 1;
168 return 0; 164 return 0;
169 } 165 }
166 return 0;
167}
170 168
171 len = out - page - off; 169static int led_proc_open(struct inode *inode, struct file *file)
172 if (len < count) { 170{
173 *eof = 1; 171 return single_open(file, led_proc_show, PDE(inode)->data);
174 if (len <= 0) return 0;
175 } else {
176 len = count;
177 }
178 *start = page + off;
179 return len;
180} 172}
181 173
182static int led_proc_write(struct file *file, const char *buf, 174
183 unsigned long count, void *data) 175static ssize_t led_proc_write(struct file *file, const char *buf,
176 size_t count, loff_t *pos)
184{ 177{
178 void *data = PDE(file->f_path.dentry->d_inode)->data;
185 char *cur, lbuf[count + 1]; 179 char *cur, lbuf[count + 1];
186 int d; 180 int d;
187 181
@@ -234,6 +228,15 @@ parse_error:
234 return -EINVAL; 228 return -EINVAL;
235} 229}
236 230
231static const struct file_operations led_proc_fops = {
232 .owner = THIS_MODULE,
233 .open = led_proc_open,
234 .read = seq_read,
235 .llseek = seq_lseek,
236 .release = single_release,
237 .write = led_proc_write,
238};
239
237static int __init led_create_procfs(void) 240static int __init led_create_procfs(void)
238{ 241{
239 struct proc_dir_entry *proc_pdc_root = NULL; 242 struct proc_dir_entry *proc_pdc_root = NULL;
@@ -243,19 +246,15 @@ static int __init led_create_procfs(void)
243 246
244 proc_pdc_root = proc_mkdir("pdc", 0); 247 proc_pdc_root = proc_mkdir("pdc", 0);
245 if (!proc_pdc_root) return -1; 248 if (!proc_pdc_root) return -1;
246 ent = create_proc_entry("led", S_IFREG|S_IRUGO|S_IWUSR, proc_pdc_root); 249 ent = proc_create_data("led", S_IRUGO|S_IWUSR, proc_pdc_root,
250 &led_proc_fops, (void *)LED_NOLCD); /* LED */
247 if (!ent) return -1; 251 if (!ent) return -1;
248 ent->data = (void *)LED_NOLCD; /* LED */
249 ent->read_proc = led_proc_read;
250 ent->write_proc = led_proc_write;
251 252
252 if (led_type == LED_HASLCD) 253 if (led_type == LED_HASLCD)
253 { 254 {
254 ent = create_proc_entry("lcd", S_IFREG|S_IRUGO|S_IWUSR, proc_pdc_root); 255 ent = proc_create_data("lcd", S_IRUGO|S_IWUSR, proc_pdc_root,
256 &led_proc_fops, (void *)LED_HASLCD); /* LCD */
255 if (!ent) return -1; 257 if (!ent) return -1;
256 ent->data = (void *)LED_HASLCD; /* LCD */
257 ent->read_proc = led_proc_read;
258 ent->write_proc = led_proc_write;
259 } 258 }
260 259
261 return 0; 260 return 0;