X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fchar%2Fraw.c;h=a2e33ec796151ab4f96f4a869447f87088f0e300;hb=9bf4aaab3e101692164d49b7ca357651eb691cb6;hp=9c19dbc8eb19128be7d1d00acd4ef199853ce868;hpb=db216c3d5e4c040e557a50f8f5d35d5c415e8c1c;p=linux-2.6.git diff --git a/drivers/char/raw.c b/drivers/char/raw.c index 9c19dbc8e..a2e33ec79 100644 --- a/drivers/char/raw.c +++ b/drivers/char/raw.c @@ -18,6 +18,7 @@ #include #include #include +#include #include @@ -26,6 +27,7 @@ struct raw_device_data { int inuse; }; +static struct class_simple *raw_class; static struct raw_device_data raw_devices[MAX_RAW_MINORS]; static DECLARE_MUTEX(raw_mutex); static struct file_operations raw_ctl_fops; /* forward declaration */ @@ -123,6 +125,13 @@ raw_ioctl(struct inode *inode, struct file *filp, return ioctl_by_bdev(bdev, command, arg); } +static void bind_device(struct raw_config_request *rq) +{ + class_simple_device_remove(MKDEV(RAW_MAJOR, rq->raw_minor)); + class_simple_device_add(raw_class, MKDEV(RAW_MAJOR, rq->raw_minor), + NULL, "raw%d", rq->raw_minor); +} + /* * Deal with ioctls against the raw-device control interface, to bind * and unbind other raw devices. @@ -191,12 +200,16 @@ static int raw_ctl_ioctl(struct inode *inode, struct file *filp, if (rq.block_major == 0 && rq.block_minor == 0) { /* unbind */ rawdev->binding = NULL; + class_simple_device_remove(MKDEV(RAW_MAJOR, + rq.raw_minor)); } else { rawdev->binding = bdget(dev); if (rawdev->binding == NULL) err = -ENOMEM; - else + else { __module_get(THIS_MODULE); + bind_device(&rq); + } } up(&raw_mutex); } else { @@ -287,6 +300,15 @@ static int __init raw_init(void) goto error; } + raw_class = class_simple_create(THIS_MODULE, "raw"); + if (IS_ERR(raw_class)) { + printk(KERN_ERR "Error creating raw class.\n"); + cdev_del(&raw_cdev); + unregister_chrdev_region(dev, MAX_RAW_MINORS); + goto error; + } + class_simple_device_add(raw_class, MKDEV(RAW_MAJOR, 0), NULL, "rawctl"); + devfs_mk_cdev(MKDEV(RAW_MAJOR, 0), S_IFCHR | S_IRUGO | S_IWUGO, "raw/rawctl"); @@ -309,6 +331,8 @@ static void __exit raw_exit(void) devfs_remove("raw/raw%d", i); devfs_remove("raw/rawctl"); devfs_remove("raw"); + class_simple_device_remove(MKDEV(RAW_MAJOR, 0)); + class_simple_destroy(raw_class); cdev_del(&raw_cdev); unregister_chrdev_region(MKDEV(RAW_MAJOR, 0), MAX_RAW_MINORS); }