diff options
author | Wolfgang Grandegger <wg@grandegger.com> | 2009-10-20 03:08:01 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-10-20 03:08:01 -0400 |
commit | 7b6856a0296a8f187bb88ba31fa83a08abba7966 (patch) | |
tree | 0afbcc9291eeb368e4e4616b6eed9062df646de0 /drivers/net/can | |
parent | 0eae750e6019a93643063924209c1daf9cb9b4a7 (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.c | 32 | ||||
-rw-r--r-- | drivers/net/can/dev.c | 42 | ||||
-rw-r--r-- | drivers/net/can/sja1000/sja1000.c | 12 | ||||
-rw-r--r-- | drivers/net/can/ti_hecc.c | 17 | ||||
-rw-r--r-- | drivers/net/can/usb/ems_usb.c | 16 |
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 | ||
224 | static 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 | |||
240 | static 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 | ||
447 | struct 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 | } | ||
463 | EXPORT_SYMBOL_GPL(alloc_can_skb); | ||
464 | |||
465 | struct 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 | } | ||
478 | EXPORT_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 | ||