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; |