/*
 * 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 <net/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 != -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);
}
