diff mbox

[RFC,20/24] SERIAL: core: add xmit buffer allocation callbacks

Message ID E1TKTlL-0002ni-MB@rmk-PC.arm.linux.org.uk (mailing list archive)
State New, archived
Headers show

Commit Message

Russell King Oct. 6, 2012, 12:45 p.m. UTC
This allows drivers (such as OMAP serial) to allocate and free their
transmit buffers in a sane manner, rather than working around the
buffer allocation provided by serial_core.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/tty/serial/serial_core.c |   23 ++++++++++++++++-------
 include/linux/serial_core.h      |    2 ++
 2 files changed, 18 insertions(+), 7 deletions(-)

Comments

Alan Cox Oct. 6, 2012, 3:49 p.m. UTC | #1
On Sat, 06 Oct 2012 13:45:47 +0100
Russell King <rmk+kernel@arm.linux.org.uk> wrote:

> This allows drivers (such as OMAP serial) to allocate and free their
> transmit buffers in a sane manner, rather than working around the
> buffer allocation provided by serial_core.

I think this just illustrates how broken the serial_core layering is in
that drivers can't treat it as a library but get constrained by it.

Fine for now and actually probably a useful hook to begin removing the
circ buffers for the kernel generic kfifo and other work that needs doing
eventually.

Alan
Russell King - ARM Linux Oct. 6, 2012, 4:51 p.m. UTC | #2
On Sat, Oct 06, 2012 at 04:49:56PM +0100, Alan Cox wrote:
> On Sat, 06 Oct 2012 13:45:47 +0100
> Russell King <rmk+kernel@arm.linux.org.uk> wrote:
> 
> > This allows drivers (such as OMAP serial) to allocate and free their
> > transmit buffers in a sane manner, rather than working around the
> > buffer allocation provided by serial_core.
> 
> I think this just illustrates how broken the serial_core layering is in
> that drivers can't treat it as a library but get constrained by it.
> 
> Fine for now and actually probably a useful hook to begin removing the
> circ buffers for the kernel generic kfifo and other work that needs doing
> eventually.

Yes, I was thinking about turning the 'default' buffer allocation into
a library call which drivers would set, but I felt that's just asking
for a big patch and problems with new drivers appearing.

We could transition it by providing a default buffer allocation call,
converting all the drivers, and then making that call mandatory.  That
probably would then give us a better path to convert to kfifo.

The view that serial_core should be a library is one that Ted mentioned
when I created serial_core originally - I disagreed at the time, and
I still believe it would've ended up being much more complex - and
hairy - to go that route at that time.  Maybe as things have moved
forward in the tty layer that's changed, but I've been out of tty stuff
for too long to properly comment.
diff mbox

Patch

diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 4dd609e..53274ae 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -147,12 +147,18 @@  static int uart_port_startup(struct tty_struct *tty, struct uart_state *state,
 	 * buffer.
 	 */
 	if (!state->xmit.buf) {
-		/* This is protected by the per port mutex */
-		page = get_zeroed_page(GFP_KERNEL);
-		if (!page)
-			return -ENOMEM;
+		if (uport->ops->alloc_xmit) {
+			retval = uport->ops->alloc_xmit(uport, &state->xmit);
+			if (retval)
+				return retval;
+		} else {
+			/* This is protected by the per port mutex */
+			page = get_zeroed_page(GFP_KERNEL);
+			if (!page)
+				return -ENOMEM;
 
-		state->xmit.buf = (unsigned char *) page;
+			state->xmit.buf = (unsigned char *) page;
+		}
 		uart_circ_clear(&state->xmit);
 	}
 
@@ -257,7 +263,10 @@  static void uart_shutdown(struct tty_struct *tty, struct uart_state *state)
 	 * Free the transmit buffer page.
 	 */
 	if (state->xmit.buf) {
-		free_page((unsigned long)state->xmit.buf);
+		if (uport->ops->free_xmit)
+			uport->ops->free_xmit(uport, &state->xmit);
+		else
+			free_page((unsigned long)state->xmit.buf);
 		state->xmit.buf = NULL;
 	}
 }
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index b17d4c9..ebe9af1 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -248,6 +248,8 @@  struct uart_ops {
 	void		(*break_ctl)(struct uart_port *, int ctl);
 	int		(*startup)(struct uart_port *);
 	void		(*shutdown)(struct uart_port *);
+	int		(*alloc_xmit)(struct uart_port *, struct circ_buf *);
+	void		(*free_xmit)(struct uart_port *, struct circ_buf *);
 	void		(*flush_buffer)(struct uart_port *);
 	void		(*set_termios)(struct uart_port *, struct ktermios *new,
 				       struct ktermios *old);