Lionel Sambuc 5d8311761a Turn PCI into a character driver
Change-Id: Ia9c83af4d52e82e845b6a847c3e82e33d1920ae0
2014-11-10 14:43:27 +01:00

229 lines
5.1 KiB
C

#include "inc.h"
#include <sys/ioctl.h>
#include <minix/partition.h>
#include <sys/mtio.h>
const char *
block_ioctl_name(unsigned long req)
{
switch (req) {
NAME(BIOCTRACEBUF);
NAME(BIOCTRACECTL);
NAME(BIOCTRACEGET); /* big IOCTL, not printing argument */
NAME(DIOCSETP);
NAME(DIOCGETP);
NAME(DIOCEJECT); /* no argument */
NAME(DIOCTIMEOUT);
NAME(DIOCOPENCT);
NAME(DIOCFLUSH); /* no argument */
NAME(DIOCGETWC);
NAME(DIOCSETWC);
NAME(FBDCADDRULE);
NAME(FBDCDELRULE);
NAME(FBDCGETRULE);
NAME(MIOCRAMSIZE);
NAME(MTIOCGET); /* TODO: print argument */
NAME(MTIOCTOP); /* TODO: print argument */
NAME(VNDIOCCLR);
NAME(VNDIOCGET);
NAME(VNDIOCSET);
}
return NULL;
}
static const struct flags fbd_flags[] = {
FLAG(FBD_FLAG_READ),
FLAG(FBD_FLAG_WRITE),
};
static void
put_fbd_action(struct trace_proc * proc, const char * name, int action)
{
const char *text = NULL;
if (!valuesonly) {
switch (action) {
TEXT(FBD_ACTION_CORRUPT);
TEXT(FBD_ACTION_ERROR);
TEXT(FBD_ACTION_MISDIR);
TEXT(FBD_ACTION_LOSTTORN);
}
}
if (text != NULL)
put_field(proc, name, text);
else
put_value(proc, name, "%d", action);
}
static const struct flags vnd_flags[] = {
FLAG(VNDIOF_HASGEOM),
FLAG(VNDIOF_READONLY),
FLAG(VNDIOF_FORCE),
};
int
block_ioctl_arg(struct trace_proc * proc, unsigned long req, void * ptr,
int dir)
{
struct part_geom *part;
struct fbd_rule *rule;
struct vnd_ioctl *vnd;
struct vnd_user *vnu;
int i;
switch (req) {
case BIOCTRACEBUF:
if (ptr == NULL)
return IF_OUT;
put_value(proc, NULL, "%zu", *(size_t *)ptr);
return IF_ALL;
case BIOCTRACECTL:
if (ptr == NULL)
return IF_OUT;
i = *(int *)ptr;
if (!valuesonly && i == BTCTL_START)
put_field(proc, NULL, "BTCTL_START");
else if (!valuesonly && i == BTCTL_STOP)
put_field(proc, NULL, "BTCTL_STOP");
else
put_value(proc, NULL, "%d", i);
return IF_ALL;
case DIOCSETP:
if ((part = (struct part_geom *)ptr) == NULL)
return IF_OUT;
put_value(proc, "base", "%"PRIu64, part->base);
put_value(proc, "size", "%"PRIu64, part->size);
return IF_ALL;
case DIOCGETP:
if ((part = (struct part_geom *)ptr) == NULL)
return IF_IN;
put_value(proc, "base", "%"PRIu64, part->base);
put_value(proc, "size", "%"PRIu64, part->size);
if (verbose > 0) {
put_value(proc, "cylinders", "%u", part->cylinders);
put_value(proc, "heads", "%u", part->heads);
put_value(proc, "sectors", "%u", part->sectors);
return IF_ALL;
} else
return 0;
case DIOCTIMEOUT:
/* Print the old timeout only if verbosity is high enough. */
if (ptr == NULL)
return IF_OUT | ((verbose > 0) ? IF_IN : 0);
/* Same action for out and in. */
put_value(proc, NULL, "%d", *(int *)ptr);
return IF_ALL;
case DIOCOPENCT:
if (ptr == NULL)
return IF_IN;
put_value(proc, NULL, "%d", *(int *)ptr);
return IF_ALL;
case DIOCSETWC:
case DIOCGETWC:
if (ptr == NULL)
return dir; /* out or in, depending on the request */
put_value(proc, NULL, "%d", *(int *)ptr);
return IF_ALL;
case FBDCDELRULE:
if (ptr == NULL)
return IF_OUT;
put_value(proc, NULL, "%d", *(fbd_rulenum_t *)ptr);
return IF_ALL;
case FBDCGETRULE:
if ((rule = (struct fbd_rule *)ptr) == NULL)
return IF_OUT | IF_IN;
if (dir == IF_OUT) {
put_value(proc, "num", "%d", rule->num);
return IF_ALL;
}
/*
* The returned result is the same as what is passed to the
* add request, so we can use the same code to print both.
*/
/* FALLTHROUGH */
case FBDCADDRULE:
if ((rule = (struct fbd_rule *)ptr) == NULL)
return IF_OUT;
if (rule->start != 0 || rule->end != 0 || verbose > 0) {
put_value(proc, "start", "%"PRIu64, rule->start);
put_value(proc, "end", "%"PRIu64, rule->end);
}
if (rule->flags != (FBD_FLAG_READ | FBD_FLAG_WRITE) ||
verbose > 0)
put_flags(proc, "flags", fbd_flags, COUNT(fbd_flags),
"0x%x", rule->flags);
if (rule->skip != 0 || verbose > 0)
put_value(proc, "skip", "%u", rule->skip);
if (rule->count != 0 || verbose > 0)
put_value(proc, "count", "%u", rule->count);
put_fbd_action(proc, "action", rule->action);
return 0; /* TODO: optionally print the union fields */
case MIOCRAMSIZE:
if (ptr == NULL)
return IF_OUT;
put_value(proc, NULL, "%"PRIu32, *(u32_t *)ptr);
return IF_ALL;
case VNDIOCSET:
if ((vnd = (struct vnd_ioctl *)ptr) == NULL)
return IF_OUT | IF_IN;
if (dir == IF_OUT) {
put_value(proc, "vnd_fildes", "%d", vnd->vnd_fildes);
put_flags(proc, "vnd_flags", vnd_flags,
COUNT(vnd_flags), "0x%x", vnd->vnd_flags);
return 0; /* TODO: print geometry if given */
} else {
put_value(proc, "vnd_size", "%"PRIu64, vnd->vnd_size);
return IF_ALL;
}
case VNDIOCCLR:
if ((vnd = (struct vnd_ioctl *)ptr) == NULL)
return IF_OUT;
put_flags(proc, "vnd_flags", vnd_flags, COUNT(vnd_flags),
"0x%x", vnd->vnd_flags);
return IF_ALL;
case VNDIOCGET:
if ((vnu = (struct vnd_user *)ptr) == NULL)
return IF_IN;
put_value(proc, "vnu_unit", "%d", vnu->vnu_unit);
put_dev(proc, "vnu_dev", vnu->vnu_dev);
put_value(proc, "vnu_ino", "%"PRId64, vnu->vnu_ino);
return IF_ALL;
default:
return 0;
}
}