diff options
-rw-r--r-- | Documentation/video4linux/v4l2-framework.txt | 27 | ||||
-rw-r--r-- | drivers/media/video/v4l2-dev.c | 14 | ||||
-rw-r--r-- | drivers/media/video/v4l2-ioctl.c | 189 | ||||
-rw-r--r-- | include/media/v4l2-dev.h | 11 |
4 files changed, 148 insertions, 93 deletions
diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt index fe53177f0d3c..e1e6a01d7ac6 100644 --- a/Documentation/video4linux/v4l2-framework.txt +++ b/Documentation/video4linux/v4l2-framework.txt | |||
@@ -580,19 +580,25 @@ allocated memory. | |||
580 | You should also set these fields: | 580 | You should also set these fields: |
581 | 581 | ||
582 | - v4l2_dev: set to the v4l2_device parent device. | 582 | - v4l2_dev: set to the v4l2_device parent device. |
583 | |||
583 | - name: set to something descriptive and unique. | 584 | - name: set to something descriptive and unique. |
585 | |||
584 | - fops: set to the v4l2_file_operations struct. | 586 | - fops: set to the v4l2_file_operations struct. |
587 | |||
585 | - ioctl_ops: if you use the v4l2_ioctl_ops to simplify ioctl maintenance | 588 | - ioctl_ops: if you use the v4l2_ioctl_ops to simplify ioctl maintenance |
586 | (highly recommended to use this and it might become compulsory in the | 589 | (highly recommended to use this and it might become compulsory in the |
587 | future!), then set this to your v4l2_ioctl_ops struct. | 590 | future!), then set this to your v4l2_ioctl_ops struct. |
591 | |||
588 | - lock: leave to NULL if you want to do all the locking in the driver. | 592 | - lock: leave to NULL if you want to do all the locking in the driver. |
589 | Otherwise you give it a pointer to a struct mutex_lock and before any | 593 | Otherwise you give it a pointer to a struct mutex_lock and before any |
590 | of the v4l2_file_operations is called this lock will be taken by the | 594 | of the v4l2_file_operations is called this lock will be taken by the |
591 | core and released afterwards. | 595 | core and released afterwards. See the next section for more details. |
596 | |||
592 | - prio: keeps track of the priorities. Used to implement VIDIOC_G/S_PRIORITY. | 597 | - prio: keeps track of the priorities. Used to implement VIDIOC_G/S_PRIORITY. |
593 | If left to NULL, then it will use the struct v4l2_prio_state in v4l2_device. | 598 | If left to NULL, then it will use the struct v4l2_prio_state in v4l2_device. |
594 | If you want to have a separate priority state per (group of) device node(s), | 599 | If you want to have a separate priority state per (group of) device node(s), |
595 | then you can point it to your own struct v4l2_prio_state. | 600 | then you can point it to your own struct v4l2_prio_state. |
601 | |||
596 | - parent: you only set this if v4l2_device was registered with NULL as | 602 | - parent: you only set this if v4l2_device was registered with NULL as |
597 | the parent device struct. This only happens in cases where one hardware | 603 | the parent device struct. This only happens in cases where one hardware |
598 | device has multiple PCI devices that all share the same v4l2_device core. | 604 | device has multiple PCI devices that all share the same v4l2_device core. |
@@ -602,6 +608,7 @@ You should also set these fields: | |||
602 | (cx8802). Since the v4l2_device cannot be associated with a particular | 608 | (cx8802). Since the v4l2_device cannot be associated with a particular |
603 | PCI device it is setup without a parent device. But when the struct | 609 | PCI device it is setup without a parent device. But when the struct |
604 | video_device is setup you do know which parent PCI device to use. | 610 | video_device is setup you do know which parent PCI device to use. |
611 | |||
605 | - flags: optional. Set to V4L2_FL_USE_FH_PRIO if you want to let the framework | 612 | - flags: optional. Set to V4L2_FL_USE_FH_PRIO if you want to let the framework |
606 | handle the VIDIOC_G/S_PRIORITY ioctls. This requires that you use struct | 613 | handle the VIDIOC_G/S_PRIORITY ioctls. This requires that you use struct |
607 | v4l2_fh. Eventually this flag will disappear once all drivers use the core | 614 | v4l2_fh. Eventually this flag will disappear once all drivers use the core |
@@ -634,8 +641,22 @@ v4l2_file_operations and locking | |||
634 | -------------------------------- | 641 | -------------------------------- |
635 | 642 | ||
636 | You can set a pointer to a mutex_lock in struct video_device. Usually this | 643 | You can set a pointer to a mutex_lock in struct video_device. Usually this |
637 | will be either a top-level mutex or a mutex per device node. If you want | 644 | will be either a top-level mutex or a mutex per device node. By default this |
638 | finer-grained locking then you have to set it to NULL and do you own locking. | 645 | lock will be used for each file operation and ioctl, but you can disable |
646 | locking for selected ioctls by calling: | ||
647 | |||
648 | void v4l2_dont_use_lock(struct video_device *vdev, unsigned int cmd); | ||
649 | |||
650 | E.g.: v4l2_dont_use_lock(vdev, VIDIOC_DQBUF); | ||
651 | |||
652 | You have to call this before you register the video_device. | ||
653 | |||
654 | Particularly with USB drivers where certain commands such as setting controls | ||
655 | can take a long time you may want to do your own locking for the buffer queuing | ||
656 | ioctls. | ||
657 | |||
658 | If you want still finer-grained locking then you have to set mutex_lock to NULL | ||
659 | and do you own locking completely. | ||
639 | 660 | ||
640 | It is up to the driver developer to decide which method to use. However, if | 661 | It is up to the driver developer to decide which method to use. However, if |
641 | your driver has high-latency operations (for example, changing the exposure | 662 | your driver has high-latency operations (for example, changing the exposure |
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 70bec548d904..e4a9ed67bb2e 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c | |||
@@ -322,11 +322,19 @@ static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
322 | int ret = -ENODEV; | 322 | int ret = -ENODEV; |
323 | 323 | ||
324 | if (vdev->fops->unlocked_ioctl) { | 324 | if (vdev->fops->unlocked_ioctl) { |
325 | if (vdev->lock && mutex_lock_interruptible(vdev->lock)) | 325 | bool locked = false; |
326 | return -ERESTARTSYS; | 326 | |
327 | if (vdev->lock) { | ||
328 | /* always lock unless the cmd is marked as "don't use lock" */ | ||
329 | locked = !v4l2_is_known_ioctl(cmd) || | ||
330 | !test_bit(_IOC_NR(cmd), vdev->dont_use_lock); | ||
331 | |||
332 | if (locked && mutex_lock_interruptible(vdev->lock)) | ||
333 | return -ERESTARTSYS; | ||
334 | } | ||
327 | if (video_is_registered(vdev)) | 335 | if (video_is_registered(vdev)) |
328 | ret = vdev->fops->unlocked_ioctl(filp, cmd, arg); | 336 | ret = vdev->fops->unlocked_ioctl(filp, cmd, arg); |
329 | if (vdev->lock) | 337 | if (locked) |
330 | mutex_unlock(vdev->lock); | 338 | mutex_unlock(vdev->lock); |
331 | } else if (vdev->fops->ioctl) { | 339 | } else if (vdev->fops->ioctl) { |
332 | /* This code path is a replacement for the BKL. It is a major | 340 | /* This code path is a replacement for the BKL. It is a major |
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index 5b2ec1fd2d0a..ef44b084132a 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c | |||
@@ -195,93 +195,106 @@ static const char *v4l2_memory_names[] = { | |||
195 | 195 | ||
196 | /* ------------------------------------------------------------------ */ | 196 | /* ------------------------------------------------------------------ */ |
197 | /* debug help functions */ | 197 | /* debug help functions */ |
198 | static const char *v4l2_ioctls[] = { | 198 | |
199 | [_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP", | 199 | struct v4l2_ioctl_info { |
200 | [_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED", | 200 | unsigned int ioctl; |
201 | [_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT", | 201 | const char * const name; |
202 | [_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT", | 202 | }; |
203 | [_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT", | 203 | |
204 | [_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS", | 204 | #define IOCTL_INFO(_ioctl) [_IOC_NR(_ioctl)] = { \ |
205 | [_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF", | 205 | .ioctl = _ioctl, \ |
206 | [_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF", | 206 | .name = #_ioctl, \ |
207 | [_IOC_NR(VIDIOC_S_FBUF)] = "VIDIOC_S_FBUF", | 207 | } |
208 | [_IOC_NR(VIDIOC_OVERLAY)] = "VIDIOC_OVERLAY", | 208 | |
209 | [_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF", | 209 | static struct v4l2_ioctl_info v4l2_ioctls[] = { |
210 | [_IOC_NR(VIDIOC_DQBUF)] = "VIDIOC_DQBUF", | 210 | IOCTL_INFO(VIDIOC_QUERYCAP), |
211 | [_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON", | 211 | IOCTL_INFO(VIDIOC_ENUM_FMT), |
212 | [_IOC_NR(VIDIOC_STREAMOFF)] = "VIDIOC_STREAMOFF", | 212 | IOCTL_INFO(VIDIOC_G_FMT), |
213 | [_IOC_NR(VIDIOC_G_PARM)] = "VIDIOC_G_PARM", | 213 | IOCTL_INFO(VIDIOC_S_FMT), |
214 | [_IOC_NR(VIDIOC_S_PARM)] = "VIDIOC_S_PARM", | 214 | IOCTL_INFO(VIDIOC_REQBUFS), |
215 | [_IOC_NR(VIDIOC_G_STD)] = "VIDIOC_G_STD", | 215 | IOCTL_INFO(VIDIOC_QUERYBUF), |
216 | [_IOC_NR(VIDIOC_S_STD)] = "VIDIOC_S_STD", | 216 | IOCTL_INFO(VIDIOC_G_FBUF), |
217 | [_IOC_NR(VIDIOC_ENUMSTD)] = "VIDIOC_ENUMSTD", | 217 | IOCTL_INFO(VIDIOC_S_FBUF), |
218 | [_IOC_NR(VIDIOC_ENUMINPUT)] = "VIDIOC_ENUMINPUT", | 218 | IOCTL_INFO(VIDIOC_OVERLAY), |
219 | [_IOC_NR(VIDIOC_G_CTRL)] = "VIDIOC_G_CTRL", | 219 | IOCTL_INFO(VIDIOC_QBUF), |
220 | [_IOC_NR(VIDIOC_S_CTRL)] = "VIDIOC_S_CTRL", | 220 | IOCTL_INFO(VIDIOC_DQBUF), |
221 | [_IOC_NR(VIDIOC_G_TUNER)] = "VIDIOC_G_TUNER", | 221 | IOCTL_INFO(VIDIOC_STREAMON), |
222 | [_IOC_NR(VIDIOC_S_TUNER)] = "VIDIOC_S_TUNER", | 222 | IOCTL_INFO(VIDIOC_STREAMOFF), |
223 | [_IOC_NR(VIDIOC_G_AUDIO)] = "VIDIOC_G_AUDIO", | 223 | IOCTL_INFO(VIDIOC_G_PARM), |
224 | [_IOC_NR(VIDIOC_S_AUDIO)] = "VIDIOC_S_AUDIO", | 224 | IOCTL_INFO(VIDIOC_S_PARM), |
225 | [_IOC_NR(VIDIOC_QUERYCTRL)] = "VIDIOC_QUERYCTRL", | 225 | IOCTL_INFO(VIDIOC_G_STD), |
226 | [_IOC_NR(VIDIOC_QUERYMENU)] = "VIDIOC_QUERYMENU", | 226 | IOCTL_INFO(VIDIOC_S_STD), |
227 | [_IOC_NR(VIDIOC_G_INPUT)] = "VIDIOC_G_INPUT", | 227 | IOCTL_INFO(VIDIOC_ENUMSTD), |
228 | [_IOC_NR(VIDIOC_S_INPUT)] = "VIDIOC_S_INPUT", | 228 | IOCTL_INFO(VIDIOC_ENUMINPUT), |
229 | [_IOC_NR(VIDIOC_G_OUTPUT)] = "VIDIOC_G_OUTPUT", | 229 | IOCTL_INFO(VIDIOC_G_CTRL), |
230 | [_IOC_NR(VIDIOC_S_OUTPUT)] = "VIDIOC_S_OUTPUT", | 230 | IOCTL_INFO(VIDIOC_S_CTRL), |
231 | [_IOC_NR(VIDIOC_ENUMOUTPUT)] = "VIDIOC_ENUMOUTPUT", | 231 | IOCTL_INFO(VIDIOC_G_TUNER), |
232 | [_IOC_NR(VIDIOC_G_AUDOUT)] = "VIDIOC_G_AUDOUT", | 232 | IOCTL_INFO(VIDIOC_S_TUNER), |
233 | [_IOC_NR(VIDIOC_S_AUDOUT)] = "VIDIOC_S_AUDOUT", | 233 | IOCTL_INFO(VIDIOC_G_AUDIO), |
234 | [_IOC_NR(VIDIOC_G_MODULATOR)] = "VIDIOC_G_MODULATOR", | 234 | IOCTL_INFO(VIDIOC_S_AUDIO), |
235 | [_IOC_NR(VIDIOC_S_MODULATOR)] = "VIDIOC_S_MODULATOR", | 235 | IOCTL_INFO(VIDIOC_QUERYCTRL), |
236 | [_IOC_NR(VIDIOC_G_FREQUENCY)] = "VIDIOC_G_FREQUENCY", | 236 | IOCTL_INFO(VIDIOC_QUERYMENU), |
237 | [_IOC_NR(VIDIOC_S_FREQUENCY)] = "VIDIOC_S_FREQUENCY", | 237 | IOCTL_INFO(VIDIOC_G_INPUT), |
238 | [_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP", | 238 | IOCTL_INFO(VIDIOC_S_INPUT), |
239 | [_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP", | 239 | IOCTL_INFO(VIDIOC_G_OUTPUT), |
240 | [_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP", | 240 | IOCTL_INFO(VIDIOC_S_OUTPUT), |
241 | [_IOC_NR(VIDIOC_G_SELECTION)] = "VIDIOC_G_SELECTION", | 241 | IOCTL_INFO(VIDIOC_ENUMOUTPUT), |
242 | [_IOC_NR(VIDIOC_S_SELECTION)] = "VIDIOC_S_SELECTION", | 242 | IOCTL_INFO(VIDIOC_G_AUDOUT), |
243 | [_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP", | 243 | IOCTL_INFO(VIDIOC_S_AUDOUT), |
244 | [_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP", | 244 | IOCTL_INFO(VIDIOC_G_MODULATOR), |
245 | [_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD", | 245 | IOCTL_INFO(VIDIOC_S_MODULATOR), |
246 | [_IOC_NR(VIDIOC_TRY_FMT)] = "VIDIOC_TRY_FMT", | 246 | IOCTL_INFO(VIDIOC_G_FREQUENCY), |
247 | [_IOC_NR(VIDIOC_ENUMAUDIO)] = "VIDIOC_ENUMAUDIO", | 247 | IOCTL_INFO(VIDIOC_S_FREQUENCY), |
248 | [_IOC_NR(VIDIOC_ENUMAUDOUT)] = "VIDIOC_ENUMAUDOUT", | 248 | IOCTL_INFO(VIDIOC_CROPCAP), |
249 | [_IOC_NR(VIDIOC_G_PRIORITY)] = "VIDIOC_G_PRIORITY", | 249 | IOCTL_INFO(VIDIOC_G_CROP), |
250 | [_IOC_NR(VIDIOC_S_PRIORITY)] = "VIDIOC_S_PRIORITY", | 250 | IOCTL_INFO(VIDIOC_S_CROP), |
251 | [_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP", | 251 | IOCTL_INFO(VIDIOC_G_SELECTION), |
252 | [_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS", | 252 | IOCTL_INFO(VIDIOC_S_SELECTION), |
253 | [_IOC_NR(VIDIOC_G_EXT_CTRLS)] = "VIDIOC_G_EXT_CTRLS", | 253 | IOCTL_INFO(VIDIOC_G_JPEGCOMP), |
254 | [_IOC_NR(VIDIOC_S_EXT_CTRLS)] = "VIDIOC_S_EXT_CTRLS", | 254 | IOCTL_INFO(VIDIOC_S_JPEGCOMP), |
255 | [_IOC_NR(VIDIOC_TRY_EXT_CTRLS)] = "VIDIOC_TRY_EXT_CTRLS", | 255 | IOCTL_INFO(VIDIOC_QUERYSTD), |
256 | #if 1 | 256 | IOCTL_INFO(VIDIOC_TRY_FMT), |
257 | [_IOC_NR(VIDIOC_ENUM_FRAMESIZES)] = "VIDIOC_ENUM_FRAMESIZES", | 257 | IOCTL_INFO(VIDIOC_ENUMAUDIO), |
258 | [_IOC_NR(VIDIOC_ENUM_FRAMEINTERVALS)] = "VIDIOC_ENUM_FRAMEINTERVALS", | 258 | IOCTL_INFO(VIDIOC_ENUMAUDOUT), |
259 | [_IOC_NR(VIDIOC_G_ENC_INDEX)] = "VIDIOC_G_ENC_INDEX", | 259 | IOCTL_INFO(VIDIOC_G_PRIORITY), |
260 | [_IOC_NR(VIDIOC_ENCODER_CMD)] = "VIDIOC_ENCODER_CMD", | 260 | IOCTL_INFO(VIDIOC_S_PRIORITY), |
261 | [_IOC_NR(VIDIOC_TRY_ENCODER_CMD)] = "VIDIOC_TRY_ENCODER_CMD", | 261 | IOCTL_INFO(VIDIOC_G_SLICED_VBI_CAP), |
262 | 262 | IOCTL_INFO(VIDIOC_LOG_STATUS), | |
263 | [_IOC_NR(VIDIOC_DECODER_CMD)] = "VIDIOC_DECODER_CMD", | 263 | IOCTL_INFO(VIDIOC_G_EXT_CTRLS), |
264 | [_IOC_NR(VIDIOC_TRY_DECODER_CMD)] = "VIDIOC_TRY_DECODER_CMD", | 264 | IOCTL_INFO(VIDIOC_S_EXT_CTRLS), |
265 | [_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER", | 265 | IOCTL_INFO(VIDIOC_TRY_EXT_CTRLS), |
266 | [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER", | 266 | IOCTL_INFO(VIDIOC_ENUM_FRAMESIZES), |
267 | 267 | IOCTL_INFO(VIDIOC_ENUM_FRAMEINTERVALS), | |
268 | [_IOC_NR(VIDIOC_DBG_G_CHIP_IDENT)] = "VIDIOC_DBG_G_CHIP_IDENT", | 268 | IOCTL_INFO(VIDIOC_G_ENC_INDEX), |
269 | [_IOC_NR(VIDIOC_S_HW_FREQ_SEEK)] = "VIDIOC_S_HW_FREQ_SEEK", | 269 | IOCTL_INFO(VIDIOC_ENCODER_CMD), |
270 | #endif | 270 | IOCTL_INFO(VIDIOC_TRY_ENCODER_CMD), |
271 | [_IOC_NR(VIDIOC_ENUM_DV_PRESETS)] = "VIDIOC_ENUM_DV_PRESETS", | 271 | IOCTL_INFO(VIDIOC_DECODER_CMD), |
272 | [_IOC_NR(VIDIOC_S_DV_PRESET)] = "VIDIOC_S_DV_PRESET", | 272 | IOCTL_INFO(VIDIOC_TRY_DECODER_CMD), |
273 | [_IOC_NR(VIDIOC_G_DV_PRESET)] = "VIDIOC_G_DV_PRESET", | 273 | IOCTL_INFO(VIDIOC_DBG_S_REGISTER), |
274 | [_IOC_NR(VIDIOC_QUERY_DV_PRESET)] = "VIDIOC_QUERY_DV_PRESET", | 274 | IOCTL_INFO(VIDIOC_DBG_G_REGISTER), |
275 | [_IOC_NR(VIDIOC_S_DV_TIMINGS)] = "VIDIOC_S_DV_TIMINGS", | 275 | IOCTL_INFO(VIDIOC_DBG_G_CHIP_IDENT), |
276 | [_IOC_NR(VIDIOC_G_DV_TIMINGS)] = "VIDIOC_G_DV_TIMINGS", | 276 | IOCTL_INFO(VIDIOC_S_HW_FREQ_SEEK), |
277 | [_IOC_NR(VIDIOC_DQEVENT)] = "VIDIOC_DQEVENT", | 277 | IOCTL_INFO(VIDIOC_ENUM_DV_PRESETS), |
278 | [_IOC_NR(VIDIOC_SUBSCRIBE_EVENT)] = "VIDIOC_SUBSCRIBE_EVENT", | 278 | IOCTL_INFO(VIDIOC_S_DV_PRESET), |
279 | [_IOC_NR(VIDIOC_UNSUBSCRIBE_EVENT)] = "VIDIOC_UNSUBSCRIBE_EVENT", | 279 | IOCTL_INFO(VIDIOC_G_DV_PRESET), |
280 | [_IOC_NR(VIDIOC_CREATE_BUFS)] = "VIDIOC_CREATE_BUFS", | 280 | IOCTL_INFO(VIDIOC_QUERY_DV_PRESET), |
281 | [_IOC_NR(VIDIOC_PREPARE_BUF)] = "VIDIOC_PREPARE_BUF", | 281 | IOCTL_INFO(VIDIOC_S_DV_TIMINGS), |
282 | IOCTL_INFO(VIDIOC_G_DV_TIMINGS), | ||
283 | IOCTL_INFO(VIDIOC_DQEVENT), | ||
284 | IOCTL_INFO(VIDIOC_SUBSCRIBE_EVENT), | ||
285 | IOCTL_INFO(VIDIOC_UNSUBSCRIBE_EVENT), | ||
286 | IOCTL_INFO(VIDIOC_CREATE_BUFS), | ||
287 | IOCTL_INFO(VIDIOC_PREPARE_BUF), | ||
282 | }; | 288 | }; |
283 | #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) | 289 | #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) |
284 | 290 | ||
291 | bool v4l2_is_known_ioctl(unsigned int cmd) | ||
292 | { | ||
293 | if (_IOC_NR(cmd) >= V4L2_IOCTLS) | ||
294 | return false; | ||
295 | return v4l2_ioctls[_IOC_NR(cmd)].ioctl == cmd; | ||
296 | } | ||
297 | |||
285 | /* Common ioctl debug function. This function can be used by | 298 | /* Common ioctl debug function. This function can be used by |
286 | external ioctl messages as well as internal V4L ioctl */ | 299 | external ioctl messages as well as internal V4L ioctl */ |
287 | void v4l_printk_ioctl(unsigned int cmd) | 300 | void v4l_printk_ioctl(unsigned int cmd) |
@@ -297,7 +310,7 @@ void v4l_printk_ioctl(unsigned int cmd) | |||
297 | type = "v4l2"; | 310 | type = "v4l2"; |
298 | break; | 311 | break; |
299 | } | 312 | } |
300 | printk("%s", v4l2_ioctls[_IOC_NR(cmd)]); | 313 | printk("%s", v4l2_ioctls[_IOC_NR(cmd)].name); |
301 | return; | 314 | return; |
302 | default: | 315 | default: |
303 | type = "unknown"; | 316 | type = "unknown"; |
@@ -1948,9 +1961,9 @@ static long __video_do_ioctl(struct file *file, | |||
1948 | vfd->v4l2_dev->name); | 1961 | vfd->v4l2_dev->name); |
1949 | break; | 1962 | break; |
1950 | } | 1963 | } |
1951 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
1952 | case VIDIOC_DBG_G_REGISTER: | 1964 | case VIDIOC_DBG_G_REGISTER: |
1953 | { | 1965 | { |
1966 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
1954 | struct v4l2_dbg_register *p = arg; | 1967 | struct v4l2_dbg_register *p = arg; |
1955 | 1968 | ||
1956 | if (ops->vidioc_g_register) { | 1969 | if (ops->vidioc_g_register) { |
@@ -1959,10 +1972,12 @@ static long __video_do_ioctl(struct file *file, | |||
1959 | else | 1972 | else |
1960 | ret = ops->vidioc_g_register(file, fh, p); | 1973 | ret = ops->vidioc_g_register(file, fh, p); |
1961 | } | 1974 | } |
1975 | #endif | ||
1962 | break; | 1976 | break; |
1963 | } | 1977 | } |
1964 | case VIDIOC_DBG_S_REGISTER: | 1978 | case VIDIOC_DBG_S_REGISTER: |
1965 | { | 1979 | { |
1980 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
1966 | struct v4l2_dbg_register *p = arg; | 1981 | struct v4l2_dbg_register *p = arg; |
1967 | 1982 | ||
1968 | if (ops->vidioc_s_register) { | 1983 | if (ops->vidioc_s_register) { |
@@ -1971,9 +1986,9 @@ static long __video_do_ioctl(struct file *file, | |||
1971 | else | 1986 | else |
1972 | ret = ops->vidioc_s_register(file, fh, p); | 1987 | ret = ops->vidioc_s_register(file, fh, p); |
1973 | } | 1988 | } |
1989 | #endif | ||
1974 | break; | 1990 | break; |
1975 | } | 1991 | } |
1976 | #endif | ||
1977 | case VIDIOC_DBG_G_CHIP_IDENT: | 1992 | case VIDIOC_DBG_G_CHIP_IDENT: |
1978 | { | 1993 | { |
1979 | struct v4l2_dbg_chip_ident *p = arg; | 1994 | struct v4l2_dbg_chip_ident *p = arg; |
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index 96d22215cc88..d00b9d3511f2 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h | |||
@@ -128,6 +128,7 @@ struct video_device | |||
128 | const struct v4l2_ioctl_ops *ioctl_ops; | 128 | const struct v4l2_ioctl_ops *ioctl_ops; |
129 | 129 | ||
130 | /* serialization lock */ | 130 | /* serialization lock */ |
131 | DECLARE_BITMAP(dont_use_lock, BASE_VIDIOC_PRIVATE); | ||
131 | struct mutex *lock; | 132 | struct mutex *lock; |
132 | }; | 133 | }; |
133 | 134 | ||
@@ -173,6 +174,16 @@ void video_device_release(struct video_device *vdev); | |||
173 | a dubious construction at best. */ | 174 | a dubious construction at best. */ |
174 | void video_device_release_empty(struct video_device *vdev); | 175 | void video_device_release_empty(struct video_device *vdev); |
175 | 176 | ||
177 | /* returns true if cmd is a known V4L2 ioctl */ | ||
178 | bool v4l2_is_known_ioctl(unsigned int cmd); | ||
179 | |||
180 | /* mark that this command shouldn't use core locking */ | ||
181 | static inline void v4l2_dont_use_lock(struct video_device *vdev, unsigned int cmd) | ||
182 | { | ||
183 | if (_IOC_NR(cmd) < BASE_VIDIOC_PRIVATE) | ||
184 | set_bit(_IOC_NR(cmd), vdev->dont_use_lock); | ||
185 | } | ||
186 | |||
176 | /* helper functions to access driver private data. */ | 187 | /* helper functions to access driver private data. */ |
177 | static inline void *video_get_drvdata(struct video_device *vdev) | 188 | static inline void *video_get_drvdata(struct video_device *vdev) |
178 | { | 189 | { |