Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 308359 Details for
Bug 445211
[RFE] DTR/DSR flow control
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
first test patch (latest git based)
test-20080604.patch (text/plain), 10.70 KB, created by
Aristeu Rozanski
on 2008-06-04 15:46:03 UTC
(
hide
)
Description:
first test patch (latest git based)
Filename:
MIME Type:
Creator:
Aristeu Rozanski
Created:
2008-06-04 15:46:03 UTC
Size:
10.70 KB
patch
obsolete
>--- linus-2.6.orig/drivers/serial/8250.c 2008-05-06 14:46:11.000000000 -0400 >+++ linus-2.6/drivers/serial/8250.c 2008-05-30 10:55:28.000000000 -0400 >@@ -350,6 +350,7 @@ static inline int map_8250_out_reg(struc > #define map_8250_out_reg(up, offset) (offset) > > #endif >+#define DEBUG > > static unsigned int serial_in(struct uart_8250_port *up, int offset) > { >@@ -1223,6 +1224,7 @@ static void serial8250_stop_tx(struct ua > { > struct uart_8250_port *up = (struct uart_8250_port *)port; > >+printk("%s: port stopped\n", port->info->tty->name); > __stop_tx(up); > > /* >@@ -1240,6 +1242,7 @@ static void serial8250_start_tx(struct u > { > struct uart_8250_port *up = (struct uart_8250_port *)port; > >+printk("%s: start_tx\n", port->info->tty->name); > if (!(up->ier & UART_IER_THRI)) { > up->ier |= UART_IER_THRI; > serial_out(up, UART_IER, up->ier); >@@ -1270,6 +1273,7 @@ static void serial8250_stop_rx(struct ua > { > struct uart_8250_port *up = (struct uart_8250_port *)port; > >+printk("%s: stop rx\n", port->info->tty->name); > up->ier &= ~UART_IER_RLSI; > up->port.read_status_mask &= ~UART_LSR_DR; > serial_out(up, UART_IER, up->ier); >@@ -1295,6 +1299,7 @@ receive_chars(struct uart_8250_port *up, > int max_count = 256; > char flag; > >+ printk("%s: receiving chars DTR: %i\n", tty->name, (up->mcr & UART_MCR_DTR)? 1:0); > do { > ch = serial_inp(up, UART_RX); > flag = TTY_NORMAL; >@@ -1401,7 +1406,7 @@ static unsigned int check_modem_status(s > if (status & UART_MSR_TERI) > up->port.icount.rng++; > if (status & UART_MSR_DDSR) >- up->port.icount.dsr++; >+ uart_handle_dsr_change(&up->port, status & UART_MSR_DSR); > if (status & UART_MSR_DDCD) > uart_handle_dcd_change(&up->port, status & UART_MSR_DCD); > if (status & UART_MSR_DCTS) >@@ -1676,6 +1681,11 @@ static void serial8250_set_mctrl(struct > struct uart_8250_port *up = (struct uart_8250_port *)port; > unsigned char mcr = 0; > >+ if (mctrl & TIOCM_DTR) >+ printk("%s (%i): setting DTR (%p)\n", port->info->tty->name, __LINE__, __builtin_frame_address(0)); >+ if (mctrl & TIOCM_DSR) >+ printk("%s (%i): setting DSR (%p)\n", port->info->tty->name, __LINE__, __builtin_frame_address(0)); >+ > if (mctrl & TIOCM_RTS) > mcr |= UART_MCR_RTS; > if (mctrl & TIOCM_DTR) >@@ -1729,11 +1739,21 @@ static inline void wait_for_xmitr(struct > /* Wait up to 1s for flow control if necessary */ > if (up->port.flags & UPF_CONS_FLOW) { > unsigned int tmout; >+ struct uart_info *info = up->port.info; >+ > for (tmout = 1000000; tmout; tmout--) { > unsigned int msr = serial_in(up, UART_MSR); > up->msr_saved_flags |= msr & MSR_SAVE_FLAGS; >- if (msr & UART_MSR_CTS) >+ if ((info->flags & UIF_CTS_FLOW) && >+ (msr & UART_MSR_CTS)) { >+printk("%s:%i: 8250: got CTS\n", __FILE__, __LINE__); > break; >+ } >+ else if ((info->flags & UIF_DSR_FLOW) && >+ (msr & UART_MSR_DSR)) { >+printk("%s:%i: 8250: got DSR\n", __FILE__, __LINE__); >+ break; >+ } > udelay(1); > touch_nmi_watchdog(); > } >--- linus-2.6.orig/drivers/serial/serial_core.c 2008-05-06 14:46:11.000000000 -0400 >+++ linus-2.6/drivers/serial/serial_core.c 2008-05-30 10:53:13.000000000 -0400 >@@ -130,8 +130,16 @@ uart_update_mctrl(struct uart_port *port > spin_unlock_irqrestore(&port->lock, flags); > } > >-#define uart_set_mctrl(port, set) uart_update_mctrl(port, set, 0) >-#define uart_clear_mctrl(port, clear) uart_update_mctrl(port, 0, clear) >+#define uart_set_mctrl(port, set) do {\ >+ if ((set) & TIOCM_DTR) printk("%s (%i): setting DTR\n", port->info->tty->name, __LINE__);\ >+ if ((set) & TIOCM_DSR) printk("%s (%i): setting DSR\n", port->info->tty->name, __LINE__);\ >+ uart_update_mctrl(port, set, 0); \ >+ } while(0) >+#define uart_clear_mctrl(port, clear) do {\ >+ if ((clear) & TIOCM_DTR) printk("%s (%i): clearing DTR\n", port->info->tty->name, __LINE__);\ >+ if ((clear) & TIOCM_DSR) printk("%s (%i): clearing DSR\n", port->info->tty->name, __LINE__);\ >+ uart_update_mctrl(port, 0, clear); \ >+ } while(0) > > /* > * Startup the port. This will be called once per open. All calls >@@ -193,6 +201,13 @@ static int uart_startup(struct uart_stat > spin_unlock_irq(&port->lock); > } > >+ if (info->flags & UIF_DSR_FLOW) { >+ spin_lock_irq(&port->lock); >+ if (!(port->ops->get_mctrl(port) & TIOCM_DSR)) >+ info->tty->hw_stopped = 1; >+ spin_unlock_irq(&port->lock); >+ } >+ > info->flags |= UIF_INITIALIZED; > > clear_bit(TTY_IO_ERROR, &info->tty->flags); >@@ -442,10 +457,21 @@ uart_change_speed(struct uart_state *sta > /* > * Set flags based on termios cflag > */ >- if (termios->c_cflag & CRTSCTS) >+ if (termios->c_cflag & CRTSCTS) { > state->info->flags |= UIF_CTS_FLOW; >- else >+ printk("%s: crtsCTS enabled\n", state->info->tty->name); >+ } else { > state->info->flags &= ~UIF_CTS_FLOW; >+ printk("%s: crtsCTS disabled\n", state->info->tty->name); >+ } >+ >+ if (termios->c_cflag & CDTRDSR) { >+ state->info->flags |= UIF_DSR_FLOW; >+ printk("%s: cdtrDSR enabled\n", state->info->tty->name); >+ } else { >+ state->info->flags &= ~UIF_DSR_FLOW; >+ printk("%s: cdtrDSR disabled\n", state->info->tty->name); >+ } > > if (termios->c_cflag & CLOCAL) > state->info->flags &= ~UIF_CHECK_CD; >@@ -607,6 +633,8 @@ static void uart_throttle(struct tty_str > > if (tty->termios->c_cflag & CRTSCTS) > uart_clear_mctrl(state->port, TIOCM_RTS); >+ if (tty->termios->c_cflag & CDTRDSR) >+ uart_clear_mctrl(state->port, TIOCM_DTR); > } > > static void uart_unthrottle(struct tty_struct *tty) >@@ -623,6 +651,8 @@ static void uart_unthrottle(struct tty_s > > if (tty->termios->c_cflag & CRTSCTS) > uart_set_mctrl(port, TIOCM_RTS); >+ if (tty->termios->c_cflag & CDTRDSR) >+ uart_set_mctrl(port, TIOCM_DTR); > } > > static int uart_get_info(struct uart_state *state, >@@ -1198,6 +1228,9 @@ static void uart_set_termios(struct tty_ > if (!(cflag & CRTSCTS) || > !test_bit(TTY_THROTTLED, &tty->flags)) > mask |= TIOCM_RTS; >+ if (!(cflag & CDTRDSR) || >+ !test_bit(TTY_THROTTLED, &tty->flags)) >+ mask &= ~TIOCM_DTR; > uart_set_mctrl(state->port, mask); > } > >@@ -1218,6 +1251,24 @@ static void uart_set_termios(struct tty_ > } > spin_unlock_irqrestore(&state->port->lock, flags); > } >+ >+ /* Handle turning off CDTRDSR */ >+ if ((old_termios->c_cflag & CDTRDSR) && !(cflag & CDTRDSR)) { >+ spin_lock_irqsave(&state->port->lock, flags); >+ tty->hw_stopped = 0; >+ __uart_start(tty); >+ spin_unlock_irqrestore(&state->port->lock, flags); >+ } >+ >+ if (!(old_termios->c_cflag & CDTRDSR) && (cflag & CDTRDSR)) { >+ spin_lock_irqsave(&state->port->lock, flags); >+ if (!(state->port->ops->get_mctrl(state->port) & TIOCM_DSR)) { >+ tty->hw_stopped = 1; >+ state->port->ops->stop_tx(state->port); >+ } >+ spin_unlock_irqrestore(&state->port->lock, flags); >+ } >+ > #if 0 > /* > * No need to wake up processes in open wait, since they >@@ -1497,7 +1548,8 @@ uart_block_til_ready(struct file *filp, > * not set RTS here - we want to make sure we catch > * the data from the modem. > */ >- if (info->tty->termios->c_cflag & CBAUD) >+ if (info->tty->termios->c_cflag & CBAUD && >+ !(info->tty->termios->c_cflag & CDTRDSR)) > uart_set_mctrl(port, TIOCM_DTR); > > /* >@@ -1942,6 +1994,8 @@ uart_set_options(struct uart_port *port, > > if (flow == 'r') > termios.c_cflag |= CRTSCTS; >+ if (flow == 'd') >+ termios.c_cflag |= CDTRDSR; > > /* > * some uarts on other side don't support no flow control. >--- linus-2.6.orig/include/asm-x86/termbits.h 2008-05-06 14:46:11.000000000 -0400 >+++ linus-2.6/include/asm-x86/termbits.h 2008-05-06 14:46:11.000000000 -0400 >@@ -157,6 +157,7 @@ struct ktermios { > #define B3500000 0010016 > #define B4000000 0010017 > #define CIBAUD 002003600000 /* input baud rate */ >+#define CDTRDSR 004000000000 /* dtrdsr flow control */ > #define CMSPAR 010000000000 /* mark or space (stick) parity */ > #define CRTSCTS 020000000000 /* flow control */ > >--- linus-2.6.orig/include/linux/serial_core.h 2008-05-06 14:46:11.000000000 -0400 >+++ linus-2.6/include/linux/serial_core.h 2008-05-30 14:41:29.000000000 -0400 >@@ -350,6 +350,7 @@ struct uart_info { > * Definitions for info->flags. These are _private_ to serial_core, and > * are specific to this structure. They may be queried by low level drivers. > */ >+#define UIF_DSR_FLOW ((__force uif_t) (1 << 22)) > #define UIF_CHECK_CD ((__force uif_t) (1 << 25)) > #define UIF_CTS_FLOW ((__force uif_t) (1 << 26)) > #define UIF_NORMAL_ACTIVE ((__force uif_t) (1 << 29)) >@@ -508,34 +509,50 @@ uart_handle_dcd_change(struct uart_port > } > > /** >- * uart_handle_cts_change - handle a change of clear-to-send state >+ * uart_handle_flow_control_change - handle a change of CTS or DSR > * @port: uart_port structure for the open port >- * @status: new clear to send status, nonzero if active >+ * @status: new CTS/DTR status, nonzero if active > */ > static inline void >-uart_handle_cts_change(struct uart_port *port, unsigned int status) >+uart_handle_flow_control_change(struct uart_port *port, unsigned int status) > { > struct uart_info *info = port->info; > struct tty_struct *tty = info->tty; > >- port->icount.cts++; >- >- if (info->flags & UIF_CTS_FLOW) { >- if (tty->hw_stopped) { >- if (status) { >- tty->hw_stopped = 0; >- port->ops->start_tx(port); >- uart_write_wakeup(port); >- } >- } else { >- if (!status) { >- tty->hw_stopped = 1; >- port->ops->stop_tx(port); >- } >+ if (tty->hw_stopped) { >+ if (status) { >+ tty->hw_stopped = 0; >+ port->ops->start_tx(port); >+ uart_write_wakeup(port); >+ } >+ } else { >+ if (!status) { >+ tty->hw_stopped = 1; >+ port->ops->stop_tx(port); > } > } > } > >+static inline void >+uart_handle_cts_change(struct uart_port *port, unsigned int status) >+{ >+ struct uart_info *info = port->info; >+printk("%s (%i): CTS %s\n", info->tty->name, __LINE__, status? "on":"off"); >+ port->icount.cts++; >+ if (info->flags & UIF_CTS_FLOW) >+ uart_handle_flow_control_change(port, status); >+} >+ >+static inline void >+uart_handle_dsr_change(struct uart_port *port, unsigned int status) >+{ >+ struct uart_info *info = port->info; >+printk("%s (%i): DSR %s\n", info->tty->name, __LINE__, status? "on":"off"); >+ port->icount.dsr++; >+ if (info->flags & UIF_DSR_FLOW) >+ uart_handle_flow_control_change(port, status); >+} >+ > #include <linux/tty_flip.h> > > static inline void >@@ -559,7 +576,7 @@ uart_insert_char(struct uart_port *port, > * UART_ENABLE_MS - determine if port should enable modem status irqs > */ > #define UART_ENABLE_MS(port,cflag) ((port)->flags & UPF_HARDPPS_CD || \ >- (cflag) & CRTSCTS || \ >+ (cflag) & (CRTSCTS | CDTRDSR) || \ > !((cflag) & CLOCAL)) > > #endif >--- linus-2.6.orig/include/linux/termios.h 2008-05-05 18:12:20.000000000 -0400 >+++ linus-2.6/include/linux/termios.h 2008-05-06 14:47:14.000000000 -0400 >@@ -4,4 +4,9 @@ > #include <linux/types.h> > #include <asm/termios.h> > >+#ifndef CDTRDSR >+#warning This architecture should implement CDTRDSR >+#define CDTRDSR 0 /* remove this when all architectures have a definition */ >+#endif >+ > #endif
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 445211
:
308359
|
308360
|
309219
|
309849
|
315299
|
315300
|
315301