aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/can
diff options
context:
space:
mode:
authorWolfgang Grandegger <wg@grandegger.com>2009-10-20 03:08:01 -0400
committerDavid S. Miller <davem@davemloft.net>2009-10-20 03:08:01 -0400
commit7b6856a0296a8f187bb88ba31fa83a08abba7966 (patch)
tree0afbcc9291eeb368e4e4616b6eed9062df646de0 /drivers/net/can
parent0eae750e6019a93643063924209c1daf9cb9b4a7 (diff)
can: provide library functions for skb allocation
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. It's now done as shown below: skb->protocol = 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 did not set "pkt_type" or "ip_summed". Also, "__constant_htons()" should not be used for runtime invocations, as pointed out by David Miller. Signed-off-by: Wolfgang Grandegger <wg@grandegger.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/can')
-rw-r--r--drivers/net/can/at91_can.c32
-rw-r--r--drivers/net/can/dev.c42
-rw-r--r--drivers/net/can/sja1000/sja1000.c12
-rw-r--r--drivers/net/can/ti_hecc.c17
-rw-r--r--drivers/net/can/usb/ems_usb.c16
5 files changed, 43 insertions, 76 deletions
diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index b13fd911413..cbe3fce53e3 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -221,38 +221,6 @@ static inline void set_mb_mode(const struct at91_priv *priv, unsigned int mb,
221 set_mb_mode_prio(priv, mb, mode, 0); 221 set_mb_mode_prio(priv, mb, mode, 0);
222} 222}
223 223
224static struct sk_buff *alloc_can_skb(struct net_device *dev,
225 struct can_frame **cf)
226{
227 struct sk_buff *skb;
228
229 skb = netdev_alloc_skb(dev, sizeof(struct can_frame));
230 if (unlikely(!skb))
231 return NULL;
232
233 skb->protocol = htons(ETH_P_CAN);
234 skb->ip_summed = CHECKSUM_UNNECESSARY;
235 *cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
236
237 return skb;
238}
239
240static struct sk_buff *alloc_can_err_skb(struct net_device *dev,
241 struct can_frame **cf)
242{
243 struct sk_buff *skb;
244
245 skb = alloc_can_skb(dev, cf);
246 if (unlikely(!skb))
247 return NULL;
248
249 memset(*cf, 0, sizeof(struct can_frame));
250 (*cf)->can_id = CAN_ERR_FLAG;
251 (*cf)->can_dlc = CAN_ERR_DLC;
252
253 return skb;
254}
255
256/* 224/*
257 * Swtich transceiver on or off 225 * Swtich transceiver on or off
258 */ 226 */
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
index 39b99f57c26..c3db111d2ff 100644
--- a/drivers/net/can/dev.c
+++ b/drivers/net/can/dev.c
@@ -366,17 +366,12 @@ void can_restart(unsigned long data)
366 can_flush_echo_skb(dev); 366 can_flush_echo_skb(dev);
367 367
368 /* send restart message upstream */ 368 /* send restart message upstream */
369 skb = dev_alloc_skb(sizeof(struct can_frame)); 369 skb = alloc_can_err_skb(dev, &cf);
370 if (skb == NULL) { 370 if (skb == NULL) {
371 err = -ENOMEM; 371 err = -ENOMEM;
372 goto restart; 372 goto restart;
373 } 373 }
374 skb->dev = dev; 374 cf->can_id |= CAN_ERR_RESTARTED;
375 skb->protocol = htons(ETH_P_CAN);
376 cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
377 memset(cf, 0, sizeof(struct can_frame));
378 cf->can_id = CAN_ERR_FLAG | CAN_ERR_RESTARTED;
379 cf->can_dlc = CAN_ERR_DLC;
380 375
381 netif_rx(skb); 376 netif_rx(skb);
382 377
@@ -449,6 +444,39 @@ static void can_setup(struct net_device *dev)
449 dev->features = NETIF_F_NO_CSUM; 444 dev->features = NETIF_F_NO_CSUM;
450} 445}
451 446
447struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf)
448{
449 struct sk_buff *skb;
450
451 skb = netdev_alloc_skb(dev, sizeof(struct can_frame));
452 if (unlikely(!skb))
453 return NULL;
454
455 skb->protocol = htons(ETH_P_CAN);
456 skb->pkt_type = PACKET_BROADCAST;
457 skb->ip_summed = CHECKSUM_UNNECESSARY;
458 *cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
459 memset(*cf, 0, sizeof(struct can_frame));
460
461 return skb;
462}
463EXPORT_SYMBOL_GPL(alloc_can_skb);
464
465struct sk_buff *alloc_can_err_skb(struct net_device *dev, struct can_frame **cf)
466{
467 struct sk_buff *skb;
468
469 skb = alloc_can_skb(dev, cf);
470 if (unlikely(!skb))
471 return NULL;
472
473 (*cf)->can_id = CAN_ERR_FLAG;
474 (*cf)->can_dlc = CAN_ERR_DLC;
475
476 return skb;
477}
478EXPORT_SYMBOL_GPL(alloc_can_err_skb);
479
452/* 480/*
453 * Allocate and setup space for the CAN network device 481 * Allocate and setup space for the CAN network device
454 */ 482 */
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
index 96d8be4253f..1a9c5958bbd 100644
--- a/drivers/net/can/sja1000/sja1000.c
+++ b/drivers/net/can/sja1000/sja1000.c
@@ -296,11 +296,9 @@ static void sja1000_rx(struct net_device *dev)
296 uint8_t dlc; 296 uint8_t dlc;
297 int i; 297 int i;
298 298
299 skb = dev_alloc_skb(sizeof(struct can_frame)); 299 skb = alloc_can_skb(dev, &cf);
300 if (skb == NULL) 300 if (skb == NULL)
301 return; 301 return;
302 skb->dev = dev;
303 skb->protocol = htons(ETH_P_CAN);
304 302
305 fi = priv->read_reg(priv, REG_FI); 303 fi = priv->read_reg(priv, REG_FI);
306 dlc = fi & 0x0F; 304 dlc = fi & 0x0F;
@@ -351,15 +349,9 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
351 enum can_state state = priv->can.state; 349 enum can_state state = priv->can.state;
352 uint8_t ecc, alc; 350 uint8_t ecc, alc;
353 351
354 skb = dev_alloc_skb(sizeof(struct can_frame)); 352 skb = alloc_can_err_skb(dev, &cf);
355 if (skb == NULL) 353 if (skb == NULL)
356 return -ENOMEM; 354 return -ENOMEM;
357 skb->dev = dev;
358 skb->protocol = htons(ETH_P_CAN);
359 cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
360 memset(cf, 0, sizeof(struct can_frame));
361 cf->can_id = CAN_ERR_FLAG;
362 cf->can_dlc = CAN_ERR_DLC;
363 355
364 if (isrc & IRQ_DOI) { 356 if (isrc & IRQ_DOI) {
365 /* data overrun interrupt */ 357 /* data overrun interrupt */
diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c
index 23a7128e4eb..07e8016b17e 100644
--- a/drivers/net/can/ti_hecc.c
+++ b/drivers/net/can/ti_hecc.c
@@ -535,18 +535,15 @@ static int ti_hecc_rx_pkt(struct ti_hecc_priv *priv, int mbxno)
535 u32 data, mbx_mask; 535 u32 data, mbx_mask;
536 unsigned long flags; 536 unsigned long flags;
537 537
538 skb = netdev_alloc_skb(priv->ndev, sizeof(struct can_frame)); 538 skb = alloc_can_skb(priv->ndev, &cf);
539 if (!skb) { 539 if (!skb) {
540 if (printk_ratelimit()) 540 if (printk_ratelimit())
541 dev_err(priv->ndev->dev.parent, 541 dev_err(priv->ndev->dev.parent,
542 "ti_hecc_rx_pkt: netdev_alloc_skb() failed\n"); 542 "ti_hecc_rx_pkt: alloc_can_skb() failed\n");
543 return -ENOMEM; 543 return -ENOMEM;
544 } 544 }
545 skb->protocol = __constant_htons(ETH_P_CAN);
546 skb->ip_summed = CHECKSUM_UNNECESSARY;
547 545
548 mbx_mask = BIT(mbxno); 546 mbx_mask = BIT(mbxno);
549 cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
550 data = hecc_read_mbx(priv, mbxno, HECC_CANMID); 547 data = hecc_read_mbx(priv, mbxno, HECC_CANMID);
551 if (data & HECC_CANMID_IDE) 548 if (data & HECC_CANMID_IDE)
552 cf->can_id = (data & CAN_EFF_MASK) | CAN_EFF_FLAG; 549 cf->can_id = (data & CAN_EFF_MASK) | CAN_EFF_FLAG;
@@ -656,19 +653,13 @@ static int ti_hecc_error(struct net_device *ndev, int int_status,
656 struct sk_buff *skb; 653 struct sk_buff *skb;
657 654
658 /* propogate the error condition to the can stack */ 655 /* propogate the error condition to the can stack */
659 skb = netdev_alloc_skb(ndev, sizeof(struct can_frame)); 656 skb = alloc_can_err_skb(ndev, &cf);
660 if (!skb) { 657 if (!skb) {
661 if (printk_ratelimit()) 658 if (printk_ratelimit())
662 dev_err(priv->ndev->dev.parent, 659 dev_err(priv->ndev->dev.parent,
663 "ti_hecc_error: netdev_alloc_skb() failed\n"); 660 "ti_hecc_error: alloc_can_err_skb() failed\n");
664 return -ENOMEM; 661 return -ENOMEM;
665 } 662 }
666 skb->protocol = __constant_htons(ETH_P_CAN);
667 skb->ip_summed = CHECKSUM_UNNECESSARY;
668 cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
669 memset(cf, 0, sizeof(struct can_frame));
670 cf->can_id = CAN_ERR_FLAG;
671 cf->can_dlc = CAN_ERR_DLC;
672 663
673 if (int_status & HECC_CANGIF_WLIF) { /* warning level int */ 664 if (int_status & HECC_CANGIF_WLIF) { /* warning level int */
674 if ((int_status & HECC_CANGIF_BOIF) == 0) { 665 if ((int_status & HECC_CANGIF_BOIF) == 0) {
diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c
index a65f56a9cd3..3685f3e42d1 100644
--- a/drivers/net/can/usb/ems_usb.c
+++ b/drivers/net/can/usb/ems_usb.c
@@ -311,14 +311,10 @@ static void ems_usb_rx_can_msg(struct ems_usb *dev, struct ems_cpc_msg *msg)
311 int i; 311 int i;
312 struct net_device_stats *stats = &dev->netdev->stats; 312 struct net_device_stats *stats = &dev->netdev->stats;
313 313
314 skb = netdev_alloc_skb(dev->netdev, sizeof(struct can_frame)); 314 skb = alloc_can_skb(dev->netdev, &cf);
315 if (skb == NULL) 315 if (skb == NULL)
316 return; 316 return;
317 317
318 skb->protocol = htons(ETH_P_CAN);
319
320 cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
321
322 cf->can_id = msg->msg.can_msg.id; 318 cf->can_id = msg->msg.can_msg.id;
323 cf->can_dlc = min_t(u8, msg->msg.can_msg.length, 8); 319 cf->can_dlc = min_t(u8, msg->msg.can_msg.length, 8);
324 320
@@ -346,18 +342,10 @@ static void ems_usb_rx_err(struct ems_usb *dev, struct ems_cpc_msg *msg)
346 struct sk_buff *skb; 342 struct sk_buff *skb;
347 struct net_device_stats *stats = &dev->netdev->stats; 343 struct net_device_stats *stats = &dev->netdev->stats;
348 344
349 skb = netdev_alloc_skb(dev->netdev, sizeof(struct can_frame)); 345 skb = alloc_can_err_skb(dev->netdev, &cf);
350 if (skb == NULL) 346 if (skb == NULL)
351 return; 347 return;
352 348
353 skb->protocol = htons(ETH_P_CAN);
354
355 cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
356 memset(cf, 0, sizeof(struct can_frame));
357
358 cf->can_id = CAN_ERR_FLAG;
359 cf->can_dlc = CAN_ERR_DLC;
360
361 if (msg->type == CPC_MSG_TYPE_CAN_STATE) { 349 if (msg->type == CPC_MSG_TYPE_CAN_STATE) {
362 u8 state = msg->msg.can_state; 350 u8 state = msg->msg.can_state;
363 351