Commit ac8d96d0 authored by Steven Parker's avatar Steven Parker Committed by Tim Hockin

drivers/net/eepro100.c: mask the interrupt and do a small delay on close()

parent 20a15907
...@@ -328,6 +328,7 @@ static inline void io_outw(unsigned int val, unsigned long port) ...@@ -328,6 +328,7 @@ static inline void io_outw(unsigned int val, unsigned long port)
All accesses need not be longword aligned. */ All accesses need not be longword aligned. */
enum speedo_offsets { enum speedo_offsets {
SCBStatus = 0, SCBCmd = 2, /* Rx/Command Unit command and status. */ SCBStatus = 0, SCBCmd = 2, /* Rx/Command Unit command and status. */
SCBIntmask = 3,
SCBPointer = 4, /* General purpose pointer. */ SCBPointer = 4, /* General purpose pointer. */
SCBPort = 8, /* Misc. commands and operands. */ SCBPort = 8, /* Misc. commands and operands. */
SCBflash = 12, SCBeeprom = 14, /* EEPROM and flash memory control. */ SCBflash = 12, SCBeeprom = 14, /* EEPROM and flash memory control. */
...@@ -491,6 +492,7 @@ struct speedo_private { ...@@ -491,6 +492,7 @@ struct speedo_private {
unsigned short partner; /* Link partner caps. */ unsigned short partner; /* Link partner caps. */
struct mii_if_info mii_if; /* MII API hooks, info */ struct mii_if_info mii_if; /* MII API hooks, info */
u32 msg_enable; /* debug message level */ u32 msg_enable; /* debug message level */
unsigned char intmask; /* Saved interrupt mask bits */
#ifdef CONFIG_PM #ifdef CONFIG_PM
u32 pm_state[16]; u32 pm_state[16];
#endif #endif
...@@ -539,6 +541,7 @@ static void speedo_refill_rx_buffers(struct net_device *dev, int force); ...@@ -539,6 +541,7 @@ static void speedo_refill_rx_buffers(struct net_device *dev, int force);
static int speedo_rx(struct net_device *dev); static int speedo_rx(struct net_device *dev);
static void speedo_tx_buffer_gc(struct net_device *dev); static void speedo_tx_buffer_gc(struct net_device *dev);
static void speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs); static void speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
static void speedo_intrmask(void *dev, int onoff);
static int speedo_close(struct net_device *dev); static int speedo_close(struct net_device *dev);
static struct net_device_stats *speedo_get_stats(struct net_device *dev); static struct net_device_stats *speedo_get_stats(struct net_device *dev);
static int speedo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static int speedo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
...@@ -1554,6 +1557,29 @@ static void speedo_tx_buffer_gc(struct net_device *dev) ...@@ -1554,6 +1557,29 @@ static void speedo_tx_buffer_gc(struct net_device *dev)
sp->dirty_tx = dirty_tx; sp->dirty_tx = dirty_tx;
} }
/*
* Interrupt mask control
*/
static void
speedo_intrmask(void *dev_instance, int onoff)
{
struct net_device *dev = (struct net_device *)dev_instance;
struct speedo_private *sp;
long ioaddr;
sp = (struct speedo_private *)dev->priv;
ioaddr = dev->base_addr;
if (onoff) {
/* enable */
outb(sp->intmask, ioaddr + SCBIntmask);
} else {
/* disable */
sp->intmask = inb(ioaddr + SCBIntmask);
outw(SCBMaskAll, ioaddr + SCBCmd);
}
}
/* The interrupt handler does all of the Rx thread work and cleans up /* The interrupt handler does all of the Rx thread work and cleans up
after the Tx thread. */ after the Tx thread. */
static void speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs) static void speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
...@@ -1882,8 +1908,15 @@ speedo_close(struct net_device *dev) ...@@ -1882,8 +1908,15 @@ speedo_close(struct net_device *dev)
/* Shut off the media monitoring timer. */ /* Shut off the media monitoring timer. */
del_timer_sync(&sp->timer); del_timer_sync(&sp->timer);
speedo_intrmask(dev, 0);
/* Shutting down the chip nicely fails to disable flow control. So.. */ /* Shutting down the chip nicely fails to disable flow control. So.. */
outl(PortPartialReset, ioaddr + SCBPort); outl(PortPartialReset, ioaddr + SCBPort);
inl(ioaddr + SCBPort); /* flush posted write */
/*
* The chip requires a 10 microsecond quiet period. Wait here!
*/
udelay(10);
free_irq(dev->irq, dev); free_irq(dev->irq, dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment