X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fia64%2Fhp%2Fsim%2Fsimserial.c;h=0e5c6ae502288f97d0dcf9e55671aa269ce94511;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=381277884e6cb59bef91cdfcbca5e2b7d095037b;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c index 381277884..0e5c6ae50 100644 --- a/arch/ia64/hp/sim/simserial.c +++ b/arch/ia64/hp/sim/simserial.c @@ -26,10 +26,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include @@ -44,15 +46,6 @@ #define KEYBOARD_INTR 3 /* must match with simulator! */ #define NR_PORTS 1 /* only one port for now */ -#define SERIAL_INLINE 1 - -#ifdef SERIAL_INLINE -#define _INLINE_ inline -#endif - -#ifndef MIN -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#endif #define IRQ_T(info) ((info->flags & ASYNC_SHARE_IRQ) ? SA_SHIRQ : SA_INTERRUPT) @@ -110,7 +103,6 @@ static struct async_struct *IRQ_ports[NR_IRQS]; static struct console *console; static unsigned char *tmp_buf; -static DECLARE_MUTEX(tmp_buf_sem); extern struct console *console_drivers; /* from kernel/printk.c */ @@ -133,7 +125,7 @@ static void rs_stop(struct tty_struct *tty) static void rs_start(struct tty_struct *tty) { -#if SIMSERIAL_DEBUG +#ifdef SIMSERIAL_DEBUG printk("rs_start: tty->stopped=%d tty->hw_stopped=%d tty->flow_stopped=%d\n", tty->stopped, tty->hw_stopped, tty->flow_stopped); #endif @@ -153,26 +145,25 @@ static void receive_chars(struct tty_struct *tty, struct pt_regs *regs) seen_esc = 2; continue; } else if ( seen_esc == 2 ) { - if ( ch == 'P' ) show_state(); /* F1 key */ -#ifdef CONFIG_KDB - if ( ch == 'S' ) - kdb(KDB_REASON_KEYBOARD, 0, (kdb_eframe_t) regs); + if ( ch == 'P' ) /* F1 */ + show_state(); +#ifdef CONFIG_MAGIC_SYSRQ + if ( ch == 'S' ) { /* F4 */ + do + ch = ia64_ssc(0, 0, 0, 0, + SSC_GETCHAR); + while (!ch); + handle_sysrq(ch, regs, NULL); + } #endif - seen_esc = 0; continue; } } seen_esc = 0; - if (tty->flip.count >= TTY_FLIPBUF_SIZE) break; - - *tty->flip.char_buf_ptr = ch; - *tty->flip.flag_buf_ptr = 0; - - tty->flip.flag_buf_ptr++; - tty->flip.char_buf_ptr++; - tty->flip.count++; + if (tty_insert_flip_char(tty, ch, TTY_NORMAL) == 0) + break; } tty_flip_buffer_push(tty); } @@ -241,7 +232,7 @@ static void rs_put_char(struct tty_struct *tty, unsigned char ch) local_irq_restore(flags); } -static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done) +static void transmit_chars(struct async_struct *info, int *intr_done) { int count; unsigned long flags; @@ -275,7 +266,7 @@ static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done) * Then from the beginning of the buffer until necessary */ - count = MIN(CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE), + count = min(CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE), SERIAL_XMIT_SIZE - info->xmit.tail); console->write(console, info->xmit.buf+info->xmit.tail, count); @@ -305,7 +296,7 @@ static void rs_flush_chars(struct tty_struct *tty) } -static int rs_write(struct tty_struct * tty, int from_user, +static int rs_write(struct tty_struct * tty, const unsigned char *buf, int count) { int c, ret = 0; @@ -314,58 +305,22 @@ static int rs_write(struct tty_struct * tty, int from_user, if (!tty || !info->xmit.buf || !tmp_buf) return 0; - if (from_user) { - down(&tmp_buf_sem); - while (1) { - int c1; - c = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); - if (count < c) - c = count; - if (c <= 0) - break; - - c -= copy_from_user(tmp_buf, buf, c); - if (!c) { - if (!ret) - ret = -EFAULT; - break; - } - - local_irq_save(flags); - { - c1 = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, - SERIAL_XMIT_SIZE); - if (c1 < c) - c = c1; - memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c); - info->xmit.head = ((info->xmit.head + c) & - (SERIAL_XMIT_SIZE-1)); - } - local_irq_restore(flags); - - buf += c; - count -= c; - ret += c; - } - up(&tmp_buf_sem); - } else { - local_irq_save(flags); - while (1) { - c = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); - if (count < c) - c = count; - if (c <= 0) { - break; - } - memcpy(info->xmit.buf + info->xmit.head, buf, c); - info->xmit.head = ((info->xmit.head + c) & - (SERIAL_XMIT_SIZE-1)); - buf += c; - count -= c; - ret += c; + local_irq_save(flags); + while (1) { + c = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); + if (count < c) + c = count; + if (c <= 0) { + break; } - local_irq_restore(flags); + memcpy(info->xmit.buf + info->xmit.head, buf, c); + info->xmit.head = ((info->xmit.head + c) & + (SERIAL_XMIT_SIZE-1)); + buf += c; + count -= c; + ret += c; } + local_irq_restore(flags); /* * Hey, we transmit directly from here in our case */ @@ -676,10 +631,8 @@ static void rs_close(struct tty_struct *tty, struct file * filp) info->event = 0; info->tty = 0; if (info->blocked_open) { - if (info->close_delay) { - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(info->close_delay); - } + if (info->close_delay) + schedule_timeout_interruptible(info->close_delay); wake_up_interruptible(&info->open_wait); } info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); @@ -1016,7 +969,7 @@ static struct tty_operations hp_ops = { static int __init simrs_init (void) { - int i; + int i, rc; struct serial_state *state; if (!ia64_platform_is("hpsim")) @@ -1051,11 +1004,14 @@ simrs_init (void) if (state->type == PORT_UNKNOWN) continue; if (!state->irq) { - state->irq = assign_irq_vector(AUTO_ASSIGN); + if ((rc = assign_irq_vector(AUTO_ASSIGN)) < 0) + panic("%s: out of interrupt vectors!\n", + __FUNCTION__); + state->irq = rc; ia64_ssc_connect_irq(KEYBOARD_INTR, state->irq); } - printk(KERN_INFO "ttyS%02d at 0x%04lx (irq = %d) is a %s\n", + printk(KERN_INFO "ttyS%d at 0x%04lx (irq = %d) is a %s\n", state->line, state->port, state->irq, uart_config[state->type].name);