con3215.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:32k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  drivers/s390/char/con3215.c
  3.  *    3215 line mode terminal driver.
  4.  *
  5.  *  S390 version
  6.  *    Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
  7.  *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
  8.  *
  9.  *  Updated:
  10.  *   Aug-2000: Added tab support
  11.  *             Dan Morrison, IBM Corporation (dmorriso@cse.buffalo.edu)
  12.  */
  13. #include <linux/config.h>
  14. #include <linux/types.h>
  15. #include <linux/kdev_t.h>
  16. #include <linux/tty.h>
  17. #include <linux/vt_kern.h>
  18. #include <linux/init.h>
  19. #include <linux/console.h>
  20. #include <linux/interrupt.h>
  21. #include <linux/slab.h>
  22. #include <linux/bootmem.h>
  23. #include <linux/devfs_fs_kernel.h>
  24. #include <asm/io.h>
  25. #include <asm/ebcdic.h>
  26. #include <asm/uaccess.h>
  27. #include <asm/delay.h>
  28. #include <asm/cpcmd.h>
  29. #include <asm/irq.h>
  30. #include <asm/setup.h>
  31. #include "ctrlchar.h"
  32. #define NR_3215     1
  33. #define NR_3215_REQ     (4*NR_3215)
  34. #define RAW3215_BUFFER_SIZE 65536     /* output buffer size */
  35. #define RAW3215_INBUF_SIZE  256       /* input buffer size */
  36. #define RAW3215_MIN_SPACE   128       /* minimum free space for wakeup */
  37. #define RAW3215_MIN_WRITE   1024      /* min. length for immediate output */
  38. #define RAW3215_MAX_BYTES   3968      /* max. bytes to write with one ssch */
  39. #define RAW3215_MAX_NEWLINE 50        /* max. lines to write with one ssch */
  40. #define RAW3215_NR_CCWS     3
  41. #define RAW3215_TIMEOUT     HZ/10     /* time for delayed output */
  42. #define RAW3215_FIXED     1       /* 3215 console device is not be freed */
  43. #define RAW3215_ACTIVE     2       /* set if the device is in use */
  44. #define RAW3215_WORKING     4       /* set if a request is being worked on */
  45. #define RAW3215_THROTTLED   8       /* set if reading is disabled */
  46. #define RAW3215_STOPPED     16       /* set if writing is disabled */
  47. #define RAW3215_CLOSING     32       /* set while in close process */
  48. #define RAW3215_TIMER_RUNS  64       /* set if the output delay timer is on */
  49. #define RAW3215_FLUSHING    128       /* set to flush buffer (no delay) */
  50. #define RAW3215_BH_PENDING  256       /* indication for bh scheduling */
  51. #define TAB_STOP_SIZE     8         /* tab stop size */
  52. struct _raw3215_info;       /* forward declaration ... */
  53. int raw3215_condevice = -1;           /* preset console device */
  54. /*
  55.  * Request types for a 3215 device
  56.  */
  57. typedef enum {
  58. RAW3215_FREE, RAW3215_READ, RAW3215_WRITE
  59. } raw3215_type;
  60. /*
  61.  * Request structure for a 3215 device
  62.  */
  63. typedef struct _raw3215_req {
  64. raw3215_type type;       /* type of the request */
  65. int start, len;       /* start index & len in output buffer */
  66.         int delayable;                /* indication to wait for more data */
  67. int residual;       /* residual count for read request */
  68. ccw1_t ccws[RAW3215_NR_CCWS]; /* space for the channel program */
  69. struct _raw3215_info *info;   /* pointer to main structure */
  70. struct _raw3215_req *next;    /* pointer to next request */
  71. } raw3215_req  __attribute__ ((aligned(8)));
  72. typedef struct _raw3215_info {
  73. int flags;       /* state flags */
  74. int irq;       /* interrupt number to do_IO */
  75. char *buffer;       /* pointer to output buffer */
  76. char *inbuf;       /* pointer to input buffer */
  77. int head;       /* first free byte in output buffer */
  78. int count;       /* number of bytes in output buffer */
  79.         int written;                  /* number of bytes in write requests */
  80. devstat_t devstat;       /* device status structure for do_IO */
  81. struct tty_struct *tty;       /* pointer to tty structure if present */
  82. struct tq_struct tqueue;      /* task queue to bottom half */
  83. raw3215_req *queued_read;     /* pointer to queued read requests */
  84. raw3215_req *queued_write;    /* pointer to queued write requests */
  85. wait_queue_head_t empty_wait; /* wait queue for flushing */
  86. struct timer_list timer;      /* timer for delayed output */
  87. char *message;                /* pending message from raw3215_irq */
  88. int msg_dstat;                /* dstat for pending message */
  89. int msg_cstat;                /* cstat for pending message */
  90. int line_pos;       /* position on the line (for tabs) */
  91. } raw3215_info;
  92. static raw3215_info *raw3215[NR_3215]; /* array of 3215 devices structures */
  93. static raw3215_req *raw3215_freelist; /* list of free request structures */
  94. static spinlock_t raw3215_freelist_lock;/* spinlock to protect free list */
  95. static struct tty_driver tty3215_driver;
  96. static struct tty_struct *tty3215_table[NR_3215];
  97. static struct termios *tty3215_termios[NR_3215];
  98. static struct termios *tty3215_termios_locked[NR_3215];
  99. static int tty3215_refcount;
  100. #ifndef MIN
  101. #define MIN(a,b) ((a) < (b) ? (a) : (b))
  102. #endif
  103. /*
  104.  * Get a request structure from the free list
  105.  */
  106. extern inline raw3215_req *raw3215_alloc_req(void) {
  107. raw3215_req *req;
  108. unsigned long flags;
  109. spin_lock_irqsave(&raw3215_freelist_lock, flags);
  110. req = raw3215_freelist;
  111. raw3215_freelist = req->next;
  112. spin_unlock_irqrestore(&raw3215_freelist_lock, flags);
  113. return req;
  114. }
  115. /*
  116.  * Put a request structure back to the free list
  117.  */
  118. extern inline void raw3215_free_req(raw3215_req *req) {
  119. unsigned long flags;
  120.         if (req->type == RAW3215_FREE)
  121.                 return;         /* don't free a free request */
  122.         req->type = RAW3215_FREE;
  123. spin_lock_irqsave(&raw3215_freelist_lock, flags);
  124. req->next = raw3215_freelist;
  125. raw3215_freelist = req;
  126. spin_unlock_irqrestore(&raw3215_freelist_lock, flags);
  127. }
  128. /*
  129.  * Set up a read request that reads up to 160 byte from the 3215 device.
  130.  * If there is a queued read request it is used, but that shouldn't happen
  131.  * because a 3215 terminal won't accept a new read before the old one is
  132.  * completed.
  133.  */
  134. static void raw3215_mk_read_req(raw3215_info *raw)
  135. {
  136. raw3215_req *req;
  137.         ccw1_t *ccw;
  138. /* there can only be ONE read request at a time */
  139. req = raw->queued_read;
  140. if (req == NULL) {
  141. /* no queued read request, use new req structure */
  142. req = raw3215_alloc_req();
  143. req->type = RAW3215_READ;
  144. req->info = raw;
  145.                 raw->queued_read = req;
  146. }
  147.         ccw = req->ccws;
  148.         ccw->cmd_code = 0x0A; /* read inquiry */
  149.         ccw->flags = 0x20;    /* ignore incorrect length */
  150.         ccw->count = 160;
  151.         ccw->cda = (__u32) __pa(raw->inbuf);
  152. }
  153. /*
  154.  * Set up a write request with the information from the main structure.
  155.  * A ccw chain is created that writes as much as possible from the output
  156.  * buffer to the 3215 device. If a queued write exists it is replaced by
  157.  * the new, probably lengthened request.
  158.  */
  159. static void raw3215_mk_write_req(raw3215_info *raw)
  160. {
  161.         raw3215_req *req;
  162. ccw1_t *ccw;
  163. int len, count, ix, lines;
  164.         if (raw->count <= raw->written)
  165.                 return;
  166.         /* check if there is a queued write request */
  167.         req = raw->queued_write;
  168.         if (req == NULL) {
  169.                 /* no queued write request, use new req structure */
  170.                 req = raw3215_alloc_req();
  171.                 req->type = RAW3215_WRITE;
  172.                 req->info = raw;
  173.                 raw->queued_write = req;
  174.         } else {
  175.                 raw->written -= req->len;
  176.         }
  177. ccw = req->ccws;
  178.         req->start = (raw->head - raw->count + raw->written) &
  179.                      (RAW3215_BUFFER_SIZE - 1);
  180.         /*
  181.          * now we have to count newlines. We can at max accept
  182.          * RAW3215_MAX_NEWLINE newlines in a single ssch due to
  183.          * a restriction in VM
  184.          */
  185.         lines = 0;
  186.         ix = req->start;
  187.         while (lines < RAW3215_MAX_NEWLINE && ix != raw->head) {
  188.                 if (raw->buffer[ix] == 0x15)
  189.                         lines++;
  190.                 ix = (ix + 1) & (RAW3215_BUFFER_SIZE - 1);
  191.         }
  192. len = ((ix - 1 - req->start) & (RAW3215_BUFFER_SIZE - 1)) + 1;
  193.         if (len > RAW3215_MAX_BYTES)
  194.                 len = RAW3215_MAX_BYTES;
  195.         req->len = len;
  196.         raw->written += len;
  197.         /* set the indication if we should try to enlarge this request */
  198.         req->delayable = (ix == raw->head) && (len < RAW3215_MIN_WRITE);
  199. ix = req->start;
  200. while (len > 0) {
  201. if (ccw > req->ccws)
  202. ccw[-1].flags |= 0x40; /* use command chaining */
  203. ccw->cmd_code = 0x01; /* write, auto carrier return */
  204. ccw->flags = 0x20;    /* ignore incorrect length ind.  */
  205. ccw->cda =
  206. (__u32) __pa(raw->buffer + ix);
  207. count = len;
  208. if (ix + count > RAW3215_BUFFER_SIZE)
  209. count = RAW3215_BUFFER_SIZE - ix;
  210. ccw->count = count;
  211. len -= count;
  212. ix = (ix + count) & (RAW3215_BUFFER_SIZE - 1);
  213. ccw++;
  214. }
  215.         /*
  216.          * Add a NOP to the channel program. 3215 devices are purely
  217.          * emulated and its much better to avoid the channel end
  218.          * interrupt in this case.
  219.          */
  220.         if (ccw > req->ccws)
  221.                 ccw[-1].flags |= 0x40; /* use command chaining */
  222.         ccw->cmd_code = 0x03; /* NOP */
  223.         ccw->flags = 0;
  224.         ccw->cda = 0;
  225.         ccw->count = 1;
  226. }
  227. /*
  228.  * Start a read or a write request
  229.  */
  230. static void raw3215_start_io(raw3215_info *raw)
  231. {
  232. raw3215_req *req;
  233. int res;
  234. req = raw->queued_read;
  235. if (req != NULL &&
  236.     !(raw->flags & (RAW3215_WORKING | RAW3215_THROTTLED))) {
  237. /* dequeue request */
  238. raw->queued_read = NULL;
  239. res = do_IO(raw->irq, req->ccws, (unsigned long) req, 0, 0);
  240. if (res != 0) {
  241. /* do_IO failed, put request back to queue */
  242. raw->queued_read = req;
  243. } else {
  244. raw->flags |= RAW3215_WORKING;
  245. }
  246. req = raw->queued_write;
  247. if (req != NULL &&
  248.     !(raw->flags & (RAW3215_WORKING | RAW3215_STOPPED))) {
  249. /* dequeue request */
  250. raw->queued_write = NULL;
  251. res = do_IO(raw->irq, req->ccws, (unsigned long) req, 0, 0);
  252. if (res != 0) {
  253. /* do_IO failed, put request back to queue */
  254. raw->queued_write = req;
  255. } else {
  256. raw->flags |= RAW3215_WORKING;
  257. }
  258. }
  259. }
  260. /*
  261.  * Function to start a delayed output after RAW3215_TIMEOUT seconds
  262.  */
  263. static void raw3215_timeout(unsigned long __data)
  264. {
  265. raw3215_info *raw = (raw3215_info *) __data;
  266. unsigned long flags;
  267. s390irq_spin_lock_irqsave(raw->irq, flags);
  268. if (raw->flags & RAW3215_TIMER_RUNS) {
  269. del_timer(&raw->timer);
  270. raw->flags &= ~RAW3215_TIMER_RUNS;
  271.                 raw3215_mk_write_req(raw);
  272. raw3215_start_io(raw);
  273. }
  274. s390irq_spin_unlock_irqrestore(raw->irq, flags);
  275. }
  276. /*
  277.  * Function to conditionally start an IO. A read is started immediatly,
  278.  * a write is only started immediatly if the flush flag is on or the
  279.  * amount of data is bigger than RAW3215_MIN_WRITE. If a write is not
  280.  * done immediatly a timer is started with a delay of RAW3215_TIMEOUT.
  281.  */
  282. extern inline void raw3215_try_io(raw3215_info *raw)
  283. {
  284. if (!(raw->flags & RAW3215_ACTIVE))
  285. return;
  286. if (raw->queued_read != NULL)
  287. raw3215_start_io(raw);
  288. else if (raw->queued_write != NULL) {
  289. if ((raw->queued_write->delayable == 0) ||
  290.     (raw->flags & RAW3215_FLUSHING)) {
  291. /* execute write requests bigger than minimum size */
  292.                         raw3215_start_io(raw);
  293. if (raw->flags & RAW3215_TIMER_RUNS) {
  294. del_timer(&raw->timer);
  295. raw->flags &= ~RAW3215_TIMER_RUNS;
  296. }
  297. } else if (!(raw->flags & RAW3215_TIMER_RUNS)) {
  298. /* delay small writes */
  299. init_timer(&raw->timer);
  300. raw->timer.expires = RAW3215_TIMEOUT + jiffies;
  301. raw->timer.data = (unsigned long) raw;
  302. raw->timer.function = raw3215_timeout;
  303. add_timer(&raw->timer);
  304. raw->flags |= RAW3215_TIMER_RUNS;
  305. }
  306. }
  307. }
  308. /*
  309.  * The bottom half handler routine for 3215 devices. It tries to start
  310.  * the next IO and wakes up processes waiting on the tty.
  311.  */
  312. static void raw3215_softint(void *data)
  313. {
  314. raw3215_info *raw;
  315. struct tty_struct *tty;
  316. unsigned long flags;
  317. raw = (raw3215_info *) data;
  318. s390irq_spin_lock_irqsave(raw->irq, flags);
  319.         raw3215_mk_write_req(raw);
  320.         raw3215_try_io(raw);
  321.         raw->flags &= ~RAW3215_BH_PENDING;
  322. s390irq_spin_unlock_irqrestore(raw->irq, flags);
  323. /* Check for pending message from raw3215_irq */
  324. if (raw->message != NULL) {
  325. printk(raw->message, raw->irq, raw->msg_dstat, raw->msg_cstat);
  326. raw->message = NULL;
  327. }
  328. tty = raw->tty;
  329. if (tty != NULL &&
  330.     RAW3215_BUFFER_SIZE - raw->count >= RAW3215_MIN_SPACE) {
  331. if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
  332.     tty->ldisc.write_wakeup)
  333. (tty->ldisc.write_wakeup)(tty);
  334. wake_up_interruptible(&tty->write_wait);
  335. }
  336. }
  337. /*
  338.  * Function to safely add raw3215_softint to tq_immediate.
  339.  * The s390irq spinlock must be held.
  340.  */
  341. static inline void raw3215_sched_bh(raw3215_info *raw)
  342. {
  343.         if (raw->flags & RAW3215_BH_PENDING)
  344.                 return;       /* already pending */
  345.         raw->flags |= RAW3215_BH_PENDING;
  346. INIT_LIST_HEAD(&raw->tqueue.list);
  347. raw->tqueue.sync = 0;
  348.         raw->tqueue.routine = raw3215_softint;
  349.         raw->tqueue.data = raw;
  350.         queue_task(&raw->tqueue, &tq_immediate);
  351.         mark_bh(IMMEDIATE_BH);
  352. }
  353. /*
  354.  * Find the raw3215_info structure associated with irq
  355.  */
  356. static inline raw3215_info *raw3215_find_info(int irq) {
  357. raw3215_info *raw;
  358. int i;
  359. for (i = 0; i < NR_3215; i++) {
  360. raw = raw3215[i];
  361. if (raw != NULL && raw->irq == irq &&
  362.     (raw->flags & RAW3215_ACTIVE))
  363. break;
  364. }
  365. return (i >= NR_3215) ? NULL : raw;
  366. }
  367. /*
  368.  * Interrupt routine, called from Ingo's I/O layer
  369.  */
  370. static void raw3215_irq(int irq, void *int_parm, struct pt_regs *regs)
  371. {
  372. raw3215_info *raw;
  373. raw3215_req *req;
  374. struct tty_struct *tty;
  375. devstat_t *stat;
  376.         int cstat, dstat;
  377. int count, slen;
  378. stat = (devstat_t *) int_parm;
  379. req = (raw3215_req *) stat->intparm;
  380. cstat = stat->cstat;
  381. dstat = stat->dstat;
  382. if (cstat != 0) {
  383. raw = raw3215_find_info(irq);
  384. if (raw != NULL) {
  385. raw->message = KERN_WARNING
  386. "Got nonzero channel status in raw3215_irq "
  387. "(dev %i, dev sts 0x%2x, sch sts 0x%2x)";
  388. raw->msg_dstat = dstat;
  389. raw->msg_cstat = cstat;
  390.                         raw3215_sched_bh(raw);
  391. }
  392. }
  393.         if (dstat & 0x01) { /* we got a unit exception */
  394. dstat &= ~0x01;  /* we can ignore it */
  395.         }
  396. switch (dstat) {
  397. case 0x80:
  398. if (cstat != 0)
  399. break;
  400. /* Attention interrupt, someone hit the enter key */
  401. if ((raw = raw3215_find_info(irq)) == NULL)
  402. return;              /* That shouldn't happen ... */
  403. /* Setup a read request */
  404. raw3215_mk_read_req(raw);
  405.                 if (MACHINE_IS_P390)
  406.                         memset(raw->inbuf, 0, RAW3215_INBUF_SIZE);
  407.                 raw3215_sched_bh(raw);
  408. break;
  409. case 0x08:
  410. case 0x0C:
  411. /* Channel end interrupt. */
  412. if ((raw = req->info) == NULL)
  413.                         return;              /* That shouldn't happen ... */
  414. if (req->type == RAW3215_READ) {
  415. /* store residual count, then wait for device end */
  416. req->residual = stat->rescnt;
  417. }
  418. if (dstat == 0x08)
  419. break;
  420. case 0x04:
  421. /* Device end interrupt. */
  422.                 if ((raw = req->info) == NULL)
  423.                         return;              /* That shouldn't happen ... */
  424. if (req->type == RAW3215_READ && raw->tty != NULL) {
  425. char *cchar;
  426. tty = raw->tty;
  427.                         count = 160 - req->residual;
  428.                         if (MACHINE_IS_P390) {
  429.                                 slen = strnlen(raw->inbuf, RAW3215_INBUF_SIZE);
  430.                                 if (count > slen)
  431.                                         count = slen;
  432.                         } else
  433. if (count >= TTY_FLIPBUF_SIZE - tty->flip.count)
  434. count = TTY_FLIPBUF_SIZE - tty->flip.count - 1;
  435. EBCASC(raw->inbuf, count);
  436. if ((cchar = ctrlchar_handle(raw->inbuf, count, tty))) {
  437. if (cchar == (char *)-1)
  438. goto in_out;
  439. tty->flip.count++;
  440. *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
  441. *tty->flip.char_buf_ptr++ = *cchar;
  442. tty_flip_buffer_push(raw->tty);
  443. } else {
  444. memcpy(tty->flip.char_buf_ptr,
  445.        raw->inbuf, count);
  446. if (count < 2 ||
  447.     (strncmp(raw->inbuf+count-2, "^n", 2) ||
  448.     strncmp(raw->inbuf+count-2, "252n", 2)) ) {
  449. /* don't add the auto n */
  450. tty->flip.char_buf_ptr[count] = 'n';
  451. memset(tty->flip.flag_buf_ptr,
  452.        TTY_NORMAL, count + 1);
  453. count++;
  454. } else
  455. count-=2;
  456. tty->flip.char_buf_ptr += count;
  457. tty->flip.flag_buf_ptr += count;
  458. tty->flip.count += count;
  459. tty_flip_buffer_push(raw->tty);
  460. }
  461. } else if (req->type == RAW3215_WRITE) {
  462. raw->count -= req->len;
  463.                         raw->written -= req->len;
  464. in_out:
  465. raw->flags &= ~RAW3215_WORKING;
  466. raw3215_free_req(req);
  467. /* check for empty wait */
  468. if (waitqueue_active(&raw->empty_wait) &&
  469.     raw->queued_write == NULL &&
  470.     raw->queued_read == NULL) {
  471. wake_up_interruptible(&raw->empty_wait);
  472. }
  473.                 raw3215_sched_bh(raw);
  474. break;
  475. default:
  476. /* Strange interrupt, I'll do my best to clean up */
  477.                 if ((raw = raw3215_find_info(irq)) == NULL)
  478.                         return;              /* That shouldn't happen ... */
  479.                 if (raw == NULL) break;
  480. if (req != NULL && req->type != RAW3215_FREE) {
  481.         if (req->type == RAW3215_WRITE) {
  482.         raw->count -= req->len;
  483.                                 raw->written -= req->len;
  484.                         }
  485.                         raw->flags &= ~RAW3215_WORKING;
  486.                         raw3215_free_req(req);
  487. }
  488. raw->message = KERN_WARNING
  489. "Spurious interrupt in in raw3215_irq "
  490. "(dev %i, dev sts 0x%2x, sch sts 0x%2x)";
  491. raw->msg_dstat = dstat;
  492. raw->msg_cstat = cstat;
  493.                 raw3215_sched_bh(raw);
  494. }
  495. return;
  496. }
  497. /*
  498.  * Wait until length bytes are available int the output buffer.
  499.  * Has to be called with the s390irq lock held. Can be called
  500.  * disabled.
  501.  */
  502. void raw3215_make_room(raw3215_info *raw, unsigned int length)
  503. {
  504. while (RAW3215_BUFFER_SIZE - raw->count < length) {
  505. /* there might be a request pending */
  506. raw->flags |= RAW3215_FLUSHING;
  507. raw3215_mk_write_req(raw);
  508. raw3215_try_io(raw);
  509. raw->flags &= ~RAW3215_FLUSHING;
  510. if (wait_cons_dev(raw->irq) != 0) {
  511. /* that shouldn't happen */
  512. raw->count = 0;
  513. raw->written = 0;
  514. }
  515. /* Enough room freed up ? */
  516. if (RAW3215_BUFFER_SIZE - raw->count >= length)
  517. break;
  518. /* there might be another cpu waiting for the lock */
  519. s390irq_spin_unlock(raw->irq);
  520. udelay(100);
  521. s390irq_spin_lock(raw->irq);
  522. }
  523. }
  524. /*
  525.  * String write routine for 3215 devices
  526.  */
  527. static int
  528. raw3215_write(raw3215_info *raw, const char *str,
  529.       int from_user, unsigned int length)
  530. {
  531. unsigned long flags;
  532. int ret, c;
  533. int count;
  534. ret = 0;
  535. while (length > 0) {
  536. s390irq_spin_lock_irqsave(raw->irq, flags);
  537. count = (length > RAW3215_BUFFER_SIZE) ?
  538.      RAW3215_BUFFER_SIZE : length;
  539. length -= count;
  540.                 raw3215_make_room(raw, count);
  541. /* copy string to output buffer and convert it to EBCDIC */
  542. if (from_user) {
  543. while (1) {
  544. c = MIN(count,
  545. MIN(RAW3215_BUFFER_SIZE - raw->count,
  546.     RAW3215_BUFFER_SIZE - raw->head));
  547. if (c <= 0)
  548. break;
  549. c -= copy_from_user(raw->buffer + raw->head,
  550.     str, c);
  551. if (c == 0) {
  552. if (!ret)
  553. ret = -EFAULT;
  554. break;
  555. }
  556. ASCEBC(raw->buffer + raw->head, c);
  557. raw->head = (raw->head + c) &
  558.     (RAW3215_BUFFER_SIZE - 1);
  559. raw->count += c;
  560. raw->line_pos += c;
  561. str += c;
  562. count -= c;
  563. ret += c;
  564. }
  565. } else {
  566. while (1) {
  567. c = MIN(count,
  568. MIN(RAW3215_BUFFER_SIZE - raw->count,
  569.     RAW3215_BUFFER_SIZE - raw->head));
  570. if (c <= 0)
  571. break;
  572. memcpy(raw->buffer + raw->head, str, c);
  573. ASCEBC(raw->buffer + raw->head, c);
  574. raw->head = (raw->head + c) &
  575.     (RAW3215_BUFFER_SIZE - 1);
  576. raw->count += c;
  577. raw->line_pos += c;
  578. str += c;
  579. count -= c;
  580. ret += c;
  581. }
  582. }
  583.                 if (!(raw->flags & RAW3215_WORKING)) {
  584.                         raw3215_mk_write_req(raw);
  585.         /* start or queue request */
  586.         raw3215_try_io(raw);
  587.                 }
  588. s390irq_spin_unlock_irqrestore(raw->irq, flags);
  589. }
  590. return ret;
  591. }
  592. /*
  593.  * Put character routine for 3215 devices
  594.  */
  595. static void raw3215_putchar(raw3215_info *raw, unsigned char ch)
  596. {
  597. unsigned long flags;
  598.         unsigned int length, i;
  599. s390irq_spin_lock_irqsave(raw->irq, flags);
  600. if (ch == 't') {
  601. length = TAB_STOP_SIZE - (raw->line_pos%TAB_STOP_SIZE);
  602. raw->line_pos += length;
  603. ch = ' ';
  604.         } else if (ch == 'n') {
  605. length = 1;
  606. raw->line_pos = 0;
  607. } else {
  608. length = 1;
  609. raw->line_pos++;
  610. }
  611.         raw3215_make_room(raw, length);
  612. for (i = 0; i < length; i++) {
  613. raw->buffer[raw->head] = (char) _ascebc[(int) ch];
  614. raw->head = (raw->head + 1) & (RAW3215_BUFFER_SIZE - 1);
  615. raw->count++;
  616. }
  617.         if (!(raw->flags & RAW3215_WORKING)) {
  618.                 raw3215_mk_write_req(raw);
  619.         /* start or queue request */
  620.         raw3215_try_io(raw);
  621.         }
  622. s390irq_spin_unlock_irqrestore(raw->irq, flags);
  623. }
  624. /*
  625.  * Flush routine, it simply sets the flush flag and tries to start 
  626.  * pending IO.
  627.  */
  628. static void raw3215_flush_buffer(raw3215_info *raw)
  629. {
  630. unsigned long flags;
  631. s390irq_spin_lock_irqsave(raw->irq, flags);
  632. if (raw->count > 0) {
  633. raw->flags |= RAW3215_FLUSHING;
  634. raw3215_try_io(raw);
  635. raw->flags &= ~RAW3215_FLUSHING;
  636. }
  637. s390irq_spin_unlock_irqrestore(raw->irq, flags);
  638. }
  639. /*
  640.  * Fire up a 3215 device.
  641.  */
  642. static int raw3215_startup(raw3215_info *raw)
  643. {
  644. unsigned long flags;
  645. if (raw->flags & RAW3215_ACTIVE)
  646. return 0;
  647. if (request_irq(raw->irq, raw3215_irq, SA_INTERRUPT,
  648. "3215 terminal driver", &raw->devstat) != 0)
  649. return -1;
  650. raw->line_pos = 0;
  651. raw->flags |= RAW3215_ACTIVE;
  652. s390irq_spin_lock_irqsave(raw->irq, flags);
  653.         set_cons_dev(raw->irq);
  654. raw3215_try_io(raw);
  655. s390irq_spin_unlock_irqrestore(raw->irq, flags);
  656. return 0;
  657. }
  658. /*
  659.  * Shutdown a 3215 device.
  660.  */
  661. static void raw3215_shutdown(raw3215_info *raw)
  662. {
  663.         DECLARE_WAITQUEUE(wait, current);
  664. unsigned long flags;
  665. if (!(raw->flags & RAW3215_ACTIVE) || (raw->flags & RAW3215_FIXED))
  666. return;
  667. /* Wait for outstanding requests, then free irq */
  668. s390irq_spin_lock_irqsave(raw->irq, flags);
  669. if ((raw->flags & RAW3215_WORKING) ||
  670.     raw->queued_write != NULL ||
  671.     raw->queued_read != NULL) {
  672. raw->flags |= RAW3215_CLOSING;
  673. add_wait_queue(&raw->empty_wait, &wait);
  674. current->state = TASK_INTERRUPTIBLE;
  675.                 s390irq_spin_unlock_irqrestore(raw->irq, flags);
  676. schedule();
  677. s390irq_spin_lock_irqsave(raw->irq, flags);
  678. remove_wait_queue(&raw->empty_wait, &wait);
  679.                 current->state = TASK_RUNNING;
  680. raw->flags &= ~(RAW3215_ACTIVE | RAW3215_CLOSING);
  681. }
  682. free_irq(raw->irq, NULL);
  683. s390irq_spin_unlock_irqrestore(raw->irq, flags);
  684. }
  685. static int
  686. raw3215_find_dev(int number)
  687. {
  688. s390_dev_info_t dinfo;
  689. int irq;
  690. int count;
  691. irq = get_irq_first();
  692. count = 0;
  693.         while (count <= number && irq != -ENODEV) {
  694.                 if (get_dev_info(irq, &dinfo) == -ENODEV)
  695.                         break;
  696.                 if (dinfo.devno == console_device ||
  697.                     dinfo.sid_data.cu_type == 0x3215) {
  698.                         count++;
  699.                     if (count > number)
  700.                         return irq;
  701.                 }
  702.                 irq = get_irq_next(irq);
  703.         }
  704.         return -1;            /* console not found */
  705. }
  706. #ifdef CONFIG_TN3215_CONSOLE
  707. /*
  708.  * Write a string to the 3215 console
  709.  */
  710. static void
  711. con3215_write(struct console *co, const char *str, unsigned int count)
  712. {
  713. raw3215_info *raw;
  714. int i;
  715. if (count <= 0)
  716. return;
  717.         raw = raw3215[0];       /* console 3215 is the first one */
  718.         while (count > 0) {
  719.                 for (i = 0; i < count; i++)
  720.                         if (str[i] == 't' || str[i] == 'n')
  721.                                 break;
  722.                 raw3215_write(raw, str, 0, i);
  723. count -= i;
  724. str += i;
  725.                 if (count > 0) {
  726. raw3215_putchar(raw, *str);
  727. count--;
  728. str++;
  729.                 }
  730.         }
  731. }
  732. kdev_t con3215_device(struct console *c)
  733. {
  734. return MKDEV(TTY_MAJOR, c->index + 64 );
  735. }
  736. /*
  737.  * panic() calls console_unblank before the system enters a
  738.  * disabled, endless loop.
  739.  */
  740. void con3215_unblank(void)
  741. {
  742. raw3215_info *raw;
  743. unsigned long flags;
  744. raw = raw3215[0];  /* console 3215 is the first one */
  745. s390irq_spin_lock_irqsave(raw->irq, flags);
  746. raw3215_make_room(raw, RAW3215_BUFFER_SIZE);
  747. s390irq_spin_unlock_irqrestore(raw->irq, flags);
  748. }
  749. static int __init con3215_consetup(struct console *co, char *options)
  750. {
  751. return 0;
  752. }
  753. /*
  754.  *  The console structure for the 3215 console
  755.  */
  756. static struct console con3215 = {
  757. name: "tty3215",
  758. write: con3215_write,
  759. device: con3215_device,
  760. unblank: con3215_unblank,
  761. setup: con3215_consetup,
  762. flags: CON_PRINTBUFFER,
  763. };
  764. #endif
  765. /*
  766.  * tty3215_open
  767.  *
  768.  * This routine is called whenever a 3215 tty is opened.
  769.  */
  770. static int tty3215_open(struct tty_struct *tty, struct file * filp)
  771. {
  772. raw3215_info *raw;
  773. int retval, line;
  774. line = MINOR(tty->device) - tty->driver.minor_start;
  775. if ((line < 0) || (line >= NR_3215))
  776. return -ENODEV;
  777. raw = raw3215[line];
  778. if (raw == NULL) {
  779. raw = kmalloc(sizeof(raw3215_info) +
  780.       RAW3215_INBUF_SIZE, GFP_KERNEL|GFP_DMA);
  781. if (raw == NULL)
  782. return -ENOMEM;
  783. raw->irq = raw3215_find_dev(line);
  784. if (raw->irq == -1) {
  785. kfree(raw);
  786. return -ENODEV;
  787. }
  788. raw->inbuf = (char *) raw + sizeof(raw3215_info);
  789. memset(raw, 0, sizeof(raw3215_info));
  790. raw->buffer = (char *) kmalloc(RAW3215_BUFFER_SIZE,
  791.        GFP_KERNEL|GFP_DMA);
  792. if (raw->buffer == NULL) {
  793. kfree(raw);
  794. return -ENOMEM;
  795. }
  796. raw->tqueue.routine = raw3215_softint;
  797. raw->tqueue.data = raw;
  798.                 init_waitqueue_head(&raw->empty_wait);
  799. raw3215[line] = raw;
  800. }
  801. tty->driver_data = raw;
  802. raw->tty = tty;
  803. tty->low_latency = 0;  /* don't use bottom half for pushing chars */
  804. /*
  805.  * Start up 3215 device
  806.  */
  807. retval = raw3215_startup(raw);
  808. if (retval)
  809. return retval;
  810. return 0;
  811. }
  812. /*
  813.  * tty3215_close()
  814.  *
  815.  * This routine is called when the 3215 tty is closed. We wait
  816.  * for the remaining request to be completed. Then we clean up.
  817.  */
  818. static void tty3215_close(struct tty_struct *tty, struct file * filp)
  819. {
  820. raw3215_info *raw;
  821. raw = (raw3215_info *) tty->driver_data;
  822. if (raw == NULL || tty->count > 1)
  823. return;
  824. tty->closing = 1;
  825. /* Shutdown the terminal */
  826. raw3215_shutdown(raw);
  827. tty->closing = 0;
  828. raw->tty = NULL;
  829. }
  830. /*
  831.  * Returns the amount of free space in the output buffer.
  832.  */
  833. static int tty3215_write_room(struct tty_struct *tty)
  834. {
  835. raw3215_info *raw;
  836. raw = (raw3215_info *) tty->driver_data;
  837. /* Subtract TAB_STOP_SIZE to allow for a tab, 8 <<< 64K */
  838. if ((RAW3215_BUFFER_SIZE - raw->count - TAB_STOP_SIZE) >= 0)
  839. return RAW3215_BUFFER_SIZE - raw->count - TAB_STOP_SIZE;
  840. else
  841. return 0;
  842. }
  843. /*
  844.  * String write routine for 3215 ttys
  845.  */
  846. static int tty3215_write(struct tty_struct * tty, int from_user,
  847.     const unsigned char *buf, int count)
  848. {
  849. raw3215_info *raw;
  850. int ret = 0;
  851. if (!tty)
  852. return 0;
  853. raw = (raw3215_info *) tty->driver_data;
  854. ret = raw3215_write(raw, buf, from_user, count);
  855. return ret;
  856. }
  857. /*
  858.  * Put character routine for 3215 ttys
  859.  */
  860. static void tty3215_put_char(struct tty_struct *tty, unsigned char ch)
  861. {
  862. raw3215_info *raw;
  863. if (!tty)
  864. return;
  865. raw = (raw3215_info *) tty->driver_data;
  866. raw3215_putchar(raw, ch);
  867. }
  868. static void tty3215_flush_chars(struct tty_struct *tty)
  869. {
  870. }
  871. /*
  872.  * Returns the number of characters in the output buffer
  873.  */
  874. static int tty3215_chars_in_buffer(struct tty_struct *tty)
  875. {
  876. raw3215_info *raw;
  877. raw = (raw3215_info *) tty->driver_data;
  878. return raw->count;
  879. }
  880. static void tty3215_flush_buffer(struct tty_struct *tty)
  881. {
  882. raw3215_info *raw;
  883. raw = (raw3215_info *) tty->driver_data;
  884. raw3215_flush_buffer(raw);
  885. wake_up_interruptible(&tty->write_wait);
  886. if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
  887.     tty->ldisc.write_wakeup)
  888. (tty->ldisc.write_wakeup)(tty);
  889. }
  890. /*
  891.  * Currently we don't have any io controls for 3215 ttys
  892.  */
  893. static int tty3215_ioctl(struct tty_struct *tty, struct file * file,
  894.     unsigned int cmd, unsigned long arg)
  895. {
  896. if (tty->flags & (1 << TTY_IO_ERROR))
  897. return -EIO;
  898. switch (cmd) {
  899. default:
  900. return -ENOIOCTLCMD;
  901. }
  902. return 0;
  903. }
  904. /*
  905.  * Disable reading from a 3215 tty
  906.  */
  907. static void tty3215_throttle(struct tty_struct * tty)
  908. {
  909. raw3215_info *raw;
  910. raw = (raw3215_info *) tty->driver_data;
  911. raw->flags |= RAW3215_THROTTLED;
  912. }
  913. /*
  914.  * Enable reading from a 3215 tty
  915.  */
  916. static void tty3215_unthrottle(struct tty_struct * tty)
  917. {
  918. raw3215_info *raw;
  919. unsigned long flags;
  920. raw = (raw3215_info *) tty->driver_data;
  921. if (raw->flags & RAW3215_THROTTLED) {
  922. s390irq_spin_lock_irqsave(raw->irq, flags);
  923. raw->flags &= ~RAW3215_THROTTLED;
  924. raw3215_try_io(raw);
  925. s390irq_spin_unlock_irqrestore(raw->irq, flags);
  926. }
  927. }
  928. /*
  929.  * Disable writing to a 3215 tty
  930.  */
  931. static void tty3215_stop(struct tty_struct *tty)
  932. {
  933. raw3215_info *raw;
  934. raw = (raw3215_info *) tty->driver_data;
  935. raw->flags |= RAW3215_STOPPED;
  936. }
  937. /*
  938.  * Enable writing to a 3215 tty
  939.  */
  940. static void tty3215_start(struct tty_struct *tty)
  941. {
  942. raw3215_info *raw;
  943. unsigned long flags;
  944. raw = (raw3215_info *) tty->driver_data;
  945. if (raw->flags & RAW3215_STOPPED) {
  946. s390irq_spin_lock_irqsave(raw->irq, flags);
  947. raw->flags &= ~RAW3215_STOPPED;
  948. raw3215_try_io(raw);
  949. s390irq_spin_unlock_irqrestore(raw->irq, flags);
  950. }
  951. }
  952. /*
  953.  * 3215 console initialization code called from console_init().
  954.  * NOTE: This is called before kmalloc is available.
  955.  */
  956. void __init con3215_init(void)
  957. {
  958. raw3215_info *raw;
  959. raw3215_req *req;
  960. int irq;
  961. int i;
  962. /* Check if 3215 is to be the console */
  963. if (!CONSOLE_IS_3215)
  964. return;
  965. irq = raw3215_find_dev(0);
  966. /* Set the console mode for VM */
  967. if (MACHINE_IS_VM) {
  968. cpcmd("TERM CONMODE 3215", NULL, 0);
  969. cpcmd("TERM AUTOCR OFF", NULL, 0);
  970. }
  971. /* allocate 3215 request structures */
  972. raw3215_freelist = NULL;
  973. spin_lock_init(&raw3215_freelist_lock);
  974. for (i = 0; i < NR_3215_REQ; i++) {
  975.                 req = (raw3215_req *) alloc_bootmem_low(sizeof(raw3215_req));
  976. req->next = raw3215_freelist;
  977. raw3215_freelist = req;
  978. }
  979. ctrlchar_init();
  980. #ifdef CONFIG_TN3215_CONSOLE
  981.         raw3215[0] = raw = (raw3215_info *)
  982.                 alloc_bootmem_low(sizeof(raw3215_info));
  983. memset(raw, 0, sizeof(raw3215_info));
  984.         raw->buffer = (char *) alloc_bootmem_low(RAW3215_BUFFER_SIZE);
  985.         raw->inbuf = (char *) alloc_bootmem_low(RAW3215_INBUF_SIZE);
  986. /* Find the first console */
  987. raw->irq = raw3215_find_dev(0);
  988. raw->flags |= RAW3215_FIXED;
  989. raw->tqueue.routine = raw3215_softint;
  990. raw->tqueue.data = raw;
  991.         init_waitqueue_head(&raw->empty_wait);
  992. /* Request the console irq */
  993. if ( raw3215_startup(raw) != 0 )
  994. raw->irq = -1;
  995. if (raw->irq != -1) {
  996. register_console(&con3215);
  997. } else {
  998.                 free_bootmem((unsigned long) raw->inbuf, RAW3215_INBUF_SIZE);
  999.                 free_bootmem((unsigned long) raw->buffer, RAW3215_BUFFER_SIZE);
  1000.                 free_bootmem((unsigned long) raw, sizeof(raw3215_info));
  1001. raw3215[0] = NULL;
  1002. printk("Couldn't find a 3215 console devicen");
  1003. }
  1004. #endif
  1005. }
  1006. /*
  1007.  * 3215 tty registration code called from tty_init().
  1008.  * Most kernel services (incl. kmalloc) are available at this poimt.
  1009.  */
  1010. void __init tty3215_init(void)
  1011. {
  1012. /*
  1013.  * Initialize the tty_driver structure
  1014.  * Entries in tty3215_driver that are NOT initialized:
  1015.  * proc_entry, set_termios, flush_buffer, set_ldisc, write_proc
  1016.  */
  1017. memset(&tty3215_driver, 0, sizeof(struct tty_driver));
  1018. tty3215_driver.magic = TTY_DRIVER_MAGIC;
  1019. tty3215_driver.driver_name = "tty3215";
  1020. tty3215_driver.name = "ttyS";
  1021. tty3215_driver.name_base = 0;
  1022. tty3215_driver.major = TTY_MAJOR;
  1023. tty3215_driver.minor_start = 64;
  1024. tty3215_driver.num = NR_3215;
  1025. tty3215_driver.type = TTY_DRIVER_TYPE_SYSTEM;
  1026. tty3215_driver.subtype = SYSTEM_TYPE_TTY;
  1027. tty3215_driver.init_termios = tty_std_termios;
  1028. tty3215_driver.init_termios.c_iflag = IGNBRK | IGNPAR;
  1029. tty3215_driver.init_termios.c_oflag = ONLCR | XTABS;
  1030. tty3215_driver.init_termios.c_lflag = ISIG;
  1031. tty3215_driver.flags = TTY_DRIVER_REAL_RAW; 
  1032. tty3215_driver.refcount = &tty3215_refcount;
  1033. tty3215_driver.table = tty3215_table;
  1034. tty3215_driver.termios = tty3215_termios;
  1035. tty3215_driver.termios_locked = tty3215_termios_locked;
  1036. tty3215_driver.open = tty3215_open;
  1037. tty3215_driver.close = tty3215_close;
  1038. tty3215_driver.write = tty3215_write;
  1039. tty3215_driver.put_char = tty3215_put_char;
  1040. tty3215_driver.flush_chars = tty3215_flush_chars;
  1041. tty3215_driver.write_room = tty3215_write_room;
  1042. tty3215_driver.chars_in_buffer = tty3215_chars_in_buffer;
  1043. tty3215_driver.flush_buffer = tty3215_flush_buffer;
  1044. tty3215_driver.ioctl = tty3215_ioctl;
  1045. tty3215_driver.throttle = tty3215_throttle;
  1046. tty3215_driver.unthrottle = tty3215_unthrottle;
  1047. tty3215_driver.send_xchar = NULL;
  1048. tty3215_driver.set_termios = NULL;
  1049. tty3215_driver.stop = tty3215_stop;
  1050. tty3215_driver.start = tty3215_start;
  1051. tty3215_driver.hangup = NULL;
  1052. tty3215_driver.break_ctl = NULL;
  1053. tty3215_driver.wait_until_sent = NULL;
  1054. tty3215_driver.read_proc = NULL;
  1055. if (tty_register_driver(&tty3215_driver))
  1056. panic("Couldn't register tty3215 drivern");
  1057. }