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.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 * NOTE TO LINUX KERNEL HACKERS: DO NOT REFORMAT THIS CODE!
22 * This is shared code between Digi's CVS archive and the
23 * Linux Kernel sources.
24 * Changing the source just for reformatting needlessly breaks
25 * our CVS diff history.
27 * Send any bug fixes/changes to: Eng.Linux at digi dot com.
33 #include <linux/kernel.h>
34 #include <linux/module.h>
35 #include <linux/ctype.h>
36 #include <linux/string.h>
37 #include <linux/serial_reg.h>
38 #include <linux/device.h>
39 #include <linux/pci.h>
40 #include <linux/kdev_t.h>
42 #include "dgnc_driver.h"
43 #include "dgnc_mgmt.h"
46 static ssize_t dgnc_driver_version_show(struct device_driver *ddp, char *buf)
48 return snprintf(buf, PAGE_SIZE, "%s\n", DG_PART);
50 static DRIVER_ATTR(version, S_IRUSR, dgnc_driver_version_show, NULL);
53 static ssize_t dgnc_driver_boards_show(struct device_driver *ddp, char *buf)
55 return snprintf(buf, PAGE_SIZE, "%d\n", dgnc_NumBoards);
57 static DRIVER_ATTR(boards, S_IRUSR, dgnc_driver_boards_show, NULL);
60 static ssize_t dgnc_driver_maxboards_show(struct device_driver *ddp, char *buf)
62 return snprintf(buf, PAGE_SIZE, "%d\n", MAXBOARDS);
64 static DRIVER_ATTR(maxboards, S_IRUSR, dgnc_driver_maxboards_show, NULL);
67 static ssize_t dgnc_driver_pollrate_show(struct device_driver *ddp, char *buf)
69 return snprintf(buf, PAGE_SIZE, "%dms\n", dgnc_poll_tick);
72 static ssize_t dgnc_driver_pollrate_store(struct device_driver *ddp, const char *buf, size_t count)
76 ret = sscanf(buf, "%d\n", &dgnc_poll_tick);
81 static DRIVER_ATTR(pollrate, (S_IRUSR | S_IWUSR), dgnc_driver_pollrate_show, dgnc_driver_pollrate_store);
84 void dgnc_create_driver_sysfiles(struct pci_driver *dgnc_driver)
87 struct device_driver *driverfs = &dgnc_driver->driver;
89 rc |= driver_create_file(driverfs, &driver_attr_version);
90 rc |= driver_create_file(driverfs, &driver_attr_boards);
91 rc |= driver_create_file(driverfs, &driver_attr_maxboards);
92 rc |= driver_create_file(driverfs, &driver_attr_pollrate);
94 printk(KERN_ERR "DGNC: sysfs driver_create_file failed!\n");
98 void dgnc_remove_driver_sysfiles(struct pci_driver *dgnc_driver)
100 struct device_driver *driverfs = &dgnc_driver->driver;
102 driver_remove_file(driverfs, &driver_attr_version);
103 driver_remove_file(driverfs, &driver_attr_boards);
104 driver_remove_file(driverfs, &driver_attr_maxboards);
105 driver_remove_file(driverfs, &driver_attr_pollrate);
109 #define DGNC_VERIFY_BOARD(p, bd) \
114 bd = dev_get_drvdata(p); \
115 if (!bd || bd->magic != DGNC_BOARD_MAGIC) \
117 if (bd->state != BOARD_READY) \
123 static ssize_t dgnc_vpd_show(struct device *p, struct device_attribute *attr, char *buf)
125 struct dgnc_board *bd;
129 DGNC_VERIFY_BOARD(p, bd);
131 count += sprintf(buf + count, "\n 0 1 2 3 4 5 6 7 8 9 A B C D E F");
132 for (i = 0; i < 0x40 * 2; i++) {
134 count += sprintf(buf + count, "\n%04X ", i * 2);
135 count += sprintf(buf + count, "%02X ", bd->vpd[i]);
137 count += sprintf(buf + count, "\n");
141 static DEVICE_ATTR(vpd, S_IRUSR, dgnc_vpd_show, NULL);
143 static ssize_t dgnc_serial_number_show(struct device *p, struct device_attribute *attr, char *buf)
145 struct dgnc_board *bd;
148 DGNC_VERIFY_BOARD(p, bd);
150 if (bd->serial_num[0] == '\0')
151 count += sprintf(buf + count, "<UNKNOWN>\n");
153 count += sprintf(buf + count, "%s\n", bd->serial_num);
157 static DEVICE_ATTR(serial_number, S_IRUSR, dgnc_serial_number_show, NULL);
160 static ssize_t dgnc_ports_state_show(struct device *p, struct device_attribute *attr, char *buf)
162 struct dgnc_board *bd;
166 DGNC_VERIFY_BOARD(p, bd);
168 for (i = 0; i < bd->nasync; i++) {
169 count += snprintf(buf + count, PAGE_SIZE - count,
170 "%d %s\n", bd->channels[i]->ch_portnum,
171 bd->channels[i]->ch_open_count ? "Open" : "Closed");
175 static DEVICE_ATTR(ports_state, S_IRUSR, dgnc_ports_state_show, NULL);
178 static ssize_t dgnc_ports_baud_show(struct device *p, struct device_attribute *attr, char *buf)
180 struct dgnc_board *bd;
184 DGNC_VERIFY_BOARD(p, bd);
186 for (i = 0; i < bd->nasync; i++) {
187 count += snprintf(buf + count, PAGE_SIZE - count,
188 "%d %d\n", bd->channels[i]->ch_portnum, bd->channels[i]->ch_old_baud);
192 static DEVICE_ATTR(ports_baud, S_IRUSR, dgnc_ports_baud_show, NULL);
195 static ssize_t dgnc_ports_msignals_show(struct device *p, struct device_attribute *attr, char *buf)
197 struct dgnc_board *bd;
201 DGNC_VERIFY_BOARD(p, bd);
203 for (i = 0; i < bd->nasync; i++) {
204 if (bd->channels[i]->ch_open_count) {
205 count += snprintf(buf + count, PAGE_SIZE - count,
206 "%d %s %s %s %s %s %s\n", bd->channels[i]->ch_portnum,
207 (bd->channels[i]->ch_mostat & UART_MCR_RTS) ? "RTS" : "",
208 (bd->channels[i]->ch_mistat & UART_MSR_CTS) ? "CTS" : "",
209 (bd->channels[i]->ch_mostat & UART_MCR_DTR) ? "DTR" : "",
210 (bd->channels[i]->ch_mistat & UART_MSR_DSR) ? "DSR" : "",
211 (bd->channels[i]->ch_mistat & UART_MSR_DCD) ? "DCD" : "",
212 (bd->channels[i]->ch_mistat & UART_MSR_RI) ? "RI" : "");
214 count += snprintf(buf + count, PAGE_SIZE - count,
215 "%d\n", bd->channels[i]->ch_portnum);
220 static DEVICE_ATTR(ports_msignals, S_IRUSR, dgnc_ports_msignals_show, NULL);
223 static ssize_t dgnc_ports_iflag_show(struct device *p, struct device_attribute *attr, char *buf)
225 struct dgnc_board *bd;
229 DGNC_VERIFY_BOARD(p, bd);
231 for (i = 0; i < bd->nasync; i++) {
232 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
233 bd->channels[i]->ch_portnum, bd->channels[i]->ch_c_iflag);
237 static DEVICE_ATTR(ports_iflag, S_IRUSR, dgnc_ports_iflag_show, NULL);
240 static ssize_t dgnc_ports_cflag_show(struct device *p, struct device_attribute *attr, char *buf)
242 struct dgnc_board *bd;
246 DGNC_VERIFY_BOARD(p, bd);
248 for (i = 0; i < bd->nasync; i++) {
249 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
250 bd->channels[i]->ch_portnum, bd->channels[i]->ch_c_cflag);
254 static DEVICE_ATTR(ports_cflag, S_IRUSR, dgnc_ports_cflag_show, NULL);
257 static ssize_t dgnc_ports_oflag_show(struct device *p, 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, bd->channels[i]->ch_c_oflag);
271 static DEVICE_ATTR(ports_oflag, S_IRUSR, dgnc_ports_oflag_show, NULL);
274 static ssize_t dgnc_ports_lflag_show(struct device *p, struct device_attribute *attr, char *buf)
276 struct dgnc_board *bd;
280 DGNC_VERIFY_BOARD(p, bd);
282 for (i = 0; i < bd->nasync; i++) {
283 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
284 bd->channels[i]->ch_portnum, bd->channels[i]->ch_c_lflag);
288 static DEVICE_ATTR(ports_lflag, S_IRUSR, dgnc_ports_lflag_show, NULL);
291 static ssize_t dgnc_ports_digi_flag_show(struct device *p, struct device_attribute *attr, char *buf)
293 struct dgnc_board *bd;
297 DGNC_VERIFY_BOARD(p, bd);
299 for (i = 0; i < bd->nasync; i++) {
300 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
301 bd->channels[i]->ch_portnum, bd->channels[i]->ch_digi.digi_flags);
305 static DEVICE_ATTR(ports_digi_flag, S_IRUSR, dgnc_ports_digi_flag_show, NULL);
308 static ssize_t dgnc_ports_rxcount_show(struct device *p, struct device_attribute *attr, char *buf)
310 struct dgnc_board *bd;
314 DGNC_VERIFY_BOARD(p, bd);
316 for (i = 0; i < bd->nasync; i++) {
317 count += snprintf(buf + count, PAGE_SIZE - count, "%d %ld\n",
318 bd->channels[i]->ch_portnum, bd->channels[i]->ch_rxcount);
322 static DEVICE_ATTR(ports_rxcount, S_IRUSR, dgnc_ports_rxcount_show, NULL);
325 static ssize_t dgnc_ports_txcount_show(struct device *p, struct device_attribute *attr, char *buf)
327 struct dgnc_board *bd;
331 DGNC_VERIFY_BOARD(p, bd);
333 for (i = 0; i < bd->nasync; i++) {
334 count += snprintf(buf + count, PAGE_SIZE - count, "%d %ld\n",
335 bd->channels[i]->ch_portnum, bd->channels[i]->ch_txcount);
339 static DEVICE_ATTR(ports_txcount, S_IRUSR, dgnc_ports_txcount_show, NULL);
342 /* this function creates the sys files that will export each signal status
343 * to sysfs each value will be put in a separate filename
345 void dgnc_create_ports_sysfiles(struct dgnc_board *bd)
349 dev_set_drvdata(&bd->pdev->dev, bd);
350 rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_state);
351 rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_baud);
352 rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_msignals);
353 rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_iflag);
354 rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_cflag);
355 rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_oflag);
356 rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_lflag);
357 rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_digi_flag);
358 rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_rxcount);
359 rc |= device_create_file(&(bd->pdev->dev), &dev_attr_ports_txcount);
360 rc |= device_create_file(&(bd->pdev->dev), &dev_attr_vpd);
361 rc |= device_create_file(&(bd->pdev->dev), &dev_attr_serial_number);
363 printk(KERN_ERR "DGNC: sysfs device_create_file failed!\n");
367 /* removes all the sys files created for that port */
368 void dgnc_remove_ports_sysfiles(struct dgnc_board *bd)
370 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_state);
371 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_baud);
372 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_msignals);
373 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_iflag);
374 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_cflag);
375 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_oflag);
376 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_lflag);
377 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_digi_flag);
378 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_rxcount);
379 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_txcount);
380 device_remove_file(&(bd->pdev->dev), &dev_attr_vpd);
381 device_remove_file(&(bd->pdev->dev), &dev_attr_serial_number);
385 static ssize_t dgnc_tty_state_show(struct device *d, struct device_attribute *attr, char *buf)
387 struct dgnc_board *bd;
388 struct channel_t *ch;
393 un = dev_get_drvdata(d);
394 if (!un || un->magic != DGNC_UNIT_MAGIC)
397 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
400 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
402 if (bd->state != BOARD_READY)
405 return snprintf(buf, PAGE_SIZE, "%s", un->un_open_count ? "Open" : "Closed");
407 static DEVICE_ATTR(state, S_IRUSR, dgnc_tty_state_show, NULL);
410 static ssize_t dgnc_tty_baud_show(struct device *d, struct device_attribute *attr, char *buf)
412 struct dgnc_board *bd;
413 struct channel_t *ch;
418 un = dev_get_drvdata(d);
419 if (!un || un->magic != DGNC_UNIT_MAGIC)
422 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
425 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
427 if (bd->state != BOARD_READY)
430 return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_old_baud);
432 static DEVICE_ATTR(baud, S_IRUSR, dgnc_tty_baud_show, NULL);
435 static ssize_t dgnc_tty_msignals_show(struct device *d, struct device_attribute *attr, char *buf)
437 struct dgnc_board *bd;
438 struct channel_t *ch;
443 un = dev_get_drvdata(d);
444 if (!un || un->magic != DGNC_UNIT_MAGIC)
447 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
450 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
452 if (bd->state != BOARD_READY)
455 if (ch->ch_open_count) {
456 return snprintf(buf, PAGE_SIZE, "%s %s %s %s %s %s\n",
457 (ch->ch_mostat & UART_MCR_RTS) ? "RTS" : "",
458 (ch->ch_mistat & UART_MSR_CTS) ? "CTS" : "",
459 (ch->ch_mostat & UART_MCR_DTR) ? "DTR" : "",
460 (ch->ch_mistat & UART_MSR_DSR) ? "DSR" : "",
461 (ch->ch_mistat & UART_MSR_DCD) ? "DCD" : "",
462 (ch->ch_mistat & UART_MSR_RI) ? "RI" : "");
466 static DEVICE_ATTR(msignals, S_IRUSR, dgnc_tty_msignals_show, NULL);
469 static ssize_t dgnc_tty_iflag_show(struct device *d, struct device_attribute *attr, char *buf)
471 struct dgnc_board *bd;
472 struct channel_t *ch;
477 un = dev_get_drvdata(d);
478 if (!un || un->magic != DGNC_UNIT_MAGIC)
481 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
484 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
486 if (bd->state != BOARD_READY)
489 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_iflag);
491 static DEVICE_ATTR(iflag, S_IRUSR, dgnc_tty_iflag_show, NULL);
494 static ssize_t dgnc_tty_cflag_show(struct device *d, struct device_attribute *attr, char *buf)
496 struct dgnc_board *bd;
497 struct channel_t *ch;
502 un = dev_get_drvdata(d);
503 if (!un || un->magic != DGNC_UNIT_MAGIC)
506 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
509 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
511 if (bd->state != BOARD_READY)
514 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_cflag);
516 static DEVICE_ATTR(cflag, S_IRUSR, dgnc_tty_cflag_show, NULL);
519 static ssize_t dgnc_tty_oflag_show(struct device *d, struct device_attribute *attr, char *buf)
521 struct dgnc_board *bd;
522 struct channel_t *ch;
527 un = dev_get_drvdata(d);
528 if (!un || un->magic != DGNC_UNIT_MAGIC)
531 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
534 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
536 if (bd->state != BOARD_READY)
539 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_oflag);
541 static DEVICE_ATTR(oflag, S_IRUSR, dgnc_tty_oflag_show, NULL);
544 static ssize_t dgnc_tty_lflag_show(struct device *d, struct device_attribute *attr, char *buf)
546 struct dgnc_board *bd;
547 struct channel_t *ch;
552 un = dev_get_drvdata(d);
553 if (!un || un->magic != DGNC_UNIT_MAGIC)
556 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
559 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
561 if (bd->state != BOARD_READY)
564 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_lflag);
566 static DEVICE_ATTR(lflag, S_IRUSR, dgnc_tty_lflag_show, NULL);
569 static ssize_t dgnc_tty_digi_flag_show(struct device *d, struct device_attribute *attr, char *buf)
571 struct dgnc_board *bd;
572 struct channel_t *ch;
577 un = dev_get_drvdata(d);
578 if (!un || un->magic != DGNC_UNIT_MAGIC)
581 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
584 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
586 if (bd->state != BOARD_READY)
589 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_digi.digi_flags);
591 static DEVICE_ATTR(digi_flag, S_IRUSR, dgnc_tty_digi_flag_show, NULL);
594 static ssize_t dgnc_tty_rxcount_show(struct device *d, struct device_attribute *attr, char *buf)
596 struct dgnc_board *bd;
597 struct channel_t *ch;
602 un = dev_get_drvdata(d);
603 if (!un || un->magic != DGNC_UNIT_MAGIC)
606 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
609 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
611 if (bd->state != BOARD_READY)
614 return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_rxcount);
616 static DEVICE_ATTR(rxcount, S_IRUSR, dgnc_tty_rxcount_show, NULL);
619 static ssize_t dgnc_tty_txcount_show(struct device *d, struct device_attribute *attr, char *buf)
621 struct dgnc_board *bd;
622 struct channel_t *ch;
627 un = dev_get_drvdata(d);
628 if (!un || un->magic != DGNC_UNIT_MAGIC)
631 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
634 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
636 if (bd->state != BOARD_READY)
639 return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_txcount);
641 static DEVICE_ATTR(txcount, S_IRUSR, dgnc_tty_txcount_show, NULL);
644 static ssize_t dgnc_tty_name_show(struct device *d, struct device_attribute *attr, char *buf)
646 struct dgnc_board *bd;
647 struct channel_t *ch;
652 un = dev_get_drvdata(d);
653 if (!un || un->magic != DGNC_UNIT_MAGIC)
656 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
659 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
661 if (bd->state != BOARD_READY)
664 return snprintf(buf, PAGE_SIZE, "%sn%d%c\n",
665 (un->un_type == DGNC_PRINT) ? "pr" : "tty",
666 bd->boardnum + 1, 'a' + ch->ch_portnum);
668 static DEVICE_ATTR(custom_name, S_IRUSR, dgnc_tty_name_show, NULL);
671 static struct attribute *dgnc_sysfs_tty_entries[] = {
672 &dev_attr_state.attr,
674 &dev_attr_msignals.attr,
675 &dev_attr_iflag.attr,
676 &dev_attr_cflag.attr,
677 &dev_attr_oflag.attr,
678 &dev_attr_lflag.attr,
679 &dev_attr_digi_flag.attr,
680 &dev_attr_rxcount.attr,
681 &dev_attr_txcount.attr,
682 &dev_attr_custom_name.attr,
687 static struct attribute_group dgnc_tty_attribute_group = {
689 .attrs = dgnc_sysfs_tty_entries,
693 void dgnc_create_tty_sysfs(struct un_t *un, struct device *c)
697 ret = sysfs_create_group(&c->kobj, &dgnc_tty_attribute_group);
699 dev_err(c, "dgnc: failed to create sysfs tty device attributes.\n");
700 sysfs_remove_group(&c->kobj, &dgnc_tty_attribute_group);
704 dev_set_drvdata(c, un);
709 void dgnc_remove_tty_sysfs(struct device *c)
711 sysfs_remove_group(&c->kobj, &dgnc_tty_attribute_group);