static int occ_putsram()

in fsi-occ.c [315:391]


static int occ_putsram(struct occ *occ, const void *data, ssize_t len,
		       u8 seq_no, u16 checksum)
{
	u32 data_len = ((len + 7) / 8) * 8;	/* must be multiples of 8 B */
	size_t cmd_len, parsed_len, resp_data_len;
	size_t resp_len = OCC_MAX_RESP_WORDS;
	__be32 *buf = occ->buffer;
	u8 *byte_buf;
	int idx = 0, rc;

	cmd_len = (occ->version == occ_p10) ? 6 : 5;
	cmd_len += data_len >> 2;

	/*
	 * Magic sequence to do SBE putsram command. SBE will transfer
	 * data to specified SRAM address.
	 */
	buf[0] = cpu_to_be32(cmd_len);
	buf[1] = cpu_to_be32(SBEFIFO_CMD_PUT_OCC_SRAM);

	switch (occ->version) {
	default:
	case occ_p9:
		buf[2] = cpu_to_be32(1);	/* Normal mode */
		buf[3] = cpu_to_be32(OCC_P9_SRAM_CMD_ADDR);
		break;
	case occ_p10:
		idx = 1;
		buf[2] = cpu_to_be32(OCC_P10_SRAM_MODE);
		buf[3] = 0;
		buf[4] = cpu_to_be32(OCC_P10_SRAM_CMD_ADDR);
		break;
	}

	buf[4 + idx] = cpu_to_be32(data_len);
	memcpy(&buf[5 + idx], data, len);

	byte_buf = (u8 *)&buf[5 + idx];
	/*
	 * Overwrite the first byte with our sequence number and the last two
	 * bytes with the checksum.
	 */
	byte_buf[0] = seq_no;
	byte_buf[len - 2] = checksum >> 8;
	byte_buf[len - 1] = checksum & 0xff;

	rc = sbefifo_submit(occ->sbefifo, buf, cmd_len, buf, &resp_len);
	if (rc)
		return rc;

	rc = sbefifo_parse_status(occ->sbefifo, SBEFIFO_CMD_PUT_OCC_SRAM,
				  buf, resp_len, &parsed_len);
	if (rc > 0) {
		dev_err(occ->dev, "SRAM write returned failure status: %08x\n",
			rc);
		occ_save_ffdc(occ, buf, parsed_len, resp_len);
		return -ECOMM;
	} else if (rc) {
		return rc;
	}

	if (parsed_len != 1) {
		dev_err(occ->dev, "SRAM write response length invalid: %zd\n",
			parsed_len);
		rc = -EBADMSG;
	} else {
		resp_data_len = be32_to_cpu(buf[0]);
		if (resp_data_len != data_len) {
			dev_err(occ->dev,
				"SRAM write expected %d bytes got %zd\n",
				data_len, resp_data_len);
			rc = -EBADMSG;
		}
	}

	return rc;
}