sclp_rw.c 12 KB

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