diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2009-02-14 11:23:12 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-03-30 11:42:50 -0400 |
commit | 5ab6c9af375e27c48bd2e86f4d9f6d68c9ab98fd (patch) | |
tree | bc6dae0d02ee6169149a67f93a089b091a6ce06c /drivers/media/video/vivi.c | |
parent | b01676005446ad51a32bb00577647c7aae7d2624 (diff) |
V4L/DVB (10645): vivi: introduce v4l2_device and do several cleanups
- add v4l2_device
- remove BKL
- make the debug parameter settable on the fly
- set bus_info in querycap
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/vivi.c')
-rw-r--r-- | drivers/media/video/vivi.c | 258 |
1 files changed, 130 insertions, 128 deletions
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 0f25d686ca20..625e9662c7ad 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c | |||
@@ -33,12 +33,13 @@ | |||
33 | #include <linux/videodev.h> | 33 | #include <linux/videodev.h> |
34 | #endif | 34 | #endif |
35 | #include <linux/interrupt.h> | 35 | #include <linux/interrupt.h> |
36 | #include <media/videobuf-vmalloc.h> | ||
37 | #include <media/v4l2-common.h> | ||
38 | #include <media/v4l2-ioctl.h> | ||
39 | #include <linux/kthread.h> | 36 | #include <linux/kthread.h> |
40 | #include <linux/highmem.h> | 37 | #include <linux/highmem.h> |
41 | #include <linux/freezer.h> | 38 | #include <linux/freezer.h> |
39 | #include <media/videobuf-vmalloc.h> | ||
40 | #include <media/v4l2-device.h> | ||
41 | #include <media/v4l2-ioctl.h> | ||
42 | #include "font.h" | ||
42 | 43 | ||
43 | #define VIVI_MODULE_NAME "vivi" | 44 | #define VIVI_MODULE_NAME "vivi" |
44 | 45 | ||
@@ -47,18 +48,32 @@ | |||
47 | #define WAKE_DENOMINATOR 1001 | 48 | #define WAKE_DENOMINATOR 1001 |
48 | #define BUFFER_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */ | 49 | #define BUFFER_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */ |
49 | 50 | ||
50 | #include "font.h" | ||
51 | |||
52 | #define VIVI_MAJOR_VERSION 0 | 51 | #define VIVI_MAJOR_VERSION 0 |
53 | #define VIVI_MINOR_VERSION 5 | 52 | #define VIVI_MINOR_VERSION 6 |
54 | #define VIVI_RELEASE 0 | 53 | #define VIVI_RELEASE 0 |
55 | #define VIVI_VERSION \ | 54 | #define VIVI_VERSION \ |
56 | KERNEL_VERSION(VIVI_MAJOR_VERSION, VIVI_MINOR_VERSION, VIVI_RELEASE) | 55 | KERNEL_VERSION(VIVI_MAJOR_VERSION, VIVI_MINOR_VERSION, VIVI_RELEASE) |
57 | 56 | ||
58 | /* Declare static vars that will be used as parameters */ | 57 | MODULE_DESCRIPTION("Video Technology Magazine Virtual Video Capture Board"); |
59 | static unsigned int vid_limit = 16; /* Video memory limit, in Mb */ | 58 | MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol"); |
60 | static int video_nr = -1; /* /dev/videoN, -1 for autodetect */ | 59 | MODULE_LICENSE("Dual BSD/GPL"); |
61 | static int n_devs = 1; /* Number of virtual devices */ | 60 | |
61 | static unsigned video_nr = -1; | ||
62 | module_param(video_nr, uint, 0644); | ||
63 | MODULE_PARM_DESC(video_nr, "videoX start number, -1 is autodetect"); | ||
64 | |||
65 | static unsigned n_devs = 1; | ||
66 | module_param(n_devs, uint, 0644); | ||
67 | MODULE_PARM_DESC(n_devs, "number of video devices to create"); | ||
68 | |||
69 | static unsigned debug; | ||
70 | module_param(debug, uint, 0644); | ||
71 | MODULE_PARM_DESC(debug, "activates debug info"); | ||
72 | |||
73 | static unsigned int vid_limit = 16; | ||
74 | module_param(vid_limit, uint, 0644); | ||
75 | MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes"); | ||
76 | |||
62 | 77 | ||
63 | /* supported controls */ | 78 | /* supported controls */ |
64 | static struct v4l2_queryctrl vivi_qctrl[] = { | 79 | static struct v4l2_queryctrl vivi_qctrl[] = { |
@@ -112,11 +127,8 @@ static struct v4l2_queryctrl vivi_qctrl[] = { | |||
112 | 127 | ||
113 | static int qctl_regs[ARRAY_SIZE(vivi_qctrl)]; | 128 | static int qctl_regs[ARRAY_SIZE(vivi_qctrl)]; |
114 | 129 | ||
115 | #define dprintk(dev, level, fmt, arg...) \ | 130 | #define dprintk(dev, level, fmt, arg...) \ |
116 | do { \ | 131 | v4l2_dbg(level, debug, &dev->v4l2_dev, fmt, ## arg) |
117 | if (dev->vfd->debug >= (level)) \ | ||
118 | printk(KERN_DEBUG "vivi: " fmt , ## arg); \ | ||
119 | } while (0) | ||
120 | 132 | ||
121 | /* ------------------------------------------------------------------ | 133 | /* ------------------------------------------------------------------ |
122 | Basic structures | 134 | Basic structures |
@@ -206,6 +218,7 @@ static LIST_HEAD(vivi_devlist); | |||
206 | 218 | ||
207 | struct vivi_dev { | 219 | struct vivi_dev { |
208 | struct list_head vivi_devlist; | 220 | struct list_head vivi_devlist; |
221 | struct v4l2_device v4l2_dev; | ||
209 | 222 | ||
210 | spinlock_t slock; | 223 | spinlock_t slock; |
211 | struct mutex mutex; | 224 | struct mutex mutex; |
@@ -656,7 +669,7 @@ static int vivi_start_thread(struct vivi_fh *fh) | |||
656 | dma_q->kthread = kthread_run(vivi_thread, fh, "vivi"); | 669 | dma_q->kthread = kthread_run(vivi_thread, fh, "vivi"); |
657 | 670 | ||
658 | if (IS_ERR(dma_q->kthread)) { | 671 | if (IS_ERR(dma_q->kthread)) { |
659 | printk(KERN_ERR "vivi: kernel_thread() failed\n"); | 672 | v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n"); |
660 | return PTR_ERR(dma_q->kthread); | 673 | return PTR_ERR(dma_q->kthread); |
661 | } | 674 | } |
662 | /* Wakes thread */ | 675 | /* Wakes thread */ |
@@ -799,8 +812,12 @@ static struct videobuf_queue_ops vivi_video_qops = { | |||
799 | static int vidioc_querycap(struct file *file, void *priv, | 812 | static int vidioc_querycap(struct file *file, void *priv, |
800 | struct v4l2_capability *cap) | 813 | struct v4l2_capability *cap) |
801 | { | 814 | { |
815 | struct vivi_fh *fh = priv; | ||
816 | struct vivi_dev *dev = fh->dev; | ||
817 | |||
802 | strcpy(cap->driver, "vivi"); | 818 | strcpy(cap->driver, "vivi"); |
803 | strcpy(cap->card, "vivi"); | 819 | strcpy(cap->card, "vivi"); |
820 | strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info)); | ||
804 | cap->version = VIVI_VERSION; | 821 | cap->version = VIVI_VERSION; |
805 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | | 822 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | |
806 | V4L2_CAP_STREAMING | | 823 | V4L2_CAP_STREAMING | |
@@ -1124,32 +1141,21 @@ static int vidioc_s_ctrl(struct file *file, void *priv, | |||
1124 | 1141 | ||
1125 | static int vivi_open(struct file *file) | 1142 | static int vivi_open(struct file *file) |
1126 | { | 1143 | { |
1127 | int minor = video_devdata(file)->minor; | 1144 | struct vivi_dev *dev = video_drvdata(file); |
1128 | struct vivi_dev *dev; | ||
1129 | struct vivi_fh *fh = NULL; | 1145 | struct vivi_fh *fh = NULL; |
1130 | int i; | 1146 | int i; |
1131 | int retval = 0; | 1147 | int retval = 0; |
1132 | 1148 | ||
1133 | printk(KERN_DEBUG "vivi: open called (minor=%d)\n", minor); | ||
1134 | |||
1135 | lock_kernel(); | ||
1136 | list_for_each_entry(dev, &vivi_devlist, vivi_devlist) | ||
1137 | if (dev->vfd->minor == minor) | ||
1138 | goto found; | ||
1139 | unlock_kernel(); | ||
1140 | return -ENODEV; | ||
1141 | |||
1142 | found: | ||
1143 | mutex_lock(&dev->mutex); | 1149 | mutex_lock(&dev->mutex); |
1144 | dev->users++; | 1150 | dev->users++; |
1145 | 1151 | ||
1146 | if (dev->users > 1) { | 1152 | if (dev->users > 1) { |
1147 | dev->users--; | 1153 | dev->users--; |
1148 | retval = -EBUSY; | 1154 | mutex_unlock(&dev->mutex); |
1149 | goto unlock; | 1155 | return -EBUSY; |
1150 | } | 1156 | } |
1151 | 1157 | ||
1152 | dprintk(dev, 1, "open minor=%d type=%s users=%d\n", minor, | 1158 | dprintk(dev, 1, "open /dev/video%d type=%s users=%d\n", dev->vfd->num, |
1153 | v4l2_type_names[V4L2_BUF_TYPE_VIDEO_CAPTURE], dev->users); | 1159 | v4l2_type_names[V4L2_BUF_TYPE_VIDEO_CAPTURE], dev->users); |
1154 | 1160 | ||
1155 | /* allocate + initialize per filehandle data */ | 1161 | /* allocate + initialize per filehandle data */ |
@@ -1157,14 +1163,11 @@ found: | |||
1157 | if (NULL == fh) { | 1163 | if (NULL == fh) { |
1158 | dev->users--; | 1164 | dev->users--; |
1159 | retval = -ENOMEM; | 1165 | retval = -ENOMEM; |
1160 | goto unlock; | ||
1161 | } | 1166 | } |
1162 | unlock: | ||
1163 | mutex_unlock(&dev->mutex); | 1167 | mutex_unlock(&dev->mutex); |
1164 | if (retval) { | 1168 | |
1165 | unlock_kernel(); | 1169 | if (retval) |
1166 | return retval; | 1170 | return retval; |
1167 | } | ||
1168 | 1171 | ||
1169 | file->private_data = fh; | 1172 | file->private_data = fh; |
1170 | fh->dev = dev; | 1173 | fh->dev = dev; |
@@ -1193,7 +1196,6 @@ unlock: | |||
1193 | sizeof(struct vivi_buffer), fh); | 1196 | sizeof(struct vivi_buffer), fh); |
1194 | 1197 | ||
1195 | vivi_start_thread(fh); | 1198 | vivi_start_thread(fh); |
1196 | unlock_kernel(); | ||
1197 | 1199 | ||
1198 | return 0; | 1200 | return 0; |
1199 | } | 1201 | } |
@@ -1249,32 +1251,6 @@ static int vivi_close(struct file *file) | |||
1249 | return 0; | 1251 | return 0; |
1250 | } | 1252 | } |
1251 | 1253 | ||
1252 | static int vivi_release(void) | ||
1253 | { | ||
1254 | struct vivi_dev *dev; | ||
1255 | struct list_head *list; | ||
1256 | |||
1257 | while (!list_empty(&vivi_devlist)) { | ||
1258 | list = vivi_devlist.next; | ||
1259 | list_del(list); | ||
1260 | dev = list_entry(list, struct vivi_dev, vivi_devlist); | ||
1261 | |||
1262 | if (-1 != dev->vfd->minor) { | ||
1263 | printk(KERN_INFO "%s: unregistering /dev/video%d\n", | ||
1264 | VIVI_MODULE_NAME, dev->vfd->num); | ||
1265 | video_unregister_device(dev->vfd); | ||
1266 | } else { | ||
1267 | printk(KERN_INFO "%s: releasing /dev/video%d\n", | ||
1268 | VIVI_MODULE_NAME, dev->vfd->num); | ||
1269 | video_device_release(dev->vfd); | ||
1270 | } | ||
1271 | |||
1272 | kfree(dev); | ||
1273 | } | ||
1274 | |||
1275 | return 0; | ||
1276 | } | ||
1277 | |||
1278 | static int vivi_mmap(struct file *file, struct vm_area_struct *vma) | 1254 | static int vivi_mmap(struct file *file, struct vm_area_struct *vma) |
1279 | { | 1255 | { |
1280 | struct vivi_fh *fh = file->private_data; | 1256 | struct vivi_fh *fh = file->private_data; |
@@ -1337,84 +1313,126 @@ static struct video_device vivi_template = { | |||
1337 | .tvnorms = V4L2_STD_525_60, | 1313 | .tvnorms = V4L2_STD_525_60, |
1338 | .current_norm = V4L2_STD_NTSC_M, | 1314 | .current_norm = V4L2_STD_NTSC_M, |
1339 | }; | 1315 | }; |
1316 | |||
1340 | /* ----------------------------------------------------------------- | 1317 | /* ----------------------------------------------------------------- |
1341 | Initialization and module stuff | 1318 | Initialization and module stuff |
1342 | ------------------------------------------------------------------*/ | 1319 | ------------------------------------------------------------------*/ |
1343 | 1320 | ||
1344 | /* This routine allocates from 1 to n_devs virtual drivers. | 1321 | static int vivi_release(void) |
1322 | { | ||
1323 | struct vivi_dev *dev; | ||
1324 | struct list_head *list; | ||
1345 | 1325 | ||
1346 | The real maximum number of virtual drivers will depend on how many drivers | 1326 | while (!list_empty(&vivi_devlist)) { |
1347 | will succeed. This is limited to the maximum number of devices that | 1327 | list = vivi_devlist.next; |
1348 | videodev supports, which is equal to VIDEO_NUM_DEVICES. | 1328 | list_del(list); |
1349 | */ | 1329 | dev = list_entry(list, struct vivi_dev, vivi_devlist); |
1350 | static int __init vivi_init(void) | 1330 | |
1331 | v4l2_info(&dev->v4l2_dev, "unregistering /dev/video%d\n", | ||
1332 | dev->vfd->num); | ||
1333 | video_unregister_device(dev->vfd); | ||
1334 | v4l2_device_unregister(&dev->v4l2_dev); | ||
1335 | kfree(dev); | ||
1336 | } | ||
1337 | |||
1338 | return 0; | ||
1339 | } | ||
1340 | |||
1341 | static int __init vivi_create_instance(int i) | ||
1351 | { | 1342 | { |
1352 | int ret = -ENOMEM, i; | ||
1353 | struct vivi_dev *dev; | 1343 | struct vivi_dev *dev; |
1354 | struct video_device *vfd; | 1344 | struct video_device *vfd; |
1345 | int ret; | ||
1355 | 1346 | ||
1356 | if (n_devs <= 0) | 1347 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
1357 | n_devs = 1; | 1348 | if (!dev) |
1349 | return -ENOMEM; | ||
1358 | 1350 | ||
1359 | for (i = 0; i < n_devs; i++) { | 1351 | snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), |
1360 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 1352 | "%s-%03d", VIVI_MODULE_NAME, i); |
1361 | if (!dev) | 1353 | ret = v4l2_device_register(NULL, &dev->v4l2_dev); |
1362 | break; | 1354 | if (ret) |
1355 | goto free_dev; | ||
1363 | 1356 | ||
1364 | /* init video dma queues */ | 1357 | /* init video dma queues */ |
1365 | INIT_LIST_HEAD(&dev->vidq.active); | 1358 | INIT_LIST_HEAD(&dev->vidq.active); |
1366 | init_waitqueue_head(&dev->vidq.wq); | 1359 | init_waitqueue_head(&dev->vidq.wq); |
1367 | 1360 | ||
1368 | /* initialize locks */ | 1361 | /* initialize locks */ |
1369 | spin_lock_init(&dev->slock); | 1362 | spin_lock_init(&dev->slock); |
1370 | mutex_init(&dev->mutex); | 1363 | mutex_init(&dev->mutex); |
1371 | 1364 | ||
1372 | vfd = video_device_alloc(); | 1365 | ret = -ENOMEM; |
1373 | if (!vfd) { | 1366 | vfd = video_device_alloc(); |
1374 | kfree(dev); | 1367 | if (!vfd) |
1375 | break; | 1368 | goto unreg_dev; |
1376 | } | ||
1377 | 1369 | ||
1378 | *vfd = vivi_template; | 1370 | *vfd = vivi_template; |
1379 | 1371 | ||
1380 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr); | 1372 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr); |
1381 | if (ret < 0) { | 1373 | if (ret < 0) |
1382 | video_device_release(vfd); | 1374 | goto rel_vdev; |
1383 | kfree(dev); | ||
1384 | 1375 | ||
1385 | /* If some registers succeeded, keep driver */ | 1376 | video_set_drvdata(vfd, dev); |
1386 | if (i) | ||
1387 | ret = 0; | ||
1388 | 1377 | ||
1389 | break; | 1378 | /* Now that everything is fine, let's add it to device list */ |
1390 | } | 1379 | list_add_tail(&dev->vivi_devlist, &vivi_devlist); |
1391 | 1380 | ||
1392 | /* Now that everything is fine, let's add it to device list */ | 1381 | snprintf(vfd->name, sizeof(vfd->name), "%s (%i)", |
1393 | list_add_tail(&dev->vivi_devlist, &vivi_devlist); | 1382 | vivi_template.name, vfd->num); |
1394 | 1383 | ||
1395 | snprintf(vfd->name, sizeof(vfd->name), "%s (%i)", | 1384 | if (video_nr >= 0) |
1396 | vivi_template.name, vfd->minor); | 1385 | video_nr++; |
1397 | 1386 | ||
1398 | if (video_nr >= 0) | 1387 | dev->vfd = vfd; |
1399 | video_nr++; | 1388 | v4l2_info(&dev->v4l2_dev, "V4L2 device registered as /dev/video%d\n", |
1389 | vfd->num); | ||
1390 | return 0; | ||
1391 | |||
1392 | rel_vdev: | ||
1393 | video_device_release(vfd); | ||
1394 | unreg_dev: | ||
1395 | v4l2_device_unregister(&dev->v4l2_dev); | ||
1396 | free_dev: | ||
1397 | kfree(dev); | ||
1398 | return ret; | ||
1399 | } | ||
1400 | 1400 | ||
1401 | dev->vfd = vfd; | 1401 | /* This routine allocates from 1 to n_devs virtual drivers. |
1402 | printk(KERN_INFO "%s: V4L2 device registered as /dev/video%d\n", | 1402 | |
1403 | VIVI_MODULE_NAME, vfd->num); | 1403 | The real maximum number of virtual drivers will depend on how many drivers |
1404 | will succeed. This is limited to the maximum number of devices that | ||
1405 | videodev supports, which is equal to VIDEO_NUM_DEVICES. | ||
1406 | */ | ||
1407 | static int __init vivi_init(void) | ||
1408 | { | ||
1409 | int ret, i; | ||
1410 | |||
1411 | if (n_devs <= 0) | ||
1412 | n_devs = 1; | ||
1413 | |||
1414 | for (i = 0; i < n_devs; i++) { | ||
1415 | ret = vivi_create_instance(i); | ||
1416 | if (ret) { | ||
1417 | /* If some instantiations succeeded, keep driver */ | ||
1418 | if (i) | ||
1419 | ret = 0; | ||
1420 | break; | ||
1421 | } | ||
1404 | } | 1422 | } |
1405 | 1423 | ||
1406 | if (ret < 0) { | 1424 | if (ret < 0) { |
1407 | vivi_release(); | ||
1408 | printk(KERN_INFO "Error %d while loading vivi driver\n", ret); | 1425 | printk(KERN_INFO "Error %d while loading vivi driver\n", ret); |
1409 | } else { | 1426 | return ret; |
1410 | printk(KERN_INFO "Video Technology Magazine Virtual Video " | 1427 | } |
1428 | |||
1429 | printk(KERN_INFO "Video Technology Magazine Virtual Video " | ||
1411 | "Capture Board ver %u.%u.%u successfully loaded.\n", | 1430 | "Capture Board ver %u.%u.%u successfully loaded.\n", |
1412 | (VIVI_VERSION >> 16) & 0xFF, (VIVI_VERSION >> 8) & 0xFF, | 1431 | (VIVI_VERSION >> 16) & 0xFF, (VIVI_VERSION >> 8) & 0xFF, |
1413 | VIVI_VERSION & 0xFF); | 1432 | VIVI_VERSION & 0xFF); |
1414 | 1433 | ||
1415 | /* n_devs will reflect the actual number of allocated devices */ | 1434 | /* n_devs will reflect the actual number of allocated devices */ |
1416 | n_devs = i; | 1435 | n_devs = i; |
1417 | } | ||
1418 | 1436 | ||
1419 | return ret; | 1437 | return ret; |
1420 | } | 1438 | } |
@@ -1426,19 +1444,3 @@ static void __exit vivi_exit(void) | |||
1426 | 1444 | ||
1427 | module_init(vivi_init); | 1445 | module_init(vivi_init); |
1428 | module_exit(vivi_exit); | 1446 | module_exit(vivi_exit); |
1429 | |||
1430 | MODULE_DESCRIPTION("Video Technology Magazine Virtual Video Capture Board"); | ||
1431 | MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol"); | ||
1432 | MODULE_LICENSE("Dual BSD/GPL"); | ||
1433 | |||
1434 | module_param(video_nr, uint, 0444); | ||
1435 | MODULE_PARM_DESC(video_nr, "video iminor start number"); | ||
1436 | |||
1437 | module_param(n_devs, uint, 0444); | ||
1438 | MODULE_PARM_DESC(n_devs, "number of video devices to create"); | ||
1439 | |||
1440 | module_param_named(debug, vivi_template.debug, int, 0444); | ||
1441 | MODULE_PARM_DESC(debug, "activates debug info"); | ||
1442 | |||
1443 | module_param(vid_limit, int, 0644); | ||
1444 | MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes"); | ||