sclp_rw.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * driver: reading from and writing to system console on S/390 via SCLP
  4. *
  5. * Copyright IBM Corp. 1999, 2009
  6. *
  7. * Author(s): Martin Peschke <[email protected]>
  8. * Martin Schwidefsky <[email protected]>
  9. */
  10. #include <linux/kmod.h>
  11. #include <linux/types.h>
  12. #include <linux/err.h>
  13. #include <linux/string.h>
  14. #include <linux/spinlock.h>
  15. #include <linux/ctype.h>
  16. #include <linux/uaccess.h>
  17. #include "sclp.h"
  18. #include "sclp_rw.h"
  19. /*
  20. * The room for the SCCB (only for writing) is not equal to a pages size
  21. * (as it is specified as the maximum size in the SCLP documentation)
  22. * because of the additional data structure described above.
  23. */
  24. #define MAX_SCCB_ROOM (PAGE_SIZE - sizeof(struct sclp_buffer))
  25. /* Event type structure for write message and write priority message */
  26. static struct sclp_register sclp_rw_event = {
  27. .send_mask = EVTYP_MSG_MASK,
  28. };
  29. /*
  30. * Setup a sclp write buffer. Gets a page as input (4K) and returns
  31. * a pointer to a struct sclp_buffer structure that is located at the
  32. * end of the input page. This reduces the buffer space by a few
  33. * bytes but simplifies things.
  34. */
  35. struct sclp_buffer *
  36. sclp_make_buffer(void *page, unsigned short columns, unsigned short htab)
  37. {
  38. struct sclp_buffer *buffer;
  39. struct sccb_header *sccb;
  40. sccb = (struct sccb_header *) page;
  41. /*
  42. * We keep the struct sclp_buffer structure at the end
  43. * of the sccb page.
  44. */
  45. buffer = ((struct sclp_buffer *) ((addr_t) sccb + PAGE_SIZE)) - 1;
  46. buffer->sccb = sccb;
  47. buffer->retry_count = 0;
  48. buffer->messages = 0;
  49. buffer->char_sum = 0;
  50. buffer->current_line = NULL;
  51. buffer->current_length = 0;
  52. buffer->columns = columns;
  53. buffer->htab = htab;
  54. /* initialize sccb */
  55. memset(sccb, 0, sizeof(struct sccb_header));
  56. sccb->length = sizeof(struct sccb_header);
  57. return buffer;
  58. }
  59. /*
  60. * Return a pointer to the original page that has been used to create
  61. * the buffer.
  62. */
  63. void *
  64. sclp_unmake_buffer(struct sclp_buffer *buffer)
  65. {
  66. return buffer->sccb;
  67. }
  68. /*
  69. * Initialize a new message the end of the provided buffer with
  70. * enough room for max_len characters. Return 0 on success.
  71. */
  72. static int
  73. sclp_initialize_mto(struct sclp_buffer *buffer, int max_len)
  74. {
  75. struct sccb_header *sccb;
  76. struct msg_buf *msg;
  77. struct mdb *mdb;
  78. struct go *go;
  79. struct mto *mto;
  80. int msg_size;
  81. /* max size of new message including message text */
  82. msg_size = sizeof(struct msg_buf) + max_len;
  83. /* check if current buffer sccb can contain the mto */
  84. sccb = buffer->sccb;
  85. if ((MAX_SCCB_ROOM - sccb->length) < msg_size)
  86. return -ENOMEM;
  87. msg = (struct msg_buf *)((addr_t) sccb + sccb->length);
  88. memset(msg, 0, sizeof(struct msg_buf));
  89. msg->header.length = sizeof(struct msg_buf);
  90. msg->header.type = EVTYP_MSG;
  91. mdb = &msg->mdb;
  92. mdb->header.length = sizeof(struct mdb);
  93. mdb->header.type = 1;
  94. mdb->header.tag = 0xD4C4C240; /* ebcdic "MDB " */
  95. mdb->header.revision_code = 1;
  96. go = &mdb->go;
  97. go->length = sizeof(struct go);
  98. go->type = 1;
  99. mto = &mdb->mto;
  100. mto->length = sizeof(struct mto);
  101. mto->type = 4; /* message text object */
  102. mto->line_type_flags = LNTPFLGS_ENDTEXT; /* end text */
  103. /* set pointer to first byte after struct mto. */
  104. buffer->current_msg = msg;
  105. buffer->current_line = (char *) (mto + 1);
  106. buffer->current_length = 0;
  107. return 0;
  108. }
  109. /*
  110. * Finalize message initialized by sclp_initialize_mto(),
  111. * updating the sizes of MTO, enclosing MDB, event buffer and SCCB.
  112. */
  113. static void
  114. sclp_finalize_mto(struct sclp_buffer *buffer)
  115. {
  116. struct sccb_header *sccb;
  117. struct msg_buf *msg;
  118. /*
  119. * update values of sizes
  120. * (SCCB, Event(Message) Buffer, Message Data Block)
  121. */
  122. sccb = buffer->sccb;
  123. msg = buffer->current_msg;
  124. msg->header.length += buffer->current_length;
  125. msg->mdb.header.length += buffer->current_length;
  126. msg->mdb.mto.length += buffer->current_length;
  127. sccb->length += msg->header.length;
  128. /*
  129. * count number of buffered messages (= number of Message Text
  130. * Objects) and number of buffered characters
  131. * for the SCCB currently used for buffering and at all
  132. */
  133. buffer->messages++;
  134. buffer->char_sum += buffer->current_length;
  135. buffer->current_line = NULL;
  136. buffer->current_length = 0;
  137. buffer->current_msg = NULL;
  138. }
  139. /*
  140. * processing of a message including escape characters,
  141. * returns number of characters written to the output sccb
  142. * ("processed" means that is not guaranteed that the character have already
  143. * been sent to the SCLP but that it will be done at least next time the SCLP
  144. * is not busy)
  145. */
  146. int
  147. sclp_write(struct sclp_buffer *buffer, const unsigned char *msg, int count)
  148. {
  149. int spaces, i_msg;
  150. int rc;
  151. /*
  152. * parse msg for escape sequences (\t,\v ...) and put formated
  153. * msg into an mto (created by sclp_initialize_mto).
  154. *
  155. * We have to do this work ourselfs because there is no support for
  156. * these characters on the native machine and only partial support
  157. * under VM (Why does VM interpret \n but the native machine doesn't ?)
  158. *
  159. * Depending on i/o-control setting the message is always written
  160. * immediately or we wait for a final new line maybe coming with the
  161. * next message. Besides we avoid a buffer overrun by writing its
  162. * content.
  163. *
  164. * RESTRICTIONS:
  165. *
  166. * \r and \b work within one line because we are not able to modify
  167. * previous output that have already been accepted by the SCLP.
  168. *
  169. * \t combined with following \r is not correctly represented because
  170. * \t is expanded to some spaces but \r does not know about a
  171. * previous \t and decreases the current position by one column.
  172. * This is in order to a slim and quick implementation.
  173. */
  174. for (i_msg = 0; i_msg < count; i_msg++) {
  175. switch (msg[i_msg]) {
  176. case '\n': /* new line, line feed (ASCII) */
  177. /* check if new mto needs to be created */
  178. if (buffer->current_line == NULL) {
  179. rc = sclp_initialize_mto(buffer, 0);
  180. if (rc)
  181. return i_msg;
  182. }
  183. sclp_finalize_mto(buffer);
  184. break;
  185. case '\a': /* bell, one for several times */
  186. /* set SCLP sound alarm bit in General Object */
  187. if (buffer->current_line == NULL) {
  188. rc = sclp_initialize_mto(buffer,
  189. buffer->columns);
  190. if (rc)
  191. return i_msg;
  192. }
  193. buffer->current_msg->mdb.go.general_msg_flags |=
  194. GNRLMSGFLGS_SNDALRM;
  195. break;
  196. case '\t': /* horizontal tabulator */
  197. /* check if new mto needs to be created */
  198. if (buffer->current_line == NULL) {
  199. rc = sclp_initialize_mto(buffer,
  200. buffer->columns);
  201. if (rc)
  202. return i_msg;
  203. }
  204. /* "go to (next htab-boundary + 1, same line)" */
  205. do {
  206. if (buffer->current_length >= buffer->columns)
  207. break;
  208. /* ok, add a blank */
  209. *buffer->current_line++ = 0x40;
  210. buffer->current_length++;
  211. } while (buffer->current_length % buffer->htab);
  212. break;
  213. case '\f': /* form feed */
  214. case '\v': /* vertical tabulator */
  215. /* "go to (actual column, actual line + 1)" */
  216. /* = new line, leading spaces */
  217. if (buffer->current_line != NULL) {
  218. spaces = buffer->current_length;
  219. sclp_finalize_mto(buffer);
  220. rc = sclp_initialize_mto(buffer,
  221. buffer->columns);
  222. if (rc)
  223. return i_msg;
  224. memset(buffer->current_line, 0x40, spaces);
  225. buffer->current_line += spaces;
  226. buffer->current_length = spaces;
  227. } else {
  228. /* one an empty line this is the same as \n */
  229. rc = sclp_initialize_mto(buffer,
  230. buffer->columns);
  231. if (rc)
  232. return i_msg;
  233. sclp_finalize_mto(buffer);
  234. }
  235. break;
  236. case '\b': /* backspace */
  237. /* "go to (actual column - 1, actual line)" */
  238. /* decrement counter indicating position, */
  239. /* do not remove last character */
  240. if (buffer->current_line != NULL &&
  241. buffer->current_length > 0) {
  242. buffer->current_length--;
  243. buffer->current_line--;
  244. }
  245. break;
  246. case 0x00: /* end of string */
  247. /* transfer current line to SCCB */
  248. if (buffer->current_line != NULL)
  249. sclp_finalize_mto(buffer);
  250. /* skip the rest of the message including the 0 byte */
  251. i_msg = count - 1;
  252. break;
  253. default: /* no escape character */
  254. /* do not output unprintable characters */
  255. if (!isprint(msg[i_msg]))
  256. break;
  257. /* check if new mto needs to be created */
  258. if (buffer->current_line == NULL) {
  259. rc = sclp_initialize_mto(buffer,
  260. buffer->columns);
  261. if (rc)
  262. return i_msg;
  263. }
  264. *buffer->current_line++ = sclp_ascebc(msg[i_msg]);
  265. buffer->current_length++;
  266. break;
  267. }
  268. /* check if current mto is full */
  269. if (buffer->current_line != NULL &&
  270. buffer->current_length >= buffer->columns)
  271. sclp_finalize_mto(buffer);
  272. }
  273. /* return number of processed characters */
  274. return i_msg;
  275. }
  276. /*
  277. * Return the number of free bytes in the sccb
  278. */
  279. int
  280. sclp_buffer_space(struct sclp_buffer *buffer)
  281. {
  282. struct sccb_header *sccb;
  283. int count;
  284. sccb = buffer->sccb;
  285. count = MAX_SCCB_ROOM - sccb->length;
  286. if (buffer->current_line != NULL)
  287. count -= sizeof(struct msg_buf) + buffer->current_length;
  288. return count;
  289. }
  290. /*
  291. * Return number of characters in buffer
  292. */
  293. unsigned int
  294. sclp_chars_in_buffer(struct sclp_buffer *buffer)
  295. {
  296. unsigned int count;
  297. count = buffer->char_sum;
  298. if (buffer->current_line != NULL)
  299. count += buffer->current_length;
  300. return count;
  301. }
  302. /*
  303. * called by sclp_console_init and/or sclp_tty_init
  304. */
  305. int
  306. sclp_rw_init(void)
  307. {
  308. static int init_done = 0;
  309. int rc;
  310. if (init_done)
  311. return 0;
  312. rc = sclp_register(&sclp_rw_event);
  313. if (rc == 0)
  314. init_done = 1;
  315. return rc;
  316. }
  317. #define SCLP_BUFFER_MAX_RETRY 1
  318. /*
  319. * second half of Write Event Data-function that has to be done after
  320. * interruption indicating completion of Service Call.
  321. */
  322. static void
  323. sclp_writedata_callback(struct sclp_req *request, void *data)
  324. {
  325. int rc;
  326. struct sclp_buffer *buffer;
  327. struct sccb_header *sccb;
  328. buffer = (struct sclp_buffer *) data;
  329. sccb = buffer->sccb;
  330. if (request->status == SCLP_REQ_FAILED) {
  331. if (buffer->callback != NULL)
  332. buffer->callback(buffer, -EIO);
  333. return;
  334. }
  335. /* check SCLP response code and choose suitable action */
  336. switch (sccb->response_code) {
  337. case 0x0020 :
  338. /* Normal completion, buffer processed, message(s) sent */
  339. rc = 0;
  340. break;
  341. case 0x0340: /* Contained SCLP equipment check */
  342. if (++buffer->retry_count > SCLP_BUFFER_MAX_RETRY) {
  343. rc = -EIO;
  344. break;
  345. }
  346. /* remove processed buffers and requeue rest */
  347. if (sclp_remove_processed((struct sccb_header *) sccb) > 0) {
  348. /* not all buffers were processed */
  349. sccb->response_code = 0x0000;
  350. buffer->request.status = SCLP_REQ_FILLED;
  351. rc = sclp_add_request(request);
  352. if (rc == 0)
  353. return;
  354. } else
  355. rc = 0;
  356. break;
  357. case 0x0040: /* SCLP equipment check */
  358. case 0x05f0: /* Target resource in improper state */
  359. if (++buffer->retry_count > SCLP_BUFFER_MAX_RETRY) {
  360. rc = -EIO;
  361. break;
  362. }
  363. /* retry request */
  364. sccb->response_code = 0x0000;
  365. buffer->request.status = SCLP_REQ_FILLED;
  366. rc = sclp_add_request(request);
  367. if (rc == 0)
  368. return;
  369. break;
  370. default:
  371. if (sccb->response_code == 0x71f0)
  372. rc = -ENOMEM;
  373. else
  374. rc = -EINVAL;
  375. break;
  376. }
  377. if (buffer->callback != NULL)
  378. buffer->callback(buffer, rc);
  379. }
  380. /*
  381. * Setup the request structure in the struct sclp_buffer to do SCLP Write
  382. * Event Data and pass the request to the core SCLP loop. Return zero on
  383. * success, non-zero otherwise.
  384. */
  385. int
  386. sclp_emit_buffer(struct sclp_buffer *buffer,
  387. void (*callback)(struct sclp_buffer *, int))
  388. {
  389. /* add current line if there is one */
  390. if (buffer->current_line != NULL)
  391. sclp_finalize_mto(buffer);
  392. /* Are there messages in the output buffer ? */
  393. if (buffer->messages == 0)
  394. return -EIO;
  395. buffer->request.command = SCLP_CMDW_WRITE_EVENT_DATA;
  396. buffer->request.status = SCLP_REQ_FILLED;
  397. buffer->request.callback = sclp_writedata_callback;
  398. buffer->request.callback_data = buffer;
  399. buffer->request.sccb = buffer->sccb;
  400. buffer->callback = callback;
  401. return sclp_add_request(&buffer->request);
  402. }