aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Vidrine <nectar@FreeBSD.org>2005-01-06 17:54:47 +0000
committerJacques Vidrine <nectar@FreeBSD.org>2005-01-06 17:54:47 +0000
commitb4bd4006ca31f475c5b79727e6d28f6ae6f4a363 (patch)
tree61853006df4eb76dcba71ab3eb02bed287ff2c7b
parenta750b6376a2b63602115e458bea53cc9b7bcb37b (diff)
Notes
-rw-r--r--UPDATING4
-rw-r--r--sys/conf/newvers.sh2
-rw-r--r--sys/pci/if_sk.c49
-rw-r--r--sys/pci/if_skreg.h1
4 files changed, 39 insertions, 17 deletions
diff --git a/UPDATING b/UPDATING
index 7c8427d1db1c..9f2f61c6b49b 100644
--- a/UPDATING
+++ b/UPDATING
@@ -8,6 +8,10 @@ Items affecting the ports and packages system can be found in
/usr/ports/UPDATING. Please read that file before running
portupgrade. Important recent entries: 20040724 (default X changes).
+20050106: p4 FreeBSD-EN-05:02.sk
+ Correct bugs in the sk(4) network driver that could result in
+ data corruption and system crashes on SMP systems.
+
20050103: p3 FreeBSD-EN-05:01.nfs
Correct a bug in nfsrv_create() where a call to nfsrv_access()
might be made while holding the NFS server mutex, which resulted
diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh
index 37d90ee10576..7d3f2d668bfa 100644
--- a/sys/conf/newvers.sh
+++ b/sys/conf/newvers.sh
@@ -32,7 +32,7 @@
TYPE="FreeBSD"
REVISION="5.3"
-BRANCH="RELEASE-p3"
+BRANCH="RELEASE-p4"
RELEASE="${REVISION}-${BRANCH}"
VERSION="${TYPE} ${RELEASE}"
diff --git a/sys/pci/if_sk.c b/sys/pci/if_sk.c
index 49ad9e2b36f4..da75d55c1c2d 100644
--- a/sys/pci/if_sk.c
+++ b/sys/pci/if_sk.c
@@ -505,7 +505,7 @@ sk_vpd_read(sc)
pos += sizeof(res);
sc->sk_vpd_readonly = malloc(res.vr_len, M_DEVBUF, M_NOWAIT);
- for (i = 0; i < res.vr_len + 1; i++)
+ for (i = 0; i < res.vr_len; i++)
sc->sk_vpd_readonly[i] = sk_vpd_readbyte(sc, i + pos);
return;
@@ -1073,9 +1073,11 @@ sk_jalloc(sc_if)
struct sk_if_softc *sc_if;
{
struct sk_jpool_entry *entry;
-
+
+ SK_IF_LOCK_ASSERT(sc_if);
+
entry = SLIST_FIRST(&sc_if->sk_jfree_listhead);
-
+
if (entry == NULL) {
#ifdef SK_VERBOSE
printf("sk%d: no free jumbo buffers\n", sc_if->sk_unit);
@@ -1102,10 +1104,11 @@ sk_jfree(buf, args)
/* Extract the softc struct pointer. */
sc_if = (struct sk_if_softc *)args;
-
if (sc_if == NULL)
panic("sk_jfree: didn't get softc pointer!");
+ SK_IF_LOCK(sc_if);
+
/* calculate the slot this buffer belongs to */
i = ((vm_offset_t)buf
- (vm_offset_t)sc_if->sk_cdata.sk_jumbo_buf) / SK_JLEN;
@@ -1120,6 +1123,7 @@ sk_jfree(buf, args)
SLIST_REMOVE_HEAD(&sc_if->sk_jinuse_listhead, jpool_entries);
SLIST_INSERT_HEAD(&sc_if->sk_jfree_listhead, entry, jpool_entries);
+ SK_IF_UNLOCK(sc_if);
return;
}
@@ -1501,6 +1505,7 @@ skc_attach(dev)
{
struct sk_softc *sc;
int unit, error = 0, rid, *port;
+ uint8_t skrs;
sc = device_get_softc(dev);
unit = device_get_unit(dev);
@@ -1561,9 +1566,10 @@ skc_attach(dev)
/* Read and save vital product data from EEPROM. */
sk_vpd_read(sc);
+ skrs = sk_win_read_1(sc, SK_EPROM0);
if (sc->sk_type == SK_GENESIS) {
/* Read and save RAM size and RAMbuffer offset */
- switch(sk_win_read_1(sc, SK_EPROM0)) {
+ switch(skrs) {
case SK_RAMSIZE_512K_64:
sc->sk_ramsize = 0x80000;
sc->sk_rboff = SK_RBOFF_0;
@@ -1586,8 +1592,11 @@ skc_attach(dev)
error = ENXIO;
goto fail;
}
- } else {
- sc->sk_ramsize = 0x20000;
+ } else { /* SK_YUKON */
+ if (skrs == 0x00)
+ sc->sk_ramsize = 0x20000;
+ else
+ sc->sk_ramsize = skrs * (1<<12);
sc->sk_rboff = SK_RBOFF_0;
}
@@ -1736,6 +1745,8 @@ sk_encap(sc_if, m_head, txidx)
struct mbuf *m;
u_int32_t frag, cur, cnt = 0;
+ SK_IF_LOCK_ASSERT(sc_if);
+
m = m_head;
cur = frag = *txidx;
@@ -1816,11 +1827,13 @@ sk_start(ifp)
}
/* Transmit */
- sc_if->sk_cdata.sk_tx_prod = idx;
- CSR_WRITE_4(sc, sc_if->sk_tx_bmu, SK_TXBMU_TX_START);
+ if (idx != sc_if->sk_cdata.sk_tx_prod) {
+ sc_if->sk_cdata.sk_tx_prod = idx;
+ CSR_WRITE_4(sc, sc_if->sk_tx_bmu, SK_TXBMU_TX_START);
- /* Set a timeout in case the chip goes out to lunch. */
- ifp->if_timer = 5;
+ /* Set a timeout in case the chip goes out to lunch. */
+ ifp->if_timer = 5;
+ }
SK_IF_UNLOCK(sc_if);
return;
@@ -1937,10 +1950,12 @@ static void
sk_txeof(sc_if)
struct sk_if_softc *sc_if;
{
- struct sk_tx_desc *cur_tx = NULL;
+ struct sk_softc *sc;
+ struct sk_tx_desc *cur_tx;
struct ifnet *ifp;
u_int32_t idx;
+ sc = sc_if->sk_softc;
ifp = &sc_if->arpcom.ac_if;
/*
@@ -1960,15 +1975,17 @@ sk_txeof(sc_if)
}
sc_if->sk_cdata.sk_tx_cnt--;
SK_INC(idx, SK_TX_RING_CNT);
- ifp->if_timer = 0;
}
- sc_if->sk_cdata.sk_tx_cons = idx;
+ if (sc_if->sk_cdata.sk_tx_cnt == 0) {
+ ifp->if_timer = 0;
+ } else /* nudge chip to keep tx ring moving */
+ CSR_WRITE_4(sc, sc_if->sk_tx_bmu, SK_TXBMU_TX_START);
- if (cur_tx != NULL)
+ if (sc_if->sk_cdata.sk_tx_cnt < SK_TX_RING_CNT - 2)
ifp->if_flags &= ~IFF_OACTIVE;
- return;
+ sc_if->sk_cdata.sk_tx_cons = idx;
}
static void
diff --git a/sys/pci/if_skreg.h b/sys/pci/if_skreg.h
index 2ef61c456945..be2af20a53d4 100644
--- a/sys/pci/if_skreg.h
+++ b/sys/pci/if_skreg.h
@@ -1441,6 +1441,7 @@ struct sk_softc {
#define SK_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sk_mtx, MA_OWNED)
#define SK_IF_LOCK(_sc) SK_LOCK((_sc)->sk_softc)
#define SK_IF_UNLOCK(_sc) SK_UNLOCK((_sc)->sk_softc)
+#define SK_IF_LOCK_ASSERT(_sc) SK_LOCK_ASSERT((_sc)->sk_softc)
/* Softc for each logical interface */
struct sk_if_softc {