~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to drivers/scsi/qla2xxx/qla_dfs.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * QLogic Fibre Channel HBA Driver
 
3
 * Copyright (c)  2003-2011 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_fce_show(struct seq_file *s, void *unused)
 
17
{
 
18
        scsi_qla_host_t *vha = s->private;
 
19
        uint32_t cnt;
 
20
        uint32_t *fce;
 
21
        uint64_t fce_start;
 
22
        struct qla_hw_data *ha = vha->hw;
 
23
 
 
24
        mutex_lock(&ha->fce_mutex);
 
25
 
 
26
        seq_printf(s, "FCE Trace Buffer\n");
 
27
        seq_printf(s, "In Pointer = %llx\n\n", (unsigned long long)ha->fce_wr);
 
28
        seq_printf(s, "Base = %llx\n\n", (unsigned long long) ha->fce_dma);
 
29
        seq_printf(s, "FCE Enable Registers\n");
 
30
        seq_printf(s, "%08x %08x %08x %08x %08x %08x\n",
 
31
            ha->fce_mb[0], ha->fce_mb[2], ha->fce_mb[3], ha->fce_mb[4],
 
32
            ha->fce_mb[5], ha->fce_mb[6]);
 
33
 
 
34
        fce = (uint32_t *) ha->fce;
 
35
        fce_start = (unsigned long long) ha->fce_dma;
 
36
        for (cnt = 0; cnt < fce_calc_size(ha->fce_bufs) / 4; cnt++) {
 
37
                if (cnt % 8 == 0)
 
38
                        seq_printf(s, "\n%llx: ",
 
39
                            (unsigned long long)((cnt * 4) + fce_start));
 
40
                else
 
41
                        seq_printf(s, " ");
 
42
                seq_printf(s, "%08x", *fce++);
 
43
        }
 
44
 
 
45
        seq_printf(s, "\nEnd\n");
 
46
 
 
47
        mutex_unlock(&ha->fce_mutex);
 
48
 
 
49
        return 0;
 
50
}
 
51
 
 
52
static int
 
53
qla2x00_dfs_fce_open(struct inode *inode, struct file *file)
 
54
{
 
55
        scsi_qla_host_t *vha = inode->i_private;
 
56
        struct qla_hw_data *ha = vha->hw;
 
57
        int rval;
 
58
 
 
59
        if (!ha->flags.fce_enabled)
 
60
                goto out;
 
61
 
 
62
        mutex_lock(&ha->fce_mutex);
 
63
 
 
64
        /* Pause tracing to flush FCE buffers. */
 
65
        rval = qla2x00_disable_fce_trace(vha, &ha->fce_wr, &ha->fce_rd);
 
66
        if (rval)
 
67
                ql_dbg(ql_dbg_user, vha, 0x705c,
 
68
                    "DebugFS: Unable to disable FCE (%d).\n", rval);
 
69
 
 
70
        ha->flags.fce_enabled = 0;
 
71
 
 
72
        mutex_unlock(&ha->fce_mutex);
 
73
out:
 
74
        return single_open(file, qla2x00_dfs_fce_show, vha);
 
75
}
 
76
 
 
77
static int
 
78
qla2x00_dfs_fce_release(struct inode *inode, struct file *file)
 
79
{
 
80
        scsi_qla_host_t *vha = inode->i_private;
 
81
        struct qla_hw_data *ha = vha->hw;
 
82
        int rval;
 
83
 
 
84
        if (ha->flags.fce_enabled)
 
85
                goto out;
 
86
 
 
87
        mutex_lock(&ha->fce_mutex);
 
88
 
 
89
        /* Re-enable FCE tracing. */
 
90
        ha->flags.fce_enabled = 1;
 
91
        memset(ha->fce, 0, fce_calc_size(ha->fce_bufs));
 
92
        rval = qla2x00_enable_fce_trace(vha, ha->fce_dma, ha->fce_bufs,
 
93
            ha->fce_mb, &ha->fce_bufs);
 
94
        if (rval) {
 
95
                ql_dbg(ql_dbg_user, vha, 0x700d,
 
96
                    "DebugFS: Unable to reinitialize FCE (%d).\n", rval);
 
97
                ha->flags.fce_enabled = 0;
 
98
        }
 
99
 
 
100
        mutex_unlock(&ha->fce_mutex);
 
101
out:
 
102
        return single_release(inode, file);
 
103
}
 
104
 
 
105
static const struct file_operations dfs_fce_ops = {
 
106
        .open           = qla2x00_dfs_fce_open,
 
107
        .read           = seq_read,
 
108
        .llseek         = seq_lseek,
 
109
        .release        = qla2x00_dfs_fce_release,
 
110
};
 
111
 
 
112
int
 
113
qla2x00_dfs_setup(scsi_qla_host_t *vha)
 
114
{
 
115
        struct qla_hw_data *ha = vha->hw;
 
116
 
 
117
        if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha))
 
118
                goto out;
 
119
        if (!ha->fce)
 
120
                goto out;
 
121
 
 
122
        if (qla2x00_dfs_root)
 
123
                goto create_dir;
 
124
 
 
125
        atomic_set(&qla2x00_dfs_root_count, 0);
 
126
        qla2x00_dfs_root = debugfs_create_dir(QLA2XXX_DRIVER_NAME, NULL);
 
127
        if (!qla2x00_dfs_root) {
 
128
                ql_log(ql_log_warn, vha, 0x00f7,
 
129
                    "Unable to create debugfs root directory.\n");
 
130
                goto out;
 
131
        }
 
132
 
 
133
create_dir:
 
134
        if (ha->dfs_dir)
 
135
                goto create_nodes;
 
136
 
 
137
        mutex_init(&ha->fce_mutex);
 
138
        ha->dfs_dir = debugfs_create_dir(vha->host_str, qla2x00_dfs_root);
 
139
        if (!ha->dfs_dir) {
 
140
                ql_log(ql_log_warn, vha, 0x00f8,
 
141
                    "Unable to create debugfs ha directory.\n");
 
142
                goto out;
 
143
        }
 
144
 
 
145
        atomic_inc(&qla2x00_dfs_root_count);
 
146
 
 
147
create_nodes:
 
148
        ha->dfs_fce = debugfs_create_file("fce", S_IRUSR, ha->dfs_dir, vha,
 
149
            &dfs_fce_ops);
 
150
        if (!ha->dfs_fce) {
 
151
                ql_log(ql_log_warn, vha, 0x00f9,
 
152
                    "Unable to create debugfs fce node.\n");
 
153
                goto out;
 
154
        }
 
155
out:
 
156
        return 0;
 
157
}
 
158
 
 
159
int
 
160
qla2x00_dfs_remove(scsi_qla_host_t *vha)
 
161
{
 
162
        struct qla_hw_data *ha = vha->hw;
 
163
        if (ha->dfs_fce) {
 
164
                debugfs_remove(ha->dfs_fce);
 
165
                ha->dfs_fce = NULL;
 
166
        }
 
167
 
 
168
        if (ha->dfs_dir) {
 
169
                debugfs_remove(ha->dfs_dir);
 
170
                ha->dfs_dir = NULL;
 
171
                atomic_dec(&qla2x00_dfs_root_count);
 
172
        }
 
173
 
 
174
        if (atomic_read(&qla2x00_dfs_root_count) == 0 &&
 
175
            qla2x00_dfs_root) {
 
176
                debugfs_remove(qla2x00_dfs_root);
 
177
                qla2x00_dfs_root = NULL;
 
178
        }
 
179
 
 
180
        return 0;
 
181
}