blob: 5d92116c1f7e8ffcfa4ef0892042f90cf718b71a [file] [log] [blame]
/* Copyright (c) 2020 Google Inc
* Barret Rhoden <brho@cs.berkeley.edu>
* See LICENSE for details.
*
* #template. Dummy device with a devdir table.
*/
#include <ns.h>
#include <kmalloc.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <error.h>
struct dev template_devtab;
static char *devname(void)
{
return template_devtab.name;
}
enum {
Qdir,
Qctl,
};
static struct dirtab XXX_dir[] = {
{".", {Qdir, 0, QTDIR}, 0, DMDIR | 0555},
{"ctl", {Qctl, 0, QTFILE}, 0, 0666},
};
static struct chan *XXX_attach(char *spec)
{
return devattach(devname(), spec);
}
static struct walkqid *XXX_walk(struct chan *c, struct chan *nc, char **name,
unsigned int nname)
{
return devwalk(c, nc, name, nname, XXX_dir, ARRAY_SIZE(XXX_dir),
devgen);
}
static size_t XXX_stat(struct chan *c, uint8_t *db, size_t n)
{
return devstat(c, db, n, XXX_dir, ARRAY_SIZE(XXX_dir), devgen);
}
static struct chan *XXX_open(struct chan *c, int omode)
{
return devopen(c, omode, XXX_dir, ARRAY_SIZE(XXX_dir), devgen);
}
static void XXX_close(struct chan *c)
{
/* If you do anything after open, only undo it for COPEN chans */
if (!(c->flag & COPEN))
return;
}
static size_t XXX_read(struct chan *c, void *ubuf, size_t n, off64_t offset)
{
switch (c->qid.path) {
case Qdir:
return devdirread(c, ubuf, n, XXX_dir, ARRAY_SIZE(XXX_dir),
devgen);
case Qctl:
return readstr(offset, ubuf, n, "XXX");
default:
panic("Bad Qid %p!", c->qid.path);
}
return -1;
}
#define XXX_CTL_USAGE "start|stop|print|reset"
static void XXX_ctl_cmd(struct chan *c, struct cmdbuf *cb)
{
ERRSTACK(1);
if (cb->nf < 1)
error(EFAIL, XXX_CTL_USAGE);
if (waserror()) {
nexterror();
}
if (!strcmp(cb->f[0], "start")) {
;
} else if (!strcmp(cb->f[0], "stop")) {
;
} else if (!strcmp(cb->f[0], "print")) {
;
} else if (!strcmp(cb->f[0], "reset")) {
;
} else {
error(EFAIL, XXX_CTL_USAGE);
}
poperror();
}
static size_t XXX_write(struct chan *c, void *ubuf, size_t n, off64_t unused)
{
ERRSTACK(1);
struct cmdbuf *cb = parsecmd(ubuf, n);
if (waserror()) {
kfree(cb);
nexterror();
}
switch (c->qid.path) {
case Qctl:
XXX_ctl_cmd(c, cb);
break;
default:
error(EFAIL, "Unable to write to %s", devname());
}
kfree(cb);
poperror();
return n;
}
struct dev template_devtab __devtab = {
.name = "template",
.reset = devreset,
.init = devinit,
.shutdown = devshutdown,
.attach = XXX_attach,
.walk = XXX_walk,
.stat = XXX_stat,
.open = XXX_open,
.create = devcreate,
.close = XXX_close,
.read = XXX_read,
.bread = devbread,
.write = XXX_write,
.bwrite = devbwrite,
.remove = devremove,
.wstat = devwstat,
.power = devpower,
.chaninfo = devchaninfo,
};