root/drivers/scsi/qla2xxx/qla_dfs.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. qla2x00_dfs_tgt_sess_show
  2. qla2x00_dfs_tgt_sess_open
  3. qla2x00_dfs_tgt_port_database_show
  4. qla2x00_dfs_tgt_port_database_open
  5. qla_dfs_fw_resource_cnt_show
  6. qla_dfs_fw_resource_cnt_open
  7. qla_dfs_tgt_counters_show
  8. qla_dfs_tgt_counters_open
  9. qla2x00_dfs_fce_show
  10. qla2x00_dfs_fce_open
  11. qla2x00_dfs_fce_release
  12. qla_dfs_naqp_show
  13. qla_dfs_naqp_open
  14. qla_dfs_naqp_write
  15. qla2x00_dfs_setup
  16. qla2x00_dfs_remove

   1 /*
   2  * QLogic Fibre Channel HBA Driver
   3  * Copyright (c)  2003-2014 QLogic Corporation
   4  *
   5  * See LICENSE.qla2xxx for copyright and licensing details.
   6  */
   7 #include "qla_def.h"
   8 
   9 #include <linux/debugfs.h>
  10 #include <linux/seq_file.h>
  11 
  12 static struct dentry *qla2x00_dfs_root;
  13 static atomic_t qla2x00_dfs_root_count;
  14 
  15 static int
  16 qla2x00_dfs_tgt_sess_show(struct seq_file *s, void *unused)
  17 {
  18         scsi_qla_host_t *vha = s->private;
  19         struct qla_hw_data *ha = vha->hw;
  20         unsigned long flags;
  21         struct fc_port *sess = NULL;
  22         struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
  23 
  24         seq_printf(s, "%s\n", vha->host_str);
  25         if (tgt) {
  26                 seq_puts(s, "Port ID   Port Name                Handle\n");
  27 
  28                 spin_lock_irqsave(&ha->tgt.sess_lock, flags);
  29                 list_for_each_entry(sess, &vha->vp_fcports, list)
  30                         seq_printf(s, "%02x:%02x:%02x  %8phC  %d\n",
  31                             sess->d_id.b.domain, sess->d_id.b.area,
  32                             sess->d_id.b.al_pa, sess->port_name,
  33                             sess->loop_id);
  34                 spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
  35         }
  36 
  37         return 0;
  38 }
  39 
  40 static int
  41 qla2x00_dfs_tgt_sess_open(struct inode *inode, struct file *file)
  42 {
  43         scsi_qla_host_t *vha = inode->i_private;
  44 
  45         return single_open(file, qla2x00_dfs_tgt_sess_show, vha);
  46 }
  47 
  48 static const struct file_operations dfs_tgt_sess_ops = {
  49         .open           = qla2x00_dfs_tgt_sess_open,
  50         .read           = seq_read,
  51         .llseek         = seq_lseek,
  52         .release        = single_release,
  53 };
  54 
  55 static int
  56 qla2x00_dfs_tgt_port_database_show(struct seq_file *s, void *unused)
  57 {
  58         scsi_qla_host_t *vha = s->private;
  59         struct qla_hw_data *ha = vha->hw;
  60         struct gid_list_info *gid_list, *gid;
  61         dma_addr_t gid_list_dma;
  62         fc_port_t fc_port;
  63         int rc, i;
  64         uint16_t entries, loop_id;
  65         struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
  66 
  67         seq_printf(s, "%s\n", vha->host_str);
  68         if (tgt) {
  69                 gid_list = dma_alloc_coherent(&ha->pdev->dev,
  70                     qla2x00_gid_list_size(ha),
  71                     &gid_list_dma, GFP_KERNEL);
  72                 if (!gid_list) {
  73                         ql_dbg(ql_dbg_user, vha, 0x7018,
  74                             "DMA allocation failed for %u\n",
  75                              qla2x00_gid_list_size(ha));
  76                         return 0;
  77                 }
  78 
  79                 rc = qla24xx_gidlist_wait(vha, gid_list, gid_list_dma,
  80                     &entries);
  81                 if (rc != QLA_SUCCESS)
  82                         goto out_free_id_list;
  83 
  84                 gid = gid_list;
  85 
  86                 seq_puts(s, "Port Name  Port ID         Loop ID\n");
  87 
  88                 for (i = 0; i < entries; i++) {
  89                         loop_id = le16_to_cpu(gid->loop_id);
  90                         memset(&fc_port, 0, sizeof(fc_port_t));
  91 
  92                         fc_port.loop_id = loop_id;
  93 
  94                         rc = qla24xx_gpdb_wait(vha, &fc_port, 0);
  95                         seq_printf(s, "%8phC  %02x%02x%02x  %d\n",
  96                                 fc_port.port_name, fc_port.d_id.b.domain,
  97                                 fc_port.d_id.b.area, fc_port.d_id.b.al_pa,
  98                                 fc_port.loop_id);
  99                         gid = (void *)gid + ha->gid_list_info_size;
 100                 }
 101 out_free_id_list:
 102                 dma_free_coherent(&ha->pdev->dev, qla2x00_gid_list_size(ha),
 103                     gid_list, gid_list_dma);
 104         }
 105 
 106         return 0;
 107 }
 108 
 109 static int
 110 qla2x00_dfs_tgt_port_database_open(struct inode *inode, struct file *file)
 111 {
 112         scsi_qla_host_t *vha = inode->i_private;
 113 
 114         return single_open(file, qla2x00_dfs_tgt_port_database_show, vha);
 115 }
 116 
 117 static const struct file_operations dfs_tgt_port_database_ops = {
 118         .open           = qla2x00_dfs_tgt_port_database_open,
 119         .read           = seq_read,
 120         .llseek         = seq_lseek,
 121         .release        = single_release,
 122 };
 123 
 124 static int
 125 qla_dfs_fw_resource_cnt_show(struct seq_file *s, void *unused)
 126 {
 127         struct scsi_qla_host *vha = s->private;
 128         uint16_t mb[MAX_IOCB_MB_REG];
 129         int rc;
 130 
 131         rc = qla24xx_res_count_wait(vha, mb, SIZEOF_IOCB_MB_REG);
 132         if (rc != QLA_SUCCESS) {
 133                 seq_printf(s, "Mailbox Command failed %d, mb %#x", rc, mb[0]);
 134         } else {
 135                 seq_puts(s, "FW Resource count\n\n");
 136                 seq_printf(s, "Original TGT exchg count[%d]\n", mb[1]);
 137                 seq_printf(s, "current TGT exchg count[%d]\n", mb[2]);
 138                 seq_printf(s, "original Initiator Exchange count[%d]\n", mb[3]);
 139                 seq_printf(s, "Current Initiator Exchange count[%d]\n", mb[6]);
 140                 seq_printf(s, "Original IOCB count[%d]\n", mb[7]);
 141                 seq_printf(s, "Current IOCB count[%d]\n", mb[10]);
 142                 seq_printf(s, "MAX VP count[%d]\n", mb[11]);
 143                 seq_printf(s, "MAX FCF count[%d]\n", mb[12]);
 144                 seq_printf(s, "Current free pageable XCB buffer cnt[%d]\n",
 145                     mb[20]);
 146                 seq_printf(s, "Original Initiator fast XCB buffer cnt[%d]\n",
 147                     mb[21]);
 148                 seq_printf(s, "Current free Initiator fast XCB buffer cnt[%d]\n",
 149                     mb[22]);
 150                 seq_printf(s, "Original Target fast XCB buffer cnt[%d]\n",
 151                     mb[23]);
 152 
 153         }
 154 
 155         return 0;
 156 }
 157 
 158 static int
 159 qla_dfs_fw_resource_cnt_open(struct inode *inode, struct file *file)
 160 {
 161         struct scsi_qla_host *vha = inode->i_private;
 162 
 163         return single_open(file, qla_dfs_fw_resource_cnt_show, vha);
 164 }
 165 
 166 static const struct file_operations dfs_fw_resource_cnt_ops = {
 167         .open           = qla_dfs_fw_resource_cnt_open,
 168         .read           = seq_read,
 169         .llseek         = seq_lseek,
 170         .release        = single_release,
 171 };
 172 
 173 static int
 174 qla_dfs_tgt_counters_show(struct seq_file *s, void *unused)
 175 {
 176         struct scsi_qla_host *vha = s->private;
 177         struct qla_qpair *qpair = vha->hw->base_qpair;
 178         uint64_t qla_core_sbt_cmd, core_qla_que_buf, qla_core_ret_ctio,
 179                 core_qla_snd_status, qla_core_ret_sta_ctio, core_qla_free_cmd,
 180                 num_q_full_sent, num_alloc_iocb_failed, num_term_xchg_sent;
 181         u16 i;
 182 
 183         qla_core_sbt_cmd = qpair->tgt_counters.qla_core_sbt_cmd;
 184         core_qla_que_buf = qpair->tgt_counters.core_qla_que_buf;
 185         qla_core_ret_ctio = qpair->tgt_counters.qla_core_ret_ctio;
 186         core_qla_snd_status = qpair->tgt_counters.core_qla_snd_status;
 187         qla_core_ret_sta_ctio = qpair->tgt_counters.qla_core_ret_sta_ctio;
 188         core_qla_free_cmd = qpair->tgt_counters.core_qla_free_cmd;
 189         num_q_full_sent = qpair->tgt_counters.num_q_full_sent;
 190         num_alloc_iocb_failed = qpair->tgt_counters.num_alloc_iocb_failed;
 191         num_term_xchg_sent = qpair->tgt_counters.num_term_xchg_sent;
 192 
 193         for (i = 0; i < vha->hw->max_qpairs; i++) {
 194                 qpair = vha->hw->queue_pair_map[i];
 195                 if (!qpair)
 196                         continue;
 197                 qla_core_sbt_cmd += qpair->tgt_counters.qla_core_sbt_cmd;
 198                 core_qla_que_buf += qpair->tgt_counters.core_qla_que_buf;
 199                 qla_core_ret_ctio += qpair->tgt_counters.qla_core_ret_ctio;
 200                 core_qla_snd_status += qpair->tgt_counters.core_qla_snd_status;
 201                 qla_core_ret_sta_ctio +=
 202                     qpair->tgt_counters.qla_core_ret_sta_ctio;
 203                 core_qla_free_cmd += qpair->tgt_counters.core_qla_free_cmd;
 204                 num_q_full_sent += qpair->tgt_counters.num_q_full_sent;
 205                 num_alloc_iocb_failed +=
 206                     qpair->tgt_counters.num_alloc_iocb_failed;
 207                 num_term_xchg_sent += qpair->tgt_counters.num_term_xchg_sent;
 208         }
 209 
 210         seq_puts(s, "Target Counters\n");
 211         seq_printf(s, "qla_core_sbt_cmd = %lld\n",
 212                 qla_core_sbt_cmd);
 213         seq_printf(s, "qla_core_ret_sta_ctio = %lld\n",
 214                 qla_core_ret_sta_ctio);
 215         seq_printf(s, "qla_core_ret_ctio = %lld\n",
 216                 qla_core_ret_ctio);
 217         seq_printf(s, "core_qla_que_buf = %lld\n",
 218                 core_qla_que_buf);
 219         seq_printf(s, "core_qla_snd_status = %lld\n",
 220                 core_qla_snd_status);
 221         seq_printf(s, "core_qla_free_cmd = %lld\n",
 222                 core_qla_free_cmd);
 223         seq_printf(s, "num alloc iocb failed = %lld\n",
 224                 num_alloc_iocb_failed);
 225         seq_printf(s, "num term exchange sent = %lld\n",
 226                 num_term_xchg_sent);
 227         seq_printf(s, "num Q full sent = %lld\n",
 228                 num_q_full_sent);
 229 
 230         /* DIF stats */
 231         seq_printf(s, "DIF Inp Bytes = %lld\n",
 232                 vha->qla_stats.qla_dif_stats.dif_input_bytes);
 233         seq_printf(s, "DIF Outp Bytes = %lld\n",
 234                 vha->qla_stats.qla_dif_stats.dif_output_bytes);
 235         seq_printf(s, "DIF Inp Req = %lld\n",
 236                 vha->qla_stats.qla_dif_stats.dif_input_requests);
 237         seq_printf(s, "DIF Outp Req = %lld\n",
 238                 vha->qla_stats.qla_dif_stats.dif_output_requests);
 239         seq_printf(s, "DIF Guard err = %d\n",
 240                 vha->qla_stats.qla_dif_stats.dif_guard_err);
 241         seq_printf(s, "DIF Ref tag err = %d\n",
 242                 vha->qla_stats.qla_dif_stats.dif_ref_tag_err);
 243         seq_printf(s, "DIF App tag err = %d\n",
 244                 vha->qla_stats.qla_dif_stats.dif_app_tag_err);
 245         return 0;
 246 }
 247 
 248 static int
 249 qla_dfs_tgt_counters_open(struct inode *inode, struct file *file)
 250 {
 251         struct scsi_qla_host *vha = inode->i_private;
 252 
 253         return single_open(file, qla_dfs_tgt_counters_show, vha);
 254 }
 255 
 256 static const struct file_operations dfs_tgt_counters_ops = {
 257         .open           = qla_dfs_tgt_counters_open,
 258         .read           = seq_read,
 259         .llseek         = seq_lseek,
 260         .release        = single_release,
 261 };
 262 
 263 static int
 264 qla2x00_dfs_fce_show(struct seq_file *s, void *unused)
 265 {
 266         scsi_qla_host_t *vha = s->private;
 267         uint32_t cnt;
 268         uint32_t *fce;
 269         uint64_t fce_start;
 270         struct qla_hw_data *ha = vha->hw;
 271 
 272         mutex_lock(&ha->fce_mutex);
 273 
 274         seq_puts(s, "FCE Trace Buffer\n");
 275         seq_printf(s, "In Pointer = %llx\n\n", (unsigned long long)ha->fce_wr);
 276         seq_printf(s, "Base = %llx\n\n", (unsigned long long) ha->fce_dma);
 277         seq_puts(s, "FCE Enable Registers\n");
 278         seq_printf(s, "%08x %08x %08x %08x %08x %08x\n",
 279             ha->fce_mb[0], ha->fce_mb[2], ha->fce_mb[3], ha->fce_mb[4],
 280             ha->fce_mb[5], ha->fce_mb[6]);
 281 
 282         fce = (uint32_t *) ha->fce;
 283         fce_start = (unsigned long long) ha->fce_dma;
 284         for (cnt = 0; cnt < fce_calc_size(ha->fce_bufs) / 4; cnt++) {
 285                 if (cnt % 8 == 0)
 286                         seq_printf(s, "\n%llx: ",
 287                             (unsigned long long)((cnt * 4) + fce_start));
 288                 else
 289                         seq_putc(s, ' ');
 290                 seq_printf(s, "%08x", *fce++);
 291         }
 292 
 293         seq_puts(s, "\nEnd\n");
 294 
 295         mutex_unlock(&ha->fce_mutex);
 296 
 297         return 0;
 298 }
 299 
 300 static int
 301 qla2x00_dfs_fce_open(struct inode *inode, struct file *file)
 302 {
 303         scsi_qla_host_t *vha = inode->i_private;
 304         struct qla_hw_data *ha = vha->hw;
 305         int rval;
 306 
 307         if (!ha->flags.fce_enabled)
 308                 goto out;
 309 
 310         mutex_lock(&ha->fce_mutex);
 311 
 312         /* Pause tracing to flush FCE buffers. */
 313         rval = qla2x00_disable_fce_trace(vha, &ha->fce_wr, &ha->fce_rd);
 314         if (rval)
 315                 ql_dbg(ql_dbg_user, vha, 0x705c,
 316                     "DebugFS: Unable to disable FCE (%d).\n", rval);
 317 
 318         ha->flags.fce_enabled = 0;
 319 
 320         mutex_unlock(&ha->fce_mutex);
 321 out:
 322         return single_open(file, qla2x00_dfs_fce_show, vha);
 323 }
 324 
 325 static int
 326 qla2x00_dfs_fce_release(struct inode *inode, struct file *file)
 327 {
 328         scsi_qla_host_t *vha = inode->i_private;
 329         struct qla_hw_data *ha = vha->hw;
 330         int rval;
 331 
 332         if (ha->flags.fce_enabled)
 333                 goto out;
 334 
 335         mutex_lock(&ha->fce_mutex);
 336 
 337         /* Re-enable FCE tracing. */
 338         ha->flags.fce_enabled = 1;
 339         memset(ha->fce, 0, fce_calc_size(ha->fce_bufs));
 340         rval = qla2x00_enable_fce_trace(vha, ha->fce_dma, ha->fce_bufs,
 341             ha->fce_mb, &ha->fce_bufs);
 342         if (rval) {
 343                 ql_dbg(ql_dbg_user, vha, 0x700d,
 344                     "DebugFS: Unable to reinitialize FCE (%d).\n", rval);
 345                 ha->flags.fce_enabled = 0;
 346         }
 347 
 348         mutex_unlock(&ha->fce_mutex);
 349 out:
 350         return single_release(inode, file);
 351 }
 352 
 353 static const struct file_operations dfs_fce_ops = {
 354         .open           = qla2x00_dfs_fce_open,
 355         .read           = seq_read,
 356         .llseek         = seq_lseek,
 357         .release        = qla2x00_dfs_fce_release,
 358 };
 359 
 360 static int
 361 qla_dfs_naqp_show(struct seq_file *s, void *unused)
 362 {
 363         struct scsi_qla_host *vha = s->private;
 364         struct qla_hw_data *ha = vha->hw;
 365 
 366         seq_printf(s, "%d\n", ha->tgt.num_act_qpairs);
 367         return 0;
 368 }
 369 
 370 static int
 371 qla_dfs_naqp_open(struct inode *inode, struct file *file)
 372 {
 373         struct scsi_qla_host *vha = inode->i_private;
 374 
 375         return single_open(file, qla_dfs_naqp_show, vha);
 376 }
 377 
 378 static ssize_t
 379 qla_dfs_naqp_write(struct file *file, const char __user *buffer,
 380     size_t count, loff_t *pos)
 381 {
 382         struct seq_file *s = file->private_data;
 383         struct scsi_qla_host *vha = s->private;
 384         struct qla_hw_data *ha = vha->hw;
 385         char *buf;
 386         int rc = 0;
 387         unsigned long num_act_qp;
 388 
 389         if (!(IS_QLA27XX(ha) || IS_QLA83XX(ha) || IS_QLA28XX(ha))) {
 390                 pr_err("host%ld: this adapter does not support Multi Q.",
 391                     vha->host_no);
 392                 return -EINVAL;
 393         }
 394 
 395         if (!vha->flags.qpairs_available) {
 396                 pr_err("host%ld: Driver is not setup with Multi Q.",
 397                     vha->host_no);
 398                 return -EINVAL;
 399         }
 400         buf = memdup_user_nul(buffer, count);
 401         if (IS_ERR(buf)) {
 402                 pr_err("host%ld: fail to copy user buffer.",
 403                     vha->host_no);
 404                 return PTR_ERR(buf);
 405         }
 406 
 407         num_act_qp = simple_strtoul(buf, NULL, 0);
 408 
 409         if (num_act_qp >= vha->hw->max_qpairs) {
 410                 pr_err("User set invalid number of qpairs %lu. Max = %d",
 411                     num_act_qp, vha->hw->max_qpairs);
 412                 rc = -EINVAL;
 413                 goto out_free;
 414         }
 415 
 416         if (num_act_qp != ha->tgt.num_act_qpairs) {
 417                 ha->tgt.num_act_qpairs = num_act_qp;
 418                 qlt_clr_qp_table(vha);
 419         }
 420         rc = count;
 421 out_free:
 422         kfree(buf);
 423         return rc;
 424 }
 425 
 426 static const struct file_operations dfs_naqp_ops = {
 427         .open           = qla_dfs_naqp_open,
 428         .read           = seq_read,
 429         .llseek         = seq_lseek,
 430         .release        = single_release,
 431         .write          = qla_dfs_naqp_write,
 432 };
 433 
 434 
 435 int
 436 qla2x00_dfs_setup(scsi_qla_host_t *vha)
 437 {
 438         struct qla_hw_data *ha = vha->hw;
 439 
 440         if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) &&
 441             !IS_QLA27XX(ha) && !IS_QLA28XX(ha))
 442                 goto out;
 443         if (!ha->fce)
 444                 goto out;
 445 
 446         if (qla2x00_dfs_root)
 447                 goto create_dir;
 448 
 449         atomic_set(&qla2x00_dfs_root_count, 0);
 450         qla2x00_dfs_root = debugfs_create_dir(QLA2XXX_DRIVER_NAME, NULL);
 451 
 452 create_dir:
 453         if (ha->dfs_dir)
 454                 goto create_nodes;
 455 
 456         mutex_init(&ha->fce_mutex);
 457         ha->dfs_dir = debugfs_create_dir(vha->host_str, qla2x00_dfs_root);
 458 
 459         atomic_inc(&qla2x00_dfs_root_count);
 460 
 461 create_nodes:
 462         ha->dfs_fw_resource_cnt = debugfs_create_file("fw_resource_count",
 463             S_IRUSR, ha->dfs_dir, vha, &dfs_fw_resource_cnt_ops);
 464 
 465         ha->dfs_tgt_counters = debugfs_create_file("tgt_counters", S_IRUSR,
 466             ha->dfs_dir, vha, &dfs_tgt_counters_ops);
 467 
 468         ha->tgt.dfs_tgt_port_database = debugfs_create_file("tgt_port_database",
 469             S_IRUSR,  ha->dfs_dir, vha, &dfs_tgt_port_database_ops);
 470 
 471         ha->dfs_fce = debugfs_create_file("fce", S_IRUSR, ha->dfs_dir, vha,
 472             &dfs_fce_ops);
 473 
 474         ha->tgt.dfs_tgt_sess = debugfs_create_file("tgt_sess",
 475                 S_IRUSR, ha->dfs_dir, vha, &dfs_tgt_sess_ops);
 476 
 477         if (IS_QLA27XX(ha) || IS_QLA83XX(ha) || IS_QLA28XX(ha))
 478                 ha->tgt.dfs_naqp = debugfs_create_file("naqp",
 479                     0400, ha->dfs_dir, vha, &dfs_naqp_ops);
 480 out:
 481         return 0;
 482 }
 483 
 484 int
 485 qla2x00_dfs_remove(scsi_qla_host_t *vha)
 486 {
 487         struct qla_hw_data *ha = vha->hw;
 488 
 489         if (ha->tgt.dfs_naqp) {
 490                 debugfs_remove(ha->tgt.dfs_naqp);
 491                 ha->tgt.dfs_naqp = NULL;
 492         }
 493 
 494         if (ha->tgt.dfs_tgt_sess) {
 495                 debugfs_remove(ha->tgt.dfs_tgt_sess);
 496                 ha->tgt.dfs_tgt_sess = NULL;
 497         }
 498 
 499         if (ha->tgt.dfs_tgt_port_database) {
 500                 debugfs_remove(ha->tgt.dfs_tgt_port_database);
 501                 ha->tgt.dfs_tgt_port_database = NULL;
 502         }
 503 
 504         if (ha->dfs_fw_resource_cnt) {
 505                 debugfs_remove(ha->dfs_fw_resource_cnt);
 506                 ha->dfs_fw_resource_cnt = NULL;
 507         }
 508 
 509         if (ha->dfs_tgt_counters) {
 510                 debugfs_remove(ha->dfs_tgt_counters);
 511                 ha->dfs_tgt_counters = NULL;
 512         }
 513 
 514         if (ha->dfs_fce) {
 515                 debugfs_remove(ha->dfs_fce);
 516                 ha->dfs_fce = NULL;
 517         }
 518 
 519         if (ha->dfs_dir) {
 520                 debugfs_remove(ha->dfs_dir);
 521                 ha->dfs_dir = NULL;
 522                 atomic_dec(&qla2x00_dfs_root_count);
 523         }
 524 
 525         if (atomic_read(&qla2x00_dfs_root_count) == 0 &&
 526             qla2x00_dfs_root) {
 527                 debugfs_remove(qla2x00_dfs_root);
 528                 qla2x00_dfs_root = NULL;
 529         }
 530 
 531         return 0;
 532 }

/* [<][>][^][v][top][bottom][index][help] */