]> err.no Git - linux-2.6/blobdiff - drivers/media/dvb/dvb-core/dvb_net.c
Merge branch 'for-linus' of git://git.o-hand.com/linux-rpurdie-leds
[linux-2.6] / drivers / media / dvb / dvb-core / dvb_net.c
index 6a5ab409c4e71919b5331339adc51ed9b3b4fa0c..2117377c141d206cce3d2710a1deeb93916efdb1 100644 (file)
@@ -347,7 +347,8 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
 {
        struct dvb_net_priv *priv = dev->priv;
        unsigned long skipped = 0L;
-       u8 *ts, *ts_end, *from_where = NULL, ts_remain = 0, how_much = 0, new_ts = 1;
+       const u8 *ts, *ts_end, *from_where = NULL;
+       u8 ts_remain = 0, how_much = 0, new_ts = 1;
        struct ethhdr *ethh = NULL;
 
 #ifdef ULE_DEBUG
@@ -356,15 +357,10 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
        static unsigned char *ule_where = ule_hist, ule_dump = 0;
 #endif
 
-       if (dev == NULL) {
-               printk( KERN_ERR "NO netdev struct!\n" );
-               return;
-       }
-
        /* For all TS cells in current buffer.
         * Appearently, we are called for every single TS cell.
         */
-       for (ts = (char *)buf, ts_end = (char *)buf + buf_len; ts < ts_end; /* no default incr. */ ) {
+       for (ts = buf, ts_end = buf + buf_len; ts < ts_end; /* no default incr. */ ) {
 
                if (new_ts) {
                        /* We are about to process a new TS cell. */
@@ -799,7 +795,8 @@ static int dvb_net_ts_callback(const u8 *buffer1, size_t buffer1_len,
 }
 
 
-static void dvb_net_sec(struct net_device *dev, u8 *pkt, int pkt_len)
+static void dvb_net_sec(struct net_device *dev,
+                       const u8 *pkt, int pkt_len)
 {
        u8 *eth;
        struct sk_buff *skb;
@@ -901,7 +898,7 @@ static int dvb_net_sec_callback(const u8 *buffer1, size_t buffer1_len,
         * we rely on the DVB API definition where exactly one complete
         * section is delivered in buffer1
         */
-       dvb_net_sec (dev, (u8*) buffer1, buffer1_len);
+       dvb_net_sec (dev, buffer1, buffer1_len);
        return 0;
 }
 
@@ -1439,11 +1436,27 @@ static int dvb_net_ioctl(struct inode *inode, struct file *file,
        return dvb_usercopy(inode, file, cmd, arg, dvb_net_do_ioctl);
 }
 
+static int dvb_net_close(struct inode *inode, struct file *file)
+{
+       struct dvb_device *dvbdev = file->private_data;
+       struct dvb_net *dvbnet = dvbdev->priv;
+
+       dvb_generic_release(inode, file);
+
+       if(dvbdev->users == 1 && dvbnet->exit == 1) {
+               fops_put(file->f_op);
+               file->f_op = NULL;
+               wake_up(&dvbdev->wait_queue);
+       }
+       return 0;
+}
+
+
 static struct file_operations dvb_net_fops = {
        .owner = THIS_MODULE,
        .ioctl = dvb_net_ioctl,
        .open = dvb_generic_open,
-       .release = dvb_generic_release,
+       .release = dvb_net_close,
 };
 
 static struct dvb_device dvbdev_net = {
@@ -1458,6 +1471,11 @@ void dvb_net_release (struct dvb_net *dvbnet)
 {
        int i;
 
+       dvbnet->exit = 1;
+       if (dvbnet->dvbdev->users < 1)
+               wait_event(dvbnet->dvbdev->wait_queue,
+                               dvbnet->dvbdev->users==1);
+
        dvb_unregister_device(dvbnet->dvbdev);
 
        for (i=0; i<DVB_NET_DEVICES_MAX; i++) {