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 { ...@@ -242,7 +242,7 @@ struct scc_priv {
struct scc_info { struct scc_info {
int irq_used; int irq_used;
int twin_serial_cfg; int twin_serial_cfg;
struct net_device dev[2]; struct net_device *dev[2];
struct scc_priv priv[2]; struct scc_priv priv[2];
struct scc_info *next; struct scc_info *next;
spinlock_t register_lock; /* Per device register lock */ spinlock_t register_lock; /* Per device register lock */
...@@ -310,18 +310,19 @@ static void __exit dmascc_exit(void) { ...@@ -310,18 +310,19 @@ static void __exit dmascc_exit(void) {
info = first; info = first;
/* Unregister devices */ /* Unregister devices */
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++)
if (info->dev[i].name) unregister_netdev(info->dev[i]);
unregister_netdev(&info->dev[i]);
}
/* Reset board */ /* Reset board */
if (info->priv[0].type == TYPE_TWIN) 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); 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); hw[info->priv[0].type].io_size);
for (i = 0; i < 2; i++)
free_netdev(info->dev[i]);
/* Free memory */ /* Free memory */
first = info->next; first = info->next;
kfree(info); kfree(info);
...@@ -443,8 +444,19 @@ static int __init dmascc_init(void) { ...@@ -443,8 +444,19 @@ static int __init dmascc_init(void) {
module_init(dmascc_init); module_init(dmascc_init);
module_exit(dmascc_exit); 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; int i, irq, chip;
struct scc_info *info; struct scc_info *info;
struct net_device *dev; struct net_device *dev;
...@@ -458,13 +470,30 @@ int __init setup_adapter(int card_base, int type, int n) { ...@@ -458,13 +470,30 @@ int __init setup_adapter(int card_base, int type, int n) {
/* Allocate memory */ /* Allocate memory */
info = kmalloc(sizeof(struct scc_info), GFP_KERNEL | GFP_DMA); info = kmalloc(sizeof(struct scc_info), GFP_KERNEL | GFP_DMA);
if (!info) { 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); hw[type].name, card_base);
return -1; goto out;
} }
/* Initialize what is necessary for write_scc and write_scc_data */ /* Initialize what is necessary for write_scc and write_scc_data */
memset(info, 0, sizeof(struct scc_info)); 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); spin_lock_init(&info->register_lock);
priv = &info->priv[0]; priv = &info->priv[0];
...@@ -503,7 +532,8 @@ int __init setup_adapter(int card_base, int type, int n) { ...@@ -503,7 +532,8 @@ int __init setup_adapter(int card_base, int type, int n) {
outb(0, card_base + TWIN_DMA_CFG); outb(0, card_base + TWIN_DMA_CFG);
inb(card_base + TWIN_CLR_TMR1); inb(card_base + TWIN_CLR_TMR1);
inb(card_base + TWIN_CLR_TMR2); 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 { } else {
write_scc(priv, R15, CTSIE); write_scc(priv, R15, CTSIE);
write_scc(priv, R0, RES_EXT_INT); write_scc(priv, R0, RES_EXT_INT);
...@@ -530,13 +560,12 @@ int __init setup_adapter(int card_base, int type, int n) { ...@@ -530,13 +560,12 @@ int __init setup_adapter(int card_base, int type, int n) {
if (irq <= 0) { if (irq <= 0) {
printk(KERN_ERR "dmascc: could not find irq of %s at %#3x (irq=%d)\n", printk(KERN_ERR "dmascc: could not find irq of %s at %#3x (irq=%d)\n",
hw[type].name, card_base, irq); hw[type].name, card_base, irq);
kfree(info); goto out3;
return -1;
} }
/* Set up data structures */ /* Set up data structures */
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
dev = &info->dev[i]; dev = info->dev[i];
priv = &info->priv[i]; priv = &info->priv[i];
priv->type = type; priv->type = type;
priv->chip = chip; priv->chip = chip;
...@@ -558,9 +587,6 @@ int __init setup_adapter(int card_base, int type, int n) { ...@@ -558,9 +587,6 @@ int __init setup_adapter(int card_base, int type, int n) {
priv->param.dma = -1; priv->param.dma = -1;
INIT_WORK(&priv->rx_work, rx_bh, priv); INIT_WORK(&priv->rx_work, rx_bh, priv);
dev->priv = 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); sprintf(dev->name, "dmascc%i", 2*n+i);
SET_MODULE_OWNER(dev); SET_MODULE_OWNER(dev);
dev->base_addr = card_base; dev->base_addr = card_base;
...@@ -573,18 +599,16 @@ int __init setup_adapter(int card_base, int type, int n) { ...@@ -573,18 +599,16 @@ int __init setup_adapter(int card_base, int type, int n) {
dev->hard_header = ax25_encapsulate; dev->hard_header = ax25_encapsulate;
dev->rebuild_header = ax25_rebuild_header; dev->rebuild_header = ax25_rebuild_header;
dev->set_mac_address = scc_set_mac_address; 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) { ...@@ -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, printk(KERN_INFO "dmascc: found %s (%s) at %#3x, irq %d\n", hw[type].name,
chipnames[chip], card_base, irq); chipnames[chip], card_base, irq);
return 0; 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