Merge tag 'tty-3.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
[deliverable/linux.git] / drivers / staging / dgrp / dgrp_sysfs.c
1 /*
2 * Copyright 2004 Digi International (www.digi.com)
3 * Scott H Kilau <Scott_Kilau at digi dot com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
12 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
13 * PURPOSE. See the GNU General Public License for more details.
14 *
15 */
16
17 #include "dgrp_common.h"
18
19 #include <linux/kernel.h>
20 #include <linux/module.h>
21 #include <linux/ctype.h>
22 #include <linux/string.h>
23 #include <linux/serial_reg.h>
24 #include <linux/pci.h>
25 #include <linux/kdev_t.h>
26
27
28 #define PORTSERVER_DIVIDEND 1843200
29 #define SERIAL_TYPE_NORMAL 1
30 #define SERIAL_TYPE_CALLOUT 2
31 #define SERIAL_TYPE_XPRINT 3
32
33
34 static struct class *dgrp_class;
35 static struct device *dgrp_class_nodes_dev;
36 static struct device *dgrp_class_global_settings_dev;
37
38
39 static ssize_t dgrp_class_version_show(struct class *class,
40 struct class_attribute *attr, char *buf)
41 {
42 return snprintf(buf, PAGE_SIZE, "%s\n", DIGI_VERSION);
43 }
44 static CLASS_ATTR(driver_version, 0400, dgrp_class_version_show, NULL);
45
46
47 static ssize_t dgrp_class_register_with_sysfs_show(struct device *c,
48 struct device_attribute *attr,
49 char *buf)
50 {
51 return snprintf(buf, PAGE_SIZE, "1\n");
52 }
53 static DEVICE_ATTR(register_with_sysfs, 0400,
54 dgrp_class_register_with_sysfs_show, NULL);
55
56
57 static ssize_t dgrp_class_pollrate_show(struct device *c,
58 struct device_attribute *attr,
59 char *buf)
60 {
61 return snprintf(buf, PAGE_SIZE, "%d\n", dgrp_poll_tick);
62 }
63
64 static ssize_t dgrp_class_pollrate_store(struct device *c,
65 struct device_attribute *attr,
66 const char *buf, size_t count)
67 {
68 sscanf(buf, "0x%x\n", &dgrp_poll_tick);
69 return count;
70 }
71 static DEVICE_ATTR(pollrate, 0600, dgrp_class_pollrate_show,
72 dgrp_class_pollrate_store);
73
74 static struct attribute *dgrp_sysfs_global_settings_entries[] = {
75 &dev_attr_pollrate.attr,
76 &dev_attr_register_with_sysfs.attr,
77 NULL
78 };
79
80
81 static struct attribute_group dgrp_global_settings_attribute_group = {
82 .name = NULL,
83 .attrs = dgrp_sysfs_global_settings_entries,
84 };
85
86
87
88 void dgrp_create_class_sysfs_files(void)
89 {
90 int ret = 0;
91 int max_majors = 1U << (32 - MINORBITS);
92
93 dgrp_class = class_create(THIS_MODULE, "digi_realport");
94 ret = class_create_file(dgrp_class, &class_attr_driver_version);
95
96 dgrp_class_global_settings_dev = device_create(dgrp_class, NULL,
97 MKDEV(0, max_majors + 1), NULL, "driver_settings");
98
99 ret = sysfs_create_group(&dgrp_class_global_settings_dev->kobj,
100 &dgrp_global_settings_attribute_group);
101 if (ret) {
102 pr_alert("%s: failed to create sysfs global settings device attributes.\n",
103 __func__);
104 sysfs_remove_group(&dgrp_class_global_settings_dev->kobj,
105 &dgrp_global_settings_attribute_group);
106 return;
107 }
108
109 dgrp_class_nodes_dev = device_create(dgrp_class, NULL,
110 MKDEV(0, max_majors + 2), NULL, "nodes");
111
112 }
113
114
115 void dgrp_remove_class_sysfs_files(void)
116 {
117 struct nd_struct *nd;
118 int max_majors = 1U << (32 - MINORBITS);
119
120 list_for_each_entry(nd, &nd_struct_list, list)
121 dgrp_remove_node_class_sysfs_files(nd);
122
123 sysfs_remove_group(&dgrp_class_global_settings_dev->kobj,
124 &dgrp_global_settings_attribute_group);
125
126 class_remove_file(dgrp_class, &class_attr_driver_version);
127
128 device_destroy(dgrp_class, MKDEV(0, max_majors + 1));
129 device_destroy(dgrp_class, MKDEV(0, max_majors + 2));
130 class_destroy(dgrp_class);
131 }
132
133 static ssize_t dgrp_node_state_show(struct device *c,
134 struct device_attribute *attr, char *buf)
135 {
136 struct nd_struct *nd;
137
138 if (!c)
139 return 0;
140 nd = (struct nd_struct *) dev_get_drvdata(c);
141 if (!nd)
142 return 0;
143
144 return snprintf(buf, PAGE_SIZE, "%s\n", ND_STATE_STR(nd->nd_state));
145 }
146
147 static DEVICE_ATTR(state, 0600, dgrp_node_state_show, NULL);
148
149 static ssize_t dgrp_node_description_show(struct device *c,
150 struct device_attribute *attr,
151 char *buf)
152 {
153 struct nd_struct *nd;
154
155 if (!c)
156 return 0;
157 nd = (struct nd_struct *) dev_get_drvdata(c);
158 if (!nd)
159 return 0;
160
161 if (nd->nd_state == NS_READY)
162 return snprintf(buf, PAGE_SIZE, "%s\n", nd->nd_ps_desc);
163 return 0;
164 }
165 static DEVICE_ATTR(description_info, 0600, dgrp_node_description_show, NULL);
166
167 static ssize_t dgrp_node_hw_version_show(struct device *c,
168 struct device_attribute *attr,
169 char *buf)
170 {
171 struct nd_struct *nd;
172
173 if (!c)
174 return 0;
175 nd = (struct nd_struct *) dev_get_drvdata(c);
176 if (!nd)
177 return 0;
178
179 if (nd->nd_state == NS_READY)
180 return snprintf(buf, PAGE_SIZE, "%d.%d\n",
181 (nd->nd_hw_ver >> 8) & 0xff,
182 nd->nd_hw_ver & 0xff);
183
184 return 0;
185 }
186 static DEVICE_ATTR(hw_version_info, 0600, dgrp_node_hw_version_show, NULL);
187
188 static ssize_t dgrp_node_hw_id_show(struct device *c,
189 struct device_attribute *attr, char *buf)
190 {
191 struct nd_struct *nd;
192
193 if (!c)
194 return 0;
195 nd = (struct nd_struct *) dev_get_drvdata(c);
196 if (!nd)
197 return 0;
198
199
200 if (nd->nd_state == NS_READY)
201 return snprintf(buf, PAGE_SIZE, "%d\n", nd->nd_hw_id);
202 return 0;
203 }
204 static DEVICE_ATTR(hw_id_info, 0600, dgrp_node_hw_id_show, NULL);
205
206 static ssize_t dgrp_node_sw_version_show(struct device *c,
207 struct device_attribute *attr,
208 char *buf)
209 {
210 struct nd_struct *nd;
211
212 if (!c)
213 return 0;
214
215 nd = (struct nd_struct *) dev_get_drvdata(c);
216 if (!nd)
217 return 0;
218
219 if (nd->nd_state == NS_READY)
220 return snprintf(buf, PAGE_SIZE, "%d.%d\n",
221 (nd->nd_sw_ver >> 8) & 0xff,
222 nd->nd_sw_ver & 0xff);
223
224 return 0;
225 }
226 static DEVICE_ATTR(sw_version_info, 0600, dgrp_node_sw_version_show, NULL);
227
228
229 static struct attribute *dgrp_sysfs_node_entries[] = {
230 &dev_attr_state.attr,
231 &dev_attr_description_info.attr,
232 &dev_attr_hw_version_info.attr,
233 &dev_attr_hw_id_info.attr,
234 &dev_attr_sw_version_info.attr,
235 NULL
236 };
237
238
239 static struct attribute_group dgrp_node_attribute_group = {
240 .name = NULL,
241 .attrs = dgrp_sysfs_node_entries,
242 };
243
244
245 void dgrp_create_node_class_sysfs_files(struct nd_struct *nd)
246 {
247 int ret;
248 char name[10];
249
250 if (nd->nd_ID)
251 ID_TO_CHAR(nd->nd_ID, name);
252 else
253 sprintf(name, "node%ld", nd->nd_major);
254
255 nd->nd_class_dev = device_create(dgrp_class, dgrp_class_nodes_dev,
256 MKDEV(0, nd->nd_major), NULL, name);
257
258 ret = sysfs_create_group(&nd->nd_class_dev->kobj,
259 &dgrp_node_attribute_group);
260
261 if (ret) {
262 pr_alert("%s: failed to create sysfs node device attributes.\n",
263 __func__);
264 sysfs_remove_group(&nd->nd_class_dev->kobj,
265 &dgrp_node_attribute_group);
266 return;
267 }
268
269 dev_set_drvdata(nd->nd_class_dev, nd);
270
271 }
272
273
274 void dgrp_remove_node_class_sysfs_files(struct nd_struct *nd)
275 {
276 if (nd->nd_class_dev) {
277 sysfs_remove_group(&nd->nd_class_dev->kobj,
278 &dgrp_node_attribute_group);
279
280 device_destroy(dgrp_class, MKDEV(0, nd->nd_major));
281 nd->nd_class_dev = NULL;
282 }
283 }
284
285
286
287 static ssize_t dgrp_tty_state_show(struct device *d,
288 struct device_attribute *attr, char *buf)
289 {
290 struct un_struct *un;
291
292 if (!d)
293 return 0;
294 un = (struct un_struct *) dev_get_drvdata(d);
295 if (!un)
296 return 0;
297
298 return snprintf(buf, PAGE_SIZE, "%s\n",
299 un->un_open_count ? "Open" : "Closed");
300 }
301 static DEVICE_ATTR(state_info, 0600, dgrp_tty_state_show, NULL);
302
303 static ssize_t dgrp_tty_baud_show(struct device *d,
304 struct device_attribute *attr, char *buf)
305 {
306 struct ch_struct *ch;
307 struct un_struct *un;
308
309 if (!d)
310 return 0;
311 un = (struct un_struct *) dev_get_drvdata(d);
312 if (!un)
313 return 0;
314 ch = un->un_ch;
315 if (!ch)
316 return 0;
317 return snprintf(buf, PAGE_SIZE, "%d\n",
318 un->un_open_count ? (PORTSERVER_DIVIDEND / ch->ch_s_brate) : 0);
319 }
320 static DEVICE_ATTR(baud_info, 0400, dgrp_tty_baud_show, NULL);
321
322
323 static ssize_t dgrp_tty_msignals_show(struct device *d,
324 struct device_attribute *attr, char *buf)
325 {
326 struct ch_struct *ch;
327 struct un_struct *un;
328
329 if (!d)
330 return 0;
331 un = (struct un_struct *) dev_get_drvdata(d);
332 if (!un)
333 return 0;
334 ch = un->un_ch;
335 if (!ch)
336 return 0;
337
338 if (ch->ch_open_count) {
339 return snprintf(buf, PAGE_SIZE, "%s %s %s %s %s %s\n",
340 (ch->ch_s_mlast & DM_RTS) ? "RTS" : "",
341 (ch->ch_s_mlast & DM_CTS) ? "CTS" : "",
342 (ch->ch_s_mlast & DM_DTR) ? "DTR" : "",
343 (ch->ch_s_mlast & DM_DSR) ? "DSR" : "",
344 (ch->ch_s_mlast & DM_CD) ? "DCD" : "",
345 (ch->ch_s_mlast & DM_RI) ? "RI" : "");
346 }
347 return 0;
348 }
349 static DEVICE_ATTR(msignals_info, 0400, dgrp_tty_msignals_show, NULL);
350
351
352 static ssize_t dgrp_tty_iflag_show(struct device *d,
353 struct device_attribute *attr, char *buf)
354 {
355 struct ch_struct *ch;
356 struct un_struct *un;
357
358 if (!d)
359 return 0;
360 un = (struct un_struct *) dev_get_drvdata(d);
361 if (!un)
362 return 0;
363 ch = un->un_ch;
364 if (!ch)
365 return 0;
366 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_s_iflag);
367 }
368 static DEVICE_ATTR(iflag_info, 0600, dgrp_tty_iflag_show, NULL);
369
370
371 static ssize_t dgrp_tty_cflag_show(struct device *d,
372 struct device_attribute *attr, char *buf)
373 {
374 struct ch_struct *ch;
375 struct un_struct *un;
376
377 if (!d)
378 return 0;
379 un = (struct un_struct *) dev_get_drvdata(d);
380 if (!un)
381 return 0;
382 ch = un->un_ch;
383 if (!ch)
384 return 0;
385 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_s_cflag);
386 }
387 static DEVICE_ATTR(cflag_info, 0600, dgrp_tty_cflag_show, NULL);
388
389
390 static ssize_t dgrp_tty_oflag_show(struct device *d,
391 struct device_attribute *attr, char *buf)
392 {
393 struct ch_struct *ch;
394 struct un_struct *un;
395
396 if (!d)
397 return 0;
398 un = (struct un_struct *) dev_get_drvdata(d);
399 if (!un)
400 return 0;
401 ch = un->un_ch;
402 if (!ch)
403 return 0;
404 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_s_oflag);
405 }
406 static DEVICE_ATTR(oflag_info, 0600, dgrp_tty_oflag_show, NULL);
407
408
409 static ssize_t dgrp_tty_digi_flag_show(struct device *d,
410 struct device_attribute *attr, char *buf)
411 {
412 struct ch_struct *ch;
413 struct un_struct *un;
414
415 if (!d)
416 return 0;
417 un = (struct un_struct *) dev_get_drvdata(d);
418 if (!un)
419 return 0;
420 ch = un->un_ch;
421 if (!ch)
422 return 0;
423 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_digi.digi_flags);
424 }
425 static DEVICE_ATTR(digi_flag_info, 0600, dgrp_tty_digi_flag_show, NULL);
426
427
428 static ssize_t dgrp_tty_rxcount_show(struct device *d,
429 struct device_attribute *attr, char *buf)
430 {
431 struct ch_struct *ch;
432 struct un_struct *un;
433
434 if (!d)
435 return 0;
436 un = (struct un_struct *) dev_get_drvdata(d);
437 if (!un)
438 return 0;
439 ch = un->un_ch;
440 if (!ch)
441 return 0;
442 return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_rxcount);
443 }
444 static DEVICE_ATTR(rxcount_info, 0600, dgrp_tty_rxcount_show, NULL);
445
446
447 static ssize_t dgrp_tty_txcount_show(struct device *d,
448 struct device_attribute *attr, char *buf)
449 {
450 struct ch_struct *ch;
451 struct un_struct *un;
452
453 if (!d)
454 return 0;
455 un = (struct un_struct *) dev_get_drvdata(d);
456 if (!un)
457 return 0;
458 ch = un->un_ch;
459 if (!ch)
460 return 0;
461 return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_txcount);
462 }
463 static DEVICE_ATTR(txcount_info, 0600, dgrp_tty_txcount_show, NULL);
464
465
466 static ssize_t dgrp_tty_name_show(struct device *d,
467 struct device_attribute *attr, char *buf)
468 {
469 struct nd_struct *nd;
470 struct ch_struct *ch;
471 struct un_struct *un;
472 char name[10];
473
474 if (!d)
475 return 0;
476 un = (struct un_struct *) dev_get_drvdata(d);
477 if (!un)
478 return 0;
479 ch = un->un_ch;
480 if (!ch)
481 return 0;
482 nd = ch->ch_nd;
483 if (!nd)
484 return 0;
485
486 ID_TO_CHAR(nd->nd_ID, name);
487
488 return snprintf(buf, PAGE_SIZE, "%s%s%02d\n",
489 un->un_type == SERIAL_TYPE_XPRINT ? "pr" : "tty",
490 name, ch->ch_portnum);
491 }
492 static DEVICE_ATTR(custom_name, 0600, dgrp_tty_name_show, NULL);
493
494
495 static struct attribute *dgrp_sysfs_tty_entries[] = {
496 &dev_attr_state_info.attr,
497 &dev_attr_baud_info.attr,
498 &dev_attr_msignals_info.attr,
499 &dev_attr_iflag_info.attr,
500 &dev_attr_cflag_info.attr,
501 &dev_attr_oflag_info.attr,
502 &dev_attr_digi_flag_info.attr,
503 &dev_attr_rxcount_info.attr,
504 &dev_attr_txcount_info.attr,
505 &dev_attr_custom_name.attr,
506 NULL
507 };
508
509
510 static struct attribute_group dgrp_tty_attribute_group = {
511 .name = NULL,
512 .attrs = dgrp_sysfs_tty_entries,
513 };
514
515
516 void dgrp_create_tty_sysfs(struct un_struct *un, struct device *c)
517 {
518 int ret;
519
520 ret = sysfs_create_group(&c->kobj, &dgrp_tty_attribute_group);
521 if (ret) {
522 pr_alert("%s: failed to create sysfs tty device attributes.\n",
523 __func__);
524 sysfs_remove_group(&c->kobj, &dgrp_tty_attribute_group);
525 return;
526 }
527
528 dev_set_drvdata(c, un);
529
530 }
531
532
533 void dgrp_remove_tty_sysfs(struct device *c)
534 {
535 sysfs_remove_group(&c->kobj, &dgrp_tty_attribute_group);
536 }
This page took 0.040883 seconds and 5 git commands to generate.