Merge from head

This commit is contained in:
Baptiste Daroussin 2015-10-13 20:57:37 +00:00
commit 7d710f0522
29 changed files with 347 additions and 302 deletions

View File

@ -7,6 +7,5 @@ SUBDIR= libasn1 libgssapi_krb5 libgssapi_ntlm libgssapi_spnego libhdb \
SUBDIR+= libkafs5 # requires krb_err.h from libkrb5
SUBDIR_DEPEND_libkafs5= libkrb5
SUBDIR_PARALLEL=
.include <bsd.subdir.mk>

View File

@ -25,14 +25,17 @@
# This is a variant of install, which will
# put the stuff into the right "distribution".
#
# afterinstall, all, all-man, beforeinstall, checkdpadd, clean,
# cleandepend, cleandir, cleanilinks depend, install, lint,
# maninstall, manlint, obj, objlink, realinstall, regress, tags
# See ALL_SUBDIR_TARGETS for list of targets that will recurse.
# Custom targets can be added to SUBDIR_TARGETS in src.conf.
#
.if !target(__<bsd.subdir.mk>__)
__<bsd.subdir.mk>__:
ALL_SUBDIR_TARGETS= all all-man checkdpadd clean cleandepend cleandir \
cleanilinks cleanobj depend distribute lint maninstall manlint obj \
objlink realinstall regress tags ${SUBDIR_TARGETS}
.include <bsd.init.mk>
.if !defined(NEED_SUBDIR)
@ -85,9 +88,7 @@ ${SUBDIR:N.WAIT}: .PHONY .MAKE
# Work around parsing of .if nested in .for by putting .WAIT string into a var.
__wait= .WAIT
.for __target in all all-man checkdpadd clean cleandepend cleandir \
cleanilinks depend distribute lint maninstall manlint obj objlink \
realinstall regress tags ${SUBDIR_TARGETS}
.for __target in ${ALL_SUBDIR_TARGETS}
.ifdef SUBDIR_PARALLEL
__subdir_targets=
.for __dir in ${SUBDIR}

View File

@ -65,7 +65,7 @@ ioat_bus_space_write_8_lower_first(bus_space_tag_t tag,
bus_space_write_4(tag, handle, offset + 4, val >> 32);
}
#ifdef i386
#ifdef __i386__
#define ioat_bus_space_read_8 ioat_bus_space_read_8_lower_first
#define ioat_bus_space_write_8 ioat_bus_space_write_8_lower_first
#else

View File

@ -715,7 +715,7 @@ ntb_transport_link_up(struct ntb_transport_qp *qp)
* @len: length of the data buffer
*
* Enqueue a new transmit buffer onto the transport queue from which a NTB
* payload will be transmitted. This assumes that a lock is behing held to
* payload will be transmitted. This assumes that a lock is being held to
* serialize access to the qp.
*
* RETURNS: An appropriate ERRNO error value on error, or zero for success.
@ -809,7 +809,7 @@ ntb_tx_copy_task(struct ntb_transport_qp *qp, struct ntb_queue_entry *entry,
/* TODO: replace with bus_space_write */
hdr->flags = entry->flags | IF_NTB_DESC_DONE_FLAG;
ntb_ring_sdb(qp->ntb, qp->qp_num);
ntb_ring_doorbell(qp->ntb, qp->qp_num);
/*
* The entry length can only be zero if the packet is intended to be a
@ -1047,7 +1047,7 @@ ntb_transport_link_work(void *arg)
/* send the local info, in the opposite order of the way we read it */
for (i = 0; i < num_mw; i++) {
rc = ntb_write_remote_spad(ntb, IF_NTB_MW0_SZ_HIGH + (i * 2),
ntb_get_mw_size(ntb, i) >> 32);
(uint64_t)ntb_get_mw_size(ntb, i) >> 32);
if (rc != 0)
goto out;
@ -1311,7 +1311,7 @@ ntb_qp_link_cleanup(struct ntb_transport_qp *qp)
*
* Notify NTB transport layer of client's desire to no longer receive data on
* transport queue specified. It is the client's responsibility to ensure all
* entries on queue are purged or otherwise handled appropraitely.
* entries on queue are purged or otherwise handled appropriately.
*/
static void
ntb_transport_link_down(struct ntb_transport_qp *qp)

View File

@ -133,11 +133,11 @@ struct ntb_softc {
uint8_t msix_cnt;
} limits;
struct {
uint32_t pdb;
uint32_t pdb_mask;
uint32_t sdb;
uint32_t sbar2_xlat;
uint32_t sbar4_xlat;
uint32_t ldb;
uint32_t ldb_mask;
uint32_t rdb;
uint32_t bar2_xlat;
uint32_t bar4_xlat;
uint32_t spad_remote;
uint32_t spad_local;
uint32_t lnk_cntl;
@ -476,9 +476,9 @@ ntb_setup_interrupts(struct ntb_softc *ntb)
* Interrupt. The rest will be unmasked as callbacks are registered.
*/
if (ntb->type == NTB_SOC)
ntb_reg_write(8, ntb->reg_ofs.pdb_mask, ~0);
ntb_reg_write(8, ntb->reg_ofs.ldb_mask, ~0);
else
ntb_reg_write(2, ntb->reg_ofs.pdb_mask,
ntb_reg_write(2, ntb->reg_ofs.ldb_mask,
~(1 << ntb->limits.max_db_bits));
num_vectors = MIN(pci_msix_count(ntb->device),
@ -578,7 +578,7 @@ handle_soc_irq(void *arg)
struct ntb_db_cb *db_cb = arg;
struct ntb_softc *ntb = db_cb->ntb;
ntb_reg_write(8, ntb->reg_ofs.pdb, (uint64_t) 1 << db_cb->db_num);
ntb_reg_write(8, ntb->reg_ofs.ldb, (uint64_t) 1 << db_cb->db_num);
if (db_cb->callback != NULL)
db_cb->callback(db_cb->data, db_cb->db_num);
@ -596,7 +596,7 @@ handle_xeon_irq(void *arg)
* vectors, with the 4th having a single bit for link
* interrupts.
*/
ntb_reg_write(2, ntb->reg_ofs.pdb,
ntb_reg_write(2, ntb->reg_ofs.ldb,
((1 << ntb->bits_per_vector) - 1) <<
(db_cb->db_num * ntb->bits_per_vector));
@ -616,7 +616,7 @@ handle_xeon_event_irq(void *arg)
device_printf(ntb->device, "Error determining link status\n");
/* bit 15 is always the link bit */
ntb_reg_write(2, ntb->reg_ofs.pdb, 1 << ntb->limits.max_db_bits);
ntb_reg_write(2, ntb->reg_ofs.ldb, 1 << ntb->limits.max_db_bits);
}
static void
@ -624,28 +624,28 @@ ntb_handle_legacy_interrupt(void *arg)
{
struct ntb_softc *ntb = arg;
unsigned int i = 0;
uint64_t pdb64;
uint16_t pdb16;
uint64_t ldb64;
uint16_t ldb16;
if (ntb->type == NTB_SOC) {
pdb64 = ntb_reg_read(8, ntb->reg_ofs.pdb);
ldb64 = ntb_reg_read(8, ntb->reg_ofs.ldb);
while (pdb64) {
i = ffs(pdb64);
pdb64 &= pdb64 - 1;
while (ldb64) {
i = ffs(ldb64);
ldb64 &= ldb64 - 1;
handle_soc_irq(&ntb->db_cb[i]);
}
} else {
pdb16 = ntb_reg_read(2, ntb->reg_ofs.pdb);
ldb16 = ntb_reg_read(2, ntb->reg_ofs.ldb);
if ((pdb16 & XEON_DB_HW_LINK) != 0) {
if ((ldb16 & XEON_DB_HW_LINK) != 0) {
handle_xeon_event_irq(ntb);
pdb16 &= ~XEON_DB_HW_LINK;
ldb16 &= ~XEON_DB_HW_LINK;
}
while (pdb16 != 0) {
i = ffs(pdb16);
pdb16 &= pdb16 - 1;
while (ldb16 != 0) {
i = ffs(ldb16);
ldb16 &= ldb16 - 1;
handle_xeon_irq(&ntb->db_cb[i]);
}
}
@ -709,31 +709,50 @@ ntb_setup_xeon(struct ntb_softc *ntb)
val = pci_read_config(ntb->device, NTB_PPD_OFFSET, 1);
connection_type = val & XEON_PPD_CONN_TYPE;
switch (connection_type) {
case NTB_CONN_B2B:
ntb->conn_type = NTB_CONN_B2B;
break;
case NTB_CONN_CLASSIC:
case NTB_CONN_RP:
default:
device_printf(ntb->device, "Connection type %d not supported\n",
connection_type);
return (ENXIO);
}
if ((val & XEON_PPD_DEV_TYPE) != 0)
ntb->dev_type = NTB_DEV_USD;
else
ntb->dev_type = NTB_DEV_DSD;
ntb->reg_ofs.pdb = XEON_PDOORBELL_OFFSET;
ntb->reg_ofs.pdb_mask = XEON_PDBMSK_OFFSET;
ntb->reg_ofs.sbar2_xlat = XEON_SBAR2XLAT_OFFSET;
ntb->reg_ofs.sbar4_xlat = XEON_SBAR4XLAT_OFFSET;
ntb->reg_ofs.lnk_cntl = XEON_NTBCNTL_OFFSET;
ntb->reg_ofs.lnk_stat = XEON_LINK_STATUS_OFFSET;
ntb->reg_ofs.ldb = XEON_PDOORBELL_OFFSET;
ntb->reg_ofs.ldb_mask = XEON_PDBMSK_OFFSET;
ntb->reg_ofs.spad_local = XEON_SPAD_OFFSET;
ntb->reg_ofs.spci_cmd = XEON_PCICMD_OFFSET;
ntb->reg_ofs.bar2_xlat = XEON_SBAR2XLAT_OFFSET;
ntb->reg_ofs.bar4_xlat = XEON_SBAR4XLAT_OFFSET;
switch (connection_type) {
case NTB_CONN_B2B:
ntb->conn_type = NTB_CONN_B2B;
/*
* reg_ofs.rdb and reg_ofs.spad_remote are effectively ignored
* with the NTB_REGS_THRU_MW errata mode enabled. (See
* ntb_ring_doorbell() and ntb_read/write_remote_spad().)
*/
ntb->reg_ofs.rdb = XEON_B2B_DOORBELL_OFFSET;
ntb->reg_ofs.spad_remote = XEON_B2B_SPAD_OFFSET;
ntb->limits.max_spads = XEON_MAX_SPADS;
break;
case NTB_CONN_RP:
/*
* Every Xeon today needs NTB_REGS_THRU_MW, so punt on RP for
* now.
*/
KASSERT(HAS_FEATURE(NTB_REGS_THRU_MW),
("Xeon without MW errata unimplemented"));
device_printf(ntb->device,
"NTB-RP disabled to due hardware errata.\n");
return (ENXIO);
case NTB_CONN_TRANSPARENT:
default:
device_printf(ntb->device, "Connection type %d not supported\n",
connection_type);
return (ENXIO);
}
/*
* There is a Xeon hardware errata related to writes to SDOORBELL or
@ -757,25 +776,20 @@ ntb_setup_xeon(struct ntb_softc *ntb)
ntb_reg_write(8, XEON_PBAR4LMT_OFFSET, 0);
if (ntb->conn_type == NTB_CONN_B2B) {
ntb->reg_ofs.sdb = XEON_B2B_DOORBELL_OFFSET;
ntb->reg_ofs.spad_remote = XEON_B2B_SPAD_OFFSET;
ntb->limits.max_spads = XEON_MAX_SPADS;
} else {
ntb->reg_ofs.sdb = XEON_SDOORBELL_OFFSET;
ntb->reg_ofs.spad_remote = XEON_SPAD_OFFSET;
ntb->limits.max_spads = XEON_MAX_COMPAT_SPADS;
}
ntb->reg_ofs.lnk_cntl = XEON_NTBCNTL_OFFSET;
ntb->reg_ofs.lnk_stat = XEON_LINK_STATUS_OFFSET;
ntb->reg_ofs.spci_cmd = XEON_PCICMD_OFFSET;
ntb->limits.max_db_bits = XEON_MAX_DB_BITS;
ntb->limits.max_db_bits = XEON_MAX_DB_BITS;
ntb->limits.msix_cnt = XEON_MSIX_CNT;
ntb->bits_per_vector = XEON_DB_BITS_PER_VEC;
configure_xeon_secondary_side_bars(ntb);
/* Enable Bus Master and Memory Space on the secondary side */
ntb_reg_write(2, ntb->reg_ofs.spci_cmd,
PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN);
if (ntb->conn_type == NTB_CONN_B2B)
ntb_reg_write(2, ntb->reg_ofs.spci_cmd,
PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN);
/* Enable link training */
ntb_reg_write(4, ntb->reg_ofs.lnk_cntl,
@ -796,10 +810,9 @@ ntb_setup_soc(struct ntb_softc *ntb)
case NTB_CONN_B2B:
ntb->conn_type = NTB_CONN_B2B;
break;
case NTB_CONN_RP:
default:
device_printf(ntb->device, "Connection type %d not supported\n",
connection_type);
device_printf(ntb->device,
"Unsupported NTB configuration (%d)\n", connection_type);
return (ENXIO);
}
@ -812,26 +825,19 @@ ntb_setup_soc(struct ntb_softc *ntb)
pci_write_config(ntb->device, NTB_PPD_OFFSET, val | SOC_PPD_INIT_LINK,
4);
ntb->reg_ofs.pdb = SOC_PDOORBELL_OFFSET;
ntb->reg_ofs.pdb_mask = SOC_PDBMSK_OFFSET;
ntb->reg_ofs.sbar2_xlat = SOC_SBAR2XLAT_OFFSET;
ntb->reg_ofs.sbar4_xlat = SOC_SBAR4XLAT_OFFSET;
ntb->reg_ofs.ldb = SOC_PDOORBELL_OFFSET;
ntb->reg_ofs.ldb_mask = SOC_PDBMSK_OFFSET;
ntb->reg_ofs.rdb = SOC_B2B_DOORBELL_OFFSET;
ntb->reg_ofs.bar2_xlat = SOC_SBAR2XLAT_OFFSET;
ntb->reg_ofs.bar4_xlat = SOC_SBAR4XLAT_OFFSET;
ntb->reg_ofs.lnk_cntl = SOC_NTBCNTL_OFFSET;
ntb->reg_ofs.lnk_stat = SOC_LINK_STATUS_OFFSET;
ntb->reg_ofs.spad_local = SOC_SPAD_OFFSET;
ntb->reg_ofs.spad_remote = SOC_B2B_SPAD_OFFSET;
ntb->reg_ofs.spci_cmd = SOC_PCICMD_OFFSET;
if (ntb->conn_type == NTB_CONN_B2B) {
ntb->reg_ofs.sdb = SOC_B2B_DOORBELL_OFFSET;
ntb->reg_ofs.spad_remote = SOC_B2B_SPAD_OFFSET;
ntb->limits.max_spads = SOC_MAX_SPADS;
} else {
ntb->reg_ofs.sdb = SOC_PDOORBELL_OFFSET;
ntb->reg_ofs.spad_remote = SOC_SPAD_OFFSET;
ntb->limits.max_spads = SOC_MAX_COMPAT_SPADS;
}
ntb->limits.max_db_bits = SOC_MAX_DB_BITS;
ntb->limits.max_spads = SOC_MAX_SPADS;
ntb->limits.max_db_bits = SOC_MAX_DB_BITS;
ntb->limits.msix_cnt = SOC_MSIX_CNT;
ntb->bits_per_vector = SOC_DB_BITS_PER_VEC;
@ -996,7 +1002,8 @@ ntb_handle_link_event(struct ntb_softc *ntb, int link_state)
ntb->link_status = NTB_LINK_UP;
event = NTB_EVENT_HW_LINK_UP;
if (ntb->type == NTB_SOC)
if (ntb->type == NTB_SOC ||
ntb->conn_type == NTB_CONN_TRANSPARENT)
status = ntb_reg_read(2, ntb->reg_ofs.lnk_stat);
else
status = pci_read_config(ntb->device,
@ -1133,6 +1140,7 @@ ntb_unregister_event_callback(struct ntb_softc *ntb)
* ntb_register_db_callback() - register a callback for doorbell interrupt
* @ntb: pointer to ntb_softc instance
* @idx: doorbell index to register callback, zero based
* @data: pointer to be returned to caller with every callback
* @func: callback function to register
*
* This function registers a callback function for the doorbell interrupt
@ -1156,9 +1164,9 @@ ntb_register_db_callback(struct ntb_softc *ntb, unsigned int idx, void *data,
ntb->db_cb[idx].data = data;
/* unmask interrupt */
mask = ntb_reg_read(2, ntb->reg_ofs.pdb_mask);
mask = ntb_reg_read(2, ntb->reg_ofs.ldb_mask);
mask &= ~(1 << (idx * ntb->bits_per_vector));
ntb_reg_write(2, ntb->reg_ofs.pdb_mask, mask);
ntb_reg_write(2, ntb->reg_ofs.ldb_mask, mask);
return (0);
}
@ -1179,9 +1187,9 @@ ntb_unregister_db_callback(struct ntb_softc *ntb, unsigned int idx)
if (idx >= ntb->allocated_interrupts || !ntb->db_cb[idx].callback)
return;
mask = ntb_reg_read(2, ntb->reg_ofs.pdb_mask);
mask = ntb_reg_read(2, ntb->reg_ofs.ldb_mask);
mask |= 1 << (idx * ntb->bits_per_vector);
ntb_reg_write(2, ntb->reg_ofs.pdb_mask, mask);
ntb_reg_write(2, ntb->reg_ofs.ldb_mask, mask);
ntb->db_cb[idx].callback = NULL;
}
@ -1430,16 +1438,16 @@ ntb_set_mw_addr(struct ntb_softc *ntb, unsigned int mw, uint64_t addr)
switch (NTB_MW_TO_BAR(mw)) {
case NTB_B2B_BAR_1:
ntb_reg_write(8, ntb->reg_ofs.sbar2_xlat, addr);
ntb_reg_write(8, ntb->reg_ofs.bar2_xlat, addr);
break;
case NTB_B2B_BAR_2:
ntb_reg_write(8, ntb->reg_ofs.sbar4_xlat, addr);
ntb_reg_write(8, ntb->reg_ofs.bar4_xlat, addr);
break;
}
}
/**
* ntb_ring_sdb() - Set the doorbell on the secondary/external side
* ntb_ring_doorbell() - Set the doorbell on the secondary/external side
* @ntb: pointer to ntb_softc instance
* @db: doorbell to ring
*
@ -1449,18 +1457,18 @@ ntb_set_mw_addr(struct ntb_softc *ntb, unsigned int mw, uint64_t addr)
* RETURNS: An appropriate ERRNO error value on error, or zero for success.
*/
void
ntb_ring_sdb(struct ntb_softc *ntb, unsigned int db)
ntb_ring_doorbell(struct ntb_softc *ntb, unsigned int db)
{
if (ntb->type == NTB_SOC)
ntb_reg_write(8, ntb->reg_ofs.sdb, (uint64_t) 1 << db);
ntb_reg_write(8, ntb->reg_ofs.rdb, (uint64_t) 1 << db);
else {
if (HAS_FEATURE(NTB_REGS_THRU_MW))
ntb_mw_write(2, XEON_SHADOW_PDOORBELL_OFFSET,
((1 << ntb->bits_per_vector) - 1) <<
(db * ntb->bits_per_vector));
else
ntb_reg_write(2, ntb->reg_ofs.sdb,
ntb_reg_write(2, ntb->reg_ofs.rdb,
((1 << ntb->bits_per_vector) - 1) <<
(db * ntb->bits_per_vector));
}

View File

@ -69,7 +69,7 @@ void *ntb_get_mw_vbase(struct ntb_softc *ntb, unsigned int mw);
vm_paddr_t ntb_get_mw_pbase(struct ntb_softc *ntb, unsigned int mw);
u_long ntb_get_mw_size(struct ntb_softc *ntb, unsigned int mw);
void ntb_set_mw_addr(struct ntb_softc *ntb, unsigned int mw, uint64_t addr);
void ntb_ring_sdb(struct ntb_softc *ntb, unsigned int db);
void ntb_ring_doorbell(struct ntb_softc *ntb, unsigned int db);
bool ntb_query_link_status(struct ntb_softc *ntb);
device_t ntb_get_device(struct ntb_softc *ntb);

View File

@ -29,8 +29,6 @@
#ifndef _NTB_REGS_H_
#define _NTB_REGS_H_
#define NTB_LINK_ENABLE 0x0000
#define NTB_LINK_DISABLE 0x0002
#define NTB_LINK_STATUS_ACTIVE 0x2000
#define NTB_LINK_SPEED_MASK 0x000f
#define NTB_LINK_WIDTH_MASK 0x03f0
@ -47,6 +45,7 @@
#define XEON_PCICMD_OFFSET 0x0504
#define XEON_DEVCTRL_OFFSET 0x0598
#define XEON_LINK_STATUS_OFFSET 0x01a2
#define XEON_SLINK_STATUS_OFFSET 0x05a2
#define XEON_PBAR2LMT_OFFSET 0x0000
#define XEON_PBAR4LMT_OFFSET 0x0008
@ -76,7 +75,6 @@
#define SOC_MSIX_CNT 34
#define SOC_MAX_SPADS 16
#define SOC_MAX_COMPAT_SPADS 16
#define SOC_MAX_DB_BITS 34
#define SOC_DB_BITS_PER_VEC 1
@ -117,6 +115,8 @@
#define SOC_LTSSMSTATEJMP_FORCEDETECT (1 << 2)
#define SOC_IBIST_ERR_OFLOW 0x7fff7fff
#define NTB_CNTL_CFG_LOCK (1 << 0)
#define NTB_CNTL_LINK_DISABLE (1 << 1)
#define NTB_CNTL_BAR23_SNOOP (1 << 2)
#define NTB_CNTL_BAR45_SNOOP (1 << 6)
#define SOC_CNTL_LINK_DOWN (1 << 16)
@ -130,7 +130,7 @@
#define SOC_PPD_CONN_TYPE 0x0300
#define SOC_PPD_DEV_TYPE 0x1000
#define NTB_CONN_CLASSIC 0
#define NTB_CONN_TRANSPARENT 0
#define NTB_CONN_B2B 1
#define NTB_CONN_RP 2

View File

@ -408,7 +408,11 @@ sctp_backoff_on_timeout(struct sctp_tcb *stcb,
int num_marked, int num_abandoned)
{
if (net->RTO == 0) {
net->RTO = stcb->asoc.minrto;
if (net->RTO_measured) {
net->RTO = stcb->asoc.minrto;
} else {
net->RTO = stcb->asoc.initial_rto;
}
}
net->RTO <<= 1;
if (net->RTO > stcb->asoc.maxrto) {

View File

@ -2,87 +2,64 @@
NO_WERROR=
PROG= truss
SRCS= main.c setup.c syscalls.c syscalls.h ioctl.c
.if exists(${.CURDIR}/${MACHINE_ARCH}-fbsd.c)
SRCS+= ${MACHINE_ARCH}-fbsd.c
.else
SRCS+= ${MACHINE_CPUARCH}-fbsd.c
.endif
SRCS= main.c setup.c syscalls.c ioctl.c
.PATH: ${.CURDIR:H}/kdump
SRCS+= utrace.c
CFLAGS+= -I${.CURDIR} -I. -I${.CURDIR}/../../sys
CLEANFILES= syscalls.master syscalls.h ioctl.c
.SUFFIXES: .master
syscalls.master: ${.CURDIR}/../../sys/kern/syscalls.master
cat ${.ALLSRC} > syscalls.master
syscalls.h: syscalls.master
/bin/sh ${.CURDIR}/../../sys/kern/makesyscalls.sh syscalls.master \
${.CURDIR}/i386.conf
CLEANFILES= ioctl.c
ioctl.c: ${.CURDIR}/../kdump/mkioctls
env MACHINE=${MACHINE} CPP="${CPP}" \
/bin/sh ${.CURDIR}/../kdump/mkioctls return ${DESTDIR}${INCLUDEDIR} > ${.TARGET}
# Define where to generate syscalls for each ABI.
ABI_SYSPATH.freebsd= sys/kern
ABI_SYSPATH.freebsd32= sys/compat/freebsd32
ABI_SYSPATH.cloudabi64= sys/compat/cloudabi64
ABI_SYSPATH.i386-linux= sys/i386/linux
ABI_SYSPATH.amd64-linux32= sys/amd64/linux32
ABIS+= freebsd
# Each ABI is expected to have an ABI.c, MACHINE_ARCH-ABI.c or
# MACHINE_CPUARCH-ABI.c file that will be used to map the syscall arguments.
.if ${MACHINE_CPUARCH} == "i386"
SRCS+= i386-linux.c linux_syscalls.h
CLEANFILES+=i386l-syscalls.master linux_syscalls.h
i386l-syscalls.master: ${.CURDIR}/../../sys/i386/linux/syscalls.master
cat ${.ALLSRC} > ${.TARGET}
linux_syscalls.h: i386l-syscalls.master
/bin/sh ${.CURDIR}/../../sys/kern/makesyscalls.sh ${.ALLSRC} \
${.CURDIR}/i386linux.conf
ABIS+= i386-linux
.endif
.if ${MACHINE_CPUARCH} == "amd64"
SRCS+= amd64-linux32.c linux32_syscalls.h
CLEANFILES+=amd64l32-syscalls.master linux32_syscalls.h
amd64l32-syscalls.master: ${.CURDIR}/../../sys/amd64/linux32/syscalls.master
cat ${.ALLSRC} > ${.TARGET}
linux32_syscalls.h: amd64l32-syscalls.master
/bin/sh ${.CURDIR}/../../sys/kern/makesyscalls.sh ${.ALLSRC} \
${.CURDIR}/amd64linux32.conf
SRCS+= amd64-fbsd32.c freebsd32_syscalls.h
CLEANFILES+=fbsd32-syscalls.master freebsd32_syscalls.h
fbsd32-syscalls.master: ${.CURDIR}/../../sys/compat/freebsd32/syscalls.master
cat ${.ALLSRC} > ${.TARGET}
freebsd32_syscalls.h: fbsd32-syscalls.master
/bin/sh ${.CURDIR}/../../sys/kern/makesyscalls.sh ${.ALLSRC} \
${.CURDIR}/fbsd32.conf
SRCS+= amd64-cloudabi64.c cloudabi64_syscalls.h
CLEANFILES+=amd64cloudabi64-syscalls.master cloudabi64_syscalls.h
amd64cloudabi64-syscalls.master: ${.CURDIR}/../../sys/compat/cloudabi64/syscalls.master
cat ${.ALLSRC} > ${.TARGET}
cloudabi64_syscalls.h: amd64cloudabi64-syscalls.master
/bin/sh ${.CURDIR}/../../sys/kern/makesyscalls.sh ${.ALLSRC} \
${.CURDIR}/amd64cloudabi64.conf
ABIS+= amd64-linux32
ABIS+= freebsd32
ABIS+= cloudabi64
.endif
.if ${MACHINE_ARCH} == "powerpc64"
SRCS+= powerpc-fbsd.c freebsd32_syscalls.h
CLEANFILES+=fbsd32-syscalls.master freebsd32_syscalls.h
fbsd32-syscalls.master: ${.CURDIR}/../../sys/compat/freebsd32/syscalls.master
cat ${.ALLSRC} > ${.TARGET}
freebsd32_syscalls.h: fbsd32-syscalls.master
/bin/sh ${.CURDIR}/../../sys/kern/makesyscalls.sh ${.ALLSRC} \
${.CURDIR}/fbsd32.conf
ABIS+= freebsd32
.endif
.for abi in ${ABIS}
# Find the right file to handle this ABI.
abi_src=
ABI_SRCS= ${abi}.c ${MACHINE_ARCH}-${abi}.c ${MACHINE_CPUARCH}-${abi}.c
.for f in ${ABI_SRCS}
.if exists(${.CURDIR}/${f}) && empty(abi_src)
abi_src= ${f}
.endif
.endfor
SRCS:= ${SRCS} ${abi_src} ${abi}_syscalls.h
CLEANFILES+= ${abi}_syscalls.conf ${abi}_syscalls.master ${abi}_syscalls.h
${abi}_syscalls.conf: ${.CURDIR}/makesyscallsconf.sh
/bin/sh ${.CURDIR}/makesyscallsconf.sh ${abi} ${.TARGET}
${abi}_syscalls.master: ${.CURDIR:H:H}/${ABI_SYSPATH.${abi}}/syscalls.master
cp -f ${.ALLSRC} ${.TARGET}
${abi}_syscalls.h: ${abi}_syscalls.master ${abi}_syscalls.conf \
${.CURDIR:H:H}/sys/kern/makesyscalls.sh
/bin/sh ${.CURDIR:H:H}/sys/kern/makesyscalls.sh \
${abi}_syscalls.master ${abi}_syscalls.conf
# Eliminate compiler warning about non-static global.
sed -i '' '/^const char \*/s/^/static /' ${.TARGET}.tmp
mv ${.TARGET}.tmp ${.TARGET}
.endfor
.include <bsd.prog.mk>

View File

@ -19,12 +19,12 @@ DIRDEPS = \
# local dependencies - needed for -jN in clean tree
amd64-cloudabi64.o: cloudabi64_syscalls.h
amd64-cloudabi64.po: cloudabi64_syscalls.h
amd64-fbsd.o: syscalls.h
amd64-fbsd.po: syscalls.h
amd64-fbsd32.o: freebsd32_syscalls.h
amd64-fbsd32.po: freebsd32_syscalls.h
amd64-linux32.o: linux32_syscalls.h
amd64-linux32.po: linux32_syscalls.h
amd64-freebsd.o: freebsd_syscalls.h
amd64-freebsd.po: freebsd_syscalls.h
amd64-freebsd32.o: freebsd32_syscalls.h
amd64-freebsd32.po: freebsd32_syscalls.h
amd64-linux32.o: amd64-linux32_syscalls.h
amd64-linux32.po: amd64-linux32_syscalls.h
ioctl.o: ioctl.c
ioctl.po: ioctl.c
.endif

View File

@ -42,8 +42,7 @@ __FBSDID("$FreeBSD$");
#include "truss.h"
extern const char *syscallnames[]; /* silence compiler */
#include "syscalls.h"
#include "freebsd_syscalls.h"
static int
aarch64_fetch_args(struct trussinfo *trussinfo, u_int narg)
@ -99,7 +98,7 @@ aarch64_fetch_retval(struct trussinfo *trussinfo, long *retval, int *errorp)
return (0);
}
static struct procabi aarch64_fbsd = {
static struct procabi aarch64_freebsd = {
"FreeBSD ELF64",
syscallnames,
nitems(syscallnames),
@ -107,4 +106,4 @@ static struct procabi aarch64_fbsd = {
aarch64_fetch_retval
};
PROCABI(aarch64_fbsd);
PROCABI(aarch64_freebsd);

View File

@ -171,8 +171,8 @@ amd64_cloudabi64_fetch_retval(struct trussinfo *trussinfo, long *retval,
static struct procabi amd64_cloudabi64 = {
"CloudABI ELF64",
cloudabi64_syscallnames,
nitems(cloudabi64_syscallnames),
syscallnames,
nitems(syscallnames),
amd64_cloudabi64_fetch_args,
amd64_cloudabi64_fetch_retval
};

View File

@ -44,7 +44,7 @@ __FBSDID("$FreeBSD$");
#include "truss.h"
#include "syscalls.h"
#include "freebsd_syscalls.h"
static int
amd64_fetch_args(struct trussinfo *trussinfo, u_int narg)
@ -120,7 +120,7 @@ amd64_fetch_retval(struct trussinfo *trussinfo, long *retval, int *errorp)
return (0);
}
static struct procabi amd64_fbsd = {
static struct procabi amd64_freebsd = {
"FreeBSD ELF64",
syscallnames,
nitems(syscallnames),
@ -128,4 +128,4 @@ static struct procabi amd64_fbsd = {
amd64_fetch_retval
};
PROCABI(amd64_fbsd);
PROCABI(amd64_freebsd);

View File

@ -32,7 +32,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/* FreeBSD/i386-specific system call handling. */
/* FreeBSD/amd64-freebsd32-specific system call handling. */
#include <sys/ptrace.h>
#include <sys/syscall.h>
@ -48,7 +48,7 @@ __FBSDID("$FreeBSD$");
#include "freebsd32_syscalls.h"
static int
amd64_fbsd32_fetch_args(struct trussinfo *trussinfo, u_int narg)
amd64_freebsd32_fetch_args(struct trussinfo *trussinfo, u_int narg)
{
struct ptrace_io_desc iorequest;
struct reg regs;
@ -98,7 +98,7 @@ amd64_fbsd32_fetch_args(struct trussinfo *trussinfo, u_int narg)
}
static int
amd64_fbsd32_fetch_retval(struct trussinfo *trussinfo, long *retval,
amd64_freebsd32_fetch_retval(struct trussinfo *trussinfo, long *retval,
int *errorp)
{
struct reg regs;
@ -116,22 +116,22 @@ amd64_fbsd32_fetch_retval(struct trussinfo *trussinfo, long *retval,
return (0);
}
static struct procabi amd64_fbsd32 = {
static struct procabi amd64_freebsd32 = {
"FreeBSD ELF32",
freebsd32_syscallnames,
nitems(freebsd32_syscallnames),
amd64_fbsd32_fetch_args,
amd64_fbsd32_fetch_retval
syscallnames,
nitems(syscallnames),
amd64_freebsd32_fetch_args,
amd64_freebsd32_fetch_retval
};
PROCABI(amd64_fbsd32);
PROCABI(amd64_freebsd32);
static struct procabi amd64_fbsd32_aout = {
static struct procabi amd64_freebsd32_aout = {
"FreeBSD a.out",
freebsd32_syscallnames,
nitems(freebsd32_syscallnames),
amd64_fbsd32_fetch_args,
amd64_fbsd32_fetch_retval
syscallnames,
nitems(syscallnames),
amd64_freebsd32_fetch_args,
amd64_freebsd32_fetch_retval
};
PROCABI(amd64_fbsd32_aout);
PROCABI(amd64_freebsd32_aout);

View File

@ -43,7 +43,7 @@ __FBSDID("$FreeBSD$");
#include "truss.h"
#include "linux32_syscalls.h"
#include "amd64-linux32_syscalls.h"
static int
amd64_linux32_fetch_args(struct trussinfo *trussinfo, u_int narg)
@ -132,8 +132,8 @@ amd64_linux32_fetch_retval(struct trussinfo *trussinfo, long *retval,
static struct procabi amd64_linux32 = {
"Linux ELF32",
linux32_syscallnames,
nitems(linux32_syscallnames),
syscallnames,
nitems(syscallnames),
amd64_linux32_fetch_args,
amd64_linux32_fetch_retval
};

View File

@ -1,13 +0,0 @@
# $FreeBSD$
sysnames="cloudabi64_syscalls.h"
sysproto="/dev/null"
sysproto_h="/dev/null"
syshdr="/dev/null"
sysmk="/dev/null"
syssw="/dev/null"
syshide="/dev/null"
syscallprefix="SYS_"
switchname="sysent"
namesname="cloudabi64_syscallnames"
systrace="/dev/null"

View File

@ -1,13 +0,0 @@
# $FreeBSD$
sysnames="linux32_syscalls.h"
sysproto="/dev/null"
sysproto_h="/dev/null"
syshdr="/dev/null"
sysmk="/dev/null"
syssw="/dev/null"
syshide="/dev/null"
syscallprefix="SYS_"
switchname="sysent"
namesname="linux32_syscallnames"
systrace="/dev/null"

View File

@ -45,7 +45,7 @@ __FBSDID("$FreeBSD$");
#include "truss.h"
#include "syscalls.h"
#include "freebsd_syscalls.h"
static int
arm_fetch_args(struct trussinfo *trussinfo, u_int narg)
@ -127,7 +127,7 @@ arm_fetch_retval(struct trussinfo *trussinfo, long *retval, int *errorp)
return (0);
}
static struct procabi arm_fbsd = {
static struct procabi arm_freebsd = {
"FreeBSD ELF32",
syscallnames,
nitems(syscallnames),
@ -135,4 +135,4 @@ static struct procabi arm_fbsd = {
arm_fetch_retval
};
PROCABI(arm_fbsd);
PROCABI(arm_freebsd);

View File

@ -1,13 +0,0 @@
# $FreeBSD$
sysnames="freebsd32_syscalls.h"
sysproto="/dev/null"
sysproto_h="/dev/null"
syshdr="/dev/null"
sysmk="/dev/null"
syssw="/dev/null"
syshide="/dev/null"
syscallprefix="SYS_"
switchname="sysent"
namesname="freebsd32_syscallnames"
systrace="/dev/null"

View File

@ -44,7 +44,7 @@ __FBSDID("$FreeBSD$");
#include "truss.h"
#include "syscalls.h"
#include "freebsd_syscalls.h"
static int
i386_fetch_args(struct trussinfo *trussinfo, u_int narg)
@ -109,7 +109,7 @@ i386_fetch_retval(struct trussinfo *trussinfo, long *retval, int *errorp)
return (0);
}
static struct procabi i386_fbsd = {
static struct procabi i386_freebsd = {
"FreeBSD ELF32",
syscallnames,
nitems(syscallnames),
@ -117,9 +117,9 @@ static struct procabi i386_fbsd = {
i386_fetch_retval
};
PROCABI(i386_fbsd);
PROCABI(i386_freebsd);
static struct procabi i386_fbsd_aout = {
static struct procabi i386_freebsd_aout = {
"FreeBSD a.out",
syscallnames,
nitems(syscallnames),
@ -127,5 +127,5 @@ static struct procabi i386_fbsd_aout = {
i386_fetch_retval
};
PROCABI(i386_fbsd_aout);
PROCABI(i386_freebsd_aout);

View File

@ -43,7 +43,7 @@ __FBSDID("$FreeBSD$");
#include "truss.h"
#include "linux_syscalls.h"
#include "i386-linux_syscalls.h"
static int
i386_linux_fetch_args(struct trussinfo *trussinfo, u_int narg)
@ -131,8 +131,8 @@ i386_linux_fetch_retval(struct trussinfo *trussinfo, long *retval, int *errorp)
static struct procabi i386_linux = {
"Linux ELF32",
linux_syscallnames,
nitems(linux_syscallnames),
syscallnames,
nitems(syscallnames),
i386_linux_fetch_args,
i386_linux_fetch_retval
};

View File

@ -1,13 +0,0 @@
# $FreeBSD$
sysnames="linux_syscalls.h"
sysproto="/dev/null"
sysproto_h="/dev/null"
syshdr="/dev/null"
sysmk="/dev/null"
syssw="/dev/null"
syshide="/dev/null"
syscallprefix="SYS_"
switchname="sysent"
namesname="linux_syscallnames"
systrace="/dev/null"

View File

@ -1,6 +1,13 @@
#! /bin/sh
# $FreeBSD$
sysnames="syscalls.h"
ABI="$1"
CONF="$2"
header="${ABI}_syscalls.h"
cat > "${CONF}" << EOF
sysnames="${header}.tmp"
sysproto="/dev/null"
sysproto_h="/dev/null"
syshdr="/dev/null"
@ -11,3 +18,4 @@ syscallprefix="SYS_"
switchname="sysent"
namesname="syscallnames"
systrace="/dev/null"
EOF

View File

@ -44,7 +44,7 @@ __FBSDID("$FreeBSD$");
#include "truss.h"
#include "syscalls.h"
#include "freebsd_syscalls.h"
static int
mips_fetch_args(struct trussinfo *trussinfo, u_int narg)
@ -126,7 +126,7 @@ mips_fetch_retval(struct trussinfo *trussinfo, long *retval, int *errorp)
}
static struct procabi mips_fbsd = {
static struct procabi mips_freebsd = {
#ifdef __mips_n64
"FreeBSD ELF64",
#else
@ -138,4 +138,4 @@ static struct procabi mips_fbsd = {
mips_fetch_retval
};
PROCABI(mips_fbsd);
PROCABI(mips_freebsd);

View File

@ -40,12 +40,7 @@ __FBSDID("$FreeBSD$");
#include "truss.h"
#ifdef __powerpc64__ /* 32-bit compatibility */
#include "freebsd32_syscalls.h"
#define syscallnames freebsd32_syscallnames
#else /* native 32-bit */
#include "syscalls.h"
#endif
#include "freebsd_syscalls.h"
static int
powerpc_fetch_args(struct trussinfo *trussinfo, u_int narg)
@ -82,34 +77,16 @@ powerpc_fetch_args(struct trussinfo *trussinfo, u_int narg)
}
for (i = 0; i < narg && reg < NARGREG; i++, reg++) {
#ifdef __powerpc64__
cs->args[i] = regs.fixreg[FIRSTARG + reg] & 0xffffffff;
#else
cs->args[i] = regs.fixreg[FIRSTARG + reg];
#endif
}
if (narg > i) {
#ifdef __powerpc64__
uint32_t args32[narg - i];
u_int j;
#endif
iorequest.piod_op = PIOD_READ_D;
iorequest.piod_offs = (void *)(regs.fixreg[1] + 8);
#ifdef __powerpc64__
iorequest.piod_addr = args32;
iorequest.piod_len = sizeof(args32);
#else
iorequest.piod_addr = &cs->args[i];
iorequest.piod_len = (narg - i) * sizeof(cs->args[0]);
#endif
ptrace(PT_IO, tid, (caddr_t)&iorequest, 0);
if (iorequest.piod_len == 0)
return (-1);
#ifdef __powerpc64__
for (j = 0; j < narg - i; j++)
cs->args[i + j] = args32[j];
#endif
}
return (0);
@ -128,18 +105,13 @@ powerpc_fetch_retval(struct trussinfo *trussinfo, long *retval, int *errorp)
}
/* XXX: Does not have fixup for __syscall(). */
#ifdef __powerpc64__
retval[0] = regs.fixreg[3] & 0xffffffff;
retval[1] = regs.fixreg[4] & 0xffffffff;
#else
retval[0] = regs.fixreg[3];
retval[1] = regs.fixreg[4];
#endif
*errorp = !!(regs.cr & 0x10000000);
return (0);
}
static struct procabi powerpc_fbsd = {
static struct procabi powerpc_freebsd = {
"FreeBSD ELF32",
syscallnames,
nitems(syscallnames),
@ -147,4 +119,4 @@ static struct procabi powerpc_fbsd = {
powerpc_fetch_retval
};
PROCABI(powerpc_fbsd);
PROCABI(powerpc_freebsd);

View File

@ -40,7 +40,7 @@ __FBSDID("$FreeBSD$");
#include "truss.h"
#include "syscalls.h"
#include "freebsd_syscalls.h"
static int
powerpc64_fetch_args(struct trussinfo *trussinfo, u_int narg)
@ -107,7 +107,7 @@ powerpc64_fetch_retval(struct trussinfo *trussinfo, long *retval, int *errorp)
return (0);
}
static struct procabi powerpc64_fbsd = {
static struct procabi powerpc64_freebsd = {
"FreeBSD ELF64",
syscallnames,
nitems(syscallnames),
@ -115,4 +115,4 @@ static struct procabi powerpc64_fbsd = {
powerpc64_fetch_retval
};
PROCABI(powerpc64_fbsd);
PROCABI(powerpc64_freebsd);

View File

@ -0,0 +1,127 @@
/*
* Copyright 2006 Peter Grehan <grehan@freebsd.org>
* Copyright 2005 Orlando Bassotto <orlando@break.net>
* Copyright 1998 Sean Eric Fagan
*
* 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$");
/* FreeBSD/powerpc64-freebsd32-specific system call handling. */
#include <sys/ptrace.h>
#include <sys/syscall.h>
#include <machine/reg.h>
#include <machine/frame.h>
#include <stdio.h>
#include "truss.h"
#include "freebsd32_syscalls.h"
static int
powerpc64_freebsd32_fetch_args(struct trussinfo *trussinfo, u_int narg)
{
struct ptrace_io_desc iorequest;
struct reg regs;
struct current_syscall *cs;
lwpid_t tid;
u_int i, reg;
tid = trussinfo->curthread->tid;
cs = &trussinfo->curthread->cs;
if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
return (-1);
}
/*
* FreeBSD has two special kinds of system call redirections --
* SYS_syscall, and SYS___syscall. The former is the old syscall()
* routine, basically; the latter is for quad-aligned arguments.
*
* The system call argument count and code from ptrace() already
* account for these, but we need to skip over the first argument.
*/
reg = 0;
switch (regs.fixreg[0]) {
case SYS_syscall:
reg += 1;
break;
case SYS___syscall:
reg += 2;
break;
}
for (i = 0; i < narg && reg < NARGREG; i++, reg++) {
cs->args[i] = regs.fixreg[FIRSTARG + reg] & 0xffffffff;
}
if (narg > i) {
uint32_t args32[narg - i];
u_int j;
iorequest.piod_op = PIOD_READ_D;
iorequest.piod_offs = (void *)(regs.fixreg[1] + 8);
iorequest.piod_addr = args32;
iorequest.piod_len = sizeof(args32);
ptrace(PT_IO, tid, (caddr_t)&iorequest, 0);
if (iorequest.piod_len == 0)
return (-1);
for (j = 0; j < narg - i; j++)
cs->args[i + j] = args32[j];
}
return (0);
}
static int
powerpc64_freebsd32_fetch_retval(struct trussinfo *trussinfo, long *retval, int *errorp)
{
struct reg regs;
lwpid_t tid;
tid = trussinfo->curthread->tid;
if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
return (-1);
}
/* XXX: Does not have fixup for __syscall(). */
retval[0] = regs.fixreg[3] & 0xffffffff;
retval[1] = regs.fixreg[4] & 0xffffffff;
*errorp = !!(regs.cr & 0x10000000);
return (0);
}
static struct procabi powerpc64_freebsd32 = {
"FreeBSD ELF32",
syscallnames,
nitems(syscallnames),
powerpc64_freebsd32_fetch_args,
powerpc64_freebsd32_fetch_retval
};
PROCABI(powerpc64_freebsd32);

View File

@ -46,7 +46,7 @@ __FBSDID("$FreeBSD$");
#include "truss.h"
#include "syscalls.h"
#include "freebsd_syscalls.h"
static int
sparc64_fetch_args(struct trussinfo *trussinfo, u_int narg)
@ -114,7 +114,7 @@ sparc64_fetch_retval(struct trussinfo *trussinfo, long *retval, int *errorp)
return (0);
}
static struct procabi sparc64_fbsd = {
static struct procabi sparc64_freebsd = {
"FreeBSD ELF64",
syscallnames,
nitems(syscallnames),
@ -122,4 +122,4 @@ static struct procabi sparc64_fbsd = {
sparc64_fetch_retval
};
PROCABI(sparc64_fbsd);
PROCABI(sparc64_freebsd);

View File

@ -623,6 +623,7 @@ do_xxfiles(char *tag, FILE *fp)
slen = strlen(suff);
fprintf(fp, "%sFILES=", SUFF);
free(SUFF);
lpos = 8;
STAILQ_FOREACH(tp, &ftab, f_next)
if (tp->f_type != NODEPEND) {
@ -641,6 +642,7 @@ do_xxfiles(char *tag, FILE *fp)
fprintf(fp, "%s ", tp->f_fn);
lpos += len + 1;
}
free(suff);
if (lpos != 8)
putc('\n', fp);
}