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

« back to all changes in this revision

Viewing changes to drivers/scsi/lpfc/lpfc_debugfs.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
 * This file is part of the Emulex Linux Device Driver for         *
 
3
 * Fibre Channel Host Bus Adapters.                                *
 
4
 * Copyright (C) 2007-2011 Emulex.  All rights reserved.           *
 
5
 * EMULEX and SLI are trademarks of Emulex.                        *
 
6
 * www.emulex.com                                                  *
 
7
 *                                                                 *
 
8
 * This program is free software; you can redistribute it and/or   *
 
9
 * modify it under the terms of version 2 of the GNU General       *
 
10
 * Public License as published by the Free Software Foundation.    *
 
11
 * This program is distributed in the hope that it will be useful. *
 
12
 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
 
13
 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
 
14
 * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
 
15
 * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
 
16
 * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
 
17
 * more details, a copy of which can be found in the file COPYING  *
 
18
 * included with this package.                                     *
 
19
 *******************************************************************/
 
20
 
 
21
#include <linux/blkdev.h>
 
22
#include <linux/delay.h>
 
23
#include <linux/module.h>
 
24
#include <linux/dma-mapping.h>
 
25
#include <linux/idr.h>
 
26
#include <linux/interrupt.h>
 
27
#include <linux/kthread.h>
 
28
#include <linux/slab.h>
 
29
#include <linux/pci.h>
 
30
#include <linux/spinlock.h>
 
31
#include <linux/ctype.h>
 
32
 
 
33
#include <scsi/scsi.h>
 
34
#include <scsi/scsi_device.h>
 
35
#include <scsi/scsi_host.h>
 
36
#include <scsi/scsi_transport_fc.h>
 
37
 
 
38
#include "lpfc_hw4.h"
 
39
#include "lpfc_hw.h"
 
40
#include "lpfc_sli.h"
 
41
#include "lpfc_sli4.h"
 
42
#include "lpfc_nl.h"
 
43
#include "lpfc_disc.h"
 
44
#include "lpfc_scsi.h"
 
45
#include "lpfc.h"
 
46
#include "lpfc_logmsg.h"
 
47
#include "lpfc_crtn.h"
 
48
#include "lpfc_vport.h"
 
49
#include "lpfc_version.h"
 
50
#include "lpfc_compat.h"
 
51
#include "lpfc_debugfs.h"
 
52
#include "lpfc_bsg.h"
 
53
 
 
54
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
 
55
/*
 
56
 * debugfs interface
 
57
 *
 
58
 * To access this interface the user should:
 
59
 * # mount -t debugfs none /sys/kernel/debug
 
60
 *
 
61
 * The lpfc debugfs directory hierarchy is:
 
62
 * /sys/kernel/debug/lpfc/fnX/vportY
 
63
 * where X is the lpfc hba function unique_id
 
64
 * where Y is the vport VPI on that hba
 
65
 *
 
66
 * Debugging services available per vport:
 
67
 * discovery_trace
 
68
 * This is an ACSII readable file that contains a trace of the last
 
69
 * lpfc_debugfs_max_disc_trc events that happened on a specific vport.
 
70
 * See lpfc_debugfs.h for different categories of  discovery events.
 
71
 * To enable the discovery trace, the following module parameters must be set:
 
72
 * lpfc_debugfs_enable=1         Turns on lpfc debugfs filesystem support
 
73
 * lpfc_debugfs_max_disc_trc=X   Where X is the event trace depth for
 
74
 *                               EACH vport. X MUST also be a power of 2.
 
75
 * lpfc_debugfs_mask_disc_trc=Y  Where Y is an event mask as defined in
 
76
 *                               lpfc_debugfs.h .
 
77
 *
 
78
 * slow_ring_trace
 
79
 * This is an ACSII readable file that contains a trace of the last
 
80
 * lpfc_debugfs_max_slow_ring_trc events that happened on a specific HBA.
 
81
 * To enable the slow ring trace, the following module parameters must be set:
 
82
 * lpfc_debugfs_enable=1         Turns on lpfc debugfs filesystem support
 
83
 * lpfc_debugfs_max_slow_ring_trc=X   Where X is the event trace depth for
 
84
 *                               the HBA. X MUST also be a power of 2.
 
85
 */
 
86
static int lpfc_debugfs_enable = 1;
 
87
module_param(lpfc_debugfs_enable, int, S_IRUGO);
 
88
MODULE_PARM_DESC(lpfc_debugfs_enable, "Enable debugfs services");
 
89
 
 
90
/* This MUST be a power of 2 */
 
91
static int lpfc_debugfs_max_disc_trc;
 
92
module_param(lpfc_debugfs_max_disc_trc, int, S_IRUGO);
 
93
MODULE_PARM_DESC(lpfc_debugfs_max_disc_trc,
 
94
        "Set debugfs discovery trace depth");
 
95
 
 
96
/* This MUST be a power of 2 */
 
97
static int lpfc_debugfs_max_slow_ring_trc;
 
98
module_param(lpfc_debugfs_max_slow_ring_trc, int, S_IRUGO);
 
99
MODULE_PARM_DESC(lpfc_debugfs_max_slow_ring_trc,
 
100
        "Set debugfs slow ring trace depth");
 
101
 
 
102
static int lpfc_debugfs_mask_disc_trc;
 
103
module_param(lpfc_debugfs_mask_disc_trc, int, S_IRUGO);
 
104
MODULE_PARM_DESC(lpfc_debugfs_mask_disc_trc,
 
105
        "Set debugfs discovery trace mask");
 
106
 
 
107
#include <linux/debugfs.h>
 
108
 
 
109
static atomic_t lpfc_debugfs_seq_trc_cnt = ATOMIC_INIT(0);
 
110
static unsigned long lpfc_debugfs_start_time = 0L;
 
111
 
 
112
/* iDiag */
 
113
static struct lpfc_idiag idiag;
 
114
 
 
115
/**
 
116
 * lpfc_debugfs_disc_trc_data - Dump discovery logging to a buffer
 
117
 * @vport: The vport to gather the log info from.
 
118
 * @buf: The buffer to dump log into.
 
119
 * @size: The maximum amount of data to process.
 
120
 *
 
121
 * Description:
 
122
 * This routine gathers the lpfc discovery debugfs data from the @vport and
 
123
 * dumps it to @buf up to @size number of bytes. It will start at the next entry
 
124
 * in the log and process the log until the end of the buffer. Then it will
 
125
 * gather from the beginning of the log and process until the current entry.
 
126
 *
 
127
 * Notes:
 
128
 * Discovery logging will be disabled while while this routine dumps the log.
 
129
 *
 
130
 * Return Value:
 
131
 * This routine returns the amount of bytes that were dumped into @buf and will
 
132
 * not exceed @size.
 
133
 **/
 
134
static int
 
135
lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size)
 
136
{
 
137
        int i, index, len, enable;
 
138
        uint32_t ms;
 
139
        struct lpfc_debugfs_trc *dtp;
 
140
        char *buffer;
 
141
 
 
142
        buffer = kmalloc(LPFC_DEBUG_TRC_ENTRY_SIZE, GFP_KERNEL);
 
143
        if (!buffer)
 
144
                return 0;
 
145
 
 
146
        enable = lpfc_debugfs_enable;
 
147
        lpfc_debugfs_enable = 0;
 
148
 
 
149
        len = 0;
 
150
        index = (atomic_read(&vport->disc_trc_cnt) + 1) &
 
151
                (lpfc_debugfs_max_disc_trc - 1);
 
152
        for (i = index; i < lpfc_debugfs_max_disc_trc; i++) {
 
153
                dtp = vport->disc_trc + i;
 
154
                if (!dtp->fmt)
 
155
                        continue;
 
156
                ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
 
157
                snprintf(buffer,
 
158
                        LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
 
159
                        dtp->seq_cnt, ms, dtp->fmt);
 
160
                len +=  snprintf(buf+len, size-len, buffer,
 
161
                        dtp->data1, dtp->data2, dtp->data3);
 
162
        }
 
163
        for (i = 0; i < index; i++) {
 
164
                dtp = vport->disc_trc + i;
 
165
                if (!dtp->fmt)
 
166
                        continue;
 
167
                ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
 
168
                snprintf(buffer,
 
169
                        LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
 
170
                        dtp->seq_cnt, ms, dtp->fmt);
 
171
                len +=  snprintf(buf+len, size-len, buffer,
 
172
                        dtp->data1, dtp->data2, dtp->data3);
 
173
        }
 
174
 
 
175
        lpfc_debugfs_enable = enable;
 
176
        kfree(buffer);
 
177
 
 
178
        return len;
 
179
}
 
180
 
 
181
/**
 
182
 * lpfc_debugfs_slow_ring_trc_data - Dump slow ring logging to a buffer
 
183
 * @phba: The HBA to gather the log info from.
 
184
 * @buf: The buffer to dump log into.
 
185
 * @size: The maximum amount of data to process.
 
186
 *
 
187
 * Description:
 
188
 * This routine gathers the lpfc slow ring debugfs data from the @phba and
 
189
 * dumps it to @buf up to @size number of bytes. It will start at the next entry
 
190
 * in the log and process the log until the end of the buffer. Then it will
 
191
 * gather from the beginning of the log and process until the current entry.
 
192
 *
 
193
 * Notes:
 
194
 * Slow ring logging will be disabled while while this routine dumps the log.
 
195
 *
 
196
 * Return Value:
 
197
 * This routine returns the amount of bytes that were dumped into @buf and will
 
198
 * not exceed @size.
 
199
 **/
 
200
static int
 
201
lpfc_debugfs_slow_ring_trc_data(struct lpfc_hba *phba, char *buf, int size)
 
202
{
 
203
        int i, index, len, enable;
 
204
        uint32_t ms;
 
205
        struct lpfc_debugfs_trc *dtp;
 
206
        char *buffer;
 
207
 
 
208
        buffer = kmalloc(LPFC_DEBUG_TRC_ENTRY_SIZE, GFP_KERNEL);
 
209
        if (!buffer)
 
210
                return 0;
 
211
 
 
212
        enable = lpfc_debugfs_enable;
 
213
        lpfc_debugfs_enable = 0;
 
214
 
 
215
        len = 0;
 
216
        index = (atomic_read(&phba->slow_ring_trc_cnt) + 1) &
 
217
                (lpfc_debugfs_max_slow_ring_trc - 1);
 
218
        for (i = index; i < lpfc_debugfs_max_slow_ring_trc; i++) {
 
219
                dtp = phba->slow_ring_trc + i;
 
220
                if (!dtp->fmt)
 
221
                        continue;
 
222
                ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
 
223
                snprintf(buffer,
 
224
                        LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
 
225
                        dtp->seq_cnt, ms, dtp->fmt);
 
226
                len +=  snprintf(buf+len, size-len, buffer,
 
227
                        dtp->data1, dtp->data2, dtp->data3);
 
228
        }
 
229
        for (i = 0; i < index; i++) {
 
230
                dtp = phba->slow_ring_trc + i;
 
231
                if (!dtp->fmt)
 
232
                        continue;
 
233
                ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
 
234
                snprintf(buffer,
 
235
                        LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
 
236
                        dtp->seq_cnt, ms, dtp->fmt);
 
237
                len +=  snprintf(buf+len, size-len, buffer,
 
238
                        dtp->data1, dtp->data2, dtp->data3);
 
239
        }
 
240
 
 
241
        lpfc_debugfs_enable = enable;
 
242
        kfree(buffer);
 
243
 
 
244
        return len;
 
245
}
 
246
 
 
247
static int lpfc_debugfs_last_hbq = -1;
 
248
 
 
249
/**
 
250
 * lpfc_debugfs_hbqinfo_data - Dump host buffer queue info to a buffer
 
251
 * @phba: The HBA to gather host buffer info from.
 
252
 * @buf: The buffer to dump log into.
 
253
 * @size: The maximum amount of data to process.
 
254
 *
 
255
 * Description:
 
256
 * This routine dumps the host buffer queue info from the @phba to @buf up to
 
257
 * @size number of bytes. A header that describes the current hbq state will be
 
258
 * dumped to @buf first and then info on each hbq entry will be dumped to @buf
 
259
 * until @size bytes have been dumped or all the hbq info has been dumped.
 
260
 *
 
261
 * Notes:
 
262
 * This routine will rotate through each configured HBQ each time called.
 
263
 *
 
264
 * Return Value:
 
265
 * This routine returns the amount of bytes that were dumped into @buf and will
 
266
 * not exceed @size.
 
267
 **/
 
268
static int
 
269
lpfc_debugfs_hbqinfo_data(struct lpfc_hba *phba, char *buf, int size)
 
270
{
 
271
        int len = 0;
 
272
        int cnt, i, j, found, posted, low;
 
273
        uint32_t phys, raw_index, getidx;
 
274
        struct lpfc_hbq_init *hip;
 
275
        struct hbq_s *hbqs;
 
276
        struct lpfc_hbq_entry *hbqe;
 
277
        struct lpfc_dmabuf *d_buf;
 
278
        struct hbq_dmabuf *hbq_buf;
 
279
 
 
280
        if (phba->sli_rev != 3)
 
281
                return 0;
 
282
        cnt = LPFC_HBQINFO_SIZE;
 
283
        spin_lock_irq(&phba->hbalock);
 
284
 
 
285
        /* toggle between multiple hbqs, if any */
 
286
        i = lpfc_sli_hbq_count();
 
287
        if (i > 1) {
 
288
                 lpfc_debugfs_last_hbq++;
 
289
                 if (lpfc_debugfs_last_hbq >= i)
 
290
                        lpfc_debugfs_last_hbq = 0;
 
291
        }
 
292
        else
 
293
                lpfc_debugfs_last_hbq = 0;
 
294
 
 
295
        i = lpfc_debugfs_last_hbq;
 
296
 
 
297
        len +=  snprintf(buf+len, size-len, "HBQ %d Info\n", i);
 
298
 
 
299
        hbqs =  &phba->hbqs[i];
 
300
        posted = 0;
 
301
        list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list)
 
302
                posted++;
 
303
 
 
304
        hip =  lpfc_hbq_defs[i];
 
305
        len +=  snprintf(buf+len, size-len,
 
306
                "idx:%d prof:%d rn:%d bufcnt:%d icnt:%d acnt:%d posted %d\n",
 
307
                hip->hbq_index, hip->profile, hip->rn,
 
308
                hip->buffer_count, hip->init_count, hip->add_count, posted);
 
309
 
 
310
        raw_index = phba->hbq_get[i];
 
311
        getidx = le32_to_cpu(raw_index);
 
312
        len +=  snprintf(buf+len, size-len,
 
313
                "entrys:%d bufcnt:%d Put:%d nPut:%d localGet:%d hbaGet:%d\n",
 
314
                hbqs->entry_count, hbqs->buffer_count, hbqs->hbqPutIdx,
 
315
                hbqs->next_hbqPutIdx, hbqs->local_hbqGetIdx, getidx);
 
316
 
 
317
        hbqe = (struct lpfc_hbq_entry *) phba->hbqs[i].hbq_virt;
 
318
        for (j=0; j<hbqs->entry_count; j++) {
 
319
                len +=  snprintf(buf+len, size-len,
 
320
                        "%03d: %08x %04x %05x ", j,
 
321
                        le32_to_cpu(hbqe->bde.addrLow),
 
322
                        le32_to_cpu(hbqe->bde.tus.w),
 
323
                        le32_to_cpu(hbqe->buffer_tag));
 
324
                i = 0;
 
325
                found = 0;
 
326
 
 
327
                /* First calculate if slot has an associated posted buffer */
 
328
                low = hbqs->hbqPutIdx - posted;
 
329
                if (low >= 0) {
 
330
                        if ((j >= hbqs->hbqPutIdx) || (j < low)) {
 
331
                                len +=  snprintf(buf+len, size-len, "Unused\n");
 
332
                                goto skipit;
 
333
                        }
 
334
                }
 
335
                else {
 
336
                        if ((j >= hbqs->hbqPutIdx) &&
 
337
                                (j < (hbqs->entry_count+low))) {
 
338
                                len +=  snprintf(buf+len, size-len, "Unused\n");
 
339
                                goto skipit;
 
340
                        }
 
341
                }
 
342
 
 
343
                /* Get the Buffer info for the posted buffer */
 
344
                list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list) {
 
345
                        hbq_buf = container_of(d_buf, struct hbq_dmabuf, dbuf);
 
346
                        phys = ((uint64_t)hbq_buf->dbuf.phys & 0xffffffff);
 
347
                        if (phys == le32_to_cpu(hbqe->bde.addrLow)) {
 
348
                                len +=  snprintf(buf+len, size-len,
 
349
                                        "Buf%d: %p %06x\n", i,
 
350
                                        hbq_buf->dbuf.virt, hbq_buf->tag);
 
351
                                found = 1;
 
352
                                break;
 
353
                        }
 
354
                        i++;
 
355
                }
 
356
                if (!found) {
 
357
                        len +=  snprintf(buf+len, size-len, "No DMAinfo?\n");
 
358
                }
 
359
skipit:
 
360
                hbqe++;
 
361
                if (len > LPFC_HBQINFO_SIZE - 54)
 
362
                        break;
 
363
        }
 
364
        spin_unlock_irq(&phba->hbalock);
 
365
        return len;
 
366
}
 
367
 
 
368
static int lpfc_debugfs_last_hba_slim_off;
 
369
 
 
370
/**
 
371
 * lpfc_debugfs_dumpHBASlim_data - Dump HBA SLIM info to a buffer
 
372
 * @phba: The HBA to gather SLIM info from.
 
373
 * @buf: The buffer to dump log into.
 
374
 * @size: The maximum amount of data to process.
 
375
 *
 
376
 * Description:
 
377
 * This routine dumps the current contents of HBA SLIM for the HBA associated
 
378
 * with @phba to @buf up to @size bytes of data. This is the raw HBA SLIM data.
 
379
 *
 
380
 * Notes:
 
381
 * This routine will only dump up to 1024 bytes of data each time called and
 
382
 * should be called multiple times to dump the entire HBA SLIM.
 
383
 *
 
384
 * Return Value:
 
385
 * This routine returns the amount of bytes that were dumped into @buf and will
 
386
 * not exceed @size.
 
387
 **/
 
388
static int
 
389
lpfc_debugfs_dumpHBASlim_data(struct lpfc_hba *phba, char *buf, int size)
 
390
{
 
391
        int len = 0;
 
392
        int i, off;
 
393
        uint32_t *ptr;
 
394
        char *buffer;
 
395
 
 
396
        buffer = kmalloc(1024, GFP_KERNEL);
 
397
        if (!buffer)
 
398
                return 0;
 
399
 
 
400
        off = 0;
 
401
        spin_lock_irq(&phba->hbalock);
 
402
 
 
403
        len +=  snprintf(buf+len, size-len, "HBA SLIM\n");
 
404
        lpfc_memcpy_from_slim(buffer,
 
405
                phba->MBslimaddr + lpfc_debugfs_last_hba_slim_off, 1024);
 
406
 
 
407
        ptr = (uint32_t *)&buffer[0];
 
408
        off = lpfc_debugfs_last_hba_slim_off;
 
409
 
 
410
        /* Set it up for the next time */
 
411
        lpfc_debugfs_last_hba_slim_off += 1024;
 
412
        if (lpfc_debugfs_last_hba_slim_off >= 4096)
 
413
                lpfc_debugfs_last_hba_slim_off = 0;
 
414
 
 
415
        i = 1024;
 
416
        while (i > 0) {
 
417
                len +=  snprintf(buf+len, size-len,
 
418
                "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
 
419
                off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4),
 
420
                *(ptr+5), *(ptr+6), *(ptr+7));
 
421
                ptr += 8;
 
422
                i -= (8 * sizeof(uint32_t));
 
423
                off += (8 * sizeof(uint32_t));
 
424
        }
 
425
 
 
426
        spin_unlock_irq(&phba->hbalock);
 
427
        kfree(buffer);
 
428
 
 
429
        return len;
 
430
}
 
431
 
 
432
/**
 
433
 * lpfc_debugfs_dumpHostSlim_data - Dump host SLIM info to a buffer
 
434
 * @phba: The HBA to gather Host SLIM info from.
 
435
 * @buf: The buffer to dump log into.
 
436
 * @size: The maximum amount of data to process.
 
437
 *
 
438
 * Description:
 
439
 * This routine dumps the current contents of host SLIM for the host associated
 
440
 * with @phba to @buf up to @size bytes of data. The dump will contain the
 
441
 * Mailbox, PCB, Rings, and Registers that are located in host memory.
 
442
 *
 
443
 * Return Value:
 
444
 * This routine returns the amount of bytes that were dumped into @buf and will
 
445
 * not exceed @size.
 
446
 **/
 
447
static int
 
448
lpfc_debugfs_dumpHostSlim_data(struct lpfc_hba *phba, char *buf, int size)
 
449
{
 
450
        int len = 0;
 
451
        int i, off;
 
452
        uint32_t word0, word1, word2, word3;
 
453
        uint32_t *ptr;
 
454
        struct lpfc_pgp *pgpp;
 
455
        struct lpfc_sli *psli = &phba->sli;
 
456
        struct lpfc_sli_ring *pring;
 
457
 
 
458
        off = 0;
 
459
        spin_lock_irq(&phba->hbalock);
 
460
 
 
461
        len +=  snprintf(buf+len, size-len, "SLIM Mailbox\n");
 
462
        ptr = (uint32_t *)phba->slim2p.virt;
 
463
        i = sizeof(MAILBOX_t);
 
464
        while (i > 0) {
 
465
                len +=  snprintf(buf+len, size-len,
 
466
                "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
 
467
                off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4),
 
468
                *(ptr+5), *(ptr+6), *(ptr+7));
 
469
                ptr += 8;
 
470
                i -= (8 * sizeof(uint32_t));
 
471
                off += (8 * sizeof(uint32_t));
 
472
        }
 
473
 
 
474
        len +=  snprintf(buf+len, size-len, "SLIM PCB\n");
 
475
        ptr = (uint32_t *)phba->pcb;
 
476
        i = sizeof(PCB_t);
 
477
        while (i > 0) {
 
478
                len +=  snprintf(buf+len, size-len,
 
479
                "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
 
480
                off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4),
 
481
                *(ptr+5), *(ptr+6), *(ptr+7));
 
482
                ptr += 8;
 
483
                i -= (8 * sizeof(uint32_t));
 
484
                off += (8 * sizeof(uint32_t));
 
485
        }
 
486
 
 
487
        for (i = 0; i < 4; i++) {
 
488
                pgpp = &phba->port_gp[i];
 
489
                pring = &psli->ring[i];
 
490
                len +=  snprintf(buf+len, size-len,
 
491
                                 "Ring %d: CMD GetInx:%d (Max:%d Next:%d "
 
492
                                 "Local:%d flg:x%x)  RSP PutInx:%d Max:%d\n",
 
493
                                 i, pgpp->cmdGetInx, pring->numCiocb,
 
494
                                 pring->next_cmdidx, pring->local_getidx,
 
495
                                 pring->flag, pgpp->rspPutInx, pring->numRiocb);
 
496
        }
 
497
 
 
498
        if (phba->sli_rev <= LPFC_SLI_REV3) {
 
499
                word0 = readl(phba->HAregaddr);
 
500
                word1 = readl(phba->CAregaddr);
 
501
                word2 = readl(phba->HSregaddr);
 
502
                word3 = readl(phba->HCregaddr);
 
503
                len +=  snprintf(buf+len, size-len, "HA:%08x CA:%08x HS:%08x "
 
504
                                 "HC:%08x\n", word0, word1, word2, word3);
 
505
        }
 
506
        spin_unlock_irq(&phba->hbalock);
 
507
        return len;
 
508
}
 
509
 
 
510
/**
 
511
 * lpfc_debugfs_nodelist_data - Dump target node list to a buffer
 
512
 * @vport: The vport to gather target node info from.
 
513
 * @buf: The buffer to dump log into.
 
514
 * @size: The maximum amount of data to process.
 
515
 *
 
516
 * Description:
 
517
 * This routine dumps the current target node list associated with @vport to
 
518
 * @buf up to @size bytes of data. Each node entry in the dump will contain a
 
519
 * node state, DID, WWPN, WWNN, RPI, flags, type, and other useful fields.
 
520
 *
 
521
 * Return Value:
 
522
 * This routine returns the amount of bytes that were dumped into @buf and will
 
523
 * not exceed @size.
 
524
 **/
 
525
static int
 
526
lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
 
527
{
 
528
        int len = 0;
 
529
        int cnt;
 
530
        struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
 
531
        struct lpfc_nodelist *ndlp;
 
532
        unsigned char *statep, *name;
 
533
 
 
534
        cnt = (LPFC_NODELIST_SIZE / LPFC_NODELIST_ENTRY_SIZE);
 
535
 
 
536
        spin_lock_irq(shost->host_lock);
 
537
        list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
 
538
                if (!cnt) {
 
539
                        len +=  snprintf(buf+len, size-len,
 
540
                                "Missing Nodelist Entries\n");
 
541
                        break;
 
542
                }
 
543
                cnt--;
 
544
                switch (ndlp->nlp_state) {
 
545
                case NLP_STE_UNUSED_NODE:
 
546
                        statep = "UNUSED";
 
547
                        break;
 
548
                case NLP_STE_PLOGI_ISSUE:
 
549
                        statep = "PLOGI ";
 
550
                        break;
 
551
                case NLP_STE_ADISC_ISSUE:
 
552
                        statep = "ADISC ";
 
553
                        break;
 
554
                case NLP_STE_REG_LOGIN_ISSUE:
 
555
                        statep = "REGLOG";
 
556
                        break;
 
557
                case NLP_STE_PRLI_ISSUE:
 
558
                        statep = "PRLI  ";
 
559
                        break;
 
560
                case NLP_STE_UNMAPPED_NODE:
 
561
                        statep = "UNMAP ";
 
562
                        break;
 
563
                case NLP_STE_MAPPED_NODE:
 
564
                        statep = "MAPPED";
 
565
                        break;
 
566
                case NLP_STE_NPR_NODE:
 
567
                        statep = "NPR   ";
 
568
                        break;
 
569
                default:
 
570
                        statep = "UNKNOWN";
 
571
                }
 
572
                len +=  snprintf(buf+len, size-len, "%s DID:x%06x ",
 
573
                        statep, ndlp->nlp_DID);
 
574
                name = (unsigned char *)&ndlp->nlp_portname;
 
575
                len +=  snprintf(buf+len, size-len,
 
576
                        "WWPN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ",
 
577
                        *name, *(name+1), *(name+2), *(name+3),
 
578
                        *(name+4), *(name+5), *(name+6), *(name+7));
 
579
                name = (unsigned char *)&ndlp->nlp_nodename;
 
580
                len +=  snprintf(buf+len, size-len,
 
581
                        "WWNN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ",
 
582
                        *name, *(name+1), *(name+2), *(name+3),
 
583
                        *(name+4), *(name+5), *(name+6), *(name+7));
 
584
                len +=  snprintf(buf+len, size-len, "RPI:%03d flag:x%08x ",
 
585
                        ndlp->nlp_rpi, ndlp->nlp_flag);
 
586
                if (!ndlp->nlp_type)
 
587
                        len +=  snprintf(buf+len, size-len, "UNKNOWN_TYPE ");
 
588
                if (ndlp->nlp_type & NLP_FC_NODE)
 
589
                        len +=  snprintf(buf+len, size-len, "FC_NODE ");
 
590
                if (ndlp->nlp_type & NLP_FABRIC)
 
591
                        len +=  snprintf(buf+len, size-len, "FABRIC ");
 
592
                if (ndlp->nlp_type & NLP_FCP_TARGET)
 
593
                        len +=  snprintf(buf+len, size-len, "FCP_TGT sid:%d ",
 
594
                                ndlp->nlp_sid);
 
595
                if (ndlp->nlp_type & NLP_FCP_INITIATOR)
 
596
                        len +=  snprintf(buf+len, size-len, "FCP_INITIATOR ");
 
597
                len += snprintf(buf+len, size-len, "usgmap:%x ",
 
598
                        ndlp->nlp_usg_map);
 
599
                len += snprintf(buf+len, size-len, "refcnt:%x",
 
600
                        atomic_read(&ndlp->kref.refcount));
 
601
                len +=  snprintf(buf+len, size-len, "\n");
 
602
        }
 
603
        spin_unlock_irq(shost->host_lock);
 
604
        return len;
 
605
}
 
606
#endif
 
607
 
 
608
/**
 
609
 * lpfc_debugfs_disc_trc - Store discovery trace log
 
610
 * @vport: The vport to associate this trace string with for retrieval.
 
611
 * @mask: Log entry classification.
 
612
 * @fmt: Format string to be displayed when dumping the log.
 
613
 * @data1: 1st data parameter to be applied to @fmt.
 
614
 * @data2: 2nd data parameter to be applied to @fmt.
 
615
 * @data3: 3rd data parameter to be applied to @fmt.
 
616
 *
 
617
 * Description:
 
618
 * This routine is used by the driver code to add a debugfs log entry to the
 
619
 * discovery trace buffer associated with @vport. Only entries with a @mask that
 
620
 * match the current debugfs discovery mask will be saved. Entries that do not
 
621
 * match will be thrown away. @fmt, @data1, @data2, and @data3 are used like
 
622
 * printf when displaying the log.
 
623
 **/
 
624
inline void
 
625
lpfc_debugfs_disc_trc(struct lpfc_vport *vport, int mask, char *fmt,
 
626
        uint32_t data1, uint32_t data2, uint32_t data3)
 
627
{
 
628
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
 
629
        struct lpfc_debugfs_trc *dtp;
 
630
        int index;
 
631
 
 
632
        if (!(lpfc_debugfs_mask_disc_trc & mask))
 
633
                return;
 
634
 
 
635
        if (!lpfc_debugfs_enable || !lpfc_debugfs_max_disc_trc ||
 
636
                !vport || !vport->disc_trc)
 
637
                return;
 
638
 
 
639
        index = atomic_inc_return(&vport->disc_trc_cnt) &
 
640
                (lpfc_debugfs_max_disc_trc - 1);
 
641
        dtp = vport->disc_trc + index;
 
642
        dtp->fmt = fmt;
 
643
        dtp->data1 = data1;
 
644
        dtp->data2 = data2;
 
645
        dtp->data3 = data3;
 
646
        dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt);
 
647
        dtp->jif = jiffies;
 
648
#endif
 
649
        return;
 
650
}
 
651
 
 
652
/**
 
653
 * lpfc_debugfs_slow_ring_trc - Store slow ring trace log
 
654
 * @phba: The phba to associate this trace string with for retrieval.
 
655
 * @fmt: Format string to be displayed when dumping the log.
 
656
 * @data1: 1st data parameter to be applied to @fmt.
 
657
 * @data2: 2nd data parameter to be applied to @fmt.
 
658
 * @data3: 3rd data parameter to be applied to @fmt.
 
659
 *
 
660
 * Description:
 
661
 * This routine is used by the driver code to add a debugfs log entry to the
 
662
 * discovery trace buffer associated with @vport. @fmt, @data1, @data2, and
 
663
 * @data3 are used like printf when displaying the log.
 
664
 **/
 
665
inline void
 
666
lpfc_debugfs_slow_ring_trc(struct lpfc_hba *phba, char *fmt,
 
667
        uint32_t data1, uint32_t data2, uint32_t data3)
 
668
{
 
669
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
 
670
        struct lpfc_debugfs_trc *dtp;
 
671
        int index;
 
672
 
 
673
        if (!lpfc_debugfs_enable || !lpfc_debugfs_max_slow_ring_trc ||
 
674
                !phba || !phba->slow_ring_trc)
 
675
                return;
 
676
 
 
677
        index = atomic_inc_return(&phba->slow_ring_trc_cnt) &
 
678
                (lpfc_debugfs_max_slow_ring_trc - 1);
 
679
        dtp = phba->slow_ring_trc + index;
 
680
        dtp->fmt = fmt;
 
681
        dtp->data1 = data1;
 
682
        dtp->data2 = data2;
 
683
        dtp->data3 = data3;
 
684
        dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt);
 
685
        dtp->jif = jiffies;
 
686
#endif
 
687
        return;
 
688
}
 
689
 
 
690
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
 
691
/**
 
692
 * lpfc_debugfs_disc_trc_open - Open the discovery trace log
 
693
 * @inode: The inode pointer that contains a vport pointer.
 
694
 * @file: The file pointer to attach the log output.
 
695
 *
 
696
 * Description:
 
697
 * This routine is the entry point for the debugfs open file operation. It gets
 
698
 * the vport from the i_private field in @inode, allocates the necessary buffer
 
699
 * for the log, fills the buffer from the in-memory log for this vport, and then
 
700
 * returns a pointer to that log in the private_data field in @file.
 
701
 *
 
702
 * Returns:
 
703
 * This function returns zero if successful. On error it will return an negative
 
704
 * error value.
 
705
 **/
 
706
static int
 
707
lpfc_debugfs_disc_trc_open(struct inode *inode, struct file *file)
 
708
{
 
709
        struct lpfc_vport *vport = inode->i_private;
 
710
        struct lpfc_debug *debug;
 
711
        int size;
 
712
        int rc = -ENOMEM;
 
713
 
 
714
        if (!lpfc_debugfs_max_disc_trc) {
 
715
                 rc = -ENOSPC;
 
716
                goto out;
 
717
        }
 
718
 
 
719
        debug = kmalloc(sizeof(*debug), GFP_KERNEL);
 
720
        if (!debug)
 
721
                goto out;
 
722
 
 
723
        /* Round to page boundary */
 
724
        size =  (lpfc_debugfs_max_disc_trc * LPFC_DEBUG_TRC_ENTRY_SIZE);
 
725
        size = PAGE_ALIGN(size);
 
726
 
 
727
        debug->buffer = kmalloc(size, GFP_KERNEL);
 
728
        if (!debug->buffer) {
 
729
                kfree(debug);
 
730
                goto out;
 
731
        }
 
732
 
 
733
        debug->len = lpfc_debugfs_disc_trc_data(vport, debug->buffer, size);
 
734
        file->private_data = debug;
 
735
 
 
736
        rc = 0;
 
737
out:
 
738
        return rc;
 
739
}
 
740
 
 
741
/**
 
742
 * lpfc_debugfs_slow_ring_trc_open - Open the Slow Ring trace log
 
743
 * @inode: The inode pointer that contains a vport pointer.
 
744
 * @file: The file pointer to attach the log output.
 
745
 *
 
746
 * Description:
 
747
 * This routine is the entry point for the debugfs open file operation. It gets
 
748
 * the vport from the i_private field in @inode, allocates the necessary buffer
 
749
 * for the log, fills the buffer from the in-memory log for this vport, and then
 
750
 * returns a pointer to that log in the private_data field in @file.
 
751
 *
 
752
 * Returns:
 
753
 * This function returns zero if successful. On error it will return an negative
 
754
 * error value.
 
755
 **/
 
756
static int
 
757
lpfc_debugfs_slow_ring_trc_open(struct inode *inode, struct file *file)
 
758
{
 
759
        struct lpfc_hba *phba = inode->i_private;
 
760
        struct lpfc_debug *debug;
 
761
        int size;
 
762
        int rc = -ENOMEM;
 
763
 
 
764
        if (!lpfc_debugfs_max_slow_ring_trc) {
 
765
                 rc = -ENOSPC;
 
766
                goto out;
 
767
        }
 
768
 
 
769
        debug = kmalloc(sizeof(*debug), GFP_KERNEL);
 
770
        if (!debug)
 
771
                goto out;
 
772
 
 
773
        /* Round to page boundary */
 
774
        size =  (lpfc_debugfs_max_slow_ring_trc * LPFC_DEBUG_TRC_ENTRY_SIZE);
 
775
        size = PAGE_ALIGN(size);
 
776
 
 
777
        debug->buffer = kmalloc(size, GFP_KERNEL);
 
778
        if (!debug->buffer) {
 
779
                kfree(debug);
 
780
                goto out;
 
781
        }
 
782
 
 
783
        debug->len = lpfc_debugfs_slow_ring_trc_data(phba, debug->buffer, size);
 
784
        file->private_data = debug;
 
785
 
 
786
        rc = 0;
 
787
out:
 
788
        return rc;
 
789
}
 
790
 
 
791
/**
 
792
 * lpfc_debugfs_hbqinfo_open - Open the hbqinfo debugfs buffer
 
793
 * @inode: The inode pointer that contains a vport pointer.
 
794
 * @file: The file pointer to attach the log output.
 
795
 *
 
796
 * Description:
 
797
 * This routine is the entry point for the debugfs open file operation. It gets
 
798
 * the vport from the i_private field in @inode, allocates the necessary buffer
 
799
 * for the log, fills the buffer from the in-memory log for this vport, and then
 
800
 * returns a pointer to that log in the private_data field in @file.
 
801
 *
 
802
 * Returns:
 
803
 * This function returns zero if successful. On error it will return an negative
 
804
 * error value.
 
805
 **/
 
806
static int
 
807
lpfc_debugfs_hbqinfo_open(struct inode *inode, struct file *file)
 
808
{
 
809
        struct lpfc_hba *phba = inode->i_private;
 
810
        struct lpfc_debug *debug;
 
811
        int rc = -ENOMEM;
 
812
 
 
813
        debug = kmalloc(sizeof(*debug), GFP_KERNEL);
 
814
        if (!debug)
 
815
                goto out;
 
816
 
 
817
        /* Round to page boundary */
 
818
        debug->buffer = kmalloc(LPFC_HBQINFO_SIZE, GFP_KERNEL);
 
819
        if (!debug->buffer) {
 
820
                kfree(debug);
 
821
                goto out;
 
822
        }
 
823
 
 
824
        debug->len = lpfc_debugfs_hbqinfo_data(phba, debug->buffer,
 
825
                LPFC_HBQINFO_SIZE);
 
826
        file->private_data = debug;
 
827
 
 
828
        rc = 0;
 
829
out:
 
830
        return rc;
 
831
}
 
832
 
 
833
/**
 
834
 * lpfc_debugfs_dumpHBASlim_open - Open the Dump HBA SLIM debugfs buffer
 
835
 * @inode: The inode pointer that contains a vport pointer.
 
836
 * @file: The file pointer to attach the log output.
 
837
 *
 
838
 * Description:
 
839
 * This routine is the entry point for the debugfs open file operation. It gets
 
840
 * the vport from the i_private field in @inode, allocates the necessary buffer
 
841
 * for the log, fills the buffer from the in-memory log for this vport, and then
 
842
 * returns a pointer to that log in the private_data field in @file.
 
843
 *
 
844
 * Returns:
 
845
 * This function returns zero if successful. On error it will return an negative
 
846
 * error value.
 
847
 **/
 
848
static int
 
849
lpfc_debugfs_dumpHBASlim_open(struct inode *inode, struct file *file)
 
850
{
 
851
        struct lpfc_hba *phba = inode->i_private;
 
852
        struct lpfc_debug *debug;
 
853
        int rc = -ENOMEM;
 
854
 
 
855
        debug = kmalloc(sizeof(*debug), GFP_KERNEL);
 
856
        if (!debug)
 
857
                goto out;
 
858
 
 
859
        /* Round to page boundary */
 
860
        debug->buffer = kmalloc(LPFC_DUMPHBASLIM_SIZE, GFP_KERNEL);
 
861
        if (!debug->buffer) {
 
862
                kfree(debug);
 
863
                goto out;
 
864
        }
 
865
 
 
866
        debug->len = lpfc_debugfs_dumpHBASlim_data(phba, debug->buffer,
 
867
                LPFC_DUMPHBASLIM_SIZE);
 
868
        file->private_data = debug;
 
869
 
 
870
        rc = 0;
 
871
out:
 
872
        return rc;
 
873
}
 
874
 
 
875
/**
 
876
 * lpfc_debugfs_dumpHostSlim_open - Open the Dump Host SLIM debugfs buffer
 
877
 * @inode: The inode pointer that contains a vport pointer.
 
878
 * @file: The file pointer to attach the log output.
 
879
 *
 
880
 * Description:
 
881
 * This routine is the entry point for the debugfs open file operation. It gets
 
882
 * the vport from the i_private field in @inode, allocates the necessary buffer
 
883
 * for the log, fills the buffer from the in-memory log for this vport, and then
 
884
 * returns a pointer to that log in the private_data field in @file.
 
885
 *
 
886
 * Returns:
 
887
 * This function returns zero if successful. On error it will return an negative
 
888
 * error value.
 
889
 **/
 
890
static int
 
891
lpfc_debugfs_dumpHostSlim_open(struct inode *inode, struct file *file)
 
892
{
 
893
        struct lpfc_hba *phba = inode->i_private;
 
894
        struct lpfc_debug *debug;
 
895
        int rc = -ENOMEM;
 
896
 
 
897
        debug = kmalloc(sizeof(*debug), GFP_KERNEL);
 
898
        if (!debug)
 
899
                goto out;
 
900
 
 
901
        /* Round to page boundary */
 
902
        debug->buffer = kmalloc(LPFC_DUMPHOSTSLIM_SIZE, GFP_KERNEL);
 
903
        if (!debug->buffer) {
 
904
                kfree(debug);
 
905
                goto out;
 
906
        }
 
907
 
 
908
        debug->len = lpfc_debugfs_dumpHostSlim_data(phba, debug->buffer,
 
909
                LPFC_DUMPHOSTSLIM_SIZE);
 
910
        file->private_data = debug;
 
911
 
 
912
        rc = 0;
 
913
out:
 
914
        return rc;
 
915
}
 
916
 
 
917
static int
 
918
lpfc_debugfs_dumpData_open(struct inode *inode, struct file *file)
 
919
{
 
920
        struct lpfc_debug *debug;
 
921
        int rc = -ENOMEM;
 
922
 
 
923
        if (!_dump_buf_data)
 
924
                return -EBUSY;
 
925
 
 
926
        debug = kmalloc(sizeof(*debug), GFP_KERNEL);
 
927
        if (!debug)
 
928
                goto out;
 
929
 
 
930
        /* Round to page boundary */
 
931
        printk(KERN_ERR "9059 BLKGRD:  %s: _dump_buf_data=0x%p\n",
 
932
                        __func__, _dump_buf_data);
 
933
        debug->buffer = _dump_buf_data;
 
934
        if (!debug->buffer) {
 
935
                kfree(debug);
 
936
                goto out;
 
937
        }
 
938
 
 
939
        debug->len = (1 << _dump_buf_data_order) << PAGE_SHIFT;
 
940
        file->private_data = debug;
 
941
 
 
942
        rc = 0;
 
943
out:
 
944
        return rc;
 
945
}
 
946
 
 
947
static int
 
948
lpfc_debugfs_dumpDif_open(struct inode *inode, struct file *file)
 
949
{
 
950
        struct lpfc_debug *debug;
 
951
        int rc = -ENOMEM;
 
952
 
 
953
        if (!_dump_buf_dif)
 
954
                return -EBUSY;
 
955
 
 
956
        debug = kmalloc(sizeof(*debug), GFP_KERNEL);
 
957
        if (!debug)
 
958
                goto out;
 
959
 
 
960
        /* Round to page boundary */
 
961
        printk(KERN_ERR "9060 BLKGRD: %s: _dump_buf_dif=0x%p file=%s\n",
 
962
                __func__, _dump_buf_dif, file->f_dentry->d_name.name);
 
963
        debug->buffer = _dump_buf_dif;
 
964
        if (!debug->buffer) {
 
965
                kfree(debug);
 
966
                goto out;
 
967
        }
 
968
 
 
969
        debug->len = (1 << _dump_buf_dif_order) << PAGE_SHIFT;
 
970
        file->private_data = debug;
 
971
 
 
972
        rc = 0;
 
973
out:
 
974
        return rc;
 
975
}
 
976
 
 
977
static ssize_t
 
978
lpfc_debugfs_dumpDataDif_write(struct file *file, const char __user *buf,
 
979
                  size_t nbytes, loff_t *ppos)
 
980
{
 
981
        /*
 
982
         * The Data/DIF buffers only save one failing IO
 
983
         * The write op is used as a reset mechanism after an IO has
 
984
         * already been saved to the next one can be saved
 
985
         */
 
986
        spin_lock(&_dump_buf_lock);
 
987
 
 
988
        memset((void *)_dump_buf_data, 0,
 
989
                        ((1 << PAGE_SHIFT) << _dump_buf_data_order));
 
990
        memset((void *)_dump_buf_dif, 0,
 
991
                        ((1 << PAGE_SHIFT) << _dump_buf_dif_order));
 
992
 
 
993
        _dump_buf_done = 0;
 
994
 
 
995
        spin_unlock(&_dump_buf_lock);
 
996
 
 
997
        return nbytes;
 
998
}
 
999
 
 
1000
static int
 
1001
lpfc_debugfs_dif_err_open(struct inode *inode, struct file *file)
 
1002
{
 
1003
        file->private_data = inode->i_private;
 
1004
        return 0;
 
1005
}
 
1006
 
 
1007
static ssize_t
 
1008
lpfc_debugfs_dif_err_read(struct file *file, char __user *buf,
 
1009
        size_t nbytes, loff_t *ppos)
 
1010
{
 
1011
        struct dentry *dent = file->f_dentry;
 
1012
        struct lpfc_hba *phba = file->private_data;
 
1013
        char cbuf[16];
 
1014
        int cnt = 0;
 
1015
 
 
1016
        if (dent == phba->debug_writeGuard)
 
1017
                cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_wgrd_cnt);
 
1018
        else if (dent == phba->debug_writeApp)
 
1019
                cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_wapp_cnt);
 
1020
        else if (dent == phba->debug_writeRef)
 
1021
                cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_wref_cnt);
 
1022
        else if (dent == phba->debug_readApp)
 
1023
                cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_rapp_cnt);
 
1024
        else if (dent == phba->debug_readRef)
 
1025
                cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_rref_cnt);
 
1026
        else if (dent == phba->debug_InjErrLBA)
 
1027
                cnt = snprintf(cbuf, 16, "0x%lx\n",
 
1028
                                 (unsigned long) phba->lpfc_injerr_lba);
 
1029
        else
 
1030
                lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
 
1031
                         "0547 Unknown debugfs error injection entry\n");
 
1032
 
 
1033
        return simple_read_from_buffer(buf, nbytes, ppos, &cbuf, cnt);
 
1034
}
 
1035
 
 
1036
static ssize_t
 
1037
lpfc_debugfs_dif_err_write(struct file *file, const char __user *buf,
 
1038
        size_t nbytes, loff_t *ppos)
 
1039
{
 
1040
        struct dentry *dent = file->f_dentry;
 
1041
        struct lpfc_hba *phba = file->private_data;
 
1042
        char dstbuf[32];
 
1043
        unsigned long tmp;
 
1044
        int size;
 
1045
 
 
1046
        memset(dstbuf, 0, 32);
 
1047
        size = (nbytes < 32) ? nbytes : 32;
 
1048
        if (copy_from_user(dstbuf, buf, size))
 
1049
                return 0;
 
1050
 
 
1051
        if (strict_strtoul(dstbuf, 0, &tmp))
 
1052
                return 0;
 
1053
 
 
1054
        if (dent == phba->debug_writeGuard)
 
1055
                phba->lpfc_injerr_wgrd_cnt = (uint32_t)tmp;
 
1056
        else if (dent == phba->debug_writeApp)
 
1057
                phba->lpfc_injerr_wapp_cnt = (uint32_t)tmp;
 
1058
        else if (dent == phba->debug_writeRef)
 
1059
                phba->lpfc_injerr_wref_cnt = (uint32_t)tmp;
 
1060
        else if (dent == phba->debug_readApp)
 
1061
                phba->lpfc_injerr_rapp_cnt = (uint32_t)tmp;
 
1062
        else if (dent == phba->debug_readRef)
 
1063
                phba->lpfc_injerr_rref_cnt = (uint32_t)tmp;
 
1064
        else if (dent == phba->debug_InjErrLBA)
 
1065
                phba->lpfc_injerr_lba = (sector_t)tmp;
 
1066
        else
 
1067
                lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
 
1068
                         "0548 Unknown debugfs error injection entry\n");
 
1069
 
 
1070
        return nbytes;
 
1071
}
 
1072
 
 
1073
static int
 
1074
lpfc_debugfs_dif_err_release(struct inode *inode, struct file *file)
 
1075
{
 
1076
        return 0;
 
1077
}
 
1078
 
 
1079
/**
 
1080
 * lpfc_debugfs_nodelist_open - Open the nodelist debugfs file
 
1081
 * @inode: The inode pointer that contains a vport pointer.
 
1082
 * @file: The file pointer to attach the log output.
 
1083
 *
 
1084
 * Description:
 
1085
 * This routine is the entry point for the debugfs open file operation. It gets
 
1086
 * the vport from the i_private field in @inode, allocates the necessary buffer
 
1087
 * for the log, fills the buffer from the in-memory log for this vport, and then
 
1088
 * returns a pointer to that log in the private_data field in @file.
 
1089
 *
 
1090
 * Returns:
 
1091
 * This function returns zero if successful. On error it will return an negative
 
1092
 * error value.
 
1093
 **/
 
1094
static int
 
1095
lpfc_debugfs_nodelist_open(struct inode *inode, struct file *file)
 
1096
{
 
1097
        struct lpfc_vport *vport = inode->i_private;
 
1098
        struct lpfc_debug *debug;
 
1099
        int rc = -ENOMEM;
 
1100
 
 
1101
        debug = kmalloc(sizeof(*debug), GFP_KERNEL);
 
1102
        if (!debug)
 
1103
                goto out;
 
1104
 
 
1105
        /* Round to page boundary */
 
1106
        debug->buffer = kmalloc(LPFC_NODELIST_SIZE, GFP_KERNEL);
 
1107
        if (!debug->buffer) {
 
1108
                kfree(debug);
 
1109
                goto out;
 
1110
        }
 
1111
 
 
1112
        debug->len = lpfc_debugfs_nodelist_data(vport, debug->buffer,
 
1113
                LPFC_NODELIST_SIZE);
 
1114
        file->private_data = debug;
 
1115
 
 
1116
        rc = 0;
 
1117
out:
 
1118
        return rc;
 
1119
}
 
1120
 
 
1121
/**
 
1122
 * lpfc_debugfs_lseek - Seek through a debugfs file
 
1123
 * @file: The file pointer to seek through.
 
1124
 * @off: The offset to seek to or the amount to seek by.
 
1125
 * @whence: Indicates how to seek.
 
1126
 *
 
1127
 * Description:
 
1128
 * This routine is the entry point for the debugfs lseek file operation. The
 
1129
 * @whence parameter indicates whether @off is the offset to directly seek to,
 
1130
 * or if it is a value to seek forward or reverse by. This function figures out
 
1131
 * what the new offset of the debugfs file will be and assigns that value to the
 
1132
 * f_pos field of @file.
 
1133
 *
 
1134
 * Returns:
 
1135
 * This function returns the new offset if successful and returns a negative
 
1136
 * error if unable to process the seek.
 
1137
 **/
 
1138
static loff_t
 
1139
lpfc_debugfs_lseek(struct file *file, loff_t off, int whence)
 
1140
{
 
1141
        struct lpfc_debug *debug;
 
1142
        loff_t pos = -1;
 
1143
 
 
1144
        debug = file->private_data;
 
1145
 
 
1146
        switch (whence) {
 
1147
        case 0:
 
1148
                pos = off;
 
1149
                break;
 
1150
        case 1:
 
1151
                pos = file->f_pos + off;
 
1152
                break;
 
1153
        case 2:
 
1154
                pos = debug->len - off;
 
1155
        }
 
1156
        return (pos < 0 || pos > debug->len) ? -EINVAL : (file->f_pos = pos);
 
1157
}
 
1158
 
 
1159
/**
 
1160
 * lpfc_debugfs_read - Read a debugfs file
 
1161
 * @file: The file pointer to read from.
 
1162
 * @buf: The buffer to copy the data to.
 
1163
 * @nbytes: The number of bytes to read.
 
1164
 * @ppos: The position in the file to start reading from.
 
1165
 *
 
1166
 * Description:
 
1167
 * This routine reads data from from the buffer indicated in the private_data
 
1168
 * field of @file. It will start reading at @ppos and copy up to @nbytes of
 
1169
 * data to @buf.
 
1170
 *
 
1171
 * Returns:
 
1172
 * This function returns the amount of data that was read (this could be less
 
1173
 * than @nbytes if the end of the file was reached) or a negative error value.
 
1174
 **/
 
1175
static ssize_t
 
1176
lpfc_debugfs_read(struct file *file, char __user *buf,
 
1177
                  size_t nbytes, loff_t *ppos)
 
1178
{
 
1179
        struct lpfc_debug *debug = file->private_data;
 
1180
 
 
1181
        return simple_read_from_buffer(buf, nbytes, ppos, debug->buffer,
 
1182
                                       debug->len);
 
1183
}
 
1184
 
 
1185
/**
 
1186
 * lpfc_debugfs_release - Release the buffer used to store debugfs file data
 
1187
 * @inode: The inode pointer that contains a vport pointer. (unused)
 
1188
 * @file: The file pointer that contains the buffer to release.
 
1189
 *
 
1190
 * Description:
 
1191
 * This routine frees the buffer that was allocated when the debugfs file was
 
1192
 * opened.
 
1193
 *
 
1194
 * Returns:
 
1195
 * This function returns zero.
 
1196
 **/
 
1197
static int
 
1198
lpfc_debugfs_release(struct inode *inode, struct file *file)
 
1199
{
 
1200
        struct lpfc_debug *debug = file->private_data;
 
1201
 
 
1202
        kfree(debug->buffer);
 
1203
        kfree(debug);
 
1204
 
 
1205
        return 0;
 
1206
}
 
1207
 
 
1208
static int
 
1209
lpfc_debugfs_dumpDataDif_release(struct inode *inode, struct file *file)
 
1210
{
 
1211
        struct lpfc_debug *debug = file->private_data;
 
1212
 
 
1213
        debug->buffer = NULL;
 
1214
        kfree(debug);
 
1215
 
 
1216
        return 0;
 
1217
}
 
1218
 
 
1219
/*
 
1220
 * ---------------------------------
 
1221
 * iDiag debugfs file access methods
 
1222
 * ---------------------------------
 
1223
 *
 
1224
 * All access methods are through the proper SLI4 PCI function's debugfs
 
1225
 * iDiag directory:
 
1226
 *
 
1227
 *     /sys/kernel/debug/lpfc/fn<#>/iDiag
 
1228
 */
 
1229
 
 
1230
/**
 
1231
 * lpfc_idiag_cmd_get - Get and parse idiag debugfs comands from user space
 
1232
 * @buf: The pointer to the user space buffer.
 
1233
 * @nbytes: The number of bytes in the user space buffer.
 
1234
 * @idiag_cmd: pointer to the idiag command struct.
 
1235
 *
 
1236
 * This routine reads data from debugfs user space buffer and parses the
 
1237
 * buffer for getting the idiag command and arguments. The while space in
 
1238
 * between the set of data is used as the parsing separator.
 
1239
 *
 
1240
 * This routine returns 0 when successful, it returns proper error code
 
1241
 * back to the user space in error conditions.
 
1242
 */
 
1243
static int lpfc_idiag_cmd_get(const char __user *buf, size_t nbytes,
 
1244
                              struct lpfc_idiag_cmd *idiag_cmd)
 
1245
{
 
1246
        char mybuf[64];
 
1247
        char *pbuf, *step_str;
 
1248
        int i;
 
1249
        size_t bsize;
 
1250
 
 
1251
        /* Protect copy from user */
 
1252
        if (!access_ok(VERIFY_READ, buf, nbytes))
 
1253
                return -EFAULT;
 
1254
 
 
1255
        memset(mybuf, 0, sizeof(mybuf));
 
1256
        memset(idiag_cmd, 0, sizeof(*idiag_cmd));
 
1257
        bsize = min(nbytes, (sizeof(mybuf)-1));
 
1258
 
 
1259
        if (copy_from_user(mybuf, buf, bsize))
 
1260
                return -EFAULT;
 
1261
        pbuf = &mybuf[0];
 
1262
        step_str = strsep(&pbuf, "\t ");
 
1263
 
 
1264
        /* The opcode must present */
 
1265
        if (!step_str)
 
1266
                return -EINVAL;
 
1267
 
 
1268
        idiag_cmd->opcode = simple_strtol(step_str, NULL, 0);
 
1269
        if (idiag_cmd->opcode == 0)
 
1270
                return -EINVAL;
 
1271
 
 
1272
        for (i = 0; i < LPFC_IDIAG_CMD_DATA_SIZE; i++) {
 
1273
                step_str = strsep(&pbuf, "\t ");
 
1274
                if (!step_str)
 
1275
                        return i;
 
1276
                idiag_cmd->data[i] = simple_strtol(step_str, NULL, 0);
 
1277
        }
 
1278
        return i;
 
1279
}
 
1280
 
 
1281
/**
 
1282
 * lpfc_idiag_open - idiag open debugfs
 
1283
 * @inode: The inode pointer that contains a pointer to phba.
 
1284
 * @file: The file pointer to attach the file operation.
 
1285
 *
 
1286
 * Description:
 
1287
 * This routine is the entry point for the debugfs open file operation. It
 
1288
 * gets the reference to phba from the i_private field in @inode, it then
 
1289
 * allocates buffer for the file operation, performs the necessary PCI config
 
1290
 * space read into the allocated buffer according to the idiag user command
 
1291
 * setup, and then returns a pointer to buffer in the private_data field in
 
1292
 * @file.
 
1293
 *
 
1294
 * Returns:
 
1295
 * This function returns zero if successful. On error it will return an
 
1296
 * negative error value.
 
1297
 **/
 
1298
static int
 
1299
lpfc_idiag_open(struct inode *inode, struct file *file)
 
1300
{
 
1301
        struct lpfc_debug *debug;
 
1302
 
 
1303
        debug = kmalloc(sizeof(*debug), GFP_KERNEL);
 
1304
        if (!debug)
 
1305
                return -ENOMEM;
 
1306
 
 
1307
        debug->i_private = inode->i_private;
 
1308
        debug->buffer = NULL;
 
1309
        file->private_data = debug;
 
1310
 
 
1311
        return 0;
 
1312
}
 
1313
 
 
1314
/**
 
1315
 * lpfc_idiag_release - Release idiag access file operation
 
1316
 * @inode: The inode pointer that contains a vport pointer. (unused)
 
1317
 * @file: The file pointer that contains the buffer to release.
 
1318
 *
 
1319
 * Description:
 
1320
 * This routine is the generic release routine for the idiag access file
 
1321
 * operation, it frees the buffer that was allocated when the debugfs file
 
1322
 * was opened.
 
1323
 *
 
1324
 * Returns:
 
1325
 * This function returns zero.
 
1326
 **/
 
1327
static int
 
1328
lpfc_idiag_release(struct inode *inode, struct file *file)
 
1329
{
 
1330
        struct lpfc_debug *debug = file->private_data;
 
1331
 
 
1332
        /* Free the buffers to the file operation */
 
1333
        kfree(debug->buffer);
 
1334
        kfree(debug);
 
1335
 
 
1336
        return 0;
 
1337
}
 
1338
 
 
1339
/**
 
1340
 * lpfc_idiag_cmd_release - Release idiag cmd access file operation
 
1341
 * @inode: The inode pointer that contains a vport pointer. (unused)
 
1342
 * @file: The file pointer that contains the buffer to release.
 
1343
 *
 
1344
 * Description:
 
1345
 * This routine frees the buffer that was allocated when the debugfs file
 
1346
 * was opened. It also reset the fields in the idiag command struct in the
 
1347
 * case of command for write operation.
 
1348
 *
 
1349
 * Returns:
 
1350
 * This function returns zero.
 
1351
 **/
 
1352
static int
 
1353
lpfc_idiag_cmd_release(struct inode *inode, struct file *file)
 
1354
{
 
1355
        struct lpfc_debug *debug = file->private_data;
 
1356
 
 
1357
        if (debug->op == LPFC_IDIAG_OP_WR) {
 
1358
                switch (idiag.cmd.opcode) {
 
1359
                case LPFC_IDIAG_CMD_PCICFG_WR:
 
1360
                case LPFC_IDIAG_CMD_PCICFG_ST:
 
1361
                case LPFC_IDIAG_CMD_PCICFG_CL:
 
1362
                case LPFC_IDIAG_CMD_QUEACC_WR:
 
1363
                case LPFC_IDIAG_CMD_QUEACC_ST:
 
1364
                case LPFC_IDIAG_CMD_QUEACC_CL:
 
1365
                        memset(&idiag, 0, sizeof(idiag));
 
1366
                        break;
 
1367
                default:
 
1368
                        break;
 
1369
                }
 
1370
        }
 
1371
 
 
1372
        /* Free the buffers to the file operation */
 
1373
        kfree(debug->buffer);
 
1374
        kfree(debug);
 
1375
 
 
1376
        return 0;
 
1377
}
 
1378
 
 
1379
/**
 
1380
 * lpfc_idiag_pcicfg_read - idiag debugfs read pcicfg
 
1381
 * @file: The file pointer to read from.
 
1382
 * @buf: The buffer to copy the data to.
 
1383
 * @nbytes: The number of bytes to read.
 
1384
 * @ppos: The position in the file to start reading from.
 
1385
 *
 
1386
 * Description:
 
1387
 * This routine reads data from the @phba pci config space according to the
 
1388
 * idiag command, and copies to user @buf. Depending on the PCI config space
 
1389
 * read command setup, it does either a single register read of a byte
 
1390
 * (8 bits), a word (16 bits), or a dword (32 bits) or browsing through all
 
1391
 * registers from the 4K extended PCI config space.
 
1392
 *
 
1393
 * Returns:
 
1394
 * This function returns the amount of data that was read (this could be less
 
1395
 * than @nbytes if the end of the file was reached) or a negative error value.
 
1396
 **/
 
1397
static ssize_t
 
1398
lpfc_idiag_pcicfg_read(struct file *file, char __user *buf, size_t nbytes,
 
1399
                       loff_t *ppos)
 
1400
{
 
1401
        struct lpfc_debug *debug = file->private_data;
 
1402
        struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
 
1403
        int offset_label, offset, len = 0, index = LPFC_PCI_CFG_RD_SIZE;
 
1404
        int where, count;
 
1405
        char *pbuffer;
 
1406
        struct pci_dev *pdev;
 
1407
        uint32_t u32val;
 
1408
        uint16_t u16val;
 
1409
        uint8_t u8val;
 
1410
 
 
1411
        pdev = phba->pcidev;
 
1412
        if (!pdev)
 
1413
                return 0;
 
1414
 
 
1415
        /* This is a user read operation */
 
1416
        debug->op = LPFC_IDIAG_OP_RD;
 
1417
 
 
1418
        if (!debug->buffer)
 
1419
                debug->buffer = kmalloc(LPFC_PCI_CFG_SIZE, GFP_KERNEL);
 
1420
        if (!debug->buffer)
 
1421
                return 0;
 
1422
        pbuffer = debug->buffer;
 
1423
 
 
1424
        if (*ppos)
 
1425
                return 0;
 
1426
 
 
1427
        if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_RD) {
 
1428
                where = idiag.cmd.data[IDIAG_PCICFG_WHERE_INDX];
 
1429
                count = idiag.cmd.data[IDIAG_PCICFG_COUNT_INDX];
 
1430
        } else
 
1431
                return 0;
 
1432
 
 
1433
        /* Read single PCI config space register */
 
1434
        switch (count) {
 
1435
        case SIZE_U8: /* byte (8 bits) */
 
1436
                pci_read_config_byte(pdev, where, &u8val);
 
1437
                len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
 
1438
                                "%03x: %02x\n", where, u8val);
 
1439
                break;
 
1440
        case SIZE_U16: /* word (16 bits) */
 
1441
                pci_read_config_word(pdev, where, &u16val);
 
1442
                len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
 
1443
                                "%03x: %04x\n", where, u16val);
 
1444
                break;
 
1445
        case SIZE_U32: /* double word (32 bits) */
 
1446
                pci_read_config_dword(pdev, where, &u32val);
 
1447
                len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
 
1448
                                "%03x: %08x\n", where, u32val);
 
1449
                break;
 
1450
        case LPFC_PCI_CFG_BROWSE: /* browse all */
 
1451
                goto pcicfg_browse;
 
1452
                break;
 
1453
        default:
 
1454
                /* illegal count */
 
1455
                len = 0;
 
1456
                break;
 
1457
        }
 
1458
        return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
 
1459
 
 
1460
pcicfg_browse:
 
1461
 
 
1462
        /* Browse all PCI config space registers */
 
1463
        offset_label = idiag.offset.last_rd;
 
1464
        offset = offset_label;
 
1465
 
 
1466
        /* Read PCI config space */
 
1467
        len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
 
1468
                        "%03x: ", offset_label);
 
1469
        while (index > 0) {
 
1470
                pci_read_config_dword(pdev, offset, &u32val);
 
1471
                len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
 
1472
                                "%08x ", u32val);
 
1473
                offset += sizeof(uint32_t);
 
1474
                if (offset >= LPFC_PCI_CFG_SIZE) {
 
1475
                        len += snprintf(pbuffer+len,
 
1476
                                        LPFC_PCI_CFG_SIZE-len, "\n");
 
1477
                        break;
 
1478
                }
 
1479
                index -= sizeof(uint32_t);
 
1480
                if (!index)
 
1481
                        len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
 
1482
                                        "\n");
 
1483
                else if (!(index % (8 * sizeof(uint32_t)))) {
 
1484
                        offset_label += (8 * sizeof(uint32_t));
 
1485
                        len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
 
1486
                                        "\n%03x: ", offset_label);
 
1487
                }
 
1488
        }
 
1489
 
 
1490
        /* Set up the offset for next portion of pci cfg read */
 
1491
        if (index == 0) {
 
1492
                idiag.offset.last_rd += LPFC_PCI_CFG_RD_SIZE;
 
1493
                if (idiag.offset.last_rd >= LPFC_PCI_CFG_SIZE)
 
1494
                        idiag.offset.last_rd = 0;
 
1495
        } else
 
1496
                idiag.offset.last_rd = 0;
 
1497
 
 
1498
        return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
 
1499
}
 
1500
 
 
1501
/**
 
1502
 * lpfc_idiag_pcicfg_write - Syntax check and set up idiag pcicfg commands
 
1503
 * @file: The file pointer to read from.
 
1504
 * @buf: The buffer to copy the user data from.
 
1505
 * @nbytes: The number of bytes to get.
 
1506
 * @ppos: The position in the file to start reading from.
 
1507
 *
 
1508
 * This routine get the debugfs idiag command struct from user space and
 
1509
 * then perform the syntax check for PCI config space read or write command
 
1510
 * accordingly. In the case of PCI config space read command, it sets up
 
1511
 * the command in the idiag command struct for the debugfs read operation.
 
1512
 * In the case of PCI config space write operation, it executes the write
 
1513
 * operation into the PCI config space accordingly.
 
1514
 *
 
1515
 * It returns the @nbytges passing in from debugfs user space when successful.
 
1516
 * In case of error conditions, it returns proper error code back to the user
 
1517
 * space.
 
1518
 */
 
1519
static ssize_t
 
1520
lpfc_idiag_pcicfg_write(struct file *file, const char __user *buf,
 
1521
                        size_t nbytes, loff_t *ppos)
 
1522
{
 
1523
        struct lpfc_debug *debug = file->private_data;
 
1524
        struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
 
1525
        uint32_t where, value, count;
 
1526
        uint32_t u32val;
 
1527
        uint16_t u16val;
 
1528
        uint8_t u8val;
 
1529
        struct pci_dev *pdev;
 
1530
        int rc;
 
1531
 
 
1532
        pdev = phba->pcidev;
 
1533
        if (!pdev)
 
1534
                return -EFAULT;
 
1535
 
 
1536
        /* This is a user write operation */
 
1537
        debug->op = LPFC_IDIAG_OP_WR;
 
1538
 
 
1539
        rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
 
1540
        if (rc < 0)
 
1541
                return rc;
 
1542
 
 
1543
        if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_RD) {
 
1544
                /* Sanity check on PCI config read command line arguments */
 
1545
                if (rc != LPFC_PCI_CFG_RD_CMD_ARG)
 
1546
                        goto error_out;
 
1547
                /* Read command from PCI config space, set up command fields */
 
1548
                where = idiag.cmd.data[IDIAG_PCICFG_WHERE_INDX];
 
1549
                count = idiag.cmd.data[IDIAG_PCICFG_COUNT_INDX];
 
1550
                if (count == LPFC_PCI_CFG_BROWSE) {
 
1551
                        if (where % sizeof(uint32_t))
 
1552
                                goto error_out;
 
1553
                        /* Starting offset to browse */
 
1554
                        idiag.offset.last_rd = where;
 
1555
                } else if ((count != sizeof(uint8_t)) &&
 
1556
                           (count != sizeof(uint16_t)) &&
 
1557
                           (count != sizeof(uint32_t)))
 
1558
                        goto error_out;
 
1559
                if (count == sizeof(uint8_t)) {
 
1560
                        if (where > LPFC_PCI_CFG_SIZE - sizeof(uint8_t))
 
1561
                                goto error_out;
 
1562
                        if (where % sizeof(uint8_t))
 
1563
                                goto error_out;
 
1564
                }
 
1565
                if (count == sizeof(uint16_t)) {
 
1566
                        if (where > LPFC_PCI_CFG_SIZE - sizeof(uint16_t))
 
1567
                                goto error_out;
 
1568
                        if (where % sizeof(uint16_t))
 
1569
                                goto error_out;
 
1570
                }
 
1571
                if (count == sizeof(uint32_t)) {
 
1572
                        if (where > LPFC_PCI_CFG_SIZE - sizeof(uint32_t))
 
1573
                                goto error_out;
 
1574
                        if (where % sizeof(uint32_t))
 
1575
                                goto error_out;
 
1576
                }
 
1577
        } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_WR ||
 
1578
                   idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_ST ||
 
1579
                   idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_CL) {
 
1580
                /* Sanity check on PCI config write command line arguments */
 
1581
                if (rc != LPFC_PCI_CFG_WR_CMD_ARG)
 
1582
                        goto error_out;
 
1583
                /* Write command to PCI config space, read-modify-write */
 
1584
                where = idiag.cmd.data[IDIAG_PCICFG_WHERE_INDX];
 
1585
                count = idiag.cmd.data[IDIAG_PCICFG_COUNT_INDX];
 
1586
                value = idiag.cmd.data[IDIAG_PCICFG_VALUE_INDX];
 
1587
                /* Sanity checks */
 
1588
                if ((count != sizeof(uint8_t)) &&
 
1589
                    (count != sizeof(uint16_t)) &&
 
1590
                    (count != sizeof(uint32_t)))
 
1591
                        goto error_out;
 
1592
                if (count == sizeof(uint8_t)) {
 
1593
                        if (where > LPFC_PCI_CFG_SIZE - sizeof(uint8_t))
 
1594
                                goto error_out;
 
1595
                        if (where % sizeof(uint8_t))
 
1596
                                goto error_out;
 
1597
                        if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_WR)
 
1598
                                pci_write_config_byte(pdev, where,
 
1599
                                                      (uint8_t)value);
 
1600
                        if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_ST) {
 
1601
                                rc = pci_read_config_byte(pdev, where, &u8val);
 
1602
                                if (!rc) {
 
1603
                                        u8val |= (uint8_t)value;
 
1604
                                        pci_write_config_byte(pdev, where,
 
1605
                                                              u8val);
 
1606
                                }
 
1607
                        }
 
1608
                        if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_CL) {
 
1609
                                rc = pci_read_config_byte(pdev, where, &u8val);
 
1610
                                if (!rc) {
 
1611
                                        u8val &= (uint8_t)(~value);
 
1612
                                        pci_write_config_byte(pdev, where,
 
1613
                                                              u8val);
 
1614
                                }
 
1615
                        }
 
1616
                }
 
1617
                if (count == sizeof(uint16_t)) {
 
1618
                        if (where > LPFC_PCI_CFG_SIZE - sizeof(uint16_t))
 
1619
                                goto error_out;
 
1620
                        if (where % sizeof(uint16_t))
 
1621
                                goto error_out;
 
1622
                        if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_WR)
 
1623
                                pci_write_config_word(pdev, where,
 
1624
                                                      (uint16_t)value);
 
1625
                        if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_ST) {
 
1626
                                rc = pci_read_config_word(pdev, where, &u16val);
 
1627
                                if (!rc) {
 
1628
                                        u16val |= (uint16_t)value;
 
1629
                                        pci_write_config_word(pdev, where,
 
1630
                                                              u16val);
 
1631
                                }
 
1632
                        }
 
1633
                        if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_CL) {
 
1634
                                rc = pci_read_config_word(pdev, where, &u16val);
 
1635
                                if (!rc) {
 
1636
                                        u16val &= (uint16_t)(~value);
 
1637
                                        pci_write_config_word(pdev, where,
 
1638
                                                              u16val);
 
1639
                                }
 
1640
                        }
 
1641
                }
 
1642
                if (count == sizeof(uint32_t)) {
 
1643
                        if (where > LPFC_PCI_CFG_SIZE - sizeof(uint32_t))
 
1644
                                goto error_out;
 
1645
                        if (where % sizeof(uint32_t))
 
1646
                                goto error_out;
 
1647
                        if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_WR)
 
1648
                                pci_write_config_dword(pdev, where, value);
 
1649
                        if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_ST) {
 
1650
                                rc = pci_read_config_dword(pdev, where,
 
1651
                                                           &u32val);
 
1652
                                if (!rc) {
 
1653
                                        u32val |= value;
 
1654
                                        pci_write_config_dword(pdev, where,
 
1655
                                                               u32val);
 
1656
                                }
 
1657
                        }
 
1658
                        if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_CL) {
 
1659
                                rc = pci_read_config_dword(pdev, where,
 
1660
                                                           &u32val);
 
1661
                                if (!rc) {
 
1662
                                        u32val &= ~value;
 
1663
                                        pci_write_config_dword(pdev, where,
 
1664
                                                               u32val);
 
1665
                                }
 
1666
                        }
 
1667
                }
 
1668
        } else
 
1669
                /* All other opecodes are illegal for now */
 
1670
                goto error_out;
 
1671
 
 
1672
        return nbytes;
 
1673
error_out:
 
1674
        memset(&idiag, 0, sizeof(idiag));
 
1675
        return -EINVAL;
 
1676
}
 
1677
 
 
1678
/**
 
1679
 * lpfc_idiag_baracc_read - idiag debugfs pci bar access read
 
1680
 * @file: The file pointer to read from.
 
1681
 * @buf: The buffer to copy the data to.
 
1682
 * @nbytes: The number of bytes to read.
 
1683
 * @ppos: The position in the file to start reading from.
 
1684
 *
 
1685
 * Description:
 
1686
 * This routine reads data from the @phba pci bar memory mapped space
 
1687
 * according to the idiag command, and copies to user @buf.
 
1688
 *
 
1689
 * Returns:
 
1690
 * This function returns the amount of data that was read (this could be less
 
1691
 * than @nbytes if the end of the file was reached) or a negative error value.
 
1692
 **/
 
1693
static ssize_t
 
1694
lpfc_idiag_baracc_read(struct file *file, char __user *buf, size_t nbytes,
 
1695
                       loff_t *ppos)
 
1696
{
 
1697
        struct lpfc_debug *debug = file->private_data;
 
1698
        struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
 
1699
        int offset_label, offset, offset_run, len = 0, index;
 
1700
        int bar_num, acc_range, bar_size;
 
1701
        char *pbuffer;
 
1702
        void __iomem *mem_mapped_bar;
 
1703
        uint32_t if_type;
 
1704
        struct pci_dev *pdev;
 
1705
        uint32_t u32val;
 
1706
 
 
1707
        pdev = phba->pcidev;
 
1708
        if (!pdev)
 
1709
                return 0;
 
1710
 
 
1711
        /* This is a user read operation */
 
1712
        debug->op = LPFC_IDIAG_OP_RD;
 
1713
 
 
1714
        if (!debug->buffer)
 
1715
                debug->buffer = kmalloc(LPFC_PCI_BAR_RD_BUF_SIZE, GFP_KERNEL);
 
1716
        if (!debug->buffer)
 
1717
                return 0;
 
1718
        pbuffer = debug->buffer;
 
1719
 
 
1720
        if (*ppos)
 
1721
                return 0;
 
1722
 
 
1723
        if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_RD) {
 
1724
                bar_num   = idiag.cmd.data[IDIAG_BARACC_BAR_NUM_INDX];
 
1725
                offset    = idiag.cmd.data[IDIAG_BARACC_OFF_SET_INDX];
 
1726
                acc_range = idiag.cmd.data[IDIAG_BARACC_ACC_MOD_INDX];
 
1727
                bar_size = idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX];
 
1728
        } else
 
1729
                return 0;
 
1730
 
 
1731
        if (acc_range == 0)
 
1732
                return 0;
 
1733
 
 
1734
        if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
 
1735
        if (if_type == LPFC_SLI_INTF_IF_TYPE_0) {
 
1736
                if (bar_num == IDIAG_BARACC_BAR_0)
 
1737
                        mem_mapped_bar = phba->sli4_hba.conf_regs_memmap_p;
 
1738
                else if (bar_num == IDIAG_BARACC_BAR_1)
 
1739
                        mem_mapped_bar = phba->sli4_hba.ctrl_regs_memmap_p;
 
1740
                else if (bar_num == IDIAG_BARACC_BAR_2)
 
1741
                        mem_mapped_bar = phba->sli4_hba.drbl_regs_memmap_p;
 
1742
                else
 
1743
                        return 0;
 
1744
        } else if (if_type == LPFC_SLI_INTF_IF_TYPE_2) {
 
1745
                if (bar_num == IDIAG_BARACC_BAR_0)
 
1746
                        mem_mapped_bar = phba->sli4_hba.conf_regs_memmap_p;
 
1747
                else
 
1748
                        return 0;
 
1749
        } else
 
1750
                return 0;
 
1751
 
 
1752
        /* Read single PCI bar space register */
 
1753
        if (acc_range == SINGLE_WORD) {
 
1754
                offset_run = offset;
 
1755
                u32val = readl(mem_mapped_bar + offset_run);
 
1756
                len += snprintf(pbuffer+len, LPFC_PCI_BAR_RD_BUF_SIZE-len,
 
1757
                                "%05x: %08x\n", offset_run, u32val);
 
1758
        } else
 
1759
                goto baracc_browse;
 
1760
 
 
1761
        return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
 
1762
 
 
1763
baracc_browse:
 
1764
 
 
1765
        /* Browse all PCI bar space registers */
 
1766
        offset_label = idiag.offset.last_rd;
 
1767
        offset_run = offset_label;
 
1768
 
 
1769
        /* Read PCI bar memory mapped space */
 
1770
        len += snprintf(pbuffer+len, LPFC_PCI_BAR_RD_BUF_SIZE-len,
 
1771
                        "%05x: ", offset_label);
 
1772
        index = LPFC_PCI_BAR_RD_SIZE;
 
1773
        while (index > 0) {
 
1774
                u32val = readl(mem_mapped_bar + offset_run);
 
1775
                len += snprintf(pbuffer+len, LPFC_PCI_BAR_RD_BUF_SIZE-len,
 
1776
                                "%08x ", u32val);
 
1777
                offset_run += sizeof(uint32_t);
 
1778
                if (acc_range == LPFC_PCI_BAR_BROWSE) {
 
1779
                        if (offset_run >= bar_size) {
 
1780
                                len += snprintf(pbuffer+len,
 
1781
                                        LPFC_PCI_BAR_RD_BUF_SIZE-len, "\n");
 
1782
                                break;
 
1783
                        }
 
1784
                } else {
 
1785
                        if (offset_run >= offset +
 
1786
                            (acc_range * sizeof(uint32_t))) {
 
1787
                                len += snprintf(pbuffer+len,
 
1788
                                        LPFC_PCI_BAR_RD_BUF_SIZE-len, "\n");
 
1789
                                break;
 
1790
                        }
 
1791
                }
 
1792
                index -= sizeof(uint32_t);
 
1793
                if (!index)
 
1794
                        len += snprintf(pbuffer+len,
 
1795
                                        LPFC_PCI_BAR_RD_BUF_SIZE-len, "\n");
 
1796
                else if (!(index % (8 * sizeof(uint32_t)))) {
 
1797
                        offset_label += (8 * sizeof(uint32_t));
 
1798
                        len += snprintf(pbuffer+len,
 
1799
                                        LPFC_PCI_BAR_RD_BUF_SIZE-len,
 
1800
                                        "\n%05x: ", offset_label);
 
1801
                }
 
1802
        }
 
1803
 
 
1804
        /* Set up the offset for next portion of pci bar read */
 
1805
        if (index == 0) {
 
1806
                idiag.offset.last_rd += LPFC_PCI_BAR_RD_SIZE;
 
1807
                if (acc_range == LPFC_PCI_BAR_BROWSE) {
 
1808
                        if (idiag.offset.last_rd >= bar_size)
 
1809
                                idiag.offset.last_rd = 0;
 
1810
                } else {
 
1811
                        if (offset_run >= offset +
 
1812
                            (acc_range * sizeof(uint32_t)))
 
1813
                                idiag.offset.last_rd = offset;
 
1814
                }
 
1815
        } else {
 
1816
                if (acc_range == LPFC_PCI_BAR_BROWSE)
 
1817
                        idiag.offset.last_rd = 0;
 
1818
                else
 
1819
                        idiag.offset.last_rd = offset;
 
1820
        }
 
1821
 
 
1822
        return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
 
1823
}
 
1824
 
 
1825
/**
 
1826
 * lpfc_idiag_baracc_write - Syntax check and set up idiag bar access commands
 
1827
 * @file: The file pointer to read from.
 
1828
 * @buf: The buffer to copy the user data from.
 
1829
 * @nbytes: The number of bytes to get.
 
1830
 * @ppos: The position in the file to start reading from.
 
1831
 *
 
1832
 * This routine get the debugfs idiag command struct from user space and
 
1833
 * then perform the syntax check for PCI bar memory mapped space read or
 
1834
 * write command accordingly. In the case of PCI bar memory mapped space
 
1835
 * read command, it sets up the command in the idiag command struct for
 
1836
 * the debugfs read operation. In the case of PCI bar memorpy mapped space
 
1837
 * write operation, it executes the write operation into the PCI bar memory
 
1838
 * mapped space accordingly.
 
1839
 *
 
1840
 * It returns the @nbytges passing in from debugfs user space when successful.
 
1841
 * In case of error conditions, it returns proper error code back to the user
 
1842
 * space.
 
1843
 */
 
1844
static ssize_t
 
1845
lpfc_idiag_baracc_write(struct file *file, const char __user *buf,
 
1846
                        size_t nbytes, loff_t *ppos)
 
1847
{
 
1848
        struct lpfc_debug *debug = file->private_data;
 
1849
        struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
 
1850
        uint32_t bar_num, bar_size, offset, value, acc_range;
 
1851
        struct pci_dev *pdev;
 
1852
        void __iomem *mem_mapped_bar;
 
1853
        uint32_t if_type;
 
1854
        uint32_t u32val;
 
1855
        int rc;
 
1856
 
 
1857
        pdev = phba->pcidev;
 
1858
        if (!pdev)
 
1859
                return -EFAULT;
 
1860
 
 
1861
        /* This is a user write operation */
 
1862
        debug->op = LPFC_IDIAG_OP_WR;
 
1863
 
 
1864
        rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
 
1865
        if (rc < 0)
 
1866
                return rc;
 
1867
 
 
1868
        if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
 
1869
        bar_num = idiag.cmd.data[IDIAG_BARACC_BAR_NUM_INDX];
 
1870
 
 
1871
        if (if_type == LPFC_SLI_INTF_IF_TYPE_0) {
 
1872
                if ((bar_num != IDIAG_BARACC_BAR_0) &&
 
1873
                    (bar_num != IDIAG_BARACC_BAR_1) &&
 
1874
                    (bar_num != IDIAG_BARACC_BAR_2))
 
1875
                        goto error_out;
 
1876
        } else if (if_type == LPFC_SLI_INTF_IF_TYPE_2) {
 
1877
                if (bar_num != IDIAG_BARACC_BAR_0)
 
1878
                        goto error_out;
 
1879
        } else
 
1880
                goto error_out;
 
1881
 
 
1882
        if (if_type == LPFC_SLI_INTF_IF_TYPE_0) {
 
1883
                if (bar_num == IDIAG_BARACC_BAR_0) {
 
1884
                        idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX] =
 
1885
                                LPFC_PCI_IF0_BAR0_SIZE;
 
1886
                        mem_mapped_bar = phba->sli4_hba.conf_regs_memmap_p;
 
1887
                } else if (bar_num == IDIAG_BARACC_BAR_1) {
 
1888
                        idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX] =
 
1889
                                LPFC_PCI_IF0_BAR1_SIZE;
 
1890
                        mem_mapped_bar = phba->sli4_hba.ctrl_regs_memmap_p;
 
1891
                } else if (bar_num == IDIAG_BARACC_BAR_2) {
 
1892
                        idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX] =
 
1893
                                LPFC_PCI_IF0_BAR2_SIZE;
 
1894
                        mem_mapped_bar = phba->sli4_hba.drbl_regs_memmap_p;
 
1895
                } else
 
1896
                        goto error_out;
 
1897
        } else if (if_type == LPFC_SLI_INTF_IF_TYPE_2) {
 
1898
                if (bar_num == IDIAG_BARACC_BAR_0) {
 
1899
                        idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX] =
 
1900
                                LPFC_PCI_IF2_BAR0_SIZE;
 
1901
                        mem_mapped_bar = phba->sli4_hba.conf_regs_memmap_p;
 
1902
                } else
 
1903
                        goto error_out;
 
1904
        } else
 
1905
                goto error_out;
 
1906
 
 
1907
        offset = idiag.cmd.data[IDIAG_BARACC_OFF_SET_INDX];
 
1908
        if (offset % sizeof(uint32_t))
 
1909
                goto error_out;
 
1910
 
 
1911
        bar_size = idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX];
 
1912
        if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_RD) {
 
1913
                /* Sanity check on PCI config read command line arguments */
 
1914
                if (rc != LPFC_PCI_BAR_RD_CMD_ARG)
 
1915
                        goto error_out;
 
1916
                acc_range = idiag.cmd.data[IDIAG_BARACC_ACC_MOD_INDX];
 
1917
                if (acc_range == LPFC_PCI_BAR_BROWSE) {
 
1918
                        if (offset > bar_size - sizeof(uint32_t))
 
1919
                                goto error_out;
 
1920
                        /* Starting offset to browse */
 
1921
                        idiag.offset.last_rd = offset;
 
1922
                } else if (acc_range > SINGLE_WORD) {
 
1923
                        if (offset + acc_range * sizeof(uint32_t) > bar_size)
 
1924
                                goto error_out;
 
1925
                        /* Starting offset to browse */
 
1926
                        idiag.offset.last_rd = offset;
 
1927
                } else if (acc_range != SINGLE_WORD)
 
1928
                        goto error_out;
 
1929
        } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_WR ||
 
1930
                   idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_ST ||
 
1931
                   idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_CL) {
 
1932
                /* Sanity check on PCI bar write command line arguments */
 
1933
                if (rc != LPFC_PCI_BAR_WR_CMD_ARG)
 
1934
                        goto error_out;
 
1935
                /* Write command to PCI bar space, read-modify-write */
 
1936
                acc_range = SINGLE_WORD;
 
1937
                value = idiag.cmd.data[IDIAG_BARACC_REG_VAL_INDX];
 
1938
                if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_WR) {
 
1939
                        writel(value, mem_mapped_bar + offset);
 
1940
                        readl(mem_mapped_bar + offset);
 
1941
                }
 
1942
                if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_ST) {
 
1943
                        u32val = readl(mem_mapped_bar + offset);
 
1944
                        u32val |= value;
 
1945
                        writel(u32val, mem_mapped_bar + offset);
 
1946
                        readl(mem_mapped_bar + offset);
 
1947
                }
 
1948
                if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_CL) {
 
1949
                        u32val = readl(mem_mapped_bar + offset);
 
1950
                        u32val &= ~value;
 
1951
                        writel(u32val, mem_mapped_bar + offset);
 
1952
                        readl(mem_mapped_bar + offset);
 
1953
                }
 
1954
        } else
 
1955
                /* All other opecodes are illegal for now */
 
1956
                goto error_out;
 
1957
 
 
1958
        return nbytes;
 
1959
error_out:
 
1960
        memset(&idiag, 0, sizeof(idiag));
 
1961
        return -EINVAL;
 
1962
}
 
1963
 
 
1964
/**
 
1965
 * lpfc_idiag_queinfo_read - idiag debugfs read queue information
 
1966
 * @file: The file pointer to read from.
 
1967
 * @buf: The buffer to copy the data to.
 
1968
 * @nbytes: The number of bytes to read.
 
1969
 * @ppos: The position in the file to start reading from.
 
1970
 *
 
1971
 * Description:
 
1972
 * This routine reads data from the @phba SLI4 PCI function queue information,
 
1973
 * and copies to user @buf.
 
1974
 *
 
1975
 * Returns:
 
1976
 * This function returns the amount of data that was read (this could be less
 
1977
 * than @nbytes if the end of the file was reached) or a negative error value.
 
1978
 **/
 
1979
static ssize_t
 
1980
lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes,
 
1981
                        loff_t *ppos)
 
1982
{
 
1983
        struct lpfc_debug *debug = file->private_data;
 
1984
        struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
 
1985
        int len = 0, fcp_qidx;
 
1986
        char *pbuffer;
 
1987
 
 
1988
        if (!debug->buffer)
 
1989
                debug->buffer = kmalloc(LPFC_QUE_INFO_GET_BUF_SIZE, GFP_KERNEL);
 
1990
        if (!debug->buffer)
 
1991
                return 0;
 
1992
        pbuffer = debug->buffer;
 
1993
 
 
1994
        if (*ppos)
 
1995
                return 0;
 
1996
 
 
1997
        /* Get slow-path event queue information */
 
1998
        len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
 
1999
                        "Slow-path EQ information:\n");
 
2000
        len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
 
2001
                        "\tEQID[%02d], "
 
2002
                        "QE-COUNT[%04d], QE-SIZE[%04d], "
 
2003
                        "HOST-INDEX[%04d], PORT-INDEX[%04d]\n\n",
 
2004
                        phba->sli4_hba.sp_eq->queue_id,
 
2005
                        phba->sli4_hba.sp_eq->entry_count,
 
2006
                        phba->sli4_hba.sp_eq->entry_size,
 
2007
                        phba->sli4_hba.sp_eq->host_index,
 
2008
                        phba->sli4_hba.sp_eq->hba_index);
 
2009
 
 
2010
        /* Get fast-path event queue information */
 
2011
        len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
 
2012
                        "Fast-path EQ information:\n");
 
2013
        for (fcp_qidx = 0; fcp_qidx < phba->cfg_fcp_eq_count; fcp_qidx++) {
 
2014
                len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
 
2015
                                "\tEQID[%02d], "
 
2016
                                "QE-COUNT[%04d], QE-SIZE[%04d], "
 
2017
                                "HOST-INDEX[%04d], PORT-INDEX[%04d]\n",
 
2018
                                phba->sli4_hba.fp_eq[fcp_qidx]->queue_id,
 
2019
                                phba->sli4_hba.fp_eq[fcp_qidx]->entry_count,
 
2020
                                phba->sli4_hba.fp_eq[fcp_qidx]->entry_size,
 
2021
                                phba->sli4_hba.fp_eq[fcp_qidx]->host_index,
 
2022
                                phba->sli4_hba.fp_eq[fcp_qidx]->hba_index);
 
2023
        }
 
2024
        len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
 
2025
 
 
2026
        /* Get mailbox complete queue information */
 
2027
        len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
 
2028
                        "Slow-path MBX CQ information:\n");
 
2029
        len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
 
2030
                        "Associated EQID[%02d]:\n",
 
2031
                        phba->sli4_hba.mbx_cq->assoc_qid);
 
2032
        len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
 
2033
                        "\tCQID[%02d], "
 
2034
                        "QE-COUNT[%04d], QE-SIZE[%04d], "
 
2035
                        "HOST-INDEX[%04d], PORT-INDEX[%04d]\n\n",
 
2036
                        phba->sli4_hba.mbx_cq->queue_id,
 
2037
                        phba->sli4_hba.mbx_cq->entry_count,
 
2038
                        phba->sli4_hba.mbx_cq->entry_size,
 
2039
                        phba->sli4_hba.mbx_cq->host_index,
 
2040
                        phba->sli4_hba.mbx_cq->hba_index);
 
2041
 
 
2042
        /* Get slow-path complete queue information */
 
2043
        len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
 
2044
                        "Slow-path ELS CQ information:\n");
 
2045
        len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
 
2046
                        "Associated EQID[%02d]:\n",
 
2047
                        phba->sli4_hba.els_cq->assoc_qid);
 
2048
        len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
 
2049
                        "\tCQID [%02d], "
 
2050
                        "QE-COUNT[%04d], QE-SIZE[%04d], "
 
2051
                        "HOST-INDEX[%04d], PORT-INDEX[%04d]\n\n",
 
2052
                        phba->sli4_hba.els_cq->queue_id,
 
2053
                        phba->sli4_hba.els_cq->entry_count,
 
2054
                        phba->sli4_hba.els_cq->entry_size,
 
2055
                        phba->sli4_hba.els_cq->host_index,
 
2056
                        phba->sli4_hba.els_cq->hba_index);
 
2057
 
 
2058
        /* Get fast-path complete queue information */
 
2059
        len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
 
2060
                        "Fast-path FCP CQ information:\n");
 
2061
        fcp_qidx = 0;
 
2062
        do {
 
2063
                len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
 
2064
                                "Associated EQID[%02d]:\n",
 
2065
                                phba->sli4_hba.fcp_cq[fcp_qidx]->assoc_qid);
 
2066
                len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
 
2067
                                "\tCQID[%02d], "
 
2068
                                "QE-COUNT[%04d], QE-SIZE[%04d], "
 
2069
                                "HOST-INDEX[%04d], PORT-INDEX[%04d]\n",
 
2070
                                phba->sli4_hba.fcp_cq[fcp_qidx]->queue_id,
 
2071
                                phba->sli4_hba.fcp_cq[fcp_qidx]->entry_count,
 
2072
                                phba->sli4_hba.fcp_cq[fcp_qidx]->entry_size,
 
2073
                                phba->sli4_hba.fcp_cq[fcp_qidx]->host_index,
 
2074
                                phba->sli4_hba.fcp_cq[fcp_qidx]->hba_index);
 
2075
        } while (++fcp_qidx < phba->cfg_fcp_eq_count);
 
2076
        len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
 
2077
 
 
2078
        /* Get mailbox queue information */
 
2079
        len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
 
2080
                        "Slow-path MBX MQ information:\n");
 
2081
        len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
 
2082
                        "Associated CQID[%02d]:\n",
 
2083
                        phba->sli4_hba.mbx_wq->assoc_qid);
 
2084
        len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
 
2085
                        "\tWQID[%02d], "
 
2086
                        "QE-COUNT[%04d], QE-SIZE[%04d], "
 
2087
                        "HOST-INDEX[%04d], PORT-INDEX[%04d]\n\n",
 
2088
                        phba->sli4_hba.mbx_wq->queue_id,
 
2089
                        phba->sli4_hba.mbx_wq->entry_count,
 
2090
                        phba->sli4_hba.mbx_wq->entry_size,
 
2091
                        phba->sli4_hba.mbx_wq->host_index,
 
2092
                        phba->sli4_hba.mbx_wq->hba_index);
 
2093
 
 
2094
        /* Get slow-path work queue information */
 
2095
        len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
 
2096
                        "Slow-path ELS WQ information:\n");
 
2097
        len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
 
2098
                        "Associated CQID[%02d]:\n",
 
2099
                        phba->sli4_hba.els_wq->assoc_qid);
 
2100
        len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
 
2101
                        "\tWQID[%02d], "
 
2102
                        "QE-COUNT[%04d], QE-SIZE[%04d], "
 
2103
                        "HOST-INDEX[%04d], PORT-INDEX[%04d]\n\n",
 
2104
                        phba->sli4_hba.els_wq->queue_id,
 
2105
                        phba->sli4_hba.els_wq->entry_count,
 
2106
                        phba->sli4_hba.els_wq->entry_size,
 
2107
                        phba->sli4_hba.els_wq->host_index,
 
2108
                        phba->sli4_hba.els_wq->hba_index);
 
2109
 
 
2110
        /* Get fast-path work queue information */
 
2111
        len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
 
2112
                        "Fast-path FCP WQ information:\n");
 
2113
        for (fcp_qidx = 0; fcp_qidx < phba->cfg_fcp_wq_count; fcp_qidx++) {
 
2114
                len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
 
2115
                                "Associated CQID[%02d]:\n",
 
2116
                                phba->sli4_hba.fcp_wq[fcp_qidx]->assoc_qid);
 
2117
                len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
 
2118
                                "\tWQID[%02d], "
 
2119
                                "QE-COUNT[%04d], WQE-SIZE[%04d], "
 
2120
                                "HOST-INDEX[%04d], PORT-INDEX[%04d]\n",
 
2121
                                phba->sli4_hba.fcp_wq[fcp_qidx]->queue_id,
 
2122
                                phba->sli4_hba.fcp_wq[fcp_qidx]->entry_count,
 
2123
                                phba->sli4_hba.fcp_wq[fcp_qidx]->entry_size,
 
2124
                                phba->sli4_hba.fcp_wq[fcp_qidx]->host_index,
 
2125
                                phba->sli4_hba.fcp_wq[fcp_qidx]->hba_index);
 
2126
        }
 
2127
        len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
 
2128
 
 
2129
        /* Get receive queue information */
 
2130
        len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
 
2131
                        "Slow-path RQ information:\n");
 
2132
        len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
 
2133
                        "Associated CQID[%02d]:\n",
 
2134
                        phba->sli4_hba.hdr_rq->assoc_qid);
 
2135
        len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
 
2136
                        "\tHQID[%02d], "
 
2137
                        "QE-COUNT[%04d], QE-SIZE[%04d], "
 
2138
                        "HOST-INDEX[%04d], PORT-INDEX[%04d]\n",
 
2139
                        phba->sli4_hba.hdr_rq->queue_id,
 
2140
                        phba->sli4_hba.hdr_rq->entry_count,
 
2141
                        phba->sli4_hba.hdr_rq->entry_size,
 
2142
                        phba->sli4_hba.hdr_rq->host_index,
 
2143
                        phba->sli4_hba.hdr_rq->hba_index);
 
2144
        len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
 
2145
                        "\tDQID[%02d], "
 
2146
                        "QE-COUNT[%04d], QE-SIZE[%04d], "
 
2147
                        "HOST-INDEX[%04d], PORT-INDEX[%04d]\n",
 
2148
                        phba->sli4_hba.dat_rq->queue_id,
 
2149
                        phba->sli4_hba.dat_rq->entry_count,
 
2150
                        phba->sli4_hba.dat_rq->entry_size,
 
2151
                        phba->sli4_hba.dat_rq->host_index,
 
2152
                        phba->sli4_hba.dat_rq->hba_index);
 
2153
 
 
2154
        return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
 
2155
}
 
2156
 
 
2157
/**
 
2158
 * lpfc_idiag_que_param_check - queue access command parameter sanity check
 
2159
 * @q: The pointer to queue structure.
 
2160
 * @index: The index into a queue entry.
 
2161
 * @count: The number of queue entries to access.
 
2162
 *
 
2163
 * Description:
 
2164
 * The routine performs sanity check on device queue access method commands.
 
2165
 *
 
2166
 * Returns:
 
2167
 * This function returns -EINVAL when fails the sanity check, otherwise, it
 
2168
 * returns 0.
 
2169
 **/
 
2170
static int
 
2171
lpfc_idiag_que_param_check(struct lpfc_queue *q, int index, int count)
 
2172
{
 
2173
        /* Only support single entry read or browsing */
 
2174
        if ((count != 1) && (count != LPFC_QUE_ACC_BROWSE))
 
2175
                return -EINVAL;
 
2176
        if (index > q->entry_count - 1)
 
2177
                return -EINVAL;
 
2178
        return 0;
 
2179
}
 
2180
 
 
2181
/**
 
2182
 * lpfc_idiag_queacc_read_qe - read a single entry from the given queue index
 
2183
 * @pbuffer: The pointer to buffer to copy the read data into.
 
2184
 * @pque: The pointer to the queue to be read.
 
2185
 * @index: The index into the queue entry.
 
2186
 *
 
2187
 * Description:
 
2188
 * This routine reads out a single entry from the given queue's index location
 
2189
 * and copies it into the buffer provided.
 
2190
 *
 
2191
 * Returns:
 
2192
 * This function returns 0 when it fails, otherwise, it returns the length of
 
2193
 * the data read into the buffer provided.
 
2194
 **/
 
2195
static int
 
2196
lpfc_idiag_queacc_read_qe(char *pbuffer, int len, struct lpfc_queue *pque,
 
2197
                          uint32_t index)
 
2198
{
 
2199
        int offset, esize;
 
2200
        uint32_t *pentry;
 
2201
 
 
2202
        if (!pbuffer || !pque)
 
2203
                return 0;
 
2204
 
 
2205
        esize = pque->entry_size;
 
2206
        len += snprintf(pbuffer+len, LPFC_QUE_ACC_BUF_SIZE-len,
 
2207
                        "QE-INDEX[%04d]:\n", index);
 
2208
 
 
2209
        offset = 0;
 
2210
        pentry = pque->qe[index].address;
 
2211
        while (esize > 0) {
 
2212
                len += snprintf(pbuffer+len, LPFC_QUE_ACC_BUF_SIZE-len,
 
2213
                                "%08x ", *pentry);
 
2214
                pentry++;
 
2215
                offset += sizeof(uint32_t);
 
2216
                esize -= sizeof(uint32_t);
 
2217
                if (esize > 0 && !(offset % (4 * sizeof(uint32_t))))
 
2218
                        len += snprintf(pbuffer+len,
 
2219
                                        LPFC_QUE_ACC_BUF_SIZE-len, "\n");
 
2220
        }
 
2221
        len += snprintf(pbuffer+len, LPFC_QUE_ACC_BUF_SIZE-len, "\n");
 
2222
 
 
2223
        return len;
 
2224
}
 
2225
 
 
2226
/**
 
2227
 * lpfc_idiag_queacc_read - idiag debugfs read port queue
 
2228
 * @file: The file pointer to read from.
 
2229
 * @buf: The buffer to copy the data to.
 
2230
 * @nbytes: The number of bytes to read.
 
2231
 * @ppos: The position in the file to start reading from.
 
2232
 *
 
2233
 * Description:
 
2234
 * This routine reads data from the @phba device queue memory according to the
 
2235
 * idiag command, and copies to user @buf. Depending on the queue dump read
 
2236
 * command setup, it does either a single queue entry read or browing through
 
2237
 * all entries of the queue.
 
2238
 *
 
2239
 * Returns:
 
2240
 * This function returns the amount of data that was read (this could be less
 
2241
 * than @nbytes if the end of the file was reached) or a negative error value.
 
2242
 **/
 
2243
static ssize_t
 
2244
lpfc_idiag_queacc_read(struct file *file, char __user *buf, size_t nbytes,
 
2245
                       loff_t *ppos)
 
2246
{
 
2247
        struct lpfc_debug *debug = file->private_data;
 
2248
        uint32_t last_index, index, count;
 
2249
        struct lpfc_queue *pque = NULL;
 
2250
        char *pbuffer;
 
2251
        int len = 0;
 
2252
 
 
2253
        /* This is a user read operation */
 
2254
        debug->op = LPFC_IDIAG_OP_RD;
 
2255
 
 
2256
        if (!debug->buffer)
 
2257
                debug->buffer = kmalloc(LPFC_QUE_ACC_BUF_SIZE, GFP_KERNEL);
 
2258
        if (!debug->buffer)
 
2259
                return 0;
 
2260
        pbuffer = debug->buffer;
 
2261
 
 
2262
        if (*ppos)
 
2263
                return 0;
 
2264
 
 
2265
        if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_RD) {
 
2266
                index = idiag.cmd.data[IDIAG_QUEACC_INDEX_INDX];
 
2267
                count = idiag.cmd.data[IDIAG_QUEACC_COUNT_INDX];
 
2268
                pque = (struct lpfc_queue *)idiag.ptr_private;
 
2269
        } else
 
2270
                return 0;
 
2271
 
 
2272
        /* Browse the queue starting from index */
 
2273
        if (count == LPFC_QUE_ACC_BROWSE)
 
2274
                goto que_browse;
 
2275
 
 
2276
        /* Read a single entry from the queue */
 
2277
        len = lpfc_idiag_queacc_read_qe(pbuffer, len, pque, index);
 
2278
 
 
2279
        return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
 
2280
 
 
2281
que_browse:
 
2282
 
 
2283
        /* Browse all entries from the queue */
 
2284
        last_index = idiag.offset.last_rd;
 
2285
        index = last_index;
 
2286
 
 
2287
        while (len < LPFC_QUE_ACC_SIZE - pque->entry_size) {
 
2288
                len = lpfc_idiag_queacc_read_qe(pbuffer, len, pque, index);
 
2289
                index++;
 
2290
                if (index > pque->entry_count - 1)
 
2291
                        break;
 
2292
        }
 
2293
 
 
2294
        /* Set up the offset for next portion of pci cfg read */
 
2295
        if (index > pque->entry_count - 1)
 
2296
                index = 0;
 
2297
        idiag.offset.last_rd = index;
 
2298
 
 
2299
        return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
 
2300
}
 
2301
 
 
2302
/**
 
2303
 * lpfc_idiag_queacc_write - Syntax check and set up idiag queacc commands
 
2304
 * @file: The file pointer to read from.
 
2305
 * @buf: The buffer to copy the user data from.
 
2306
 * @nbytes: The number of bytes to get.
 
2307
 * @ppos: The position in the file to start reading from.
 
2308
 *
 
2309
 * This routine get the debugfs idiag command struct from user space and then
 
2310
 * perform the syntax check for port queue read (dump) or write (set) command
 
2311
 * accordingly. In the case of port queue read command, it sets up the command
 
2312
 * in the idiag command struct for the following debugfs read operation. In
 
2313
 * the case of port queue write operation, it executes the write operation
 
2314
 * into the port queue entry accordingly.
 
2315
 *
 
2316
 * It returns the @nbytges passing in from debugfs user space when successful.
 
2317
 * In case of error conditions, it returns proper error code back to the user
 
2318
 * space.
 
2319
 **/
 
2320
static ssize_t
 
2321
lpfc_idiag_queacc_write(struct file *file, const char __user *buf,
 
2322
                        size_t nbytes, loff_t *ppos)
 
2323
{
 
2324
        struct lpfc_debug *debug = file->private_data;
 
2325
        struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
 
2326
        uint32_t qidx, quetp, queid, index, count, offset, value;
 
2327
        uint32_t *pentry;
 
2328
        struct lpfc_queue *pque;
 
2329
        int rc;
 
2330
 
 
2331
        /* This is a user write operation */
 
2332
        debug->op = LPFC_IDIAG_OP_WR;
 
2333
 
 
2334
        rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
 
2335
        if (rc < 0)
 
2336
                return rc;
 
2337
 
 
2338
        /* Get and sanity check on command feilds */
 
2339
        quetp  = idiag.cmd.data[IDIAG_QUEACC_QUETP_INDX];
 
2340
        queid  = idiag.cmd.data[IDIAG_QUEACC_QUEID_INDX];
 
2341
        index  = idiag.cmd.data[IDIAG_QUEACC_INDEX_INDX];
 
2342
        count  = idiag.cmd.data[IDIAG_QUEACC_COUNT_INDX];
 
2343
        offset = idiag.cmd.data[IDIAG_QUEACC_OFFST_INDX];
 
2344
        value  = idiag.cmd.data[IDIAG_QUEACC_VALUE_INDX];
 
2345
 
 
2346
        /* Sanity check on command line arguments */
 
2347
        if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_WR ||
 
2348
            idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_ST ||
 
2349
            idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_CL) {
 
2350
                if (rc != LPFC_QUE_ACC_WR_CMD_ARG)
 
2351
                        goto error_out;
 
2352
                if (count != 1)
 
2353
                        goto error_out;
 
2354
        } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_RD) {
 
2355
                if (rc != LPFC_QUE_ACC_RD_CMD_ARG)
 
2356
                        goto error_out;
 
2357
        } else
 
2358
                goto error_out;
 
2359
 
 
2360
        switch (quetp) {
 
2361
        case LPFC_IDIAG_EQ:
 
2362
                /* Slow-path event queue */
 
2363
                if (phba->sli4_hba.sp_eq->queue_id == queid) {
 
2364
                        /* Sanity check */
 
2365
                        rc = lpfc_idiag_que_param_check(
 
2366
                                        phba->sli4_hba.sp_eq, index, count);
 
2367
                        if (rc)
 
2368
                                goto error_out;
 
2369
                        idiag.ptr_private = phba->sli4_hba.sp_eq;
 
2370
                        goto pass_check;
 
2371
                }
 
2372
                /* Fast-path event queue */
 
2373
                for (qidx = 0; qidx < phba->cfg_fcp_eq_count; qidx++) {
 
2374
                        if (phba->sli4_hba.fp_eq[qidx]->queue_id == queid) {
 
2375
                                /* Sanity check */
 
2376
                                rc = lpfc_idiag_que_param_check(
 
2377
                                                phba->sli4_hba.fp_eq[qidx],
 
2378
                                                index, count);
 
2379
                                if (rc)
 
2380
                                        goto error_out;
 
2381
                                idiag.ptr_private = phba->sli4_hba.fp_eq[qidx];
 
2382
                                goto pass_check;
 
2383
                        }
 
2384
                }
 
2385
                goto error_out;
 
2386
                break;
 
2387
        case LPFC_IDIAG_CQ:
 
2388
                /* MBX complete queue */
 
2389
                if (phba->sli4_hba.mbx_cq->queue_id == queid) {
 
2390
                        /* Sanity check */
 
2391
                        rc = lpfc_idiag_que_param_check(
 
2392
                                        phba->sli4_hba.mbx_cq, index, count);
 
2393
                        if (rc)
 
2394
                                goto error_out;
 
2395
                        idiag.ptr_private = phba->sli4_hba.mbx_cq;
 
2396
                        goto pass_check;
 
2397
                }
 
2398
                /* ELS complete queue */
 
2399
                if (phba->sli4_hba.els_cq->queue_id == queid) {
 
2400
                        /* Sanity check */
 
2401
                        rc = lpfc_idiag_que_param_check(
 
2402
                                        phba->sli4_hba.els_cq, index, count);
 
2403
                        if (rc)
 
2404
                                goto error_out;
 
2405
                        idiag.ptr_private = phba->sli4_hba.els_cq;
 
2406
                        goto pass_check;
 
2407
                }
 
2408
                /* FCP complete queue */
 
2409
                qidx = 0;
 
2410
                do {
 
2411
                        if (phba->sli4_hba.fcp_cq[qidx]->queue_id == queid) {
 
2412
                                /* Sanity check */
 
2413
                                rc = lpfc_idiag_que_param_check(
 
2414
                                                phba->sli4_hba.fcp_cq[qidx],
 
2415
                                                index, count);
 
2416
                                if (rc)
 
2417
                                        goto error_out;
 
2418
                                idiag.ptr_private =
 
2419
                                                phba->sli4_hba.fcp_cq[qidx];
 
2420
                                goto pass_check;
 
2421
                        }
 
2422
                } while (++qidx < phba->cfg_fcp_eq_count);
 
2423
                goto error_out;
 
2424
                break;
 
2425
        case LPFC_IDIAG_MQ:
 
2426
                /* MBX work queue */
 
2427
                if (phba->sli4_hba.mbx_wq->queue_id == queid) {
 
2428
                        /* Sanity check */
 
2429
                        rc = lpfc_idiag_que_param_check(
 
2430
                                        phba->sli4_hba.mbx_wq, index, count);
 
2431
                        if (rc)
 
2432
                                goto error_out;
 
2433
                        idiag.ptr_private = phba->sli4_hba.mbx_wq;
 
2434
                        goto pass_check;
 
2435
                }
 
2436
                break;
 
2437
        case LPFC_IDIAG_WQ:
 
2438
                /* ELS work queue */
 
2439
                if (phba->sli4_hba.els_wq->queue_id == queid) {
 
2440
                        /* Sanity check */
 
2441
                        rc = lpfc_idiag_que_param_check(
 
2442
                                        phba->sli4_hba.els_wq, index, count);
 
2443
                        if (rc)
 
2444
                                goto error_out;
 
2445
                        idiag.ptr_private = phba->sli4_hba.els_wq;
 
2446
                        goto pass_check;
 
2447
                }
 
2448
                /* FCP work queue */
 
2449
                for (qidx = 0; qidx < phba->cfg_fcp_wq_count; qidx++) {
 
2450
                        if (phba->sli4_hba.fcp_wq[qidx]->queue_id == queid) {
 
2451
                                /* Sanity check */
 
2452
                                rc = lpfc_idiag_que_param_check(
 
2453
                                                phba->sli4_hba.fcp_wq[qidx],
 
2454
                                                index, count);
 
2455
                                if (rc)
 
2456
                                        goto error_out;
 
2457
                                idiag.ptr_private =
 
2458
                                        phba->sli4_hba.fcp_wq[qidx];
 
2459
                                goto pass_check;
 
2460
                        }
 
2461
                }
 
2462
                goto error_out;
 
2463
                break;
 
2464
        case LPFC_IDIAG_RQ:
 
2465
                /* HDR queue */
 
2466
                if (phba->sli4_hba.hdr_rq->queue_id == queid) {
 
2467
                        /* Sanity check */
 
2468
                        rc = lpfc_idiag_que_param_check(
 
2469
                                        phba->sli4_hba.hdr_rq, index, count);
 
2470
                        if (rc)
 
2471
                                goto error_out;
 
2472
                        idiag.ptr_private = phba->sli4_hba.hdr_rq;
 
2473
                        goto pass_check;
 
2474
                }
 
2475
                /* DAT queue */
 
2476
                if (phba->sli4_hba.dat_rq->queue_id == queid) {
 
2477
                        /* Sanity check */
 
2478
                        rc = lpfc_idiag_que_param_check(
 
2479
                                        phba->sli4_hba.dat_rq, index, count);
 
2480
                        if (rc)
 
2481
                                goto error_out;
 
2482
                        idiag.ptr_private = phba->sli4_hba.dat_rq;
 
2483
                        goto pass_check;
 
2484
                }
 
2485
                goto error_out;
 
2486
                break;
 
2487
        default:
 
2488
                goto error_out;
 
2489
                break;
 
2490
        }
 
2491
 
 
2492
pass_check:
 
2493
 
 
2494
        if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_RD) {
 
2495
                if (count == LPFC_QUE_ACC_BROWSE)
 
2496
                        idiag.offset.last_rd = index;
 
2497
        }
 
2498
 
 
2499
        if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_WR ||
 
2500
            idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_ST ||
 
2501
            idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_CL) {
 
2502
                /* Additional sanity checks on write operation */
 
2503
                pque = (struct lpfc_queue *)idiag.ptr_private;
 
2504
                if (offset > pque->entry_size/sizeof(uint32_t) - 1)
 
2505
                        goto error_out;
 
2506
                pentry = pque->qe[index].address;
 
2507
                pentry += offset;
 
2508
                if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_WR)
 
2509
                        *pentry = value;
 
2510
                if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_ST)
 
2511
                        *pentry |= value;
 
2512
                if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_CL)
 
2513
                        *pentry &= ~value;
 
2514
        }
 
2515
        return nbytes;
 
2516
 
 
2517
error_out:
 
2518
        /* Clean out command structure on command error out */
 
2519
        memset(&idiag, 0, sizeof(idiag));
 
2520
        return -EINVAL;
 
2521
}
 
2522
 
 
2523
/**
 
2524
 * lpfc_idiag_drbacc_read_reg - idiag debugfs read a doorbell register
 
2525
 * @phba: The pointer to hba structure.
 
2526
 * @pbuffer: The pointer to the buffer to copy the data to.
 
2527
 * @len: The lenght of bytes to copied.
 
2528
 * @drbregid: The id to doorbell registers.
 
2529
 *
 
2530
 * Description:
 
2531
 * This routine reads a doorbell register and copies its content to the
 
2532
 * user buffer pointed to by @pbuffer.
 
2533
 *
 
2534
 * Returns:
 
2535
 * This function returns the amount of data that was copied into @pbuffer.
 
2536
 **/
 
2537
static int
 
2538
lpfc_idiag_drbacc_read_reg(struct lpfc_hba *phba, char *pbuffer,
 
2539
                           int len, uint32_t drbregid)
 
2540
{
 
2541
 
 
2542
        if (!pbuffer)
 
2543
                return 0;
 
2544
 
 
2545
        switch (drbregid) {
 
2546
        case LPFC_DRB_EQCQ:
 
2547
                len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
 
2548
                                "EQCQ-DRB-REG: 0x%08x\n",
 
2549
                                readl(phba->sli4_hba.EQCQDBregaddr));
 
2550
                break;
 
2551
        case LPFC_DRB_MQ:
 
2552
                len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
 
2553
                                "MQ-DRB-REG:   0x%08x\n",
 
2554
                                readl(phba->sli4_hba.MQDBregaddr));
 
2555
                break;
 
2556
        case LPFC_DRB_WQ:
 
2557
                len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
 
2558
                                "WQ-DRB-REG:   0x%08x\n",
 
2559
                                readl(phba->sli4_hba.WQDBregaddr));
 
2560
                break;
 
2561
        case LPFC_DRB_RQ:
 
2562
                len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
 
2563
                                "RQ-DRB-REG:   0x%08x\n",
 
2564
                                readl(phba->sli4_hba.RQDBregaddr));
 
2565
                break;
 
2566
        default:
 
2567
                break;
 
2568
        }
 
2569
 
 
2570
        return len;
 
2571
}
 
2572
 
 
2573
/**
 
2574
 * lpfc_idiag_drbacc_read - idiag debugfs read port doorbell
 
2575
 * @file: The file pointer to read from.
 
2576
 * @buf: The buffer to copy the data to.
 
2577
 * @nbytes: The number of bytes to read.
 
2578
 * @ppos: The position in the file to start reading from.
 
2579
 *
 
2580
 * Description:
 
2581
 * This routine reads data from the @phba device doorbell register according
 
2582
 * to the idiag command, and copies to user @buf. Depending on the doorbell
 
2583
 * register read command setup, it does either a single doorbell register
 
2584
 * read or dump all doorbell registers.
 
2585
 *
 
2586
 * Returns:
 
2587
 * This function returns the amount of data that was read (this could be less
 
2588
 * than @nbytes if the end of the file was reached) or a negative error value.
 
2589
 **/
 
2590
static ssize_t
 
2591
lpfc_idiag_drbacc_read(struct file *file, char __user *buf, size_t nbytes,
 
2592
                       loff_t *ppos)
 
2593
{
 
2594
        struct lpfc_debug *debug = file->private_data;
 
2595
        struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
 
2596
        uint32_t drb_reg_id, i;
 
2597
        char *pbuffer;
 
2598
        int len = 0;
 
2599
 
 
2600
        /* This is a user read operation */
 
2601
        debug->op = LPFC_IDIAG_OP_RD;
 
2602
 
 
2603
        if (!debug->buffer)
 
2604
                debug->buffer = kmalloc(LPFC_DRB_ACC_BUF_SIZE, GFP_KERNEL);
 
2605
        if (!debug->buffer)
 
2606
                return 0;
 
2607
        pbuffer = debug->buffer;
 
2608
 
 
2609
        if (*ppos)
 
2610
                return 0;
 
2611
 
 
2612
        if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_RD)
 
2613
                drb_reg_id = idiag.cmd.data[IDIAG_DRBACC_REGID_INDX];
 
2614
        else
 
2615
                return 0;
 
2616
 
 
2617
        if (drb_reg_id == LPFC_DRB_ACC_ALL)
 
2618
                for (i = 1; i <= LPFC_DRB_MAX; i++)
 
2619
                        len = lpfc_idiag_drbacc_read_reg(phba,
 
2620
                                                         pbuffer, len, i);
 
2621
        else
 
2622
                len = lpfc_idiag_drbacc_read_reg(phba,
 
2623
                                                 pbuffer, len, drb_reg_id);
 
2624
 
 
2625
        return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
 
2626
}
 
2627
 
 
2628
/**
 
2629
 * lpfc_idiag_drbacc_write - Syntax check and set up idiag drbacc commands
 
2630
 * @file: The file pointer to read from.
 
2631
 * @buf: The buffer to copy the user data from.
 
2632
 * @nbytes: The number of bytes to get.
 
2633
 * @ppos: The position in the file to start reading from.
 
2634
 *
 
2635
 * This routine get the debugfs idiag command struct from user space and then
 
2636
 * perform the syntax check for port doorbell register read (dump) or write
 
2637
 * (set) command accordingly. In the case of port queue read command, it sets
 
2638
 * up the command in the idiag command struct for the following debugfs read
 
2639
 * operation. In the case of port doorbell register write operation, it
 
2640
 * executes the write operation into the port doorbell register accordingly.
 
2641
 *
 
2642
 * It returns the @nbytges passing in from debugfs user space when successful.
 
2643
 * In case of error conditions, it returns proper error code back to the user
 
2644
 * space.
 
2645
 **/
 
2646
static ssize_t
 
2647
lpfc_idiag_drbacc_write(struct file *file, const char __user *buf,
 
2648
                        size_t nbytes, loff_t *ppos)
 
2649
{
 
2650
        struct lpfc_debug *debug = file->private_data;
 
2651
        struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
 
2652
        uint32_t drb_reg_id, value, reg_val = 0;
 
2653
        void __iomem *drb_reg;
 
2654
        int rc;
 
2655
 
 
2656
        /* This is a user write operation */
 
2657
        debug->op = LPFC_IDIAG_OP_WR;
 
2658
 
 
2659
        rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
 
2660
        if (rc < 0)
 
2661
                return rc;
 
2662
 
 
2663
        /* Sanity check on command line arguments */
 
2664
        drb_reg_id = idiag.cmd.data[IDIAG_DRBACC_REGID_INDX];
 
2665
        value = idiag.cmd.data[IDIAG_DRBACC_VALUE_INDX];
 
2666
 
 
2667
        if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_WR ||
 
2668
            idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST ||
 
2669
            idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_CL) {
 
2670
                if (rc != LPFC_DRB_ACC_WR_CMD_ARG)
 
2671
                        goto error_out;
 
2672
                if (drb_reg_id > LPFC_DRB_MAX)
 
2673
                        goto error_out;
 
2674
        } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_RD) {
 
2675
                if (rc != LPFC_DRB_ACC_RD_CMD_ARG)
 
2676
                        goto error_out;
 
2677
                if ((drb_reg_id > LPFC_DRB_MAX) &&
 
2678
                    (drb_reg_id != LPFC_DRB_ACC_ALL))
 
2679
                        goto error_out;
 
2680
        } else
 
2681
                goto error_out;
 
2682
 
 
2683
        /* Perform the write access operation */
 
2684
        if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_WR ||
 
2685
            idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST ||
 
2686
            idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_CL) {
 
2687
                switch (drb_reg_id) {
 
2688
                case LPFC_DRB_EQCQ:
 
2689
                        drb_reg = phba->sli4_hba.EQCQDBregaddr;
 
2690
                        break;
 
2691
                case LPFC_DRB_MQ:
 
2692
                        drb_reg = phba->sli4_hba.MQDBregaddr;
 
2693
                        break;
 
2694
                case LPFC_DRB_WQ:
 
2695
                        drb_reg = phba->sli4_hba.WQDBregaddr;
 
2696
                        break;
 
2697
                case LPFC_DRB_RQ:
 
2698
                        drb_reg = phba->sli4_hba.RQDBregaddr;
 
2699
                        break;
 
2700
                default:
 
2701
                        goto error_out;
 
2702
                }
 
2703
 
 
2704
                if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_WR)
 
2705
                        reg_val = value;
 
2706
                if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST) {
 
2707
                        reg_val = readl(drb_reg);
 
2708
                        reg_val |= value;
 
2709
                }
 
2710
                if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_CL) {
 
2711
                        reg_val = readl(drb_reg);
 
2712
                        reg_val &= ~value;
 
2713
                }
 
2714
                writel(reg_val, drb_reg);
 
2715
                readl(drb_reg); /* flush */
 
2716
        }
 
2717
        return nbytes;
 
2718
 
 
2719
error_out:
 
2720
        /* Clean out command structure on command error out */
 
2721
        memset(&idiag, 0, sizeof(idiag));
 
2722
        return -EINVAL;
 
2723
}
 
2724
 
 
2725
/**
 
2726
 * lpfc_idiag_ctlacc_read_reg - idiag debugfs read a control registers
 
2727
 * @phba: The pointer to hba structure.
 
2728
 * @pbuffer: The pointer to the buffer to copy the data to.
 
2729
 * @len: The lenght of bytes to copied.
 
2730
 * @drbregid: The id to doorbell registers.
 
2731
 *
 
2732
 * Description:
 
2733
 * This routine reads a control register and copies its content to the
 
2734
 * user buffer pointed to by @pbuffer.
 
2735
 *
 
2736
 * Returns:
 
2737
 * This function returns the amount of data that was copied into @pbuffer.
 
2738
 **/
 
2739
static int
 
2740
lpfc_idiag_ctlacc_read_reg(struct lpfc_hba *phba, char *pbuffer,
 
2741
                           int len, uint32_t ctlregid)
 
2742
{
 
2743
 
 
2744
        if (!pbuffer)
 
2745
                return 0;
 
2746
 
 
2747
        switch (ctlregid) {
 
2748
        case LPFC_CTL_PORT_SEM:
 
2749
                len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
 
2750
                                "Port SemReg:   0x%08x\n",
 
2751
                                readl(phba->sli4_hba.conf_regs_memmap_p +
 
2752
                                      LPFC_CTL_PORT_SEM_OFFSET));
 
2753
                break;
 
2754
        case LPFC_CTL_PORT_STA:
 
2755
                len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
 
2756
                                "Port StaReg:   0x%08x\n",
 
2757
                                readl(phba->sli4_hba.conf_regs_memmap_p +
 
2758
                                      LPFC_CTL_PORT_STA_OFFSET));
 
2759
                break;
 
2760
        case LPFC_CTL_PORT_CTL:
 
2761
                len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
 
2762
                                "Port CtlReg:   0x%08x\n",
 
2763
                                readl(phba->sli4_hba.conf_regs_memmap_p +
 
2764
                                      LPFC_CTL_PORT_CTL_OFFSET));
 
2765
                break;
 
2766
        case LPFC_CTL_PORT_ER1:
 
2767
                len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
 
2768
                                "Port Er1Reg:   0x%08x\n",
 
2769
                                readl(phba->sli4_hba.conf_regs_memmap_p +
 
2770
                                      LPFC_CTL_PORT_ER1_OFFSET));
 
2771
                break;
 
2772
        case LPFC_CTL_PORT_ER2:
 
2773
                len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
 
2774
                                "Port Er2Reg:   0x%08x\n",
 
2775
                                readl(phba->sli4_hba.conf_regs_memmap_p +
 
2776
                                      LPFC_CTL_PORT_ER2_OFFSET));
 
2777
                break;
 
2778
        case LPFC_CTL_PDEV_CTL:
 
2779
                len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
 
2780
                                "PDev CtlReg:   0x%08x\n",
 
2781
                                readl(phba->sli4_hba.conf_regs_memmap_p +
 
2782
                                      LPFC_CTL_PDEV_CTL_OFFSET));
 
2783
                break;
 
2784
        default:
 
2785
                break;
 
2786
        }
 
2787
        return len;
 
2788
}
 
2789
 
 
2790
/**
 
2791
 * lpfc_idiag_ctlacc_read - idiag debugfs read port and device control register
 
2792
 * @file: The file pointer to read from.
 
2793
 * @buf: The buffer to copy the data to.
 
2794
 * @nbytes: The number of bytes to read.
 
2795
 * @ppos: The position in the file to start reading from.
 
2796
 *
 
2797
 * Description:
 
2798
 * This routine reads data from the @phba port and device registers according
 
2799
 * to the idiag command, and copies to user @buf.
 
2800
 *
 
2801
 * Returns:
 
2802
 * This function returns the amount of data that was read (this could be less
 
2803
 * than @nbytes if the end of the file was reached) or a negative error value.
 
2804
 **/
 
2805
static ssize_t
 
2806
lpfc_idiag_ctlacc_read(struct file *file, char __user *buf, size_t nbytes,
 
2807
                       loff_t *ppos)
 
2808
{
 
2809
        struct lpfc_debug *debug = file->private_data;
 
2810
        struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
 
2811
        uint32_t ctl_reg_id, i;
 
2812
        char *pbuffer;
 
2813
        int len = 0;
 
2814
 
 
2815
        /* This is a user read operation */
 
2816
        debug->op = LPFC_IDIAG_OP_RD;
 
2817
 
 
2818
        if (!debug->buffer)
 
2819
                debug->buffer = kmalloc(LPFC_CTL_ACC_BUF_SIZE, GFP_KERNEL);
 
2820
        if (!debug->buffer)
 
2821
                return 0;
 
2822
        pbuffer = debug->buffer;
 
2823
 
 
2824
        if (*ppos)
 
2825
                return 0;
 
2826
 
 
2827
        if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_RD)
 
2828
                ctl_reg_id = idiag.cmd.data[IDIAG_CTLACC_REGID_INDX];
 
2829
        else
 
2830
                return 0;
 
2831
 
 
2832
        if (ctl_reg_id == LPFC_CTL_ACC_ALL)
 
2833
                for (i = 1; i <= LPFC_CTL_MAX; i++)
 
2834
                        len = lpfc_idiag_ctlacc_read_reg(phba,
 
2835
                                                         pbuffer, len, i);
 
2836
        else
 
2837
                len = lpfc_idiag_ctlacc_read_reg(phba,
 
2838
                                                 pbuffer, len, ctl_reg_id);
 
2839
 
 
2840
        return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
 
2841
}
 
2842
 
 
2843
/**
 
2844
 * lpfc_idiag_ctlacc_write - Syntax check and set up idiag ctlacc commands
 
2845
 * @file: The file pointer to read from.
 
2846
 * @buf: The buffer to copy the user data from.
 
2847
 * @nbytes: The number of bytes to get.
 
2848
 * @ppos: The position in the file to start reading from.
 
2849
 *
 
2850
 * This routine get the debugfs idiag command struct from user space and then
 
2851
 * perform the syntax check for port and device control register read (dump)
 
2852
 * or write (set) command accordingly.
 
2853
 *
 
2854
 * It returns the @nbytges passing in from debugfs user space when successful.
 
2855
 * In case of error conditions, it returns proper error code back to the user
 
2856
 * space.
 
2857
 **/
 
2858
static ssize_t
 
2859
lpfc_idiag_ctlacc_write(struct file *file, const char __user *buf,
 
2860
                        size_t nbytes, loff_t *ppos)
 
2861
{
 
2862
        struct lpfc_debug *debug = file->private_data;
 
2863
        struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
 
2864
        uint32_t ctl_reg_id, value, reg_val = 0;
 
2865
        void __iomem *ctl_reg;
 
2866
        int rc;
 
2867
 
 
2868
        /* This is a user write operation */
 
2869
        debug->op = LPFC_IDIAG_OP_WR;
 
2870
 
 
2871
        rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
 
2872
        if (rc < 0)
 
2873
                return rc;
 
2874
 
 
2875
        /* Sanity check on command line arguments */
 
2876
        ctl_reg_id = idiag.cmd.data[IDIAG_CTLACC_REGID_INDX];
 
2877
        value = idiag.cmd.data[IDIAG_CTLACC_VALUE_INDX];
 
2878
 
 
2879
        if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_WR ||
 
2880
            idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_ST ||
 
2881
            idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_CL) {
 
2882
                if (rc != LPFC_CTL_ACC_WR_CMD_ARG)
 
2883
                        goto error_out;
 
2884
                if (ctl_reg_id > LPFC_CTL_MAX)
 
2885
                        goto error_out;
 
2886
        } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_RD) {
 
2887
                if (rc != LPFC_CTL_ACC_RD_CMD_ARG)
 
2888
                        goto error_out;
 
2889
                if ((ctl_reg_id > LPFC_CTL_MAX) &&
 
2890
                    (ctl_reg_id != LPFC_CTL_ACC_ALL))
 
2891
                        goto error_out;
 
2892
        } else
 
2893
                goto error_out;
 
2894
 
 
2895
        /* Perform the write access operation */
 
2896
        if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_WR ||
 
2897
            idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_ST ||
 
2898
            idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_CL) {
 
2899
                switch (ctl_reg_id) {
 
2900
                case LPFC_CTL_PORT_SEM:
 
2901
                        ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
 
2902
                                        LPFC_CTL_PORT_SEM_OFFSET;
 
2903
                        break;
 
2904
                case LPFC_CTL_PORT_STA:
 
2905
                        ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
 
2906
                                        LPFC_CTL_PORT_STA_OFFSET;
 
2907
                        break;
 
2908
                case LPFC_CTL_PORT_CTL:
 
2909
                        ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
 
2910
                                        LPFC_CTL_PORT_CTL_OFFSET;
 
2911
                        break;
 
2912
                case LPFC_CTL_PORT_ER1:
 
2913
                        ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
 
2914
                                        LPFC_CTL_PORT_ER1_OFFSET;
 
2915
                        break;
 
2916
                case LPFC_CTL_PORT_ER2:
 
2917
                        ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
 
2918
                                        LPFC_CTL_PORT_ER2_OFFSET;
 
2919
                        break;
 
2920
                case LPFC_CTL_PDEV_CTL:
 
2921
                        ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
 
2922
                                        LPFC_CTL_PDEV_CTL_OFFSET;
 
2923
                        break;
 
2924
                default:
 
2925
                        goto error_out;
 
2926
                }
 
2927
 
 
2928
                if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_WR)
 
2929
                        reg_val = value;
 
2930
                if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_ST) {
 
2931
                        reg_val = readl(ctl_reg);
 
2932
                        reg_val |= value;
 
2933
                }
 
2934
                if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_CL) {
 
2935
                        reg_val = readl(ctl_reg);
 
2936
                        reg_val &= ~value;
 
2937
                }
 
2938
                writel(reg_val, ctl_reg);
 
2939
                readl(ctl_reg); /* flush */
 
2940
        }
 
2941
        return nbytes;
 
2942
 
 
2943
error_out:
 
2944
        /* Clean out command structure on command error out */
 
2945
        memset(&idiag, 0, sizeof(idiag));
 
2946
        return -EINVAL;
 
2947
}
 
2948
 
 
2949
/**
 
2950
 * lpfc_idiag_mbxacc_get_setup - idiag debugfs get mailbox access setup
 
2951
 * @phba: Pointer to HBA context object.
 
2952
 * @pbuffer: Pointer to data buffer.
 
2953
 *
 
2954
 * Description:
 
2955
 * This routine gets the driver mailbox access debugfs setup information.
 
2956
 *
 
2957
 * Returns:
 
2958
 * This function returns the amount of data that was read (this could be less
 
2959
 * than @nbytes if the end of the file was reached) or a negative error value.
 
2960
 **/
 
2961
static int
 
2962
lpfc_idiag_mbxacc_get_setup(struct lpfc_hba *phba, char *pbuffer)
 
2963
{
 
2964
        uint32_t mbx_dump_map, mbx_dump_cnt, mbx_word_cnt, mbx_mbox_cmd;
 
2965
        int len = 0;
 
2966
 
 
2967
        mbx_mbox_cmd = idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX];
 
2968
        mbx_dump_map = idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX];
 
2969
        mbx_dump_cnt = idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX];
 
2970
        mbx_word_cnt = idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX];
 
2971
 
 
2972
        len += snprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len,
 
2973
                        "mbx_dump_map: 0x%08x\n", mbx_dump_map);
 
2974
        len += snprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len,
 
2975
                        "mbx_dump_cnt: %04d\n", mbx_dump_cnt);
 
2976
        len += snprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len,
 
2977
                        "mbx_word_cnt: %04d\n", mbx_word_cnt);
 
2978
        len += snprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len,
 
2979
                        "mbx_mbox_cmd: 0x%02x\n", mbx_mbox_cmd);
 
2980
 
 
2981
        return len;
 
2982
}
 
2983
 
 
2984
/**
 
2985
 * lpfc_idiag_mbxacc_read - idiag debugfs read on mailbox access
 
2986
 * @file: The file pointer to read from.
 
2987
 * @buf: The buffer to copy the data to.
 
2988
 * @nbytes: The number of bytes to read.
 
2989
 * @ppos: The position in the file to start reading from.
 
2990
 *
 
2991
 * Description:
 
2992
 * This routine reads data from the @phba driver mailbox access debugfs setup
 
2993
 * information.
 
2994
 *
 
2995
 * Returns:
 
2996
 * This function returns the amount of data that was read (this could be less
 
2997
 * than @nbytes if the end of the file was reached) or a negative error value.
 
2998
 **/
 
2999
static ssize_t
 
3000
lpfc_idiag_mbxacc_read(struct file *file, char __user *buf, size_t nbytes,
 
3001
                       loff_t *ppos)
 
3002
{
 
3003
        struct lpfc_debug *debug = file->private_data;
 
3004
        struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
 
3005
        char *pbuffer;
 
3006
        int len = 0;
 
3007
 
 
3008
        /* This is a user read operation */
 
3009
        debug->op = LPFC_IDIAG_OP_RD;
 
3010
 
 
3011
        if (!debug->buffer)
 
3012
                debug->buffer = kmalloc(LPFC_MBX_ACC_BUF_SIZE, GFP_KERNEL);
 
3013
        if (!debug->buffer)
 
3014
                return 0;
 
3015
        pbuffer = debug->buffer;
 
3016
 
 
3017
        if (*ppos)
 
3018
                return 0;
 
3019
 
 
3020
        if ((idiag.cmd.opcode != LPFC_IDIAG_CMD_MBXACC_DP) &&
 
3021
            (idiag.cmd.opcode != LPFC_IDIAG_BSG_MBXACC_DP))
 
3022
                return 0;
 
3023
 
 
3024
        len = lpfc_idiag_mbxacc_get_setup(phba, pbuffer);
 
3025
 
 
3026
        return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
 
3027
}
 
3028
 
 
3029
/**
 
3030
 * lpfc_idiag_mbxacc_write - Syntax check and set up idiag mbxacc commands
 
3031
 * @file: The file pointer to read from.
 
3032
 * @buf: The buffer to copy the user data from.
 
3033
 * @nbytes: The number of bytes to get.
 
3034
 * @ppos: The position in the file to start reading from.
 
3035
 *
 
3036
 * This routine get the debugfs idiag command struct from user space and then
 
3037
 * perform the syntax check for driver mailbox command (dump) and sets up the
 
3038
 * necessary states in the idiag command struct accordingly.
 
3039
 *
 
3040
 * It returns the @nbytges passing in from debugfs user space when successful.
 
3041
 * In case of error conditions, it returns proper error code back to the user
 
3042
 * space.
 
3043
 **/
 
3044
static ssize_t
 
3045
lpfc_idiag_mbxacc_write(struct file *file, const char __user *buf,
 
3046
                        size_t nbytes, loff_t *ppos)
 
3047
{
 
3048
        struct lpfc_debug *debug = file->private_data;
 
3049
        uint32_t mbx_dump_map, mbx_dump_cnt, mbx_word_cnt, mbx_mbox_cmd;
 
3050
        int rc;
 
3051
 
 
3052
        /* This is a user write operation */
 
3053
        debug->op = LPFC_IDIAG_OP_WR;
 
3054
 
 
3055
        rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
 
3056
        if (rc < 0)
 
3057
                return rc;
 
3058
 
 
3059
        /* Sanity check on command line arguments */
 
3060
        mbx_mbox_cmd = idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX];
 
3061
        mbx_dump_map = idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX];
 
3062
        mbx_dump_cnt = idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX];
 
3063
        mbx_word_cnt = idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX];
 
3064
 
 
3065
        if (idiag.cmd.opcode == LPFC_IDIAG_CMD_MBXACC_DP) {
 
3066
                if (!(mbx_dump_map & LPFC_MBX_DMP_MBX_ALL))
 
3067
                        goto error_out;
 
3068
                if ((mbx_dump_map & ~LPFC_MBX_DMP_MBX_ALL) &&
 
3069
                    (mbx_dump_map != LPFC_MBX_DMP_ALL))
 
3070
                        goto error_out;
 
3071
                if (mbx_word_cnt > sizeof(MAILBOX_t))
 
3072
                        goto error_out;
 
3073
        } else if (idiag.cmd.opcode == LPFC_IDIAG_BSG_MBXACC_DP) {
 
3074
                if (!(mbx_dump_map & LPFC_BSG_DMP_MBX_ALL))
 
3075
                        goto error_out;
 
3076
                if ((mbx_dump_map & ~LPFC_BSG_DMP_MBX_ALL) &&
 
3077
                    (mbx_dump_map != LPFC_MBX_DMP_ALL))
 
3078
                        goto error_out;
 
3079
                if (mbx_word_cnt > (BSG_MBOX_SIZE)/4)
 
3080
                        goto error_out;
 
3081
                if (mbx_mbox_cmd != 0x9b)
 
3082
                        goto error_out;
 
3083
        } else
 
3084
                goto error_out;
 
3085
 
 
3086
        if (mbx_word_cnt == 0)
 
3087
                goto error_out;
 
3088
        if (rc != LPFC_MBX_DMP_ARG)
 
3089
                goto error_out;
 
3090
        if (mbx_mbox_cmd & ~0xff)
 
3091
                goto error_out;
 
3092
 
 
3093
        /* condition for stop mailbox dump */
 
3094
        if (mbx_dump_cnt == 0)
 
3095
                goto reset_out;
 
3096
 
 
3097
        return nbytes;
 
3098
 
 
3099
reset_out:
 
3100
        /* Clean out command structure on command error out */
 
3101
        memset(&idiag, 0, sizeof(idiag));
 
3102
        return nbytes;
 
3103
 
 
3104
error_out:
 
3105
        /* Clean out command structure on command error out */
 
3106
        memset(&idiag, 0, sizeof(idiag));
 
3107
        return -EINVAL;
 
3108
}
 
3109
 
 
3110
/**
 
3111
 * lpfc_idiag_extacc_avail_get - get the available extents information
 
3112
 * @phba: pointer to lpfc hba data structure.
 
3113
 * @pbuffer: pointer to internal buffer.
 
3114
 * @len: length into the internal buffer data has been copied.
 
3115
 *
 
3116
 * Description:
 
3117
 * This routine is to get the available extent information.
 
3118
 *
 
3119
 * Returns:
 
3120
 * overall lenth of the data read into the internal buffer.
 
3121
 **/
 
3122
static int
 
3123
lpfc_idiag_extacc_avail_get(struct lpfc_hba *phba, char *pbuffer, int len)
 
3124
{
 
3125
        uint16_t ext_cnt, ext_size;
 
3126
 
 
3127
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3128
                        "\nAvailable Extents Information:\n");
 
3129
 
 
3130
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3131
                        "\tPort Available VPI extents: ");
 
3132
        lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_VPI,
 
3133
                                       &ext_cnt, &ext_size);
 
3134
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3135
                        "Count %3d, Size %3d\n", ext_cnt, ext_size);
 
3136
 
 
3137
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3138
                        "\tPort Available VFI extents: ");
 
3139
        lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_VFI,
 
3140
                                       &ext_cnt, &ext_size);
 
3141
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3142
                        "Count %3d, Size %3d\n", ext_cnt, ext_size);
 
3143
 
 
3144
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3145
                        "\tPort Available RPI extents: ");
 
3146
        lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_RPI,
 
3147
                                       &ext_cnt, &ext_size);
 
3148
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3149
                        "Count %3d, Size %3d\n", ext_cnt, ext_size);
 
3150
 
 
3151
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3152
                        "\tPort Available XRI extents: ");
 
3153
        lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_XRI,
 
3154
                                       &ext_cnt, &ext_size);
 
3155
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3156
                        "Count %3d, Size %3d\n", ext_cnt, ext_size);
 
3157
 
 
3158
        return len;
 
3159
}
 
3160
 
 
3161
/**
 
3162
 * lpfc_idiag_extacc_alloc_get - get the allocated extents information
 
3163
 * @phba: pointer to lpfc hba data structure.
 
3164
 * @pbuffer: pointer to internal buffer.
 
3165
 * @len: length into the internal buffer data has been copied.
 
3166
 *
 
3167
 * Description:
 
3168
 * This routine is to get the allocated extent information.
 
3169
 *
 
3170
 * Returns:
 
3171
 * overall lenth of the data read into the internal buffer.
 
3172
 **/
 
3173
static int
 
3174
lpfc_idiag_extacc_alloc_get(struct lpfc_hba *phba, char *pbuffer, int len)
 
3175
{
 
3176
        uint16_t ext_cnt, ext_size;
 
3177
        int rc;
 
3178
 
 
3179
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3180
                        "\nAllocated Extents Information:\n");
 
3181
 
 
3182
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3183
                        "\tHost Allocated VPI extents: ");
 
3184
        rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_VPI,
 
3185
                                            &ext_cnt, &ext_size);
 
3186
        if (!rc)
 
3187
                len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3188
                                "Port %d Extent %3d, Size %3d\n",
 
3189
                                phba->brd_no, ext_cnt, ext_size);
 
3190
        else
 
3191
                len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3192
                                "N/A\n");
 
3193
 
 
3194
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3195
                        "\tHost Allocated VFI extents: ");
 
3196
        rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_VFI,
 
3197
                                            &ext_cnt, &ext_size);
 
3198
        if (!rc)
 
3199
                len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3200
                                "Port %d Extent %3d, Size %3d\n",
 
3201
                                phba->brd_no, ext_cnt, ext_size);
 
3202
        else
 
3203
                len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3204
                                "N/A\n");
 
3205
 
 
3206
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3207
                        "\tHost Allocated RPI extents: ");
 
3208
        rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_RPI,
 
3209
                                            &ext_cnt, &ext_size);
 
3210
        if (!rc)
 
3211
                len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3212
                                "Port %d Extent %3d, Size %3d\n",
 
3213
                                phba->brd_no, ext_cnt, ext_size);
 
3214
        else
 
3215
                len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3216
                                "N/A\n");
 
3217
 
 
3218
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3219
                        "\tHost Allocated XRI extents: ");
 
3220
        rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_XRI,
 
3221
                                            &ext_cnt, &ext_size);
 
3222
        if (!rc)
 
3223
                len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3224
                                "Port %d Extent %3d, Size %3d\n",
 
3225
                                phba->brd_no, ext_cnt, ext_size);
 
3226
        else
 
3227
                len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3228
                                "N/A\n");
 
3229
 
 
3230
        return len;
 
3231
}
 
3232
 
 
3233
/**
 
3234
 * lpfc_idiag_extacc_drivr_get - get driver extent information
 
3235
 * @phba: pointer to lpfc hba data structure.
 
3236
 * @pbuffer: pointer to internal buffer.
 
3237
 * @len: length into the internal buffer data has been copied.
 
3238
 *
 
3239
 * Description:
 
3240
 * This routine is to get the driver extent information.
 
3241
 *
 
3242
 * Returns:
 
3243
 * overall lenth of the data read into the internal buffer.
 
3244
 **/
 
3245
static int
 
3246
lpfc_idiag_extacc_drivr_get(struct lpfc_hba *phba, char *pbuffer, int len)
 
3247
{
 
3248
        struct lpfc_rsrc_blks *rsrc_blks;
 
3249
        int index;
 
3250
 
 
3251
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3252
                        "\nDriver Extents Information:\n");
 
3253
 
 
3254
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3255
                        "\tVPI extents:\n");
 
3256
        index = 0;
 
3257
        list_for_each_entry(rsrc_blks, &phba->lpfc_vpi_blk_list, list) {
 
3258
                len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3259
                                "\t\tBlock %3d: Start %4d, Count %4d\n",
 
3260
                                index, rsrc_blks->rsrc_start,
 
3261
                                rsrc_blks->rsrc_size);
 
3262
                index++;
 
3263
        }
 
3264
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3265
                        "\tVFI extents:\n");
 
3266
        index = 0;
 
3267
        list_for_each_entry(rsrc_blks, &phba->sli4_hba.lpfc_vfi_blk_list,
 
3268
                            list) {
 
3269
                len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3270
                                "\t\tBlock %3d: Start %4d, Count %4d\n",
 
3271
                                index, rsrc_blks->rsrc_start,
 
3272
                                rsrc_blks->rsrc_size);
 
3273
                index++;
 
3274
        }
 
3275
 
 
3276
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3277
                        "\tRPI extents:\n");
 
3278
        index = 0;
 
3279
        list_for_each_entry(rsrc_blks, &phba->sli4_hba.lpfc_rpi_blk_list,
 
3280
                            list) {
 
3281
                len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3282
                                "\t\tBlock %3d: Start %4d, Count %4d\n",
 
3283
                                index, rsrc_blks->rsrc_start,
 
3284
                                rsrc_blks->rsrc_size);
 
3285
                index++;
 
3286
        }
 
3287
 
 
3288
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3289
                        "\tXRI extents:\n");
 
3290
        index = 0;
 
3291
        list_for_each_entry(rsrc_blks, &phba->sli4_hba.lpfc_xri_blk_list,
 
3292
                            list) {
 
3293
                len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3294
                                "\t\tBlock %3d: Start %4d, Count %4d\n",
 
3295
                                index, rsrc_blks->rsrc_start,
 
3296
                                rsrc_blks->rsrc_size);
 
3297
                index++;
 
3298
        }
 
3299
 
 
3300
        return len;
 
3301
}
 
3302
 
 
3303
/**
 
3304
 * lpfc_idiag_extacc_write - Syntax check and set up idiag extacc commands
 
3305
 * @file: The file pointer to read from.
 
3306
 * @buf: The buffer to copy the user data from.
 
3307
 * @nbytes: The number of bytes to get.
 
3308
 * @ppos: The position in the file to start reading from.
 
3309
 *
 
3310
 * This routine get the debugfs idiag command struct from user space and then
 
3311
 * perform the syntax check for extent information access commands and sets
 
3312
 * up the necessary states in the idiag command struct accordingly.
 
3313
 *
 
3314
 * It returns the @nbytges passing in from debugfs user space when successful.
 
3315
 * In case of error conditions, it returns proper error code back to the user
 
3316
 * space.
 
3317
 **/
 
3318
static ssize_t
 
3319
lpfc_idiag_extacc_write(struct file *file, const char __user *buf,
 
3320
                        size_t nbytes, loff_t *ppos)
 
3321
{
 
3322
        struct lpfc_debug *debug = file->private_data;
 
3323
        uint32_t ext_map;
 
3324
        int rc;
 
3325
 
 
3326
        /* This is a user write operation */
 
3327
        debug->op = LPFC_IDIAG_OP_WR;
 
3328
 
 
3329
        rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
 
3330
        if (rc < 0)
 
3331
                return rc;
 
3332
 
 
3333
        ext_map = idiag.cmd.data[IDIAG_EXTACC_EXMAP_INDX];
 
3334
 
 
3335
        if (idiag.cmd.opcode != LPFC_IDIAG_CMD_EXTACC_RD)
 
3336
                goto error_out;
 
3337
        if (rc != LPFC_EXT_ACC_CMD_ARG)
 
3338
                goto error_out;
 
3339
        if (!(ext_map & LPFC_EXT_ACC_ALL))
 
3340
                goto error_out;
 
3341
 
 
3342
        return nbytes;
 
3343
error_out:
 
3344
        /* Clean out command structure on command error out */
 
3345
        memset(&idiag, 0, sizeof(idiag));
 
3346
        return -EINVAL;
 
3347
}
 
3348
 
 
3349
/**
 
3350
 * lpfc_idiag_extacc_read - idiag debugfs read access to extent information
 
3351
 * @file: The file pointer to read from.
 
3352
 * @buf: The buffer to copy the data to.
 
3353
 * @nbytes: The number of bytes to read.
 
3354
 * @ppos: The position in the file to start reading from.
 
3355
 *
 
3356
 * Description:
 
3357
 * This routine reads data from the proper extent information according to
 
3358
 * the idiag command, and copies to user @buf.
 
3359
 *
 
3360
 * Returns:
 
3361
 * This function returns the amount of data that was read (this could be less
 
3362
 * than @nbytes if the end of the file was reached) or a negative error value.
 
3363
 **/
 
3364
static ssize_t
 
3365
lpfc_idiag_extacc_read(struct file *file, char __user *buf, size_t nbytes,
 
3366
                       loff_t *ppos)
 
3367
{
 
3368
        struct lpfc_debug *debug = file->private_data;
 
3369
        struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
 
3370
        char *pbuffer;
 
3371
        uint32_t ext_map;
 
3372
        int len = 0;
 
3373
 
 
3374
        /* This is a user read operation */
 
3375
        debug->op = LPFC_IDIAG_OP_RD;
 
3376
 
 
3377
        if (!debug->buffer)
 
3378
                debug->buffer = kmalloc(LPFC_EXT_ACC_BUF_SIZE, GFP_KERNEL);
 
3379
        if (!debug->buffer)
 
3380
                return 0;
 
3381
        pbuffer = debug->buffer;
 
3382
        if (*ppos)
 
3383
                return 0;
 
3384
        if (idiag.cmd.opcode != LPFC_IDIAG_CMD_EXTACC_RD)
 
3385
                return 0;
 
3386
 
 
3387
        ext_map = idiag.cmd.data[IDIAG_EXTACC_EXMAP_INDX];
 
3388
        if (ext_map & LPFC_EXT_ACC_AVAIL)
 
3389
                len = lpfc_idiag_extacc_avail_get(phba, pbuffer, len);
 
3390
        if (ext_map & LPFC_EXT_ACC_ALLOC)
 
3391
                len = lpfc_idiag_extacc_alloc_get(phba, pbuffer, len);
 
3392
        if (ext_map & LPFC_EXT_ACC_DRIVR)
 
3393
                len = lpfc_idiag_extacc_drivr_get(phba, pbuffer, len);
 
3394
 
 
3395
        return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
 
3396
}
 
3397
 
 
3398
#undef lpfc_debugfs_op_disc_trc
 
3399
static const struct file_operations lpfc_debugfs_op_disc_trc = {
 
3400
        .owner =        THIS_MODULE,
 
3401
        .open =         lpfc_debugfs_disc_trc_open,
 
3402
        .llseek =       lpfc_debugfs_lseek,
 
3403
        .read =         lpfc_debugfs_read,
 
3404
        .release =      lpfc_debugfs_release,
 
3405
};
 
3406
 
 
3407
#undef lpfc_debugfs_op_nodelist
 
3408
static const struct file_operations lpfc_debugfs_op_nodelist = {
 
3409
        .owner =        THIS_MODULE,
 
3410
        .open =         lpfc_debugfs_nodelist_open,
 
3411
        .llseek =       lpfc_debugfs_lseek,
 
3412
        .read =         lpfc_debugfs_read,
 
3413
        .release =      lpfc_debugfs_release,
 
3414
};
 
3415
 
 
3416
#undef lpfc_debugfs_op_hbqinfo
 
3417
static const struct file_operations lpfc_debugfs_op_hbqinfo = {
 
3418
        .owner =        THIS_MODULE,
 
3419
        .open =         lpfc_debugfs_hbqinfo_open,
 
3420
        .llseek =       lpfc_debugfs_lseek,
 
3421
        .read =         lpfc_debugfs_read,
 
3422
        .release =      lpfc_debugfs_release,
 
3423
};
 
3424
 
 
3425
#undef lpfc_debugfs_op_dumpHBASlim
 
3426
static const struct file_operations lpfc_debugfs_op_dumpHBASlim = {
 
3427
        .owner =        THIS_MODULE,
 
3428
        .open =         lpfc_debugfs_dumpHBASlim_open,
 
3429
        .llseek =       lpfc_debugfs_lseek,
 
3430
        .read =         lpfc_debugfs_read,
 
3431
        .release =      lpfc_debugfs_release,
 
3432
};
 
3433
 
 
3434
#undef lpfc_debugfs_op_dumpHostSlim
 
3435
static const struct file_operations lpfc_debugfs_op_dumpHostSlim = {
 
3436
        .owner =        THIS_MODULE,
 
3437
        .open =         lpfc_debugfs_dumpHostSlim_open,
 
3438
        .llseek =       lpfc_debugfs_lseek,
 
3439
        .read =         lpfc_debugfs_read,
 
3440
        .release =      lpfc_debugfs_release,
 
3441
};
 
3442
 
 
3443
#undef lpfc_debugfs_op_dumpData
 
3444
static const struct file_operations lpfc_debugfs_op_dumpData = {
 
3445
        .owner =        THIS_MODULE,
 
3446
        .open =         lpfc_debugfs_dumpData_open,
 
3447
        .llseek =       lpfc_debugfs_lseek,
 
3448
        .read =         lpfc_debugfs_read,
 
3449
        .write =        lpfc_debugfs_dumpDataDif_write,
 
3450
        .release =      lpfc_debugfs_dumpDataDif_release,
 
3451
};
 
3452
 
 
3453
#undef lpfc_debugfs_op_dumpDif
 
3454
static const struct file_operations lpfc_debugfs_op_dumpDif = {
 
3455
        .owner =        THIS_MODULE,
 
3456
        .open =         lpfc_debugfs_dumpDif_open,
 
3457
        .llseek =       lpfc_debugfs_lseek,
 
3458
        .read =         lpfc_debugfs_read,
 
3459
        .write =        lpfc_debugfs_dumpDataDif_write,
 
3460
        .release =      lpfc_debugfs_dumpDataDif_release,
 
3461
};
 
3462
 
 
3463
#undef lpfc_debugfs_op_dif_err
 
3464
static const struct file_operations lpfc_debugfs_op_dif_err = {
 
3465
        .owner =        THIS_MODULE,
 
3466
        .open =         lpfc_debugfs_dif_err_open,
 
3467
        .llseek =       lpfc_debugfs_lseek,
 
3468
        .read =         lpfc_debugfs_dif_err_read,
 
3469
        .write =        lpfc_debugfs_dif_err_write,
 
3470
        .release =      lpfc_debugfs_dif_err_release,
 
3471
};
 
3472
 
 
3473
#undef lpfc_debugfs_op_slow_ring_trc
 
3474
static const struct file_operations lpfc_debugfs_op_slow_ring_trc = {
 
3475
        .owner =        THIS_MODULE,
 
3476
        .open =         lpfc_debugfs_slow_ring_trc_open,
 
3477
        .llseek =       lpfc_debugfs_lseek,
 
3478
        .read =         lpfc_debugfs_read,
 
3479
        .release =      lpfc_debugfs_release,
 
3480
};
 
3481
 
 
3482
static struct dentry *lpfc_debugfs_root = NULL;
 
3483
static atomic_t lpfc_debugfs_hba_count;
 
3484
 
 
3485
/*
 
3486
 * File operations for the iDiag debugfs
 
3487
 */
 
3488
#undef lpfc_idiag_op_pciCfg
 
3489
static const struct file_operations lpfc_idiag_op_pciCfg = {
 
3490
        .owner =        THIS_MODULE,
 
3491
        .open =         lpfc_idiag_open,
 
3492
        .llseek =       lpfc_debugfs_lseek,
 
3493
        .read =         lpfc_idiag_pcicfg_read,
 
3494
        .write =        lpfc_idiag_pcicfg_write,
 
3495
        .release =      lpfc_idiag_cmd_release,
 
3496
};
 
3497
 
 
3498
#undef lpfc_idiag_op_barAcc
 
3499
static const struct file_operations lpfc_idiag_op_barAcc = {
 
3500
        .owner =        THIS_MODULE,
 
3501
        .open =         lpfc_idiag_open,
 
3502
        .llseek =       lpfc_debugfs_lseek,
 
3503
        .read =         lpfc_idiag_baracc_read,
 
3504
        .write =        lpfc_idiag_baracc_write,
 
3505
        .release =      lpfc_idiag_cmd_release,
 
3506
};
 
3507
 
 
3508
#undef lpfc_idiag_op_queInfo
 
3509
static const struct file_operations lpfc_idiag_op_queInfo = {
 
3510
        .owner =        THIS_MODULE,
 
3511
        .open =         lpfc_idiag_open,
 
3512
        .read =         lpfc_idiag_queinfo_read,
 
3513
        .release =      lpfc_idiag_release,
 
3514
};
 
3515
 
 
3516
#undef lpfc_idiag_op_queAcc
 
3517
static const struct file_operations lpfc_idiag_op_queAcc = {
 
3518
        .owner =        THIS_MODULE,
 
3519
        .open =         lpfc_idiag_open,
 
3520
        .llseek =       lpfc_debugfs_lseek,
 
3521
        .read =         lpfc_idiag_queacc_read,
 
3522
        .write =        lpfc_idiag_queacc_write,
 
3523
        .release =      lpfc_idiag_cmd_release,
 
3524
};
 
3525
 
 
3526
#undef lpfc_idiag_op_drbAcc
 
3527
static const struct file_operations lpfc_idiag_op_drbAcc = {
 
3528
        .owner =        THIS_MODULE,
 
3529
        .open =         lpfc_idiag_open,
 
3530
        .llseek =       lpfc_debugfs_lseek,
 
3531
        .read =         lpfc_idiag_drbacc_read,
 
3532
        .write =        lpfc_idiag_drbacc_write,
 
3533
        .release =      lpfc_idiag_cmd_release,
 
3534
};
 
3535
 
 
3536
#undef lpfc_idiag_op_ctlAcc
 
3537
static const struct file_operations lpfc_idiag_op_ctlAcc = {
 
3538
        .owner =        THIS_MODULE,
 
3539
        .open =         lpfc_idiag_open,
 
3540
        .llseek =       lpfc_debugfs_lseek,
 
3541
        .read =         lpfc_idiag_ctlacc_read,
 
3542
        .write =        lpfc_idiag_ctlacc_write,
 
3543
        .release =      lpfc_idiag_cmd_release,
 
3544
};
 
3545
 
 
3546
#undef lpfc_idiag_op_mbxAcc
 
3547
static const struct file_operations lpfc_idiag_op_mbxAcc = {
 
3548
        .owner =        THIS_MODULE,
 
3549
        .open =         lpfc_idiag_open,
 
3550
        .llseek =       lpfc_debugfs_lseek,
 
3551
        .read =         lpfc_idiag_mbxacc_read,
 
3552
        .write =        lpfc_idiag_mbxacc_write,
 
3553
        .release =      lpfc_idiag_cmd_release,
 
3554
};
 
3555
 
 
3556
#undef lpfc_idiag_op_extAcc
 
3557
static const struct file_operations lpfc_idiag_op_extAcc = {
 
3558
        .owner =        THIS_MODULE,
 
3559
        .open =         lpfc_idiag_open,
 
3560
        .llseek =       lpfc_debugfs_lseek,
 
3561
        .read =         lpfc_idiag_extacc_read,
 
3562
        .write =        lpfc_idiag_extacc_write,
 
3563
        .release =      lpfc_idiag_cmd_release,
 
3564
};
 
3565
 
 
3566
#endif
 
3567
 
 
3568
/* lpfc_idiag_mbxacc_dump_bsg_mbox - idiag debugfs dump bsg mailbox command
 
3569
 * @phba: Pointer to HBA context object.
 
3570
 * @dmabuf: Pointer to a DMA buffer descriptor.
 
3571
 *
 
3572
 * Description:
 
3573
 * This routine dump a bsg pass-through non-embedded mailbox command with
 
3574
 * external buffer.
 
3575
 **/
 
3576
void
 
3577
lpfc_idiag_mbxacc_dump_bsg_mbox(struct lpfc_hba *phba, enum nemb_type nemb_tp,
 
3578
                                enum mbox_type mbox_tp, enum dma_type dma_tp,
 
3579
                                enum sta_type sta_tp,
 
3580
                                struct lpfc_dmabuf *dmabuf, uint32_t ext_buf)
 
3581
{
 
3582
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
 
3583
        uint32_t *mbx_mbox_cmd, *mbx_dump_map, *mbx_dump_cnt, *mbx_word_cnt;
 
3584
        char line_buf[LPFC_MBX_ACC_LBUF_SZ];
 
3585
        int len = 0;
 
3586
        uint32_t do_dump = 0;
 
3587
        uint32_t *pword;
 
3588
        uint32_t i;
 
3589
 
 
3590
        if (idiag.cmd.opcode != LPFC_IDIAG_BSG_MBXACC_DP)
 
3591
                return;
 
3592
 
 
3593
        mbx_mbox_cmd = &idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX];
 
3594
        mbx_dump_map = &idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX];
 
3595
        mbx_dump_cnt = &idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX];
 
3596
        mbx_word_cnt = &idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX];
 
3597
 
 
3598
        if (!(*mbx_dump_map & LPFC_MBX_DMP_ALL) ||
 
3599
            (*mbx_dump_cnt == 0) ||
 
3600
            (*mbx_word_cnt == 0))
 
3601
                return;
 
3602
 
 
3603
        if (*mbx_mbox_cmd != 0x9B)
 
3604
                return;
 
3605
 
 
3606
        if ((mbox_tp == mbox_rd) && (dma_tp == dma_mbox)) {
 
3607
                if (*mbx_dump_map & LPFC_BSG_DMP_MBX_RD_MBX) {
 
3608
                        do_dump |= LPFC_BSG_DMP_MBX_RD_MBX;
 
3609
                        printk(KERN_ERR "\nRead mbox command (x%x), "
 
3610
                               "nemb:0x%x, extbuf_cnt:%d:\n",
 
3611
                               sta_tp, nemb_tp, ext_buf);
 
3612
                }
 
3613
        }
 
3614
        if ((mbox_tp == mbox_rd) && (dma_tp == dma_ebuf)) {
 
3615
                if (*mbx_dump_map & LPFC_BSG_DMP_MBX_RD_BUF) {
 
3616
                        do_dump |= LPFC_BSG_DMP_MBX_RD_BUF;
 
3617
                        printk(KERN_ERR "\nRead mbox buffer (x%x), "
 
3618
                               "nemb:0x%x, extbuf_seq:%d:\n",
 
3619
                               sta_tp, nemb_tp, ext_buf);
 
3620
                }
 
3621
        }
 
3622
        if ((mbox_tp == mbox_wr) && (dma_tp == dma_mbox)) {
 
3623
                if (*mbx_dump_map & LPFC_BSG_DMP_MBX_WR_MBX) {
 
3624
                        do_dump |= LPFC_BSG_DMP_MBX_WR_MBX;
 
3625
                        printk(KERN_ERR "\nWrite mbox command (x%x), "
 
3626
                               "nemb:0x%x, extbuf_cnt:%d:\n",
 
3627
                               sta_tp, nemb_tp, ext_buf);
 
3628
                }
 
3629
        }
 
3630
        if ((mbox_tp == mbox_wr) && (dma_tp == dma_ebuf)) {
 
3631
                if (*mbx_dump_map & LPFC_BSG_DMP_MBX_WR_BUF) {
 
3632
                        do_dump |= LPFC_BSG_DMP_MBX_WR_BUF;
 
3633
                        printk(KERN_ERR "\nWrite mbox buffer (x%x), "
 
3634
                               "nemb:0x%x, extbuf_seq:%d:\n",
 
3635
                               sta_tp, nemb_tp, ext_buf);
 
3636
                }
 
3637
        }
 
3638
 
 
3639
        /* dump buffer content */
 
3640
        if (do_dump) {
 
3641
                pword = (uint32_t *)dmabuf->virt;
 
3642
                for (i = 0; i < *mbx_word_cnt; i++) {
 
3643
                        if (!(i % 8)) {
 
3644
                                if (i != 0)
 
3645
                                        printk(KERN_ERR "%s\n", line_buf);
 
3646
                                len = 0;
 
3647
                                len += snprintf(line_buf+len,
 
3648
                                                LPFC_MBX_ACC_LBUF_SZ-len,
 
3649
                                                "%03d: ", i);
 
3650
                        }
 
3651
                        len += snprintf(line_buf+len, LPFC_MBX_ACC_LBUF_SZ-len,
 
3652
                                        "%08x ", (uint32_t)*pword);
 
3653
                        pword++;
 
3654
                }
 
3655
                if ((i - 1) % 8)
 
3656
                        printk(KERN_ERR "%s\n", line_buf);
 
3657
                (*mbx_dump_cnt)--;
 
3658
        }
 
3659
 
 
3660
        /* Clean out command structure on reaching dump count */
 
3661
        if (*mbx_dump_cnt == 0)
 
3662
                memset(&idiag, 0, sizeof(idiag));
 
3663
        return;
 
3664
#endif
 
3665
}
 
3666
 
 
3667
/* lpfc_idiag_mbxacc_dump_issue_mbox - idiag debugfs dump issue mailbox command
 
3668
 * @phba: Pointer to HBA context object.
 
3669
 * @dmabuf: Pointer to a DMA buffer descriptor.
 
3670
 *
 
3671
 * Description:
 
3672
 * This routine dump a pass-through non-embedded mailbox command from issue
 
3673
 * mailbox command.
 
3674
 **/
 
3675
void
 
3676
lpfc_idiag_mbxacc_dump_issue_mbox(struct lpfc_hba *phba, MAILBOX_t *pmbox)
 
3677
{
 
3678
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
 
3679
        uint32_t *mbx_dump_map, *mbx_dump_cnt, *mbx_word_cnt, *mbx_mbox_cmd;
 
3680
        char line_buf[LPFC_MBX_ACC_LBUF_SZ];
 
3681
        int len = 0;
 
3682
        uint32_t *pword;
 
3683
        uint8_t *pbyte;
 
3684
        uint32_t i, j;
 
3685
 
 
3686
        if (idiag.cmd.opcode != LPFC_IDIAG_CMD_MBXACC_DP)
 
3687
                return;
 
3688
 
 
3689
        mbx_mbox_cmd = &idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX];
 
3690
        mbx_dump_map = &idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX];
 
3691
        mbx_dump_cnt = &idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX];
 
3692
        mbx_word_cnt = &idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX];
 
3693
 
 
3694
        if (!(*mbx_dump_map & LPFC_MBX_DMP_MBX_ALL) ||
 
3695
            (*mbx_dump_cnt == 0) ||
 
3696
            (*mbx_word_cnt == 0))
 
3697
                return;
 
3698
 
 
3699
        if ((*mbx_mbox_cmd != LPFC_MBX_ALL_CMD) &&
 
3700
            (*mbx_mbox_cmd != pmbox->mbxCommand))
 
3701
                return;
 
3702
 
 
3703
        /* dump buffer content */
 
3704
        if (*mbx_dump_map & LPFC_MBX_DMP_MBX_WORD) {
 
3705
                printk(KERN_ERR "Mailbox command:0x%x dump by word:\n",
 
3706
                       pmbox->mbxCommand);
 
3707
                pword = (uint32_t *)pmbox;
 
3708
                for (i = 0; i < *mbx_word_cnt; i++) {
 
3709
                        if (!(i % 8)) {
 
3710
                                if (i != 0)
 
3711
                                        printk(KERN_ERR "%s\n", line_buf);
 
3712
                                len = 0;
 
3713
                                memset(line_buf, 0, LPFC_MBX_ACC_LBUF_SZ);
 
3714
                                len += snprintf(line_buf+len,
 
3715
                                                LPFC_MBX_ACC_LBUF_SZ-len,
 
3716
                                                "%03d: ", i);
 
3717
                        }
 
3718
                        len += snprintf(line_buf+len, LPFC_MBX_ACC_LBUF_SZ-len,
 
3719
                                        "%08x ",
 
3720
                                        ((uint32_t)*pword) & 0xffffffff);
 
3721
                        pword++;
 
3722
                }
 
3723
                if ((i - 1) % 8)
 
3724
                        printk(KERN_ERR "%s\n", line_buf);
 
3725
                printk(KERN_ERR "\n");
 
3726
        }
 
3727
        if (*mbx_dump_map & LPFC_MBX_DMP_MBX_BYTE) {
 
3728
                printk(KERN_ERR "Mailbox command:0x%x dump by byte:\n",
 
3729
                       pmbox->mbxCommand);
 
3730
                pbyte = (uint8_t *)pmbox;
 
3731
                for (i = 0; i < *mbx_word_cnt; i++) {
 
3732
                        if (!(i % 8)) {
 
3733
                                if (i != 0)
 
3734
                                        printk(KERN_ERR "%s\n", line_buf);
 
3735
                                len = 0;
 
3736
                                memset(line_buf, 0, LPFC_MBX_ACC_LBUF_SZ);
 
3737
                                len += snprintf(line_buf+len,
 
3738
                                                LPFC_MBX_ACC_LBUF_SZ-len,
 
3739
                                                "%03d: ", i);
 
3740
                        }
 
3741
                        for (j = 0; j < 4; j++) {
 
3742
                                len += snprintf(line_buf+len,
 
3743
                                                LPFC_MBX_ACC_LBUF_SZ-len,
 
3744
                                                "%02x",
 
3745
                                                ((uint8_t)*pbyte) & 0xff);
 
3746
                                pbyte++;
 
3747
                        }
 
3748
                        len += snprintf(line_buf+len,
 
3749
                                        LPFC_MBX_ACC_LBUF_SZ-len, " ");
 
3750
                }
 
3751
                if ((i - 1) % 8)
 
3752
                        printk(KERN_ERR "%s\n", line_buf);
 
3753
                printk(KERN_ERR "\n");
 
3754
        }
 
3755
        (*mbx_dump_cnt)--;
 
3756
 
 
3757
        /* Clean out command structure on reaching dump count */
 
3758
        if (*mbx_dump_cnt == 0)
 
3759
                memset(&idiag, 0, sizeof(idiag));
 
3760
        return;
 
3761
#endif
 
3762
}
 
3763
 
 
3764
/**
 
3765
 * lpfc_debugfs_initialize - Initialize debugfs for a vport
 
3766
 * @vport: The vport pointer to initialize.
 
3767
 *
 
3768
 * Description:
 
3769
 * When Debugfs is configured this routine sets up the lpfc debugfs file system.
 
3770
 * If not already created, this routine will create the lpfc directory, and
 
3771
 * lpfcX directory (for this HBA), and vportX directory for this vport. It will
 
3772
 * also create each file used to access lpfc specific debugfs information.
 
3773
 **/
 
3774
inline void
 
3775
lpfc_debugfs_initialize(struct lpfc_vport *vport)
 
3776
{
 
3777
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
 
3778
        struct lpfc_hba   *phba = vport->phba;
 
3779
        char name[64];
 
3780
        uint32_t num, i;
 
3781
 
 
3782
        if (!lpfc_debugfs_enable)
 
3783
                return;
 
3784
 
 
3785
        /* Setup lpfc root directory */
 
3786
        if (!lpfc_debugfs_root) {
 
3787
                lpfc_debugfs_root = debugfs_create_dir("lpfc", NULL);
 
3788
                atomic_set(&lpfc_debugfs_hba_count, 0);
 
3789
                if (!lpfc_debugfs_root) {
 
3790
                        lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
3791
                                         "0408 Cannot create debugfs root\n");
 
3792
                        goto debug_failed;
 
3793
                }
 
3794
        }
 
3795
        if (!lpfc_debugfs_start_time)
 
3796
                lpfc_debugfs_start_time = jiffies;
 
3797
 
 
3798
        /* Setup funcX directory for specific HBA PCI function */
 
3799
        snprintf(name, sizeof(name), "fn%d", phba->brd_no);
 
3800
        if (!phba->hba_debugfs_root) {
 
3801
                phba->hba_debugfs_root =
 
3802
                        debugfs_create_dir(name, lpfc_debugfs_root);
 
3803
                if (!phba->hba_debugfs_root) {
 
3804
                        lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
3805
                                         "0412 Cannot create debugfs hba\n");
 
3806
                        goto debug_failed;
 
3807
                }
 
3808
                atomic_inc(&lpfc_debugfs_hba_count);
 
3809
                atomic_set(&phba->debugfs_vport_count, 0);
 
3810
 
 
3811
                /* Setup hbqinfo */
 
3812
                snprintf(name, sizeof(name), "hbqinfo");
 
3813
                phba->debug_hbqinfo =
 
3814
                        debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
 
3815
                                 phba->hba_debugfs_root,
 
3816
                                 phba, &lpfc_debugfs_op_hbqinfo);
 
3817
                if (!phba->debug_hbqinfo) {
 
3818
                        lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
3819
                                "0411 Cannot create debugfs hbqinfo\n");
 
3820
                        goto debug_failed;
 
3821
                }
 
3822
 
 
3823
                /* Setup dumpHBASlim */
 
3824
                if (phba->sli_rev < LPFC_SLI_REV4) {
 
3825
                        snprintf(name, sizeof(name), "dumpHBASlim");
 
3826
                        phba->debug_dumpHBASlim =
 
3827
                                debugfs_create_file(name,
 
3828
                                        S_IFREG|S_IRUGO|S_IWUSR,
 
3829
                                        phba->hba_debugfs_root,
 
3830
                                        phba, &lpfc_debugfs_op_dumpHBASlim);
 
3831
                        if (!phba->debug_dumpHBASlim) {
 
3832
                                lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
3833
                                                 "0413 Cannot create debugfs "
 
3834
                                                "dumpHBASlim\n");
 
3835
                                goto debug_failed;
 
3836
                        }
 
3837
                } else
 
3838
                        phba->debug_dumpHBASlim = NULL;
 
3839
 
 
3840
                /* Setup dumpHostSlim */
 
3841
                if (phba->sli_rev < LPFC_SLI_REV4) {
 
3842
                        snprintf(name, sizeof(name), "dumpHostSlim");
 
3843
                        phba->debug_dumpHostSlim =
 
3844
                                debugfs_create_file(name,
 
3845
                                        S_IFREG|S_IRUGO|S_IWUSR,
 
3846
                                        phba->hba_debugfs_root,
 
3847
                                        phba, &lpfc_debugfs_op_dumpHostSlim);
 
3848
                        if (!phba->debug_dumpHostSlim) {
 
3849
                                lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
3850
                                                 "0414 Cannot create debugfs "
 
3851
                                                 "dumpHostSlim\n");
 
3852
                                goto debug_failed;
 
3853
                        }
 
3854
                } else
 
3855
                        phba->debug_dumpHBASlim = NULL;
 
3856
 
 
3857
                /* Setup dumpData */
 
3858
                snprintf(name, sizeof(name), "dumpData");
 
3859
                phba->debug_dumpData =
 
3860
                        debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
 
3861
                                 phba->hba_debugfs_root,
 
3862
                                 phba, &lpfc_debugfs_op_dumpData);
 
3863
                if (!phba->debug_dumpData) {
 
3864
                        lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
3865
                                "0800 Cannot create debugfs dumpData\n");
 
3866
                        goto debug_failed;
 
3867
                }
 
3868
 
 
3869
                /* Setup dumpDif */
 
3870
                snprintf(name, sizeof(name), "dumpDif");
 
3871
                phba->debug_dumpDif =
 
3872
                        debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
 
3873
                                 phba->hba_debugfs_root,
 
3874
                                 phba, &lpfc_debugfs_op_dumpDif);
 
3875
                if (!phba->debug_dumpDif) {
 
3876
                        lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
3877
                                "0801 Cannot create debugfs dumpDif\n");
 
3878
                        goto debug_failed;
 
3879
                }
 
3880
 
 
3881
                /* Setup DIF Error Injections */
 
3882
                snprintf(name, sizeof(name), "InjErrLBA");
 
3883
                phba->debug_InjErrLBA =
 
3884
                        debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
 
3885
                        phba->hba_debugfs_root,
 
3886
                        phba, &lpfc_debugfs_op_dif_err);
 
3887
                if (!phba->debug_InjErrLBA) {
 
3888
                        lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
3889
                                "0807 Cannot create debugfs InjErrLBA\n");
 
3890
                        goto debug_failed;
 
3891
                }
 
3892
                phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF;
 
3893
 
 
3894
                snprintf(name, sizeof(name), "writeGuardInjErr");
 
3895
                phba->debug_writeGuard =
 
3896
                        debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
 
3897
                        phba->hba_debugfs_root,
 
3898
                        phba, &lpfc_debugfs_op_dif_err);
 
3899
                if (!phba->debug_writeGuard) {
 
3900
                        lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
3901
                                "0802 Cannot create debugfs writeGuard\n");
 
3902
                        goto debug_failed;
 
3903
                }
 
3904
 
 
3905
                snprintf(name, sizeof(name), "writeAppInjErr");
 
3906
                phba->debug_writeApp =
 
3907
                        debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
 
3908
                        phba->hba_debugfs_root,
 
3909
                        phba, &lpfc_debugfs_op_dif_err);
 
3910
                if (!phba->debug_writeApp) {
 
3911
                        lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
3912
                                "0803 Cannot create debugfs writeApp\n");
 
3913
                        goto debug_failed;
 
3914
                }
 
3915
 
 
3916
                snprintf(name, sizeof(name), "writeRefInjErr");
 
3917
                phba->debug_writeRef =
 
3918
                        debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
 
3919
                        phba->hba_debugfs_root,
 
3920
                        phba, &lpfc_debugfs_op_dif_err);
 
3921
                if (!phba->debug_writeRef) {
 
3922
                        lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
3923
                                "0804 Cannot create debugfs writeRef\n");
 
3924
                        goto debug_failed;
 
3925
                }
 
3926
 
 
3927
                snprintf(name, sizeof(name), "readAppInjErr");
 
3928
                phba->debug_readApp =
 
3929
                        debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
 
3930
                        phba->hba_debugfs_root,
 
3931
                        phba, &lpfc_debugfs_op_dif_err);
 
3932
                if (!phba->debug_readApp) {
 
3933
                        lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
3934
                                "0805 Cannot create debugfs readApp\n");
 
3935
                        goto debug_failed;
 
3936
                }
 
3937
 
 
3938
                snprintf(name, sizeof(name), "readRefInjErr");
 
3939
                phba->debug_readRef =
 
3940
                        debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
 
3941
                        phba->hba_debugfs_root,
 
3942
                        phba, &lpfc_debugfs_op_dif_err);
 
3943
                if (!phba->debug_readRef) {
 
3944
                        lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
3945
                                "0806 Cannot create debugfs readApp\n");
 
3946
                        goto debug_failed;
 
3947
                }
 
3948
 
 
3949
                /* Setup slow ring trace */
 
3950
                if (lpfc_debugfs_max_slow_ring_trc) {
 
3951
                        num = lpfc_debugfs_max_slow_ring_trc - 1;
 
3952
                        if (num & lpfc_debugfs_max_slow_ring_trc) {
 
3953
                                /* Change to be a power of 2 */
 
3954
                                num = lpfc_debugfs_max_slow_ring_trc;
 
3955
                                i = 0;
 
3956
                                while (num > 1) {
 
3957
                                        num = num >> 1;
 
3958
                                        i++;
 
3959
                                }
 
3960
                                lpfc_debugfs_max_slow_ring_trc = (1 << i);
 
3961
                                printk(KERN_ERR
 
3962
                                       "lpfc_debugfs_max_disc_trc changed to "
 
3963
                                       "%d\n", lpfc_debugfs_max_disc_trc);
 
3964
                        }
 
3965
                }
 
3966
 
 
3967
                snprintf(name, sizeof(name), "slow_ring_trace");
 
3968
                phba->debug_slow_ring_trc =
 
3969
                        debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
 
3970
                                 phba->hba_debugfs_root,
 
3971
                                 phba, &lpfc_debugfs_op_slow_ring_trc);
 
3972
                if (!phba->debug_slow_ring_trc) {
 
3973
                        lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
3974
                                         "0415 Cannot create debugfs "
 
3975
                                         "slow_ring_trace\n");
 
3976
                        goto debug_failed;
 
3977
                }
 
3978
                if (!phba->slow_ring_trc) {
 
3979
                        phba->slow_ring_trc = kmalloc(
 
3980
                                (sizeof(struct lpfc_debugfs_trc) *
 
3981
                                lpfc_debugfs_max_slow_ring_trc),
 
3982
                                GFP_KERNEL);
 
3983
                        if (!phba->slow_ring_trc) {
 
3984
                                lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
3985
                                                 "0416 Cannot create debugfs "
 
3986
                                                 "slow_ring buffer\n");
 
3987
                                goto debug_failed;
 
3988
                        }
 
3989
                        atomic_set(&phba->slow_ring_trc_cnt, 0);
 
3990
                        memset(phba->slow_ring_trc, 0,
 
3991
                                (sizeof(struct lpfc_debugfs_trc) *
 
3992
                                lpfc_debugfs_max_slow_ring_trc));
 
3993
                }
 
3994
        }
 
3995
 
 
3996
        snprintf(name, sizeof(name), "vport%d", vport->vpi);
 
3997
        if (!vport->vport_debugfs_root) {
 
3998
                vport->vport_debugfs_root =
 
3999
                        debugfs_create_dir(name, phba->hba_debugfs_root);
 
4000
                if (!vport->vport_debugfs_root) {
 
4001
                        lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
4002
                                         "0417 Can't create debugfs\n");
 
4003
                        goto debug_failed;
 
4004
                }
 
4005
                atomic_inc(&phba->debugfs_vport_count);
 
4006
        }
 
4007
 
 
4008
        if (lpfc_debugfs_max_disc_trc) {
 
4009
                num = lpfc_debugfs_max_disc_trc - 1;
 
4010
                if (num & lpfc_debugfs_max_disc_trc) {
 
4011
                        /* Change to be a power of 2 */
 
4012
                        num = lpfc_debugfs_max_disc_trc;
 
4013
                        i = 0;
 
4014
                        while (num > 1) {
 
4015
                                num = num >> 1;
 
4016
                                i++;
 
4017
                        }
 
4018
                        lpfc_debugfs_max_disc_trc = (1 << i);
 
4019
                        printk(KERN_ERR
 
4020
                               "lpfc_debugfs_max_disc_trc changed to %d\n",
 
4021
                               lpfc_debugfs_max_disc_trc);
 
4022
                }
 
4023
        }
 
4024
 
 
4025
        vport->disc_trc = kzalloc(
 
4026
                (sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc),
 
4027
                GFP_KERNEL);
 
4028
 
 
4029
        if (!vport->disc_trc) {
 
4030
                lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
4031
                                 "0418 Cannot create debugfs disc trace "
 
4032
                                 "buffer\n");
 
4033
                goto debug_failed;
 
4034
        }
 
4035
        atomic_set(&vport->disc_trc_cnt, 0);
 
4036
 
 
4037
        snprintf(name, sizeof(name), "discovery_trace");
 
4038
        vport->debug_disc_trc =
 
4039
                debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
 
4040
                                 vport->vport_debugfs_root,
 
4041
                                 vport, &lpfc_debugfs_op_disc_trc);
 
4042
        if (!vport->debug_disc_trc) {
 
4043
                lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
4044
                                 "0419 Cannot create debugfs "
 
4045
                                 "discovery_trace\n");
 
4046
                goto debug_failed;
 
4047
        }
 
4048
        snprintf(name, sizeof(name), "nodelist");
 
4049
        vport->debug_nodelist =
 
4050
                debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
 
4051
                                 vport->vport_debugfs_root,
 
4052
                                 vport, &lpfc_debugfs_op_nodelist);
 
4053
        if (!vport->debug_nodelist) {
 
4054
                lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
4055
                                 "2985 Can't create debugfs nodelist\n");
 
4056
                goto debug_failed;
 
4057
        }
 
4058
 
 
4059
        /*
 
4060
         * iDiag debugfs root entry points for SLI4 device only
 
4061
         */
 
4062
        if (phba->sli_rev < LPFC_SLI_REV4)
 
4063
                goto debug_failed;
 
4064
 
 
4065
        snprintf(name, sizeof(name), "iDiag");
 
4066
        if (!phba->idiag_root) {
 
4067
                phba->idiag_root =
 
4068
                        debugfs_create_dir(name, phba->hba_debugfs_root);
 
4069
                if (!phba->idiag_root) {
 
4070
                        lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
4071
                                         "2922 Can't create idiag debugfs\n");
 
4072
                        goto debug_failed;
 
4073
                }
 
4074
                /* Initialize iDiag data structure */
 
4075
                memset(&idiag, 0, sizeof(idiag));
 
4076
        }
 
4077
 
 
4078
        /* iDiag read PCI config space */
 
4079
        snprintf(name, sizeof(name), "pciCfg");
 
4080
        if (!phba->idiag_pci_cfg) {
 
4081
                phba->idiag_pci_cfg =
 
4082
                        debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
 
4083
                                phba->idiag_root, phba, &lpfc_idiag_op_pciCfg);
 
4084
                if (!phba->idiag_pci_cfg) {
 
4085
                        lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
4086
                                         "2923 Can't create idiag debugfs\n");
 
4087
                        goto debug_failed;
 
4088
                }
 
4089
                idiag.offset.last_rd = 0;
 
4090
        }
 
4091
 
 
4092
        /* iDiag PCI BAR access */
 
4093
        snprintf(name, sizeof(name), "barAcc");
 
4094
        if (!phba->idiag_bar_acc) {
 
4095
                phba->idiag_bar_acc =
 
4096
                        debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
 
4097
                                phba->idiag_root, phba, &lpfc_idiag_op_barAcc);
 
4098
                if (!phba->idiag_bar_acc) {
 
4099
                        lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
4100
                                        "3056 Can't create idiag debugfs\n");
 
4101
                        goto debug_failed;
 
4102
                }
 
4103
                idiag.offset.last_rd = 0;
 
4104
        }
 
4105
 
 
4106
        /* iDiag get PCI function queue information */
 
4107
        snprintf(name, sizeof(name), "queInfo");
 
4108
        if (!phba->idiag_que_info) {
 
4109
                phba->idiag_que_info =
 
4110
                        debugfs_create_file(name, S_IFREG|S_IRUGO,
 
4111
                        phba->idiag_root, phba, &lpfc_idiag_op_queInfo);
 
4112
                if (!phba->idiag_que_info) {
 
4113
                        lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
4114
                                         "2924 Can't create idiag debugfs\n");
 
4115
                        goto debug_failed;
 
4116
                }
 
4117
        }
 
4118
 
 
4119
        /* iDiag access PCI function queue */
 
4120
        snprintf(name, sizeof(name), "queAcc");
 
4121
        if (!phba->idiag_que_acc) {
 
4122
                phba->idiag_que_acc =
 
4123
                        debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
 
4124
                                phba->idiag_root, phba, &lpfc_idiag_op_queAcc);
 
4125
                if (!phba->idiag_que_acc) {
 
4126
                        lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
4127
                                         "2926 Can't create idiag debugfs\n");
 
4128
                        goto debug_failed;
 
4129
                }
 
4130
        }
 
4131
 
 
4132
        /* iDiag access PCI function doorbell registers */
 
4133
        snprintf(name, sizeof(name), "drbAcc");
 
4134
        if (!phba->idiag_drb_acc) {
 
4135
                phba->idiag_drb_acc =
 
4136
                        debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
 
4137
                                phba->idiag_root, phba, &lpfc_idiag_op_drbAcc);
 
4138
                if (!phba->idiag_drb_acc) {
 
4139
                        lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
4140
                                         "2927 Can't create idiag debugfs\n");
 
4141
                        goto debug_failed;
 
4142
                }
 
4143
        }
 
4144
 
 
4145
        /* iDiag access PCI function control registers */
 
4146
        snprintf(name, sizeof(name), "ctlAcc");
 
4147
        if (!phba->idiag_ctl_acc) {
 
4148
                phba->idiag_ctl_acc =
 
4149
                        debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
 
4150
                                phba->idiag_root, phba, &lpfc_idiag_op_ctlAcc);
 
4151
                if (!phba->idiag_ctl_acc) {
 
4152
                        lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
4153
                                         "2981 Can't create idiag debugfs\n");
 
4154
                        goto debug_failed;
 
4155
                }
 
4156
        }
 
4157
 
 
4158
        /* iDiag access mbox commands */
 
4159
        snprintf(name, sizeof(name), "mbxAcc");
 
4160
        if (!phba->idiag_mbx_acc) {
 
4161
                phba->idiag_mbx_acc =
 
4162
                        debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
 
4163
                                phba->idiag_root, phba, &lpfc_idiag_op_mbxAcc);
 
4164
                if (!phba->idiag_mbx_acc) {
 
4165
                        lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
4166
                                        "2980 Can't create idiag debugfs\n");
 
4167
                        goto debug_failed;
 
4168
                }
 
4169
        }
 
4170
 
 
4171
        /* iDiag extents access commands */
 
4172
        if (phba->sli4_hba.extents_in_use) {
 
4173
                snprintf(name, sizeof(name), "extAcc");
 
4174
                if (!phba->idiag_ext_acc) {
 
4175
                        phba->idiag_ext_acc =
 
4176
                                debugfs_create_file(name,
 
4177
                                                    S_IFREG|S_IRUGO|S_IWUSR,
 
4178
                                                    phba->idiag_root, phba,
 
4179
                                                    &lpfc_idiag_op_extAcc);
 
4180
                        if (!phba->idiag_ext_acc) {
 
4181
                                lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
4182
                                                "2986 Cant create "
 
4183
                                                "idiag debugfs\n");
 
4184
                                goto debug_failed;
 
4185
                        }
 
4186
                }
 
4187
        }
 
4188
 
 
4189
debug_failed:
 
4190
        return;
 
4191
#endif
 
4192
}
 
4193
 
 
4194
/**
 
4195
 * lpfc_debugfs_terminate -  Tear down debugfs infrastructure for this vport
 
4196
 * @vport: The vport pointer to remove from debugfs.
 
4197
 *
 
4198
 * Description:
 
4199
 * When Debugfs is configured this routine removes debugfs file system elements
 
4200
 * that are specific to this vport. It also checks to see if there are any
 
4201
 * users left for the debugfs directories associated with the HBA and driver. If
 
4202
 * this is the last user of the HBA directory or driver directory then it will
 
4203
 * remove those from the debugfs infrastructure as well.
 
4204
 **/
 
4205
inline void
 
4206
lpfc_debugfs_terminate(struct lpfc_vport *vport)
 
4207
{
 
4208
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
 
4209
        struct lpfc_hba   *phba = vport->phba;
 
4210
 
 
4211
        if (vport->disc_trc) {
 
4212
                kfree(vport->disc_trc);
 
4213
                vport->disc_trc = NULL;
 
4214
        }
 
4215
        if (vport->debug_disc_trc) {
 
4216
                debugfs_remove(vport->debug_disc_trc); /* discovery_trace */
 
4217
                vport->debug_disc_trc = NULL;
 
4218
        }
 
4219
        if (vport->debug_nodelist) {
 
4220
                debugfs_remove(vport->debug_nodelist); /* nodelist */
 
4221
                vport->debug_nodelist = NULL;
 
4222
        }
 
4223
        if (vport->vport_debugfs_root) {
 
4224
                debugfs_remove(vport->vport_debugfs_root); /* vportX */
 
4225
                vport->vport_debugfs_root = NULL;
 
4226
                atomic_dec(&phba->debugfs_vport_count);
 
4227
        }
 
4228
        if (atomic_read(&phba->debugfs_vport_count) == 0) {
 
4229
 
 
4230
                if (phba->debug_hbqinfo) {
 
4231
                        debugfs_remove(phba->debug_hbqinfo); /* hbqinfo */
 
4232
                        phba->debug_hbqinfo = NULL;
 
4233
                }
 
4234
                if (phba->debug_dumpHBASlim) {
 
4235
                        debugfs_remove(phba->debug_dumpHBASlim); /* HBASlim */
 
4236
                        phba->debug_dumpHBASlim = NULL;
 
4237
                }
 
4238
                if (phba->debug_dumpHostSlim) {
 
4239
                        debugfs_remove(phba->debug_dumpHostSlim); /* HostSlim */
 
4240
                        phba->debug_dumpHostSlim = NULL;
 
4241
                }
 
4242
                if (phba->debug_dumpData) {
 
4243
                        debugfs_remove(phba->debug_dumpData); /* dumpData */
 
4244
                        phba->debug_dumpData = NULL;
 
4245
                }
 
4246
 
 
4247
                if (phba->debug_dumpDif) {
 
4248
                        debugfs_remove(phba->debug_dumpDif); /* dumpDif */
 
4249
                        phba->debug_dumpDif = NULL;
 
4250
                }
 
4251
                if (phba->debug_InjErrLBA) {
 
4252
                        debugfs_remove(phba->debug_InjErrLBA); /* InjErrLBA */
 
4253
                        phba->debug_InjErrLBA = NULL;
 
4254
                }
 
4255
                if (phba->debug_writeGuard) {
 
4256
                        debugfs_remove(phba->debug_writeGuard); /* writeGuard */
 
4257
                        phba->debug_writeGuard = NULL;
 
4258
                }
 
4259
                if (phba->debug_writeApp) {
 
4260
                        debugfs_remove(phba->debug_writeApp); /* writeApp */
 
4261
                        phba->debug_writeApp = NULL;
 
4262
                }
 
4263
                if (phba->debug_writeRef) {
 
4264
                        debugfs_remove(phba->debug_writeRef); /* writeRef */
 
4265
                        phba->debug_writeRef = NULL;
 
4266
                }
 
4267
                if (phba->debug_readApp) {
 
4268
                        debugfs_remove(phba->debug_readApp); /* readApp */
 
4269
                        phba->debug_readApp = NULL;
 
4270
                }
 
4271
                if (phba->debug_readRef) {
 
4272
                        debugfs_remove(phba->debug_readRef); /* readRef */
 
4273
                        phba->debug_readRef = NULL;
 
4274
                }
 
4275
 
 
4276
                if (phba->slow_ring_trc) {
 
4277
                        kfree(phba->slow_ring_trc);
 
4278
                        phba->slow_ring_trc = NULL;
 
4279
                }
 
4280
                if (phba->debug_slow_ring_trc) {
 
4281
                        /* slow_ring_trace */
 
4282
                        debugfs_remove(phba->debug_slow_ring_trc);
 
4283
                        phba->debug_slow_ring_trc = NULL;
 
4284
                }
 
4285
 
 
4286
                /*
 
4287
                 * iDiag release
 
4288
                 */
 
4289
                if (phba->sli_rev == LPFC_SLI_REV4) {
 
4290
                        if (phba->idiag_ext_acc) {
 
4291
                                /* iDiag extAcc */
 
4292
                                debugfs_remove(phba->idiag_ext_acc);
 
4293
                                phba->idiag_ext_acc = NULL;
 
4294
                        }
 
4295
                        if (phba->idiag_mbx_acc) {
 
4296
                                /* iDiag mbxAcc */
 
4297
                                debugfs_remove(phba->idiag_mbx_acc);
 
4298
                                phba->idiag_mbx_acc = NULL;
 
4299
                        }
 
4300
                        if (phba->idiag_ctl_acc) {
 
4301
                                /* iDiag ctlAcc */
 
4302
                                debugfs_remove(phba->idiag_ctl_acc);
 
4303
                                phba->idiag_ctl_acc = NULL;
 
4304
                        }
 
4305
                        if (phba->idiag_drb_acc) {
 
4306
                                /* iDiag drbAcc */
 
4307
                                debugfs_remove(phba->idiag_drb_acc);
 
4308
                                phba->idiag_drb_acc = NULL;
 
4309
                        }
 
4310
                        if (phba->idiag_que_acc) {
 
4311
                                /* iDiag queAcc */
 
4312
                                debugfs_remove(phba->idiag_que_acc);
 
4313
                                phba->idiag_que_acc = NULL;
 
4314
                        }
 
4315
                        if (phba->idiag_que_info) {
 
4316
                                /* iDiag queInfo */
 
4317
                                debugfs_remove(phba->idiag_que_info);
 
4318
                                phba->idiag_que_info = NULL;
 
4319
                        }
 
4320
                        if (phba->idiag_bar_acc) {
 
4321
                                /* iDiag barAcc */
 
4322
                                debugfs_remove(phba->idiag_bar_acc);
 
4323
                                phba->idiag_bar_acc = NULL;
 
4324
                        }
 
4325
                        if (phba->idiag_pci_cfg) {
 
4326
                                /* iDiag pciCfg */
 
4327
                                debugfs_remove(phba->idiag_pci_cfg);
 
4328
                                phba->idiag_pci_cfg = NULL;
 
4329
                        }
 
4330
 
 
4331
                        /* Finally remove the iDiag debugfs root */
 
4332
                        if (phba->idiag_root) {
 
4333
                                /* iDiag root */
 
4334
                                debugfs_remove(phba->idiag_root);
 
4335
                                phba->idiag_root = NULL;
 
4336
                        }
 
4337
                }
 
4338
 
 
4339
                if (phba->hba_debugfs_root) {
 
4340
                        debugfs_remove(phba->hba_debugfs_root); /* fnX */
 
4341
                        phba->hba_debugfs_root = NULL;
 
4342
                        atomic_dec(&lpfc_debugfs_hba_count);
 
4343
                }
 
4344
 
 
4345
                if (atomic_read(&lpfc_debugfs_hba_count) == 0) {
 
4346
                        debugfs_remove(lpfc_debugfs_root); /* lpfc */
 
4347
                        lpfc_debugfs_root = NULL;
 
4348
                }
 
4349
        }
 
4350
#endif
 
4351
        return;
 
4352
}