drivers/tty: make pty.c slightly more explicitly non-modular
[firefly-linux-kernel-4.4.55.git] / drivers / staging / dgnc / dgnc_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 <linux/kernel.h>
18 #include <linux/module.h>
19 #include <linux/ctype.h>
20 #include <linux/string.h>
21 #include <linux/serial_reg.h>
22 #include <linux/device.h>
23 #include <linux/pci.h>
24 #include <linux/kdev_t.h>
25
26 #include "dgnc_driver.h"
27 #include "dgnc_mgmt.h"
28
29
30 static ssize_t dgnc_driver_version_show(struct device_driver *ddp, char *buf)
31 {
32         return snprintf(buf, PAGE_SIZE, "%s\n", DG_PART);
33 }
34 static DRIVER_ATTR(version, S_IRUSR, dgnc_driver_version_show, NULL);
35
36
37 static ssize_t dgnc_driver_boards_show(struct device_driver *ddp, char *buf)
38 {
39         return snprintf(buf, PAGE_SIZE, "%d\n", dgnc_NumBoards);
40 }
41 static DRIVER_ATTR(boards, S_IRUSR, dgnc_driver_boards_show, NULL);
42
43
44 static ssize_t dgnc_driver_maxboards_show(struct device_driver *ddp, char *buf)
45 {
46         return snprintf(buf, PAGE_SIZE, "%d\n", MAXBOARDS);
47 }
48 static DRIVER_ATTR(maxboards, S_IRUSR, dgnc_driver_maxboards_show, NULL);
49
50
51 static ssize_t dgnc_driver_pollrate_show(struct device_driver *ddp, char *buf)
52 {
53         return snprintf(buf, PAGE_SIZE, "%dms\n", dgnc_poll_tick);
54 }
55
56 static ssize_t dgnc_driver_pollrate_store(struct device_driver *ddp,
57                                           const char *buf, size_t count)
58 {
59         int ret;
60
61         ret = sscanf(buf, "%d\n", &dgnc_poll_tick);
62         if (ret != 1)
63                 return -EINVAL;
64         return count;
65 }
66 static DRIVER_ATTR(pollrate, (S_IRUSR | S_IWUSR), dgnc_driver_pollrate_show,
67                    dgnc_driver_pollrate_store);
68
69
70 void dgnc_create_driver_sysfiles(struct pci_driver *dgnc_driver)
71 {
72         int rc = 0;
73         struct device_driver *driverfs = &dgnc_driver->driver;
74
75         rc |= driver_create_file(driverfs, &driver_attr_version);
76         rc |= driver_create_file(driverfs, &driver_attr_boards);
77         rc |= driver_create_file(driverfs, &driver_attr_maxboards);
78         rc |= driver_create_file(driverfs, &driver_attr_pollrate);
79         if (rc)
80                 pr_err("DGNC: sysfs driver_create_file failed!\n");
81 }
82
83
84 void dgnc_remove_driver_sysfiles(struct pci_driver *dgnc_driver)
85 {
86         struct device_driver *driverfs = &dgnc_driver->driver;
87
88         driver_remove_file(driverfs, &driver_attr_version);
89         driver_remove_file(driverfs, &driver_attr_boards);
90         driver_remove_file(driverfs, &driver_attr_maxboards);
91         driver_remove_file(driverfs, &driver_attr_pollrate);
92 }
93
94
95 #define DGNC_VERIFY_BOARD(p, bd)                                \
96         do {                                                    \
97                 if (!p)                                         \
98                         return 0;                               \
99                                                                 \
100                 bd = dev_get_drvdata(p);                        \
101                 if (!bd || bd->magic != DGNC_BOARD_MAGIC)       \
102                         return 0;                               \
103                 if (bd->state != BOARD_READY)                   \
104                         return 0;                               \
105         } while (0)
106
107
108
109 static ssize_t dgnc_vpd_show(struct device *p, struct device_attribute *attr,
110                              char *buf)
111 {
112         struct dgnc_board *bd;
113         int count = 0;
114         int i = 0;
115
116         DGNC_VERIFY_BOARD(p, bd);
117
118         count += sprintf(buf + count,
119                 "\n      0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F");
120         for (i = 0; i < 0x40 * 2; i++) {
121                 if (!(i % 16))
122                         count += sprintf(buf + count, "\n%04X ", i * 2);
123                 count += sprintf(buf + count, "%02X ", bd->vpd[i]);
124         }
125         count += sprintf(buf + count, "\n");
126
127         return count;
128 }
129 static DEVICE_ATTR(vpd, S_IRUSR, dgnc_vpd_show, NULL);
130
131 static ssize_t dgnc_serial_number_show(struct device *p,
132                                        struct device_attribute *attr, char *buf)
133 {
134         struct dgnc_board *bd;
135         int count = 0;
136
137         DGNC_VERIFY_BOARD(p, bd);
138
139         if (bd->serial_num[0] == '\0')
140                 count += sprintf(buf + count, "<UNKNOWN>\n");
141         else
142                 count += sprintf(buf + count, "%s\n", bd->serial_num);
143
144         return count;
145 }
146 static DEVICE_ATTR(serial_number, S_IRUSR, dgnc_serial_number_show, NULL);
147
148
149 static ssize_t dgnc_ports_state_show(struct device *p,
150                                      struct device_attribute *attr, char *buf)
151 {
152         struct dgnc_board *bd;
153         int count = 0;
154         int i = 0;
155
156         DGNC_VERIFY_BOARD(p, bd);
157
158         for (i = 0; i < bd->nasync; i++) {
159                 count += snprintf(buf + count, PAGE_SIZE - count,
160                         "%d %s\n", bd->channels[i]->ch_portnum,
161                         bd->channels[i]->ch_open_count ? "Open" : "Closed");
162         }
163         return count;
164 }
165 static DEVICE_ATTR(ports_state, S_IRUSR, dgnc_ports_state_show, NULL);
166
167
168 static ssize_t dgnc_ports_baud_show(struct device *p,
169                                     struct device_attribute *attr, char *buf)
170 {
171         struct dgnc_board *bd;
172         int count = 0;
173         int i = 0;
174
175         DGNC_VERIFY_BOARD(p, bd);
176
177         for (i = 0; i < bd->nasync; i++) {
178                 count +=  snprintf(buf + count, PAGE_SIZE - count,
179                         "%d %d\n", bd->channels[i]->ch_portnum,
180                         bd->channels[i]->ch_old_baud);
181         }
182         return count;
183 }
184 static DEVICE_ATTR(ports_baud, S_IRUSR, dgnc_ports_baud_show, NULL);
185
186
187 static ssize_t dgnc_ports_msignals_show(struct device *p,
188                                         struct device_attribute *attr,
189                                         char *buf)
190 {
191         struct dgnc_board *bd;
192         int count = 0;
193         int i = 0;
194
195         DGNC_VERIFY_BOARD(p, bd);
196
197         for (i = 0; i < bd->nasync; i++) {
198                 if (bd->channels[i]->ch_open_count) {
199                         count += snprintf(buf + count, PAGE_SIZE - count,
200                                 "%d %s %s %s %s %s %s\n",
201                                 bd->channels[i]->ch_portnum,
202                                 (bd->channels[i]->ch_mostat & UART_MCR_RTS) ? "RTS" : "",
203                                 (bd->channels[i]->ch_mistat & UART_MSR_CTS) ? "CTS" : "",
204                                 (bd->channels[i]->ch_mostat & UART_MCR_DTR) ? "DTR" : "",
205                                 (bd->channels[i]->ch_mistat & UART_MSR_DSR) ? "DSR" : "",
206                                 (bd->channels[i]->ch_mistat & UART_MSR_DCD) ? "DCD" : "",
207                                 (bd->channels[i]->ch_mistat & UART_MSR_RI)  ? "RI"  : "");
208                 } else {
209                         count += snprintf(buf + count, PAGE_SIZE - count,
210                                 "%d\n", bd->channels[i]->ch_portnum);
211                 }
212         }
213         return count;
214 }
215 static DEVICE_ATTR(ports_msignals, S_IRUSR, dgnc_ports_msignals_show, NULL);
216
217
218 static ssize_t dgnc_ports_iflag_show(struct device *p,
219                                      struct device_attribute *attr, char *buf)
220 {
221         struct dgnc_board *bd;
222         int count = 0;
223         int i = 0;
224
225         DGNC_VERIFY_BOARD(p, bd);
226
227         for (i = 0; i < bd->nasync; i++) {
228                 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
229                         bd->channels[i]->ch_portnum,
230                         bd->channels[i]->ch_c_iflag);
231         }
232         return count;
233 }
234 static DEVICE_ATTR(ports_iflag, S_IRUSR, dgnc_ports_iflag_show, NULL);
235
236
237 static ssize_t dgnc_ports_cflag_show(struct device *p,
238                                      struct device_attribute *attr, char *buf)
239 {
240         struct dgnc_board *bd;
241         int count = 0;
242         int i = 0;
243
244         DGNC_VERIFY_BOARD(p, bd);
245
246         for (i = 0; i < bd->nasync; i++) {
247                 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
248                         bd->channels[i]->ch_portnum,
249                         bd->channels[i]->ch_c_cflag);
250         }
251         return count;
252 }
253 static DEVICE_ATTR(ports_cflag, S_IRUSR, dgnc_ports_cflag_show, NULL);
254
255
256 static ssize_t dgnc_ports_oflag_show(struct device *p,
257                                      struct device_attribute *attr, char *buf)
258 {
259         struct dgnc_board *bd;
260         int count = 0;
261         int i = 0;
262
263         DGNC_VERIFY_BOARD(p, bd);
264
265         for (i = 0; i < bd->nasync; i++) {
266                 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
267                         bd->channels[i]->ch_portnum,
268                         bd->channels[i]->ch_c_oflag);
269         }
270         return count;
271 }
272 static DEVICE_ATTR(ports_oflag, S_IRUSR, dgnc_ports_oflag_show, NULL);
273
274
275 static ssize_t dgnc_ports_lflag_show(struct device *p,
276                                      struct device_attribute *attr, char *buf)
277 {
278         struct dgnc_board *bd;
279         int count = 0;
280         int i = 0;
281
282         DGNC_VERIFY_BOARD(p, bd);
283
284         for (i = 0; i < bd->nasync; i++) {
285                 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
286                         bd->channels[i]->ch_portnum,
287                         bd->channels[i]->ch_c_lflag);
288         }
289         return count;
290 }
291 static DEVICE_ATTR(ports_lflag, S_IRUSR, dgnc_ports_lflag_show, NULL);
292
293
294 static ssize_t dgnc_ports_digi_flag_show(struct device *p,
295                                          struct device_attribute *attr,
296                                          char *buf)
297 {
298         struct dgnc_board *bd;
299         int count = 0;
300         int i = 0;
301
302         DGNC_VERIFY_BOARD(p, bd);
303
304         for (i = 0; i < bd->nasync; i++) {
305                 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
306                         bd->channels[i]->ch_portnum,
307                         bd->channels[i]->ch_digi.digi_flags);
308         }
309         return count;
310 }
311 static DEVICE_ATTR(ports_digi_flag, S_IRUSR, dgnc_ports_digi_flag_show, NULL);
312
313
314 static ssize_t dgnc_ports_rxcount_show(struct device *p,
315                                        struct device_attribute *attr, char *buf)
316 {
317         struct dgnc_board *bd;
318         int count = 0;
319         int i = 0;
320
321         DGNC_VERIFY_BOARD(p, bd);
322
323         for (i = 0; i < bd->nasync; i++) {
324                 count += snprintf(buf + count, PAGE_SIZE - count, "%d %ld\n",
325                         bd->channels[i]->ch_portnum,
326                         bd->channels[i]->ch_rxcount);
327         }
328         return count;
329 }
330 static DEVICE_ATTR(ports_rxcount, S_IRUSR, dgnc_ports_rxcount_show, NULL);
331
332
333 static ssize_t dgnc_ports_txcount_show(struct device *p,
334                                        struct device_attribute *attr, char *buf)
335 {
336         struct dgnc_board *bd;
337         int count = 0;
338         int i = 0;
339
340         DGNC_VERIFY_BOARD(p, bd);
341
342         for (i = 0; i < bd->nasync; i++) {
343                 count += snprintf(buf + count, PAGE_SIZE - count, "%d %ld\n",
344                         bd->channels[i]->ch_portnum,
345                         bd->channels[i]->ch_txcount);
346         }
347         return count;
348 }
349 static DEVICE_ATTR(ports_txcount, S_IRUSR, dgnc_ports_txcount_show, NULL);
350
351
352 /* this function creates the sys files that will export each signal status
353  * to sysfs each value will be put in a separate filename
354  */
355 void dgnc_create_ports_sysfiles(struct dgnc_board *bd)
356 {
357         int rc = 0;
358
359         dev_set_drvdata(&bd->pdev->dev, bd);
360         rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_state);
361         rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_baud);
362         rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_msignals);
363         rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_iflag);
364         rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_cflag);
365         rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_oflag);
366         rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_lflag);
367         rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_digi_flag);
368         rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_rxcount);
369         rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_txcount);
370         rc |= device_create_file(&(bd->pdev->dev), &dev_attr_vpd);
371         rc |= device_create_file(&(bd->pdev->dev), &dev_attr_serial_number);
372         if (rc)
373                 dev_err(&bd->pdev->dev, "dgnc: sysfs device_create_file failed!\n");
374 }
375
376
377 /* removes all the sys files created for that port */
378 void dgnc_remove_ports_sysfiles(struct dgnc_board *bd)
379 {
380         device_remove_file(&(bd->pdev->dev), &dev_attr_ports_state);
381         device_remove_file(&(bd->pdev->dev), &dev_attr_ports_baud);
382         device_remove_file(&(bd->pdev->dev), &dev_attr_ports_msignals);
383         device_remove_file(&(bd->pdev->dev), &dev_attr_ports_iflag);
384         device_remove_file(&(bd->pdev->dev), &dev_attr_ports_cflag);
385         device_remove_file(&(bd->pdev->dev), &dev_attr_ports_oflag);
386         device_remove_file(&(bd->pdev->dev), &dev_attr_ports_lflag);
387         device_remove_file(&(bd->pdev->dev), &dev_attr_ports_digi_flag);
388         device_remove_file(&(bd->pdev->dev), &dev_attr_ports_rxcount);
389         device_remove_file(&(bd->pdev->dev), &dev_attr_ports_txcount);
390         device_remove_file(&(bd->pdev->dev), &dev_attr_vpd);
391         device_remove_file(&(bd->pdev->dev), &dev_attr_serial_number);
392 }
393
394
395 static ssize_t dgnc_tty_state_show(struct device *d,
396                                    struct device_attribute *attr, char *buf)
397 {
398         struct dgnc_board *bd;
399         struct channel_t *ch;
400         struct un_t *un;
401
402         if (!d)
403                 return 0;
404         un = dev_get_drvdata(d);
405         if (!un || un->magic != DGNC_UNIT_MAGIC)
406                 return 0;
407         ch = un->un_ch;
408         if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
409                 return 0;
410         bd = ch->ch_bd;
411         if (!bd || bd->magic != DGNC_BOARD_MAGIC)
412                 return 0;
413         if (bd->state != BOARD_READY)
414                 return 0;
415
416         return snprintf(buf, PAGE_SIZE, "%s",
417                         un->un_open_count ? "Open" : "Closed");
418 }
419 static DEVICE_ATTR(state, S_IRUSR, dgnc_tty_state_show, NULL);
420
421
422 static ssize_t dgnc_tty_baud_show(struct device *d,
423                                   struct device_attribute *attr, char *buf)
424 {
425         struct dgnc_board *bd;
426         struct channel_t *ch;
427         struct un_t *un;
428
429         if (!d)
430                 return 0;
431         un = dev_get_drvdata(d);
432         if (!un || un->magic != DGNC_UNIT_MAGIC)
433                 return 0;
434         ch = un->un_ch;
435         if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
436                 return 0;
437         bd = ch->ch_bd;
438         if (!bd || bd->magic != DGNC_BOARD_MAGIC)
439                 return 0;
440         if (bd->state != BOARD_READY)
441                 return 0;
442
443         return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_old_baud);
444 }
445 static DEVICE_ATTR(baud, S_IRUSR, dgnc_tty_baud_show, NULL);
446
447
448 static ssize_t dgnc_tty_msignals_show(struct device *d,
449                                       struct device_attribute *attr, char *buf)
450 {
451         struct dgnc_board *bd;
452         struct channel_t *ch;
453         struct un_t *un;
454
455         if (!d)
456                 return 0;
457         un = dev_get_drvdata(d);
458         if (!un || un->magic != DGNC_UNIT_MAGIC)
459                 return 0;
460         ch = un->un_ch;
461         if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
462                 return 0;
463         bd = ch->ch_bd;
464         if (!bd || bd->magic != DGNC_BOARD_MAGIC)
465                 return 0;
466         if (bd->state != BOARD_READY)
467                 return 0;
468
469         if (ch->ch_open_count) {
470                 return snprintf(buf, PAGE_SIZE, "%s %s %s %s %s %s\n",
471                         (ch->ch_mostat & UART_MCR_RTS) ? "RTS" : "",
472                         (ch->ch_mistat & UART_MSR_CTS) ? "CTS" : "",
473                         (ch->ch_mostat & UART_MCR_DTR) ? "DTR" : "",
474                         (ch->ch_mistat & UART_MSR_DSR) ? "DSR" : "",
475                         (ch->ch_mistat & UART_MSR_DCD) ? "DCD" : "",
476                         (ch->ch_mistat & UART_MSR_RI)  ? "RI"  : "");
477         }
478         return 0;
479 }
480 static DEVICE_ATTR(msignals, S_IRUSR, dgnc_tty_msignals_show, NULL);
481
482
483 static ssize_t dgnc_tty_iflag_show(struct device *d,
484                                    struct device_attribute *attr, char *buf)
485 {
486         struct dgnc_board *bd;
487         struct channel_t *ch;
488         struct un_t *un;
489
490         if (!d)
491                 return 0;
492         un = dev_get_drvdata(d);
493         if (!un || un->magic != DGNC_UNIT_MAGIC)
494                 return 0;
495         ch = un->un_ch;
496         if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
497                 return 0;
498         bd = ch->ch_bd;
499         if (!bd || bd->magic != DGNC_BOARD_MAGIC)
500                 return 0;
501         if (bd->state != BOARD_READY)
502                 return 0;
503
504         return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_iflag);
505 }
506 static DEVICE_ATTR(iflag, S_IRUSR, dgnc_tty_iflag_show, NULL);
507
508
509 static ssize_t dgnc_tty_cflag_show(struct device *d,
510                                    struct device_attribute *attr, char *buf)
511 {
512         struct dgnc_board *bd;
513         struct channel_t *ch;
514         struct un_t *un;
515
516         if (!d)
517                 return 0;
518         un = dev_get_drvdata(d);
519         if (!un || un->magic != DGNC_UNIT_MAGIC)
520                 return 0;
521         ch = un->un_ch;
522         if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
523                 return 0;
524         bd = ch->ch_bd;
525         if (!bd || bd->magic != DGNC_BOARD_MAGIC)
526                 return 0;
527         if (bd->state != BOARD_READY)
528                 return 0;
529
530         return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_cflag);
531 }
532 static DEVICE_ATTR(cflag, S_IRUSR, dgnc_tty_cflag_show, NULL);
533
534
535 static ssize_t dgnc_tty_oflag_show(struct device *d,
536                                    struct device_attribute *attr, char *buf)
537 {
538         struct dgnc_board *bd;
539         struct channel_t *ch;
540         struct un_t *un;
541
542         if (!d)
543                 return 0;
544         un = dev_get_drvdata(d);
545         if (!un || un->magic != DGNC_UNIT_MAGIC)
546                 return 0;
547         ch = un->un_ch;
548         if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
549                 return 0;
550         bd = ch->ch_bd;
551         if (!bd || bd->magic != DGNC_BOARD_MAGIC)
552                 return 0;
553         if (bd->state != BOARD_READY)
554                 return 0;
555
556         return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_oflag);
557 }
558 static DEVICE_ATTR(oflag, S_IRUSR, dgnc_tty_oflag_show, NULL);
559
560
561 static ssize_t dgnc_tty_lflag_show(struct device *d,
562                                    struct device_attribute *attr, char *buf)
563 {
564         struct dgnc_board *bd;
565         struct channel_t *ch;
566         struct un_t *un;
567
568         if (!d)
569                 return 0;
570         un = dev_get_drvdata(d);
571         if (!un || un->magic != DGNC_UNIT_MAGIC)
572                 return 0;
573         ch = un->un_ch;
574         if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
575                 return 0;
576         bd = ch->ch_bd;
577         if (!bd || bd->magic != DGNC_BOARD_MAGIC)
578                 return 0;
579         if (bd->state != BOARD_READY)
580                 return 0;
581
582         return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_lflag);
583 }
584 static DEVICE_ATTR(lflag, S_IRUSR, dgnc_tty_lflag_show, NULL);
585
586
587 static ssize_t dgnc_tty_digi_flag_show(struct device *d,
588                                        struct device_attribute *attr, char *buf)
589 {
590         struct dgnc_board *bd;
591         struct channel_t *ch;
592         struct un_t *un;
593
594         if (!d)
595                 return 0;
596         un = dev_get_drvdata(d);
597         if (!un || un->magic != DGNC_UNIT_MAGIC)
598                 return 0;
599         ch = un->un_ch;
600         if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
601                 return 0;
602         bd = ch->ch_bd;
603         if (!bd || bd->magic != DGNC_BOARD_MAGIC)
604                 return 0;
605         if (bd->state != BOARD_READY)
606                 return 0;
607
608         return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_digi.digi_flags);
609 }
610 static DEVICE_ATTR(digi_flag, S_IRUSR, dgnc_tty_digi_flag_show, NULL);
611
612
613 static ssize_t dgnc_tty_rxcount_show(struct device *d,
614                                      struct device_attribute *attr, char *buf)
615 {
616         struct dgnc_board *bd;
617         struct channel_t *ch;
618         struct un_t *un;
619
620         if (!d)
621                 return 0;
622         un = dev_get_drvdata(d);
623         if (!un || un->magic != DGNC_UNIT_MAGIC)
624                 return 0;
625         ch = un->un_ch;
626         if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
627                 return 0;
628         bd = ch->ch_bd;
629         if (!bd || bd->magic != DGNC_BOARD_MAGIC)
630                 return 0;
631         if (bd->state != BOARD_READY)
632                 return 0;
633
634         return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_rxcount);
635 }
636 static DEVICE_ATTR(rxcount, S_IRUSR, dgnc_tty_rxcount_show, NULL);
637
638
639 static ssize_t dgnc_tty_txcount_show(struct device *d,
640                                      struct device_attribute *attr, char *buf)
641 {
642         struct dgnc_board *bd;
643         struct channel_t *ch;
644         struct un_t *un;
645
646         if (!d)
647                 return 0;
648         un = dev_get_drvdata(d);
649         if (!un || un->magic != DGNC_UNIT_MAGIC)
650                 return 0;
651         ch = un->un_ch;
652         if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
653                 return 0;
654         bd = ch->ch_bd;
655         if (!bd || bd->magic != DGNC_BOARD_MAGIC)
656                 return 0;
657         if (bd->state != BOARD_READY)
658                 return 0;
659
660         return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_txcount);
661 }
662 static DEVICE_ATTR(txcount, S_IRUSR, dgnc_tty_txcount_show, NULL);
663
664
665 static ssize_t dgnc_tty_name_show(struct device *d,
666                                   struct device_attribute *attr, char *buf)
667 {
668         struct dgnc_board *bd;
669         struct channel_t *ch;
670         struct un_t *un;
671
672         if (!d)
673                 return 0;
674         un = dev_get_drvdata(d);
675         if (!un || un->magic != DGNC_UNIT_MAGIC)
676                 return 0;
677         ch = un->un_ch;
678         if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
679                 return 0;
680         bd = ch->ch_bd;
681         if (!bd || bd->magic != DGNC_BOARD_MAGIC)
682                 return 0;
683         if (bd->state != BOARD_READY)
684                 return 0;
685
686         return snprintf(buf, PAGE_SIZE, "%sn%d%c\n",
687                 (un->un_type == DGNC_PRINT) ? "pr" : "tty",
688                 bd->boardnum + 1, 'a' + ch->ch_portnum);
689 }
690 static DEVICE_ATTR(custom_name, S_IRUSR, dgnc_tty_name_show, NULL);
691
692
693 static struct attribute *dgnc_sysfs_tty_entries[] = {
694         &dev_attr_state.attr,
695         &dev_attr_baud.attr,
696         &dev_attr_msignals.attr,
697         &dev_attr_iflag.attr,
698         &dev_attr_cflag.attr,
699         &dev_attr_oflag.attr,
700         &dev_attr_lflag.attr,
701         &dev_attr_digi_flag.attr,
702         &dev_attr_rxcount.attr,
703         &dev_attr_txcount.attr,
704         &dev_attr_custom_name.attr,
705         NULL
706 };
707
708
709 static struct attribute_group dgnc_tty_attribute_group = {
710         .name = NULL,
711         .attrs = dgnc_sysfs_tty_entries,
712 };
713
714
715 void dgnc_create_tty_sysfs(struct un_t *un, struct device *c)
716 {
717         int ret;
718
719         ret = sysfs_create_group(&c->kobj, &dgnc_tty_attribute_group);
720         if (ret) {
721                 dev_err(c, "dgnc: failed to create sysfs tty device attributes.\n");
722                 sysfs_remove_group(&c->kobj, &dgnc_tty_attribute_group);
723                 return;
724         }
725
726         dev_set_drvdata(c, un);
727
728 }
729
730
731 void dgnc_remove_tty_sysfs(struct device *c)
732 {
733         sysfs_remove_group(&c->kobj, &dgnc_tty_attribute_group);
734 }
735