Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 127086 | Differences between
and this patch

Collapse All | Expand All

(-)uvcvideo.c (-21 / +69 lines)
Lines 49-55 Link Here
49
49
50
#define DRIVER_AUTHOR		"Laurent Pinchart <laurent.pinchart@skynet.be>"
50
#define DRIVER_AUTHOR		"Laurent Pinchart <laurent.pinchart@skynet.be>"
51
#define DRIVER_DESC		"USB Video Class driver"
51
#define DRIVER_DESC		"USB Video Class driver"
52
#define DRIVER_VERSION		"0.1.0"
52
#define DRIVER_VERSION		"0.1.0-b"
53
#define DRIVER_VERSION_NUMBER	KERNEL_VERSION(0, 1, 0)
53
#define DRIVER_VERSION_NUMBER	KERNEL_VERSION(0, 1, 0)
54
54
55
#define UVC_CTRL_TIMEOUT	300
55
#define UVC_CTRL_TIMEOUT	300
Lines 73-78 Link Here
73
				 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
73
				 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
74
#define UVC_GUID_FORMAT_YUY2	{0x59, 0x55, 0x59, 0x32, 0x00, 0x00, 0x10, 0x00, \
74
#define UVC_GUID_FORMAT_YUY2	{0x59, 0x55, 0x59, 0x32, 0x00, 0x00, 0x10, 0x00, \
75
				 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
75
				 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
76
#define UVC_GUID_FORMAT_YUY2A	{0x59, 0x55, 0x59, 0x32, 0x00, 0x00, 0x10, 0x00, \
77
				 0x00, 0x80, 0x71, 0x9b, 0x38, 0x00, 0xaa, 0x00}
76
#define UVC_GUID_FORMAT_NV12	{0x4e, 0x56, 0x31, 0x32, 0x00, 0x00, 0x10, 0x00, \
78
#define UVC_GUID_FORMAT_NV12	{0x4e, 0x56, 0x31, 0x32, 0x00, 0x00, 0x10, 0x00, \
77
				 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
79
				 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
78
80
Lines 564-571 Link Here
564
		.fcc		= V4L2_PIX_FMT_YUYV,
566
		.fcc		= V4L2_PIX_FMT_YUYV,
565
	},
567
	},
566
	{
568
	{
567
		.guid		= UVC_GUID_FORMAT_YUY2,
569
		.guid		= UVC_GUID_FORMAT_YUY2A,
568
		.fcc		= V4L2_PIX_FMT_YUYV,
570
		.fcc		= V4L2_PIX_FMT_UYVY,
569
	},
571
	},
570
	{
572
	{
571
		.guid		= UVC_GUID_FORMAT_NV12,
573
		.guid		= UVC_GUID_FORMAT_NV12,
Lines 1271-1294 Link Here
1271
		struct uvc_buffer *buf, const __u8 *data, unsigned int len)
1273
		struct uvc_buffer *buf, const __u8 *data, unsigned int len)
1272
{
1274
{
1273
	unsigned int maxlen, nbytes;
1275
	unsigned int maxlen, nbytes;
1274
	void *mem;
1276
	__u8 *mem;
1275
	__u8 fid;
1277
	__u8 fid = queue->last_fid;
1278
	int hlen = 0, flags = 0, is_header = 0;
1279
	static const __u8 hdr[] = { 0x11, 0x22, 0x33, 0x44,
1280
				    0xde, 0xad, 0xbe, 0xef,
1281
				    0xde, 0xad, 0xfa, 0xce };
1276
1282
1277
	/* Sanity checks:
1283
	/* Sanity checks:
1278
	 * - packet must be at least 2 bytes long
1284
	 * - packet must be at least 2 bytes long
1279
	 * - bHeaderLength value must be at least 2 bytes (see above)
1285
	 * - bHeaderLength value must be at least 2 bytes (see above)
1280
	 * - bHeaderLength value can't be larger than the packet size.
1286
	 * - bHeaderLength value can't be larger than the packet size.
1281
	 */
1287
	 */
1282
	if (len < 2 || data[0] < 2 || data[0] > len)
1288
	if ((len >= 14 && memcmp (&data[3], hdr, 12) == 0) ||
1283
		return -EINVAL;
1289
	    (len >= 13 && memcmp (&data[2], hdr, 12) == 0)) {
1290
		uvc_trace(UVC_TRACE_FRAME, "Detecting new header");
1291
		hlen = (data[3] == 0x11) ? data[1] : data[0];
1292
		if (hlen > len - 1 || hlen < 2)
1293
			return -EINVAL;
1294
		flags = (data[3] == 0x11) ? data[2] : data[1];
1295
		is_header = 1;
1296
	}
1284
1297
1285
	/* Skip payloads marked with the error bit ("error frames"). */
1298
	/* Skip payloads marked with the error bit ("error frames"). */
1286
	if (data[1] & UVC_STREAM_ERR) {
1299
	if (hlen != 0 && flags & UVC_STREAM_ERR) {
1287
		uvc_trace(UVC_TRACE_FRAME, "Dropping packet (error bit set).\n");
1300
		uvc_trace(UVC_TRACE_FRAME, "Dropping packet (error bit set).\n");
1288
		return 0;
1301
1302
		//return 0;
1289
	}
1303
	}
1290
1304
1291
	fid = data[1] & UVC_STREAM_FID;
1305
	if (hlen != 0) {
1306
		fid = flags & UVC_STREAM_FID;
1307
	}
1292
1308
1293
	/* Store the packet FID bit and return immediately when the buffer is
1309
	/* Store the packet FID bit and return immediately when the buffer is
1294
	 * NULL.
1310
	 * NULL.
Lines 1334-1361 Link Here
1334
				"toggled).\n");
1350
				"toggled).\n");
1335
		buf->state = UVC_BUF_STATE_DONE;
1351
		buf->state = UVC_BUF_STATE_DONE;
1336
		return -EAGAIN;
1352
		return -EAGAIN;
1353
	} else if (is_header && buf->buf.bytesused > 0) {
1354
		buf->state = UVC_BUF_STATE_DONE;
1355
		return -EAGAIN;
1337
	}
1356
	}
1338
1357
1339
	queue->last_fid = fid;
1358
	queue->last_fid = fid;
1340
1359
1341
	/* Copy the video data to the buffer. */
1360
	/* Copy the video data to the buffer. */
1342
	len -= data[0];
1361
	len -= hlen;
1343
	maxlen = buf->buf.length - buf->buf.bytesused;
1362
	maxlen = buf->buf.length - buf->buf.bytesused;
1344
	mem = queue->mem + buf->buf.m.offset + buf->buf.bytesused;
1363
	if (!is_header) { /* we skip headers, they do not contain data */
1345
	nbytes = min(len, maxlen);
1364
		mem = queue->mem + buf->buf.m.offset + buf->buf.bytesused;
1346
	memcpy(mem, data + data[0], nbytes);
1365
		nbytes = min(len - hlen, maxlen);
1347
	buf->buf.bytesused += nbytes;
1366
		memmove(mem, data + hlen, nbytes);
1367
		buf->buf.bytesused += nbytes;
1368
	}
1348
1369
1349
	/* Drop the current frame if the buffer size was exceeded. */
1370
	/* Drop the current frame if the buffer size was exceeded. */
1350
	if (len > maxlen) {
1371
	if (len - hlen > maxlen || buf->buf.bytesused == buf->buf.length) {
1351
		uvc_trace(UVC_TRACE_FRAME, "Frame complete (overflow).\n");
1372
		uvc_trace(UVC_TRACE_FRAME, "Frame complete (overflow).\n");
1352
		buf->state = UVC_BUF_STATE_DONE;
1373
		buf->state = UVC_BUF_STATE_DONE;
1353
	}
1374
	}
1354
1375
1355
	/* Mark the buffer as done if the EOF marker is set. */
1376
	/* Mark the buffer as done if the EOF marker is set. */
1356
	if (data[1] & UVC_STREAM_EOF && buf->buf.bytesused != 0) {
1377
	if (hlen != 0 && (flags & UVC_STREAM_EOF && buf->buf.bytesused != 0)) {
1357
		uvc_trace(UVC_TRACE_FRAME, "Frame complete (EOF found).\n");
1378
		uvc_trace(UVC_TRACE_FRAME, "Frame complete (EOF found).\n");
1358
		if (data[0] == len)
1379
		if (hlen != 0 && hlen == len)
1359
			printk("EOF in empty packet.\n");
1380
			printk("EOF in empty packet.\n");
1360
		buf->state = UVC_BUF_STATE_DONE;
1381
		buf->state = UVC_BUF_STATE_DONE;
1361
	}
1382
	}
Lines 1593-1599 Link Here
1593
1614
1594
	if (ret != size) {
1615
	if (ret != size) {
1595
		uvc_printk(KERN_ERR, "Failed to query (%u) UVC control %u "
1616
		uvc_printk(KERN_ERR, "Failed to query (%u) UVC control %u "
1596
			"(unit %u) : %d.\n", query, cs, unit, ret);
1617
			"(unit %u) : %d (exp: %u).\n", query, cs, unit, ret, size);
1597
		return -EIO;
1618
		return -EIO;
1598
	}
1619
	}
1599
1620
Lines 1883-1890 Link Here
1883
1904
1884
	/* Get the minimum and maximum values for compression settings. */
1905
	/* Get the minimum and maximum values for compression settings. */
1885
	if ((ret = uvc_get_video_ctrl(video, &probe_min, 1, GET_MIN)) < 0 ||
1906
	if ((ret = uvc_get_video_ctrl(video, &probe_min, 1, GET_MIN)) < 0 ||
1886
	    (ret = uvc_get_video_ctrl(video, &probe_max, 1, GET_MAX)) < 0)
1907
	    (ret = uvc_get_video_ctrl(video, &probe_max, 1, GET_MAX)) < 0) {
1908
		ret = 0;
1887
		goto done;
1909
		goto done;
1910
	}
1888
1911
1889
	probe->wCompQuality = probe_max.wCompQuality;
1912
	probe->wCompQuality = probe_max.wCompQuality;
1890
1913
Lines 1942-1948 Link Here
1942
		return ret;
1965
		return ret;
1943
1966
1944
	/* Retrieve the default format and commit it. */
1967
	/* Retrieve the default format and commit it. */
1945
	if ((ret = uvc_get_video_ctrl(video, probe, 1, GET_DEF)) < 0)
1968
	if ((ret = uvc_get_video_ctrl(video, probe, 1, GET_CUR)) < 0)
1946
		return ret;
1969
		return ret;
1947
	if ((ret = uvc_set_video_ctrl(video, probe, 0)) < 0)
1970
	if ((ret = uvc_set_video_ctrl(video, probe, 0)) < 0)
1948
		return ret;
1971
		return ret;
Lines 2214-2219 Link Here
2214
	if ((ret = uvc_set_video_ctrl(video, &probe, 0)) < 0)
2237
	if ((ret = uvc_set_video_ctrl(video, &probe, 0)) < 0)
2215
		return ret;
2238
		return ret;
2216
2239
2240
	if (probe.dwMaxVideoFrameSize == 0)
2241
		probe.dwMaxVideoFrameSize =
2242
			video->streaming->format[probe.bFormatIndex - 1].
2243
				frame[probe.bFrameIndex - 1].dwMaxVideoFrameBufferSize;
2244
2217
	memcpy(&video->streaming->ctrl, &probe, sizeof probe);
2245
	memcpy(&video->streaming->ctrl, &probe, sizeof probe);
2218
	video->streaming->cur_format = format;
2246
	video->streaming->cur_format = format;
2219
	video->streaming->cur_frame = frame;
2247
	video->streaming->cur_frame = frame;
Lines 3506-3511 Link Here
3506
3534
3507
	if (!found) {
3535
	if (!found) {
3508
		uvc_printk(KERN_INFO, "No valid video chain found.\n");
3536
		uvc_printk(KERN_INFO, "No valid video chain found.\n");
3537
		if (dev->udev->descriptor.idVendor == 0x05ac &&
3538
		    dev->udev->descriptor.idProduct == 0x8300) {
3539
			uvc_printk (KERN_ERR, "Possible an Apple iSight "
3540
				    "without firmware loaded; please read "
3541
				    "the documentation, load the firmware "
3542
				    "and re-load the driver.");
3543
		}
3509
		return -1;
3544
		return -1;
3510
	}
3545
	}
3511
3546
Lines 3757-3762 Link Here
3757
	  .bInterfaceClass	= USB_CLASS_VENDOR_SPEC,
3792
	  .bInterfaceClass	= USB_CLASS_VENDOR_SPEC,
3758
	  .bInterfaceSubClass	= 1,
3793
	  .bInterfaceSubClass	= 1,
3759
	  .bInterfaceProtocol	= 0 },
3794
	  .bInterfaceProtocol	= 0 },
3795
	/* Apple iSight (built-in in Macintels) */
3796
	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE,
3797
	  .idVendor		= 0x05ac,
3798
	  .idProduct		= 0x8501 },
3799
	/* same, but without firmware loaded (will give useful warning)
3800
	 * when the firmware is not loaded in the pre-instal step). */
3801
	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
3802
				| USB_DEVICE_ID_MATCH_INT_INFO,
3803
	  .idVendor		= 0x05ac,
3804
	  .idProduct		= 0x8300,
3805
	  .bInterfaceClass	= USB_CLASS_VENDOR_SPEC,
3806
	  .bInterfaceSubClass	= 0xff,
3807
	  .bInterfaceProtocol	= 0xff },
3760
	/* Generic USB Video Class */
3808
	/* Generic USB Video Class */
3761
	{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) },
3809
	{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) },
3762
	{}
3810
	{}
(-)Makefile (-2 / +11 lines)
Lines 1-7 Link Here
1
KERNEL_VERSION	:= `uname -r`
1
KERNEL_VERSION	:= `uname -r`
2
KERNEL_DIR	:= /lib/modules/$(KERNEL_VERSION)/build
2
KERNEL_DIR	:= /lib/modules/$(KERNEL_VERSION)/build
3
INSTALL_MOD_DIR	:= usb/media
3
INSTALL_MOD_DIR	:= usb/media
4
4
DRIVER_VERSION	:= `grep DRIVER_VERSION uvcvideo.c | grep define | grep -v DRIVER_VERSION_NUMBER | cut -d"\"" -f2`
5
PWD		:= $(shell pwd)
5
PWD		:= $(shell pwd)
6
6
7
obj-m		:= uvcvideo.o
7
obj-m		:= uvcvideo.o
Lines 9-15 Link Here
9
%.o : %.c
9
%.o : %.c
10
	gcc $(TEST_CFLAGS) -c -o $@ $<
10
	gcc $(TEST_CFLAGS) -c -o $@ $<
11
11
12
all: uvcvideo
12
all: uvcvideo extract
13
13
14
uvcvideo:
14
uvcvideo:
15
	@echo "Building USB Video Class driver..."
15
	@echo "Building USB Video Class driver..."
Lines 24-26 Link Here
24
	-rm -f *.o *.ko .*.cmd .*.flags *.mod.c Modules.symvers
24
	-rm -f *.o *.ko .*.cmd .*.flags *.mod.c Modules.symvers
25
	-rm -rf .tmp_versions
25
	-rm -rf .tmp_versions
26
26
27
extract: extract.c
28
	gcc -g `pkg-config --cflags --libs libusb` -o extract extract.c
29
30
dist:
31
	rm -fr linux-uvc-${DRIVER_VERSION}
32
	mkdir linux-uvc-${DRIVER_VERSION}
33
	cp uvcvideo.[ch] Makefile extract.c linux-uvc-${DRIVER_VERSION}/
34
	tar -zcf linux-uvc-${DRIVER_VERSION}.tar.gz linux-uvc-${DRIVER_VERSION}
35
	rm -fr linux-uvc-${DRIVER_VERSION}
(-) (+202 lines)
Added Link Here
1
/*
2
 * Apple iSight (the one built in the screen of Macbooks) firmware loader
3
 * Copyright (C) 2006 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
4
 *
5
 * Special thanks to Johannes Berg <johannes@sipsolutions.net> for helping
6
 * to find out how to load the firmware; see his website on
7
 * http://johannes.sipsolutions.net/MacBook/iSight for details.
8
 *
9
 * This program is free software; you can redistribute it and/or modify
10
 * it under the terms of the GNU General Public License as published by
11
 * the Free Software Foundation; either version 2 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22
 * MA 02110-1301, USA
23
 */
24
25
#include <stdlib.h>
26
#include <stdio.h>
27
#include <sys/types.h>
28
#include <sys/stat.h>
29
#include <fcntl.h>
30
#include <errno.h>
31
32
#include <usb.h>
33
#define TIMEOUT 300
34
35
static int
36
read_fw (struct usb_dev_handle *dev, char *filename)
37
{
38
	long long int pos;
39
	int fd, rd, len, req, llen, res, ret = -1;
40
	unsigned char data[4], rdata[1024], *ptr;
41
42
	if ((fd = open (filename, O_RDONLY)) == -1) {
43
		perror ("Opening file");
44
		return -1;
45
	} else if (lseek (fd, 5172, SEEK_SET) != 5172) {
46
		perror ("Seeking");
47
		close (fd);
48
		return -1;
49
	}
50
51
	if ((res = usb_control_msg (dev, 0x40, 0xA0, 0xe600, 0,
52
				    "\1", 1, TIMEOUT)) != 1) {
53
		perror ("Firmware load init failed");
54
		close (fd);
55
		return -1;
56
	}
57
	while (1) {
58
		if ((len = read (fd, data, 4)) != 4) {
59
			if (len == 0) {
60
				fprintf (stderr,
61
					 "Unexpected eos - corrupt driver?\n");
62
				goto end;
63
			} else {
64
				perror("Reading firmware header chunk failed");
65
				goto end;
66
			}
67
		}
68
		len = (data[0] << 8) | data[1];
69
		req = (data[2] << 8) | data[3];
70
		if (len == 0x8001)
71
			break; /* success */
72
		else if (len == 0)
73
			continue;
74
		else if (len < 0 || len >= 1024) {
75
			fprintf (stderr,
76
				 "Invalid firmware length %d, load aborted\n",
77
				 len);
78
			goto end;
79
		} else if (read (fd, rdata, len) != len) {
80
			perror ("Error reading firmware data");
81
			goto end;
82
		}
83
84
		/* upload to usb bus */
85
		for (ptr = rdata; len > 0; req += 50, ptr += 50) {
86
			llen = len > 50 ? 50 : len;
87
			len -= llen;
88
89
			if ((res = usb_control_msg (dev, 0x40, 0xA0, req, 0,
90
						    (char *) ptr, llen,
91
						    TIMEOUT)) != llen) {
92
				fprintf (stderr,
93
					 "firmware load req=0x%x failed: %s\n",
94
					 req, strerror (errno));
95
				goto end;
96
			}
97
		}
98
	}
99
100
	ret = 0;
101
end:
102
	if ((res = usb_control_msg (dev, 0x40, 0xA0, 0xe600, 0,
103
				    "\0", 1, TIMEOUT)) != 1) {
104
		perror ("Firmware finish-up failed");
105
		ret = -1;
106
	}
107
108
	close (fd);
109
110
	return ret;
111
}
112
113
static int
114
probe_dev (struct usb_device *dev, char *fw_filename)
115
{
116
	int n, total = 0;
117
118
	if (dev->descriptor.idVendor == 0x05ac &&
119
	    dev->descriptor.idProduct == 0x8300 &&
120
	    dev->descriptor.bDeviceClass == 0xff &&
121
	    dev->descriptor.bDeviceSubClass == 0xff &&
122
	    dev->descriptor.bDeviceProtocol == 0xff) {
123
		usb_dev_handle *h;
124
125
		/* load firmware */
126
		if (!(h = usb_open (dev))) {
127
			perror ("Opening iSight");
128
			return;
129
		}
130
		printf ("Loading firmware for iSight...\n");
131
		if (read_fw (h, fw_filename) == 0) {
132
			printf ("done\n");
133
			total++;
134
		}
135
		usb_close (h);
136
	} else if (dev->descriptor.idVendor == 0x05ac &&
137
		   dev->descriptor.idProduct == 0x8501) {
138
		printf ("Apple iSight with firmware already loaded found\n");
139
		total++;
140
	}
141
142
	for (n = 0; n < dev->num_children; n++)
143
		total += probe_dev (dev->children[n], fw_filename);
144
145
	return total;
146
}
147
148
int
149
main (int argc, char *argv[])
150
{
151
	int n, m, found = 0;
152
	char command[1024];
153
	struct usb_bus *bus;
154
	struct usb_device *dev;
155
156
	if (argc != 2) {
157
		fprintf(stderr, "Usage: %s <firmware file>\n", argv[0]);
158
		fprintf(stderr, "Firmware can usually be found on your Mac "
159
			"partition in /System/Library/Extensions/"
160
			"IOUSBFamily.kext/Contents/PlugIns/"
161
			"AppleUSBVideoSupport.kext/Contents/MacOS/"
162
			"AppleUSBVideoSupport\n");
163
		return -1;
164
	}
165
	
166
	/* check sha1sum on firmware, to prevent loading crap into the
167
	 * iSight and thus possibly damaging it. */
168
	snprintf (command, sizeof (command) - 1,
169
		  "test \"x`sha1sum %s`\" == \"x%s  %s\" &> /dev/null",
170
		  argv[1], "86430c04f9b67c5c3d84409138a7679827025ec2",
171
		  argv[1]);
172
	if (system (command) != 0) {
173
		fprintf (stderr, "Sha1sum check on firmware file failed\n");
174
		return -1;
175
	}
176
177
	/* init usb */
178
	usb_init ();
179
	if (usb_find_busses () == 0) {
180
		fprintf (stderr, "No USB busses found\n");
181
		return -1;
182
	} else if (usb_find_devices () == 0) {
183
		fprintf (stderr, "No USB devices found\n");
184
		return -1;
185
	}
186
187
	/* find iSight */
188
	for (bus = usb_busses; bus != NULL; bus = bus->next) {
189
		if (bus->devices != NULL) {
190
			for (dev = bus->devices; dev != NULL;
191
			     dev = dev->next) {
192
				found += probe_dev (dev, argv[1]);
193
			}
194
		}
195
	}
196
	if (found == 0) {
197
		fprintf (stderr, "No Apple iSight found!\n");
198
		return -1;
199
	}
200
201
	return 0;
202
}

Return to bug 127086