static struct {
const char *name;
int vfl_type;
- int minor_offset;
+ int num_offset;
int dma;
enum v4l2_buf_type buf_type;
struct file_operations *fops;
{
struct cx18_stream *s = &cx->streams[type];
u32 cap = cx->v4l2_cap;
- int minor_offset = cx18_stream_info[type].minor_offset;
- int minor;
+ int num_offset = cx18_stream_info[type].num_offset;
+ int num = cx->num + cx18_first_minor + num_offset;
/* These four fields are always initialized. If v4l2dev == NULL, then
this stream is not in use. In that case no other fields but these
!(cap & (V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE)))
return 0;
- /* card number + user defined offset + device offset */
- minor = cx->num + cx18_first_minor + minor_offset;
-
/* User explicitly selected 0 buffers for these streams, so don't
create them. */
if (cx18_stream_info[type].dma != PCI_DMA_NONE &&
cx18_stream_init(cx, type);
- if (minor_offset == -1)
+ if (num_offset == -1)
return 0;
/* allocate and initialize the v4l2 video device structure */
snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "cx18-%d",
cx->num);
- s->v4l2dev->minor = minor;
+ s->v4l2dev->num = num;
s->v4l2dev->parent = &cx->dev->dev;
s->v4l2dev->fops = cx18_stream_info[type].fops;
s->v4l2dev->release = video_device_release;
/* Initialize v4l2 variables and register v4l2 devices */
int cx18_streams_setup(struct cx18 *cx)
{
- int type;
+ int type, ret;
/* Setup V4L2 Devices */
for (type = 0; type < CX18_MAX_STREAMS; type++) {
/* Prepare device */
- if (cx18_prep_dev(cx, type))
+ ret = cx18_prep_dev(cx, type);
+ if (ret < 0)
break;
/* Allocate Stream */
- if (cx18_stream_alloc(&cx->streams[type]))
+ ret = cx18_stream_alloc(&cx->streams[type]);
+ if (ret < 0)
break;
}
if (type == CX18_MAX_STREAMS)
/* One or more streams could not be initialized. Clean 'em all up. */
cx18_streams_cleanup(cx, 0);
- return -ENOMEM;
+ return ret;
}
static int cx18_reg_dev(struct cx18 *cx, int type)
{
struct cx18_stream *s = &cx->streams[type];
int vfl_type = cx18_stream_info[type].vfl_type;
- int minor;
+ int num, ret;
/* TODO: Shouldn't this be a VFL_TYPE_TRANSPORT or something?
* We need a VFL_TYPE_TS defined.
/* just return if no DVB is supported */
if ((cx->card->hw_all & CX18_HW_DVB) == 0)
return 0;
- if (cx18_dvb_register(s) < 0) {
+ ret = cx18_dvb_register(s);
+ if (ret < 0) {
CX18_ERR("DVB failed to register\n");
- return -EINVAL;
+ return ret;
}
}
if (s->v4l2dev == NULL)
return 0;
- minor = s->v4l2dev->minor;
+ num = s->v4l2dev->num;
+ /* card number + user defined offset + device offset */
+ if (type != CX18_ENC_STREAM_TYPE_MPG) {
+ struct cx18_stream *s_mpg = &cx->streams[CX18_ENC_STREAM_TYPE_MPG];
+
+ if (s_mpg->v4l2dev)
+ num = s_mpg->v4l2dev->num + cx18_stream_info[type].num_offset;
+ }
/* Register device. First try the desired minor, then any free one. */
- if (video_register_device(s->v4l2dev, vfl_type, minor) &&
- video_register_device(s->v4l2dev, vfl_type, -1)) {
- CX18_ERR("Couldn't register v4l2 device for %s minor %d\n",
- s->name, minor);
+ ret = video_register_device(s->v4l2dev, vfl_type, num);
+ if (ret < 0) {
+ CX18_ERR("Couldn't register v4l2 device for %s kernel number %d\n",
+ s->name, num);
video_device_release(s->v4l2dev);
s->v4l2dev = NULL;
- return -ENOMEM;
+ return ret;
}
- minor = s->v4l2dev->minor;
+ num = s->v4l2dev->num;
switch (vfl_type) {
case VFL_TYPE_GRABBER:
CX18_INFO("Registered device video%d for %s (%d MB)\n",
- minor, s->name, cx->options.megabytes[type]);
+ num, s->name, cx->options.megabytes[type]);
break;
case VFL_TYPE_RADIO:
CX18_INFO("Registered device radio%d for %s\n",
- minor - MINOR_VFL_TYPE_RADIO_MIN, s->name);
+ num, s->name);
break;
case VFL_TYPE_VBI:
if (cx->options.megabytes[type])
CX18_INFO("Registered device vbi%d for %s (%d MB)\n",
- minor - MINOR_VFL_TYPE_VBI_MIN,
+ num,
s->name, cx->options.megabytes[type]);
else
CX18_INFO("Registered device vbi%d for %s\n",
- minor - MINOR_VFL_TYPE_VBI_MIN, s->name);
+ num, s->name);
break;
}
int cx18_streams_register(struct cx18 *cx)
{
int type;
- int err = 0;
+ int err;
+ int ret = 0;
/* Register V4L2 devices */
- for (type = 0; type < CX18_MAX_STREAMS; type++)
- err |= cx18_reg_dev(cx, type);
+ for (type = 0; type < CX18_MAX_STREAMS; type++) {
+ err = cx18_reg_dev(cx, type);
+ if (err && ret == 0)
+ ret = err;
+ }
- if (err == 0)
+ if (ret == 0)
return 0;
/* One or more streams could not be initialized. Clean 'em all up. */
cx18_streams_cleanup(cx, 1);
- return -ENOMEM;
+ return ret;
}
/* Unregister v4l2 devices */