| .. | .. |
|---|
| 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++) |
|---|