summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorjkim <jkim@FreeBSD.org>2009-06-03 22:54:27 +0000
committerjkim <jkim@FreeBSD.org>2009-06-03 22:54:27 +0000
commit8b4d37b6a77bc5293cb64640e5e438e517676aa3 (patch)
treec84ae4a93183dfcb38f5e0f2bfa127f31847bbc6 /sys
parentfeac47ed6a1eb54eff18f1d19649bc92dbf7af87 (diff)
parent6b340c06d17352b1fd07ec2fe19a9c83af9e9e5b (diff)
downloadFreeBSD-src-8b4d37b6a77bc5293cb64640e5e438e517676aa3.zip
FreeBSD-src-8b4d37b6a77bc5293cb64640e5e438e517676aa3.tar.gz
Resync with head.
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/conf/GENERIC1
-rw-r--r--sys/amd64/conf/MAC28
-rw-r--r--sys/boot/uboot/lib/disk.c41
-rw-r--r--sys/dev/aic7xxx/aicasm/Makefile1
-rw-r--r--sys/dev/ata/ata-all.h17
-rw-r--r--sys/dev/ata/chipsets/ata-ahci.c55
-rw-r--r--sys/dev/ath/if_ath.c63
-rw-r--r--sys/dev/bwi/if_bwi.c26
-rw-r--r--sys/dev/if_ndis/if_ndis.c26
-rw-r--r--sys/dev/iir/iir.c3
-rw-r--r--sys/dev/iir/iir_ctrl.c4
-rw-r--r--sys/dev/ksyms/ksyms.c2
-rw-r--r--sys/dev/mii/e1000phy.c22
-rw-r--r--sys/dev/mii/e1000phyreg.h32
-rw-r--r--sys/dev/msk/if_msk.c240
-rw-r--r--sys/dev/msk/if_mskreg.h137
-rw-r--r--sys/dev/mxge/if_mxge.c29
-rw-r--r--sys/dev/mxge/if_mxge_var.h6
-rw-r--r--sys/dev/pci/pci.c1
-rw-r--r--sys/dev/puc/pucdata.c11
-rw-r--r--sys/dev/usb/input/ukbd.c4
-rw-r--r--sys/dev/usb/usb_compat_linux.h2
-rw-r--r--sys/dev/usb/usb_dev.c186
-rw-r--r--sys/dev/usb/usb_dev.h10
-rw-r--r--sys/dev/usb/usb_request.c18
-rw-r--r--sys/gnu/fs/ext2fs/ext2_fs.h88
-rw-r--r--sys/gnu/fs/ext2fs/ext2_fs_sb.h13
-rw-r--r--sys/gnu/fs/ext2fs/ext2_lookup.c5
-rw-r--r--sys/gnu/fs/ext2fs/ext2_vfsops.c486
-rw-r--r--sys/gnu/fs/ext2fs/ext2_vnops.c3
-rw-r--r--sys/gnu/fs/ext2fs/sparc64-bitops.h264
-rw-r--r--sys/i386/conf/GENERIC1
-rw-r--r--sys/i386/conf/MAC28
-rw-r--r--sys/ia64/conf/GENERIC1
-rw-r--r--sys/ia64/conf/MAC28
-rw-r--r--sys/kern/kern_descrip.c8
-rw-r--r--sys/kern/kern_lock.c11
-rw-r--r--sys/kern/kern_prot.c2
-rw-r--r--sys/kern/kern_rwlock.c12
-rw-r--r--sys/kern/kern_sx.c14
-rw-r--r--sys/kern/sys_socket.c8
-rw-r--r--sys/kern/uipc_mbuf.c2
-rw-r--r--sys/kern/uipc_shm.c21
-rw-r--r--sys/kern/uipc_socket.c2
-rw-r--r--sys/kern/uipc_syscalls.c48
-rw-r--r--sys/kern/uipc_usrreq.c2
-rw-r--r--sys/net/if.c4
-rw-r--r--sys/net80211/ieee80211.c37
-rw-r--r--sys/net80211/ieee80211_ddb.c5
-rw-r--r--sys/net80211/ieee80211_freebsd.c10
-rw-r--r--sys/net80211/ieee80211_hostap.c6
-rw-r--r--sys/net80211/ieee80211_input.c11
-rw-r--r--sys/net80211/ieee80211_ioctl.c23
-rw-r--r--sys/net80211/ieee80211_monitor.c3
-rw-r--r--sys/net80211/ieee80211_proto.c22
-rw-r--r--sys/net80211/ieee80211_radiotap.c75
-rw-r--r--sys/net80211/ieee80211_scan.c1
-rw-r--r--sys/net80211/ieee80211_var.h5
-rw-r--r--sys/netatalk/ddp_input.c6
-rw-r--r--sys/netinet/in_pcb.c2
-rw-r--r--sys/netinet/ip_divert.c2
-rw-r--r--sys/netinet/tcp_input.c2
-rw-r--r--sys/netinet/tcp_syncache.c2
-rw-r--r--sys/pc98/conf/GENERIC1
-rw-r--r--sys/pc98/conf/MAC28
-rw-r--r--sys/powerpc/conf/GENERIC1
-rw-r--r--sys/powerpc/conf/MAC28
-rw-r--r--sys/rpc/svc_vc.c2
-rw-r--r--sys/security/mac/mac_atalk.c3
-rw-r--r--sys/security/mac/mac_framework.c20
-rw-r--r--sys/security/mac/mac_inet.c46
-rw-r--r--sys/security/mac/mac_inet6.c15
-rw-r--r--sys/security/mac/mac_internal.h1
-rw-r--r--sys/security/mac/mac_net.c18
-rw-r--r--sys/security/mac/mac_socket.c47
-rw-r--r--sys/security/mac_biba/mac_biba.c49
-rw-r--r--sys/security/mac_lomac/mac_lomac.c46
-rw-r--r--sys/security/mac_mls/mac_mls.c47
-rw-r--r--sys/security/mac_stub/mac_stub.c79
-rw-r--r--sys/security/mac_test/mac_test.c48
-rw-r--r--sys/sparc64/conf/GENERIC1
-rw-r--r--sys/sparc64/conf/MAC28
-rw-r--r--sys/sun4v/conf/GENERIC1
-rw-r--r--sys/sun4v/conf/MAC28
-rw-r--r--sys/sun4v/include/pcpu.h4
-rw-r--r--sys/sys/pmc.h5
-rw-r--r--sys/sys/vnode.h2
-rw-r--r--sys/ufs/ffs/ffs_softdep.c4
-rw-r--r--sys/ufs/ufs/dirhash.h2
-rw-r--r--sys/ufs/ufs/ufs_dirhash.c133
-rw-r--r--sys/vm/vnode_pager.c26
91 files changed, 1588 insertions, 1353 deletions
diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC
index 569e0cd..6ff85e2 100644
--- a/sys/amd64/conf/GENERIC
+++ b/sys/amd64/conf/GENERIC
@@ -70,6 +70,7 @@ options KBD_INSTALL_CDEV # install a CDEV entry in /dev
options STOP_NMI # Stop CPUS using NMI instead of IPI
options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4)
options AUDIT # Security event auditing
+options MAC # TrustedBSD MAC Framework
#options KDTRACE_FRAME # Ensure frames are compiled in
#options KDTRACE_HOOKS # Kernel DTrace hooks
diff --git a/sys/amd64/conf/MAC b/sys/amd64/conf/MAC
deleted file mode 100644
index 306f36f..0000000
--- a/sys/amd64/conf/MAC
+++ /dev/null
@@ -1,28 +0,0 @@
-# MAC -- Generic kernel configuration file for FreeBSD/amd64 MAC
-#
-# The Mandatory Access Control, or MAC, framework allows administrators to
-# finely control system security by providing for a loadable security pol-
-# icy architecture.
-#
-# For more information see:
-#
-# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/mac.html
-#
-# $FreeBSD$
-
-include GENERIC
-ident MAC
-
-options MAC
-
-#options MAC_BIBA # BIBA data integrity policy
-#options MAC_BSDEXTENDED # File system firewall policy
-#options MAC_IFOFF # Network interface silencing policy
-#options MAC_LOMAC # Low-watermark data integrity policy
-#options MAC_MLS # Multi-level confidentiality policy
-#options MAC_NONE # NULL policy
-#options MAC_PARTITION # Process partition policy
-#options MAC_PORTACL # Network port access control policy
-#options MAC_SEEOTHERUIDS # UID visibility policy
-#options MAC_STUB # Stub policy
-#options MAC_TEST # Testing policy for the MAC framework
diff --git a/sys/boot/uboot/lib/disk.c b/sys/boot/uboot/lib/disk.c
index 1725d07..4cbdbea 100644
--- a/sys/boot/uboot/lib/disk.c
+++ b/sys/boot/uboot/lib/disk.c
@@ -34,6 +34,7 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <sys/endian.h>
#include <sys/queue.h>
#include <netinet/in.h>
#include <machine/stdarg.h>
@@ -122,6 +123,15 @@ struct devsw uboot_storage = {
stor_print
};
+static void
+uuid_letoh(uuid_t *uuid)
+{
+
+ uuid->time_low = le32toh(uuid->time_low);
+ uuid->time_mid = le16toh(uuid->time_mid);
+ uuid->time_hi_and_version = le16toh(uuid->time_hi_and_version);
+}
+
static int
stor_init(void)
{
@@ -251,7 +261,7 @@ stor_open_gpt(struct open_dev *od, struct uboot_devdesc *dev)
}
/* Check the slice table magic. */
- if (*((uint16_t *)(buf + DOSMAGICOFFSET)) != DOSMAGIC) {
+ if (le16toh(*((uint16_t *)(buf + DOSMAGICOFFSET))) != DOSMAGIC) {
err = ENXIO;
goto out;
}
@@ -286,9 +296,10 @@ stor_open_gpt(struct open_dev *od, struct uboot_devdesc *dev)
/* Check GPT header */
if (bcmp(hdr->hdr_sig, GPT_HDR_SIG, sizeof(hdr->hdr_sig)) != 0 ||
- hdr->hdr_lba_self != 1 || hdr->hdr_revision < 0x00010000 ||
- hdr->hdr_entsz < sizeof(*ent) ||
- od->od_bsize % hdr->hdr_entsz != 0) {
+ le64toh(hdr->hdr_lba_self) != 1 ||
+ le32toh(hdr->hdr_revision) < 0x00010000 ||
+ le32toh(hdr->hdr_entsz) < sizeof(*ent) ||
+ od->od_bsize % le32toh(hdr->hdr_entsz) != 0) {
debugf("Invalid GPT header!\n");
err = EINVAL;
goto out;
@@ -296,9 +307,9 @@ stor_open_gpt(struct open_dev *od, struct uboot_devdesc *dev)
/* Count number of valid partitions */
part = 0;
- eps = od->od_bsize / hdr->hdr_entsz;
- slba = hdr->hdr_lba_table;
- elba = slba + hdr->hdr_entries / eps;
+ eps = od->od_bsize / le32toh(hdr->hdr_entsz);
+ slba = le64toh(hdr->hdr_lba_table);
+ elba = slba + le32toh(hdr->hdr_entries) / eps;
for (lba = slba; lba < elba; lba++) {
err = stor_readdev(dev, lba, 1, buf);
@@ -312,8 +323,9 @@ stor_open_gpt(struct open_dev *od, struct uboot_devdesc *dev)
for (i = 0; i < eps; i++) {
if (uuid_is_nil(&ent[i].ent_type, NULL) ||
- ent[i].ent_lba_start == 0 ||
- ent[i].ent_lba_end < ent[i].ent_lba_start)
+ le64toh(ent[i].ent_lba_start) == 0 ||
+ le64toh(ent[i].ent_lba_end) <
+ le64toh(ent[i].ent_lba_start))
continue;
part += 1;
@@ -343,8 +355,9 @@ stor_open_gpt(struct open_dev *od, struct uboot_devdesc *dev)
for (i = 0; i < eps; i++) {
if (uuid_is_nil(&ent[i].ent_type, NULL) ||
- ent[i].ent_lba_start == 0 ||
- ent[i].ent_lba_end < ent[i].ent_lba_start)
+ le64toh(ent[i].ent_lba_start) == 0 ||
+ le64toh(ent[i].ent_lba_end) <
+ le64toh(ent[i].ent_lba_start))
continue;
od->od_partitions[part].gp_index = (lba - slba)
@@ -352,9 +365,11 @@ stor_open_gpt(struct open_dev *od, struct uboot_devdesc *dev)
od->od_partitions[part].gp_type =
ent[i].ent_type;
od->od_partitions[part].gp_start =
- ent[i].ent_lba_start;
+ le64toh(ent[i].ent_lba_start);
od->od_partitions[part].gp_end =
- ent[i].ent_lba_end;
+ le64toh(ent[i].ent_lba_end);
+
+ uuid_letoh(&od->od_partitions[part].gp_type);
part += 1;
}
}
diff --git a/sys/dev/aic7xxx/aicasm/Makefile b/sys/dev/aic7xxx/aicasm/Makefile
index 78701b0..222c96a 100644
--- a/sys/dev/aic7xxx/aicasm/Makefile
+++ b/sys/dev/aic7xxx/aicasm/Makefile
@@ -15,6 +15,7 @@ SRCS= ${GENHDRS} ${CSRCS} ${YSRCS} ${LSRCS}
CLEANFILES+= ${GENHDRS} ${YSRCS:R:C/(.*)/\1.output/g}
DPADD= ${LIBL}
LDADD= -ll
+WARNS?= 6
# Correct path for kernel builds
# Don't rely on the kernel's .depend file
diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h
index e22758f..b8ee9a0 100644
--- a/sys/dev/ata/ata-all.h
+++ b/sys/dev/ata/ata-all.h
@@ -149,11 +149,26 @@
/* SATA AHCI v1.0 register defines */
#define ATA_AHCI_CAP 0x00
#define ATA_AHCI_CAP_NPMASK 0x0000001f
+#define ATA_AHCI_CAP_SXS 0x00000020
+#define ATA_AHCI_CAP_EMS 0x00000040
+#define ATA_AHCI_CAP_CCCS 0x00000080
+#define ATA_AHCI_CAP_NCS 0x00001F00
+#define ATA_AHCI_CAP_NCS_SHIFT 8
#define ATA_AHCI_CAP_PSC 0x00002000
#define ATA_AHCI_CAP_SSC 0x00004000
+#define ATA_AHCI_CAP_PMD 0x00008000
+#define ATA_AHCI_CAP_FBSS 0x00010000
#define ATA_AHCI_CAP_SPM 0x00020000
-#define ATA_AHCI_CAP_CLO 0x01000000
+#define ATA_AHCI_CAP_SAM 0x00080000
+#define ATA_AHCI_CAP_ISS 0x00F00000
+#define ATA_AHCI_CAP_ISS_SHIFT 20
+#define ATA_AHCI_CAP_SCLO 0x01000000
+#define ATA_AHCI_CAP_SAL 0x02000000
#define ATA_AHCI_CAP_SALP 0x04000000
+#define ATA_AHCI_CAP_SSS 0x08000000
+#define ATA_AHCI_CAP_SMPS 0x10000000
+#define ATA_AHCI_CAP_SSNTF 0x20000000
+#define ATA_AHCI_CAP_SNCQ 0x40000000
#define ATA_AHCI_CAP_64BIT 0x80000000
#define ATA_AHCI_GHC 0x04
diff --git a/sys/dev/ata/chipsets/ata-ahci.c b/sys/dev/ata/chipsets/ata-ahci.c
index 7037f4d..eb490ab 100644
--- a/sys/dev/ata/chipsets/ata-ahci.c
+++ b/sys/dev/ata/chipsets/ata-ahci.c
@@ -101,8 +101,8 @@ int
ata_ahci_chipinit(device_t dev)
{
struct ata_pci_controller *ctlr = device_get_softc(dev);
- int error;
- u_int32_t version;
+ int error, speed;
+ u_int32_t caps, version;
/* if we have a memory BAR(5) we are likely on an AHCI part */
ctlr->r_type2 = SYS_RES_MEMORY;
@@ -142,16 +142,45 @@ ata_ahci_chipinit(device_t dev)
ctlr->suspend = ata_ahci_suspend;
ctlr->resume = ata_ahci_ctlr_reset;
- /* announce we support the HW */
- version = ATA_INL(ctlr->r_res2, ATA_AHCI_VS);
- device_printf(dev,
- "AHCI Version %x%x.%x%x controller with %d ports PM %s\n",
- (version >> 24) & 0xff, (version >> 16) & 0xff,
- (version >> 8) & 0xff, version & 0xff,
- (ATA_INL(ctlr->r_res2, ATA_AHCI_CAP) & ATA_AHCI_CAP_NPMASK) + 1,
- (ATA_INL(ctlr->r_res2, ATA_AHCI_CAP) & ATA_AHCI_CAP_SPM) ?
- "supported" : "not supported");
- return 0;
+ /* announce we support the HW */
+ version = ATA_INL(ctlr->r_res2, ATA_AHCI_VS);
+ caps = ATA_INL(ctlr->r_res2, ATA_AHCI_CAP);
+ speed = (caps & ATA_AHCI_CAP_ISS) >> ATA_AHCI_CAP_ISS_SHIFT;
+ device_printf(dev,
+ "AHCI v%x.%02x controller with %d %sGbps ports, PM %s\n",
+ ((version >> 20) & 0xf0) + ((version >> 16) & 0x0f),
+ ((version >> 4) & 0xf0) + (version & 0x0f),
+ (caps & ATA_AHCI_CAP_NPMASK) + 1,
+ ((speed == 1) ? "1.5":((speed == 2) ? "3":
+ ((speed == 3) ? "6":"?"))),
+ (caps & ATA_AHCI_CAP_SPM) ?
+ "supported" : "not supported");
+ if (bootverbose) {
+ device_printf(dev, "Caps:%s%s%s%s%s%s%s%s %sGbps",
+ (caps & ATA_AHCI_CAP_64BIT) ? " 64bit":"",
+ (caps & ATA_AHCI_CAP_SNCQ) ? " NCQ":"",
+ (caps & ATA_AHCI_CAP_SSNTF) ? " SNTF":"",
+ (caps & ATA_AHCI_CAP_SMPS) ? " MPS":"",
+ (caps & ATA_AHCI_CAP_SSS) ? " SS":"",
+ (caps & ATA_AHCI_CAP_SALP) ? " ALP":"",
+ (caps & ATA_AHCI_CAP_SAL) ? " AL":"",
+ (caps & ATA_AHCI_CAP_SCLO) ? " CLO":"",
+ ((speed == 1) ? "1.5":((speed == 2) ? "3":
+ ((speed == 3) ? "6":"?"))));
+ printf("%s%s%s%s%s%s %dcmd%s%s%s %dports\n",
+ (caps & ATA_AHCI_CAP_SAM) ? " AM":"",
+ (caps & ATA_AHCI_CAP_SPM) ? " PM":"",
+ (caps & ATA_AHCI_CAP_FBSS) ? " FBS":"",
+ (caps & ATA_AHCI_CAP_PMD) ? " PMD":"",
+ (caps & ATA_AHCI_CAP_SSC) ? " SSC":"",
+ (caps & ATA_AHCI_CAP_PSC) ? " PSC":"",
+ ((caps & ATA_AHCI_CAP_NCS) >> ATA_AHCI_CAP_NCS_SHIFT) + 1,
+ (caps & ATA_AHCI_CAP_CCCS) ? " CCC":"",
+ (caps & ATA_AHCI_CAP_EMS) ? " EM":"",
+ (caps & ATA_AHCI_CAP_SXS) ? " eSATA":"",
+ (caps & ATA_AHCI_CAP_NPMASK) + 1);
+ }
+ return 0;
}
int
@@ -625,7 +654,7 @@ ata_ahci_clo(device_t dev)
int timeout;
/* issue Command List Override if supported */
- if (ATA_INL(ctlr->r_res2, ATA_AHCI_CAP) & ATA_AHCI_CAP_CLO) {
+ if (ATA_INL(ctlr->r_res2, ATA_AHCI_CAP) & ATA_AHCI_CAP_SCLO) {
cmd = ATA_INL(ctlr->r_res2, ATA_AHCI_P_CMD + offset);
cmd |= ATA_AHCI_P_CMD_CLO;
ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CMD + offset, cmd);
diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c
index 05930e3..2413d19 100644
--- a/sys/dev/ath/if_ath.c
+++ b/sys/dev/ath/if_ath.c
@@ -1153,8 +1153,14 @@ ath_vap_delete(struct ieee80211vap *vap)
if (ath_startrecv(sc) != 0)
if_printf(ifp, "%s: unable to restart recv logic\n",
__func__);
- if (sc->sc_beacons)
- ath_beacon_config(sc, NULL);
+ if (sc->sc_beacons) { /* restart beacons */
+#ifdef IEEE80211_SUPPORT_TDMA
+ if (sc->sc_tdma)
+ ath_tdma_config(sc, NULL);
+ else
+#endif
+ ath_beacon_config(sc, NULL);
+ }
ath_hal_intrset(ah, sc->sc_imask);
}
}
@@ -1652,13 +1658,13 @@ ath_reset(struct ifnet *ifp)
* might change as a result.
*/
ath_chan_change(sc, ic->ic_curchan);
- if (sc->sc_beacons) {
+ if (sc->sc_beacons) { /* restart beacons */
#ifdef IEEE80211_SUPPORT_TDMA
if (sc->sc_tdma)
ath_tdma_config(sc, NULL);
else
#endif
- ath_beacon_config(sc, NULL); /* restart beacons */
+ ath_beacon_config(sc, NULL);
}
ath_hal_intrset(ah, sc->sc_imask);
@@ -1704,7 +1710,6 @@ _ath_getbuf_locked(struct ath_softc *sc)
DPRINTF(sc, ATH_DEBUG_XMIT, "%s: %s\n", __func__,
STAILQ_FIRST(&sc->sc_txbuf) == NULL ?
"out of xmit buffers" : "xmit buffer busy");
- sc->sc_stats.ast_tx_nobuf++;
}
return bf;
}
@@ -1814,6 +1819,7 @@ ath_start(struct ifnet *ifp)
DPRINTF(sc, ATH_DEBUG_XMIT,
"%s: out of txfrag buffers\n", __func__);
sc->sc_stats.ast_tx_nofrag++;
+ ifp->if_oerrors++;
ath_freetx(m);
goto bad;
}
@@ -2796,7 +2802,7 @@ ath_beacon_proc(void *arg, int pending)
slot = ((tsftu % ic->ic_lintval) * ATH_BCBUF) / ic->ic_lintval;
vap = sc->sc_bslot[(slot+1) % ATH_BCBUF];
bfaddr = 0;
- if (vap != NULL && vap->iv_state == IEEE80211_S_RUN) {
+ if (vap != NULL && vap->iv_state >= IEEE80211_S_RUN) {
bf = ath_beacon_generate(sc, vap);
if (bf != NULL)
bfaddr = bf->bf_daddr;
@@ -2806,7 +2812,7 @@ ath_beacon_proc(void *arg, int pending)
for (slot = 0; slot < ATH_BCBUF; slot++) {
vap = sc->sc_bslot[slot];
- if (vap != NULL && vap->iv_state == IEEE80211_S_RUN) {
+ if (vap != NULL && vap->iv_state >= IEEE80211_S_RUN) {
bf = ath_beacon_generate(sc, vap);
if (bf != NULL) {
*bflink = bf->bf_daddr;
@@ -2872,7 +2878,7 @@ ath_beacon_generate(struct ath_softc *sc, struct ieee80211vap *vap)
struct mbuf *m;
int nmcastq, error;
- KASSERT(vap->iv_state == IEEE80211_S_RUN,
+ KASSERT(vap->iv_state >= IEEE80211_S_RUN,
("not running, state %d", vap->iv_state));
KASSERT(avp->av_bcbuf != NULL, ("no beacon buffer"));
@@ -4126,7 +4132,7 @@ ath_txq_update(struct ath_softc *sc, int ac)
/*
* AIFS is zero so there's no pre-transmit wait. The
* burst time defines the slot duration and is configured
- * via sysctl. The QCU is setup to not do post-xmit
+ * through net80211. The QCU is setup to not do post-xmit
* back off, lockout all lower-priority QCU's, and fire
* off the DMA beacon alert timer which is setup based
* on the slot configuration.
@@ -5500,7 +5506,7 @@ ath_isanyrunningvaps(struct ieee80211vap *this)
IEEE80211_LOCK_ASSERT(ic);
TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
- if (vap != this && vap->iv_state == IEEE80211_S_RUN)
+ if (vap != this && vap->iv_state >= IEEE80211_S_RUN)
return 1;
}
return 0;
@@ -6825,55 +6831,60 @@ ath_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
struct ifnet *ifp = ic->ic_ifp;
struct ath_softc *sc = ifp->if_softc;
struct ath_buf *bf;
+ int error;
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->sc_invalid) {
DPRINTF(sc, ATH_DEBUG_XMIT, "%s: discard frame, %s", __func__,
(ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ?
"!running" : "invalid");
- sc->sc_stats.ast_tx_raw_fail++;
- ieee80211_free_node(ni);
m_freem(m);
- return ENETDOWN;
+ error = ENETDOWN;
+ goto bad;
}
/*
* Grab a TX buffer and associated resources.
*/
bf = ath_getbuf(sc);
if (bf == NULL) {
- /* NB: ath_getbuf handles stat+msg */
- ieee80211_free_node(ni);
+ sc->sc_stats.ast_tx_nobuf++;
m_freem(m);
- return ENOBUFS;
+ error = ENOBUFS;
+ goto bad;
}
- ifp->if_opackets++;
- sc->sc_stats.ast_tx_raw++;
-
if (params == NULL) {
/*
* Legacy path; interpret frame contents to decide
* precisely how to send the frame.
*/
- if (ath_tx_start(sc, ni, bf, m))
- goto bad;
+ if (ath_tx_start(sc, ni, bf, m)) {
+ error = EIO; /* XXX */
+ goto bad2;
+ }
} else {
/*
* Caller supplied explicit parameters to use in
* sending the frame.
*/
- if (ath_tx_raw_start(sc, ni, bf, m, params))
- goto bad;
+ if (ath_tx_raw_start(sc, ni, bf, m, params)) {
+ error = EIO; /* XXX */
+ goto bad2;
+ }
}
sc->sc_wd_timer = 5;
+ ifp->if_opackets++;
+ sc->sc_stats.ast_tx_raw++;
return 0;
-bad:
- ifp->if_oerrors++;
+bad2:
ATH_TXBUF_LOCK(sc);
STAILQ_INSERT_HEAD(&sc->sc_txbuf, bf, bf_list);
ATH_TXBUF_UNLOCK(sc);
+bad:
+ ifp->if_oerrors++;
+ sc->sc_stats.ast_tx_raw_fail++;
ieee80211_free_node(ni);
- return EIO; /* XXX */
+ return error;
}
/*
diff --git a/sys/dev/bwi/if_bwi.c b/sys/dev/bwi/if_bwi.c
index dba7a7a..327b736 100644
--- a/sys/dev/bwi/if_bwi.c
+++ b/sys/dev/bwi/if_bwi.c
@@ -1771,10 +1771,12 @@ static int
bwi_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct bwi_vap *bvp = BWI_VAP(vap);
- struct ifnet *ifp = vap->iv_ic->ic_ifp;
+ struct ieee80211com *ic= vap->iv_ic;
+ struct ifnet *ifp = ic->ic_ifp;
+ enum ieee80211_state ostate = vap->iv_state;
struct bwi_softc *sc = ifp->if_softc;
struct bwi_mac *mac;
- struct ieee80211_node *ni;
+ struct ieee80211_node *ni = vap->iv_bss;
int error;
BWI_LOCK(sc);
@@ -1790,11 +1792,25 @@ bwi_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
if (error != 0)
goto back;
+ /*
+ * Clear the BSSID when we stop a STA
+ */
+ if (vap->iv_opmode == IEEE80211_M_STA) {
+ if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) {
+ /*
+ * Clear out the BSSID. If we reassociate to
+ * the same AP, this will reinialize things
+ * correctly...
+ */
+ if (ic->ic_opmode == IEEE80211_M_STA &&
+ !(sc->sc_flags & BWI_F_STOP))
+ bwi_set_bssid(sc, bwi_zero_addr);
+ }
+ }
+
if (vap->iv_opmode == IEEE80211_M_MONITOR) {
/* Nothing to do */
} else if (nstate == IEEE80211_S_RUN) {
- ni = vap->iv_bss;
-
bwi_set_bssid(sc, vap->iv_bss->ni_bssid);
KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC,
@@ -1814,8 +1830,6 @@ bwi_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
}
callout_reset(&sc->sc_calib_ch, hz, bwi_calibrate, sc);
- } else {
- bwi_set_bssid(sc, bwi_zero_addr);
}
back:
BWI_UNLOCK(sc);
diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c
index 71a6b23..d191d38 100644
--- a/sys/dev/if_ndis/if_ndis.c
+++ b/sys/dev/if_ndis/if_ndis.c
@@ -2727,31 +2727,7 @@ ndis_getstate_80211(sc)
if (rval)
device_printf (sc->ndis_dev, "get link speed failed: %d\n",
rval);
-
- if (isset(ic->ic_modecaps, IEEE80211_MODE_11B)) {
- ni->ni_rates = ic->ic_sup_rates[IEEE80211_MODE_11B];
- for (i = 0; i < ni->ni_rates.rs_nrates; i++) {
- if ((ni->ni_rates.rs_rates[i] &
- IEEE80211_RATE_VAL) == arg / 5000)
- break;
- }
- }
-
- if (i == ni->ni_rates.rs_nrates &&
- isset(ic->ic_modecaps, IEEE80211_MODE_11G)) {
- ni->ni_rates = ic->ic_sup_rates[IEEE80211_MODE_11G];
- for (i = 0; i < ni->ni_rates.rs_nrates; i++) {
- if ((ni->ni_rates.rs_rates[i] &
- IEEE80211_RATE_VAL) == arg / 5000)
- break;
- }
- }
-
- if (i == ni->ni_rates.rs_nrates)
- device_printf(sc->ndis_dev, "no matching rate for: %d\n",
- arg / 5000);
- else
- ni->ni_txrate = i;
+ ni->ni_txrate = arg / 5000;
if (ic->ic_caps & IEEE80211_C_PMGT) {
len = sizeof(arg);
diff --git a/sys/dev/iir/iir.c b/sys/dev/iir/iir.c
index cbcb449..f5f6d7e 100644
--- a/sys/dev/iir/iir.c
+++ b/sys/dev/iir/iir.c
@@ -67,9 +67,6 @@ __FBSDID("$FreeBSD$");
#include <cam/scsi/scsi_all.h>
#include <cam/scsi/scsi_message.h>
-#include <vm/vm.h>
-#include <vm/pmap.h>
-
#include <dev/iir/iir.h>
MALLOC_DEFINE(M_GDTBUF, "iirbuf", "iir driver buffer");
diff --git a/sys/dev/iir/iir_ctrl.c b/sys/dev/iir/iir_ctrl.c
index 6546f07..51ef043 100644
--- a/sys/dev/iir/iir_ctrl.c
+++ b/sys/dev/iir/iir_ctrl.c
@@ -52,10 +52,6 @@ __FBSDID("$FreeBSD$");
#include <sys/stat.h>
#include <sys/disklabel.h>
#include <machine/bus.h>
-#include <vm/vm.h>
-#include <vm/vm_kern.h>
-#include <vm/vm_extern.h>
-#include <vm/pmap.h>
#include <dev/iir/iir.h>
diff --git a/sys/dev/ksyms/ksyms.c b/sys/dev/ksyms/ksyms.c
index f725f06..cb0f967 100644
--- a/sys/dev/ksyms/ksyms.c
+++ b/sys/dev/ksyms/ksyms.c
@@ -552,7 +552,7 @@ ksyms_read(struct cdev *dev, struct uio *uio, int flags __unused)
/* ARGSUSED */
static int
ksyms_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int32_t flag __unused,
- d_thread_t *td __unused)
+ struct thread *td __unused)
{
int error = 0;
struct ksyms_softc *sc;
diff --git a/sys/dev/mii/e1000phy.c b/sys/dev/mii/e1000phy.c
index 9f9b986..f0d159b 100644
--- a/sys/dev/mii/e1000phy.c
+++ b/sys/dev/mii/e1000phy.c
@@ -238,21 +238,37 @@ e1000phy_reset(struct mii_softc *sc)
}
PHY_WRITE(sc, E1000_SCR, reg);
- if (esc->mii_model == MII_MODEL_MARVELL_E1116) {
+ if (esc->mii_model == MII_MODEL_MARVELL_E1116 ||
+ esc->mii_model == MII_MODEL_MARVELL_E1149) {
+ page = PHY_READ(sc, E1000_EADR);
+ /* Select page 2, MAC specific control register. */
PHY_WRITE(sc, E1000_EADR, 2);
reg = PHY_READ(sc, E1000_SCR);
reg |= E1000_SCR_RGMII_POWER_UP;
PHY_WRITE(sc, E1000_SCR, reg);
- PHY_WRITE(sc, E1000_EADR, 0);
+ PHY_WRITE(sc, E1000_EADR, page);
}
}
switch (MII_MODEL(esc->mii_model)) {
case MII_MODEL_MARVELL_E3082:
case MII_MODEL_MARVELL_E1112:
- case MII_MODEL_MARVELL_E1116:
case MII_MODEL_MARVELL_E1118:
+ break;
+ case MII_MODEL_MARVELL_E1116:
case MII_MODEL_MARVELL_E1149:
+ page = PHY_READ(sc, E1000_EADR);
+ /* Select page 3, LED control register. */
+ PHY_WRITE(sc, E1000_EADR, 3);
+ PHY_WRITE(sc, E1000_SCR,
+ E1000_SCR_LED_LOS(1) | /* Link/Act */
+ E1000_SCR_LED_INIT(8) | /* 10Mbps */
+ E1000_SCR_LED_STAT1(7) | /* 100Mbps */
+ E1000_SCR_LED_STAT0(7)); /* 1000Mbps */
+ /* Set blink rate. */
+ PHY_WRITE(sc, E1000_IER, E1000_PULSE_DUR(E1000_PULSE_170MS) |
+ E1000_BLINK_RATE(E1000_BLINK_84MS));
+ PHY_WRITE(sc, E1000_EADR, page);
break;
case MII_MODEL_MARVELL_E3016:
/* LED2 -> ACT, LED1 -> LINK, LED0 -> SPEED. */
diff --git a/sys/dev/mii/e1000phyreg.h b/sys/dev/mii/e1000phyreg.h
index 0b72224..41b9c09 100644
--- a/sys/dev/mii/e1000phyreg.h
+++ b/sys/dev/mii/e1000phyreg.h
@@ -256,9 +256,19 @@
/* 88E1116 page 0 */
#define E1000_SCR_POWER_DOWN 0x0004
-/* 88E1116 page 2 */
+/* 88E1116, 88E1149 page 2 */
#define E1000_SCR_RGMII_POWER_UP 0x0008
+/* 88E1116, 88E1149 page 3 */
+#define E1000_SCR_LED_STAT0_MASK 0x000F
+#define E1000_SCR_LED_STAT1_MASK 0x00F0
+#define E1000_SCR_LED_INIT_MASK 0x0F00
+#define E1000_SCR_LED_LOS_MASK 0xF000
+#define E1000_SCR_LED_STAT0(x) ((x) & E1000_SCR_LED_STAT0_MASK)
+#define E1000_SCR_LED_STAT1(x) ((x) & E1000_SCR_LED_STAT1_MASK)
+#define E1000_SCR_LED_INIT(x) ((x) & E1000_SCR_LED_INIT_MASK)
+#define E1000_SCR_LED_LOS(x) ((x) & E1000_SCR_LED_LOS_MASK)
+
#define E1000_SSR 0x11 /* special status register */
#define E1000_SSR_JABBER 0x0001
#define E1000_SSR_REV_POLARITY 0x0002
@@ -286,6 +296,26 @@
#define E1000_IER_SPEED_CHANGED 0x4000
#define E1000_IER_AUTO_NEG_ERR 0x8000
+/* 88E1116, 88E1149 page 3, LED timer control. */
+#define E1000_PULSE_MASK 0x7000
+#define E1000_PULSE_NO_STR 0 /* no pulse stretching */
+#define E1000_PULSE_21MS 1 /* 21 ms to 42 ms */
+#define E1000_PULSE_42MS 2 /* 42 ms to 84 ms */
+#define E1000_PULSE_84MS 3 /* 84 ms to 170 ms */
+#define E1000_PULSE_170MS 4 /* 170 ms to 340 ms */
+#define E1000_PULSE_340MS 5 /* 340 ms to 670 ms */
+#define E1000_PULSE_670MS 6 /* 670 ms to 1300 ms */
+#define E1000_PULSE_1300MS 7 /* 1300 ms to 2700 ms */
+#define E1000_PULSE_DUR(x) ((x) & E1000_PULSE_MASK)
+
+#define E1000_BLINK_MASK 0x0700
+#define E1000_BLINK_42MS 0 /* 42 ms */
+#define E1000_BLINK_84MS 1 /* 84 ms */
+#define E1000_BLINK_170MS 2 /* 170 ms */
+#define E1000_BLINK_340MS 3 /* 340 ms */
+#define E1000_BLINK_670MS 4 /* 670 ms */
+#define E1000_BLINK_RATE(x) ((x) & E1000_BLINK_MASK)
+
#define E1000_ISR 0x13 /* interrupt status reg */
#define E1000_ISR_JABBER 0x0001
#define E1000_ISR_POLARITY_CHANGE 0x0002
diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c
index 93575cf..73d5232 100644
--- a/sys/dev/msk/if_msk.c
+++ b/sys/dev/msk/if_msk.c
@@ -203,8 +203,6 @@ static struct msk_product {
"Marvell Yukon 88E8040T Fast Ethernet" },
{ VENDORID_MARVELL, DEVICEID_MRVL_8048,
"Marvell Yukon 88E8048 Fast Ethernet" },
- { VENDORID_MARVELL, DEVICEID_MRVL_8070,
- "Marvell Yukon 88E8070 Fast Ethernet" },
{ VENDORID_MARVELL, DEVICEID_MRVL_4361,
"Marvell Yukon 88E8050 Gigabit Ethernet" },
{ VENDORID_MARVELL, DEVICEID_MRVL_4360,
@@ -215,8 +213,14 @@ static struct msk_product {
"Marvell Yukon 88E8055 Gigabit Ethernet" },
{ VENDORID_MARVELL, DEVICEID_MRVL_4364,
"Marvell Yukon 88E8056 Gigabit Ethernet" },
+ { VENDORID_MARVELL, DEVICEID_MRVL_4365,
+ "Marvell Yukon 88E8070 Gigabit Ethernet" },
{ VENDORID_MARVELL, DEVICEID_MRVL_436A,
"Marvell Yukon 88E8058 Gigabit Ethernet" },
+ { VENDORID_MARVELL, DEVICEID_MRVL_436B,
+ "Marvell Yukon 88E8071 Gigabit Ethernet" },
+ { VENDORID_MARVELL, DEVICEID_MRVL_436C,
+ "Marvell Yukon 88E8072 Gigabit Ethernet" },
{ VENDORID_DLINK, DEVICEID_DLINK_DGE550SX,
"D-Link 550SX Gigabit Ethernet" },
{ VENDORID_DLINK, DEVICEID_DLINK_DGE560T,
@@ -226,7 +230,7 @@ static struct msk_product {
static const char *model_name[] = {
"Yukon XL",
"Yukon EC Ultra",
- "Yukon Unknown",
+ "Yukon EX",
"Yukon EC",
"Yukon FE",
"Yukon FE+"
@@ -258,8 +262,8 @@ static void msk_intr_hwerr(struct msk_softc *);
#ifndef __NO_STRICT_ALIGNMENT
static __inline void msk_fixup_rx(struct mbuf *);
#endif
-static void msk_rxeof(struct msk_if_softc *, uint32_t, int);
-static void msk_jumbo_rxeof(struct msk_if_softc *, uint32_t, int);
+static void msk_rxeof(struct msk_if_softc *, uint32_t, uint32_t, int);
+static void msk_jumbo_rxeof(struct msk_if_softc *, uint32_t, uint32_t, int);
static void msk_txeof(struct msk_if_softc *, int);
static int msk_encap(struct msk_if_softc *, struct mbuf **);
static void msk_tx_task(void *, int);
@@ -267,6 +271,7 @@ static void msk_start(struct ifnet *);
static int msk_ioctl(struct ifnet *, u_long, caddr_t);
static void msk_set_prefetch(struct msk_softc *, int, bus_addr_t, uint32_t);
static void msk_set_rambuffer(struct msk_if_softc *);
+static void msk_set_tx_stfwd(struct msk_if_softc *);
static void msk_init(void *);
static void msk_init_locked(struct msk_if_softc *);
static void msk_stop(struct msk_if_softc *);
@@ -991,12 +996,17 @@ msk_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
else
ifp->if_hwassist &= ~MSK_CSUM_FEATURES;
}
+ if ((mask & IFCAP_RXCSUM) != 0 &&
+ (IFCAP_RXCSUM & ifp->if_capabilities) != 0)
+ ifp->if_capenable ^= IFCAP_RXCSUM;
if ((mask & IFCAP_VLAN_HWTAGGING) != 0 &&
(IFCAP_VLAN_HWTAGGING & ifp->if_capabilities) != 0) {
ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
msk_setvlan(sc_if, ifp);
}
-
+ if ((mask & IFCAP_VLAN_HWCSUM) != 0 &&
+ (IFCAP_VLAN_HWCSUM & ifp->if_capabilities) != 0)
+ ifp->if_capenable ^= IFCAP_VLAN_HWCSUM;
if ((mask & IFCAP_TSO4) != 0 &&
(IFCAP_TSO4 & ifp->if_capabilities) != 0) {
ifp->if_capenable ^= IFCAP_TSO4;
@@ -1116,16 +1126,19 @@ msk_phy_power(struct msk_softc *sc, int mode)
val = pci_read_config(sc->msk_dev, PCI_OUR_REG_1, 4);
val &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD);
- switch (sc->msk_hw_id) {
- case CHIP_ID_YUKON_XL:
+ if (sc->msk_hw_id == CHIP_ID_YUKON_XL) {
if (sc->msk_hw_rev > CHIP_REV_YU_XL_A1) {
/* Deassert Low Power for 1st PHY. */
val |= PCI_Y2_PHY1_COMA;
if (sc->msk_num_port > 1)
val |= PCI_Y2_PHY2_COMA;
}
- break;
+ }
+ /* Release PHY from PowerDown/COMA mode. */
+ pci_write_config(sc->msk_dev, PCI_OUR_REG_1, val, 4);
+ switch (sc->msk_hw_id) {
case CHIP_ID_YUKON_EC_U:
+ case CHIP_ID_YUKON_EX:
case CHIP_ID_YUKON_FE_P:
CSR_WRITE_2(sc, B0_CTST, Y2_HW_WOL_OFF);
@@ -1136,14 +1149,22 @@ msk_phy_power(struct msk_softc *sc, int mode)
PCI_ASPM_INT_FIFO_EMPTY|PCI_ASPM_CLKRUN_REQUEST);
/* Set all bits to 0 except bits 15..12. */
pci_write_config(sc->msk_dev, PCI_OUR_REG_4, our, 4);
- /* Set to default value. */
- pci_write_config(sc->msk_dev, PCI_OUR_REG_5, 0, 4);
+ our = pci_read_config(sc->msk_dev, PCI_OUR_REG_5, 4);
+ our &= PCI_CTL_TIM_VMAIN_AV_MSK;
+ pci_write_config(sc->msk_dev, PCI_OUR_REG_5, our, 4);
+ pci_write_config(sc->msk_dev, PCI_CFG_REG_1, 0, 4);
+ /*
+ * Disable status race, workaround for
+ * Yukon EC Ultra & Yukon EX.
+ */
+ val = CSR_READ_4(sc, B2_GP_IO);
+ val |= GLB_GPIO_STAT_RACE_DIS;
+ CSR_WRITE_4(sc, B2_GP_IO, val);
+ CSR_READ_4(sc, B2_GP_IO);
break;
default:
break;
}
- /* Release PHY from PowerDown/COMA mode. */
- pci_write_config(sc->msk_dev, PCI_OUR_REG_1, val, 4);
for (i = 0; i < sc->msk_num_port; i++) {
CSR_WRITE_2(sc, MR_ADDR(i, GMAC_LINK_CTRL),
GMLC_RST_SET);
@@ -1194,10 +1215,18 @@ mskc_reset(struct msk_softc *sc)
CSR_WRITE_2(sc, B0_CTST, CS_RST_CLR);
/* Disable ASF. */
- if (sc->msk_hw_id < CHIP_ID_YUKON_XL) {
- CSR_WRITE_4(sc, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET);
- CSR_WRITE_2(sc, B0_CTST, Y2_ASF_DISABLE);
- }
+ if (sc->msk_hw_id == CHIP_ID_YUKON_EX) {
+ status = CSR_READ_2(sc, B28_Y2_ASF_HCU_CCSR);
+ /* Clear AHB bridge & microcontroller reset. */
+ status &= ~(Y2_ASF_HCU_CCSR_AHB_RST |
+ Y2_ASF_HCU_CCSR_CPU_RST_MODE);
+ /* Clear ASF microcontroller state. */
+ status &= ~ Y2_ASF_HCU_CCSR_UC_STATE_MSK;
+ CSR_WRITE_2(sc, B28_Y2_ASF_HCU_CCSR, status);
+ } else
+ CSR_WRITE_1(sc, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET);
+ CSR_WRITE_2(sc, B0_CTST, Y2_ASF_DISABLE);
+
/*
* Since we disabled ASF, S/W reset is required for Power Management.
*/
@@ -1249,6 +1278,10 @@ mskc_reset(struct msk_softc *sc)
CSR_WRITE_4(sc, MR_ADDR(i, GMAC_CTRL), GMC_RST_SET);
CSR_WRITE_4(sc, MR_ADDR(i, GMAC_CTRL), GMC_RST_CLR);
CSR_WRITE_4(sc, MR_ADDR(i, GMAC_CTRL), GMC_F_LOOPB_OFF);
+ if (sc->msk_hw_id == CHIP_ID_YUKON_EX)
+ CSR_WRITE_4(sc, MR_ADDR(i, GMAC_CTRL),
+ GMC_BYP_MACSECRX_ON | GMC_BYP_MACSECTX_ON |
+ GMC_BYP_RETR_ON);
}
CSR_WRITE_1(sc, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
@@ -1469,6 +1502,13 @@ msk_attach(device_t dev)
* make Rx checksum offload work on Yukon II hardware.
*/
ifp->if_capabilities = IFCAP_TXCSUM | IFCAP_TSO4;
+ /*
+ * Enable Rx checksum offloading if controller support new
+ * descriptor format.
+ */
+ if ((sc_if->msk_flags & MSK_FLAG_DESCV2) != 0 &&
+ (sc_if->msk_flags & MSK_FLAG_NORX_CSUM) == 0)
+ ifp->if_capabilities |= IFCAP_RXCSUM;
ifp->if_hwassist = MSK_CSUM_FEATURES | CSUM_TSO;
ifp->if_capenable = ifp->if_capabilities;
ifp->if_ioctl = msk_ioctl;
@@ -1512,6 +1552,13 @@ msk_attach(device_t dev)
* for VLAN interface.
*/
ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING;
+ /*
+ * Enable Rx checksum offloading for VLAN taggedd frames
+ * if controller support new descriptor format.
+ */
+ if ((sc_if->msk_flags & MSK_FLAG_DESCV2) != 0 &&
+ (sc_if->msk_flags & MSK_FLAG_NORX_CSUM) == 0)
+ ifp->if_capabilities |= IFCAP_VLAN_HWCSUM;
}
ifp->if_capenable = ifp->if_capabilities;
@@ -1651,13 +1698,32 @@ mskc_attach(device_t dev)
sc->msk_clock = 125; /* 125 Mhz */
sc->msk_pflags |= MSK_FLAG_JUMBO | MSK_FLAG_JUMBO_NOCSUM;
break;
+ case CHIP_ID_YUKON_EX:
+ sc->msk_clock = 125; /* 125 Mhz */
+ sc->msk_pflags |= MSK_FLAG_JUMBO | MSK_FLAG_DESCV2 |
+ MSK_FLAG_AUTOTX_CSUM;
+ /*
+ * Yukon Extreme seems to have silicon bug for
+ * automatic Tx checksum calculation capability.
+ */
+ if (sc->msk_hw_rev == CHIP_REV_YU_EX_B0)
+ sc->msk_pflags &= ~MSK_FLAG_AUTOTX_CSUM;
+ /*
+ * Yukon Extreme A0 could not use store-and-forward
+ * for jumbo frames, so disable Tx checksum
+ * offloading for jumbo frames.
+ */
+ if (sc->msk_hw_rev == CHIP_REV_YU_EX_A0)
+ sc->msk_pflags |= MSK_FLAG_JUMBO_NOCSUM;
+ break;
case CHIP_ID_YUKON_FE:
sc->msk_clock = 100; /* 100 Mhz */
sc->msk_pflags |= MSK_FLAG_FASTETHER;
break;
case CHIP_ID_YUKON_FE_P:
sc->msk_clock = 50; /* 50 Mhz */
- sc->msk_pflags |= MSK_FLAG_FASTETHER | MSK_FLAG_DESCV2;
+ sc->msk_pflags |= MSK_FLAG_FASTETHER | MSK_FLAG_DESCV2 |
+ MSK_FLAG_AUTOTX_CSUM;
if (sc->msk_hw_rev == CHIP_REV_YU_FE_P_A0) {
/*
* XXX
@@ -1669,7 +1735,8 @@ mskc_attach(device_t dev)
* Just pass received frames to upper stack with
* minimal test and let upper stack handle them.
*/
- sc->msk_pflags |= MSK_FLAG_NOHWVLAN | MSK_FLAG_NORXCHK;
+ sc->msk_pflags |= MSK_FLAG_NOHWVLAN |
+ MSK_FLAG_NORXCHK | MSK_FLAG_NORX_CSUM;
}
break;
case CHIP_ID_YUKON_XL:
@@ -2450,8 +2517,10 @@ msk_encap(struct msk_if_softc *sc_if, struct mbuf **m_head)
tcp_offset = offset = 0;
m = *m_head;
- if ((sc_if->msk_flags & MSK_FLAG_DESCV2) == 0 &&
- (m->m_pkthdr.csum_flags & (MSK_CSUM_FEATURES | CSUM_TSO)) != 0) {
+ if (((sc_if->msk_flags & MSK_FLAG_AUTOTX_CSUM) == 0 &&
+ (m->m_pkthdr.csum_flags & MSK_CSUM_FEATURES) != 0) ||
+ ((sc_if->msk_flags & MSK_FLAG_DESCV2) == 0 &&
+ (m->m_pkthdr.csum_flags & CSUM_TSO) != 0)) {
/*
* Since mbuf has no protocol specific structure information
* in it we have to inspect protocol information here to
@@ -2510,9 +2579,12 @@ msk_encap(struct msk_if_softc *sc_if, struct mbuf **m_head)
* resort to S/W checksum routine when we encounter short
* TCP frames.
* Short UDP packets appear to be handled correctly by
- * Yukon II.
+ * Yukon II. Also I assume this bug does not happen on
+ * controllers that use newer descriptor format or
+ * automatic Tx checksum calaulcation.
*/
- if (m->m_pkthdr.len < MSK_MIN_FRAMELEN &&
+ if ((sc_if->msk_flags & MSK_FLAG_AUTOTX_CSUM) == 0 &&
+ (m->m_pkthdr.len < MSK_MIN_FRAMELEN) &&
(m->m_pkthdr.csum_flags & CSUM_TCP) != 0) {
m = m_pullup(m, offset + sizeof(struct tcphdr));
if (m == NULL) {
@@ -2613,7 +2685,7 @@ msk_encap(struct msk_if_softc *sc_if, struct mbuf **m_head)
}
/* Check if we have to handle checksum offload. */
if (tso == 0 && (m->m_pkthdr.csum_flags & MSK_CSUM_FEATURES) != 0) {
- if ((sc_if->msk_flags & MSK_FLAG_DESCV2) != 0)
+ if ((sc_if->msk_flags & MSK_FLAG_AUTOTX_CSUM) != 0)
control |= CALSUM;
else {
tx_le = &sc_if->msk_rdata.msk_tx_ring[prod];
@@ -2895,7 +2967,8 @@ msk_fixup_rx(struct mbuf *m)
#endif
static void
-msk_rxeof(struct msk_if_softc *sc_if, uint32_t status, int len)
+msk_rxeof(struct msk_if_softc *sc_if, uint32_t status, uint32_t control,
+ int len)
{
struct mbuf *m;
struct ifnet *ifp;
@@ -2947,6 +3020,18 @@ msk_rxeof(struct msk_if_softc *sc_if, uint32_t status, int len)
msk_fixup_rx(m);
#endif
ifp->if_ipackets++;
+ if ((ifp->if_capenable & IFCAP_RXCSUM) != 0 &&
+ (control & (CSS_IPV4 | CSS_IPFRAG)) == CSS_IPV4) {
+ m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
+ if ((control & CSS_IPV4_CSUM_OK) != 0)
+ m->m_pkthdr.csum_flags |= CSUM_IP_VALID;
+ if ((control & (CSS_TCP | CSS_UDP)) != 0 &&
+ (control & (CSS_TCPUDP_CSUM_OK)) != 0) {
+ m->m_pkthdr.csum_flags |= CSUM_DATA_VALID |
+ CSUM_PSEUDO_HDR;
+ m->m_pkthdr.csum_data = 0xffff;
+ }
+ }
/* Check for VLAN tagged packets. */
if ((status & GMR_FS_VLAN) != 0 &&
(ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0) {
@@ -2963,7 +3048,8 @@ msk_rxeof(struct msk_if_softc *sc_if, uint32_t status, int len)
}
static void
-msk_jumbo_rxeof(struct msk_if_softc *sc_if, uint32_t status, int len)
+msk_jumbo_rxeof(struct msk_if_softc *sc_if, uint32_t status, uint32_t control,
+ int len)
{
struct mbuf *m;
struct ifnet *ifp;
@@ -3004,6 +3090,18 @@ msk_jumbo_rxeof(struct msk_if_softc *sc_if, uint32_t status, int len)
msk_fixup_rx(m);
#endif
ifp->if_ipackets++;
+ if ((ifp->if_capenable & IFCAP_RXCSUM) != 0 &&
+ (control & (CSS_IPV4 | CSS_IPFRAG)) == CSS_IPV4) {
+ m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
+ if ((control & CSS_IPV4_CSUM_OK) != 0)
+ m->m_pkthdr.csum_flags |= CSUM_IP_VALID;
+ if ((control & (CSS_TCP | CSS_UDP)) != 0 &&
+ (control & (CSS_TCPUDP_CSUM_OK)) != 0) {
+ m->m_pkthdr.csum_flags |= CSUM_DATA_VALID |
+ CSUM_PSEUDO_HDR;
+ m->m_pkthdr.csum_data = 0xffff;
+ }
+ }
/* Check for VLAN tagged packets. */
if ((status & GMR_FS_VLAN) != 0 &&
(ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0) {
@@ -3332,9 +3430,9 @@ msk_handle_events(struct msk_softc *sc)
case OP_RXSTAT:
if (sc_if->msk_framesize >
(MCLBYTES - MSK_RX_BUF_ALIGN))
- msk_jumbo_rxeof(sc_if, status, len);
+ msk_jumbo_rxeof(sc_if, status, control, len);
else
- msk_rxeof(sc_if, status, len);
+ msk_rxeof(sc_if, status, control, len);
rxprog++;
/*
* Because there is no way to sync single Rx LE
@@ -3542,6 +3640,48 @@ done:
}
static void
+msk_set_tx_stfwd(struct msk_if_softc *sc_if)
+{
+ struct msk_softc *sc;
+ struct ifnet *ifp;
+
+ ifp = sc_if->msk_ifp;
+ sc = sc_if->msk_softc;
+ switch (sc->msk_hw_id) {
+ case CHIP_ID_YUKON_EX:
+ if (sc->msk_hw_rev == CHIP_REV_YU_EX_A0)
+ goto yukon_ex_workaround;
+ if (ifp->if_mtu > ETHERMTU)
+ CSR_WRITE_4(sc,
+ MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T),
+ TX_JUMBO_ENA | TX_STFW_ENA);
+ else
+ CSR_WRITE_4(sc,
+ MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T),
+ TX_JUMBO_DIS | TX_STFW_ENA);
+ break;
+ default:
+yukon_ex_workaround:
+ if (ifp->if_mtu > ETHERMTU) {
+ /* Set Tx GMAC FIFO Almost Empty Threshold. */
+ CSR_WRITE_4(sc,
+ MR_ADDR(sc_if->msk_port, TX_GMF_AE_THR),
+ MSK_ECU_JUMBO_WM << 16 | MSK_ECU_AE_THR);
+ /* Disable Store & Forward mode for Tx. */
+ CSR_WRITE_4(sc,
+ MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T),
+ TX_JUMBO_ENA | TX_STFW_DIS);
+ } else {
+ /* Enable Store & Forward mode for Tx. */
+ CSR_WRITE_4(sc,
+ MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T),
+ TX_JUMBO_DIS | TX_STFW_ENA);
+ }
+ break;
+ }
+}
+
+static void
msk_init(void *xsc)
{
struct msk_if_softc *sc_if = xsc;
@@ -3590,6 +3730,10 @@ msk_init_locked(struct msk_if_softc *sc_if)
CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_RST_SET);
CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_RST_CLR);
CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_F_LOOPB_OFF);
+ if (sc->msk_hw_id == CHIP_ID_YUKON_EX)
+ CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL),
+ GMC_BYP_MACSECRX_ON | GMC_BYP_MACSECTX_ON |
+ GMC_BYP_RETR_ON);
/*
* Initialize GMAC first such that speed/duplex/flow-control
@@ -3642,7 +3786,8 @@ msk_init_locked(struct msk_if_softc *sc_if)
CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, RX_GMF_CTRL_T), GMF_RST_SET);
CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, RX_GMF_CTRL_T), GMF_RST_CLR);
reg = GMF_OPER_ON | GMF_RX_F_FL_ON;
- if (sc->msk_hw_id == CHIP_ID_YUKON_FE_P)
+ if (sc->msk_hw_id == CHIP_ID_YUKON_FE_P ||
+ sc->msk_hw_id == CHIP_ID_YUKON_EX)
reg |= GMF_RX_OVER_ON;
CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, RX_GMF_CTRL_T), reg);
@@ -3678,20 +3823,8 @@ msk_init_locked(struct msk_if_softc *sc_if)
MSK_ECU_LLPP);
CSR_WRITE_1(sc, MR_ADDR(sc_if->msk_port, RX_GMF_UP_THR),
MSK_ECU_ULPP);
- if (ifp->if_mtu > ETHERMTU) {
- /*
- * Set Tx GMAC FIFO Almost Empty Threshold.
- */
- CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_AE_THR),
- MSK_ECU_JUMBO_WM << 16 | MSK_ECU_AE_THR);
- /* Disable Store & Forward mode for Tx. */
- CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T),
- TX_JUMBO_ENA | TX_STFW_DIS);
- } else {
- /* Enable Store & Forward mode for Tx. */
- CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T),
- TX_JUMBO_DIS | TX_STFW_ENA);
- }
+ /* Configure store-and-forward for Tx. */
+ msk_set_tx_stfwd(sc_if);
}
if (sc->msk_hw_id == CHIP_ID_YUKON_FE_P &&
@@ -3722,10 +3855,23 @@ msk_init_locked(struct msk_if_softc *sc_if)
CSR_WRITE_4(sc, Q_ADDR(sc_if->msk_txq, Q_CSR), BMU_OPER_INIT);
CSR_WRITE_4(sc, Q_ADDR(sc_if->msk_txq, Q_CSR), BMU_FIFO_OP_ON);
CSR_WRITE_2(sc, Q_ADDR(sc_if->msk_txq, Q_WM), MSK_BMU_TX_WM);
- if (sc->msk_hw_id == CHIP_ID_YUKON_EC_U &&
- sc->msk_hw_rev == CHIP_REV_YU_EC_U_A0) {
- /* Fix for Yukon-EC Ultra: set BMU FIFO level */
- CSR_WRITE_2(sc, Q_ADDR(sc_if->msk_txq, Q_AL), MSK_ECU_TXFF_LEV);
+ switch (sc->msk_hw_id) {
+ case CHIP_ID_YUKON_EC_U:
+ if (sc->msk_hw_rev == CHIP_REV_YU_EC_U_A0) {
+ /* Fix for Yukon-EC Ultra: set BMU FIFO level */
+ CSR_WRITE_2(sc, Q_ADDR(sc_if->msk_txq, Q_AL),
+ MSK_ECU_TXFF_LEV);
+ }
+ break;
+ case CHIP_ID_YUKON_EX:
+ /*
+ * Yukon Extreme seems to have silicon bug for
+ * automatic Tx checksum calculation capability.
+ */
+ if (sc->msk_hw_rev == CHIP_REV_YU_EX_B0)
+ CSR_WRITE_4(sc, Q_ADDR(sc_if->msk_txq, Q_F),
+ F_TX_CHK_AUTO_OFF);
+ break;
}
/* Setup Rx Queue Bus Memory Interface. */
diff --git a/sys/dev/msk/if_mskreg.h b/sys/dev/msk/if_mskreg.h
index 24a2376..d345b60 100644
--- a/sys/dev/msk/if_mskreg.h
+++ b/sys/dev/msk/if_mskreg.h
@@ -139,8 +139,10 @@
#define DEVICEID_MRVL_4362 0x4362
#define DEVICEID_MRVL_4363 0x4363
#define DEVICEID_MRVL_4364 0x4364
-#define DEVICEID_MRVL_8070 0x4365
+#define DEVICEID_MRVL_4365 0x4365
#define DEVICEID_MRVL_436A 0x436A
+#define DEVICEID_MRVL_436B 0x436B
+#define DEVICEID_MRVL_436C 0x436C
/*
* D-Link gigabit ethernet device ID
@@ -225,6 +227,8 @@
#define PCI_OUR_REG_3 0x80 /* 32 bit Our Register 3 */
#define PCI_OUR_REG_4 0x84 /* 32 bit Our Register 4 */
#define PCI_OUR_REG_5 0x88 /* 32 bit Our Register 5 */
+#define PCI_CFG_REG_0 0x90 /* 32 bit Config Register 0 */
+#define PCI_CFG_REG_1 0x94 /* 32 bit Config Register 1 */
/* PCI Express Capability */
#define PEX_CAP_ID 0xe0 /* 8 bit PEX Capability ID */
@@ -325,6 +329,56 @@
#define PCI_CLK_GATE_PEX_UNIT_ENA BIT_1 /* Enable Gate PEX Unit Clock */
#define PCI_CLK_GATE_ROOT_COR_ENA BIT_0 /* Enable Gate Root Core Clock */
+/* PCI_OUR_REG_5 32 bit Our Register 5 (Yukon-ECU only) */
+ /* Bit 31..27: for A3 & later */
+#define PCI_CTL_DIV_CORE_CLK_ENA BIT_31 /* Divide Core Clock Enable */
+#define PCI_CTL_SRESET_VMAIN_AV BIT_30 /* Soft Reset for Vmain_av De-Glitch */
+#define PCI_CTL_BYPASS_VMAIN_AV BIT_29 /* Bypass En. for Vmain_av De-Glitch */
+#define PCI_CTL_TIM_VMAIN_AV1 BIT_28 /* Bit 28..27: Timer Vmain_av Mask */
+#define PCI_CTL_TIM_VMAIN_AV0 BIT_27 /* Bit 28..27: Timer Vmain_av Mask */
+#define PCI_CTL_TIM_VMAIN_AV_MSK (BIT_28 | BIT_27)
+ /* Bit 26..16: Release Clock on Event */
+#define PCI_REL_PCIE_RST_DE_ASS BIT_26 /* PCIe Reset De-Asserted */
+#define PCI_REL_GPHY_REC_PACKET BIT_25 /* GPHY Received Packet */
+#define PCI_REL_INT_FIFO_N_EMPTY BIT_24 /* Internal FIFO Not Empty */
+#define PCI_REL_MAIN_PWR_AVAIL BIT_23 /* Main Power Available */
+#define PCI_REL_CLKRUN_REQ_REL BIT_22 /* CLKRUN Request Release */
+#define PCI_REL_PCIE_RESET_ASS BIT_21 /* PCIe Reset Asserted */
+#define PCI_REL_PME_ASSERTED BIT_20 /* PME Asserted */
+#define PCI_REL_PCIE_EXIT_L1_ST BIT_19 /* PCIe Exit L1 State */
+#define PCI_REL_LOADER_NOT_FIN BIT_18 /* EPROM Loader Not Finished */
+#define PCI_REL_PCIE_RX_EX_IDLE BIT_17 /* PCIe Rx Exit Electrical Idle State */
+#define PCI_REL_GPHY_LINK_UP BIT_16 /* GPHY Link Up */
+ /* Bit 10.. 0: Mask for Gate Clock */
+#define PCI_GAT_PCIE_RST_ASSERTED BIT_10 /* PCIe Reset Asserted */
+#define PCI_GAT_GPHY_N_REC_PACKET BIT_9 /* GPHY Not Received Packet */
+#define PCI_GAT_INT_FIFO_EMPTY BIT_8 /* Internal FIFO Empty */
+#define PCI_GAT_MAIN_PWR_N_AVAIL BIT_7 /* Main Power Not Available */
+#define PCI_GAT_CLKRUN_REQ_REL BIT_6 /* CLKRUN Not Requested */
+#define PCI_GAT_PCIE_RESET_ASS BIT_5 /* PCIe Reset Asserted */
+#define PCI_GAT_PME_DE_ASSERTED BIT_4 /* PME De-Asserted */
+#define PCI_GAT_PCIE_ENTER_L1_ST BIT_3 /* PCIe Enter L1 State */
+#define PCI_GAT_LOADER_FINISHED BIT_2 /* EPROM Loader Finished */
+#define PCI_GAT_PCIE_RX_EL_IDLE BIT_1 /* PCIe Rx Electrical Idle State */
+#define PCI_GAT_GPHY_LINK_DOWN BIT_0 /* GPHY Link Down */
+
+/* PCI_CFG_REG_1 32 bit Config Register 1 */
+#define PCI_CF1_DIS_REL_EVT_RST BIT_24 /* Dis. Rel. Event during PCIE reset */
+ /* Bit 23..21: Release Clock on Event */
+#define PCI_CF1_REL_LDR_NOT_FIN BIT_23 /* EEPROM Loader Not Finished */
+#define PCI_CF1_REL_VMAIN_AVLBL BIT_22 /* Vmain available */
+#define PCI_CF1_REL_PCIE_RESET BIT_21 /* PCI-E reset */
+ /* Bit 20..18: Gate Clock on Event */
+#define PCI_CF1_GAT_LDR_NOT_FIN BIT_20 /* EEPROM Loader Finished */
+#define PCI_CF1_GAT_PCIE_RX_IDLE BIT_19 /* PCI-E Rx Electrical idle */
+#define PCI_CF1_GAT_PCIE_RESET BIT_18 /* PCI-E Reset */
+#define PCI_CF1_PRST_PHY_CLKREQ BIT_17 /* Enable PCI-E rst & PM2PHY gen. CLKREQ */
+#define PCI_CF1_PCIE_RST_CLKREQ BIT_16 /* Enable PCI-E rst generate CLKREQ */
+
+#define PCI_CF1_ENA_CFG_LDR_DONE BIT_8 /* Enable core level Config loader done */
+#define PCI_CF1_ENA_TXBMU_RD_IDLE BIT_1 /* Enable TX BMU Read IDLE for ASPM */
+#define PCI_CF1_ENA_TXBMU_WR_IDLE BIT_0 /* Enable TX BMU Write IDLE for ASPM */
+
/* PEX_DEV_CTRL 16 bit PEX Device Control (Yukon-2) */
#define PEX_DC_MAX_RRS_MSK (7<<12) /* Bit 14..12: Max. Read Request Size */
#define PEX_DC_EN_NO_SNOOP BIT_11 /* Enable No Snoop */
@@ -621,6 +675,7 @@
#define B28_Y2_SMB_CSD_REG 0x0e44 /* 32 bit ASF SMB Control/Status/Data */
#define B28_Y2_ASF_IRQ_V_BASE 0x0e60 /* 32 bit ASF IRQ Vector Base */
#define B28_Y2_ASF_STAT_CMD 0x0e68 /* 32 bit ASF Status and Command Reg */
+#define B28_Y2_ASF_HCU_CCSR 0x0e68 /* 32 bit ASF HCU CCSR (Yukon EX) */
#define B28_Y2_ASF_HOST_COM 0x0e6c /* 32 bit ASF Host Communication Reg */
#define B28_Y2_DATA_REG_1 0x0e70 /* 32 bit ASF/Host Data Register 1 */
#define B28_Y2_DATA_REG_2 0x0e74 /* 32 bit ASF/Host Data Register 2 */
@@ -830,6 +885,7 @@
#define CHIP_ID_YUKON_LP 0xb2 /* Chip ID for YUKON-LP */
#define CHIP_ID_YUKON_XL 0xb3 /* Chip ID for YUKON-2 XL */
#define CHIP_ID_YUKON_EC_U 0xb4 /* Chip ID for YUKON-2 EC Ultra */
+#define CHIP_ID_YUKON_EX 0xb5 /* Chip ID for YUKON-2 Extreme */
#define CHIP_ID_YUKON_EC 0xb6 /* Chip ID for YUKON-2 EC */
#define CHIP_ID_YUKON_FE 0xb7 /* Chip ID for YUKON-2 FE */
#define CHIP_ID_YUKON_FE_P 0xb8 /* Chip ID for YUKON-2 FE+ */
@@ -848,6 +904,9 @@
#define CHIP_REV_YU_FE_P_A0 0 /* Chip Rev. for Yukon-2 FE+ A0 */
+#define CHIP_REV_YU_EX_A0 1 /* Chip Rev. for Yukon-2 EX A0 */
+#define CHIP_REV_YU_EX_B0 2 /* Chip Rev. for Yukon-2 EX B0 */
+
/* B2_Y2_CLK_GATE 8 bit Clock Gating (Yukon-2 only) */
#define Y2_STATUS_LNK2_INAC BIT_7 /* Status Link 2 inactiv (0 = activ) */
#define Y2_CLK_GAT_LNK2_DIS BIT_6 /* Disable clock gating Link 2 */
@@ -912,6 +971,18 @@
#define TST_CFG_WRITE_ON BIT_1 /* Enable Config Reg WR */
#define TST_CFG_WRITE_OFF BIT_0 /* Disable Config Reg WR */
+/* B2_GP_IO */
+#define GLB_GPIO_CLK_DEB_ENA BIT_31 /* Clock Debug Enable */
+#define GLB_GPIO_CLK_DBG_MSK 0x3c000000 /* Clock Debug */
+
+#define GLB_GPIO_INT_RST_D3_DIS BIT_15 /* Disable Internal Reset After D3 to D0 */
+#define GLB_GPIO_LED_PAD_SPEED_UP BIT_14 /* LED PAD Speed Up */
+#define GLB_GPIO_STAT_RACE_DIS BIT_13 /* Status Race Disable */
+#define GLB_GPIO_TEST_SEL_MSK 0x00001800 /* Testmode Select */
+#define GLB_GPIO_TEST_SEL_BASE BIT_11
+#define GLB_GPIO_RAND_ENA BIT_10 /* Random Enable */
+#define GLB_GPIO_RAND_BIT_1 BIT_9 /* Random Bit 1 */
+
/* B2_I2C_CTRL 32 bit I2C HW Control Register */
#define I2C_FLAG BIT_31 /* Start read/write if WR */
#define I2C_ADDR (0x7fff<<16) /* Bit 30..16: Addr to be RD/WR */
@@ -1033,13 +1104,16 @@
/* Bit 10..0: same as for Rx */
/* Q_F 32 bit Flag Register */
-#define F_ALM_FULL BIT_27 /* Rx FIFO: almost full */
-#define F_EMPTY BIT_27 /* Tx FIFO: empty flag */
-#define F_FIFO_EOF BIT_26 /* Tag (EOF Flag) bit in FIFO */
-#define F_WM_REACHED BIT_25 /* Watermark reached */
-#define F_M_RX_RAM_DIS BIT_24 /* MAC Rx RAM Read Port disable */
-#define F_FIFO_LEVEL (0x1f<<16) /* Bit 23..16: # of Qwords in FIFO */
-#define F_WATER_MARK 0x0007ff /* Bit 10.. 0: Watermark */
+#define F_TX_CHK_AUTO_OFF BIT_31 /* Tx checksum auto-calc Off(Yukon EX)*/
+#define F_TX_CHK_AUTO_ON BIT_30 /* Tx checksum auto-calc On(Yukon EX)*/
+#define F_ALM_FULL BIT_28 /* Rx FIFO: almost full */
+#define F_EMPTY BIT_27 /* Tx FIFO: empty flag */
+#define F_FIFO_EOF BIT_26 /* Tag (EOF Flag) bit in FIFO */
+#define F_WM_REACHED BIT_25 /* Watermark reached */
+#define F_M_RX_RAM_DIS BIT_24 /* MAC Rx RAM Read Port disable */
+#define F_FIFO_LEVEL (0x1f<<16)
+ /* Bit 23..16: # of Qwords in FIFO */
+#define F_WATER_MARK 0x0007ff/* Bit 10.. 0: Watermark */
/* Queue Prefetch Unit Offsets, use Y2_PREF_Q_ADDR() to address (Yukon-2 only)*/
/* PREF_UNIT_CTRL_REG 32 bit Prefetch Control register */
@@ -1927,6 +2001,28 @@
#define Y2_ASF_UC_STATE (3<<2) /* ASF uC State */
#define Y2_ASF_CLK_HALT 0 /* ASF system clock stopped */
+/* B28_Y2_ASF_HCU_CCSR 32bit CPU Control and Status Register (Yukon EX) */
+#define Y2_ASF_HCU_CCSR_SMBALERT_MONITOR BIT_27 /* SMBALERT pin monitor */
+#define Y2_ASF_HCU_CCSR_CPU_SLEEP BIT_26 /* CPU sleep status */
+#define Y2_ASF_HCU_CCSR_CS_TO BIT_25 /* Clock Stretching Timeout */
+#define Y2_ASF_HCU_CCSR_WDOG BIT_24 /* Watchdog Reset */
+#define Y2_ASF_HCU_CCSR_CLR_IRQ_HOST BIT_17 /* Clear IRQ_HOST */
+#define Y2_ASF_HCU_CCSR_SET_IRQ_HCU BIT_16 /* Set IRQ_HCU */
+#define Y2_ASF_HCU_CCSR_AHB_RST BIT_9 /* Reset AHB bridge */
+#define Y2_ASF_HCU_CCSR_CPU_RST_MODE BIT_8 /* CPU Reset Mode */
+#define Y2_ASF_HCU_CCSR_SET_SYNC_CPU BIT_5
+#define Y2_ASF_HCU_CCSR_CPU_CLK_DIVIDE1 BIT_4
+#define Y2_ASF_HCU_CCSR_CPU_CLK_DIVIDE0 BIT_3
+#define Y2_ASF_HCU_CCSR_CPU_CLK_DIVIDE_MSK (BIT_4 | BIT_3) /* CPU Clock Divide */
+#define Y2_ASF_HCU_CCSR_CPU_CLK_DIVIDE_BASE BIT_3
+#define Y2_ASF_HCU_CCSR_OS_PRSNT BIT_2 /* ASF OS Present */
+ /* Microcontroller State */
+#define Y2_ASF_HCU_CCSR_UC_STATE_MSK 3
+#define Y2_ASF_HCU_CCSR_UC_STATE_BASE BIT_0
+#define Y2_ASF_HCU_CCSR_ASF_RESET 0
+#define Y2_ASF_HCU_CCSR_ASF_HALTED BIT_1
+#define Y2_ASF_HCU_CCSR_ASF_RUNNING BIT_0
+
/* B28_Y2_ASF_HOST_COM 32 bit ASF Host Communication Reg */
/* This register is used by the ASF firmware */
#define Y2_ASF_CLR_ASFI BIT_1 /* Clear host IRQ */
@@ -1940,6 +2036,14 @@
#define SC_STAT_RST_SET BIT_0 /* Set Status Unit Reset */
/* GMAC_CTRL 32 bit GMAC Control Reg (YUKON only) */
+#define GMC_SEC_RST BIT_15 /* MAC SEC RST */
+#define GMC_SEC_RST_OFF BIT_14 /* MAC SEC RST Off */
+#define GMC_BYP_MACSECRX_ON BIT_13 /* Bypass MAC SEC RX */
+#define GMC_BYP_MACSECRX_OFF BIT_12 /* Bypass MAC SEC RX Off */
+#define GMC_BYP_MACSECTX_ON BIT_11 /* Bypass MAC SEC TX */
+#define GMC_BYP_MACSECTX_OFF BIT_10 /* Bypass MAC SEC TX Off */
+#define GMC_BYP_RETR_ON BIT_9 /* Bypass MAC retransmit FIFO On */
+#define GMC_BYP_RETR_OFF BIT_8 /* Bypass MAC retransmit FIFO Off */
#define GMC_H_BURST_ON BIT_7 /* Half Duplex Burst Mode On */
#define GMC_H_BURST_OFF BIT_6 /* Half Duplex Burst Mode Off */
#define GMC_F_LOOPB_ON BIT_5 /* FIFO Loopback On */
@@ -2153,8 +2257,19 @@ struct msk_stat_desc {
#define OP_PUTIDX 0x70000000
#define STLE_OP_MASK 0xff000000
+#define STLE_CSS_MASK 0x00ff0000
#define STLE_LEN_MASK 0x0000ffff
+/* CSS defined in status LE(valid for descriptor V2 format). */
+#define CSS_TCPUDP_CSUM_OK 0x00800000
+#define CSS_UDP 0x00400000
+#define CSS_TCP 0x00200000
+#define CSS_IPFRAG 0x00100000
+#define CSS_IPV6 0x00080000
+#define CSS_IPV4_CSUM_OK 0x00040000
+#define CSS_IPV4 0x00020000
+#define CSS_PORT 0x00010000
+
/* Descriptor Bit Definition */
/* TxCtrl Transmit Buffer Control Field */
/* RxCtrl Receive Buffer Control Field */
@@ -2400,8 +2515,10 @@ struct msk_if_softc {
#define MSK_FLAG_JUMBO_NOCSUM 0x0010
#define MSK_FLAG_RAMBUF 0x0020
#define MSK_FLAG_DESCV2 0x0040
-#define MSK_FLAG_NOHWVLAN 0x0080
-#define MSK_FLAG_NORXCHK 0x0100
+#define MSK_FLAG_AUTOTX_CSUM 0x0080
+#define MSK_FLAG_NOHWVLAN 0x0100
+#define MSK_FLAG_NORXCHK 0x0200
+#define MSK_FLAG_NORX_CSUM 0x0400
#define MSK_FLAG_SUSPEND 0x2000
#define MSK_FLAG_DETACH 0x4000
#define MSK_FLAG_LINK 0x8000
diff --git a/sys/dev/mxge/if_mxge.c b/sys/dev/mxge/if_mxge.c
index 22b5ce2..765b4d9 100644
--- a/sys/dev/mxge/if_mxge.c
+++ b/sys/dev/mxge/if_mxge.c
@@ -30,8 +30,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#define IFNET_BUF_RING
-
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/linker.h>
@@ -68,9 +66,6 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/in_cksum.h>
#include <machine/resource.h>
-#ifdef IFNET_BUF_RING
-#include <sys/buf_ring.h>
-#endif
#include <sys/bus.h>
#include <sys/rman.h>
#include <sys/smp.h>
@@ -90,6 +85,9 @@ __FBSDID("$FreeBSD$");
#include <dev/mxge/mcp_gen_header.h>
/*#define MXGE_FAKE_IFP*/
#include <dev/mxge/if_mxge_var.h>
+#ifdef IFNET_BUF_RING
+#include <sys/buf_ring.h>
+#endif
/* tunable params */
static int mxge_nvidia_ecrc_enable = 1;
@@ -2200,6 +2198,7 @@ mxge_transmit_locked(struct mxge_slice_state *ss, struct mbuf *m)
BPF_MTAP(ifp, m);
/* give it to the nic */
mxge_encap(ss, m);
+ drbr_stats_update(ifp, m->m_pkthdr.len, m->m_flags);
} else if ((err = drbr_enqueue(ifp, tx->br, m)) != 0) {
return (err);
}
@@ -2656,11 +2655,6 @@ mxge_tx_done(struct mxge_slice_state *ss, uint32_t mcp_idx)
/* mbuf and DMA map only attached to the first
segment per-mbuf */
if (m != NULL) {
-#ifdef IFNET_BUF_RING
- ss->obytes += m->m_pkthdr.len;
- if (m->m_flags & M_MCAST)
- ss->omcasts++;
-#endif
ss->opackets++;
tx->info[idx].m = NULL;
map = tx->info[idx].map;
@@ -3787,11 +3781,6 @@ mxge_update_stats(mxge_softc_t *sc)
struct mxge_slice_state *ss;
u_long ipackets = 0;
u_long opackets = 0;
-#ifdef IFNET_BUF_RING
- u_long obytes = 0;
- u_long omcasts = 0;
- u_long odrops = 0;
-#endif
u_long oerrors = 0;
int slice;
@@ -3799,20 +3788,10 @@ mxge_update_stats(mxge_softc_t *sc)
ss = &sc->ss[slice];
ipackets += ss->ipackets;
opackets += ss->opackets;
-#ifdef IFNET_BUF_RING
- obytes += ss->obytes;
- omcasts += ss->omcasts;
- odrops += ss->tx.br->br_drops;
-#endif
oerrors += ss->oerrors;
}
sc->ifp->if_ipackets = ipackets;
sc->ifp->if_opackets = opackets;
-#ifdef IFNET_BUF_RING
- sc->ifp->if_obytes = obytes;
- sc->ifp->if_omcasts = omcasts;
- sc->ifp->if_snd.ifq_drops = odrops;
-#endif
sc->ifp->if_oerrors = oerrors;
}
diff --git a/sys/dev/mxge/if_mxge_var.h b/sys/dev/mxge/if_mxge_var.h
index b17faf2..8240b62 100644
--- a/sys/dev/mxge/if_mxge_var.h
+++ b/sys/dev/mxge/if_mxge_var.h
@@ -46,6 +46,10 @@ $FreeBSD$
#define MXGE_VIRT_JUMBOS 0
#endif
+#if (__FreeBSD_version > 800082)
+#define IFNET_BUF_RING 1
+#endif
+
#ifndef VLAN_CAPABILITIES
#define VLAN_CAPABILITIES(ifp)
#define mxge_vlans_active(sc) (sc)->ifp->if_nvlans
@@ -192,8 +196,6 @@ struct mxge_slice_state {
volatile uint32_t *irq_claim;
u_long ipackets;
u_long opackets;
- u_long obytes;
- u_long omcasts;
u_long oerrors;
int if_drv_flags;
struct lro_head lro_active;
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index 49a272b..667072f 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
+#include <machine/stdarg.h>
#if defined(__i386__) || defined(__amd64__)
#include <machine/intr_machdep.h>
diff --git a/sys/dev/puc/pucdata.c b/sys/dev/puc/pucdata.c
index 4d42a04..07f603d 100644
--- a/sys/dev/puc/pucdata.c
+++ b/sys/dev/puc/pucdata.c
@@ -234,6 +234,17 @@ const struct puc_cfg puc_pci_devices[] = {
},
/*
+ * IBM SurePOS 300 Series (481033H) serial ports
+ * Details can be found on the IBM RSS websites
+ */
+
+ { 0x1014, 0x0297, 0xffff, 0,
+ "IBM SurePOS 300 Series (481033H) serial ports",
+ DEFAULT_RCLK,
+ PUC_PORT_4S, 0x10, 4, 0
+ },
+
+ /*
* SIIG Boards.
*
* SIIG provides documentation for their boards at:
diff --git a/sys/dev/usb/input/ukbd.c b/sys/dev/usb/input/ukbd.c
index 32826664..836cedf 100644
--- a/sys/dev/usb/input/ukbd.c
+++ b/sys/dev/usb/input/ukbd.c
@@ -822,7 +822,7 @@ detach:
return (ENXIO); /* error */
}
-int
+static int
ukbd_detach(device_t dev)
{
struct ukbd_softc *sc = device_get_softc(dev);
@@ -1569,7 +1569,7 @@ static int
ukbd_driver_load(module_t mod, int what, void *arg)
{
switch (what) {
- case MOD_LOAD:
+ case MOD_LOAD:
kbd_add_driver(&ukbd_kbd_driver);
break;
case MOD_UNLOAD:
diff --git a/sys/dev/usb/usb_compat_linux.h b/sys/dev/usb/usb_compat_linux.h
index 9066702..0dc815d 100644
--- a/sys/dev/usb/usb_compat_linux.h
+++ b/sys/dev/usb/usb_compat_linux.h
@@ -339,6 +339,6 @@ void usb_linux_register(void *arg);
void usb_linux_deregister(void *arg);
#define interface_to_usbdev(intf) (intf)->linux_udev
-#define interface_to_bsddev(intf) (intf)->linux_udev->bsd_udev
+#define interface_to_bsddev(intf) (intf)->linux_udev
#endif /* _USB_COMPAT_LINUX_H */
diff --git a/sys/dev/usb/usb_dev.c b/sys/dev/usb/usb_dev.c
index 138fc5c..1b1e986 100644
--- a/sys/dev/usb/usb_dev.c
+++ b/sys/dev/usb/usb_dev.c
@@ -88,9 +88,9 @@ static struct usb_pipe *usb2_dev_get_pipe(struct usb_device *, uint8_t,
static void usb2_loc_fill(struct usb_fs_privdata *,
struct usb_cdev_privdata *);
static void usb2_close(void *);
-static usb_error_t usb2_ref_device(struct usb_cdev_privdata *, int);
-static usb_error_t usb2_usb_ref_device(struct usb_cdev_privdata *);
-static void usb2_unref_device(struct usb_cdev_privdata *);
+static usb_error_t usb2_ref_device(struct usb_cdev_privdata *, struct usb_cdev_refdata *, int);
+static usb_error_t usb2_usb_ref_device(struct usb_cdev_privdata *, struct usb_cdev_refdata *);
+static void usb2_unref_device(struct usb_cdev_privdata *, struct usb_cdev_refdata *);
static d_open_t usb2_open;
static d_ioctl_t usb2_ioctl;
@@ -158,12 +158,16 @@ usb2_loc_fill(struct usb_fs_privdata* pd, struct usb_cdev_privdata *cpd)
* Else: Failure.
*------------------------------------------------------------------------*/
usb_error_t
-usb2_ref_device(struct usb_cdev_privdata* cpd, int need_uref)
+usb2_ref_device(struct usb_cdev_privdata *cpd,
+ struct usb_cdev_refdata *crd, int need_uref)
{
struct usb_fifo **ppf;
struct usb_fifo *f;
- DPRINTFN(2, "usb2_ref_device, cpd=%p need uref=%d\n", cpd, need_uref);
+ DPRINTFN(2, "cpd=%p need uref=%d\n", cpd, need_uref);
+
+ /* clear all refs */
+ memset(crd, 0, sizeof(*crd));
mtx_lock(&usb2_ref_lock);
cpd->bus = devclass_get_softc(usb2_devclass_ptr, cpd->bus_index);
@@ -183,7 +187,6 @@ usb2_ref_device(struct usb_cdev_privdata* cpd, int need_uref)
if (need_uref) {
DPRINTFN(2, "ref udev - needed\n");
cpd->udev->refcount++;
- cpd->is_uref = 1;
mtx_unlock(&usb2_ref_lock);
@@ -194,82 +197,72 @@ usb2_ref_device(struct usb_cdev_privdata* cpd, int need_uref)
sx_xlock(cpd->udev->default_sx + 1);
mtx_lock(&usb2_ref_lock);
+
+ /*
+ * Set "is_uref" after grabbing the default SX lock
+ */
+ crd->is_uref = 1;
}
/* check if we are doing an open */
if (cpd->fflags == 0) {
- /* set defaults */
- cpd->txfifo = NULL;
- cpd->rxfifo = NULL;
- cpd->is_write = 0;
- cpd->is_read = 0;
- cpd->is_usbfs = 0;
+ /* use zero defaults */
} else {
- /* initialise "is_usbfs" flag */
- cpd->is_usbfs = 0;
-
/* check for write */
if (cpd->fflags & FWRITE) {
ppf = cpd->udev->fifo;
f = ppf[cpd->fifo_index + USB_FIFO_TX];
- cpd->txfifo = f;
- cpd->is_write = 1; /* ref */
+ crd->txfifo = f;
+ crd->is_write = 1; /* ref */
if (f == NULL || f->refcount == USB_FIFO_REF_MAX)
goto error;
if (f->curr_cpd != cpd)
goto error;
/* check if USB-FS is active */
if (f->fs_ep_max != 0) {
- cpd->is_usbfs = 1;
+ crd->is_usbfs = 1;
}
- } else {
- cpd->txfifo = NULL;
- cpd->is_write = 0; /* no ref */
}
/* check for read */
if (cpd->fflags & FREAD) {
ppf = cpd->udev->fifo;
f = ppf[cpd->fifo_index + USB_FIFO_RX];
- cpd->rxfifo = f;
- cpd->is_read = 1; /* ref */
+ crd->rxfifo = f;
+ crd->is_read = 1; /* ref */
if (f == NULL || f->refcount == USB_FIFO_REF_MAX)
goto error;
if (f->curr_cpd != cpd)
goto error;
/* check if USB-FS is active */
if (f->fs_ep_max != 0) {
- cpd->is_usbfs = 1;
+ crd->is_usbfs = 1;
}
- } else {
- cpd->rxfifo = NULL;
- cpd->is_read = 0; /* no ref */
}
}
/* when everything is OK we increment the refcounts */
- if (cpd->is_write) {
+ if (crd->is_write) {
DPRINTFN(2, "ref write\n");
- cpd->txfifo->refcount++;
+ crd->txfifo->refcount++;
}
- if (cpd->is_read) {
+ if (crd->is_read) {
DPRINTFN(2, "ref read\n");
- cpd->rxfifo->refcount++;
+ crd->rxfifo->refcount++;
}
mtx_unlock(&usb2_ref_lock);
- if (cpd->is_uref) {
+ if (crd->is_uref) {
mtx_lock(&Giant); /* XXX */
}
return (0);
error:
- if (cpd->is_uref) {
+ if (crd->is_uref) {
sx_unlock(cpd->udev->default_sx + 1);
if (--(cpd->udev->refcount) == 0) {
usb2_cv_signal(cpd->udev->default_cv + 1);
}
- cpd->is_uref = 0;
}
mtx_unlock(&usb2_ref_lock);
DPRINTFN(2, "fail\n");
@@ -287,21 +280,22 @@ error:
* Else: Failure.
*------------------------------------------------------------------------*/
static usb_error_t
-usb2_usb_ref_device(struct usb_cdev_privdata *cpd)
+usb2_usb_ref_device(struct usb_cdev_privdata *cpd,
+ struct usb_cdev_refdata *crd)
{
/*
* Check if we already got an USB reference on this location:
*/
- if (cpd->is_uref)
+ if (crd->is_uref)
return (0); /* success */
/*
* To avoid deadlock at detach we need to drop the FIFO ref
* and re-acquire a new ref!
*/
- usb2_unref_device(cpd);
+ usb2_unref_device(cpd, crd);
- return (usb2_ref_device(cpd, 1 /* need uref */));
+ return (usb2_ref_device(cpd, crd, 1 /* need uref */));
}
/*------------------------------------------------------------------------*
@@ -311,30 +305,34 @@ usb2_usb_ref_device(struct usb_cdev_privdata *cpd)
* given USB device.
*------------------------------------------------------------------------*/
void
-usb2_unref_device(struct usb_cdev_privdata *cpd)
+usb2_unref_device(struct usb_cdev_privdata *cpd,
+ struct usb_cdev_refdata *crd)
{
- if (cpd->is_uref) {
+
+ DPRINTFN(2, "cpd=%p is_uref=%d\n", cpd, crd->is_uref);
+
+ if (crd->is_uref) {
mtx_unlock(&Giant); /* XXX */
sx_unlock(cpd->udev->default_sx + 1);
}
mtx_lock(&usb2_ref_lock);
- if (cpd->is_read) {
- if (--(cpd->rxfifo->refcount) == 0) {
- usb2_cv_signal(&cpd->rxfifo->cv_drain);
+ if (crd->is_read) {
+ if (--(crd->rxfifo->refcount) == 0) {
+ usb2_cv_signal(&crd->rxfifo->cv_drain);
}
- cpd->is_read = 0;
+ crd->is_read = 0;
}
- if (cpd->is_write) {
- if (--(cpd->txfifo->refcount) == 0) {
- usb2_cv_signal(&cpd->txfifo->cv_drain);
+ if (crd->is_write) {
+ if (--(crd->txfifo->refcount) == 0) {
+ usb2_cv_signal(&crd->txfifo->cv_drain);
}
- cpd->is_write = 0;
+ crd->is_write = 0;
}
- if (cpd->is_uref) {
+ if (crd->is_uref) {
if (--(cpd->udev->refcount) == 0) {
usb2_cv_signal(cpd->udev->default_cv + 1);
}
- cpd->is_uref = 0;
+ crd->is_uref = 0;
}
mtx_unlock(&usb2_ref_lock);
}
@@ -357,7 +355,8 @@ usb2_fifo_alloc(void)
* usb2_fifo_create
*------------------------------------------------------------------------*/
static int
-usb2_fifo_create(struct usb_cdev_privdata *cpd)
+usb2_fifo_create(struct usb_cdev_privdata *cpd,
+ struct usb_cdev_refdata *crd)
{
struct usb_device *udev = cpd->udev;
struct usb_fifo *f;
@@ -381,13 +380,13 @@ usb2_fifo_create(struct usb_cdev_privdata *cpd)
f = udev->fifo[cpd->fifo_index + USB_FIFO_TX];
if (f == NULL)
return (EINVAL);
- cpd->txfifo = f;
+ crd->txfifo = f;
}
if (is_rx) {
f = udev->fifo[cpd->fifo_index + USB_FIFO_RX];
if (f == NULL)
return (EINVAL);
- cpd->rxfifo = f;
+ crd->rxfifo = f;
}
return (0);
}
@@ -516,10 +515,10 @@ usb2_fifo_create(struct usb_cdev_privdata *cpd)
mtx_unlock(&usb2_ref_lock);
}
if (is_tx) {
- cpd->txfifo = udev->fifo[n + USB_FIFO_TX];
+ crd->txfifo = udev->fifo[n + USB_FIFO_TX];
}
if (is_rx) {
- cpd->rxfifo = udev->fifo[n + USB_FIFO_RX];
+ crd->rxfifo = udev->fifo[n + USB_FIFO_RX];
}
/* fill out fifo index */
DPRINTFN(5, "fifo index = %d\n", n);
@@ -806,6 +805,7 @@ static int
usb2_open(struct cdev *dev, int fflags, int devtype, struct thread *td)
{
struct usb_fs_privdata* pd = (struct usb_fs_privdata*)dev->si_drv1;
+ struct usb_cdev_refdata refs;
struct usb_cdev_privdata *cpd;
int err, ep;
@@ -822,7 +822,7 @@ usb2_open(struct cdev *dev, int fflags, int devtype, struct thread *td)
ep = cpd->ep_addr = pd->ep_addr;
usb2_loc_fill(pd, cpd);
- err = usb2_ref_device(cpd, 1);
+ err = usb2_ref_device(cpd, &refs, 1);
if (err) {
DPRINTFN(2, "cannot ref device\n");
free(cpd, M_USBDEV);
@@ -831,36 +831,36 @@ usb2_open(struct cdev *dev, int fflags, int devtype, struct thread *td)
cpd->fflags = fflags; /* access mode for open lifetime */
/* create FIFOs, if any */
- err = usb2_fifo_create(cpd);
+ err = usb2_fifo_create(cpd, &refs);
/* check for error */
if (err) {
DPRINTFN(2, "cannot create fifo\n");
- usb2_unref_device(cpd);
+ usb2_unref_device(cpd, &refs);
free(cpd, M_USBDEV);
return (err);
}
if (fflags & FREAD) {
- err = usb2_fifo_open(cpd, cpd->rxfifo, fflags);
+ err = usb2_fifo_open(cpd, refs.rxfifo, fflags);
if (err) {
DPRINTFN(2, "read open failed\n");
- usb2_unref_device(cpd);
+ usb2_unref_device(cpd, &refs);
free(cpd, M_USBDEV);
return (err);
}
}
if (fflags & FWRITE) {
- err = usb2_fifo_open(cpd, cpd->txfifo, fflags);
+ err = usb2_fifo_open(cpd, refs.txfifo, fflags);
if (err) {
DPRINTFN(2, "write open failed\n");
if (fflags & FREAD) {
- usb2_fifo_close(cpd->rxfifo, fflags);
+ usb2_fifo_close(refs.rxfifo, fflags);
}
- usb2_unref_device(cpd);
+ usb2_unref_device(cpd, &refs);
free(cpd, M_USBDEV);
return (err);
}
}
- usb2_unref_device(cpd);
+ usb2_unref_device(cpd, &refs);
devfs_set_cdevpriv(cpd, usb2_close);
return (0);
@@ -872,24 +872,25 @@ usb2_open(struct cdev *dev, int fflags, int devtype, struct thread *td)
static void
usb2_close(void *arg)
{
+ struct usb_cdev_refdata refs;
struct usb_cdev_privdata *cpd = arg;
int err;
DPRINTFN(2, "cpd=%p\n", cpd);
- err = usb2_ref_device(cpd, 1);
+ err = usb2_ref_device(cpd, &refs, 1);
if (err) {
free(cpd, M_USBDEV);
return;
}
if (cpd->fflags & FREAD) {
- usb2_fifo_close(cpd->rxfifo, cpd->fflags);
+ usb2_fifo_close(refs.rxfifo, cpd->fflags);
}
if (cpd->fflags & FWRITE) {
- usb2_fifo_close(cpd->txfifo, cpd->fflags);
+ usb2_fifo_close(refs.txfifo, cpd->fflags);
}
- usb2_unref_device(cpd);
+ usb2_unref_device(cpd, &refs);
free(cpd, M_USBDEV);
return;
}
@@ -988,6 +989,7 @@ usb2_ioctl_f_sub(struct usb_fifo *f, u_long cmd, void *addr,
static int
usb2_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int fflag, struct thread* td)
{
+ struct usb_cdev_refdata refs;
struct usb_cdev_privdata* cpd;
struct usb_fifo *f;
int fflags;
@@ -1000,11 +1002,11 @@ usb2_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int fflag, struct thread*
return (err);
/*
- * Performance optimistaion: We try to check for IOCTL's that
+ * Performance optimisation: We try to check for IOCTL's that
* don't need the USB reference first. Then we grab the USB
* reference if we need it!
*/
- err = usb2_ref_device(cpd, 0 /* no uref */ );
+ err = usb2_ref_device(cpd, &refs, 0 /* no uref */ );
if (err) {
return (ENXIO);
}
@@ -1014,11 +1016,11 @@ usb2_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int fflag, struct thread*
err = ENOIOCTL; /* set default value */
if (fflags & FWRITE) {
- f = cpd->txfifo;
+ f = refs.txfifo;
err = usb2_ioctl_f_sub(f, cmd, addr, td);
}
if (fflags & FREAD) {
- f = cpd->rxfifo;
+ f = refs.rxfifo;
err = usb2_ioctl_f_sub(f, cmd, addr, td);
}
KASSERT(f != NULL, ("fifo not found"));
@@ -1026,7 +1028,7 @@ usb2_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int fflag, struct thread*
err = (f->methods->f_ioctl) (f, cmd, addr, fflags);
DPRINTFN(2, "f_ioctl cmd 0x%lx = %d\n", cmd, err);
if (err == ENOIOCTL) {
- if (usb2_usb_ref_device(cpd)) {
+ if (usb2_usb_ref_device(cpd, &refs)) {
err = ENXIO;
goto done;
}
@@ -1038,7 +1040,7 @@ usb2_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int fflag, struct thread*
err = ENOTTY;
}
done:
- usb2_unref_device(cpd);
+ usb2_unref_device(cpd, &refs);
return (err);
}
@@ -1046,13 +1048,14 @@ done:
static int
usb2_poll(struct cdev* dev, int events, struct thread* td)
{
+ struct usb_cdev_refdata refs;
struct usb_cdev_privdata* cpd;
struct usb_fifo *f;
struct usb_mbuf *m;
int fflags, revents;
if (devfs_get_cdevpriv((void **)&cpd) != 0 ||
- usb2_ref_device(cpd, 0) != 0)
+ usb2_ref_device(cpd, &refs, 0) != 0)
return (events &
(POLLHUP|POLLIN|POLLRDNORM|POLLOUT|POLLWRNORM));
@@ -1063,11 +1066,11 @@ usb2_poll(struct cdev* dev, int events, struct thread* td)
if ((events & (POLLOUT | POLLWRNORM)) &&
(fflags & FWRITE)) {
- f = cpd->txfifo;
+ f = refs.txfifo;
mtx_lock(f->priv_mtx);
- if (!cpd->is_usbfs) {
+ if (!refs.is_usbfs) {
if (f->flag_iserror) {
/* we got an error */
m = (void *)1;
@@ -1102,11 +1105,11 @@ usb2_poll(struct cdev* dev, int events, struct thread* td)
if ((events & (POLLIN | POLLRDNORM)) &&
(fflags & FREAD)) {
- f = cpd->rxfifo;
+ f = refs.rxfifo;
mtx_lock(f->priv_mtx);
- if (!cpd->is_usbfs) {
+ if (!refs.is_usbfs) {
if (f->flag_iserror) {
/* we have and error */
m = (void *)1;
@@ -1135,7 +1138,7 @@ usb2_poll(struct cdev* dev, int events, struct thread* td)
f->flag_isselect = 1;
selrecord(td, &f->selinfo);
- if (!cpd->is_usbfs) {
+ if (!refs.is_usbfs) {
/* start reading data */
(f->methods->f_start_read) (f);
}
@@ -1143,13 +1146,14 @@ usb2_poll(struct cdev* dev, int events, struct thread* td)
mtx_unlock(f->priv_mtx);
}
- usb2_unref_device(cpd);
+ usb2_unref_device(cpd, &refs);
return (revents);
}
static int
usb2_read(struct cdev *dev, struct uio *uio, int ioflag)
{
+ struct usb_cdev_refdata refs;
struct usb_cdev_privdata* cpd;
struct usb_fifo *f;
struct usb_mbuf *m;
@@ -1163,15 +1167,16 @@ usb2_read(struct cdev *dev, struct uio *uio, int ioflag)
if (err != 0)
return (err);
- err = usb2_ref_device(cpd, 0 /* no uref */ );
+ err = usb2_ref_device(cpd, &refs, 0 /* no uref */ );
if (err) {
return (ENXIO);
}
fflags = cpd->fflags;
- f = cpd->rxfifo;
+ f = refs.rxfifo;
if (f == NULL) {
/* should not happen */
+ usb2_unref_device(cpd, &refs);
return (EPERM);
}
@@ -1185,7 +1190,7 @@ usb2_read(struct cdev *dev, struct uio *uio, int ioflag)
goto done;
}
/* check if USB-FS interface is active */
- if (cpd->is_usbfs) {
+ if (refs.is_usbfs) {
/*
* The queue is used for events that should be
* retrieved using the "USB_FS_COMPLETE" ioctl.
@@ -1263,7 +1268,7 @@ usb2_read(struct cdev *dev, struct uio *uio, int ioflag)
done:
mtx_unlock(f->priv_mtx);
- usb2_unref_device(cpd);
+ usb2_unref_device(cpd, &refs);
return (err);
}
@@ -1271,6 +1276,7 @@ done:
static int
usb2_write(struct cdev *dev, struct uio *uio, int ioflag)
{
+ struct usb_cdev_refdata refs;
struct usb_cdev_privdata* cpd;
struct usb_fifo *f;
struct usb_mbuf *m;
@@ -1286,16 +1292,16 @@ usb2_write(struct cdev *dev, struct uio *uio, int ioflag)
if (err != 0)
return (err);
- err = usb2_ref_device(cpd, 0 /* no uref */ );
+ err = usb2_ref_device(cpd, &refs, 0 /* no uref */ );
if (err) {
return (ENXIO);
}
fflags = cpd->fflags;
- f = cpd->txfifo;
+ f = refs.txfifo;
if (f == NULL) {
/* should not happen */
- usb2_unref_device(cpd);
+ usb2_unref_device(cpd, &refs);
return (EPERM);
}
resid = uio->uio_resid;
@@ -1308,7 +1314,7 @@ usb2_write(struct cdev *dev, struct uio *uio, int ioflag)
goto done;
}
/* check if USB-FS interface is active */
- if (cpd->is_usbfs) {
+ if (refs.is_usbfs) {
/*
* The queue is used for events that should be
* retrieved using the "USB_FS_COMPLETE" ioctl.
@@ -1376,7 +1382,7 @@ usb2_write(struct cdev *dev, struct uio *uio, int ioflag)
done:
mtx_unlock(f->priv_mtx);
- usb2_unref_device(cpd);
+ usb2_unref_device(cpd, &refs);
return (err);
}
diff --git a/sys/dev/usb/usb_dev.h b/sys/dev/usb/usb_dev.h
index 3f21542..fb41e5a 100644
--- a/sys/dev/usb/usb_dev.h
+++ b/sys/dev/usb/usb_dev.h
@@ -88,13 +88,19 @@ struct usb_cdev_privdata {
struct usb_bus *bus;
struct usb_device *udev;
struct usb_interface *iface;
- struct usb_fifo *rxfifo;
- struct usb_fifo *txfifo;
int bus_index; /* bus index */
int dev_index; /* device index */
int ep_addr; /* endpoint address */
int fflags;
uint8_t fifo_index; /* FIFO index */
+};
+
+/*
+ * Private per-device and per-thread reference information
+ */
+struct usb_cdev_refdata {
+ struct usb_fifo *rxfifo;
+ struct usb_fifo *txfifo;
uint8_t is_read; /* location has read access */
uint8_t is_write; /* location has write access */
uint8_t is_uref; /* USB refcount decr. needed */
diff --git a/sys/dev/usb/usb_request.c b/sys/dev/usb/usb_request.c
index 3e25655..bdf0a03 100644
--- a/sys/dev/usb/usb_request.c
+++ b/sys/dev/usb/usb_request.c
@@ -109,11 +109,11 @@ usb2_do_clear_stall_callback(struct usb_xfer *xfer)
pipe_end = udev->pipes + udev->pipes_max;
pipe_first = udev->pipes;
to = udev->pipes_max;
- if (pipe == NULL) {
- pipe = pipe_first;
- }
+
switch (USB_GET_STATE(xfer)) {
case USB_ST_TRANSFERRED:
+ if (pipe == NULL)
+ goto tr_setup; /* device was unconfigured */
if (pipe->edesc &&
pipe->is_stalled) {
pipe->toggle_next = 0;
@@ -126,9 +126,10 @@ usb2_do_clear_stall_callback(struct usb_xfer *xfer)
case USB_ST_SETUP:
tr_setup:
- if (pipe == pipe_end) {
- pipe = pipe_first;
- }
+ if (to == 0)
+ break; /* no pipes - nothing to do */
+ if ((pipe < pipe_first) || (pipe >= pipe_end))
+ pipe = pipe_first; /* pipe wrapped around */
if (pipe->edesc &&
pipe->is_stalled) {
@@ -156,9 +157,8 @@ tr_setup:
break;
}
pipe++;
- if (--to)
- goto tr_setup;
- break;
+ to--;
+ goto tr_setup;
default:
if (xfer->error == USB_ERR_CANCELLED) {
diff --git a/sys/gnu/fs/ext2fs/ext2_fs.h b/sys/gnu/fs/ext2fs/ext2_fs.h
index c1d6ffd..8a4081e 100644
--- a/sys/gnu/fs/ext2fs/ext2_fs.h
+++ b/sys/gnu/fs/ext2fs/ext2_fs.h
@@ -52,6 +52,8 @@
#define umode_t mode_t
#define loff_t off_t
+#define cpu_to_le32(x) htole32(x)
+
/*
* The second extended filesystem constants/structures
*/
@@ -87,12 +89,10 @@
#endif
/*
- * Special inodes numbers
+ * Special inode numbers
*/
#define EXT2_BAD_INO 1 /* Bad blocks inode */
#define EXT2_ROOT_INO 2 /* Root inode */
-#define EXT2_ACL_IDX_INO 3 /* ACL inode */
-#define EXT2_ACL_DATA_INO 4 /* ACL inode */
#define EXT2_BOOT_LOADER_INO 5 /* Boot loader inode */
#define EXT2_UNDEL_DIR_INO 6 /* Undelete directory inode */
@@ -104,17 +104,29 @@
*/
#define EXT2_SUPER_MAGIC 0xEF53
+#ifdef __KERNEL__
+#include <linux/ext2_fs_sb.h>
+static inline struct ext2_sb_info *EXT2_SB(struct super_block *sb)
+{
+ return sb->s_fs_info;
+}
+#elif defined(_KERNEL)
/*
- * Maximal count of links to a file
+ * FreeBSD passes the pointer to the in-core struct with relevant
+ * fields to EXT2_SB macro when accessing superblock fields.
*/
-#define EXT2_LINK_MAX 32000
+#define EXT2_SB(sb) (sb)
+#else
+/* Assume that user mode programs are passing in an ext2fs superblock, not
+ * a kernel struct super_block. This will allow us to call the feature-test
+ * macros from user land. */
+#define EXT2_SB(sb) (sb)
+#endif
/*
- * Note: under FreeBSD, the "user" versions of the following macros are
- * used (and must be used) in most cases, because ((s)->u.ext2_sb.s_es is
- * not accessible. This depends on __KERNEL__ not being defined for
- * kernel builds under FreeBSD.
+ * Maximal count of links to a file
*/
+#define EXT2_LINK_MAX 32000
/*
* Macro-instructions used to manage several block sizes
@@ -122,23 +134,22 @@
#define EXT2_MIN_BLOCK_SIZE 1024
#define EXT2_MAX_BLOCK_SIZE 4096
#define EXT2_MIN_BLOCK_LOG_SIZE 10
-#if defined(__KERNEL__) || (defined(__FreeBSD__) && defined(_KERNEL))
+#if defined(__KERNEL__) || defined(_KERNEL)
# define EXT2_BLOCK_SIZE(s) ((s)->s_blocksize)
#else
# define EXT2_BLOCK_SIZE(s) (EXT2_MIN_BLOCK_SIZE << (s)->s_log_block_size)
#endif
-#define EXT2_ACLE_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_acl_entry))
#define EXT2_ADDR_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (__u32))
-#ifdef __KERNEL__
+#if defined(__KERNEL__) || defined(_KERNEL)
# define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits)
#else
# define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_log_block_size + 10)
#endif
-#ifdef notyet
-#ifdef __KERNEL__
-#define EXT2_ADDR_PER_BLOCK_BITS(s) ((s)->u.ext2_sb.s_addr_per_block_bits)
-#define EXT2_INODE_SIZE(s) ((s)->u.ext2_sb.s_inode_size)
-#define EXT2_FIRST_INO(s) ((s)->u.ext2_sb.s_first_ino)
+#if defined(__KERNEL__) || defined(_KERNEL)
+#define EXT2_ADDR_PER_BLOCK_BITS(s) (EXT2_SB(s)->s_addr_per_block_bits)
+#define EXT2_INODE_SIZE(s) (EXT2_SB(s)->s_inode_size)
+#define EXT2_FIRST_INO(s) (EXT2_SB(s)->s_first_ino)
+#define EXT2_INODES_PER_BLOCK(s) ((s)->s_inodes_per_block)
#else
#define EXT2_INODE_SIZE(s) (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \
EXT2_GOOD_OLD_INODE_SIZE : \
@@ -147,12 +158,6 @@
EXT2_GOOD_OLD_FIRST_INO : \
(s)->s_first_ino)
#endif
-#else /* !notyet */
-#define EXT2_INODES_PER_BLOCK(s) ((s)->s_inodes_per_block)
-/* Should be sizeof(struct ext2_inode): */
-#define EXT2_INODE_SIZE(s) ((s)->s_inode_size)
-#define EXT2_FIRST_INO(s) ((s)->s_first_inode)
-#endif /* notyet */
/*
* Macro-instructions used to manage fragments
@@ -160,15 +165,11 @@
#define EXT2_MIN_FRAG_SIZE 1024
#define EXT2_MAX_FRAG_SIZE 4096
#define EXT2_MIN_FRAG_LOG_SIZE 10
-#ifdef __KERNEL__
-# define EXT2_FRAG_SIZE(s) ((s)->u.ext2_sb.s_frag_size)
-# define EXT2_FRAGS_PER_BLOCK(s) ((s)->u.ext2_sb.s_frags_per_block)
+#if defined(__KERNEL__) || defined(_KERNEL)
+# define EXT2_FRAG_SIZE(s) (EXT2_SB(s)->s_frag_size)
+# define EXT2_FRAGS_PER_BLOCK(s) (EXT2_SB(s)->s_frags_per_block)
#else
-# if defined(_KERNEL) && defined(__FreeBSD__)
-# define EXT2_FRAG_SIZE(s) ((s)->s_frag_size)
-# else
# define EXT2_FRAG_SIZE(s) (EXT2_MIN_FRAG_SIZE << (s)->s_log_frag_size)
-# endif
# define EXT2_FRAGS_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / EXT2_FRAG_SIZE(s))
#endif
@@ -212,11 +213,11 @@ struct ext2_group_desc
/*
* Macro-instructions used to manage group descriptors
*/
-#ifdef __KERNEL__
-# define EXT2_BLOCKS_PER_GROUP(s) ((s)->u.ext2_sb.s_blocks_per_group)
-# define EXT2_DESC_PER_BLOCK(s) ((s)->u.ext2_sb.s_desc_per_block)
-# define EXT2_INODES_PER_GROUP(s) ((s)->u.ext2_sb.s_inodes_per_group)
-# define EXT2_DESC_PER_BLOCK_BITS(s) ((s)->u.ext2_sb.s_desc_per_block_bits)
+#if defined(__KERNEL__) || defined(_KERNEL)
+# define EXT2_BLOCKS_PER_GROUP(s) (EXT2_SB(s)->s_blocks_per_group)
+# define EXT2_DESC_PER_BLOCK(s) (EXT2_SB(s)->s_desc_per_block)
+# define EXT2_INODES_PER_GROUP(s) (EXT2_SB(s)->s_inodes_per_group)
+# define EXT2_DESC_PER_BLOCK_BITS(s) (EXT2_SB(s)->s_desc_per_block_bits)
#else
# define EXT2_BLOCKS_PER_GROUP(s) ((s)->s_blocks_per_group)
# define EXT2_DESC_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc))
@@ -366,7 +367,7 @@ struct ext2_inode {
#define clear_opt(o, opt) o &= ~EXT2_MOUNT_##opt
#define set_opt(o, opt) o |= EXT2_MOUNT_##opt
-#define test_opt(sb, opt) ((sb)->u.ext2_sb.s_mount_opt & \
+#define test_opt(sb, opt) (EXT2_SB(sb)->s_mount_opt & \
EXT2_MOUNT_##opt)
/*
* Maximal mount counts between two filesystem checks
@@ -444,15 +445,6 @@ struct ext2_super_block {
__u32 s_reserved[204]; /* Padding to the end of the block */
};
-#ifdef __KERNEL__
-#define EXT2_SB(sb) (&((sb)->u.ext2_sb))
-#else
-/* Assume that user mode programs are passing in an ext2fs superblock, not
- * a kernel struct super_block. This will allow us to call the feature-test
- * macros from user land. */
-#define EXT2_SB(sb) (sb)
-#endif
-
/*
* Codes for operating systems
*/
@@ -478,11 +470,11 @@ struct ext2_super_block {
*/
#define EXT2_HAS_COMPAT_FEATURE(sb,mask) \
- ( EXT2_SB(sb)->s_feature_compat & (mask) )
+ ( EXT2_SB(sb)->s_es->s_feature_compat & cpu_to_le32(mask) )
#define EXT2_HAS_RO_COMPAT_FEATURE(sb,mask) \
- ( EXT2_SB(sb)->s_feature_ro_compat & (mask) )
+ ( EXT2_SB(sb)->s_es->s_feature_ro_compat & cpu_to_le32(mask) )
#define EXT2_HAS_INCOMPAT_FEATURE(sb,mask) \
- ( EXT2_SB(sb)->s_feature_incompat & (mask) )
+ ( EXT2_SB(sb)->s_es->s_feature_incompat & cpu_to_le32(mask) )
#define EXT2_FEATURE_COMPAT_DIR_PREALLOC 0x0001
diff --git a/sys/gnu/fs/ext2fs/ext2_fs_sb.h b/sys/gnu/fs/ext2fs/ext2_fs_sb.h
index ae5c268..2e3d78f 100644
--- a/sys/gnu/fs/ext2fs/ext2_fs_sb.h
+++ b/sys/gnu/fs/ext2fs/ext2_fs_sb.h
@@ -60,11 +60,9 @@ struct ext2_sb_info {
unsigned long s_blocks_per_group;/* Number of blocks in a group */
unsigned long s_inodes_per_group;/* Number of inodes in a group */
unsigned long s_itb_per_group; /* Number of inode table blocks per group */
- unsigned long s_db_per_group; /* Number of descriptor blocks per group */
+ unsigned long s_gdb_count; /* Number of group descriptor blocks */
unsigned long s_desc_per_block; /* Number of group descriptors per block */
unsigned long s_groups_count; /* Number of groups in the fs */
- unsigned long s_first_inode; /* First inode on fs */
- unsigned int s_inode_size; /* Size for inode with extra data */
struct buffer_head * s_sbh; /* Buffer containing the super block */
struct ext2_super_block * s_es; /* Pointer to the super block in the buffer */
struct buffer_head ** s_group_desc;
@@ -74,10 +72,13 @@ struct ext2_sb_info {
struct buffer_head * s_inode_bitmap[EXT2_MAX_GROUP_LOADED];
unsigned long s_block_bitmap_number[EXT2_MAX_GROUP_LOADED];
struct buffer_head * s_block_bitmap[EXT2_MAX_GROUP_LOADED];
- int s_rename_lock;
unsigned long s_mount_opt;
- unsigned short s_resuid;
- unsigned short s_resgid;
+#ifdef notyet
+ uid_t s_resuid;
+ gid_t s_resgid;
+#endif
+ unsigned short s_inode_size;
+ unsigned int s_first_ino;
unsigned short s_mount_state;
/*
stuff that FFS keeps in its super block or that linux
diff --git a/sys/gnu/fs/ext2fs/ext2_lookup.c b/sys/gnu/fs/ext2fs/ext2_lookup.c
index 7788d58..261d85f 100644
--- a/sys/gnu/fs/ext2fs/ext2_lookup.c
+++ b/sys/gnu/fs/ext2fs/ext2_lookup.c
@@ -46,6 +46,7 @@
#include <sys/namei.h>
#include <sys/bio.h>
#include <sys/buf.h>
+#include <sys/endian.h>
#include <sys/mount.h>
#include <sys/vnode.h>
#include <sys/malloc.h>
@@ -771,7 +772,7 @@ ext2_direnter(ip, dvp, cnp)
dp = VTOI(dvp);
newdir.inode = ip->i_number;
newdir.name_len = cnp->cn_namelen;
- if (EXT2_HAS_INCOMPAT_FEATURE(ip->i_e2fs->s_es,
+ if (EXT2_HAS_INCOMPAT_FEATURE(ip->i_e2fs,
EXT2_FEATURE_INCOMPAT_FILETYPE))
newdir.file_type = DTTOFT(IFTODT(ip->i_mode));
else
@@ -949,7 +950,7 @@ ext2_dirrewrite(dp, ip, cnp)
&bp)) != 0)
return (error);
ep->inode = ip->i_number;
- if (EXT2_HAS_INCOMPAT_FEATURE(ip->i_e2fs->s_es,
+ if (EXT2_HAS_INCOMPAT_FEATURE(ip->i_e2fs,
EXT2_FEATURE_INCOMPAT_FILETYPE))
ep->file_type = DTTOFT(IFTODT(ip->i_mode));
else
diff --git a/sys/gnu/fs/ext2fs/ext2_vfsops.c b/sys/gnu/fs/ext2fs/ext2_vfsops.c
index c8d79fb..6171671 100644
--- a/sys/gnu/fs/ext2fs/ext2_vfsops.c
+++ b/sys/gnu/fs/ext2fs/ext2_vfsops.c
@@ -78,13 +78,13 @@
#include <gnu/fs/ext2fs/fs.h>
#include <gnu/fs/ext2fs/ext2_extern.h>
-#include <gnu/fs/ext2fs/ext2_fs.h>
#include <gnu/fs/ext2fs/ext2_fs_sb.h>
+#include <gnu/fs/ext2fs/ext2_fs.h>
-static int ext2_flushfiles(struct mount *mp, int flags, struct thread *td);
-static int ext2_mountfs(struct vnode *, struct mount *);
-static int ext2_reload(struct mount *mp, struct thread *td);
-static int ext2_sbupdate(struct ext2mount *, int);
+static int ext2_flushfiles(struct mount *mp, int flags, struct thread *td);
+static int ext2_mountfs(struct vnode *, struct mount *);
+static int ext2_reload(struct mount *mp, struct thread *td);
+static int ext2_sbupdate(struct ext2mount *, int);
static vfs_unmount_t ext2_unmount;
static vfs_root_t ext2_root;
@@ -109,9 +109,6 @@ static struct vfsops ext2fs_vfsops = {
VFS_SET(ext2fs_vfsops, ext2fs, 0);
-#define bsd_malloc malloc
-#define bsd_free free
-
static int ext2_check_sb_compat(struct ext2_super_block *es, struct cdev *dev,
int ronly);
static int compute_sb_data(struct vnode * devvp,
@@ -127,18 +124,17 @@ static const char *ext2_opts[] = { "from", "export", "acls", "noexec",
* mount system call
*/
static int
-ext2_mount(mp)
- struct mount *mp;
+ext2_mount(struct mount *mp)
{
struct vfsoptlist *opts;
struct vnode *devvp;
struct thread *td;
struct ext2mount *ump = 0;
struct ext2_sb_info *fs;
+ struct nameidata nd, *ndp = &nd;
+ accmode_t accmode;
char *path, *fspec;
int error, flags, len;
- accmode_t accmode;
- struct nameidata nd, *ndp = &nd;
td = curthread;
opts = mp->mnt_optnew;
@@ -196,6 +192,7 @@ ext2_mount(mp)
if (fs->s_rd_only && !vfs_flagopt(opts, "ro", NULL, 0)) {
if (ext2_check_sb_compat(fs->s_es, devvp->v_rdev, 0))
return (EPERM);
+
/*
* If upgrade to read-write by non-root, then verify
* that user has necessary permissions on the device.
@@ -221,13 +218,12 @@ ext2_mount(mp)
if ((fs->s_es->s_state & EXT2_VALID_FS) == 0 ||
(fs->s_es->s_state & EXT2_ERROR_FS)) {
if (mp->mnt_flag & MNT_FORCE) {
- printf(
-"WARNING: %s was not properly dismounted\n",
- fs->fs_fsmnt);
+ printf("WARNING: %s was not properly "
+ "dismounted\n", fs->fs_fsmnt);
} else {
- printf(
-"WARNING: R/W mount of %s denied. Filesystem is not clean - run fsck\n",
- fs->fs_fsmnt);
+ printf("WARNING: R/W mount of %s "
+ "denied. Filesystem is not clean"
+ " - run fsck\n", fs->fs_fsmnt);
return (EPERM);
}
}
@@ -243,6 +239,7 @@ ext2_mount(mp)
return (error);
}
}
+
/*
* Not an update, or updating the name: look up the name
* and verify that it refers to a sensible disk device.
@@ -292,6 +289,7 @@ ext2_mount(mp)
}
ump = VFSTOEXT2(mp);
fs = ump->um_e2fs;
+
/*
* Note that this strncpy() is ok because of a check at the start
* of ext2_mount().
@@ -303,63 +301,55 @@ ext2_mount(mp)
}
/*
- * checks that the data in the descriptor blocks make sense
- * this is taken from ext2/super.c
+ * Checks that the data in the descriptor blocks make sense
+ * this is taken from ext2/super.c.
*/
-static int ext2_check_descriptors (struct ext2_sb_info * sb)
+static int
+ext2_check_descriptors(struct ext2_sb_info *sb)
{
- int i;
- int desc_block = 0;
- unsigned long block = sb->s_es->s_first_data_block;
- struct ext2_group_desc * gdp = NULL;
+ struct ext2_group_desc *gdp = NULL;
+ unsigned long block = sb->s_es->s_first_data_block;
+ int desc_block = 0;
+ int i;
- /* ext2_debug ("Checking group descriptors"); */
-
- for (i = 0; i < sb->s_groups_count; i++)
- {
+ for (i = 0; i < sb->s_groups_count; i++) {
/* examine next descriptor block */
- if ((i % EXT2_DESC_PER_BLOCK(sb)) == 0)
- gdp = (struct ext2_group_desc *)
- sb->s_group_desc[desc_block++]->b_data;
- if (gdp->bg_block_bitmap < block ||
- gdp->bg_block_bitmap >= block + EXT2_BLOCKS_PER_GROUP(sb))
- {
- printf ("ext2_check_descriptors: "
- "Block bitmap for group %d"
- " not in group (block %lu)!\n",
- i, (unsigned long) gdp->bg_block_bitmap);
- return 0;
- }
- if (gdp->bg_inode_bitmap < block ||
- gdp->bg_inode_bitmap >= block + EXT2_BLOCKS_PER_GROUP(sb))
- {
- printf ("ext2_check_descriptors: "
- "Inode bitmap for group %d"
- " not in group (block %lu)!\n",
- i, (unsigned long) gdp->bg_inode_bitmap);
- return 0;
- }
- if (gdp->bg_inode_table < block ||
- gdp->bg_inode_table + sb->s_itb_per_group >=
- block + EXT2_BLOCKS_PER_GROUP(sb))
- {
- printf ("ext2_check_descriptors: "
- "Inode table for group %d"
- " not in group (block %lu)!\n",
- i, (unsigned long) gdp->bg_inode_table);
- return 0;
- }
- block += EXT2_BLOCKS_PER_GROUP(sb);
- gdp++;
- }
- return 1;
+ if ((i % EXT2_DESC_PER_BLOCK(sb)) == 0)
+ gdp = (struct ext2_group_desc *)
+ sb->s_group_desc[desc_block++]->b_data;
+ if (gdp->bg_block_bitmap < block ||
+ gdp->bg_block_bitmap >= block + EXT2_BLOCKS_PER_GROUP(sb)) {
+ printf ("ext2_check_descriptors: "
+ "Block bitmap for group %d"
+ " not in group (block %lu)!\n",
+ i, (unsigned long) gdp->bg_block_bitmap);
+ return (0);
+ }
+ if (gdp->bg_inode_bitmap < block ||
+ gdp->bg_inode_bitmap >= block + EXT2_BLOCKS_PER_GROUP(sb)) {
+ printf ("ext2_check_descriptors: "
+ "Inode bitmap for group %d"
+ " not in group (block %lu)!\n",
+ i, (unsigned long) gdp->bg_inode_bitmap);
+ return (0);
+ }
+ if (gdp->bg_inode_table < block ||
+ gdp->bg_inode_table + sb->s_itb_per_group >=
+ block + EXT2_BLOCKS_PER_GROUP(sb)) {
+ printf ("ext2_check_descriptors: "
+ "Inode table for group %d"
+ " not in group (block %lu)!\n",
+ i, (unsigned long) gdp->bg_inode_table);
+ return (0);
+ }
+ block += EXT2_BLOCKS_PER_GROUP(sb);
+ gdp++;
+ }
+ return (1);
}
static int
-ext2_check_sb_compat(es, dev, ronly)
- struct ext2_super_block *es;
- struct cdev *dev;
- int ronly;
+ext2_check_sb_compat(struct ext2_super_block *es, struct cdev *dev, int ronly)
{
if (es->s_magic != EXT2_SUPER_MAGIC) {
@@ -369,16 +359,14 @@ ext2_check_sb_compat(es, dev, ronly)
}
if (es->s_rev_level > EXT2_GOOD_OLD_REV) {
if (es->s_feature_incompat & ~EXT2_FEATURE_INCOMPAT_SUPP) {
- printf(
-"WARNING: mount of %s denied due to unsupported optional features\n",
- devtoname(dev));
+ printf("WARNING: mount of %s denied due to unsupported "
+ "optional features\n", devtoname(dev));
return (1);
}
if (!ronly &&
(es->s_feature_ro_compat & ~EXT2_FEATURE_RO_COMPAT_SUPP)) {
- printf(
-"WARNING: R/W mount of %s denied due to unsupported optional features\n",
- devtoname(dev));
+ printf("WARNING: R/W mount of %s denied due to "
+ "unsupported optional features\n", devtoname(dev));
return (1);
}
}
@@ -386,111 +374,101 @@ ext2_check_sb_compat(es, dev, ronly)
}
/*
- * this computes the fields of the ext2_sb_info structure from the
- * data in the ext2_super_block structure read in
+ * This computes the fields of the ext2_sb_info structure from the
+ * data in the ext2_super_block structure read in.
*/
-static int compute_sb_data(devvp, es, fs)
- struct vnode * devvp;
- struct ext2_super_block * es;
- struct ext2_sb_info * fs;
+static int
+compute_sb_data(struct vnode *devvp, struct ext2_super_block *es,
+ struct ext2_sb_info *fs)
{
- int db_count, error;
- int i, j;
- int logic_sb_block = 1; /* XXX for now */
-
-#if 1
-#define V(v)
-#else
-#define V(v) printf(#v"= %lu\n", (unsigned long)fs->v);
-#endif
+ int db_count, error;
+ int i, j;
+ int logic_sb_block = 1; /* XXX for now */
+
+ fs->s_blocksize = EXT2_MIN_BLOCK_SIZE << es->s_log_block_size;
+ fs->s_bshift = EXT2_MIN_BLOCK_LOG_SIZE + es->s_log_block_size;
+ fs->s_fsbtodb = es->s_log_block_size + 1;
+ fs->s_qbmask = fs->s_blocksize - 1;
+ fs->s_blocksize_bits = es->s_log_block_size + 10;
+ fs->s_frag_size = EXT2_MIN_FRAG_SIZE << es->s_log_frag_size;
+ if (fs->s_frag_size)
+ fs->s_frags_per_block = fs->s_blocksize / fs->s_frag_size;
+ fs->s_blocks_per_group = es->s_blocks_per_group;
+ fs->s_frags_per_group = es->s_frags_per_group;
+ fs->s_inodes_per_group = es->s_inodes_per_group;
+ if (es->s_rev_level == EXT2_GOOD_OLD_REV) {
+ fs->s_first_ino = EXT2_GOOD_OLD_FIRST_INO;
+ fs->s_inode_size = EXT2_GOOD_OLD_INODE_SIZE;
+ } else {
+ fs->s_first_ino = es->s_first_ino;
+ fs->s_inode_size = es->s_inode_size;
- fs->s_blocksize = EXT2_MIN_BLOCK_SIZE << es->s_log_block_size;
- V(s_blocksize)
- fs->s_bshift = EXT2_MIN_BLOCK_LOG_SIZE + es->s_log_block_size;
- V(s_bshift)
- fs->s_fsbtodb = es->s_log_block_size + 1;
- V(s_fsbtodb)
- fs->s_qbmask = fs->s_blocksize - 1;
- V(s_qbmask)
- fs->s_blocksize_bits = EXT2_BLOCK_SIZE_BITS(es);
- V(s_blocksize_bits)
- fs->s_frag_size = EXT2_MIN_FRAG_SIZE << es->s_log_frag_size;
- V(s_frag_size)
- if (fs->s_frag_size)
- fs->s_frags_per_block = fs->s_blocksize / fs->s_frag_size;
- V(s_frags_per_block)
- fs->s_blocks_per_group = es->s_blocks_per_group;
- V(s_blocks_per_group)
- fs->s_frags_per_group = es->s_frags_per_group;
- V(s_frags_per_group)
- fs->s_inodes_per_group = es->s_inodes_per_group;
- V(s_inodes_per_group)
- fs->s_inode_size = es->s_inode_size;
- V(s_inode_size)
- fs->s_first_inode = es->s_first_ino;
- V(s_first_inode);
- fs->s_inodes_per_block = fs->s_blocksize / EXT2_INODE_SIZE(fs);
- V(s_inodes_per_block)
- fs->s_itb_per_group = fs->s_inodes_per_group /fs->s_inodes_per_block;
- V(s_itb_per_group)
- fs->s_desc_per_block = fs->s_blocksize / sizeof (struct ext2_group_desc);
- V(s_desc_per_block)
- /* s_resuid / s_resgid ? */
- fs->s_groups_count = (es->s_blocks_count -
- es->s_first_data_block +
- EXT2_BLOCKS_PER_GROUP(fs) - 1) /
- EXT2_BLOCKS_PER_GROUP(fs);
- V(s_groups_count)
- db_count = (fs->s_groups_count + EXT2_DESC_PER_BLOCK(fs) - 1) /
- EXT2_DESC_PER_BLOCK(fs);
- fs->s_db_per_group = db_count;
- V(s_db_per_group)
-
- fs->s_group_desc = bsd_malloc(db_count * sizeof (struct buf *),
- M_EXT2MNT, M_WAITOK);
+ /*
+ * Simple sanity check for superblock inode size value.
+ */
+ if (fs->s_inode_size < EXT2_GOOD_OLD_INODE_SIZE ||
+ fs->s_inode_size > fs->s_blocksize ||
+ (fs->s_inode_size & (fs->s_inode_size - 1)) != 0) {
+ printf("EXT2-fs: invalid inode size %d\n",
+ fs->s_inode_size);
+ return (EIO);
+ }
+ }
+ fs->s_inodes_per_block = fs->s_blocksize / EXT2_INODE_SIZE(fs);
+ fs->s_itb_per_group = fs->s_inodes_per_group /fs->s_inodes_per_block;
+ fs->s_desc_per_block = fs->s_blocksize / sizeof (struct ext2_group_desc);
+ /* s_resuid / s_resgid ? */
+ fs->s_groups_count = (es->s_blocks_count - es->s_first_data_block +
+ EXT2_BLOCKS_PER_GROUP(fs) - 1) / EXT2_BLOCKS_PER_GROUP(fs);
+ db_count = (fs->s_groups_count + EXT2_DESC_PER_BLOCK(fs) - 1) /
+ EXT2_DESC_PER_BLOCK(fs);
+ fs->s_gdb_count = db_count;
+ fs->s_group_desc = malloc(db_count * sizeof (struct buf *),
+ M_EXT2MNT, M_WAITOK);
- /* adjust logic_sb_block */
- if(fs->s_blocksize > SBSIZE)
- /* Godmar thinks: if the blocksize is greater than 1024, then
- the superblock is logically part of block zero.
+ /*
+ * Adjust logic_sb_block.
+ * Godmar thinks: if the blocksize is greater than 1024, then
+ * the superblock is logically part of block zero.
*/
- logic_sb_block = 0;
-
- for (i = 0; i < db_count; i++) {
- error = bread(devvp , fsbtodb(fs, logic_sb_block + i + 1),
- fs->s_blocksize, NOCRED, &fs->s_group_desc[i]);
- if(error) {
- for (j = 0; j < i; j++)
- brelse(fs->s_group_desc[j]);
- bsd_free(fs->s_group_desc, M_EXT2MNT);
- printf("EXT2-fs: unable to read group descriptors (%d)\n", error);
- return EIO;
+ if(fs->s_blocksize > SBSIZE)
+ logic_sb_block = 0;
+
+ for (i = 0; i < db_count; i++) {
+ error = bread(devvp , fsbtodb(fs, logic_sb_block + i + 1),
+ fs->s_blocksize, NOCRED, &fs->s_group_desc[i]);
+ if(error) {
+ for (j = 0; j < i; j++)
+ brelse(fs->s_group_desc[j]);
+ free(fs->s_group_desc, M_EXT2MNT);
+ printf("EXT2-fs: unable to read group descriptors"
+ " (%d)\n", error);
+ return (EIO);
+ }
+ LCK_BUF(fs->s_group_desc[i])
}
- LCK_BUF(fs->s_group_desc[i])
- }
- if(!ext2_check_descriptors(fs)) {
- for (j = 0; j < db_count; j++)
- ULCK_BUF(fs->s_group_desc[j])
- bsd_free(fs->s_group_desc, M_EXT2MNT);
- printf("EXT2-fs: (ext2_check_descriptors failure) "
- "unable to read group descriptors\n");
- return EIO;
- }
-
- for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) {
- fs->s_inode_bitmap_number[i] = 0;
- fs->s_inode_bitmap[i] = NULL;
- fs->s_block_bitmap_number[i] = 0;
- fs->s_block_bitmap[i] = NULL;
- }
- fs->s_loaded_inode_bitmaps = 0;
- fs->s_loaded_block_bitmaps = 0;
- if (es->s_rev_level == EXT2_GOOD_OLD_REV || (es->s_feature_ro_compat &
- EXT2_FEATURE_RO_COMPAT_LARGE_FILE) == 0)
- fs->fs_maxfilesize = 0x7fffffff;
- else
- fs->fs_maxfilesize = 0x7fffffffffffffff;
- return 0;
+ if(!ext2_check_descriptors(fs)) {
+ for (j = 0; j < db_count; j++)
+ ULCK_BUF(fs->s_group_desc[j])
+ free(fs->s_group_desc, M_EXT2MNT);
+ printf("EXT2-fs: (ext2_check_descriptors failure) "
+ "unable to read group descriptors\n");
+ return (EIO);
+ }
+ for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) {
+ fs->s_inode_bitmap_number[i] = 0;
+ fs->s_inode_bitmap[i] = NULL;
+ fs->s_block_bitmap_number[i] = 0;
+ fs->s_block_bitmap[i] = NULL;
+ }
+ fs->s_loaded_inode_bitmaps = 0;
+ fs->s_loaded_block_bitmaps = 0;
+ if (es->s_rev_level == EXT2_GOOD_OLD_REV ||
+ (es->s_feature_ro_compat & EXT2_FEATURE_RO_COMPAT_LARGE_FILE) == 0)
+ fs->fs_maxfilesize = 0x7fffffff;
+ else
+ fs->fs_maxfilesize = 0x7fffffffffffffff;
+ return (0);
}
/*
@@ -512,7 +490,7 @@ ext2_reload(struct mount *mp, struct thread *td)
struct vnode *vp, *mvp, *devvp;
struct inode *ip;
struct buf *bp;
- struct ext2_super_block * es;
+ struct ext2_super_block *es;
struct ext2_sb_info *fs;
int error;
@@ -543,7 +521,7 @@ ext2_reload(struct mount *mp, struct thread *td)
if((error = compute_sb_data(devvp, es, fs)) != 0) {
brelse(bp);
- return error;
+ return (error);
}
#ifdef UNKLAR
if (fs->fs_sbsize < SBSIZE)
@@ -569,12 +547,12 @@ loop:
}
if (vinvalbuf(vp, 0, 0, 0))
panic("ext2_reload: dirty2");
+
/*
* Step 5: re-read inode data for all active vnodes.
*/
ip = VTOI(vp);
- error =
- bread(devvp, fsbtodb(fs, ino_to_fsba(fs, ip->i_number)),
+ error = bread(devvp, fsbtodb(fs, ino_to_fsba(fs, ip->i_number)),
(int)fs->s_blocksize, NOCRED, &bp);
if (error) {
VOP_UNLOCK(vp, 0);
@@ -594,17 +572,15 @@ loop:
}
/*
- * Common code for mount and mountroot
+ * Common code for mount and mountroot.
*/
static int
-ext2_mountfs(devvp, mp)
- struct vnode *devvp;
- struct mount *mp;
+ext2_mountfs(struct vnode *devvp, struct mount *mp)
{
struct ext2mount *ump;
struct buf *bp;
struct ext2_sb_info *fs;
- struct ext2_super_block * es;
+ struct ext2_super_block *es;
struct cdev *dev = devvp->v_rdev;
struct g_consumer *cp;
struct bufobj *bo;
@@ -653,28 +629,31 @@ ext2_mountfs(devvp, mp)
if ((es->s_state & EXT2_VALID_FS) == 0 ||
(es->s_state & EXT2_ERROR_FS)) {
if (ronly || (mp->mnt_flag & MNT_FORCE)) {
- printf(
-"WARNING: Filesystem was not properly dismounted\n");
+ printf("WARNING: Filesystem was not properly "
+ "dismounted\n");
} else {
- printf(
-"WARNING: R/W mount denied. Filesystem is not clean - run fsck\n");
+ printf("WARNING: R/W mount denied. Filesystem "
+ "is not clean - run fsck\n");
error = EPERM;
goto out;
}
}
- ump = bsd_malloc(sizeof *ump, M_EXT2MNT, M_WAITOK);
+ ump = malloc(sizeof *ump, M_EXT2MNT, M_WAITOK);
bzero((caddr_t)ump, sizeof *ump);
- /* I don't know whether this is the right strategy. Note that
- we dynamically allocate both an ext2_sb_info and an ext2_super_block
- while Linux keeps the super block in a locked buffer
+
+ /*
+ * I don't know whether this is the right strategy. Note that
+ * we dynamically allocate both an ext2_sb_info and an ext2_super_block
+ * while Linux keeps the super block in a locked buffer.
*/
- ump->um_e2fs = bsd_malloc(sizeof(struct ext2_sb_info),
+ ump->um_e2fs = malloc(sizeof(struct ext2_sb_info),
M_EXT2MNT, M_WAITOK);
- ump->um_e2fs->s_es = bsd_malloc(sizeof(struct ext2_super_block),
+ ump->um_e2fs->s_es = malloc(sizeof(struct ext2_super_block),
M_EXT2MNT, M_WAITOK);
bcopy(es, ump->um_e2fs->s_es, (u_int)sizeof(struct ext2_super_block));
if ((error = compute_sb_data(devvp, ump->um_e2fs->s_es, ump->um_e2fs)))
goto out;
+
/*
* We don't free the group descriptors allocated by compute_sb_data()
* until ext2_unmount(). This is OK since the mount will succeed.
@@ -683,8 +662,10 @@ ext2_mountfs(devvp, mp)
bp = NULL;
fs = ump->um_e2fs;
fs->s_rd_only = ronly; /* ronly is set according to mnt_flags */
- /* if the fs is not mounted read-only, make sure the super block is
- always written back on a sync()
+
+ /*
+ * If the fs is not mounted read-only, make sure the super block is
+ * always written back on a sync().
*/
fs->s_wasvalid = fs->s_es->s_state & EXT2_VALID_FS ? 1 : 0;
if (ronly == 0) {
@@ -703,9 +684,11 @@ ext2_mountfs(devvp, mp)
ump->um_devvp = devvp;
ump->um_bo = &devvp->v_bufobj;
ump->um_cp = cp;
- /* setting those two parameters allowed us to use
- ufs_bmap w/o changse !
- */
+
+ /*
+ * Setting those two parameters allowed us to use
+ * ufs_bmap w/o changse!
+ */
ump->um_nindir = EXT2_ADDR_PER_BLOCK(fs);
ump->um_bptrtodb = fs->s_es->s_log_block_size + 1;
ump->um_seqinc = EXT2_FRAGS_PER_BLOCK(fs);
@@ -723,21 +706,19 @@ out:
PICKUP_GIANT();
}
if (ump) {
- bsd_free(ump->um_e2fs->s_es, M_EXT2MNT);
- bsd_free(ump->um_e2fs, M_EXT2MNT);
- bsd_free(ump, M_EXT2MNT);
+ free(ump->um_e2fs->s_es, M_EXT2MNT);
+ free(ump->um_e2fs, M_EXT2MNT);
+ free(ump, M_EXT2MNT);
mp->mnt_data = NULL;
}
return (error);
}
/*
- * unmount system call
+ * Unmount system call.
*/
static int
-ext2_unmount(mp, mntflags)
- struct mount *mp;
- int mntflags;
+ext2_unmount(struct mount *mp, int mntflags)
{
struct ext2mount *ump;
struct ext2_sb_info *fs;
@@ -761,18 +742,17 @@ ext2_unmount(mp, mntflags)
}
/* release buffers containing group descriptors */
- for(i = 0; i < fs->s_db_per_group; i++)
+ for(i = 0; i < fs->s_gdb_count; i++)
ULCK_BUF(fs->s_group_desc[i])
- bsd_free(fs->s_group_desc, M_EXT2MNT);
+ free(fs->s_group_desc, M_EXT2MNT);
/* release cached inode/block bitmaps */
- for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++)
- if (fs->s_inode_bitmap[i])
- ULCK_BUF(fs->s_inode_bitmap[i])
-
- for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++)
- if (fs->s_block_bitmap[i])
- ULCK_BUF(fs->s_block_bitmap[i])
+ for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++)
+ if (fs->s_inode_bitmap[i])
+ ULCK_BUF(fs->s_inode_bitmap[i])
+ for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++)
+ if (fs->s_block_bitmap[i])
+ ULCK_BUF(fs->s_block_bitmap[i])
DROP_GIANT();
g_topology_lock();
@@ -780,9 +760,9 @@ ext2_unmount(mp, mntflags)
g_topology_unlock();
PICKUP_GIANT();
vrele(ump->um_devvp);
- bsd_free(fs->s_es, M_EXT2MNT);
- bsd_free(fs, M_EXT2MNT);
- bsd_free(ump, M_EXT2MNT);
+ free(fs->s_es, M_EXT2MNT);
+ free(fs, M_EXT2MNT);
+ free(ump, M_EXT2MNT);
mp->mnt_data = NULL;
MNT_ILOCK(mp);
mp->mnt_flag &= ~MNT_LOCAL;
@@ -794,10 +774,7 @@ ext2_unmount(mp, mntflags)
* Flush out all the files in a filesystem.
*/
static int
-ext2_flushfiles(mp, flags, td)
- struct mount *mp;
- int flags;
- struct thread *td;
+ext2_flushfiles(struct mount *mp, int flags, struct thread *td)
{
int error;
@@ -807,17 +784,15 @@ ext2_flushfiles(mp, flags, td)
/*
* Get file system statistics.
- * taken from ext2/super.c ext2_statfs
+ * taken from ext2/super.c ext2_statfs.
*/
static int
-ext2_statfs(mp, sbp)
- struct mount *mp;
- struct statfs *sbp;
+ext2_statfs(struct mount *mp, struct statfs *sbp)
{
- unsigned long overhead;
struct ext2mount *ump;
struct ext2_sb_info *fs;
struct ext2_super_block *es;
+ unsigned long overhead;
int i, nsb;
ump = VFSTOEXT2(mp);
@@ -838,10 +813,10 @@ ext2_statfs(mp, sbp)
} else
nsb = fs->s_groups_count;
overhead = es->s_first_data_block +
- /* Superblocks and block group descriptors: */
- nsb * (1 + fs->s_db_per_group) +
- /* Inode bitmap, block bitmap, and inode table: */
- fs->s_groups_count * (1 + 1 + fs->s_itb_per_group);
+ /* Superblocks and block group descriptors: */
+ nsb * (1 + fs->s_gdb_count) +
+ /* Inode bitmap, block bitmap, and inode table: */
+ fs->s_groups_count * (1 + 1 + fs->s_itb_per_group);
sbp->f_bsize = EXT2_FRAG_SIZE(fs);
sbp->f_iosize = EXT2_BLOCK_SIZE(fs);
@@ -861,9 +836,7 @@ ext2_statfs(mp, sbp)
* Note: we are always called with the filesystem marked `MPBUSY'.
*/
static int
-ext2_sync(mp, waitfor)
- struct mount *mp;
- int waitfor;
+ext2_sync(struct mount *mp, int waitfor)
{
struct vnode *mvp, *vp;
struct thread *td;
@@ -878,6 +851,7 @@ ext2_sync(mp, waitfor)
printf("fs = %s\n", fs->fs_fsmnt);
panic("ext2_sync: rofs mod");
}
+
/*
* Write back each (modified) inode.
*/
@@ -915,6 +889,7 @@ loop:
MNT_ILOCK(mp);
}
MNT_IUNLOCK(mp);
+
/*
* Force stale file system control information to be flushed.
*/
@@ -924,6 +899,7 @@ loop:
allerror = error;
VOP_UNLOCK(ump->um_devvp, 0);
}
+
/*
* Write back modified superblock.
*/
@@ -943,11 +919,7 @@ loop:
* done by the calling routine.
*/
static int
-ext2_vget(mp, ino, flags, vpp)
- struct mount *mp;
- ino_t ino;
- int flags;
- struct vnode **vpp;
+ext2_vget(struct mount *mp, ino_t ino, int flags, struct vnode **vpp)
{
struct ext2_sb_info *fs;
struct inode *ip;
@@ -955,9 +927,9 @@ ext2_vget(mp, ino, flags, vpp)
struct buf *bp;
struct vnode *vp;
struct cdev *dev;
+ struct thread *td;
int i, error;
int used_blocks;
- struct thread *td;
td = curthread;
error = vfs_hash_get(mp, ino, flags, td, vpp, NULL, NULL);
@@ -999,9 +971,6 @@ ext2_vget(mp, ino, flags, vpp)
return (error);
/* Read in the disk contents for the inode, copy into the inode. */
-#if 0
-printf("ext2_vget(%d) dbn= %lu ", ino, fsbtodb(fs, ino_to_fsba(fs, ino)));
-#endif
if ((error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ino)),
(int)fs->s_blocksize, NOCRED, &bp)) != 0) {
/*
@@ -1023,10 +992,12 @@ printf("ext2_vget(%d) dbn= %lu ", ino, fsbtodb(fs, ino_to_fsba(fs, ino)));
ip->i_next_alloc_goal = 0;
ip->i_prealloc_count = 0;
ip->i_prealloc_block = 0;
- /* now we want to make sure that block pointers for unused
- blocks are zeroed out - ext2_balloc depends on this
- although for regular files and directories only
- */
+
+ /*
+ * Now we want to make sure that block pointers for unused
+ * blocks are zeroed out - ext2_balloc depends on this
+ * although for regular files and directories only
+ */
if(S_ISDIR(ip->i_mode) || S_ISREG(ip->i_mode)) {
used_blocks = (ip->i_size+fs->s_blocksize-1) / fs->s_blocksize;
for(i = used_blocks; i < EXT2_NDIR_BLOCKS; i++)
@@ -1046,10 +1017,12 @@ printf("ext2_vget(%d) dbn= %lu ", ino, fsbtodb(fs, ino_to_fsba(fs, ino)));
*vpp = NULL;
return (error);
}
+
/*
* Finish inode initialization now that aliasing has been resolved.
*/
ip->i_devvp = ump->um_devvp;
+
/*
* Set up a generation number for this inode if it does not
* already have one. This should only happen on old filesystems.
@@ -1074,10 +1047,7 @@ printf("ext2_vget(%d) dbn= %lu ", ino, fsbtodb(fs, ino_to_fsba(fs, ino)));
* those rights via. exflagsp and credanonp
*/
static int
-ext2_fhtovp(mp, fhp, vpp)
- struct mount *mp;
- struct fid *fhp;
- struct vnode **vpp;
+ext2_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp)
{
struct inode *ip;
struct ufid *ufhp;
@@ -1112,17 +1082,13 @@ ext2_fhtovp(mp, fhp, vpp)
* Write a superblock and associated information back to disk.
*/
static int
-ext2_sbupdate(mp, waitfor)
- struct ext2mount *mp;
- int waitfor;
+ext2_sbupdate(struct ext2mount *mp, int waitfor)
{
struct ext2_sb_info *fs = mp->um_e2fs;
struct ext2_super_block *es = fs->s_es;
struct buf *bp;
int error = 0;
-/*
-printf("\nupdating superblock, waitfor=%s\n", waitfor == MNT_WAIT ? "yes":"no");
-*/
+
bp = getblk(mp->um_devvp, SBLOCK, SBSIZE, 0, 0, 0);
bcopy((caddr_t)es, bp->b_data, (u_int)sizeof(struct ext2_super_block));
if (waitfor == MNT_WAIT)
@@ -1133,9 +1099,8 @@ printf("\nupdating superblock, waitfor=%s\n", waitfor == MNT_WAIT ? "yes":"no");
/*
* The buffers for group descriptors, inode bitmaps and block bitmaps
* are not busy at this point and are (hopefully) written by the
- * usual sync mechanism. No need to write them here
- */
-
+ * usual sync mechanism. No need to write them here.
+ */
return (error);
}
@@ -1143,10 +1108,7 @@ printf("\nupdating superblock, waitfor=%s\n", waitfor == MNT_WAIT ? "yes":"no");
* Return the root of a filesystem.
*/
static int
-ext2_root(mp, flags, vpp)
- struct mount *mp;
- int flags;
- struct vnode **vpp;
+ext2_root(struct mount *mp, int flags, struct vnode **vpp)
{
struct vnode *nvp;
int error;
diff --git a/sys/gnu/fs/ext2fs/ext2_vnops.c b/sys/gnu/fs/ext2fs/ext2_vnops.c
index 1b5023c..248c433 100644
--- a/sys/gnu/fs/ext2fs/ext2_vnops.c
+++ b/sys/gnu/fs/ext2fs/ext2_vnops.c
@@ -52,6 +52,7 @@
#include <sys/stat.h>
#include <sys/bio.h>
#include <sys/buf.h>
+#include <sys/endian.h>
#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/mount.h>
@@ -1185,7 +1186,7 @@ ext2_mkdir(ap)
goto bad;
/* Initialize directory with "." and ".." from static template. */
- if (EXT2_HAS_INCOMPAT_FEATURE(ip->i_e2fs->s_es,
+ if (EXT2_HAS_INCOMPAT_FEATURE(ip->i_e2fs,
EXT2_FEATURE_INCOMPAT_FILETYPE))
dtp = &mastertemplate;
else
diff --git a/sys/gnu/fs/ext2fs/sparc64-bitops.h b/sys/gnu/fs/ext2fs/sparc64-bitops.h
deleted file mode 100644
index 26cb578..0000000
--- a/sys/gnu/fs/ext2fs/sparc64-bitops.h
+++ /dev/null
@@ -1,264 +0,0 @@
-/*-
- * $Id: bitops.h,v 1.31 2000/09/23 02:09:21 davem Exp $
- * bitops.h: Bit string operations on the V9.
- *
- * Copyright 1996, 1997 David S. Miller (davem@caip.rutgers.edu)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-/* $FreeBSD$ */
-#ifndef _SPARC64_BITOPS_H
-#define _SPARC64_BITOPS_H
-
-#include <asm/byteorder.h>
-
-extern long __test_and_set_bit(unsigned long nr, volatile void *addr);
-extern long __test_and_clear_bit(unsigned long nr, volatile void *addr);
-extern long __test_and_change_bit(unsigned long nr, volatile void *addr);
-
-#define test_and_set_bit(nr,addr) (__test_and_set_bit(nr,addr)!=0)
-#define test_and_clear_bit(nr,addr) (__test_and_clear_bit(nr,addr)!=0)
-#define test_and_change_bit(nr,addr) (__test_and_change_bit(nr,addr)!=0)
-#define set_bit(nr,addr) ((void)__test_and_set_bit(nr,addr))
-#define clear_bit(nr,addr) ((void)__test_and_clear_bit(nr,addr))
-#define change_bit(nr,addr) ((void)__test_and_change_bit(nr,addr))
-
-#define smp_mb__before_clear_bit() do { } while(0)
-#define smp_mb__after_clear_bit() do { } while(0)
-
-extern __inline__ int test_bit(int nr, __const__ void *addr)
-{
- return (1UL & (((__const__ long *) addr)[nr >> 6] >> (nr & 63))) != 0UL;
-}
-
-/* The easy/cheese version for now. */
-extern __inline__ unsigned long ffz(unsigned long word)
-{
- unsigned long result;
-
-#ifdef ULTRA_HAS_POPULATION_COUNT /* Thanks for nothing Sun... */
- __asm__ __volatile__("
- brz,pn %0, 1f
- neg %0, %%g1
- xnor %0, %%g1, %%g2
- popc %%g2, %0
-1: " : "=&r" (result)
- : "0" (word)
- : "g1", "g2");
-#else
-#if 1 /* def EASY_CHEESE_VERSION */
- result = 0;
- while(word & 1) {
- result++;
- word >>= 1;
- }
-#else
- unsigned long tmp;
-
- result = 0;
- tmp = ~word & -~word;
- if (!(unsigned)tmp) {
- tmp >>= 32;
- result = 32;
- }
- if (!(unsigned short)tmp) {
- tmp >>= 16;
- result += 16;
- }
- if (!(unsigned char)tmp) {
- tmp >>= 8;
- result += 8;
- }
- if (tmp & 0xf0) result += 4;
- if (tmp & 0xcc) result += 2;
- if (tmp & 0xaa) result ++;
-#endif
-#endif
- return result;
-}
-
-#ifdef __KERNEL__
-
-/*
- * ffs: find first bit set. This is defined the same way as
- * the libc and compiler builtin ffs routines, therefore
- * differs in spirit from the above ffz (man ffs).
- */
-
-#define ffs(x) generic_ffs(x)
-
-/*
- * hweightN: returns the hamming weight (i.e. the number
- * of bits set) of a N-bit word
- */
-
-#ifdef ULTRA_HAS_POPULATION_COUNT
-
-extern __inline__ unsigned int hweight32(unsigned int w)
-{
- unsigned int res;
-
- __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xffffffff));
- return res;
-}
-
-extern __inline__ unsigned int hweight16(unsigned int w)
-{
- unsigned int res;
-
- __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xffff));
- return res;
-}
-
-extern __inline__ unsigned int hweight8(unsigned int w)
-{
- unsigned int res;
-
- __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xff));
- return res;
-}
-
-#else
-
-#define hweight32(x) generic_hweight32(x)
-#define hweight16(x) generic_hweight16(x)
-#define hweight8(x) generic_hweight8(x)
-
-#endif
-#endif /* __KERNEL__ */
-
-/* find_next_zero_bit() finds the first zero bit in a bit string of length
- * 'size' bits, starting the search at bit 'offset'. This is largely based
- * on Linus's ALPHA routines, which are pretty portable BTW.
- */
-
-extern __inline__ unsigned long find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
-{
- unsigned long *p = ((unsigned long *) addr) + (offset >> 6);
- unsigned long result = offset & ~63UL;
- unsigned long tmp;
-
- if (offset >= size)
- return size;
- size -= result;
- offset &= 63UL;
- if (offset) {
- tmp = *(p++);
- tmp |= ~0UL >> (64-offset);
- if (size < 64)
- goto found_first;
- if (~tmp)
- goto found_middle;
- size -= 64;
- result += 64;
- }
- while (size & ~63UL) {
- if (~(tmp = *(p++)))
- goto found_middle;
- result += 64;
- size -= 64;
- }
- if (!size)
- return result;
- tmp = *p;
-
-found_first:
- tmp |= ~0UL << size;
- if (tmp == ~0UL) /* Are any bits zero? */
- return result + size; /* Nope. */
-found_middle:
- return result + ffz(tmp);
-}
-
-#define find_first_zero_bit(addr, size) \
- find_next_zero_bit((addr), (size), 0)
-
-extern long __test_and_set_le_bit(int nr, volatile void *addr);
-extern long __test_and_clear_le_bit(int nr, volatile void *addr);
-
-#define test_and_set_le_bit(nr,addr) (__test_and_set_le_bit(nr,addr)!=0)
-#define test_and_clear_le_bit(nr,addr) (__test_and_clear_le_bit(nr,addr)!=0)
-#define set_le_bit(nr,addr) ((void)__test_and_set_le_bit(nr,addr))
-#define clear_le_bit(nr,addr) ((void)__test_and_clear_le_bit(nr,addr))
-
-extern __inline__ int test_le_bit(int nr, __const__ void * addr)
-{
- int mask;
- __const__ unsigned char *ADDR = (__const__ unsigned char *) addr;
-
- ADDR += nr >> 3;
- mask = 1 << (nr & 0x07);
- return ((mask & *ADDR) != 0);
-}
-
-#define find_first_zero_le_bit(addr, size) \
- find_next_zero_le_bit((addr), (size), 0)
-
-extern __inline__ unsigned long find_next_zero_le_bit(void *addr, unsigned long size, unsigned long offset)
-{
- unsigned long *p = ((unsigned long *) addr) + (offset >> 6);
- unsigned long result = offset & ~63UL;
- unsigned long tmp;
-
- if (offset >= size)
- return size;
- size -= result;
- offset &= 63UL;
- if(offset) {
- tmp = __swab64p(p++);
- tmp |= (~0UL >> (64-offset));
- if(size < 64)
- goto found_first;
- if(~tmp)
- goto found_middle;
- size -= 64;
- result += 64;
- }
- while(size & ~63) {
- if(~(tmp = __swab64p(p++)))
- goto found_middle;
- result += 64;
- size -= 64;
- }
- if(!size)
- return result;
- tmp = __swab64p(p);
-found_first:
- tmp |= (~0UL << size);
- if (tmp == ~0UL) /* Are any bits zero? */
- return result + size; /* Nope. */
-found_middle:
- return result + ffz(tmp);
-}
-
-#ifdef __KERNEL__
-
-#define ext2_set_bit test_and_set_le_bit
-#define ext2_clear_bit test_and_clear_le_bit
-#define ext2_test_bit test_le_bit
-#define ext2_find_first_zero_bit find_first_zero_le_bit
-#define ext2_find_next_zero_bit find_next_zero_le_bit
-
-/* Bitmap functions for the minix filesystem. */
-#define minix_test_and_set_bit(nr,addr) test_and_set_bit(nr,addr)
-#define minix_set_bit(nr,addr) set_bit(nr,addr)
-#define minix_test_and_clear_bit(nr,addr) test_and_clear_bit(nr,addr)
-#define minix_test_bit(nr,addr) test_bit(nr,addr)
-#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
-
-#endif /* __KERNEL__ */
-
-#endif /* defined(_SPARC64_BITOPS_H) */
diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC
index 7475efd..08edaf7 100644
--- a/sys/i386/conf/GENERIC
+++ b/sys/i386/conf/GENERIC
@@ -71,6 +71,7 @@ options KBD_INSTALL_CDEV # install a CDEV entry in /dev
options STOP_NMI # Stop CPUS using NMI instead of IPI
options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4)
options AUDIT # Security event auditing
+options MAC # TrustedBSD MAC Framework
#options KDTRACE_HOOKS # Kernel DTrace hooks
# Debugging for use in -current
diff --git a/sys/i386/conf/MAC b/sys/i386/conf/MAC
deleted file mode 100644
index d208741..0000000
--- a/sys/i386/conf/MAC
+++ /dev/null
@@ -1,28 +0,0 @@
-# MAC -- Generic kernel configuration file for FreeBSD/i386 MAC
-#
-# The Mandatory Access Control, or MAC, framework allows administrators to
-# finely control system security by providing for a loadable security pol-
-# icy architecture.
-#
-# For more information see:
-#
-# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/mac.html
-#
-# $FreeBSD$
-
-include GENERIC
-ident MAC
-
-options MAC
-
-#options MAC_BIBA # BIBA data integrity policy
-#options MAC_BSDEXTENDED # File system firewall policy
-#options MAC_IFOFF # Network interface silencing policy
-#options MAC_LOMAC # Low-watermark data integrity policy
-#options MAC_MLS # Multi-level confidentiality policy
-#options MAC_NONE # NULL policy
-#options MAC_PARTITION # Process partition policy
-#options MAC_PORTACL # Network port access control policy
-#options MAC_SEEOTHERUIDS # UID visibility policy
-#options MAC_STUB # Stub policy
-#options MAC_TEST # Testing policy for the MAC framework
diff --git a/sys/ia64/conf/GENERIC b/sys/ia64/conf/GENERIC
index ab471f7..83d1f60 100644
--- a/sys/ia64/conf/GENERIC
+++ b/sys/ia64/conf/GENERIC
@@ -40,6 +40,7 @@ options INVARIANTS # Enable calls of extra sanity checking
options INVARIANT_SUPPORT # required by INVARIANTS
options KDB # Enable kernel debugger support
options KTRACE # ktrace(1) syscall trace support
+options MAC # TrustedBSD MAC Framework
options MD_ROOT # MD usable as root device
options MSDOSFS # MSDOS Filesystem
options NFSCLIENT # Network Filesystem Client
diff --git a/sys/ia64/conf/MAC b/sys/ia64/conf/MAC
deleted file mode 100644
index a4acaeb..0000000
--- a/sys/ia64/conf/MAC
+++ /dev/null
@@ -1,28 +0,0 @@
-# MAC -- Generic kernel configuration file for FreeBSD/ia64 MAC
-#
-# The Mandatory Access Control, or MAC, framework allows administrators to
-# finely control system security by providing for a loadable security pol-
-# icy architecture.
-#
-# For more information see:
-#
-# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/mac.html
-#
-# $FreeBSD$
-
-include GENERIC
-ident MAC
-
-options MAC
-
-#options MAC_BIBA # BIBA data integrity policy
-#options MAC_BSDEXTENDED # File system firewall policy
-#options MAC_IFOFF # Network interface silencing policy
-#options MAC_LOMAC # Low-watermark data integrity policy
-#options MAC_MLS # Multi-level confidentiality policy
-#options MAC_NONE # NULL policy
-#options MAC_PARTITION # Process partition policy
-#options MAC_PORTACL # Network port access control policy
-#options MAC_SEEOTHERUIDS # UID visibility policy
-#options MAC_STUB # Stub policy
-#options MAC_TEST # Testing policy for the MAC framework
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index c93d05a..1221825 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -2075,9 +2075,13 @@ fget_unlocked(struct filedesc *fdp, int fd)
count = fp->f_count;
if (count == 0)
continue;
- if (atomic_cmpset_int(&fp->f_count, count, count + 1) != 1)
+ /*
+ * Use an acquire barrier to prevent caching of fd_ofiles
+ * so it is refreshed for verification.
+ */
+ if (atomic_cmpset_acq_int(&fp->f_count, count, count + 1) != 1)
continue;
- if (fp == ((struct file *volatile*)fdp->fd_ofiles)[fd])
+ if (fp == fdp->fd_ofiles[fd])
break;
fdrop(fp, curthread);
}
diff --git a/sys/kern/kern_lock.c b/sys/kern/kern_lock.c
index f03ddbc..c365e65 100644
--- a/sys/kern/kern_lock.c
+++ b/sys/kern/kern_lock.c
@@ -51,8 +51,7 @@ __FBSDID("$FreeBSD$");
#include <ddb/ddb.h>
#endif
-CTASSERT(((LK_CANRECURSE | LK_NOSHARE) & LO_CLASSFLAGS) ==
- (LK_CANRECURSE | LK_NOSHARE));
+CTASSERT((LK_NOSHARE & LO_CLASSFLAGS) == LK_NOSHARE);
#define SQ_EXCLUSIVE_QUEUE 0
#define SQ_SHARED_QUEUE 1
@@ -316,7 +315,9 @@ lockinit(struct lock *lk, int pri, const char *wmesg, int timo, int flags)
MPASS((flags & ~LK_INIT_MASK) == 0);
- iflags = LO_RECURSABLE | LO_SLEEPABLE | LO_UPGRADABLE;
+ iflags = LO_SLEEPABLE | LO_UPGRADABLE;
+ if (flags & LK_CANRECURSE)
+ iflags |= LO_RECURSABLE;
if ((flags & LK_NODUP) == 0)
iflags |= LO_DUPOK;
if (flags & LK_NOPROFILE)
@@ -325,7 +326,7 @@ lockinit(struct lock *lk, int pri, const char *wmesg, int timo, int flags)
iflags |= LO_WITNESS;
if (flags & LK_QUIET)
iflags |= LO_QUIET;
- iflags |= flags & (LK_CANRECURSE | LK_NOSHARE);
+ iflags |= flags & LK_NOSHARE;
lk->lk_lock = LK_UNLOCKED;
lk->lk_recurse = 0;
@@ -530,7 +531,7 @@ __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk,
*/
if (lockmgr_xlocked(lk)) {
if ((flags & LK_CANRECURSE) == 0 &&
- (lk->lock_object.lo_flags & LK_CANRECURSE) == 0) {
+ (lk->lock_object.lo_flags & LO_RECURSABLE) == 0) {
/*
* If the lock is expected to not panic just
diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c
index a1a55f2..4e0bdf0 100644
--- a/sys/kern/kern_prot.c
+++ b/sys/kern/kern_prot.c
@@ -1690,9 +1690,7 @@ cr_canseesocket(struct ucred *cred, struct socket *so)
if (error)
return (ENOENT);
#ifdef MAC
- SOCK_LOCK(so);
error = mac_socket_check_visible(cred, so);
- SOCK_UNLOCK(so);
if (error)
return (error);
#endif
diff --git a/sys/kern/kern_rwlock.c b/sys/kern/kern_rwlock.c
index 28fccce..c07f595 100644
--- a/sys/kern/kern_rwlock.c
+++ b/sys/kern/kern_rwlock.c
@@ -51,8 +51,6 @@ __FBSDID("$FreeBSD$");
#include <machine/cpu.h>
-CTASSERT((RW_RECURSE & LO_CLASSFLAGS) == RW_RECURSE);
-
#if defined(SMP) && !defined(NO_ADAPTIVE_RWLOCKS)
#define ADAPTIVE_RWLOCKS
#endif
@@ -177,16 +175,17 @@ rw_init_flags(struct rwlock *rw, const char *name, int opts)
MPASS((opts & ~(RW_DUPOK | RW_NOPROFILE | RW_NOWITNESS | RW_QUIET |
RW_RECURSE)) == 0);
- flags = LO_UPGRADABLE | LO_RECURSABLE;
+ flags = LO_UPGRADABLE;
if (opts & RW_DUPOK)
flags |= LO_DUPOK;
if (opts & RW_NOPROFILE)
flags |= LO_NOPROFILE;
if (!(opts & RW_NOWITNESS))
flags |= LO_WITNESS;
+ if (opts & RW_RECURSE)
+ flags |= LO_RECURSABLE;
if (opts & RW_QUIET)
flags |= LO_QUIET;
- flags |= opts & RW_RECURSE;
rw->rw_lock = RW_UNLOCKED;
rw->rw_recurse = 0;
@@ -249,7 +248,8 @@ _rw_try_wlock(struct rwlock *rw, const char *file, int line)
KASSERT(rw->rw_lock != RW_DESTROYED,
("rw_try_wlock() of destroyed rwlock @ %s:%d", file, line));
- if (rw_wlocked(rw) && (rw->lock_object.lo_flags & RW_RECURSE) != 0) {
+ if (rw_wlocked(rw) &&
+ (rw->lock_object.lo_flags & LO_RECURSABLE) != 0) {
rw->rw_recurse++;
rval = 1;
} else
@@ -646,7 +646,7 @@ _rw_wlock_hard(struct rwlock *rw, uintptr_t tid, const char *file, int line)
#endif
if (rw_wlocked(rw)) {
- KASSERT(rw->lock_object.lo_flags & RW_RECURSE,
+ KASSERT(rw->lock_object.lo_flags & LO_RECURSABLE,
("%s: recursing but non-recursive rw %s @ %s:%d\n",
__func__, rw->lock_object.lo_name, file, line));
rw->rw_recurse++;
diff --git a/sys/kern/kern_sx.c b/sys/kern/kern_sx.c
index 6342252..04c2c98 100644
--- a/sys/kern/kern_sx.c
+++ b/sys/kern/kern_sx.c
@@ -66,8 +66,7 @@ __FBSDID("$FreeBSD$");
#define ADAPTIVE_SX
#endif
-CTASSERT(((SX_NOADAPTIVE | SX_RECURSE) & LO_CLASSFLAGS) ==
- (SX_NOADAPTIVE | SX_RECURSE));
+CTASSERT((SX_NOADAPTIVE & LO_CLASSFLAGS) == SX_NOADAPTIVE);
/* Handy macros for sleep queues. */
#define SQ_EXCLUSIVE_QUEUE 0
@@ -207,17 +206,19 @@ sx_init_flags(struct sx *sx, const char *description, int opts)
MPASS((opts & ~(SX_QUIET | SX_RECURSE | SX_NOWITNESS | SX_DUPOK |
SX_NOPROFILE | SX_NOADAPTIVE)) == 0);
- flags = LO_RECURSABLE | LO_SLEEPABLE | LO_UPGRADABLE;
+ flags = LO_SLEEPABLE | LO_UPGRADABLE;
if (opts & SX_DUPOK)
flags |= LO_DUPOK;
if (opts & SX_NOPROFILE)
flags |= LO_NOPROFILE;
if (!(opts & SX_NOWITNESS))
flags |= LO_WITNESS;
+ if (opts & SX_RECURSE)
+ flags |= LO_RECURSABLE;
if (opts & SX_QUIET)
flags |= LO_QUIET;
- flags |= opts & (SX_NOADAPTIVE | SX_RECURSE);
+ flags |= opts & SX_NOADAPTIVE;
sx->sx_lock = SX_LOCK_UNLOCKED;
sx->sx_recurse = 0;
lock_init(&sx->lock_object, &lock_class_sx, description, NULL, flags);
@@ -305,7 +306,8 @@ _sx_try_xlock(struct sx *sx, const char *file, int line)
KASSERT(sx->sx_lock != SX_LOCK_DESTROYED,
("sx_try_xlock() of destroyed sx @ %s:%d", file, line));
- if (sx_xlocked(sx) && (sx->lock_object.lo_flags & SX_RECURSE) != 0) {
+ if (sx_xlocked(sx) &&
+ (sx->lock_object.lo_flags & LO_RECURSABLE) != 0) {
sx->sx_recurse++;
atomic_set_ptr(&sx->sx_lock, SX_LOCK_RECURSED);
rval = 1;
@@ -479,7 +481,7 @@ _sx_xlock_hard(struct sx *sx, uintptr_t tid, int opts, const char *file,
/* If we already hold an exclusive lock, then recurse. */
if (sx_xlocked(sx)) {
- KASSERT((sx->lock_object.lo_flags & SX_RECURSE) != 0,
+ KASSERT((sx->lock_object.lo_flags & LO_RECURSABLE) != 0,
("_sx_xlock_hard: recursed on non-recursive sx %s @ %s:%d\n",
sx->lock_object.lo_name, file, line));
sx->sx_recurse++;
diff --git a/sys/kern/sys_socket.c b/sys/kern/sys_socket.c
index 61b0361..5e5695c 100644
--- a/sys/kern/sys_socket.c
+++ b/sys/kern/sys_socket.c
@@ -78,9 +78,7 @@ soo_read(struct file *fp, struct uio *uio, struct ucred *active_cred,
int error;
#ifdef MAC
- SOCK_LOCK(so);
error = mac_socket_check_receive(active_cred, so);
- SOCK_UNLOCK(so);
if (error)
return (error);
#endif
@@ -99,9 +97,7 @@ soo_write(struct file *fp, struct uio *uio, struct ucred *active_cred,
int error;
#ifdef MAC
- SOCK_LOCK(so);
error = mac_socket_check_send(active_cred, so);
- SOCK_UNLOCK(so);
if (error)
return (error);
#endif
@@ -222,9 +218,7 @@ soo_poll(struct file *fp, int events, struct ucred *active_cred,
#ifdef MAC
int error;
- SOCK_LOCK(so);
error = mac_socket_check_poll(active_cred, so);
- SOCK_UNLOCK(so);
if (error)
return (error);
#endif
@@ -243,9 +237,7 @@ soo_stat(struct file *fp, struct stat *ub, struct ucred *active_cred,
bzero((caddr_t)ub, sizeof (*ub));
ub->st_mode = S_IFSOCK;
#ifdef MAC
- SOCK_LOCK(so);
error = mac_socket_check_stat(active_cred, so);
- SOCK_UNLOCK(so);
if (error)
return (error);
#endif
diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c
index bf24132..ea53885 100644
--- a/sys/kern/uipc_mbuf.c
+++ b/sys/kern/uipc_mbuf.c
@@ -49,8 +49,6 @@ __FBSDID("$FreeBSD$");
#include <sys/protosw.h>
#include <sys/uio.h>
-#include <security/mac/mac_framework.h>
-
int max_linkhdr;
int max_protohdr;
int max_hdr;
diff --git a/sys/kern/uipc_shm.c b/sys/kern/uipc_shm.c
index a12c731..00fb438 100644
--- a/sys/kern/uipc_shm.c
+++ b/sys/kern/uipc_shm.c
@@ -274,7 +274,7 @@ shm_dotruncate(struct shmfd *shmfd, off_t length)
/*
* If the last page is partially mapped, then zero out
* the garbage at the end of the page. See comments
- * in vnode_page_setsize() for more details.
+ * in vnode_pager_setsize() for more details.
*
* XXXJHB: This handles in memory pages, but what about
* a page swapped out to disk?
@@ -286,10 +286,23 @@ shm_dotruncate(struct shmfd *shmfd, off_t length)
int size = PAGE_SIZE - base;
pmap_zero_page_area(m, base, size);
+
+ /*
+ * Update the valid bits to reflect the blocks that
+ * have been zeroed. Some of these valid bits may
+ * have already been set.
+ */
+ vm_page_set_valid(m, base, size);
+
+ /*
+ * Round "base" to the next block boundary so that the
+ * dirty bit for a partially zeroed block is not
+ * cleared.
+ */
+ base = roundup2(base, DEV_BSIZE);
+
vm_page_lock_queues();
- vm_page_set_validclean(m, base, size);
- if (m->dirty != 0)
- m->dirty = VM_PAGE_BITS_ALL;
+ vm_page_clear_dirty(m, base, PAGE_SIZE - base);
vm_page_unlock_queues();
} else if ((length & PAGE_MASK) &&
__predict_false(object->cache != NULL)) {
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index 80f9a55..7341d3f 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -444,9 +444,7 @@ sonewconn(struct socket *head, int connstatus)
so->so_proto = head->so_proto;
so->so_cred = crhold(head->so_cred);
#ifdef MAC
- SOCK_LOCK(head);
mac_socket_newconn(head, so);
- SOCK_UNLOCK(head);
#endif
knlist_init(&so->so_rcv.sb_sel.si_note, SOCKBUF_MTX(&so->so_rcv),
NULL, NULL, NULL);
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index 66eb7e1..964547c 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -221,16 +221,10 @@ kern_bind(td, fd, sa)
ktrsockaddr(sa);
#endif
#ifdef MAC
- SOCK_LOCK(so);
error = mac_socket_check_bind(td->td_ucred, so, sa);
- SOCK_UNLOCK(so);
- if (error)
- goto done;
-#endif
- error = sobind(so, sa, td);
-#ifdef MAC
-done:
+ if (error == 0)
#endif
+ error = sobind(so, sa, td);
fdrop(fp, td);
return (error);
}
@@ -252,17 +246,14 @@ listen(td, uap)
if (error == 0) {
so = fp->f_data;
#ifdef MAC
- SOCK_LOCK(so);
error = mac_socket_check_listen(td->td_ucred, so);
- SOCK_UNLOCK(so);
- if (error)
- goto done;
+ if (error == 0) {
#endif
- CURVNET_SET(so->so_vnet);
- error = solisten(so, uap->backlog, td);
- CURVNET_RESTORE();
+ CURVNET_SET(so->so_vnet);
+ error = solisten(so, uap->backlog, td);
+ CURVNET_RESTORE();
#ifdef MAC
-done:
+ }
#endif
fdrop(fp, td);
}
@@ -354,9 +345,7 @@ kern_accept(struct thread *td, int s, struct sockaddr **name,
goto done;
}
#ifdef MAC
- SOCK_LOCK(head);
error = mac_socket_check_accept(td->td_ucred, head);
- SOCK_UNLOCK(head);
if (error != 0)
goto done;
#endif
@@ -549,9 +538,7 @@ kern_connect(td, fd, sa)
ktrsockaddr(sa);
#endif
#ifdef MAC
- SOCK_LOCK(so);
error = mac_socket_check_connect(td->td_ucred, so, sa);
- SOCK_UNLOCK(so);
if (error)
goto bad;
#endif
@@ -603,7 +590,6 @@ kern_socketpair(struct thread *td, int domain, int type, int protocol,
if (error)
return (error);
#endif
-
error = socreate(domain, &so1, type, protocol, td->td_ucred, td);
if (error)
return (error);
@@ -752,13 +738,13 @@ kern_sendit(td, s, mp, flags, control, segflg)
so = (struct socket *)fp->f_data;
#ifdef MAC
- SOCK_LOCK(so);
- if (mp->msg_name != NULL)
+ if (mp->msg_name != NULL) {
error = mac_socket_check_connect(td->td_ucred, so,
mp->msg_name);
- if (error == 0)
- error = mac_socket_check_send(td->td_ucred, so);
- SOCK_UNLOCK(so);
+ if (error)
+ goto bad;
+ }
+ error = mac_socket_check_send(td->td_ucred, so);
if (error)
goto bad;
#endif
@@ -951,9 +937,7 @@ kern_recvit(td, s, mp, fromseg, controlp)
so = fp->f_data;
#ifdef MAC
- SOCK_LOCK(so);
error = mac_socket_check_receive(td->td_ucred, so);
- SOCK_UNLOCK(so);
if (error) {
fdrop(fp, td);
return (error);
@@ -1887,9 +1871,7 @@ kern_sendfile(struct thread *td, struct sendfile_args *uap,
}
#ifdef MAC
- SOCK_LOCK(so);
error = mac_socket_check_send(td->td_ucred, so);
- SOCK_UNLOCK(so);
if (error)
goto out;
#endif
@@ -2417,9 +2399,7 @@ sctp_generic_sendmsg (td, uap)
so = (struct socket *)fp->f_data;
#ifdef MAC
- SOCK_LOCK(so);
error = mac_socket_check_send(td->td_ucred, so);
- SOCK_UNLOCK(so);
if (error)
goto sctp_bad;
#endif /* MAC */
@@ -2521,9 +2501,7 @@ sctp_generic_sendmsg_iov(td, uap)
so = (struct socket *)fp->f_data;
#ifdef MAC
- SOCK_LOCK(so);
error = mac_socket_check_send(td->td_ucred, so);
- SOCK_UNLOCK(so);
if (error)
goto sctp_bad;
#endif /* MAC */
@@ -2618,9 +2596,7 @@ sctp_generic_recvmsg(td, uap)
so = fp->f_data;
#ifdef MAC
- SOCK_LOCK(so);
error = mac_socket_check_receive(td->td_ucred, so);
- SOCK_UNLOCK(so);
if (error) {
goto out;
return (error);
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
index 2f33008..c9e7d39 100644
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -1246,10 +1246,8 @@ unp_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
UNP_PCB_UNLOCK(unp2);
UNP_PCB_UNLOCK(unp);
#ifdef MAC
- SOCK_LOCK(so);
mac_socketpeer_set_from_socket(so, so3);
mac_socketpeer_set_from_socket(so3, so);
- SOCK_UNLOCK(so);
#endif
so2 = so3;
diff --git a/sys/net/if.c b/sys/net/if.c
index 9a3c1fd..ffff619 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -574,6 +574,7 @@ if_free_internal(struct ifnet *ifp)
knlist_destroy(&ifp->if_klist);
IF_AFDATA_DESTROY(ifp);
IF_ADDR_LOCK_DESTROY(ifp);
+ ifq_detach(&ifp->if_snd);
free(ifp, M_IFNET);
}
@@ -1025,9 +1026,6 @@ if_detach_internal(struct ifnet *ifp, int vmove)
}
ifp->if_afdata_initialized = 0;
IF_AFDATA_UNLOCK(ifp);
-
- if (!vmove)
- ifq_detach(&ifp->if_snd);
}
#ifdef VIMAGE
diff --git a/sys/net80211/ieee80211.c b/sys/net80211/ieee80211.c
index 22c690c..092514b 100644
--- a/sys/net80211/ieee80211.c
+++ b/sys/net80211/ieee80211.c
@@ -313,6 +313,8 @@ ieee80211_ifdetach(struct ieee80211com *ic)
struct ifnet *ifp = ic->ic_ifp;
struct ieee80211vap *vap;
+ if_detach(ifp);
+
while ((vap = TAILQ_FIRST(&ic->ic_vaps)) != NULL)
ieee80211_vap_destroy(vap);
ieee80211_waitfor_parent(ic);
@@ -329,11 +331,10 @@ ieee80211_ifdetach(struct ieee80211com *ic)
ieee80211_crypto_detach(ic);
ieee80211_power_detach(ic);
ieee80211_node_detach(ic);
- ifmedia_removeall(&ic->ic_media);
+ ifmedia_removeall(&ic->ic_media);
taskqueue_free(ic->ic_tq);
IEEE80211_LOCK_DESTROY(ic);
- if_detach(ifp);
}
/*
@@ -513,8 +514,6 @@ ieee80211_vap_attach(struct ieee80211vap *vap,
IEEE80211_LOCK(ic);
TAILQ_INSERT_TAIL(&ic->ic_vaps, vap, iv_next);
- if (vap->iv_opmode == IEEE80211_M_MONITOR)
- ic->ic_monvaps++;
ieee80211_syncflag_locked(ic, IEEE80211_F_WME);
#ifdef IEEE80211_SUPPORT_SUPERG
ieee80211_syncflag_locked(ic, IEEE80211_F_TURBOP);
@@ -546,24 +545,10 @@ ieee80211_vap_detach(struct ieee80211vap *vap)
__func__, ieee80211_opmode_name[vap->iv_opmode],
ic->ic_ifp->if_xname);
- IEEE80211_LOCK(ic);
- /* block traffic from above */
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- /*
- * Evil hack. Clear the backpointer from the ifnet to the
- * vap so any requests from above will return an error or
- * be ignored. In particular this short-circuits requests
- * by the bridge to turn off promiscuous mode as a result
- * of calling ether_ifdetach.
- */
- ifp->if_softc = NULL;
- /*
- * Stop the vap before detaching the ifnet. Ideally we'd
- * do this in the other order so the ifnet is inaccessible
- * while we cleanup internal state but that is hard.
- */
- ieee80211_stop_locked(vap);
- IEEE80211_UNLOCK(ic);
+ /* NB: bpfdetach is called by ether_ifdetach and claims all taps */
+ ether_ifdetach(ifp);
+
+ ieee80211_stop(vap);
/*
* Flush any deferred vap tasks.
@@ -575,8 +560,6 @@ ieee80211_vap_detach(struct ieee80211vap *vap)
IEEE80211_LOCK(ic);
KASSERT(vap->iv_state == IEEE80211_S_INIT , ("vap still running"));
TAILQ_REMOVE(&ic->ic_vaps, vap, iv_next);
- if (vap->iv_opmode == IEEE80211_M_MONITOR)
- ic->ic_monvaps--;
ieee80211_syncflag_locked(ic, IEEE80211_F_WME);
#ifdef IEEE80211_SUPPORT_SUPERG
ieee80211_syncflag_locked(ic, IEEE80211_F_TURBOP);
@@ -591,10 +574,6 @@ ieee80211_vap_detach(struct ieee80211vap *vap)
ieee80211_syncifflag_locked(ic, IFF_ALLMULTI);
IEEE80211_UNLOCK(ic);
- /* XXX can't hold com lock */
- /* NB: bpfdetach is called by ether_ifdetach and claims all taps */
- ether_ifdetach(ifp);
-
ifmedia_removeall(&vap->iv_media);
ieee80211_radiotap_vdetach(vap);
@@ -1207,7 +1186,7 @@ ieee80211_media_change(struct ifnet *ifp)
return EINVAL;
if (vap->iv_des_mode != newmode) {
vap->iv_des_mode = newmode;
- return ENETRESET;
+ /* XXX kick state machine if up+running */
}
return 0;
}
diff --git a/sys/net80211/ieee80211_ddb.c b/sys/net80211/ieee80211_ddb.c
index 8545140..2b66d6b 100644
--- a/sys/net80211/ieee80211_ddb.c
+++ b/sys/net80211/ieee80211_ddb.c
@@ -584,6 +584,11 @@ _db_show_com(const struct ieee80211com *ic, int showvaps, int showsta, int showp
db_printf(" lastnonht %d", ic->ic_lastnonht);
db_printf("\n");
+ db_printf("\tsuperg %p\n", ic->ic_superg);
+
+ db_printf("\tmontaps %d th %p txchan %p rh %p rxchan %p\n",
+ ic->ic_montaps, ic->ic_th, ic->ic_txchan, ic->ic_rh, ic->ic_rxchan);
+
if (showprocs) {
DB_PRINTSYM("\t", "ic_vap_create", ic->ic_vap_create);
DB_PRINTSYM("\t", "ic_vap_delete", ic->ic_vap_delete);
diff --git a/sys/net80211/ieee80211_freebsd.c b/sys/net80211/ieee80211_freebsd.c
index 0dfa4a9..47a76bb 100644
--- a/sys/net80211/ieee80211_freebsd.c
+++ b/sys/net80211/ieee80211_freebsd.c
@@ -706,11 +706,15 @@ bpf_track(void *arg, struct ifnet *ifp, int dlt, int attach)
* vap. This flag is used by drivers to prepare radiotap
* state only when needed.
*/
- if (attach)
+ if (attach) {
ieee80211_syncflag_ext(vap, IEEE80211_FEXT_BPF);
- /* NB: if_softc is NULL on vap detach */
- else if (vap != NULL && !bpf_peers_present(vap->iv_rawbpf))
+ if (vap->iv_opmode == IEEE80211_M_MONITOR)
+ atomic_add_int(&vap->iv_ic->ic_montaps, 1);
+ } else if (!bpf_peers_present(vap->iv_rawbpf)) {
ieee80211_syncflag_ext(vap, -IEEE80211_FEXT_BPF);
+ if (vap->iv_opmode == IEEE80211_M_MONITOR)
+ atomic_subtract_int(&vap->iv_ic->ic_montaps, 1);
+ }
}
}
diff --git a/sys/net80211/ieee80211_hostap.c b/sys/net80211/ieee80211_hostap.c
index ee83eace..eec52f9 100644
--- a/sys/net80211/ieee80211_hostap.c
+++ b/sys/net80211/ieee80211_hostap.c
@@ -302,6 +302,9 @@ hostap_deliver_data(struct ieee80211vap *vap,
struct ether_header *eh = mtod(m, struct ether_header *);
struct ifnet *ifp = vap->iv_ifp;
+ /* clear driver/net80211 flags before passing up */
+ m->m_flags &= ~(M_80211_RX | M_MCAST | M_BCAST);
+
KASSERT(vap->iv_opmode == IEEE80211_M_HOSTAP,
("gack, opmode %d", vap->iv_opmode));
/*
@@ -316,9 +319,6 @@ hostap_deliver_data(struct ieee80211vap *vap,
} else
IEEE80211_NODE_STAT(ni, rx_ucast);
- /* clear driver/net80211 flags before passing up */
- m->m_flags &= ~M_80211_RX;
-
/* perform as a bridge within the AP */
if ((vap->iv_flags & IEEE80211_F_NOBRIDGE) == 0) {
struct mbuf *mcopy = NULL;
diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c
index 6e06918..53c2285 100644
--- a/sys/net80211/ieee80211_input.c
+++ b/sys/net80211/ieee80211_input.c
@@ -60,11 +60,16 @@ ieee80211_input_all(struct ieee80211com *ic, struct mbuf *m, int rssi, int nf)
struct ieee80211vap *vap;
int type = -1;
+ m->m_flags |= M_BCAST; /* NB: mark for bpf tap'ing */
+
/* XXX locking */
TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
struct ieee80211_node *ni;
struct mbuf *mcopy;
+ /* NB: could check for IFF_UP but this is cheaper */
+ if (vap->iv_state == IEEE80211_S_INIT)
+ continue;
/*
* WDS vap's only receive directed traffic from the
* station at the ``far end''. That traffic should
@@ -196,6 +201,9 @@ ieee80211_deliver_data(struct ieee80211vap *vap,
struct ether_header *eh = mtod(m, struct ether_header *);
struct ifnet *ifp = vap->iv_ifp;
+ /* clear driver/net80211 flags before passing up */
+ m->m_flags &= ~(M_80211_RX | M_MCAST | M_BCAST);
+
/* NB: see hostap_deliver_data, this path doesn't handle hostap */
KASSERT(vap->iv_opmode != IEEE80211_M_HOSTAP, ("gack, hostap"));
/*
@@ -211,9 +219,6 @@ ieee80211_deliver_data(struct ieee80211vap *vap,
IEEE80211_NODE_STAT(ni, rx_ucast);
m->m_pkthdr.rcvif = ifp;
- /* clear driver/net80211 flags before passing up */
- m->m_flags &= ~M_80211_RX;
-
if (ni->ni_vlan != 0) {
/* attach vlan tag */
m->m_pkthdr.ether_vtag = ni->ni_vlan;
diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c
index d40680a..36c6f4c 100644
--- a/sys/net80211/ieee80211_ioctl.c
+++ b/sys/net80211/ieee80211_ioctl.c
@@ -64,7 +64,7 @@ __FBSDID("$FreeBSD$");
#include <net80211/ieee80211_input.h>
#define IS_UP_AUTO(_vap) \
- (IFNET_IS_UP_RUNNING(vap->iv_ifp) && \
+ (IFNET_IS_UP_RUNNING((_vap)->iv_ifp) && \
(_vap)->iv_roaming == IEEE80211_ROAMING_AUTO)
static const uint8_t zerobssid[IEEE80211_ADDR_LEN];
@@ -3202,29 +3202,14 @@ ieee80211_ioctl_updatemulti(struct ieee80211com *ic)
int
ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
- struct ieee80211vap *vap;
- struct ieee80211com *ic;
+ struct ieee80211vap *vap = ifp->if_softc;
+ struct ieee80211com *ic = vap->iv_ic;
int error = 0;
struct ifreq *ifr;
struct ifaddr *ifa; /* XXX */
- vap = ifp->if_softc;
- if (vap == NULL) {
- /*
- * During detach we clear the backpointer in the softc
- * so any ioctl request through the ifnet that arrives
- * before teardown is ignored/rejected. In particular
- * this hack handles destroying a vap used by an app
- * like wpa_supplicant that will respond to the vap
- * being forced into INIT state by immediately trying
- * to force it back up. We can yank this hack if/when
- * we can destroy the ifnet before cleaning up vap state.
- */
- return ENXIO;
- }
switch (cmd) {
case SIOCSIFFLAGS:
- ic = vap->iv_ic;
IEEE80211_LOCK(ic);
ieee80211_syncifflag_locked(ic, IFF_PROMISC);
ieee80211_syncifflag_locked(ic, IFF_ALLMULTI);
@@ -3250,7 +3235,7 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
break;
case SIOCADDMULTI:
case SIOCDELMULTI:
- ieee80211_ioctl_updatemulti(vap->iv_ic);
+ ieee80211_ioctl_updatemulti(ic);
break;
case SIOCSIFMEDIA:
case SIOCGIFMEDIA:
diff --git a/sys/net80211/ieee80211_monitor.c b/sys/net80211/ieee80211_monitor.c
index 3f2c847..e324081 100644
--- a/sys/net80211/ieee80211_monitor.c
+++ b/sys/net80211/ieee80211_monitor.c
@@ -127,6 +127,9 @@ static int
monitor_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
{
struct ieee80211vap *vap = ni->ni_vap;
+ struct ifnet *ifp = vap->iv_ifp;
+
+ ifp->if_ipackets++;
if (ieee80211_radiotap_active_vap(vap))
ieee80211_radiotap_rx(vap, m);
diff --git a/sys/net80211/ieee80211_proto.c b/sys/net80211/ieee80211_proto.c
index 99b995c8..7e69929 100644
--- a/sys/net80211/ieee80211_proto.c
+++ b/sys/net80211/ieee80211_proto.c
@@ -1220,22 +1220,12 @@ ieee80211_init(void *arg)
{
struct ieee80211vap *vap = arg;
- /*
- * This routine is publicly accessible through the vap's
- * if_init method so guard against calls during detach.
- * ieee80211_vap_detach null's the backpointer before
- * tearing down state to signal any callback should be
- * rejected/ignored.
- */
- if (vap != NULL) {
- IEEE80211_DPRINTF(vap,
- IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG,
- "%s\n", __func__);
-
- IEEE80211_LOCK(vap->iv_ic);
- ieee80211_start_locked(vap);
- IEEE80211_UNLOCK(vap->iv_ic);
- }
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG,
+ "%s\n", __func__);
+
+ IEEE80211_LOCK(vap->iv_ic);
+ ieee80211_start_locked(vap);
+ IEEE80211_UNLOCK(vap->iv_ic);
}
/*
diff --git a/sys/net80211/ieee80211_radiotap.c b/sys/net80211/ieee80211_radiotap.c
index 9c8dc4d..b39a071 100644
--- a/sys/net80211/ieee80211_radiotap.c
+++ b/sys/net80211/ieee80211_radiotap.c
@@ -168,6 +168,7 @@ ieee80211_radiotap_chan_change(struct ieee80211com *ic)
}
}
+#if 0
static void
dispatch_radiotap(struct ieee80211vap *vap0, struct mbuf *m,
struct ieee80211_radiotap_header *rh)
@@ -175,17 +176,46 @@ dispatch_radiotap(struct ieee80211vap *vap0, struct mbuf *m,
struct ieee80211com *ic = vap0->iv_ic;
int len = le16toh(rh->it_len);
- if (ieee80211_radiotap_active_vap(vap0))
+ if (vap0->iv_flags_ext & IEEE80211_FEXT_BPF)
bpf_mtap2(vap0->iv_rawbpf, rh, len, m);
- if (ic->ic_monvaps) {
+ /*
+ * Spam monitor mode vaps with unicast frames. Multicast
+ * frames are handled by passing through ieee80211_input_all
+ * which distributes copies to the monitor mode vaps to be
+ * processed above.
+ */
+ if (ic->ic_montaps != 0 && (m->m_flags & M_BCAST) == 0) {
struct ieee80211vap *vap;
TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
- if (vap->iv_opmode == IEEE80211_M_MONITOR &&
- vap != vap0 && ieee80211_radiotap_active_vap(vap))
+ if (vap != vap0 &&
+ vap->iv_opmode == IEEE80211_M_MONITOR &&
+ (vap->iv_flags_ext & IEEE80211_FEXT_BPF) &&
+ vap->iv_state != IEEE80211_S_INIT)
bpf_mtap2(vap->iv_rawbpf, rh, len, m);
}
}
}
+#endif
+
+/*
+ * Distribute radiotap data (+packet) to all monitor mode
+ * vaps with an active tap other than vap0.
+ */
+static void
+spam_vaps(struct ieee80211vap *vap0, struct mbuf *m,
+ struct ieee80211_radiotap_header *rh, int len)
+{
+ struct ieee80211com *ic = vap0->iv_ic;
+ struct ieee80211vap *vap;
+
+ TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
+ if (vap != vap0 &&
+ vap->iv_opmode == IEEE80211_M_MONITOR &&
+ (vap->iv_flags_ext & IEEE80211_FEXT_BPF) &&
+ vap->iv_state != IEEE80211_S_INIT)
+ bpf_mtap2(vap->iv_rawbpf, rh, len, m);
+ }
+}
/*
* Dispatch radiotap data for transmitted packet.
@@ -193,8 +223,20 @@ dispatch_radiotap(struct ieee80211vap *vap0, struct mbuf *m,
void
ieee80211_radiotap_tx(struct ieee80211vap *vap0, struct mbuf *m)
{
- KASSERT(vap0->iv_ic->ic_th != NULL, ("no tx radiotap header"));
- dispatch_radiotap(vap0, m, vap0->iv_ic->ic_th);
+ struct ieee80211com *ic = vap0->iv_ic;
+ struct ieee80211_radiotap_header *th = ic->ic_th;
+ int len;
+
+ KASSERT(th != NULL, ("no tx radiotap header"));
+ len = le16toh(th->it_len);
+
+ if (vap0->iv_flags_ext & IEEE80211_FEXT_BPF)
+ bpf_mtap2(vap0->iv_rawbpf, th, len, m);
+ /*
+ * Spam monitor mode vaps.
+ */
+ if (ic->ic_montaps != 0)
+ spam_vaps(vap0, m, th, len);
}
/*
@@ -203,8 +245,22 @@ ieee80211_radiotap_tx(struct ieee80211vap *vap0, struct mbuf *m)
void
ieee80211_radiotap_rx(struct ieee80211vap *vap0, struct mbuf *m)
{
- KASSERT(vap0->iv_ic->ic_rh != NULL, ("no rx radiotap header"));
- dispatch_radiotap(vap0, m, vap0->iv_ic->ic_rh);
+ struct ieee80211com *ic = vap0->iv_ic;
+ struct ieee80211_radiotap_header *rh = ic->ic_rh;
+ int len;
+
+ KASSERT(rh != NULL, ("no rx radiotap header"));
+ len = le16toh(rh->it_len);
+
+ if (vap0->iv_flags_ext & IEEE80211_FEXT_BPF)
+ bpf_mtap2(vap0->iv_rawbpf, rh, len, m);
+ /*
+ * Spam monitor mode vaps with unicast frames. Multicast
+ * frames are handled by passing through ieee80211_input_all
+ * which distributes copies to the monitor mode vaps.
+ */
+ if (ic->ic_montaps != 0 && (m->m_flags & M_BCAST) == 0)
+ spam_vaps(vap0, m, rh, len);
}
/*
@@ -221,7 +277,8 @@ ieee80211_radiotap_rx_all(struct ieee80211com *ic, struct mbuf *m)
/* XXX locking? */
TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
- if (ieee80211_radiotap_active_vap(vap))
+ if (ieee80211_radiotap_active_vap(vap) &&
+ vap->iv_state != IEEE80211_S_INIT)
bpf_mtap2(vap->iv_rawbpf, rh, len, m);
}
}
diff --git a/sys/net80211/ieee80211_scan.c b/sys/net80211/ieee80211_scan.c
index b41ed59..951e762 100644
--- a/sys/net80211/ieee80211_scan.c
+++ b/sys/net80211/ieee80211_scan.c
@@ -131,6 +131,7 @@ ieee80211_scan_detach(struct ieee80211com *ic)
scan_signal(ss);
IEEE80211_UNLOCK(ic);
ieee80211_draintask(ic, &SCAN_PRIVATE(ss)->ss_scan_task);
+ callout_drain(&SCAN_PRIVATE(ss)->ss_scan_timer);
KASSERT((ic->ic_flags & IEEE80211_F_SCAN) == 0,
("scan still running"));
if (ss->ss_ops != NULL) {
diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h
index 31037fe..3e999c8 100644
--- a/sys/net80211/ieee80211_var.h
+++ b/sys/net80211/ieee80211_var.h
@@ -215,7 +215,7 @@ struct ieee80211com {
void *ic_txchan; /* channel state in ic_th */
struct ieee80211_radiotap_header *ic_rh;/* rx radiotap headers */
void *ic_rxchan; /* channel state in ic_rh */
- int ic_monvaps; /* # monitor mode vaps */
+ int ic_montaps; /* active monitor mode taps */
/* virtual ap create/delete */
struct ieee80211vap* (*ic_vap_create)(struct ieee80211com *,
@@ -669,7 +669,8 @@ ieee80211_radiotap_active(const struct ieee80211com *ic)
static __inline int
ieee80211_radiotap_active_vap(const struct ieee80211vap *vap)
{
- return (vap->iv_flags_ext & IEEE80211_FEXT_BPF) != 0;
+ return (vap->iv_flags_ext & IEEE80211_FEXT_BPF) ||
+ vap->iv_ic->ic_montaps != 0;
}
/*
diff --git a/sys/netatalk/ddp_input.c b/sys/netatalk/ddp_input.c
index 2e7dac8..d90b2e8 100644
--- a/sys/netatalk/ddp_input.c
+++ b/sys/netatalk/ddp_input.c
@@ -410,12 +410,8 @@ ddp_input(struct mbuf *m, struct ifnet *ifp, struct elaphdr *elh, int phase)
goto out;
#ifdef MAC
- SOCK_LOCK(ddp->ddp_socket);
- if (mac_socket_check_deliver(ddp->ddp_socket, m) != 0) {
- SOCK_UNLOCK(ddp->ddp_socket);
+ if (mac_socket_check_deliver(ddp->ddp_socket, m) != 0)
goto out;
- }
- SOCK_UNLOCK(ddp->ddp_socket);
#endif
/*
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index 0b4ef27..140f41a 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -212,9 +212,7 @@ in_pcballoc(struct socket *so, struct inpcbinfo *pcbinfo)
error = mac_inpcb_init(inp, M_NOWAIT);
if (error != 0)
goto out;
- SOCK_LOCK(so);
mac_inpcb_create(so, inp);
- SOCK_UNLOCK(so);
#endif
#ifdef IPSEC
error = ipsec_init_policy(so, &inp->inp_sp);
diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c
index 5e71d4d..0894bfa4 100644
--- a/sys/netinet/ip_divert.c
+++ b/sys/netinet/ip_divert.c
@@ -467,9 +467,7 @@ div_output(struct socket *so, struct mbuf *m, struct sockaddr_in *sin,
m->m_pkthdr.rcvif = ifa->ifa_ifp;
}
#ifdef MAC
- SOCK_LOCK(so);
mac_socket_create_mbuf(so, m);
- SOCK_UNLOCK(so);
#endif
/* Send packet to input processing via netisr */
netisr_queue_src(NETISR_IP, (uintptr_t)so, m);
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index bbf5d8f..674c77e 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -1562,9 +1562,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
TCPSTAT_INC(tcps_connects);
soisconnected(so);
#ifdef MAC
- SOCK_LOCK(so);
mac_socketpeer_set_from_mbuf(m, so);
- SOCK_UNLOCK(so);
#endif
/* Do window scaling on this connection? */
if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) ==
diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c
index 8e80842..2763183 100644
--- a/sys/netinet/tcp_syncache.c
+++ b/sys/netinet/tcp_syncache.c
@@ -635,9 +635,7 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m)
goto abort2;
}
#ifdef MAC
- SOCK_LOCK(so);
mac_socketpeer_set_from_mbuf(m, so);
- SOCK_UNLOCK(so);
#endif
inp = sotoinpcb(so);
diff --git a/sys/pc98/conf/GENERIC b/sys/pc98/conf/GENERIC
index 539feab..82b8888 100644
--- a/sys/pc98/conf/GENERIC
+++ b/sys/pc98/conf/GENERIC
@@ -73,6 +73,7 @@ options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
options KBD_INSTALL_CDEV # install a CDEV entry in /dev
options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4)
options AUDIT # Security event auditing
+options MAC # TrustedBSD MAC Framework
# Debugging for use in -current
options KDB # Enable kernel debugger support.
diff --git a/sys/pc98/conf/MAC b/sys/pc98/conf/MAC
deleted file mode 100644
index 6aee5da..0000000
--- a/sys/pc98/conf/MAC
+++ /dev/null
@@ -1,28 +0,0 @@
-# MAC -- Generic kernel configuration file for FreeBSD/pc98 MAC
-#
-# The Mandatory Access Control, or MAC, framework allows administrators to
-# finely control system security by providing for a loadable security pol-
-# icy architecture.
-#
-# For more information see:
-#
-# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/mac.html
-#
-# $FreeBSD$
-
-include GENERIC
-ident MAC
-
-options MAC
-
-#options MAC_BIBA # BIBA data integrity policy
-#options MAC_BSDEXTENDED # File system firewall policy
-#options MAC_IFOFF # Network interface silencing policy
-#options MAC_LOMAC # Low-watermark data integrity policy
-#options MAC_MLS # Multi-level confidentiality policy
-#options MAC_NONE # NULL policy
-#options MAC_PARTITION # Process partition policy
-#options MAC_PORTACL # Network port access control policy
-#options MAC_SEEOTHERUIDS # UID visibility policy
-#options MAC_STUB # Stub policy
-#options MAC_TEST # Testing policy for the MAC framework
diff --git a/sys/powerpc/conf/GENERIC b/sys/powerpc/conf/GENERIC
index 819d768..2f9b264 100644
--- a/sys/powerpc/conf/GENERIC
+++ b/sys/powerpc/conf/GENERIC
@@ -64,6 +64,7 @@ options SYSVSEM #SYSV-style semaphores
options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions
options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4)
options AUDIT # Security event auditing
+options MAC # TrustedBSD MAC Framework
# Debugging for use in -current
options KDB #Enable the kernel debugger
diff --git a/sys/powerpc/conf/MAC b/sys/powerpc/conf/MAC
deleted file mode 100644
index 8626383..0000000
--- a/sys/powerpc/conf/MAC
+++ /dev/null
@@ -1,28 +0,0 @@
-# MAC -- Generic kernel configuration file for FreeBSD/powerpc MAC
-#
-# The Mandatory Access Control, or MAC, framework allows administrators to
-# finely control system security by providing for a loadable security pol-
-# icy architecture.
-#
-# For more information see:
-#
-# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/mac.html
-#
-# $FreeBSD$
-
-include GENERIC
-ident MAC
-
-options MAC
-
-#options MAC_BIBA # BIBA data integrity policy
-#options MAC_BSDEXTENDED # File system firewall policy
-#options MAC_IFOFF # Network interface silencing policy
-#options MAC_LOMAC # Low-watermark data integrity policy
-#options MAC_MLS # Multi-level confidentiality policy
-#options MAC_NONE # NULL policy
-#options MAC_PARTITION # Process partition policy
-#options MAC_PORTACL # Network port access control policy
-#options MAC_SEEOTHERUIDS # UID visibility policy
-#options MAC_STUB # Stub policy
-#options MAC_TEST # Testing policy for the MAC framework
diff --git a/sys/rpc/svc_vc.c b/sys/rpc/svc_vc.c
index 9f6a4a4..be366de 100644
--- a/sys/rpc/svc_vc.c
+++ b/sys/rpc/svc_vc.c
@@ -271,9 +271,7 @@ svc_vc_accept(struct socket *head, struct socket **sop)
goto done;
}
#ifdef MAC
- SOCK_LOCK(head);
error = mac_socket_check_accept(td->td_ucred, head);
- SOCK_UNLOCK(head);
if (error != 0)
goto done;
#endif
diff --git a/sys/security/mac/mac_atalk.c b/sys/security/mac/mac_atalk.c
index 7ca338e..18bbb8d 100644
--- a/sys/security/mac/mac_atalk.c
+++ b/sys/security/mac/mac_atalk.c
@@ -61,6 +61,9 @@ mac_netatalk_aarp_send(struct ifnet *ifp, struct mbuf *m)
{
struct label *mlabel;
+ if (mac_policy_count == 0)
+ return;
+
mlabel = mac_mbuf_to_label(m);
MAC_IFNET_LOCK(ifp);
diff --git a/sys/security/mac/mac_framework.c b/sys/security/mac/mac_framework.c
index 6f675cb..1f43c02 100644
--- a/sys/security/mac/mac_framework.c
+++ b/sys/security/mac/mac_framework.c
@@ -179,6 +179,7 @@ static struct sx mac_policy_sx; /* Sleeping entry points. */
struct mac_policy_list_head mac_policy_list;
struct mac_policy_list_head mac_static_policy_list;
+u_int mac_policy_count; /* Registered policy count. */
static void mac_policy_xlock(void);
static void mac_policy_xlock_assert(void);
@@ -289,8 +290,8 @@ mac_init(void)
mac_labelzone_init();
#ifndef MAC_STATIC
- rm_init(&mac_policy_rm, "mac_policy_rm");
- sx_init(&mac_policy_sx, "mac_policy_sx");
+ rm_init_flags(&mac_policy_rm, "mac_policy_rm", RM_NOWITNESS);
+ sx_init_flags(&mac_policy_sx, "mac_policy_sx", SX_NOWITNESS);
#endif
}
@@ -351,17 +352,22 @@ mac_policy_getlabeled(struct mac_policy_conf *mpc)
* requiring labels across all policies.
*/
static void
-mac_policy_updateflags(void)
+mac_policy_update(void)
{
struct mac_policy_conf *mpc;
mac_policy_xlock_assert();
mac_labeled = 0;
- LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list)
+ mac_policy_count = 0;
+ LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) {
mac_labeled |= mac_policy_getlabeled(mpc);
- LIST_FOREACH(mpc, &mac_policy_list, mpc_list)
+ mac_policy_count++;
+ }
+ LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {
mac_labeled |= mac_policy_getlabeled(mpc);
+ mac_policy_count++;
+ }
}
static int
@@ -434,7 +440,7 @@ mac_policy_register(struct mac_policy_conf *mpc)
*/
if (mpc->mpc_ops->mpo_init != NULL)
(*(mpc->mpc_ops->mpo_init))(mpc);
- mac_policy_updateflags();
+ mac_policy_update();
SDT_PROBE(mac, kernel, policy, register, mpc, 0, 0, 0, 0);
printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname,
@@ -480,7 +486,7 @@ mac_policy_unregister(struct mac_policy_conf *mpc)
LIST_REMOVE(mpc, mpc_list);
mpc->mpc_runtime_flags &= ~MPC_RUNTIME_FLAG_REGISTERED;
- mac_policy_updateflags();
+ mac_policy_update();
mac_policy_xunlock();
SDT_PROBE(mac, kernel, policy, unregister, mpc, 0, 0, 0, 0);
diff --git a/sys/security/mac/mac_inet.c b/sys/security/mac/mac_inet.c
index fd2c629..5753bb6 100644
--- a/sys/security/mac/mac_inet.c
+++ b/sys/security/mac/mac_inet.c
@@ -193,6 +193,9 @@ mac_ipq_reassemble(struct ipq *q, struct mbuf *m)
{
struct label *label;
+ if (mac_policy_count == 0)
+ return;
+
label = mac_mbuf_to_label(m);
MAC_POLICY_PERFORM_NOSLEEP(ipq_reassemble, q, q->ipq_label, m,
@@ -204,6 +207,9 @@ mac_netinet_fragment(struct mbuf *m, struct mbuf *frag)
{
struct label *mlabel, *fraglabel;
+ if (mac_policy_count == 0)
+ return;
+
mlabel = mac_mbuf_to_label(m);
fraglabel = mac_mbuf_to_label(frag);
@@ -216,6 +222,9 @@ mac_ipq_create(struct mbuf *m, struct ipq *q)
{
struct label *label;
+ if (mac_policy_count == 0)
+ return;
+
label = mac_mbuf_to_label(m);
MAC_POLICY_PERFORM_NOSLEEP(ipq_create, m, label, q, q->ipq_label);
@@ -227,6 +236,10 @@ mac_inpcb_create_mbuf(struct inpcb *inp, struct mbuf *m)
struct label *mlabel;
INP_LOCK_ASSERT(inp);
+
+ if (mac_policy_count == 0)
+ return;
+
mlabel = mac_mbuf_to_label(m);
MAC_POLICY_PERFORM_NOSLEEP(inpcb_create_mbuf, inp, inp->inp_label, m,
@@ -239,6 +252,9 @@ mac_ipq_match(struct mbuf *m, struct ipq *q)
struct label *label;
int result;
+ if (mac_policy_count == 0)
+ return (1);
+
label = mac_mbuf_to_label(m);
result = 1;
@@ -252,6 +268,9 @@ mac_netinet_arp_send(struct ifnet *ifp, struct mbuf *m)
{
struct label *mlabel;
+ if (mac_policy_count == 0)
+ return;
+
mlabel = mac_mbuf_to_label(m);
MAC_IFNET_LOCK(ifp);
@@ -265,6 +284,9 @@ mac_netinet_icmp_reply(struct mbuf *mrecv, struct mbuf *msend)
{
struct label *mrecvlabel, *msendlabel;
+ if (mac_policy_count == 0)
+ return;
+
mrecvlabel = mac_mbuf_to_label(mrecv);
msendlabel = mac_mbuf_to_label(msend);
@@ -277,6 +299,9 @@ mac_netinet_icmp_replyinplace(struct mbuf *m)
{
struct label *label;
+ if (mac_policy_count == 0)
+ return;
+
label = mac_mbuf_to_label(m);
MAC_POLICY_PERFORM_NOSLEEP(netinet_icmp_replyinplace, m, label);
@@ -287,6 +312,9 @@ mac_netinet_igmp_send(struct ifnet *ifp, struct mbuf *m)
{
struct label *mlabel;
+ if (mac_policy_count == 0)
+ return;
+
mlabel = mac_mbuf_to_label(m);
MAC_IFNET_LOCK(ifp);
@@ -300,6 +328,9 @@ mac_netinet_tcp_reply(struct mbuf *m)
{
struct label *label;
+ if (mac_policy_count == 0)
+ return;
+
label = mac_mbuf_to_label(m);
MAC_POLICY_PERFORM_NOSLEEP(netinet_tcp_reply, m, label);
@@ -310,6 +341,9 @@ mac_ipq_update(struct mbuf *m, struct ipq *q)
{
struct label *label;
+ if (mac_policy_count == 0)
+ return;
+
label = mac_mbuf_to_label(m);
MAC_POLICY_PERFORM_NOSLEEP(ipq_update, m, label, q, q->ipq_label);
@@ -326,6 +360,9 @@ mac_inpcb_check_deliver(struct inpcb *inp, struct mbuf *m)
M_ASSERTPKTHDR(m);
+ if (mac_policy_count == 0)
+ return (0);
+
label = mac_mbuf_to_label(m);
MAC_POLICY_CHECK_NOSLEEP(inpcb_check_deliver, inp, inp->inp_label, m,
@@ -371,6 +408,9 @@ mac_netinet_firewall_reply(struct mbuf *mrecv, struct mbuf *msend)
M_ASSERTPKTHDR(mrecv);
M_ASSERTPKTHDR(msend);
+ if (mac_policy_count == 0)
+ return;
+
mrecvlabel = mac_mbuf_to_label(mrecv);
msendlabel = mac_mbuf_to_label(msend);
@@ -385,6 +425,9 @@ mac_netinet_firewall_send(struct mbuf *m)
M_ASSERTPKTHDR(m);
+ if (mac_policy_count == 0)
+ return;
+
label = mac_mbuf_to_label(m);
MAC_POLICY_PERFORM_NOSLEEP(netinet_firewall_send, m, label);
@@ -455,6 +498,9 @@ mac_syncache_create_mbuf(struct label *sc_label, struct mbuf *m)
M_ASSERTPKTHDR(m);
+ if (mac_policy_count == 0)
+ return;
+
mlabel = mac_mbuf_to_label(m);
MAC_POLICY_PERFORM_NOSLEEP(syncache_create_mbuf, sc_label, m,
diff --git a/sys/security/mac/mac_inet6.c b/sys/security/mac/mac_inet6.c
index be26a9d..a080a74 100644
--- a/sys/security/mac/mac_inet6.c
+++ b/sys/security/mac/mac_inet6.c
@@ -118,6 +118,9 @@ mac_ip6q_reassemble(struct ip6q *q6, struct mbuf *m)
{
struct label *label;
+ if (mac_policy_count == 0)
+ return;
+
label = mac_mbuf_to_label(m);
MAC_POLICY_PERFORM_NOSLEEP(ip6q_reassemble, q6, q6->ip6q_label, m,
@@ -129,6 +132,9 @@ mac_ip6q_create(struct mbuf *m, struct ip6q *q6)
{
struct label *label;
+ if (mac_policy_count == 0)
+ return;
+
label = mac_mbuf_to_label(m);
MAC_POLICY_PERFORM_NOSLEEP(ip6q_create, m, label, q6,
@@ -141,6 +147,9 @@ mac_ip6q_match(struct mbuf *m, struct ip6q *q6)
struct label *label;
int result;
+ if (mac_policy_count == 0)
+ return (1);
+
label = mac_mbuf_to_label(m);
result = 1;
@@ -155,6 +164,9 @@ mac_ip6q_update(struct mbuf *m, struct ip6q *q6)
{
struct label *label;
+ if (mac_policy_count == 0)
+ return;
+
label = mac_mbuf_to_label(m);
MAC_POLICY_PERFORM_NOSLEEP(ip6q_update, m, label, q6,
@@ -166,6 +178,9 @@ mac_netinet6_nd6_send(struct ifnet *ifp, struct mbuf *m)
{
struct label *mlabel;
+ if (mac_policy_count == 0)
+ return;
+
mlabel = mac_mbuf_to_label(m);
MAC_POLICY_PERFORM_NOSLEEP(netinet6_nd6_send, ifp, ifp->if_label, m,
diff --git a/sys/security/mac/mac_internal.h b/sys/security/mac/mac_internal.h
index 45bd524..39fc404 100644
--- a/sys/security/mac/mac_internal.h
+++ b/sys/security/mac/mac_internal.h
@@ -189,6 +189,7 @@ struct label {
*/
extern struct mac_policy_list_head mac_policy_list;
extern struct mac_policy_list_head mac_static_policy_list;
+extern u_int mac_policy_count;
extern uint64_t mac_labeled;
extern struct mtx mac_ifnet_mtx;
diff --git a/sys/security/mac/mac_net.c b/sys/security/mac/mac_net.c
index ecd4195..ed33885 100644
--- a/sys/security/mac/mac_net.c
+++ b/sys/security/mac/mac_net.c
@@ -258,6 +258,9 @@ mac_mbuf_copy(struct mbuf *m_from, struct mbuf *m_to)
{
struct label *src_label, *dest_label;
+ if (mac_policy_count == 0)
+ return;
+
src_label = mac_mbuf_to_label(m_from);
dest_label = mac_mbuf_to_label(m_to);
@@ -296,6 +299,9 @@ void
mac_ifnet_create(struct ifnet *ifp)
{
+ if (mac_policy_count == 0)
+ return;
+
MAC_IFNET_LOCK(ifp);
MAC_POLICY_PERFORM_NOSLEEP(ifnet_create, ifp, ifp->if_label);
MAC_IFNET_UNLOCK(ifp);
@@ -315,6 +321,9 @@ mac_bpfdesc_create_mbuf(struct bpf_d *d, struct mbuf *m)
BPFD_LOCK_ASSERT(d);
+ if (mac_policy_count == 0)
+ return;
+
label = mac_mbuf_to_label(m);
MAC_POLICY_PERFORM_NOSLEEP(bpfdesc_create_mbuf, d, d->bd_label, m,
@@ -326,6 +335,9 @@ mac_ifnet_create_mbuf(struct ifnet *ifp, struct mbuf *m)
{
struct label *label;
+ if (mac_policy_count == 0)
+ return;
+
label = mac_mbuf_to_label(m);
MAC_IFNET_LOCK(ifp);
@@ -344,6 +356,9 @@ mac_bpfdesc_check_receive(struct bpf_d *d, struct ifnet *ifp)
BPFD_LOCK_ASSERT(d);
+ if (mac_policy_count == 0)
+ return (0);
+
MAC_IFNET_LOCK(ifp);
MAC_POLICY_CHECK_NOSLEEP(bpfdesc_check_receive, d, d->bd_label, ifp,
ifp->if_label);
@@ -364,6 +379,9 @@ mac_ifnet_check_transmit(struct ifnet *ifp, struct mbuf *m)
M_ASSERTPKTHDR(m);
+ if (mac_policy_count == 0)
+ return (0);
+
label = mac_mbuf_to_label(m);
MAC_IFNET_LOCK(ifp);
diff --git a/sys/security/mac/mac_socket.c b/sys/security/mac/mac_socket.c
index 25f8dae..11d5e05 100644
--- a/sys/security/mac/mac_socket.c
+++ b/sys/security/mac/mac_socket.c
@@ -88,6 +88,16 @@ __FBSDID("$FreeBSD$");
* remote socket for UNIX domain sockets rather than keeping a local copy on
* this endpoint, but be cached and updated based on packets received for
* TCP/IP.
+ *
+ * Unlike with many other object types, the lock protecting MAC labels on
+ * sockets (the socket lock) is not frequently held at the points in code
+ * where socket-related checks are called. The MAC Framework acquires the
+ * lock over some entry points in order to enforce atomicity (such as label
+ * copies) but in other cases the policy modules will have to acquire the
+ * lock themselves if they use labels. This approach (a) avoids lock
+ * acquisitions when policies don't require labels and (b) solves a number of
+ * potential lock order issues when multiple sockets are used in the same
+ * entry point.
*/
struct label *
@@ -234,8 +244,6 @@ void
mac_socket_newconn(struct socket *oldso, struct socket *newso)
{
- SOCK_LOCK_ASSERT(oldso);
-
MAC_POLICY_PERFORM_NOSLEEP(socket_newconn, oldso, oldso->so_label,
newso, newso->so_label);
}
@@ -256,7 +264,8 @@ mac_socketpeer_set_from_mbuf(struct mbuf *m, struct socket *so)
{
struct label *label;
- SOCK_LOCK_ASSERT(so);
+ if (mac_policy_count == 0)
+ return;
label = mac_mbuf_to_label(m);
@@ -267,12 +276,10 @@ mac_socketpeer_set_from_mbuf(struct mbuf *m, struct socket *so)
void
mac_socketpeer_set_from_socket(struct socket *oldso, struct socket *newso)
{
+
+ if (mac_policy_count == 0)
+ return;
- /*
- * XXXRW: only hold the socket lock on one at a time, as one socket
- * is the original, and one is the new. However, it's called in both
- * directions, so we can't assert the lock here currently.
- */
MAC_POLICY_PERFORM_NOSLEEP(socketpeer_set_from_socket, oldso,
oldso->so_label, newso, newso->so_peerlabel);
}
@@ -282,7 +289,8 @@ mac_socket_create_mbuf(struct socket *so, struct mbuf *m)
{
struct label *label;
- SOCK_LOCK_ASSERT(so);
+ if (mac_policy_count == 0)
+ return;
label = mac_mbuf_to_label(m);
@@ -298,8 +306,6 @@ mac_socket_check_accept(struct ucred *cred, struct socket *so)
{
int error;
- SOCK_LOCK_ASSERT(so);
-
MAC_POLICY_CHECK_NOSLEEP(socket_check_accept, cred, so,
so->so_label);
MAC_CHECK_PROBE2(socket_check_accept, error, cred, so);
@@ -316,8 +322,6 @@ mac_socket_check_bind(struct ucred *cred, struct socket *so,
{
int error;
- SOCK_LOCK_ASSERT(so);
-
MAC_POLICY_CHECK_NOSLEEP(socket_check_bind, cred, so, so->so_label,
sa);
MAC_CHECK_PROBE3(socket_check_bind, error, cred, so, sa);
@@ -334,8 +338,6 @@ mac_socket_check_connect(struct ucred *cred, struct socket *so,
{
int error;
- SOCK_LOCK_ASSERT(so);
-
MAC_POLICY_CHECK_NOSLEEP(socket_check_connect, cred, so,
so->so_label, sa);
MAC_CHECK_PROBE3(socket_check_connect, error, cred, so, sa);
@@ -368,7 +370,8 @@ mac_socket_check_deliver(struct socket *so, struct mbuf *m)
struct label *label;
int error;
- SOCK_LOCK_ASSERT(so);
+ if (mac_policy_count == 0)
+ return (0);
label = mac_mbuf_to_label(m);
@@ -387,8 +390,6 @@ mac_socket_check_listen(struct ucred *cred, struct socket *so)
{
int error;
- SOCK_LOCK_ASSERT(so);
-
MAC_POLICY_CHECK_NOSLEEP(socket_check_listen, cred, so,
so->so_label);
MAC_CHECK_PROBE2(socket_check_listen, error, cred, so);
@@ -404,8 +405,6 @@ mac_socket_check_poll(struct ucred *cred, struct socket *so)
{
int error;
- SOCK_LOCK_ASSERT(so);
-
MAC_POLICY_CHECK_NOSLEEP(socket_check_poll, cred, so, so->so_label);
MAC_CHECK_PROBE2(socket_check_poll, error, cred, so);
@@ -420,8 +419,6 @@ mac_socket_check_receive(struct ucred *cred, struct socket *so)
{
int error;
- SOCK_LOCK_ASSERT(so);
-
MAC_POLICY_CHECK_NOSLEEP(socket_check_receive, cred, so,
so->so_label);
MAC_CHECK_PROBE2(socket_check_receive, error, cred, so);
@@ -455,8 +452,6 @@ mac_socket_check_send(struct ucred *cred, struct socket *so)
{
int error;
- SOCK_LOCK_ASSERT(so);
-
MAC_POLICY_CHECK_NOSLEEP(socket_check_send, cred, so, so->so_label);
MAC_CHECK_PROBE2(socket_check_send, error, cred, so);
@@ -471,8 +466,6 @@ mac_socket_check_stat(struct ucred *cred, struct socket *so)
{
int error;
- SOCK_LOCK_ASSERT(so);
-
MAC_POLICY_CHECK_NOSLEEP(socket_check_stat, cred, so, so->so_label);
MAC_CHECK_PROBE2(socket_check_stat, error, cred, so);
@@ -487,8 +480,6 @@ mac_socket_check_visible(struct ucred *cred, struct socket *so)
{
int error;
- SOCK_LOCK_ASSERT(so);
-
MAC_POLICY_CHECK_NOSLEEP(socket_check_visible, cred, so,
so->so_label);
MAC_CHECK_PROBE2(socket_check_visible, error, cred, so);
diff --git a/sys/security/mac_biba/mac_biba.c b/sys/security/mac_biba/mac_biba.c
index 97c3cbe..2c6ada1 100644
--- a/sys/security/mac_biba/mac_biba.c
+++ b/sys/security/mac_biba/mac_biba.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1999-2002, 2007-2008 Robert N. M. Watson
+ * Copyright (c) 1999-2002, 2007-2009 Robert N. M. Watson
* Copyright (c) 2001-2005 McAfee, Inc.
* Copyright (c) 2006 SPARTA, Inc.
* All rights reserved.
@@ -125,7 +125,7 @@ SYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RW, &ptys_equal,
0, "Label pty devices as biba/equal on create");
TUNABLE_INT("security.mac.biba.ptys_equal", &ptys_equal);
-static int interfaces_equal;
+static int interfaces_equal = 1;
SYSCTL_INT(_security_mac_biba, OID_AUTO, interfaces_equal, CTLFLAG_RW,
&interfaces_equal, 0, "Label network interfaces as biba/equal on create");
TUNABLE_INT("security.mac.biba.interfaces_equal", &interfaces_equal);
@@ -1177,7 +1177,9 @@ biba_inpcb_create(struct socket *so, struct label *solabel,
source = SLOT(solabel);
dest = SLOT(inplabel);
+ SOCK_LOCK(so);
biba_copy_effective(source, dest);
+ SOCK_UNLOCK(so);
}
static void
@@ -1198,6 +1200,8 @@ biba_inpcb_sosetlabel(struct socket *so, struct label *solabel,
{
struct mac_biba *source, *dest;
+ SOCK_LOCK_ASSERT(so);
+
source = SLOT(solabel);
dest = SLOT(inplabel);
@@ -1918,6 +1922,7 @@ biba_socket_check_deliver(struct socket *so, struct label *solabel,
struct mbuf *m, struct label *mlabel)
{
struct mac_biba *p, *s;
+ int error;
if (!biba_enabled)
return (0);
@@ -1925,7 +1930,10 @@ biba_socket_check_deliver(struct socket *so, struct label *solabel,
p = SLOT(mlabel);
s = SLOT(solabel);
- return (biba_equal_effective(p, s) ? 0 : EACCES);
+ SOCK_LOCK(so);
+ error = biba_equal_effective(p, s) ? 0 : EACCES;
+ SOCK_UNLOCK(so);
+ return (error);
}
static int
@@ -1935,6 +1943,8 @@ biba_socket_check_relabel(struct ucred *cred, struct socket *so,
struct mac_biba *subj, *obj, *new;
int error;
+ SOCK_LOCK_ASSERT(so);
+
new = SLOT(newlabel);
subj = SLOT(cred->cr_label);
obj = SLOT(solabel);
@@ -1991,8 +2001,12 @@ biba_socket_check_visible(struct ucred *cred, struct socket *so,
subj = SLOT(cred->cr_label);
obj = SLOT(solabel);
- if (!biba_dominate_effective(obj, subj))
+ SOCK_LOCK(so);
+ if (!biba_dominate_effective(obj, subj)) {
+ SOCK_UNLOCK(so);
return (ENOENT);
+ }
+ SOCK_UNLOCK(so);
return (0);
}
@@ -2018,19 +2032,26 @@ biba_socket_create_mbuf(struct socket *so, struct label *solabel,
source = SLOT(solabel);
dest = SLOT(mlabel);
+ SOCK_LOCK(so);
biba_copy_effective(source, dest);
+ SOCK_UNLOCK(so);
}
static void
biba_socket_newconn(struct socket *oldso, struct label *oldsolabel,
struct socket *newso, struct label *newsolabel)
{
- struct mac_biba *source, *dest;
+ struct mac_biba source, *dest;
+
+ SOCK_LOCK(oldso);
+ source = *SLOT(oldsolabel);
+ SOCK_UNLOCK(oldso);
- source = SLOT(oldsolabel);
dest = SLOT(newsolabel);
- biba_copy_effective(source, dest);
+ SOCK_LOCK(newso);
+ biba_copy_effective(&source, dest);
+ SOCK_UNLOCK(newso);
}
static void
@@ -2039,6 +2060,8 @@ biba_socket_relabel(struct ucred *cred, struct socket *so,
{
struct mac_biba *source, *dest;
+ SOCK_LOCK_ASSERT(so);
+
source = SLOT(newlabel);
dest = SLOT(solabel);
@@ -2054,7 +2077,9 @@ biba_socketpeer_set_from_mbuf(struct mbuf *m, struct label *mlabel,
source = SLOT(mlabel);
dest = SLOT(sopeerlabel);
+ SOCK_LOCK(so);
biba_copy_effective(source, dest);
+ SOCK_UNLOCK(so);
}
static void
@@ -2062,12 +2087,16 @@ biba_socketpeer_set_from_socket(struct socket *oldso,
struct label *oldsolabel, struct socket *newso,
struct label *newsopeerlabel)
{
- struct mac_biba *source, *dest;
+ struct mac_biba source, *dest;
- source = SLOT(oldsolabel);
+ SOCK_LOCK(oldso);
+ source = *SLOT(oldsolabel);
+ SOCK_UNLOCK(oldso);
dest = SLOT(newsopeerlabel);
- biba_copy_effective(source, dest);
+ SOCK_LOCK(newso);
+ biba_copy_effective(&source, dest);
+ SOCK_UNLOCK(newso);
}
static void
diff --git a/sys/security/mac_lomac/mac_lomac.c b/sys/security/mac_lomac/mac_lomac.c
index ab41c0a..2359b42 100644
--- a/sys/security/mac_lomac/mac_lomac.c
+++ b/sys/security/mac_lomac/mac_lomac.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1999-2002, 2007-2008 Robert N. M. Watson
+ * Copyright (c) 1999-2002, 2007-2009 Robert N. M. Watson
* Copyright (c) 2001-2005 Networks Associates Technology, Inc.
* Copyright (c) 2006 SPARTA, Inc.
* All rights reserved.
@@ -1315,6 +1315,8 @@ lomac_inpcb_sosetlabel(struct socket *so, struct label *solabel,
{
struct mac_lomac *source, *dest;
+ SOCK_LOCK_ASSERT(so);
+
source = SLOT(solabel);
dest = SLOT(inplabel);
@@ -1930,6 +1932,7 @@ lomac_socket_check_deliver(struct socket *so, struct label *solabel,
struct mbuf *m, struct label *mlabel)
{
struct mac_lomac *p, *s;
+ int error;
if (!lomac_enabled)
return (0);
@@ -1937,7 +1940,10 @@ lomac_socket_check_deliver(struct socket *so, struct label *solabel,
p = SLOT(mlabel);
s = SLOT(solabel);
- return (lomac_equal_single(p, s) ? 0 : EACCES);
+ SOCK_LOCK(so);
+ error = lomac_equal_single(p, s) ? 0 : EACCES;
+ SOCK_UNLOCK(so);
+ return (error);
}
static int
@@ -1947,6 +1953,8 @@ lomac_socket_check_relabel(struct ucred *cred, struct socket *so,
struct mac_lomac *subj, *obj, *new;
int error;
+ SOCK_LOCK_ASSERT(so);
+
new = SLOT(newlabel);
subj = SLOT(cred->cr_label);
obj = SLOT(solabel);
@@ -2003,8 +2011,12 @@ lomac_socket_check_visible(struct ucred *cred, struct socket *so,
subj = SLOT(cred->cr_label);
obj = SLOT(solabel);
- if (!lomac_dominate_single(obj, subj))
+ SOCK_LOCK(so);
+ if (!lomac_dominate_single(obj, subj)) {
+ SOCK_UNLOCK(so);
return (ENOENT);
+ }
+ SOCK_UNLOCK(so);
return (0);
}
@@ -2030,19 +2042,26 @@ lomac_socket_create_mbuf(struct socket *so, struct label *solabel,
source = SLOT(solabel);
dest = SLOT(mlabel);
+ SOCK_LOCK(so);
lomac_copy_single(source, dest);
+ SOCK_UNLOCK(so);
}
static void
lomac_socket_newconn(struct socket *oldso, struct label *oldsolabel,
struct socket *newso, struct label *newsolabel)
{
- struct mac_lomac *source, *dest;
+ struct mac_lomac source, *dest;
+
+ SOCK_LOCK(oldso);
+ source = *SLOT(oldsolabel);
+ SOCK_UNLOCK(oldso);
- source = SLOT(oldsolabel);
dest = SLOT(newsolabel);
- lomac_copy_single(source, dest);
+ SOCK_LOCK(newso);
+ lomac_copy_single(&source, dest);
+ SOCK_UNLOCK(newso);
}
static void
@@ -2051,6 +2070,8 @@ lomac_socket_relabel(struct ucred *cred, struct socket *so,
{
struct mac_lomac *source, *dest;
+ SOCK_LOCK_ASSERT(so);
+
source = SLOT(newlabel);
dest = SLOT(solabel);
@@ -2066,7 +2087,9 @@ lomac_socketpeer_set_from_mbuf(struct mbuf *m, struct label *mlabel,
source = SLOT(mlabel);
dest = SLOT(sopeerlabel);
+ SOCK_LOCK(so);
lomac_copy_single(source, dest);
+ SOCK_UNLOCK(so);
}
static void
@@ -2074,12 +2097,17 @@ lomac_socketpeer_set_from_socket(struct socket *oldso,
struct label *oldsolabel, struct socket *newso,
struct label *newsopeerlabel)
{
- struct mac_lomac *source, *dest;
+ struct mac_lomac source, *dest;
+
+ SOCK_LOCK(oldso);
+ source = *SLOT(oldsolabel);
+ SOCK_UNLOCK(oldso);
- source = SLOT(oldsolabel);
dest = SLOT(newsopeerlabel);
- lomac_copy_single(source, dest);
+ SOCK_LOCK(newso);
+ lomac_copy_single(&source, dest);
+ SOCK_UNLOCK(newso);
}
static void
diff --git a/sys/security/mac_mls/mac_mls.c b/sys/security/mac_mls/mac_mls.c
index 6d13505..a0669c7 100644
--- a/sys/security/mac_mls/mac_mls.c
+++ b/sys/security/mac_mls/mac_mls.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1999-2002, 2007-2008 Robert N. M. Watson
+ * Copyright (c) 1999-2002, 2007-2009 Robert N. M. Watson
* Copyright (c) 2001-2005 McAfee, Inc.
* Copyright (c) 2006 SPARTA, Inc.
* All rights reserved.
@@ -1116,6 +1116,8 @@ mls_inpcb_sosetlabel(struct socket *so, struct label *solabel,
{
struct mac_mls *source, *dest;
+ SOCK_LOCK_ASSERT(so);
+
source = SLOT(solabel);
dest = SLOT(inplabel);
@@ -1623,6 +1625,7 @@ mls_socket_check_deliver(struct socket *so, struct label *solabel,
struct mbuf *m, struct label *mlabel)
{
struct mac_mls *p, *s;
+ int error;
if (!mls_enabled)
return (0);
@@ -1630,7 +1633,11 @@ mls_socket_check_deliver(struct socket *so, struct label *solabel,
p = SLOT(mlabel);
s = SLOT(solabel);
- return (mls_equal_effective(p, s) ? 0 : EACCES);
+ SOCK_LOCK(so);
+ error = mls_equal_effective(p, s) ? 0 : EACCES;
+ SOCK_UNLOCK(so);
+
+ return (error);
}
static int
@@ -1640,6 +1647,8 @@ mls_socket_check_relabel(struct ucred *cred, struct socket *so,
struct mac_mls *subj, *obj, *new;
int error;
+ SOCK_LOCK_ASSERT(so);
+
new = SLOT(newlabel);
subj = SLOT(cred->cr_label);
obj = SLOT(solabel);
@@ -1696,8 +1705,12 @@ mls_socket_check_visible(struct ucred *cred, struct socket *so,
subj = SLOT(cred->cr_label);
obj = SLOT(solabel);
- if (!mls_dominate_effective(subj, obj))
+ SOCK_LOCK(so);
+ if (!mls_dominate_effective(subj, obj)) {
+ SOCK_UNLOCK(so);
return (ENOENT);
+ }
+ SOCK_UNLOCK(so);
return (0);
}
@@ -1723,19 +1736,26 @@ mls_socket_create_mbuf(struct socket *so, struct label *solabel,
source = SLOT(solabel);
dest = SLOT(mlabel);
+ SOCK_LOCK(so);
mls_copy_effective(source, dest);
+ SOCK_UNLOCK(so);
}
static void
mls_socket_newconn(struct socket *oldso, struct label *oldsolabel,
struct socket *newso, struct label *newsolabel)
{
- struct mac_mls *source, *dest;
+ struct mac_mls source, *dest;
+
+ SOCK_LOCK(oldso);
+ source = *SLOT(oldsolabel);
+ SOCK_UNLOCK(oldso);
- source = SLOT(oldsolabel);
dest = SLOT(newsolabel);
- mls_copy_effective(source, dest);
+ SOCK_LOCK(newso);
+ mls_copy_effective(&source, dest);
+ SOCK_UNLOCK(newso);
}
static void
@@ -1744,6 +1764,8 @@ mls_socket_relabel(struct ucred *cred, struct socket *so,
{
struct mac_mls *source, *dest;
+ SOCK_LOCK_ASSERT(so);
+
source = SLOT(newlabel);
dest = SLOT(solabel);
@@ -1759,7 +1781,9 @@ mls_socketpeer_set_from_mbuf(struct mbuf *m, struct label *mlabel,
source = SLOT(mlabel);
dest = SLOT(sopeerlabel);
+ SOCK_LOCK(so);
mls_copy_effective(source, dest);
+ SOCK_UNLOCK(so);
}
static void
@@ -1767,12 +1791,17 @@ mls_socketpeer_set_from_socket(struct socket *oldso,
struct label *oldsolabel, struct socket *newso,
struct label *newsopeerlabel)
{
- struct mac_mls *source, *dest;
+ struct mac_mls source, *dest;
+
+ SOCK_LOCK(oldso);
+ source = *SLOT(oldsolabel);
+ SOCK_UNLOCK(oldso);
- source = SLOT(oldsolabel);
dest = SLOT(newsopeerlabel);
- mls_copy_effective(source, dest);
+ SOCK_LOCK(newso);
+ mls_copy_effective(&source, dest);
+ SOCK_UNLOCK(newso);
}
static void
diff --git a/sys/security/mac_stub/mac_stub.c b/sys/security/mac_stub/mac_stub.c
index cecf2ea..007efb8 100644
--- a/sys/security/mac_stub/mac_stub.c
+++ b/sys/security/mac_stub/mac_stub.c
@@ -413,6 +413,8 @@ stub_inpcb_sosetlabel(struct socket *so, struct label *solabel,
struct inpcb *inp, struct label *inplabel)
{
+ SOCK_LOCK_ASSERT(so);
+
}
static void
@@ -809,6 +811,11 @@ stub_socket_check_accept(struct ucred *cred, struct socket *so,
struct label *solabel)
{
+#if 0
+ SOCK_LOCK(so);
+ SOCK_UNLOCK(so);
+#endif
+
return (0);
}
@@ -817,6 +824,11 @@ stub_socket_check_bind(struct ucred *cred, struct socket *so,
struct label *solabel, struct sockaddr *sa)
{
+#if 0
+ SOCK_LOCK(so);
+ SOCK_UNLOCK(so);
+#endif
+
return (0);
}
@@ -825,6 +837,11 @@ stub_socket_check_connect(struct ucred *cred, struct socket *so,
struct label *solabel, struct sockaddr *sa)
{
+#if 0
+ SOCK_LOCK(so);
+ SOCK_UNLOCK(so);
+#endif
+
return (0);
}
@@ -840,6 +857,11 @@ stub_socket_check_deliver(struct socket *so, struct label *solabel,
struct mbuf *m, struct label *mlabel)
{
+#if 0
+ SOCK_LOCK(so);
+ SOCK_UNLOCK(so);
+#endif
+
return (0);
}
@@ -848,6 +870,11 @@ stub_socket_check_listen(struct ucred *cred, struct socket *so,
struct label *solabel)
{
+#if 0
+ SOCK_LOCK(so);
+ SOCK_UNLOCK(so);
+#endif
+
return (0);
}
@@ -856,6 +883,11 @@ stub_socket_check_poll(struct ucred *cred, struct socket *so,
struct label *solabel)
{
+#if 0
+ SOCK_LOCK(so);
+ SOCK_UNLOCK(so);
+#endif
+
return (0);
}
@@ -864,6 +896,11 @@ stub_socket_check_receive(struct ucred *cred, struct socket *so,
struct label *solabel)
{
+#if 0
+ SOCK_LOCK(so);
+ SOCK_UNLOCK(so);
+#endif
+
return (0);
}
@@ -872,6 +909,8 @@ stub_socket_check_relabel(struct ucred *cred, struct socket *so,
struct label *solabel, struct label *newlabel)
{
+ SOCK_LOCK_ASSERT(so);
+
return (0);
}
static int
@@ -879,6 +918,11 @@ stub_socket_check_send(struct ucred *cred, struct socket *so,
struct label *solabel)
{
+#if 0
+ SOCK_LOCK(so);
+ SOCK_UNLOCK(so);
+#endif
+
return (0);
}
@@ -887,6 +931,11 @@ stub_socket_check_stat(struct ucred *cred, struct socket *so,
struct label *solabel)
{
+#if 0
+ SOCK_LOCK(so);
+ SOCK_UNLOCK(so);
+#endif
+
return (0);
}
@@ -903,6 +952,11 @@ stub_socket_check_visible(struct ucred *cred, struct socket *so,
struct label *solabel)
{
+#if 0
+ SOCK_LOCK(so);
+ SOCK_UNLOCK(so);
+#endif
+
return (0);
}
@@ -918,6 +972,10 @@ stub_socket_create_mbuf(struct socket *so, struct label *solabel,
struct mbuf *m, struct label *mlabel)
{
+#if 0
+ SOCK_LOCK(so);
+ SOCK_UNLOCK(so);
+#endif
}
static void
@@ -925,6 +983,14 @@ stub_socket_newconn(struct socket *oldso, struct label *oldsolabel,
struct socket *newso, struct label *newsolabel)
{
+#if 0
+ SOCK_LOCK(oldso);
+ SOCK_UNLOCK(oldso);
+#endif
+#if 0
+ SOCK_LOCK(newso);
+ SOCK_UNLOCK(newso);
+#endif
}
static void
@@ -932,6 +998,7 @@ stub_socket_relabel(struct ucred *cred, struct socket *so,
struct label *solabel, struct label *newlabel)
{
+ SOCK_LOCK_ASSERT(so);
}
static void
@@ -939,6 +1006,10 @@ stub_socketpeer_set_from_mbuf(struct mbuf *m, struct label *mlabel,
struct socket *so, struct label *sopeerlabel)
{
+#if 0
+ SOCK_LOCK(so);
+ SOCK_UNLOCK(so);
+#endif
}
static void
@@ -947,6 +1018,14 @@ stub_socketpeer_set_from_socket(struct socket *oldso,
struct label *newsopeerlabel)
{
+#if 0
+ SOCK_LOCK(oldso);
+ SOCK_UNLOCK(oldso);
+#endif
+#if 0
+ SOCK_LOCK(newso);
+ SOCK_UNLOCK(newso);
+#endif
}
static void
diff --git a/sys/security/mac_test/mac_test.c b/sys/security/mac_test/mac_test.c
index 20ca542..bef0cb7 100644
--- a/sys/security/mac_test/mac_test.c
+++ b/sys/security/mac_test/mac_test.c
@@ -671,7 +671,9 @@ test_inpcb_create(struct socket *so, struct label *solabel,
struct inpcb *inp, struct label *inplabel)
{
+ SOCK_LOCK(so);
LABEL_CHECK(solabel, MAGIC_SOCKET);
+ SOCK_UNLOCK(so);
LABEL_CHECK(inplabel, MAGIC_INPCB);
COUNTER_INC(inpcb_create);
}
@@ -717,6 +719,8 @@ test_inpcb_sosetlabel(struct socket *so, struct label *solabel,
struct inpcb *inp, struct label *inplabel)
{
+ SOCK_LOCK_ASSERT(so);
+
LABEL_CHECK(solabel, MAGIC_SOCKET);
LABEL_CHECK(inplabel, MAGIC_INPCB);
COUNTER_INC(inpcb_sosetlabel);
@@ -1526,7 +1530,9 @@ test_socket_check_accept(struct ucred *cred, struct socket *so,
{
LABEL_CHECK(cred->cr_label, MAGIC_CRED);
+ SOCK_LOCK(so);
LABEL_CHECK(solabel, MAGIC_SOCKET);
+ SOCK_UNLOCK(so);
COUNTER_INC(socket_check_accept);
return (0);
@@ -1539,7 +1545,9 @@ test_socket_check_bind(struct ucred *cred, struct socket *so,
{
LABEL_CHECK(cred->cr_label, MAGIC_CRED);
+ SOCK_LOCK(so);
LABEL_CHECK(solabel, MAGIC_SOCKET);
+ SOCK_UNLOCK(so);
COUNTER_INC(socket_check_bind);
return (0);
@@ -1552,7 +1560,9 @@ test_socket_check_connect(struct ucred *cred, struct socket *so,
{
LABEL_CHECK(cred->cr_label, MAGIC_CRED);
+ SOCK_LOCK(so);
LABEL_CHECK(solabel, MAGIC_SOCKET);
+ SOCK_UNLOCK(so);
COUNTER_INC(socket_check_connect);
return (0);
@@ -1564,7 +1574,9 @@ test_socket_check_deliver(struct socket *so, struct label *solabel,
struct mbuf *m, struct label *mlabel)
{
+ SOCK_LOCK(so);
LABEL_CHECK(solabel, MAGIC_SOCKET);
+ SOCK_UNLOCK(so);
LABEL_CHECK(mlabel, MAGIC_MBUF);
COUNTER_INC(socket_check_deliver);
@@ -1578,7 +1590,9 @@ test_socket_check_listen(struct ucred *cred, struct socket *so,
{
LABEL_CHECK(cred->cr_label, MAGIC_CRED);
+ SOCK_LOCK(so);
LABEL_CHECK(solabel, MAGIC_SOCKET);
+ SOCK_UNLOCK(so);
COUNTER_INC(socket_check_listen);
return (0);
@@ -1591,7 +1605,9 @@ test_socket_check_poll(struct ucred *cred, struct socket *so,
{
LABEL_CHECK(cred->cr_label, MAGIC_CRED);
+ SOCK_LOCK(so);
LABEL_CHECK(solabel, MAGIC_SOCKET);
+ SOCK_UNLOCK(so);
COUNTER_INC(socket_check_poll);
return (0);
@@ -1604,7 +1620,9 @@ test_socket_check_receive(struct ucred *cred, struct socket *so,
{
LABEL_CHECK(cred->cr_label, MAGIC_CRED);
+ SOCK_LOCK(so);
LABEL_CHECK(solabel, MAGIC_SOCKET);
+ SOCK_UNLOCK(so);
COUNTER_INC(socket_check_receive);
return (0);
@@ -1616,6 +1634,8 @@ test_socket_check_relabel(struct ucred *cred, struct socket *so,
struct label *solabel, struct label *newlabel)
{
+ SOCK_LOCK_ASSERT(so);
+
LABEL_CHECK(cred->cr_label, MAGIC_CRED);
LABEL_CHECK(solabel, MAGIC_SOCKET);
LABEL_CHECK(newlabel, MAGIC_SOCKET);
@@ -1631,7 +1651,9 @@ test_socket_check_send(struct ucred *cred, struct socket *so,
{
LABEL_CHECK(cred->cr_label, MAGIC_CRED);
+ SOCK_LOCK(so);
LABEL_CHECK(solabel, MAGIC_SOCKET);
+ SOCK_UNLOCK(so);
COUNTER_INC(socket_check_send);
return (0);
@@ -1644,7 +1666,9 @@ test_socket_check_stat(struct ucred *cred, struct socket *so,
{
LABEL_CHECK(cred->cr_label, MAGIC_CRED);
+ SOCK_LOCK(so);
LABEL_CHECK(solabel, MAGIC_SOCKET);
+ SOCK_UNLOCK(so);
COUNTER_INC(socket_check_stat);
return (0);
@@ -1657,7 +1681,9 @@ test_socket_check_visible(struct ucred *cred, struct socket *so,
{
LABEL_CHECK(cred->cr_label, MAGIC_CRED);
+ SOCK_LOCK(so);
LABEL_CHECK(solabel, MAGIC_SOCKET);
+ SOCK_UNLOCK(so);
COUNTER_INC(socket_check_visible);
return (0);
@@ -1686,11 +1712,13 @@ test_socket_create(struct ucred *cred, struct socket *so,
COUNTER_DECL(socket_create_mbuf);
static void
-test_socket_create_mbuf(struct socket *so, struct label *socketlabel,
+test_socket_create_mbuf(struct socket *so, struct label *solabel,
struct mbuf *m, struct label *mlabel)
{
- LABEL_CHECK(socketlabel, MAGIC_SOCKET);
+ SOCK_LOCK(so);
+ LABEL_CHECK(solabel, MAGIC_SOCKET);
+ SOCK_UNLOCK(so);
LABEL_CHECK(mlabel, MAGIC_MBUF);
COUNTER_INC(socket_create_mbuf);
}
@@ -1749,8 +1777,12 @@ test_socket_newconn(struct socket *oldso, struct label *oldsolabel,
struct socket *newso, struct label *newsolabel)
{
+ SOCK_LOCK(oldso);
LABEL_CHECK(oldsolabel, MAGIC_SOCKET);
+ SOCK_UNLOCK(oldso);
+ SOCK_LOCK(newso);
LABEL_CHECK(newsolabel, MAGIC_SOCKET);
+ SOCK_UNLOCK(newso);
COUNTER_INC(socket_newconn);
}
@@ -1760,6 +1792,8 @@ test_socket_relabel(struct ucred *cred, struct socket *so,
struct label *solabel, struct label *newlabel)
{
+ SOCK_LOCK_ASSERT(so);
+
LABEL_CHECK(cred->cr_label, MAGIC_CRED);
LABEL_CHECK(solabel, MAGIC_SOCKET);
LABEL_CHECK(newlabel, MAGIC_SOCKET);
@@ -1805,11 +1839,13 @@ test_socketpeer_init_label(struct label *label, int flag)
COUNTER_DECL(socketpeer_set_from_mbuf);
static void
test_socketpeer_set_from_mbuf(struct mbuf *m, struct label *mlabel,
- struct socket *socket, struct label *socketpeerlabel)
+ struct socket *so, struct label *sopeerlabel)
{
LABEL_CHECK(mlabel, MAGIC_MBUF);
- LABEL_CHECK(socketpeerlabel, MAGIC_SOCKET);
+ SOCK_LOCK(so);
+ LABEL_CHECK(sopeerlabel, MAGIC_SOCKET);
+ SOCK_UNLOCK(so);
COUNTER_INC(socketpeer_set_from_mbuf);
}
@@ -1820,8 +1856,12 @@ test_socketpeer_set_from_socket(struct socket *oldso,
struct label *newsopeerlabel)
{
+ SOCK_LOCK(oldso);
LABEL_CHECK(oldsolabel, MAGIC_SOCKET);
+ SOCK_UNLOCK(oldso);
+ SOCK_LOCK(newso);
LABEL_CHECK(newsopeerlabel, MAGIC_SOCKET);
+ SOCK_UNLOCK(newso);
COUNTER_INC(socketpeer_set_from_socket);
}
diff --git a/sys/sparc64/conf/GENERIC b/sys/sparc64/conf/GENERIC
index a3dad1c..943dc74 100644
--- a/sys/sparc64/conf/GENERIC
+++ b/sys/sparc64/conf/GENERIC
@@ -65,6 +65,7 @@ options SYSVSEM # SYSV-style semaphores
options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4)
options AUDIT # Security event auditing
+options MAC # TrustedBSD MAC Framework
# Debugging for use in -current
options KDB # Enable kernel debugger support.
diff --git a/sys/sparc64/conf/MAC b/sys/sparc64/conf/MAC
deleted file mode 100644
index 56af83d..0000000
--- a/sys/sparc64/conf/MAC
+++ /dev/null
@@ -1,28 +0,0 @@
-# MAC -- Generic kernel configuration file for FreeBSD/sparc64 MAC
-#
-# The Mandatory Access Control, or MAC, framework allows administrators to
-# finely control system security by providing for a loadable security pol-
-# icy architecture.
-#
-# For more information see:
-#
-# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/mac.html
-#
-# $FreeBSD$
-
-include GENERIC
-ident MAC
-
-options MAC
-
-#options MAC_BIBA # BIBA data integrity policy
-#options MAC_BSDEXTENDED # File system firewall policy
-#options MAC_IFOFF # Network interface silencing policy
-#options MAC_LOMAC # Low-watermark data integrity policy
-#options MAC_MLS # Multi-level confidentiality policy
-#options MAC_NONE # NULL policy
-#options MAC_PARTITION # Process partition policy
-#options MAC_PORTACL # Network port access control policy
-#options MAC_SEEOTHERUIDS # UID visibility policy
-#options MAC_STUB # Stub policy
-#options MAC_TEST # Testing policy for the MAC framework
diff --git a/sys/sun4v/conf/GENERIC b/sys/sun4v/conf/GENERIC
index 2291087..438db17 100644
--- a/sys/sun4v/conf/GENERIC
+++ b/sys/sun4v/conf/GENERIC
@@ -66,6 +66,7 @@ options AHC_REG_PRETTY_PRINT # Print register bitfields in debug
options PRINTF_BUFR_SIZE=128 # Prevent printf output being interspersed.
options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4)
options AUDIT # Security event auditing
+options MAC # TrustedBSD MAC Framework
# Debugging for use in -current
options KDB # Enable kernel debugger support.
diff --git a/sys/sun4v/conf/MAC b/sys/sun4v/conf/MAC
deleted file mode 100644
index 56af83d..0000000
--- a/sys/sun4v/conf/MAC
+++ /dev/null
@@ -1,28 +0,0 @@
-# MAC -- Generic kernel configuration file for FreeBSD/sparc64 MAC
-#
-# The Mandatory Access Control, or MAC, framework allows administrators to
-# finely control system security by providing for a loadable security pol-
-# icy architecture.
-#
-# For more information see:
-#
-# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/mac.html
-#
-# $FreeBSD$
-
-include GENERIC
-ident MAC
-
-options MAC
-
-#options MAC_BIBA # BIBA data integrity policy
-#options MAC_BSDEXTENDED # File system firewall policy
-#options MAC_IFOFF # Network interface silencing policy
-#options MAC_LOMAC # Low-watermark data integrity policy
-#options MAC_MLS # Multi-level confidentiality policy
-#options MAC_NONE # NULL policy
-#options MAC_PARTITION # Process partition policy
-#options MAC_PORTACL # Network port access control policy
-#options MAC_SEEOTHERUIDS # UID visibility policy
-#options MAC_STUB # Stub policy
-#options MAC_TEST # Testing policy for the MAC framework
diff --git a/sys/sun4v/include/pcpu.h b/sys/sun4v/include/pcpu.h
index 434f1cd..ec89212 100644
--- a/sys/sun4v/include/pcpu.h
+++ b/sys/sun4v/include/pcpu.h
@@ -39,9 +39,9 @@
struct pmap;
#ifdef KTR
-#define PCPU_MD_FIELDS_PAD (4 - (PCPU_NAME_LEN + 7) / 8)
+#define PCPU_MD_FIELDS_PAD (3 - (PCPU_NAME_LEN + 7) / 8)
#else
-#define PCPU_MD_FIELDS_PAD 4
+#define PCPU_MD_FIELDS_PAD 3
#endif
/*
diff --git a/sys/sys/pmc.h b/sys/sys/pmc.h
index 2be03d1..68d7df0 100644
--- a/sys/sys/pmc.h
+++ b/sys/sys/pmc.h
@@ -709,11 +709,6 @@ struct pmc {
* array. The size of this structure is thus PMC architecture
* dependent.
*
- * TODO: Only process-private counting mode PMCs may be attached to a
- * process different from the allocator process (since we do not have
- * the infrastructure to make sense of an interrupted PC value from a
- * 'target' process (yet)).
- *
*/
struct pmc_targetstate {
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index 3feae69..1e19bb6 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -419,7 +419,7 @@ extern struct vattr va_null; /* predefined null vattr structure */
#define VI_MTX(vp) (&(vp)->v_interlock)
#define VN_LOCK_AREC(vp) \
- ((vp)->v_vnlock->lock_object.lo_flags |= LK_CANRECURSE)
+ ((vp)->v_vnlock->lock_object.lo_flags |= LO_RECURSABLE)
#define VN_LOCK_ASHARE(vp) \
((vp)->v_vnlock->lock_object.lo_flags &= ~LK_NOSHARE)
diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c
index 5d959ac4..195df44 100644
--- a/sys/ufs/ffs/ffs_softdep.c
+++ b/sys/ufs/ffs/ffs_softdep.c
@@ -556,8 +556,8 @@ MTX_SYSINIT(softdep_lock, &lk, "Softdep Lock", MTX_DEF);
#define ACQUIRE_LOCK(lk) mtx_lock(lk)
#define FREE_LOCK(lk) mtx_unlock(lk)
-#define BUF_AREC(bp) ((bp)->b_lock.lock_object.lo_flags |= LK_CANRECURSE)
-#define BUF_NOREC(bp) ((bp)->b_lock.lock_object.lo_flags &= ~LK_CANRECURSE)
+#define BUF_AREC(bp) ((bp)->b_lock.lock_object.lo_flags |= LO_RECURSABLE)
+#define BUF_NOREC(bp) ((bp)->b_lock.lock_object.lo_flags &= ~LO_RECURSABLE)
/*
* Worklist queue management.
diff --git a/sys/ufs/ufs/dirhash.h b/sys/ufs/ufs/dirhash.h
index 9778752..e5978b4 100644
--- a/sys/ufs/ufs/dirhash.h
+++ b/sys/ufs/ufs/dirhash.h
@@ -105,6 +105,8 @@ struct dirhash {
int dh_onlist; /* true if on the ufsdirhash_list chain */
+ time_t dh_lastused; /* time the dirhash was last read or written*/
+
/* Protected by ufsdirhash_mtx. */
TAILQ_ENTRY(dirhash) dh_list; /* chain of all dirhashes */
};
diff --git a/sys/ufs/ufs/ufs_dirhash.c b/sys/ufs/ufs/ufs_dirhash.c
index 3b6d5e1..5066326 100644
--- a/sys/ufs/ufs/ufs_dirhash.c
+++ b/sys/ufs/ufs/ufs_dirhash.c
@@ -49,6 +49,8 @@ __FBSDID("$FreeBSD$");
#include <sys/refcount.h>
#include <sys/sysctl.h>
#include <sys/sx.h>
+#include <sys/eventhandler.h>
+#include <sys/time.h>
#include <vm/uma.h>
#include <ufs/ufs/quota.h>
@@ -81,6 +83,13 @@ SYSCTL_INT(_vfs_ufs, OID_AUTO, dirhash_mem, CTLFLAG_RD, &ufs_dirhashmem,
static int ufs_dirhashcheck = 0;
SYSCTL_INT(_vfs_ufs, OID_AUTO, dirhash_docheck, CTLFLAG_RW, &ufs_dirhashcheck,
0, "enable extra sanity tests");
+static int ufs_dirhashlowmemcount = 0;
+SYSCTL_INT(_vfs_ufs, OID_AUTO, dirhash_lowmemcount, CTLFLAG_RD,
+ &ufs_dirhashlowmemcount, 0, "number of times low memory hook called");
+static int ufs_dirhashreclaimage = 5;
+SYSCTL_INT(_vfs_ufs, OID_AUTO, dirhash_reclaimage, CTLFLAG_RW,
+ &ufs_dirhashreclaimage, 0,
+ "max time in seconds of hash inactivity before deletion in low VM events");
static int ufsdirhash_hash(struct dirhash *dh, char *name, int namelen);
@@ -90,6 +99,7 @@ static int ufsdirhash_findslot(struct dirhash *dh, char *name, int namelen,
doff_t offset);
static doff_t ufsdirhash_getprev(struct direct *dp, doff_t offset);
static int ufsdirhash_recycle(int wanted);
+static void ufsdirhash_lowmem(void);
static void ufsdirhash_free_locked(struct inode *ip);
static uma_zone_t ufsdirhash_zone;
@@ -393,6 +403,7 @@ ufsdirhash_build(struct inode *ip)
dh->dh_seqopt = 0;
dh->dh_seqoff = 0;
dh->dh_score = DH_SCOREINIT;
+ dh->dh_lastused = time_second;
/*
* Use non-blocking mallocs so that we will revert to a linear
@@ -569,6 +580,9 @@ ufsdirhash_lookup(struct inode *ip, char *name, int namelen, doff_t *offp,
/* Update the score. */
if (dh->dh_score < DH_SCOREMAX)
dh->dh_score++;
+
+ /* Update last used time. */
+ dh->dh_lastused = time_second;
DIRHASHLIST_UNLOCK();
vp = ip->i_vnode;
@@ -811,6 +825,9 @@ ufsdirhash_add(struct inode *ip, struct direct *dirp, doff_t offset)
dh->dh_hused++;
DH_ENTRY(dh, slot) = offset;
+ /* Update last used time. */
+ dh->dh_lastused = time_second;
+
/* Update the per-block summary info. */
ufsdirhash_adjfree(dh, offset, -DIRSIZ(0, dirp));
ufsdirhash_release(dh);
@@ -1150,6 +1167,46 @@ ufsdirhash_getprev(struct direct *dirp, doff_t offset)
}
/*
+ * Delete the given dirhash and reclaim its memory. Assumes that
+ * ufsdirhash_list is locked, and leaves it locked. Also assumes
+ * that dh is locked. Returns the amount of memory freed.
+ */
+static int
+ufsdirhash_destroy(struct dirhash *dh)
+{
+ doff_t **hash;
+ u_int8_t *blkfree;
+ int i, mem, narrays;
+
+ KASSERT(dh->dh_hash != NULL, ("dirhash: NULL hash on list"));
+
+ /* Remove it from the list and detach its memory. */
+ TAILQ_REMOVE(&ufsdirhash_list, dh, dh_list);
+ dh->dh_onlist = 0;
+ hash = dh->dh_hash;
+ dh->dh_hash = NULL;
+ blkfree = dh->dh_blkfree;
+ dh->dh_blkfree = NULL;
+ narrays = dh->dh_narrays;
+ mem = dh->dh_memreq;
+ dh->dh_memreq = 0;
+
+ /* Unlock everything, free the detached memory. */
+ ufsdirhash_release(dh);
+ DIRHASHLIST_UNLOCK();
+ for (i = 0; i < narrays; i++)
+ DIRHASH_BLKFREE(hash[i]);
+ free(hash, M_DIRHASH);
+ free(blkfree, M_DIRHASH);
+
+ /* Account for the returned memory. */
+ DIRHASHLIST_LOCK();
+ ufs_dirhashmem -= mem;
+
+ return (mem);
+}
+
+/*
* Try to free up `wanted' bytes by stealing memory from existing
* dirhashes. Returns zero with list locked if successful.
*/
@@ -1157,9 +1214,6 @@ static int
ufsdirhash_recycle(int wanted)
{
struct dirhash *dh;
- doff_t **hash;
- u_int8_t *blkfree;
- int i, mem, narrays;
DIRHASHLIST_LOCK();
dh = TAILQ_FIRST(&ufsdirhash_list);
@@ -1177,36 +1231,59 @@ ufsdirhash_recycle(int wanted)
dh = TAILQ_NEXT(dh, dh_list);
continue;
}
- KASSERT(dh->dh_hash != NULL, ("dirhash: NULL hash on list"));
- /* Remove it from the list and detach its memory. */
- TAILQ_REMOVE(&ufsdirhash_list, dh, dh_list);
- dh->dh_onlist = 0;
- hash = dh->dh_hash;
- dh->dh_hash = NULL;
- blkfree = dh->dh_blkfree;
- dh->dh_blkfree = NULL;
- narrays = dh->dh_narrays;
- mem = dh->dh_memreq;
- dh->dh_memreq = 0;
-
- /* Unlock everything, free the detached memory. */
- ufsdirhash_release(dh);
- DIRHASHLIST_UNLOCK();
- for (i = 0; i < narrays; i++)
- DIRHASH_BLKFREE(hash[i]);
- free(hash, M_DIRHASH);
- free(blkfree, M_DIRHASH);
-
- /* Account for the returned memory, and repeat if necessary. */
- DIRHASHLIST_LOCK();
- ufs_dirhashmem -= mem;
+ ufsdirhash_destroy(dh);
+
+ /* Repeat if necessary. */
dh = TAILQ_FIRST(&ufsdirhash_list);
}
/* Success; return with list locked. */
return (0);
}
+/*
+ * Callback that frees some dirhashes when the system is low on virtual memory.
+ */
+static void
+ufsdirhash_lowmem()
+{
+ struct dirhash *dh;
+ int memfreed = 0;
+ /* XXX: this 10% may need to be adjusted */
+ int memwanted = ufs_dirhashmem / 10;
+
+ ufs_dirhashlowmemcount++;
+
+ DIRHASHLIST_LOCK();
+ /*
+ * Delete dirhashes not used for more than ufs_dirhashreclaimage
+ * seconds. If we can't get a lock on the dirhash, it will be skipped.
+ */
+ for (dh = TAILQ_FIRST(&ufsdirhash_list); dh != NULL; dh =
+ TAILQ_NEXT(dh, dh_list)) {
+ if (!sx_try_xlock(&dh->dh_lock))
+ continue;
+ if (time_second - dh->dh_lastused > ufs_dirhashreclaimage)
+ memfreed += ufsdirhash_destroy(dh);
+ /* Unlock if we didn't delete the dirhash */
+ else
+ ufsdirhash_release(dh);
+ }
+
+ /*
+ * If not enough memory was freed, keep deleting hashes from the head
+ * of the dirhash list. The ones closest to the head should be the
+ * oldest.
+ */
+ for (dh = TAILQ_FIRST(&ufsdirhash_list); memfreed < memwanted &&
+ dh !=NULL; dh = TAILQ_NEXT(dh, dh_list)) {
+ if (!sx_try_xlock(&dh->dh_lock))
+ continue;
+ memfreed += ufsdirhash_destroy(dh);
+ }
+ DIRHASHLIST_UNLOCK();
+}
+
void
ufsdirhash_init()
@@ -1215,6 +1292,10 @@ ufsdirhash_init()
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
mtx_init(&ufsdirhash_mtx, "dirhash list", NULL, MTX_DEF);
TAILQ_INIT(&ufsdirhash_list);
+
+ /* Register a callback function to handle low memory signals */
+ EVENTHANDLER_REGISTER(vm_lowmem, ufsdirhash_lowmem, NULL,
+ EVENTHANDLER_PRI_FIRST);
}
void
diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c
index ed09044..47177e3 100644
--- a/sys/vm/vnode_pager.c
+++ b/sys/vm/vnode_pager.c
@@ -403,22 +403,28 @@ vnode_pager_setsize(vp, nsize)
pmap_zero_page_area(m, base, size);
/*
- * Clear out partial-page dirty bits. This
- * has the side effect of setting the valid
- * bits, but that is ok. There are a bunch
- * of places in the VM system where we expected
- * m->dirty == VM_PAGE_BITS_ALL. The file EOF
- * case is one of them. If the page is still
- * partially dirty, make it fully dirty.
+ * Update the valid bits to reflect the blocks that
+ * have been zeroed. Some of these valid bits may
+ * have already been set.
+ */
+ vm_page_set_valid(m, base, size);
+
+ /*
+ * Round "base" to the next block boundary so that the
+ * dirty bit for a partially zeroed block is not
+ * cleared.
+ */
+ base = roundup2(base, DEV_BSIZE);
+
+ /*
+ * Clear out partial-page dirty bits.
*
* note that we do not clear out the valid
* bits. This would prevent bogus_page
* replacement from working properly.
*/
vm_page_lock_queues();
- vm_page_set_validclean(m, base, size);
- if (m->dirty != 0)
- m->dirty = VM_PAGE_BITS_ALL;
+ vm_page_clear_dirty(m, base, PAGE_SIZE - base);
vm_page_unlock_queues();
} else if ((nsize & PAGE_MASK) &&
__predict_false(object->cache != NULL)) {
OpenPOWER on IntegriCloud