/*
 * This file is part of the UCB release of Plan 9. It is subject to the license
 * terms in the LICENSE file found in the top-level directory of this
 * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
 * part of the UCB release of Plan 9, including this file, may be copied,
 * modified, propagated, or distributed except according to the terms contained
 * in the LICENSE file.
 */

/*
 * Storage Device.
 */


#include <assert.h>
#include <cpio.h>
#include <error.h>
#include <net/ip.h>
#include <kmalloc.h>
#include <kref.h>
#include <pmap.h>
#include <slab.h>
#include <smp.h>
#include <stdio.h>
#include <string.h>

#include <sd.h>

extern struct dev sddevtab;
struct sdifc sdiahciifc;

/* In Plan 9, this array is auto-generated. That's almost certainly not
 * necessary;
 * we can use linker sets at some point, as we do elsewhere in Akaros. */
struct sdifc *sdifc[] = {
    &sdiahciifc, NULL,
};

static const char Echange[] = "media or partition has changed";

static const char devletters[] =
    "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

static struct sdev *devs[sizeof(devletters) - 1];

static qlock_t devslock = QLOCK_INITIALIZER(devslock);

enum {
	Rawcmd,
	Rawdata,
	Rawstatus,
};

enum {
	Qtopdir = 1, /* top level directory */
	Qtopbase,
	Qtopctl = Qtopbase,

	Qunitdir, /* directory per unit */
	Qunitbase,
	Qctl = Qunitbase,
	Qraw,
	Qpart,

	TypeLOG = 4,
	NType = (1 << TypeLOG),
	TypeMASK = (NType - 1),
	TypeSHIFT = 0,

	PartLOG = 8,
	NPart = (1 << PartLOG),
	PartMASK = (NPart - 1),
	PartSHIFT = TypeLOG,

	UnitLOG = 8,
	NUnit = (1 << UnitLOG),
	UnitMASK = (NUnit - 1),
	UnitSHIFT = (PartLOG + TypeLOG),

	DevLOG = 8,
	NDev = (1 << DevLOG),
	DevMASK = (NDev - 1),
	DevSHIFT = (UnitLOG + PartLOG + TypeLOG),

	Ncmd = 20,
};

#define TYPE(q) ((((uint32_t)(q).path) >> TypeSHIFT) & TypeMASK)
#define PART(q) ((((uint32_t)(q).path) >> PartSHIFT) & PartMASK)
#define UNIT(q) ((((uint32_t)(q).path) >> UnitSHIFT) & UnitMASK)
#define DEV(q) ((((uint32_t)(q).path) >> DevSHIFT) & DevMASK)
#define QID(d, u, p, t)                                                        \
	(((d) << DevSHIFT) | ((u) << UnitSHIFT) | ((p) << PartSHIFT) |             \
	 ((t) << TypeSHIFT))

void sdaddpart(struct sdunit *unit, char *name, uint64_t start, uint64_t end)
{
	struct sdpart *pp;
	int i, partno;

	/*
	 * Check name not already used
	 * and look for a free slot.
	 */
	if (unit->part != NULL) {
		partno = -1;
		for (i = 0; i < unit->npart; i++) {
			pp = &unit->part[i];
			if (!pp->valid) {
				if (partno == -1)
					partno = i;
				break;
			}
			if (strcmp(name, pp->sdperm.name) == 0) {
				if (pp->start == start && pp->end == end)
					return;
				error(EINVAL, "%s: '%s' is not valid", __func__, name);
			}
		}
	} else {
		unit->part = kzmalloc(sizeof(struct sdpart) * SDnpart, 0);
		if (unit->part == NULL)
			error(ENOMEM, "%s: can't allocate %d bytes", __func__,
			      sizeof(struct sdpart) * SDnpart);
		unit->npart = SDnpart;
		partno = 0;
	}

	/*
	 * If no free slot found then increase the
	 * array size (can't get here with unit->part == NULL).
	 */
	if (partno == -1) {
		if (unit->npart >= NPart)
			error(ENOMEM, "%s: no memory", __func__);
		pp = kzmalloc(sizeof(struct sdpart) * (unit->npart + SDnpart), 0);
		if (pp == NULL)
			error(ENOMEM, "%s: Can't allocate space for %d partitions",
			      unit->npart + SDnpart);
		memmove(pp, unit->part, sizeof(struct sdpart) * unit->npart);
		kfree(unit->part);
		unit->part = pp;
		partno = unit->npart;
		unit->npart += SDnpart;
	}

	/*
	 * Check size and extent are valid.
	 */
	if (start > end)
		error(EINVAL, "%s: start %d > end %d", __func__, start, end);
	if (end > unit->sectors)
		error(EINVAL, "%s: end %d > number of sectors %d", __func__, end,
		      unit->sectors);
	pp = &unit->part[partno];
	pp->start = start;
	pp->end = end;
	kstrdup(&pp->sdperm.name, name);
	kstrdup(&pp->sdperm.user, eve.name);
	pp->sdperm.perm = 0640;
	pp->valid = 1;
}

static void sddelpart(struct sdunit *unit, char *name)
{
	int i;
	struct sdpart *pp;
	/*
	 * Look for the partition to delete.
	 * Can't delete if someone still has it open.
	 */
	pp = unit->part;
	for (i = 0; i < unit->npart; i++) {
		if (strcmp(name, pp->sdperm.name) == 0)
			break;
		pp++;
	}
	if (i >= unit->npart)
		error(EINVAL, "%s: %d > npart %d", __func__, i, unit->npart);

	/* TODO: Implement permission checking and raise errors as appropriate. */
	// if (strcmp(current->user.name, pp->SDperm.user) && !iseve())
		// error(Eperm);

	pp->valid = 0;
	pp->vers++;
}

static void sdincvers(struct sdunit *unit)
{
	int i;

	unit->vers++;
	if (unit->part) {
		for (i = 0; i < unit->npart; i++) {
			unit->part[i].valid = 0;
			unit->part[i].vers++;
		}
	}
}

static int sdinitpart(struct sdunit *unit)
{
#if 0
	Mach *m;
	int nf;
	uint64_t start, end;
	char *f[4], *p, *q, buf[10];

	m = machp();
#endif
	if (unit->sectors > 0) {
		unit->sectors = unit->secsize = 0;
		sdincvers(unit);
	}

	/* device must be connected or not; other values are trouble */
	if (unit->inquiry[0] & 0xC0) /* see SDinq0periphqual */
		return 0;
	switch (unit->inquiry[0] & SDinq0periphtype) {
	case SDperdisk:
	case SDperworm:
	case SDpercd:
	case SDpermo:
		break;
	default:
		return 0;
	}

	if (unit->dev->ifc->online)
		unit->dev->ifc->online(unit);
	if (unit->sectors) {
		sdincvers(unit);
		sdaddpart(unit, "data", 0, unit->sectors);

/*
 * Use partitions passed from boot program,
 * e.g.
 *	sdC0part=dos 63 123123/plan9 123123 456456
 * This happens before /boot sets hostname so the
 * partitions will have the null-string for user.
 * The gen functions patch it up.
 */
#if 0
		snprintf(buf, sizeof(buf), "%spart", unit->sdperm.name);
		for (p = getconf(buf); p != NULL; p = q) {
			q = strchr(p, '/');
			if (q)
				*q++ = '\0';
			nf = tokenize(p, f, ARRAY_SIZE(f));
			if (nf < 3)
				continue;

			start = strtoull(f[1], 0, 0);
			end = strtoull(f[2], 0, 0);
			if (!waserror())
				sdaddpart(unit, f[0], start, end);
			poperror();
		}
#endif
	}

	return 1;
}

static int sdindex(int idno)
{
	char *p;

	p = strchr(devletters, idno);
	if (p == NULL)
		return -1;
	return p - devletters;
}

static struct sdev *sdgetdev(int idno)
{
	struct sdev *sdev;
	int i;

	if ((i = sdindex(idno)) < 0)
		return NULL;

	qlock(&devslock);
	sdev = devs[i];
	if (sdev)
		kref_get(&sdev->r, 1);
	qunlock(&devslock);
	return sdev;
}

static struct sdunit *sdgetunit(struct sdev *sdev, int subno)
{
	struct sdunit *unit;
	char buf[32];

	/*
	 * Associate a unit with a given device and sub-unit
	 * number on that device.
	 * The device will be probed if it has not already been
	 * successfully accessed.
	 */
	qlock(&sdev->unitlock);
	if (subno > sdev->nunit) {
		qunlock(&sdev->unitlock);
		return NULL;
	}

	unit = sdev->unit[subno];
	if (unit == NULL) {
		/*
		 * Probe the unit only once. This decision
		 * may be a little severe and reviewed later.
		 */
		if (sdev->unitflg[subno]) {
			qunlock(&sdev->unitlock);
			return NULL;
		}
		unit = kzmalloc(sizeof(struct sdunit), 0);
		if (unit == NULL) {
			qunlock(&sdev->unitlock);
			return NULL;
		}
		sdev->unitflg[subno] = 1;

		snprintf(buf, sizeof(buf), "%s%d", sdev->name, subno);
		kstrdup(&unit->sdperm.name, buf);
		kstrdup(&unit->sdperm.user, eve.name);
		unit->sdperm.perm = 0555;
		unit->subno = subno;
		unit->dev = sdev;
		qlock_init(&unit->ctl);

		if (sdev->enabled == 0 && sdev->ifc->enable)
			sdev->ifc->enable(sdev);
		sdev->enabled = 1;

		/*
		 * No need to lock anything here as this is only
		 * called before the unit is made available in the
		 * sdunit[] array.
		 */
		if (unit->dev->ifc->verify(unit) == 0) {
			qunlock(&sdev->unitlock);
			kfree(unit);
			return NULL;
		}
		sdev->unit[subno] = unit;
	}
	qunlock(&sdev->unitlock);
	return unit;
}

static void sdreset(void)
{
	int i;
	struct sdev *sdev;

	/*
	 * Probe all known controller types and register any devices found.
	 */
	for (i = 0; sdifc[i] != NULL; i++) {
		if (sdifc[i]->pnp == NULL)
			continue;
		sdev = sdifc[i]->pnp();
		if (sdev == NULL)
			continue;
		sdadddevs(sdev);
	}
}

void sdadddevs(struct sdev *sdev)
{
	int i, j, id;
	struct sdev *next;

	for (; sdev; sdev = next) {
		next = sdev->next;

		sdev->unit = (struct sdunit **)kzmalloc(
		    sdev->nunit * sizeof(struct sdunit *), 0);
		sdev->unitflg = (int *)kzmalloc(sdev->nunit * sizeof(int), 0);
		if (sdev->unit == NULL || sdev->unitflg == NULL) {
			printd("sdadddevs: out of memory\n");
		giveup:
			kfree(sdev->unit);
			kfree(sdev->unitflg);
			if (sdev->ifc->clear)
				sdev->ifc->clear(sdev);
			kfree(sdev);
			continue;
		}
		id = sdindex(sdev->idno);
		if (id == -1) {
			printd("sdadddevs: bad id number %d (%C)\n", id, id);
			goto giveup;
		}
		qlock(&devslock);
		for (i = 0; i < ARRAY_SIZE(devs); i++) {
			j = (id + i) % ARRAY_SIZE(devs);
			if (devs[j] == NULL) {
				sdev->idno = devletters[j];
				devs[j] = sdev;
				snprintf(sdev->name, sizeof(sdev->name), "sd%c", devletters[j]);
				break;
			}
		}
		qunlock(&devslock);
		if (i == ARRAY_SIZE(devs)) {
			printd("sdadddevs: out of device letters\n");
			goto giveup;
		}
	}
}

void sdaddallconfs(void (*addconf)(struct sdunit *))
{
	int i, u;
	struct sdev *sdev;

	for (i = 0; i < ARRAY_SIZE(devs); i++) /* each controller */
		for (sdev = devs[i]; sdev; sdev = sdev->next)
			for (u = 0; u < sdev->nunit; u++) /* each drive */
				(*addconf)(sdev->unit[u]);
}

static int sd2gen(struct chan *c, int i, struct dir *dp)
{
	struct qid q;
	uint64_t l;
	struct sdpart *pp;
	struct sdperm *perm;
	struct sdunit *unit;
	struct sdev *sdev;
	int rv;

	sdev = sdgetdev(DEV(c->qid));
	assert(sdev);
	unit = sdev->unit[UNIT(c->qid)];

	rv = -1;
	switch (i) {
	case Qctl:
		mkqid(&q, QID(DEV(c->qid), UNIT(c->qid), PART(c->qid), Qctl),
		      unit->vers, QTFILE);
		perm = &unit->ctlperm;
		if (emptystr(perm->user)) {
			kstrdup(&perm->user, eve.name);
			perm->perm = 0644; /* nothing secret in ctl */
		}
		devdir(c, q, "ctl", 0, perm->user, perm->perm, dp);
		rv = 1;
		break;

	case Qraw:
		mkqid(&q, QID(DEV(c->qid), UNIT(c->qid), PART(c->qid), Qraw),
		      unit->vers, QTFILE);
		perm = &unit->rawperm;
		if (emptystr(perm->user)) {
			kstrdup(&perm->user, eve.name);
			perm->perm = DMEXCL | 0600;
		}
		devdir(c, q, "raw", 0, perm->user, perm->perm, dp);
		rv = 1;
		break;

	case Qpart:
		pp = &unit->part[PART(c->qid)];
		l = (pp->end - pp->start) * unit->secsize;
		mkqid(&q, QID(DEV(c->qid), UNIT(c->qid), PART(c->qid), Qpart),
		      unit->vers + pp->vers, QTFILE);
		if (emptystr(pp->sdperm.user))
			kstrdup(&pp->sdperm.user, eve.name);
		devdir(c, q, pp->sdperm.name, l, pp->sdperm.user, pp->sdperm.perm, dp);
		rv = 1;
		break;
	}

	kref_put(&sdev->r);
	return rv;
}

static int sd1gen(struct chan *c, int i, struct dir *dp)
{
	struct qid q;

	switch (i) {
	case Qtopctl:
		mkqid(&q, QID(0, 0, 0, Qtopctl), 0, QTFILE);
		devdir(c, q, "sdctl", 0, eve.name, 0644, dp); /* no secrets */
		return 1;
	}
	return -1;
}

static int sdgen(struct chan *c, char *d, struct dirtab *dir, int j, int s,
                 struct dir *dp)
{
	struct qid q = {};
	int64_t l;
	int i, r;
	struct sdpart *pp;
	struct sdunit *unit;
	struct sdev *sdev;

	switch (TYPE(c->qid)) {
	case Qtopdir:
		if (s == DEVDOTDOT) {
			mkqid(&q, QID(0, 0, 0, Qtopdir), 0, QTDIR);
			snprintf(get_cur_genbuf(), GENBUF_SZ, "#%s", sddevtab.name);
			devdir(c, q, get_cur_genbuf(), 0, eve.name, 0555, dp);
			return 1;
		}

		if (s + Qtopbase < Qunitdir)
			return sd1gen(c, s + Qtopbase, dp);
		s -= (Qunitdir - Qtopbase);

		qlock(&devslock);
		for (i = 0; i < ARRAY_SIZE(devs); i++) {
			if (devs[i]) {
				if (s < devs[i]->nunit)
					break;
				s -= devs[i]->nunit;
			}
		}

		if (i == ARRAY_SIZE(devs)) {
			/* Run off the end of the list */
			qunlock(&devslock);
			return -1;
		}

		sdev = devs[i];
		if (sdev == NULL) {
			qunlock(&devslock);
			return 0;
		}

		kref_get(&sdev->r, 1);
		qunlock(&devslock);

		unit = sdev->unit[s];
		if (unit == NULL)
			unit = sdgetunit(sdev, s);
		if (unit == NULL) {
			kref_put(&sdev->r);
			return 0;
		}

		mkqid(&q, QID(sdev->idno, s, 0, Qunitdir), 0, QTDIR);
		if (emptystr(unit->sdperm.user))
			kstrdup(&unit->sdperm.user, eve.name);
		devdir(c, q, unit->sdperm.name, 0, unit->sdperm.user, unit->sdperm.perm,
		       dp);
		kref_put(&sdev->r);
		return 1;

	case Qunitdir:
		if (s == DEVDOTDOT) {
			mkqid(&q, QID(0, 0, 0, Qtopdir), 0, QTDIR);
			snprintf(get_cur_genbuf(), GENBUF_SZ, "#%s", sddevtab.name);
			devdir(c, q, get_cur_genbuf(), 0, eve.name, 0555, dp);
			return 1;
		}

		sdev = sdgetdev(DEV(c->qid));
		if (sdev == NULL) {
			devdir(c, c->qid, "unavailable", 0, eve.name, 0, dp);
			return 1;
		}

		unit = sdev->unit[UNIT(c->qid)];
		qlock(&unit->ctl);

		/*
		 * Check for media change.
		 * If one has already been detected, sectors will be zero.
		 * If there is one waiting to be detected, online
		 * will return > 1.
		 * Online is a bit of a large hammer but does the job.
		 */
		if (unit->sectors == 0 ||
		    (unit->dev->ifc->online && unit->dev->ifc->online(unit) > 1))
			sdinitpart(unit);

		i = s + Qunitbase;
		if (i < Qpart) {
			r = sd2gen(c, i, dp);
			qunlock(&unit->ctl);
			kref_put(&sdev->r);
			return r;
		}
		i -= Qpart;
		if (unit->part == NULL || i >= unit->npart) {
			qunlock(&unit->ctl);
			kref_put(&sdev->r);
			break;
		}
		pp = &unit->part[i];
		if (!pp->valid) {
			qunlock(&unit->ctl);
			kref_put(&sdev->r);
			return 0;
		}
		l = (pp->end - pp->start) * (int64_t)unit->secsize;
		mkqid(&q, QID(DEV(c->qid), UNIT(c->qid), i, Qpart),
		      unit->vers + pp->vers, QTFILE);
		if (emptystr(pp->sdperm.user))
			kstrdup(&pp->sdperm.user, eve.name);
		devdir(c, q, pp->sdperm.name, l, pp->sdperm.user, pp->sdperm.perm, dp);
		qunlock(&unit->ctl);
		kref_put(&sdev->r);
		return 1;
	case Qraw:
	case Qctl:
	case Qpart:
		sdev = sdgetdev(DEV(c->qid));
		if (sdev == NULL) {
			devdir(c, q, "unavailable", 0, eve.name, 0, dp);
			return 1;
		}
		unit = sdev->unit[UNIT(c->qid)];
		qlock(&unit->ctl);
		r = sd2gen(c, TYPE(c->qid), dp);
		qunlock(&unit->ctl);
		kref_put(&sdev->r);
		return r;
	case Qtopctl:
		return sd1gen(c, TYPE(c->qid), dp);
	default:
		break;
	}

	return -1;
}

static struct chan *sdattach(char *spec)
{
	struct chan *c;
	char *p;
	struct sdev *sdev;
	int idno, subno;

	if (*spec == '\0') {
		c = devattach(sddevtab.name, spec);
		mkqid(&c->qid, QID(0, 0, 0, Qtopdir), 0, QTDIR);
		return c;
	}

	if (spec[0] != 's' || spec[1] != 'd')
		error(EINVAL, "First two characters of spec must be 'sd', not %c%c",
		      spec[0], spec[1]);
	idno = spec[2];
	subno = strtol(&spec[3], &p, 0);
	if (p == &spec[3])
		error(EINVAL, "subno '%s' is not a number", &spec[3]);

	sdev = sdgetdev(idno);
	if (sdev == NULL)
		error(ENOENT, "No such unit %d", idno);
	if (sdgetunit(sdev, subno) == NULL) {
		kref_put(&sdev->r);
		error(ENOENT, "No such subno %d", subno);
	}

	c = devattach(sddevtab.name, spec);
	mkqid(&c->qid, QID(sdev->idno, subno, 0, Qunitdir), 0, QTDIR);
	c->dev = (sdev->idno << UnitLOG) + subno;
	kref_put(&sdev->r);
	return c;
}

static struct walkqid *sdwalk(struct chan *c, struct chan *nc, char **name,
                              unsigned int nname)
{
	return devwalk(c, nc, name, nname, NULL, 0, sdgen);
}

static size_t sdstat(struct chan *c, uint8_t *db, size_t n)
{
	return devstat(c, db, n, NULL, 0, sdgen);
}

static struct chan *sdopen(struct chan *c, int omode)
{
	ERRSTACK(1);
	struct sdpart *pp;
	struct sdunit *unit;
	struct sdev *sdev;
	uint8_t tp;

	c = devopen(c, omode, 0, 0, sdgen);
	if ((tp = TYPE(c->qid)) != Qctl && tp != Qraw && tp != Qpart)
		return c;

	sdev = sdgetdev(DEV(c->qid));
	if (sdev == NULL)
		error(ENOENT, "No such device");

	unit = sdev->unit[UNIT(c->qid)];

	switch (TYPE(c->qid)) {
	case Qctl:
		c->qid.vers = unit->vers;
		break;
	case Qraw:
		c->qid.vers = unit->vers;
		if (test_and_set_bit(0, (unsigned long *)&unit->rawinuse) !=
		    0) {
			c->flag &= ~COPEN;
			kref_put(&sdev->r);
			error(EBUSY, "In use");
		}
		unit->state = Rawcmd;
		break;
	case Qpart:
		qlock(&unit->ctl);
		if (waserror()) {
			qunlock(&unit->ctl);
			c->flag &= ~COPEN;
			kref_put(&sdev->r);
			nexterror();
		}
		pp = &unit->part[PART(c->qid)];
		c->qid.vers = unit->vers + pp->vers;
		qunlock(&unit->ctl);
		poperror();
		break;
	}
	kref_put(&sdev->r);
	return c;
}

static void sdclose(struct chan *c)
{
	struct sdunit *unit;
	struct sdev *sdev;

	if (c->qid.type & QTDIR)
		return;
	if (!(c->flag & COPEN))
		return;

	switch (TYPE(c->qid)) {
	default:
		break;
	case Qraw:
		sdev = sdgetdev(DEV(c->qid));
		if (sdev) {
			unit = sdev->unit[UNIT(c->qid)];
			unit->rawinuse = 0;
			kref_put(&sdev->r);
		}
		break;
	}
}

static size_t sdbio(struct chan *c, int write, char *a, size_t len,
                    off64_t off)
{
	ERRSTACK(2);
	int nchange;
	uint8_t *b;
	struct sdpart *pp;
	struct sdunit *unit;
	struct sdev *sdev;
	int64_t bno;
	size_t l, max, nb, offset;

	sdev = sdgetdev(DEV(c->qid));
	if (sdev == NULL) {
		kref_put(&sdev->r);
		error(ENOENT, "No such file or directory");
	}
	unit = sdev->unit[UNIT(c->qid)];
	if (unit == NULL)
		error(ENOENT, "No such file or directory");

	nchange = 0;
	qlock(&unit->ctl);
	while (waserror()) {
		/* notification of media change; go around again */
		/* Meta-comment: I'm leaving commented-out code in place,
		 * which originally contained a strcmp of the error string to
		 * a value, to remind us: plan 9 is a distributed system. It's
		 * possible in principle to have the storage device on this
		 * machine use an sdi{ata,ahci} on another machine, and it all
		 * works. Nobody is going to do that, now, so get_errno() it is.
		 * if (strcmp(up->errstr, Eio) == 0 ... */
		if ((get_errno() == EIO) && (unit->sectors == 0) && (nchange++ == 0)) {
			sdinitpart(unit);
			poperror();
			continue;
		}

		/* other errors; give up */
		qunlock(&unit->ctl);
		kref_put(&sdev->r);
		nexterror();
	}
	pp = &unit->part[PART(c->qid)];
	if (unit->vers + pp->vers != c->qid.vers)
		error(EIO, "disk changed");

	/*
	 * Check the request is within bounds.
	 * Removeable drives are locked throughout the I/O
	 * in case the media changes unexpectedly.
	 * Non-removeable drives are not locked during the I/O
	 * to allow the hardware to optimise if it can; this is
	 * a little fast and loose.
	 * It's assumed that non-removeable media parameters
	 * (sectors, secsize) can't change once the drive has
	 * been brought online.
	 */
	bno = (off / unit->secsize) + pp->start;
	nb = ((off + len + unit->secsize - 1) / unit->secsize) + pp->start - bno;
	max = SDmaxio / unit->secsize;
	if (nb > max)
		nb = max;
	if (bno + nb > pp->end)
		nb = pp->end - bno;
	if (bno >= pp->end || nb == 0) {
		if (write)
			error(EIO, "bno(%d) >= pp->end(%d) or nb(%d) == 0", bno, pp->end,
			      nb);
		qunlock(&unit->ctl);
		kref_put(&sdev->r);
		poperror();
		return 0;
	}
	if (!(unit->inquiry[1] & SDinq1removable)) {
		qunlock(&unit->ctl);
		poperror();
	}

	b = kzmalloc(nb * unit->secsize, MEM_WAIT);
	if (b == NULL)
		error(ENOMEM, "%s: could not allocate %d bytes", nb * unit->secsize);
	if (waserror()) {
		kfree(b);
		if (!(unit->inquiry[1] & SDinq1removable))
			kref_put(&sdev->r); /* gadverdamme! */
		nexterror();
	}

	offset = off % unit->secsize;
	if (offset + len > nb * unit->secsize)
		len = nb * unit->secsize - offset;
	if (write) {
		if (offset || (len % unit->secsize)) {
			l = unit->dev->ifc->bio(unit, 0, 0, b, nb, bno);
			if (l < 0)
				error(EIO, "IO Error");
			if (l < (nb * unit->secsize)) {
				nb = l / unit->secsize;
				l = nb * unit->secsize - offset;
				if (len > l)
					len = l;
			}
		}
		memmove(b + offset, a, len);
		l = unit->dev->ifc->bio(unit, 0, 1, b, nb, bno);
		if (l < 0)
			error(EIO, "IO Error");
		if (l < offset)
			len = 0;
		else if (len > l - offset)
			len = l - offset;
	} else {
		l = unit->dev->ifc->bio(unit, 0, 0, b, nb, bno);
		if (l < 0)
			error(EIO, "IO Error");
		if (l < offset)
			len = 0;
		else if (len > l - offset)
			len = l - offset;
		memmove(a, b + offset, len);
	}
	kfree(b);
	poperror();

	if (unit->inquiry[1] & SDinq1removable) {
		qunlock(&unit->ctl);
		poperror();
	}

	kref_put(&sdev->r);
	return len;
}

static size_t sdrio(struct sdreq *r, void *a, size_t n)
{
	ERRSTACK(1);
	void *data;

	if (n >= SDmaxio || n < 0)
		error(EINVAL, "%d is < 0 or > SDmaxio", n);

	data = NULL;
	if (n) {
		data = kzmalloc(n, MEM_WAIT);
		if (data == NULL)
			error(ENOMEM, "Alloc of %d bytes failed", n);
		if (r->write)
			memmove(data, a, n);
	}
	r->data = data;
	r->dlen = n;

	if (waserror()) {
		kfree(data);
		r->data = NULL;
		nexterror();
	}

	if (r->unit->dev->ifc->rio(r) != SDok)
		error(EIO, "IO Error");

	if (!r->write && r->rlen > 0)
		memmove(a, data, r->rlen);
	kfree(data);
	r->data = NULL;
	poperror();

	return r->rlen;
}

/*
 * SCSI simulation for non-SCSI devices
 */
int sdsetsense(struct sdreq *r, int status, int key, int asc, int ascq)
{
	int len;
	struct sdunit *unit;

	unit = r->unit;
	unit->sense[2] = key;
	unit->sense[12] = asc;
	unit->sense[13] = ascq;

	r->status = status;
	if (status == SDcheck && !(r->flags & SDnosense)) {
		/* request sense case from sdfakescsi */
		len = sizeof unit->sense;
		if (len > sizeof(r->sense) - 1)
			len = sizeof(r->sense) - 1;
		memmove(r->sense, unit->sense, len);
		unit->sense[2] = 0;
		unit->sense[12] = 0;
		unit->sense[13] = 0;
		r->flags |= SDvalidsense;
		return SDok;
	}
	return status;
}

int sdmodesense(struct sdreq *r, uint8_t *cmd, void *info, int ilen)
{
	int len;
	uint8_t *data;

	/*
	 * Fake a vendor-specific request with page code 0,
	 * return the drive info.
	 */
	if ((cmd[2] & 0x3F) != 0 && (cmd[2] & 0x3F) != 0x3F)
		return sdsetsense(r, SDcheck, 0x05, 0x24, 0);
	len = (cmd[7] << 8) | cmd[8];
	if (len == 0)
		return SDok;
	if (len < 8 + ilen)
		return sdsetsense(r, SDcheck, 0x05, 0x1A, 0);
	if (r->data == NULL || r->dlen < len)
		return sdsetsense(r, SDcheck, 0x05, 0x20, 1);
	data = r->data;
	memset(data, 0, 8);
	data[0] = ilen >> 8;
	data[1] = ilen;
	if (ilen)
		memmove(data + 8, info, ilen);
	r->rlen = 8 + ilen;
	return sdsetsense(r, SDok, 0, 0, 0);
}

int sdfakescsi(struct sdreq *r, void *info, int ilen)
{
	uint8_t *cmd, *p;
	uint64_t len;
	struct sdunit *unit;

	cmd = r->cmd;
	r->rlen = 0;
	unit = r->unit;

	/*
	 * Rewrite read(6)/write(6) into read(10)/write(10).
	 */
	switch (cmd[0]) {
	case 0x08: /* read */
	case 0x0A: /* write */
		cmd[9] = 0;
		cmd[8] = cmd[4];
		cmd[7] = 0;
		cmd[6] = 0;
		cmd[5] = cmd[3];
		cmd[4] = cmd[2];
		cmd[3] = cmd[1] & 0x0F;
		cmd[2] = 0;
		cmd[1] &= 0xE0;
		cmd[0] |= 0x20;
		break;
	}

	/*
	 * Map SCSI commands into ATA commands for discs.
	 * Fail any command with a LUN except INQUIRY which
	 * will return 'logical unit not supported'.
	 */
	if ((cmd[1] >> 5) && cmd[0] != 0x12)
		return sdsetsense(r, SDcheck, 0x05, 0x25, 0);

	switch (cmd[0]) {
	default:
		return sdsetsense(r, SDcheck, 0x05, 0x20, 0);

	case 0x00: /* test unit ready */
		return sdsetsense(r, SDok, 0, 0, 0);

	case 0x03: /* request sense */
		if (cmd[4] < sizeof unit->sense)
			len = cmd[4];
		else
			len = sizeof unit->sense;
		if (r->data && r->dlen >= len) {
			memmove(r->data, unit->sense, len);
			r->rlen = len;
		}
		return sdsetsense(r, SDok, 0, 0, 0);

	case 0x12: /* inquiry */
		if (cmd[4] < sizeof unit->inquiry)
			len = cmd[4];
		else
			len = sizeof unit->inquiry;
		if (r->data && r->dlen >= len) {
			memmove(r->data, unit->inquiry, len);
			r->rlen = len;
		}
		return sdsetsense(r, SDok, 0, 0, 0);

	case 0x1B: /* start/stop unit */
		/*
		 * nop for now, can use power management later.
		 */
		return sdsetsense(r, SDok, 0, 0, 0);

	case 0x25: /* read capacity */
		if ((cmd[1] & 0x01) || cmd[2] || cmd[3])
			return sdsetsense(r, SDcheck, 0x05, 0x24, 0);
		if (r->data == NULL || r->dlen < 8)
			return sdsetsense(r, SDcheck, 0x05, 0x20, 1);

		/*
		 * Read capacity returns the LBA of the last sector.
		 */
		len = unit->sectors - 1;
		p = r->data;
		*p++ = len >> 24;
		*p++ = len >> 16;
		*p++ = len >> 8;
		*p++ = len;
		len = 512;
		*p++ = len >> 24;
		*p++ = len >> 16;
		*p++ = len >> 8;
		*p++ = len;
		r->rlen = p - (uint8_t *)r->data;
		return sdsetsense(r, SDok, 0, 0, 0);

	case 0x9E: /* long read capacity */
		if ((cmd[1] & 0x01) || cmd[2] || cmd[3])
			return sdsetsense(r, SDcheck, 0x05, 0x24, 0);
		if (r->data == NULL || r->dlen < 8)
			return sdsetsense(r, SDcheck, 0x05, 0x20, 1);
		/*
		 * Read capcity returns the LBA of the last sector.
		 */
		len = unit->sectors - 1;
		p = r->data;
		*p++ = len >> 56;
		*p++ = len >> 48;
		*p++ = len >> 40;
		*p++ = len >> 32;
		*p++ = len >> 24;
		*p++ = len >> 16;
		*p++ = len >> 8;
		*p++ = len;
		len = 512;
		*p++ = len >> 24;
		*p++ = len >> 16;
		*p++ = len >> 8;
		*p++ = len;
		r->rlen = p - (uint8_t *)r->data;
		return sdsetsense(r, SDok, 0, 0, 0);

	case 0x5A: /* mode sense */
		return sdmodesense(r, cmd, info, ilen);

	case 0x28: /* read */
	case 0x2A: /* write */
	case 0x88: /* read16 */
	case 0x8a: /* write16 */
		return SDnostatus;
	}
}

static size_t sdread(struct chan *c, void *a, size_t n, off64_t off)
{
	ERRSTACK(1);
	char *p, *e, *buf;
	struct sdpart *pp;
	struct sdunit *unit;
	struct sdev *sdev;
	off64_t offset;
	int i, l, mm, status;

	offset = off;
	switch (TYPE(c->qid)) {
	default:
		error(EPERM, "Permission denied");
	case Qtopctl:
		mm = 64 * 1024; /* room for register dumps */
		p = buf = kzmalloc(mm, 0);
		if (p == NULL)
			error(ENOMEM, "Alloc of %d bytes failed", mm);
		e = p + mm;
		qlock(&devslock);
		for (i = 0; i < ARRAY_SIZE(devs); i++) {
			sdev = devs[i];
			if (sdev && sdev->ifc->rtopctl)
				p = sdev->ifc->rtopctl(sdev, p, e);
		}
		qunlock(&devslock);
		n = readstr(offset, a, n, buf);
		kfree(buf);
		return n;

	case Qtopdir:
	case Qunitdir:
		return devdirread(c, a, n, 0, 0, sdgen);

	case Qctl:
		sdev = sdgetdev(DEV(c->qid));
		if (sdev == NULL)
			error(ENOENT, "No such device");

		unit = sdev->unit[UNIT(c->qid)];
		mm = 16 * 1024; /* room for register dumps */
		p = kzmalloc(mm, 0);
		if (p == NULL)
			error(ENOMEM, "Alloc of %d bytes failed", mm);
		l = snprintf(p, mm, "inquiry %.48s\n", (char *)unit->inquiry + 8);
		qlock(&unit->ctl);
		/*
		 * If there's a device specific routine it must
		 * provide all information pertaining to night geometry
		 * and the garscadden trains.
		 */
		if (unit->dev->ifc->rctl)
			l += unit->dev->ifc->rctl(unit, p + l, mm - l);
		if (unit->sectors == 0)
			sdinitpart(unit);
		if (unit->sectors) {
			if (unit->dev->ifc->rctl == NULL)
				l += snprintf(p + l, mm - l, "geometry %llu %lu\n",
				              unit->sectors, unit->secsize);
			pp = unit->part;
			for (i = 0; i < unit->npart; i++) {
				if (pp->valid)
					l += snprintf(p + l, mm - l, "part %s %llu %llu\n",
					              pp->sdperm.name, pp->start, pp->end);
				pp++;
			}
		}
		qunlock(&unit->ctl);
		kref_put(&sdev->r);
		l = readstr(offset, a, n, p);
		kfree(p);
		return l;

	case Qraw:
		sdev = sdgetdev(DEV(c->qid));
		if (sdev == NULL)
			error(ENOENT, "No such file or directory");

		unit = sdev->unit[UNIT(c->qid)];
		qlock(&unit->raw);
		if (waserror()) {
			qunlock(&unit->raw);
			kref_put(&sdev->r);
			nexterror();
		}
		if (unit->state == Rawdata) {
			unit->state = Rawstatus;
			n = sdrio(unit->req, a, n);
		} else if (unit->state == Rawstatus) {
			status = unit->req->status;
			unit->state = Rawcmd;
			kfree(unit->req);
			unit->req = NULL;
			n = readnum(0, a, n, status, NUMSIZE);
		} else
			n = 0;
		qunlock(&unit->raw);
		kref_put(&sdev->r);
		poperror();
		return n;

	case Qpart:
		return sdbio(c, 0, a, n, off);
	}
}

static void legacytopctl(struct cmdbuf *);

static size_t sdwrite(struct chan *c, void *a, size_t n, off64_t off)
{
	ERRSTACK(2);
	char *f0;
	int i;
	uint64_t end, start;
	struct cmdbuf *cb;
	struct sdifc *ifc;
	struct sdreq *req;
	struct sdunit *unit;
	struct sdev *sdev;

	switch (TYPE(c->qid)) {
	default:
		error(EPERM, "Permission denied");
	case Qtopctl:
		cb = parsecmd(a, n);
		if (waserror()) {
			kfree(cb);
			nexterror();
		}
		if (cb->nf == 0)
			error(EINVAL, "empty control message");
		f0 = cb->f[0];
		cb->f++;
		cb->nf--;
		if (strcmp(f0, "config") == 0) {
			/* wormhole into ugly legacy interface */
			legacytopctl(cb);
			poperror();
			kfree(cb);
			break;
		}
		/*
		 * "ata arg..." invokes sdifc[i]->wtopctl(NULL, cb),
		 * where sdifc[i]->sdperm.name=="ata" and cb contains the args.
		 */
		ifc = NULL;
		sdev = NULL;
		for (i = 0; sdifc[i]; i++) {
			if (strcmp(sdifc[i]->name, f0) == 0) {
				ifc = sdifc[i];
				sdev = NULL;
				goto subtopctl;
			}
		}
		/*
		 * "sd1 arg..." invokes sdifc[i]->wtopctl(sdev, cb),
		 * where sdifc[i] and sdev match controller letter "1",
		 * and cb contains the args.
		 */
		if (f0[0] == 's' && f0[1] == 'd' && f0[2] && f0[3] == 0) {
			sdev = sdgetdev(f0[2]);
			if (sdev != NULL) {
				ifc = sdev->ifc;
				goto subtopctl;
			}
		}
		error(EINVAL, "unknown interface");

	subtopctl:
		if (waserror()) {
			if (sdev)
				kref_put(&sdev->r);
			nexterror();
		}
		if (ifc->wtopctl)
			ifc->wtopctl(sdev, cb);
		else
			error(EINVAL, "Bad control");
		poperror();
		poperror();
		if (sdev)
			kref_put(&sdev->r);
		kfree(cb);
		break;

	case Qctl:
		cb = parsecmd(a, n);
		sdev = sdgetdev(DEV(c->qid));
		if (sdev == NULL)
			error(ENOENT, "No such file or directory");
		unit = sdev->unit[UNIT(c->qid)];

		qlock(&unit->ctl);
		if (waserror()) {
			qunlock(&unit->ctl);
			kref_put(&sdev->r);
			kfree(cb);
			nexterror();
		}
		if (unit->vers != c->qid.vers)
			error(EIO, "Unit changed");

		if (cb->nf < 1)
			error(EINVAL, "%s requires at least one argument", cb->f[0]);
		if (strcmp(cb->f[0], "part") == 0) {
			if (cb->nf != 4)
				error(EINVAL, "Part got %d arguments, requires 4", cb->nf);
			if (unit->sectors == 0)
				error(EINVAL, "unit->sectors was 0");
			if (!sdinitpart(unit))
				error(EIO, "sdinitpart failed");
			start = strtoul(cb->f[2], 0, 0);
			end = strtoul(cb->f[3], 0, 0);
			sdaddpart(unit, cb->f[1], start, end);
		} else if (strcmp(cb->f[0], "delpart") == 0) {
			if (cb->nf != 2)
				error(EINVAL, "delpart got %d args, 2 required");
			if (unit->part == NULL)
				error(EIO, "partition was NULL");
			sddelpart(unit, cb->f[1]);
		} else if (unit->dev->ifc->wctl)
			unit->dev->ifc->wctl(unit, cb);
		else
			error(EINVAL, "Bad control %s", cb->f[0]);
		qunlock(&unit->ctl);
		kref_put(&sdev->r);
		poperror();
		kfree(cb);
		break;

	case Qraw:
		sdev = sdgetdev(DEV(c->qid));
		if (sdev == NULL)
			error(ENOENT, "No such file or directory");
		unit = sdev->unit[UNIT(c->qid)];
		qlock(&unit->raw);
		if (waserror()) {
			qunlock(&unit->raw);
			kref_put(&sdev->r);
			nexterror();
		}
		switch (unit->state) {
		case Rawcmd:
			if (n < 6 || n > sizeof(req->cmd))
				error(EINVAL, "%d is < 6 or > %d", n, sizeof(req->cmd));
			req = kzmalloc(sizeof(struct sdreq), 0);
			if (req == NULL)
				error(ENOMEM, "Can't allocate an sdreq");
			req->unit = unit;
			memmove(req->cmd, a, n);
			req->clen = n;
			req->flags = SDnosense;
			req->status = ~0;

			unit->req = req;
			unit->state = Rawdata;
			break;

		case Rawstatus:
			unit->state = Rawcmd;
			kfree(unit->req);
			unit->req = NULL;
			error(EINVAL, "Bad use of rawstatus");

		case Rawdata:
			unit->state = Rawstatus;
			unit->req->write = 1;
			n = sdrio(unit->req, a, n);
		}
		qunlock(&unit->raw);
		kref_put(&sdev->r);
		poperror();
		break;
	case Qpart:
		return sdbio(c, 1, a, n, off);
	}

	return n;
}

static size_t sdwstat(struct chan *c, uint8_t *dp, size_t n)
{
	ERRSTACK(2);
	struct dir *d;
	struct sdpart *pp;
	struct sdperm *perm;
	struct sdunit *unit;
	struct sdev *sdev;

	if (c->qid.type & QTDIR)
		error(EPERM, "Not a directory");

	sdev = sdgetdev(DEV(c->qid));
	if (sdev == NULL)
		error(ENOENT, "No such file or device");
	unit = sdev->unit[UNIT(c->qid)];
	qlock(&unit->ctl);
	d = NULL;
	if (waserror()) {
		kfree(d);
		qunlock(&unit->ctl);
		kref_put(&sdev->r);
		nexterror();
	}

	switch (TYPE(c->qid)) {
	default:
		error(EPERM, "Permission denied");
	case Qctl:
		perm = &unit->ctlperm;
		break;
	case Qraw:
		perm = &unit->rawperm;
		break;
	case Qpart:
		pp = &unit->part[PART(c->qid)];
		if (unit->vers + pp->vers != c->qid.vers)
			error(ENOENT, "No such file or directory");
		perm = &pp->sdperm;
		break;
	}

	/* TODO: Implement permissions checking and raise errors as appropriate. */
	// if (strcmp(current->user.name, perm->user) && !iseve())
		// error(Eperm);

	d = kzmalloc(sizeof(struct dir) + n, 0);
	n = convM2D(dp, n, &d[0], (char *)&d[1]);
	if (n == 0)
		error(EIO, "Short status");
	if (!emptystr(d[0].uid))
		kstrdup(&perm->user, d[0].uid);
	if (d[0].mode != -1)
		perm->perm = (perm->perm & ~0777) | (d[0].mode & 0777);

	kfree(d);
	qunlock(&unit->ctl);
	kref_put(&sdev->r);
	poperror();
	return n;
}

static int configure(char *spec, struct devconf *cf)
{
	struct sdev *s, *sdev;
	char *p;
	int i;

	if (sdindex(*spec) < 0)
		error(EINVAL, "bad sd spec '%s'", spec);

	p = strchr(cf->type, '/');
	if (p != NULL)
		*p++ = '\0';

	for (i = 0; sdifc[i] != NULL; i++)
		if (strcmp(sdifc[i]->name, cf->type) == 0)
			break;
	if (sdifc[i] == NULL)
		error(ENOENT, "sd type not found");
	if (p)
		*(p - 1) = '/';

	if (sdifc[i]->probe == NULL)
		error(EIO, "sd type cannot probe");

	sdev = sdifc[i]->probe(cf);
	for (s = sdev; s; s = s->next)
		s->idno = *spec;
	sdadddevs(sdev);
	return 0;
}

static int unconfigure(char *spec)
{
	int i;
	struct sdev *sdev;
	struct sdunit *unit;

	if ((i = sdindex(*spec)) < 0)
		error(ENOENT, "No such file or directory '%s'", spec);

	qlock(&devslock);
	sdev = devs[i];
	if (sdev == NULL) {
		qunlock(&devslock);
		error(ENOENT, "No such file or directory at index %d", i);
	}
	if (kref_refcnt(&sdev->r)) {
		qunlock(&devslock);
		error(EBUSY, "%s is busy", spec);
	}
	devs[i] = NULL;
	qunlock(&devslock);

	/* make sure no interrupts arrive anymore before removing resources */
	if (sdev->enabled && sdev->ifc->disable)
		sdev->ifc->disable(sdev);

	for (i = 0; i != sdev->nunit; i++) {
		unit = sdev->unit[i];
		if (unit) {
			kfree(unit->sdperm.name);
			kfree(unit->sdperm.user);
			kfree(unit);
		}
	}

	if (sdev->ifc->clear)
		sdev->ifc->clear(sdev);
	kfree(sdev);
	return 0;
}

static int sdconfig(int on, char *spec, struct devconf *cf)
{
	if (on)
		return configure(spec, cf);
	return unconfigure(spec);
}

struct dev sddevtab __devtab = {
    .name = "sd",

    .reset = sdreset,
    .init = devinit,
    .shutdown = devshutdown,
    .attach = sdattach,
    .walk = sdwalk,
    .stat = sdstat,
    .open = sdopen,
    .create = devcreate,
    .close = sdclose,
    .read = sdread,
    .bread = devbread,
    .write = sdwrite,
    .bwrite = devbwrite,
    .remove = devremove,
    .wstat = sdwstat,
    .power = devpower,
};

/*
 * This is wrong for so many reasons.  This code must go.
 */
struct confdata {
	int on;
	char *spec;
	struct devconf cf;
};

static void parseswitch(struct confdata *cd, char *option)
{
	if (!strcmp("on", option))
		cd->on = 1;
	else if (!strcmp("off", option))
		cd->on = 0;
	else
		error(EINVAL, "Got %s, must be on or off", option);
}

static void parsespec(struct confdata *cd, char *option)
{
	if (strlen(option) > 1)
		error(EINVAL, "spec is %d bytes, must be 1", strlen(option));
	cd->spec = option;
}

static struct devport *getnewport(struct devconf *dc)
{
	struct devport *p;

	p = (struct devport *)kzmalloc((dc->nports + 1) * sizeof(struct devport),
	                               0);
	if (p == NULL)
		error(ENOMEM, "Can't allocate %d bytes for %d ports", dc->nports,
		      (dc->nports + 1) * sizeof(struct devport));
	if (dc->nports > 0) {
		memmove(p, dc->ports, dc->nports * sizeof(struct devport));
		kfree(dc->ports);
	}
	dc->ports = p;
	p = &dc->ports[dc->nports++];
	p->size = -1;
	p->port = (uint32_t)-1;
	return p;
}

static void parseport(struct confdata *cd, char *option)
{
	char *e;
	struct devport *p;

	if ((cd->cf.nports == 0) ||
	    (cd->cf.ports[cd->cf.nports - 1].port != (uint32_t)-1))
		p = getnewport(&cd->cf);
	else
		p = &cd->cf.ports[cd->cf.nports - 1];
	p->port = strtol(option, &e, 0);
	if (e == NULL || *e != '\0')
		error(EINVAL, "option %s is not a number", option);
}

static void parsesize(struct confdata *cd, char *option)
{
	char *e;
	struct devport *p;

	if (cd->cf.nports == 0 || cd->cf.ports[cd->cf.nports - 1].size != -1)
		p = getnewport(&cd->cf);
	else
		p = &cd->cf.ports[cd->cf.nports - 1];
	p->size = (int)strtol(option, &e, 0);
	if (e == NULL || *e != '\0')
		error(EINVAL, "%s is not a number", option);
}

static void parseirq(struct confdata *cd, char *option)
{
	char *e;

	cd->cf.intnum = strtoul(option, &e, 0);
	if (e == NULL || *e != '\0')
		error(EINVAL, "%s is not a number", option);
}

static void parsetype(struct confdata *cd, char *option)
{
	cd->cf.type = option;
}

static struct {
	char *name;
	void (*parse)(struct confdata *, char *unused_char_p_t);
} options[] = {
    {"switch", parseswitch},
    {"spec", parsespec},
    {"port", parseport},
    {"size", parsesize},
    {"irq", parseirq},
    {"type", parsetype},
};

static void legacytopctl(struct cmdbuf *cb)
{
	char *opt;
	int i, j;
	struct confdata cd;

	memset(&cd, 0, sizeof(cd));
	cd.on = -1;
	for (i = 0; i < cb->nf; i += 2) {
		if (i + 2 > cb->nf)
			error(EINVAL, "FIX ME. I don't know what this means");
		opt = cb->f[i];
		for (j = 0; j < ARRAY_SIZE(options); j++)
			if (strcmp(opt, options[j].name) == 0) {
				options[j].parse(&cd, cb->f[i + 1]);
				break;
			}
		if (j == ARRAY_SIZE(options))
			error(EINVAL, "FIX ME");
	}
	/* this has been rewritten to accommodate sdaoe */
	if (cd.on < 0 || cd.spec == 0)
		error(EINVAL, "cd.on(%d) < 0 or cd.spec == 0", cd.on);
	if (cd.on && cd.cf.type == NULL)
		error(EINVAL, "cd.on non-zero and cd.cf.type == NULL");
	sdconfig(cd.on, cd.spec, &cd.cf);
}
