diff options
Diffstat (limited to 'drivers/media/video/gspca/gspca.c')
| -rw-r--r-- | drivers/media/video/gspca/gspca.c | 67 |
1 files changed, 54 insertions, 13 deletions
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 4076f8e5a6fc..e930a67d526b 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c | |||
| @@ -304,7 +304,6 @@ void gspca_frame_add(struct gspca_dev *gspca_dev, | |||
| 304 | j = gspca_dev->fr_queue[i]; | 304 | j = gspca_dev->fr_queue[i]; |
| 305 | gspca_dev->cur_frame = &gspca_dev->frame[j]; | 305 | gspca_dev->cur_frame = &gspca_dev->frame[j]; |
| 306 | } | 306 | } |
| 307 | return; | ||
| 308 | } | 307 | } |
| 309 | EXPORT_SYMBOL(gspca_frame_add); | 308 | EXPORT_SYMBOL(gspca_frame_add); |
| 310 | 309 | ||
| @@ -321,7 +320,7 @@ static int gspca_is_compressed(__u32 format) | |||
| 321 | return 0; | 320 | return 0; |
| 322 | } | 321 | } |
| 323 | 322 | ||
| 324 | static void *rvmalloc(unsigned long size) | 323 | static void *rvmalloc(long size) |
| 325 | { | 324 | { |
| 326 | void *mem; | 325 | void *mem; |
| 327 | unsigned long adr; | 326 | unsigned long adr; |
| @@ -329,7 +328,7 @@ static void *rvmalloc(unsigned long size) | |||
| 329 | mem = vmalloc_32(size); | 328 | mem = vmalloc_32(size); |
| 330 | if (mem != NULL) { | 329 | if (mem != NULL) { |
| 331 | adr = (unsigned long) mem; | 330 | adr = (unsigned long) mem; |
| 332 | while ((long) size > 0) { | 331 | while (size > 0) { |
| 333 | SetPageReserved(vmalloc_to_page((void *) adr)); | 332 | SetPageReserved(vmalloc_to_page((void *) adr)); |
| 334 | adr += PAGE_SIZE; | 333 | adr += PAGE_SIZE; |
| 335 | size -= PAGE_SIZE; | 334 | size -= PAGE_SIZE; |
| @@ -768,6 +767,7 @@ static int vidioc_g_register(struct file *file, void *priv, | |||
| 768 | 767 | ||
| 769 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | 768 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) |
| 770 | return -ERESTARTSYS; | 769 | return -ERESTARTSYS; |
| 770 | gspca_dev->usb_err = 0; | ||
| 771 | if (gspca_dev->present) | 771 | if (gspca_dev->present) |
| 772 | ret = gspca_dev->sd_desc->get_register(gspca_dev, reg); | 772 | ret = gspca_dev->sd_desc->get_register(gspca_dev, reg); |
| 773 | else | 773 | else |
| @@ -791,6 +791,7 @@ static int vidioc_s_register(struct file *file, void *priv, | |||
| 791 | 791 | ||
| 792 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | 792 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) |
| 793 | return -ERESTARTSYS; | 793 | return -ERESTARTSYS; |
| 794 | gspca_dev->usb_err = 0; | ||
| 794 | if (gspca_dev->present) | 795 | if (gspca_dev->present) |
| 795 | ret = gspca_dev->sd_desc->set_register(gspca_dev, reg); | 796 | ret = gspca_dev->sd_desc->set_register(gspca_dev, reg); |
| 796 | else | 797 | else |
| @@ -812,6 +813,7 @@ static int vidioc_g_chip_ident(struct file *file, void *priv, | |||
| 812 | 813 | ||
| 813 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | 814 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) |
| 814 | return -ERESTARTSYS; | 815 | return -ERESTARTSYS; |
| 816 | gspca_dev->usb_err = 0; | ||
| 815 | if (gspca_dev->present) | 817 | if (gspca_dev->present) |
| 816 | ret = gspca_dev->sd_desc->get_chip_ident(gspca_dev, chip); | 818 | ret = gspca_dev->sd_desc->get_chip_ident(gspca_dev, chip); |
| 817 | else | 819 | else |
| @@ -983,11 +985,40 @@ static int vidioc_enum_framesizes(struct file *file, void *priv, | |||
| 983 | return -EINVAL; | 985 | return -EINVAL; |
| 984 | } | 986 | } |
| 985 | 987 | ||
| 988 | static int vidioc_enum_frameintervals(struct file *filp, void *priv, | ||
| 989 | struct v4l2_frmivalenum *fival) | ||
| 990 | { | ||
| 991 | struct gspca_dev *gspca_dev = priv; | ||
| 992 | int mode = wxh_to_mode(gspca_dev, fival->width, fival->height); | ||
| 993 | __u32 i; | ||
| 994 | |||
| 995 | if (gspca_dev->cam.mode_framerates == NULL || | ||
| 996 | gspca_dev->cam.mode_framerates[mode].nrates == 0) | ||
| 997 | return -EINVAL; | ||
| 998 | |||
| 999 | if (fival->pixel_format != | ||
| 1000 | gspca_dev->cam.cam_mode[mode].pixelformat) | ||
| 1001 | return -EINVAL; | ||
| 1002 | |||
| 1003 | for (i = 0; i < gspca_dev->cam.mode_framerates[mode].nrates; i++) { | ||
| 1004 | if (fival->index == i) { | ||
| 1005 | fival->type = V4L2_FRMSIZE_TYPE_DISCRETE; | ||
| 1006 | fival->discrete.numerator = 1; | ||
| 1007 | fival->discrete.denominator = | ||
| 1008 | gspca_dev->cam.mode_framerates[mode].rates[i]; | ||
| 1009 | return 0; | ||
| 1010 | } | ||
| 1011 | } | ||
| 1012 | |||
| 1013 | return -EINVAL; | ||
| 1014 | } | ||
| 1015 | |||
| 986 | static void gspca_release(struct video_device *vfd) | 1016 | static void gspca_release(struct video_device *vfd) |
| 987 | { | 1017 | { |
| 988 | struct gspca_dev *gspca_dev = container_of(vfd, struct gspca_dev, vdev); | 1018 | struct gspca_dev *gspca_dev = container_of(vfd, struct gspca_dev, vdev); |
| 989 | 1019 | ||
| 990 | PDEBUG(D_PROBE, "/dev/video%d released", gspca_dev->vdev.num); | 1020 | PDEBUG(D_PROBE, "%s released", |
| 1021 | video_device_node_name(&gspca_dev->vdev)); | ||
| 991 | 1022 | ||
| 992 | kfree(gspca_dev->usb_buf); | 1023 | kfree(gspca_dev->usb_buf); |
| 993 | kfree(gspca_dev); | 1024 | kfree(gspca_dev); |
| @@ -1053,6 +1084,7 @@ static int dev_close(struct file *file) | |||
| 1053 | if (gspca_dev->capt_file == file) { | 1084 | if (gspca_dev->capt_file == file) { |
| 1054 | if (gspca_dev->streaming) { | 1085 | if (gspca_dev->streaming) { |
| 1055 | mutex_lock(&gspca_dev->usb_lock); | 1086 | mutex_lock(&gspca_dev->usb_lock); |
| 1087 | gspca_dev->usb_err = 0; | ||
| 1056 | gspca_stream_off(gspca_dev); | 1088 | gspca_stream_off(gspca_dev); |
| 1057 | mutex_unlock(&gspca_dev->usb_lock); | 1089 | mutex_unlock(&gspca_dev->usb_lock); |
| 1058 | } | 1090 | } |
| @@ -1143,12 +1175,14 @@ static int vidioc_queryctrl(struct file *file, void *priv, | |||
| 1143 | continue; | 1175 | continue; |
| 1144 | ctrls = &gspca_dev->sd_desc->ctrls[i]; | 1176 | ctrls = &gspca_dev->sd_desc->ctrls[i]; |
| 1145 | } | 1177 | } |
| 1178 | if (ctrls == NULL) | ||
| 1179 | return -EINVAL; | ||
| 1146 | } else { | 1180 | } else { |
| 1147 | ctrls = get_ctrl(gspca_dev, id); | 1181 | ctrls = get_ctrl(gspca_dev, id); |
| 1182 | if (ctrls == NULL) | ||
| 1183 | return -EINVAL; | ||
| 1148 | i = ctrls - gspca_dev->sd_desc->ctrls; | 1184 | i = ctrls - gspca_dev->sd_desc->ctrls; |
| 1149 | } | 1185 | } |
| 1150 | if (ctrls == NULL) | ||
| 1151 | return -EINVAL; | ||
| 1152 | memcpy(q_ctrl, ctrls, sizeof *q_ctrl); | 1186 | memcpy(q_ctrl, ctrls, sizeof *q_ctrl); |
| 1153 | if (gspca_dev->ctrl_inac & (1 << i)) | 1187 | if (gspca_dev->ctrl_inac & (1 << i)) |
| 1154 | q_ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; | 1188 | q_ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; |
| @@ -1172,6 +1206,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv, | |||
| 1172 | PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value); | 1206 | PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value); |
| 1173 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | 1207 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) |
| 1174 | return -ERESTARTSYS; | 1208 | return -ERESTARTSYS; |
| 1209 | gspca_dev->usb_err = 0; | ||
| 1175 | if (gspca_dev->present) | 1210 | if (gspca_dev->present) |
| 1176 | ret = ctrls->set(gspca_dev, ctrl->value); | 1211 | ret = ctrls->set(gspca_dev, ctrl->value); |
| 1177 | else | 1212 | else |
| @@ -1193,6 +1228,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv, | |||
| 1193 | 1228 | ||
| 1194 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | 1229 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) |
| 1195 | return -ERESTARTSYS; | 1230 | return -ERESTARTSYS; |
| 1231 | gspca_dev->usb_err = 0; | ||
| 1196 | if (gspca_dev->present) | 1232 | if (gspca_dev->present) |
| 1197 | ret = ctrls->get(gspca_dev, &ctrl->value); | 1233 | ret = ctrls->get(gspca_dev, &ctrl->value); |
| 1198 | else | 1234 | else |
| @@ -1307,6 +1343,7 @@ static int vidioc_reqbufs(struct file *file, void *priv, | |||
| 1307 | /* stop streaming */ | 1343 | /* stop streaming */ |
| 1308 | if (gspca_dev->streaming) { | 1344 | if (gspca_dev->streaming) { |
| 1309 | mutex_lock(&gspca_dev->usb_lock); | 1345 | mutex_lock(&gspca_dev->usb_lock); |
| 1346 | gspca_dev->usb_err = 0; | ||
| 1310 | gspca_stream_off(gspca_dev); | 1347 | gspca_stream_off(gspca_dev); |
| 1311 | mutex_unlock(&gspca_dev->usb_lock); | 1348 | mutex_unlock(&gspca_dev->usb_lock); |
| 1312 | } | 1349 | } |
| @@ -1398,6 +1435,7 @@ static int vidioc_streamoff(struct file *file, void *priv, | |||
| 1398 | ret = -ERESTARTSYS; | 1435 | ret = -ERESTARTSYS; |
| 1399 | goto out; | 1436 | goto out; |
| 1400 | } | 1437 | } |
| 1438 | gspca_dev->usb_err = 0; | ||
| 1401 | gspca_stream_off(gspca_dev); | 1439 | gspca_stream_off(gspca_dev); |
| 1402 | mutex_unlock(&gspca_dev->usb_lock); | 1440 | mutex_unlock(&gspca_dev->usb_lock); |
| 1403 | 1441 | ||
| @@ -1423,6 +1461,7 @@ static int vidioc_g_jpegcomp(struct file *file, void *priv, | |||
| 1423 | return -EINVAL; | 1461 | return -EINVAL; |
| 1424 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | 1462 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) |
| 1425 | return -ERESTARTSYS; | 1463 | return -ERESTARTSYS; |
| 1464 | gspca_dev->usb_err = 0; | ||
| 1426 | if (gspca_dev->present) | 1465 | if (gspca_dev->present) |
| 1427 | ret = gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp); | 1466 | ret = gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp); |
| 1428 | else | 1467 | else |
| @@ -1441,6 +1480,7 @@ static int vidioc_s_jpegcomp(struct file *file, void *priv, | |||
| 1441 | return -EINVAL; | 1480 | return -EINVAL; |
| 1442 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | 1481 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) |
| 1443 | return -ERESTARTSYS; | 1482 | return -ERESTARTSYS; |
| 1483 | gspca_dev->usb_err = 0; | ||
| 1444 | if (gspca_dev->present) | 1484 | if (gspca_dev->present) |
| 1445 | ret = gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp); | 1485 | ret = gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp); |
| 1446 | else | 1486 | else |
| @@ -1461,6 +1501,7 @@ static int vidioc_g_parm(struct file *filp, void *priv, | |||
| 1461 | 1501 | ||
| 1462 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | 1502 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) |
| 1463 | return -ERESTARTSYS; | 1503 | return -ERESTARTSYS; |
| 1504 | gspca_dev->usb_err = 0; | ||
| 1464 | if (gspca_dev->present) | 1505 | if (gspca_dev->present) |
| 1465 | ret = gspca_dev->sd_desc->get_streamparm(gspca_dev, | 1506 | ret = gspca_dev->sd_desc->get_streamparm(gspca_dev, |
| 1466 | parm); | 1507 | parm); |
| @@ -1490,6 +1531,7 @@ static int vidioc_s_parm(struct file *filp, void *priv, | |||
| 1490 | 1531 | ||
| 1491 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | 1532 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) |
| 1492 | return -ERESTARTSYS; | 1533 | return -ERESTARTSYS; |
| 1534 | gspca_dev->usb_err = 0; | ||
| 1493 | if (gspca_dev->present) | 1535 | if (gspca_dev->present) |
| 1494 | ret = gspca_dev->sd_desc->set_streamparm(gspca_dev, | 1536 | ret = gspca_dev->sd_desc->set_streamparm(gspca_dev, |
| 1495 | parm); | 1537 | parm); |
| @@ -1613,7 +1655,7 @@ static int dev_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 1613 | size -= PAGE_SIZE; | 1655 | size -= PAGE_SIZE; |
| 1614 | } | 1656 | } |
| 1615 | 1657 | ||
| 1616 | vma->vm_ops = (struct vm_operations_struct *) &gspca_vm_ops; | 1658 | vma->vm_ops = &gspca_vm_ops; |
| 1617 | vma->vm_private_data = frame; | 1659 | vma->vm_private_data = frame; |
| 1618 | gspca_vm_open(vma); | 1660 | gspca_vm_open(vma); |
| 1619 | ret = 0; | 1661 | ret = 0; |
| @@ -1661,6 +1703,7 @@ static int frame_wait(struct gspca_dev *gspca_dev, | |||
| 1661 | 1703 | ||
| 1662 | if (gspca_dev->sd_desc->dq_callback) { | 1704 | if (gspca_dev->sd_desc->dq_callback) { |
| 1663 | mutex_lock(&gspca_dev->usb_lock); | 1705 | mutex_lock(&gspca_dev->usb_lock); |
| 1706 | gspca_dev->usb_err = 0; | ||
| 1664 | if (gspca_dev->present) | 1707 | if (gspca_dev->present) |
| 1665 | gspca_dev->sd_desc->dq_callback(gspca_dev); | 1708 | gspca_dev->sd_desc->dq_callback(gspca_dev); |
| 1666 | mutex_unlock(&gspca_dev->usb_lock); | 1709 | mutex_unlock(&gspca_dev->usb_lock); |
| @@ -1973,6 +2016,7 @@ static const struct v4l2_ioctl_ops dev_ioctl_ops = { | |||
| 1973 | .vidioc_g_parm = vidioc_g_parm, | 2016 | .vidioc_g_parm = vidioc_g_parm, |
| 1974 | .vidioc_s_parm = vidioc_s_parm, | 2017 | .vidioc_s_parm = vidioc_s_parm, |
| 1975 | .vidioc_enum_framesizes = vidioc_enum_framesizes, | 2018 | .vidioc_enum_framesizes = vidioc_enum_framesizes, |
| 2019 | .vidioc_enum_frameintervals = vidioc_enum_frameintervals, | ||
| 1976 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 2020 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 1977 | .vidioc_g_register = vidioc_g_register, | 2021 | .vidioc_g_register = vidioc_g_register, |
| 1978 | .vidioc_s_register = vidioc_s_register, | 2022 | .vidioc_s_register = vidioc_s_register, |
| @@ -1988,7 +2032,6 @@ static struct video_device gspca_template = { | |||
| 1988 | .fops = &dev_fops, | 2032 | .fops = &dev_fops, |
| 1989 | .ioctl_ops = &dev_ioctl_ops, | 2033 | .ioctl_ops = &dev_ioctl_ops, |
| 1990 | .release = gspca_release, | 2034 | .release = gspca_release, |
| 1991 | .minor = -1, | ||
| 1992 | }; | 2035 | }; |
| 1993 | 2036 | ||
| 1994 | /* | 2037 | /* |
| @@ -2049,9 +2092,6 @@ int gspca_dev_probe(struct usb_interface *intf, | |||
| 2049 | ret = sd_desc->init(gspca_dev); | 2092 | ret = sd_desc->init(gspca_dev); |
| 2050 | if (ret < 0) | 2093 | if (ret < 0) |
| 2051 | goto out; | 2094 | goto out; |
| 2052 | ret = gspca_set_alt0(gspca_dev); | ||
| 2053 | if (ret < 0) | ||
| 2054 | goto out; | ||
| 2055 | gspca_set_default_mode(gspca_dev); | 2095 | gspca_set_default_mode(gspca_dev); |
| 2056 | 2096 | ||
| 2057 | mutex_init(&gspca_dev->usb_lock); | 2097 | mutex_init(&gspca_dev->usb_lock); |
| @@ -2073,7 +2113,7 @@ int gspca_dev_probe(struct usb_interface *intf, | |||
| 2073 | } | 2113 | } |
| 2074 | 2114 | ||
| 2075 | usb_set_intfdata(intf, gspca_dev); | 2115 | usb_set_intfdata(intf, gspca_dev); |
| 2076 | PDEBUG(D_PROBE, "/dev/video%d created", gspca_dev->vdev.num); | 2116 | PDEBUG(D_PROBE, "%s created", video_device_node_name(&gspca_dev->vdev)); |
| 2077 | return 0; | 2117 | return 0; |
| 2078 | out: | 2118 | out: |
| 2079 | kfree(gspca_dev->usb_buf); | 2119 | kfree(gspca_dev->usb_buf); |
| @@ -2092,7 +2132,8 @@ void gspca_disconnect(struct usb_interface *intf) | |||
| 2092 | { | 2132 | { |
| 2093 | struct gspca_dev *gspca_dev = usb_get_intfdata(intf); | 2133 | struct gspca_dev *gspca_dev = usb_get_intfdata(intf); |
| 2094 | 2134 | ||
| 2095 | PDEBUG(D_PROBE, "/dev/video%d disconnect", gspca_dev->vdev.num); | 2135 | PDEBUG(D_PROBE, "%s disconnect", |
| 2136 | video_device_node_name(&gspca_dev->vdev)); | ||
| 2096 | mutex_lock(&gspca_dev->usb_lock); | 2137 | mutex_lock(&gspca_dev->usb_lock); |
| 2097 | gspca_dev->present = 0; | 2138 | gspca_dev->present = 0; |
| 2098 | 2139 | ||
