From: Alan Cox <alan@lxorguk.ukuu.org.uk>
To: i2c@lm-sensors.org, linux-kernel@vger.kernel.org
Subject: [PATCH] i2c: Push ioctl BKL down into the i2c code
Date: Thu, 22 May 2008 22:23:27 +0100 [thread overview]
Message-ID: <20080522222327.1af72794@core> (raw)
Signed-off-by: Alan Cox <alan@redhat.com>
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
index d34c14c..16cf0f2 100644
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
@@ -34,7 +34,8 @@
#include <linux/list.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
-#include <asm/uaccess.h>
+#include <linux/smp_lock.h>
+#include <linux/uaccess.h>
static struct i2c_driver i2cdev_driver;
@@ -266,8 +267,9 @@ static noinline int i2cdev_ioctl_rdrw(struct i2c_client *client,
kfree(rdwr_pa);
return res;
}
-
+ lock_kernel();
res = i2c_transfer(client->adapter, rdwr_pa, rdwr_arg.nmsgs);
+ unlock_kernel();
while (i-- > 0) {
if (res >= 0 && (rdwr_pa[i].flags & I2C_M_RD)) {
if (copy_to_user(data_ptrs[i], rdwr_pa[i].buf,
@@ -320,11 +322,15 @@ static noinline int i2cdev_ioctl_smbus(struct i2c_client *client,
if ((data_arg.size == I2C_SMBUS_QUICK) ||
((data_arg.size == I2C_SMBUS_BYTE) &&
- (data_arg.read_write == I2C_SMBUS_WRITE)))
+ (data_arg.read_write == I2C_SMBUS_WRITE))) {
/* These are special: we do not use data */
- return i2c_smbus_xfer(client->adapter, client->addr,
+ lock_kernel();
+ res =i2c_smbus_xfer(client->adapter, client->addr,
client->flags, data_arg.read_write,
data_arg.command, data_arg.size, NULL);
+ unlock_kernel();
+ return res;
+ }
if (data_arg.data == NULL) {
dev_dbg(&client->adapter->dev,
@@ -355,8 +361,10 @@ static noinline int i2cdev_ioctl_smbus(struct i2c_client *client,
if (data_arg.read_write == I2C_SMBUS_READ)
temp.block[0] = I2C_SMBUS_BLOCK_MAX;
}
+ lock_kernel();
res = i2c_smbus_xfer(client->adapter, client->addr, client->flags,
data_arg.read_write, data_arg.command, data_arg.size, &temp);
+ unlock_kernel();
if (!res && ((data_arg.size == I2C_SMBUS_PROC_CALL) ||
(data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) ||
(data_arg.read_write == I2C_SMBUS_READ))) {
@@ -366,11 +374,12 @@ static noinline int i2cdev_ioctl_smbus(struct i2c_client *client,
return res;
}
-static int i2cdev_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static long i2cdev_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
{
struct i2c_client *client = (struct i2c_client *)file->private_data;
unsigned long funcs;
+ int ret = 0;
dev_dbg(&client->adapter->dev, "ioctl, cmd=0x%02x, arg=0x%02lx\n",
cmd, arg);
@@ -388,28 +397,37 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file,
* the PEC flag already set, the i2c-dev driver won't see
* (or use) this setting.
*/
+ lock_kernel();
if ((arg > 0x3ff) ||
(((client->flags & I2C_M_TEN) == 0) && arg > 0x7f))
- return -EINVAL;
- if (cmd == I2C_SLAVE && i2cdev_check_addr(client->adapter, arg))
- return -EBUSY;
- /* REVISIT: address could become busy later */
- client->addr = arg;
- return 0;
+ ret = -EINVAL;
+ else if (cmd == I2C_SLAVE &&
+ i2cdev_check_addr(client->adapter, arg))
+ ret = -EBUSY;
+ else
+ /* REVISIT: address could become busy later */
+ client->addr = arg;
+ return ret;
case I2C_TENBIT:
+ lock_kernel();
if (arg)
client->flags |= I2C_M_TEN;
else
client->flags &= ~I2C_M_TEN;
+ unlock_kernel();
return 0;
case I2C_PEC:
+ lock_kernel();
if (arg)
client->flags |= I2C_CLIENT_PEC;
else
client->flags &= ~I2C_CLIENT_PEC;
+ unlock_kernel();
return 0;
case I2C_FUNCS:
+ lock_kernel();
funcs = i2c_get_functionality(client->adapter);
+ unlock_kernel();
return put_user(funcs, (unsigned long __user *)arg);
case I2C_RDWR:
@@ -419,10 +437,14 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file,
return i2cdev_ioctl_smbus(client, arg);
case I2C_RETRIES:
+ lock_kernel();
client->adapter->retries = arg;
+ unlock_kernel();
break;
case I2C_TIMEOUT:
+ lock_kernel();
client->adapter->timeout = arg;
+ unlock_kernel();
break;
default:
/* NOTE: returning a fault code here could cause trouble
@@ -487,7 +509,7 @@ static const struct file_operations i2cdev_fops = {
.llseek = no_llseek,
.read = i2cdev_read,
.write = i2cdev_write,
- .ioctl = i2cdev_ioctl,
+ .unlocked_ioctl = i2cdev_ioctl,
.open = i2cdev_open,
.release = i2cdev_release,
};
next reply other threads:[~2008-05-22 21:38 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-05-22 21:23 Alan Cox [this message]
2008-05-23 7:35 ` [PATCH] i2c: Push ioctl BKL down into the i2c code Jean Delvare
2008-05-23 8:46 ` Stefan Richter
2008-05-23 17:53 ` Jean Delvare
2008-05-23 18:08 ` Stefan Richter
2008-05-23 10:46 ` Alan Cox
2008-05-23 14:01 ` [i2c] " Jon Smirl
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20080522222327.1af72794@core \
--to=alan@lxorguk.ukuu.org.uk \
--cc=i2c@lm-sensors.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox