summaryrefslogtreecommitdiff
path: root/drivers/tty/hvc
diff options
context:
space:
mode:
authorHendrik Brueckner <brueckner@linux.vnet.ibm.com>2014-01-17 19:11:07 +0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2014-01-22 17:02:13 +0400
commit4f5922194dbed57581f470e49073a96d346a7174 (patch)
treee3d82e9acc991b32327088a0bd2fec4843726c8c /drivers/tty/hvc
parentf1206bad2557de8868878a188cf5c506bb676ff7 (diff)
downloadlinux-4f5922194dbed57581f470e49073a96d346a7174.tar.xz
s390/hvc_iucv: Automatically assign free HVC terminal devices
Add the generic "lnxhvc" terminal ID to automatically assign a HVC terminal when connecting to the HVC IUCV terminal device driver. The terminal device driver tries to find a free (not connected) HVC terminal to satisfy the incoming connection request. With this improvement, you do not longer need to guess which HVC terminal is free, that is, not connected. Also you can still connect to a particular HVC terminal by using its associated terminal ID. Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/tty/hvc')
-rw-r--r--drivers/tty/hvc/hvc_iucv.c33
1 files changed, 26 insertions, 7 deletions
diff --git a/drivers/tty/hvc/hvc_iucv.c b/drivers/tty/hvc/hvc_iucv.c
index fbd023cee4ba..ea74460f3638 100644
--- a/drivers/tty/hvc/hvc_iucv.c
+++ b/drivers/tty/hvc/hvc_iucv.c
@@ -773,18 +773,37 @@ static int hvc_iucv_filter_connreq(u8 ipvmid[8])
static int hvc_iucv_path_pending(struct iucv_path *path,
u8 ipvmid[8], u8 ipuser[16])
{
- struct hvc_iucv_private *priv;
+ struct hvc_iucv_private *priv, *tmp;
+ u8 wildcard[9] = "lnxhvc ";
+ int i, rc, find_unused;
u8 nuser_data[16];
u8 vm_user_id[9];
- int i, rc;
+ ASCEBC(wildcard, sizeof(wildcard));
+ find_unused = !memcmp(wildcard, ipuser, 8);
+
+ /* First, check if the pending path request is managed by this
+ * IUCV handler:
+ * - find a disconnected device if ipuser contains the wildcard
+ * - find the device that matches the terminal ID in ipuser
+ */
priv = NULL;
- for (i = 0; i < hvc_iucv_devices; i++)
- if (hvc_iucv_table[i] &&
- (0 == memcmp(hvc_iucv_table[i]->srv_name, ipuser, 8))) {
- priv = hvc_iucv_table[i];
+ for (i = 0; i < hvc_iucv_devices; i++) {
+ tmp = hvc_iucv_table[i];
+ if (!tmp)
+ continue;
+
+ if (find_unused) {
+ spin_lock(&tmp->lock);
+ if (tmp->iucv_state == IUCV_DISCONN)
+ priv = tmp;
+ spin_unlock(&tmp->lock);
+
+ } else if (!memcmp(tmp->srv_name, ipuser, 8))
+ priv = tmp;
+ if (priv)
break;
- }
+ }
if (!priv)
return -ENODEV;