ARM: OMAP3: fix dpll4_m3_ck and dpll4_m4_ck dividers
[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         if (!p)                                         \
155                 return (0);                             \
156                                                         \
157         bd = dev_get_drvdata(p);                        \
158         if (!bd || bd->magic != DGNC_BOARD_MAGIC)       \
159                 return (0);                             \
160         if (bd->state != BOARD_READY)                   \
161                 return (0);                             \
162
163
164
165 static ssize_t dgnc_vpd_show(struct device *p, struct device_attribute *attr, char *buf)
166 {
167         struct board_t *bd;
168         int count = 0;
169         int i = 0;
170
171         DGNC_VERIFY_BOARD(p, bd);
172
173         count += sprintf(buf + count, "\n      0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F");
174         for (i = 0; i < 0x40 * 2; i++) {
175                 if (!(i % 16))
176                         count += sprintf(buf + count, "\n%04X ", i * 2);
177                 count += sprintf(buf + count, "%02X ", bd->vpd[i]);
178         }
179         count += sprintf(buf + count, "\n");
180
181         return count;
182 }
183 static DEVICE_ATTR(vpd, S_IRUSR, dgnc_vpd_show, NULL);
184
185 static ssize_t dgnc_serial_number_show(struct device *p, struct device_attribute *attr, char *buf)
186 {
187         struct board_t *bd;
188         int count = 0;
189
190         DGNC_VERIFY_BOARD(p, bd);
191
192         if (bd->serial_num[0] == '\0')
193                 count += sprintf(buf + count, "<UNKNOWN>\n");
194         else
195                 count += sprintf(buf + count, "%s\n", bd->serial_num);
196
197         return count;
198 }
199 static DEVICE_ATTR(serial_number, S_IRUSR, dgnc_serial_number_show, NULL);
200
201
202 static ssize_t dgnc_ports_state_show(struct device *p, struct device_attribute *attr, char *buf)
203 {
204         struct board_t *bd;
205         int count = 0;
206         int i = 0;
207
208         DGNC_VERIFY_BOARD(p, bd);
209
210         for (i = 0; i < bd->nasync; i++) {
211                 count += snprintf(buf + count, PAGE_SIZE - count,
212                         "%d %s\n", bd->channels[i]->ch_portnum,
213                         bd->channels[i]->ch_open_count ? "Open" : "Closed");
214         }
215         return count;
216 }
217 static DEVICE_ATTR(ports_state, S_IRUSR, dgnc_ports_state_show, NULL);
218
219
220 static ssize_t dgnc_ports_baud_show(struct device *p, struct device_attribute *attr, char *buf)
221 {
222         struct board_t *bd;
223         int count = 0;
224         int i = 0;
225
226         DGNC_VERIFY_BOARD(p, bd);
227
228         for (i = 0; i < bd->nasync; i++) {
229                 count +=  snprintf(buf + count, PAGE_SIZE - count,
230                         "%d %d\n", bd->channels[i]->ch_portnum, bd->channels[i]->ch_old_baud);
231         }
232         return count;
233 }
234 static DEVICE_ATTR(ports_baud, S_IRUSR, dgnc_ports_baud_show, NULL);
235
236
237 static ssize_t dgnc_ports_msignals_show(struct device *p, struct device_attribute *attr, char *buf)
238 {
239         struct board_t *bd;
240         int count = 0;
241         int i = 0;
242
243         DGNC_VERIFY_BOARD(p, bd);
244
245         for (i = 0; i < bd->nasync; i++) {
246                 if (bd->channels[i]->ch_open_count) {
247                         count += snprintf(buf + count, PAGE_SIZE - count,
248                                 "%d %s %s %s %s %s %s\n", bd->channels[i]->ch_portnum,
249                                 (bd->channels[i]->ch_mostat & UART_MCR_RTS) ? "RTS" : "",
250                                 (bd->channels[i]->ch_mistat & UART_MSR_CTS) ? "CTS" : "",
251                                 (bd->channels[i]->ch_mostat & UART_MCR_DTR) ? "DTR" : "",
252                                 (bd->channels[i]->ch_mistat & UART_MSR_DSR) ? "DSR" : "",
253                                 (bd->channels[i]->ch_mistat & UART_MSR_DCD) ? "DCD" : "",
254                                 (bd->channels[i]->ch_mistat & UART_MSR_RI)  ? "RI"  : "");
255                 } else {
256                         count += snprintf(buf + count, PAGE_SIZE - count,
257                                 "%d\n", bd->channels[i]->ch_portnum);
258                 }
259         }
260         return count;
261 }
262 static DEVICE_ATTR(ports_msignals, S_IRUSR, dgnc_ports_msignals_show, NULL);
263
264
265 static ssize_t dgnc_ports_iflag_show(struct device *p, struct device_attribute *attr, char *buf)
266 {
267         struct board_t *bd;
268         int count = 0;
269         int i = 0;
270
271         DGNC_VERIFY_BOARD(p, bd);
272
273         for (i = 0; i < bd->nasync; i++) {
274                 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
275                         bd->channels[i]->ch_portnum, bd->channels[i]->ch_c_iflag);
276         }
277         return count;
278 }
279 static DEVICE_ATTR(ports_iflag, S_IRUSR, dgnc_ports_iflag_show, NULL);
280
281
282 static ssize_t dgnc_ports_cflag_show(struct device *p, struct device_attribute *attr, char *buf)
283 {
284         struct board_t *bd;
285         int count = 0;
286         int i = 0;
287
288         DGNC_VERIFY_BOARD(p, bd);
289
290         for (i = 0; i < bd->nasync; i++) {
291                 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
292                         bd->channels[i]->ch_portnum, bd->channels[i]->ch_c_cflag);
293         }
294         return count;
295 }
296 static DEVICE_ATTR(ports_cflag, S_IRUSR, dgnc_ports_cflag_show, NULL);
297
298
299 static ssize_t dgnc_ports_oflag_show(struct device *p, struct device_attribute *attr, char *buf)
300 {
301         struct board_t *bd;
302         int count = 0;
303         int i = 0;
304
305         DGNC_VERIFY_BOARD(p, bd);
306
307         for (i = 0; i < bd->nasync; i++) {
308                 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
309                         bd->channels[i]->ch_portnum, bd->channels[i]->ch_c_oflag);
310         }
311         return count;
312 }
313 static DEVICE_ATTR(ports_oflag, S_IRUSR, dgnc_ports_oflag_show, NULL);
314
315
316 static ssize_t dgnc_ports_lflag_show(struct device *p, struct device_attribute *attr, char *buf)
317 {
318         struct board_t *bd;
319         int count = 0;
320         int i = 0;
321
322         DGNC_VERIFY_BOARD(p, bd);
323
324         for (i = 0; i < bd->nasync; i++) {
325                 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
326                         bd->channels[i]->ch_portnum, bd->channels[i]->ch_c_lflag);
327         }
328         return count;
329 }
330 static DEVICE_ATTR(ports_lflag, S_IRUSR, dgnc_ports_lflag_show, NULL);
331
332
333 static ssize_t dgnc_ports_digi_flag_show(struct device *p, struct device_attribute *attr, char *buf)
334 {
335         struct board_t *bd;
336         int count = 0;
337         int i = 0;
338
339         DGNC_VERIFY_BOARD(p, bd);
340
341         for (i = 0; i < bd->nasync; i++) {
342                 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
343                         bd->channels[i]->ch_portnum, bd->channels[i]->ch_digi.digi_flags);
344         }
345         return count;
346 }
347 static DEVICE_ATTR(ports_digi_flag, S_IRUSR, dgnc_ports_digi_flag_show, NULL);
348
349
350 static ssize_t dgnc_ports_rxcount_show(struct device *p, struct device_attribute *attr, char *buf)
351 {
352         struct board_t *bd;
353         int count = 0;
354         int i = 0;
355
356         DGNC_VERIFY_BOARD(p, bd);
357
358         for (i = 0; i < bd->nasync; i++) {
359                 count += snprintf(buf + count, PAGE_SIZE - count, "%d %ld\n",
360                         bd->channels[i]->ch_portnum, bd->channels[i]->ch_rxcount);
361         }
362         return count;
363 }
364 static DEVICE_ATTR(ports_rxcount, S_IRUSR, dgnc_ports_rxcount_show, NULL);
365
366
367 static ssize_t dgnc_ports_txcount_show(struct device *p, struct device_attribute *attr, char *buf)
368 {
369         struct board_t *bd;
370         int count = 0;
371         int i = 0;
372
373         DGNC_VERIFY_BOARD(p, bd);
374
375         for (i = 0; i < bd->nasync; i++) {
376                 count += snprintf(buf + count, PAGE_SIZE - count, "%d %ld\n",
377                         bd->channels[i]->ch_portnum, bd->channels[i]->ch_txcount);
378         }
379         return count;
380 }
381 static DEVICE_ATTR(ports_txcount, S_IRUSR, dgnc_ports_txcount_show, NULL);
382
383
384 /* this function creates the sys files that will export each signal status
385  * to sysfs each value will be put in a separate filename
386  */
387 void dgnc_create_ports_sysfiles(struct board_t *bd)
388 {
389         int rc = 0;
390
391         dev_set_drvdata(&bd->pdev->dev, bd);
392         rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_state);
393         rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_baud);
394         rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_msignals);
395         rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_iflag);
396         rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_cflag);
397         rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_oflag);
398         rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_lflag);
399         rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_digi_flag);
400         rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_rxcount);
401         rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_txcount);
402         rc |= device_create_file(&(bd->pdev->dev), &dev_attr_vpd);
403         rc |= device_create_file(&(bd->pdev->dev), &dev_attr_serial_number);
404         if (rc) {
405                 printk(KERN_ERR "DGNC: sysfs device_create_file failed!\n");
406         }
407 }
408
409
410 /* removes all the sys files created for that port */
411 void dgnc_remove_ports_sysfiles(struct board_t *bd)
412 {
413         device_remove_file(&(bd->pdev->dev), &dev_attr_ports_state);
414         device_remove_file(&(bd->pdev->dev), &dev_attr_ports_baud);
415         device_remove_file(&(bd->pdev->dev), &dev_attr_ports_msignals);
416         device_remove_file(&(bd->pdev->dev), &dev_attr_ports_iflag);
417         device_remove_file(&(bd->pdev->dev), &dev_attr_ports_cflag);
418         device_remove_file(&(bd->pdev->dev), &dev_attr_ports_oflag);
419         device_remove_file(&(bd->pdev->dev), &dev_attr_ports_lflag);
420         device_remove_file(&(bd->pdev->dev), &dev_attr_ports_digi_flag);
421         device_remove_file(&(bd->pdev->dev), &dev_attr_ports_rxcount);
422         device_remove_file(&(bd->pdev->dev), &dev_attr_ports_txcount);
423         device_remove_file(&(bd->pdev->dev), &dev_attr_vpd);
424         device_remove_file(&(bd->pdev->dev), &dev_attr_serial_number);
425 }
426
427
428 static ssize_t dgnc_tty_state_show(struct device *d, struct device_attribute *attr, char *buf)
429 {
430         struct board_t *bd;
431         struct channel_t *ch;
432         struct un_t *un;
433
434         if (!d)
435                 return (0);
436         un = (struct un_t *) dev_get_drvdata(d);
437         if (!un || un->magic != DGNC_UNIT_MAGIC)
438                 return (0);
439         ch = un->un_ch;
440         if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
441                 return (0);
442         bd = ch->ch_bd;
443         if (!bd || bd->magic != DGNC_BOARD_MAGIC)
444                 return (0);
445         if (bd->state != BOARD_READY)
446                 return (0);
447
448         return snprintf(buf, PAGE_SIZE, "%s", un->un_open_count ? "Open" : "Closed");
449 }
450 static DEVICE_ATTR(state, S_IRUSR, dgnc_tty_state_show, NULL);
451
452
453 static ssize_t dgnc_tty_baud_show(struct device *d, struct device_attribute *attr, char *buf)
454 {
455         struct board_t *bd;
456         struct channel_t *ch;
457         struct un_t *un;
458
459         if (!d)
460                 return (0);
461         un = (struct un_t *) 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, "%d\n", ch->ch_old_baud);
474 }
475 static DEVICE_ATTR(baud, S_IRUSR, dgnc_tty_baud_show, NULL);
476
477
478 static ssize_t dgnc_tty_msignals_show(struct device *d, struct device_attribute *attr, char *buf)
479 {
480         struct board_t *bd;
481         struct channel_t *ch;
482         struct un_t *un;
483
484         if (!d)
485                 return (0);
486         un = (struct un_t *) 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         if (ch->ch_open_count) {
499                 return snprintf(buf, PAGE_SIZE, "%s %s %s %s %s %s\n",
500                         (ch->ch_mostat & UART_MCR_RTS) ? "RTS" : "",
501                         (ch->ch_mistat & UART_MSR_CTS) ? "CTS" : "",
502                         (ch->ch_mostat & UART_MCR_DTR) ? "DTR" : "",
503                         (ch->ch_mistat & UART_MSR_DSR) ? "DSR" : "",
504                         (ch->ch_mistat & UART_MSR_DCD) ? "DCD" : "",
505                         (ch->ch_mistat & UART_MSR_RI)  ? "RI"  : "");
506         }
507         return 0;
508 }
509 static DEVICE_ATTR(msignals, S_IRUSR, dgnc_tty_msignals_show, NULL);
510
511
512 static ssize_t dgnc_tty_iflag_show(struct device *d, struct device_attribute *attr, char *buf)
513 {
514         struct board_t *bd;
515         struct channel_t *ch;
516         struct un_t *un;
517
518         if (!d)
519                 return (0);
520         un = (struct un_t *) dev_get_drvdata(d);
521         if (!un || un->magic != DGNC_UNIT_MAGIC)
522                 return (0);
523         ch = un->un_ch;
524         if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
525                 return (0);
526         bd = ch->ch_bd;
527         if (!bd || bd->magic != DGNC_BOARD_MAGIC)
528                 return (0);
529         if (bd->state != BOARD_READY)
530                 return (0);
531
532         return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_iflag);
533 }
534 static DEVICE_ATTR(iflag, S_IRUSR, dgnc_tty_iflag_show, NULL);
535
536
537 static ssize_t dgnc_tty_cflag_show(struct device *d, struct device_attribute *attr, char *buf)
538 {
539         struct board_t *bd;
540         struct channel_t *ch;
541         struct un_t *un;
542
543         if (!d)
544                 return (0);
545         un = (struct un_t *) dev_get_drvdata(d);
546         if (!un || un->magic != DGNC_UNIT_MAGIC)
547                 return (0);
548         ch = un->un_ch;
549         if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
550                 return (0);
551         bd = ch->ch_bd;
552         if (!bd || bd->magic != DGNC_BOARD_MAGIC)
553                 return (0);
554         if (bd->state != BOARD_READY)
555                 return (0);
556
557         return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_cflag);
558 }
559 static DEVICE_ATTR(cflag, S_IRUSR, dgnc_tty_cflag_show, NULL);
560
561
562 static ssize_t dgnc_tty_oflag_show(struct device *d, struct device_attribute *attr, char *buf)
563 {
564         struct board_t *bd;
565         struct channel_t *ch;
566         struct un_t *un;
567
568         if (!d)
569                 return (0);
570         un = (struct un_t *) 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_oflag);
583 }
584 static DEVICE_ATTR(oflag, S_IRUSR, dgnc_tty_oflag_show, NULL);
585
586
587 static ssize_t dgnc_tty_lflag_show(struct device *d, struct device_attribute *attr, char *buf)
588 {
589         struct board_t *bd;
590         struct channel_t *ch;
591         struct un_t *un;
592
593         if (!d)
594                 return (0);
595         un = (struct un_t *) dev_get_drvdata(d);
596         if (!un || un->magic != DGNC_UNIT_MAGIC)
597                 return (0);
598         ch = un->un_ch;
599         if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
600                 return (0);
601         bd = ch->ch_bd;
602         if (!bd || bd->magic != DGNC_BOARD_MAGIC)
603                 return (0);
604         if (bd->state != BOARD_READY)
605                 return (0);
606
607         return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_lflag);
608 }
609 static DEVICE_ATTR(lflag, S_IRUSR, dgnc_tty_lflag_show, NULL);
610
611
612 static ssize_t dgnc_tty_digi_flag_show(struct device *d, struct device_attribute *attr, char *buf)
613 {
614         struct board_t *bd;
615         struct channel_t *ch;
616         struct un_t *un;
617
618         if (!d)
619                 return (0);
620         un = (struct un_t *) dev_get_drvdata(d);
621         if (!un || un->magic != DGNC_UNIT_MAGIC)
622                 return (0);
623         ch = un->un_ch;
624         if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
625                 return (0);
626         bd = ch->ch_bd;
627         if (!bd || bd->magic != DGNC_BOARD_MAGIC)
628                 return (0);
629         if (bd->state != BOARD_READY)
630                 return (0);
631
632         return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_digi.digi_flags);
633 }
634 static DEVICE_ATTR(digi_flag, S_IRUSR, dgnc_tty_digi_flag_show, NULL);
635
636
637 static ssize_t dgnc_tty_rxcount_show(struct device *d, struct device_attribute *attr, char *buf)
638 {
639         struct board_t *bd;
640         struct channel_t *ch;
641         struct un_t *un;
642
643         if (!d)
644                 return (0);
645         un = (struct un_t *) dev_get_drvdata(d);
646         if (!un || un->magic != DGNC_UNIT_MAGIC)
647                 return (0);
648         ch = un->un_ch;
649         if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
650                 return (0);
651         bd = ch->ch_bd;
652         if (!bd || bd->magic != DGNC_BOARD_MAGIC)
653                 return (0);
654         if (bd->state != BOARD_READY)
655                 return (0);
656
657         return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_rxcount);
658 }
659 static DEVICE_ATTR(rxcount, S_IRUSR, dgnc_tty_rxcount_show, NULL);
660
661
662 static ssize_t dgnc_tty_txcount_show(struct device *d, struct device_attribute *attr, char *buf)
663 {
664         struct board_t *bd;
665         struct channel_t *ch;
666         struct un_t *un;
667
668         if (!d)
669                 return (0);
670         un = (struct un_t *) dev_get_drvdata(d);
671         if (!un || un->magic != DGNC_UNIT_MAGIC)
672                 return (0);
673         ch = un->un_ch;
674         if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
675                 return (0);
676         bd = ch->ch_bd;
677         if (!bd || bd->magic != DGNC_BOARD_MAGIC)
678                 return (0);
679         if (bd->state != BOARD_READY)
680                 return (0);
681
682         return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_txcount);
683 }
684 static DEVICE_ATTR(txcount, S_IRUSR, dgnc_tty_txcount_show, NULL);
685
686
687 static ssize_t dgnc_tty_name_show(struct device *d, struct device_attribute *attr, char *buf)
688 {
689         struct board_t *bd;
690         struct channel_t *ch;
691         struct un_t *un;
692
693         if (!d)
694                 return (0);
695         un = (struct un_t *) dev_get_drvdata(d);
696         if (!un || un->magic != DGNC_UNIT_MAGIC)
697                 return (0);
698         ch = un->un_ch;
699         if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
700                 return (0);
701         bd = ch->ch_bd;
702         if (!bd || bd->magic != DGNC_BOARD_MAGIC)
703                 return (0);
704         if (bd->state != BOARD_READY)
705                 return (0);
706
707         return snprintf(buf, PAGE_SIZE, "%sn%d%c\n",
708                 (un->un_type == DGNC_PRINT) ? "pr" : "tty",
709                 bd->boardnum + 1, 'a' + ch->ch_portnum);
710 }
711 static DEVICE_ATTR(custom_name, S_IRUSR, dgnc_tty_name_show, NULL);
712
713
714 static struct attribute *dgnc_sysfs_tty_entries[] = {
715         &dev_attr_state.attr,
716         &dev_attr_baud.attr,
717         &dev_attr_msignals.attr,
718         &dev_attr_iflag.attr,
719         &dev_attr_cflag.attr,
720         &dev_attr_oflag.attr,
721         &dev_attr_lflag.attr,
722         &dev_attr_digi_flag.attr,
723         &dev_attr_rxcount.attr,
724         &dev_attr_txcount.attr,
725         &dev_attr_custom_name.attr,
726         NULL
727 };
728
729
730 static struct attribute_group dgnc_tty_attribute_group = {
731         .name = NULL,
732         .attrs = dgnc_sysfs_tty_entries,
733 };
734
735
736 void dgnc_create_tty_sysfs(struct un_t *un, struct device *c)
737 {
738         int ret;
739
740         ret = sysfs_create_group(&c->kobj, &dgnc_tty_attribute_group);
741         if (ret) {
742                 printk(KERN_ERR "dgnc: failed to create sysfs tty device attributes.\n");
743                 sysfs_remove_group(&c->kobj, &dgnc_tty_attribute_group);
744                 return;
745         }
746
747         dev_set_drvdata(c, un);
748
749 }
750
751
752 void dgnc_remove_tty_sysfs(struct device *c)
753 {
754         sysfs_remove_group(&c->kobj, &dgnc_tty_attribute_group);
755 }
756