--- zzzz-none-000/linux-3.10.107/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c 2021-02-04 17:41:59.000000000 +0000 @@ -21,7 +21,6 @@ #include #include -#include #include "pvrusb2-context.h" #include "pvrusb2-hdw.h" #include "pvrusb2.h" @@ -31,6 +30,8 @@ #include #include #include +#include +#include #include #include @@ -49,14 +50,11 @@ }; struct pvr2_v4l2_fh { + struct v4l2_fh fh; struct pvr2_channel channel; struct pvr2_v4l2_dev *pdi; - enum v4l2_priority prio; struct pvr2_ioread *rhp; struct file *file; - struct pvr2_v4l2 *vhead; - struct pvr2_v4l2_fh *vnext; - struct pvr2_v4l2_fh *vprev; wait_queue_head_t wait_data; int fw_mode_flag; /* Map contiguous ordinal value to input id */ @@ -66,10 +64,6 @@ struct pvr2_v4l2 { struct pvr2_channel channel; - struct pvr2_v4l2_fh *vfirst; - struct pvr2_v4l2_fh *vlast; - - struct v4l2_prio_state prio; /* streams - Note that these must be separately, individually, * allocated pointers. This is because the v4l core is going to @@ -88,16 +82,6 @@ module_param_array(vbi_nr, int, NULL, 0444); MODULE_PARM_DESC(vbi_nr, "Offset for device's vbi dev minor"); -static struct v4l2_capability pvr_capability ={ - .driver = "pvrusb2", - .card = "Hauppauge WinTV pvr-usb2", - .bus_info = "usb", - .version = LINUX_VERSION_CODE, - .capabilities = (V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO | - V4L2_CAP_READWRITE), -}; - static struct v4l2_fmtdesc pvr_fmtdesc [] = { { .index = 0, @@ -159,30 +143,25 @@ struct pvr2_v4l2_fh *fh = file->private_data; struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - memcpy(cap, &pvr_capability, sizeof(struct v4l2_capability)); + strlcpy(cap->driver, "pvrusb2", sizeof(cap->driver)); strlcpy(cap->bus_info, pvr2_hdw_get_bus_info(hdw), sizeof(cap->bus_info)); strlcpy(cap->card, pvr2_hdw_get_desc(hdw), sizeof(cap->card)); + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | + V4L2_CAP_AUDIO | V4L2_CAP_RADIO | + V4L2_CAP_READWRITE | V4L2_CAP_DEVICE_CAPS; + switch (fh->pdi->devbase.vfl_type) { + case VFL_TYPE_GRABBER: + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_AUDIO; + break; + case VFL_TYPE_RADIO: + cap->device_caps = V4L2_CAP_RADIO; + break; + } + cap->device_caps |= V4L2_CAP_TUNER | V4L2_CAP_READWRITE; return 0; } -static int pvr2_g_priority(struct file *file, void *priv, enum v4l2_priority *p) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_v4l2 *vp = fh->vhead; - - *p = v4l2_prio_max(&vp->prio); - return 0; -} - -static int pvr2_s_priority(struct file *file, void *priv, enum v4l2_priority prio) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_v4l2 *vp = fh->vhead; - - return v4l2_prio_change(&vp->prio, &fh->prio, prio); -} - static int pvr2_g_std(struct file *file, void *priv, v4l2_std_id *std) { struct pvr2_v4l2_fh *fh = file->private_data; @@ -800,40 +779,8 @@ return 0; } -#ifdef CONFIG_VIDEO_ADV_DEBUG -static int pvr2_g_register(struct file *file, void *priv, struct v4l2_dbg_register *req) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - u64 val; - int ret; - - ret = pvr2_hdw_register_access( - hdw, &req->match, req->reg, - 0, &val); - req->val = val; - return ret; -} - -static int pvr2_s_register(struct file *file, void *priv, const struct v4l2_dbg_register *req) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - u64 val; - int ret; - - val = req->val; - ret = pvr2_hdw_register_access( - hdw, &req->match, req->reg, - 1, &val); - return ret; -} -#endif - static const struct v4l2_ioctl_ops pvr2_ioctl_ops = { .vidioc_querycap = pvr2_querycap, - .vidioc_g_priority = pvr2_g_priority, - .vidioc_s_priority = pvr2_s_priority, .vidioc_s_audio = pvr2_s_audio, .vidioc_g_audio = pvr2_g_audio, .vidioc_enumaudio = pvr2_enumaudio, @@ -864,10 +811,6 @@ .vidioc_g_ext_ctrls = pvr2_g_ext_ctrls, .vidioc_s_ext_ctrls = pvr2_s_ext_ctrls, .vidioc_try_ext_ctrls = pvr2_try_ext_ctrls, -#ifdef CONFIG_VIDEO_ADV_DEBUG - .vidioc_g_register = pvr2_g_register, - .vidioc_s_register = pvr2_s_register, -#endif }; static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip) @@ -904,8 +847,8 @@ static void pvr2_v4l2_dev_disassociate_parent(struct pvr2_v4l2_dev *dip) { if (!dip) return; - if (!dip->devbase.parent) return; - dip->devbase.parent = NULL; + if (!dip->devbase.v4l2_dev->dev) return; + dip->devbase.v4l2_dev->dev = NULL; device_move(&dip->devbase.dev, NULL, DPM_ORDER_NONE); } @@ -942,7 +885,9 @@ if (!vp->channel.mc_head->disconnect_flag) return; pvr2_v4l2_dev_disassociate_parent(vp->dev_video); pvr2_v4l2_dev_disassociate_parent(vp->dev_radio); - if (vp->vfirst) return; + if (!list_empty(&vp->dev_video->devbase.fh_list) || + !list_empty(&vp->dev_radio->devbase.fh_list)) + return; pvr2_v4l2_destroy_no_lock(vp); } @@ -952,7 +897,6 @@ { struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_v4l2 *vp = fh->vhead; struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; long ret = -EINVAL; @@ -965,18 +909,6 @@ return -EFAULT; } - /* check priority */ - switch (cmd) { - case VIDIOC_S_CTRL: - case VIDIOC_S_STD: - case VIDIOC_S_INPUT: - case VIDIOC_S_TUNER: - case VIDIOC_S_FREQUENCY: - ret = v4l2_prio_check(&vp->prio, fh->prio); - if (ret) - return ret; - } - ret = video_ioctl2(file, cmd, arg); pvr2_hdw_commit_ctl(hdw); @@ -984,15 +916,9 @@ if (ret < 0) { if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) { pvr2_trace(PVR2_TRACE_V4LIOCTL, - "pvr2_v4l2_do_ioctl failure, ret=%ld", ret); - } else { - if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) { - pvr2_trace(PVR2_TRACE_V4LIOCTL, - "pvr2_v4l2_do_ioctl failure, ret=%ld" - " command was:", ret); - v4l_printk_ioctl(pvr2_hdw_get_driver_name(hdw), - cmd); - } + "pvr2_v4l2_do_ioctl failure, ret=%ld" + " command was:", ret); + v4l_printk_ioctl(pvr2_hdw_get_driver_name(hdw), cmd); } } else { pvr2_trace(PVR2_TRACE_V4LIOCTL, @@ -1007,7 +933,7 @@ static int pvr2_v4l2_release(struct file *file) { struct pvr2_v4l2_fh *fhp = file->private_data; - struct pvr2_v4l2 *vp = fhp->vhead; + struct pvr2_v4l2 *vp = fhp->pdi->v4lp; struct pvr2_hdw *hdw = fhp->channel.mc_head->hdw; pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_release"); @@ -1021,22 +947,10 @@ fhp->rhp = NULL; } - v4l2_prio_close(&vp->prio, fhp->prio); + v4l2_fh_del(&fhp->fh); + v4l2_fh_exit(&fhp->fh); file->private_data = NULL; - if (fhp->vnext) { - fhp->vnext->vprev = fhp->vprev; - } else { - vp->vlast = fhp->vprev; - } - if (fhp->vprev) { - fhp->vprev->vnext = fhp->vnext; - } else { - vp->vfirst = fhp->vnext; - } - fhp->vnext = NULL; - fhp->vprev = NULL; - fhp->vhead = NULL; pvr2_channel_done(&fhp->channel); pvr2_trace(PVR2_TRACE_STRUCT, "Destroying pvr_v4l2_fh id=%p",fhp); @@ -1045,7 +959,9 @@ fhp->input_map = NULL; } kfree(fhp); - if (vp->channel.mc_head->disconnect_flag && !vp->vfirst) { + if (vp->channel.mc_head->disconnect_flag && + list_empty(&vp->dev_video->devbase.fh_list) && + list_empty(&vp->dev_radio->devbase.fh_list)) { pvr2_v4l2_destroy_no_lock(vp); } return 0; @@ -1080,6 +996,7 @@ return -ENOMEM; } + v4l2_fh_init(&fhp->fh, &dip->devbase); init_waitqueue_head(&fhp->wait_data); fhp->pdi = dip; @@ -1130,21 +1047,11 @@ fhp->input_map[input_cnt++] = idx; } - fhp->vnext = NULL; - fhp->vprev = vp->vlast; - if (vp->vlast) { - vp->vlast->vnext = fhp; - } else { - vp->vfirst = fhp; - } - vp->vlast = fhp; - fhp->vhead = vp; - fhp->file = file; file->private_data = fhp; - v4l2_prio_open(&vp->prio, &fhp->prio); fhp->fw_mode_flag = pvr2_hdw_cpufw_get_enabled(hdw); + v4l2_fh_add(&fhp->fh); return 0; } @@ -1284,7 +1191,7 @@ .open = pvr2_v4l2_open, .release = pvr2_v4l2_release, .read = pvr2_v4l2_read, - .ioctl = pvr2_v4l2_ioctl, + .unlocked_ioctl = pvr2_v4l2_ioctl, .poll = pvr2_v4l2_poll, }; @@ -1298,7 +1205,6 @@ struct pvr2_v4l2 *vp, int v4l_type) { - struct usb_device *usbdev; int mindevnum; int unit_number; struct pvr2_hdw *hdw; @@ -1306,7 +1212,6 @@ dip->v4lp = vp; hdw = vp->channel.mc_head->hdw; - usbdev = pvr2_hdw_get_dev(hdw); dip->v4l_type = v4l_type; switch (v4l_type) { case VFL_TYPE_GRABBER: @@ -1355,7 +1260,7 @@ if (nr_ptr && (unit_number >= 0) && (unit_number < PVR_NUM)) { mindevnum = nr_ptr[unit_number]; } - dip->devbase.parent = &usbdev->dev; + pvr2_hdw_set_v4l2_dev(hdw, &dip->devbase); if ((video_register_device(&dip->devbase, dip->v4l_type, mindevnum) < 0) && (video_register_device(&dip->devbase, @@ -1401,13 +1306,3 @@ pvr2_v4l2_destroy_no_lock(vp); return NULL; } - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */