1 /* 2 * dvbdev.c 3 * 4 * Copyright (C) 2000 Ralph Metzler <ralph@convergence.de> 5 * & Marcus Metzler <marcus@convergence.de> 6 * for convergence integrated media GmbH 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public License 10 * as published by the Free Software Foundation; either version 2.1 11 * of the License, or (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 21 * 22 */ 23 24 #include <linux/types.h> 25 #include <linux/errno.h> 26 #include <linux/string.h> 27 #include <linux/module.h> 28 #include <linux/kernel.h> 29 #include <linux/init.h> 30 #include <linux/slab.h> 31 #include <linux/device.h> 32 #include <linux/fs.h> 33 #include <linux/cdev.h> 34 #include <linux/mutex.h> 35 #include "dvbdev.h" 36 37 static DEFINE_MUTEX(dvbdev_mutex); 38 static int dvbdev_debug; 39 40 module_param(dvbdev_debug, int, 0644); 41 MODULE_PARM_DESC(dvbdev_debug, "Turn on/off device debugging (default:off)."); 42 43 #define dprintk if (dvbdev_debug) printk 44 45 static LIST_HEAD(dvb_adapter_list); 46 static DEFINE_MUTEX(dvbdev_register_lock); 47 48 static const char * const dnames[] = { 49 "video", "audio", "sec", "frontend", "demux", "dvr", "ca", 50 "net", "osd" 51 }; 52 53 #ifdef CONFIG_DVB_DYNAMIC_MINORS 54 #define MAX_DVB_MINORS 256 55 #define DVB_MAX_IDS MAX_DVB_MINORS 56 #else 57 #define DVB_MAX_IDS 4 58 #define nums2minor(num,type,id) ((num << 6) | (id << 4) | type) 59 #define MAX_DVB_MINORS (DVB_MAX_ADAPTERS*64) 60 #endif 61 62 static struct class *dvb_class; 63 64 static struct dvb_device *dvb_minors[MAX_DVB_MINORS]; 65 static DECLARE_RWSEM(minor_rwsem); 66 67 static int dvb_device_open(struct inode *inode, struct file *file) 68 { 69 struct dvb_device *dvbdev; 70 71 mutex_lock(&dvbdev_mutex); 72 down_read(&minor_rwsem); 73 dvbdev = dvb_minors[iminor(inode)]; 74 75 if (dvbdev && dvbdev->fops) { 76 int err = 0; 77 const struct file_operations *new_fops; 78 79 new_fops = fops_get(dvbdev->fops); 80 if (!new_fops) 81 goto fail; 82 file->private_data = dvbdev; 83 replace_fops(file, new_fops); 84 if (file->f_op->open) 85 err = file->f_op->open(inode,file); 86 up_read(&minor_rwsem); 87 mutex_unlock(&dvbdev_mutex); 88 return err; 89 } 90 fail: 91 up_read(&minor_rwsem); 92 mutex_unlock(&dvbdev_mutex); 93 return -ENODEV; 94 } 95 96 97 static const struct file_operations dvb_device_fops = 98 { 99 .owner = THIS_MODULE, 100 .open = dvb_device_open, 101 .llseek = noop_llseek, 102 }; 103 104 static struct cdev dvb_device_cdev; 105 106 int dvb_generic_open(struct inode *inode, struct file *file) 107 { 108 struct dvb_device *dvbdev = file->private_data; 109 110 if (!dvbdev) 111 return -ENODEV; 112 113 if (!dvbdev->users) 114 return -EBUSY; 115 116 if ((file->f_flags & O_ACCMODE) == O_RDONLY) { 117 if (!dvbdev->readers) 118 return -EBUSY; 119 dvbdev->readers--; 120 } else { 121 if (!dvbdev->writers) 122 return -EBUSY; 123 dvbdev->writers--; 124 } 125 126 dvbdev->users--; 127 return 0; 128 } 129 EXPORT_SYMBOL(dvb_generic_open); 130 131 132 int dvb_generic_release(struct inode *inode, struct file *file) 133 { 134 struct dvb_device *dvbdev = file->private_data; 135 136 if (!dvbdev) 137 return -ENODEV; 138 139 if ((file->f_flags & O_ACCMODE) == O_RDONLY) { 140 dvbdev->readers++; 141 } else { 142 dvbdev->writers++; 143 } 144 145 dvbdev->users++; 146 return 0; 147 } 148 EXPORT_SYMBOL(dvb_generic_release); 149 150 151 long dvb_generic_ioctl(struct file *file, 152 unsigned int cmd, unsigned long arg) 153 { 154 struct dvb_device *dvbdev = file->private_data; 155 156 if (!dvbdev) 157 return -ENODEV; 158 159 if (!dvbdev->kernel_ioctl) 160 return -EINVAL; 161 162 return dvb_usercopy(file, cmd, arg, dvbdev->kernel_ioctl); 163 } 164 EXPORT_SYMBOL(dvb_generic_ioctl); 165 166 167 static int dvbdev_get_free_id (struct dvb_adapter *adap, int type) 168 { 169 u32 id = 0; 170 171 while (id < DVB_MAX_IDS) { 172 struct dvb_device *dev; 173 list_for_each_entry(dev, &adap->device_list, list_head) 174 if (dev->type == type && dev->id == id) 175 goto skip; 176 return id; 177 skip: 178 id++; 179 } 180 return -ENFILE; 181 } 182 183 184 int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, 185 const struct dvb_device *template, void *priv, int type) 186 { 187 struct dvb_device *dvbdev; 188 struct file_operations *dvbdevfops; 189 struct device *clsdev; 190 int minor; 191 int id; 192 193 mutex_lock(&dvbdev_register_lock); 194 195 if ((id = dvbdev_get_free_id (adap, type)) < 0){ 196 mutex_unlock(&dvbdev_register_lock); 197 *pdvbdev = NULL; 198 printk(KERN_ERR "%s: couldn't find free device id\n", __func__); 199 return -ENFILE; 200 } 201 202 *pdvbdev = dvbdev = kmalloc(sizeof(struct dvb_device), GFP_KERNEL); 203 204 if (!dvbdev){ 205 mutex_unlock(&dvbdev_register_lock); 206 return -ENOMEM; 207 } 208 209 dvbdevfops = kzalloc(sizeof(struct file_operations), GFP_KERNEL); 210 211 if (!dvbdevfops){ 212 kfree (dvbdev); 213 mutex_unlock(&dvbdev_register_lock); 214 return -ENOMEM; 215 } 216 217 memcpy(dvbdev, template, sizeof(struct dvb_device)); 218 dvbdev->type = type; 219 dvbdev->id = id; 220 dvbdev->adapter = adap; 221 dvbdev->priv = priv; 222 dvbdev->fops = dvbdevfops; 223 init_waitqueue_head (&dvbdev->wait_queue); 224 225 memcpy(dvbdevfops, template->fops, sizeof(struct file_operations)); 226 dvbdevfops->owner = adap->module; 227 228 list_add_tail (&dvbdev->list_head, &adap->device_list); 229 230 down_write(&minor_rwsem); 231 #ifdef CONFIG_DVB_DYNAMIC_MINORS 232 for (minor = 0; minor < MAX_DVB_MINORS; minor++) 233 if (dvb_minors[minor] == NULL) 234 break; 235 236 if (minor == MAX_DVB_MINORS) { 237 kfree(dvbdevfops); 238 kfree(dvbdev); 239 up_write(&minor_rwsem); 240 mutex_unlock(&dvbdev_register_lock); 241 return -EINVAL; 242 } 243 #else 244 minor = nums2minor(adap->num, type, id); 245 #endif 246 247 dvbdev->minor = minor; 248 dvb_minors[minor] = dvbdev; 249 up_write(&minor_rwsem); 250 251 mutex_unlock(&dvbdev_register_lock); 252 253 clsdev = device_create(dvb_class, adap->device, 254 MKDEV(DVB_MAJOR, minor), 255 dvbdev, "dvb%d.%s%d", adap->num, dnames[type], id); 256 if (IS_ERR(clsdev)) { 257 printk(KERN_ERR "%s: failed to create device dvb%d.%s%d (%ld)\n", 258 __func__, adap->num, dnames[type], id, PTR_ERR(clsdev)); 259 return PTR_ERR(clsdev); 260 } 261 262 dprintk(KERN_DEBUG "DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n", 263 adap->num, dnames[type], id, minor, minor); 264 265 return 0; 266 } 267 EXPORT_SYMBOL(dvb_register_device); 268 269 270 void dvb_unregister_device(struct dvb_device *dvbdev) 271 { 272 if (!dvbdev) 273 return; 274 275 down_write(&minor_rwsem); 276 dvb_minors[dvbdev->minor] = NULL; 277 up_write(&minor_rwsem); 278 279 device_destroy(dvb_class, MKDEV(DVB_MAJOR, dvbdev->minor)); 280 281 list_del (&dvbdev->list_head); 282 kfree (dvbdev->fops); 283 kfree (dvbdev); 284 } 285 EXPORT_SYMBOL(dvb_unregister_device); 286 287 static int dvbdev_check_free_adapter_num(int num) 288 { 289 struct list_head *entry; 290 list_for_each(entry, &dvb_adapter_list) { 291 struct dvb_adapter *adap; 292 adap = list_entry(entry, struct dvb_adapter, list_head); 293 if (adap->num == num) 294 return 0; 295 } 296 return 1; 297 } 298 299 static int dvbdev_get_free_adapter_num (void) 300 { 301 int num = 0; 302 303 while (num < DVB_MAX_ADAPTERS) { 304 if (dvbdev_check_free_adapter_num(num)) 305 return num; 306 num++; 307 } 308 309 return -ENFILE; 310 } 311 312 313 int dvb_register_adapter(struct dvb_adapter *adap, const char *name, 314 struct module *module, struct device *device, 315 short *adapter_nums) 316 { 317 int i, num; 318 319 mutex_lock(&dvbdev_register_lock); 320 321 for (i = 0; i < DVB_MAX_ADAPTERS; ++i) { 322 num = adapter_nums[i]; 323 if (num >= 0 && num < DVB_MAX_ADAPTERS) { 324 /* use the one the driver asked for */ 325 if (dvbdev_check_free_adapter_num(num)) 326 break; 327 } else { 328 num = dvbdev_get_free_adapter_num(); 329 break; 330 } 331 num = -1; 332 } 333 334 if (num < 0) { 335 mutex_unlock(&dvbdev_register_lock); 336 return -ENFILE; 337 } 338 339 memset (adap, 0, sizeof(struct dvb_adapter)); 340 INIT_LIST_HEAD (&adap->device_list); 341 342 printk(KERN_INFO "DVB: registering new adapter (%s)\n", name); 343 344 adap->num = num; 345 adap->name = name; 346 adap->module = module; 347 adap->device = device; 348 adap->mfe_shared = 0; 349 adap->mfe_dvbdev = NULL; 350 mutex_init (&adap->mfe_lock); 351 352 list_add_tail (&adap->list_head, &dvb_adapter_list); 353 354 mutex_unlock(&dvbdev_register_lock); 355 356 return num; 357 } 358 EXPORT_SYMBOL(dvb_register_adapter); 359 360 361 int dvb_unregister_adapter(struct dvb_adapter *adap) 362 { 363 mutex_lock(&dvbdev_register_lock); 364 list_del (&adap->list_head); 365 mutex_unlock(&dvbdev_register_lock); 366 return 0; 367 } 368 EXPORT_SYMBOL(dvb_unregister_adapter); 369 370 /* if the miracle happens and "generic_usercopy()" is included into 371 the kernel, then this can vanish. please don't make the mistake and 372 define this as video_usercopy(). this will introduce a dependecy 373 to the v4l "videodev.o" module, which is unnecessary for some 374 cards (ie. the budget dvb-cards don't need the v4l module...) */ 375 int dvb_usercopy(struct file *file, 376 unsigned int cmd, unsigned long arg, 377 int (*func)(struct file *file, 378 unsigned int cmd, void *arg)) 379 { 380 char sbuf[128]; 381 void *mbuf = NULL; 382 void *parg = NULL; 383 int err = -EINVAL; 384 385 /* Copy arguments into temp kernel buffer */ 386 switch (_IOC_DIR(cmd)) { 387 case _IOC_NONE: 388 /* 389 * For this command, the pointer is actually an integer 390 * argument. 391 */ 392 parg = (void *) arg; 393 break; 394 case _IOC_READ: /* some v4l ioctls are marked wrong ... */ 395 case _IOC_WRITE: 396 case (_IOC_WRITE | _IOC_READ): 397 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) { 398 parg = sbuf; 399 } else { 400 /* too big to allocate from stack */ 401 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL); 402 if (NULL == mbuf) 403 return -ENOMEM; 404 parg = mbuf; 405 } 406 407 err = -EFAULT; 408 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd))) 409 goto out; 410 break; 411 } 412 413 /* call driver */ 414 if ((err = func(file, cmd, parg)) == -ENOIOCTLCMD) 415 err = -ENOTTY; 416 417 if (err < 0) 418 goto out; 419 420 /* Copy results into user buffer */ 421 switch (_IOC_DIR(cmd)) 422 { 423 case _IOC_READ: 424 case (_IOC_WRITE | _IOC_READ): 425 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd))) 426 err = -EFAULT; 427 break; 428 } 429 430 out: 431 kfree(mbuf); 432 return err; 433 } 434 435 static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env) 436 { 437 struct dvb_device *dvbdev = dev_get_drvdata(dev); 438 439 add_uevent_var(env, "DVB_ADAPTER_NUM=%d", dvbdev->adapter->num); 440 add_uevent_var(env, "DVB_DEVICE_TYPE=%s", dnames[dvbdev->type]); 441 add_uevent_var(env, "DVB_DEVICE_NUM=%d", dvbdev->id); 442 return 0; 443 } 444 445 static char *dvb_devnode(struct device *dev, umode_t *mode) 446 { 447 struct dvb_device *dvbdev = dev_get_drvdata(dev); 448 449 return kasprintf(GFP_KERNEL, "dvb/adapter%d/%s%d", 450 dvbdev->adapter->num, dnames[dvbdev->type], dvbdev->id); 451 } 452 453 454 static int __init init_dvbdev(void) 455 { 456 int retval; 457 dev_t dev = MKDEV(DVB_MAJOR, 0); 458 459 if ((retval = register_chrdev_region(dev, MAX_DVB_MINORS, "DVB")) != 0) { 460 printk(KERN_ERR "dvb-core: unable to get major %d\n", DVB_MAJOR); 461 return retval; 462 } 463 464 cdev_init(&dvb_device_cdev, &dvb_device_fops); 465 if ((retval = cdev_add(&dvb_device_cdev, dev, MAX_DVB_MINORS)) != 0) { 466 printk(KERN_ERR "dvb-core: unable register character device\n"); 467 goto error; 468 } 469 470 dvb_class = class_create(THIS_MODULE, "dvb"); 471 if (IS_ERR(dvb_class)) { 472 retval = PTR_ERR(dvb_class); 473 goto error; 474 } 475 dvb_class->dev_uevent = dvb_uevent; 476 dvb_class->devnode = dvb_devnode; 477 return 0; 478 479 error: 480 cdev_del(&dvb_device_cdev); 481 unregister_chrdev_region(dev, MAX_DVB_MINORS); 482 return retval; 483 } 484 485 486 static void __exit exit_dvbdev(void) 487 { 488 class_destroy(dvb_class); 489 cdev_del(&dvb_device_cdev); 490 unregister_chrdev_region(MKDEV(DVB_MAJOR, 0), MAX_DVB_MINORS); 491 } 492 493 subsys_initcall(init_dvbdev); 494 module_exit(exit_dvbdev); 495 496 MODULE_DESCRIPTION("DVB Core Driver"); 497 MODULE_AUTHOR("Marcus Metzler, Ralph Metzler, Holger Waechtler"); 498 MODULE_LICENSE("GPL"); 499