Merge tag 'for-linus-4.1-merge-window' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-block.git] / drivers / staging / dgnc / dgnc_sysfs.c
CommitLineData
0b99d589
LL
1/*
2 * Copyright 2004 Digi International (www.digi.com)
3 * Scott H Kilau <Scott_Kilau at digi dot com>
7a97deb2 4 *
0b99d589
LL
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
7a97deb2 12 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
0b99d589 13 * PURPOSE. See the GNU General Public License for more details.
0b99d589
LL
14 */
15
16
17#include <linux/kernel.h>
0b99d589
LL
18#include <linux/module.h>
19#include <linux/ctype.h>
20#include <linux/string.h>
21#include <linux/serial_reg.h>
22#include <linux/device.h>
23#include <linux/pci.h>
24#include <linux/kdev_t.h>
7a97deb2 25
0b99d589 26#include "dgnc_driver.h"
0b99d589
LL
27#include "dgnc_mgmt.h"
28
29
30static ssize_t dgnc_driver_version_show(struct device_driver *ddp, char *buf)
31{
32 return snprintf(buf, PAGE_SIZE, "%s\n", DG_PART);
33}
34static DRIVER_ATTR(version, S_IRUSR, dgnc_driver_version_show, NULL);
35
36
37static ssize_t dgnc_driver_boards_show(struct device_driver *ddp, char *buf)
38{
39 return snprintf(buf, PAGE_SIZE, "%d\n", dgnc_NumBoards);
40}
41static DRIVER_ATTR(boards, S_IRUSR, dgnc_driver_boards_show, NULL);
42
43
44static ssize_t dgnc_driver_maxboards_show(struct device_driver *ddp, char *buf)
45{
46 return snprintf(buf, PAGE_SIZE, "%d\n", MAXBOARDS);
47}
48static DRIVER_ATTR(maxboards, S_IRUSR, dgnc_driver_maxboards_show, NULL);
49
0b99d589 50
0b99d589
LL
51static ssize_t dgnc_driver_pollrate_show(struct device_driver *ddp, char *buf)
52{
53 return snprintf(buf, PAGE_SIZE, "%dms\n", dgnc_poll_tick);
54}
55
56static ssize_t dgnc_driver_pollrate_store(struct device_driver *ddp, const char *buf, size_t count)
57{
fb33aa47
RD
58 int ret;
59
60 ret = sscanf(buf, "%d\n", &dgnc_poll_tick);
61 if (ret != 1)
62 return -EINVAL;
0b99d589
LL
63 return count;
64}
65static DRIVER_ATTR(pollrate, (S_IRUSR | S_IWUSR), dgnc_driver_pollrate_show, dgnc_driver_pollrate_store);
66
67
68void dgnc_create_driver_sysfiles(struct pci_driver *dgnc_driver)
69{
70 int rc = 0;
71 struct device_driver *driverfs = &dgnc_driver->driver;
72
73 rc |= driver_create_file(driverfs, &driver_attr_version);
74 rc |= driver_create_file(driverfs, &driver_attr_boards);
75 rc |= driver_create_file(driverfs, &driver_attr_maxboards);
0b99d589 76 rc |= driver_create_file(driverfs, &driver_attr_pollrate);
77b55d84 77 if (rc)
c471c989 78 pr_err("DGNC: sysfs driver_create_file failed!\n");
0b99d589
LL
79}
80
81
82void dgnc_remove_driver_sysfiles(struct pci_driver *dgnc_driver)
83{
84 struct device_driver *driverfs = &dgnc_driver->driver;
e8756d4a 85
0b99d589
LL
86 driver_remove_file(driverfs, &driver_attr_version);
87 driver_remove_file(driverfs, &driver_attr_boards);
88 driver_remove_file(driverfs, &driver_attr_maxboards);
0b99d589 89 driver_remove_file(driverfs, &driver_attr_pollrate);
0b99d589
LL
90}
91
92
635c4efa
JM
93#define DGNC_VERIFY_BOARD(p, bd) \
94 do { \
95 if (!p) \
96 return 0; \
97 \
98 bd = dev_get_drvdata(p); \
99 if (!bd || bd->magic != DGNC_BOARD_MAGIC) \
100 return 0; \
101 if (bd->state != BOARD_READY) \
102 return 0; \
103 } while (0)
0b99d589
LL
104
105
106
107static ssize_t dgnc_vpd_show(struct device *p, struct device_attribute *attr, char *buf)
108{
03425f55 109 struct dgnc_board *bd;
0b99d589
LL
110 int count = 0;
111 int i = 0;
112
113 DGNC_VERIFY_BOARD(p, bd);
114
115 count += sprintf(buf + count, "\n 0 1 2 3 4 5 6 7 8 9 A B C D E F");
116 for (i = 0; i < 0x40 * 2; i++) {
117 if (!(i % 16))
118 count += sprintf(buf + count, "\n%04X ", i * 2);
119 count += sprintf(buf + count, "%02X ", bd->vpd[i]);
120 }
121 count += sprintf(buf + count, "\n");
122
123 return count;
124}
125static DEVICE_ATTR(vpd, S_IRUSR, dgnc_vpd_show, NULL);
126
127static ssize_t dgnc_serial_number_show(struct device *p, struct device_attribute *attr, char *buf)
128{
03425f55 129 struct dgnc_board *bd;
0b99d589
LL
130 int count = 0;
131
132 DGNC_VERIFY_BOARD(p, bd);
133
134 if (bd->serial_num[0] == '\0')
135 count += sprintf(buf + count, "<UNKNOWN>\n");
136 else
137 count += sprintf(buf + count, "%s\n", bd->serial_num);
138
139 return count;
140}
141static DEVICE_ATTR(serial_number, S_IRUSR, dgnc_serial_number_show, NULL);
142
143
144static ssize_t dgnc_ports_state_show(struct device *p, struct device_attribute *attr, char *buf)
145{
03425f55 146 struct dgnc_board *bd;
0b99d589
LL
147 int count = 0;
148 int i = 0;
149
150 DGNC_VERIFY_BOARD(p, bd);
151
152 for (i = 0; i < bd->nasync; i++) {
153 count += snprintf(buf + count, PAGE_SIZE - count,
154 "%d %s\n", bd->channels[i]->ch_portnum,
155 bd->channels[i]->ch_open_count ? "Open" : "Closed");
156 }
157 return count;
158}
159static DEVICE_ATTR(ports_state, S_IRUSR, dgnc_ports_state_show, NULL);
160
161
162static ssize_t dgnc_ports_baud_show(struct device *p, struct device_attribute *attr, char *buf)
163{
03425f55 164 struct dgnc_board *bd;
0b99d589
LL
165 int count = 0;
166 int i = 0;
167
168 DGNC_VERIFY_BOARD(p, bd);
169
170 for (i = 0; i < bd->nasync; i++) {
171 count += snprintf(buf + count, PAGE_SIZE - count,
172 "%d %d\n", bd->channels[i]->ch_portnum, bd->channels[i]->ch_old_baud);
173 }
174 return count;
175}
176static DEVICE_ATTR(ports_baud, S_IRUSR, dgnc_ports_baud_show, NULL);
177
178
179static ssize_t dgnc_ports_msignals_show(struct device *p, struct device_attribute *attr, char *buf)
180{
03425f55 181 struct dgnc_board *bd;
0b99d589
LL
182 int count = 0;
183 int i = 0;
184
185 DGNC_VERIFY_BOARD(p, bd);
186
187 for (i = 0; i < bd->nasync; i++) {
188 if (bd->channels[i]->ch_open_count) {
189 count += snprintf(buf + count, PAGE_SIZE - count,
190 "%d %s %s %s %s %s %s\n", bd->channels[i]->ch_portnum,
191 (bd->channels[i]->ch_mostat & UART_MCR_RTS) ? "RTS" : "",
192 (bd->channels[i]->ch_mistat & UART_MSR_CTS) ? "CTS" : "",
193 (bd->channels[i]->ch_mostat & UART_MCR_DTR) ? "DTR" : "",
194 (bd->channels[i]->ch_mistat & UART_MSR_DSR) ? "DSR" : "",
195 (bd->channels[i]->ch_mistat & UART_MSR_DCD) ? "DCD" : "",
196 (bd->channels[i]->ch_mistat & UART_MSR_RI) ? "RI" : "");
197 } else {
198 count += snprintf(buf + count, PAGE_SIZE - count,
199 "%d\n", bd->channels[i]->ch_portnum);
200 }
201 }
202 return count;
203}
204static DEVICE_ATTR(ports_msignals, S_IRUSR, dgnc_ports_msignals_show, NULL);
205
206
207static ssize_t dgnc_ports_iflag_show(struct device *p, struct device_attribute *attr, char *buf)
208{
03425f55 209 struct dgnc_board *bd;
0b99d589
LL
210 int count = 0;
211 int i = 0;
212
213 DGNC_VERIFY_BOARD(p, bd);
214
215 for (i = 0; i < bd->nasync; i++) {
216 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
217 bd->channels[i]->ch_portnum, bd->channels[i]->ch_c_iflag);
218 }
219 return count;
220}
221static DEVICE_ATTR(ports_iflag, S_IRUSR, dgnc_ports_iflag_show, NULL);
222
223
224static ssize_t dgnc_ports_cflag_show(struct device *p, struct device_attribute *attr, char *buf)
225{
03425f55 226 struct dgnc_board *bd;
0b99d589
LL
227 int count = 0;
228 int i = 0;
229
230 DGNC_VERIFY_BOARD(p, bd);
231
232 for (i = 0; i < bd->nasync; i++) {
233 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
234 bd->channels[i]->ch_portnum, bd->channels[i]->ch_c_cflag);
235 }
236 return count;
237}
238static DEVICE_ATTR(ports_cflag, S_IRUSR, dgnc_ports_cflag_show, NULL);
239
240
241static ssize_t dgnc_ports_oflag_show(struct device *p, struct device_attribute *attr, char *buf)
242{
03425f55 243 struct dgnc_board *bd;
0b99d589
LL
244 int count = 0;
245 int i = 0;
246
247 DGNC_VERIFY_BOARD(p, bd);
248
249 for (i = 0; i < bd->nasync; i++) {
250 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
251 bd->channels[i]->ch_portnum, bd->channels[i]->ch_c_oflag);
252 }
253 return count;
254}
255static DEVICE_ATTR(ports_oflag, S_IRUSR, dgnc_ports_oflag_show, NULL);
256
257
258static ssize_t dgnc_ports_lflag_show(struct device *p, struct device_attribute *attr, char *buf)
259{
03425f55 260 struct dgnc_board *bd;
0b99d589
LL
261 int count = 0;
262 int i = 0;
263
264 DGNC_VERIFY_BOARD(p, bd);
265
266 for (i = 0; i < bd->nasync; i++) {
267 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
268 bd->channels[i]->ch_portnum, bd->channels[i]->ch_c_lflag);
269 }
270 return count;
271}
272static DEVICE_ATTR(ports_lflag, S_IRUSR, dgnc_ports_lflag_show, NULL);
273
274
275static ssize_t dgnc_ports_digi_flag_show(struct device *p, struct device_attribute *attr, char *buf)
276{
03425f55 277 struct dgnc_board *bd;
0b99d589
LL
278 int count = 0;
279 int i = 0;
280
281 DGNC_VERIFY_BOARD(p, bd);
282
283 for (i = 0; i < bd->nasync; i++) {
284 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
285 bd->channels[i]->ch_portnum, bd->channels[i]->ch_digi.digi_flags);
286 }
287 return count;
288}
289static DEVICE_ATTR(ports_digi_flag, S_IRUSR, dgnc_ports_digi_flag_show, NULL);
290
291
292static ssize_t dgnc_ports_rxcount_show(struct device *p, struct device_attribute *attr, char *buf)
293{
03425f55 294 struct dgnc_board *bd;
0b99d589
LL
295 int count = 0;
296 int i = 0;
297
298 DGNC_VERIFY_BOARD(p, bd);
299
300 for (i = 0; i < bd->nasync; i++) {
301 count += snprintf(buf + count, PAGE_SIZE - count, "%d %ld\n",
302 bd->channels[i]->ch_portnum, bd->channels[i]->ch_rxcount);
303 }
304 return count;
305}
306static DEVICE_ATTR(ports_rxcount, S_IRUSR, dgnc_ports_rxcount_show, NULL);
307
308
309static ssize_t dgnc_ports_txcount_show(struct device *p, struct device_attribute *attr, char *buf)
310{
03425f55 311 struct dgnc_board *bd;
0b99d589
LL
312 int count = 0;
313 int i = 0;
314
315 DGNC_VERIFY_BOARD(p, bd);
316
317 for (i = 0; i < bd->nasync; i++) {
318 count += snprintf(buf + count, PAGE_SIZE - count, "%d %ld\n",
319 bd->channels[i]->ch_portnum, bd->channels[i]->ch_txcount);
320 }
321 return count;
322}
323static DEVICE_ATTR(ports_txcount, S_IRUSR, dgnc_ports_txcount_show, NULL);
324
325
326/* this function creates the sys files that will export each signal status
327 * to sysfs each value will be put in a separate filename
328 */
03425f55 329void dgnc_create_ports_sysfiles(struct dgnc_board *bd)
0b99d589
LL
330{
331 int rc = 0;
332
333 dev_set_drvdata(&bd->pdev->dev, bd);
334 rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_state);
335 rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_baud);
336 rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_msignals);
337 rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_iflag);
338 rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_cflag);
339 rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_oflag);
340 rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_lflag);
341 rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_digi_flag);
342 rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_rxcount);
343 rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_txcount);
344 rc |= device_create_file(&(bd->pdev->dev), &dev_attr_vpd);
345 rc |= device_create_file(&(bd->pdev->dev), &dev_attr_serial_number);
77b55d84 346 if (rc)
c28645e3 347 dev_err(&bd->pdev->dev, "dgnc: sysfs device_create_file failed!\n");
0b99d589
LL
348}
349
350
351/* removes all the sys files created for that port */
03425f55 352void dgnc_remove_ports_sysfiles(struct dgnc_board *bd)
0b99d589
LL
353{
354 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_state);
355 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_baud);
356 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_msignals);
357 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_iflag);
358 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_cflag);
359 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_oflag);
360 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_lflag);
361 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_digi_flag);
362 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_rxcount);
363 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_txcount);
364 device_remove_file(&(bd->pdev->dev), &dev_attr_vpd);
365 device_remove_file(&(bd->pdev->dev), &dev_attr_serial_number);
366}
367
368
369static ssize_t dgnc_tty_state_show(struct device *d, struct device_attribute *attr, char *buf)
370{
03425f55 371 struct dgnc_board *bd;
0b99d589
LL
372 struct channel_t *ch;
373 struct un_t *un;
374
375 if (!d)
8f90ef80 376 return 0;
0e4f66b4 377 un = dev_get_drvdata(d);
0b99d589 378 if (!un || un->magic != DGNC_UNIT_MAGIC)
8f90ef80 379 return 0;
0b99d589
LL
380 ch = un->un_ch;
381 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
8f90ef80 382 return 0;
0b99d589
LL
383 bd = ch->ch_bd;
384 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
8f90ef80 385 return 0;
0b99d589 386 if (bd->state != BOARD_READY)
8f90ef80 387 return 0;
0b99d589
LL
388
389 return snprintf(buf, PAGE_SIZE, "%s", un->un_open_count ? "Open" : "Closed");
390}
391static DEVICE_ATTR(state, S_IRUSR, dgnc_tty_state_show, NULL);
392
393
394static ssize_t dgnc_tty_baud_show(struct device *d, struct device_attribute *attr, char *buf)
395{
03425f55 396 struct dgnc_board *bd;
0b99d589
LL
397 struct channel_t *ch;
398 struct un_t *un;
399
400 if (!d)
8f90ef80 401 return 0;
0e4f66b4 402 un = dev_get_drvdata(d);
0b99d589 403 if (!un || un->magic != DGNC_UNIT_MAGIC)
8f90ef80 404 return 0;
0b99d589
LL
405 ch = un->un_ch;
406 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
8f90ef80 407 return 0;
0b99d589
LL
408 bd = ch->ch_bd;
409 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
8f90ef80 410 return 0;
0b99d589 411 if (bd->state != BOARD_READY)
8f90ef80 412 return 0;
0b99d589
LL
413
414 return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_old_baud);
415}
416static DEVICE_ATTR(baud, S_IRUSR, dgnc_tty_baud_show, NULL);
417
418
419static ssize_t dgnc_tty_msignals_show(struct device *d, struct device_attribute *attr, char *buf)
420{
03425f55 421 struct dgnc_board *bd;
0b99d589
LL
422 struct channel_t *ch;
423 struct un_t *un;
424
425 if (!d)
8f90ef80 426 return 0;
0e4f66b4 427 un = dev_get_drvdata(d);
0b99d589 428 if (!un || un->magic != DGNC_UNIT_MAGIC)
8f90ef80 429 return 0;
0b99d589
LL
430 ch = un->un_ch;
431 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
8f90ef80 432 return 0;
0b99d589
LL
433 bd = ch->ch_bd;
434 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
8f90ef80 435 return 0;
0b99d589 436 if (bd->state != BOARD_READY)
8f90ef80 437 return 0;
0b99d589
LL
438
439 if (ch->ch_open_count) {
440 return snprintf(buf, PAGE_SIZE, "%s %s %s %s %s %s\n",
441 (ch->ch_mostat & UART_MCR_RTS) ? "RTS" : "",
442 (ch->ch_mistat & UART_MSR_CTS) ? "CTS" : "",
443 (ch->ch_mostat & UART_MCR_DTR) ? "DTR" : "",
444 (ch->ch_mistat & UART_MSR_DSR) ? "DSR" : "",
445 (ch->ch_mistat & UART_MSR_DCD) ? "DCD" : "",
446 (ch->ch_mistat & UART_MSR_RI) ? "RI" : "");
447 }
448 return 0;
449}
450static DEVICE_ATTR(msignals, S_IRUSR, dgnc_tty_msignals_show, NULL);
451
452
453static ssize_t dgnc_tty_iflag_show(struct device *d, struct device_attribute *attr, char *buf)
454{
03425f55 455 struct dgnc_board *bd;
0b99d589
LL
456 struct channel_t *ch;
457 struct un_t *un;
458
459 if (!d)
8f90ef80 460 return 0;
0e4f66b4 461 un = dev_get_drvdata(d);
0b99d589 462 if (!un || un->magic != DGNC_UNIT_MAGIC)
8f90ef80 463 return 0;
0b99d589
LL
464 ch = un->un_ch;
465 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
8f90ef80 466 return 0;
0b99d589
LL
467 bd = ch->ch_bd;
468 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
8f90ef80 469 return 0;
0b99d589 470 if (bd->state != BOARD_READY)
8f90ef80 471 return 0;
0b99d589
LL
472
473 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_iflag);
474}
475static DEVICE_ATTR(iflag, S_IRUSR, dgnc_tty_iflag_show, NULL);
476
477
478static ssize_t dgnc_tty_cflag_show(struct device *d, struct device_attribute *attr, char *buf)
479{
03425f55 480 struct dgnc_board *bd;
0b99d589
LL
481 struct channel_t *ch;
482 struct un_t *un;
483
484 if (!d)
8f90ef80 485 return 0;
0e4f66b4 486 un = dev_get_drvdata(d);
0b99d589 487 if (!un || un->magic != DGNC_UNIT_MAGIC)
8f90ef80 488 return 0;
0b99d589
LL
489 ch = un->un_ch;
490 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
8f90ef80 491 return 0;
0b99d589
LL
492 bd = ch->ch_bd;
493 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
8f90ef80 494 return 0;
0b99d589 495 if (bd->state != BOARD_READY)
8f90ef80 496 return 0;
0b99d589
LL
497
498 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_cflag);
499}
500static DEVICE_ATTR(cflag, S_IRUSR, dgnc_tty_cflag_show, NULL);
501
502
503static ssize_t dgnc_tty_oflag_show(struct device *d, struct device_attribute *attr, char *buf)
504{
03425f55 505 struct dgnc_board *bd;
0b99d589
LL
506 struct channel_t *ch;
507 struct un_t *un;
508
509 if (!d)
8f90ef80 510 return 0;
0e4f66b4 511 un = dev_get_drvdata(d);
0b99d589 512 if (!un || un->magic != DGNC_UNIT_MAGIC)
8f90ef80 513 return 0;
0b99d589
LL
514 ch = un->un_ch;
515 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
8f90ef80 516 return 0;
0b99d589
LL
517 bd = ch->ch_bd;
518 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
8f90ef80 519 return 0;
0b99d589 520 if (bd->state != BOARD_READY)
8f90ef80 521 return 0;
0b99d589
LL
522
523 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_oflag);
524}
525static DEVICE_ATTR(oflag, S_IRUSR, dgnc_tty_oflag_show, NULL);
526
527
528static ssize_t dgnc_tty_lflag_show(struct device *d, struct device_attribute *attr, char *buf)
529{
03425f55 530 struct dgnc_board *bd;
0b99d589
LL
531 struct channel_t *ch;
532 struct un_t *un;
533
534 if (!d)
8f90ef80 535 return 0;
0e4f66b4 536 un = dev_get_drvdata(d);
0b99d589 537 if (!un || un->magic != DGNC_UNIT_MAGIC)
8f90ef80 538 return 0;
0b99d589
LL
539 ch = un->un_ch;
540 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
8f90ef80 541 return 0;
0b99d589
LL
542 bd = ch->ch_bd;
543 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
8f90ef80 544 return 0;
0b99d589 545 if (bd->state != BOARD_READY)
8f90ef80 546 return 0;
0b99d589
LL
547
548 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_lflag);
549}
550static DEVICE_ATTR(lflag, S_IRUSR, dgnc_tty_lflag_show, NULL);
551
552
553static ssize_t dgnc_tty_digi_flag_show(struct device *d, struct device_attribute *attr, char *buf)
554{
03425f55 555 struct dgnc_board *bd;
0b99d589
LL
556 struct channel_t *ch;
557 struct un_t *un;
558
559 if (!d)
8f90ef80 560 return 0;
0e4f66b4 561 un = dev_get_drvdata(d);
0b99d589 562 if (!un || un->magic != DGNC_UNIT_MAGIC)
8f90ef80 563 return 0;
0b99d589
LL
564 ch = un->un_ch;
565 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
8f90ef80 566 return 0;
0b99d589
LL
567 bd = ch->ch_bd;
568 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
8f90ef80 569 return 0;
0b99d589 570 if (bd->state != BOARD_READY)
8f90ef80 571 return 0;
0b99d589
LL
572
573 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_digi.digi_flags);
574}
575static DEVICE_ATTR(digi_flag, S_IRUSR, dgnc_tty_digi_flag_show, NULL);
576
577
578static ssize_t dgnc_tty_rxcount_show(struct device *d, struct device_attribute *attr, char *buf)
579{
03425f55 580 struct dgnc_board *bd;
0b99d589
LL
581 struct channel_t *ch;
582 struct un_t *un;
583
584 if (!d)
8f90ef80 585 return 0;
0e4f66b4 586 un = dev_get_drvdata(d);
0b99d589 587 if (!un || un->magic != DGNC_UNIT_MAGIC)
8f90ef80 588 return 0;
0b99d589
LL
589 ch = un->un_ch;
590 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
8f90ef80 591 return 0;
0b99d589
LL
592 bd = ch->ch_bd;
593 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
8f90ef80 594 return 0;
0b99d589 595 if (bd->state != BOARD_READY)
8f90ef80 596 return 0;
0b99d589
LL
597
598 return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_rxcount);
599}
600static DEVICE_ATTR(rxcount, S_IRUSR, dgnc_tty_rxcount_show, NULL);
601
602
603static ssize_t dgnc_tty_txcount_show(struct device *d, struct device_attribute *attr, char *buf)
604{
03425f55 605 struct dgnc_board *bd;
0b99d589
LL
606 struct channel_t *ch;
607 struct un_t *un;
608
609 if (!d)
8f90ef80 610 return 0;
0e4f66b4 611 un = dev_get_drvdata(d);
0b99d589 612 if (!un || un->magic != DGNC_UNIT_MAGIC)
8f90ef80 613 return 0;
0b99d589
LL
614 ch = un->un_ch;
615 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
8f90ef80 616 return 0;
0b99d589
LL
617 bd = ch->ch_bd;
618 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
8f90ef80 619 return 0;
0b99d589 620 if (bd->state != BOARD_READY)
8f90ef80 621 return 0;
0b99d589
LL
622
623 return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_txcount);
624}
625static DEVICE_ATTR(txcount, S_IRUSR, dgnc_tty_txcount_show, NULL);
626
627
628static ssize_t dgnc_tty_name_show(struct device *d, struct device_attribute *attr, char *buf)
629{
03425f55 630 struct dgnc_board *bd;
0b99d589
LL
631 struct channel_t *ch;
632 struct un_t *un;
633
634 if (!d)
8f90ef80 635 return 0;
0e4f66b4 636 un = dev_get_drvdata(d);
0b99d589 637 if (!un || un->magic != DGNC_UNIT_MAGIC)
8f90ef80 638 return 0;
0b99d589
LL
639 ch = un->un_ch;
640 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
8f90ef80 641 return 0;
0b99d589
LL
642 bd = ch->ch_bd;
643 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
8f90ef80 644 return 0;
0b99d589 645 if (bd->state != BOARD_READY)
8f90ef80 646 return 0;
0b99d589
LL
647
648 return snprintf(buf, PAGE_SIZE, "%sn%d%c\n",
649 (un->un_type == DGNC_PRINT) ? "pr" : "tty",
650 bd->boardnum + 1, 'a' + ch->ch_portnum);
651}
652static DEVICE_ATTR(custom_name, S_IRUSR, dgnc_tty_name_show, NULL);
653
654
655static struct attribute *dgnc_sysfs_tty_entries[] = {
656 &dev_attr_state.attr,
657 &dev_attr_baud.attr,
658 &dev_attr_msignals.attr,
659 &dev_attr_iflag.attr,
660 &dev_attr_cflag.attr,
7a97deb2 661 &dev_attr_oflag.attr,
0b99d589
LL
662 &dev_attr_lflag.attr,
663 &dev_attr_digi_flag.attr,
664 &dev_attr_rxcount.attr,
665 &dev_attr_txcount.attr,
666 &dev_attr_custom_name.attr,
667 NULL
668};
669
670
671static struct attribute_group dgnc_tty_attribute_group = {
0a60eb33
LL
672 .name = NULL,
673 .attrs = dgnc_sysfs_tty_entries,
0b99d589
LL
674};
675
676
677void dgnc_create_tty_sysfs(struct un_t *un, struct device *c)
678{
679 int ret;
680
681 ret = sysfs_create_group(&c->kobj, &dgnc_tty_attribute_group);
682 if (ret) {
0f33ae1e 683 dev_err(c, "dgnc: failed to create sysfs tty device attributes.\n");
0b99d589
LL
684 sysfs_remove_group(&c->kobj, &dgnc_tty_attribute_group);
685 return;
686 }
687
688 dev_set_drvdata(c, un);
689
690}
691
7a97deb2 692
0b99d589
LL
693void dgnc_remove_tty_sysfs(struct device *c)
694{
695 sysfs_remove_group(&c->kobj, &dgnc_tty_attribute_group);
696}
697