akaros/kern/drivers/dev/template.c
<<
>>
Prefs
   1/* Copyright (c) 2020 Google Inc
   2 * Barret Rhoden <brho@cs.berkeley.edu>
   3 * See LICENSE for details.
   4 *
   5 * #template.  Dummy device with a devdir table.
   6 */
   7
   8#include <ns.h>
   9#include <kmalloc.h>
  10#include <string.h>
  11#include <stdio.h>
  12#include <assert.h>
  13#include <error.h>
  14
  15struct dev template_devtab;
  16
  17static char *devname(void)
  18{
  19        return template_devtab.name;
  20}
  21
  22enum {
  23        Qdir,
  24        Qctl,
  25};
  26
  27static struct dirtab XXX_dir[] = {
  28        {".", {Qdir, 0, QTDIR}, 0, DMDIR | 0555},
  29        {"ctl", {Qctl, 0, QTFILE}, 0, 0666},
  30};
  31
  32static struct chan *XXX_attach(char *spec)
  33{
  34        return devattach(devname(), spec);
  35}
  36
  37static struct walkqid *XXX_walk(struct chan *c, struct chan *nc, char **name,
  38                               unsigned int nname)
  39{
  40        return devwalk(c, nc, name, nname, XXX_dir, ARRAY_SIZE(XXX_dir),
  41                       devgen);
  42}
  43
  44static size_t XXX_stat(struct chan *c, uint8_t *db, size_t n)
  45{
  46        return devstat(c, db, n, XXX_dir, ARRAY_SIZE(XXX_dir), devgen);
  47}
  48
  49static struct chan *XXX_open(struct chan *c, int omode)
  50{
  51        return devopen(c, omode, XXX_dir, ARRAY_SIZE(XXX_dir), devgen);
  52}
  53
  54static void XXX_close(struct chan *c)
  55{
  56        /* If you do anything after open, only undo it for COPEN chans */
  57        if (!(c->flag & COPEN))
  58                return;
  59}
  60
  61static size_t XXX_read(struct chan *c, void *ubuf, size_t n, off64_t offset)
  62{
  63        switch (c->qid.path) {
  64        case Qdir:
  65                return devdirread(c, ubuf, n, XXX_dir, ARRAY_SIZE(XXX_dir),
  66                                  devgen);
  67        case Qctl:
  68                return readstr(offset, ubuf, n, "XXX");
  69        default:
  70                panic("Bad Qid %p!", c->qid.path);
  71        }
  72        return -1;
  73}
  74
  75#define XXX_CTL_USAGE "start|stop|print|reset"
  76
  77static void XXX_ctl_cmd(struct chan *c, struct cmdbuf *cb)
  78{
  79        ERRSTACK(1);
  80
  81        if (cb->nf < 1)
  82                error(EFAIL, XXX_CTL_USAGE);
  83
  84        if (waserror()) {
  85                nexterror();
  86        }
  87        if (!strcmp(cb->f[0], "start")) {
  88                ;
  89        } else if (!strcmp(cb->f[0], "stop")) {
  90                ;
  91        } else if (!strcmp(cb->f[0], "print")) {
  92                ;
  93        } else if (!strcmp(cb->f[0], "reset")) {
  94                ;
  95        } else {
  96                error(EFAIL, XXX_CTL_USAGE);
  97        }
  98        poperror();
  99}
 100
 101static size_t XXX_write(struct chan *c, void *ubuf, size_t n, off64_t unused)
 102{
 103        ERRSTACK(1);
 104        struct cmdbuf *cb = parsecmd(ubuf, n);
 105
 106        if (waserror()) {
 107                kfree(cb);
 108                nexterror();
 109        }
 110        switch (c->qid.path) {
 111        case Qctl:
 112                XXX_ctl_cmd(c, cb);
 113                break;
 114        default:
 115                error(EFAIL, "Unable to write to %s", devname());
 116        }
 117        kfree(cb);
 118        poperror();
 119        return n;
 120}
 121
 122struct dev template_devtab __devtab = {
 123        .name = "template",
 124        .reset = devreset,
 125        .init = devinit,
 126        .shutdown = devshutdown,
 127        .attach = XXX_attach,
 128        .walk = XXX_walk,
 129        .stat = XXX_stat,
 130        .open = XXX_open,
 131        .create = devcreate,
 132        .close = XXX_close,
 133        .read = XXX_read,
 134        .bread = devbread,
 135        .write = XXX_write,
 136        .bwrite = devbwrite,
 137        .remove = devremove,
 138        .wstat = devwstat,
 139        .power = devpower,
 140        .chaninfo = devchaninfo,
 141};
 142