コード例 #1
0
ファイル: cfi_disk.c プロジェクト: 2asoft/freebsd
static void
cfi_disk_read(struct cfi_softc *sc, struct bio *bp)
{
	long resid;

	KASSERT(sc->sc_width == 1 || sc->sc_width == 2 || sc->sc_width == 4,
	    ("sc_width %d", sc->sc_width));

	if (sc->sc_writing) {
		bp->bio_error = cfi_block_finish(sc);
		if (bp->bio_error) {
			bp->bio_flags |= BIO_ERROR;
			goto done;
		}
	}
	if (bp->bio_offset > sc->sc_size) {
		bp->bio_flags |= BIO_ERROR;
		bp->bio_error = EIO;
		goto done;
	}
	resid = bp->bio_bcount;
	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_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_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_raw(sc, bp->bio_offset);
			bp->bio_offset += 4, resid -= 4;
		}
	}
	bp->bio_resid = resid;
done:
	biodone(bp);
}
コード例 #2
0
ファイル: cfi_dev.c プロジェクト: JabirTech/Source
/*
 * Begin writing into a new block/sector.  We read the sector into
 * memory and keep updating that, until we move into another sector
 * or the process stops writing. At that time we write the whole
 * sector to flash (see cfi_block_finish).  To avoid unneeded erase
 * cycles, keep a pristine copy of the sector on hand.
 */
int
cfi_block_start(struct cfi_softc *sc, u_int ofs)
{
	union {
		uint8_t		*x8;
		uint16_t	*x16;
		uint32_t	*x32;
	} ptr;
	u_int rofs, rsz;
	uint32_t val;
	int r;

	rofs = 0;
	for (r = 0; r < sc->sc_regions; r++) {
		rsz = sc->sc_region[r].r_blocks * sc->sc_region[r].r_blksz;
		if (ofs < rofs + rsz)
			break;
		rofs += rsz;
	}
	if (r == sc->sc_regions)
		return (EFAULT);

	sc->sc_wrbufsz = sc->sc_region[r].r_blksz;
	sc->sc_wrbuf = malloc(sc->sc_wrbufsz, M_TEMP, M_WAITOK);
	sc->sc_wrofs = ofs - (ofs - rofs) % sc->sc_wrbufsz;

	/* 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_raw(sc, sc->sc_wrofs + r);
		switch (sc->sc_width) {
		case 1:
			*(ptr.x8)++ = val;
			break;
		case 2:
			*(ptr.x16)++ = val;
			break;
		case 4:
			*(ptr.x32)++ = val;
			break;
		}
	}
	sc->sc_wrbufcpy = malloc(sc->sc_wrbufsz, M_TEMP, M_WAITOK);
	memcpy(sc->sc_wrbufcpy, sc->sc_wrbuf, sc->sc_wrbufsz);
	sc->sc_writing = 1;
	return (0);
}
コード例 #3
0
ファイル: cfi_dev.c プロジェクト: JabirTech/Source
static int
cfi_devread(struct cdev *dev, struct uio *uio, int ioflag)
{
	union {
		uint8_t		x8[4];
		uint16_t	x16[2];
		uint32_t	x32[1];
	} buf;
	struct cfi_softc *sc;
	u_int ofs;
	uint32_t val;
	int error;

	sc = dev->si_drv1;

	error = (sc->sc_writing) ? cfi_block_finish(sc) : 0;
	if (!error)
		error = (uio->uio_offset > sc->sc_size) ? EIO : 0;

	while (error == 0 && uio->uio_resid > 0 &&
	    uio->uio_offset < sc->sc_size) {
		ofs = uio->uio_offset;
		val = cfi_read_raw(sc, ofs);
		switch (sc->sc_width) {
		case 1:
			buf.x8[0] = val;
			break;
		case 2:
			buf.x16[0] = val;
			break;
		case 4:
			buf.x32[0] = val;
			break;
		}
		ofs &= sc->sc_width - 1;
		error = uiomove(buf.x8 + ofs,
		    MIN(uio->uio_resid, sc->sc_width - ofs), uio);
	}
	return (error);
}