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/version.h>
21 #include <linux/module.h>
22 #include <linux/ctype.h>
23 #include <linux/string.h>
24 #include <linux/serial_reg.h>
25 #include <linux/pci.h>
26 #include <linux/kdev_t.h>
29 #define PORTSERVER_DIVIDEND 1843200
30 #define SERIAL_TYPE_NORMAL 1
31 #define SERIAL_TYPE_CALLOUT 2
32 #define SERIAL_TYPE_XPRINT 3
35 static struct class *dgrp_class
;
36 static struct device
*dgrp_class_nodes_dev
;
37 static struct device
*dgrp_class_global_settings_dev
;
40 static ssize_t
dgrp_class_version_show(struct class *class,
41 struct class_attribute
*attr
, char *buf
)
43 return snprintf(buf
, PAGE_SIZE
, "%s\n", DIGI_VERSION
);
45 static CLASS_ATTR(driver_version
, 0400, dgrp_class_version_show
, NULL
);
48 static ssize_t
dgrp_class_register_with_sysfs_show(struct device
*c
,
49 struct device_attribute
*attr
,
52 return snprintf(buf
, PAGE_SIZE
, "1\n");
54 static DEVICE_ATTR(register_with_sysfs
, 0400,
55 dgrp_class_register_with_sysfs_show
, NULL
);
58 static ssize_t
dgrp_class_rawreadok_show(struct device
*c
,
59 struct device_attribute
*attr
,
62 return snprintf(buf
, PAGE_SIZE
, "%d\n", dgrp_rawreadok
);
64 static ssize_t
dgrp_class_rawreadok_store(struct device
*c
,
65 struct device_attribute
*attr
,
66 const char *buf
, size_t count
)
68 sscanf(buf
, "0x%x\n", &dgrp_rawreadok
);
71 static DEVICE_ATTR(rawreadok
, 0600, dgrp_class_rawreadok_show
,
72 dgrp_class_rawreadok_store
);
75 static ssize_t
dgrp_class_pollrate_show(struct device
*c
,
76 struct device_attribute
*attr
,
79 return snprintf(buf
, PAGE_SIZE
, "%d\n", dgrp_poll_tick
);
82 static ssize_t
dgrp_class_pollrate_store(struct device
*c
,
83 struct device_attribute
*attr
,
84 const char *buf
, size_t count
)
86 sscanf(buf
, "0x%x\n", &dgrp_poll_tick
);
89 static DEVICE_ATTR(pollrate
, 0600, dgrp_class_pollrate_show
,
90 dgrp_class_pollrate_store
);
92 static struct attribute
*dgrp_sysfs_global_settings_entries
[] = {
93 &dev_attr_pollrate
.attr
,
94 &dev_attr_rawreadok
.attr
,
95 &dev_attr_register_with_sysfs
.attr
,
100 static struct attribute_group dgrp_global_settings_attribute_group
= {
102 .attrs
= dgrp_sysfs_global_settings_entries
,
107 void dgrp_create_class_sysfs_files(void)
110 int max_majors
= 1U << (32 - MINORBITS
);
112 dgrp_class
= class_create(THIS_MODULE
, "digi_realport");
113 ret
= class_create_file(dgrp_class
, &class_attr_driver_version
);
115 dgrp_class_global_settings_dev
= device_create(dgrp_class
, NULL
,
116 MKDEV(0, max_majors
+ 1), NULL
, "driver_settings");
118 ret
= sysfs_create_group(&dgrp_class_global_settings_dev
->kobj
,
119 &dgrp_global_settings_attribute_group
);
121 pr_alert("%s: failed to create sysfs global settings device attributes.\n",
123 sysfs_remove_group(&dgrp_class_global_settings_dev
->kobj
,
124 &dgrp_global_settings_attribute_group
);
128 dgrp_class_nodes_dev
= device_create(dgrp_class
, NULL
,
129 MKDEV(0, max_majors
+ 2), NULL
, "nodes");
134 void dgrp_remove_class_sysfs_files(void)
136 struct nd_struct
*nd
;
137 int max_majors
= 1U << (32 - MINORBITS
);
139 list_for_each_entry(nd
, &nd_struct_list
, list
)
140 dgrp_remove_node_class_sysfs_files(nd
);
142 sysfs_remove_group(&dgrp_class_global_settings_dev
->kobj
,
143 &dgrp_global_settings_attribute_group
);
145 class_remove_file(dgrp_class
, &class_attr_driver_version
);
147 device_destroy(dgrp_class
, MKDEV(0, max_majors
+ 1));
148 device_destroy(dgrp_class
, MKDEV(0, max_majors
+ 2));
149 class_destroy(dgrp_class
);
152 static ssize_t
dgrp_node_state_show(struct device
*c
,
153 struct device_attribute
*attr
, char *buf
)
155 struct nd_struct
*nd
;
159 nd
= (struct nd_struct
*) dev_get_drvdata(c
);
163 return snprintf(buf
, PAGE_SIZE
, "%s\n", ND_STATE_STR(nd
->nd_state
));
166 static DEVICE_ATTR(state
, 0600, dgrp_node_state_show
, NULL
);
168 static ssize_t
dgrp_node_description_show(struct device
*c
,
169 struct device_attribute
*attr
,
172 struct nd_struct
*nd
;
176 nd
= (struct nd_struct
*) dev_get_drvdata(c
);
180 if (nd
->nd_state
== NS_READY
&& nd
->nd_ps_desc
)
181 return snprintf(buf
, PAGE_SIZE
, "%s\n", nd
->nd_ps_desc
);
184 static DEVICE_ATTR(description_info
, 0600, dgrp_node_description_show
, NULL
);
186 static ssize_t
dgrp_node_hw_version_show(struct device
*c
,
187 struct device_attribute
*attr
,
190 struct nd_struct
*nd
;
194 nd
= (struct nd_struct
*) dev_get_drvdata(c
);
198 if (nd
->nd_state
== NS_READY
)
199 return snprintf(buf
, PAGE_SIZE
, "%d.%d\n",
200 (nd
->nd_hw_ver
>> 8) & 0xff,
201 nd
->nd_hw_ver
& 0xff);
205 static DEVICE_ATTR(hw_version_info
, 0600, dgrp_node_hw_version_show
, NULL
);
207 static ssize_t
dgrp_node_hw_id_show(struct device
*c
,
208 struct device_attribute
*attr
, char *buf
)
210 struct nd_struct
*nd
;
214 nd
= (struct nd_struct
*) dev_get_drvdata(c
);
219 if (nd
->nd_state
== NS_READY
)
220 return snprintf(buf
, PAGE_SIZE
, "%d\n", nd
->nd_hw_id
);
223 static DEVICE_ATTR(hw_id_info
, 0600, dgrp_node_hw_id_show
, NULL
);
225 static ssize_t
dgrp_node_sw_version_show(struct device
*c
,
226 struct device_attribute
*attr
,
229 struct nd_struct
*nd
;
234 nd
= (struct nd_struct
*) dev_get_drvdata(c
);
238 if (nd
->nd_state
== NS_READY
)
239 return snprintf(buf
, PAGE_SIZE
, "%d.%d\n",
240 (nd
->nd_sw_ver
>> 8) & 0xff,
241 nd
->nd_sw_ver
& 0xff);
245 static DEVICE_ATTR(sw_version_info
, 0600, dgrp_node_sw_version_show
, NULL
);
248 static struct attribute
*dgrp_sysfs_node_entries
[] = {
249 &dev_attr_state
.attr
,
250 &dev_attr_description_info
.attr
,
251 &dev_attr_hw_version_info
.attr
,
252 &dev_attr_hw_id_info
.attr
,
253 &dev_attr_sw_version_info
.attr
,
258 static struct attribute_group dgrp_node_attribute_group
= {
260 .attrs
= dgrp_sysfs_node_entries
,
264 void dgrp_create_node_class_sysfs_files(struct nd_struct
*nd
)
270 ID_TO_CHAR(nd
->nd_ID
, name
);
272 sprintf(name
, "node%ld", nd
->nd_major
);
274 nd
->nd_class_dev
= device_create(dgrp_class
, dgrp_class_nodes_dev
,
275 MKDEV(0, nd
->nd_major
), NULL
, name
);
277 ret
= sysfs_create_group(&nd
->nd_class_dev
->kobj
,
278 &dgrp_node_attribute_group
);
281 pr_alert("%s: failed to create sysfs node device attributes.\n",
283 sysfs_remove_group(&nd
->nd_class_dev
->kobj
,
284 &dgrp_node_attribute_group
);
288 dev_set_drvdata(nd
->nd_class_dev
, nd
);
293 void dgrp_remove_node_class_sysfs_files(struct nd_struct
*nd
)
295 if (nd
->nd_class_dev
) {
296 sysfs_remove_group(&nd
->nd_class_dev
->kobj
,
297 &dgrp_node_attribute_group
);
299 device_destroy(dgrp_class
, MKDEV(0, nd
->nd_major
));
300 nd
->nd_class_dev
= NULL
;
306 static ssize_t
dgrp_tty_state_show(struct device
*d
,
307 struct device_attribute
*attr
, char *buf
)
309 struct un_struct
*un
;
313 un
= (struct un_struct
*) dev_get_drvdata(d
);
317 return snprintf(buf
, PAGE_SIZE
, "%s\n",
318 un
->un_open_count
? "Open" : "Closed");
320 static DEVICE_ATTR(state_info
, 0600, dgrp_tty_state_show
, NULL
);
322 static ssize_t
dgrp_tty_baud_show(struct device
*d
,
323 struct device_attribute
*attr
, char *buf
)
325 struct ch_struct
*ch
;
326 struct un_struct
*un
;
330 un
= (struct un_struct
*) dev_get_drvdata(d
);
336 return snprintf(buf
, PAGE_SIZE
, "%d\n",
337 un
->un_open_count
? (PORTSERVER_DIVIDEND
/ ch
->ch_s_brate
) : 0);
339 static DEVICE_ATTR(baud_info
, 0400, dgrp_tty_baud_show
, NULL
);
342 static ssize_t
dgrp_tty_msignals_show(struct device
*d
,
343 struct device_attribute
*attr
, char *buf
)
345 struct ch_struct
*ch
;
346 struct un_struct
*un
;
350 un
= (struct un_struct
*) dev_get_drvdata(d
);
357 if (ch
->ch_open_count
) {
358 return snprintf(buf
, PAGE_SIZE
, "%s %s %s %s %s %s\n",
359 (ch
->ch_s_mlast
& DM_RTS
) ? "RTS" : "",
360 (ch
->ch_s_mlast
& DM_CTS
) ? "CTS" : "",
361 (ch
->ch_s_mlast
& DM_DTR
) ? "DTR" : "",
362 (ch
->ch_s_mlast
& DM_DSR
) ? "DSR" : "",
363 (ch
->ch_s_mlast
& DM_CD
) ? "DCD" : "",
364 (ch
->ch_s_mlast
& DM_RI
) ? "RI" : "");
368 static DEVICE_ATTR(msignals_info
, 0400, dgrp_tty_msignals_show
, NULL
);
371 static ssize_t
dgrp_tty_iflag_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_iflag
);
387 static DEVICE_ATTR(iflag_info
, 0600, dgrp_tty_iflag_show
, NULL
);
390 static ssize_t
dgrp_tty_cflag_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_cflag
);
406 static DEVICE_ATTR(cflag_info
, 0600, dgrp_tty_cflag_show
, NULL
);
409 static ssize_t
dgrp_tty_oflag_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_s_oflag
);
425 static DEVICE_ATTR(oflag_info
, 0600, dgrp_tty_oflag_show
, NULL
);
428 static ssize_t
dgrp_tty_digi_flag_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
, "%x\n", ch
->ch_digi
.digi_flags
);
444 static DEVICE_ATTR(digi_flag_info
, 0600, dgrp_tty_digi_flag_show
, NULL
);
447 static ssize_t
dgrp_tty_rxcount_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_rxcount
);
463 static DEVICE_ATTR(rxcount_info
, 0600, dgrp_tty_rxcount_show
, NULL
);
466 static ssize_t
dgrp_tty_txcount_show(struct device
*d
,
467 struct device_attribute
*attr
, char *buf
)
469 struct ch_struct
*ch
;
470 struct un_struct
*un
;
474 un
= (struct un_struct
*) dev_get_drvdata(d
);
480 return snprintf(buf
, PAGE_SIZE
, "%d\n", ch
->ch_txcount
);
482 static DEVICE_ATTR(txcount_info
, 0600, dgrp_tty_txcount_show
, NULL
);
485 static ssize_t
dgrp_tty_name_show(struct device
*d
,
486 struct device_attribute
*attr
, char *buf
)
488 struct nd_struct
*nd
;
489 struct ch_struct
*ch
;
490 struct un_struct
*un
;
495 un
= (struct un_struct
*) dev_get_drvdata(d
);
505 ID_TO_CHAR(nd
->nd_ID
, name
);
507 return snprintf(buf
, PAGE_SIZE
, "%s%s%02d\n",
508 un
->un_type
== SERIAL_TYPE_XPRINT
? "pr" : "tty",
509 name
, ch
->ch_portnum
);
511 static DEVICE_ATTR(custom_name
, 0600, dgrp_tty_name_show
, NULL
);
514 static struct attribute
*dgrp_sysfs_tty_entries
[] = {
515 &dev_attr_state_info
.attr
,
516 &dev_attr_baud_info
.attr
,
517 &dev_attr_msignals_info
.attr
,
518 &dev_attr_iflag_info
.attr
,
519 &dev_attr_cflag_info
.attr
,
520 &dev_attr_oflag_info
.attr
,
521 &dev_attr_digi_flag_info
.attr
,
522 &dev_attr_rxcount_info
.attr
,
523 &dev_attr_txcount_info
.attr
,
524 &dev_attr_custom_name
.attr
,
529 static struct attribute_group dgrp_tty_attribute_group
= {
531 .attrs
= dgrp_sysfs_tty_entries
,
535 void dgrp_create_tty_sysfs(struct un_struct
*un
, struct device
*c
)
539 ret
= sysfs_create_group(&c
->kobj
, &dgrp_tty_attribute_group
);
541 pr_alert("%s: failed to create sysfs tty device attributes.\n",
543 sysfs_remove_group(&c
->kobj
, &dgrp_tty_attribute_group
);
547 dev_set_drvdata(c
, un
);
552 void dgrp_remove_tty_sysfs(struct device
*c
)
554 sysfs_remove_group(&c
->kobj
, &dgrp_tty_attribute_group
);