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.
This commit is contained in:
parent
9742410797
commit
9c1f1330d6
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=233553
@ -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 ofs, u_int val)
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ cfi_block_start(struct cfi_softc *sc, u_int ofs)
|
||||
/* 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 *uio, int ioflag)
|
||||
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;
|
||||
|
@ -182,19 +182,19 @@ cfi_disk_read(struct cfi_softc *sc, struct bio *bp)
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -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 *);
|
||||
|
Loading…
Reference in New Issue
Block a user