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