xref: /linux-6.15/drivers/media/dvb-core/dvbdev.c (revision df2f94e5)
1 /*
2  * dvbdev.c
3  *
4  * Copyright (C) 2000 Ralph  Metzler <[email protected]>
5  *                  & Marcus Metzler <[email protected]>
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 static void dvb_create_tsout_entity(struct dvb_device *dvbdev,
184 				    const char *name, int npads)
185 {
186 #if defined(CONFIG_MEDIA_CONTROLLER_DVB)
187 	int i, ret = 0;
188 
189 	dvbdev->tsout_pads = kcalloc(npads, sizeof(*dvbdev->tsout_pads),
190 				     GFP_KERNEL);
191 	if (!dvbdev->tsout_pads)
192 		return;
193 	dvbdev->tsout_entity = kcalloc(npads, sizeof(*dvbdev->tsout_entity),
194 				       GFP_KERNEL);
195 	if (!dvbdev->tsout_entity) {
196 		kfree(dvbdev->tsout_pads);
197 		dvbdev->tsout_pads = NULL;
198 		return;
199 	}
200 	for (i = 0; i < npads; i++) {
201 		struct media_pad *pads = &dvbdev->tsout_pads[i];
202 		struct media_entity *entity = &dvbdev->tsout_entity[i];
203 
204 		entity->name = kasprintf(GFP_KERNEL, "%s #%d", name, i);
205 		if (!entity->name) {
206 			ret = -ENOMEM;
207 			break;
208 		}
209 
210 		entity->type = MEDIA_ENT_T_DVB_TSOUT;
211 		pads->flags = MEDIA_PAD_FL_SINK;
212 
213 		ret = media_entity_init(entity, 1, pads);
214 		if (ret < 0)
215 			break;
216 
217 		ret = media_device_register_entity(dvbdev->adapter->mdev,
218 						   entity);
219 		if (ret < 0)
220 			break;
221 	}
222 
223 	if (!ret) {
224 		dvbdev->tsout_num_entities = npads;
225 		return;
226 	}
227 
228 	for (i--; i >= 0; i--) {
229 		media_device_unregister_entity(&dvbdev->tsout_entity[i]);
230 		kfree(dvbdev->tsout_entity[i].name);
231 	}
232 
233 	printk(KERN_ERR
234 		"%s: media_device_register_entity failed for %s\n",
235 		__func__, name);
236 
237 	kfree(dvbdev->tsout_entity);
238 	kfree(dvbdev->tsout_pads);
239 	dvbdev->tsout_entity = NULL;
240 	dvbdev->tsout_pads = NULL;
241 #endif
242 }
243 
244 #define DEMUX_TSOUT	"demux-tsout"
245 #define DVR_TSOUT	"dvr-tsout"
246 
247 static void dvb_create_media_entity(struct dvb_device *dvbdev,
248 				    int type, int demux_sink_pads)
249 {
250 #if defined(CONFIG_MEDIA_CONTROLLER_DVB)
251 	int i, ret = 0, npads;
252 
253 	switch (type) {
254 	case DVB_DEVICE_FRONTEND:
255 		npads = 2;
256 		break;
257 	case DVB_DEVICE_DVR:
258 		dvb_create_tsout_entity(dvbdev, DVR_TSOUT, demux_sink_pads);
259 		return;
260 	case DVB_DEVICE_DEMUX:
261 		npads = 1 + demux_sink_pads;
262 		dvb_create_tsout_entity(dvbdev, DEMUX_TSOUT, demux_sink_pads);
263 		break;
264 	case DVB_DEVICE_CA:
265 		npads = 2;
266 		break;
267 	case DVB_DEVICE_NET:
268 		/*
269 		 * We should be creating entities for the MPE/ULE
270 		 * decapsulation hardware (or software implementation).
271 		 *
272 		 * However, the number of for the MPE/ULE decaps may not be
273 		 * fixed. As we don't have yet dynamic support for PADs at
274 		 * the Media Controller, let's not create the decap
275 		 * entities yet.
276 		 */
277 		return;
278 	default:
279 		return;
280 	}
281 
282 	dvbdev->entity = kzalloc(sizeof(*dvbdev->entity), GFP_KERNEL);
283 	if (!dvbdev->entity)
284 		return;
285 
286 	dvbdev->entity->name = dvbdev->name;
287 
288 	if (npads) {
289 		dvbdev->pads = kcalloc(npads, sizeof(*dvbdev->pads),
290 				       GFP_KERNEL);
291 		if (!dvbdev->pads) {
292 			kfree(dvbdev->entity);
293 			return;
294 		}
295 	}
296 
297 	switch (type) {
298 	case DVB_DEVICE_FRONTEND:
299 		dvbdev->entity->type = MEDIA_ENT_T_DVB_DEMOD;
300 		dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK;
301 		dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE;
302 		break;
303 	case DVB_DEVICE_DEMUX:
304 		dvbdev->entity->type = MEDIA_ENT_T_DVB_DEMUX;
305 		dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK;
306 		for (i = 1; i < npads; i++)
307 			dvbdev->pads[i].flags = MEDIA_PAD_FL_SOURCE;
308 		break;
309 	case DVB_DEVICE_CA:
310 		dvbdev->entity->type = MEDIA_ENT_T_DVB_CA;
311 		dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK;
312 		dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE;
313 		break;
314 	default:
315 		kfree(dvbdev->entity);
316 		dvbdev->entity = NULL;
317 		return;
318 	}
319 
320 	if (npads)
321 		ret = media_entity_init(dvbdev->entity, npads, dvbdev->pads);
322 	if (!ret)
323 		ret = media_device_register_entity(dvbdev->adapter->mdev,
324 						   dvbdev->entity);
325 	if (ret < 0) {
326 		printk(KERN_ERR
327 			"%s: media_device_register_entity failed for %s\n",
328 			__func__, dvbdev->entity->name);
329 
330 		media_device_unregister_entity(dvbdev->entity);
331 		for (i = 0; i < dvbdev->tsout_num_entities; i++) {
332 			media_device_unregister_entity(&dvbdev->tsout_entity[i]);
333 			kfree(dvbdev->tsout_entity[i].name);
334 		}
335 		kfree(dvbdev->pads);
336 		kfree(dvbdev->entity);
337 		kfree(dvbdev->tsout_pads);
338 		kfree(dvbdev->tsout_entity);
339 		dvbdev->entity = NULL;
340 		return;
341 	}
342 
343 	printk(KERN_DEBUG "%s: media entity '%s' registered.\n",
344 		__func__, dvbdev->entity->name);
345 #endif
346 }
347 
348 static void dvb_register_media_device(struct dvb_device *dvbdev,
349 				      int type, int minor,
350 				      unsigned demux_sink_pads)
351 {
352 #if defined(CONFIG_MEDIA_CONTROLLER_DVB)
353 	u32 intf_type;
354 
355 	if (!dvbdev->adapter->mdev)
356 		return;
357 
358 	dvb_create_media_entity(dvbdev, type, demux_sink_pads);
359 
360 	switch (type) {
361 	case DVB_DEVICE_FRONTEND:
362 		intf_type = MEDIA_INTF_T_DVB_FE;
363 		break;
364 	case DVB_DEVICE_DEMUX:
365 		intf_type = MEDIA_INTF_T_DVB_DEMUX;
366 		break;
367 	case DVB_DEVICE_DVR:
368 		intf_type = MEDIA_INTF_T_DVB_DVR;
369 		break;
370 	case DVB_DEVICE_CA:
371 		intf_type = MEDIA_INTF_T_DVB_CA;
372 		break;
373 	case DVB_DEVICE_NET:
374 		intf_type = MEDIA_INTF_T_DVB_NET;
375 		break;
376 	default:
377 		return;
378 	}
379 
380 	dvbdev->intf_devnode = media_devnode_create(dvbdev->adapter->mdev,
381 						 intf_type, 0,
382 						 DVB_MAJOR, minor,
383 						 GFP_KERNEL);
384 
385 	/*
386 	 * Create the "obvious" link, e. g. the ones that represent
387 	 * a direct association between an interface and an entity.
388 	 * Other links should be created elsewhere, like:
389 	 *		DVB FE intf    -> tuner
390 	 *		DVB demux intf -> dvr
391 	 */
392 
393 	if (!dvbdev->entity || !dvbdev->intf_devnode)
394 		return;
395 
396 	media_create_intf_link(dvbdev->entity, &dvbdev->intf_devnode->intf, 0);
397 
398 #endif
399 }
400 
401 int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
402 			const struct dvb_device *template, void *priv, int type,
403 			int demux_sink_pads)
404 {
405 	struct dvb_device *dvbdev;
406 	struct file_operations *dvbdevfops;
407 	struct device *clsdev;
408 	int minor;
409 	int id;
410 
411 	mutex_lock(&dvbdev_register_lock);
412 
413 	if ((id = dvbdev_get_free_id (adap, type)) < 0){
414 		mutex_unlock(&dvbdev_register_lock);
415 		*pdvbdev = NULL;
416 		printk(KERN_ERR "%s: couldn't find free device id\n", __func__);
417 		return -ENFILE;
418 	}
419 
420 	*pdvbdev = dvbdev = kmalloc(sizeof(struct dvb_device), GFP_KERNEL);
421 
422 	if (!dvbdev){
423 		mutex_unlock(&dvbdev_register_lock);
424 		return -ENOMEM;
425 	}
426 
427 	dvbdevfops = kzalloc(sizeof(struct file_operations), GFP_KERNEL);
428 
429 	if (!dvbdevfops){
430 		kfree (dvbdev);
431 		mutex_unlock(&dvbdev_register_lock);
432 		return -ENOMEM;
433 	}
434 
435 	memcpy(dvbdev, template, sizeof(struct dvb_device));
436 	dvbdev->type = type;
437 	dvbdev->id = id;
438 	dvbdev->adapter = adap;
439 	dvbdev->priv = priv;
440 	dvbdev->fops = dvbdevfops;
441 	init_waitqueue_head (&dvbdev->wait_queue);
442 
443 	memcpy(dvbdevfops, template->fops, sizeof(struct file_operations));
444 	dvbdevfops->owner = adap->module;
445 
446 	list_add_tail (&dvbdev->list_head, &adap->device_list);
447 
448 	down_write(&minor_rwsem);
449 #ifdef CONFIG_DVB_DYNAMIC_MINORS
450 	for (minor = 0; minor < MAX_DVB_MINORS; minor++)
451 		if (dvb_minors[minor] == NULL)
452 			break;
453 
454 	if (minor == MAX_DVB_MINORS) {
455 		kfree(dvbdevfops);
456 		kfree(dvbdev);
457 		up_write(&minor_rwsem);
458 		mutex_unlock(&dvbdev_register_lock);
459 		return -EINVAL;
460 	}
461 #else
462 	minor = nums2minor(adap->num, type, id);
463 #endif
464 
465 	dvbdev->minor = minor;
466 	dvb_minors[minor] = dvbdev;
467 	up_write(&minor_rwsem);
468 
469 	mutex_unlock(&dvbdev_register_lock);
470 
471 	clsdev = device_create(dvb_class, adap->device,
472 			       MKDEV(DVB_MAJOR, minor),
473 			       dvbdev, "dvb%d.%s%d", adap->num, dnames[type], id);
474 	if (IS_ERR(clsdev)) {
475 		printk(KERN_ERR "%s: failed to create device dvb%d.%s%d (%ld)\n",
476 		       __func__, adap->num, dnames[type], id, PTR_ERR(clsdev));
477 		return PTR_ERR(clsdev);
478 	}
479 	dprintk(KERN_DEBUG "DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
480 		adap->num, dnames[type], id, minor, minor);
481 
482 	dvb_register_media_device(dvbdev, type, minor, demux_sink_pads);
483 
484 	return 0;
485 }
486 EXPORT_SYMBOL(dvb_register_device);
487 
488 
489 void dvb_unregister_device(struct dvb_device *dvbdev)
490 {
491 	if (!dvbdev)
492 		return;
493 
494 	down_write(&minor_rwsem);
495 	dvb_minors[dvbdev->minor] = NULL;
496 	up_write(&minor_rwsem);
497 
498 	device_destroy(dvb_class, MKDEV(DVB_MAJOR, dvbdev->minor));
499 
500 #if defined(CONFIG_MEDIA_CONTROLLER_DVB)
501 	if (dvbdev->entity) {
502 		int i;
503 
504 		media_device_unregister_entity(dvbdev->entity);
505 		for (i = 0; i < dvbdev->tsout_num_entities; i++) {
506 			media_device_unregister_entity(&dvbdev->tsout_entity[i]);
507 			kfree(dvbdev->tsout_entity[i].name);
508 		}
509 
510 		kfree(dvbdev->entity);
511 		kfree(dvbdev->pads);
512 		kfree(dvbdev->tsout_entity);
513 		kfree(dvbdev->tsout_pads);
514 	}
515 #endif
516 
517 	list_del (&dvbdev->list_head);
518 	kfree (dvbdev->fops);
519 	kfree (dvbdev);
520 }
521 EXPORT_SYMBOL(dvb_unregister_device);
522 
523 
524 #ifdef CONFIG_MEDIA_CONTROLLER_DVB
525 void dvb_create_media_graph(struct dvb_adapter *adap)
526 {
527 	struct media_device *mdev = adap->mdev;
528 	struct media_entity *entity, *tuner = NULL, *demod = NULL;
529 	struct media_entity *demux = NULL, *ca = NULL;
530 	struct media_interface *intf;
531 	unsigned demux_pad = 0;
532 	unsigned dvr_pad = 0;
533 
534 	if (!mdev)
535 		return;
536 
537 	media_device_for_each_entity(entity, mdev) {
538 		switch (entity->type) {
539 		case MEDIA_ENT_T_V4L2_SUBDEV_TUNER:
540 			tuner = entity;
541 			break;
542 		case MEDIA_ENT_T_DVB_DEMOD:
543 			demod = entity;
544 			break;
545 		case MEDIA_ENT_T_DVB_DEMUX:
546 			demux = entity;
547 			break;
548 		case MEDIA_ENT_T_DVB_CA:
549 			ca = entity;
550 			break;
551 		}
552 	}
553 
554 	if (tuner && demod)
555 		media_create_pad_link(tuner, 0, demod, 0, 0);
556 
557 	if (demod && demux)
558 		media_create_pad_link(demod, 1, demux, 0, MEDIA_LNK_FL_ENABLED);
559 	if (demux && ca)
560 		media_create_pad_link(demux, 1, ca, 0, MEDIA_LNK_FL_ENABLED);
561 
562 	/* Create demux links for each ringbuffer/pad */
563 	if (demux) {
564 		media_device_for_each_entity(entity, mdev) {
565 			if (entity->type == MEDIA_ENT_T_DVB_TSOUT) {
566 				if (!strncmp(entity->name, DVR_TSOUT,
567 					strlen(DVR_TSOUT)))
568 					media_create_pad_link(demux,
569 							      ++dvr_pad,
570 							entity, 0, 0);
571 				if (!strncmp(entity->name, DEMUX_TSOUT,
572 					strlen(DEMUX_TSOUT)))
573 					media_create_pad_link(demux,
574 							      ++demux_pad,
575 							entity, 0, 0);
576 			}
577 		}
578 	}
579 
580 	/* Create indirect interface links for FE->tuner, DVR->demux and CA->ca */
581 	list_for_each_entry(intf, &mdev->interfaces, list) {
582 		if (intf->type == MEDIA_INTF_T_DVB_CA && ca)
583 			media_create_intf_link(ca, intf, 0);
584 		if (intf->type == MEDIA_INTF_T_DVB_FE && tuner)
585 			media_create_intf_link(tuner, intf, 0);
586 
587 		if (intf->type == MEDIA_INTF_T_DVB_DVR && demux)
588 			media_create_intf_link(demux, intf, 0);
589 
590 		media_device_for_each_entity(entity, mdev) {
591 			if (entity->type == MEDIA_ENT_T_DVB_TSOUT) {
592 				if (!strcmp(entity->name, DVR_TSOUT))
593 					media_create_intf_link(entity, intf, 0);
594 				if (!strcmp(entity->name, DEMUX_TSOUT))
595 					media_create_intf_link(entity, intf, 0);
596 				break;
597 			}
598 		}
599 	}
600 }
601 EXPORT_SYMBOL_GPL(dvb_create_media_graph);
602 #endif
603 
604 static int dvbdev_check_free_adapter_num(int num)
605 {
606 	struct list_head *entry;
607 	list_for_each(entry, &dvb_adapter_list) {
608 		struct dvb_adapter *adap;
609 		adap = list_entry(entry, struct dvb_adapter, list_head);
610 		if (adap->num == num)
611 			return 0;
612 	}
613 	return 1;
614 }
615 
616 static int dvbdev_get_free_adapter_num (void)
617 {
618 	int num = 0;
619 
620 	while (num < DVB_MAX_ADAPTERS) {
621 		if (dvbdev_check_free_adapter_num(num))
622 			return num;
623 		num++;
624 	}
625 
626 	return -ENFILE;
627 }
628 
629 
630 int dvb_register_adapter(struct dvb_adapter *adap, const char *name,
631 			 struct module *module, struct device *device,
632 			 short *adapter_nums)
633 {
634 	int i, num;
635 
636 	mutex_lock(&dvbdev_register_lock);
637 
638 	for (i = 0; i < DVB_MAX_ADAPTERS; ++i) {
639 		num = adapter_nums[i];
640 		if (num >= 0  &&  num < DVB_MAX_ADAPTERS) {
641 		/* use the one the driver asked for */
642 			if (dvbdev_check_free_adapter_num(num))
643 				break;
644 		} else {
645 			num = dvbdev_get_free_adapter_num();
646 			break;
647 		}
648 		num = -1;
649 	}
650 
651 	if (num < 0) {
652 		mutex_unlock(&dvbdev_register_lock);
653 		return -ENFILE;
654 	}
655 
656 	memset (adap, 0, sizeof(struct dvb_adapter));
657 	INIT_LIST_HEAD (&adap->device_list);
658 
659 	printk(KERN_INFO "DVB: registering new adapter (%s)\n", name);
660 
661 	adap->num = num;
662 	adap->name = name;
663 	adap->module = module;
664 	adap->device = device;
665 	adap->mfe_shared = 0;
666 	adap->mfe_dvbdev = NULL;
667 	mutex_init (&adap->mfe_lock);
668 
669 	list_add_tail (&adap->list_head, &dvb_adapter_list);
670 
671 	mutex_unlock(&dvbdev_register_lock);
672 
673 	return num;
674 }
675 EXPORT_SYMBOL(dvb_register_adapter);
676 
677 
678 int dvb_unregister_adapter(struct dvb_adapter *adap)
679 {
680 	mutex_lock(&dvbdev_register_lock);
681 	list_del (&adap->list_head);
682 	mutex_unlock(&dvbdev_register_lock);
683 	return 0;
684 }
685 EXPORT_SYMBOL(dvb_unregister_adapter);
686 
687 /* if the miracle happens and "generic_usercopy()" is included into
688    the kernel, then this can vanish. please don't make the mistake and
689    define this as video_usercopy(). this will introduce a dependecy
690    to the v4l "videodev.o" module, which is unnecessary for some
691    cards (ie. the budget dvb-cards don't need the v4l module...) */
692 int dvb_usercopy(struct file *file,
693 		     unsigned int cmd, unsigned long arg,
694 		     int (*func)(struct file *file,
695 		     unsigned int cmd, void *arg))
696 {
697 	char    sbuf[128];
698 	void    *mbuf = NULL;
699 	void    *parg = NULL;
700 	int     err  = -EINVAL;
701 
702 	/*  Copy arguments into temp kernel buffer  */
703 	switch (_IOC_DIR(cmd)) {
704 	case _IOC_NONE:
705 		/*
706 		 * For this command, the pointer is actually an integer
707 		 * argument.
708 		 */
709 		parg = (void *) arg;
710 		break;
711 	case _IOC_READ: /* some v4l ioctls are marked wrong ... */
712 	case _IOC_WRITE:
713 	case (_IOC_WRITE | _IOC_READ):
714 		if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
715 			parg = sbuf;
716 		} else {
717 			/* too big to allocate from stack */
718 			mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
719 			if (NULL == mbuf)
720 				return -ENOMEM;
721 			parg = mbuf;
722 		}
723 
724 		err = -EFAULT;
725 		if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
726 			goto out;
727 		break;
728 	}
729 
730 	/* call driver */
731 	if ((err = func(file, cmd, parg)) == -ENOIOCTLCMD)
732 		err = -ENOTTY;
733 
734 	if (err < 0)
735 		goto out;
736 
737 	/*  Copy results into user buffer  */
738 	switch (_IOC_DIR(cmd))
739 	{
740 	case _IOC_READ:
741 	case (_IOC_WRITE | _IOC_READ):
742 		if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
743 			err = -EFAULT;
744 		break;
745 	}
746 
747 out:
748 	kfree(mbuf);
749 	return err;
750 }
751 
752 static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env)
753 {
754 	struct dvb_device *dvbdev = dev_get_drvdata(dev);
755 
756 	add_uevent_var(env, "DVB_ADAPTER_NUM=%d", dvbdev->adapter->num);
757 	add_uevent_var(env, "DVB_DEVICE_TYPE=%s", dnames[dvbdev->type]);
758 	add_uevent_var(env, "DVB_DEVICE_NUM=%d", dvbdev->id);
759 	return 0;
760 }
761 
762 static char *dvb_devnode(struct device *dev, umode_t *mode)
763 {
764 	struct dvb_device *dvbdev = dev_get_drvdata(dev);
765 
766 	return kasprintf(GFP_KERNEL, "dvb/adapter%d/%s%d",
767 		dvbdev->adapter->num, dnames[dvbdev->type], dvbdev->id);
768 }
769 
770 
771 static int __init init_dvbdev(void)
772 {
773 	int retval;
774 	dev_t dev = MKDEV(DVB_MAJOR, 0);
775 
776 	if ((retval = register_chrdev_region(dev, MAX_DVB_MINORS, "DVB")) != 0) {
777 		printk(KERN_ERR "dvb-core: unable to get major %d\n", DVB_MAJOR);
778 		return retval;
779 	}
780 
781 	cdev_init(&dvb_device_cdev, &dvb_device_fops);
782 	if ((retval = cdev_add(&dvb_device_cdev, dev, MAX_DVB_MINORS)) != 0) {
783 		printk(KERN_ERR "dvb-core: unable register character device\n");
784 		goto error;
785 	}
786 
787 	dvb_class = class_create(THIS_MODULE, "dvb");
788 	if (IS_ERR(dvb_class)) {
789 		retval = PTR_ERR(dvb_class);
790 		goto error;
791 	}
792 	dvb_class->dev_uevent = dvb_uevent;
793 	dvb_class->devnode = dvb_devnode;
794 	return 0;
795 
796 error:
797 	cdev_del(&dvb_device_cdev);
798 	unregister_chrdev_region(dev, MAX_DVB_MINORS);
799 	return retval;
800 }
801 
802 
803 static void __exit exit_dvbdev(void)
804 {
805 	class_destroy(dvb_class);
806 	cdev_del(&dvb_device_cdev);
807 	unregister_chrdev_region(MKDEV(DVB_MAJOR, 0), MAX_DVB_MINORS);
808 }
809 
810 subsys_initcall(init_dvbdev);
811 module_exit(exit_dvbdev);
812 
813 MODULE_DESCRIPTION("DVB Core Driver");
814 MODULE_AUTHOR("Marcus Metzler, Ralph Metzler, Holger Waechtler");
815 MODULE_LICENSE("GPL");
816