aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/ftdi_sio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/ftdi_sio.c')
-rw-r--r--drivers/usb/serial/ftdi_sio.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 51d7bdea2869..f92f4d773374 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -143,6 +143,7 @@ static struct ftdi_sio_quirk ftdi_HE_TIRA1_quirk = {
143static struct usb_device_id id_table_combined [] = { 143static struct usb_device_id id_table_combined [] = {
144 { USB_DEVICE(FTDI_VID, FTDI_AMC232_PID) }, 144 { USB_DEVICE(FTDI_VID, FTDI_AMC232_PID) },
145 { USB_DEVICE(FTDI_VID, FTDI_CANUSB_PID) }, 145 { USB_DEVICE(FTDI_VID, FTDI_CANUSB_PID) },
146 { USB_DEVICE(FTDI_VID, FTDI_CANDAPTER_PID) },
146 { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_0_PID) }, 147 { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_0_PID) },
147 { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_1_PID) }, 148 { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_1_PID) },
148 { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_2_PID) }, 149 { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_2_PID) },
@@ -166,6 +167,7 @@ static struct usb_device_id id_table_combined [] = {
166 { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_PID) }, 167 { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_PID) },
167 { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) }, 168 { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) },
168 { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) }, 169 { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) },
170 { USB_DEVICE(FTDI_VID, FTDI_SPROG_II) },
169 { USB_DEVICE(FTDI_VID, FTDI_XF_632_PID) }, 171 { USB_DEVICE(FTDI_VID, FTDI_XF_632_PID) },
170 { USB_DEVICE(FTDI_VID, FTDI_XF_634_PID) }, 172 { USB_DEVICE(FTDI_VID, FTDI_XF_634_PID) },
171 { USB_DEVICE(FTDI_VID, FTDI_XF_547_PID) }, 173 { USB_DEVICE(FTDI_VID, FTDI_XF_547_PID) },
@@ -658,6 +660,9 @@ static struct usb_device_id id_table_combined [] = {
658 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) }, 660 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) },
659 { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DGQG_PID) }, 661 { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DGQG_PID) },
660 { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) }, 662 { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) },
663 { USB_DEVICE(ALTI2_VID, ALTI2_N3_PID) },
664 { USB_DEVICE(FTDI_VID, DIEBOLD_BCS_SE923_PID) },
665 { USB_DEVICE(FTDI_VID, FTDI_NDI_HUC_PID) },
661 { }, /* Optional parameter entry */ 666 { }, /* Optional parameter entry */
662 { } /* Terminating entry */ 667 { } /* Terminating entry */
663}; 668};
@@ -1052,14 +1057,18 @@ static int set_serial_info(struct tty_struct *tty,
1052 1057
1053 if (copy_from_user(&new_serial, newinfo, sizeof(new_serial))) 1058 if (copy_from_user(&new_serial, newinfo, sizeof(new_serial)))
1054 return -EFAULT; 1059 return -EFAULT;
1060
1061 lock_kernel();
1055 old_priv = *priv; 1062 old_priv = *priv;
1056 1063
1057 /* Do error checking and permission checking */ 1064 /* Do error checking and permission checking */
1058 1065
1059 if (!capable(CAP_SYS_ADMIN)) { 1066 if (!capable(CAP_SYS_ADMIN)) {
1060 if (((new_serial.flags & ~ASYNC_USR_MASK) != 1067 if (((new_serial.flags & ~ASYNC_USR_MASK) !=
1061 (priv->flags & ~ASYNC_USR_MASK))) 1068 (priv->flags & ~ASYNC_USR_MASK))) {
1069 unlock_kernel();
1062 return -EPERM; 1070 return -EPERM;
1071 }
1063 priv->flags = ((priv->flags & ~ASYNC_USR_MASK) | 1072 priv->flags = ((priv->flags & ~ASYNC_USR_MASK) |
1064 (new_serial.flags & ASYNC_USR_MASK)); 1073 (new_serial.flags & ASYNC_USR_MASK));
1065 priv->custom_divisor = new_serial.custom_divisor; 1074 priv->custom_divisor = new_serial.custom_divisor;
@@ -1067,8 +1076,10 @@ static int set_serial_info(struct tty_struct *tty,
1067 } 1076 }
1068 1077
1069 if ((new_serial.baud_base != priv->baud_base) && 1078 if ((new_serial.baud_base != priv->baud_base) &&
1070 (new_serial.baud_base < 9600)) 1079 (new_serial.baud_base < 9600)) {
1080 unlock_kernel();
1071 return -EINVAL; 1081 return -EINVAL;
1082 }
1072 1083
1073 /* Make the changes - these are privileged changes! */ 1084 /* Make the changes - these are privileged changes! */
1074 1085
@@ -1096,8 +1107,11 @@ check_and_exit:
1096 (priv->flags & ASYNC_SPD_MASK)) || 1107 (priv->flags & ASYNC_SPD_MASK)) ||
1097 (((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) && 1108 (((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) &&
1098 (old_priv.custom_divisor != priv->custom_divisor))) { 1109 (old_priv.custom_divisor != priv->custom_divisor))) {
1110 unlock_kernel();
1099 change_speed(tty, port); 1111 change_speed(tty, port);
1100 } 1112 }
1113 else
1114 unlock_kernel();
1101 return 0; 1115 return 0;
1102 1116
1103} /* set_serial_info */ 1117} /* set_serial_info */
@@ -1498,7 +1512,7 @@ static int ftdi_open(struct tty_struct *tty,
1498 priv->interface, buf, 0, WDR_TIMEOUT); 1512 priv->interface, buf, 0, WDR_TIMEOUT);
1499 1513
1500 /* Termios defaults are set by usb_serial_init. We don't change 1514 /* Termios defaults are set by usb_serial_init. We don't change
1501 port->tty->termios - this would loose speed settings, etc. 1515 port->tty->termios - this would lose speed settings, etc.
1502 This is same behaviour as serial.c/rs_open() - Kuba */ 1516 This is same behaviour as serial.c/rs_open() - Kuba */
1503 1517
1504 /* ftdi_set_termios will send usb control messages */ 1518 /* ftdi_set_termios will send usb control messages */
@@ -2021,7 +2035,7 @@ static void ftdi_process_read(struct work_struct *work)
2021 spin_unlock_irqrestore(&priv->rx_lock, flags); 2035 spin_unlock_irqrestore(&priv->rx_lock, flags);
2022 dbg("%s - deferring remainder until unthrottled", 2036 dbg("%s - deferring remainder until unthrottled",
2023 __func__); 2037 __func__);
2024 return; 2038 goto out;
2025 } 2039 }
2026 spin_unlock_irqrestore(&priv->rx_lock, flags); 2040 spin_unlock_irqrestore(&priv->rx_lock, flags);
2027 /* if the port is closed stop trying to read */ 2041 /* if the port is closed stop trying to read */