Merge branch 'llseek' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/bkl
[linux-2.6.git] / drivers / media / dvb / dvb-core / dvb_net.c
index c2334ae..4df42aa 100644 (file)
@@ -63,6 +63,7 @@
 #include <asm/uaccess.h>
 #include <linux/crc32.h>
 #include <linux/mutex.h>
+#include <linux/sched.h>
 
 #include "dvb_demux.h"
 #include "dvb_net.h"
@@ -125,7 +126,6 @@ static void hexdump( const unsigned char *buf, unsigned short len )
 
 struct dvb_net_priv {
        int in_use;
-       struct net_device_stats stats;
        u16 pid;
        struct net_device *net;
        struct dvb_net *host;
@@ -345,11 +345,12 @@ static inline void reset_ule( struct dvb_net_priv *p )
  */
 static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
 {
-       struct dvb_net_priv *priv = dev->priv;
+       struct dvb_net_priv *priv = netdev_priv(dev);
        unsigned long skipped = 0L;
        const u8 *ts, *ts_end, *from_where = NULL;
        u8 ts_remain = 0, how_much = 0, new_ts = 1;
        struct ethhdr *ethh = NULL;
+       bool error = false;
 
 #ifdef ULE_DEBUG
        /* The code inside ULE_DEBUG keeps a history of the last 100 TS cells processed. */
@@ -384,8 +385,8 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
                                if (priv->ule_skb) {
                                        dev_kfree_skb( priv->ule_skb );
                                        /* Prepare for next SNDU. */
-                                       priv->stats.rx_errors++;
-                                       priv->stats.rx_frame_errors++;
+                                       dev->stats.rx_errors++;
+                                       dev->stats.rx_frame_errors++;
                                }
                                reset_ule(priv);
                                priv->need_pusi = 1;
@@ -438,8 +439,8 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
                                        dev_kfree_skb( priv->ule_skb );
                                        /* Prepare for next SNDU. */
                                        // reset_ule(priv);  moved to below.
-                                       priv->stats.rx_errors++;
-                                       priv->stats.rx_frame_errors++;
+                                       dev->stats.rx_errors++;
+                                       dev->stats.rx_frame_errors++;
                                }
                                reset_ule(priv);
                                /* skip to next PUSI. */
@@ -459,10 +460,16 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
 
                                                /* Drop partly decoded SNDU, reset state, resync on PUSI. */
                                                if (priv->ule_skb) {
-                                                       dev_kfree_skb( priv->ule_skb );
-                                                       ((struct dvb_net_priv *) dev->priv)->stats.rx_errors++;
-                                                       ((struct dvb_net_priv *) dev->priv)->stats.rx_frame_errors++;
+                                                       error = true;
+                                                       dev_kfree_skb(priv->ule_skb);
                                                }
+
+                                               if (error || priv->ule_sndu_remain) {
+                                                       dev->stats.rx_errors++;
+                                                       dev->stats.rx_frame_errors++;
+                                                       error = false;
+                                               }
+
                                                reset_ule(priv);
                                                priv->need_pusi = 1;
                                                continue;
@@ -477,8 +484,8 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
                                if (priv->ule_sndu_remain > 183) {
                                        /* Current SNDU lacks more data than there could be available in the
                                         * current TS cell. */
-                                       priv->stats.rx_errors++;
-                                       priv->stats.rx_length_errors++;
+                                       dev->stats.rx_errors++;
+                                       dev->stats.rx_length_errors++;
                                        printk(KERN_WARNING "%lu: Expected %d more SNDU bytes, but "
                                               "got PUSI (pf %d, ts_remain %d).  Flushing incomplete payload.\n",
                                               priv->ts_count, priv->ule_sndu_remain, ts[4], ts_remain);
@@ -504,6 +511,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
                                       "bytes left in TS.  Resyncing.\n", ts_remain);
                                priv->ule_sndu_len = 0;
                                priv->need_pusi = 1;
+                               ts += TS_SZ;
                                continue;
                        }
 
@@ -520,8 +528,8 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
                                if (priv->ule_sndu_len < 5) {
                                        printk(KERN_WARNING "%lu: Invalid ULE SNDU length %u. "
                                               "Resyncing.\n", priv->ts_count, priv->ule_sndu_len);
-                                       priv->stats.rx_errors++;
-                                       priv->stats.rx_length_errors++;
+                                       dev->stats.rx_errors++;
+                                       dev->stats.rx_length_errors++;
                                        priv->ule_sndu_len = 0;
                                        priv->need_pusi = 1;
                                        new_ts = 1;
@@ -533,6 +541,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
                                from_where += 2;
                        }
 
+                       priv->ule_sndu_remain = priv->ule_sndu_len + 2;
                        /*
                         * State of current TS:
                         *   ts_remain (remaining bytes in the current TS cell)
@@ -542,6 +551,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
                         */
                        switch (ts_remain) {
                                case 1:
+                                       priv->ule_sndu_remain--;
                                        priv->ule_sndu_type = from_where[0] << 8;
                                        priv->ule_sndu_type_1 = 1; /* first byte of ule_type is set. */
                                        ts_remain -= 1; from_where += 1;
@@ -555,6 +565,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
                                default: /* complete ULE header is present in current TS. */
                                        /* Extract ULE type field. */
                                        if (priv->ule_sndu_type_1) {
+                                               priv->ule_sndu_type_1 = 0;
                                                priv->ule_sndu_type |= from_where[0];
                                                from_where += 1; /* points to payload start. */
                                                ts_remain -= 1;
@@ -573,7 +584,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
                        if (priv->ule_skb == NULL) {
                                printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n",
                                       dev->name);
-                               ((struct dvb_net_priv *)dev->priv)->stats.rx_dropped++;
+                               dev->stats.rx_dropped++;
                                return;
                        }
 
@@ -606,7 +617,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
                        if (priv->ule_dbit) {
                                /* Set D-bit for CRC32 verification,
                                 * if it was set originally. */
-                               ulen |= 0x0080;
+                               ulen |= htons(0x8000);
                        }
 
                        ule_crc = iov_crc32(ule_crc, iov, 3);
@@ -637,8 +648,8 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
                                ule_dump = 1;
 #endif
 
-                               priv->stats.rx_errors++;
-                               priv->stats.rx_crc_errors++;
+                               dev->stats.rx_errors++;
+                               dev->stats.rx_crc_errors++;
                                dev_kfree_skb(priv->ule_skb);
                        } else {
                                /* CRC32 verified OK. */
@@ -744,8 +755,8 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
                                 * receive the packet anyhow. */
                                /* if (priv->ule_dbit && skb->pkt_type == PACKET_OTHERHOST)
                                        priv->ule_skb->pkt_type = PACKET_HOST; */
-                               priv->stats.rx_packets++;
-                               priv->stats.rx_bytes += priv->ule_skb->len;
+                               dev->stats.rx_packets++;
+                               dev->stats.rx_bytes += priv->ule_skb->len;
                                netif_rx(priv->ule_skb);
                        }
                        sndu_done:
@@ -800,7 +811,7 @@ static void dvb_net_sec(struct net_device *dev,
 {
        u8 *eth;
        struct sk_buff *skb;
-       struct net_device_stats *stats = &(((struct dvb_net_priv *) dev->priv)->stats);
+       struct net_device_stats *stats = &dev->stats;
        int snap = 0;
 
        /* note: pkt_len includes a 32bit checksum */
@@ -905,7 +916,7 @@ static int dvb_net_sec_callback(const u8 *buffer1, size_t buffer1_len,
 static int dvb_net_tx(struct sk_buff *skb, struct net_device *dev)
 {
        dev_kfree_skb(skb);
-       return 0;
+       return NETDEV_TX_OK;
 }
 
 static u8 mask_normal[6]={0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
@@ -917,7 +928,7 @@ static int dvb_net_filter_sec_set(struct net_device *dev,
                   struct dmx_section_filter **secfilter,
                   u8 *mac, u8 *mac_mask)
 {
-       struct dvb_net_priv *priv = dev->priv;
+       struct dvb_net_priv *priv = netdev_priv(dev);
        int ret;
 
        *secfilter=NULL;
@@ -949,11 +960,8 @@ static int dvb_net_filter_sec_set(struct net_device *dev,
        (*secfilter)->filter_mask[10] = mac_mask[1];
        (*secfilter)->filter_mask[11]=mac_mask[0];
 
-       dprintk("%s: filter mac=%02x %02x %02x %02x %02x %02x\n",
-              dev->name, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
-       dprintk("%s: filter mask=%02x %02x %02x %02x %02x %02x\n",
-              dev->name, mac_mask[0], mac_mask[1], mac_mask[2],
-              mac_mask[3], mac_mask[4], mac_mask[5]);
+       dprintk("%s: filter mac=%pM\n", dev->name, mac);
+       dprintk("%s: filter mask=%pM\n", dev->name, mac_mask);
 
        return 0;
 }
@@ -961,7 +969,7 @@ static int dvb_net_filter_sec_set(struct net_device *dev,
 static int dvb_net_feed_start(struct net_device *dev)
 {
        int ret = 0, i;
-       struct dvb_net_priv *priv = dev->priv;
+       struct dvb_net_priv *priv = netdev_priv(dev);
        struct dmx_demux *demux = priv->demux;
        unsigned char *mac = (unsigned char *) dev->dev_addr;
 
@@ -1060,7 +1068,7 @@ error:
 
 static int dvb_net_feed_stop(struct net_device *dev)
 {
-       struct dvb_net_priv *priv = dev->priv;
+       struct dvb_net_priv *priv = netdev_priv(dev);
        int i, ret = 0;
 
        dprintk("%s\n", __func__);
@@ -1111,14 +1119,14 @@ static int dvb_net_feed_stop(struct net_device *dev)
 }
 
 
-static int dvb_set_mc_filter (struct net_device *dev, struct dev_mc_list *mc)
+static int dvb_set_mc_filter(struct net_device *dev, unsigned char *addr)
 {
-       struct dvb_net_priv *priv = dev->priv;
+       struct dvb_net_priv *priv = netdev_priv(dev);
 
        if (priv->multi_num == DVB_NET_MULTICAST_MAX)
                return -ENOMEM;
 
-       memcpy(priv->multi_macs[priv->multi_num], mc->dmi_addr, 6);
+       memcpy(priv->multi_macs[priv->multi_num], addr, ETH_ALEN);
 
        priv->multi_num++;
        return 0;
@@ -1133,7 +1141,7 @@ static void wq_set_multicast_list (struct work_struct *work)
 
        dvb_net_feed_stop(dev);
        priv->rx_mode = RX_MODE_UNI;
-       netif_tx_lock_bh(dev);
+       netif_addr_lock_bh(dev);
 
        if (dev->flags & IFF_PROMISC) {
                dprintk("%s: promiscuous mode\n", dev->name);
@@ -1141,31 +1149,27 @@ static void wq_set_multicast_list (struct work_struct *work)
        } else if ((dev->flags & IFF_ALLMULTI)) {
                dprintk("%s: allmulti mode\n", dev->name);
                priv->rx_mode = RX_MODE_ALL_MULTI;
-       } else if (dev->mc_count) {
-               int mci;
-               struct dev_mc_list *mc;
+       } else if (!netdev_mc_empty(dev)) {
+               struct netdev_hw_addr *ha;
 
                dprintk("%s: set_mc_list, %d entries\n",
-                       dev->name, dev->mc_count);
+                       dev->name, netdev_mc_count(dev));
 
                priv->rx_mode = RX_MODE_MULTI;
                priv->multi_num = 0;
 
-               for (mci = 0, mc=dev->mc_list;
-                    mci < dev->mc_count;
-                    mc = mc->next, mci++) {
-                       dvb_set_mc_filter(dev, mc);
-               }
+               netdev_for_each_mc_addr(ha, dev)
+                       dvb_set_mc_filter(dev, ha->addr);
        }
 
-       netif_tx_unlock_bh(dev);
+       netif_addr_unlock_bh(dev);
        dvb_net_feed_start(dev);
 }
 
 
 static void dvb_net_set_multicast_list (struct net_device *dev)
 {
-       struct dvb_net_priv *priv = dev->priv;
+       struct dvb_net_priv *priv = netdev_priv(dev);
        schedule_work(&priv->set_multicast_list_wq);
 }
 
@@ -1185,7 +1189,7 @@ static void wq_restart_net_feed (struct work_struct *work)
 
 static int dvb_net_set_mac (struct net_device *dev, void *p)
 {
-       struct dvb_net_priv *priv = dev->priv;
+       struct dvb_net_priv *priv = netdev_priv(dev);
        struct sockaddr *addr=p;
 
        memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
@@ -1199,7 +1203,7 @@ static int dvb_net_set_mac (struct net_device *dev, void *p)
 
 static int dvb_net_open(struct net_device *dev)
 {
-       struct dvb_net_priv *priv = dev->priv;
+       struct dvb_net_priv *priv = netdev_priv(dev);
 
        priv->in_use++;
        dvb_net_feed_start(dev);
@@ -1209,36 +1213,36 @@ static int dvb_net_open(struct net_device *dev)
 
 static int dvb_net_stop(struct net_device *dev)
 {
-       struct dvb_net_priv *priv = dev->priv;
+       struct dvb_net_priv *priv = netdev_priv(dev);
 
        priv->in_use--;
        return dvb_net_feed_stop(dev);
 }
 
-static struct net_device_stats * dvb_net_get_stats(struct net_device *dev)
-{
-       return &((struct dvb_net_priv*) dev->priv)->stats;
-}
-
 static const struct header_ops dvb_header_ops = {
        .create         = eth_header,
        .parse          = eth_header_parse,
        .rebuild        = eth_rebuild_header,
 };
 
+
+static const struct net_device_ops dvb_netdev_ops = {
+       .ndo_open               = dvb_net_open,
+       .ndo_stop               = dvb_net_stop,
+       .ndo_start_xmit         = dvb_net_tx,
+       .ndo_set_multicast_list = dvb_net_set_multicast_list,
+       .ndo_set_mac_address    = dvb_net_set_mac,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+};
+
 static void dvb_net_setup(struct net_device *dev)
 {
        ether_setup(dev);
 
        dev->header_ops         = &dvb_header_ops;
-       dev->open               = dvb_net_open;
-       dev->stop               = dvb_net_stop;
-       dev->hard_start_xmit    = dvb_net_tx;
-       dev->get_stats          = dvb_net_get_stats;
-       dev->set_multicast_list = dvb_net_set_multicast_list;
-       dev->set_mac_address    = dvb_net_set_mac;
+       dev->netdev_ops         = &dvb_netdev_ops;
        dev->mtu                = 4096;
-       dev->mc_count           = 0;
 
        dev->flags |= IFF_NOARP;
 }
@@ -1287,7 +1291,7 @@ static int dvb_net_add_if(struct dvb_net *dvbnet, u16 pid, u8 feedtype)
 
        dvbnet->device[if_num] = net;
 
-       priv = net->priv;
+       priv = netdev_priv(net);
        priv->net = net;
        priv->demux = dvbnet->demux;
        priv->pid = pid;
@@ -1320,7 +1324,7 @@ static int dvb_net_remove_if(struct dvb_net *dvbnet, unsigned long num)
 
        if (!dvbnet->state[num])
                return -EINVAL;
-       priv = net->priv;
+       priv = netdev_priv(net);
        if (priv->in_use)
                return -EBUSY;
 
@@ -1335,7 +1339,7 @@ static int dvb_net_remove_if(struct dvb_net *dvbnet, unsigned long num)
        return 0;
 }
 
-static int dvb_net_do_ioctl(struct inode *inode, struct file *file,
+static int dvb_net_do_ioctl(struct file *file,
                  unsigned int cmd, void *parg)
 {
        struct dvb_device *dvbdev = file->private_data;
@@ -1376,7 +1380,7 @@ static int dvb_net_do_ioctl(struct inode *inode, struct file *file,
 
                netdev = dvbnet->device[dvbnetif->if_num];
 
-               priv_data = netdev->priv;
+               priv_data = netdev_priv(netdev);
                dvbnetif->pid=priv_data->pid;
                dvbnetif->feedtype=priv_data->feedtype;
                break;
@@ -1395,7 +1399,7 @@ static int dvb_net_do_ioctl(struct inode *inode, struct file *file,
                return ret;
        }
 
-       /* binary compatiblity cruft */
+       /* binary compatibility cruft */
        case __NET_ADD_IF_OLD:
        {
                struct __dvb_net_if_old *dvbnetif = parg;
@@ -1427,7 +1431,7 @@ static int dvb_net_do_ioctl(struct inode *inode, struct file *file,
 
                netdev = dvbnet->device[dvbnetif->if_num];
 
-               priv_data = netdev->priv;
+               priv_data = netdev_priv(netdev);
                dvbnetif->pid=priv_data->pid;
                break;
        }
@@ -1437,10 +1441,10 @@ static int dvb_net_do_ioctl(struct inode *inode, struct file *file,
        return 0;
 }
 
-static int dvb_net_ioctl(struct inode *inode, struct file *file,
+static long dvb_net_ioctl(struct file *file,
              unsigned int cmd, unsigned long arg)
 {
-       return dvb_usercopy(inode, file, cmd, arg, dvb_net_do_ioctl);
+       return dvb_usercopy(file, cmd, arg, dvb_net_do_ioctl);
 }
 
 static int dvb_net_close(struct inode *inode, struct file *file)
@@ -1459,11 +1463,12 @@ static int dvb_net_close(struct inode *inode, struct file *file)
 }
 
 
-static struct file_operations dvb_net_fops = {
+static const struct file_operations dvb_net_fops = {
        .owner = THIS_MODULE,
-       .ioctl = dvb_net_ioctl,
+       .unlocked_ioctl = dvb_net_ioctl,
        .open = dvb_generic_open,
        .release = dvb_net_close,
+       .llseek = noop_llseek,
 };
 
 static struct dvb_device dvbdev_net = {