Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6
[GitHub/mt8127/android_kernel_alcatel_ttab.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 /*****************************************************************************/