/* * Match LDD devices to drivers. Just do a simple name test. */ staticint ldd_match(struct device *dev, struct device_driver *driver) { return!strncmp(dev->bus_id, driver->name,strlen(driver->name)); //这里比较的长度为什么是driver->name的长度,而不是dev->bus_id的长度,是因为,一般一个驱动可以驱动多个设备,而一个设备只能有一个驱动,比如这里的驱动名为sculld,而设备有sculld0,sculld1等。 }
/* * And the bus type. */ struct bus_type ldd_bus_type ={ .name ="ldd", .match = ldd_match, .hotplug = ldd_hotplug, };
int sculld_init(void) { int result, i; dev_t dev = MKDEV(sculld_major, 0);
/* * Register your major, and accept a dynamic number. */ if(sculld_major) result = register_chrdev_region(dev, sculld_devs,"sculld"); else{ result = alloc_chrdev_region(&dev, 0, sculld_devs,"sculld"); sculld_major = MAJOR(dev); } if(result < 0) return result;
/* * Register with the driver core. */ register_ldd_driver(&sculld_driver);
/* * allocate the devices -- we can't have them static, as the number * can be specified at load time */ sculld_devices = kmalloc(sculld_devs*sizeof(struct sculld_dev), GFP_KERNEL); if(!sculld_devices){ result =-ENOMEM; goto fail_malloc; } memset(sculld_devices, 0, sculld_devs*sizeof(struct sculld_dev)); for(i = 0; i < sculld_devs; i++){ sculld_devices[i].order = sculld_order; sculld_devices[i].qset = sculld_qset; sema_init (&sculld_devices[i].sem, 1); sculld_setup_cdev(sculld_devices + i, i); sculld_register_dev(sculld_devices + i, i); }
#ifdef SCULLD_USE_PROC /* only when available */ create_proc_read_entry("sculldmem", 0,NULL, sculld_read_procmem,NULL); #endif return 0;/* succeed */
struct sculld_dev { void**data; struct sculld_dev *next;/* next listitem */ int vmas;/* active mappings */ int order;/* the current allocation order */ int qset;/* the current array size */ size_t size;/* 32-bit will suffice */ struct semaphore sem;/* Mutual exclusion */ struct cdev cdev; char devname[20]; struct ldd_device ldev; };