2 * Copyright 2004 Digi International (www.digi.com)
3 * Scott H Kilau <Scott_Kilau at digi dot com>
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)
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.
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.
20 * NOTE TO LINUX KERNEL HACKERS: DO NOT REFORMAT THIS CODE!
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.
27 * Send any bug fixes/changes to: Eng.Linux at digi dot com.
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>
42 #include "dgnc_driver.h"
43 #include "dgnc_mgmt.h"
46 static ssize_t
dgnc_driver_version_show(struct device_driver
*ddp
, char *buf
)
48 return snprintf(buf
, PAGE_SIZE
, "%s\n", DG_PART
);
50 static DRIVER_ATTR(version
, S_IRUSR
, dgnc_driver_version_show
, NULL
);
53 static ssize_t
dgnc_driver_boards_show(struct device_driver
*ddp
, char *buf
)
55 return snprintf(buf
, PAGE_SIZE
, "%d\n", dgnc_NumBoards
);
57 static DRIVER_ATTR(boards
, S_IRUSR
, dgnc_driver_boards_show
, NULL
);
60 static ssize_t
dgnc_driver_maxboards_show(struct device_driver
*ddp
, char *buf
)
62 return snprintf(buf
, PAGE_SIZE
, "%d\n", MAXBOARDS
);
64 static DRIVER_ATTR(maxboards
, S_IRUSR
, dgnc_driver_maxboards_show
, NULL
);
66 static ssize_t
dgnc_driver_debug_show(struct device_driver
*ddp
, char *buf
)
68 return snprintf(buf
, PAGE_SIZE
, "0x%x\n", dgnc_debug
);
71 static ssize_t
dgnc_driver_debug_store(struct device_driver
*ddp
, const char *buf
, size_t count
)
73 sscanf(buf
, "0x%x\n", &dgnc_debug
);
76 static DRIVER_ATTR(debug
, (S_IRUSR
| S_IWUSR
), dgnc_driver_debug_show
, dgnc_driver_debug_store
);
79 static ssize_t
dgnc_driver_rawreadok_show(struct device_driver
*ddp
, char *buf
)
81 return snprintf(buf
, PAGE_SIZE
, "0x%x\n", dgnc_rawreadok
);
84 static ssize_t
dgnc_driver_rawreadok_store(struct device_driver
*ddp
, const char *buf
, size_t count
)
86 sscanf(buf
, "0x%x\n", &dgnc_rawreadok
);
89 static DRIVER_ATTR(rawreadok
, (S_IRUSR
| S_IWUSR
), dgnc_driver_rawreadok_show
, dgnc_driver_rawreadok_store
);
92 static ssize_t
dgnc_driver_pollrate_show(struct device_driver
*ddp
, char *buf
)
94 return snprintf(buf
, PAGE_SIZE
, "%dms\n", dgnc_poll_tick
);
97 static ssize_t
dgnc_driver_pollrate_store(struct device_driver
*ddp
, const char *buf
, size_t count
)
99 sscanf(buf
, "%d\n", &dgnc_poll_tick
);
102 static DRIVER_ATTR(pollrate
, (S_IRUSR
| S_IWUSR
), dgnc_driver_pollrate_show
, dgnc_driver_pollrate_store
);
105 void dgnc_create_driver_sysfiles(struct pci_driver
*dgnc_driver
)
108 struct device_driver
*driverfs
= &dgnc_driver
->driver
;
110 rc
|= driver_create_file(driverfs
, &driver_attr_version
);
111 rc
|= driver_create_file(driverfs
, &driver_attr_boards
);
112 rc
|= driver_create_file(driverfs
, &driver_attr_maxboards
);
113 rc
|= driver_create_file(driverfs
, &driver_attr_debug
);
114 rc
|= driver_create_file(driverfs
, &driver_attr_rawreadok
);
115 rc
|= driver_create_file(driverfs
, &driver_attr_pollrate
);
117 printk(KERN_ERR
"DGNC: sysfs driver_create_file failed!\n");
122 void dgnc_remove_driver_sysfiles(struct pci_driver
*dgnc_driver
)
124 struct device_driver
*driverfs
= &dgnc_driver
->driver
;
125 driver_remove_file(driverfs
, &driver_attr_version
);
126 driver_remove_file(driverfs
, &driver_attr_boards
);
127 driver_remove_file(driverfs
, &driver_attr_maxboards
);
128 driver_remove_file(driverfs
, &driver_attr_debug
);
129 driver_remove_file(driverfs
, &driver_attr_rawreadok
);
130 driver_remove_file(driverfs
, &driver_attr_pollrate
);
134 #define DGNC_VERIFY_BOARD(p, bd) \
139 bd = dev_get_drvdata(p); \
140 if (!bd || bd->magic != DGNC_BOARD_MAGIC) \
142 if (bd->state != BOARD_READY) \
148 static ssize_t
dgnc_vpd_show(struct device
*p
, struct device_attribute
*attr
, char *buf
)
150 struct dgnc_board
*bd
;
154 DGNC_VERIFY_BOARD(p
, bd
);
156 count
+= sprintf(buf
+ count
, "\n 0 1 2 3 4 5 6 7 8 9 A B C D E F");
157 for (i
= 0; i
< 0x40 * 2; i
++) {
159 count
+= sprintf(buf
+ count
, "\n%04X ", i
* 2);
160 count
+= sprintf(buf
+ count
, "%02X ", bd
->vpd
[i
]);
162 count
+= sprintf(buf
+ count
, "\n");
166 static DEVICE_ATTR(vpd
, S_IRUSR
, dgnc_vpd_show
, NULL
);
168 static ssize_t
dgnc_serial_number_show(struct device
*p
, struct device_attribute
*attr
, char *buf
)
170 struct dgnc_board
*bd
;
173 DGNC_VERIFY_BOARD(p
, bd
);
175 if (bd
->serial_num
[0] == '\0')
176 count
+= sprintf(buf
+ count
, "<UNKNOWN>\n");
178 count
+= sprintf(buf
+ count
, "%s\n", bd
->serial_num
);
182 static DEVICE_ATTR(serial_number
, S_IRUSR
, dgnc_serial_number_show
, NULL
);
185 static ssize_t
dgnc_ports_state_show(struct device
*p
, struct device_attribute
*attr
, char *buf
)
187 struct dgnc_board
*bd
;
191 DGNC_VERIFY_BOARD(p
, bd
);
193 for (i
= 0; i
< bd
->nasync
; i
++) {
194 count
+= snprintf(buf
+ count
, PAGE_SIZE
- count
,
195 "%d %s\n", bd
->channels
[i
]->ch_portnum
,
196 bd
->channels
[i
]->ch_open_count
? "Open" : "Closed");
200 static DEVICE_ATTR(ports_state
, S_IRUSR
, dgnc_ports_state_show
, NULL
);
203 static ssize_t
dgnc_ports_baud_show(struct device
*p
, struct device_attribute
*attr
, char *buf
)
205 struct dgnc_board
*bd
;
209 DGNC_VERIFY_BOARD(p
, bd
);
211 for (i
= 0; i
< bd
->nasync
; i
++) {
212 count
+= snprintf(buf
+ count
, PAGE_SIZE
- count
,
213 "%d %d\n", bd
->channels
[i
]->ch_portnum
, bd
->channels
[i
]->ch_old_baud
);
217 static DEVICE_ATTR(ports_baud
, S_IRUSR
, dgnc_ports_baud_show
, NULL
);
220 static ssize_t
dgnc_ports_msignals_show(struct device
*p
, struct device_attribute
*attr
, char *buf
)
222 struct dgnc_board
*bd
;
226 DGNC_VERIFY_BOARD(p
, bd
);
228 for (i
= 0; i
< bd
->nasync
; i
++) {
229 if (bd
->channels
[i
]->ch_open_count
) {
230 count
+= snprintf(buf
+ count
, PAGE_SIZE
- count
,
231 "%d %s %s %s %s %s %s\n", bd
->channels
[i
]->ch_portnum
,
232 (bd
->channels
[i
]->ch_mostat
& UART_MCR_RTS
) ? "RTS" : "",
233 (bd
->channels
[i
]->ch_mistat
& UART_MSR_CTS
) ? "CTS" : "",
234 (bd
->channels
[i
]->ch_mostat
& UART_MCR_DTR
) ? "DTR" : "",
235 (bd
->channels
[i
]->ch_mistat
& UART_MSR_DSR
) ? "DSR" : "",
236 (bd
->channels
[i
]->ch_mistat
& UART_MSR_DCD
) ? "DCD" : "",
237 (bd
->channels
[i
]->ch_mistat
& UART_MSR_RI
) ? "RI" : "");
239 count
+= snprintf(buf
+ count
, PAGE_SIZE
- count
,
240 "%d\n", bd
->channels
[i
]->ch_portnum
);
245 static DEVICE_ATTR(ports_msignals
, S_IRUSR
, dgnc_ports_msignals_show
, NULL
);
248 static ssize_t
dgnc_ports_iflag_show(struct device
*p
, struct device_attribute
*attr
, char *buf
)
250 struct dgnc_board
*bd
;
254 DGNC_VERIFY_BOARD(p
, bd
);
256 for (i
= 0; i
< bd
->nasync
; i
++) {
257 count
+= snprintf(buf
+ count
, PAGE_SIZE
- count
, "%d %x\n",
258 bd
->channels
[i
]->ch_portnum
, bd
->channels
[i
]->ch_c_iflag
);
262 static DEVICE_ATTR(ports_iflag
, S_IRUSR
, dgnc_ports_iflag_show
, NULL
);
265 static ssize_t
dgnc_ports_cflag_show(struct device
*p
, struct device_attribute
*attr
, char *buf
)
267 struct dgnc_board
*bd
;
271 DGNC_VERIFY_BOARD(p
, bd
);
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_cflag
);
279 static DEVICE_ATTR(ports_cflag
, S_IRUSR
, dgnc_ports_cflag_show
, NULL
);
282 static ssize_t
dgnc_ports_oflag_show(struct device
*p
, struct device_attribute
*attr
, char *buf
)
284 struct dgnc_board
*bd
;
288 DGNC_VERIFY_BOARD(p
, bd
);
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_oflag
);
296 static DEVICE_ATTR(ports_oflag
, S_IRUSR
, dgnc_ports_oflag_show
, NULL
);
299 static ssize_t
dgnc_ports_lflag_show(struct device
*p
, struct device_attribute
*attr
, char *buf
)
301 struct dgnc_board
*bd
;
305 DGNC_VERIFY_BOARD(p
, bd
);
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_lflag
);
313 static DEVICE_ATTR(ports_lflag
, S_IRUSR
, dgnc_ports_lflag_show
, NULL
);
316 static ssize_t
dgnc_ports_digi_flag_show(struct device
*p
, struct device_attribute
*attr
, char *buf
)
318 struct dgnc_board
*bd
;
322 DGNC_VERIFY_BOARD(p
, bd
);
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_digi
.digi_flags
);
330 static DEVICE_ATTR(ports_digi_flag
, S_IRUSR
, dgnc_ports_digi_flag_show
, NULL
);
333 static ssize_t
dgnc_ports_rxcount_show(struct device
*p
, struct device_attribute
*attr
, char *buf
)
335 struct dgnc_board
*bd
;
339 DGNC_VERIFY_BOARD(p
, bd
);
341 for (i
= 0; i
< bd
->nasync
; i
++) {
342 count
+= snprintf(buf
+ count
, PAGE_SIZE
- count
, "%d %ld\n",
343 bd
->channels
[i
]->ch_portnum
, bd
->channels
[i
]->ch_rxcount
);
347 static DEVICE_ATTR(ports_rxcount
, S_IRUSR
, dgnc_ports_rxcount_show
, NULL
);
350 static ssize_t
dgnc_ports_txcount_show(struct device
*p
, struct device_attribute
*attr
, char *buf
)
352 struct dgnc_board
*bd
;
356 DGNC_VERIFY_BOARD(p
, bd
);
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_txcount
);
364 static DEVICE_ATTR(ports_txcount
, S_IRUSR
, dgnc_ports_txcount_show
, NULL
);
367 /* this function creates the sys files that will export each signal status
368 * to sysfs each value will be put in a separate filename
370 void dgnc_create_ports_sysfiles(struct dgnc_board
*bd
)
374 dev_set_drvdata(&bd
->pdev
->dev
, bd
);
375 rc
|= device_create_file(&(bd
->pdev
->dev
), &dev_attr_ports_state
);
376 rc
|= device_create_file(&(bd
->pdev
->dev
), &dev_attr_ports_baud
);
377 rc
|= device_create_file(&(bd
->pdev
->dev
), &dev_attr_ports_msignals
);
378 rc
|= device_create_file(&(bd
->pdev
->dev
), &dev_attr_ports_iflag
);
379 rc
|= device_create_file(&(bd
->pdev
->dev
), &dev_attr_ports_cflag
);
380 rc
|= device_create_file(&(bd
->pdev
->dev
), &dev_attr_ports_oflag
);
381 rc
|= device_create_file(&(bd
->pdev
->dev
), &dev_attr_ports_lflag
);
382 rc
|= device_create_file(&(bd
->pdev
->dev
), &dev_attr_ports_digi_flag
);
383 rc
|= device_create_file(&(bd
->pdev
->dev
), &dev_attr_ports_rxcount
);
384 rc
|= device_create_file(&(bd
->pdev
->dev
), &dev_attr_ports_txcount
);
385 rc
|= device_create_file(&(bd
->pdev
->dev
), &dev_attr_vpd
);
386 rc
|= device_create_file(&(bd
->pdev
->dev
), &dev_attr_serial_number
);
388 printk(KERN_ERR
"DGNC: sysfs device_create_file failed!\n");
393 /* removes all the sys files created for that port */
394 void dgnc_remove_ports_sysfiles(struct dgnc_board
*bd
)
396 device_remove_file(&(bd
->pdev
->dev
), &dev_attr_ports_state
);
397 device_remove_file(&(bd
->pdev
->dev
), &dev_attr_ports_baud
);
398 device_remove_file(&(bd
->pdev
->dev
), &dev_attr_ports_msignals
);
399 device_remove_file(&(bd
->pdev
->dev
), &dev_attr_ports_iflag
);
400 device_remove_file(&(bd
->pdev
->dev
), &dev_attr_ports_cflag
);
401 device_remove_file(&(bd
->pdev
->dev
), &dev_attr_ports_oflag
);
402 device_remove_file(&(bd
->pdev
->dev
), &dev_attr_ports_lflag
);
403 device_remove_file(&(bd
->pdev
->dev
), &dev_attr_ports_digi_flag
);
404 device_remove_file(&(bd
->pdev
->dev
), &dev_attr_ports_rxcount
);
405 device_remove_file(&(bd
->pdev
->dev
), &dev_attr_ports_txcount
);
406 device_remove_file(&(bd
->pdev
->dev
), &dev_attr_vpd
);
407 device_remove_file(&(bd
->pdev
->dev
), &dev_attr_serial_number
);
411 static ssize_t
dgnc_tty_state_show(struct device
*d
, struct device_attribute
*attr
, char *buf
)
413 struct dgnc_board
*bd
;
414 struct channel_t
*ch
;
419 un
= dev_get_drvdata(d
);
420 if (!un
|| un
->magic
!= DGNC_UNIT_MAGIC
)
423 if (!ch
|| ch
->magic
!= DGNC_CHANNEL_MAGIC
)
426 if (!bd
|| bd
->magic
!= DGNC_BOARD_MAGIC
)
428 if (bd
->state
!= BOARD_READY
)
431 return snprintf(buf
, PAGE_SIZE
, "%s", un
->un_open_count
? "Open" : "Closed");
433 static DEVICE_ATTR(state
, S_IRUSR
, dgnc_tty_state_show
, NULL
);
436 static ssize_t
dgnc_tty_baud_show(struct device
*d
, struct device_attribute
*attr
, char *buf
)
438 struct dgnc_board
*bd
;
439 struct channel_t
*ch
;
444 un
= dev_get_drvdata(d
);
445 if (!un
|| un
->magic
!= DGNC_UNIT_MAGIC
)
448 if (!ch
|| ch
->magic
!= DGNC_CHANNEL_MAGIC
)
451 if (!bd
|| bd
->magic
!= DGNC_BOARD_MAGIC
)
453 if (bd
->state
!= BOARD_READY
)
456 return snprintf(buf
, PAGE_SIZE
, "%d\n", ch
->ch_old_baud
);
458 static DEVICE_ATTR(baud
, S_IRUSR
, dgnc_tty_baud_show
, NULL
);
461 static ssize_t
dgnc_tty_msignals_show(struct device
*d
, struct device_attribute
*attr
, char *buf
)
463 struct dgnc_board
*bd
;
464 struct channel_t
*ch
;
469 un
= dev_get_drvdata(d
);
470 if (!un
|| un
->magic
!= DGNC_UNIT_MAGIC
)
473 if (!ch
|| ch
->magic
!= DGNC_CHANNEL_MAGIC
)
476 if (!bd
|| bd
->magic
!= DGNC_BOARD_MAGIC
)
478 if (bd
->state
!= BOARD_READY
)
481 if (ch
->ch_open_count
) {
482 return snprintf(buf
, PAGE_SIZE
, "%s %s %s %s %s %s\n",
483 (ch
->ch_mostat
& UART_MCR_RTS
) ? "RTS" : "",
484 (ch
->ch_mistat
& UART_MSR_CTS
) ? "CTS" : "",
485 (ch
->ch_mostat
& UART_MCR_DTR
) ? "DTR" : "",
486 (ch
->ch_mistat
& UART_MSR_DSR
) ? "DSR" : "",
487 (ch
->ch_mistat
& UART_MSR_DCD
) ? "DCD" : "",
488 (ch
->ch_mistat
& UART_MSR_RI
) ? "RI" : "");
492 static DEVICE_ATTR(msignals
, S_IRUSR
, dgnc_tty_msignals_show
, NULL
);
495 static ssize_t
dgnc_tty_iflag_show(struct device
*d
, struct device_attribute
*attr
, char *buf
)
497 struct dgnc_board
*bd
;
498 struct channel_t
*ch
;
503 un
= dev_get_drvdata(d
);
504 if (!un
|| un
->magic
!= DGNC_UNIT_MAGIC
)
507 if (!ch
|| ch
->magic
!= DGNC_CHANNEL_MAGIC
)
510 if (!bd
|| bd
->magic
!= DGNC_BOARD_MAGIC
)
512 if (bd
->state
!= BOARD_READY
)
515 return snprintf(buf
, PAGE_SIZE
, "%x\n", ch
->ch_c_iflag
);
517 static DEVICE_ATTR(iflag
, S_IRUSR
, dgnc_tty_iflag_show
, NULL
);
520 static ssize_t
dgnc_tty_cflag_show(struct device
*d
, struct device_attribute
*attr
, char *buf
)
522 struct dgnc_board
*bd
;
523 struct channel_t
*ch
;
528 un
= dev_get_drvdata(d
);
529 if (!un
|| un
->magic
!= DGNC_UNIT_MAGIC
)
532 if (!ch
|| ch
->magic
!= DGNC_CHANNEL_MAGIC
)
535 if (!bd
|| bd
->magic
!= DGNC_BOARD_MAGIC
)
537 if (bd
->state
!= BOARD_READY
)
540 return snprintf(buf
, PAGE_SIZE
, "%x\n", ch
->ch_c_cflag
);
542 static DEVICE_ATTR(cflag
, S_IRUSR
, dgnc_tty_cflag_show
, NULL
);
545 static ssize_t
dgnc_tty_oflag_show(struct device
*d
, struct device_attribute
*attr
, char *buf
)
547 struct dgnc_board
*bd
;
548 struct channel_t
*ch
;
553 un
= dev_get_drvdata(d
);
554 if (!un
|| un
->magic
!= DGNC_UNIT_MAGIC
)
557 if (!ch
|| ch
->magic
!= DGNC_CHANNEL_MAGIC
)
560 if (!bd
|| bd
->magic
!= DGNC_BOARD_MAGIC
)
562 if (bd
->state
!= BOARD_READY
)
565 return snprintf(buf
, PAGE_SIZE
, "%x\n", ch
->ch_c_oflag
);
567 static DEVICE_ATTR(oflag
, S_IRUSR
, dgnc_tty_oflag_show
, NULL
);
570 static ssize_t
dgnc_tty_lflag_show(struct device
*d
, struct device_attribute
*attr
, char *buf
)
572 struct dgnc_board
*bd
;
573 struct channel_t
*ch
;
578 un
= dev_get_drvdata(d
);
579 if (!un
|| un
->magic
!= DGNC_UNIT_MAGIC
)
582 if (!ch
|| ch
->magic
!= DGNC_CHANNEL_MAGIC
)
585 if (!bd
|| bd
->magic
!= DGNC_BOARD_MAGIC
)
587 if (bd
->state
!= BOARD_READY
)
590 return snprintf(buf
, PAGE_SIZE
, "%x\n", ch
->ch_c_lflag
);
592 static DEVICE_ATTR(lflag
, S_IRUSR
, dgnc_tty_lflag_show
, NULL
);
595 static ssize_t
dgnc_tty_digi_flag_show(struct device
*d
, struct device_attribute
*attr
, char *buf
)
597 struct dgnc_board
*bd
;
598 struct channel_t
*ch
;
603 un
= dev_get_drvdata(d
);
604 if (!un
|| un
->magic
!= DGNC_UNIT_MAGIC
)
607 if (!ch
|| ch
->magic
!= DGNC_CHANNEL_MAGIC
)
610 if (!bd
|| bd
->magic
!= DGNC_BOARD_MAGIC
)
612 if (bd
->state
!= BOARD_READY
)
615 return snprintf(buf
, PAGE_SIZE
, "%x\n", ch
->ch_digi
.digi_flags
);
617 static DEVICE_ATTR(digi_flag
, S_IRUSR
, dgnc_tty_digi_flag_show
, NULL
);
620 static ssize_t
dgnc_tty_rxcount_show(struct device
*d
, struct device_attribute
*attr
, char *buf
)
622 struct dgnc_board
*bd
;
623 struct channel_t
*ch
;
628 un
= dev_get_drvdata(d
);
629 if (!un
|| un
->magic
!= DGNC_UNIT_MAGIC
)
632 if (!ch
|| ch
->magic
!= DGNC_CHANNEL_MAGIC
)
635 if (!bd
|| bd
->magic
!= DGNC_BOARD_MAGIC
)
637 if (bd
->state
!= BOARD_READY
)
640 return snprintf(buf
, PAGE_SIZE
, "%ld\n", ch
->ch_rxcount
);
642 static DEVICE_ATTR(rxcount
, S_IRUSR
, dgnc_tty_rxcount_show
, NULL
);
645 static ssize_t
dgnc_tty_txcount_show(struct device
*d
, struct device_attribute
*attr
, char *buf
)
647 struct dgnc_board
*bd
;
648 struct channel_t
*ch
;
653 un
= dev_get_drvdata(d
);
654 if (!un
|| un
->magic
!= DGNC_UNIT_MAGIC
)
657 if (!ch
|| ch
->magic
!= DGNC_CHANNEL_MAGIC
)
660 if (!bd
|| bd
->magic
!= DGNC_BOARD_MAGIC
)
662 if (bd
->state
!= BOARD_READY
)
665 return snprintf(buf
, PAGE_SIZE
, "%ld\n", ch
->ch_txcount
);
667 static DEVICE_ATTR(txcount
, S_IRUSR
, dgnc_tty_txcount_show
, NULL
);
670 static ssize_t
dgnc_tty_name_show(struct device
*d
, struct device_attribute
*attr
, char *buf
)
672 struct dgnc_board
*bd
;
673 struct channel_t
*ch
;
678 un
= dev_get_drvdata(d
);
679 if (!un
|| un
->magic
!= DGNC_UNIT_MAGIC
)
682 if (!ch
|| ch
->magic
!= DGNC_CHANNEL_MAGIC
)
685 if (!bd
|| bd
->magic
!= DGNC_BOARD_MAGIC
)
687 if (bd
->state
!= BOARD_READY
)
690 return snprintf(buf
, PAGE_SIZE
, "%sn%d%c\n",
691 (un
->un_type
== DGNC_PRINT
) ? "pr" : "tty",
692 bd
->boardnum
+ 1, 'a' + ch
->ch_portnum
);
694 static DEVICE_ATTR(custom_name
, S_IRUSR
, dgnc_tty_name_show
, NULL
);
697 static struct attribute
*dgnc_sysfs_tty_entries
[] = {
698 &dev_attr_state
.attr
,
700 &dev_attr_msignals
.attr
,
701 &dev_attr_iflag
.attr
,
702 &dev_attr_cflag
.attr
,
703 &dev_attr_oflag
.attr
,
704 &dev_attr_lflag
.attr
,
705 &dev_attr_digi_flag
.attr
,
706 &dev_attr_rxcount
.attr
,
707 &dev_attr_txcount
.attr
,
708 &dev_attr_custom_name
.attr
,
713 static struct attribute_group dgnc_tty_attribute_group
= {
715 .attrs
= dgnc_sysfs_tty_entries
,
719 void dgnc_create_tty_sysfs(struct un_t
*un
, struct device
*c
)
723 ret
= sysfs_create_group(&c
->kobj
, &dgnc_tty_attribute_group
);
725 dev_err(c
, "dgnc: failed to create sysfs tty device attributes.\n");
726 sysfs_remove_group(&c
->kobj
, &dgnc_tty_attribute_group
);
730 dev_set_drvdata(c
, un
);
735 void dgnc_remove_tty_sysfs(struct device
*c
)
737 sysfs_remove_group(&c
->kobj
, &dgnc_tty_attribute_group
);