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.
17 #include <linux/kernel.h>
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>
26 #include "dgnc_driver.h"
27 #include "dgnc_mgmt.h"
30 static ssize_t dgnc_driver_version_show(struct device_driver *ddp, char *buf)
32 return snprintf(buf, PAGE_SIZE, "%s\n", DG_PART);
34 static DRIVER_ATTR(version, S_IRUSR, dgnc_driver_version_show, NULL);
37 static ssize_t dgnc_driver_boards_show(struct device_driver *ddp, char *buf)
39 return snprintf(buf, PAGE_SIZE, "%d\n", dgnc_NumBoards);
41 static DRIVER_ATTR(boards, S_IRUSR, dgnc_driver_boards_show, NULL);
44 static ssize_t dgnc_driver_maxboards_show(struct device_driver *ddp, char *buf)
46 return snprintf(buf, PAGE_SIZE, "%d\n", MAXBOARDS);
48 static DRIVER_ATTR(maxboards, S_IRUSR, dgnc_driver_maxboards_show, NULL);
51 static ssize_t dgnc_driver_pollrate_show(struct device_driver *ddp, char *buf)
53 return snprintf(buf, PAGE_SIZE, "%dms\n", dgnc_poll_tick);
56 static ssize_t dgnc_driver_pollrate_store(struct device_driver *ddp, const char *buf, size_t count)
60 ret = sscanf(buf, "%d\n", &dgnc_poll_tick);
65 static DRIVER_ATTR(pollrate, (S_IRUSR | S_IWUSR), dgnc_driver_pollrate_show, dgnc_driver_pollrate_store);
68 void dgnc_create_driver_sysfiles(struct pci_driver *dgnc_driver)
71 struct device_driver *driverfs = &dgnc_driver->driver;
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);
76 rc |= driver_create_file(driverfs, &driver_attr_pollrate);
78 pr_err("DGNC: sysfs driver_create_file failed!\n");
82 void dgnc_remove_driver_sysfiles(struct pci_driver *dgnc_driver)
84 struct device_driver *driverfs = &dgnc_driver->driver;
86 driver_remove_file(driverfs, &driver_attr_version);
87 driver_remove_file(driverfs, &driver_attr_boards);
88 driver_remove_file(driverfs, &driver_attr_maxboards);
89 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) \
107 static ssize_t dgnc_vpd_show(struct device *p, struct device_attribute *attr, char *buf)
109 struct dgnc_board *bd;
113 DGNC_VERIFY_BOARD(p, bd);
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++) {
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(vpd, S_IRUSR, dgnc_vpd_show, NULL);
127 static ssize_t dgnc_serial_number_show(struct device *p, struct device_attribute *attr, char *buf)
129 struct dgnc_board *bd;
132 DGNC_VERIFY_BOARD(p, bd);
134 if (bd->serial_num[0] == '\0')
135 count += sprintf(buf + count, "<UNKNOWN>\n");
137 count += sprintf(buf + count, "%s\n", bd->serial_num);
141 static DEVICE_ATTR(serial_number, S_IRUSR, dgnc_serial_number_show, NULL);
144 static ssize_t dgnc_ports_state_show(struct device *p, struct device_attribute *attr, char *buf)
146 struct dgnc_board *bd;
150 DGNC_VERIFY_BOARD(p, bd);
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");
159 static DEVICE_ATTR(ports_state, S_IRUSR, dgnc_ports_state_show, NULL);
162 static ssize_t dgnc_ports_baud_show(struct device *p, struct device_attribute *attr, char *buf)
164 struct dgnc_board *bd;
168 DGNC_VERIFY_BOARD(p, bd);
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);
176 static DEVICE_ATTR(ports_baud, S_IRUSR, dgnc_ports_baud_show, NULL);
179 static ssize_t dgnc_ports_msignals_show(struct device *p, struct device_attribute *attr, char *buf)
181 struct dgnc_board *bd;
185 DGNC_VERIFY_BOARD(p, bd);
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" : "");
198 count += snprintf(buf + count, PAGE_SIZE - count,
199 "%d\n", bd->channels[i]->ch_portnum);
204 static DEVICE_ATTR(ports_msignals, S_IRUSR, dgnc_ports_msignals_show, NULL);
207 static ssize_t dgnc_ports_iflag_show(struct device *p, struct device_attribute *attr, char *buf)
209 struct dgnc_board *bd;
213 DGNC_VERIFY_BOARD(p, bd);
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);
221 static DEVICE_ATTR(ports_iflag, S_IRUSR, dgnc_ports_iflag_show, NULL);
224 static ssize_t dgnc_ports_cflag_show(struct device *p, struct device_attribute *attr, char *buf)
226 struct dgnc_board *bd;
230 DGNC_VERIFY_BOARD(p, bd);
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);
238 static DEVICE_ATTR(ports_cflag, S_IRUSR, dgnc_ports_cflag_show, NULL);
241 static ssize_t dgnc_ports_oflag_show(struct device *p, struct device_attribute *attr, char *buf)
243 struct dgnc_board *bd;
247 DGNC_VERIFY_BOARD(p, bd);
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);
255 static DEVICE_ATTR(ports_oflag, S_IRUSR, dgnc_ports_oflag_show, NULL);
258 static ssize_t dgnc_ports_lflag_show(struct device *p, struct device_attribute *attr, char *buf)
260 struct dgnc_board *bd;
264 DGNC_VERIFY_BOARD(p, bd);
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);
272 static DEVICE_ATTR(ports_lflag, S_IRUSR, dgnc_ports_lflag_show, NULL);
275 static ssize_t dgnc_ports_digi_flag_show(struct device *p, struct device_attribute *attr, char *buf)
277 struct dgnc_board *bd;
281 DGNC_VERIFY_BOARD(p, bd);
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);
289 static DEVICE_ATTR(ports_digi_flag, S_IRUSR, dgnc_ports_digi_flag_show, NULL);
292 static ssize_t dgnc_ports_rxcount_show(struct device *p, struct device_attribute *attr, char *buf)
294 struct dgnc_board *bd;
298 DGNC_VERIFY_BOARD(p, bd);
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);
306 static DEVICE_ATTR(ports_rxcount, S_IRUSR, dgnc_ports_rxcount_show, NULL);
309 static ssize_t dgnc_ports_txcount_show(struct device *p, struct device_attribute *attr, char *buf)
311 struct dgnc_board *bd;
315 DGNC_VERIFY_BOARD(p, bd);
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);
323 static DEVICE_ATTR(ports_txcount, S_IRUSR, dgnc_ports_txcount_show, NULL);
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
329 void dgnc_create_ports_sysfiles(struct dgnc_board *bd)
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);
347 dev_err(&bd->pdev->dev, "dgnc: sysfs device_create_file failed!\n");
351 /* removes all the sys files created for that port */
352 void dgnc_remove_ports_sysfiles(struct dgnc_board *bd)
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);
369 static ssize_t dgnc_tty_state_show(struct device *d, struct device_attribute *attr, char *buf)
371 struct dgnc_board *bd;
372 struct channel_t *ch;
377 un = dev_get_drvdata(d);
378 if (!un || un->magic != DGNC_UNIT_MAGIC)
381 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
384 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
386 if (bd->state != BOARD_READY)
389 return snprintf(buf, PAGE_SIZE, "%s", un->un_open_count ? "Open" : "Closed");
391 static DEVICE_ATTR(state, S_IRUSR, dgnc_tty_state_show, NULL);
394 static ssize_t dgnc_tty_baud_show(struct device *d, struct device_attribute *attr, char *buf)
396 struct dgnc_board *bd;
397 struct channel_t *ch;
402 un = dev_get_drvdata(d);
403 if (!un || un->magic != DGNC_UNIT_MAGIC)
406 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
409 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
411 if (bd->state != BOARD_READY)
414 return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_old_baud);
416 static DEVICE_ATTR(baud, S_IRUSR, dgnc_tty_baud_show, NULL);
419 static ssize_t dgnc_tty_msignals_show(struct device *d, struct device_attribute *attr, char *buf)
421 struct dgnc_board *bd;
422 struct channel_t *ch;
427 un = dev_get_drvdata(d);
428 if (!un || un->magic != DGNC_UNIT_MAGIC)
431 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
434 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
436 if (bd->state != BOARD_READY)
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" : "");
450 static DEVICE_ATTR(msignals, S_IRUSR, dgnc_tty_msignals_show, NULL);
453 static ssize_t dgnc_tty_iflag_show(struct device *d, struct device_attribute *attr, char *buf)
455 struct dgnc_board *bd;
456 struct channel_t *ch;
461 un = dev_get_drvdata(d);
462 if (!un || un->magic != DGNC_UNIT_MAGIC)
465 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
468 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
470 if (bd->state != BOARD_READY)
473 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_iflag);
475 static DEVICE_ATTR(iflag, S_IRUSR, dgnc_tty_iflag_show, NULL);
478 static ssize_t dgnc_tty_cflag_show(struct device *d, struct device_attribute *attr, char *buf)
480 struct dgnc_board *bd;
481 struct channel_t *ch;
486 un = dev_get_drvdata(d);
487 if (!un || un->magic != DGNC_UNIT_MAGIC)
490 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
493 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
495 if (bd->state != BOARD_READY)
498 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_cflag);
500 static DEVICE_ATTR(cflag, S_IRUSR, dgnc_tty_cflag_show, NULL);
503 static ssize_t dgnc_tty_oflag_show(struct device *d, struct device_attribute *attr, char *buf)
505 struct dgnc_board *bd;
506 struct channel_t *ch;
511 un = dev_get_drvdata(d);
512 if (!un || un->magic != DGNC_UNIT_MAGIC)
515 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
518 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
520 if (bd->state != BOARD_READY)
523 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_oflag);
525 static DEVICE_ATTR(oflag, S_IRUSR, dgnc_tty_oflag_show, NULL);
528 static ssize_t dgnc_tty_lflag_show(struct device *d, struct device_attribute *attr, char *buf)
530 struct dgnc_board *bd;
531 struct channel_t *ch;
536 un = dev_get_drvdata(d);
537 if (!un || un->magic != DGNC_UNIT_MAGIC)
540 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
543 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
545 if (bd->state != BOARD_READY)
548 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_lflag);
550 static DEVICE_ATTR(lflag, S_IRUSR, dgnc_tty_lflag_show, NULL);
553 static ssize_t dgnc_tty_digi_flag_show(struct device *d, struct device_attribute *attr, char *buf)
555 struct dgnc_board *bd;
556 struct channel_t *ch;
561 un = dev_get_drvdata(d);
562 if (!un || un->magic != DGNC_UNIT_MAGIC)
565 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
568 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
570 if (bd->state != BOARD_READY)
573 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_digi.digi_flags);
575 static DEVICE_ATTR(digi_flag, S_IRUSR, dgnc_tty_digi_flag_show, NULL);
578 static ssize_t dgnc_tty_rxcount_show(struct device *d, struct device_attribute *attr, char *buf)
580 struct dgnc_board *bd;
581 struct channel_t *ch;
586 un = dev_get_drvdata(d);
587 if (!un || un->magic != DGNC_UNIT_MAGIC)
590 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
593 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
595 if (bd->state != BOARD_READY)
598 return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_rxcount);
600 static DEVICE_ATTR(rxcount, S_IRUSR, dgnc_tty_rxcount_show, NULL);
603 static ssize_t dgnc_tty_txcount_show(struct device *d, struct device_attribute *attr, char *buf)
605 struct dgnc_board *bd;
606 struct channel_t *ch;
611 un = dev_get_drvdata(d);
612 if (!un || un->magic != DGNC_UNIT_MAGIC)
615 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
618 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
620 if (bd->state != BOARD_READY)
623 return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_txcount);
625 static DEVICE_ATTR(txcount, S_IRUSR, dgnc_tty_txcount_show, NULL);
628 static ssize_t dgnc_tty_name_show(struct device *d, struct device_attribute *attr, char *buf)
630 struct dgnc_board *bd;
631 struct channel_t *ch;
636 un = dev_get_drvdata(d);
637 if (!un || un->magic != DGNC_UNIT_MAGIC)
640 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
643 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
645 if (bd->state != BOARD_READY)
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);
652 static DEVICE_ATTR(custom_name, S_IRUSR, dgnc_tty_name_show, NULL);
655 static struct attribute *dgnc_sysfs_tty_entries[] = {
656 &dev_attr_state.attr,
658 &dev_attr_msignals.attr,
659 &dev_attr_iflag.attr,
660 &dev_attr_cflag.attr,
661 &dev_attr_oflag.attr,
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,
671 static struct attribute_group dgnc_tty_attribute_group = {
673 .attrs = dgnc_sysfs_tty_entries,
677 void dgnc_create_tty_sysfs(struct un_t *un, struct device *c)
681 ret = sysfs_create_group(&c->kobj, &dgnc_tty_attribute_group);
683 dev_err(c, "dgnc: failed to create sysfs tty device attributes.\n");
684 sysfs_remove_group(&c->kobj, &dgnc_tty_attribute_group);
688 dev_set_drvdata(c, un);
693 void dgnc_remove_tty_sysfs(struct device *c)
695 sysfs_remove_group(&c->kobj, &dgnc_tty_attribute_group);