aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/em28xx
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2008-12-16 20:04:56 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-12-30 06:39:14 -0500
commitefc52a94840198eb5ba68107812b879d34959dbb (patch)
tree24cfe20c1c2558e1c572a91718596f994a75b933 /drivers/media/video/em28xx
parentcf8c91c3e77cc26c43cfe6fc47e649b685736259 (diff)
V4L/DVB (9912): em28xx: fix/improve em28xx locking schema
Changes/fixes on em28xx dev->lock: - em28xx_init_dev() were unlocking without a previous lock; - some read ioctls need to lock after the removal of KBL, since a write may be happening at the same time an ioctl is reading; - keep the device locked during all device initialization; - lock/unlock while reading/writing registers. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/em28xx')
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c55
1 files changed, 43 insertions, 12 deletions
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 1681af192b02..de2d2fdbe6a4 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -784,10 +784,10 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
784 if (rc < 0) 784 if (rc < 0)
785 return rc; 785 return rc;
786 786
787 vidioc_try_fmt_vid_cap(file, priv, f);
788
789 mutex_lock(&dev->lock); 787 mutex_lock(&dev->lock);
790 788
789 vidioc_try_fmt_vid_cap(file, priv, f);
790
791 if (videobuf_queue_is_busy(&fh->vb_vidq)) { 791 if (videobuf_queue_is_busy(&fh->vb_vidq)) {
792 em28xx_errdev("%s queue busy\n", __func__); 792 em28xx_errdev("%s queue busy\n", __func__);
793 rc = -EBUSY; 793 rc = -EBUSY;
@@ -828,15 +828,12 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * norm)
828 828
829 mutex_lock(&dev->lock); 829 mutex_lock(&dev->lock);
830 dev->norm = *norm; 830 dev->norm = *norm;
831 mutex_unlock(&dev->lock);
832 831
833 /* Adjusts width/height, if needed */ 832 /* Adjusts width/height, if needed */
834 f.fmt.pix.width = dev->width; 833 f.fmt.pix.width = dev->width;
835 f.fmt.pix.height = dev->height; 834 f.fmt.pix.height = dev->height;
836 vidioc_try_fmt_vid_cap(file, priv, &f); 835 vidioc_try_fmt_vid_cap(file, priv, &f);
837 836
838 mutex_lock(&dev->lock);
839
840 /* set new image size */ 837 /* set new image size */
841 dev->width = f.fmt.pix.width; 838 dev->width = f.fmt.pix.width;
842 dev->height = f.fmt.pix.height; 839 dev->height = f.fmt.pix.height;
@@ -966,11 +963,15 @@ static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
966 struct em28xx_fh *fh = priv; 963 struct em28xx_fh *fh = priv;
967 struct em28xx *dev = fh->dev; 964 struct em28xx *dev = fh->dev;
968 965
966 mutex_lock(&dev->lock);
967
969 dev->ctl_ainput = INPUT(a->index)->amux; 968 dev->ctl_ainput = INPUT(a->index)->amux;
970 dev->ctl_aoutput = INPUT(a->index)->aout; 969 dev->ctl_aoutput = INPUT(a->index)->aout;
971 970
972 if (!dev->ctl_aoutput) 971 if (!dev->ctl_aoutput)
973 dev->ctl_aoutput = EM28XX_AOUT_MASTER; 972 dev->ctl_aoutput = EM28XX_AOUT_MASTER;
973
974 mutex_unlock(&dev->lock);
974 return 0; 975 return 0;
975} 976}
976 977
@@ -1019,6 +1020,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
1019 rc = check_dev(dev); 1020 rc = check_dev(dev);
1020 if (rc < 0) 1021 if (rc < 0)
1021 return rc; 1022 return rc;
1023
1022 mutex_lock(&dev->lock); 1024 mutex_lock(&dev->lock);
1023 1025
1024 if (!dev->board.has_msp34xx) 1026 if (!dev->board.has_msp34xx)
@@ -1129,8 +1131,10 @@ static int vidioc_g_frequency(struct file *file, void *priv,
1129 struct em28xx_fh *fh = priv; 1131 struct em28xx_fh *fh = priv;
1130 struct em28xx *dev = fh->dev; 1132 struct em28xx *dev = fh->dev;
1131 1133
1134 mutex_lock(&dev->lock);
1132 f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 1135 f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
1133 f->frequency = dev->ctl_freq; 1136 f->frequency = dev->ctl_freq;
1137 mutex_unlock(&dev->lock);
1134 1138
1135 return 0; 1139 return 0;
1136} 1140}
@@ -1160,6 +1164,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
1160 em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f); 1164 em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f);
1161 1165
1162 mutex_unlock(&dev->lock); 1166 mutex_unlock(&dev->lock);
1167
1163 return 0; 1168 return 0;
1164} 1169}
1165 1170
@@ -1187,15 +1192,20 @@ static int vidioc_g_register(struct file *file, void *priv,
1187 return -EINVAL; 1192 return -EINVAL;
1188 1193
1189 if (em28xx_reg_len(reg->reg) == 1) { 1194 if (em28xx_reg_len(reg->reg) == 1) {
1195 mutex_lock(&dev->lock);
1190 ret = em28xx_read_reg(dev, reg->reg); 1196 ret = em28xx_read_reg(dev, reg->reg);
1197 mutex_unlock(&dev->lock);
1198
1191 if (ret < 0) 1199 if (ret < 0)
1192 return ret; 1200 return ret;
1193 1201
1194 reg->val = ret; 1202 reg->val = ret;
1195 } else { 1203 } else {
1196 __le64 val = 0; 1204 __le64 val = 0;
1205 mutex_lock(&dev->lock);
1197 ret = em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS, 1206 ret = em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS,
1198 reg->reg, (char *)&val, 2); 1207 reg->reg, (char *)&val, 2);
1208 mutex_unlock(&dev->lock);
1199 if (ret < 0) 1209 if (ret < 0)
1200 return ret; 1210 return ret;
1201 1211
@@ -1211,11 +1221,16 @@ static int vidioc_s_register(struct file *file, void *priv,
1211 struct em28xx_fh *fh = priv; 1221 struct em28xx_fh *fh = priv;
1212 struct em28xx *dev = fh->dev; 1222 struct em28xx *dev = fh->dev;
1213 __le64 buf; 1223 __le64 buf;
1224 int rc;
1214 1225
1215 buf = cpu_to_le64(reg->val); 1226 buf = cpu_to_le64(reg->val);
1216 1227
1217 return em28xx_write_regs(dev, reg->reg, (char *)&buf, 1228 mutex_lock(&dev->lock);
1218 em28xx_reg_len(reg->reg)); 1229 rc = em28xx_write_regs(dev, reg->reg, (char *)&buf,
1230 em28xx_reg_len(reg->reg));
1231 mutex_unlock(&dev->lock);
1232
1233 return rc;
1219} 1234}
1220#endif 1235#endif
1221 1236
@@ -1254,12 +1269,15 @@ static int vidioc_streamon(struct file *file, void *priv,
1254 1269
1255 mutex_lock(&dev->lock); 1270 mutex_lock(&dev->lock);
1256 rc = res_get(fh); 1271 rc = res_get(fh);
1257 mutex_unlock(&dev->lock);
1258 1272
1259 if (unlikely(rc < 0)) 1273 if (unlikely(rc < 0))
1260 return rc; 1274 return rc;
1261 1275
1262 return (videobuf_streamon(&fh->vb_vidq)); 1276 rc = videobuf_streamon(&fh->vb_vidq);
1277
1278 mutex_unlock(&dev->lock);
1279
1280 return rc;
1263} 1281}
1264 1282
1265static int vidioc_streamoff(struct file *file, void *priv, 1283static int vidioc_streamoff(struct file *file, void *priv,
@@ -1278,9 +1296,11 @@ static int vidioc_streamoff(struct file *file, void *priv,
1278 if (type != fh->type) 1296 if (type != fh->type)
1279 return -EINVAL; 1297 return -EINVAL;
1280 1298
1281 videobuf_streamoff(&fh->vb_vidq);
1282 mutex_lock(&dev->lock); 1299 mutex_lock(&dev->lock);
1300
1301 videobuf_streamoff(&fh->vb_vidq);
1283 res_free(fh); 1302 res_free(fh);
1303
1284 mutex_unlock(&dev->lock); 1304 mutex_unlock(&dev->lock);
1285 1305
1286 return 0; 1306 return 0;
@@ -1465,7 +1485,10 @@ static int radio_g_tuner(struct file *file, void *priv,
1465 strcpy(t->name, "Radio"); 1485 strcpy(t->name, "Radio");
1466 t->type = V4L2_TUNER_RADIO; 1486 t->type = V4L2_TUNER_RADIO;
1467 1487
1488 mutex_lock(&dev->lock);
1468 em28xx_i2c_call_clients(dev, VIDIOC_G_TUNER, t); 1489 em28xx_i2c_call_clients(dev, VIDIOC_G_TUNER, t);
1490 mutex_unlock(&dev->lock);
1491
1469 return 0; 1492 return 0;
1470} 1493}
1471 1494
@@ -1497,7 +1520,9 @@ static int radio_s_tuner(struct file *file, void *priv,
1497 if (0 != t->index) 1520 if (0 != t->index)
1498 return -EINVAL; 1521 return -EINVAL;
1499 1522
1523 mutex_lock(&dev->lock);
1500 em28xx_i2c_call_clients(dev, VIDIOC_S_TUNER, t); 1524 em28xx_i2c_call_clients(dev, VIDIOC_S_TUNER, t);
1525 mutex_unlock(&dev->lock);
1501 1526
1502 return 0; 1527 return 0;
1503} 1528}
@@ -1561,6 +1586,7 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
1561 } 1586 }
1562 } 1587 }
1563 mutex_unlock(&em28xx_devlist_mutex); 1588 mutex_unlock(&em28xx_devlist_mutex);
1589
1564 if (NULL == dev) 1590 if (NULL == dev)
1565 return -ENODEV; 1591 return -ENODEV;
1566 1592
@@ -2036,7 +2062,6 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
2036 unsigned int maxh, maxw; 2062 unsigned int maxh, maxw;
2037 2063
2038 dev->udev = udev; 2064 dev->udev = udev;
2039 mutex_init(&dev->lock);
2040 mutex_init(&dev->ctrl_urb_lock); 2065 mutex_init(&dev->ctrl_urb_lock);
2041 spin_lock_init(&dev->slock); 2066 spin_lock_init(&dev->slock);
2042 init_waitqueue_head(&dev->open); 2067 init_waitqueue_head(&dev->open);
@@ -2151,7 +2176,6 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
2151 return 0; 2176 return 0;
2152 2177
2153fail_reg_devices: 2178fail_reg_devices:
2154 mutex_unlock(&dev->lock);
2155 return retval; 2179 return retval;
2156} 2180}
2157 2181
@@ -2343,6 +2367,8 @@ static int em28xx_usb_probe(struct usb_interface *interface,
2343 dev->model = card[nr]; 2367 dev->model = card[nr];
2344 2368
2345 /* allocate device struct */ 2369 /* allocate device struct */
2370 mutex_init(&dev->lock);
2371 mutex_lock(&dev->lock);
2346 retval = em28xx_init_dev(&dev, udev, nr); 2372 retval = em28xx_init_dev(&dev, udev, nr);
2347 if (retval) { 2373 if (retval) {
2348 em28xx_devused &= ~(1<<dev->devno); 2374 em28xx_devused &= ~(1<<dev->devno);
@@ -2356,6 +2382,11 @@ static int em28xx_usb_probe(struct usb_interface *interface,
2356 2382
2357 request_modules(dev); 2383 request_modules(dev);
2358 2384
2385 /* Should be the last thing to do, to avoid newer udev's to
2386 open the device before fully initializing it
2387 */
2388 mutex_unlock(&dev->lock);
2389
2359 return 0; 2390 return 0;
2360} 2391}
2361 2392