Beispiel #1
0
/* Read a Length-Type-Value record from the card.
 *
 * If length is NULL, we ignore the length read from the card, and
 * read the entire buffer regardless. This is useful because some of
 * the configuration records appear to have incorrect lengths in
 * practice.
 *
 * Callable from user or bh context.  */
int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned bufsize,
		    u16 *length, void *buf)
{
	int err = 0;
	int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
	u16 rlength, rtype;
	unsigned nwords;

	if ( (bufsize < 0) || (bufsize % 2) )
		return -EINVAL;

	err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS, rid, NULL);
	if (err)
		return err;

	err = hermes_bap_seek(hw, bap, rid, 0);
	if (err)
		return err;

	rlength = hermes_read_reg(hw, dreg);

	if (! rlength)
		return -ENOENT;

	rtype = hermes_read_reg(hw, dreg);

	if (length)
		*length = rlength;

	if (rtype != rid)
		printk(KERN_WARNING "hermes @ %s0x%lx: "
		       "hermes_read_ltv(): rid  (0x%04x) does not match type (0x%04x)\n",
		       IO_TYPE(hw), hw->iobase, rid, rtype);
	if (HERMES_RECLEN_TO_BYTES(rlength) > bufsize)
		printk(KERN_WARNING "hermes @ %s0x%lx: "
		       "Truncating LTV record from %d to %d bytes. "
		       "(rid=0x%04x, len=0x%04x)\n",
		       IO_TYPE(hw), hw->iobase,
		       HERMES_RECLEN_TO_BYTES(rlength), bufsize, rid, rlength);

	nwords = min((unsigned)rlength - 1, bufsize / 2);
	hermes_read_words(hw, dreg, buf, nwords);

	return 0;
}
static int hermes_bap_pread(struct hermes *hw, int bap, void *buf, int len,
			    u16 id, u16 offset)
{
	int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
	int err = 0;

	if ((len < 0) || (len % 2))
		return -EINVAL;

	err = hermes_bap_seek(hw, bap, id, offset);
	if (err)
		goto out;

	
	hermes_read_words(hw, dreg, buf, len / 2);

 out:
	return err;
}
Beispiel #3
0
/* Read a block of data from the chip's buffer, via the
 * BAP. Synchronization/serialization is the caller's problem.  len
 * must be even.
 *
 * Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware
 */
int hermes_bap_pread(hermes_t *hw, int bap, void *buf, unsigned len,
		     u16 id, u16 offset)
{
	int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
	int err = 0;

	if ( (len < 0) || (len % 2) )
		return -EINVAL;

	err = hermes_bap_seek(hw, bap, id, offset);
	if (err)
		goto out;

	/* Actually do the transfer */
	hermes_read_words(hw, dreg, buf, len/2);

 out:
	return err;
}
Beispiel #4
0
/* Read a Length-Type-Value record from the card.
 *
 * If length is NULL, we ignore the length read from the card, and
 * read the entire buffer regardless. This is useful because some of
 * the configuration records appear to have incorrect lengths in
 * practice.
 *
 * Callable from user or bh context.  */
int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, int bufsize,
		    u16 *length, void *buf)
{
	int err = 0;
	int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
	u16 rlength, rtype;
	hermes_response_t resp;

	if (bufsize % 2)
		return -EINVAL;

	err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS, rid, &resp);
	if (err)
		goto out;

	err = hermes_bap_seek(hw, bap, rid, 0);
	if (err)
		goto out;

	rlength = hermes_read_reg(hw, dreg);
	rtype = hermes_read_reg(hw, dreg);

	if (length)
		*length = rlength;

	if (rtype != rid)
		printk(KERN_WARNING "hermes_read_ltv(): rid  (0x%04x) does "
		       "not match type (0x%04x)\n", rid, rtype);
	if (HERMES_RECLEN_TO_BYTES(rlength) > bufsize)
		printk(KERN_WARNING "hermes @ 0x%x: Truncating LTV record from %d to %d bytes. "
		       "(rid=0x%04x, len=0x%04x)\n", hw->iobase,
		       HERMES_RECLEN_TO_BYTES(rlength), bufsize, rid, rlength);
	
	/* FIXME: we should read the min of the requested length and
           the actual record length */
	hermes_read_words(hw, dreg, buf, bufsize / 2);

 out:
	return err;
}