svn commit: r345975 - head/sys/powerpc/powernv

Justin Hibbits jhibbits at FreeBSD.org
Tue Sep 3 14:06:26 UTC 2019


Author: jhibbits
Date: Sat Apr  6 02:39:56 2019
New Revision: 345975
URL: https://svnweb.freebsd.org/changeset/base/345975

Log:
  powerpc/powernv: Fix major bugs in opal_flash
  
  * The BIO bio_data may not be page aligned.  Only the base address of each
    page worth of data is extracted to pass to OPAL.  Without page alignment
    it can scribble over random memory when finishing the page read.  Fix this
    by short-reading the first page to properly align for full page reads.
  * Fix the definition of OPAL_FLASH_ERASE.
  * Properly handle the async message result, as now returned from r345974.

Modified:
  head/sys/powerpc/powernv/opal.h
  head/sys/powerpc/powernv/opal_flash.c

Modified: head/sys/powerpc/powernv/opal.h
==============================================================================
--- head/sys/powerpc/powernv/opal.h	Sat Apr  6 02:31:01 2019	(r345974)
+++ head/sys/powerpc/powernv/opal.h	Sat Apr  6 02:39:56 2019	(r345975)
@@ -82,7 +82,7 @@ int opal_call(uint64_t token, ...);
 #define	OPAL_I2C_REQUEST		109
 #define	OPAL_FLASH_READ			110
 #define	OPAL_FLASH_WRITE		111
-#define	OPAL_FLASH_ERASE		111
+#define	OPAL_FLASH_ERASE		112
 #define	OPAL_INT_GET_XIRR		122
 #define	OPAL_INT_SET_CPPR		123
 #define	OPAL_INT_EOI			124

Modified: head/sys/powerpc/powernv/opal_flash.c
==============================================================================
--- head/sys/powerpc/powernv/opal_flash.c	Sat Apr  6 02:31:01 2019	(r345974)
+++ head/sys/powerpc/powernv/opal_flash.c	Sat Apr  6 02:39:56 2019	(r345975)
@@ -175,16 +175,22 @@ opalflash_read(struct opalflash_softc *sc, off_t off,
 	 * Read one page at a time.  It's not guaranteed that the buffer is
 	 * physically contiguous.
 	 */
+	rv = 0;
 	while (count > 0) {
 		size = MIN(count, PAGE_SIZE);
+		size = MIN(size, PAGE_SIZE - ((u_long)data & PAGE_MASK));
 		rv = opal_call(OPAL_FLASH_READ, sc->sc_opal_id, off,
 		    vtophys(data), size, token);
-		if (rv == OPAL_ASYNC_COMPLETION)
+		if (rv == OPAL_ASYNC_COMPLETION) {
 			rv = opal_wait_completion(&msg, sizeof(msg), token);
+			if (rv == OPAL_SUCCESS)
+				rv = msg.params[1];
+		}
 		if (rv != OPAL_SUCCESS)
 			break;
 		count -= size;
 		off += size;
+		data += size;
 	}
 	opal_free_async_token(token);
 	if (rv == OPAL_SUCCESS)
@@ -209,8 +215,11 @@ opalflash_erase(struct opalflash_softc *sc, off_t off,
 	token = opal_alloc_async_token();
 
 	rv = opal_call(OPAL_FLASH_ERASE, sc->sc_opal_id, off, count, token);
-	if (rv == OPAL_ASYNC_COMPLETION)
+	if (rv == OPAL_ASYNC_COMPLETION) {
 		rv = opal_wait_completion(&msg, sizeof(msg), token);
+		if (rv == OPAL_SUCCESS)
+			rv = msg.params[1];
+	}
 	opal_free_async_token(token);
 
 	if (rv == OPAL_SUCCESS)
@@ -246,14 +255,19 @@ opalflash_write(struct opalflash_softc *sc, off_t off,
 	 */
 	while (count > 0) {
 		size = MIN(count, PAGE_SIZE);
+		size = MIN(size, PAGE_SIZE - ((u_long)data & PAGE_MASK));
 		rv = opal_call(OPAL_FLASH_WRITE, sc->sc_opal_id, off,
 		    vtophys(data), size, token);
-		if (rv == OPAL_ASYNC_COMPLETION)
+		if (rv == OPAL_ASYNC_COMPLETION) {
 			rv = opal_wait_completion(&msg, sizeof(msg), token);
+			if (rv == OPAL_SUCCESS)
+				rv = msg.params[1];
+		}
 		if (rv != OPAL_SUCCESS)
 			break;
 		count -= size;
 		off += size;
+		data += size;
 	}
 	opal_free_async_token(token);
 




More information about the svn-src-head mailing list