sclp_rw.c 12 KB

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