当前位置: 技术问答>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
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