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,
57 const char *buf, size_t count)
61 ret = sscanf(buf, "%d\n", &dgnc_poll_tick);
66 static DRIVER_ATTR(pollrate, (S_IRUSR | S_IWUSR), dgnc_driver_pollrate_show,
67 dgnc_driver_pollrate_store);
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");
84 void dgnc_remove_driver_sysfiles(struct pci_driver *dgnc_driver)
86 struct device_driver *driverfs = &dgnc_driver->driver;
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);
95 #define DGNC_VERIFY_BOARD(p, bd) \
100 bd = dev_get_drvdata(p); \
101 if (!bd || bd->magic != DGNC_BOARD_MAGIC) \
103 if (bd->state != BOARD_READY) \
109 static ssize_t dgnc_vpd_show(struct device *p, struct device_attribute *attr,
112 struct dgnc_board *bd;
116 DGNC_VERIFY_BOARD(p, bd);
118 count += sprintf(buf + count,
119 "\n 0 1 2 3 4 5 6 7 8 9 A B C D E F");
120 for (i = 0; i < 0x40 * 2; i++) {
122 count += sprintf(buf + count, "\n%04X ", i * 2);
123 count += sprintf(buf + count, "%02X ", bd->vpd[i]);
125 count += sprintf(buf + count, "\n");
129 static DEVICE_ATTR(vpd, S_IRUSR, dgnc_vpd_show, NULL);
131 static ssize_t dgnc_serial_number_show(struct device *p,
132 struct device_attribute *attr, char *buf)
134 struct dgnc_board *bd;
137 DGNC_VERIFY_BOARD(p, bd);
139 if (bd->serial_num[0] == '\0')
140 count += sprintf(buf + count, "<UNKNOWN>\n");
142 count += sprintf(buf + count, "%s\n", bd->serial_num);
146 static DEVICE_ATTR(serial_number, S_IRUSR, dgnc_serial_number_show, NULL);
149 static ssize_t dgnc_ports_state_show(struct device *p,
150 struct device_attribute *attr, char *buf)
152 struct dgnc_board *bd;
156 DGNC_VERIFY_BOARD(p, bd);
158 for (i = 0; i < bd->nasync; i++) {
159 count += snprintf(buf + count, PAGE_SIZE - count,
160 "%d %s\n", bd->channels[i]->ch_portnum,
161 bd->channels[i]->ch_open_count ? "Open" : "Closed");
165 static DEVICE_ATTR(ports_state, S_IRUSR, dgnc_ports_state_show, NULL);
168 static ssize_t dgnc_ports_baud_show(struct device *p,
169 struct device_attribute *attr, char *buf)
171 struct dgnc_board *bd;
175 DGNC_VERIFY_BOARD(p, bd);
177 for (i = 0; i < bd->nasync; i++) {
178 count += snprintf(buf + count, PAGE_SIZE - count,
179 "%d %d\n", bd->channels[i]->ch_portnum,
180 bd->channels[i]->ch_old_baud);
184 static DEVICE_ATTR(ports_baud, S_IRUSR, dgnc_ports_baud_show, NULL);
187 static ssize_t dgnc_ports_msignals_show(struct device *p,
188 struct device_attribute *attr,
191 struct dgnc_board *bd;
195 DGNC_VERIFY_BOARD(p, bd);
197 for (i = 0; i < bd->nasync; i++) {
198 if (bd->channels[i]->ch_open_count) {
199 count += snprintf(buf + count, PAGE_SIZE - count,
200 "%d %s %s %s %s %s %s\n",
201 bd->channels[i]->ch_portnum,
202 (bd->channels[i]->ch_mostat & UART_MCR_RTS) ? "RTS" : "",
203 (bd->channels[i]->ch_mistat & UART_MSR_CTS) ? "CTS" : "",
204 (bd->channels[i]->ch_mostat & UART_MCR_DTR) ? "DTR" : "",
205 (bd->channels[i]->ch_mistat & UART_MSR_DSR) ? "DSR" : "",
206 (bd->channels[i]->ch_mistat & UART_MSR_DCD) ? "DCD" : "",
207 (bd->channels[i]->ch_mistat & UART_MSR_RI) ? "RI" : "");
209 count += snprintf(buf + count, PAGE_SIZE - count,
210 "%d\n", bd->channels[i]->ch_portnum);
215 static DEVICE_ATTR(ports_msignals, S_IRUSR, dgnc_ports_msignals_show, NULL);
218 static ssize_t dgnc_ports_iflag_show(struct device *p,
219 struct device_attribute *attr, char *buf)
221 struct dgnc_board *bd;
225 DGNC_VERIFY_BOARD(p, bd);
227 for (i = 0; i < bd->nasync; i++) {
228 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
229 bd->channels[i]->ch_portnum,
230 bd->channels[i]->ch_c_iflag);
234 static DEVICE_ATTR(ports_iflag, S_IRUSR, dgnc_ports_iflag_show, NULL);
237 static ssize_t dgnc_ports_cflag_show(struct device *p,
238 struct device_attribute *attr, char *buf)
240 struct dgnc_board *bd;
244 DGNC_VERIFY_BOARD(p, bd);
246 for (i = 0; i < bd->nasync; i++) {
247 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
248 bd->channels[i]->ch_portnum,
249 bd->channels[i]->ch_c_cflag);
253 static DEVICE_ATTR(ports_cflag, S_IRUSR, dgnc_ports_cflag_show, NULL);
256 static ssize_t dgnc_ports_oflag_show(struct device *p,
257 struct device_attribute *attr, char *buf)
259 struct dgnc_board *bd;
263 DGNC_VERIFY_BOARD(p, bd);
265 for (i = 0; i < bd->nasync; i++) {
266 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
267 bd->channels[i]->ch_portnum,
268 bd->channels[i]->ch_c_oflag);
272 static DEVICE_ATTR(ports_oflag, S_IRUSR, dgnc_ports_oflag_show, NULL);
275 static ssize_t dgnc_ports_lflag_show(struct device *p,
276 struct device_attribute *attr, char *buf)
278 struct dgnc_board *bd;
282 DGNC_VERIFY_BOARD(p, bd);
284 for (i = 0; i < bd->nasync; i++) {
285 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
286 bd->channels[i]->ch_portnum,
287 bd->channels[i]->ch_c_lflag);
291 static DEVICE_ATTR(ports_lflag, S_IRUSR, dgnc_ports_lflag_show, NULL);
294 static ssize_t dgnc_ports_digi_flag_show(struct device *p,
295 struct device_attribute *attr,
298 struct dgnc_board *bd;
302 DGNC_VERIFY_BOARD(p, bd);
304 for (i = 0; i < bd->nasync; i++) {
305 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
306 bd->channels[i]->ch_portnum,
307 bd->channels[i]->ch_digi.digi_flags);
311 static DEVICE_ATTR(ports_digi_flag, S_IRUSR, dgnc_ports_digi_flag_show, NULL);
314 static ssize_t dgnc_ports_rxcount_show(struct device *p,
315 struct device_attribute *attr, char *buf)
317 struct dgnc_board *bd;
321 DGNC_VERIFY_BOARD(p, bd);
323 for (i = 0; i < bd->nasync; i++) {
324 count += snprintf(buf + count, PAGE_SIZE - count, "%d %ld\n",
325 bd->channels[i]->ch_portnum,
326 bd->channels[i]->ch_rxcount);
330 static DEVICE_ATTR(ports_rxcount, S_IRUSR, dgnc_ports_rxcount_show, NULL);
333 static ssize_t dgnc_ports_txcount_show(struct device *p,
334 struct device_attribute *attr, char *buf)
336 struct dgnc_board *bd;
340 DGNC_VERIFY_BOARD(p, bd);
342 for (i = 0; i < bd->nasync; i++) {
343 count += snprintf(buf + count, PAGE_SIZE - count, "%d %ld\n",
344 bd->channels[i]->ch_portnum,
345 bd->channels[i]->ch_txcount);
349 static DEVICE_ATTR(ports_txcount, S_IRUSR, dgnc_ports_txcount_show, NULL);
352 /* this function creates the sys files that will export each signal status
353 * to sysfs each value will be put in a separate filename
355 void dgnc_create_ports_sysfiles(struct dgnc_board *bd)
359 dev_set_drvdata(&bd->pdev->dev, bd);
360 rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_state);
361 rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_baud);
362 rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_msignals);
363 rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_iflag);
364 rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_cflag);
365 rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_oflag);
366 rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_lflag);
367 rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_digi_flag);
368 rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_rxcount);
369 rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_txcount);
370 rc |= device_create_file(&(bd->pdev->dev), &dev_attr_vpd);
371 rc |= device_create_file(&(bd->pdev->dev), &dev_attr_serial_number);
373 dev_err(&bd->pdev->dev, "dgnc: sysfs device_create_file failed!\n");
377 /* removes all the sys files created for that port */
378 void dgnc_remove_ports_sysfiles(struct dgnc_board *bd)
380 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_state);
381 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_baud);
382 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_msignals);
383 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_iflag);
384 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_cflag);
385 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_oflag);
386 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_lflag);
387 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_digi_flag);
388 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_rxcount);
389 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_txcount);
390 device_remove_file(&(bd->pdev->dev), &dev_attr_vpd);
391 device_remove_file(&(bd->pdev->dev), &dev_attr_serial_number);
395 static ssize_t dgnc_tty_state_show(struct device *d,
396 struct device_attribute *attr, char *buf)
398 struct dgnc_board *bd;
399 struct channel_t *ch;
404 un = dev_get_drvdata(d);
405 if (!un || un->magic != DGNC_UNIT_MAGIC)
408 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
411 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
413 if (bd->state != BOARD_READY)
416 return snprintf(buf, PAGE_SIZE, "%s",
417 un->un_open_count ? "Open" : "Closed");
419 static DEVICE_ATTR(state, S_IRUSR, dgnc_tty_state_show, NULL);
422 static ssize_t dgnc_tty_baud_show(struct device *d,
423 struct device_attribute *attr, char *buf)
425 struct dgnc_board *bd;
426 struct channel_t *ch;
431 un = dev_get_drvdata(d);
432 if (!un || un->magic != DGNC_UNIT_MAGIC)
435 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
438 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
440 if (bd->state != BOARD_READY)
443 return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_old_baud);
445 static DEVICE_ATTR(baud, S_IRUSR, dgnc_tty_baud_show, NULL);
448 static ssize_t dgnc_tty_msignals_show(struct device *d,
449 struct device_attribute *attr, char *buf)
451 struct dgnc_board *bd;
452 struct channel_t *ch;
457 un = dev_get_drvdata(d);
458 if (!un || un->magic != DGNC_UNIT_MAGIC)
461 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
464 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
466 if (bd->state != BOARD_READY)
469 if (ch->ch_open_count) {
470 return snprintf(buf, PAGE_SIZE, "%s %s %s %s %s %s\n",
471 (ch->ch_mostat & UART_MCR_RTS) ? "RTS" : "",
472 (ch->ch_mistat & UART_MSR_CTS) ? "CTS" : "",
473 (ch->ch_mostat & UART_MCR_DTR) ? "DTR" : "",
474 (ch->ch_mistat & UART_MSR_DSR) ? "DSR" : "",
475 (ch->ch_mistat & UART_MSR_DCD) ? "DCD" : "",
476 (ch->ch_mistat & UART_MSR_RI) ? "RI" : "");
480 static DEVICE_ATTR(msignals, S_IRUSR, dgnc_tty_msignals_show, NULL);
483 static ssize_t dgnc_tty_iflag_show(struct device *d,
484 struct device_attribute *attr, char *buf)
486 struct dgnc_board *bd;
487 struct channel_t *ch;
492 un = dev_get_drvdata(d);
493 if (!un || un->magic != DGNC_UNIT_MAGIC)
496 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
499 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
501 if (bd->state != BOARD_READY)
504 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_iflag);
506 static DEVICE_ATTR(iflag, S_IRUSR, dgnc_tty_iflag_show, NULL);
509 static ssize_t dgnc_tty_cflag_show(struct device *d,
510 struct device_attribute *attr, char *buf)
512 struct dgnc_board *bd;
513 struct channel_t *ch;
518 un = dev_get_drvdata(d);
519 if (!un || un->magic != DGNC_UNIT_MAGIC)
522 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
525 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
527 if (bd->state != BOARD_READY)
530 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_cflag);
532 static DEVICE_ATTR(cflag, S_IRUSR, dgnc_tty_cflag_show, NULL);
535 static ssize_t dgnc_tty_oflag_show(struct device *d,
536 struct device_attribute *attr, char *buf)
538 struct dgnc_board *bd;
539 struct channel_t *ch;
544 un = dev_get_drvdata(d);
545 if (!un || un->magic != DGNC_UNIT_MAGIC)
548 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
551 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
553 if (bd->state != BOARD_READY)
556 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_oflag);
558 static DEVICE_ATTR(oflag, S_IRUSR, dgnc_tty_oflag_show, NULL);
561 static ssize_t dgnc_tty_lflag_show(struct device *d,
562 struct device_attribute *attr, char *buf)
564 struct dgnc_board *bd;
565 struct channel_t *ch;
570 un = dev_get_drvdata(d);
571 if (!un || un->magic != DGNC_UNIT_MAGIC)
574 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
577 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
579 if (bd->state != BOARD_READY)
582 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_lflag);
584 static DEVICE_ATTR(lflag, S_IRUSR, dgnc_tty_lflag_show, NULL);
587 static ssize_t dgnc_tty_digi_flag_show(struct device *d,
588 struct device_attribute *attr, char *buf)
590 struct dgnc_board *bd;
591 struct channel_t *ch;
596 un = dev_get_drvdata(d);
597 if (!un || un->magic != DGNC_UNIT_MAGIC)
600 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
603 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
605 if (bd->state != BOARD_READY)
608 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_digi.digi_flags);
610 static DEVICE_ATTR(digi_flag, S_IRUSR, dgnc_tty_digi_flag_show, NULL);
613 static ssize_t dgnc_tty_rxcount_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_rxcount);
636 static DEVICE_ATTR(rxcount, S_IRUSR, dgnc_tty_rxcount_show, NULL);
639 static ssize_t dgnc_tty_txcount_show(struct device *d,
640 struct device_attribute *attr, char *buf)
642 struct dgnc_board *bd;
643 struct channel_t *ch;
648 un = dev_get_drvdata(d);
649 if (!un || un->magic != DGNC_UNIT_MAGIC)
652 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
655 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
657 if (bd->state != BOARD_READY)
660 return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_txcount);
662 static DEVICE_ATTR(txcount, S_IRUSR, dgnc_tty_txcount_show, NULL);
665 static ssize_t dgnc_tty_name_show(struct device *d,
666 struct device_attribute *attr, char *buf)
668 struct dgnc_board *bd;
669 struct channel_t *ch;
674 un = dev_get_drvdata(d);
675 if (!un || un->magic != DGNC_UNIT_MAGIC)
678 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
681 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
683 if (bd->state != BOARD_READY)
686 return snprintf(buf, PAGE_SIZE, "%sn%d%c\n",
687 (un->un_type == DGNC_PRINT) ? "pr" : "tty",
688 bd->boardnum + 1, 'a' + ch->ch_portnum);
690 static DEVICE_ATTR(custom_name, S_IRUSR, dgnc_tty_name_show, NULL);
693 static struct attribute *dgnc_sysfs_tty_entries[] = {
694 &dev_attr_state.attr,
696 &dev_attr_msignals.attr,
697 &dev_attr_iflag.attr,
698 &dev_attr_cflag.attr,
699 &dev_attr_oflag.attr,
700 &dev_attr_lflag.attr,
701 &dev_attr_digi_flag.attr,
702 &dev_attr_rxcount.attr,
703 &dev_attr_txcount.attr,
704 &dev_attr_custom_name.attr,
709 static struct attribute_group dgnc_tty_attribute_group = {
711 .attrs = dgnc_sysfs_tty_entries,
715 void dgnc_create_tty_sysfs(struct un_t *un, struct device *c)
719 ret = sysfs_create_group(&c->kobj, &dgnc_tty_attribute_group);
721 dev_err(c, "dgnc: failed to create sysfs tty device attributes.\n");
722 sysfs_remove_group(&c->kobj, &dgnc_tty_attribute_group);
726 dev_set_drvdata(c, un);
731 void dgnc_remove_tty_sysfs(struct device *c)
733 sysfs_remove_group(&c->kobj, &dgnc_tty_attribute_group);