patch-2.4.6 linux/drivers/net/tulip/tulip_core.c
Next file: linux/drivers/net/tun.c
Previous file: linux/drivers/net/tulip/tulip.h
Back to the patch index
Back to the overall index
- Lines: 637
- Date:
Mon Jul 2 14:03:04 2001
- Orig file:
v2.4.5/linux/drivers/net/tulip/tulip_core.c
- Orig date:
Sun May 20 12:11:38 2001
diff -u --recursive --new-file v2.4.5/linux/drivers/net/tulip/tulip_core.c linux/drivers/net/tulip/tulip_core.c
@@ -1,4 +1,4 @@
-/* tulip_core.c: A DEC 21040-family ethernet driver for Linux. */
+/* tulip_core.c: A DEC 21x4x-family ethernet driver for Linux. */
/*
Maintained by Jeff Garzik <jgarzik@mandrakesoft.com>
@@ -15,8 +15,8 @@
*/
#define DRV_NAME "tulip"
-#define DRV_VERSION "0.9.15-pre2"
-#define DRV_RELDATE "May 16, 2001"
+#define DRV_VERSION "0.9.15-pre6"
+#define DRV_RELDATE "July 2, 2001"
#include <linux/config.h>
#include <linux/module.h>
@@ -276,7 +276,7 @@
/* On some chip revs we must set the MII/SYM port before the reset!? */
if (tp->mii_cnt || (tp->mtable && tp->mtable->has_mii))
- tulip_outl_csr (tp, 0x00040000, CSR6);
+ outl(0x00040000, ioaddr + CSR6);
/* Reset the chip, holding bit 0 set at least 50 PCI cycles. */
outl(0x00000001, ioaddr + CSR0);
@@ -291,6 +291,11 @@
if (tulip_debug > 1)
printk(KERN_DEBUG "%s: tulip_up(), irq==%d.\n", dev->name, dev->irq);
+ outl(tp->rx_ring_dma, ioaddr + CSR3);
+ outl(tp->tx_ring_dma, ioaddr + CSR4);
+ tp->cur_rx = tp->cur_tx = 0;
+ tp->dirty_rx = tp->dirty_tx = 0;
+
if (tp->chip_id == PNIC2) {
u32 addr_high = (dev->dev_addr[1]<<8) + (dev->dev_addr[0]<<0);
/* This address setting does not appear to impact chip operation?? */
@@ -340,9 +345,6 @@
tp->cur_tx++;
}
- outl(tp->rx_ring_dma, ioaddr + CSR3);
- outl(tp->tx_ring_dma, ioaddr + CSR4);
-
tp->saved_if_port = dev->if_port;
if (dev->if_port == 0)
dev->if_port = tp->default_port;
@@ -409,7 +411,7 @@
printk(KERN_INFO "%s: Using MII transceiver %d, status "
"%4.4x.\n",
dev->name, tp->phys[0], tulip_mdio_read(dev, tp->phys[0], 1));
- tulip_outl_csr(tp, csr6_mask_defstate, CSR6);
+ outl(csr6_mask_defstate, ioaddr + CSR6);
tp->csr6 = csr6_mask_hdcap;
dev->if_port = 11;
outl(0x0000, ioaddr + CSR13);
@@ -455,26 +457,26 @@
tulip_select_media(dev, 1);
/* Start the chip's Tx to process setup frame. */
- tulip_outl_csr(tp, tp->csr6, CSR6);
- tulip_outl_csr(tp, tp->csr6 | csr6_st, CSR6);
+ tulip_stop_rxtx(tp);
+ barrier();
+ udelay(5);
+ outl(tp->csr6 | TxOn, ioaddr + CSR6);
/* Enable interrupts by setting the interrupt mask. */
outl(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR5);
outl(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR7);
- tulip_outl_csr(tp, tp->csr6 | csr6_st | csr6_sr, CSR6);
+ tulip_start_rxtx(tp);
outl(0, ioaddr + CSR2); /* Rx poll demand */
if (tulip_debug > 2) {
- printk(KERN_DEBUG "%s: Done tulip_open(), CSR0 %8.8x, CSR5 %8.8x CSR6 %8.8x.\n",
+ printk(KERN_DEBUG "%s: Done tulip_up(), CSR0 %8.8x, CSR5 %8.8x CSR6 %8.8x.\n",
dev->name, inl(ioaddr + CSR0), inl(ioaddr + CSR5),
inl(ioaddr + CSR6));
}
+
/* Set the timer to switch to check for link beat and perhaps switch
to an alternate media type. */
- init_timer(&tp->timer);
tp->timer.expires = RUN_AT(next_tick);
- tp->timer.data = (unsigned long)dev;
- tp->timer.function = tulip_tbl[tp->chip_id].media_timer;
add_timer(&tp->timer);
}
@@ -626,7 +628,7 @@
if (tp->fc_bit && test_bit(tp->fc_bit,&netdev_fc_xoff))
printk("BUG tx_timeout restarting rx when fc on\n");
#endif
- tulip_restart_rxtx(tp, tp->csr6);
+ tulip_restart_rxtx(tp);
/* Trigger an immediate transmit demand. */
outl(0, ioaddr + CSR1);
@@ -645,8 +647,6 @@
struct tulip_private *tp = (struct tulip_private *)dev->priv;
int i;
- tp->cur_rx = tp->cur_tx = 0;
- tp->dirty_rx = tp->dirty_tx = 0;
tp->susp_rx = 0;
tp->ttimer = 0;
tp->nir = 0;
@@ -742,6 +742,41 @@
return 0;
}
+static void tulip_release_unconsumed_tx_buffers(struct tulip_private *tp)
+{
+ unsigned int dirty_tx;
+
+ for (dirty_tx = tp->dirty_tx ; tp->cur_tx - dirty_tx > 0;
+ dirty_tx++) {
+ int entry = dirty_tx % TX_RING_SIZE;
+ int status = le32_to_cpu(tp->tx_ring[entry].status);
+
+ if (status > 0)
+ break; /* It has been Txed */
+
+ /* Check for Rx filter setup frames. */
+ if (tp->tx_buffers[entry].skb == NULL) {
+ /* test because dummy frames not mapped */
+ if (tp->tx_buffers[entry].mapping)
+ pci_unmap_single(tp->pdev,
+ tp->tx_buffers[entry].mapping,
+ sizeof(tp->setup_frame),
+ PCI_DMA_TODEVICE);
+ continue;
+ }
+ tp->stats.tx_errors++;
+
+ pci_unmap_single(tp->pdev, tp->tx_buffers[entry].mapping,
+ tp->tx_buffers[entry].skb->len,
+ PCI_DMA_TODEVICE);
+
+ /* Free the original skb. */
+ dev_kfree_skb_irq(tp->tx_buffers[entry].skb);
+ tp->tx_buffers[entry].skb = NULL;
+ tp->tx_buffers[entry].mapping = 0;
+ }
+}
+
static void tulip_down (struct net_device *dev)
{
long ioaddr = dev->base_addr;
@@ -756,7 +791,13 @@
outl (0x00000000, ioaddr + CSR7);
/* Stop the Tx and Rx processes. */
- tulip_stop_rxtx(tp, inl(ioaddr + CSR6));
+ tulip_stop_rxtx(tp);
+
+ /* prepare receive buffers */
+ tulip_refill_rx(dev);
+
+ /* release any unconsumed transmit buffers */
+ tulip_release_unconsumed_tx_buffers(tp);
/* 21040 -- Leave the card in 10baseT state. */
if (tp->chip_id == DC21040)
@@ -767,6 +808,10 @@
spin_unlock_irqrestore (&tp->lock, flags);
+ init_timer(&tp->timer);
+ tp->timer.data = (unsigned long)dev;
+ tp->timer.function = tulip_tbl[tp->chip_id].media_timer;
+
dev->if_port = tp->saved_if_port;
/* Leave the driver in snooze, not sleep, mode. */
@@ -879,66 +924,72 @@
{
struct tulip_private *tp = dev->priv;
long ioaddr = dev->base_addr;
- u16 *data = (u16 *) & rq->ifr_data;
+ struct mii_ioctl_data *data = (struct mii_ioctl_data *) & rq->ifr_data;
const unsigned int phy_idx = 0;
int phy = tp->phys[phy_idx] & 0x1f;
- unsigned int regnum = data[1];
+ unsigned int regnum = data->reg_num;
switch (cmd) {
case SIOCETHTOOL:
return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
- case SIOCDEVPRIVATE: /* Get the address of the PHY in use. */
+
+ case SIOCGMIIPHY: /* Get address of MII PHY in use. */
+ case SIOCDEVPRIVATE: /* for binary compat, remove in 2.5 */
if (tp->mii_cnt)
- data[0] = phy;
+ data->phy_id = phy;
else if (tp->flags & HAS_NWAY)
- data[0] = 32;
+ data->phy_id = 32;
else if (tp->chip_id == COMET)
- data[0] = 1;
+ data->phy_id = 1;
else
return -ENODEV;
- case SIOCDEVPRIVATE + 1: /* Read the specified MII register. */
- if (data[0] == 32 && (tp->flags & HAS_NWAY)) {
+
+ case SIOCGMIIREG: /* Read MII PHY register. */
+ case SIOCDEVPRIVATE+1: /* for binary compat, remove in 2.5 */
+ if (data->phy_id == 32 && (tp->flags & HAS_NWAY)) {
int csr12 = inl (ioaddr + CSR12);
int csr14 = inl (ioaddr + CSR14);
switch (regnum) {
case 0:
if (((csr14<<5) & 0x1000) ||
(dev->if_port == 5 && tp->nwayset))
- data[3] = 0x1000;
+ data->val_out = 0x1000;
else
- data[3] = (tulip_media_cap[dev->if_port]&MediaIs100 ? 0x2000 : 0)
+ data->val_out = (tulip_media_cap[dev->if_port]&MediaIs100 ? 0x2000 : 0)
| (tulip_media_cap[dev->if_port]&MediaIsFD ? 0x0100 : 0);
break;
case 1:
- data[3] =
+ data->val_out =
0x1848 +
((csr12&0x7000) == 0x5000 ? 0x20 : 0) +
((csr12&0x06) == 6 ? 0 : 4);
if (tp->chip_id != DC21041)
- data[3] |= 0x6048;
+ data->val_out |= 0x6048;
break;
case 4:
/* Advertised value, bogus 10baseTx-FD value from CSR6. */
- data[3] =
+ data->val_out =
((inl(ioaddr + CSR6) >> 3) & 0x0040) +
((csr14 >> 1) & 0x20) + 1;
if (tp->chip_id != DC21041)
- data[3] |= ((csr14 >> 9) & 0x03C0);
+ data->val_out |= ((csr14 >> 9) & 0x03C0);
break;
- case 5: data[3] = tp->lpar; break;
- default: data[3] = 0; break;
+ case 5: data->val_out = tp->lpar; break;
+ default: data->val_out = 0; break;
}
} else {
- data[3] = tulip_mdio_read (dev, data[0] & 0x1f, regnum);
+ data->val_out = tulip_mdio_read (dev, data->phy_id & 0x1f, regnum);
}
return 0;
- case SIOCDEVPRIVATE + 2: /* Write the specified MII register */
+
+ case SIOCSMIIREG: /* Write MII PHY register. */
+ case SIOCDEVPRIVATE+2: /* for binary compat, remove in 2.5 */
if (!capable (CAP_NET_ADMIN))
return -EPERM;
if (regnum & ~0x1f)
return -EINVAL;
- if (data[0] == phy) {
- u16 value = data[2];
+ if (data->phy_id == phy) {
+ u16 value = data->val_in;
switch (regnum) {
case 0: /* Check for autonegotiation on or reset. */
tp->full_duplex_lock = (value & 0x9000) ? 0 : 1;
@@ -947,19 +998,19 @@
break;
case 4:
tp->advertising[phy_idx] =
- tp->mii_advertise = data[2];
+ tp->mii_advertise = data->val_in;
break;
}
}
- if (data[0] == 32 && (tp->flags & HAS_NWAY)) {
- u16 value = data[2];
+ if (data->phy_id == 32 && (tp->flags & HAS_NWAY)) {
+ u16 value = data->val_in;
if (regnum == 0) {
if ((value & 0x1200) == 0x1200)
t21142_start_nway (dev);
} else if (regnum == 4)
tp->sym_advertise = value;
} else {
- tulip_mdio_write (dev, data[0] & 0x1f, regnum, data[2]);
+ tulip_mdio_write (dev, data->phy_id & 0x1f, regnum, data->val_in);
}
return 0;
default:
@@ -1108,7 +1159,7 @@
else
filterbit = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
filterbit &= 0x3f;
- set_bit(filterbit, mc_filter);
+ mc_filter[filterbit >> 5] |= cpu_to_le32(1 << (filterbit & 31));
if (tulip_debug > 2) {
printk(KERN_INFO "%s: Added filter for %2.2x:%2.2x:%2.2x:"
"%2.2x:%2.2x:%2.2x %8.8x bit %d.\n", dev->name,
@@ -1193,95 +1244,96 @@
spin_unlock_irqrestore(&tp->lock, flags);
}
- /* Can someone explain to me what the OR here is supposed to accomplish???? */
- tulip_outl_csr(tp, csr6 | 0x0000, CSR6);
+ outl(csr6, ioaddr + CSR6);
}
+#ifdef CONFIG_TULIP_MWI
static void __devinit tulip_mwi_config (struct pci_dev *pdev,
struct net_device *dev)
{
struct tulip_private *tp = dev->priv;
- u8 pci_cacheline;
+ u8 cache;
u16 pci_command, new_command;
- unsigned mwi = 1;
+ u32 csr0;
if (tulip_debug > 3)
printk(KERN_DEBUG "%s: tulip_mwi_config()\n", pdev->slot_name);
- /* get a sane cache line size, if possible */
- pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &pci_cacheline);
- if (pci_cacheline < (SMP_CACHE_BYTES / 4))
- pci_cacheline = SMP_CACHE_BYTES / 4;
- if (pci_cacheline > TULIP_MAX_CACHE_LINE)
- pci_cacheline = TULIP_MAX_CACHE_LINE;
- switch (pci_cacheline) {
- case 8:
- case 16:
- case 32: break;
- default: pci_cacheline = TULIP_MIN_CACHE_LINE; break;
+ tp->csr0 = 0;
+
+ /* check for sane cache line size. from acenic.c. */
+ pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache);
+ if ((cache << 2) != SMP_CACHE_BYTES) {
+ printk(KERN_WARNING "%s: PCI cache line size set incorrectly "
+ "(%i bytes) by BIOS/FW, correcting to %i\n",
+ pdev->slot_name, (cache << 2), SMP_CACHE_BYTES);
+ pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE,
+ SMP_CACHE_BYTES >> 2);
+ udelay(5);
}
- pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, pci_cacheline);
- /* read back the result. if zero, or if a buggy chip rev,
- * disable MWI
- */
- pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &pci_cacheline);
- if (!pci_cacheline || (tp->chip_id == DC21143 && tp->revision == 65))
- mwi = 0;
-
- /* re-clamp cache line values to ones supported by tulip */
- /* From this point forward, 'pci_cacheline' is really
- * the value used for csr0 cache alignment and
- * csr0 programmable burst length
+ /* read cache line size again, hardware may not have accepted
+ * our cache line size change
*/
- switch (pci_cacheline) {
- case 0:
- case 8:
- case 16:
- case 32: break;
- default: pci_cacheline = TULIP_MIN_CACHE_LINE; break;
- }
+ pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache);
+ if (!cache)
+ goto out;
+
+ /* if we have any cache line size at all, we can do MRM */
+ csr0 |= MRM;
+
+ /* ...and barring hardware bugs, MWI */
+ if (!(tp->chip_id == DC21143 && tp->revision == 65))
+ csr0 |= MWI;
/* set or disable MWI in the standard PCI command bit.
* Check for the case where mwi is desired but not available
*/
pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
- if (mwi) new_command = pci_command | PCI_COMMAND_INVALIDATE;
+ if (csr0 & MWI) new_command = pci_command | PCI_COMMAND_INVALIDATE;
else new_command = pci_command & ~PCI_COMMAND_INVALIDATE;
if (new_command != pci_command) {
pci_write_config_word(pdev, PCI_COMMAND, new_command);
+ udelay(5);
pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
- if ((new_command != pci_command) && mwi &&
- ((pci_command & PCI_COMMAND_INVALIDATE) == 0))
- mwi = 0;
+ if ((csr0 & MWI) && (!(pci_command & PCI_COMMAND_INVALIDATE)))
+ csr0 &= ~MWI;
}
- tp->csr0 = MRL | MRM;
-
- /* if no PCI cache line size, bail out with minimal
- * burst size and cache alignment of 8 dwords.
- * We always want to have some sort of limit.
+ /* assign per-cacheline-size cache alignment and
+ * burst length values
*/
- if (!pci_cacheline) {
- tp->csr0 |= (8 << BurstLenShift) | (1 << CALShift);
+ switch (cache) {
+ case 8:
+ csr0 |= MRL | (1 << CALShift) | (16 << BurstLenShift);
+ break;
+ case 16:
+ csr0 |= MRL | (2 << CALShift) | (16 << BurstLenShift);
+ break;
+ case 32:
+ csr0 |= MRL | (3 << CALShift) | (32 << BurstLenShift);
+ break;
+ default:
goto out;
}
+
+ tp->csr0 = csr0;
+ goto out;
- /* finally, build the csr0 value */
- if (mwi)
- tp->csr0 |= MWI;
- tp->csr0 |= (pci_cacheline << BurstLenShift);
- switch (pci_cacheline) {
- case 8: tp->csr0 |= (1 << CALShift);
- case 16: tp->csr0 |= (2 << CALShift);
- case 32: tp->csr0 |= (3 << CALShift);
+early_out:
+ if (csr0 & MWI) {
+ pci_command &= ~PCI_COMMAND_INVALIDATE;
+ pci_write_config_word(pdev, PCI_COMMAND, pci_command);
+ csr0 &= ~MWI;
}
+ tp->csr0 = csr0 | (8 << BurstLenShift) | (1 << CALShift);
out:
if (tulip_debug > 2)
- printk(KERN_DEBUG "%s: MWI config mwi=%d, cacheline=%d, csr0=%08x\n",
- pdev->slot_name, mwi, pci_cacheline, tp->csr0);
+ printk(KERN_DEBUG "%s: MWI config cacheline=%d, csr0=%08x\n",
+ pdev->slot_name, cache, csr0);
}
+#endif
static int __devinit tulip_init_one (struct pci_dev *pdev,
const struct pci_device_id *ent)
@@ -1402,6 +1454,13 @@
if (pci_request_regions (pdev, "tulip"))
goto err_out_free_netdev;
+#ifndef USE_IO_OPS
+ ioaddr = (unsigned long) ioremap (pci_resource_start (pdev, 1),
+ tulip_tbl[chip_idx].io_size);
+ if (!ioaddr)
+ goto err_out_free_res;
+#endif
+
pci_set_master(pdev);
pci_read_config_byte (pdev, PCI_REVISION_ID, &chip_rev);
@@ -1417,7 +1476,7 @@
sizeof(struct tulip_tx_desc) * TX_RING_SIZE,
&tp->rx_ring_dma);
if (!tp->rx_ring)
- goto err_out_free_res;
+ goto err_out_mtable;
tp->tx_ring = (struct tulip_tx_desc *)(tp->rx_ring + RX_RING_SIZE);
tp->tx_ring_dma = tp->rx_ring_dma + sizeof(struct tulip_rx_desc) * RX_RING_SIZE;
@@ -1429,15 +1488,20 @@
tp->csr0 = csr0;
spin_lock_init(&tp->lock);
spin_lock_init(&tp->mii_lock);
+ init_timer(&tp->timer);
+ tp->timer.data = (unsigned long)dev;
+ tp->timer.function = tulip_tbl[tp->chip_id].media_timer;
dev->base_addr = ioaddr;
dev->irq = irq;
+#ifdef CONFIG_TULIP_MWI
if (!force_csr0 && (tp->flags & HAS_PCI_MWI))
tulip_mwi_config (pdev, dev);
+#endif
/* Stop the chip's Tx and Rx processes. */
- tulip_stop_rxtx(tp, inl(ioaddr + CSR6));
+ tulip_stop_rxtx(tp);
/* Clear the missed-packet counter. */
inl(ioaddr + CSR8);
@@ -1600,7 +1664,7 @@
dev->set_multicast_list = set_rx_mode;
if (register_netdev(dev))
- goto err_out_mtable;
+ goto err_out_free_ring;
printk(KERN_INFO "%s: %s rev %d at %#3lx,",
dev->name, tulip_tbl[chip_idx].chip_name, chip_rev, ioaddr);
@@ -1631,7 +1695,7 @@
outl(0x00000000, ioaddr + CSR13);
outl(0xFFFFFFFF, ioaddr + CSR14);
outl(0x00000008, ioaddr + CSR15); /* Listen on AUI also. */
- tulip_outl_csr(tp, inl(ioaddr + CSR6) | csr6_fd, CSR6);
+ outl(inl(ioaddr + CSR6) | csr6_fd, ioaddr + CSR6);
outl(0x0000EF01, ioaddr + CSR13);
break;
case DC21040:
@@ -1647,10 +1711,10 @@
case DC21142:
case PNIC2:
if (tp->mii_cnt || tulip_media_cap[dev->if_port] & MediaIsMII) {
- tulip_outl_csr(tp, csr6_mask_defstate, CSR6);
+ outl(csr6_mask_defstate, ioaddr + CSR6);
outl(0x0000, ioaddr + CSR13);
outl(0x0000, ioaddr + CSR14);
- tulip_outl_csr(tp, csr6_mask_hdcap, CSR6);
+ outl(csr6_mask_hdcap, ioaddr + CSR6);
} else
t21142_start_nway(dev);
break;
@@ -1658,21 +1722,21 @@
if ( ! tp->mii_cnt) {
tp->nway = 1;
tp->nwayset = 0;
- tulip_outl_csr(tp, csr6_ttm | csr6_ca, CSR6);
+ outl(csr6_ttm | csr6_ca, ioaddr + CSR6);
outl(0x30, ioaddr + CSR12);
- tulip_outl_csr(tp, 0x0001F078, CSR6);
- tulip_outl_csr(tp, 0x0201F078, CSR6); /* Turn on autonegotiation. */
+ outl(0x0001F078, ioaddr + CSR6);
+ outl(0x0201F078, ioaddr + CSR6); /* Turn on autonegotiation. */
}
break;
case MX98713:
case COMPEX9881:
- tulip_outl_csr(tp, 0x00000000, CSR6);
+ outl(0x00000000, ioaddr + CSR6);
outl(0x000711C0, ioaddr + CSR14); /* Turn on NWay. */
outl(0x00000001, ioaddr + CSR13);
break;
case MX98715:
case MX98725:
- tulip_outl_csr(tp, 0x01a80000, CSR6);
+ outl(0x01a80000, ioaddr + CSR6);
outl(0xFFFFFFFF, ioaddr + CSR14);
outl(0x00001000, ioaddr + CSR12);
break;
@@ -1686,18 +1750,31 @@
return 0;
+err_out_free_ring:
+ pci_free_consistent (pdev,
+ sizeof (struct tulip_rx_desc) * RX_RING_SIZE +
+ sizeof (struct tulip_tx_desc) * TX_RING_SIZE,
+ tp->rx_ring, tp->rx_ring_dma);
+
err_out_mtable:
if (tp->mtable)
kfree (tp->mtable);
+#ifndef USE_IO_OPS
+ iounmap((void *)ioaddr);
+#endif
+
err_out_free_res:
pci_release_regions (pdev);
+
err_out_free_netdev:
kfree (dev);
return -ENODEV;
}
-static void tulip_suspend (struct pci_dev *pdev)
+#ifdef CONFIG_PM
+
+static int tulip_suspend (struct pci_dev *pdev, u32 state)
{
struct net_device *dev = pci_get_drvdata(pdev);
@@ -1706,10 +1783,11 @@
tulip_down (dev);
/* pci_power_off(pdev, -1); */
}
+ return 0;
}
-static void tulip_resume(struct pci_dev *pdev)
+static int tulip_resume(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
@@ -1721,8 +1799,11 @@
tulip_up (dev);
netif_device_attach (dev);
}
+ return 0;
}
+#endif /* CONFIG_PM */
+
static void __devexit tulip_remove_one (struct pci_dev *pdev)
{
@@ -1740,6 +1821,9 @@
unregister_netdev (dev);
if (tp->mtable)
kfree (tp->mtable);
+#ifndef USE_IO_OPS
+ iounmap((void *)dev->base_addr);
+#endif
kfree (dev);
pci_release_regions (pdev);
pci_set_drvdata (pdev, NULL);
@@ -1753,8 +1837,10 @@
id_table: tulip_pci_tbl,
probe: tulip_init_one,
remove: tulip_remove_one,
+#ifdef CONFIG_PM
suspend: tulip_suspend,
resume: tulip_resume,
+#endif /* CONFIG_PM */
};
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)