summaryrefslogtreecommitdiff
path: root/drivers/media/usb
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-08-19 10:09:22 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-08-19 10:09:22 -0700
commitf4cdf7ca9a1fdcca413157df19753f388a5a224e (patch)
tree60a31895b2446cd7fa27514e8c2843534a0de0da /drivers/media/usb
parente5c91aac491def6ab3f90c4cc246e3fcb0f8f058 (diff)
parent4900cad020c0580dfb1be27776ff10a4ef110cfa (diff)
downloadlinux-next-f4cdf7ca9a1fdcca413157df19753f388a5a224e.tar.gz
linux-next-f4cdf7ca9a1fdcca413157df19753f388a5a224e.zip
Merge tag 'media/v7.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab: - v4l2-core: added ISP statistics support and per-block validation - v4l2-core: Allow unknown HDR10 white point and luminance - New camera sensors: Sony IMX678 and IMX471m, Himax HM1092 IR sensor - New codec: Milos: VPU v2.0 codec support - isp driver: gained support for Dreamchip RPPX1 ISP framework - vsp1 driver: gained support for RZ/T2H and RZ/N2H - Novalake driver: gained CVS support for new NVL hardware - dvb-core: fix feed leak on failed DMX_ADD_PID - several driver fixes, cleanups and minor improvements * tag 'media/v7.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (308 commits) media: ipu-bridge: check all DMI entries when overriding sensor rotation media: v4l2-async: avoid deleting unlinked ASC entry on link error media: rzg2l-cru: Align bytesperline to hardware DMA stride requirement media: intel/ipu6: fix async notifier cleanup leak on parse error media: staging/ipu7: fix async notifier UAF on probe error path media: amd: isp4: fix self-deadlock in isp4sd_pwron_and_init() error path media: amd: isp4: release partial allocations in isp4if_alloc_fw_gpumem() media: rcar-isp: Fix VSPX reference leaks media: rcar-isp: Release ISPCORE resources media: i2c: imx415: Release runtime PM reference on VBLANK error media: i2c: imx415: Return test pattern write errors media: renesas: vsp1: Declare index variables in for loop statement media: renesas: vsp1: Make reset control optional to support platforms without a reset line media: dt-bindings: media: renesas,vsp1: Document RZ/T2H and RZ/N2H SoCs media: dt-bindings: media: renesas,fcp: Document RZ/T2H and RZ/N2H SoCs media: nxp: imx8-isi: Add additional 32-bit RGB format support media: nxp: imx8-isi: Add 16-bit raw Bayer format support media: nxp: imx8-isi: Implement per-stream reference counting for multiplexed streams media: nxp: imx8-isi: Use BIT_ULL() for 64-bit stream masks media: nxp: imx8-isi: Correct color map between V4L2 and ISI ...
Diffstat (limited to 'drivers/media/usb')
-rw-r--r--drivers/media/usb/airspy/airspy.c17
-rw-r--r--drivers/media/usb/au0828/au0828-cards.c14
-rw-r--r--drivers/media/usb/au0828/au0828-cards.h1
-rw-r--r--drivers/media/usb/au0828/au0828-dvb.c1
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-audio.c5
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-video.c4
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf.c12
-rw-r--r--drivers/media/usb/em28xx/em28xx-cards.c36
-rw-r--r--drivers/media/usb/em28xx/em28xx-core.c4
-rw-r--r--drivers/media/usb/em28xx/em28xx-dvb.c2
-rw-r--r--drivers/media/usb/em28xx/em28xx-reg.h1
-rw-r--r--drivers/media/usb/em28xx/em28xx-video.c114
-rw-r--r--drivers/media/usb/em28xx/em28xx.h3
-rw-r--r--drivers/media/usb/go7007/go7007-driver.c14
-rw-r--r--drivers/media/usb/go7007/go7007-fw.c28
-rw-r--r--drivers/media/usb/go7007/s2250-board.c54
-rw-r--r--drivers/media/usb/go7007/snd-go7007.c10
-rw-r--r--drivers/media/usb/gspca/jl2005bcd.c7
-rw-r--r--drivers/media/usb/s2255/s2255drv.c422
-rw-r--r--drivers/media/usb/stk1160/stk1160-core.c15
-rw-r--r--drivers/media/usb/stk1160/stk1160-video.c3
-rw-r--r--drivers/media/usb/usbtv/usbtv-audio.c11
-rw-r--r--drivers/media/usb/usbtv/usbtv-core.c5
-rw-r--r--drivers/media/usb/usbtv/usbtv-video.c4
24 files changed, 454 insertions, 333 deletions
diff --git a/drivers/media/usb/airspy/airspy.c b/drivers/media/usb/airspy/airspy.c
index 57edb42463e8..358a66ab8e48 100644
--- a/drivers/media/usb/airspy/airspy.c
+++ b/drivers/media/usb/airspy/airspy.c
@@ -464,14 +464,21 @@ static void airspy_disconnect(struct usb_interface *intf)
dev_dbg(s->dev, "\n");
- mutex_lock(&s->vb_queue_lock);
+ /*
+ * vb2_video_unregister_device() releases the vb2 queue, which
+ * triggers airspy_stop_streaming() if streaming is active.
+ * stop_streaming() dereferences s->udev via airspy_ctrl_msg() and
+ * airspy_free_stream_bufs(), so it must run before s->udev is
+ * cleared. vb2_video_unregister_device() locks vb_queue_lock
+ * internally and stop_streaming() locks v4l2_lock, so neither may
+ * be held by the caller.
+ */
+ v4l2_device_disconnect(&s->v4l2_dev);
+ vb2_video_unregister_device(&s->vdev);
+
mutex_lock(&s->v4l2_lock);
- /* No need to keep the urbs around after disconnection */
s->udev = NULL;
- v4l2_device_disconnect(&s->v4l2_dev);
- video_unregister_device(&s->vdev);
mutex_unlock(&s->v4l2_lock);
- mutex_unlock(&s->vb_queue_lock);
v4l2_device_put(&s->v4l2_dev);
}
diff --git a/drivers/media/usb/au0828/au0828-cards.c b/drivers/media/usb/au0828/au0828-cards.c
index 9929ce5dcdcd..8ab100db01ab 100644
--- a/drivers/media/usb/au0828/au0828-cards.c
+++ b/drivers/media/usb/au0828/au0828-cards.c
@@ -124,6 +124,17 @@ struct au0828_board au0828_boards[] = {
},
},
},
+ [AU0828_BOARD_MONOPRICE_106456] = {
+ /*
+ * Monoprice 106456 USB ATSC/QAM tuner (board rev TV22AD-A),
+ * a.k.a. AnyTV AUTV002, USB ID 05e1:0400. Same AU8522 demod +
+ * NXP TDA18271HDC2 tuner @ 0x60 as the Hauppauge Woodbury.
+ */
+ .name = "Monoprice 106456 USB ATSC/QAM (TV22AD-A)",
+ .tuner_type = TUNER_NXP_TDA18271,
+ .tuner_addr = 0x60,
+ .i2c_clk_divider = AU0828_I2C_CLK_250KHZ,
+ },
[AU0828_BOARD_HAUPPAUGE_HVR1265] = {
.name = "Hauppauge HVR1265",
.tuner_type = TUNER_XC5000,
@@ -294,6 +305,7 @@ void au0828_gpio_setup(struct au0828_dev *dev)
case AU0828_BOARD_HAUPPAUGE_WOODBURY:
case AU0828_BOARD_HAUPPAUGE_HVR1265:
case AU0828_BOARD_HAUPPAUGE_IMPACTVCBE:
+ case AU0828_BOARD_MONOPRICE_106456:
/* GPIO's
* 4 - CS5340
* 5 - AU8522 Demodulator
@@ -378,6 +390,8 @@ struct usb_device_id au0828_usb_id_table[] = {
.driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL },
{ USB_DEVICE(0x05e1, 0x0480),
.driver_info = AU0828_BOARD_HAUPPAUGE_WOODBURY },
+ { USB_DEVICE(0x05e1, 0x0400),
+ .driver_info = AU0828_BOARD_MONOPRICE_106456 },
{ USB_DEVICE(0x2040, 0x8200),
.driver_info = AU0828_BOARD_HAUPPAUGE_WOODBURY },
{ USB_DEVICE(0x2040, 0x7260),
diff --git a/drivers/media/usb/au0828/au0828-cards.h b/drivers/media/usb/au0828/au0828-cards.h
index a438aeb334a0..a4a283731f7d 100644
--- a/drivers/media/usb/au0828/au0828-cards.h
+++ b/drivers/media/usb/au0828/au0828-cards.h
@@ -13,3 +13,4 @@
#define AU0828_BOARD_HAUPPAUGE_WOODBURY 5
#define AU0828_BOARD_HAUPPAUGE_IMPACTVCBE 6
#define AU0828_BOARD_HAUPPAUGE_HVR1265 7
+#define AU0828_BOARD_MONOPRICE_106456 8
diff --git a/drivers/media/usb/au0828/au0828-dvb.c b/drivers/media/usb/au0828/au0828-dvb.c
index 31123e6f9fc3..9c95b7ceaecd 100644
--- a/drivers/media/usb/au0828/au0828-dvb.c
+++ b/drivers/media/usb/au0828/au0828-dvb.c
@@ -600,6 +600,7 @@ int au0828_dvb_register(struct au0828_dev *dev)
&mxl5007t_hvr950q_config);
break;
case AU0828_BOARD_HAUPPAUGE_WOODBURY:
+ case AU0828_BOARD_MONOPRICE_106456:
dvb->frontend = dvb_attach(au8522_attach,
&hauppauge_woodbury_config,
&dev->i2c_adap);
diff --git a/drivers/media/usb/cx231xx/cx231xx-audio.c b/drivers/media/usb/cx231xx/cx231xx-audio.c
index 9c71b32552df..b24ceef497e4 100644
--- a/drivers/media/usb/cx231xx/cx231xx-audio.c
+++ b/drivers/media/usb/cx231xx/cx231xx-audio.c
@@ -443,6 +443,11 @@ static int snd_cx231xx_pcm_close(struct snd_pcm_substream *substream)
int ret;
struct cx231xx *dev = snd_pcm_substream_chip(substream);
+ if (!dev) {
+ pr_err("cx231xx: called with null device\n");
+ return -ENODEV;
+ }
+
dev_dbg(dev->dev, "closing device\n");
/* inform hardware to stop streaming */
diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c
index 2cd4e333bc4b..70aa99fead27 100644
--- a/drivers/media/usb/cx231xx/cx231xx-video.c
+++ b/drivers/media/usb/cx231xx/cx231xx-video.c
@@ -898,7 +898,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
if (rc)
return rc;
- if (vb2_is_busy(&dev->vidq)) {
+ if (vb2_is_busy(&dev->vidq) || vb2_is_busy(&dev->vbiq)) {
dev_err(dev->dev, "%s: queue busy\n", __func__);
return -EBUSY;
}
@@ -933,7 +933,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm)
if (dev->norm == norm)
return 0;
- if (vb2_is_busy(&dev->vidq))
+ if (vb2_is_busy(&dev->vidq) || vb2_is_busy(&dev->vbiq))
return -EBUSY;
dev->norm = norm;
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf.c b/drivers/media/usb/dvb-usb-v2/mxl111sf.c
index 870ac3c8b085..6404eb74db32 100644
--- a/drivers/media/usb/dvb-usb-v2/mxl111sf.c
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf.c
@@ -987,11 +987,7 @@ static int mxl111sf_frontend_attach_atsc_mh(struct dvb_usb_adapter *adap)
if (ret < 0)
return ret;
- ret = mxl111sf_lg2160_frontend_attach(adap, 2);
- if (ret < 0)
- return ret;
-
- return ret;
+ return mxl111sf_lg2160_frontend_attach(adap, 2);
}
static int mxl111sf_frontend_attach_mercury(struct dvb_usb_adapter *adap)
@@ -1007,11 +1003,7 @@ static int mxl111sf_frontend_attach_mercury(struct dvb_usb_adapter *adap)
if (ret < 0)
return ret;
- ret = mxl111sf_lg2161_ep6_frontend_attach(adap, 2);
- if (ret < 0)
- return ret;
-
- return ret;
+ return mxl111sf_lg2161_ep6_frontend_attach(adap, 2);
}
static int mxl111sf_frontend_attach_mercury_mh(struct dvb_usb_adapter *adap)
diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c
index fbfb74eab475..b7c534fc8a21 100644
--- a/drivers/media/usb/em28xx/em28xx-cards.c
+++ b/drivers/media/usb/em28xx/em28xx-cards.c
@@ -2677,6 +2677,28 @@ const struct em28xx_board em28xx_boards[] = {
.gpio = mygica_utv3_tuner_audio_gpio,
} },
},
+ /* eb1a:8286 StarTech SVID2USB232
+ * Empia EM28281 with integrated TVP5150-compatible video decoder.
+ * Composite and S-Video inputs, stereo line-in audio.
+ */
+ [EM28281_BOARD_STARTECH_SVID2USB232] = {
+ .name = "StarTech SVID2USB232",
+ .vchannels = 2,
+ .tuner_type = TUNER_ABSENT,
+ .has_dvb = 0,
+ .decoder = EM28XX_BUILTIN,
+ .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ,
+ .xclk = EM28XX_XCLK_FREQUENCY_12MHZ,
+ .input = { {
+ .type = EM28XX_VMUX_COMPOSITE,
+ .vmux = EM2828X_COMPOSITE,
+ .amux = EM28XX_AMUX_LINE_IN,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = EM2828X_SVIDEO,
+ .amux = EM28XX_AMUX_LINE_IN,
+ } },
+ },
[EM2828X_BOARD_HAUPPAUGE_USB_LIVE2] = {
.name = "Hauppauge USB Live2",
.vchannels = 2,
@@ -2946,6 +2968,8 @@ struct usb_device_id em28xx_id_table[] = {
.driver_info = EM2874_BOARD_HAUPPAUGE_USB_QUADHD },
{ USB_DEVICE(0x2040, 0xc220),
.driver_info = EM2828X_BOARD_HAUPPAUGE_USB_LIVE2 },
+ { USB_DEVICE(0xeb1a, 0x8286),
+ .driver_info = EM28281_BOARD_STARTECH_SVID2USB232 },
{ USB_DEVICE(0x2040, 0x0360),
.driver_info = EM2828X_BOARD_HAUPPAUGE_935_V2 },
{ USB_DEVICE(0x2040, 0x8360),
@@ -3651,6 +3675,7 @@ static void request_module_async(struct work_struct *work)
* intf. Don't register extensions twice on those devices.
*/
if (dev->is_audio_only) {
+ em28xx_init_extension(dev);
#if defined(CONFIG_MODULES) && defined(MODULE)
request_module("em28xx-alsa");
#endif
@@ -3758,7 +3783,7 @@ void em28xx_free_device(struct kref *ref)
{
struct em28xx *dev = kref_to_dev(ref);
- dev_info(&dev->intf->dev, "Freeing device\n");
+ pr_info("%s: Freeing device\n", dev->name);
if (!dev->disconnected)
em28xx_release_resources(dev);
@@ -3859,6 +3884,11 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev,
dev->wait_after_write = 0;
dev->eeprom_addrwidth_16bit = 1;
break;
+ case CHIP_ID_EM28281:
+ chip_name = "em28281";
+ dev->wait_after_write = 0;
+ dev->eeprom_addrwidth_16bit = 1;
+ break;
case CHIP_ID_EM2883:
chip_name = "em2882/3";
dev->wait_after_write = 0;
@@ -3884,8 +3914,6 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev,
retval = -ENODEV;
goto err_deinit_media;
}
- em28xx_init_extension(dev);
-
return 0;
}
@@ -4082,7 +4110,7 @@ static void em28xx_check_usb_descriptor(struct em28xx *dev,
dev->analog_ep_bulk = e->bEndpointAddress;
}
return;
- };
+ }
}
/*
diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c
index 5bbb082dbed9..0b998e7cafef 100644
--- a/drivers/media/usb/em28xx/em28xx-core.c
+++ b/drivers/media/usb/em28xx/em28xx-core.c
@@ -632,7 +632,7 @@ void em2828X_decoder_vmux(struct em28xx *dev, unsigned int vin)
default:
dev_dbg(&dev->intf->dev, "EM2828X_SVIDEO\n");
break;
- };
+ }
em28xx_write_reg(dev, 0x24, 0x00);
em28xx_write_reg(dev, 0x25, 0x02);
@@ -1265,6 +1265,8 @@ void em28xx_close_extension(struct em28xx *dev)
ops->fini(dev);
}
}
+ if (dev->dev_next)
+ list_del(&dev->dev_next->devlist);
list_del(&dev->devlist);
mutex_unlock(&em28xx_devlist_mutex);
}
diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c
index 938f1980d448..8482fc4045ea 100644
--- a/drivers/media/usb/em28xx/em28xx-dvb.c
+++ b/drivers/media/usb/em28xx/em28xx-dvb.c
@@ -29,7 +29,7 @@
#include <media/dmxdev.h>
#include <media/tuner.h>
#include "tuner-simple.h"
-#include <linux/gpio.h>
+#include <linux/gpio/legacy.h>
#include "lgdt330x.h"
#include "lgdt3305.h"
diff --git a/drivers/media/usb/em28xx/em28xx-reg.h b/drivers/media/usb/em28xx/em28xx-reg.h
index 68a0fcc2fa72..8931733a8e24 100644
--- a/drivers/media/usb/em28xx/em28xx-reg.h
+++ b/drivers/media/usb/em28xx/em28xx-reg.h
@@ -283,6 +283,7 @@ enum em28xx_chip_id {
CHIP_ID_EM2884 = 68,
CHIP_ID_EM28174 = 113,
CHIP_ID_EM28178 = 114,
+ CHIP_ID_EM28281 = 145,
CHIP_ID_EM2828X = 148,
};
diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c
index da0422c65e5f..c418add65bb5 100644
--- a/drivers/media/usb/em28xx/em28xx-video.c
+++ b/drivers/media/usb/em28xx/em28xx-video.c
@@ -1213,6 +1213,9 @@ int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count)
{
struct em28xx *dev = vb2_get_drv_priv(vq);
struct em28xx_v4l2 *v4l2 = dev->v4l2;
+ struct em28xx_dmaqueue *dmaq = vq->type == V4L2_BUF_TYPE_VBI_CAPTURE ?
+ &dev->vbiq : &dev->vidq;
+ unsigned long flags = 0;
struct v4l2_frequency f;
struct v4l2_fh *owner;
int rc = 0;
@@ -1227,7 +1230,7 @@ int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count)
*/
rc = res_get(dev, vq->type);
if (rc)
- return rc;
+ goto exit;
if (v4l2->streaming_users == 0) {
/* First active streaming user, so allocate all the URBs */
@@ -1250,7 +1253,7 @@ int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count)
em28xx_urb_data_copy);
if (rc < 0) {
res_free(dev, vq->type);
- return rc;
+ goto exit;
}
/*
@@ -1275,7 +1278,18 @@ int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count)
}
v4l2->streaming_users++;
+ return 0;
+
+exit:
+ spin_lock_irqsave(&dev->slock, flags);
+ while (!list_empty(&dmaq->active)) {
+ struct em28xx_buffer *buf;
+ buf = list_entry(dmaq->active.next, struct em28xx_buffer, list);
+ list_del(&buf->list);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
+ }
+ spin_unlock_irqrestore(&dev->slock, flags);
return rc;
}
@@ -2275,18 +2289,27 @@ static int radio_s_tuner(struct file *file, void *priv,
}
/*
- * em28xx_free_v4l2() - Free struct em28xx_v4l2
+ * em28xx_free_v4l2() - v4l2_device release callback
*
- * @ref: struct kref for struct em28xx_v4l2
+ * @v4l2_dev: pointer to struct v4l2_device embedded in struct em28xx_v4l2
*
- * Called when all users of struct em28xx_v4l2 are gone
+ * Called by the v4l2 core when the last reference to the v4l2_device is
+ * released. At this point no userspace file handle nor video_device node
+ * keeps the v4l2 instance alive anymore, so it is safe to release all
+ * v4l2-related resources and drop the em28xx device reference taken when
+ * the v4l2 extension was initialized.
*/
-static void em28xx_free_v4l2(struct kref *ref)
+static void em28xx_free_v4l2(struct v4l2_device *v4l2_dev)
{
- struct em28xx_v4l2 *v4l2 = container_of(ref, struct em28xx_v4l2, ref);
+ struct em28xx_v4l2 *v4l2 =
+ container_of(v4l2_dev, struct em28xx_v4l2, v4l2_dev);
+ struct em28xx *dev = v4l2->dev;
- v4l2->dev->v4l2 = NULL;
+ v4l2_ctrl_handler_free(&v4l2->ctrl_handler);
+ v4l2_device_unregister(v4l2_dev);
+ dev->v4l2 = NULL;
kfree(v4l2);
+ kref_put(&dev->ref, em28xx_free_device);
}
/*
@@ -2323,9 +2346,8 @@ static int em28xx_v4l2_open(struct file *filp)
return -ENODEV;
}
- em28xx_videodbg("open dev=%s type=%s users=%d\n",
- video_device_node_name(vdev), v4l2_type_names[fh_type],
- v4l2->users);
+ em28xx_videodbg("open dev=%s type=%s\n",
+ video_device_node_name(vdev), v4l2_type_names[fh_type]);
ret = v4l2_fh_open(filp);
if (ret) {
@@ -2336,7 +2358,7 @@ static int em28xx_v4l2_open(struct file *filp)
return ret;
}
- if (v4l2->users == 0) {
+ if (v4l2_fh_is_singular_file(filp)) {
em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
if (vdev->vfl_type != VFL_TYPE_RADIO)
@@ -2354,10 +2376,6 @@ static int em28xx_v4l2_open(struct file *filp)
v4l2_device_call_all(&v4l2->v4l2_dev, 0, tuner, s_radio);
}
- kref_get(&dev->ref);
- kref_get(&v4l2->ref);
- v4l2->users++;
-
mutex_unlock(&dev->lock);
return 0;
@@ -2398,27 +2416,27 @@ static int em28xx_v4l2_fini(struct em28xx *dev)
if (video_is_registered(&v4l2->radio_dev)) {
dev_info(&dev->intf->dev, "V4L2 device %s deregistered\n",
video_device_node_name(&v4l2->radio_dev));
- video_unregister_device(&v4l2->radio_dev);
+ vb2_video_unregister_device(&v4l2->radio_dev);
}
if (video_is_registered(&v4l2->vbi_dev)) {
dev_info(&dev->intf->dev, "V4L2 device %s deregistered\n",
video_device_node_name(&v4l2->vbi_dev));
- video_unregister_device(&v4l2->vbi_dev);
+ vb2_video_unregister_device(&v4l2->vbi_dev);
}
if (video_is_registered(&v4l2->vdev)) {
dev_info(&dev->intf->dev, "V4L2 device %s deregistered\n",
video_device_node_name(&v4l2->vdev));
- video_unregister_device(&v4l2->vdev);
+ vb2_video_unregister_device(&v4l2->vdev);
}
- v4l2_ctrl_handler_free(&v4l2->ctrl_handler);
- v4l2_device_unregister(&v4l2->v4l2_dev);
-
- kref_put(&v4l2->ref, em28xx_free_v4l2);
-
mutex_unlock(&dev->lock);
- kref_put(&dev->ref, em28xx_free_device);
+ /*
+ * Drop the initial reference taken at v4l2_device_register() time.
+ * The em28xx_free_v4l2() release callback will be invoked once all
+ * userspace file handles to the video device nodes are closed.
+ */
+ v4l2_device_put(&v4l2->v4l2_dev);
return 0;
}
@@ -2460,13 +2478,13 @@ static int em28xx_v4l2_close(struct file *filp)
struct em28xx_v4l2 *v4l2 = dev->v4l2;
struct usb_device *udev = interface_to_usbdev(dev->intf);
int err;
+ bool last_user;
- em28xx_videodbg("users=%d\n", v4l2->users);
-
- vb2_fop_release(filp);
mutex_lock(&dev->lock);
+ last_user = v4l2_fh_is_singular_file(filp);
+ _vb2_fop_release(filp, NULL);
- if (v4l2->users == 1) {
+ if (last_user) {
/* No sense to try to write to the device */
if (dev->disconnected)
goto exit;
@@ -2489,10 +2507,7 @@ static int em28xx_v4l2_close(struct file *filp)
}
exit:
- v4l2->users--;
- kref_put(&v4l2->ref, em28xx_free_v4l2);
mutex_unlock(&dev->lock);
- kref_put(&dev->ref, em28xx_free_device);
return 0;
}
@@ -2711,7 +2726,6 @@ static int em28xx_v4l2_init(struct em28xx *dev)
mutex_unlock(&dev->lock);
return -ENOMEM;
}
- kref_init(&v4l2->ref);
v4l2->dev = dev;
dev->v4l2 = v4l2;
@@ -2722,9 +2736,21 @@ static int em28xx_v4l2_init(struct em28xx *dev)
if (ret < 0) {
dev_err(&dev->intf->dev,
"Call to v4l2_device_register() failed!\n");
- goto err;
+ dev->v4l2 = NULL;
+ kfree(v4l2);
+ mutex_unlock(&dev->lock);
+ return ret;
}
+ /*
+ * From this point on, em28xx_free_v4l2() will be used to release
+ * v4l2-related resources when the v4l2_device refcount reaches
+ * zero. Take a reference to the em28xx device so that it cannot
+ * be freed before the v4l2 instance is released.
+ */
+ v4l2->v4l2_dev.release = em28xx_free_v4l2;
+ kref_get(&dev->ref);
+
hdl = &v4l2->ctrl_handler;
v4l2_ctrl_handler_init(hdl, 9);
v4l2->v4l2_dev.ctrl_handler = hdl;
@@ -3048,8 +3074,6 @@ static int em28xx_v4l2_init(struct em28xx *dev)
dev_info(&dev->intf->dev,
"V4L2 extension successfully initialized\n");
- kref_get(&dev->ref);
-
mutex_unlock(&dev->lock);
return 0;
@@ -3058,27 +3082,29 @@ unregister_dev:
dev_info(&dev->intf->dev,
"V4L2 device %s deregistered\n",
video_device_node_name(&v4l2->radio_dev));
- video_unregister_device(&v4l2->radio_dev);
+ vb2_video_unregister_device(&v4l2->radio_dev);
}
if (video_is_registered(&v4l2->vbi_dev)) {
dev_info(&dev->intf->dev,
"V4L2 device %s deregistered\n",
video_device_node_name(&v4l2->vbi_dev));
- video_unregister_device(&v4l2->vbi_dev);
+ vb2_video_unregister_device(&v4l2->vbi_dev);
}
if (video_is_registered(&v4l2->vdev)) {
dev_info(&dev->intf->dev,
"V4L2 device %s deregistered\n",
video_device_node_name(&v4l2->vdev));
- video_unregister_device(&v4l2->vdev);
+ vb2_video_unregister_device(&v4l2->vdev);
}
- v4l2_ctrl_handler_free(&v4l2->ctrl_handler);
- v4l2_device_unregister(&v4l2->v4l2_dev);
-err:
- dev->v4l2 = NULL;
- kref_put(&v4l2->ref, em28xx_free_v4l2);
mutex_unlock(&dev->lock);
+
+ /*
+ * Drop the initial reference. em28xx_free_v4l2() will be called
+ * once the last video_device node release has decremented the
+ * v4l2_device refcount to zero.
+ */
+ v4l2_device_put(&v4l2->v4l2_dev);
return ret;
}
diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h
index 711f281613f5..8eee639b0940 100644
--- a/drivers/media/usb/em28xx/em28xx.h
+++ b/drivers/media/usb/em28xx/em28xx.h
@@ -150,6 +150,7 @@
#define EM2828X_BOARD_HAUPPAUGE_955_V2 110
#define EM2828X_BOARD_HAUPPAUGE_975_V2 111
#define EM28178_BOARD_PCTV_461E_V3 112
+#define EM28281_BOARD_STARTECH_SVID2USB232 113
/* Limits minimum and default number of buffers */
#define EM28XX_MIN_BUF 4
@@ -558,7 +559,6 @@ struct em28xx_eeprom {
#define EM28XX_RESOURCE_VBI 0x02
struct em28xx_v4l2 {
- struct kref ref;
struct em28xx *dev;
struct v4l2_device v4l2_dev;
@@ -582,7 +582,6 @@ struct em28xx_v4l2 {
int sensor_yres;
int sensor_xtal;
- int users; /* user count for exclusive use */
int streaming_users; /* number of actively streaming users */
u32 frequency; /* selected tuner frequency */
diff --git a/drivers/media/usb/go7007/go7007-driver.c b/drivers/media/usb/go7007/go7007-driver.c
index 25b3ee25aaa4..453ab5c3aa03 100644
--- a/drivers/media/usb/go7007/go7007-driver.c
+++ b/drivers/media/usb/go7007/go7007-driver.c
@@ -264,17 +264,17 @@ int go7007_register_encoder(struct go7007 *go, unsigned num_i2c_devs)
ret = go7007_init_encoder(go);
mutex_unlock(&go->hw_lock);
if (ret < 0)
- return ret;
+ goto err_unregister_v4l2_dev;
ret = go7007_v4l2_ctrl_init(go);
if (ret < 0)
- return ret;
+ goto err_free_controls;
if (!go->i2c_adapter_online &&
go->board_info->flags & GO7007_BOARD_USE_ONBOARD_I2C) {
ret = go7007_i2c_init(go);
if (ret < 0)
- return ret;
+ goto err_free_controls;
go->i2c_adapter_online = 1;
}
if (go->i2c_adapter_online) {
@@ -304,13 +304,19 @@ int go7007_register_encoder(struct go7007 *go, unsigned num_i2c_devs)
ret = go7007_v4l2_init(go);
if (ret < 0)
- return ret;
+ goto err_free_controls;
if (go->board_info->flags & GO7007_BOARD_HAS_AUDIO) {
go->audio_enabled = 1;
go7007_snd_init(go);
}
return 0;
+
+err_free_controls:
+ v4l2_ctrl_handler_free(&go->hdl);
+err_unregister_v4l2_dev:
+ v4l2_device_unregister(&go->v4l2_dev);
+ return ret;
}
EXPORT_SYMBOL(go7007_register_encoder);
diff --git a/drivers/media/usb/go7007/go7007-fw.c b/drivers/media/usb/go7007/go7007-fw.c
index 86ce593e0c54..8cf959c20e30 100644
--- a/drivers/media/usb/go7007/go7007-fw.c
+++ b/drivers/media/usb/go7007/go7007-fw.c
@@ -13,6 +13,7 @@
*/
#include <linux/module.h>
+#include <linux/bitops.h>
#include <linux/time.h>
#include <linux/mm.h>
#include <linux/device.h>
@@ -58,14 +59,16 @@ struct code_gen {
#define CODE_GEN(name, dest) struct code_gen name = { dest, 0, 32, 0 }
#define CODE_ADD(name, val, length) do { \
- name.b -= (length); \
- name.a |= (val) << name.b; \
- while (name.b <= 24) { \
- *name.p = name.a >> 24; \
- ++name.p; \
- name.a <<= 8; \
- name.b += 8; \
- name.len += 8; \
+ if (length) { \
+ name.b -= (length); \
+ name.a |= (val) << name.b; \
+ while (name.b <= 24) { \
+ *name.p = name.a >> 24; \
+ ++name.p; \
+ name.a <<= 8; \
+ name.b += 8; \
+ name.len += 8; \
+ } \
} \
} while (0)
@@ -707,11 +710,10 @@ done:
static int vti_bitlen(struct go7007 *go)
{
- unsigned int i, max_time_incr = go->sensor_framerate / go->fps_scale;
+ unsigned int max_time_incr = go->sensor_framerate / go->fps_scale;
+ int bitlen = fls(max_time_incr);
- for (i = 31; (max_time_incr & ((1 << i) - 1)) == max_time_incr; --i)
- ;
- return i + 1;
+ return bitlen ?: 1;
}
static int mpeg4_frame_header(struct go7007 *go, unsigned char *buf,
@@ -1209,7 +1211,7 @@ static int seqhead_to_package(struct go7007 *go, __le16 *code, int space,
0xbf08, fps,
0xbf09, 0,
0xbff2, vop_time_increment_bitlength,
- 0xbff3, (1 << vop_time_increment_bitlength) - 1,
+ 0xbff3, GENMASK(vop_time_increment_bitlength - 1, 0),
0xbfe6, 0,
0xbfe7, (fps / 1000) << 8,
0, 0,
diff --git a/drivers/media/usb/go7007/s2250-board.c b/drivers/media/usb/go7007/s2250-board.c
index 0901d79e827d..d11f8e723624 100644
--- a/drivers/media/usb/go7007/s2250-board.c
+++ b/drivers/media/usb/go7007/s2250-board.c
@@ -365,36 +365,48 @@ static int s2250_s_ctrl(struct v4l2_ctrl *ctrl)
struct s2250 *state = container_of(ctrl->handler, struct s2250, hdl);
struct i2c_client *client = v4l2_get_subdevdata(&state->sd);
u16 oldvalue;
+ int ret;
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
- read_reg_fp(client, VPX322_ADDR_BRIGHTNESS0, &oldvalue);
- write_reg_fp(client, VPX322_ADDR_BRIGHTNESS0,
- ctrl->val | (oldvalue & ~0xff));
- read_reg_fp(client, VPX322_ADDR_BRIGHTNESS1, &oldvalue);
- write_reg_fp(client, VPX322_ADDR_BRIGHTNESS1,
- ctrl->val | (oldvalue & ~0xff));
- write_reg_fp(client, 0x140, 0x60);
- break;
+ ret = read_reg_fp(client, VPX322_ADDR_BRIGHTNESS0, &oldvalue);
+ if (ret)
+ return ret;
+ ret = write_reg_fp(client, VPX322_ADDR_BRIGHTNESS0,
+ ctrl->val | (oldvalue & ~0xff));
+ if (ret)
+ return ret;
+ ret = read_reg_fp(client, VPX322_ADDR_BRIGHTNESS1, &oldvalue);
+ if (ret)
+ return ret;
+ ret = write_reg_fp(client, VPX322_ADDR_BRIGHTNESS1,
+ ctrl->val | (oldvalue & ~0xff));
+ if (ret)
+ return ret;
+ return write_reg_fp(client, 0x140, 0x60);
case V4L2_CID_CONTRAST:
- read_reg_fp(client, VPX322_ADDR_CONTRAST0, &oldvalue);
- write_reg_fp(client, VPX322_ADDR_CONTRAST0,
- ctrl->val | (oldvalue & ~0x3f));
- read_reg_fp(client, VPX322_ADDR_CONTRAST1, &oldvalue);
- write_reg_fp(client, VPX322_ADDR_CONTRAST1,
- ctrl->val | (oldvalue & ~0x3f));
- write_reg_fp(client, 0x140, 0x60);
- break;
+ ret = read_reg_fp(client, VPX322_ADDR_CONTRAST0, &oldvalue);
+ if (ret)
+ return ret;
+ ret = write_reg_fp(client, VPX322_ADDR_CONTRAST0,
+ ctrl->val | (oldvalue & ~0x3f));
+ if (ret)
+ return ret;
+ ret = read_reg_fp(client, VPX322_ADDR_CONTRAST1, &oldvalue);
+ if (ret)
+ return ret;
+ ret = write_reg_fp(client, VPX322_ADDR_CONTRAST1,
+ ctrl->val | (oldvalue & ~0x3f));
+ if (ret)
+ return ret;
+ return write_reg_fp(client, 0x140, 0x60);
case V4L2_CID_SATURATION:
- write_reg_fp(client, VPX322_ADDR_SAT, ctrl->val);
- break;
+ return write_reg_fp(client, VPX322_ADDR_SAT, ctrl->val);
case V4L2_CID_HUE:
- write_reg_fp(client, VPX322_ADDR_HUE, ctrl->val);
- break;
+ return write_reg_fp(client, VPX322_ADDR_HUE, ctrl->val);
default:
return -EINVAL;
}
- return 0;
}
static int s2250_set_fmt(struct v4l2_subdev *sd,
diff --git a/drivers/media/usb/go7007/snd-go7007.c b/drivers/media/usb/go7007/snd-go7007.c
index e4b9f37be77b..01d547ad678d 100644
--- a/drivers/media/usb/go7007/snd-go7007.c
+++ b/drivers/media/usb/go7007/snd-go7007.c
@@ -195,6 +195,13 @@ static const struct snd_device_ops go7007_snd_device_ops = {
.dev_free = go7007_snd_free,
};
+static void go7007_snd_card_free(struct snd_card *card)
+{
+ struct go7007 *go = card->private_data;
+
+ v4l2_device_put(&go->v4l2_dev);
+}
+
int go7007_snd_init(struct go7007 *go)
{
static int dev;
@@ -245,6 +252,8 @@ int go7007_snd_init(struct go7007 *go)
gosnd->substream = NULL;
go->snd_context = gosnd;
v4l2_device_get(&go->v4l2_dev);
+ gosnd->card->private_data = go;
+ gosnd->card->private_free = go7007_snd_card_free;
++dev;
return 0;
@@ -263,7 +272,6 @@ int go7007_snd_remove(struct go7007 *go)
snd_card_disconnect(gosnd->card);
snd_card_free_when_closed(gosnd->card);
- v4l2_device_put(&go->v4l2_dev);
return 0;
}
EXPORT_SYMBOL(go7007_snd_remove);
diff --git a/drivers/media/usb/gspca/jl2005bcd.c b/drivers/media/usb/gspca/jl2005bcd.c
index a408fcc3a060..4988fbf5005e 100644
--- a/drivers/media/usb/gspca/jl2005bcd.c
+++ b/drivers/media/usb/gspca/jl2005bcd.c
@@ -148,17 +148,12 @@ static int jl2005c_start_new_frame(struct gspca_dev *gspca_dev)
static int jl2005c_write_reg(struct gspca_dev *gspca_dev, unsigned char reg,
unsigned char value)
{
- int retval;
u8 instruction[2];
instruction[0] = reg;
instruction[1] = value;
- retval = jl2005c_write2(gspca_dev, instruction);
- if (retval < 0)
- return retval;
-
- return retval;
+ return jl2005c_write2(gspca_dev, instruction);
}
static int jl2005c_get_firmware_id(struct gspca_dev *gspca_dev)
diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c
index 0b8182edf8e4..15012d73975c 100644
--- a/drivers/media/usb/s2255/s2255drv.c
+++ b/drivers/media/usb/s2255/s2255drv.c
@@ -69,7 +69,7 @@
#define MAX_CHANNELS 4
#define SYS_FRAMES 4
/* maximum size is PAL full size plus room for the marker header(s) */
-#define SYS_FRAMES_MAXSIZE (720*288*2*2 + 4096)
+#define SYS_FRAMES_MAXSIZE (720 * 288 * 2 * 2 + 4096)
#define DEF_USB_BLOCK S2255_USB_XFER_SIZE
#define LINE_SZ_4CIFS_NTSC 640
#define LINE_SZ_2CIFS_NTSC 640
@@ -86,7 +86,6 @@
#define LINE_SZ_DEF 640
#define NUM_LINES_DEF 240
-
/* predefined settings */
#define FORMAT_NTSC 1
#define FORMAT_PAL 2
@@ -111,9 +110,9 @@
#define FDEC_3 3 /* capture every 3rd frame */
#define FDEC_5 5 /* capture every 5th frame */
-/*-------------------------------------------------------
- * Default mode parameters.
- *-------------------------------------------------------*/
+/*-------------------------------------------------------*/
+/* Default mode parameters. */
+/*-------------------------------------------------------*/
#define DEF_SCALE SCALE_4CIFS
#define DEF_COLOR COLOR_YUVPL
#define DEF_FDEC FDEC_1
@@ -144,21 +143,20 @@ struct s2255_mode {
u32 restart; /* if DSP requires restart */
};
-
#define S2255_READ_IDLE 0
#define S2255_READ_FRAME 1
/* frame structure */
struct s2255_framei {
unsigned long size;
- unsigned long ulState; /* ulState:S2255_READ_IDLE, S2255_READ_FRAME*/
+ unsigned long state; /* state:S2255_READ_IDLE, S2255_READ_FRAME*/
void *lpvbits; /* image data */
unsigned long cur_size; /* current data copied to it */
};
/* image buffer structure */
struct s2255_bufferi {
- unsigned long dwFrames; /* number of frames in buffer */
+ unsigned long num_frames; /* number of frames in buffer */
struct s2255_framei frame[SYS_FRAMES]; /* array of FRAME structures */
};
@@ -212,7 +210,7 @@ struct s2255_vc {
struct s2255_mode mode;
v4l2_std_id std;
/* jpeg compression */
- unsigned jpegqual;
+ unsigned int jpegqual;
/* capture parameters (for high quality mode full size) */
struct v4l2_captureparm cap_parm;
int cur_frame;
@@ -243,7 +241,6 @@ struct s2255_vc {
spinlock_t qlock;
};
-
struct s2255_dev {
struct s2255_vc vc[MAX_CHANNELS];
struct v4l2_device v4l2_dev;
@@ -284,7 +281,6 @@ struct s2255_buffer {
struct list_head list;
};
-
/* current cypress EEPROM firmware version */
#define S2255_CUR_USB_FWVER ((3 << 8) | 12)
/* current DSP FW version */
@@ -343,8 +339,8 @@ static int s2255_board_shutdown(struct s2255_dev *dev);
static void s2255_fwload_start(struct s2255_dev *dev);
static void s2255_destroy(struct s2255_dev *dev);
static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req,
- u16 index, u16 value, void *buf,
- s32 buf_len, int bOut);
+ u16 index, u16 value, void *xfer_buf,
+ s32 xfer_buf_len, int is_out);
/* dev_err macro with driver name */
#define S2255_DRIVER_NAME "s2255"
@@ -352,7 +348,7 @@ static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req,
dev_err(dev, S2255_DRIVER_NAME " - " fmt, ##arg)
#define dprintk(dev, level, fmt, arg...) \
- v4l2_dbg(level, debug, &dev->v4l2_dev, fmt, ## arg)
+ v4l2_dbg(level, debug, &(dev)->v4l2_dev, fmt, ## arg)
static struct usb_driver s2255_driver;
@@ -430,7 +426,6 @@ static int norm_minh(struct s2255_vc *vc)
(NUM_LINES_1CIFS_NTSC) : (NUM_LINES_1CIFS_PAL);
}
-
/*
* TODO: fixme: move YUV reordering to hardware
* converts 2255 planar format to yuyv or uyvy
@@ -440,21 +435,21 @@ static void planar422p_to_yuv_packed(const unsigned char *in,
int width, int height,
int fmt)
{
- unsigned char *pY;
- unsigned char *pCb;
- unsigned char *pCr;
+ unsigned char *p_y;
+ unsigned char *p_cb;
+ unsigned char *p_cr;
unsigned long size = height * width;
unsigned int i;
- pY = (unsigned char *)in;
- pCr = (unsigned char *)in + height * width;
- pCb = (unsigned char *)in + height * width + (height * width / 2);
+
+ p_y = (unsigned char *)in;
+ p_cr = (unsigned char *)in + height * width;
+ p_cb = (unsigned char *)in + height * width + (height * width / 2);
for (i = 0; i < size * 2; i += 4) {
- out[i] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCr++;
- out[i + 1] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCr++ : *pY++;
- out[i + 2] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCb++;
- out[i + 3] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCb++ : *pY++;
+ out[i] = (fmt == V4L2_PIX_FMT_YUYV) ? *p_y++ : *p_cr++;
+ out[i + 1] = (fmt == V4L2_PIX_FMT_YUYV) ? *p_cr++ : *p_y++;
+ out[i + 2] = (fmt == V4L2_PIX_FMT_YUYV) ? *p_y++ : *p_cb++;
+ out[i + 3] = (fmt == V4L2_PIX_FMT_YUYV) ? *p_cb++ : *p_y++;
}
- return;
}
static void s2255_reset_dsppower(struct s2255_dev *dev)
@@ -464,7 +459,6 @@ static void s2255_reset_dsppower(struct s2255_dev *dev)
s2255_vendor_req(dev, 0x50, 0x0000, 0x0000, NULL, 0, 1);
msleep(600);
s2255_vendor_req(dev, 0x10, 0x0000, 0x0000, NULL, 0, 1);
- return;
}
/* kickstarts the firmware loading. from probe
@@ -473,6 +467,7 @@ static void s2255_timer(struct timer_list *t)
{
struct s2255_dev *dev = timer_container_of(dev, t, timer);
struct s2255_fw *data = dev->fw_data;
+
if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
pr_err("s2255: can't submit urb\n");
atomic_set(&data->fw_state, S2255_FW_FAILED);
@@ -482,18 +477,18 @@ static void s2255_timer(struct timer_list *t)
}
}
-
/* this loads the firmware asynchronously.
- Originally this was done synchronously in probe.
- But it is better to load it asynchronously here than block
- inside the probe function. Blocking inside probe affects boot time.
- FW loading is triggered by the timer in the probe function
-*/
+ * Originally this was done synchronously in probe.
+ * But it is better to load it asynchronously here than block
+ * inside the probe function. Blocking inside probe affects boot time.
+ * FW loading is triggered by the timer in the probe function
+ */
static void s2255_fwchunk_complete(struct urb *urb)
{
struct s2255_fw *data = urb->context;
struct usb_device *udev = urb->dev;
int len;
+
if (urb->status) {
dev_err(&udev->dev, "URB failed with status %d\n", urb->status);
atomic_set(&data->fw_state, S2255_FW_FAILED);
@@ -501,7 +496,7 @@ static void s2255_fwchunk_complete(struct urb *urb)
wake_up(&data->wait_fw);
return;
}
- if (data->fw_urb == NULL) {
+ if (!data->fw_urb) {
s2255_dev_err(&udev->dev, "disconnected\n");
atomic_set(&data->fw_state, S2255_FW_FAILED);
/* wake up anything waiting for the firmware */
@@ -510,8 +505,8 @@ static void s2255_fwchunk_complete(struct urb *urb)
}
#define CHUNK_SIZE 512
/* all USB transfers must be done with continuous kernel memory.
- can't allocate more than 128k in current linux kernel, so
- upload the firmware in chunks
+ * can't allocate more than 128k in current linux kernel, so
+ * upload the firmware in chunks
*/
if (data->fw_loaded < data->fw_size) {
len = (data->fw_loaded + CHUNK_SIZE) > data->fw_size ?
@@ -521,7 +516,7 @@ static void s2255_fwchunk_complete(struct urb *urb)
memset(data->pfw_data, 0, CHUNK_SIZE);
memcpy(data->pfw_data,
- (char *) data->fw->data + data->fw_loaded, len);
+ (char *)data->fw->data + data->fw_loaded, len);
usb_fill_bulk_urb(data->fw_urb, udev, usb_sndbulkpipe(udev, 2),
data->pfw_data, CHUNK_SIZE,
@@ -534,10 +529,9 @@ static void s2255_fwchunk_complete(struct urb *urb)
return;
}
data->fw_loaded += len;
- } else
+ } else {
atomic_set(&data->fw_state, S2255_FW_LOADED_DSPWAIT);
- return;
-
+ }
}
static void s2255_got_frame(struct s2255_vc *vc, int jpgsize)
@@ -569,11 +563,12 @@ static void s2255_got_frame(struct s2255_vc *vc, int jpgsize)
static const struct s2255_fmt *format_by_fourcc(int fourcc)
{
unsigned int i;
+
for (i = 0; i < ARRAY_SIZE(formats); i++) {
if (-1 == formats[i].fourcc)
continue;
- if (!jpeg_enable && ((formats[i].fourcc == V4L2_PIX_FMT_JPEG) ||
- (formats[i].fourcc == V4L2_PIX_FMT_MJPEG)))
+ if (!jpeg_enable && (formats[i].fourcc == V4L2_PIX_FMT_JPEG ||
+ formats[i].fourcc == V4L2_PIX_FMT_MJPEG))
continue;
if (formats[i].fourcc == fourcc)
return formats + i;
@@ -617,6 +612,12 @@ static void s2255_fillbuff(struct s2255_vc *vc,
break;
case V4L2_PIX_FMT_JPEG:
case V4L2_PIX_FMT_MJPEG:
+ if (jpgsize < 0 ||
+ jpgsize > vb2_plane_size(&buf->vb.vb2_buf, 0)) {
+ dprintk(dev, 1, "bad JPEG frame size %d\n",
+ jpgsize);
+ break;
+ }
vb2_set_plane_payload(&buf->vb.vb2_buf, 0, jpgsize);
memcpy(vbuf, tmpbuf, jpgsize);
break;
@@ -636,16 +637,16 @@ static void s2255_fillbuff(struct s2255_vc *vc,
vbuf, pos);
}
-
-/* ------------------------------------------------------------------
- Videobuf operations
- ------------------------------------------------------------------*/
+/* ------------------------------------------------------------------ */
+/* Videobuf operations */
+/* ------------------------------------------------------------------ */
static int queue_setup(struct vb2_queue *vq,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], struct device *alloc_devs[])
{
struct s2255_vc *vc = vb2_get_drv_priv(vq);
+
if (*nbuffers < S2255_MIN_BUFS)
*nbuffers = S2255_MIN_BUFS;
*nplanes = 1;
@@ -662,14 +663,13 @@ static int buffer_prepare(struct vb2_buffer *vb)
int h = vc->height;
unsigned long size;
- dprintk(vc->dev, 4, "%s\n", __func__);
- if (vc->fmt == NULL)
+ if (!vc->fmt)
return -EINVAL;
- if ((w < norm_minw(vc)) ||
- (w > norm_maxw(vc)) ||
- (h < norm_minh(vc)) ||
- (h > norm_maxh(vc))) {
+ if (w < norm_minw(vc) ||
+ w > norm_maxw(vc) ||
+ h < norm_minh(vc) ||
+ h > norm_maxh(vc)) {
dprintk(vc->dev, 4, "invalid buffer prepare\n");
return -EINVAL;
}
@@ -689,7 +689,7 @@ static void buffer_queue(struct vb2_buffer *vb)
struct s2255_buffer *buf = container_of(vbuf, struct s2255_buffer, vb);
struct s2255_vc *vc = vb2_get_drv_priv(vb->vb2_queue);
unsigned long flags = 0;
- dprintk(vc->dev, 1, "%s\n", __func__);
+
spin_lock_irqsave(&vc->qlock, flags);
list_add_tail(&buf->list, &vc->buf_list);
spin_unlock_irqrestore(&vc->qlock, flags);
@@ -719,21 +719,21 @@ static int vidioc_querycap(struct file *file, void *priv,
}
static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
+ struct v4l2_fmtdesc *f)
{
int index = f->index;
if (index >= ARRAY_SIZE(formats))
return -EINVAL;
- if (!jpeg_enable && ((formats[index].fourcc == V4L2_PIX_FMT_JPEG) ||
- (formats[index].fourcc == V4L2_PIX_FMT_MJPEG)))
+ if (!jpeg_enable && (formats[index].fourcc == V4L2_PIX_FMT_JPEG ||
+ formats[index].fourcc == V4L2_PIX_FMT_MJPEG))
return -EINVAL;
f->pixelformat = formats[index].fourcc;
return 0;
}
static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
+ struct v4l2_format *f)
{
struct s2255_vc *vc = video_drvdata(file);
int is_ntsc = vc->std & V4L2_STD_525_60;
@@ -753,7 +753,7 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
}
static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
+ struct v4l2_format *f)
{
const struct s2255_fmt *fmt;
enum v4l2_field field;
@@ -762,7 +762,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
fmt = format_by_fourcc(f->fmt.pix.pixelformat);
- if (fmt == NULL)
+ if (!fmt)
return -EINVAL;
dprintk(vc->dev, 50, "%s NTSC: %d suggested width: %d, height: %d\n",
@@ -804,7 +804,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
}
static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
+ struct v4l2_format *f)
{
struct s2255_vc *vc = video_drvdata(file);
const struct s2255_fmt *fmt;
@@ -819,7 +819,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
fmt = format_by_fourcc(f->fmt.pix.pixelformat);
- if (fmt == NULL)
+ if (!fmt)
return -EINVAL;
if (vb2_is_busy(q)) {
@@ -839,8 +839,9 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
mode.scale = SCALE_4CIFSI;
else
mode.scale = SCALE_4CIFS;
- } else
+ } else {
mode.scale = SCALE_2CIFS;
+ }
} else {
mode.scale = SCALE_1CIFS;
@@ -875,11 +876,10 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
else if (mode.format != vc->mode.format)
mode.restart = 1;
vc->mode = mode;
- (void) s2255_set_mode(vc, &mode);
+ (void)s2255_set_mode(vc, &mode);
return 0;
}
-
/* write to the configuration pipe, synchronously */
static int s2255_write_config(struct usb_device *udev, unsigned char *pbuf,
int size)
@@ -887,6 +887,7 @@ static int s2255_write_config(struct usb_device *udev, unsigned char *pbuf,
int pipe;
int done;
long retval = -1;
+
if (udev) {
pipe = usb_sndbulkpipe(udev, S2255_CONFIG_EP);
retval = usb_bulk_msg(udev, pipe, pbuf, size, &done, 500);
@@ -896,29 +897,29 @@ static int s2255_write_config(struct usb_device *udev, unsigned char *pbuf,
static u32 get_transfer_size(struct s2255_mode *mode)
{
- int linesPerFrame = LINE_SZ_DEF;
- int pixelsPerLine = NUM_LINES_DEF;
- u32 outImageSize;
- u32 usbInSize;
+ int lines_per_frame = LINE_SZ_DEF;
+ int pixels_per_line = NUM_LINES_DEF;
+ u32 out_image_size;
+ u32 usb_in_size;
unsigned int mask_mult;
- if (mode == NULL)
+ if (!mode)
return 0;
if (mode->format == FORMAT_NTSC) {
switch (mode->scale) {
case SCALE_4CIFS:
case SCALE_4CIFSI:
- linesPerFrame = NUM_LINES_4CIFS_NTSC * 2;
- pixelsPerLine = LINE_SZ_4CIFS_NTSC;
+ lines_per_frame = NUM_LINES_4CIFS_NTSC * 2;
+ pixels_per_line = LINE_SZ_4CIFS_NTSC;
break;
case SCALE_2CIFS:
- linesPerFrame = NUM_LINES_2CIFS_NTSC;
- pixelsPerLine = LINE_SZ_2CIFS_NTSC;
+ lines_per_frame = NUM_LINES_2CIFS_NTSC;
+ pixels_per_line = LINE_SZ_2CIFS_NTSC;
break;
case SCALE_1CIFS:
- linesPerFrame = NUM_LINES_1CIFS_NTSC;
- pixelsPerLine = LINE_SZ_1CIFS_NTSC;
+ lines_per_frame = NUM_LINES_1CIFS_NTSC;
+ pixels_per_line = LINE_SZ_1CIFS_NTSC;
break;
default:
break;
@@ -927,40 +928,42 @@ static u32 get_transfer_size(struct s2255_mode *mode)
switch (mode->scale) {
case SCALE_4CIFS:
case SCALE_4CIFSI:
- linesPerFrame = NUM_LINES_4CIFS_PAL * 2;
- pixelsPerLine = LINE_SZ_4CIFS_PAL;
+ lines_per_frame = NUM_LINES_4CIFS_PAL * 2;
+ pixels_per_line = LINE_SZ_4CIFS_PAL;
break;
case SCALE_2CIFS:
- linesPerFrame = NUM_LINES_2CIFS_PAL;
- pixelsPerLine = LINE_SZ_2CIFS_PAL;
+ lines_per_frame = NUM_LINES_2CIFS_PAL;
+ pixels_per_line = LINE_SZ_2CIFS_PAL;
break;
case SCALE_1CIFS:
- linesPerFrame = NUM_LINES_1CIFS_PAL;
- pixelsPerLine = LINE_SZ_1CIFS_PAL;
+ lines_per_frame = NUM_LINES_1CIFS_PAL;
+ pixels_per_line = LINE_SZ_1CIFS_PAL;
break;
default:
break;
}
}
- outImageSize = linesPerFrame * pixelsPerLine;
+ out_image_size = lines_per_frame * pixels_per_line;
if ((mode->color & MASK_COLOR) != COLOR_Y8) {
/* 2 bytes/pixel if not monochrome */
- outImageSize *= 2;
+ out_image_size *= 2;
}
/* total bytes to send including prefix and 4K padding;
- must be a multiple of USB_READ_SIZE */
- usbInSize = outImageSize + PREFIX_SIZE; /* always send prefix */
+ * must be a multiple of USB_READ_SIZE
+ */
+ usb_in_size = out_image_size + PREFIX_SIZE; /* always send prefix */
mask_mult = 0xffffffffUL - DEF_USB_BLOCK + 1;
/* if size not a multiple of USB_READ_SIZE */
- if (usbInSize & ~mask_mult)
- usbInSize = (usbInSize & mask_mult) + (DEF_USB_BLOCK);
- return usbInSize;
+ if (usb_in_size & ~mask_mult)
+ usb_in_size = (usb_in_size & mask_mult) + (DEF_USB_BLOCK);
+ return usb_in_size;
}
static void s2255_print_cfg(struct s2255_dev *sdev, struct s2255_mode *mode)
{
struct device *dev = &sdev->udev->dev;
+
dev_info(dev, "------------------------------------------------\n");
dev_info(dev, "format: %d\nscale %d\n", mode->format, mode->scale);
dev_info(dev, "fdec: %d\ncolor %d\n", mode->fdec, mode->color);
@@ -1001,7 +1004,7 @@ static int s2255_set_mode(struct s2255_vc *vc,
dprintk(dev, 1, "%s: reqsize %ld\n", __func__, vc->req_image_size);
/* set the mode */
buffer[0] = IN_DATA_TOKEN;
- buffer[1] = (__le32) cpu_to_le32(chn_rev);
+ buffer[1] = (__le32)cpu_to_le32(chn_rev);
buffer[2] = CMD_SET_MODE;
for (i = 0; i < sizeof(struct s2255_mode) / sizeof(u32); i++)
buffer[3 + i] = cpu_to_le32(((u32 *)&vc->mode)[i]);
@@ -1038,7 +1041,7 @@ static int s2255_cmd_status(struct s2255_vc *vc, u32 *pstatus)
dprintk(dev, 4, "%s chan %d\n", __func__, vc->idx);
/* form the get vid status command */
buffer[0] = IN_DATA_TOKEN;
- buffer[1] = (__le32) cpu_to_le32(chn_rev);
+ buffer[1] = (__le32)cpu_to_le32(chn_rev);
buffer[2] = CMD_STATUS;
*pstatus = 0;
vc->vidstatus_ready = 0;
@@ -1066,7 +1069,7 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count)
vc->cur_frame = 0;
vc->frame_count = 0;
for (j = 0; j < SYS_FRAMES; j++) {
- vc->buffer.frame[j].ulState = S2255_READ_IDLE;
+ vc->buffer.frame[j].state = S2255_READ_IDLE;
vc->buffer.frame[j].cur_size = 0;
}
return s2255_start_acquire(vc);
@@ -1078,7 +1081,7 @@ static void stop_streaming(struct vb2_queue *vq)
struct s2255_vc *vc = vb2_get_drv_priv(vq);
struct s2255_buffer *buf, *node;
unsigned long flags;
- (void) s2255_stop_acquire(vc);
+ (void)s2255_stop_acquire(vc);
spin_lock_irqsave(&vc->qlock, flags);
list_for_each_entry_safe(buf, node, &vc->buf_list, list) {
list_del(&buf->list);
@@ -1122,8 +1125,9 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id i)
vc->width = LINE_SZ_4CIFS_PAL;
vc->height = NUM_LINES_4CIFS_PAL * 2;
}
- } else
+ } else {
return -EINVAL;
+ }
vc->std = i;
if (mode.restart)
s2255_set_mode(vc, &mode);
@@ -1139,12 +1143,12 @@ static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *i)
}
/* Sensoray 2255 is a multiple channel capture device.
- It does not have a "crossbar" of inputs.
- We use one V4L device per channel. The user must
- be aware that certain combinations are not allowed.
- For instance, you cannot do full FPS on more than 2 channels(2 videodevs)
- at once in color(you can do full fps on 4 channels with greyscale.
-*/
+ * It does not have a "crossbar" of inputs.
+ * We use one V4L device per channel. The user must
+ * be aware that certain combinations are not allowed.
+ * For instance, you cannot do full FPS on more than 2 channels(2 videodevs)
+ * at once in color(you can do full fps on 4 channels with greyscale.
+ */
static int vidioc_enum_input(struct file *file, void *priv,
struct v4l2_input *inp)
{
@@ -1159,6 +1163,7 @@ static int vidioc_enum_input(struct file *file, void *priv,
inp->status = 0;
if (dev->dsp_fw_ver >= S2255_MIN_DSP_STATUS) {
int rc;
+
rc = s2255_cmd_status(vc, &status);
dprintk(dev, 4, "s2255_cmd_status rc: %d status %x\n",
rc, status);
@@ -1184,6 +1189,7 @@ static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
*i = 0;
return 0;
}
+
static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
{
if (i > 0)
@@ -1196,6 +1202,7 @@ static int s2255_s_ctrl(struct v4l2_ctrl *ctrl)
struct s2255_vc *vc =
container_of(ctrl->handler, struct s2255_vc, hdl);
struct s2255_mode mode;
+
mode = vc->mode;
/* update the mode to the corresponding value */
switch (ctrl->id) {
@@ -1223,15 +1230,15 @@ static int s2255_s_ctrl(struct v4l2_ctrl *ctrl)
}
mode.restart = 0;
/* set mode here. Note: stream does not need restarted.
- some V4L programs restart stream unnecessarily
- after a s_crtl.
- */
+ * some V4L programs restart stream unnecessarily
+ * after a s_crtl.
+ */
s2255_set_mode(vc, &mode);
return 0;
}
static int vidioc_g_jpegcomp(struct file *file, void *priv,
- struct v4l2_jpegcompression *jc)
+ struct v4l2_jpegcompression *jc)
{
struct s2255_vc *vc = video_drvdata(file);
@@ -1242,7 +1249,7 @@ static int vidioc_g_jpegcomp(struct file *file, void *priv,
}
static int vidioc_s_jpegcomp(struct file *file, void *priv,
- const struct v4l2_jpegcompression *jc)
+ const struct v4l2_jpegcompression *jc)
{
struct s2255_vc *vc = video_drvdata(file);
@@ -1297,20 +1304,21 @@ static int vidioc_s_parm(struct file *file, void *priv,
struct s2255_mode mode;
int fdec = FDEC_1;
__u32 def_num, def_dem;
+
if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
mode = vc->mode;
/* high quality capture mode requires a stream restart */
- if ((vc->cap_parm.capturemode != sp->parm.capture.capturemode)
- && vb2_is_streaming(&vc->vb_vidq))
+ if (vc->cap_parm.capturemode != sp->parm.capture.capturemode &&
+ vb2_is_streaming(&vc->vb_vidq))
return -EBUSY;
def_num = (mode.format == FORMAT_NTSC) ? 1001 : 1000;
def_dem = (mode.format == FORMAT_NTSC) ? 30000 : 25000;
- if (def_dem != sp->parm.capture.timeperframe.denominator)
+ if (def_dem != sp->parm.capture.timeperframe.denominator) {
sp->parm.capture.timeperframe.numerator = def_num;
- else if (sp->parm.capture.timeperframe.numerator <= def_num)
+ } else if (sp->parm.capture.timeperframe.numerator <= def_num) {
sp->parm.capture.timeperframe.numerator = def_num;
- else if (sp->parm.capture.timeperframe.numerator <= (def_num * 2)) {
+ } else if (sp->parm.capture.timeperframe.numerator <= (def_num * 2)) {
sp->parm.capture.timeperframe.numerator = def_num * 2;
fdec = FDEC_2;
} else if (sp->parm.capture.timeperframe.numerator <= (def_num * 3)) {
@@ -1338,6 +1346,7 @@ static const struct v4l2_frmsize_discrete ntsc_sizes[] = {
{ 640, 240 },
{ 320, 240 },
};
+
static const struct v4l2_frmsize_discrete pal_sizes[] = {
{ 704, 576 },
{ 704, 288 },
@@ -1345,7 +1354,7 @@ static const struct v4l2_frmsize_discrete pal_sizes[] = {
};
static int vidioc_enum_framesizes(struct file *file, void *priv,
- struct v4l2_frmsizeenum *fe)
+ struct v4l2_frmsizeenum *fe)
{
struct s2255_vc *vc = video_drvdata(file);
int is_ntsc = vc->std & V4L2_STD_525_60;
@@ -1355,7 +1364,7 @@ static int vidioc_enum_framesizes(struct file *file, void *priv,
return -EINVAL;
fmt = format_by_fourcc(fe->pixel_format);
- if (fmt == NULL)
+ if (!fmt)
return -EINVAL;
fe->type = V4L2_FRMSIZE_TYPE_DISCRETE;
fe->discrete = is_ntsc ? ntsc_sizes[fe->index] : pal_sizes[fe->index];
@@ -1363,7 +1372,7 @@ static int vidioc_enum_framesizes(struct file *file, void *priv,
}
static int vidioc_enum_frameintervals(struct file *file, void *priv,
- struct v4l2_frmivalenum *fe)
+ struct v4l2_frmivalenum *fe)
{
struct s2255_vc *vc = video_drvdata(file);
const struct s2255_fmt *fmt;
@@ -1377,7 +1386,7 @@ static int vidioc_enum_frameintervals(struct file *file, void *priv,
return -EINVAL;
fmt = format_by_fourcc(fe->pixel_format);
- if (fmt == NULL)
+ if (!fmt)
return -EINVAL;
sizes = is_ntsc ? ntsc_sizes : pal_sizes;
@@ -1415,7 +1424,7 @@ static int s2255_open(struct file *file)
return -ENODEV;
case S2255_FW_FAILED:
s2255_dev_err(&dev->udev->dev,
- "firmware load failed. retrying.\n");
+ "firmware load failed. retrying.\n");
s2255_fwload_start(dev);
wait_event_timeout(dev->fw_data->wait_fw,
((atomic_read(&dev->fw_data->fw_state)
@@ -1429,7 +1438,8 @@ static int s2255_open(struct file *file)
case S2255_FW_NOTLOADED:
case S2255_FW_LOADED_DSPWAIT:
/* give S2255_LOAD_TIMEOUT time for firmware to load in case
- driver loaded and then device immediately opened */
+ * driver loaded and then device immediately opened
+ */
pr_info("%s waiting for firmware load\n", __func__);
wait_event_timeout(dev->fw_data->wait_fw,
((atomic_read(&dev->fw_data->fw_state)
@@ -1481,7 +1491,6 @@ static int s2255_open(struct file *file)
static void s2255_destroy(struct s2255_dev *dev)
{
- dprintk(dev, 1, "%s", __func__);
/* board shutdown stops the read pipe if it is running */
s2255_board_shutdown(dev);
/* make sure firmware still not trying to load */
@@ -1554,7 +1563,6 @@ static void s2255_video_device_release(struct video_device *vdev)
if (refcount_dec_and_test(&dev->num_channels))
s2255_destroy(dev);
- return;
}
static const struct video_device template = {
@@ -1598,17 +1606,17 @@ static int s2255_probe_v4l(struct s2255_dev *dev)
v4l2_ctrl_handler_init(&vc->hdl, 6);
v4l2_ctrl_new_std(&vc->hdl, &s2255_ctrl_ops,
- V4L2_CID_BRIGHTNESS, -127, 127, 1, DEF_BRIGHT);
+ V4L2_CID_BRIGHTNESS, -127, 127, 1, DEF_BRIGHT);
v4l2_ctrl_new_std(&vc->hdl, &s2255_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 255, 1, DEF_CONTRAST);
+ V4L2_CID_CONTRAST, 0, 255, 1, DEF_CONTRAST);
v4l2_ctrl_new_std(&vc->hdl, &s2255_ctrl_ops,
- V4L2_CID_SATURATION, 0, 255, 1, DEF_SATURATION);
+ V4L2_CID_SATURATION, 0, 255, 1, DEF_SATURATION);
v4l2_ctrl_new_std(&vc->hdl, &s2255_ctrl_ops,
- V4L2_CID_HUE, 0, 255, 1, DEF_HUE);
+ V4L2_CID_HUE, 0, 255, 1, DEF_HUE);
vc->jpegqual_ctrl = v4l2_ctrl_new_std(&vc->hdl,
- &s2255_ctrl_ops,
- V4L2_CID_JPEG_COMPRESSION_QUALITY,
- 0, 100, 1, S2255_DEF_JPEG_QUAL);
+ &s2255_ctrl_ops,
+ V4L2_CID_JPEG_COMPRESSION_QUALITY,
+ 0, 100, 1, S2255_DEF_JPEG_QUAL);
if (dev->dsp_fw_ver >= S2255_MIN_DSP_COLORFILTER &&
(dev->pid != 0x2257 || vc->idx <= 1))
v4l2_ctrl_new_custom(&vc->hdl, &color_filter_ctrl,
@@ -1660,7 +1668,6 @@ static int s2255_probe_v4l(struct s2255_dev *dev)
refcount_inc(&dev->num_channels);
v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n",
video_device_node_name(&vc->vdev));
-
}
pr_info("Sensoray 2255 V4L driver Revision: %s\n",
S2255_VERSION);
@@ -1697,11 +1704,12 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
struct s2255_framei *frm;
unsigned char *pdata;
struct s2255_vc *vc;
+
dprintk(dev, 100, "buffer to user\n");
vc = &dev->vc[dev->cc];
idx = vc->cur_frame;
frm = &vc->buffer.frame[idx];
- if (frm->ulState == S2255_READ_IDLE) {
+ if (frm->state == S2255_READ_IDLE) {
int jj;
unsigned int cc;
__le32 *pdword; /*data from dsp is little endian */
@@ -1790,20 +1798,19 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
/* search done. now find out if should be acquiring on this channel */
if (!vb2_is_streaming(&vc->vb_vidq)) {
/* we found a frame, but this channel is turned off */
- frm->ulState = S2255_READ_IDLE;
+ frm->state = S2255_READ_IDLE;
return -EINVAL;
}
- if (frm->ulState == S2255_READ_IDLE) {
- frm->ulState = S2255_READ_FRAME;
+ if (frm->state == S2255_READ_IDLE) {
+ frm->state = S2255_READ_FRAME;
frm->cur_size = 0;
}
/* skip the marker 512 bytes (and offset if out of sync) */
psrc = (u8 *)pipe_info->transfer_buffer + offset;
-
- if (frm->lpvbits == NULL) {
+ if (!frm->lpvbits) {
dprintk(dev, 1, "s2255 frame buffer == NULL.%p %p %d %d",
frm, dev, dev->cc, idx);
return -ENOMEM;
@@ -1828,16 +1835,15 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
vc->last_frame = vc->cur_frame;
vc->cur_frame++;
/* end of system frame ring buffer, start at zero */
- if ((vc->cur_frame == SYS_FRAMES) ||
- (vc->cur_frame == vc->buffer.dwFrames))
+ if (vc->cur_frame == SYS_FRAMES ||
+ vc->cur_frame == vc->buffer.num_frames)
vc->cur_frame = 0;
/* frame ready */
if (vb2_is_streaming(&vc->vb_vidq))
s2255_got_frame(vc, vc->jpg_size);
vc->frame_count++;
- frm->ulState = S2255_READ_IDLE;
+ frm->state = S2255_READ_IDLE;
frm->cur_size = 0;
-
}
/* done successfully */
return 0;
@@ -1847,6 +1853,7 @@ static void s2255_read_video_callback(struct s2255_dev *dev,
struct s2255_pipeinfo *pipe_info)
{
int res;
+
dprintk(dev, 50, "callback read video\n");
if (dev->cc >= MAX_CHANNELS) {
@@ -1860,36 +1867,35 @@ static void s2255_read_video_callback(struct s2255_dev *dev,
dprintk(dev, 4, "s2255: read callback failed\n");
dprintk(dev, 50, "callback read video done\n");
- return;
}
-static long s2255_vendor_req(struct s2255_dev *dev, unsigned char Request,
- u16 Index, u16 Value, void *TransferBuffer,
- s32 TransferBufferLength, int bOut)
+static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req,
+ u16 index, u16 value, void *xfer_buf,
+ s32 xfer_buf_len, int is_out)
{
int r;
unsigned char *buf;
- buf = kmalloc(TransferBufferLength, GFP_KERNEL);
+ buf = kmalloc(xfer_buf_len, GFP_KERNEL);
if (!buf)
return -ENOMEM;
- if (!bOut) {
+ if (!is_out) {
r = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
- Request,
+ req,
USB_TYPE_VENDOR | USB_RECIP_DEVICE |
USB_DIR_IN,
- Value, Index, buf,
- TransferBufferLength, USB_CTRL_SET_TIMEOUT);
+ value, index, buf,
+ xfer_buf_len, USB_CTRL_SET_TIMEOUT);
if (r >= 0)
- memcpy(TransferBuffer, buf, TransferBufferLength);
+ memcpy(xfer_buf, buf, xfer_buf_len);
} else {
- memcpy(buf, TransferBuffer, TransferBufferLength);
+ memcpy(buf, xfer_buf, xfer_buf_len);
r = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
- Request, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- Value, Index, buf,
- TransferBufferLength, USB_CTRL_SET_TIMEOUT);
+ req, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ value, index, buf,
+ xfer_buf_len, USB_CTRL_SET_TIMEOUT);
}
kfree(buf);
return r;
@@ -1904,14 +1910,14 @@ static int s2255_get_fx2fw(struct s2255_dev *dev)
{
int fw;
int ret;
- u8 transBuffer[2] = {};
+ u8 trans_buf[2] = {};
- ret = s2255_vendor_req(dev, S2255_VR_FW, 0, 0, transBuffer,
- sizeof(transBuffer), S2255_VR_IN);
+ ret = s2255_vendor_req(dev, S2255_VR_FW, 0, 0, trans_buf,
+ sizeof(trans_buf), S2255_VR_IN);
if (ret < 0)
dprintk(dev, 2, "get fw error: %x\n", ret);
- fw = transBuffer[0] + (transBuffer[1] << 8);
- dprintk(dev, 2, "Get FW %x %x\n", transBuffer[0], transBuffer[1]);
+ fw = trans_buf[0] + (trans_buf[1] << 8);
+ dprintk(dev, 2, "Get FW %x %x\n", trans_buf[0], trans_buf[1]);
return fw;
}
@@ -1923,7 +1929,8 @@ static int s2255_create_sys_buffers(struct s2255_vc *vc)
{
unsigned long i;
unsigned long reqsize;
- vc->buffer.dwFrames = SYS_FRAMES;
+
+ vc->buffer.num_frames = SYS_FRAMES;
/* always allocate maximum size(PAL) for system buffers */
reqsize = SYS_FRAMES_MAXSIZE;
@@ -1934,16 +1941,15 @@ static int s2255_create_sys_buffers(struct s2255_vc *vc)
/* allocate the frames */
vc->buffer.frame[i].lpvbits = vmalloc(reqsize);
vc->buffer.frame[i].size = reqsize;
- if (vc->buffer.frame[i].lpvbits == NULL) {
- pr_info("out of memory. using less frames\n");
- vc->buffer.dwFrames = i;
+ if (!vc->buffer.frame[i].lpvbits) {
+ vc->buffer.num_frames = i;
break;
}
}
/* make sure internal states are set */
for (i = 0; i < SYS_FRAMES; i++) {
- vc->buffer.frame[i].ulState = 0;
+ vc->buffer.frame[i].state = 0;
vc->buffer.frame[i].cur_size = 0;
}
@@ -1955,6 +1961,7 @@ static int s2255_create_sys_buffers(struct s2255_vc *vc)
static int s2255_release_sys_buffers(struct s2255_vc *vc)
{
unsigned long i;
+
for (i = 0; i < SYS_FRAMES; i++) {
vfree(vc->buffer.frame[i].lpvbits);
vc->buffer.frame[i].lpvbits = NULL;
@@ -1968,6 +1975,7 @@ static int s2255_board_init(struct s2255_dev *dev)
int fw_ver;
int j;
struct s2255_pipeinfo *pipe = &dev->pipe;
+
dprintk(dev, 4, "board init: %p", dev);
memset(pipe, 0, sizeof(*pipe));
pipe->dev = dev;
@@ -1976,10 +1984,8 @@ static int s2255_board_init(struct s2255_dev *dev)
pipe->transfer_buffer = kzalloc(pipe->max_transfer_size,
GFP_KERNEL);
- if (pipe->transfer_buffer == NULL) {
- dprintk(dev, 1, "out of memory!\n");
+ if (!pipe->transfer_buffer)
return -ENOMEM;
- }
/* query the firmware */
fw_ver = s2255_get_fx2fw(dev);
@@ -1992,6 +1998,7 @@ static int s2255_board_init(struct s2255_dev *dev)
for (j = 0; j < MAX_CHANNELS; j++) {
struct s2255_vc *vc = &dev->vc[j];
+
vc->mode = mode_def;
if (dev->pid == 0x2257 && j > 1)
vc->mode.color |= (1 << 16);
@@ -2015,6 +2022,7 @@ static int s2255_board_init(struct s2255_dev *dev)
static int s2255_board_shutdown(struct s2255_dev *dev)
{
u32 i;
+
dprintk(dev, 1, "%s: dev: %p", __func__, dev);
for (i = 0; i < MAX_CHANNELS; i++) {
@@ -2035,13 +2043,14 @@ static void read_pipe_completion(struct urb *purb)
struct s2255_dev *dev;
int status;
int pipe;
+
pipe_info = purb->context;
- if (pipe_info == NULL) {
+ if (!pipe_info) {
dev_err(&purb->dev->dev, "no context!\n");
return;
}
dev = pipe_info->dev;
- if (dev == NULL) {
+ if (!dev) {
dev_err(&purb->dev->dev, "no context!\n");
return;
}
@@ -2058,9 +2067,9 @@ static void read_pipe_completion(struct urb *purb)
return;
}
- if (status == 0)
+ if (status == 0) {
s2255_read_video_callback(dev, pipe_info);
- else {
+ } else {
pipe_info->err_count++;
dprintk(dev, 1, "%s: failed URB %d\n", __func__, status);
}
@@ -2079,7 +2088,6 @@ static void read_pipe_completion(struct urb *purb)
} else {
dprintk(dev, 2, "%s :complete state 0\n", __func__);
}
- return;
}
static int s2255_start_readpipe(struct s2255_dev *dev)
@@ -2087,6 +2095,7 @@ static int s2255_start_readpipe(struct s2255_dev *dev)
int pipe;
int retval;
struct s2255_pipeinfo *pipe_info = &dev->pipe;
+
pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
dprintk(dev, 2, "%s: IN %d\n", __func__, dev->read_endpoint);
pipe_info->state = 1;
@@ -2123,13 +2132,13 @@ static int s2255_start_acquire(struct s2255_vc *vc)
vc->bad_payload = 0;
vc->cur_frame = 0;
for (j = 0; j < SYS_FRAMES; j++) {
- vc->buffer.frame[j].ulState = 0;
+ vc->buffer.frame[j].state = 0;
vc->buffer.frame[j].cur_size = 0;
}
/* send the start command */
buffer[0] = IN_DATA_TOKEN;
- buffer[1] = (__le32) cpu_to_le32(chn_rev);
+ buffer[1] = (__le32)cpu_to_le32(chn_rev);
buffer[2] = CMD_START;
res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
if (res != 0)
@@ -2151,7 +2160,7 @@ static int s2255_stop_acquire(struct s2255_vc *vc)
chn_rev = G_chnmap[vc->idx];
/* send the stop command */
buffer[0] = IN_DATA_TOKEN;
- buffer[1] = (__le32) cpu_to_le32(chn_rev);
+ buffer[1] = (__le32)cpu_to_le32(chn_rev);
buffer[2] = CMD_STOP;
res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
@@ -2174,8 +2183,6 @@ static void s2255_stop_readpipe(struct s2255_dev *dev)
usb_free_urb(pipe->stream_urb);
pipe->stream_urb = NULL;
}
- dprintk(dev, 4, "%s", __func__);
- return;
}
static void s2255_fwload_start(struct s2255_dev *dev)
@@ -2208,30 +2215,26 @@ static int s2255_probe(struct usb_interface *interface,
/* allocate memory for our device state and initialize it to zero */
dev = kzalloc_obj(struct s2255_dev);
- if (dev == NULL) {
- s2255_dev_err(&interface->dev, "out of memory\n");
+ if (!dev)
return -ENOMEM;
- }
dev->cmdbuf = kzalloc(S2255_CMDBUF_SIZE, GFP_KERNEL);
- if (dev->cmdbuf == NULL) {
- s2255_dev_err(&interface->dev, "out of memory\n");
- goto errorFWDATA1;
- }
+ if (!dev->cmdbuf)
+ goto err_fwdata1;
refcount_set(&dev->num_channels, 0);
dev->pid = id->idProduct;
dev->fw_data = kzalloc_obj(struct s2255_fw);
if (!dev->fw_data)
- goto errorFWDATA1;
+ goto err_fwdata1;
mutex_init(&dev->lock);
mutex_init(&dev->cmdlock);
/* grab usb_device and save it */
dev->udev = usb_get_dev(interface_to_usbdev(interface));
- if (dev->udev == NULL) {
+ if (!dev->udev) {
dev_err(&interface->dev, "null usb device\n");
retval = -ENODEV;
- goto errorUDEV;
+ goto err_udev;
}
dev_dbg(&interface->dev, "dev: %p, udev %p interface %p\n",
dev, dev->udev, interface);
@@ -2243,7 +2246,7 @@ static int s2255_probe(struct usb_interface *interface,
if (usb_find_bulk_in_endpoint(iface_desc, &endpoint)) {
dev_err(&interface->dev, "Could not find bulk-in endpoint\n");
- goto errorEP;
+ goto err_ep;
}
dev->read_endpoint = endpoint->bEndpointAddress;
@@ -2252,6 +2255,7 @@ static int s2255_probe(struct usb_interface *interface,
init_waitqueue_head(&dev->fw_data->wait_fw);
for (i = 0; i < MAX_CHANNELS; i++) {
struct s2255_vc *vc = &dev->vc[i];
+
vc->idx = i;
vc->dev = dev;
init_waitqueue_head(&vc->wait_setmode);
@@ -2262,37 +2266,41 @@ static int s2255_probe(struct usb_interface *interface,
dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!dev->fw_data->fw_urb)
- goto errorFWURB;
+ goto err_fwurb;
dev->fw_data->pfw_data = kzalloc(CHUNK_SIZE, GFP_KERNEL);
- if (!dev->fw_data->pfw_data) {
- dev_err(&interface->dev, "out of memory!\n");
- goto errorFWDATA2;
- }
+ if (!dev->fw_data->pfw_data)
+ goto err_fwdata2;
/* load the first chunk */
if (request_firmware(&dev->fw_data->fw,
FIRMWARE_FILE_NAME, &dev->udev->dev)) {
dev_err(&interface->dev, "sensoray 2255 failed to get firmware\n");
- goto errorREQFW;
+ goto err_reqfw;
}
/* check the firmware is valid */
fw_size = dev->fw_data->fw->size;
- pdata = (__le32 *) &dev->fw_data->fw->data[fw_size - 8];
+ if (fw_size < 8) {
+ dev_err(&interface->dev, "Firmware invalid: too small.\n");
+ retval = -ENODEV;
+ goto err_fwmarker;
+ }
+ pdata = (__le32 *)&dev->fw_data->fw->data[fw_size - 8];
if (*pdata != S2255_FW_MARKER) {
dev_err(&interface->dev, "Firmware invalid.\n");
retval = -ENODEV;
- goto errorFWMARKER;
+ goto err_fwmarker;
} else {
/* make sure firmware is the latest */
- __le32 *pRel;
- pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4];
- pr_info("s2255 dsp fw version %x\n", le32_to_cpu(*pRel));
- dev->dsp_fw_ver = le32_to_cpu(*pRel);
+ __le32 *p_rel;
+
+ p_rel = (__le32 *)&dev->fw_data->fw->data[fw_size - 4];
+ pr_info("s2255 dsp fw version %x\n", le32_to_cpu(*p_rel));
+ dev->dsp_fw_ver = le32_to_cpu(*p_rel);
if (dev->dsp_fw_ver < S2255_CUR_DSP_FWVER)
pr_info("s2255: f2255usb.bin out of date.\n");
if (dev->pid == 0x2257 &&
- dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
+ dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
pr_warn("2257 needs firmware %d or above.\n",
S2255_MIN_DSP_COLORFILTER);
}
@@ -2300,30 +2308,30 @@ static int s2255_probe(struct usb_interface *interface,
/* load 2255 board specific */
retval = s2255_board_init(dev);
if (retval)
- goto errorBOARDINIT;
+ goto err_boardinit;
s2255_fwload_start(dev);
/* loads v4l specific */
retval = s2255_probe_v4l(dev);
if (retval)
- goto errorBOARDINIT;
+ goto err_boardinit;
dev_info(&interface->dev, "Sensoray 2255 detected\n");
return 0;
-errorBOARDINIT:
+err_boardinit:
s2255_board_shutdown(dev);
-errorFWMARKER:
+err_fwmarker:
release_firmware(dev->fw_data->fw);
-errorREQFW:
+err_reqfw:
kfree(dev->fw_data->pfw_data);
-errorFWDATA2:
+err_fwdata2:
usb_free_urb(dev->fw_data->fw_urb);
-errorFWURB:
+err_fwurb:
timer_shutdown_sync(&dev->timer);
-errorEP:
+err_ep:
usb_put_dev(dev->udev);
-errorUDEV:
+err_udev:
kfree(dev->fw_data);
mutex_destroy(&dev->lock);
-errorFWDATA1:
+err_fwdata1:
kfree(dev->cmdbuf);
kfree(dev);
pr_warn("Sensoray 2255 driver load failed: 0x%x\n", retval);
@@ -2336,6 +2344,7 @@ static void s2255_disconnect(struct usb_interface *interface)
struct s2255_dev *dev = to_s2255_dev(usb_get_intfdata(interface));
int i;
int channels = refcount_read(&dev->num_channels);
+
mutex_lock(&dev->lock);
v4l2_device_disconnect(&dev->v4l2_dev);
mutex_unlock(&dev->lock);
@@ -2355,7 +2364,6 @@ static void s2255_disconnect(struct usb_interface *interface)
}
if (refcount_dec_and_test(&dev->num_channels))
s2255_destroy(dev);
- dev_info(&interface->dev, "%s\n", __func__);
}
static struct usb_driver s2255_driver = {
diff --git a/drivers/media/usb/stk1160/stk1160-core.c b/drivers/media/usb/stk1160/stk1160-core.c
index f9462a9ca761..5058cada0d0a 100644
--- a/drivers/media/usb/stk1160/stk1160-core.c
+++ b/drivers/media/usb/stk1160/stk1160-core.c
@@ -263,7 +263,7 @@ static int stk1160_scan_usb(struct usb_interface *intf, struct usb_device *udev,
static int stk1160_probe(struct usb_interface *interface,
const struct usb_device_id *id)
{
- int rc = 0;
+ int rc;
unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */
struct usb_device *udev;
@@ -290,15 +290,13 @@ static int stk1160_probe(struct usb_interface *interface,
* Also, check if device speed is fast enough.
*/
rc = stk1160_scan_usb(interface, udev, alt_max_pkt_size);
- if (rc < 0) {
- kfree(alt_max_pkt_size);
- return rc;
- }
+ if (rc < 0)
+ goto free_array;
dev = kzalloc_obj(struct stk1160);
if (dev == NULL) {
- kfree(alt_max_pkt_size);
- return -ENOMEM;
+ rc = -ENOMEM;
+ goto free_array;
}
dev->alt_max_pkt_size = alt_max_pkt_size;
@@ -379,8 +377,9 @@ unreg_v4l2:
free_ctrl:
v4l2_ctrl_handler_free(&dev->ctrl_handler);
free_err:
- kfree(alt_max_pkt_size);
kfree(dev);
+free_array:
+ kfree(alt_max_pkt_size);
return rc;
}
diff --git a/drivers/media/usb/stk1160/stk1160-video.c b/drivers/media/usb/stk1160/stk1160-video.c
index f4baf9263286..020b75fc5b2d 100644
--- a/drivers/media/usb/stk1160/stk1160-video.c
+++ b/drivers/media/usb/stk1160/stk1160-video.c
@@ -48,6 +48,9 @@ static inline void print_err_status(struct stk1160 *dev,
case -EILSEQ:
errmsg = "CRC/Timeout (could be anything)";
break;
+ case -ESHUTDOWN:
+ errmsg = "host controller removed";
+ break;
case -ETIME:
errmsg = "Device does not respond";
break;
diff --git a/drivers/media/usb/usbtv/usbtv-audio.c b/drivers/media/usb/usbtv/usbtv-audio.c
index 333bd305a4f9..ae0a14e5ed2a 100644
--- a/drivers/media/usb/usbtv/usbtv-audio.c
+++ b/drivers/media/usb/usbtv/usbtv-audio.c
@@ -317,6 +317,13 @@ static const struct snd_pcm_ops snd_usbtv_pcm_ops = {
.pointer = snd_usbtv_pointer,
};
+static void usbtv_audio_card_free(struct snd_card *card)
+{
+ struct usbtv *usbtv = card->private_data;
+
+ v4l2_device_put(&usbtv->v4l2_dev);
+}
+
int usbtv_audio_init(struct usbtv *usbtv)
{
int rv;
@@ -331,6 +338,10 @@ int usbtv_audio_init(struct usbtv *usbtv)
if (rv < 0)
return rv;
+ v4l2_device_get(&usbtv->v4l2_dev);
+ card->private_data = usbtv;
+ card->private_free = usbtv_audio_card_free;
+
strscpy(card->driver, usbtv->dev->driver->name, sizeof(card->driver));
strscpy(card->shortname, "usbtv", sizeof(card->shortname));
snprintf(card->longname, sizeof(card->longname),
diff --git a/drivers/media/usb/usbtv/usbtv-core.c b/drivers/media/usb/usbtv/usbtv-core.c
index 6c4facf4f41a..4f10f6613bc4 100644
--- a/drivers/media/usb/usbtv/usbtv-core.c
+++ b/drivers/media/usb/usbtv/usbtv-core.c
@@ -119,7 +119,10 @@ usbtv_audio_fail:
usbtv_video_fail:
usb_set_intfdata(intf, NULL);
- kfree(usbtv);
+ if (usbtv->v4l2_dev.dev)
+ v4l2_device_put(&usbtv->v4l2_dev);
+ else
+ kfree(usbtv);
return ret;
}
diff --git a/drivers/media/usb/usbtv/usbtv-video.c b/drivers/media/usb/usbtv/usbtv-video.c
index de0328100a60..92bc7a2509c3 100644
--- a/drivers/media/usb/usbtv/usbtv-video.c
+++ b/drivers/media/usb/usbtv/usbtv-video.c
@@ -949,13 +949,11 @@ int usbtv_video_init(struct usbtv *usbtv)
ret = video_register_device(&usbtv->vdev, VFL_TYPE_VIDEO, -1);
if (ret < 0) {
dev_warn(usbtv->dev, "Could not register video device\n");
- goto vdev_fail;
+ return ret;
}
return 0;
-vdev_fail:
- v4l2_device_unregister(&usbtv->v4l2_dev);
v4l2_fail:
ctrl_fail:
v4l2_ctrl_handler_free(&usbtv->ctrl);