Blame view

drivers/rapidio/rio-sysfs.c 7.74 KB
2874c5fd2   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-or-later
394b701ce   Matt Porter   [PATCH] RapidIO s...
2
3
4
5
6
  /*
   * RapidIO sysfs attributes and support
   *
   * Copyright 2005 MontaVista Software, Inc.
   * Matt Porter <mporter@kernel.crashing.org>
394b701ce   Matt Porter   [PATCH] RapidIO s...
7
   */
394b701ce   Matt Porter   [PATCH] RapidIO s...
8
9
10
11
  #include <linux/kernel.h>
  #include <linux/rio.h>
  #include <linux/rio_drv.h>
  #include <linux/stat.h>
388b78adc   Alexandre Bounine   rapidio: modify c...
12
  #include <linux/capability.h>
394b701ce   Matt Porter   [PATCH] RapidIO s...
13
14
15
16
17
18
  
  #include "rio.h"
  
  /* Sysfs support */
  #define rio_config_attr(field, format_string)					\
  static ssize_t								\
6978bbc09   Matt Porter   [PATCH] rapidio: ...
19
  field##_show(struct device *dev, struct device_attribute *attr, char *buf)			\
394b701ce   Matt Porter   [PATCH] RapidIO s...
20
21
22
23
24
  {									\
  	struct rio_dev *rdev = to_rio_dev(dev);				\
  									\
  	return sprintf(buf, format_string, rdev->field);		\
  }									\
6d39c80b1   Greg Kroah-Hartman   rapidio: convert ...
25
  static DEVICE_ATTR_RO(field);
394b701ce   Matt Porter   [PATCH] RapidIO s...
26
27
28
29
30
31
32
33
34
35
36
37
38
  
  rio_config_attr(did, "0x%04x
  ");
  rio_config_attr(vid, "0x%04x
  ");
  rio_config_attr(device_rev, "0x%08x
  ");
  rio_config_attr(asm_did, "0x%04x
  ");
  rio_config_attr(asm_vid, "0x%04x
  ");
  rio_config_attr(asm_rev, "0x%04x
  ");
cd8b974fa   Alexandre Bounine   rapidio: add new ...
39
40
41
42
  rio_config_attr(destid, "0x%04x
  ");
  rio_config_attr(hopcount, "0x%02x
  ");
394b701ce   Matt Porter   [PATCH] RapidIO s...
43

6978bbc09   Matt Porter   [PATCH] rapidio: ...
44
  static ssize_t routes_show(struct device *dev, struct device_attribute *attr, char *buf)
394b701ce   Matt Porter   [PATCH] RapidIO s...
45
46
47
48
  {
  	struct rio_dev *rdev = to_rio_dev(dev);
  	char *str = buf;
  	int i;
e04232360   Zhang Wei   [RAPIDIO] Auto-pr...
49
50
  	for (i = 0; i < RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size);
  			i++) {
394b701ce   Matt Porter   [PATCH] RapidIO s...
51
52
53
54
55
56
57
  		if (rdev->rswitch->route_table[i] == RIO_INVALID_ROUTE)
  			continue;
  		str +=
  		    sprintf(str, "%04x %02x
  ", i,
  			    rdev->rswitch->route_table[i]);
  	}
394b701ce   Matt Porter   [PATCH] RapidIO s...
58
59
  	return (str - buf);
  }
6d39c80b1   Greg Kroah-Hartman   rapidio: convert ...
60
  static DEVICE_ATTR_RO(routes);
394b701ce   Matt Porter   [PATCH] RapidIO s...
61

cd8b974fa   Alexandre Bounine   rapidio: add new ...
62
63
64
65
66
67
68
69
70
  static ssize_t lprev_show(struct device *dev,
  			  struct device_attribute *attr, char *buf)
  {
  	struct rio_dev *rdev = to_rio_dev(dev);
  
  	return sprintf(buf, "%s
  ",
  			(rdev->prev) ? rio_name(rdev->prev) : "root");
  }
6d39c80b1   Greg Kroah-Hartman   rapidio: convert ...
71
  static DEVICE_ATTR_RO(lprev);
cd8b974fa   Alexandre Bounine   rapidio: add new ...
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
  
  static ssize_t lnext_show(struct device *dev,
  			  struct device_attribute *attr, char *buf)
  {
  	struct rio_dev *rdev = to_rio_dev(dev);
  	char *str = buf;
  	int i;
  
  	if (rdev->pef & RIO_PEF_SWITCH) {
  		for (i = 0; i < RIO_GET_TOTAL_PORTS(rdev->swpinfo); i++) {
  			if (rdev->rswitch->nextdev[i])
  				str += sprintf(str, "%s
  ",
  					rio_name(rdev->rswitch->nextdev[i]));
  			else
  				str += sprintf(str, "null
  ");
  		}
  	}
  
  	return str - buf;
  }
6d39c80b1   Greg Kroah-Hartman   rapidio: convert ...
94
  static DEVICE_ATTR_RO(lnext);
cd8b974fa   Alexandre Bounine   rapidio: add new ...
95

3bdbb62fe   Alexandre Bounine   rapidio: add udev...
96
97
98
99
100
101
102
103
104
  static ssize_t modalias_show(struct device *dev,
  			     struct device_attribute *attr, char *buf)
  {
  	struct rio_dev *rdev = to_rio_dev(dev);
  
  	return sprintf(buf, "rapidio:v%04Xd%04Xav%04Xad%04X
  ",
  		       rdev->vid, rdev->did, rdev->asm_vid, rdev->asm_did);
  }
6d39c80b1   Greg Kroah-Hartman   rapidio: convert ...
105
106
107
108
109
110
111
112
113
114
115
116
  static DEVICE_ATTR_RO(modalias);
  
  static struct attribute *rio_dev_attrs[] = {
  	&dev_attr_did.attr,
  	&dev_attr_vid.attr,
  	&dev_attr_device_rev.attr,
  	&dev_attr_asm_did.attr,
  	&dev_attr_asm_vid.attr,
  	&dev_attr_asm_rev.attr,
  	&dev_attr_lprev.attr,
  	&dev_attr_destid.attr,
  	&dev_attr_modalias.attr,
3bdbb62fe   Alexandre Bounine   rapidio: add udev...
117

70359c4a6   Dmitry Torokhov   rapidio: use is_v...
118
119
120
121
  	/* Switch-only attributes */
  	&dev_attr_routes.attr,
  	&dev_attr_lnext.attr,
  	&dev_attr_hopcount.attr,
6d39c80b1   Greg Kroah-Hartman   rapidio: convert ...
122
123
  	NULL,
  };
ac38d7232   Alexandre Bounine   rapidio: modify s...
124

394b701ce   Matt Porter   [PATCH] RapidIO s...
125
  static ssize_t
2c3c8bea6   Chris Wright   sysfs: add struct...
126
127
  rio_read_config(struct file *filp, struct kobject *kobj,
  		struct bin_attribute *bin_attr,
91a690295   Zhang Rui   sysfs: add parame...
128
  		char *buf, loff_t off, size_t count)
394b701ce   Matt Porter   [PATCH] RapidIO s...
129
  {
a253f1eee   Geliang Tang   rapidio: use kobj...
130
  	struct rio_dev *dev = to_rio_dev(kobj_to_dev(kobj));
394b701ce   Matt Porter   [PATCH] RapidIO s...
131
132
133
134
135
136
  	unsigned int size = 0x100;
  	loff_t init_off = off;
  	u8 *data = (u8 *) buf;
  
  	/* Several chips lock up trying to read undefined config space */
  	if (capable(CAP_SYS_ADMIN))
fe41947e1   Alexandre Bounine   rapidio: fix sysf...
137
  		size = RIO_MAINT_SPACE_SZ;
394b701ce   Matt Porter   [PATCH] RapidIO s...
138

fe41947e1   Alexandre Bounine   rapidio: fix sysf...
139
  	if (off >= size)
394b701ce   Matt Porter   [PATCH] RapidIO s...
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
  		return 0;
  	if (off + count > size) {
  		size -= off;
  		count = size;
  	} else {
  		size = count;
  	}
  
  	if ((off & 1) && size) {
  		u8 val;
  		rio_read_config_8(dev, off, &val);
  		data[off - init_off] = val;
  		off++;
  		size--;
  	}
  
  	if ((off & 3) && size > 2) {
  		u16 val;
  		rio_read_config_16(dev, off, &val);
  		data[off - init_off] = (val >> 8) & 0xff;
  		data[off - init_off + 1] = val & 0xff;
  		off += 2;
  		size -= 2;
  	}
  
  	while (size > 3) {
  		u32 val;
  		rio_read_config_32(dev, off, &val);
  		data[off - init_off] = (val >> 24) & 0xff;
  		data[off - init_off + 1] = (val >> 16) & 0xff;
  		data[off - init_off + 2] = (val >> 8) & 0xff;
  		data[off - init_off + 3] = val & 0xff;
  		off += 4;
  		size -= 4;
  	}
  
  	if (size >= 2) {
  		u16 val;
  		rio_read_config_16(dev, off, &val);
  		data[off - init_off] = (val >> 8) & 0xff;
  		data[off - init_off + 1] = val & 0xff;
  		off += 2;
  		size -= 2;
  	}
  
  	if (size > 0) {
  		u8 val;
  		rio_read_config_8(dev, off, &val);
  		data[off - init_off] = val;
  		off++;
  		--size;
  	}
  
  	return count;
  }
  
  static ssize_t
2c3c8bea6   Chris Wright   sysfs: add struct...
197
198
  rio_write_config(struct file *filp, struct kobject *kobj,
  		 struct bin_attribute *bin_attr,
91a690295   Zhang Rui   sysfs: add parame...
199
  		 char *buf, loff_t off, size_t count)
394b701ce   Matt Porter   [PATCH] RapidIO s...
200
  {
a253f1eee   Geliang Tang   rapidio: use kobj...
201
  	struct rio_dev *dev = to_rio_dev(kobj_to_dev(kobj));
394b701ce   Matt Porter   [PATCH] RapidIO s...
202
203
204
  	unsigned int size = count;
  	loff_t init_off = off;
  	u8 *data = (u8 *) buf;
fe41947e1   Alexandre Bounine   rapidio: fix sysf...
205
  	if (off >= RIO_MAINT_SPACE_SZ)
394b701ce   Matt Porter   [PATCH] RapidIO s...
206
  		return 0;
fe41947e1   Alexandre Bounine   rapidio: fix sysf...
207
208
  	if (off + count > RIO_MAINT_SPACE_SZ) {
  		size = RIO_MAINT_SPACE_SZ - off;
394b701ce   Matt Porter   [PATCH] RapidIO s...
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
  		count = size;
  	}
  
  	if ((off & 1) && size) {
  		rio_write_config_8(dev, off, data[off - init_off]);
  		off++;
  		size--;
  	}
  
  	if ((off & 3) && (size > 2)) {
  		u16 val = data[off - init_off + 1];
  		val |= (u16) data[off - init_off] << 8;
  		rio_write_config_16(dev, off, val);
  		off += 2;
  		size -= 2;
  	}
  
  	while (size > 3) {
  		u32 val = data[off - init_off + 3];
  		val |= (u32) data[off - init_off + 2] << 8;
  		val |= (u32) data[off - init_off + 1] << 16;
  		val |= (u32) data[off - init_off] << 24;
  		rio_write_config_32(dev, off, val);
  		off += 4;
  		size -= 4;
  	}
  
  	if (size >= 2) {
  		u16 val = data[off - init_off + 1];
  		val |= (u16) data[off - init_off] << 8;
  		rio_write_config_16(dev, off, val);
  		off += 2;
  		size -= 2;
  	}
  
  	if (size) {
  		rio_write_config_8(dev, off, data[off - init_off]);
  		off++;
  		--size;
  	}
  
  	return count;
  }
  
  static struct bin_attribute rio_config_attr = {
  	.attr = {
  		 .name = "config",
  		 .mode = S_IRUGO | S_IWUSR,
394b701ce   Matt Porter   [PATCH] RapidIO s...
257
  		 },
fe41947e1   Alexandre Bounine   rapidio: fix sysf...
258
  	.size = RIO_MAINT_SPACE_SZ,
394b701ce   Matt Porter   [PATCH] RapidIO s...
259
260
261
  	.read = rio_read_config,
  	.write = rio_write_config,
  };
70359c4a6   Dmitry Torokhov   rapidio: use is_v...
262
263
264
265
  static struct bin_attribute *rio_dev_bin_attrs[] = {
  	&rio_config_attr,
  	NULL,
  };
ac38d7232   Alexandre Bounine   rapidio: modify s...
266

70359c4a6   Dmitry Torokhov   rapidio: use is_v...
267
268
269
270
271
272
273
274
275
276
277
278
279
280
  static umode_t rio_dev_is_attr_visible(struct kobject *kobj,
  				       struct attribute *attr, int n)
  {
  	struct rio_dev *rdev = to_rio_dev(kobj_to_dev(kobj));
  	umode_t mode = attr->mode;
  
  	if (!(rdev->pef & RIO_PEF_SWITCH) &&
  	    (attr == &dev_attr_routes.attr ||
  	     attr == &dev_attr_lnext.attr ||
  	     attr == &dev_attr_hopcount.attr)) {
  		/*
  		 * Hide switch-specific attributes for a non-switch device.
  		 */
  		mode = 0;
ac38d7232   Alexandre Bounine   rapidio: modify s...
281
  	}
70359c4a6   Dmitry Torokhov   rapidio: use is_v...
282
  	return mode;
394b701ce   Matt Porter   [PATCH] RapidIO s...
283
  }
70359c4a6   Dmitry Torokhov   rapidio: use is_v...
284
285
286
287
288
289
290
291
292
293
  static const struct attribute_group rio_dev_group = {
  	.attrs		= rio_dev_attrs,
  	.is_visible	= rio_dev_is_attr_visible,
  	.bin_attrs	= rio_dev_bin_attrs,
  };
  
  const struct attribute_group *rio_dev_groups[] = {
  	&rio_dev_group,
  	NULL,
  };
bc8fcfea1   Alexandre Bounine   rapidio: add enum...
294

c9fbe769d   Greg Kroah-Hartman   rapidio: rio-sysf...
295
  static ssize_t scan_store(struct bus_type *bus, const char *buf, size_t count)
bc8fcfea1   Alexandre Bounine   rapidio: add enum...
296
297
  {
  	long val;
bc8fcfea1   Alexandre Bounine   rapidio: add enum...
298
299
300
301
302
303
304
305
306
307
308
309
  	int rc;
  
  	if (kstrtol(buf, 0, &val) < 0)
  		return -EINVAL;
  
  	if (val == RIO_MPORT_ANY) {
  		rc = rio_init_mports();
  		goto exit;
  	}
  
  	if (val < 0 || val >= RIO_MAX_MPORTS)
  		return -EINVAL;
9edbc30b4   Alexandre Bounine   rapidio: update e...
310
  	rc = rio_mport_scan((int)val);
bc8fcfea1   Alexandre Bounine   rapidio: add enum...
311
312
313
314
315
316
  exit:
  	if (!rc)
  		rc = count;
  
  	return rc;
  }
c9fbe769d   Greg Kroah-Hartman   rapidio: rio-sysf...
317
  static BUS_ATTR_WO(scan);
bc8fcfea1   Alexandre Bounine   rapidio: add enum...
318

ed1d2da28   Greg Kroah-Hartman   rapidio: convert ...
319
320
321
322
323
324
325
326
327
328
329
330
  static struct attribute *rio_bus_attrs[] = {
  	&bus_attr_scan.attr,
  	NULL,
  };
  
  static const struct attribute_group rio_bus_group = {
  	.attrs = rio_bus_attrs,
  };
  
  const struct attribute_group *rio_bus_groups[] = {
  	&rio_bus_group,
  	NULL,
bc8fcfea1   Alexandre Bounine   rapidio: add enum...
331
  };
2aaf308b9   Alexandre Bounine   rapidio: rework d...
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
  
  static ssize_t
  port_destid_show(struct device *dev, struct device_attribute *attr,
  		 char *buf)
  {
  	struct rio_mport *mport = to_rio_mport(dev);
  
  	if (mport)
  		return sprintf(buf, "0x%04x
  ", mport->host_deviceid);
  	else
  		return -ENODEV;
  }
  static DEVICE_ATTR_RO(port_destid);
  
  static ssize_t sys_size_show(struct device *dev, struct device_attribute *attr,
  			   char *buf)
  {
  	struct rio_mport *mport = to_rio_mport(dev);
  
  	if (mport)
  		return sprintf(buf, "%u
  ", mport->sys_size);
  	else
  		return -ENODEV;
  }
  static DEVICE_ATTR_RO(sys_size);
  
  static struct attribute *rio_mport_attrs[] = {
  	&dev_attr_port_destid.attr,
  	&dev_attr_sys_size.attr,
  	NULL,
  };
  
  static const struct attribute_group rio_mport_group = {
  	.attrs = rio_mport_attrs,
  };
  
  const struct attribute_group *rio_mport_groups[] = {
  	&rio_mport_group,
  	NULL,
  };