PCMCIA updates
Subsystems (2)
PATCH 1/1 PCMCIA updates
Here's a patch covering a forward-port of a couple of changes from David Hinds to 2.6. I've tested them, and the ISA/PCI irq fix has been independently tested.
I'm also sending this to Linus/akpm shortly.
| [PCMCIA] fix ISA/PCI interrupt allocation | | Patch from David Hinds | | This is a forward port of a patch for 2.4. This changes interrupt | allocation for 16-bit cards so that if ISA interrupts are all in | use, the bridge's PCI interrupt will be used. | | [PCMCIA] fix half/full duplex selection for pcnet_cs driver | | Patch from David Hinds. | | Another forward port from 2.4; this fixes full/half duplex selection | for certain DL10019 based cards.
drivers/net/pcmcia/pcnet_cs.c +100 -3
@@ -11,7 +11,7 @@ Copyright (C) 1999 David A. Hinds -- [email protected] - pcnet_cs.c 1.149 2002/06/29 06:27:37 + pcnet_cs.c 1.153 2003/11/09 18:53:09 The network driver code is based on Donald Becker's NE2000 code:
@@ -74,7 +74,7 @@MODULE_PARM (pc_debug,"i" ); #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)static char *version = -"pcnet_cs.c 1.149 2002/06/29 06:27:37 (David Hinds)" ; +"pcnet_cs.c 1.153 2003/11/09 18:53:09 (David Hinds)" ;#else #define DEBUG(n, args...)#endif
@@ -871,13 +871,15 @@MII interface support for DL10019 and DL10022 based cards -On the DL10019, the MII IO direction bit is 0x10; on the DL10022 +On the DL10019, the MII IO direction bit is 0x10; on the DL10022 it is 0x20. Setting both bits seems to work on both card types. ======================================================================*/ #define DLINK_GPIO 0x1c#define DLINK_DIAG 0x1d +#define DLINK_EEPROM 0x1e +#define MDIO_SHIFT_CLK 0x80#define MDIO_DATA_OUT 0x40#define MDIO_DIR_WRITE 0x30
@@ -940,6 +942,98 @@outb_p (0x00 , addr); } +/*====================================================================== + +EEPROM access routines for DL10019 and DL10022 based cards + +======================================================================*/ + +#define EE_EEP 0x40 +#define EE_ASIC 0x10 +#define EE_CS 0x08 +#define EE_CK 0x04 +#define EE_DO 0x02 +#define EE_DI 0x01 +#define EE_ADOT 0x01/* DataOut for ASIC */ +#define EE_READ_CMD 0x06 + +#define DL19FDUPLX 0x0400/* DL10019 Full duplex mode */ + +static int read_eeprom (ioaddr_t ioaddr,int location) +{ +int i, retval =0 ; +ioaddr_t ee_addr = ioaddr +DLINK_EEPROM ; +int read_cmd = location | (EE_READ_CMD <<8 ); + +outb (0 , ee_addr); +outb (EE_EEP |EE_CS , ee_addr); + +/* Shift the read command bits out. */ +for (i =10 ; i >=0 ; i--) { +short dataval = (read_cmd & (1 << i)) ?EE_DO :0 ; +outb_p (EE_EEP |EE_CS |dataval, ee_addr); +outb_p (EE_EEP |EE_CS |dataval|EE_CK , ee_addr); + } +outb (EE_EEP |EE_CS , ee_addr); + +for (i =16 ; i >0 ; i--) { +outb_p (EE_EEP |EE_CS |EE_CK , ee_addr); + retval = (retval <<1 ) | ((inb (ee_addr) &EE_DI ) ?1 :0 ); +outb_p (EE_EEP |EE_CS , ee_addr); + } + +/* Terminate the EEPROM access. */ +outb (0 , ee_addr); +return retval; +} + +/* +The internal ASIC registers can be changed by EEPROM READ access +with EE_ASIC bit set. +In ASIC mode, EE_ADOT is used to output the data to the ASIC. +*/ + +static void write_asic (ioaddr_t ioaddr,int location,short asic_data) +{ +int i; +ioaddr_t ee_addr = ioaddr +DLINK_EEPROM ; +short dataval; +int read_cmd = location | (EE_READ_CMD <<8 ); + + asic_data |=read_eeprom (ioaddr, location); + +outb (0 , ee_addr); +outb (EE_ASIC |EE_CS |EE_DI , ee_addr); + + read_cmd = read_cmd >>1 ; + +/* Shift the read command bits out. */ +for (i =9 ; i >=0 ; i--) { + dataval = (read_cmd & (1 << i)) ?EE_DO :0 ; +outb_p (EE_ASIC |EE_CS |EE_DI |dataval, ee_addr); +outb_p (EE_ASIC |EE_CS |EE_DI |dataval|EE_CK , ee_addr); +outb_p (EE_ASIC |EE_CS |EE_DI |dataval, ee_addr); + } +// sync +outb (EE_ASIC |EE_CS , ee_addr); +outb (EE_ASIC |EE_CS |EE_CK , ee_addr); +outb (EE_ASIC |EE_CS , ee_addr); + +for (i =15 ; i >=0 ; i--) { + dataval = (asic_data & (1 << i)) ?EE_ADOT :0 ; +outb_p (EE_ASIC |EE_CS |dataval, ee_addr); +outb_p (EE_ASIC |EE_CS |dataval|EE_CK , ee_addr); +outb_p (EE_ASIC |EE_CS |dataval, ee_addr); + } + +/* Terminate the ASIC access. */ +outb (EE_ASIC |EE_DI , ee_addr); +outb (EE_ASIC |EE_DI |EE_CK , ee_addr); +outb (EE_ASIC |EE_DI , ee_addr); + +outb (0 , ee_addr); +} +/*====================================================================*/ static void set_misc_reg (struct net_device *dev)
@@ -1154,6 +1248,9 @@if (link && (info->flags &IS_DL10022 )) {/* Disable collision detection on full duplex links */ outb ((p &0x0140 ) ?4 :0 , nic_base +DLINK_DIAG ); + }else if (link && (info->flags &IS_DL10019 )) { +/* Disable collision detection on full duplex links */ +write_asic (dev->base_addr,4 , (p &0x140 ) ?DL19FDUPLX :0 ); }if (link) {if (info->phy_id == info->eth_phy) {
drivers/pcmcia/cs.c +8 -12
@@ -1916,7 +1916,7 @@ {struct pcmcia_socket *s;config_t *c; -int ret =0 , irq =0 ; +int ret =CS_IN_USE , irq =0 ;if (CHECK_HANDLE (handle))return CS_BAD_HANDLE ;
@@ -1928,13 +1928,9 @@return CS_CONFIGURATION_LOCKED ;if (c->state &CONFIG_IRQ_REQ )return CS_IN_USE ; - -/* Short cut: if there are no ISA interrupts, then it is PCI */ -if (!s->irq_mask) { - irq = s->pci_irq; - ret = (irq) ?0 :CS_IN_USE ; +#ifdef CONFIG_PCMCIA_PROBE - }else if (s->irq.AssignedIRQ !=0 ) { +if (s->irq.AssignedIRQ !=0 ) {/* If the interrupt is already assigned, it must match */ irq = s->irq.AssignedIRQ;if (req->IRQInfo1 &IRQ_INFO2_VALID ) {
@@ -1943,7 +1939,6 @@ }else ret = ((req->IRQInfo1&IRQ_MASK ) == irq) ?0 :CS_BAD_ARGS ; }else { - ret =CS_IN_USE ;if (req->IRQInfo1 &IRQ_INFO2_VALID ) {u_int try, mask = req->IRQInfo2 & s->irq_mask;for (try =0 ; try <2 ; try++) {
@@ -1958,12 +1953,13 @@ irq = req->IRQInfo1 &IRQ_MASK ; ret = try_irq(req->Attributes, irq, 1); } -#else - }else { - ret =CS_UNSUPPORTED_MODE ; + }#endif +if (ret !=0 ) { +if (!s->pci_irq) +return ret; + irq = s->pci_irq; } -if (ret !=0 )return ret;if (req->Attributes &IRQ_HANDLE_PRESENT ) { if (request_irq(irq, req->Handler,
Signature · 4 lines
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/
2.6 Serial coreQuoted 8 lines · Russell King
| Patch from David Hinds | | This is a forward port of a patch for 2.4. This changes interrupt | allocation for 16-bit cards so that if ISA interrupts are all in | use, the bridge's PCI interrupt will be used.#endif
drivers/pcmcia/cs.c line 1966
Quoted 6 lines
drivers/pcmcia/cs.c +4
-1+if (ret !=0 ) { +if (!s->pci_irq) +return ret; + irq = s->pci_irq; } -if (ret !=0 )return ret;
Very nice to push this, since w/out this my orinoco does not come up.
- Davide