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