tulip chip driver...

Matthew Jacob (mjacob@feral.com)
Sun, 3 Nov 96 14:56:49 PST




I've tried to get Mr. Becker and/or Manabe to respond- but they must
be busy.

below are patches to the tulip driver that clean up a bit of the PCI
stuff and run the larger etherarrays.

I've tested them. If you want to wait for the nominal owners to
look at them, that's fine- but I have to give the cards back today
so I wanted to come to closure on this...

*** linux/drivers/net/tulip.c-2.1.6 Fri Nov 1 10:03:06 1996
--- linux/drivers/net/tulip.c Fri Nov 1 10:03:06 1996
***************
*** 15,23 ****
*/

static char *version =
! "tulip.c:v0.10 8/11/95 becker@cesdis.gsfc.nasa.gov\n"
! " +0.72 4/17/96 "
! "http://www.dsl.tutics.tut.ac.jp/~linux/tulip\n";

/* A few user-configurable values. */

--- 15,24 ----
*/

static char *version =
! "tulip.c:v0.10 8/11/95 becker@cesdis.gsfc.nasa.gov\n"
! " +0.72 4/17/96 "
! "http://www.dsl.tutics.tut.ac.jp/~linux/tulip\n"
! " +0.01 10/24/96 mjacob@feral.com\n";

/* A few user-configurable values. */

***************
*** 334,339 ****
--- 335,341 ----
int setup_frame[48]; /* Pseudo-Tx frame to init address table. */
void (*port_select)(struct device *dev);
int (*port_fail)(struct device *dev);
+ struct device *next_module;
char *signature;
unsigned int cur_rx, cur_tx; /* The next free ring entry */
unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */
***************
*** 367,373 ****
static void tulip_interrupt(int irq, void *dev_id, struct pt_regs *regs);
static int tulip_close(struct device *dev);
static struct enet_statistics *tulip_get_stats(struct device *dev);
- static struct device *tulip_alloc(struct device *dev);
static void set_multicast_list(struct device *dev);

#define generic21140_fail NULL
--- 369,374 ----
***************
*** 379,384 ****
--- 380,390 ----
static int generic21040_fail(struct device *dev);
static int generic21041_fail(struct device *dev);

+ #ifdef MODULE
+ /* A list of all installed Tulip devices, for removing the driver module. */
+ static struct device *root_tulip_dev = NULL;
+ #endif
+
static struct {
void (*port_select)(struct device *dev);
int (*port_fail)(struct device *dev);
***************
*** 436,442 ****

#ifdef MODULE
static int if_port=TULIP_AUTO_PORT;
- static size_t alloc_size;
#ifdef TULIP_FULL_DUPLEX
static int full_duplex=1;
#else
--- 442,447 ----
***************
*** 1136,1180 ****
}
}

- static struct device *tulip_alloc(struct device *dev)
- {
- struct tulip_private *tp;
- char *buff;
- #ifndef MODULE
- size_t alloc_size;
- #endif
- if (!dev || dev->priv) {
- struct device *olddev = dev;
-
- alloc_size = sizeof(struct device)
- + sizeof(struct tulip_private)
- + ETHNAMSIZ;
- alloc_size = ROUND_UP(alloc_size, 8);
-
- buff = (char *)kmalloc(alloc_size, GFP_KERNEL);
- dev = (struct device *)buff;
- if (dev == NULL) {
- printk("tulip_alloc: kmalloc failed.\n");
- return(NULL);
- }
- tp = (struct tulip_private *)(buff + sizeof(struct device));
- memset(buff, 0, alloc_size);
- dev->priv = (void *)tp;
- dev->name = (char *)(buff + sizeof(struct device)
- + sizeof(struct tulip_private));
- if (olddev) {
- dev->next = olddev->next;
- olddev->next = dev;
- }
- } else {
- alloc_size = ROUND_UP(sizeof(struct tulip_private), 8);
- tp = (struct tulip_private *)kmalloc(alloc_size, GFP_KERNEL);
- memset((void *)tp, 0, alloc_size);
- dev->priv = (void *)tp;
- }
- return(dev);
- }
-
int
tulip_hwinit(struct device *dev, int ioaddr,
int irq, int device_id)
--- 1141,1146 ----
***************
*** 1181,1186 ****
--- 1147,1153 ----
{
/* See note below on the Znyx 315 etherarray. */
static unsigned char last_phys_addr[6] = {0x00, 'L', 'i', 'n', 'u', 'x'};
+ static int last_irq;
char detect_mesg[80], *mesgp=detect_mesg;
struct tulip_private *tp = (struct tulip_private *)dev->priv;
int i;
***************
*** 1250,1260 ****
--- 1217,1229 ----
for (i = 0; i < ETH_ALEN - 1; i++)
dev->dev_addr[i] = last_phys_addr[i];
dev->dev_addr[i] = last_phys_addr[i] + 1;
+ irq = last_irq;
}
for (i = 0; i < ETH_ALEN - 1; i++)
mesgp += sprintf(mesgp, "%2.2x:", dev->dev_addr[i]);
mesgp += sprintf(mesgp, "%2.2x, IRQ %d\n",
last_phys_addr[i] = dev->dev_addr[i], irq);
+ last_irq = irq;

/* copy ethernet address */
if (card_type(tp, device_id,
***************
*** 1276,1282 ****
dev->set_multicast_list = &set_multicast_list;

#ifdef MODULE
- ether_setup(dev);
if (if_port == TULIP_AUTO_PORT)
if_port = TULIP_PORT;
else
--- 1245,1250 ----
***************
*** 1283,1296 ****
tp->port_fix = 1;
dev->if_port = if_port;
tp->full_duplex = full_duplex;
#else
#ifdef TULIP_FULL_DUPLEX
tp->full_duplex = 1;
#endif
- init_etherdev(dev, 0);
dev->if_port = TULIP_PORT;
#endif
-
#ifdef TULIP_FIX_PORT
tp->port_fix = 1;
#endif
--- 1251,1264 ----
tp->port_fix = 1;
dev->if_port = if_port;
tp->full_duplex = full_duplex;
+ tp->next_module = root_tulip_dev;
+ root_tulip_dev = dev;
#else
#ifdef TULIP_FULL_DUPLEX
tp->full_duplex = 1;
#endif
dev->if_port = TULIP_PORT;
#endif
#ifdef TULIP_FIX_PORT
tp->port_fix = 1;
#endif
***************
*** 1321,1334 ****

if (!pcibios_present()) return(-ENODEV);

! for (pci_index = 0; pci_index < 8; pci_index++) {
/* Search for the PCI_DEVICE_ID_DEV_TULIP* chips */
! for (cno = 0; pci_chips[cno] != PCI_DEVICE_ID_NONE; cno ++)
if (pcibios_find_device(PCI_VENDOR_ID_DEC,
pci_chips[cno],
pci_index, &pci_bus,
&pci_device_fn) == 0) {
- struct device *dp;

/* get IO address */
pcibios_read_config_dword(pci_bus, pci_device_fn,
--- 1289,1301 ----

if (!pcibios_present()) return(-ENODEV);

! for (pci_index = 0; pci_index < 0xff; pci_index++) {
/* Search for the PCI_DEVICE_ID_DEV_TULIP* chips */
! for (cno = 0; pci_chips[cno] != PCI_DEVICE_ID_NONE; cno++) {
if (pcibios_find_device(PCI_VENDOR_ID_DEC,
pci_chips[cno],
pci_index, &pci_bus,
&pci_device_fn) == 0) {

/* get IO address */
pcibios_read_config_dword(pci_bus, pci_device_fn,
***************
*** 1336,1354 ****
&pci_ioaddr);
/* Remove I/O space marker in bit 0. */
pci_ioaddr &= ~3;
- for (dp = tulip_head; dp != NULL; dp = dp->next)
- if (dp->base_addr == pci_ioaddr) break;
- if (dp) continue;
/* get IRQ */
! pcibios_read_config_byte(pci_bus, pci_device_fn,
! PCI_INTERRUPT_LINE, &pci_irq);
! #ifdef MODULE
! /* compare requested IRQ/IO address */
! if (dev && dev->base_addr &&
! dev->base_addr != pci_ioaddr) continue;
! #else
! if ((dev = tulip_alloc(dev)) == NULL) break;
! #endif
if (!tulip_head) {
printk(version);
tulip_head = dev;
--- 1303,1316 ----
&pci_ioaddr);
/* Remove I/O space marker in bit 0. */
pci_ioaddr &= ~3;
/* get IRQ */
! pcibios_read_config_byte(pci_bus, pci_device_fn, PCI_INTERRUPT_LINE, &pci_irq);
! dev = init_etherdev(NULL,
! ROUND_UP(sizeof(struct device) +
! sizeof (struct tulip_private) +
! ETHNAMSIZ, 8));
!
! if (dev == NULL) break;
if (!tulip_head) {
printk(version);
tulip_head = dev;
***************
*** 1375,1388 ****
PCI_LATENCY_TIMER, 100);
}
if (tulip_hwinit(dev, pci_ioaddr, pci_irq,
! pci_chips[cno]) < 0) continue;
! num ++;
! #ifdef MODULE
! return(0);
! #endif
#ifdef TULIP_MAX_CARDS
if (num >= TULIP_MAX_CARDS) return(0);
#endif
}
}
return(num > 0 ? 0: -ENODEV);
--- 1337,1350 ----
PCI_LATENCY_TIMER, 100);
}
if (tulip_hwinit(dev, pci_ioaddr, pci_irq,
! pci_chips[cno]) < 0) {
! continue;
! }
! num++;
#ifdef TULIP_MAX_CARDS
if (num >= TULIP_MAX_CARDS) return(0);
#endif
+ }
}
}
return(num > 0 ? 0: -ENODEV);
***************
*** 1389,1430 ****
}

#ifdef MODULE
- #ifdef __alpha__
- #if 1
- static int io = 0xb000;
- #else
- static int io = 0x10400;
- #endif
- #else
- static int io = 0xfc80;
- #endif

! static struct device *mod_dev;

! int init_module(void)
{
! if ((mod_dev = tulip_alloc(0)) == NULL) return(-EIO);
!
! mod_dev->base_addr = io;
! mod_dev->irq = 0;
! mod_dev->init = &tulip_probe;
!
! if (register_netdev(mod_dev)) {
! printk("tulip: register_netdev() returned non-zero.\n");
! kfree_s(mod_dev, alloc_size);
! return -EIO;
! }
! return(0);
}

void
cleanup_module(void)
{
! release_region(mod_dev->base_addr, TULIP_TOTAL_SIZE);
! unregister_netdev(mod_dev);
! kfree_s(mod_dev, alloc_size);
! }

#endif /* MODULE */


--- 1351,1384 ----
}

#ifdef MODULE

! /* The parameters that may be passed in... */
! /* This driver does nothing with options yet. It will later be used to
! pass the full-duplex flag, etc. */
! int debug = -1;

! int
! init_module(void)
{
! root_tulip_dev = NULL;
! return tulip_probe(NULL);
}

void
cleanup_module(void)
{
! struct device *next_dev;

+ /* No need to check MOD_IN_USE, as sys_delete_module() checks. */
+ while (root_tulip_dev) {
+ next_dev =
+ ((struct tulip_private *) root_tulip_dev->priv)->next_module;
+ unregister_netdev(root_tulip_dev);
+ release_region(root_tulip_dev->base_addr, TULIP_TOTAL_SIZE);
+ kfree(root_tulip_dev);
+ root_tulip_dev = next_dev;
+ }
+ }
#endif /* MODULE */


----- End Included Message -----