Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f34d7a5b authored by Alan Cox's avatar Alan Cox Committed by Linus Torvalds
Browse files

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

[akpm@linux-foundation.org: fix fs/compat_ioctl.c build]
[akpm@linux-foundation.org: fix isicom]
[akpm@linux-foundation.org: fix arch/ia64/hp/sim/simserial.c build]
[akpm@linux-foundation.org: fix kgdb]
Signed-off-by: default avatarAlan Cox <alan@redhat.com>
Acked-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
Cc: Jason Wessel <jason.wessel@windriver.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 251b8dd7
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -210,21 +210,23 @@ static void do_softint(struct work_struct *private_)
	printk(KERN_ERR "simserial: do_softint called\n");
}

static void rs_put_char(struct tty_struct *tty, unsigned char ch)
static int rs_put_char(struct tty_struct *tty, unsigned char ch)
{
	struct async_struct *info = (struct async_struct *)tty->driver_data;
	unsigned long flags;

	if (!tty || !info->xmit.buf) return;
	if (!tty || !info->xmit.buf)
		return 0;

	local_irq_save(flags);
	if (CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE) == 0) {
		local_irq_restore(flags);
		return;
		return 0;
	}
	info->xmit.buf[info->xmit.head] = ch;
	info->xmit.head = (info->xmit.head + 1) & (SERIAL_XMIT_SIZE-1);
	local_irq_restore(flags);
	return 1;
}

static void transmit_chars(struct async_struct *info, int *intr_done)
@@ -621,7 +623,8 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
	 * the line discipline to only process XON/XOFF characters.
	 */
	shutdown(info);
	if (tty->driver->flush_buffer) tty->driver->flush_buffer(tty);
	if (tty->ops->flush_buffer)
		tty->ops->flush_buffer(tty);
	if (tty->ldisc.flush_buffer) tty->ldisc.flush_buffer(tty);
	info->event = 0;
	info->tty = NULL;
+5 −8
Original line number Diff line number Diff line
@@ -143,7 +143,7 @@ int hci_uart_tx_wakeup(struct hci_uart *hu)
		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 @@ static int hci_uart_flush(struct hci_dev *hdev)

	/* 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 @@ static int hci_uart_tty_open(struct tty_struct *tty)

	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 @@ static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *f
	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)
+6 −6
Original line number Diff line number Diff line
@@ -169,7 +169,7 @@ static int Fip_firmware_size;
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 @@ ip2_close( PTTY tty, struct file *pFile )

	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 @@ ip2_write( PTTY tty, const unsigned char *pData, int count)
/*                                                                            */
/*                                                                            */
/******************************************************************************/
static void
static int
ip2_putchar( PTTY tty, unsigned char ch )
{
	i2ChanStrPtr  pCh = tty->driver_data;
@@ -1753,6 +1752,7 @@ ip2_putchar( PTTY tty, unsigned char ch )
		ip2_flush_chars( tty );
	} else
		write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
	return 1;

//	ip2trace (CHANN, ITRC_PUTC, ITRC_RETURN, 1, ch );
}
+8 −7
Original line number Diff line number Diff line
@@ -1140,28 +1140,29 @@ static int isicom_write(struct tty_struct *tty, const unsigned char *buf,
}

/* put_char et all */
static void isicom_put_char(struct tty_struct *tty, unsigned char ch)
static int isicom_put_char(struct tty_struct *tty, unsigned char ch)
{
	struct isi_port *port = tty->driver_data;
	struct isi_board *card = port->card;
	unsigned long flags;

	if (isicom_paranoia_check(port, tty->name, "isicom_put_char"))
		return;
		return 0;

	if (!port->xmit_buf)
		return;
		return 0;

	spin_lock_irqsave(&card->card_lock, flags);
	if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1)
		goto out;
	if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {
		spin_unlock_irqrestore(&card->card_lock, flags);
		return 0;
	}

	port->xmit_buf[port->xmit_head++] = ch;
	port->xmit_head &= (SERIAL_XMIT_SIZE - 1);
	port->xmit_cnt++;
	spin_unlock_irqrestore(&card->card_lock, flags);
out:
	return;
	return 1;
}

/* flush_chars et all */
+1 −1
Original line number Diff line number Diff line
@@ -1230,7 +1230,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)

	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
Loading