Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

staging/easycap: Improve interface to the videodev module

The changes here represent an intermediate step towards bringing the
driver within the V4L2 framework.

Signed-off-by: Mike Thomas <rmthomas@sciolus.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

Mike Thomas and committed by
Greg Kroah-Hartman
268dfede ae59dad4

+290 -75
+67 -32
drivers/staging/easycap/README
··· 24 24 BUILD OPTIONS AND DEPENDENCIES 25 25 ------------------------------ 26 26 27 + Unless EASYCAP_DEBUG is defined during compilation it will not be possible 28 + to select a debug level at the time of module installation. 29 + 27 30 If the parameter EASYCAP_IS_VIDEODEV_CLIENT is undefined during compilation 28 31 the built module is entirely independent of the videodev module, and when 29 32 the EasyCAP is physically plugged into a USB port the special files ··· 36 33 If the parameter EASYCAP_IS_VIDEODEV_CLIENT is defined during compilation 37 34 the built easycap module is configured to register with the videodev module, 38 35 in which case the special files created when the EasyCAP is plugged in are 39 - /dev/video0 and /dev/easysnd0. Use of the easycap module as a client of 40 - the videodev module has received very little testing as of June 2010. 36 + /dev/video0 and /dev/easysnd0. 41 37 38 + During in-tree builds the following should should be defined whenever the 39 + parameter EASYCAP_IS_VIDEODEV_CLIENT is defined: 42 40 43 - KNOWN BUILD PROBLEMS 44 - -------------------- 41 + EASYCAP_NEEDS_V4L2_DEVICE_H 42 + EASYCAP_NEEDS_V4L2_FOPS 43 + EASYCAP_NEEDS_UNLOCKED_IOCTL 45 44 46 - (1) Recent gcc versions may generate the message: 47 - 48 - warning: the frame size of .... bytes is larger than 1024 bytes 49 - 50 - This warning can be suppressed by specifying in the Makefile: 51 - 52 - EXTRA_CFLAGS += -Wframe-larger-than=8192 53 - 54 - but it would be preferable to remove the cause of the warning. 45 + If the build is performed out-of-tree against older kernels the parameters 46 + to be defined depend on the kernel version in a way which will not be 47 + discussed here. 55 48 56 49 57 50 KNOWN RUNTIME ISSUES 58 51 -------------------- 59 52 60 - (1) Randomly (maybe 5 to 10% of occasions) the driver fails to produce any 61 - output at start-up. Closing mplayer (or whatever the user program is) and 62 - restarting it restores normal performance without any other remedial action 63 - being necessary. The reason for this is not known. 53 + (1) Intentionally, this driver will not stream material which is unambiguously 54 + identified by the hardware as copy-protected. Normal video output will be 55 + present for about a minute but will then freeze when this situation arises. 64 56 65 - (2) Intentionally, this driver will not stream material which is unambiguously 66 - identified by the hardware as copy-protected. The video output will freeze 67 - within about a minute when this situation arises. 68 - 69 - (3) The controls for luminance, contrast, saturation, hue and volume may not 57 + (2) The controls for luminance, contrast, saturation, hue and volume may not 70 58 always work properly. 71 59 72 - (4) Reduced-resolution S-Video seems to suffer from moire artefacts. No 73 - attempt has yet been made to rememdy this. 60 + (3) Reduced-resolution S-Video seems to suffer from moire artefacts. 61 + 62 + 63 + INPUT NUMBERING 64 + --------------- 65 + 66 + For the EasyCAP with S-VIDEO input cable the driver regards a request for 67 + inputs numbered 0 or 1 as referring to CVBS and a request for input 68 + numbered 5 as referring to S-VIDEO. 69 + 70 + For the EasyCAP with four CVBS inputs the driver expects to be asked for 71 + any one of inputs numbered 1,2,3,4. If input 0 is asked for, it is 72 + interpreted as input 1. 73 + 74 + 75 + MODULE PARAMETERS 76 + ----------------- 77 + 78 + Three module parameters are defined: 79 + 80 + debug the easycap module is configured at diagnostic level n (0 to 9) 81 + gain audio gain level n (0 to 31, default is 16) 82 + bars 0 => testcard bars when incoming video signal is lost 83 + 1 => testcard bars when incoming video signal is lost (default) 74 84 75 85 76 86 SUPPORTED TV STANDARDS AND RESOLUTIONS ··· 98 82 PAL_60, NTSC_443, 99 83 PAL_M. 100 84 85 + In addition, the driver offers "custom" pseudo-standards with a framerate 86 + which is 20% of the usual framerate. These pseudo-standards are named: 87 + 88 + PAL_BGHIN_SLOW, NTSC_N_443_SLOW, 89 + PAL_Nc_SLOW, NTSC_N_SLOW, 90 + SECAM_SLOW, NTSC_M_SLOW, NTSC_M_JP_SLOW, 91 + PAL_60_SLOW, NTSC_443_SLOW, 92 + PAL_M_SLOW. 93 + 94 + 101 95 The available picture sizes are: 102 96 103 97 at 25 frames per second: 720x576, 704x576, 640x480, 360x288, 320x240; 104 - at 30 frames per second: 720x480, 640x480, 360x240, 320x240; 98 + at 30 frames per second: 720x480, 640x480, 360x240, 320x240. 105 99 106 100 107 101 WHAT'S TESTED AND WHAT'S NOT 108 102 ---------------------------- 109 103 110 - This driver is known to work with mplayer, mencoder, tvtime and sufficiently 111 - recent versions of vlc. An interface to ffmpeg is implemented, but serious 112 - audio-video synchronization problems remain. 104 + This driver is known to work with mplayer, mencoder, tvtime, zoneminder, 105 + xawtv, gstreamer and sufficiently recent versions of vlc. An interface 106 + to ffmpeg is implemented, but serious audio-video synchronization problems 107 + remain. 113 108 114 109 The driver is designed to support all the TV standards accepted by the 115 110 hardware, but as yet it has actually been tested on only a few of these. ··· 128 101 I have been unable to test and calibrate the S-video input myself because I 129 102 do not possess any equipment with S-video output. 130 103 131 - This driver does not understand the V4L1 IOCTL commands, so programs such 132 - as camorama are not compatible. There are reports that the driver does 133 - work with sufficiently recent (V4L2) versions of zoneminder, but I have not 134 - attempted to confirm this myself. 104 + This driver does not understand the V4L1 IOCTL commands. 135 105 136 106 137 107 UDEV RULES ··· 142 118 ATTRS{idVendor}=="05e1", ATTRS{idProduct}=="0408", \ 143 119 MODE="0666", OWNER="root", GROUP="root" 144 120 LABEL="easycap_rules_end" 121 + 122 + 123 + MODPROBE CONFIGURATION 124 + ---------------------- 125 + 126 + The easycap module is in competition with the module snd-usb-audio for the 127 + EasyCAP's audio channel, and its installation can be aided by providing a 128 + file in directory /etc/modprobe.d with content: 129 + 130 + options easycap gain=16 bars=1 131 + install easycap /sbin/rmmod snd-usb-audio; /sbin/modprobe --ignore-install easycap 145 132 146 133 147 134 ACKNOWLEGEMENTS AND REFERENCES
+3 -13
drivers/staging/easycap/easycap.h
··· 33 33 * EASYCAP_NEEDS_USBVIDEO_H 34 34 * EASYCAP_NEEDS_V4L2_DEVICE_H 35 35 * EASYCAP_NEEDS_V4L2_FOPS 36 + * EASYCAP_NEEDS_UNLOCKED_IOCTL 36 37 * 37 38 * IF REQUIRED THEY MUST BE EXTERNALLY DEFINED, FOR EXAMPLE AS COMPILER 38 39 * OPTIONS. ··· 82 81 83 82 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ 84 83 #if defined(EASYCAP_IS_VIDEODEV_CLIENT) 85 - #if (!defined(__OLD_VIDIOC_)) 86 - #define __OLD_VIDIOC_ 87 - #endif /* !defined(__OLD_VIDIOC_) */ 88 - 89 84 #include <media/v4l2-dev.h> 90 - 91 85 #if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) 92 86 #include <media/v4l2-device.h> 93 87 #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ 94 88 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ 95 89 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ 96 - 97 - #if (!defined(__OLD_VIDIOC_)) 98 - #define __OLD_VIDIOC_ 99 - #endif /* !defined(__OLD_VIDIOC_) */ 100 90 #include <linux/videodev2.h> 101 - 102 91 #include <linux/soundcard.h> 103 - 104 92 #if defined(EASYCAP_NEEDS_USBVIDEO_H) 105 93 #include <config/video/usbvideo.h> 106 94 #endif /*EASYCAP_NEEDS_USBVIDEO_H*/ ··· 100 110 101 111 #define STRINGIZE_AGAIN(x) #x 102 112 #define STRINGIZE(x) STRINGIZE_AGAIN(x) 103 - 104 113 /*---------------------------------------------------------------------------*/ 105 114 /* VENDOR, PRODUCT: Syntek Semiconductor Co., Ltd 106 115 * ··· 294 305 */ 295 306 /*---------------------------------------------------------------------------*/ 296 307 struct easycap { 308 + #define TELLTALE "expectedstring" 309 + char telltale[16]; 297 310 int isdongle; 298 311 299 312 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ ··· 492 501 unsigned long); 493 502 int easycap_ioctl(struct inode *, struct file *, unsigned int, \ 494 503 unsigned long); 495 - 496 504 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ 497 505 #if defined(EASYCAP_IS_VIDEODEV_CLIENT) 498 506 int easycap_open_noinode(struct file *);
+24 -2
drivers/staging/easycap/easycap_ioctl.c
··· 977 977 } 978 978 peasycap = file->private_data; 979 979 if (NULL == peasycap) { 980 - SAY("ERROR: peasycap is NULL.\n"); 980 + SAY("ERROR: peasycap is NULL\n"); 981 981 return -1; 982 + } 983 + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { 984 + SAY("ERROR: bad peasycap\n"); 985 + return -EFAULT; 982 986 } 983 987 p = peasycap->pusb_device; 984 988 if (NULL == p) { ··· 1015 1011 SAY("ERROR: peasycap is NULL\n"); 1016 1012 mutex_unlock(&easycap_dongle[kd].mutex_video); 1017 1013 return -ERESTARTSYS; 1014 + } 1015 + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { 1016 + SAY("ERROR: bad peasycap\n"); 1017 + mutex_unlock(&easycap_dongle[kd].mutex_video); 1018 + return -EFAULT; 1018 1019 } 1019 1020 p = peasycap->pusb_device; 1020 1021 if (NULL == peasycap->pusb_device) { ··· 2306 2297 ((long long int)(timeval.tv_sec - \ 2307 2298 timeval2.tv_sec)) + \ 2308 2299 (long long int)(timeval.tv_usec - \ 2309 - timeval2.tv_usec); 2300 + timeval2.tv_usec); 2310 2301 sdr = signed_div(fudge, 1000); 2311 2302 sll = sdr.quotient; 2312 2303 ull = sdr.remainder; ··· 2326 2317 JOM(16, " %10i=bytesused\n", v4l2_buffer.bytesused); 2327 2318 JOM(16, " 0x%08X=flags\n", v4l2_buffer.flags); 2328 2319 JOM(16, " %10i=field\n", v4l2_buffer.field); 2320 + JOM(16, " %10li=timestamp.tv_sec\n", \ 2321 + (long)v4l2_buffer.timestamp.tv_sec); 2329 2322 JOM(16, " %10li=timestamp.tv_usec\n", \ 2330 2323 (long)v4l2_buffer.timestamp.tv_usec); 2331 2324 JOM(16, " %10i=sequence\n", v4l2_buffer.sequence); ··· 2539 2528 SAY("ERROR: peasycap is NULL.\n"); 2540 2529 return -EFAULT; 2541 2530 } 2531 + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { 2532 + SAY("ERROR: bad peasycap\n"); 2533 + return -EFAULT; 2534 + } 2542 2535 p = peasycap->pusb_device; 2543 2536 if (NULL == p) { 2544 2537 SAM("ERROR: peasycap->pusb_device is NULL\n"); ··· 2574 2559 SAY("ERROR: peasycap is NULL\n"); 2575 2560 mutex_unlock(&easycap_dongle[kd].mutex_audio); 2576 2561 return -ERESTARTSYS; 2562 + } 2563 + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { 2564 + SAY("ERROR: bad peasycap\n"); 2565 + mutex_unlock(&easycap_dongle[kd].mutex_audio); 2566 + return -EFAULT; 2577 2567 } 2578 2568 p = peasycap->pusb_device; 2579 2569 if (NULL == peasycap->pusb_device) { ··· 2815 2795 return 0; 2816 2796 } 2817 2797 /*****************************************************************************/ 2798 + 2799 +
+135 -26
drivers/staging/easycap/easycap_main.c
··· 93 93 .llseek = no_llseek, 94 94 }; 95 95 struct vm_operations_struct easycap_vm_ops = { 96 - .open = easycap_vma_open, 97 - .close = easycap_vma_close, 98 - .fault = easycap_vma_fault, 96 + .open = easycap_vma_open, 97 + .close = easycap_vma_close, 98 + .fault = easycap_vma_fault, 99 99 }; 100 100 struct usb_class_driver easycap_class = { 101 - .name = "usb/easycap%d", 102 - .fops = &easycap_fops, 103 - .minor_base = USB_SKEL_MINOR_BASE, 101 + .name = "usb/easycap%d", 102 + .fops = &easycap_fops, 103 + .minor_base = USB_SKEL_MINOR_BASE, 104 104 }; 105 - 106 105 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ 107 106 #if defined(EASYCAP_IS_VIDEODEV_CLIENT) 108 107 #if defined(EASYCAP_NEEDS_V4L2_FOPS) ··· 120 121 #endif /*EASYCAP_NEEDS_V4L2_FOPS*/ 121 122 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ 122 123 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ 123 - 124 124 /*--------------------------------------------------------------------------*/ 125 125 /* 126 126 * PARAMETERS USED WHEN REGISTERING THE AUDIO INTERFACE ··· 145 147 /****************************************************************************/ 146 148 /*---------------------------------------------------------------------------*/ 147 149 /* 148 - * THIS ROUTINE DOES NOT DETECT MULTIPLE OCCURRENCES OF POINTER peasycap 150 + * THIS ROUTINE DOES NOT DETECT DUPLICATE OCCURRENCES OF POINTER peasycap 149 151 */ 150 152 /*---------------------------------------------------------------------------*/ 151 153 int ··· 211 213 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ 212 214 if (NULL == peasycap) { 213 215 SAY("ERROR: peasycap is NULL\n"); 216 + return -EFAULT; 217 + } 218 + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { 219 + SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); 214 220 return -EFAULT; 215 221 } 216 222 if (NULL == peasycap->pusb_device) { ··· 840 838 SAY("ending unsuccessfully\n"); 841 839 return -EFAULT; 842 840 } 841 + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { 842 + SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); 843 + return -EFAULT; 844 + } 843 845 if (0 != kill_video_urbs(peasycap)) { 844 846 SAM("ERROR: kill_video_urbs() failed\n"); 845 847 return -EFAULT; ··· 871 865 if (NULL == peasycap) { 872 866 SAY("ERROR: peasycap is NULL\n"); 873 867 SAY("ending unsuccessfully\n"); 868 + return -EFAULT; 869 + } 870 + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { 871 + SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); 874 872 return -EFAULT; 875 873 } 876 874 if (0 != kill_video_urbs(peasycap)) { ··· 912 902 peasycap = container_of(pkref, struct easycap, kref); 913 903 if (NULL == peasycap) { 914 904 SAM("ERROR: peasycap is NULL: cannot perform deletions\n"); 905 + return; 906 + } 907 + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { 908 + SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); 915 909 return; 916 910 } 917 911 kd = isdongle(peasycap); ··· 1040 1026 JOM(4, "%i audio data_urb structures freed\n", m); 1041 1027 JOM(4, "setting peasycap->purb_audio_head=NULL\n"); 1042 1028 peasycap->purb_audio_head = (struct list_head *)NULL; 1043 - } else { 1044 - JOM(4, "peasycap->purb_audio_head is NULL\n"); 1045 1029 } 1046 1030 /*---------------------------------------------------------------------------*/ 1047 1031 JOM(4, "freeing audio isoc buffers.\n"); ··· 1120 1108 SAY("ERROR: peasycap is NULL\n"); 1121 1109 return -EFAULT; 1122 1110 } 1111 + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { 1112 + SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); 1113 + return -EFAULT; 1114 + } 1123 1115 if (NULL == peasycap->pusb_device) { 1124 1116 SAY("ERROR: peasycap->pusb_device is NULL\n"); 1125 1117 return -EFAULT; ··· 1156 1140 mutex_unlock(&easycap_dongle[kd].mutex_video); 1157 1141 return -ERESTARTSYS; 1158 1142 } 1143 + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { 1144 + SAY("ERROR: bad peasycap: 0x%08lX\n", \ 1145 + (unsigned long int) peasycap); 1146 + mutex_unlock(&easycap_dongle[kd].mutex_video); 1147 + return -ERESTARTSYS; 1148 + } 1159 1149 if (NULL == peasycap->pusb_device) { 1160 1150 SAM("ERROR: peasycap->pusb_device is NULL\n"); 1161 1151 mutex_unlock(&easycap_dongle[kd].mutex_video); 1162 - return -ERESTARTSYS; 1152 + return -ERESTARTSYS; 1163 1153 } 1164 1154 } else 1165 1155 /*-------------------------------------------------------------------*/ ··· 2709 2687 struct easycap *peasycap; 2710 2688 2711 2689 peasycap = pvma->vm_private_data; 2712 - if (NULL != peasycap) 2713 - peasycap->vma_many++; 2714 - 2690 + if (NULL == peasycap) { 2691 + SAY("ERROR: peasycap is NULL\n"); 2692 + return; 2693 + } 2694 + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { 2695 + SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); 2696 + return; 2697 + } 2698 + peasycap->vma_many++; 2715 2699 JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many); 2716 - 2717 2700 return; 2718 2701 } 2719 2702 /*****************************************************************************/ ··· 2728 2701 struct easycap *peasycap; 2729 2702 2730 2703 peasycap = pvma->vm_private_data; 2731 - if (NULL != peasycap) { 2732 - peasycap->vma_many--; 2733 - JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many); 2704 + if (NULL == peasycap) { 2705 + SAY("ERROR: peasycap is NULL\n"); 2706 + return; 2734 2707 } 2708 + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { 2709 + SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); 2710 + return; 2711 + } 2712 + peasycap->vma_many--; 2713 + JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many); 2735 2714 return; 2736 2715 } 2737 2716 /*****************************************************************************/ ··· 2853 2820 SAY("ERROR: easycap_complete(): peasycap is NULL\n"); 2854 2821 return; 2855 2822 } 2856 - 2823 + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { 2824 + SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); 2825 + return; 2826 + } 2857 2827 if (peasycap->video_eof) 2858 2828 return; 2859 - 2860 2829 for (i = 0; i < VIDEO_ISOC_BUFFER_MANY; i++) 2861 2830 if (purb->transfer_buffer == peasycap->video_isoc_buffer[i].pgo) 2862 2831 break; ··· 3580 3545 * PERFORM URGENT INTIALIZATIONS ... 3581 3546 */ 3582 3547 /*---------------------------------------------------------------------------*/ 3548 + strcpy(&peasycap->telltale[0], TELLTALE); 3583 3549 kref_init(&peasycap->kref); 3584 3550 JOM(8, "intf[%i]: after kref_init(..._video) " \ 3585 3551 "%i=peasycap->kref.refcount.counter\n", \ ··· 4335 4299 */ 4336 4300 /*--------------------------------------------------------------------------*/ 4337 4301 usb_set_intfdata(pusb_interface, peasycap); 4302 + /*---------------------------------------------------------------------------*/ 4303 + /* 4304 + * IT IS ESSENTIAL TO INITIALIZE THE HARDWARE BEFORE, RATHER THAN AFTER, 4305 + * THE DEVICE IS REGISTERED, BECAUSE SOME VERSIONS OF THE videodev MODULE 4306 + * CALL easycap_open() IMMEDIATELY AFTER REGISTRATION, CAUSING A CLASH. 4307 + * BEWARE. 4308 + */ 4309 + /*---------------------------------------------------------------------------*/ 4310 + #if defined(PREFER_NTSC) 4311 + peasycap->ntsc = true; 4312 + JOM(8, "defaulting initially to NTSC\n"); 4313 + #else 4314 + peasycap->ntsc = false; 4315 + JOM(8, "defaulting initially to PAL\n"); 4316 + #endif /*PREFER_NTSC*/ 4317 + rc = reset(peasycap); 4318 + if (0 != rc) { 4319 + SAM("ERROR: reset() returned %i\n", rc); 4320 + return -EFAULT; 4321 + } 4338 4322 /*--------------------------------------------------------------------------*/ 4339 4323 /* 4340 4324 * THE VIDEO DEVICE CAN BE REGISTERED NOW, AS IT IS READY. ··· 4743 4687 struct list_head *plist_head; 4744 4688 struct data_urb *pdata_urb; 4745 4689 int minor, m, kd; 4690 + /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ 4691 + #if defined(EASYCAP_IS_VIDEODEV_CLIENT) 4692 + #if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) 4693 + struct v4l2_device *pv4l2_device; 4694 + #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ 4695 + #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ 4696 + /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ 4746 4697 4747 4698 JOT(4, "\n"); 4748 4699 ··· 4777 4714 peasycap = usb_get_intfdata(pusb_interface); 4778 4715 if (NULL == peasycap) { 4779 4716 SAY("ERROR: peasycap is NULL\n"); 4717 + return; 4718 + } 4719 + /*---------------------------------------------------------------------------*/ 4720 + #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT)) 4721 + # 4722 + /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ 4723 + #else 4724 + #if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) 4725 + /*---------------------------------------------------------------------------*/ 4726 + /* 4727 + * SOME VERSIONS OF THE videodev MODULE OVERWRITE THE DATA WHICH HAS 4728 + * BEEN WRITTEN BY THE CALL TO usb_set_intfdata() IN easycap_usb_probe(), 4729 + * REPLACING IT WITH A POINTER TO THE EMBEDDED v4l2_device STRUCTURE. 4730 + * TO DETECT THIS, THE STRING IN THE easycap.telltale[] BUFFER IS CHECKED. 4731 + */ 4732 + /*---------------------------------------------------------------------------*/ 4733 + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { 4734 + pv4l2_device = usb_get_intfdata(pusb_interface); 4735 + if ((struct v4l2_device *)NULL == pv4l2_device) { 4736 + SAY("ERROR: pv4l2_device is NULL\n"); 4737 + return; 4738 + } 4739 + peasycap = (struct easycap *) \ 4740 + container_of(pv4l2_device, struct easycap, v4l2_device); 4741 + } 4742 + #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ 4743 + # 4744 + #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ 4745 + /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ 4746 + /*---------------------------------------------------------------------------*/ 4747 + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { 4748 + SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); 4780 4749 return; 4781 4750 } 4782 4751 /*---------------------------------------------------------------------------*/ ··· 4901 4806 JOM(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber); 4902 4807 SAM("easycap detached from minor #%d\n", minor); 4903 4808 } 4904 - /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ 4809 + /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ 4905 4810 #else 4811 + #if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) 4812 + if (!peasycap->v4l2_device.name[0]) { 4813 + SAM("ERROR: peasycap->v4l2_device.name is empty\n"); 4814 + if (0 <= kd && DONGLE_MANY > kd) 4815 + mutex_unlock(&easycap_dongle[kd].mutex_video); 4816 + return; 4817 + } 4818 + v4l2_device_disconnect(&peasycap->v4l2_device); 4819 + JOM(4, "v4l2_device_disconnect() OK\n"); 4820 + v4l2_device_unregister(&peasycap->v4l2_device); 4821 + JOM(4, "v4l2_device_unregister() OK\n"); 4822 + #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ 4823 + 4906 4824 video_unregister_device(&peasycap->video_device); 4907 - JOM(4, "unregistered with videodev: %i=minor\n", \ 4908 - peasycap->video_device.minor); 4825 + JOM(4, "intf[%i]: video_unregister_device() OK\n", bInterfaceNumber); 4909 4826 (peasycap->registered_video)--; 4910 - /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ 4827 + JOM(4, "unregistered with videodev: %i=minor\n", minor); 4911 4828 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ 4829 + /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ 4830 + 4912 4831 if (0 <= kd && DONGLE_MANY > kd) { 4913 4832 mutex_unlock(&easycap_dongle[kd].mutex_video); 4914 4833 JOM(4, "unlocked easycap_dongle[%i].mutex_video\n", kd); ··· 5050 4941 MODULE_DESCRIPTION(EASYCAP_DRIVER_DESCRIPTION); 5051 4942 MODULE_VERSION(EASYCAP_DRIVER_VERSION); 5052 4943 #if defined(EASYCAP_DEBUG) 5053 - MODULE_PARM_DESC(debug, "Debug level: 0 (default),1,2,..."); 4944 + MODULE_PARM_DESC(debug, "Debug level: 0(default),1,2,...,9"); 5054 4945 #endif /*EASYCAP_DEBUG*/ 5055 4946 MODULE_PARM_DESC(bars, \ 5056 4947 "Testcard bars on input signal failure: 0=>no, 1=>yes(default)");
+61 -2
drivers/staging/easycap/easycap_sound.c
··· 64 64 SAY("ERROR: peasycap is NULL\n"); 65 65 return; 66 66 } 67 + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { 68 + SAY("ERROR: bad peasycap\n"); 69 + return; 70 + } 71 + 67 72 much = 0; 68 73 69 74 if (peasycap->audio_idle) { ··· 600 595 struct usb_interface *pusb_interface; 601 596 struct easycap *peasycap; 602 597 int subminor, rc; 598 + /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ 599 + #if defined(EASYCAP_IS_VIDEODEV_CLIENT) 600 + #if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) 601 + struct v4l2_device *pv4l2_device; 602 + #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ 603 + #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ 604 + /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ 603 605 604 606 JOT(4, "begins\n"); 605 607 ··· 624 612 SAY("ending unsuccessfully\n"); 625 613 return -1; 626 614 } 615 + /*---------------------------------------------------------------------------*/ 616 + #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT)) 617 + # 618 + /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ 619 + #else 620 + #if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) 621 + /*---------------------------------------------------------------------------*/ 622 + /* 623 + * SOME VERSIONS OF THE videodev MODULE OVERWRITE THE DATA WHICH HAS 624 + * BEEN WRITTEN BY THE CALL TO usb_set_intfdata() IN easycap_usb_probe(), 625 + * REPLACING IT WITH A POINTER TO THE EMBEDDED v4l2_device STRUCTURE. 626 + * TO DETECT THIS, THE STRING IN THE easycap.telltale[] BUFFER IS CHECKED. 627 + */ 628 + /*---------------------------------------------------------------------------*/ 629 + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { 630 + pv4l2_device = usb_get_intfdata(pusb_interface); 631 + if ((struct v4l2_device *)NULL == pv4l2_device) { 632 + SAY("ERROR: pv4l2_device is NULL\n"); 633 + return -EFAULT; 634 + } 635 + peasycap = (struct easycap *) \ 636 + container_of(pv4l2_device, struct easycap, v4l2_device); 637 + } 638 + #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ 639 + # 640 + #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ 641 + /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ 642 + /*---------------------------------------------------------------------------*/ 643 + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { 644 + SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); 645 + return -EFAULT; 646 + } 647 + /*---------------------------------------------------------------------------*/ 627 648 628 649 file->private_data = peasycap; 629 650 ··· 669 624 670 625 if ((struct usb_device *)NULL == peasycap->pusb_device) { 671 626 SAM("ERROR: peasycap->pusb_device is NULL\n"); 672 - return -EFAULT; 627 + return -ENODEV; 673 628 } 674 629 JOM(16, "0x%08lX=peasycap->pusb_device\n", (long int)peasycap->pusb_device); 675 630 ··· 686 641 /*---------------------------------------------------------------------------*/ 687 642 if ((struct usb_device *)NULL == peasycap->pusb_device) { 688 643 SAM("ERROR: peasycap->pusb_device has become NULL\n"); 689 - return -EFAULT; 644 + return -ENODEV; 690 645 } 691 646 rc = usb_set_interface(peasycap->pusb_device, peasycap->audio_interface, \ 692 647 peasycap->audio_altsetting_on); ··· 721 676 peasycap = file->private_data; 722 677 if (NULL == peasycap) { 723 678 SAY("ERROR: peasycap is NULL.\n"); 679 + return -EFAULT; 680 + } 681 + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { 682 + SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); 724 683 return -EFAULT; 725 684 } 726 685 if (0 != kill_audio_urbs(peasycap)) { ··· 771 722 SAY("ERROR in easysnd_read(): peasycap is NULL\n"); 772 723 return -EFAULT; 773 724 } 725 + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { 726 + SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); 727 + return -EFAULT; 728 + } 774 729 if (NULL == peasycap->pusb_device) { 775 730 SAY("ERROR in easysnd_read(): peasycap->pusb_device is NULL\n"); 776 731 return -EFAULT; ··· 803 750 peasycap = file->private_data; 804 751 if (NULL == peasycap) { 805 752 SAY("ERROR: peasycap is NULL\n"); 753 + mutex_unlock(&easycap_dongle[kd].mutex_audio); 754 + return -ERESTARTSYS; 755 + } 756 + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { 757 + SAY("ERROR: bad peasycap: 0x%08lX\n", \ 758 + (unsigned long int) peasycap); 806 759 mutex_unlock(&easycap_dongle[kd].mutex_audio); 807 760 return -ERESTARTSYS; 808 761 }