aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/moxa.c
diff options
context:
space:
mode:
authorAlan Cox <alan@linux.intel.com>2009-11-30 08:18:24 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2009-12-11 18:18:08 -0500
commite8c62103fd5fecc8d2086bae244b32d089892175 (patch)
treeb87fe3662714c89f38cddd6b7fafc4b60e8b2642 /drivers/char/moxa.c
parentf710ebd7f70801e31751f2c49fe4b92a477d24eb (diff)
tty: moxa: split open lock
moxa_openlock is used for several situations where we want to handle the case of an ioctl that crosses many ports (not just the open tty), and also cases where an open races a deinit (eg a pci unplug) and we hangup a port before we can cope with that. The non open race cases can use the moxa_lock spinlock. This simplifies sorting out the remaining mess. Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/char/moxa.c')
-rw-r--r--drivers/char/moxa.c23
1 files changed, 11 insertions, 12 deletions
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index d53fac5229bf..63ee3bbc1ce4 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -163,6 +163,7 @@ static struct mon_str moxaLog;
163static unsigned int moxaFuncTout = HZ / 2; 163static unsigned int moxaFuncTout = HZ / 2;
164static unsigned int moxaLowWaterChk; 164static unsigned int moxaLowWaterChk;
165static DEFINE_MUTEX(moxa_openlock); 165static DEFINE_MUTEX(moxa_openlock);
166static DEFINE_SPINLOCK(moxa_lock);
166/* Variables for insmod */ 167/* Variables for insmod */
167#ifdef MODULE 168#ifdef MODULE
168static unsigned long baseaddr[MAX_BOARDS]; 169static unsigned long baseaddr[MAX_BOARDS];
@@ -313,22 +314,20 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
313 struct moxa_port *p; 314 struct moxa_port *p;
314 unsigned int i, j; 315 unsigned int i, j;
315 316
316 mutex_lock(&moxa_openlock);
317 for (i = 0; i < MAX_BOARDS; i++) { 317 for (i = 0; i < MAX_BOARDS; i++) {
318 p = moxa_boards[i].ports; 318 p = moxa_boards[i].ports;
319 for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) { 319 for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) {
320 memset(&tmp, 0, sizeof(tmp)); 320 memset(&tmp, 0, sizeof(tmp));
321 spin_lock_bh(&moxa_lock);
321 if (moxa_boards[i].ready) { 322 if (moxa_boards[i].ready) {
322 tmp.inq = MoxaPortRxQueue(p); 323 tmp.inq = MoxaPortRxQueue(p);
323 tmp.outq = MoxaPortTxQueue(p); 324 tmp.outq = MoxaPortTxQueue(p);
324 } 325 }
325 if (copy_to_user(argm, &tmp, sizeof(tmp))) { 326 spin_unlock_bh(&moxa_lock);
326 mutex_unlock(&moxa_openlock); 327 if (copy_to_user(argm, &tmp, sizeof(tmp)))
327 return -EFAULT; 328 return -EFAULT;
328 }
329 } 329 }
330 } 330 }
331 mutex_unlock(&moxa_openlock);
332 break; 331 break;
333 } case MOXA_GET_OQUEUE: 332 } case MOXA_GET_OQUEUE:
334 status = MoxaPortTxQueue(ch); 333 status = MoxaPortTxQueue(ch);
@@ -344,16 +343,20 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
344 struct moxa_port *p; 343 struct moxa_port *p;
345 unsigned int i, j; 344 unsigned int i, j;
346 345
347 mutex_lock(&moxa_openlock);
348 for (i = 0; i < MAX_BOARDS; i++) { 346 for (i = 0; i < MAX_BOARDS; i++) {
349 p = moxa_boards[i].ports; 347 p = moxa_boards[i].ports;
350 for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) { 348 for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) {
351 struct tty_struct *ttyp; 349 struct tty_struct *ttyp;
352 memset(&tmp, 0, sizeof(tmp)); 350 memset(&tmp, 0, sizeof(tmp));
353 if (!moxa_boards[i].ready) 351 spin_lock_bh(&moxa_lock);
352 if (!moxa_boards[i].ready) {
353 spin_unlock_bh(&moxa_lock);
354 goto copy; 354 goto copy;
355 }
355 356
356 status = MoxaPortLineStatus(p); 357 status = MoxaPortLineStatus(p);
358 spin_unlock_bh(&moxa_lock);
359
357 if (status & 1) 360 if (status & 1)
358 tmp.cts = 1; 361 tmp.cts = 1;
359 if (status & 2) 362 if (status & 2)
@@ -368,13 +371,10 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
368 tmp.cflag = ttyp->termios->c_cflag; 371 tmp.cflag = ttyp->termios->c_cflag;
369 tty_kref_put(tty); 372 tty_kref_put(tty);
370copy: 373copy:
371 if (copy_to_user(argm, &tmp, sizeof(tmp))) { 374 if (copy_to_user(argm, &tmp, sizeof(tmp)))
372 mutex_unlock(&moxa_openlock);
373 return -EFAULT; 375 return -EFAULT;
374 }
375 } 376 }
376 } 377 }
377 mutex_unlock(&moxa_openlock);
378 break; 378 break;
379 } 379 }
380 case TIOCGSERIAL: 380 case TIOCGSERIAL:
@@ -427,7 +427,6 @@ static const struct tty_port_operations moxa_port_ops = {
427 427
428static struct tty_driver *moxaDriver; 428static struct tty_driver *moxaDriver;
429static DEFINE_TIMER(moxaTimer, moxa_poll, 0, 0); 429static DEFINE_TIMER(moxaTimer, moxa_poll, 0, 0);
430static DEFINE_SPINLOCK(moxa_lock);
431 430
432/* 431/*
433 * HW init 432 * HW init