hc
2024-05-10 23fa18eaa71266feff7ba8d83022d9e1cc83c65a
kernel/drivers/media/usb/pwc/pwc-if.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /* Linux driver for Philips webcam
23 USB and Video4Linux interface part.
34 (C) 1999-2004 Nemosoft Unv.
....@@ -10,19 +11,6 @@
1011 The decompression routines have been implemented by reverse-engineering the
1112 Nemosoft binary pwcx module. Caveat emptor.
1213
13
- This program is free software; you can redistribute it and/or modify
14
- it under the terms of the GNU General Public License as published by
15
- the Free Software Foundation; either version 2 of the License, or
16
- (at your option) any later version.
17
-
18
- This program is distributed in the hope that it will be useful,
19
- but WITHOUT ANY WARRANTY; without even the implied warranty of
20
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
- GNU General Public License for more details.
22
-
23
- You should have received a copy of the GNU General Public License
24
- along with this program; if not, write to the Free Software
25
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2614
2715 */
2816
....@@ -76,41 +64,52 @@
7664 #include "pwc-dec23.h"
7765 #include "pwc-dec1.h"
7866
67
+#define CREATE_TRACE_POINTS
68
+#include <trace/events/pwc.h>
69
+
7970 /* Function prototypes and driver templates */
8071
8172 /* hotplug device table support */
8273 static const struct usb_device_id pwc_device_table [] = {
83
- { USB_DEVICE(0x0471, 0x0302) }, /* Philips models */
84
- { USB_DEVICE(0x0471, 0x0303) },
85
- { USB_DEVICE(0x0471, 0x0304) },
86
- { USB_DEVICE(0x0471, 0x0307) },
87
- { USB_DEVICE(0x0471, 0x0308) },
88
- { USB_DEVICE(0x0471, 0x030C) },
89
- { USB_DEVICE(0x0471, 0x0310) },
90
- { USB_DEVICE(0x0471, 0x0311) }, /* Philips ToUcam PRO II */
91
- { USB_DEVICE(0x0471, 0x0312) },
92
- { USB_DEVICE(0x0471, 0x0313) }, /* the 'new' 720K */
93
- { USB_DEVICE(0x0471, 0x0329) }, /* Philips SPC 900NC PC Camera */
94
- { USB_DEVICE(0x0471, 0x032C) }, /* Philips SPC 880NC PC Camera */
95
- { USB_DEVICE(0x069A, 0x0001) }, /* Askey */
96
- { USB_DEVICE(0x046D, 0x08B0) }, /* Logitech QuickCam Pro 3000 */
74
+ { USB_DEVICE(0x041E, 0x400C) }, /* Creative Webcam 5 */
75
+ { USB_DEVICE(0x041E, 0x4011) }, /* Creative Webcam Pro Ex */
76
+
77
+ { USB_DEVICE(0x046D, 0x08B0) }, /* Logitech QuickCam 3000 Pro */
9778 { USB_DEVICE(0x046D, 0x08B1) }, /* Logitech QuickCam Notebook Pro */
98
- { USB_DEVICE(0x046D, 0x08B2) }, /* Logitech QuickCam Pro 4000 */
79
+ { USB_DEVICE(0x046D, 0x08B2) }, /* Logitech QuickCam 4000 Pro */
9980 { USB_DEVICE(0x046D, 0x08B3) }, /* Logitech QuickCam Zoom (old model) */
10081 { USB_DEVICE(0x046D, 0x08B4) }, /* Logitech QuickCam Zoom (new model) */
10182 { USB_DEVICE(0x046D, 0x08B5) }, /* Logitech QuickCam Orbit/Sphere */
102
- { USB_DEVICE(0x046D, 0x08B6) }, /* Cisco VT Camera */
83
+ { USB_DEVICE(0x046D, 0x08B6) }, /* Logitech/Cisco VT Camera */
10384 { USB_DEVICE(0x046D, 0x08B7) }, /* Logitech ViewPort AV 100 */
104
- { USB_DEVICE(0x046D, 0x08B8) }, /* Logitech (reserved) */
85
+ { USB_DEVICE(0x046D, 0x08B8) }, /* Logitech QuickCam */
86
+
87
+ { USB_DEVICE(0x0471, 0x0302) }, /* Philips PCA645VC */
88
+ { USB_DEVICE(0x0471, 0x0303) }, /* Philips PCA646VC */
89
+ { USB_DEVICE(0x0471, 0x0304) }, /* Askey VC010 type 2 */
90
+ { USB_DEVICE(0x0471, 0x0307) }, /* Philips PCVC675K (Vesta) */
91
+ { USB_DEVICE(0x0471, 0x0308) }, /* Philips PCVC680K (Vesta Pro) */
92
+ { USB_DEVICE(0x0471, 0x030C) }, /* Philips PCVC690K (Vesta Pro Scan) */
93
+ { USB_DEVICE(0x0471, 0x0310) }, /* Philips PCVC730K (ToUCam Fun)/PCVC830 (ToUCam II) */
94
+ { USB_DEVICE(0x0471, 0x0311) }, /* Philips PCVC740K (ToUCam Pro)/PCVC840 (ToUCam II) */
95
+ { USB_DEVICE(0x0471, 0x0312) }, /* Philips PCVC750K (ToUCam Pro Scan) */
96
+ { USB_DEVICE(0x0471, 0x0313) }, /* Philips PCVC720K/40 (ToUCam XS) */
97
+ { USB_DEVICE(0x0471, 0x0329) }, /* Philips SPC 900NC webcam */
98
+ { USB_DEVICE(0x0471, 0x032C) }, /* Philips SPC 880NC webcam */
99
+
100
+ { USB_DEVICE(0x04CC, 0x8116) }, /* Sotec Afina Eye */
101
+
105102 { USB_DEVICE(0x055D, 0x9000) }, /* Samsung MPC-C10 */
106103 { USB_DEVICE(0x055D, 0x9001) }, /* Samsung MPC-C30 */
107104 { USB_DEVICE(0x055D, 0x9002) }, /* Samsung SNC-35E (Ver3.0) */
108
- { USB_DEVICE(0x041E, 0x400C) }, /* Creative Webcam 5 */
109
- { USB_DEVICE(0x041E, 0x4011) }, /* Creative Webcam Pro Ex */
110
- { USB_DEVICE(0x04CC, 0x8116) }, /* Afina Eye */
111
- { USB_DEVICE(0x06BE, 0x8116) }, /* new Afina Eye */
112
- { USB_DEVICE(0x0d81, 0x1910) }, /* Visionite */
113
- { USB_DEVICE(0x0d81, 0x1900) },
105
+
106
+ { USB_DEVICE(0x069A, 0x0001) }, /* Askey VC010 type 1 */
107
+
108
+ { USB_DEVICE(0x06BE, 0x8116) }, /* AME Co. Afina Eye */
109
+
110
+ { USB_DEVICE(0x0d81, 0x1900) }, /* Visionite VCS-UC300 */
111
+ { USB_DEVICE(0x0d81, 0x1910) }, /* Visionite VCS-UM100 */
112
+
114113 { }
115114 };
116115 MODULE_DEVICE_TABLE(usb, pwc_device_table);
....@@ -155,6 +154,35 @@
155154
156155 /***************************************************************************/
157156 /* Private functions */
157
+
158
+static void *pwc_alloc_urb_buffer(struct usb_device *dev,
159
+ size_t size, dma_addr_t *dma_handle)
160
+{
161
+ struct device *dmadev = dev->bus->sysdev;
162
+ void *buffer = kmalloc(size, GFP_KERNEL);
163
+
164
+ if (!buffer)
165
+ return NULL;
166
+
167
+ *dma_handle = dma_map_single(dmadev, buffer, size, DMA_FROM_DEVICE);
168
+ if (dma_mapping_error(dmadev, *dma_handle)) {
169
+ kfree(buffer);
170
+ return NULL;
171
+ }
172
+
173
+ return buffer;
174
+}
175
+
176
+static void pwc_free_urb_buffer(struct usb_device *dev,
177
+ size_t size,
178
+ void *buffer,
179
+ dma_addr_t dma_handle)
180
+{
181
+ struct device *dmadev = dev->bus->sysdev;
182
+
183
+ dma_unmap_single(dmadev, dma_handle, size, DMA_FROM_DEVICE);
184
+ kfree(buffer);
185
+}
158186
159187 static struct pwc_frame_buf *pwc_get_next_fill_buf(struct pwc_device *pdev)
160188 {
....@@ -257,8 +285,11 @@
257285 static void pwc_isoc_handler(struct urb *urb)
258286 {
259287 struct pwc_device *pdev = (struct pwc_device *)urb->context;
288
+ struct device *dmadev = urb->dev->bus->sysdev;
260289 int i, fst, flen;
261290 unsigned char *iso_buf = NULL;
291
+
292
+ trace_pwc_handler_enter(urb, pdev);
262293
263294 if (urb->status == -ENOENT || urb->status == -ECONNRESET ||
264295 urb->status == -ESHUTDOWN) {
....@@ -300,6 +331,11 @@
300331
301332 /* Reset ISOC error counter. We did get here, after all. */
302333 pdev->visoc_errors = 0;
334
+
335
+ dma_sync_single_for_cpu(dmadev,
336
+ urb->transfer_dma,
337
+ urb->transfer_buffer_length,
338
+ DMA_FROM_DEVICE);
303339
304340 /* vsync: 0 = don't copy data
305341 1 = sync-hunt
....@@ -347,7 +383,14 @@
347383 pdev->vlast_packet_size = flen;
348384 }
349385
386
+ dma_sync_single_for_device(dmadev,
387
+ urb->transfer_dma,
388
+ urb->transfer_buffer_length,
389
+ DMA_FROM_DEVICE);
390
+
350391 handler_end:
392
+ trace_pwc_handler_exit(urb, pdev);
393
+
351394 i = usb_submit_urb(urb, GFP_ATOMIC);
352395 if (i != 0)
353396 PWC_ERROR("Error (%d) re-submitting urb in pwc_isoc_handler.\n", i);
....@@ -421,16 +464,15 @@
421464 urb->dev = udev;
422465 urb->pipe = usb_rcvisocpipe(udev, pdev->vendpoint);
423466 urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
424
- urb->transfer_buffer = usb_alloc_coherent(udev,
425
- ISO_BUFFER_SIZE,
426
- GFP_KERNEL,
427
- &urb->transfer_dma);
467
+ urb->transfer_buffer_length = ISO_BUFFER_SIZE;
468
+ urb->transfer_buffer = pwc_alloc_urb_buffer(udev,
469
+ urb->transfer_buffer_length,
470
+ &urb->transfer_dma);
428471 if (urb->transfer_buffer == NULL) {
429472 PWC_ERROR("Failed to allocate urb buffer %d\n", i);
430473 pwc_isoc_cleanup(pdev);
431474 return -ENOMEM;
432475 }
433
- urb->transfer_buffer_length = ISO_BUFFER_SIZE;
434476 urb->complete = pwc_isoc_handler;
435477 urb->context = pdev;
436478 urb->start_frame = 0;
....@@ -481,15 +523,16 @@
481523
482524 /* Freeing ISOC buffers one by one */
483525 for (i = 0; i < MAX_ISO_BUFS; i++) {
484
- if (pdev->urbs[i]) {
526
+ struct urb *urb = pdev->urbs[i];
527
+
528
+ if (urb) {
485529 PWC_DEBUG_MEMORY("Freeing URB\n");
486
- if (pdev->urbs[i]->transfer_buffer) {
487
- usb_free_coherent(pdev->udev,
488
- pdev->urbs[i]->transfer_buffer_length,
489
- pdev->urbs[i]->transfer_buffer,
490
- pdev->urbs[i]->transfer_dma);
491
- }
492
- usb_free_urb(pdev->urbs[i]);
530
+ if (urb->transfer_buffer)
531
+ pwc_free_urb_buffer(urb->dev,
532
+ urb->transfer_buffer_length,
533
+ urb->transfer_buffer,
534
+ urb->transfer_dma);
535
+ usb_free_urb(urb);
493536 pdev->urbs[i] = NULL;
494537 }
495538 }
....@@ -610,7 +653,7 @@
610653 {
611654 struct pwc_device *pdev = vb2_get_drv_priv(vb->vb2_queue);
612655
613
- /* Don't allow queing new buffers after device disconnection */
656
+ /* Don't allow queueing new buffers after device disconnection */
614657 if (!pdev->udev)
615658 return -ENODEV;
616659
....@@ -1027,7 +1070,7 @@
10271070
10281071 /* Init video_device structure */
10291072 pdev->vdev = pwc_template;
1030
- strcpy(pdev->vdev.name, name);
1073
+ strscpy(pdev->vdev.name, name, sizeof(pdev->vdev.name));
10311074 pdev->vdev.queue = &pdev->vb_queue;
10321075 pdev->vdev.queue->lock = &pdev->vb_queue_lock;
10331076 video_set_drvdata(&pdev->vdev, pdev);
....@@ -1082,8 +1125,10 @@
10821125 pdev->v4l2_dev.ctrl_handler = &pdev->ctrl_handler;
10831126 pdev->vdev.v4l2_dev = &pdev->v4l2_dev;
10841127 pdev->vdev.lock = &pdev->v4l2_lock;
1128
+ pdev->vdev.device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
1129
+ V4L2_CAP_READWRITE;
10851130
1086
- rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, -1);
1131
+ rc = video_register_device(&pdev->vdev, VFL_TYPE_VIDEO, -1);
10871132 if (rc < 0) {
10881133 PWC_ERROR("Failed to register as video device (%d).\n", rc);
10891134 goto err_unregister_v4l2_dev;