]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/staging/dgrp/dgrp_sysfs.c
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[karo-tx-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 }