hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/media/dvb-core/dvb_ca_en50221.c
....@@ -151,13 +151,19 @@
151151
152152 /* mutex serializing ioctls */
153153 struct mutex ioctl_mutex;
154
+
155
+ /* A mutex used when a device is disconnected */
156
+ struct mutex remove_mutex;
157
+
158
+ /* Whether the device is disconnected */
159
+ int exit;
154160 };
155161
156162 static void dvb_ca_private_free(struct dvb_ca_private *ca)
157163 {
158164 unsigned int i;
159165
160
- dvb_free_device(ca->dvbdev);
166
+ dvb_device_put(ca->dvbdev);
161167 for (i = 0; i < ca->slot_count; i++)
162168 vfree(ca->slot_info[i].rx_buffer.data);
163169
....@@ -187,7 +193,7 @@
187193 static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot,
188194 u8 *ebuf, int ecount);
189195 static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot,
190
- u8 *ebuf, int ecount);
196
+ u8 *ebuf, int ecount, int size_write_flag);
191197
192198 /**
193199 * Safely find needle in haystack.
....@@ -370,7 +376,7 @@
370376 ret = dvb_ca_en50221_wait_if_status(ca, slot, STATUSREG_FR, HZ / 10);
371377 if (ret)
372378 return ret;
373
- ret = dvb_ca_en50221_write_data(ca, slot, buf, 2);
379
+ ret = dvb_ca_en50221_write_data(ca, slot, buf, 2, CMDREG_SW);
374380 if (ret != 2)
375381 return -EIO;
376382 ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN);
....@@ -778,11 +784,13 @@
778784 * @buf: The data in this buffer is treated as a complete link-level packet to
779785 * be written.
780786 * @bytes_write: Size of ebuf.
787
+ * @size_write_flag: A flag on Command Register which says whether the link size
788
+ * information will be writen or not.
781789 *
782790 * return: Number of bytes written, or < 0 on error.
783791 */
784792 static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot,
785
- u8 *buf, int bytes_write)
793
+ u8 *buf, int bytes_write, int size_write_flag)
786794 {
787795 struct dvb_ca_slot *sl = &ca->slot_info[slot];
788796 int status;
....@@ -817,7 +825,7 @@
817825
818826 /* OK, set HC bit */
819827 status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND,
820
- IRQEN | CMDREG_HC);
828
+ IRQEN | CMDREG_HC | size_write_flag);
821829 if (status)
822830 goto exit;
823831
....@@ -1505,7 +1513,7 @@
15051513
15061514 mutex_lock(&sl->slot_lock);
15071515 status = dvb_ca_en50221_write_data(ca, slot, fragbuf,
1508
- fraglen + 2);
1516
+ fraglen + 2, 0);
15091517 mutex_unlock(&sl->slot_lock);
15101518 if (status == (fraglen + 2)) {
15111519 written = 1;
....@@ -1706,12 +1714,22 @@
17061714
17071715 dprintk("%s\n", __func__);
17081716
1709
- if (!try_module_get(ca->pub->owner))
1717
+ mutex_lock(&ca->remove_mutex);
1718
+
1719
+ if (ca->exit) {
1720
+ mutex_unlock(&ca->remove_mutex);
1721
+ return -ENODEV;
1722
+ }
1723
+
1724
+ if (!try_module_get(ca->pub->owner)) {
1725
+ mutex_unlock(&ca->remove_mutex);
17101726 return -EIO;
1727
+ }
17111728
17121729 err = dvb_generic_open(inode, file);
17131730 if (err < 0) {
17141731 module_put(ca->pub->owner);
1732
+ mutex_unlock(&ca->remove_mutex);
17151733 return err;
17161734 }
17171735
....@@ -1736,6 +1754,7 @@
17361754
17371755 dvb_ca_private_get(ca);
17381756
1757
+ mutex_unlock(&ca->remove_mutex);
17391758 return 0;
17401759 }
17411760
....@@ -1755,6 +1774,8 @@
17551774
17561775 dprintk("%s\n", __func__);
17571776
1777
+ mutex_lock(&ca->remove_mutex);
1778
+
17581779 /* mark the CA device as closed */
17591780 ca->open = 0;
17601781 dvb_ca_en50221_thread_update_delay(ca);
....@@ -1764,6 +1785,13 @@
17641785 module_put(ca->pub->owner);
17651786
17661787 dvb_ca_private_put(ca);
1788
+
1789
+ if (dvbdev->users == 1 && ca->exit == 1) {
1790
+ mutex_unlock(&ca->remove_mutex);
1791
+ wake_up(&dvbdev->wait_queue);
1792
+ } else {
1793
+ mutex_unlock(&ca->remove_mutex);
1794
+ }
17671795
17681796 return err;
17691797 }
....@@ -1888,6 +1916,7 @@
18881916 }
18891917
18901918 mutex_init(&ca->ioctl_mutex);
1919
+ mutex_init(&ca->remove_mutex);
18911920
18921921 if (signal_pending(current)) {
18931922 ret = -EINTR;
....@@ -1930,6 +1959,14 @@
19301959
19311960 dprintk("%s\n", __func__);
19321961
1962
+ mutex_lock(&ca->remove_mutex);
1963
+ ca->exit = 1;
1964
+ mutex_unlock(&ca->remove_mutex);
1965
+
1966
+ if (ca->dvbdev->users < 1)
1967
+ wait_event(ca->dvbdev->wait_queue,
1968
+ ca->dvbdev->users == 1);
1969
+
19331970 /* shutdown the thread if there was one */
19341971 kthread_stop(ca->thread);
19351972