123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704 |
- /*
- * Copyright 2004 Digi International (www.digi.com)
- * Scott H Kilau <Scott_Kilau at digi dot com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- */
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/ctype.h>
- #include <linux/string.h>
- #include <linux/serial_reg.h>
- #include <linux/device.h>
- #include <linux/pci.h>
- #include <linux/kdev_t.h>
- #include "dgnc_driver.h"
- #include "dgnc_mgmt.h"
- static ssize_t dgnc_driver_version_show(struct device_driver *ddp, char *buf)
- {
- return snprintf(buf, PAGE_SIZE, "%s\n", DG_PART);
- }
- static DRIVER_ATTR(version, S_IRUSR, dgnc_driver_version_show, NULL);
- static ssize_t dgnc_driver_boards_show(struct device_driver *ddp, char *buf)
- {
- return snprintf(buf, PAGE_SIZE, "%d\n", dgnc_NumBoards);
- }
- static DRIVER_ATTR(boards, S_IRUSR, dgnc_driver_boards_show, NULL);
- static ssize_t dgnc_driver_maxboards_show(struct device_driver *ddp, char *buf)
- {
- return snprintf(buf, PAGE_SIZE, "%d\n", MAXBOARDS);
- }
- static DRIVER_ATTR(maxboards, S_IRUSR, dgnc_driver_maxboards_show, NULL);
- static ssize_t dgnc_driver_pollrate_show(struct device_driver *ddp, char *buf)
- {
- return snprintf(buf, PAGE_SIZE, "%dms\n", dgnc_poll_tick);
- }
- static ssize_t dgnc_driver_pollrate_store(struct device_driver *ddp,
- const char *buf, size_t count)
- {
- unsigned long flags;
- int tick;
- int ret;
- ret = sscanf(buf, "%d\n", &tick);
- if (ret != 1)
- return -EINVAL;
- spin_lock_irqsave(&dgnc_poll_lock, flags);
- dgnc_poll_tick = tick;
- spin_unlock_irqrestore(&dgnc_poll_lock, flags);
- return count;
- }
- static DRIVER_ATTR(pollrate, (S_IRUSR | S_IWUSR), dgnc_driver_pollrate_show,
- dgnc_driver_pollrate_store);
- void dgnc_create_driver_sysfiles(struct pci_driver *dgnc_driver)
- {
- int rc = 0;
- struct device_driver *driverfs = &dgnc_driver->driver;
- rc |= driver_create_file(driverfs, &driver_attr_version);
- rc |= driver_create_file(driverfs, &driver_attr_boards);
- rc |= driver_create_file(driverfs, &driver_attr_maxboards);
- rc |= driver_create_file(driverfs, &driver_attr_pollrate);
- if (rc)
- pr_err("DGNC: sysfs driver_create_file failed!\n");
- }
- void dgnc_remove_driver_sysfiles(struct pci_driver *dgnc_driver)
- {
- struct device_driver *driverfs = &dgnc_driver->driver;
- driver_remove_file(driverfs, &driver_attr_version);
- driver_remove_file(driverfs, &driver_attr_boards);
- driver_remove_file(driverfs, &driver_attr_maxboards);
- driver_remove_file(driverfs, &driver_attr_pollrate);
- }
- #define DGNC_VERIFY_BOARD(p, bd) \
- do { \
- if (!p) \
- return 0; \
- \
- bd = dev_get_drvdata(p); \
- if (!bd || bd->magic != DGNC_BOARD_MAGIC) \
- return 0; \
- if (bd->state != BOARD_READY) \
- return 0; \
- } while (0)
- static ssize_t dgnc_vpd_show(struct device *p, struct device_attribute *attr,
- char *buf)
- {
- struct dgnc_board *bd;
- int count = 0;
- int i = 0;
- DGNC_VERIFY_BOARD(p, bd);
- count += sprintf(buf + count,
- "\n 0 1 2 3 4 5 6 7 8 9 A B C D E F");
- for (i = 0; i < 0x40 * 2; i++) {
- if (!(i % 16))
- count += sprintf(buf + count, "\n%04X ", i * 2);
- count += sprintf(buf + count, "%02X ", bd->vpd[i]);
- }
- count += sprintf(buf + count, "\n");
- return count;
- }
- static DEVICE_ATTR(vpd, S_IRUSR, dgnc_vpd_show, NULL);
- static ssize_t dgnc_serial_number_show(struct device *p,
- struct device_attribute *attr, char *buf)
- {
- struct dgnc_board *bd;
- int count = 0;
- DGNC_VERIFY_BOARD(p, bd);
- if (bd->serial_num[0] == '\0')
- count += sprintf(buf + count, "<UNKNOWN>\n");
- else
- count += sprintf(buf + count, "%s\n", bd->serial_num);
- return count;
- }
- static DEVICE_ATTR(serial_number, S_IRUSR, dgnc_serial_number_show, NULL);
- static ssize_t dgnc_ports_state_show(struct device *p,
- struct device_attribute *attr, char *buf)
- {
- struct dgnc_board *bd;
- int count = 0;
- int i = 0;
- DGNC_VERIFY_BOARD(p, bd);
- for (i = 0; i < bd->nasync; i++) {
- count += snprintf(buf + count, PAGE_SIZE - count,
- "%d %s\n", bd->channels[i]->ch_portnum,
- bd->channels[i]->ch_open_count ? "Open" : "Closed");
- }
- return count;
- }
- static DEVICE_ATTR(ports_state, S_IRUSR, dgnc_ports_state_show, NULL);
- static ssize_t dgnc_ports_baud_show(struct device *p,
- struct device_attribute *attr, char *buf)
- {
- struct dgnc_board *bd;
- int count = 0;
- int i = 0;
- DGNC_VERIFY_BOARD(p, bd);
- for (i = 0; i < bd->nasync; i++) {
- count += snprintf(buf + count, PAGE_SIZE - count,
- "%d %d\n", bd->channels[i]->ch_portnum,
- bd->channels[i]->ch_old_baud);
- }
- return count;
- }
- static DEVICE_ATTR(ports_baud, S_IRUSR, dgnc_ports_baud_show, NULL);
- static ssize_t dgnc_ports_msignals_show(struct device *p,
- struct device_attribute *attr,
- char *buf)
- {
- struct dgnc_board *bd;
- int count = 0;
- int i = 0;
- DGNC_VERIFY_BOARD(p, bd);
- for (i = 0; i < bd->nasync; i++) {
- if (bd->channels[i]->ch_open_count) {
- count += snprintf(buf + count, PAGE_SIZE - count,
- "%d %s %s %s %s %s %s\n",
- bd->channels[i]->ch_portnum,
- (bd->channels[i]->ch_mostat & UART_MCR_RTS) ? "RTS" : "",
- (bd->channels[i]->ch_mistat & UART_MSR_CTS) ? "CTS" : "",
- (bd->channels[i]->ch_mostat & UART_MCR_DTR) ? "DTR" : "",
- (bd->channels[i]->ch_mistat & UART_MSR_DSR) ? "DSR" : "",
- (bd->channels[i]->ch_mistat & UART_MSR_DCD) ? "DCD" : "",
- (bd->channels[i]->ch_mistat & UART_MSR_RI) ? "RI" : "");
- } else {
- count += snprintf(buf + count, PAGE_SIZE - count,
- "%d\n", bd->channels[i]->ch_portnum);
- }
- }
- return count;
- }
- static DEVICE_ATTR(ports_msignals, S_IRUSR, dgnc_ports_msignals_show, NULL);
- static ssize_t dgnc_ports_iflag_show(struct device *p,
- struct device_attribute *attr, char *buf)
- {
- struct dgnc_board *bd;
- int count = 0;
- int i = 0;
- DGNC_VERIFY_BOARD(p, bd);
- for (i = 0; i < bd->nasync; i++) {
- count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
- bd->channels[i]->ch_portnum,
- bd->channels[i]->ch_c_iflag);
- }
- return count;
- }
- static DEVICE_ATTR(ports_iflag, S_IRUSR, dgnc_ports_iflag_show, NULL);
- static ssize_t dgnc_ports_cflag_show(struct device *p,
- struct device_attribute *attr, char *buf)
- {
- struct dgnc_board *bd;
- int count = 0;
- int i = 0;
- DGNC_VERIFY_BOARD(p, bd);
- for (i = 0; i < bd->nasync; i++) {
- count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
- bd->channels[i]->ch_portnum,
- bd->channels[i]->ch_c_cflag);
- }
- return count;
- }
- static DEVICE_ATTR(ports_cflag, S_IRUSR, dgnc_ports_cflag_show, NULL);
- static ssize_t dgnc_ports_oflag_show(struct device *p,
- struct device_attribute *attr, char *buf)
- {
- struct dgnc_board *bd;
- int count = 0;
- int i = 0;
- DGNC_VERIFY_BOARD(p, bd);
- for (i = 0; i < bd->nasync; i++) {
- count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
- bd->channels[i]->ch_portnum,
- bd->channels[i]->ch_c_oflag);
- }
- return count;
- }
- static DEVICE_ATTR(ports_oflag, S_IRUSR, dgnc_ports_oflag_show, NULL);
- static ssize_t dgnc_ports_lflag_show(struct device *p,
- struct device_attribute *attr, char *buf)
- {
- struct dgnc_board *bd;
- int count = 0;
- int i = 0;
- DGNC_VERIFY_BOARD(p, bd);
- for (i = 0; i < bd->nasync; i++) {
- count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
- bd->channels[i]->ch_portnum,
- bd->channels[i]->ch_c_lflag);
- }
- return count;
- }
- static DEVICE_ATTR(ports_lflag, S_IRUSR, dgnc_ports_lflag_show, NULL);
- static ssize_t dgnc_ports_digi_flag_show(struct device *p,
- struct device_attribute *attr,
- char *buf)
- {
- struct dgnc_board *bd;
- int count = 0;
- int i = 0;
- DGNC_VERIFY_BOARD(p, bd);
- for (i = 0; i < bd->nasync; i++) {
- count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
- bd->channels[i]->ch_portnum,
- bd->channels[i]->ch_digi.digi_flags);
- }
- return count;
- }
- static DEVICE_ATTR(ports_digi_flag, S_IRUSR, dgnc_ports_digi_flag_show, NULL);
- static ssize_t dgnc_ports_rxcount_show(struct device *p,
- struct device_attribute *attr, char *buf)
- {
- struct dgnc_board *bd;
- int count = 0;
- int i = 0;
- DGNC_VERIFY_BOARD(p, bd);
- for (i = 0; i < bd->nasync; i++) {
- count += snprintf(buf + count, PAGE_SIZE - count, "%d %ld\n",
- bd->channels[i]->ch_portnum,
- bd->channels[i]->ch_rxcount);
- }
- return count;
- }
- static DEVICE_ATTR(ports_rxcount, S_IRUSR, dgnc_ports_rxcount_show, NULL);
- static ssize_t dgnc_ports_txcount_show(struct device *p,
- struct device_attribute *attr, char *buf)
- {
- struct dgnc_board *bd;
- int count = 0;
- int i = 0;
- DGNC_VERIFY_BOARD(p, bd);
- for (i = 0; i < bd->nasync; i++) {
- count += snprintf(buf + count, PAGE_SIZE - count, "%d %ld\n",
- bd->channels[i]->ch_portnum,
- bd->channels[i]->ch_txcount);
- }
- return count;
- }
- static DEVICE_ATTR(ports_txcount, S_IRUSR, dgnc_ports_txcount_show, NULL);
- /* this function creates the sys files that will export each signal status
- * to sysfs each value will be put in a separate filename
- */
- void dgnc_create_ports_sysfiles(struct dgnc_board *bd)
- {
- int rc = 0;
- dev_set_drvdata(&bd->pdev->dev, bd);
- rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_state);
- rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_baud);
- rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_msignals);
- rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_iflag);
- rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_cflag);
- rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_oflag);
- rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_lflag);
- rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_digi_flag);
- rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_rxcount);
- rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_txcount);
- rc |= device_create_file(&bd->pdev->dev, &dev_attr_vpd);
- rc |= device_create_file(&bd->pdev->dev, &dev_attr_serial_number);
- if (rc)
- dev_err(&bd->pdev->dev, "dgnc: sysfs device_create_file failed!\n");
- }
- /* removes all the sys files created for that port */
- void dgnc_remove_ports_sysfiles(struct dgnc_board *bd)
- {
- device_remove_file(&bd->pdev->dev, &dev_attr_ports_state);
- device_remove_file(&bd->pdev->dev, &dev_attr_ports_baud);
- device_remove_file(&bd->pdev->dev, &dev_attr_ports_msignals);
- device_remove_file(&bd->pdev->dev, &dev_attr_ports_iflag);
- device_remove_file(&bd->pdev->dev, &dev_attr_ports_cflag);
- device_remove_file(&bd->pdev->dev, &dev_attr_ports_oflag);
- device_remove_file(&bd->pdev->dev, &dev_attr_ports_lflag);
- device_remove_file(&bd->pdev->dev, &dev_attr_ports_digi_flag);
- device_remove_file(&bd->pdev->dev, &dev_attr_ports_rxcount);
- device_remove_file(&bd->pdev->dev, &dev_attr_ports_txcount);
- device_remove_file(&bd->pdev->dev, &dev_attr_vpd);
- device_remove_file(&bd->pdev->dev, &dev_attr_serial_number);
- }
- static ssize_t dgnc_tty_state_show(struct device *d,
- struct device_attribute *attr, char *buf)
- {
- struct dgnc_board *bd;
- struct channel_t *ch;
- struct un_t *un;
- if (!d)
- return 0;
- un = dev_get_drvdata(d);
- if (!un || un->magic != DGNC_UNIT_MAGIC)
- return 0;
- ch = un->un_ch;
- if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
- return 0;
- bd = ch->ch_bd;
- if (!bd || bd->magic != DGNC_BOARD_MAGIC)
- return 0;
- if (bd->state != BOARD_READY)
- return 0;
- return snprintf(buf, PAGE_SIZE, "%s",
- un->un_open_count ? "Open" : "Closed");
- }
- static DEVICE_ATTR(state, S_IRUSR, dgnc_tty_state_show, NULL);
- static ssize_t dgnc_tty_baud_show(struct device *d,
- struct device_attribute *attr, char *buf)
- {
- struct dgnc_board *bd;
- struct channel_t *ch;
- struct un_t *un;
- if (!d)
- return 0;
- un = dev_get_drvdata(d);
- if (!un || un->magic != DGNC_UNIT_MAGIC)
- return 0;
- ch = un->un_ch;
- if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
- return 0;
- bd = ch->ch_bd;
- if (!bd || bd->magic != DGNC_BOARD_MAGIC)
- return 0;
- if (bd->state != BOARD_READY)
- return 0;
- return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_old_baud);
- }
- static DEVICE_ATTR(baud, S_IRUSR, dgnc_tty_baud_show, NULL);
- static ssize_t dgnc_tty_msignals_show(struct device *d,
- struct device_attribute *attr, char *buf)
- {
- struct dgnc_board *bd;
- struct channel_t *ch;
- struct un_t *un;
- if (!d)
- return 0;
- un = dev_get_drvdata(d);
- if (!un || un->magic != DGNC_UNIT_MAGIC)
- return 0;
- ch = un->un_ch;
- if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
- return 0;
- bd = ch->ch_bd;
- if (!bd || bd->magic != DGNC_BOARD_MAGIC)
- return 0;
- if (bd->state != BOARD_READY)
- return 0;
- if (ch->ch_open_count) {
- return snprintf(buf, PAGE_SIZE, "%s %s %s %s %s %s\n",
- (ch->ch_mostat & UART_MCR_RTS) ? "RTS" : "",
- (ch->ch_mistat & UART_MSR_CTS) ? "CTS" : "",
- (ch->ch_mostat & UART_MCR_DTR) ? "DTR" : "",
- (ch->ch_mistat & UART_MSR_DSR) ? "DSR" : "",
- (ch->ch_mistat & UART_MSR_DCD) ? "DCD" : "",
- (ch->ch_mistat & UART_MSR_RI) ? "RI" : "");
- }
- return 0;
- }
- static DEVICE_ATTR(msignals, S_IRUSR, dgnc_tty_msignals_show, NULL);
- static ssize_t dgnc_tty_iflag_show(struct device *d,
- struct device_attribute *attr, char *buf)
- {
- struct dgnc_board *bd;
- struct channel_t *ch;
- struct un_t *un;
- if (!d)
- return 0;
- un = dev_get_drvdata(d);
- if (!un || un->magic != DGNC_UNIT_MAGIC)
- return 0;
- ch = un->un_ch;
- if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
- return 0;
- bd = ch->ch_bd;
- if (!bd || bd->magic != DGNC_BOARD_MAGIC)
- return 0;
- if (bd->state != BOARD_READY)
- return 0;
- return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_iflag);
- }
- static DEVICE_ATTR(iflag, S_IRUSR, dgnc_tty_iflag_show, NULL);
- static ssize_t dgnc_tty_cflag_show(struct device *d,
- struct device_attribute *attr, char *buf)
- {
- struct dgnc_board *bd;
- struct channel_t *ch;
- struct un_t *un;
- if (!d)
- return 0;
- un = dev_get_drvdata(d);
- if (!un || un->magic != DGNC_UNIT_MAGIC)
- return 0;
- ch = un->un_ch;
- if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
- return 0;
- bd = ch->ch_bd;
- if (!bd || bd->magic != DGNC_BOARD_MAGIC)
- return 0;
- if (bd->state != BOARD_READY)
- return 0;
- return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_cflag);
- }
- static DEVICE_ATTR(cflag, S_IRUSR, dgnc_tty_cflag_show, NULL);
- static ssize_t dgnc_tty_oflag_show(struct device *d,
- struct device_attribute *attr, char *buf)
- {
- struct dgnc_board *bd;
- struct channel_t *ch;
- struct un_t *un;
- if (!d)
- return 0;
- un = dev_get_drvdata(d);
- if (!un || un->magic != DGNC_UNIT_MAGIC)
- return 0;
- ch = un->un_ch;
- if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
- return 0;
- bd = ch->ch_bd;
- if (!bd || bd->magic != DGNC_BOARD_MAGIC)
- return 0;
- if (bd->state != BOARD_READY)
- return 0;
- return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_oflag);
- }
- static DEVICE_ATTR(oflag, S_IRUSR, dgnc_tty_oflag_show, NULL);
- static ssize_t dgnc_tty_lflag_show(struct device *d,
- struct device_attribute *attr, char *buf)
- {
- struct dgnc_board *bd;
- struct channel_t *ch;
- struct un_t *un;
- if (!d)
- return 0;
- un = dev_get_drvdata(d);
- if (!un || un->magic != DGNC_UNIT_MAGIC)
- return 0;
- ch = un->un_ch;
- if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
- return 0;
- bd = ch->ch_bd;
- if (!bd || bd->magic != DGNC_BOARD_MAGIC)
- return 0;
- if (bd->state != BOARD_READY)
- return 0;
- return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_lflag);
- }
- static DEVICE_ATTR(lflag, S_IRUSR, dgnc_tty_lflag_show, NULL);
- static ssize_t dgnc_tty_digi_flag_show(struct device *d,
- struct device_attribute *attr, char *buf)
- {
- struct dgnc_board *bd;
- struct channel_t *ch;
- struct un_t *un;
- if (!d)
- return 0;
- un = dev_get_drvdata(d);
- if (!un || un->magic != DGNC_UNIT_MAGIC)
- return 0;
- ch = un->un_ch;
- if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
- return 0;
- bd = ch->ch_bd;
- if (!bd || bd->magic != DGNC_BOARD_MAGIC)
- return 0;
- if (bd->state != BOARD_READY)
- return 0;
- return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_digi.digi_flags);
- }
- static DEVICE_ATTR(digi_flag, S_IRUSR, dgnc_tty_digi_flag_show, NULL);
- static ssize_t dgnc_tty_rxcount_show(struct device *d,
- struct device_attribute *attr, char *buf)
- {
- struct dgnc_board *bd;
- struct channel_t *ch;
- struct un_t *un;
- if (!d)
- return 0;
- un = dev_get_drvdata(d);
- if (!un || un->magic != DGNC_UNIT_MAGIC)
- return 0;
- ch = un->un_ch;
- if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
- return 0;
- bd = ch->ch_bd;
- if (!bd || bd->magic != DGNC_BOARD_MAGIC)
- return 0;
- if (bd->state != BOARD_READY)
- return 0;
- return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_rxcount);
- }
- static DEVICE_ATTR(rxcount, S_IRUSR, dgnc_tty_rxcount_show, NULL);
- static ssize_t dgnc_tty_txcount_show(struct device *d,
- struct device_attribute *attr, char *buf)
- {
- struct dgnc_board *bd;
- struct channel_t *ch;
- struct un_t *un;
- if (!d)
- return 0;
- un = dev_get_drvdata(d);
- if (!un || un->magic != DGNC_UNIT_MAGIC)
- return 0;
- ch = un->un_ch;
- if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
- return 0;
- bd = ch->ch_bd;
- if (!bd || bd->magic != DGNC_BOARD_MAGIC)
- return 0;
- if (bd->state != BOARD_READY)
- return 0;
- return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_txcount);
- }
- static DEVICE_ATTR(txcount, S_IRUSR, dgnc_tty_txcount_show, NULL);
- static ssize_t dgnc_tty_name_show(struct device *d,
- struct device_attribute *attr, char *buf)
- {
- struct dgnc_board *bd;
- struct channel_t *ch;
- struct un_t *un;
- if (!d)
- return 0;
- un = dev_get_drvdata(d);
- if (!un || un->magic != DGNC_UNIT_MAGIC)
- return 0;
- ch = un->un_ch;
- if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
- return 0;
- bd = ch->ch_bd;
- if (!bd || bd->magic != DGNC_BOARD_MAGIC)
- return 0;
- if (bd->state != BOARD_READY)
- return 0;
- return snprintf(buf, PAGE_SIZE, "%sn%d%c\n",
- (un->un_type == DGNC_PRINT) ? "pr" : "tty",
- bd->boardnum + 1, 'a' + ch->ch_portnum);
- }
- static DEVICE_ATTR(custom_name, S_IRUSR, dgnc_tty_name_show, NULL);
- static struct attribute *dgnc_sysfs_tty_entries[] = {
- &dev_attr_state.attr,
- &dev_attr_baud.attr,
- &dev_attr_msignals.attr,
- &dev_attr_iflag.attr,
- &dev_attr_cflag.attr,
- &dev_attr_oflag.attr,
- &dev_attr_lflag.attr,
- &dev_attr_digi_flag.attr,
- &dev_attr_rxcount.attr,
- &dev_attr_txcount.attr,
- &dev_attr_custom_name.attr,
- NULL
- };
- static struct attribute_group dgnc_tty_attribute_group = {
- .name = NULL,
- .attrs = dgnc_sysfs_tty_entries,
- };
- void dgnc_create_tty_sysfs(struct un_t *un, struct device *c)
- {
- int ret;
- ret = sysfs_create_group(&c->kobj, &dgnc_tty_attribute_group);
- if (ret) {
- dev_err(c, "dgnc: failed to create sysfs tty device attributes.\n");
- sysfs_remove_group(&c->kobj, &dgnc_tty_attribute_group);
- return;
- }
- dev_set_drvdata(c, un);
- }
- void dgnc_remove_tty_sysfs(struct device *c)
- {
- sysfs_remove_group(&c->kobj, &dgnc_tty_attribute_group);
- }
|