MFhead@r321851

This commit is contained in:
Enji Cooper 2017-08-01 08:42:08 +00:00
commit b99d790542
29 changed files with 620 additions and 188 deletions

View File

@ -175,10 +175,6 @@ symtab_init(void)
int fd;
int i;
int strindex = -1;
#ifndef illumos
void *ksyms;
size_t sz;
#endif
#ifndef illumos
if ((fd = open("/dev/ksyms", O_RDONLY)) == -1) {
@ -194,33 +190,9 @@ symtab_init(void)
return (-1);
#endif
#ifdef illumos
(void) elf_version(EV_CURRENT);
elf = elf_begin(fd, ELF_C_READ, NULL);
#else
/*
* XXX - libelf needs to be fixed so it will work with
* non 'ordinary' files like /dev/ksyms. The following
* is a work around for now.
*/
if (elf_version(EV_CURRENT) == EV_NONE) {
close(fd);
return (-1);
}
if (ioctl(fd, KIOCGSIZE, &sz) < 0) {
close(fd);
return (-1);
}
if (ioctl(fd, KIOCGADDR, &ksyms) < 0) {
close(fd);
return (-1);
}
if ((elf = elf_memory(ksyms, sz)) == NULL) {
close(fd);
return (-1);
}
#endif
for (cnt = 1; (scn = elf_nextscn(elf, scn)) != NULL; cnt++) {
Shdr *shdr = elf_getshdr(scn);

View File

@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd February 8, 2010
.Dd August 1, 2017
.Dt LINUX 4
.Os
.Sh NAME
@ -127,9 +127,11 @@ regardless of whether the
module is statically linked into the kernel
or loaded as a module.
.Sh FILES
.Bl -tag -width /compat/linux/proc -compact
.Bl -tag -width /compat/linux/dev/fd -compact
.It Pa /compat/linux
minimal Linux run-time environment
.It Pa /compat/linux/dev/fd
limited Linux file-descriptor file system
.It Pa /compat/linux/proc
limited Linux process file system
.It Pa /compat/linux/sys
@ -138,6 +140,7 @@ limited Linux system file system
.Sh SEE ALSO
.Xr brandelf 1 ,
.Xr elf 5 ,
.Xr fdescfs 5 ,
.Xr linprocfs 5 ,
.Xr linsysfs 5
.Sh HISTORY

View File

@ -34,7 +34,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd September 18, 2010
.Dd August 1, 2017
.Dt FDESCFS 5
.Os
.Sh NAME
@ -92,6 +92,14 @@ and
files are created by default when devfs alone is mounted.
.Nm
creates entries for all file descriptors opened by the process.
.Pp
For
.Xr linux 4
ABI compatibility mount
.Nm
volume with
.Cm linrdlnk
option.
.Sh FILES
.Bl -tag -width /dev/stderr -compact
.It Pa /dev/fd/#
@ -103,6 +111,12 @@ volume located on
.Pa /dev/fd :
.Pp
.Dl "mount -t fdescfs null /dev/fd"
.Pp
For
.Xr linux 4
ABI compatibility:
.Pp
.Dl "mount -t fdescfs -o linrdlnk null /compat/linux/dev/fd"
.Sh SEE ALSO
.Xr devfs 5 ,
.Xr mount 8

View File

@ -2209,12 +2209,14 @@ static __inline void
pmap_free_zero_pages(struct spglist *free)
{
vm_page_t m;
int count;
while ((m = SLIST_FIRST(free)) != NULL) {
for (count = 0; (m = SLIST_FIRST(free)) != NULL; count++) {
SLIST_REMOVE_HEAD(free, plinks.s.ss);
/* Preserve the page's PG_ZERO setting. */
vm_page_free_toq(m);
}
atomic_subtract_int(&vm_cnt.v_wire_count, count);
}
/*
@ -2320,13 +2322,6 @@ _pmap_unwire_ptp(pmap_t pmap, vm_offset_t va, vm_page_t m, struct spglist *free)
pmap_unwire_ptp(pmap, va, pdppg, free);
}
/*
* This is a release store so that the ordinary store unmapping
* the page table page is globally performed before TLB shoot-
* down is begun.
*/
atomic_subtract_rel_int(&vm_cnt.v_wire_count, 1);
/*
* Put page on a list so that it is released after
* *ALL* TLB shootdown is done
@ -3010,7 +3005,6 @@ reclaim_pv_chunk(pmap_t locked_pmap, struct rwlock **lockp)
SLIST_REMOVE_HEAD(&free, plinks.s.ss);
/* Recycle a freed page table page. */
m_pc->wire_count = 1;
atomic_add_int(&vm_cnt.v_wire_count, 1);
}
pmap_free_zero_pages(&free);
return (m_pc);
@ -3678,7 +3672,6 @@ pmap_remove_pde(pmap_t pmap, pd_entry_t *pdq, vm_offset_t sva,
("pmap_remove_pde: pte page wire count error"));
mpte->wire_count = 0;
pmap_add_delayed_free_list(mpte, free, FALSE);
atomic_subtract_int(&vm_cnt.v_wire_count, 1);
}
}
return (pmap_unuse_pt(pmap, sva, *pmap_pdpe(pmap, sva), free));
@ -5622,7 +5615,6 @@ pmap_remove_pages(pmap_t pmap)
("pmap_remove_pages: pte page wire count error"));
mpte->wire_count = 0;
pmap_add_delayed_free_list(mpte, &free, FALSE);
atomic_subtract_int(&vm_cnt.v_wire_count, 1);
}
} else {
pmap_resident_count_dec(pmap, 1);

View File

@ -28,16 +28,16 @@ SRCS+= bcmp.c bcopy.c bzero.c
SRCS+= pwgets.c
# sha256 and sha512 from sys/crypto
.PATH: ${.CURDIR}/../../crypto/sha2
.PATH: ${SRCTOP}/sys/crypto/sha2
CFLAGS+= -DWEAK_REFS
SRCS+= sha256c.c sha512c.c
# md5 from libmd
.PATH: ${.CURDIR}/../../../lib/libmd
.PATH: ${SRCTOP}/lib/libmd
SRCS+= md5c.c
# AES implementation from sys/crypto
.PATH: ${.CURDIR}/../../crypto/rijndael
.PATH: ${SRCTOP}/sys/crypto/rijndael
CFLAGS+= -I${.CURDIR}/../../
CFLAGS+= -I${.CURDIR}/../common/
# Remove asserts
@ -45,7 +45,7 @@ CFLAGS+= -DNDEBUG
SRCS+= rijndael-alg-fst.c rijndael-api-fst.c rijndael-api.c
# local GELI Implementation
.PATH: ${.CURDIR}/../../geom/eli
.PATH: ${SRCTOP}/sys/geom/eli
CFLAGS+= -D_STAND
SRCS+= geliboot_crypto.c g_eli_hmac.c g_eli_key.c g_eli_key_cache.c pkcs5v2.c

View File

@ -794,6 +794,7 @@ pager_printf(const char *fmt, ...)
va_start(args, fmt);
vsprintf(line, fmt, args);
va_end(args);
return (pager_output(line));
}
@ -804,15 +805,15 @@ pager_printf(const char *fmt, ...)
static int
print_state(int indent, const char *name, vdev_state_t state)
{
int i;
char buf[512];
int i;
buf[0] = 0;
for (i = 0; i < indent; i++)
strcat(buf, " ");
strcat(buf, name);
return (pager_printf(STATUS_FORMAT, buf, state_name(state)));
}
static int

View File

@ -1736,6 +1736,7 @@ dev/iicbus/iiconf.c optional iicbus
dev/iicbus/iicsmb.c optional iicsmb \
dependency "iicbus_if.h"
dev/iicbus/iicoc.c optional iicoc
dev/iicbus/isl12xx.c optional isl12xx
dev/iicbus/lm75.c optional lm75
dev/iicbus/nxprtc.c optional nxprtc | pcf8563
dev/iicbus/ofw_iicbus.c optional fdt iicbus

View File

@ -222,9 +222,9 @@ struct hn_rxinfo {
uint32_t hash_value;
};
struct hn_update_vf {
struct hn_rxvf_setarg {
struct hn_rx_ring *rxr;
struct ifnet *vf;
struct ifnet *vf_ifp;
};
#define HN_RXINFO_VLAN 0x0001
@ -264,6 +264,13 @@ static void hn_ifaddr_event(void *, struct ifnet *);
static void hn_ifnet_attevent(void *, struct ifnet *);
static void hn_ifnet_detevent(void *, struct ifnet *);
static bool hn_ismyvf(const struct hn_softc *,
const struct ifnet *);
static void hn_rxvf_change(struct hn_softc *,
struct ifnet *, bool);
static void hn_rxvf_set(struct hn_softc *, struct ifnet *);
static void hn_rxvf_set_task(void *, int);
static int hn_rndis_rxinfo(const void *, int,
struct hn_rxinfo *);
static void hn_rndis_rx_data(struct hn_rx_ring *,
@ -801,7 +808,7 @@ hn_rxfilter_config(struct hn_softc *sc)
HN_LOCK_ASSERT(sc);
if ((ifp->if_flags & IFF_PROMISC) ||
(sc->hn_flags & HN_FLAG_VF)) {
(sc->hn_flags & HN_FLAG_RXVF)) {
filter = NDIS_PACKET_TYPE_PROMISCUOUS;
} else {
filter = NDIS_PACKET_TYPE_DIRECTED;
@ -991,39 +998,39 @@ hn_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
}
static void
hn_update_vf_task(void *arg, int pending __unused)
hn_rxvf_set_task(void *xarg, int pending __unused)
{
struct hn_update_vf *uv = arg;
struct hn_rxvf_setarg *arg = xarg;
uv->rxr->hn_rxvf_ifp = uv->vf;
arg->rxr->hn_rxvf_ifp = arg->vf_ifp;
}
static void
hn_update_vf(struct hn_softc *sc, struct ifnet *vf)
hn_rxvf_set(struct hn_softc *sc, struct ifnet *vf_ifp)
{
struct hn_rx_ring *rxr;
struct hn_update_vf uv;
struct hn_rxvf_setarg arg;
struct task task;
int i;
HN_LOCK_ASSERT(sc);
TASK_INIT(&task, 0, hn_update_vf_task, &uv);
TASK_INIT(&task, 0, hn_rxvf_set_task, &arg);
for (i = 0; i < sc->hn_rx_ring_cnt; ++i) {
rxr = &sc->hn_rx_ring[i];
if (i < sc->hn_rx_ring_inuse) {
uv.rxr = rxr;
uv.vf = vf;
arg.rxr = rxr;
arg.vf_ifp = vf_ifp;
vmbus_chan_run_task(rxr->hn_chan, &task);
} else {
rxr->hn_rxvf_ifp = vf;
rxr->hn_rxvf_ifp = vf_ifp;
}
}
}
static __inline bool
static bool
hn_ismyvf(const struct hn_softc *sc, const struct ifnet *ifp)
{
const struct ifnet *hn_ifp;
@ -1048,7 +1055,7 @@ hn_ismyvf(const struct hn_softc *sc, const struct ifnet *ifp)
}
static void
hn_set_vf(struct hn_softc *sc, struct ifnet *ifp, bool vf)
hn_rxvf_change(struct hn_softc *sc, struct ifnet *ifp, bool rxvf)
{
struct ifnet *hn_ifp;
@ -1059,21 +1066,19 @@ hn_set_vf(struct hn_softc *sc, struct ifnet *ifp, bool vf)
if (!hn_ismyvf(sc, ifp))
goto out;
hn_ifp = sc->hn_ifp;
/* Now we're sure 'ifp' is a real VF device. */
if (vf) {
if (sc->hn_flags & HN_FLAG_VF)
if (rxvf) {
if (sc->hn_flags & HN_FLAG_RXVF)
goto out;
sc->hn_flags |= HN_FLAG_VF;
sc->hn_flags |= HN_FLAG_RXVF;
hn_rxfilter_config(sc);
} else {
if (!(sc->hn_flags & HN_FLAG_VF))
if (!(sc->hn_flags & HN_FLAG_RXVF))
goto out;
sc->hn_flags &= ~HN_FLAG_VF;
sc->hn_flags &= ~HN_FLAG_RXVF;
if (hn_ifp->if_drv_flags & IFF_DRV_RUNNING)
hn_rxfilter_config(sc);
else
@ -1081,11 +1086,11 @@ hn_set_vf(struct hn_softc *sc, struct ifnet *ifp, bool vf)
}
hn_nvs_set_datapath(sc,
vf ? HN_NVS_DATAPATH_VF : HN_NVS_DATAPATH_SYNTHETIC);
rxvf ? HN_NVS_DATAPATH_VF : HN_NVS_DATAPATH_SYNTHETIC);
hn_update_vf(sc, vf ? ifp : NULL);
hn_rxvf_set(sc, rxvf ? ifp : NULL);
if (vf) {
if (rxvf) {
hn_suspend_mgmt(sc);
sc->hn_link_flags &=
~(HN_LINK_FLAG_LINKUP | HN_LINK_FLAG_NETCHG);
@ -1094,12 +1099,13 @@ hn_set_vf(struct hn_softc *sc, struct ifnet *ifp, bool vf)
hn_resume_mgmt(sc);
}
devctl_notify("HYPERV_NIC_VF", if_name(hn_ifp),
vf ? "VF_UP" : "VF_DOWN", NULL);
devctl_notify("HYPERV_NIC_VF", hn_ifp->if_xname,
rxvf ? "VF_UP" : "VF_DOWN", NULL);
if (bootverbose)
if_printf(hn_ifp, "Data path is switched %s %s\n",
vf ? "to" : "from", if_name(ifp));
if (bootverbose) {
if_printf(hn_ifp, "datapath is switched %s %s\n",
rxvf ? "to" : "from", ifp->if_xname);
}
out:
HN_UNLOCK(sc);
}
@ -1107,16 +1113,17 @@ out:
static void
hn_ifnet_event(void *arg, struct ifnet *ifp, int event)
{
if (event != IFNET_EVENT_UP && event != IFNET_EVENT_DOWN)
return;
hn_set_vf(arg, ifp, event == IFNET_EVENT_UP);
hn_rxvf_change(arg, ifp, event == IFNET_EVENT_UP);
}
static void
hn_ifaddr_event(void *arg, struct ifnet *ifp)
{
hn_set_vf(arg, ifp, ifp->if_flags & IFF_UP);
hn_rxvf_change(arg, ifp, ifp->if_flags & IFF_UP);
}
static void
@ -1534,6 +1541,12 @@ hn_attach(device_t dev)
sc->hn_ifaddr_evthand = EVENTHANDLER_REGISTER(ifaddr_event,
hn_ifaddr_event, sc, EVENTHANDLER_PRI_ANY);
/*
* NOTE:
* Subscribe ether_ifattach event, instead of ifnet_arrival event,
* since interface's LLADDR is needed; interface LLADDR is not
* available when ifnet_arrival event is triggered.
*/
sc->hn_ifnet_atthand = EVENTHANDLER_REGISTER(ether_ifattach_event,
hn_ifnet_attevent, sc, EVENTHANDLER_PRI_ANY);
sc->hn_ifnet_dethand = EVENTHANDLER_REGISTER(ifnet_departure_event,
@ -2902,7 +2915,7 @@ hn_stop(struct hn_softc *sc, bool detaching)
* If the VF is active, make sure the filter is not 0, even if
* the synthetic NIC is down.
*/
if (!detaching && (sc->hn_flags & HN_FLAG_VF))
if (!detaching && (sc->hn_flags & HN_FLAG_RXVF))
hn_rxfilter_config(sc);
}
@ -3438,13 +3451,13 @@ hn_vf_sysctl(SYSCTL_HANDLER_ARGS)
{
struct hn_softc *sc = arg1;
char vf_name[IFNAMSIZ + 1];
struct ifnet *vf;
struct ifnet *vf_ifp;
HN_LOCK(sc);
vf_name[0] = '\0';
vf = sc->hn_vf_ifp;
if (vf != NULL)
snprintf(vf_name, sizeof(vf_name), "%s", if_name(vf));
vf_ifp = sc->hn_vf_ifp;
if (vf_ifp != NULL)
snprintf(vf_name, sizeof(vf_name), "%s", vf_ifp->if_xname);
HN_UNLOCK(sc);
return sysctl_handle_string(oidp, vf_name, sizeof(vf_name), req);
}
@ -3454,13 +3467,13 @@ hn_rxvf_sysctl(SYSCTL_HANDLER_ARGS)
{
struct hn_softc *sc = arg1;
char vf_name[IFNAMSIZ + 1];
struct ifnet *vf;
struct ifnet *vf_ifp;
HN_LOCK(sc);
vf_name[0] = '\0';
vf = sc->hn_rx_ring[0].hn_rxvf_ifp;
if (vf != NULL)
snprintf(vf_name, sizeof(vf_name), "%s", if_name(vf));
vf_ifp = sc->hn_rx_ring[0].hn_rxvf_ifp;
if (vf_ifp != NULL)
snprintf(vf_name, sizeof(vf_name), "%s", vf_ifp->if_xname);
HN_UNLOCK(sc);
return sysctl_handle_string(oidp, vf_name, sizeof(vf_name), req);
}
@ -5445,7 +5458,7 @@ hn_suspend(struct hn_softc *sc)
hn_polling(sc, 0);
if ((sc->hn_ifp->if_drv_flags & IFF_DRV_RUNNING) ||
(sc->hn_flags & HN_FLAG_VF))
(sc->hn_flags & HN_FLAG_RXVF))
hn_suspend_data(sc);
hn_suspend_mgmt(sc);
}
@ -5535,16 +5548,16 @@ hn_resume(struct hn_softc *sc)
{
if ((sc->hn_ifp->if_drv_flags & IFF_DRV_RUNNING) ||
(sc->hn_flags & HN_FLAG_VF))
(sc->hn_flags & HN_FLAG_RXVF))
hn_resume_data(sc);
/*
* When the VF is activated, the synthetic interface is changed
* to DOWN in hn_set_vf(). Here, if the VF is still active, we
* don't call hn_resume_mgmt() until the VF is deactivated in
* hn_set_vf().
* to DOWN in hn_rxvf_change(). Here, if the VF is still active,
* we don't call hn_resume_mgmt() until the VF is deactivated in
* hn_rxvf_change().
*/
if (!(sc->hn_flags & HN_FLAG_VF))
if (!(sc->hn_flags & HN_FLAG_RXVF))
hn_resume_mgmt(sc);
/*

View File

@ -251,7 +251,7 @@ struct hn_softc {
#define HN_FLAG_NO_SLEEPING 0x0020
#define HN_FLAG_RXBUF_REF 0x0040
#define HN_FLAG_CHIM_REF 0x0080
#define HN_FLAG_VF 0x0100
#define HN_FLAG_RXVF 0x0100
#define HN_FLAG_ERRORS (HN_FLAG_RXBUF_REF | HN_FLAG_CHIM_REF)

354
sys/dev/iicbus/isl12xx.c Normal file
View File

@ -0,0 +1,354 @@
/*-
* Copyright (c) 2017 Ian Lepore. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*
* Driver for ISL12xx family i2c realtime clocks:
* - ISL1209 = 2B sram, tamper/event timestamp
* - ISL1218 = 8B sram, DS13xx pin compatible (but not software compatible)
* - ISL1219 = 2B sram, tamper/event timestamp
* - ISL1220 = 8B sram, separate Fout
* - ISL1221 = 2B sram, separate Fout, tamper/event timestamp
*
* This driver supports only the basic RTC functionality in all these chips.
*/
#include "opt_platform.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/clock.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/module.h>
#include <sys/sx.h>
#ifdef FDT
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#endif
#include <dev/iicbus/iiconf.h>
#include <dev/iicbus/iicbus.h>
#include "clock_if.h"
#include "iicbus_if.h"
/*
* All register and bit names as found in the datasheet. When a bit name ends
* in 'B' that stands for "bar" and it is an active-low signal; something named
* "EVENB" implies 1=event-disable, 0=event-enable.
*/
#define ISL12XX_SC_REG 0x00 /* RTC Seconds */
#define ISL12XX_SR_REG 0x07 /* Status */
#define ISL12XX_SR_ARST (1u << 7) /* Auto-reset on status read */
#define ISL12XX_SR_XTOSCB (1u << 5) /* Osc disable (use ext osc) */
#define ISL12XX_SR_WRTC (1u << 4) /* Write RTC enable */
#define ISL12XX_SR_EVT (1u << 3) /* Event occurred (w0c) */
#define ISL12XX_SR_ALM (1u << 2) /* Alarm occurred (w0c) */
#define ISL12XX_SR_BAT (1u << 1) /* Running on battery (w0c) */
#define ISL12XX_SR_RTCF (1u << 0) /* RTC fail (power loss) */
#define ISL12XX_SR_W0C_BITS (ISL12XX_SR_BAT | ISL12XX_SR_ALM | ISL12XX_SR_EVT)
#define ISL12XX_INT_REG 0x08 /* Interrupts */
#define ISL12XX_INT_IM (1u << 7) /* Alarm interrupt mode */
#define ISL12XX_INT_ALME (1u << 6) /* Alarm enable */
#define ISL12XX_INT_LPMODE (1u << 5) /* Low Power mode */
#define ISL12XX_INT_FOBATB (1u << 4) /* Fout/IRQ disabled on bat */
#define ISL12XX_INT_FO_SHIFT 0 /* Frequency output select */
#define ISL12XX_INT_FO_MASK 0x0f /* shift and mask. */
#define ISL12XX_EV_REG 0x09 /* Event */
#define ISL12XX_EV_EVIENB (1u << 7) /* Disable internal pullup */
#define ISL12XX_EV_EVBATB (1u << 6) /* Disable ev detect on bat */
#define ISL12XX_EV_RTCHLT (1u << 5) /* Halt RTC on event */
#define ISL12XX_EV_EVEN (1u << 4) /* Event detect enable */
#define ISL12XX_EV_EHYS_SHIFT 2 /* Event input hysteresis */
#define ISL12XX_EV_EHYS_MASK 0x03 /* selection; see datasheet */
#define ISL12XX_EV_ESMP_SHIFT 0 /* Event input sample rate */
#define ISL12XX_EV_ESMP_MASK 0x03 /* selection; see datasheet */
#define ISL12XX_ATR_REG 0x0a /* Analog trim (osc adjust) */
#define ISL12XX_DTR_REG 0x0b /* Digital trim (osc adjust) */
#define ISL12XX_SCA_REG 0x0c /* Alarm seconds */
#define ISL12XX_USR1_REG 0x12 /* User byte 1 */
#define ISL12XX_USR2_REG 0x13 /* User byte 2 */
#define ISL12XX_SCT_REG 0x14 /* Timestamp (event) seconds */
#define ISL12XX_24HR_FLAG (1u << 7) /* Hours register 24-hr mode */
#define ISL12XX_PM_FLAG (1u << 5) /* Hours register PM flag */
#define ISL12xx_12HR_MASK 0x1f /* Hours mask in AM/PM mode */
#define ISL12xx_24HR_MASK 0x3f /* Hours mask in 24-hr mode */
/*
* A struct laid out in the same order as the time registers in the chip.
*/
struct time_regs {
uint8_t sec, min, hour, day, month, year;
};
struct isl12xx_softc {
device_t dev;
device_t busdev;
struct intr_config_hook
init_hook;
bool use_ampm;
};
#ifdef FDT
static struct ofw_compat_data compat_data[] = {
{"isil,isl1209", 1},
{"isil,isl1218", 1},
{"isil,isl1219", 1},
{"isil,isl1220", 1},
{"isil,isl1221", 1},
{NULL, 0},
};
#endif
static inline int
isl12xx_read1(struct isl12xx_softc *sc, uint8_t reg, uint8_t *data)
{
return (iicdev_readfrom(sc->dev, reg, data, 1, IIC_WAIT));
}
static inline int
isl12xx_write1(struct isl12xx_softc *sc, uint8_t reg, uint8_t val)
{
return (iicdev_writeto(sc->dev, reg, &val, 1, IIC_WAIT));
}
static void
isl12xx_init(void *arg)
{
struct isl12xx_softc *sc = arg;
uint8_t sreg;
config_intrhook_disestablish(&sc->init_hook);
/*
* Check the clock-stopped/power-fail bit, just so we can report it to
* the user at boot time.
*/
isl12xx_read1(sc, ISL12XX_SR_REG, &sreg);
if (sreg & ISL12XX_SR_RTCF) {
device_printf(sc->dev,
"RTC clock stopped; check battery\n");
}
/*
* Register as a system realtime clock.
*/
clock_register_flags(sc->dev, 1000000, CLOCKF_SETTIME_NO_ADJ);
clock_schedule(sc->dev, 1);
}
static int
isl12xx_probe(device_t dev)
{
#ifdef FDT
if (!ofw_bus_status_okay(dev))
return (ENXIO);
if (ofw_bus_search_compatible(dev, compat_data)->ocd_data != 0) {
device_set_desc(dev, "Intersil ISL12xx RTC");
return (BUS_PROBE_DEFAULT);
}
#endif
return (ENXIO);
}
static int
isl12xx_attach(device_t dev)
{
struct isl12xx_softc *sc = device_get_softc(dev);
sc->dev = dev;
sc->busdev = device_get_parent(sc->dev);
/*
* Chip init must wait until interrupts are enabled. Often i2c access
* works only when the interrupts are available.
*/
sc->init_hook.ich_func = isl12xx_init;
sc->init_hook.ich_arg = sc;
if (config_intrhook_establish(&sc->init_hook) != 0)
return (ENOMEM);
return (0);
}
static int
isl12xx_detach(device_t dev)
{
clock_unregister(dev);
return (0);
}
static int
isl12xx_gettime(device_t dev, struct timespec *ts)
{
struct isl12xx_softc *sc = device_get_softc(dev);
struct clocktime ct;
struct time_regs tregs;
int err;
uint8_t hourmask, sreg;
/* If power failed, we can't provide valid time. */
if ((err = isl12xx_read1(sc, ISL12XX_SR_REG, &sreg)) != 0)
return (err);
if (sreg & ISL12XX_SR_RTCF)
return (EINVAL);
/* Read the bcd time registers. */
if ((err = iicdev_readfrom(sc->dev, ISL12XX_SC_REG, &tregs, sizeof(tregs),
IIC_WAIT)) != 0)
return (EINVAL);
/* If chip is in AM/PM mode remember that for when we set time. */
if (tregs.hour & ISL12XX_24HR_FLAG) {
hourmask = ISL12xx_24HR_MASK;
} else {
sc->use_ampm = true;
hourmask = ISL12xx_12HR_MASK;
}
ct.nsec = 0;
ct.sec = FROMBCD(tregs.sec);
ct.min = FROMBCD(tregs.min);
ct.hour = FROMBCD(tregs.hour & hourmask);
ct.day = FROMBCD(tregs.day);
ct.mon = FROMBCD(tregs.month);
ct.year = FROMBCD(tregs.year);
if (sc->use_ampm) {
if (ct.hour == 12)
ct.hour = 0;
if (tregs.hour & ISL12XX_PM_FLAG)
ct.hour += 12;
}
return (clock_ct_to_ts(&ct, ts));
}
static int
isl12xx_settime(device_t dev, struct timespec *ts)
{
struct isl12xx_softc *sc = device_get_softc(dev);
struct clocktime ct;
struct time_regs tregs;
int err;
uint8_t ampmflags, sreg;
/*
* We request a timespec with no resolution-adjustment. That also
* disables utc adjustment, so apply that ourselves.
*/
ts->tv_sec -= utc_offset();
ts->tv_nsec = 0;
clock_ts_to_ct(ts, &ct);
/* If the chip is in AM/PM mode, adjust hour and set flags as needed. */
if (!sc->use_ampm) {
ampmflags = ISL12XX_24HR_FLAG;
} else {
ampmflags = 0;
if (ct.hour >= 12) {
ct.hour -= 12;
ampmflags |= ISL12XX_PM_FLAG;
}
if (ct.hour == 0)
ct.hour = 12;
}
tregs.sec = TOBCD(ct.sec);
tregs.min = TOBCD(ct.min);
tregs.hour = TOBCD(ct.hour) | ampmflags;
tregs.day = TOBCD(ct.day);
tregs.month = TOBCD(ct.mon);
tregs.year = TOBCD(ct.year % 100);
/*
* To set the time we have to set the WRTC enable bit in the control
* register, then write the time regs, then clear the WRTC bit. While
* doing so we have to be careful to not write a 0 to any sreg bit which
* is "write 0 to clear". One of those bits could get set between
* reading and writing the register. All those bits ignore attempts to
* write a 1, so just always OR-in all the W0C bits to be sure we never
* accidentally clear one. We hold ownership of the i2c bus for the
* whole read-modify-write sequence.
*/
if ((err = iicbus_request_bus(sc->busdev, sc->dev, IIC_WAIT)) != 0)
return (err);
if ((err = isl12xx_read1(sc, ISL12XX_SR_REG, &sreg)) == 0) {
sreg |= ISL12XX_SR_WRTC | ISL12XX_SR_W0C_BITS;
if ((err = isl12xx_write1(sc, ISL12XX_SR_REG, sreg)) == 0) {
err = iicdev_writeto(sc->dev, ISL12XX_SC_REG, &tregs,
sizeof(tregs), IIC_WAIT);
sreg &= ~ISL12XX_SR_WRTC;
isl12xx_write1(sc, ISL12XX_SR_REG, sreg);
}
}
iicbus_release_bus(sc->busdev, sc->dev);
return (err);
}
static device_method_t isl12xx_methods[] = {
/* device_if methods */
DEVMETHOD(device_probe, isl12xx_probe),
DEVMETHOD(device_attach, isl12xx_attach),
DEVMETHOD(device_detach, isl12xx_detach),
/* clock_if methods */
DEVMETHOD(clock_gettime, isl12xx_gettime),
DEVMETHOD(clock_settime, isl12xx_settime),
DEVMETHOD_END,
};
static driver_t isl12xx_driver = {
"isl12xx",
isl12xx_methods,
sizeof(struct isl12xx_softc),
};
static devclass_t isl12xx_devclass;
DRIVER_MODULE(isl12xx, iicbus, isl12xx_driver, isl12xx_devclass, NULL, NULL);
MODULE_VERSION(isl12xx, 1);
MODULE_DEPEND(isl12xx, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);

View File

@ -38,7 +38,9 @@
#define _FS_FDESC_H_
/* Private mount flags for fdescfs. */
#define FMNT_UNMOUNTF 0x01
#define FMNT_UNMOUNTF 0x01
#define FMNT_LINRDLNKF 0x02
struct fdescmount {
struct vnode *f_root; /* Root node */
int flags;

View File

@ -101,6 +101,8 @@ fdesc_mount(struct mount *mp)
*/
mp->mnt_data = fmp;
fmp->flags = 0;
if (vfs_getopt(mp->mnt_optnew, "linrdlnk", NULL, NULL) == 0)
fmp->flags |= FMNT_LINRDLNKF;
error = fdesc_allocvp(Froot, -1, FD_ROOT, mp, &rvp);
if (error) {
free(fmp, M_FDESCMNT);

View File

@ -69,6 +69,7 @@ static vop_getattr_t fdesc_getattr;
static vop_lookup_t fdesc_lookup;
static vop_open_t fdesc_open;
static vop_readdir_t fdesc_readdir;
static vop_readlink_t fdesc_readlink;
static vop_reclaim_t fdesc_reclaim;
static vop_setattr_t fdesc_setattr;
@ -81,6 +82,7 @@ static struct vop_vector fdesc_vnodeops = {
.vop_open = fdesc_open,
.vop_pathconf = vop_stdpathconf,
.vop_readdir = fdesc_readdir,
.vop_readlink = fdesc_readlink,
.vop_reclaim = fdesc_reclaim,
.vop_setattr = fdesc_setattr,
};
@ -195,6 +197,8 @@ loop:
fd->fd_type = ftype;
fd->fd_fd = fd_fd;
fd->fd_ix = ix;
if (ftype == Fdesc && fmp->flags & FMNT_LINRDLNKF)
vp->v_vflag |= VV_READLINK;
error = insmntque1(vp, mp, fdesc_insmntque_dtr, NULL);
if (error != 0) {
*vpp = NULLVP;
@ -420,7 +424,7 @@ fdesc_getattr(struct vop_getattr_args *ap)
break;
case Fdesc:
vap->va_type = VCHR;
vap->va_type = (vp->v_vflag & VV_READLINK) == 0 ? VCHR : VLNK;
vap->va_nlink = 1;
vap->va_size = 0;
vap->va_rdev = makedev(0, vap->va_fileid);
@ -490,6 +494,7 @@ fdesc_setattr(struct vop_setattr_args *ap)
static int
fdesc_readdir(struct vop_readdir_args *ap)
{
struct fdescmount *fmp;
struct uio *uio = ap->a_uio;
struct filedesc *fdp;
struct dirent d;
@ -499,6 +504,7 @@ fdesc_readdir(struct vop_readdir_args *ap)
if (VTOFDESC(ap->a_vp)->fd_type != Froot)
panic("fdesc_readdir: not dir");
fmp = VFSTOFDESC(ap->a_vp->v_mount);
if (ap->a_ncookies != NULL)
*ap->a_ncookies = 0;
@ -530,7 +536,8 @@ fdesc_readdir(struct vop_readdir_args *ap)
break;
dp->d_namlen = sprintf(dp->d_name, "%d", fcnt);
dp->d_reclen = UIO_MX;
dp->d_type = DT_CHR;
dp->d_type = (fmp->flags & FMNT_LINRDLNKF) == 0 ?
DT_CHR : DT_LNK;
dp->d_fileno = i + FD_DESC;
break;
}
@ -567,3 +574,52 @@ fdesc_reclaim(struct vop_reclaim_args *ap)
vp->v_data = NULL;
return (0);
}
static int
fdesc_readlink(struct vop_readlink_args *va)
{
struct vnode *vp, *vn;
cap_rights_t rights;
struct thread *td;
struct uio *uio;
struct file *fp;
char *freepath, *fullpath;
size_t pathlen;
int lockflags, fd_fd;
int error;
freepath = NULL;
vn = va->a_vp;
if (VTOFDESC(vn)->fd_type != Fdesc)
panic("fdesc_readlink: not fdescfs link");
fd_fd = ((struct fdescnode *)vn->v_data)->fd_fd;
lockflags = VOP_ISLOCKED(vn);
VOP_UNLOCK(vn, 0);
td = curthread;
error = fget_cap(td, fd_fd, cap_rights_init(&rights), &fp, NULL);
if (error != 0)
goto out;
switch (fp->f_type) {
case DTYPE_VNODE:
vp = fp->f_vnode;
error = vn_fullpath(td, vp, &fullpath, &freepath);
break;
default:
fullpath = "anon_inode:[unknown]";
break;
}
if (error == 0) {
uio = va->a_uio;
pathlen = strlen(fullpath);
error = uiomove(fullpath, pathlen, uio);
}
if (freepath != NULL)
free(freepath, M_TEMP);
fdrop(fp, td);
out:
vn_lock(vn, lockflags | LK_RETRY);
return (error);
}

View File

@ -1709,12 +1709,14 @@ static __inline void
pmap_free_zero_pages(struct spglist *free)
{
vm_page_t m;
int count;
while ((m = SLIST_FIRST(free)) != NULL) {
for (count = 0; (m = SLIST_FIRST(free)) != NULL; count++) {
SLIST_REMOVE_HEAD(free, plinks.s.ss);
/* Preserve the page's PG_ZERO setting. */
vm_page_free_toq(m);
}
atomic_subtract_int(&vm_cnt.v_wire_count, count);
}
/*
@ -1791,13 +1793,6 @@ _pmap_unwire_ptp(pmap_t pmap, vm_page_t m, struct spglist *free)
pmap->pm_pdir[m->pindex] = 0;
--pmap->pm_stats.resident_count;
/*
* This is a release store so that the ordinary store unmapping
* the page table page is globally performed before TLB shoot-
* down is begun.
*/
atomic_subtract_rel_int(&vm_cnt.v_wire_count, 1);
/*
* Do an invltlb to make the invalidated mapping
* take effect immediately.
@ -2061,11 +2056,11 @@ pmap_release(pmap_t pmap)
("pmap_release: got wrong ptd page"));
#endif
m->wire_count--;
atomic_subtract_int(&vm_cnt.v_wire_count, 1);
vm_page_free_zero(m);
}
atomic_subtract_int(&vm_cnt.v_wire_count, NPGPTD);
}
static int
kvm_size(SYSCTL_HANDLER_ARGS)
{
@ -2324,7 +2319,6 @@ out:
SLIST_REMOVE_HEAD(&free, plinks.s.ss);
/* Recycle a freed page table page. */
m_pc->wire_count = 1;
atomic_add_int(&vm_cnt.v_wire_count, 1);
}
pmap_free_zero_pages(&free);
return (m_pc);
@ -2873,7 +2867,6 @@ pmap_remove_pde(pmap_t pmap, pd_entry_t *pdq, vm_offset_t sva,
("pmap_remove_pde: pte page wire count error"));
mpte->wire_count = 0;
pmap_add_delayed_free_list(mpte, free, FALSE);
atomic_subtract_int(&vm_cnt.v_wire_count, 1);
}
}
}
@ -4593,7 +4586,6 @@ pmap_remove_pages(pmap_t pmap)
("pmap_remove_pages: pte page wire count error"));
mpte->wire_count = 0;
pmap_add_delayed_free_list(mpte, &free, FALSE);
atomic_subtract_int(&vm_cnt.v_wire_count, 1);
}
} else {
pmap->pm_stats.resident_count--;

View File

@ -123,26 +123,47 @@ void panic(const char *ctl, ...);
static daddr_t blst_leaf_alloc(blmeta_t *scan, daddr_t blk, int count,
daddr_t cursor);
static daddr_t blst_meta_alloc(blmeta_t *scan, daddr_t blk, daddr_t count,
daddr_t radix, daddr_t skip, daddr_t cursor);
daddr_t radix, daddr_t cursor);
static void blst_leaf_free(blmeta_t *scan, daddr_t relblk, int count);
static void blst_meta_free(blmeta_t *scan, daddr_t freeBlk, daddr_t count,
daddr_t radix, daddr_t skip, daddr_t blk);
daddr_t radix, daddr_t blk);
static void blst_copy(blmeta_t *scan, daddr_t blk, daddr_t radix,
daddr_t skip, blist_t dest, daddr_t count);
blist_t dest, daddr_t count);
static daddr_t blst_leaf_fill(blmeta_t *scan, daddr_t blk, int count);
static daddr_t blst_meta_fill(blmeta_t *scan, daddr_t allocBlk, daddr_t count,
daddr_t radix, daddr_t skip, daddr_t blk);
static daddr_t blst_radix_init(blmeta_t *scan, daddr_t radix, daddr_t skip,
daddr_t count);
daddr_t radix, daddr_t blk);
static daddr_t blst_radix_init(blmeta_t *scan, daddr_t radix, daddr_t count);
#ifndef _KERNEL
static void blst_radix_print(blmeta_t *scan, daddr_t blk, daddr_t radix,
daddr_t skip, int tab);
int tab);
#endif
#ifdef _KERNEL
static MALLOC_DEFINE(M_SWAP, "SWAP", "Swap space");
#endif
/*
* For a subtree that can represent the state of up to 'radix' blocks, the
* number of leaf nodes of the subtree is L=radix/BLIST_BMAP_RADIX. If 'm'
* is short for BLIST_META_RADIX, then for a tree of height h with L=m**h
* leaf nodes, the total number of tree nodes is 1 + m + m**2 + ... + m**h,
* or, equivalently, (m**(h+1)-1)/(m-1). This quantity is called 'skip'
* in the 'meta' functions that process subtrees. Since integer division
* discards remainders, we can express this computation as
* skip = (m * m**h) / (m - 1)
* skip = (m * radix / BLIST_BMAP_RADIX) / (m - 1)
* and if m divides BLIST_BMAP_RADIX, we can simplify further to
* skip = radix / (BLIST_BMAP_RADIX / m * (m - 1))
* so that a simple integer division is enough for the calculation.
*/
static inline daddr_t
radix_to_skip(daddr_t radix)
{
return (radix /
(BLIST_BMAP_RADIX / BLIST_META_RADIX * (BLIST_META_RADIX - 1)));
}
/*
* blist_create() - create a blist capable of handling up to the specified
* number of blocks
@ -157,18 +178,16 @@ blist_t
blist_create(daddr_t blocks, int flags)
{
blist_t bl;
daddr_t nodes, radix, skip;
daddr_t nodes, radix;
/*
* Calculate radix and skip field used for scanning.
* Calculate the radix field used for scanning.
*/
radix = BLIST_BMAP_RADIX;
skip = 0;
while (radix < blocks) {
radix *= BLIST_META_RADIX;
skip = (skip + 1) * BLIST_META_RADIX;
}
nodes = 1 + blst_radix_init(NULL, radix, skip, blocks);
nodes = 1 + blst_radix_init(NULL, radix, blocks);
bl = malloc(sizeof(struct blist), M_SWAP, flags);
if (bl == NULL)
@ -176,14 +195,13 @@ blist_create(daddr_t blocks, int flags)
bl->bl_blocks = blocks;
bl->bl_radix = radix;
bl->bl_skip = skip;
bl->bl_cursor = 0;
bl->bl_root = malloc(nodes * sizeof(blmeta_t), M_SWAP, flags);
if (bl->bl_root == NULL) {
free(bl, M_SWAP);
return (NULL);
}
blst_radix_init(bl->bl_root, radix, skip, blocks);
blst_radix_init(bl->bl_root, radix, blocks);
#if defined(BLIST_DEBUG)
printf(
@ -225,7 +243,7 @@ blist_alloc(blist_t bl, daddr_t count)
*/
while (count <= bl->bl_root->bm_bighint) {
blk = blst_meta_alloc(bl->bl_root, 0, count, bl->bl_radix,
bl->bl_skip, bl->bl_cursor);
bl->bl_cursor);
if (blk != SWAPBLK_NONE) {
bl->bl_cursor = blk + count;
return (blk);
@ -257,7 +275,7 @@ void
blist_free(blist_t bl, daddr_t blkno, daddr_t count)
{
blst_meta_free(bl->bl_root, blkno, count, bl->bl_radix, bl->bl_skip, 0);
blst_meta_free(bl->bl_root, blkno, count, bl->bl_radix, 0);
}
/*
@ -270,8 +288,7 @@ daddr_t
blist_fill(blist_t bl, daddr_t blkno, daddr_t count)
{
return (blst_meta_fill(bl->bl_root, blkno, count, bl->bl_radix,
bl->bl_skip, 0));
return (blst_meta_fill(bl->bl_root, blkno, count, bl->bl_radix, 0));
}
/*
@ -290,7 +307,7 @@ blist_resize(blist_t *pbl, daddr_t count, int freenew, int flags)
*pbl = newbl;
if (count > save->bl_blocks)
count = save->bl_blocks;
blst_copy(save->bl_root, 0, save->bl_radix, save->bl_skip, newbl, count);
blst_copy(save->bl_root, 0, save->bl_radix, newbl, count);
/*
* If resizing upwards, should we free the new space or not?
@ -309,8 +326,8 @@ blist_resize(blist_t *pbl, daddr_t count, int freenew, int flags)
void
blist_print(blist_t bl)
{
printf("BLIST {\n");
blst_radix_print(bl->bl_root, 0, bl->bl_radix, bl->bl_skip, 4);
printf("BLIST cursor = %08jx {\n", (uintmax_t)bl->bl_cursor);
blst_radix_print(bl->bl_root, 0, bl->bl_radix, 4);
printf("}\n");
}
@ -426,9 +443,9 @@ blst_leaf_alloc(blmeta_t *scan, daddr_t blk, int count, daddr_t cursor)
*/
static daddr_t
blst_meta_alloc(blmeta_t *scan, daddr_t blk, daddr_t count, daddr_t radix,
daddr_t skip, daddr_t cursor)
daddr_t cursor)
{
daddr_t i, next_skip, r;
daddr_t i, next_skip, r, skip;
int child;
bool scan_from_start;
@ -443,6 +460,7 @@ blst_meta_alloc(blmeta_t *scan, daddr_t blk, daddr_t count, daddr_t radix,
scan->bm_bighint = scan->u.bmu_avail;
return (SWAPBLK_NONE);
}
skip = radix_to_skip(radix);
next_skip = skip / BLIST_META_RADIX;
/*
@ -456,7 +474,7 @@ blst_meta_alloc(blmeta_t *scan, daddr_t blk, daddr_t count, daddr_t radix,
* Reinitialize each of the meta node's children. An ALL-FREE
* meta node cannot have a terminator in any subtree.
*/
for (i = 1; i <= skip; i += next_skip) {
for (i = 1; i < skip; i += next_skip) {
if (next_skip == 1)
scan[i].u.bmu_bitmap = (u_daddr_t)-1;
else
@ -477,13 +495,13 @@ blst_meta_alloc(blmeta_t *scan, daddr_t blk, daddr_t count, daddr_t radix,
scan_from_start = cursor == blk;
child = (cursor - blk) / radix;
blk += child * radix;
for (i = 1 + child * next_skip; i <= skip; i += next_skip) {
for (i = 1 + child * next_skip; i < skip; i += next_skip) {
if (count <= scan[i].bm_bighint) {
/*
* The allocation might fit in the i'th subtree.
*/
r = blst_meta_alloc(&scan[i], blk, count, radix,
next_skip - 1, cursor > blk ? cursor : blk);
cursor > blk ? cursor : blk);
if (r != SWAPBLK_NONE) {
scan->u.bmu_avail -= count;
return (r);
@ -552,15 +570,16 @@ blst_leaf_free(blmeta_t *scan, daddr_t blk, int count)
*/
static void
blst_meta_free(blmeta_t *scan, daddr_t freeBlk, daddr_t count, daddr_t radix,
daddr_t skip, daddr_t blk)
daddr_t blk)
{
daddr_t i, next_skip, v;
daddr_t i, next_skip, skip, v;
int child;
if (scan->bm_bighint == (daddr_t)-1)
panic("freeing invalid range");
if (radix == BLIST_BMAP_RADIX)
return (blst_leaf_free(scan, freeBlk, count));
skip = radix_to_skip(radix);
next_skip = skip / BLIST_META_RADIX;
if (scan->u.bmu_avail == 0) {
@ -572,7 +591,7 @@ blst_meta_free(blmeta_t *scan, daddr_t freeBlk, daddr_t count, daddr_t radix,
scan->bm_bighint = count;
if (count != radix) {
for (i = 1; i <= skip; i += next_skip) {
for (i = 1; i < skip; i += next_skip) {
if (scan[i].bm_bighint == (daddr_t)-1)
break;
scan[i].bm_bighint = 0;
@ -609,11 +628,11 @@ blst_meta_free(blmeta_t *scan, daddr_t freeBlk, daddr_t count, daddr_t radix,
child = (freeBlk - blk) / radix;
blk += child * radix;
i = 1 + child * next_skip;
while (i <= skip && blk < freeBlk + count) {
while (i < skip && blk < freeBlk + count) {
v = blk + radix - freeBlk;
if (v > count)
v = count;
blst_meta_free(&scan[i], freeBlk, v, radix, next_skip - 1, blk);
blst_meta_free(&scan[i], freeBlk, v, radix, blk);
if (scan->bm_bighint < scan[i].bm_bighint)
scan->bm_bighint = scan[i].bm_bighint;
count -= v;
@ -630,10 +649,10 @@ blst_meta_free(blmeta_t *scan, daddr_t freeBlk, daddr_t count, daddr_t radix,
* tree. The space may not already be free in the destination.
*/
static void
blst_copy(blmeta_t *scan, daddr_t blk, daddr_t radix, daddr_t skip,
blist_t dest, daddr_t count)
blst_copy(blmeta_t *scan, daddr_t blk, daddr_t radix, blist_t dest,
daddr_t count)
{
daddr_t i, next_skip;
daddr_t i, next_skip, skip;
/*
* Leaf node
@ -677,21 +696,20 @@ blst_copy(blmeta_t *scan, daddr_t blk, daddr_t radix, daddr_t skip,
}
radix /= BLIST_META_RADIX;
skip = radix_to_skip(radix);
next_skip = skip / BLIST_META_RADIX;
radix /= BLIST_META_RADIX;
for (i = 1; count && i <= skip; i += next_skip) {
for (i = 1; count && i < skip; i += next_skip) {
if (scan[i].bm_bighint == (daddr_t)-1)
break;
if (count >= radix) {
blst_copy(&scan[i], blk, radix, next_skip - 1, dest,
radix);
blst_copy(&scan[i], blk, radix, dest, radix);
count -= radix;
} else {
if (count) {
blst_copy(&scan[i], blk, radix, next_skip - 1,
dest, count);
blst_copy(&scan[i], blk, radix, dest, count);
}
count = 0;
}
@ -733,9 +751,9 @@ blst_leaf_fill(blmeta_t *scan, daddr_t blk, int count)
*/
static daddr_t
blst_meta_fill(blmeta_t *scan, daddr_t allocBlk, daddr_t count, daddr_t radix,
daddr_t skip, daddr_t blk)
daddr_t blk)
{
daddr_t i, nblks, next_skip, v;
daddr_t i, nblks, next_skip, skip, v;
int child;
if (scan->bm_bighint == (daddr_t)-1)
@ -758,6 +776,7 @@ blst_meta_fill(blmeta_t *scan, daddr_t allocBlk, daddr_t count, daddr_t radix,
scan->bm_bighint = 0;
return (nblks);
}
skip = radix_to_skip(radix);
next_skip = skip / BLIST_META_RADIX;
/*
@ -771,7 +790,7 @@ blst_meta_fill(blmeta_t *scan, daddr_t allocBlk, daddr_t count, daddr_t radix,
* Reinitialize each of the meta node's children. An ALL-FREE
* meta node cannot have a terminator in any subtree.
*/
for (i = 1; i <= skip; i += next_skip) {
for (i = 1; i < skip; i += next_skip) {
if (next_skip == 1)
scan[i].u.bmu_bitmap = (u_daddr_t)-1;
else
@ -786,12 +805,11 @@ blst_meta_fill(blmeta_t *scan, daddr_t allocBlk, daddr_t count, daddr_t radix,
child = (allocBlk - blk) / radix;
blk += child * radix;
i = 1 + child * next_skip;
while (i <= skip && blk < allocBlk + count) {
while (i < skip && blk < allocBlk + count) {
v = blk + radix - allocBlk;
if (v > count)
v = count;
nblks += blst_meta_fill(&scan[i], allocBlk, v, radix,
next_skip - 1, blk);
nblks += blst_meta_fill(&scan[i], allocBlk, v, radix, blk);
count -= v;
allocBlk += v;
blk += radix;
@ -810,9 +828,9 @@ blst_meta_fill(blmeta_t *scan, daddr_t allocBlk, daddr_t count, daddr_t radix,
* RADIX values we use.
*/
static daddr_t
blst_radix_init(blmeta_t *scan, daddr_t radix, daddr_t skip, daddr_t count)
blst_radix_init(blmeta_t *scan, daddr_t radix, daddr_t count)
{
daddr_t i, memindex, next_skip;
daddr_t i, memindex, next_skip, skip;
memindex = 0;
@ -839,17 +857,18 @@ blst_radix_init(blmeta_t *scan, daddr_t radix, daddr_t skip, daddr_t count)
scan->u.bmu_avail = 0;
}
radix /= BLIST_META_RADIX;
skip = radix_to_skip(radix);
next_skip = skip / BLIST_META_RADIX;
radix /= BLIST_META_RADIX;
for (i = 1; i <= skip; i += next_skip) {
for (i = 1; i < skip; i += next_skip) {
if (count >= radix) {
/*
* Allocate the entire object
*/
memindex = i +
blst_radix_init(((scan) ? &scan[i] : NULL), radix,
next_skip - 1, radix);
radix);
count -= radix;
} else if (count > 0) {
/*
@ -857,7 +876,7 @@ blst_radix_init(blmeta_t *scan, daddr_t radix, daddr_t skip, daddr_t count)
*/
memindex = i +
blst_radix_init(((scan) ? &scan[i] : NULL), radix,
next_skip - 1, count);
count);
count = 0;
} else {
/*
@ -876,10 +895,9 @@ blst_radix_init(blmeta_t *scan, daddr_t radix, daddr_t skip, daddr_t count)
#ifdef BLIST_DEBUG
static void
blst_radix_print(blmeta_t *scan, daddr_t blk, daddr_t radix, daddr_t skip,
int tab)
blst_radix_print(blmeta_t *scan, daddr_t blk, daddr_t radix, int tab)
{
daddr_t i, next_skip;
daddr_t i, next_skip, skip;
if (radix == BLIST_BMAP_RADIX) {
printf(
@ -920,11 +938,12 @@ blst_radix_print(blmeta_t *scan, daddr_t blk, daddr_t radix, daddr_t skip,
(long long)scan->bm_bighint
);
radix /= BLIST_META_RADIX;
skip = radix_to_skip(radix);
next_skip = skip / BLIST_META_RADIX;
radix /= BLIST_META_RADIX;
tab += 4;
for (i = 1; i <= skip; i += next_skip) {
for (i = 1; i < skip; i += next_skip) {
if (scan[i].bm_bighint == (daddr_t)-1) {
printf(
"%*.*s(%08llx,%lld): Terminator\n",
@ -933,7 +952,7 @@ blst_radix_print(blmeta_t *scan, daddr_t blk, daddr_t radix, daddr_t skip,
);
break;
}
blst_radix_print(&scan[i], blk, radix, next_skip - 1, tab);
blst_radix_print(&scan[i], blk, radix, tab);
blk += radix;
}
tab -= 4;

View File

@ -2484,7 +2484,7 @@ kern_readlinkat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
return (error);
}
#endif
if (vp->v_type != VLNK)
if (vp->v_type != VLNK && (vp->v_vflag & VV_READLINK) == 0)
error = EINVAL;
else {
aiov.iov_base = buf;

View File

@ -11,6 +11,7 @@ SUBDIR = \
iicbus \
iicsmb \
isl \
isl12xx \
jedec_ts \
nxprtc \
smb \

View File

@ -0,0 +1,7 @@
# $FreeBSD$
.PATH: ${SRCTOP}/sys/dev/iicbus
KMOD = isl12xx
SRCS = isl12xx.c bus_if.h clock_if.h device_if.h iicbus_if.h
.include <bsd.kmod.mk>

View File

@ -2014,9 +2014,10 @@ setcurchan(struct ieee80211vap *vap, struct ieee80211_channel *c)
/* XXX need state machine for other vap's to follow */
ieee80211_setcurchan(ic, vap->iv_des_chan);
vap->iv_bss->ni_chan = ic->ic_curchan;
} else
} else {
ic->ic_curchan = vap->iv_des_chan;
ic->ic_rt = ieee80211_get_ratetable(ic->ic_curchan);
}
} else {
/*
* Need to go through the state machine in case we

View File

@ -2630,7 +2630,7 @@ mesh_recv_action_meshgate(struct ieee80211_node *ni,
/* popagate only if decremented ttl >= 1 && forwarding is enabled */
if ((ie.gann_ttl - 1) < 1 && !(ms->ms_flags & IEEE80211_MESHFLAGS_FWD))
return 0;
pgann.gann_flags = ie.gann_flags; /* Reserved */
pgann.gann_flags = ie.gann_flags; /* Reserved */
pgann.gann_hopcount = ie.gann_hopcount + 1;
pgann.gann_ttl = ie.gann_ttl - 1;
IEEE80211_ADDR_COPY(pgann.gann_addr, ie.gann_addr);

View File

@ -81,7 +81,6 @@ typedef struct blmeta {
typedef struct blist {
daddr_t bl_blocks; /* area of coverage */
daddr_t bl_radix; /* coverage radix */
daddr_t bl_skip; /* starting skip */
daddr_t bl_cursor; /* next-fit search starts at */
blmeta_t *bl_root; /* root of radix tree */
} *blist_t;

View File

@ -250,6 +250,7 @@ struct xvnode {
#define VV_DELETED 0x0400 /* should be removed */
#define VV_MD 0x0800 /* vnode backs the md device */
#define VV_FORCEINSMQ 0x1000 /* force the insmntque to succeed */
#define VV_READLINK 0x2000 /* fdescfs linux vnode */
#define VMP_TMPMNTFREELIST 0x0001 /* Vnode is on mnt's tmp free list */

View File

@ -1,6 +1,6 @@
# $FreeBSD$
.PATH: ${.CURDIR}/../../../sys/boot/common
.PATH: ${SRCTOP}/sys/boot/common
BINDIR?= /usr/bin
@ -9,12 +9,10 @@ MAN=
SRCS= bootparttest.c crc32.c stub.c part.c disk.c
CFLAGS= -I${.CURDIR}/../../../sys/boot/common \
CFLAGS= -I${SRCTOP}/sys/boot/common \
-DLOADER_GPT_SUPPORT -DLOADER_MBR_SUPPORT -DPART_DEBUG \
-DDISK_DEBUG
DPADD+= ${LIBGEOM}
LDADD+= ${LIBGEOM}
LDFLAGS+= -lgeom
LIBADD+= geom
.include <bsd.prog.mk>

View File

@ -124,7 +124,7 @@ main(int argc, char **argv)
printf("Mediasize: %ju Bytes (%ju sectors)\nSectorsize: %u Bytes\n",
disk.mediasize, disk.mediasize / disk.sectorsize, disk.sectorsize);
if (disk_open(&dev, disk.mediasize, disk.sectorsize, 0) != 0)
if (disk_open(&dev, disk.mediasize, disk.sectorsize) != 0)
errx(1, "disk_open failed");
printf("\tdisk0:\n");
disk_print(&dev, "\tdisk0", 1);

View File

@ -44,9 +44,9 @@ Free(void *ptr, const char *file, int line)
return (free(ptr));
}
void
int
pager_output(const char *s)
{
printf("%s", s);
return (printf("%s", s));
}

View File

@ -1,6 +1,6 @@
# $FreeBSD$
.PATH: ${.CURDIR}/../../../sys/boot/zfs ${.CURDIR}/../../../sys/cddl/boot/zfs
.PATH: ${SRCTOP}/sys/boot/zfs ${SRCTOP}/sys/cddl/boot/zfs
BINDIR?= /usr/bin
SCRIPTSDIR?= /usr/bin
@ -11,8 +11,8 @@ SCRIPTSNAME= zfsboottest.sh
MAN=
CFLAGS= -O1 \
-I${.CURDIR}/../../../sys/boot/zfs \
-I${.CURDIR}/../../../sys/cddl/boot/zfs \
-I${SRCTOP}/sys/boot/zfs \
-I${SRCTOP}/sys/cddl/boot/zfs \
-I. \
-fdiagnostics-show-option \
-W -Wextra -Wno-sign-compare -Wno-unused-parameter
@ -23,7 +23,7 @@ LIBADD+= md
beforedepend zfsboottest.o: machine
CLEANFILES+= machine
machine:
ln -sf ${.CURDIR}/../../../sys/i386/include machine
ln -sf ${SRCTOP}/sys/i386/include machine
.endif
.include <bsd.prog.mk>

View File

@ -43,11 +43,11 @@
#define NBBY 8
void
int
pager_output(const char *line)
{
fprintf(stderr, "%s", line);
return (fprintf(stderr, "%s", line));
}
#define ZFS_TEST

View File

@ -290,6 +290,7 @@
08/19 Chin-San Huang <chinsan@FreeBSD.org> born in Yi-Lan, Taiwan, Republic of China, 1979
08/19 Pav Lucistnik <pav@FreeBSD.org> born in Kutna Hora, Czech Republic, 1980
08/20 Michael Heffner <mikeh@FreeBSD.org> born in Cleona, Pennsylvania, United States, 1981
08/21 Jason A. Harmening <jah@FreeBSD.org> born in Fort Wayne, Indiana, United States, 1981
08/24 Mark Linimon <linimon@FreeBSD.org> born in Houston, Texas, United States, 1955
08/24 Alexander Botero-Lowry <alexbl@FreeBSD.org> died in San Francisco, California, United States, 2012
08/25 Beech Rintoul <beech@FreeBSD.org> born in Oakland, California, United States, 1952
@ -353,6 +354,7 @@
10/18 Sheldon Hearn <sheldonh@FreeBSD.org> born in Cape Town, Western Cape, South Africa, 1974
10/19 Nicholas Souchu <nsouch@FreeBSD.org> born in Suresnes, Hauts-de-Seine, France, 1972
10/19 Nick Barkas <snb@FreeBSD.org> born in Longview, Washington, United States, 1981
10/19 Pedro Giffuni <pfg@FreeBSD.org> born in Bogotá, Colombia, 1968
10/20 Joel Dahl <joel@FreeBSD.org> born in Bitterna, Skaraborg, Sweden, 1983
10/20 Dmitry Marakasov <amdmi3@FreeBSD.org> born in Moscow, Russian Federation, 1984
10/21 Ben Smithurst <ben@FreeBSD.org> born in Sheffield, South Yorkshire, United Kingdom, 1981

View File

@ -92,6 +92,7 @@ flatten_entries(struct env *env)
free(tmp);
}
env->sc_user_lines = linep;
log_debug("done pushing users");
wrlen = env->sc_group_line_len;
if ((linep = calloc(1, env->sc_group_line_len + 1)) == NULL) {
@ -117,6 +118,7 @@ flatten_entries(struct env *env)
wrlen -= len;
}
env->sc_group_lines = linep;
log_debug("done pushing groups");
}
int