hvc_iucv.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970
  1. /*
  2. * hvc_iucv.c - z/VM IUCV hypervisor console (HVC) device driver
  3. *
  4. * This HVC device driver provides terminal access using
  5. * z/VM IUCV communication paths.
  6. *
  7. * Copyright IBM Corp. 2008
  8. *
  9. * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
  10. */
  11. #define KMSG_COMPONENT "hvc_iucv"
  12. #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
  13. #include <linux/types.h>
  14. #include <asm/ebcdic.h>
  15. #include <linux/delay.h>
  16. #include <linux/init.h>
  17. #include <linux/mempool.h>
  18. #include <linux/module.h>
  19. #include <linux/tty.h>
  20. #include <linux/wait.h>
  21. #include <net/iucv/iucv.h>
  22. #include "hvc_console.h"
  23. /* General device driver settings */
  24. #define HVC_IUCV_MAGIC 0xc9e4c3e5
  25. #define MAX_HVC_IUCV_LINES HVC_ALLOC_TTY_ADAPTERS
  26. #define MEMPOOL_MIN_NR (PAGE_SIZE / sizeof(struct iucv_tty_buffer)/4)
  27. /* IUCV TTY message */
  28. #define MSG_VERSION 0x02 /* Message version */
  29. #define MSG_TYPE_ERROR 0x01 /* Error message */
  30. #define MSG_TYPE_TERMENV 0x02 /* Terminal environment variable */
  31. #define MSG_TYPE_TERMIOS 0x04 /* Terminal IO struct update */
  32. #define MSG_TYPE_WINSIZE 0x08 /* Terminal window size update */
  33. #define MSG_TYPE_DATA 0x10 /* Terminal data */
  34. struct iucv_tty_msg {
  35. u8 version; /* Message version */
  36. u8 type; /* Message type */
  37. #define MSG_MAX_DATALEN ((u16)(~0))
  38. u16 datalen; /* Payload length */
  39. u8 data[]; /* Payload buffer */
  40. } __attribute__((packed));
  41. #define MSG_SIZE(s) ((s) + offsetof(struct iucv_tty_msg, data))
  42. enum iucv_state_t {
  43. IUCV_DISCONN = 0,
  44. IUCV_CONNECTED = 1,
  45. IUCV_SEVERED = 2,
  46. };
  47. enum tty_state_t {
  48. TTY_CLOSED = 0,
  49. TTY_OPENED = 1,
  50. };
  51. struct hvc_iucv_private {
  52. struct hvc_struct *hvc; /* HVC struct reference */
  53. u8 srv_name[8]; /* IUCV service name (ebcdic) */
  54. unsigned char is_console; /* Linux console usage flag */
  55. enum iucv_state_t iucv_state; /* IUCV connection status */
  56. enum tty_state_t tty_state; /* TTY status */
  57. struct iucv_path *path; /* IUCV path pointer */
  58. spinlock_t lock; /* hvc_iucv_private lock */
  59. #define SNDBUF_SIZE (PAGE_SIZE) /* must be < MSG_MAX_DATALEN */
  60. void *sndbuf; /* send buffer */
  61. size_t sndbuf_len; /* length of send buffer */
  62. #define QUEUE_SNDBUF_DELAY (HZ / 25)
  63. struct delayed_work sndbuf_work; /* work: send iucv msg(s) */
  64. wait_queue_head_t sndbuf_waitq; /* wait for send completion */
  65. struct list_head tty_outqueue; /* outgoing IUCV messages */
  66. struct list_head tty_inqueue; /* incoming IUCV messages */
  67. };
  68. struct iucv_tty_buffer {
  69. struct list_head list; /* list pointer */
  70. struct iucv_message msg; /* store an IUCV message */
  71. size_t offset; /* data buffer offset */
  72. struct iucv_tty_msg *mbuf; /* buffer to store input/output data */
  73. };
  74. /* IUCV callback handler */
  75. static int hvc_iucv_path_pending(struct iucv_path *, u8[8], u8[16]);
  76. static void hvc_iucv_path_severed(struct iucv_path *, u8[16]);
  77. static void hvc_iucv_msg_pending(struct iucv_path *, struct iucv_message *);
  78. static void hvc_iucv_msg_complete(struct iucv_path *, struct iucv_message *);
  79. /* Kernel module parameter: use one terminal device as default */
  80. static unsigned long hvc_iucv_devices = 1;
  81. /* Array of allocated hvc iucv tty lines... */
  82. static struct hvc_iucv_private *hvc_iucv_table[MAX_HVC_IUCV_LINES];
  83. #define IUCV_HVC_CON_IDX (0)
  84. /* Kmem cache and mempool for iucv_tty_buffer elements */
  85. static struct kmem_cache *hvc_iucv_buffer_cache;
  86. static mempool_t *hvc_iucv_mempool;
  87. /* IUCV handler callback functions */
  88. static struct iucv_handler hvc_iucv_handler = {
  89. .path_pending = hvc_iucv_path_pending,
  90. .path_severed = hvc_iucv_path_severed,
  91. .message_complete = hvc_iucv_msg_complete,
  92. .message_pending = hvc_iucv_msg_pending,
  93. };
  94. /**
  95. * hvc_iucv_get_private() - Return a struct hvc_iucv_private instance.
  96. * @num: The HVC virtual terminal number (vtermno)
  97. *
  98. * This function returns the struct hvc_iucv_private instance that corresponds
  99. * to the HVC virtual terminal number specified as parameter @num.
  100. */
  101. struct hvc_iucv_private *hvc_iucv_get_private(uint32_t num)
  102. {
  103. if ((num < HVC_IUCV_MAGIC) || (num - HVC_IUCV_MAGIC > hvc_iucv_devices))
  104. return NULL;
  105. return hvc_iucv_table[num - HVC_IUCV_MAGIC];
  106. }
  107. /**
  108. * alloc_tty_buffer() - Return a new struct iucv_tty_buffer element.
  109. * @size: Size of the internal buffer used to store data.
  110. * @flags: Memory allocation flags passed to mempool.
  111. *
  112. * This function allocates a new struct iucv_tty_buffer element and, optionally,
  113. * allocates an internal data buffer with the specified size @size.
  114. * Note: The total message size arises from the internal buffer size and the
  115. * members of the iucv_tty_msg structure.
  116. * The function returns NULL if memory allocation has failed.
  117. */
  118. static struct iucv_tty_buffer *alloc_tty_buffer(size_t size, gfp_t flags)
  119. {
  120. struct iucv_tty_buffer *bufp;
  121. bufp = mempool_alloc(hvc_iucv_mempool, flags);
  122. if (!bufp)
  123. return NULL;
  124. memset(bufp, 0, sizeof(*bufp));
  125. if (size > 0) {
  126. bufp->msg.length = MSG_SIZE(size);
  127. bufp->mbuf = kmalloc(bufp->msg.length, flags);
  128. if (!bufp->mbuf) {
  129. mempool_free(bufp, hvc_iucv_mempool);
  130. return NULL;
  131. }
  132. bufp->mbuf->version = MSG_VERSION;
  133. bufp->mbuf->type = MSG_TYPE_DATA;
  134. bufp->mbuf->datalen = (u16) size;
  135. }
  136. return bufp;
  137. }
  138. /**
  139. * destroy_tty_buffer() - destroy struct iucv_tty_buffer element.
  140. * @bufp: Pointer to a struct iucv_tty_buffer element, SHALL NOT be NULL.
  141. */
  142. static void destroy_tty_buffer(struct iucv_tty_buffer *bufp)
  143. {
  144. kfree(bufp->mbuf);
  145. mempool_free(bufp, hvc_iucv_mempool);
  146. }
  147. /**
  148. * destroy_tty_buffer_list() - call destroy_tty_buffer() for each list element.
  149. * @list: List containing struct iucv_tty_buffer elements.
  150. */
  151. static void destroy_tty_buffer_list(struct list_head *list)
  152. {
  153. struct iucv_tty_buffer *ent, *next;
  154. list_for_each_entry_safe(ent, next, list, list) {
  155. list_del(&ent->list);
  156. destroy_tty_buffer(ent);
  157. }
  158. }
  159. /**
  160. * hvc_iucv_write() - Receive IUCV message & write data to HVC buffer.
  161. * @priv: Pointer to struct hvc_iucv_private
  162. * @buf: HVC buffer for writing received terminal data.
  163. * @count: HVC buffer size.
  164. * @has_more_data: Pointer to an int variable.
  165. *
  166. * The function picks up pending messages from the input queue and receives
  167. * the message data that is then written to the specified buffer @buf.
  168. * If the buffer size @count is less than the data message size, the
  169. * message is kept on the input queue and @has_more_data is set to 1.
  170. * If all message data has been written, the message is removed from
  171. * the input queue.
  172. *
  173. * The function returns the number of bytes written to the terminal, zero if
  174. * there are no pending data messages available or if there is no established
  175. * IUCV path.
  176. * If the IUCV path has been severed, then -EPIPE is returned to cause a
  177. * hang up (that is issued by the HVC layer).
  178. */
  179. static int hvc_iucv_write(struct hvc_iucv_private *priv,
  180. char *buf, int count, int *has_more_data)
  181. {
  182. struct iucv_tty_buffer *rb;
  183. int written;
  184. int rc;
  185. /* immediately return if there is no IUCV connection */
  186. if (priv->iucv_state == IUCV_DISCONN)
  187. return 0;
  188. /* if the IUCV path has been severed, return -EPIPE to inform the
  189. * HVC layer to hang up the tty device. */
  190. if (priv->iucv_state == IUCV_SEVERED)
  191. return -EPIPE;
  192. /* check if there are pending messages */
  193. if (list_empty(&priv->tty_inqueue))
  194. return 0;
  195. /* receive an iucv message and flip data to the tty (ldisc) */
  196. rb = list_first_entry(&priv->tty_inqueue, struct iucv_tty_buffer, list);
  197. written = 0;
  198. if (!rb->mbuf) { /* message not yet received ... */
  199. /* allocate mem to store msg data; if no memory is available
  200. * then leave the buffer on the list and re-try later */
  201. rb->mbuf = kmalloc(rb->msg.length, GFP_ATOMIC);
  202. if (!rb->mbuf)
  203. return -ENOMEM;
  204. rc = __iucv_message_receive(priv->path, &rb->msg, 0,
  205. rb->mbuf, rb->msg.length, NULL);
  206. switch (rc) {
  207. case 0: /* Successful */
  208. break;
  209. case 2: /* No message found */
  210. case 9: /* Message purged */
  211. break;
  212. default:
  213. written = -EIO;
  214. }
  215. /* remove buffer if an error has occured or received data
  216. * is not correct */
  217. if (rc || (rb->mbuf->version != MSG_VERSION) ||
  218. (rb->msg.length != MSG_SIZE(rb->mbuf->datalen)))
  219. goto out_remove_buffer;
  220. }
  221. switch (rb->mbuf->type) {
  222. case MSG_TYPE_DATA:
  223. written = min_t(int, rb->mbuf->datalen - rb->offset, count);
  224. memcpy(buf, rb->mbuf->data + rb->offset, written);
  225. if (written < (rb->mbuf->datalen - rb->offset)) {
  226. rb->offset += written;
  227. *has_more_data = 1;
  228. goto out_written;
  229. }
  230. break;
  231. case MSG_TYPE_WINSIZE:
  232. if (rb->mbuf->datalen != sizeof(struct winsize))
  233. break;
  234. hvc_resize(priv->hvc, *((struct winsize *) rb->mbuf->data));
  235. break;
  236. case MSG_TYPE_ERROR: /* ignored ... */
  237. case MSG_TYPE_TERMENV: /* ignored ... */
  238. case MSG_TYPE_TERMIOS: /* ignored ... */
  239. break;
  240. }
  241. out_remove_buffer:
  242. list_del(&rb->list);
  243. destroy_tty_buffer(rb);
  244. *has_more_data = !list_empty(&priv->tty_inqueue);
  245. out_written:
  246. return written;
  247. }
  248. /**
  249. * hvc_iucv_get_chars() - HVC get_chars operation.
  250. * @vtermno: HVC virtual terminal number.
  251. * @buf: Pointer to a buffer to store data
  252. * @count: Size of buffer available for writing
  253. *
  254. * The HVC thread calls this method to read characters from the back-end.
  255. * If an IUCV communication path has been established, pending IUCV messages
  256. * are received and data is copied into buffer @buf up to @count bytes.
  257. *
  258. * Locking: The routine gets called under an irqsave() spinlock; and
  259. * the routine locks the struct hvc_iucv_private->lock to call
  260. * helper functions.
  261. */
  262. static int hvc_iucv_get_chars(uint32_t vtermno, char *buf, int count)
  263. {
  264. struct hvc_iucv_private *priv = hvc_iucv_get_private(vtermno);
  265. int written;
  266. int has_more_data;
  267. if (count <= 0)
  268. return 0;
  269. if (!priv)
  270. return -ENODEV;
  271. spin_lock(&priv->lock);
  272. has_more_data = 0;
  273. written = hvc_iucv_write(priv, buf, count, &has_more_data);
  274. spin_unlock(&priv->lock);
  275. /* if there are still messages on the queue... schedule another run */
  276. if (has_more_data)
  277. hvc_kick();
  278. return written;
  279. }
  280. /**
  281. * hvc_iucv_queue() - Buffer terminal data for sending.
  282. * @priv: Pointer to struct hvc_iucv_private instance.
  283. * @buf: Buffer containing data to send.
  284. * @count: Size of buffer and amount of data to send.
  285. *
  286. * The function queues data for sending. To actually send the buffered data,
  287. * a work queue function is scheduled (with QUEUE_SNDBUF_DELAY).
  288. * The function returns the number of data bytes that has been buffered.
  289. *
  290. * If the device is not connected, data is ignored and the function returns
  291. * @count.
  292. * If the buffer is full, the function returns 0.
  293. * If an existing IUCV communicaton path has been severed, -EPIPE is returned
  294. * (that can be passed to HVC layer to cause a tty hangup).
  295. */
  296. static int hvc_iucv_queue(struct hvc_iucv_private *priv, const char *buf,
  297. int count)
  298. {
  299. size_t len;
  300. if (priv->iucv_state == IUCV_DISCONN)
  301. return count; /* ignore data */
  302. if (priv->iucv_state == IUCV_SEVERED)
  303. return -EPIPE;
  304. len = min_t(size_t, count, SNDBUF_SIZE - priv->sndbuf_len);
  305. if (!len)
  306. return 0;
  307. memcpy(priv->sndbuf + priv->sndbuf_len, buf, len);
  308. priv->sndbuf_len += len;
  309. if (priv->iucv_state == IUCV_CONNECTED)
  310. schedule_delayed_work(&priv->sndbuf_work, QUEUE_SNDBUF_DELAY);
  311. return len;
  312. }
  313. /**
  314. * hvc_iucv_send() - Send an IUCV message containing terminal data.
  315. * @priv: Pointer to struct hvc_iucv_private instance.
  316. *
  317. * If an IUCV communication path has been established, the buffered output data
  318. * is sent via an IUCV message and the number of bytes sent is returned.
  319. * Returns 0 if there is no established IUCV communication path or
  320. * -EPIPE if an existing IUCV communicaton path has been severed.
  321. */
  322. static int hvc_iucv_send(struct hvc_iucv_private *priv)
  323. {
  324. struct iucv_tty_buffer *sb;
  325. int rc, len;
  326. if (priv->iucv_state == IUCV_SEVERED)
  327. return -EPIPE;
  328. if (priv->iucv_state == IUCV_DISCONN)
  329. return -EIO;
  330. if (!priv->sndbuf_len)
  331. return 0;
  332. /* allocate internal buffer to store msg data and also compute total
  333. * message length */
  334. sb = alloc_tty_buffer(priv->sndbuf_len, GFP_ATOMIC);
  335. if (!sb)
  336. return -ENOMEM;
  337. memcpy(sb->mbuf->data, priv->sndbuf, priv->sndbuf_len);
  338. sb->mbuf->datalen = (u16) priv->sndbuf_len;
  339. sb->msg.length = MSG_SIZE(sb->mbuf->datalen);
  340. list_add_tail(&sb->list, &priv->tty_outqueue);
  341. rc = __iucv_message_send(priv->path, &sb->msg, 0, 0,
  342. (void *) sb->mbuf, sb->msg.length);
  343. if (rc) {
  344. /* drop the message here; however we might want to handle
  345. * 0x03 (msg limit reached) by trying again... */
  346. list_del(&sb->list);
  347. destroy_tty_buffer(sb);
  348. }
  349. len = priv->sndbuf_len;
  350. priv->sndbuf_len = 0;
  351. return len;
  352. }
  353. /**
  354. * hvc_iucv_sndbuf_work() - Send buffered data over IUCV
  355. * @work: Work structure.
  356. *
  357. * This work queue function sends buffered output data over IUCV and,
  358. * if not all buffered data could be sent, reschedules itself.
  359. */
  360. static void hvc_iucv_sndbuf_work(struct work_struct *work)
  361. {
  362. struct hvc_iucv_private *priv;
  363. priv = container_of(work, struct hvc_iucv_private, sndbuf_work.work);
  364. if (!priv)
  365. return;
  366. spin_lock_bh(&priv->lock);
  367. hvc_iucv_send(priv);
  368. spin_unlock_bh(&priv->lock);
  369. }
  370. /**
  371. * hvc_iucv_put_chars() - HVC put_chars operation.
  372. * @vtermno: HVC virtual terminal number.
  373. * @buf: Pointer to an buffer to read data from
  374. * @count: Size of buffer available for reading
  375. *
  376. * The HVC thread calls this method to write characters to the back-end.
  377. * The function calls hvc_iucv_queue() to queue terminal data for sending.
  378. *
  379. * Locking: The method gets called under an irqsave() spinlock; and
  380. * locks struct hvc_iucv_private->lock.
  381. */
  382. static int hvc_iucv_put_chars(uint32_t vtermno, const char *buf, int count)
  383. {
  384. struct hvc_iucv_private *priv = hvc_iucv_get_private(vtermno);
  385. int queued;
  386. if (count <= 0)
  387. return 0;
  388. if (!priv)
  389. return -ENODEV;
  390. spin_lock(&priv->lock);
  391. queued = hvc_iucv_queue(priv, buf, count);
  392. spin_unlock(&priv->lock);
  393. return queued;
  394. }
  395. /**
  396. * hvc_iucv_notifier_add() - HVC notifier for opening a TTY for the first time.
  397. * @hp: Pointer to the HVC device (struct hvc_struct)
  398. * @id: Additional data (originally passed to hvc_alloc): the index of an struct
  399. * hvc_iucv_private instance.
  400. *
  401. * The function sets the tty state to TTY_OPENED for the struct hvc_iucv_private
  402. * instance that is derived from @id. Always returns 0.
  403. *
  404. * Locking: struct hvc_iucv_private->lock, spin_lock_bh
  405. */
  406. static int hvc_iucv_notifier_add(struct hvc_struct *hp, int id)
  407. {
  408. struct hvc_iucv_private *priv;
  409. priv = hvc_iucv_get_private(id);
  410. if (!priv)
  411. return 0;
  412. spin_lock_bh(&priv->lock);
  413. priv->tty_state = TTY_OPENED;
  414. spin_unlock_bh(&priv->lock);
  415. return 0;
  416. }
  417. /**
  418. * hvc_iucv_cleanup() - Clean up and reset a z/VM IUCV HVC instance.
  419. * @priv: Pointer to the struct hvc_iucv_private instance.
  420. */
  421. static void hvc_iucv_cleanup(struct hvc_iucv_private *priv)
  422. {
  423. destroy_tty_buffer_list(&priv->tty_outqueue);
  424. destroy_tty_buffer_list(&priv->tty_inqueue);
  425. priv->tty_state = TTY_CLOSED;
  426. priv->iucv_state = IUCV_DISCONN;
  427. priv->sndbuf_len = 0;
  428. }
  429. /**
  430. * tty_outqueue_empty() - Test if the tty outq is empty
  431. * @priv: Pointer to struct hvc_iucv_private instance.
  432. */
  433. static inline int tty_outqueue_empty(struct hvc_iucv_private *priv)
  434. {
  435. int rc;
  436. spin_lock_bh(&priv->lock);
  437. rc = list_empty(&priv->tty_outqueue);
  438. spin_unlock_bh(&priv->lock);
  439. return rc;
  440. }
  441. /**
  442. * flush_sndbuf_sync() - Flush send buffer and wait for completion
  443. * @priv: Pointer to struct hvc_iucv_private instance.
  444. *
  445. * The routine cancels a pending sndbuf work, calls hvc_iucv_send()
  446. * to flush any buffered terminal output data and waits for completion.
  447. */
  448. static void flush_sndbuf_sync(struct hvc_iucv_private *priv)
  449. {
  450. int sync_wait;
  451. cancel_delayed_work_sync(&priv->sndbuf_work);
  452. spin_lock_bh(&priv->lock);
  453. hvc_iucv_send(priv); /* force sending buffered data */
  454. sync_wait = !list_empty(&priv->tty_outqueue); /* anything queued ? */
  455. spin_unlock_bh(&priv->lock);
  456. if (sync_wait)
  457. wait_event_timeout(priv->sndbuf_waitq,
  458. tty_outqueue_empty(priv), HZ);
  459. }
  460. /**
  461. * hvc_iucv_notifier_hangup() - HVC notifier for TTY hangups.
  462. * @hp: Pointer to the HVC device (struct hvc_struct)
  463. * @id: Additional data (originally passed to hvc_alloc):
  464. * the index of an struct hvc_iucv_private instance.
  465. *
  466. * This routine notifies the HVC back-end that a tty hangup (carrier loss,
  467. * virtual or otherwise) has occured.
  468. * The z/VM IUCV HVC device driver ignores virtual hangups (vhangup())
  469. * to keep an existing IUCV communication path established.
  470. * (Background: vhangup() is called from user space (by getty or login) to
  471. * disable writing to the tty by other applications).
  472. * If the tty has been opened and an established IUCV path has been severed
  473. * (we caused the tty hangup), the function calls hvc_iucv_cleanup().
  474. *
  475. * Locking: struct hvc_iucv_private->lock
  476. */
  477. static void hvc_iucv_notifier_hangup(struct hvc_struct *hp, int id)
  478. {
  479. struct hvc_iucv_private *priv;
  480. priv = hvc_iucv_get_private(id);
  481. if (!priv)
  482. return;
  483. flush_sndbuf_sync(priv);
  484. spin_lock_bh(&priv->lock);
  485. /* NOTE: If the hangup was scheduled by ourself (from the iucv
  486. * path_servered callback [IUCV_SEVERED]), we have to clean up
  487. * our structure and to set state to TTY_CLOSED.
  488. * If the tty was hung up otherwise (e.g. vhangup()), then we
  489. * ignore this hangup and keep an established IUCV path open...
  490. * (...the reason is that we are not able to connect back to the
  491. * client if we disconnect on hang up) */
  492. priv->tty_state = TTY_CLOSED;
  493. if (priv->iucv_state == IUCV_SEVERED)
  494. hvc_iucv_cleanup(priv);
  495. spin_unlock_bh(&priv->lock);
  496. }
  497. /**
  498. * hvc_iucv_notifier_del() - HVC notifier for closing a TTY for the last time.
  499. * @hp: Pointer to the HVC device (struct hvc_struct)
  500. * @id: Additional data (originally passed to hvc_alloc):
  501. * the index of an struct hvc_iucv_private instance.
  502. *
  503. * This routine notifies the HVC back-end that the last tty device fd has been
  504. * closed. The function calls hvc_iucv_cleanup() to clean up the struct
  505. * hvc_iucv_private instance.
  506. *
  507. * Locking: struct hvc_iucv_private->lock
  508. */
  509. static void hvc_iucv_notifier_del(struct hvc_struct *hp, int id)
  510. {
  511. struct hvc_iucv_private *priv;
  512. struct iucv_path *path;
  513. priv = hvc_iucv_get_private(id);
  514. if (!priv)
  515. return;
  516. flush_sndbuf_sync(priv);
  517. spin_lock_bh(&priv->lock);
  518. path = priv->path; /* save reference to IUCV path */
  519. priv->path = NULL;
  520. hvc_iucv_cleanup(priv);
  521. spin_unlock_bh(&priv->lock);
  522. /* sever IUCV path outside of priv->lock due to lock ordering of:
  523. * priv->lock <--> iucv_table_lock */
  524. if (path) {
  525. iucv_path_sever(path, NULL);
  526. iucv_path_free(path);
  527. }
  528. }
  529. /**
  530. * hvc_iucv_path_pending() - IUCV handler to process a connection request.
  531. * @path: Pending path (struct iucv_path)
  532. * @ipvmid: z/VM system identifier of originator
  533. * @ipuser: User specified data for this path
  534. * (AF_IUCV: port/service name and originator port)
  535. *
  536. * The function uses the @ipuser data to determine if the pending path belongs
  537. * to a terminal managed by this device driver.
  538. * If the path belongs to this driver, ensure that the terminal is not accessed
  539. * multiple times (only one connection to a terminal is allowed).
  540. * If the terminal is not yet connected, the pending path is accepted and is
  541. * associated to the appropriate struct hvc_iucv_private instance.
  542. *
  543. * Returns 0 if @path belongs to a terminal managed by the this device driver;
  544. * otherwise returns -ENODEV in order to dispatch this path to other handlers.
  545. *
  546. * Locking: struct hvc_iucv_private->lock
  547. */
  548. static int hvc_iucv_path_pending(struct iucv_path *path,
  549. u8 ipvmid[8], u8 ipuser[16])
  550. {
  551. struct hvc_iucv_private *priv;
  552. u8 nuser_data[16];
  553. int i, rc;
  554. priv = NULL;
  555. for (i = 0; i < hvc_iucv_devices; i++)
  556. if (hvc_iucv_table[i] &&
  557. (0 == memcmp(hvc_iucv_table[i]->srv_name, ipuser, 8))) {
  558. priv = hvc_iucv_table[i];
  559. break;
  560. }
  561. if (!priv)
  562. return -ENODEV;
  563. spin_lock(&priv->lock);
  564. /* If the terminal is already connected or being severed, then sever
  565. * this path to enforce that there is only ONE established communication
  566. * path per terminal. */
  567. if (priv->iucv_state != IUCV_DISCONN) {
  568. iucv_path_sever(path, ipuser);
  569. iucv_path_free(path);
  570. goto out_path_handled;
  571. }
  572. /* accept path */
  573. memcpy(nuser_data, ipuser + 8, 8); /* remote service (for af_iucv) */
  574. memcpy(nuser_data + 8, ipuser, 8); /* local service (for af_iucv) */
  575. path->msglim = 0xffff; /* IUCV MSGLIMIT */
  576. path->flags &= ~IUCV_IPRMDATA; /* TODO: use IUCV_IPRMDATA */
  577. rc = iucv_path_accept(path, &hvc_iucv_handler, nuser_data, priv);
  578. if (rc) {
  579. iucv_path_sever(path, ipuser);
  580. iucv_path_free(path);
  581. goto out_path_handled;
  582. }
  583. priv->path = path;
  584. priv->iucv_state = IUCV_CONNECTED;
  585. /* flush buffered output data... */
  586. schedule_delayed_work(&priv->sndbuf_work, 5);
  587. out_path_handled:
  588. spin_unlock(&priv->lock);
  589. return 0;
  590. }
  591. /**
  592. * hvc_iucv_path_severed() - IUCV handler to process a path sever.
  593. * @path: Pending path (struct iucv_path)
  594. * @ipuser: User specified data for this path
  595. * (AF_IUCV: port/service name and originator port)
  596. *
  597. * The function also severs the path (as required by the IUCV protocol) and
  598. * sets the iucv state to IUCV_SEVERED for the associated struct
  599. * hvc_iucv_private instance. Later, the IUCV_SEVERED state triggers a tty
  600. * hangup (hvc_iucv_get_chars() / hvc_iucv_write()).
  601. * If tty portion of the HVC is closed, clean up the outqueue.
  602. *
  603. * Locking: struct hvc_iucv_private->lock
  604. */
  605. static void hvc_iucv_path_severed(struct iucv_path *path, u8 ipuser[16])
  606. {
  607. struct hvc_iucv_private *priv = path->private;
  608. spin_lock(&priv->lock);
  609. priv->iucv_state = IUCV_SEVERED;
  610. /* If the tty has not yet been opened, clean up the hvc_iucv_private
  611. * structure to allow re-connects.
  612. * This is also done for our console device because console hangups
  613. * are handled specially and no notifier is called by HVC.
  614. * The tty session is active (TTY_OPEN) and ready for re-connects...
  615. *
  616. * If it has been opened, let get_chars() return -EPIPE to signal the
  617. * HVC layer to hang up the tty.
  618. * If so, we need to wake up the HVC thread to call get_chars()...
  619. */
  620. priv->path = NULL;
  621. if (priv->tty_state == TTY_CLOSED)
  622. hvc_iucv_cleanup(priv);
  623. else
  624. if (priv->is_console) {
  625. hvc_iucv_cleanup(priv);
  626. priv->tty_state = TTY_OPENED;
  627. } else
  628. hvc_kick();
  629. spin_unlock(&priv->lock);
  630. /* finally sever path (outside of priv->lock due to lock ordering) */
  631. iucv_path_sever(path, ipuser);
  632. iucv_path_free(path);
  633. }
  634. /**
  635. * hvc_iucv_msg_pending() - IUCV handler to process an incoming IUCV message.
  636. * @path: Pending path (struct iucv_path)
  637. * @msg: Pointer to the IUCV message
  638. *
  639. * The function puts an incoming message on the input queue for later
  640. * processing (by hvc_iucv_get_chars() / hvc_iucv_write()).
  641. * If the tty has not yet been opened, the message is rejected.
  642. *
  643. * Locking: struct hvc_iucv_private->lock
  644. */
  645. static void hvc_iucv_msg_pending(struct iucv_path *path,
  646. struct iucv_message *msg)
  647. {
  648. struct hvc_iucv_private *priv = path->private;
  649. struct iucv_tty_buffer *rb;
  650. /* reject messages that exceed max size of iucv_tty_msg->datalen */
  651. if (msg->length > MSG_SIZE(MSG_MAX_DATALEN)) {
  652. iucv_message_reject(path, msg);
  653. return;
  654. }
  655. spin_lock(&priv->lock);
  656. /* reject messages if tty has not yet been opened */
  657. if (priv->tty_state == TTY_CLOSED) {
  658. iucv_message_reject(path, msg);
  659. goto unlock_return;
  660. }
  661. /* allocate tty buffer to save iucv msg only */
  662. rb = alloc_tty_buffer(0, GFP_ATOMIC);
  663. if (!rb) {
  664. iucv_message_reject(path, msg);
  665. goto unlock_return; /* -ENOMEM */
  666. }
  667. rb->msg = *msg;
  668. list_add_tail(&rb->list, &priv->tty_inqueue);
  669. hvc_kick(); /* wake up hvc thread */
  670. unlock_return:
  671. spin_unlock(&priv->lock);
  672. }
  673. /**
  674. * hvc_iucv_msg_complete() - IUCV handler to process message completion
  675. * @path: Pending path (struct iucv_path)
  676. * @msg: Pointer to the IUCV message
  677. *
  678. * The function is called upon completion of message delivery to remove the
  679. * message from the outqueue. Additional delivery information can be found
  680. * msg->audit: rejected messages (0x040000 (IPADRJCT)), and
  681. * purged messages (0x010000 (IPADPGNR)).
  682. *
  683. * Locking: struct hvc_iucv_private->lock
  684. */
  685. static void hvc_iucv_msg_complete(struct iucv_path *path,
  686. struct iucv_message *msg)
  687. {
  688. struct hvc_iucv_private *priv = path->private;
  689. struct iucv_tty_buffer *ent, *next;
  690. LIST_HEAD(list_remove);
  691. spin_lock(&priv->lock);
  692. list_for_each_entry_safe(ent, next, &priv->tty_outqueue, list)
  693. if (ent->msg.id == msg->id) {
  694. list_move(&ent->list, &list_remove);
  695. break;
  696. }
  697. wake_up(&priv->sndbuf_waitq);
  698. spin_unlock(&priv->lock);
  699. destroy_tty_buffer_list(&list_remove);
  700. }
  701. /* HVC operations */
  702. static struct hv_ops hvc_iucv_ops = {
  703. .get_chars = hvc_iucv_get_chars,
  704. .put_chars = hvc_iucv_put_chars,
  705. .notifier_add = hvc_iucv_notifier_add,
  706. .notifier_del = hvc_iucv_notifier_del,
  707. .notifier_hangup = hvc_iucv_notifier_hangup,
  708. };
  709. /**
  710. * hvc_iucv_alloc() - Allocates a new struct hvc_iucv_private instance
  711. * @id: hvc_iucv_table index
  712. * @is_console: Flag if the instance is used as Linux console
  713. *
  714. * This function allocates a new hvc_iucv_private structure and stores
  715. * the instance in hvc_iucv_table at index @id.
  716. * Returns 0 on success; otherwise non-zero.
  717. */
  718. static int __init hvc_iucv_alloc(int id, unsigned int is_console)
  719. {
  720. struct hvc_iucv_private *priv;
  721. char name[9];
  722. int rc;
  723. priv = kzalloc(sizeof(struct hvc_iucv_private), GFP_KERNEL);
  724. if (!priv)
  725. return -ENOMEM;
  726. spin_lock_init(&priv->lock);
  727. INIT_LIST_HEAD(&priv->tty_outqueue);
  728. INIT_LIST_HEAD(&priv->tty_inqueue);
  729. INIT_DELAYED_WORK(&priv->sndbuf_work, hvc_iucv_sndbuf_work);
  730. init_waitqueue_head(&priv->sndbuf_waitq);
  731. priv->sndbuf = (void *) get_zeroed_page(GFP_KERNEL);
  732. if (!priv->sndbuf) {
  733. kfree(priv);
  734. return -ENOMEM;
  735. }
  736. /* set console flag */
  737. priv->is_console = is_console;
  738. /* finally allocate hvc */
  739. priv->hvc = hvc_alloc(HVC_IUCV_MAGIC + id, /* PAGE_SIZE */
  740. HVC_IUCV_MAGIC + id, &hvc_iucv_ops, 256);
  741. if (IS_ERR(priv->hvc)) {
  742. rc = PTR_ERR(priv->hvc);
  743. free_page((unsigned long) priv->sndbuf);
  744. kfree(priv);
  745. return rc;
  746. }
  747. /* notify HVC thread instead of using polling */
  748. priv->hvc->irq_requested = 1;
  749. /* setup iucv related information */
  750. snprintf(name, 9, "lnxhvc%-2d", id);
  751. memcpy(priv->srv_name, name, 8);
  752. ASCEBC(priv->srv_name, 8);
  753. hvc_iucv_table[id] = priv;
  754. return 0;
  755. }
  756. /**
  757. * hvc_iucv_init() - z/VM IUCV HVC device driver initialization
  758. */
  759. static int __init hvc_iucv_init(void)
  760. {
  761. int rc;
  762. unsigned int i;
  763. if (!MACHINE_IS_VM) {
  764. pr_info("The z/VM IUCV HVC device driver cannot "
  765. "be used without z/VM\n");
  766. return -ENODEV;
  767. }
  768. if (!hvc_iucv_devices)
  769. return -ENODEV;
  770. if (hvc_iucv_devices > MAX_HVC_IUCV_LINES)
  771. return -EINVAL;
  772. hvc_iucv_buffer_cache = kmem_cache_create(KMSG_COMPONENT,
  773. sizeof(struct iucv_tty_buffer),
  774. 0, 0, NULL);
  775. if (!hvc_iucv_buffer_cache) {
  776. pr_err("Allocating memory failed with reason code=%d\n", 1);
  777. return -ENOMEM;
  778. }
  779. hvc_iucv_mempool = mempool_create_slab_pool(MEMPOOL_MIN_NR,
  780. hvc_iucv_buffer_cache);
  781. if (!hvc_iucv_mempool) {
  782. pr_err("Allocating memory failed with reason code=%d\n", 2);
  783. kmem_cache_destroy(hvc_iucv_buffer_cache);
  784. return -ENOMEM;
  785. }
  786. /* register the first terminal device as console
  787. * (must be done before allocating hvc terminal devices) */
  788. rc = hvc_instantiate(HVC_IUCV_MAGIC, IUCV_HVC_CON_IDX, &hvc_iucv_ops);
  789. if (rc) {
  790. pr_err("Registering HVC terminal device as "
  791. "Linux console failed\n");
  792. goto out_error_memory;
  793. }
  794. /* allocate hvc_iucv_private structs */
  795. for (i = 0; i < hvc_iucv_devices; i++) {
  796. rc = hvc_iucv_alloc(i, (i == IUCV_HVC_CON_IDX) ? 1 : 0);
  797. if (rc) {
  798. pr_err("Creating a new HVC terminal device "
  799. "failed with error code=%d\n", rc);
  800. goto out_error_hvc;
  801. }
  802. }
  803. /* register IUCV callback handler */
  804. rc = iucv_register(&hvc_iucv_handler, 0);
  805. if (rc) {
  806. pr_err("Registering IUCV handlers failed with error code=%d\n",
  807. rc);
  808. goto out_error_iucv;
  809. }
  810. return 0;
  811. out_error_iucv:
  812. iucv_unregister(&hvc_iucv_handler, 0);
  813. out_error_hvc:
  814. for (i = 0; i < hvc_iucv_devices; i++)
  815. if (hvc_iucv_table[i]) {
  816. if (hvc_iucv_table[i]->hvc)
  817. hvc_remove(hvc_iucv_table[i]->hvc);
  818. kfree(hvc_iucv_table[i]);
  819. }
  820. out_error_memory:
  821. mempool_destroy(hvc_iucv_mempool);
  822. kmem_cache_destroy(hvc_iucv_buffer_cache);
  823. return rc;
  824. }
  825. /**
  826. * hvc_iucv_config() - Parsing of hvc_iucv= kernel command line parameter
  827. * @val: Parameter value (numeric)
  828. */
  829. static int __init hvc_iucv_config(char *val)
  830. {
  831. return strict_strtoul(val, 10, &hvc_iucv_devices);
  832. }
  833. device_initcall(hvc_iucv_init);
  834. __setup("hvc_iucv=", hvc_iucv_config);