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.
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>
25 #include "dgnc_driver.h"
26 #include "dgnc_mgmt.h"
28 static ssize_t version_show(struct device_driver *ddp, char *buf)
30 return snprintf(buf, PAGE_SIZE, "%s\n", DG_PART);
32 static DRIVER_ATTR_RO(version);
34 static ssize_t boards_show(struct device_driver *ddp, char *buf)
36 return snprintf(buf, PAGE_SIZE, "%d\n", dgnc_num_boards);
38 static DRIVER_ATTR_RO(boards);
40 static ssize_t maxboards_show(struct device_driver *ddp, char *buf)
42 return snprintf(buf, PAGE_SIZE, "%d\n", MAXBOARDS);
44 static DRIVER_ATTR_RO(maxboards);
46 static ssize_t pollrate_show(struct device_driver *ddp, char *buf)
48 return snprintf(buf, PAGE_SIZE, "%dms\n", dgnc_poll_tick);
51 static ssize_t pollrate_store(struct device_driver *ddp,
52 const char *buf, size_t count)
58 ret = sscanf(buf, "%d\n", &tick);
62 spin_lock_irqsave(&dgnc_poll_lock, flags);
63 dgnc_poll_tick = tick;
64 spin_unlock_irqrestore(&dgnc_poll_lock, flags);
68 static DRIVER_ATTR_RW(pollrate);
70 void dgnc_create_driver_sysfiles(struct pci_driver *dgnc_driver)
73 struct device_driver *driverfs = &dgnc_driver->driver;
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);
78 rc |= driver_create_file(driverfs, &driver_attr_pollrate);
80 pr_err("DGNC: sysfs driver_create_file failed!\n");
83 void dgnc_remove_driver_sysfiles(struct pci_driver *dgnc_driver)
85 struct device_driver *driverfs = &dgnc_driver->driver;
87 driver_remove_file(driverfs, &driver_attr_version);
88 driver_remove_file(driverfs, &driver_attr_boards);
89 driver_remove_file(driverfs, &driver_attr_maxboards);
90 driver_remove_file(driverfs, &driver_attr_pollrate);
93 #define DGNC_VERIFY_BOARD(p, bd) \
98 bd = dev_get_drvdata(p); \
99 if (!bd || bd->magic != DGNC_BOARD_MAGIC) \
101 if (bd->state != BOARD_READY) \
105 static ssize_t vpd_show(struct device *p, struct device_attribute *attr,
108 struct dgnc_board *bd;
112 DGNC_VERIFY_BOARD(p, bd);
114 count += sprintf(buf + count,
115 "\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++) {
118 count += sprintf(buf + count, "\n%04X ", i * 2);
119 count += sprintf(buf + count, "%02X ", bd->vpd[i]);
121 count += sprintf(buf + count, "\n");
125 static DEVICE_ATTR_RO(vpd);
127 static ssize_t serial_number_show(struct device *p,
128 struct device_attribute *attr, char *buf)
130 struct dgnc_board *bd;
133 DGNC_VERIFY_BOARD(p, bd);
135 if (bd->serial_num[0] == '\0')
136 count += sprintf(buf + count, "<UNKNOWN>\n");
138 count += sprintf(buf + count, "%s\n", bd->serial_num);
142 static DEVICE_ATTR_RO(serial_number);
144 static ssize_t ports_state_show(struct device *p,
145 struct device_attribute *attr, char *buf)
147 struct dgnc_board *bd;
151 DGNC_VERIFY_BOARD(p, bd);
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");
160 static DEVICE_ATTR_RO(ports_state);
162 static ssize_t ports_baud_show(struct device *p,
163 struct device_attribute *attr, char *buf)
165 struct dgnc_board *bd;
169 DGNC_VERIFY_BOARD(p, bd);
171 for (i = 0; i < bd->nasync; i++) {
172 count += snprintf(buf + count, PAGE_SIZE - count,
173 "%d %d\n", bd->channels[i]->ch_portnum,
174 bd->channels[i]->ch_old_baud);
178 static DEVICE_ATTR_RO(ports_baud);
180 static ssize_t ports_msignals_show(struct device *p,
181 struct device_attribute *attr, char *buf)
183 struct dgnc_board *bd;
187 DGNC_VERIFY_BOARD(p, bd);
189 for (i = 0; i < bd->nasync; i++) {
190 struct channel_t *ch = bd->channels[i];
192 if (ch->ch_open_count) {
193 count += snprintf(buf + count, PAGE_SIZE - count,
194 "%d %s %s %s %s %s %s\n",
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" : "");
203 count += snprintf(buf + count, PAGE_SIZE - count,
204 "%d\n", ch->ch_portnum);
209 static DEVICE_ATTR_RO(ports_msignals);
211 static ssize_t ports_iflag_show(struct device *p,
212 struct device_attribute *attr, char *buf)
214 struct dgnc_board *bd;
218 DGNC_VERIFY_BOARD(p, bd);
220 for (i = 0; i < bd->nasync; i++) {
221 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
222 bd->channels[i]->ch_portnum,
223 bd->channels[i]->ch_c_iflag);
227 static DEVICE_ATTR_RO(ports_iflag);
229 static ssize_t ports_cflag_show(struct device *p,
230 struct device_attribute *attr, char *buf)
232 struct dgnc_board *bd;
236 DGNC_VERIFY_BOARD(p, bd);
238 for (i = 0; i < bd->nasync; i++) {
239 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
240 bd->channels[i]->ch_portnum,
241 bd->channels[i]->ch_c_cflag);
245 static DEVICE_ATTR_RO(ports_cflag);
247 static ssize_t ports_oflag_show(struct device *p,
248 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,
259 bd->channels[i]->ch_c_oflag);
263 static DEVICE_ATTR_RO(ports_oflag);
265 static ssize_t ports_lflag_show(struct device *p,
266 struct device_attribute *attr, char *buf)
268 struct dgnc_board *bd;
272 DGNC_VERIFY_BOARD(p, bd);
274 for (i = 0; i < bd->nasync; i++) {
275 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
276 bd->channels[i]->ch_portnum,
277 bd->channels[i]->ch_c_lflag);
281 static DEVICE_ATTR_RO(ports_lflag);
283 static ssize_t ports_digi_flag_show(struct device *p,
284 struct device_attribute *attr, char *buf)
286 struct dgnc_board *bd;
290 DGNC_VERIFY_BOARD(p, bd);
292 for (i = 0; i < bd->nasync; i++) {
293 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
294 bd->channels[i]->ch_portnum,
295 bd->channels[i]->ch_digi.digi_flags);
299 static DEVICE_ATTR_RO(ports_digi_flag);
301 static ssize_t ports_rxcount_show(struct device *p,
302 struct device_attribute *attr, char *buf)
304 struct dgnc_board *bd;
308 DGNC_VERIFY_BOARD(p, bd);
310 for (i = 0; i < bd->nasync; i++) {
311 count += snprintf(buf + count, PAGE_SIZE - count, "%d %ld\n",
312 bd->channels[i]->ch_portnum,
313 bd->channels[i]->ch_rxcount);
317 static DEVICE_ATTR_RO(ports_rxcount);
319 static ssize_t ports_txcount_show(struct device *p,
320 struct device_attribute *attr, char *buf)
322 struct dgnc_board *bd;
326 DGNC_VERIFY_BOARD(p, bd);
328 for (i = 0; i < bd->nasync; i++) {
329 count += snprintf(buf + count, PAGE_SIZE - count, "%d %ld\n",
330 bd->channels[i]->ch_portnum,
331 bd->channels[i]->ch_txcount);
335 static DEVICE_ATTR_RO(ports_txcount);
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
340 void dgnc_create_ports_sysfiles(struct dgnc_board *bd)
344 dev_set_drvdata(&bd->pdev->dev, bd);
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);
358 dev_err(&bd->pdev->dev, "dgnc: sysfs device_create_file failed!\n");
361 /* removes all the sys files created for that port */
362 void dgnc_remove_ports_sysfiles(struct dgnc_board *bd)
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);
378 static ssize_t tty_state_show(struct device *d,
379 struct device_attribute *attr, char *buf)
381 struct dgnc_board *bd;
382 struct channel_t *ch;
387 un = dev_get_drvdata(d);
388 if (!un || un->magic != DGNC_UNIT_MAGIC)
391 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
394 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
396 if (bd->state != BOARD_READY)
399 return snprintf(buf, PAGE_SIZE, "%s",
400 un->un_open_count ? "Open" : "Closed");
402 static DEVICE_ATTR_RO(tty_state);
404 static ssize_t tty_baud_show(struct device *d,
405 struct device_attribute *attr, char *buf)
407 struct dgnc_board *bd;
408 struct channel_t *ch;
413 un = dev_get_drvdata(d);
414 if (!un || un->magic != DGNC_UNIT_MAGIC)
417 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
420 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
422 if (bd->state != BOARD_READY)
425 return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_old_baud);
427 static DEVICE_ATTR_RO(tty_baud);
429 static ssize_t tty_msignals_show(struct device *d,
430 struct device_attribute *attr, char *buf)
432 struct dgnc_board *bd;
433 struct channel_t *ch;
438 un = dev_get_drvdata(d);
439 if (!un || un->magic != DGNC_UNIT_MAGIC)
442 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
445 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
447 if (bd->state != BOARD_READY)
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" : "");
461 static DEVICE_ATTR_RO(tty_msignals);
463 static ssize_t tty_iflag_show(struct device *d,
464 struct device_attribute *attr, char *buf)
466 struct dgnc_board *bd;
467 struct channel_t *ch;
472 un = dev_get_drvdata(d);
473 if (!un || un->magic != DGNC_UNIT_MAGIC)
476 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
479 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
481 if (bd->state != BOARD_READY)
484 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_iflag);
486 static DEVICE_ATTR_RO(tty_iflag);
488 static ssize_t tty_cflag_show(struct device *d,
489 struct device_attribute *attr, char *buf)
491 struct dgnc_board *bd;
492 struct channel_t *ch;
497 un = dev_get_drvdata(d);
498 if (!un || un->magic != DGNC_UNIT_MAGIC)
501 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
504 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
506 if (bd->state != BOARD_READY)
509 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_cflag);
511 static DEVICE_ATTR_RO(tty_cflag);
513 static ssize_t tty_oflag_show(struct device *d,
514 struct device_attribute *attr, char *buf)
516 struct dgnc_board *bd;
517 struct channel_t *ch;
522 un = dev_get_drvdata(d);
523 if (!un || un->magic != DGNC_UNIT_MAGIC)
526 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
529 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
531 if (bd->state != BOARD_READY)
534 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_oflag);
536 static DEVICE_ATTR_RO(tty_oflag);
538 static ssize_t tty_lflag_show(struct device *d,
539 struct device_attribute *attr, char *buf)
541 struct dgnc_board *bd;
542 struct channel_t *ch;
547 un = dev_get_drvdata(d);
548 if (!un || un->magic != DGNC_UNIT_MAGIC)
551 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
554 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
556 if (bd->state != BOARD_READY)
559 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_lflag);
561 static DEVICE_ATTR_RO(tty_lflag);
563 static ssize_t tty_digi_flag_show(struct device *d,
564 struct device_attribute *attr, char *buf)
566 struct dgnc_board *bd;
567 struct channel_t *ch;
572 un = dev_get_drvdata(d);
573 if (!un || un->magic != DGNC_UNIT_MAGIC)
576 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
579 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
581 if (bd->state != BOARD_READY)
584 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_digi.digi_flags);
586 static DEVICE_ATTR_RO(tty_digi_flag);
588 static ssize_t tty_rxcount_show(struct device *d,
589 struct device_attribute *attr, char *buf)
591 struct dgnc_board *bd;
592 struct channel_t *ch;
597 un = dev_get_drvdata(d);
598 if (!un || un->magic != DGNC_UNIT_MAGIC)
601 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
604 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
606 if (bd->state != BOARD_READY)
609 return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_rxcount);
611 static DEVICE_ATTR_RO(tty_rxcount);
613 static ssize_t tty_txcount_show(struct device *d,
614 struct device_attribute *attr, char *buf)
616 struct dgnc_board *bd;
617 struct channel_t *ch;
622 un = dev_get_drvdata(d);
623 if (!un || un->magic != DGNC_UNIT_MAGIC)
626 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
629 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
631 if (bd->state != BOARD_READY)
634 return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_txcount);
636 static DEVICE_ATTR_RO(tty_txcount);
638 static ssize_t tty_custom_name_show(struct device *d,
639 struct device_attribute *attr, char *buf)
641 struct dgnc_board *bd;
642 struct channel_t *ch;
647 un = dev_get_drvdata(d);
648 if (!un || un->magic != DGNC_UNIT_MAGIC)
651 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
654 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
656 if (bd->state != BOARD_READY)
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);
663 static DEVICE_ATTR_RO(tty_custom_name);
665 static struct attribute *dgnc_sysfs_tty_entries[] = {
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,
680 static struct attribute_group dgnc_tty_attribute_group = {
682 .attrs = dgnc_sysfs_tty_entries,
685 void dgnc_create_tty_sysfs(struct un_t *un, struct device *c)
689 ret = sysfs_create_group(&c->kobj, &dgnc_tty_attribute_group);
691 dev_err(c, "dgnc: failed to create sysfs tty device attributes.\n");
692 sysfs_remove_group(&c->kobj, &dgnc_tty_attribute_group);
696 dev_set_drvdata(c, un);
699 void dgnc_remove_tty_sysfs(struct device *c)
701 sysfs_remove_group(&c->kobj, &dgnc_tty_attribute_group);