1*ef270ab1SKenneth D. Merry /*-
2*ef270ab1SKenneth D. Merry * Copyright (c) 2017 Broadcom. All rights reserved.
3*ef270ab1SKenneth D. Merry * The term "Broadcom" refers to Broadcom Limited and/or its subsidiaries.
4*ef270ab1SKenneth D. Merry *
5*ef270ab1SKenneth D. Merry * Redistribution and use in source and binary forms, with or without
6*ef270ab1SKenneth D. Merry * modification, are permitted provided that the following conditions are met:
7*ef270ab1SKenneth D. Merry *
8*ef270ab1SKenneth D. Merry * 1. Redistributions of source code must retain the above copyright notice,
9*ef270ab1SKenneth D. Merry * this list of conditions and the following disclaimer.
10*ef270ab1SKenneth D. Merry *
11*ef270ab1SKenneth D. Merry * 2. Redistributions in binary form must reproduce the above copyright notice,
12*ef270ab1SKenneth D. Merry * this list of conditions and the following disclaimer in the documentation
13*ef270ab1SKenneth D. Merry * and/or other materials provided with the distribution.
14*ef270ab1SKenneth D. Merry *
15*ef270ab1SKenneth D. Merry * 3. Neither the name of the copyright holder nor the names of its contributors
16*ef270ab1SKenneth D. Merry * may be used to endorse or promote products derived from this software
17*ef270ab1SKenneth D. Merry * without specific prior written permission.
18*ef270ab1SKenneth D. Merry *
19*ef270ab1SKenneth D. Merry * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20*ef270ab1SKenneth D. Merry * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21*ef270ab1SKenneth D. Merry * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22*ef270ab1SKenneth D. Merry * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23*ef270ab1SKenneth D. Merry * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24*ef270ab1SKenneth D. Merry * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25*ef270ab1SKenneth D. Merry * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26*ef270ab1SKenneth D. Merry * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27*ef270ab1SKenneth D. Merry * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28*ef270ab1SKenneth D. Merry * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29*ef270ab1SKenneth D. Merry * POSSIBILITY OF SUCH DAMAGE.
30*ef270ab1SKenneth D. Merry */
31*ef270ab1SKenneth D. Merry
32*ef270ab1SKenneth D. Merry /**
33*ef270ab1SKenneth D. Merry * @file
34*ef270ab1SKenneth D. Merry * generate FC ddump
35*ef270ab1SKenneth D. Merry *
36*ef270ab1SKenneth D. Merry */
37*ef270ab1SKenneth D. Merry
38*ef270ab1SKenneth D. Merry #include "ocs.h"
39*ef270ab1SKenneth D. Merry #include "ocs_ddump.h"
40*ef270ab1SKenneth D. Merry
41*ef270ab1SKenneth D. Merry #define DEFAULT_SAVED_DUMP_SIZE (4*1024*1024)
42*ef270ab1SKenneth D. Merry
43*ef270ab1SKenneth D. Merry void hw_queue_ddump(ocs_textbuf_t *textbuf, ocs_hw_t *hw);
44*ef270ab1SKenneth D. Merry
45*ef270ab1SKenneth D. Merry /**
46*ef270ab1SKenneth D. Merry * @brief Generate sli4 queue ddump
47*ef270ab1SKenneth D. Merry *
48*ef270ab1SKenneth D. Merry * Generates sli4 queue ddump data
49*ef270ab1SKenneth D. Merry *
50*ef270ab1SKenneth D. Merry * @param textbuf pointer to text buffer
51*ef270ab1SKenneth D. Merry * @param name name of SLI4 queue
52*ef270ab1SKenneth D. Merry * @param hw pointer HW context
53*ef270ab1SKenneth D. Merry * @param q pointer to SLI4 queues array
54*ef270ab1SKenneth D. Merry * @param q_count count of SLI4 queues
55*ef270ab1SKenneth D. Merry * @param qentries number of SLI4 queue entries to dump
56*ef270ab1SKenneth D. Merry *
57*ef270ab1SKenneth D. Merry * @return none
58*ef270ab1SKenneth D. Merry */
59*ef270ab1SKenneth D. Merry
60*ef270ab1SKenneth D. Merry static void
ocs_ddump_sli4_queue(ocs_textbuf_t * textbuf,const char * name,ocs_hw_t * hw,sli4_queue_t * q,uint32_t q_count,uint32_t qentries)61*ef270ab1SKenneth D. Merry ocs_ddump_sli4_queue(ocs_textbuf_t *textbuf, const char *name, ocs_hw_t *hw, sli4_queue_t *q, uint32_t q_count, uint32_t qentries)
62*ef270ab1SKenneth D. Merry {
63*ef270ab1SKenneth D. Merry uint32_t i;
64*ef270ab1SKenneth D. Merry
65*ef270ab1SKenneth D. Merry for (i = 0; i < q_count; i ++, q ++) {
66*ef270ab1SKenneth D. Merry ocs_ddump_section(textbuf, name, i);
67*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "index", "%d", q->index);
68*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "size", "%d", q->size);
69*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "length", "%d", q->length);
70*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "n_posted", "%d", q->n_posted);
71*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "id", "%d", q->id);
72*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "type", "%d", q->type);
73*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "proc_limit", "%d", q->proc_limit);
74*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "posted_limit", "%d", q->posted_limit);
75*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "max_num_processed", "%d", q->max_num_processed);
76*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "max_process_time", "%ld", (unsigned long)q->max_process_time);
77*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "virt_addr", "%p", q->dma.virt);
78*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "phys_addr", "%lx", (unsigned long)q->dma.phys);
79*ef270ab1SKenneth D. Merry
80*ef270ab1SKenneth D. Merry /* queue-specific information */
81*ef270ab1SKenneth D. Merry switch (q->type) {
82*ef270ab1SKenneth D. Merry case SLI_QTYPE_MQ:
83*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "r_idx", "%d", q->u.r_idx);
84*ef270ab1SKenneth D. Merry break;
85*ef270ab1SKenneth D. Merry case SLI_QTYPE_CQ:
86*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "is_mq", "%d", q->u.flag.is_mq);
87*ef270ab1SKenneth D. Merry break;
88*ef270ab1SKenneth D. Merry case SLI_QTYPE_WQ:
89*ef270ab1SKenneth D. Merry break;
90*ef270ab1SKenneth D. Merry case SLI_QTYPE_RQ: {
91*ef270ab1SKenneth D. Merry uint32_t i;
92*ef270ab1SKenneth D. Merry uint32_t j;
93*ef270ab1SKenneth D. Merry uint32_t rqe_count = 0;
94*ef270ab1SKenneth D. Merry hw_rq_t *rq;
95*ef270ab1SKenneth D. Merry
96*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "is_hdr", "%d", q->u.flag.is_hdr);
97*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "rq_batch", "%d", q->u.flag.rq_batch);
98*ef270ab1SKenneth D. Merry
99*ef270ab1SKenneth D. Merry /* loop through RQ tracker to see how many RQEs were produced */
100*ef270ab1SKenneth D. Merry for (i = 0; i < hw->hw_rq_count; i++) {
101*ef270ab1SKenneth D. Merry rq = hw->hw_rq[i];
102*ef270ab1SKenneth D. Merry for (j = 0; j < rq->entry_count; j++) {
103*ef270ab1SKenneth D. Merry if (rq->rq_tracker[j] != NULL) {
104*ef270ab1SKenneth D. Merry rqe_count++;
105*ef270ab1SKenneth D. Merry }
106*ef270ab1SKenneth D. Merry }
107*ef270ab1SKenneth D. Merry }
108*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "rqes_produced", "%d", rqe_count);
109*ef270ab1SKenneth D. Merry break;
110*ef270ab1SKenneth D. Merry }
111*ef270ab1SKenneth D. Merry }
112*ef270ab1SKenneth D. Merry ocs_ddump_queue_entries(textbuf, q->dma.virt, q->size, q->length,
113*ef270ab1SKenneth D. Merry ((q->type == SLI_QTYPE_MQ) ? q->u.r_idx : q->index),
114*ef270ab1SKenneth D. Merry qentries);
115*ef270ab1SKenneth D. Merry ocs_ddump_endsection(textbuf, name, i);
116*ef270ab1SKenneth D. Merry }
117*ef270ab1SKenneth D. Merry }
118*ef270ab1SKenneth D. Merry
119*ef270ab1SKenneth D. Merry /**
120*ef270ab1SKenneth D. Merry * @brief Generate SLI4 ddump
121*ef270ab1SKenneth D. Merry *
122*ef270ab1SKenneth D. Merry * Generates sli4 ddump
123*ef270ab1SKenneth D. Merry *
124*ef270ab1SKenneth D. Merry * @param textbuf pointer to text buffer
125*ef270ab1SKenneth D. Merry * @param sli4 pointer SLI context
126*ef270ab1SKenneth D. Merry * @param qtype SLI4 queue type
127*ef270ab1SKenneth D. Merry *
128*ef270ab1SKenneth D. Merry * @return none
129*ef270ab1SKenneth D. Merry */
130*ef270ab1SKenneth D. Merry
131*ef270ab1SKenneth D. Merry static void
ocs_ddump_sli_q_fields(ocs_textbuf_t * textbuf,sli4_t * sli4,sli4_qtype_e qtype)132*ef270ab1SKenneth D. Merry ocs_ddump_sli_q_fields(ocs_textbuf_t *textbuf, sli4_t *sli4, sli4_qtype_e qtype)
133*ef270ab1SKenneth D. Merry {
134*ef270ab1SKenneth D. Merry char * q_desc;
135*ef270ab1SKenneth D. Merry
136*ef270ab1SKenneth D. Merry switch(qtype) {
137*ef270ab1SKenneth D. Merry case SLI_QTYPE_EQ: q_desc = "EQ"; break;
138*ef270ab1SKenneth D. Merry case SLI_QTYPE_CQ: q_desc = "CQ"; break;
139*ef270ab1SKenneth D. Merry case SLI_QTYPE_MQ: q_desc = "MQ"; break;
140*ef270ab1SKenneth D. Merry case SLI_QTYPE_WQ: q_desc = "WQ"; break;
141*ef270ab1SKenneth D. Merry case SLI_QTYPE_RQ: q_desc = "RQ"; break;
142*ef270ab1SKenneth D. Merry default: q_desc = "unknown"; break;
143*ef270ab1SKenneth D. Merry }
144*ef270ab1SKenneth D. Merry
145*ef270ab1SKenneth D. Merry ocs_ddump_section(textbuf, q_desc, qtype);
146*ef270ab1SKenneth D. Merry
147*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "max_qcount", "%d", sli4->config.max_qcount[qtype]);
148*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "max_qentries", "%d", sli4->config.max_qentries[qtype]);
149*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "qpage_count", "%d", sli4->config.qpage_count[qtype]);
150*ef270ab1SKenneth D. Merry ocs_ddump_endsection(textbuf, q_desc, qtype);
151*ef270ab1SKenneth D. Merry }
152*ef270ab1SKenneth D. Merry
153*ef270ab1SKenneth D. Merry /**
154*ef270ab1SKenneth D. Merry * @brief Generate SLI4 ddump
155*ef270ab1SKenneth D. Merry *
156*ef270ab1SKenneth D. Merry * Generates sli4 ddump
157*ef270ab1SKenneth D. Merry *
158*ef270ab1SKenneth D. Merry * @param textbuf pointer to text buffer
159*ef270ab1SKenneth D. Merry * @param sli4 pointer SLI context
160*ef270ab1SKenneth D. Merry *
161*ef270ab1SKenneth D. Merry * @return none
162*ef270ab1SKenneth D. Merry */
163*ef270ab1SKenneth D. Merry
164*ef270ab1SKenneth D. Merry static void
ocs_ddump_sli(ocs_textbuf_t * textbuf,sli4_t * sli4)165*ef270ab1SKenneth D. Merry ocs_ddump_sli(ocs_textbuf_t *textbuf, sli4_t *sli4)
166*ef270ab1SKenneth D. Merry {
167*ef270ab1SKenneth D. Merry sli4_sgl_chaining_params_t *cparams = &sli4->config.sgl_chaining_params;
168*ef270ab1SKenneth D. Merry const char *p;
169*ef270ab1SKenneth D. Merry
170*ef270ab1SKenneth D. Merry ocs_ddump_section(textbuf, "sli4", 0);
171*ef270ab1SKenneth D. Merry
172*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "sli_rev", "%d", sli4->sli_rev);
173*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "sli_family", "%d", sli4->sli_family);
174*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "if_type", "%d", sli4->if_type);
175*ef270ab1SKenneth D. Merry
176*ef270ab1SKenneth D. Merry switch(sli4->asic_type) {
177*ef270ab1SKenneth D. Merry case SLI4_ASIC_TYPE_BE3: p = "BE3"; break;
178*ef270ab1SKenneth D. Merry case SLI4_ASIC_TYPE_SKYHAWK: p = "Skyhawk"; break;
179*ef270ab1SKenneth D. Merry case SLI4_ASIC_TYPE_LANCER: p = "Lancer"; break;
180*ef270ab1SKenneth D. Merry case SLI4_ASIC_TYPE_LANCERG6: p = "LancerG6"; break;
181*ef270ab1SKenneth D. Merry default: p = "unknown"; break;
182*ef270ab1SKenneth D. Merry }
183*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "asic_type", "%s", p);
184*ef270ab1SKenneth D. Merry
185*ef270ab1SKenneth D. Merry switch(sli4->asic_rev) {
186*ef270ab1SKenneth D. Merry case SLI4_ASIC_REV_FPGA: p = "fpga"; break;
187*ef270ab1SKenneth D. Merry case SLI4_ASIC_REV_A0: p = "A0"; break;
188*ef270ab1SKenneth D. Merry case SLI4_ASIC_REV_A1: p = "A1"; break;
189*ef270ab1SKenneth D. Merry case SLI4_ASIC_REV_A2: p = "A2"; break;
190*ef270ab1SKenneth D. Merry case SLI4_ASIC_REV_A3: p = "A3"; break;
191*ef270ab1SKenneth D. Merry case SLI4_ASIC_REV_B0: p = "B0"; break;
192*ef270ab1SKenneth D. Merry case SLI4_ASIC_REV_C0: p = "C0"; break;
193*ef270ab1SKenneth D. Merry case SLI4_ASIC_REV_D0: p = "D0"; break;
194*ef270ab1SKenneth D. Merry default: p = "unknown"; break;
195*ef270ab1SKenneth D. Merry }
196*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "asic_rev", "%s", p);
197*ef270ab1SKenneth D. Merry
198*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "e_d_tov", "%d", sli4->config.e_d_tov);
199*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "r_a_tov", "%d", sli4->config.r_a_tov);
200*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "link_module_type", "%d", sli4->config.link_module_type);
201*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "rq_batch", "%d", sli4->config.rq_batch);
202*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "topology", "%d", sli4->config.topology);
203*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "wwpn", "%02x%02x%02x%02x%02x%02x%02x%02x",
204*ef270ab1SKenneth D. Merry sli4->config.wwpn[0],
205*ef270ab1SKenneth D. Merry sli4->config.wwpn[1],
206*ef270ab1SKenneth D. Merry sli4->config.wwpn[2],
207*ef270ab1SKenneth D. Merry sli4->config.wwpn[3],
208*ef270ab1SKenneth D. Merry sli4->config.wwpn[4],
209*ef270ab1SKenneth D. Merry sli4->config.wwpn[5],
210*ef270ab1SKenneth D. Merry sli4->config.wwpn[6],
211*ef270ab1SKenneth D. Merry sli4->config.wwpn[7]);
212*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "wwnn", "%02x%02x%02x%02x%02x%02x%02x%02x",
213*ef270ab1SKenneth D. Merry sli4->config.wwnn[0],
214*ef270ab1SKenneth D. Merry sli4->config.wwnn[1],
215*ef270ab1SKenneth D. Merry sli4->config.wwnn[2],
216*ef270ab1SKenneth D. Merry sli4->config.wwnn[3],
217*ef270ab1SKenneth D. Merry sli4->config.wwnn[4],
218*ef270ab1SKenneth D. Merry sli4->config.wwnn[5],
219*ef270ab1SKenneth D. Merry sli4->config.wwnn[6],
220*ef270ab1SKenneth D. Merry sli4->config.wwnn[7]);
221*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "fw_rev0", "%d", sli4->config.fw_rev[0]);
222*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "fw_rev1", "%d", sli4->config.fw_rev[1]);
223*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "fw_name0", "%s", (char*)sli4->config.fw_name[0]);
224*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "fw_name1", "%s", (char*)sli4->config.fw_name[1]);
225*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "hw_rev0", "%x", sli4->config.hw_rev[0]);
226*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "hw_rev1", "%x", sli4->config.hw_rev[1]);
227*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "hw_rev2", "%x", sli4->config.hw_rev[2]);
228*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "sge_supported_length", "%x", sli4->config.sge_supported_length);
229*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "sgl_page_sizes", "%x", sli4->config.sgl_page_sizes);
230*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "max_sgl_pages", "%x", sli4->config.max_sgl_pages);
231*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "high_login_mode", "%x", sli4->config.high_login_mode);
232*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "sgl_pre_registered", "%x", sli4->config.sgl_pre_registered);
233*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "sgl_pre_registration_required", "%x", sli4->config.sgl_pre_registration_required);
234*ef270ab1SKenneth D. Merry
235*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "sgl_chaining_capable", "%x", cparams->chaining_capable);
236*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "frag_num_field_offset", "%x", cparams->frag_num_field_offset);
237*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "frag_num_field_mask", "%016llx", (unsigned long long)cparams->frag_num_field_mask);
238*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "sgl_index_field_offset", "%x", cparams->sgl_index_field_offset);
239*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "sgl_index_field_mask", "%016llx", (unsigned long long)cparams->sgl_index_field_mask);
240*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "chain_sge_initial_value_lo", "%x", cparams->chain_sge_initial_value_lo);
241*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "chain_sge_initial_value_hi", "%x", cparams->chain_sge_initial_value_hi);
242*ef270ab1SKenneth D. Merry
243*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "max_vfi", "%d", sli_get_max_rsrc(sli4, SLI_RSRC_FCOE_VFI));
244*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "max_vpi", "%d", sli_get_max_rsrc(sli4, SLI_RSRC_FCOE_VPI));
245*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "max_rpi", "%d", sli_get_max_rsrc(sli4, SLI_RSRC_FCOE_RPI));
246*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "max_xri", "%d", sli_get_max_rsrc(sli4, SLI_RSRC_FCOE_XRI));
247*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "max_fcfi", "%d", sli_get_max_rsrc(sli4, SLI_RSRC_FCOE_FCFI));
248*ef270ab1SKenneth D. Merry
249*ef270ab1SKenneth D. Merry ocs_ddump_sli_q_fields(textbuf, sli4, SLI_QTYPE_EQ);
250*ef270ab1SKenneth D. Merry ocs_ddump_sli_q_fields(textbuf, sli4, SLI_QTYPE_CQ);
251*ef270ab1SKenneth D. Merry ocs_ddump_sli_q_fields(textbuf, sli4, SLI_QTYPE_MQ);
252*ef270ab1SKenneth D. Merry ocs_ddump_sli_q_fields(textbuf, sli4, SLI_QTYPE_WQ);
253*ef270ab1SKenneth D. Merry ocs_ddump_sli_q_fields(textbuf, sli4, SLI_QTYPE_RQ);
254*ef270ab1SKenneth D. Merry
255*ef270ab1SKenneth D. Merry ocs_ddump_endsection(textbuf, "sli4", 0);
256*ef270ab1SKenneth D. Merry }
257*ef270ab1SKenneth D. Merry
258*ef270ab1SKenneth D. Merry /**
259*ef270ab1SKenneth D. Merry * @brief Dump HW IO
260*ef270ab1SKenneth D. Merry *
261*ef270ab1SKenneth D. Merry * Dump HW IO
262*ef270ab1SKenneth D. Merry *
263*ef270ab1SKenneth D. Merry * @param textbuf pointer to text buffer
264*ef270ab1SKenneth D. Merry * @param io pointer to HW IO object
265*ef270ab1SKenneth D. Merry *
266*ef270ab1SKenneth D. Merry * @return none
267*ef270ab1SKenneth D. Merry */
268*ef270ab1SKenneth D. Merry
269*ef270ab1SKenneth D. Merry static void
ocs_ddump_hw_io(ocs_textbuf_t * textbuf,ocs_hw_io_t * io)270*ef270ab1SKenneth D. Merry ocs_ddump_hw_io(ocs_textbuf_t *textbuf, ocs_hw_io_t *io)
271*ef270ab1SKenneth D. Merry {
272*ef270ab1SKenneth D. Merry ocs_assert(io);
273*ef270ab1SKenneth D. Merry
274*ef270ab1SKenneth D. Merry ocs_ddump_section(textbuf, "hw_io", io->indicator);
275*ef270ab1SKenneth D. Merry
276*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "state", "%d", io->state);
277*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "xri", "0x%x", io->indicator);
278*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "tag", "0x%x", io->reqtag);
279*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "abort_reqtag", "0x%x", io->abort_reqtag);
280*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "ref_count", "%d", ocs_ref_read_count(&io->ref));
281*ef270ab1SKenneth D. Merry
282*ef270ab1SKenneth D. Merry /* just to make it obvious, display abort bit from tag */
283*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "abort", "0x%x", io->abort_in_progress);
284*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "wq_index", "%d", (io->wq == NULL ? 0xffff : io->wq->instance));
285*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "type", "%d", io->type);
286*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "xbusy", "%d", io->xbusy);
287*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "active_wqe_link", "%d", ocs_list_on_list(&io->wqe_link));
288*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "def_sgl_count", "%d", io->def_sgl_count);
289*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "n_sge", "%d", io->n_sge);
290*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "has_ovfl_sgl", "%s", (io->ovfl_sgl != NULL ? "TRUE" : "FALSE"));
291*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "has_ovfl_io", "%s", (io->ovfl_io != NULL ? "TRUE" : "FALSE"));
292*ef270ab1SKenneth D. Merry
293*ef270ab1SKenneth D. Merry ocs_ddump_endsection(textbuf, "hw_io", io->indicator);
294*ef270ab1SKenneth D. Merry }
295*ef270ab1SKenneth D. Merry
296*ef270ab1SKenneth D. Merry #if defined(OCS_DEBUG_QUEUE_HISTORY)
297*ef270ab1SKenneth D. Merry
298*ef270ab1SKenneth D. Merry /**
299*ef270ab1SKenneth D. Merry * @brief Generate queue history ddump
300*ef270ab1SKenneth D. Merry *
301*ef270ab1SKenneth D. Merry * @param textbuf pointer to text buffer
302*ef270ab1SKenneth D. Merry * @param q_hist Pointer to queue history object.
303*ef270ab1SKenneth D. Merry */
304*ef270ab1SKenneth D. Merry static void
ocs_ddump_queue_history(ocs_textbuf_t * textbuf,ocs_hw_q_hist_t * q_hist)305*ef270ab1SKenneth D. Merry ocs_ddump_queue_history(ocs_textbuf_t *textbuf, ocs_hw_q_hist_t *q_hist)
306*ef270ab1SKenneth D. Merry {
307*ef270ab1SKenneth D. Merry uint32_t x;
308*ef270ab1SKenneth D. Merry
309*ef270ab1SKenneth D. Merry ocs_ddump_section(textbuf, "q_hist", 0);
310*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "count", "%ld", OCS_Q_HIST_SIZE);
311*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "index", "%d", q_hist->q_hist_index);
312*ef270ab1SKenneth D. Merry
313*ef270ab1SKenneth D. Merry if (q_hist->q_hist == NULL) {
314*ef270ab1SKenneth D. Merry ocs_ddump_section(textbuf, "history", 0);
315*ef270ab1SKenneth D. Merry ocs_textbuf_printf(textbuf, "No history available\n");
316*ef270ab1SKenneth D. Merry ocs_ddump_endsection(textbuf, "history", 0);
317*ef270ab1SKenneth D. Merry ocs_ddump_endsection(textbuf, "q_hist", 0);
318*ef270ab1SKenneth D. Merry return;
319*ef270ab1SKenneth D. Merry }
320*ef270ab1SKenneth D. Merry
321*ef270ab1SKenneth D. Merry /* start from last entry and go backwards */
322*ef270ab1SKenneth D. Merry ocs_textbuf_printf(textbuf, "<history>\n");
323*ef270ab1SKenneth D. Merry ocs_textbuf_printf(textbuf, "(newest first):\n");
324*ef270ab1SKenneth D. Merry
325*ef270ab1SKenneth D. Merry ocs_lock(&q_hist->q_hist_lock);
326*ef270ab1SKenneth D. Merry x = ocs_queue_history_prev_index(q_hist->q_hist_index);
327*ef270ab1SKenneth D. Merry do {
328*ef270ab1SKenneth D. Merry int i;
329*ef270ab1SKenneth D. Merry ocs_q_hist_ftr_t ftr;
330*ef270ab1SKenneth D. Merry uint32_t mask;
331*ef270ab1SKenneth D. Merry
332*ef270ab1SKenneth D. Merry /* footer's mask indicates what words were captured */
333*ef270ab1SKenneth D. Merry ftr.word = q_hist->q_hist[x];
334*ef270ab1SKenneth D. Merry mask = ftr.s.mask;
335*ef270ab1SKenneth D. Merry i = 0;
336*ef270ab1SKenneth D. Merry
337*ef270ab1SKenneth D. Merry /* if we've encountered a mask of 0, must be done */
338*ef270ab1SKenneth D. Merry if (mask == 0) {
339*ef270ab1SKenneth D. Merry break;
340*ef270ab1SKenneth D. Merry }
341*ef270ab1SKenneth D. Merry
342*ef270ab1SKenneth D. Merry /* display entry type */
343*ef270ab1SKenneth D. Merry ocs_textbuf_printf(textbuf, "%s:\n",
344*ef270ab1SKenneth D. Merry ocs_queue_history_type_name(ftr.s.type));
345*ef270ab1SKenneth D. Merry
346*ef270ab1SKenneth D. Merry if (ocs_queue_history_timestamp_enabled()) {
347*ef270ab1SKenneth D. Merry uint64_t tsc_value;
348*ef270ab1SKenneth D. Merry x = ocs_queue_history_prev_index(x);
349*ef270ab1SKenneth D. Merry tsc_value = ((q_hist->q_hist[x]) & 0x00000000FFFFFFFFull);
350*ef270ab1SKenneth D. Merry x = ocs_queue_history_prev_index(x);
351*ef270ab1SKenneth D. Merry tsc_value |= (((uint64_t)q_hist->q_hist[x] << 32) & 0xFFFFFFFF00000000ull);
352*ef270ab1SKenneth D. Merry ocs_textbuf_printf(textbuf, " t: %" PRIu64 "\n", tsc_value);
353*ef270ab1SKenneth D. Merry }
354*ef270ab1SKenneth D. Merry
355*ef270ab1SKenneth D. Merry if (ocs_queue_history_q_info_enabled()) {
356*ef270ab1SKenneth D. Merry if (ftr.s.type == OCS_Q_HIST_TYPE_CWQE ||
357*ef270ab1SKenneth D. Merry ftr.s.type == OCS_Q_HIST_TYPE_CXABT ||
358*ef270ab1SKenneth D. Merry ftr.s.type == OCS_Q_HIST_TYPE_WQE) {
359*ef270ab1SKenneth D. Merry x = ocs_queue_history_prev_index(x);
360*ef270ab1SKenneth D. Merry ocs_textbuf_printf(textbuf, " qid=0x%x idx=0x%x\n",
361*ef270ab1SKenneth D. Merry ((q_hist->q_hist[x] >> 16) & 0xFFFF),
362*ef270ab1SKenneth D. Merry ((q_hist->q_hist[x] >> 0) & 0xFFFF));
363*ef270ab1SKenneth D. Merry }
364*ef270ab1SKenneth D. Merry }
365*ef270ab1SKenneth D. Merry
366*ef270ab1SKenneth D. Merry while (mask) {
367*ef270ab1SKenneth D. Merry if ((mask & 1) && (x != q_hist->q_hist_index)){
368*ef270ab1SKenneth D. Merry /* get next word */
369*ef270ab1SKenneth D. Merry x = ocs_queue_history_prev_index(x);
370*ef270ab1SKenneth D. Merry ocs_textbuf_printf(textbuf, " [%d]=%x\n",
371*ef270ab1SKenneth D. Merry i, q_hist->q_hist[x]);
372*ef270ab1SKenneth D. Merry }
373*ef270ab1SKenneth D. Merry mask = (mask >> 1UL);
374*ef270ab1SKenneth D. Merry i++;
375*ef270ab1SKenneth D. Merry }
376*ef270ab1SKenneth D. Merry
377*ef270ab1SKenneth D. Merry /* go backwards to next element */
378*ef270ab1SKenneth D. Merry x = ocs_queue_history_prev_index(x);
379*ef270ab1SKenneth D. Merry } while (x != ocs_queue_history_prev_index(q_hist->q_hist_index));
380*ef270ab1SKenneth D. Merry ocs_unlock(&q_hist->q_hist_lock);
381*ef270ab1SKenneth D. Merry
382*ef270ab1SKenneth D. Merry ocs_textbuf_printf(textbuf, "</history>\n");
383*ef270ab1SKenneth D. Merry ocs_ddump_endsection(textbuf, "q_hist", 0);
384*ef270ab1SKenneth D. Merry }
385*ef270ab1SKenneth D. Merry #endif
386*ef270ab1SKenneth D. Merry
387*ef270ab1SKenneth D. Merry /**
388*ef270ab1SKenneth D. Merry * @brief Generate hw ddump
389*ef270ab1SKenneth D. Merry *
390*ef270ab1SKenneth D. Merry * Generates hw ddump
391*ef270ab1SKenneth D. Merry *
392*ef270ab1SKenneth D. Merry * @param textbuf pointer to text buffer
393*ef270ab1SKenneth D. Merry * @param hw pointer HW context
394*ef270ab1SKenneth D. Merry * @param flags ddump flags
395*ef270ab1SKenneth D. Merry * @param qentries number of qentries to dump
396*ef270ab1SKenneth D. Merry *
397*ef270ab1SKenneth D. Merry * @return none
398*ef270ab1SKenneth D. Merry */
399*ef270ab1SKenneth D. Merry
400*ef270ab1SKenneth D. Merry static void
ocs_ddump_hw(ocs_textbuf_t * textbuf,ocs_hw_t * hw,uint32_t flags,uint32_t qentries)401*ef270ab1SKenneth D. Merry ocs_ddump_hw(ocs_textbuf_t *textbuf, ocs_hw_t *hw, uint32_t flags, uint32_t qentries)
402*ef270ab1SKenneth D. Merry {
403*ef270ab1SKenneth D. Merry ocs_t *ocs = hw->os;
404*ef270ab1SKenneth D. Merry uint32_t cnt = 0;
405*ef270ab1SKenneth D. Merry ocs_hw_io_t *io = NULL;
406*ef270ab1SKenneth D. Merry uint32_t i;
407*ef270ab1SKenneth D. Merry uint32_t j;
408*ef270ab1SKenneth D. Merry uint32_t max_rpi = sli_get_max_rsrc(&hw->sli, SLI_RSRC_FCOE_RPI);
409*ef270ab1SKenneth D. Merry
410*ef270ab1SKenneth D. Merry ocs_assert(ocs);
411*ef270ab1SKenneth D. Merry
412*ef270ab1SKenneth D. Merry ocs_ddump_section(textbuf, "hw", ocs->instance_index);
413*ef270ab1SKenneth D. Merry
414*ef270ab1SKenneth D. Merry /* device specific information */
415*ef270ab1SKenneth D. Merry switch(hw->sli.if_type) {
416*ef270ab1SKenneth D. Merry case 0:
417*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "uerr_mask_hi", "%08x",
418*ef270ab1SKenneth D. Merry sli_reg_read(&hw->sli, SLI4_REG_UERR_MASK_HI));
419*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "uerr_mask_lo", "%08x",
420*ef270ab1SKenneth D. Merry sli_reg_read(&hw->sli, SLI4_REG_UERR_MASK_LO));
421*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "uerr_status_hi", "%08x",
422*ef270ab1SKenneth D. Merry sli_reg_read(&hw->sli, SLI4_REG_UERR_STATUS_HI));
423*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "uerr_status_lo", "%08x",
424*ef270ab1SKenneth D. Merry sli_reg_read(&hw->sli, SLI4_REG_UERR_STATUS_LO));
425*ef270ab1SKenneth D. Merry break;
426*ef270ab1SKenneth D. Merry case 2:
427*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "sliport_status", "%08x",
428*ef270ab1SKenneth D. Merry sli_reg_read(&hw->sli, SLI4_REG_SLIPORT_STATUS));
429*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "sliport_error1", "%08x",
430*ef270ab1SKenneth D. Merry sli_reg_read(&hw->sli, SLI4_REG_SLIPORT_ERROR1));
431*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "sliport_error2", "%08x",
432*ef270ab1SKenneth D. Merry sli_reg_read(&hw->sli, SLI4_REG_SLIPORT_ERROR2));
433*ef270ab1SKenneth D. Merry break;
434*ef270ab1SKenneth D. Merry }
435*ef270ab1SKenneth D. Merry
436*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "link_status", "%d", hw->link.status);
437*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "link_speed", "%d", hw->link.speed);
438*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "link_topology", "%d", hw->link.topology);
439*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "state", "%d", hw->state);
440*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "io_alloc_failed_count", "%d", ocs_atomic_read(&hw->io_alloc_failed_count));
441*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "n_io", "%d", hw->config.n_io);
442*ef270ab1SKenneth D. Merry
443*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "queue_topology", "%s", hw->config.queue_topology);
444*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "rq_selection_policy", "%d", hw->config.rq_selection_policy);
445*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "rr_quanta", "%d", hw->config.rr_quanta);
446*ef270ab1SKenneth D. Merry for (i = 0; i < ARRAY_SIZE(hw->config.filter_def); i++) {
447*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "filter_def", "%08X", hw->config.filter_def[i]);
448*ef270ab1SKenneth D. Merry }
449*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "n_eq", "%d", hw->eq_count);
450*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "n_cq", "%d", hw->cq_count);
451*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "n_mq", "%d", hw->mq_count);
452*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "n_rq", "%d", hw->rq_count);
453*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "n_wq", "%d", hw->wq_count);
454*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "n_sgl", "%d", hw->config.n_sgl);
455*ef270ab1SKenneth D. Merry
456*ef270ab1SKenneth D. Merry ocs_ddump_sli(textbuf, &hw->sli);
457*ef270ab1SKenneth D. Merry
458*ef270ab1SKenneth D. Merry ocs_ddump_sli4_queue(textbuf, "wq", hw, hw->wq, hw->wq_count,
459*ef270ab1SKenneth D. Merry ((flags & OCS_DDUMP_FLAGS_WQES) ? qentries : 0));
460*ef270ab1SKenneth D. Merry ocs_ddump_sli4_queue(textbuf, "rq", hw, hw->rq, hw->rq_count,
461*ef270ab1SKenneth D. Merry ((flags & OCS_DDUMP_FLAGS_RQES) ? qentries : 0));
462*ef270ab1SKenneth D. Merry ocs_ddump_sli4_queue(textbuf, "mq", hw, hw->mq, hw->mq_count,
463*ef270ab1SKenneth D. Merry ((flags & OCS_DDUMP_FLAGS_MQES) ? qentries : 0));
464*ef270ab1SKenneth D. Merry ocs_ddump_sli4_queue(textbuf, "cq", hw, hw->cq, hw->cq_count,
465*ef270ab1SKenneth D. Merry ((flags & OCS_DDUMP_FLAGS_CQES) ? qentries : 0));
466*ef270ab1SKenneth D. Merry ocs_ddump_sli4_queue(textbuf, "eq", hw, hw->eq, hw->eq_count,
467*ef270ab1SKenneth D. Merry ((flags & OCS_DDUMP_FLAGS_EQES) ? qentries : 0));
468*ef270ab1SKenneth D. Merry
469*ef270ab1SKenneth D. Merry /* dump the IO quarantine list */
470*ef270ab1SKenneth D. Merry for (i = 0; i < hw->wq_count; i++) {
471*ef270ab1SKenneth D. Merry ocs_ddump_section(textbuf, "io_quarantine", i);
472*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "quarantine_index", "%d", hw->hw_wq[i]->quarantine_info.quarantine_index);
473*ef270ab1SKenneth D. Merry for (j = 0; j < OCS_HW_QUARANTINE_QUEUE_DEPTH; j++) {
474*ef270ab1SKenneth D. Merry if (hw->hw_wq[i]->quarantine_info.quarantine_ios[j] != NULL) {
475*ef270ab1SKenneth D. Merry ocs_ddump_hw_io(textbuf, hw->hw_wq[i]->quarantine_info.quarantine_ios[j]);
476*ef270ab1SKenneth D. Merry }
477*ef270ab1SKenneth D. Merry }
478*ef270ab1SKenneth D. Merry ocs_ddump_endsection(textbuf, "io_quarantine", i);
479*ef270ab1SKenneth D. Merry }
480*ef270ab1SKenneth D. Merry
481*ef270ab1SKenneth D. Merry ocs_ddump_section(textbuf, "workaround", ocs->instance_index);
482*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "fwrev", "%08llx", (unsigned long long)hw->workaround.fwrev);
483*ef270ab1SKenneth D. Merry ocs_ddump_endsection(textbuf, "workaround", ocs->instance_index);
484*ef270ab1SKenneth D. Merry
485*ef270ab1SKenneth D. Merry ocs_lock(&hw->io_lock);
486*ef270ab1SKenneth D. Merry ocs_ddump_section(textbuf, "io_inuse", ocs->instance_index);
487*ef270ab1SKenneth D. Merry ocs_list_foreach(&hw->io_inuse, io) {
488*ef270ab1SKenneth D. Merry ocs_ddump_hw_io(textbuf, io);
489*ef270ab1SKenneth D. Merry }
490*ef270ab1SKenneth D. Merry ocs_ddump_endsection(textbuf, "io_inuse", ocs->instance_index);
491*ef270ab1SKenneth D. Merry
492*ef270ab1SKenneth D. Merry ocs_ddump_section(textbuf, "io_wait_free", ocs->instance_index);
493*ef270ab1SKenneth D. Merry ocs_list_foreach(&hw->io_wait_free, io) {
494*ef270ab1SKenneth D. Merry ocs_ddump_hw_io(textbuf, io);
495*ef270ab1SKenneth D. Merry }
496*ef270ab1SKenneth D. Merry ocs_ddump_endsection(textbuf, "io_wait_free", ocs->instance_index);
497*ef270ab1SKenneth D. Merry ocs_ddump_section(textbuf, "io_free", ocs->instance_index);
498*ef270ab1SKenneth D. Merry ocs_list_foreach(&hw->io_free, io) {
499*ef270ab1SKenneth D. Merry if (io->xbusy) {
500*ef270ab1SKenneth D. Merry /* only display free ios if they're active */
501*ef270ab1SKenneth D. Merry ocs_ddump_hw_io(textbuf, io);
502*ef270ab1SKenneth D. Merry }
503*ef270ab1SKenneth D. Merry cnt++;
504*ef270ab1SKenneth D. Merry }
505*ef270ab1SKenneth D. Merry ocs_ddump_endsection(textbuf, "io_free", ocs->instance_index);
506*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "ios_free", "%d", cnt);
507*ef270ab1SKenneth D. Merry
508*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "sec_hio_wait_count", "%d", hw->sec_hio_wait_count);
509*ef270ab1SKenneth D. Merry ocs_unlock(&hw->io_lock);
510*ef270ab1SKenneth D. Merry
511*ef270ab1SKenneth D. Merry /* now check the IOs not in a list; i.e. sequence coalescing xris */
512*ef270ab1SKenneth D. Merry ocs_ddump_section(textbuf, "port_owned_ios", ocs->instance_index);
513*ef270ab1SKenneth D. Merry for (i = 0; i < hw->config.n_io; i++) {
514*ef270ab1SKenneth D. Merry io = hw->io[i];
515*ef270ab1SKenneth D. Merry if (!io)
516*ef270ab1SKenneth D. Merry continue;
517*ef270ab1SKenneth D. Merry
518*ef270ab1SKenneth D. Merry if (ocs_hw_is_xri_port_owned(hw, io->indicator)) {
519*ef270ab1SKenneth D. Merry if (ocs_ref_read_count(&io->ref)) {
520*ef270ab1SKenneth D. Merry /* only display free ios if they're active */
521*ef270ab1SKenneth D. Merry ocs_ddump_hw_io(textbuf, io);
522*ef270ab1SKenneth D. Merry }
523*ef270ab1SKenneth D. Merry }
524*ef270ab1SKenneth D. Merry }
525*ef270ab1SKenneth D. Merry ocs_ddump_endsection(textbuf, "port_owned_ios", ocs->instance_index);
526*ef270ab1SKenneth D. Merry
527*ef270ab1SKenneth D. Merry ocs_textbuf_printf(textbuf, "<rpi_ref>");
528*ef270ab1SKenneth D. Merry for (i = 0; i < max_rpi; i++) {
529*ef270ab1SKenneth D. Merry if (ocs_atomic_read(&hw->rpi_ref[i].rpi_attached) ||
530*ef270ab1SKenneth D. Merry ocs_atomic_read(&hw->rpi_ref[i].rpi_count) ) {
531*ef270ab1SKenneth D. Merry ocs_textbuf_printf(textbuf, "[%d] att=%d cnt=%d\n", i,
532*ef270ab1SKenneth D. Merry ocs_atomic_read(&hw->rpi_ref[i].rpi_attached),
533*ef270ab1SKenneth D. Merry ocs_atomic_read(&hw->rpi_ref[i].rpi_count));
534*ef270ab1SKenneth D. Merry }
535*ef270ab1SKenneth D. Merry }
536*ef270ab1SKenneth D. Merry ocs_textbuf_printf(textbuf, "</rpi_ref>");
537*ef270ab1SKenneth D. Merry
538*ef270ab1SKenneth D. Merry for (i = 0; i < hw->wq_count; i++) {
539*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "wq_submit", "%d", hw->tcmd_wq_submit[i]);
540*ef270ab1SKenneth D. Merry }
541*ef270ab1SKenneth D. Merry for (i = 0; i < hw->wq_count; i++) {
542*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "wq_complete", "%d", hw->tcmd_wq_complete[i]);
543*ef270ab1SKenneth D. Merry }
544*ef270ab1SKenneth D. Merry
545*ef270ab1SKenneth D. Merry hw_queue_ddump(textbuf, hw);
546*ef270ab1SKenneth D. Merry
547*ef270ab1SKenneth D. Merry ocs_ddump_endsection(textbuf, "hw", ocs->instance_index);
548*ef270ab1SKenneth D. Merry
549*ef270ab1SKenneth D. Merry }
550*ef270ab1SKenneth D. Merry
551*ef270ab1SKenneth D. Merry void
hw_queue_ddump(ocs_textbuf_t * textbuf,ocs_hw_t * hw)552*ef270ab1SKenneth D. Merry hw_queue_ddump(ocs_textbuf_t *textbuf, ocs_hw_t *hw)
553*ef270ab1SKenneth D. Merry {
554*ef270ab1SKenneth D. Merry hw_eq_t *eq;
555*ef270ab1SKenneth D. Merry hw_cq_t *cq;
556*ef270ab1SKenneth D. Merry hw_q_t *q;
557*ef270ab1SKenneth D. Merry hw_mq_t *mq;
558*ef270ab1SKenneth D. Merry hw_wq_t *wq;
559*ef270ab1SKenneth D. Merry hw_rq_t *rq;
560*ef270ab1SKenneth D. Merry
561*ef270ab1SKenneth D. Merry ocs_ddump_section(textbuf, "hw_queue", 0);
562*ef270ab1SKenneth D. Merry ocs_list_foreach(&hw->eq_list, eq) {
563*ef270ab1SKenneth D. Merry ocs_ddump_section(textbuf, "eq", eq->instance);
564*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "queue-id", "%d", eq->queue->id);
565*ef270ab1SKenneth D. Merry OCS_STAT(ocs_ddump_value(textbuf, "use_count", "%d", eq->use_count));
566*ef270ab1SKenneth D. Merry ocs_list_foreach(&eq->cq_list, cq) {
567*ef270ab1SKenneth D. Merry ocs_ddump_section(textbuf, "cq", cq->instance);
568*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "queue-id", "%d", cq->queue->id);
569*ef270ab1SKenneth D. Merry OCS_STAT(ocs_ddump_value(textbuf, "use_count", "%d", cq->use_count));
570*ef270ab1SKenneth D. Merry ocs_list_foreach(&cq->q_list, q) {
571*ef270ab1SKenneth D. Merry switch(q->type) {
572*ef270ab1SKenneth D. Merry case SLI_QTYPE_MQ:
573*ef270ab1SKenneth D. Merry mq = (hw_mq_t *) q;
574*ef270ab1SKenneth D. Merry ocs_ddump_section(textbuf, "mq", mq->instance);
575*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "queue-id", "%d", mq->queue->id);
576*ef270ab1SKenneth D. Merry OCS_STAT(ocs_ddump_value(textbuf, "use_count", "%d", mq->use_count));
577*ef270ab1SKenneth D. Merry ocs_ddump_endsection(textbuf, "mq", mq->instance);
578*ef270ab1SKenneth D. Merry break;
579*ef270ab1SKenneth D. Merry case SLI_QTYPE_WQ:
580*ef270ab1SKenneth D. Merry wq = (hw_wq_t *) q;
581*ef270ab1SKenneth D. Merry ocs_ddump_section(textbuf, "wq", wq->instance);
582*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "queue-id", "%d", wq->queue->id);
583*ef270ab1SKenneth D. Merry OCS_STAT(ocs_ddump_value(textbuf, "use_count", "%d", wq->use_count));
584*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "wqec_count", "%d", wq->wqec_count);
585*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "free_count", "%d", wq->free_count);
586*ef270ab1SKenneth D. Merry OCS_STAT(ocs_ddump_value(textbuf, "wq_pending_count", "%d",
587*ef270ab1SKenneth D. Merry wq->wq_pending_count));
588*ef270ab1SKenneth D. Merry ocs_ddump_endsection(textbuf, "wq", wq->instance);
589*ef270ab1SKenneth D. Merry break;
590*ef270ab1SKenneth D. Merry case SLI_QTYPE_RQ:
591*ef270ab1SKenneth D. Merry rq = (hw_rq_t *) q;
592*ef270ab1SKenneth D. Merry ocs_ddump_section(textbuf, "rq", rq->instance);
593*ef270ab1SKenneth D. Merry OCS_STAT(ocs_ddump_value(textbuf, "use_count", "%d", rq->use_count));
594*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "filter_mask", "%d", rq->filter_mask);
595*ef270ab1SKenneth D. Merry if (rq->hdr != NULL) {
596*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "hdr-id", "%d", rq->hdr->id);
597*ef270ab1SKenneth D. Merry OCS_STAT(ocs_ddump_value(textbuf, "hdr_use_count", "%d", rq->hdr_use_count));
598*ef270ab1SKenneth D. Merry }
599*ef270ab1SKenneth D. Merry if (rq->first_burst != NULL) {
600*ef270ab1SKenneth D. Merry OCS_STAT(ocs_ddump_value(textbuf, "fb-id", "%d", rq->first_burst->id));
601*ef270ab1SKenneth D. Merry OCS_STAT(ocs_ddump_value(textbuf, "fb_use_count", "%d", rq->fb_use_count));
602*ef270ab1SKenneth D. Merry }
603*ef270ab1SKenneth D. Merry if (rq->data != NULL) {
604*ef270ab1SKenneth D. Merry OCS_STAT(ocs_ddump_value(textbuf, "payload-id", "%d", rq->data->id));
605*ef270ab1SKenneth D. Merry OCS_STAT(ocs_ddump_value(textbuf, "payload_use_count", "%d", rq->payload_use_count));
606*ef270ab1SKenneth D. Merry }
607*ef270ab1SKenneth D. Merry ocs_ddump_endsection(textbuf, "rq", rq->instance);
608*ef270ab1SKenneth D. Merry break;
609*ef270ab1SKenneth D. Merry default:
610*ef270ab1SKenneth D. Merry break;
611*ef270ab1SKenneth D. Merry }
612*ef270ab1SKenneth D. Merry }
613*ef270ab1SKenneth D. Merry ocs_ddump_endsection(textbuf, "cq", cq->instance);
614*ef270ab1SKenneth D. Merry }
615*ef270ab1SKenneth D. Merry ocs_ddump_endsection(textbuf, "eq", eq->instance);
616*ef270ab1SKenneth D. Merry }
617*ef270ab1SKenneth D. Merry ocs_ddump_endsection(textbuf, "hw_queue", 0);
618*ef270ab1SKenneth D. Merry }
619*ef270ab1SKenneth D. Merry
620*ef270ab1SKenneth D. Merry /**
621*ef270ab1SKenneth D. Merry * @brief Initiate ddump
622*ef270ab1SKenneth D. Merry *
623*ef270ab1SKenneth D. Merry * Traverses the ocs/domain/port/node/io data structures to generate a driver
624*ef270ab1SKenneth D. Merry * dump.
625*ef270ab1SKenneth D. Merry *
626*ef270ab1SKenneth D. Merry * @param ocs pointer to device context
627*ef270ab1SKenneth D. Merry * @param textbuf pointer to text buffer
628*ef270ab1SKenneth D. Merry * @param flags ddump flags
629*ef270ab1SKenneth D. Merry * @param qentries number of queue entries to dump
630*ef270ab1SKenneth D. Merry *
631*ef270ab1SKenneth D. Merry * @return Returns 0 on success, or a negative value on failure.
632*ef270ab1SKenneth D. Merry */
633*ef270ab1SKenneth D. Merry
634*ef270ab1SKenneth D. Merry int
ocs_ddump(ocs_t * ocs,ocs_textbuf_t * textbuf,uint32_t flags,uint32_t qentries)635*ef270ab1SKenneth D. Merry ocs_ddump(ocs_t *ocs, ocs_textbuf_t *textbuf, uint32_t flags, uint32_t qentries)
636*ef270ab1SKenneth D. Merry {
637*ef270ab1SKenneth D. Merry ocs_xport_t *xport = ocs->xport;
638*ef270ab1SKenneth D. Merry ocs_domain_t *domain;
639*ef270ab1SKenneth D. Merry uint32_t instance;
640*ef270ab1SKenneth D. Merry ocs_vport_spec_t *vport;
641*ef270ab1SKenneth D. Merry ocs_io_t *io;
642*ef270ab1SKenneth D. Merry int retval = 0;
643*ef270ab1SKenneth D. Merry uint32_t i;
644*ef270ab1SKenneth D. Merry
645*ef270ab1SKenneth D. Merry ocs_ddump_startfile(textbuf);
646*ef270ab1SKenneth D. Merry
647*ef270ab1SKenneth D. Merry ocs_ddump_section(textbuf, "ocs", ocs->instance_index);
648*ef270ab1SKenneth D. Merry
649*ef270ab1SKenneth D. Merry ocs_ddump_section(textbuf, "ocs_os", ocs->instance_index);
650*ef270ab1SKenneth D. Merry #ifdef OCS_ENABLE_NUMA_SUPPORT
651*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "numa_node", "%d", ocs->ocs_os.numa_node);
652*ef270ab1SKenneth D. Merry #endif
653*ef270ab1SKenneth D. Merry ocs_ddump_endsection(textbuf, "ocs_os", ocs->instance_index);
654*ef270ab1SKenneth D. Merry
655*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "drv_name", "%s", DRV_NAME);
656*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "drv_version", "%s", DRV_VERSION);
657*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "display_name", "%s", ocs->display_name);
658*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "enable_ini", "%d", ocs->enable_ini);
659*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "enable_tgt", "%d", ocs->enable_tgt);
660*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "nodes_count", "%d", xport->nodes_count);
661*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "enable_hlm", "%d", ocs->enable_hlm);
662*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "hlm_group_size", "%d", ocs->hlm_group_size);
663*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "auto_xfer_rdy_size", "%d", ocs->auto_xfer_rdy_size);
664*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "io_alloc_failed_count", "%d", ocs_atomic_read(&xport->io_alloc_failed_count));
665*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "io_active_count", "%d", ocs_atomic_read(&xport->io_active_count));
666*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "io_pending_count", "%d", ocs_atomic_read(&xport->io_pending_count));
667*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "io_total_alloc", "%d", ocs_atomic_read(&xport->io_total_alloc));
668*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "io_total_free", "%d", ocs_atomic_read(&xport->io_total_free));
669*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "io_total_pending", "%d", ocs_atomic_read(&xport->io_total_pending));
670*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "io_pending_recursing", "%d", ocs_atomic_read(&xport->io_pending_recursing));
671*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "max_isr_time_msec", "%d", ocs->max_isr_time_msec);
672*ef270ab1SKenneth D. Merry for (i = 0; i < SLI4_MAX_FCFI; i++) {
673*ef270ab1SKenneth D. Merry ocs_lock(&xport->fcfi[i].pend_frames_lock);
674*ef270ab1SKenneth D. Merry if (!ocs_list_empty(&xport->fcfi[i].pend_frames)) {
675*ef270ab1SKenneth D. Merry ocs_hw_sequence_t *frame;
676*ef270ab1SKenneth D. Merry ocs_ddump_section(textbuf, "pending_frames", i);
677*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "hold_frames", "%d", xport->fcfi[i].hold_frames);
678*ef270ab1SKenneth D. Merry ocs_list_foreach(&xport->fcfi[i].pend_frames, frame) {
679*ef270ab1SKenneth D. Merry fc_header_t *hdr;
680*ef270ab1SKenneth D. Merry char buf[128];
681*ef270ab1SKenneth D. Merry
682*ef270ab1SKenneth D. Merry hdr = frame->header->dma.virt;
683*ef270ab1SKenneth D. Merry ocs_snprintf(buf, sizeof(buf), "%02x/%04x/%04x len %zu",
684*ef270ab1SKenneth D. Merry hdr->r_ctl, ocs_be16toh(hdr->ox_id), ocs_be16toh(hdr->rx_id),
685*ef270ab1SKenneth D. Merry frame->payload->dma.len);
686*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "frame", "%s", buf);
687*ef270ab1SKenneth D. Merry }
688*ef270ab1SKenneth D. Merry ocs_ddump_endsection(textbuf, "pending_frames", i);
689*ef270ab1SKenneth D. Merry }
690*ef270ab1SKenneth D. Merry ocs_unlock(&xport->fcfi[i].pend_frames_lock);
691*ef270ab1SKenneth D. Merry }
692*ef270ab1SKenneth D. Merry
693*ef270ab1SKenneth D. Merry ocs_lock(&xport->io_pending_lock);
694*ef270ab1SKenneth D. Merry ocs_ddump_section(textbuf, "io_pending_list", ocs->instance_index);
695*ef270ab1SKenneth D. Merry ocs_list_foreach(&xport->io_pending_list, io) {
696*ef270ab1SKenneth D. Merry ocs_ddump_io(textbuf, io);
697*ef270ab1SKenneth D. Merry }
698*ef270ab1SKenneth D. Merry ocs_ddump_endsection(textbuf, "io_pending_list", ocs->instance_index);
699*ef270ab1SKenneth D. Merry ocs_unlock(&xport->io_pending_lock);
700*ef270ab1SKenneth D. Merry
701*ef270ab1SKenneth D. Merry #if defined(ENABLE_LOCK_DEBUG)
702*ef270ab1SKenneth D. Merry /* Dump the lock list */
703*ef270ab1SKenneth D. Merry ocs_ddump_section(textbuf, "locks", 0);
704*ef270ab1SKenneth D. Merry ocs_lock(&ocs->ocs_os.locklist_lock); {
705*ef270ab1SKenneth D. Merry ocs_lock_t *l;
706*ef270ab1SKenneth D. Merry uint32_t idx = 0;
707*ef270ab1SKenneth D. Merry ocs_list_foreach(&ocs->ocs_os.locklist, l) {
708*ef270ab1SKenneth D. Merry ocs_ddump_section(textbuf, "lock", idx);
709*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "name", "%s", l->name);
710*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "inuse", "%d", l->inuse);
711*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "caller", "%p", l->caller[0]);
712*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "pid", "%08x", l->pid.l);
713*ef270ab1SKenneth D. Merry ocs_ddump_endsection(textbuf, "lock", idx);
714*ef270ab1SKenneth D. Merry idx++;
715*ef270ab1SKenneth D. Merry }
716*ef270ab1SKenneth D. Merry } ocs_unlock(&ocs->ocs_os.locklist_lock);
717*ef270ab1SKenneth D. Merry ocs_ddump_endsection(textbuf, "locks", 0);
718*ef270ab1SKenneth D. Merry #endif
719*ef270ab1SKenneth D. Merry
720*ef270ab1SKenneth D. Merry /* Dump any pending vports */
721*ef270ab1SKenneth D. Merry if (ocs_device_lock_try(ocs) != TRUE) {
722*ef270ab1SKenneth D. Merry /* Didn't get the lock */
723*ef270ab1SKenneth D. Merry return -1;
724*ef270ab1SKenneth D. Merry }
725*ef270ab1SKenneth D. Merry instance = 0;
726*ef270ab1SKenneth D. Merry ocs_list_foreach(&xport->vport_list, vport) {
727*ef270ab1SKenneth D. Merry ocs_ddump_section(textbuf, "vport_spec", instance);
728*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "domain_instance", "%d", vport->domain_instance);
729*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "wwnn", "%llx", (unsigned long long)vport->wwnn);
730*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "wwpn", "%llx", (unsigned long long)vport->wwpn);
731*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "fc_id", "0x%x", vport->fc_id);
732*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "enable_tgt", "%d", vport->enable_tgt);
733*ef270ab1SKenneth D. Merry ocs_ddump_value(textbuf, "enable_ini", "%d" PRIx64, vport->enable_ini);
734*ef270ab1SKenneth D. Merry ocs_ddump_endsection(textbuf, "vport_spec", instance ++);
735*ef270ab1SKenneth D. Merry }
736*ef270ab1SKenneth D. Merry ocs_device_unlock(ocs);
737*ef270ab1SKenneth D. Merry
738*ef270ab1SKenneth D. Merry /* Dump target and initiator private data */
739*ef270ab1SKenneth D. Merry ocs_scsi_ini_ddump(textbuf, OCS_SCSI_DDUMP_DEVICE, ocs);
740*ef270ab1SKenneth D. Merry ocs_scsi_tgt_ddump(textbuf, OCS_SCSI_DDUMP_DEVICE, ocs);
741*ef270ab1SKenneth D. Merry
742*ef270ab1SKenneth D. Merry ocs_ddump_hw(textbuf, &ocs->hw, flags, qentries);
743*ef270ab1SKenneth D. Merry
744*ef270ab1SKenneth D. Merry if (ocs_device_lock_try(ocs) != TRUE) {
745*ef270ab1SKenneth D. Merry /* Didn't get the lock */
746*ef270ab1SKenneth D. Merry return -1;
747*ef270ab1SKenneth D. Merry }
748*ef270ab1SKenneth D. Merry /* Here the device lock is held */
749*ef270ab1SKenneth D. Merry ocs_list_foreach(&ocs->domain_list, domain) {
750*ef270ab1SKenneth D. Merry retval = ocs_ddump_domain(textbuf, domain);
751*ef270ab1SKenneth D. Merry if (retval != 0) {
752*ef270ab1SKenneth D. Merry break;
753*ef270ab1SKenneth D. Merry }
754*ef270ab1SKenneth D. Merry }
755*ef270ab1SKenneth D. Merry
756*ef270ab1SKenneth D. Merry /* Dump ramlog */
757*ef270ab1SKenneth D. Merry ocs_ddump_ramlog(textbuf, ocs->ramlog);
758*ef270ab1SKenneth D. Merry ocs_device_unlock(ocs);
759*ef270ab1SKenneth D. Merry
760*ef270ab1SKenneth D. Merry #if !defined(OCS_DEBUG_QUEUE_HISTORY)
761*ef270ab1SKenneth D. Merry ocs_ddump_section(textbuf, "q_hist", ocs->instance_index);
762*ef270ab1SKenneth D. Merry ocs_textbuf_printf(textbuf, "<history>\n");
763*ef270ab1SKenneth D. Merry ocs_textbuf_printf(textbuf, "No history available\n");
764*ef270ab1SKenneth D. Merry ocs_textbuf_printf(textbuf, "</history>\n");
765*ef270ab1SKenneth D. Merry ocs_ddump_endsection(textbuf, "q_hist", ocs->instance_index);
766*ef270ab1SKenneth D. Merry #else
767*ef270ab1SKenneth D. Merry ocs_ddump_queue_history(textbuf, &ocs->hw.q_hist);
768*ef270ab1SKenneth D. Merry #endif
769*ef270ab1SKenneth D. Merry
770*ef270ab1SKenneth D. Merry #if defined(OCS_DEBUG_MEMORY)
771*ef270ab1SKenneth D. Merry ocs_memory_allocated_ddump(textbuf);
772*ef270ab1SKenneth D. Merry #endif
773*ef270ab1SKenneth D. Merry
774*ef270ab1SKenneth D. Merry ocs_ddump_endsection(textbuf, "ocs", ocs->instance_index);
775*ef270ab1SKenneth D. Merry
776*ef270ab1SKenneth D. Merry ocs_ddump_endfile(textbuf);
777*ef270ab1SKenneth D. Merry
778*ef270ab1SKenneth D. Merry return retval;
779*ef270ab1SKenneth D. Merry }
780*ef270ab1SKenneth D. Merry
781*ef270ab1SKenneth D. Merry /**
782*ef270ab1SKenneth D. Merry * @brief Capture and save ddump
783*ef270ab1SKenneth D. Merry *
784*ef270ab1SKenneth D. Merry * Captures and saves a ddump to the ocs_t structure to save the
785*ef270ab1SKenneth D. Merry * current state. The goal of this function is to save a ddump
786*ef270ab1SKenneth D. Merry * as soon as an issue is encountered. The saved ddump will be
787*ef270ab1SKenneth D. Merry * kept until the user reads it.
788*ef270ab1SKenneth D. Merry *
789*ef270ab1SKenneth D. Merry * @param ocs pointer to device context
790*ef270ab1SKenneth D. Merry * @param flags ddump flags
791*ef270ab1SKenneth D. Merry * @param qentries number of queue entries to dump
792*ef270ab1SKenneth D. Merry *
793*ef270ab1SKenneth D. Merry * @return 0 if ddump was saved; > 0 of one already exists; < 0
794*ef270ab1SKenneth D. Merry * error
795*ef270ab1SKenneth D. Merry */
796*ef270ab1SKenneth D. Merry
797*ef270ab1SKenneth D. Merry int32_t
ocs_save_ddump(ocs_t * ocs,uint32_t flags,uint32_t qentries)798*ef270ab1SKenneth D. Merry ocs_save_ddump(ocs_t *ocs, uint32_t flags, uint32_t qentries)
799*ef270ab1SKenneth D. Merry {
800*ef270ab1SKenneth D. Merry if (ocs_textbuf_get_written(&ocs->ddump_saved) > 0) {
801*ef270ab1SKenneth D. Merry ocs_log_debug(ocs, "Saved ddump already exists\n");
802*ef270ab1SKenneth D. Merry return 1;
803*ef270ab1SKenneth D. Merry }
804*ef270ab1SKenneth D. Merry
805*ef270ab1SKenneth D. Merry if (!ocs_textbuf_initialized(&ocs->ddump_saved)) {
806*ef270ab1SKenneth D. Merry ocs_log_err(ocs, "Saved ddump not allocated\n");
807*ef270ab1SKenneth D. Merry return -1;
808*ef270ab1SKenneth D. Merry }
809*ef270ab1SKenneth D. Merry
810*ef270ab1SKenneth D. Merry ocs_log_debug(ocs, "Saving ddump\n");
811*ef270ab1SKenneth D. Merry ocs_ddump(ocs, &ocs->ddump_saved, flags, qentries);
812*ef270ab1SKenneth D. Merry ocs_log_debug(ocs, "Saved ddump: %d bytes written\n", ocs_textbuf_get_written(&ocs->ddump_saved));
813*ef270ab1SKenneth D. Merry return 0;
814*ef270ab1SKenneth D. Merry }
815*ef270ab1SKenneth D. Merry
816*ef270ab1SKenneth D. Merry /**
817*ef270ab1SKenneth D. Merry * @brief Capture and save ddump for all OCS instances
818*ef270ab1SKenneth D. Merry *
819*ef270ab1SKenneth D. Merry * Calls ocs_save_ddump() for each OCS instance.
820*ef270ab1SKenneth D. Merry *
821*ef270ab1SKenneth D. Merry * @param flags ddump flags
822*ef270ab1SKenneth D. Merry * @param qentries number of queue entries to dump
823*ef270ab1SKenneth D. Merry * @param alloc_flag allocate dump buffer if not already allocated
824*ef270ab1SKenneth D. Merry *
825*ef270ab1SKenneth D. Merry * @return 0 if ddump was saved; > 0 of one already exists; < 0
826*ef270ab1SKenneth D. Merry * error
827*ef270ab1SKenneth D. Merry */
828*ef270ab1SKenneth D. Merry
829*ef270ab1SKenneth D. Merry int32_t
ocs_save_ddump_all(uint32_t flags,uint32_t qentries,uint32_t alloc_flag)830*ef270ab1SKenneth D. Merry ocs_save_ddump_all(uint32_t flags, uint32_t qentries, uint32_t alloc_flag)
831*ef270ab1SKenneth D. Merry {
832*ef270ab1SKenneth D. Merry ocs_t *ocs;
833*ef270ab1SKenneth D. Merry uint32_t i;
834*ef270ab1SKenneth D. Merry int32_t rc = 0;
835*ef270ab1SKenneth D. Merry
836*ef270ab1SKenneth D. Merry for (i = 0; (ocs = ocs_get_instance(i)) != NULL; i++) {
837*ef270ab1SKenneth D. Merry if (alloc_flag && (!ocs_textbuf_initialized(&ocs->ddump_saved))) {
838*ef270ab1SKenneth D. Merry rc = ocs_textbuf_alloc(ocs, &ocs->ddump_saved, DEFAULT_SAVED_DUMP_SIZE);
839*ef270ab1SKenneth D. Merry if (rc) {
840*ef270ab1SKenneth D. Merry break;
841*ef270ab1SKenneth D. Merry }
842*ef270ab1SKenneth D. Merry }
843*ef270ab1SKenneth D. Merry
844*ef270ab1SKenneth D. Merry rc = ocs_save_ddump(ocs, flags, qentries);
845*ef270ab1SKenneth D. Merry if (rc < 0) {
846*ef270ab1SKenneth D. Merry break;
847*ef270ab1SKenneth D. Merry }
848*ef270ab1SKenneth D. Merry }
849*ef270ab1SKenneth D. Merry return rc;
850*ef270ab1SKenneth D. Merry }
851*ef270ab1SKenneth D. Merry
852*ef270ab1SKenneth D. Merry /**
853*ef270ab1SKenneth D. Merry * @brief Clear saved ddump
854*ef270ab1SKenneth D. Merry *
855*ef270ab1SKenneth D. Merry * Clears saved ddump to make room for next one.
856*ef270ab1SKenneth D. Merry *
857*ef270ab1SKenneth D. Merry * @param ocs pointer to device context
858*ef270ab1SKenneth D. Merry *
859*ef270ab1SKenneth D. Merry * @return 0 if ddump was cleared; > 0 no saved ddump found
860*ef270ab1SKenneth D. Merry */
861*ef270ab1SKenneth D. Merry
862*ef270ab1SKenneth D. Merry int32_t
ocs_clear_saved_ddump(ocs_t * ocs)863*ef270ab1SKenneth D. Merry ocs_clear_saved_ddump(ocs_t *ocs)
864*ef270ab1SKenneth D. Merry {
865*ef270ab1SKenneth D. Merry /* if there's a saved ddump, copy to newly allocated textbuf */
866*ef270ab1SKenneth D. Merry if (ocs_textbuf_get_written(&ocs->ddump_saved)) {
867*ef270ab1SKenneth D. Merry ocs_log_debug(ocs, "saved ddump cleared\n");
868*ef270ab1SKenneth D. Merry ocs_textbuf_reset(&ocs->ddump_saved);
869*ef270ab1SKenneth D. Merry return 0;
870*ef270ab1SKenneth D. Merry } else {
871*ef270ab1SKenneth D. Merry ocs_log_debug(ocs, "no saved ddump found\n");
872*ef270ab1SKenneth D. Merry return 1;
873*ef270ab1SKenneth D. Merry }
874*ef270ab1SKenneth D. Merry }
875