1 /* 2 * Kernel CAPI 2.0 Module - /proc/capi handling 3 * 4 * Copyright 1999 by Carsten Paeth <calle@calle.de> 5 * Copyright 2002 by Kai Germaschewski <kai@germaschewski.name> 6 * 7 * This software may be used and distributed according to the terms 8 * of the GNU General Public License, incorporated herein by reference. 9 * 10 */ 11 12 13 #include "kcapi.h" 14 #include <linux/proc_fs.h> 15 #include <linux/seq_file.h> 16 #include <linux/init.h> 17 #include <linux/export.h> 18 19 static char *state2str(unsigned short state) 20 { 21 switch (state) { 22 case CAPI_CTR_DETECTED: return "detected"; 23 case CAPI_CTR_LOADING: return "loading"; 24 case CAPI_CTR_RUNNING: return "running"; 25 default: return "???"; 26 } 27 } 28 29 // /proc/capi 30 // =========================================================================== 31 32 // /proc/capi/controller: 33 // cnr driver cardstate name driverinfo 34 // /proc/capi/contrstats: 35 // cnr nrecvctlpkt nrecvdatapkt nsentctlpkt nsentdatapkt 36 // --------------------------------------------------------------------------- 37 38 static void *controller_start(struct seq_file *seq, loff_t *pos) 39 __acquires(capi_controller_lock) 40 { 41 mutex_lock(&capi_controller_lock); 42 43 if (*pos < CAPI_MAXCONTR) 44 return &capi_controller[*pos]; 45 46 return NULL; 47 } 48 49 static void *controller_next(struct seq_file *seq, void *v, loff_t *pos) 50 { 51 ++*pos; 52 if (*pos < CAPI_MAXCONTR) 53 return &capi_controller[*pos]; 54 55 return NULL; 56 } 57 58 static void controller_stop(struct seq_file *seq, void *v) 59 __releases(capi_controller_lock) 60 { 61 mutex_unlock(&capi_controller_lock); 62 } 63 64 static int controller_show(struct seq_file *seq, void *v) 65 { 66 struct capi_ctr *ctr = *(struct capi_ctr **) v; 67 68 if (!ctr) 69 return 0; 70 71 seq_printf(seq, "%d %-10s %-8s %-16s %s\n", 72 ctr->cnr, ctr->driver_name, 73 state2str(ctr->state), 74 ctr->name, 75 ctr->procinfo ? ctr->procinfo(ctr) : ""); 76 77 return 0; 78 } 79 80 static int contrstats_show(struct seq_file *seq, void *v) 81 { 82 struct capi_ctr *ctr = *(struct capi_ctr **) v; 83 84 if (!ctr) 85 return 0; 86 87 seq_printf(seq, "%d %lu %lu %lu %lu\n", 88 ctr->cnr, 89 ctr->nrecvctlpkt, 90 ctr->nrecvdatapkt, 91 ctr->nsentctlpkt, 92 ctr->nsentdatapkt); 93 94 return 0; 95 } 96 97 static const struct seq_operations seq_controller_ops = { 98 .start = controller_start, 99 .next = controller_next, 100 .stop = controller_stop, 101 .show = controller_show, 102 }; 103 104 static const struct seq_operations seq_contrstats_ops = { 105 .start = controller_start, 106 .next = controller_next, 107 .stop = controller_stop, 108 .show = contrstats_show, 109 }; 110 111 static int seq_controller_open(struct inode *inode, struct file *file) 112 { 113 return seq_open(file, &seq_controller_ops); 114 } 115 116 static int seq_contrstats_open(struct inode *inode, struct file *file) 117 { 118 return seq_open(file, &seq_contrstats_ops); 119 } 120 121 static const struct file_operations proc_controller_ops = { 122 .owner = THIS_MODULE, 123 .open = seq_controller_open, 124 .read = seq_read, 125 .llseek = seq_lseek, 126 .release = seq_release, 127 }; 128 129 static const struct file_operations proc_contrstats_ops = { 130 .owner = THIS_MODULE, 131 .open = seq_contrstats_open, 132 .read = seq_read, 133 .llseek = seq_lseek, 134 .release = seq_release, 135 }; 136 137 // /proc/capi/applications: 138 // applid l3cnt dblkcnt dblklen #ncci recvqueuelen 139 // /proc/capi/applstats: 140 // applid nrecvctlpkt nrecvdatapkt nsentctlpkt nsentdatapkt 141 // --------------------------------------------------------------------------- 142 143 static void *applications_start(struct seq_file *seq, loff_t *pos) 144 __acquires(capi_controller_lock) 145 { 146 mutex_lock(&capi_controller_lock); 147 148 if (*pos < CAPI_MAXAPPL) 149 return &capi_applications[*pos]; 150 151 return NULL; 152 } 153 154 static void * 155 applications_next(struct seq_file *seq, void *v, loff_t *pos) 156 { 157 ++*pos; 158 if (*pos < CAPI_MAXAPPL) 159 return &capi_applications[*pos]; 160 161 return NULL; 162 } 163 164 static void applications_stop(struct seq_file *seq, void *v) 165 __releases(capi_controller_lock) 166 { 167 mutex_unlock(&capi_controller_lock); 168 } 169 170 static int 171 applications_show(struct seq_file *seq, void *v) 172 { 173 struct capi20_appl *ap = *(struct capi20_appl **) v; 174 175 if (!ap) 176 return 0; 177 178 seq_printf(seq, "%u %d %d %d\n", 179 ap->applid, 180 ap->rparam.level3cnt, 181 ap->rparam.datablkcnt, 182 ap->rparam.datablklen); 183 184 return 0; 185 } 186 187 static int 188 applstats_show(struct seq_file *seq, void *v) 189 { 190 struct capi20_appl *ap = *(struct capi20_appl **) v; 191 192 if (!ap) 193 return 0; 194 195 seq_printf(seq, "%u %lu %lu %lu %lu\n", 196 ap->applid, 197 ap->nrecvctlpkt, 198 ap->nrecvdatapkt, 199 ap->nsentctlpkt, 200 ap->nsentdatapkt); 201 202 return 0; 203 } 204 205 static const struct seq_operations seq_applications_ops = { 206 .start = applications_start, 207 .next = applications_next, 208 .stop = applications_stop, 209 .show = applications_show, 210 }; 211 212 static const struct seq_operations seq_applstats_ops = { 213 .start = applications_start, 214 .next = applications_next, 215 .stop = applications_stop, 216 .show = applstats_show, 217 }; 218 219 static int 220 seq_applications_open(struct inode *inode, struct file *file) 221 { 222 return seq_open(file, &seq_applications_ops); 223 } 224 225 static int 226 seq_applstats_open(struct inode *inode, struct file *file) 227 { 228 return seq_open(file, &seq_applstats_ops); 229 } 230 231 static const struct file_operations proc_applications_ops = { 232 .owner = THIS_MODULE, 233 .open = seq_applications_open, 234 .read = seq_read, 235 .llseek = seq_lseek, 236 .release = seq_release, 237 }; 238 239 static const struct file_operations proc_applstats_ops = { 240 .owner = THIS_MODULE, 241 .open = seq_applstats_open, 242 .read = seq_read, 243 .llseek = seq_lseek, 244 .release = seq_release, 245 }; 246 247 // --------------------------------------------------------------------------- 248 249 static void *capi_driver_start(struct seq_file *seq, loff_t *pos) 250 __acquires(&capi_drivers_lock) 251 { 252 mutex_lock(&capi_drivers_lock); 253 return seq_list_start(&capi_drivers, *pos); 254 } 255 256 static void *capi_driver_next(struct seq_file *seq, void *v, loff_t *pos) 257 { 258 return seq_list_next(v, &capi_drivers, pos); 259 } 260 261 static void capi_driver_stop(struct seq_file *seq, void *v) 262 __releases(&capi_drivers_lock) 263 { 264 mutex_unlock(&capi_drivers_lock); 265 } 266 267 static int capi_driver_show(struct seq_file *seq, void *v) 268 { 269 struct capi_driver *drv = list_entry(v, struct capi_driver, list); 270 271 seq_printf(seq, "%-32s %s\n", drv->name, drv->revision); 272 return 0; 273 } 274 275 static const struct seq_operations seq_capi_driver_ops = { 276 .start = capi_driver_start, 277 .next = capi_driver_next, 278 .stop = capi_driver_stop, 279 .show = capi_driver_show, 280 }; 281 282 static int 283 seq_capi_driver_open(struct inode *inode, struct file *file) 284 { 285 int err; 286 err = seq_open(file, &seq_capi_driver_ops); 287 return err; 288 } 289 290 static const struct file_operations proc_driver_ops = { 291 .owner = THIS_MODULE, 292 .open = seq_capi_driver_open, 293 .read = seq_read, 294 .llseek = seq_lseek, 295 .release = seq_release, 296 }; 297 298 // --------------------------------------------------------------------------- 299 300 void __init 301 kcapi_proc_init(void) 302 { 303 proc_mkdir("capi", NULL); 304 proc_mkdir("capi/controllers", NULL); 305 proc_create("capi/controller", 0, NULL, &proc_controller_ops); 306 proc_create("capi/contrstats", 0, NULL, &proc_contrstats_ops); 307 proc_create("capi/applications", 0, NULL, &proc_applications_ops); 308 proc_create("capi/applstats", 0, NULL, &proc_applstats_ops); 309 proc_create("capi/driver", 0, NULL, &proc_driver_ops); 310 } 311 312 void __exit 313 kcapi_proc_exit(void) 314 { 315 remove_proc_entry("capi/driver", NULL); 316 remove_proc_entry("capi/controller", NULL); 317 remove_proc_entry("capi/contrstats", NULL); 318 remove_proc_entry("capi/applications", NULL); 319 remove_proc_entry("capi/applstats", NULL); 320 remove_proc_entry("capi/controllers", NULL); 321 remove_proc_entry("capi", NULL); 322 } 323