Teach the md driver to use preloaded files of type "md_image".
This commit is contained in:
parent
bde2cb8327
commit
4209c94c0b
200
sys/dev/md/md.c
200
sys/dev/md/md.c
@ -19,6 +19,7 @@
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/linker.h>
|
||||
|
||||
#ifndef MDNSECT
|
||||
#define MDNSECT (10000 * 2)
|
||||
@ -61,11 +62,17 @@ struct md_s {
|
||||
struct buf_queue_head buf_queue;
|
||||
struct disk disk;
|
||||
dev_t dev;
|
||||
int busy;
|
||||
enum {MD_MALLOC, MD_PRELOAD} type;
|
||||
unsigned nsect;
|
||||
|
||||
/* MD_MALLOC related fields */
|
||||
unsigned nsecp;
|
||||
u_char **secp;
|
||||
|
||||
int busy;
|
||||
/* MD_PRELOAD related fields */
|
||||
u_char *pl_ptr;
|
||||
unsigned pl_len;
|
||||
};
|
||||
|
||||
static int mdunits;
|
||||
@ -87,7 +94,7 @@ mdopen(dev_t dev, int flag, int fmt, struct proc *p)
|
||||
dl->d_secsize = DEV_BSIZE;
|
||||
dl->d_nsectors = 1024;
|
||||
dl->d_ntracks = 1;
|
||||
dl->d_secpercyl = dl->d_nsectors + dl->d_ntracks;
|
||||
dl->d_secpercyl = dl->d_nsectors * dl->d_ntracks;
|
||||
dl->d_secperunit = sc->nsect;
|
||||
dl->d_ncylinders = dl->d_secperunit / dl->d_secpercyl;
|
||||
return (0);
|
||||
@ -148,78 +155,88 @@ mdstrategy(struct buf *bp)
|
||||
else
|
||||
dop = DEVSTAT_WRITE;
|
||||
|
||||
nsec = bp->b_bcount / DEV_BSIZE;
|
||||
secno = bp->b_pblkno;
|
||||
dst = bp->b_data;
|
||||
while (nsec--) {
|
||||
if (sc->type == MD_MALLOC) {
|
||||
nsec = bp->b_bcount / DEV_BSIZE;
|
||||
secno = bp->b_pblkno;
|
||||
dst = bp->b_data;
|
||||
while (nsec--) {
|
||||
|
||||
if (secno < sc->nsecp) {
|
||||
secpp = &sc->secp[secno];
|
||||
if ((u_int)*secpp > 255) {
|
||||
secp = *secpp;
|
||||
secval = 0;
|
||||
} else {
|
||||
secp = 0;
|
||||
secval = (u_int) *secpp;
|
||||
}
|
||||
} else {
|
||||
secpp = 0;
|
||||
secp = 0;
|
||||
secval = 0;
|
||||
}
|
||||
if (md_debug > 2)
|
||||
printf("%lx %p %p %d\n", bp->b_flags, secpp, secp, secval);
|
||||
|
||||
if (bp->b_flags & B_FREEBUF) {
|
||||
if (secpp) {
|
||||
if (secp)
|
||||
FREE(secp, M_MDSECT);
|
||||
*secpp = 0;
|
||||
}
|
||||
} else if (bp->b_flags & B_READ) {
|
||||
if (secp) {
|
||||
bcopy(secp, dst, DEV_BSIZE);
|
||||
} else if (secval) {
|
||||
for (i = 0; i < DEV_BSIZE; i++)
|
||||
dst[i] = secval;
|
||||
} else {
|
||||
bzero(dst, DEV_BSIZE);
|
||||
}
|
||||
} else {
|
||||
uc = dst[0];
|
||||
for (i = 1; i < DEV_BSIZE; i++)
|
||||
if (dst[i] != uc)
|
||||
break;
|
||||
if (i == DEV_BSIZE && !uc) {
|
||||
if (secp)
|
||||
FREE(secp, M_MDSECT);
|
||||
if (secpp)
|
||||
*secpp = (u_char *)uc;
|
||||
} else {
|
||||
if (!secpp) {
|
||||
MALLOC(secpp, u_char **, (secno + nsec + 1) * sizeof(u_char *), M_MD, M_WAITOK);
|
||||
bzero(secpp, (secno + nsec + 1) * sizeof(u_char *));
|
||||
bcopy(sc->secp, secpp, sc->nsecp * sizeof(u_char *));
|
||||
FREE(sc->secp, M_MD);
|
||||
sc->secp = secpp;
|
||||
sc->nsecp = secno + nsec + 1;
|
||||
secpp = &sc->secp[secno];
|
||||
if (secno < sc->nsecp) {
|
||||
secpp = &sc->secp[secno];
|
||||
if ((u_int)*secpp > 255) {
|
||||
secp = *secpp;
|
||||
secval = 0;
|
||||
} else {
|
||||
secp = 0;
|
||||
secval = (u_int) *secpp;
|
||||
}
|
||||
if (i == DEV_BSIZE) {
|
||||
} else {
|
||||
secpp = 0;
|
||||
secp = 0;
|
||||
secval = 0;
|
||||
}
|
||||
if (md_debug > 2)
|
||||
printf("%lx %p %p %d\n", bp->b_flags, secpp, secp, secval);
|
||||
|
||||
if (bp->b_flags & B_FREEBUF) {
|
||||
if (secpp) {
|
||||
if (secp)
|
||||
FREE(secp, M_MDSECT);
|
||||
*secpp = (u_char *)uc;
|
||||
*secpp = 0;
|
||||
}
|
||||
} else if (bp->b_flags & B_READ) {
|
||||
if (secp) {
|
||||
bcopy(secp, dst, DEV_BSIZE);
|
||||
} else if (secval) {
|
||||
for (i = 0; i < DEV_BSIZE; i++)
|
||||
dst[i] = secval;
|
||||
} else {
|
||||
if (!secp)
|
||||
MALLOC(secp, u_char *, DEV_BSIZE, M_MDSECT, M_WAITOK);
|
||||
bcopy(dst, secp, DEV_BSIZE);
|
||||
bzero(dst, DEV_BSIZE);
|
||||
}
|
||||
} else {
|
||||
uc = dst[0];
|
||||
for (i = 1; i < DEV_BSIZE; i++)
|
||||
if (dst[i] != uc)
|
||||
break;
|
||||
if (i == DEV_BSIZE && !uc) {
|
||||
if (secp)
|
||||
FREE(secp, M_MDSECT);
|
||||
if (secpp)
|
||||
*secpp = (u_char *)uc;
|
||||
} else {
|
||||
if (!secpp) {
|
||||
MALLOC(secpp, u_char **, (secno + nsec + 1) * sizeof(u_char *), M_MD, M_WAITOK);
|
||||
bzero(secpp, (secno + nsec + 1) * sizeof(u_char *));
|
||||
bcopy(sc->secp, secpp, sc->nsecp * sizeof(u_char *));
|
||||
FREE(sc->secp, M_MD);
|
||||
sc->secp = secpp;
|
||||
sc->nsecp = secno + nsec + 1;
|
||||
secpp = &sc->secp[secno];
|
||||
}
|
||||
if (i == DEV_BSIZE) {
|
||||
if (secp)
|
||||
FREE(secp, M_MDSECT);
|
||||
*secpp = (u_char *)uc;
|
||||
} else {
|
||||
if (!secp)
|
||||
MALLOC(secp, u_char *, DEV_BSIZE, M_MDSECT, M_WAITOK);
|
||||
bcopy(dst, secp, DEV_BSIZE);
|
||||
|
||||
*secpp = secp;
|
||||
*secpp = secp;
|
||||
}
|
||||
}
|
||||
}
|
||||
secno++;
|
||||
dst += DEV_BSIZE;
|
||||
}
|
||||
} else {
|
||||
if (bp->b_flags & B_FREEBUF) {
|
||||
/* nothing */
|
||||
} else if (bp->b_flags & B_READ) {
|
||||
bcopy(sc->pl_ptr + (secno << DEV_BSHIFT), bp->b_data, bp->b_bcount);
|
||||
} else {
|
||||
bcopy(bp->b_data, sc->pl_ptr + (secno << DEV_BSHIFT), bp->b_bcount);
|
||||
}
|
||||
secno++;
|
||||
dst += DEV_BSIZE;
|
||||
}
|
||||
|
||||
bp->b_resid = 0;
|
||||
@ -231,14 +248,36 @@ mdstrategy(struct buf *bp)
|
||||
return;
|
||||
}
|
||||
|
||||
static dev_t
|
||||
mdcreate(void)
|
||||
static void
|
||||
mdcreate_preload(u_char *image, unsigned length)
|
||||
{
|
||||
struct md_s *sc;
|
||||
|
||||
MALLOC(sc, struct md_s *,sizeof(*sc), M_MD, M_WAITOK);
|
||||
bzero(sc, sizeof(*sc));
|
||||
sc->unit = mdunits++;
|
||||
sc->type = MD_PRELOAD;
|
||||
bufq_init(&sc->buf_queue);
|
||||
devstat_add_entry(&sc->stats, "md", sc->unit, DEV_BSIZE,
|
||||
DEVSTAT_NO_ORDERED_TAGS,
|
||||
DEVSTAT_TYPE_DIRECT | DEVSTAT_TYPE_IF_OTHER, 0x190);
|
||||
sc->dev = disk_create(sc->unit, &sc->disk, 0,
|
||||
&md_cdevsw, &mddisk_cdevsw);
|
||||
sc->dev->si_drv1 = sc;
|
||||
sc->nsect = length / DEV_BSIZE;
|
||||
sc->pl_ptr = image;
|
||||
sc->pl_len = length;
|
||||
}
|
||||
|
||||
static void
|
||||
mdcreate_malloc(void)
|
||||
{
|
||||
struct md_s *sc;
|
||||
|
||||
MALLOC(sc, struct md_s *,sizeof(*sc), M_MD, M_WAITOK);
|
||||
bzero(sc, sizeof(*sc));
|
||||
sc->unit = mdunits++;
|
||||
sc->type = MD_MALLOC;
|
||||
|
||||
bufq_init(&sc->buf_queue);
|
||||
|
||||
@ -254,15 +293,36 @@ mdcreate(void)
|
||||
MALLOC(sc->secp, u_char **, sizeof(u_char *), M_MD, M_WAITOK);
|
||||
bzero(sc->secp, sizeof(u_char *));
|
||||
sc->nsecp = 1;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
md_drvinit(void *unused)
|
||||
{
|
||||
|
||||
mdcreate();
|
||||
caddr_t mod;
|
||||
caddr_t c;
|
||||
u_char *ptr, *name, *type;
|
||||
unsigned len;
|
||||
|
||||
mod = NULL;
|
||||
while ((mod = preload_search_next_name(mod)) != NULL) {
|
||||
name = (char *)preload_search_info(mod, MODINFO_NAME);
|
||||
type = (char *)preload_search_info(mod, MODINFO_TYPE);
|
||||
if (name == NULL)
|
||||
continue;
|
||||
if (type == NULL)
|
||||
continue;
|
||||
if (strcmp(type, "md_image"))
|
||||
continue;
|
||||
c = preload_search_info(mod, MODINFO_ADDR);
|
||||
ptr = *(u_char **)c;
|
||||
c = preload_search_info(mod, MODINFO_SIZE);
|
||||
len = *(unsigned *)c;
|
||||
printf("md%d: Preloaded image <%s> %d bytes at %p\n",
|
||||
mdunits, name, len, ptr);
|
||||
mdcreate_preload(ptr, len);
|
||||
}
|
||||
mdcreate_malloc();
|
||||
}
|
||||
|
||||
SYSINIT(ptcdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR, md_drvinit,NULL)
|
||||
|
Loading…
Reference in New Issue
Block a user