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