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