sclp_rw.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  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 sccb_header *sccb;
  45. sccb = (struct sccb_header *) 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->messages = 0;
  54. buffer->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 sccb_header));
  61. sccb->length = sizeof(struct sccb_header);
  62. return buffer;
  63. }
  64. /*
  65. * Return a pointer to the original page that has been used to create
  66. * the buffer.
  67. */
  68. void *
  69. sclp_unmake_buffer(struct sclp_buffer *buffer)
  70. {
  71. return buffer->sccb;
  72. }
  73. /*
  74. * Initialize a new message the end of the provided buffer with
  75. * enough room for max_len characters. Return 0 on success.
  76. */
  77. static int
  78. sclp_initialize_mto(struct sclp_buffer *buffer, int max_len)
  79. {
  80. struct sccb_header *sccb;
  81. struct msg_buf *msg;
  82. struct mdb *mdb;
  83. struct go *go;
  84. struct mto *mto;
  85. int msg_size;
  86. /* max size of new message including message text */
  87. msg_size = sizeof(struct msg_buf) + max_len;
  88. /* check if current buffer sccb can contain the mto */
  89. sccb = buffer->sccb;
  90. if ((MAX_SCCB_ROOM - sccb->length) < msg_size)
  91. return -ENOMEM;
  92. msg = (struct msg_buf *)((addr_t) sccb + sccb->length);
  93. memset(msg, 0, sizeof(struct msg_buf));
  94. msg->header.length = sizeof(struct msg_buf);
  95. msg->header.type = EVTYP_MSG;
  96. mdb = &msg->mdb;
  97. mdb->header.length = sizeof(struct mdb);
  98. mdb->header.type = 1;
  99. mdb->header.tag = 0xD4C4C240; /* ebcdic "MDB " */
  100. mdb->header.revision_code = 1;
  101. go = &mdb->go;
  102. go->length = sizeof(struct go);
  103. go->type = 1;
  104. mto = &mdb->mto;
  105. mto->length = sizeof(struct mto);
  106. mto->type = 4; /* message text object */
  107. mto->line_type_flags = LNTPFLGS_ENDTEXT; /* end text */
  108. /* set pointer to first byte after struct mto. */
  109. buffer->current_msg = msg;
  110. buffer->current_line = (char *) (mto + 1);
  111. buffer->current_length = 0;
  112. return 0;
  113. }
  114. /*
  115. * Finalize message initialized by sclp_initialize_mto(),
  116. * updating the sizes of MTO, enclosing MDB, event buffer and SCCB.
  117. */
  118. static void
  119. sclp_finalize_mto(struct sclp_buffer *buffer)
  120. {
  121. struct sccb_header *sccb;
  122. struct msg_buf *msg;
  123. /*
  124. * update values of sizes
  125. * (SCCB, Event(Message) Buffer, Message Data Block)
  126. */
  127. sccb = buffer->sccb;
  128. msg = buffer->current_msg;
  129. msg->header.length += buffer->current_length;
  130. msg->mdb.header.length += buffer->current_length;
  131. msg->mdb.mto.length += buffer->current_length;
  132. sccb->length += msg->header.length;
  133. /*
  134. * count number of buffered messages (= number of Message Text
  135. * Objects) and number of buffered characters
  136. * for the SCCB currently used for buffering and at all
  137. */
  138. buffer->messages++;
  139. buffer->char_sum += buffer->current_length;
  140. buffer->current_line = NULL;
  141. buffer->current_length = 0;
  142. buffer->current_msg = NULL;
  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. if (buffer->current_line == NULL) {
  193. rc = sclp_initialize_mto(buffer,
  194. buffer->columns);
  195. if (rc)
  196. return i_msg;
  197. }
  198. buffer->current_msg->mdb.go.general_msg_flags |=
  199. GNRLMSGFLGS_SNDALRM;
  200. break;
  201. case '\t': /* horizontal tabulator */
  202. /* check if new mto needs to be created */
  203. if (buffer->current_line == NULL) {
  204. rc = sclp_initialize_mto(buffer,
  205. buffer->columns);
  206. if (rc)
  207. return i_msg;
  208. }
  209. /* "go to (next htab-boundary + 1, same line)" */
  210. do {
  211. if (buffer->current_length >= buffer->columns)
  212. break;
  213. /* ok, add a blank */
  214. *buffer->current_line++ = 0x40;
  215. buffer->current_length++;
  216. } while (buffer->current_length % buffer->htab);
  217. break;
  218. case '\f': /* form feed */
  219. case '\v': /* vertical tabulator */
  220. /* "go to (actual column, actual line + 1)" */
  221. /* = new line, leading spaces */
  222. if (buffer->current_line != NULL) {
  223. spaces = buffer->current_length;
  224. sclp_finalize_mto(buffer);
  225. rc = sclp_initialize_mto(buffer,
  226. buffer->columns);
  227. if (rc)
  228. return i_msg;
  229. memset(buffer->current_line, 0x40, spaces);
  230. buffer->current_line += spaces;
  231. buffer->current_length = spaces;
  232. } else {
  233. /* one an empty line this is the same as \n */
  234. rc = sclp_initialize_mto(buffer,
  235. buffer->columns);
  236. if (rc)
  237. return i_msg;
  238. sclp_finalize_mto(buffer);
  239. }
  240. break;
  241. case '\b': /* backspace */
  242. /* "go to (actual column - 1, actual line)" */
  243. /* decrement counter indicating position, */
  244. /* do not remove last character */
  245. if (buffer->current_line != NULL &&
  246. buffer->current_length > 0) {
  247. buffer->current_length--;
  248. buffer->current_line--;
  249. }
  250. break;
  251. case 0x00: /* end of string */
  252. /* transfer current line to SCCB */
  253. if (buffer->current_line != NULL)
  254. sclp_finalize_mto(buffer);
  255. /* skip the rest of the message including the 0 byte */
  256. i_msg = count - 1;
  257. break;
  258. default: /* no escape character */
  259. /* do not output unprintable characters */
  260. if (!isprint(msg[i_msg]))
  261. break;
  262. /* check if new mto needs to be created */
  263. if (buffer->current_line == NULL) {
  264. rc = sclp_initialize_mto(buffer,
  265. buffer->columns);
  266. if (rc)
  267. return i_msg;
  268. }
  269. *buffer->current_line++ = sclp_ascebc(msg[i_msg]);
  270. buffer->current_length++;
  271. break;
  272. }
  273. /* check if current mto is full */
  274. if (buffer->current_line != NULL &&
  275. buffer->current_length >= buffer->columns)
  276. sclp_finalize_mto(buffer);
  277. }
  278. /* return number of processed characters */
  279. return i_msg;
  280. }
  281. /*
  282. * Return the number of free bytes in the sccb
  283. */
  284. int
  285. sclp_buffer_space(struct sclp_buffer *buffer)
  286. {
  287. struct sccb_header *sccb;
  288. int count;
  289. sccb = buffer->sccb;
  290. count = MAX_SCCB_ROOM - sccb->length;
  291. if (buffer->current_line != NULL)
  292. count -= sizeof(struct msg_buf) + buffer->current_length;
  293. return count;
  294. }
  295. /*
  296. * Return number of characters in buffer
  297. */
  298. int
  299. sclp_chars_in_buffer(struct sclp_buffer *buffer)
  300. {
  301. int count;
  302. count = buffer->char_sum;
  303. if (buffer->current_line != NULL)
  304. count += buffer->current_length;
  305. return count;
  306. }
  307. /*
  308. * sets or provides some values that influence the drivers behaviour
  309. */
  310. void
  311. sclp_set_columns(struct sclp_buffer *buffer, unsigned short columns)
  312. {
  313. buffer->columns = columns;
  314. if (buffer->current_line != NULL &&
  315. buffer->current_length > buffer->columns)
  316. sclp_finalize_mto(buffer);
  317. }
  318. void
  319. sclp_set_htab(struct sclp_buffer *buffer, unsigned short htab)
  320. {
  321. buffer->htab = htab;
  322. }
  323. /*
  324. * called by sclp_console_init and/or sclp_tty_init
  325. */
  326. int
  327. sclp_rw_init(void)
  328. {
  329. static int init_done = 0;
  330. int rc;
  331. if (init_done)
  332. return 0;
  333. rc = sclp_register(&sclp_rw_event);
  334. if (rc == 0)
  335. init_done = 1;
  336. return rc;
  337. }
  338. #define SCLP_BUFFER_MAX_RETRY 1
  339. /*
  340. * second half of Write Event Data-function that has to be done after
  341. * interruption indicating completion of Service Call.
  342. */
  343. static void
  344. sclp_writedata_callback(struct sclp_req *request, void *data)
  345. {
  346. int rc;
  347. struct sclp_buffer *buffer;
  348. struct sccb_header *sccb;
  349. buffer = (struct sclp_buffer *) data;
  350. sccb = buffer->sccb;
  351. if (request->status == SCLP_REQ_FAILED) {
  352. if (buffer->callback != NULL)
  353. buffer->callback(buffer, -EIO);
  354. return;
  355. }
  356. /* check SCLP response code and choose suitable action */
  357. switch (sccb->response_code) {
  358. case 0x0020 :
  359. /* Normal completion, buffer processed, message(s) sent */
  360. rc = 0;
  361. break;
  362. case 0x0340: /* Contained SCLP equipment check */
  363. if (++buffer->retry_count > SCLP_BUFFER_MAX_RETRY) {
  364. rc = -EIO;
  365. break;
  366. }
  367. /* remove processed buffers and requeue rest */
  368. if (sclp_remove_processed((struct sccb_header *) sccb) > 0) {
  369. /* not all buffers were processed */
  370. sccb->response_code = 0x0000;
  371. buffer->request.status = SCLP_REQ_FILLED;
  372. rc = sclp_add_request(request);
  373. if (rc == 0)
  374. return;
  375. } else
  376. rc = 0;
  377. break;
  378. case 0x0040: /* SCLP equipment check */
  379. case 0x05f0: /* Target resource in improper state */
  380. if (++buffer->retry_count > SCLP_BUFFER_MAX_RETRY) {
  381. rc = -EIO;
  382. break;
  383. }
  384. /* retry request */
  385. sccb->response_code = 0x0000;
  386. buffer->request.status = SCLP_REQ_FILLED;
  387. rc = sclp_add_request(request);
  388. if (rc == 0)
  389. return;
  390. break;
  391. default:
  392. if (sccb->response_code == 0x71f0)
  393. rc = -ENOMEM;
  394. else
  395. rc = -EINVAL;
  396. break;
  397. }
  398. if (buffer->callback != NULL)
  399. buffer->callback(buffer, rc);
  400. }
  401. /*
  402. * Setup the request structure in the struct sclp_buffer to do SCLP Write
  403. * Event Data and pass the request to the core SCLP loop. Return zero on
  404. * success, non-zero otherwise.
  405. */
  406. int
  407. sclp_emit_buffer(struct sclp_buffer *buffer,
  408. void (*callback)(struct sclp_buffer *, int))
  409. {
  410. /* add current line if there is one */
  411. if (buffer->current_line != NULL)
  412. sclp_finalize_mto(buffer);
  413. /* Are there messages in the output buffer ? */
  414. if (buffer->messages == 0)
  415. return -EIO;
  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 = buffer->sccb;
  421. buffer->callback = callback;
  422. return sclp_add_request(&buffer->request);
  423. }