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