}
}
-
-/*
- * Device has already been stopped at this point.
- */
-static void au1k_irda_net_uninit(struct net_device *dev)
-{
- dev->hard_start_xmit = NULL;
- dev->open = NULL;
- dev->stop = NULL;
- dev->do_ioctl = NULL;
- dev->get_stats = NULL;
- dev->priv = NULL;
-}
-
-
static int au1k_irda_init(void)
{
static unsigned version_printed = 0;
+ struct au1k_private *aup;
struct net_device *dev;
int err;
if (version_printed++ == 0) printk(version);
- rtnl_lock();
- dev = dev_alloc("irda%d", &err);
- if (dev) {
- dev->irq = AU1000_IRDA_RX_INT; /* TX has its own interrupt */
- dev->init = au1k_irda_net_init;
- dev->uninit = au1k_irda_net_uninit;
- err = register_netdevice(dev);
-
- if (err)
- kfree(dev);
- else
- ir_devs[0] = dev;
- printk(KERN_INFO "IrDA: Registered device %s\n", dev->name);
- }
- rtnl_unlock();
+ dev = alloc_irdadev(sizeof(struct au1k_private));
+ if (!dev)
+ return -ENOMEM;
+
+ dev->irq = AU1000_IRDA_RX_INT; /* TX has its own interrupt */
+ err = au1k_irda_net_init(dev);
+ if (err)
+ goto out;
+ err = register_netdev(dev);
+ if (err)
+ goto out1;
+ ir_devs[0] = dev;
+ printk(KERN_INFO "IrDA: Registered device %s\n", dev->name);
+ return 0;
+
+out1:
+ aup = dev->priv;
+ dma_free((void *)aup->db[0].vaddr,
+ MAX_BUF_SIZE * 2*NUM_IR_DESC);
+ dma_free((void *)aup->rx_ring[0],
+ 2 * MAX_NUM_IR_DESC*(sizeof(ring_dest_t)));
+ kfree(aup->rx_buff.head);
+out:
+ free_netdev(dev);
return err;
}
static int au1k_irda_net_init(struct net_device *dev)
{
- struct au1k_private *aup = NULL;
+ struct au1k_private *aup = dev->priv;
int i, retval = 0, err;
db_dest_t *pDB, *pDBfree;
unsigned long temp;
- dev->priv = kmalloc(sizeof(struct au1k_private), GFP_KERNEL);
- if (dev->priv == NULL) {
- retval = -ENOMEM;
- goto out;
- }
- memset(dev->priv, 0, sizeof(struct au1k_private));
- aup = dev->priv;
-
err = au1k_irda_init_iobuf(&aup->rx_buff, 14384);
if (err)
- goto out;
+ goto out1;
dev->open = au1k_irda_start;
dev->hard_start_xmit = au1k_irda_hard_xmit;
dev->do_ioctl = au1k_irda_ioctl;
dev->tx_timeout = au1k_tx_timeout;
- irda_device_setup(dev);
irda_init_max_qos_capabilies(&aup->qos);
/* The only value we must override it the baudrate */
aup->qos.min_turn_time.bits = qos_mtt_bits;
irda_qos_bits_to_value(&aup->qos);
+ retval = -ENOMEM;
/* Tx ring follows rx ring + 512 bytes */
/* we need a 1k aligned buffer */
aup->rx_ring[0] = (ring_dest_t *)
dma_alloc(2*MAX_NUM_IR_DESC*(sizeof(ring_dest_t)), &temp);
+ if (!aup->rx_ring[0])
+ goto out2;
/* allocate the data buffers */
aup->db[0].vaddr =
(void *)dma_alloc(MAX_BUF_SIZE * 2*NUM_IR_DESC, &temp);
- if (!aup->db[0].vaddr || !aup->rx_ring[0]) {
- retval = -ENOMEM;
- goto out;
- }
+ if (!aup->db[0].vaddr)
+ goto out3;
setup_hw_rings(aup, (u32)aup->rx_ring[0], (u32)aup->rx_ring[0] + 512);
}
return 0;
-out:
- if (aup->db[0].vaddr)
- dma_free((void *)aup->db[0].vaddr,
- MAX_BUF_SIZE * 2*NUM_IR_DESC);
- if (aup->rx_ring[0])
- kfree((void *)aup->rx_ring[0]);
- if (aup->rx_buff.head)
- kfree(aup->rx_buff.head);
- if (dev->priv != NULL)
- kfree(dev->priv);
- unregister_netdevice(dev);
- printk(KERN_ERR "%s: au1k_init_module failed. Returns %d\n",
- dev->name, retval);
+out3:
+ dma_free((void *)aup->rx_ring[0],
+ 2 * MAX_NUM_IR_DESC*(sizeof(ring_dest_t)));
+out2:
+ kfree(aup->rx_buff.head);
+out1:
+ printk(KERN_ERR "au1k_init_module failed. Returns %d\n", retval);
return retval;
}
struct net_device *dev = ir_devs[0];
struct au1k_private *aup = (struct au1k_private *) dev->priv;
- if (!dev) {
- printk(KERN_ERR "au1k_ircc no dev found\n");
- return;
- }
- if (aup->db[0].vaddr) {
- dma_free((void *)aup->db[0].vaddr,
- MAX_BUF_SIZE * 2*NUM_IR_DESC);
- aup->db[0].vaddr = 0;
- }
- if (aup->rx_ring[0]) {
- dma_free((void *)aup->rx_ring[0],
- 2*MAX_NUM_IR_DESC*(sizeof(ring_dest_t)));
- aup->rx_ring[0] = 0;
- }
- rtnl_lock();
- unregister_netdevice(dev);
- rtnl_unlock();
- ir_devs[0] = 0;
+ unregister_netdev(dev);
+
+ dma_free((void *)aup->db[0].vaddr,
+ MAX_BUF_SIZE * 2*NUM_IR_DESC);
+ dma_free((void *)aup->rx_ring[0],
+ 2 * MAX_NUM_IR_DESC*(sizeof(ring_dest_t)));
+ kfree(aup->rx_buff.head);
+ free_netdev(dev);
}