Пример #1
0
static void
cfi_disk_write(struct cfi_softc *sc, struct bio *bp)
{
	long resid;
	u_int top;

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

	if (bp->bio_offset > sc->sc_size) {
		bp->bio_flags |= BIO_ERROR;
		bp->bio_error = EIO;
		goto done;
	}
	resid = bp->bio_bcount;
	while (resid > 0) {
		/*
		 * Finish the current block if we're about to write
		 * to a different block.
		 */
		if (sc->sc_writing) {
			top = sc->sc_wrofs + sc->sc_wrbufsz;
			if (bp->bio_offset < sc->sc_wrofs ||
			    bp->bio_offset >= top)
				cfi_block_finish(sc);
		}

		/* Start writing to a (new) block if applicable. */
		if (!sc->sc_writing) {
			bp->bio_error = cfi_block_start(sc, bp->bio_offset);
			if (bp->bio_error) {
				bp->bio_flags |= BIO_ERROR;
				goto done;
			}
		}

		top = sc->sc_wrofs + sc->sc_wrbufsz;
		bcopy(bp->bio_data,
		    sc->sc_wrbuf + bp->bio_offset - sc->sc_wrofs,
		    MIN(top - bp->bio_offset, resid));
		resid -= MIN(top - bp->bio_offset, resid);
	}
	bp->bio_resid = resid;
done:
	biodone(bp);
}
Пример #2
0
static int
cfi_devwrite(struct cdev *dev, struct uio *uio, int ioflag)
{
	struct cfi_softc *sc;
	u_int ofs, top;
	int error;

	sc = dev->si_drv1;

	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;

		/*
		 * Finish the current block if we're about to write
		 * to a different block.
		 */
		if (sc->sc_writing) {
			top = sc->sc_wrofs + sc->sc_wrbufsz;
			if (ofs < sc->sc_wrofs || ofs >= top)
				cfi_block_finish(sc);
		}

		/* Start writing to a (new) block if applicable. */
		if (!sc->sc_writing) {
			error = cfi_block_start(sc, uio->uio_offset);
			if (error)
				break;
		}

		top = sc->sc_wrofs + sc->sc_wrbufsz;
		error = uiomove(sc->sc_wrbuf + ofs - sc->sc_wrofs,
		    MIN(top - ofs, uio->uio_resid), uio);
	}
	return (error);
}