sclp_rw.c 13 KB

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