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
)
75 ret
= sscanf(buf
, "0x%x\n", &dgnc_debug
);
80 static DRIVER_ATTR(debug
, (S_IRUSR
| S_IWUSR
), dgnc_driver_debug_show
, dgnc_driver_debug_store
);
83 static ssize_t
dgnc_driver_rawreadok_show(struct device_driver
*ddp
, char *buf
)
85 return snprintf(buf
, PAGE_SIZE
, "0x%x\n", dgnc_rawreadok
);
88 static ssize_t
dgnc_driver_rawreadok_store(struct device_driver
*ddp
, const char *buf
, size_t count
)
92 ret
= sscanf(buf
, "0x%x\n", &dgnc_rawreadok
);
97 static DRIVER_ATTR(rawreadok
, (S_IRUSR
| S_IWUSR
), dgnc_driver_rawreadok_show
, dgnc_driver_rawreadok_store
);
100 static ssize_t
dgnc_driver_pollrate_show(struct device_driver
*ddp
, char *buf
)
102 return snprintf(buf
, PAGE_SIZE
, "%dms\n", dgnc_poll_tick
);
105 static ssize_t
dgnc_driver_pollrate_store(struct device_driver
*ddp
, const char *buf
, size_t count
)
109 ret
= sscanf(buf
, "%d\n", &dgnc_poll_tick
);
114 static DRIVER_ATTR(pollrate
, (S_IRUSR
| S_IWUSR
), dgnc_driver_pollrate_show
, dgnc_driver_pollrate_store
);
117 void dgnc_create_driver_sysfiles(struct pci_driver
*dgnc_driver
)
120 struct device_driver
*driverfs
= &dgnc_driver
->driver
;
122 rc
|= driver_create_file(driverfs
, &driver_attr_version
);
123 rc
|= driver_create_file(driverfs
, &driver_attr_boards
);
124 rc
|= driver_create_file(driverfs
, &driver_attr_maxboards
);
125 rc
|= driver_create_file(driverfs
, &driver_attr_debug
);
126 rc
|= driver_create_file(driverfs
, &driver_attr_rawreadok
);
127 rc
|= driver_create_file(driverfs
, &driver_attr_pollrate
);
129 printk(KERN_ERR
"DGNC: sysfs driver_create_file failed!\n");
133 void dgnc_remove_driver_sysfiles(struct pci_driver
*dgnc_driver
)
135 struct device_driver
*driverfs
= &dgnc_driver
->driver
;
137 driver_remove_file(driverfs
, &driver_attr_version
);
138 driver_remove_file(driverfs
, &driver_attr_boards
);
139 driver_remove_file(driverfs
, &driver_attr_maxboards
);
140 driver_remove_file(driverfs
, &driver_attr_debug
);
141 driver_remove_file(driverfs
, &driver_attr_rawreadok
);
142 driver_remove_file(driverfs
, &driver_attr_pollrate
);
146 #define DGNC_VERIFY_BOARD(p, bd) \
151 bd = dev_get_drvdata(p); \
152 if (!bd || bd->magic != DGNC_BOARD_MAGIC) \
154 if (bd->state != BOARD_READY) \
160 static ssize_t
dgnc_vpd_show(struct device
*p
, struct device_attribute
*attr
, char *buf
)
162 struct dgnc_board
*bd
;
166 DGNC_VERIFY_BOARD(p
, bd
);
168 count
+= sprintf(buf
+ count
, "\n 0 1 2 3 4 5 6 7 8 9 A B C D E F");
169 for (i
= 0; i
< 0x40 * 2; i
++) {
171 count
+= sprintf(buf
+ count
, "\n%04X ", i
* 2);
172 count
+= sprintf(buf
+ count
, "%02X ", bd
->vpd
[i
]);
174 count
+= sprintf(buf
+ count
, "\n");
178 static DEVICE_ATTR(vpd
, S_IRUSR
, dgnc_vpd_show
, NULL
);
180 static ssize_t
dgnc_serial_number_show(struct device
*p
, struct device_attribute
*attr
, char *buf
)
182 struct dgnc_board
*bd
;
185 DGNC_VERIFY_BOARD(p
, bd
);
187 if (bd
->serial_num
[0] == '\0')
188 count
+= sprintf(buf
+ count
, "<UNKNOWN>\n");
190 count
+= sprintf(buf
+ count
, "%s\n", bd
->serial_num
);
194 static DEVICE_ATTR(serial_number
, S_IRUSR
, dgnc_serial_number_show
, NULL
);
197 static ssize_t
dgnc_ports_state_show(struct device
*p
, struct device_attribute
*attr
, char *buf
)
199 struct dgnc_board
*bd
;
203 DGNC_VERIFY_BOARD(p
, bd
);
205 for (i
= 0; i
< bd
->nasync
; i
++) {
206 count
+= snprintf(buf
+ count
, PAGE_SIZE
- count
,
207 "%d %s\n", bd
->channels
[i
]->ch_portnum
,
208 bd
->channels
[i
]->ch_open_count
? "Open" : "Closed");
212 static DEVICE_ATTR(ports_state
, S_IRUSR
, dgnc_ports_state_show
, NULL
);
215 static ssize_t
dgnc_ports_baud_show(struct device
*p
, struct device_attribute
*attr
, char *buf
)
217 struct dgnc_board
*bd
;
221 DGNC_VERIFY_BOARD(p
, bd
);
223 for (i
= 0; i
< bd
->nasync
; i
++) {
224 count
+= snprintf(buf
+ count
, PAGE_SIZE
- count
,
225 "%d %d\n", bd
->channels
[i
]->ch_portnum
, bd
->channels
[i
]->ch_old_baud
);
229 static DEVICE_ATTR(ports_baud
, S_IRUSR
, dgnc_ports_baud_show
, NULL
);
232 static ssize_t
dgnc_ports_msignals_show(struct device
*p
, struct device_attribute
*attr
, char *buf
)
234 struct dgnc_board
*bd
;
238 DGNC_VERIFY_BOARD(p
, bd
);
240 for (i
= 0; i
< bd
->nasync
; i
++) {
241 if (bd
->channels
[i
]->ch_open_count
) {
242 count
+= snprintf(buf
+ count
, PAGE_SIZE
- count
,
243 "%d %s %s %s %s %s %s\n", bd
->channels
[i
]->ch_portnum
,
244 (bd
->channels
[i
]->ch_mostat
& UART_MCR_RTS
) ? "RTS" : "",
245 (bd
->channels
[i
]->ch_mistat
& UART_MSR_CTS
) ? "CTS" : "",
246 (bd
->channels
[i
]->ch_mostat
& UART_MCR_DTR
) ? "DTR" : "",
247 (bd
->channels
[i
]->ch_mistat
& UART_MSR_DSR
) ? "DSR" : "",
248 (bd
->channels
[i
]->ch_mistat
& UART_MSR_DCD
) ? "DCD" : "",
249 (bd
->channels
[i
]->ch_mistat
& UART_MSR_RI
) ? "RI" : "");
251 count
+= snprintf(buf
+ count
, PAGE_SIZE
- count
,
252 "%d\n", bd
->channels
[i
]->ch_portnum
);
257 static DEVICE_ATTR(ports_msignals
, S_IRUSR
, dgnc_ports_msignals_show
, NULL
);
260 static ssize_t
dgnc_ports_iflag_show(struct device
*p
, struct device_attribute
*attr
, char *buf
)
262 struct dgnc_board
*bd
;
266 DGNC_VERIFY_BOARD(p
, bd
);
268 for (i
= 0; i
< bd
->nasync
; i
++) {
269 count
+= snprintf(buf
+ count
, PAGE_SIZE
- count
, "%d %x\n",
270 bd
->channels
[i
]->ch_portnum
, bd
->channels
[i
]->ch_c_iflag
);
274 static DEVICE_ATTR(ports_iflag
, S_IRUSR
, dgnc_ports_iflag_show
, NULL
);
277 static ssize_t
dgnc_ports_cflag_show(struct device
*p
, struct device_attribute
*attr
, char *buf
)
279 struct dgnc_board
*bd
;
283 DGNC_VERIFY_BOARD(p
, bd
);
285 for (i
= 0; i
< bd
->nasync
; i
++) {
286 count
+= snprintf(buf
+ count
, PAGE_SIZE
- count
, "%d %x\n",
287 bd
->channels
[i
]->ch_portnum
, bd
->channels
[i
]->ch_c_cflag
);
291 static DEVICE_ATTR(ports_cflag
, S_IRUSR
, dgnc_ports_cflag_show
, NULL
);
294 static ssize_t
dgnc_ports_oflag_show(struct device
*p
, struct device_attribute
*attr
, char *buf
)
296 struct dgnc_board
*bd
;
300 DGNC_VERIFY_BOARD(p
, bd
);
302 for (i
= 0; i
< bd
->nasync
; i
++) {
303 count
+= snprintf(buf
+ count
, PAGE_SIZE
- count
, "%d %x\n",
304 bd
->channels
[i
]->ch_portnum
, bd
->channels
[i
]->ch_c_oflag
);
308 static DEVICE_ATTR(ports_oflag
, S_IRUSR
, dgnc_ports_oflag_show
, NULL
);
311 static ssize_t
dgnc_ports_lflag_show(struct device
*p
, struct device_attribute
*attr
, char *buf
)
313 struct dgnc_board
*bd
;
317 DGNC_VERIFY_BOARD(p
, bd
);
319 for (i
= 0; i
< bd
->nasync
; i
++) {
320 count
+= snprintf(buf
+ count
, PAGE_SIZE
- count
, "%d %x\n",
321 bd
->channels
[i
]->ch_portnum
, bd
->channels
[i
]->ch_c_lflag
);
325 static DEVICE_ATTR(ports_lflag
, S_IRUSR
, dgnc_ports_lflag_show
, NULL
);
328 static ssize_t
dgnc_ports_digi_flag_show(struct device
*p
, struct device_attribute
*attr
, char *buf
)
330 struct dgnc_board
*bd
;
334 DGNC_VERIFY_BOARD(p
, bd
);
336 for (i
= 0; i
< bd
->nasync
; i
++) {
337 count
+= snprintf(buf
+ count
, PAGE_SIZE
- count
, "%d %x\n",
338 bd
->channels
[i
]->ch_portnum
, bd
->channels
[i
]->ch_digi
.digi_flags
);
342 static DEVICE_ATTR(ports_digi_flag
, S_IRUSR
, dgnc_ports_digi_flag_show
, NULL
);
345 static ssize_t
dgnc_ports_rxcount_show(struct device
*p
, struct device_attribute
*attr
, char *buf
)
347 struct dgnc_board
*bd
;
351 DGNC_VERIFY_BOARD(p
, bd
);
353 for (i
= 0; i
< bd
->nasync
; i
++) {
354 count
+= snprintf(buf
+ count
, PAGE_SIZE
- count
, "%d %ld\n",
355 bd
->channels
[i
]->ch_portnum
, bd
->channels
[i
]->ch_rxcount
);
359 static DEVICE_ATTR(ports_rxcount
, S_IRUSR
, dgnc_ports_rxcount_show
, NULL
);
362 static ssize_t
dgnc_ports_txcount_show(struct device
*p
, struct device_attribute
*attr
, char *buf
)
364 struct dgnc_board
*bd
;
368 DGNC_VERIFY_BOARD(p
, bd
);
370 for (i
= 0; i
< bd
->nasync
; i
++) {
371 count
+= snprintf(buf
+ count
, PAGE_SIZE
- count
, "%d %ld\n",
372 bd
->channels
[i
]->ch_portnum
, bd
->channels
[i
]->ch_txcount
);
376 static DEVICE_ATTR(ports_txcount
, S_IRUSR
, dgnc_ports_txcount_show
, NULL
);
379 /* this function creates the sys files that will export each signal status
380 * to sysfs each value will be put in a separate filename
382 void dgnc_create_ports_sysfiles(struct dgnc_board
*bd
)
386 dev_set_drvdata(&bd
->pdev
->dev
, bd
);
387 rc
|= device_create_file(&(bd
->pdev
->dev
), &dev_attr_ports_state
);
388 rc
|= device_create_file(&(bd
->pdev
->dev
), &dev_attr_ports_baud
);
389 rc
|= device_create_file(&(bd
->pdev
->dev
), &dev_attr_ports_msignals
);
390 rc
|= device_create_file(&(bd
->pdev
->dev
), &dev_attr_ports_iflag
);
391 rc
|= device_create_file(&(bd
->pdev
->dev
), &dev_attr_ports_cflag
);
392 rc
|= device_create_file(&(bd
->pdev
->dev
), &dev_attr_ports_oflag
);
393 rc
|= device_create_file(&(bd
->pdev
->dev
), &dev_attr_ports_lflag
);
394 rc
|= device_create_file(&(bd
->pdev
->dev
), &dev_attr_ports_digi_flag
);
395 rc
|= device_create_file(&(bd
->pdev
->dev
), &dev_attr_ports_rxcount
);
396 rc
|= device_create_file(&(bd
->pdev
->dev
), &dev_attr_ports_txcount
);
397 rc
|= device_create_file(&(bd
->pdev
->dev
), &dev_attr_vpd
);
398 rc
|= device_create_file(&(bd
->pdev
->dev
), &dev_attr_serial_number
);
400 printk(KERN_ERR
"DGNC: sysfs device_create_file failed!\n");
404 /* removes all the sys files created for that port */
405 void dgnc_remove_ports_sysfiles(struct dgnc_board
*bd
)
407 device_remove_file(&(bd
->pdev
->dev
), &dev_attr_ports_state
);
408 device_remove_file(&(bd
->pdev
->dev
), &dev_attr_ports_baud
);
409 device_remove_file(&(bd
->pdev
->dev
), &dev_attr_ports_msignals
);
410 device_remove_file(&(bd
->pdev
->dev
), &dev_attr_ports_iflag
);
411 device_remove_file(&(bd
->pdev
->dev
), &dev_attr_ports_cflag
);
412 device_remove_file(&(bd
->pdev
->dev
), &dev_attr_ports_oflag
);
413 device_remove_file(&(bd
->pdev
->dev
), &dev_attr_ports_lflag
);
414 device_remove_file(&(bd
->pdev
->dev
), &dev_attr_ports_digi_flag
);
415 device_remove_file(&(bd
->pdev
->dev
), &dev_attr_ports_rxcount
);
416 device_remove_file(&(bd
->pdev
->dev
), &dev_attr_ports_txcount
);
417 device_remove_file(&(bd
->pdev
->dev
), &dev_attr_vpd
);
418 device_remove_file(&(bd
->pdev
->dev
), &dev_attr_serial_number
);
422 static ssize_t
dgnc_tty_state_show(struct device
*d
, struct device_attribute
*attr
, char *buf
)
424 struct dgnc_board
*bd
;
425 struct channel_t
*ch
;
430 un
= dev_get_drvdata(d
);
431 if (!un
|| un
->magic
!= DGNC_UNIT_MAGIC
)
434 if (!ch
|| ch
->magic
!= DGNC_CHANNEL_MAGIC
)
437 if (!bd
|| bd
->magic
!= DGNC_BOARD_MAGIC
)
439 if (bd
->state
!= BOARD_READY
)
442 return snprintf(buf
, PAGE_SIZE
, "%s", un
->un_open_count
? "Open" : "Closed");
444 static DEVICE_ATTR(state
, S_IRUSR
, dgnc_tty_state_show
, NULL
);
447 static ssize_t
dgnc_tty_baud_show(struct device
*d
, struct device_attribute
*attr
, char *buf
)
449 struct dgnc_board
*bd
;
450 struct channel_t
*ch
;
455 un
= dev_get_drvdata(d
);
456 if (!un
|| un
->magic
!= DGNC_UNIT_MAGIC
)
459 if (!ch
|| ch
->magic
!= DGNC_CHANNEL_MAGIC
)
462 if (!bd
|| bd
->magic
!= DGNC_BOARD_MAGIC
)
464 if (bd
->state
!= BOARD_READY
)
467 return snprintf(buf
, PAGE_SIZE
, "%d\n", ch
->ch_old_baud
);
469 static DEVICE_ATTR(baud
, S_IRUSR
, dgnc_tty_baud_show
, NULL
);
472 static ssize_t
dgnc_tty_msignals_show(struct device
*d
, struct device_attribute
*attr
, char *buf
)
474 struct dgnc_board
*bd
;
475 struct channel_t
*ch
;
480 un
= dev_get_drvdata(d
);
481 if (!un
|| un
->magic
!= DGNC_UNIT_MAGIC
)
484 if (!ch
|| ch
->magic
!= DGNC_CHANNEL_MAGIC
)
487 if (!bd
|| bd
->magic
!= DGNC_BOARD_MAGIC
)
489 if (bd
->state
!= BOARD_READY
)
492 if (ch
->ch_open_count
) {
493 return snprintf(buf
, PAGE_SIZE
, "%s %s %s %s %s %s\n",
494 (ch
->ch_mostat
& UART_MCR_RTS
) ? "RTS" : "",
495 (ch
->ch_mistat
& UART_MSR_CTS
) ? "CTS" : "",
496 (ch
->ch_mostat
& UART_MCR_DTR
) ? "DTR" : "",
497 (ch
->ch_mistat
& UART_MSR_DSR
) ? "DSR" : "",
498 (ch
->ch_mistat
& UART_MSR_DCD
) ? "DCD" : "",
499 (ch
->ch_mistat
& UART_MSR_RI
) ? "RI" : "");
503 static DEVICE_ATTR(msignals
, S_IRUSR
, dgnc_tty_msignals_show
, NULL
);
506 static ssize_t
dgnc_tty_iflag_show(struct device
*d
, struct device_attribute
*attr
, char *buf
)
508 struct dgnc_board
*bd
;
509 struct channel_t
*ch
;
514 un
= dev_get_drvdata(d
);
515 if (!un
|| un
->magic
!= DGNC_UNIT_MAGIC
)
518 if (!ch
|| ch
->magic
!= DGNC_CHANNEL_MAGIC
)
521 if (!bd
|| bd
->magic
!= DGNC_BOARD_MAGIC
)
523 if (bd
->state
!= BOARD_READY
)
526 return snprintf(buf
, PAGE_SIZE
, "%x\n", ch
->ch_c_iflag
);
528 static DEVICE_ATTR(iflag
, S_IRUSR
, dgnc_tty_iflag_show
, NULL
);
531 static ssize_t
dgnc_tty_cflag_show(struct device
*d
, struct device_attribute
*attr
, char *buf
)
533 struct dgnc_board
*bd
;
534 struct channel_t
*ch
;
539 un
= dev_get_drvdata(d
);
540 if (!un
|| un
->magic
!= DGNC_UNIT_MAGIC
)
543 if (!ch
|| ch
->magic
!= DGNC_CHANNEL_MAGIC
)
546 if (!bd
|| bd
->magic
!= DGNC_BOARD_MAGIC
)
548 if (bd
->state
!= BOARD_READY
)
551 return snprintf(buf
, PAGE_SIZE
, "%x\n", ch
->ch_c_cflag
);
553 static DEVICE_ATTR(cflag
, S_IRUSR
, dgnc_tty_cflag_show
, NULL
);
556 static ssize_t
dgnc_tty_oflag_show(struct device
*d
, struct device_attribute
*attr
, char *buf
)
558 struct dgnc_board
*bd
;
559 struct channel_t
*ch
;
564 un
= dev_get_drvdata(d
);
565 if (!un
|| un
->magic
!= DGNC_UNIT_MAGIC
)
568 if (!ch
|| ch
->magic
!= DGNC_CHANNEL_MAGIC
)
571 if (!bd
|| bd
->magic
!= DGNC_BOARD_MAGIC
)
573 if (bd
->state
!= BOARD_READY
)
576 return snprintf(buf
, PAGE_SIZE
, "%x\n", ch
->ch_c_oflag
);
578 static DEVICE_ATTR(oflag
, S_IRUSR
, dgnc_tty_oflag_show
, NULL
);
581 static ssize_t
dgnc_tty_lflag_show(struct device
*d
, struct device_attribute
*attr
, char *buf
)
583 struct dgnc_board
*bd
;
584 struct channel_t
*ch
;
589 un
= dev_get_drvdata(d
);
590 if (!un
|| un
->magic
!= DGNC_UNIT_MAGIC
)
593 if (!ch
|| ch
->magic
!= DGNC_CHANNEL_MAGIC
)
596 if (!bd
|| bd
->magic
!= DGNC_BOARD_MAGIC
)
598 if (bd
->state
!= BOARD_READY
)
601 return snprintf(buf
, PAGE_SIZE
, "%x\n", ch
->ch_c_lflag
);
603 static DEVICE_ATTR(lflag
, S_IRUSR
, dgnc_tty_lflag_show
, NULL
);
606 static ssize_t
dgnc_tty_digi_flag_show(struct device
*d
, struct device_attribute
*attr
, char *buf
)
608 struct dgnc_board
*bd
;
609 struct channel_t
*ch
;
614 un
= dev_get_drvdata(d
);
615 if (!un
|| un
->magic
!= DGNC_UNIT_MAGIC
)
618 if (!ch
|| ch
->magic
!= DGNC_CHANNEL_MAGIC
)
621 if (!bd
|| bd
->magic
!= DGNC_BOARD_MAGIC
)
623 if (bd
->state
!= BOARD_READY
)
626 return snprintf(buf
, PAGE_SIZE
, "%x\n", ch
->ch_digi
.digi_flags
);
628 static DEVICE_ATTR(digi_flag
, S_IRUSR
, dgnc_tty_digi_flag_show
, NULL
);
631 static ssize_t
dgnc_tty_rxcount_show(struct device
*d
, struct device_attribute
*attr
, char *buf
)
633 struct dgnc_board
*bd
;
634 struct channel_t
*ch
;
639 un
= dev_get_drvdata(d
);
640 if (!un
|| un
->magic
!= DGNC_UNIT_MAGIC
)
643 if (!ch
|| ch
->magic
!= DGNC_CHANNEL_MAGIC
)
646 if (!bd
|| bd
->magic
!= DGNC_BOARD_MAGIC
)
648 if (bd
->state
!= BOARD_READY
)
651 return snprintf(buf
, PAGE_SIZE
, "%ld\n", ch
->ch_rxcount
);
653 static DEVICE_ATTR(rxcount
, S_IRUSR
, dgnc_tty_rxcount_show
, NULL
);
656 static ssize_t
dgnc_tty_txcount_show(struct device
*d
, struct device_attribute
*attr
, char *buf
)
658 struct dgnc_board
*bd
;
659 struct channel_t
*ch
;
664 un
= dev_get_drvdata(d
);
665 if (!un
|| un
->magic
!= DGNC_UNIT_MAGIC
)
668 if (!ch
|| ch
->magic
!= DGNC_CHANNEL_MAGIC
)
671 if (!bd
|| bd
->magic
!= DGNC_BOARD_MAGIC
)
673 if (bd
->state
!= BOARD_READY
)
676 return snprintf(buf
, PAGE_SIZE
, "%ld\n", ch
->ch_txcount
);
678 static DEVICE_ATTR(txcount
, S_IRUSR
, dgnc_tty_txcount_show
, NULL
);
681 static ssize_t
dgnc_tty_name_show(struct device
*d
, struct device_attribute
*attr
, char *buf
)
683 struct dgnc_board
*bd
;
684 struct channel_t
*ch
;
689 un
= dev_get_drvdata(d
);
690 if (!un
|| un
->magic
!= DGNC_UNIT_MAGIC
)
693 if (!ch
|| ch
->magic
!= DGNC_CHANNEL_MAGIC
)
696 if (!bd
|| bd
->magic
!= DGNC_BOARD_MAGIC
)
698 if (bd
->state
!= BOARD_READY
)
701 return snprintf(buf
, PAGE_SIZE
, "%sn%d%c\n",
702 (un
->un_type
== DGNC_PRINT
) ? "pr" : "tty",
703 bd
->boardnum
+ 1, 'a' + ch
->ch_portnum
);
705 static DEVICE_ATTR(custom_name
, S_IRUSR
, dgnc_tty_name_show
, NULL
);
708 static struct attribute
*dgnc_sysfs_tty_entries
[] = {
709 &dev_attr_state
.attr
,
711 &dev_attr_msignals
.attr
,
712 &dev_attr_iflag
.attr
,
713 &dev_attr_cflag
.attr
,
714 &dev_attr_oflag
.attr
,
715 &dev_attr_lflag
.attr
,
716 &dev_attr_digi_flag
.attr
,
717 &dev_attr_rxcount
.attr
,
718 &dev_attr_txcount
.attr
,
719 &dev_attr_custom_name
.attr
,
724 static struct attribute_group dgnc_tty_attribute_group
= {
726 .attrs
= dgnc_sysfs_tty_entries
,
730 void dgnc_create_tty_sysfs(struct un_t
*un
, struct device
*c
)
734 ret
= sysfs_create_group(&c
->kobj
, &dgnc_tty_attribute_group
);
736 dev_err(c
, "dgnc: failed to create sysfs tty device attributes.\n");
737 sysfs_remove_group(&c
->kobj
, &dgnc_tty_attribute_group
);
741 dev_set_drvdata(c
, un
);
746 void dgnc_remove_tty_sysfs(struct device
*c
)
748 sysfs_remove_group(&c
->kobj
, &dgnc_tty_attribute_group
);