aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Slaby <jirislaby@gmail.com>2008-04-30 03:53:45 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-30 11:29:43 -0400
commita8f5cda067e2eeefe49fe386caf0f61fc5c825e0 (patch)
tree980c91f37b242ae9e6d7efa6cbb62f8550f3359c
parent2a5413416b6b2fd8a5a38601a4fe3b56a52cfb86 (diff)
Char: moxa, rework open/close
- add locking to open/close/hangup and ioctl (tiocm) - add pci hot-un-plug support (hangup on board remove, wait for openers) - cleanup block_till_ready - move close code common to close/hangup into separate function to be able to call it from open when hangup occurs while block_till_ready - let ldisc flush on tty layer, it will do it after we return Signed-off-by: Jiri Slaby <jirislaby@gmail.com> Tested-by: Oyvind Aabling <Oyvind.Aabling@uni-c.dk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/char/moxa.c320
1 files changed, 158 insertions, 162 deletions
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index abcc16eba44f..af8077c25cbe 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -42,7 +42,6 @@
42#include <linux/pci.h> 42#include <linux/pci.h>
43#include <linux/init.h> 43#include <linux/init.h>
44#include <linux/bitops.h> 44#include <linux/bitops.h>
45#include <linux/completion.h>
46 45
47#include <asm/system.h> 46#include <asm/system.h>
48#include <asm/io.h> 47#include <asm/io.h>
@@ -134,13 +133,11 @@ struct moxa_port {
134 133
135 int type; 134 int type;
136 int close_delay; 135 int close_delay;
137 int count; 136 unsigned int count;
138 int blocked_open;
139 int asyncflags; 137 int asyncflags;
140 int cflag; 138 int cflag;
141 unsigned long statusflags; 139 unsigned long statusflags;
142 wait_queue_head_t open_wait; 140 wait_queue_head_t open_wait;
143 struct completion close_wait;
144 141
145 u8 DCDState; 142 u8 DCDState;
146 u8 lineCtrl; 143 u8 lineCtrl;
@@ -167,6 +164,7 @@ static int ttymajor = MOXAMAJOR;
167static struct mon_str moxaLog; 164static struct mon_str moxaLog;
168static unsigned int moxaFuncTout = HZ / 2; 165static unsigned int moxaFuncTout = HZ / 2;
169static unsigned int moxaLowWaterChk; 166static unsigned int moxaLowWaterChk;
167static DEFINE_MUTEX(moxa_openlock);
170/* Variables for insmod */ 168/* Variables for insmod */
171#ifdef MODULE 169#ifdef MODULE
172static unsigned long baseaddr[MAX_BOARDS]; 170static unsigned long baseaddr[MAX_BOARDS];
@@ -209,8 +207,6 @@ static int moxa_tiocmset(struct tty_struct *tty, struct file *file,
209 unsigned int set, unsigned int clear); 207 unsigned int set, unsigned int clear);
210static void moxa_poll(unsigned long); 208static void moxa_poll(unsigned long);
211static void moxa_set_tty_param(struct tty_struct *, struct ktermios *); 209static void moxa_set_tty_param(struct tty_struct *, struct ktermios *);
212static int moxa_block_till_ready(struct tty_struct *, struct file *,
213 struct moxa_port *);
214static void moxa_setup_empty_event(struct tty_struct *); 210static void moxa_setup_empty_event(struct tty_struct *);
215static void moxa_shut_down(struct moxa_port *); 211static void moxa_shut_down(struct moxa_port *);
216/* 212/*
@@ -280,7 +276,7 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
280{ 276{
281 struct moxa_port *ch = tty->driver_data; 277 struct moxa_port *ch = tty->driver_data;
282 void __user *argp = (void __user *)arg; 278 void __user *argp = (void __user *)arg;
283 int status; 279 int status, ret = 0;
284 280
285 if (tty->index == MAX_PORTS) { 281 if (tty->index == MAX_PORTS) {
286 if (cmd != MOXA_GETDATACOUNT && cmd != MOXA_GET_IOQUEUE && 282 if (cmd != MOXA_GETDATACOUNT && cmd != MOXA_GET_IOQUEUE &&
@@ -292,17 +288,19 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
292 switch (cmd) { 288 switch (cmd) {
293 case MOXA_GETDATACOUNT: 289 case MOXA_GETDATACOUNT:
294 moxaLog.tick = jiffies; 290 moxaLog.tick = jiffies;
295 return copy_to_user(argp, &moxaLog, sizeof(moxaLog)) ? 291 if (copy_to_user(argp, &moxaLog, sizeof(moxaLog)))
296 -EFAULT : 0; 292 ret = -EFAULT;
293 break;
297 case MOXA_FLUSH_QUEUE: 294 case MOXA_FLUSH_QUEUE:
298 MoxaPortFlushData(ch, arg); 295 MoxaPortFlushData(ch, arg);
299 return 0; 296 break;
300 case MOXA_GET_IOQUEUE: { 297 case MOXA_GET_IOQUEUE: {
301 struct moxaq_str __user *argm = argp; 298 struct moxaq_str __user *argm = argp;
302 struct moxaq_str tmp; 299 struct moxaq_str tmp;
303 struct moxa_port *p; 300 struct moxa_port *p;
304 unsigned int i, j; 301 unsigned int i, j;
305 302
303 mutex_lock(&moxa_openlock);
306 for (i = 0; i < MAX_BOARDS; i++) { 304 for (i = 0; i < MAX_BOARDS; i++) {
307 p = moxa_boards[i].ports; 305 p = moxa_boards[i].ports;
308 for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) { 306 for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) {
@@ -311,23 +309,29 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
311 tmp.inq = MoxaPortRxQueue(p); 309 tmp.inq = MoxaPortRxQueue(p);
312 tmp.outq = MoxaPortTxQueue(p); 310 tmp.outq = MoxaPortTxQueue(p);
313 } 311 }
314 if (copy_to_user(argm, &tmp, sizeof(tmp))) 312 if (copy_to_user(argm, &tmp, sizeof(tmp))) {
313 mutex_unlock(&moxa_openlock);
315 return -EFAULT; 314 return -EFAULT;
315 }
316 } 316 }
317 } 317 }
318 return 0; 318 mutex_unlock(&moxa_openlock);
319 break;
319 } case MOXA_GET_OQUEUE: 320 } case MOXA_GET_OQUEUE:
320 status = MoxaPortTxQueue(ch); 321 status = MoxaPortTxQueue(ch);
321 return put_user(status, (unsigned long __user *)argp); 322 ret = put_user(status, (unsigned long __user *)argp);
323 break;
322 case MOXA_GET_IQUEUE: 324 case MOXA_GET_IQUEUE:
323 status = MoxaPortRxQueue(ch); 325 status = MoxaPortRxQueue(ch);
324 return put_user(status, (unsigned long __user *)argp); 326 ret = put_user(status, (unsigned long __user *)argp);
327 break;
325 case MOXA_GETMSTATUS: { 328 case MOXA_GETMSTATUS: {
326 struct mxser_mstatus __user *argm = argp; 329 struct mxser_mstatus __user *argm = argp;
327 struct mxser_mstatus tmp; 330 struct mxser_mstatus tmp;
328 struct moxa_port *p; 331 struct moxa_port *p;
329 unsigned int i, j; 332 unsigned int i, j;
330 333
334 mutex_lock(&moxa_openlock);
331 for (i = 0; i < MAX_BOARDS; i++) { 335 for (i = 0; i < MAX_BOARDS; i++) {
332 p = moxa_boards[i].ports; 336 p = moxa_boards[i].ports;
333 for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) { 337 for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) {
@@ -348,18 +352,29 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
348 else 352 else
349 tmp.cflag = p->tty->termios->c_cflag; 353 tmp.cflag = p->tty->termios->c_cflag;
350copy: 354copy:
351 if (copy_to_user(argm, &tmp, sizeof(tmp))) 355 if (copy_to_user(argm, &tmp, sizeof(tmp))) {
356 mutex_unlock(&moxa_openlock);
352 return -EFAULT; 357 return -EFAULT;
358 }
353 } 359 }
354 } 360 }
355 return 0; 361 mutex_unlock(&moxa_openlock);
362 break;
356 } 363 }
357 case TIOCGSERIAL: 364 case TIOCGSERIAL:
358 return moxa_get_serial_info(ch, argp); 365 mutex_lock(&moxa_openlock);
366 ret = moxa_get_serial_info(ch, argp);
367 mutex_unlock(&moxa_openlock);
368 break;
359 case TIOCSSERIAL: 369 case TIOCSSERIAL:
360 return moxa_set_serial_info(ch, argp); 370 mutex_lock(&moxa_openlock);
371 ret = moxa_set_serial_info(ch, argp);
372 mutex_unlock(&moxa_openlock);
373 break;
374 default:
375 ret = -ENOIOCTLCMD;
361 } 376 }
362 return -ENOIOCTLCMD; 377 return ret;
363} 378}
364 379
365static void moxa_break_ctl(struct tty_struct *tty, int state) 380static void moxa_break_ctl(struct tty_struct *tty, int state)
@@ -817,7 +832,6 @@ static int moxa_init_board(struct moxa_board_conf *brd, struct device *dev)
817 p->close_delay = 5 * HZ / 10; 832 p->close_delay = 5 * HZ / 10;
818 p->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL; 833 p->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;
819 init_waitqueue_head(&p->open_wait); 834 init_waitqueue_head(&p->open_wait);
820 init_completion(&p->close_wait);
821 } 835 }
822 836
823 switch (brd->boardType) { 837 switch (brd->boardType) {
@@ -861,9 +875,29 @@ err:
861 875
862static void moxa_board_deinit(struct moxa_board_conf *brd) 876static void moxa_board_deinit(struct moxa_board_conf *brd)
863{ 877{
878 unsigned int a, opened;
879
880 mutex_lock(&moxa_openlock);
864 spin_lock_bh(&moxa_lock); 881 spin_lock_bh(&moxa_lock);
865 brd->ready = 0; 882 brd->ready = 0;
866 spin_unlock_bh(&moxa_lock); 883 spin_unlock_bh(&moxa_lock);
884
885 /* pci hot-un-plug support */
886 for (a = 0; a < brd->numPorts; a++)
887 if (brd->ports[a].asyncflags & ASYNC_INITIALIZED)
888 tty_hangup(brd->ports[a].tty);
889 while (1) {
890 opened = 0;
891 for (a = 0; a < brd->numPorts; a++)
892 if (brd->ports[a].asyncflags & ASYNC_INITIALIZED)
893 opened++;
894 mutex_unlock(&moxa_openlock);
895 if (!opened)
896 break;
897 msleep(50);
898 mutex_lock(&moxa_openlock);
899 }
900
867 iounmap(brd->basemem); 901 iounmap(brd->basemem);
868 brd->basemem = NULL; 902 brd->basemem = NULL;
869 kfree(brd->ports); 903 kfree(brd->ports);
@@ -1061,6 +1095,49 @@ static void __exit moxa_exit(void)
1061module_init(moxa_init); 1095module_init(moxa_init);
1062module_exit(moxa_exit); 1096module_exit(moxa_exit);
1063 1097
1098static void moxa_close_port(struct moxa_port *ch)
1099{
1100 moxa_shut_down(ch);
1101 MoxaPortFlushData(ch, 2);
1102 ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
1103 ch->tty->driver_data = NULL;
1104 ch->tty = NULL;
1105}
1106
1107static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
1108 struct moxa_port *ch)
1109{
1110 DEFINE_WAIT(wait);
1111 int retval = 0;
1112 u8 dcd;
1113
1114 while (1) {
1115 prepare_to_wait(&ch->open_wait, &wait, TASK_INTERRUPTIBLE);
1116 if (tty_hung_up_p(filp)) {
1117#ifdef SERIAL_DO_RESTART
1118 retval = -ERESTARTSYS;
1119#else
1120 retval = -EAGAIN;
1121#endif
1122 break;
1123 }
1124 spin_lock_bh(&moxa_lock);
1125 dcd = ch->DCDState;
1126 spin_unlock_bh(&moxa_lock);
1127 if (dcd)
1128 break;
1129
1130 if (signal_pending(current)) {
1131 retval = -ERESTARTSYS;
1132 break;
1133 }
1134 schedule();
1135 }
1136 finish_wait(&ch->open_wait, &wait);
1137
1138 return retval;
1139}
1140
1064static int moxa_open(struct tty_struct *tty, struct file *filp) 1141static int moxa_open(struct tty_struct *tty, struct file *filp)
1065{ 1142{
1066 struct moxa_board_conf *brd; 1143 struct moxa_board_conf *brd;
@@ -1072,9 +1149,13 @@ static int moxa_open(struct tty_struct *tty, struct file *filp)
1072 if (port == MAX_PORTS) { 1149 if (port == MAX_PORTS) {
1073 return capable(CAP_SYS_ADMIN) ? 0 : -EPERM; 1150 return capable(CAP_SYS_ADMIN) ? 0 : -EPERM;
1074 } 1151 }
1152 if (mutex_lock_interruptible(&moxa_openlock))
1153 return -ERESTARTSYS;
1075 brd = &moxa_boards[port / MAX_PORTS_PER_BOARD]; 1154 brd = &moxa_boards[port / MAX_PORTS_PER_BOARD];
1076 if (!brd->ready) 1155 if (!brd->ready) {
1156 mutex_unlock(&moxa_openlock);
1077 return -ENODEV; 1157 return -ENODEV;
1158 }
1078 1159
1079 ch = &brd->ports[port % MAX_PORTS_PER_BOARD]; 1160 ch = &brd->ports[port % MAX_PORTS_PER_BOARD];
1080 ch->count++; 1161 ch->count++;
@@ -1085,19 +1166,24 @@ static int moxa_open(struct tty_struct *tty, struct file *filp)
1085 moxa_set_tty_param(tty, tty->termios); 1166 moxa_set_tty_param(tty, tty->termios);
1086 MoxaPortLineCtrl(ch, 1, 1); 1167 MoxaPortLineCtrl(ch, 1, 1);
1087 MoxaPortEnable(ch); 1168 MoxaPortEnable(ch);
1169 MoxaSetFifo(ch, ch->type == PORT_16550A);
1088 ch->asyncflags |= ASYNC_INITIALIZED; 1170 ch->asyncflags |= ASYNC_INITIALIZED;
1089 } 1171 }
1090 retval = moxa_block_till_ready(tty, filp, ch); 1172 mutex_unlock(&moxa_openlock);
1091 1173
1092 moxa_unthrottle(tty); 1174 retval = 0;
1093 1175 if (!(filp->f_flags & O_NONBLOCK) && !C_CLOCAL(tty))
1094 if (ch->type == PORT_16550A) { 1176 retval = moxa_block_till_ready(tty, filp, ch);
1095 MoxaSetFifo(ch, 1); 1177 mutex_lock(&moxa_openlock);
1096 } else { 1178 if (retval) {
1097 MoxaSetFifo(ch, 0); 1179 if (ch->count) /* 0 means already hung up... */
1098 } 1180 if (--ch->count == 0)
1181 moxa_close_port(ch);
1182 } else
1183 ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
1184 mutex_unlock(&moxa_openlock);
1099 1185
1100 return (retval); 1186 return retval;
1101} 1187}
1102 1188
1103static void moxa_close(struct tty_struct *tty, struct file *filp) 1189static void moxa_close(struct tty_struct *tty, struct file *filp)
@@ -1106,18 +1192,14 @@ static void moxa_close(struct tty_struct *tty, struct file *filp)
1106 int port; 1192 int port;
1107 1193
1108 port = tty->index; 1194 port = tty->index;
1109 if (port == MAX_PORTS) { 1195 if (port == MAX_PORTS || tty_hung_up_p(filp))
1110 return;
1111 }
1112 if (tty->driver_data == NULL) {
1113 return; 1196 return;
1114 }
1115 if (tty_hung_up_p(filp)) {
1116 return;
1117 }
1118 ch = (struct moxa_port *) tty->driver_data;
1119 1197
1120 if ((tty->count == 1) && (ch->count != 1)) { 1198 mutex_lock(&moxa_openlock);
1199 ch = tty->driver_data;
1200 if (ch == NULL)
1201 goto unlock;
1202 if (tty->count == 1 && ch->count != 1) {
1121 printk(KERN_WARNING "moxa_close: bad serial port count; " 1203 printk(KERN_WARNING "moxa_close: bad serial port count; "
1122 "tty->count is 1, ch->count is %d\n", ch->count); 1204 "tty->count is 1, ch->count is %d\n", ch->count);
1123 ch->count = 1; 1205 ch->count = 1;
@@ -1127,33 +1209,18 @@ static void moxa_close(struct tty_struct *tty, struct file *filp)
1127 "device=%s\n", tty->name); 1209 "device=%s\n", tty->name);
1128 ch->count = 0; 1210 ch->count = 0;
1129 } 1211 }
1130 if (ch->count) { 1212 if (ch->count)
1131 return; 1213 goto unlock;
1132 }
1133 ch->asyncflags |= ASYNC_CLOSING;
1134 1214
1135 ch->cflag = tty->termios->c_cflag; 1215 ch->cflag = tty->termios->c_cflag;
1136 if (ch->asyncflags & ASYNC_INITIALIZED) { 1216 if (ch->asyncflags & ASYNC_INITIALIZED) {
1137 moxa_setup_empty_event(tty); 1217 moxa_setup_empty_event(tty);
1138 tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */ 1218 tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */
1139 } 1219 }
1140 moxa_shut_down(ch);
1141 MoxaPortFlushData(ch, 2);
1142 1220
1143 if (tty->driver->flush_buffer) 1221 moxa_close_port(ch);
1144 tty->driver->flush_buffer(tty); 1222unlock:
1145 tty_ldisc_flush(tty); 1223 mutex_unlock(&moxa_openlock);
1146
1147 tty->closing = 0;
1148 ch->tty = NULL;
1149 if (ch->blocked_open) {
1150 if (ch->close_delay) {
1151 msleep_interruptible(jiffies_to_msecs(ch->close_delay));
1152 }
1153 wake_up_interruptible(&ch->open_wait);
1154 }
1155 ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
1156 complete_all(&ch->close_wait);
1157} 1224}
1158 1225
1159static int moxa_write(struct tty_struct *tty, 1226static int moxa_write(struct tty_struct *tty,
@@ -1249,11 +1316,15 @@ static void moxa_put_char(struct tty_struct *tty, unsigned char c)
1249 1316
1250static int moxa_tiocmget(struct tty_struct *tty, struct file *file) 1317static int moxa_tiocmget(struct tty_struct *tty, struct file *file)
1251{ 1318{
1252 struct moxa_port *ch = tty->driver_data; 1319 struct moxa_port *ch;
1253 int flag = 0, dtr, rts; 1320 int flag = 0, dtr, rts;
1254 1321
1255 if (!ch) 1322 mutex_lock(&moxa_openlock);
1323 ch = tty->driver_data;
1324 if (!ch) {
1325 mutex_unlock(&moxa_openlock);
1256 return -EINVAL; 1326 return -EINVAL;
1327 }
1257 1328
1258 MoxaPortGetLineOut(ch, &dtr, &rts); 1329 MoxaPortGetLineOut(ch, &dtr, &rts);
1259 if (dtr) 1330 if (dtr)
@@ -1267,19 +1338,24 @@ static int moxa_tiocmget(struct tty_struct *tty, struct file *file)
1267 flag |= TIOCM_DSR; 1338 flag |= TIOCM_DSR;
1268 if (dtr & 4) 1339 if (dtr & 4)
1269 flag |= TIOCM_CD; 1340 flag |= TIOCM_CD;
1341 mutex_unlock(&moxa_openlock);
1270 return flag; 1342 return flag;
1271} 1343}
1272 1344
1273static int moxa_tiocmset(struct tty_struct *tty, struct file *file, 1345static int moxa_tiocmset(struct tty_struct *tty, struct file *file,
1274 unsigned int set, unsigned int clear) 1346 unsigned int set, unsigned int clear)
1275{ 1347{
1276 struct moxa_port *ch = tty->driver_data; 1348 struct moxa_port *ch;
1277 int port; 1349 int port;
1278 int dtr, rts; 1350 int dtr, rts;
1279 1351
1280 port = tty->index; 1352 port = tty->index;
1281 if (!ch) 1353 mutex_lock(&moxa_openlock);
1354 ch = tty->driver_data;
1355 if (!ch) {
1356 mutex_unlock(&moxa_openlock);
1282 return -EINVAL; 1357 return -EINVAL;
1358 }
1283 1359
1284 MoxaPortGetLineOut(ch, &dtr, &rts); 1360 MoxaPortGetLineOut(ch, &dtr, &rts);
1285 if (set & TIOCM_RTS) 1361 if (set & TIOCM_RTS)
@@ -1291,6 +1367,7 @@ static int moxa_tiocmset(struct tty_struct *tty, struct file *file,
1291 if (clear & TIOCM_DTR) 1367 if (clear & TIOCM_DTR)
1292 dtr = 0; 1368 dtr = 0;
1293 MoxaPortLineCtrl(ch, dtr, rts); 1369 MoxaPortLineCtrl(ch, dtr, rts);
1370 mutex_unlock(&moxa_openlock);
1294 return 0; 1371 return 0;
1295} 1372}
1296 1373
@@ -1348,13 +1425,18 @@ static void moxa_start(struct tty_struct *tty)
1348 1425
1349static void moxa_hangup(struct tty_struct *tty) 1426static void moxa_hangup(struct tty_struct *tty)
1350{ 1427{
1351 struct moxa_port *ch = (struct moxa_port *) tty->driver_data; 1428 struct moxa_port *ch;
1352 1429
1353 moxa_flush_buffer(tty); 1430 mutex_lock(&moxa_openlock);
1354 moxa_shut_down(ch); 1431 ch = tty->driver_data;
1432 if (ch == NULL) {
1433 mutex_unlock(&moxa_openlock);
1434 return;
1435 }
1355 ch->count = 0; 1436 ch->count = 0;
1356 ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE; 1437 moxa_close_port(ch);
1357 ch->tty = NULL; 1438 mutex_unlock(&moxa_openlock);
1439
1358 wake_up_interruptible(&ch->open_wait); 1440 wake_up_interruptible(&ch->open_wait);
1359} 1441}
1360 1442
@@ -1363,11 +1445,8 @@ static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd)
1363 dcd = !!dcd; 1445 dcd = !!dcd;
1364 1446
1365 if ((dcd != p->DCDState) && p->tty && C_CLOCAL(p->tty)) { 1447 if ((dcd != p->DCDState) && p->tty && C_CLOCAL(p->tty)) {
1366 if (!dcd) { 1448 if (!dcd)
1367 tty_hangup(p->tty); 1449 tty_hangup(p->tty);
1368 p->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
1369 }
1370 wake_up_interruptible(&p->open_wait);
1371 } 1450 }
1372 p->DCDState = dcd; 1451 p->DCDState = dcd;
1373} 1452}
@@ -1499,91 +1578,6 @@ static void moxa_set_tty_param(struct tty_struct *tty, struct ktermios *old_term
1499 tty_encode_baud_rate(tty, baud, baud); 1578 tty_encode_baud_rate(tty, baud, baud);
1500} 1579}
1501 1580
1502static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
1503 struct moxa_port *ch)
1504{
1505 DECLARE_WAITQUEUE(wait,current);
1506 int retval;
1507 int do_clocal = C_CLOCAL(tty);
1508
1509 /*
1510 * If the device is in the middle of being closed, then block
1511 * until it's done, and then try again.
1512 */
1513 if (tty_hung_up_p(filp) || (ch->asyncflags & ASYNC_CLOSING)) {
1514 if (ch->asyncflags & ASYNC_CLOSING)
1515 wait_for_completion_interruptible(&ch->close_wait);
1516#ifdef SERIAL_DO_RESTART
1517 if (ch->asyncflags & ASYNC_HUP_NOTIFY)
1518 return (-EAGAIN);
1519 else
1520 return (-ERESTARTSYS);
1521#else
1522 return (-EAGAIN);
1523#endif
1524 }
1525 /*
1526 * If non-blocking mode is set, then make the check up front
1527 * and then exit.
1528 */
1529 if (filp->f_flags & O_NONBLOCK) {
1530 ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
1531 return (0);
1532 }
1533 /*
1534 * Block waiting for the carrier detect and the line to become free
1535 */
1536 retval = 0;
1537 add_wait_queue(&ch->open_wait, &wait);
1538 pr_debug("block_til_ready before block: ttys%d, count = %d\n",
1539 tty->index, ch->count);
1540 spin_lock_bh(&moxa_lock);
1541 if (!tty_hung_up_p(filp))
1542 ch->count--;
1543 ch->blocked_open++;
1544 spin_unlock_bh(&moxa_lock);
1545
1546 while (1) {
1547 set_current_state(TASK_INTERRUPTIBLE);
1548 if (tty_hung_up_p(filp) ||
1549 !(ch->asyncflags & ASYNC_INITIALIZED)) {
1550#ifdef SERIAL_DO_RESTART
1551 if (ch->asyncflags & ASYNC_HUP_NOTIFY)
1552 retval = -EAGAIN;
1553 else
1554 retval = -ERESTARTSYS;
1555#else
1556 retval = -EAGAIN;
1557#endif
1558 break;
1559 }
1560 if (!(ch->asyncflags & ASYNC_CLOSING) && (do_clocal ||
1561 ch->DCDState))
1562 break;
1563
1564 if (signal_pending(current)) {
1565 retval = -ERESTARTSYS;
1566 break;
1567 }
1568 schedule();
1569 }
1570 set_current_state(TASK_RUNNING);
1571 remove_wait_queue(&ch->open_wait, &wait);
1572
1573 spin_lock_bh(&moxa_lock);
1574 if (!tty_hung_up_p(filp))
1575 ch->count++;
1576 ch->blocked_open--;
1577 spin_unlock_bh(&moxa_lock);
1578 pr_debug("block_til_ready after blocking: ttys%d, count = %d\n",
1579 tty->index, ch->count);
1580 if (retval)
1581 return (retval);
1582 /* FIXME: review to see if we need to use set_bit on these */
1583 ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
1584 return 0;
1585}
1586
1587static void moxa_setup_empty_event(struct tty_struct *tty) 1581static void moxa_setup_empty_event(struct tty_struct *tty)
1588{ 1582{
1589 struct moxa_port *ch = tty->driver_data; 1583 struct moxa_port *ch = tty->driver_data;
@@ -1595,22 +1589,22 @@ static void moxa_setup_empty_event(struct tty_struct *tty)
1595 1589
1596static void moxa_shut_down(struct moxa_port *ch) 1590static void moxa_shut_down(struct moxa_port *ch)
1597{ 1591{
1598 struct tty_struct *tp; 1592 struct tty_struct *tp = ch->tty;
1599 1593
1600 if (!(ch->asyncflags & ASYNC_INITIALIZED)) 1594 if (!(ch->asyncflags & ASYNC_INITIALIZED))
1601 return; 1595 return;
1602 1596
1603 tp = ch->tty;
1604
1605 MoxaPortDisable(ch); 1597 MoxaPortDisable(ch);
1606 1598
1607 /* 1599 /*
1608 * If we're a modem control device and HUPCL is on, drop RTS & DTR. 1600 * If we're a modem control device and HUPCL is on, drop RTS & DTR.
1609 */ 1601 */
1610 if (tp->termios->c_cflag & HUPCL) 1602 if (C_HUPCL(tp))
1611 MoxaPortLineCtrl(ch, 0, 0); 1603 MoxaPortLineCtrl(ch, 0, 0);
1612 1604
1605 spin_lock_bh(&moxa_lock);
1613 ch->asyncflags &= ~ASYNC_INITIALIZED; 1606 ch->asyncflags &= ~ASYNC_INITIALIZED;
1607 spin_unlock_bh(&moxa_lock);
1614} 1608}
1615 1609
1616/***************************************************************************** 1610/*****************************************************************************
@@ -2029,7 +2023,9 @@ static int MoxaPortLineStatus(struct moxa_port *port)
2029 val &= 0x0B; 2023 val &= 0x0B;
2030 if (val & 8) 2024 if (val & 8)
2031 val |= 4; 2025 val |= 4;
2026 spin_lock_bh(&moxa_lock);
2032 moxa_new_dcdstate(port, val & 8); 2027 moxa_new_dcdstate(port, val & 8);
2028 spin_unlock_bh(&moxa_lock);
2033 val &= 7; 2029 val &= 7;
2034 return val; 2030 return val;
2035} 2031}