forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-31 f70575805708cabdedea7498aaa3f710fde4d920
kernel/drivers/scsi/qla2xxx/qla_tmpl.c
....@@ -1,109 +1,15 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * QLogic Fibre Channel HBA Driver
34 * Copyright (c) 2003-2014 QLogic Corporation
4
- *
5
- * See LICENSE.qla2xxx for copyright and licensing details.
65 */
76 #include "qla_def.h"
87 #include "qla_tmpl.h"
98
10
-/* note default template is in big endian */
11
-static const uint32_t ql27xx_fwdt_default_template[] = {
12
- 0x63000000, 0xa4000000, 0x7c050000, 0x00000000,
13
- 0x30000000, 0x01000000, 0x00000000, 0xc0406eb4,
14
- 0x00000000, 0x00000000, 0x00000000, 0x00000000,
15
- 0x00000000, 0x00000000, 0x00000000, 0x00000000,
16
- 0x00000000, 0x00000000, 0x00000000, 0x00000000,
17
- 0x00000000, 0x00000000, 0x00000000, 0x00000000,
18
- 0x00000000, 0x00000000, 0x00000000, 0x00000000,
19
- 0x00000000, 0x00000000, 0x00000000, 0x00000000,
20
- 0x00000000, 0x00000000, 0x00000000, 0x00000000,
21
- 0x00000000, 0x00000000, 0x00000000, 0x00000000,
22
- 0x00000000, 0x04010000, 0x14000000, 0x00000000,
23
- 0x02000000, 0x44000000, 0x09010000, 0x10000000,
24
- 0x00000000, 0x02000000, 0x01010000, 0x1c000000,
25
- 0x00000000, 0x02000000, 0x00600000, 0x00000000,
26
- 0xc0000000, 0x01010000, 0x1c000000, 0x00000000,
27
- 0x02000000, 0x00600000, 0x00000000, 0xcc000000,
28
- 0x01010000, 0x1c000000, 0x00000000, 0x02000000,
29
- 0x10600000, 0x00000000, 0xd4000000, 0x01010000,
30
- 0x1c000000, 0x00000000, 0x02000000, 0x700f0000,
31
- 0x00000060, 0xf0000000, 0x00010000, 0x18000000,
32
- 0x00000000, 0x02000000, 0x00700000, 0x041000c0,
33
- 0x00010000, 0x18000000, 0x00000000, 0x02000000,
34
- 0x10700000, 0x041000c0, 0x00010000, 0x18000000,
35
- 0x00000000, 0x02000000, 0x40700000, 0x041000c0,
36
- 0x01010000, 0x1c000000, 0x00000000, 0x02000000,
37
- 0x007c0000, 0x01000000, 0xc0000000, 0x00010000,
38
- 0x18000000, 0x00000000, 0x02000000, 0x007c0000,
39
- 0x040300c4, 0x00010000, 0x18000000, 0x00000000,
40
- 0x02000000, 0x007c0000, 0x040100c0, 0x01010000,
41
- 0x1c000000, 0x00000000, 0x02000000, 0x007c0000,
42
- 0x00000000, 0xc0000000, 0x00010000, 0x18000000,
43
- 0x00000000, 0x02000000, 0x007c0000, 0x04200000,
44
- 0x0b010000, 0x18000000, 0x00000000, 0x02000000,
45
- 0x0c000000, 0x00000000, 0x02010000, 0x20000000,
46
- 0x00000000, 0x02000000, 0x700f0000, 0x040100fc,
47
- 0xf0000000, 0x000000b0, 0x02010000, 0x20000000,
48
- 0x00000000, 0x02000000, 0x700f0000, 0x040100fc,
49
- 0xf0000000, 0x000010b0, 0x02010000, 0x20000000,
50
- 0x00000000, 0x02000000, 0x700f0000, 0x040100fc,
51
- 0xf0000000, 0x000020b0, 0x02010000, 0x20000000,
52
- 0x00000000, 0x02000000, 0x700f0000, 0x040100fc,
53
- 0xf0000000, 0x000030b0, 0x02010000, 0x20000000,
54
- 0x00000000, 0x02000000, 0x700f0000, 0x040100fc,
55
- 0xf0000000, 0x000040b0, 0x02010000, 0x20000000,
56
- 0x00000000, 0x02000000, 0x700f0000, 0x040100fc,
57
- 0xf0000000, 0x000050b0, 0x02010000, 0x20000000,
58
- 0x00000000, 0x02000000, 0x700f0000, 0x040100fc,
59
- 0xf0000000, 0x000060b0, 0x02010000, 0x20000000,
60
- 0x00000000, 0x02000000, 0x700f0000, 0x040100fc,
61
- 0xf0000000, 0x000070b0, 0x02010000, 0x20000000,
62
- 0x00000000, 0x02000000, 0x700f0000, 0x040100fc,
63
- 0xf0000000, 0x000080b0, 0x02010000, 0x20000000,
64
- 0x00000000, 0x02000000, 0x700f0000, 0x040100fc,
65
- 0xf0000000, 0x000090b0, 0x02010000, 0x20000000,
66
- 0x00000000, 0x02000000, 0x700f0000, 0x040100fc,
67
- 0xf0000000, 0x0000a0b0, 0x00010000, 0x18000000,
68
- 0x00000000, 0x02000000, 0x0a000000, 0x040100c0,
69
- 0x00010000, 0x18000000, 0x00000000, 0x02000000,
70
- 0x0a000000, 0x04200080, 0x00010000, 0x18000000,
71
- 0x00000000, 0x02000000, 0x00be0000, 0x041000c0,
72
- 0x00010000, 0x18000000, 0x00000000, 0x02000000,
73
- 0x10be0000, 0x041000c0, 0x00010000, 0x18000000,
74
- 0x00000000, 0x02000000, 0x20be0000, 0x041000c0,
75
- 0x00010000, 0x18000000, 0x00000000, 0x02000000,
76
- 0x30be0000, 0x041000c0, 0x00010000, 0x18000000,
77
- 0x00000000, 0x02000000, 0x00b00000, 0x041000c0,
78
- 0x00010000, 0x18000000, 0x00000000, 0x02000000,
79
- 0x10b00000, 0x041000c0, 0x00010000, 0x18000000,
80
- 0x00000000, 0x02000000, 0x20b00000, 0x041000c0,
81
- 0x00010000, 0x18000000, 0x00000000, 0x02000000,
82
- 0x30b00000, 0x041000c0, 0x00010000, 0x18000000,
83
- 0x00000000, 0x02000000, 0x00300000, 0x041000c0,
84
- 0x00010000, 0x18000000, 0x00000000, 0x02000000,
85
- 0x10300000, 0x041000c0, 0x00010000, 0x18000000,
86
- 0x00000000, 0x02000000, 0x20300000, 0x041000c0,
87
- 0x00010000, 0x18000000, 0x00000000, 0x02000000,
88
- 0x30300000, 0x041000c0, 0x0a010000, 0x10000000,
89
- 0x00000000, 0x02000000, 0x06010000, 0x1c000000,
90
- 0x00000000, 0x02000000, 0x01000000, 0x00000200,
91
- 0xff230200, 0x06010000, 0x1c000000, 0x00000000,
92
- 0x02000000, 0x02000000, 0x00001000, 0x00000000,
93
- 0x07010000, 0x18000000, 0x00000000, 0x02000000,
94
- 0x00000000, 0x01000000, 0x07010000, 0x18000000,
95
- 0x00000000, 0x02000000, 0x00000000, 0x02000000,
96
- 0x07010000, 0x18000000, 0x00000000, 0x02000000,
97
- 0x00000000, 0x03000000, 0x0d010000, 0x14000000,
98
- 0x00000000, 0x02000000, 0x00000000, 0xff000000,
99
- 0x10000000, 0x00000000, 0x00000080,
100
-};
101
-
102
-static inline void __iomem *
103
-qla27xx_isp_reg(struct scsi_qla_host *vha)
104
-{
105
- return &vha->hw->iobase->isp24;
106
-}
9
+#define ISPREG(vha) (&(vha)->hw->iobase->isp24)
10
+#define IOBAR(reg) offsetof(typeof(*(reg)), iobase_addr)
11
+#define IOBASE(vha) IOBAR(ISPREG(vha))
12
+#define INVALID_ENTRY ((struct qla27xx_fwdt_entry *)0xffffffffffffffffUL)
10713
10814 static inline void
10915 qla27xx_insert16(uint16_t value, void *buf, ulong *len)
....@@ -128,7 +34,6 @@
12834 static inline void
12935 qla27xx_insertbuf(void *mem, ulong size, void *buf, ulong *len)
13036 {
131
-
13237 if (buf && mem && size) {
13338 buf += *len;
13439 memcpy(buf, mem, size);
....@@ -142,7 +47,7 @@
14247 uint8_t value = ~0;
14348
14449 if (buf) {
145
- value = RD_REG_BYTE(window);
50
+ value = rd_reg_byte(window);
14651 }
14752 qla27xx_insert32(value, buf, len);
14853 }
....@@ -153,7 +58,7 @@
15358 uint16_t value = ~0;
15459
15560 if (buf) {
156
- value = RD_REG_WORD(window);
61
+ value = rd_reg_word(window);
15762 }
15863 qla27xx_insert32(value, buf, len);
15964 }
....@@ -164,7 +69,7 @@
16469 uint32_t value = ~0;
16570
16671 if (buf) {
167
- value = RD_REG_DWORD(window);
72
+ value = rd_reg_dword(window);
16873 }
16974 qla27xx_insert32(value, buf, len);
17075 }
....@@ -190,10 +95,10 @@
19095 qla27xx_write_reg(__iomem struct device_reg_24xx *reg,
19196 uint offset, uint32_t data, void *buf)
19297 {
193
- __iomem void *window = (void __iomem *)reg + offset;
194
-
19598 if (buf) {
196
- WRT_REG_DWORD(window, data);
99
+ void __iomem *window = (void __iomem *)reg + offset;
100
+
101
+ wrt_reg_dword(window, data);
197102 }
198103 }
199104
....@@ -205,7 +110,7 @@
205110 void __iomem *window = (void __iomem *)reg + offset;
206111 void (*readn)(void __iomem*, void *, ulong *) = qla27xx_read_vector(width);
207112
208
- qla27xx_write_reg(reg, IOBASE_ADDR, addr, buf);
113
+ qla27xx_write_reg(reg, IOBAR(reg), addr, buf);
209114 while (count--) {
210115 qla27xx_insert32(addr, buf, len);
211116 readn(window, buf, len);
....@@ -221,7 +126,13 @@
221126 ent->hdr.driver_flags |= DRIVER_FLAG_SKIP_ENTRY;
222127 }
223128
224
-static int
129
+static inline struct qla27xx_fwdt_entry *
130
+qla27xx_next_entry(struct qla27xx_fwdt_entry *ent)
131
+{
132
+ return (void *)ent + le32_to_cpu(ent->hdr.size);
133
+}
134
+
135
+static struct qla27xx_fwdt_entry *
225136 qla27xx_fwdt_entry_t0(struct scsi_qla_host *vha,
226137 struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
227138 {
....@@ -229,10 +140,10 @@
229140 "%s: nop [%lx]\n", __func__, *len);
230141 qla27xx_skip_entry(ent, buf);
231142
232
- return false;
143
+ return qla27xx_next_entry(ent);
233144 }
234145
235
-static int
146
+static struct qla27xx_fwdt_entry *
236147 qla27xx_fwdt_entry_t255(struct scsi_qla_host *vha,
237148 struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
238149 {
....@@ -241,138 +152,156 @@
241152 qla27xx_skip_entry(ent, buf);
242153
243154 /* terminate */
244
- return true;
155
+ return NULL;
245156 }
246157
247
-static int
158
+static struct qla27xx_fwdt_entry *
248159 qla27xx_fwdt_entry_t256(struct scsi_qla_host *vha,
249160 struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
250161 {
251
- struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha);
162
+ ulong addr = le32_to_cpu(ent->t256.base_addr);
163
+ uint offset = ent->t256.pci_offset;
164
+ ulong count = le16_to_cpu(ent->t256.reg_count);
165
+ uint width = ent->t256.reg_width;
252166
253167 ql_dbg(ql_dbg_misc, vha, 0xd200,
254168 "%s: rdio t1 [%lx]\n", __func__, *len);
255
- qla27xx_read_window(reg, ent->t256.base_addr, ent->t256.pci_offset,
256
- ent->t256.reg_count, ent->t256.reg_width, buf, len);
169
+ qla27xx_read_window(ISPREG(vha), addr, offset, count, width, buf, len);
257170
258
- return false;
171
+ return qla27xx_next_entry(ent);
259172 }
260173
261
-static int
174
+static struct qla27xx_fwdt_entry *
262175 qla27xx_fwdt_entry_t257(struct scsi_qla_host *vha,
263176 struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
264177 {
265
- struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha);
178
+ ulong addr = le32_to_cpu(ent->t257.base_addr);
179
+ uint offset = ent->t257.pci_offset;
180
+ ulong data = le32_to_cpu(ent->t257.write_data);
266181
267182 ql_dbg(ql_dbg_misc, vha, 0xd201,
268183 "%s: wrio t1 [%lx]\n", __func__, *len);
269
- qla27xx_write_reg(reg, IOBASE_ADDR, ent->t257.base_addr, buf);
270
- qla27xx_write_reg(reg, ent->t257.pci_offset, ent->t257.write_data, buf);
184
+ qla27xx_write_reg(ISPREG(vha), IOBASE(vha), addr, buf);
185
+ qla27xx_write_reg(ISPREG(vha), offset, data, buf);
271186
272
- return false;
187
+ return qla27xx_next_entry(ent);
273188 }
274189
275
-static int
190
+static struct qla27xx_fwdt_entry *
276191 qla27xx_fwdt_entry_t258(struct scsi_qla_host *vha,
277192 struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
278193 {
279
- struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha);
194
+ uint banksel = ent->t258.banksel_offset;
195
+ ulong bank = le32_to_cpu(ent->t258.bank);
196
+ ulong addr = le32_to_cpu(ent->t258.base_addr);
197
+ uint offset = ent->t258.pci_offset;
198
+ uint count = le16_to_cpu(ent->t258.reg_count);
199
+ uint width = ent->t258.reg_width;
280200
281201 ql_dbg(ql_dbg_misc, vha, 0xd202,
282202 "%s: rdio t2 [%lx]\n", __func__, *len);
283
- qla27xx_write_reg(reg, ent->t258.banksel_offset, ent->t258.bank, buf);
284
- qla27xx_read_window(reg, ent->t258.base_addr, ent->t258.pci_offset,
285
- ent->t258.reg_count, ent->t258.reg_width, buf, len);
203
+ qla27xx_write_reg(ISPREG(vha), banksel, bank, buf);
204
+ qla27xx_read_window(ISPREG(vha), addr, offset, count, width, buf, len);
286205
287
- return false;
206
+ return qla27xx_next_entry(ent);
288207 }
289208
290
-static int
209
+static struct qla27xx_fwdt_entry *
291210 qla27xx_fwdt_entry_t259(struct scsi_qla_host *vha,
292211 struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
293212 {
294
- struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha);
213
+ ulong addr = le32_to_cpu(ent->t259.base_addr);
214
+ uint banksel = ent->t259.banksel_offset;
215
+ ulong bank = le32_to_cpu(ent->t259.bank);
216
+ uint offset = ent->t259.pci_offset;
217
+ ulong data = le32_to_cpu(ent->t259.write_data);
295218
296219 ql_dbg(ql_dbg_misc, vha, 0xd203,
297220 "%s: wrio t2 [%lx]\n", __func__, *len);
298
- qla27xx_write_reg(reg, IOBASE_ADDR, ent->t259.base_addr, buf);
299
- qla27xx_write_reg(reg, ent->t259.banksel_offset, ent->t259.bank, buf);
300
- qla27xx_write_reg(reg, ent->t259.pci_offset, ent->t259.write_data, buf);
221
+ qla27xx_write_reg(ISPREG(vha), IOBASE(vha), addr, buf);
222
+ qla27xx_write_reg(ISPREG(vha), banksel, bank, buf);
223
+ qla27xx_write_reg(ISPREG(vha), offset, data, buf);
301224
302
- return false;
225
+ return qla27xx_next_entry(ent);
303226 }
304227
305
-static int
228
+static struct qla27xx_fwdt_entry *
306229 qla27xx_fwdt_entry_t260(struct scsi_qla_host *vha,
307230 struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
308231 {
309
- struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha);
232
+ uint offset = ent->t260.pci_offset;
310233
311234 ql_dbg(ql_dbg_misc, vha, 0xd204,
312235 "%s: rdpci [%lx]\n", __func__, *len);
313
- qla27xx_insert32(ent->t260.pci_offset, buf, len);
314
- qla27xx_read_reg(reg, ent->t260.pci_offset, buf, len);
236
+ qla27xx_insert32(offset, buf, len);
237
+ qla27xx_read_reg(ISPREG(vha), offset, buf, len);
315238
316
- return false;
239
+ return qla27xx_next_entry(ent);
317240 }
318241
319
-static int
242
+static struct qla27xx_fwdt_entry *
320243 qla27xx_fwdt_entry_t261(struct scsi_qla_host *vha,
321244 struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
322245 {
323
- struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha);
246
+ uint offset = ent->t261.pci_offset;
247
+ ulong data = le32_to_cpu(ent->t261.write_data);
324248
325249 ql_dbg(ql_dbg_misc, vha, 0xd205,
326250 "%s: wrpci [%lx]\n", __func__, *len);
327
- qla27xx_write_reg(reg, ent->t261.pci_offset, ent->t261.write_data, buf);
251
+ qla27xx_write_reg(ISPREG(vha), offset, data, buf);
328252
329
- return false;
253
+ return qla27xx_next_entry(ent);
330254 }
331255
332
-static int
256
+static struct qla27xx_fwdt_entry *
333257 qla27xx_fwdt_entry_t262(struct scsi_qla_host *vha,
334258 struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
335259 {
260
+ uint area = ent->t262.ram_area;
261
+ ulong start = le32_to_cpu(ent->t262.start_addr);
262
+ ulong end = le32_to_cpu(ent->t262.end_addr);
336263 ulong dwords;
337
- ulong start;
338
- ulong end;
264
+ int rc;
339265
340266 ql_dbg(ql_dbg_misc, vha, 0xd206,
341267 "%s: rdram(%x) [%lx]\n", __func__, ent->t262.ram_area, *len);
342
- start = ent->t262.start_addr;
343
- end = ent->t262.end_addr;
344268
345
- if (ent->t262.ram_area == T262_RAM_AREA_CRITICAL_RAM) {
269
+ if (area == T262_RAM_AREA_CRITICAL_RAM) {
346270 ;
347
- } else if (ent->t262.ram_area == T262_RAM_AREA_EXTERNAL_RAM) {
271
+ } else if (area == T262_RAM_AREA_EXTERNAL_RAM) {
348272 end = vha->hw->fw_memory_size;
349273 if (buf)
350
- ent->t262.end_addr = end;
351
- } else if (ent->t262.ram_area == T262_RAM_AREA_SHARED_RAM) {
274
+ ent->t262.end_addr = cpu_to_le32(end);
275
+ } else if (area == T262_RAM_AREA_SHARED_RAM) {
352276 start = vha->hw->fw_shared_ram_start;
353277 end = vha->hw->fw_shared_ram_end;
354278 if (buf) {
355
- ent->t262.start_addr = start;
356
- ent->t262.end_addr = end;
279
+ ent->t262.start_addr = cpu_to_le32(start);
280
+ ent->t262.end_addr = cpu_to_le32(end);
357281 }
358
- } else if (ent->t262.ram_area == T262_RAM_AREA_DDR_RAM) {
282
+ } else if (area == T262_RAM_AREA_DDR_RAM) {
359283 start = vha->hw->fw_ddr_ram_start;
360284 end = vha->hw->fw_ddr_ram_end;
361285 if (buf) {
362
- ent->t262.start_addr = start;
363
- ent->t262.end_addr = end;
286
+ ent->t262.start_addr = cpu_to_le32(start);
287
+ ent->t262.end_addr = cpu_to_le32(end);
288
+ }
289
+ } else if (area == T262_RAM_AREA_MISC) {
290
+ if (buf) {
291
+ ent->t262.start_addr = cpu_to_le32(start);
292
+ ent->t262.end_addr = cpu_to_le32(end);
364293 }
365294 } else {
366295 ql_dbg(ql_dbg_misc, vha, 0xd022,
367
- "%s: unknown area %x\n", __func__, ent->t262.ram_area);
296
+ "%s: unknown area %x\n", __func__, area);
368297 qla27xx_skip_entry(ent, buf);
369298 goto done;
370299 }
371300
372301 if (end < start || start == 0 || end == 0) {
373302 ql_dbg(ql_dbg_misc, vha, 0xd023,
374
- "%s: unusable range (start=%x end=%x)\n", __func__,
375
- ent->t262.end_addr, ent->t262.start_addr);
303
+ "%s: unusable range (start=%lx end=%lx)\n",
304
+ __func__, start, end);
376305 qla27xx_skip_entry(ent, buf);
377306 goto done;
378307 }
....@@ -380,24 +309,31 @@
380309 dwords = end - start + 1;
381310 if (buf) {
382311 buf += *len;
383
- qla24xx_dump_ram(vha->hw, start, buf, dwords, &buf);
312
+ rc = qla24xx_dump_ram(vha->hw, start, buf, dwords, &buf);
313
+ if (rc != QLA_SUCCESS) {
314
+ ql_dbg(ql_dbg_async, vha, 0xffff,
315
+ "%s: dump ram MB failed. Area %xh start %lxh end %lxh\n",
316
+ __func__, area, start, end);
317
+ return INVALID_ENTRY;
318
+ }
384319 }
385320 *len += dwords * sizeof(uint32_t);
386321 done:
387
- return false;
322
+ return qla27xx_next_entry(ent);
388323 }
389324
390
-static int
325
+static struct qla27xx_fwdt_entry *
391326 qla27xx_fwdt_entry_t263(struct scsi_qla_host *vha,
392327 struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
393328 {
329
+ uint type = ent->t263.queue_type;
394330 uint count = 0;
395331 uint i;
396332 uint length;
397333
398
- ql_dbg(ql_dbg_misc, vha, 0xd207,
399
- "%s: getq(%x) [%lx]\n", __func__, ent->t263.queue_type, *len);
400
- if (ent->t263.queue_type == T263_QUEUE_TYPE_REQ) {
334
+ ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd207,
335
+ "%s: getq(%x) [%lx]\n", __func__, type, *len);
336
+ if (type == T263_QUEUE_TYPE_REQ) {
401337 for (i = 0; i < vha->hw->max_req_queues; i++) {
402338 struct req_que *req = vha->hw->req_q_map[i];
403339
....@@ -411,7 +347,7 @@
411347 count++;
412348 }
413349 }
414
- } else if (ent->t263.queue_type == T263_QUEUE_TYPE_RSP) {
350
+ } else if (type == T263_QUEUE_TYPE_RSP) {
415351 for (i = 0; i < vha->hw->max_rsp_queues; i++) {
416352 struct rsp_que *rsp = vha->hw->rsp_q_map[i];
417353
....@@ -439,7 +375,7 @@
439375 }
440376 } else {
441377 ql_dbg(ql_dbg_misc, vha, 0xd026,
442
- "%s: unknown queue %x\n", __func__, ent->t263.queue_type);
378
+ "%s: unknown queue %x\n", __func__, type);
443379 qla27xx_skip_entry(ent, buf);
444380 }
445381
....@@ -450,10 +386,10 @@
450386 qla27xx_skip_entry(ent, buf);
451387 }
452388
453
- return false;
389
+ return qla27xx_next_entry(ent);
454390 }
455391
456
-static int
392
+static struct qla27xx_fwdt_entry *
457393 qla27xx_fwdt_entry_t264(struct scsi_qla_host *vha,
458394 struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
459395 {
....@@ -478,49 +414,48 @@
478414 qla27xx_skip_entry(ent, buf);
479415 }
480416
481
- return false;
417
+ return qla27xx_next_entry(ent);
482418 }
483419
484
-static int
420
+static struct qla27xx_fwdt_entry *
485421 qla27xx_fwdt_entry_t265(struct scsi_qla_host *vha,
486422 struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
487423 {
488
- struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha);
489
-
490
- ql_dbg(ql_dbg_misc, vha, 0xd209,
424
+ ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd209,
491425 "%s: pause risc [%lx]\n", __func__, *len);
492426 if (buf)
493
- qla24xx_pause_risc(reg, vha->hw);
427
+ qla24xx_pause_risc(ISPREG(vha), vha->hw);
494428
495
- return false;
429
+ return qla27xx_next_entry(ent);
496430 }
497431
498
-static int
432
+static struct qla27xx_fwdt_entry *
499433 qla27xx_fwdt_entry_t266(struct scsi_qla_host *vha,
500434 struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
501435 {
502436 ql_dbg(ql_dbg_misc, vha, 0xd20a,
503437 "%s: reset risc [%lx]\n", __func__, *len);
504438 if (buf)
505
- qla24xx_soft_reset(vha->hw);
439
+ WARN_ON_ONCE(qla24xx_soft_reset(vha->hw) != QLA_SUCCESS);
506440
507
- return false;
441
+ return qla27xx_next_entry(ent);
508442 }
509443
510
-static int
444
+static struct qla27xx_fwdt_entry *
511445 qla27xx_fwdt_entry_t267(struct scsi_qla_host *vha,
512446 struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
513447 {
514
- struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha);
448
+ uint offset = ent->t267.pci_offset;
449
+ ulong data = le32_to_cpu(ent->t267.data);
515450
516451 ql_dbg(ql_dbg_misc, vha, 0xd20b,
517452 "%s: dis intr [%lx]\n", __func__, *len);
518
- qla27xx_write_reg(reg, ent->t267.pci_offset, ent->t267.data, buf);
453
+ qla27xx_write_reg(ISPREG(vha), offset, data, buf);
519454
520
- return false;
455
+ return qla27xx_next_entry(ent);
521456 }
522457
523
-static int
458
+static struct qla27xx_fwdt_entry *
524459 qla27xx_fwdt_entry_t268(struct scsi_qla_host *vha,
525460 struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
526461 {
....@@ -587,10 +522,10 @@
587522 break;
588523 }
589524
590
- return false;
525
+ return qla27xx_next_entry(ent);
591526 }
592527
593
-static int
528
+static struct qla27xx_fwdt_entry *
594529 qla27xx_fwdt_entry_t269(struct scsi_qla_host *vha,
595530 struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
596531 {
....@@ -604,53 +539,51 @@
604539 if (buf)
605540 ent->t269.scratch_size = 5 * sizeof(uint32_t);
606541
607
- return false;
542
+ return qla27xx_next_entry(ent);
608543 }
609544
610
-static int
545
+static struct qla27xx_fwdt_entry *
611546 qla27xx_fwdt_entry_t270(struct scsi_qla_host *vha,
612547 struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
613548 {
614
- struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha);
615
- ulong dwords = ent->t270.count;
616
- ulong addr = ent->t270.addr;
549
+ ulong addr = le32_to_cpu(ent->t270.addr);
550
+ ulong dwords = le32_to_cpu(ent->t270.count);
617551
618552 ql_dbg(ql_dbg_misc, vha, 0xd20e,
619553 "%s: rdremreg [%lx]\n", __func__, *len);
620
- qla27xx_write_reg(reg, IOBASE_ADDR, 0x40, buf);
554
+ qla27xx_write_reg(ISPREG(vha), IOBASE_ADDR, 0x40, buf);
621555 while (dwords--) {
622
- qla27xx_write_reg(reg, 0xc0, addr|0x80000000, buf);
556
+ qla27xx_write_reg(ISPREG(vha), 0xc0, addr|0x80000000, buf);
623557 qla27xx_insert32(addr, buf, len);
624
- qla27xx_read_reg(reg, 0xc4, buf, len);
558
+ qla27xx_read_reg(ISPREG(vha), 0xc4, buf, len);
625559 addr += sizeof(uint32_t);
626560 }
627561
628
- return false;
562
+ return qla27xx_next_entry(ent);
629563 }
630564
631
-static int
565
+static struct qla27xx_fwdt_entry *
632566 qla27xx_fwdt_entry_t271(struct scsi_qla_host *vha,
633567 struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
634568 {
635
- struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha);
636
- ulong addr = ent->t271.addr;
637
- ulong data = ent->t271.data;
569
+ ulong addr = le32_to_cpu(ent->t271.addr);
570
+ ulong data = le32_to_cpu(ent->t271.data);
638571
639572 ql_dbg(ql_dbg_misc, vha, 0xd20f,
640573 "%s: wrremreg [%lx]\n", __func__, *len);
641
- qla27xx_write_reg(reg, IOBASE_ADDR, 0x40, buf);
642
- qla27xx_write_reg(reg, 0xc4, data, buf);
643
- qla27xx_write_reg(reg, 0xc0, addr, buf);
574
+ qla27xx_write_reg(ISPREG(vha), IOBASE(vha), 0x40, buf);
575
+ qla27xx_write_reg(ISPREG(vha), 0xc4, data, buf);
576
+ qla27xx_write_reg(ISPREG(vha), 0xc0, addr, buf);
644577
645
- return false;
578
+ return qla27xx_next_entry(ent);
646579 }
647580
648
-static int
581
+static struct qla27xx_fwdt_entry *
649582 qla27xx_fwdt_entry_t272(struct scsi_qla_host *vha,
650583 struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
651584 {
652
- ulong dwords = ent->t272.count;
653
- ulong start = ent->t272.addr;
585
+ ulong dwords = le32_to_cpu(ent->t272.count);
586
+ ulong start = le32_to_cpu(ent->t272.addr);
654587
655588 ql_dbg(ql_dbg_misc, vha, 0xd210,
656589 "%s: rdremram [%lx]\n", __func__, *len);
....@@ -662,15 +595,15 @@
662595 }
663596 *len += dwords * sizeof(uint32_t);
664597
665
- return false;
598
+ return qla27xx_next_entry(ent);
666599 }
667600
668
-static int
601
+static struct qla27xx_fwdt_entry *
669602 qla27xx_fwdt_entry_t273(struct scsi_qla_host *vha,
670603 struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
671604 {
672
- ulong dwords = ent->t273.count;
673
- ulong addr = ent->t273.addr;
605
+ ulong dwords = le32_to_cpu(ent->t273.count);
606
+ ulong addr = le32_to_cpu(ent->t273.addr);
674607 uint32_t value;
675608
676609 ql_dbg(ql_dbg_misc, vha, 0xd211,
....@@ -685,19 +618,20 @@
685618 addr += sizeof(uint32_t);
686619 }
687620
688
- return false;
621
+ return qla27xx_next_entry(ent);
689622 }
690623
691
-static int
624
+static struct qla27xx_fwdt_entry *
692625 qla27xx_fwdt_entry_t274(struct scsi_qla_host *vha,
693626 struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
694627 {
628
+ ulong type = ent->t274.queue_type;
695629 uint count = 0;
696630 uint i;
697631
698
- ql_dbg(ql_dbg_misc, vha, 0xd212,
699
- "%s: getqsh(%x) [%lx]\n", __func__, ent->t274.queue_type, *len);
700
- if (ent->t274.queue_type == T274_QUEUE_TYPE_REQ_SHAD) {
632
+ ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd212,
633
+ "%s: getqsh(%lx) [%lx]\n", __func__, type, *len);
634
+ if (type == T274_QUEUE_TYPE_REQ_SHAD) {
701635 for (i = 0; i < vha->hw->max_req_queues; i++) {
702636 struct req_que *req = vha->hw->req_q_map[i];
703637
....@@ -709,7 +643,7 @@
709643 count++;
710644 }
711645 }
712
- } else if (ent->t274.queue_type == T274_QUEUE_TYPE_RSP_SHAD) {
646
+ } else if (type == T274_QUEUE_TYPE_RSP_SHAD) {
713647 for (i = 0; i < vha->hw->max_rsp_queues; i++) {
714648 struct rsp_que *rsp = vha->hw->rsp_q_map[i];
715649
....@@ -735,7 +669,7 @@
735669 }
736670 } else {
737671 ql_dbg(ql_dbg_misc, vha, 0xd02f,
738
- "%s: unknown queue %x\n", __func__, ent->t274.queue_type);
672
+ "%s: unknown queue %lx\n", __func__, type);
739673 qla27xx_skip_entry(ent, buf);
740674 }
741675
....@@ -746,85 +680,146 @@
746680 qla27xx_skip_entry(ent, buf);
747681 }
748682
749
- return false;
683
+ return qla27xx_next_entry(ent);
750684 }
751685
752
-static int
686
+static struct qla27xx_fwdt_entry *
753687 qla27xx_fwdt_entry_t275(struct scsi_qla_host *vha,
754688 struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
755689 {
756690 ulong offset = offsetof(typeof(*ent), t275.buffer);
691
+ ulong length = le32_to_cpu(ent->t275.length);
692
+ ulong size = le32_to_cpu(ent->hdr.size);
693
+ void *buffer = ent->t275.buffer;
757694
758
- ql_dbg(ql_dbg_misc, vha, 0xd213,
759
- "%s: buffer(%x) [%lx]\n", __func__, ent->t275.length, *len);
760
- if (!ent->t275.length) {
695
+ ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd213,
696
+ "%s: buffer(%lx) [%lx]\n", __func__, length, *len);
697
+ if (!length) {
761698 ql_dbg(ql_dbg_misc, vha, 0xd020,
762699 "%s: buffer zero length\n", __func__);
763700 qla27xx_skip_entry(ent, buf);
764701 goto done;
765702 }
766
- if (offset + ent->t275.length > ent->hdr.entry_size) {
703
+ if (offset + length > size) {
704
+ length = size - offset;
767705 ql_dbg(ql_dbg_misc, vha, 0xd030,
768
- "%s: buffer overflow\n", __func__);
769
- qla27xx_skip_entry(ent, buf);
770
- goto done;
706
+ "%s: buffer overflow, truncate [%lx]\n", __func__, length);
707
+ ent->t275.length = cpu_to_le32(length);
771708 }
772709
773
- qla27xx_insertbuf(ent->t275.buffer, ent->t275.length, buf, len);
710
+ qla27xx_insertbuf(buffer, length, buf, len);
774711 done:
775
- return false;
712
+ return qla27xx_next_entry(ent);
776713 }
777714
778
-static int
715
+static struct qla27xx_fwdt_entry *
716
+qla27xx_fwdt_entry_t276(struct scsi_qla_host *vha,
717
+ struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
718
+{
719
+ ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd214,
720
+ "%s: cond [%lx]\n", __func__, *len);
721
+
722
+ if (buf) {
723
+ ulong cond1 = le32_to_cpu(ent->t276.cond1);
724
+ ulong cond2 = le32_to_cpu(ent->t276.cond2);
725
+ uint type = vha->hw->pdev->device >> 4 & 0xf;
726
+ uint func = vha->hw->port_no & 0x3;
727
+
728
+ if (type != cond1 || func != cond2) {
729
+ struct qla27xx_fwdt_template *tmp = buf;
730
+
731
+ tmp->count--;
732
+ ent = qla27xx_next_entry(ent);
733
+ qla27xx_skip_entry(ent, buf);
734
+ }
735
+ }
736
+
737
+ return qla27xx_next_entry(ent);
738
+}
739
+
740
+static struct qla27xx_fwdt_entry *
741
+qla27xx_fwdt_entry_t277(struct scsi_qla_host *vha,
742
+ struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
743
+{
744
+ ulong cmd_addr = le32_to_cpu(ent->t277.cmd_addr);
745
+ ulong wr_cmd_data = le32_to_cpu(ent->t277.wr_cmd_data);
746
+ ulong data_addr = le32_to_cpu(ent->t277.data_addr);
747
+
748
+ ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd215,
749
+ "%s: rdpep [%lx]\n", __func__, *len);
750
+ qla27xx_insert32(wr_cmd_data, buf, len);
751
+ qla27xx_write_reg(ISPREG(vha), cmd_addr, wr_cmd_data, buf);
752
+ qla27xx_read_reg(ISPREG(vha), data_addr, buf, len);
753
+
754
+ return qla27xx_next_entry(ent);
755
+}
756
+
757
+static struct qla27xx_fwdt_entry *
758
+qla27xx_fwdt_entry_t278(struct scsi_qla_host *vha,
759
+ struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
760
+{
761
+ ulong cmd_addr = le32_to_cpu(ent->t278.cmd_addr);
762
+ ulong wr_cmd_data = le32_to_cpu(ent->t278.wr_cmd_data);
763
+ ulong data_addr = le32_to_cpu(ent->t278.data_addr);
764
+ ulong wr_data = le32_to_cpu(ent->t278.wr_data);
765
+
766
+ ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd216,
767
+ "%s: wrpep [%lx]\n", __func__, *len);
768
+ qla27xx_write_reg(ISPREG(vha), data_addr, wr_data, buf);
769
+ qla27xx_write_reg(ISPREG(vha), cmd_addr, wr_cmd_data, buf);
770
+
771
+ return qla27xx_next_entry(ent);
772
+}
773
+
774
+static struct qla27xx_fwdt_entry *
779775 qla27xx_fwdt_entry_other(struct scsi_qla_host *vha,
780776 struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
781777 {
778
+ ulong type = le32_to_cpu(ent->hdr.type);
779
+
782780 ql_dbg(ql_dbg_misc, vha, 0xd2ff,
783
- "%s: type %x [%lx]\n", __func__, ent->hdr.entry_type, *len);
781
+ "%s: other %lx [%lx]\n", __func__, type, *len);
784782 qla27xx_skip_entry(ent, buf);
785783
786
- return false;
784
+ return qla27xx_next_entry(ent);
787785 }
788786
789
-struct qla27xx_fwdt_entry_call {
787
+static struct {
790788 uint type;
791
- int (*call)(
792
- struct scsi_qla_host *,
793
- struct qla27xx_fwdt_entry *,
794
- void *,
795
- ulong *);
789
+ typeof(qla27xx_fwdt_entry_other)(*call);
790
+} qla27xx_fwdt_entry_call[] = {
791
+ { ENTRY_TYPE_NOP, qla27xx_fwdt_entry_t0 },
792
+ { ENTRY_TYPE_TMP_END, qla27xx_fwdt_entry_t255 },
793
+ { ENTRY_TYPE_RD_IOB_T1, qla27xx_fwdt_entry_t256 },
794
+ { ENTRY_TYPE_WR_IOB_T1, qla27xx_fwdt_entry_t257 },
795
+ { ENTRY_TYPE_RD_IOB_T2, qla27xx_fwdt_entry_t258 },
796
+ { ENTRY_TYPE_WR_IOB_T2, qla27xx_fwdt_entry_t259 },
797
+ { ENTRY_TYPE_RD_PCI, qla27xx_fwdt_entry_t260 },
798
+ { ENTRY_TYPE_WR_PCI, qla27xx_fwdt_entry_t261 },
799
+ { ENTRY_TYPE_RD_RAM, qla27xx_fwdt_entry_t262 },
800
+ { ENTRY_TYPE_GET_QUEUE, qla27xx_fwdt_entry_t263 },
801
+ { ENTRY_TYPE_GET_FCE, qla27xx_fwdt_entry_t264 },
802
+ { ENTRY_TYPE_PSE_RISC, qla27xx_fwdt_entry_t265 },
803
+ { ENTRY_TYPE_RST_RISC, qla27xx_fwdt_entry_t266 },
804
+ { ENTRY_TYPE_DIS_INTR, qla27xx_fwdt_entry_t267 },
805
+ { ENTRY_TYPE_GET_HBUF, qla27xx_fwdt_entry_t268 },
806
+ { ENTRY_TYPE_SCRATCH, qla27xx_fwdt_entry_t269 },
807
+ { ENTRY_TYPE_RDREMREG, qla27xx_fwdt_entry_t270 },
808
+ { ENTRY_TYPE_WRREMREG, qla27xx_fwdt_entry_t271 },
809
+ { ENTRY_TYPE_RDREMRAM, qla27xx_fwdt_entry_t272 },
810
+ { ENTRY_TYPE_PCICFG, qla27xx_fwdt_entry_t273 },
811
+ { ENTRY_TYPE_GET_SHADOW, qla27xx_fwdt_entry_t274 },
812
+ { ENTRY_TYPE_WRITE_BUF, qla27xx_fwdt_entry_t275 },
813
+ { ENTRY_TYPE_CONDITIONAL, qla27xx_fwdt_entry_t276 },
814
+ { ENTRY_TYPE_RDPEPREG, qla27xx_fwdt_entry_t277 },
815
+ { ENTRY_TYPE_WRPEPREG, qla27xx_fwdt_entry_t278 },
816
+ { -1, qla27xx_fwdt_entry_other }
796817 };
797818
798
-static struct qla27xx_fwdt_entry_call ql27xx_fwdt_entry_call_list[] = {
799
- { ENTRY_TYPE_NOP , qla27xx_fwdt_entry_t0 } ,
800
- { ENTRY_TYPE_TMP_END , qla27xx_fwdt_entry_t255 } ,
801
- { ENTRY_TYPE_RD_IOB_T1 , qla27xx_fwdt_entry_t256 } ,
802
- { ENTRY_TYPE_WR_IOB_T1 , qla27xx_fwdt_entry_t257 } ,
803
- { ENTRY_TYPE_RD_IOB_T2 , qla27xx_fwdt_entry_t258 } ,
804
- { ENTRY_TYPE_WR_IOB_T2 , qla27xx_fwdt_entry_t259 } ,
805
- { ENTRY_TYPE_RD_PCI , qla27xx_fwdt_entry_t260 } ,
806
- { ENTRY_TYPE_WR_PCI , qla27xx_fwdt_entry_t261 } ,
807
- { ENTRY_TYPE_RD_RAM , qla27xx_fwdt_entry_t262 } ,
808
- { ENTRY_TYPE_GET_QUEUE , qla27xx_fwdt_entry_t263 } ,
809
- { ENTRY_TYPE_GET_FCE , qla27xx_fwdt_entry_t264 } ,
810
- { ENTRY_TYPE_PSE_RISC , qla27xx_fwdt_entry_t265 } ,
811
- { ENTRY_TYPE_RST_RISC , qla27xx_fwdt_entry_t266 } ,
812
- { ENTRY_TYPE_DIS_INTR , qla27xx_fwdt_entry_t267 } ,
813
- { ENTRY_TYPE_GET_HBUF , qla27xx_fwdt_entry_t268 } ,
814
- { ENTRY_TYPE_SCRATCH , qla27xx_fwdt_entry_t269 } ,
815
- { ENTRY_TYPE_RDREMREG , qla27xx_fwdt_entry_t270 } ,
816
- { ENTRY_TYPE_WRREMREG , qla27xx_fwdt_entry_t271 } ,
817
- { ENTRY_TYPE_RDREMRAM , qla27xx_fwdt_entry_t272 } ,
818
- { ENTRY_TYPE_PCICFG , qla27xx_fwdt_entry_t273 } ,
819
- { ENTRY_TYPE_GET_SHADOW , qla27xx_fwdt_entry_t274 } ,
820
- { ENTRY_TYPE_WRITE_BUF , qla27xx_fwdt_entry_t275 } ,
821
- { -1 , qla27xx_fwdt_entry_other }
822
-};
823
-
824
-static inline int (*qla27xx_find_entry(uint type))
825
- (struct scsi_qla_host *, struct qla27xx_fwdt_entry *, void *, ulong *)
819
+static inline
820
+typeof(qla27xx_fwdt_entry_call->call)(qla27xx_find_entry(uint type))
826821 {
827
- struct qla27xx_fwdt_entry_call *list = ql27xx_fwdt_entry_call_list;
822
+ typeof(*qla27xx_fwdt_entry_call) *list = qla27xx_fwdt_entry_call;
828823
829824 while (list->type < type)
830825 list++;
....@@ -834,56 +829,47 @@
834829 return qla27xx_fwdt_entry_other;
835830 }
836831
837
-static inline void *
838
-qla27xx_next_entry(void *p)
839
-{
840
- struct qla27xx_fwdt_entry *ent = p;
841
-
842
- return p + ent->hdr.entry_size;
843
-}
844
-
845832 static void
846833 qla27xx_walk_template(struct scsi_qla_host *vha,
847834 struct qla27xx_fwdt_template *tmp, void *buf, ulong *len)
848835 {
849
- struct qla27xx_fwdt_entry *ent = (void *)tmp + tmp->entry_offset;
850
- ulong count = tmp->entry_count;
836
+ struct qla27xx_fwdt_entry *ent = (void *)tmp +
837
+ le32_to_cpu(tmp->entry_offset);
838
+ ulong type;
851839
840
+ tmp->count = le32_to_cpu(tmp->entry_count);
852841 ql_dbg(ql_dbg_misc, vha, 0xd01a,
853
- "%s: entry count %lx\n", __func__, count);
854
- while (count--) {
855
- if (buf && *len >= vha->hw->fw_dump_len)
842
+ "%s: entry count %u\n", __func__, tmp->count);
843
+ while (ent && tmp->count--) {
844
+ type = le32_to_cpu(ent->hdr.type);
845
+ ent = qla27xx_find_entry(type)(vha, ent, buf, len);
846
+ if (!ent)
856847 break;
857
- if (qla27xx_find_entry(ent->hdr.entry_type)(vha, ent, buf, len))
858
- break;
859
- ent = qla27xx_next_entry(ent);
848
+
849
+ if (ent == INVALID_ENTRY) {
850
+ *len = 0;
851
+ ql_dbg(ql_dbg_async, vha, 0xffff,
852
+ "Unable to capture FW dump");
853
+ goto bailout;
854
+ }
860855 }
861856
862
- if (count)
857
+ if (tmp->count)
863858 ql_dbg(ql_dbg_misc, vha, 0xd018,
864
- "%s: entry residual count (%lx)\n", __func__, count);
859
+ "%s: entry count residual=+%u\n", __func__, tmp->count);
865860
866
- if (ent->hdr.entry_type != ENTRY_TYPE_TMP_END)
861
+ if (ent)
867862 ql_dbg(ql_dbg_misc, vha, 0xd019,
868
- "%s: missing end entry (%lx)\n", __func__, count);
863
+ "%s: missing end entry\n", __func__);
869864
870
- if (buf && *len != vha->hw->fw_dump_len)
871
- ql_dbg(ql_dbg_misc, vha, 0xd01b,
872
- "%s: length=%#lx residual=%+ld\n",
873
- __func__, *len, vha->hw->fw_dump_len - *len);
874
-
875
- if (buf) {
876
- ql_log(ql_log_warn, vha, 0xd015,
877
- "Firmware dump saved to temp buffer (%lu/%p)\n",
878
- vha->host_no, vha->hw->fw_dump);
879
- qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP);
880
- }
865
+bailout:
866
+ cpu_to_le32s(&tmp->count); /* endianize residual count */
881867 }
882868
883869 static void
884870 qla27xx_time_stamp(struct qla27xx_fwdt_template *tmp)
885871 {
886
- tmp->capture_timestamp = jiffies;
872
+ tmp->capture_timestamp = cpu_to_le32(jiffies);
887873 }
888874
889875 static void
....@@ -891,25 +877,27 @@
891877 {
892878 uint8_t v[] = { 0, 0, 0, 0, 0, 0 };
893879
894
- sscanf(qla2x00_version_str, "%hhu.%hhu.%hhu.%hhu.%hhu.%hhu",
895
- v+0, v+1, v+2, v+3, v+4, v+5);
880
+ WARN_ON_ONCE(sscanf(qla2x00_version_str,
881
+ "%hhu.%hhu.%hhu.%hhu",
882
+ v + 0, v + 1, v + 2, v + 3) != 4);
896883
897
- tmp->driver_info[0] = v[3] << 24 | v[2] << 16 | v[1] << 8 | v[0];
898
- tmp->driver_info[1] = v[5] << 8 | v[4];
899
- tmp->driver_info[2] = 0x12345678;
884
+ tmp->driver_info[0] = cpu_to_le32(
885
+ v[3] << 24 | v[2] << 16 | v[1] << 8 | v[0]);
886
+ tmp->driver_info[1] = cpu_to_le32(v[5] << 8 | v[4]);
887
+ tmp->driver_info[2] = __constant_cpu_to_le32(0x12345678);
900888 }
901889
902890 static void
903
-qla27xx_firmware_info(struct qla27xx_fwdt_template *tmp,
904
- struct scsi_qla_host *vha)
891
+qla27xx_firmware_info(struct scsi_qla_host *vha,
892
+ struct qla27xx_fwdt_template *tmp)
905893 {
906
- tmp->firmware_version[0] = vha->hw->fw_major_version;
907
- tmp->firmware_version[1] = vha->hw->fw_minor_version;
908
- tmp->firmware_version[2] = vha->hw->fw_subminor_version;
909
- tmp->firmware_version[3] =
910
- vha->hw->fw_attributes_h << 16 | vha->hw->fw_attributes;
911
- tmp->firmware_version[4] =
912
- vha->hw->fw_attributes_ext[1] << 16 | vha->hw->fw_attributes_ext[0];
894
+ tmp->firmware_version[0] = cpu_to_le32(vha->hw->fw_major_version);
895
+ tmp->firmware_version[1] = cpu_to_le32(vha->hw->fw_minor_version);
896
+ tmp->firmware_version[2] = cpu_to_le32(vha->hw->fw_subminor_version);
897
+ tmp->firmware_version[3] = cpu_to_le32(
898
+ vha->hw->fw_attributes_h << 16 | vha->hw->fw_attributes);
899
+ tmp->firmware_version[4] = cpu_to_le32(
900
+ vha->hw->fw_attributes_ext[1] << 16 | vha->hw->fw_attributes_ext[0]);
913901 }
914902
915903 static void
....@@ -918,19 +906,19 @@
918906 {
919907 qla27xx_time_stamp(tmp);
920908 qla27xx_driver_info(tmp);
921
- qla27xx_firmware_info(tmp, vha);
909
+ qla27xx_firmware_info(vha, tmp);
922910 }
923911
924912 static inline uint32_t
925913 qla27xx_template_checksum(void *p, ulong size)
926914 {
927
- uint32_t *buf = p;
915
+ __le32 *buf = p;
928916 uint64_t sum = 0;
929917
930918 size /= sizeof(*buf);
931919
932
- while (size--)
933
- sum += *buf++;
920
+ for ( ; size--; buf++)
921
+ sum += le32_to_cpu(*buf);
934922
935923 sum = (sum & 0xffffffff) + (sum >> 32);
936924
....@@ -947,29 +935,29 @@
947935 static inline int
948936 qla27xx_verify_template_header(struct qla27xx_fwdt_template *tmp)
949937 {
950
- return tmp->template_type == TEMPLATE_TYPE_FWDUMP;
938
+ return le32_to_cpu(tmp->template_type) == TEMPLATE_TYPE_FWDUMP;
951939 }
952940
953
-static void
954
-qla27xx_execute_fwdt_template(struct scsi_qla_host *vha)
941
+static ulong
942
+qla27xx_execute_fwdt_template(struct scsi_qla_host *vha,
943
+ struct qla27xx_fwdt_template *tmp, void *buf)
955944 {
956
- struct qla27xx_fwdt_template *tmp = vha->hw->fw_dump_template;
957
- ulong len;
945
+ ulong len = 0;
958946
959947 if (qla27xx_fwdt_template_valid(tmp)) {
960948 len = le32_to_cpu(tmp->template_size);
961
- tmp = memcpy(vha->hw->fw_dump, tmp, len);
949
+ tmp = memcpy(buf, tmp, len);
962950 ql27xx_edit_template(vha, tmp);
963
- qla27xx_walk_template(vha, tmp, tmp, &len);
964
- vha->hw->fw_dump_len = len;
965
- vha->hw->fw_dumped = 1;
951
+ qla27xx_walk_template(vha, tmp, buf, &len);
966952 }
953
+
954
+ return len;
967955 }
968956
969957 ulong
970
-qla27xx_fwdt_calculate_dump_size(struct scsi_qla_host *vha)
958
+qla27xx_fwdt_calculate_dump_size(struct scsi_qla_host *vha, void *p)
971959 {
972
- struct qla27xx_fwdt_template *tmp = vha->hw->fw_dump_template;
960
+ struct qla27xx_fwdt_template *tmp = p;
973961 ulong len = 0;
974962
975963 if (qla27xx_fwdt_template_valid(tmp)) {
....@@ -988,18 +976,6 @@
988976 return le32_to_cpu(tmp->template_size);
989977 }
990978
991
-ulong
992
-qla27xx_fwdt_template_default_size(void)
993
-{
994
- return sizeof(ql27xx_fwdt_default_template);
995
-}
996
-
997
-const void *
998
-qla27xx_fwdt_template_default(void)
999
-{
1000
- return ql27xx_fwdt_default_template;
1001
-}
1002
-
1003979 int
1004980 qla27xx_fwdt_template_valid(void *p)
1005981 {
....@@ -1007,7 +983,8 @@
1007983
1008984 if (!qla27xx_verify_template_header(tmp)) {
1009985 ql_log(ql_log_warn, NULL, 0xd01c,
1010
- "%s: template type %x\n", __func__, tmp->template_type);
986
+ "%s: template type %x\n", __func__,
987
+ le32_to_cpu(tmp->template_type));
1011988 return false;
1012989 }
1013990
....@@ -1021,30 +998,98 @@
1021998 }
1022999
10231000 void
1024
-qla27xx_fwdump(scsi_qla_host_t *vha, int hardware_locked)
1001
+qla27xx_mpi_fwdump(scsi_qla_host_t *vha, int hardware_locked)
10251002 {
10261003 ulong flags = 0;
10271004
1028
-#ifndef __CHECKER__
10291005 if (!hardware_locked)
10301006 spin_lock_irqsave(&vha->hw->hardware_lock, flags);
1031
-#endif
1007
+ if (!vha->hw->mpi_fw_dump) {
1008
+ ql_log(ql_log_warn, vha, 0x02f3, "-> mpi_fwdump no buffer\n");
1009
+ } else {
1010
+ struct fwdt *fwdt = &vha->hw->fwdt[1];
1011
+ ulong len;
1012
+ void *buf = vha->hw->mpi_fw_dump;
1013
+ bool walk_template_only = false;
10321014
1033
- if (!vha->hw->fw_dump)
1034
- ql_log(ql_log_warn, vha, 0xd01e, "fwdump buffer missing.\n");
1035
- else if (!vha->hw->fw_dump_template)
1036
- ql_log(ql_log_warn, vha, 0xd01f, "fwdump template missing.\n");
1037
- else if (vha->hw->fw_dumped)
1038
- ql_log(ql_log_warn, vha, 0xd300,
1039
- "Firmware has been previously dumped (%p),"
1040
- " -- ignoring request\n", vha->hw->fw_dump);
1041
- else {
1042
- QLA_FW_STOPPED(vha->hw);
1043
- qla27xx_execute_fwdt_template(vha);
1015
+ if (vha->hw->mpi_fw_dumped) {
1016
+ /* Use the spare area for any further dumps. */
1017
+ buf += fwdt->dump_size;
1018
+ walk_template_only = true;
1019
+ ql_log(ql_log_warn, vha, 0x02f4,
1020
+ "-> MPI firmware already dumped -- dump saving to temporary buffer %p.\n",
1021
+ buf);
1022
+ }
1023
+
1024
+ ql_log(ql_log_warn, vha, 0x02f5, "-> fwdt1 running...\n");
1025
+ if (!fwdt->template) {
1026
+ ql_log(ql_log_warn, vha, 0x02f6,
1027
+ "-> fwdt1 no template\n");
1028
+ goto bailout;
1029
+ }
1030
+ len = qla27xx_execute_fwdt_template(vha, fwdt->template, buf);
1031
+ if (len == 0) {
1032
+ goto bailout;
1033
+ } else if (len != fwdt->dump_size) {
1034
+ ql_log(ql_log_warn, vha, 0x02f7,
1035
+ "-> fwdt1 fwdump residual=%+ld\n",
1036
+ fwdt->dump_size - len);
1037
+ }
1038
+ vha->hw->stat.num_mpi_reset++;
1039
+ if (walk_template_only)
1040
+ goto bailout;
1041
+
1042
+ vha->hw->mpi_fw_dump_len = len;
1043
+ vha->hw->mpi_fw_dumped = 1;
1044
+
1045
+ ql_log(ql_log_warn, vha, 0x02f8,
1046
+ "-> MPI firmware dump saved to buffer (%lu/%p)\n",
1047
+ vha->host_no, vha->hw->mpi_fw_dump);
1048
+ qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP);
10441049 }
10451050
1046
-#ifndef __CHECKER__
1051
+bailout:
10471052 if (!hardware_locked)
10481053 spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
1049
-#endif
1054
+}
1055
+
1056
+void
1057
+qla27xx_fwdump(scsi_qla_host_t *vha)
1058
+{
1059
+ lockdep_assert_held(&vha->hw->hardware_lock);
1060
+
1061
+ if (!vha->hw->fw_dump) {
1062
+ ql_log(ql_log_warn, vha, 0xd01e, "-> fwdump no buffer\n");
1063
+ } else if (vha->hw->fw_dumped) {
1064
+ ql_log(ql_log_warn, vha, 0xd01f,
1065
+ "-> Firmware already dumped (%p) -- ignoring request\n",
1066
+ vha->hw->fw_dump);
1067
+ } else {
1068
+ struct fwdt *fwdt = vha->hw->fwdt;
1069
+ ulong len;
1070
+ void *buf = vha->hw->fw_dump;
1071
+
1072
+ ql_log(ql_log_warn, vha, 0xd011, "-> fwdt0 running...\n");
1073
+ if (!fwdt->template) {
1074
+ ql_log(ql_log_warn, vha, 0xd012,
1075
+ "-> fwdt0 no template\n");
1076
+ return;
1077
+ }
1078
+ len = qla27xx_execute_fwdt_template(vha, fwdt->template, buf);
1079
+ if (len == 0) {
1080
+ return;
1081
+ } else if (len != fwdt->dump_size) {
1082
+ ql_log(ql_log_warn, vha, 0xd013,
1083
+ "-> fwdt0 fwdump residual=%+ld\n",
1084
+ fwdt->dump_size - len);
1085
+ }
1086
+
1087
+ vha->hw->fw_dump_len = len;
1088
+ vha->hw->fw_dumped = true;
1089
+
1090
+ ql_log(ql_log_warn, vha, 0xd015,
1091
+ "-> Firmware dump saved to buffer (%lu/%p) <%lx>\n",
1092
+ vha->host_no, vha->hw->fw_dump, vha->hw->fw_dump_cap_flags);
1093
+ qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP);
1094
+ }
10501095 }