aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/serial_core.c
diff options
context:
space:
mode:
authorAlan Cox <alan@linux.intel.com>2012-09-04 11:34:45 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-09-05 16:11:03 -0400
commit7ba2e769825fef035a943ed74d90379245508764 (patch)
tree58583d882d6216a80b51d00a88a406864e10ad85 /drivers/tty/serial/serial_core.c
parent9250dd5738ca2f2728913fefc6573daf5b95efa4 (diff)
tty: Split the serial_core helpers for setserial into two
We want them split so that we can call them from setserial functionality where we copy to/from user space and do the locking, but also from sysfs where in future we'll want to came them within a sysfs context. Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial/serial_core.c')
-rw-r--r--drivers/tty/serial/serial_core.c158
1 files changed, 87 insertions, 71 deletions
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 5b308c87b68c..bb5f23603836 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -634,38 +634,44 @@ static void uart_unthrottle(struct tty_struct *tty)
634 uart_set_mctrl(port, TIOCM_RTS); 634 uart_set_mctrl(port, TIOCM_RTS);
635} 635}
636 636
637static int uart_get_info(struct uart_state *state, 637static void uart_get_info(struct tty_port *port,
638 struct serial_struct __user *retinfo) 638 struct uart_state *state,
639 struct serial_struct *retinfo)
639{ 640{
640 struct uart_port *uport = state->uart_port; 641 struct uart_port *uport = state->uart_port;
641 struct tty_port *port = &state->port;
642 struct serial_struct tmp;
643
644 memset(&tmp, 0, sizeof(tmp));
645 642
646 /* Ensure the state we copy is consistent and no hardware changes 643 memset(retinfo, 0, sizeof(retinfo));
647 occur as we go */
648 mutex_lock(&port->mutex);
649 644
650 tmp.type = uport->type; 645 retinfo->type = uport->type;
651 tmp.line = uport->line; 646 retinfo->line = uport->line;
652 tmp.port = uport->iobase; 647 retinfo->port = uport->iobase;
653 if (HIGH_BITS_OFFSET) 648 if (HIGH_BITS_OFFSET)
654 tmp.port_high = (long) uport->iobase >> HIGH_BITS_OFFSET; 649 retinfo->port_high = (long) uport->iobase >> HIGH_BITS_OFFSET;
655 tmp.irq = uport->irq; 650 retinfo->irq = uport->irq;
656 tmp.flags = uport->flags; 651 retinfo->flags = uport->flags;
657 tmp.xmit_fifo_size = uport->fifosize; 652 retinfo->xmit_fifo_size = uport->fifosize;
658 tmp.baud_base = uport->uartclk / 16; 653 retinfo->baud_base = uport->uartclk / 16;
659 tmp.close_delay = jiffies_to_msecs(port->close_delay) / 10; 654 retinfo->close_delay = jiffies_to_msecs(port->close_delay) / 10;
660 tmp.closing_wait = port->closing_wait == ASYNC_CLOSING_WAIT_NONE ? 655 retinfo->closing_wait = port->closing_wait == ASYNC_CLOSING_WAIT_NONE ?
661 ASYNC_CLOSING_WAIT_NONE : 656 ASYNC_CLOSING_WAIT_NONE :
662 jiffies_to_msecs(port->closing_wait) / 10; 657 jiffies_to_msecs(port->closing_wait) / 10;
663 tmp.custom_divisor = uport->custom_divisor; 658 retinfo->custom_divisor = uport->custom_divisor;
664 tmp.hub6 = uport->hub6; 659 retinfo->hub6 = uport->hub6;
665 tmp.io_type = uport->iotype; 660 retinfo->io_type = uport->iotype;
666 tmp.iomem_reg_shift = uport->regshift; 661 retinfo->iomem_reg_shift = uport->regshift;
667 tmp.iomem_base = (void *)(unsigned long)uport->mapbase; 662 retinfo->iomem_base = (void *)(unsigned long)uport->mapbase;
663}
664
665static int uart_get_info_user(struct uart_state *state,
666 struct serial_struct __user *retinfo)
667{
668 struct tty_port *port = &state->port;
669 struct serial_struct tmp;
668 670
671 /* Ensure the state we copy is consistent and no hardware changes
672 occur as we go */
673 mutex_lock(&port->mutex);
674 uart_get_info(port, state, &tmp);
669 mutex_unlock(&port->mutex); 675 mutex_unlock(&port->mutex);
670 676
671 if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) 677 if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
@@ -673,42 +679,30 @@ static int uart_get_info(struct uart_state *state,
673 return 0; 679 return 0;
674} 680}
675 681
676static int uart_set_info(struct tty_struct *tty, struct uart_state *state, 682static int uart_set_info(struct tty_struct *tty, struct tty_port *port,
677 struct serial_struct __user *newinfo) 683 struct uart_state *state,
684 struct serial_struct *new_info)
678{ 685{
679 struct serial_struct new_serial;
680 struct uart_port *uport = state->uart_port; 686 struct uart_port *uport = state->uart_port;
681 struct tty_port *port = &state->port;
682 unsigned long new_port; 687 unsigned long new_port;
683 unsigned int change_irq, change_port, closing_wait; 688 unsigned int change_irq, change_port, closing_wait;
684 unsigned int old_custom_divisor, close_delay; 689 unsigned int old_custom_divisor, close_delay;
685 upf_t old_flags, new_flags; 690 upf_t old_flags, new_flags;
686 int retval = 0; 691 int retval = 0;
687 692
688 if (copy_from_user(&new_serial, newinfo, sizeof(new_serial))) 693 new_port = new_info->port;
689 return -EFAULT;
690
691 new_port = new_serial.port;
692 if (HIGH_BITS_OFFSET) 694 if (HIGH_BITS_OFFSET)
693 new_port += (unsigned long) new_serial.port_high << HIGH_BITS_OFFSET; 695 new_port += (unsigned long) new_info->port_high << HIGH_BITS_OFFSET;
694 696
695 new_serial.irq = irq_canonicalize(new_serial.irq); 697 new_info->irq = irq_canonicalize(new_info->irq);
696 close_delay = msecs_to_jiffies(new_serial.close_delay * 10); 698 close_delay = msecs_to_jiffies(new_info->close_delay * 10);
697 closing_wait = new_serial.closing_wait == ASYNC_CLOSING_WAIT_NONE ? 699 closing_wait = new_info->closing_wait == ASYNC_CLOSING_WAIT_NONE ?
698 ASYNC_CLOSING_WAIT_NONE : 700 ASYNC_CLOSING_WAIT_NONE :
699 msecs_to_jiffies(new_serial.closing_wait * 10); 701 msecs_to_jiffies(new_info->closing_wait * 10);
700 702
701 /*
702 * This semaphore protects port->count. It is also
703 * very useful to prevent opens. Also, take the
704 * port configuration semaphore to make sure that a
705 * module insertion/removal doesn't change anything
706 * under us.
707 */
708 mutex_lock(&port->mutex);
709 703
710 change_irq = !(uport->flags & UPF_FIXED_PORT) 704 change_irq = !(uport->flags & UPF_FIXED_PORT)
711 && new_serial.irq != uport->irq; 705 && new_info->irq != uport->irq;
712 706
713 /* 707 /*
714 * Since changing the 'type' of the port changes its resource 708 * Since changing the 'type' of the port changes its resource
@@ -717,29 +711,29 @@ static int uart_set_info(struct tty_struct *tty, struct uart_state *state,
717 */ 711 */
718 change_port = !(uport->flags & UPF_FIXED_PORT) 712 change_port = !(uport->flags & UPF_FIXED_PORT)
719 && (new_port != uport->iobase || 713 && (new_port != uport->iobase ||
720 (unsigned long)new_serial.iomem_base != uport->mapbase || 714 (unsigned long)new_info->iomem_base != uport->mapbase ||
721 new_serial.hub6 != uport->hub6 || 715 new_info->hub6 != uport->hub6 ||
722 new_serial.io_type != uport->iotype || 716 new_info->io_type != uport->iotype ||
723 new_serial.iomem_reg_shift != uport->regshift || 717 new_info->iomem_reg_shift != uport->regshift ||
724 new_serial.type != uport->type); 718 new_info->type != uport->type);
725 719
726 old_flags = uport->flags; 720 old_flags = uport->flags;
727 new_flags = new_serial.flags; 721 new_flags = new_info->flags;
728 old_custom_divisor = uport->custom_divisor; 722 old_custom_divisor = uport->custom_divisor;
729 723
730 if (!capable(CAP_SYS_ADMIN)) { 724 if (!capable(CAP_SYS_ADMIN)) {
731 retval = -EPERM; 725 retval = -EPERM;
732 if (change_irq || change_port || 726 if (change_irq || change_port ||
733 (new_serial.baud_base != uport->uartclk / 16) || 727 (new_info->baud_base != uport->uartclk / 16) ||
734 (close_delay != port->close_delay) || 728 (close_delay != port->close_delay) ||
735 (closing_wait != port->closing_wait) || 729 (closing_wait != port->closing_wait) ||
736 (new_serial.xmit_fifo_size && 730 (new_info->xmit_fifo_size &&
737 new_serial.xmit_fifo_size != uport->fifosize) || 731 new_info->xmit_fifo_size != uport->fifosize) ||
738 (((new_flags ^ old_flags) & ~UPF_USR_MASK) != 0)) 732 (((new_flags ^ old_flags) & ~UPF_USR_MASK) != 0))
739 goto exit; 733 goto exit;
740 uport->flags = ((uport->flags & ~UPF_USR_MASK) | 734 uport->flags = ((uport->flags & ~UPF_USR_MASK) |
741 (new_flags & UPF_USR_MASK)); 735 (new_flags & UPF_USR_MASK));
742 uport->custom_divisor = new_serial.custom_divisor; 736 uport->custom_divisor = new_info->custom_divisor;
743 goto check_and_exit; 737 goto check_and_exit;
744 } 738 }
745 739
@@ -747,10 +741,10 @@ static int uart_set_info(struct tty_struct *tty, struct uart_state *state,
747 * Ask the low level driver to verify the settings. 741 * Ask the low level driver to verify the settings.
748 */ 742 */
749 if (uport->ops->verify_port) 743 if (uport->ops->verify_port)
750 retval = uport->ops->verify_port(uport, &new_serial); 744 retval = uport->ops->verify_port(uport, new_info);
751 745
752 if ((new_serial.irq >= nr_irqs) || (new_serial.irq < 0) || 746 if ((new_info->irq >= nr_irqs) || (new_info->irq < 0) ||
753 (new_serial.baud_base < 9600)) 747 (new_info->baud_base < 9600))
754 retval = -EINVAL; 748 retval = -EINVAL;
755 749
756 if (retval) 750 if (retval)
@@ -790,11 +784,11 @@ static int uart_set_info(struct tty_struct *tty, struct uart_state *state,
790 uport->ops->release_port(uport); 784 uport->ops->release_port(uport);
791 785
792 uport->iobase = new_port; 786 uport->iobase = new_port;
793 uport->type = new_serial.type; 787 uport->type = new_info->type;
794 uport->hub6 = new_serial.hub6; 788 uport->hub6 = new_info->hub6;
795 uport->iotype = new_serial.io_type; 789 uport->iotype = new_info->io_type;
796 uport->regshift = new_serial.iomem_reg_shift; 790 uport->regshift = new_info->iomem_reg_shift;
797 uport->mapbase = (unsigned long)new_serial.iomem_base; 791 uport->mapbase = (unsigned long)new_info->iomem_base;
798 792
799 /* 793 /*
800 * Claim and map the new regions 794 * Claim and map the new regions
@@ -835,16 +829,16 @@ static int uart_set_info(struct tty_struct *tty, struct uart_state *state,
835 } 829 }
836 830
837 if (change_irq) 831 if (change_irq)
838 uport->irq = new_serial.irq; 832 uport->irq = new_info->irq;
839 if (!(uport->flags & UPF_FIXED_PORT)) 833 if (!(uport->flags & UPF_FIXED_PORT))
840 uport->uartclk = new_serial.baud_base * 16; 834 uport->uartclk = new_info->baud_base * 16;
841 uport->flags = (uport->flags & ~UPF_CHANGE_MASK) | 835 uport->flags = (uport->flags & ~UPF_CHANGE_MASK) |
842 (new_flags & UPF_CHANGE_MASK); 836 (new_flags & UPF_CHANGE_MASK);
843 uport->custom_divisor = new_serial.custom_divisor; 837 uport->custom_divisor = new_info->custom_divisor;
844 port->close_delay = close_delay; 838 port->close_delay = close_delay;
845 port->closing_wait = closing_wait; 839 port->closing_wait = closing_wait;
846 if (new_serial.xmit_fifo_size) 840 if (new_info->xmit_fifo_size)
847 uport->fifosize = new_serial.xmit_fifo_size; 841 uport->fifosize = new_info->xmit_fifo_size;
848 if (port->tty) 842 if (port->tty)
849 port->tty->low_latency = 843 port->tty->low_latency =
850 (uport->flags & UPF_LOW_LATENCY) ? 1 : 0; 844 (uport->flags & UPF_LOW_LATENCY) ? 1 : 0;
@@ -873,6 +867,28 @@ static int uart_set_info(struct tty_struct *tty, struct uart_state *state,
873 } else 867 } else
874 retval = uart_startup(tty, state, 1); 868 retval = uart_startup(tty, state, 1);
875 exit: 869 exit:
870 return retval;
871}
872
873static int uart_set_info_user(struct tty_struct *tty, struct uart_state *state,
874 struct serial_struct __user *newinfo)
875{
876 struct serial_struct new_serial;
877 struct tty_port *port = &state->port;
878 int retval;
879
880 if (copy_from_user(&new_serial, newinfo, sizeof(new_serial)))
881 return -EFAULT;
882
883 /*
884 * This semaphore protects port->count. It is also
885 * very useful to prevent opens. Also, take the
886 * port configuration semaphore to make sure that a
887 * module insertion/removal doesn't change anything
888 * under us.
889 */
890 mutex_lock(&port->mutex);
891 retval = uart_set_info(tty, port, state, &new_serial);
876 mutex_unlock(&port->mutex); 892 mutex_unlock(&port->mutex);
877 return retval; 893 return retval;
878} 894}
@@ -1115,11 +1131,11 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd,
1115 */ 1131 */
1116 switch (cmd) { 1132 switch (cmd) {
1117 case TIOCGSERIAL: 1133 case TIOCGSERIAL:
1118 ret = uart_get_info(state, uarg); 1134 ret = uart_get_info_user(state, uarg);
1119 break; 1135 break;
1120 1136
1121 case TIOCSSERIAL: 1137 case TIOCSSERIAL:
1122 ret = uart_set_info(tty, state, uarg); 1138 ret = uart_set_info_user(tty, state, uarg);
1123 break; 1139 break;
1124 1140
1125 case TIOCSERCONFIG: 1141 case TIOCSERCONFIG: