写一个以太网驱动,在hard_start_xmit中访问dev->priv中的成员,出现崩溃
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 \r\n", 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 \r\n", 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 \r\n", 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 \r\n", dev->name, skb->len);
for(i=0; i<skb->len; i++){
if(i%20 == 0)
printk(KERN_ALERT "\r\n");
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("\r\n");
}
#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 \r\n", 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)