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