diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-02-04 07:40:19 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-02-04 07:40:19 +0000 |
commit | 33263fc5f9ac8e8cb2b22d06af3ce5ac1dd815e4 (patch) | |
tree | 2d1b86a40bef0958a68cf1a2eafbeb0667a70543 /drivers/net/tlan.c | |
parent | 216f5f51aa02f8b113aa620ebc14a9631a217a00 (diff) |
Merge with Linux 2.3.32.
Diffstat (limited to 'drivers/net/tlan.c')
-rw-r--r-- | drivers/net/tlan.c | 89 |
1 files changed, 57 insertions, 32 deletions
diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c index cbbee8532..00ae312fa 100644 --- a/drivers/net/tlan.c +++ b/drivers/net/tlan.c @@ -31,6 +31,8 @@ * new PCI BIOS interface. * Alan Cox <alan@redhat.com>: Fixed the out of memory * handling. + * + * Torben Mathiasen <torben.mathiasen@compaq.com> New Maintainer! * ********************************************************************/ @@ -43,7 +45,7 @@ #include <linux/pci.h> #include <linux/etherdevice.h> #include <linux/delay.h> - +#include <linux/spinlock.h> typedef u32 (TLanIntVectorFunc)( struct net_device *, u16 ); @@ -234,13 +236,15 @@ static inline void TLan_SetTimer( struct net_device *dev, u32 ticks, u32 type ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; + unsigned long flags; - cli(); + spin_lock_irqsave(&priv->lock, flags); if ( priv->timer.function != NULL ) { + spin_unlock_irqrestore(&priv->lock, flags); return; } priv->timer.function = &TLan_Timer; - sti(); + spin_unlock_irqrestore(&priv->lock, flags); priv->timer.data = (unsigned long) dev; priv->timer.expires = jiffies + ticks; @@ -336,6 +340,8 @@ extern int init_module(void) priv->speed = speed; priv->sa_int = sa_int; priv->debug = debug; + + spin_lock_init(&priv->lock); ether_setup( dev ); @@ -464,9 +470,6 @@ extern int tlan_probe( struct net_device *dev ) priv = (TLanPrivateInfo *) dev->priv; - dev->name = priv->devName; - strcpy( priv->devName, " " ); - dev = init_etherdev( dev, sizeof(TLanPrivateInfo) ); dev->base_addr = io_base; @@ -485,7 +488,7 @@ extern int tlan_probe( struct net_device *dev ) } priv->sa_int = dev->mem_start & 0x02; priv->debug = dev->mem_end; - + spin_lock_init(&priv->lock); printk("TLAN %d.%d: %s irq=%2d io=%04x, %s, Rev. %d\n", TLanVersionMajor, @@ -770,6 +773,7 @@ int TLan_StartTx( struct sk_buff *skb, struct net_device *dev ) TLanList *tail_list; u8 *tail_buffer; int pad; + unsigned long flags; if ( ! priv->phyOnline ) { TLAN_DBG( TLAN_DEBUG_TX, "TLAN TRANSMIT: %s PHY is not ready\n", dev->name ); @@ -810,7 +814,7 @@ int TLan_StartTx( struct sk_buff *skb, struct net_device *dev ) tail_list->buffer[1].address = 0; } - cli(); + spin_lock_irqsave(&priv->lock, flags); tail_list->cStat = TLAN_CSTAT_READY; if ( ! priv->txInProgress ) { priv->txInProgress = 1; @@ -826,7 +830,7 @@ int TLan_StartTx( struct sk_buff *skb, struct net_device *dev ) ( priv->txList + ( priv->txTail - 1 ) )->forward = virt_to_bus( tail_list ); } } - sti(); + spin_unlock_irqrestore(&priv->lock, flags); CIRC_INC( priv->txTail, TLAN_NUM_TX_LISTS ); @@ -870,10 +874,12 @@ void TLan_HandleInterrupt(int irq, void *dev_id, struct pt_regs *regs) u32 host_cmd; u16 host_int; int type; + TLanPrivateInfo *priv; dev = (struct net_device *) dev_id; + priv = (TLanPrivateInfo *) dev->priv; - cli(); + spin_lock(&priv->lock); if ( dev->interrupt ) { printk( "TLAN: Re-entering interrupt handler for %s: %ld.\n" , dev->name, dev->interrupt ); } @@ -892,7 +898,7 @@ void TLan_HandleInterrupt(int irq, void *dev_id, struct pt_regs *regs) } dev->interrupt--; - sti(); + spin_unlock(&priv->lock); } /* TLan_HandleInterrupts */ @@ -1130,8 +1136,8 @@ u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int ) printk( "TLAN: Received interrupt for uncompleted TX frame.\n" ); } -#if LINUX_KERNEL_VERSION > 0x20100 - priv->stats->tx_bytes += head_list->frameSize; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0) + priv->stats.tx_bytes += head_list->frameSize; #endif head_list->cStat = TLAN_CSTAT_UNUSED; @@ -1250,8 +1256,8 @@ u32 TLan_HandleRxEOF( struct net_device *dev, u16 host_int ) skb_reserve( skb, 2 ); t = (void *) skb_put( skb, head_list->frameSize ); -#if LINUX_KERNEL_VERSION > 0x20100 - priv->stats->rx_bytes += head_list->frameSize; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0) + priv->stats.rx_bytes += head_list->frameSize; #endif memcpy( t, head_buffer, head_list->frameSize ); @@ -1274,8 +1280,8 @@ u32 TLan_HandleRxEOF( struct net_device *dev, u16 host_int ) skb = (struct sk_buff *) head_list->buffer[9].address; head_list->buffer[9].address = 0; skb_trim( skb, head_list->frameSize ); -#if LINUX_KERNEL_VERSION > 0x20100 - priv->stats->rx_bytes += head_list->frameSize; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0) + priv->stats.rx_bytes += head_list->frameSize; #endif skb->protocol = eth_type_trans( skb, dev ); @@ -1558,6 +1564,7 @@ void TLan_Timer( unsigned long data ) struct net_device *dev = (struct net_device *) data; TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; u32 elapsed; + unsigned long flags; priv->timer.function = NULL; @@ -1581,7 +1588,7 @@ void TLan_Timer( unsigned long data ) TLan_FinishReset( dev ); break; case TLAN_TIMER_ACTIVITY: - cli(); + spin_lock_irqsave(&priv->lock, flags); if ( priv->timer.function == NULL ) { elapsed = jiffies - priv->timerSetAt; if ( elapsed >= TLAN_TIMER_ACT_DELAY ) { @@ -1589,11 +1596,12 @@ void TLan_Timer( unsigned long data ) } else { priv->timer.function = &TLan_Timer; priv->timer.expires = priv->timerSetAt + TLAN_TIMER_ACT_DELAY; - sti(); + spin_unlock_irqrestore(&priv->lock, flags); add_timer( &priv->timer ); + break; } } - sti(); + spin_unlock_irqrestore(&priv->lock, flags); break; default: break; @@ -2435,16 +2443,19 @@ int TLan_MiiReadReg( struct net_device *dev, u16 phy, u16 reg, u16 *val ) { u8 nack; u16 sio, tmp; - u32 i; + u32 i; int err; int minten; + TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; + int irq; + unsigned long flags; err = FALSE; outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR); sio = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO; if ( dev->interrupt == 0 ) - cli(); + spin_lock_irqsave(&priv->lock, flags); dev->interrupt++; TLan_MiiSync(dev->base_addr); @@ -2494,7 +2505,7 @@ int TLan_MiiReadReg( struct net_device *dev, u16 phy, u16 reg, u16 *val ) dev->interrupt--; if ( dev->interrupt == 0 ) - sti(); + spin_unlock_irqrestore(&priv->lock, flags); return err; @@ -2606,12 +2617,14 @@ void TLan_MiiWriteReg( struct net_device *dev, u16 phy, u16 reg, u16 val ) { u16 sio; int minten; + unsigned long flags; + TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR); sio = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO; if ( dev->interrupt == 0 ) - cli(); + spin_lock_irqsave(&priv->lock, flags); dev->interrupt++; TLan_MiiSync( dev->base_addr ); @@ -2636,7 +2649,7 @@ void TLan_MiiWriteReg( struct net_device *dev, u16 phy, u16 reg, u16 val ) dev->interrupt--; if ( dev->interrupt == 0 ) - sti(); + spin_unlock_irqrestore(&priv->lock, flags); } /* TLan_MiiWriteReg */ @@ -2834,29 +2847,41 @@ void TLan_EeReceiveByte( u16 io_base, u8 *data, int stop ) int TLan_EeReadByte( struct net_device *dev, u8 ee_addr, u8 *data ) { int err; + TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; + unsigned long flags; + int ret=0; if ( dev->interrupt == 0 ) - cli(); + spin_lock_irqsave(&priv->lock, flags); dev->interrupt++; TLan_EeSendStart( dev->base_addr ); err = TLan_EeSendByte( dev->base_addr, 0xA0, TLAN_EEPROM_ACK ); if (err) - return 1; + { + ret=1; + goto fail; + } err = TLan_EeSendByte( dev->base_addr, ee_addr, TLAN_EEPROM_ACK ); if (err) - return 2; + { + ret=2; + goto fail; + } TLan_EeSendStart( dev->base_addr ); err = TLan_EeSendByte( dev->base_addr, 0xA1, TLAN_EEPROM_ACK ); if (err) - return 3; + { + ret=3; + goto fail; + } TLan_EeReceiveByte( dev->base_addr, data, TLAN_EEPROM_STOP ); - +fail: dev->interrupt--; if ( dev->interrupt == 0 ) - sti(); + spin_unlock_irqrestore(&priv->lock, flags); - return 0; + return ret; } /* TLan_EeReadByte */ |