diff options
Diffstat (limited to 'drivers/i2c/i2c-dev.c')
| -rw-r--r-- | drivers/i2c/i2c-dev.c | 44 |
1 files changed, 21 insertions, 23 deletions
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index 2e22a2ffa606..ac5bd2a7ca99 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | i2c-dev.c - i2c-bus driver, char device interface | 2 | i2c-dev.c - i2c-bus driver, char device interface |
| 3 | 3 | ||
| 4 | Copyright (C) 1995-97 Simon G. Vogl | 4 | Copyright (C) 1995-97 Simon G. Vogl |
| 5 | Copyright (C) 1998-99 Frodo Looijaard <frodol@dds.nl> | 5 | Copyright (C) 1998-99 Frodo Looijaard <frodol@dds.nl> |
| @@ -90,6 +90,7 @@ static void return_i2c_dev(struct i2c_dev *i2c_dev) | |||
| 90 | spin_lock(&i2c_dev_list_lock); | 90 | spin_lock(&i2c_dev_list_lock); |
| 91 | list_del(&i2c_dev->list); | 91 | list_del(&i2c_dev->list); |
| 92 | spin_unlock(&i2c_dev_list_lock); | 92 | spin_unlock(&i2c_dev_list_lock); |
| 93 | kfree(i2c_dev); | ||
| 93 | } | 94 | } |
| 94 | 95 | ||
| 95 | static ssize_t show_adapter_name(struct device *dev, | 96 | static ssize_t show_adapter_name(struct device *dev, |
| @@ -172,7 +173,7 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file, | |||
| 172 | switch ( cmd ) { | 173 | switch ( cmd ) { |
| 173 | case I2C_SLAVE: | 174 | case I2C_SLAVE: |
| 174 | case I2C_SLAVE_FORCE: | 175 | case I2C_SLAVE_FORCE: |
| 175 | if ((arg > 0x3ff) || | 176 | if ((arg > 0x3ff) || |
| 176 | (((client->flags & I2C_M_TEN) == 0) && arg > 0x7f)) | 177 | (((client->flags & I2C_M_TEN) == 0) && arg > 0x7f)) |
| 177 | return -EINVAL; | 178 | return -EINVAL; |
| 178 | if ((cmd == I2C_SLAVE) && i2c_check_addr(client->adapter,arg)) | 179 | if ((cmd == I2C_SLAVE) && i2c_check_addr(client->adapter,arg)) |
| @@ -193,12 +194,11 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file, | |||
| 193 | return 0; | 194 | return 0; |
| 194 | case I2C_FUNCS: | 195 | case I2C_FUNCS: |
| 195 | funcs = i2c_get_functionality(client->adapter); | 196 | funcs = i2c_get_functionality(client->adapter); |
| 196 | return (copy_to_user((unsigned long __user *)arg, &funcs, | 197 | return put_user(funcs, (unsigned long __user *)arg); |
| 197 | sizeof(unsigned long)))?-EFAULT:0; | ||
| 198 | 198 | ||
| 199 | case I2C_RDWR: | 199 | case I2C_RDWR: |
| 200 | if (copy_from_user(&rdwr_arg, | 200 | if (copy_from_user(&rdwr_arg, |
| 201 | (struct i2c_rdwr_ioctl_data __user *)arg, | 201 | (struct i2c_rdwr_ioctl_data __user *)arg, |
| 202 | sizeof(rdwr_arg))) | 202 | sizeof(rdwr_arg))) |
| 203 | return -EFAULT; | 203 | return -EFAULT; |
| 204 | 204 | ||
| @@ -206,9 +206,9 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file, | |||
| 206 | * be sent at once */ | 206 | * be sent at once */ |
| 207 | if (rdwr_arg.nmsgs > I2C_RDRW_IOCTL_MAX_MSGS) | 207 | if (rdwr_arg.nmsgs > I2C_RDRW_IOCTL_MAX_MSGS) |
| 208 | return -EINVAL; | 208 | return -EINVAL; |
| 209 | 209 | ||
| 210 | rdwr_pa = (struct i2c_msg *) | 210 | rdwr_pa = (struct i2c_msg *) |
| 211 | kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg), | 211 | kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg), |
| 212 | GFP_KERNEL); | 212 | GFP_KERNEL); |
| 213 | 213 | ||
| 214 | if (rdwr_pa == NULL) return -ENOMEM; | 214 | if (rdwr_pa == NULL) return -ENOMEM; |
| @@ -278,9 +278,9 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file, | |||
| 278 | (struct i2c_smbus_ioctl_data __user *) arg, | 278 | (struct i2c_smbus_ioctl_data __user *) arg, |
| 279 | sizeof(struct i2c_smbus_ioctl_data))) | 279 | sizeof(struct i2c_smbus_ioctl_data))) |
| 280 | return -EFAULT; | 280 | return -EFAULT; |
| 281 | if ((data_arg.size != I2C_SMBUS_BYTE) && | 281 | if ((data_arg.size != I2C_SMBUS_BYTE) && |
| 282 | (data_arg.size != I2C_SMBUS_QUICK) && | 282 | (data_arg.size != I2C_SMBUS_QUICK) && |
| 283 | (data_arg.size != I2C_SMBUS_BYTE_DATA) && | 283 | (data_arg.size != I2C_SMBUS_BYTE_DATA) && |
| 284 | (data_arg.size != I2C_SMBUS_WORD_DATA) && | 284 | (data_arg.size != I2C_SMBUS_WORD_DATA) && |
| 285 | (data_arg.size != I2C_SMBUS_PROC_CALL) && | 285 | (data_arg.size != I2C_SMBUS_PROC_CALL) && |
| 286 | (data_arg.size != I2C_SMBUS_BLOCK_DATA) && | 286 | (data_arg.size != I2C_SMBUS_BLOCK_DATA) && |
| @@ -291,11 +291,11 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file, | |||
| 291 | data_arg.size); | 291 | data_arg.size); |
| 292 | return -EINVAL; | 292 | return -EINVAL; |
| 293 | } | 293 | } |
| 294 | /* Note that I2C_SMBUS_READ and I2C_SMBUS_WRITE are 0 and 1, | 294 | /* Note that I2C_SMBUS_READ and I2C_SMBUS_WRITE are 0 and 1, |
| 295 | so the check is valid if size==I2C_SMBUS_QUICK too. */ | 295 | so the check is valid if size==I2C_SMBUS_QUICK too. */ |
| 296 | if ((data_arg.read_write != I2C_SMBUS_READ) && | 296 | if ((data_arg.read_write != I2C_SMBUS_READ) && |
| 297 | (data_arg.read_write != I2C_SMBUS_WRITE)) { | 297 | (data_arg.read_write != I2C_SMBUS_WRITE)) { |
| 298 | dev_dbg(&client->adapter->dev, | 298 | dev_dbg(&client->adapter->dev, |
| 299 | "read_write out of range (%x) in ioctl I2C_SMBUS.\n", | 299 | "read_write out of range (%x) in ioctl I2C_SMBUS.\n", |
| 300 | data_arg.read_write); | 300 | data_arg.read_write); |
| 301 | return -EINVAL; | 301 | return -EINVAL; |
| @@ -304,7 +304,7 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file, | |||
| 304 | /* Note that command values are always valid! */ | 304 | /* Note that command values are always valid! */ |
| 305 | 305 | ||
| 306 | if ((data_arg.size == I2C_SMBUS_QUICK) || | 306 | if ((data_arg.size == I2C_SMBUS_QUICK) || |
| 307 | ((data_arg.size == I2C_SMBUS_BYTE) && | 307 | ((data_arg.size == I2C_SMBUS_BYTE) && |
| 308 | (data_arg.read_write == I2C_SMBUS_WRITE))) | 308 | (data_arg.read_write == I2C_SMBUS_WRITE))) |
| 309 | /* These are special: we do not use data */ | 309 | /* These are special: we do not use data */ |
| 310 | return i2c_smbus_xfer(client->adapter, client->addr, | 310 | return i2c_smbus_xfer(client->adapter, client->addr, |
| @@ -322,14 +322,14 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file, | |||
| 322 | if ((data_arg.size == I2C_SMBUS_BYTE_DATA) || | 322 | if ((data_arg.size == I2C_SMBUS_BYTE_DATA) || |
| 323 | (data_arg.size == I2C_SMBUS_BYTE)) | 323 | (data_arg.size == I2C_SMBUS_BYTE)) |
| 324 | datasize = sizeof(data_arg.data->byte); | 324 | datasize = sizeof(data_arg.data->byte); |
| 325 | else if ((data_arg.size == I2C_SMBUS_WORD_DATA) || | 325 | else if ((data_arg.size == I2C_SMBUS_WORD_DATA) || |
| 326 | (data_arg.size == I2C_SMBUS_PROC_CALL)) | 326 | (data_arg.size == I2C_SMBUS_PROC_CALL)) |
| 327 | datasize = sizeof(data_arg.data->word); | 327 | datasize = sizeof(data_arg.data->word); |
| 328 | else /* size == smbus block, i2c block, or block proc. call */ | 328 | else /* size == smbus block, i2c block, or block proc. call */ |
| 329 | datasize = sizeof(data_arg.data->block); | 329 | datasize = sizeof(data_arg.data->block); |
| 330 | 330 | ||
| 331 | if ((data_arg.size == I2C_SMBUS_PROC_CALL) || | 331 | if ((data_arg.size == I2C_SMBUS_PROC_CALL) || |
| 332 | (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) || | 332 | (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) || |
| 333 | (data_arg.read_write == I2C_SMBUS_WRITE)) { | 333 | (data_arg.read_write == I2C_SMBUS_WRITE)) { |
| 334 | if (copy_from_user(&temp, data_arg.data, datasize)) | 334 | if (copy_from_user(&temp, data_arg.data, datasize)) |
| 335 | return -EFAULT; | 335 | return -EFAULT; |
| @@ -337,8 +337,8 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file, | |||
| 337 | res = i2c_smbus_xfer(client->adapter,client->addr,client->flags, | 337 | res = i2c_smbus_xfer(client->adapter,client->addr,client->flags, |
| 338 | data_arg.read_write, | 338 | data_arg.read_write, |
| 339 | data_arg.command,data_arg.size,&temp); | 339 | data_arg.command,data_arg.size,&temp); |
| 340 | if (! res && ((data_arg.size == I2C_SMBUS_PROC_CALL) || | 340 | if (! res && ((data_arg.size == I2C_SMBUS_PROC_CALL) || |
| 341 | (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) || | 341 | (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) || |
| 342 | (data_arg.read_write == I2C_SMBUS_READ))) { | 342 | (data_arg.read_write == I2C_SMBUS_READ))) { |
| 343 | if (copy_to_user(data_arg.data, &temp, datasize)) | 343 | if (copy_to_user(data_arg.data, &temp, datasize)) |
| 344 | return -EFAULT; | 344 | return -EFAULT; |
| @@ -417,8 +417,8 @@ static int i2cdev_attach_adapter(struct i2c_adapter *adap) | |||
| 417 | i2c_dev->dev = device_create(i2c_dev_class, &adap->dev, | 417 | i2c_dev->dev = device_create(i2c_dev_class, &adap->dev, |
| 418 | MKDEV(I2C_MAJOR, adap->nr), | 418 | MKDEV(I2C_MAJOR, adap->nr), |
| 419 | "i2c-%d", adap->nr); | 419 | "i2c-%d", adap->nr); |
| 420 | if (!i2c_dev->dev) { | 420 | if (IS_ERR(i2c_dev->dev)) { |
| 421 | res = -ENODEV; | 421 | res = PTR_ERR(i2c_dev->dev); |
| 422 | goto error; | 422 | goto error; |
| 423 | } | 423 | } |
| 424 | res = device_create_file(i2c_dev->dev, &dev_attr_name); | 424 | res = device_create_file(i2c_dev->dev, &dev_attr_name); |
| @@ -432,7 +432,6 @@ error_destroy: | |||
| 432 | device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr)); | 432 | device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr)); |
| 433 | error: | 433 | error: |
| 434 | return_i2c_dev(i2c_dev); | 434 | return_i2c_dev(i2c_dev); |
| 435 | kfree(i2c_dev); | ||
| 436 | return res; | 435 | return res; |
| 437 | } | 436 | } |
| 438 | 437 | ||
| @@ -447,7 +446,6 @@ static int i2cdev_detach_adapter(struct i2c_adapter *adap) | |||
| 447 | device_remove_file(i2c_dev->dev, &dev_attr_name); | 446 | device_remove_file(i2c_dev->dev, &dev_attr_name); |
| 448 | return_i2c_dev(i2c_dev); | 447 | return_i2c_dev(i2c_dev); |
| 449 | device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr)); | 448 | device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr)); |
| 450 | kfree(i2c_dev); | ||
| 451 | 449 | ||
| 452 | pr_debug("i2c-dev: adapter [%s] unregistered\n", adap->name); | 450 | pr_debug("i2c-dev: adapter [%s] unregistered\n", adap->name); |
| 453 | return 0; | 451 | return 0; |
