* under either the MPL or the GPL.
*/
+#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
hw->iobase = address;
hw->reg_spacing = reg_spacing;
hw->inten = 0x0;
+
+#ifdef HERMES_DEBUG_BUFFER
+ hw->dbufp = 0;
+ memset(&hw->dbuf, 0xff, sizeof(hw->dbuf));
+ memset(&hw->profile, 0, sizeof(hw->profile));
+#endif
}
int hermes_init(hermes_t *hw)
reg = hermes_read_reg(hw, oreg);
}
+#ifdef HERMES_DEBUG_BUFFER
+ hw->profile[HERMES_BAP_BUSY_TIMEOUT - k]++;
+
+ if (k < HERMES_BAP_BUSY_TIMEOUT) {
+ struct hermes_debug_entry *e =
+ &hw->dbuf[(hw->dbufp++) % HERMES_DEBUG_BUFSIZE];
+ e->bap = bap;
+ e->id = id;
+ e->offset = offset;
+ e->cycles = HERMES_BAP_BUSY_TIMEOUT - k;
+ }
+#endif
+
if (reg & HERMES_OFFSET_BUSY)
return -ETIMEDOUT;
}
/* Write a block of data to the chip's buffer, via the
- * BAP. Synchronization/serialization is the caller's problem.
+ * 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 dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
int err = 0;
- if (len < 0)
+ if ( (len < 0) || (len % 2) )
return -EINVAL;
err = hermes_bap_seek(hw, bap, id, offset);
goto out;
/* Actually do the transfer */
- hermes_write_bytes(hw, dreg, buf, len);
+ hermes_write_words(hw, dreg, buf, len/2);
out:
return err;
}
+/* Write a block of data to the chip's buffer with padding if
+ * neccessary, 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_pwrite_pad(hermes_t *hw, int bap, const void *buf, unsigned data_len, int len,
+ u16 id, u16 offset)
+{
+ int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
+ int err = 0;
+
+ if (len < 0 || len % 2 || data_len > len)
+ return -EINVAL;
+
+ err = hermes_bap_seek(hw, bap, id, offset);
+ if (err)
+ goto out;
+
+ /* Transfer all the complete words of data */
+ hermes_write_words(hw, dreg, buf, data_len/2);
+ /* If there is an odd byte left over pad and transfer it */
+ if (data_len & 1) {
+ u8 end[2];
+ end[1] = 0;
+ end[0] = ((unsigned char *)buf)[data_len - 1];
+ hermes_write_words(hw, dreg, end, 1);
+ data_len ++;
+ }
+ /* Now send zeros for the padding */
+ if (data_len < len)
+ hermes_clear_words(hw, dreg, (len - data_len) / 2);
+ /* Complete */
+ out:
+ return err;
+}
+
/* Read a Length-Type-Value record from the card.
*
* If length is NULL, we ignore the length read from the card, and
count = length - 1;
- hermes_write_bytes(hw, dreg, value, count << 1);
+ hermes_write_words(hw, dreg, value, count);
err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS | HERMES_CMD_WRITE,
rid, NULL);
EXPORT_SYMBOL(hermes_bap_pread);
EXPORT_SYMBOL(hermes_bap_pwrite);
+EXPORT_SYMBOL(hermes_bap_pwrite_pad);
EXPORT_SYMBOL(hermes_read_ltv);
EXPORT_SYMBOL(hermes_write_ltv);