aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/hvc_iucv.c176
1 files changed, 75 insertions, 101 deletions
diff --git a/drivers/char/hvc_iucv.c b/drivers/char/hvc_iucv.c
index a23f7e8fba86..ce1a25f779ce 100644
--- a/drivers/char/hvc_iucv.c
+++ b/drivers/char/hvc_iucv.c
@@ -1,14 +1,15 @@
1/* 1/*
2 * hvc_iucv.c - z/VM IUCV back-end for the Hypervisor Console (HVC) 2 * hvc_iucv.c - z/VM IUCV hypervisor console (HVC) device driver
3 * 3 *
4 * This back-end for HVC provides terminal access via 4 * This HVC device driver provides terminal access using
5 * z/VM IUCV communication paths. 5 * z/VM IUCV communication paths.
6 * 6 *
7 * Copyright IBM Corp. 2008. 7 * Copyright IBM Corp. 2008
8 * 8 *
9 * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com> 9 * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
10 */ 10 */
11#define KMSG_COMPONENT "hvc_iucv" 11#define KMSG_COMPONENT "hvc_iucv"
12#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
12 13
13#include <linux/types.h> 14#include <linux/types.h>
14#include <asm/ebcdic.h> 15#include <asm/ebcdic.h>
@@ -22,7 +23,7 @@
22#include "hvc_console.h" 23#include "hvc_console.h"
23 24
24 25
25/* HVC backend for z/VM IUCV */ 26/* General device driver settings */
26#define HVC_IUCV_MAGIC 0xc9e4c3e5 27#define HVC_IUCV_MAGIC 0xc9e4c3e5
27#define MAX_HVC_IUCV_LINES HVC_ALLOC_TTY_ADAPTERS 28#define MAX_HVC_IUCV_LINES HVC_ALLOC_TTY_ADAPTERS
28#define MEMPOOL_MIN_NR (PAGE_SIZE / sizeof(struct iucv_tty_buffer)/4) 29#define MEMPOOL_MIN_NR (PAGE_SIZE / sizeof(struct iucv_tty_buffer)/4)
@@ -35,7 +36,6 @@
35#define MSG_TYPE_WINSIZE 0x08 /* Terminal window size update */ 36#define MSG_TYPE_WINSIZE 0x08 /* Terminal window size update */
36#define MSG_TYPE_DATA 0x10 /* Terminal data */ 37#define MSG_TYPE_DATA 0x10 /* Terminal data */
37 38
38#define MSG_SIZE(s) ((s) + offsetof(struct iucv_tty_msg, data))
39struct iucv_tty_msg { 39struct iucv_tty_msg {
40 u8 version; /* Message version */ 40 u8 version; /* Message version */
41 u8 type; /* Message type */ 41 u8 type; /* Message type */
@@ -43,6 +43,7 @@ struct iucv_tty_msg {
43 u16 datalen; /* Payload length */ 43 u16 datalen; /* Payload length */
44 u8 data[]; /* Payload buffer */ 44 u8 data[]; /* Payload buffer */
45} __attribute__((packed)); 45} __attribute__((packed));
46#define MSG_SIZE(s) ((s) + offsetof(struct iucv_tty_msg, data))
46 47
47enum iucv_state_t { 48enum iucv_state_t {
48 IUCV_DISCONN = 0, 49 IUCV_DISCONN = 0,
@@ -56,7 +57,7 @@ enum tty_state_t {
56}; 57};
57 58
58struct hvc_iucv_private { 59struct hvc_iucv_private {
59 struct hvc_struct *hvc; /* HVC console struct reference */ 60 struct hvc_struct *hvc; /* HVC struct reference */
60 u8 srv_name[8]; /* IUCV service name (ebcdic) */ 61 u8 srv_name[8]; /* IUCV service name (ebcdic) */
61 enum iucv_state_t iucv_state; /* IUCV connection status */ 62 enum iucv_state_t iucv_state; /* IUCV connection status */
62 enum tty_state_t tty_state; /* TTY status */ 63 enum tty_state_t tty_state; /* TTY status */
@@ -74,7 +75,7 @@ struct hvc_iucv_private {
74 75
75struct iucv_tty_buffer { 76struct iucv_tty_buffer {
76 struct list_head list; /* list pointer */ 77 struct list_head list; /* list pointer */
77 struct iucv_message msg; /* store an incoming IUCV message */ 78 struct iucv_message msg; /* store an IUCV message */
78 size_t offset; /* data buffer offset */ 79 size_t offset; /* data buffer offset */
79 struct iucv_tty_msg *mbuf; /* buffer to store input/output data */ 80 struct iucv_tty_msg *mbuf; /* buffer to store input/output data */
80}; 81};
@@ -120,7 +121,7 @@ struct hvc_iucv_private *hvc_iucv_get_private(uint32_t num)
120} 121}
121 122
122/** 123/**
123 * alloc_tty_buffer() - Returns a new struct iucv_tty_buffer element. 124 * alloc_tty_buffer() - Return a new struct iucv_tty_buffer element.
124 * @size: Size of the internal buffer used to store data. 125 * @size: Size of the internal buffer used to store data.
125 * @flags: Memory allocation flags passed to mempool. 126 * @flags: Memory allocation flags passed to mempool.
126 * 127 *
@@ -128,7 +129,6 @@ struct hvc_iucv_private *hvc_iucv_get_private(uint32_t num)
128 * allocates an internal data buffer with the specified size @size. 129 * allocates an internal data buffer with the specified size @size.
129 * Note: The total message size arises from the internal buffer size and the 130 * Note: The total message size arises from the internal buffer size and the
130 * members of the iucv_tty_msg structure. 131 * members of the iucv_tty_msg structure.
131 *
132 * The function returns NULL if memory allocation has failed. 132 * The function returns NULL if memory allocation has failed.
133 */ 133 */
134static struct iucv_tty_buffer *alloc_tty_buffer(size_t size, gfp_t flags) 134static struct iucv_tty_buffer *alloc_tty_buffer(size_t size, gfp_t flags)
@@ -157,9 +157,6 @@ static struct iucv_tty_buffer *alloc_tty_buffer(size_t size, gfp_t flags)
157/** 157/**
158 * destroy_tty_buffer() - destroy struct iucv_tty_buffer element. 158 * destroy_tty_buffer() - destroy struct iucv_tty_buffer element.
159 * @bufp: Pointer to a struct iucv_tty_buffer element, SHALL NOT be NULL. 159 * @bufp: Pointer to a struct iucv_tty_buffer element, SHALL NOT be NULL.
160 *
161 * The destroy_tty_buffer() function frees the internal data buffer and returns
162 * the struct iucv_tty_buffer element back to the mempool for freeing.
163 */ 160 */
164static void destroy_tty_buffer(struct iucv_tty_buffer *bufp) 161static void destroy_tty_buffer(struct iucv_tty_buffer *bufp)
165{ 162{
@@ -169,11 +166,7 @@ static void destroy_tty_buffer(struct iucv_tty_buffer *bufp)
169 166
170/** 167/**
171 * destroy_tty_buffer_list() - call destroy_tty_buffer() for each list element. 168 * destroy_tty_buffer_list() - call destroy_tty_buffer() for each list element.
172 * @list: List head pointer to a list containing struct iucv_tty_buffer 169 * @list: List containing struct iucv_tty_buffer elements.
173 * elements.
174 *
175 * Calls destroy_tty_buffer() for each struct iucv_tty_buffer element in the
176 * list @list.
177 */ 170 */
178static void destroy_tty_buffer_list(struct list_head *list) 171static void destroy_tty_buffer_list(struct list_head *list)
179{ 172{
@@ -186,24 +179,24 @@ static void destroy_tty_buffer_list(struct list_head *list)
186} 179}
187 180
188/** 181/**
189 * hvc_iucv_write() - Receive IUCV message write data to HVC console buffer. 182 * hvc_iucv_write() - Receive IUCV message & write data to HVC buffer.
190 * @priv: Pointer to hvc_iucv_private structure. 183 * @priv: Pointer to struct hvc_iucv_private
191 * @buf: HVC console buffer for writing received terminal data. 184 * @buf: HVC buffer for writing received terminal data.
192 * @count: HVC console buffer size. 185 * @count: HVC buffer size.
193 * @has_more_data: Pointer to an int variable. 186 * @has_more_data: Pointer to an int variable.
194 * 187 *
195 * The function picks up pending messages from the input queue and receives 188 * The function picks up pending messages from the input queue and receives
196 * the message data that is then written to the specified buffer @buf. 189 * the message data that is then written to the specified buffer @buf.
197 * If the buffer size @count is less than the data message size, then the 190 * If the buffer size @count is less than the data message size, the
198 * message is kept on the input queue and @has_more_data is set to 1. 191 * message is kept on the input queue and @has_more_data is set to 1.
199 * If the message data has been entirely written, the message is removed from 192 * If all message data has been written, the message is removed from
200 * the input queue. 193 * the input queue.
201 * 194 *
202 * The function returns the number of bytes written to the terminal, zero if 195 * The function returns the number of bytes written to the terminal, zero if
203 * there are no pending data messages available or if there is no established 196 * there are no pending data messages available or if there is no established
204 * IUCV path. 197 * IUCV path.
205 * If the IUCV path has been severed, then -EPIPE is returned to cause a 198 * If the IUCV path has been severed, then -EPIPE is returned to cause a
206 * hang up (that is issued by the HVC console layer). 199 * hang up (that is issued by the HVC layer).
207 */ 200 */
208static int hvc_iucv_write(struct hvc_iucv_private *priv, 201static int hvc_iucv_write(struct hvc_iucv_private *priv,
209 char *buf, int count, int *has_more_data) 202 char *buf, int count, int *has_more_data)
@@ -212,12 +205,12 @@ static int hvc_iucv_write(struct hvc_iucv_private *priv,
212 int written; 205 int written;
213 int rc; 206 int rc;
214 207
215 /* Immediately return if there is no IUCV connection */ 208 /* immediately return if there is no IUCV connection */
216 if (priv->iucv_state == IUCV_DISCONN) 209 if (priv->iucv_state == IUCV_DISCONN)
217 return 0; 210 return 0;
218 211
219 /* If the IUCV path has been severed, return -EPIPE to inform the 212 /* if the IUCV path has been severed, return -EPIPE to inform the
220 * hvc console layer to hang up the tty device. */ 213 * HVC layer to hang up the tty device. */
221 if (priv->iucv_state == IUCV_SEVERED) 214 if (priv->iucv_state == IUCV_SEVERED)
222 return -EPIPE; 215 return -EPIPE;
223 216
@@ -225,7 +218,7 @@ static int hvc_iucv_write(struct hvc_iucv_private *priv,
225 if (list_empty(&priv->tty_inqueue)) 218 if (list_empty(&priv->tty_inqueue))
226 return 0; 219 return 0;
227 220
228 /* receive a iucv message and flip data to the tty (ldisc) */ 221 /* receive an iucv message and flip data to the tty (ldisc) */
229 rb = list_first_entry(&priv->tty_inqueue, struct iucv_tty_buffer, list); 222 rb = list_first_entry(&priv->tty_inqueue, struct iucv_tty_buffer, list);
230 223
231 written = 0; 224 written = 0;
@@ -268,7 +261,7 @@ static int hvc_iucv_write(struct hvc_iucv_private *priv,
268 case MSG_TYPE_WINSIZE: 261 case MSG_TYPE_WINSIZE:
269 if (rb->mbuf->datalen != sizeof(struct winsize)) 262 if (rb->mbuf->datalen != sizeof(struct winsize))
270 break; 263 break;
271 hvc_resize(priv->hvc, *((struct winsize *)rb->mbuf->data)); 264 hvc_resize(priv->hvc, *((struct winsize *) rb->mbuf->data));
272 break; 265 break;
273 266
274 case MSG_TYPE_ERROR: /* ignored ... */ 267 case MSG_TYPE_ERROR: /* ignored ... */
@@ -292,10 +285,9 @@ out_written:
292 * @buf: Pointer to a buffer to store data 285 * @buf: Pointer to a buffer to store data
293 * @count: Size of buffer available for writing 286 * @count: Size of buffer available for writing
294 * 287 *
295 * The hvc_console thread calls this method to read characters from 288 * The HVC thread calls this method to read characters from the back-end.
296 * the terminal backend. If an IUCV communication path has been established, 289 * If an IUCV communication path has been established, pending IUCV messages
297 * pending IUCV messages are received and data is copied into buffer @buf 290 * are received and data is copied into buffer @buf up to @count bytes.
298 * up to @count bytes.
299 * 291 *
300 * Locking: The routine gets called under an irqsave() spinlock; and 292 * Locking: The routine gets called under an irqsave() spinlock; and
301 * the routine locks the struct hvc_iucv_private->lock to call 293 * the routine locks the struct hvc_iucv_private->lock to call
@@ -332,17 +324,17 @@ static int hvc_iucv_get_chars(uint32_t vtermno, char *buf, int count)
332 * @count: Size of buffer and amount of data to send. 324 * @count: Size of buffer and amount of data to send.
333 * 325 *
334 * The function queues data for sending. To actually send the buffered data, 326 * The function queues data for sending. To actually send the buffered data,
335 * a work queue function is * scheduled (with QUEUE_SNDBUF_DELAY). 327 * a work queue function is scheduled (with QUEUE_SNDBUF_DELAY).
336 * The function returns the number of data bytes that has been buffered. 328 * The function returns the number of data bytes that has been buffered.
337 * 329 *
338 * If the device is not connected, data is ignored and the function returns 330 * If the device is not connected, data is ignored and the function returns
339 * @count. 331 * @count.
340 * If the buffer is full, the function returns 0. 332 * If the buffer is full, the function returns 0.
341 * If an existing IUCV communicaton path has been severed, the function returns 333 * If an existing IUCV communicaton path has been severed, -EPIPE is returned
342 * -EPIPE (can be passed to HVC layer to cause a tty hangup). 334 * (that can be passed to HVC layer to cause a tty hangup).
343 */ 335 */
344static int hvc_iucv_queue(struct hvc_iucv_private *priv, const char *buf, 336static int hvc_iucv_queue(struct hvc_iucv_private *priv, const char *buf,
345 int count) 337 int count)
346{ 338{
347 size_t len; 339 size_t len;
348 340
@@ -369,12 +361,10 @@ static int hvc_iucv_queue(struct hvc_iucv_private *priv, const char *buf,
369 * hvc_iucv_send() - Send an IUCV message containing terminal data. 361 * hvc_iucv_send() - Send an IUCV message containing terminal data.
370 * @priv: Pointer to struct hvc_iucv_private instance. 362 * @priv: Pointer to struct hvc_iucv_private instance.
371 * 363 *
372 * If an IUCV communication path has been established, the queued data 364 * If an IUCV communication path has been established, the buffered output data
373 * for output are sent via an IUCV message. 365 * is sent via an IUCV message and the number of bytes sent is returned.
374 * 366 * Returns 0 if there is no established IUCV communication path or
375 * If there is no IUCV communication path established, the function returns 0. 367 * -EPIPE if an existing IUCV communicaton path has been severed.
376 * If an existing IUCV communicaton path has been severed, the function returns
377 * -EPIPE.
378 */ 368 */
379static int hvc_iucv_send(struct hvc_iucv_private *priv) 369static int hvc_iucv_send(struct hvc_iucv_private *priv)
380{ 370{
@@ -420,15 +410,14 @@ static int hvc_iucv_send(struct hvc_iucv_private *priv)
420 * hvc_iucv_sndbuf_work() - Send buffered data over IUCV 410 * hvc_iucv_sndbuf_work() - Send buffered data over IUCV
421 * @work: Work structure. 411 * @work: Work structure.
422 * 412 *
423 * The function sends buffered output data over IUCV and, if necessary, 413 * This work queue function sends buffered output data over IUCV and,
424 * reschedules itself if not all buffered data could be sent. 414 * if not all buffered data could be sent, reschedules itself.
425 */ 415 */
426static void hvc_iucv_sndbuf_work(struct work_struct *work) 416static void hvc_iucv_sndbuf_work(struct work_struct *work)
427{ 417{
428 struct hvc_iucv_private *priv; 418 struct hvc_iucv_private *priv;
429 419
430 priv = container_of(work, struct hvc_iucv_private, sndbuf_work.work); 420 priv = container_of(work, struct hvc_iucv_private, sndbuf_work.work);
431
432 if (!priv) 421 if (!priv)
433 return; 422 return;
434 423
@@ -443,10 +432,8 @@ static void hvc_iucv_sndbuf_work(struct work_struct *work)
443 * @buf: Pointer to an buffer to read data from 432 * @buf: Pointer to an buffer to read data from
444 * @count: Size of buffer available for reading 433 * @count: Size of buffer available for reading
445 * 434 *
446 * The hvc_console thread calls this method to write characters from 435 * The HVC thread calls this method to write characters to the back-end.
447 * to the terminal backend. 436 * The function calls hvc_iucv_queue() to queue terminal data for sending.
448 * The function calls hvc_iucv_send() under the lock of the
449 * struct hvc_iucv_private instance that corresponds to the tty @vtermno.
450 * 437 *
451 * Locking: The method gets called under an irqsave() spinlock; and 438 * Locking: The method gets called under an irqsave() spinlock; and
452 * locks struct hvc_iucv_private->lock. 439 * locks struct hvc_iucv_private->lock.
@@ -496,12 +483,8 @@ static int hvc_iucv_notifier_add(struct hvc_struct *hp, int id)
496} 483}
497 484
498/** 485/**
499 * hvc_iucv_cleanup() - Clean up function if the tty portion is finally closed. 486 * hvc_iucv_cleanup() - Clean up and reset a z/VM IUCV HVC instance.
500 * @priv: Pointer to the struct hvc_iucv_private instance. 487 * @priv: Pointer to the struct hvc_iucv_private instance.
501 *
502 * The functions severs the established IUCV communication path (if any), and
503 * destroy struct iucv_tty_buffer elements from the in- and outqueue. Finally,
504 * the functions resets the states to TTY_CLOSED and IUCV_DISCONN.
505 */ 488 */
506static void hvc_iucv_cleanup(struct hvc_iucv_private *priv) 489static void hvc_iucv_cleanup(struct hvc_iucv_private *priv)
507{ 490{
@@ -553,22 +536,19 @@ static void flush_sndbuf_sync(struct hvc_iucv_private *priv)
553} 536}
554 537
555/** 538/**
556 * hvc_iucv_notifier_hangup() - HVC notifier for tty hangups. 539 * hvc_iucv_notifier_hangup() - HVC notifier for TTY hangups.
557 * @hp: Pointer to the HVC device (struct hvc_struct) 540 * @hp: Pointer to the HVC device (struct hvc_struct)
558 * @id: Additional data (originally passed to hvc_alloc): the index of an struct 541 * @id: Additional data (originally passed to hvc_alloc):
559 * hvc_iucv_private instance. 542 * the index of an struct hvc_iucv_private instance.
560 * 543 *
561 * This routine notifies the HVC backend that a tty hangup (carrier loss, 544 * This routine notifies the HVC back-end that a tty hangup (carrier loss,
562 * virtual or otherwise) has occured. 545 * virtual or otherwise) has occured.
563 * 546 * The z/VM IUCV HVC device driver ignores virtual hangups (vhangup())
564 * The HVC backend for z/VM IUCV ignores virtual hangups (vhangup()), to keep 547 * to keep an existing IUCV communication path established.
565 * an existing IUCV communication path established.
566 * (Background: vhangup() is called from user space (by getty or login) to 548 * (Background: vhangup() is called from user space (by getty or login) to
567 * disable writing to the tty by other applications). 549 * disable writing to the tty by other applications).
568 * 550 * If the tty has been opened and an established IUCV path has been severed
569 * If the tty has been opened (e.g. getty) and an established IUCV path has been 551 * (we caused the tty hangup), the function calls hvc_iucv_cleanup().
570 * severed (we caused the tty hangup in that case), then the functions invokes
571 * hvc_iucv_cleanup() to clean up.
572 * 552 *
573 * Locking: struct hvc_iucv_private->lock 553 * Locking: struct hvc_iucv_private->lock
574 */ 554 */
@@ -584,10 +564,8 @@ static void hvc_iucv_notifier_hangup(struct hvc_struct *hp, int id)
584 564
585 spin_lock_bh(&priv->lock); 565 spin_lock_bh(&priv->lock);
586 /* NOTE: If the hangup was scheduled by ourself (from the iucv 566 /* NOTE: If the hangup was scheduled by ourself (from the iucv
587 * path_servered callback [IUCV_SEVERED]), then we have to 567 * path_servered callback [IUCV_SEVERED]), we have to clean up
588 * finally clean up the tty backend structure and set state to 568 * our structure and to set state to TTY_CLOSED.
589 * TTY_CLOSED.
590 *
591 * If the tty was hung up otherwise (e.g. vhangup()), then we 569 * If the tty was hung up otherwise (e.g. vhangup()), then we
592 * ignore this hangup and keep an established IUCV path open... 570 * ignore this hangup and keep an established IUCV path open...
593 * (...the reason is that we are not able to connect back to the 571 * (...the reason is that we are not able to connect back to the
@@ -605,10 +583,9 @@ static void hvc_iucv_notifier_hangup(struct hvc_struct *hp, int id)
605 * @id: Additional data (originally passed to hvc_alloc): 583 * @id: Additional data (originally passed to hvc_alloc):
606 * the index of an struct hvc_iucv_private instance. 584 * the index of an struct hvc_iucv_private instance.
607 * 585 *
608 * This routine notifies the HVC backend that the last tty device file 586 * This routine notifies the HVC back-end that the last tty device fd has been
609 * descriptor has been closed. 587 * closed. The function calls hvc_iucv_cleanup() to clean up the struct
610 * The function calls hvc_iucv_cleanup() to clean up the struct hvc_iucv_private 588 * hvc_iucv_private instance.
611 * instance.
612 * 589 *
613 * Locking: struct hvc_iucv_private->lock 590 * Locking: struct hvc_iucv_private->lock
614 */ 591 */
@@ -640,20 +617,18 @@ static void hvc_iucv_notifier_del(struct hvc_struct *hp, int id)
640/** 617/**
641 * hvc_iucv_path_pending() - IUCV handler to process a connection request. 618 * hvc_iucv_path_pending() - IUCV handler to process a connection request.
642 * @path: Pending path (struct iucv_path) 619 * @path: Pending path (struct iucv_path)
643 * @ipvmid: Originator z/VM system identifier 620 * @ipvmid: z/VM system identifier of originator
644 * @ipuser: User specified data for this path 621 * @ipuser: User specified data for this path
645 * (AF_IUCV: port/service name and originator port) 622 * (AF_IUCV: port/service name and originator port)
646 * 623 *
647 * The function uses the @ipuser data to check to determine if the pending 624 * The function uses the @ipuser data to determine if the pending path belongs
648 * path belongs to a terminal managed by this HVC backend. 625 * to a terminal managed by this device driver.
649 * If the check is successful, then an additional check is done to ensure 626 * If the path belongs to this driver, ensure that the terminal is not accessed
650 * that a terminal cannot be accessed multiple times (only one connection 627 * multiple times (only one connection to a terminal is allowed).
651 * to a terminal is allowed). In that particular case, the pending path is 628 * If the terminal is not yet connected, the pending path is accepted and is
652 * severed. If it is the first connection, the pending path is accepted and 629 * associated to the appropriate struct hvc_iucv_private instance.
653 * associated to the struct hvc_iucv_private. The iucv state is updated to
654 * reflect that a communication path has been established.
655 * 630 *
656 * Returns 0 if the path belongs to a terminal managed by the this HVC backend; 631 * Returns 0 if @path belongs to a terminal managed by the this device driver;
657 * otherwise returns -ENODEV in order to dispatch this path to other handlers. 632 * otherwise returns -ENODEV in order to dispatch this path to other handlers.
658 * 633 *
659 * Locking: struct hvc_iucv_private->lock 634 * Locking: struct hvc_iucv_private->lock
@@ -672,7 +647,6 @@ static int hvc_iucv_path_pending(struct iucv_path *path,
672 priv = hvc_iucv_table[i]; 647 priv = hvc_iucv_table[i];
673 break; 648 break;
674 } 649 }
675
676 if (!priv) 650 if (!priv)
677 return -ENODEV; 651 return -ENODEV;
678 652
@@ -719,8 +693,7 @@ out_path_handled:
719 * sets the iucv state to IUCV_SEVERED for the associated struct 693 * sets the iucv state to IUCV_SEVERED for the associated struct
720 * hvc_iucv_private instance. Later, the IUCV_SEVERED state triggers a tty 694 * hvc_iucv_private instance. Later, the IUCV_SEVERED state triggers a tty
721 * hangup (hvc_iucv_get_chars() / hvc_iucv_write()). 695 * hangup (hvc_iucv_get_chars() / hvc_iucv_write()).
722 * 696 * If tty portion of the HVC is closed, clean up the outqueue.
723 * If tty portion of the HVC is closed then clean up the outqueue in addition.
724 * 697 *
725 * Locking: struct hvc_iucv_private->lock 698 * Locking: struct hvc_iucv_private->lock
726 */ 699 */
@@ -755,9 +728,9 @@ static void hvc_iucv_path_severed(struct iucv_path *path, u8 ipuser[16])
755 * @path: Pending path (struct iucv_path) 728 * @path: Pending path (struct iucv_path)
756 * @msg: Pointer to the IUCV message 729 * @msg: Pointer to the IUCV message
757 * 730 *
758 * The function stores an incoming message on the input queue for later 731 * The function puts an incoming message on the input queue for later
759 * processing (by hvc_iucv_get_chars() / hvc_iucv_write()). 732 * processing (by hvc_iucv_get_chars() / hvc_iucv_write()).
760 * However, if the tty has not yet been opened, the message is rejected. 733 * If the tty has not yet been opened, the message is rejected.
761 * 734 *
762 * Locking: struct hvc_iucv_private->lock 735 * Locking: struct hvc_iucv_private->lock
763 */ 736 */
@@ -773,6 +746,7 @@ static void hvc_iucv_msg_pending(struct iucv_path *path,
773 return; 746 return;
774 } 747 }
775 748
749
776 spin_lock(&priv->lock); 750 spin_lock(&priv->lock);
777 751
778 /* reject messages if tty has not yet been opened */ 752 /* reject messages if tty has not yet been opened */
@@ -791,7 +765,7 @@ static void hvc_iucv_msg_pending(struct iucv_path *path,
791 765
792 list_add_tail(&rb->list, &priv->tty_inqueue); 766 list_add_tail(&rb->list, &priv->tty_inqueue);
793 767
794 hvc_kick(); /* wake up hvc console thread */ 768 hvc_kick(); /* wake up hvc thread */
795 769
796unlock_return: 770unlock_return:
797 spin_unlock(&priv->lock); 771 spin_unlock(&priv->lock);
@@ -802,10 +776,10 @@ unlock_return:
802 * @path: Pending path (struct iucv_path) 776 * @path: Pending path (struct iucv_path)
803 * @msg: Pointer to the IUCV message 777 * @msg: Pointer to the IUCV message
804 * 778 *
805 * The function is called upon completion of message delivery and the 779 * The function is called upon completion of message delivery to remove the
806 * message is removed from the outqueue. Additional delivery information 780 * message from the outqueue. Additional delivery information can be found
807 * can be found in msg->audit: rejected messages (0x040000 (IPADRJCT)) and 781 * msg->audit: rejected messages (0x040000 (IPADRJCT)), and
808 * purged messages (0x010000 (IPADPGNR)). 782 * purged messages (0x010000 (IPADPGNR)).
809 * 783 *
810 * Locking: struct hvc_iucv_private->lock 784 * Locking: struct hvc_iucv_private->lock
811 */ 785 */
@@ -841,8 +815,8 @@ static struct hv_ops hvc_iucv_ops = {
841 * hvc_iucv_alloc() - Allocates a new struct hvc_iucv_private instance 815 * hvc_iucv_alloc() - Allocates a new struct hvc_iucv_private instance
842 * @id: hvc_iucv_table index 816 * @id: hvc_iucv_table index
843 * 817 *
844 * This function allocates a new hvc_iucv_private struct and put the 818 * This function allocates a new hvc_iucv_private structure and stores
845 * instance into hvc_iucv_table at index @id. 819 * the instance in hvc_iucv_table at index @id.
846 * Returns 0 on success; otherwise non-zero. 820 * Returns 0 on success; otherwise non-zero.
847 */ 821 */
848static int __init hvc_iucv_alloc(int id) 822static int __init hvc_iucv_alloc(int id)
@@ -867,7 +841,7 @@ static int __init hvc_iucv_alloc(int id)
867 return -ENOMEM; 841 return -ENOMEM;
868 } 842 }
869 843
870 /* Finally allocate hvc */ 844 /* finally allocate hvc */
871 priv->hvc = hvc_alloc(HVC_IUCV_MAGIC + id, /* PAGE_SIZE */ 845 priv->hvc = hvc_alloc(HVC_IUCV_MAGIC + id, /* PAGE_SIZE */
872 HVC_IUCV_MAGIC + id, &hvc_iucv_ops, 256); 846 HVC_IUCV_MAGIC + id, &hvc_iucv_ops, 256);
873 if (IS_ERR(priv->hvc)) { 847 if (IS_ERR(priv->hvc)) {
@@ -877,7 +851,7 @@ static int __init hvc_iucv_alloc(int id)
877 return rc; 851 return rc;
878 } 852 }
879 853
880 /* kick khvcd thread; instead of using polling */ 854 /* notify HVC thread instead of using polling */
881 priv->hvc->irq_requested = 1; 855 priv->hvc->irq_requested = 1;
882 856
883 /* setup iucv related information */ 857 /* setup iucv related information */
@@ -890,7 +864,7 @@ static int __init hvc_iucv_alloc(int id)
890} 864}
891 865
892/** 866/**
893 * hvc_iucv_init() - Initialization of HVC backend for z/VM IUCV 867 * hvc_iucv_init() - z/VM IUCV HVC device driver initialization
894 */ 868 */
895static int __init hvc_iucv_init(void) 869static int __init hvc_iucv_init(void)
896{ 870{
@@ -929,7 +903,7 @@ static int __init hvc_iucv_init(void)
929 rc = hvc_iucv_alloc(i); 903 rc = hvc_iucv_alloc(i);
930 if (rc) { 904 if (rc) {
931 pr_err("Creating a new HVC terminal device " 905 pr_err("Creating a new HVC terminal device "
932 "failed with error code=%d\n", rc); 906 "failed with error code=%d\n", rc);
933 goto out_error_hvc; 907 goto out_error_hvc;
934 } 908 }
935 } 909 }