Blame view

drivers/nubus/proc.c 5.49 KB
b24413180   Greg Kroah-Hartman   License cleanup: ...
1
  // SPDX-License-Identifier: GPL-2.0
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
5
6
7
8
9
10
11
12
  /* drivers/nubus/proc.c: Proc FS interface for NuBus.
  
     By David Huggins-Daines <dhd@debian.org>
  
     Much code and many ideas from drivers/pci/proc.c:
     Copyright (c) 1997, 1998 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
  
     This is initially based on the Zorro and PCI interfaces.  However,
     it works somewhat differently.  The intent is to provide a
     structure in /proc analogous to the structure of the NuBus ROM
     resources.
2f7dd07ec   Finn Thain   nubus: Rework /pr...
13
14
15
16
17
18
     Therefore each board function gets a directory, which may in turn
     contain subdirectories.  Each slot resource is a file.  Unrecognized
     resources are empty files, since every resource ID requires a special
     case (e.g. if the resource ID implies a directory or block, then its
     value has to be interpreted as a slot ROM pointer etc.).
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
19
20
21
22
23
  
  #include <linux/types.h>
  #include <linux/kernel.h>
  #include <linux/nubus.h>
  #include <linux/proc_fs.h>
076ec04b8   Alexey Dobriyan   proc: convert /pr...
24
  #include <linux/seq_file.h>
2f7dd07ec   Finn Thain   nubus: Rework /pr...
25
  #include <linux/slab.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
26
  #include <linux/init.h>
99ffab810   Adrian Bunk   nubus: kill drive...
27
  #include <linux/module.h>
7c0f6ba68   Linus Torvalds   Replace <asm/uacc...
28
  #include <linux/uaccess.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
29
  #include <asm/byteorder.h>
2f7dd07ec   Finn Thain   nubus: Rework /pr...
30
31
32
  /*
   * /proc/bus/nubus/devices stuff
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
33
  static int
076ec04b8   Alexey Dobriyan   proc: convert /pr...
34
  nubus_devices_proc_show(struct seq_file *m, void *v)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
35
  {
41b848160   Finn Thain   nubus: Adopt stan...
36
  	struct nubus_rsrc *fres;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
37

41b848160   Finn Thain   nubus: Adopt stan...
38
39
40
  	for_each_func_rsrc(fres)
  		seq_printf(m, "%x\t%04x %04x %04x %04x\t%08lx
  ",
189e19e8c   Finn Thain   nubus: Rename str...
41
  			   fres->board->slot, fres->category, fres->type,
41b848160   Finn Thain   nubus: Adopt stan...
42
  			   fres->dr_sw, fres->dr_hw, fres->board->slot_addr);
076ec04b8   Alexey Dobriyan   proc: convert /pr...
43
44
45
46
47
48
  	return 0;
  }
  
  static int nubus_devices_proc_open(struct inode *inode, struct file *file)
  {
  	return single_open(file, nubus_devices_proc_show, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
49
  }
076ec04b8   Alexey Dobriyan   proc: convert /pr...
50
  static const struct file_operations nubus_devices_proc_fops = {
076ec04b8   Alexey Dobriyan   proc: convert /pr...
51
52
53
54
55
  	.open		= nubus_devices_proc_open,
  	.read		= seq_read,
  	.llseek		= seq_lseek,
  	.release	= single_release,
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
56
  static struct proc_dir_entry *proc_bus_nubus_dir;
2f7dd07ec   Finn Thain   nubus: Rework /pr...
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
  /*
   * /proc/bus/nubus/x/ stuff
   */
  
  struct proc_dir_entry *nubus_proc_add_board(struct nubus_board *board)
  {
  	char name[2];
  
  	if (!proc_bus_nubus_dir)
  		return NULL;
  	snprintf(name, sizeof(name), "%x", board->slot);
  	return proc_mkdir(name, proc_bus_nubus_dir);
  }
  
  /* The PDE private data for any directory under /proc/bus/nubus/x/
   * is the bytelanes value for the board in slot x.
   */
  
  struct proc_dir_entry *nubus_proc_add_rsrc_dir(struct proc_dir_entry *procdir,
  					       const struct nubus_dirent *ent,
  					       struct nubus_board *board)
  {
  	char name[9];
  	int lanes = board->lanes;
  
  	if (!procdir)
  		return NULL;
  	snprintf(name, sizeof(name), "%x", ent->type);
  	return proc_mkdir_data(name, 0555, procdir, (void *)lanes);
  }
  
  /* The PDE private data for a file under /proc/bus/nubus/x/ is a pointer to
   * an instance of the following structure, which gives the location and size
   * of the resource data in the slot ROM. For slot resources which hold only a
   * small integer, this integer value is stored directly and size is set to 0.
   * A NULL private data pointer indicates an unrecognized resource.
   */
  
  struct nubus_proc_pde_data {
  	unsigned char *res_ptr;
  	unsigned int res_size;
11db656ad   David Howells   nubus: Don't use ...
98
  };
2f7dd07ec   Finn Thain   nubus: Rework /pr...
99
100
  static struct nubus_proc_pde_data *
  nubus_proc_alloc_pde_data(unsigned char *ptr, unsigned int size)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
101
  {
2f7dd07ec   Finn Thain   nubus: Rework /pr...
102
103
104
105
106
107
108
109
110
  	struct nubus_proc_pde_data *pde_data;
  
  	pde_data = kmalloc(sizeof(*pde_data), GFP_KERNEL);
  	if (!pde_data)
  		return NULL;
  
  	pde_data->res_ptr = ptr;
  	pde_data->res_size = size;
  	return pde_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
111
  }
2f7dd07ec   Finn Thain   nubus: Rework /pr...
112
  static int nubus_proc_rsrc_show(struct seq_file *m, void *v)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
113
  {
2f7dd07ec   Finn Thain   nubus: Rework /pr...
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
  	struct inode *inode = m->private;
  	struct nubus_proc_pde_data *pde_data;
  
  	pde_data = PDE_DATA(inode);
  	if (!pde_data)
  		return 0;
  
  	if (pde_data->res_size > m->size)
  		return -EFBIG;
  
  	if (pde_data->res_size) {
  		int lanes = (int)proc_get_parent_data(inode);
  		struct nubus_dirent ent;
  
  		if (!lanes)
  			return 0;
  
  		ent.mask = lanes;
  		ent.base = pde_data->res_ptr;
  		ent.data = 0;
  		nubus_seq_write_rsrc_mem(m, &ent, pde_data->res_size);
  	} else {
  		unsigned int data = (unsigned int)pde_data->res_ptr;
  
  		seq_putc(m, data >> 16);
  		seq_putc(m, data >> 8);
  		seq_putc(m, data >> 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
141
  	}
2f7dd07ec   Finn Thain   nubus: Rework /pr...
142
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
143
  }
2f7dd07ec   Finn Thain   nubus: Rework /pr...
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
  static int nubus_proc_rsrc_open(struct inode *inode, struct file *file)
  {
  	return single_open(file, nubus_proc_rsrc_show, inode);
  }
  
  static const struct file_operations nubus_proc_rsrc_fops = {
  	.open		= nubus_proc_rsrc_open,
  	.read		= seq_read,
  	.llseek		= seq_lseek,
  	.release	= single_release,
  };
  
  void nubus_proc_add_rsrc_mem(struct proc_dir_entry *procdir,
  			     const struct nubus_dirent *ent,
  			     unsigned int size)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
159
  {
2f828fb21   Finn Thain   nubus: Avoid arra...
160
  	char name[9];
2f7dd07ec   Finn Thain   nubus: Rework /pr...
161
  	struct nubus_proc_pde_data *pde_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
162

2f7dd07ec   Finn Thain   nubus: Rework /pr...
163
164
  	if (!procdir)
  		return;
6c8b89ea5   Finn Thain   nubus: Call proc_...
165

2f7dd07ec   Finn Thain   nubus: Rework /pr...
166
167
168
169
170
171
172
173
  	snprintf(name, sizeof(name), "%x", ent->type);
  	if (size)
  		pde_data = nubus_proc_alloc_pde_data(nubus_dirptr(ent), size);
  	else
  		pde_data = NULL;
  	proc_create_data(name, S_IFREG | 0444, procdir,
  			 &nubus_proc_rsrc_fops, pde_data);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
174

2f7dd07ec   Finn Thain   nubus: Rework /pr...
175
176
177
178
179
  void nubus_proc_add_rsrc(struct proc_dir_entry *procdir,
  			 const struct nubus_dirent *ent)
  {
  	char name[9];
  	unsigned char *data = (unsigned char *)ent->data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
180

2f7dd07ec   Finn Thain   nubus: Rework /pr...
181
182
183
184
185
186
187
  	if (!procdir)
  		return;
  
  	snprintf(name, sizeof(name), "%x", ent->type);
  	proc_create_data(name, S_IFREG | 0444, procdir,
  			 &nubus_proc_rsrc_fops,
  			 nubus_proc_alloc_pde_data(data, 0));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
188
  }
11db656ad   David Howells   nubus: Don't use ...
189
190
191
  /*
   * /proc/nubus stuff
   */
11db656ad   David Howells   nubus: Don't use ...
192
193
194
  
  static int nubus_proc_open(struct inode *inode, struct file *file)
  {
7f86c765a   Finn Thain   nubus: Add suppor...
195
  	return single_open(file, nubus_proc_show, NULL);
11db656ad   David Howells   nubus: Don't use ...
196
197
198
199
200
201
  }
  
  static const struct file_operations nubus_proc_fops = {
  	.open		= nubus_proc_open,
  	.read		= seq_read,
  	.llseek		= seq_lseek,
7f86c765a   Finn Thain   nubus: Add suppor...
202
  	.release	= single_release,
11db656ad   David Howells   nubus: Don't use ...
203
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
204
205
  void __init nubus_proc_init(void)
  {
11db656ad   David Howells   nubus: Don't use ...
206
  	proc_create("nubus", 0, NULL, &nubus_proc_fops);
9c37066d8   Alexey Dobriyan   proc: remove proc...
207
  	proc_bus_nubus_dir = proc_mkdir("bus/nubus", NULL);
2f7dd07ec   Finn Thain   nubus: Rework /pr...
208
209
  	if (!proc_bus_nubus_dir)
  		return;
076ec04b8   Alexey Dobriyan   proc: convert /pr...
210
  	proc_create("devices", 0, proc_bus_nubus_dir, &nubus_devices_proc_fops);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
211
  }