.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * dvb_net.c |
---|
3 | 4 | * |
---|
.. | .. |
---|
13 | 14 | * and Wolfram Stering <wstering@cosy.sbg.ac.at> |
---|
14 | 15 | * |
---|
15 | 16 | * ULE Decaps according to RFC 4326. |
---|
16 | | - * |
---|
17 | | - * This program is free software; you can redistribute it and/or |
---|
18 | | - * modify it under the terms of the GNU General Public License |
---|
19 | | - * as published by the Free Software Foundation; either version 2 |
---|
20 | | - * of the License, or (at your option) any later version. |
---|
21 | | - * |
---|
22 | | - * This program is distributed in the hope that it will be useful, |
---|
23 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
24 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
25 | | - * GNU General Public License for more details. |
---|
26 | | - * To obtain the license, point your browser to |
---|
27 | | - * http://www.gnu.org/copyleft/gpl.html |
---|
28 | 17 | */ |
---|
29 | 18 | |
---|
30 | 19 | /* |
---|
.. | .. |
---|
558 | 547 | h->priv->ule_sndu_type_1 = 1; |
---|
559 | 548 | h->ts_remain -= 1; |
---|
560 | 549 | h->from_where += 1; |
---|
561 | | - /* fallthrough */ |
---|
| 550 | + fallthrough; |
---|
562 | 551 | case 0: |
---|
563 | 552 | h->new_ts = 1; |
---|
564 | 553 | h->ts += TS_SZ; |
---|
.. | .. |
---|
1575 | 1564 | return dvb_usercopy(file, cmd, arg, dvb_net_do_ioctl); |
---|
1576 | 1565 | } |
---|
1577 | 1566 | |
---|
| 1567 | +static int locked_dvb_net_open(struct inode *inode, struct file *file) |
---|
| 1568 | +{ |
---|
| 1569 | + struct dvb_device *dvbdev = file->private_data; |
---|
| 1570 | + struct dvb_net *dvbnet = dvbdev->priv; |
---|
| 1571 | + int ret; |
---|
| 1572 | + |
---|
| 1573 | + if (mutex_lock_interruptible(&dvbnet->remove_mutex)) |
---|
| 1574 | + return -ERESTARTSYS; |
---|
| 1575 | + |
---|
| 1576 | + if (dvbnet->exit) { |
---|
| 1577 | + mutex_unlock(&dvbnet->remove_mutex); |
---|
| 1578 | + return -ENODEV; |
---|
| 1579 | + } |
---|
| 1580 | + |
---|
| 1581 | + ret = dvb_generic_open(inode, file); |
---|
| 1582 | + |
---|
| 1583 | + mutex_unlock(&dvbnet->remove_mutex); |
---|
| 1584 | + |
---|
| 1585 | + return ret; |
---|
| 1586 | +} |
---|
| 1587 | + |
---|
1578 | 1588 | static int dvb_net_close(struct inode *inode, struct file *file) |
---|
1579 | 1589 | { |
---|
1580 | 1590 | struct dvb_device *dvbdev = file->private_data; |
---|
1581 | 1591 | struct dvb_net *dvbnet = dvbdev->priv; |
---|
1582 | 1592 | |
---|
| 1593 | + mutex_lock(&dvbnet->remove_mutex); |
---|
| 1594 | + |
---|
1583 | 1595 | dvb_generic_release(inode, file); |
---|
1584 | 1596 | |
---|
1585 | | - if(dvbdev->users == 1 && dvbnet->exit == 1) |
---|
| 1597 | + if (dvbdev->users == 1 && dvbnet->exit == 1) { |
---|
| 1598 | + mutex_unlock(&dvbnet->remove_mutex); |
---|
1586 | 1599 | wake_up(&dvbdev->wait_queue); |
---|
| 1600 | + } else { |
---|
| 1601 | + mutex_unlock(&dvbnet->remove_mutex); |
---|
| 1602 | + } |
---|
| 1603 | + |
---|
1587 | 1604 | return 0; |
---|
1588 | 1605 | } |
---|
1589 | 1606 | |
---|
.. | .. |
---|
1591 | 1608 | static const struct file_operations dvb_net_fops = { |
---|
1592 | 1609 | .owner = THIS_MODULE, |
---|
1593 | 1610 | .unlocked_ioctl = dvb_net_ioctl, |
---|
1594 | | - .open = dvb_generic_open, |
---|
| 1611 | + .open = locked_dvb_net_open, |
---|
1595 | 1612 | .release = dvb_net_close, |
---|
1596 | 1613 | .llseek = noop_llseek, |
---|
1597 | 1614 | }; |
---|
.. | .. |
---|
1610 | 1627 | { |
---|
1611 | 1628 | int i; |
---|
1612 | 1629 | |
---|
| 1630 | + mutex_lock(&dvbnet->remove_mutex); |
---|
1613 | 1631 | dvbnet->exit = 1; |
---|
| 1632 | + mutex_unlock(&dvbnet->remove_mutex); |
---|
| 1633 | + |
---|
1614 | 1634 | if (dvbnet->dvbdev->users < 1) |
---|
1615 | 1635 | wait_event(dvbnet->dvbdev->wait_queue, |
---|
1616 | | - dvbnet->dvbdev->users==1); |
---|
| 1636 | + dvbnet->dvbdev->users == 1); |
---|
1617 | 1637 | |
---|
1618 | 1638 | dvb_unregister_device(dvbnet->dvbdev); |
---|
1619 | 1639 | |
---|
.. | .. |
---|
1632 | 1652 | int i; |
---|
1633 | 1653 | |
---|
1634 | 1654 | mutex_init(&dvbnet->ioctl_mutex); |
---|
| 1655 | + mutex_init(&dvbnet->remove_mutex); |
---|
1635 | 1656 | dvbnet->demux = dmx; |
---|
1636 | 1657 | |
---|
1637 | 1658 | for (i=0; i<DVB_NET_DEVICES_MAX; i++) |
---|