Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
[sfrench/cifs-2.6.git] / drivers / staging / easycap / easycap_main.c
1 /******************************************************************************
2 *                                                                             *
3 *  easycap_main.c                                                             *
4 *                                                                             *
5 *  Video driver for EasyCAP USB2.0 Video Capture Device DC60                  *
6 *                                                                             *
7 *                                                                             *
8 ******************************************************************************/
9 /*
10  *
11  *  Copyright (C) 2010 R.M. Thomas <rmthomas@sciolus.org>
12  *
13  *
14  *  This is free software; you can redistribute it and/or modify
15  *  it under the terms of the GNU General Public License as published by
16  *  the Free Software Foundation; either version 2 of the License, or
17  *  (at your option) any later version.
18  *
19  *  The software is distributed in the hope that it will be useful,
20  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
21  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  *  GNU General Public License for more details.
23  *
24  *  You should have received a copy of the GNU General Public License
25  *  along with this software; if not, write to the Free Software
26  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27  *
28 */
29 /*****************************************************************************/
30
31 #include "easycap.h"
32 #include "easycap_standard.h"
33
34 int easycap_debug;
35 module_param(easycap_debug, int, S_IRUGO | S_IWUSR);
36
37 /*---------------------------------------------------------------------------*/
38 /*
39  *  PARAMETERS APPLICABLE TO ENTIRE DRIVER, I.E. BOTH VIDEO AND AUDIO
40  */
41 /*---------------------------------------------------------------------------*/
42 struct usb_device_id easycap_usb_device_id_table[] = {
43 { USB_DEVICE(USB_EASYCAP_VENDOR_ID, USB_EASYCAP_PRODUCT_ID) },
44 { }
45 };
46 MODULE_DEVICE_TABLE(usb, easycap_usb_device_id_table);
47 struct usb_driver easycap_usb_driver = {
48 .name = "easycap",
49 .id_table = easycap_usb_device_id_table,
50 .probe = easycap_usb_probe,
51 .disconnect = easycap_usb_disconnect,
52 };
53 /*---------------------------------------------------------------------------*/
54 /*
55  *  PARAMETERS USED WHEN REGISTERING THE VIDEO INTERFACE
56  *
57  *  NOTE: SOME KERNELS IGNORE usb_class_driver.minor_base, AS MENTIONED BY
58  *        CORBET ET AL. "LINUX DEVICE DRIVERS", 3rd EDITION, PAGE 253.
59  *        THIS IS THE CASE FOR OpenSUSE.
60  */
61 /*---------------------------------------------------------------------------*/
62 const struct file_operations easycap_fops = {
63         .owner          = THIS_MODULE,
64         .open           = easycap_open,
65         .release        = easycap_release,
66         .unlocked_ioctl = easycap_ioctl,
67         .poll           = easycap_poll,
68         .mmap           = easycap_mmap,
69         .llseek         = no_llseek,
70 };
71 struct vm_operations_struct easycap_vm_ops = {
72 .open  = easycap_vma_open,
73 .close = easycap_vma_close,
74 .fault = easycap_vma_fault,
75 };
76 struct usb_class_driver easycap_class = {
77 .name = "usb/easycap%d",
78 .fops = &easycap_fops,
79 .minor_base = USB_SKEL_MINOR_BASE,
80 };
81
82 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
83 #if defined(EASYCAP_IS_VIDEODEV_CLIENT)
84 #if defined(EASYCAP_NEEDS_V4L2_FOPS)
85 const struct v4l2_file_operations v4l2_fops = {
86         .owner          = THIS_MODULE,
87         .open           = easycap_open_noinode,
88         .release        = easycap_release_noinode,
89         .unlocked_ioctl = easycap_ioctl,
90         .poll           = easycap_poll,
91         .mmap           = easycap_mmap,
92 };
93 #endif /*EASYCAP_NEEDS_V4L2_FOPS*/
94 int video_device_many /*=0*/;
95 struct video_device *pvideo_array[VIDEO_DEVICE_MANY], *pvideo_device;
96 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
97 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
98
99 /*--------------------------------------------------------------------------*/
100 /*
101  *  PARAMETERS USED WHEN REGISTERING THE AUDIO INTERFACE
102  */
103 /*--------------------------------------------------------------------------*/
104 const struct file_operations easysnd_fops = {
105         .owner          = THIS_MODULE,
106         .open           = easysnd_open,
107         .release        = easysnd_release,
108         .unlocked_ioctl = easysnd_ioctl,
109         .read           = easysnd_read,
110         .llseek         = no_llseek,
111 };
112 struct usb_class_driver easysnd_class = {
113 .name = "usb/easysnd%d",
114 .fops = &easysnd_fops,
115 .minor_base = USB_SKEL_MINOR_BASE,
116 };
117 /****************************************************************************/
118 /*--------------------------------------------------------------------------*/
119 /*
120  *  IT IS NOT APPROPRIATE FOR easycap_open() TO SUBMIT THE VIDEO URBS HERE,
121  *  BECAUSE THERE WILL ALWAYS BE SUBSEQUENT NEGOTIATION OF TV STANDARD AND
122  *  FORMAT BY IOCTL AND IT IS INADVISABLE TO HAVE THE URBS RUNNING WHILE
123  *  REGISTERS OF THE SA7113H ARE BEING MANIPULATED.
124  *
125  *  THE SUBMISSION OF VIDEO URBS IS THEREFORE DELAYED UNTIL THE IOCTL COMMAND
126  *  STREAMON IS RECEIVED.
127  */
128 /*--------------------------------------------------------------------------*/
129 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
130 #if defined(EASYCAP_IS_VIDEODEV_CLIENT)
131 int
132 easycap_open_noinode(struct file *file)
133 {
134 return easycap_open((struct inode *)NULL, file);
135 }
136 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
137 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
138 int
139 easycap_open(struct inode *inode, struct file *file)
140 {
141 #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
142 struct usb_interface *pusb_interface;
143 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
144 struct usb_device *p;
145 struct easycap *peasycap;
146 int i, k, m, rc;
147
148 JOT(4, "\n");
149 SAY("==========OPEN=========\n");
150
151 peasycap = (struct easycap *)NULL;
152 #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
153 if ((struct inode *)NULL == inode) {
154         SAY("ERROR: inode is NULL.\n");
155         return -EFAULT;
156 }
157 pusb_interface = usb_find_interface(&easycap_usb_driver, iminor(inode));
158 if (!pusb_interface) {
159         SAY("ERROR: pusb_interface is NULL.\n");
160         return -EFAULT;
161 }
162 peasycap = usb_get_intfdata(pusb_interface);
163 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
164 #else
165 for (i = 0;  i < video_device_many;  i++) {
166         pvideo_device = pvideo_array[i];
167         if ((struct video_device *)NULL != pvideo_device) {
168                 peasycap = (struct easycap *)video_get_drvdata(pvideo_device);
169                 break;
170         }
171 }
172 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
173 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
174 if ((struct easycap *)NULL == peasycap) {
175         SAY("MISTAKE: peasycap is NULL\n");
176         return -EFAULT;
177 }
178 file->private_data = peasycap;
179 /*---------------------------------------------------------------------------*/
180 /*
181  *  INITIALIZATION
182  */
183 /*---------------------------------------------------------------------------*/
184 JOT(4, "starting initialization\n");
185
186 for (k = 0;  k < FRAME_BUFFER_MANY;  k++) {
187         for (m = 0;  m < FRAME_BUFFER_SIZE/PAGE_SIZE;  m++)
188                 memset(peasycap->frame_buffer[k][m].pgo, 0, PAGE_SIZE);
189 }
190 p = peasycap->pusb_device;
191 if ((struct usb_device *)NULL == p) {
192         SAY("ERROR: peasycap->pusb_device is NULL\n");
193         return -EFAULT;
194 } else {
195         JOT(16, "0x%08lX=peasycap->pusb_device\n", \
196                                         (long int)peasycap->pusb_device);
197 }
198 rc = wakeup_device(peasycap->pusb_device);
199 if (0 == rc)
200         JOT(8, "wakeup_device() OK\n");
201 else {
202         SAY("ERROR: wakeup_device() returned %i\n", rc);
203         return -EFAULT;
204 }
205 rc = setup_stk(p);  peasycap->input = 0;
206 if (0 == rc)
207         JOT(8, "setup_stk() OK\n");
208 else {
209         SAY("ERROR: setup_stk() returned %i\n", rc);
210         return -EFAULT;
211 }
212 rc = setup_saa(p);
213 if (0 == rc)
214         JOT(8, "setup_saa() OK\n");
215 else {
216         SAY("ERROR: setup_saa() returned %i\n", rc);
217         return -EFAULT;
218 }
219 rc = check_saa(p);
220 if (0 == rc)
221         JOT(8, "check_saa() OK\n");
222 else if (-8 < rc)
223         SAY("check_saa() returned %i\n", rc);
224 else {
225         SAY("ERROR: check_saa() returned %i\n", rc);
226         return -EFAULT;
227 }
228 peasycap->standard_offset = -1;
229 /*---------------------------------------------------------------------------*/
230 #if defined(PREFER_NTSC)
231
232 rc = adjust_standard(peasycap, V4L2_STD_NTSC_M);
233 if (0 == rc)
234         JOT(8, "adjust_standard(.,NTSC_M) OK\n");
235 else {
236         SAY("ERROR: adjust_standard(.,NTSC_M) returned %i\n", rc);
237         return -EFAULT;
238 }
239 rc = adjust_format(peasycap, 640, 480, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE, \
240                                                                         false);
241 if (0 <= rc)
242         JOT(8, "adjust_format(.,640,480,UYVY) OK\n");
243 else {
244         SAY("ERROR: adjust_format(.,640,480,UYVY) returned %i\n", rc);
245         return -EFAULT;
246 }
247
248 #else
249
250 rc = adjust_standard(peasycap, \
251                 (V4L2_STD_PAL_B | V4L2_STD_PAL_G | V4L2_STD_PAL_H | \
252                 V4L2_STD_PAL_I | V4L2_STD_PAL_N));
253 if (0 == rc)
254         JOT(8, "adjust_standard(.,PAL_BGHIN) OK\n");
255 else {
256         SAY("ERROR: adjust_standard(.,PAL_BGHIN) returned %i\n", rc);
257         return -EFAULT;
258 }
259 rc = adjust_format(peasycap, 640, 480, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE, \
260                                                                         false);
261 if (0 <= rc)
262         JOT(8, "adjust_format(.,640,480,uyvy,false) OK\n");
263 else {
264         SAY("ERROR: adjust_format(.,640,480,uyvy,false) returned %i\n", rc);
265         return -EFAULT;
266 }
267
268 #endif /* !PREFER_NTSC*/
269 /*---------------------------------------------------------------------------*/
270 rc = adjust_brightness(peasycap, -8192);
271 if (0 != rc) {
272         SAY("ERROR: adjust_brightness(default) returned %i\n", rc);
273         return -EFAULT;
274 }
275 rc = adjust_contrast(peasycap, -8192);
276 if (0 != rc) {
277         SAY("ERROR: adjust_contrast(default) returned %i\n", rc);
278         return -EFAULT;
279 }
280 rc = adjust_saturation(peasycap, -8192);
281 if (0 != rc) {
282         SAY("ERROR: adjust_saturation(default) returned %i\n", rc);
283         return -EFAULT;
284 }
285 rc = adjust_hue(peasycap, -8192);
286 if (0 != rc) {
287         SAY("ERROR: adjust_hue(default) returned %i\n", rc);
288         return -EFAULT;
289 }
290 /*---------------------------------------------------------------------------*/
291 rc = usb_set_interface(peasycap->pusb_device, peasycap->video_interface, \
292                                                 peasycap->video_altsetting_on);
293 if (0 == rc)
294         JOT(8, "usb_set_interface(.,%i,%i) OK\n", peasycap->video_interface, \
295                                                 peasycap->video_altsetting_on);
296 else {
297         SAY("ERROR: usb_set_interface() returned %i\n", rc);
298         return -EFAULT;
299 }
300 rc = start_100(p);
301 if (0 == rc)
302         JOT(8, "start_100() OK\n");
303 else {
304         SAY("ERROR: start_100() returned %i\n", rc);
305         return -EFAULT;
306 }
307 peasycap->video_isoc_sequence = VIDEO_ISOC_BUFFER_MANY - 1;
308 peasycap->video_idle = 0;
309 peasycap->video_junk = 0;
310 for (i = 0; i < 180; i++)
311         peasycap->merit[i] = 0;
312 peasycap->video_eof = 0;
313 peasycap->audio_eof = 0;
314
315 do_gettimeofday(&peasycap->timeval7);
316
317 peasycap->fudge = 0;
318
319 JOT(4, "finished initialization\n");
320 return 0;
321 }
322 /*****************************************************************************/
323 int
324 submit_video_urbs(struct easycap *peasycap)
325 {
326 struct data_urb *pdata_urb;
327 struct urb *purb;
328 struct list_head *plist_head;
329 int j, isbad, m, rc;
330 int isbuf;
331
332 if ((struct list_head *)NULL == peasycap->purb_video_head) {
333         SAY("ERROR: peasycap->urb_video_head uninitialized\n");
334         return -EFAULT;
335 }
336 if ((struct usb_device *)NULL == peasycap->pusb_device) {
337         SAY("ERROR: peasycap->pusb_device is NULL\n");
338         return -EFAULT;
339 }
340 if (!peasycap->video_isoc_streaming) {
341
342
343
344
345
346
347
348
349         JOT(4, "submission of all video urbs\n");
350         if (0 != ready_saa(peasycap->pusb_device)) {
351                 SAY("ERROR: not ready to capture after waiting " \
352                                                         "one second\n");
353                 SAY(".....  continuing anyway\n");
354         }
355         isbad = 0;  m = 0;
356         list_for_each(plist_head, (peasycap->purb_video_head)) {
357                 pdata_urb = list_entry(plist_head, struct data_urb, list_head);
358                 if (NULL != pdata_urb) {
359                         purb = pdata_urb->purb;
360                         if (NULL != purb) {
361                                 isbuf = pdata_urb->isbuf;
362                                 purb->interval = 1;
363                                 purb->dev = peasycap->pusb_device;
364                                 purb->pipe = \
365                                         usb_rcvisocpipe(peasycap->pusb_device,\
366                                         peasycap->video_endpointnumber);
367                                 purb->transfer_flags = URB_ISO_ASAP;
368                                 purb->transfer_buffer = \
369                                         peasycap->video_isoc_buffer[isbuf].pgo;
370                                 purb->transfer_buffer_length = \
371                                         peasycap->video_isoc_buffer_size;
372                                 purb->complete = easycap_complete;
373                                 purb->context = peasycap;
374                                 purb->start_frame = 0;
375                                 purb->number_of_packets = \
376                                         peasycap->video_isoc_framesperdesc;
377
378                                 for (j = 0;  j < peasycap->\
379                                         video_isoc_framesperdesc; j++) {
380                                                 purb->iso_frame_desc[j].\
381                                                 offset = j * \
382                                                 peasycap->\
383                                                 video_isoc_maxframesize;
384                                                 purb->iso_frame_desc[j].\
385                                                 length = peasycap->\
386                                                 video_isoc_maxframesize;
387                                         }
388
389                                 rc = usb_submit_urb(purb, GFP_KERNEL);
390                                 if (0 != rc) {
391                                         isbad++;
392                                         SAY("ERROR: usb_submit_urb() failed " \
393                                                         "for urb with rc:\n");
394                                         switch (rc) {
395                                         case -ENOMEM: {
396                                                 SAY("ENOMEM\n");
397                                                 break;
398                                         }
399                                         case -ENODEV: {
400                                                 SAY("ENODEV\n");
401                                                 break;
402                                         }
403                                         case -ENXIO: {
404                                                 SAY("ENXIO\n");
405                                                 break;
406                                         }
407                                         case -EINVAL: {
408                                                 SAY("EINVAL\n");
409                                                 break;
410                                         }
411                                         case -EAGAIN: {
412                                                 SAY("EAGAIN\n");
413                                                 break;
414                                         }
415                                         case -EFBIG: {
416                                                 SAY("EFBIG\n");
417                                                 break;
418                                         }
419                                         case -EPIPE: {
420                                                 SAY("EPIPE\n");
421                                                 break;
422                                         }
423                                         case -EMSGSIZE: {
424                                                 SAY("EMSGSIZE\n");
425                                                 break;
426                                         }
427                                         default: {
428                                                 SAY("unknown error code %i\n",\
429                                                                          rc);
430                                                 break;
431                                         }
432                                         }
433                                 } else {
434                                         m++;
435                                 }
436                                 } else {
437                                         isbad++;
438                                 }
439                         } else {
440                                  isbad++;
441                         }
442                 }
443         if (isbad) {
444                 JOT(4, "attempting cleanup instead of submitting\n");
445                 list_for_each(plist_head, (peasycap->purb_video_head)) {
446                         pdata_urb = list_entry(plist_head, struct data_urb, \
447                                                                 list_head);
448                         if (NULL != pdata_urb) {
449                                 purb = pdata_urb->purb;
450                                 if (NULL != purb)
451                                         usb_kill_urb(purb);
452                         }
453                 }
454                 peasycap->video_isoc_streaming = 0;
455         } else {
456                 peasycap->video_isoc_streaming = 1;
457                 JOT(4, "submitted %i video urbs\n", m);
458         }
459
460
461
462
463
464
465 } else {
466         JOT(4, "already streaming video urbs\n");
467 }
468 return 0;
469 }
470 /*****************************************************************************/
471 int
472 kill_video_urbs(struct easycap *peasycap)
473 {
474 int m;
475 struct list_head *plist_head;
476 struct data_urb *pdata_urb;
477
478 if ((struct easycap *)NULL == peasycap) {
479         SAY("ERROR: peasycap is NULL\n");
480         return -EFAULT;
481 }
482 if (peasycap->video_isoc_streaming) {
483
484
485
486         if ((struct list_head *)NULL != peasycap->purb_video_head) {
487                 peasycap->video_isoc_streaming = 0;
488                 JOT(4, "killing video urbs\n");
489                 m = 0;
490                 list_for_each(plist_head, (peasycap->purb_video_head)) {
491                         pdata_urb = list_entry(plist_head, struct data_urb, \
492                                                                 list_head);
493                         if ((struct data_urb *)NULL != pdata_urb) {
494                                 if ((struct urb *)NULL != pdata_urb->purb) {
495                                         usb_kill_urb(pdata_urb->purb);
496                                         m++;
497                                 }
498                         }
499                 }
500                 JOT(4, "%i video urbs killed\n", m);
501         } else {
502                 SAY("ERROR: peasycap->purb_video_head is NULL\n");
503                 return -EFAULT;
504         }
505 } else {
506         JOT(8, "%i=video_isoc_streaming, no video urbs killed\n", \
507                                         peasycap->video_isoc_streaming);
508 }
509 return 0;
510 }
511 /****************************************************************************/
512 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
513 #if defined(EASYCAP_IS_VIDEODEV_CLIENT)
514 int
515 easycap_release_noinode(struct file *file)
516 {
517 return easycap_release((struct inode *)NULL, file);
518 }
519 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
520 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
521 /*--------------------------------------------------------------------------*/
522 int
523 easycap_release(struct inode *inode, struct file *file)
524 {
525 #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
526 struct easycap *peasycap;
527
528 JOT(4, "\n");
529
530 peasycap = file->private_data;
531 if (NULL == peasycap) {
532         SAY("ERROR:  peasycap is NULL.\n");
533         SAY("ending unsuccessfully\n");
534         return -EFAULT;
535 }
536 if (0 != kill_video_urbs(peasycap)) {
537         SAY("ERROR: kill_video_urbs() failed\n");
538         return -EFAULT;
539 }
540 JOT(4, "ending successfully\n");
541 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
542 #else
543 #
544 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
545 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
546
547 return 0;
548 }
549 /****************************************************************************/
550 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
551 #if defined(EASYCAP_IS_VIDEODEV_CLIENT)
552 int
553 videodev_release(struct video_device *pvd)
554 {
555 struct easycap *peasycap;
556 int i, j, k;
557
558 JOT(4, "\n");
559
560 k = 0;
561 for (i = 0;  i < video_device_many;  i++) {
562         pvideo_device = pvideo_array[i];
563         if ((struct video_device *)NULL != pvideo_device) {
564                 if (pvd->minor == pvideo_device->minor) {
565                         peasycap = (struct easycap *)\
566                                         video_get_drvdata(pvideo_device);
567                         if ((struct easycap *)NULL == peasycap) {
568                                 SAY("ERROR:  peasycap is NULL\n");
569                                 SAY("ending unsuccessfully\n");
570                                 return -EFAULT;
571                         }
572                         if (0 != kill_video_urbs(peasycap)) {
573                                 SAY("ERROR: kill_video_urbs() failed\n");
574                                 return -EFAULT;
575                         }
576                         JOT(4, "freeing video_device structure: " \
577                                                         "/dev/video%i\n", i);
578                         kfree((void *)pvideo_device);
579                         for (j = i;  j < (VIDEO_DEVICE_MANY - 1);  j++)
580                                 pvideo_array[j] = pvideo_array[j + 1];
581                         video_device_many--;  k++;
582                         break;
583                 }
584         }
585 }
586 if (!k) {
587         SAY("ERROR: lost video_device structure for %i=minor\n", pvd->minor);
588         SAY("cannot free: may cause memory leak\n");
589         SAY("ending unsuccessfully\n");
590         return -EFAULT;
591 }
592
593 JOT(4, "ending successfully\n");
594 return 0;
595 }
596 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
597 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
598 /****************************************************************************/
599 /*--------------------------------------------------------------------------*/
600 /*
601  *  THIS FUNCTION IS CALLED FROM WITHIN easycap_usb_disconnect().
602  *  BY THIS STAGE THE DEVICE HAS ALREADY BEEN PHYSICALLY UNPLUGGED.
603  *  peasycap->pusb_device IS NO LONGER VALID AND SHOULD HAVE BEEN SET TO NULL.
604  */
605 /*---------------------------------------------------------------------------*/
606 void
607 easycap_delete(struct kref *pkref)
608 {
609 int k, m, lost;
610 int allocation_video_urb, allocation_video_page, allocation_video_struct;
611 int allocation_audio_urb, allocation_audio_page, allocation_audio_struct;
612 int registered_video, registered_audio;
613 struct easycap *peasycap;
614 struct data_urb *pdata_urb;
615 struct list_head *plist_head, *plist_next;
616
617 JOT(4, "\n");
618
619 peasycap = container_of(pkref, struct easycap, kref);
620 if ((struct easycap *)NULL == peasycap) {
621         SAY("ERROR: peasycap is NULL: cannot perform deletions\n");
622         return;
623 }
624 /*---------------------------------------------------------------------------*/
625 /*
626  *  FREE VIDEO.
627  */
628 /*---------------------------------------------------------------------------*/
629 if ((struct list_head *)NULL != peasycap->purb_video_head) {
630         JOT(4, "freeing video urbs\n");
631         m = 0;
632         list_for_each(plist_head, (peasycap->purb_video_head)) {
633                 pdata_urb = list_entry(plist_head, struct data_urb, list_head);
634                 if (NULL == pdata_urb)
635                         JOT(4, "ERROR: pdata_urb is NULL\n");
636                 else {
637                         if ((struct urb *)NULL != pdata_urb->purb) {
638                                 usb_free_urb(pdata_urb->purb);
639                                 pdata_urb->purb = (struct urb *)NULL;
640                                 peasycap->allocation_video_urb -= 1;
641                                 m++;
642                         }
643                 }
644         }
645
646         JOT(4, "%i video urbs freed\n", m);
647 /*---------------------------------------------------------------------------*/
648         JOT(4, "freeing video data_urb structures.\n");
649         m = 0;
650         list_for_each_safe(plist_head, plist_next, peasycap->purb_video_head) {
651                 pdata_urb = list_entry(plist_head, struct data_urb, list_head);
652                 if ((struct data_urb *)NULL != pdata_urb) {
653                         kfree(pdata_urb);  pdata_urb = (struct data_urb *)NULL;
654                         peasycap->allocation_video_struct -= \
655                                                 sizeof(struct data_urb);
656                         m++;
657                 }
658         }
659         JOT(4, "%i video data_urb structures freed\n", m);
660         JOT(4, "setting peasycap->purb_video_head=NULL\n");
661         peasycap->purb_video_head = (struct list_head *)NULL;
662         } else {
663 JOT(4, "peasycap->purb_video_head is NULL\n");
664 }
665 /*---------------------------------------------------------------------------*/
666 JOT(4, "freeing video isoc buffers.\n");
667 m = 0;
668 for (k = 0;  k < VIDEO_ISOC_BUFFER_MANY;  k++) {
669         if ((void *)NULL != peasycap->video_isoc_buffer[k].pgo) {
670                 free_pages((unsigned long)\
671                                 (peasycap->video_isoc_buffer[k].pgo), \
672                                 VIDEO_ISOC_ORDER);
673                 peasycap->video_isoc_buffer[k].pgo = (void *)NULL;
674                 peasycap->allocation_video_page -= \
675                                 ((unsigned int)(0x01 << VIDEO_ISOC_ORDER));
676                 m++;
677         }
678 }
679 JOT(4, "isoc video buffers freed: %i pages\n", m * (0x01 << VIDEO_ISOC_ORDER));
680 /*---------------------------------------------------------------------------*/
681 JOT(4, "freeing video field buffers.\n");
682 lost = 0;
683 for (k = 0;  k < FIELD_BUFFER_MANY;  k++) {
684         for (m = 0;  m < FIELD_BUFFER_SIZE/PAGE_SIZE;  m++) {
685                 if ((void *)NULL != peasycap->field_buffer[k][m].pgo) {
686                         free_page((unsigned long)\
687                                         (peasycap->field_buffer[k][m].pgo));
688                         peasycap->field_buffer[k][m].pgo = (void *)NULL;
689                         peasycap->allocation_video_page -= 1;
690                         lost++;
691                 }
692         }
693 }
694 JOT(4, "video field buffers freed: %i pages\n", lost);
695 /*---------------------------------------------------------------------------*/
696 JOT(4, "freeing video frame buffers.\n");
697 lost = 0;
698 for (k = 0;  k < FRAME_BUFFER_MANY;  k++) {
699         for (m = 0;  m < FRAME_BUFFER_SIZE/PAGE_SIZE;  m++) {
700                 if ((void *)NULL != peasycap->frame_buffer[k][m].pgo) {
701                         free_page((unsigned long)\
702                                         (peasycap->frame_buffer[k][m].pgo));
703                         peasycap->frame_buffer[k][m].pgo = (void *)NULL;
704                         peasycap->allocation_video_page -= 1;
705                         lost++;
706                 }
707         }
708 }
709 JOT(4, "video frame buffers freed: %i pages\n", lost);
710 /*---------------------------------------------------------------------------*/
711 /*
712  *  FREE AUDIO.
713  */
714 /*---------------------------------------------------------------------------*/
715 if ((struct list_head *)NULL != peasycap->purb_audio_head) {
716         JOT(4, "freeing audio urbs\n");
717         m = 0;
718         list_for_each(plist_head, (peasycap->purb_audio_head)) {
719                 pdata_urb = list_entry(plist_head, struct data_urb, list_head);
720                 if (NULL == pdata_urb)
721                         JOT(4, "ERROR: pdata_urb is NULL\n");
722                 else {
723                         if ((struct urb *)NULL != pdata_urb->purb) {
724                                 usb_free_urb(pdata_urb->purb);
725                                 pdata_urb->purb = (struct urb *)NULL;
726                                 peasycap->allocation_audio_urb -= 1;
727                                 m++;
728                         }
729                 }
730         }
731         JOT(4, "%i audio urbs freed\n", m);
732 /*---------------------------------------------------------------------------*/
733         JOT(4, "freeing audio data_urb structures.\n");
734         m = 0;
735         list_for_each_safe(plist_head, plist_next, peasycap->purb_audio_head) {
736                 pdata_urb = list_entry(plist_head, struct data_urb, list_head);
737                 if ((struct data_urb *)NULL != pdata_urb) {
738                         kfree(pdata_urb);  pdata_urb = (struct data_urb *)NULL;
739                         peasycap->allocation_audio_struct -= \
740                                                 sizeof(struct data_urb);
741                         m++;
742                 }
743         }
744 JOT(4, "%i audio data_urb structures freed\n", m);
745 JOT(4, "setting peasycap->purb_audio_head=NULL\n");
746 peasycap->purb_audio_head = (struct list_head *)NULL;
747 } else {
748 JOT(4, "peasycap->purb_audio_head is NULL\n");
749 }
750 /*---------------------------------------------------------------------------*/
751 JOT(4, "freeing audio isoc buffers.\n");
752 m = 0;
753 for (k = 0;  k < AUDIO_ISOC_BUFFER_MANY;  k++) {
754         if ((void *)NULL != peasycap->audio_isoc_buffer[k].pgo) {
755                 free_pages((unsigned long)\
756                                 (peasycap->audio_isoc_buffer[k].pgo), \
757                                 AUDIO_ISOC_ORDER);
758                 peasycap->audio_isoc_buffer[k].pgo = (void *)NULL;
759                 peasycap->allocation_audio_page -= \
760                                 ((unsigned int)(0x01 << AUDIO_ISOC_ORDER));
761                 m++;
762         }
763 }
764 JOT(4, "easysnd_delete(): isoc audio buffers freed: %i pages\n", \
765                                         m * (0x01 << AUDIO_ISOC_ORDER));
766 /*---------------------------------------------------------------------------*/
767 JOT(4, "freeing audio buffers.\n");
768 lost = 0;
769 for (k = 0;  k < peasycap->audio_buffer_page_many;  k++) {
770         if ((void *)NULL != peasycap->audio_buffer[k].pgo) {
771                 free_page((unsigned long)(peasycap->audio_buffer[k].pgo));
772                 peasycap->audio_buffer[k].pgo = (void *)NULL;
773                 peasycap->allocation_audio_page -= 1;
774                 lost++;
775         }
776 }
777 JOT(4, "easysnd_delete(): audio buffers freed: %i pages\n", lost);
778 /*---------------------------------------------------------------------------*/
779 JOT(4, "freeing easycap structure.\n");
780 allocation_video_urb    = peasycap->allocation_video_urb;
781 allocation_video_page   = peasycap->allocation_video_page;
782 allocation_video_struct = peasycap->allocation_video_struct;
783 registered_video        = peasycap->registered_video;
784 allocation_audio_urb    = peasycap->allocation_audio_urb;
785 allocation_audio_page   = peasycap->allocation_audio_page;
786 allocation_audio_struct = peasycap->allocation_audio_struct;
787 registered_audio        = peasycap->registered_audio;
788 m = 0;
789 if ((struct easycap *)NULL != peasycap) {
790         kfree(peasycap);  peasycap = (struct easycap *)NULL;
791         allocation_video_struct -= sizeof(struct easycap);
792         m++;
793 }
794 JOT(4, "%i easycap structure freed\n", m);
795 /*---------------------------------------------------------------------------*/
796
797 SAY("%8i= video urbs     after all deletions\n", allocation_video_urb);
798 SAY("%8i= video pages    after all deletions\n", allocation_video_page);
799 SAY("%8i= video structs  after all deletions\n", allocation_video_struct);
800 SAY("%8i= video devices  after all deletions\n", registered_video);
801 SAY("%8i= audio urbs     after all deletions\n", allocation_audio_urb);
802 SAY("%8i= audio pages    after all deletions\n", allocation_audio_page);
803 SAY("%8i= audio structs  after all deletions\n", allocation_audio_struct);
804 SAY("%8i= audio devices  after all deletions\n", registered_audio);
805
806 JOT(4, "ending.\n");
807 return;
808 }
809 /*****************************************************************************/
810 unsigned int easycap_poll(struct file *file, poll_table *wait)
811 {
812 struct easycap *peasycap;
813
814 JOT(8, "\n");
815
816 if (NULL == ((poll_table *)wait))
817         JOT(8, "WARNING:  poll table pointer is NULL ... continuing\n");
818 if (NULL == ((struct file *)file)) {
819         SAY("ERROR:  file pointer is NULL\n");
820         return -EFAULT;
821 }
822 peasycap = file->private_data;
823 if (NULL == peasycap) {
824         SAY("ERROR:  peasycap is NULL\n");
825         return -EFAULT;
826 }
827 peasycap->polled = 1;
828
829 if (0 == easycap_dqbuf(peasycap, 0))
830         return POLLIN | POLLRDNORM;
831 else
832         return POLLERR;
833
834 }
835 /*****************************************************************************/
836 /*---------------------------------------------------------------------------*/
837 /*
838  *  IF mode IS NONZERO THIS ROUTINE RETURNS -EAGAIN RATHER THAN BLOCKING.
839  */
840 /*---------------------------------------------------------------------------*/
841 int
842 easycap_dqbuf(struct easycap *peasycap, int mode)
843 {
844 int miss, rc;
845
846 JOT(8, "\n");
847
848 if (NULL == peasycap) {
849         SAY("ERROR:  peasycap is NULL\n");
850         return -EFAULT;
851 }
852 /*---------------------------------------------------------------------------*/
853 /*
854  *  WAIT FOR FIELD 0
855  */
856 /*---------------------------------------------------------------------------*/
857 miss = 0;
858 if (mutex_lock_interruptible(&(peasycap->mutex_mmap_video[0])))
859         return -ERESTARTSYS;
860 while ((peasycap->field_read == peasycap->field_fill) || \
861                                 (0 != (0xFF00 & peasycap->field_buffer\
862                                         [peasycap->field_read][0].kount)) || \
863                                 (0 != (0x00FF & peasycap->field_buffer\
864                                         [peasycap->field_read][0].kount))) {
865         mutex_unlock(&(peasycap->mutex_mmap_video[0]));
866
867         if (mode)
868                 return -EAGAIN;
869
870         JOT(8, "first wait  on wq_video, " \
871                                 "%i=field_read  %i=field_fill\n", \
872                                 peasycap->field_read, peasycap->field_fill);
873
874         msleep(1);
875         if (0 != (wait_event_interruptible(peasycap->wq_video, \
876                         (peasycap->video_idle || peasycap->video_eof  || \
877                         ((peasycap->field_read != peasycap->field_fill) && \
878                                 (0 == (0xFF00 & peasycap->field_buffer\
879                                         [peasycap->field_read][0].kount)) && \
880                                 (0 == (0x00FF & peasycap->field_buffer\
881                                         [peasycap->field_read][0].kount))))))){
882                 SAY("aborted by signal\n");
883                 return -EIO;
884                 }
885         if (peasycap->video_idle) {
886                 JOT(8, "%i=peasycap->video_idle\n", peasycap->video_idle);
887                 return -EIO;
888         }
889         if (peasycap->video_eof) {
890                 JOT(8, "%i=peasycap->video_eof\n", peasycap->video_eof);
891                 debrief(peasycap);
892                 kill_video_urbs(peasycap);
893                 return -EIO;
894         }
895 miss++;
896 if (mutex_lock_interruptible(&(peasycap->mutex_mmap_video[0])))
897         return -ERESTARTSYS;
898 }
899 mutex_unlock(&(peasycap->mutex_mmap_video[0]));
900 JOT(8, "first awakening on wq_video after %i waits\n", miss);
901
902 rc = field2frame(peasycap);
903 if (0 != rc)
904         SAY("ERROR: field2frame() returned %i\n", rc);
905
906 if (true == peasycap->offerfields) {
907         peasycap->frame_read = peasycap->frame_fill;
908         (peasycap->frame_fill)++;
909         if (peasycap->frame_buffer_many <= peasycap->frame_fill)
910                 peasycap->frame_fill = 0;
911
912         if (0x01 & easycap_standard[peasycap->standard_offset].mask) {
913                 peasycap->frame_buffer[peasycap->frame_read][0].kount = \
914                                                         V4L2_FIELD_BOTTOM;
915         } else {
916                 peasycap->frame_buffer[peasycap->frame_read][0].kount = \
917                                                         V4L2_FIELD_TOP;
918         }
919 JOT(8, "setting:    %i=peasycap->frame_read\n", peasycap->frame_read);
920 JOT(8, "bumped to:  %i=peasycap->frame_fill\n", peasycap->frame_fill);
921 }
922 /*---------------------------------------------------------------------------*/
923 /*
924  *  WAIT FOR FIELD 1
925  */
926 /*---------------------------------------------------------------------------*/
927 miss = 0;
928 if (mutex_lock_interruptible(&(peasycap->mutex_mmap_video[0])))
929         return -ERESTARTSYS;
930 while ((peasycap->field_read == peasycap->field_fill) || \
931                                 (0 != (0xFF00 & peasycap->field_buffer\
932                                         [peasycap->field_read][0].kount)) || \
933                                 (0 == (0x00FF & peasycap->field_buffer\
934                                         [peasycap->field_read][0].kount))) {
935         mutex_unlock(&(peasycap->mutex_mmap_video[0]));
936
937         if (mode)
938                 return -EAGAIN;
939
940         JOT(8, "second wait on wq_video, " \
941                                 "%i=field_read  %i=field_fill\n", \
942                                 peasycap->field_read, peasycap->field_fill);
943         msleep(1);
944         if (0 != (wait_event_interruptible(peasycap->wq_video, \
945                         (peasycap->video_idle || peasycap->video_eof  || \
946                         ((peasycap->field_read != peasycap->field_fill) && \
947                                 (0 == (0xFF00 & peasycap->field_buffer\
948                                         [peasycap->field_read][0].kount)) && \
949                                 (0 != (0x00FF & peasycap->field_buffer\
950                                         [peasycap->field_read][0].kount))))))){
951                 SAY("aborted by signal\n");
952                 return -EIO;
953         }
954         if (peasycap->video_idle) {
955                 JOT(8, "%i=peasycap->video_idle\n", peasycap->video_idle);
956                 return -EIO;
957         }
958         if (peasycap->video_eof) {
959                 JOT(8, "%i=peasycap->video_eof\n", peasycap->video_eof);
960                 debrief(peasycap);
961                 kill_video_urbs(peasycap);
962                 return -EIO;
963         }
964 miss++;
965 if (mutex_lock_interruptible(&(peasycap->mutex_mmap_video[0])))
966         return -ERESTARTSYS;
967 }
968 mutex_unlock(&(peasycap->mutex_mmap_video[0]));
969 JOT(8, "second awakening on wq_video after %i waits\n", miss);
970
971 rc = field2frame(peasycap);
972 if (0 != rc)
973         SAY("ERROR: field2frame() returned %i\n", rc);
974
975 peasycap->frame_read = peasycap->frame_fill;
976 peasycap->queued[peasycap->frame_read] = 0;
977 peasycap->done[peasycap->frame_read]   = V4L2_BUF_FLAG_DONE;
978
979 (peasycap->frame_fill)++;
980 if (peasycap->frame_buffer_many <= peasycap->frame_fill)
981         peasycap->frame_fill = 0;
982
983 if (0x01 & easycap_standard[peasycap->standard_offset].mask) {
984         peasycap->frame_buffer[peasycap->frame_read][0].kount = \
985                                                         V4L2_FIELD_TOP;
986 } else {
987         peasycap->frame_buffer[peasycap->frame_read][0].kount = \
988                                                         V4L2_FIELD_BOTTOM;
989 }
990
991 JOT(8, "setting:    %i=peasycap->frame_read\n", peasycap->frame_read);
992 JOT(8, "bumped to:  %i=peasycap->frame_fill\n", peasycap->frame_fill);
993
994 return 0;
995 }
996 /*****************************************************************************/
997 /*---------------------------------------------------------------------------*/
998 /*
999  *  BY DEFINITION, odd IS true  FOR THE FIELD OCCUPYING LINES 1,3,5,...,479
1000  *                 odd IS false FOR THE FIELD OCCUPYING LINES 0,2,4,...,478
1001  *
1002  *  WHEN BOOLEAN PARAMETER decimatepixel IS true, ONLY THE FIELD FOR WHICH
1003  *  odd==false IS TRANSFERRED TO THE FRAME BUFFER.
1004  *
1005  *  THE BOOLEAN PARAMETER offerfields IS true ONLY WHEN THE USER PROGRAM
1006  *  CHOOSES THE OPTION V4L2_FIELD_ALTERNATE.  NO USERSPACE PROGRAM TESTED
1007  *  TO DATE HAS DONE THIS.  BUGS ARE LIKELY.
1008  */
1009 /*---------------------------------------------------------------------------*/
1010 int
1011 field2frame(struct easycap *peasycap)
1012 {
1013 static struct timeval timeval0;
1014 struct timeval timeval;
1015 long long int above, below;
1016 __u32 remainder;
1017 struct signed_div_result sdr;
1018
1019 void *pex, *pad;
1020 int kex, kad, mex, mad, rex, rad, rad2;
1021 int c2, c3, w2, w3, cz, wz;
1022 int rc, bytesperpixel, multiplier, much, more, over, rump, caches;
1023 __u8 mask, margin;
1024 bool odd, isuy, decimatepixel, offerfields;
1025
1026 JOT(8, "=====  parity %i, field buffer %i --> frame buffer %i\n", \
1027                         peasycap->field_buffer[peasycap->field_read][0].kount,\
1028                         peasycap->field_read, peasycap->frame_fill);
1029 JOT(8, "=====  %i=bytesperpixel\n", peasycap->bytesperpixel);
1030 if (true == peasycap->offerfields)
1031         JOT(8, "===== offerfields\n");
1032
1033 /*---------------------------------------------------------------------------*/
1034 /*
1035  *  REJECT OR CLEAN BAD FIELDS
1036  */
1037 /*---------------------------------------------------------------------------*/
1038 if (peasycap->field_read == peasycap->field_fill) {
1039         SAY("ERROR: on entry, still filling field buffer %i\n", \
1040                                                         peasycap->field_read);
1041         return 0;
1042 }
1043 #if defined(EASYCAP_TESTCARD)
1044 easycap_testcard(peasycap, peasycap->field_read);
1045 #else
1046 if (0 != (0x0400 & peasycap->field_buffer[peasycap->field_read][0].kount))
1047         easycap_testcard(peasycap, peasycap->field_read);
1048 #endif /*EASYCAP_TESTCARD*/
1049 /*---------------------------------------------------------------------------*/
1050
1051 offerfields = peasycap->offerfields;
1052 bytesperpixel = peasycap->bytesperpixel;
1053 decimatepixel = peasycap->decimatepixel;
1054
1055 if ((2 != bytesperpixel) && \
1056                         (3 != bytesperpixel) && \
1057                         (4 != bytesperpixel)) {
1058         SAY("MISTAKE: %i=bytesperpixel\n", bytesperpixel);
1059         return -EFAULT;
1060 }
1061 if (true == decimatepixel)
1062         multiplier = 2;
1063 else
1064         multiplier = 1;
1065
1066 w2 = 2 * multiplier * (peasycap->width);
1067 w3 = bytesperpixel * \
1068                 multiplier * \
1069                 (peasycap->width);
1070 wz = multiplier * \
1071                 (peasycap->height) * \
1072                 multiplier * \
1073                 (peasycap->width);
1074
1075 kex = peasycap->field_read;  mex = 0;
1076 kad = peasycap->frame_fill;  mad = 0;
1077
1078 pex = peasycap->field_buffer[kex][0].pgo;  rex = PAGE_SIZE;
1079 pad = peasycap->frame_buffer[kad][0].pgo;  rad = PAGE_SIZE;
1080 if (peasycap->field_buffer[kex][0].kount)
1081         odd = true;
1082 else
1083         odd = false;
1084
1085 if ((true == odd) && (false == offerfields) &&(false == decimatepixel)) {
1086         JOT(8, "  initial skipping    %4i          bytes p.%4i\n", \
1087                                                         w3/multiplier, mad);
1088         pad += (w3 / multiplier);  rad -= (w3 / multiplier);
1089 }
1090 isuy = true;
1091 mask = 0;  rump = 0;  caches = 0;
1092
1093 cz = 0;
1094 while (cz < wz) {
1095         /*-------------------------------------------------------------------*/
1096         /*
1097         **  PROCESS ONE LINE OF FRAME AT FULL RESOLUTION:
1098         **  READ   w2   BYTES FROM FIELD BUFFER,
1099         **  WRITE  w3   BYTES TO FRAME BUFFER
1100         **/
1101         /*-------------------------------------------------------------------*/
1102         if (false == decimatepixel) {
1103                 over = w2;
1104                 do {
1105                         much = over;  more = 0;  margin = 0;  mask = 0x00;
1106                         if (rex < much)
1107                                 much = rex;
1108                         rump = 0;
1109
1110                         if (much % 2) {
1111                                 SAY("MISTAKE: much is odd\n");
1112                                 return -EFAULT;
1113                         }
1114
1115                         more = (bytesperpixel * \
1116                                         much) / 2;
1117 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1118                         if (1 < bytesperpixel) {
1119                                 if ((rad * \
1120                                         2) < (much * \
1121                                                 bytesperpixel)) {
1122                                         /*
1123                                         **   INJUDICIOUS ALTERATION OF THIS
1124                                         **   BLOCK WILL CAUSE BREAKAGE.
1125                                         **   BEWARE.
1126                                         **/
1127                                         rad2 = rad + bytesperpixel - 1;
1128                                         much = ((((2 * \
1129                                                 rad2)/bytesperpixel)/2) * 2);
1130                                         rump = ((bytesperpixel * \
1131                                                         much) / 2) - rad;
1132                                         more = rad;
1133                                         }
1134                                 mask = (__u8)rump;
1135                                 margin = 0;
1136                                 if (much == rex) {
1137                                         mask |= 0x04;
1138                                         if ((mex + 1) < FIELD_BUFFER_SIZE/ \
1139                                                                 PAGE_SIZE) {
1140                                                 margin = *((__u8 *)(peasycap->\
1141                                                         field_buffer\
1142                                                         [kex][mex + 1].pgo));
1143                                         } else
1144                                                 mask |= 0x08;
1145                                 }
1146 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1147                         } else {
1148                                 SAY("MISTAKE: %i=bytesperpixel\n", \
1149                                                 bytesperpixel);
1150                                 return -EFAULT;
1151                         }
1152 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1153                         if (rump)
1154                                 caches++;
1155
1156                         rc = redaub(peasycap, pad, pex, much, more, \
1157                                                         mask, margin, isuy);
1158                         if (0 > rc) {
1159                                 SAY("ERROR: redaub() failed\n");
1160                                 return -EFAULT;
1161                         }
1162                         if (much % 4) {
1163                                 if (isuy)
1164                                         isuy = false;
1165                                 else
1166                                         isuy = true;
1167                         }
1168                         over -= much;   cz += much;
1169                         pex  += much;  rex -= much;
1170                         if (!rex) {
1171                                 mex++;
1172                                 pex = peasycap->field_buffer[kex][mex].pgo;
1173                                 rex = PAGE_SIZE;
1174                         }
1175                         pad  += more;
1176                         rad -= more;
1177                         if (!rad) {
1178                                 mad++;
1179                                 pad = peasycap->frame_buffer[kad][mad].pgo;
1180                                 rad = PAGE_SIZE;
1181                                 if (rump) {
1182                                         pad += rump;
1183                                         rad -= rump;
1184                                 }
1185                         }
1186                 } while (over);
1187 /*---------------------------------------------------------------------------*/
1188 /*
1189  *  SKIP  w3 BYTES IN TARGET FRAME BUFFER,
1190  *  UNLESS IT IS THE LAST LINE OF AN ODD FRAME
1191  */
1192 /*---------------------------------------------------------------------------*/
1193                 if (((false == odd) || (cz != wz))&&(false == offerfields)) {
1194                         over = w3;
1195                         do {
1196                                 if (!rad) {
1197                                         mad++;
1198                                         pad = peasycap->frame_buffer\
1199                                                 [kad][mad].pgo;
1200                                         rad = PAGE_SIZE;
1201                                 }
1202                                 more = over;
1203                                 if (rad < more)
1204                                         more = rad;
1205                                 over -= more;
1206                                 pad  += more;
1207                                 rad  -= more;
1208                         } while (over);
1209                 }
1210 /*---------------------------------------------------------------------------*/
1211 /*
1212  *  PROCESS ONE LINE OF FRAME AT REDUCED RESOLUTION:
1213  *  ONLY IF false==odd,
1214  *  READ   w2   BYTES FROM FIELD BUFFER,
1215  *  WRITE  w3 / 2  BYTES TO FRAME BUFFER
1216  */
1217 /*---------------------------------------------------------------------------*/
1218         } else if (false == odd) {
1219                 over = w2;
1220                 do {
1221                         much = over;  more = 0;  margin = 0;  mask = 0x00;
1222                         if (rex < much)
1223                                 much = rex;
1224                         rump = 0;
1225
1226                         if (much % 2) {
1227                                 SAY("MISTAKE: much is odd\n");
1228                                 return -EFAULT;
1229                         }
1230
1231                         more = (bytesperpixel * \
1232                                         much) / 4;
1233 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1234                         if (1 < bytesperpixel) {
1235                                 if ((rad * 4) < (much * \
1236                                                 bytesperpixel)) {
1237                                         /*
1238                                         **   INJUDICIOUS ALTERATION OF THIS
1239                                         **   BLOCK WILL CAUSE BREAKAGE.
1240                                         **   BEWARE.
1241                                         **/
1242                                         rad2 = rad + bytesperpixel - 1;
1243                                         much = ((((2 * rad2)/bytesperpixel)/2)\
1244                                                                         * 4);
1245                                         rump = ((bytesperpixel * \
1246                                                         much) / 4) - rad;
1247                                         more = rad;
1248                                         }
1249                                 mask = (__u8)rump;
1250                                 margin = 0;
1251                                 if (much == rex) {
1252                                         mask |= 0x04;
1253                                         if ((mex + 1) < FIELD_BUFFER_SIZE/ \
1254                                                                 PAGE_SIZE) {
1255                                                 margin = *((__u8 *)(peasycap->\
1256                                                         field_buffer\
1257                                                         [kex][mex + 1].pgo));
1258                                                 }
1259                                         else
1260                                                 mask |= 0x08;
1261                                         }
1262 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1263                                 } else {
1264                                         SAY("MISTAKE: %i=bytesperpixel\n", \
1265                                                 bytesperpixel);
1266                                         return -EFAULT;
1267                                 }
1268 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1269                         if (rump)
1270                                 caches++;
1271
1272                         rc = redaub(peasycap, pad, pex, much, more, \
1273                                                         mask, margin, isuy);
1274                         if (0 > rc) {
1275                                 SAY("ERROR: redaub() failed\n");
1276                                 return -EFAULT;
1277                         }
1278                         over -= much;   cz += much;
1279                         pex  += much;  rex -= much;
1280                         if (!rex) {
1281                                 mex++;
1282                                 pex = peasycap->field_buffer[kex][mex].pgo;
1283                                 rex = PAGE_SIZE;
1284                         }
1285                         pad  += more;
1286                         rad -= more;
1287                         if (!rad) {
1288                                 mad++;
1289                                 pad = peasycap->frame_buffer[kad][mad].pgo;
1290                                 rad = PAGE_SIZE;
1291                                 if (rump) {
1292                                         pad += rump;
1293                                         rad -= rump;
1294                                 }
1295                         }
1296                 } while (over);
1297 /*---------------------------------------------------------------------------*/
1298 /*
1299  *  OTHERWISE JUST
1300  *  READ   w2   BYTES FROM FIELD BUFFER AND DISCARD THEM
1301  */
1302 /*---------------------------------------------------------------------------*/
1303         } else {
1304                 over = w2;
1305                 do {
1306                         if (!rex) {
1307                                 mex++;
1308                                 pex = peasycap->field_buffer[kex][mex].pgo;
1309                                 rex = PAGE_SIZE;
1310                         }
1311                         much = over;
1312                         if (rex < much)
1313                                 much = rex;
1314                         over -= much;
1315                         cz += much;
1316                         pex  += much;
1317                         rex -= much;
1318                 } while (over);
1319         }
1320 }
1321 /*---------------------------------------------------------------------------*/
1322 /*
1323  *  SANITY CHECKS
1324  */
1325 /*---------------------------------------------------------------------------*/
1326 c2 = (mex + 1)*PAGE_SIZE - rex;
1327 if (cz != c2)
1328         SAY("ERROR: discrepancy %i in bytes read\n", c2 - cz);
1329 c3 = (mad + 1)*PAGE_SIZE - rad;
1330
1331 if (false == decimatepixel) {
1332         if (bytesperpixel * \
1333                 cz != c3) \
1334                 SAY("ERROR: discrepancy %i in bytes written\n", \
1335                                                 c3 - (bytesperpixel * \
1336                                                                         cz));
1337 } else {
1338         if (false == odd) {
1339                 if (bytesperpixel * \
1340                         cz != (4 * c3))
1341                         SAY("ERROR: discrepancy %i in bytes written\n", \
1342                                                 (2*c3)-(bytesperpixel * \
1343                                                                         cz));
1344                 } else {
1345                         if (0 != c3)
1346                                 SAY("ERROR: discrepancy %i " \
1347                                                 "in bytes written\n", c3);
1348                 }
1349 }
1350 if (rump)
1351         SAY("ERROR: undischarged cache at end of line in frame buffer\n");
1352
1353 JOT(8, "===== field2frame(): %i bytes --> %i bytes (incl skip)\n", c2, c3);
1354 JOT(8, "===== field2frame(): %i=mad  %i=rad\n", mad, rad);
1355
1356 if (true == odd)
1357         JOT(8, "+++++ field2frame():  frame buffer %i is full\n", kad);
1358
1359 if (peasycap->field_read == peasycap->field_fill)
1360         SAY("WARNING: on exit, filling field buffer %i\n", \
1361                                                         peasycap->field_read);
1362 /*---------------------------------------------------------------------------*/
1363 /*
1364  *  CALCULATE VIDEO STREAMING RATE
1365  */
1366 /*---------------------------------------------------------------------------*/
1367 do_gettimeofday(&timeval);
1368 if (timeval0.tv_sec) {
1369         below = ((long long int)(1000000)) * \
1370                 ((long long int)(timeval.tv_sec  - timeval0.tv_sec)) + \
1371                          (long long int)(timeval.tv_usec - timeval0.tv_usec);
1372         above = (long long int)1000000;
1373
1374         sdr = signed_div(above, below);
1375         above = sdr.quotient;
1376         remainder = (__u32)sdr.remainder;
1377
1378         JOT(8, "video streaming at %3lli.%03i fields per second\n", above, \
1379                                                         (remainder/1000));
1380 }
1381 timeval0 = timeval;
1382
1383 if (caches)
1384         JOT(8, "%i=caches\n", caches);
1385 return 0;
1386 }
1387 /*****************************************************************************/
1388 struct signed_div_result
1389 signed_div(long long int above, long long int below)
1390 {
1391 struct signed_div_result sdr;
1392
1393 if (((0 <= above) && (0 <= below)) || ((0  > above) && (0  > below))) {
1394         sdr.remainder = (unsigned long long int) do_div(above, below);
1395         sdr.quotient  = (long long int) above;
1396 } else {
1397         if (0 > above)
1398                 above = -above;
1399         if (0 > below)
1400                 below = -below;
1401         sdr.remainder = (unsigned long long int) do_div(above, below);
1402         sdr.quotient  = -((long long int) above);
1403 }
1404 return sdr;
1405 }
1406 /*****************************************************************************/
1407 /*---------------------------------------------------------------------------*/
1408 /*
1409  *  DECIMATION AND COLOURSPACE CONVERSION.
1410  *
1411  *  THIS ROUTINE REQUIRES THAT ALL THE DATA TO BE READ RESIDES ON ONE PAGE
1412  *  AND THAT ALL THE DATA TO BE WRITTEN RESIDES ON ONE (DIFFERENT) PAGE.
1413  *  THE CALLING ROUTINE MUST ENSURE THAT THIS REQUIREMENT IS MET, AND MUST
1414  *  ALSO ENSURE THAT much IS EVEN.
1415  *
1416  *  much BYTES ARE READ, AT LEAST (bytesperpixel * much)/2 BYTES ARE WRITTEN
1417  *  IF THERE IS NO DECIMATION, HALF THIS AMOUNT IF THERE IS DECIMATION.
1418  *
1419  *  mask IS ZERO WHEN NO SPECIAL BEHAVIOUR REQUIRED. OTHERWISE IT IS SET THUS:
1420  *     0x03 & mask =  number of bytes to be written to cache instead of to
1421  *                    frame buffer
1422  *     0x04 & mask => use argument margin to set the chrominance for last pixel
1423  *     0x08 & mask => do not set the chrominance for last pixel
1424  *
1425  *  YUV to RGB CONVERSION IS (OR SHOULD BE) ITU-R BT 601.
1426  *
1427  *  THERE IS A LOT OF CODE REPETITION IN THIS ROUTINE IN ORDER TO AVOID
1428  *  INEFFICIENT SWITCHING INSIDE INNER LOOPS.  REARRANGING THE LOGIC TO
1429  *  REDUCE CODE LENGTH WILL GENERALLY IMPAIR RUNTIME PERFORMANCE.  BEWARE.
1430  */
1431 /*---------------------------------------------------------------------------*/
1432 int
1433 redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, \
1434                                         __u8 mask, __u8 margin, bool isuy)
1435 {
1436 static __s32 ay[256], bu[256], rv[256], gu[256], gv[256];
1437 static __u8 cache[8], *pcache;
1438 __u8 r, g, b, y, u, v, c, *p2, *p3, *pz, *pr;
1439 int  bytesperpixel;
1440 bool byteswaporder, decimatepixel, last;
1441 int j, rump;
1442 __s32 s32;
1443
1444 if (much % 2) {
1445         SAY("MISTAKE: much is odd\n");
1446         return -EFAULT;
1447 }
1448 bytesperpixel = peasycap->bytesperpixel;
1449 byteswaporder = peasycap->byteswaporder;
1450 decimatepixel = peasycap->decimatepixel;
1451
1452 /*---------------------------------------------------------------------------*/
1453 if (!bu[255]) {
1454         for (j = 0; j < 112; j++) {
1455                 s32 = (0xFF00 & (453 * j)) >> 8;
1456                 bu[j + 128] =  s32; bu[127 - j] = -s32;
1457                 s32 = (0xFF00 & (359 * j)) >> 8;
1458                 rv[j + 128] =  s32; rv[127 - j] = -s32;
1459                 s32 = (0xFF00 & (88 * j)) >> 8;
1460                 gu[j + 128] =  s32; gu[127 - j] = -s32;
1461                 s32 = (0xFF00 & (183 * j)) >> 8;
1462                 gv[j + 128] =  s32; gv[127 - j] = -s32;
1463         }
1464         for (j = 0; j < 16; j++) {
1465                 bu[j] = bu[16]; rv[j] = rv[16];
1466                 gu[j] = gu[16]; gv[j] = gv[16];
1467         }
1468         for (j = 240; j < 256; j++) {
1469                 bu[j] = bu[239]; rv[j] = rv[239];
1470                 gu[j] = gu[239]; gv[j] = gv[239];
1471         }
1472         for (j =  16; j < 236; j++)
1473                 ay[j] = j;
1474         for (j =   0; j <  16; j++)
1475                 ay[j] = ay[16];
1476         for (j = 236; j < 256; j++)
1477                 ay[j] = ay[235];
1478         JOT(8, "lookup tables are prepared\n");
1479 }
1480 if ((__u8 *)NULL == pcache)
1481         pcache = &cache[0];
1482 /*---------------------------------------------------------------------------*/
1483 /*
1484  *  TRANSFER CONTENTS OF CACHE TO THE FRAME BUFFER
1485  */
1486 /*---------------------------------------------------------------------------*/
1487 if (!pcache) {
1488         SAY("MISTAKE: pcache is NULL\n");
1489         return -EFAULT;
1490 }
1491
1492 if (pcache != &cache[0])
1493         JOT(16, "cache has %i bytes\n", (int)(pcache - &cache[0]));
1494 p2 = &cache[0];
1495 p3 = (__u8 *)pad - (int)(pcache - &cache[0]);
1496 while (p2 < pcache) {
1497         *p3++ = *p2;  p2++;
1498 }
1499 pcache = &cache[0];
1500 if (p3 != pad) {
1501         SAY("MISTAKE: pointer misalignment\n");
1502         return -EFAULT;
1503 }
1504 /*---------------------------------------------------------------------------*/
1505 rump = (int)(0x03 & mask);
1506 u = 0; v = 0;
1507 p2 = (__u8 *)pex;  pz = p2 + much;  pr = p3 + more;  last = false;
1508 p2++;
1509
1510 if (true == isuy)
1511         u = *(p2 - 1);
1512 else
1513         v = *(p2 - 1);
1514
1515 if (rump)
1516         JOT(16, "%4i=much  %4i=more  %i=rump\n", much, more, rump);
1517
1518 /*---------------------------------------------------------------------------*/
1519 switch (bytesperpixel) {
1520 case 2: {
1521         if (false == decimatepixel) {
1522                 memcpy(pad, pex, (size_t)much);
1523                 if (false == byteswaporder)
1524                         /*---------------------------------------------------*/
1525                         /*
1526                         **  UYVY
1527                         */
1528                         /*---------------------------------------------------*/
1529                         return 0;
1530                 else {
1531                         /*---------------------------------------------------*/
1532                         /*
1533                         **  YUYV
1534                         */
1535                         /*---------------------------------------------------*/
1536                         p3 = (__u8 *)pad;  pz = p3 + much;
1537                         while  (pz > p3) {
1538                                 c = *p3;
1539                                 *p3 = *(p3 + 1);
1540                                 *(p3 + 1) = c;
1541                                 p3 += 2;
1542                         }
1543                         return 0;
1544                 }
1545         } else {
1546                 if (false == byteswaporder) {
1547                         /*---------------------------------------------------*/
1548                         /*
1549                         **  UYVY DECIMATED
1550                         */
1551                         /*---------------------------------------------------*/
1552                         p2 = (__u8 *)pex;  p3 = (__u8 *)pad;  pz = p2 + much;
1553                         while (pz > p2) {
1554                                 *p3 = *p2;
1555                                 *(p3 + 1) = *(p2 + 1);
1556                                 *(p3 + 2) = *(p2 + 2);
1557                                 *(p3 + 3) = *(p2 + 3);
1558                                 p3 += 4;  p2 += 8;
1559                         }
1560                         return 0;
1561                 } else {
1562                         /*---------------------------------------------------*/
1563                         /*
1564                         **  YUYV DECIMATED
1565                         **/
1566                         /*---------------------------------------------------*/
1567                         p2 = (__u8 *)pex;  p3 = (__u8 *)pad;  pz = p2 + much;
1568                         while (pz > p2) {
1569                                 *p3 = *(p2 + 1);
1570                                 *(p3 + 1) = *p2;
1571                                 *(p3 + 2) = *(p2 + 3);
1572                                 *(p3 + 3) = *(p2 + 2);
1573                                 p3 += 4;  p2 += 8;
1574                         }
1575                         return 0;
1576                 }
1577         }
1578         break;
1579         }
1580 case 3:
1581         {
1582         if (false == decimatepixel) {
1583                 if (false == byteswaporder) {
1584                         /*---------------------------------------------------*/
1585                         /*
1586                         **  RGB
1587                         **/
1588                         /*---------------------------------------------------*/
1589                         while (pz > p2) {
1590                                 if (pr <= (p3 + bytesperpixel))
1591                                         last = true;
1592                                 else
1593                                         last = false;
1594                                 y = *p2;
1595                                 if ((true == last) && (0x0C & mask)) {
1596                                         if (0x04 & mask) {
1597                                                 if (true == isuy)
1598                                                         v = margin;
1599                                                 else
1600                                                         u = margin;
1601                                         } else
1602                                                 if (0x08 & mask)
1603                                                         ;
1604                                 } else {
1605                                         if (true == isuy)
1606                                                 v = *(p2 + 1);
1607                                         else
1608                                                 u = *(p2 + 1);
1609                                 }
1610
1611                                 s32 = ay[(int)y] + rv[(int)v];
1612                                 r = (255 < s32) ? 255 : ((0 > s32) ? \
1613                                                         0 : (__u8)s32);
1614                                 s32 = ay[(int)y] - gu[(int)u] - gv[(int)v];
1615                                 g = (255 < s32) ? 255 : ((0 > s32) ? \
1616                                                         0 : (__u8)s32);
1617                                 s32 = ay[(int)y] + bu[(int)u];
1618                                 b = (255 < s32) ? 255 : ((0 > s32) ? \
1619                                                         0 : (__u8)s32);
1620
1621                                 if ((true == last) && rump) {
1622                                         pcache = &cache[0];
1623                                         switch (bytesperpixel - rump) {
1624                                         case 1: {
1625                                                 *p3 = r;
1626                                                 *pcache++ = g;
1627                                                 *pcache++ = b;
1628                                                 break;
1629                                         }
1630                                         case 2: {
1631                                                 *p3 = r;
1632                                                 *(p3 + 1) = g;
1633                                                 *pcache++ = b;
1634                                                 break;
1635                                         }
1636                                         default: {
1637                                                 SAY("MISTAKE: %i=rump\n", \
1638                                                         bytesperpixel - rump);
1639                                                 return -EFAULT;
1640                                         }
1641                                         }
1642                                 } else {
1643                                         *p3 = r;
1644                                         *(p3 + 1) = g;
1645                                         *(p3 + 2) = b;
1646                                 }
1647                                 p2 += 2;
1648                                 if (true == isuy)
1649                                         isuy = false;
1650                                 else
1651                                         isuy = true;
1652                                 p3 += bytesperpixel;
1653                         }
1654                         return 0;
1655                 } else {
1656                         /*---------------------------------------------------*/
1657                         /*
1658                         **  BGR
1659                         */
1660                         /*---------------------------------------------------*/
1661                         while (pz > p2) {
1662                                 if (pr <= (p3 + bytesperpixel))
1663                                         last = true;
1664                                 else
1665                                         last = false;
1666                                 y = *p2;
1667                                 if ((true == last) && (0x0C & mask)) {
1668                                         if (0x04 & mask) {
1669                                                 if (true == isuy)
1670                                                         v = margin;
1671                                                 else
1672                                                         u = margin;
1673                                         }
1674                                 else
1675                                         if (0x08 & mask)
1676                                                 ;
1677                                 } else {
1678                                         if (true == isuy)
1679                                                 v = *(p2 + 1);
1680                                         else
1681                                                 u = *(p2 + 1);
1682                                 }
1683
1684                                 s32 = ay[(int)y] + rv[(int)v];
1685                                 r = (255 < s32) ? 255 : ((0 > s32) ? \
1686                                                                 0 : (__u8)s32);
1687                                 s32 = ay[(int)y] - gu[(int)u] - gv[(int)v];
1688                                 g = (255 < s32) ? 255 : ((0 > s32) ? \
1689                                                                 0 : (__u8)s32);
1690                                 s32 = ay[(int)y] + bu[(int)u];
1691                                 b = (255 < s32) ? 255 : ((0 > s32) ? \
1692                                                                 0 : (__u8)s32);
1693
1694                                 if ((true == last) && rump) {
1695                                         pcache = &cache[0];
1696                                         switch (bytesperpixel - rump) {
1697                                         case 1: {
1698                                                 *p3 = b;
1699                                                 *pcache++ = g;
1700                                                 *pcache++ = r;
1701                                                 break;
1702                                         }
1703                                         case 2: {
1704                                                 *p3 = b;
1705                                                 *(p3 + 1) = g;
1706                                                 *pcache++ = r;
1707                                                 break;
1708                                         }
1709                                         default: {
1710                                                 SAY("MISTAKE: %i=rump\n", \
1711                                                         bytesperpixel - rump);
1712                                                 return -EFAULT;
1713                                         }
1714                                         }
1715                                 } else {
1716                                         *p3 = b;
1717                                         *(p3 + 1) = g;
1718                                         *(p3 + 2) = r;
1719                                         }
1720                                 p2 += 2;
1721                                 if (true == isuy)
1722                                         isuy = false;
1723                                 else
1724                                         isuy = true;
1725                                 p3 += bytesperpixel;
1726                                 }
1727                         }
1728                 return 0;
1729         } else {
1730                 if (false == byteswaporder) {
1731                         /*---------------------------------------------------*/
1732                         /*
1733                         **  RGB DECIMATED
1734                         */
1735                         /*---------------------------------------------------*/
1736                         while (pz > p2) {
1737                                 if (pr <= (p3 + bytesperpixel))
1738                                         last = true;
1739                                 else
1740                                         last = false;
1741                                 y = *p2;
1742                                 if ((true == last) && (0x0C & mask)) {
1743                                         if (0x04 & mask) {
1744                                                 if (true == isuy)
1745                                                         v = margin;
1746                                                 else
1747                                                         u = margin;
1748                                         } else
1749                                                 if (0x08 & mask)
1750                                                         ;
1751                                 } else {
1752                                         if (true == isuy)
1753                                                 v = *(p2 + 1);
1754                                         else
1755                                                 u = *(p2 + 1);
1756                                 }
1757
1758                                 if (true == isuy) {
1759                                         s32 = ay[(int)y] + rv[(int)v];
1760                                         r = (255 < s32) ? 255 : ((0 > s32) ? \
1761                                                                 0 : (__u8)s32);
1762                                         s32 = ay[(int)y] - gu[(int)u] - \
1763                                                                 gv[(int)v];
1764                                         g = (255 < s32) ? 255 : ((0 > s32) ? \
1765                                                                 0 : (__u8)s32);
1766                                         s32 = ay[(int)y] + bu[(int)u];
1767                                         b = (255 < s32) ? 255 : ((0 > s32) ? \
1768                                                                 0 : (__u8)s32);
1769
1770                                         if ((true == last) && rump) {
1771                                                 pcache = &cache[0];
1772                                                 switch (bytesperpixel - rump) {
1773                                                 case 1: {
1774                                                         *p3 = r;
1775                                                         *pcache++ = g;
1776                                                         *pcache++ = b;
1777                                                         break;
1778                                                 }
1779                                                 case 2: {
1780                                                         *p3 = r;
1781                                                         *(p3 + 1) = g;
1782                                                         *pcache++ = b;
1783                                                         break;
1784                                                 }
1785                                                 default: {
1786                                                         SAY("MISTAKE: " \
1787                                                         "%i=rump\n", \
1788                                                         bytesperpixel - rump);
1789                                                         return -EFAULT;
1790                                                 }
1791                                                 }
1792                                         } else {
1793                                                 *p3 = r;
1794                                                 *(p3 + 1) = g;
1795                                                 *(p3 + 2) = b;
1796                                         }
1797                                         isuy = false;
1798                                         p3 += bytesperpixel;
1799                                 } else {
1800                                         isuy = true;
1801                                 }
1802                                 p2 += 2;
1803                         }
1804                         return 0;
1805                 } else {
1806                         /*---------------------------------------------------*/
1807                         /*
1808                          *  BGR DECIMATED
1809                          */
1810                         /*---------------------------------------------------*/
1811                         while (pz > p2) {
1812                                 if (pr <= (p3 + bytesperpixel))
1813                                         last = true;
1814                                 else
1815                                         last = false;
1816                                 y = *p2;
1817                                 if ((true == last) && (0x0C & mask)) {
1818                                         if (0x04 & mask) {
1819                                                 if (true == isuy)
1820                                                         v = margin;
1821                                                 else
1822                                                         u = margin;
1823                                         } else
1824                                                 if (0x08 & mask)
1825                                                         ;
1826                                 } else {
1827                                         if (true == isuy)
1828                                                 v = *(p2 + 1);
1829                                         else
1830                                                 u = *(p2 + 1);
1831                                 }
1832
1833                                 if (true == isuy) {
1834
1835                                         s32 = ay[(int)y] + rv[(int)v];
1836                                         r = (255 < s32) ? 255 : ((0 > s32) ? \
1837                                                                 0 : (__u8)s32);
1838                                         s32 = ay[(int)y] - gu[(int)u] - \
1839                                                                 gv[(int)v];
1840                                         g = (255 < s32) ? 255 : ((0 > s32) ? \
1841                                                                 0 : (__u8)s32);
1842                                         s32 = ay[(int)y] + bu[(int)u];
1843                                         b = (255 < s32) ? 255 : ((0 > s32) ? \
1844                                                                 0 : (__u8)s32);
1845
1846                                         if ((true == last) && rump) {
1847                                                 pcache = &cache[0];
1848                                                 switch (bytesperpixel - rump) {
1849                                                 case 1: {
1850                                                         *p3 = b;
1851                                                         *pcache++ = g;
1852                                                         *pcache++ = r;
1853                                                         break;
1854                                                 }
1855                                                 case 2: {
1856                                                         *p3 = b;
1857                                                         *(p3 + 1) = g;
1858                                                         *pcache++ = r;
1859                                                         break;
1860                                                 }
1861                                                 default: {
1862                                                         SAY("MISTAKE: " \
1863                                                         "%i=rump\n", \
1864                                                         bytesperpixel - rump);
1865                                                         return -EFAULT;
1866                                                 }
1867                                                 }
1868                                         } else {
1869                                                 *p3 = b;
1870                                                 *(p3 + 1) = g;
1871                                                 *(p3 + 2) = r;
1872                                                 }
1873                                         isuy = false;
1874                                         p3 += bytesperpixel;
1875                                         }
1876                                 else
1877                                         isuy = true;
1878                                 p2 += 2;
1879                                 }
1880                         return 0;
1881                         }
1882                 }
1883         break;
1884         }
1885 case 4:
1886         {
1887         if (false == decimatepixel) {
1888                 if (false == byteswaporder) {
1889                         /*---------------------------------------------------*/
1890                         /*
1891                         **  RGBA
1892                         */
1893                         /*---------------------------------------------------*/
1894                         while (pz > p2) {
1895                                 if (pr <= (p3 + bytesperpixel))
1896                                         last = true;
1897                                 else
1898                                         last = false;
1899                                 y = *p2;
1900                                 if ((true == last) && (0x0C & mask)) {
1901                                         if (0x04 & mask) {
1902                                                 if (true == isuy)
1903                                                         v = margin;
1904                                                 else
1905                                                         u = margin;
1906                                         } else
1907                                                  if (0x08 & mask)
1908                                                         ;
1909                                 } else {
1910                                         if (true == isuy)
1911                                                 v = *(p2 + 1);
1912                                         else
1913                                                 u = *(p2 + 1);
1914                                 }
1915
1916                                 s32 = ay[(int)y] + rv[(int)v];
1917                                 r = (255 < s32) ? 255 : ((0 > s32) ? \
1918                                                                 0 : (__u8)s32);
1919                                 s32 = ay[(int)y] - gu[(int)u] - gv[(int)v];
1920                                 g = (255 < s32) ? 255 : ((0 > s32) ? \
1921                                                                 0 : (__u8)s32);
1922                                 s32 = ay[(int)y] + bu[(int)u];
1923                                 b = (255 < s32) ? 255 : ((0 > s32) ? \
1924                                                                 0 : (__u8)s32);
1925
1926                                 if ((true == last) && rump) {
1927                                         pcache = &cache[0];
1928                                         switch (bytesperpixel - rump) {
1929                                         case 1: {
1930                                                 *p3 = r;
1931                                                 *pcache++ = g;
1932                                                 *pcache++ = b;
1933                                                 *pcache++ = 0;
1934                                                 break;
1935                                         }
1936                                         case 2: {
1937                                                 *p3 = r;
1938                                                 *(p3 + 1) = g;
1939                                                 *pcache++ = b;
1940                                                 *pcache++ = 0;
1941                                                 break;
1942                                         }
1943                                         case 3: {
1944                                                 *p3 = r;
1945                                                 *(p3 + 1) = g;
1946                                                 *(p3 + 2) = b;
1947                                                 *pcache++ = 0;
1948                                                 break;
1949                                         }
1950                                         default: {
1951                                                 SAY("MISTAKE: %i=rump\n", \
1952                                                         bytesperpixel - rump);
1953                                                 return -EFAULT;
1954                                         }
1955                                         }
1956                                 } else {
1957                                         *p3 = r;
1958                                         *(p3 + 1) = g;
1959                                         *(p3 + 2) = b;
1960                                         *(p3 + 3) = 0;
1961                                 }
1962                                 p2 += 2;
1963                                 if (true == isuy)
1964                                         isuy = false;
1965                                 else
1966                                         isuy = true;
1967                                 p3 += bytesperpixel;
1968                         }
1969                         return 0;
1970                 } else {
1971                         /*---------------------------------------------------*/
1972                         /*
1973                         **  BGRA
1974                         */
1975                         /*---------------------------------------------------*/
1976                         while (pz > p2) {
1977                                 if (pr <= (p3 + bytesperpixel))
1978                                         last = true;
1979                                 else
1980                                         last = false;
1981                                 y = *p2;
1982                                 if ((true == last) && (0x0C & mask)) {
1983                                         if (0x04 & mask) {
1984                                                 if (true == isuy)
1985                                                         v = margin;
1986                                                 else
1987                                                         u = margin;
1988                                         } else
1989                                                  if (0x08 & mask)
1990                                                         ;
1991                                 } else {
1992                                         if (true == isuy)
1993                                                 v = *(p2 + 1);
1994                                         else
1995                                                 u = *(p2 + 1);
1996                                 }
1997
1998                                 s32 = ay[(int)y] + rv[(int)v];
1999                                 r = (255 < s32) ? 255 : ((0 > s32) ? \
2000                                                                 0 : (__u8)s32);
2001                                 s32 = ay[(int)y] - gu[(int)u] - gv[(int)v];
2002                                 g = (255 < s32) ? 255 : ((0 > s32) ? \
2003                                                                 0 : (__u8)s32);
2004                                 s32 = ay[(int)y] + bu[(int)u];
2005                                 b = (255 < s32) ? 255 : ((0 > s32) ? \
2006                                                                 0 : (__u8)s32);
2007
2008                                 if ((true == last) && rump) {
2009                                         pcache = &cache[0];
2010                                         switch (bytesperpixel - rump) {
2011                                         case 1: {
2012                                                 *p3 = b;
2013                                                 *pcache++ = g;
2014                                                 *pcache++ = r;
2015                                                 *pcache++ = 0;
2016                                                 break;
2017                                         }
2018                                         case 2: {
2019                                                 *p3 = b;
2020                                                 *(p3 + 1) = g;
2021                                                 *pcache++ = r;
2022                                                 *pcache++ = 0;
2023                                                 break;
2024                                         }
2025                                         case 3: {
2026                                                 *p3 = b;
2027                                                 *(p3 + 1) = g;
2028                                                 *(p3 + 2) = r;
2029                                                 *pcache++ = 0;
2030                                                 break;
2031                                         }
2032                                         default: {
2033                                                 SAY("MISTAKE: %i=rump\n", \
2034                                                         bytesperpixel - rump);
2035                                                 return -EFAULT;
2036                                         }
2037                                         }
2038                                 } else {
2039                                         *p3 = b;
2040                                         *(p3 + 1) = g;
2041                                         *(p3 + 2) = r;
2042                                         *(p3 + 3) = 0;
2043                                 }
2044                                 p2 += 2;
2045                                 if (true == isuy)
2046                                         isuy = false;
2047                                 else
2048                                         isuy = true;
2049                                 p3 += bytesperpixel;
2050                         }
2051                 }
2052                 return 0;
2053         } else {
2054                 if (false == byteswaporder) {
2055                         /*---------------------------------------------------*/
2056                         /*
2057                         **  RGBA DECIMATED
2058                         */
2059                         /*---------------------------------------------------*/
2060                         while (pz > p2) {
2061                                 if (pr <= (p3 + bytesperpixel))
2062                                         last = true;
2063                                 else
2064                                         last = false;
2065                                 y = *p2;
2066                                 if ((true == last) && (0x0C & mask)) {
2067                                         if (0x04 & mask) {
2068                                                 if (true == isuy)
2069                                                         v = margin;
2070                                                 else
2071                                                         u = margin;
2072                                         } else
2073                                                 if (0x08 & mask)
2074                                                         ;
2075                                 } else {
2076                                         if (true == isuy)
2077                                                 v = *(p2 + 1);
2078                                         else
2079                                                 u = *(p2 + 1);
2080                                 }
2081
2082                                 if (true == isuy) {
2083
2084                                         s32 = ay[(int)y] + rv[(int)v];
2085                                         r = (255 < s32) ? 255 : ((0 > s32) ? \
2086                                                                 0 : (__u8)s32);
2087                                         s32 = ay[(int)y] - gu[(int)u] - \
2088                                                                 gv[(int)v];
2089                                         g = (255 < s32) ? 255 : ((0 > s32) ? \
2090                                                                 0 : (__u8)s32);
2091                                         s32 = ay[(int)y] + bu[(int)u];
2092                                         b = (255 < s32) ? 255 : ((0 > s32) ? \
2093                                                                 0 : (__u8)s32);
2094
2095                                         if ((true == last) && rump) {
2096                                                 pcache = &cache[0];
2097                                                 switch (bytesperpixel - rump) {
2098                                                 case 1: {
2099                                                         *p3 = r;
2100                                                         *pcache++ = g;
2101                                                         *pcache++ = b;
2102                                                         *pcache++ = 0;
2103                                                         break;
2104                                                 }
2105                                                 case 2: {
2106                                                         *p3 = r;
2107                                                         *(p3 + 1) = g;
2108                                                         *pcache++ = b;
2109                                                         *pcache++ = 0;
2110                                                         break;
2111                                                 }
2112                                                 case 3: {
2113                                                         *p3 = r;
2114                                                         *(p3 + 1) = g;
2115                                                         *(p3 + 2) = b;
2116                                                         *pcache++ = 0;
2117                                                         break;
2118                                                 }
2119                                                 default: {
2120                                                         SAY("MISTAKE: " \
2121                                                         "%i=rump\n", \
2122                                                         bytesperpixel - \
2123                                                         rump);
2124                                                         return -EFAULT;
2125                                                         }
2126                                                 }
2127                                         } else {
2128                                                 *p3 = r;
2129                                                 *(p3 + 1) = g;
2130                                                 *(p3 + 2) = b;
2131                                                 *(p3 + 3) = 0;
2132                                                 }
2133                                         isuy = false;
2134                                         p3 += bytesperpixel;
2135                                 } else
2136                                         isuy = true;
2137                                 p2 += 2;
2138                         }
2139                         return 0;
2140                 } else {
2141                         /*---------------------------------------------------*/
2142                         /*
2143                         **  BGRA DECIMATED
2144                         */
2145                         /*---------------------------------------------------*/
2146                         while (pz > p2) {
2147                                 if (pr <= (p3 + bytesperpixel))
2148                                         last = true;
2149                                 else
2150                                         last = false;
2151                                 y = *p2;
2152                                 if ((true == last) && (0x0C & mask)) {
2153                                         if (0x04 & mask) {
2154                                                 if (true == isuy)
2155                                                         v = margin;
2156                                                 else
2157                                                         u = margin;
2158                                         } else
2159                                                 if (0x08 & mask)
2160                                                         ;
2161                                 } else {
2162                                         if (true == isuy)
2163                                                 v = *(p2 + 1);
2164                                         else
2165                                                 u = *(p2 + 1);
2166                                 }
2167
2168                                 if (true == isuy) {
2169                                         s32 = ay[(int)y] + rv[(int)v];
2170                                         r = (255 < s32) ? 255 : ((0 > s32) ? \
2171                                                                 0 : (__u8)s32);
2172                                         s32 = ay[(int)y] - gu[(int)u] - \
2173                                                                 gv[(int)v];
2174                                         g = (255 < s32) ? 255 : ((0 > s32) ? \
2175                                                                 0 : (__u8)s32);
2176                                         s32 = ay[(int)y] + bu[(int)u];
2177                                         b = (255 < s32) ? 255 : ((0 > s32) ? \
2178                                                                 0 : (__u8)s32);
2179
2180                                         if ((true == last) && rump) {
2181                                                 pcache = &cache[0];
2182                                                 switch (bytesperpixel - rump) {
2183                                                 case 1: {
2184                                                         *p3 = b;
2185                                                         *pcache++ = g;
2186                                                         *pcache++ = r;
2187                                                         *pcache++ = 0;
2188                                                         break;
2189                                                 }
2190                                                 case 2: {
2191                                                         *p3 = b;
2192                                                         *(p3 + 1) = g;
2193                                                         *pcache++ = r;
2194                                                         *pcache++ = 0;
2195                                                         break;
2196                                                 }
2197                                                 case 3: {
2198                                                         *p3 = b;
2199                                                         *(p3 + 1) = g;
2200                                                         *(p3 + 2) = r;
2201                                                         *pcache++ = 0;
2202                                                         break;
2203                                                 }
2204                                                 default: {
2205                                                         SAY("MISTAKE: " \
2206                                                         "%i=rump\n", \
2207                                                         bytesperpixel - rump);
2208                                                         return -EFAULT;
2209                                                 }
2210                                                 }
2211                                         } else {
2212                                                 *p3 = b;
2213                                                 *(p3 + 1) = g;
2214                                                 *(p3 + 2) = r;
2215                                                 *(p3 + 3) = 0;
2216                                         }
2217                                         isuy = false;
2218                                         p3 += bytesperpixel;
2219                                 } else
2220                                         isuy = true;
2221                                         p2 += 2;
2222                                 }
2223                                 return 0;
2224                         }
2225                 }
2226         break;
2227         }
2228 default: {
2229         SAY("MISTAKE: %i=bytesperpixel\n", bytesperpixel);
2230         return -EFAULT;
2231         }
2232 }
2233 return 0;
2234 }
2235 /*****************************************************************************/
2236 void
2237 debrief(struct easycap *peasycap)
2238 {
2239 if ((struct usb_device *)NULL != peasycap->pusb_device) {
2240         check_stk(peasycap->pusb_device);
2241         check_saa(peasycap->pusb_device);
2242         sayreadonly(peasycap);
2243         SAY("%i=peasycap->field_fill\n", peasycap->field_fill);
2244         SAY("%i=peasycap->field_read\n", peasycap->field_read);
2245         SAY("%i=peasycap->frame_fill\n", peasycap->frame_fill);
2246         SAY("%i=peasycap->frame_read\n", peasycap->frame_read);
2247 }
2248 return;
2249 }
2250 /*****************************************************************************/
2251 void
2252 sayreadonly(struct easycap *peasycap)
2253 {
2254 static int done;
2255 int got00, got1F, got60, got61, got62;
2256
2257 if ((!done) && ((struct usb_device *)NULL != peasycap->pusb_device)) {
2258         done = 1;
2259         got00 = read_saa(peasycap->pusb_device, 0x00);
2260         got1F = read_saa(peasycap->pusb_device, 0x1F);
2261         got60 = read_saa(peasycap->pusb_device, 0x60);
2262         got61 = read_saa(peasycap->pusb_device, 0x61);
2263         got62 = read_saa(peasycap->pusb_device, 0x62);
2264         SAY("0x%02X=reg0x00  0x%02X=reg0x1F\n", got00, got1F);
2265         SAY("0x%02X=reg0x60  0x%02X=reg0x61  0x%02X=reg0x62\n", \
2266                                                         got60, got61, got62);
2267 }
2268 return;
2269 }
2270 /*****************************************************************************/
2271 /*---------------------------------------------------------------------------*/
2272 /*
2273  *  SEE CORBET ET AL. "LINUX DEVICE DRIVERS", 3rd EDITION, PAGES 430-434
2274  */
2275 /*---------------------------------------------------------------------------*/
2276 int easycap_mmap(struct file *file, struct vm_area_struct *pvma)
2277 {
2278
2279 JOT(8, "\n");
2280
2281 pvma->vm_ops = &easycap_vm_ops;
2282 pvma->vm_flags |= VM_RESERVED;
2283 if (NULL != file)
2284         pvma->vm_private_data = file->private_data;
2285 easycap_vma_open(pvma);
2286 return 0;
2287 }
2288 /*****************************************************************************/
2289 void
2290 easycap_vma_open(struct vm_area_struct *pvma)
2291 {
2292 struct easycap *peasycap;
2293
2294 peasycap = pvma->vm_private_data;
2295 if (NULL != peasycap)
2296         peasycap->vma_many++;
2297
2298 JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many);
2299
2300 return;
2301 }
2302 /*****************************************************************************/
2303 void
2304 easycap_vma_close(struct vm_area_struct *pvma)
2305 {
2306 struct easycap *peasycap;
2307
2308 peasycap = pvma->vm_private_data;
2309 if (NULL != peasycap) {
2310         peasycap->vma_many--;
2311         JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many);
2312 }
2313 return;
2314 }
2315 /*****************************************************************************/
2316 int
2317 easycap_vma_fault(struct vm_area_struct *pvma, struct vm_fault *pvmf)
2318 {
2319 int k, m, retcode;
2320 void *pbuf;
2321 struct page *page;
2322 struct easycap *peasycap;
2323
2324 retcode = VM_FAULT_NOPAGE;
2325 pbuf = (void *)NULL;
2326 page = (struct page *)NULL;
2327
2328 if (NULL == pvma) {
2329         SAY("pvma is NULL\n");
2330         return retcode;
2331 }
2332 if (NULL == pvmf) {
2333         SAY("pvmf is NULL\n");
2334         return retcode;
2335 }
2336
2337 k = (pvmf->pgoff) / (FRAME_BUFFER_SIZE/PAGE_SIZE);
2338 m = (pvmf->pgoff) % (FRAME_BUFFER_SIZE/PAGE_SIZE);
2339
2340 if (!m)
2341         JOT(4, "%4i=k, %4i=m\n", k, m);
2342 else
2343         JOT(16, "%4i=k, %4i=m\n", k, m);
2344
2345 if ((0 > k) || (FRAME_BUFFER_MANY <= k)) {
2346         SAY("ERROR: buffer index %i out of range\n", k);
2347         return retcode;
2348 }
2349 if ((0 > m) || (FRAME_BUFFER_SIZE/PAGE_SIZE <= m)) {
2350         SAY("ERROR: page number  %i out of range\n", m);
2351         return retcode;
2352 }
2353 peasycap = pvma->vm_private_data;
2354 if (NULL == peasycap) {
2355         SAY("ERROR: peasycap is NULL\n");
2356         return retcode;
2357 }
2358 mutex_lock(&(peasycap->mutex_mmap_video[0]));
2359 /*---------------------------------------------------------------------------*/
2360 pbuf = peasycap->frame_buffer[k][m].pgo;
2361 if (NULL == pbuf) {
2362         SAY("ERROR:  pbuf is NULL\n");
2363         goto finish;
2364 }
2365 page = virt_to_page(pbuf);
2366 if (NULL == page) {
2367         SAY("ERROR:  page is NULL\n");
2368         goto finish;
2369 }
2370 get_page(page);
2371 /*---------------------------------------------------------------------------*/
2372 finish:
2373 mutex_unlock(&(peasycap->mutex_mmap_video[0]));
2374 if (NULL == page) {
2375         SAY("ERROR:  page is NULL after get_page(page)\n");
2376 } else {
2377         pvmf->page = page;
2378         retcode = VM_FAULT_MINOR;
2379 }
2380 return retcode;
2381 }
2382 /*****************************************************************************/
2383 /*---------------------------------------------------------------------------*/
2384 /*
2385  *  ON COMPLETION OF A VIDEO URB ITS DATA IS COPIED TO THE FIELD BUFFERS
2386  *  PROVIDED peasycap->video_idle IS ZER0.  REGARDLESS OF THIS BEING TRUE,
2387  *  IT IS RESUBMITTED PROVIDED peasycap->video_isoc_streaming IS NOT ZERO.
2388  *
2389  *  THIS FUNCTION IS AN INTERRUPT SERVICE ROUTINE AND MUST NOT SLEEP.
2390  *
2391  *  INFORMATION ABOUT THE VALIDITY OF THE CONTENTS OF THE FIELD BUFFER ARE
2392  *  STORED IN THE TWO-BYTE STATUS PARAMETER
2393  *        peasycap->field_buffer[peasycap->field_fill][0].kount
2394  *  NOTICE THAT THE INFORMATION IS STORED ONLY WITH PAGE 0 OF THE FIELD BUFFER.
2395  *
2396  *  THE LOWER BYTE CONTAINS THE FIELD PARITY BYTE FURNISHED BY THE SAA7113H
2397  *  CHIP.
2398  *
2399  *  THE UPPER BYTE IS ZERO IF NO PROBLEMS, OTHERWISE:
2400  *      0 != (kount & 0x8000)   => AT LEAST ONE URB COMPLETED WITH ERRORS
2401  *      0 != (kount & 0x4000)   => BUFFER HAS TOO MUCH DATA
2402  *      0 != (kount & 0x2000)   => BUFFER HAS NOT ENOUGH DATA
2403  *      0 != (kount & 0x0400)   => FIELD WAS SUBMITTED BY BRIDGER ROUTINE
2404  *      0 != (kount & 0x0200)   => FIELD BUFFER NOT YET CHECKED
2405  *      0 != (kount & 0x0100)   => BUFFER HAS TWO EXTRA BYTES - WHY?
2406  */
2407 /*---------------------------------------------------------------------------*/
2408 void
2409 easycap_complete(struct urb *purb)
2410 {
2411 static int mt;
2412 struct easycap *peasycap;
2413 struct data_buffer *pfield_buffer;
2414 char errbuf[16];
2415 int i, more, much, leap, rc, last;
2416 int videofieldamount;
2417 unsigned int override;
2418 int framestatus, framelength, frameactual, frameoffset;
2419 __u8 *pu;
2420 #if defined(BRIDGER)
2421 struct timeval timeval;
2422 long long usec;
2423 #endif /*BRIDGER*/
2424
2425 if (NULL == purb) {
2426         SAY("ERROR: easycap_complete(): purb is NULL\n");
2427         return;
2428 }
2429 peasycap = purb->context;
2430 if (NULL == peasycap) {
2431         SAY("ERROR: easycap_complete(): peasycap is NULL\n");
2432         return;
2433 }
2434
2435 if (peasycap->video_eof)
2436         return;
2437
2438 for (i = 0; i < VIDEO_ISOC_BUFFER_MANY; i++)
2439         if (purb->transfer_buffer == peasycap->video_isoc_buffer[i].pgo)
2440                 break;
2441 JOT(16, "%2i=urb\n", i);
2442 last = peasycap->video_isoc_sequence;
2443 if ((((VIDEO_ISOC_BUFFER_MANY - 1) == last) && \
2444                                                 (0 != i)) || \
2445         (((VIDEO_ISOC_BUFFER_MANY - 1) != last) && \
2446                                                 ((last + 1) != i))) {
2447         SAY("ERROR: out-of-order urbs %i,%i ... continuing\n", last, i);
2448 }
2449 peasycap->video_isoc_sequence = i;
2450
2451 if (peasycap->video_idle) {
2452         JOT(16, "%i=video_idle  %i=video_isoc_streaming\n", \
2453                         peasycap->video_idle, peasycap->video_isoc_streaming);
2454         if (peasycap->video_isoc_streaming) {
2455                 rc = usb_submit_urb(purb, GFP_ATOMIC);
2456                 if (0 != rc) {
2457                         SAY("ERROR: while %i=video_idle, " \
2458                                         "usb_submit_urb() failed with rc:\n", \
2459                                                         peasycap->video_idle);
2460                         switch (rc) {
2461                         case -ENOMEM: {
2462                                 SAY("ENOMEM\n");
2463                                 break;
2464                         }
2465                         case -ENODEV: {
2466                                 SAY("ENODEV\n");
2467                                 break;
2468                         }
2469                         case -ENXIO: {
2470                                 SAY("ENXIO\n");
2471                                 break;
2472                         }
2473                         case -EINVAL: {
2474                                 SAY("EINVAL\n");
2475                                 break;
2476                         }
2477                         case -EAGAIN: {
2478                                 SAY("EAGAIN\n");
2479                                 break;
2480                         }
2481                         case -EFBIG: {
2482                                 SAY("EFBIG\n");
2483                                 break;
2484                         }
2485                         case -EPIPE: {
2486                                 SAY("EPIPE\n");
2487                                 break;
2488                         }
2489                         case -EMSGSIZE: {
2490                                 SAY("EMSGSIZE\n");
2491                                 break;
2492                         }
2493                         case -ENOSPC: {
2494                                 SAY("ENOSPC\n");
2495                                 break;
2496                         }
2497                         default: {
2498                                 SAY("0x%08X\n", rc);
2499                                 break;
2500                         }
2501                         }
2502                 }
2503         }
2504 return;
2505 }
2506 override = 0;
2507 /*---------------------------------------------------------------------------*/
2508 if (FIELD_BUFFER_MANY <= peasycap->field_fill) {
2509         SAY("ERROR: bad peasycap->field_fill\n");
2510         return;
2511 }
2512 if (purb->status) {
2513         if ((-ESHUTDOWN == purb->status) || (-ENOENT == purb->status)) {
2514                 JOT(8, "urb status -ESHUTDOWN or -ENOENT\n");
2515                 return;
2516         }
2517
2518         (peasycap->field_buffer[peasycap->field_fill][0].kount) |= 0x8000 ;
2519         SAY("ERROR: bad urb status:\n");
2520         switch (purb->status) {
2521         case -EINPROGRESS: {
2522                 SAY("-EINPROGRESS\n"); break;
2523         }
2524         case -ENOSR: {
2525                 SAY("-ENOSR\n"); break;
2526         }
2527         case -EPIPE: {
2528                 SAY("-EPIPE\n"); break;
2529         }
2530         case -EOVERFLOW: {
2531                 SAY("-EOVERFLOW\n"); break;
2532         }
2533         case -EPROTO: {
2534                 SAY("-EPROTO\n"); break;
2535         }
2536         case -EILSEQ: {
2537                 SAY("-EILSEQ\n"); break;
2538         }
2539         case -ETIMEDOUT: {
2540                 SAY("-ETIMEDOUT\n"); break;
2541         }
2542         case -EMSGSIZE: {
2543                 SAY("-EMSGSIZE\n"); break;
2544         }
2545         case -EOPNOTSUPP: {
2546                 SAY("-EOPNOTSUPP\n"); break;
2547         }
2548         case -EPFNOSUPPORT: {
2549                 SAY("-EPFNOSUPPORT\n"); break;
2550         }
2551         case -EAFNOSUPPORT: {
2552                 SAY("-EAFNOSUPPORT\n"); break;
2553         }
2554         case -EADDRINUSE: {
2555                 SAY("-EADDRINUSE\n"); break;
2556         }
2557         case -EADDRNOTAVAIL: {
2558                 SAY("-EADDRNOTAVAIL\n"); break;
2559         }
2560         case -ENOBUFS: {
2561                 SAY("-ENOBUFS\n"); break;
2562         }
2563         case -EISCONN: {
2564                 SAY("-EISCONN\n"); break;
2565         }
2566         case -ENOTCONN: {
2567                 SAY("-ENOTCONN\n"); break;
2568         }
2569         case -ESHUTDOWN: {
2570                 SAY("-ESHUTDOWN\n"); break;
2571         }
2572         case -ENOENT: {
2573                 SAY("-ENOENT\n"); break;
2574         }
2575         case -ECONNRESET: {
2576                 SAY("-ECONNRESET\n"); break;
2577         }
2578         case -ENOSPC: {
2579                 SAY("ENOSPC\n"); break;
2580         }
2581         default: {
2582                 SAY("unknown error code 0x%08X\n", purb->status); break;
2583         }
2584         }
2585 /*---------------------------------------------------------------------------*/
2586 } else {
2587         for (i = 0;  i < purb->number_of_packets; i++) {
2588                 if (0 != purb->iso_frame_desc[i].status) {
2589                         (peasycap->field_buffer\
2590                                 [peasycap->field_fill][0].kount) |= 0x8000 ;
2591                         switch (purb->iso_frame_desc[i].status) {
2592                         case  0: {
2593                                 strcpy(&errbuf[0], "OK"); break;
2594                         }
2595                         case -ENOENT: {
2596                                 strcpy(&errbuf[0], "-ENOENT"); break;
2597                         }
2598                         case -EINPROGRESS: {
2599                                 strcpy(&errbuf[0], "-EINPROGRESS"); break;
2600                         }
2601                         case -EPROTO: {
2602                                 strcpy(&errbuf[0], "-EPROTO"); break;
2603                         }
2604                         case -EILSEQ: {
2605                                 strcpy(&errbuf[0], "-EILSEQ"); break;
2606                         }
2607                         case -ETIME: {
2608                                 strcpy(&errbuf[0], "-ETIME"); break;
2609                         }
2610                         case -ETIMEDOUT: {
2611                                 strcpy(&errbuf[0], "-ETIMEDOUT"); break;
2612                         }
2613                         case -EPIPE: {
2614                                 strcpy(&errbuf[0], "-EPIPE"); break;
2615                         }
2616                         case -ECOMM: {
2617                                 strcpy(&errbuf[0], "-ECOMM"); break;
2618                         }
2619                         case -ENOSR: {
2620                                 strcpy(&errbuf[0], "-ENOSR"); break;
2621                         }
2622                         case -EOVERFLOW: {
2623                                 strcpy(&errbuf[0], "-EOVERFLOW"); break;
2624                         }
2625                         case -EREMOTEIO: {
2626                                 strcpy(&errbuf[0], "-EREMOTEIO"); break;
2627                         }
2628                         case -ENODEV: {
2629                                 strcpy(&errbuf[0], "-ENODEV"); break;
2630                         }
2631                         case -EXDEV: {
2632                                 strcpy(&errbuf[0], "-EXDEV"); break;
2633                         }
2634                         case -EINVAL: {
2635                                 strcpy(&errbuf[0], "-EINVAL"); break;
2636                         }
2637                         case -ECONNRESET: {
2638                                 strcpy(&errbuf[0], "-ECONNRESET"); break;
2639                         }
2640                         case -ENOSPC: {
2641                                 SAY("ENOSPC\n"); break;
2642                         }
2643                         case -ESHUTDOWN: {
2644                                 strcpy(&errbuf[0], "-ESHUTDOWN"); break;
2645                         }
2646                         default: {
2647                                 strcpy(&errbuf[0], "unknown error"); break;
2648                         }
2649                         }
2650                 }
2651                 framestatus = purb->iso_frame_desc[i].status;
2652                 framelength = purb->iso_frame_desc[i].length;
2653                 frameactual = purb->iso_frame_desc[i].actual_length;
2654                 frameoffset = purb->iso_frame_desc[i].offset;
2655
2656                 JOT(16, "frame[%2i]:" \
2657                                 "%4i=status "  \
2658                                 "%4i=actual "  \
2659                                 "%4i=length "  \
2660                                 "%5i=offset\n", \
2661                         i, framestatus, frameactual, framelength, frameoffset);
2662                 if (!purb->iso_frame_desc[i].status) {
2663                         more = purb->iso_frame_desc[i].actual_length;
2664                         pfield_buffer = &peasycap->field_buffer\
2665                                   [peasycap->field_fill][peasycap->field_page];
2666                         videofieldamount = (peasycap->field_page * \
2667                                 PAGE_SIZE) + \
2668                                 (int)(pfield_buffer->pto - pfield_buffer->pgo);
2669                 if (4 == more)
2670                         mt++;
2671                 if (4 < more) {
2672                         if (mt) {
2673                                 JOT(8, "%4i empty video urb frames\n", mt);
2674                                 mt = 0;
2675                         }
2676                         if (FIELD_BUFFER_MANY <= peasycap->field_fill) {
2677                                 SAY("ERROR: bad peasycap->field_fill\n");
2678                                 return;
2679                         }
2680                         if (FIELD_BUFFER_SIZE/PAGE_SIZE <= \
2681                                                         peasycap->field_page) {
2682                                 SAY("ERROR: bad peasycap->field_page\n");
2683                                 return;
2684                         }
2685                         pfield_buffer = &peasycap->field_buffer\
2686                                 [peasycap->field_fill][peasycap->field_page];
2687                         pu = (__u8 *)(purb->transfer_buffer + \
2688                                         purb->iso_frame_desc[i].offset);
2689                         if (0x80 & *pu)
2690                                 leap = 8;
2691                         else
2692                                 leap = 4;
2693 /*--------------------------------------------------------------------------*/
2694 /*
2695  *  EIGHT-BYTE END-OF-VIDEOFIELD MARKER.
2696  *  NOTE:  A SUCCESSION OF URB FRAMES FOLLOWING THIS ARE EMPTY,
2697  *         CORRESPONDING TO THE FIELD FLYBACK (VERTICAL BLANKING) PERIOD.
2698  *
2699  *  PROVIDED THE FIELD BUFFER CONTAINS GOOD DATA AS INDICATED BY A ZERO UPPER
2700  *  BYTE OF
2701  *        peasycap->field_buffer[peasycap->field_fill][0].kount
2702  *  THE CONTENTS OF THE FIELD BUFFER ARE OFFERED TO dqbuf(), field_read IS
2703  *  UPDATED AND field_fill IS BUMPED.  IF THE FIELD BUFFER CONTAINS BAD DATA
2704  *  NOTHING IS OFFERED TO dqbuf().
2705  *
2706  *  THE DECISION ON WHETHER THE PARITY OF THE OFFERED FIELD BUFFER IS RIGHT
2707  *  RESTS WITH dqbuf().
2708  */
2709 /*---------------------------------------------------------------------------*/
2710                         if ((8 == more) || override) {
2711                                 if (videofieldamount > \
2712                                                 peasycap->videofieldamount) {
2713                                         if (2 == videofieldamount - \
2714                                                         peasycap->\
2715                                                         videofieldamount)
2716                                                 (peasycap->field_buffer\
2717                                                 [peasycap->field_fill]\
2718                                                         [0].kount) |= 0x0100;
2719                                         else
2720                                                 (peasycap->field_buffer\
2721                                                 [peasycap->field_fill]\
2722                                                         [0].kount) |= 0x4000;
2723                                         } else if (videofieldamount < \
2724                                                         peasycap->\
2725                                                         videofieldamount) {
2726                                                 (peasycap->field_buffer\
2727                                                 [peasycap->field_fill]\
2728                                                         [0].kount) |= 0x2000;
2729                                         }
2730                                 if (!(0xFF00 & peasycap->field_buffer\
2731                                                 [peasycap->field_fill]\
2732                                                 [0].kount)) {
2733                                         (peasycap->video_junk)--;
2734                                         if (-16 > peasycap->video_junk)
2735                                                 peasycap->video_junk = -16;
2736                                         peasycap->field_read = \
2737                                                         (peasycap->\
2738                                                                 field_fill)++;
2739
2740                                         if (FIELD_BUFFER_MANY <= \
2741                                                 peasycap->field_fill)
2742                                                 peasycap->field_fill = 0;
2743                                         peasycap->field_page = 0;
2744                                         pfield_buffer = &peasycap->\
2745                                                 field_buffer\
2746                                                 [peasycap->field_fill]\
2747                                                 [peasycap->field_page];
2748                                         pfield_buffer->pto = \
2749                                                         pfield_buffer->pgo;
2750
2751                                         JOT(8, "bumped to: %i=peasycap->" \
2752                                                 "field_fill  %i=parity\n", \
2753                                                 peasycap->field_fill, \
2754                                                 0x00FF & pfield_buffer->kount);
2755                                         JOT(8, "field buffer %i has %i " \
2756                                                 "bytes fit to be read\n", \
2757                                                 peasycap->field_read, \
2758                                                 videofieldamount);
2759                                         JOT(8, "wakeup call to wq_video, " \
2760                                                 "%i=field_read %i=field_fill "\
2761                                                 "%i=parity\n", \
2762                                                 peasycap->field_read, \
2763                                                 peasycap->field_fill, \
2764                                                 0x00FF & peasycap->\
2765                                                 field_buffer[peasycap->\
2766                                                 field_read][0].kount);
2767                                         wake_up_interruptible(&(peasycap->\
2768                                                                 wq_video));
2769                                         do_gettimeofday(&peasycap->timeval7);
2770                                         } else {
2771                                         peasycap->video_junk++;
2772                                         JOT(8, "field buffer %i had %i " \
2773                                                 "bytes, now discarded\n", \
2774                                                 peasycap->field_fill, \
2775                                                 videofieldamount);
2776
2777                                         (peasycap->field_fill)++;
2778
2779                                         if (FIELD_BUFFER_MANY <= \
2780                                                         peasycap->field_fill)
2781                                                 peasycap->field_fill = 0;
2782                                         peasycap->field_page = 0;
2783                                         pfield_buffer = \
2784                                                 &peasycap->field_buffer\
2785                                                 [peasycap->field_fill]\
2786                                                 [peasycap->field_page];
2787                                         pfield_buffer->pto = \
2788                                                         pfield_buffer->pgo;
2789
2790                                         JOT(8, "bumped to: %i=peasycap->" \
2791                                                 "field_fill  %i=parity\n", \
2792                                                 peasycap->field_fill, \
2793                                                 0x00FF & pfield_buffer->kount);
2794                                 }
2795                                 if (8 == more) {
2796                                         JOT(8, "end-of-field: received " \
2797                                                 "parity byte 0x%02X\n", \
2798                                                 (0xFF & *pu));
2799                                         if (0x40 & *pu)
2800                                                 pfield_buffer->kount = 0x0000;
2801                                         else
2802                                                 pfield_buffer->kount = 0x0001;
2803                                         JOT(8, "end-of-field: 0x%02X=kount\n",\
2804                                                 0xFF & pfield_buffer->kount);
2805                                 }
2806                         }
2807 /*---------------------------------------------------------------------------*/
2808 /*
2809  *  COPY more BYTES FROM ISOC BUFFER TO FIELD BUFFER
2810  */
2811 /*---------------------------------------------------------------------------*/
2812                         pu += leap;
2813                         more -= leap;
2814
2815                         if (FIELD_BUFFER_MANY <= peasycap->field_fill) {
2816                                 SAY("ERROR: bad peasycap->field_fill\n");
2817                                 return;
2818                         }
2819                         if (FIELD_BUFFER_SIZE/PAGE_SIZE <= \
2820                                                         peasycap->field_page) {
2821                                 SAY("ERROR: bad peasycap->field_page\n");
2822                                 return;
2823                         }
2824                         pfield_buffer = &peasycap->field_buffer\
2825                                 [peasycap->field_fill][peasycap->field_page];
2826                         while (more) {
2827                                 pfield_buffer = &peasycap->field_buffer\
2828                                                 [peasycap->field_fill]\
2829                                                 [peasycap->field_page];
2830                                 if (PAGE_SIZE < (pfield_buffer->pto - \
2831                                                         pfield_buffer->pgo)) {
2832                                         SAY("ERROR: bad pfield_buffer->pto\n");
2833                                         return;
2834                                 }
2835                                 if (PAGE_SIZE == (pfield_buffer->pto - \
2836                                                         pfield_buffer->pgo)) {
2837                                         (peasycap->field_page)++;
2838                                         if (FIELD_BUFFER_SIZE/PAGE_SIZE <= \
2839                                                         peasycap->field_page) {
2840                                                 JOT(16, "wrapping peasycap->" \
2841                                                         "field_page\n");
2842                                                 peasycap->field_page = 0;
2843                                         }
2844                                         pfield_buffer = &peasycap->\
2845                                                         field_buffer\
2846                                                         [peasycap->field_fill]\
2847                                                         [peasycap->field_page];
2848                                         pfield_buffer->pto = \
2849                                                         pfield_buffer->pgo;
2850                                 }
2851
2852                                 much = PAGE_SIZE - (int)(pfield_buffer->pto - \
2853                                                         pfield_buffer->pgo);
2854
2855                                 if (much > more)
2856                                         much = more;
2857                                 memcpy(pfield_buffer->pto, pu, much);
2858                                 pu += much;
2859                                 (pfield_buffer->pto) += much;
2860                                 more -= much;
2861                                 }
2862                         }
2863                 }
2864         }
2865 }
2866 /*---------------------------------------------------------------------------*/
2867 /*
2868  *
2869  *
2870  *             *** UNDER DEVELOPMENT/TESTING - NOT READY YET! ***
2871  *
2872  *
2873  *
2874  *  VIDEOTAPES MAY HAVE BEEN MANUALLY PAUSED AND RESTARTED DURING RECORDING.
2875  *  THIS CAUSES LOSS OF SYNC, CONFUSING DOWNSTREAM USERSPACE PROGRAMS WHICH
2876  *  MAY INTERPRET THE INTERRUPTION AS A SYMPTOM OF LATENCY.  TO OVERCOME THIS
2877  *  THE DRIVER BRIDGES THE HIATUS BY SENDING DUMMY VIDEO FRAMES AT ROUGHLY
2878  *  THE RIGHT TIME INTERVALS IN THE HOPE OF PERSUADING THE DOWNSTREAM USERSPACE
2879  *  PROGRAM TO RESUME NORMAL SERVICE WHEN THE INTERRUPTION IS OVER.
2880  */
2881 /*---------------------------------------------------------------------------*/
2882 #if defined(BRIDGER)
2883 do_gettimeofday(&timeval);
2884 if (peasycap->timeval7.tv_sec) {
2885         usec = 1000000*(timeval.tv_sec  - peasycap->timeval7.tv_sec) + \
2886                         (timeval.tv_usec - peasycap->timeval7.tv_usec);
2887         if (usec > (peasycap->usec + peasycap->tolerate)) {
2888                 JOT(8, "bridging hiatus\n");
2889                 peasycap->video_junk = 0;
2890                 peasycap->field_buffer[peasycap->field_fill][0].kount |= 0x0400;
2891
2892                 peasycap->field_read = (peasycap->field_fill)++;
2893
2894                 if (FIELD_BUFFER_MANY <= peasycap->field_fill) \
2895                                                 peasycap->field_fill = 0;
2896                 peasycap->field_page = 0;
2897                 pfield_buffer = &peasycap->field_buffer\
2898                                 [peasycap->field_fill][peasycap->field_page];
2899                 pfield_buffer->pto = pfield_buffer->pgo;
2900
2901                 JOT(8, "bumped to: %i=peasycap->field_fill  %i=parity\n", \
2902                         peasycap->field_fill, 0x00FF & pfield_buffer->kount);
2903                 JOT(8, "field buffer %i has %i bytes to be overwritten\n", \
2904                         peasycap->field_read, videofieldamount);
2905                 JOT(8, "wakeup call to wq_video, " \
2906                         "%i=field_read %i=field_fill %i=parity\n", \
2907                         peasycap->field_read, peasycap->field_fill, \
2908                         0x00FF & \
2909                         peasycap->field_buffer[peasycap->field_read][0].kount);
2910                 wake_up_interruptible(&(peasycap->wq_video));
2911                 do_gettimeofday(&peasycap->timeval7);
2912         }
2913 }
2914 #endif /*BRIDGER*/
2915 /*---------------------------------------------------------------------------*/
2916 /*
2917  *  RESUBMIT THIS URB, UNLESS A SEVERE PERSISTENT ERROR CONDITION EXISTS.
2918  *
2919  *  IF THE WAIT QUEUES ARE NOT CLEARED IN RESPONSE TO AN ERROR CONDITION
2920  *  THE USERSPACE PROGRAM, E.G. mplayer, MAY HANG ON EXIT.   BEWARE.
2921  */
2922 /*---------------------------------------------------------------------------*/
2923 if (VIDEO_ISOC_BUFFER_MANY <= peasycap->video_junk) {
2924         SAY("easycap driver shutting down on condition green\n");
2925         peasycap->video_eof = 1;
2926         peasycap->audio_eof = 1;
2927         peasycap->video_junk = -VIDEO_ISOC_BUFFER_MANY;
2928         wake_up_interruptible(&(peasycap->wq_video));
2929         wake_up_interruptible(&(peasycap->wq_audio));
2930         return;
2931 }
2932 if (peasycap->video_isoc_streaming) {
2933         rc = usb_submit_urb(purb, GFP_ATOMIC);
2934         if (0 != rc) {
2935                 SAY("ERROR: while %i=video_idle, usb_submit_urb() failed " \
2936                                         "with rc:\n", peasycap->video_idle);
2937                 switch (rc) {
2938                 case -ENOMEM: {
2939                         SAY("ENOMEM\n"); break;
2940                 }
2941                 case -ENODEV: {
2942                         SAY("ENODEV\n"); break;
2943                 }
2944                 case -ENXIO: {
2945                         SAY("ENXIO\n"); break;
2946                 }
2947                 case -EINVAL: {
2948                         SAY("EINVAL\n"); break;
2949                 }
2950                 case -EAGAIN: {
2951                         SAY("EAGAIN\n"); break;
2952                 }
2953                 case -EFBIG: {
2954                         SAY("EFBIG\n"); break;
2955                 }
2956                 case -EPIPE: {
2957                         SAY("EPIPE\n"); break;
2958                 }
2959                 case -EMSGSIZE: {
2960                         SAY("EMSGSIZE\n");  break;
2961                 }
2962                 case -ENOSPC: {
2963                         SAY("ENOSPC\n"); break;
2964                 }
2965                 default: {
2966                         SAY("0x%08X\n", rc); break;
2967                 }
2968                 }
2969         }
2970 }
2971 return;
2972 }
2973 /*****************************************************************************/
2974 /*---------------------------------------------------------------------------*/
2975 /*
2976  *
2977  *                                  FIXME
2978  *
2979  *
2980  *  THIS FUNCTION ASSUMES THAT, ON EACH AND EVERY OCCASION THAT THE DEVICE IS
2981  *  PHYSICALLY PLUGGED IN, INTERFACE 0 IS PROBED FIRST.
2982  *  IF THIS IS NOT TRUE, THERE IS THE POSSIBILITY OF AN Oops.
2983  *
2984  *  THIS HAS NEVER BEEN A PROBLEM IN PRACTICE, BUT SOMETHING SEEMS WRONG HERE.
2985  */
2986 /*---------------------------------------------------------------------------*/
2987 int
2988 easycap_usb_probe(struct usb_interface *pusb_interface, \
2989                                                 const struct usb_device_id *id)
2990 {
2991 struct usb_device *pusb_device, *pusb_device1;
2992 struct usb_host_interface *pusb_host_interface;
2993 struct usb_endpoint_descriptor *pepd;
2994 struct usb_interface_descriptor *pusb_interface_descriptor;
2995 struct usb_interface_assoc_descriptor *pusb_interface_assoc_descriptor;
2996 struct urb *purb;
2997 static struct easycap *peasycap /*=NULL*/;
2998 struct data_urb *pdata_urb;
2999 size_t wMaxPacketSize;
3000 int ISOCwMaxPacketSize;
3001 int BULKwMaxPacketSize;
3002 int INTwMaxPacketSize;
3003 int CTRLwMaxPacketSize;
3004 __u8 bEndpointAddress;
3005 __u8 ISOCbEndpointAddress;
3006 __u8 INTbEndpointAddress;
3007 int isin, i, j, k, m;
3008 __u8 bInterfaceNumber;
3009 __u8 bInterfaceClass;
3010 __u8 bInterfaceSubClass;
3011 void *pbuf;
3012 int okalt[8], isokalt;
3013 int okepn[8], isokepn;
3014 int okmps[8], isokmps;
3015 int maxpacketsize;
3016 int rc;
3017
3018 JOT(4, "\n");
3019
3020 if ((struct usb_interface *)NULL == pusb_interface) {
3021         SAY("ERROR: pusb_interface is NULL\n");
3022         return -EFAULT;
3023 }
3024 /*---------------------------------------------------------------------------*/
3025 /*
3026  *  GET POINTER TO STRUCTURE usb_device
3027  */
3028 /*---------------------------------------------------------------------------*/
3029 pusb_device1 = container_of(pusb_interface->dev.parent, \
3030                                                 struct usb_device, dev);
3031 if ((struct usb_device *)NULL == pusb_device1) {
3032         SAY("ERROR: pusb_device1 is NULL\n");
3033         return -EFAULT;
3034 }
3035 pusb_device = usb_get_dev(pusb_device1);
3036 if ((struct usb_device *)NULL == pusb_device) {
3037         SAY("ERROR: pusb_device is NULL\n");
3038         return -EFAULT;
3039 }
3040 if ((unsigned long int)pusb_device1 != (unsigned long int)pusb_device) {
3041         JOT(4, "ERROR: pusb_device1 != pusb_device\n");
3042         return -EFAULT;
3043 }
3044
3045 JOT(4, "bNumConfigurations=%i\n", pusb_device->descriptor.bNumConfigurations);
3046
3047 /*---------------------------------------------------------------------------*/
3048 pusb_host_interface = pusb_interface->cur_altsetting;
3049 if (NULL == pusb_host_interface) {
3050         SAY("ERROR: pusb_host_interface is NULL\n");
3051         return -EFAULT;
3052 }
3053 pusb_interface_descriptor = &(pusb_host_interface->desc);
3054 if (NULL == pusb_interface_descriptor) {
3055         SAY("ERROR: pusb_interface_descriptor is NULL\n");
3056         return -EFAULT;
3057 }
3058 /*---------------------------------------------------------------------------*/
3059 /*
3060  *  GET PROPERTIES OF PROBED INTERFACE
3061  */
3062 /*---------------------------------------------------------------------------*/
3063 bInterfaceNumber = pusb_interface_descriptor->bInterfaceNumber;
3064 bInterfaceClass = pusb_interface_descriptor->bInterfaceClass;
3065 bInterfaceSubClass = pusb_interface_descriptor->bInterfaceSubClass;
3066
3067 JOT(4, "intf[%i]: pusb_interface->num_altsetting=%i\n", \
3068                         bInterfaceNumber, pusb_interface->num_altsetting);
3069 JOT(4, "intf[%i]: pusb_interface->cur_altsetting - " \
3070                         "pusb_interface->altsetting=%li\n", bInterfaceNumber, \
3071                         (long int)(pusb_interface->cur_altsetting - \
3072                                                 pusb_interface->altsetting));
3073 switch (bInterfaceClass) {
3074 case USB_CLASS_AUDIO: {
3075         JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_AUDIO\n", \
3076                                 bInterfaceNumber, bInterfaceClass); break;
3077         }
3078 case USB_CLASS_VIDEO: {
3079         JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_VIDEO\n", \
3080                                 bInterfaceNumber, bInterfaceClass); break;
3081         }
3082 case USB_CLASS_VENDOR_SPEC: {
3083         JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_VENDOR_SPEC\n", \
3084                                 bInterfaceNumber, bInterfaceClass); break;
3085         }
3086 default:
3087         break;
3088 }
3089 switch (bInterfaceSubClass) {
3090 case 0x01: {
3091         JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=AUDIOCONTROL\n", \
3092                         bInterfaceNumber, bInterfaceSubClass); break;
3093 }
3094 case 0x02: {
3095         JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=AUDIOSTREAMING\n", \
3096                         bInterfaceNumber, bInterfaceSubClass); break;
3097 }
3098 case 0x03: {
3099         JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=MIDISTREAMING\n", \
3100                         bInterfaceNumber, bInterfaceSubClass); break;
3101 }
3102 default:
3103         break;
3104 }
3105 /*---------------------------------------------------------------------------*/
3106 pusb_interface_assoc_descriptor = pusb_interface->intf_assoc;
3107 if (NULL != pusb_interface_assoc_descriptor) {
3108         JOT(4, "intf[%i]: bFirstInterface=0x%02X  bInterfaceCount=0x%02X\n", \
3109                         bInterfaceNumber, \
3110                         pusb_interface_assoc_descriptor->bFirstInterface, \
3111                         pusb_interface_assoc_descriptor->bInterfaceCount);
3112 } else {
3113 JOT(4, "intf[%i]: pusb_interface_assoc_descriptor is NULL\n", \
3114                                                         bInterfaceNumber);
3115 }
3116 /*---------------------------------------------------------------------------*/
3117 /*
3118  *  A NEW struct easycap IS ALWAYS ALLOCATED WHEN INTERFACE 0 IS PROBED.
3119  *  IT IS NOT POSSIBLE HERE TO FREE ANY EXISTING struct easycap.  THIS
3120  *  SHOULD HAVE BEEN DONE BY easycap_delete() WHEN THE DEVICE WAS PHYSICALLY
3121  *  UNPLUGGED.
3122  */
3123 /*---------------------------------------------------------------------------*/
3124 if (0 == bInterfaceNumber) {
3125         peasycap = kzalloc(sizeof(struct easycap), GFP_KERNEL);
3126         if (NULL == peasycap) {
3127                 SAY("ERROR: Could not allocate peasycap\n");
3128                 return -ENOMEM;
3129         } else {
3130                 peasycap->allocation_video_struct = sizeof(struct easycap);
3131                 peasycap->allocation_video_page = 0;
3132                 peasycap->allocation_video_urb = 0;
3133                 peasycap->allocation_audio_struct = 0;
3134                 peasycap->allocation_audio_page = 0;
3135                 peasycap->allocation_audio_urb = 0;
3136         }
3137 /*---------------------------------------------------------------------------*/
3138 /*
3139  *  INITIALIZE THE NEW easycap STRUCTURE.
3140  *  NO PARAMETERS ARE SPECIFIED HERE REQUIRING THE SETTING OF REGISTERS.
3141  *  THAT IS DONE FIRST BY easycap_open() AND LATER BY easycap_ioctl().
3142  */
3143 /*---------------------------------------------------------------------------*/
3144         peasycap->pusb_device = pusb_device;
3145         peasycap->pusb_interface = pusb_interface;
3146
3147         kref_init(&peasycap->kref);
3148         JOT(8, "intf[%i]: after kref_init(..._video) " \
3149                         "%i=peasycap->kref.refcount.counter\n", \
3150                         bInterfaceNumber, peasycap->kref.refcount.counter);
3151
3152         init_waitqueue_head(&(peasycap->wq_video));
3153         init_waitqueue_head(&(peasycap->wq_audio));
3154
3155         mutex_init(&(peasycap->mutex_timeval0));
3156         mutex_init(&(peasycap->mutex_timeval1));
3157
3158         for (k = 0; k < FRAME_BUFFER_MANY; k++)
3159                 mutex_init(&(peasycap->mutex_mmap_video[k]));
3160
3161         peasycap->ilk = 0;
3162         peasycap->microphone = false;
3163
3164         peasycap->video_interface = -1;
3165         peasycap->video_altsetting_on = -1;
3166         peasycap->video_altsetting_off = -1;
3167         peasycap->video_endpointnumber = -1;
3168         peasycap->video_isoc_maxframesize = -1;
3169         peasycap->video_isoc_buffer_size = -1;
3170
3171         peasycap->audio_interface = -1;
3172         peasycap->audio_altsetting_on = -1;
3173         peasycap->audio_altsetting_off = -1;
3174         peasycap->audio_endpointnumber = -1;
3175         peasycap->audio_isoc_maxframesize = -1;
3176         peasycap->audio_isoc_buffer_size = -1;
3177
3178         peasycap->frame_buffer_many = FRAME_BUFFER_MANY;
3179
3180         if ((struct mutex *)NULL == &(peasycap->mutex_mmap_video[0])) {
3181                 SAY("ERROR: &(peasycap->mutex_mmap_video[%i]) is NULL\n", 0);
3182                 return -EFAULT;
3183         }
3184 /*---------------------------------------------------------------------------*/
3185 /*
3186  *  DYNAMICALLY FILL IN THE AVAILABLE FORMATS.
3187  */
3188 /*---------------------------------------------------------------------------*/
3189         rc = fillin_formats();
3190         if (0 > rc) {
3191                 SAY("ERROR: fillin_formats() returned %i\n", rc);
3192                 return -EFAULT;
3193         }
3194         JOT(4, "%i formats available\n", rc);
3195         } else {
3196 /*---------------------------------------------------------------------------*/
3197                 if ((struct easycap *)NULL == peasycap) {
3198                         SAY("ERROR: peasycap is NULL " \
3199                                         "when probing interface %i\n", \
3200                                                         bInterfaceNumber);
3201                         return -EFAULT;
3202                 }
3203
3204         JOT(8, "kref_get() with %i=peasycap->kref.refcount.counter\n", \
3205                                         (int)peasycap->kref.refcount.counter);
3206         kref_get(&peasycap->kref);
3207 }
3208 /*---------------------------------------------------------------------------*/
3209 if ((USB_CLASS_VIDEO == bInterfaceClass) || \
3210         (USB_CLASS_VENDOR_SPEC == bInterfaceClass)) {
3211         if (-1 == peasycap->video_interface) {
3212                 peasycap->video_interface = bInterfaceNumber;
3213                 JOT(4, "setting peasycap->video_interface=%i\n", \
3214                                                 peasycap->video_interface);
3215         } else {
3216                 if (peasycap->video_interface != bInterfaceNumber) {
3217                         SAY("ERROR: attempting to reset " \
3218                                         "peasycap->video_interface\n");
3219                         SAY("...... continuing with " \
3220                                         "%i=peasycap->video_interface\n", \
3221                                         peasycap->video_interface);
3222                 }
3223         }
3224 } else if ((USB_CLASS_AUDIO == bInterfaceClass) && \
3225                                                 (0x02 == bInterfaceSubClass)) {
3226         if (-1 == peasycap->audio_interface) {
3227                 peasycap->audio_interface = bInterfaceNumber;
3228                 JOT(4, "setting peasycap->audio_interface=%i\n", \
3229                                                  peasycap->audio_interface);
3230         } else {
3231                 if (peasycap->audio_interface != bInterfaceNumber) {
3232                         SAY("ERROR: attempting to reset " \
3233                                         "peasycap->audio_interface\n");
3234                         SAY("...... continuing with " \
3235                                         "%i=peasycap->audio_interface\n", \
3236                                         peasycap->audio_interface);
3237                 }
3238         }
3239 }
3240 /*---------------------------------------------------------------------------*/
3241 /*
3242  *  INVESTIGATE ALL ALTSETTINGS.
3243  *  DONE IN DETAIL BECAUSE USB DEVICE 05e1:0408 HAS DISPARATE INCARNATIONS.
3244  */
3245 /*---------------------------------------------------------------------------*/
3246 isokalt = 0;
3247 isokepn = 0;
3248 isokmps = 0;
3249
3250 for (i = 0; i < pusb_interface->num_altsetting; i++) {
3251         pusb_host_interface = &(pusb_interface->altsetting[i]);
3252         if ((struct usb_host_interface *)NULL == pusb_host_interface) {
3253                 SAY("ERROR: pusb_host_interface is NULL\n");
3254                 return -EFAULT;
3255         }
3256         pusb_interface_descriptor = &(pusb_host_interface->desc);
3257         if ((struct usb_interface_descriptor *)NULL == \
3258                                                 pusb_interface_descriptor) {
3259                 SAY("ERROR: pusb_interface_descriptor is NULL\n");
3260                 return -EFAULT;
3261         }
3262
3263         JOT(4, "intf[%i]alt[%i]: desc.bDescriptorType=0x%02X\n", \
3264         bInterfaceNumber, i, pusb_interface_descriptor->bDescriptorType);
3265         JOT(4, "intf[%i]alt[%i]: desc.bInterfaceNumber=0x%02X\n", \
3266         bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceNumber);
3267         JOT(4, "intf[%i]alt[%i]: desc.bAlternateSetting=0x%02X\n", \
3268         bInterfaceNumber, i, pusb_interface_descriptor->bAlternateSetting);
3269         JOT(4, "intf[%i]alt[%i]: desc.bNumEndpoints=0x%02X\n", \
3270         bInterfaceNumber, i, pusb_interface_descriptor->bNumEndpoints);
3271         JOT(4, "intf[%i]alt[%i]: desc.bInterfaceClass=0x%02X\n", \
3272         bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceClass);
3273         JOT(4, "intf[%i]alt[%i]: desc.bInterfaceSubClass=0x%02X\n", \
3274         bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceSubClass);
3275         JOT(4, "intf[%i]alt[%i]: desc.bInterfaceProtocol=0x%02X\n", \
3276         bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceProtocol);
3277         JOT(4, "intf[%i]alt[%i]: desc.iInterface=0x%02X\n", \
3278         bInterfaceNumber, i, pusb_interface_descriptor->iInterface);
3279
3280         ISOCwMaxPacketSize = -1;
3281         BULKwMaxPacketSize = -1;
3282         INTwMaxPacketSize = -1;
3283         CTRLwMaxPacketSize = -1;
3284         ISOCbEndpointAddress = 0;
3285         INTbEndpointAddress = 0;
3286
3287         if (0 == pusb_interface_descriptor->bNumEndpoints)
3288                                 JOT(4, "intf[%i]alt[%i] has no endpoints\n", \
3289                                                         bInterfaceNumber, i);
3290 /*---------------------------------------------------------------------------*/
3291         for (j = 0; j < pusb_interface_descriptor->bNumEndpoints; j++) {
3292                 pepd = &(pusb_host_interface->endpoint[j].desc);
3293                 if ((struct usb_endpoint_descriptor *)NULL == pepd) {
3294                         SAY("ERROR:  pepd is NULL.\n");
3295                         SAY("...... skipping\n");
3296                         continue;
3297                 }
3298                 wMaxPacketSize = le16_to_cpu(pepd->wMaxPacketSize);
3299                 bEndpointAddress = pepd->bEndpointAddress;
3300
3301                 JOT(4, "intf[%i]alt[%i]end[%i]: bEndpointAddress=0x%X\n", \
3302                                 bInterfaceNumber, i, j, \
3303                                 pepd->bEndpointAddress);
3304                 JOT(4, "intf[%i]alt[%i]end[%i]: bmAttributes=0x%X\n", \
3305                                 bInterfaceNumber, i, j, \
3306                                 pepd->bmAttributes);
3307                 JOT(4, "intf[%i]alt[%i]end[%i]: wMaxPacketSize=%i\n", \
3308                                 bInterfaceNumber, i, j, \
3309                                 pepd->wMaxPacketSize);
3310                 JOT(4, "intf[%i]alt[%i]end[%i]: bInterval=%i\n",
3311                                 bInterfaceNumber, i, j, \
3312                                 pepd->bInterval);
3313
3314                 if (pepd->bEndpointAddress & USB_DIR_IN) {
3315                         JOT(4, "intf[%i]alt[%i]end[%i] is an  IN  endpoint\n",\
3316                                                 bInterfaceNumber, i, j);
3317                         isin = 1;
3318                 } else {
3319                         JOT(4, "intf[%i]alt[%i]end[%i] is an  OUT endpoint\n",\
3320                                                 bInterfaceNumber, i, j);
3321                         SAY("ERROR: OUT endpoint unexpected\n");
3322                         SAY("...... continuing\n");
3323                         isin = 0;
3324                 }
3325                 if ((pepd->bmAttributes & \
3326                                 USB_ENDPOINT_XFERTYPE_MASK) == \
3327                                 USB_ENDPOINT_XFER_ISOC) {
3328                         JOT(4, "intf[%i]alt[%i]end[%i] is an ISOC endpoint\n",\
3329                                                 bInterfaceNumber, i, j);
3330                         if (isin) {
3331                                 switch (bInterfaceClass) {
3332                                 case USB_CLASS_VIDEO:
3333                                 case USB_CLASS_VENDOR_SPEC: {
3334                                         if (!peasycap) {
3335                                                 SAY("MISTAKE: " \
3336                                                         "peasycap is NULL\n");
3337                                                 return -EFAULT;
3338                                         }
3339                                         if (pepd->wMaxPacketSize) {
3340                                                 if (8 > isokalt) {
3341                                                         okalt[isokalt] = i;
3342                                                         JOT(4,\
3343                                                         "%i=okalt[%i]\n", \
3344                                                         okalt[isokalt], \
3345                                                         isokalt);
3346                                                         isokalt++;
3347                                                 }
3348                                                 if (8 > isokepn) {
3349                                                         okepn[isokepn] = \
3350                                                         pepd->\
3351                                                         bEndpointAddress & \
3352                                                         0x0F;
3353                                                         JOT(4,\
3354                                                         "%i=okepn[%i]\n", \
3355                                                         okepn[isokepn], \
3356                                                         isokepn);
3357                                                         isokepn++;
3358                                                 }
3359                                                 if (8 > isokmps) {
3360                                                         okmps[isokmps] = \
3361                                                         le16_to_cpu(pepd->\
3362                                                         wMaxPacketSize);
3363                                                         JOT(4,\
3364                                                         "%i=okmps[%i]\n", \
3365                                                         okmps[isokmps], \
3366                                                         isokmps);
3367                                                         isokmps++;
3368                                                 }
3369                                         } else {
3370                                                 if (-1 == peasycap->\
3371                                                         video_altsetting_off) {
3372                                                         peasycap->\
3373                                                         video_altsetting_off =\
3374                                                                          i;
3375                                                         JOT(4, "%i=video_" \
3376                                                         "altsetting_off " \
3377                                                                 "<====\n", \
3378                                                         peasycap->\
3379                                                         video_altsetting_off);
3380                                                 } else {
3381                                                         SAY("ERROR: peasycap" \
3382                                                         "->video_altsetting_" \
3383                                                         "off already set\n");
3384                                                         SAY("...... " \
3385                                                         "continuing with " \
3386                                                         "%i=peasycap->video_" \
3387                                                         "altsetting_off\n", \
3388                                                         peasycap->\
3389                                                         video_altsetting_off);
3390                                                 }
3391                                         }
3392                                         break;
3393                                 }
3394                                 case USB_CLASS_AUDIO: {
3395                                         if (0x02 != bInterfaceSubClass)
3396                                                 break;
3397                                         if (!peasycap) {
3398                                                 SAY("MISTAKE: " \
3399                                                 "peasycap is NULL\n");
3400                                                 return -EFAULT;
3401                                         }
3402                                         if (pepd->wMaxPacketSize) {
3403                                                 if (8 > isokalt) {
3404                                                         okalt[isokalt] = i ;
3405                                                         JOT(4,\
3406                                                         "%i=okalt[%i]\n", \
3407                                                         okalt[isokalt], \
3408                                                         isokalt);
3409                                                         isokalt++;
3410                                                 }
3411                                                 if (8 > isokepn) {
3412                                                         okepn[isokepn] = \
3413                                                         pepd->\
3414                                                         bEndpointAddress & \
3415                                                         0x0F;
3416                                                         JOT(4,\
3417                                                         "%i=okepn[%i]\n", \
3418                                                         okepn[isokepn], \
3419                                                         isokepn);
3420                                                         isokepn++;
3421                                                 }
3422                                                 if (8 > isokmps) {
3423                                                         okmps[isokmps] = \
3424                                                         le16_to_cpu(pepd->\
3425                                                         wMaxPacketSize);
3426                                                         JOT(4,\
3427                                                         "%i=okmps[%i]\n",\
3428                                                         okmps[isokmps], \
3429                                                         isokmps);
3430                                                         isokmps++;
3431                                                 }
3432                                         } else {
3433                                                 if (-1 == peasycap->\
3434                                                         audio_altsetting_off) {
3435                                                         peasycap->\
3436                                                         audio_altsetting_off =\
3437                                                                          i;
3438                                                         JOT(4, "%i=audio_" \
3439                                                         "altsetting_off " \
3440                                                         "<====\n", \
3441                                                         peasycap->\
3442                                                         audio_altsetting_off);
3443                                                 } else {
3444                                                         SAY("ERROR: peasycap" \
3445                                                         "->audio_altsetting_" \
3446                                                         "off already set\n");
3447                                                         SAY("...... " \
3448                                                         "continuing with " \
3449                                                         "%i=peasycap->\
3450                                                         audio_altsetting_" \
3451                                                         "off\n",
3452                                                         peasycap->\
3453                                                         audio_altsetting_off);
3454                                                 }
3455                                         }
3456                                 break;
3457                                 }
3458                                 default:
3459                                         break;
3460                                 }
3461                         }
3462                 } else if ((pepd->bmAttributes & \
3463                                                 USB_ENDPOINT_XFERTYPE_MASK) ==\
3464                                                 USB_ENDPOINT_XFER_BULK) {
3465                         JOT(4, "intf[%i]alt[%i]end[%i] is a  BULK endpoint\n",\
3466                                                 bInterfaceNumber, i, j);
3467                 } else if ((pepd->bmAttributes & \
3468                                                 USB_ENDPOINT_XFERTYPE_MASK) ==\
3469                                                 USB_ENDPOINT_XFER_INT) {
3470                         JOT(4, "intf[%i]alt[%i]end[%i] is an  INT endpoint\n",\
3471                                                 bInterfaceNumber, i, j);
3472                 } else {
3473                         JOT(4, "intf[%i]alt[%i]end[%i] is a  CTRL endpoint\n",\
3474                                                 bInterfaceNumber, i, j);
3475                 }
3476                 if (0 == pepd->wMaxPacketSize) {
3477                         JOT(4, "intf[%i]alt[%i]end[%i] " \
3478                                                 "has zero packet size\n", \
3479                                                 bInterfaceNumber, i, j);
3480                 }
3481         }
3482 }
3483 /*---------------------------------------------------------------------------*/
3484 /*
3485  *  PERFORM INITIALIZATION OF THE PROBED INTERFACE
3486  */
3487 /*---------------------------------------------------------------------------*/
3488 JOT(4, "initialization begins for interface %i\n", \
3489                                 pusb_interface_descriptor->bInterfaceNumber);
3490 switch (bInterfaceNumber) {
3491 /*---------------------------------------------------------------------------*/
3492 /*
3493  *  INTERFACE 0 IS THE VIDEO INTERFACE
3494  */
3495 /*---------------------------------------------------------------------------*/
3496 case 0: {
3497         if (!peasycap) {
3498                 SAY("MISTAKE: peasycap is NULL\n");
3499                 return -EFAULT;
3500         }
3501         if (!isokalt) {
3502                 SAY("ERROR:  no viable video_altsetting_on\n");
3503                 return -ENOENT;
3504         } else {
3505                 peasycap->video_altsetting_on = okalt[isokalt - 1];
3506                 JOT(4, "%i=video_altsetting_on <====\n", \
3507                                         peasycap->video_altsetting_on);
3508         }
3509         if (!isokepn) {
3510                 SAY("ERROR:  no viable video_endpointnumber\n");
3511                 return -ENOENT;
3512         } else {
3513                 peasycap->video_endpointnumber = okepn[isokepn - 1];
3514                 JOT(4, "%i=video_endpointnumber\n", \
3515                                         peasycap->video_endpointnumber);
3516                 }
3517         if (!isokmps) {
3518                 SAY("ERROR:  no viable video_maxpacketsize\n");
3519                 return -ENOENT;
3520 /*---------------------------------------------------------------------------*/
3521 /*
3522  *  DECIDE THE VIDEO STREAMING PARAMETERS
3523  */
3524 /*---------------------------------------------------------------------------*/
3525         } else {
3526                 maxpacketsize = okmps[isokmps - 1] - 1024;
3527                 if (USB_2_0_MAXPACKETSIZE > maxpacketsize) {
3528                         peasycap->video_isoc_maxframesize = maxpacketsize;
3529                 } else {
3530                         peasycap->video_isoc_maxframesize = \
3531                                                         USB_2_0_MAXPACKETSIZE;
3532                 }
3533                 JOT(4, "%i=video_isoc_maxframesize\n", \
3534                                         peasycap->video_isoc_maxframesize);
3535                 if (0 >= peasycap->video_isoc_maxframesize) {
3536                         SAY("ERROR:  bad video_isoc_maxframesize\n");
3537                         return -ENOENT;
3538                 }
3539                 peasycap->video_isoc_framesperdesc = VIDEO_ISOC_FRAMESPERDESC;
3540                 JOT(4, "%i=video_isoc_framesperdesc\n", \
3541                                         peasycap->video_isoc_framesperdesc);
3542                 if (0 >= peasycap->video_isoc_framesperdesc) {
3543                         SAY("ERROR:  bad video_isoc_framesperdesc\n");
3544                         return -ENOENT;
3545                 }
3546                 peasycap->video_isoc_buffer_size = \
3547                                         peasycap->video_isoc_maxframesize * \
3548                                         peasycap->video_isoc_framesperdesc;
3549                 JOT(4, "%i=video_isoc_buffer_size\n", \
3550                                         peasycap->video_isoc_buffer_size);
3551                 if ((PAGE_SIZE << VIDEO_ISOC_ORDER) < \
3552                                         peasycap->video_isoc_buffer_size) {
3553                         SAY("MISTAKE: " \
3554                                 "peasycap->video_isoc_buffer_size too big\n");
3555                         return -EFAULT;
3556                 }
3557         }
3558 /*---------------------------------------------------------------------------*/
3559         if (-1 == peasycap->video_interface) {
3560                 SAY("MISTAKE:  video_interface is unset\n");
3561                 return -EFAULT;
3562         }
3563         if (-1 == peasycap->video_altsetting_on) {
3564                 SAY("MISTAKE:  video_altsetting_on is unset\n");
3565                 return -EFAULT;
3566         }
3567         if (-1 == peasycap->video_altsetting_off) {
3568                 SAY("MISTAKE:  video_interface_off is unset\n");
3569                 return -EFAULT;
3570         }
3571         if (-1 == peasycap->video_endpointnumber) {
3572                 SAY("MISTAKE:  video_endpointnumber is unset\n");
3573                 return -EFAULT;
3574         }
3575         if (-1 == peasycap->video_isoc_maxframesize) {
3576                 SAY("MISTAKE:  video_isoc_maxframesize is unset\n");
3577                 return -EFAULT;
3578         }
3579         if (-1 == peasycap->video_isoc_buffer_size) {
3580                 SAY("MISTAKE:  video_isoc_buffer_size is unset\n");
3581                 return -EFAULT;
3582         }
3583 /*---------------------------------------------------------------------------*/
3584 /*
3585  *  ALLOCATE MEMORY FOR VIDEO BUFFERS.  LISTS MUST BE INITIALIZED FIRST.
3586  */
3587 /*---------------------------------------------------------------------------*/
3588         INIT_LIST_HEAD(&(peasycap->urb_video_head));
3589         peasycap->purb_video_head = &(peasycap->urb_video_head);
3590 /*---------------------------------------------------------------------------*/
3591         JOT(4, "allocating %i frame buffers of size %li\n",  \
3592                         FRAME_BUFFER_MANY, (long int)FRAME_BUFFER_SIZE);
3593         JOT(4, ".... each scattered over %li pages\n", \
3594                                                 FRAME_BUFFER_SIZE/PAGE_SIZE);
3595
3596         for (k = 0;  k < FRAME_BUFFER_MANY;  k++) {
3597                 for (m = 0;  m < FRAME_BUFFER_SIZE/PAGE_SIZE;  m++) {
3598                         if ((void *)NULL != peasycap->frame_buffer[k][m].pgo)
3599                                 SAY("attempting to reallocate frame " \
3600                                                                 " buffers\n");
3601                         else {
3602                                 pbuf = (void *)__get_free_page(GFP_KERNEL);
3603                                 if ((void *)NULL == pbuf) {
3604                                         SAY("ERROR: Could not allocate frame "\
3605                                                 "buffer %i page %i\n", k, m);
3606                                         return -ENOMEM;
3607                                 } else
3608                                         peasycap->allocation_video_page += 1;
3609                                 peasycap->frame_buffer[k][m].pgo = pbuf;
3610                         }
3611                         peasycap->frame_buffer[k][m].pto = \
3612                                         peasycap->frame_buffer[k][m].pgo;
3613                 }
3614         }
3615
3616         peasycap->frame_fill = 0;
3617         peasycap->frame_read = 0;
3618         JOT(4, "allocation of frame buffers done:  %i pages\n", k * \
3619                                                                 m);
3620 /*---------------------------------------------------------------------------*/
3621         JOT(4, "allocating %i field buffers of size %li\n",  \
3622                         FIELD_BUFFER_MANY, (long int)FIELD_BUFFER_SIZE);
3623         JOT(4, ".... each scattered over %li pages\n", \
3624                                         FIELD_BUFFER_SIZE/PAGE_SIZE);
3625
3626         for (k = 0;  k < FIELD_BUFFER_MANY;  k++) {
3627                 for (m = 0;  m < FIELD_BUFFER_SIZE/PAGE_SIZE;  m++) {
3628                         if ((void *)NULL != peasycap->field_buffer[k][m].pgo) {
3629                                 SAY("ERROR: attempting to reallocate " \
3630                                                         "field buffers\n");
3631                         } else {
3632                                 pbuf = (void *) __get_free_page(GFP_KERNEL);
3633                                 if ((void *)NULL == pbuf) {
3634                                         SAY("ERROR: Could not allocate field" \
3635                                                 " buffer %i page %i\n", k, m);
3636                                         return -ENOMEM;
3637                                         }
3638                                 else
3639                                         peasycap->allocation_video_page += 1;
3640                                 peasycap->field_buffer[k][m].pgo = pbuf;
3641                                 }
3642                         peasycap->field_buffer[k][m].pto = \
3643                                         peasycap->field_buffer[k][m].pgo;
3644                 }
3645                 peasycap->field_buffer[k][0].kount = 0x0200;
3646         }
3647         peasycap->field_fill = 0;
3648         peasycap->field_page = 0;
3649         peasycap->field_read = 0;
3650         JOT(4, "allocation of field buffers done:  %i pages\n", k * \
3651                                                                 m);
3652 /*---------------------------------------------------------------------------*/
3653         JOT(4, "allocating %i isoc video buffers of size %i\n",  \
3654                                         VIDEO_ISOC_BUFFER_MANY, \
3655                                         peasycap->video_isoc_buffer_size);
3656         JOT(4, ".... each occupying contiguous memory pages\n");
3657
3658         for (k = 0;  k < VIDEO_ISOC_BUFFER_MANY; k++) {
3659                 pbuf = (void *)__get_free_pages(GFP_KERNEL, VIDEO_ISOC_ORDER);
3660                 if (NULL == pbuf) {
3661                         SAY("ERROR: Could not allocate isoc video buffer " \
3662                                                                 "%i\n", k);
3663                         return -ENOMEM;
3664                 } else
3665                         peasycap->allocation_video_page += \
3666                                 ((unsigned int)(0x01 << VIDEO_ISOC_ORDER));
3667
3668                 peasycap->video_isoc_buffer[k].pgo = pbuf;
3669                 peasycap->video_isoc_buffer[k].pto = pbuf + \
3670                                         peasycap->video_isoc_buffer_size;
3671                 peasycap->video_isoc_buffer[k].kount = k;
3672         }
3673         JOT(4, "allocation of isoc video buffers done: %i pages\n", \
3674                                         k * (0x01 << VIDEO_ISOC_ORDER));
3675 /*---------------------------------------------------------------------------*/
3676 /*
3677  *  ALLOCATE AND INITIALIZE MULTIPLE struct urb ...
3678  */
3679 /*---------------------------------------------------------------------------*/
3680         JOT(4, "allocating %i struct urb.\n", VIDEO_ISOC_BUFFER_MANY);
3681         JOT(4, "using %i=peasycap->video_isoc_framesperdesc\n", \
3682                                         peasycap->video_isoc_framesperdesc);
3683         JOT(4, "using %i=peasycap->video_isoc_maxframesize\n", \
3684                                         peasycap->video_isoc_maxframesize);
3685         JOT(4, "using %i=peasycap->video_isoc_buffer_sizen", \
3686                                         peasycap->video_isoc_buffer_size);
3687
3688         for (k = 0;  k < VIDEO_ISOC_BUFFER_MANY; k++) {
3689                 purb = usb_alloc_urb(peasycap->video_isoc_framesperdesc, \
3690                                                                 GFP_KERNEL);
3691                 if (NULL == purb) {
3692                         SAY("ERROR: usb_alloc_urb returned NULL for buffer " \
3693                                                                 "%i\n", k);
3694                         return -ENOMEM;
3695                 } else
3696                         peasycap->allocation_video_urb += 1;
3697 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
3698                 pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL);
3699                 if (NULL == pdata_urb) {
3700                         SAY("ERROR: Could not allocate struct data_urb.\n");
3701                         return -ENOMEM;
3702                 } else
3703                         peasycap->allocation_video_struct += \
3704                                                 sizeof(struct data_urb);
3705
3706                 pdata_urb->purb = purb;
3707                 pdata_urb->isbuf = k;
3708                 pdata_urb->length = 0;
3709                 list_add_tail(&(pdata_urb->list_head), \
3710                                                 peasycap->purb_video_head);
3711 /*---------------------------------------------------------------------------*/
3712 /*
3713  *  ... AND INITIALIZE THEM
3714  */
3715 /*---------------------------------------------------------------------------*/
3716                 if (!k) {
3717                         JOT(4, "initializing video urbs thus:\n");
3718                         JOT(4, "  purb->interval = 1;\n");
3719                         JOT(4, "  purb->dev = peasycap->pusb_device;\n");
3720                         JOT(4, "  purb->pipe = usb_rcvisocpipe" \
3721                                         "(peasycap->pusb_device,%i);\n", \
3722                                         peasycap->video_endpointnumber);
3723                         JOT(4, "  purb->transfer_flags = URB_ISO_ASAP;\n");
3724                         JOT(4, "  purb->transfer_buffer = peasycap->" \
3725                                         "video_isoc_buffer[.].pgo;\n");
3726                         JOT(4, "  purb->transfer_buffer_length = %i;\n", \
3727                                         peasycap->video_isoc_buffer_size);
3728                         JOT(4, "  purb->complete = easycap_complete;\n");
3729                         JOT(4, "  purb->context = peasycap;\n");
3730                         JOT(4, "  purb->start_frame = 0;\n");
3731                         JOT(4, "  purb->number_of_packets = %i;\n", \
3732                                         peasycap->video_isoc_framesperdesc);
3733                         JOT(4, "  for (j = 0; j < %i; j++)\n", \
3734                                         peasycap->video_isoc_framesperdesc);
3735                         JOT(4, "    {\n");
3736                         JOT(4, "    purb->iso_frame_desc[j].offset = j*%i;\n",\
3737                                         peasycap->video_isoc_maxframesize);
3738                         JOT(4, "    purb->iso_frame_desc[j].length = %i;\n", \
3739                                         peasycap->video_isoc_maxframesize);
3740                         JOT(4, "    }\n");
3741                 }
3742
3743                 purb->interval = 1;
3744                 purb->dev = peasycap->pusb_device;
3745                 purb->pipe = usb_rcvisocpipe(peasycap->pusb_device, \
3746                                         peasycap->video_endpointnumber);
3747                 purb->transfer_flags = URB_ISO_ASAP;
3748                 purb->transfer_buffer = peasycap->video_isoc_buffer[k].pgo;
3749                 purb->transfer_buffer_length = \
3750                                         peasycap->video_isoc_buffer_size;
3751                 purb->complete = easycap_complete;
3752                 purb->context = peasycap;
3753                 purb->start_frame = 0;
3754                 purb->number_of_packets = peasycap->video_isoc_framesperdesc;
3755                 for (j = 0;  j < peasycap->video_isoc_framesperdesc; j++) {
3756                         purb->iso_frame_desc[j].offset = j * \
3757                                         peasycap->video_isoc_maxframesize;
3758                         purb->iso_frame_desc[j].length = \
3759                                         peasycap->video_isoc_maxframesize;
3760                 }
3761         }
3762         JOT(4, "allocation of %i struct urb done.\n", k);
3763 /*--------------------------------------------------------------------------*/
3764 /*
3765  *  SAVE POINTER peasycap IN THIS INTERFACE.
3766  */
3767 /*--------------------------------------------------------------------------*/
3768         usb_set_intfdata(pusb_interface, peasycap);
3769 /*--------------------------------------------------------------------------*/
3770 /*
3771  *  THE VIDEO DEVICE CAN BE REGISTERED NOW, AS IT IS READY.
3772  */
3773 /*--------------------------------------------------------------------------*/
3774 #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
3775         if (0 != (usb_register_dev(pusb_interface, &easycap_class))) {
3776                 err("Not able to get a minor for this device");
3777                 usb_set_intfdata(pusb_interface, NULL);
3778                 return -ENODEV;
3779         } else
3780                 (peasycap->registered_video)++;
3781         SAY("easycap attached to minor #%d\n", pusb_interface->minor);
3782         break;
3783 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
3784 #else
3785         pvideo_device = (struct video_device *)\
3786                         kzalloc(sizeof(struct video_device), GFP_KERNEL);
3787         if ((struct video_device *)NULL == pvideo_device) {
3788                 SAY("ERROR: Could not allocate structure video_device\n");
3789                 return -ENOMEM;
3790         }
3791         if (VIDEO_DEVICE_MANY <= video_device_many) {
3792                 SAY("ERROR: Too many /dev/videos\n");
3793                 return -ENOMEM;
3794         }
3795         pvideo_array[video_device_many] = pvideo_device;  video_device_many++;
3796
3797         strcpy(&pvideo_device->name[0], "easycapdc60");
3798 #if defined(EASYCAP_NEEDS_V4L2_FOPS)
3799         pvideo_device->fops = &v4l2_fops;
3800 #else
3801         pvideo_device->fops = &easycap_fops;
3802 #endif /*EASYCAP_NEEDS_V4L2_FOPS*/
3803         pvideo_device->minor = -1;
3804         pvideo_device->release = (void *)(&videodev_release);
3805
3806         video_set_drvdata(pvideo_device, (void *)peasycap);
3807
3808         rc = video_register_device(pvideo_device, VFL_TYPE_GRABBER, -1);
3809         if (0 != rc) {
3810                 err("Not able to register with videodev");
3811                 videodev_release(pvideo_device);
3812                 return -ENODEV;
3813         } else {
3814                 peasycap->pvideo_device = pvideo_device;
3815                 (peasycap->registered_video)++;
3816                 JOT(4, "registered with videodev: %i=minor\n", \
3817                                                         pvideo_device->minor);
3818         }
3819 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
3820 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
3821         break;
3822 }
3823 /*--------------------------------------------------------------------------*/
3824 /*
3825  *  INTERFACE 1 IS THE AUDIO CONTROL INTERFACE
3826  *  INTERFACE 2 IS THE AUDIO STREAMING INTERFACE
3827  */
3828 /*--------------------------------------------------------------------------*/
3829 case 1: {
3830 /*--------------------------------------------------------------------------*/
3831 /*
3832  *  SAVE POINTER peasycap IN INTERFACE 1
3833  */
3834 /*--------------------------------------------------------------------------*/
3835         usb_set_intfdata(pusb_interface, peasycap);
3836         JOT(4, "no initialization required for interface %i\n", \
3837                                 pusb_interface_descriptor->bInterfaceNumber);
3838         break;
3839 }
3840 /*--------------------------------------------------------------------------*/
3841 case 2: {
3842         if (!peasycap) {
3843                 SAY("MISTAKE: peasycap is NULL\n");
3844                 return -EFAULT;
3845         }
3846         if (!isokalt) {
3847                 SAY("ERROR:  no viable audio_altsetting_on\n");
3848                 return -ENOENT;
3849         } else {
3850                 peasycap->audio_altsetting_on = okalt[isokalt - 1];
3851                 JOT(4, "%i=audio_altsetting_on <====\n", \
3852                                                 peasycap->audio_altsetting_on);
3853         }
3854         if (!isokepn) {
3855                 SAY("ERROR:  no viable audio_endpointnumber\n");
3856                 return -ENOENT;
3857         } else {
3858                 peasycap->audio_endpointnumber = okepn[isokepn - 1];
3859                 JOT(4, "%i=audio_endpointnumber\n", \
3860                                         peasycap->audio_endpointnumber);
3861         }
3862         if (!isokmps) {
3863                 SAY("ERROR:  no viable audio_maxpacketsize\n");
3864                 return -ENOENT;
3865         } else {
3866                 peasycap->audio_isoc_maxframesize = okmps[isokmps - 1];
3867                 JOT(4, "%i=audio_isoc_maxframesize\n", \
3868                                         peasycap->audio_isoc_maxframesize);
3869                 if (0 >= peasycap->audio_isoc_maxframesize) {
3870                         SAY("ERROR:  bad audio_isoc_maxframesize\n");
3871                         return -ENOENT;
3872                 }
3873                 if (9 == peasycap->audio_isoc_maxframesize) {
3874                         peasycap->ilk |= 0x02;
3875                         SAY("hardware is FOUR-CVBS\n");
3876                         peasycap->microphone = true;
3877                         peasycap->audio_pages_per_fragment = 4;
3878                 } else if (256 == peasycap->audio_isoc_maxframesize) {
3879                         peasycap->ilk &= ~0x02;
3880                         SAY("hardware is CVBS+S-VIDEO\n");
3881                         peasycap->microphone = false;
3882                         peasycap->audio_pages_per_fragment = 4;
3883                 } else {
3884                         SAY("hardware is unidentified:\n");
3885                         SAY("%i=audio_isoc_maxframesize\n", \
3886                                         peasycap->audio_isoc_maxframesize);
3887                         return -ENOENT;
3888                 }
3889
3890                 peasycap->audio_bytes_per_fragment = \
3891                                         peasycap->audio_pages_per_fragment * \
3892                                                                 PAGE_SIZE ;
3893                 peasycap->audio_buffer_page_many = (AUDIO_FRAGMENT_MANY * \
3894                                         peasycap->audio_pages_per_fragment);
3895
3896                 JOT(4, "%6i=AUDIO_FRAGMENT_MANY\n", AUDIO_FRAGMENT_MANY);
3897                 JOT(4, "%6i=audio_pages_per_fragment\n", \
3898                                         peasycap->audio_pages_per_fragment);
3899                 JOT(4, "%6i=audio_bytes_per_fragment\n", \
3900                                         peasycap->audio_bytes_per_fragment);
3901                 JOT(4, "%6i=audio_buffer_page_many\n", \
3902                                         peasycap->audio_buffer_page_many);
3903
3904                 peasycap->audio_isoc_framesperdesc = 128;
3905
3906                 JOT(4, "%i=audio_isoc_framesperdesc\n", \
3907                                         peasycap->audio_isoc_framesperdesc);
3908                 if (0 >= peasycap->audio_isoc_framesperdesc) {
3909                         SAY("ERROR:  bad audio_isoc_framesperdesc\n");
3910                         return -ENOENT;
3911                 }
3912
3913                 peasycap->audio_isoc_buffer_size = \
3914                                 peasycap->audio_isoc_maxframesize * \
3915                                 peasycap->audio_isoc_framesperdesc;
3916                 JOT(4, "%i=audio_isoc_buffer_size\n", \
3917                                         peasycap->audio_isoc_buffer_size);
3918                 if (AUDIO_ISOC_BUFFER_SIZE < \
3919                                         peasycap->audio_isoc_buffer_size) {
3920                         SAY("MISTAKE:  audio_isoc_buffer_size bigger "
3921                         "than %li=AUDIO_ISOC_BUFFER_SIZE\n", \
3922                                                 AUDIO_ISOC_BUFFER_SIZE);
3923                         return -EFAULT;
3924                 }
3925         }
3926
3927         if (-1 == peasycap->audio_interface) {
3928                 SAY("MISTAKE:  audio_interface is unset\n");
3929                 return -EFAULT;
3930         }
3931         if (-1 == peasycap->audio_altsetting_on) {
3932                 SAY("MISTAKE:  audio_altsetting_on is unset\n");
3933                 return -EFAULT;
3934         }
3935         if (-1 == peasycap->audio_altsetting_off) {
3936                 SAY("MISTAKE:  audio_interface_off is unset\n");
3937                 return -EFAULT;
3938         }
3939         if (-1 == peasycap->audio_endpointnumber) {
3940                 SAY("MISTAKE:  audio_endpointnumber is unset\n");
3941                 return -EFAULT;
3942         }
3943         if (-1 == peasycap->audio_isoc_maxframesize) {
3944                 SAY("MISTAKE:  audio_isoc_maxframesize is unset\n");
3945                 return -EFAULT;
3946         }
3947         if (-1 == peasycap->audio_isoc_buffer_size) {
3948                 SAY("MISTAKE:  audio_isoc_buffer_size is unset\n");
3949                 return -EFAULT;
3950         }
3951 /*---------------------------------------------------------------------------*/
3952 /*
3953  *  ALLOCATE MEMORY FOR AUDIO BUFFERS.  LISTS MUST BE INITIALIZED FIRST.
3954  */
3955 /*---------------------------------------------------------------------------*/
3956         INIT_LIST_HEAD(&(peasycap->urb_audio_head));
3957         peasycap->purb_audio_head = &(peasycap->urb_audio_head);
3958
3959         JOT(4, "allocating an audio buffer\n");
3960         JOT(4, ".... scattered over %i pages\n", \
3961                                         peasycap->audio_buffer_page_many);
3962
3963         for (k = 0;  k < peasycap->audio_buffer_page_many;  k++) {
3964                 if ((void *)NULL != peasycap->audio_buffer[k].pgo) {
3965                         SAY("ERROR: attempting to reallocate audio buffers\n");
3966                 } else {
3967                         pbuf = (void *) __get_free_page(GFP_KERNEL);
3968                         if ((void *)NULL == pbuf) {
3969                                 SAY("ERROR: Could not allocate audio " \
3970                                                         "buffer page %i\n", k);
3971                                 return -ENOMEM;
3972                         } else
3973                                 peasycap->allocation_audio_page += 1;
3974
3975                         peasycap->audio_buffer[k].pgo = pbuf;
3976                 }
3977                 peasycap->audio_buffer[k].pto = peasycap->audio_buffer[k].pgo;
3978         }
3979
3980         peasycap->audio_fill = 0;
3981         peasycap->audio_read = 0;
3982         JOT(4, "allocation of audio buffer done:  %i pages\n", k);
3983 /*---------------------------------------------------------------------------*/
3984         JOT(4, "allocating %i isoc audio buffers of size %i\n",  \
3985                 AUDIO_ISOC_BUFFER_MANY, peasycap->audio_isoc_buffer_size);
3986         JOT(4, ".... each occupying contiguous memory pages\n");
3987
3988         for (k = 0;  k < AUDIO_ISOC_BUFFER_MANY;  k++) {
3989                 pbuf = (void *)__get_free_pages(GFP_KERNEL, AUDIO_ISOC_ORDER);
3990                 if (NULL == pbuf) {
3991                         SAY("ERROR: Could not allocate isoc audio buffer " \
3992                                                         "%i\n", k);
3993                         return -ENOMEM;
3994                 } else
3995                         peasycap->allocation_audio_page += \
3996                                 ((unsigned int)(0x01 << AUDIO_ISOC_ORDER));
3997
3998                 peasycap->audio_isoc_buffer[k].pgo = pbuf;
3999                 peasycap->audio_isoc_buffer[k].pto = pbuf + \
4000                 peasycap->audio_isoc_buffer_size;
4001                 peasycap->audio_isoc_buffer[k].kount = k;
4002         }
4003         JOT(4, "allocation of isoc audio buffers done.\n");
4004 /*---------------------------------------------------------------------------*/
4005 /*
4006  *  ALLOCATE AND INITIALIZE MULTIPLE struct urb ...
4007  */
4008 /*---------------------------------------------------------------------------*/
4009         JOT(4, "allocating %i struct urb.\n", AUDIO_ISOC_BUFFER_MANY);
4010         JOT(4, "using %i=peasycap->audio_isoc_framesperdesc\n", \
4011                                         peasycap->audio_isoc_framesperdesc);
4012         JOT(4, "using %i=peasycap->audio_isoc_maxframesize\n", \
4013                                         peasycap->audio_isoc_maxframesize);
4014         JOT(4, "using %i=peasycap->audio_isoc_buffer_size\n", \
4015                                         peasycap->audio_isoc_buffer_size);
4016
4017         for (k = 0;  k < AUDIO_ISOC_BUFFER_MANY; k++) {
4018                 purb = usb_alloc_urb(peasycap->audio_isoc_framesperdesc, \
4019                                                                 GFP_KERNEL);
4020                 if (NULL == purb) {
4021                         SAY("ERROR: usb_alloc_urb returned NULL for buffer " \
4022                                                         "%i\n", k);
4023                         return -ENOMEM;
4024                 } else
4025                         peasycap->allocation_audio_urb += 1 ;
4026 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
4027                 pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL);
4028                 if (NULL == pdata_urb) {
4029                         SAY("ERROR: Could not allocate struct data_urb.\n");
4030                         return -ENOMEM;
4031                 } else
4032                         peasycap->allocation_audio_struct += \
4033                                                 sizeof(struct data_urb);
4034
4035                 pdata_urb->purb = purb;
4036                 pdata_urb->isbuf = k;
4037                 pdata_urb->length = 0;
4038                 list_add_tail(&(pdata_urb->list_head), \
4039                                                 peasycap->purb_audio_head);
4040 /*---------------------------------------------------------------------------*/
4041 /*
4042  *  ... AND INITIALIZE THEM
4043  */
4044 /*---------------------------------------------------------------------------*/
4045                 if (!k) {
4046                         JOT(4, "initializing audio urbs thus:\n");
4047                         JOT(4, "  purb->interval = 1;\n");
4048                         JOT(4, "  purb->dev = peasycap->pusb_device;\n");
4049                         JOT(4, "  purb->pipe = usb_rcvisocpipe(peasycap->" \
4050                                         "pusb_device,%i);\n", \
4051                                         peasycap->audio_endpointnumber);
4052                         JOT(4, "  purb->transfer_flags = URB_ISO_ASAP;\n");
4053                         JOT(4, "  purb->transfer_buffer = " \
4054                                 "peasycap->audio_isoc_buffer[.].pgo;\n");
4055                         JOT(4, "  purb->transfer_buffer_length = %i;\n", \
4056                                         peasycap->audio_isoc_buffer_size);
4057                         JOT(4, "  purb->complete = easysnd_complete;\n");
4058                         JOT(4, "  purb->context = peasycap;\n");
4059                         JOT(4, "  purb->start_frame = 0;\n");
4060                         JOT(4, "  purb->number_of_packets = %i;\n", \
4061                                         peasycap->audio_isoc_framesperdesc);
4062                         JOT(4, "  for (j = 0; j < %i; j++)\n", \
4063                                         peasycap->audio_isoc_framesperdesc);
4064                         JOT(4, "    {\n");
4065                         JOT(4, "    purb->iso_frame_desc[j].offset = j*%i;\n",\
4066                                         peasycap->audio_isoc_maxframesize);
4067                         JOT(4, "    purb->iso_frame_desc[j].length = %i;\n", \
4068                                         peasycap->audio_isoc_maxframesize);
4069                         JOT(4, "    }\n");
4070                         }
4071
4072                 purb->interval = 1;
4073                 purb->dev = peasycap->pusb_device;
4074                 purb->pipe = usb_rcvisocpipe(peasycap->pusb_device, \
4075                                         peasycap->audio_endpointnumber);
4076                 purb->transfer_flags = URB_ISO_ASAP;
4077                 purb->transfer_buffer = peasycap->audio_isoc_buffer[k].pgo;
4078                 purb->transfer_buffer_length = \
4079                                         peasycap->audio_isoc_buffer_size;
4080                 purb->complete = easysnd_complete;
4081                 purb->context = peasycap;
4082                 purb->start_frame = 0;
4083                 purb->number_of_packets = peasycap->audio_isoc_framesperdesc;
4084                 for (j = 0;  j < peasycap->audio_isoc_framesperdesc; j++) {
4085                         purb->iso_frame_desc[j].offset = j * \
4086                                         peasycap->audio_isoc_maxframesize;
4087                         purb->iso_frame_desc[j].length = \
4088                                         peasycap->audio_isoc_maxframesize;
4089                 }
4090         }
4091         JOT(4, "allocation of %i struct urb done.\n", k);
4092 /*---------------------------------------------------------------------------*/
4093 /*
4094  *  SAVE POINTER peasycap IN THIS INTERFACE.
4095  */
4096 /*---------------------------------------------------------------------------*/
4097         usb_set_intfdata(pusb_interface, peasycap);
4098 /*---------------------------------------------------------------------------*/
4099 /*
4100  *  THE AUDIO DEVICE CAN BE REGISTERED NOW, AS IT IS READY.
4101  */
4102 /*---------------------------------------------------------------------------*/
4103         rc = usb_register_dev(pusb_interface, &easysnd_class);
4104         if (0 != rc) {
4105                 err("Not able to get a minor for this device.");
4106                 usb_set_intfdata(pusb_interface, NULL);
4107                 return -ENODEV;
4108         } else
4109                 (peasycap->registered_audio)++;
4110 /*---------------------------------------------------------------------------*/
4111 /*
4112  *  LET THE USER KNOW WHAT NODE THE AUDIO DEVICE IS ATTACHED TO.
4113  */
4114 /*---------------------------------------------------------------------------*/
4115         SAY("easysnd attached to minor #%d\n", pusb_interface->minor);
4116         break;
4117 }
4118 /*---------------------------------------------------------------------------*/
4119 /*
4120  *  INTERFACES OTHER THAN 0, 1 AND 2 ARE UNEXPECTED
4121  */
4122 /*---------------------------------------------------------------------------*/
4123 default: {
4124         JOT(4, "ERROR: unexpected interface %i\n", bInterfaceNumber);
4125         return -EINVAL;
4126 }
4127 }
4128 JOT(4, "ends successfully for interface %i\n", \
4129                                 pusb_interface_descriptor->bInterfaceNumber);
4130 return 0;
4131 }
4132 /*****************************************************************************/
4133 /*---------------------------------------------------------------------------*/
4134 /*
4135  *  WHEN THIS FUNCTION IS CALLED THE DEVICE HAS ALREADY BEEN PHYSICALLY
4136  *  UNPLUGGED.
4137  *  HENCE peasycap->pusb_device IS NO LONGER VALID AND MUST BE SET TO NULL.
4138  */
4139 /*---------------------------------------------------------------------------*/
4140 void
4141 easycap_usb_disconnect(struct usb_interface *pusb_interface)
4142 {
4143 struct usb_host_interface *pusb_host_interface;
4144 struct usb_interface_descriptor *pusb_interface_descriptor;
4145 __u8 bInterfaceNumber;
4146 struct easycap *peasycap;
4147
4148 struct list_head *plist_head;
4149 struct data_urb *pdata_urb;
4150 int minor, m;
4151
4152 JOT(4, "\n");
4153
4154 if ((struct usb_interface *)NULL == pusb_interface) {
4155         JOT(4, "ERROR: pusb_interface is NULL\n");
4156         return;
4157 }
4158 pusb_host_interface = pusb_interface->cur_altsetting;
4159 if ((struct usb_host_interface *)NULL == pusb_host_interface) {
4160         JOT(4, "ERROR: pusb_host_interface is NULL\n");
4161         return;
4162 }
4163 pusb_interface_descriptor = &(pusb_host_interface->desc);
4164 if ((struct usb_interface_descriptor *)NULL == pusb_interface_descriptor) {
4165         JOT(4, "ERROR: pusb_interface_descriptor is NULL\n");
4166         return;
4167 }
4168 bInterfaceNumber = pusb_interface_descriptor->bInterfaceNumber;
4169 minor = pusb_interface->minor;
4170 JOT(4, "intf[%i]: minor=%i\n", bInterfaceNumber, minor);
4171
4172 peasycap = usb_get_intfdata(pusb_interface);
4173 if ((struct easycap *)NULL == peasycap)
4174         SAY("ERROR: peasycap is NULL\n");
4175 else {
4176         peasycap->pusb_device = (struct usb_device *)NULL;
4177         switch (bInterfaceNumber) {
4178 /*---------------------------------------------------------------------------*/
4179         case 0: {
4180                 if ((struct list_head *)NULL != peasycap->purb_video_head) {
4181                         JOT(4, "killing video urbs\n");
4182                         m = 0;
4183                         list_for_each(plist_head, (peasycap->purb_video_head))
4184                                 {
4185                                 pdata_urb = list_entry(plist_head, \
4186                                                 struct data_urb, list_head);
4187                                 if ((struct data_urb *)NULL != pdata_urb) {
4188                                         if ((struct urb *)NULL != \
4189                                                         pdata_urb->purb) {
4190                                                 usb_kill_urb(pdata_urb->purb);
4191                                                 m++;
4192                                         }
4193                                 }
4194                         }
4195                         JOT(4, "%i video urbs killed\n", m);
4196                 } else
4197                         SAY("ERROR: peasycap->purb_video_head is NULL\n");
4198                 break;
4199         }
4200 /*---------------------------------------------------------------------------*/
4201         case 2: {
4202                 if ((struct list_head *)NULL != peasycap->purb_audio_head) {
4203                         JOT(4, "killing audio urbs\n");
4204                         m = 0;
4205                         list_for_each(plist_head, \
4206                                                 (peasycap->purb_audio_head)) {
4207                                 pdata_urb = list_entry(plist_head, \
4208                                                 struct data_urb, list_head);
4209                                 if ((struct data_urb *)NULL != pdata_urb) {
4210                                         if ((struct urb *)NULL != \
4211                                                         pdata_urb->purb) {
4212                                                 usb_kill_urb(pdata_urb->purb);
4213                                                 m++;
4214                                         }
4215                                 }
4216                         }
4217                         JOT(4, "%i audio urbs killed\n", m);
4218                 } else
4219                         SAY("ERROR: peasycap->purb_audio_head is NULL\n");
4220                 break;
4221         }
4222 /*---------------------------------------------------------------------------*/
4223         default:
4224                 break;
4225         }
4226 }
4227 /*--------------------------------------------------------------------------*/
4228 /*
4229  *  DEREGISTER
4230  */
4231 /*--------------------------------------------------------------------------*/
4232 switch (bInterfaceNumber) {
4233 case 0: {
4234 #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
4235         if ((struct easycap *)NULL == peasycap) {
4236                 SAY("ERROR: peasycap has become NULL\n");
4237         } else {
4238                 lock_kernel();
4239                 usb_deregister_dev(pusb_interface, &easycap_class);
4240                 (peasycap->registered_video)--;
4241
4242                 JOT(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber);
4243                 unlock_kernel();
4244                 SAY("easycap detached from minor #%d\n", minor);
4245         }
4246 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
4247 #else
4248         if ((struct easycap *)NULL == peasycap)
4249                 SAY("ERROR: peasycap has become NULL\n");
4250         else {
4251                 lock_kernel();
4252                 video_unregister_device(peasycap->pvideo_device);
4253                 (peasycap->registered_video)--;
4254                 unlock_kernel();
4255                 JOT(4, "unregistered with videodev: %i=minor\n", \
4256                                                         pvideo_device->minor);
4257         }
4258 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
4259 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
4260         break;
4261 }
4262 case 2: {
4263         lock_kernel();
4264
4265         usb_deregister_dev(pusb_interface, &easysnd_class);
4266         if ((struct easycap *)NULL != peasycap)
4267                 (peasycap->registered_audio)--;
4268
4269         JOT(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber);
4270         unlock_kernel();
4271
4272         SAY("easysnd detached from minor #%d\n", minor);
4273         break;
4274 }
4275 default:
4276         break;
4277 }
4278 /*---------------------------------------------------------------------------*/
4279 /*
4280  *  CALL easycap_delete() IF NO REMAINING REFERENCES TO peasycap
4281  */
4282 /*---------------------------------------------------------------------------*/
4283 if ((struct easycap *)NULL == peasycap) {
4284         SAY("ERROR: peasycap has become NULL\n");
4285         SAY("cannot call kref_put()\n");
4286         SAY("ending unsuccessfully: may cause memory leak\n");
4287         return;
4288 }
4289 if (!peasycap->kref.refcount.counter) {
4290         SAY("ERROR: peasycap->kref.refcount.counter is zero " \
4291                                                 "so cannot call kref_put()\n");
4292         SAY("ending unsuccessfully: may cause memory leak\n");
4293         return;
4294 }
4295 JOT(4, "intf[%i]: kref_put() with %i=peasycap->kref.refcount.counter\n", \
4296                 bInterfaceNumber, (int)peasycap->kref.refcount.counter);
4297 kref_put(&peasycap->kref, easycap_delete);
4298 JOT(4, "intf[%i]: kref_put() done.\n", bInterfaceNumber);
4299 /*---------------------------------------------------------------------------*/
4300
4301 JOT(4, "ends\n");
4302 return;
4303 }
4304 /*****************************************************************************/
4305 int __init
4306 easycap_module_init(void)
4307 {
4308 int result;
4309
4310 SAY("========easycap=======\n");
4311 JOT(4, "begins.  %i=debug\n", easycap_debug);
4312 SAY("version: " EASYCAP_DRIVER_VERSION "\n");
4313 /*---------------------------------------------------------------------------*/
4314 /*
4315  *  REGISTER THIS DRIVER WITH THE USB SUBSYTEM.
4316  */
4317 /*---------------------------------------------------------------------------*/
4318 JOT(4, "registering driver easycap\n");
4319
4320 result = usb_register(&easycap_usb_driver);
4321 if (0 != result)
4322         SAY("ERROR:  usb_register returned %i\n", result);
4323
4324 JOT(4, "ends\n");
4325 return result;
4326 }
4327 /*****************************************************************************/
4328 void __exit
4329 easycap_module_exit(void)
4330 {
4331 JOT(4, "begins\n");
4332
4333 /*---------------------------------------------------------------------------*/
4334 /*
4335  *  DEREGISTER THIS DRIVER WITH THE USB SUBSYTEM.
4336  */
4337 /*---------------------------------------------------------------------------*/
4338 usb_deregister(&easycap_usb_driver);
4339
4340 JOT(4, "ends\n");
4341 }
4342 /*****************************************************************************/
4343
4344 module_init(easycap_module_init);
4345 module_exit(easycap_module_exit);
4346
4347 MODULE_LICENSE("GPL");
4348 MODULE_AUTHOR("R.M. Thomas <rmthomas@sciolus.org>");
4349 MODULE_DESCRIPTION(EASYCAP_DRIVER_DESCRIPTION);
4350 MODULE_VERSION(EASYCAP_DRIVER_VERSION);
4351 #if defined(EASYCAP_DEBUG)
4352 MODULE_PARM_DESC(easycap_debug, "debug: 0 (default), 1, 2,...");
4353 #endif /*EASYCAP_DEBUG*/
4354 /*****************************************************************************/