Commit e8c62103 authored by Alan Cox's avatar Alan Cox Committed by Greg Kroah-Hartman

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: default avatarAlan Cox <alan@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent f710ebd7
...@@ -163,6 +163,7 @@ static struct mon_str moxaLog; ...@@ -163,6 +163,7 @@ static struct mon_str moxaLog;
static unsigned int moxaFuncTout = HZ / 2; static unsigned int moxaFuncTout = HZ / 2;
static unsigned int moxaLowWaterChk; static unsigned int moxaLowWaterChk;
static DEFINE_MUTEX(moxa_openlock); static DEFINE_MUTEX(moxa_openlock);
static DEFINE_SPINLOCK(moxa_lock);
/* Variables for insmod */ /* Variables for insmod */
#ifdef MODULE #ifdef MODULE
static unsigned long baseaddr[MAX_BOARDS]; static unsigned long baseaddr[MAX_BOARDS];
...@@ -313,22 +314,20 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file, ...@@ -313,22 +314,20 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
struct moxa_port *p; struct moxa_port *p;
unsigned int i, j; unsigned int i, j;
mutex_lock(&moxa_openlock);
for (i = 0; i < MAX_BOARDS; i++) { for (i = 0; i < MAX_BOARDS; i++) {
p = moxa_boards[i].ports; p = moxa_boards[i].ports;
for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) { for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) {
memset(&tmp, 0, sizeof(tmp)); memset(&tmp, 0, sizeof(tmp));
spin_lock_bh(&moxa_lock);
if (moxa_boards[i].ready) { if (moxa_boards[i].ready) {
tmp.inq = MoxaPortRxQueue(p); tmp.inq = MoxaPortRxQueue(p);
tmp.outq = MoxaPortTxQueue(p); tmp.outq = MoxaPortTxQueue(p);
} }
if (copy_to_user(argm, &tmp, sizeof(tmp))) { spin_unlock_bh(&moxa_lock);
mutex_unlock(&moxa_openlock); if (copy_to_user(argm, &tmp, sizeof(tmp)))
return -EFAULT; return -EFAULT;
}
} }
} }
mutex_unlock(&moxa_openlock);
break; break;
} case MOXA_GET_OQUEUE: } case MOXA_GET_OQUEUE:
status = MoxaPortTxQueue(ch); status = MoxaPortTxQueue(ch);
...@@ -344,16 +343,20 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file, ...@@ -344,16 +343,20 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
struct moxa_port *p; struct moxa_port *p;
unsigned int i, j; unsigned int i, j;
mutex_lock(&moxa_openlock);
for (i = 0; i < MAX_BOARDS; i++) { for (i = 0; i < MAX_BOARDS; i++) {
p = moxa_boards[i].ports; p = moxa_boards[i].ports;
for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) { for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) {
struct tty_struct *ttyp; struct tty_struct *ttyp;
memset(&tmp, 0, sizeof(tmp)); memset(&tmp, 0, sizeof(tmp));
if (!moxa_boards[i].ready) spin_lock_bh(&moxa_lock);
if (!moxa_boards[i].ready) {
spin_unlock_bh(&moxa_lock);
goto copy; goto copy;
}
status = MoxaPortLineStatus(p); status = MoxaPortLineStatus(p);
spin_unlock_bh(&moxa_lock);
if (status & 1) if (status & 1)
tmp.cts = 1; tmp.cts = 1;
if (status & 2) if (status & 2)
...@@ -368,13 +371,10 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file, ...@@ -368,13 +371,10 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
tmp.cflag = ttyp->termios->c_cflag; tmp.cflag = ttyp->termios->c_cflag;
tty_kref_put(tty); tty_kref_put(tty);
copy: copy:
if (copy_to_user(argm, &tmp, sizeof(tmp))) { if (copy_to_user(argm, &tmp, sizeof(tmp)))
mutex_unlock(&moxa_openlock);
return -EFAULT; return -EFAULT;
}
} }
} }
mutex_unlock(&moxa_openlock);
break; break;
} }
case TIOCGSERIAL: case TIOCGSERIAL:
...@@ -427,7 +427,6 @@ static const struct tty_port_operations moxa_port_ops = { ...@@ -427,7 +427,6 @@ static const struct tty_port_operations moxa_port_ops = {
static struct tty_driver *moxaDriver; static struct tty_driver *moxaDriver;
static DEFINE_TIMER(moxaTimer, moxa_poll, 0, 0); static DEFINE_TIMER(moxaTimer, moxa_poll, 0, 0);
static DEFINE_SPINLOCK(moxa_lock);
/* /*
* HW init * HW init
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment