diff options
Diffstat (limited to 'drivers/i2c/i2c-dev.c')
-rw-r--r-- | drivers/i2c/i2c-dev.c | 605 |
1 files changed, 244 insertions, 361 deletions
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index 088d730fc..c2c51bef4 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c @@ -23,7 +23,7 @@ But I have used so much of his original code and ideas that it seems only fair to recognize him as co-author -- Frodo */ -/* $Id: i2c-dev.c,v 1.18 1999/12/21 23:45:58 frodo Exp $ */ +/* $Id: i2c-dev.c,v 1.25 2000/01/26 14:14:20 frodo Exp $ */ #include <linux/kernel.h> #include <linux/module.h> @@ -34,34 +34,8 @@ /* If you want debugging uncomment: */ /* #define DEBUG */ -#ifndef KERNEL_VERSION -#define KERNEL_VERSION(a,b,c) (((a) << 16) | ((b) << 8) | (c)) -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,51) #include <linux/init.h> -#else -#define __init -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,4)) -#define copy_from_user memcpy_fromfs -#define copy_to_user memcpy_tofs -#define get_user_data(to,from) ((to) = get_user(from),0) -#else #include <asm/uaccess.h> -#define get_user_data(to,from) get_user(to,from) -#endif - -/* 2.0.0 kernel compatibility */ -#if LINUX_VERSION_CODE < 0x020100 -#define MODULE_AUTHOR(noone) -#define MODULE_DESCRIPTION(none) -#define MODULE_PARM(no,param) -#define MODULE_PARM_DESC(no,description) -#define EXPORT_SYMBOL(noexport) -#define EXPORT_NO_SYMBOLS -#endif #include <linux/i2c.h> #include <linux/i2c-dev.h> @@ -73,45 +47,18 @@ extern int cleanup_module(void); /* struct file_operations changed too often in the 2.1 series for nice code */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,70)) static loff_t i2cdev_lseek (struct file *file, loff_t offset, int origin); -#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,56)) -static long long i2cdev_lseek (struct file *file, long long offset, int origin); -#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)) -static long long i2cdev_llseek (struct inode *inode, struct file *file, - long long offset, int origin); -#else -static int i2cdev_lseek (struct inode *inode, struct file *file, off_t offset, - int origin); -#endif -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,70)) static ssize_t i2cdev_read (struct file *file, char *buf, size_t count, loff_t *offset); static ssize_t i2cdev_write (struct file *file, const char *buf, size_t count, loff_t *offset); -#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)) -static long i2cdev_read (struct inode *inode, struct file *file, char *buf, - unsigned long count); -static long i2cdev_write (struct inode *inode, struct file *file, - const char *buf, unsigned long offset); -#else -static int i2cdev_read(struct inode *inode, struct file *file, char *buf, - int count); -static int i2cdev_write(struct inode *inode, struct file *file, - const char *buf, int count); -#endif static int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); static int i2cdev_open (struct inode *inode, struct file *file); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,31)) static int i2cdev_release (struct inode *inode, struct file *file); -#else -static void i2cdev_release (struct inode *inode, struct file *file); -#endif - static int i2cdev_attach_adapter(struct i2c_adapter *adap); static int i2cdev_detach_client(struct i2c_client *client); @@ -127,413 +74,349 @@ extern static int i2cdev_cleanup(void); static struct file_operations i2cdev_fops = { - i2cdev_lseek, - i2cdev_read, - i2cdev_write, - NULL, /* i2cdev_readdir */ - NULL, /* i2cdev_select */ - i2cdev_ioctl, - NULL, /* i2cdev_mmap */ - i2cdev_open, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,118) - NULL, /* i2cdev_flush */ -#endif - i2cdev_release, + i2cdev_lseek, + i2cdev_read, + i2cdev_write, + NULL, /* i2cdev_readdir */ + NULL, /* i2cdev_select */ + i2cdev_ioctl, + NULL, /* i2cdev_mmap */ + i2cdev_open, + NULL, /* i2cdev_flush */ + i2cdev_release, }; #define I2CDEV_ADAPS_MAX I2C_ADAP_MAX static struct i2c_adapter *i2cdev_adaps[I2CDEV_ADAPS_MAX]; static struct i2c_driver i2cdev_driver = { - /* name */ "i2c-dev dummy driver", - /* id */ I2C_DRIVERID_I2CDEV, - /* flags */ I2C_DF_DUMMY, - /* attach_adapter */ i2cdev_attach_adapter, - /* detach_client */ i2cdev_detach_client, - /* command */ i2cdev_command, - /* inc_use */ NULL, - /* dec_use */ NULL, + /* name */ "i2c-dev dummy driver", + /* id */ I2C_DRIVERID_I2CDEV, + /* flags */ I2C_DF_DUMMY, + /* attach_adapter */ i2cdev_attach_adapter, + /* detach_client */ i2cdev_detach_client, + /* command */ i2cdev_command, + /* inc_use */ NULL, + /* dec_use */ NULL, }; static struct i2c_client i2cdev_client_template = { - /* name */ "I2C /dev entry", - /* id */ 1, - /* flags */ 0, - /* addr */ -1, - /* adapter */ NULL, - /* driver */ &i2cdev_driver, - /* data */ NULL + /* name */ "I2C /dev entry", + /* id */ 1, + /* flags */ 0, + /* addr */ -1, + /* adapter */ NULL, + /* driver */ &i2cdev_driver, + /* data */ NULL }; static int i2cdev_initialized; /* Note that the lseek function is called llseek in 2.1 kernels. But things are complicated enough as is. */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,70)) loff_t i2cdev_lseek (struct file *file, loff_t offset, int origin) -#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,56)) -long long i2cdev_lseek (struct file *file, long long offset, int origin) -#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)) -long long i2cdev_llseek (struct inode *inode, struct file *file, - long long offset, int origin) -#else -int i2cdev_lseek (struct inode *inode, struct file *file, off_t offset, - int origin) -#endif { #ifdef DEBUG -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,56)) - struct inode *inode = file->f_dentry->d_inode; -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,70)) */ - printk("i2c-dev,o: i2c-%d lseek to %ld bytes relative to %d.\n", - MINOR(inode->i_rdev),(long) offset,origin); + struct inode *inode = file->f_dentry->d_inode; + printk("i2c-dev,o: i2c-%d lseek to %ld bytes relative to %d.\n", + MINOR(inode->i_rdev),(long) offset,origin); #endif /* DEBUG */ - return -ESPIPE; + return -ESPIPE; } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,70)) static ssize_t i2cdev_read (struct file *file, char *buf, size_t count, loff_t *offset) -#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)) -static long i2cdev_read (struct inode *inode, struct file *file, char *buf, - unsigned long count) -#else -static int i2cdev_read(struct inode *inode, struct file *file, char *buf, - int count) -#endif { - char *tmp; - int ret; + char *tmp; + int ret; #ifdef DEBUG -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,70)) - struct inode *inode = file->f_dentry->d_inode; -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,70)) */ + struct inode *inode = file->f_dentry->d_inode; #endif /* DEBUG */ - struct i2c_client *client = (struct i2c_client *)file->private_data; + struct i2c_client *client = (struct i2c_client *)file->private_data; - /* copy user space data to kernel space. */ - tmp = kmalloc(count,GFP_KERNEL); - if (tmp==NULL) - return -ENOMEM; + /* copy user space data to kernel space. */ + tmp = kmalloc(count,GFP_KERNEL); + if (tmp==NULL) + return -ENOMEM; #ifdef DEBUG - printk("i2c-dev,o: i2c-%d reading %d bytes.\n",MINOR(inode->i_rdev),count); + printk("i2c-dev,o: i2c-%d reading %d bytes.\n",MINOR(inode->i_rdev), + count); #endif - ret = i2c_master_recv(client,tmp,count); - copy_to_user(buf,tmp,count); - kfree(tmp); - return ret; + ret = i2c_master_recv(client,tmp,count); + if (! ret) + ret = copy_to_user(buf,tmp,count)?-EFAULT:0; + kfree(tmp); + return ret; } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,70)) static ssize_t i2cdev_write (struct file *file, const char *buf, size_t count, loff_t *offset) -#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)) -static long i2cdev_write (struct inode *inode, struct file *file, - const char *buf, unsigned long offset) -#else -static int i2cdev_write(struct inode *inode, struct file *file, - const char *buf, int count) -#endif { - int ret; - char *tmp; - struct i2c_client *client = (struct i2c_client *)file->private_data; + int ret; + char *tmp; + struct i2c_client *client = (struct i2c_client *)file->private_data; #ifdef DEBUG -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,70)) - struct inode *inode = file->f_dentry->d_inode; -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,70)) */ + struct inode *inode = file->f_dentry->d_inode; #endif /* DEBUG */ - /* copy user space data to kernel space. */ - tmp = kmalloc(count,GFP_KERNEL); - if (tmp==NULL) - return -ENOMEM; - copy_from_user(tmp,buf,count); + /* copy user space data to kernel space. */ + tmp = kmalloc(count,GFP_KERNEL); + if (tmp==NULL) + return -ENOMEM; + if (copy_from_user(tmp,buf,count)) { + kfree(tmp); + return -EFAULT; + } #ifdef DEBUG - printk("i2c-dev,o: i2c-%d writing %d bytes.\n",MINOR(inode->i_rdev),count); + printk("i2c-dev,o: i2c-%d writing %d bytes.\n",MINOR(inode->i_rdev), + count); #endif - ret = i2c_master_send(client,tmp,count); - kfree(tmp); - return ret; + ret = i2c_master_send(client,tmp,count); + kfree(tmp); + return ret; } int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - struct i2c_client *client = (struct i2c_client *)file->private_data; - struct i2c_smbus_ioctl_data data_arg; - union i2c_smbus_data temp; - int ver,datasize,res; - unsigned long funcs; + struct i2c_client *client = (struct i2c_client *)file->private_data; + struct i2c_smbus_ioctl_data data_arg; + union i2c_smbus_data temp; + int datasize,res; + unsigned long funcs; #ifdef DEBUG - printk("i2c-dev.o: i2c-%d ioctl, cmd: 0x%x, arg: %lx.\n", - MINOR(inode->i_rdev),cmd, arg); + printk("i2c-dev.o: i2c-%d ioctl, cmd: 0x%x, arg: %lx.\n", + MINOR(inode->i_rdev),cmd, arg); #endif /* DEBUG */ - switch ( cmd ) { - case I2C_SLAVE: - case I2C_SLAVE_FORCE: - if ((arg > 0x3ff) || (((client->flags & I2C_M_TEN) == 0) && arg > 0x7f)) - return -EINVAL; - if ((cmd == I2C_SLAVE) && i2c_check_addr(client->adapter,arg)) - return -EBUSY; - client->addr = arg; - return 0; - case I2C_TENBIT: - if (arg) - client->flags |= I2C_M_TEN; - else - client->flags &= ~I2C_M_TEN; - return 0; - case I2C_FUNCS: - if (! arg) { -#ifdef DEBUG - printk("i2c-dev.o: NULL argument pointer in ioctl I2C_SMBUS.\n"); -#endif - return -EINVAL; - } - if (verify_area(VERIFY_WRITE,(unsigned long *) arg, - sizeof(unsigned long))) { + switch ( cmd ) { + case I2C_SLAVE: + case I2C_SLAVE_FORCE: + if ((arg > 0x3ff) || + (((client->flags & I2C_M_TEN) == 0) && arg > 0x7f)) + return -EINVAL; + if ((cmd == I2C_SLAVE) && i2c_check_addr(client->adapter,arg)) + return -EBUSY; + client->addr = arg; + return 0; + case I2C_TENBIT: + if (arg) + client->flags |= I2C_M_TEN; + else + client->flags &= ~I2C_M_TEN; + return 0; + case I2C_FUNCS: + funcs = i2c_get_functionality(client->adapter); + return (copy_to_user((unsigned long *)arg,&funcs, + sizeof(unsigned long)))?-EFAULT:0; + case I2C_SMBUS: + copy_from_user_ret(&data_arg, + (struct i2c_smbus_ioctl_data *) arg, + sizeof(struct i2c_smbus_ioctl_data), + -EFAULT); + if ((data_arg.size != I2C_SMBUS_BYTE) && + (data_arg.size != I2C_SMBUS_QUICK) && + (data_arg.size != I2C_SMBUS_BYTE_DATA) && + (data_arg.size != I2C_SMBUS_WORD_DATA) && + (data_arg.size != I2C_SMBUS_PROC_CALL) && + (data_arg.size != I2C_SMBUS_BLOCK_DATA)) { #ifdef DEBUG - printk("i2c-dev.o: invalid argument pointer (%ld) " - "in IOCTL I2C_SMBUS.\n", arg); + printk("i2c-dev.o: size out of range (%x) in ioctl I2C_SMBUS.\n", + data_arg.size); #endif - return -EINVAL; - } - - funcs = i2c_get_functionality(client->adapter); - copy_to_user((unsigned long *)arg,&funcs,sizeof(unsigned long)); - return 0; - case I2C_SMBUS: - if (! arg) { + return -EINVAL; + } + /* Note that I2C_SMBUS_READ and I2C_SMBUS_WRITE are 0 and 1, + so the check is valid if size==I2C_SMBUS_QUICK too. */ + if ((data_arg.read_write != I2C_SMBUS_READ) && + (data_arg.read_write != I2C_SMBUS_WRITE)) { #ifdef DEBUG - printk("i2c-dev.o: NULL argument pointer in ioctl I2C_SMBUS.\n"); + printk("i2c-dev.o: read_write out of range (%x) in ioctl I2C_SMBUS.\n", + data_arg.read_write); #endif - return -EINVAL; - } - if (verify_area(VERIFY_READ,(struct i2c_smbus_ioctl_data *) arg, - sizeof(struct i2c_smbus_ioctl_data))) { + return -EINVAL; + } + + /* Note that command values are always valid! */ + + if ((data_arg.size == I2C_SMBUS_QUICK) || + ((data_arg.size == I2C_SMBUS_BYTE) && + (data_arg.read_write == I2C_SMBUS_WRITE))) + /* These are special: we do not use data */ + return i2c_smbus_xfer(client->adapter, client->addr, + client->flags, + data_arg.read_write, + data_arg.command, + data_arg.size, NULL); + + if (data_arg.data == NULL) { #ifdef DEBUG - printk("i2c-dev.o: invalid argument pointer (%ld) " - "in IOCTL I2C_SMBUS.\n", arg); + printk("i2c-dev.o: data is NULL pointer in ioctl I2C_SMBUS.\n"); #endif - return -EINVAL; - } - copy_from_user(&data_arg,(struct i2c_smbus_ioctl_data *) arg, - sizeof(struct i2c_smbus_ioctl_data)); - if ((data_arg.size != I2C_SMBUS_BYTE) && - (data_arg.size != I2C_SMBUS_QUICK) && - (data_arg.size != I2C_SMBUS_BYTE_DATA) && - (data_arg.size != I2C_SMBUS_WORD_DATA) && - (data_arg.size != I2C_SMBUS_PROC_CALL) && - (data_arg.size != I2C_SMBUS_BLOCK_DATA)) { -#ifdef DEBUG - printk("i2c-dev.o: size out of range (%x) in ioctl I2C_SMBUS.\n", - data_arg.size); -#endif - return -EINVAL; - } - /* Note that I2C_SMBUS_READ and I2C_SMBUS_WRITE are 0 and 1, - so the check is valid if size==I2C_SMBUS_QUICK too. */ - if ((data_arg.read_write != I2C_SMBUS_READ) && - (data_arg.read_write != I2C_SMBUS_WRITE)) { -#ifdef DEBUG - printk("i2c-dev.o: read_write out of range (%x) in ioctl I2C_SMBUS.\n", - data_arg.read_write); -#endif - return -EINVAL; - } - - /* Note that command values are always valid! */ - - if ((data_arg.size == I2C_SMBUS_QUICK) || - ((data_arg.size == I2C_SMBUS_BYTE) && - (data_arg.read_write == I2C_SMBUS_WRITE))) - /* These are special: we do not use data */ - return i2c_smbus_xfer(client->adapter, client->addr, client->flags, - data_arg.read_write, data_arg.command, - data_arg.size, NULL); - - if (data_arg.data == NULL) { -#ifdef DEBUG - printk("i2c-dev.o: data is NULL pointer in ioctl I2C_SMBUS.\n"); -#endif - return -EINVAL; - } - - /* This seems unlogical but it is not: if the user wants to read a - value, we must write that value to user memory! */ - ver = ((data_arg.read_write == I2C_SMBUS_WRITE) && - (data_arg.size != I2C_SMBUS_PROC_CALL))?VERIFY_READ:VERIFY_WRITE; - - if ((data_arg.size == I2C_SMBUS_BYTE_DATA) || (data_arg.size == I2C_SMBUS_BYTE)) - datasize = sizeof(data_arg.data->byte); - else if ((data_arg.size == I2C_SMBUS_WORD_DATA) || - (data_arg.size == I2C_SMBUS_PROC_CALL)) - datasize = sizeof(data_arg.data->word); - else /* size == I2C_SMBUS_BLOCK_DATA */ - datasize = sizeof(data_arg.data->block); - - if (verify_area(ver,data_arg.data,datasize)) { -#ifdef DEBUG - printk("i2c-dev.o: invalid pointer data (%p) in ioctl I2C_SMBUS.\n", - data_arg.data); -#endif - return -EINVAL; - } - - if ((data_arg.size == I2C_SMBUS_PROC_CALL) || - (data_arg.read_write == I2C_SMBUS_WRITE)) - copy_from_user(&temp,data_arg.data,datasize); - res = i2c_smbus_xfer(client->adapter,client->addr,client->flags, - data_arg.read_write, - data_arg.command,data_arg.size,&temp); - if (! res && ((data_arg.size == I2C_SMBUS_PROC_CALL) || - (data_arg.read_write == I2C_SMBUS_READ))) - copy_to_user(data_arg.data,&temp,datasize); - return res; - - default: - return i2c_control(client,cmd,arg); - } - return 0; + return -EINVAL; + } + + if ((data_arg.size == I2C_SMBUS_BYTE_DATA) || + (data_arg.size == I2C_SMBUS_BYTE)) + datasize = sizeof(data_arg.data->byte); + else if ((data_arg.size == I2C_SMBUS_WORD_DATA) || + (data_arg.size == I2C_SMBUS_PROC_CALL)) + datasize = sizeof(data_arg.data->word); + else /* size == I2C_SMBUS_BLOCK_DATA */ + datasize = sizeof(data_arg.data->block); + + if ((data_arg.size == I2C_SMBUS_PROC_CALL) || + (data_arg.read_write == I2C_SMBUS_WRITE)) + copy_from_user_ret(&temp,data_arg.data,datasize, + -EFAULT); + res = i2c_smbus_xfer(client->adapter,client->addr,client->flags, + data_arg.read_write, + data_arg.command,data_arg.size,&temp); + if (! res && ((data_arg.size == I2C_SMBUS_PROC_CALL) || + (data_arg.read_write == I2C_SMBUS_READ))) + copy_to_user_ret(data_arg.data,&temp,datasize,-EFAULT); + return res; + + default: + return i2c_control(client,cmd,arg); + } + return 0; } int i2cdev_open (struct inode *inode, struct file *file) { - unsigned int minor = MINOR(inode->i_rdev); - struct i2c_client *client; + unsigned int minor = MINOR(inode->i_rdev); + struct i2c_client *client; - if ((minor >= I2CDEV_ADAPS_MAX) || ! (i2cdev_adaps[minor])) { + if ((minor >= I2CDEV_ADAPS_MAX) || ! (i2cdev_adaps[minor])) { #ifdef DEBUG - printk("i2c-dev.o: Trying to open unattached adapter i2c-%d\n",minor); + printk("i2c-dev.o: Trying to open unattached adapter i2c-%d\n", + minor); #endif - return -ENODEV; - } + return -ENODEV; + } - /* Note that we here allocate a client for later use, but we will *not* - register this client! Yes, this is safe. No, it is not very clean. */ - if(! (client = kmalloc(sizeof(struct i2c_client),GFP_KERNEL))) - return -ENOMEM; - memcpy(client,&i2cdev_client_template,sizeof(struct i2c_client)); - client->adapter = i2cdev_adaps[minor]; - file->private_data = client; + /* Note that we here allocate a client for later use, but we will *not* + register this client! Yes, this is safe. No, it is not very clean. */ + if(! (client = kmalloc(sizeof(struct i2c_client),GFP_KERNEL))) + return -ENOMEM; + memcpy(client,&i2cdev_client_template,sizeof(struct i2c_client)); + client->adapter = i2cdev_adaps[minor]; + file->private_data = client; - i2cdev_adaps[minor]->inc_use(i2cdev_adaps[minor]); - MOD_INC_USE_COUNT; + if (i2cdev_adaps[minor]->inc_use) + i2cdev_adaps[minor]->inc_use(i2cdev_adaps[minor]); + MOD_INC_USE_COUNT; #ifdef DEBUG - printk("i2c-dev.o: opened i2c-%d\n",minor); + printk("i2c-dev.o: opened i2c-%d\n",minor); #endif - return 0; + return 0; } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,31)) static int i2cdev_release (struct inode *inode, struct file *file) -#else -static void i2cdev_release (struct inode *inode, struct file *file) -#endif { - unsigned int minor = MINOR(inode->i_rdev); - kfree(file->private_data); - file->private_data=NULL; + unsigned int minor = MINOR(inode->i_rdev); + kfree(file->private_data); + file->private_data=NULL; #ifdef DEBUG - printk("i2c-dev.o: Closed: i2c-%d\n", minor); -#endif - MOD_DEC_USE_COUNT; - i2cdev_adaps[minor]->dec_use(i2cdev_adaps[minor]); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,31)) - return 0; + printk("i2c-dev.o: Closed: i2c-%d\n", minor); #endif + MOD_DEC_USE_COUNT; + if (i2cdev_adaps[minor]->dec_use) + i2cdev_adaps[minor]->dec_use(i2cdev_adaps[minor]); + return 0; } int i2cdev_attach_adapter(struct i2c_adapter *adap) { - int i; - - if ((i = i2c_adapter_id(adap)) < 0) { - printk("i2c-dev.o: Unknown adapter ?!?\n"); - return -ENODEV; - } - if (i >= I2CDEV_ADAPS_MAX) { - printk("i2c-dev.o: Adapter number too large?!? (%d)\n",i); - return -ENODEV; - } - - if (! i2cdev_adaps[i]) { - i2cdev_adaps[i] = adap; - printk("i2c-dev.o: Registered '%s' as minor %d\n",adap->name,i); - } else { - i2cdev_adaps[i] = NULL; + int i; + + if ((i = i2c_adapter_id(adap)) < 0) { + printk("i2c-dev.o: Unknown adapter ?!?\n"); + return -ENODEV; + } + if (i >= I2CDEV_ADAPS_MAX) { + printk("i2c-dev.o: Adapter number too large?!? (%d)\n",i); + return -ENODEV; + } + + if (! i2cdev_adaps[i]) { + i2cdev_adaps[i] = adap; + printk("i2c-dev.o: Registered '%s' as minor %d\n",adap->name,i); + } else { + i2cdev_adaps[i] = NULL; #ifdef DEBUG - printk("i2c-dev.o: Adapter unregistered: %s\n",adap->name); + printk("i2c-dev.o: Adapter unregistered: %s\n",adap->name); #endif - } + } - return 0; + return 0; } int i2cdev_detach_client(struct i2c_client *client) { - return 0; + return 0; } static int i2cdev_command(struct i2c_client *client, unsigned int cmd, void *arg) { - return -1; + return -1; } int __init i2c_dev_init(void) { - int res; - - printk("i2c-dev.o: i2c /dev entries driver module\n"); - - i2cdev_initialized = 0; - if (register_chrdev(I2C_MAJOR,"i2c",&i2cdev_fops)) { - printk("i2c-dev.o: unable to get major %d for i2c bus\n",I2C_MAJOR); - return -EIO; - } - i2cdev_initialized ++; - - if ((res = i2c_add_driver(&i2cdev_driver))) { - printk("i2c-dev.o: Driver registration failed, module not inserted.\n"); - i2cdev_cleanup(); - return res; - } - i2cdev_initialized ++; - return 0; + int res; + + printk("i2c-dev.o: i2c /dev entries driver module\n"); + + i2cdev_initialized = 0; + if (register_chrdev(I2C_MAJOR,"i2c",&i2cdev_fops)) { + printk("i2c-dev.o: unable to get major %d for i2c bus\n", + I2C_MAJOR); + return -EIO; + } + i2cdev_initialized ++; + + if ((res = i2c_add_driver(&i2cdev_driver))) { + printk("i2c-dev.o: Driver registration failed, module not inserted.\n"); + i2cdev_cleanup(); + return res; + } + i2cdev_initialized ++; + return 0; } int i2cdev_cleanup(void) { - int res; - - if (i2cdev_initialized >= 2) { - if ((res = i2c_del_driver(&i2cdev_driver))) { - printk("i2c-dev.o: Driver deregistration failed, " - "module not removed.\n"); - return res; - } - i2cdev_initialized ++; - } - - if (i2cdev_initialized >= 1) { - if ((res = unregister_chrdev(I2C_MAJOR,"i2c"))) { - printk("i2c-dev.o: unable to release major %d for i2c bus\n",I2C_MAJOR); - return res; - } - i2cdev_initialized --; - } - return 0; + int res; + + if (i2cdev_initialized >= 2) { + if ((res = i2c_del_driver(&i2cdev_driver))) { + printk("i2c-dev.o: Driver deregistration failed, " + "module not removed.\n"); + return res; + } + i2cdev_initialized ++; + } + + if (i2cdev_initialized >= 1) { + if ((res = unregister_chrdev(I2C_MAJOR,"i2c"))) { + printk("i2c-dev.o: unable to release major %d for i2c bus\n", + I2C_MAJOR); + return res; + } + i2cdev_initialized --; + } + return 0; } EXPORT_NO_SYMBOLS; @@ -545,12 +428,12 @@ MODULE_DESCRIPTION("I2C /dev entries driver"); int init_module(void) { - return i2c_dev_init(); + return i2c_dev_init(); } int cleanup_module(void) { - return i2cdev_cleanup(); + return i2cdev_cleanup(); } #endif /* def MODULE */ |