Blame view

drivers/rapidio/rio-sysfs.c 6.71 KB
394b701ce   Matt Porter   [PATCH] RapidIO s...
1
2
3
4
5
6
7
8
9
10
11
  /*
   * RapidIO sysfs attributes and support
   *
   * Copyright 2005 MontaVista Software, Inc.
   * Matt Porter <mporter@kernel.crashing.org>
   *
   * This program is free software; you can redistribute  it and/or modify it
   * under  the terms of  the GNU General  Public License as published by the
   * Free Software Foundation;  either version 2 of the  License, or (at your
   * option) any later version.
   */
394b701ce   Matt Porter   [PATCH] RapidIO s...
12
13
14
15
  #include <linux/kernel.h>
  #include <linux/rio.h>
  #include <linux/rio_drv.h>
  #include <linux/stat.h>
388b78adc   Alexandre Bounine   rapidio: modify c...
16
  #include <linux/capability.h>
394b701ce   Matt Porter   [PATCH] RapidIO s...
17
18
19
20
21
22
  
  #include "rio.h"
  
  /* Sysfs support */
  #define rio_config_attr(field, format_string)					\
  static ssize_t								\
6978bbc09   Matt Porter   [PATCH] rapidio: ...
23
  field##_show(struct device *dev, struct device_attribute *attr, char *buf)			\
394b701ce   Matt Porter   [PATCH] RapidIO s...
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
  {									\
  	struct rio_dev *rdev = to_rio_dev(dev);				\
  									\
  	return sprintf(buf, format_string, rdev->field);		\
  }									\
  
  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 ...
42
43
44
45
  rio_config_attr(destid, "0x%04x
  ");
  rio_config_attr(hopcount, "0x%02x
  ");
394b701ce   Matt Porter   [PATCH] RapidIO s...
46

6978bbc09   Matt Porter   [PATCH] rapidio: ...
47
  static ssize_t routes_show(struct device *dev, struct device_attribute *attr, char *buf)
394b701ce   Matt Porter   [PATCH] RapidIO s...
48
49
50
51
  {
  	struct rio_dev *rdev = to_rio_dev(dev);
  	char *str = buf;
  	int i;
e04232360   Zhang Wei   [RAPIDIO] Auto-pr...
52
53
  	for (i = 0; i < RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size);
  			i++) {
394b701ce   Matt Porter   [PATCH] RapidIO s...
54
55
56
57
58
59
60
  		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...
61
62
  	return (str - buf);
  }
cd8b974fa   Alexandre Bounine   rapidio: add new ...
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
  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");
  }
  
  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;
  }
394b701ce   Matt Porter   [PATCH] RapidIO s...
94
95
96
97
98
99
100
  struct device_attribute rio_dev_attrs[] = {
  	__ATTR_RO(did),
  	__ATTR_RO(vid),
  	__ATTR_RO(device_rev),
  	__ATTR_RO(asm_did),
  	__ATTR_RO(asm_vid),
  	__ATTR_RO(asm_rev),
cd8b974fa   Alexandre Bounine   rapidio: add new ...
101
102
  	__ATTR_RO(lprev),
  	__ATTR_RO(destid),
394b701ce   Matt Porter   [PATCH] RapidIO s...
103
104
  	__ATTR_NULL,
  };
ac38d7232   Alexandre Bounine   rapidio: modify s...
105
  static DEVICE_ATTR(routes, S_IRUGO, routes_show, NULL);
cd8b974fa   Alexandre Bounine   rapidio: add new ...
106
107
  static DEVICE_ATTR(lnext, S_IRUGO, lnext_show, NULL);
  static DEVICE_ATTR(hopcount, S_IRUGO, hopcount_show, NULL);
ac38d7232   Alexandre Bounine   rapidio: modify s...
108

394b701ce   Matt Porter   [PATCH] RapidIO s...
109
  static ssize_t
2c3c8bea6   Chris Wright   sysfs: add struct...
110
111
  rio_read_config(struct file *filp, struct kobject *kobj,
  		struct bin_attribute *bin_attr,
91a690295   Zhang Rui   sysfs: add parame...
112
  		char *buf, loff_t off, size_t count)
394b701ce   Matt Porter   [PATCH] RapidIO s...
113
114
115
116
117
118
119
120
121
  {
  	struct rio_dev *dev =
  	    to_rio_dev(container_of(kobj, struct device, kobj));
  	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...
122
  		size = RIO_MAINT_SPACE_SZ;
394b701ce   Matt Porter   [PATCH] RapidIO s...
123

fe41947e1   Alexandre Bounine   rapidio: fix sysf...
124
  	if (off >= size)
394b701ce   Matt Porter   [PATCH] RapidIO s...
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
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
  		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...
182
183
  rio_write_config(struct file *filp, struct kobject *kobj,
  		 struct bin_attribute *bin_attr,
91a690295   Zhang Rui   sysfs: add parame...
184
  		 char *buf, loff_t off, size_t count)
394b701ce   Matt Porter   [PATCH] RapidIO s...
185
186
187
188
189
190
  {
  	struct rio_dev *dev =
  	    to_rio_dev(container_of(kobj, struct device, kobj));
  	unsigned int size = count;
  	loff_t init_off = off;
  	u8 *data = (u8 *) buf;
fe41947e1   Alexandre Bounine   rapidio: fix sysf...
191
  	if (off >= RIO_MAINT_SPACE_SZ)
394b701ce   Matt Porter   [PATCH] RapidIO s...
192
  		return 0;
fe41947e1   Alexandre Bounine   rapidio: fix sysf...
193
194
  	if (off + count > RIO_MAINT_SPACE_SZ) {
  		size = RIO_MAINT_SPACE_SZ - off;
394b701ce   Matt Porter   [PATCH] RapidIO s...
195
196
197
198
199
200
201
202
203
204
205
206
207
208
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
  		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...
243
  		 },
fe41947e1   Alexandre Bounine   rapidio: fix sysf...
244
  	.size = RIO_MAINT_SPACE_SZ,
394b701ce   Matt Porter   [PATCH] RapidIO s...
245
246
247
248
249
250
251
252
253
254
255
256
  	.read = rio_read_config,
  	.write = rio_write_config,
  };
  
  /**
   * rio_create_sysfs_dev_files - create RIO specific sysfs files
   * @rdev: device whose entries should be created
   *
   * Create files when @rdev is added to sysfs.
   */
  int rio_create_sysfs_dev_files(struct rio_dev *rdev)
  {
5f28c5200   Yang Li   rio: warn_unused_...
257
  	int err = 0;
394b701ce   Matt Porter   [PATCH] RapidIO s...
258

ac38d7232   Alexandre Bounine   rapidio: modify s...
259
  	err = device_create_bin_file(&rdev->dev, &rio_config_attr);
ded057827   Alexandre Bounine   rapidio: integrat...
260
  	if (!err && (rdev->pef & RIO_PEF_SWITCH)) {
cd8b974fa   Alexandre Bounine   rapidio: add new ...
261
262
263
  		err |= device_create_file(&rdev->dev, &dev_attr_routes);
  		err |= device_create_file(&rdev->dev, &dev_attr_lnext);
  		err |= device_create_file(&rdev->dev, &dev_attr_hopcount);
ac38d7232   Alexandre Bounine   rapidio: modify s...
264
265
266
267
268
269
270
271
  		if (!err && rdev->rswitch->sw_sysfs)
  			err = rdev->rswitch->sw_sysfs(rdev, RIO_SW_SYSFS_CREATE);
  	}
  
  	if (err)
  		pr_warning("RIO: Failed to create attribute file(s) for %s
  ",
  			   rio_name(rdev));
5f28c5200   Yang Li   rio: warn_unused_...
272
273
  
  	return err;
394b701ce   Matt Porter   [PATCH] RapidIO s...
274
275
276
277
278
279
280
281
282
283
  }
  
  /**
   * rio_remove_sysfs_dev_files - cleanup RIO specific sysfs files
   * @rdev: device whose entries we should free
   *
   * Cleanup when @rdev is removed from sysfs.
   */
  void rio_remove_sysfs_dev_files(struct rio_dev *rdev)
  {
ac38d7232   Alexandre Bounine   rapidio: modify s...
284
  	device_remove_bin_file(&rdev->dev, &rio_config_attr);
ded057827   Alexandre Bounine   rapidio: integrat...
285
  	if (rdev->pef & RIO_PEF_SWITCH) {
ac38d7232   Alexandre Bounine   rapidio: modify s...
286
  		device_remove_file(&rdev->dev, &dev_attr_routes);
cd8b974fa   Alexandre Bounine   rapidio: add new ...
287
288
  		device_remove_file(&rdev->dev, &dev_attr_lnext);
  		device_remove_file(&rdev->dev, &dev_attr_hopcount);
ac38d7232   Alexandre Bounine   rapidio: modify s...
289
290
291
  		if (rdev->rswitch->sw_sysfs)
  			rdev->rswitch->sw_sysfs(rdev, RIO_SW_SYSFS_REMOVE);
  	}
394b701ce   Matt Porter   [PATCH] RapidIO s...
292
  }