aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHendrik Brueckner <brueckner@linux.vnet.ibm.com>2014-01-17 08:42:00 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2014-01-22 08:02:13 -0500
commitf1206bad2557de8868878a188cf5c506bb676ff7 (patch)
treeb044ea8c9f4bfd9611e5a6eb5906bbf732e31c2a
parent2ee13c6e98011200058686ad45219532c871afeb (diff)
s390/hvc_iucv: Display connection details through device attributes
Add device attributes to display details about the connection status of HVC IUCV terminals. Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--drivers/tty/hvc/hvc_iucv.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/drivers/tty/hvc/hvc_iucv.c b/drivers/tty/hvc/hvc_iucv.c
index ba6b3f4b15df..fbd023cee4ba 100644
--- a/drivers/tty/hvc/hvc_iucv.c
+++ b/drivers/tty/hvc/hvc_iucv.c
@@ -77,6 +77,7 @@ struct hvc_iucv_private {
77 struct list_head tty_outqueue; /* outgoing IUCV messages */ 77 struct list_head tty_outqueue; /* outgoing IUCV messages */
78 struct list_head tty_inqueue; /* incoming IUCV messages */ 78 struct list_head tty_inqueue; /* incoming IUCV messages */
79 struct device *dev; /* device structure */ 79 struct device *dev; /* device structure */
80 u8 info_path[16]; /* IUCV path info (dev attr) */
80}; 81};
81 82
82struct iucv_tty_buffer { 83struct iucv_tty_buffer {
@@ -826,6 +827,10 @@ static int hvc_iucv_path_pending(struct iucv_path *path,
826 priv->path = path; 827 priv->path = path;
827 priv->iucv_state = IUCV_CONNECTED; 828 priv->iucv_state = IUCV_CONNECTED;
828 829
830 /* store path information */
831 memcpy(priv->info_path, ipvmid, 8);
832 memcpy(priv->info_path + 8, ipuser + 8, 8);
833
829 /* flush buffered output data... */ 834 /* flush buffered output data... */
830 schedule_delayed_work(&priv->sndbuf_work, 5); 835 schedule_delayed_work(&priv->sndbuf_work, 5);
831 836
@@ -960,6 +965,49 @@ static int hvc_iucv_pm_restore_thaw(struct device *dev)
960 return 0; 965 return 0;
961} 966}
962 967
968static ssize_t hvc_iucv_dev_termid_show(struct device *dev,
969 struct device_attribute *attr,
970 char *buf)
971{
972 struct hvc_iucv_private *priv = dev_get_drvdata(dev);
973 size_t len;
974
975 len = sizeof(priv->srv_name);
976 memcpy(buf, priv->srv_name, len);
977 EBCASC(buf, len);
978 buf[len++] = '\n';
979 return len;
980}
981
982static ssize_t hvc_iucv_dev_state_show(struct device *dev,
983 struct device_attribute *attr,
984 char *buf)
985{
986 struct hvc_iucv_private *priv = dev_get_drvdata(dev);
987 return sprintf(buf, "%u:%u\n", priv->iucv_state, priv->tty_state);
988}
989
990static ssize_t hvc_iucv_dev_peer_show(struct device *dev,
991 struct device_attribute *attr,
992 char *buf)
993{
994 struct hvc_iucv_private *priv = dev_get_drvdata(dev);
995 char vmid[9], ipuser[9];
996
997 memset(vmid, 0, sizeof(vmid));
998 memset(ipuser, 0, sizeof(ipuser));
999
1000 spin_lock_bh(&priv->lock);
1001 if (priv->iucv_state == IUCV_CONNECTED) {
1002 memcpy(vmid, priv->info_path, 8);
1003 memcpy(ipuser, priv->info_path + 8, 8);
1004 }
1005 spin_unlock_bh(&priv->lock);
1006 EBCASC(ipuser, 8);
1007
1008 return sprintf(buf, "%s:%s\n", vmid, ipuser);
1009}
1010
963 1011
964/* HVC operations */ 1012/* HVC operations */
965static const struct hv_ops hvc_iucv_ops = { 1013static const struct hv_ops hvc_iucv_ops = {
@@ -985,6 +1033,25 @@ static struct device_driver hvc_iucv_driver = {
985 .pm = &hvc_iucv_pm_ops, 1033 .pm = &hvc_iucv_pm_ops,
986}; 1034};
987 1035
1036/* IUCV HVC device attributes */
1037static DEVICE_ATTR(termid, 0640, hvc_iucv_dev_termid_show, NULL);
1038static DEVICE_ATTR(state, 0640, hvc_iucv_dev_state_show, NULL);
1039static DEVICE_ATTR(peer, 0640, hvc_iucv_dev_peer_show, NULL);
1040static struct attribute *hvc_iucv_dev_attrs[] = {
1041 &dev_attr_termid.attr,
1042 &dev_attr_state.attr,
1043 &dev_attr_peer.attr,
1044 NULL,
1045};
1046static struct attribute_group hvc_iucv_dev_attr_group = {
1047 .attrs = hvc_iucv_dev_attrs,
1048};
1049static const struct attribute_group *hvc_iucv_dev_attr_groups[] = {
1050 &hvc_iucv_dev_attr_group,
1051 NULL,
1052};
1053
1054
988/** 1055/**
989 * hvc_iucv_alloc() - Allocates a new struct hvc_iucv_private instance 1056 * hvc_iucv_alloc() - Allocates a new struct hvc_iucv_private instance
990 * @id: hvc_iucv_table index 1057 * @id: hvc_iucv_table index
@@ -1046,6 +1113,7 @@ static int __init hvc_iucv_alloc(int id, unsigned int is_console)
1046 priv->dev->bus = &iucv_bus; 1113 priv->dev->bus = &iucv_bus;
1047 priv->dev->parent = iucv_root; 1114 priv->dev->parent = iucv_root;
1048 priv->dev->driver = &hvc_iucv_driver; 1115 priv->dev->driver = &hvc_iucv_driver;
1116 priv->dev->groups = hvc_iucv_dev_attr_groups;
1049 priv->dev->release = (void (*)(struct device *)) kfree; 1117 priv->dev->release = (void (*)(struct device *)) kfree;
1050 rc = device_register(priv->dev); 1118 rc = device_register(priv->dev);
1051 if (rc) { 1119 if (rc) {