Commit bd4217d8 authored by Jean Delvare's avatar Jean Delvare Committed by Jean Delvare

i2c-dev: Unbound new-style i2c clients aren't busy

Let i2c-dev deal properly with new-style i2c clients. Instead of
considering them always busy, it needs to check wether a driver is
bound to them or not.

This is still not completely correct, as the client could become
busy later, but the same problem already existed before new-style
clients were introduced. We'll want to fix it someday.
Signed-off-by: default avatarJean Delvare <khali@linux-fr.org>
Acked-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
parent 907135aa
...@@ -182,6 +182,29 @@ static ssize_t i2cdev_write (struct file *file, const char __user *buf, size_t c ...@@ -182,6 +182,29 @@ static ssize_t i2cdev_write (struct file *file, const char __user *buf, size_t c
return ret; return ret;
} }
/* This address checking function differs from the one in i2c-core
in that it considers an address with a registered device, but no
bounded driver, as NOT busy. */
static int i2cdev_check_addr(struct i2c_adapter *adapter, unsigned int addr)
{
struct list_head *item;
struct i2c_client *client;
int res = 0;
mutex_lock(&adapter->clist_lock);
list_for_each(item, &adapter->clients) {
client = list_entry(item, struct i2c_client, list);
if (client->addr == addr) {
if (client->driver)
res = -EBUSY;
break;
}
}
mutex_unlock(&adapter->clist_lock);
return res;
}
static int i2cdev_ioctl(struct inode *inode, struct file *file, static int i2cdev_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
...@@ -213,8 +236,9 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file, ...@@ -213,8 +236,9 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file,
if ((arg > 0x3ff) || if ((arg > 0x3ff) ||
(((client->flags & I2C_M_TEN) == 0) && arg > 0x7f)) (((client->flags & I2C_M_TEN) == 0) && arg > 0x7f))
return -EINVAL; return -EINVAL;
if ((cmd == I2C_SLAVE) && i2c_check_addr(client->adapter,arg)) if (cmd == I2C_SLAVE && i2cdev_check_addr(client->adapter, arg))
return -EBUSY; return -EBUSY;
/* REVISIT: address could become busy later */
client->addr = arg; client->addr = arg;
return 0; return 0;
case I2C_TENBIT: case I2C_TENBIT:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment