aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Walls <awalls@md.metrocast.net>2011-01-26 19:25:47 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-03-22 18:23:50 -0400
commit9b28500a59d7ee5da5adb43bcb384391cac401c4 (patch)
tree8cf3d412625919e0f707cf5fe85e837992ad84ed
parent12d896e1c17978599a98510fdfaff27a4e82c0bf (diff)
[media] lirc_zilog: Remove broken, ineffective reference counting
The set_use_inc() and set_use_dec() functions tried to lock the underlying bridge driver device instance in memory by changing the use count on the device's i2c_clients. This worked for PCI devices (ivtv, cx18, bttv). It doesn't work for hot-pluggable usb devices (pvrusb2 and hdpvr). With usb device instances, the driver may get locked into memory, but the unplugged hardware is gone. The set_use_inc() set_use_dec() functions also tried to have lirc_zilog change its own module refernce count, which is racy and not guaranteed to work. The lirc_dev module does actually perform proper module ref count manipulation on the lirc_zilog module, so there is need for lirc_zilog to attempt a buggy module get on itself anyway. lirc_zilog also errantly called these functions on itself in open() and close(), but lirc_dev did that already too. So let's just gut the bodies of the set_use_*() functions, and remove the extra calls to them from within lirc_zilog. Proper reference counting of the struct IR, IR_rx, and IR_tx objects -- to handle the case when the underlying bttv, ivtv, cx18, hdpvr, or pvrusb2 bridge driver module or device instance goes away -- will be added in subsequent patches. Signed-off-by: Andy Walls <awalls@md.metrocast.net> Signed-off-by: Jarod Wilson <jarod@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/staging/lirc/lirc_zilog.c32
1 files changed, 1 insertions, 31 deletions
diff --git a/drivers/staging/lirc/lirc_zilog.c b/drivers/staging/lirc/lirc_zilog.c
index 7389b77ece8c..3a912575e12d 100644
--- a/drivers/staging/lirc/lirc_zilog.c
+++ b/drivers/staging/lirc/lirc_zilog.c
@@ -305,34 +305,12 @@ static int lirc_thread(void *arg)
305 305
306static int set_use_inc(void *data) 306static int set_use_inc(void *data)
307{ 307{
308 struct IR *ir = data;
309
310 if (ir->l.owner == NULL || try_module_get(ir->l.owner) == 0)
311 return -ENODEV;
312
313 /* lock bttv in memory while /dev/lirc is in use */
314 /*
315 * this is completely broken code. lirc_unregister_driver()
316 * must be possible even when the device is open
317 */
318 if (ir->rx != NULL)
319 i2c_use_client(ir->rx->c);
320 if (ir->tx != NULL)
321 i2c_use_client(ir->tx->c);
322
323 return 0; 308 return 0;
324} 309}
325 310
326static void set_use_dec(void *data) 311static void set_use_dec(void *data)
327{ 312{
328 struct IR *ir = data; 313 return;
329
330 if (ir->rx)
331 i2c_release_client(ir->rx->c);
332 if (ir->tx)
333 i2c_release_client(ir->tx->c);
334 if (ir->l.owner != NULL)
335 module_put(ir->l.owner);
336} 314}
337 315
338/* safe read of a uint32 (always network byte order) */ 316/* safe read of a uint32 (always network byte order) */
@@ -1098,7 +1076,6 @@ static struct IR *find_ir_device_by_minor(unsigned int minor)
1098static int open(struct inode *node, struct file *filep) 1076static int open(struct inode *node, struct file *filep)
1099{ 1077{
1100 struct IR *ir; 1078 struct IR *ir;
1101 int ret;
1102 unsigned int minor = MINOR(node->i_rdev); 1079 unsigned int minor = MINOR(node->i_rdev);
1103 1080
1104 /* find our IR struct */ 1081 /* find our IR struct */
@@ -1112,12 +1089,6 @@ static int open(struct inode *node, struct file *filep)
1112 /* increment in use count */ 1089 /* increment in use count */
1113 mutex_lock(&ir->ir_lock); 1090 mutex_lock(&ir->ir_lock);
1114 ++ir->open; 1091 ++ir->open;
1115 ret = set_use_inc(ir);
1116 if (ret != 0) {
1117 --ir->open;
1118 mutex_unlock(&ir->ir_lock);
1119 return ret;
1120 }
1121 mutex_unlock(&ir->ir_lock); 1092 mutex_unlock(&ir->ir_lock);
1122 1093
1123 /* stash our IR struct */ 1094 /* stash our IR struct */
@@ -1139,7 +1110,6 @@ static int close(struct inode *node, struct file *filep)
1139 /* decrement in use count */ 1110 /* decrement in use count */
1140 mutex_lock(&ir->ir_lock); 1111 mutex_lock(&ir->ir_lock);
1141 --ir->open; 1112 --ir->open;
1142 set_use_dec(ir);
1143 mutex_unlock(&ir->ir_lock); 1113 mutex_unlock(&ir->ir_lock);
1144 1114
1145 return 0; 1115 return 0;