]> 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 76e9c36597eb6340e16a08311370bd4d0a405029..2117377c141d206cce3d2710a1deeb93916efdb1 100644 (file)
@@ -174,7 +174,7 @@ static unsigned short dvb_net_eth_type_trans(struct sk_buff *skb,
        struct ethhdr *eth;
        unsigned char *rawp;
 
-       skb->mac.raw=skb->data;
+       skb_reset_mac_header(skb);
        skb_pull(skb,dev->hard_header_len);
        eth = eth_hdr(skb);
 
@@ -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. */
@@ -600,6 +596,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
                        /* Check CRC32, we've got it in our skb already. */
                        unsigned short ulen = htons(priv->ule_sndu_len);
                        unsigned short utype = htons(priv->ule_sndu_type);
+                       const u8 *tail;
                        struct kvec iov[3] = {
                                { &ulen, sizeof ulen },
                                { &utype, sizeof utype },
@@ -613,10 +610,11 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
                        }
 
                        ule_crc = iov_crc32(ule_crc, iov, 3);
-                       expected_crc = *((u8 *)priv->ule_skb->tail - 4) << 24 |
-                                      *((u8 *)priv->ule_skb->tail - 3) << 16 |
-                                      *((u8 *)priv->ule_skb->tail - 2) << 8 |
-                                      *((u8 *)priv->ule_skb->tail - 1);
+                       tail = skb_tail_pointer(priv->ule_skb);
+                       expected_crc = *(tail - 4) << 24 |
+                                      *(tail - 3) << 16 |
+                                      *(tail - 2) << 8 |
+                                      *(tail - 1);
                        if (ule_crc != expected_crc) {
                                printk(KERN_WARNING "%lu: CRC32 check FAILED: %08x / %08x, SNDU len %d type %#x, ts_remain %d, next 2: %x.\n",
                                       priv->ts_count, ule_crc, expected_crc, priv->ule_sndu_len, priv->ule_sndu_type, ts_remain, ts_remain > 2 ? *(unsigned short *)from_where : 0);
@@ -695,7 +693,9 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
                                        }
                                        else
                                        {
-                                               memcpy(dest_addr,  priv->ule_skb->data, ETH_ALEN);
+                                               skb_copy_from_linear_data(priv->ule_skb,
+                                                             dest_addr,
+                                                             ETH_ALEN);
                                                skb_pull(priv->ule_skb, ETH_ALEN);
                                        }
                                }
@@ -795,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;
@@ -897,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;
 }
 
@@ -1435,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 = {
@@ -1454,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++) {