I2c driver crash

MohanReddy koppula mohanreddykv at gmail.com
Fri Sep 23 16:05:56 EST 2011


I think the client->adapter pointer is NULL. Make sure the
ds75_attach_adapte() is called before you invoke ioctl().

-Mohan

On Fri, Sep 23, 2011 at 6:58 AM, Benjamin Herrenschmidt
<benh at kernel.crashing.org> wrote:
> On Thu, 2011-09-22 at 15:25 +0000, smitha.vanga at wipro.com wrote:
>> Hi Scott,
>>
>> When I call if  i2c_master_send(&ds75->i2c_client,buffer,2) it
>> crashes. In module initialization I don't see any errors. Below are
>> kernel messages. Could you please let me know what may be the reason
>> for this crash.
>
> Why the heck are you trying to write a new driver for ds75 ? There's
> already one in there (lm75, same thing).
>
> Cheers,
> Ben.
>
>> -----------Logs---------
>> Loading Temperature Sensor Interface module (temp_if.ko)
>> ds75_init
>> DS75_DRIVER : Open
>> DS75_DRIVER : Device Open Successful!
>> DS75_DRIVER  : ioctl TEMP_READ cmd 1
>>  ds75_temp_read calling i2c_master_send
>> In i2c_master_send enter-------
>> Unable to handle kernel paging request for data at address 0x00000010
>> Faulting instruction address: 0xc01b06a4
>> Oops: Kernel access of bad area, sig: 11 [#1]
>>
>> Modules linked in: temp_if gpio_if
>> NIP: C01B06A4 LR: C01B06A0 CTR: C019BC90
>> REGS: c309bdc0 TRAP: 0300   Not tainted
>> (2.6.21.7-hrt1-cfs-v22-grsec-WR2.0bl_cgl)
>> MSR: 00009032 <EE,ME,IR,DR>  CR: 44004822  XER: 00000000
>> DAR: 00000010, DSISR: 20000000
>> TASK = c306f810[145] 'epn412' THREAD: c309a000
>> GPR00: 00007D00 C309BE70 C306F810 C02A0000 00000001 00000001 00000000
>> FDFBD0A0
>> GPR08: 003DE8A0 A827A936 00003F78 C02EAE88 00000001 1011C7C0 03EFD000
>> FFFFFFFF
>> GPR16: 00000001 00000000 007FFC00 37942FA8 1012EAC0 1001E530 37942FB4
>> 00000003
>> GPR24: 37942FB4 00000000 003D0F00 C309BEA8 FFFFFFF7 00000008 C309BEA8
>> 00000002
>> Call Trace:
>> [C309BE70] [C01B0698]  (unreliable)
>> [C309BEA0] [C50B71DC]
>> [C309BED0] [C007A0D0]
>> [C309BEE0] [C007A158]
>> [C309BF10] [C007A4EC]
>> [C309BF40] [C000E780]
>> --- Exception: c01Instruction dump:
>> 7c0802a6 bf61001c 7c7d1b78 3c60c02a 386313b4 7cbf2b78 90010034
>> 7c9b2378
>> 4be6bc79 386007d0 4be5ac6d 3c60c02a <839d0008> 386313d8 4be6bc61
>> a01d0004
>>
>>
>>
>>
>> Below is the driver code.
>> -------------------------
>>
>> #include "temp_if.h"
>> #include <asm-powerpc/uaccess.h>
>> #include <linux/i2c.h>
>> //#include <asm/arch/platform.h>
>>
>>
>> #define I2C_DEBUG
>>
>> #ifdef      I2C_DEBUG
>> #define     I2C_DBG1(x)                 printk(KERN_WARNING x)
>> #define     I2C_DBG2(x,y)               printk(KERN_WARNING x,y)
>> #define     I2C_DBG3(x,y,z)             printk(KERN_WARNING x,y,z)
>> #define     I2C_DBG4(w,x,y,z)           printk(KERN_WARNING w,x,y,z)
>> #else
>> #define I2C_DBG1(x)
>> #define I2C_DBG2(x,y)
>> #define I2C_DBG3(x,y,z)
>> #define I2C_DBG4(w,x,y,z)
>> #endif
>>
>> /* Function Prototype */
>> static int ds75_open(struct inode *inode, struct file *filp);
>> static int ds75_iotcl(struct inode *inode, struct file *flip, unsigned
>> int cmd, unsigned long arg);
>> static int ds75_release(struct inode *inode, struct file *flip);
>> int ds75_attach_client(struct ds75_data * ds75, struct i2c_adapter
>> *adapter);
>>
>> int ds75_attach_adapter(struct i2c_adapter *adapter);
>> int ds75_detach_client(struct i2c_client *client);
>>
>>
>>
>>
>> /* Structure */
>> static struct file_operations tmpsensor_fops =
>> {
>>         ioctl:          ds75_iotcl,
>>         open:           ds75_open,
>>         release:        ds75_release,
>>
>> };
>>
>> static struct i2c_driver ds75_driver = {
>>         .driver = {
>>                 .name   = "DS75",
>>         },
>>         .attach_adapter = ds75_attach_adapter,
>>         .detach_client  = ds75_detach_client,
>> };
>>
>> /* Global Variable */
>> static int s_nI2CMajor = 0;
>> static int s_bI2CDevOpen = 0;
>> static int s_nUseCnt = 0;
>> struct ds75_data *ds75;
>>
>>
>> static int ds75_open(struct inode *inode, struct file *flip)
>> {
>>   I2C_DBG1( "DS75_DRIVER : Open\n");
>>   if(s_bI2CDevOpen == 0)
>>     {
>>       I2C_DBG1("DS75_DRIVER : Device Open Successful!\n");
>>       s_bI2CDevOpen = 1;
>>       s_nUseCnt++;
>>
>>     }
>>   else
>>     {
>>       I2C_DBG1("DS75_DRIVER : Device Already Opened Successfully!\n");
>>       s_bI2CDevOpen = 1;
>>       s_nUseCnt++;
>>     }
>>   return 0;
>> }
>>
>>
>> static int ds75_release(struct inode *inode, struct file *flip)
>> {
>>   I2C_DBG1 (KERN_INFO "Entering ds75_release\n" );
>>   if(s_bI2CDevOpen)
>>     {
>>       if( s_nUseCnt <= 0 )
>>         {
>>           I2C_DBG1("DS75_DRIVER  : i2c driver can't be released!\n");
>>           return -EIO;
>>         }
>>       else
>>         {
>>           I2C_DBG1("DS75_DRIVER  : Release Successful!\n");
>>           s_nUseCnt--;
>>           if( s_nUseCnt == 0 )
>>             {
>>               s_bI2CDevOpen = 0;
>>               I2C_DBG1("DS75_DRIVER  : I2C Driver is Closed!\n");
>>                 }
>>         }
>>       return 0;
>>     }
>>   else
>>     {
>>       I2C_DBG1("DS75_DRIVER  : Release Fail! (Device is Not Open)\n");
>>       return -EIO;
>>     }
>> }
>>
>> /*
>>  This function will read the Temperature from the device and copies to
>> user space
>> */
>> static int ds75_temp_read(struct ds75_msg_t *pData)
>> {
>>      //unsigned char buffer[4];
>>      signed char buffer[4];
>>      int ret;
>>      buffer[0]=0;  /* Writing 0 in to Pointer register. --> Temprature
>> read register */
>>      if ((ret = i2c_master_send(&ds75->i2c_client,buffer,2)) !=2)
>>      {
>>          I2C_DBG2("DS75_DRIVER  : Error writing to I2C ret = %d
>> \n",ret);
>>                      return -1;
>>      }
>>
>>      /* reading from the temperature read register */
>>      if (i2c_master_recv(&ds75->i2c_client,buffer,2)!= 2)
>>      {
>>          I2C_DBG1("DS75_DRIVER  : Error reading from I2C\n");
>>                      return -1;
>>      }
>>
>>      //I2C_DBG3("DS75_DRIVER: data[0] = %d, data[1] = %d
>> \n",buffer[0],buffer[1]);
>>         //I2C_DBG3("DS75_DRIVER: data[0] = %d, data[1] = %d
>> \n",buffer[0],buffer[1]);
>>
>>      /* Copy User Memory Area */
>>            if(copy_to_user(pData->ReadData,buffer, 2 ) != 0)
>>            {
>>               I2C_DBG1("DS75_DRIVER  : error in copying to user
>> space");
>>               return -1;
>>            }
>>
>>      return 0;  /* Success */
>>
>> }
>>
>>
>> static int ds75_iotcl(struct inode *inode, struct file *flip, unsigned
>> int cmd, unsigned long arg)
>> {
>>         int nRetVal = 0;
>>
>>         if( ((struct ds75_msg_t *)arg) == NULL ){
>>                 I2C_DBG1("DS75_DRIVER  : ioctl Message Buff must not
>> be NULL\n");
>>                 return -EFAULT;
>>         }
>>
>>         switch(cmd){
>>                 case TEMP_READ:
>>                         I2C_DBG2("DS75_DRIVER  : ioctl TEMP_READ cmd %
>> d\n",cmd);
>>                         nRetVal = ds75_temp_read((struct ds75_msg_t *)
>> arg);
>>                         break;
>>
>>                 default:
>>                         /* Error! */
>>                         I2C_DBG1("DS75_DRIVER  : Command  not
>> implemented\n");
>>                         nRetVal = -EIO;
>>                         break;
>>         }
>>         return nRetVal;
>> }
>>
>>
>> /*
>>  *  i2c_attach_client - tries to detect and initialize slics
>> */
>> int ds75_attach_client(struct ds75_data * ds75, struct i2c_adapter
>> *adapter)
>> {
>>         struct i2c_client * client;
>>
>>         /* register i2c client */
>>         client = &ds75->i2c_client;
>>         client->adapter = adapter;
>>         client->driver = &ds75_driver;
>> //      client->flags = I2C_CLIENT_ALLOW_USE;
>>   client->addr = DS75_ADDR;
>>   strlcpy(client->name, "DS75", I2C_NAME_SIZE);
>>         i2c_set_clientdata(client, ds75);
>>
>>         if (i2c_attach_client(client))
>>      return -1;
>>
>>         printk (KERN_INFO DS75_DRIVER_NAME ": I2C client attached\n");
>>         return 0;
>> }
>>
>> /*
>>  *  i2c_attach_adapter - initializes the maxim driver
>> */
>> int ds75_attach_adapter(struct i2c_adapter *adapter)
>> {
>>         /* allocate maxim_data structure */
>>         ds75 = kmalloc(sizeof (struct ds75_data), GFP_KERNEL);
>>         if (ds75 == NULL)
>>         {
>>            printk (KERN_ERR "Unable to allocate memory for ds75 temp
>> sensor driver\n");
>>            goto err0;
>>         }
>>         memset(ds75, 0, sizeof(struct ds75_data));
>>
>>         /* Attach Spi Client */
>>         if (ds75_attach_client(ds75, adapter) != 0)
>>         {
>>            printk (KERN_ERR "No ds75 device detected\n");
>>            goto err1;
>>         }
>>
>>         return 0;
>>
>> err1:
>>         kfree(ds75);
>> err0:
>>         return -1;
>> }
>>
>> /*
>>  *  i2c_detach_client - cleans up the maxim driver
>> */
>> int ds75_detach_client(struct i2c_client *client)
>> {
>>         struct ds75_data *ds75 = i2c_get_clientdata(client);
>>
>>         if (ds75->owned_irq)
>>         {
>>                 free_irq(ds75->irq, ds75);
>>                 ds75->owned_irq = 0;
>>
>>         }
>>
>>         i2c_detach_client(&ds75->i2c_client);
>>
>>         kfree (ds75);      // Free the kernel memory */
>>
>>         return 0;
>> }
>>
>>
>>
>>
>> /*
>>  * Temperature sensor DS75 init -
>>  *
>>  */
>> int __init ds75_init(void)
>> {
>>         int rc;
>>         rc = i2c_add_driver(&ds75_driver);
>>         if (rc)
>>         {
>>                 printk (KERN_ERR DS75_DRIVER_NAME ": unable to add
>> driver\n");
>>                 return rc;
>>         }
>>
>>         rc = register_chrdev (DS75_DEVICE_MAJOR_NUM, DS75_DRIVER_NAME,
>> &tmpsensor_fops);
>>         if (rc)
>>         {
>>                 printk (KERN_ERR DS75_DRIVER_NAME ": unable to
>> register char device\n");
>>                 return rc;
>>         }
>>
>>         return 0;
>> }
>>
>> /**
>>  * maxim _exit -
>>  *
>>  *
>>  */
>> void __exit ds75_exit(void)
>> {
>>         unregister_chrdev (DS75_DEVICE_MAJOR_NUM, DS75_DRIVER_NAME);
>>
>>         i2c_del_driver(&ds75_driver);
>> }
>>
>> MODULE_AUTHOR("xxxx");
>> MODULE_DESCRIPTION("DS75 I2C driver");
>> MODULE_LICENSE("GPL");
>>
>> module_init(ds75_init);
>> module_exit(ds75_exit);
>>
>>
>> Regards,
>> Smitha
>>
>> Please do not print this email unless it is absolutely necessary.
>>
>> The information contained in this electronic message and any
>> attachments to this message are intended for the exclusive use of the
>> addressee(s) and may contain proprietary, confidential or privileged
>> information. If you are not the intended recipient, you should not
>> disseminate, distribute or copy this e-mail. Please notify the sender
>> immediately and destroy all copies of this message and any
>> attachments.
>>
>> WARNING: Computer viruses can be transmitted via email. The recipient
>> should check this email and any attachments for the presence of
>> viruses. The company accepts no liability for any damage caused by any
>> virus transmitted by this email.
>>
>> www.wipro.com
>>
>> _______________________________________________
>> Linuxppc-dev mailing list
>> Linuxppc-dev at lists.ozlabs.org
>> https://lists.ozlabs.org/listinfo/linuxppc-dev
>
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev at lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
>


More information about the Linuxppc-dev mailing list