patch for i82559-based CardBus card

Dan Brown brown@osdsun1.nrl.navy.mil
Fri Jun 11 09:29:41 1999


I recently purchased an Intel Pro/100 CardBus II pcmcia card for my
laptop.  After a few days of hacking, I have created the attached patch to
eepro100.c (it's against the version included in kernel 2.3.5) which adds:

	- CardBus support (via #ifdef CARDBUS)
	- Some hacks which I found necessary for my card, but which I
suspect are more related to differences between the 82559 and previous
chips.

It works perfectly as a pcmcia module, and it's my hope that people with
non-cardbus (ie, PCI) i82559-based cards (do they exist?) will also find
it useful.

Since this is my first attempt at such a thing, I would greatly appreciate
it if people more familiar with this driver would take a look at this
patch.

I'm also sending this to the pcmcia folks.


---------patch follows---------
397c397,399
< static void speedo_found1(struct device *dev, long ioaddr, int irq,
---
> /* DBB: Make speedo_found1 return dev so that the pcmcia attach function can
>    save it.  This is a bit of a hack -- this should be cleaned up. */
> static struct device * speedo_found1(struct device *dev, long ioaddr, int irq,
495c497
< static void speedo_found1(struct device *dev, long ioaddr, int irq,
---
> static struct device * speedo_found1(struct device *dev, long ioaddr, int irq,
502c504,505
< 	u16 eeprom[0x40];
---
> 	#define EEPROM_SAVE 10
> 	u16 eeprom[EEPROM_SAVE];
521a525,530
> #ifdef CARDBUS
> 		/* DBB: the 8/6 bit test doesn't seem to work for my CardBus card,
> 		   and it works if I force it to 8.  Somebody with access to
> 		   technical documentation should fix this :) */
> 		int addr_len = 8;
> #else
522a532,536
> #endif
> 		/* DBB: My EEPROM checksum doesn't work unless it's computed over
> 		   the entire 256-word EEPROM.  I suspect this is always true of
> 		   cards with 8-bit EEPROMs. */
> 		#define EEPROM_SIZE (1<<addr_len)
524c538
< 		for (j = 0, i = 0; i < 0x40; i++) {
---
> 		for (j = 0, i = 0; i < EEPROM_SIZE; i++) {
526c540,541
< 			eeprom[i] = value;
---
> 			if (i < EEPROM_SAVE)
> 				eeprom[i] = value;
563d577
< 		/* The self-test results must be paragraph aligned. */
565a580
> 		/* The self-test results must be paragraph aligned. */
645a661
> 
647a664,666
> #ifndef CARDBUS
> /* DBB: this test seems to contradict the one in the 'kernel bloat' section
>    above.  Somebody who knows about this lock-up bug should fix this. */
651a671
> #endif
661c681
< 	return;
---
> 	return dev;
1580a1601,1653
> #ifdef CARDBUS
> 
> #include <pcmcia/driver_ops.h>
> 
> static dev_node_t *speedo_attach(dev_locator_t *loc)
> {
> 	u8 irq;
> 	u32 io;
> 	u8 bus, devfn;
> 	struct device *dev;
> 
> 	if (loc->bus != LOC_PCI) return NULL;
> 	bus = loc->b.pci.bus; devfn = loc->b.pci.devfn;
> 	printk(KERN_INFO "speedo_attach(bus %d, function %d)\n", bus, devfn);
> 	pcibios_read_config_dword(bus, devfn, PCI_BASE_ADDRESS_1, &io);
> 	pcibios_read_config_byte(bus, devfn, PCI_INTERRUPT_LINE, &irq);
> 	io &= ~3;
> 	dev = speedo_found1(NULL, io, irq, -1);
> 	if (dev) {
> 		dev_node_t *node = kmalloc(sizeof(dev_node_t), GFP_KERNEL);
> 		strcpy(node->dev_name, dev->name);
> 		node->major = node->minor = 0;
> 		node->next = NULL;
> 		MOD_INC_USE_COUNT;
> 		return node;
> 	}
> 	return NULL;
> }
> 
> static void speedo_detach(dev_node_t *node)
> {
> 	struct device **devp, **next;
> 	printk(KERN_INFO "speedo_detach(%s)\n", node->dev_name);
> 	for (devp = &root_speedo_dev; *devp; devp = next) {
> 		next = &((struct speedo_private *)(*devp)->priv)->next_module;
> 		if (strcmp((*devp)->name, node->dev_name) == 0) break;
> 	}
> 	if (*devp) {
> 		unregister_netdev(*devp);
> 		kfree(*devp);
> 		*devp = *next;
> 		kfree(node);
> 		MOD_DEC_USE_COUNT;
> 	}
> }
> 
> struct driver_operations speedo_ops = {
> 	"speedo_cb", speedo_attach, NULL, NULL, speedo_detach
> };
> 
> #endif  /* Cardbus support */
> 
> 
1592a1666
> /* DBB: Should this line be #ifndef CARDBUS?  Probably not... */
1593a1668,1672
> 
> #ifdef CARDBUS
> 	register_driver(&speedo_ops);
> 	return 0;
> #else
1595a1675
> #endif
1601a1682,1685
> 
> #ifdef CARDBUS
> 	unregister_driver(&speedo_ops);
> #endif