blob: b8d41c5617e264da33da9668264244edeca6f943 [file] [log] [blame]
Lidza Louina0b99d582013-08-01 17:00:20 -04001/*
2 * Copyright 2004 Digi International (www.digi.com)
3 * Scott H Kilau <Scott_Kilau at digi dot com>
Lidza Louina7a97deb2013-08-21 11:08:08 -04004 *
Lidza Louina0b99d582013-08-01 17:00:20 -04005 * 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)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
Lidza Louina7a97deb2013-08-21 11:08:08 -040012 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
Lidza Louina0b99d582013-08-01 17:00:20 -040013 * PURPOSE. See the GNU General Public License for more details.
Lidza Louina0b99d582013-08-01 17:00:20 -040014 */
15
Lidza Louina0b99d582013-08-01 17:00:20 -040016#include <linux/kernel.h>
Lidza Louina0b99d582013-08-01 17:00:20 -040017#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>
Lidza Louina7a97deb2013-08-21 11:08:08 -040024
Lidza Louina0b99d582013-08-01 17:00:20 -040025#include "dgnc_driver.h"
Lidza Louina0b99d582013-08-01 17:00:20 -040026#include "dgnc_mgmt.h"
27
Lidza Louina0b99d582013-08-01 17:00:20 -040028static ssize_t dgnc_driver_version_show(struct device_driver *ddp, char *buf)
29{
30 return snprintf(buf, PAGE_SIZE, "%s\n", DG_PART);
31}
32static DRIVER_ATTR(version, S_IRUSR, dgnc_driver_version_show, NULL);
33
Lidza Louina0b99d582013-08-01 17:00:20 -040034static ssize_t dgnc_driver_boards_show(struct device_driver *ddp, char *buf)
35{
Daeseok Youn80e3e242016-03-23 20:54:36 +090036 return snprintf(buf, PAGE_SIZE, "%d\n", dgnc_num_boards);
Lidza Louina0b99d582013-08-01 17:00:20 -040037}
38static DRIVER_ATTR(boards, S_IRUSR, dgnc_driver_boards_show, NULL);
39
Lidza Louina0b99d582013-08-01 17:00:20 -040040static ssize_t dgnc_driver_maxboards_show(struct device_driver *ddp, char *buf)
41{
42 return snprintf(buf, PAGE_SIZE, "%d\n", MAXBOARDS);
43}
44static DRIVER_ATTR(maxboards, S_IRUSR, dgnc_driver_maxboards_show, NULL);
45
Lidza Louina0b99d582013-08-01 17:00:20 -040046static ssize_t dgnc_driver_pollrate_show(struct device_driver *ddp, char *buf)
47{
48 return snprintf(buf, PAGE_SIZE, "%dms\n", dgnc_poll_tick);
49}
50
Wim de With8ad524f2015-05-20 14:27:39 +020051static ssize_t dgnc_driver_pollrate_store(struct device_driver *ddp,
52 const char *buf, size_t count)
Lidza Louina0b99d582013-08-01 17:00:20 -040053{
Salah Triki51abf45c2015-10-04 02:49:48 +010054 unsigned long flags;
55 int tick;
Roberta Dobrescufb33aa42014-09-20 00:01:39 +030056 int ret;
57
Salah Triki51abf45c2015-10-04 02:49:48 +010058 ret = sscanf(buf, "%d\n", &tick);
Roberta Dobrescufb33aa42014-09-20 00:01:39 +030059 if (ret != 1)
60 return -EINVAL;
Salah Triki51abf45c2015-10-04 02:49:48 +010061
62 spin_lock_irqsave(&dgnc_poll_lock, flags);
63 dgnc_poll_tick = tick;
64 spin_unlock_irqrestore(&dgnc_poll_lock, flags);
65
Lidza Louina0b99d582013-08-01 17:00:20 -040066 return count;
67}
Wim de With8ad524f2015-05-20 14:27:39 +020068static DRIVER_ATTR(pollrate, (S_IRUSR | S_IWUSR), dgnc_driver_pollrate_show,
69 dgnc_driver_pollrate_store);
Lidza Louina0b99d582013-08-01 17:00:20 -040070
Lidza Louina0b99d582013-08-01 17:00:20 -040071void dgnc_create_driver_sysfiles(struct pci_driver *dgnc_driver)
72{
73 int rc = 0;
74 struct device_driver *driverfs = &dgnc_driver->driver;
75
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);
Lidza Louina0b99d582013-08-01 17:00:20 -040079 rc |= driver_create_file(driverfs, &driver_attr_pollrate);
Gulsah Kose77b55d82014-09-21 22:56:15 +030080 if (rc)
Ioana Ciorneic471c982015-03-31 02:29:35 +030081 pr_err("DGNC: sysfs driver_create_file failed!\n");
Lidza Louina0b99d582013-08-01 17:00:20 -040082}
83
Lidza Louina0b99d582013-08-01 17:00:20 -040084void dgnc_remove_driver_sysfiles(struct pci_driver *dgnc_driver)
85{
86 struct device_driver *driverfs = &dgnc_driver->driver;
Gulsah Kosee8756d42014-09-20 19:31:15 +030087
Lidza Louina0b99d582013-08-01 17:00:20 -040088 driver_remove_file(driverfs, &driver_attr_version);
89 driver_remove_file(driverfs, &driver_attr_boards);
90 driver_remove_file(driverfs, &driver_attr_maxboards);
Lidza Louina0b99d582013-08-01 17:00:20 -040091 driver_remove_file(driverfs, &driver_attr_pollrate);
Lidza Louina0b99d582013-08-01 17:00:20 -040092}
93
Jeremiah Mahler635c4ef2014-07-12 18:26:39 -070094#define DGNC_VERIFY_BOARD(p, bd) \
95 do { \
96 if (!p) \
97 return 0; \
98 \
99 bd = dev_get_drvdata(p); \
100 if (!bd || bd->magic != DGNC_BOARD_MAGIC) \
101 return 0; \
102 if (bd->state != BOARD_READY) \
103 return 0; \
104 } while (0)
Lidza Louina0b99d582013-08-01 17:00:20 -0400105
Wim de With8ad524f2015-05-20 14:27:39 +0200106static ssize_t dgnc_vpd_show(struct device *p, struct device_attribute *attr,
107 char *buf)
Lidza Louina0b99d582013-08-01 17:00:20 -0400108{
Lidza Louina03425f52013-09-09 15:01:22 -0400109 struct dgnc_board *bd;
Lidza Louina0b99d582013-08-01 17:00:20 -0400110 int count = 0;
111 int i = 0;
112
113 DGNC_VERIFY_BOARD(p, bd);
114
Wim de With8ad524f2015-05-20 14:27:39 +0200115 count += sprintf(buf + count,
116 "\n 0 1 2 3 4 5 6 7 8 9 A B C D E F");
Lidza Louina0b99d582013-08-01 17:00:20 -0400117 for (i = 0; i < 0x40 * 2; i++) {
118 if (!(i % 16))
119 count += sprintf(buf + count, "\n%04X ", i * 2);
120 count += sprintf(buf + count, "%02X ", bd->vpd[i]);
121 }
122 count += sprintf(buf + count, "\n");
123
124 return count;
125}
126static DEVICE_ATTR(vpd, S_IRUSR, dgnc_vpd_show, NULL);
127
Wim de With8ad524f2015-05-20 14:27:39 +0200128static ssize_t dgnc_serial_number_show(struct device *p,
129 struct device_attribute *attr, char *buf)
Lidza Louina0b99d582013-08-01 17:00:20 -0400130{
Lidza Louina03425f52013-09-09 15:01:22 -0400131 struct dgnc_board *bd;
Lidza Louina0b99d582013-08-01 17:00:20 -0400132 int count = 0;
133
134 DGNC_VERIFY_BOARD(p, bd);
135
136 if (bd->serial_num[0] == '\0')
137 count += sprintf(buf + count, "<UNKNOWN>\n");
138 else
139 count += sprintf(buf + count, "%s\n", bd->serial_num);
140
141 return count;
142}
143static DEVICE_ATTR(serial_number, S_IRUSR, dgnc_serial_number_show, NULL);
144
Wim de With8ad524f2015-05-20 14:27:39 +0200145static ssize_t dgnc_ports_state_show(struct device *p,
146 struct device_attribute *attr, char *buf)
Lidza Louina0b99d582013-08-01 17:00:20 -0400147{
Lidza Louina03425f52013-09-09 15:01:22 -0400148 struct dgnc_board *bd;
Lidza Louina0b99d582013-08-01 17:00:20 -0400149 int count = 0;
150 int i = 0;
151
152 DGNC_VERIFY_BOARD(p, bd);
153
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");
158 }
159 return count;
160}
161static DEVICE_ATTR(ports_state, S_IRUSR, dgnc_ports_state_show, NULL);
162
Wim de With8ad524f2015-05-20 14:27:39 +0200163static ssize_t dgnc_ports_baud_show(struct device *p,
164 struct device_attribute *attr, char *buf)
Lidza Louina0b99d582013-08-01 17:00:20 -0400165{
Lidza Louina03425f52013-09-09 15:01:22 -0400166 struct dgnc_board *bd;
Lidza Louina0b99d582013-08-01 17:00:20 -0400167 int count = 0;
168 int i = 0;
169
170 DGNC_VERIFY_BOARD(p, bd);
171
172 for (i = 0; i < bd->nasync; i++) {
173 count += snprintf(buf + count, PAGE_SIZE - count,
Wim de With8ad524f2015-05-20 14:27:39 +0200174 "%d %d\n", bd->channels[i]->ch_portnum,
175 bd->channels[i]->ch_old_baud);
Lidza Louina0b99d582013-08-01 17:00:20 -0400176 }
177 return count;
178}
179static DEVICE_ATTR(ports_baud, S_IRUSR, dgnc_ports_baud_show, NULL);
180
Wim de With8ad524f2015-05-20 14:27:39 +0200181static ssize_t dgnc_ports_msignals_show(struct device *p,
182 struct device_attribute *attr,
183 char *buf)
Lidza Louina0b99d582013-08-01 17:00:20 -0400184{
Lidza Louina03425f52013-09-09 15:01:22 -0400185 struct dgnc_board *bd;
Lidza Louina0b99d582013-08-01 17:00:20 -0400186 int count = 0;
187 int i = 0;
188
189 DGNC_VERIFY_BOARD(p, bd);
190
191 for (i = 0; i < bd->nasync; i++) {
Daeseok Younedd19a22016-05-09 11:46:50 +0900192 struct channel_t *ch = bd->channels[i];
193
194 if (ch->ch_open_count) {
Lidza Louina0b99d582013-08-01 17:00:20 -0400195 count += snprintf(buf + count, PAGE_SIZE - count,
Wim de With8ad524f2015-05-20 14:27:39 +0200196 "%d %s %s %s %s %s %s\n",
Daeseok Younedd19a22016-05-09 11:46:50 +0900197 ch->ch_portnum,
198 (ch->ch_mostat & UART_MCR_RTS) ? "RTS" : "",
199 (ch->ch_mistat & UART_MSR_CTS) ? "CTS" : "",
200 (ch->ch_mostat & UART_MCR_DTR) ? "DTR" : "",
201 (ch->ch_mistat & UART_MSR_DSR) ? "DSR" : "",
202 (ch->ch_mistat & UART_MSR_DCD) ? "DCD" : "",
203 (ch->ch_mistat & UART_MSR_RI) ? "RI" : "");
Lidza Louina0b99d582013-08-01 17:00:20 -0400204 } else {
205 count += snprintf(buf + count, PAGE_SIZE - count,
Daeseok Younedd19a22016-05-09 11:46:50 +0900206 "%d\n", ch->ch_portnum);
Lidza Louina0b99d582013-08-01 17:00:20 -0400207 }
208 }
209 return count;
210}
211static DEVICE_ATTR(ports_msignals, S_IRUSR, dgnc_ports_msignals_show, NULL);
212
Wim de With8ad524f2015-05-20 14:27:39 +0200213static ssize_t dgnc_ports_iflag_show(struct device *p,
214 struct device_attribute *attr, char *buf)
Lidza Louina0b99d582013-08-01 17:00:20 -0400215{
Lidza Louina03425f52013-09-09 15:01:22 -0400216 struct dgnc_board *bd;
Lidza Louina0b99d582013-08-01 17:00:20 -0400217 int count = 0;
218 int i = 0;
219
220 DGNC_VERIFY_BOARD(p, bd);
221
222 for (i = 0; i < bd->nasync; i++) {
223 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
Wim de With8ad524f2015-05-20 14:27:39 +0200224 bd->channels[i]->ch_portnum,
225 bd->channels[i]->ch_c_iflag);
Lidza Louina0b99d582013-08-01 17:00:20 -0400226 }
227 return count;
228}
229static DEVICE_ATTR(ports_iflag, S_IRUSR, dgnc_ports_iflag_show, NULL);
230
Wim de With8ad524f2015-05-20 14:27:39 +0200231static ssize_t dgnc_ports_cflag_show(struct device *p,
232 struct device_attribute *attr, char *buf)
Lidza Louina0b99d582013-08-01 17:00:20 -0400233{
Lidza Louina03425f52013-09-09 15:01:22 -0400234 struct dgnc_board *bd;
Lidza Louina0b99d582013-08-01 17:00:20 -0400235 int count = 0;
236 int i = 0;
237
238 DGNC_VERIFY_BOARD(p, bd);
239
240 for (i = 0; i < bd->nasync; i++) {
241 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
Wim de With8ad524f2015-05-20 14:27:39 +0200242 bd->channels[i]->ch_portnum,
243 bd->channels[i]->ch_c_cflag);
Lidza Louina0b99d582013-08-01 17:00:20 -0400244 }
245 return count;
246}
247static DEVICE_ATTR(ports_cflag, S_IRUSR, dgnc_ports_cflag_show, NULL);
248
Wim de With8ad524f2015-05-20 14:27:39 +0200249static ssize_t dgnc_ports_oflag_show(struct device *p,
250 struct device_attribute *attr, char *buf)
Lidza Louina0b99d582013-08-01 17:00:20 -0400251{
Lidza Louina03425f52013-09-09 15:01:22 -0400252 struct dgnc_board *bd;
Lidza Louina0b99d582013-08-01 17:00:20 -0400253 int count = 0;
254 int i = 0;
255
256 DGNC_VERIFY_BOARD(p, bd);
257
258 for (i = 0; i < bd->nasync; i++) {
259 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
Wim de With8ad524f2015-05-20 14:27:39 +0200260 bd->channels[i]->ch_portnum,
261 bd->channels[i]->ch_c_oflag);
Lidza Louina0b99d582013-08-01 17:00:20 -0400262 }
263 return count;
264}
265static DEVICE_ATTR(ports_oflag, S_IRUSR, dgnc_ports_oflag_show, NULL);
266
Wim de With8ad524f2015-05-20 14:27:39 +0200267static ssize_t dgnc_ports_lflag_show(struct device *p,
268 struct device_attribute *attr, char *buf)
Lidza Louina0b99d582013-08-01 17:00:20 -0400269{
Lidza Louina03425f52013-09-09 15:01:22 -0400270 struct dgnc_board *bd;
Lidza Louina0b99d582013-08-01 17:00:20 -0400271 int count = 0;
272 int i = 0;
273
274 DGNC_VERIFY_BOARD(p, bd);
275
276 for (i = 0; i < bd->nasync; i++) {
277 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
Wim de With8ad524f2015-05-20 14:27:39 +0200278 bd->channels[i]->ch_portnum,
279 bd->channels[i]->ch_c_lflag);
Lidza Louina0b99d582013-08-01 17:00:20 -0400280 }
281 return count;
282}
283static DEVICE_ATTR(ports_lflag, S_IRUSR, dgnc_ports_lflag_show, NULL);
284
Wim de With8ad524f2015-05-20 14:27:39 +0200285static ssize_t dgnc_ports_digi_flag_show(struct device *p,
286 struct device_attribute *attr,
287 char *buf)
Lidza Louina0b99d582013-08-01 17:00:20 -0400288{
Lidza Louina03425f52013-09-09 15:01:22 -0400289 struct dgnc_board *bd;
Lidza Louina0b99d582013-08-01 17:00:20 -0400290 int count = 0;
291 int i = 0;
292
293 DGNC_VERIFY_BOARD(p, bd);
294
295 for (i = 0; i < bd->nasync; i++) {
296 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
Wim de With8ad524f2015-05-20 14:27:39 +0200297 bd->channels[i]->ch_portnum,
298 bd->channels[i]->ch_digi.digi_flags);
Lidza Louina0b99d582013-08-01 17:00:20 -0400299 }
300 return count;
301}
302static DEVICE_ATTR(ports_digi_flag, S_IRUSR, dgnc_ports_digi_flag_show, NULL);
303
Wim de With8ad524f2015-05-20 14:27:39 +0200304static ssize_t dgnc_ports_rxcount_show(struct device *p,
305 struct device_attribute *attr, char *buf)
Lidza Louina0b99d582013-08-01 17:00:20 -0400306{
Lidza Louina03425f52013-09-09 15:01:22 -0400307 struct dgnc_board *bd;
Lidza Louina0b99d582013-08-01 17:00:20 -0400308 int count = 0;
309 int i = 0;
310
311 DGNC_VERIFY_BOARD(p, bd);
312
313 for (i = 0; i < bd->nasync; i++) {
314 count += snprintf(buf + count, PAGE_SIZE - count, "%d %ld\n",
Wim de With8ad524f2015-05-20 14:27:39 +0200315 bd->channels[i]->ch_portnum,
316 bd->channels[i]->ch_rxcount);
Lidza Louina0b99d582013-08-01 17:00:20 -0400317 }
318 return count;
319}
320static DEVICE_ATTR(ports_rxcount, S_IRUSR, dgnc_ports_rxcount_show, NULL);
321
Wim de With8ad524f2015-05-20 14:27:39 +0200322static ssize_t dgnc_ports_txcount_show(struct device *p,
323 struct device_attribute *attr, char *buf)
Lidza Louina0b99d582013-08-01 17:00:20 -0400324{
Lidza Louina03425f52013-09-09 15:01:22 -0400325 struct dgnc_board *bd;
Lidza Louina0b99d582013-08-01 17:00:20 -0400326 int count = 0;
327 int i = 0;
328
329 DGNC_VERIFY_BOARD(p, bd);
330
331 for (i = 0; i < bd->nasync; i++) {
332 count += snprintf(buf + count, PAGE_SIZE - count, "%d %ld\n",
Wim de With8ad524f2015-05-20 14:27:39 +0200333 bd->channels[i]->ch_portnum,
334 bd->channels[i]->ch_txcount);
Lidza Louina0b99d582013-08-01 17:00:20 -0400335 }
336 return count;
337}
338static DEVICE_ATTR(ports_txcount, S_IRUSR, dgnc_ports_txcount_show, NULL);
339
Lidza Louina0b99d582013-08-01 17:00:20 -0400340/* this function creates the sys files that will export each signal status
341 * to sysfs each value will be put in a separate filename
342 */
Lidza Louina03425f52013-09-09 15:01:22 -0400343void dgnc_create_ports_sysfiles(struct dgnc_board *bd)
Lidza Louina0b99d582013-08-01 17:00:20 -0400344{
345 int rc = 0;
346
347 dev_set_drvdata(&bd->pdev->dev, bd);
Sudip Mukherjee7df227c2015-10-04 19:50:15 +0530348 rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_state);
349 rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_baud);
350 rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_msignals);
351 rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_iflag);
352 rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_cflag);
353 rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_oflag);
354 rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_lflag);
355 rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_digi_flag);
356 rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_rxcount);
357 rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_txcount);
358 rc |= device_create_file(&bd->pdev->dev, &dev_attr_vpd);
359 rc |= device_create_file(&bd->pdev->dev, &dev_attr_serial_number);
Gulsah Kose77b55d82014-09-21 22:56:15 +0300360 if (rc)
Cristina Opriceanac28645e2015-02-27 14:10:36 +0200361 dev_err(&bd->pdev->dev, "dgnc: sysfs device_create_file failed!\n");
Lidza Louina0b99d582013-08-01 17:00:20 -0400362}
363
Lidza Louina0b99d582013-08-01 17:00:20 -0400364/* removes all the sys files created for that port */
Lidza Louina03425f52013-09-09 15:01:22 -0400365void dgnc_remove_ports_sysfiles(struct dgnc_board *bd)
Lidza Louina0b99d582013-08-01 17:00:20 -0400366{
Sudip Mukherjee7df227c2015-10-04 19:50:15 +0530367 device_remove_file(&bd->pdev->dev, &dev_attr_ports_state);
368 device_remove_file(&bd->pdev->dev, &dev_attr_ports_baud);
369 device_remove_file(&bd->pdev->dev, &dev_attr_ports_msignals);
370 device_remove_file(&bd->pdev->dev, &dev_attr_ports_iflag);
371 device_remove_file(&bd->pdev->dev, &dev_attr_ports_cflag);
372 device_remove_file(&bd->pdev->dev, &dev_attr_ports_oflag);
373 device_remove_file(&bd->pdev->dev, &dev_attr_ports_lflag);
374 device_remove_file(&bd->pdev->dev, &dev_attr_ports_digi_flag);
375 device_remove_file(&bd->pdev->dev, &dev_attr_ports_rxcount);
376 device_remove_file(&bd->pdev->dev, &dev_attr_ports_txcount);
377 device_remove_file(&bd->pdev->dev, &dev_attr_vpd);
378 device_remove_file(&bd->pdev->dev, &dev_attr_serial_number);
Lidza Louina0b99d582013-08-01 17:00:20 -0400379}
380
Wim de With8ad524f2015-05-20 14:27:39 +0200381static ssize_t dgnc_tty_state_show(struct device *d,
382 struct device_attribute *attr, char *buf)
Lidza Louina0b99d582013-08-01 17:00:20 -0400383{
Lidza Louina03425f52013-09-09 15:01:22 -0400384 struct dgnc_board *bd;
Lidza Louina0b99d582013-08-01 17:00:20 -0400385 struct channel_t *ch;
386 struct un_t *un;
387
388 if (!d)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400389 return 0;
Jingoo Han0e4f66b2013-09-26 08:35:49 +0900390 un = dev_get_drvdata(d);
Lidza Louina0b99d582013-08-01 17:00:20 -0400391 if (!un || un->magic != DGNC_UNIT_MAGIC)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400392 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400393 ch = un->un_ch;
394 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400395 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400396 bd = ch->ch_bd;
397 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400398 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400399 if (bd->state != BOARD_READY)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400400 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400401
Wim de With8ad524f2015-05-20 14:27:39 +0200402 return snprintf(buf, PAGE_SIZE, "%s",
403 un->un_open_count ? "Open" : "Closed");
Lidza Louina0b99d582013-08-01 17:00:20 -0400404}
405static DEVICE_ATTR(state, S_IRUSR, dgnc_tty_state_show, NULL);
406
Wim de With8ad524f2015-05-20 14:27:39 +0200407static ssize_t dgnc_tty_baud_show(struct device *d,
408 struct device_attribute *attr, char *buf)
Lidza Louina0b99d582013-08-01 17:00:20 -0400409{
Lidza Louina03425f52013-09-09 15:01:22 -0400410 struct dgnc_board *bd;
Lidza Louina0b99d582013-08-01 17:00:20 -0400411 struct channel_t *ch;
412 struct un_t *un;
413
414 if (!d)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400415 return 0;
Jingoo Han0e4f66b2013-09-26 08:35:49 +0900416 un = dev_get_drvdata(d);
Lidza Louina0b99d582013-08-01 17:00:20 -0400417 if (!un || un->magic != DGNC_UNIT_MAGIC)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400418 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400419 ch = un->un_ch;
420 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400421 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400422 bd = ch->ch_bd;
423 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400424 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400425 if (bd->state != BOARD_READY)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400426 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400427
428 return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_old_baud);
429}
430static DEVICE_ATTR(baud, S_IRUSR, dgnc_tty_baud_show, NULL);
431
Wim de With8ad524f2015-05-20 14:27:39 +0200432static ssize_t dgnc_tty_msignals_show(struct device *d,
433 struct device_attribute *attr, char *buf)
Lidza Louina0b99d582013-08-01 17:00:20 -0400434{
Lidza Louina03425f52013-09-09 15:01:22 -0400435 struct dgnc_board *bd;
Lidza Louina0b99d582013-08-01 17:00:20 -0400436 struct channel_t *ch;
437 struct un_t *un;
438
439 if (!d)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400440 return 0;
Jingoo Han0e4f66b2013-09-26 08:35:49 +0900441 un = dev_get_drvdata(d);
Lidza Louina0b99d582013-08-01 17:00:20 -0400442 if (!un || un->magic != DGNC_UNIT_MAGIC)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400443 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400444 ch = un->un_ch;
445 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400446 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400447 bd = ch->ch_bd;
448 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400449 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400450 if (bd->state != BOARD_READY)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400451 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400452
453 if (ch->ch_open_count) {
454 return snprintf(buf, PAGE_SIZE, "%s %s %s %s %s %s\n",
455 (ch->ch_mostat & UART_MCR_RTS) ? "RTS" : "",
456 (ch->ch_mistat & UART_MSR_CTS) ? "CTS" : "",
457 (ch->ch_mostat & UART_MCR_DTR) ? "DTR" : "",
458 (ch->ch_mistat & UART_MSR_DSR) ? "DSR" : "",
459 (ch->ch_mistat & UART_MSR_DCD) ? "DCD" : "",
460 (ch->ch_mistat & UART_MSR_RI) ? "RI" : "");
461 }
462 return 0;
463}
464static DEVICE_ATTR(msignals, S_IRUSR, dgnc_tty_msignals_show, NULL);
465
Wim de With8ad524f2015-05-20 14:27:39 +0200466static ssize_t dgnc_tty_iflag_show(struct device *d,
467 struct device_attribute *attr, char *buf)
Lidza Louina0b99d582013-08-01 17:00:20 -0400468{
Lidza Louina03425f52013-09-09 15:01:22 -0400469 struct dgnc_board *bd;
Lidza Louina0b99d582013-08-01 17:00:20 -0400470 struct channel_t *ch;
471 struct un_t *un;
472
473 if (!d)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400474 return 0;
Jingoo Han0e4f66b2013-09-26 08:35:49 +0900475 un = dev_get_drvdata(d);
Lidza Louina0b99d582013-08-01 17:00:20 -0400476 if (!un || un->magic != DGNC_UNIT_MAGIC)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400477 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400478 ch = un->un_ch;
479 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400480 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400481 bd = ch->ch_bd;
482 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400483 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400484 if (bd->state != BOARD_READY)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400485 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400486
487 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_iflag);
488}
489static DEVICE_ATTR(iflag, S_IRUSR, dgnc_tty_iflag_show, NULL);
490
Wim de With8ad524f2015-05-20 14:27:39 +0200491static ssize_t dgnc_tty_cflag_show(struct device *d,
492 struct device_attribute *attr, char *buf)
Lidza Louina0b99d582013-08-01 17:00:20 -0400493{
Lidza Louina03425f52013-09-09 15:01:22 -0400494 struct dgnc_board *bd;
Lidza Louina0b99d582013-08-01 17:00:20 -0400495 struct channel_t *ch;
496 struct un_t *un;
497
498 if (!d)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400499 return 0;
Jingoo Han0e4f66b2013-09-26 08:35:49 +0900500 un = dev_get_drvdata(d);
Lidza Louina0b99d582013-08-01 17:00:20 -0400501 if (!un || un->magic != DGNC_UNIT_MAGIC)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400502 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400503 ch = un->un_ch;
504 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400505 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400506 bd = ch->ch_bd;
507 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400508 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400509 if (bd->state != BOARD_READY)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400510 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400511
512 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_cflag);
513}
514static DEVICE_ATTR(cflag, S_IRUSR, dgnc_tty_cflag_show, NULL);
515
Wim de With8ad524f2015-05-20 14:27:39 +0200516static ssize_t dgnc_tty_oflag_show(struct device *d,
517 struct device_attribute *attr, char *buf)
Lidza Louina0b99d582013-08-01 17:00:20 -0400518{
Lidza Louina03425f52013-09-09 15:01:22 -0400519 struct dgnc_board *bd;
Lidza Louina0b99d582013-08-01 17:00:20 -0400520 struct channel_t *ch;
521 struct un_t *un;
522
523 if (!d)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400524 return 0;
Jingoo Han0e4f66b2013-09-26 08:35:49 +0900525 un = dev_get_drvdata(d);
Lidza Louina0b99d582013-08-01 17:00:20 -0400526 if (!un || un->magic != DGNC_UNIT_MAGIC)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400527 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400528 ch = un->un_ch;
529 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400530 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400531 bd = ch->ch_bd;
532 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400533 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400534 if (bd->state != BOARD_READY)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400535 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400536
537 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_oflag);
538}
539static DEVICE_ATTR(oflag, S_IRUSR, dgnc_tty_oflag_show, NULL);
540
Wim de With8ad524f2015-05-20 14:27:39 +0200541static ssize_t dgnc_tty_lflag_show(struct device *d,
542 struct device_attribute *attr, char *buf)
Lidza Louina0b99d582013-08-01 17:00:20 -0400543{
Lidza Louina03425f52013-09-09 15:01:22 -0400544 struct dgnc_board *bd;
Lidza Louina0b99d582013-08-01 17:00:20 -0400545 struct channel_t *ch;
546 struct un_t *un;
547
548 if (!d)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400549 return 0;
Jingoo Han0e4f66b2013-09-26 08:35:49 +0900550 un = dev_get_drvdata(d);
Lidza Louina0b99d582013-08-01 17:00:20 -0400551 if (!un || un->magic != DGNC_UNIT_MAGIC)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400552 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400553 ch = un->un_ch;
554 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400555 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400556 bd = ch->ch_bd;
557 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400558 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400559 if (bd->state != BOARD_READY)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400560 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400561
562 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_lflag);
563}
564static DEVICE_ATTR(lflag, S_IRUSR, dgnc_tty_lflag_show, NULL);
565
Wim de With8ad524f2015-05-20 14:27:39 +0200566static ssize_t dgnc_tty_digi_flag_show(struct device *d,
567 struct device_attribute *attr, char *buf)
Lidza Louina0b99d582013-08-01 17:00:20 -0400568{
Lidza Louina03425f52013-09-09 15:01:22 -0400569 struct dgnc_board *bd;
Lidza Louina0b99d582013-08-01 17:00:20 -0400570 struct channel_t *ch;
571 struct un_t *un;
572
573 if (!d)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400574 return 0;
Jingoo Han0e4f66b2013-09-26 08:35:49 +0900575 un = dev_get_drvdata(d);
Lidza Louina0b99d582013-08-01 17:00:20 -0400576 if (!un || un->magic != DGNC_UNIT_MAGIC)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400577 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400578 ch = un->un_ch;
579 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400580 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400581 bd = ch->ch_bd;
582 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400583 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400584 if (bd->state != BOARD_READY)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400585 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400586
587 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_digi.digi_flags);
588}
589static DEVICE_ATTR(digi_flag, S_IRUSR, dgnc_tty_digi_flag_show, NULL);
590
Wim de With8ad524f2015-05-20 14:27:39 +0200591static ssize_t dgnc_tty_rxcount_show(struct device *d,
592 struct device_attribute *attr, char *buf)
Lidza Louina0b99d582013-08-01 17:00:20 -0400593{
Lidza Louina03425f52013-09-09 15:01:22 -0400594 struct dgnc_board *bd;
Lidza Louina0b99d582013-08-01 17:00:20 -0400595 struct channel_t *ch;
596 struct un_t *un;
597
598 if (!d)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400599 return 0;
Jingoo Han0e4f66b2013-09-26 08:35:49 +0900600 un = dev_get_drvdata(d);
Lidza Louina0b99d582013-08-01 17:00:20 -0400601 if (!un || un->magic != DGNC_UNIT_MAGIC)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400602 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400603 ch = un->un_ch;
604 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400605 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400606 bd = ch->ch_bd;
607 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400608 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400609 if (bd->state != BOARD_READY)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400610 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400611
612 return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_rxcount);
613}
614static DEVICE_ATTR(rxcount, S_IRUSR, dgnc_tty_rxcount_show, NULL);
615
Wim de With8ad524f2015-05-20 14:27:39 +0200616static ssize_t dgnc_tty_txcount_show(struct device *d,
617 struct device_attribute *attr, char *buf)
Lidza Louina0b99d582013-08-01 17:00:20 -0400618{
Lidza Louina03425f52013-09-09 15:01:22 -0400619 struct dgnc_board *bd;
Lidza Louina0b99d582013-08-01 17:00:20 -0400620 struct channel_t *ch;
621 struct un_t *un;
622
623 if (!d)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400624 return 0;
Jingoo Han0e4f66b2013-09-26 08:35:49 +0900625 un = dev_get_drvdata(d);
Lidza Louina0b99d582013-08-01 17:00:20 -0400626 if (!un || un->magic != DGNC_UNIT_MAGIC)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400627 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400628 ch = un->un_ch;
629 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400630 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400631 bd = ch->ch_bd;
632 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400633 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400634 if (bd->state != BOARD_READY)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400635 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400636
637 return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_txcount);
638}
639static DEVICE_ATTR(txcount, S_IRUSR, dgnc_tty_txcount_show, NULL);
640
Wim de With8ad524f2015-05-20 14:27:39 +0200641static ssize_t dgnc_tty_name_show(struct device *d,
642 struct device_attribute *attr, char *buf)
Lidza Louina0b99d582013-08-01 17:00:20 -0400643{
Lidza Louina03425f52013-09-09 15:01:22 -0400644 struct dgnc_board *bd;
Lidza Louina0b99d582013-08-01 17:00:20 -0400645 struct channel_t *ch;
646 struct un_t *un;
647
648 if (!d)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400649 return 0;
Jingoo Han0e4f66b2013-09-26 08:35:49 +0900650 un = dev_get_drvdata(d);
Lidza Louina0b99d582013-08-01 17:00:20 -0400651 if (!un || un->magic != DGNC_UNIT_MAGIC)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400652 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400653 ch = un->un_ch;
654 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400655 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400656 bd = ch->ch_bd;
657 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400658 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400659 if (bd->state != BOARD_READY)
Lidza Louina8f90ef82013-09-09 15:01:23 -0400660 return 0;
Lidza Louina0b99d582013-08-01 17:00:20 -0400661
662 return snprintf(buf, PAGE_SIZE, "%sn%d%c\n",
663 (un->un_type == DGNC_PRINT) ? "pr" : "tty",
664 bd->boardnum + 1, 'a' + ch->ch_portnum);
665}
666static DEVICE_ATTR(custom_name, S_IRUSR, dgnc_tty_name_show, NULL);
667
Lidza Louina0b99d582013-08-01 17:00:20 -0400668static struct attribute *dgnc_sysfs_tty_entries[] = {
669 &dev_attr_state.attr,
670 &dev_attr_baud.attr,
671 &dev_attr_msignals.attr,
672 &dev_attr_iflag.attr,
673 &dev_attr_cflag.attr,
Lidza Louina7a97deb2013-08-21 11:08:08 -0400674 &dev_attr_oflag.attr,
Lidza Louina0b99d582013-08-01 17:00:20 -0400675 &dev_attr_lflag.attr,
676 &dev_attr_digi_flag.attr,
677 &dev_attr_rxcount.attr,
678 &dev_attr_txcount.attr,
679 &dev_attr_custom_name.attr,
680 NULL
681};
682
Lidza Louina0b99d582013-08-01 17:00:20 -0400683static struct attribute_group dgnc_tty_attribute_group = {
Lidza Louina0a60eb32013-08-21 13:30:10 -0400684 .name = NULL,
685 .attrs = dgnc_sysfs_tty_entries,
Lidza Louina0b99d582013-08-01 17:00:20 -0400686};
687
Lidza Louina0b99d582013-08-01 17:00:20 -0400688void dgnc_create_tty_sysfs(struct un_t *un, struct device *c)
689{
690 int ret;
691
692 ret = sysfs_create_group(&c->kobj, &dgnc_tty_attribute_group);
693 if (ret) {
Martin Kepplinger0f33ae12014-04-29 11:43:08 +0200694 dev_err(c, "dgnc: failed to create sysfs tty device attributes.\n");
Lidza Louina0b99d582013-08-01 17:00:20 -0400695 sysfs_remove_group(&c->kobj, &dgnc_tty_attribute_group);
696 return;
697 }
698
699 dev_set_drvdata(c, un);
Lidza Louina0b99d582013-08-01 17:00:20 -0400700}
701
Lidza Louina0b99d582013-08-01 17:00:20 -0400702void dgnc_remove_tty_sysfs(struct device *c)
703{
704 sysfs_remove_group(&c->kobj, &dgnc_tty_attribute_group);
705}
706