[media] dsbr100: ensure correct disconnect sequence
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
Родитель
e64d07c92d
Коммит
1309929497
|
@ -129,7 +129,7 @@ devices, that would be 76 and 91. */
|
||||||
#define STARTED 0
|
#define STARTED 0
|
||||||
#define STOPPED 1
|
#define STOPPED 1
|
||||||
|
|
||||||
#define videodev_to_radio(d) container_of(d, struct dsbr100_device, videodev)
|
#define v4l2_dev_to_radio(d) container_of(d, struct dsbr100_device, v4l2_dev)
|
||||||
|
|
||||||
static int usb_dsbr100_probe(struct usb_interface *intf,
|
static int usb_dsbr100_probe(struct usb_interface *intf,
|
||||||
const struct usb_device_id *id);
|
const struct usb_device_id *id);
|
||||||
|
@ -151,7 +151,6 @@ struct dsbr100_device {
|
||||||
struct mutex v4l2_lock;
|
struct mutex v4l2_lock;
|
||||||
int curfreq;
|
int curfreq;
|
||||||
int stereo;
|
int stereo;
|
||||||
int removed;
|
|
||||||
int status;
|
int status;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -346,10 +345,6 @@ static int vidioc_g_tuner(struct file *file, void *priv,
|
||||||
{
|
{
|
||||||
struct dsbr100_device *radio = video_drvdata(file);
|
struct dsbr100_device *radio = video_drvdata(file);
|
||||||
|
|
||||||
/* safety check */
|
|
||||||
if (radio->removed)
|
|
||||||
return -EIO;
|
|
||||||
|
|
||||||
if (v->index > 0)
|
if (v->index > 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -371,16 +366,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
|
||||||
static int vidioc_s_tuner(struct file *file, void *priv,
|
static int vidioc_s_tuner(struct file *file, void *priv,
|
||||||
struct v4l2_tuner *v)
|
struct v4l2_tuner *v)
|
||||||
{
|
{
|
||||||
struct dsbr100_device *radio = video_drvdata(file);
|
return v->index ? -EINVAL : 0;
|
||||||
|
|
||||||
/* safety check */
|
|
||||||
if (radio->removed)
|
|
||||||
return -EIO;
|
|
||||||
|
|
||||||
if (v->index > 0)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vidioc_s_frequency(struct file *file, void *priv,
|
static int vidioc_s_frequency(struct file *file, void *priv,
|
||||||
|
@ -389,10 +375,6 @@ static int vidioc_s_frequency(struct file *file, void *priv,
|
||||||
struct dsbr100_device *radio = video_drvdata(file);
|
struct dsbr100_device *radio = video_drvdata(file);
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
/* safety check */
|
|
||||||
if (radio->removed)
|
|
||||||
return -EIO;
|
|
||||||
|
|
||||||
radio->curfreq = f->frequency;
|
radio->curfreq = f->frequency;
|
||||||
|
|
||||||
retval = dsbr100_setfreq(radio);
|
retval = dsbr100_setfreq(radio);
|
||||||
|
@ -406,10 +388,6 @@ static int vidioc_g_frequency(struct file *file, void *priv,
|
||||||
{
|
{
|
||||||
struct dsbr100_device *radio = video_drvdata(file);
|
struct dsbr100_device *radio = video_drvdata(file);
|
||||||
|
|
||||||
/* safety check */
|
|
||||||
if (radio->removed)
|
|
||||||
return -EIO;
|
|
||||||
|
|
||||||
f->type = V4L2_TUNER_RADIO;
|
f->type = V4L2_TUNER_RADIO;
|
||||||
f->frequency = radio->curfreq;
|
f->frequency = radio->curfreq;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -431,10 +409,6 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
|
||||||
{
|
{
|
||||||
struct dsbr100_device *radio = video_drvdata(file);
|
struct dsbr100_device *radio = video_drvdata(file);
|
||||||
|
|
||||||
/* safety check */
|
|
||||||
if (radio->removed)
|
|
||||||
return -EIO;
|
|
||||||
|
|
||||||
switch (ctrl->id) {
|
switch (ctrl->id) {
|
||||||
case V4L2_CID_AUDIO_MUTE:
|
case V4L2_CID_AUDIO_MUTE:
|
||||||
ctrl->value = radio->status;
|
ctrl->value = radio->status;
|
||||||
|
@ -449,10 +423,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
|
||||||
struct dsbr100_device *radio = video_drvdata(file);
|
struct dsbr100_device *radio = video_drvdata(file);
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
/* safety check */
|
|
||||||
if (radio->removed)
|
|
||||||
return -EIO;
|
|
||||||
|
|
||||||
switch (ctrl->id) {
|
switch (ctrl->id) {
|
||||||
case V4L2_CID_AUDIO_MUTE:
|
case V4L2_CID_AUDIO_MUTE:
|
||||||
if (ctrl->value) {
|
if (ctrl->value) {
|
||||||
|
@ -494,17 +464,13 @@ static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
|
||||||
|
|
||||||
static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
|
static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
|
||||||
{
|
{
|
||||||
if (i != 0)
|
return i ? -EINVAL : 0;
|
||||||
return -EINVAL;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vidioc_s_audio(struct file *file, void *priv,
|
static int vidioc_s_audio(struct file *file, void *priv,
|
||||||
struct v4l2_audio *a)
|
struct v4l2_audio *a)
|
||||||
{
|
{
|
||||||
if (a->index != 0)
|
return a->index ? -EINVAL : 0;
|
||||||
return -EINVAL;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* USB subsystem interface begins here */
|
/* USB subsystem interface begins here */
|
||||||
|
@ -519,14 +485,13 @@ static void usb_dsbr100_disconnect(struct usb_interface *intf)
|
||||||
{
|
{
|
||||||
struct dsbr100_device *radio = usb_get_intfdata(intf);
|
struct dsbr100_device *radio = usb_get_intfdata(intf);
|
||||||
|
|
||||||
usb_set_intfdata(intf, NULL);
|
v4l2_device_get(&radio->v4l2_dev);
|
||||||
|
|
||||||
mutex_lock(&radio->v4l2_lock);
|
mutex_lock(&radio->v4l2_lock);
|
||||||
radio->removed = 1;
|
usb_set_intfdata(intf, NULL);
|
||||||
mutex_unlock(&radio->v4l2_lock);
|
|
||||||
|
|
||||||
video_unregister_device(&radio->videodev);
|
video_unregister_device(&radio->videodev);
|
||||||
v4l2_device_disconnect(&radio->v4l2_dev);
|
v4l2_device_disconnect(&radio->v4l2_dev);
|
||||||
|
mutex_unlock(&radio->v4l2_lock);
|
||||||
|
v4l2_device_put(&radio->v4l2_dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -576,9 +541,9 @@ static int usb_dsbr100_resume(struct usb_interface *intf)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* free data structures */
|
/* free data structures */
|
||||||
static void usb_dsbr100_video_device_release(struct video_device *videodev)
|
static void usb_dsbr100_release(struct v4l2_device *v4l2_dev)
|
||||||
{
|
{
|
||||||
struct dsbr100_device *radio = videodev_to_radio(videodev);
|
struct dsbr100_device *radio = v4l2_dev_to_radio(v4l2_dev);
|
||||||
|
|
||||||
v4l2_device_unregister(&radio->v4l2_dev);
|
v4l2_device_unregister(&radio->v4l2_dev);
|
||||||
kfree(radio->transfer_buffer);
|
kfree(radio->transfer_buffer);
|
||||||
|
@ -627,6 +592,7 @@ static int usb_dsbr100_probe(struct usb_interface *intf,
|
||||||
}
|
}
|
||||||
|
|
||||||
v4l2_dev = &radio->v4l2_dev;
|
v4l2_dev = &radio->v4l2_dev;
|
||||||
|
v4l2_dev->release = usb_dsbr100_release;
|
||||||
|
|
||||||
retval = v4l2_device_register(&intf->dev, v4l2_dev);
|
retval = v4l2_device_register(&intf->dev, v4l2_dev);
|
||||||
if (retval < 0) {
|
if (retval < 0) {
|
||||||
|
@ -641,10 +607,9 @@ static int usb_dsbr100_probe(struct usb_interface *intf,
|
||||||
radio->videodev.v4l2_dev = v4l2_dev;
|
radio->videodev.v4l2_dev = v4l2_dev;
|
||||||
radio->videodev.fops = &usb_dsbr100_fops;
|
radio->videodev.fops = &usb_dsbr100_fops;
|
||||||
radio->videodev.ioctl_ops = &usb_dsbr100_ioctl_ops;
|
radio->videodev.ioctl_ops = &usb_dsbr100_ioctl_ops;
|
||||||
radio->videodev.release = usb_dsbr100_video_device_release;
|
radio->videodev.release = video_device_release_empty;
|
||||||
radio->videodev.lock = &radio->v4l2_lock;
|
radio->videodev.lock = &radio->v4l2_lock;
|
||||||
|
|
||||||
radio->removed = 0;
|
|
||||||
radio->usbdev = interface_to_usbdev(intf);
|
radio->usbdev = interface_to_usbdev(intf);
|
||||||
radio->curfreq = FREQ_MIN * FREQ_MUL;
|
radio->curfreq = FREQ_MIN * FREQ_MUL;
|
||||||
radio->status = STOPPED;
|
radio->status = STOPPED;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче