Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 217bfb51 authored by Alexey Dobriyan's avatar Alexey Dobriyan Committed by Kyle McMartin
Browse files

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 786d7e16
"Fix rmmod/read/write races in /proc entries"

Signed-off-by: default avatarAlexey Dobriyan <adobriyan@gmail.com>
Reviewed-by: default avatarGrant Grundler <grundler@parisc-linux.org>
Signed-off-by: default avatarKyle McMartin <kyle@mcmartin.ca>
parent 05920797
Loading
Loading
Loading
Loading
+29 −30
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@
#include <linux/kernel_stat.h>
#include <linux/reboot.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/ctype.h>
#include <linux/blkdev.h>
#include <linux/workqueue.h>
@@ -147,41 +148,34 @@ device_initcall(start_task);
static void (*led_func_ptr) (unsigned char) __read_mostly;

#ifdef CONFIG_PROC_FS
static int led_proc_read(char *page, char **start, off_t off, int count, 
	int *eof, void *data)
static int led_proc_show(struct seq_file *m, void *v)
{
	char *out = page;
	int len;

	switch ((long)data)
	switch ((long)m->private)
	{
	case LED_NOLCD:
		out += sprintf(out, "Heartbeat: %d\n", led_heartbeat);
		out += sprintf(out, "Disk IO: %d\n", led_diskio);
		out += sprintf(out, "LAN Rx/Tx: %d\n", led_lanrxtx);
		seq_printf(m, "Heartbeat: %d\n", led_heartbeat);
		seq_printf(m, "Disk IO: %d\n", led_diskio);
		seq_printf(m, "LAN Rx/Tx: %d\n", led_lanrxtx);
		break;
	case LED_HASLCD:
		out += sprintf(out, "%s\n", lcd_text);
		seq_printf(m, "%s\n", lcd_text);
		break;
	default:
		*eof = 1;
		return 0;
	}

	len = out - page - off;
	if (len < count) {
		*eof = 1;
		if (len <= 0) return 0;
	} else {
		len = count;
	return 0;
}
	*start = page + off;
	return len;

static int led_proc_open(struct inode *inode, struct file *file)
{
	return single_open(file, led_proc_show, PDE(inode)->data);
}

static int led_proc_write(struct file *file, const char *buf, 
	unsigned long count, void *data)

static ssize_t led_proc_write(struct file *file, const char *buf,
	size_t count, loff_t *pos)
{
	void *data = PDE(file->f_path.dentry->d_inode)->data;
	char *cur, lbuf[count + 1];
	int d;

@@ -234,6 +228,15 @@ parse_error:
	return -EINVAL;
}

static const struct file_operations led_proc_fops = {
	.owner		= THIS_MODULE,
	.open		= led_proc_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
	.write		= led_proc_write,
};

static int __init led_create_procfs(void)
{
	struct proc_dir_entry *proc_pdc_root = NULL;
@@ -243,19 +246,15 @@ static int __init led_create_procfs(void)

	proc_pdc_root = proc_mkdir("pdc", 0);
	if (!proc_pdc_root) return -1;
	ent = create_proc_entry("led", S_IFREG|S_IRUGO|S_IWUSR, proc_pdc_root);
	ent = proc_create_data("led", S_IRUGO|S_IWUSR, proc_pdc_root,
				&led_proc_fops, (void *)LED_NOLCD); /* LED */
	if (!ent) return -1;
	ent->data = (void *)LED_NOLCD; /* LED */
	ent->read_proc = led_proc_read;
	ent->write_proc = led_proc_write;

	if (led_type == LED_HASLCD)
	{
		ent = create_proc_entry("lcd", S_IFREG|S_IRUGO|S_IWUSR, proc_pdc_root);
		ent = proc_create_data("lcd", S_IRUGO|S_IWUSR, proc_pdc_root,
					&led_proc_fops, (void *)LED_HASLCD); /* LCD */
		if (!ent) return -1;
		ent->data = (void *)LED_HASLCD; /* LCD */
		ent->read_proc = led_proc_read;
		ent->write_proc = led_proc_write;
	}

	return 0;