1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * RapidIO sysfs attributes and support
5 * Copyright 2005 MontaVista Software, Inc.
6 * Matt Porter <mporter@kernel.crashing.org>
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>
18 #define rio_config_attr(field, format_string) \
20 field##_show(struct device *dev, struct device_attribute *attr, char *buf) \
22 struct rio_dev *rdev = to_rio_dev(dev); \
24 return sprintf(buf, format_string, rdev->field); \
26 static DEVICE_ATTR_RO(field);
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");
37 static ssize_t
routes_show(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
39 struct rio_dev
*rdev
= to_rio_dev(dev
);
43 for (i
= 0; i
< RIO_MAX_ROUTE_ENTRIES(rdev
->net
->hport
->sys_size
);
45 if (rdev
->rswitch
->route_table
[i
] == RIO_INVALID_ROUTE
)
48 sprintf(str
, "%04x %02x\n", i
,
49 rdev
->rswitch
->route_table
[i
]);
54 static DEVICE_ATTR_RO(routes
);
56 static ssize_t
lprev_show(struct device
*dev
,
57 struct device_attribute
*attr
, char *buf
)
59 struct rio_dev
*rdev
= to_rio_dev(dev
);
61 return sprintf(buf
, "%s\n",
62 (rdev
->prev
) ? rio_name(rdev
->prev
) : "root");
64 static DEVICE_ATTR_RO(lprev
);
66 static ssize_t
lnext_show(struct device
*dev
,
67 struct device_attribute
*attr
, char *buf
)
69 struct rio_dev
*rdev
= to_rio_dev(dev
);
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
]));
79 str
+= sprintf(str
, "null\n");
85 static DEVICE_ATTR_RO(lnext
);
87 static ssize_t
modalias_show(struct device
*dev
,
88 struct device_attribute
*attr
, char *buf
)
90 struct rio_dev
*rdev
= to_rio_dev(dev
);
92 return sprintf(buf
, "rapidio:v%04Xd%04Xav%04Xad%04X\n",
93 rdev
->vid
, rdev
->did
, rdev
->asm_vid
, rdev
->asm_did
);
95 static DEVICE_ATTR_RO(modalias
);
97 static struct attribute
*rio_dev_attrs
[] = {
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
,
108 /* Switch-only attributes */
109 &dev_attr_routes
.attr
,
110 &dev_attr_lnext
.attr
,
111 &dev_attr_hopcount
.attr
,
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
)
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
;
125 /* Several chips lock up trying to read undefined config space */
126 if (capable(CAP_SYS_ADMIN
))
127 size
= RIO_MAINT_SPACE_SZ
;
131 if (off
+ count
> size
) {
138 if ((off
& 1) && size
) {
140 rio_read_config_8(dev
, off
, &val
);
141 data
[off
- init_off
] = val
;
146 if ((off
& 3) && size
> 2) {
148 rio_read_config_16(dev
, off
, &val
);
149 data
[off
- init_off
] = (val
>> 8) & 0xff;
150 data
[off
- init_off
+ 1] = val
& 0xff;
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;
168 rio_read_config_16(dev
, off
, &val
);
169 data
[off
- init_off
] = (val
>> 8) & 0xff;
170 data
[off
- init_off
+ 1] = val
& 0xff;
177 rio_read_config_8(dev
, off
, &val
);
178 data
[off
- init_off
] = val
;
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
)
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
;
196 if (off
>= RIO_MAINT_SPACE_SZ
)
198 if (off
+ count
> RIO_MAINT_SPACE_SZ
) {
199 size
= RIO_MAINT_SPACE_SZ
- off
;
203 if ((off
& 1) && size
) {
204 rio_write_config_8(dev
, off
, data
[off
- init_off
]);
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
);
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
);
228 u16 val
= data
[off
- init_off
+ 1];
229 val
|= (u16
) data
[off
- init_off
] << 8;
230 rio_write_config_16(dev
, off
, val
);
236 rio_write_config_8(dev
, off
, data
[off
- init_off
]);
244 static struct bin_attribute rio_config_attr
= {
247 .mode
= S_IRUGO
| S_IWUSR
,
249 .size
= RIO_MAINT_SPACE_SZ
,
250 .read
= rio_read_config
,
251 .write
= rio_write_config
,
254 static struct bin_attribute
*rio_dev_bin_attrs
[] = {
259 static umode_t
rio_dev_is_attr_visible(struct kobject
*kobj
,
260 struct attribute
*attr
, int n
)
262 struct rio_dev
*rdev
= to_rio_dev(kobj_to_dev(kobj
));
263 umode_t mode
= attr
->mode
;
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
)) {
270 * Hide switch-specific attributes for a non-switch device.
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
,
284 const struct attribute_group
*rio_dev_groups
[] = {
289 static ssize_t
scan_store(struct bus_type
*bus
, const char *buf
, size_t count
)
294 if (kstrtol(buf
, 0, &val
) < 0)
297 if (val
== RIO_MPORT_ANY
) {
298 rc
= rio_init_mports();
302 if (val
< 0 || val
>= RIO_MAX_MPORTS
)
305 rc
= rio_mport_scan((int)val
);
312 static BUS_ATTR_WO(scan
);
314 static struct attribute
*rio_bus_attrs
[] = {
319 static const struct attribute_group rio_bus_group
= {
320 .attrs
= rio_bus_attrs
,
323 const struct attribute_group
*rio_bus_groups
[] = {
329 port_destid_show(struct device
*dev
, struct device_attribute
*attr
,
332 struct rio_mport
*mport
= to_rio_mport(dev
);
335 return sprintf(buf
, "0x%04x\n", mport
->host_deviceid
);
339 static DEVICE_ATTR_RO(port_destid
);
341 static ssize_t
sys_size_show(struct device
*dev
, struct device_attribute
*attr
,
344 struct rio_mport
*mport
= to_rio_mport(dev
);
347 return sprintf(buf
, "%u\n", mport
->sys_size
);
351 static DEVICE_ATTR_RO(sys_size
);
353 static struct attribute
*rio_mport_attrs
[] = {
354 &dev_attr_port_destid
.attr
,
355 &dev_attr_sys_size
.attr
,
359 static const struct attribute_group rio_mport_group
= {
360 .attrs
= rio_mport_attrs
,
363 const struct attribute_group
*rio_mport_groups
[] = {