xref: /linux/drivers/rapidio/rio-sysfs.c (revision 2f804aca48322f02a8f44cca540663845ee80fb1)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * RapidIO sysfs attributes and support
4  *
5  * Copyright 2005 MontaVista Software, Inc.
6  * Matt Porter <mporter@kernel.crashing.org>
7  */
8 
9 #include <linux/kernel.h>
10 #include <linux/rio.h>
11 #include <linux/rio_drv.h>
12 #include <linux/stat.h>
13 #include <linux/capability.h>
14 
15 #include "rio.h"
16 
17 /* Sysfs support */
18 #define rio_config_attr(field, format_string)					\
19 static ssize_t								\
20 field##_show(struct device *dev, struct device_attribute *attr, char *buf)			\
21 {									\
22 	struct rio_dev *rdev = to_rio_dev(dev);				\
23 									\
24 	return sprintf(buf, format_string, rdev->field);		\
25 }									\
26 static DEVICE_ATTR_RO(field);
27 
28 rio_config_attr(did, "0x%04x\n");
29 rio_config_attr(vid, "0x%04x\n");
30 rio_config_attr(device_rev, "0x%08x\n");
31 rio_config_attr(asm_did, "0x%04x\n");
32 rio_config_attr(asm_vid, "0x%04x\n");
33 rio_config_attr(asm_rev, "0x%04x\n");
34 rio_config_attr(destid, "0x%04x\n");
35 rio_config_attr(hopcount, "0x%02x\n");
36 
37 static ssize_t routes_show(struct device *dev, struct device_attribute *attr, char *buf)
38 {
39 	struct rio_dev *rdev = to_rio_dev(dev);
40 	char *str = buf;
41 	int i;
42 
43 	for (i = 0; i < RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size);
44 			i++) {
45 		if (rdev->rswitch->route_table[i] == RIO_INVALID_ROUTE)
46 			continue;
47 		str +=
48 		    sprintf(str, "%04x %02x\n", i,
49 			    rdev->rswitch->route_table[i]);
50 	}
51 
52 	return (str - buf);
53 }
54 static DEVICE_ATTR_RO(routes);
55 
56 static ssize_t lprev_show(struct device *dev,
57 			  struct device_attribute *attr, char *buf)
58 {
59 	struct rio_dev *rdev = to_rio_dev(dev);
60 
61 	return sprintf(buf, "%s\n",
62 			(rdev->prev) ? rio_name(rdev->prev) : "root");
63 }
64 static DEVICE_ATTR_RO(lprev);
65 
66 static ssize_t lnext_show(struct device *dev,
67 			  struct device_attribute *attr, char *buf)
68 {
69 	struct rio_dev *rdev = to_rio_dev(dev);
70 	char *str = buf;
71 	int i;
72 
73 	if (rdev->pef & RIO_PEF_SWITCH) {
74 		for (i = 0; i < RIO_GET_TOTAL_PORTS(rdev->swpinfo); i++) {
75 			if (rdev->rswitch->nextdev[i])
76 				str += sprintf(str, "%s\n",
77 					rio_name(rdev->rswitch->nextdev[i]));
78 			else
79 				str += sprintf(str, "null\n");
80 		}
81 	}
82 
83 	return str - buf;
84 }
85 static DEVICE_ATTR_RO(lnext);
86 
87 static ssize_t modalias_show(struct device *dev,
88 			     struct device_attribute *attr, char *buf)
89 {
90 	struct rio_dev *rdev = to_rio_dev(dev);
91 
92 	return sprintf(buf, "rapidio:v%04Xd%04Xav%04Xad%04X\n",
93 		       rdev->vid, rdev->did, rdev->asm_vid, rdev->asm_did);
94 }
95 static DEVICE_ATTR_RO(modalias);
96 
97 static struct attribute *rio_dev_attrs[] = {
98 	&dev_attr_did.attr,
99 	&dev_attr_vid.attr,
100 	&dev_attr_device_rev.attr,
101 	&dev_attr_asm_did.attr,
102 	&dev_attr_asm_vid.attr,
103 	&dev_attr_asm_rev.attr,
104 	&dev_attr_lprev.attr,
105 	&dev_attr_destid.attr,
106 	&dev_attr_modalias.attr,
107 
108 	/* Switch-only attributes */
109 	&dev_attr_routes.attr,
110 	&dev_attr_lnext.attr,
111 	&dev_attr_hopcount.attr,
112 	NULL,
113 };
114 
115 static ssize_t
116 rio_read_config(struct file *filp, struct kobject *kobj,
117 		struct bin_attribute *bin_attr,
118 		char *buf, loff_t off, size_t count)
119 {
120 	struct rio_dev *dev = to_rio_dev(kobj_to_dev(kobj));
121 	unsigned int size = 0x100;
122 	loff_t init_off = off;
123 	u8 *data = (u8 *) buf;
124 
125 	/* Several chips lock up trying to read undefined config space */
126 	if (capable(CAP_SYS_ADMIN))
127 		size = RIO_MAINT_SPACE_SZ;
128 
129 	if (off >= size)
130 		return 0;
131 	if (off + count > size) {
132 		size -= off;
133 		count = size;
134 	} else {
135 		size = count;
136 	}
137 
138 	if ((off & 1) && size) {
139 		u8 val;
140 		rio_read_config_8(dev, off, &val);
141 		data[off - init_off] = val;
142 		off++;
143 		size--;
144 	}
145 
146 	if ((off & 3) && size > 2) {
147 		u16 val;
148 		rio_read_config_16(dev, off, &val);
149 		data[off - init_off] = (val >> 8) & 0xff;
150 		data[off - init_off + 1] = val & 0xff;
151 		off += 2;
152 		size -= 2;
153 	}
154 
155 	while (size > 3) {
156 		u32 val;
157 		rio_read_config_32(dev, off, &val);
158 		data[off - init_off] = (val >> 24) & 0xff;
159 		data[off - init_off + 1] = (val >> 16) & 0xff;
160 		data[off - init_off + 2] = (val >> 8) & 0xff;
161 		data[off - init_off + 3] = val & 0xff;
162 		off += 4;
163 		size -= 4;
164 	}
165 
166 	if (size >= 2) {
167 		u16 val;
168 		rio_read_config_16(dev, off, &val);
169 		data[off - init_off] = (val >> 8) & 0xff;
170 		data[off - init_off + 1] = val & 0xff;
171 		off += 2;
172 		size -= 2;
173 	}
174 
175 	if (size > 0) {
176 		u8 val;
177 		rio_read_config_8(dev, off, &val);
178 		data[off - init_off] = val;
179 		off++;
180 		--size;
181 	}
182 
183 	return count;
184 }
185 
186 static ssize_t
187 rio_write_config(struct file *filp, struct kobject *kobj,
188 		 struct bin_attribute *bin_attr,
189 		 char *buf, loff_t off, size_t count)
190 {
191 	struct rio_dev *dev = to_rio_dev(kobj_to_dev(kobj));
192 	unsigned int size = count;
193 	loff_t init_off = off;
194 	u8 *data = (u8 *) buf;
195 
196 	if (off >= RIO_MAINT_SPACE_SZ)
197 		return 0;
198 	if (off + count > RIO_MAINT_SPACE_SZ) {
199 		size = RIO_MAINT_SPACE_SZ - off;
200 		count = size;
201 	}
202 
203 	if ((off & 1) && size) {
204 		rio_write_config_8(dev, off, data[off - init_off]);
205 		off++;
206 		size--;
207 	}
208 
209 	if ((off & 3) && (size > 2)) {
210 		u16 val = data[off - init_off + 1];
211 		val |= (u16) data[off - init_off] << 8;
212 		rio_write_config_16(dev, off, val);
213 		off += 2;
214 		size -= 2;
215 	}
216 
217 	while (size > 3) {
218 		u32 val = data[off - init_off + 3];
219 		val |= (u32) data[off - init_off + 2] << 8;
220 		val |= (u32) data[off - init_off + 1] << 16;
221 		val |= (u32) data[off - init_off] << 24;
222 		rio_write_config_32(dev, off, val);
223 		off += 4;
224 		size -= 4;
225 	}
226 
227 	if (size >= 2) {
228 		u16 val = data[off - init_off + 1];
229 		val |= (u16) data[off - init_off] << 8;
230 		rio_write_config_16(dev, off, val);
231 		off += 2;
232 		size -= 2;
233 	}
234 
235 	if (size) {
236 		rio_write_config_8(dev, off, data[off - init_off]);
237 		off++;
238 		--size;
239 	}
240 
241 	return count;
242 }
243 
244 static struct bin_attribute rio_config_attr = {
245 	.attr = {
246 		 .name = "config",
247 		 .mode = S_IRUGO | S_IWUSR,
248 		 },
249 	.size = RIO_MAINT_SPACE_SZ,
250 	.read = rio_read_config,
251 	.write = rio_write_config,
252 };
253 
254 static struct bin_attribute *rio_dev_bin_attrs[] = {
255 	&rio_config_attr,
256 	NULL,
257 };
258 
259 static umode_t rio_dev_is_attr_visible(struct kobject *kobj,
260 				       struct attribute *attr, int n)
261 {
262 	struct rio_dev *rdev = to_rio_dev(kobj_to_dev(kobj));
263 	umode_t mode = attr->mode;
264 
265 	if (!(rdev->pef & RIO_PEF_SWITCH) &&
266 	    (attr == &dev_attr_routes.attr ||
267 	     attr == &dev_attr_lnext.attr ||
268 	     attr == &dev_attr_hopcount.attr)) {
269 		/*
270 		 * Hide switch-specific attributes for a non-switch device.
271 		 */
272 		mode = 0;
273 	}
274 
275 	return mode;
276 }
277 
278 static const struct attribute_group rio_dev_group = {
279 	.attrs		= rio_dev_attrs,
280 	.is_visible	= rio_dev_is_attr_visible,
281 	.bin_attrs	= rio_dev_bin_attrs,
282 };
283 
284 const struct attribute_group *rio_dev_groups[] = {
285 	&rio_dev_group,
286 	NULL,
287 };
288 
289 static ssize_t scan_store(const struct bus_type *bus, const char *buf, size_t count)
290 {
291 	long val;
292 	int rc;
293 
294 	if (kstrtol(buf, 0, &val) < 0)
295 		return -EINVAL;
296 
297 	if (val == RIO_MPORT_ANY) {
298 		rc = rio_init_mports();
299 		goto exit;
300 	}
301 
302 	if (val < 0 || val >= RIO_MAX_MPORTS)
303 		return -EINVAL;
304 
305 	rc = rio_mport_scan((int)val);
306 exit:
307 	if (!rc)
308 		rc = count;
309 
310 	return rc;
311 }
312 static BUS_ATTR_WO(scan);
313 
314 static struct attribute *rio_bus_attrs[] = {
315 	&bus_attr_scan.attr,
316 	NULL,
317 };
318 
319 static const struct attribute_group rio_bus_group = {
320 	.attrs = rio_bus_attrs,
321 };
322 
323 const struct attribute_group *rio_bus_groups[] = {
324 	&rio_bus_group,
325 	NULL,
326 };
327 
328 static ssize_t
329 port_destid_show(struct device *dev, struct device_attribute *attr,
330 		 char *buf)
331 {
332 	struct rio_mport *mport = to_rio_mport(dev);
333 
334 	if (mport)
335 		return sprintf(buf, "0x%04x\n", mport->host_deviceid);
336 	else
337 		return -ENODEV;
338 }
339 static DEVICE_ATTR_RO(port_destid);
340 
341 static ssize_t sys_size_show(struct device *dev, struct device_attribute *attr,
342 			   char *buf)
343 {
344 	struct rio_mport *mport = to_rio_mport(dev);
345 
346 	if (mport)
347 		return sprintf(buf, "%u\n", mport->sys_size);
348 	else
349 		return -ENODEV;
350 }
351 static DEVICE_ATTR_RO(sys_size);
352 
353 static struct attribute *rio_mport_attrs[] = {
354 	&dev_attr_port_destid.attr,
355 	&dev_attr_sys_size.attr,
356 	NULL,
357 };
358 
359 static const struct attribute_group rio_mport_group = {
360 	.attrs = rio_mport_attrs,
361 };
362 
363 const struct attribute_group *rio_mport_groups[] = {
364 	&rio_mport_group,
365 	NULL,
366 };
367