在新linux中使用proc_create_data编写proc

2019-07-13 09:28发布


主要讲使用proc_create_data如何传递私有数据。 其中可以参考/fs/proc/uptime.c
以下是我在工作中,针对一个phy驱动写的一个proc

const char *___dev_name(const struct device *dev) {  /* Use the init name until the kobject becomes available */  if (dev->init_name)   return dev->init_name;
 return kobject_name(&dev->kobj); }

static struct proc_dir_entry *proc_root = NULL;
static ssize_t __delay_write(struct file *file,  //注册这个file的结构。与read,show的不一样。      const char __user *user_buf,      size_t count, loff_t *ppos) {     char ch[20];     struct phy_device *phydev = ((struct seq_file *)file->private_data)->private; 从struct file中取得私有数据的方式。     char *after;
    int regvalue = at803x_dbg_reg_read(phydev,0x0b);     int delay_val = 0;     if(user_buf == NULL)     {         printk("Input buf is NULL ");         return 0;     }
    copy_from_user(&ch, user_buf, 20);         printk("buf:%s,len:%d,count:%u ",user_buf,strlen(user_buf),count);

    delay_val = (int)simple_strtoul(ch, &after, 0);         printk("new delay_val:%d ; orig regvalue 0x%x ",delay_val,regvalue);         if(delay_val > 3)     {         printk("Input buf is invalid ");         return 0;     }  
    regvalue = regvalue & ~(3<<5);     regvalue |= delay_val<<5;     at803x_dbg_reg_write(phydev,0xb,regvalue);     return count;     }


static int __init _proc_init(void) {  printk("0" "AT803x phy Proc Module Load ... ");
 proc_root = proc_mkdir("at803x", NULL);  return 0;
}
static int __delay_info_show(struct seq_file *file, void *v)  //注册这个file的结构。 {     struct phy_device *phydev = file->private;     char buf[1024];     int len;     int regvalue = 0;     int delay_val = 0;
    regvalue=  at803x_dbg_reg_read(phydev,0x0B);     delay_val = (regvalue>>5)&0x3;
    printk ("%s:%d>>> phydev %p   ",__func__,__LINE__,phydev);     sprintf(buf, "RGMII GTX CLOCK Delay Reg 0x%x; Gtx_dly_val %d. ",regvalue,delay_val );     len = seq_printf(file, buf);
    return len; }

static int __delay_info_open(struct inode *inode, struct file *file) {  /* 在open时,使用PDE_DATA(inode)作为私有数据向下传。其实PDE_DATA(inode) 就是phydev.  这个私有数据的保存在seq_file的private里。  在write和show函数中可以直接使用file->private来找到私有数据。 */  return single_open(file, __delay_info_show, PDE_DATA(inode)); }
static const struct file_operations proc_ops = {  .owner = THIS_MODULE,  .write = __delay_write,            // 这个函数自己来写。  .open = __delay_info_open,   //这个函数自己来写。  .read = seq_read,  .llseek = seq_lseek,  .release = single_release, };
static int  _proc_phydev(struct phy_device *phydev) {         struct proc_dir_entry * _proc_dir;     char name[80];

    sprintf(name,"%s",___dev_name(&phydev->dev));      _proc_dir = proc_mkdir(name, proc_root);     proc_create_data("tx_delay",0644,_proc_dir,&proc_ops,phydev);//使用proc_create_data,其中最后一个参数是私有数据。这里是 phydev.      return 0; }