Example #1
0
static u32 check_header(const void *buf)
{
	u32 i, pattern;
	int swap = SWAP_NO;
	u32 *test = (u32 *)buf;

	debug("%s: Let's check bitstream header\n", __func__);

	/* Checking that passing bin is not a bitstream */
	for (i = 0; i < ARRAY_SIZE(bin_format); i++) {
		pattern = load_word(&test[i], swap);

		/*
		 * Bitstreams in binary format are swapped
		 * compare to regular bistream.
		 * Do not swap dummy word but if swap is done assume
		 * that parsing buffer is binary format
		 */
		if ((__swab32(pattern) != DUMMY_WORD) &&
		    (__swab32(pattern) == bin_format[i])) {
			swap = SWAP_DONE;
			debug("%s: data swapped - let's swap\n", __func__);
		}

		debug("%s: %d/%px: pattern %x/%x bin_format\n", __func__, i,
		      &test[i], pattern, bin_format[i]);
	}
	debug("%s: Found bitstream header at %px %s swapinng\n", __func__,
	      buf, swap == SWAP_NO ? "without" : "with");

	return swap;
}
Example #2
0
File: lutil.c Project: LLNL/lustre
void liblustre_init_random()
{
    int seed[2];
    struct timeval tv;

#ifdef LIBLUSTRE_USE_URANDOM
    int _rand_dev_fd;
    _rand_dev_fd = syscall(SYS_open, "/dev/urandom", O_RDONLY);
    if (_rand_dev_fd >= 0) {
        if (syscall(SYS_read, _rand_dev_fd,
                    &seed, sizeof(seed)) == sizeof(seed)) {
            cfs_srand(seed[0], seed[1]);
            syscall(SYS_close, _rand_dev_fd);
            return;
        }
        syscall(SYS_close, _rand_dev_fd);
    }
#endif /* LIBLUSTRE_USE_URANDOM */

#ifdef HAVE_GETHOSTBYNAME
    seed[0] = get_ipv4_addr();
#else
    seed[0] = _my_pnid;
#endif
    gettimeofday(&tv, NULL);
    cfs_srand(tv.tv_sec ^ __swab32(seed[0]), tv.tv_usec ^__swab32(getpid()));
}
Example #3
0
/**
 * Get the striping layout for the file referenced by file descriptor \a fd.
 *
 * If the filesystem does not support the "lustre." xattr namespace, the
 * file must be on a non-Lustre filesystem, so set errno to ENOTTY per
 * convention.  If the file has no "lustre.lov" data, the file will
 * inherit default values, so return a default layout.
 *
 * If the kernel gives us back less than the expected amount of data,
 * we fail with errno set to EINTR.
 *
 * \param[in] fd	open file descriptor
 * \param[in] flags	open file descriptor
 *
 * \retval	valid llapi_layout pointer on success
 * \retval	NULL if an error occurs
 */
struct llapi_layout *llapi_layout_get_by_fd(int fd, uint32_t flags)
{
    size_t lum_len;
    struct lov_user_md *lum;
    struct llapi_layout *layout = NULL;
    ssize_t bytes_read;
    int object_count;
    struct stat st;

    lum_len = XATTR_SIZE_MAX;
    lum = malloc(lum_len);
    if (lum == NULL)
        return NULL;

    bytes_read = fgetxattr(fd, XATTR_LUSTRE_LOV, lum, lum_len);
    if (bytes_read < 0) {
        if (errno == EOPNOTSUPP)
            errno = ENOTTY;
        else if (errno == ENODATA)
            layout = llapi_layout_alloc();
        goto out;
    }

    /* Return an error if we got back a partial layout. */
    if (llapi_layout_lum_truncated(lum, bytes_read)) {
        errno = EINTR;
        goto out;
    }

    object_count = llapi_layout_objects_in_lum(lum, bytes_read);

    /* Directories may have a positive non-zero lum->lmm_stripe_count
     * yet have an empty lum->lmm_objects array. For non-directories the
     * amount of data returned from the kernel must be consistent
     * with the stripe count. */
    if (fstat(fd, &st) < 0)
        goto out;

    if (!S_ISDIR(st.st_mode) && object_count != lum->lmm_stripe_count) {
        errno = EINTR;
        goto out;
    }

    if (lum->lmm_magic == __swab32(LOV_MAGIC_V1) ||
            lum->lmm_magic == __swab32(LOV_MAGIC_V3))
        llapi_layout_swab_lov_user_md(lum, object_count);

    layout = llapi_layout_from_lum(lum, object_count);

out:
    free(lum);
    return layout;
}
Example #4
0
int hw_atl_utils_get_mac_permanent(struct aq_hw_s *self,
				   u8 *mac)
{
	int err = 0;
	u32 h = 0U;
	u32 l = 0U;
	u32 mac_addr[2];

	if (!aq_hw_read_reg(self, HW_ATL_UCP_0X370_REG)) {
		unsigned int rnd = 0;
		unsigned int ucp_0x370 = 0;

		get_random_bytes(&rnd, sizeof(unsigned int));

		ucp_0x370 = 0x02020202 | (0xFEFEFEFE & rnd);
		aq_hw_write_reg(self, HW_ATL_UCP_0X370_REG, ucp_0x370);
	}

	err = hw_atl_utils_fw_downld_dwords(self,
					    aq_hw_read_reg(self, 0x00000374U) +
					    (40U * 4U),
					    mac_addr,
					    ARRAY_SIZE(mac_addr));
	if (err < 0) {
		mac_addr[0] = 0U;
		mac_addr[1] = 0U;
		err = 0;
	} else {
		mac_addr[0] = __swab32(mac_addr[0]);
		mac_addr[1] = __swab32(mac_addr[1]);
	}

	ether_addr_copy(mac, (u8 *)mac_addr);

	if ((mac[0] & 0x01U) || ((mac[0] | mac[1] | mac[2]) == 0x00U)) {
		/* chip revision */
		l = 0xE3000000U
			| (0xFFFFU & aq_hw_read_reg(self, HW_ATL_UCP_0X370_REG))
			| (0x00 << 16);
		h = 0x8001300EU;

		mac[5] = (u8)(0xFFU & l);
		l >>= 8;
		mac[4] = (u8)(0xFFU & l);
		l >>= 8;
		mac[3] = (u8)(0xFFU & l);
		l >>= 8;
		mac[2] = (u8)(0xFFU & l);
		mac[1] = (u8)(0xFFU & h);
		h >>= 8;
		mac[0] = (u8)(0xFFU & h);
	}
Example #5
0
/**
 * Check if the given \a lum_size is large enough to hold the required
 * fields in \a lum.
 *
 * \param[in] lum	the struct lov_user_md to check
 * \param[in] lum_size	the number of bytes in \a lum
 *
 * \retval true		the \a lum_size is too small
 * \retval false	the \a lum_size is large enough
 */
static bool llapi_layout_lum_truncated(struct lov_user_md *lum, size_t lum_size)
{
    uint32_t magic;

    if (lum_size < lov_user_md_size(0, LOV_MAGIC_V1))
        return false;

    if (lum->lmm_magic == __swab32(LOV_MAGIC_V1) ||
            lum->lmm_magic == __swab32(LOV_MAGIC_V3))
        magic = __swab32(lum->lmm_magic);
    else
        magic = lum->lmm_magic;

    return lum_size < lov_user_md_size(0, magic);
}
Example #6
0
int memory_display(const void *addr, loff_t offs, unsigned nbytes, int size, int swab)
{
	ulong linebytes, i;
	u_char	*cp;

	/* Print the lines.
	 *
	 * We buffer all read data, so we can make sure data is read only
	 * once, and all accesses are with the specified bus width.
	 */
	do {
		char linebuf[DISP_LINE_LEN];
		uint32_t *uip = (uint   *)linebuf;
		uint16_t *usp = (ushort *)linebuf;
		uint8_t *ucp = (u_char *)linebuf;
		unsigned count = 52;

		printf("%08llx:", offs);
		linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes;

		for (i = 0; i < linebytes; i += size) {
			if (size == 4) {
				u32 res;
				res = (*uip++ = *((uint *)addr));
				if (swab)
					res = __swab32(res);
				count -= printf(" %08x", res);
			} else if (size == 2) {
				u16 res;
				res = (*usp++ = *((ushort *)addr));
				if (swab)
					res = __swab16(res);
				count -= printf(" %04x", res);
			} else {
				count -= printf(" %02x", (*ucp++ = *((u_char *)addr)));
			}
			addr += size;
			offs += size;
		}

		while (count--)
			putchar(' ');

		cp = (uint8_t *)linebuf;
		for (i = 0; i < linebytes; i++) {
			if ((*cp < 0x20) || (*cp > 0x7e))
				putchar('.');
			else
				printf("%c", *cp);
			cp++;
		}

		putchar('\n');
		nbytes -= linebytes;
		if (ctrlc())
			return -EINTR;
	} while (nbytes > 0);

	return 0;
}
Example #7
0
/**
 * Swap endianess to read data on an i.MX28 based platform
 * @param buf Pointer to little endian data
 * @param len Size in words (max. 1500 bytes)
 *
 * TODO: Check for the risk of destroying some other data behind the buffer
 * if its size is not a multiple of 4.
 */
static void imx28_fix_endianess_rd(uint32_t *buf, unsigned wlen)
{
	unsigned u;

	for (u = 0; u < wlen; u++, buf++)
		*buf = __swab32(*buf);
}
Example #8
0
int flash_vs_read(uint8_t *buf, loff_t offs, int len, int extra)
{
	uint8_t tx[8] = {0, 0, 0, FLASH_CMD_FARD };
	int remain = len, *d = (int *)&tx[4];
	struct spi_transfer td[] = {
		{NULL, &tx[3], 5 },
		{buf,  NULL, 0 }
	}, *p;

//	printf("spi: r (b=%p, o=0x%llx, l=0x%x)\n", buf, offs, len);

	for(p = &td[1]; remain;) {

		*d = offs;
		*d = __swab32(*d);
		*d >>= 8;

		p->len = (remain < FLASH_READ_BLOCK)?
			remain: FLASH_READ_BLOCK;

		spi_exchange(td, ARRAY_SIZE(td));
		remain -= p->len;
		offs   += p->len;
		p->in  += p->len;
	}

	return len;
}
Example #9
0
static void swap_packet(uint32_t *packet, int length)
{
	int i;

	for (i = 0; i < DIV_ROUND_UP(length, 4); i++)
		packet[i] = __swab32(packet[i]);
}
Example #10
0
int flash_vs_write(uint8_t *buf, loff_t offs, int len, int extra)
{
	uint8_t tx[8] = { FLASH_CMD_WREN, 0, 0, FLASH_CMD_WRIT };
	int remain = len, *d = (int *)&tx[4];
	struct spi_transfer td[] = {
		{NULL, &tx[4], 4 },
		{NULL, buf,    0 },
	}, *p;
	
//	printf("spi: w (b=%p, o=0x%llx, l=0x%x)\n", buf, offs, len);

	for(p = &td[1]; remain;) {
		*d = offs;
		*d = __swab32(*d);
		*d &= ~0xff;
		*d |= FLASH_CMD_WRIT;
		p->len = (remain < spibytes) ? remain: spibytes;

		flash_wren();
		spi_exchange(td, ARRAY_SIZE(td));
		flash_poll(FLASH_MOD_POLLREDY);

		remain -= p->len;
		offs   += p->len;
		p->out += p->len;
	}

	return len;
}
Example #11
0
static struct crm_remote_header_v0 *
crm_remote_header(crm_remote_t * remote)
{
    struct crm_remote_header_v0 *header = (struct crm_remote_header_v0 *)remote->buffer;
    if(remote->buffer_offset < sizeof(struct crm_remote_header_v0)) {
        return NULL;

    } else if(header->endian != ENDIAN_LOCAL) {
        uint32_t endian = __swab32(header->endian);

        CRM_LOG_ASSERT(endian == ENDIAN_LOCAL);
        if(endian != ENDIAN_LOCAL) {
            crm_err("Invalid message detected, endian mismatch: %lx is neither %lx nor the swab'd %lx",
                    ENDIAN_LOCAL, header->endian, endian);
            return NULL;
        }

        header->id = __swab64(header->id);
        header->flags = __swab64(header->flags);
        header->endian = __swab32(header->endian);

        header->version = __swab32(header->version);
        header->size_total = __swab32(header->size_total);
        header->payload_offset = __swab32(header->payload_offset);
        header->payload_compressed = __swab32(header->payload_compressed);
        header->payload_uncompressed = __swab32(header->payload_uncompressed);
    }

    return header;
}
Example #12
0
/**
 * Swap endianess to send data on an i.MX28 based platform
 * @param buf Pointer to little endian data
 * @param len Size in words (max. 1500 bytes)
 * @return Pointer to the big endian data
 */
static void *imx28_fix_endianess_wr(uint32_t *buf, unsigned wlen)
{
	unsigned u;
	static uint32_t data[376];	/* = 1500 bytes + 4 bytes */

	for (u = 0; u < wlen; u++, buf++)
		data[u] = __swab32(*buf);

	return data;
}
Example #13
0
/**
 * Mark the linkEA as overflow with current timestamp,
 * and remove the last linkEA entry.
 *
 * Return the new linkEA size.
 */
int linkea_overflow_shrink(struct linkea_data *ldata)
{
	struct link_ea_header *leh;
	struct lu_name tname;
	struct lu_fid tfid;
	int count;

	leh = ldata->ld_leh = ldata->ld_buf->lb_buf;
	if (leh->leh_magic == __swab32(LINK_EA_MAGIC)) {
		leh->leh_magic = LINK_EA_MAGIC;
		leh->leh_reccount = __swab32(leh->leh_reccount);
		leh->leh_overflow_time = __swab32(leh->leh_overflow_time);
		leh->leh_padding = __swab32(leh->leh_padding);
	}

	LASSERT(leh->leh_reccount > 0);

	leh->leh_len = sizeof(struct link_ea_header);
	leh->leh_reccount--;
	if (unlikely(leh->leh_reccount == 0))
		return 0;

	leh->leh_overflow_time = cfs_time_current_sec();
	if (unlikely(leh->leh_overflow_time == 0))
		leh->leh_overflow_time++;
	ldata->ld_reclen = 0;
	ldata->ld_lee = (struct link_ea_entry *)(leh + 1);
	for (count = 0; count < leh->leh_reccount; count++) {
		linkea_entry_unpack(ldata->ld_lee, &ldata->ld_reclen,
				    &tname, &tfid);
		leh->leh_len += ldata->ld_reclen;
		ldata->ld_lee = (struct link_ea_entry *)((char *)ldata->ld_lee +
							 ldata->ld_reclen);
	}

	linkea_entry_unpack(ldata->ld_lee, &ldata->ld_reclen, &tname, &tfid);
	CDEBUG(D_INODE, "No enough space to hold the last linkea entry '"
	       DFID": %.*s', shrink it, left %d linkea entries, size %llu\n",
	       PFID(&tfid), tname.ln_namelen, tname.ln_name,
	       leh->leh_reccount, leh->leh_len);

	return leh->leh_len;
}
Example #14
0
/* include/linux/byteorder does not support "unsigned long" type */
static inline unsigned long ext2_swab(const unsigned long y)
{
#if BITS_PER_LONG == 64
	return (unsigned long) __swab64((u64) y);
#elif BITS_PER_LONG == 32
	return (unsigned long) __swab32((u32) y);
#else
#error BITS_PER_LONG not defined
#endif
}
Example #15
0
/*
 * please see comment above LOV_MAGIC_V1_DEF
 */
static void mdt_fix_lov_magic(struct mdt_thread_info *info)
{
	struct mdt_reint_record *rr = &info->mti_rr;
	struct lov_user_md_v1   *v1;

	v1 = (void *)rr->rr_eadata;
	LASSERT(v1);

	if (unlikely(req_is_replay(mdt_info_req(info)))) {
		if (v1->lmm_magic == LOV_USER_MAGIC_V1) {
			v1->lmm_magic = LOV_MAGIC_V1_DEF;
		} else if (v1->lmm_magic == __swab32(LOV_USER_MAGIC_V1)) {
			v1->lmm_magic = __swab32(LOV_MAGIC_V1_DEF);
		} else if (v1->lmm_magic == LOV_USER_MAGIC_V3) {
			v1->lmm_magic = LOV_MAGIC_V3_DEF;
		} else if (v1->lmm_magic == __swab32(LOV_USER_MAGIC_V3)) {
			v1->lmm_magic = __swab32(LOV_MAGIC_V3_DEF);
		}
	}
}
Example #16
0
int linkea_init(struct linkea_data *ldata)
{
	struct link_ea_header *leh;

	LASSERT(ldata->ld_buf);
	leh = ldata->ld_buf->lb_buf;
	if (leh->leh_magic == __swab32(LINK_EA_MAGIC)) {
		leh->leh_magic = LINK_EA_MAGIC;
		leh->leh_reccount = __swab32(leh->leh_reccount);
		leh->leh_len = __swab64(leh->leh_len);
		/* entries are swabbed by linkea_entry_unpack */
	}
	if (leh->leh_magic != LINK_EA_MAGIC)
		return -EINVAL;
	if (leh->leh_reccount == 0)
		return -ENODATA;

	ldata->ld_leh = leh;
	return 0;
}
Example #17
0
/**
 * Compute the number of elements in the lmm_objects array of \a lum
 * with size \a lum_size.
 *
 * \param[in] lum	the struct lov_user_md to check
 * \param[in] lum_size	the number of bytes in \a lum
 *
 * \retval		number of elements in array lum->lmm_objects
 */
static int llapi_layout_objects_in_lum(struct lov_user_md *lum, size_t lum_size)
{
    uint32_t magic;
    size_t base_size;

    if (lum_size < lov_user_md_size(0, LOV_MAGIC_V1))
        return 0;

    if (lum->lmm_magic == __swab32(LOV_MAGIC_V1) ||
            lum->lmm_magic == __swab32(LOV_MAGIC_V3))
        magic = __swab32(lum->lmm_magic);
    else
        magic = lum->lmm_magic;

    base_size = lov_user_md_size(0, magic);

    if (lum_size <= base_size)
        return 0;
    else
        return (lum_size - base_size) / sizeof(lum->lmm_objects[0]);
}
Example #18
0
int linkea_init(struct linkea_data *ldata)
{
	struct link_ea_header *leh;

	LASSERT(ldata->ld_buf != NULL);
	leh = ldata->ld_buf->lb_buf;
	if (leh->leh_magic == __swab32(LINK_EA_MAGIC)) {
		leh->leh_magic = LINK_EA_MAGIC;
		leh->leh_reccount = __swab32(leh->leh_reccount);
		leh->leh_len = __swab64(leh->leh_len);
		leh->leh_overflow_time = __swab32(leh->leh_overflow_time);
		leh->leh_padding = __swab32(leh->leh_padding);
		/* individual entries are swabbed by linkea_entry_unpack() */
	}

	if (leh->leh_magic != LINK_EA_MAGIC)
		return -EINVAL;

	if (leh->leh_reccount == 0 && leh->leh_overflow_time == 0)
		return -ENODATA;

	ldata->ld_leh = leh;
	return 0;
}
Example #19
0
static int
ping_server_handle(struct srpc_server_rpc *rpc)
{
	struct srpc_service	*sv  = rpc->srpc_scd->scd_svc;
	srpc_msg_t	*reqstmsg = &rpc->srpc_reqstbuf->buf_msg;
	srpc_msg_t	  *replymsg = &rpc->srpc_replymsg;
	srpc_ping_reqst_t *req = &reqstmsg->msg_body.ping_reqst;
	srpc_ping_reply_t *rep = &rpc->srpc_replymsg.msg_body.ping_reply;

	LASSERT (sv->sv_id == SRPC_SERVICE_PING);

	if (reqstmsg->msg_magic != SRPC_MSG_MAGIC) {
		LASSERT (reqstmsg->msg_magic == __swab32(SRPC_MSG_MAGIC));

		__swab32s(&req->pnr_seq);
		__swab32s(&req->pnr_magic);
		__swab64s(&req->pnr_time_sec);
		__swab64s(&req->pnr_time_usec);
	}
	LASSERT (reqstmsg->msg_type == srpc_service2request(sv->sv_id));

	if (req->pnr_magic != LST_PING_TEST_MAGIC) {
		CERROR ("Unexpected magic %08x from %s\n",
			req->pnr_magic, libcfs_id2str(rpc->srpc_peer));
		return -EINVAL;
	}

	rep->pnr_seq   = req->pnr_seq;
	rep->pnr_magic = LST_PING_TEST_MAGIC;

	if ((reqstmsg->msg_ses_feats & ~LST_FEATS_MASK) != 0) {
		replymsg->msg_ses_feats = LST_FEATS_MASK;
		rep->pnr_status = EPROTO;
		return 0;
	}

	replymsg->msg_ses_feats = reqstmsg->msg_ses_feats;

	CDEBUG(D_NET, "Get ping %d from %s\n",
	       req->pnr_seq, libcfs_id2str(rpc->srpc_peer));
	return 0;
}
int nouveau_load(struct drm_device *dev, unsigned long flags)
{
	struct drm_nouveau_private *dev_priv;
	void __iomem *regs;
	uint32_t reg0,reg1;
	uint8_t architecture = 0;

	dev_priv = drm_calloc(1, sizeof(*dev_priv), DRM_MEM_DRIVER);
	if (!dev_priv)
		return -ENOMEM;

	dev_priv->flags = flags & NOUVEAU_FLAGS;
	dev_priv->init_state = NOUVEAU_CARD_INIT_DOWN;

	DRM_DEBUG("vendor: 0x%X device: 0x%X class: 0x%X\n", dev->pci_vendor, dev->pci_device, dev->pdev->class);

	/* Time to determine the card architecture */
	regs = ioremap_nocache(pci_resource_start(dev->pdev, 0), 0x8);
	if (!regs) {
		DRM_ERROR("Could not ioremap to determine register\n");
		return -ENOMEM;
	}

	reg0 = readl(regs+NV03_PMC_BOOT_0);
	reg1 = readl(regs+NV03_PMC_BOOT_1);
#if defined(__powerpc__)
	if (reg1)
		reg0=__swab32(reg0);
#endif

	/* We're dealing with >=NV10 */
	if ((reg0 & 0x0f000000) > 0 ) {
		/* Bit 27-20 contain the architecture in hex */
		architecture = (reg0 & 0xff00000) >> 20;
	/* NV04 or NV05 */
	} else if ((reg0 & 0xff00fff0) == 0x20004000) {
Example #21
0
static int __lov_setstripe(struct obd_export *exp, int max_lmm_size,
                           struct lov_stripe_md **lsmp,
                           struct lov_user_md *lump)
{
    struct obd_device *obd = class_exp2obd(exp);
    struct lov_obd *lov = &obd->u.lov;
    char buffer[sizeof(struct lov_user_md_v3)];
    struct lov_user_md_v3 *lumv3 = (struct lov_user_md_v3 *)&buffer[0];
    struct lov_user_md_v1 *lumv1 = (struct lov_user_md_v1 *)&buffer[0];
    int lmm_magic;
    int stripe_count;
    int rc;
    ENTRY;

    if (cfs_copy_from_user(lumv3, lump, sizeof(struct lov_user_md_v1)))
        RETURN(-EFAULT);

    lmm_magic = lumv1->lmm_magic;

    if (lmm_magic == __swab32(LOV_USER_MAGIC_V1)) {
        lustre_swab_lov_user_md_v1(lumv1);
        lmm_magic = LOV_USER_MAGIC_V1;
    } else if (lmm_magic == LOV_USER_MAGIC_V3) {
        if (cfs_copy_from_user(lumv3, lump, sizeof(*lumv3)))
            RETURN(-EFAULT);
    } else if (lmm_magic == __swab32(LOV_USER_MAGIC_V3)) {
        if (cfs_copy_from_user(lumv3, lump, sizeof(*lumv3)))
            RETURN(-EFAULT);
        lustre_swab_lov_user_md_v3(lumv3);
        lmm_magic = LOV_USER_MAGIC_V3;
    } else if (lmm_magic != LOV_USER_MAGIC_V1) {
        CDEBUG(D_IOCTL,
               "bad userland LOV MAGIC: %#08x != %#08x nor %#08x\n",
               lmm_magic, LOV_USER_MAGIC_V1, LOV_USER_MAGIC_V3);
        RETURN(-EINVAL);
    }

    /* in the rest of the tests, as *lumv1 and lumv3 have the same
     * fields, we use lumv1 to avoid code duplication */

    if (lumv1->lmm_pattern == 0) {
        lumv1->lmm_pattern = lov->desc.ld_pattern ?
                             lov->desc.ld_pattern : LOV_PATTERN_RAID0;
    }

    if (lumv1->lmm_pattern != LOV_PATTERN_RAID0) {
        CDEBUG(D_IOCTL, "bad userland stripe pattern: %#x\n",
               lumv1->lmm_pattern);
        RETURN(-EINVAL);
    }

    /* 64kB is the largest common page size we see (ia64), and matches the
     * check in lfs */
    if (lumv1->lmm_stripe_size & (LOV_MIN_STRIPE_SIZE - 1)) {
        CDEBUG(D_IOCTL, "stripe size %u not multiple of %u, fixing\n",
               lumv1->lmm_stripe_size, LOV_MIN_STRIPE_SIZE);
        lumv1->lmm_stripe_size = LOV_MIN_STRIPE_SIZE;
    }

    if ((lumv1->lmm_stripe_offset >= lov->desc.ld_tgt_count) &&
            (lumv1->lmm_stripe_offset !=
             (typeof(lumv1->lmm_stripe_offset))(-1))) {
        CDEBUG(D_IOCTL, "stripe offset %u > number of OSTs %u\n",
               lumv1->lmm_stripe_offset, lov->desc.ld_tgt_count);
        RETURN(-EINVAL);
    }
    stripe_count = lov_get_stripecnt(lov, lumv1->lmm_stripe_count);

    if (max_lmm_size) {
        int max_stripes = (max_lmm_size -
                           lov_mds_md_size(0, lmm_magic)) /
                          sizeof(struct lov_ost_data_v1);
        if (unlikely(max_stripes < stripe_count)) {
            CDEBUG(D_IOCTL, "stripe count reset from %d to %d\n",
                   stripe_count, max_stripes);
            stripe_count = max_stripes;
        }
    }

    if (lmm_magic == LOV_USER_MAGIC_V3) {
        struct pool_desc *pool;

        pool = lov_find_pool(lov, lumv3->lmm_pool_name);
        if (pool != NULL) {
            if (lumv3->lmm_stripe_offset !=
                    (typeof(lumv3->lmm_stripe_offset))(-1)) {
                rc = lov_check_index_in_pool(
                         lumv3->lmm_stripe_offset, pool);
                if (rc < 0) {
                    lov_pool_putref(pool);
                    RETURN(-EINVAL);
                }
            }

            if (stripe_count > pool_tgt_count(pool))
                stripe_count = pool_tgt_count(pool);

            lov_pool_putref(pool);
        }
    }

    rc = lov_alloc_memmd(lsmp, stripe_count, lumv1->lmm_pattern, lmm_magic);

    if (rc >= 0) {
        (*lsmp)->lsm_oinfo[0]->loi_ost_idx = lumv1->lmm_stripe_offset;
        (*lsmp)->lsm_stripe_size = lumv1->lmm_stripe_size;
        if (lmm_magic == LOV_USER_MAGIC_V3)
            strncpy((*lsmp)->lsm_pool_name, lumv3->lmm_pool_name,
                    LOV_MAXPOOLNAME);
        rc = 0;
    }

    RETURN(rc);
}
Example #22
0
static int osd_find_parent_fid(const struct lu_env *env, struct dt_object *o,
			       struct lu_fid *fid)
{
	struct link_ea_header  *leh;
	struct link_ea_entry   *lee;
	struct lu_buf		buf;
	int			rc;
	ENTRY;

	buf.lb_buf = osd_oti_get(env)->oti_buf;
	buf.lb_len = sizeof(osd_oti_get(env)->oti_buf);

	rc = osd_xattr_get(env, o, &buf, XATTR_NAME_LINK, BYPASS_CAPA);
	if (rc == -ERANGE) {
		rc = osd_xattr_get(env, o, &LU_BUF_NULL,
				   XATTR_NAME_LINK, BYPASS_CAPA);
		if (rc < 0)
			RETURN(rc);
		LASSERT(rc > 0);
		OBD_ALLOC(buf.lb_buf, rc);
		if (buf.lb_buf == NULL)
			RETURN(-ENOMEM);
		buf.lb_len = rc;
		rc = osd_xattr_get(env, o, &buf, XATTR_NAME_LINK, BYPASS_CAPA);
	}
	if (rc < 0)
		GOTO(out, rc);
	if (rc < sizeof(*leh) + sizeof(*lee))
		GOTO(out, rc = -EINVAL);

	leh = buf.lb_buf;
	if (leh->leh_magic == __swab32(LINK_EA_MAGIC)) {
		leh->leh_magic = LINK_EA_MAGIC;
		leh->leh_reccount = __swab32(leh->leh_reccount);
		leh->leh_len = __swab64(leh->leh_len);
	}
	if (leh->leh_magic != LINK_EA_MAGIC)
		GOTO(out, rc = -EINVAL);
	if (leh->leh_reccount == 0)
		GOTO(out, rc = -ENODATA);

	lee = (struct link_ea_entry *)(leh + 1);
	fid_be_to_cpu(fid, (const struct lu_fid *)&lee->lee_parent_fid);
	rc = 0;

out:
	if (buf.lb_buf != osd_oti_get(env)->oti_buf)
		OBD_FREE(buf.lb_buf, buf.lb_len);

#if 0
	/* this block can be enabled for additional verification
	 * it's trying to match FID from LinkEA vs. FID from LMA */
	if (rc == 0) {
		struct lu_fid fid2;
		int rc2;
		rc2 = osd_find_parent_by_dnode(env, o, &fid2);
		if (rc2 == 0)
			if (lu_fid_eq(fid, &fid2) == 0)
				CERROR("wrong parent: "DFID" != "DFID"\n",
				       PFID(fid), PFID(&fid2));
	}
#endif

	/* no LinkEA is found, let's try to find the fid in parent's LMA */
	if (unlikely(rc != 0))
		rc = osd_find_parent_by_dnode(env, o, fid);

	RETURN(rc);
}
Example #23
0
static int bif_add_part(struct bif_entry *bf, const char *data, size_t len)
{
	size_t parthdr_offset = 0;
	struct partition_header parthdr = {
		.len_enc = cpu_to_le32(len / 4),
		.len_unenc = cpu_to_le32(len / 4),
		.len = cpu_to_le32(len / 4),
		.entry_point = cpu_to_le64(bf->entry),
		.load_address = cpu_to_le64(bf->load),
	};
	int r;
	uint32_t csum;

	if (bf->flags & (1ULL << BIF_FLAG_PMUFW_IMAGE))
		return bif_add_pmufw(bf, data, len);

	r = bif_add_blob(data, len, &bf->offset);
	if (r)
		return r;

	parthdr.offset = cpu_to_le32(bf->offset / 4);

	if (bf->flags & (1ULL << BIF_FLAG_BOOTLOADER)) {
		if (bif_output.last_part) {
			printf("ERROR: Bootloader expected before others\n");
			return -1;
		}

		parthdr.offset = cpu_to_le32(bif_output.header->image_offset);
		parthdr.len = cpu_to_le32((bf->offset + len -
			bif_output.header->image_offset) / 4);
		parthdr.len_enc = parthdr.len;
		parthdr.len_unenc = parthdr.len;
	}

	/* Normalize EL */
	bf->exp_lvl = bf->exp_lvl ? bf->exp_lvl - 1 : 3;
	parthdr.attributes |= bf->exp_lvl << PART_ATTR_TARGET_EL_SHIFT;
	parthdr.attributes |= bf->dest_dev;
	parthdr.attributes |= bf->dest_cpu;
	if (bf->flags & (1ULL << BIF_FLAG_TZ))
		parthdr.attributes |= PART_ATTR_TZ_SECURE;
	if (bf->flags & (1ULL << BIF_FLAG_PART_OWNER_UBOOT))
		parthdr.attributes |= PART_ATTR_PART_OWNER_UBOOT;
	switch (bf->dest_cpu) {
	case PART_ATTR_DEST_CPU_NONE:
	case PART_ATTR_DEST_CPU_A53_0:
	case PART_ATTR_DEST_CPU_A53_1:
	case PART_ATTR_DEST_CPU_A53_2:
	case PART_ATTR_DEST_CPU_A53_3:
		if (bf->flags & (1ULL << BIF_FLAG_AARCH32))
			parthdr.attributes |= PART_ATTR_A53_EXEC_AARCH32;
	}

	csum = zynqmp_csum(&parthdr, &parthdr.checksum);
	parthdr.checksum = cpu_to_le32(csum);

	r = bif_add_blob(&parthdr, sizeof(parthdr), &parthdr_offset);
	if (r)
		return r;

	/* Add image header table if not there yet */
	if (!bif_output.imgheader) {
		size_t imghdr_off = 0;
		struct image_header_table imghdr = {
			.version = cpu_to_le32(0x01020000),
			.nr_parts = 0,
		};

		r = bif_add_blob(&imghdr, sizeof(imghdr), &imghdr_off);
		if (r)
			return r;

		bif_output.header->image_header_table_offset = imghdr_off;
		bif_output.imgheader = (void *)(bif_output.data + imghdr_off);
	}

	bif_output.imgheader->nr_parts = cpu_to_le32(le32_to_cpu(
		bif_output.imgheader->nr_parts) + 1);

	/* Link to this partition header */
	if (bif_output.last_part) {
		bif_output.last_part->next_partition_offset =
			cpu_to_le32(parthdr_offset / 4);

		/* Recalc checksum of last_part */
		csum = zynqmp_csum(bif_output.last_part,
				   &bif_output.last_part->checksum);
		bif_output.last_part->checksum = cpu_to_le32(csum);
	} else {
		bif_output.imgheader->partition_header_offset =
			cpu_to_le32(parthdr_offset / 4);
	}
	bif_output.last_part = (void *)(bif_output.data + parthdr_offset);

	if (bf->flags & (1ULL << BIF_FLAG_BOOTLOADER)) {
		bif_output.header->image_load = cpu_to_le32(bf->load);
		if (!bif_output.header->image_offset)
			bif_output.header->image_offset =
				cpu_to_le32(bf->offset);
		bif_output.header->image_size = cpu_to_le32(len);
		bif_output.header->image_stored_size = cpu_to_le32(len);

		bif_output.header->image_attributes &= ~HEADER_CPU_SELECT_MASK;
		switch (bf->dest_cpu) {
		default:
		case PART_ATTR_DEST_CPU_A53_0:
			if (bf->flags & BIF_FLAG_AARCH32)
				bif_output.header->image_attributes |=
					HEADER_CPU_SELECT_A53_32BIT;
			else
				bif_output.header->image_attributes |=
					HEADER_CPU_SELECT_A53_64BIT;
			break;
		case PART_ATTR_DEST_CPU_R5_0:
			bif_output.header->image_attributes |=
				HEADER_CPU_SELECT_R5_SINGLE;
			break;
		case PART_ATTR_DEST_CPU_R5_L:
			bif_output.header->image_attributes |=
				HEADER_CPU_SELECT_R5_DUAL;
			break;
		}
	}

	return 0;
}

/* Add .bit bitstream */
static int bif_add_bit(struct bif_entry *bf)
{
	char *bit = read_full_file(bf->filename, NULL);
	char *bitbin;
	uint8_t initial_header[] = { 0x00, 0x09, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f,
				     0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x01, 0x61 };
	uint16_t len;
	uint32_t bitlen;
	int i;

	if (!bit)
		return -1;

	/* Skip initial header */
	if (memcmp(bit, initial_header, sizeof(initial_header)))
		return -1;

	bit += sizeof(initial_header);

	/* Design name */
	len = be16_to_cpu(*(uint16_t *)bit);
	bit += sizeof(uint16_t);
	debug("Design: %s\n", bit);
	bit += len;

	/* Device identifier */
	if (*bit != 'b')
		return -1;
	bit++;
	len = be16_to_cpu(*(uint16_t *)bit);
	bit += sizeof(uint16_t);
	debug("Device: %s\n", bit);
	bit += len;

	/* Date */
	if (*bit != 'c')
		return -1;
	bit++;
	len = be16_to_cpu(*(uint16_t *)bit);
	bit += sizeof(uint16_t);
	debug("Date: %s\n", bit);
	bit += len;

	/* Time */
	if (*bit != 'd')
		return -1;
	bit++;
	len = be16_to_cpu(*(uint16_t *)bit);
	bit += sizeof(uint16_t);
	debug("Time: %s\n", bit);
	bit += len;

	/* Bitstream length */
	if (*bit != 'e')
		return -1;
	bit++;
	bitlen = be32_to_cpu(*(uint32_t *)bit);
	bit += sizeof(uint32_t);
	bitbin = bit;

	debug("Bitstream Length: 0x%x\n", bitlen);
	for (i = 0; i < bitlen; i += sizeof(uint32_t)) {
		uint32_t *bitbin32 = (uint32_t *)&bitbin[i];
		*bitbin32 = __swab32(*bitbin32);
	}

	if (!bf->dest_dev)
		bf->dest_dev = PART_ATTR_DEST_DEVICE_PL;

	bf->load = 0xffffffff;
	bf->entry = 0;

	bf->flags |= 1ULL << BIF_FLAG_BIT_FILE;
	return bif_add_part(bf, bit, bitlen);
}
Example #24
0
static inline void tc358767_reg_write(struct tegra_dc_dsi2edp_data *dsi2edp,
					unsigned int addr, unsigned int val)
{
	regmap_write(dsi2edp->regmap, addr,
		TO_LITTLE_ENDIAN ? __swab32(val) : val);
}
Example #25
0
static inline int
lnet_accept_magic(__u32 magic, __u32 constant)
{
	return (magic == constant ||
		magic == __swab32(constant));
}
Example #26
0
static inline void tc358767_reg_read(struct tegra_dc_dsi2edp_data *dsi2edp,
					unsigned int addr, unsigned int *val)
{
	regmap_read(dsi2edp->regmap, addr, val);
	*val = TO_LITTLE_ENDIAN ? __swab32(*val) : *val;
}
Example #27
0
void
ate_thaw(pcibr_dmamap_t pcibr_dmamap,
	 int ate_index,
#if PCIBR_FREEZE_TIME
	 bridge_ate_t ate,
	 int ate_total,
	 unsigned freeze_time_start,
#endif
	 unsigned *cmd_regs,
	 unsigned s)
{
    pcibr_soft_t            pcibr_soft = pcibr_dmamap->bd_soft;
    int                     dma_slot = pcibr_dmamap->bd_slot;
    int                     slot;
    bridge_t               *bridge = pcibr_soft->bs_base;
    int                     ext_ates = pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM;

    unsigned                cmd_reg;

#if PCIBR_FREEZE_TIME
    unsigned                freeze_time;
    static unsigned         max_freeze_time = 0;
    static unsigned         max_ate_total;
#endif

    if (!ext_ates)
	return;

    /* restore cmd regs */
    for (slot = pcibr_soft->bs_min_slot; 
		slot < PCIBR_NUM_SLOTS(pcibr_soft); ++slot) {
	if ((cmd_reg = cmd_regs[slot]) & PCI_CMD_BUS_MASTER) {
		if ( IS_PIC_SOFT(pcibr_soft) ) {
			pcibr_slot_config_set(bridge, slot, PCI_CFG_COMMAND/4, cmd_reg);
		}
		else {
			if (io_get_sh_swapper(NASID_GET(bridge))) {
				bridge->b_type0_cfg_dev[slot].l[PCI_CFG_COMMAND / 4] = __swab32(cmd_reg);
			}
			else {
//				BUG(); /* Does this really work if called when io_get_sh_swapper = 0? */
//				bridge->b_type0_cfg_dev[slot].l[PCI_CFG_COMMAND / 4] = cmd_reg;
				pcibr_slot_config_set(bridge, slot, PCI_CFG_COMMAND/4, cmd_reg);
			}
		}
	}
    }
    pcibr_dmamap->bd_flags |= PCIBR_DMAMAP_BUSY;
    atomic_inc(&(pcibr_soft->bs_slot[dma_slot]. bss_ext_ates_active));

#if PCIBR_FREEZE_TIME
    freeze_time = get_timestamp() - freeze_time_start;

    if ((max_freeze_time < freeze_time) ||
	(max_ate_total < ate_total)) {
	if (max_freeze_time < freeze_time)
	    max_freeze_time = freeze_time;
	if (max_ate_total < ate_total)
	    max_ate_total = ate_total;
	pcibr_unlock(pcibr_soft, s);
	printk( "%s: pci freeze time %d usec for %d ATEs\n"
		"\tfirst ate: %R\n",
		pcibr_soft->bs_name,
		freeze_time * 1000 / 1250,
		ate_total,
		ate, ate_bits);
    } else
#endif
	pcibr_unlock(pcibr_soft, s);
}
Example #28
0
/*
 * Determine the size of this bridge's external mapping SSRAM, and set
 * the control register appropriately to reflect this size, and initialize
 * the external SSRAM.
 */
int
pcibr_init_ext_ate_ram(bridge_t *bridge)
{
    int                     largest_working_size = 0;
    int                     num_entries, entry;
    int                     i, j;
    bridgereg_t             old_enable, new_enable;
    int                     s;
    int			    this_is_pic = is_pic(bridge);

    /* Probe SSRAM to determine its size. */
    if ( this_is_pic ) {
	old_enable = bridge->b_int_enable;
	new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;
	bridge->b_int_enable = new_enable;
    }
    else {
	if (io_get_sh_swapper(NASID_GET(bridge))) {
		old_enable = BRIDGE_REG_GET32((&bridge->b_int_enable));
		new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;
		BRIDGE_REG_SET32((&bridge->b_int_enable)) = new_enable;
	}
	else {
		old_enable = bridge->b_int_enable;
		new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;
		bridge->b_int_enable = new_enable;
	}
    }

    for (i = 1; i < ATE_NUM_SIZES; i++) {
	/* Try writing a value */
	if ( this_is_pic ) {
		bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] = ATE_PROBE_VALUE;
	}
	else {
		if (io_get_sh_swapper(NASID_GET(bridge)))
			bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] = __swab64(ATE_PROBE_VALUE);
		else
			bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] = ATE_PROBE_VALUE;
	}

	/* Guard against wrap */
	for (j = 1; j < i; j++)
	    bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(j) - 1] = 0;

	/* See if value was written */
	if ( this_is_pic ) {
		if (bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] == ATE_PROBE_VALUE)
				largest_working_size = i;
	}
	else {
		if (io_get_sh_swapper(NASID_GET(bridge))) {
			if (bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] == __swab64(ATE_PROBE_VALUE))
					largest_working_size = i;
			else {
				if (bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] == ATE_PROBE_VALUE)
					largest_working_size = i;
			}
		}
	}
    }
    if ( this_is_pic ) {
	bridge->b_int_enable = old_enable;
	bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
    }
    else {
	if (io_get_sh_swapper(NASID_GET(bridge))) {
		BRIDGE_REG_SET32((&bridge->b_int_enable)) = old_enable;
		BRIDGE_REG_GET32((&bridge->b_wid_tflush));   /* wait until Bridge PIO complete */
	}
	else {
		bridge->b_int_enable = old_enable;
		bridge->b_wid_tflush;               /* wait until Bridge PIO complete */
	}
    }

    /*
     * ensure that we write and read without any interruption.
     * The read following the write is required for the Bridge war
     */

    s = splhi();
    if ( this_is_pic ) {
	bridge->b_wid_control = (bridge->b_wid_control
			& ~BRIDGE_CTRL_SSRAM_SIZE_MASK)
			| BRIDGE_CTRL_SSRAM_SIZE(largest_working_size);
	bridge->b_wid_control;		/* inval addr bug war */
    }
    else {
	if (io_get_sh_swapper(NASID_GET(bridge))) {
		BRIDGE_REG_SET32((&(bridge->b_wid_control))) = 
				__swab32((BRIDGE_REG_GET32((&bridge->b_wid_control))
					& ~BRIDGE_CTRL_SSRAM_SIZE_MASK)
					| BRIDGE_CTRL_SSRAM_SIZE(largest_working_size));
		BRIDGE_REG_GET32((&bridge->b_wid_control));/* inval addr bug war */
	}
	else {
		bridge->b_wid_control = (bridge->b_wid_control & ~BRIDGE_CTRL_SSRAM_SIZE_MASK)
				| BRIDGE_CTRL_SSRAM_SIZE(largest_working_size);
		bridge->b_wid_control;              /* inval addr bug war */
	}
    }
    splx(s);

    num_entries = ATE_NUM_ENTRIES(largest_working_size);

    if (pcibr_debug_mask & PCIBR_DEBUG_ATE) {
	if (num_entries) {
	    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATE, NULL,
			"bridge at 0x%x: clearing %d external ATEs\n",
			bridge, num_entries));
	} else {
	    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATE, NULL,
			"bridge at 0x%x: no external ATE RAM found\n",
			bridge));
	}
    }

    /* Initialize external mapping entries */
    for (entry = 0; entry < num_entries; entry++)
	bridge->b_ext_ate_ram[entry] = 0;

    return (num_entries);
}
Example #29
0
/* Switch on rx_state.
 * Return 0 on success, else return <0
 * Always set cont_flag: 1 if we're ready to continue reading, else 0
 */
int
usocklnd_read_hello(usock_conn_t *conn, int *cont_flag)
{
        int                rc = 0;
        ksock_hello_msg_t *hello = conn->uc_rx_hello;

        *cont_flag = 0;

        /* smth. new emerged in hello - let's process it */
        switch (conn->uc_rx_state) {
        case UC_RX_HELLO_MAGIC:
                if (hello->kshm_magic == LNET_PROTO_MAGIC)
                        conn->uc_flip = 0;
                else if (hello->kshm_magic == __swab32(LNET_PROTO_MAGIC))
                        conn->uc_flip = 1;
                else
                        return -EPROTO;

                usocklnd_rx_helloversion_state_transition(conn);
                *cont_flag = 1;
                break;

        case UC_RX_HELLO_VERSION:
                if ((!conn->uc_flip &&
                     (hello->kshm_version != KSOCK_PROTO_V2)) ||
                    (conn->uc_flip &&
                     (hello->kshm_version != __swab32(KSOCK_PROTO_V2))))
                        return -EPROTO;

                usocklnd_rx_hellobody_state_transition(conn);
                *cont_flag = 1;
                break;

        case UC_RX_HELLO_BODY:
                if (conn->uc_flip) {
                        ksock_hello_msg_t *hello = conn->uc_rx_hello;
                        __swab32s(&hello->kshm_src_pid);
                        __swab64s(&hello->kshm_src_nid);
                        __swab32s(&hello->kshm_dst_pid);
                        __swab64s(&hello->kshm_dst_nid);
                        __swab64s(&hello->kshm_src_incarnation);
                        __swab64s(&hello->kshm_dst_incarnation);
                        __swab32s(&hello->kshm_ctype);
                        __swab32s(&hello->kshm_nips);
                }

                if (conn->uc_rx_hello->kshm_nips > LNET_MAX_INTERFACES) {
                        CERROR("Bad nips %d from ip %u.%u.%u.%u port %d\n",
                               conn->uc_rx_hello->kshm_nips,
                               HIPQUAD(conn->uc_peer_ip), conn->uc_peer_port);
                        return -EPROTO;
                }

                if (conn->uc_rx_hello->kshm_nips) {
                        usocklnd_rx_helloIPs_state_transition(conn);
                        *cont_flag = 1;
                        break;
                }
                /* fall through */

        case UC_RX_HELLO_IPS:
                if (conn->uc_activeflag == 1) /* active conn */
                        rc = usocklnd_activeconn_hellorecv(conn);
                else                          /* passive conn */
                        rc = usocklnd_passiveconn_hellorecv(conn);

                break;

        default:
                LBUG(); /* unknown state */
        }

        return rc;
}
Example #30
0
int decode_linkea(const char *fname)
{
	char buf[BUFFER_SIZE];
	struct link_ea_header *leh;
	ssize_t size;
	struct link_ea_entry *lee;
	int i;
	__u64 length;
	int reclen;
	struct lu_fid pfid;

	size = getxattr(fname, "trusted.link", buf, BUFFER_SIZE);
	if (size < 0) {
		if (errno == ERANGE) {
			fprintf(stderr, "%s: failed to read trusted.link "
				"xattr, the buffer size %u might be too "
				"small\n", fname, BUFFER_SIZE);
		} else {
			fprintf(stderr,
				"%s: failed to read trusted.link xattr: %s\n",
				fname, strerror(errno));
		}
		return -1;
	}

	leh = (struct link_ea_header *)buf;
	if (leh->leh_magic == __swab32(LINK_EA_MAGIC)) {
		leh->leh_magic = LINK_EA_MAGIC;
		leh->leh_reccount = __swab32(leh->leh_reccount);
		leh->leh_len = __swab64(leh->leh_len);
	}
	if (leh->leh_magic != LINK_EA_MAGIC) {
		fprintf(stderr,
			"%s: magic mismatch, expected 0x%lx, got 0x%x\n",
			fname, LINK_EA_MAGIC, leh->leh_magic);
		return -1;
	}
	if (leh->leh_reccount == 0) {
		fprintf(stderr, "%s: empty record count\n", fname);
		return -1;
	}
	if (leh->leh_len > size) {
		fprintf(stderr,
			"%s: invalid length %llu, should smaller than %zd\n",
			fname, leh->leh_len, size);
		return -1;
	}

	length = sizeof(struct link_ea_header);
	lee = (struct link_ea_entry *)(leh + 1);
	printf("%s: count %u\n", fname, leh->leh_reccount);
	for (i = 0; i < leh->leh_reccount; i++) {
		reclen = (lee->lee_reclen[0] << 8) | lee->lee_reclen[1];
		length += reclen;
		if (length > leh->leh_len) {
			fprintf(stderr,
				"%s: length exceeded, expected %lld, got %lld\n",
				fname, leh->leh_len, length);
			return -1;
		}
		memcpy(&pfid, &lee->lee_parent_fid, sizeof(pfid));
		fid_be_to_cpu(&pfid, &pfid);

		printf("    %d: pfid "DFID", name '%s'\n", i, PFID(&pfid),
		       lee->lee_name);
		lee = (struct link_ea_entry *)((char *)lee + reclen);
	}

	if (length != leh->leh_len) {
		fprintf(stderr,
			"%s: length mismatch, expected %lld, got %lld\n",
			fname, leh->leh_len, length);
		return -1;
	}

	return 0;
}