Commit c714a164 authored by Jochen Friedrich's avatar Jochen Friedrich Committed by Jeff Garzik

Update several token ring drivers:

New low level tms380 driver for Proteon 1392 / 1392+ cards
(port from existing 2.2 kernel code)

Add spinlock to fix race condition in tms380tr.

Fix startup of tmsisa to not register and unregister devices multiple
times, so hotplug doesn't run wild.

Add support for statically compiling tmsisa into kernel.

Remove unnecessary console SPAM during boot.

Fixed probing of ISA devices in tmsisa.

Fixed unsafe reference counting.

Fixed __init function causing Oops with new module system.

Rename tmsisa to skisa.
parent 1db75d47
......@@ -551,6 +551,8 @@ static struct net_device eth0_dev = {
#ifdef CONFIG_TR
/* Token-ring device probe */
extern int ibmtr_probe(struct net_device *);
extern int sk_isa_probe(struct net_device *);
extern int proteon_probe(struct net_device *);
extern int smctr_probe(struct net_device *);
static int
......@@ -560,6 +562,12 @@ trif_probe(struct net_device *dev)
#ifdef CONFIG_IBMTR
&& ibmtr_probe(dev)
#endif
#ifdef CONFIG_SKISA
&& sk_isa_probe(dev)
#endif
#ifdef CONFIG_PROTEON
&& proteon_probe(dev)
#endif
#ifdef CONFIG_SMCTR
&& smctr_probe(dev)
#endif
......
......@@ -131,18 +131,33 @@ config TMSPCI
The module will be called tmspci. If you want to compile it
as a module, say M here and read <file:Documentation/modules.txt>.
config TMSISA
tristate "Generic TMS380 ISA support"
config SKISA
tristate "SysKonnect TR4/16 ISA support"
depends on TR && TMS380TR!=n && ISA
help
This tms380 module supports generic TMS380-based ISA cards.
This tms380 module supports SysKonnect TR4/16 ISA cards.
These cards are known to work:
- SysKonnect TR4/16 ISA (SK-4190)
This driver is available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module will be called tmsisa. If you want to compile it
The module will be called skisa. If you want to compile it
as a module, say M here and read <file:Documentation/modules.txt>.
config PROTEON
tristate "Proteon ISA support"
depends on TR && TMS380TR!=n && ISA
help
This tms380 module supports Proteon ISA cards.
These cards are known to work:
- Proteon 1392
- Proteon 1392 plus
This driver is available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module will be called proteon. If you want to compile it
as a module, say M here and read <file:Documentation/modules.txt>.
config ABYSS
......
......@@ -8,7 +8,8 @@ obj-$(CONFIG_IBMLS) += lanstreamer.o
obj-$(CONFIG_TMS380TR) += tms380tr.o
obj-$(CONFIG_ABYSS) += abyss.o
obj-$(CONFIG_MADGEMC) += madgemc.o
obj-$(CONFIG_PROTEON) += proteon.o
obj-$(CONFIG_TMSPCI) += tmspci.o
obj-$(CONFIG_TMSISA) += tmsisa.o
obj-$(CONFIG_SKISA) += skisa.o
obj-$(CONFIG_SMCTR) += smctr.o
obj-$(CONFIG_3C359) += 3c359.o
/*
* proteon.c: A network driver for Proteon ISA token ring cards.
*
* Based on tmspci written 1999 by Adam Fritzler
*
* Written 2003 by Jochen Friedrich
*
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
*
* This driver module supports the following cards:
* - Proteon 1392, 1392+
*
* Maintainer(s):
* AF Adam Fritzler mid@auk.cx
* JF Jochen Friedrich jochen@scram.de
*
* Modification History:
* 02-Jan-03 JF Created
*
*/
static const char version[] = "proteon.c: v1.00 02/01/2003 by Jochen Friedrich\n";
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/trdevice.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/pci.h>
#include <asm/dma.h>
#include "tms380tr.h"
#define PROTEON_IO_EXTENT 32
/* A zero-terminated list of I/O addresses to be probed. */
static unsigned int portlist[] __initdata = {
0x0A20, 0x0E20, 0x1A20, 0x1E20, 0x2A20, 0x2E20, 0x3A20, 0x3E20,// Prot.
0x4A20, 0x4E20, 0x5A20, 0x5E20, 0x6A20, 0x6E20, 0x7A20, 0x7E20,// Prot.
0x8A20, 0x8E20, 0x9A20, 0x9E20, 0xAA20, 0xAE20, 0xBA20, 0xBE20,// Prot.
0xCA20, 0xCE20, 0xDA20, 0xDE20, 0xEA20, 0xEE20, 0xFA20, 0xFE20,// Prot.
0
};
/* A zero-terminated list of IRQs to be probed. */
static unsigned short irqlist[] = {
7, 6, 5, 4, 3, 12, 11, 10, 9,
0
};
/* A zero-terminated list of DMAs to be probed. */
static int dmalist[] __initdata = {
5, 6, 7,
0
};
static char cardname[] = "Proteon 1392\0";
int proteon_probe(struct net_device *dev);
static int proteon_open(struct net_device *dev);
static int proteon_close(struct net_device *dev);
static void proteon_read_eeprom(struct net_device *dev);
static unsigned short proteon_setnselout_pins(struct net_device *dev);
static unsigned short proteon_sifreadb(struct net_device *dev, unsigned short reg)
{
return inb(dev->base_addr + reg);
}
static unsigned short proteon_sifreadw(struct net_device *dev, unsigned short reg)
{
return inw(dev->base_addr + reg);
}
static void proteon_sifwriteb(struct net_device *dev, unsigned short val, unsigned short reg)
{
outb(val, dev->base_addr + reg);
}
static void proteon_sifwritew(struct net_device *dev, unsigned short val, unsigned short reg)
{
outw(val, dev->base_addr + reg);
}
struct proteon_card {
struct net_device *dev;
struct proteon_card *next;
};
static struct proteon_card *proteon_card_list;
static int __init proteon_probe1(int ioaddr)
{
unsigned char chk1, chk2;
int i;
chk1 = inb(ioaddr + 0x1f); /* Get Proteon ID reg 1 */
if (chk1 != 0x1f)
return (-1);
chk1 = inb(ioaddr + 0x1e) & 0x07; /* Get Proteon ID reg 0 */
for (i=0; i<16; i++) {
chk2 = inb(ioaddr + 0x1e) & 0x07;
if (((chk1 + 1) & 0x07) != chk2)
return (-1);
chk1 = chk2;
}
return (0);
}
int __init proteon_probe(struct net_device *dev)
{
static int versionprinted;
struct net_local *tp;
int i,j;
struct proteon_card *card;
SET_MODULE_OWNER(dev);
if (!dev->base_addr)
{
for(i = 0; portlist[i]; i++)
{
if (!request_region(portlist[i], PROTEON_IO_EXTENT, cardname))
continue;
if(proteon_probe1(portlist[i]))
{
release_region(dev->base_addr, PROTEON_IO_EXTENT);
continue;
}
dev->base_addr = portlist[i];
break;
}
if(!dev->base_addr)
return -1;
}
else
{
if (!request_region(dev->base_addr, PROTEON_IO_EXTENT, cardname))
return -1;
if(proteon_probe1(dev->base_addr))
{
release_region(dev->base_addr, PROTEON_IO_EXTENT);
return -1;
}
}
/* At this point we have found a valid card. */
if (versionprinted++ == 0)
printk(KERN_DEBUG "%s", version);
#ifndef MODULE
dev = init_trdev(dev, 0);
if (!dev)
{
release_region(dev->base_addr, PROTEON_IO_EXTENT);
return -1;
}
#endif
if (tmsdev_init(dev, ISA_MAX_ADDRESS, NULL))
{
release_region(dev->base_addr, PROTEON_IO_EXTENT);
return -1;
}
dev->base_addr &= ~3;
proteon_read_eeprom(dev);
printk(KERN_DEBUG "%s: Ring Station Address: ", dev->name);
printk("%2.2x", dev->dev_addr[0]);
for (j = 1; j < 6; j++)
printk(":%2.2x", dev->dev_addr[j]);
printk("\n");
tp = (struct net_local *)dev->priv;
tp->setnselout = proteon_setnselout_pins;
tp->sifreadb = proteon_sifreadb;
tp->sifreadw = proteon_sifreadw;
tp->sifwriteb = proteon_sifwriteb;
tp->sifwritew = proteon_sifwritew;
memcpy(tp->ProductID, cardname, PROD_ID_SIZE + 1);
tp->tmspriv = NULL;
dev->open = proteon_open;
dev->stop = proteon_close;
if (dev->irq == 0)
{
for(j = 0; irqlist[j] != 0; j++)
{
dev->irq = irqlist[j];
if (!request_irq(dev->irq, tms380tr_interrupt, 0,
cardname, dev))
break;
}
if(irqlist[j] == 0)
{
printk(KERN_INFO "%s: AutoSelect no IRQ available\n", dev->name);
release_region(dev->base_addr, PROTEON_IO_EXTENT);
tmsdev_term(dev);
return -1;
}
}
else
{
for(j = 0; irqlist[j] != 0; j++)
if (irqlist[j] == dev->irq)
break;
if (irqlist[j] == 0)
{
printk(KERN_INFO "%s: Illegal IRQ %d specified\n",
dev->name, dev->irq);
release_region(dev->base_addr, PROTEON_IO_EXTENT);
tmsdev_term(dev);
return -1;
}
if (request_irq(dev->irq, tms380tr_interrupt, 0,
cardname, dev))
{
printk(KERN_INFO "%s: Selected IRQ %d not available\n",
dev->name, dev->irq);
release_region(dev->base_addr, PROTEON_IO_EXTENT);
tmsdev_term(dev);
return -1;
}
}
if (dev->dma == 0)
{
for(j = 0; dmalist[j] != 0; j++)
{
dev->dma = dmalist[j];
if (!request_dma(dev->dma, cardname))
break;
}
if(dmalist[j] == 0)
{
printk(KERN_INFO "%s: AutoSelect no DMA available\n", dev->name);
release_region(dev->base_addr, PROTEON_IO_EXTENT);
free_irq(dev->irq, dev);
tmsdev_term(dev);
return -1;
}
}
else
{
for(j = 0; dmalist[j] != 0; j++)
if (dmalist[j] == dev->dma)
break;
if (dmalist[j] == 0)
{
printk(KERN_INFO "%s: Illegal DMA %d specified\n",
dev->name, dev->dma);
release_region(dev->base_addr, PROTEON_IO_EXTENT);
free_irq(dev->irq, dev);
tmsdev_term(dev);
return -1;
}
if (request_dma(dev->dma, cardname))
{
printk(KERN_INFO "%s: Selected DMA %d not available\n",
dev->name, dev->dma);
release_region(dev->base_addr, PROTEON_IO_EXTENT);
free_irq(dev->irq, dev);
tmsdev_term(dev);
return -1;
}
}
printk(KERN_DEBUG "%s: IO: %#4lx IRQ: %d DMA: %d\n",
dev->name, dev->base_addr, dev->irq, dev->dma);
if (register_trdev(dev) == 0)
{
/* Enlist in the card list */
card = kmalloc(sizeof(struct proteon_card), GFP_KERNEL);
if (!card) {
unregister_trdev(dev);
release_region(dev->base_addr, PROTEON_IO_EXTENT);
free_irq(dev->irq, dev);
free_dma(dev->dma);
tmsdev_term(dev);
return -1;
}
card->next = proteon_card_list;
proteon_card_list = card;
card->dev = dev;
}
else
{
printk("KERN_INFO %s: register_trdev() returned non-zero.\n", dev->name);
release_region(dev->base_addr, PROTEON_IO_EXTENT);
free_irq(dev->irq, dev);
free_dma(dev->dma);
tmsdev_term(dev);
return -1;
}
return 0;
}
/*
* Reads MAC address from adapter RAM, which should've read it from
* the onboard ROM.
*
* Calling this on a board that does not support it can be a very
* dangerous thing. The Madge board, for instance, will lock your
* machine hard when this is called. Luckily, its supported in a
* seperate driver. --ASF
*/
static void proteon_read_eeprom(struct net_device *dev)
{
int i;
/* Address: 0000:0000 */
proteon_sifwritew(dev, 0, SIFADX);
proteon_sifwritew(dev, 0, SIFADR);
/* Read six byte MAC address data */
dev->addr_len = 6;
for(i = 0; i < 6; i++)
dev->dev_addr[i] = proteon_sifreadw(dev, SIFINC) >> 8;
}
unsigned short proteon_setnselout_pins(struct net_device *dev)
{
return 0;
}
static int proteon_open(struct net_device *dev)
{
struct net_local *tp = (struct net_local *)dev->priv;
unsigned short val = 0;
int i;
/* Proteon reset sequence */
outb(0, dev->base_addr + 0x11);
mdelay(20);
outb(0x04, dev->base_addr + 0x11);
mdelay(20);
outb(0, dev->base_addr + 0x11);
mdelay(100);
/* set control/status reg */
val = inb(dev->base_addr + 0x11);
val |= 0x78;
val &= 0xf9;
if(tp->DataRate == SPEED_4)
val |= 0x20;
else
val &= ~0x20;
outb(val, dev->base_addr + 0x11);
outb(0xff, dev->base_addr + 0x12);
for(i = 0; irqlist[i] != 0; i++)
{
if(irqlist[i] == dev->irq)
break;
}
val = i;
i = (7 - dev->dma) << 4;
val |= i;
outb(val, dev->base_addr + 0x13);
tms380tr_open(dev);
return 0;
}
static int proteon_close(struct net_device *dev)
{
tms380tr_close(dev);
return 0;
}
#ifdef MODULE
#define ISATR_MAX_ADAPTERS 3
static int io[ISATR_MAX_ADAPTERS];
static int irq[ISATR_MAX_ADAPTERS];
static int dma[ISATR_MAX_ADAPTERS];
MODULE_LICENSE("GPL");
MODULE_PARM(io, "1-" __MODULE_STRING(ISATR_MAX_ADAPTERS) "i");
MODULE_PARM(irq, "1-" __MODULE_STRING(ISATR_MAX_ADAPTERS) "i");
MODULE_PARM(dma, "1-" __MODULE_STRING(ISATR_MAX_ADAPTERS) "i");
int init_module(void)
{
int i, num;
struct net_device *dev;
num = 0;
if (io[0])
{ /* Only probe addresses from command line */
dev = init_trdev(NULL, 0);
if (!dev)
return (-ENOMEM);
for (i = 0; i < ISATR_MAX_ADAPTERS; i++)
{
if (io[i] == 0)
continue;
dev->base_addr = io[i];
dev->irq = irq[i];
dev->dma = dma[i];
if (!proteon_probe(dev))
{
num++;
dev = init_trdev(NULL, 0);
if (!dev)
goto partial;
}
}
unregister_netdev(dev);
kfree(dev);
}
else
{
dev = init_trdev(NULL, 0);
if (!dev)
return (-ENOMEM);
for(i = 0; portlist[i]; i++)
{
if (num >= ISATR_MAX_ADAPTERS)
continue;
dev->base_addr = portlist[i];
dev->irq = irq[num];
dev->dma = dma[num];
if (!proteon_probe(dev))
{
num++;
dev = init_trdev(NULL, 0);
if (!dev)
goto partial;
}
}
unregister_netdev(dev);
kfree(dev);
}
partial:
printk(KERN_NOTICE "proteon.c: %d cards found.\n", num);
/* Probe for cards. */
if (num == 0) {
printk(KERN_NOTICE "proteon.c: No cards found.\n");
return (-ENODEV);
}
return (0);
}
void cleanup_module(void)
{
struct net_device *dev;
struct proteon_card *this_card;
while (proteon_card_list) {
dev = proteon_card_list->dev;
unregister_netdev(dev);
release_region(dev->base_addr, PROTEON_IO_EXTENT);
free_irq(dev->irq, dev);
free_dma(dev->dma);
tmsdev_term(dev);
kfree(dev);
this_card = proteon_card_list;
proteon_card_list = this_card->next;
kfree(this_card);
}
}
#endif /* MODULE */
/*
* Local variables:
* compile-command: "gcc -DMODVERSIONS -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c proteon.c"
* alt-compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c proteon.c"
* c-set-style "K&R"
* c-indent-level: 8
* c-basic-offset: 8
* tab-width: 8
* End:
*/
/*
* tmsisa.c: A generic network driver for TMS380-based ISA token ring cards.
* skisa.c: A network driver for SK-NET TMS380-based ISA token ring cards.
*
* Based on tmspci written 1999 by Adam Fritzler
*
......@@ -16,10 +16,18 @@
* AF Adam Fritzler mid@auk.cx
* JF Jochen Friedrich jochen@scram.de
*
* TODO:
* 1. Add support for Proteon TR ISA adapters (1392, 1392+)
* Modification History:
* 14-Jan-01 JF Created
* 28-Oct-02 JF Fixed probe of card for static compilation.
* Fixed module init to not make hotplug go wild.
* 09-Nov-02 JF Fixed early bail out on out of memory
* situations if multiple cards are found.
* Cleaned up some unnecessary console SPAM.
* 09-Dec-02 JF Fixed module reference counting.
* 02-Jan-03 JF Renamed to skisa.c
*
*/
static const char version[] = "tmsisa.c: v1.00 14/01/2001 by Jochen Friedrich\n";
static const char version[] = "skisa.c: v1.03 09/12/2002 by Jochen Friedrich\n";
#include <linux/module.h>
#include <linux/kernel.h>
......@@ -37,7 +45,7 @@ static const char version[] = "tmsisa.c: v1.00 14/01/2001 by Jochen Friedrich\n"
#include "tms380tr.h"
#define TMS_ISA_IO_EXTENT 32
#define SK_ISA_IO_EXTENT 32
/* A zero-terminated list of I/O addresses to be probed. */
static unsigned int portlist[] __initdata = {
......@@ -61,40 +69,40 @@ static int dmalist[] __initdata = {
static char isa_cardname[] = "SK NET TR 4/16 ISA\0";
int tms_isa_probe(struct net_device *dev);
static int tms_isa_open(struct net_device *dev);
static int tms_isa_close(struct net_device *dev);
static void tms_isa_read_eeprom(struct net_device *dev);
static unsigned short tms_isa_setnselout_pins(struct net_device *dev);
int sk_isa_probe(struct net_device *dev);
static int sk_isa_open(struct net_device *dev);
static int sk_isa_close(struct net_device *dev);
static void sk_isa_read_eeprom(struct net_device *dev);
static unsigned short sk_isa_setnselout_pins(struct net_device *dev);
static unsigned short tms_isa_sifreadb(struct net_device *dev, unsigned short reg)
static unsigned short sk_isa_sifreadb(struct net_device *dev, unsigned short reg)
{
return inb(dev->base_addr + reg);
}
static unsigned short tms_isa_sifreadw(struct net_device *dev, unsigned short reg)
static unsigned short sk_isa_sifreadw(struct net_device *dev, unsigned short reg)
{
return inw(dev->base_addr + reg);
}
static void tms_isa_sifwriteb(struct net_device *dev, unsigned short val, unsigned short reg)
static void sk_isa_sifwriteb(struct net_device *dev, unsigned short val, unsigned short reg)
{
outb(val, dev->base_addr + reg);
}
static void tms_isa_sifwritew(struct net_device *dev, unsigned short val, unsigned short reg)
static void sk_isa_sifwritew(struct net_device *dev, unsigned short val, unsigned short reg)
{
outw(val, dev->base_addr + reg);
}
struct tms_isa_card {
struct sk_isa_card {
struct net_device *dev;
struct tms_isa_card *next;
struct sk_isa_card *next;
};
static struct tms_isa_card *tms_isa_card_list;
static struct sk_isa_card *sk_isa_card_list;
static int __init tms_isa_probe1(int ioaddr)
static int __init sk_isa_probe1(int ioaddr)
{
unsigned char old, chk1, chk2;
......@@ -126,57 +134,89 @@ static int __init tms_isa_probe1(int ioaddr)
return (0);
}
int __init tms_isa_probe(struct net_device *dev)
int __init sk_isa_probe(struct net_device *dev)
{
static int versionprinted;
struct net_local *tp;
int j;
struct tms_isa_card *card;
int i,j;
struct sk_isa_card *card;
if(check_region(dev->base_addr, TMS_ISA_IO_EXTENT))
return -1;
SET_MODULE_OWNER(dev);
if (!dev->base_addr)
{
for(i = 0; portlist[i]; i++)
{
if (!request_region(portlist[i], SK_ISA_IO_EXTENT, isa_cardname))
continue;
if(sk_isa_probe1(portlist[i]))
{
release_region(dev->base_addr, SK_ISA_IO_EXTENT);
continue;
}
dev->base_addr = portlist[i];
break;
}
if(!dev->base_addr)
return -1;
}
else
{
if (!request_region(dev->base_addr, SK_ISA_IO_EXTENT, isa_cardname))
return -1;
if(sk_isa_probe1(dev->base_addr))
{
release_region(dev->base_addr, SK_ISA_IO_EXTENT);
return -1;
}
}
if(tms_isa_probe1(dev->base_addr))
return -1;
if (versionprinted++ == 0)
printk("%s", version);
/* At this point we have found a valid card. */
if (!request_region(dev->base_addr, TMS_ISA_IO_EXTENT, isa_cardname))
if (versionprinted++ == 0)
printk(KERN_DEBUG "%s", version);
#ifndef MODULE
dev = init_trdev(dev, 0);
if (!dev)
{
release_region(dev->base_addr, SK_ISA_IO_EXTENT);
return -1;
}
#endif
if (tmsdev_init(dev, ISA_MAX_ADDRESS, NULL))
{
release_region(dev->base_addr, TMS_ISA_IO_EXTENT);
release_region(dev->base_addr, SK_ISA_IO_EXTENT);
return -1;
}
dev->base_addr &= ~3;
tms_isa_read_eeprom(dev);
sk_isa_read_eeprom(dev);
printk("%s: Ring Station Address: ", dev->name);
printk(KERN_DEBUG "%s: Ring Station Address: ", dev->name);
printk("%2.2x", dev->dev_addr[0]);
for (j = 1; j < 6; j++)
printk(":%2.2x", dev->dev_addr[j]);
printk("\n");
tp = (struct net_local *)dev->priv;
tp->setnselout = tms_isa_setnselout_pins;
tp->setnselout = sk_isa_setnselout_pins;
tp->sifreadb = tms_isa_sifreadb;
tp->sifreadw = tms_isa_sifreadw;
tp->sifwriteb = tms_isa_sifwriteb;
tp->sifwritew = tms_isa_sifwritew;
tp->sifreadb = sk_isa_sifreadb;
tp->sifreadw = sk_isa_sifreadw;
tp->sifwriteb = sk_isa_sifwriteb;
tp->sifwritew = sk_isa_sifwritew;
memcpy(tp->ProductID, isa_cardname, PROD_ID_SIZE + 1);
tp->tmspriv = NULL;
dev->open = tms_isa_open;
dev->stop = tms_isa_close;
dev->open = sk_isa_open;
dev->stop = sk_isa_close;
if (dev->irq == 0)
{
......@@ -190,8 +230,8 @@ int __init tms_isa_probe(struct net_device *dev)
if(irqlist[j] == 0)
{
printk("%s: AutoSelect no IRQ available\n", dev->name);
release_region(dev->base_addr, TMS_ISA_IO_EXTENT);
printk(KERN_INFO "%s: AutoSelect no IRQ available\n", dev->name);
release_region(dev->base_addr, SK_ISA_IO_EXTENT);
tmsdev_term(dev);
return -1;
}
......@@ -203,18 +243,18 @@ int __init tms_isa_probe(struct net_device *dev)
break;
if (irqlist[j] == 0)
{
printk("%s: Illegal IRQ %d specified\n",
printk(KERN_INFO "%s: Illegal IRQ %d specified\n",
dev->name, dev->irq);
release_region(dev->base_addr, TMS_ISA_IO_EXTENT);
release_region(dev->base_addr, SK_ISA_IO_EXTENT);
tmsdev_term(dev);
return -1;
}
if (request_irq(dev->irq, tms380tr_interrupt, 0,
isa_cardname, dev))
{
printk("%s: Selected IRQ %d not available\n",
printk(KERN_INFO "%s: Selected IRQ %d not available\n",
dev->name, dev->irq);
release_region(dev->base_addr, TMS_ISA_IO_EXTENT);
release_region(dev->base_addr, SK_ISA_IO_EXTENT);
tmsdev_term(dev);
return -1;
}
......@@ -231,8 +271,8 @@ int __init tms_isa_probe(struct net_device *dev)
if(dmalist[j] == 0)
{
printk("%s: AutoSelect no DMA available\n", dev->name);
release_region(dev->base_addr, TMS_ISA_IO_EXTENT);
printk(KERN_INFO "%s: AutoSelect no DMA available\n", dev->name);
release_region(dev->base_addr, SK_ISA_IO_EXTENT);
free_irq(dev->irq, dev);
tmsdev_term(dev);
return -1;
......@@ -245,47 +285,47 @@ int __init tms_isa_probe(struct net_device *dev)
break;
if (dmalist[j] == 0)
{
printk("%s: Illegal DMA %d specified\n",
printk(KERN_INFO "%s: Illegal DMA %d specified\n",
dev->name, dev->dma);
release_region(dev->base_addr, TMS_ISA_IO_EXTENT);
release_region(dev->base_addr, SK_ISA_IO_EXTENT);
free_irq(dev->irq, dev);
tmsdev_term(dev);
return -1;
}
if (request_dma(dev->dma, isa_cardname))
{
printk("%s: Selected DMA %d not available\n",
printk(KERN_INFO "%s: Selected DMA %d not available\n",
dev->name, dev->dma);
release_region(dev->base_addr, TMS_ISA_IO_EXTENT);
release_region(dev->base_addr, SK_ISA_IO_EXTENT);
free_irq(dev->irq, dev);
tmsdev_term(dev);
return -1;
}
}
printk("%s: IO: %#4lx IRQ: %d DMA: %d\n",
printk(KERN_DEBUG "%s: IO: %#4lx IRQ: %d DMA: %d\n",
dev->name, dev->base_addr, dev->irq, dev->dma);
if (register_trdev(dev) == 0)
{
/* Enlist in the card list */
card = kmalloc(sizeof(struct tms_isa_card), GFP_KERNEL);
card = kmalloc(sizeof(struct sk_isa_card), GFP_KERNEL);
if (!card) {
unregister_trdev(dev);
release_region(dev->base_addr, TMS_ISA_IO_EXTENT);
release_region(dev->base_addr, SK_ISA_IO_EXTENT);
free_irq(dev->irq, dev);
free_dma(dev->dma);
tmsdev_term(dev);
return -1;
}
card->next = tms_isa_card_list;
tms_isa_card_list = card;
card->next = sk_isa_card_list;
sk_isa_card_list = card;
card->dev = dev;
}
else
{
printk("%s: register_trdev() returned non-zero.\n", dev->name);
release_region(dev->base_addr, TMS_ISA_IO_EXTENT);
printk("KERN_INFO %s: register_trdev() returned non-zero.\n", dev->name);
release_region(dev->base_addr, SK_ISA_IO_EXTENT);
free_irq(dev->irq, dev);
free_dma(dev->dma);
tmsdev_term(dev);
......@@ -304,26 +344,26 @@ int __init tms_isa_probe(struct net_device *dev)
* machine hard when this is called. Luckily, its supported in a
* separate driver. --ASF
*/
static void tms_isa_read_eeprom(struct net_device *dev)
static void sk_isa_read_eeprom(struct net_device *dev)
{
int i;
/* Address: 0000:0000 */
tms_isa_sifwritew(dev, 0, SIFADX);
tms_isa_sifwritew(dev, 0, SIFADR);
sk_isa_sifwritew(dev, 0, SIFADX);
sk_isa_sifwritew(dev, 0, SIFADR);
/* Read six byte MAC address data */
dev->addr_len = 6;
for(i = 0; i < 6; i++)
dev->dev_addr[i] = tms_isa_sifreadw(dev, SIFINC) >> 8;
dev->dev_addr[i] = sk_isa_sifreadw(dev, SIFINC) >> 8;
}
unsigned short tms_isa_setnselout_pins(struct net_device *dev)
unsigned short sk_isa_setnselout_pins(struct net_device *dev)
{
return 0;
}
static int tms_isa_open(struct net_device *dev)
static int sk_isa_open(struct net_device *dev)
{
struct net_local *tp = (struct net_local *)dev->priv;
unsigned short val = 0;
......@@ -345,21 +385,19 @@ static int tms_isa_open(struct net_device *dev)
val |= LINE_SPEED_BIT;
else
val &= ~LINE_SPEED_BIT;
oldval = tms_isa_sifreadb(dev, POSREG);
oldval = sk_isa_sifreadb(dev, POSREG);
/* Leave cycle bits alone */
oldval |= 0xf3;
val &= oldval;
tms_isa_sifwriteb(dev, val, POSREG);
sk_isa_sifwriteb(dev, val, POSREG);
tms380tr_open(dev);
MOD_INC_USE_COUNT;
return 0;
}
static int tms_isa_close(struct net_device *dev)
static int sk_isa_close(struct net_device *dev)
{
tms380tr_close(dev);
MOD_DEC_USE_COUNT;
return 0;
}
......@@ -385,56 +423,61 @@ int init_module(void)
num = 0;
if (io[0])
{ /* Only probe addresses from command line */
dev = init_trdev(NULL, 0);
if (!dev)
return (-ENOMEM);
for (i = 0; i < ISATR_MAX_ADAPTERS; i++)
{
if (io[i] == 0)
continue;
dev = init_trdev(NULL, 0);
if (!dev)
return (-ENOMEM);
dev->base_addr = io[i];
dev->irq = irq[i];
dev->dma = dma[i];
if (tms_isa_probe(dev))
if (!sk_isa_probe(dev))
{
unregister_netdev(dev);
kfree(dev);
}
else
num++;
dev = init_trdev(NULL, 0);
if (!dev)
goto partial;
}
}
unregister_netdev(dev);
kfree(dev);
}
else
{
dev = init_trdev(NULL, 0);
if (!dev)
return (-ENOMEM);
for(i = 0; portlist[i]; i++)
{
if (num >= ISATR_MAX_ADAPTERS)
continue;
dev = init_trdev(NULL, 0);
if (!dev)
return (-ENOMEM);
dev->base_addr = portlist[i];
dev->irq = irq[num];
dev->dma = dma[num];
if (tms_isa_probe(dev))
if (!sk_isa_probe(dev))
{
unregister_netdev(dev);
kfree(dev);
}
else
num++;
dev = init_trdev(NULL, 0);
if (!dev)
goto partial;
}
}
unregister_netdev(dev);
kfree(dev);
}
printk(KERN_NOTICE "tmsisa.c: %d cards found.\n", num);
partial:
printk(KERN_NOTICE "skisa.c: %d cards found.\n", num);
/* Probe for cards. */
if (num == 0) {
printk(KERN_NOTICE "tmsisa.c: No cards found.\n");
printk(KERN_NOTICE "skisa.c: No cards found.\n");
return (-ENODEV);
}
return (0);
}
......@@ -442,19 +485,19 @@ int init_module(void)
void cleanup_module(void)
{
struct net_device *dev;
struct tms_isa_card *this_card;
struct sk_isa_card *this_card;
while (tms_isa_card_list) {
dev = tms_isa_card_list->dev;
while (sk_isa_card_list) {
dev = sk_isa_card_list->dev;
unregister_netdev(dev);
release_region(dev->base_addr, TMS_ISA_IO_EXTENT);
release_region(dev->base_addr, SK_ISA_IO_EXTENT);
free_irq(dev->irq, dev);
free_dma(dev->dma);
tmsdev_term(dev);
kfree(dev);
this_card = tms_isa_card_list;
tms_isa_card_list = this_card->next;
this_card = sk_isa_card_list;
sk_isa_card_list = this_card->next;
kfree(this_card);
}
}
......@@ -463,8 +506,8 @@ void cleanup_module(void)
/*
* Local variables:
* compile-command: "gcc -DMODVERSIONS -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c tmsisa.c"
* alt-compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c tmsisa.c"
* compile-command: "gcc -DMODVERSIONS -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c skisa.c"
* alt-compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c skisa.c"
* c-set-style "K&R"
* c-indent-level: 8
* c-basic-offset: 8
......
......@@ -57,6 +57,11 @@
* as well.
* 14-Jan-01 JF Fix DMA on ifdown/ifup sequences. Some
* cleanup.
* 13-Jan-02 JF Add spinlock to fix race condition.
* 09-Nov-02 JF Fixed printks to not SPAM the console during
* normal operation.
* 30-Dec-02 JF Removed incorrect __init from
* tms380tr_init_card.
*
* To do:
* 1. Multi/Broadcast packet handling (this may have fixed itself)
......@@ -68,7 +73,7 @@
*/
#ifdef MODULE
static const char version[] = "tms380tr.c: v1.08 14/01/2001 by Christoph Goos, Adam Fritzler\n";
static const char version[] = "tms380tr.c: v1.10 30/12/2002 by Christoph Goos, Adam Fritzler\n";
#endif
#include <linux/module.h>
......@@ -230,10 +235,10 @@ static int madgemc_sifprobe(struct net_device *dev)
#endif
/* Dummy function */
static int __init tms380tr_init_card(struct net_device *dev)
static int tms380tr_init_card(struct net_device *dev)
{
if(tms380tr_debug > 3)
printk("%s: tms380tr_init_card\n", dev->name);
printk(KERN_DEBUG "%s: tms380tr_init_card\n", dev->name);
return (0);
}
......@@ -251,6 +256,9 @@ int tms380tr_open(struct net_device *dev)
struct net_local *tp = (struct net_local *)dev->priv;
int err;
/* init the spinlock */
spin_lock_init(tp->lock);
/* Reset the hardware here. Don't forget to set the station address. */
if(dev->dma > 0)
......@@ -276,7 +284,7 @@ int tms380tr_open(struct net_device *dev)
tp->timer.data = (unsigned long)dev;
add_timer(&tp->timer);
printk(KERN_INFO "%s: Adapter RAM size: %dK\n",
printk(KERN_DEBUG "%s: Adapter RAM size: %dK\n",
dev->name, tms380tr_read_ptr(dev));
tms380tr_enable_interrupts(dev);
......@@ -339,25 +347,25 @@ static int tms380tr_chipset_init(struct net_device *dev)
tms380tr_init_net_local(dev);
if(tms380tr_debug > 3)
printk(KERN_INFO "%s: Resetting adapter...\n", dev->name);
printk(KERN_DEBUG "%s: Resetting adapter...\n", dev->name);
err = tms380tr_reset_adapter(dev);
if(err < 0)
return (-1);
if(tms380tr_debug > 3)
printk(KERN_INFO "%s: Bringup diags...\n", dev->name);
printk(KERN_DEBUG "%s: Bringup diags...\n", dev->name);
err = tms380tr_bringup_diags(dev);
if(err < 0)
return (-1);
if(tms380tr_debug > 3)
printk(KERN_INFO "%s: Init adapter...\n", dev->name);
printk(KERN_DEBUG "%s: Init adapter...\n", dev->name);
err = tms380tr_init_adapter(dev);
if(err < 0)
return (-1);
if(tms380tr_debug > 3)
printk(KERN_INFO "%s: Done!\n", dev->name);
printk(KERN_DEBUG "%s: Done!\n", dev->name);
return (0);
}
......@@ -628,6 +636,7 @@ static void tms380tr_hardware_send_packet(struct net_device *dev, struct net_loc
TPL *tpl;
short length;
unsigned char *buf;
unsigned long flags;
struct sk_buff *skb;
int i;
dma_addr_t dmabuf, newbuf;
......@@ -639,18 +648,22 @@ static void tms380tr_hardware_send_packet(struct net_device *dev, struct net_loc
* NOTE: We *must* always leave one unused TPL in the chain,
* because otherwise the adapter might send frames twice.
*/
spin_lock_irqsave(&tp->lock, flags);
if(tp->TplFree->NextTPLPtr->BusyFlag) /* No free TPL */
{
if (tms380tr_debug > 0)
printk(KERN_INFO "%s: No free TPL\n", dev->name);
printk(KERN_DEBUG "%s: No free TPL\n", dev->name);
spin_unlock_irqrestore(&tp->lock, flags);
return;
}
/* Send first buffer from queue */
skb = skb_dequeue(&tp->SendSkbQueue);
if(skb == NULL)
{
spin_unlock_irqrestore(&tp->lock, flags);
return;
}
tp->QueueSkb++;
dmabuf = 0;
......@@ -698,6 +711,7 @@ static void tms380tr_hardware_send_packet(struct net_device *dev, struct net_loc
/* Let adapter send the frame. */
tms380tr_exec_sifcmd(dev, CMD_TX_VALID);
spin_unlock_irqrestore(&tp->lock, flags);
}
return;
......@@ -773,7 +787,7 @@ void tms380tr_interrupt(int irq, void *dev_id, struct pt_regs *regs)
unsigned short irq_type;
if(dev == NULL) {
printk("%s: irq %d for unknown device.\n", dev->name, irq);
printk(KERN_INFO "%s: irq %d for unknown device.\n", dev->name, irq);
return;
}
......@@ -785,7 +799,7 @@ void tms380tr_interrupt(int irq, void *dev_id, struct pt_regs *regs)
irq_type &= STS_IRQ_MASK;
if(!tms380tr_chk_ssb(tp, irq_type)) {
printk(KERN_INFO "%s: DATA LATE occurred\n", dev->name);
printk(KERN_DEBUG "%s: DATA LATE occurred\n", dev->name);
break;
}
......@@ -843,7 +857,7 @@ void tms380tr_interrupt(int irq, void *dev_id, struct pt_regs *regs)
break;
default:
printk(KERN_INFO "Unknown Token Ring IRQ (0x%04x)\n", irq_type);
printk(KERN_DEBUG "Unknown Token Ring IRQ (0x%04x)\n", irq_type);
break;
}
......@@ -1377,7 +1391,7 @@ static int tms380tr_bringup_diags(struct net_device *dev)
do {
retry_cnt--;
if(tms380tr_debug > 3)
printk(KERN_INFO "BUD-Status: ");
printk(KERN_DEBUG "BUD-Status: ");
loop_cnt = BUD_MAX_LOOPCNT; /* maximum: three seconds*/
do { /* Inspect BUD results */
loop_cnt--;
......@@ -1386,7 +1400,7 @@ static int tms380tr_bringup_diags(struct net_device *dev)
Status &= STS_MASK;
if(tms380tr_debug > 3)
printk(KERN_INFO " %04X \n", Status);
printk(KERN_DEBUG " %04X \n", Status);
/* BUD successfully completed */
if(Status == STS_INITIALIZE)
return (1);
......@@ -1443,10 +1457,10 @@ static int tms380tr_init_adapter(struct net_device *dev)
if(tms380tr_debug > 3)
{
printk(KERN_INFO "%s: buffer (real): %lx\n", dev->name, (long) &tp->scb);
printk(KERN_INFO "%s: buffer (virt): %lx\n", dev->name, (long) ((char *)&tp->scb - (char *)tp) + tp->dmabuffer);
printk(KERN_INFO "%s: buffer (DMA) : %lx\n", dev->name, (long) tp->dmabuffer);
printk(KERN_INFO "%s: buffer (tp) : %lx\n", dev->name, (long) tp);
printk(KERN_DEBUG "%s: buffer (real): %lx\n", dev->name, (long) &tp->scb);
printk(KERN_DEBUG "%s: buffer (virt): %lx\n", dev->name, (long) ((char *)&tp->scb - (char *)tp) + tp->dmabuffer);
printk(KERN_DEBUG "%s: buffer (DMA) : %lx\n", dev->name, (long) tp->dmabuffer);
printk(KERN_DEBUG "%s: buffer (tp) : %lx\n", dev->name, (long) tp);
}
/* Maximum: three initialization retries */
retry_cnt = INIT_MAX_RETRIES;
......@@ -1797,7 +1811,7 @@ static void tms380tr_chk_irq(struct net_device *dev)
if(tms380tr_debug > 3)
{
printk("%s: AdapterCheckBlock: ", dev->name);
printk(KERN_DEBUG "%s: AdapterCheckBlock: ", dev->name);
for (i = 0; i < 4; i++)
printk("%04X", AdapterCheckBlock[i]);
printk("\n");
......@@ -1874,52 +1888,52 @@ static void tms380tr_chk_irq(struct net_device *dev)
break;
case ILLEGAL_OP_CODE:
printk("%s: Illegal operation code in firmware\n",
printk(KERN_INFO "%s: Illegal operation code in firmware\n",
dev->name);
/* Parm[0-3]: adapter internal register R13-R15 */
break;
case PARITY_ERRORS:
printk("%s: Adapter internal bus parity error\n",
printk(KERN_INFO "%s: Adapter internal bus parity error\n",
dev->name);
/* Parm[0-3]: adapter internal register R13-R15 */
break;
case RAM_DATA_ERROR:
printk("%s: RAM data error\n", dev->name);
printk(KERN_INFO "%s: RAM data error\n", dev->name);
/* Parm[0-1]: MSW/LSW address of RAM location. */
break;
case RAM_PARITY_ERROR:
printk("%s: RAM parity error\n", dev->name);
printk(KERN_INFO "%s: RAM parity error\n", dev->name);
/* Parm[0-1]: MSW/LSW address of RAM location. */
break;
case RING_UNDERRUN:
printk("%s: Internal DMA underrun detected\n",
printk(KERN_INFO "%s: Internal DMA underrun detected\n",
dev->name);
break;
case INVALID_IRQ:
printk("%s: Unrecognized interrupt detected\n",
printk(KERN_INFO "%s: Unrecognized interrupt detected\n",
dev->name);
/* Parm[0-3]: adapter internal register R13-R15 */
break;
case INVALID_ERROR_IRQ:
printk("%s: Unrecognized error interrupt detected\n",
printk(KERN_INFO "%s: Unrecognized error interrupt detected\n",
dev->name);
/* Parm[0-3]: adapter internal register R13-R15 */
break;
case INVALID_XOP:
printk("%s: Unrecognized XOP request detected\n",
printk(KERN_INFO "%s: Unrecognized XOP request detected\n",
dev->name);
/* Parm[0-3]: adapter internal register R13-R15 */
break;
default:
printk("%s: Unknown status", dev->name);
printk(KERN_INFO "%s: Unknown status", dev->name);
break;
}
......@@ -2070,14 +2084,14 @@ static void tms380tr_tx_status_irq(struct net_device *dev)
if((HighAc != LowAc) || (HighAc == AC_NOT_RECOGNIZED))
{
printk(KERN_INFO "%s: (DA=%08lX not recognized)",
printk(KERN_DEBUG "%s: (DA=%08lX not recognized)\n",
dev->name,
*(unsigned long *)&tpl->MData[2+2]);
}
else
{
if(tms380tr_debug > 3)
printk("%s: Directed frame tx'd\n",
printk(KERN_DEBUG "%s: Directed frame tx'd\n",
dev->name);
}
}
......@@ -2086,7 +2100,7 @@ static void tms380tr_tx_status_irq(struct net_device *dev)
if(!DIRECTED_FRAME(tpl))
{
if(tms380tr_debug > 3)
printk("%s: Broadcast frame tx'd\n",
printk(KERN_DEBUG "%s: Broadcast frame tx'd\n",
dev->name);
}
}
......@@ -2163,7 +2177,7 @@ static void tms380tr_rcv_status_irq(struct net_device *dev)
tms380tr_update_rcv_stats(tp,ReceiveDataPtr,Length);
if(tms380tr_debug > 3)
printk("%s: Packet Length %04X (%d)\n",
printk(KERN_DEBUG "%s: Packet Length %04X (%d)\n",
dev->name, Length, Length);
/* Indicate the received frame to system the
......@@ -2347,12 +2361,11 @@ int tmsdev_init(struct net_device *dev, unsigned long dmalimit,
if (dev->priv == NULL)
{
struct net_local *tms_local;
dma_addr_t buffer;
dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL | GFP_DMA);
if (dev->priv == NULL)
{
printk("%s: Out of memory for DMA\n",
printk(KERN_INFO "%s: Out of memory for DMA\n",
dev->name);
return -ENOMEM;
}
......@@ -2361,16 +2374,15 @@ int tmsdev_init(struct net_device *dev, unsigned long dmalimit,
init_waitqueue_head(&tms_local->wait_for_tok_int);
tms_local->dmalimit = dmalimit;
tms_local->pdev = pdev;
buffer = pci_map_single(pdev, (void *)tms_local,
tms_local->dmabuffer = pci_map_single(pdev, (void *)tms_local,
sizeof(struct net_local), PCI_DMA_BIDIRECTIONAL);
if (buffer + sizeof(struct net_local) > dmalimit)
if (tms_local->dmabuffer + sizeof(struct net_local) > dmalimit)
{
printk("%s: Memory not accessible for DMA\n",
printk(KERN_INFO "%s: Memory not accessible for DMA\n",
dev->name);
tmsdev_term(dev);
return -ENOMEM;
}
tms_local->dmabuffer = buffer;
}
/* These can be overridden by the card driver if needed */
......@@ -2401,7 +2413,7 @@ struct module *TMS380_module = NULL;
int init_module(void)
{
printk("%s", version);
printk(KERN_DEBUG "%s", version);
TMS380_module = &__this_module;
return 0;
......
......@@ -1135,6 +1135,7 @@ typedef struct net_local {
unsigned short (*sifreadw)(struct net_device *, unsigned short);
void (*sifwritew)(struct net_device *, unsigned short, unsigned short);
spinlock_t lock; /* SMP protection */
void *tmspriv;
} NET_LOCAL;
......
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