sclp_rw.c 13 KB

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