Commit 0cffc996 authored by Alexander Viro's avatar Alexander Viro Committed by Stephen Hemminger

[hamradio dmascc] convert embedded net_device to dynamic allocation

parent f346af6a
......@@ -242,7 +242,7 @@ struct scc_priv {
struct scc_info {
int irq_used;
int twin_serial_cfg;
struct net_device dev[2];
struct net_device *dev[2];
struct scc_priv priv[2];
struct scc_info *next;
spinlock_t register_lock; /* Per device register lock */
......@@ -310,18 +310,19 @@ static void __exit dmascc_exit(void) {
info = first;
/* Unregister devices */
for (i = 0; i < 2; i++) {
if (info->dev[i].name)
unregister_netdev(&info->dev[i]);
}
for (i = 0; i < 2; i++)
unregister_netdev(info->dev[i]);
/* Reset board */
if (info->priv[0].type == TYPE_TWIN)
outb(0, info->dev[0].base_addr + TWIN_SERIAL_CFG);
outb(0, info->dev[0]->base_addr + TWIN_SERIAL_CFG);
write_scc(&info->priv[0], R9, FHWRES);
release_region(info->dev[0].base_addr,
release_region(info->dev[0]->base_addr,
hw[info->priv[0].type].io_size);
for (i = 0; i < 2; i++)
free_netdev(info->dev[i]);
/* Free memory */
first = info->next;
kfree(info);
......@@ -443,8 +444,19 @@ static int __init dmascc_init(void) {
module_init(dmascc_init);
module_exit(dmascc_exit);
static void dev_setup(struct net_device *dev)
{
dev->type = ARPHRD_AX25;
dev->hard_header_len = 73;
dev->mtu = 1500;
dev->addr_len = 7;
dev->tx_queue_len = 64;
memcpy(dev->broadcast, ax25_broadcast, 7);
memcpy(dev->dev_addr, ax25_test, 7);
}
int __init setup_adapter(int card_base, int type, int n) {
static int __init setup_adapter(int card_base, int type, int n)
{
int i, irq, chip;
struct scc_info *info;
struct net_device *dev;
......@@ -458,13 +470,30 @@ int __init setup_adapter(int card_base, int type, int n) {
/* Allocate memory */
info = kmalloc(sizeof(struct scc_info), GFP_KERNEL | GFP_DMA);
if (!info) {
printk(KERN_ERR "dmascc: could not allocate memory for %s at %#3x\n",
printk(KERN_ERR "dmascc: "
"could not allocate memory for %s at %#3x\n",
hw[type].name, card_base);
return -1;
goto out;
}
/* Initialize what is necessary for write_scc and write_scc_data */
memset(info, 0, sizeof(struct scc_info));
info->dev[0] = alloc_netdev(0, "", dev_setup);
if (!info->dev[0]) {
printk(KERN_ERR "dmascc: "
"could not allocate memory for %s at %#3x\n",
hw[type].name, card_base);
goto out1;
}
info->dev[1] = alloc_netdev(0, "", dev_setup);
if (!info->dev[1]) {
printk(KERN_ERR "dmascc: "
"could not allocate memory for %s at %#3x\n",
hw[type].name, card_base);
goto out2;
}
spin_lock_init(&info->register_lock);
priv = &info->priv[0];
......@@ -503,7 +532,8 @@ int __init setup_adapter(int card_base, int type, int n) {
outb(0, card_base + TWIN_DMA_CFG);
inb(card_base + TWIN_CLR_TMR1);
inb(card_base + TWIN_CLR_TMR2);
outb((info->twin_serial_cfg = TWIN_EI), card_base + TWIN_SERIAL_CFG);
info->twin_serial_cfg = TWIN_EI;
outb(info->twin_serial_cfg, card_base + TWIN_SERIAL_CFG);
} else {
write_scc(priv, R15, CTSIE);
write_scc(priv, R0, RES_EXT_INT);
......@@ -530,13 +560,12 @@ int __init setup_adapter(int card_base, int type, int n) {
if (irq <= 0) {
printk(KERN_ERR "dmascc: could not find irq of %s at %#3x (irq=%d)\n",
hw[type].name, card_base, irq);
kfree(info);
return -1;
goto out3;
}
/* Set up data structures */
for (i = 0; i < 2; i++) {
dev = &info->dev[i];
dev = info->dev[i];
priv = &info->priv[i];
priv->type = type;
priv->chip = chip;
......@@ -558,9 +587,6 @@ int __init setup_adapter(int card_base, int type, int n) {
priv->param.dma = -1;
INIT_WORK(&priv->rx_work, rx_bh, priv);
dev->priv = priv;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
if (sizeof(dev->name) == sizeof(char *)) dev->name = priv->name;
#endif
sprintf(dev->name, "dmascc%i", 2*n+i);
SET_MODULE_OWNER(dev);
dev->base_addr = card_base;
......@@ -573,18 +599,16 @@ int __init setup_adapter(int card_base, int type, int n) {
dev->hard_header = ax25_encapsulate;
dev->rebuild_header = ax25_rebuild_header;
dev->set_mac_address = scc_set_mac_address;
dev->type = ARPHRD_AX25;
dev->hard_header_len = 73;
dev->mtu = 1500;
dev->addr_len = 7;
dev->tx_queue_len = 64;
memcpy(dev->broadcast, ax25_broadcast, 7);
memcpy(dev->dev_addr, ax25_test, 7);
rtnl_lock();
if (register_netdevice(dev)) {
printk(KERN_ERR "dmascc: could not register %s\n", dev->name);
}
rtnl_unlock();
if (register_netdev(info->dev[0])) {
printk(KERN_ERR "dmascc: could not register %s\n",
info->dev[0]->name);
goto out3;
}
if (register_netdev(info->dev[1])) {
printk(KERN_ERR "dmascc: could not register %s\n",
info->dev[1]->name);
goto out4;
}
......@@ -593,6 +617,20 @@ int __init setup_adapter(int card_base, int type, int n) {
printk(KERN_INFO "dmascc: found %s (%s) at %#3x, irq %d\n", hw[type].name,
chipnames[chip], card_base, irq);
return 0;
out4:
unregister_netdev(info->dev[0]);
out3:
if (info->priv[0].type == TYPE_TWIN)
outb(0, info->dev[0]->base_addr + TWIN_SERIAL_CFG);
write_scc(&info->priv[0], R9, FHWRES);
free_netdev(info->dev[1]);
out2:
free_netdev(info->dev[0]);
out1:
kfree(info);
out:
return -1;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment