"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "drivers/net/can/dev.c" between
linux-3.16.62.tar.xz and linux-3.16.63.tar.xz

About: The full source of the Linux kernel 3.16.x (longterm stable)

dev.c  (linux-3.16.62.tar.xz):dev.c  (linux-3.16.63.tar.xz)
skipping to change at line 425 skipping to change at line 425
/* save this skb for tx interrupt echo handling */ /* save this skb for tx interrupt echo handling */
priv->echo_skb[idx] = skb; priv->echo_skb[idx] = skb;
} else { } else {
/* locking problem with netif_stop_queue() ?? */ /* locking problem with netif_stop_queue() ?? */
netdev_err(dev, "%s: BUG! echo_skb is occupied!\n", __func__); netdev_err(dev, "%s: BUG! echo_skb is occupied!\n", __func__);
kfree_skb(skb); kfree_skb(skb);
} }
} }
EXPORT_SYMBOL_GPL(can_put_echo_skb); EXPORT_SYMBOL_GPL(can_put_echo_skb);
struct sk_buff *__can_get_echo_skb(struct net_device *dev, unsigned int idx, u8
*len_ptr)
{
struct can_priv *priv = netdev_priv(dev);
struct sk_buff *skb = priv->echo_skb[idx];
struct canfd_frame *cf;
if (idx >= priv->echo_skb_max) {
netdev_err(dev, "%s: BUG! Trying to access can_priv::echo_skb out
of bounds (%u/max %u)\n",
__func__, idx, priv->echo_skb_max);
return NULL;
}
if (!skb) {
netdev_err(dev, "%s: BUG! Trying to echo non existing skb: can_pr
iv::echo_skb[%u]\n",
__func__, idx);
return NULL;
}
/* Using "struct canfd_frame::len" for the frame
* length is supported on both CAN and CANFD frames.
*/
cf = (struct canfd_frame *)skb->data;
*len_ptr = cf->len;
priv->echo_skb[idx] = NULL;
return skb;
}
/* /*
* Get the skb from the stack and loop it back locally * Get the skb from the stack and loop it back locally
* *
* The function is typically called when the TX done interrupt * The function is typically called when the TX done interrupt
* is handled in the device driver. The driver must protect * is handled in the device driver. The driver must protect
* access to priv->echo_skb, if necessary. * access to priv->echo_skb, if necessary.
*/ */
unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx) unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx)
{ {
struct can_priv *priv = netdev_priv(dev); struct sk_buff *skb;
u8 len;
BUG_ON(idx >= priv->echo_skb_max); skb = __can_get_echo_skb(dev, idx, &len);
if (!skb)
return 0;
if (priv->echo_skb[idx]) { netif_rx(skb);
struct sk_buff *skb = priv->echo_skb[idx];
struct can_frame *cf = (struct can_frame *)skb->data;
u8 dlc = cf->can_dlc;
netif_rx(priv->echo_skb[idx]);
priv->echo_skb[idx] = NULL;
return dlc;
}
return 0; return len;
} }
EXPORT_SYMBOL_GPL(can_get_echo_skb); EXPORT_SYMBOL_GPL(can_get_echo_skb);
/* /*
* Remove the skb from the stack and free it. * Remove the skb from the stack and free it.
* *
* The function is typically called when TX failed. * The function is typically called when TX failed.
*/ */
void can_free_echo_skb(struct net_device *dev, unsigned int idx) void can_free_echo_skb(struct net_device *dev, unsigned int idx)
{ {
 End of changes. 5 change blocks. 
13 lines changed or deleted 38 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)