dvbdev.c 22.9 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/*
 * dvbdev.c
 *
 * Copyright (C) 2000 Ralph  Metzler <ralph@convergence.de>
 *                  & Marcus Metzler <marcus@convergence.de>
 *                    for convergence integrated media GmbH
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */

20 21
#define pr_fmt(fmt) "dvbdev: " fmt

L
Linus Torvalds 已提交
22 23 24 25 26 27 28 29 30 31
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/cdev.h>
32
#include <linux/mutex.h>
L
Linus Torvalds 已提交
33 34
#include "dvbdev.h"

35 36 37
/* Due to enum tuner_pad_index */
#include <media/tuner.h>

A
Arnd Bergmann 已提交
38
static DEFINE_MUTEX(dvbdev_mutex);
L
Linus Torvalds 已提交
39 40 41 42 43
static int dvbdev_debug;

module_param(dvbdev_debug, int, 0644);
MODULE_PARM_DESC(dvbdev_debug, "Turn on/off device debugging (default:off).");

44 45 46 47 48
#define dprintk(fmt, arg...) do {					\
	if (dvbdev_debug)						\
		printk(KERN_DEBUG pr_fmt("%s: " fmt),			\
		       __func__, ##arg);				\
} while (0)
L
Linus Torvalds 已提交
49 50

static LIST_HEAD(dvb_adapter_list);
51
static DEFINE_MUTEX(dvbdev_register_lock);
L
Linus Torvalds 已提交
52 53

static const char * const dnames[] = {
54 55 56 57 58 59 60 61 62
	[DVB_DEVICE_VIDEO] =		"video",
	[DVB_DEVICE_AUDIO] =		"audio",
	[DVB_DEVICE_SEC] =		"sec",
	[DVB_DEVICE_FRONTEND] =		"frontend",
	[DVB_DEVICE_DEMUX] =		"demux",
	[DVB_DEVICE_DVR] =		"dvr",
	[DVB_DEVICE_CA] =		"ca",
	[DVB_DEVICE_NET] =		"net",
	[DVB_DEVICE_OSD] =		"osd"
L
Linus Torvalds 已提交
63 64
};

65 66 67 68
#ifdef CONFIG_DVB_DYNAMIC_MINORS
#define MAX_DVB_MINORS		256
#define DVB_MAX_IDS		MAX_DVB_MINORS
#else
L
Linus Torvalds 已提交
69
#define DVB_MAX_IDS		4
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87

static int nums2minor(int num, enum dvb_device_type type, int id)
{
	int n = (num << 6) | (id << 4);

	switch (type) {
	case DVB_DEVICE_VIDEO:		return n;
	case DVB_DEVICE_AUDIO:		return n | 1;
	case DVB_DEVICE_SEC:		return n | 2;
	case DVB_DEVICE_FRONTEND:	return n | 3;
	case DVB_DEVICE_DEMUX:		return n | 4;
	case DVB_DEVICE_DVR:		return n | 5;
	case DVB_DEVICE_CA:		return n | 6;
	case DVB_DEVICE_NET:		return n | 7;
	case DVB_DEVICE_OSD:		return n | 8;
	}
}

L
Linus Torvalds 已提交
88
#define MAX_DVB_MINORS		(DVB_MAX_ADAPTERS*64)
89
#endif
L
Linus Torvalds 已提交
90

91
static struct class *dvb_class;
L
Linus Torvalds 已提交
92

93 94
static struct dvb_device *dvb_minors[MAX_DVB_MINORS];
static DECLARE_RWSEM(minor_rwsem);
L
Linus Torvalds 已提交
95 96 97 98 99

static int dvb_device_open(struct inode *inode, struct file *file)
{
	struct dvb_device *dvbdev;

A
Arnd Bergmann 已提交
100
	mutex_lock(&dvbdev_mutex);
101 102
	down_read(&minor_rwsem);
	dvbdev = dvb_minors[iminor(inode)];
L
Linus Torvalds 已提交
103 104 105

	if (dvbdev && dvbdev->fops) {
		int err = 0;
106
		const struct file_operations *new_fops;
L
Linus Torvalds 已提交
107

108 109
		new_fops = fops_get(dvbdev->fops);
		if (!new_fops)
L
Laurent Pinchart 已提交
110
			goto fail;
111 112 113
		file->private_data = dvbdev;
		replace_fops(file, new_fops);
		if (file->f_op->open)
114
			err = file->f_op->open(inode, file);
115
		up_read(&minor_rwsem);
A
Arnd Bergmann 已提交
116
		mutex_unlock(&dvbdev_mutex);
117
		return err;
L
Linus Torvalds 已提交
118
	}
L
Laurent Pinchart 已提交
119
fail:
120
	up_read(&minor_rwsem);
A
Arnd Bergmann 已提交
121
	mutex_unlock(&dvbdev_mutex);
L
Linus Torvalds 已提交
122 123 124 125
	return -ENODEV;
}


126
static const struct file_operations dvb_device_fops =
L
Linus Torvalds 已提交
127 128 129
{
	.owner =	THIS_MODULE,
	.open =		dvb_device_open,
130
	.llseek =	noop_llseek,
L
Linus Torvalds 已提交
131 132
};

133
static struct cdev dvb_device_cdev;
L
Linus Torvalds 已提交
134 135 136

int dvb_generic_open(struct inode *inode, struct file *file)
{
137
	struct dvb_device *dvbdev = file->private_data;
L
Linus Torvalds 已提交
138

139 140
	if (!dvbdev)
		return -ENODEV;
L
Linus Torvalds 已提交
141 142

	if (!dvbdev->users)
143
		return -EBUSY;
L
Linus Torvalds 已提交
144 145

	if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
146 147
		if (!dvbdev->readers)
			return -EBUSY;
L
Linus Torvalds 已提交
148 149
		dvbdev->readers--;
	} else {
150 151
		if (!dvbdev->writers)
			return -EBUSY;
L
Linus Torvalds 已提交
152 153 154 155 156 157 158 159 160 161 162
		dvbdev->writers--;
	}

	dvbdev->users--;
	return 0;
}
EXPORT_SYMBOL(dvb_generic_open);


int dvb_generic_release(struct inode *inode, struct file *file)
{
163
	struct dvb_device *dvbdev = file->private_data;
L
Linus Torvalds 已提交
164 165

	if (!dvbdev)
166
		return -ENODEV;
L
Linus Torvalds 已提交
167 168 169 170 171 172 173 174 175 176 177 178 179

	if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
		dvbdev->readers++;
	} else {
		dvbdev->writers++;
	}

	dvbdev->users++;
	return 0;
}
EXPORT_SYMBOL(dvb_generic_release);


180 181
long dvb_generic_ioctl(struct file *file,
		       unsigned int cmd, unsigned long arg)
L
Linus Torvalds 已提交
182
{
183
	struct dvb_device *dvbdev = file->private_data;
L
Linus Torvalds 已提交
184

185 186
	if (!dvbdev)
		return -ENODEV;
L
Linus Torvalds 已提交
187 188 189 190

	if (!dvbdev->kernel_ioctl)
		return -EINVAL;

A
Arnd Bergmann 已提交
191
	return dvb_usercopy(file, cmd, arg, dvbdev->kernel_ioctl);
L
Linus Torvalds 已提交
192 193 194 195 196 197 198 199 200
}
EXPORT_SYMBOL(dvb_generic_ioctl);


static int dvbdev_get_free_id (struct dvb_adapter *adap, int type)
{
	u32 id = 0;

	while (id < DVB_MAX_IDS) {
201 202
		struct dvb_device *dev;
		list_for_each_entry(dev, &adap->device_list, list_head)
L
Linus Torvalds 已提交
203 204 205 206 207 208 209 210 211
			if (dev->type == type && dev->id == id)
				goto skip;
		return id;
skip:
		id++;
	}
	return -ENFILE;
}

212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
static void dvb_media_device_free(struct dvb_device *dvbdev)
{
#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
	if (dvbdev->entity) {
		media_device_unregister_entity(dvbdev->entity);
		kfree(dvbdev->entity);
		kfree(dvbdev->pads);
		dvbdev->entity = NULL;
		dvbdev->pads = NULL;
	}

	if (dvbdev->tsout_entity) {
		int i;

		for (i = 0; i < dvbdev->tsout_num_entities; i++) {
			media_device_unregister_entity(&dvbdev->tsout_entity[i]);
			kfree(dvbdev->tsout_entity[i].name);
		}
		kfree(dvbdev->tsout_entity);
		kfree(dvbdev->tsout_pads);
		dvbdev->tsout_entity = NULL;
		dvbdev->tsout_pads = NULL;

		dvbdev->tsout_num_entities = 0;
	}

	if (dvbdev->intf_devnode) {
		media_devnode_remove(dvbdev->intf_devnode);
		dvbdev->intf_devnode = NULL;
	}
242 243 244 245 246 247 248

	if (dvbdev->adapter->conn) {
		media_device_unregister_entity(dvbdev->adapter->conn);
		dvbdev->adapter->conn = NULL;
		kfree(dvbdev->adapter->conn_pads);
		dvbdev->adapter->conn_pads = NULL;
	}
249 250 251
#endif
}

252
#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
253
static int dvb_create_tsout_entity(struct dvb_device *dvbdev,
254 255 256 257 258 259 260
				    const char *name, int npads)
{
	int i, ret = 0;

	dvbdev->tsout_pads = kcalloc(npads, sizeof(*dvbdev->tsout_pads),
				     GFP_KERNEL);
	if (!dvbdev->tsout_pads)
261 262
		return -ENOMEM;

263 264
	dvbdev->tsout_entity = kcalloc(npads, sizeof(*dvbdev->tsout_entity),
				       GFP_KERNEL);
265 266 267 268 269
	if (!dvbdev->tsout_entity)
		return -ENOMEM;

	dvbdev->tsout_num_entities = npads;

270 271 272 273 274
	for (i = 0; i < npads; i++) {
		struct media_pad *pads = &dvbdev->tsout_pads[i];
		struct media_entity *entity = &dvbdev->tsout_entity[i];

		entity->name = kasprintf(GFP_KERNEL, "%s #%d", name, i);
275 276
		if (!entity->name)
			return -ENOMEM;
277

278
		entity->function = MEDIA_ENT_F_IO_DTV;
279 280
		pads->flags = MEDIA_PAD_FL_SINK;

281
		ret = media_entity_pads_init(entity, 1, pads);
282
		if (ret < 0)
283
			return ret;
284 285 286 287

		ret = media_device_register_entity(dvbdev->adapter->mdev,
						   entity);
		if (ret < 0)
288
			return ret;
289
	}
290
	return 0;
291 292 293 294 295
}

#define DEMUX_TSOUT	"demux-tsout"
#define DVR_TSOUT	"dvr-tsout"

296 297
static int dvb_create_media_entity(struct dvb_device *dvbdev,
				   int type, int demux_sink_pads)
298
{
299
	int i, ret, npads;
300

301 302 303 304
	switch (type) {
	case DVB_DEVICE_FRONTEND:
		npads = 2;
		break;
305
	case DVB_DEVICE_DVR:
306 307 308
		ret = dvb_create_tsout_entity(dvbdev, DVR_TSOUT,
					      demux_sink_pads);
		return ret;
309
	case DVB_DEVICE_DEMUX:
310
		npads = 1 + demux_sink_pads;
311 312 313 314
		ret = dvb_create_tsout_entity(dvbdev, DEMUX_TSOUT,
					      demux_sink_pads);
		if (ret < 0)
			return ret;
315 316 317 318 319 320 321 322 323 324 325 326 327 328
		break;
	case DVB_DEVICE_CA:
		npads = 2;
		break;
	case DVB_DEVICE_NET:
		/*
		 * We should be creating entities for the MPE/ULE
		 * decapsulation hardware (or software implementation).
		 *
		 * However, the number of for the MPE/ULE decaps may not be
		 * fixed. As we don't have yet dynamic support for PADs at
		 * the Media Controller, let's not create the decap
		 * entities yet.
		 */
329
		return 0;
330
	default:
331
		return 0;
332
	}
333 334 335

	dvbdev->entity = kzalloc(sizeof(*dvbdev->entity), GFP_KERNEL);
	if (!dvbdev->entity)
336
		return -ENOMEM;
337 338

	dvbdev->entity->name = dvbdev->name;
339 340 341 342

	if (npads) {
		dvbdev->pads = kcalloc(npads, sizeof(*dvbdev->pads),
				       GFP_KERNEL);
343 344
		if (!dvbdev->pads)
			return -ENOMEM;
345 346
	}

347 348
	switch (type) {
	case DVB_DEVICE_FRONTEND:
349
		dvbdev->entity->function = MEDIA_ENT_F_DTV_DEMOD;
350 351
		dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK;
		dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE;
352 353
		break;
	case DVB_DEVICE_DEMUX:
354
		dvbdev->entity->function = MEDIA_ENT_F_TS_DEMUX;
355
		dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK;
356 357
		for (i = 1; i < npads; i++)
			dvbdev->pads[i].flags = MEDIA_PAD_FL_SOURCE;
358 359
		break;
	case DVB_DEVICE_CA:
360
		dvbdev->entity->function = MEDIA_ENT_F_DTV_CA;
361 362
		dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK;
		dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE;
363 364
		break;
	default:
365
		/* Should never happen, as the first switch prevents it */
366
		kfree(dvbdev->entity);
367
		kfree(dvbdev->pads);
368
		dvbdev->entity = NULL;
369 370
		dvbdev->pads = NULL;
		return 0;
371 372
	}

373
	if (npads) {
374
		ret = media_entity_pads_init(dvbdev->entity, npads, dvbdev->pads);
375 376
		if (ret)
			return ret;
377
	}
378 379 380
	ret = media_device_register_entity(dvbdev->adapter->mdev,
					   dvbdev->entity);
	if (ret)
381
		return ret;
382

383
	pr_info("%s: media entity '%s' registered.\n",
384
		__func__, dvbdev->entity->name);
385 386

	return 0;
387
}
388
#endif
L
Linus Torvalds 已提交
389

390 391 392
static int dvb_register_media_device(struct dvb_device *dvbdev,
				     int type, int minor,
				     unsigned demux_sink_pads)
393 394
{
#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
395
	struct media_link *link;
396
	u32 intf_type;
397
	int ret;
398 399

	if (!dvbdev->adapter->mdev)
400
		return 0;
401

402 403 404
	ret = dvb_create_media_entity(dvbdev, type, demux_sink_pads);
	if (ret)
		return ret;
405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422

	switch (type) {
	case DVB_DEVICE_FRONTEND:
		intf_type = MEDIA_INTF_T_DVB_FE;
		break;
	case DVB_DEVICE_DEMUX:
		intf_type = MEDIA_INTF_T_DVB_DEMUX;
		break;
	case DVB_DEVICE_DVR:
		intf_type = MEDIA_INTF_T_DVB_DVR;
		break;
	case DVB_DEVICE_CA:
		intf_type = MEDIA_INTF_T_DVB_CA;
		break;
	case DVB_DEVICE_NET:
		intf_type = MEDIA_INTF_T_DVB_NET;
		break;
	default:
423
		return 0;
424 425 426
	}

	dvbdev->intf_devnode = media_devnode_create(dvbdev->adapter->mdev,
427
						    intf_type, 0,
428
						    DVB_MAJOR, minor);
429 430 431

	if (!dvbdev->intf_devnode)
		return -ENOMEM;
432 433 434 435 436 437 438 439 440

	/*
	 * Create the "obvious" link, e. g. the ones that represent
	 * a direct association between an interface and an entity.
	 * Other links should be created elsewhere, like:
	 *		DVB FE intf    -> tuner
	 *		DVB demux intf -> dvr
	 */

441 442
	if (!dvbdev->entity)
		return 0;
443

444 445 446 447
	link = media_create_intf_link(dvbdev->entity, &dvbdev->intf_devnode->intf,
				      MEDIA_LNK_FL_ENABLED);
	if (!link)
		return -ENOMEM;
448
#endif
449
	return 0;
450 451
}

L
Linus Torvalds 已提交
452
int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
453 454
			const struct dvb_device *template, void *priv,
			enum dvb_device_type type, int demux_sink_pads)
L
Linus Torvalds 已提交
455 456
{
	struct dvb_device *dvbdev;
457
	struct file_operations *dvbdevfops;
458
	struct device *clsdev;
459
	int minor;
460
	int id, ret;
L
Linus Torvalds 已提交
461

462
	mutex_lock(&dvbdev_register_lock);
L
Linus Torvalds 已提交
463

464
	if ((id = dvbdev_get_free_id (adap, type)) < 0){
465
		mutex_unlock(&dvbdev_register_lock);
L
Linus Torvalds 已提交
466
		*pdvbdev = NULL;
467
		pr_err("%s: couldn't find free device id\n", __func__);
L
Linus Torvalds 已提交
468 469 470
		return -ENFILE;
	}

471
	*pdvbdev = dvbdev = kzalloc(sizeof(*dvbdev), GFP_KERNEL);
L
Linus Torvalds 已提交
472

473 474 475 476 477 478 479 480 481
	if (!dvbdev){
		mutex_unlock(&dvbdev_register_lock);
		return -ENOMEM;
	}

	dvbdevfops = kzalloc(sizeof(struct file_operations), GFP_KERNEL);

	if (!dvbdevfops){
		kfree (dvbdev);
482
		mutex_unlock(&dvbdev_register_lock);
L
Linus Torvalds 已提交
483 484 485 486 487 488 489 490
		return -ENOMEM;
	}

	memcpy(dvbdev, template, sizeof(struct dvb_device));
	dvbdev->type = type;
	dvbdev->id = id;
	dvbdev->adapter = adap;
	dvbdev->priv = priv;
491
	dvbdev->fops = dvbdevfops;
492
	init_waitqueue_head (&dvbdev->wait_queue);
L
Linus Torvalds 已提交
493

494 495
	memcpy(dvbdevfops, template->fops, sizeof(struct file_operations));
	dvbdevfops->owner = adap->module;
L
Linus Torvalds 已提交
496 497 498

	list_add_tail (&dvbdev->list_head, &adap->device_list);

499 500 501 502 503 504 505 506 507
	down_write(&minor_rwsem);
#ifdef CONFIG_DVB_DYNAMIC_MINORS
	for (minor = 0; minor < MAX_DVB_MINORS; minor++)
		if (dvb_minors[minor] == NULL)
			break;

	if (minor == MAX_DVB_MINORS) {
		kfree(dvbdevfops);
		kfree(dvbdev);
508
		up_write(&minor_rwsem);
509 510 511 512 513 514 515 516 517 518 519
		mutex_unlock(&dvbdev_register_lock);
		return -EINVAL;
	}
#else
	minor = nums2minor(adap->num, type, id);
#endif

	dvbdev->minor = minor;
	dvb_minors[minor] = dvbdev;
	up_write(&minor_rwsem);

520 521
	ret = dvb_register_media_device(dvbdev, type, minor, demux_sink_pads);
	if (ret) {
522
		pr_err("%s: dvb_register_media_device failed to create the mediagraph\n",
523 524 525 526 527 528 529 530 531 532
		      __func__);

		dvb_media_device_free(dvbdev);
		kfree(dvbdevfops);
		kfree(dvbdev);
		up_write(&minor_rwsem);
		mutex_unlock(&dvbdev_register_lock);
		return ret;
	}

533 534
	mutex_unlock(&dvbdev_register_lock);

535
	clsdev = device_create(dvb_class, adap->device,
536
			       MKDEV(DVB_MAJOR, minor),
537
			       dvbdev, "dvb%d.%s%d", adap->num, dnames[type], id);
538
	if (IS_ERR(clsdev)) {
539
		pr_err("%s: failed to create device dvb%d.%s%d (%ld)\n",
540
		       __func__, adap->num, dnames[type], id, PTR_ERR(clsdev));
541 542
		return PTR_ERR(clsdev);
	}
543
	dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
544
		adap->num, dnames[type], id, minor, minor);
L
Linus Torvalds 已提交
545 546 547 548 549 550

	return 0;
}
EXPORT_SYMBOL(dvb_register_device);


551
void dvb_remove_device(struct dvb_device *dvbdev)
L
Linus Torvalds 已提交
552 553 554 555
{
	if (!dvbdev)
		return;

556 557 558 559
	down_write(&minor_rwsem);
	dvb_minors[dvbdev->minor] = NULL;
	up_write(&minor_rwsem);

560
	dvb_media_device_free(dvbdev);
561

562
	device_destroy(dvb_class, MKDEV(DVB_MAJOR, dvbdev->minor));
563

L
Linus Torvalds 已提交
564
	list_del (&dvbdev->list_head);
565 566 567 568 569 570 571 572 573
}
EXPORT_SYMBOL(dvb_remove_device);


void dvb_free_device(struct dvb_device *dvbdev)
{
	if (!dvbdev)
		return;

574
	kfree (dvbdev->fops);
L
Linus Torvalds 已提交
575 576
	kfree (dvbdev);
}
577 578 579 580 581 582 583 584
EXPORT_SYMBOL(dvb_free_device);


void dvb_unregister_device(struct dvb_device *dvbdev)
{
	dvb_remove_device(dvbdev);
	dvb_free_device(dvbdev);
}
L
Linus Torvalds 已提交
585 586
EXPORT_SYMBOL(dvb_unregister_device);

587 588

#ifdef CONFIG_MEDIA_CONTROLLER_DVB
589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610

static int dvb_create_io_intf_links(struct dvb_adapter *adap,
				    struct media_interface *intf,
				    char *name)
{
	struct media_device *mdev = adap->mdev;
	struct media_entity *entity;
	struct media_link *link;

	media_device_for_each_entity(entity, mdev) {
		if (entity->function == MEDIA_ENT_F_IO_DTV) {
			if (strncmp(entity->name, name, strlen(name)))
				continue;
			link = media_create_intf_link(entity, intf,
						      MEDIA_LNK_FL_ENABLED);
			if (!link)
				return -ENOMEM;
		}
	}
	return 0;
}

611 612
int dvb_create_media_graph(struct dvb_adapter *adap,
			   bool create_rf_connector)
613 614
{
	struct media_device *mdev = adap->mdev;
615
	struct media_entity *entity, *tuner = NULL, *demod = NULL, *conn;
616
	struct media_entity *demux = NULL, *ca = NULL;
617
	struct media_link *link;
618
	struct media_interface *intf;
619 620
	unsigned demux_pad = 0;
	unsigned dvr_pad = 0;
621
	unsigned ntuner = 0, ndemod = 0;
622
	int ret;
623
	static const char *connector_name = "Television";
624 625

	if (!mdev)
626
		return 0;
627 628

	media_device_for_each_entity(entity, mdev) {
629
		switch (entity->function) {
630
		case MEDIA_ENT_F_TUNER:
631
			tuner = entity;
632
			ntuner++;
633
			break;
634
		case MEDIA_ENT_F_DTV_DEMOD:
635
			demod = entity;
636
			ndemod++;
637
			break;
638
		case MEDIA_ENT_F_TS_DEMUX:
639 640
			demux = entity;
			break;
641
		case MEDIA_ENT_F_DTV_CA:
642 643 644 645 646
			ca = entity;
			break;
		}
	}

647 648 649 650 651 652 653 654 655 656 657 658
	/*
	 * Prepare to signalize to media_create_pad_links() that multiple
	 * entities of the same type exists and a 1:n or n:1 links need to be
	 * created.
	 * NOTE: if both tuner and demod have multiple instances, it is up
	 * to the caller driver to create such links.
	 */
	if (ntuner > 1)
		tuner = NULL;
	if (ndemod > 1)
		demod = NULL;

659 660 661 662 663 664
	if (create_rf_connector) {
		conn = kzalloc(sizeof(*conn), GFP_KERNEL);
		if (!conn)
			return -ENOMEM;
		adap->conn = conn;

665
		adap->conn_pads = kzalloc(sizeof(*adap->conn_pads), GFP_KERNEL);
666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681
		if (!adap->conn_pads)
			return -ENOMEM;

		conn->flags = MEDIA_ENT_FL_CONNECTOR;
		conn->function = MEDIA_ENT_F_CONN_RF;
		conn->name = connector_name;
		adap->conn_pads->flags = MEDIA_PAD_FL_SOURCE;

		ret = media_entity_pads_init(conn, 1, adap->conn_pads);
		if (ret)
			return ret;

		ret = media_device_register_entity(mdev, conn);
		if (ret)
			return ret;

682 683 684 685 686 687 688 689
		if (!ntuner)
			ret = media_create_pad_links(mdev,
						     MEDIA_ENT_F_CONN_RF,
						     conn, 0,
						     MEDIA_ENT_F_DTV_DEMOD,
						     demod, 0,
						     MEDIA_LNK_FL_ENABLED,
						     false);
690
		else
691 692 693 694 695 696 697
			ret = media_create_pad_links(mdev,
						     MEDIA_ENT_F_CONN_RF,
						     conn, 0,
						     MEDIA_ENT_F_TUNER,
						     tuner, TUNER_PAD_RF_INPUT,
						     MEDIA_LNK_FL_ENABLED,
						     false);
698 699 700 701
		if (ret)
			return ret;
	}

702 703 704
	if (ntuner && ndemod) {
		ret = media_create_pad_links(mdev,
					     MEDIA_ENT_F_TUNER,
705
					     tuner, TUNER_PAD_OUTPUT,
706 707 708
					     MEDIA_ENT_F_DTV_DEMOD,
					     demod, 0, MEDIA_LNK_FL_ENABLED,
					     false);
709 710 711
		if (ret)
			return ret;
	}
712

713 714 715 716 717 718 719
	if (ndemod && demux) {
		ret = media_create_pad_links(mdev,
					     MEDIA_ENT_F_DTV_DEMOD,
					     demod, 1,
					     MEDIA_ENT_F_TS_DEMUX,
					     demux, 0, MEDIA_LNK_FL_ENABLED,
					     false);
720
		if (ret)
721
			return ret;
722 723 724 725
	}
	if (demux && ca) {
		ret = media_create_pad_link(demux, 1, ca,
					    0, MEDIA_LNK_FL_ENABLED);
726
		if (ret)
727
			return ret;
728
	}
729

730 731 732
	/* Create demux links for each ringbuffer/pad */
	if (demux) {
		media_device_for_each_entity(entity, mdev) {
733
			if (entity->function == MEDIA_ENT_F_IO_DTV) {
734
				if (!strncmp(entity->name, DVR_TSOUT,
735 736 737 738 739 740 741
				    strlen(DVR_TSOUT))) {
					ret = media_create_pad_link(demux,
								++dvr_pad,
							    entity, 0, 0);
					if (ret)
						return ret;
				}
742
				if (!strncmp(entity->name, DEMUX_TSOUT,
743 744
				    strlen(DEMUX_TSOUT))) {
					ret = media_create_pad_link(demux,
745
							      ++demux_pad,
746 747 748 749
							    entity, 0, 0);
					if (ret)
						return ret;
				}
750 751 752 753
			}
		}
	}

754
	/* Create interface links for FE->tuner, DVR->demux and CA->ca */
755
	media_device_for_each_intf(intf, mdev) {
756 757 758 759 760 761
		if (intf->type == MEDIA_INTF_T_DVB_CA && ca) {
			link = media_create_intf_link(ca, intf,
						      MEDIA_LNK_FL_ENABLED);
			if (!link)
				return -ENOMEM;
		}
762

763 764 765 766 767 768
		if (intf->type == MEDIA_INTF_T_DVB_FE && tuner) {
			link = media_create_intf_link(tuner, intf,
						      MEDIA_LNK_FL_ENABLED);
			if (!link)
				return -ENOMEM;
		}
769 770 771 772 773 774
#if 0
		/*
		 * Indirect link - let's not create yet, as we don't know how
		 *		   to handle indirect links, nor if this will
		 *		   actually be needed.
		 */
775 776 777 778 779 780
		if (intf->type == MEDIA_INTF_T_DVB_DVR && demux) {
			link = media_create_intf_link(demux, intf,
						      MEDIA_LNK_FL_ENABLED);
			if (!link)
				return -ENOMEM;
		}
781
#endif
782 783 784 785 786 787 788 789 790
		if (intf->type == MEDIA_INTF_T_DVB_DVR) {
			ret = dvb_create_io_intf_links(adap, intf, DVR_TSOUT);
			if (ret)
				return ret;
		}
		if (intf->type == MEDIA_INTF_T_DVB_DEMUX) {
			ret = dvb_create_io_intf_links(adap, intf, DEMUX_TSOUT);
			if (ret)
				return ret;
791
		}
792
	}
793
	return 0;
794 795
}
EXPORT_SYMBOL_GPL(dvb_create_media_graph);
796
#endif
797

798 799 800 801 802 803 804 805 806 807 808
static int dvbdev_check_free_adapter_num(int num)
{
	struct list_head *entry;
	list_for_each(entry, &dvb_adapter_list) {
		struct dvb_adapter *adap;
		adap = list_entry(entry, struct dvb_adapter, list_head);
		if (adap->num == num)
			return 0;
	}
	return 1;
}
L
Linus Torvalds 已提交
809 810 811 812 813 814

static int dvbdev_get_free_adapter_num (void)
{
	int num = 0;

	while (num < DVB_MAX_ADAPTERS) {
815 816
		if (dvbdev_check_free_adapter_num(num))
			return num;
L
Linus Torvalds 已提交
817 818 819 820 821 822 823
		num++;
	}

	return -ENFILE;
}


824 825 826
int dvb_register_adapter(struct dvb_adapter *adap, const char *name,
			 struct module *module, struct device *device,
			 short *adapter_nums)
L
Linus Torvalds 已提交
827
{
828
	int i, num;
L
Linus Torvalds 已提交
829

830
	mutex_lock(&dvbdev_register_lock);
L
Linus Torvalds 已提交
831

832 833 834 835 836 837 838 839 840 841 842 843 844 845
	for (i = 0; i < DVB_MAX_ADAPTERS; ++i) {
		num = adapter_nums[i];
		if (num >= 0  &&  num < DVB_MAX_ADAPTERS) {
		/* use the one the driver asked for */
			if (dvbdev_check_free_adapter_num(num))
				break;
		} else {
			num = dvbdev_get_free_adapter_num();
			break;
		}
		num = -1;
	}

	if (num < 0) {
846
		mutex_unlock(&dvbdev_register_lock);
L
Linus Torvalds 已提交
847 848 849 850 851 852
		return -ENFILE;
	}

	memset (adap, 0, sizeof(struct dvb_adapter));
	INIT_LIST_HEAD (&adap->device_list);

853
	pr_info("DVB: registering new adapter (%s)\n", name);
L
Linus Torvalds 已提交
854 855 856 857

	adap->num = num;
	adap->name = name;
	adap->module = module;
858
	adap->device = device;
859 860 861
	adap->mfe_shared = 0;
	adap->mfe_dvbdev = NULL;
	mutex_init (&adap->mfe_lock);
L
Linus Torvalds 已提交
862 863 864

	list_add_tail (&adap->list_head, &dvb_adapter_list);

865
	mutex_unlock(&dvbdev_register_lock);
L
Linus Torvalds 已提交
866 867 868 869 870 871 872 873

	return num;
}
EXPORT_SYMBOL(dvb_register_adapter);


int dvb_unregister_adapter(struct dvb_adapter *adap)
{
874
	mutex_lock(&dvbdev_register_lock);
L
Linus Torvalds 已提交
875
	list_del (&adap->list_head);
876
	mutex_unlock(&dvbdev_register_lock);
L
Linus Torvalds 已提交
877 878 879 880 881 882 883 884 885
	return 0;
}
EXPORT_SYMBOL(dvb_unregister_adapter);

/* if the miracle happens and "generic_usercopy()" is included into
   the kernel, then this can vanish. please don't make the mistake and
   define this as video_usercopy(). this will introduce a dependecy
   to the v4l "videodev.o" module, which is unnecessary for some
   cards (ie. the budget dvb-cards don't need the v4l module...) */
886
int dvb_usercopy(struct file *file,
887
		     unsigned int cmd, unsigned long arg,
888
		     int (*func)(struct file *file,
L
Linus Torvalds 已提交
889 890
		     unsigned int cmd, void *arg))
{
891 892 893 894 895 896 897 898
	char    sbuf[128];
	void    *mbuf = NULL;
	void    *parg = NULL;
	int     err  = -EINVAL;

	/*  Copy arguments into temp kernel buffer  */
	switch (_IOC_DIR(cmd)) {
	case _IOC_NONE:
L
Linus Torvalds 已提交
899 900 901 902 903 904
		/*
		 * For this command, the pointer is actually an integer
		 * argument.
		 */
		parg = (void *) arg;
		break;
905 906 907 908
	case _IOC_READ: /* some v4l ioctls are marked wrong ... */
	case _IOC_WRITE:
	case (_IOC_WRITE | _IOC_READ):
		if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
909
			parg = sbuf;
910
		} else {
911
			/* too big to allocate from stack */
912
			mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
913 914 915
			if (NULL == mbuf)
				return -ENOMEM;
			parg = mbuf;
916 917 918 919
		}

		err = -EFAULT;
		if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
920
			goto out;
921 922 923 924
		break;
	}

	/* call driver */
925
	if ((err = func(file, cmd, parg)) == -ENOIOCTLCMD)
926
		err = -ENOTTY;
927 928 929 930 931 932 933 934 935 936

	if (err < 0)
		goto out;

	/*  Copy results into user buffer  */
	switch (_IOC_DIR(cmd))
	{
	case _IOC_READ:
	case (_IOC_WRITE | _IOC_READ):
		if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
937
			err = -EFAULT;
938 939
		break;
	}
L
Linus Torvalds 已提交
940 941

out:
942 943
	kfree(mbuf);
	return err;
L
Linus Torvalds 已提交
944 945
}

946 947 948 949 950
static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env)
{
	struct dvb_device *dvbdev = dev_get_drvdata(dev);

	add_uevent_var(env, "DVB_ADAPTER_NUM=%d", dvbdev->adapter->num);
951 952
	add_uevent_var(env, "DVB_DEVICE_TYPE=%s", dnames[dvbdev->type]);
	add_uevent_var(env, "DVB_DEVICE_NUM=%d", dvbdev->id);
953 954 955
	return 0;
}

956
static char *dvb_devnode(struct device *dev, umode_t *mode)
957 958 959 960 961 962 963 964
{
	struct dvb_device *dvbdev = dev_get_drvdata(dev);

	return kasprintf(GFP_KERNEL, "dvb/adapter%d/%s%d",
		dvbdev->adapter->num, dnames[dvbdev->type], dvbdev->id);
}


L
Linus Torvalds 已提交
965 966 967 968 969 970
static int __init init_dvbdev(void)
{
	int retval;
	dev_t dev = MKDEV(DVB_MAJOR, 0);

	if ((retval = register_chrdev_region(dev, MAX_DVB_MINORS, "DVB")) != 0) {
971
		pr_err("dvb-core: unable to get major %d\n", DVB_MAJOR);
L
Linus Torvalds 已提交
972 973 974 975 976
		return retval;
	}

	cdev_init(&dvb_device_cdev, &dvb_device_fops);
	if ((retval = cdev_add(&dvb_device_cdev, dev, MAX_DVB_MINORS)) != 0) {
977
		pr_err("dvb-core: unable register character device\n");
L
Linus Torvalds 已提交
978 979 980
		goto error;
	}

981
	dvb_class = class_create(THIS_MODULE, "dvb");
L
Linus Torvalds 已提交
982 983 984 985
	if (IS_ERR(dvb_class)) {
		retval = PTR_ERR(dvb_class);
		goto error;
	}
986
	dvb_class->dev_uevent = dvb_uevent;
987
	dvb_class->devnode = dvb_devnode;
L
Linus Torvalds 已提交
988 989 990 991 992 993 994 995 996 997 998
	return 0;

error:
	cdev_del(&dvb_device_cdev);
	unregister_chrdev_region(dev, MAX_DVB_MINORS);
	return retval;
}


static void __exit exit_dvbdev(void)
{
999
	class_destroy(dvb_class);
L
Linus Torvalds 已提交
1000
	cdev_del(&dvb_device_cdev);
1001
	unregister_chrdev_region(MKDEV(DVB_MAJOR, 0), MAX_DVB_MINORS);
L
Linus Torvalds 已提交
1002 1003
}

1004
subsys_initcall(init_dvbdev);
L
Linus Torvalds 已提交
1005 1006 1007 1008 1009
module_exit(exit_dvbdev);

MODULE_DESCRIPTION("DVB Core Driver");
MODULE_AUTHOR("Marcus Metzler, Ralph Metzler, Holger Waechtler");
MODULE_LICENSE("GPL");