Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 124015
b: refs/heads/master
c: 5dd3f30
h: refs/heads/master
i:
  124013: 572638f
  124011: 79e35a4
  124007: 0bae04d
  123999: 5e04b0c
v: v3
  • Loading branch information
Andreas Oberritter authored and Mauro Carvalho Chehab committed Dec 29, 2008
1 parent 924076b commit 05df9a8
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 20 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 568e9bb8d764300e1de81d49ae698cc970a511d8
refs/heads/master: 5dd3f3071070f5a306bdf8d474c80062f5691cba
13 changes: 13 additions & 0 deletions trunk/drivers/media/dvb/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,19 @@
# DVB device configuration
#

config DVB_DYNAMIC_MINORS
bool "Dynamic DVB minor allocation"
depends on DVB_CORE
default n
help
If you say Y here, the DVB subsystem will use dynamic minor
allocation for any device that uses the DVB major number.
This means that you can have more than 4 of a single type
of device (like demuxes and frontends) per adapter, but udev
will be required to manage the device nodes.

If you are unsure about this, say N here.

menuconfig DVB_CAPTURE_DRIVERS
bool "DVB/ATSC adapters"
depends on DVB_CORE
Expand Down
57 changes: 38 additions & 19 deletions trunk/drivers/media/dvb/dvb-core/dvbdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,33 +50,27 @@ static const char * const dnames[] = {
"net", "osd"
};

#ifdef CONFIG_DVB_DYNAMIC_MINORS
#define MAX_DVB_MINORS 256
#define DVB_MAX_IDS MAX_DVB_MINORS
#else
#define DVB_MAX_IDS 4
#define nums2minor(num,type,id) ((num << 6) | (id << 4) | type)
#define MAX_DVB_MINORS (DVB_MAX_ADAPTERS*64)
#endif

static struct class *dvb_class;

static struct dvb_device* dvbdev_find_device (int minor)
{
struct dvb_adapter *adap;

list_for_each_entry(adap, &dvb_adapter_list, list_head) {
struct dvb_device *dev;
list_for_each_entry(dev, &adap->device_list, list_head)
if (nums2minor(adap->num, dev->type, dev->id) == minor)
return dev;
}

return NULL;
}

static struct dvb_device *dvb_minors[MAX_DVB_MINORS];
static DECLARE_RWSEM(minor_rwsem);

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

lock_kernel();
dvbdev = dvbdev_find_device (iminor(inode));
down_read(&minor_rwsem);
dvbdev = dvb_minors[iminor(inode)];

if (dvbdev && dvbdev->fops) {
int err = 0;
Expand All @@ -92,9 +86,11 @@ static int dvb_device_open(struct inode *inode, struct file *file)
file->f_op = fops_get(old_fops);
}
fops_put(old_fops);
up_read(&minor_rwsem);
unlock_kernel();
return err;
}
up_read(&minor_rwsem);
unlock_kernel();
return -ENODEV;
}
Expand Down Expand Up @@ -192,6 +188,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
struct dvb_device *dvbdev;
struct file_operations *dvbdevfops;
struct device *clsdev;
int minor;
int id;

mutex_lock(&dvbdev_register_lock);
Expand Down Expand Up @@ -231,6 +228,26 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,

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

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);
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);

mutex_unlock(&dvbdev_register_lock);

clsdev = device_create(dvb_class, adap->device,
Expand All @@ -243,8 +260,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
}

dprintk(KERN_DEBUG "DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
adap->num, dnames[type], id, nums2minor(adap->num, type, id),
nums2minor(adap->num, type, id));
adap->num, dnames[type], id, minor, minor);

return 0;
}
Expand All @@ -256,8 +272,11 @@ void dvb_unregister_device(struct dvb_device *dvbdev)
if (!dvbdev)
return;

device_destroy(dvb_class, MKDEV(DVB_MAJOR, nums2minor(dvbdev->adapter->num,
dvbdev->type, dvbdev->id)));
down_write(&minor_rwsem);
dvb_minors[dvbdev->minor] = NULL;
up_write(&minor_rwsem);

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

list_del (&dvbdev->list_head);
kfree (dvbdev->fops);
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/media/dvb/dvb-core/dvbdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ struct dvb_device {
struct file_operations *fops;
struct dvb_adapter *adapter;
int type;
int minor;
u32 id;

/* in theory, 'users' can vanish now,
Expand Down

0 comments on commit 05df9a8

Please sign in to comment.