V4L/DVB (4237): Move LOG_STATUS bracketing to a different part of the pvrusb2 driver
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / media / video / pvrusb2 / pvrusb2-v4l2.c
blobdda560cd1c06db756a1e14b0e4f4179cbb03be9b
1 /*
3 * $Id$
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include <linux/kernel.h>
24 #include "pvrusb2-context.h"
25 #include "pvrusb2-hdw.h"
26 #include "pvrusb2.h"
27 #include "pvrusb2-debug.h"
28 #include "pvrusb2-v4l2.h"
29 #include "pvrusb2-ioread.h"
30 #include <linux/videodev2.h>
31 #include <media/v4l2-common.h>
33 struct pvr2_v4l2_dev;
34 struct pvr2_v4l2_fh;
35 struct pvr2_v4l2;
37 /* V4L no longer provide the ability to set / get a private context pointer
38 (i.e. video_get_drvdata / video_set_drvdata), which means we have to
39 concoct our own context locating mechanism. Supposedly this is intended
40 to simplify driver implementation. It's not clear to me how that can
41 possibly be true. Our solution here is to maintain a lookup table of
42 our context instances, indexed by the minor device number of the V4L
43 device. See pvr2_v4l2_open() for some implications of this approach. */
44 static struct pvr2_v4l2_dev *devices[256];
45 static DEFINE_MUTEX(device_lock);
47 struct pvr2_v4l2_dev {
48 struct pvr2_v4l2 *v4lp;
49 struct video_device *vdev;
50 struct pvr2_context_stream *stream;
51 int ctxt_idx;
52 enum pvr2_config config;
55 struct pvr2_v4l2_fh {
56 struct pvr2_channel channel;
57 struct pvr2_v4l2_dev *dev_info;
58 enum v4l2_priority prio;
59 struct pvr2_ioread *rhp;
60 struct file *file;
61 struct pvr2_v4l2 *vhead;
62 struct pvr2_v4l2_fh *vnext;
63 struct pvr2_v4l2_fh *vprev;
64 wait_queue_head_t wait_data;
65 int fw_mode_flag;
68 struct pvr2_v4l2 {
69 struct pvr2_channel channel;
70 struct pvr2_v4l2_fh *vfirst;
71 struct pvr2_v4l2_fh *vlast;
73 struct v4l2_prio_state prio;
75 /* streams */
76 struct pvr2_v4l2_dev video_dev;
79 static int video_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
80 module_param_array(video_nr, int, NULL, 0444);
81 MODULE_PARM_DESC(video_nr, "Offset for device's minor");
83 struct v4l2_capability pvr_capability ={
84 .driver = "pvrusb2",
85 .card = "Hauppauge WinTV pvr-usb2",
86 .bus_info = "usb",
87 .version = KERNEL_VERSION(0,8,0),
88 .capabilities = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE |
89 V4L2_CAP_TUNER | V4L2_CAP_AUDIO |
90 V4L2_CAP_READWRITE),
91 .reserved = {0,0,0,0}
94 static struct v4l2_tuner pvr_v4l2_tuners[]= {
96 .index = 0,
97 .name = "TV Tuner",
98 .type = V4L2_TUNER_ANALOG_TV,
99 .capability = (V4L2_TUNER_CAP_NORM |
100 V4L2_TUNER_CAP_STEREO |
101 V4L2_TUNER_CAP_LANG1 |
102 V4L2_TUNER_CAP_LANG2),
103 .rangelow = 0,
104 .rangehigh = 0,
105 .rxsubchans = V4L2_TUNER_SUB_STEREO,
106 .audmode = V4L2_TUNER_MODE_STEREO,
107 .signal = 0,
108 .afc = 0,
109 .reserved = {0,0,0,0}
113 struct v4l2_fmtdesc pvr_fmtdesc [] = {
115 .index = 0,
116 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
117 .flags = V4L2_FMT_FLAG_COMPRESSED,
118 .description = "MPEG1/2",
119 // This should really be V4L2_PIX_FMT_MPEG, but xawtv
120 // breaks when I do that.
121 .pixelformat = 0, // V4L2_PIX_FMT_MPEG,
122 .reserved = { 0, 0, 0, 0 }
126 #define PVR_FORMAT_PIX 0
127 #define PVR_FORMAT_VBI 1
129 struct v4l2_format pvr_format [] = {
130 [PVR_FORMAT_PIX] = {
131 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
132 .fmt = {
133 .pix = {
134 .width = 720,
135 .height = 576,
136 // This should really be V4L2_PIX_FMT_MPEG,
137 // but xawtv breaks when I do that.
138 .pixelformat = 0, // V4L2_PIX_FMT_MPEG,
139 .field = V4L2_FIELD_INTERLACED,
140 .bytesperline = 0, // doesn't make sense
141 // here
142 //FIXME : Don't know what to put here...
143 .sizeimage = (32*1024),
144 .colorspace = 0, // doesn't make sense here
145 .priv = 0
149 [PVR_FORMAT_VBI] = {
150 .type = V4L2_BUF_TYPE_VBI_CAPTURE,
151 .fmt = {
152 .vbi = {
153 .sampling_rate = 27000000,
154 .offset = 248,
155 .samples_per_line = 1443,
156 .sample_format = V4L2_PIX_FMT_GREY,
157 .start = { 0, 0 },
158 .count = { 0, 0 },
159 .flags = 0,
160 .reserved = { 0, 0 }
167 * pvr_ioctl()
169 * This is part of Video 4 Linux API. The procedure handles ioctl() calls.
172 static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
173 unsigned int cmd, void *arg)
175 struct pvr2_v4l2_fh *fh = file->private_data;
176 struct pvr2_v4l2 *vp = fh->vhead;
177 struct pvr2_v4l2_dev *dev_info = fh->dev_info;
178 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
179 int ret = -EINVAL;
181 if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) {
182 v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw),cmd);
185 if (!pvr2_hdw_dev_ok(hdw)) {
186 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
187 "ioctl failed - bad or no context");
188 return -EFAULT;
191 /* check priority */
192 switch (cmd) {
193 case VIDIOC_S_CTRL:
194 case VIDIOC_S_STD:
195 case VIDIOC_S_INPUT:
196 case VIDIOC_S_TUNER:
197 case VIDIOC_S_FREQUENCY:
198 ret = v4l2_prio_check(&vp->prio, &fh->prio);
199 if (ret)
200 return ret;
203 switch (cmd) {
204 case VIDIOC_QUERYCAP:
206 struct v4l2_capability *cap = arg;
208 memcpy(cap, &pvr_capability, sizeof(struct v4l2_capability));
210 ret = 0;
211 break;
214 case VIDIOC_G_PRIORITY:
216 enum v4l2_priority *p = arg;
218 *p = v4l2_prio_max(&vp->prio);
219 ret = 0;
220 break;
223 case VIDIOC_S_PRIORITY:
225 enum v4l2_priority *prio = arg;
227 ret = v4l2_prio_change(&vp->prio, &fh->prio, *prio);
228 break;
231 case VIDIOC_ENUMSTD:
233 struct v4l2_standard *vs = (struct v4l2_standard *)arg;
234 int idx = vs->index;
235 ret = pvr2_hdw_get_stdenum_value(hdw,vs,idx+1);
236 break;
239 case VIDIOC_G_STD:
241 int val = 0;
242 ret = pvr2_ctrl_get_value(
243 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR),&val);
244 *(v4l2_std_id *)arg = val;
245 break;
248 case VIDIOC_S_STD:
250 ret = pvr2_ctrl_set_value(
251 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR),
252 *(v4l2_std_id *)arg);
253 break;
256 case VIDIOC_ENUMINPUT:
258 struct pvr2_ctrl *cptr;
259 struct v4l2_input *vi = (struct v4l2_input *)arg;
260 struct v4l2_input tmp;
261 unsigned int cnt;
263 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT);
265 memset(&tmp,0,sizeof(tmp));
266 tmp.index = vi->index;
267 ret = 0;
268 switch (vi->index) {
269 case PVR2_CVAL_INPUT_TV:
270 case PVR2_CVAL_INPUT_RADIO:
271 tmp.type = V4L2_INPUT_TYPE_TUNER;
272 break;
273 case PVR2_CVAL_INPUT_SVIDEO:
274 case PVR2_CVAL_INPUT_COMPOSITE:
275 tmp.type = V4L2_INPUT_TYPE_CAMERA;
276 break;
277 default:
278 ret = -EINVAL;
279 break;
281 if (ret < 0) break;
283 cnt = 0;
284 pvr2_ctrl_get_valname(cptr,vi->index,
285 tmp.name,sizeof(tmp.name)-1,&cnt);
286 tmp.name[cnt] = 0;
288 /* Don't bother with audioset, since this driver currently
289 always switches the audio whenever the video is
290 switched. */
292 /* Handling std is a tougher problem. It doesn't make
293 sense in cases where a device might be multi-standard.
294 We could just copy out the current value for the
295 standard, but it can change over time. For now just
296 leave it zero. */
298 memcpy(vi, &tmp, sizeof(tmp));
300 ret = 0;
301 break;
304 case VIDIOC_G_INPUT:
306 struct pvr2_ctrl *cptr;
307 struct v4l2_input *vi = (struct v4l2_input *)arg;
308 int val;
309 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT);
310 val = 0;
311 ret = pvr2_ctrl_get_value(cptr,&val);
312 vi->index = val;
313 break;
316 case VIDIOC_S_INPUT:
318 struct v4l2_input *vi = (struct v4l2_input *)arg;
319 ret = pvr2_ctrl_set_value(
320 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT),
321 vi->index);
322 break;
325 case VIDIOC_ENUMAUDIO:
327 ret = -EINVAL;
328 break;
331 case VIDIOC_G_AUDIO:
333 ret = -EINVAL;
334 break;
337 case VIDIOC_S_AUDIO:
339 ret = -EINVAL;
340 break;
342 case VIDIOC_G_TUNER:
344 struct v4l2_tuner *vt = (struct v4l2_tuner *)arg;
345 unsigned int status_mask;
346 int val;
347 if (vt->index !=0) break;
349 status_mask = pvr2_hdw_get_signal_status(hdw);
351 memcpy(vt, &pvr_v4l2_tuners[vt->index],
352 sizeof(struct v4l2_tuner));
354 vt->signal = 0;
355 if (status_mask & PVR2_SIGNAL_OK) {
356 if (status_mask & PVR2_SIGNAL_STEREO) {
357 vt->rxsubchans = V4L2_TUNER_SUB_STEREO;
358 } else {
359 vt->rxsubchans = V4L2_TUNER_SUB_MONO;
361 if (status_mask & PVR2_SIGNAL_SAP) {
362 vt->rxsubchans |= (V4L2_TUNER_SUB_LANG1 |
363 V4L2_TUNER_SUB_LANG2);
365 vt->signal = 65535;
368 val = 0;
369 ret = pvr2_ctrl_get_value(
370 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_AUDIOMODE),
371 &val);
372 vt->audmode = val;
373 break;
376 case VIDIOC_S_TUNER:
378 struct v4l2_tuner *vt=(struct v4l2_tuner *)arg;
380 if (vt->index != 0)
381 break;
383 ret = pvr2_ctrl_set_value(
384 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_AUDIOMODE),
385 vt->audmode);
388 case VIDIOC_S_FREQUENCY:
390 const struct v4l2_frequency *vf = (struct v4l2_frequency *)arg;
391 ret = pvr2_ctrl_set_value(
392 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_FREQUENCY),
393 vf->frequency * 62500);
394 break;
397 case VIDIOC_G_FREQUENCY:
399 struct v4l2_frequency *vf = (struct v4l2_frequency *)arg;
400 int val = 0;
401 ret = pvr2_ctrl_get_value(
402 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_FREQUENCY),
403 &val);
404 val /= 62500;
405 vf->frequency = val;
406 break;
409 case VIDIOC_ENUM_FMT:
411 struct v4l2_fmtdesc *fd = (struct v4l2_fmtdesc *)arg;
413 /* Only one format is supported : mpeg.*/
414 if (fd->index != 0)
415 break;
417 memcpy(fd, pvr_fmtdesc, sizeof(struct v4l2_fmtdesc));
418 ret = 0;
419 break;
422 case VIDIOC_G_FMT:
424 struct v4l2_format *vf = (struct v4l2_format *)arg;
425 int val;
426 switch(vf->type) {
427 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
428 memcpy(vf, &pvr_format[PVR_FORMAT_PIX],
429 sizeof(struct v4l2_format));
430 val = 0;
431 pvr2_ctrl_get_value(
432 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_HRES),
433 &val);
434 vf->fmt.pix.width = val;
435 val = 0;
436 pvr2_ctrl_get_value(
437 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_VRES),
438 &val);
439 vf->fmt.pix.height = val;
440 ret = 0;
441 break;
442 case V4L2_BUF_TYPE_VBI_CAPTURE:
443 // ????? Still need to figure out to do VBI correctly
444 ret = -EINVAL;
445 break;
446 default:
447 ret = -EINVAL;
448 break;
450 break;
453 case VIDIOC_TRY_FMT:
454 case VIDIOC_S_FMT:
456 struct v4l2_format *vf = (struct v4l2_format *)arg;
458 ret = 0;
459 switch(vf->type) {
460 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
461 int h = vf->fmt.pix.height;
462 int w = vf->fmt.pix.width;
464 if (h < 200) {
465 h = 200;
466 } else if (h > 625) {
467 h = 625;
469 if (w < 320) {
470 w = 320;
471 } else if (w > 720) {
472 w = 720;
475 memcpy(vf, &pvr_format[PVR_FORMAT_PIX],
476 sizeof(struct v4l2_format));
477 vf->fmt.pix.width = w;
478 vf->fmt.pix.height = h;
480 if (cmd == VIDIOC_S_FMT) {
481 pvr2_ctrl_set_value(
482 pvr2_hdw_get_ctrl_by_id(hdw,
483 PVR2_CID_HRES),
484 vf->fmt.pix.width);
485 pvr2_ctrl_set_value(
486 pvr2_hdw_get_ctrl_by_id(hdw,
487 PVR2_CID_VRES),
488 vf->fmt.pix.height);
490 } break;
491 case V4L2_BUF_TYPE_VBI_CAPTURE:
492 // ????? Still need to figure out to do VBI correctly
493 ret = -EINVAL;
494 break;
495 default:
496 ret = -EINVAL;
497 break;
499 break;
502 case VIDIOC_STREAMON:
504 ret = pvr2_hdw_set_stream_type(hdw,dev_info->config);
505 if (ret < 0) return ret;
506 ret = pvr2_hdw_set_streaming(hdw,!0);
507 break;
510 case VIDIOC_STREAMOFF:
512 ret = pvr2_hdw_set_streaming(hdw,0);
513 break;
516 case VIDIOC_QUERYCTRL:
518 struct pvr2_ctrl *cptr;
519 struct v4l2_queryctrl *vc = (struct v4l2_queryctrl *)arg;
520 ret = 0;
521 cptr = pvr2_hdw_get_ctrl_v4l(hdw,vc->id);
522 if (!cptr) {
523 ret = -EINVAL;
524 break;
527 strlcpy(vc->name,pvr2_ctrl_get_name(cptr),sizeof(vc->name));
528 vc->default_value = pvr2_ctrl_get_def(cptr);
529 switch (pvr2_ctrl_get_type(cptr)) {
530 case pvr2_ctl_enum:
531 vc->type = V4L2_CTRL_TYPE_MENU;
532 vc->minimum = 0;
533 vc->maximum = pvr2_ctrl_get_cnt(cptr) - 1;
534 vc->step = 1;
535 break;
536 case pvr2_ctl_int:
537 vc->type = V4L2_CTRL_TYPE_INTEGER;
538 vc->minimum = pvr2_ctrl_get_min(cptr);
539 vc->maximum = pvr2_ctrl_get_max(cptr);
540 vc->step = 1;
541 break;
542 default:
543 ret = -EINVAL;
544 break;
546 break;
549 case VIDIOC_QUERYMENU:
551 struct v4l2_querymenu *vm = (struct v4l2_querymenu *)arg;
552 unsigned int cnt = 0;
553 ret = pvr2_ctrl_get_valname(pvr2_hdw_get_ctrl_v4l(hdw,vm->id),
554 vm->index,
555 vm->name,sizeof(vm->name)-1,
556 &cnt);
557 vm->name[cnt] = 0;
558 break;
561 case VIDIOC_G_CTRL:
563 struct v4l2_control *vc = (struct v4l2_control *)arg;
564 int val = 0;
565 ret = pvr2_ctrl_get_value(pvr2_hdw_get_ctrl_v4l(hdw,vc->id),
566 &val);
567 vc->value = val;
568 break;
571 case VIDIOC_S_CTRL:
573 struct v4l2_control *vc = (struct v4l2_control *)arg;
574 ret = pvr2_ctrl_set_value(pvr2_hdw_get_ctrl_v4l(hdw,vc->id),
575 vc->value);
576 break;
579 case VIDIOC_LOG_STATUS:
581 pvr2_hdw_trigger_module_log(hdw);
582 ret = 0;
583 break;
586 default :
587 ret = v4l_compat_translate_ioctl(inode,file,cmd,
588 arg,pvr2_v4l2_do_ioctl);
591 pvr2_hdw_commit_ctl(hdw);
593 if (ret < 0) {
594 if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) {
595 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
596 "pvr2_v4l2_do_ioctl failure, ret=%d",ret);
597 } else {
598 if (pvrusb2_debug & PVR2_TRACE_ERROR_LEGS) {
599 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
600 "pvr2_v4l2_do_ioctl failure, ret=%d"
601 " command was:",ret);
602 v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw),
603 cmd);
606 } else {
607 pvr2_trace(PVR2_TRACE_V4LIOCTL,
608 "pvr2_v4l2_do_ioctl complete, ret=%d (0x%x)",
609 ret,ret);
611 return ret;
615 static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip)
617 pvr2_trace(PVR2_TRACE_INIT,
618 "unregistering device video%d [%s]",
619 dip->vdev->minor,pvr2_config_get_name(dip->config));
620 if (dip->ctxt_idx >= 0) {
621 mutex_lock(&device_lock);
622 devices[dip->ctxt_idx] = NULL;
623 dip->ctxt_idx = -1;
624 mutex_unlock(&device_lock);
626 video_unregister_device(dip->vdev);
630 static void pvr2_v4l2_destroy_no_lock(struct pvr2_v4l2 *vp)
632 pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw,-1);
633 pvr2_v4l2_dev_destroy(&vp->video_dev);
635 pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_v4l2 id=%p",vp);
636 pvr2_channel_done(&vp->channel);
637 kfree(vp);
641 void pvr2_v4l2_internal_check(struct pvr2_channel *chp)
643 struct pvr2_v4l2 *vp;
644 vp = container_of(chp,struct pvr2_v4l2,channel);
645 if (!vp->channel.mc_head->disconnect_flag) return;
646 if (vp->vfirst) return;
647 pvr2_v4l2_destroy_no_lock(vp);
651 int pvr2_v4l2_ioctl(struct inode *inode, struct file *file,
652 unsigned int cmd, unsigned long arg)
655 /* Temporary hack : use ivtv api until a v4l2 one is available. */
656 #define IVTV_IOC_G_CODEC 0xFFEE7703
657 #define IVTV_IOC_S_CODEC 0xFFEE7704
658 if (cmd == IVTV_IOC_G_CODEC || cmd == IVTV_IOC_S_CODEC) return 0;
659 return video_usercopy(inode, file, cmd, arg, pvr2_v4l2_do_ioctl);
663 int pvr2_v4l2_release(struct inode *inode, struct file *file)
665 struct pvr2_v4l2_fh *fhp = file->private_data;
666 struct pvr2_v4l2 *vp = fhp->vhead;
667 struct pvr2_context *mp = fhp->vhead->channel.mc_head;
669 pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_release");
671 if (fhp->rhp) {
672 struct pvr2_stream *sp;
673 struct pvr2_hdw *hdw;
674 hdw = fhp->channel.mc_head->hdw;
675 pvr2_hdw_set_streaming(hdw,0);
676 sp = pvr2_ioread_get_stream(fhp->rhp);
677 if (sp) pvr2_stream_set_callback(sp,0,0);
678 pvr2_ioread_destroy(fhp->rhp);
679 fhp->rhp = 0;
681 v4l2_prio_close(&vp->prio, &fhp->prio);
682 file->private_data = NULL;
684 pvr2_context_enter(mp); do {
685 if (fhp->vnext) {
686 fhp->vnext->vprev = fhp->vprev;
687 } else {
688 vp->vlast = fhp->vprev;
690 if (fhp->vprev) {
691 fhp->vprev->vnext = fhp->vnext;
692 } else {
693 vp->vfirst = fhp->vnext;
695 fhp->vnext = 0;
696 fhp->vprev = 0;
697 fhp->vhead = 0;
698 pvr2_channel_done(&fhp->channel);
699 pvr2_trace(PVR2_TRACE_STRUCT,
700 "Destroying pvr_v4l2_fh id=%p",fhp);
701 kfree(fhp);
702 if (vp->channel.mc_head->disconnect_flag && !vp->vfirst) {
703 pvr2_v4l2_destroy_no_lock(vp);
705 } while (0); pvr2_context_exit(mp);
706 return 0;
710 int pvr2_v4l2_open(struct inode *inode, struct file *file)
712 struct pvr2_v4l2_dev *dip = 0; /* Our own context pointer */
713 struct pvr2_v4l2_fh *fhp;
714 struct pvr2_v4l2 *vp;
715 struct pvr2_hdw *hdw;
717 mutex_lock(&device_lock);
718 /* MCI 7-Jun-2006 Even though we're just doing what amounts to an
719 atomic read of the device mapping array here, we still need the
720 mutex. The problem is that there is a tiny race possible when
721 we register the device. We can't update the device mapping
722 array until after the device has been registered, owing to the
723 fact that we can't know the minor device number until after the
724 registration succeeds. And if another thread tries to open the
725 device in the window of time after registration but before the
726 map is updated, then it will get back an erroneous null pointer
727 and the open will result in a spurious failure. The only way to
728 prevent that is to (a) be inside the mutex here before we access
729 the array, and (b) cover the entire registration process later
730 on with this same mutex. Thus if we get inside the mutex here,
731 then we can be assured that the registration process actually
732 completed correctly. This is an unhappy complication from the
733 use of global data in a driver that lives in a preemptible
734 environment. It sure would be nice if the video device itself
735 had a means for storing and retrieving a local context pointer.
736 Oh wait. It did. But now it's gone. Silly me. */
738 unsigned int midx = iminor(file->f_dentry->d_inode);
739 if (midx < sizeof(devices)/sizeof(devices[0])) {
740 dip = devices[midx];
743 mutex_unlock(&device_lock);
745 if (!dip) return -ENODEV; /* Should be impossible but I'm paranoid */
747 vp = dip->v4lp;
748 hdw = vp->channel.hdw;
750 pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_open");
752 if (!pvr2_hdw_dev_ok(hdw)) {
753 pvr2_trace(PVR2_TRACE_OPEN_CLOSE,
754 "pvr2_v4l2_open: hardware not ready");
755 return -EIO;
758 fhp = kmalloc(sizeof(*fhp),GFP_KERNEL);
759 if (!fhp) {
760 return -ENOMEM;
762 memset(fhp,0,sizeof(*fhp));
764 init_waitqueue_head(&fhp->wait_data);
765 fhp->dev_info = dip;
767 pvr2_context_enter(vp->channel.mc_head); do {
768 pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr_v4l2_fh id=%p",fhp);
769 pvr2_channel_init(&fhp->channel,vp->channel.mc_head);
770 fhp->vnext = 0;
771 fhp->vprev = vp->vlast;
772 if (vp->vlast) {
773 vp->vlast->vnext = fhp;
774 } else {
775 vp->vfirst = fhp;
777 vp->vlast = fhp;
778 fhp->vhead = vp;
779 } while (0); pvr2_context_exit(vp->channel.mc_head);
781 fhp->file = file;
782 file->private_data = fhp;
783 v4l2_prio_open(&vp->prio,&fhp->prio);
785 fhp->fw_mode_flag = pvr2_hdw_cpufw_get_enabled(hdw);
787 return 0;
791 static void pvr2_v4l2_notify(struct pvr2_v4l2_fh *fhp)
793 wake_up(&fhp->wait_data);
796 static int pvr2_v4l2_iosetup(struct pvr2_v4l2_fh *fh)
798 int ret;
799 struct pvr2_stream *sp;
800 struct pvr2_hdw *hdw;
801 if (fh->rhp) return 0;
803 /* First read() attempt. Try to claim the stream and start
804 it... */
805 if ((ret = pvr2_channel_claim_stream(&fh->channel,
806 fh->dev_info->stream)) != 0) {
807 /* Someone else must already have it */
808 return ret;
811 fh->rhp = pvr2_channel_create_mpeg_stream(fh->dev_info->stream);
812 if (!fh->rhp) {
813 pvr2_channel_claim_stream(&fh->channel,0);
814 return -ENOMEM;
817 hdw = fh->channel.mc_head->hdw;
818 sp = fh->dev_info->stream->stream;
819 pvr2_stream_set_callback(sp,(pvr2_stream_callback)pvr2_v4l2_notify,fh);
820 pvr2_hdw_set_stream_type(hdw,fh->dev_info->config);
821 pvr2_hdw_set_streaming(hdw,!0);
822 ret = pvr2_ioread_set_enabled(fh->rhp,!0);
824 return ret;
828 static ssize_t pvr2_v4l2_read(struct file *file,
829 char __user *buff, size_t count, loff_t *ppos)
831 struct pvr2_v4l2_fh *fh = file->private_data;
832 int ret;
834 if (fh->fw_mode_flag) {
835 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
836 char *tbuf;
837 int c1,c2;
838 int tcnt = 0;
839 unsigned int offs = *ppos;
841 tbuf = kmalloc(PAGE_SIZE,GFP_KERNEL);
842 if (!tbuf) return -ENOMEM;
844 while (count) {
845 c1 = count;
846 if (c1 > PAGE_SIZE) c1 = PAGE_SIZE;
847 c2 = pvr2_hdw_cpufw_get(hdw,offs,tbuf,c1);
848 if (c2 < 0) {
849 tcnt = c2;
850 break;
852 if (!c2) break;
853 if (copy_to_user(buff,tbuf,c2)) {
854 tcnt = -EFAULT;
855 break;
857 offs += c2;
858 tcnt += c2;
859 buff += c2;
860 count -= c2;
861 *ppos += c2;
863 kfree(tbuf);
864 return tcnt;
867 if (!fh->rhp) {
868 ret = pvr2_v4l2_iosetup(fh);
869 if (ret) {
870 return ret;
874 for (;;) {
875 ret = pvr2_ioread_read(fh->rhp,buff,count);
876 if (ret >= 0) break;
877 if (ret != -EAGAIN) break;
878 if (file->f_flags & O_NONBLOCK) break;
879 /* Doing blocking I/O. Wait here. */
880 ret = wait_event_interruptible(
881 fh->wait_data,
882 pvr2_ioread_avail(fh->rhp) >= 0);
883 if (ret < 0) break;
886 return ret;
890 static unsigned int pvr2_v4l2_poll(struct file *file, poll_table *wait)
892 unsigned int mask = 0;
893 struct pvr2_v4l2_fh *fh = file->private_data;
894 int ret;
896 if (fh->fw_mode_flag) {
897 mask |= POLLIN | POLLRDNORM;
898 return mask;
901 if (!fh->rhp) {
902 ret = pvr2_v4l2_iosetup(fh);
903 if (ret) return POLLERR;
906 poll_wait(file,&fh->wait_data,wait);
908 if (pvr2_ioread_avail(fh->rhp) >= 0) {
909 mask |= POLLIN | POLLRDNORM;
912 return mask;
916 static struct file_operations vdev_fops = {
917 .owner = THIS_MODULE,
918 .open = pvr2_v4l2_open,
919 .release = pvr2_v4l2_release,
920 .read = pvr2_v4l2_read,
921 .ioctl = pvr2_v4l2_ioctl,
922 .llseek = no_llseek,
923 .poll = pvr2_v4l2_poll,
927 #define VID_HARDWARE_PVRUSB2 38 /* FIXME : need a good value */
929 static struct video_device vdev_template = {
930 .owner = THIS_MODULE,
931 .type = VID_TYPE_CAPTURE | VID_TYPE_TUNER,
932 .type2 = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE
933 | V4L2_CAP_TUNER | V4L2_CAP_AUDIO
934 | V4L2_CAP_READWRITE),
935 .hardware = VID_HARDWARE_PVRUSB2,
936 .fops = &vdev_fops,
940 static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
941 struct pvr2_v4l2 *vp,
942 enum pvr2_config cfg)
944 int mindevnum;
945 int unit_number;
946 int v4l_type;
947 dip->v4lp = vp;
948 dip->config = cfg;
951 switch (cfg) {
952 case pvr2_config_mpeg:
953 v4l_type = VFL_TYPE_GRABBER;
954 dip->stream = &vp->channel.mc_head->video_stream;
955 break;
956 case pvr2_config_vbi:
957 v4l_type = VFL_TYPE_VBI;
958 break;
959 case pvr2_config_radio:
960 v4l_type = VFL_TYPE_RADIO;
961 break;
962 default:
963 /* Bail out (this should be impossible) */
964 err("Failed to set up pvrusb2 v4l dev"
965 " due to unrecognized config");
966 return;
969 if (!dip->stream) {
970 err("Failed to set up pvrusb2 v4l dev"
971 " due to missing stream instance");
972 return;
975 dip->vdev = video_device_alloc();
976 if (!dip->vdev) {
977 err("Alloc of pvrusb2 v4l video device failed");
978 return;
981 memcpy(dip->vdev,&vdev_template,sizeof(vdev_template));
982 dip->vdev->release = video_device_release;
983 mutex_lock(&device_lock);
985 mindevnum = -1;
986 unit_number = pvr2_hdw_get_unit_number(vp->channel.mc_head->hdw);
987 if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
988 mindevnum = video_nr[unit_number];
990 if ((video_register_device(dip->vdev, v4l_type, mindevnum) < 0) &&
991 (video_register_device(dip->vdev, v4l_type, -1) < 0)) {
992 err("Failed to register pvrusb2 v4l video device");
993 } else {
994 pvr2_trace(PVR2_TRACE_INIT,
995 "registered device video%d [%s]",
996 dip->vdev->minor,pvr2_config_get_name(dip->config));
999 if ((dip->vdev->minor < sizeof(devices)/sizeof(devices[0])) &&
1000 (devices[dip->vdev->minor] == NULL)) {
1001 dip->ctxt_idx = dip->vdev->minor;
1002 devices[dip->ctxt_idx] = dip;
1004 mutex_unlock(&device_lock);
1006 pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw,
1007 dip->vdev->minor);
1011 struct pvr2_v4l2 *pvr2_v4l2_create(struct pvr2_context *mnp)
1013 struct pvr2_v4l2 *vp;
1015 vp = kmalloc(sizeof(*vp),GFP_KERNEL);
1016 if (!vp) return vp;
1017 memset(vp,0,sizeof(*vp));
1018 vp->video_dev.ctxt_idx = -1;
1019 pvr2_channel_init(&vp->channel,mnp);
1020 pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_v4l2 id=%p",vp);
1022 vp->channel.check_func = pvr2_v4l2_internal_check;
1024 /* register streams */
1025 pvr2_v4l2_dev_init(&vp->video_dev,vp,pvr2_config_mpeg);
1028 return vp;
1032 Stuff for Emacs to see, in order to encourage consistent editing style:
1033 *** Local Variables: ***
1034 *** mode: c ***
1035 *** fill-column: 75 ***
1036 *** tab-width: 8 ***
1037 *** c-basic-offset: 8 ***
1038 *** End: ***