Merge tag 'media/v6.18-2' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media

Pull media fixes from Mauro Carvalho Chehab:

 - honour privacy led with pdx86/int3472

 - fix invalid file access on cx18 and ivtv

 - forbid remove_bufs when legacy fileio is active on videbuf2

 - add an heuristic to find stream entity on uvcvideo

* tag 'media/v6.18-2' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media:
  media: videobuf2: forbid remove_bufs when legacy fileio is active
  media: uvcvideo: Use heuristic to find stream entity
  media: v4l2-subdev / pdx86: int3472: Use "privacy" as con_id for the privacy LED
  media: ivtv: Fix invalid access to file *
  media: cx18: Fix invalid access to file *
This commit is contained in:
Linus Torvalds
2025-11-05 18:56:15 +09:00
10 changed files with 73 additions and 37 deletions

View File

@@ -1010,6 +1010,11 @@ int vb2_ioctl_remove_bufs(struct file *file, void *priv,
if (vb2_queue_is_busy(vdev->queue, file))
return -EBUSY;
if (vb2_fileio_is_active(vdev->queue)) {
dprintk(vdev->queue, 1, "file io in progress\n");
return -EBUSY;
}
return vb2_core_remove_bufs(vdev->queue, d->index, d->count);
}
EXPORT_SYMBOL_GPL(vb2_ioctl_remove_bufs);

View File

@@ -1136,11 +1136,8 @@ int cx18_init_on_first_open(struct cx18 *cx)
int video_input;
int fw_retry_count = 3;
struct v4l2_frequency vf;
struct cx18_open_id fh;
v4l2_std_id std;
fh.cx = cx;
if (test_bit(CX18_F_I_FAILED, &cx->i_flags))
return -ENXIO;
@@ -1220,14 +1217,14 @@ int cx18_init_on_first_open(struct cx18 *cx)
video_input = cx->active_input;
cx->active_input++; /* Force update of input */
cx18_s_input(NULL, &fh, video_input);
cx18_do_s_input(cx, video_input);
/* Let the VIDIOC_S_STD ioctl do all the work, keeps the code
in one place. */
cx->std++; /* Force full standard initialization */
std = (cx->tuner_std == V4L2_STD_ALL) ? V4L2_STD_NTSC_M : cx->tuner_std;
cx18_s_std(NULL, &fh, std);
cx18_s_frequency(NULL, &fh, &vf);
cx18_do_s_std(cx, std);
cx18_do_s_frequency(cx, &vf);
return 0;
}

View File

@@ -521,10 +521,8 @@ static int cx18_g_input(struct file *file, void *fh, unsigned int *i)
return 0;
}
int cx18_s_input(struct file *file, void *fh, unsigned int inp)
int cx18_do_s_input(struct cx18 *cx, unsigned int inp)
{
struct cx18_open_id *id = file2id(file);
struct cx18 *cx = id->cx;
v4l2_std_id std = V4L2_STD_ALL;
const struct cx18_card_video_input *card_input =
cx->card->video_inputs + inp;
@@ -558,6 +556,11 @@ int cx18_s_input(struct file *file, void *fh, unsigned int inp)
return 0;
}
static int cx18_s_input(struct file *file, void *fh, unsigned int inp)
{
return cx18_do_s_input(file2id(file)->cx, inp);
}
static int cx18_g_frequency(struct file *file, void *fh,
struct v4l2_frequency *vf)
{
@@ -570,11 +573,8 @@ static int cx18_g_frequency(struct file *file, void *fh,
return 0;
}
int cx18_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf)
int cx18_do_s_frequency(struct cx18 *cx, const struct v4l2_frequency *vf)
{
struct cx18_open_id *id = file2id(file);
struct cx18 *cx = id->cx;
if (vf->tuner != 0)
return -EINVAL;
@@ -585,6 +585,12 @@ int cx18_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *v
return 0;
}
static int cx18_s_frequency(struct file *file, void *fh,
const struct v4l2_frequency *vf)
{
return cx18_do_s_frequency(file2id(file)->cx, vf);
}
static int cx18_g_std(struct file *file, void *fh, v4l2_std_id *std)
{
struct cx18 *cx = file2id(file)->cx;
@@ -593,11 +599,8 @@ static int cx18_g_std(struct file *file, void *fh, v4l2_std_id *std)
return 0;
}
int cx18_s_std(struct file *file, void *fh, v4l2_std_id std)
int cx18_do_s_std(struct cx18 *cx, v4l2_std_id std)
{
struct cx18_open_id *id = file2id(file);
struct cx18 *cx = id->cx;
if ((std & V4L2_STD_ALL) == 0)
return -EINVAL;
@@ -642,6 +645,11 @@ int cx18_s_std(struct file *file, void *fh, v4l2_std_id std)
return 0;
}
static int cx18_s_std(struct file *file, void *fh, v4l2_std_id std)
{
return cx18_do_s_std(file2id(file)->cx, std);
}
static int cx18_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt)
{
struct cx18_open_id *id = file2id(file);

View File

@@ -12,6 +12,8 @@ u16 cx18_service2vbi(int type);
void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal);
u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt);
void cx18_set_funcs(struct video_device *vdev);
int cx18_s_std(struct file *file, void *fh, v4l2_std_id std);
int cx18_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf);
int cx18_s_input(struct file *file, void *fh, unsigned int inp);
struct cx18;
int cx18_do_s_std(struct cx18 *cx, v4l2_std_id std);
int cx18_do_s_frequency(struct cx18 *cx, const struct v4l2_frequency *vf);
int cx18_do_s_input(struct cx18 *cx, unsigned int inp);

View File

@@ -1247,15 +1247,12 @@ err:
int ivtv_init_on_first_open(struct ivtv *itv)
{
struct v4l2_frequency vf;
/* Needed to call ioctls later */
struct ivtv_open_id fh;
struct ivtv_stream *s = &itv->streams[IVTV_ENC_STREAM_TYPE_MPG];
struct v4l2_frequency vf;
int fw_retry_count = 3;
int video_input;
fh.itv = itv;
fh.type = IVTV_ENC_STREAM_TYPE_MPG;
if (test_bit(IVTV_F_I_FAILED, &itv->i_flags))
return -ENXIO;
@@ -1297,13 +1294,13 @@ int ivtv_init_on_first_open(struct ivtv *itv)
video_input = itv->active_input;
itv->active_input++; /* Force update of input */
ivtv_s_input(NULL, &fh, video_input);
ivtv_do_s_input(itv, video_input);
/* Let the VIDIOC_S_STD ioctl do all the work, keeps the code
in one place. */
itv->std++; /* Force full standard initialization */
itv->std_out = itv->std;
ivtv_s_frequency(NULL, &fh, &vf);
ivtv_do_s_frequency(s, &vf);
if (itv->card->v4l2_capabilities & V4L2_CAP_VIDEO_OUTPUT) {
/* Turn on the TV-out: ivtv_init_mpeg_decoder() initializes

View File

@@ -974,9 +974,8 @@ static int ivtv_g_input(struct file *file, void *fh, unsigned int *i)
return 0;
}
int ivtv_s_input(struct file *file, void *fh, unsigned int inp)
int ivtv_do_s_input(struct ivtv *itv, unsigned int inp)
{
struct ivtv *itv = file2id(file)->itv;
v4l2_std_id std;
int i;
@@ -1017,6 +1016,11 @@ int ivtv_s_input(struct file *file, void *fh, unsigned int inp)
return 0;
}
static int ivtv_s_input(struct file *file, void *fh, unsigned int inp)
{
return ivtv_do_s_input(file2id(file)->itv, inp);
}
static int ivtv_g_output(struct file *file, void *fh, unsigned int *i)
{
struct ivtv *itv = file2id(file)->itv;
@@ -1065,10 +1069,9 @@ static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *
return 0;
}
int ivtv_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf)
int ivtv_do_s_frequency(struct ivtv_stream *s, const struct v4l2_frequency *vf)
{
struct ivtv *itv = file2id(file)->itv;
struct ivtv_stream *s = &itv->streams[file2id(file)->type];
struct ivtv *itv = s->itv;
if (s->vdev.vfl_dir)
return -ENOTTY;
@@ -1082,6 +1085,15 @@ int ivtv_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *v
return 0;
}
static int ivtv_s_frequency(struct file *file, void *fh,
const struct v4l2_frequency *vf)
{
struct ivtv_open_id *id = file2id(file);
struct ivtv *itv = id->itv;
return ivtv_do_s_frequency(&itv->streams[id->type], vf);
}
static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std)
{
struct ivtv *itv = file2id(file)->itv;

View File

@@ -9,6 +9,8 @@
#ifndef IVTV_IOCTL_H
#define IVTV_IOCTL_H
struct ivtv;
u16 ivtv_service2vbi(int type);
void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal);
u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt);
@@ -17,7 +19,7 @@ int ivtv_set_speed(struct ivtv *itv, int speed);
void ivtv_set_funcs(struct video_device *vdev);
void ivtv_s_std_enc(struct ivtv *itv, v4l2_std_id std);
void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id std);
int ivtv_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf);
int ivtv_s_input(struct file *file, void *fh, unsigned int inp);
int ivtv_do_s_frequency(struct ivtv_stream *s, const struct v4l2_frequency *vf);
int ivtv_do_s_input(struct ivtv *itv, unsigned int inp);
#endif

View File

@@ -167,13 +167,26 @@ static struct uvc_entity *uvc_entity_by_reference(struct uvc_device *dev,
static struct uvc_streaming *uvc_stream_by_id(struct uvc_device *dev, int id)
{
struct uvc_streaming *stream;
struct uvc_streaming *stream, *last_stream;
unsigned int count = 0;
list_for_each_entry(stream, &dev->streams, list) {
count += 1;
last_stream = stream;
if (stream->header.bTerminalLink == id)
return stream;
}
/*
* If the streaming entity is referenced by an invalid ID, notify the
* user and use heuristics to guess the correct entity.
*/
if (count == 1 && id == UVC_INVALID_ENTITY_ID) {
dev_warn(&dev->intf->dev,
"UVC non compliance: Invalid USB header. The streaming entity has an invalid ID, guessing the correct one.");
return last_stream;
}
return NULL;
}

View File

@@ -2608,7 +2608,7 @@ EXPORT_SYMBOL_GPL(v4l2_subdev_is_streaming);
int v4l2_subdev_get_privacy_led(struct v4l2_subdev *sd)
{
#if IS_REACHABLE(CONFIG_LEDS_CLASS)
sd->privacy_led = led_get(sd->dev, "privacy-led");
sd->privacy_led = led_get(sd->dev, "privacy");
if (IS_ERR(sd->privacy_led) && PTR_ERR(sd->privacy_led) != -ENOENT)
return dev_err_probe(sd->dev, PTR_ERR(sd->privacy_led),
"getting privacy LED\n");

View File

@@ -43,7 +43,7 @@ int skl_int3472_register_pled(struct int3472_discrete_device *int3472, struct gp
int3472->pled.lookup.provider = int3472->pled.name;
int3472->pled.lookup.dev_id = int3472->sensor_name;
int3472->pled.lookup.con_id = "privacy-led";
int3472->pled.lookup.con_id = "privacy";
led_add_lookup(&int3472->pled.lookup);
return 0;