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