]> rtime.felk.cvut.cz Git - socketcan-devel.git/commitdiff
can: provide library functions for skb allocation
authorwolf <wolf@030b6a49-0b11-0410-94ab-b0dab22257f2>
Wed, 7 Oct 2009 17:37:57 +0000 (17:37 +0000)
committerwolf <wolf@030b6a49-0b11-0410-94ab-b0dab22257f2>
Wed, 7 Oct 2009 17:37:57 +0000 (17:37 +0000)
This patch makes the private functions alloc_can_skb() and
alloc_can_err_skb() of the at91_can driver public and adapts all
drivers to use these. While making the patch I realized, that
the skb's are *not* setup consistently. The skb's are now setup
as shown:

skb->protocol = __constant_htons(ETH_P_CAN);
skb->pkt_type = PACKET_BROADCAST;
skb->ip_summed = CHECKSUM_UNNECESSARY;
*cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
memset(*cf, 0, sizeof(struct can_frame));

The frame is zeroed out to avoid uninitialized data to be passed
to user space.

Some drivers or library code used "htons(ETH_P_CAN)" or did not set
"pkt_type" or "ip_summed" or did not zero the fame.

Signed-off-by: Wolfgang Grandegger <wg@grandegger.com>
Acked-by: Oliver Hartkopp <oliver@hartkopp.net>
git-svn-id: svn://svn.berlios.de//socketcan/trunk@1068 030b6a49-0b11-0410-94ab-b0dab22257f2

kernel/2.6/drivers/net/can/at91_can.c
kernel/2.6/drivers/net/can/cc770/cc770.c
kernel/2.6/drivers/net/can/dev.c
kernel/2.6/drivers/net/can/esd_pci331.c
kernel/2.6/drivers/net/can/mcp251x.c
kernel/2.6/drivers/net/can/mscan/mscan.c
kernel/2.6/drivers/net/can/sja1000/sja1000.c
kernel/2.6/drivers/net/can/softing/softing_main.c
kernel/2.6/drivers/net/can/usb/ems_usb.c
kernel/2.6/include/socketcan/can/dev.h

index 28b65d75d832a04cb41b7705b516fe2838ea87f7..92696402d0a1ea3d2635f8bf19e78e5b6a413f6e 100644 (file)
@@ -221,38 +221,6 @@ static inline void set_mb_mode(const struct at91_priv *priv, unsigned int mb,
        set_mb_mode_prio(priv, mb, mode, 0);
 }
 
-static struct sk_buff *alloc_can_skb(struct net_device *dev,
-               struct can_frame **cf)
-{
-       struct sk_buff *skb;
-
-       skb = netdev_alloc_skb(dev, sizeof(struct can_frame));
-       if (unlikely(!skb))
-               return NULL;
-
-       skb->protocol = htons(ETH_P_CAN);
-       skb->ip_summed = CHECKSUM_UNNECESSARY;
-       *cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
-
-       return skb;
-}
-
-static struct sk_buff *alloc_can_err_skb(struct net_device *dev,
-               struct can_frame **cf)
-{
-       struct sk_buff *skb;
-
-       skb = alloc_can_skb(dev, cf);
-       if (unlikely(!skb))
-               return NULL;
-
-       memset(*cf, 0, sizeof(struct can_frame));
-       (*cf)->can_id = CAN_ERR_FLAG;
-       (*cf)->can_dlc = CAN_ERR_DLC;
-
-       return skb;
-}
-
 /*
  * Swtich transceiver on or off
  */
index 02c033e5ae829dade1a45c7f963c677dbc931a36..c7a324030851f3218320cfa16de10aab9f713570 100644 (file)
@@ -517,13 +517,10 @@ static void cc770_rx(struct net_device *dev, unsigned int mo, u8 ctrl1)
        u32 id;
        int i;
 
-       skb = dev_alloc_skb(sizeof(struct can_frame));
+       skb = alloc_can_skb(dev, &cf);
        if (skb == NULL)
                return;
-       skb->dev = dev;
-       skb->protocol = htons(ETH_P_CAN);
 
-       cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
        config = cc770_read_reg(priv, msgobj[mo].config);
 
        if (ctrl1 & RMTPND_SET) {
@@ -582,15 +579,9 @@ static int cc770_err(struct net_device *dev, u8 status)
 
        dev_dbg(ND2D(dev), "status interrupt (%#x)\n", status);
 
-       skb = dev_alloc_skb(sizeof(struct can_frame));
+       skb = alloc_can_err_skb(dev, &cf);
        if (skb == NULL)
                return -ENOMEM;
-       skb->dev = dev;
-       skb->protocol = htons(ETH_P_CAN);
-       cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
-       memset(cf, 0, sizeof(struct can_frame));
-       cf->can_id = CAN_ERR_FLAG;
-       cf->can_dlc = CAN_ERR_DLC;
 
        if (status & STAT_BOFF) {
                /* Disable interrupts */
index 111e7a9eb00169efc09ee4ecfbd64410dd8864b0..3be767f6e93a23bb0f141a9a2d6c3907a9c6c2c5 100644 (file)
@@ -318,7 +318,7 @@ void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
                skb->sk = srcsk;
 
                /* make settings for echo to reduce code in irq context */
-               skb->protocol = htons(ETH_P_CAN);
+               skb->protocol = __constant_htons(ETH_P_CAN);
                skb->pkt_type = PACKET_BROADCAST;
                skb->ip_summed = CHECKSUM_UNNECESSARY;
                skb->dev = dev;
@@ -397,17 +397,12 @@ void can_restart(unsigned long data)
        can_flush_echo_skb(dev);
 
        /* send restart message upstream */
-       skb = dev_alloc_skb(sizeof(struct can_frame));
+       skb = alloc_can_err_skb(dev, &cf);
        if (skb == NULL) {
                err = -ENOMEM;
                goto restart;
        }
-       skb->dev = dev;
-       skb->protocol = htons(ETH_P_CAN);
-       cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
-       memset(cf, 0, sizeof(struct can_frame));
-       cf->can_id = CAN_ERR_FLAG | CAN_ERR_RESTARTED;
-       cf->can_dlc = CAN_ERR_DLC;
+       cf->can_id |= CAN_ERR_RESTARTED;
 
        netif_rx(skb);
 
@@ -496,6 +491,39 @@ static void can_setup(struct net_device *dev)
 #endif
 }
 
+struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf)
+{
+       struct sk_buff *skb;
+
+       skb = netdev_alloc_skb(dev, sizeof(struct can_frame));
+       if (unlikely(!skb))
+               return NULL;
+
+       skb->protocol = __constant_htons(ETH_P_CAN);
+       skb->pkt_type = PACKET_BROADCAST;
+       skb->ip_summed = CHECKSUM_UNNECESSARY;
+       *cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
+       memset(*cf, 0, sizeof(struct can_frame));
+
+       return skb;
+}
+EXPORT_SYMBOL_GPL(alloc_can_skb);
+
+struct sk_buff *alloc_can_err_skb(struct net_device *dev, struct can_frame **cf)
+{
+       struct sk_buff *skb;
+
+       skb = alloc_can_skb(dev, cf);
+       if (unlikely(!skb))
+               return NULL;
+
+       (*cf)->can_id = CAN_ERR_FLAG;
+       (*cf)->can_dlc = CAN_ERR_DLC;
+
+       return skb;
+}
+EXPORT_SYMBOL_GPL(alloc_can_err_skb);
+
 /*
  * Allocate and setup space for the CAN network device
  */
index d19578c1cc692642246bfe3db17fe88a0b1a90f2..534c762cdc7affec20a9c6e3f3e7f717e8ebd84a 100644 (file)
@@ -439,7 +439,7 @@ static int esd331_create_err_frame(struct net_device *dev, canid_t idflags,
        struct can_frame *cf;
        struct sk_buff *skb;
 
-       skb = dev_alloc_skb(sizeof(*cf));
+       skb = alloc_can_err_skb(dev, &cf);
        if (unlikely(skb == NULL))
                return -ENOMEM;
 
@@ -449,13 +449,7 @@ static int esd331_create_err_frame(struct net_device *dev, canid_t idflags,
        stats = &dev->stats;
 #endif
 
-       skb->dev = dev;
-       skb->protocol = htons(ETH_P_CAN);
-       cf = (struct can_frame *)skb_put(skb, sizeof(*cf));
-       memset(cf, 0, sizeof(*cf));
-
-       cf->can_id = CAN_ERR_FLAG | idflags;
-       cf->can_dlc = CAN_ERR_DLC;
+       cf->can_id |= idflags;
        cf->data[1] = d1;
 
        netif_rx(skb);
@@ -481,15 +475,11 @@ static void esd331_irq_rx(struct net_device *dev, struct esd331_can_msg *msg,
        struct sk_buff *skb;
        int i;
 
-       skb = netdev_alloc_skb(dev, sizeof(*cfrm));
+       skb = alloc_can_skb(dev, &cfrm);
        if (unlikely(skb == NULL)) {
                stats->rx_dropped++;
                return;
        }
-       skb->protocol = htons(ETH_P_CAN);
-
-       cfrm = (struct can_frame *)skb_put(skb, sizeof(*cfrm));
-       memset(cfrm, 0, sizeof(*cfrm));
 
        if (eff) {
                cfrm->can_id = (msg->id << 16);
index 3f92d17b8d57589a8009ac06b5a1d7b496245e1f..5fa74be9ae7465d51c6f7945cdda186b2c21b8cf 100644 (file)
@@ -357,15 +357,13 @@ static void mcp251x_hw_rx(struct spi_device *spi, int buf_idx)
        struct sk_buff *skb;
        struct can_frame *frame;
 
-       skb = dev_alloc_skb(sizeof(struct can_frame));
+       skb = alloc_can_skb(priv->net, &frame);
        if (!skb) {
                dev_err(&spi->dev, "%s: out of memory for Rx'd frame\n",
                        __func__);
                priv->net->stats.rx_dropped++;
                return;
        }
-       skb->dev = priv->net;
-       frame = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
 
        if (pdata->model == CAN_MCP251X_MCP2510) {
                int i;
@@ -457,9 +455,6 @@ static void mcp251x_hw_rx(struct spi_device *spi, int buf_idx)
        priv->net->stats.rx_packets++;
        priv->net->stats.rx_bytes += frame->can_dlc;
 
-       skb->protocol = __constant_htons(ETH_P_CAN);
-       skb->pkt_type = PACKET_BROADCAST;
-       skb->ip_summed = CHECKSUM_UNNECESSARY;
        netif_rx(skb);
 }
 
@@ -808,19 +803,8 @@ static void mcp251x_irq_work_handler(struct work_struct *ws)
                        u8 eflag = mcp251x_read_reg(spi, EFLG);
 
                        /* create error frame */
-                       skb = dev_alloc_skb(sizeof(struct can_frame));
+                       skb = alloc_can_err_skb(net, &frame);
                        if (skb) {
-                               frame = (struct can_frame *)
-                                       skb_put(skb, sizeof(struct can_frame));
-                               *(unsigned long long *)&frame->data = 0ULL;
-                               frame->can_id = CAN_ERR_FLAG;
-                               frame->can_dlc = CAN_ERR_DLC;
-
-                               skb->dev = net;
-                               skb->protocol = __constant_htons(ETH_P_CAN);
-                               skb->pkt_type = PACKET_BROADCAST;
-                               skb->ip_summed = CHECKSUM_UNNECESSARY;
-
                                /* Set error frame flags based on bus state */
                                if (eflag & EFLG_TXBO) {
                                        frame->can_id |= CAN_ERR_BUSOFF;
index 38fe340565224f1053a1b3f0d1ef44748b218463..e5d5004d74185886d6f1a53800b0c733a27d535f 100644 (file)
@@ -364,7 +364,7 @@ static int mscan_rx_poll(struct net_device *dev, int *budget)
        while (npackets < quota && ((canrflg = in_8(&regs->canrflg)) &
                                    (MSCAN_RXF | MSCAN_ERR_IF))) {
 
-               skb = dev_alloc_skb(sizeof(struct can_frame));
+               skb = alloc_can_skb(dev, &frame);
                if (!skb) {
                        if (printk_ratelimit())
                                dev_notice(ND2D(dev), "packet dropped\n");
@@ -373,9 +373,6 @@ static int mscan_rx_poll(struct net_device *dev, int *budget)
                        continue;
                }
 
-               frame = (struct can_frame *)skb_put(skb, sizeof(*frame));
-               memset(frame, 0, sizeof(*frame));
-
                if (canrflg & MSCAN_RXF) {
                        can_id = in_be16(&regs->rx.idr1_0);
                        if (can_id & (1 << 3)) {
@@ -459,9 +456,6 @@ static int mscan_rx_poll(struct net_device *dev, int *budget)
                }
 
                npackets++;
-               skb->dev = dev;
-               skb->protocol = __constant_htons(ETH_P_CAN);
-               skb->ip_summed = CHECKSUM_UNNECESSARY;
                netif_receive_skb(skb);
        }
 
index 84838d4014890ed1507489bc980aac0ddbde677d..03c9b9a88f79260999cdb8188a04f3d61d8a2170 100644 (file)
@@ -308,11 +308,9 @@ static void sja1000_rx(struct net_device *dev)
        uint8_t dlc;
        int i;
 
-       skb = dev_alloc_skb(sizeof(struct can_frame));
+       skb = alloc_can_skb(dev, &cf);
        if (skb == NULL)
                return;
-       skb->dev = dev;
-       skb->protocol = htons(ETH_P_CAN);
 
        fi = priv->read_reg(priv, REG_FI);
        dlc = fi & 0x0F;
@@ -370,15 +368,9 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
        enum can_state state = priv->can.state;
        uint8_t ecc, alc;
 
-       skb = dev_alloc_skb(sizeof(struct can_frame));
+       skb = alloc_can_err_skb(dev, &cf);
        if (skb == NULL)
                return -ENOMEM;
-       skb->dev = dev;
-       skb->protocol = htons(ETH_P_CAN);
-       cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
-       memset(cf, 0, sizeof(struct can_frame));
-       cf->can_id = CAN_ERR_FLAG;
-       cf->can_dlc = CAN_ERR_DLC;
 
        if (isrc & IRQ_DOI) {
                /* data overrun interrupt */
index 8d807346f11dbbade4b2aef99de7c1fad2381be7..043ff56f19a6fbe3b3129b7f67f2b33d47381379 100644 (file)
@@ -143,16 +143,14 @@ int softing_rx(struct net_device *netdev, const struct can_frame *msg,
        ktime_t ktime)
 {
        struct sk_buff *skb;
+       struct can_frame *cf;
        int ret;
        struct net_device_stats *stats;
 
-       skb = dev_alloc_skb(sizeof(msg));
+       skb = alloc_can_skb(netdev, &cf);
        if (!skb)
                return -ENOMEM;
-       skb->dev = netdev;
-       skb->protocol = htons(ETH_P_CAN);
-       skb->ip_summed = CHECKSUM_UNNECESSARY;
-       memcpy(skb_put(skb, sizeof(*msg)), msg, sizeof(*msg));
+       memcpy(cf, msg, sizeof(*msg));
        skb->tstamp = ktime;
        ret = netif_rx(skb);
        if (ret == NET_RX_DROP) {
index 17df9d7ea9a7fc7633fdf81753c7152cde8f888f..62d0e04f40be7c80649d3e3d4df0ecbf87a2de32 100644 (file)
@@ -311,14 +311,10 @@ static void ems_usb_rx_can_msg(struct ems_usb *dev, struct ems_cpc_msg *msg)
        int i;
        struct net_device_stats *stats = &dev->netdev->stats;
 
-       skb = netdev_alloc_skb(dev->netdev, sizeof(struct can_frame));
+       skb = alloc_can_skb(dev->netdev, &cf);
        if (skb == NULL)
                return;
 
-       skb->protocol = htons(ETH_P_CAN);
-
-       cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
-
        cf->can_id = msg->msg.can_msg.id;
        cf->can_dlc = min_t(u8, msg->msg.can_msg.length, 8);
 
@@ -349,18 +345,10 @@ static void ems_usb_rx_err(struct ems_usb *dev, struct ems_cpc_msg *msg)
        struct sk_buff *skb;
        struct net_device_stats *stats = &dev->netdev->stats;
 
-       skb = netdev_alloc_skb(dev->netdev, sizeof(struct can_frame));
+       skb = alloc_can_err_skb(dev->netdev, &cf);
        if (skb == NULL)
                return;
 
-       skb->protocol = htons(ETH_P_CAN);
-
-       cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
-       memset(cf, 0, sizeof(struct can_frame));
-
-       cf->can_id = CAN_ERR_FLAG;
-       cf->can_dlc = CAN_ERR_DLC;
-
        if (msg->type == CPC_MSG_TYPE_CAN_STATE) {
                u8 state = msg->msg.can_state;
 
index 617037c3a4cbcf496c9e2d5f4aa5735cb6497f1c..9cac23748ec743ae45a2acec8f11d11d7263f3fc 100644 (file)
@@ -88,4 +88,8 @@ void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
 void can_get_echo_skb(struct net_device *dev, unsigned int idx);
 void can_free_echo_skb(struct net_device *dev, unsigned int idx);
 
+struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf);
+struct sk_buff *alloc_can_err_skb(struct net_device *dev,
+                                 struct can_frame **cf);
+
 #endif /* CAN_DEV_H */