11 #define KMSG_COMPONENT "hvc_iucv"
12 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
14 #include <linux/types.h>
15 #include <linux/slab.h>
17 #include <linux/ctype.h>
19 #include <linux/device.h>
23 #include <linux/tty.h>
24 #include <linux/wait.h>
31 #define HVC_IUCV_MAGIC 0xc9e4c3e5
32 #define MAX_HVC_IUCV_LINES HVC_ALLOC_TTY_ADAPTERS
33 #define MEMPOOL_MIN_NR (PAGE_SIZE / sizeof(struct iucv_tty_buffer)/4)
36 #define MSG_VERSION 0x02
37 #define MSG_TYPE_ERROR 0x01
38 #define MSG_TYPE_TERMENV 0x02
39 #define MSG_TYPE_TERMIOS 0x04
40 #define MSG_TYPE_WINSIZE 0x08
41 #define MSG_TYPE_DATA 0x10
46 #define MSG_MAX_DATALEN ((u16)(~0))
50 #define MSG_SIZE(s) ((s) + offsetof(struct iucv_tty_msg, data))
71 #define SNDBUF_SIZE (PAGE_SIZE)
74 #define QUEUE_SNDBUF_DELAY (HZ / 25)
90 static int hvc_iucv_path_pending(
struct iucv_path *,
u8[8],
u8[16]);
91 static void hvc_iucv_path_severed(
struct iucv_path *,
u8[16]);
97 static unsigned long hvc_iucv_devices = 1;
101 #define IUCV_HVC_CON_IDX (0)
103 #define MAX_VMID_FILTER (500)
104 static size_t hvc_iucv_filter_size;
105 static void *hvc_iucv_filter;
106 static const char *hvc_iucv_filter_string;
110 static struct kmem_cache *hvc_iucv_buffer_cache;
115 .path_pending = hvc_iucv_path_pending,
116 .path_severed = hvc_iucv_path_severed,
117 .message_complete = hvc_iucv_msg_complete,
118 .message_pending = hvc_iucv_msg_pending,
156 memset(bufp, 0,
sizeof(*bufp));
167 bufp->
mbuf->datalen = (
u16) size;
192 destroy_tty_buffer(ent);
217 char *
buf,
int count,
int *has_more_data)
262 goto out_remove_buffer;
265 switch (rb->
mbuf->type) {
269 if (written < (rb->
mbuf->datalen - rb->
offset)) {
292 destroy_tty_buffer(rb);
313 static int hvc_iucv_get_chars(
uint32_t vtermno,
char *buf,
int count)
325 spin_lock(&priv->
lock);
327 written = hvc_iucv_write(priv, buf, count, &has_more_data);
328 spin_unlock(&priv->
lock);
413 (
void *) sb->
mbuf, sb->
msg.length);
418 destroy_tty_buffer(sb);
441 spin_lock_bh(&priv->
lock);
443 spin_unlock_bh(&priv->
lock);
458 static int hvc_iucv_put_chars(
uint32_t vtermno,
const char *buf,
int count)
469 spin_lock(&priv->
lock);
470 queued = hvc_iucv_queue(priv, buf, count);
471 spin_unlock(&priv->
lock);
487 static int hvc_iucv_notifier_add(
struct hvc_struct *hp,
int id)
495 spin_lock_bh(&priv->
lock);
497 spin_unlock_bh(&priv->
lock);
525 spin_lock_bh(&priv->
lock);
527 spin_unlock_bh(&priv->
lock);
545 spin_lock_bh(&priv->
lock);
548 spin_unlock_bh(&priv->
lock);
552 tty_outqueue_empty(priv),
HZ/10);
592 spin_lock(&priv->
lock);
598 hvc_iucv_cleanup(priv);
602 hvc_iucv_cleanup(priv);
607 spin_unlock(&priv->
lock);
612 iucv_path_free(path);
633 static void hvc_iucv_notifier_hangup(
struct hvc_struct *hp,
int id)
641 flush_sndbuf_sync(priv);
643 spin_lock_bh(&priv->
lock);
654 hvc_iucv_cleanup(priv);
655 spin_unlock_bh(&priv->
lock);
670 static void hvc_iucv_notifier_del(
struct hvc_struct *hp,
int id)
679 flush_sndbuf_sync(priv);
681 spin_lock_bh(&priv->
lock);
684 hvc_iucv_cleanup(priv);
685 spin_unlock_bh(&priv->
lock);
691 iucv_path_free(path);
702 static int hvc_iucv_filter_connreq(
u8 ipvmid[8])
707 if (!hvc_iucv_filter_size)
710 for (i = 0; i < hvc_iucv_filter_size; i++)
711 if (0 ==
memcmp(ipvmid, hvc_iucv_filter + (8 * i), 8))
735 static int hvc_iucv_path_pending(
struct iucv_path *path,
744 for (i = 0; i < hvc_iucv_devices; i++)
745 if (hvc_iucv_table[i] &&
747 priv = hvc_iucv_table[
i];
755 rc = hvc_iucv_filter_connreq(ipvmid);
759 iucv_path_free(path);
760 memcpy(vm_user_id, ipvmid, 8);
762 pr_info(
"A connection request from z/VM user ID %s "
763 "was refused\n", vm_user_id);
767 spin_lock(&priv->
lock);
774 iucv_path_free(path);
775 goto out_path_handled;
779 memcpy(nuser_data, ipuser + 8, 8);
780 memcpy(nuser_data + 8, ipuser, 8);
783 rc = iucv_path_accept(path, &hvc_iucv_handler, nuser_data, priv);
786 iucv_path_free(path);
787 goto out_path_handled;
796 spin_unlock(&priv->
lock);
811 static void hvc_iucv_path_severed(
struct iucv_path *path,
u8 ipuser[16])
815 hvc_iucv_hangup(priv);
829 static void hvc_iucv_msg_pending(
struct iucv_path *path,
841 spin_lock(&priv->
lock);
862 spin_unlock(&priv->
lock);
877 static void hvc_iucv_msg_complete(
struct iucv_path *path,
884 spin_lock(&priv->
lock);
886 if (ent->msg.
id == msg->
id) {
887 list_move(&ent->
list, &list_remove);
891 spin_unlock(&priv->
lock);
892 destroy_tty_buffer_list(&list_remove);
902 static int hvc_iucv_pm_freeze(
struct device *
dev)
907 hvc_iucv_hangup(priv);
920 static int hvc_iucv_pm_restore_thaw(
struct device *
dev)
928 static const struct hv_ops hvc_iucv_ops = {
929 .get_chars = hvc_iucv_get_chars,
930 .put_chars = hvc_iucv_put_chars,
931 .notifier_add = hvc_iucv_notifier_add,
932 .notifier_del = hvc_iucv_notifier_del,
933 .notifier_hangup = hvc_iucv_notifier_hangup,
937 static const struct dev_pm_ops hvc_iucv_pm_ops = {
938 .freeze = hvc_iucv_pm_freeze,
939 .thaw = hvc_iucv_pm_restore_thaw,
940 .restore = hvc_iucv_pm_restore_thaw,
947 .pm = &hvc_iucv_pm_ops,
959 static int __init hvc_iucv_alloc(
int id,
unsigned int is_console)
987 if (IS_ERR(priv->
hvc)) {
988 rc = PTR_ERR(priv->
hvc);
993 priv->
hvc->irq_requested = 1;
996 snprintf(name, 9,
"lnxhvc%-2d",
id);
1010 priv->
dev->driver = &hvc_iucv_driver;
1018 hvc_iucv_table[
id] =
priv;
1045 static const char *hvc_iucv_parse_filter(
const char *
filter,
char *
dest)
1050 nextdelim =
strchr(filter,
',');
1052 len = nextdelim -
filter;
1053 residual = nextdelim + 1;
1056 residual = filter + len;
1063 if (filter[len - 1] ==
'\n')
1072 dest[len] =
toupper(filter[len]);
1086 static int hvc_iucv_setup_filter(
const char *
val)
1091 void *array, *old_filter;
1094 if (count == 0 || (count == 1 && val[0] ==
'\n')) {
1097 goto out_replace_filter;
1103 while ((residual =
strchr(residual,
',')) !=
NULL) {
1118 while (*residual && count) {
1119 residual = hvc_iucv_parse_filter(residual,
1120 array + ((size - count) * 8));
1121 if (IS_ERR(residual)) {
1122 err = PTR_ERR(residual);
1131 old_filter = hvc_iucv_filter;
1132 hvc_iucv_filter_size =
size;
1133 hvc_iucv_filter = array;
1152 static int param_set_vmidfilter(
const char *val,
const struct kernel_param *kp)
1164 rc = hvc_iucv_setup_filter(val);
1166 hvc_iucv_filter_string =
val;
1190 for (index = 0; index < hvc_iucv_filter_size; index++) {
1191 start = hvc_iucv_filter + (8 *
index);
1192 end =
memchr(start,
' ', 8);
1193 len = (
end) ? end - start : 8;
1194 memcpy(buffer + rc, start, len);
1200 buffer[--
rc] =
'\0';
1204 #define param_check_vmidfilter(name, p) __param_check(name, p, void)
1207 .set = param_set_vmidfilter,
1208 .get = param_get_vmidfilter,
1214 static int __init hvc_iucv_init(
void)
1219 if (!hvc_iucv_devices)
1223 pr_notice(
"The z/VM IUCV HVC device driver cannot "
1224 "be used without z/VM\n");
1230 pr_err(
"%lu is not a valid value for the hvc_iucv= "
1231 "kernel parameter\n", hvc_iucv_devices);
1242 if (hvc_iucv_filter_string) {
1243 rc = hvc_iucv_setup_filter(hvc_iucv_filter_string);
1248 pr_err(
"Allocating memory failed with "
1249 "reason code=%d\n", 3);
1252 pr_err(
"hvc_iucv_allow= does not specify a valid "
1253 "z/VM user ID list\n");
1256 pr_err(
"hvc_iucv_allow= specifies too many "
1267 if (!hvc_iucv_buffer_cache) {
1268 pr_err(
"Allocating memory failed with reason code=%d\n", 1);
1274 hvc_iucv_buffer_cache);
1275 if (!hvc_iucv_mempool) {
1276 pr_err(
"Allocating memory failed with reason code=%d\n", 2);
1286 pr_err(
"Registering HVC terminal device as "
1287 "Linux console failed\n");
1288 goto out_error_memory;
1292 for (i = 0; i < hvc_iucv_devices; i++) {
1295 pr_err(
"Creating a new HVC terminal device "
1296 "failed with error code=%d\n", rc);
1304 pr_err(
"Registering IUCV handlers failed with error code=%d\n",
1312 for (i = 0; i < hvc_iucv_devices; i++)
1313 if (hvc_iucv_table[i])
1314 hvc_iucv_destroy(hvc_iucv_table[i]);
1319 if (hvc_iucv_filter)
1320 kfree(hvc_iucv_filter);
1321 hvc_iucv_devices = 0;
1329 static int __init hvc_iucv_config(
char *val)
1336 __setup(
"hvc_iucv=", hvc_iucv_config);
1337 core_param(hvc_iucv_allow, hvc_iucv_filter, vmidfilter, 0640);