inline int scull_open(int tid, inode i, file filp) { scull_dev dev; dev = container_of(i); filp = dev; if (down_interruptible()) return -ERESTARTSYS; __X__ = 2; /* check mutual exclusion */ scull_trim(dev); /* ignore errors */ assert(__X__ >= 2); /* check mutual exclusion */ up(); return 0; /* success */ }
int scull_open(struct inode *inode, struct file *filp) { struct scull_dev *dev; /* device information */ dev = container_of(inode->i_cdev, struct scull_dev, cdev); filp->private_data = dev; /* for other methods */ /* now trim to 0 the length of the device if open was write-only */ if ( (filp->f_flags & O_ACCMODE) == O_WRONLY) { if (down_interruptible(&dev->sem)) return -ERESTARTSYS; scull_trim(dev); /* ignore errors */ up(&dev->sem); } return 0; /* success */ }
int scull_open(struct inode *inode, struct file *filp) { struct scull_dev *dev; /* device information */ dev = container_of(inode->i_cdev, struct scull_dev, cdev); filp->private_data = dev; /* for other methods */ /* If the device was opened write-only, trim it to a length of 0. */ if ( (filp->f_flags & O_ACCMODE) == O_WRONLY) { if (mutex_lock_interruptible(&dev->mutex)) return -ERESTARTSYS; scull_trim(dev); /* Ignore errors. */ mutex_unlock(&dev->mutex); } return 0; }
int scull_open( struct inode *inode, struct file *filp ) { struct scull_dev *dev; dev = container_of( inode->i_cdev, struct scull_dev, cdev ); filp->private_data = dev; if ( (filp->f_flags & O_ACCMODE) == O_WRONLY ) { if ( down_interruptible( &dev->sem ) ) return(-ERESTARTSYS); scull_trim( dev ); up( &dev->sem ); } return(0); }
/* * The cleanup function is used to handle initialization failures as well. * Thefore, it must be careful to work correctly even if some of the items * have not been initialized */ void scull_cleanup_module(void) { int i; dev_t devno = MKDEV(scull_major, scull_minor); /* Get rid of our char dev entries */ if (scull_devices) { for (i = 0; i < scull_nr_devs; i++) { scull_trim(scull_devices + i); cdev_del(&scull_devices[i].cdev); } kfree(scull_devices); } /* cleanup_module is never called if registering failed */ unregister_chrdev_region(devno, scull_nr_devs); }
int scull_s_open (struct inode *inode, struct file *filp) { Scull_Dev *dev = &scull_s_device; /* device information */ int num = NUM(inode->i_rdev); if (num > 0) return -ENODEV; /* 1 device only */ if (scull_s_count) return -EBUSY; /* already open */ scull_s_count++; /* then, everything else is copied from the bare scull device */ if ( (filp->f_flags & O_ACCMODE) == O_WRONLY) scull_trim(dev); filp->private_data = dev; MOD_INC_USE_COUNT; return 0; /* success */ }
void cleanup_module(void) { int i; unregister_chrdev(scull_major, "scull"); #ifdef SCULL_USE_PROC proc_unregister(&proc_root, scull_proc_entry.low_ino); #endif for (i=0; i<scull_nr_devs; i++) scull_trim(scull_devices+i); kfree(scull_devices); /* and call the cleanup functions for friend devices */ scull_p_cleanup(); scull_access_cleanup(); }
/* In scull_open, the fop_array is used according to TYPE(dev) */ int scull_open(struct inode *inode, struct file *filp) { Scull_Dev *dev; /* device information */ int num = NUM(inode->i_rdev); int type = TYPE(inode->i_rdev); /* * the type and num values are only valid if we are not using devfs. * However, since we use them to retrieve the device pointer, we * don't need them with devfs as filp->private_data is already * initialized */ /* * If private data is not valid, we are not using devfs * so use the type (from minor nr.) to select a new f_op */ if (!filp->private_data && type) { if (type > SCULL_MAX_TYPE) return -ENODEV; filp->f_op = scull_fop_array[type]; return filp->f_op->open(inode, filp); /* dispatch to specific open */ } /* type 0, check the device number (unless private_data valid) */ dev = (Scull_Dev *)filp->private_data; if (!dev) { if (num >= scull_nr_devs) return -ENODEV; dev = &scull_devices[num]; filp->private_data = dev; /* for other methods */ } MOD_INC_USE_COUNT; /* Before we maybe sleep */ /* now trim to 0 the length of the device if open was write-only */ if ( (filp->f_flags & O_ACCMODE) == O_WRONLY) { if (down_interruptible(&dev->sem)) { MOD_DEC_USE_COUNT; return -ERESTARTSYS; } scull_trim(dev); /* ignore errors */ up(&dev->sem); } return 0; /* success */ }
int scull_open(struct inode *inodp, struct file *filp) { struct Scull_dev *lscull_dev; #ifdef PRINTK printk(KERN_INFO"Begin:%s\n",__func__); #endif lscull_dev = container_of(inodp->i_cdev,struct Scull_dev,cdev); if(!lscull_dev) { #ifdef PRINTK printk(KERN_ERR"End E:Error in container_of\n"); #endif } filp->private_data = lscull_dev; //check for access mode if((filp->f_flags & O_ACCMODE)==O_RDONLY) { #ifdef PRINTK printk(KERN_INFO"File opened in read only mode\n"); #endif } //trim if in write only mode if((filp->f_flags & O_ACCMODE)==O_WRONLY) { #ifdef PRINTK printk(KERN_INFO"File opened in write only mode\n"); #endif scull_trim(scull_dev); } filp->private_data = lscull_dev; #ifdef PRINTK printk(KERN_INFO"End:%s\n",__func__); #endif return 0; }
/* * open and close */ int sculloc_open(struct inode *inode, struct file *filp) { struct scull_dev *dev; /* device info */ /* Find the device */ dev = container_of(inode->i_cdev, struct scullc_dev, cdev); /* now trim to 0 the length of the device if open was write-only */ if ((filp->f_flags & O_ACCMODE) == O_WRONLY) { if (down_interruptible(&dev->sem)) return -ERESTARTSYS; scull_trim(dev); /* ignore errrs */ up(&dev->sem); } /* and use filp->private_data to point to the device data */ filp->private_data = dev; return 0; /* success */ }
int scull_open(struct inode *inode, struct file *filp) { struct scull_dev *dev; dev = container_of(inode->i_cdev, struct scull_dev, cdev); if(!dev) { printk(KERN_ALERT "In scull_open(), dev is NULL"); return 0; } filp->private_data = dev; if((filp->f_flags & O_ACCMODE) == O_WRONLY){ scull_trim(dev); } #ifdef __DEBUG_INFO printk(KERN_ALERT "In scull_open()\n"); #endif return 0; }
int scull_open(struct inode *inode, struct file *filp) { struct scull_dev *dev; /* device information */ /* * 调用container_of宏,通过cdev成员得到包含该cdev的scull_dev结构,然后保存在flip文件中 */ dev = container_of(inode->i_cdev, struct scull_dev, cdev); filp->private_data = dev; /* for other methods */ /* now trim to 0 the length of the device if open was write-only */ /* 如果scull设备文件是以只写的方式打开,则要调用scull_trim将scull设备清空 */ if ( (filp->f_flags & O_ACCMODE) == O_WRONLY) { /* * 进行加锁解锁操作,进行互斥 */ if (down_interruptible(&dev->sem)) return -ERESTARTSYS; scull_trim(dev); /* ignore errors */ up(&dev->sem); } return 0; /* success */ }
/* * The cleanup function is used to handle initialization failures as well. * Thefore, it must be careful to work correctly even if some of the items * have not been initialized */ void scull_cleanup_module(void) { int i; dev_t devno = MKDEV(scull_major, scull_minor); /* Remove proc entry */ remove_proc_entry("scullmem", NULL /* parent dir */); /* Remove seq_file interfaced proc entry */ remove_proc_entry("scullseq", NULL); /* Get rid of our char dev entries */ if (scull_devices) { for (i = 0; i < scull_nr_devs; i++) { scull_trim(scull_devices + i); cdev_del(&scull_devices[i].cdev); } kfree(scull_devices); } /* cleanup_module is never called if registering failed */ unregister_chrdev_region(devno, scull_nr_devs); }
static int scull_u_open(struct inode *inode, struct file *filp) { struct scull_dev *dev = &scull_u_device; spin_lock(&scull_u_lock); if (scull_u_count && (scull_u_owner != current->uid) && (scull_u_owner != current->euid) && !capable(CAP_DAC_OVERRIDE)) { spin_unlock(&scull_u_lock); return -EBUSY; } if (scull_u_count == 0) scull_u_owner = current->uid; scull_u_count++; spin_unlock(&scull_u_lock); if ((filp->f_flags & O_ACCMODE) == O_WRONLY) scull_trim(dev); filp->private_data = dev; return 0; }
static void scull_cleanup_module(void) { int i; dev_t dev = MKDEV(scull_major, scull_minor); #ifdef __DEBUG_INFO printk(KERN_ALERT "In clean up !!!/n"); #endif if(scull_devices != NULL){ printk(KERN_ALERT "In clean up !!!/n"); for(i = 0; i < scull_num; i++) { scull_trim(scull_devices + i); cdev_del(&(scull_devices[i].cdev)); } kfree(scull_devices); }else{ printk(KERN_ALERT "In clean up,devices is NULL !!!/n"); } unregister_chrdev_region(dev, scull_num); }
void scull_cleanup_module(void) { int i; dev_t devno = MKDEV(scull_major, scull_minor); /* Get rid of our char dev entries */ if (scull_devices) { for (i = 0; i < scull_nr_devs; i++) { scull_trim(scull_devices + i); cdev_del(&scull_devices[i].cdev); } kfree(scull_devices); } #ifdef SCULL_DEBUG /* use proc only if debugging */ scull_remove_proc(); #endif /* cleanup_module is never called if registering failed */ unregister_chrdev_region(devno, scull_nr_devs); /* and call the cleanup functions for friend devices */ //scull_p_cleanup(); //scull_access_cleanup(); printk(KERN_ALERT "Scull device removed.. \n"); }
static int scull_w_open(struct inode *inode, struct file *filp) { struct scull_dev *dev = &scull_w_device; /* device information */ spin_lock(&scull_w_lock); while (! scull_w_available()) { spin_unlock(&scull_w_lock); if (filp->f_flags & O_NONBLOCK) return -EAGAIN; if (wait_event_interruptible (scull_w_wait, scull_w_available())) return -ERESTARTSYS; /* tell the fs layer to handle it */ spin_lock(&scull_w_lock); } if (scull_w_count == 0) scull_w_owner = current->cred->uid.val; /* grab it */ scull_w_count++; spin_unlock(&scull_w_lock); /* then, everything else is copied from the bare scull device */ if ((filp->f_flags & O_ACCMODE) == O_WRONLY) scull_trim(dev); filp->private_data = dev; return 0; /* success */ }
static int scull_u_open(struct inode *inode, struct file *filp) { struct scull_dev *dev = &scull_u_device; /* device information */ spin_lock_init(&scull_u_lock); /* Initialize lock */ spin_lock(&scull_u_lock); /* spin till lock is acquired */ if (scull_u_count && (scull_u_owner != current_uid().val) && /* allow user */ (scull_u_owner != current_euid().val) && /* allow whoever did su */ !capable(CAP_DAC_OVERRIDE)) { /* still allow root */ spin_unlock(&scull_u_lock); return -EBUSY; /* -EPERM would confuse user */ } if (scull_u_count == 0) scull_u_owner = current_uid().val; /* grab it */ scull_u_count++; spin_unlock(&scull_u_lock); /* then everything else is copied from the bare scull device */ if ((filp->f_flags & O_ACCMODE) == O_WRONLY) scull_trim(dev); filp->private_data = dev; return 0; }
void scull_cleanup_module(void) { int i; dev_t devno = MKDEV(scull_major, scull_minor); if (scull_devices) { for (i = 0; i < scull_nr_devs; i++) { scull_trim(scull_devices + i);//??? cdev_del(&scull_devices[i].cdev); } kfree(scull_devices); } //#ifdef SCULL_DEBUG scull_remove_proc(); //#endif unregister_chrdev_region(devno, scull_nr_devs); // scull_p_cleanup(); // scull_access_cleanup(); }
//限制每次只能由一个进程打开 //只允许一个进程打开设备 static int scull_s_open(struct inode *inode, struct file *filp) { struct scull_dev *dev = &scull_s_device; /* 设备信息 */ /* 此设备中维护一个atomic_t变量 称为scull_s_available 该变量值初始化值为1,表明该设备真正可用 open 会减小并测试scull_s_available 并在其他进程打开该设备时拒绝访问 */ //int atomic_dec_and_test(atomic_t *v); 原子类型的变量v原子地减1,并判断结果是否为0,如果为0,返回真,否则返回假 if (! atomic_dec_and_test (&scull_s_available)) { //void atomic_inc(atomic_t *v); 原子类型变量v原子地增加1。 atomic_inc(&scull_s_available); return -EBUSY; /* 已打开 */ } /* 然后 从裸的scull设备中复制所有其他数据 */ if ( (filp->f_flags & O_ACCMODE) == O_WRONLY) { scull_trim(dev); } filp->private_data = dev; return 0; /* 成功 */ }
static int char_reg_setup_cdev (void) { int retval; int temp = 0; struct device *class_dev; dev_t devid = MKDEV (helloworld_major, helloworld_minor); scull_devices = kmalloc(helloworld_nr_device * sizeof (struct scull_dev),\ GFP_KERNEL); memset((char *)scull_devices, 0,\ helloworld_nr_device * sizeof(struct scull_dev)); for (; temp < helloworld_nr_device; temp++) { scull_devices[temp].quantum = quantum; scull_devices[temp].qset = qset; scull_devices[temp].size = 0; cdev_init(&scull_devices[temp].cdev, &helloworld_fops); scull_devices[temp].cdev.ops = &helloworld_fops; scull_devices[temp].cdev.owner = THIS_MODULE; } retval= cdev_add(&scull_devices[temp].cdev, devid, helloworld_nr_device); if (retval < 0) { DEBUG (1, "err_cdev_add."); goto err_cdev_add; } helloworld_class = class_create(THIS_MODULE, "hbgk_class"); if (IS_ERR(helloworld_class)) { retval = PTR_ERR(helloworld_class); DEBUG (1, "err_class_create."); goto err_class_create; } for (temp = 0; temp < helloworld_nr_device; temp++) { class_dev = device_create(helloworld_class, NULL, MKDEV(helloworld_major, temp), NULL, "hbgk_device%d", temp); //class_dev = device_create(bsg_class, parent, dev, NULL, "%s", devname); if (IS_ERR(class_dev)) { retval= PTR_ERR(class_dev); DEBUG (1, "err_device_create %d", temp); goto err_device_create; } } #if 0 cdev_p= cdev_alloc(); if (!cdev_p) { DEBUG(1, "cdev_alloc failed\n"); goto out; } cdev_p->owner = THIS_MODULE; cdev_p->ops = &helloworld_fops; err = cdev_add(cdev_p, devid, HELLOWORLD_MAX_DEVICE); if (err < 0) { DEBUG (1, "cdev_add fialed.\n"); goto err_cdev_add; } #endif return 0; err_device_create: class_destroy(helloworld_class); err_class_create: for (temp = 0; temp < helloworld_nr_device; temp++) { cdev_del(&scull_devices[temp].cdev); scull_trim(&scull_devices[temp]); } err_cdev_add: kfree (scull_devices); scull_devices = NULL; return retval; }
/* * The cleanup function is used to handle initialization failures as well. * Thefore, it must be careful to work correctly even if some of the items * have not been initialized */ inline void scull_cleanup_module(void) { scull_dev dev; scull_trim(dev); }