tty: The big operations rework
Subsystems (9)
PATCH 1/1 tty: The big operations rework
- Operations are now a shared const function block as with most other Linux objects
- Introduce wrappers for some optional functions to get consistent behaviour
- Wrap put_char which used to be patched by the tty layer
- Document which functions are needed/optional
- Make put_char report success/fail
- Cache the driver->ops pointer in the tty as tty->ops
- Remove various surplus lock calls we no longer need
- Remove proc_write method as noted by Alexey Dobriyan
- Introduce some missing sanity checks where certain driver/ldisc combinations would oops as they didn't check needed methods were present
drivers/bluetooth/hci_ldisc.c +5 -8
@@ -143,7 +143,7 @@int len;set_bit (TTY_DO_WRITE_WAKEUP , &tty->flags); - len = tty->driver->write (tty, skb->data, skb->len); + len = tty->ops->write (tty, skb->data, skb->len); hdev->stat.byte_tx += len;skb_pull (skb, len);
@@ -190,8 +190,7 @@/* Flush any pending characters in the driver and discipline. */ tty_ldisc_flush (tty); -if (tty->driver && tty->driver->flush_buffer) - tty->driver->flush_buffer (tty); +tty_driver_flush_buffer (tty);if (test_bit (HCI_UART_PROTO_SET , &hu->flags)) hu->proto->flush (hu);
@@ -285,9 +284,7 @@if (tty->ldisc.flush_buffer) tty->ldisc.flush_buffer (tty); - -if (tty->driver && tty->driver->flush_buffer) - tty->driver->flush_buffer (tty); +tty_driver_flush_buffer (tty);return 0 ; }
@@ -374,8 +371,8 @@spin_unlock (&hu->rx_lock);if (test_and_clear_bit (TTY_THROTTLED , &tty->flags) && - tty->driver->unthrottle) - tty->driver->unthrottle (tty); + tty->ops->unthrottle) + tty->ops->unthrottle (tty); }static int hci_uart_register_dev (struct hci_uart *hu)
drivers/char/ip2/ip2main.c +9 -9
@@ -169,7 +169,7 @@static int ip2_open (PTTY ,struct file *);static void ip2_close (PTTY ,struct file *);static int ip2_write (PTTY ,const unsigned char *,int ); -static void ip2_putchar (PTTY ,unsigned char ); +static int ip2_putchar (PTTY ,unsigned char );static void ip2_flush_chars (PTTY );static int ip2_write_room (PTTY );static int ip2_chars_in_buf (PTTY );
@@ -1616,10 +1616,9 @@serviceOutgoingFifo ( pCh->pMyBord ); -if ( tty->driver->flush_buffer ) - tty->driver->flush_buffer (tty); -if ( tty->ldisc.flush_buffer ) - tty->ldisc.flush_buffer (tty); +if ( tty->driver->ops->flush_buffer ) + tty->driver->ops->flush_buffer (tty); +tty_ldisc_flush (tty); tty->closing =0 ; pCh->pTTY =NULL ;
@@ -1738,7 +1737,7 @@/* */ /* */ /******************************************************************************/ -static void +static int ip2_putchar (PTTY tty,unsigned char ch ) {i2ChanStrPtr pCh = tty->driver_data;
@@ -1746,13 +1745,14 @@// ip2trace (CHANN, ITRC_PUTC, ITRC_ENTER, 1, ch ); -write_lock_irqsave (&pCh->Pbuf_spinlock, flags); +write_lock_irqsave (&pCh->Pbuf_spinlock, flags); pCh->Pbuf[pCh->Pbuf_stuff++] = ch;if ( pCh->Pbuf_stuff ==sizeof pCh->Pbuf ) { -write_unlock_irqrestore (&pCh->Pbuf_spinlock, flags); +write_unlock_irqrestore (&pCh->Pbuf_spinlock, flags);ip2_flush_chars ( tty ); }else -write_unlock_irqrestore (&pCh->Pbuf_spinlock, flags); +write_unlock_irqrestore (&pCh->Pbuf_spinlock, flags); +return 1 ;// ip2trace (CHANN, ITRC_PUTC, ITRC_RETURN, 1, ch ); }
drivers/char/keyboard.c +1 -1
@@ -1230,7 +1230,7 @@if (rep && (!vc_kbd_mode (kbd,VC_REPEAT ) || - (tty && !L_ECHO (tty) && tty->driver->chars_in_buffer (tty)))) { + (tty && !L_ECHO (tty) &&tty_chars_in_buffer (tty)))) {/* * Don't repeat a key if the input buffers are not empty and the * characters get aren't echoed locally. This makes key repeat
drivers/char/n_hdlc.c +4 -7
@@ -342,12 +342,10 @@#endif /* Flush any pending characters in the driver and discipline. */ -if (tty->ldisc.flush_buffer) - tty->ldisc.flush_buffer (tty); + tty->ldisc.flush_buffer (tty); -if (tty->driver->flush_buffer) - tty->driver->flush_buffer (tty); +tty_driver_flush_buffer (tty);if (debuglevel >=DEBUG_LEVEL_INFO )printk ("%s(%d)n_hdlc_tty_open() success\n" ,__FILE__,__LINE__);
@@ -399,7 +397,7 @@/* Send the next block of data to device */ tty->flags |= (1 <<TTY_DO_WRITE_WAKEUP ); - actual = tty->driver->write (tty, tbuf->buf, tbuf->count); + actual = tty->ops->write (tty, tbuf->buf, tbuf->count);/* rollback was possible and has been done */ if (actual == -ERESTARTSYS ) {
@@ -752,8 +750,7 @@case TIOCOUTQ :/* get the pending tx byte count in the driver */ - count = tty->driver->chars_in_buffer ? - tty->driver->chars_in_buffer (tty) :0 ; + count =tty_chars_in_buffer (tty);/* add size of next output frame in queue */ spin_lock_irqsave (&n_hdlc->tx_buf_list.spinlock,flags);if (n_hdlc->tx_buf_list.head)
drivers/char/n_r3964.c +7 -10
@@ -376,8 +376,9 @@if (tty ==NULL )return ; -if (tty->driver->put_char) { - tty->driver->put_char (tty, ch); +/* FIXME: put_char should not be called from an IRQ */ +if (tty->ops->put_char) { + tty->ops->put_char (tty, ch); } pInfo->bcc ^= ch; }
@@ -386,12 +387,9 @@ {struct tty_struct *tty = pInfo->tty; -if (tty ==NULL ) +if (tty ==NULL || tty->ops->flush_chars ==NULL )return ; - -if (tty->driver->flush_chars) { - tty->driver->flush_chars (tty); - } + tty->ops->flush_chars (tty); }static void trigger_transmit (struct r3964_info *pInfo)
@@ -449,12 +447,11 @@struct r3964_block_header *pBlock = pInfo->tx_first;int room =0 ; -if ((tty ==NULL ) || (pBlock ==NULL )) { +if (tty ==NULL || pBlock ==NULL ) {return ; } -if (tty->driver->write_room) - room = tty->driver->write_room (tty); + room =tty_write_room (tty);TRACE_PS ("transmit_block %p, room %d, length %d" , pBlock, room, pBlock->length);
drivers/char/n_tty.c +43 -60
270 lines not on this page · raw message
drivers/char/tty_io.c +70 -99
355 lines not on this page · raw message
drivers/char/tty_ioctl.c +43 -21
126 lines not on this page · raw message
drivers/input/serio/serport.c +1 -1
@@ -46,7 +46,7 @@static int serport_serio_write (struct serio *serio,unsigned char data) {struct serport *serport = serio->port_data; -return -(serport->tty->driver->write (serport->tty, &data,1 ) !=1 ); +return -(serport->tty->ops->write (serport->tty, &data,1 ) !=1 ); }static int serport_serio_open (struct serio *serio)
drivers/isdn/gigaset/ser-gigaset.c +8 -7
@@ -68,10 +68,10 @@struct tty_struct *tty = cs->hw.ser->tty;struct bc_state *bcs = &cs->bcs[0 ];/* only one channel */ struct sk_buff *skb = bcs->tx_skb; -int sent; +int sent = -EOPNOTSUPP ;if (!tty || !tty->driver || !skb) -return -EFAULT ; +return -EINVAL ;if (!skb->len) {dev_kfree_skb_any (skb);
@@ -80,7 +80,8 @@ }set_bit (TTY_DO_WRITE_WAKEUP , &tty->flags); - sent = tty->driver->write (tty, skb->data, skb->len); +if (tty->ops->write) + sent = tty->ops->write (tty, skb->data, skb->len);gig_dbg (DEBUG_OUTPUT ,"write_modem: sent %d" , sent);if (sent <0 ) {/* error */
@@ -120,7 +121,7 @@if (cb->len) {set_bit (TTY_DO_WRITE_WAKEUP , &tty->flags); - sent = tty->driver->write (tty, cb->buf + cb->offset, cb->len); + sent = tty->ops->write (tty, cb->buf + cb->offset, cb->len);if (sent <0 ) {/* error */ gig_dbg (DEBUG_OUTPUT ,"send_cb: write error %d" , sent);
@@ -440,14 +441,14 @@struct tty_struct *tty = cs->hw.ser->tty;unsigned int set, clear; -if (!tty || !tty->driver || !tty->driver->tiocmset) -return -EFAULT ; +if (!tty || !tty->driver || !tty->ops->tiocmset) +return -EINVAL ; set = new_state & ~old_state; clear = old_state & ~new_state;if (!set && !clear)return 0 ;gig_dbg (DEBUG_IF ,"tiocmset set %x clear %x" , set, clear); -return tty->driver->tiocmset (tty,NULL , set, clear); +return tty->ops->tiocmset (tty,NULL , set, clear); }static int gigaset_baud_rate (struct cardstate *cs,unsigned cflag)
drivers/net/hamradio/6pack.c +19 -17
@@ -148,13 +148,13 @@if (((sp->status1 &SIXP_DCD_MASK ) ==0 ) && (random < sp->persistence)) { sp->led_state =0x70 ; - sp->tty->driver->write (sp->tty, &sp->led_state,1 ); + sp->tty->ops->write (sp->tty, &sp->led_state,1 ); sp->tx_enable =1 ; - actual = sp->tty->driver->write (sp->tty, sp->xbuff, sp->status2); + actual = sp->tty->ops->write (sp->tty, sp->xbuff, sp->status2); sp->xleft -= actual; sp->xhead += actual; sp->led_state =0x60 ; - sp->tty->driver->write (sp->tty, &sp->led_state,1 ); + sp->tty->ops->write (sp->tty, &sp->led_state,1 ); sp->status2 =0 ; }else mod_timer (&sp->tx_t, jiffies + ((when +1 ) *HZ ) /100 );
@@ -220,13 +220,13 @@*/ if (sp->duplex ==1 ) { sp->led_state =0x70 ; - sp->tty->driver->write (sp->tty, &sp->led_state,1 ); + sp->tty->ops->write (sp->tty, &sp->led_state,1 ); sp->tx_enable =1 ; - actual = sp->tty->driver->write (sp->tty, sp->xbuff, count); + actual = sp->tty->ops->write (sp->tty, sp->xbuff, count); sp->xleft = count - actual; sp->xhead = sp->xbuff + actual; sp->led_state =0x60 ; - sp->tty->driver->write (sp->tty, &sp->led_state,1 ); + sp->tty->ops->write (sp->tty, &sp->led_state,1 ); }else { sp->xleft = count; sp->xhead = sp->xbuff;
@@ -444,7 +444,7 @@ }if (sp->tx_enable) { - actual = tty->driver->write (tty, sp->xhead, sp->xleft); + actual = tty->ops->write (tty, sp->xhead, sp->xleft); sp->xleft -= actual; sp->xhead += actual; }
@@ -492,8 +492,8 @@sp_put (sp);if (test_and_clear_bit (TTY_THROTTLED , &tty->flags) - && tty->driver->unthrottle) - tty->driver->unthrottle (tty); + && tty->ops->unthrottle) + tty->ops->unthrottle (tty); }/*
@@ -554,8 +554,8 @@/* resync the TNC */ sp->led_state =0x60 ; - sp->tty->driver->write (sp->tty, &sp->led_state,1 ); - sp->tty->driver->write (sp->tty, &resync_cmd,1 ); + sp->tty->ops->write (sp->tty, &sp->led_state,1 ); + sp->tty->ops->write (sp->tty, &resync_cmd,1 );/* Start resync timer again -- the TNC might be still absent */
@@ -573,7 +573,7 @@tnc_set_sync_state (sp,TNC_UNSYNC_STARTUP ); - sp->tty->driver->write (sp->tty, &inbyte,1 ); + sp->tty->ops->write (sp->tty, &inbyte,1 );del_timer (&sp->resync_t); sp->resync_t.data = (unsigned long ) sp;
@@ -601,6 +601,8 @@if (!capable (CAP_NET_ADMIN ))return -EPERM ; +if (tty->ops->write ==NULL ) +return -EOPNOTSUPP ; dev =alloc_netdev (sizeof (struct sixpack ),"sp%d" , sp_setup);if (!dev) {
@@ -914,9 +916,9 @@ }else {/* output watchdog char if idle */ if ((sp->status2 !=0 ) && (sp->duplex ==1 )) { sp->led_state =0x70 ; - sp->tty->driver->write (sp->tty, &sp->led_state,1 ); + sp->tty->ops->write (sp->tty, &sp->led_state,1 ); sp->tx_enable =1 ; - actual = sp->tty->driver->write (sp->tty, sp->xbuff, sp->status2); + actual = sp->tty->ops->write (sp->tty, sp->xbuff, sp->status2); sp->xleft -= actual; sp->xhead += actual; sp->led_state =0x60 ;
@@ -926,7 +928,7 @@ }/* needed to trigger the TNC watchdog */ - sp->tty->driver->write (sp->tty, &sp->led_state,1 ); + sp->tty->ops->write (sp->tty, &sp->led_state,1 );/* if the state byte has been received, the TNC is present, so the resync timer can be reset. */
@@ -956,12 +958,12 @@if ((sp->status &SIXP_RX_DCD_MASK ) ==SIXP_RX_DCD_MASK ) { sp->led_state =0x68 ; - sp->tty->driver->write (sp->tty, &sp->led_state,1 ); + sp->tty->ops->write (sp->tty, &sp->led_state,1 ); } }else { sp->led_state =0x60 ;/* fill trailing bytes with zeroes */ - sp->tty->driver->write (sp->tty, &sp->led_state,1 ); + sp->tty->ops->write (sp->tty, &sp->led_state,1 ); rest = sp->rx_count;if (rest !=0 )for (i = rest; i <=3 ; i++)
drivers/net/hamradio/mkiss.c +8 -7
@@ -516,7 +516,7 @@spin_unlock_bh (&ax->buflock);set_bit (TTY_DO_WRITE_WAKEUP , &ax->tty->flags); - actual = ax->tty->driver->write (ax->tty, ax->xbuff, count); + actual = ax->tty->ops->write (ax->tty, ax->xbuff, count); ax->stats.tx_packets++; ax->stats.tx_bytes += actual;
@@ -546,7 +546,7 @@ }printk (KERN_ERR "mkiss: %s: transmit timed out, %s?\n" , dev->name, - (ax->tty->driver->chars_in_buffer (ax->tty) || ax->xleft) ? + (ax->tty->ops->chars_in_buffer (ax->tty) || ax->xleft) ?"bad line quality" :"driver error" ); ax->xleft =0 ;
@@ -736,6 +736,8 @@if (!capable (CAP_NET_ADMIN ))return -EPERM ; +if (tty->ops->write ==NULL ) +return -EOPNOTSUPP ; dev =alloc_netdev (sizeof (struct mkiss ),"ax%d" , ax_setup);if (!dev) {
@@ -754,8 +756,7 @@ tty->disc_data = ax; tty->receive_room =65535 ; -if (tty->driver->flush_buffer) - tty->driver->flush_buffer (tty); +tty_driver_flush_buffer (tty);/* Restore default settings */ dev->type =ARPHRD_AX25 ;
@@ -936,8 +937,8 @@mkiss_put (ax);if (test_and_clear_bit (TTY_THROTTLED , &tty->flags) - && tty->driver->unthrottle) - tty->driver->unthrottle (tty); + && tty->ops->unthrottle) + tty->ops->unthrottle (tty); }/*
@@ -962,7 +963,7 @@ goto out; } - actual = tty->driver->write (tty, ax->xhead, ax->xleft); + actual = tty->ops->write (tty, ax->xhead, ax->xleft); ax->xleft -= actual; ax->xhead += actual;
drivers/net/irda/irtty-sir.c +28 -69
170 lines not on this page · raw message
drivers/net/ppp_async.c +6 -3
@@ -158,6 +158,9 @@struct asyncppp *ap;int err; +if (tty->ops->write ==NULL ) +return -EOPNOTSUPP ; + err = -ENOMEM ; ap =kzalloc (sizeof (*ap),GFP_KERNEL );if (!ap)
@@ -359,8 +362,8 @@tasklet_schedule (&ap->tsk);ap_put (ap);if (test_and_clear_bit (TTY_THROTTLED , &tty->flags) - && tty->driver->unthrottle) - tty->driver->unthrottle (tty); + && tty->ops->unthrottle) + tty->ops->unthrottle (tty); } static void
@@ -676,7 +679,7 @@if (!tty_stuffed && ap->optr < ap->olim) { avail = ap->olim - ap->optr;set_bit (TTY_DO_WRITE_WAKEUP , &tty->flags); - sent = tty->driver->write (tty, ap->optr, avail); + sent = tty->ops->write (tty, ap->optr, avail);if (sent <0 ) goto flush;/* error, e.g. loss of CD */ ap->optr += sent;
drivers/net/ppp_synctty.c +6 -3
@@ -207,6 +207,9 @@struct syncppp *ap;int err; +if (tty->ops->write ==NULL ) +return -EOPNOTSUPP ; + ap =kzalloc (sizeof (*ap),GFP_KERNEL ); err = -ENOMEM ;if (!ap)
@@ -399,8 +402,8 @@tasklet_schedule (&ap->tsk);sp_put (ap);if (test_and_clear_bit (TTY_THROTTLED , &tty->flags) - && tty->driver->unthrottle) - tty->driver->unthrottle (tty); + && tty->ops->unthrottle) + tty->ops->unthrottle (tty); } static void
@@ -653,7 +656,7 @@ tty_stuffed =0 ;if (!tty_stuffed && ap->tpkt) {set_bit (TTY_DO_WRITE_WAKEUP , &tty->flags); - sent = tty->driver->write (tty, ap->tpkt->data, ap->tpkt->len); + sent = tty->ops->write (tty, ap->tpkt->data, ap->tpkt->len);if (sent <0 ) goto flush;/* error, e.g. loss of CD */ if (sent < ap->tpkt->len) {
drivers/net/slip.c +8 -5
@@ -396,14 +396,14 @@/* Order of next two lines is *very* important. * When we are sending a little amount of data, -* the transfer may be completed inside driver.write() +* the transfer may be completed inside the ops->write() * routine, because it's running with interrupts enabled. * In this case we *never* got WRITE_WAKEUP event, * if we did not request it before write operation. * 14 Oct 1994 Dmitry Gorodchanin. */ sl->tty->flags |= (1 <<TTY_DO_WRITE_WAKEUP ); - actual = sl->tty->driver->write (sl->tty, sl->xbuff, count); + actual = sl->tty->ops->write (sl->tty, sl->xbuff, count);#ifdef SL_CHECK_TRANSMIT sl->dev->trans_start = jiffies;#endif
@@ -437,7 +437,7 @@return ; } - actual = tty->driver->write (tty, sl->xhead, sl->xleft); + actual = tty->ops->write (tty, sl->xhead, sl->xleft); sl->xleft -= actual; sl->xhead += actual; }
@@ -462,7 +462,7 @@ }printk (KERN_WARNING "%s: transmit timed out, %s?\n" , dev->name, - (sl->tty->driver->chars_in_buffer (sl->tty) || sl->xleft) ? + (tty_chars_in_buffer (sl->tty) || sl->xleft) ?"bad line quality" :"driver error" ); sl->xleft =0 ; sl->tty->flags &= ~(1 <<TTY_DO_WRITE_WAKEUP );
@@ -830,6 +830,9 @@if (!capable (CAP_NET_ADMIN ))return -EPERM ; +if (tty->ops->write ==NULL ) +return -EOPNOTSUPP ; +/* RTnetlink lock is misused here to serialize concurrent opens of slip channels. There are better ways, but it is the simplest one.
@@ -1432,7 +1435,7 @@/* put END into tty queue. Is it right ??? */ if (!netif_queue_stopped (sl->dev)) {/* if device busy no outfill */ - sl->tty->driver->write (sl->tty, &s,1 ); + sl->tty->ops->write (sl->tty, &s,1 ); } }else set_bit (SLF_OUTWAIT , &sl->flags);
drivers/serial/serial_core.c +26 -12
@@ -528,15 +532,25 @@static int uart_write_room (struct tty_struct *tty) {struct uart_state *state = tty->driver_data; +unsigned long flags; +int ret; -return uart_circ_chars_free (&state->info->xmit); +spin_lock_irqsave (&state->port->lock, flags); + ret =uart_circ_chars_free (&state->info->xmit); +spin_unlock_irqrestore (&state->port->lock, flags); +return ret; }static int uart_chars_in_buffer (struct tty_struct *tty) {struct uart_state *state = tty->driver_data; +unsigned long flags; +int ret; -return uart_circ_chars_pending (&state->info->xmit); +spin_lock_irqsave (&state->port->lock, flags); + ret =uart_circ_chars_pending (&state->info->xmit); +spin_unlock_irqrestore (&state->port->lock, flags); +return ret; }static void uart_flush_buffer (struct tty_struct *tty)
@@ -618,6 +632,11 @@struct serial_struct tmp;memset (&tmp,0 ,sizeof (tmp)); + +/* Ensure the state we copy is consistent and no hardware changes +occur as we go */ +mutex_lock (&state->mutex); + tmp.type = port->type; tmp.line = port->line; tmp.port = port->iobase;
@@ -637,6 +656,8 @@ tmp.iomem_reg_shift = port->regshift; tmp.iomem_base = (void *)(unsigned long )port->mapbase; +mutex_unlock (&state->mutex); +if (copy_to_user (retinfo, &tmp,sizeof (*retinfo)))return -EFAULT ;return 0 ;
@@ -914,14 +935,12 @@struct uart_state *state = tty->driver_data;struct uart_port *port = state->port; -lock_kernel ();mutex_lock (&state->mutex);if (port->type !=PORT_UNKNOWN ) port->ops->break_ctl (port, break_state);mutex_unlock (&state->mutex); -unlock_kernel (); }static int uart_do_autoconfig (struct uart_state *state)
@@ -1070,7 +1089,6 @@int ret = -ENOIOCTLCMD ; -lock_kernel ();/* * These ioctls don't rely on the hardware to be present. */
@@ -1140,10 +1158,9 @@break ; } } - out_up: +out_up:mutex_unlock (&state->mutex); - out: -unlock_kernel (); +out:return ret; }
@@ -1169,7 +1186,6 @@return ; } -lock_kernel ();uart_change_speed (state, old_termios);/* Handle transition to B0 status */
@@ -1202,7 +1218,6 @@ }spin_unlock_irqrestore (&state->port->lock, flags); } -unlock_kernel ();#if 0 /* * No need to wake up processes in open wait, since they
@@ -1318,11 +1333,11 @@struct uart_port *port = state->port;unsigned long char_time, expire; -BUG_ON (!kernel_locked ()); -if (port->type ==PORT_UNKNOWN || port->fifosize ==0 )return ; +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
@@ -1368,6 +1383,7 @@break ; }set_current_state (TASK_RUNNING );/* might not be needed */ +unlock_kernel (); }/*
@@ -2081,7 +2097,9 @@int ret;uart_change_pm (state,0 ); +spin_lock_irq (&port->lock); ops->set_mctrl (port,0 ); +spin_unlock_irq (&port->lock); ret = ops->startup (port);if (ret ==0 ) {uart_change_speed (state,NULL );
drivers/usb/serial/digi_acceleport.c +1 -2
@@ -1427,8 +1427,7 @@tty_wait_until_sent (tty,DIGI_CLOSE_TIMEOUT );/* flush driver and line discipline buffers */ -if (tty->driver->flush_buffer) - tty->driver->flush_buffer (tty); +tty_driver_flush_buffer (tty);tty_ldisc_flush (tty);if (port->serial->dev) {
drivers/usb/serial/usb-serial.c +23 -106
221 lines not on this page · raw message
drivers/usb/serial/whiteheat.c +1 -3
@@ -679,15 +679,13 @@} */ -if (port->tty->driver->flush_buffer) - port->tty->driver->flush_buffer (port->tty); +tty_driver_flush_buffer (port->tty);tty_ldisc_flush (port->tty);firm_report_tx_done (port);firm_close (port); -printk (KERN_ERR "Before processing rx_urbs_submitted.\n" );/* shutdown our bulk reads and writes */ mutex_lock (&info->deathwarrant);spin_lock_irq (&info->lock);
fs/proc/proc_tty.c +2 -4
@@ -177,16 +177,14 @@ {struct proc_dir_entry *ent; -if ((!driver->read_proc && !driver->write_proc) || - !driver->driver_name || +if (!driver->ops->read_proc || !driver->driver_name || driver->proc_entry)return ; ent =create_proc_entry (driver->driver_name,0 , proc_tty_driver);if (!ent)return ; - ent->read_proc = driver->read_proc; - ent->write_proc = driver->write_proc; + ent->read_proc = driver->ops->read_proc; ent->owner = driver->owner; ent->data = driver;
include/linux/tty_driver.h +50 -7
153 lines not on this page · raw message
int (*chars_in_buffer)(struct tty_struct *tty);
@@ -153,8 +197,6 @@
void (*send_xchar)(struct tty_struct *tty, char ch); int (*read_proc)(char *page, char **start, off_t off,
int count, int *eof, void *data);
- int (*write_proc)(struct file *file, const char __user *buffer,
- unsigned long count, void *data);
int (*tiocmget)(struct tty_struct *tty, struct file *file); int (*tiocmset)(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear);
@@ -190,48 +234,13 @@
struct tty_struct **ttys;
struct ktermios **termios;
struct ktermios **termios_locked;
- void *driver_state; /* only used for the PTY driver */
-
+ void *driver_state;
+
/*
- * Interface routines from the upper tty layer to the tty
- * driver. Will be replaced with struct tty_operations.
+ * Driver methods
*/
- int (*open)(struct tty_struct * tty, struct file * filp);
- void (*close)(struct tty_struct * tty, struct file * filp);
- int (*write)(struct tty_struct * tty,
- const unsigned char *buf, int count);
- void (*put_char)(struct tty_struct *tty, unsigned char ch);
- void (*flush_chars)(struct tty_struct *tty);
- int (*write_room)(struct tty_struct *tty); - int (*chars_in_buffer)(struct tty_struct *tty); - int (*ioctl)(struct tty_struct *tty, struct file * file, - unsigned int cmd, unsigned long arg);
- long (*compat_ioctl)(struct tty_struct *tty, struct file * file,
- unsigned int cmd, unsigned long arg);
- void (*set_termios)(struct tty_struct *tty, struct ktermios * old);
- void (*throttle)(struct tty_struct * tty);
- void (*unthrottle)(struct tty_struct * tty);
- void (*stop)(struct tty_struct *tty);
- void (*start)(struct tty_struct *tty);
- void (*hangup)(struct tty_struct *tty);
- void (*break_ctl)(struct tty_struct *tty, int state);
- void (*flush_buffer)(struct tty_struct *tty);
- void (*set_ldisc)(struct tty_struct *tty);
- void (*wait_until_sent)(struct tty_struct *tty, int timeout);
- void (*send_xchar)(struct tty_struct *tty, char ch);
- int (*read_proc)(char *page, char **start, off_t off,
- int count, int *eof, void *data);
- int (*write_proc)(struct file *file, const char __user *buffer,
- unsigned long count, void *data);
- int (*tiocmget)(struct tty_struct *tty, struct file *file);
- int (*tiocmset)(struct tty_struct *tty, struct file *file,
- unsigned int set, unsigned int clear);
-#ifdef CONFIG_CONSOLE_POLL
- int (*poll_init)(struct tty_driver *driver, int line, char *options);
- int (*poll_get_char)(struct tty_driver *driver, int line);
- void (*poll_put_char)(struct tty_driver *driver, int line, char ch);
-#endif
+ const struct tty_operations *ops;
struct list_head tty_drivers;
};
include/linux/tty.h +8 -0
@@ -177,9 +194,13 @@* size each time the window is created or resized anyway. * - TYT, 9/14/92 */ + +struct tty_operations ; +struct tty_struct {int magic;struct tty_driver *driver; +const struct tty_operations *ops;int index;struct tty_ldisc ldisc;struct mutex termios_mutex;
@@ -295,6 +317,10 @@extern int tty_read_raw_data (struct tty_struct *tty,unsigned char *bufp,int buflen);extern void tty_write_message (struct tty_struct *tty,char *msg); +extern int tty_put_char (struct tty_struct *tty,unsigned char c); +extern int tty_chars_in_buffer (struct tty_struct *tty); +extern int tty_write_room (struct tty_struct *tty); +extern void tty_driver_flush_buffer (struct tty_struct *tty);extern int is_current_pgrp_orphaned (void );extern struct pid *tty_get_pgrp (struct tty_struct *tty);
kernel/printk.c +2 -2
@@ -1304,8 +1304,8 @@*/ void tty_write_message (struct tty_struct *tty,char *msg) { -if (tty && tty->driver->write) - tty->driver->write (tty, msg,strlen (msg)); +if (tty && tty->ops->write) + tty->ops->write (tty, msg,strlen (msg));return ; }
net/irda/ircomm/ircomm_tty.c +2 -4
@@ -555,10 +555,8 @@ircomm_tty_shutdown (self); -if (tty->driver->flush_buffer) - tty->driver->flush_buffer (tty); -if (tty->ldisc.flush_buffer) - tty->ldisc.flush_buffer (tty); +tty_driver_flush_buffer (tty); +tty_ldisc_flush (tty); tty->closing =0 ; self->tty =NULL ;
Quoted 13 lines · Alan Cox
- Operations are now a shared const function block as with most other Linux objects
- Introduce wrappers for some optional functions to get consistent behaviour
- Wrapput_charwhich used to be patched by the tty layer
- Document which functions are needed/optional
- Makeput_charreport success/fail
- Cache thedriver->opspointer in the tty astty->ops
- Remove various surplus lock calls we no longer need
- Removeproc_writemethod as noted by Alexey Dobriyan
- Introduce some missing sanity checks where certain driver/ldisc combinations would oops as they didn't check needed methods were present
Quoted 1 line
Signed-off-by Alan Cox <[email protected]>
Very nice, thanks for plugging away on this rework, it's really appreciated.
If you want, you can add:
to the patch.
thanks,
greg k-h