Example #1
0
/*
 * Common code for read and readdir.
 */
static
int
emu_doread(struct emu_softc *sc, uint32_t handle, uint32_t len,
	   uint32_t op, struct uio *uio)
{
	int result;

	KASSERT(uio->uio_rw == UIO_READ);

	if (uio->uio_offset > (off_t)0xffffffff) {
		/* beyond the largest size the file can have; generate EOF */
		return 0;
	}

	lock_acquire(sc->e_lock);

	emu_wreg(sc, REG_HANDLE, handle);
	emu_wreg(sc, REG_IOLEN, len);
	emu_wreg(sc, REG_OFFSET, uio->uio_offset);
	emu_wreg(sc, REG_OPER, op);
	result = emu_waitdone(sc);
	if (result) {
		goto out;
	}

	membar_load_load();
	result = uiomove(sc->e_iobuf, emu_rreg(sc, REG_IOLEN), uio);

	uio->uio_offset = emu_rreg(sc, REG_OFFSET);

 out:
	lock_release(sc->e_lock);
	return result;
}
Example #2
0
/*
 * Common code for read and readdir.
 */
static
int
emu_doread(struct emu_softc *sc, uint32_t handle, uint32_t len,
           uint32_t op, struct uio *uio)
{
    int result;

    KASSERT(uio->uio_rw == UIO_READ);

    lock_acquire(sc->e_lock);

    emu_wreg(sc, REG_HANDLE, handle);
    emu_wreg(sc, REG_IOLEN, len);
    emu_wreg(sc, REG_OFFSET, uio->uio_offset);
    emu_wreg(sc, REG_OPER, op);
    result = emu_waitdone(sc);
    if (result) {
        goto out;
    }

    result = uiomove(sc->e_iobuf, emu_rreg(sc, REG_IOLEN), uio);

    uio->uio_offset = emu_rreg(sc, REG_OFFSET);

out:
    lock_release(sc->e_lock);
    return result;
}
Example #3
0
/*
 * Common file open routine (for both VOP_LOOKUP and VOP_CREATE).  Not
 * for VOP_EACHOPEN. At the hardware level, we need to "open" files in
 * order to look at them, so by the time VOP_EACHOPEN is called the
 * files are already open.
 */
static
int
emu_open(struct emu_softc *sc, uint32_t handle, const char *name,
	 bool create, bool excl, mode_t mode,
	 uint32_t *newhandle, int *newisdir)
{
	uint32_t op;
	int result;

	if (strlen(name)+1 > EMU_MAXIO) {
		return ENAMETOOLONG;
	}

	if (create && excl) {
		op = EMU_OP_EXCLCREATE;
	}
	else if (create) {
		op = EMU_OP_CREATE;
	}
	else {
		op = EMU_OP_OPEN;
	}

	/* mode isn't supported (yet?) */
	(void)mode;

	lock_acquire(sc->e_lock);

	strcpy(sc->e_iobuf, name);
	membar_store_store();
	emu_wreg(sc, REG_IOLEN, strlen(name));
	emu_wreg(sc, REG_HANDLE, handle);
	emu_wreg(sc, REG_OPER, op);
	result = emu_waitdone(sc);

	if (result==0) {
		*newhandle = emu_rreg(sc, REG_HANDLE);
		*newisdir = emu_rreg(sc, REG_IOLEN)>0;
	}

	lock_release(sc->e_lock);
	return result;
}
Example #4
0
/*
 * Called by the underlying bus code when an interrupt happens
 */
void
emu_irq(void *dev)
{
	struct emu_softc *sc = dev;

	sc->e_result = emu_rreg(sc, REG_RESULT);
	emu_wreg(sc, REG_RESULT, 0);

	V(sc->e_sem);
}
Example #5
0
/*
 * Get the file size associated with a hardware-level file handle.
 */
static
int
emu_getsize(struct emu_softc *sc, uint32_t handle, off_t *retval)
{
	int result;

	lock_acquire(sc->e_lock);

	emu_wreg(sc, REG_HANDLE, handle);
	emu_wreg(sc, REG_OPER, EMU_OP_GETSIZE);
	result = emu_waitdone(sc);
	if (result==0) {
		*retval = emu_rreg(sc, REG_IOLEN);
	}

	lock_release(sc->e_lock);
	return result;
}