File: /usr/src/linux/drivers/zorro/proc.c

1     /*
2      *	$Id: proc.c,v 1.1.2.1 1998/06/07 23:21:01 geert Exp $
3      *
4      *	Procfs interface for the Zorro bus.
5      *
6      *	Copyright (C) 1998-2000 Geert Uytterhoeven
7      *
8      *	Heavily based on the procfs interface for the PCI bus, which is
9      *
10      *	Copyright (C) 1997, 1998 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
11      */
12     
13     #include <linux/types.h>
14     #include <linux/zorro.h>
15     #include <linux/proc_fs.h>
16     #include <linux/init.h>
17     #include <asm/uaccess.h>
18     #include <asm/amigahw.h>
19     #include <asm/setup.h>
20     
21     static loff_t
22     proc_bus_zorro_lseek(struct file *file, loff_t off, int whence)
23     {
24     	loff_t new;
25     
26     	switch (whence) {
27     	case 0:
28     		new = off;
29     		break;
30     	case 1:
31     		new = file->f_pos + off;
32     		break;
33     	case 2:
34     		new = sizeof(struct ConfigDev) + off;
35     		break;
36     	default:
37     		return -EINVAL;
38     	}
39     	if (new < 0 || new > sizeof(struct ConfigDev))
40     		return -EINVAL;
41     	return (file->f_pos = new);
42     }
43     
44     static ssize_t
45     proc_bus_zorro_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos)
46     {
47     	struct inode *ino = file->f_dentry->d_inode;
48     	struct proc_dir_entry *dp = ino->u.generic_ip;
49     	struct zorro_dev *dev = dp->data;
50     	struct ConfigDev cd;
51     	int pos = *ppos;
52     
53     	if (pos >= sizeof(struct ConfigDev))
54     		return 0;
55     	if (nbytes >= sizeof(struct ConfigDev))
56     		nbytes = sizeof(struct ConfigDev);
57     	if (pos + nbytes > sizeof(struct ConfigDev))
58     		nbytes = sizeof(struct ConfigDev) - pos;
59     
60     	/* Construct a ConfigDev */
61     	memset(&cd, 0, sizeof(cd));
62     	cd.cd_Rom = dev->rom;
63     	cd.cd_SlotAddr = dev->slotaddr;
64     	cd.cd_SlotSize = dev->slotsize;
65     	cd.cd_BoardAddr = (void *)dev->resource.start;
66     	cd.cd_BoardSize = dev->resource.end-dev->resource.start+1;
67     
68     	if (copy_to_user(buf, &cd, nbytes))
69     		return -EFAULT;
70     	*ppos += nbytes;
71     
72     	return nbytes;
73     }
74     
75     static struct file_operations proc_bus_zorro_operations = {
76     	llseek:		proc_bus_zorro_lseek,
77     	read:		proc_bus_zorro_read,
78     };
79     
80     static int
81     get_zorro_dev_info(char *buf, char **start, off_t pos, int count)
82     {
83     	u_int slot;
84     	off_t at = 0;
85     	int len, cnt;
86     
87     	for (slot = cnt = 0; slot < zorro_num_autocon && count > cnt; slot++) {
88     		struct zorro_dev *dev = &zorro_autocon[slot];
89     		len = sprintf(buf, "%02x\t%08x\t%08lx\t%08lx\t%02x\n", slot,
90     			      dev->id, dev->resource.start,
91     			      dev->resource.end-dev->resource.start+1,
92     			      dev->rom.er_Type);
93     		at += len;
94     		if (at >= pos) {
95     			if (!*start) {
96     				*start = buf + (pos - (at - len));
97     				cnt = at - pos;
98     			} else
99     				cnt += len;
100     			buf += len;
101     		}
102     	}
103     	return (count > cnt) ? cnt : count;
104     }
105     
106     static struct proc_dir_entry *proc_bus_zorro_dir;
107     
108     static int __init zorro_proc_attach_device(u_int slot)
109     {
110     	struct proc_dir_entry *entry;
111     	char name[4];
112     
113     	sprintf(name, "%02x", slot);
114     	entry = create_proc_entry(name, 0, proc_bus_zorro_dir);
115     	if (!entry)
116     		return -ENOMEM;
117     	entry->proc_fops = &proc_bus_zorro_operations;
118     	entry->data = &zorro_autocon[slot];
119     	entry->size = sizeof(struct zorro_dev);
120     	return 0;
121     }
122     
123     static int __init zorro_proc_init(void)
124     {
125     	u_int slot;
126     
127     	if (MACH_IS_AMIGA && AMIGAHW_PRESENT(ZORRO)) {
128     		proc_bus_zorro_dir = proc_mkdir("zorro", proc_bus);
129     		create_proc_info_entry("devices", 0, proc_bus_zorro_dir,
130     				       get_zorro_dev_info);
131     		for (slot = 0; slot < zorro_num_autocon; slot++)
132     			zorro_proc_attach_device(slot);
133     	}
134     	return 0;
135     }
136     
137     __initcall(zorro_proc_init);
138