1 2 #include "inc.h" 3 4 #include <sys/ioctl.h> 5 #include <minix/partition.h> 6 #include <sys/mtio.h> 7 8 const char * 9 block_ioctl_name(unsigned long req) 10 { 11 12 switch (req) { 13 NAME(BIOCTRACEBUF); 14 NAME(BIOCTRACECTL); 15 NAME(BIOCTRACEGET); /* big IOCTL, not printing argument */ 16 NAME(DIOCSETP); 17 NAME(DIOCGETP); 18 NAME(DIOCEJECT); /* no argument */ 19 NAME(DIOCTIMEOUT); 20 NAME(DIOCOPENCT); 21 NAME(DIOCFLUSH); /* no argument */ 22 NAME(DIOCGETWC); 23 NAME(DIOCSETWC); 24 NAME(FBDCADDRULE); 25 NAME(FBDCDELRULE); 26 NAME(FBDCGETRULE); 27 NAME(MIOCRAMSIZE); 28 NAME(MTIOCGET); /* TODO: print argument */ 29 NAME(MTIOCTOP); /* TODO: print argument */ 30 NAME(VNDIOCCLR); 31 NAME(VNDIOCGET); 32 NAME(VNDIOCSET); 33 } 34 35 return NULL; 36 } 37 38 static const struct flags fbd_flags[] = { 39 FLAG(FBD_FLAG_READ), 40 FLAG(FBD_FLAG_WRITE), 41 }; 42 43 static void 44 put_fbd_action(struct trace_proc * proc, const char * name, int action) 45 { 46 const char *text = NULL; 47 48 if (!valuesonly) { 49 switch (action) { 50 TEXT(FBD_ACTION_CORRUPT); 51 TEXT(FBD_ACTION_ERROR); 52 TEXT(FBD_ACTION_MISDIR); 53 TEXT(FBD_ACTION_LOSTTORN); 54 } 55 } 56 57 if (text != NULL) 58 put_field(proc, name, text); 59 else 60 put_value(proc, name, "%d", action); 61 } 62 63 static const struct flags vnd_flags[] = { 64 FLAG(VNDIOF_HASGEOM), 65 FLAG(VNDIOF_READONLY), 66 FLAG(VNDIOF_FORCE), 67 }; 68 69 int 70 block_ioctl_arg(struct trace_proc * proc, unsigned long req, void * ptr, 71 int dir) 72 { 73 struct part_geom *part; 74 struct fbd_rule *rule; 75 struct vnd_ioctl *vnd; 76 struct vnd_user *vnu; 77 int i; 78 79 switch (req) { 80 case BIOCTRACEBUF: 81 if (ptr == NULL) 82 return IF_OUT; 83 84 put_value(proc, NULL, "%zu", *(size_t *)ptr); 85 return IF_ALL; 86 87 case BIOCTRACECTL: 88 if (ptr == NULL) 89 return IF_OUT; 90 91 i = *(int *)ptr; 92 if (!valuesonly && i == BTCTL_START) 93 put_field(proc, NULL, "BTCTL_START"); 94 else if (!valuesonly && i == BTCTL_STOP) 95 put_field(proc, NULL, "BTCTL_STOP"); 96 else 97 put_value(proc, NULL, "%d", i); 98 return IF_ALL; 99 100 case DIOCSETP: 101 if ((part = (struct part_geom *)ptr) == NULL) 102 return IF_OUT; 103 104 put_value(proc, "base", "%"PRIu64, part->base); 105 put_value(proc, "size", "%"PRIu64, part->size); 106 return IF_ALL; 107 108 case DIOCGETP: 109 if ((part = (struct part_geom *)ptr) == NULL) 110 return IF_IN; 111 112 put_value(proc, "base", "%"PRIu64, part->base); 113 put_value(proc, "size", "%"PRIu64, part->size); 114 if (verbose > 0) { 115 put_value(proc, "cylinders", "%u", part->cylinders); 116 put_value(proc, "heads", "%u", part->heads); 117 put_value(proc, "sectors", "%u", part->sectors); 118 return IF_ALL; 119 } else 120 return 0; 121 122 case DIOCTIMEOUT: 123 /* Print the old timeout only if verbosity is high enough. */ 124 if (ptr == NULL) 125 return IF_OUT | ((verbose > 0) ? IF_IN : 0); 126 127 /* Same action for out and in. */ 128 put_value(proc, NULL, "%d", *(int *)ptr); 129 return IF_ALL; 130 131 case DIOCOPENCT: 132 if (ptr == NULL) 133 return IF_IN; 134 135 put_value(proc, NULL, "%d", *(int *)ptr); 136 return IF_ALL; 137 138 case DIOCSETWC: 139 case DIOCGETWC: 140 if (ptr == NULL) 141 return dir; /* out or in, depending on the request */ 142 143 put_value(proc, NULL, "%d", *(int *)ptr); 144 return IF_ALL; 145 146 case FBDCDELRULE: 147 if (ptr == NULL) 148 return IF_OUT; 149 150 put_value(proc, NULL, "%d", *(fbd_rulenum_t *)ptr); 151 return IF_ALL; 152 153 case FBDCGETRULE: 154 if ((rule = (struct fbd_rule *)ptr) == NULL) 155 return IF_OUT | IF_IN; 156 157 if (dir == IF_OUT) { 158 put_value(proc, "num", "%d", rule->num); 159 return IF_ALL; 160 } 161 162 /* 163 * The returned result is the same as what is passed to the 164 * add request, so we can use the same code to print both. 165 */ 166 /* FALLTHROUGH */ 167 case FBDCADDRULE: 168 if ((rule = (struct fbd_rule *)ptr) == NULL) 169 return IF_OUT; 170 171 if (rule->start != 0 || rule->end != 0 || verbose > 0) { 172 put_value(proc, "start", "%"PRIu64, rule->start); 173 put_value(proc, "end", "%"PRIu64, rule->end); 174 } 175 if (rule->flags != (FBD_FLAG_READ | FBD_FLAG_WRITE) || 176 verbose > 0) 177 put_flags(proc, "flags", fbd_flags, COUNT(fbd_flags), 178 "0x%x", rule->flags); 179 if (rule->skip != 0 || verbose > 0) 180 put_value(proc, "skip", "%u", rule->skip); 181 if (rule->count != 0 || verbose > 0) 182 put_value(proc, "count", "%u", rule->count); 183 put_fbd_action(proc, "action", rule->action); 184 185 return 0; /* TODO: optionally print the union fields */ 186 187 case MIOCRAMSIZE: 188 if (ptr == NULL) 189 return IF_OUT; 190 191 put_value(proc, NULL, "%"PRIu32, *(u32_t *)ptr); 192 return IF_ALL; 193 194 case VNDIOCSET: 195 if ((vnd = (struct vnd_ioctl *)ptr) == NULL) 196 return IF_OUT | IF_IN; 197 198 if (dir == IF_OUT) { 199 put_value(proc, "vnd_fildes", "%d", vnd->vnd_fildes); 200 put_flags(proc, "vnd_flags", vnd_flags, 201 COUNT(vnd_flags), "0x%x", vnd->vnd_flags); 202 return 0; /* TODO: print geometry if given */ 203 } else { 204 put_value(proc, "vnd_size", "%"PRIu64, vnd->vnd_size); 205 return IF_ALL; 206 } 207 208 case VNDIOCCLR: 209 if ((vnd = (struct vnd_ioctl *)ptr) == NULL) 210 return IF_OUT; 211 212 put_flags(proc, "vnd_flags", vnd_flags, COUNT(vnd_flags), 213 "0x%x", vnd->vnd_flags); 214 return IF_ALL; 215 216 case VNDIOCGET: 217 if ((vnu = (struct vnd_user *)ptr) == NULL) 218 return IF_IN; 219 220 put_value(proc, "vnu_unit", "%d", vnu->vnu_unit); 221 put_dev(proc, "vnu_dev", vnu->vnu_dev); 222 put_value(proc, "vnu_ino", "%"PRId64, vnu->vnu_ino); 223 return IF_ALL; 224 225 default: 226 return 0; 227 } 228 } 229