aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/generic_serial.c
diff options
context:
space:
mode:
authorAlan Cox <alan@lxorguk.ukuu.org.uk>2007-07-16 02:41:47 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-16 12:05:51 -0400
commit35426128adaacf8cdabc2482598252d488b7ccb9 (patch)
tree492831903703126e883c9eb82c61f49e81c230fb /drivers/char/generic_serial.c
parentdb0ef08efa1bb94ba9a9e44c255d9058df5fde8d (diff)
genericserial: remove bogus optimisation check and dead code paths
We've been using the 'new locking' for a long time now so it seems pointless keeping the old one around. Remove it and undo the macros it uses back into real code for readability. Remove the bogus 'no termios change' checks. Signed-off-by: Alan Cox <alan@redhat.com> Cc: Morten Helgesen <morten@sourcepoet.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char/generic_serial.c')
-rw-r--r--drivers/char/generic_serial.c120
1 files changed, 3 insertions, 117 deletions
diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c
index 8ea02755b1c9..8facf3e25c49 100644
--- a/drivers/char/generic_serial.c
+++ b/drivers/char/generic_serial.c
@@ -43,16 +43,6 @@ static int gs_debug;
43 43
44#define func_enter() gs_dprintk (GS_DEBUG_FLOW, "gs: enter %s\n", __FUNCTION__) 44#define func_enter() gs_dprintk (GS_DEBUG_FLOW, "gs: enter %s\n", __FUNCTION__)
45#define func_exit() gs_dprintk (GS_DEBUG_FLOW, "gs: exit %s\n", __FUNCTION__) 45#define func_exit() gs_dprintk (GS_DEBUG_FLOW, "gs: exit %s\n", __FUNCTION__)
46#define NEW_WRITE_LOCKING 1
47#if NEW_WRITE_LOCKING
48#define DECL /* Nothing */
49#define LOCKIT mutex_lock(& port->port_write_mutex);
50#define RELEASEIT mutex_unlock(&port->port_write_mutex);
51#else
52#define DECL unsigned long flags;
53#define LOCKIT save_flags (flags);cli ()
54#define RELEASEIT restore_flags (flags)
55#endif
56 46
57#define RS_EVENT_WRITE_WAKEUP 1 47#define RS_EVENT_WRITE_WAKEUP 1
58 48
@@ -62,7 +52,6 @@ module_param(gs_debug, int, 0644);
62void gs_put_char(struct tty_struct * tty, unsigned char ch) 52void gs_put_char(struct tty_struct * tty, unsigned char ch)
63{ 53{
64 struct gs_port *port; 54 struct gs_port *port;
65 DECL
66 55
67 func_enter (); 56 func_enter ();
68 57
@@ -75,11 +64,11 @@ void gs_put_char(struct tty_struct * tty, unsigned char ch)
75 if (! (port->flags & ASYNC_INITIALIZED)) return; 64 if (! (port->flags & ASYNC_INITIALIZED)) return;
76 65
77 /* Take a lock on the serial tranmit buffer! */ 66 /* Take a lock on the serial tranmit buffer! */
78 LOCKIT; 67 mutex_lock(& port->port_write_mutex);
79 68
80 if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) { 69 if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {
81 /* Sorry, buffer is full, drop character. Update statistics???? -- REW */ 70 /* Sorry, buffer is full, drop character. Update statistics???? -- REW */
82 RELEASEIT; 71 mutex_unlock(&port->port_write_mutex);
83 return; 72 return;
84 } 73 }
85 74
@@ -87,13 +76,11 @@ void gs_put_char(struct tty_struct * tty, unsigned char ch)
87 port->xmit_head &= SERIAL_XMIT_SIZE - 1; 76 port->xmit_head &= SERIAL_XMIT_SIZE - 1;
88 port->xmit_cnt++; /* Characters in buffer */ 77 port->xmit_cnt++; /* Characters in buffer */
89 78
90 RELEASEIT; 79 mutex_unlock(&port->port_write_mutex);
91 func_exit (); 80 func_exit ();
92} 81}
93 82
94 83
95#ifdef NEW_WRITE_LOCKING
96
97/* 84/*
98> Problems to take into account are: 85> Problems to take into account are:
99> -1- Interrupts that empty part of the buffer. 86> -1- Interrupts that empty part of the buffer.
@@ -166,90 +153,6 @@ int gs_write(struct tty_struct * tty,
166 func_exit (); 153 func_exit ();
167 return total; 154 return total;
168} 155}
169#else
170/*
171> Problems to take into account are:
172> -1- Interrupts that empty part of the buffer.
173> -2- page faults on the access to userspace.
174> -3- Other processes that are also trying to do a "write".
175*/
176
177int gs_write(struct tty_struct * tty,
178 const unsigned char *buf, int count)
179{
180 struct gs_port *port;
181 int c, total = 0;
182 int t;
183 unsigned long flags;
184
185 func_enter ();
186
187 /* The standard serial driver returns 0 in this case.
188 That sounds to me as "No error, I just didn't get to writing any
189 bytes. Feel free to try again."
190 The "official" way to write n bytes from buf is:
191
192 for (nwritten = 0;nwritten < n;nwritten += rv) {
193 rv = write (fd, buf+nwritten, n-nwritten);
194 if (rv < 0) break; // Error: bail out. //
195 }
196
197 which will loop endlessly in this case. The manual page for write
198 agrees with me. In practise almost everybody writes
199 "write (fd, buf,n);" but some people might have had to deal with
200 incomplete writes in the past and correctly implemented it by now...
201 */
202
203 if (!tty) return -EIO;
204
205 port = tty->driver_data;
206 if (!port || !port->xmit_buf)
207 return -EIO;
208
209 local_save_flags(flags);
210 while (1) {
211 cli();
212 c = count;
213
214 /* This is safe because we "OWN" the "head". Noone else can
215 change the "head": we own the port_write_mutex. */
216 /* Don't overrun the end of the buffer */
217 t = SERIAL_XMIT_SIZE - port->xmit_head;
218 if (t < c) c = t;
219
220 /* This is safe because the xmit_cnt can only decrease. This
221 would increase "t", so we might copy too little chars. */
222 /* Don't copy past the "head" of the buffer */
223 t = SERIAL_XMIT_SIZE - 1 - port->xmit_cnt;
224 if (t < c) c = t;
225
226 /* Can't copy more? break out! */
227 if (c <= 0) {
228 local_restore_flags(flags);
229 break;
230 }
231 memcpy(port->xmit_buf + port->xmit_head, buf, c);
232 port->xmit_head = ((port->xmit_head + c) &
233 (SERIAL_XMIT_SIZE-1));
234 port->xmit_cnt += c;
235 local_restore_flags(flags);
236 buf += c;
237 count -= c;
238 total += c;
239 }
240
241 if (port->xmit_cnt &&
242 !tty->stopped &&
243 !tty->hw_stopped &&
244 !(port->flags & GS_TX_INTEN)) {
245 port->flags |= GS_TX_INTEN;
246 port->rd->enable_tx_interrupts (port);
247 }
248 func_exit ();
249 return total;
250}
251
252#endif
253 156
254 157
255 158
@@ -737,23 +640,6 @@ void gs_set_termios (struct tty_struct * tty,
737 gs_dprintk (GS_DEBUG_TERMIOS, "termios structure (%p):\n", tiosp); 640 gs_dprintk (GS_DEBUG_TERMIOS, "termios structure (%p):\n", tiosp);
738 } 641 }
739 642
740 /* This is an optimization that is only allowed for dumb cards */
741 /* Smart cards require knowledge of iflags and oflags too: that
742 might change hardware cooking mode.... */
743 if (old_termios) {
744 if( (tiosp->c_iflag == old_termios->c_iflag)
745 && (tiosp->c_oflag == old_termios->c_oflag)
746 && (tiosp->c_cflag == old_termios->c_cflag)
747 && (tiosp->c_lflag == old_termios->c_lflag)
748 && (tiosp->c_line == old_termios->c_line)
749 && (memcmp(tiosp->c_cc, old_termios->c_cc, NCC) == 0)) {
750 gs_dprintk(GS_DEBUG_TERMIOS, "gs_set_termios: optimized away\n");
751 return /* 0 */;
752 }
753 } else
754 gs_dprintk(GS_DEBUG_TERMIOS, "gs_set_termios: no old_termios: "
755 "no optimization\n");
756
757 if(old_termios && (gs_debug & GS_DEBUG_TERMIOS)) { 643 if(old_termios && (gs_debug & GS_DEBUG_TERMIOS)) {
758 if(tiosp->c_iflag != old_termios->c_iflag) printk("c_iflag changed\n"); 644 if(tiosp->c_iflag != old_termios->c_iflag) printk("c_iflag changed\n");
759 if(tiosp->c_oflag != old_termios->c_oflag) printk("c_oflag changed\n"); 645 if(tiosp->c_oflag != old_termios->c_oflag) printk("c_oflag changed\n");