/*
 * 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 <vfs.h>

#include <assert.h>
#include <cpio.h>
#include <error.h>
#include <ip.h>
#include <kfs.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,
                              int nname)
{
	return devwalk(c, nc, name, nname, NULL, 0, sdgen);
}

static int32_t sdstat(struct chan *c, uint8_t *db, int32_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 int32_t sdbio(struct chan *c, int write, char *a, int32_t len,
                     int64_t off)
{
	ERRSTACK(2);
	int nchange;
	uint8_t *b;
	struct sdpart *pp;
	struct sdunit *unit;
	struct sdev *sdev;
	int64_t bno;
	int32_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 int32_t sdrio(struct sdreq *r, void *a, int32_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 long sdread(struct chan *c, void *a, long n, int64_t off)
{
	ERRSTACK(1);
	char *p, *e, *buf;
	struct sdpart *pp;
	struct sdunit *unit;
	struct sdev *sdev;
	int32_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;
			i = sdrio(unit->req, a, n);
		} else if (unit->state == Rawstatus) {
			status = unit->req->status;
			unit->state = Rawcmd;
			kfree(unit->req);
			unit->req = NULL;
			i = readnum(0, a, n, status, NUMSIZE);
		} else
			i = 0;
		qunlock(&unit->raw);
		kref_put(&sdev->r);
		poperror();
		return i;

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

static void legacytopctl(struct cmdbuf *);

static long sdwrite(struct chan *c, void *a, long n, int64_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 int32_t sdwstat(struct chan *c, uint8_t *dp, int32_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 != (uint32_t)~0UL)
		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);
}
