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 *);
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to