| 1 | /* |
| 2 | * Copyright 2010-2017 Intel Corporation. |
| 3 | * |
| 4 | * This program is free software; you can redistribute it and/or modify |
| 5 | * it under the terms of the GNU General Public License, version 2, |
| 6 | * as published by the Free Software Foundation. |
| 7 | * |
| 8 | * This program is distributed in the hope that it will be useful, |
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 11 | * General Public License for more details. |
| 12 | * |
| 13 | * Disclaimer: The codes contained in these modules may be specific to |
| 14 | * the Intel Software Development Platform codenamed Knights Ferry, |
| 15 | * and the Intel product codenamed Knights Corner, and are not backward |
| 16 | * compatible with other Intel products. Additionally, Intel will NOT |
| 17 | * support the codes or instruction set in future products. |
| 18 | * |
| 19 | * Intel offers no warranty of any kind regarding the code. This code is |
| 20 | * licensed on an "AS IS" basis and Intel is not obligated to provide |
| 21 | * any support, assistance, installation, training, or other services |
| 22 | * of any kind. Intel is also not obligated to provide any updates, |
| 23 | * enhancements or extensions. Intel specifically disclaims any warranty |
| 24 | * of merchantability, non-infringement, fitness for any particular |
| 25 | * purpose, and any other warranty. |
| 26 | * |
| 27 | * Further, Intel disclaims all liability of any kind, including but |
| 28 | * not limited to liability for infringement of any proprietary rights, |
| 29 | * relating to the use of the code, even if Intel is notified of the |
| 30 | * possibility of such liability. Except as expressly stated in an Intel |
| 31 | * license agreement provided with this code and agreed upon with Intel, |
| 32 | * no license, express or implied, by estoppel or otherwise, to any |
| 33 | * intellectual property rights is granted herein. |
| 34 | */ |
| 35 | |
| 36 | #include "mic/micscif.h" |
| 37 | #ifndef _MIC_SCIF_ |
| 38 | #include "mic_common.h" |
| 39 | #endif |
| 40 | #include "scif.h" |
| 41 | #include <linux/proc_fs.h> |
| 42 | #include <linux/debugfs.h> |
| 43 | |
| 44 | #include <linux/module.h> |
| 45 | |
| 46 | static char *window_type[] = { |
| 47 | "NONE", |
| 48 | "SELF", |
| 49 | "PEER"}; |
| 50 | |
| 51 | static char *scifdev_state[] = { |
| 52 | "SCIFDEV_NOTPRESENT", |
| 53 | "SCIFDEV_INIT", |
| 54 | "SCIFDEV_RUNNING", |
| 55 | "SCIFDEV_SLEEPING", |
| 56 | "SCIFDEV_STOPPING", |
| 57 | "SCIFDEV_STOPPED"}; |
| 58 | |
| 59 | static struct proc_dir_entry *scif_proc; |
| 60 | static struct dentry *mic_debug = NULL; |
| 61 | |
| 62 | #define DEBUG_LEN 10 |
| 63 | |
| 64 | static int |
| 65 | scif_ep_show(struct seq_file *m, void *data) |
| 66 | { |
| 67 | struct endpt *ep; |
| 68 | struct list_head *pos; |
| 69 | unsigned long sflags; |
| 70 | |
| 71 | seq_printf(m, "EP Address State Port Peer Remote Ep Address\n"); |
| 72 | seq_printf(m, "=================================================================\n"); |
| 73 | spin_lock_irqsave(&ms_info.mi_eplock, sflags); |
| 74 | list_for_each(pos, &ms_info.mi_listen) { |
| 75 | ep = list_entry(pos, struct endpt, list); |
| 76 | seq_printf(m, "%p %s %6d\n", |
| 77 | ep, scif_ep_states[ep->state], ep->port.port); |
| 78 | } |
| 79 | spin_unlock_irqrestore(&ms_info.mi_eplock, sflags); |
| 80 | |
| 81 | spin_lock_irqsave(&ms_info.mi_connlock, sflags); |
| 82 | list_for_each(pos, &ms_info.mi_connected) { |
| 83 | ep = list_entry(pos, struct endpt, list); |
| 84 | seq_printf(m, "%p %s %6d %2d:%-6d %p\n", |
| 85 | ep, scif_ep_states[ep->state], ep->port.port, ep->peer.node, |
| 86 | ep->peer.port, (void *)ep->remote_ep); |
| 87 | } |
| 88 | list_for_each(pos, &ms_info.mi_disconnected) { |
| 89 | ep = list_entry(pos, struct endpt, list); |
| 90 | seq_printf(m, "%p %s %6d %2d:%-6d %p\n", |
| 91 | ep, scif_ep_states[ep->state], ep->port.port, ep->peer.node, |
| 92 | ep->peer.port, (void *)ep->remote_ep); |
| 93 | } |
| 94 | spin_unlock_irqrestore(&ms_info.mi_connlock, sflags); |
| 95 | |
| 96 | seq_printf(m, "EP Address State Port Peer Remote Ep Address reg_list " |
| 97 | "remote_reg_list mmn_list tw_refcount tcw_refcount mi_rma mi_rma_tc " |
| 98 | "task_list mic_mmu_notif_cleanup\n"); |
| 99 | seq_printf(m, "=================================================================\n"); |
| 100 | spin_lock_irqsave(&ms_info.mi_eplock, sflags); |
| 101 | list_for_each(pos, &ms_info.mi_zombie) { |
| 102 | ep = list_entry(pos, struct endpt, list); |
| 103 | seq_printf(m, "%p %s %6d %2d:%-6d %p %d %d %d %d %d %d %d %d %d\n", |
| 104 | ep, scif_ep_states[ep->state], ep->port.port, ep->peer.node, |
| 105 | ep->peer.port, (void *)ep->remote_ep, |
| 106 | list_empty(&ep->rma_info.reg_list), |
| 107 | list_empty(&ep->rma_info.remote_reg_list), |
| 108 | list_empty(&ep->rma_info.mmn_list), |
| 109 | atomic_read(&ep->rma_info.tw_refcount), |
| 110 | atomic_read(&ep->rma_info.tcw_refcount), |
| 111 | list_empty(&ms_info.mi_rma), |
| 112 | list_empty(&ms_info.mi_rma_tc), |
| 113 | list_empty(&ep->rma_info.task_list), |
| 114 | #ifdef CONFIG_MMU_NOTIFIER |
| 115 | list_empty(&ms_info.mi_mmu_notif_cleanup) |
| 116 | #else |
| 117 | -1 |
| 118 | #endif |
| 119 | ); |
| 120 | } |
| 121 | spin_unlock_irqrestore(&ms_info.mi_eplock, sflags); |
| 122 | |
| 123 | return 0; |
| 124 | } |
| 125 | |
| 126 | static int |
| 127 | scif_ep_open(struct inode *inode, struct file *file) |
| 128 | { |
| 129 | return single_open(file, scif_ep_show, NULL); |
| 130 | } |
| 131 | |
| 132 | struct file_operations scif_ep_fops = { |
| 133 | .open = scif_ep_open, |
| 134 | .read = seq_read, |
| 135 | .llseek = seq_lseek, |
| 136 | .release = single_release, |
| 137 | }; |
| 138 | |
| 139 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)) |
| 140 | |
| 141 | static int |
| 142 | scif_rma_window_show(struct seq_file *m, void *data) |
| 143 | { |
| 144 | struct endpt *ep; |
| 145 | struct list_head *pos, *item, *tmp; |
| 146 | unsigned long sflags; |
| 147 | struct reg_range_t *window; |
| 148 | |
| 149 | seq_printf(m, "SCIF Connected EP RMA Window Info\n"); |
| 150 | seq_printf(m, "=================================================================\n"); |
| 151 | seq_printf(m, "%-16s\t%-16s %-16s %-16s %-8s %-8s %-8s\n", |
| 152 | "Endpoint", "Type", "Offset", "NumPages", "Prot", "Ref_Count", "Unreg State"); |
| 153 | spin_lock_irqsave(&ms_info.mi_connlock, sflags); |
| 154 | list_for_each(pos, &ms_info.mi_connected) { |
| 155 | ep = list_entry(pos, struct endpt, list); |
| 156 | if (mutex_trylock(&ep->rma_info.rma_lock)) { |
| 157 | list_for_each_safe(item, tmp, &ep->rma_info.reg_list) { |
| 158 | window = list_entry(item, struct reg_range_t, list_member); |
| 159 | seq_printf(m, |
| 160 | "%-16p\t%-16s 0x%-16llx %-16lld %-8d %-8d %-8d\n", |
| 161 | ep, window_type[window->type], window->offset, |
| 162 | window->nr_pages, window->prot, window->ref_count, |
| 163 | window->unreg_state); |
| 164 | } |
| 165 | list_for_each_safe(item, tmp, &ep->rma_info.remote_reg_list) { |
| 166 | window = list_entry(item, struct reg_range_t, list_member); |
| 167 | seq_printf(m, |
| 168 | "%-16p\t%-16s 0x%-16llx %-16lld %-8d %-8d %-8d\n", |
| 169 | ep, window_type[window->type], window->offset, |
| 170 | window->nr_pages, window->prot, window->ref_count, |
| 171 | window->unreg_state); |
| 172 | } |
| 173 | mutex_unlock(&ep->rma_info.rma_lock); |
| 174 | } else |
| 175 | seq_printf(m, |
| 176 | "Try Again, some other thread has the RMA lock for ep %p\n", |
| 177 | ep); |
| 178 | } |
| 179 | spin_unlock_irqrestore(&ms_info.mi_connlock, sflags); |
| 180 | |
| 181 | seq_printf(m, "=================================================================\n"); |
| 182 | seq_printf(m, "SCIF Zombie EP RMA Window Info\n"); |
| 183 | spin_lock_irqsave(&ms_info.mi_eplock, sflags); |
| 184 | list_for_each(pos, &ms_info.mi_zombie) { |
| 185 | ep = list_entry(pos, struct endpt, list); |
| 186 | if (mutex_trylock(&ep->rma_info.rma_lock)) { |
| 187 | list_for_each_safe(item, tmp, &ep->rma_info.reg_list) { |
| 188 | window = list_entry(item, struct reg_range_t, list_member); |
| 189 | seq_printf(m, |
| 190 | "%-16p\t%-16s 0x%-16llx %-16lld %-8d %-8d %-8d\n", |
| 191 | ep, window_type[window->type], window->offset, |
| 192 | window->nr_pages, window->prot, window->ref_count, |
| 193 | window->unreg_state); |
| 194 | } |
| 195 | list_for_each_safe(item, tmp, &ep->rma_info.remote_reg_list) { |
| 196 | window = list_entry(item, struct reg_range_t, list_member); |
| 197 | seq_printf(m, |
| 198 | "%-16p\t%-16s 0x%-16llx %-16lld %-8d %-8d %-8d\n", |
| 199 | ep, window_type[window->type], window->offset, |
| 200 | window->nr_pages, window->prot, window->ref_count, |
| 201 | window->unreg_state); |
| 202 | } |
| 203 | mutex_unlock(&ep->rma_info.rma_lock); |
| 204 | } else |
| 205 | seq_printf(m, |
| 206 | "Try Again, some other thread has the RMA lock for ep %p\n", |
| 207 | ep); |
| 208 | } |
| 209 | spin_unlock_irqrestore(&ms_info.mi_eplock, sflags); |
| 210 | seq_printf(m, "=================================================================\n"); |
| 211 | seq_printf(m, "%-16s\t%-16s %-16s %-16s %-8s %-8s %-8s\n", |
| 212 | "Endpoint", "Type", "Offset", "NumPages", "Prot", "Ref_Count", "Unreg State"); |
| 213 | spin_lock(&ms_info.mi_rmalock); |
| 214 | list_for_each_safe(item, tmp, &ms_info.mi_rma) { |
| 215 | window = list_entry(item, |
| 216 | struct reg_range_t, list_member); |
| 217 | ep = (struct endpt *)window->ep; |
| 218 | seq_printf(m, "%-16p\t%-16s 0x%-16llx %-16lld %-8d %-8d %-8d\n", |
| 219 | ep, window_type[window->type], window->offset, |
| 220 | window->nr_pages, window->prot, window->ref_count, |
| 221 | window->unreg_state); |
| 222 | } |
| 223 | spin_unlock(&ms_info.mi_rmalock); |
| 224 | |
| 225 | return 0; |
| 226 | } |
| 227 | |
| 228 | static int |
| 229 | scif_rma_window_open(struct inode *inode, struct file *file) |
| 230 | { |
| 231 | return single_open(file, scif_rma_window_show, NULL); |
| 232 | } |
| 233 | |
| 234 | struct file_operations scif_rma_window_fops = { |
| 235 | .open = scif_rma_window_open, |
| 236 | .read = seq_read, |
| 237 | .llseek = seq_lseek, |
| 238 | .release = single_release, |
| 239 | }; |
| 240 | |
| 241 | static int |
| 242 | scif_rma_xfer_show(struct seq_file *m, void *data) |
| 243 | { |
| 244 | struct endpt *ep; |
| 245 | struct list_head *pos; |
| 246 | unsigned long sflags; |
| 247 | |
| 248 | seq_printf(m, "SCIF RMA Debug\n"); |
| 249 | seq_printf(m, "=================================================================\n"); |
| 250 | seq_printf(m, "%-16s\t %-16s %-16s %-16s\n", |
| 251 | "Endpoint", "Fence Ref Count", "Temp Window Ref Count", "DMA CHANNEL"); |
| 252 | spin_lock_irqsave(&ms_info.mi_connlock, sflags); |
| 253 | list_for_each(pos, &ms_info.mi_connected) { |
| 254 | ep = list_entry(pos, struct endpt, list); |
| 255 | seq_printf(m, "%-16p\t%-16d %-16d %-16d\n", |
| 256 | ep, ep->rma_info.fence_refcount, |
| 257 | atomic_read(&ep->rma_info.tw_refcount), |
| 258 | ep->rma_info.dma_chan ? get_chan_num(ep->rma_info.dma_chan): -1); |
| 259 | } |
| 260 | spin_unlock_irqrestore(&ms_info.mi_connlock, sflags); |
| 261 | return 0; |
| 262 | } |
| 263 | |
| 264 | static int |
| 265 | scif_rma_xfer_open(struct inode *inode, struct file *file) |
| 266 | { |
| 267 | return single_open(file, scif_rma_xfer_show, NULL); |
| 268 | } |
| 269 | |
| 270 | struct file_operations scif_rma_xfer_fops = { |
| 271 | .open = scif_rma_xfer_open, |
| 272 | .read = seq_read, |
| 273 | .llseek = seq_lseek, |
| 274 | .release = single_release, |
| 275 | }; |
| 276 | |
| 277 | static int |
| 278 | scif_dev_show(struct seq_file *m, void *data) |
| 279 | { |
| 280 | int node; |
| 281 | |
| 282 | seq_printf(m, "Total Nodes %d Self Node Id %d Maxid %d\n", |
| 283 | ms_info.mi_total, ms_info.mi_nodeid, ms_info.mi_maxid); |
| 284 | |
| 285 | seq_printf(m, "%-16s\t%-16s %-16s\t%-16s\t%-8s\t%-8s\t%-8s\n", |
| 286 | "node_id", "state", "scif_ref_cnt", "scif_map_ref_cnt", |
| 287 | "wait_status", "conn count", "numa_node"); |
| 288 | |
| 289 | for (node = 0; node <= ms_info.mi_maxid; node++) |
| 290 | seq_printf(m, "%-16d\t%-16s\t0x%-16lx\t%-16d\t%-16lld\t%-16d\t%-16d\n", |
| 291 | scif_dev[node].sd_node, scifdev_state[scif_dev[node].sd_state], |
| 292 | atomic_long_read(&scif_dev[node].scif_ref_cnt), |
| 293 | scif_dev[node].scif_map_ref_cnt, |
| 294 | scif_dev[node].sd_wait_status, |
| 295 | scif_dev[node].num_active_conn, |
| 296 | scif_dev[node].sd_numa_node); |
| 297 | |
| 298 | return 0; |
| 299 | } |
| 300 | |
| 301 | static int |
| 302 | scif_dev_open(struct inode *inode, struct file *file) |
| 303 | { |
| 304 | return single_open(file, scif_dev_show, NULL); |
| 305 | } |
| 306 | |
| 307 | struct file_operations scif_dev_fops = { |
| 308 | .open = scif_dev_open, |
| 309 | .read = seq_read, |
| 310 | .llseek = seq_lseek, |
| 311 | .release = single_release, |
| 312 | }; |
| 313 | |
| 314 | static int |
| 315 | scif_debug_show(struct seq_file *m, void *data) |
| 316 | { |
| 317 | seq_printf(m, "Num gtt_entries %d\n", ms_info.nr_gtt_entries); |
| 318 | /* |
| 319 | * Tracking the number of zombies for debug. |
| 320 | * Need to make sure they are not being left behind forever. |
| 321 | */ |
| 322 | seq_printf(m, "Num Zombie Endpoints %d\n", ms_info.mi_nr_zombies); |
| 323 | seq_printf(m, "Watchdog timeout %d\n", ms_info.mi_watchdog_to); |
| 324 | seq_printf(m, "Watchdog enabled %d\n", ms_info.mi_watchdog_enabled); |
| 325 | seq_printf(m, "Watchdog auto reboot %d\n", ms_info.mi_watchdog_auto_reboot); |
| 326 | seq_printf(m, "Huge Pages Enabled %d Detected 2mb %lld 4k %lld\n", |
| 327 | mic_huge_page_enable, ms_info.nr_2mb_pages, ms_info.nr_4k_pages); |
| 328 | #ifdef RMA_DEBUG |
| 329 | seq_printf(m, "rma_alloc_cnt %ld rma_pin_cnt %ld mmu_notif %ld rma_unaligned_cpu_cnt %ld\n", |
| 330 | atomic_long_read(&ms_info.rma_alloc_cnt), |
| 331 | atomic_long_read(&ms_info.rma_pin_cnt), |
| 332 | atomic_long_read(&ms_info.mmu_notif_cnt), |
| 333 | atomic_long_read(&ms_info.rma_unaligned_cpu_cnt)); |
| 334 | #endif |
| 335 | seq_printf(m, "List empty? mi_uaccept %d mi_listen %d mi_zombie %d " |
| 336 | "mi_connected %d mi_disconnected %d\n", |
| 337 | list_empty(&ms_info.mi_uaccept), |
| 338 | list_empty(&ms_info.mi_listen), |
| 339 | list_empty(&ms_info.mi_zombie), |
| 340 | list_empty(&ms_info.mi_connected), |
| 341 | list_empty(&ms_info.mi_disconnected)); |
| 342 | |
| 343 | return 0; |
| 344 | } |
| 345 | |
| 346 | static int |
| 347 | scif_debug_open(struct inode *inode, struct file *file) |
| 348 | { |
| 349 | return single_open(file, scif_debug_show, NULL); |
| 350 | } |
| 351 | |
| 352 | struct file_operations scif_debug_fops = { |
| 353 | .open = scif_debug_open, |
| 354 | .read = seq_read, |
| 355 | .llseek = seq_lseek, |
| 356 | .release = single_release, |
| 357 | }; |
| 358 | |
| 359 | static int |
| 360 | scif_suspend_show(struct seq_file *m, void *data) |
| 361 | { |
| 362 | int node; |
| 363 | uint64_t ret; |
| 364 | seq_printf(m, "Removing Nodes mask 0x7\n"); |
| 365 | |
| 366 | for (node = 1; node < ms_info.mi_total; node++) { |
| 367 | ret = micscif_disconnect_node(node, 0 , 1); |
| 368 | seq_printf(m, "Node %d requested disconnect. ret = %lld\n", |
| 369 | node, ret); |
| 370 | } |
| 371 | |
| 372 | return 0; |
| 373 | } |
| 374 | |
| 375 | static int |
| 376 | scif_suspend_open(struct inode *inode, struct file *file) |
| 377 | { |
| 378 | return single_open(file, scif_suspend_show, NULL); |
| 379 | } |
| 380 | |
| 381 | struct file_operations scif_suspend_fops = { |
| 382 | .open = scif_suspend_open, |
| 383 | .read = seq_read, |
| 384 | .llseek = seq_lseek, |
| 385 | .release = single_release, |
| 386 | }; |
| 387 | |
| 388 | static int |
| 389 | scif_cache_limit_show(struct seq_file *m, void *data) |
| 390 | { |
| 391 | seq_printf(m, "reg_cache_limit = 0x%lx\n", ms_info.mi_rma_tc_limit); |
| 392 | return 0; |
| 393 | } |
| 394 | |
| 395 | static int |
| 396 | scif_cache_limit_open(struct inode *inode, struct file *file) |
| 397 | { |
| 398 | return single_open(file, scif_cache_limit_show, NULL); |
| 399 | } |
| 400 | |
| 401 | struct file_operations scif_cache_limit_fops = { |
| 402 | .open = scif_cache_limit_open, |
| 403 | .read = seq_read, |
| 404 | .llseek = seq_lseek, |
| 405 | .release = single_release, |
| 406 | }; |
| 407 | |
| 408 | #else // LINUX VERSION 3.10 |
| 409 | |
| 410 | static int |
| 411 | scif_rma_window_read(char *buf, char **start, off_t offset, int len, int *eof, void *data) |
| 412 | { |
| 413 | struct endpt *ep; |
| 414 | struct list_head *pos, *item, *tmp; |
| 415 | unsigned long sflags; |
| 416 | int l = 0; |
| 417 | struct reg_range_t *window; |
| 418 | |
| 419 | l += snprintf(buf + l, len - l > 0 ? len - l : 0 , |
| 420 | "SCIF Connected EP RMA Window Info\n"); |
| 421 | l += snprintf(buf + l, len - l > 0 ? len - l : 0 , |
| 422 | "=================================================================\n"); |
| 423 | l += snprintf(buf + l, len - l > 0 ? len - l : 0 , |
| 424 | "%-16s\t%-16s %-16s %-16s %-8s %-8s %-8s\n", |
| 425 | "Endpoint", "Type", "Offset", "NumPages", "Prot", "Ref_Count", "Unreg State"); |
| 426 | spin_lock_irqsave(&ms_info.mi_connlock, sflags); |
| 427 | list_for_each(pos, &ms_info.mi_connected) { |
| 428 | ep = list_entry(pos, struct endpt, list); |
| 429 | if (mutex_trylock(&ep->rma_info.rma_lock)) { |
| 430 | list_for_each_safe(item, tmp, &ep->rma_info.reg_list) { |
| 431 | window = list_entry(item, struct reg_range_t, list_member); |
| 432 | l += snprintf(buf + l, len - l > 0 ? len - l : 0 , |
| 433 | "%-16p\t%-16s 0x%-16llx %-16lld %-8d %-8d %-8d\n", |
| 434 | ep, window_type[window->type], window->offset, |
| 435 | window->nr_pages, window->prot, window->ref_count, |
| 436 | window->unreg_state); |
| 437 | } |
| 438 | list_for_each_safe(item, tmp, &ep->rma_info.remote_reg_list) { |
| 439 | window = list_entry(item, struct reg_range_t, list_member); |
| 440 | l += snprintf(buf + l, len - l > 0 ? len - l : 0 , |
| 441 | "%-16p\t%-16s 0x%-16llx %-16lld %-8d %-8d %-8d\n", |
| 442 | ep, window_type[window->type], window->offset, |
| 443 | window->nr_pages, window->prot, window->ref_count, |
| 444 | window->unreg_state); |
| 445 | } |
| 446 | mutex_unlock(&ep->rma_info.rma_lock); |
| 447 | } else |
| 448 | l += snprintf(buf + l, len - l > 0 ? len - l : 0 , |
| 449 | "Try Again, some other thread has the RMA lock for ep %p\n", |
| 450 | ep); |
| 451 | } |
| 452 | spin_unlock_irqrestore(&ms_info.mi_connlock, sflags); |
| 453 | |
| 454 | l += snprintf(buf + l, len - l > 0 ? len - l : 0 , |
| 455 | "=================================================================\n"); |
| 456 | l += snprintf(buf + l, len - l > 0 ? len - l : 0 , |
| 457 | "SCIF Zombie EP RMA Window Info\n"); |
| 458 | spin_lock_irqsave(&ms_info.mi_eplock, sflags); |
| 459 | list_for_each(pos, &ms_info.mi_zombie) { |
| 460 | ep = list_entry(pos, struct endpt, list); |
| 461 | if (mutex_trylock(&ep->rma_info.rma_lock)) { |
| 462 | list_for_each_safe(item, tmp, &ep->rma_info.reg_list) { |
| 463 | window = list_entry(item, struct reg_range_t, list_member); |
| 464 | l += snprintf(buf + l, len - l > 0 ? len - l : 0 , |
| 465 | "%-16p\t%-16s 0x%-16llx %-16lld %-8d %-8d %-8d\n", |
| 466 | ep, window_type[window->type], window->offset, |
| 467 | window->nr_pages, window->prot, window->ref_count, |
| 468 | window->unreg_state); |
| 469 | } |
| 470 | list_for_each_safe(item, tmp, &ep->rma_info.remote_reg_list) { |
| 471 | window = list_entry(item, struct reg_range_t, list_member); |
| 472 | l += snprintf(buf + l, len - l > 0 ? len - l : 0 , |
| 473 | "%-16p\t%-16s 0x%-16llx %-16lld %-8d %-8d %-8d\n", |
| 474 | ep, window_type[window->type], window->offset, |
| 475 | window->nr_pages, window->prot, window->ref_count, |
| 476 | window->unreg_state); |
| 477 | } |
| 478 | mutex_unlock(&ep->rma_info.rma_lock); |
| 479 | } else |
| 480 | l += snprintf(buf + l, len - l > 0 ? len - l : 0 , |
| 481 | "Try Again, some other thread has the RMA lock for ep %p\n", |
| 482 | ep); |
| 483 | } |
| 484 | spin_unlock_irqrestore(&ms_info.mi_eplock, sflags); |
| 485 | l += snprintf(buf + l, len - l > 0 ? len - l : 0 , |
| 486 | "=================================================================\n"); |
| 487 | l += snprintf(buf + l, len - l > 0 ? len - l : 0 , |
| 488 | "%-16s\t%-16s %-16s %-16s %-8s %-8s %-8s\n", |
| 489 | "Endpoint", "Type", "Offset", "NumPages", "Prot", "Ref_Count", "Unreg State"); |
| 490 | spin_lock(&ms_info.mi_rmalock); |
| 491 | list_for_each_safe(item, tmp, &ms_info.mi_rma) { |
| 492 | window = list_entry(item, |
| 493 | struct reg_range_t, list_member); |
| 494 | ep = (struct endpt *)window->ep; |
| 495 | l += snprintf(buf + l, len - l > 0 ? len - l : 0 , |
| 496 | "%-16p\t%-16s 0x%-16llx %-16lld %-8d %-8d %-8d\n", |
| 497 | ep, window_type[window->type], window->offset, |
| 498 | window->nr_pages, window->prot, window->ref_count, |
| 499 | window->unreg_state); |
| 500 | } |
| 501 | spin_unlock(&ms_info.mi_rmalock); |
| 502 | |
| 503 | *eof = 1; |
| 504 | return l; |
| 505 | } |
| 506 | |
| 507 | static int |
| 508 | scif_rma_xfer_read(char *buf, char **start, off_t offset, int len, int *eof, void *data) |
| 509 | { |
| 510 | struct endpt *ep; |
| 511 | struct list_head *pos; |
| 512 | unsigned long sflags; |
| 513 | int l = 0; |
| 514 | |
| 515 | l += snprintf(buf + l, len - l > 0 ? len - l : 0 , "SCIF RMA Debug\n"); |
| 516 | l += snprintf(buf + l, len - l > 0 ? len - l : 0 , |
| 517 | "=================================================================\n"); |
| 518 | l += snprintf(buf + l, len - l > 0 ? len - l : 0 , "%-16s\t %-16s %-16s %-16s\n", |
| 519 | "Endpoint", "Fence Ref Count", "Temp Window Ref Count", "DMA CHANNEL"); |
| 520 | spin_lock_irqsave(&ms_info.mi_connlock, sflags); |
| 521 | list_for_each(pos, &ms_info.mi_connected) { |
| 522 | ep = list_entry(pos, struct endpt, list); |
| 523 | l += snprintf(buf + l, len - l > 0 ? len - l : 0 , "%-16p\t%-16d %-16d %-16d\n", |
| 524 | ep, ep->rma_info.fence_refcount, |
| 525 | atomic_read(&ep->rma_info.tw_refcount), |
| 526 | ep->rma_info.dma_chan ? get_chan_num(ep->rma_info.dma_chan): -1); |
| 527 | } |
| 528 | spin_unlock_irqrestore(&ms_info.mi_connlock, sflags); |
| 529 | |
| 530 | *eof = 1; |
| 531 | return l; |
| 532 | } |
| 533 | |
| 534 | /* Place Holder for generic SCIF debug information */ |
| 535 | static int |
| 536 | scif_debug_read(char *buf, char **start, off_t offset, int len, int *eof, void *data) |
| 537 | { |
| 538 | int l = 0; |
| 539 | |
| 540 | l += snprintf(buf + l, len - l > 0 ? len - l : 0, |
| 541 | "Num gtt_entries %d\n", ms_info.nr_gtt_entries); |
| 542 | /* |
| 543 | * Tracking the number of zombies for debug. |
| 544 | * Need to make sure they are not being left behind forever. |
| 545 | */ |
| 546 | l += snprintf(buf + l, len - l > 0 ? len - l : 0, |
| 547 | "Num Zombie Endpoints %d\n", ms_info.mi_nr_zombies); |
| 548 | |
| 549 | l += snprintf(buf + l, len - l > 0 ? len - l : 0, |
| 550 | "Watchdog timeout %d\n", ms_info.mi_watchdog_to); |
| 551 | |
| 552 | l += snprintf(buf + l, len - l > 0 ? len - l : 0, |
| 553 | "Watchdog enabled %d\n", ms_info.mi_watchdog_enabled); |
| 554 | |
| 555 | l += snprintf(buf + l, len - l > 0 ? len - l : 0, |
| 556 | "Watchdog auto reboot %d\n", ms_info.mi_watchdog_auto_reboot); |
| 557 | |
| 558 | l += snprintf(buf + l, len - l > 0 ? len - l : 0, |
| 559 | "Huge Pages Enabled %d Detected 2mb %lld 4k %lld\n", |
| 560 | mic_huge_page_enable, ms_info.nr_2mb_pages, ms_info.nr_4k_pages); |
| 561 | #ifdef RMA_DEBUG |
| 562 | l += snprintf(buf + l, len - l > 0 ? len - l : 0, |
| 563 | "mm ref cnt %ld rma_alloc_cnt %ld rma_pin_cnt %ld mmu_notif %ld rma_unaligned_cpu_cnt %ld\n", |
| 564 | atomic_long_read(&ms_info.rma_mm_cnt), |
| 565 | atomic_long_read(&ms_info.rma_alloc_cnt), |
| 566 | atomic_long_read(&ms_info.rma_pin_cnt), |
| 567 | atomic_long_read(&ms_info.mmu_notif_cnt), |
| 568 | atomic_long_read(&ms_info.rma_unaligned_cpu_cnt)); |
| 569 | #endif |
| 570 | l += snprintf(buf + l, len - l > 0 ? len - l : 0, |
| 571 | "List empty? mi_uaccept %d mi_listen %d mi_zombie %d " |
| 572 | "mi_connected %d mi_disconnected %d\n", |
| 573 | list_empty(&ms_info.mi_uaccept), |
| 574 | list_empty(&ms_info.mi_listen), |
| 575 | list_empty(&ms_info.mi_zombie), |
| 576 | list_empty(&ms_info.mi_connected), |
| 577 | list_empty(&ms_info.mi_disconnected)); |
| 578 | |
| 579 | *eof = 1; |
| 580 | return l; |
| 581 | } |
| 582 | |
| 583 | static int |
| 584 | scif_dev_info(char *buf, char **start, off_t offset, int len, int *eof, void *data) |
| 585 | { |
| 586 | int l = 0; |
| 587 | int node; |
| 588 | |
| 589 | #ifdef _MIC_SCIF_ |
| 590 | micscif_get_node_info(); |
| 591 | |
| 592 | mutex_lock(&ms_info.mi_conflock); |
| 593 | #endif |
| 594 | l += snprintf(buf + l, len - l > 0 ? len - l : 0, |
| 595 | "Total Nodes %d Self Node Id %d Maxid %d\n", |
| 596 | ms_info.mi_total, ms_info.mi_nodeid, ms_info.mi_maxid); |
| 597 | |
| 598 | l += snprintf(buf + l, len - l > 0 ? len - l : 0 , |
| 599 | "%-16s\t%-16s %-16s\t%-16s\t%-8s\t%-8s\t%-8s\n", |
| 600 | "node_id", "state", "scif_ref_cnt", "scif_map_ref_cnt", |
| 601 | "wait_status", "conn count", "numa_node"); |
| 602 | |
| 603 | for (node = 0; node <= ms_info.mi_maxid; node++) |
| 604 | l += snprintf(buf + l, len - l > 0 ? len - l : 0, |
| 605 | "%-16d\t%-16s\t0x%-16lx\t%-16d\t%-16lld\t%-16d\t%-16d\n", |
| 606 | scif_dev[node].sd_node, scifdev_state[scif_dev[node].sd_state], |
| 607 | atomic_long_read(&scif_dev[node].scif_ref_cnt), |
| 608 | scif_dev[node].scif_map_ref_cnt, |
| 609 | scif_dev[node].sd_wait_status, |
| 610 | scif_dev[node].num_active_conn, |
| 611 | scif_dev[node].sd_numa_node); |
| 612 | #ifdef _MIC_SCIF_ |
| 613 | mutex_unlock(&ms_info.mi_conflock); |
| 614 | #endif |
| 615 | |
| 616 | *eof = 1; |
| 617 | return l; |
| 618 | } |
| 619 | |
| 620 | static int |
| 621 | scif_suspend(char *buf, char **start, off_t offset, int len, int *eof, void *data) |
| 622 | { |
| 623 | int l = 0; |
| 624 | |
| 625 | #ifdef _MIC_SCIF_ |
| 626 | micscif_suspend_handler(NULL, 0, NULL); |
| 627 | #else |
| 628 | { |
| 629 | int node; |
| 630 | uint64_t ret; |
| 631 | l += snprintf(buf + l, len - l > 0 ? len - l : 0, |
| 632 | "Removing Nodes mask 0x7\n"); |
| 633 | for (node = 1; node < ms_info.mi_total; node++) { |
| 634 | ret = micscif_disconnect_node(node, 0 , 1); |
| 635 | l += snprintf(buf + l, len - l > 0 ? len - l : 0, |
| 636 | "Node %d requested disconnect. ret = %lld\n", |
| 637 | node, ret); |
| 638 | } |
| 639 | } |
| 640 | #endif |
| 641 | |
| 642 | *eof = 1; |
| 643 | return l; |
| 644 | } |
| 645 | |
| 646 | #ifdef _MIC_SCIF_ |
| 647 | static int |
| 648 | scif_crash(char *buf, char **start, off_t offset, int len, int *eof, void *data) |
| 649 | { |
| 650 | int l = 0; |
| 651 | l += snprintf(buf + l, len - l > 0 ? len - l : 0, |
| 652 | "%s %d Crash the Card to test Lost Nodes\n", __func__, __LINE__); |
| 653 | panic("Test Lost Node! Crash the card intentionally\n"); |
| 654 | *eof = 1; |
| 655 | return l; |
| 656 | } |
| 657 | |
| 658 | static int |
| 659 | scif_bugon(char *buf, char **start, off_t offset, int len, int *eof, void *data) |
| 660 | { |
| 661 | int l = 0; |
| 662 | l += snprintf(buf + l, len - l > 0 ? len - l : 0, |
| 663 | "%s %d Bug on the Card to test Lost Nodes\n", __func__, __LINE__); |
| 664 | BUG_ON(1); |
| 665 | *eof = 1; |
| 666 | return l; |
| 667 | } |
| 668 | #endif |
| 669 | |
| 670 | static int |
| 671 | scif_fail_suspend(char *buf, char **start, off_t offset, int len, int *eof, void *data) |
| 672 | { |
| 673 | int l = 0; |
| 674 | |
| 675 | #ifdef _MIC_SCIF_ |
| 676 | micscif_fail_suspend_handler(NULL, 0, NULL); |
| 677 | l += snprintf(buf + l, len - l > 0 ? len - l : 0, |
| 678 | "Failing Suspend\n"); |
| 679 | #endif |
| 680 | |
| 681 | *eof = 1; |
| 682 | return l; |
| 683 | } |
| 684 | |
| 685 | static int |
| 686 | scif_resume(char *buf, char **start, off_t offset, int len, int *eof, void *data) |
| 687 | { |
| 688 | int l = 0; |
| 689 | |
| 690 | #ifdef _MIC_SCIF_ |
| 691 | micscif_resume_handler(NULL, 0, NULL); |
| 692 | l += snprintf(buf + l, len - l > 0 ? len - l : 0, |
| 693 | "Resuming/Waking up node\n"); |
| 694 | #endif |
| 695 | |
| 696 | *eof = 1; |
| 697 | return l; |
| 698 | } |
| 699 | |
| 700 | static int |
| 701 | scif_get_reg_cache_limit(char *buf, char **start, off_t offset, int len, int *eof, void *data) |
| 702 | { |
| 703 | int l = 0; |
| 704 | |
| 705 | l += snprintf(buf + l, len - l > 0 ? len - l : 0 , |
| 706 | "reg_cache_limit = 0x%lx\n", ms_info.mi_rma_tc_limit); |
| 707 | *eof = 1; |
| 708 | return l; |
| 709 | } |
| 710 | |
| 711 | static int |
| 712 | scif_set_reg_cache_limit(struct file *file, const char __user *buffer, |
| 713 | unsigned long len, void *unused) |
| 714 | { |
| 715 | unsigned long data = 0; |
| 716 | char *p; |
| 717 | if (!(p = kzalloc(len, GFP_KERNEL))) |
| 718 | return -ENOMEM; |
| 719 | if (copy_from_user(p, buffer, len)) |
| 720 | return -EFAULT; |
| 721 | data = simple_strtoul(p, NULL, 0); |
| 722 | ms_info.mi_rma_tc_limit = data; |
| 723 | return len; |
| 724 | } |
| 725 | #endif |
| 726 | |
| 727 | #ifdef _MIC_SCIF_ |
| 728 | static int smpt_seq_show(struct seq_file *s, void *pos) |
| 729 | { |
| 730 | volatile uint8_t *mm_sbox = scif_dev[SCIF_HOST_NODE].mm_sbox; |
| 731 | uint32_t smpt_reg_offset = SBOX_SMPT00; |
| 732 | uint32_t smpt_reg_val; |
| 733 | int i; |
| 734 | |
| 735 | seq_printf(s, |
| 736 | "=================================================================\n"); |
| 737 | seq_printf(s,"%-11s| %-15s %-14s %-5s \n", |
| 738 | "SMPT entry", "SMPT reg value", "DMA addr", "SNOOP"); |
| 739 | seq_printf(s, |
| 740 | "=================================================================\n"); |
| 741 | |
| 742 | for (i = 0; i < NUM_SMPT_ENTRIES_IN_USE; i++) { |
| 743 | smpt_reg_val = readl(mm_sbox + smpt_reg_offset); |
| 744 | seq_printf(s,"%-11d| %-#15x %-#14llx %-5s \n", |
| 745 | i, smpt_reg_val, ((uint64_t)smpt_reg_val >> 2ULL) << MIC_SYSTEM_PAGE_SHIFT, |
| 746 | (smpt_reg_val & 0x1) ? "OFF" : "ON"); |
| 747 | smpt_reg_offset += 4; |
| 748 | } |
| 749 | |
| 750 | seq_printf(s, |
| 751 | "=================================================================\n"); |
| 752 | return 0; |
| 753 | } |
| 754 | |
| 755 | #else |
| 756 | static int smpt_seq_show(struct seq_file *s, void *pos) |
| 757 | { |
| 758 | uint64_t bid = (uint64_t)s->private; |
| 759 | mic_ctx_t *mic_ctx; |
| 760 | int i; |
| 761 | unsigned long flags; |
| 762 | |
| 763 | mic_ctx = get_per_dev_ctx(bid); |
| 764 | seq_printf(s, |
| 765 | "=================================================================\n"); |
| 766 | seq_printf(s,"Board %-2d |%-10s| %-14s %-10s \n", |
| 767 | (int)bid + 1, "SMPT entry", "DMA addr", "Reference Count"); |
| 768 | seq_printf(s, |
| 769 | "=================================================================\n"); |
| 770 | |
| 771 | if (mic_ctx && mic_ctx->mic_smpt) { |
| 772 | spin_lock_irqsave(&mic_ctx->smpt_lock, flags); |
| 773 | for (i = 0; i < NUM_SMPT_ENTRIES_IN_USE; i++) { |
| 774 | seq_printf(s,"%9s|%-10d| %-#14llx %-10lld \n", |
| 775 | " ", i, mic_ctx->mic_smpt[i].dma_addr, mic_ctx->mic_smpt[i].ref_count); |
| 776 | } |
| 777 | spin_unlock_irqrestore(&mic_ctx->smpt_lock, flags); |
| 778 | } |
| 779 | |
| 780 | seq_printf(s, |
| 781 | "================================================================X\n"); |
| 782 | return 0; |
| 783 | } |
| 784 | #endif |
| 785 | |
| 786 | static int smpt_debug_open(struct inode *inode, struct file *file) |
| 787 | { |
| 788 | return single_open(file, smpt_seq_show, inode->i_private); |
| 789 | } |
| 790 | |
| 791 | static int smpt_debug_release(struct inode *inode, struct file *file) |
| 792 | { |
| 793 | return single_release(inode, file); |
| 794 | } |
| 795 | |
| 796 | static struct file_operations smpt_file_ops = { |
| 797 | .owner = THIS_MODULE, |
| 798 | .open = smpt_debug_open, |
| 799 | .read = seq_read, |
| 800 | .llseek = seq_lseek, |
| 801 | .release = smpt_debug_release |
| 802 | }; |
| 803 | |
| 804 | #ifndef _MIC_SCIF_ |
| 805 | static int log_buf_seq_show(struct seq_file *s, void *pos) |
| 806 | { |
| 807 | uint64_t bid = (uint64_t)s->private; |
| 808 | mic_ctx_t *mic_ctx; |
| 809 | void *log_buf_len_va, *log_buf_va; |
| 810 | struct micscif_dev *dev; |
| 811 | |
| 812 | mic_ctx = get_per_dev_ctx(bid); |
| 813 | if (!mic_ctx || !mic_ctx->log_buf_addr || !mic_ctx->log_buf_len) |
| 814 | goto done; |
| 815 | |
| 816 | if (mic_ctx->bi_family == FAMILY_ABR) { |
| 817 | seq_printf(s, "log buffer display not supported for KNF\n"); |
| 818 | goto done; |
| 819 | } |
| 820 | |
| 821 | dev = &scif_dev[mic_get_scifnode_id(mic_ctx)]; |
| 822 | log_buf_len_va = virt_to_phys(mic_ctx->log_buf_len) + mic_ctx->aper.va; |
| 823 | log_buf_va = virt_to_phys(mic_ctx->log_buf_addr) + mic_ctx->aper.va; |
| 824 | |
| 825 | mutex_lock(&mic_ctx->state_lock); |
| 826 | switch (mic_ctx->state) { |
| 827 | case MIC_BOOT: |
| 828 | case MIC_BOOTFAIL: |
| 829 | case MIC_ONLINE: |
| 830 | case MIC_SHUTDOWN: |
| 831 | case MIC_LOST: |
| 832 | micscif_inc_node_refcnt(dev, 1); |
| 833 | seq_write(s, log_buf_va, *(int*)log_buf_len_va); |
| 834 | micscif_dec_node_refcnt(dev, 1); |
| 835 | break; |
| 836 | case MIC_NORESPONSE: |
| 837 | case MIC_READY: |
| 838 | /* Cannot access GDDR while reset is ongoing */ |
| 839 | case MIC_RESET: |
| 840 | case MIC_RESETFAIL: |
| 841 | case MIC_INVALID: |
| 842 | default: |
| 843 | break; |
| 844 | } |
| 845 | mutex_unlock(&mic_ctx->state_lock); |
| 846 | done: |
| 847 | return 0; |
| 848 | } |
| 849 | |
| 850 | static int log_buf_open(struct inode *inode, struct file *file) |
| 851 | { |
| 852 | return single_open(file, log_buf_seq_show, inode->i_private); |
| 853 | } |
| 854 | |
| 855 | static int log_buf_release(struct inode *inode, struct file *file) |
| 856 | { |
| 857 | return single_release(inode, file); |
| 858 | } |
| 859 | |
| 860 | static struct file_operations log_buf_ops = { |
| 861 | .owner = THIS_MODULE, |
| 862 | .open = log_buf_open, |
| 863 | .read = seq_read, |
| 864 | .llseek = seq_lseek, |
| 865 | .release = log_buf_release |
| 866 | }; |
| 867 | #endif |
| 868 | |
| 869 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)) |
| 870 | void |
| 871 | scif_proc_init(void) |
| 872 | { |
| 873 | if ((scif_proc = proc_mkdir("scif", NULL)) != NULL) { |
| 874 | proc_create_data("ep", 0444, scif_proc, &scif_ep_fops, NULL); |
| 875 | proc_create_data("rma_window", 0444, scif_proc, &scif_rma_window_fops, NULL); |
| 876 | proc_create_data("rma_xfer", 0444, scif_proc, &scif_rma_xfer_fops, NULL); |
| 877 | proc_create_data("scif_dev", 0444, scif_proc, &scif_dev_fops, NULL); |
| 878 | proc_create_data("debug", 0444, scif_proc, &scif_debug_fops, NULL); |
| 879 | proc_create_data("suspend", 0444, scif_proc, &scif_suspend_fops, NULL); |
| 880 | proc_create("reg_cache_limit", S_IFREG | S_IRUGO | S_IWUGO, scif_proc, |
| 881 | &scif_cache_limit_fops); |
| 882 | } |
| 883 | } |
| 884 | #else |
| 885 | void |
| 886 | scif_proc_init(void) |
| 887 | { |
| 888 | struct proc_dir_entry *reg_cache_limit_entry; |
| 889 | struct proc_dir_entry *ep_entry; |
| 890 | |
| 891 | if ((scif_proc = create_proc_entry("scif", S_IFDIR | S_IRUGO, NULL)) != NULL) { |
| 892 | create_proc_read_entry("rma_window", 0444, scif_proc, scif_rma_window_read, NULL); |
| 893 | create_proc_read_entry("rma_xfer", 0444, scif_proc, scif_rma_xfer_read, NULL); |
| 894 | create_proc_read_entry("scif_dev", 0444, scif_proc, scif_dev_info, NULL); |
| 895 | create_proc_read_entry("debug", 0444, scif_proc, scif_debug_read, NULL); |
| 896 | create_proc_read_entry("suspend", 0444, scif_proc, scif_suspend, NULL); |
| 897 | create_proc_read_entry("fail_suspend", 0444, scif_proc, scif_fail_suspend, NULL); |
| 898 | create_proc_read_entry("resume", 0444, scif_proc, scif_resume, NULL); |
| 899 | #ifdef _MIC_SCIF_ |
| 900 | create_proc_read_entry("crash", 0444, scif_proc, scif_crash, NULL); |
| 901 | create_proc_read_entry("bugon", 0444, scif_proc, scif_bugon, NULL); |
| 902 | #endif |
| 903 | if ((reg_cache_limit_entry = create_proc_entry("reg_cache_limit", S_IFREG | S_IRUGO | S_IWUGO, scif_proc))) { |
| 904 | reg_cache_limit_entry->write_proc = scif_set_reg_cache_limit; |
| 905 | reg_cache_limit_entry->read_proc = scif_get_reg_cache_limit; |
| 906 | reg_cache_limit_entry->data = NULL; |
| 907 | } |
| 908 | if ((ep_entry = create_proc_entry("ep", S_IFREG | S_IRUGO | S_IWUGO, scif_proc))) { |
| 909 | ep_entry->proc_fops = &scif_ep_fops; |
| 910 | } |
| 911 | |
| 912 | |
| 913 | } |
| 914 | } |
| 915 | #endif // LINUX VERSION |
| 916 | |
| 917 | #ifdef _MIC_SCIF_ |
| 918 | void |
| 919 | mic_debug_init(void) |
| 920 | { |
| 921 | if ((mic_debug = debugfs_create_dir("mic_debug", NULL))) { |
| 922 | debugfs_create_file("smpt", 0444, mic_debug, NULL, &smpt_file_ops); |
| 923 | debugfs_create_u8("enable_msg_logging", 0666, mic_debug, &(ms_info.en_msg_log)); |
| 924 | } |
| 925 | } |
| 926 | #else |
| 927 | void |
| 928 | mic_debug_init(mic_ctx_t *mic_ctx) |
| 929 | { |
| 930 | char name[DEBUG_LEN]; |
| 931 | uint64_t id = mic_ctx->bi_id; |
| 932 | struct dentry *child; |
| 933 | |
| 934 | if (!mic_debug) |
| 935 | mic_debug = debugfs_create_dir("mic_debug", NULL); |
| 936 | |
| 937 | if (mic_debug) { |
| 938 | snprintf(name, DEBUG_LEN, "mic%d", (int)id); |
| 939 | if ((child = debugfs_create_dir(name, mic_debug))) { |
| 940 | debugfs_create_file("smpt", 0444, child, (void*)id, &smpt_file_ops); |
| 941 | debugfs_create_file("log_buf", 0444, child, (void*)id, &log_buf_ops); |
| 942 | } |
| 943 | debugfs_create_u8("enable_msg_logging", 0666, mic_debug, &(ms_info.en_msg_log)); |
| 944 | } |
| 945 | } |
| 946 | #endif |
| 947 | |
| 948 | void |
| 949 | mic_debug_uninit(void) |
| 950 | { |
| 951 | debugfs_remove_recursive(mic_debug); |
| 952 | } |
| 953 | |
| 954 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)) |
| 955 | void |
| 956 | scif_proc_cleanup(void) |
| 957 | { |
| 958 | if (scif_proc) |
| 959 | remove_proc_subtree("scif", NULL); |
| 960 | } |
| 961 | #else |
| 962 | void |
| 963 | scif_proc_cleanup(void) |
| 964 | { |
| 965 | if (scif_proc) { |
| 966 | remove_proc_entry("reg_cache_limit", scif_proc); |
| 967 | remove_proc_entry("ep", scif_proc); |
| 968 | remove_proc_entry("rma_window", scif_proc); |
| 969 | remove_proc_entry("rma_xfer", scif_proc); |
| 970 | remove_proc_entry("scif_dev", scif_proc); |
| 971 | remove_proc_entry("debug", scif_proc); |
| 972 | remove_proc_entry("suspend", scif_proc); |
| 973 | remove_proc_entry("fail_suspend", scif_proc); |
| 974 | remove_proc_entry("resume", scif_proc); |
| 975 | #ifdef _MIC_SCIF_ |
| 976 | remove_proc_entry("crash", scif_proc); |
| 977 | remove_proc_entry("bugon", scif_proc); |
| 978 | #endif |
| 979 | remove_proc_entry("scif", NULL); |
| 980 | scif_proc = NULL; |
| 981 | } |
| 982 | } |
| 983 | #endif |
| 984 | |
| 985 | #ifdef _MIC_SCIF_ |
| 986 | extern int micscif_max_msg_id; |
| 987 | |
| 988 | /* |
| 989 | * Test entry point for error injection |
| 990 | */ |
| 991 | int |
| 992 | micscif_error_inject(int scenario) |
| 993 | { |
| 994 | switch (scenario) { |
| 995 | case 1: |
| 996 | micscif_max_msg_id = 0; |
| 997 | break; |
| 998 | default: |
| 999 | pr_debug("Illegal error injection scenario %d\n", scenario); |
| 1000 | return -EINVAL; |
| 1001 | } |
| 1002 | return 0; |
| 1003 | } |
| 1004 | EXPORT_SYMBOL(micscif_error_inject); |
| 1005 | #endif // _MIC_SCIF_ |