Commit 51845e3a authored by Stephen Hemminger's avatar Stephen Hemminger

[NET]: Convert SDLA to new initialization.

Based on Al viro's NE10-sdla
* switched sdla to dynamic allocation
* sdla: embedded ->priv
* sdla: fixed resource leaks on failure exits
Additionally fixes.
* get rid of cli/sti
* get rid of MOD/INC

Builds and probes, but don't have the hardware.
Driver has never built on 2.6 before this.
parent 775b2356
...@@ -98,6 +98,9 @@ extern int macsonic_probe(struct net_device *dev); ...@@ -98,6 +98,9 @@ extern int macsonic_probe(struct net_device *dev);
extern int mac8390_probe(struct net_device *dev); extern int mac8390_probe(struct net_device *dev);
extern int mac89x0_probe(struct net_device *dev); extern int mac89x0_probe(struct net_device *dev);
extern int mc32_probe(struct net_device *dev); extern int mc32_probe(struct net_device *dev);
#ifdef CONFIG_SDLA
extern struct net_device *sdla_init(void);
#endif
/* Detachable devices ("pocket adaptors") */ /* Detachable devices ("pocket adaptors") */
extern int de620_probe(struct net_device *); extern int de620_probe(struct net_device *);
...@@ -385,20 +388,12 @@ static int __init ethif_probe(struct net_device *dev) ...@@ -385,20 +388,12 @@ static int __init ethif_probe(struct net_device *dev)
/* Statically configured drivers -- order matters here. */ /* Statically configured drivers -- order matters here. */
void probe_old_netdevs(void) void probe_old_netdevs(void)
{ {
}
#ifdef CONFIG_SDLA #ifdef CONFIG_SDLA
extern int sdla_init(struct net_device *); sdla_init();
static struct net_device sdla0_dev = {
.name = "sdla0",
.next = NEXT_DEV,
.init = sdla_init,
};
#undef NEXT_DEV
#define NEXT_DEV (&sdla0_dev)
#endif #endif
}
#if defined(CONFIG_LTPC) #if defined(CONFIG_LTPC)
extern int ltpc_probe(struct net_device *); extern int ltpc_probe(struct net_device *);
static struct net_device dev_ltpc = { static struct net_device dev_ltpc = {
......
...@@ -71,6 +71,8 @@ static unsigned int valid_mem[] __initdata = { ...@@ -71,6 +71,8 @@ static unsigned int valid_mem[] __initdata = {
0xD0000, 0xD2000, 0xD4000, 0xD6000, 0xD8000, 0xDA000, 0xDC000, 0xDE000, 0xD0000, 0xD2000, 0xD4000, 0xD6000, 0xD8000, 0xDA000, 0xDC000, 0xDE000,
0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000, 0xEE000}; 0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000, 0xEE000};
static spinlock_t sdla_lock = SPIN_LOCK_UNLOCKED;
/********************************************************* /*********************************************************
* *
* these are the core routines that access the card itself * these are the core routines that access the card itself
...@@ -79,10 +81,10 @@ static unsigned int valid_mem[] __initdata = { ...@@ -79,10 +81,10 @@ static unsigned int valid_mem[] __initdata = {
#define SDLA_WINDOW(dev,addr) outb((((addr) >> 13) & 0x1F), (dev)->base_addr + SDLA_REG_Z80_WINDOW) #define SDLA_WINDOW(dev,addr) outb((((addr) >> 13) & 0x1F), (dev)->base_addr + SDLA_REG_Z80_WINDOW)
static void sdla_read(struct net_device *dev, int addr, void *buf, short len) static void __sdla_read(struct net_device *dev, int addr, void *buf, short len)
{ {
unsigned long flags; char *temp;
char *temp, *base; const void *base;
int offset, bytes; int offset, bytes;
temp = buf; temp = buf;
...@@ -90,13 +92,10 @@ static void sdla_read(struct net_device *dev, int addr, void *buf, short len) ...@@ -90,13 +92,10 @@ static void sdla_read(struct net_device *dev, int addr, void *buf, short len)
{ {
offset = addr & SDLA_ADDR_MASK; offset = addr & SDLA_ADDR_MASK;
bytes = offset + len > SDLA_WINDOW_SIZE ? SDLA_WINDOW_SIZE - offset : len; bytes = offset + len > SDLA_WINDOW_SIZE ? SDLA_WINDOW_SIZE - offset : len;
base = (void *) (dev->mem_start + offset); base = (const void *) (dev->mem_start + offset);
save_flags(flags);
cli();
SDLA_WINDOW(dev, addr); SDLA_WINDOW(dev, addr);
memcpy(temp, base, bytes); memcpy(temp, base, bytes);
restore_flags(flags);
addr += bytes; addr += bytes;
temp += bytes; temp += bytes;
...@@ -104,10 +103,19 @@ static void sdla_read(struct net_device *dev, int addr, void *buf, short len) ...@@ -104,10 +103,19 @@ static void sdla_read(struct net_device *dev, int addr, void *buf, short len)
} }
} }
static void sdla_write(struct net_device *dev, int addr, void *buf, short len) static void sdla_read(struct net_device *dev, int addr, void *buf, short len)
{ {
unsigned long flags; unsigned long flags;
char *temp, *base; spin_lock_irqsave(&sdla_lock, flags);
__sdla_read(dev, addr, buf, len);
spin_unlock_irqrestore(&sdla_lock, flags);
}
static void __sdla_write(struct net_device *dev, int addr,
const void *buf, short len)
{
const char *temp;
void *base;
int offset, bytes; int offset, bytes;
temp = buf; temp = buf;
...@@ -116,17 +124,27 @@ static void sdla_write(struct net_device *dev, int addr, void *buf, short len) ...@@ -116,17 +124,27 @@ static void sdla_write(struct net_device *dev, int addr, void *buf, short len)
offset = addr & SDLA_ADDR_MASK; offset = addr & SDLA_ADDR_MASK;
bytes = offset + len > SDLA_WINDOW_SIZE ? SDLA_WINDOW_SIZE - offset : len; bytes = offset + len > SDLA_WINDOW_SIZE ? SDLA_WINDOW_SIZE - offset : len;
base = (void *) (dev->mem_start + offset); base = (void *) (dev->mem_start + offset);
save_flags(flags);
cli();
SDLA_WINDOW(dev, addr); SDLA_WINDOW(dev, addr);
memcpy(base, temp, bytes); memcpy(base, temp, bytes);
restore_flags(flags);
addr += bytes; addr += bytes;
temp += bytes; temp += bytes;
len -= bytes; len -= bytes;
} }
} }
static void sdla_write(struct net_device *dev, int addr,
const void *buf, short len)
{
unsigned long flags;
spin_lock_irqsave(&sdla_lock, flags);
__sdla_write(dev, addr, buf, len);
spin_unlock_irqrestore(&sdla_lock, flags);
}
static void sdla_clear(struct net_device *dev) static void sdla_clear(struct net_device *dev)
{ {
unsigned long flags; unsigned long flags;
...@@ -138,8 +156,7 @@ static void sdla_clear(struct net_device *dev) ...@@ -138,8 +156,7 @@ static void sdla_clear(struct net_device *dev)
bytes = SDLA_WINDOW_SIZE; bytes = SDLA_WINDOW_SIZE;
base = (void *) dev->mem_start; base = (void *) dev->mem_start;
save_flags(flags); spin_lock_irqsave(&sdla_lock, flags);
cli();
while(len) while(len)
{ {
SDLA_WINDOW(dev, addr); SDLA_WINDOW(dev, addr);
...@@ -148,7 +165,8 @@ static void sdla_clear(struct net_device *dev) ...@@ -148,7 +165,8 @@ static void sdla_clear(struct net_device *dev)
addr += bytes; addr += bytes;
len -= bytes; len -= bytes;
} }
restore_flags(flags); spin_unlock_irqrestore(&sdla_lock, flags);
} }
static char sdla_byte(struct net_device *dev, int addr) static char sdla_byte(struct net_device *dev, int addr)
...@@ -158,11 +176,10 @@ static char sdla_byte(struct net_device *dev, int addr) ...@@ -158,11 +176,10 @@ static char sdla_byte(struct net_device *dev, int addr)
temp = (void *) (dev->mem_start + (addr & SDLA_ADDR_MASK)); temp = (void *) (dev->mem_start + (addr & SDLA_ADDR_MASK));
save_flags(flags); spin_lock_irqsave(&sdla_lock, flags);
cli();
SDLA_WINDOW(dev, addr); SDLA_WINDOW(dev, addr);
byte = *temp; byte = *temp;
restore_flags(flags); spin_unlock_irqrestore(&sdla_lock, flags);
return(byte); return(byte);
} }
...@@ -414,7 +431,8 @@ static int sdla_cmd(struct net_device *dev, int cmd, short dlci, short flags, ...@@ -414,7 +431,8 @@ static int sdla_cmd(struct net_device *dev, int cmd, short dlci, short flags,
struct frad_local *flp; struct frad_local *flp;
struct sdla_cmd *cmd_buf; struct sdla_cmd *cmd_buf;
unsigned long pflags; unsigned long pflags;
int jiffs, ret, waiting, len; unsigned long jiffs;
int ret, waiting, len;
long window; long window;
flp = dev->priv; flp = dev->priv;
...@@ -423,8 +441,8 @@ static int sdla_cmd(struct net_device *dev, int cmd, short dlci, short flags, ...@@ -423,8 +441,8 @@ static int sdla_cmd(struct net_device *dev, int cmd, short dlci, short flags,
ret = 0; ret = 0;
len = 0; len = 0;
jiffs = jiffies + HZ; /* 1 second is plenty */ jiffs = jiffies + HZ; /* 1 second is plenty */
save_flags(pflags);
cli(); spin_lock_irqsave(&sdla_lock, pflags);
SDLA_WINDOW(dev, window); SDLA_WINDOW(dev, window);
cmd_buf->cmd = cmd; cmd_buf->cmd = cmd;
cmd_buf->dlci = dlci; cmd_buf->dlci = dlci;
...@@ -436,7 +454,7 @@ static int sdla_cmd(struct net_device *dev, int cmd, short dlci, short flags, ...@@ -436,7 +454,7 @@ static int sdla_cmd(struct net_device *dev, int cmd, short dlci, short flags,
cmd_buf->length = inlen; cmd_buf->length = inlen;
cmd_buf->opp_flag = 1; cmd_buf->opp_flag = 1;
restore_flags(pflags); spin_unlock_irqrestore(&sdla_lock, pflags);
waiting = 1; waiting = 1;
len = 0; len = 0;
...@@ -444,18 +462,17 @@ static int sdla_cmd(struct net_device *dev, int cmd, short dlci, short flags, ...@@ -444,18 +462,17 @@ static int sdla_cmd(struct net_device *dev, int cmd, short dlci, short flags,
{ {
if (waiting++ % 3) if (waiting++ % 3)
{ {
save_flags(pflags); spin_lock_irqsave(&sdla_lock, pflags);
cli();
SDLA_WINDOW(dev, window); SDLA_WINDOW(dev, window);
waiting = ((volatile int)(cmd_buf->opp_flag)); waiting = ((volatile int)(cmd_buf->opp_flag));
restore_flags(pflags); spin_unlock_irqrestore(&sdla_lock, pflags);
} }
} }
if (!waiting) if (!waiting)
{ {
save_flags(pflags);
cli(); spin_lock_irqsave(&sdla_lock, pflags);
SDLA_WINDOW(dev, window); SDLA_WINDOW(dev, window);
ret = cmd_buf->retval; ret = cmd_buf->retval;
len = cmd_buf->length; len = cmd_buf->length;
...@@ -471,7 +488,7 @@ static int sdla_cmd(struct net_device *dev, int cmd, short dlci, short flags, ...@@ -471,7 +488,7 @@ static int sdla_cmd(struct net_device *dev, int cmd, short dlci, short flags,
if (ret) if (ret)
memcpy(&status, cmd_buf->data, len > sizeof(status) ? sizeof(status) : len); memcpy(&status, cmd_buf->data, len > sizeof(status) ? sizeof(status) : len);
restore_flags(pflags); spin_unlock_irqrestore(&sdla_lock, pflags);
} }
else else
ret = SDLA_RET_TIMEOUT; ret = SDLA_RET_TIMEOUT;
...@@ -555,7 +572,6 @@ int sdla_assoc(struct net_device *slave, struct net_device *master) ...@@ -555,7 +572,6 @@ int sdla_assoc(struct net_device *slave, struct net_device *master)
if (i == CONFIG_DLCI_MAX) if (i == CONFIG_DLCI_MAX)
return(-EMLINK); /* #### Alan: Comments on this ?? */ return(-EMLINK); /* #### Alan: Comments on this ?? */
MOD_INC_USE_COUNT;
flp->master[i] = master; flp->master[i] = master;
flp->dlci[i] = -*(short *)(master->dev_addr); flp->dlci[i] = -*(short *)(master->dev_addr);
...@@ -588,7 +604,6 @@ int sdla_deassoc(struct net_device *slave, struct net_device *master) ...@@ -588,7 +604,6 @@ int sdla_deassoc(struct net_device *slave, struct net_device *master)
flp->master[i] = NULL; flp->master[i] = NULL;
flp->dlci[i] = 0; flp->dlci[i] = 0;
MOD_DEC_USE_COUNT;
if (netif_running(slave)) { if (netif_running(slave)) {
if (flp->config.station == FRAD_STATION_CPE) if (flp->config.station == FRAD_STATION_CPE)
...@@ -688,14 +703,14 @@ static int sdla_transmit(struct sk_buff *skb, struct net_device *dev) ...@@ -688,14 +703,14 @@ static int sdla_transmit(struct sk_buff *skb, struct net_device *dev)
ret = sdla_cmd(dev, SDLA_INFORMATION_WRITE, *(short *)(skb->dev->dev_addr), 0, NULL, skb->len, &addr, &size); ret = sdla_cmd(dev, SDLA_INFORMATION_WRITE, *(short *)(skb->dev->dev_addr), 0, NULL, skb->len, &addr, &size);
if (ret == SDLA_RET_OK) if (ret == SDLA_RET_OK)
{ {
save_flags(flags);
cli(); spin_lock_irqsave(&sdla_lock, flags);
SDLA_WINDOW(dev, addr); SDLA_WINDOW(dev, addr);
pbuf = (void *)(((int) dev->mem_start) + (addr & SDLA_ADDR_MASK)); pbuf = (void *)(((int) dev->mem_start) + (addr & SDLA_ADDR_MASK));
sdla_write(dev, pbuf->buf_addr, skb->data, skb->len); __sdla_write(dev, pbuf->buf_addr, skb->data, skb->len);
SDLA_WINDOW(dev, addr); SDLA_WINDOW(dev, addr);
pbuf->opp_flag = 1; pbuf->opp_flag = 1;
restore_flags(flags); spin_unlock_irqrestore(&sdla_lock, flags);
} }
break; break;
} }
...@@ -753,8 +768,7 @@ static void sdla_receive(struct net_device *dev) ...@@ -753,8 +768,7 @@ static void sdla_receive(struct net_device *dev)
pbufi = NULL; pbufi = NULL;
pbuf = NULL; pbuf = NULL;
save_flags(flags); spin_lock_irqsave(&sdla_lock, flags);
cli();
switch (flp->type) switch (flp->type)
{ {
...@@ -821,7 +835,7 @@ static void sdla_receive(struct net_device *dev) ...@@ -821,7 +835,7 @@ static void sdla_receive(struct net_device *dev)
case SDLA_S502A: case SDLA_S502A:
case SDLA_S502E: case SDLA_S502E:
if (success) if (success)
sdla_read(dev, SDLA_502_RCV_BUF + SDLA_502_DATA_OFS, skb_put(skb,len), len); __sdla_read(dev, SDLA_502_RCV_BUF + SDLA_502_DATA_OFS, skb_put(skb,len), len);
SDLA_WINDOW(dev, SDLA_502_RCV_BUF); SDLA_WINDOW(dev, SDLA_502_RCV_BUF);
cmd->opp_flag = 0; cmd->opp_flag = 0;
...@@ -834,9 +848,9 @@ static void sdla_receive(struct net_device *dev) ...@@ -834,9 +848,9 @@ static void sdla_receive(struct net_device *dev)
split = addr + len > buf_top + 1 ? len - (buf_top - addr + 1) : 0; split = addr + len > buf_top + 1 ? len - (buf_top - addr + 1) : 0;
len2 = len - split; len2 = len - split;
sdla_read(dev, addr, skb_put(skb, len2), len2); __sdla_read(dev, addr, skb_put(skb, len2), len2);
if (split) if (split)
sdla_read(dev, buf_base, skb_put(skb, split), split); __sdla_read(dev, buf_base, skb_put(skb, split), split);
} }
/* increment the buffer we're looking at */ /* increment the buffer we're looking at */
...@@ -853,7 +867,7 @@ static void sdla_receive(struct net_device *dev) ...@@ -853,7 +867,7 @@ static void sdla_receive(struct net_device *dev)
(*dlp->receive)(skb, master); (*dlp->receive)(skb, master);
} }
restore_flags(flags); spin_unlock_irqrestore(&sdla_lock, flags);
} }
static irqreturn_t sdla_isr(int irq, void *dev_id, struct pt_regs * regs) static irqreturn_t sdla_isr(int irq, void *dev_id, struct pt_regs * regs)
...@@ -979,8 +993,6 @@ static int sdla_close(struct net_device *dev) ...@@ -979,8 +993,6 @@ static int sdla_close(struct net_device *dev)
netif_stop_queue(dev); netif_stop_queue(dev);
MOD_DEC_USE_COUNT;
return(0); return(0);
} }
...@@ -1082,8 +1094,6 @@ static int sdla_open(struct net_device *dev) ...@@ -1082,8 +1094,6 @@ static int sdla_open(struct net_device *dev)
netif_start_queue(dev); netif_start_queue(dev);
MOD_INC_USE_COUNT;
return(0); return(0);
} }
...@@ -1614,19 +1624,30 @@ static struct net_device_stats *sdla_stats(struct net_device *dev) ...@@ -1614,19 +1624,30 @@ static struct net_device_stats *sdla_stats(struct net_device *dev)
return(&flp->stats); return(&flp->stats);
} }
int __init sdla_init(struct net_device *dev) static void setup_sdla(struct net_device *dev)
{ {
dev->flags = 0;
dev->type = 0xFFFF;
dev->hard_header_len = 0;
dev->addr_len = 0;
dev->mtu = SDLA_MAX_MTU;
}
struct net_device * __init sdla_init(void)
{
struct net_device *dev;
struct frad_local *flp; struct frad_local *flp;
int err = -ENOMEM;
/* allocate the private data structure */ dev = alloc_netdev(sizeof(struct frad_local), "sdla0", setup_sdla);
flp = kmalloc(sizeof(struct frad_local), GFP_KERNEL); if (!dev)
if (!flp) goto out;
return(-ENOMEM);
SET_MODULE_OWNER(dev);
netdev_boot_setup_check(dev);
memset(flp, 0, sizeof(struct frad_local)); flp = dev->priv;
dev->priv = flp;
dev->flags = 0;
dev->open = sdla_open; dev->open = sdla_open;
dev->stop = sdla_close; dev->stop = sdla_close;
dev->do_ioctl = sdla_ioctl; dev->do_ioctl = sdla_ioctl;
...@@ -1635,12 +1656,6 @@ int __init sdla_init(struct net_device *dev) ...@@ -1635,12 +1656,6 @@ int __init sdla_init(struct net_device *dev)
dev->hard_start_xmit = sdla_transmit; dev->hard_start_xmit = sdla_transmit;
dev->change_mtu = sdla_change_mtu; dev->change_mtu = sdla_change_mtu;
dev->type = 0xFFFF;
dev->hard_header_len = 0;
dev->addr_len = 0;
dev->mtu = SDLA_MAX_MTU;
SET_MODULE_OWNER(dev);
flp->activate = sdla_activate; flp->activate = sdla_activate;
flp->deactivate = sdla_deactivate; flp->deactivate = sdla_deactivate;
flp->assoc = sdla_assoc; flp->assoc = sdla_assoc;
...@@ -1652,7 +1667,14 @@ int __init sdla_init(struct net_device *dev) ...@@ -1652,7 +1667,14 @@ int __init sdla_init(struct net_device *dev)
flp->timer.data = (unsigned long) dev; flp->timer.data = (unsigned long) dev;
flp->timer.function = sdla_poll; flp->timer.function = sdla_poll;
return(0); err = register_netdev(dev);
if (err)
goto out1;
return dev;
out1:
kfree(dev);
out:
return ERR_PTR(err);
} }
int __init sdla_c_setup(void) int __init sdla_c_setup(void)
...@@ -1663,10 +1685,7 @@ int __init sdla_c_setup(void) ...@@ -1663,10 +1685,7 @@ int __init sdla_c_setup(void)
} }
#ifdef MODULE #ifdef MODULE
static struct net_device sdla0 = { static struct net_device *sdla0;
.name = "sdla0",
.init = sdla_init
};
#endif /* MODULE */ #endif /* MODULE */
static int __init init_sdla(void) static int __init init_sdla(void)
...@@ -1675,7 +1694,9 @@ static int __init init_sdla(void) ...@@ -1675,7 +1694,9 @@ static int __init init_sdla(void)
sdla_c_setup(); sdla_c_setup();
#ifdef MODULE #ifdef MODULE
result = register_netdev(&sdla0); sdla0 = sdla_init();
if (IS_ERR(sdla0))
result = PTR_ERR(sdla0);
#endif #endif
return result; return result;
} }
...@@ -1683,11 +1704,10 @@ static int __init init_sdla(void) ...@@ -1683,11 +1704,10 @@ static int __init init_sdla(void)
static void __exit exit_sdla(void) static void __exit exit_sdla(void)
{ {
#ifdef MODULE #ifdef MODULE
unregister_netdev(&sdla0); unregister_netdev(sdla0);
if (sdla0.priv) if (sdla0->irq)
kfree(sdla0.priv); free_irq(sdla0->irq, sdla0);
if (sdla0.irq) free_netdev(sdla0);
free_irq(sdla0.irq, &sdla0);
#endif #endif
} }
......
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