]>
Commit | Line | Data |
---|---|---|
826a9352 | 1 | diff -Nur --exclude='*.orig' linux-2.6.0-test1.org/drivers/media/video/bttv-cards.c linux-2.6.0-test1/drivers/media/video/bttv-cards.c |
2 | --- linux-2.6.0-test1.org/drivers/media/video/bttv-cards.c Mon Jul 14 03:34:03 2003 | |
3 | +++ linux-2.6.0-test1/drivers/media/video/bttv-cards.c Tue Jul 22 09:01:24 2003 | |
4 | @@ -1630,12 +1630,8 @@ | |
5 | btv->type=card[btv->nr]; | |
6 | ||
7 | /* print which card config we are using */ | |
8 | - sprintf(btv->video_dev.name,"BT%d%s(%.23s)", | |
9 | - btv->id, | |
10 | - (btv->id==848 && btv->revision==0x12) ? "A" : "", | |
11 | - bttv_tvcards[btv->type].name); | |
12 | printk(KERN_INFO "bttv%d: using: %s [card=%d,%s]\n",btv->nr, | |
13 | - btv->video_dev.name,btv->type, | |
14 | + bttv_tvcards[btv->type].name, btv->type, | |
15 | (card[btv->nr] >= 0 && card[btv->nr] < bttv_num_tvcards) ? | |
16 | "insmod option" : "autodetected"); | |
17 | ||
18 | diff -Nur --exclude='*.orig' linux-2.6.0-test1.org/drivers/media/video/bttv-driver.c linux-2.6.0-test1/drivers/media/video/bttv-driver.c | |
19 | --- linux-2.6.0-test1.org/drivers/media/video/bttv-driver.c Mon Jul 14 03:36:43 2003 | |
20 | +++ linux-2.6.0-test1/drivers/media/video/bttv-driver.c Tue Jul 22 09:02:57 2003 | |
21 | @@ -33,6 +33,7 @@ | |
22 | #include <linux/sched.h> | |
23 | #include <linux/interrupt.h> | |
24 | #include <linux/kdev_t.h> | |
25 | +#include <linux/device.h> | |
26 | ||
27 | #include <asm/io.h> | |
28 | ||
29 | @@ -123,6 +124,17 @@ | |
30 | #endif | |
31 | ||
32 | /* ----------------------------------------------------------------------- */ | |
33 | +/* sysfs */ | |
34 | + | |
35 | +static ssize_t show_card(struct class_device *cd, char *buf) | |
36 | +{ | |
37 | + struct video_device *vfd = to_video_device(cd); | |
38 | + struct bttv *btv = dev_get_drvdata(vfd->dev); | |
39 | + return sprintf(buf, "%d\n", btv ? btv->type : UNSET); | |
40 | +} | |
41 | +static CLASS_DEVICE_ATTR(card, S_IRUGO, show_card, NULL); | |
42 | + | |
43 | +/* ----------------------------------------------------------------------- */ | |
44 | /* static data */ | |
45 | ||
46 | /* special timing tables from conexant... */ | |
47 | @@ -2007,7 +2019,7 @@ | |
48 | struct video_capability *cap = arg; | |
49 | ||
50 | memset(cap,0,sizeof(*cap)); | |
51 | - strcpy(cap->name,btv->video_dev.name); | |
52 | + strcpy(cap->name,btv->video_dev->name); | |
53 | if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { | |
54 | /* vbi */ | |
55 | cap->type = VID_TYPE_TUNER|VID_TYPE_TELETEXT; | |
56 | @@ -2309,7 +2321,7 @@ | |
57 | if (0 == v4l2) | |
58 | return -EINVAL; | |
59 | strcpy(cap->driver,"bttv"); | |
60 | - strlcpy(cap->card,btv->video_dev.name,sizeof(cap->card)); | |
61 | + strlcpy(cap->card,btv->video_dev->name,sizeof(cap->card)); | |
62 | sprintf(cap->bus_info,"PCI:%s",btv->dev->slot_name); | |
63 | cap->version = BTTV_VERSION_CODE; | |
64 | cap->capabilities = | |
65 | @@ -2683,12 +2695,12 @@ | |
66 | dprintk(KERN_DEBUG "bttv: open minor=%d\n",minor); | |
67 | ||
68 | for (i = 0; i < bttv_num; i++) { | |
69 | - if (bttvs[i].video_dev.minor == minor) { | |
70 | + if (bttvs[i].video_dev->minor == minor) { | |
71 | btv = &bttvs[i]; | |
72 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | |
73 | break; | |
74 | } | |
75 | - if (bttvs[i].vbi_dev.minor == minor) { | |
76 | + if (bttvs[i].vbi_dev->minor == minor) { | |
77 | btv = &bttvs[i]; | |
78 | type = V4L2_BUF_TYPE_VBI_CAPTURE; | |
79 | break; | |
80 | @@ -2786,8 +2798,8 @@ | |
81 | static struct video_device bttv_video_template = | |
82 | { | |
83 | .name = "UNSET", | |
84 | - type: VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY| | |
85 | - VID_TYPE_CLIPPING|VID_TYPE_SCALES, | |
86 | + .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY| | |
87 | + VID_TYPE_CLIPPING|VID_TYPE_SCALES, | |
88 | .hardware = VID_HARDWARE_BT848, | |
89 | .fops = &bttv_fops, | |
90 | .minor = -1, | |
91 | @@ -2815,7 +2827,7 @@ | |
92 | dprintk("bttv: open minor=%d\n",minor); | |
93 | ||
94 | for (i = 0; i < bttv_num; i++) { | |
95 | - if (bttvs[i].radio_dev.minor == minor) { | |
96 | + if (bttvs[i].radio_dev->minor == minor) { | |
97 | btv = &bttvs[i]; | |
98 | break; | |
99 | } | |
100 | @@ -2860,7 +2872,7 @@ | |
101 | struct video_capability *cap = arg; | |
102 | ||
103 | memset(cap,0,sizeof(*cap)); | |
104 | - strcpy(cap->name,btv->radio_dev.name); | |
105 | + strcpy(cap->name,btv->radio_dev->name); | |
106 | cap->type = VID_TYPE_TUNER; | |
107 | cap->channels = 1; | |
108 | cap->audios = 1; | |
109 | @@ -3239,30 +3251,83 @@ | |
110 | /* ----------------------------------------------------------------------- */ | |
111 | /* initialitation */ | |
112 | ||
113 | +static struct video_device *vdev_init(struct bttv *btv, | |
114 | + struct video_device *template, | |
115 | + char *type) | |
116 | +{ | |
117 | + struct video_device *vfd; | |
118 | + | |
119 | + vfd = video_device_alloc(); | |
120 | + if (NULL == vfd) | |
121 | + return NULL; | |
122 | + *vfd = *template; | |
123 | + vfd->minor = -1; | |
124 | + vfd->release = video_device_release; | |
125 | + vfd->dev = &btv->dev->dev; | |
126 | + snprintf(vfd->name, sizeof(vfd->name), "BT%d%s %s (%s)", | |
127 | + btv->id, (btv->id==848 && btv->revision==0x12) ? "A" : "", | |
128 | + type, bttv_tvcards[btv->type].name); | |
129 | + return vfd; | |
130 | +} | |
131 | + | |
132 | /* register video4linux devices */ | |
133 | static int __devinit bttv_register_video(struct bttv *btv) | |
134 | { | |
135 | - if(video_register_device(&btv->video_dev,VFL_TYPE_GRABBER,video_nr)<0) | |
136 | - return -1; | |
137 | + /* video */ | |
138 | + btv->video_dev = vdev_init(btv, &bttv_video_template, "video"); | |
139 | + if (NULL == btv->video_dev) | |
140 | + goto err; | |
141 | + if (video_register_device(btv->video_dev,VFL_TYPE_GRABBER,video_nr)<0) | |
142 | + goto err; | |
143 | printk(KERN_INFO "bttv%d: registered device video%d\n", | |
144 | - btv->nr,btv->video_dev.minor & 0x1f); | |
145 | + btv->nr,btv->video_dev->minor & 0x1f); | |
146 | + video_device_create_file(btv->video_dev, &class_device_attr_card); | |
147 | ||
148 | - if(video_register_device(&btv->vbi_dev,VFL_TYPE_VBI,vbi_nr)<0) { | |
149 | - video_unregister_device(&btv->video_dev); | |
150 | - return -1; | |
151 | - } | |
152 | + /* vbi */ | |
153 | + btv->vbi_dev = vdev_init(btv, &bttv_vbi_template, "vbi"); | |
154 | + if (NULL == btv->vbi_dev) | |
155 | + goto err; | |
156 | + if (video_register_device(btv->vbi_dev,VFL_TYPE_VBI,vbi_nr)<0) | |
157 | + goto err; | |
158 | printk(KERN_INFO "bttv%d: registered device vbi%d\n", | |
159 | - btv->nr,btv->vbi_dev.minor & 0x1f); | |
160 | + btv->nr,btv->vbi_dev->minor & 0x1f); | |
161 | ||
162 | if (!btv->has_radio) | |
163 | return 0; | |
164 | - if (video_register_device(&btv->radio_dev, VFL_TYPE_RADIO,radio_nr)<0) { | |
165 | - video_unregister_device(&btv->vbi_dev); | |
166 | - video_unregister_device(&btv->video_dev); | |
167 | - return -1; | |
168 | - } | |
169 | + /* radio */ | |
170 | + btv->radio_dev = vdev_init(btv, &radio_template, "radio"); | |
171 | + if (NULL == btv->radio_dev) | |
172 | + goto err; | |
173 | + if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO,radio_nr)<0) | |
174 | + goto err; | |
175 | printk(KERN_INFO "bttv%d: registered device radio%d\n", | |
176 | - btv->nr,btv->radio_dev.minor & 0x1f); | |
177 | + btv->nr,btv->radio_dev->minor & 0x1f); | |
178 | + | |
179 | + /* all done */ | |
180 | + return 0; | |
181 | + | |
182 | + err: | |
183 | + if (btv->video_dev) { | |
184 | + if (-1 != btv->video_dev->minor) | |
185 | + video_unregister_device(btv->video_dev); | |
186 | + else | |
187 | + video_device_release(btv->video_dev); | |
188 | + btv->video_dev = NULL; | |
189 | + } | |
190 | + if (btv->vbi_dev) { | |
191 | + if (-1 != btv->vbi_dev->minor) | |
192 | + video_unregister_device(btv->vbi_dev); | |
193 | + else | |
194 | + video_device_release(btv->vbi_dev); | |
195 | + btv->vbi_dev = NULL; | |
196 | + } | |
197 | + if (btv->radio_dev) { | |
198 | + if (-1 != btv->radio_dev->minor) | |
199 | + video_unregister_device(btv->radio_dev); | |
200 | + else | |
201 | + video_device_release(btv->radio_dev); | |
202 | + btv->radio_dev = NULL; | |
203 | + } | |
204 | return 0; | |
205 | } | |
206 | ||
207 | @@ -3310,15 +3375,6 @@ | |
208 | btv->i2c_rc = -1; | |
209 | btv->tuner_type = -1; | |
210 | ||
211 | - memcpy(&btv->video_dev, &bttv_video_template, sizeof(bttv_video_template)); | |
212 | - memcpy(&btv->radio_dev, &radio_template, sizeof(radio_template)); | |
213 | - memcpy(&btv->vbi_dev, &bttv_vbi_template, sizeof(bttv_vbi_template)); | |
214 | - btv->video_dev.minor = -1; | |
215 | - btv->video_dev.priv = btv; | |
216 | - btv->radio_dev.minor = -1; | |
217 | - btv->radio_dev.priv = btv; | |
218 | - btv->vbi_dev.minor = -1; | |
219 | - btv->vbi_dev.priv = btv; | |
220 | btv->has_radio=radio[btv->nr]; | |
221 | ||
222 | /* pci stuff (init, get irq/mmip, ... */ | |
223 | @@ -3477,12 +3533,18 @@ | |
224 | i2c_bit_del_bus(&btv->i2c_adap); | |
225 | ||
226 | /* unregister video4linux */ | |
227 | - if (btv->video_dev.minor!=-1) | |
228 | - video_unregister_device(&btv->video_dev); | |
229 | - if (btv->radio_dev.minor!=-1) | |
230 | - video_unregister_device(&btv->radio_dev); | |
231 | - if (btv->vbi_dev.minor!=-1) | |
232 | - video_unregister_device(&btv->vbi_dev); | |
233 | + if (btv->video_dev) { | |
234 | + video_unregister_device(btv->video_dev); | |
235 | + btv->video_dev = NULL; | |
236 | + } | |
237 | + if (btv->radio_dev) { | |
238 | + video_unregister_device(btv->radio_dev); | |
239 | + btv->radio_dev = NULL; | |
240 | + } | |
241 | + if (btv->vbi_dev) { | |
242 | + video_unregister_device(btv->vbi_dev); | |
243 | + btv->vbi_dev = NULL; | |
244 | + } | |
245 | ||
246 | /* free allocated memory */ | |
247 | bttv_riscmem_free(btv->dev,&btv->main); | |
248 | diff -Nur --exclude='*.orig' linux-2.6.0-test1.org/drivers/media/video/bttvp.h linux-2.6.0-test1/drivers/media/video/bttvp.h | |
249 | --- linux-2.6.0-test1.org/drivers/media/video/bttvp.h Mon Jul 14 03:32:44 2003 | |
250 | +++ linux-2.6.0-test1/drivers/media/video/bttvp.h Tue Jul 22 08:57:59 2003 | |
251 | @@ -280,9 +280,9 @@ | |
252 | int i2c_state, i2c_rc; | |
253 | ||
254 | /* video4linux (1) */ | |
255 | - struct video_device video_dev; | |
256 | - struct video_device radio_dev; | |
257 | - struct video_device vbi_dev; | |
258 | + struct video_device *video_dev; | |
259 | + struct video_device *radio_dev; | |
260 | + struct video_device *vbi_dev; | |
261 | ||
262 | /* locking */ | |
263 | spinlock_t s_lock; | |
264 | diff -Nur --exclude='*.orig' linux-2.6.0-test1.org/drivers/media/video/videodev.c linux-2.6.0-test1/drivers/media/video/videodev.c | |
265 | --- linux-2.6.0-test1.org/drivers/media/video/videodev.c Mon Jul 14 03:30:42 2003 | |
266 | +++ linux-2.6.0-test1/drivers/media/video/videodev.c Tue Jul 22 08:57:54 2003 | |
267 | @@ -15,7 +15,6 @@ | |
268 | * - Added procfs support | |
269 | */ | |
270 | ||
271 | -#include <linux/config.h> | |
272 | #include <linux/version.h> | |
273 | #include <linux/module.h> | |
274 | #include <linux/types.h> | |
275 | @@ -28,6 +27,7 @@ | |
276 | #include <linux/init.h> | |
277 | #include <linux/kmod.h> | |
278 | #include <linux/slab.h> | |
279 | +#include <linux/types.h> | |
280 | #include <linux/devfs_fs_kernel.h> | |
281 | #include <asm/uaccess.h> | |
282 | #include <asm/system.h> | |
283 | @@ -35,33 +35,67 @@ | |
284 | ||
285 | #include <linux/videodev.h> | |
286 | ||
287 | -#define VIDEO_NUM_DEVICES 256 | |
288 | +#define VIDEO_NUM_DEVICES 256 | |
289 | +#define VIDEO_NAME "video4linux" | |
290 | ||
291 | /* | |
292 | - * Active devices | |
293 | + * sysfs stuff | |
294 | */ | |
295 | - | |
296 | -static struct video_device *video_device[VIDEO_NUM_DEVICES]; | |
297 | -static DECLARE_MUTEX(videodev_lock); | |
298 | ||
299 | +static ssize_t show_name(struct class_device *cd, char *buf) | |
300 | +{ | |
301 | + struct video_device *vfd = to_video_device(cd); | |
302 | + return sprintf(buf,"%.*s\n",(int)sizeof(vfd->name),vfd->name); | |
303 | +} | |
304 | + | |
305 | +static ssize_t show_dev(struct class_device *cd, char *buf) | |
306 | +{ | |
307 | + struct video_device *vfd = to_video_device(cd); | |
308 | + dev_t dev = MKDEV(VIDEO_MAJOR, vfd->minor); | |
309 | + return sprintf(buf,"%04x\n",(int)dev); | |
310 | +} | |
311 | ||
312 | -#ifdef CONFIG_VIDEO_PROC_FS | |
313 | +static CLASS_DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | |
314 | +static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL); | |
315 | ||
316 | -#include <linux/proc_fs.h> | |
317 | +struct video_device *video_device_alloc(void) | |
318 | +{ | |
319 | + struct video_device *vfd; | |
320 | ||
321 | -struct videodev_proc_data { | |
322 | - struct list_head proc_list; | |
323 | - char name[16]; | |
324 | - struct video_device *vdev; | |
325 | - struct proc_dir_entry *proc_entry; | |
326 | -}; | |
327 | + vfd = kmalloc(sizeof(*vfd),GFP_KERNEL); | |
328 | + if (NULL == vfd) | |
329 | + return NULL; | |
330 | + memset(vfd,0,sizeof(*vfd)); | |
331 | + return vfd; | |
332 | +} | |
333 | + | |
334 | +void video_device_release(struct video_device *vfd) | |
335 | +{ | |
336 | + kfree(vfd); | |
337 | +} | |
338 | + | |
339 | +static void video_release(struct class_device *cd) | |
340 | +{ | |
341 | + struct video_device *vfd = container_of(cd, struct video_device, class_dev); | |
342 | ||
343 | -static struct proc_dir_entry *video_dev_proc_entry = NULL; | |
344 | -struct proc_dir_entry *video_proc_entry = NULL; | |
345 | -EXPORT_SYMBOL(video_proc_entry); | |
346 | -LIST_HEAD(videodev_proc_list); | |
347 | +#if 1 /* needed until all drivers are fixed */ | |
348 | + if (!vfd->release) | |
349 | + return; | |
350 | +#endif | |
351 | + vfd->release(vfd); | |
352 | +} | |
353 | ||
354 | -#endif /* CONFIG_VIDEO_PROC_FS */ | |
355 | +static struct class video_class = { | |
356 | + .name = VIDEO_NAME, | |
357 | + .release = video_release, | |
358 | +}; | |
359 | + | |
360 | +/* | |
361 | + * Active devices | |
362 | + */ | |
363 | + | |
364 | +static struct video_device *video_device[VIDEO_NUM_DEVICES]; | |
365 | +static DECLARE_MUTEX(videodev_lock); | |
366 | ||
367 | struct video_device* video_devdata(struct file *file) | |
368 | { | |
369 | @@ -192,156 +226,6 @@ | |
370 | return 0; | |
371 | } | |
372 | ||
373 | -/* | |
374 | - * /proc support | |
375 | - */ | |
376 | - | |
377 | -#ifdef CONFIG_VIDEO_PROC_FS | |
378 | - | |
379 | -/* Hmm... i'd like to see video_capability information here, but | |
380 | - * how can I access it (without changing the other drivers? -claudio | |
381 | - */ | |
382 | -static int videodev_proc_read(char *page, char **start, off_t off, | |
383 | - int count, int *eof, void *data) | |
384 | -{ | |
385 | - char *out = page; | |
386 | - struct video_device *vfd = data; | |
387 | - struct videodev_proc_data *d; | |
388 | - struct list_head *tmp; | |
389 | - int len; | |
390 | - char c = ' '; | |
391 | - | |
392 | - list_for_each (tmp, &videodev_proc_list) { | |
393 | - d = list_entry(tmp, struct videodev_proc_data, proc_list); | |
394 | - if (vfd == d->vdev) | |
395 | - break; | |
396 | - } | |
397 | - | |
398 | - /* Sanity check */ | |
399 | - if (tmp == &videodev_proc_list) | |
400 | - goto skip; | |
401 | - | |
402 | -#define PRINT_VID_TYPE(x) do { if (vfd->type & x) \ | |
403 | - out += sprintf (out, "%c%s", c, #x); c='|';} while (0) | |
404 | - | |
405 | - out += sprintf (out, "name : %s\n", vfd->name); | |
406 | - out += sprintf (out, "type :"); | |
407 | - PRINT_VID_TYPE(VID_TYPE_CAPTURE); | |
408 | - PRINT_VID_TYPE(VID_TYPE_TUNER); | |
409 | - PRINT_VID_TYPE(VID_TYPE_TELETEXT); | |
410 | - PRINT_VID_TYPE(VID_TYPE_OVERLAY); | |
411 | - PRINT_VID_TYPE(VID_TYPE_CHROMAKEY); | |
412 | - PRINT_VID_TYPE(VID_TYPE_CLIPPING); | |
413 | - PRINT_VID_TYPE(VID_TYPE_FRAMERAM); | |
414 | - PRINT_VID_TYPE(VID_TYPE_SCALES); | |
415 | - PRINT_VID_TYPE(VID_TYPE_MONOCHROME); | |
416 | - PRINT_VID_TYPE(VID_TYPE_SUBCAPTURE); | |
417 | - PRINT_VID_TYPE(VID_TYPE_MPEG_DECODER); | |
418 | - PRINT_VID_TYPE(VID_TYPE_MPEG_ENCODER); | |
419 | - PRINT_VID_TYPE(VID_TYPE_MJPEG_DECODER); | |
420 | - PRINT_VID_TYPE(VID_TYPE_MJPEG_ENCODER); | |
421 | - out += sprintf (out, "\n"); | |
422 | - out += sprintf (out, "hardware : 0x%x\n", vfd->hardware); | |
423 | -#if 0 | |
424 | - out += sprintf (out, "channels : %d\n", d->vcap.channels); | |
425 | - out += sprintf (out, "audios : %d\n", d->vcap.audios); | |
426 | - out += sprintf (out, "maxwidth : %d\n", d->vcap.maxwidth); | |
427 | - out += sprintf (out, "maxheight : %d\n", d->vcap.maxheight); | |
428 | - out += sprintf (out, "minwidth : %d\n", d->vcap.minwidth); | |
429 | - out += sprintf (out, "minheight : %d\n", d->vcap.minheight); | |
430 | -#endif | |
431 | - | |
432 | -skip: | |
433 | - len = out - page; | |
434 | - len -= off; | |
435 | - if (len < count) { | |
436 | - *eof = 1; | |
437 | - if (len <= 0) | |
438 | - return 0; | |
439 | - } else | |
440 | - len = count; | |
441 | - | |
442 | - *start = page + off; | |
443 | - | |
444 | - return len; | |
445 | -} | |
446 | - | |
447 | -static void videodev_proc_create(void) | |
448 | -{ | |
449 | - video_proc_entry = create_proc_entry("video", S_IFDIR, &proc_root); | |
450 | - | |
451 | - if (video_proc_entry == NULL) { | |
452 | - printk("video_dev: unable to initialise /proc/video\n"); | |
453 | - return; | |
454 | - } | |
455 | - | |
456 | - video_proc_entry->owner = THIS_MODULE; | |
457 | - video_dev_proc_entry = create_proc_entry("dev", S_IFDIR, video_proc_entry); | |
458 | - | |
459 | - if (video_dev_proc_entry == NULL) { | |
460 | - printk("video_dev: unable to initialise /proc/video/dev\n"); | |
461 | - return; | |
462 | - } | |
463 | - | |
464 | - video_dev_proc_entry->owner = THIS_MODULE; | |
465 | -} | |
466 | - | |
467 | -static void __exit videodev_proc_destroy(void) | |
468 | -{ | |
469 | - if (video_dev_proc_entry != NULL) | |
470 | - remove_proc_entry("dev", video_proc_entry); | |
471 | - | |
472 | - if (video_proc_entry != NULL) | |
473 | - remove_proc_entry("video", &proc_root); | |
474 | -} | |
475 | - | |
476 | -static void videodev_proc_create_dev (struct video_device *vfd, char *name) | |
477 | -{ | |
478 | - struct videodev_proc_data *d; | |
479 | - struct proc_dir_entry *p; | |
480 | - | |
481 | - if (video_dev_proc_entry == NULL) | |
482 | - return; | |
483 | - | |
484 | - d = kmalloc (sizeof (struct videodev_proc_data), GFP_KERNEL); | |
485 | - if (!d) | |
486 | - return; | |
487 | - | |
488 | - p = create_proc_entry(name, S_IFREG|S_IRUGO|S_IWUSR, video_dev_proc_entry); | |
489 | - if (!p) { | |
490 | - kfree(d); | |
491 | - return; | |
492 | - } | |
493 | - p->data = vfd; | |
494 | - p->read_proc = videodev_proc_read; | |
495 | - | |
496 | - d->proc_entry = p; | |
497 | - d->vdev = vfd; | |
498 | - strcpy (d->name, name); | |
499 | - | |
500 | - /* How can I get capability information ? */ | |
501 | - | |
502 | - list_add (&d->proc_list, &videodev_proc_list); | |
503 | -} | |
504 | - | |
505 | -static void videodev_proc_destroy_dev (struct video_device *vfd) | |
506 | -{ | |
507 | - struct list_head *tmp; | |
508 | - struct videodev_proc_data *d; | |
509 | - | |
510 | - list_for_each (tmp, &videodev_proc_list) { | |
511 | - d = list_entry(tmp, struct videodev_proc_data, proc_list); | |
512 | - if (vfd == d->vdev) { | |
513 | - remove_proc_entry(d->name, video_dev_proc_entry); | |
514 | - list_del (&d->proc_list); | |
515 | - kfree(d); | |
516 | - break; | |
517 | - } | |
518 | - } | |
519 | -} | |
520 | - | |
521 | -#endif /* CONFIG_VIDEO_PROC_FS */ | |
522 | - | |
523 | extern struct file_operations video_fops; | |
524 | ||
525 | /** | |
526 | @@ -429,15 +313,23 @@ | |
527 | devfs_mk_cdev(MKDEV(VIDEO_MAJOR, vfd->minor), | |
528 | S_IFCHR | S_IRUSR | S_IWUSR, vfd->devfs_name); | |
529 | init_MUTEX(&vfd->lock); | |
530 | - | |
531 | -#ifdef CONFIG_VIDEO_PROC_FS | |
532 | -{ | |
533 | - char name[16]; | |
534 | - sprintf(name, "%s%d", name_base, i - base); | |
535 | - videodev_proc_create_dev(vfd, name); | |
536 | -} | |
537 | -#endif | |
538 | ||
539 | + /* sysfs class */ | |
540 | + memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev)); | |
541 | + if (vfd->dev) | |
542 | + vfd->class_dev.dev = vfd->dev; | |
543 | + vfd->class_dev.class = &video_class; | |
544 | + strlcpy(vfd->class_dev.class_id, vfd->devfs_name + 4, BUS_ID_SIZE); | |
545 | + class_device_register(&vfd->class_dev); | |
546 | + video_device_create_file(vfd, &class_device_attr_name); | |
547 | + video_device_create_file(vfd, &class_device_attr_dev); | |
548 | + | |
549 | +#if 1 /* needed until all drivers are fixed */ | |
550 | + if (!vfd->release) | |
551 | + printk(KERN_WARNING "videodev: \"%s\" has no release callback. " | |
552 | + "Please fix your driver for proper sysfs support, see " | |
553 | + "http://lwn.net/Articles/36850/\n", vfd->name); | |
554 | +#endif | |
555 | return 0; | |
556 | } | |
557 | ||
558 | @@ -455,10 +347,7 @@ | |
559 | if(video_device[vfd->minor]!=vfd) | |
560 | panic("videodev: bad unregister"); | |
561 | ||
562 | -#ifdef CONFIG_VIDEO_PROC_FS | |
563 | - videodev_proc_destroy_dev (vfd); | |
564 | -#endif | |
565 | - | |
566 | + class_device_unregister(&vfd->class_dev); | |
567 | devfs_remove(vfd->devfs_name); | |
568 | video_device[vfd->minor]=NULL; | |
569 | up(&videodev_lock); | |
570 | @@ -479,24 +368,18 @@ | |
571 | static int __init videodev_init(void) | |
572 | { | |
573 | printk(KERN_INFO "Linux video capture interface: v1.00\n"); | |
574 | - if (register_chrdev(VIDEO_MAJOR,"video_capture", &video_fops)) { | |
575 | + if (register_chrdev(VIDEO_MAJOR,VIDEO_NAME, &video_fops)) { | |
576 | printk("video_dev: unable to get major %d\n", VIDEO_MAJOR); | |
577 | return -EIO; | |
578 | } | |
579 | - | |
580 | -#ifdef CONFIG_VIDEO_PROC_FS | |
581 | - videodev_proc_create (); | |
582 | -#endif | |
583 | - | |
584 | + class_register(&video_class); | |
585 | return 0; | |
586 | } | |
587 | ||
588 | static void __exit videodev_exit(void) | |
589 | { | |
590 | -#ifdef CONFIG_VIDEO_PROC_FS | |
591 | - videodev_proc_destroy (); | |
592 | -#endif | |
593 | - unregister_chrdev(VIDEO_MAJOR, "video_capture"); | |
594 | + class_unregister(&video_class); | |
595 | + unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME); | |
596 | } | |
597 | ||
598 | module_init(videodev_init) | |
599 | @@ -508,6 +391,8 @@ | |
600 | EXPORT_SYMBOL(video_usercopy); | |
601 | EXPORT_SYMBOL(video_exclusive_open); | |
602 | EXPORT_SYMBOL(video_exclusive_release); | |
603 | +EXPORT_SYMBOL(video_device_alloc); | |
604 | +EXPORT_SYMBOL(video_device_release); | |
605 | ||
606 | MODULE_AUTHOR("Alan Cox"); | |
607 | MODULE_DESCRIPTION("Device registrar for Video4Linux drivers"); | |
608 | diff -Nur --exclude='*.orig' linux-2.6.0-test1.org/include/linux/videodev.h linux-2.6.0-test1/include/linux/videodev.h | |
609 | --- linux-2.6.0-test1.org/include/linux/videodev.h Mon Jul 14 03:39:37 2003 | |
610 | +++ linux-2.6.0-test1/include/linux/videodev.h Tue Jul 22 08:57:54 2003 | |
611 | @@ -3,18 +3,10 @@ | |
612 | ||
613 | #include <linux/types.h> | |
614 | #include <linux/version.h> | |
615 | +#include <linux/device.h> | |
616 | ||
617 | -#if 1 | |
618 | -/* | |
619 | - * v4l2 is still work-in-progress, integration planed for 2.5.x | |
620 | - * documentation: http://bytesex.org/v4l/ | |
621 | - * patches available from: http://bytesex.org/patches/ | |
622 | - */ | |
623 | -# define HAVE_V4L2 1 | |
624 | -# include <linux/videodev2.h> | |
625 | -#else | |
626 | -# undef HAVE_V4L2 | |
627 | -#endif | |
628 | +#define HAVE_V4L2 1 | |
629 | +#include <linux/videodev2.h> | |
630 | ||
631 | #ifdef __KERNEL__ | |
632 | ||
633 | @@ -23,35 +15,70 @@ | |
634 | ||
635 | struct video_device | |
636 | { | |
637 | - struct module *owner; | |
638 | + /* device info */ | |
639 | + struct device *dev; | |
640 | char name[32]; | |
641 | int type; /* v4l1 */ | |
642 | int type2; /* v4l2 */ | |
643 | int hardware; | |
644 | int minor; | |
645 | ||
646 | - /* new interface -- we will use file_operations directly | |
647 | - * like soundcore does. */ | |
648 | + /* device ops + callbacks */ | |
649 | struct file_operations *fops; | |
650 | - void *priv; /* Used to be 'private' but that upsets C++ */ | |
651 | + void (*release)(struct video_device *vfd); | |
652 | ||
653 | - /* for videodev.c intenal usage -- don't touch */ | |
654 | - int users; | |
655 | - struct semaphore lock; | |
656 | - char devfs_name[64]; /* devfs */ | |
657 | +#if 1 /* to be removed in 2.7.x */ | |
658 | + /* obsolete -- fops->owner is used instead */ | |
659 | + struct module *owner; | |
660 | + /* dev->driver_data will be used instead some day. | |
661 | + * Use the video_{get|set}_drvdata() helper functions, | |
662 | + * so the switch over will be transparent for you. | |
663 | + * Or use {pci|usb|dev}_{get|set}_drvdata() directly. */ | |
664 | + void *priv; | |
665 | +#endif | |
666 | + | |
667 | + /* for videodev.c intenal usage -- please don't touch */ | |
668 | + int users; /* video_exclusive_{open|close} ... */ | |
669 | + struct semaphore lock; /* ... helper function uses these */ | |
670 | + char devfs_name[64]; /* devfs */ | |
671 | + struct class_device class_dev; /* sysfs */ | |
672 | }; | |
673 | ||
674 | #define VIDEO_MAJOR 81 | |
675 | -extern int video_register_device(struct video_device *, int type, int nr); | |
676 | ||
677 | #define VFL_TYPE_GRABBER 0 | |
678 | #define VFL_TYPE_VBI 1 | |
679 | #define VFL_TYPE_RADIO 2 | |
680 | #define VFL_TYPE_VTX 3 | |
681 | ||
682 | +extern int video_register_device(struct video_device *, int type, int nr); | |
683 | extern void video_unregister_device(struct video_device *); | |
684 | extern struct video_device* video_devdata(struct file*); | |
685 | ||
686 | +#define to_video_device(cd) container_of(cd, struct video_device, class_dev) | |
687 | +static inline void | |
688 | +video_device_create_file(struct video_device *vfd, | |
689 | + struct class_device_attribute *attr) | |
690 | +{ | |
691 | + class_device_create_file(&vfd->class_dev, attr); | |
692 | +} | |
693 | + | |
694 | +/* helper functions to alloc / release struct video_device, the | |
695 | + later can be used for video_device->release() */ | |
696 | +struct video_device *video_device_alloc(void); | |
697 | +void video_device_release(struct video_device *vfd); | |
698 | + | |
699 | +/* helper functions to access driver private data. */ | |
700 | +static inline void *video_get_drvdata(struct video_device *dev) | |
701 | +{ | |
702 | + return dev->priv; | |
703 | +} | |
704 | + | |
705 | +static inline void video_set_drvdata(struct video_device *dev, void *data) | |
706 | +{ | |
707 | + dev->priv = data; | |
708 | +} | |
709 | + | |
710 | extern int video_exclusive_open(struct inode *inode, struct file *file); | |
711 | extern int video_exclusive_release(struct inode *inode, struct file *file); | |
712 | extern int video_usercopy(struct inode *inode, struct file *file, |