]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/staging/dgap/dgap_sysfs.c
staging: dgap: tty.c: fixes termios error
[karo-tx-linux.git] / drivers / staging / dgap / dgap_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  * $Id: dgap_sysfs.c,v 1.1 2009/10/23 14:01:57 markh Exp $   
33  */
34
35
36 #include <linux/kernel.h>
37 #include <linux/version.h>
38 #include <linux/module.h>
39 #include <linux/ctype.h>
40 #include <linux/string.h>
41 #include <linux/serial_reg.h>
42 #include <linux/device.h>
43 #include <linux/pci.h>
44 #include <linux/kdev_t.h>
45   
46 #include "dgap_driver.h"
47 #include "dgap_proc.h"
48 #include "dgap_mgmt.h"
49 #include "dgap_conf.h"
50 #include "dgap_parse.h"
51
52
53 static ssize_t dgap_driver_version_show(struct device_driver *ddp, char *buf)
54 {
55         return snprintf(buf, PAGE_SIZE, "%s\n", DG_PART);
56 }
57 static DRIVER_ATTR(version, S_IRUSR, dgap_driver_version_show, NULL);
58
59
60 static ssize_t dgap_driver_boards_show(struct device_driver *ddp, char *buf)
61 {
62         return snprintf(buf, PAGE_SIZE, "%d\n", dgap_NumBoards);
63 }
64 static DRIVER_ATTR(boards, S_IRUSR, dgap_driver_boards_show, NULL);
65
66
67 static ssize_t dgap_driver_maxboards_show(struct device_driver *ddp, char *buf)
68 {
69         return snprintf(buf, PAGE_SIZE, "%d\n", MAXBOARDS);
70 }
71 static DRIVER_ATTR(maxboards, S_IRUSR, dgap_driver_maxboards_show, NULL);
72
73
74 static ssize_t dgap_driver_pollcounter_show(struct device_driver *ddp, char *buf)
75 {
76         return snprintf(buf, PAGE_SIZE, "%ld\n", dgap_poll_counter);
77 }
78 static DRIVER_ATTR(pollcounter, S_IRUSR, dgap_driver_pollcounter_show, NULL);
79
80
81 static ssize_t dgap_driver_state_show(struct device_driver *ddp, char *buf)
82 {
83         return snprintf(buf, PAGE_SIZE, "%s\n", dgap_driver_state_text[dgap_driver_state]);
84 }
85 static DRIVER_ATTR(state, S_IRUSR, dgap_driver_state_show, NULL);
86
87
88 static ssize_t dgap_driver_debug_show(struct device_driver *ddp, char *buf)
89 {
90         return snprintf(buf, PAGE_SIZE, "0x%x\n", dgap_debug);
91 }
92
93 static ssize_t dgap_driver_debug_store(struct device_driver *ddp, const char *buf, size_t count)
94 {
95         sscanf(buf, "0x%x\n", &dgap_debug);
96         return count;
97 }
98 static DRIVER_ATTR(debug, (S_IRUSR | S_IWUSR), dgap_driver_debug_show, dgap_driver_debug_store);
99
100
101 static ssize_t dgap_driver_rawreadok_show(struct device_driver *ddp, char *buf)
102 {
103         return snprintf(buf, PAGE_SIZE, "0x%x\n", dgap_rawreadok);
104 }
105
106 static ssize_t dgap_driver_rawreadok_store(struct device_driver *ddp, const char *buf, size_t count)
107 {
108         sscanf(buf, "0x%x\n", &dgap_rawreadok);
109         return count;
110 }
111 static DRIVER_ATTR(rawreadok, (S_IRUSR | S_IWUSR), dgap_driver_rawreadok_show, dgap_driver_rawreadok_store);
112
113
114 static ssize_t dgap_driver_pollrate_show(struct device_driver *ddp, char *buf)
115 {
116         return snprintf(buf, PAGE_SIZE, "%dms\n", dgap_poll_tick);
117 }
118
119 static ssize_t dgap_driver_pollrate_store(struct device_driver *ddp, const char *buf, size_t count)
120 {
121         sscanf(buf, "%d\n", &dgap_poll_tick);
122         return count;
123 }
124 static DRIVER_ATTR(pollrate, (S_IRUSR | S_IWUSR), dgap_driver_pollrate_show, dgap_driver_pollrate_store);
125
126
127 void dgap_create_driver_sysfiles(struct pci_driver *dgap_driver)
128 {
129         int rc = 0;
130         struct device_driver *driverfs = &dgap_driver->driver;
131
132         rc |= driver_create_file(driverfs, &driver_attr_version);
133         rc |= driver_create_file(driverfs, &driver_attr_boards);
134         rc |= driver_create_file(driverfs, &driver_attr_maxboards);
135         rc |= driver_create_file(driverfs, &driver_attr_debug);
136         rc |= driver_create_file(driverfs, &driver_attr_rawreadok); 
137         rc |= driver_create_file(driverfs, &driver_attr_pollrate);
138         rc |= driver_create_file(driverfs, &driver_attr_pollcounter);
139         rc |= driver_create_file(driverfs, &driver_attr_state);
140         if (rc) {
141                 printk(KERN_ERR "DGAP: sysfs driver_create_file failed!\n");
142         }
143 }
144
145
146 void dgap_remove_driver_sysfiles(struct pci_driver *dgap_driver)
147 {
148         struct device_driver *driverfs = &dgap_driver->driver;
149         driver_remove_file(driverfs, &driver_attr_version);
150         driver_remove_file(driverfs, &driver_attr_boards);
151         driver_remove_file(driverfs, &driver_attr_maxboards);
152         driver_remove_file(driverfs, &driver_attr_debug);
153         driver_remove_file(driverfs, &driver_attr_rawreadok);
154         driver_remove_file(driverfs, &driver_attr_pollrate);
155         driver_remove_file(driverfs, &driver_attr_pollcounter);
156         driver_remove_file(driverfs, &driver_attr_state);
157 }
158
159
160 #define DGAP_VERIFY_BOARD(p, bd)                        \
161         if (!p)                                         \
162                 return (0);                             \
163                                                         \
164         bd = dev_get_drvdata(p);                        \
165         if (!bd || bd->magic != DGAP_BOARD_MAGIC)       \
166                 return (0);                             \
167         if (bd->state != BOARD_READY)                   \
168                 return (0);                             \
169
170
171 static ssize_t dgap_ports_state_show(struct device *p, struct device_attribute *attr, char *buf)
172 {
173         struct board_t *bd;
174         int count = 0;
175         int i = 0;
176
177         DGAP_VERIFY_BOARD(p, bd);
178
179         for (i = 0; i < bd->nasync; i++) {
180                 count += snprintf(buf + count, PAGE_SIZE - count,
181                         "%d %s\n", bd->channels[i]->ch_portnum,
182                         bd->channels[i]->ch_open_count ? "Open" : "Closed");
183         }
184         return count;
185 }
186 static DEVICE_ATTR(ports_state, S_IRUSR, dgap_ports_state_show, NULL);
187
188
189 static ssize_t dgap_ports_baud_show(struct device *p, struct device_attribute *attr, char *buf)
190 {
191         struct board_t *bd;
192         int count = 0;
193         int i = 0;
194
195         DGAP_VERIFY_BOARD(p, bd);
196
197         for (i = 0; i < bd->nasync; i++) {
198                 count +=  snprintf(buf + count, PAGE_SIZE - count,
199                         "%d %d\n", bd->channels[i]->ch_portnum, bd->channels[i]->ch_baud_info);
200         }
201         return count;
202 }
203 static DEVICE_ATTR(ports_baud, S_IRUSR, dgap_ports_baud_show, NULL);
204
205
206 static ssize_t dgap_ports_msignals_show(struct device *p, struct device_attribute *attr, char *buf)
207 {
208         struct board_t *bd;
209         int count = 0;
210         int i = 0;
211
212         DGAP_VERIFY_BOARD(p, bd);
213
214         for (i = 0; i < bd->nasync; i++) {
215                 if (bd->channels[i]->ch_open_count) {
216                         count += snprintf(buf + count, PAGE_SIZE - count,
217                                 "%d %s %s %s %s %s %s\n", bd->channels[i]->ch_portnum,
218                                 (bd->channels[i]->ch_mostat & UART_MCR_RTS) ? "RTS" : "",
219                                 (bd->channels[i]->ch_mistat & UART_MSR_CTS) ? "CTS" : "",
220                                 (bd->channels[i]->ch_mostat & UART_MCR_DTR) ? "DTR" : "",
221                                 (bd->channels[i]->ch_mistat & UART_MSR_DSR) ? "DSR" : "",
222                                 (bd->channels[i]->ch_mistat & UART_MSR_DCD) ? "DCD" : "",
223                                 (bd->channels[i]->ch_mistat & UART_MSR_RI)  ? "RI"  : "");
224                 } else {
225                         count += snprintf(buf + count, PAGE_SIZE - count,
226                                 "%d\n", bd->channels[i]->ch_portnum);
227                 }
228         }
229         return count;
230 }
231 static DEVICE_ATTR(ports_msignals, S_IRUSR, dgap_ports_msignals_show, NULL);
232
233
234 static ssize_t dgap_ports_iflag_show(struct device *p, struct device_attribute *attr, char *buf)
235 {
236         struct board_t *bd;
237         int count = 0;
238         int i = 0;
239
240         DGAP_VERIFY_BOARD(p, bd);
241
242         for (i = 0; i < bd->nasync; i++) {
243                 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
244                         bd->channels[i]->ch_portnum, bd->channels[i]->ch_c_iflag);
245         }
246         return count;
247 }
248 static DEVICE_ATTR(ports_iflag, S_IRUSR, dgap_ports_iflag_show, NULL);
249
250
251 static ssize_t dgap_ports_cflag_show(struct device *p, struct device_attribute *attr, char *buf)
252 {
253         struct board_t *bd;
254         int count = 0;
255         int i = 0;
256
257         DGAP_VERIFY_BOARD(p, bd);
258
259         for (i = 0; i < bd->nasync; i++) {
260                 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
261                         bd->channels[i]->ch_portnum, bd->channels[i]->ch_c_cflag);
262         }
263         return count;
264 }
265 static DEVICE_ATTR(ports_cflag, S_IRUSR, dgap_ports_cflag_show, NULL);
266
267
268 static ssize_t dgap_ports_oflag_show(struct device *p, struct device_attribute *attr, char *buf)
269 {
270         struct board_t *bd;
271         int count = 0;
272         int i = 0;
273
274         DGAP_VERIFY_BOARD(p, bd);
275
276         for (i = 0; i < bd->nasync; i++) {
277                 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
278                         bd->channels[i]->ch_portnum, bd->channels[i]->ch_c_oflag);
279         }
280         return count;
281 }
282 static DEVICE_ATTR(ports_oflag, S_IRUSR, dgap_ports_oflag_show, NULL);
283
284
285 static ssize_t dgap_ports_lflag_show(struct device *p, struct device_attribute *attr, char *buf)
286 {
287         struct board_t *bd;
288         int count = 0;
289         int i = 0;
290
291         DGAP_VERIFY_BOARD(p, bd);
292
293         for (i = 0; i < bd->nasync; i++) {
294                 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
295                         bd->channels[i]->ch_portnum, bd->channels[i]->ch_c_lflag);
296         }
297         return count;
298 }
299 static DEVICE_ATTR(ports_lflag, S_IRUSR, dgap_ports_lflag_show, NULL);
300
301
302 static ssize_t dgap_ports_digi_flag_show(struct device *p, struct device_attribute *attr, char *buf)
303 {
304         struct board_t *bd;
305         int count = 0;
306         int i = 0;
307
308         DGAP_VERIFY_BOARD(p, bd);
309
310         for (i = 0; i < bd->nasync; i++) {
311                 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
312                         bd->channels[i]->ch_portnum, bd->channels[i]->ch_digi.digi_flags);
313         }
314         return count;
315 }
316 static DEVICE_ATTR(ports_digi_flag, S_IRUSR, dgap_ports_digi_flag_show, NULL);
317
318
319 static ssize_t dgap_ports_rxcount_show(struct device *p, struct device_attribute *attr, char *buf)
320 {
321         struct board_t *bd;
322         int count = 0;
323         int i = 0;
324
325         DGAP_VERIFY_BOARD(p, bd);
326
327         for (i = 0; i < bd->nasync; i++) {
328                 count += snprintf(buf + count, PAGE_SIZE - count, "%d %ld\n",
329                         bd->channels[i]->ch_portnum, bd->channels[i]->ch_rxcount);
330         }
331         return count;
332 }
333 static DEVICE_ATTR(ports_rxcount, S_IRUSR, dgap_ports_rxcount_show, NULL);
334
335
336 static ssize_t dgap_ports_txcount_show(struct device *p, struct device_attribute *attr, char *buf)
337 {
338         struct board_t *bd;
339         int count = 0;
340         int i = 0;
341
342         DGAP_VERIFY_BOARD(p, bd);
343
344         for (i = 0; i < bd->nasync; i++) {
345                 count += snprintf(buf + count, PAGE_SIZE - count, "%d %ld\n",
346                         bd->channels[i]->ch_portnum, bd->channels[i]->ch_txcount);
347         }
348         return count;
349 }
350 static DEVICE_ATTR(ports_txcount, S_IRUSR, dgap_ports_txcount_show, NULL);
351
352
353 /* this function creates the sys files that will export each signal status
354  * to sysfs each value will be put in a separate filename
355  */
356 void dgap_create_ports_sysfiles(struct board_t *bd)
357 {
358         int rc = 0;
359
360         dev_set_drvdata(&bd->pdev->dev, bd);
361         rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_state);
362         rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_baud);
363         rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_msignals);
364         rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_iflag);
365         rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_cflag);
366         rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_oflag);
367         rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_lflag);
368         rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_digi_flag);
369         rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_rxcount);
370         rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_txcount);
371         if (rc) {
372                 printk(KERN_ERR "DGAP: sysfs device_create_file failed!\n");
373         }
374 }
375
376
377 /* removes all the sys files created for that port */
378 void dgap_remove_ports_sysfiles(struct board_t *bd)
379 {
380         device_remove_file(&(bd->pdev->dev), &dev_attr_ports_state);
381         device_remove_file(&(bd->pdev->dev), &dev_attr_ports_baud);
382         device_remove_file(&(bd->pdev->dev), &dev_attr_ports_msignals);
383         device_remove_file(&(bd->pdev->dev), &dev_attr_ports_iflag);
384         device_remove_file(&(bd->pdev->dev), &dev_attr_ports_cflag);
385         device_remove_file(&(bd->pdev->dev), &dev_attr_ports_oflag);
386         device_remove_file(&(bd->pdev->dev), &dev_attr_ports_lflag);
387         device_remove_file(&(bd->pdev->dev), &dev_attr_ports_digi_flag);
388         device_remove_file(&(bd->pdev->dev), &dev_attr_ports_rxcount);
389         device_remove_file(&(bd->pdev->dev), &dev_attr_ports_txcount);
390 }
391
392
393 static ssize_t dgap_tty_state_show(struct device *d, struct device_attribute *attr, char *buf)
394 {
395         struct board_t *bd;
396         struct channel_t *ch;
397         struct un_t *un;
398
399         if (!d)
400                 return (0);
401         un = (struct un_t *) dev_get_drvdata(d);
402         if (!un || un->magic != DGAP_UNIT_MAGIC)
403                 return (0);
404         ch = un->un_ch;
405         if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
406                 return (0);
407         bd = ch->ch_bd;
408         if (!bd || bd->magic != DGAP_BOARD_MAGIC)
409                 return (0);
410         if (bd->state != BOARD_READY)
411                 return (0);
412
413         return snprintf(buf, PAGE_SIZE, "%s", un->un_open_count ? "Open" : "Closed");
414 }
415 static DEVICE_ATTR(state, S_IRUSR, dgap_tty_state_show, NULL);
416
417
418 static ssize_t dgap_tty_baud_show(struct device *d, struct device_attribute *attr, char *buf)
419 {
420         struct board_t *bd;
421         struct channel_t *ch;
422         struct un_t *un;
423
424         if (!d)
425                 return (0);
426         un = (struct un_t *) dev_get_drvdata(d);
427         if (!un || un->magic != DGAP_UNIT_MAGIC)
428                 return (0);
429         ch = un->un_ch;
430         if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
431                 return (0);
432         bd = ch->ch_bd;
433         if (!bd || bd->magic != DGAP_BOARD_MAGIC)
434                 return (0);
435         if (bd->state != BOARD_READY)
436                 return (0);
437
438         return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_baud_info);
439 }
440 static DEVICE_ATTR(baud, S_IRUSR, dgap_tty_baud_show, NULL);
441
442
443 static ssize_t dgap_tty_msignals_show(struct device *d, struct device_attribute *attr, char *buf)
444 {
445         struct board_t *bd;
446         struct channel_t *ch;
447         struct un_t *un;
448
449         if (!d)
450                 return (0);
451         un = (struct un_t *) dev_get_drvdata(d);
452         if (!un || un->magic != DGAP_UNIT_MAGIC)
453                 return (0);
454         ch = un->un_ch;
455         if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
456                 return (0);
457         bd = ch->ch_bd;
458         if (!bd || bd->magic != DGAP_BOARD_MAGIC)
459                 return (0);
460         if (bd->state != BOARD_READY)
461                 return (0);
462
463         if (ch->ch_open_count) {
464                 return snprintf(buf, PAGE_SIZE, "%s %s %s %s %s %s\n",
465                         (ch->ch_mostat & UART_MCR_RTS) ? "RTS" : "",
466                         (ch->ch_mistat & UART_MSR_CTS) ? "CTS" : "",
467                         (ch->ch_mostat & UART_MCR_DTR) ? "DTR" : "",
468                         (ch->ch_mistat & UART_MSR_DSR) ? "DSR" : "",
469                         (ch->ch_mistat & UART_MSR_DCD) ? "DCD" : "",
470                         (ch->ch_mistat & UART_MSR_RI)  ? "RI"  : "");
471         }
472         return 0;
473 }
474 static DEVICE_ATTR(msignals, S_IRUSR, dgap_tty_msignals_show, NULL);
475
476
477 static ssize_t dgap_tty_iflag_show(struct device *d, struct device_attribute *attr, char *buf)
478 {
479         struct board_t *bd;
480         struct channel_t *ch;
481         struct un_t *un;
482
483         if (!d)
484                 return (0);
485         un = (struct un_t *) dev_get_drvdata(d);
486         if (!un || un->magic != DGAP_UNIT_MAGIC)
487                 return (0);
488         ch = un->un_ch;
489         if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
490                 return (0);
491         bd = ch->ch_bd;
492         if (!bd || bd->magic != DGAP_BOARD_MAGIC)
493                 return (0);
494         if (bd->state != BOARD_READY)
495                 return (0);
496
497         return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_iflag);
498 }
499 static DEVICE_ATTR(iflag, S_IRUSR, dgap_tty_iflag_show, NULL);
500
501
502 static ssize_t dgap_tty_cflag_show(struct device *d, struct device_attribute *attr, char *buf)
503 {
504         struct board_t *bd;
505         struct channel_t *ch;
506         struct un_t *un;
507
508         if (!d)
509                 return (0);
510         un = (struct un_t *) dev_get_drvdata(d);
511         if (!un || un->magic != DGAP_UNIT_MAGIC)
512                 return (0);
513         ch = un->un_ch;
514         if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
515                 return (0);
516         bd = ch->ch_bd;
517         if (!bd || bd->magic != DGAP_BOARD_MAGIC)
518                 return (0);
519         if (bd->state != BOARD_READY)
520                 return (0);
521
522         return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_cflag);
523 }
524 static DEVICE_ATTR(cflag, S_IRUSR, dgap_tty_cflag_show, NULL);
525
526
527 static ssize_t dgap_tty_oflag_show(struct device *d, struct device_attribute *attr, char *buf)
528 {
529         struct board_t *bd;
530         struct channel_t *ch;
531         struct un_t *un;
532
533         if (!d)
534                 return (0);
535         un = (struct un_t *) dev_get_drvdata(d);
536         if (!un || un->magic != DGAP_UNIT_MAGIC)
537                 return (0);
538         ch = un->un_ch;
539         if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
540                 return (0);
541         bd = ch->ch_bd;
542         if (!bd || bd->magic != DGAP_BOARD_MAGIC)
543                 return (0);
544         if (bd->state != BOARD_READY)
545                 return (0);
546
547         return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_oflag);
548 }
549 static DEVICE_ATTR(oflag, S_IRUSR, dgap_tty_oflag_show, NULL);
550
551
552 static ssize_t dgap_tty_lflag_show(struct device *d, struct device_attribute *attr, char *buf)
553 {
554         struct board_t *bd;
555         struct channel_t *ch;
556         struct un_t *un;
557
558         if (!d)
559                 return (0);
560         un = (struct un_t *) dev_get_drvdata(d);
561         if (!un || un->magic != DGAP_UNIT_MAGIC)
562                 return (0);
563         ch = un->un_ch;
564         if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
565                 return (0);
566         bd = ch->ch_bd;
567         if (!bd || bd->magic != DGAP_BOARD_MAGIC)
568                 return (0);
569         if (bd->state != BOARD_READY)
570                 return (0);
571
572         return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_lflag);
573 }
574 static DEVICE_ATTR(lflag, S_IRUSR, dgap_tty_lflag_show, NULL);
575
576
577 static ssize_t dgap_tty_digi_flag_show(struct device *d, struct device_attribute *attr, char *buf)
578 {
579         struct board_t *bd;
580         struct channel_t *ch;
581         struct un_t *un;
582
583         if (!d)
584                 return (0);
585         un = (struct un_t *) dev_get_drvdata(d);
586         if (!un || un->magic != DGAP_UNIT_MAGIC)
587                 return (0);
588         ch = un->un_ch;
589         if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
590                 return (0);
591         bd = ch->ch_bd;
592         if (!bd || bd->magic != DGAP_BOARD_MAGIC)
593                 return (0);
594         if (bd->state != BOARD_READY)
595                 return (0);
596
597         return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_digi.digi_flags);
598 }
599 static DEVICE_ATTR(digi_flag, S_IRUSR, dgap_tty_digi_flag_show, NULL);
600
601
602 static ssize_t dgap_tty_rxcount_show(struct device *d, struct device_attribute *attr, char *buf)
603 {
604         struct board_t *bd;
605         struct channel_t *ch;
606         struct un_t *un;
607
608         if (!d)
609                 return (0);
610         un = (struct un_t *) dev_get_drvdata(d);
611         if (!un || un->magic != DGAP_UNIT_MAGIC)
612                 return (0);
613         ch = un->un_ch;
614         if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
615                 return (0);
616         bd = ch->ch_bd;
617         if (!bd || bd->magic != DGAP_BOARD_MAGIC)
618                 return (0);
619         if (bd->state != BOARD_READY)
620                 return (0);
621
622         return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_rxcount);
623 }
624 static DEVICE_ATTR(rxcount, S_IRUSR, dgap_tty_rxcount_show, NULL);
625
626
627 static ssize_t dgap_tty_txcount_show(struct device *d, struct device_attribute *attr, char *buf)
628 {
629         struct board_t *bd;
630         struct channel_t *ch;
631         struct un_t *un;
632
633         if (!d)
634                 return (0);
635         un = (struct un_t *) dev_get_drvdata(d);
636         if (!un || un->magic != DGAP_UNIT_MAGIC)
637                 return (0);
638         ch = un->un_ch;
639         if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
640                 return (0);
641         bd = ch->ch_bd;
642         if (!bd || bd->magic != DGAP_BOARD_MAGIC)
643                 return (0);
644         if (bd->state != BOARD_READY)
645                 return (0);
646
647         return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_txcount);
648 }
649 static DEVICE_ATTR(txcount, S_IRUSR, dgap_tty_txcount_show, NULL);
650
651
652 static ssize_t dgap_tty_name_show(struct device *d, struct device_attribute *attr, char *buf)
653 {
654         struct board_t *bd;
655         struct channel_t *ch;
656         struct un_t *un;
657         int     cn;
658         int     bn;
659         struct cnode *cptr = NULL;
660         int found = FALSE;
661         int ncount = 0;
662         int starto = 0;
663         int i = 0;
664
665         if (!d)
666                 return (0);
667         un = (struct un_t *) dev_get_drvdata(d);
668         if (!un || un->magic != DGAP_UNIT_MAGIC)
669                 return (0);
670         ch = un->un_ch;
671         if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
672                 return (0);
673         bd = ch->ch_bd;
674         if (!bd || bd->magic != DGAP_BOARD_MAGIC)
675                 return (0);
676         if (bd->state != BOARD_READY)
677                 return (0);
678
679         bn = bd->boardnum;
680         cn = ch->ch_portnum;
681
682         for (cptr = bd->bd_config; cptr; cptr = cptr->next) {
683
684                 if ((cptr->type == BNODE) &&
685                     ((cptr->u.board.type == APORT2_920P) || (cptr->u.board.type == APORT4_920P) ||
686                      (cptr->u.board.type == APORT8_920P) || (cptr->u.board.type == PAPORT4) ||
687                      (cptr->u.board.type == PAPORT8))) {
688
689                                 found = TRUE;
690                                 if (cptr->u.board.v_start)
691                                         starto = cptr->u.board.start;
692                                 else
693                                         starto = 1;
694                 }
695
696                 if (cptr->type == TNODE && found == TRUE) {
697                         char *ptr1;
698                         if (strstr(cptr->u.ttyname, "tty")) {
699                                 ptr1 = cptr->u.ttyname;
700                                 ptr1 += 3;
701                         }
702                         else {
703                                 ptr1 = cptr->u.ttyname;
704                         }
705
706                         for (i = 0; i < dgap_config_get_number_of_ports(bd); i++) {
707                                 if (cn == i) {
708                                         return snprintf(buf, PAGE_SIZE, "%s%s%02d\n",
709                                                 (un->un_type == DGAP_PRINT) ? "pr" : "tty",
710                                                 ptr1, i + starto);
711                                 }
712                         }
713                 }
714
715                 if (cptr->type == CNODE) {
716
717                         for (i = 0; i < cptr->u.conc.nport; i++) {
718                                 if (cn == (i + ncount)) {
719
720                                         return snprintf(buf, PAGE_SIZE, "%s%s%02d\n",
721                                                 (un->un_type == DGAP_PRINT) ? "pr" : "tty",
722                                                 cptr->u.conc.id,
723                                                 i + (cptr->u.conc.v_start ? cptr->u.conc.start : 1));
724                                 }
725                         }
726
727                         ncount += cptr->u.conc.nport;
728                 }
729
730                 if (cptr->type == MNODE) {
731
732                         for (i = 0; i < cptr->u.module.nport; i++) {
733                                 if (cn == (i + ncount)) {
734                                         return snprintf(buf, PAGE_SIZE, "%s%s%02d\n",
735                                                 (un->un_type == DGAP_PRINT) ? "pr" : "tty",
736                                                 cptr->u.module.id,
737                                                 i + (cptr->u.module.v_start ? cptr->u.module.start : 1));
738                                 }
739                         }
740
741                         ncount += cptr->u.module.nport;
742
743                 }
744         }
745
746         return snprintf(buf, PAGE_SIZE, "%s_dgap_%d_%d\n",
747                 (un->un_type == DGAP_PRINT) ? "pr" : "tty", bn, cn);
748
749 }
750 static DEVICE_ATTR(custom_name, S_IRUSR, dgap_tty_name_show, NULL);
751
752
753 static struct attribute *dgap_sysfs_tty_entries[] = {
754         &dev_attr_state.attr,
755         &dev_attr_baud.attr,
756         &dev_attr_msignals.attr,
757         &dev_attr_iflag.attr,
758         &dev_attr_cflag.attr,
759         &dev_attr_oflag.attr,
760         &dev_attr_lflag.attr,
761         &dev_attr_digi_flag.attr,
762         &dev_attr_rxcount.attr,
763         &dev_attr_txcount.attr,
764         &dev_attr_custom_name.attr,
765         NULL
766 };
767
768
769 static struct attribute_group dgap_tty_attribute_group = {
770         .name = NULL,
771         .attrs = dgap_sysfs_tty_entries,
772 };
773
774
775
776
777 void dgap_create_tty_sysfs(struct un_t *un, struct device *c)
778 {
779         int ret;
780
781         ret = sysfs_create_group(&c->kobj, &dgap_tty_attribute_group);
782         if (ret) {
783                 printk(KERN_ERR "dgap: failed to create sysfs tty device attributes.\n");
784                 sysfs_remove_group(&c->kobj, &dgap_tty_attribute_group);
785                 return;
786         }
787
788         dev_set_drvdata(c, un);
789
790 }
791
792
793 void dgap_remove_tty_sysfs(struct device *c)
794 {
795         sysfs_remove_group(&c->kobj, &dgap_tty_attribute_group);
796 }