分类: LINUX
2010-05-09 17:12:33
MINOR(dev_t dev)
int register_chrdev_region(dev_t first, unsigned int count, char *name); //指定设备编号 int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count, char *name); //动态生成设备编号 void unregister_chrdev_region(dev_t first, unsigned int count); //释放设备编号 |
if (scull_major) { dev = MKDEV(scull_major, scull_minor); result = register_chrdev_region(dev, scull_nr_devs, "scull"); } else { result = alloc_chrdev_region(&dev, scull_minor, scull_nr_devs,"scull"); scull_major = MAJOR(dev); } if (result < 0) { printk(KERN_WARNING "scull: can't get major %d\n", scull_major); return result; } |
/* * Set up the char_dev structure for this device. */ static void scull_setup_cdev(struct scull_dev *dev, int index) { int err, devno = MKDEV(scull_major, scull_minor + index); cdev_init(&dev->cdev, &scull_fops); dev->cdev.owner = THIS_MODULE; dev->cdev.ops = &scull_fops; //这句可以省略,在cdev_init中已经做过 err = cdev_add (&dev->cdev, devno, 1); /* Fail gracefully if need be 这步值得注意*/ if (err) printk(KERN_NOTICE "Error %d adding scull%d", err, index); } |
/* * Representation of scull quantum sets. */ struct scull_qset { void **data; struct scull_qset *next; }; struct scull_dev { struct scull_qset *data; /* Pointer to first quantum set */ int quantum; /* the current quantum size */ int qset; /* the current array size */ unsigned long size; /* amount of data stored here */ unsigned int access_key; /* used by sculluid and scullpriv */ struct semaphore sem; /* mutual exclusion semaphore */ struct cdev cdev; /* Char device structure */ }; |
void *kmalloc(size_t size, int flags); void kfree(void *ptr); |
int scull_trim(struct scull_dev *dev) { struct scull_qset *next, *dptr; int qset = dev->qset; /* 量子集中量子的个数*/ int i; for (dptr = dev->data; dptr; dptr = next) { /* 循环scull_set个数次,直到dptr为NULL为止。*/ if (dptr->data) { for (i = 0; i < qset; i++)/* 循环一个量子集中量子的个数次*/ kfree(dptr->data[i]);/* 释放其中一个量子的空间*/ kfree(dptr->data);/* 释放当前的scull_set的量子集的空间*/ dptr->data = NULL;/* 释放一个scull_set中的void **data指针*/ } next = dptr->next; /* 准备下个scull_set的指针*/ kfree(dptr);/* 释放当前的scull_set*/ } dev->size = 0; /* 当前的scull_device所存的数据为0字节*/ dev->quantum = scull_quantum;/* 初始化一个量子的大小*/ dev->qset = scull_qset;/* 初始化一个量子集中量子的个数*/ dev->data = NULL;/* 释放当前的scull_device的struct scull_qset *data指针*/ return 0; } |
/*Follow the list*/ struct scull_qset *scull_follow(struct scull_dev *dev, int n) { struct scull_qset *qs = dev->data; /* Allocate first qset explicitly if need be */ if (! qs) { qs = dev->data = kmalloc(sizeof(struct scull_qset), GFP_KERNEL); if (qs == NULL) return NULL; /* Never mind */ memset(qs, 0, sizeof(struct scull_qset)); } /* Then follow the list */ while (n--) { if (!qs->next) { qs->next = kmalloc(sizeof(struct scull_qset), GFP_KERNEL); if (qs->next == NULL) return NULL; /* Never mind */ memset(qs->next, 0, sizeof(struct scull_qset)); } qs = qs->next; continue; } return qs; } |
#define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );}) |
unsigned long copy_to_user(void __user *to, const void *from, unsigned long count); unsigned long copy_from_user(void *to, const void __user *from, unsigned long count); |
#define __copy_from_user(to,from,n) (memcpy(to, (void __force *)from, n), 0) #define __copy_to_user(to,from,n) (memcpy((void __force *)to, from, n), 0) |