diff options
Diffstat (limited to 'drivers/char/mxser.c')
-rw-r--r-- | drivers/char/mxser.c | 63 |
1 files changed, 38 insertions, 25 deletions
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index 68c2e9234691..00cf09aa11fc 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c | |||
@@ -1460,6 +1460,7 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | |||
1460 | struct mxser_port *port; | 1460 | struct mxser_port *port; |
1461 | int result, status; | 1461 | int result, status; |
1462 | unsigned int i, j; | 1462 | unsigned int i, j; |
1463 | int ret = 0; | ||
1463 | 1464 | ||
1464 | switch (cmd) { | 1465 | switch (cmd) { |
1465 | case MOXA_GET_MAJOR: | 1466 | case MOXA_GET_MAJOR: |
@@ -1467,18 +1468,21 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | |||
1467 | 1468 | ||
1468 | case MOXA_CHKPORTENABLE: | 1469 | case MOXA_CHKPORTENABLE: |
1469 | result = 0; | 1470 | result = 0; |
1470 | 1471 | lock_kernel(); | |
1471 | for (i = 0; i < MXSER_BOARDS; i++) | 1472 | for (i = 0; i < MXSER_BOARDS; i++) |
1472 | for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) | 1473 | for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) |
1473 | if (mxser_boards[i].ports[j].ioaddr) | 1474 | if (mxser_boards[i].ports[j].ioaddr) |
1474 | result |= (1 << i); | 1475 | result |= (1 << i); |
1475 | 1476 | unlock_kernel(); | |
1476 | return put_user(result, (unsigned long __user *)argp); | 1477 | return put_user(result, (unsigned long __user *)argp); |
1477 | case MOXA_GETDATACOUNT: | 1478 | case MOXA_GETDATACOUNT: |
1479 | lock_kernel(); | ||
1478 | if (copy_to_user(argp, &mxvar_log, sizeof(mxvar_log))) | 1480 | if (copy_to_user(argp, &mxvar_log, sizeof(mxvar_log))) |
1479 | return -EFAULT; | 1481 | ret = -EFAULT; |
1480 | return 0; | 1482 | unlock_kernel(); |
1483 | return ret; | ||
1481 | case MOXA_GETMSTATUS: | 1484 | case MOXA_GETMSTATUS: |
1485 | lock_kernel(); | ||
1482 | for (i = 0; i < MXSER_BOARDS; i++) | 1486 | for (i = 0; i < MXSER_BOARDS; i++) |
1483 | for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) { | 1487 | for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) { |
1484 | port = &mxser_boards[i].ports[j]; | 1488 | port = &mxser_boards[i].ports[j]; |
@@ -1515,6 +1519,7 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | |||
1515 | else | 1519 | else |
1516 | GMStatus[i].cts = 0; | 1520 | GMStatus[i].cts = 0; |
1517 | } | 1521 | } |
1522 | unlock_kernel(); | ||
1518 | if (copy_to_user(argp, GMStatus, | 1523 | if (copy_to_user(argp, GMStatus, |
1519 | sizeof(struct mxser_mstatus) * MXSER_PORTS)) | 1524 | sizeof(struct mxser_mstatus) * MXSER_PORTS)) |
1520 | return -EFAULT; | 1525 | return -EFAULT; |
@@ -1524,7 +1529,8 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | |||
1524 | unsigned long opmode; | 1529 | unsigned long opmode; |
1525 | unsigned cflag, iflag; | 1530 | unsigned cflag, iflag; |
1526 | 1531 | ||
1527 | for (i = 0; i < MXSER_BOARDS; i++) | 1532 | lock_kernel(); |
1533 | for (i = 0; i < MXSER_BOARDS; i++) { | ||
1528 | for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) { | 1534 | for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) { |
1529 | port = &mxser_boards[i].ports[j]; | 1535 | port = &mxser_boards[i].ports[j]; |
1530 | if (!port->ioaddr) | 1536 | if (!port->ioaddr) |
@@ -1589,13 +1595,14 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | |||
1589 | mon_data_ext.iftype[i] = opmode; | 1595 | mon_data_ext.iftype[i] = opmode; |
1590 | 1596 | ||
1591 | } | 1597 | } |
1592 | if (copy_to_user(argp, &mon_data_ext, | 1598 | } |
1593 | sizeof(mon_data_ext))) | 1599 | unlock_kernel(); |
1594 | return -EFAULT; | 1600 | if (copy_to_user(argp, &mon_data_ext, |
1595 | 1601 | sizeof(mon_data_ext))) | |
1596 | return 0; | 1602 | return -EFAULT; |
1597 | 1603 | return 0; | |
1598 | } default: | 1604 | } |
1605 | default: | ||
1599 | return -ENOIOCTLCMD; | 1606 | return -ENOIOCTLCMD; |
1600 | } | 1607 | } |
1601 | return 0; | 1608 | return 0; |
@@ -1651,16 +1658,20 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1651 | opmode != RS422_MODE && | 1658 | opmode != RS422_MODE && |
1652 | opmode != RS485_4WIRE_MODE) | 1659 | opmode != RS485_4WIRE_MODE) |
1653 | return -EFAULT; | 1660 | return -EFAULT; |
1661 | lock_kernel(); | ||
1654 | mask = ModeMask[p]; | 1662 | mask = ModeMask[p]; |
1655 | shiftbit = p * 2; | 1663 | shiftbit = p * 2; |
1656 | val = inb(info->opmode_ioaddr); | 1664 | val = inb(info->opmode_ioaddr); |
1657 | val &= mask; | 1665 | val &= mask; |
1658 | val |= (opmode << shiftbit); | 1666 | val |= (opmode << shiftbit); |
1659 | outb(val, info->opmode_ioaddr); | 1667 | outb(val, info->opmode_ioaddr); |
1668 | unlock_kernel(); | ||
1660 | } else { | 1669 | } else { |
1670 | lock_kernel(); | ||
1661 | shiftbit = p * 2; | 1671 | shiftbit = p * 2; |
1662 | opmode = inb(info->opmode_ioaddr) >> shiftbit; | 1672 | opmode = inb(info->opmode_ioaddr) >> shiftbit; |
1663 | opmode &= OP_MODE_MASK; | 1673 | opmode &= OP_MODE_MASK; |
1674 | unlock_kernel(); | ||
1664 | if (put_user(opmode, (int __user *)argp)) | 1675 | if (put_user(opmode, (int __user *)argp)) |
1665 | return -EFAULT; | 1676 | return -EFAULT; |
1666 | } | 1677 | } |
@@ -1687,19 +1698,18 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1687 | tty_wait_until_sent(tty, 0); | 1698 | tty_wait_until_sent(tty, 0); |
1688 | mxser_send_break(info, arg ? arg * (HZ / 10) : HZ / 4); | 1699 | mxser_send_break(info, arg ? arg * (HZ / 10) : HZ / 4); |
1689 | return 0; | 1700 | return 0; |
1690 | case TIOCGSOFTCAR: | ||
1691 | return put_user(!!C_CLOCAL(tty), (unsigned long __user *)argp); | ||
1692 | case TIOCSSOFTCAR: | ||
1693 | if (get_user(arg, (unsigned long __user *)argp)) | ||
1694 | return -EFAULT; | ||
1695 | tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) | (arg ? CLOCAL : 0)); | ||
1696 | return 0; | ||
1697 | case TIOCGSERIAL: | 1701 | case TIOCGSERIAL: |
1698 | return mxser_get_serial_info(info, argp); | 1702 | lock_kernel(); |
1703 | retval = mxser_get_serial_info(info, argp); | ||
1704 | unlock_kernel(); | ||
1705 | return retval; | ||
1699 | case TIOCSSERIAL: | 1706 | case TIOCSSERIAL: |
1700 | return mxser_set_serial_info(info, argp); | 1707 | lock_kernel(); |
1708 | retval = mxser_set_serial_info(info, argp); | ||
1709 | unlock_kernel(); | ||
1710 | return retval; | ||
1701 | case TIOCSERGETLSR: /* Get line status register */ | 1711 | case TIOCSERGETLSR: /* Get line status register */ |
1702 | return mxser_get_lsr_info(info, argp); | 1712 | return mxser_get_lsr_info(info, argp); |
1703 | /* | 1713 | /* |
1704 | * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change | 1714 | * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change |
1705 | * - mask passed in arg for lines of interest | 1715 | * - mask passed in arg for lines of interest |
@@ -1746,24 +1756,27 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1746 | case MOXA_HighSpeedOn: | 1756 | case MOXA_HighSpeedOn: |
1747 | return put_user(info->baud_base != 115200 ? 1 : 0, (int __user *)argp); | 1757 | return put_user(info->baud_base != 115200 ? 1 : 0, (int __user *)argp); |
1748 | case MOXA_SDS_RSTICOUNTER: | 1758 | case MOXA_SDS_RSTICOUNTER: |
1759 | lock_kernel(); | ||
1749 | info->mon_data.rxcnt = 0; | 1760 | info->mon_data.rxcnt = 0; |
1750 | info->mon_data.txcnt = 0; | 1761 | info->mon_data.txcnt = 0; |
1762 | unlock_kernel(); | ||
1751 | return 0; | 1763 | return 0; |
1752 | 1764 | ||
1753 | case MOXA_ASPP_OQUEUE:{ | 1765 | case MOXA_ASPP_OQUEUE:{ |
1754 | int len, lsr; | 1766 | int len, lsr; |
1755 | 1767 | ||
1768 | lock_kernel(); | ||
1756 | len = mxser_chars_in_buffer(tty); | 1769 | len = mxser_chars_in_buffer(tty); |
1757 | |||
1758 | lsr = inb(info->ioaddr + UART_LSR) & UART_LSR_TEMT; | 1770 | lsr = inb(info->ioaddr + UART_LSR) & UART_LSR_TEMT; |
1759 | |||
1760 | len += (lsr ? 0 : 1); | 1771 | len += (lsr ? 0 : 1); |
1772 | unlock_kernel(); | ||
1761 | 1773 | ||
1762 | return put_user(len, (int __user *)argp); | 1774 | return put_user(len, (int __user *)argp); |
1763 | } | 1775 | } |
1764 | case MOXA_ASPP_MON: { | 1776 | case MOXA_ASPP_MON: { |
1765 | int mcr, status; | 1777 | int mcr, status; |
1766 | 1778 | ||
1779 | lock_kernel(); | ||
1767 | status = mxser_get_msr(info->ioaddr, 1, tty->index); | 1780 | status = mxser_get_msr(info->ioaddr, 1, tty->index); |
1768 | mxser_check_modem_status(info, status); | 1781 | mxser_check_modem_status(info, status); |
1769 | 1782 | ||
@@ -1782,7 +1795,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1782 | info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD; | 1795 | info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD; |
1783 | else | 1796 | else |
1784 | info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD; | 1797 | info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD; |
1785 | 1798 | unlock_kernel(); | |
1786 | if (copy_to_user(argp, &info->mon_data, | 1799 | if (copy_to_user(argp, &info->mon_data, |
1787 | sizeof(struct mxser_mon))) | 1800 | sizeof(struct mxser_mon))) |
1788 | return -EFAULT; | 1801 | return -EFAULT; |