[Pdbg] [PATCH 06/10] sbefifo: Return only the response data from sbefifo_op

Amitay Isaacs amitay at ozlabs.org
Wed Jul 3 13:46:15 AEST 2019


Instead of returning the entire response buffer, extract the response
data and status.

To differentiate between the chip-op failure and other failures,
return 1 from sbefifo_op() if chip-op completes but does not succeed.

Signed-off-by: Amitay Isaacs <amitay at ozlabs.org>
---
 libpdbg/sbefifo.c | 74 ++++++++++++++++++++++++++++-------------------
 1 file changed, 45 insertions(+), 29 deletions(-)

diff --git a/libpdbg/sbefifo.c b/libpdbg/sbefifo.c
index 9ca92f7..54dc90d 100644
--- a/libpdbg/sbefifo.c
+++ b/libpdbg/sbefifo.c
@@ -199,8 +199,8 @@ static void sbefifo_ffdc_dump(struct sbefifo *sbefifo)
 }
 
 static int sbefifo_op(struct sbefifo *sbefifo,
-		      uint32_t *msg, size_t msg_len, uint16_t cmd,
-		      size_t out_len, uint8_t **out)
+		      uint32_t *msg, uint32_t msg_len, uint16_t cmd,
+		      uint8_t **out, uint32_t *out_len, uint32_t *status)
 {
 	uint8_t *buf;
 	uint32_t resp[2];
@@ -214,7 +214,7 @@ static int sbefifo_op(struct sbefifo *sbefifo,
 	assert(msg_len > 0);
 
 	/* Allocate extra memory for FFDC (SBEFIFO_MAX_FFDC_SIZE = 0x2000) */
-	buflen = out_len + 0x2000;
+	buflen = 0x2000;
 	buf = malloc(buflen);
 	assert(buf);
 
@@ -231,8 +231,7 @@ static int sbefifo_op(struct sbefifo *sbefifo,
 	 * header word, status word, header offset word
 	 */
 	if (buflen < 3 * 4) {
-		PR_ERROR("sbefifo: Short read, expected %zu, got %zu\n",
-			 out_len + 3 * 4, buflen);
+		PR_ERROR("sbefifo: Short read, got %zu\n", buflen);
 		sbefifo_op_dump("DATA:", buf, buflen);
 		goto fail;
 	}
@@ -241,6 +240,7 @@ static int sbefifo_op(struct sbefifo *sbefifo,
 	PR_INFO("sbefifo: status header word offset = %u\n", word_offset);
 
 	offset = buflen - (word_offset * 4);
+	*out_len = offset;
 
 	resp[0] = be32toh(*(uint32_t *)(buf + offset));
 	offset += 4;
@@ -262,14 +262,26 @@ static int sbefifo_op(struct sbefifo *sbefifo,
 		goto fail;
 	}
 
-	if (resp[1] == 0) {
-		*out = buf;
-		return 0;
-	} else {
+	*status = resp[1];
+	if (resp[1] != 0) {
 		PR_ERROR("sbefifo: Operation failed, response=0x%08x\n", resp[1]);
 		sbefifo_ffdc_set(sbefifo, buf + offset, buflen - offset - 4, resp[1]);
+		free(buf);
+		return 1;
+	}
+
+	if (*out_len > 0) {
+		*out = malloc(*out_len);
+		assert(*out);
+
+		memcpy(*out, buf, *out_len);
+	} else {
+		*out = NULL;
 	}
 
+	free(buf);
+	return 0;
+
 fail:
 	free(buf);
 	return -1;
@@ -280,7 +292,7 @@ static int sbefifo_op_istep(struct sbefifo *sbefifo,
 {
 	uint8_t *out;
 	uint32_t msg[3];
-	uint32_t cmd, step;
+	uint32_t cmd, step, out_len, status;
 	int rc;
 
 	PR_NOTICE("sbefifo: istep %u.%u\n", major, minor);
@@ -292,12 +304,10 @@ static int sbefifo_op_istep(struct sbefifo *sbefifo,
 	msg[1] = htobe32(cmd);
 	msg[2] = htobe32(step);
 
-	/* Return - data read + length of data read */
-	rc = sbefifo_op(sbefifo, msg, sizeof(msg), cmd, 0, &out);
+	rc = sbefifo_op(sbefifo, msg, sizeof(msg), cmd, &out, &out_len, &status);
 	if (rc)
 		return rc;
 
-	free(out);
 	return 0;
 }
 
@@ -307,9 +317,9 @@ static int sbefifo_op_getmem(struct sbefifo *sbefifo,
 {
 	uint8_t *out;
 	uint64_t start_addr, end_addr;
-	uint32_t align, offset, len;
+	uint32_t align, offset, len, out_len, status;
 	uint32_t msg[6];
-	uint32_t cmd, flags, count;
+	uint32_t cmd, flags;
 	int rc;
 
 	align = ci ? 8 : 128;
@@ -338,22 +348,22 @@ static int sbefifo_op_getmem(struct sbefifo *sbefifo,
 	msg[4] = htobe32(start_addr & 0xffffffff);
 	msg[5] = htobe32(len);
 
-	/* Return - data read + length of data read */
-	rc = sbefifo_op(sbefifo, msg, sizeof(msg), cmd, len+4, &out);
+	rc = sbefifo_op(sbefifo, msg, sizeof(msg), cmd, &out, &out_len, &status);
 	if (rc)
 		return rc;
 
-	memcpy(data, out+offset, size);
-	count = htobe32(*(uint32_t *)&out[len]);
-	free(out);
-
-	pdbg_progress_tick(count, len);
+	pdbg_progress_tick(len + 4, out_len);
 
-	if (count != len) {
-		PR_ERROR("sbefifo: getmem read %u bytes of %u\n", count, len);
+	if (out_len != size + 4) {
+		PR_ERROR("sbefifo: getmem error got %u, expected %"PRIu64"\n", out_len, size + 4);
+		if (out_len > 0)
+			free(out);
 		return -1;
 	}
 
+	memcpy(data, out+offset, size);
+	free(out);
+
 	return 0;
 }
 
@@ -363,7 +373,7 @@ static int sbefifo_op_putmem(struct sbefifo *sbefifo,
 {
 	uint8_t *out;
 	uint32_t *msg;
-	uint32_t align, len, msg_len;
+	uint32_t align, len, msg_len, out_len, status;
 	uint32_t cmd, flags, count;
 	int rc;
 
@@ -402,16 +412,22 @@ static int sbefifo_op_putmem(struct sbefifo *sbefifo,
 	msg[5] = htobe32(len);
 	memcpy(&msg[6], data, len);
 
-	/* Return - length of data written */
-	rc = sbefifo_op(sbefifo, msg, msg_len, cmd, 0, &out);
+	rc = sbefifo_op(sbefifo, msg, msg_len, cmd, &out, &out_len, &status);
 	if (rc)
 		return rc;
 
+	pdbg_progress_tick(len + 4, out_len);
+
+	if (out_len != 4) {
+		PR_ERROR("sbefifo: putmem error got %u, expected 4\n", out_len);
+		if (out_len > 0)
+			free(out);
+		return -1;
+	}
+
 	count = be32toh(*(uint32_t *)out);
 	free(out);
 
-	pdbg_progress_tick(count, len);
-
 	if (count != len) {
 		PR_ERROR("sbefifo: putmem wrote %u bytes of %u\n", count, len);
 		return -1;
-- 
2.21.0



More information about the Pdbg mailing list