From: Alan Cox <alan@redhat.com>
To: linux-kernel@vger.kernel.org
Subject: PATCH: make the 3c59x/3c90x driver somewhat more reliable
Date: Wed, 16 Jun 2004 17:01:12 -0400 [thread overview]
Message-ID: <20040616210112.GA11858@devserv.devel.redhat.com> (raw)
The existing driver violates basic PCI rules in several places making it
unusable for basic things like DHCP in Fedora Core. This patch removes
all the situations I can find where it writes to the device while in D3
state and breaks stuff
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux-2.6.7/drivers/net/3c59x.c 2.6.7-ac/drivers/net/3c59x.c
--- linux-2.6.7/drivers/net/3c59x.c 2004-06-16 21:11:36.032434312 +0100
+++ 2.6.7-ac/drivers/net/3c59x.c 2004-06-16 21:22:13.580512272 +0100
@@ -884,7 +884,7 @@
static int vortex_probe1(struct device *gendev, long ioaddr, int irq,
int chip_idx, int card_idx);
static void vortex_up(struct net_device *dev);
-static void vortex_down(struct net_device *dev);
+static void vortex_down(struct net_device *dev, int final);
static int vortex_open(struct net_device *dev);
static void mdio_sync(long ioaddr, int bits);
static int mdio_read(struct net_device *dev, int phy_id, int location);
@@ -948,7 +948,7 @@
if (dev && dev->priv) {
if (netif_running(dev)) {
netif_device_detach(dev);
- vortex_down(dev);
+ vortex_down(dev, 1);
}
}
return 0;
@@ -2059,7 +2059,8 @@
printk(KERN_ERR "%s: PCI bus error, bus status %8.8x\n", dev->name, bus_status);
/* In this case, blow the card away */
- vortex_down(dev);
+ /* Must not enter D3 or we can't legally issue the reset! */
+ vortex_down(dev, 0);
issue_and_wait(dev, TotalReset | 0xff);
vortex_up(dev); /* AKPM: bug. vortex_up() assumes that the rx ring is full. It may not be. */
} else if (fifo_diag & 0x0400)
@@ -2656,7 +2657,7 @@
}
static void
-vortex_down(struct net_device *dev)
+vortex_down(struct net_device *dev, int final_down)
{
struct vortex_private *vp = netdev_priv(dev);
long ioaddr = dev->base_addr;
@@ -2685,7 +2686,7 @@
if (vp->full_bus_master_tx)
outl(0, ioaddr + DownListPtr);
- if (VORTEX_PCI(vp) && vp->enable_wol) {
+ if (final_down && VORTEX_PCI(vp) && vp->enable_wol) {
pci_save_state(VORTEX_PCI(vp), vp->power_state);
acpi_set_WOL(dev);
}
@@ -2699,7 +2700,7 @@
int i;
if (netif_device_present(dev))
- vortex_down(dev);
+ vortex_down(dev, 1);
if (vortex_debug > 1) {
printk(KERN_DEBUG"%s: vortex_close() status %4.4x, Tx status %2.2x.\n",
@@ -2869,7 +2870,7 @@
.get_drvinfo = vortex_get_drvinfo,
};
-static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+static int vortex_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
struct vortex_private *vp = netdev_priv(dev);
long ioaddr = dev->base_addr;
@@ -2904,6 +2905,30 @@
return retval;
}
+/*
+ * Must power the device up to do MDIO operations
+ */
+static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+ int err;
+ struct vortex_private *vp = netdev_priv(dev);
+ int state = 0;
+
+ if(VORTEX_PCI(vp))
+ state = VORTEX_PCI(vp)->current_state;
+
+ /* The kernel core really should have pci_get_power_state() */
+
+ if(state != 0)
+ pci_set_power_state(VORTEX_PCI(vp), 0);
+ err = vortex_do_ioctl(dev, rq, cmd);
+ if(state != 0)
+ pci_set_power_state(VORTEX_PCI(vp), state);
+
+ return err;
+}
+
+
/* Pre-Cyclone chips have no documented multicast filter, so the only
multicast setting is to receive all multicast frames. At least
the chip has a very clean way to set the mode, unlike many others. */
@@ -3059,14 +3084,14 @@
* here
*/
unregister_netdev(dev);
- /* Should really use issue_and_wait() here */
- outw(TotalReset|0x14, dev->base_addr + EL3_CMD);
if (VORTEX_PCI(vp) && vp->enable_wol) {
pci_set_power_state(VORTEX_PCI(vp), 0); /* Go active */
if (vp->pm_state_valid)
pci_restore_state(VORTEX_PCI(vp), vp->power_state);
}
+ /* Should really use issue_and_wait() here */
+ outw(TotalReset|0x14, dev->base_addr + EL3_CMD);
pci_free_consistent(pdev,
sizeof(struct boom_rx_desc) * RX_RING_SIZE
Developer's Certificate of Origin 1.0
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or
(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am
by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated
in the file; or
(c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.
Signed-off-by: Alan Cox <alan@redhat.com>
"Me" in this case being Red Hat
reply other threads:[~2004-06-16 21:05 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20040616210112.GA11858@devserv.devel.redhat.com \
--to=alan@redhat.com \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.