Ver Fonte

tty: Drop the lock_kernel in the private ioctl hook

We don't need the BKL here any more so it can go. In a couple of spots the
driver requirements are not clear so push the lock down into the driver.

Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Alan Cox há 16 anos atrás
pai
commit
6b447f04a9

+ 8 - 1
drivers/usb/serial/ftdi_sio.c

@@ -1054,6 +1054,8 @@ static int set_serial_info(struct tty_struct *tty,
 
 
 	if (copy_from_user(&new_serial, newinfo, sizeof(new_serial)))
 	if (copy_from_user(&new_serial, newinfo, sizeof(new_serial)))
 		return -EFAULT;
 		return -EFAULT;
+
+	lock_kernel();
 	old_priv = *priv;
 	old_priv = *priv;
 
 
 	/* Do error checking and permission checking */
 	/* Do error checking and permission checking */
@@ -1069,8 +1071,10 @@ static int set_serial_info(struct tty_struct *tty,
 	}
 	}
 
 
 	if ((new_serial.baud_base != priv->baud_base) &&
 	if ((new_serial.baud_base != priv->baud_base) &&
-	    (new_serial.baud_base < 9600))
+	    (new_serial.baud_base < 9600)) {
+	    	unlock_kernel();
 		return -EINVAL;
 		return -EINVAL;
+	}
 
 
 	/* Make the changes - these are privileged changes! */
 	/* Make the changes - these are privileged changes! */
 
 
@@ -1098,8 +1102,11 @@ check_and_exit:
 	     (priv->flags & ASYNC_SPD_MASK)) ||
 	     (priv->flags & ASYNC_SPD_MASK)) ||
 	    (((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) &&
 	    (((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) &&
 	     (old_priv.custom_divisor != priv->custom_divisor))) {
 	     (old_priv.custom_divisor != priv->custom_divisor))) {
+		unlock_kernel();
 		change_speed(tty, port);
 		change_speed(tty, port);
 	}
 	}
+	else
+		unlock_kernel();
 	return 0;
 	return 0;
 
 
 } /* set_serial_info */
 } /* set_serial_info */

+ 1 - 0
drivers/usb/serial/kl5kusb105.c

@@ -878,6 +878,7 @@ static void mct_u232_break_ctl(struct tty_struct *tty, int break_state)
 
 
 	dbg("%sstate=%d", __func__, break_state);
 	dbg("%sstate=%d", __func__, break_state);
 
 
+	/* LOCKING */
 	if (break_state)
 	if (break_state)
 		lcr |= MCT_U232_SET_BREAK;
 		lcr |= MCT_U232_SET_BREAK;
 
 

+ 1 - 1
drivers/usb/serial/mct_u232.c

@@ -721,10 +721,10 @@ static void mct_u232_break_ctl(struct tty_struct *tty, int break_state)
 
 
 	spin_lock_irqsave(&priv->lock, flags);
 	spin_lock_irqsave(&priv->lock, flags);
 	lcr = priv->last_lcr;
 	lcr = priv->last_lcr;
-	spin_unlock_irqrestore(&priv->lock, flags);
 
 
 	if (break_state)
 	if (break_state)
 		lcr |= MCT_U232_SET_BREAK;
 		lcr |= MCT_U232_SET_BREAK;
+	spin_unlock_irqrestore(&priv->lock, flags);
 
 
 	mct_u232_set_line_ctrl(serial, lcr);
 	mct_u232_set_line_ctrl(serial, lcr);
 } /* mct_u232_break_ctl */
 } /* mct_u232_break_ctl */

+ 3 - 0
drivers/usb/serial/mos7840.c

@@ -1343,6 +1343,7 @@ static void mos7840_break(struct tty_struct *tty, int break_state)
 	else
 	else
 		data = mos7840_port->shadowLCR & ~LCR_SET_BREAK;
 		data = mos7840_port->shadowLCR & ~LCR_SET_BREAK;
 
 
+	/* FIXME: no locking on shadowLCR anywhere in driver */
 	mos7840_port->shadowLCR = data;
 	mos7840_port->shadowLCR = data;
 	dbg("mcs7840_break mos7840_port->shadowLCR is %x\n",
 	dbg("mcs7840_break mos7840_port->shadowLCR is %x\n",
 	    mos7840_port->shadowLCR);
 	    mos7840_port->shadowLCR);
@@ -2214,10 +2215,12 @@ static int mos7840_set_modem_info(struct moschip_port *mos7840_port,
 		break;
 		break;
 	}
 	}
 
 
+	lock_kernel();
 	mos7840_port->shadowMCR = mcr;
 	mos7840_port->shadowMCR = mcr;
 
 
 	Data = mos7840_port->shadowMCR;
 	Data = mos7840_port->shadowMCR;
 	status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
 	status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
+	unlock_kernel();
 	if (status < 0) {
 	if (status < 0) {
 		dbg("setting MODEM_CONTROL_REGISTER Failed\n");
 		dbg("setting MODEM_CONTROL_REGISTER Failed\n");
 		return -1;
 		return -1;

+ 1 - 6
drivers/usb/serial/usb-serial.c

@@ -382,9 +382,7 @@ static int serial_ioctl(struct tty_struct *tty, struct file *file,
 	/* pass on to the driver specific version of this function
 	/* pass on to the driver specific version of this function
 	   if it is available */
 	   if it is available */
 	if (port->serial->type->ioctl) {
 	if (port->serial->type->ioctl) {
-		lock_kernel();
 		retval = port->serial->type->ioctl(tty, file, cmd, arg);
 		retval = port->serial->type->ioctl(tty, file, cmd, arg);
-		unlock_kernel();
 	} else
 	} else
 		retval = -ENOIOCTLCMD;
 		retval = -ENOIOCTLCMD;
 	return retval;
 	return retval;
@@ -413,11 +411,8 @@ static int serial_break(struct tty_struct *tty, int break_state)
 	WARN_ON(!port->port.count);
 	WARN_ON(!port->port.count);
 	/* pass on to the driver specific version of this function
 	/* pass on to the driver specific version of this function
 	   if it is available */
 	   if it is available */
-	if (port->serial->type->break_ctl) {
-		lock_kernel();
+	if (port->serial->type->break_ctl)
 		port->serial->type->break_ctl(tty, break_state);
 		port->serial->type->break_ctl(tty, break_state);
-		unlock_kernel();
-	}
 	return 0;
 	return 0;
 }
 }