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 dgnc_driver_version_show(struct device_driver *ddp, char *buf)
30 return snprintf(buf, PAGE_SIZE, "%s\n", DG_PART);
32 static DRIVER_ATTR(version, S_IRUSR, dgnc_driver_version_show, NULL);
34 static ssize_t dgnc_driver_boards_show(struct device_driver *ddp, char *buf)
36 return snprintf(buf, PAGE_SIZE, "%d\n", dgnc_NumBoards);
38 static DRIVER_ATTR(boards, S_IRUSR, dgnc_driver_boards_show, NULL);
40 static ssize_t dgnc_driver_maxboards_show(struct device_driver *ddp, char *buf)
42 return snprintf(buf, PAGE_SIZE, "%d\n", MAXBOARDS);
44 static DRIVER_ATTR(maxboards, S_IRUSR, dgnc_driver_maxboards_show, NULL);
46 static ssize_t dgnc_driver_pollrate_show(struct device_driver *ddp, char *buf)
48 return snprintf(buf, PAGE_SIZE, "%dms\n", dgnc_poll_tick);
51 static ssize_t dgnc_driver_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(pollrate, (S_IRUSR | S_IWUSR), dgnc_driver_pollrate_show,
69 dgnc_driver_pollrate_store);
71 void dgnc_create_driver_sysfiles(struct pci_driver *dgnc_driver)
74 struct device_driver *driverfs = &dgnc_driver->driver;
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);
81 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);
94 #define DGNC_VERIFY_BOARD(p, bd) \
99 bd = dev_get_drvdata(p); \
100 if (!bd || bd->magic != DGNC_BOARD_MAGIC) \
102 if (bd->state != BOARD_READY) \
106 static ssize_t dgnc_vpd_show(struct device *p, struct device_attribute *attr,
109 struct dgnc_board *bd;
113 DGNC_VERIFY_BOARD(p, bd);
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++) {
119 count += sprintf(buf + count, "\n%04X ", i * 2);
120 count += sprintf(buf + count, "%02X ", bd->vpd[i]);
122 count += sprintf(buf + count, "\n");
126 static DEVICE_ATTR(vpd, S_IRUSR, dgnc_vpd_show, NULL);
128 static ssize_t dgnc_serial_number_show(struct device *p,
129 struct device_attribute *attr, char *buf)
131 struct dgnc_board *bd;
134 DGNC_VERIFY_BOARD(p, bd);
136 if (bd->serial_num[0] == '\0')
137 count += sprintf(buf + count, "<UNKNOWN>\n");
139 count += sprintf(buf + count, "%s\n", bd->serial_num);
143 static DEVICE_ATTR(serial_number, S_IRUSR, dgnc_serial_number_show, NULL);
145 static ssize_t dgnc_ports_state_show(struct device *p,
146 struct device_attribute *attr, char *buf)
148 struct dgnc_board *bd;
152 DGNC_VERIFY_BOARD(p, bd);
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");
161 static DEVICE_ATTR(ports_state, S_IRUSR, dgnc_ports_state_show, NULL);
163 static ssize_t dgnc_ports_baud_show(struct device *p,
164 struct device_attribute *attr, char *buf)
166 struct dgnc_board *bd;
170 DGNC_VERIFY_BOARD(p, bd);
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);
179 static DEVICE_ATTR(ports_baud, S_IRUSR, dgnc_ports_baud_show, NULL);
181 static ssize_t dgnc_ports_msignals_show(struct device *p,
182 struct device_attribute *attr,
185 struct dgnc_board *bd;
189 DGNC_VERIFY_BOARD(p, bd);
191 for (i = 0; i < bd->nasync; i++) {
192 if (bd->channels[i]->ch_open_count) {
193 count += snprintf(buf + count, PAGE_SIZE - count,
194 "%d %s %s %s %s %s %s\n",
195 bd->channels[i]->ch_portnum,
196 (bd->channels[i]->ch_mostat & UART_MCR_RTS) ? "RTS" : "",
197 (bd->channels[i]->ch_mistat & UART_MSR_CTS) ? "CTS" : "",
198 (bd->channels[i]->ch_mostat & UART_MCR_DTR) ? "DTR" : "",
199 (bd->channels[i]->ch_mistat & UART_MSR_DSR) ? "DSR" : "",
200 (bd->channels[i]->ch_mistat & UART_MSR_DCD) ? "DCD" : "",
201 (bd->channels[i]->ch_mistat & UART_MSR_RI) ? "RI" : "");
203 count += snprintf(buf + count, PAGE_SIZE - count,
204 "%d\n", bd->channels[i]->ch_portnum);
209 static DEVICE_ATTR(ports_msignals, S_IRUSR, dgnc_ports_msignals_show, NULL);
211 static ssize_t dgnc_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(ports_iflag, S_IRUSR, dgnc_ports_iflag_show, NULL);
229 static ssize_t dgnc_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(ports_cflag, S_IRUSR, dgnc_ports_cflag_show, NULL);
247 static ssize_t dgnc_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(ports_oflag, S_IRUSR, dgnc_ports_oflag_show, NULL);
265 static ssize_t dgnc_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(ports_lflag, S_IRUSR, dgnc_ports_lflag_show, NULL);
283 static ssize_t dgnc_ports_digi_flag_show(struct device *p,
284 struct device_attribute *attr,
287 struct dgnc_board *bd;
291 DGNC_VERIFY_BOARD(p, bd);
293 for (i = 0; i < bd->nasync; i++) {
294 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
295 bd->channels[i]->ch_portnum,
296 bd->channels[i]->ch_digi.digi_flags);
300 static DEVICE_ATTR(ports_digi_flag, S_IRUSR, dgnc_ports_digi_flag_show, NULL);
302 static ssize_t dgnc_ports_rxcount_show(struct device *p,
303 struct device_attribute *attr, char *buf)
305 struct dgnc_board *bd;
309 DGNC_VERIFY_BOARD(p, bd);
311 for (i = 0; i < bd->nasync; i++) {
312 count += snprintf(buf + count, PAGE_SIZE - count, "%d %ld\n",
313 bd->channels[i]->ch_portnum,
314 bd->channels[i]->ch_rxcount);
318 static DEVICE_ATTR(ports_rxcount, S_IRUSR, dgnc_ports_rxcount_show, NULL);
320 static ssize_t dgnc_ports_txcount_show(struct device *p,
321 struct device_attribute *attr, char *buf)
323 struct dgnc_board *bd;
327 DGNC_VERIFY_BOARD(p, bd);
329 for (i = 0; i < bd->nasync; i++) {
330 count += snprintf(buf + count, PAGE_SIZE - count, "%d %ld\n",
331 bd->channels[i]->ch_portnum,
332 bd->channels[i]->ch_txcount);
336 static DEVICE_ATTR(ports_txcount, S_IRUSR, dgnc_ports_txcount_show, NULL);
338 /* this function creates the sys files that will export each signal status
339 * to sysfs each value will be put in a separate filename
341 void dgnc_create_ports_sysfiles(struct dgnc_board *bd)
345 dev_set_drvdata(&bd->pdev->dev, bd);
346 rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_state);
347 rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_baud);
348 rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_msignals);
349 rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_iflag);
350 rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_cflag);
351 rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_oflag);
352 rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_lflag);
353 rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_digi_flag);
354 rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_rxcount);
355 rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_txcount);
356 rc |= device_create_file(&bd->pdev->dev, &dev_attr_vpd);
357 rc |= device_create_file(&bd->pdev->dev, &dev_attr_serial_number);
359 dev_err(&bd->pdev->dev, "dgnc: sysfs device_create_file failed!\n");
362 /* removes all the sys files created for that port */
363 void dgnc_remove_ports_sysfiles(struct dgnc_board *bd)
365 device_remove_file(&bd->pdev->dev, &dev_attr_ports_state);
366 device_remove_file(&bd->pdev->dev, &dev_attr_ports_baud);
367 device_remove_file(&bd->pdev->dev, &dev_attr_ports_msignals);
368 device_remove_file(&bd->pdev->dev, &dev_attr_ports_iflag);
369 device_remove_file(&bd->pdev->dev, &dev_attr_ports_cflag);
370 device_remove_file(&bd->pdev->dev, &dev_attr_ports_oflag);
371 device_remove_file(&bd->pdev->dev, &dev_attr_ports_lflag);
372 device_remove_file(&bd->pdev->dev, &dev_attr_ports_digi_flag);
373 device_remove_file(&bd->pdev->dev, &dev_attr_ports_rxcount);
374 device_remove_file(&bd->pdev->dev, &dev_attr_ports_txcount);
375 device_remove_file(&bd->pdev->dev, &dev_attr_vpd);
376 device_remove_file(&bd->pdev->dev, &dev_attr_serial_number);
379 static ssize_t dgnc_tty_state_show(struct device *d,
380 struct device_attribute *attr, char *buf)
382 struct dgnc_board *bd;
383 struct channel_t *ch;
388 un = dev_get_drvdata(d);
389 if (!un || un->magic != DGNC_UNIT_MAGIC)
392 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
395 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
397 if (bd->state != BOARD_READY)
400 return snprintf(buf, PAGE_SIZE, "%s",
401 un->un_open_count ? "Open" : "Closed");
403 static DEVICE_ATTR(state, S_IRUSR, dgnc_tty_state_show, NULL);
405 static ssize_t dgnc_tty_baud_show(struct device *d,
406 struct device_attribute *attr, char *buf)
408 struct dgnc_board *bd;
409 struct channel_t *ch;
414 un = dev_get_drvdata(d);
415 if (!un || un->magic != DGNC_UNIT_MAGIC)
418 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
421 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
423 if (bd->state != BOARD_READY)
426 return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_old_baud);
428 static DEVICE_ATTR(baud, S_IRUSR, dgnc_tty_baud_show, NULL);
430 static ssize_t dgnc_tty_msignals_show(struct device *d,
431 struct device_attribute *attr, char *buf)
433 struct dgnc_board *bd;
434 struct channel_t *ch;
439 un = dev_get_drvdata(d);
440 if (!un || un->magic != DGNC_UNIT_MAGIC)
443 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
446 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
448 if (bd->state != BOARD_READY)
451 if (ch->ch_open_count) {
452 return snprintf(buf, PAGE_SIZE, "%s %s %s %s %s %s\n",
453 (ch->ch_mostat & UART_MCR_RTS) ? "RTS" : "",
454 (ch->ch_mistat & UART_MSR_CTS) ? "CTS" : "",
455 (ch->ch_mostat & UART_MCR_DTR) ? "DTR" : "",
456 (ch->ch_mistat & UART_MSR_DSR) ? "DSR" : "",
457 (ch->ch_mistat & UART_MSR_DCD) ? "DCD" : "",
458 (ch->ch_mistat & UART_MSR_RI) ? "RI" : "");
462 static DEVICE_ATTR(msignals, S_IRUSR, dgnc_tty_msignals_show, NULL);
464 static ssize_t dgnc_tty_iflag_show(struct device *d,
465 struct device_attribute *attr, char *buf)
467 struct dgnc_board *bd;
468 struct channel_t *ch;
473 un = dev_get_drvdata(d);
474 if (!un || un->magic != DGNC_UNIT_MAGIC)
477 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
480 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
482 if (bd->state != BOARD_READY)
485 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_iflag);
487 static DEVICE_ATTR(iflag, S_IRUSR, dgnc_tty_iflag_show, NULL);
489 static ssize_t dgnc_tty_cflag_show(struct device *d,
490 struct device_attribute *attr, char *buf)
492 struct dgnc_board *bd;
493 struct channel_t *ch;
498 un = dev_get_drvdata(d);
499 if (!un || un->magic != DGNC_UNIT_MAGIC)
502 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
505 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
507 if (bd->state != BOARD_READY)
510 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_cflag);
512 static DEVICE_ATTR(cflag, S_IRUSR, dgnc_tty_cflag_show, NULL);
514 static ssize_t dgnc_tty_oflag_show(struct device *d,
515 struct device_attribute *attr, char *buf)
517 struct dgnc_board *bd;
518 struct channel_t *ch;
523 un = dev_get_drvdata(d);
524 if (!un || un->magic != DGNC_UNIT_MAGIC)
527 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
530 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
532 if (bd->state != BOARD_READY)
535 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_oflag);
537 static DEVICE_ATTR(oflag, S_IRUSR, dgnc_tty_oflag_show, NULL);
539 static ssize_t dgnc_tty_lflag_show(struct device *d,
540 struct device_attribute *attr, char *buf)
542 struct dgnc_board *bd;
543 struct channel_t *ch;
548 un = dev_get_drvdata(d);
549 if (!un || un->magic != DGNC_UNIT_MAGIC)
552 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
555 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
557 if (bd->state != BOARD_READY)
560 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_lflag);
562 static DEVICE_ATTR(lflag, S_IRUSR, dgnc_tty_lflag_show, NULL);
564 static ssize_t dgnc_tty_digi_flag_show(struct device *d,
565 struct device_attribute *attr, char *buf)
567 struct dgnc_board *bd;
568 struct channel_t *ch;
573 un = dev_get_drvdata(d);
574 if (!un || un->magic != DGNC_UNIT_MAGIC)
577 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
580 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
582 if (bd->state != BOARD_READY)
585 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_digi.digi_flags);
587 static DEVICE_ATTR(digi_flag, S_IRUSR, dgnc_tty_digi_flag_show, NULL);
589 static ssize_t dgnc_tty_rxcount_show(struct device *d,
590 struct device_attribute *attr, char *buf)
592 struct dgnc_board *bd;
593 struct channel_t *ch;
598 un = dev_get_drvdata(d);
599 if (!un || un->magic != DGNC_UNIT_MAGIC)
602 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
605 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
607 if (bd->state != BOARD_READY)
610 return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_rxcount);
612 static DEVICE_ATTR(rxcount, S_IRUSR, dgnc_tty_rxcount_show, NULL);
614 static ssize_t dgnc_tty_txcount_show(struct device *d,
615 struct device_attribute *attr, char *buf)
617 struct dgnc_board *bd;
618 struct channel_t *ch;
623 un = dev_get_drvdata(d);
624 if (!un || un->magic != DGNC_UNIT_MAGIC)
627 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
630 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
632 if (bd->state != BOARD_READY)
635 return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_txcount);
637 static DEVICE_ATTR(txcount, S_IRUSR, dgnc_tty_txcount_show, NULL);
639 static ssize_t dgnc_tty_name_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, "%sn%d%c\n",
661 (un->un_type == DGNC_PRINT) ? "pr" : "tty",
662 bd->boardnum + 1, 'a' + ch->ch_portnum);
664 static DEVICE_ATTR(custom_name, S_IRUSR, dgnc_tty_name_show, NULL);
666 static struct attribute *dgnc_sysfs_tty_entries[] = {
667 &dev_attr_state.attr,
669 &dev_attr_msignals.attr,
670 &dev_attr_iflag.attr,
671 &dev_attr_cflag.attr,
672 &dev_attr_oflag.attr,
673 &dev_attr_lflag.attr,
674 &dev_attr_digi_flag.attr,
675 &dev_attr_rxcount.attr,
676 &dev_attr_txcount.attr,
677 &dev_attr_custom_name.attr,
681 static struct attribute_group dgnc_tty_attribute_group = {
683 .attrs = dgnc_sysfs_tty_entries,
686 void dgnc_create_tty_sysfs(struct un_t *un, struct device *c)
690 ret = sysfs_create_group(&c->kobj, &dgnc_tty_attribute_group);
692 dev_err(c, "dgnc: failed to create sysfs tty device attributes.\n");
693 sysfs_remove_group(&c->kobj, &dgnc_tty_attribute_group);
697 dev_set_drvdata(c, un);
700 void dgnc_remove_tty_sysfs(struct device *c)
702 sysfs_remove_group(&c->kobj, &dgnc_tty_attribute_group);