Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 27 Mar 2012 15:13:12 +0000 (UTC)
From:      "Jayachandran C." <jchandra@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r233553 - head/sys/dev/cfi
Message-ID:  <201203271513.q2RFDCDq091343@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jchandra
Date: Tue Mar 27 15:13:12 2012
New Revision: 233553
URL: http://svn.freebsd.org/changeset/base/233553

Log:
  CFI fixes for big endian archs.
  
  The flash commands and responses are little-endian and have to be
  byte swapped on big-endian systems.  However the raw read of data
  need not be swapped.
  
  Make the cfi_read and cfi_write do the swapping, and provide a
  cfi_read_raw which does not byte swap for reading data from
  flash.

Modified:
  head/sys/dev/cfi/cfi_core.c
  head/sys/dev/cfi/cfi_dev.c
  head/sys/dev/cfi/cfi_disk.c
  head/sys/dev/cfi/cfi_var.h

Modified: head/sys/dev/cfi/cfi_core.c
==============================================================================
--- head/sys/dev/cfi/cfi_core.c	Tue Mar 27 15:07:43 2012	(r233552)
+++ head/sys/dev/cfi/cfi_core.c	Tue Mar 27 15:13:12 2012	(r233553)
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/systm.h>
 #include <sys/bus.h>
 #include <sys/conf.h>
+#include <sys/endian.h>
 #include <sys/kernel.h>
 #include <sys/malloc.h>   
 #include <sys/module.h>
@@ -54,7 +55,7 @@ devclass_t cfi_devclass;
 devclass_t cfi_diskclass;
 
 uint32_t
-cfi_read(struct cfi_softc *sc, u_int ofs)
+cfi_read_raw(struct cfi_softc *sc, u_int ofs)
 {
 	uint32_t val;
 
@@ -76,6 +77,32 @@ cfi_read(struct cfi_softc *sc, u_int ofs
 	return (val);
 }
 
+uint32_t
+cfi_read(struct cfi_softc *sc, u_int ofs)
+{
+	uint32_t val;
+	uint16_t sval;
+
+	ofs &= ~(sc->sc_width - 1);
+	switch (sc->sc_width) {
+	case 1:
+		val = bus_space_read_1(sc->sc_tag, sc->sc_handle, ofs);
+		break;
+	case 2:
+		sval = bus_space_read_2(sc->sc_tag, sc->sc_handle, ofs);
+		val = le16toh(sval);
+		break;
+	case 4:
+		val = bus_space_read_4(sc->sc_tag, sc->sc_handle, ofs);
+		val = le32toh(val);
+		break;
+	default:
+		val = ~0;
+		break;
+	}
+	return (val);
+}
+
 static void
 cfi_write(struct cfi_softc *sc, u_int ofs, u_int val)
 {
@@ -86,10 +113,10 @@ cfi_write(struct cfi_softc *sc, u_int of
 		bus_space_write_1(sc->sc_tag, sc->sc_handle, ofs, val);
 		break;
 	case 2:
-		bus_space_write_2(sc->sc_tag, sc->sc_handle, ofs, val);
+		bus_space_write_2(sc->sc_tag, sc->sc_handle, ofs, htole16(val));
 		break;
 	case 4:
-		bus_space_write_4(sc->sc_tag, sc->sc_handle, ofs, val);
+		bus_space_write_4(sc->sc_tag, sc->sc_handle, ofs, htole32(val));
 		break;
 	}
 }

Modified: head/sys/dev/cfi/cfi_dev.c
==============================================================================
--- head/sys/dev/cfi/cfi_dev.c	Tue Mar 27 15:07:43 2012	(r233552)
+++ head/sys/dev/cfi/cfi_dev.c	Tue Mar 27 15:13:12 2012	(r233553)
@@ -103,7 +103,7 @@ cfi_block_start(struct cfi_softc *sc, u_
 	/* Read the block from flash for byte-serving. */
 	ptr.x8 = sc->sc_wrbuf;
 	for (r = 0; r < sc->sc_wrbufsz; r += sc->sc_width) {
-		val = cfi_read(sc, sc->sc_wrofs + r);
+		val = cfi_read_raw(sc, sc->sc_wrofs + r);
 		switch (sc->sc_width) {
 		case 1:
 			*(ptr.x8)++ = val;
@@ -189,7 +189,7 @@ cfi_devread(struct cdev *dev, struct uio
 	while (error == 0 && uio->uio_resid > 0 &&
 	    uio->uio_offset < sc->sc_size) {
 		ofs = uio->uio_offset;
-		val = cfi_read(sc, ofs);
+		val = cfi_read_raw(sc, ofs);
 		switch (sc->sc_width) {
 		case 1:
 			buf.x8[0] = val;

Modified: head/sys/dev/cfi/cfi_disk.c
==============================================================================
--- head/sys/dev/cfi/cfi_disk.c	Tue Mar 27 15:07:43 2012	(r233552)
+++ head/sys/dev/cfi/cfi_disk.c	Tue Mar 27 15:13:12 2012	(r233553)
@@ -182,19 +182,19 @@ cfi_disk_read(struct cfi_softc *sc, stru
 	if (sc->sc_width == 1) {
 		uint8_t *dp = (uint8_t *)bp->bio_data;
 		while (resid > 0 && bp->bio_offset < sc->sc_size) {
-			*dp++ = cfi_read(sc, bp->bio_offset);
+			*dp++ = cfi_read_raw(sc, bp->bio_offset);
 			bp->bio_offset += 1, resid -= 1;
 		}
 	} else if (sc->sc_width == 2) {
 		uint16_t *dp = (uint16_t *)bp->bio_data;
 		while (resid > 0 && bp->bio_offset < sc->sc_size) {
-			*dp++ = cfi_read(sc, bp->bio_offset);
+			*dp++ = cfi_read_raw(sc, bp->bio_offset);
 			bp->bio_offset += 2, resid -= 2;
 		}
 	} else {
 		uint32_t *dp = (uint32_t *)bp->bio_data;
 		while (resid > 0 && bp->bio_offset < sc->sc_size) {
-			*dp++ = cfi_read(sc, bp->bio_offset);
+			*dp++ = cfi_read_raw(sc, bp->bio_offset);
 			bp->bio_offset += 4, resid -= 4;
 		}
 	}

Modified: head/sys/dev/cfi/cfi_var.h
==============================================================================
--- head/sys/dev/cfi/cfi_var.h	Tue Mar 27 15:07:43 2012	(r233552)
+++ head/sys/dev/cfi/cfi_var.h	Tue Mar 27 15:13:12 2012	(r233553)
@@ -71,6 +71,7 @@ int cfi_probe(device_t);
 int cfi_attach(device_t);
 int cfi_detach(device_t);
 
+uint32_t cfi_read_raw(struct cfi_softc *, u_int);
 uint32_t cfi_read(struct cfi_softc *, u_int);
 uint8_t cfi_read_qry(struct cfi_softc *, u_int);
 int cfi_write_block(struct cfi_softc *);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201203271513.q2RFDCDq091343>