From 04e0ffbbdd297fac1d8a5696b5d27887d6ff3dc2 Mon Sep 17 00:00:00 2001 From: Alexey Klimov Date: Sat, 8 Nov 2008 00:40:46 -0300 Subject: V4L/DVB (9539): dsbr100: add suspend and resume This patch adds support for suspend and resume methods in driver. Without this kradio and gnomeradio crashes during resume. Also .supports_autosuspend in usb_driver struct set equal to 0 to avoid suspending of module if usb_autosuspend enabled. Signed-off-by: Alexey Klimov Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/dsbr100.c | 45 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) (limited to 'drivers/media/radio/dsbr100.c') diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c index a5ca176a7b08..e6485cfe1218 100644 --- a/drivers/media/radio/dsbr100.c +++ b/drivers/media/radio/dsbr100.c @@ -131,6 +131,9 @@ static int usb_dsbr100_probe(struct usb_interface *intf, static void usb_dsbr100_disconnect(struct usb_interface *intf); static int usb_dsbr100_open(struct inode *inode, struct file *file); static int usb_dsbr100_close(struct inode *inode, struct file *file); +static int usb_dsbr100_suspend(struct usb_interface *intf, + pm_message_t message); +static int usb_dsbr100_resume(struct usb_interface *intf); static int radio_nr = -1; module_param(radio_nr, int, 0); @@ -157,10 +160,14 @@ MODULE_DEVICE_TABLE (usb, usb_dsbr100_device_table); /* USB subsystem interface */ static struct usb_driver usb_dsbr100_driver = { - .name = "dsbr100", - .probe = usb_dsbr100_probe, - .disconnect = usb_dsbr100_disconnect, - .id_table = usb_dsbr100_device_table, + .name = "dsbr100", + .probe = usb_dsbr100_probe, + .disconnect = usb_dsbr100_disconnect, + .id_table = usb_dsbr100_device_table, + .suspend = usb_dsbr100_suspend, + .resume = usb_dsbr100_resume, + .reset_resume = usb_dsbr100_resume, + .supports_autosuspend = 0, }; /* Low-level device interface begins here */ @@ -448,6 +455,36 @@ static int usb_dsbr100_close(struct inode *inode, struct file *file) return 0; } +/* Suspend device - stop device. */ +static int usb_dsbr100_suspend(struct usb_interface *intf, pm_message_t message) +{ + struct dsbr100_device *radio = usb_get_intfdata(intf); + int retval; + + retval = dsbr100_stop(radio); + if (retval == -1) + dev_warn(&intf->dev, "dsbr100_stop failed\n"); + + dev_info(&intf->dev, "going into suspend..\n"); + + return 0; +} + +/* Resume device - start device. */ +static int usb_dsbr100_resume(struct usb_interface *intf) +{ + struct dsbr100_device *radio = usb_get_intfdata(intf); + int retval; + + retval = dsbr100_start(radio); + if (retval == -1) + dev_warn(&intf->dev, "dsbr100_start failed\n"); + + dev_info(&intf->dev, "coming out of suspend..\n"); + + return 0; +} + /* File system interface */ static const struct file_operations usb_dsbr100_fops = { .owner = THIS_MODULE, -- cgit v1.2.3 From 54b7b0deb4c602d0751627d14510dc50b5bba372 Mon Sep 17 00:00:00 2001 From: Alexey Klimov Date: Sat, 8 Nov 2008 00:31:50 -0300 Subject: V4L/DVB (9540): dsbr100: add disabled controls and fix version Patch adds disabled controls in v4l2_queryctrl struct. Also version of driver corrected. -- Signed-off-by: Alexey Klimov Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/dsbr100.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'drivers/media/radio/dsbr100.c') diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c index e6485cfe1218..eafa547ca96b 100644 --- a/drivers/media/radio/dsbr100.c +++ b/drivers/media/radio/dsbr100.c @@ -93,8 +93,8 @@ */ #include /* for KERNEL_VERSION MACRO */ -#define DRIVER_VERSION "v0.41" -#define RADIO_VERSION KERNEL_VERSION(0,4,1) +#define DRIVER_VERSION "v0.43" +#define RADIO_VERSION KERNEL_VERSION(0, 4, 3) static struct v4l2_queryctrl radio_qctrl[] = { { @@ -104,7 +104,27 @@ static struct v4l2_queryctrl radio_qctrl[] = { .maximum = 1, .default_value = 1, .type = V4L2_CTRL_TYPE_BOOLEAN, - } + }, +/* HINT: the disabled controls are only here to satify kradio and such apps */ + { .id = V4L2_CID_AUDIO_VOLUME, + .flags = V4L2_CTRL_FLAG_DISABLED, + }, + { + .id = V4L2_CID_AUDIO_BALANCE, + .flags = V4L2_CTRL_FLAG_DISABLED, + }, + { + .id = V4L2_CID_AUDIO_BASS, + .flags = V4L2_CTRL_FLAG_DISABLED, + }, + { + .id = V4L2_CID_AUDIO_TREBLE, + .flags = V4L2_CTRL_FLAG_DISABLED, + }, + { + .id = V4L2_CID_AUDIO_LOUDNESS, + .flags = V4L2_CTRL_FLAG_DISABLED, + }, }; #define DRIVER_AUTHOR "Markus Demleitner " -- cgit v1.2.3 From 3a0efc3200386b9288e1d3d3be0a9f5d6f286906 Mon Sep 17 00:00:00 2001 From: Alexey Klimov Date: Sat, 27 Dec 2008 21:32:49 -0300 Subject: V4L/DVB (10054): dsbr100: fix unplug oops This patch corrects unplug procedure. Patch adds usb_dsbr100_video_device_release, new macros - videodev_to_radio, mutex lock and a lot of safety checks. Struct video_device videodev is embedded in dsbr100_device structure. Signed-off-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/dsbr100.c | 106 ++++++++++++++++++++++++++++++------------ 1 file changed, 77 insertions(+), 29 deletions(-) (limited to 'drivers/media/radio/dsbr100.c') diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c index eafa547ca96b..84914fb267be 100644 --- a/drivers/media/radio/dsbr100.c +++ b/drivers/media/radio/dsbr100.c @@ -145,6 +145,7 @@ devices, that would be 76 and 91. */ #define FREQ_MAX 108.0 #define FREQ_MUL 16000 +#define videodev_to_radio(d) container_of(d, struct dsbr100_device, videodev) static int usb_dsbr100_probe(struct usb_interface *intf, const struct usb_device_id *id); @@ -161,8 +162,9 @@ module_param(radio_nr, int, 0); /* Data for one (physical) device */ struct dsbr100_device { struct usb_device *usbdev; - struct video_device *videodev; + struct video_device videodev; u8 *transfer_buffer; + struct mutex lock; /* buffer locking */ int curfreq; int stereo; int users; @@ -195,6 +197,7 @@ static struct usb_driver usb_dsbr100_driver = { /* switch on radio */ static int dsbr100_start(struct dsbr100_device *radio) { + mutex_lock(&radio->lock); if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), USB_REQ_GET_STATUS, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, @@ -202,9 +205,13 @@ static int dsbr100_start(struct dsbr100_device *radio) usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), DSB100_ONOFF, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, - 0x01, 0x00, radio->transfer_buffer, 8, 300) < 0) + 0x01, 0x00, radio->transfer_buffer, 8, 300) < 0) { + mutex_unlock(&radio->lock); return -1; + } + radio->muted=0; + mutex_unlock(&radio->lock); return (radio->transfer_buffer)[0]; } @@ -212,6 +219,7 @@ static int dsbr100_start(struct dsbr100_device *radio) /* switch off radio */ static int dsbr100_stop(struct dsbr100_device *radio) { + mutex_lock(&radio->lock); if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), USB_REQ_GET_STATUS, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, @@ -219,9 +227,13 @@ static int dsbr100_stop(struct dsbr100_device *radio) usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), DSB100_ONOFF, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, - 0x00, 0x00, radio->transfer_buffer, 8, 300) < 0) + 0x00, 0x00, radio->transfer_buffer, 8, 300) < 0) { + mutex_unlock(&radio->lock); return -1; + } + radio->muted=1; + mutex_unlock(&radio->lock); return (radio->transfer_buffer)[0]; } @@ -229,6 +241,7 @@ static int dsbr100_stop(struct dsbr100_device *radio) static int dsbr100_setfreq(struct dsbr100_device *radio, int freq) { freq = (freq / 16 * 80) / 1000 + 856; + mutex_lock(&radio->lock); if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), DSB100_TUNE, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, @@ -243,9 +256,12 @@ static int dsbr100_setfreq(struct dsbr100_device *radio, int freq) USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 0x00, 0x24, radio->transfer_buffer, 8, 300) < 0) { radio->stereo = -1; + mutex_unlock(&radio->lock); return -1; } + radio->stereo = !((radio->transfer_buffer)[0] & 0x01); + mutex_unlock(&radio->lock); return (radio->transfer_buffer)[0]; } @@ -253,6 +269,7 @@ static int dsbr100_setfreq(struct dsbr100_device *radio, int freq) sees a stereo signal or not. Pity. */ static void dsbr100_getstat(struct dsbr100_device *radio) { + mutex_lock(&radio->lock); if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), USB_REQ_GET_STATUS, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, @@ -260,6 +277,7 @@ static void dsbr100_getstat(struct dsbr100_device *radio) radio->stereo = -1; else radio->stereo = !(radio->transfer_buffer[0] & 0x01); + mutex_unlock(&radio->lock); } @@ -274,16 +292,12 @@ static void usb_dsbr100_disconnect(struct usb_interface *intf) struct dsbr100_device *radio = usb_get_intfdata(intf); usb_set_intfdata (intf, NULL); - if (radio) { - video_unregister_device(radio->videodev); - radio->videodev = NULL; - if (radio->users) { - kfree(radio->transfer_buffer); - kfree(radio); - } else { - radio->removed = 1; - } - } + + mutex_lock(&radio->lock); + radio->removed = 1; + mutex_unlock(&radio->lock); + + video_unregister_device(&radio->videodev); } @@ -303,6 +317,10 @@ static int vidioc_g_tuner(struct file *file, void *priv, { struct dsbr100_device *radio = video_drvdata(file); + /* safety check */ + if (radio->removed) + return -EIO; + if (v->index > 0) return -EINVAL; @@ -324,6 +342,12 @@ static int vidioc_g_tuner(struct file *file, void *priv, static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { + struct dsbr100_device *radio = video_drvdata(file); + + /* safety check */ + if (radio->removed) + return -EIO; + if (v->index > 0) return -EINVAL; @@ -335,6 +359,10 @@ static int vidioc_s_frequency(struct file *file, void *priv, { struct dsbr100_device *radio = video_drvdata(file); + /* safety check */ + if (radio->removed) + return -EIO; + radio->curfreq = f->frequency; if (dsbr100_setfreq(radio, radio->curfreq) == -1) dev_warn(&radio->usbdev->dev, "Set frequency failed\n"); @@ -346,6 +374,10 @@ static int vidioc_g_frequency(struct file *file, void *priv, { struct dsbr100_device *radio = video_drvdata(file); + /* safety check */ + if (radio->removed) + return -EIO; + f->type = V4L2_TUNER_RADIO; f->frequency = radio->curfreq; return 0; @@ -370,6 +402,10 @@ static int vidioc_g_ctrl(struct file *file, void *priv, { struct dsbr100_device *radio = video_drvdata(file); + /* safety check */ + if (radio->removed) + return -EIO; + switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: ctrl->value = radio->muted; @@ -383,6 +419,10 @@ static int vidioc_s_ctrl(struct file *file, void *priv, { struct dsbr100_device *radio = video_drvdata(file); + /* safety check */ + if (radio->removed) + return -EIO; + switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: if (ctrl->value) { @@ -464,13 +504,19 @@ static int usb_dsbr100_open(struct inode *inode, struct file *file) static int usb_dsbr100_close(struct inode *inode, struct file *file) { struct dsbr100_device *radio = video_drvdata(file); + int retval; if (!radio) return -ENODEV; + radio->users = 0; - if (radio->removed) { - kfree(radio->transfer_buffer); - kfree(radio); + if (!radio->removed) { + retval = dsbr100_stop(radio); + if (retval == -1) { + dev_warn(&radio->usbdev->dev, + "dsbr100_stop failed\n"); + } + } return 0; } @@ -505,6 +551,14 @@ static int usb_dsbr100_resume(struct usb_interface *intf) return 0; } +static void usb_dsbr100_video_device_release(struct video_device *videodev) +{ + struct dsbr100_device *radio = videodev_to_radio(videodev); + + kfree(radio->transfer_buffer); + kfree(radio); +} + /* File system interface */ static const struct file_operations usb_dsbr100_fops = { .owner = THIS_MODULE, @@ -533,11 +587,11 @@ static const struct v4l2_ioctl_ops usb_dsbr100_ioctl_ops = { }; /* V4L2 interface */ -static struct video_device dsbr100_videodev_template = { +static struct video_device dsbr100_videodev_data = { .name = "D-Link DSB-R 100", .fops = &usb_dsbr100_fops, .ioctl_ops = &usb_dsbr100_ioctl_ops, - .release = video_device_release, + .release = usb_dsbr100_video_device_release, }; /* check if the device is present and register with v4l and @@ -558,23 +612,17 @@ static int usb_dsbr100_probe(struct usb_interface *intf, kfree(radio); return -ENOMEM; } - radio->videodev = video_device_alloc(); - if (!(radio->videodev)) { - kfree(radio->transfer_buffer); - kfree(radio); - return -ENOMEM; - } - memcpy(radio->videodev, &dsbr100_videodev_template, - sizeof(dsbr100_videodev_template)); + mutex_init(&radio->lock); + radio->videodev = dsbr100_videodev_data; + radio->removed = 0; radio->users = 0; radio->usbdev = interface_to_usbdev(intf); radio->curfreq = FREQ_MIN * FREQ_MUL; - video_set_drvdata(radio->videodev, radio); - if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr) < 0) { + video_set_drvdata(&radio->videodev, radio); + if (video_register_device(&radio->videodev, VFL_TYPE_RADIO, radio_nr) < 0) { dev_warn(&intf->dev, "Could not register video device\n"); - video_device_release(radio->videodev); kfree(radio->transfer_buffer); kfree(radio); return -EIO; -- cgit v1.2.3 From 290588e067b6710b614da4bd538197dd88158b62 Mon Sep 17 00:00:00 2001 From: Alexey Klimov Date: Sat, 27 Dec 2008 21:42:39 -0300 Subject: V4L/DVB (10057): dsbr100: place dev_warn instead of printk Remove printk in one line and place dev_warn there. Signed-off-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/dsbr100.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/media/radio/dsbr100.c') diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c index 84914fb267be..e1cc369bdbd6 100644 --- a/drivers/media/radio/dsbr100.c +++ b/drivers/media/radio/dsbr100.c @@ -495,7 +495,8 @@ static int usb_dsbr100_open(struct inode *inode, struct file *file) retval = dsbr100_setfreq(radio, radio->curfreq); if (retval == -1) - printk(KERN_WARNING KBUILD_MODNAME ": Set frequency failed\n"); + dev_warn(&radio->usbdev->dev, + "set frequency failed\n"); unlock_kernel(); return 0; -- cgit v1.2.3 From 417b7953668574ff38d3f2dc76e9fe669f121469 Mon Sep 17 00:00:00 2001 From: Alexey Klimov Date: Sat, 27 Dec 2008 22:30:29 -0300 Subject: V4L/DVB (10058): dsbr100: fix codingstyle, add dev_err messages We should make if-constructions more clear. Introduce int retval variables in some functions to make it this way. Also a lot of useful dev_err messages added. And now we check every returned value after usb_control_msg. Signed-off-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/dsbr100.c | 184 +++++++++++++++++++++++++++++++----------- 1 file changed, 137 insertions(+), 47 deletions(-) (limited to 'drivers/media/radio/dsbr100.c') diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c index e1cc369bdbd6..e0d7485226cd 100644 --- a/drivers/media/radio/dsbr100.c +++ b/drivers/media/radio/dsbr100.c @@ -197,86 +197,169 @@ static struct usb_driver usb_dsbr100_driver = { /* switch on radio */ static int dsbr100_start(struct dsbr100_device *radio) { + int retval; + int request; + mutex_lock(&radio->lock); - if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), - USB_REQ_GET_STATUS, - USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, - 0x00, 0xC7, radio->transfer_buffer, 8, 300) < 0 || - usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), - DSB100_ONOFF, - USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, - 0x01, 0x00, radio->transfer_buffer, 8, 300) < 0) { - mutex_unlock(&radio->lock); - return -1; + + retval = usb_control_msg(radio->usbdev, + usb_rcvctrlpipe(radio->usbdev, 0), + USB_REQ_GET_STATUS, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, + 0x00, 0xC7, radio->transfer_buffer, 8, 300); + + if (retval < 0) { + request = USB_REQ_GET_STATUS; + goto usb_control_msg_failed; } - radio->muted=0; + retval = usb_control_msg(radio->usbdev, + usb_rcvctrlpipe(radio->usbdev, 0), + DSB100_ONOFF, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, + 0x01, 0x00, radio->transfer_buffer, 8, 300); + + if (retval < 0) { + request = DSB100_ONOFF; + goto usb_control_msg_failed; + } + + radio->muted = 0; mutex_unlock(&radio->lock); return (radio->transfer_buffer)[0]; + +usb_control_msg_failed: + mutex_unlock(&radio->lock); + dev_err(&radio->usbdev->dev, + "%s - usb_control_msg returned %i, request %i\n", + __func__, retval, request); + return -1; + } /* switch off radio */ static int dsbr100_stop(struct dsbr100_device *radio) { + int retval; + int request; + mutex_lock(&radio->lock); - if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), - USB_REQ_GET_STATUS, - USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, - 0x16, 0x1C, radio->transfer_buffer, 8, 300) < 0 || - usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), - DSB100_ONOFF, - USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, - 0x00, 0x00, radio->transfer_buffer, 8, 300) < 0) { - mutex_unlock(&radio->lock); - return -1; + + retval = usb_control_msg(radio->usbdev, + usb_rcvctrlpipe(radio->usbdev, 0), + USB_REQ_GET_STATUS, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, + 0x16, 0x1C, radio->transfer_buffer, 8, 300); + + if (retval < 0) { + request = USB_REQ_GET_STATUS; + goto usb_control_msg_failed; + } + + retval = usb_control_msg(radio->usbdev, + usb_rcvctrlpipe(radio->usbdev, 0), + DSB100_ONOFF, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, + 0x00, 0x00, radio->transfer_buffer, 8, 300); + + if (retval < 0) { + request = DSB100_ONOFF; + goto usb_control_msg_failed; } - radio->muted=1; + radio->muted = 1; mutex_unlock(&radio->lock); return (radio->transfer_buffer)[0]; + +usb_control_msg_failed: + mutex_unlock(&radio->lock); + dev_err(&radio->usbdev->dev, + "%s - usb_control_msg returned %i, request %i\n", + __func__, retval, request); + return -1; + } /* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */ static int dsbr100_setfreq(struct dsbr100_device *radio, int freq) { + int retval; + int request; + freq = (freq / 16 * 80) / 1000 + 856; mutex_lock(&radio->lock); - if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), - DSB100_TUNE, - USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, - (freq >> 8) & 0x00ff, freq & 0xff, - radio->transfer_buffer, 8, 300) < 0 || - usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), - USB_REQ_GET_STATUS, - USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, - 0x96, 0xB7, radio->transfer_buffer, 8, 300) < 0 || - usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), - USB_REQ_GET_STATUS, - USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, - 0x00, 0x24, radio->transfer_buffer, 8, 300) < 0) { - radio->stereo = -1; - mutex_unlock(&radio->lock); - return -1; + + retval = usb_control_msg(radio->usbdev, + usb_rcvctrlpipe(radio->usbdev, 0), + DSB100_TUNE, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, + (freq >> 8) & 0x00ff, freq & 0xff, + radio->transfer_buffer, 8, 300); + + if (retval < 0) { + request = DSB100_TUNE; + goto usb_control_msg_failed; + } + + retval = usb_control_msg(radio->usbdev, + usb_rcvctrlpipe(radio->usbdev, 0), + USB_REQ_GET_STATUS, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, + 0x96, 0xB7, radio->transfer_buffer, 8, 300); + + if (retval < 0) { + request = USB_REQ_GET_STATUS; + goto usb_control_msg_failed; + } + + retval = usb_control_msg(radio->usbdev, + usb_rcvctrlpipe(radio->usbdev, 0), + USB_REQ_GET_STATUS, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, + 0x00, 0x24, radio->transfer_buffer, 8, 300); + + if (retval < 0) { + request = USB_REQ_GET_STATUS; + goto usb_control_msg_failed; } radio->stereo = !((radio->transfer_buffer)[0] & 0x01); mutex_unlock(&radio->lock); return (radio->transfer_buffer)[0]; + +usb_control_msg_failed: + radio->stereo = -1; + mutex_unlock(&radio->lock); + dev_err(&radio->usbdev->dev, + "%s - usb_control_msg returned %i, request %i\n", + __func__, retval, request); + return -1; } /* return the device status. This is, in effect, just whether it sees a stereo signal or not. Pity. */ static void dsbr100_getstat(struct dsbr100_device *radio) { + int retval; + mutex_lock(&radio->lock); - if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), + + retval = usb_control_msg(radio->usbdev, + usb_rcvctrlpipe(radio->usbdev, 0), USB_REQ_GET_STATUS, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, - 0x00 , 0x24, radio->transfer_buffer, 8, 300) < 0) + 0x00 , 0x24, radio->transfer_buffer, 8, 300); + + if (retval < 0) { radio->stereo = -1; - else + dev_err(&radio->usbdev->dev, + "%s - usb_control_msg returned %i, request %i\n", + __func__, retval, USB_REQ_GET_STATUS); + } else { radio->stereo = !(radio->transfer_buffer[0] & 0x01); + } + mutex_unlock(&radio->lock); } @@ -358,13 +441,15 @@ static int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { struct dsbr100_device *radio = video_drvdata(file); + int retval; /* safety check */ if (radio->removed) return -EIO; radio->curfreq = f->frequency; - if (dsbr100_setfreq(radio, radio->curfreq) == -1) + retval = dsbr100_setfreq(radio, radio->curfreq); + if (retval == -1) dev_warn(&radio->usbdev->dev, "Set frequency failed\n"); return 0; } @@ -418,6 +503,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { struct dsbr100_device *radio = video_drvdata(file); + int retval; /* safety check */ if (radio->removed) @@ -426,13 +512,15 @@ static int vidioc_s_ctrl(struct file *file, void *priv, switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: if (ctrl->value) { - if (dsbr100_stop(radio) == -1) { + retval = dsbr100_stop(radio); + if (retval == -1) { dev_warn(&radio->usbdev->dev, "Radio did not respond properly\n"); return -EBUSY; } } else { - if (dsbr100_start(radio) == -1) { + retval = dsbr100_start(radio); + if (retval == -1) { dev_warn(&radio->usbdev->dev, "Radio did not respond properly\n"); return -EBUSY; @@ -484,7 +572,8 @@ static int usb_dsbr100_open(struct inode *inode, struct file *file) radio->users = 1; radio->muted = 1; - if (dsbr100_start(radio) < 0) { + retval = dsbr100_start(radio); + if (retval < 0) { dev_warn(&radio->usbdev->dev, "Radio did not start up properly\n"); radio->users = 0; @@ -493,7 +582,6 @@ static int usb_dsbr100_open(struct inode *inode, struct file *file) } retval = dsbr100_setfreq(radio, radio->curfreq); - if (retval == -1) dev_warn(&radio->usbdev->dev, "set frequency failed\n"); @@ -601,6 +689,7 @@ static int usb_dsbr100_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct dsbr100_device *radio; + int retval; radio = kmalloc(sizeof(struct dsbr100_device), GFP_KERNEL); @@ -622,7 +711,8 @@ static int usb_dsbr100_probe(struct usb_interface *intf, radio->usbdev = interface_to_usbdev(intf); radio->curfreq = FREQ_MIN * FREQ_MUL; video_set_drvdata(&radio->videodev, radio); - if (video_register_device(&radio->videodev, VFL_TYPE_RADIO, radio_nr) < 0) { + retval = video_register_device(&radio->videodev, VFL_TYPE_RADIO, radio_nr); + if (retval < 0) { dev_warn(&intf->dev, "Could not register video device\n"); kfree(radio->transfer_buffer); kfree(radio); -- cgit v1.2.3 From 7e1ca8491d046d1f01de105add7f2f8f477869ec Mon Sep 17 00:00:00 2001 From: Alexey Klimov Date: Sat, 27 Dec 2008 22:31:52 -0300 Subject: V4L/DVB (10059): dsbr100: dev_err instead of dev_warn We should use dev_err (not dev_warn) if video_register_device fails. Signed-off-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/dsbr100.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/radio/dsbr100.c') diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c index e0d7485226cd..5de5def9c166 100644 --- a/drivers/media/radio/dsbr100.c +++ b/drivers/media/radio/dsbr100.c @@ -713,7 +713,7 @@ static int usb_dsbr100_probe(struct usb_interface *intf, video_set_drvdata(&radio->videodev, radio); retval = video_register_device(&radio->videodev, VFL_TYPE_RADIO, radio_nr); if (retval < 0) { - dev_warn(&intf->dev, "Could not register video device\n"); + dev_err(&intf->dev, "couldn't register video device\n"); kfree(radio->transfer_buffer); kfree(radio); return -EIO; -- cgit v1.2.3 From fc55bcb0a04a66465ab13c33f36a290f6e3a3f7d Mon Sep 17 00:00:00 2001 From: Alexey Klimov Date: Sat, 27 Dec 2008 22:33:54 -0300 Subject: V4L/DVB (10060): dsbr100: fix and add right comments Fix and add right comments. Few empty lines removed. Signed-off-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/dsbr100.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'drivers/media/radio/dsbr100.c') diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c index 5de5def9c166..448e5a42b468 100644 --- a/drivers/media/radio/dsbr100.c +++ b/drivers/media/radio/dsbr100.c @@ -1,5 +1,5 @@ -/* A driver for the D-Link DSB-R100 USB radio. The R100 plugs - into both the USB and an analog audio input, so this thing +/* A driver for the D-Link DSB-R100 USB radio and Gemtek USB Radio 21. + The device plugs into both the USB and an analog audio input, so this thing only deals with initialisation and frequency setting, the audio data has to be handled by a sound driver. @@ -172,7 +172,6 @@ struct dsbr100_device { int muted; }; - static struct usb_device_id usb_dsbr100_device_table [] = { { USB_DEVICE(DSB100_VENDOR, DSB100_PRODUCT) }, { } /* Terminating entry */ @@ -237,7 +236,6 @@ usb_control_msg_failed: } - /* switch off radio */ static int dsbr100_stop(struct dsbr100_device *radio) { @@ -363,13 +361,14 @@ static void dsbr100_getstat(struct dsbr100_device *radio) mutex_unlock(&radio->lock); } - /* USB subsystem interface begins here */ -/* handle unplugging of the device, release data structures -if nothing keeps us from doing it. If something is still -keeping us busy, the release callback of v4l will take care -of releasing it. */ +/* + * Handle unplugging of the device. + * We call video_unregister_device in any case. + * The last function called in this procedure is + * usb_dsbr100_video_device_release + */ static void usb_dsbr100_disconnect(struct usb_interface *intf) { struct dsbr100_device *radio = usb_get_intfdata(intf); @@ -640,6 +639,7 @@ static int usb_dsbr100_resume(struct usb_interface *intf) return 0; } +/* free data structures */ static void usb_dsbr100_video_device_release(struct video_device *videodev) { struct dsbr100_device *radio = videodev_to_radio(videodev); @@ -683,8 +683,7 @@ static struct video_device dsbr100_videodev_data = { .release = usb_dsbr100_video_device_release, }; -/* check if the device is present and register with v4l and -usb if it is */ +/* check if the device is present and register with v4l and usb if it is */ static int usb_dsbr100_probe(struct usb_interface *intf, const struct usb_device_id *id) { -- cgit v1.2.3 From 6076dbf46a776a666166f8cdad97802334a0083c Mon Sep 17 00:00:00 2001 From: Alexey Klimov Date: Sat, 27 Dec 2008 22:35:21 -0300 Subject: V4L/DVB (10061): dsbr100: increase driver version Due to a lot of patches for dsbr100 last time we should update version of driver. Signed-off-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/dsbr100.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/media/radio/dsbr100.c') diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c index 448e5a42b468..5e0d651ffdd2 100644 --- a/drivers/media/radio/dsbr100.c +++ b/drivers/media/radio/dsbr100.c @@ -33,6 +33,10 @@ History: + Version 0.44: + Add suspend/resume functions, fix unplug of device, + a lot of cleanups and fixes by Alexey Klimov + Version 0.43: Oliver Neukum: avoided DMA coherency issue @@ -93,8 +97,8 @@ */ #include /* for KERNEL_VERSION MACRO */ -#define DRIVER_VERSION "v0.43" -#define RADIO_VERSION KERNEL_VERSION(0, 4, 3) +#define DRIVER_VERSION "v0.44" +#define RADIO_VERSION KERNEL_VERSION(0, 4, 4) static struct v4l2_queryctrl radio_qctrl[] = { { -- cgit v1.2.3 From d25cb6461ac93683ac04b2e181bcaa0cc15c349b Mon Sep 17 00:00:00 2001 From: Alexey Klimov Date: Sat, 27 Dec 2008 22:40:57 -0300 Subject: V4L/DVB (10062): dsbr100: change return values in 3 functions Patch replace return -1; with return retval; in 3 functions. And we also change if-checks for this returned values. Signed-off-by: Alexey Klimov Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/dsbr100.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers/media/radio/dsbr100.c') diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c index 5e0d651ffdd2..5474a22c1b22 100644 --- a/drivers/media/radio/dsbr100.c +++ b/drivers/media/radio/dsbr100.c @@ -236,7 +236,7 @@ usb_control_msg_failed: dev_err(&radio->usbdev->dev, "%s - usb_control_msg returned %i, request %i\n", __func__, retval, request); - return -1; + return retval; } @@ -279,7 +279,7 @@ usb_control_msg_failed: dev_err(&radio->usbdev->dev, "%s - usb_control_msg returned %i, request %i\n", __func__, retval, request); - return -1; + return retval; } @@ -336,7 +336,7 @@ usb_control_msg_failed: dev_err(&radio->usbdev->dev, "%s - usb_control_msg returned %i, request %i\n", __func__, retval, request); - return -1; + return retval; } /* return the device status. This is, in effect, just whether it @@ -452,7 +452,7 @@ static int vidioc_s_frequency(struct file *file, void *priv, radio->curfreq = f->frequency; retval = dsbr100_setfreq(radio, radio->curfreq); - if (retval == -1) + if (retval < 0) dev_warn(&radio->usbdev->dev, "Set frequency failed\n"); return 0; } @@ -516,14 +516,14 @@ static int vidioc_s_ctrl(struct file *file, void *priv, case V4L2_CID_AUDIO_MUTE: if (ctrl->value) { retval = dsbr100_stop(radio); - if (retval == -1) { + if (retval < 0) { dev_warn(&radio->usbdev->dev, "Radio did not respond properly\n"); return -EBUSY; } } else { retval = dsbr100_start(radio); - if (retval == -1) { + if (retval < 0) { dev_warn(&radio->usbdev->dev, "Radio did not respond properly\n"); return -EBUSY; @@ -585,7 +585,7 @@ static int usb_dsbr100_open(struct inode *inode, struct file *file) } retval = dsbr100_setfreq(radio, radio->curfreq); - if (retval == -1) + if (retval < 0) dev_warn(&radio->usbdev->dev, "set frequency failed\n"); @@ -604,7 +604,7 @@ static int usb_dsbr100_close(struct inode *inode, struct file *file) radio->users = 0; if (!radio->removed) { retval = dsbr100_stop(radio); - if (retval == -1) { + if (retval < 0) { dev_warn(&radio->usbdev->dev, "dsbr100_stop failed\n"); } @@ -620,7 +620,7 @@ static int usb_dsbr100_suspend(struct usb_interface *intf, pm_message_t message) int retval; retval = dsbr100_stop(radio); - if (retval == -1) + if (retval < 0) dev_warn(&intf->dev, "dsbr100_stop failed\n"); dev_info(&intf->dev, "going into suspend..\n"); @@ -635,7 +635,7 @@ static int usb_dsbr100_resume(struct usb_interface *intf) int retval; retval = dsbr100_start(radio); - if (retval == -1) + if (retval < 0) dev_warn(&intf->dev, "dsbr100_start failed\n"); dev_info(&intf->dev, "coming out of suspend..\n"); -- cgit v1.2.3