X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fchar%2Fgeneric_serial.c;h=8facf3e25c490f75773a857a012e66a968469654;hb=6920c12a407e073168d6cae164fa820d666af5c6;hp=5e59c0b42731990818df9c713adb635f378ec236;hpb=81861d78c9edf9a9b03a9ba1f5b242d658f16832;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c index 5e59c0b..8facf3e 100644 --- a/drivers/char/generic_serial.c +++ b/drivers/char/generic_serial.c @@ -33,8 +33,6 @@ #define DEBUG -static char * tmp_buf; - static int gs_debug; #ifdef DEBUG @@ -45,16 +43,6 @@ static int gs_debug; #define func_enter() gs_dprintk (GS_DEBUG_FLOW, "gs: enter %s\n", __FUNCTION__) #define func_exit() gs_dprintk (GS_DEBUG_FLOW, "gs: exit %s\n", __FUNCTION__) -#define NEW_WRITE_LOCKING 1 -#if NEW_WRITE_LOCKING -#define DECL /* Nothing */ -#define LOCKIT mutex_lock(& port->port_write_mutex); -#define RELEASEIT mutex_unlock(&port->port_write_mutex); -#else -#define DECL unsigned long flags; -#define LOCKIT save_flags (flags);cli () -#define RELEASEIT restore_flags (flags) -#endif #define RS_EVENT_WRITE_WAKEUP 1 @@ -64,7 +52,6 @@ module_param(gs_debug, int, 0644); void gs_put_char(struct tty_struct * tty, unsigned char ch) { struct gs_port *port; - DECL func_enter (); @@ -77,11 +64,11 @@ void gs_put_char(struct tty_struct * tty, unsigned char ch) if (! (port->flags & ASYNC_INITIALIZED)) return; /* Take a lock on the serial tranmit buffer! */ - LOCKIT; + mutex_lock(& port->port_write_mutex); if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) { /* Sorry, buffer is full, drop character. Update statistics???? -- REW */ - RELEASEIT; + mutex_unlock(&port->port_write_mutex); return; } @@ -89,13 +76,11 @@ void gs_put_char(struct tty_struct * tty, unsigned char ch) port->xmit_head &= SERIAL_XMIT_SIZE - 1; port->xmit_cnt++; /* Characters in buffer */ - RELEASEIT; + mutex_unlock(&port->port_write_mutex); func_exit (); } -#ifdef NEW_WRITE_LOCKING - /* > Problems to take into account are: > -1- Interrupts that empty part of the buffer. @@ -168,90 +153,6 @@ int gs_write(struct tty_struct * tty, func_exit (); return total; } -#else -/* -> Problems to take into account are: -> -1- Interrupts that empty part of the buffer. -> -2- page faults on the access to userspace. -> -3- Other processes that are also trying to do a "write". -*/ - -int gs_write(struct tty_struct * tty, - const unsigned char *buf, int count) -{ - struct gs_port *port; - int c, total = 0; - int t; - unsigned long flags; - - func_enter (); - - /* The standard serial driver returns 0 in this case. - That sounds to me as "No error, I just didn't get to writing any - bytes. Feel free to try again." - The "official" way to write n bytes from buf is: - - for (nwritten = 0;nwritten < n;nwritten += rv) { - rv = write (fd, buf+nwritten, n-nwritten); - if (rv < 0) break; // Error: bail out. // - } - - which will loop endlessly in this case. The manual page for write - agrees with me. In practise almost everybody writes - "write (fd, buf,n);" but some people might have had to deal with - incomplete writes in the past and correctly implemented it by now... - */ - - if (!tty) return -EIO; - - port = tty->driver_data; - if (!port || !port->xmit_buf || !tmp_buf) - return -EIO; - - local_save_flags(flags); - while (1) { - cli(); - c = count; - - /* This is safe because we "OWN" the "head". Noone else can - change the "head": we own the port_write_mutex. */ - /* Don't overrun the end of the buffer */ - t = SERIAL_XMIT_SIZE - port->xmit_head; - if (t < c) c = t; - - /* This is safe because the xmit_cnt can only decrease. This - would increase "t", so we might copy too little chars. */ - /* Don't copy past the "head" of the buffer */ - t = SERIAL_XMIT_SIZE - 1 - port->xmit_cnt; - if (t < c) c = t; - - /* Can't copy more? break out! */ - if (c <= 0) { - local_restore_flags(flags); - break; - } - memcpy(port->xmit_buf + port->xmit_head, buf, c); - port->xmit_head = ((port->xmit_head + c) & - (SERIAL_XMIT_SIZE-1)); - port->xmit_cnt += c; - local_restore_flags(flags); - buf += c; - count -= c; - total += c; - } - - if (port->xmit_cnt && - !tty->stopped && - !tty->hw_stopped && - !(port->flags & GS_TX_INTEN)) { - port->flags |= GS_TX_INTEN; - port->rd->enable_tx_interrupts (port); - } - func_exit (); - return total; -} - -#endif @@ -384,7 +285,6 @@ void gs_flush_buffer(struct tty_struct *tty) port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; spin_unlock_irqrestore (&port->driver_lock, flags); - wake_up_interruptible(&tty->write_wait); tty_wakeup(tty); func_exit (); } @@ -713,18 +613,12 @@ void gs_close(struct tty_struct * tty, struct file * filp) } -static unsigned int gs_baudrates[] = { - 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, - 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600 -}; - - void gs_set_termios (struct tty_struct * tty, - struct termios * old_termios) + struct ktermios * old_termios) { struct gs_port *port; int baudrate, tmp, rv; - struct termios *tiosp; + struct ktermios *tiosp; func_enter(); @@ -746,25 +640,6 @@ void gs_set_termios (struct tty_struct * tty, gs_dprintk (GS_DEBUG_TERMIOS, "termios structure (%p):\n", tiosp); } -#if 0 - /* This is an optimization that is only allowed for dumb cards */ - /* Smart cards require knowledge of iflags and oflags too: that - might change hardware cooking mode.... */ -#endif - if (old_termios) { - if( (tiosp->c_iflag == old_termios->c_iflag) - && (tiosp->c_oflag == old_termios->c_oflag) - && (tiosp->c_cflag == old_termios->c_cflag) - && (tiosp->c_lflag == old_termios->c_lflag) - && (tiosp->c_line == old_termios->c_line) - && (memcmp(tiosp->c_cc, old_termios->c_cc, NCC) == 0)) { - gs_dprintk(GS_DEBUG_TERMIOS, "gs_set_termios: optimized away\n"); - return /* 0 */; - } - } else - gs_dprintk(GS_DEBUG_TERMIOS, "gs_set_termios: no old_termios: " - "no optimization\n"); - if(old_termios && (gs_debug & GS_DEBUG_TERMIOS)) { if(tiosp->c_iflag != old_termios->c_iflag) printk("c_iflag changed\n"); if(tiosp->c_oflag != old_termios->c_oflag) printk("c_oflag changed\n"); @@ -774,16 +649,8 @@ void gs_set_termios (struct tty_struct * tty, if(!memcmp(tiosp->c_cc, old_termios->c_cc, NCC)) printk("c_cc changed\n"); } - baudrate = tiosp->c_cflag & CBAUD; - if (baudrate & CBAUDEX) { - baudrate &= ~CBAUDEX; - if ((baudrate < 1) || (baudrate > 4)) - tiosp->c_cflag &= ~CBAUDEX; - else - baudrate += 15; - } + baudrate = tty_get_baud_rate(tty); - baudrate = gs_baudrates[baudrate]; if ((tiosp->c_cflag & CBAUD) == B38400) { if ( (port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) baudrate = 57600; @@ -846,24 +713,9 @@ void gs_set_termios (struct tty_struct * tty, int gs_init_port(struct gs_port *port) { unsigned long flags; - unsigned long page; func_enter (); - if (!tmp_buf) { - page = get_zeroed_page(GFP_KERNEL); - spin_lock_irqsave (&port->driver_lock, flags); /* Don't expect this to make a difference. */ - if (tmp_buf) - free_page(page); - else - tmp_buf = (unsigned char *) page; - spin_unlock_irqrestore (&port->driver_lock, flags); - if (!tmp_buf) { - func_exit (); - return -ENOMEM; - } - } - if (port->flags & ASYNC_INITIALIZED) { func_exit (); return 0;