diff mbox

[2/2] platforms/mambo: Support large unaligned reads

Message ID 20161102054329.9851-2-cyril.bur@au1.ibm.com
State Accepted
Headers show

Commit Message

Cyril Bur Nov. 2, 2016, 5:43 a.m. UTC
Recent changes to the skiboot resource loading code means that reads for
BOOTKERNEL and ROOTFS partitions will be exactly the number of bytes
required and no longer the (inaccurate) partition total size which
happened to be block size aligned.

Error when booting in mambo:
1140078: (1140078): [    0.001132323,3] FLASH: failed to read content
size 14252376 BOOTKERNEL partition, rc -1

Signed-off-by: Cyril Bur <cyril.bur@au1.ibm.com>
[initial review and changes by Mikey Neuling]
Signed-off-by: Michael Neuling <mikey@neuling.org>

---
 platforms/mambo/mambo.c | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)
diff mbox

Patch

diff --git a/platforms/mambo/mambo.c b/platforms/mambo/mambo.c
index bd151ed..7f910b2 100644
--- a/platforms/mambo/mambo.c
+++ b/platforms/mambo/mambo.c
@@ -131,22 +131,29 @@  static int bogus_disk_read(struct blocklevel_device *bl, uint64_t pos, void *buf
 			  uint64_t len)
 {
 	struct bogus_disk_info *bdi = bl->priv;
-	int rc;
+	int rc, read_sectors = 0;
 	char b[BD_SECT_SZ];
 
-	if ((len % BD_SECT_SZ) == 0)
-		return callthru_disk_read(bdi->id, buf, pos/BD_SECT_SZ,
+	if (len >= BD_SECT_SZ) {
+		rc = callthru_disk_read(bdi->id, buf, pos/BD_SECT_SZ,
 					  len/BD_SECT_SZ);
+		if (rc)
+			return rc;
+		read_sectors = (len / BD_SECT_SZ);
+	}
 
-	/* We don't support block reads > BD_SECT_SZ */
-	if (len > BD_SECT_SZ)
-		return OPAL_PARAMETER;
+	if ((len % BD_SECT_SZ) == 0)
+		return 0;
 
-	/* Skiboot does small reads for system flash header checking */
-	rc =  callthru_disk_read(bdi->id, b, pos/BD_SECT_SZ, 1);
+	/*
+	 * Read any unaligned data into a temporaty buffer b, then copy
+	 * to buf
+	 */
+	rc =  callthru_disk_read(bdi->id, b, (pos/BD_SECT_SZ) + read_sectors, 1);
 	if (rc)
 		return rc;
-	memcpy(buf, &b[pos % BD_SECT_SZ], len);
+	memcpy(buf + (read_sectors * BD_SECT_SZ) , &b[pos % BD_SECT_SZ],
+			len - (read_sectors * BD_SECT_SZ));
 	return rc;
 }