当前位置:  技术问答>linux和unix

写一个以太网驱动,在hard_start_xmit中访问dev->priv中的成员,出现崩溃

    来源: 互联网  发布时间:2016-12-05

    本文导语:  struct net_device *veth_devs[VETH_NUM]; static int veth_open(struct net_device *dev) { veth_private_s *vep ; vep = (veth_private_s *)dev->priv; vep->dev = dev; /*Remember dev in veth_private_s*/ queue_delayed_work(vep->rx_poll, &vep->rx_poll_task, POLL_SPEED)...

struct net_device *veth_devs[VETH_NUM];

static int
veth_open(struct net_device *dev)
{
veth_private_s *vep ;

vep = (veth_private_s *)dev->priv;

vep->dev = dev; /*Remember dev in veth_private_s*/

queue_delayed_work(vep->rx_poll, &vep->rx_poll_task, POLL_SPEED);

netif_start_queue(dev);

printk(KERN_ALERT "%s: %s rn", dev->name, __FUNCTION__);

return 0; /* Always succeed */
}

static int
veth_close(struct net_device *dev)
{
veth_private_s *vep ;

vep = (veth_private_s *)dev->priv;

netif_stop_queue(dev);

flush_workqueue(vep->rx_poll);
cancel_delayed_work(&vep->rx_poll_task); 

printk(KERN_ALERT "%s: %s rn", dev->name, __FUNCTION__);

return 0;
}

#if 1
static int
veth_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
int i;
char *p;
char tmp[4];

veth_private_s *vep = (veth_private_s *)dev->priv;

printk(KERN_ALERT "%s: %s  rn", dev->name, __FUNCTION__);

vep->rx_buff = (unsigned char *)kmalloc(VETH_RX_BUFFSIZE, GFP_KERNEL);

memset(vep->rx_buff, 0, VETH_RX_BUFFSIZE);

memcpy(vep->rx_buff, skb->data, skb->len); //这里出现崩溃,系统重启
#if 0
p = vep->rx_buff;
//p = skb->data;

if(skb->len > 0){
printk(KERN_ALERT "%s: veth_start_xmit len=%d rn", dev->name, skb->len);

for(i=0; ilen; i++){
if(i%20 == 0)
printk(KERN_ALERT "rn");
else{
memset(tmp, 0, 4);
sprintf(tmp, "%d", vep->rx_buff[i]);
printk(KERN_ALERT "%d,%s,%d ", i, tmp, vep->rx_buff[i]);
}
}
printk("rn");
}
#endif

dev_kfree_skb(skb);

return 0; /* Our simple device can not fail */
}
#endif

static void veth_rx_poll(struct work_struct *work)
{
veth_private_s *vep = 
container_of(work, veth_private_s, rx_poll_task.work);

struct net_device *dev = vep->dev;

printk(KERN_ALERT "%s: %s rn", dev->name, __FUNCTION__);

//dev_kfree_skb(skb);

queue_delayed_work(vep->rx_poll, &vep->rx_poll_task, POLL_SPEED);
}

void veth_init(struct net_device *dev)
{
veth_private_s *vep;
bd_t *bd;
int i;
static char mc_addr4 = 0x0;
static char mc_addr5 = 0x0;

bd = (bd_t *)__res;

/*
* Make the usual checks: check_region(), probe irq, ...  -ENODEV
* should be returned if no device found.  No resource should be
* grabbed: this is done on open(). 
*/

ether_setup(dev); /* assign some of the fields */

dev->open = veth_open;
dev->stop = veth_close;
dev->hard_start_xmit = veth_start_xmit;
dev->watchdog_timeo  = TX_TIMEOUT;

/*
dev->set_config = snull_config;
dev->do_ioctl = snull_ioctl;
dev->get_stats = snull_stats;
dev->change_mtu = snull_change_mtu;  
dev->rebuild_header = snull_rebuild_header;
dev->hard_header = snull_header;
dev->tx_timeout = snull_tx_timeout;
dev->watchdog_timeo = timeout;
*/

/* keep the default flags, just add NOARP */
dev->flags |= IFF_NOARP;
dev->features |= NETIF_F_NO_CSUM;
dev->hard_header_cache = NULL;      /* Disable caching */

vep = netdev_priv(dev);
//vep->rx_buff = (unsigned char *)kmalloc(VETH_RX_BUFFSIZE, GFP_KERNEL);

memset(vep, 0, sizeof(veth_private_s));
spin_lock_init(&vep->lock);

vep->rx_poll = create_singlethread_workqueue("rx_poll");
INIT_DELAYED_WORK(&vep->rx_poll_task, veth_rx_poll);

for (i=5; i>=0; i--)
dev->dev_addr[i] = bd->bi_enetaddr[i];

mc_addr4++;
mc_addr5++;

dev->dev_addr[4] += mc_addr4;
dev->dev_addr[5] += mc_addr5;
}

static void __exit veth_exit_module(void)
{
    int i;

    for (i=0; i

    
 
 
 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3