aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/moxa.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-12-11 18:34:40 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-11 18:34:40 -0500
commit0f4974c439dd7826c85bae4e6a8088ce2db0f498 (patch)
treefdabc7d9bb7d7bc49aad547c0aac3a633ce01f09 /drivers/char/moxa.c
parent3126c136bc30225d7a43af741778aa50e95e467a (diff)
parent36ba782e9674cdc29ec7003757df0b375e99fa96 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6: (58 commits) tty: split the lock up a bit further tty: Move the leader test in disassociate tty: Push the bkl down a bit in the hangup code tty: Push the lock down further into the ldisc code tty: push the BKL down into the handlers a bit tty: moxa: split open lock tty: moxa: Kill the use of lock_kernel tty: moxa: Fix modem op locking tty: moxa: Kill off the throttle method tty: moxa: Locking clean up tty: moxa: rework the locking a bit tty: moxa: Use more tty_port ops tty: isicom: fix deadlock on shutdown tty: mxser: Use the new locking rules to fix setserial properly tty: mxser: use the tty_port_open method tty: isicom: sort out the board init logic tty: isicom: switch to the new tty_port_open helper tty: tty_port: Add a kref object to the tty port tty: istallion: tty port open/close methods tty: stallion: Convert to the tty_port_open/close methods ...
Diffstat (limited to 'drivers/char/moxa.c')
-rw-r--r--drivers/char/moxa.c289
1 files changed, 83 insertions, 206 deletions
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index dd0083bbb64a..63ee3bbc1ce4 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -34,7 +34,6 @@
34#include <linux/tty.h> 34#include <linux/tty.h>
35#include <linux/tty_flip.h> 35#include <linux/tty_flip.h>
36#include <linux/major.h> 36#include <linux/major.h>
37#include <linux/smp_lock.h>
38#include <linux/string.h> 37#include <linux/string.h>
39#include <linux/fcntl.h> 38#include <linux/fcntl.h>
40#include <linux/ptrace.h> 39#include <linux/ptrace.h>
@@ -139,7 +138,7 @@ struct moxa_port {
139 int cflag; 138 int cflag;
140 unsigned long statusflags; 139 unsigned long statusflags;
141 140
142 u8 DCDState; 141 u8 DCDState; /* Protected by the port lock */
143 u8 lineCtrl; 142 u8 lineCtrl;
144 u8 lowChkFlag; 143 u8 lowChkFlag;
145}; 144};
@@ -151,10 +150,9 @@ struct mon_str {
151}; 150};
152 151
153/* statusflags */ 152/* statusflags */
154#define TXSTOPPED 0x1 153#define TXSTOPPED 1
155#define LOWWAIT 0x2 154#define LOWWAIT 2
156#define EMPTYWAIT 0x4 155#define EMPTYWAIT 3
157#define THROTTLE 0x8
158 156
159#define SERIAL_DO_RESTART 157#define SERIAL_DO_RESTART
160 158
@@ -165,6 +163,7 @@ static struct mon_str moxaLog;
165static unsigned int moxaFuncTout = HZ / 2; 163static unsigned int moxaFuncTout = HZ / 2;
166static unsigned int moxaLowWaterChk; 164static unsigned int moxaLowWaterChk;
167static DEFINE_MUTEX(moxa_openlock); 165static DEFINE_MUTEX(moxa_openlock);
166static DEFINE_SPINLOCK(moxa_lock);
168/* Variables for insmod */ 167/* Variables for insmod */
169#ifdef MODULE 168#ifdef MODULE
170static unsigned long baseaddr[MAX_BOARDS]; 169static unsigned long baseaddr[MAX_BOARDS];
@@ -194,8 +193,6 @@ static int moxa_write(struct tty_struct *, const unsigned char *, int);
194static int moxa_write_room(struct tty_struct *); 193static int moxa_write_room(struct tty_struct *);
195static void moxa_flush_buffer(struct tty_struct *); 194static void moxa_flush_buffer(struct tty_struct *);
196static int moxa_chars_in_buffer(struct tty_struct *); 195static int moxa_chars_in_buffer(struct tty_struct *);
197static void moxa_throttle(struct tty_struct *);
198static void moxa_unthrottle(struct tty_struct *);
199static void moxa_set_termios(struct tty_struct *, struct ktermios *); 196static void moxa_set_termios(struct tty_struct *, struct ktermios *);
200static void moxa_stop(struct tty_struct *); 197static void moxa_stop(struct tty_struct *);
201static void moxa_start(struct tty_struct *); 198static void moxa_start(struct tty_struct *);
@@ -205,9 +202,9 @@ static int moxa_tiocmset(struct tty_struct *tty, struct file *file,
205 unsigned int set, unsigned int clear); 202 unsigned int set, unsigned int clear);
206static void moxa_poll(unsigned long); 203static void moxa_poll(unsigned long);
207static void moxa_set_tty_param(struct tty_struct *, struct ktermios *); 204static void moxa_set_tty_param(struct tty_struct *, struct ktermios *);
208static void moxa_setup_empty_event(struct tty_struct *); 205static void moxa_shutdown(struct tty_port *);
209static void moxa_shut_down(struct tty_struct *);
210static int moxa_carrier_raised(struct tty_port *); 206static int moxa_carrier_raised(struct tty_port *);
207static void moxa_dtr_rts(struct tty_port *, int);
211/* 208/*
212 * moxa board interface functions: 209 * moxa board interface functions:
213 */ 210 */
@@ -234,6 +231,8 @@ static void MoxaSetFifo(struct moxa_port *port, int enable);
234 * I/O functions 231 * I/O functions
235 */ 232 */
236 233
234static DEFINE_SPINLOCK(moxafunc_lock);
235
237static void moxa_wait_finish(void __iomem *ofsAddr) 236static void moxa_wait_finish(void __iomem *ofsAddr)
238{ 237{
239 unsigned long end = jiffies + moxaFuncTout; 238 unsigned long end = jiffies + moxaFuncTout;
@@ -247,9 +246,25 @@ static void moxa_wait_finish(void __iomem *ofsAddr)
247 246
248static void moxafunc(void __iomem *ofsAddr, u16 cmd, u16 arg) 247static void moxafunc(void __iomem *ofsAddr, u16 cmd, u16 arg)
249{ 248{
249 unsigned long flags;
250 spin_lock_irqsave(&moxafunc_lock, flags);
250 writew(arg, ofsAddr + FuncArg); 251 writew(arg, ofsAddr + FuncArg);
251 writew(cmd, ofsAddr + FuncCode); 252 writew(cmd, ofsAddr + FuncCode);
252 moxa_wait_finish(ofsAddr); 253 moxa_wait_finish(ofsAddr);
254 spin_unlock_irqrestore(&moxafunc_lock, flags);
255}
256
257static int moxafuncret(void __iomem *ofsAddr, u16 cmd, u16 arg)
258{
259 unsigned long flags;
260 u16 ret;
261 spin_lock_irqsave(&moxafunc_lock, flags);
262 writew(arg, ofsAddr + FuncArg);
263 writew(cmd, ofsAddr + FuncCode);
264 moxa_wait_finish(ofsAddr);
265 ret = readw(ofsAddr + FuncArg);
266 spin_unlock_irqrestore(&moxafunc_lock, flags);
267 return ret;
253} 268}
254 269
255static void moxa_low_water_check(void __iomem *ofsAddr) 270static void moxa_low_water_check(void __iomem *ofsAddr)
@@ -299,22 +314,20 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
299 struct moxa_port *p; 314 struct moxa_port *p;
300 unsigned int i, j; 315 unsigned int i, j;
301 316
302 mutex_lock(&moxa_openlock);
303 for (i = 0; i < MAX_BOARDS; i++) { 317 for (i = 0; i < MAX_BOARDS; i++) {
304 p = moxa_boards[i].ports; 318 p = moxa_boards[i].ports;
305 for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) { 319 for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) {
306 memset(&tmp, 0, sizeof(tmp)); 320 memset(&tmp, 0, sizeof(tmp));
321 spin_lock_bh(&moxa_lock);
307 if (moxa_boards[i].ready) { 322 if (moxa_boards[i].ready) {
308 tmp.inq = MoxaPortRxQueue(p); 323 tmp.inq = MoxaPortRxQueue(p);
309 tmp.outq = MoxaPortTxQueue(p); 324 tmp.outq = MoxaPortTxQueue(p);
310 } 325 }
311 if (copy_to_user(argm, &tmp, sizeof(tmp))) { 326 spin_unlock_bh(&moxa_lock);
312 mutex_unlock(&moxa_openlock); 327 if (copy_to_user(argm, &tmp, sizeof(tmp)))
313 return -EFAULT; 328 return -EFAULT;
314 }
315 } 329 }
316 } 330 }
317 mutex_unlock(&moxa_openlock);
318 break; 331 break;
319 } case MOXA_GET_OQUEUE: 332 } case MOXA_GET_OQUEUE:
320 status = MoxaPortTxQueue(ch); 333 status = MoxaPortTxQueue(ch);
@@ -330,16 +343,20 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
330 struct moxa_port *p; 343 struct moxa_port *p;
331 unsigned int i, j; 344 unsigned int i, j;
332 345
333 mutex_lock(&moxa_openlock);
334 for (i = 0; i < MAX_BOARDS; i++) { 346 for (i = 0; i < MAX_BOARDS; i++) {
335 p = moxa_boards[i].ports; 347 p = moxa_boards[i].ports;
336 for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) { 348 for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) {
337 struct tty_struct *ttyp; 349 struct tty_struct *ttyp;
338 memset(&tmp, 0, sizeof(tmp)); 350 memset(&tmp, 0, sizeof(tmp));
339 if (!moxa_boards[i].ready) 351 spin_lock_bh(&moxa_lock);
352 if (!moxa_boards[i].ready) {
353 spin_unlock_bh(&moxa_lock);
340 goto copy; 354 goto copy;
355 }
341 356
342 status = MoxaPortLineStatus(p); 357 status = MoxaPortLineStatus(p);
358 spin_unlock_bh(&moxa_lock);
359
343 if (status & 1) 360 if (status & 1)
344 tmp.cts = 1; 361 tmp.cts = 1;
345 if (status & 2) 362 if (status & 2)
@@ -354,24 +371,21 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
354 tmp.cflag = ttyp->termios->c_cflag; 371 tmp.cflag = ttyp->termios->c_cflag;
355 tty_kref_put(tty); 372 tty_kref_put(tty);
356copy: 373copy:
357 if (copy_to_user(argm, &tmp, sizeof(tmp))) { 374 if (copy_to_user(argm, &tmp, sizeof(tmp)))
358 mutex_unlock(&moxa_openlock);
359 return -EFAULT; 375 return -EFAULT;
360 }
361 } 376 }
362 } 377 }
363 mutex_unlock(&moxa_openlock);
364 break; 378 break;
365 } 379 }
366 case TIOCGSERIAL: 380 case TIOCGSERIAL:
367 mutex_lock(&moxa_openlock); 381 mutex_lock(&ch->port.mutex);
368 ret = moxa_get_serial_info(ch, argp); 382 ret = moxa_get_serial_info(ch, argp);
369 mutex_unlock(&moxa_openlock); 383 mutex_unlock(&ch->port.mutex);
370 break; 384 break;
371 case TIOCSSERIAL: 385 case TIOCSSERIAL:
372 mutex_lock(&moxa_openlock); 386 mutex_lock(&ch->port.mutex);
373 ret = moxa_set_serial_info(ch, argp); 387 ret = moxa_set_serial_info(ch, argp);
374 mutex_unlock(&moxa_openlock); 388 mutex_unlock(&ch->port.mutex);
375 break; 389 break;
376 default: 390 default:
377 ret = -ENOIOCTLCMD; 391 ret = -ENOIOCTLCMD;
@@ -396,8 +410,6 @@ static const struct tty_operations moxa_ops = {
396 .flush_buffer = moxa_flush_buffer, 410 .flush_buffer = moxa_flush_buffer,
397 .chars_in_buffer = moxa_chars_in_buffer, 411 .chars_in_buffer = moxa_chars_in_buffer,
398 .ioctl = moxa_ioctl, 412 .ioctl = moxa_ioctl,
399 .throttle = moxa_throttle,
400 .unthrottle = moxa_unthrottle,
401 .set_termios = moxa_set_termios, 413 .set_termios = moxa_set_termios,
402 .stop = moxa_stop, 414 .stop = moxa_stop,
403 .start = moxa_start, 415 .start = moxa_start,
@@ -409,11 +421,12 @@ static const struct tty_operations moxa_ops = {
409 421
410static const struct tty_port_operations moxa_port_ops = { 422static const struct tty_port_operations moxa_port_ops = {
411 .carrier_raised = moxa_carrier_raised, 423 .carrier_raised = moxa_carrier_raised,
424 .dtr_rts = moxa_dtr_rts,
425 .shutdown = moxa_shutdown,
412}; 426};
413 427
414static struct tty_driver *moxaDriver; 428static struct tty_driver *moxaDriver;
415static DEFINE_TIMER(moxaTimer, moxa_poll, 0, 0); 429static DEFINE_TIMER(moxaTimer, moxa_poll, 0, 0);
416static DEFINE_SPINLOCK(moxa_lock);
417 430
418/* 431/*
419 * HW init 432 * HW init
@@ -1112,14 +1125,12 @@ static void __exit moxa_exit(void)
1112module_init(moxa_init); 1125module_init(moxa_init);
1113module_exit(moxa_exit); 1126module_exit(moxa_exit);
1114 1127
1115static void moxa_close_port(struct tty_struct *tty) 1128static void moxa_shutdown(struct tty_port *port)
1116{ 1129{
1117 struct moxa_port *ch = tty->driver_data; 1130 struct moxa_port *ch = container_of(port, struct moxa_port, port);
1118 moxa_shut_down(tty); 1131 MoxaPortDisable(ch);
1119 MoxaPortFlushData(ch, 2); 1132 MoxaPortFlushData(ch, 2);
1120 ch->port.flags &= ~ASYNC_NORMAL_ACTIVE; 1133 clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags);
1121 tty->driver_data = NULL;
1122 tty_port_tty_set(&ch->port, NULL);
1123} 1134}
1124 1135
1125static int moxa_carrier_raised(struct tty_port *port) 1136static int moxa_carrier_raised(struct tty_port *port)
@@ -1127,45 +1138,19 @@ static int moxa_carrier_raised(struct tty_port *port)
1127 struct moxa_port *ch = container_of(port, struct moxa_port, port); 1138 struct moxa_port *ch = container_of(port, struct moxa_port, port);
1128 int dcd; 1139 int dcd;
1129 1140
1130 spin_lock_bh(&moxa_lock); 1141 spin_lock_irq(&port->lock);
1131 dcd = ch->DCDState; 1142 dcd = ch->DCDState;
1132 spin_unlock_bh(&moxa_lock); 1143 spin_unlock_irq(&port->lock);
1133 return dcd; 1144 return dcd;
1134} 1145}
1135 1146
1136static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp, 1147static void moxa_dtr_rts(struct tty_port *port, int onoff)
1137 struct moxa_port *ch)
1138{ 1148{
1139 struct tty_port *port = &ch->port; 1149 struct moxa_port *ch = container_of(port, struct moxa_port, port);
1140 DEFINE_WAIT(wait); 1150 MoxaPortLineCtrl(ch, onoff, onoff);
1141 int retval = 0;
1142 u8 dcd;
1143
1144 while (1) {
1145 prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE);
1146 if (tty_hung_up_p(filp)) {
1147#ifdef SERIAL_DO_RESTART
1148 retval = -ERESTARTSYS;
1149#else
1150 retval = -EAGAIN;
1151#endif
1152 break;
1153 }
1154 dcd = tty_port_carrier_raised(port);
1155 if (dcd)
1156 break;
1157
1158 if (signal_pending(current)) {
1159 retval = -ERESTARTSYS;
1160 break;
1161 }
1162 schedule();
1163 }
1164 finish_wait(&port->open_wait, &wait);
1165
1166 return retval;
1167} 1151}
1168 1152
1153
1169static int moxa_open(struct tty_struct *tty, struct file *filp) 1154static int moxa_open(struct tty_struct *tty, struct file *filp)
1170{ 1155{
1171 struct moxa_board_conf *brd; 1156 struct moxa_board_conf *brd;
@@ -1194,6 +1179,7 @@ static int moxa_open(struct tty_struct *tty, struct file *filp)
1194 ch->port.count++; 1179 ch->port.count++;
1195 tty->driver_data = ch; 1180 tty->driver_data = ch;
1196 tty_port_tty_set(&ch->port, tty); 1181 tty_port_tty_set(&ch->port, tty);
1182 mutex_lock(&ch->port.mutex);
1197 if (!(ch->port.flags & ASYNC_INITIALIZED)) { 1183 if (!(ch->port.flags & ASYNC_INITIALIZED)) {
1198 ch->statusflags = 0; 1184 ch->statusflags = 0;
1199 moxa_set_tty_param(tty, tty->termios); 1185 moxa_set_tty_param(tty, tty->termios);
@@ -1202,58 +1188,20 @@ static int moxa_open(struct tty_struct *tty, struct file *filp)
1202 MoxaSetFifo(ch, ch->type == PORT_16550A); 1188 MoxaSetFifo(ch, ch->type == PORT_16550A);
1203 ch->port.flags |= ASYNC_INITIALIZED; 1189 ch->port.flags |= ASYNC_INITIALIZED;
1204 } 1190 }
1191 mutex_unlock(&ch->port.mutex);
1205 mutex_unlock(&moxa_openlock); 1192 mutex_unlock(&moxa_openlock);
1206 1193
1207 retval = 0; 1194 retval = tty_port_block_til_ready(&ch->port, tty, filp);
1208 if (!(filp->f_flags & O_NONBLOCK) && !C_CLOCAL(tty)) 1195 if (retval == 0)
1209 retval = moxa_block_till_ready(tty, filp, ch); 1196 set_bit(ASYNCB_NORMAL_ACTIVE, &ch->port.flags);
1210 mutex_lock(&moxa_openlock);
1211 if (retval) {
1212 if (ch->port.count) /* 0 means already hung up... */
1213 if (--ch->port.count == 0)
1214 moxa_close_port(tty);
1215 } else
1216 ch->port.flags |= ASYNC_NORMAL_ACTIVE;
1217 mutex_unlock(&moxa_openlock);
1218
1219 return retval; 1197 return retval;
1220} 1198}
1221 1199
1222static void moxa_close(struct tty_struct *tty, struct file *filp) 1200static void moxa_close(struct tty_struct *tty, struct file *filp)
1223{ 1201{
1224 struct moxa_port *ch; 1202 struct moxa_port *ch = tty->driver_data;
1225 int port;
1226
1227 port = tty->index;
1228 if (port == MAX_PORTS || tty_hung_up_p(filp))
1229 return;
1230
1231 mutex_lock(&moxa_openlock);
1232 ch = tty->driver_data;
1233 if (ch == NULL)
1234 goto unlock;
1235 if (tty->count == 1 && ch->port.count != 1) {
1236 printk(KERN_WARNING "moxa_close: bad serial port count; "
1237 "tty->count is 1, ch->port.count is %d\n", ch->port.count);
1238 ch->port.count = 1;
1239 }
1240 if (--ch->port.count < 0) {
1241 printk(KERN_WARNING "moxa_close: bad serial port count, "
1242 "device=%s\n", tty->name);
1243 ch->port.count = 0;
1244 }
1245 if (ch->port.count)
1246 goto unlock;
1247
1248 ch->cflag = tty->termios->c_cflag; 1203 ch->cflag = tty->termios->c_cflag;
1249 if (ch->port.flags & ASYNC_INITIALIZED) { 1204 tty_port_close(&ch->port, tty, filp);
1250 moxa_setup_empty_event(tty);
1251 tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */
1252 }
1253
1254 moxa_close_port(tty);
1255unlock:
1256 mutex_unlock(&moxa_openlock);
1257} 1205}
1258 1206
1259static int moxa_write(struct tty_struct *tty, 1207static int moxa_write(struct tty_struct *tty,
@@ -1269,7 +1217,7 @@ static int moxa_write(struct tty_struct *tty,
1269 len = MoxaPortWriteData(tty, buf, count); 1217 len = MoxaPortWriteData(tty, buf, count);
1270 spin_unlock_bh(&moxa_lock); 1218 spin_unlock_bh(&moxa_lock);
1271 1219
1272 ch->statusflags |= LOWWAIT; 1220 set_bit(LOWWAIT, &ch->statusflags);
1273 return len; 1221 return len;
1274} 1222}
1275 1223
@@ -1300,40 +1248,21 @@ static int moxa_chars_in_buffer(struct tty_struct *tty)
1300 struct moxa_port *ch = tty->driver_data; 1248 struct moxa_port *ch = tty->driver_data;
1301 int chars; 1249 int chars;
1302 1250
1303 /*
1304 * Sigh...I have to check if driver_data is NULL here, because
1305 * if an open() fails, the TTY subsystem eventually calls
1306 * tty_wait_until_sent(), which calls the driver's chars_in_buffer()
1307 * routine. And since the open() failed, we return 0 here. TDJ
1308 */
1309 if (ch == NULL)
1310 return 0;
1311 lock_kernel();
1312 chars = MoxaPortTxQueue(ch); 1251 chars = MoxaPortTxQueue(ch);
1313 if (chars) { 1252 if (chars)
1314 /* 1253 /*
1315 * Make it possible to wakeup anything waiting for output 1254 * Make it possible to wakeup anything waiting for output
1316 * in tty_ioctl.c, etc. 1255 * in tty_ioctl.c, etc.
1317 */ 1256 */
1318 if (!(ch->statusflags & EMPTYWAIT)) 1257 set_bit(EMPTYWAIT, &ch->statusflags);
1319 moxa_setup_empty_event(tty);
1320 }
1321 unlock_kernel();
1322 return chars; 1258 return chars;
1323} 1259}
1324 1260
1325static int moxa_tiocmget(struct tty_struct *tty, struct file *file) 1261static int moxa_tiocmget(struct tty_struct *tty, struct file *file)
1326{ 1262{
1327 struct moxa_port *ch; 1263 struct moxa_port *ch = tty->driver_data;
1328 int flag = 0, dtr, rts; 1264 int flag = 0, dtr, rts;
1329 1265
1330 mutex_lock(&moxa_openlock);
1331 ch = tty->driver_data;
1332 if (!ch) {
1333 mutex_unlock(&moxa_openlock);
1334 return -EINVAL;
1335 }
1336
1337 MoxaPortGetLineOut(ch, &dtr, &rts); 1266 MoxaPortGetLineOut(ch, &dtr, &rts);
1338 if (dtr) 1267 if (dtr)
1339 flag |= TIOCM_DTR; 1268 flag |= TIOCM_DTR;
@@ -1346,7 +1275,6 @@ static int moxa_tiocmget(struct tty_struct *tty, struct file *file)
1346 flag |= TIOCM_DSR; 1275 flag |= TIOCM_DSR;
1347 if (dtr & 4) 1276 if (dtr & 4)
1348 flag |= TIOCM_CD; 1277 flag |= TIOCM_CD;
1349 mutex_unlock(&moxa_openlock);
1350 return flag; 1278 return flag;
1351} 1279}
1352 1280
@@ -1379,20 +1307,6 @@ static int moxa_tiocmset(struct tty_struct *tty, struct file *file,
1379 return 0; 1307 return 0;
1380} 1308}
1381 1309
1382static void moxa_throttle(struct tty_struct *tty)
1383{
1384 struct moxa_port *ch = tty->driver_data;
1385
1386 ch->statusflags |= THROTTLE;
1387}
1388
1389static void moxa_unthrottle(struct tty_struct *tty)
1390{
1391 struct moxa_port *ch = tty->driver_data;
1392
1393 ch->statusflags &= ~THROTTLE;
1394}
1395
1396static void moxa_set_termios(struct tty_struct *tty, 1310static void moxa_set_termios(struct tty_struct *tty,
1397 struct ktermios *old_termios) 1311 struct ktermios *old_termios)
1398{ 1312{
@@ -1412,7 +1326,7 @@ static void moxa_stop(struct tty_struct *tty)
1412 if (ch == NULL) 1326 if (ch == NULL)
1413 return; 1327 return;
1414 MoxaPortTxDisable(ch); 1328 MoxaPortTxDisable(ch);
1415 ch->statusflags |= TXSTOPPED; 1329 set_bit(TXSTOPPED, &ch->statusflags);
1416} 1330}
1417 1331
1418 1332
@@ -1427,38 +1341,32 @@ static void moxa_start(struct tty_struct *tty)
1427 return; 1341 return;
1428 1342
1429 MoxaPortTxEnable(ch); 1343 MoxaPortTxEnable(ch);
1430 ch->statusflags &= ~TXSTOPPED; 1344 clear_bit(TXSTOPPED, &ch->statusflags);
1431} 1345}
1432 1346
1433static void moxa_hangup(struct tty_struct *tty) 1347static void moxa_hangup(struct tty_struct *tty)
1434{ 1348{
1435 struct moxa_port *ch; 1349 struct moxa_port *ch = tty->driver_data;
1436 1350 tty_port_hangup(&ch->port);
1437 mutex_lock(&moxa_openlock);
1438 ch = tty->driver_data;
1439 if (ch == NULL) {
1440 mutex_unlock(&moxa_openlock);
1441 return;
1442 }
1443 ch->port.count = 0;
1444 moxa_close_port(tty);
1445 mutex_unlock(&moxa_openlock);
1446
1447 wake_up_interruptible(&ch->port.open_wait);
1448} 1351}
1449 1352
1450static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd) 1353static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd)
1451{ 1354{
1452 struct tty_struct *tty; 1355 struct tty_struct *tty;
1356 unsigned long flags;
1453 dcd = !!dcd; 1357 dcd = !!dcd;
1454 1358
1359 spin_lock_irqsave(&p->port.lock, flags);
1455 if (dcd != p->DCDState) { 1360 if (dcd != p->DCDState) {
1361 p->DCDState = dcd;
1362 spin_unlock_irqrestore(&p->port.lock, flags);
1456 tty = tty_port_tty_get(&p->port); 1363 tty = tty_port_tty_get(&p->port);
1457 if (tty && C_CLOCAL(tty) && !dcd) 1364 if (tty && C_CLOCAL(tty) && !dcd)
1458 tty_hangup(tty); 1365 tty_hangup(tty);
1459 tty_kref_put(tty); 1366 tty_kref_put(tty);
1460 } 1367 }
1461 p->DCDState = dcd; 1368 else
1369 spin_unlock_irqrestore(&p->port.lock, flags);
1462} 1370}
1463 1371
1464static int moxa_poll_port(struct moxa_port *p, unsigned int handle, 1372static int moxa_poll_port(struct moxa_port *p, unsigned int handle,
@@ -1470,24 +1378,24 @@ static int moxa_poll_port(struct moxa_port *p, unsigned int handle,
1470 u16 intr; 1378 u16 intr;
1471 1379
1472 if (tty) { 1380 if (tty) {
1473 if ((p->statusflags & EMPTYWAIT) && 1381 if (test_bit(EMPTYWAIT, &p->statusflags) &&
1474 MoxaPortTxQueue(p) == 0) { 1382 MoxaPortTxQueue(p) == 0) {
1475 p->statusflags &= ~EMPTYWAIT; 1383 clear_bit(EMPTYWAIT, &p->statusflags);
1476 tty_wakeup(tty); 1384 tty_wakeup(tty);
1477 } 1385 }
1478 if ((p->statusflags & LOWWAIT) && !tty->stopped && 1386 if (test_bit(LOWWAIT, &p->statusflags) && !tty->stopped &&
1479 MoxaPortTxQueue(p) <= WAKEUP_CHARS) { 1387 MoxaPortTxQueue(p) <= WAKEUP_CHARS) {
1480 p->statusflags &= ~LOWWAIT; 1388 clear_bit(LOWWAIT, &p->statusflags);
1481 tty_wakeup(tty); 1389 tty_wakeup(tty);
1482 } 1390 }
1483 1391
1484 if (inited && !(p->statusflags & THROTTLE) && 1392 if (inited && !test_bit(TTY_THROTTLED, &tty->flags) &&
1485 MoxaPortRxQueue(p) > 0) { /* RX */ 1393 MoxaPortRxQueue(p) > 0) { /* RX */
1486 MoxaPortReadData(p); 1394 MoxaPortReadData(p);
1487 tty_schedule_flip(tty); 1395 tty_schedule_flip(tty);
1488 } 1396 }
1489 } else { 1397 } else {
1490 p->statusflags &= ~EMPTYWAIT; 1398 clear_bit(EMPTYWAIT, &p->statusflags);
1491 MoxaPortFlushData(p, 0); /* flush RX */ 1399 MoxaPortFlushData(p, 0); /* flush RX */
1492 } 1400 }
1493 1401
@@ -1588,35 +1496,6 @@ static void moxa_set_tty_param(struct tty_struct *tty, struct ktermios *old_term
1588 tty_encode_baud_rate(tty, baud, baud); 1496 tty_encode_baud_rate(tty, baud, baud);
1589} 1497}
1590 1498
1591static void moxa_setup_empty_event(struct tty_struct *tty)
1592{
1593 struct moxa_port *ch = tty->driver_data;
1594
1595 spin_lock_bh(&moxa_lock);
1596 ch->statusflags |= EMPTYWAIT;
1597 spin_unlock_bh(&moxa_lock);
1598}
1599
1600static void moxa_shut_down(struct tty_struct *tty)
1601{
1602 struct moxa_port *ch = tty->driver_data;
1603
1604 if (!(ch->port.flags & ASYNC_INITIALIZED))
1605 return;
1606
1607 MoxaPortDisable(ch);
1608
1609 /*
1610 * If we're a modem control device and HUPCL is on, drop RTS & DTR.
1611 */
1612 if (C_HUPCL(tty))
1613 MoxaPortLineCtrl(ch, 0, 0);
1614
1615 spin_lock_bh(&moxa_lock);
1616 ch->port.flags &= ~ASYNC_INITIALIZED;
1617 spin_unlock_bh(&moxa_lock);
1618}
1619
1620/***************************************************************************** 1499/*****************************************************************************
1621 * Driver level functions: * 1500 * Driver level functions: *
1622 *****************************************************************************/ 1501 *****************************************************************************/
@@ -1918,10 +1797,12 @@ static int MoxaPortSetTermio(struct moxa_port *port, struct ktermios *termio,
1918 baud = MoxaPortSetBaud(port, baud); 1797 baud = MoxaPortSetBaud(port, baud);
1919 1798
1920 if (termio->c_iflag & (IXON | IXOFF | IXANY)) { 1799 if (termio->c_iflag & (IXON | IXOFF | IXANY)) {
1800 spin_lock_irq(&moxafunc_lock);
1921 writeb(termio->c_cc[VSTART], ofsAddr + FuncArg); 1801 writeb(termio->c_cc[VSTART], ofsAddr + FuncArg);
1922 writeb(termio->c_cc[VSTOP], ofsAddr + FuncArg1); 1802 writeb(termio->c_cc[VSTOP], ofsAddr + FuncArg1);
1923 writeb(FC_SetXonXoff, ofsAddr + FuncCode); 1803 writeb(FC_SetXonXoff, ofsAddr + FuncCode);
1924 moxa_wait_finish(ofsAddr); 1804 moxa_wait_finish(ofsAddr);
1805 spin_unlock_irq(&moxafunc_lock);
1925 1806
1926 } 1807 }
1927 return baud; 1808 return baud;
@@ -1974,18 +1855,14 @@ static int MoxaPortLineStatus(struct moxa_port *port)
1974 int val; 1855 int val;
1975 1856
1976 ofsAddr = port->tableAddr; 1857 ofsAddr = port->tableAddr;
1977 if (MOXA_IS_320(port->board)) { 1858 if (MOXA_IS_320(port->board))
1978 moxafunc(ofsAddr, FC_LineStatus, 0); 1859 val = moxafuncret(ofsAddr, FC_LineStatus, 0);
1979 val = readw(ofsAddr + FuncArg); 1860 else
1980 } else {
1981 val = readw(ofsAddr + FlagStat) >> 4; 1861 val = readw(ofsAddr + FlagStat) >> 4;
1982 }
1983 val &= 0x0B; 1862 val &= 0x0B;
1984 if (val & 8) 1863 if (val & 8)
1985 val |= 4; 1864 val |= 4;
1986 spin_lock_bh(&moxa_lock);
1987 moxa_new_dcdstate(port, val & 8); 1865 moxa_new_dcdstate(port, val & 8);
1988 spin_unlock_bh(&moxa_lock);
1989 val &= 7; 1866 val &= 7;
1990 return val; 1867 return val;
1991} 1868}