aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/moxa.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/moxa.c')
-rw-r--r--drivers/char/moxa.c310
1 files changed, 93 insertions, 217 deletions
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index dd0083bbb64a..107b0bd58d19 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>
@@ -44,6 +43,7 @@
44#include <linux/pci.h> 43#include <linux/pci.h>
45#include <linux/init.h> 44#include <linux/init.h>
46#include <linux/bitops.h> 45#include <linux/bitops.h>
46#include <linux/slab.h>
47 47
48#include <asm/system.h> 48#include <asm/system.h>
49#include <asm/io.h> 49#include <asm/io.h>
@@ -139,7 +139,7 @@ struct moxa_port {
139 int cflag; 139 int cflag;
140 unsigned long statusflags; 140 unsigned long statusflags;
141 141
142 u8 DCDState; 142 u8 DCDState; /* Protected by the port lock */
143 u8 lineCtrl; 143 u8 lineCtrl;
144 u8 lowChkFlag; 144 u8 lowChkFlag;
145}; 145};
@@ -151,10 +151,9 @@ struct mon_str {
151}; 151};
152 152
153/* statusflags */ 153/* statusflags */
154#define TXSTOPPED 0x1 154#define TXSTOPPED 1
155#define LOWWAIT 0x2 155#define LOWWAIT 2
156#define EMPTYWAIT 0x4 156#define EMPTYWAIT 3
157#define THROTTLE 0x8
158 157
159#define SERIAL_DO_RESTART 158#define SERIAL_DO_RESTART
160 159
@@ -165,24 +164,26 @@ static struct mon_str moxaLog;
165static unsigned int moxaFuncTout = HZ / 2; 164static unsigned int moxaFuncTout = HZ / 2;
166static unsigned int moxaLowWaterChk; 165static unsigned int moxaLowWaterChk;
167static DEFINE_MUTEX(moxa_openlock); 166static DEFINE_MUTEX(moxa_openlock);
168/* Variables for insmod */ 167static DEFINE_SPINLOCK(moxa_lock);
169#ifdef MODULE 168
170static unsigned long baseaddr[MAX_BOARDS]; 169static unsigned long baseaddr[MAX_BOARDS];
171static unsigned int type[MAX_BOARDS]; 170static unsigned int type[MAX_BOARDS];
172static unsigned int numports[MAX_BOARDS]; 171static unsigned int numports[MAX_BOARDS];
173#endif
174 172
175MODULE_AUTHOR("William Chen"); 173MODULE_AUTHOR("William Chen");
176MODULE_DESCRIPTION("MOXA Intellio Family Multiport Board Device Driver"); 174MODULE_DESCRIPTION("MOXA Intellio Family Multiport Board Device Driver");
177MODULE_LICENSE("GPL"); 175MODULE_LICENSE("GPL");
178#ifdef MODULE 176MODULE_FIRMWARE("c218tunx.cod");
177MODULE_FIRMWARE("cp204unx.cod");
178MODULE_FIRMWARE("c320tunx.cod");
179
179module_param_array(type, uint, NULL, 0); 180module_param_array(type, uint, NULL, 0);
180MODULE_PARM_DESC(type, "card type: C218=2, C320=4"); 181MODULE_PARM_DESC(type, "card type: C218=2, C320=4");
181module_param_array(baseaddr, ulong, NULL, 0); 182module_param_array(baseaddr, ulong, NULL, 0);
182MODULE_PARM_DESC(baseaddr, "base address"); 183MODULE_PARM_DESC(baseaddr, "base address");
183module_param_array(numports, uint, NULL, 0); 184module_param_array(numports, uint, NULL, 0);
184MODULE_PARM_DESC(numports, "numports (ignored for C218)"); 185MODULE_PARM_DESC(numports, "numports (ignored for C218)");
185#endif 186
186module_param(ttymajor, int, 0); 187module_param(ttymajor, int, 0);
187 188
188/* 189/*
@@ -194,8 +195,6 @@ static int moxa_write(struct tty_struct *, const unsigned char *, int);
194static int moxa_write_room(struct tty_struct *); 195static int moxa_write_room(struct tty_struct *);
195static void moxa_flush_buffer(struct tty_struct *); 196static void moxa_flush_buffer(struct tty_struct *);
196static int moxa_chars_in_buffer(struct tty_struct *); 197static 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 *); 198static void moxa_set_termios(struct tty_struct *, struct ktermios *);
200static void moxa_stop(struct tty_struct *); 199static void moxa_stop(struct tty_struct *);
201static void moxa_start(struct tty_struct *); 200static void moxa_start(struct tty_struct *);
@@ -205,9 +204,9 @@ static int moxa_tiocmset(struct tty_struct *tty, struct file *file,
205 unsigned int set, unsigned int clear); 204 unsigned int set, unsigned int clear);
206static void moxa_poll(unsigned long); 205static void moxa_poll(unsigned long);
207static void moxa_set_tty_param(struct tty_struct *, struct ktermios *); 206static void moxa_set_tty_param(struct tty_struct *, struct ktermios *);
208static void moxa_setup_empty_event(struct tty_struct *); 207static void moxa_shutdown(struct tty_port *);
209static void moxa_shut_down(struct tty_struct *);
210static int moxa_carrier_raised(struct tty_port *); 208static int moxa_carrier_raised(struct tty_port *);
209static void moxa_dtr_rts(struct tty_port *, int);
211/* 210/*
212 * moxa board interface functions: 211 * moxa board interface functions:
213 */ 212 */
@@ -234,6 +233,8 @@ static void MoxaSetFifo(struct moxa_port *port, int enable);
234 * I/O functions 233 * I/O functions
235 */ 234 */
236 235
236static DEFINE_SPINLOCK(moxafunc_lock);
237
237static void moxa_wait_finish(void __iomem *ofsAddr) 238static void moxa_wait_finish(void __iomem *ofsAddr)
238{ 239{
239 unsigned long end = jiffies + moxaFuncTout; 240 unsigned long end = jiffies + moxaFuncTout;
@@ -247,9 +248,25 @@ static void moxa_wait_finish(void __iomem *ofsAddr)
247 248
248static void moxafunc(void __iomem *ofsAddr, u16 cmd, u16 arg) 249static void moxafunc(void __iomem *ofsAddr, u16 cmd, u16 arg)
249{ 250{
251 unsigned long flags;
252 spin_lock_irqsave(&moxafunc_lock, flags);
250 writew(arg, ofsAddr + FuncArg); 253 writew(arg, ofsAddr + FuncArg);
251 writew(cmd, ofsAddr + FuncCode); 254 writew(cmd, ofsAddr + FuncCode);
252 moxa_wait_finish(ofsAddr); 255 moxa_wait_finish(ofsAddr);
256 spin_unlock_irqrestore(&moxafunc_lock, flags);
257}
258
259static int moxafuncret(void __iomem *ofsAddr, u16 cmd, u16 arg)
260{
261 unsigned long flags;
262 u16 ret;
263 spin_lock_irqsave(&moxafunc_lock, flags);
264 writew(arg, ofsAddr + FuncArg);
265 writew(cmd, ofsAddr + FuncCode);
266 moxa_wait_finish(ofsAddr);
267 ret = readw(ofsAddr + FuncArg);
268 spin_unlock_irqrestore(&moxafunc_lock, flags);
269 return ret;
253} 270}
254 271
255static void moxa_low_water_check(void __iomem *ofsAddr) 272static void moxa_low_water_check(void __iomem *ofsAddr)
@@ -299,22 +316,20 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
299 struct moxa_port *p; 316 struct moxa_port *p;
300 unsigned int i, j; 317 unsigned int i, j;
301 318
302 mutex_lock(&moxa_openlock);
303 for (i = 0; i < MAX_BOARDS; i++) { 319 for (i = 0; i < MAX_BOARDS; i++) {
304 p = moxa_boards[i].ports; 320 p = moxa_boards[i].ports;
305 for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) { 321 for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) {
306 memset(&tmp, 0, sizeof(tmp)); 322 memset(&tmp, 0, sizeof(tmp));
323 spin_lock_bh(&moxa_lock);
307 if (moxa_boards[i].ready) { 324 if (moxa_boards[i].ready) {
308 tmp.inq = MoxaPortRxQueue(p); 325 tmp.inq = MoxaPortRxQueue(p);
309 tmp.outq = MoxaPortTxQueue(p); 326 tmp.outq = MoxaPortTxQueue(p);
310 } 327 }
311 if (copy_to_user(argm, &tmp, sizeof(tmp))) { 328 spin_unlock_bh(&moxa_lock);
312 mutex_unlock(&moxa_openlock); 329 if (copy_to_user(argm, &tmp, sizeof(tmp)))
313 return -EFAULT; 330 return -EFAULT;
314 }
315 } 331 }
316 } 332 }
317 mutex_unlock(&moxa_openlock);
318 break; 333 break;
319 } case MOXA_GET_OQUEUE: 334 } case MOXA_GET_OQUEUE:
320 status = MoxaPortTxQueue(ch); 335 status = MoxaPortTxQueue(ch);
@@ -330,16 +345,20 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
330 struct moxa_port *p; 345 struct moxa_port *p;
331 unsigned int i, j; 346 unsigned int i, j;
332 347
333 mutex_lock(&moxa_openlock);
334 for (i = 0; i < MAX_BOARDS; i++) { 348 for (i = 0; i < MAX_BOARDS; i++) {
335 p = moxa_boards[i].ports; 349 p = moxa_boards[i].ports;
336 for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) { 350 for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) {
337 struct tty_struct *ttyp; 351 struct tty_struct *ttyp;
338 memset(&tmp, 0, sizeof(tmp)); 352 memset(&tmp, 0, sizeof(tmp));
339 if (!moxa_boards[i].ready) 353 spin_lock_bh(&moxa_lock);
354 if (!moxa_boards[i].ready) {
355 spin_unlock_bh(&moxa_lock);
340 goto copy; 356 goto copy;
357 }
341 358
342 status = MoxaPortLineStatus(p); 359 status = MoxaPortLineStatus(p);
360 spin_unlock_bh(&moxa_lock);
361
343 if (status & 1) 362 if (status & 1)
344 tmp.cts = 1; 363 tmp.cts = 1;
345 if (status & 2) 364 if (status & 2)
@@ -354,24 +373,21 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
354 tmp.cflag = ttyp->termios->c_cflag; 373 tmp.cflag = ttyp->termios->c_cflag;
355 tty_kref_put(tty); 374 tty_kref_put(tty);
356copy: 375copy:
357 if (copy_to_user(argm, &tmp, sizeof(tmp))) { 376 if (copy_to_user(argm, &tmp, sizeof(tmp)))
358 mutex_unlock(&moxa_openlock);
359 return -EFAULT; 377 return -EFAULT;
360 }
361 } 378 }
362 } 379 }
363 mutex_unlock(&moxa_openlock);
364 break; 380 break;
365 } 381 }
366 case TIOCGSERIAL: 382 case TIOCGSERIAL:
367 mutex_lock(&moxa_openlock); 383 mutex_lock(&ch->port.mutex);
368 ret = moxa_get_serial_info(ch, argp); 384 ret = moxa_get_serial_info(ch, argp);
369 mutex_unlock(&moxa_openlock); 385 mutex_unlock(&ch->port.mutex);
370 break; 386 break;
371 case TIOCSSERIAL: 387 case TIOCSSERIAL:
372 mutex_lock(&moxa_openlock); 388 mutex_lock(&ch->port.mutex);
373 ret = moxa_set_serial_info(ch, argp); 389 ret = moxa_set_serial_info(ch, argp);
374 mutex_unlock(&moxa_openlock); 390 mutex_unlock(&ch->port.mutex);
375 break; 391 break;
376 default: 392 default:
377 ret = -ENOIOCTLCMD; 393 ret = -ENOIOCTLCMD;
@@ -396,8 +412,6 @@ static const struct tty_operations moxa_ops = {
396 .flush_buffer = moxa_flush_buffer, 412 .flush_buffer = moxa_flush_buffer,
397 .chars_in_buffer = moxa_chars_in_buffer, 413 .chars_in_buffer = moxa_chars_in_buffer,
398 .ioctl = moxa_ioctl, 414 .ioctl = moxa_ioctl,
399 .throttle = moxa_throttle,
400 .unthrottle = moxa_unthrottle,
401 .set_termios = moxa_set_termios, 415 .set_termios = moxa_set_termios,
402 .stop = moxa_stop, 416 .stop = moxa_stop,
403 .start = moxa_start, 417 .start = moxa_start,
@@ -409,11 +423,12 @@ static const struct tty_operations moxa_ops = {
409 423
410static const struct tty_port_operations moxa_port_ops = { 424static const struct tty_port_operations moxa_port_ops = {
411 .carrier_raised = moxa_carrier_raised, 425 .carrier_raised = moxa_carrier_raised,
426 .dtr_rts = moxa_dtr_rts,
427 .shutdown = moxa_shutdown,
412}; 428};
413 429
414static struct tty_driver *moxaDriver; 430static struct tty_driver *moxaDriver;
415static DEFINE_TIMER(moxaTimer, moxa_poll, 0, 0); 431static DEFINE_TIMER(moxaTimer, moxa_poll, 0, 0);
416static DEFINE_SPINLOCK(moxa_lock);
417 432
418/* 433/*
419 * HW init 434 * HW init
@@ -1011,6 +1026,8 @@ static int __init moxa_init(void)
1011{ 1026{
1012 unsigned int isabrds = 0; 1027 unsigned int isabrds = 0;
1013 int retval = 0; 1028 int retval = 0;
1029 struct moxa_board_conf *brd = moxa_boards;
1030 unsigned int i;
1014 1031
1015 printk(KERN_INFO "MOXA Intellio family driver version %s\n", 1032 printk(KERN_INFO "MOXA Intellio family driver version %s\n",
1016 MOXA_VERSION); 1033 MOXA_VERSION);
@@ -1038,10 +1055,7 @@ static int __init moxa_init(void)
1038 } 1055 }
1039 1056
1040 /* Find the boards defined from module args. */ 1057 /* Find the boards defined from module args. */
1041#ifdef MODULE 1058
1042 {
1043 struct moxa_board_conf *brd = moxa_boards;
1044 unsigned int i;
1045 for (i = 0; i < MAX_BOARDS; i++) { 1059 for (i = 0; i < MAX_BOARDS; i++) {
1046 if (!baseaddr[i]) 1060 if (!baseaddr[i])
1047 break; 1061 break;
@@ -1074,8 +1088,6 @@ static int __init moxa_init(void)
1074 isabrds++; 1088 isabrds++;
1075 } 1089 }
1076 } 1090 }
1077 }
1078#endif
1079 1091
1080#ifdef CONFIG_PCI 1092#ifdef CONFIG_PCI
1081 retval = pci_register_driver(&moxa_pci_driver); 1093 retval = pci_register_driver(&moxa_pci_driver);
@@ -1112,14 +1124,12 @@ static void __exit moxa_exit(void)
1112module_init(moxa_init); 1124module_init(moxa_init);
1113module_exit(moxa_exit); 1125module_exit(moxa_exit);
1114 1126
1115static void moxa_close_port(struct tty_struct *tty) 1127static void moxa_shutdown(struct tty_port *port)
1116{ 1128{
1117 struct moxa_port *ch = tty->driver_data; 1129 struct moxa_port *ch = container_of(port, struct moxa_port, port);
1118 moxa_shut_down(tty); 1130 MoxaPortDisable(ch);
1119 MoxaPortFlushData(ch, 2); 1131 MoxaPortFlushData(ch, 2);
1120 ch->port.flags &= ~ASYNC_NORMAL_ACTIVE; 1132 clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags);
1121 tty->driver_data = NULL;
1122 tty_port_tty_set(&ch->port, NULL);
1123} 1133}
1124 1134
1125static int moxa_carrier_raised(struct tty_port *port) 1135static int moxa_carrier_raised(struct tty_port *port)
@@ -1127,45 +1137,19 @@ static int moxa_carrier_raised(struct tty_port *port)
1127 struct moxa_port *ch = container_of(port, struct moxa_port, port); 1137 struct moxa_port *ch = container_of(port, struct moxa_port, port);
1128 int dcd; 1138 int dcd;
1129 1139
1130 spin_lock_bh(&moxa_lock); 1140 spin_lock_irq(&port->lock);
1131 dcd = ch->DCDState; 1141 dcd = ch->DCDState;
1132 spin_unlock_bh(&moxa_lock); 1142 spin_unlock_irq(&port->lock);
1133 return dcd; 1143 return dcd;
1134} 1144}
1135 1145
1136static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp, 1146static void moxa_dtr_rts(struct tty_port *port, int onoff)
1137 struct moxa_port *ch)
1138{ 1147{
1139 struct tty_port *port = &ch->port; 1148 struct moxa_port *ch = container_of(port, struct moxa_port, port);
1140 DEFINE_WAIT(wait); 1149 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} 1150}
1168 1151
1152
1169static int moxa_open(struct tty_struct *tty, struct file *filp) 1153static int moxa_open(struct tty_struct *tty, struct file *filp)
1170{ 1154{
1171 struct moxa_board_conf *brd; 1155 struct moxa_board_conf *brd;
@@ -1194,6 +1178,7 @@ static int moxa_open(struct tty_struct *tty, struct file *filp)
1194 ch->port.count++; 1178 ch->port.count++;
1195 tty->driver_data = ch; 1179 tty->driver_data = ch;
1196 tty_port_tty_set(&ch->port, tty); 1180 tty_port_tty_set(&ch->port, tty);
1181 mutex_lock(&ch->port.mutex);
1197 if (!(ch->port.flags & ASYNC_INITIALIZED)) { 1182 if (!(ch->port.flags & ASYNC_INITIALIZED)) {
1198 ch->statusflags = 0; 1183 ch->statusflags = 0;
1199 moxa_set_tty_param(tty, tty->termios); 1184 moxa_set_tty_param(tty, tty->termios);
@@ -1202,58 +1187,20 @@ static int moxa_open(struct tty_struct *tty, struct file *filp)
1202 MoxaSetFifo(ch, ch->type == PORT_16550A); 1187 MoxaSetFifo(ch, ch->type == PORT_16550A);
1203 ch->port.flags |= ASYNC_INITIALIZED; 1188 ch->port.flags |= ASYNC_INITIALIZED;
1204 } 1189 }
1190 mutex_unlock(&ch->port.mutex);
1205 mutex_unlock(&moxa_openlock); 1191 mutex_unlock(&moxa_openlock);
1206 1192
1207 retval = 0; 1193 retval = tty_port_block_til_ready(&ch->port, tty, filp);
1208 if (!(filp->f_flags & O_NONBLOCK) && !C_CLOCAL(tty)) 1194 if (retval == 0)
1209 retval = moxa_block_till_ready(tty, filp, ch); 1195 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; 1196 return retval;
1220} 1197}
1221 1198
1222static void moxa_close(struct tty_struct *tty, struct file *filp) 1199static void moxa_close(struct tty_struct *tty, struct file *filp)
1223{ 1200{
1224 struct moxa_port *ch; 1201 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; 1202 ch->cflag = tty->termios->c_cflag;
1249 if (ch->port.flags & ASYNC_INITIALIZED) { 1203 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} 1204}
1258 1205
1259static int moxa_write(struct tty_struct *tty, 1206static int moxa_write(struct tty_struct *tty,
@@ -1269,7 +1216,7 @@ static int moxa_write(struct tty_struct *tty,
1269 len = MoxaPortWriteData(tty, buf, count); 1216 len = MoxaPortWriteData(tty, buf, count);
1270 spin_unlock_bh(&moxa_lock); 1217 spin_unlock_bh(&moxa_lock);
1271 1218
1272 ch->statusflags |= LOWWAIT; 1219 set_bit(LOWWAIT, &ch->statusflags);
1273 return len; 1220 return len;
1274} 1221}
1275 1222
@@ -1300,40 +1247,21 @@ static int moxa_chars_in_buffer(struct tty_struct *tty)
1300 struct moxa_port *ch = tty->driver_data; 1247 struct moxa_port *ch = tty->driver_data;
1301 int chars; 1248 int chars;
1302 1249
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); 1250 chars = MoxaPortTxQueue(ch);
1313 if (chars) { 1251 if (chars)
1314 /* 1252 /*
1315 * Make it possible to wakeup anything waiting for output 1253 * Make it possible to wakeup anything waiting for output
1316 * in tty_ioctl.c, etc. 1254 * in tty_ioctl.c, etc.
1317 */ 1255 */
1318 if (!(ch->statusflags & EMPTYWAIT)) 1256 set_bit(EMPTYWAIT, &ch->statusflags);
1319 moxa_setup_empty_event(tty);
1320 }
1321 unlock_kernel();
1322 return chars; 1257 return chars;
1323} 1258}
1324 1259
1325static int moxa_tiocmget(struct tty_struct *tty, struct file *file) 1260static int moxa_tiocmget(struct tty_struct *tty, struct file *file)
1326{ 1261{
1327 struct moxa_port *ch; 1262 struct moxa_port *ch = tty->driver_data;
1328 int flag = 0, dtr, rts; 1263 int flag = 0, dtr, rts;
1329 1264
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); 1265 MoxaPortGetLineOut(ch, &dtr, &rts);
1338 if (dtr) 1266 if (dtr)
1339 flag |= TIOCM_DTR; 1267 flag |= TIOCM_DTR;
@@ -1346,7 +1274,6 @@ static int moxa_tiocmget(struct tty_struct *tty, struct file *file)
1346 flag |= TIOCM_DSR; 1274 flag |= TIOCM_DSR;
1347 if (dtr & 4) 1275 if (dtr & 4)
1348 flag |= TIOCM_CD; 1276 flag |= TIOCM_CD;
1349 mutex_unlock(&moxa_openlock);
1350 return flag; 1277 return flag;
1351} 1278}
1352 1279
@@ -1379,20 +1306,6 @@ static int moxa_tiocmset(struct tty_struct *tty, struct file *file,
1379 return 0; 1306 return 0;
1380} 1307}
1381 1308
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, 1309static void moxa_set_termios(struct tty_struct *tty,
1397 struct ktermios *old_termios) 1310 struct ktermios *old_termios)
1398{ 1311{
@@ -1412,7 +1325,7 @@ static void moxa_stop(struct tty_struct *tty)
1412 if (ch == NULL) 1325 if (ch == NULL)
1413 return; 1326 return;
1414 MoxaPortTxDisable(ch); 1327 MoxaPortTxDisable(ch);
1415 ch->statusflags |= TXSTOPPED; 1328 set_bit(TXSTOPPED, &ch->statusflags);
1416} 1329}
1417 1330
1418 1331
@@ -1427,38 +1340,32 @@ static void moxa_start(struct tty_struct *tty)
1427 return; 1340 return;
1428 1341
1429 MoxaPortTxEnable(ch); 1342 MoxaPortTxEnable(ch);
1430 ch->statusflags &= ~TXSTOPPED; 1343 clear_bit(TXSTOPPED, &ch->statusflags);
1431} 1344}
1432 1345
1433static void moxa_hangup(struct tty_struct *tty) 1346static void moxa_hangup(struct tty_struct *tty)
1434{ 1347{
1435 struct moxa_port *ch; 1348 struct moxa_port *ch = tty->driver_data;
1436 1349 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} 1350}
1449 1351
1450static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd) 1352static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd)
1451{ 1353{
1452 struct tty_struct *tty; 1354 struct tty_struct *tty;
1355 unsigned long flags;
1453 dcd = !!dcd; 1356 dcd = !!dcd;
1454 1357
1358 spin_lock_irqsave(&p->port.lock, flags);
1455 if (dcd != p->DCDState) { 1359 if (dcd != p->DCDState) {
1360 p->DCDState = dcd;
1361 spin_unlock_irqrestore(&p->port.lock, flags);
1456 tty = tty_port_tty_get(&p->port); 1362 tty = tty_port_tty_get(&p->port);
1457 if (tty && C_CLOCAL(tty) && !dcd) 1363 if (tty && C_CLOCAL(tty) && !dcd)
1458 tty_hangup(tty); 1364 tty_hangup(tty);
1459 tty_kref_put(tty); 1365 tty_kref_put(tty);
1460 } 1366 }
1461 p->DCDState = dcd; 1367 else
1368 spin_unlock_irqrestore(&p->port.lock, flags);
1462} 1369}
1463 1370
1464static int moxa_poll_port(struct moxa_port *p, unsigned int handle, 1371static int moxa_poll_port(struct moxa_port *p, unsigned int handle,
@@ -1470,24 +1377,24 @@ static int moxa_poll_port(struct moxa_port *p, unsigned int handle,
1470 u16 intr; 1377 u16 intr;
1471 1378
1472 if (tty) { 1379 if (tty) {
1473 if ((p->statusflags & EMPTYWAIT) && 1380 if (test_bit(EMPTYWAIT, &p->statusflags) &&
1474 MoxaPortTxQueue(p) == 0) { 1381 MoxaPortTxQueue(p) == 0) {
1475 p->statusflags &= ~EMPTYWAIT; 1382 clear_bit(EMPTYWAIT, &p->statusflags);
1476 tty_wakeup(tty); 1383 tty_wakeup(tty);
1477 } 1384 }
1478 if ((p->statusflags & LOWWAIT) && !tty->stopped && 1385 if (test_bit(LOWWAIT, &p->statusflags) && !tty->stopped &&
1479 MoxaPortTxQueue(p) <= WAKEUP_CHARS) { 1386 MoxaPortTxQueue(p) <= WAKEUP_CHARS) {
1480 p->statusflags &= ~LOWWAIT; 1387 clear_bit(LOWWAIT, &p->statusflags);
1481 tty_wakeup(tty); 1388 tty_wakeup(tty);
1482 } 1389 }
1483 1390
1484 if (inited && !(p->statusflags & THROTTLE) && 1391 if (inited && !test_bit(TTY_THROTTLED, &tty->flags) &&
1485 MoxaPortRxQueue(p) > 0) { /* RX */ 1392 MoxaPortRxQueue(p) > 0) { /* RX */
1486 MoxaPortReadData(p); 1393 MoxaPortReadData(p);
1487 tty_schedule_flip(tty); 1394 tty_schedule_flip(tty);
1488 } 1395 }
1489 } else { 1396 } else {
1490 p->statusflags &= ~EMPTYWAIT; 1397 clear_bit(EMPTYWAIT, &p->statusflags);
1491 MoxaPortFlushData(p, 0); /* flush RX */ 1398 MoxaPortFlushData(p, 0); /* flush RX */
1492 } 1399 }
1493 1400
@@ -1588,35 +1495,6 @@ static void moxa_set_tty_param(struct tty_struct *tty, struct ktermios *old_term
1588 tty_encode_baud_rate(tty, baud, baud); 1495 tty_encode_baud_rate(tty, baud, baud);
1589} 1496}
1590 1497
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/***************************************************************************** 1498/*****************************************************************************
1621 * Driver level functions: * 1499 * Driver level functions: *
1622 *****************************************************************************/ 1500 *****************************************************************************/
@@ -1918,10 +1796,12 @@ static int MoxaPortSetTermio(struct moxa_port *port, struct ktermios *termio,
1918 baud = MoxaPortSetBaud(port, baud); 1796 baud = MoxaPortSetBaud(port, baud);
1919 1797
1920 if (termio->c_iflag & (IXON | IXOFF | IXANY)) { 1798 if (termio->c_iflag & (IXON | IXOFF | IXANY)) {
1799 spin_lock_irq(&moxafunc_lock);
1921 writeb(termio->c_cc[VSTART], ofsAddr + FuncArg); 1800 writeb(termio->c_cc[VSTART], ofsAddr + FuncArg);
1922 writeb(termio->c_cc[VSTOP], ofsAddr + FuncArg1); 1801 writeb(termio->c_cc[VSTOP], ofsAddr + FuncArg1);
1923 writeb(FC_SetXonXoff, ofsAddr + FuncCode); 1802 writeb(FC_SetXonXoff, ofsAddr + FuncCode);
1924 moxa_wait_finish(ofsAddr); 1803 moxa_wait_finish(ofsAddr);
1804 spin_unlock_irq(&moxafunc_lock);
1925 1805
1926 } 1806 }
1927 return baud; 1807 return baud;
@@ -1974,18 +1854,14 @@ static int MoxaPortLineStatus(struct moxa_port *port)
1974 int val; 1854 int val;
1975 1855
1976 ofsAddr = port->tableAddr; 1856 ofsAddr = port->tableAddr;
1977 if (MOXA_IS_320(port->board)) { 1857 if (MOXA_IS_320(port->board))
1978 moxafunc(ofsAddr, FC_LineStatus, 0); 1858 val = moxafuncret(ofsAddr, FC_LineStatus, 0);
1979 val = readw(ofsAddr + FuncArg); 1859 else
1980 } else {
1981 val = readw(ofsAddr + FlagStat) >> 4; 1860 val = readw(ofsAddr + FlagStat) >> 4;
1982 }
1983 val &= 0x0B; 1861 val &= 0x0B;
1984 if (val & 8) 1862 if (val & 8)
1985 val |= 4; 1863 val |= 4;
1986 spin_lock_bh(&moxa_lock);
1987 moxa_new_dcdstate(port, val & 8); 1864 moxa_new_dcdstate(port, val & 8);
1988 spin_unlock_bh(&moxa_lock);
1989 val &= 7; 1865 val &= 7;
1990 return val; 1866 return val;
1991} 1867}