sclp_rw.c 13 KB

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