diff options
author | Andy Walls <awalls@md.metrocast.net> | 2011-01-26 19:25:47 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-03-22 18:23:50 -0400 |
commit | 9b28500a59d7ee5da5adb43bcb384391cac401c4 (patch) | |
tree | 8cf3d412625919e0f707cf5fe85e837992ad84ed | |
parent | 12d896e1c17978599a98510fdfaff27a4e82c0bf (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.c | 32 |
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 | ||
306 | static int set_use_inc(void *data) | 306 | static 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 | ||
326 | static void set_use_dec(void *data) | 311 | static 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) | |||
1098 | static int open(struct inode *node, struct file *filep) | 1076 | static 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; |