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 "dgrp_common.h"
19 #include <linux/kernel.h>
20 #include <linux/module.h>
21 #include <linux/ctype.h>
22 #include <linux/string.h>
23 #include <linux/serial_reg.h>
24 #include <linux/pci.h>
25 #include <linux/kdev_t.h>
28 #define PORTSERVER_DIVIDEND 1843200
29 #define SERIAL_TYPE_NORMAL 1
30 #define SERIAL_TYPE_CALLOUT 2
31 #define SERIAL_TYPE_XPRINT 3
34 static struct class *dgrp_class;
35 static struct device *dgrp_class_nodes_dev;
36 static struct device *dgrp_class_global_settings_dev;
39 static ssize_t dgrp_class_version_show(struct class *class,
40 struct class_attribute *attr, char *buf)
42 return snprintf(buf, PAGE_SIZE, "%s\n", DIGI_VERSION);
44 static CLASS_ATTR(driver_version, 0400, dgrp_class_version_show, NULL);
47 static ssize_t dgrp_class_register_with_sysfs_show(struct device *c,
48 struct device_attribute *attr,
51 return snprintf(buf, PAGE_SIZE, "1\n");
53 static DEVICE_ATTR(register_with_sysfs, 0400,
54 dgrp_class_register_with_sysfs_show, NULL);
57 static ssize_t dgrp_class_pollrate_show(struct device *c,
58 struct device_attribute *attr,
61 return snprintf(buf, PAGE_SIZE, "%d\n", dgrp_poll_tick);
64 static ssize_t dgrp_class_pollrate_store(struct device *c,
65 struct device_attribute *attr,
66 const char *buf, size_t count)
68 sscanf(buf, "0x%x\n", &dgrp_poll_tick);
71 static DEVICE_ATTR(pollrate, 0600, dgrp_class_pollrate_show,
72 dgrp_class_pollrate_store);
74 static struct attribute *dgrp_sysfs_global_settings_entries[] = {
75 &dev_attr_pollrate.attr,
76 &dev_attr_register_with_sysfs.attr,
81 static struct attribute_group dgrp_global_settings_attribute_group = {
83 .attrs = dgrp_sysfs_global_settings_entries,
88 void dgrp_create_class_sysfs_files(void)
91 int max_majors = 1U << (32 - MINORBITS);
93 dgrp_class = class_create(THIS_MODULE, "digi_realport");
94 ret = class_create_file(dgrp_class, &class_attr_driver_version);
96 dgrp_class_global_settings_dev = device_create(dgrp_class, NULL,
97 MKDEV(0, max_majors + 1), NULL, "driver_settings");
99 ret = sysfs_create_group(&dgrp_class_global_settings_dev->kobj,
100 &dgrp_global_settings_attribute_group);
102 pr_alert("%s: failed to create sysfs global settings device attributes.\n",
104 sysfs_remove_group(&dgrp_class_global_settings_dev->kobj,
105 &dgrp_global_settings_attribute_group);
109 dgrp_class_nodes_dev = device_create(dgrp_class, NULL,
110 MKDEV(0, max_majors + 2), NULL, "nodes");
115 void dgrp_remove_class_sysfs_files(void)
117 struct nd_struct *nd;
118 int max_majors = 1U << (32 - MINORBITS);
120 list_for_each_entry(nd, &nd_struct_list, list)
121 dgrp_remove_node_class_sysfs_files(nd);
123 sysfs_remove_group(&dgrp_class_global_settings_dev->kobj,
124 &dgrp_global_settings_attribute_group);
126 class_remove_file(dgrp_class, &class_attr_driver_version);
128 device_destroy(dgrp_class, MKDEV(0, max_majors + 1));
129 device_destroy(dgrp_class, MKDEV(0, max_majors + 2));
130 class_destroy(dgrp_class);
133 static ssize_t dgrp_node_state_show(struct device *c,
134 struct device_attribute *attr, char *buf)
136 struct nd_struct *nd;
140 nd = (struct nd_struct *) dev_get_drvdata(c);
144 return snprintf(buf, PAGE_SIZE, "%s\n", ND_STATE_STR(nd->nd_state));
147 static DEVICE_ATTR(state, 0600, dgrp_node_state_show, NULL);
149 static ssize_t dgrp_node_description_show(struct device *c,
150 struct device_attribute *attr,
153 struct nd_struct *nd;
157 nd = (struct nd_struct *) dev_get_drvdata(c);
161 if (nd->nd_state == NS_READY)
162 return snprintf(buf, PAGE_SIZE, "%s\n", nd->nd_ps_desc);
165 static DEVICE_ATTR(description_info, 0600, dgrp_node_description_show, NULL);
167 static ssize_t dgrp_node_hw_version_show(struct device *c,
168 struct device_attribute *attr,
171 struct nd_struct *nd;
175 nd = (struct nd_struct *) dev_get_drvdata(c);
179 if (nd->nd_state == NS_READY)
180 return snprintf(buf, PAGE_SIZE, "%d.%d\n",
181 (nd->nd_hw_ver >> 8) & 0xff,
182 nd->nd_hw_ver & 0xff);
186 static DEVICE_ATTR(hw_version_info, 0600, dgrp_node_hw_version_show, NULL);
188 static ssize_t dgrp_node_hw_id_show(struct device *c,
189 struct device_attribute *attr, char *buf)
191 struct nd_struct *nd;
195 nd = (struct nd_struct *) dev_get_drvdata(c);
200 if (nd->nd_state == NS_READY)
201 return snprintf(buf, PAGE_SIZE, "%d\n", nd->nd_hw_id);
204 static DEVICE_ATTR(hw_id_info, 0600, dgrp_node_hw_id_show, NULL);
206 static ssize_t dgrp_node_sw_version_show(struct device *c,
207 struct device_attribute *attr,
210 struct nd_struct *nd;
215 nd = (struct nd_struct *) dev_get_drvdata(c);
219 if (nd->nd_state == NS_READY)
220 return snprintf(buf, PAGE_SIZE, "%d.%d\n",
221 (nd->nd_sw_ver >> 8) & 0xff,
222 nd->nd_sw_ver & 0xff);
226 static DEVICE_ATTR(sw_version_info, 0600, dgrp_node_sw_version_show, NULL);
229 static struct attribute *dgrp_sysfs_node_entries[] = {
230 &dev_attr_state.attr,
231 &dev_attr_description_info.attr,
232 &dev_attr_hw_version_info.attr,
233 &dev_attr_hw_id_info.attr,
234 &dev_attr_sw_version_info.attr,
239 static struct attribute_group dgrp_node_attribute_group = {
241 .attrs = dgrp_sysfs_node_entries,
245 void dgrp_create_node_class_sysfs_files(struct nd_struct *nd)
251 ID_TO_CHAR(nd->nd_ID, name);
253 sprintf(name, "node%ld", nd->nd_major);
255 nd->nd_class_dev = device_create(dgrp_class, dgrp_class_nodes_dev,
256 MKDEV(0, nd->nd_major), NULL, name);
258 ret = sysfs_create_group(&nd->nd_class_dev->kobj,
259 &dgrp_node_attribute_group);
262 pr_alert("%s: failed to create sysfs node device attributes.\n",
264 sysfs_remove_group(&nd->nd_class_dev->kobj,
265 &dgrp_node_attribute_group);
269 dev_set_drvdata(nd->nd_class_dev, nd);
274 void dgrp_remove_node_class_sysfs_files(struct nd_struct *nd)
276 if (nd->nd_class_dev) {
277 sysfs_remove_group(&nd->nd_class_dev->kobj,
278 &dgrp_node_attribute_group);
280 device_destroy(dgrp_class, MKDEV(0, nd->nd_major));
281 nd->nd_class_dev = NULL;
287 static ssize_t dgrp_tty_state_show(struct device *d,
288 struct device_attribute *attr, char *buf)
290 struct un_struct *un;
294 un = (struct un_struct *) dev_get_drvdata(d);
298 return snprintf(buf, PAGE_SIZE, "%s\n",
299 un->un_open_count ? "Open" : "Closed");
301 static DEVICE_ATTR(state_info, 0600, dgrp_tty_state_show, NULL);
303 static ssize_t dgrp_tty_baud_show(struct device *d,
304 struct device_attribute *attr, char *buf)
306 struct ch_struct *ch;
307 struct un_struct *un;
311 un = (struct un_struct *) dev_get_drvdata(d);
317 return snprintf(buf, PAGE_SIZE, "%d\n",
318 un->un_open_count ? (PORTSERVER_DIVIDEND / ch->ch_s_brate) : 0);
320 static DEVICE_ATTR(baud_info, 0400, dgrp_tty_baud_show, NULL);
323 static ssize_t dgrp_tty_msignals_show(struct device *d,
324 struct device_attribute *attr, char *buf)
326 struct ch_struct *ch;
327 struct un_struct *un;
331 un = (struct un_struct *) dev_get_drvdata(d);
338 if (ch->ch_open_count) {
339 return snprintf(buf, PAGE_SIZE, "%s %s %s %s %s %s\n",
340 (ch->ch_s_mlast & DM_RTS) ? "RTS" : "",
341 (ch->ch_s_mlast & DM_CTS) ? "CTS" : "",
342 (ch->ch_s_mlast & DM_DTR) ? "DTR" : "",
343 (ch->ch_s_mlast & DM_DSR) ? "DSR" : "",
344 (ch->ch_s_mlast & DM_CD) ? "DCD" : "",
345 (ch->ch_s_mlast & DM_RI) ? "RI" : "");
349 static DEVICE_ATTR(msignals_info, 0400, dgrp_tty_msignals_show, NULL);
352 static ssize_t dgrp_tty_iflag_show(struct device *d,
353 struct device_attribute *attr, char *buf)
355 struct ch_struct *ch;
356 struct un_struct *un;
360 un = (struct un_struct *) dev_get_drvdata(d);
366 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_s_iflag);
368 static DEVICE_ATTR(iflag_info, 0600, dgrp_tty_iflag_show, NULL);
371 static ssize_t dgrp_tty_cflag_show(struct device *d,
372 struct device_attribute *attr, char *buf)
374 struct ch_struct *ch;
375 struct un_struct *un;
379 un = (struct un_struct *) dev_get_drvdata(d);
385 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_s_cflag);
387 static DEVICE_ATTR(cflag_info, 0600, dgrp_tty_cflag_show, NULL);
390 static ssize_t dgrp_tty_oflag_show(struct device *d,
391 struct device_attribute *attr, char *buf)
393 struct ch_struct *ch;
394 struct un_struct *un;
398 un = (struct un_struct *) dev_get_drvdata(d);
404 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_s_oflag);
406 static DEVICE_ATTR(oflag_info, 0600, dgrp_tty_oflag_show, NULL);
409 static ssize_t dgrp_tty_digi_flag_show(struct device *d,
410 struct device_attribute *attr, char *buf)
412 struct ch_struct *ch;
413 struct un_struct *un;
417 un = (struct un_struct *) dev_get_drvdata(d);
423 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_digi.digi_flags);
425 static DEVICE_ATTR(digi_flag_info, 0600, dgrp_tty_digi_flag_show, NULL);
428 static ssize_t dgrp_tty_rxcount_show(struct device *d,
429 struct device_attribute *attr, char *buf)
431 struct ch_struct *ch;
432 struct un_struct *un;
436 un = (struct un_struct *) dev_get_drvdata(d);
442 return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_rxcount);
444 static DEVICE_ATTR(rxcount_info, 0600, dgrp_tty_rxcount_show, NULL);
447 static ssize_t dgrp_tty_txcount_show(struct device *d,
448 struct device_attribute *attr, char *buf)
450 struct ch_struct *ch;
451 struct un_struct *un;
455 un = (struct un_struct *) dev_get_drvdata(d);
461 return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_txcount);
463 static DEVICE_ATTR(txcount_info, 0600, dgrp_tty_txcount_show, NULL);
466 static ssize_t dgrp_tty_name_show(struct device *d,
467 struct device_attribute *attr, char *buf)
469 struct nd_struct *nd;
470 struct ch_struct *ch;
471 struct un_struct *un;
476 un = (struct un_struct *) dev_get_drvdata(d);
486 ID_TO_CHAR(nd->nd_ID, name);
488 return snprintf(buf, PAGE_SIZE, "%s%s%02d\n",
489 un->un_type == SERIAL_TYPE_XPRINT ? "pr" : "tty",
490 name, ch->ch_portnum);
492 static DEVICE_ATTR(custom_name, 0600, dgrp_tty_name_show, NULL);
495 static struct attribute *dgrp_sysfs_tty_entries[] = {
496 &dev_attr_state_info.attr,
497 &dev_attr_baud_info.attr,
498 &dev_attr_msignals_info.attr,
499 &dev_attr_iflag_info.attr,
500 &dev_attr_cflag_info.attr,
501 &dev_attr_oflag_info.attr,
502 &dev_attr_digi_flag_info.attr,
503 &dev_attr_rxcount_info.attr,
504 &dev_attr_txcount_info.attr,
505 &dev_attr_custom_name.attr,
510 static struct attribute_group dgrp_tty_attribute_group = {
512 .attrs = dgrp_sysfs_tty_entries,
516 void dgrp_create_tty_sysfs(struct un_struct *un, struct device *c)
520 ret = sysfs_create_group(&c->kobj, &dgrp_tty_attribute_group);
522 pr_alert("%s: failed to create sysfs tty device attributes.\n",
524 sysfs_remove_group(&c->kobj, &dgrp_tty_attribute_group);
528 dev_set_drvdata(c, un);
533 void dgrp_remove_tty_sysfs(struct device *c)
535 sysfs_remove_group(&c->kobj, &dgrp_tty_attribute_group);