tty/serial: Lay the foundations for the next set of reworks
Subsystems (2)
PATCH 1/1 tty/serial: Lay the foundations for the next set of reworks
- Stop drivers calling their own flush method indirectly, it obfuscates code and it will change soon anyway
- A few more lock_kernel paths temporarily needed in some driver internal waiting code
- Remove private put_char method that does a write call for one char - we have that anyway
- Most but not yet all of the termios copy under lock fixing (some has other dependancies to follow)
- Note a few locking bugs in drivers found in the process
- Kill remaining [ab]users of TIOCG/SSOFTCAR in the driver, these must go to fix the termios locking
drivers/char/amiserial.c +4 -2
@@ -1505,8 +1506,7 @@rs_wait_until_sent (tty, info->timeout); }shutdown (info); -if (tty->driver->flush_buffer) - tty->driver->flush_buffer (tty); +rs_flush_buffer (tty);tty_ldisc_flush (tty); tty->closing =0 ;
@@ -1539,6 +1539,8 @@return ;/* Just in case.... */ orig_jiffies = jiffies; + +lock_kernel ();/* * Set the check interval to be 1/5 of the estimated time to * send a single character, and make it at least 1. The check
@@ -1579,6 +1581,7 @@break ; }__set_current_state (TASK_RUNNING ); +unlock_kernel ();#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT printk ("lsr = %d (jiff=%lu)...done\n" , lsr, jiffies);#endif
drivers/char/cyclades.c +40 -36
117 lines not on this page · raw message
drivers/char/epca.c +2 -11
@@ -157,7 +157,6 @@static void pc_close (struct tty_struct *,struct file *);static void shutdown (struct channel *);static void pc_hangup (struct tty_struct *); -static void pc_put_char (struct tty_struct *,unsigned char );static int pc_write_room (struct tty_struct *);static int pc_chars_in_buffer (struct tty_struct *);static void pc_flush_buffer (struct tty_struct *);
@@ -459,8 +458,7 @@setup_empty_event (tty, ch);tty_wait_until_sent (tty,3000 );/* 30 seconds timeout */ } -if (tty->driver->flush_buffer) - tty->driver->flush_buffer (tty); +pc_flush_buffer (tty);tty_ldisc_flush (tty);shutdown (ch);
@@ -532,8 +530,7 @@if ((ch =verifyChannel (tty)) !=NULL ) {unsigned long flags; -if (tty->driver->flush_buffer) - tty->driver->flush_buffer (tty); +pc_flush_buffer (tty);tty_ldisc_flush (tty);shutdown (ch);
@@ -645,11 +642,6 @@return amountCopied; } -static void pc_put_char (struct tty_struct *tty,unsigned char c) -{ -pc_write (tty, &c,1 ); -} -static int pc_write_room (struct tty_struct *tty) {int remain;
@@ -1035,7 +1027,6 @@ .flush_buffer = pc_flush_buffer, .chars_in_buffer = pc_chars_in_buffer, .flush_chars = pc_flush_chars, - .put_char = pc_put_char, .ioctl = pc_ioctl, .set_termios = pc_set_termios, .stop = pc_stop,
drivers/char/esp.c +1 -2
@@ -1994,8 +1997,7 @@rs_wait_until_sent (tty, info->timeout); }shutdown (info); -if (tty->driver->flush_buffer) - tty->driver->flush_buffer (tty); +rs_flush_buffer (tty);tty_ldisc_flush (tty); tty->closing =0 ; info->tty =NULL ;
drivers/char/generic_serial.c +1 -2
@@ -587,8 +588,7 @@ port->flags &= ~GS_ACTIVE ; -if (tty->driver->flush_buffer) - tty->driver->flush_buffer (tty); +gs_flush_buffer (tty);tty_ldisc_flush (tty); tty->closing =0 ;
drivers/char/isicom.c +17 -18
@@ -1012,6 +1012,22 @@ } } +static void isicom_flush_buffer (struct tty_struct *tty) +{ +struct isi_port *port = tty->driver_data; +struct isi_board *card = port->card; +unsigned long flags; + +if (isicom_paranoia_check (port, tty->name,"isicom_flush_buffer" )) +return ; + +spin_lock_irqsave (&card->card_lock, flags); + port->xmit_cnt = port->xmit_head = port->xmit_tail =0 ; +spin_unlock_irqrestore (&card->card_lock, flags); + +tty_wakeup (tty); +} +static void isicom_close (struct tty_struct *tty,struct file *filp) {struct isi_port *port = tty->driver_data;
@@ -1065,8 +1081,7 @@isicom_shutdown_port (port);spin_unlock_irqrestore (&card->card_lock, flags); -if (tty->driver->flush_buffer) - tty->driver->flush_buffer (tty); +isicom_flush_buffer (tty);tty_ldisc_flush (tty);spin_lock_irqsave (&card->card_lock, flags);
@@ -1447,22 +1463,6 @@wake_up_interruptible (&port->open_wait); } -/* flush_buffer et all */ -static void isicom_flush_buffer (struct tty_struct *tty) -{ -struct isi_port *port = tty->driver_data; -struct isi_board *card = port->card; -unsigned long flags; - -if (isicom_paranoia_check (port, tty->name,"isicom_flush_buffer" )) -return ; - -spin_lock_irqsave (&card->card_lock, flags); - port->xmit_cnt = port->xmit_head = port->xmit_tail =0 ; -spin_unlock_irqrestore (&card->card_lock, flags); - -tty_wakeup (tty); -}/* * Driver init and deinit functions
drivers/char/moxa.c +2 -0
@@ -1280,6 +1280,7 @@*/ if (ch ==NULL )return 0 ; +lock_kernel (); chars =MoxaPortTxQueue (ch);if (chars) {/*
@@ -1289,6 +1290,7 @@if (!(ch->statusflags &EMPTYWAIT ))moxa_setup_empty_event (tty); } +unlock_kernel ();return chars; }
drivers/char/mxser.c +24 -23
77 lines not on this page · raw message
drivers/char/nozomi.c +2 -11
@@ -1724,6 +1724,8 @@const struct ctrl_dl *ctrl_dl = &port->ctrl_dl;const struct ctrl_ul *ctrl_ul = &port->ctrl_ul; +/* Note: these could change under us but it is not clear this +matters if so */ return (ctrl_ul->RTS ?TIOCM_RTS :0 ) | (ctrl_ul->DTR ?TIOCM_DTR :0 ) | (ctrl_dl->DCD ? TIOCM_CAR : 0) |
@@ -1849,16 +1851,6 @@spin_unlock_irqrestore (&dc->spin_mutex, flags); } -/* just to discard single character writes */ -static void ntty_put_char (struct tty_struct *tty,unsigned char c) -{ -/* -* card does not react correct when we write single chars -* to the card, so we discard them -*/ -DBG2 ("PUT CHAR Function: %c" , c); -} -/* Returns number of chars in buffer, called by tty layer */ static s32 ntty_chars_in_buffer (struct tty_struct *tty) {
@@ -1892,7 +1884,6 @@ .unthrottle = ntty_unthrottle, .throttle = ntty_throttle, .chars_in_buffer = ntty_chars_in_buffer, - .put_char = ntty_put_char, .tiocmget = ntty_tiocmget, .tiocmset = ntty_tiocmset, };
drivers/char/pcmcia/synclink_cs.c +2 -14
@@ -503,20 +503,9 @@* The wrappers maintain line discipline references * while calling into the line discipline. * -* ldisc_flush_buffer - flush line discipline receive buffers * ldisc_receive_buf - pass receive data to line discipline */ -static void ldisc_flush_buffer (struct tty_struct *tty) -{ -struct tty_ldisc *ld =tty_ldisc_ref (tty); -if (ld) { -if (ld->flush_buffer) - ld->flush_buffer (tty); -tty_ldisc_deref (ld); - } -} -static void ldisc_receive_buf (struct tty_struct *tty,const __u8 *data,char *flags,int count) {
@@ -2469,10 +2459,9 @@if (info->flags &ASYNC_INITIALIZED )mgslpc_wait_until_sent (tty, info->timeout); -if (tty->driver->flush_buffer) - tty->driver->flush_buffer (tty); +mgslpc_flush_buffer (tty); -ldisc_flush_buffer (tty); +tty_ldisc_flush (tty);shutdown (info);
drivers/char/riscom8.c +19 -19
@@ -1015,6 +1015,24 @@return 0 ; } +static void rc_flush_buffer (struct tty_struct *tty) +{ +struct riscom_port *port = (struct riscom_port *)tty->driver_data; +unsigned long flags; + +if (rc_paranoia_check (port, tty->name,"rc_flush_buffer" )) +return ; + +spin_lock_irqsave (&riscom_lock, flags); + + port->xmit_cnt = port->xmit_head = port->xmit_tail =0 ; + +spin_unlock_irqrestore (&riscom_lock, flags); + +tty_wakeup (tty); +} + +static void rc_close (struct tty_struct * tty,struct file * filp) {struct riscom_port *port = (struct riscom_port *) tty->driver_data;
@@ -1078,8 +1096,7 @@ } }rc_shutdown_port (bp, port); -if (tty->driver->flush_buffer) - tty->driver->flush_buffer (tty); +rc_flush_buffer (tty);tty_ldisc_flush (tty); tty->closing =0 ;
@@ -1213,23 +1233,6 @@return port->xmit_cnt; } -static void rc_flush_buffer (struct tty_struct *tty) -{ -struct riscom_port *port = (struct riscom_port *)tty->driver_data; -unsigned long flags; - -if (rc_paranoia_check (port, tty->name,"rc_flush_buffer" )) -return ; - -spin_lock_irqsave (&riscom_lock, flags); - - port->xmit_cnt = port->xmit_head = port->xmit_tail =0 ; - -spin_unlock_irqrestore (&riscom_lock, flags); - -tty_wakeup (tty); -} -static int rc_tiocmget (struct tty_struct *tty,struct file *file) {struct riscom_port *port = (struct riscom_port *)tty->driver_data;
drivers/char/rocket.c +2 -0
@@ -1585,6 +1585,7 @@ jiffies);printk (KERN_INFO "cps=%d...\n" , info->cps);#endif +lock_kernel ();while (1 ) { txcnt =sGetTxCnt (cp);if (!txcnt) {
@@ -1612,6 +1613,7 @@break ; }__set_current_state (TASK_RUNNING ); +unlock_kernel ();#ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT printk (KERN_INFO "txcnt = %d (jiff=%lu)...done\n" , txcnt, jiffies);#endif
drivers/char/serial167.c +1 -2
@@ -1674,8 +1675,7 @@if (info->flags &ASYNC_INITIALIZED )tty_wait_until_sent (tty,3000 );/* 30 seconds timeout */ shutdown (info); -if (tty->driver->flush_buffer) - tty->driver->flush_buffer (tty); +cy_flush_buffer (tty);tty_ldisc_flush (tty); info->tty =NULL ;if (info->blocked_open) {
drivers/char/specialix.c +22 -24
64 lines not on this page · raw message
drivers/char/stallion.c +2 -0
@@ -875,6 +875,7 @@ timeout =HZ ; tend = jiffies + timeout; +lock_kernel ();while (stl_datastate (portp)) {if (signal_pending (current))break ;
@@ -882,6 +883,7 @@if (time_after_eq (jiffies, tend))break ; } +unlock_kernel (); }/*****************************************************************************/
drivers/char/synclink.c +4 -3
@@ -3160,8 +3161,7 @@if (info->flags &ASYNC_INITIALIZED )mgsl_wait_until_sent (tty, info->timeout); -if (tty->driver->flush_buffer) - tty->driver->flush_buffer (tty); +mgsl_flush_buffer (tty);tty_ldisc_flush (tty);
@@ -3224,7 +3224,8 @@* interval should also be less than the timeout. * Note: use tight timings here to satisfy the NIST-PCTS. */ - + +lock_kernel ();if ( info->params.data_rate ) { char_time = info->timeout/(32 *5 );if (!char_time)
@@ -3254,6 +3255,7 @@break ; } } +unlock_kernel (); exit:if (debug_level >=DEBUG_LEVEL_INFO )
drivers/char/synclink_gt.c +4 -2
@@ -772,8 +772,7 @@if (info->flags &ASYNC_INITIALIZED )wait_until_sent (tty, info->timeout); -if (tty->driver->flush_buffer) - tty->driver->flush_buffer (tty); +flush_buffer (tty);tty_ldisc_flush (tty);shutdown (info);
@@ -968,6 +971,8 @@* Note: use tight timings here to satisfy the NIST-PCTS. */ +lock_kernel (); +if (info->params.data_rate) { char_time = info->timeout/(32 *5 );if (!char_time)
@@ -985,6 +990,7 @@if (timeout &&time_after (jiffies, orig_jiffies + timeout))break ; } +unlock_kernel (); exit:DBGINFO (("%s wait_until_sent exit\n" , info->device_name));
drivers/char/synclinkmp.c +6 -2
@@ -862,8 +862,7 @@if (info->flags &ASYNC_INITIALIZED )wait_until_sent (tty, info->timeout); -if (tty->driver->flush_buffer) - tty->driver->flush_buffer (tty); +flush_buffer (tty);tty_ldisc_flush (tty);
@@ -1119,6 +1121,8 @@if (sanity_check (info, tty->name,"wait_until_sent" ))return ; +lock_kernel (); +if (!(info->flags &ASYNC_INITIALIZED )) goto exit;
@@ -1161,6 +1165,7 @@ } exit: +unlock_kernel ();if (debug_level >=DEBUG_LEVEL_INFO )printk ("%s(%d):%s wait_until_sent() exit\n" , __FILE__,__LINE__, info->device_name );
@@ -1176,6 +1181,7 @@if (sanity_check (info, tty->name,"write_room" ))return 0 ; +lock_kernel ();if (info->params.mode ==MGSL_MODE_HDLC ) { ret = (info->tx_active) ?0 :HDLC_MAX_FRAME_SIZE ; }else {
@@ -1183,6 +1189,7 @@if (ret <0 ) ret =0 ; } +unlock_kernel ();if (debug_level >=DEBUG_LEVEL_INFO ) printk("%s(%d):%s write_room()=%d\n",
drivers/char/tty_io.c +1 -1
@@ -1204,7 +1204,7 @@* not in the foreground, send a SIGTTOU. If the signal is blocked or * ignored, go ahead and perform the operation. (POSIX 7.2) * -* Locking: ctrl_lock - FIXME: review this +* Locking: ctrl_lock */ int tty_check_change (struct tty_struct *tty)
drivers/char/tty_ioctl.c +12 -2
@@ -396,7 +420,7 @@static void change_termios (struct tty_struct *tty,struct ktermios *new_termios) {int canon_change; -struct ktermios old_termios = *tty->termios; +struct ktermios old_termios;struct tty_ldisc *ld;unsigned long flags;
@@ -408,7 +432,7 @@/* FIXME: we need to decide on some locking/ordering semantics for the set_termios notification eventually */ mutex_lock (&tty->termios_mutex); - + old_termios = *tty->termios; *tty->termios = *new_termios;unset_locked_termios (tty->termios, &old_termios, tty->termios_locked); canon_change = (old_termios.c_lflag ^ tty->termios->c_lflag) &ICANON ;
@@ -480,7 +504,9 @@if (retval)return retval; +mutex_lock (&tty->termios_mutex);memcpy (&tmp_termios, tty->termios,sizeof (struct ktermios )); +mutex_unlock (&tty->termios_mutex);if (opt &TERMIOS_TERMIO ) { if (user_termio_to_kernel_termios(&tmp_termios,
@@ -666,12 +692,14 @@ {struct tchars tmp; +mutex_lock (&tty->termios_mutex); tmp.t_intrc = tty->termios->c_cc[VINTR ]; tmp.t_quitc = tty->termios->c_cc[VQUIT ]; tmp.t_startc = tty->termios->c_cc[VSTART ]; tmp.t_stopc = tty->termios->c_cc[VSTOP ]; tmp.t_eofc = tty->termios->c_cc[VEOF ]; tmp.t_brkc = tty->termios->c_cc[VEOL2 ];/* what is brkc anyway? */ +mutex_unlock (&tty->termios_mutex);return copy_to_user (tchars, &tmp,sizeof (tmp)) ? -EFAULT :0 ; }
@@ -681,12 +709,14 @@if (copy_from_user (&tmp, tchars,sizeof (tmp)))return -EFAULT ; +mutex_lock (&tty->termios_mutex); tty->termios->c_cc[VINTR ] = tmp.t_intrc; tty->termios->c_cc[VQUIT ] = tmp.t_quitc; tty->termios->c_cc[VSTART ] = tmp.t_startc; tty->termios->c_cc[VSTOP ] = tmp.t_stopc; tty->termios->c_cc[VEOF ] = tmp.t_eofc; tty->termios->c_cc[VEOL2 ] = tmp.t_brkc;/* what is brkc anyway? */ +mutex_unlock (&tty->termios_mutex); return 0; }#endif
@@ -696,6 +726,7 @@ {struct ltchars tmp; +mutex_lock (&tty->termios_mutex); tmp.t_suspc = tty->termios->c_cc[VSUSP ];/* what is dsuspc anyway? */ tmp.t_dsuspc = tty->termios->c_cc[VSUSP ];
@@ -704,6 +735,7 @@ tmp.t_flushc = tty->termios->c_cc[VEOL2 ]; tmp.t_werasc = tty->termios->c_cc[VWERASE ]; tmp.t_lnextc = tty->termios->c_cc[VLNEXT ]; +mutex_unlock (&tty->termios_mutex);return copy_to_user (ltchars, &tmp,sizeof (tmp)) ? -EFAULT :0 ; }
@@ -714,6 +746,7 @@if (copy_from_user (&tmp, ltchars,sizeof (tmp)))return -EFAULT ; +mutex_lock (&tty->termios_mutex); tty->termios->c_cc[VSUSP ] = tmp.t_suspc;/* what is dsuspc anyway? */ tty->termios->c_cc[VEOL2 ] = tmp.t_dsuspc;
@@ -722,6 +755,7 @@ tty->termios->c_cc[VEOL2 ] = tmp.t_flushc; tty->termios->c_cc[VWERASE ] = tmp.t_werasc; tty->termios->c_cc[VLNEXT ] = tmp.t_lnextc; +mutex_unlock (&tty->termios_mutex); return 0; }#endif
drivers/isdn/i4l/isdn_tty.c +1 -3
@@ -1708,9 +1708,7 @@ } dev->modempoll--;isdn_tty_shutdown (info); - -if (tty->driver->flush_buffer) - tty->driver->flush_buffer (tty); +isdn_tty_flush_buffer (tty);tty_ldisc_flush (tty); info->tty =NULL ; info->ncarrier =0 ;
drivers/serial/68328serial.c +1 -17
@@ -1017,18 +1018,6 @@tty_wait_until_sent (tty,0 );send_break (info, arg ? arg*(100 ) :250 );return 0 ; -case TIOCGSOFTCAR : - error =put_user (C_CLOCAL (tty) ?1 :0 , - (unsigned long *) arg); -if (error) -return error; -return 0 ; -case TIOCSSOFTCAR : -get_user (arg, (unsigned long *) arg); - tty->termios->c_cflag = - ((tty->termios->c_cflag & ~CLOCAL ) | - (arg ?CLOCAL :0 )); -return 0 ;case TIOCGSERIAL :if (access_ok (VERIFY_WRITE , (void *) arg,sizeof (struct serial_struct )))
@@ -1061,9 +1050,6 @@ {struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; -if (tty->termios->c_cflag == old_termios->c_cflag) -return ; -change_speed (info); if ((old_termios->c_cflag & CRTSCTS) &&
@@ -1140,8 +1126,7 @@ uart->ustcnt &= ~(USTCNT_RXEN |USTCNT_RX_INTR_MASK );shutdown (info); -if (tty->driver->flush_buffer) - tty->driver->flush_buffer (tty); +rs_flush_buffer (tty);tty_ldisc_flush (tty); tty->closing =0 ;
drivers/serial/68360serial.c +3 -14
@@ -1435,18 +1436,6 @@return retval;end_break (info);return 0 ; -case TIOCGSOFTCAR : -/* return put_user(C_CLOCAL(tty) ? 1 : 0, (int *) arg); */ -put_user (C_CLOCAL (tty) ?1 :0 , (int *) arg); -return 0 ; -case TIOCSSOFTCAR : - error =get_user (arg, (unsigned int *) arg); -if (error) -return error; - tty->termios->c_cflag = - ((tty->termios->c_cflag & ~CLOCAL ) | - (arg ?CLOCAL :0 )); -return 0 ;#ifdef maybecase TIOCSERGETLSR :/* Get line status register */ return get_lsr_info (info, (unsigned int *) arg);
@@ -1664,8 +1653,7 @@rs_360_wait_until_sent (tty, info->timeout); }shutdown (info); -if (tty->driver->flush_buffer) - tty->driver->flush_buffer (tty); +rs_360_flush_buffer (tty);tty_ldisc_flush (tty); tty->closing =0 ; info->event =0 ;
@@ -1716,6 +1704,7 @@printk ("jiff=%lu..." , jiffies);#endif +lock_kernel ();/* We go through the loop at least once because we can't tell * exactly when the last character exits the shifter. There can * be at least two characters waiting to be sent after the buffers
@@ -1744,6 +1733,7 @@ bdp--; }while (bdp->status &BD_SC_READY ); current->state =TASK_RUNNING ; +unlock_kernel ();#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT printk ("lsr = %d (jiff=%lu)...done\n" , lsr, jiffies);#endif
drivers/serial/crisv10.c +12 -13
@@ -3581,9 +3581,10 @@ unsigned int set, unsigned int clear) {struct e100_serial *info = (struct e100_serial *)tty->driver_data; +unsigned long flags; -lock_kernel (); - +local_irq_save (flags); +if (clear &TIOCM_RTS )e100_rts (info,0 );if (clear &TIOCM_DTR )
@@ -3604,7 +3605,7 @@if (set &TIOCM_CD )e100_cd_out (info,1 ); -unlock_kernel (); +local_irq_restore (flags);return 0 ; }
@@ -3613,8 +3614,10 @@ {struct e100_serial *info = (struct e100_serial *)tty->driver_data;unsigned int result; +unsigned long flags; + +local_irq_save (flags); -lock_kernel (); result = (!E100_RTS_GET (info) ?TIOCM_RTS :0 ) | (!E100_DTR_GET (info) ?TIOCM_DTR :0 )
@@ -3623,7 +3626,7 @@ | (!E100_CD_GET(info) ? TIOCM_CAR : 0) | (!E100_CTS_GET (info) ?TIOCM_CTS :0 ); -unlock_kernel (); +local_irq_restore (flags);#ifdef SERIAL_DEBUG_IO printk(KERN_DEBUG "ser%i: modem state: %i 0x%08X\n",
@@ -3702,10 +3705,6 @@ {struct e100_serial *info = (struct e100_serial *)tty->driver_data; -if (tty->termios->c_cflag == old_termios->c_cflag && - tty->termios->c_iflag == old_termios->c_iflag) -return ; -change_speed (info);/* Handle turning off CRTSCTS */
@@ -3808,10 +3807,8 @@#endif shutdown (info); -if (tty->driver->flush_buffer) - tty->driver->flush_buffer (tty); -if (tty->ldisc.flush_buffer) - tty->ldisc.flush_buffer (tty); +rs_flush_buffer (tty); +tty_ldisc_flush_buffer (tty); tty->closing =0 ; info->event =0 ; info->tty =0 ;
@@ -3885,6 +3882,7 @@* Check R_DMA_CHx_STATUS bit 0-6=number of available bytes in FIFO * R_DMA_CHx_HWSW bit 31-16=nbr of bytes left in DMA buffer (0=64k) */ +lock_kernel (); orig_jiffies = jiffies; while (info->xmit.head != info->xmit.tail || /* More in send queue */ (*info->ostatusadr & 0x007f) || /* more in FIFO */
@@ -3901,6 +3899,7 @@ curr_time_usec - info->last_tx_active_usec; }set_current_state (TASK_RUNNING ); +unlock_kernel (); }/*
drivers/serial/mcfserial.c +4 -14
@@ -1073,18 +1073,6 @@tty_wait_until_sent (tty,0 );send_break (info, arg ? arg*(HZ /10 ) :HZ /4 );return 0 ; -case TIOCGSOFTCAR : - error =put_user (C_CLOCAL (tty) ?1 :0 , - (unsigned long *) arg); -if (error) -return error; -return 0 ; -case TIOCSSOFTCAR : -get_user (arg, (unsigned long *) arg); - tty->termios->c_cflag = - ((tty->termios->c_cflag & ~CLOCAL ) | - (arg ?CLOCAL :0 )); -return 0 ;case TIOCGSERIAL :if (access_ok (VERIFY_WRITE , (void *) arg,sizeof (struct serial_struct )))
@@ -1223,8 +1211,7 @@ } else#endif shutdown (info); -if (tty->driver->flush_buffer) - tty->driver->flush_buffer (tty); +mcfrs_flush_buffer (tty);tty_ldisc_flush (tty); tty->closing =0 ;
@@ -1277,6 +1264,8 @@* Note: we have to use pretty tight timings here to satisfy * the NIST-PCTS. */ +lock_kernel (); + fifo_time = (MCF5272_FIFO_SIZE *HZ *10 ) / info->baud; char_time = fifo_time /5 ;if (char_time ==0 )
@@ -1313,6 +1302,7 @@if (timeout &&time_after (jiffies, orig_jiffies + timeout)) break; } +unlock_kernel ();#else /* * For the other coldfire models, assume all data has been sent
drivers/serial/netx-serial.c +1 -0
@@ -287,6 +287,7 @@ {unsigned int val; +/* FIXME: Locking needed ? */ if (mctrl &TIOCM_RTS ) { val =readl (port->membase +UART_RTS_CR );writel (val |RTS_CR_RTS , port->membase +UART_RTS_CR );
Quoted 33 lines · Alan Cox
- Remove private
put_charmethod that does a write call for one char - we have that anywaydiff -u --new-file --recursive --exclude-from
/usr/src/excludelinux.vanilla-2.6.25-rc8-mm1/drivers/char/nozomi.clinux-2.6.25-rc8-mm1/drivers/char/nozomi.cdrivers/char/nozomi.c +2
-10@@ -1724,6 +1724,8 @@const struct ctrl_dl *ctrl_dl = &port->ctrl_dl;const struct ctrl_ul *ctrl_ul = &port->ctrl_ul; +/* Note: these could change under us but it is not clear this +matters if so */ return (ctrl_ul->RTS ?TIOCM_RTS :0 ) | (ctrl_ul->DTR ?TIOCM_DTR :0 ) | (ctrl_dl->DCD ? TIOCM_CAR : 0) |@@ -1849,16 +1851,6 @@spin_unlock_irqrestore (&dc->spin_mutex, flags); } -/* just to discard single character writes */ -static void ntty_put_char (struct tty_struct *tty,unsigned char c) -{ -/* -* card does not react correct when we write single chars -* to the card, so we discard them -*/ -DBG2 ("PUT CHAR Function: %c" , c); -} -/* Returns number of chars in buffer, called by tty layer */ static s32 ntty_chars_in_buffer (struct tty_struct *tty) {
drivers/char/nozomi.c line 1889
Quoted 7 lines
drivers/char/nozomi.c +0
-1@@ -1892,7 +1884,6 @@ .unthrottle = ntty_unthrottle, .throttle = ntty_throttle, .chars_in_buffer = ntty_chars_in_buffer, - .put_char = ntty_put_char, .tiocmget = ntty_tiocmget, .tiocmset = ntty_tiocmset, };
Well, how exactly the card behaves on 1 byte write? And how did the .write protect against it?
Quoted 2 lines
Well, how exactly the card behaves on 1 byte write? And how did the .write protect against it?
One byte writes work fine via the write path and already occur. I suspect the original author forgot to turn echo off and saw fun things happening between the inbuilt modem emulation and the Linux side.
Quoted 3 lines · Alan Cox
Quoted 1 line
Well, how exactly the card behaves on 1 byte write? And how did the .write protect against it?
One byte writes work fine via the write path and already occur.
I guessed so, because there is no protection against one byte writes in .write.
Quoted 3 lines
I suspect
the original author forgot to turn echo off and saw fun things happening between the inbuilt modem emulation and the Linux side.
He was Cced, I hope he'll make things clear :).