Add support for block devices.

This commit is contained in:
pooka 2007-11-21 18:10:48 +00:00
parent dc3828d089
commit 750d633918
3 changed files with 60 additions and 28 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: pud.c,v 1.2 2007/11/21 01:31:34 dogcow Exp $ */ /* $NetBSD: pud.c,v 1.3 2007/11/21 18:10:48 pooka Exp $ */
/* /*
* Copyright (c) 2007 Antti Kantee. All Rights Reserved. * Copyright (c) 2007 Antti Kantee. All Rights Reserved.
@ -29,7 +29,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: pud.c,v 1.2 2007/11/21 01:31:34 dogcow Exp $"); __KERNEL_RCSID(0, "$NetBSD: pud.c,v 1.3 2007/11/21 18:10:48 pooka Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/conf.h> #include <sys/conf.h>
@ -100,6 +100,7 @@ pud_putter_getout(void *this, size_t maxsize, int nonblock,
putp = TAILQ_FIRST(&pd->pd_waitq_req); putp = TAILQ_FIRST(&pd->pd_waitq_req);
TAILQ_REMOVE(&pd->pd_waitq_req, putp, pt_entries); TAILQ_REMOVE(&pd->pd_waitq_req, putp, pt_entries);
KASSERT(error == 0);
break; break;
} }
mutex_exit(&pd->pd_mtx); mutex_exit(&pd->pd_mtx);
@ -177,7 +178,7 @@ pudconf_reg(struct pud_dev *pd, struct pud_conf_reg *pcr)
int cmajor, bmajor, error; int cmajor, bmajor, error;
cmajor = major(pcr->pm_regdev); cmajor = major(pcr->pm_regdev);
if (pcr->pm_flags & PUD_CONF_BDEV) { if (pcr->pm_flags & PUD_CONFFLAG_BDEV) {
bsw = &pud_bdevsw; bsw = &pud_bdevsw;
bmajor = cmajor; bmajor = cmajor;
} else { } else {

View File

@ -1,4 +1,4 @@
/* $NetBSD: pud_dev.c,v 1.2 2007/11/21 11:19:44 pooka Exp $ */ /* $NetBSD: pud_dev.c,v 1.3 2007/11/21 18:10:48 pooka Exp $ */
/* /*
* Copyright (c) 2007 Antti Kantee. All Rights Reserved. * Copyright (c) 2007 Antti Kantee. All Rights Reserved.
@ -29,7 +29,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: pud_dev.c,v 1.2 2007/11/21 11:19:44 pooka Exp $"); __KERNEL_RCSID(0, "$NetBSD: pud_dev.c,v 1.3 2007/11/21 18:10:48 pooka Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/buf.h> #include <sys/buf.h>
@ -41,6 +41,17 @@ __KERNEL_RCSID(0, "$NetBSD: pud_dev.c,v 1.2 2007/11/21 11:19:44 pooka Exp $");
#include <dev/pud/pud_sys.h> #include <dev/pud/pud_sys.h>
static int
openclose(dev_t dev, int flags, int fmt, int class, int type)
{
struct pud_req_openclose pc_oc; /* XXX: stack = stupid */
pc_oc.pm_flags = flags;
pc_oc.pm_fmt = fmt;
return pud_request(dev, &pc_oc, sizeof(pc_oc), class, type);
}
/* /*
* Block de-vices * Block de-vices
*/ */
@ -69,21 +80,50 @@ static int
pud_bdev_open(dev_t dev, int flags, int fmt, lwp_t *l) pud_bdev_open(dev_t dev, int flags, int fmt, lwp_t *l)
{ {
return EOPNOTSUPP; return openclose(dev, flags, fmt, PUD_REQ_BDEV, PUD_BDEV_OPEN);
} }
static int static int
pud_bdev_close(dev_t dev, int flags, int fmt, lwp_t *l) pud_bdev_close(dev_t dev, int flags, int fmt, lwp_t *l)
{ {
return EOPNOTSUPP; return openclose(dev, flags, fmt, PUD_REQ_BDEV, PUD_BDEV_CLOSE);
} }
static void static void
pud_bdev_strategy(struct buf *bp) pud_bdev_strategy(struct buf *bp)
{ {
struct pud_req_readwrite *pc_rw;
size_t allocsize;
int error;
bp->b_error = EOPNOTSUPP; allocsize = sizeof(struct pud_req_readwrite) + bp->b_bcount;
pc_rw = kmem_zalloc(allocsize, KM_SLEEP);
pc_rw->pm_offset = bp->b_blkno << DEV_BSHIFT;
pc_rw->pm_resid = bp->b_bcount;
if (BUF_ISWRITE(bp))
memcpy(pc_rw->pm_data, bp->b_data, bp->b_bcount);
error = pud_request(bp->b_dev, pc_rw, allocsize, PUD_REQ_BDEV,
BUF_ISREAD(bp) ? PUD_BDEV_STRATREAD : PUD_BDEV_STRATWRITE);
if (error)
goto out;
if (pc_rw->pm_resid > bp->b_bcount) {
error = EINVAL;
goto out;
}
if (BUF_ISREAD(bp))
memcpy(bp->b_data,pc_rw->pm_data,bp->b_bcount-pc_rw->pm_resid);
bp->b_resid = pc_rw->pm_resid;
out:
kmem_free(pc_rw, allocsize);
bp->b_error = error;
biodone(bp); biodone(bp);
} }
@ -143,25 +183,15 @@ struct cdevsw pud_cdevsw = {
static int static int
pud_cdev_open(dev_t dev, int flags, int fmt, lwp_t *l) pud_cdev_open(dev_t dev, int flags, int fmt, lwp_t *l)
{ {
struct pud_creq_open pc_open; /* XXX: stack = stupid */
pc_open.pm_flags = flags; return openclose(dev, flags, fmt, PUD_REQ_CDEV, PUD_CDEV_OPEN);
pc_open.pm_fmt = fmt;
return pud_request(dev, &pc_open, sizeof(pc_open),
PUD_REQ_CDEV, PUD_CDEV_OPEN);
} }
static int static int
pud_cdev_close(dev_t dev, int flags, int fmt, lwp_t *l) pud_cdev_close(dev_t dev, int flags, int fmt, lwp_t *l)
{ {
struct pud_creq_close pc_close; /* XXX: stack = stupid */
pc_close.pm_flags = flags; return openclose(dev, flags, fmt, PUD_REQ_CDEV, PUD_CDEV_OPEN);
pc_close.pm_fmt = fmt;
return pud_request(dev, &pc_close, sizeof(pc_close),
PUD_REQ_CDEV, PUD_CDEV_CLOSE);
} }
static int static int
@ -187,7 +217,8 @@ pud_cdev_read(dev_t dev, struct uio *uio, int flag)
goto out; goto out;
} }
error = uiomove(pc_read->pm_data, pc_read->pm_resid, uio); error = uiomove(pc_read->pm_data,
uio->uio_resid - pc_read->pm_resid, uio);
out: out:
kmem_free(pc_read, allocsize); kmem_free(pc_read, allocsize);

View File

@ -1,4 +1,4 @@
/* $NetBSD: pud_msgif.h,v 1.1 2007/11/20 18:47:05 pooka Exp $ */ /* $NetBSD: pud_msgif.h,v 1.2 2007/11/21 18:10:48 pooka Exp $ */
/* /*
* Copyright (c) 2007 Antti Kantee. All Rights Reserved. * Copyright (c) 2007 Antti Kantee. All Rights Reserved.
@ -68,9 +68,9 @@ struct pud_req_openclose {
int pm_fmt; int pm_fmt;
}; };
#define pud_creq_read pud_creq_readwrite #define pud_creq_read pud_req_readwrite
#define pud_creq_write pud_creq_readwrite #define pud_creq_write pud_req_readwrite
struct pud_creq_readwrite { struct pud_req_readwrite {
struct pud_req pm_pdr; struct pud_req pm_pdr;
off_t pm_offset; off_t pm_offset;
@ -87,7 +87,7 @@ struct pud_conf_reg {
int pm_flags; int pm_flags;
char pm_devname[PUD_DEVNAME_MAX+1]; char pm_devname[PUD_DEVNAME_MAX+1];
}; };
#define PUD_CONF_BDEV 1 #define PUD_CONFFLAG_BDEV 1
struct pud_conf_ioctl { struct pud_conf_ioctl {
struct pud_req pm_pdr; struct pud_req pm_pdr;
@ -103,12 +103,12 @@ enum {
}; };
enum { enum {
PUD_BDEV_OPEN, PUD_BDEV_CLOSE, PUD_BDEV_STRATEGY, PUD_BDEV_OPEN, PUD_BDEV_CLOSE, PUD_BDEV_STRATREAD, PUD_BDEV_STRATWRITE,
PUD_BDEV_IOCTL, PUD_BDEV_DUMP, PUD_BDEV_PSIZE, PUD_BDEV_IOCTL, PUD_BDEV_DUMP, PUD_BDEV_PSIZE,
}; };
enum { enum {
PUD_CONF_REG, PUD_CONF_DEREG, PUD_CONF_IOCTL, PUD_CONF_REG, PUD_CONF_DEREG, PUD_CONF_IOCTL, PUD_CONF_MMAP,
}; };
#endif /* _DEV_PUD_PUDMSGIF_H_ */ #endif /* _DEV_PUD_PUDMSGIF_H_ */