aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla4xxx
diff options
context:
space:
mode:
authorVikas Chaudhary <vikas.chaudhary@qlogic.com>2012-08-22 07:55:08 -0400
committerJames Bottomley <JBottomley@Parallels.com>2012-09-24 04:11:08 -0400
commit6e7b429259fc0b7f2d9b1147466656b34d114815 (patch)
treeb5bc8dc7e7e803f6589c9cdd4e71c8dc7a9932ab /drivers/scsi/qla4xxx
parentaec07caedbb769535e78adca30c851c977fd5741 (diff)
[SCSI] qla4xxx: Added support for ISP83XX
Signed-off-by: Poornima Vonti <poornima.vonti@qlogic.com> Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com> Reviewed-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/qla4xxx')
-rw-r--r--drivers/scsi/qla4xxx/Kconfig4
-rw-r--r--drivers/scsi/qla4xxx/Makefile2
-rw-r--r--drivers/scsi/qla4xxx/ql4_83xx.c1468
-rw-r--r--drivers/scsi/qla4xxx/ql4_83xx.h262
-rw-r--r--drivers/scsi/qla4xxx/ql4_attr.c2
-rw-r--r--drivers/scsi/qla4xxx/ql4_dbg.c28
-rw-r--r--drivers/scsi/qla4xxx/ql4_def.h27
-rw-r--r--drivers/scsi/qla4xxx/ql4_fw.h38
-rw-r--r--drivers/scsi/qla4xxx/ql4_glbl.h41
-rw-r--r--drivers/scsi/qla4xxx/ql4_init.c15
-rw-r--r--drivers/scsi/qla4xxx/ql4_iocb.c12
-rw-r--r--drivers/scsi/qla4xxx/ql4_isr.c202
-rw-r--r--drivers/scsi/qla4xxx/ql4_mbx.c6
-rw-r--r--drivers/scsi/qla4xxx/ql4_nx.c488
-rw-r--r--drivers/scsi/qla4xxx/ql4_nx.h17
-rw-r--r--drivers/scsi/qla4xxx/ql4_os.c262
16 files changed, 2689 insertions, 185 deletions
diff --git a/drivers/scsi/qla4xxx/Kconfig b/drivers/scsi/qla4xxx/Kconfig
index f1ad02ea212b..e4dc7c733c29 100644
--- a/drivers/scsi/qla4xxx/Kconfig
+++ b/drivers/scsi/qla4xxx/Kconfig
@@ -4,5 +4,5 @@ config SCSI_QLA_ISCSI
4 select SCSI_ISCSI_ATTRS 4 select SCSI_ISCSI_ATTRS
5 select ISCSI_BOOT_SYSFS 5 select ISCSI_BOOT_SYSFS
6 ---help--- 6 ---help---
7 This driver supports the QLogic 40xx (ISP4XXX) and 8022 (ISP82XX) 7 This driver supports the QLogic 40xx (ISP4XXX), 8022 (ISP82XX)
8 iSCSI host adapter family. 8 and 8032 (ISP83XX) iSCSI host adapter family.
diff --git a/drivers/scsi/qla4xxx/Makefile b/drivers/scsi/qla4xxx/Makefile
index 5b44139ff43d..4230977748cf 100644
--- a/drivers/scsi/qla4xxx/Makefile
+++ b/drivers/scsi/qla4xxx/Makefile
@@ -1,5 +1,5 @@
1qla4xxx-y := ql4_os.o ql4_init.o ql4_mbx.o ql4_iocb.o ql4_isr.o \ 1qla4xxx-y := ql4_os.o ql4_init.o ql4_mbx.o ql4_iocb.o ql4_isr.o \
2 ql4_nx.o ql4_nvram.o ql4_dbg.o ql4_attr.o ql4_bsg.o 2 ql4_nx.o ql4_nvram.o ql4_dbg.o ql4_attr.o ql4_bsg.o ql4_83xx.o
3 3
4obj-$(CONFIG_SCSI_QLA_ISCSI) += qla4xxx.o 4obj-$(CONFIG_SCSI_QLA_ISCSI) += qla4xxx.o
5 5
diff --git a/drivers/scsi/qla4xxx/ql4_83xx.c b/drivers/scsi/qla4xxx/ql4_83xx.c
new file mode 100644
index 000000000000..f963b06a1583
--- /dev/null
+++ b/drivers/scsi/qla4xxx/ql4_83xx.c
@@ -0,0 +1,1468 @@
1/*
2 * QLogic iSCSI HBA Driver
3 * Copyright (c) 2003-2012 QLogic Corporation
4 *
5 * See LICENSE.qla4xxx for copyright and licensing details.
6 */
7
8#include <linux/ratelimit.h>
9
10#include "ql4_def.h"
11#include "ql4_version.h"
12#include "ql4_glbl.h"
13#include "ql4_dbg.h"
14#include "ql4_inline.h"
15
16uint32_t qla4_83xx_rd_reg(struct scsi_qla_host *ha, ulong addr)
17{
18 return readl((void __iomem *)(ha->nx_pcibase + addr));
19}
20
21void qla4_83xx_wr_reg(struct scsi_qla_host *ha, ulong addr, uint32_t val)
22{
23 writel(val, (void __iomem *)(ha->nx_pcibase + addr));
24}
25
26static int qla4_83xx_set_win_base(struct scsi_qla_host *ha, uint32_t addr)
27{
28 uint32_t val;
29 int ret_val = QLA_SUCCESS;
30
31 qla4_83xx_wr_reg(ha, QLA83XX_CRB_WIN_FUNC(ha->func_num), addr);
32 val = qla4_83xx_rd_reg(ha, QLA83XX_CRB_WIN_FUNC(ha->func_num));
33 if (val != addr) {
34 ql4_printk(KERN_ERR, ha, "%s: Failed to set register window : addr written 0x%x, read 0x%x!\n",
35 __func__, addr, val);
36 ret_val = QLA_ERROR;
37 }
38
39 return ret_val;
40}
41
42int qla4_83xx_rd_reg_indirect(struct scsi_qla_host *ha, uint32_t addr,
43 uint32_t *data)
44{
45 int ret_val;
46
47 ret_val = qla4_83xx_set_win_base(ha, addr);
48
49 if (ret_val == QLA_SUCCESS)
50 *data = qla4_83xx_rd_reg(ha, QLA83XX_WILDCARD);
51 else
52 ql4_printk(KERN_ERR, ha, "%s: failed read of addr 0x%x!\n",
53 __func__, addr);
54
55 return ret_val;
56}
57
58int qla4_83xx_wr_reg_indirect(struct scsi_qla_host *ha, uint32_t addr,
59 uint32_t data)
60{
61 int ret_val;
62
63 ret_val = qla4_83xx_set_win_base(ha, addr);
64
65 if (ret_val == QLA_SUCCESS)
66 qla4_83xx_wr_reg(ha, QLA83XX_WILDCARD, data);
67 else
68 ql4_printk(KERN_ERR, ha, "%s: failed wrt to addr 0x%x, data 0x%x\n",
69 __func__, addr, data);
70
71 return ret_val;
72}
73
74static int qla4_83xx_flash_lock(struct scsi_qla_host *ha)
75{
76 int lock_owner;
77 int timeout = 0;
78 uint32_t lock_status = 0;
79 int ret_val = QLA_SUCCESS;
80
81 while (lock_status == 0) {
82 lock_status = qla4_83xx_rd_reg(ha, QLA83XX_FLASH_LOCK);
83 if (lock_status)
84 break;
85
86 if (++timeout >= QLA83XX_FLASH_LOCK_TIMEOUT / 20) {
87 lock_owner = qla4_83xx_rd_reg(ha,
88 QLA83XX_FLASH_LOCK_ID);
89 ql4_printk(KERN_ERR, ha, "%s: flash lock by func %d failed, held by func %d\n",
90 __func__, ha->func_num, lock_owner);
91 ret_val = QLA_ERROR;
92 break;
93 }
94 msleep(20);
95 }
96
97 qla4_83xx_wr_reg(ha, QLA83XX_FLASH_LOCK_ID, ha->func_num);
98 return ret_val;
99}
100
101static void qla4_83xx_flash_unlock(struct scsi_qla_host *ha)
102{
103 /* Reading FLASH_UNLOCK register unlocks the Flash */
104 qla4_83xx_wr_reg(ha, QLA83XX_FLASH_LOCK_ID, 0xFF);
105 qla4_83xx_rd_reg(ha, QLA83XX_FLASH_UNLOCK);
106}
107
108int qla4_83xx_flash_read_u32(struct scsi_qla_host *ha, uint32_t flash_addr,
109 uint8_t *p_data, int u32_word_count)
110{
111 int i;
112 uint32_t u32_word;
113 uint32_t addr = flash_addr;
114 int ret_val = QLA_SUCCESS;
115
116 ret_val = qla4_83xx_flash_lock(ha);
117 if (ret_val == QLA_ERROR)
118 goto exit_lock_error;
119
120 if (addr & 0x03) {
121 ql4_printk(KERN_ERR, ha, "%s: Illegal addr = 0x%x\n",
122 __func__, addr);
123 ret_val = QLA_ERROR;
124 goto exit_flash_read;
125 }
126
127 for (i = 0; i < u32_word_count; i++) {
128 ret_val = qla4_83xx_wr_reg_indirect(ha,
129 QLA83XX_FLASH_DIRECT_WINDOW,
130 (addr & 0xFFFF0000));
131 if (ret_val == QLA_ERROR) {
132 ql4_printk(KERN_ERR, ha, "%s: failed to write addr 0x%x to FLASH_DIRECT_WINDOW\n!",
133 __func__, addr);
134 goto exit_flash_read;
135 }
136
137 ret_val = qla4_83xx_rd_reg_indirect(ha,
138 QLA83XX_FLASH_DIRECT_DATA(addr),
139 &u32_word);
140 if (ret_val == QLA_ERROR) {
141 ql4_printk(KERN_ERR, ha, "%s: failed to read addr 0x%x!\n",
142 __func__, addr);
143 goto exit_flash_read;
144 }
145
146 *(__le32 *)p_data = le32_to_cpu(u32_word);
147 p_data = p_data + 4;
148 addr = addr + 4;
149 }
150
151exit_flash_read:
152 qla4_83xx_flash_unlock(ha);
153
154exit_lock_error:
155 return ret_val;
156}
157
158int qla4_83xx_lockless_flash_read_u32(struct scsi_qla_host *ha,
159 uint32_t flash_addr, uint8_t *p_data,
160 int u32_word_count)
161{
162 uint32_t i;
163 uint32_t u32_word;
164 uint32_t flash_offset;
165 uint32_t addr = flash_addr;
166 int ret_val = QLA_SUCCESS;
167
168 flash_offset = addr & (QLA83XX_FLASH_SECTOR_SIZE - 1);
169
170 if (addr & 0x3) {
171 ql4_printk(KERN_ERR, ha, "%s: Illegal addr = 0x%x\n",
172 __func__, addr);
173 ret_val = QLA_ERROR;
174 goto exit_lockless_read;
175 }
176
177 ret_val = qla4_83xx_wr_reg_indirect(ha, QLA83XX_FLASH_DIRECT_WINDOW,
178 addr);
179 if (ret_val == QLA_ERROR) {
180 ql4_printk(KERN_ERR, ha, "%s: failed to write addr 0x%x to FLASH_DIRECT_WINDOW!\n",
181 __func__, addr);
182 goto exit_lockless_read;
183 }
184
185 /* Check if data is spread across multiple sectors */
186 if ((flash_offset + (u32_word_count * sizeof(uint32_t))) >
187 (QLA83XX_FLASH_SECTOR_SIZE - 1)) {
188
189 /* Multi sector read */
190 for (i = 0; i < u32_word_count; i++) {
191 ret_val = qla4_83xx_rd_reg_indirect(ha,
192 QLA83XX_FLASH_DIRECT_DATA(addr),
193 &u32_word);
194 if (ret_val == QLA_ERROR) {
195 ql4_printk(KERN_ERR, ha, "%s: failed to read addr 0x%x!\n",
196 __func__, addr);
197 goto exit_lockless_read;
198 }
199
200 *(__le32 *)p_data = le32_to_cpu(u32_word);
201 p_data = p_data + 4;
202 addr = addr + 4;
203 flash_offset = flash_offset + 4;
204
205 if (flash_offset > (QLA83XX_FLASH_SECTOR_SIZE - 1)) {
206 /* This write is needed once for each sector */
207 ret_val = qla4_83xx_wr_reg_indirect(ha,
208 QLA83XX_FLASH_DIRECT_WINDOW,
209 addr);
210 if (ret_val == QLA_ERROR) {
211 ql4_printk(KERN_ERR, ha, "%s: failed to write addr 0x%x to FLASH_DIRECT_WINDOW!\n",
212 __func__, addr);
213 goto exit_lockless_read;
214 }
215 flash_offset = 0;
216 }
217 }
218 } else {
219 /* Single sector read */
220 for (i = 0; i < u32_word_count; i++) {
221 ret_val = qla4_83xx_rd_reg_indirect(ha,
222 QLA83XX_FLASH_DIRECT_DATA(addr),
223 &u32_word);
224 if (ret_val == QLA_ERROR) {
225 ql4_printk(KERN_ERR, ha, "%s: failed to read addr 0x%x!\n",
226 __func__, addr);
227 goto exit_lockless_read;
228 }
229
230 *(__le32 *)p_data = le32_to_cpu(u32_word);
231 p_data = p_data + 4;
232 addr = addr + 4;
233 }
234 }
235
236exit_lockless_read:
237 return ret_val;
238}
239
240void qla4_83xx_rom_lock_recovery(struct scsi_qla_host *ha)
241{
242 if (qla4_83xx_flash_lock(ha))
243 ql4_printk(KERN_INFO, ha, "%s: Resetting rom lock\n", __func__);
244
245 /*
246 * We got the lock, or someone else is holding the lock
247 * since we are restting, forcefully unlock
248 */
249 qla4_83xx_flash_unlock(ha);
250}
251
252/**
253 * qla4_83xx_ms_mem_write_128b - Writes data to MS/off-chip memory
254 * @ha: Pointer to adapter structure
255 * @addr: Flash address to write to
256 * @data: Data to be written
257 * @count: word_count to be written
258 *
259 * Return: On success return QLA_SUCCESS
260 * On error return QLA_ERROR
261 **/
262static int qla4_83xx_ms_mem_write_128b(struct scsi_qla_host *ha, uint64_t addr,
263 uint32_t *data, uint32_t count)
264{
265 int i, j;
266 uint32_t agt_ctrl;
267 unsigned long flags;
268 int ret_val = QLA_SUCCESS;
269
270 /* Only 128-bit aligned access */
271 if (addr & 0xF) {
272 ret_val = QLA_ERROR;
273 goto exit_ms_mem_write;
274 }
275
276 write_lock_irqsave(&ha->hw_lock, flags);
277
278 /* Write address */
279 ret_val = qla4_83xx_wr_reg_indirect(ha, MD_MIU_TEST_AGT_ADDR_HI, 0);
280 if (ret_val == QLA_ERROR) {
281 ql4_printk(KERN_ERR, ha, "%s: write to AGT_ADDR_HI failed\n",
282 __func__);
283 goto exit_ms_mem_write_unlock;
284 }
285
286 for (i = 0; i < count; i++, addr += 16) {
287 if (!((QLA8XXX_ADDR_IN_RANGE(addr, QLA8XXX_ADDR_QDR_NET,
288 QLA8XXX_ADDR_QDR_NET_MAX)) ||
289 (QLA8XXX_ADDR_IN_RANGE(addr, QLA8XXX_ADDR_DDR_NET,
290 QLA8XXX_ADDR_DDR_NET_MAX)))) {
291 ret_val = QLA_ERROR;
292 goto exit_ms_mem_write_unlock;
293 }
294
295 ret_val = qla4_83xx_wr_reg_indirect(ha, MD_MIU_TEST_AGT_ADDR_LO,
296 addr);
297 /* Write data */
298 ret_val |= qla4_83xx_wr_reg_indirect(ha,
299 MD_MIU_TEST_AGT_WRDATA_LO,
300 *data++);
301 ret_val |= qla4_83xx_wr_reg_indirect(ha,
302 MD_MIU_TEST_AGT_WRDATA_HI,
303 *data++);
304 ret_val |= qla4_83xx_wr_reg_indirect(ha,
305 MD_MIU_TEST_AGT_WRDATA_ULO,
306 *data++);
307 ret_val |= qla4_83xx_wr_reg_indirect(ha,
308 MD_MIU_TEST_AGT_WRDATA_UHI,
309 *data++);
310 if (ret_val == QLA_ERROR) {
311 ql4_printk(KERN_ERR, ha, "%s: write to AGT_WRDATA failed\n",
312 __func__);
313 goto exit_ms_mem_write_unlock;
314 }
315
316 /* Check write status */
317 ret_val = qla4_83xx_wr_reg_indirect(ha, MD_MIU_TEST_AGT_CTRL,
318 MIU_TA_CTL_WRITE_ENABLE);
319 ret_val |= qla4_83xx_wr_reg_indirect(ha, MD_MIU_TEST_AGT_CTRL,
320 MIU_TA_CTL_WRITE_START);
321 if (ret_val == QLA_ERROR) {
322 ql4_printk(KERN_ERR, ha, "%s: write to AGT_CTRL failed\n",
323 __func__);
324 goto exit_ms_mem_write_unlock;
325 }
326
327 for (j = 0; j < MAX_CTL_CHECK; j++) {
328 ret_val = qla4_83xx_rd_reg_indirect(ha,
329 MD_MIU_TEST_AGT_CTRL,
330 &agt_ctrl);
331 if (ret_val == QLA_ERROR) {
332 ql4_printk(KERN_ERR, ha, "%s: failed to read MD_MIU_TEST_AGT_CTRL\n",
333 __func__);
334 goto exit_ms_mem_write_unlock;
335 }
336 if ((agt_ctrl & MIU_TA_CTL_BUSY) == 0)
337 break;
338 }
339
340 /* Status check failed */
341 if (j >= MAX_CTL_CHECK) {
342 printk_ratelimited(KERN_ERR "%s: MS memory write failed!\n",
343 __func__);
344 ret_val = QLA_ERROR;
345 goto exit_ms_mem_write_unlock;
346 }
347 }
348
349exit_ms_mem_write_unlock:
350 write_unlock_irqrestore(&ha->hw_lock, flags);
351
352exit_ms_mem_write:
353 return ret_val;
354}
355
356#define INTENT_TO_RECOVER 0x01
357#define PROCEED_TO_RECOVER 0x02
358
359static int qla4_83xx_lock_recovery(struct scsi_qla_host *ha)
360{
361
362 uint32_t lock = 0, lockid;
363 int ret_val = QLA_ERROR;
364
365 lockid = ha->isp_ops->rd_reg_direct(ha, QLA83XX_DRV_LOCKRECOVERY);
366
367 /* Check for other Recovery in progress, go wait */
368 if ((lockid & 0x3) != 0)
369 goto exit_lock_recovery;
370
371 /* Intent to Recover */
372 ha->isp_ops->wr_reg_direct(ha, QLA83XX_DRV_LOCKRECOVERY,
373 (ha->func_num << 2) | INTENT_TO_RECOVER);
374
375 msleep(200);
376
377 /* Check Intent to Recover is advertised */
378 lockid = ha->isp_ops->rd_reg_direct(ha, QLA83XX_DRV_LOCKRECOVERY);
379 if ((lockid & 0x3C) != (ha->func_num << 2))
380 goto exit_lock_recovery;
381
382 ql4_printk(KERN_INFO, ha, "%s: IDC Lock recovery initiated for func %d\n",
383 __func__, ha->func_num);
384
385 /* Proceed to Recover */
386 ha->isp_ops->wr_reg_direct(ha, QLA83XX_DRV_LOCKRECOVERY,
387 (ha->func_num << 2) | PROCEED_TO_RECOVER);
388
389 /* Force Unlock */
390 ha->isp_ops->wr_reg_direct(ha, QLA83XX_DRV_LOCK_ID, 0xFF);
391 ha->isp_ops->rd_reg_direct(ha, QLA83XX_DRV_UNLOCK);
392
393 /* Clear bits 0-5 in IDC_RECOVERY register*/
394 ha->isp_ops->wr_reg_direct(ha, QLA83XX_DRV_LOCKRECOVERY, 0);
395
396 /* Get lock */
397 lock = ha->isp_ops->rd_reg_direct(ha, QLA83XX_DRV_LOCK);
398 if (lock) {
399 lockid = ha->isp_ops->rd_reg_direct(ha, QLA83XX_DRV_LOCK_ID);
400 lockid = ((lockid + (1 << 8)) & ~0xFF) | ha->func_num;
401 ha->isp_ops->wr_reg_direct(ha, QLA83XX_DRV_LOCK_ID, lockid);
402 ret_val = QLA_SUCCESS;
403 }
404
405exit_lock_recovery:
406 return ret_val;
407}
408
409#define QLA83XX_DRV_LOCK_MSLEEP 200
410
411int qla4_83xx_drv_lock(struct scsi_qla_host *ha)
412{
413 int timeout = 0;
414 uint32_t status = 0;
415 int ret_val = QLA_SUCCESS;
416 uint32_t first_owner = 0;
417 uint32_t tmo_owner = 0;
418 uint32_t lock_id;
419 uint32_t func_num;
420 uint32_t lock_cnt;
421
422 while (status == 0) {
423 status = qla4_83xx_rd_reg(ha, QLA83XX_DRV_LOCK);
424 if (status) {
425 /* Increment Counter (8-31) and update func_num (0-7) on
426 * getting a successful lock */
427 lock_id = qla4_83xx_rd_reg(ha, QLA83XX_DRV_LOCK_ID);
428 lock_id = ((lock_id + (1 << 8)) & ~0xFF) | ha->func_num;
429 qla4_83xx_wr_reg(ha, QLA83XX_DRV_LOCK_ID, lock_id);
430 break;
431 }
432
433 if (timeout == 0)
434 /* Save counter + ID of function holding the lock for
435 * first failure */
436 first_owner = ha->isp_ops->rd_reg_direct(ha,
437 QLA83XX_DRV_LOCK_ID);
438
439 if (++timeout >=
440 (QLA83XX_DRV_LOCK_TIMEOUT / QLA83XX_DRV_LOCK_MSLEEP)) {
441 tmo_owner = qla4_83xx_rd_reg(ha, QLA83XX_DRV_LOCK_ID);
442 func_num = tmo_owner & 0xFF;
443 lock_cnt = tmo_owner >> 8;
444 ql4_printk(KERN_INFO, ha, "%s: Lock by func %d failed after 2s, lock held by func %d, lock count %d, first_owner %d\n",
445 __func__, ha->func_num, func_num, lock_cnt,
446 (first_owner & 0xFF));
447
448 if (first_owner != tmo_owner) {
449 /* Some other driver got lock, OR same driver
450 * got lock again (counter value changed), when
451 * we were waiting for lock.
452 * Retry for another 2 sec */
453 ql4_printk(KERN_INFO, ha, "%s: IDC lock failed for func %d\n",
454 __func__, ha->func_num);
455 timeout = 0;
456 } else {
457 /* Same driver holding lock > 2sec.
458 * Force Recovery */
459 ret_val = qla4_83xx_lock_recovery(ha);
460 if (ret_val == QLA_SUCCESS) {
461 /* Recovered and got lock */
462 ql4_printk(KERN_INFO, ha, "%s: IDC lock Recovery by %d successful\n",
463 __func__, ha->func_num);
464 break;
465 }
466 /* Recovery Failed, some other function
467 * has the lock, wait for 2secs and retry */
468 ql4_printk(KERN_INFO, ha, "%s: IDC lock Recovery by %d failed, Retrying timout\n",
469 __func__, ha->func_num);
470 timeout = 0;
471 }
472 }
473 msleep(QLA83XX_DRV_LOCK_MSLEEP);
474 }
475
476 return ret_val;
477}
478
479void qla4_83xx_drv_unlock(struct scsi_qla_host *ha)
480{
481 int id;
482
483 id = qla4_83xx_rd_reg(ha, QLA83XX_DRV_LOCK_ID);
484
485 if ((id & 0xFF) != ha->func_num) {
486 ql4_printk(KERN_ERR, ha, "%s: IDC Unlock by %d failed, lock owner is %d\n",
487 __func__, ha->func_num, (id & 0xFF));
488 return;
489 }
490
491 /* Keep lock counter value, update the ha->func_num to 0xFF */
492 qla4_83xx_wr_reg(ha, QLA83XX_DRV_LOCK_ID, (id | 0xFF));
493 qla4_83xx_rd_reg(ha, QLA83XX_DRV_UNLOCK);
494}
495
496void qla4_83xx_set_idc_dontreset(struct scsi_qla_host *ha)
497{
498 uint32_t idc_ctrl;
499
500 idc_ctrl = qla4_83xx_rd_reg(ha, QLA83XX_IDC_DRV_CTRL);
501 idc_ctrl |= DONTRESET_BIT0;
502 qla4_83xx_wr_reg(ha, QLA83XX_IDC_DRV_CTRL, idc_ctrl);
503 DEBUG2(ql4_printk(KERN_INFO, ha, "%s: idc_ctrl = %d\n", __func__,
504 idc_ctrl));
505}
506
507void qla4_83xx_clear_idc_dontreset(struct scsi_qla_host *ha)
508{
509 uint32_t idc_ctrl;
510
511 idc_ctrl = qla4_83xx_rd_reg(ha, QLA83XX_IDC_DRV_CTRL);
512 idc_ctrl &= ~DONTRESET_BIT0;
513 qla4_83xx_wr_reg(ha, QLA83XX_IDC_DRV_CTRL, idc_ctrl);
514 DEBUG2(ql4_printk(KERN_INFO, ha, "%s: idc_ctrl = %d\n", __func__,
515 idc_ctrl));
516}
517
518int qla4_83xx_idc_dontreset(struct scsi_qla_host *ha)
519{
520 uint32_t idc_ctrl;
521
522 idc_ctrl = qla4_83xx_rd_reg(ha, QLA83XX_IDC_DRV_CTRL);
523 return idc_ctrl & DONTRESET_BIT0;
524}
525
526/*-------------------------IDC State Machine ---------------------*/
527
528enum {
529 UNKNOWN_CLASS = 0,
530 NIC_CLASS,
531 FCOE_CLASS,
532 ISCSI_CLASS
533};
534
535struct device_info {
536 int func_num;
537 int device_type;
538 int port_num;
539};
540
541static int qla4_83xx_can_perform_reset(struct scsi_qla_host *ha)
542{
543 uint32_t drv_active;
544 uint32_t dev_part, dev_part1, dev_part2;
545 int i;
546 struct device_info device_map[16];
547 int func_nibble;
548 int nibble;
549 int nic_present = 0;
550 int iscsi_present = 0;
551 int iscsi_func_low = 0;
552
553 /* Use the dev_partition register to determine the PCI function number
554 * and then check drv_active register to see which driver is loaded */
555 dev_part1 = qla4_83xx_rd_reg(ha,
556 ha->reg_tbl[QLA8XXX_CRB_DEV_PART_INFO]);
557 dev_part2 = qla4_83xx_rd_reg(ha, QLA83XX_CRB_DEV_PART_INFO2);
558 drv_active = qla4_83xx_rd_reg(ha, ha->reg_tbl[QLA8XXX_CRB_DRV_ACTIVE]);
559
560 /* Each function has 4 bits in dev_partition Info register,
561 * Lower 2 bits - device type, Upper 2 bits - physical port number */
562 dev_part = dev_part1;
563 for (i = nibble = 0; i <= 15; i++, nibble++) {
564 func_nibble = dev_part & (0xF << (nibble * 4));
565 func_nibble >>= (nibble * 4);
566 device_map[i].func_num = i;
567 device_map[i].device_type = func_nibble & 0x3;
568 device_map[i].port_num = func_nibble & 0xC;
569
570 if (device_map[i].device_type == NIC_CLASS) {
571 if (drv_active & (1 << device_map[i].func_num)) {
572 nic_present++;
573 break;
574 }
575 } else if (device_map[i].device_type == ISCSI_CLASS) {
576 if (drv_active & (1 << device_map[i].func_num)) {
577 if (!iscsi_present ||
578 (iscsi_present &&
579 (iscsi_func_low > device_map[i].func_num)))
580 iscsi_func_low = device_map[i].func_num;
581
582 iscsi_present++;
583 }
584 }
585
586 /* For function_num[8..15] get info from dev_part2 register */
587 if (nibble == 7) {
588 nibble = 0;
589 dev_part = dev_part2;
590 }
591 }
592
593 /* NIC, iSCSI and FCOE are the Reset owners based on order, NIC gets
594 * precedence over iSCSI and FCOE and iSCSI over FCOE, based on drivers
595 * present. */
596 if (!nic_present && (ha->func_num == iscsi_func_low)) {
597 DEBUG2(ql4_printk(KERN_INFO, ha,
598 "%s: can reset - NIC not present and lower iSCSI function is %d\n",
599 __func__, ha->func_num));
600 return 1;
601 }
602
603 return 0;
604}
605
606/**
607 * qla4_83xx_need_reset_handler - Code to start reset sequence
608 * @ha: pointer to adapter structure
609 *
610 * Note: IDC lock must be held upon entry
611 **/
612void qla4_83xx_need_reset_handler(struct scsi_qla_host *ha)
613{
614 uint32_t dev_state, drv_state, drv_active;
615 unsigned long reset_timeout, dev_init_timeout;
616
617 ql4_printk(KERN_INFO, ha, "%s: Performing ISP error recovery\n",
618 __func__);
619
620 if (!test_bit(AF_8XXX_RST_OWNER, &ha->flags)) {
621 DEBUG2(ql4_printk(KERN_INFO, ha, "%s: reset acknowledged\n",
622 __func__));
623 qla4_8xxx_set_rst_ready(ha);
624
625 /* Non-reset owners ACK Reset and wait for device INIT state
626 * as part of Reset Recovery by Reset Owner */
627 dev_init_timeout = jiffies + (ha->nx_dev_init_timeout * HZ);
628
629 do {
630 if (time_after_eq(jiffies, dev_init_timeout)) {
631 ql4_printk(KERN_INFO, ha, "%s: Non Reset owner dev init timeout\n",
632 __func__);
633 break;
634 }
635
636 ha->isp_ops->idc_unlock(ha);
637 msleep(1000);
638 ha->isp_ops->idc_lock(ha);
639
640 dev_state = qla4_8xxx_rd_direct(ha,
641 QLA8XXX_CRB_DEV_STATE);
642 } while (dev_state == QLA8XXX_DEV_NEED_RESET);
643 } else {
644 qla4_8xxx_set_rst_ready(ha);
645 reset_timeout = jiffies + (ha->nx_reset_timeout * HZ);
646 drv_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_STATE);
647 drv_active = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_ACTIVE);
648
649 ql4_printk(KERN_INFO, ha, "%s: drv_state = 0x%x, drv_active = 0x%x\n",
650 __func__, drv_state, drv_active);
651
652 while (drv_state != drv_active) {
653 if (time_after_eq(jiffies, reset_timeout)) {
654 ql4_printk(KERN_INFO, ha, "%s: %s: RESET TIMEOUT! drv_state: 0x%08x, drv_active: 0x%08x\n",
655 __func__, DRIVER_NAME, drv_state,
656 drv_active);
657 break;
658 }
659
660 ha->isp_ops->idc_unlock(ha);
661 msleep(1000);
662 ha->isp_ops->idc_lock(ha);
663
664 drv_state = qla4_8xxx_rd_direct(ha,
665 QLA8XXX_CRB_DRV_STATE);
666 drv_active = qla4_8xxx_rd_direct(ha,
667 QLA8XXX_CRB_DRV_ACTIVE);
668 }
669
670 if (drv_state != drv_active) {
671 ql4_printk(KERN_INFO, ha, "%s: Reset_owner turning off drv_active of non-acking function 0x%x\n",
672 __func__, (drv_active ^ drv_state));
673 drv_active = drv_active & drv_state;
674 qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_ACTIVE,
675 drv_active);
676 }
677
678 clear_bit(AF_8XXX_RST_OWNER, &ha->flags);
679 /* Start Reset Recovery */
680 qla4_8xxx_device_bootstrap(ha);
681 }
682}
683
684void qla4_83xx_get_idc_param(struct scsi_qla_host *ha)
685{
686 uint32_t idc_params, ret_val;
687
688 ret_val = qla4_83xx_flash_read_u32(ha, QLA83XX_IDC_PARAM_ADDR,
689 (uint8_t *)&idc_params, 1);
690 if (ret_val == QLA_SUCCESS) {
691 ha->nx_dev_init_timeout = idc_params & 0xFFFF;
692 ha->nx_reset_timeout = (idc_params >> 16) & 0xFFFF;
693 } else {
694 ha->nx_dev_init_timeout = ROM_DEV_INIT_TIMEOUT;
695 ha->nx_reset_timeout = ROM_DRV_RESET_ACK_TIMEOUT;
696 }
697
698 DEBUG2(ql4_printk(KERN_DEBUG, ha,
699 "%s: ha->nx_dev_init_timeout = %d, ha->nx_reset_timeout = %d\n",
700 __func__, ha->nx_dev_init_timeout,
701 ha->nx_reset_timeout));
702}
703
704/*-------------------------Reset Sequence Functions-----------------------*/
705
706static void qla4_83xx_dump_reset_seq_hdr(struct scsi_qla_host *ha)
707{
708 uint8_t *phdr;
709
710 if (!ha->reset_tmplt.buff) {
711 ql4_printk(KERN_ERR, ha, "%s: Error: Invalid reset_seq_template\n",
712 __func__);
713 return;
714 }
715
716 phdr = ha->reset_tmplt.buff;
717
718 DEBUG2(ql4_printk(KERN_INFO, ha,
719 "Reset Template: 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X\n",
720 *phdr, *(phdr+1), *(phdr+2), *(phdr+3), *(phdr+4),
721 *(phdr+5), *(phdr+6), *(phdr+7), *(phdr + 8),
722 *(phdr+9), *(phdr+10), *(phdr+11), *(phdr+12),
723 *(phdr+13), *(phdr+14), *(phdr+15)));
724}
725
726static int qla4_83xx_copy_bootloader(struct scsi_qla_host *ha)
727{
728 uint8_t *p_cache;
729 uint32_t src, count, size;
730 uint64_t dest;
731 int ret_val = QLA_SUCCESS;
732
733 src = QLA83XX_BOOTLOADER_FLASH_ADDR;
734 dest = qla4_83xx_rd_reg(ha, QLA83XX_BOOTLOADER_ADDR);
735 size = qla4_83xx_rd_reg(ha, QLA83XX_BOOTLOADER_SIZE);
736
737 /* 128 bit alignment check */
738 if (size & 0xF)
739 size = (size + 16) & ~0xF;
740
741 /* 16 byte count */
742 count = size/16;
743
744 p_cache = vmalloc(size);
745 if (p_cache == NULL) {
746 ql4_printk(KERN_ERR, ha, "%s: Failed to allocate memory for boot loader cache\n",
747 __func__);
748 ret_val = QLA_ERROR;
749 goto exit_copy_bootloader;
750 }
751
752 ret_val = qla4_83xx_lockless_flash_read_u32(ha, src, p_cache,
753 size / sizeof(uint32_t));
754 if (ret_val == QLA_ERROR) {
755 ql4_printk(KERN_ERR, ha, "%s: Error reading firmware from flash\n",
756 __func__);
757 goto exit_copy_error;
758 }
759 DEBUG2(ql4_printk(KERN_INFO, ha, "%s: Read firmware from flash\n",
760 __func__));
761
762 /* 128 bit/16 byte write to MS memory */
763 ret_val = qla4_83xx_ms_mem_write_128b(ha, dest, (uint32_t *)p_cache,
764 count);
765 if (ret_val == QLA_ERROR) {
766 ql4_printk(KERN_ERR, ha, "%s: Error writing firmware to MS\n",
767 __func__);
768 goto exit_copy_error;
769 }
770
771 DEBUG2(ql4_printk(KERN_INFO, ha, "%s: Wrote firmware size %d to MS\n",
772 __func__, size));
773
774exit_copy_error:
775 vfree(p_cache);
776
777exit_copy_bootloader:
778 return ret_val;
779}
780
781static int qla4_83xx_check_cmd_peg_status(struct scsi_qla_host *ha)
782{
783 uint32_t val, ret_val = QLA_ERROR;
784 int retries = CRB_CMDPEG_CHECK_RETRY_COUNT;
785
786 do {
787 val = qla4_83xx_rd_reg(ha, QLA83XX_CMDPEG_STATE);
788 if (val == PHAN_INITIALIZE_COMPLETE) {
789 DEBUG2(ql4_printk(KERN_INFO, ha,
790 "%s: Command Peg initialization complete. State=0x%x\n",
791 __func__, val));
792 ret_val = QLA_SUCCESS;
793 break;
794 }
795 msleep(CRB_CMDPEG_CHECK_DELAY);
796 } while (--retries);
797
798 return ret_val;
799}
800
801/**
802 * qla4_83xx_poll_reg - Poll the given CRB addr for duration msecs till
803 * value read ANDed with test_mask is equal to test_result.
804 *
805 * @ha : Pointer to adapter structure
806 * @addr : CRB register address
807 * @duration : Poll for total of "duration" msecs
808 * @test_mask : Mask value read with "test_mask"
809 * @test_result : Compare (value&test_mask) with test_result.
810 **/
811static int qla4_83xx_poll_reg(struct scsi_qla_host *ha, uint32_t addr,
812 int duration, uint32_t test_mask,
813 uint32_t test_result)
814{
815 uint32_t value;
816 uint8_t retries;
817 int ret_val = QLA_SUCCESS;
818
819 ret_val = qla4_83xx_rd_reg_indirect(ha, addr, &value);
820 if (ret_val == QLA_ERROR)
821 goto exit_poll_reg;
822
823 retries = duration / 10;
824 do {
825 if ((value & test_mask) != test_result) {
826 msleep(duration / 10);
827 ret_val = qla4_83xx_rd_reg_indirect(ha, addr, &value);
828 if (ret_val == QLA_ERROR)
829 goto exit_poll_reg;
830
831 ret_val = QLA_ERROR;
832 } else {
833 ret_val = QLA_SUCCESS;
834 break;
835 }
836 } while (retries--);
837
838exit_poll_reg:
839 if (ret_val == QLA_ERROR) {
840 ha->reset_tmplt.seq_error++;
841 ql4_printk(KERN_ERR, ha, "%s: Poll Failed: 0x%08x 0x%08x 0x%08x\n",
842 __func__, value, test_mask, test_result);
843 }
844
845 return ret_val;
846}
847
848static int qla4_83xx_reset_seq_checksum_test(struct scsi_qla_host *ha)
849{
850 uint32_t sum = 0;
851 uint16_t *buff = (uint16_t *)ha->reset_tmplt.buff;
852 int u16_count = ha->reset_tmplt.hdr->size / sizeof(uint16_t);
853 int ret_val;
854
855 while (u16_count-- > 0)
856 sum += *buff++;
857
858 while (sum >> 16)
859 sum = (sum & 0xFFFF) + (sum >> 16);
860
861 /* checksum of 0 indicates a valid template */
862 if (~sum) {
863 ret_val = QLA_SUCCESS;
864 } else {
865 ql4_printk(KERN_ERR, ha, "%s: Reset seq checksum failed\n",
866 __func__);
867 ret_val = QLA_ERROR;
868 }
869
870 return ret_val;
871}
872
873/**
874 * qla4_83xx_read_reset_template - Read Reset Template from Flash
875 * @ha: Pointer to adapter structure
876 **/
877void qla4_83xx_read_reset_template(struct scsi_qla_host *ha)
878{
879 uint8_t *p_buff;
880 uint32_t addr, tmplt_hdr_def_size, tmplt_hdr_size;
881 uint32_t ret_val;
882
883 ha->reset_tmplt.seq_error = 0;
884 ha->reset_tmplt.buff = vmalloc(QLA83XX_RESTART_TEMPLATE_SIZE);
885 if (ha->reset_tmplt.buff == NULL) {
886 ql4_printk(KERN_ERR, ha, "%s: Failed to allocate reset template resources\n",
887 __func__);
888 goto exit_read_reset_template;
889 }
890
891 p_buff = ha->reset_tmplt.buff;
892 addr = QLA83XX_RESET_TEMPLATE_ADDR;
893
894 tmplt_hdr_def_size = sizeof(struct qla4_83xx_reset_template_hdr) /
895 sizeof(uint32_t);
896
897 DEBUG2(ql4_printk(KERN_INFO, ha,
898 "%s: Read template hdr size %d from Flash\n",
899 __func__, tmplt_hdr_def_size));
900
901 /* Copy template header from flash */
902 ret_val = qla4_83xx_flash_read_u32(ha, addr, p_buff,
903 tmplt_hdr_def_size);
904 if (ret_val != QLA_SUCCESS) {
905 ql4_printk(KERN_ERR, ha, "%s: Failed to read reset template\n",
906 __func__);
907 goto exit_read_template_error;
908 }
909
910 ha->reset_tmplt.hdr =
911 (struct qla4_83xx_reset_template_hdr *)ha->reset_tmplt.buff;
912
913 /* Validate the template header size and signature */
914 tmplt_hdr_size = ha->reset_tmplt.hdr->hdr_size/sizeof(uint32_t);
915 if ((tmplt_hdr_size != tmplt_hdr_def_size) ||
916 (ha->reset_tmplt.hdr->signature != RESET_TMPLT_HDR_SIGNATURE)) {
917 ql4_printk(KERN_ERR, ha, "%s: Template Header size %d is invalid, tmplt_hdr_def_size %d\n",
918 __func__, tmplt_hdr_size, tmplt_hdr_def_size);
919 goto exit_read_template_error;
920 }
921
922 addr = QLA83XX_RESET_TEMPLATE_ADDR + ha->reset_tmplt.hdr->hdr_size;
923 p_buff = ha->reset_tmplt.buff + ha->reset_tmplt.hdr->hdr_size;
924 tmplt_hdr_def_size = (ha->reset_tmplt.hdr->size -
925 ha->reset_tmplt.hdr->hdr_size) / sizeof(uint32_t);
926
927 DEBUG2(ql4_printk(KERN_INFO, ha,
928 "%s: Read rest of the template size %d\n",
929 __func__, ha->reset_tmplt.hdr->size));
930
931 /* Copy rest of the template */
932 ret_val = qla4_83xx_flash_read_u32(ha, addr, p_buff,
933 tmplt_hdr_def_size);
934 if (ret_val != QLA_SUCCESS) {
935 ql4_printk(KERN_ERR, ha, "%s: Failed to read reset tempelate\n",
936 __func__);
937 goto exit_read_template_error;
938 }
939
940 /* Integrity check */
941 if (qla4_83xx_reset_seq_checksum_test(ha)) {
942 ql4_printk(KERN_ERR, ha, "%s: Reset Seq checksum failed!\n",
943 __func__);
944 goto exit_read_template_error;
945 }
946 DEBUG2(ql4_printk(KERN_INFO, ha,
947 "%s: Reset Seq checksum passed, Get stop, start and init seq offsets\n",
948 __func__));
949
950 /* Get STOP, START, INIT sequence offsets */
951 ha->reset_tmplt.init_offset = ha->reset_tmplt.buff +
952 ha->reset_tmplt.hdr->init_seq_offset;
953 ha->reset_tmplt.start_offset = ha->reset_tmplt.buff +
954 ha->reset_tmplt.hdr->start_seq_offset;
955 ha->reset_tmplt.stop_offset = ha->reset_tmplt.buff +
956 ha->reset_tmplt.hdr->hdr_size;
957 qla4_83xx_dump_reset_seq_hdr(ha);
958
959 goto exit_read_reset_template;
960
961exit_read_template_error:
962 vfree(ha->reset_tmplt.buff);
963
964exit_read_reset_template:
965 return;
966}
967
968/**
969 * qla4_83xx_read_write_crb_reg - Read from raddr and write value to waddr.
970 *
971 * @ha : Pointer to adapter structure
972 * @raddr : CRB address to read from
973 * @waddr : CRB address to write to
974 **/
975static void qla4_83xx_read_write_crb_reg(struct scsi_qla_host *ha,
976 uint32_t raddr, uint32_t waddr)
977{
978 uint32_t value;
979
980 qla4_83xx_rd_reg_indirect(ha, raddr, &value);
981 qla4_83xx_wr_reg_indirect(ha, waddr, value);
982}
983
984/**
985 * qla4_83xx_rmw_crb_reg - Read Modify Write crb register
986 *
987 * This function read value from raddr, AND with test_mask,
988 * Shift Left,Right/OR/XOR with values RMW header and write value to waddr.
989 *
990 * @ha : Pointer to adapter structure
991 * @raddr : CRB address to read from
992 * @waddr : CRB address to write to
993 * @p_rmw_hdr : header with shift/or/xor values.
994 **/
995static void qla4_83xx_rmw_crb_reg(struct scsi_qla_host *ha, uint32_t raddr,
996 uint32_t waddr,
997 struct qla4_83xx_rmw *p_rmw_hdr)
998{
999 uint32_t value;
1000
1001 if (p_rmw_hdr->index_a)
1002 value = ha->reset_tmplt.array[p_rmw_hdr->index_a];
1003 else
1004 qla4_83xx_rd_reg_indirect(ha, raddr, &value);
1005
1006 value &= p_rmw_hdr->test_mask;
1007 value <<= p_rmw_hdr->shl;
1008 value >>= p_rmw_hdr->shr;
1009 value |= p_rmw_hdr->or_value;
1010 value ^= p_rmw_hdr->xor_value;
1011
1012 qla4_83xx_wr_reg_indirect(ha, waddr, value);
1013
1014 return;
1015}
1016
1017static void qla4_83xx_write_list(struct scsi_qla_host *ha,
1018 struct qla4_83xx_reset_entry_hdr *p_hdr)
1019{
1020 struct qla4_83xx_entry *p_entry;
1021 uint32_t i;
1022
1023 p_entry = (struct qla4_83xx_entry *)
1024 ((char *)p_hdr + sizeof(struct qla4_83xx_reset_entry_hdr));
1025
1026 for (i = 0; i < p_hdr->count; i++, p_entry++) {
1027 qla4_83xx_wr_reg_indirect(ha, p_entry->arg1, p_entry->arg2);
1028 if (p_hdr->delay)
1029 udelay((uint32_t)(p_hdr->delay));
1030 }
1031}
1032
1033static void qla4_83xx_read_write_list(struct scsi_qla_host *ha,
1034 struct qla4_83xx_reset_entry_hdr *p_hdr)
1035{
1036 struct qla4_83xx_entry *p_entry;
1037 uint32_t i;
1038
1039 p_entry = (struct qla4_83xx_entry *)
1040 ((char *)p_hdr + sizeof(struct qla4_83xx_reset_entry_hdr));
1041
1042 for (i = 0; i < p_hdr->count; i++, p_entry++) {
1043 qla4_83xx_read_write_crb_reg(ha, p_entry->arg1, p_entry->arg2);
1044 if (p_hdr->delay)
1045 udelay((uint32_t)(p_hdr->delay));
1046 }
1047}
1048
1049static void qla4_83xx_poll_list(struct scsi_qla_host *ha,
1050 struct qla4_83xx_reset_entry_hdr *p_hdr)
1051{
1052 long delay;
1053 struct qla4_83xx_entry *p_entry;
1054 struct qla4_83xx_poll *p_poll;
1055 uint32_t i;
1056 uint32_t value;
1057
1058 p_poll = (struct qla4_83xx_poll *)
1059 ((char *)p_hdr + sizeof(struct qla4_83xx_reset_entry_hdr));
1060
1061 /* Entries start after 8 byte qla4_83xx_poll, poll header contains
1062 * the test_mask, test_value. */
1063 p_entry = (struct qla4_83xx_entry *)((char *)p_poll +
1064 sizeof(struct qla4_83xx_poll));
1065
1066 delay = (long)p_hdr->delay;
1067 if (!delay) {
1068 for (i = 0; i < p_hdr->count; i++, p_entry++) {
1069 qla4_83xx_poll_reg(ha, p_entry->arg1, delay,
1070 p_poll->test_mask,
1071 p_poll->test_value);
1072 }
1073 } else {
1074 for (i = 0; i < p_hdr->count; i++, p_entry++) {
1075 if (qla4_83xx_poll_reg(ha, p_entry->arg1, delay,
1076 p_poll->test_mask,
1077 p_poll->test_value)) {
1078 qla4_83xx_rd_reg_indirect(ha, p_entry->arg1,
1079 &value);
1080 qla4_83xx_rd_reg_indirect(ha, p_entry->arg2,
1081 &value);
1082 }
1083 }
1084 }
1085}
1086
1087static void qla4_83xx_poll_write_list(struct scsi_qla_host *ha,
1088 struct qla4_83xx_reset_entry_hdr *p_hdr)
1089{
1090 long delay;
1091 struct qla4_83xx_quad_entry *p_entry;
1092 struct qla4_83xx_poll *p_poll;
1093 uint32_t i;
1094
1095 p_poll = (struct qla4_83xx_poll *)
1096 ((char *)p_hdr + sizeof(struct qla4_83xx_reset_entry_hdr));
1097 p_entry = (struct qla4_83xx_quad_entry *)
1098 ((char *)p_poll + sizeof(struct qla4_83xx_poll));
1099 delay = (long)p_hdr->delay;
1100
1101 for (i = 0; i < p_hdr->count; i++, p_entry++) {
1102 qla4_83xx_wr_reg_indirect(ha, p_entry->dr_addr,
1103 p_entry->dr_value);
1104 qla4_83xx_wr_reg_indirect(ha, p_entry->ar_addr,
1105 p_entry->ar_value);
1106 if (delay) {
1107 if (qla4_83xx_poll_reg(ha, p_entry->ar_addr, delay,
1108 p_poll->test_mask,
1109 p_poll->test_value)) {
1110 DEBUG2(ql4_printk(KERN_INFO, ha,
1111 "%s: Timeout Error: poll list, item_num %d, entry_num %d\n",
1112 __func__, i,
1113 ha->reset_tmplt.seq_index));
1114 }
1115 }
1116 }
1117}
1118
1119static void qla4_83xx_read_modify_write(struct scsi_qla_host *ha,
1120 struct qla4_83xx_reset_entry_hdr *p_hdr)
1121{
1122 struct qla4_83xx_entry *p_entry;
1123 struct qla4_83xx_rmw *p_rmw_hdr;
1124 uint32_t i;
1125
1126 p_rmw_hdr = (struct qla4_83xx_rmw *)
1127 ((char *)p_hdr + sizeof(struct qla4_83xx_reset_entry_hdr));
1128 p_entry = (struct qla4_83xx_entry *)
1129 ((char *)p_rmw_hdr + sizeof(struct qla4_83xx_rmw));
1130
1131 for (i = 0; i < p_hdr->count; i++, p_entry++) {
1132 qla4_83xx_rmw_crb_reg(ha, p_entry->arg1, p_entry->arg2,
1133 p_rmw_hdr);
1134 if (p_hdr->delay)
1135 udelay((uint32_t)(p_hdr->delay));
1136 }
1137}
1138
1139static void qla4_83xx_pause(struct scsi_qla_host *ha,
1140 struct qla4_83xx_reset_entry_hdr *p_hdr)
1141{
1142 if (p_hdr->delay)
1143 mdelay((uint32_t)((long)p_hdr->delay));
1144}
1145
1146static void qla4_83xx_poll_read_list(struct scsi_qla_host *ha,
1147 struct qla4_83xx_reset_entry_hdr *p_hdr)
1148{
1149 long delay;
1150 int index;
1151 struct qla4_83xx_quad_entry *p_entry;
1152 struct qla4_83xx_poll *p_poll;
1153 uint32_t i;
1154 uint32_t value;
1155
1156 p_poll = (struct qla4_83xx_poll *)
1157 ((char *)p_hdr + sizeof(struct qla4_83xx_reset_entry_hdr));
1158 p_entry = (struct qla4_83xx_quad_entry *)
1159 ((char *)p_poll + sizeof(struct qla4_83xx_poll));
1160 delay = (long)p_hdr->delay;
1161
1162 for (i = 0; i < p_hdr->count; i++, p_entry++) {
1163 qla4_83xx_wr_reg_indirect(ha, p_entry->ar_addr,
1164 p_entry->ar_value);
1165 if (delay) {
1166 if (qla4_83xx_poll_reg(ha, p_entry->ar_addr, delay,
1167 p_poll->test_mask,
1168 p_poll->test_value)) {
1169 DEBUG2(ql4_printk(KERN_INFO, ha,
1170 "%s: Timeout Error: poll list, Item_num %d, entry_num %d\n",
1171 __func__, i,
1172 ha->reset_tmplt.seq_index));
1173 } else {
1174 index = ha->reset_tmplt.array_index;
1175 qla4_83xx_rd_reg_indirect(ha, p_entry->dr_addr,
1176 &value);
1177 ha->reset_tmplt.array[index++] = value;
1178
1179 if (index == QLA83XX_MAX_RESET_SEQ_ENTRIES)
1180 ha->reset_tmplt.array_index = 1;
1181 }
1182 }
1183 }
1184}
1185
1186static void qla4_83xx_seq_end(struct scsi_qla_host *ha,
1187 struct qla4_83xx_reset_entry_hdr *p_hdr)
1188{
1189 ha->reset_tmplt.seq_end = 1;
1190}
1191
1192static void qla4_83xx_template_end(struct scsi_qla_host *ha,
1193 struct qla4_83xx_reset_entry_hdr *p_hdr)
1194{
1195 ha->reset_tmplt.template_end = 1;
1196
1197 if (ha->reset_tmplt.seq_error == 0) {
1198 DEBUG2(ql4_printk(KERN_INFO, ha,
1199 "%s: Reset sequence completed SUCCESSFULLY.\n",
1200 __func__));
1201 } else {
1202 ql4_printk(KERN_ERR, ha, "%s: Reset sequence completed with some timeout errors.\n",
1203 __func__);
1204 }
1205}
1206
1207/**
1208 * qla4_83xx_process_reset_template - Process reset template.
1209 *
1210 * Process all entries in reset template till entry with SEQ_END opcode,
1211 * which indicates end of the reset template processing. Each entry has a
1212 * Reset Entry header, entry opcode/command, with size of the entry, number
1213 * of entries in sub-sequence and delay in microsecs or timeout in millisecs.
1214 *
1215 * @ha : Pointer to adapter structure
1216 * @p_buff : Common reset entry header.
1217 **/
1218static void qla4_83xx_process_reset_template(struct scsi_qla_host *ha,
1219 char *p_buff)
1220{
1221 int index, entries;
1222 struct qla4_83xx_reset_entry_hdr *p_hdr;
1223 char *p_entry = p_buff;
1224
1225 ha->reset_tmplt.seq_end = 0;
1226 ha->reset_tmplt.template_end = 0;
1227 entries = ha->reset_tmplt.hdr->entries;
1228 index = ha->reset_tmplt.seq_index;
1229
1230 for (; (!ha->reset_tmplt.seq_end) && (index < entries); index++) {
1231
1232 p_hdr = (struct qla4_83xx_reset_entry_hdr *)p_entry;
1233 switch (p_hdr->cmd) {
1234 case OPCODE_NOP:
1235 break;
1236 case OPCODE_WRITE_LIST:
1237 qla4_83xx_write_list(ha, p_hdr);
1238 break;
1239 case OPCODE_READ_WRITE_LIST:
1240 qla4_83xx_read_write_list(ha, p_hdr);
1241 break;
1242 case OPCODE_POLL_LIST:
1243 qla4_83xx_poll_list(ha, p_hdr);
1244 break;
1245 case OPCODE_POLL_WRITE_LIST:
1246 qla4_83xx_poll_write_list(ha, p_hdr);
1247 break;
1248 case OPCODE_READ_MODIFY_WRITE:
1249 qla4_83xx_read_modify_write(ha, p_hdr);
1250 break;
1251 case OPCODE_SEQ_PAUSE:
1252 qla4_83xx_pause(ha, p_hdr);
1253 break;
1254 case OPCODE_SEQ_END:
1255 qla4_83xx_seq_end(ha, p_hdr);
1256 break;
1257 case OPCODE_TMPL_END:
1258 qla4_83xx_template_end(ha, p_hdr);
1259 break;
1260 case OPCODE_POLL_READ_LIST:
1261 qla4_83xx_poll_read_list(ha, p_hdr);
1262 break;
1263 default:
1264 ql4_printk(KERN_ERR, ha, "%s: Unknown command ==> 0x%04x on entry = %d\n",
1265 __func__, p_hdr->cmd, index);
1266 break;
1267 }
1268
1269 /* Set pointer to next entry in the sequence. */
1270 p_entry += p_hdr->size;
1271 }
1272
1273 ha->reset_tmplt.seq_index = index;
1274}
1275
1276static void qla4_83xx_process_stop_seq(struct scsi_qla_host *ha)
1277{
1278 ha->reset_tmplt.seq_index = 0;
1279 qla4_83xx_process_reset_template(ha, ha->reset_tmplt.stop_offset);
1280
1281 if (ha->reset_tmplt.seq_end != 1)
1282 ql4_printk(KERN_ERR, ha, "%s: Abrupt STOP Sub-Sequence end.\n",
1283 __func__);
1284}
1285
1286static void qla4_83xx_process_start_seq(struct scsi_qla_host *ha)
1287{
1288 qla4_83xx_process_reset_template(ha, ha->reset_tmplt.start_offset);
1289
1290 if (ha->reset_tmplt.template_end != 1)
1291 ql4_printk(KERN_ERR, ha, "%s: Abrupt START Sub-Sequence end.\n",
1292 __func__);
1293}
1294
1295static void qla4_83xx_process_init_seq(struct scsi_qla_host *ha)
1296{
1297 qla4_83xx_process_reset_template(ha, ha->reset_tmplt.init_offset);
1298
1299 if (ha->reset_tmplt.seq_end != 1)
1300 ql4_printk(KERN_ERR, ha, "%s: Abrupt INIT Sub-Sequence end.\n",
1301 __func__);
1302}
1303
1304static int qla4_83xx_restart(struct scsi_qla_host *ha)
1305{
1306 int ret_val = QLA_SUCCESS;
1307
1308 qla4_83xx_process_stop_seq(ha);
1309
1310 /* Collect minidump*/
1311 if (!test_and_clear_bit(AF_83XX_NO_FW_DUMP, &ha->flags))
1312 qla4_8xxx_get_minidump(ha);
1313
1314 qla4_83xx_process_init_seq(ha);
1315
1316 if (qla4_83xx_copy_bootloader(ha)) {
1317 ql4_printk(KERN_ERR, ha, "%s: Copy bootloader, firmware restart failed!\n",
1318 __func__);
1319 ret_val = QLA_ERROR;
1320 goto exit_restart;
1321 }
1322
1323 qla4_83xx_wr_reg(ha, QLA83XX_FW_IMAGE_VALID, QLA83XX_BOOT_FROM_FLASH);
1324 qla4_83xx_process_start_seq(ha);
1325
1326exit_restart:
1327 return ret_val;
1328}
1329
1330int qla4_83xx_start_firmware(struct scsi_qla_host *ha)
1331{
1332 int ret_val = QLA_SUCCESS;
1333
1334 ret_val = qla4_83xx_restart(ha);
1335 if (ret_val == QLA_ERROR) {
1336 ql4_printk(KERN_ERR, ha, "%s: Restart error\n", __func__);
1337 goto exit_start_fw;
1338 } else {
1339 DEBUG2(ql4_printk(KERN_INFO, ha, "%s: Restart done\n",
1340 __func__));
1341 }
1342
1343 ret_val = qla4_83xx_check_cmd_peg_status(ha);
1344 if (ret_val == QLA_ERROR)
1345 ql4_printk(KERN_ERR, ha, "%s: Peg not initialized\n",
1346 __func__);
1347
1348exit_start_fw:
1349 return ret_val;
1350}
1351
1352/*----------------------Interrupt Related functions ---------------------*/
1353
1354void qla4_83xx_disable_intrs(struct scsi_qla_host *ha)
1355{
1356 uint32_t mb_int, ret;
1357
1358 if (test_and_clear_bit(AF_INTERRUPTS_ON, &ha->flags))
1359 qla4_8xxx_mbx_intr_disable(ha);
1360
1361 ret = readl(&ha->qla4_83xx_reg->mbox_int);
1362 mb_int = ret & ~INT_ENABLE_FW_MB;
1363 writel(mb_int, &ha->qla4_83xx_reg->mbox_int);
1364 writel(1, &ha->qla4_83xx_reg->leg_int_mask);
1365}
1366
1367void qla4_83xx_enable_intrs(struct scsi_qla_host *ha)
1368{
1369 uint32_t mb_int;
1370
1371 qla4_8xxx_mbx_intr_enable(ha);
1372 mb_int = INT_ENABLE_FW_MB;
1373 writel(mb_int, &ha->qla4_83xx_reg->mbox_int);
1374 writel(0, &ha->qla4_83xx_reg->leg_int_mask);
1375
1376 set_bit(AF_INTERRUPTS_ON, &ha->flags);
1377}
1378
1379void qla4_83xx_queue_mbox_cmd(struct scsi_qla_host *ha, uint32_t *mbx_cmd,
1380 int incount)
1381{
1382 int i;
1383
1384 /* Load all mailbox registers, except mailbox 0. */
1385 for (i = 1; i < incount; i++)
1386 writel(mbx_cmd[i], &ha->qla4_83xx_reg->mailbox_in[i]);
1387
1388 writel(mbx_cmd[0], &ha->qla4_83xx_reg->mailbox_in[0]);
1389
1390 /* Set Host Interrupt register to 1, to tell the firmware that
1391 * a mailbox command is pending. Firmware after reading the
1392 * mailbox command, clears the host interrupt register */
1393 writel(HINT_MBX_INT_PENDING, &ha->qla4_83xx_reg->host_intr);
1394}
1395
1396void qla4_83xx_process_mbox_intr(struct scsi_qla_host *ha, int outcount)
1397{
1398 int intr_status;
1399
1400 intr_status = readl(&ha->qla4_83xx_reg->risc_intr);
1401 if (intr_status) {
1402 ha->mbox_status_count = outcount;
1403 ha->isp_ops->interrupt_service_routine(ha, intr_status);
1404 }
1405 writel(0, &ha->qla4_83xx_reg->risc_intr);
1406}
1407
1408/**
1409 * qla4_83xx_isp_reset - Resets ISP and aborts all outstanding commands.
1410 * @ha: pointer to host adapter structure.
1411 **/
1412int qla4_83xx_isp_reset(struct scsi_qla_host *ha)
1413{
1414 int rval;
1415 uint32_t dev_state;
1416
1417 ha->isp_ops->idc_lock(ha);
1418 dev_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE);
1419
1420 if (ql4xdontresethba)
1421 qla4_83xx_set_idc_dontreset(ha);
1422
1423 if (dev_state == QLA8XXX_DEV_READY) {
1424 /* If IDC_CTRL DONTRESETHBA_BIT0 is set dont do reset
1425 * recovery */
1426 if (qla4_83xx_idc_dontreset(ha) == DONTRESET_BIT0) {
1427 ql4_printk(KERN_ERR, ha, "%s: Reset recovery disabled\n",
1428 __func__);
1429 rval = QLA_ERROR;
1430 goto exit_isp_reset;
1431 }
1432
1433 DEBUG2(ql4_printk(KERN_INFO, ha, "%s: HW State: NEED RESET\n",
1434 __func__));
1435 qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
1436 QLA8XXX_DEV_NEED_RESET);
1437
1438 } else {
1439 /* If device_state is NEED_RESET, go ahead with
1440 * Reset,irrespective of ql4xdontresethba. This is to allow a
1441 * non-reset-owner to force a reset. Non-reset-owner sets
1442 * the IDC_CTRL BIT0 to prevent Reset-owner from doing a Reset
1443 * and then forces a Reset by setting device_state to
1444 * NEED_RESET. */
1445 DEBUG2(ql4_printk(KERN_INFO, ha,
1446 "%s: HW state already set to NEED_RESET\n",
1447 __func__));
1448 }
1449
1450 /* For ISP8324, Reset owner is NIC, iSCSI or FCOE based on priority
1451 * and which drivers are present. Unlike ISP8022, the function setting
1452 * NEED_RESET, may not be the Reset owner. */
1453 if (qla4_83xx_can_perform_reset(ha))
1454 set_bit(AF_8XXX_RST_OWNER, &ha->flags);
1455
1456 ha->isp_ops->idc_unlock(ha);
1457 rval = qla4_8xxx_device_state_handler(ha);
1458
1459 ha->isp_ops->idc_lock(ha);
1460 qla4_8xxx_clear_rst_ready(ha);
1461exit_isp_reset:
1462 ha->isp_ops->idc_unlock(ha);
1463
1464 if (rval == QLA_SUCCESS)
1465 clear_bit(AF_FW_RECOVERY, &ha->flags);
1466
1467 return rval;
1468}
diff --git a/drivers/scsi/qla4xxx/ql4_83xx.h b/drivers/scsi/qla4xxx/ql4_83xx.h
new file mode 100644
index 000000000000..a67926383940
--- /dev/null
+++ b/drivers/scsi/qla4xxx/ql4_83xx.h
@@ -0,0 +1,262 @@
1/*
2 * QLogic iSCSI HBA Driver
3 * Copyright (c) 2003-2012 QLogic Corporation
4 *
5 * See LICENSE.qla4xxx for copyright and licensing details.
6 */
7
8#ifndef __QL483XX_H
9#define __QL483XX_H
10
11/* Indirectly Mapped Registers */
12#define QLA83XX_FLASH_SPI_STATUS 0x2808E010
13#define QLA83XX_FLASH_SPI_CONTROL 0x2808E014
14#define QLA83XX_FLASH_STATUS 0x42100004
15#define QLA83XX_FLASH_CONTROL 0x42110004
16#define QLA83XX_FLASH_ADDR 0x42110008
17#define QLA83XX_FLASH_WRDATA 0x4211000C
18#define QLA83XX_FLASH_RDDATA 0x42110018
19#define QLA83XX_FLASH_DIRECT_WINDOW 0x42110030
20#define QLA83XX_FLASH_DIRECT_DATA(DATA) (0x42150000 | (0x0000FFFF&DATA))
21
22/* Directly Mapped Registers in 83xx register table */
23
24/* Flash access regs */
25#define QLA83XX_FLASH_LOCK 0x3850
26#define QLA83XX_FLASH_UNLOCK 0x3854
27#define QLA83XX_FLASH_LOCK_ID 0x3500
28
29/* Driver Lock regs */
30#define QLA83XX_DRV_LOCK 0x3868
31#define QLA83XX_DRV_UNLOCK 0x386C
32#define QLA83XX_DRV_LOCK_ID 0x3504
33#define QLA83XX_DRV_LOCKRECOVERY 0x379C
34
35/* IDC version */
36#define QLA83XX_IDC_VER_MAJ_VALUE 0x1
37#define QLA83XX_IDC_VER_MIN_VALUE 0x0
38
39/* IDC Registers : Driver Coexistence Defines */
40#define QLA83XX_CRB_IDC_VER_MAJOR 0x3780
41#define QLA83XX_CRB_IDC_VER_MINOR 0x3798
42#define QLA83XX_IDC_DRV_CTRL 0x3790
43#define QLA83XX_IDC_DRV_AUDIT 0x3794
44
45/* qla_83xx_reg_tbl registers */
46#define QLA83XX_PEG_HALT_STATUS1 0x34A8
47#define QLA83XX_PEG_HALT_STATUS2 0x34AC
48#define QLA83XX_PEG_ALIVE_COUNTER 0x34B0 /* FW_HEARTBEAT */
49#define QLA83XX_FW_CAPABILITIES 0x3528
50#define QLA83XX_CRB_DRV_ACTIVE 0x3788 /* IDC_DRV_PRESENCE */
51#define QLA83XX_CRB_DEV_STATE 0x3784 /* IDC_DEV_STATE */
52#define QLA83XX_CRB_DRV_STATE 0x378C /* IDC_DRV_ACK */
53#define QLA83XX_CRB_DRV_SCRATCH 0x3548
54#define QLA83XX_CRB_DEV_PART_INFO1 0x37E0
55#define QLA83XX_CRB_DEV_PART_INFO2 0x37E4
56
57#define QLA83XX_FW_VER_MAJOR 0x3550
58#define QLA83XX_FW_VER_MINOR 0x3554
59#define QLA83XX_FW_VER_SUB 0x3558
60#define QLA83XX_NPAR_STATE 0x359C
61#define QLA83XX_FW_IMAGE_VALID 0x35FC
62#define QLA83XX_CMDPEG_STATE 0x3650
63#define QLA83XX_ASIC_TEMP 0x37B4
64#define QLA83XX_FW_API 0x356C
65#define QLA83XX_DRV_OP_MODE 0x3570
66
67static const uint32_t qla4_83xx_reg_tbl[] = {
68 QLA83XX_PEG_HALT_STATUS1,
69 QLA83XX_PEG_HALT_STATUS2,
70 QLA83XX_PEG_ALIVE_COUNTER,
71 QLA83XX_CRB_DRV_ACTIVE,
72 QLA83XX_CRB_DEV_STATE,
73 QLA83XX_CRB_DRV_STATE,
74 QLA83XX_CRB_DRV_SCRATCH,
75 QLA83XX_CRB_DEV_PART_INFO1,
76 QLA83XX_CRB_IDC_VER_MAJOR,
77 QLA83XX_FW_VER_MAJOR,
78 QLA83XX_FW_VER_MINOR,
79 QLA83XX_FW_VER_SUB,
80 QLA83XX_CMDPEG_STATE,
81 QLA83XX_ASIC_TEMP,
82};
83
84#define QLA83XX_CRB_WIN_BASE 0x3800
85#define QLA83XX_CRB_WIN_FUNC(f) (QLA83XX_CRB_WIN_BASE+((f)*4))
86#define QLA83XX_SEM_LOCK_BASE 0x3840
87#define QLA83XX_SEM_UNLOCK_BASE 0x3844
88#define QLA83XX_SEM_LOCK_FUNC(f) (QLA83XX_SEM_LOCK_BASE+((f)*8))
89#define QLA83XX_SEM_UNLOCK_FUNC(f) (QLA83XX_SEM_UNLOCK_BASE+((f)*8))
90#define QLA83XX_LINK_STATE(f) (0x3698+((f) > 7 ? 4 : 0))
91#define QLA83XX_LINK_SPEED(f) (0x36E0+(((f) >> 2) * 4))
92#define QLA83XX_MAX_LINK_SPEED(f) (0x36F0+(((f) / 4) * 4))
93#define QLA83XX_LINK_SPEED_FACTOR 10
94
95/* FLASH API Defines */
96#define QLA83xx_FLASH_MAX_WAIT_USEC 100
97#define QLA83XX_FLASH_LOCK_TIMEOUT 10000
98#define QLA83XX_FLASH_SECTOR_SIZE 65536
99#define QLA83XX_DRV_LOCK_TIMEOUT 2000
100#define QLA83XX_FLASH_SECTOR_ERASE_CMD 0xdeadbeef
101#define QLA83XX_FLASH_WRITE_CMD 0xdacdacda
102#define QLA83XX_FLASH_BUFFER_WRITE_CMD 0xcadcadca
103#define QLA83XX_FLASH_READ_RETRY_COUNT 2000
104#define QLA83XX_FLASH_STATUS_READY 0x6
105#define QLA83XX_FLASH_BUFFER_WRITE_MIN 2
106#define QLA83XX_FLASH_BUFFER_WRITE_MAX 64
107#define QLA83XX_FLASH_STATUS_REG_POLL_DELAY 1
108#define QLA83XX_ERASE_MODE 1
109#define QLA83XX_WRITE_MODE 2
110#define QLA83XX_DWORD_WRITE_MODE 3
111
112#define QLA83XX_GLOBAL_RESET 0x38CC
113#define QLA83XX_WILDCARD 0x38F0
114#define QLA83XX_INFORMANT 0x38FC
115#define QLA83XX_HOST_MBX_CTRL 0x3038
116#define QLA83XX_FW_MBX_CTRL 0x303C
117#define QLA83XX_BOOTLOADER_ADDR 0x355C
118#define QLA83XX_BOOTLOADER_SIZE 0x3560
119#define QLA83XX_FW_IMAGE_ADDR 0x3564
120#define QLA83XX_MBX_INTR_ENABLE 0x1000
121#define QLA83XX_MBX_INTR_MASK 0x1200
122
123/* IDC Control Register bit defines */
124#define DONTRESET_BIT0 0x1
125#define GRACEFUL_RESET_BIT1 0x2
126
127#define QLA83XX_HALT_STATUS_INFORMATIONAL (0x1 << 29)
128#define QLA83XX_HALT_STATUS_FW_RESET (0x2 << 29)
129#define QLA83XX_HALT_STATUS_UNRECOVERABLE (0x4 << 29)
130
131/* Firmware image definitions */
132#define QLA83XX_BOOTLOADER_FLASH_ADDR 0x10000
133#define QLA83XX_BOOT_FROM_FLASH 0
134
135#define QLA83XX_IDC_PARAM_ADDR 0x3e8020
136/* Reset template definitions */
137#define QLA83XX_MAX_RESET_SEQ_ENTRIES 16
138#define QLA83XX_RESTART_TEMPLATE_SIZE 0x2000
139#define QLA83XX_RESET_TEMPLATE_ADDR 0x4F0000
140#define QLA83XX_RESET_SEQ_VERSION 0x0101
141
142/* Reset template entry opcodes */
143#define OPCODE_NOP 0x0000
144#define OPCODE_WRITE_LIST 0x0001
145#define OPCODE_READ_WRITE_LIST 0x0002
146#define OPCODE_POLL_LIST 0x0004
147#define OPCODE_POLL_WRITE_LIST 0x0008
148#define OPCODE_READ_MODIFY_WRITE 0x0010
149#define OPCODE_SEQ_PAUSE 0x0020
150#define OPCODE_SEQ_END 0x0040
151#define OPCODE_TMPL_END 0x0080
152#define OPCODE_POLL_READ_LIST 0x0100
153
154/* Template Header */
155#define RESET_TMPLT_HDR_SIGNATURE 0xCAFE
156struct qla4_83xx_reset_template_hdr {
157 __le16 version;
158 __le16 signature;
159 __le16 size;
160 __le16 entries;
161 __le16 hdr_size;
162 __le16 checksum;
163 __le16 init_seq_offset;
164 __le16 start_seq_offset;
165} __packed;
166
167/* Common Entry Header. */
168struct qla4_83xx_reset_entry_hdr {
169 __le16 cmd;
170 __le16 size;
171 __le16 count;
172 __le16 delay;
173} __packed;
174
175/* Generic poll entry type. */
176struct qla4_83xx_poll {
177 __le32 test_mask;
178 __le32 test_value;
179} __packed;
180
181/* Read modify write entry type. */
182struct qla4_83xx_rmw {
183 __le32 test_mask;
184 __le32 xor_value;
185 __le32 or_value;
186 uint8_t shl;
187 uint8_t shr;
188 uint8_t index_a;
189 uint8_t rsvd;
190} __packed;
191
192/* Generic Entry Item with 2 DWords. */
193struct qla4_83xx_entry {
194 __le32 arg1;
195 __le32 arg2;
196} __packed;
197
198/* Generic Entry Item with 4 DWords.*/
199struct qla4_83xx_quad_entry {
200 __le32 dr_addr;
201 __le32 dr_value;
202 __le32 ar_addr;
203 __le32 ar_value;
204} __packed;
205
206struct qla4_83xx_reset_template {
207 int seq_index;
208 int seq_error;
209 int array_index;
210 uint32_t array[QLA83XX_MAX_RESET_SEQ_ENTRIES];
211 uint8_t *buff;
212 uint8_t *stop_offset;
213 uint8_t *start_offset;
214 uint8_t *init_offset;
215 struct qla4_83xx_reset_template_hdr *hdr;
216 uint8_t seq_end;
217 uint8_t template_end;
218};
219
220/* POLLRD Entry */
221struct qla83xx_minidump_entry_pollrd {
222 struct qla8xxx_minidump_entry_hdr h;
223 uint32_t select_addr;
224 uint32_t read_addr;
225 uint32_t select_value;
226 uint16_t select_value_stride;
227 uint16_t op_count;
228 uint32_t poll_wait;
229 uint32_t poll_mask;
230 uint32_t data_size;
231 uint32_t rsvd_1;
232};
233
234/* RDMUX2 Entry */
235struct qla83xx_minidump_entry_rdmux2 {
236 struct qla8xxx_minidump_entry_hdr h;
237 uint32_t select_addr_1;
238 uint32_t select_addr_2;
239 uint32_t select_value_1;
240 uint32_t select_value_2;
241 uint32_t op_count;
242 uint32_t select_value_mask;
243 uint32_t read_addr;
244 uint8_t select_value_stride;
245 uint8_t data_size;
246 uint8_t rsvd[2];
247};
248
249/* POLLRDMWR Entry */
250struct qla83xx_minidump_entry_pollrdmwr {
251 struct qla8xxx_minidump_entry_hdr h;
252 uint32_t addr_1;
253 uint32_t addr_2;
254 uint32_t value_1;
255 uint32_t value_2;
256 uint32_t poll_wait;
257 uint32_t poll_mask;
258 uint32_t modify_mask;
259 uint32_t data_size;
260};
261
262#endif
diff --git a/drivers/scsi/qla4xxx/ql4_attr.c b/drivers/scsi/qla4xxx/ql4_attr.c
index a24008f18539..76819b71ada7 100644
--- a/drivers/scsi/qla4xxx/ql4_attr.c
+++ b/drivers/scsi/qla4xxx/ql4_attr.c
@@ -150,7 +150,7 @@ qla4xxx_fw_version_show(struct device *dev,
150{ 150{
151 struct scsi_qla_host *ha = to_qla_host(class_to_shost(dev)); 151 struct scsi_qla_host *ha = to_qla_host(class_to_shost(dev));
152 152
153 if (is_qla8022(ha)) 153 if (is_qla80XX(ha))
154 return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d (%x)\n", 154 return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d (%x)\n",
155 ha->firmware_version[0], 155 ha->firmware_version[0],
156 ha->firmware_version[1], 156 ha->firmware_version[1],
diff --git a/drivers/scsi/qla4xxx/ql4_dbg.c b/drivers/scsi/qla4xxx/ql4_dbg.c
index ea6af8ca6b3e..f2a841f69719 100644
--- a/drivers/scsi/qla4xxx/ql4_dbg.c
+++ b/drivers/scsi/qla4xxx/ql4_dbg.c
@@ -131,3 +131,31 @@ void qla4xxx_dump_registers(struct scsi_qla_host *ha)
131 &ha->reg->ctrl_status); 131 &ha->reg->ctrl_status);
132 } 132 }
133} 133}
134
135void qla4_8xxx_dump_peg_reg(struct scsi_qla_host *ha)
136{
137 uint32_t halt_status1, halt_status2;
138
139 halt_status1 = qla4_8xxx_rd_direct(ha, QLA8XXX_PEG_HALT_STATUS1);
140 halt_status2 = qla4_8xxx_rd_direct(ha, QLA8XXX_PEG_HALT_STATUS2);
141
142 if (is_qla8022(ha)) {
143 ql4_printk(KERN_INFO, ha,
144 "scsi(%ld): %s, ISP8022 Dumping hw/fw registers:\n"
145 " PEG_HALT_STATUS1: 0x%x, PEG_HALT_STATUS2: 0x%x,\n"
146 " PEG_NET_0_PC: 0x%x, PEG_NET_1_PC: 0x%x,\n"
147 " PEG_NET_2_PC: 0x%x, PEG_NET_3_PC: 0x%x,\n"
148 " PEG_NET_4_PC: 0x%x\n", ha->host_no,
149 __func__, halt_status1, halt_status2,
150 qla4_82xx_rd_32(ha, QLA82XX_CRB_PEG_NET_0 + 0x3c),
151 qla4_82xx_rd_32(ha, QLA82XX_CRB_PEG_NET_1 + 0x3c),
152 qla4_82xx_rd_32(ha, QLA82XX_CRB_PEG_NET_2 + 0x3c),
153 qla4_82xx_rd_32(ha, QLA82XX_CRB_PEG_NET_3 + 0x3c),
154 qla4_82xx_rd_32(ha, QLA82XX_CRB_PEG_NET_4 + 0x3c));
155 } else if (is_qla8032(ha)) {
156 ql4_printk(KERN_INFO, ha,
157 "scsi(%ld): %s, ISP8324 Dumping hw/fw registers:\n"
158 " PEG_HALT_STATUS1: 0x%x, PEG_HALT_STATUS2: 0x%x,\n",
159 ha->host_no, __func__, halt_status1, halt_status2);
160 }
161}
diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h
index 11271a2f551c..58b52cffebe0 100644
--- a/drivers/scsi/qla4xxx/ql4_def.h
+++ b/drivers/scsi/qla4xxx/ql4_def.h
@@ -42,6 +42,7 @@
42#include "ql4_nx.h" 42#include "ql4_nx.h"
43#include "ql4_fw.h" 43#include "ql4_fw.h"
44#include "ql4_nvram.h" 44#include "ql4_nvram.h"
45#include "ql4_83xx.h"
45 46
46#ifndef PCI_DEVICE_ID_QLOGIC_ISP4010 47#ifndef PCI_DEVICE_ID_QLOGIC_ISP4010
47#define PCI_DEVICE_ID_QLOGIC_ISP4010 0x4010 48#define PCI_DEVICE_ID_QLOGIC_ISP4010 0x4010
@@ -59,6 +60,10 @@
59#define PCI_DEVICE_ID_QLOGIC_ISP8022 0x8022 60#define PCI_DEVICE_ID_QLOGIC_ISP8022 0x8022
60#endif 61#endif
61 62
63#ifndef PCI_DEVICE_ID_QLOGIC_ISP8324
64#define PCI_DEVICE_ID_QLOGIC_ISP8324 0x8032
65#endif
66
62#define ISP4XXX_PCI_FN_1 0x1 67#define ISP4XXX_PCI_FN_1 0x1
63#define ISP4XXX_PCI_FN_2 0x3 68#define ISP4XXX_PCI_FN_2 0x3
64 69
@@ -510,6 +515,7 @@ struct scsi_qla_host {
510#define AF_82XX_FW_DUMPED 24 /* 0x01000000 */ 515#define AF_82XX_FW_DUMPED 24 /* 0x01000000 */
511#define AF_8XXX_RST_OWNER 25 /* 0x02000000 */ 516#define AF_8XXX_RST_OWNER 25 /* 0x02000000 */
512#define AF_82XX_DUMP_READING 26 /* 0x04000000 */ 517#define AF_82XX_DUMP_READING 26 /* 0x04000000 */
518#define AF_83XX_NO_FW_DUMP 27 /* 0x08000000 */
513 519
514 unsigned long dpc_flags; 520 unsigned long dpc_flags;
515 521
@@ -746,6 +752,10 @@ struct scsi_qla_host {
746 uint32_t mrb_index; 752 uint32_t mrb_index;
747 753
748 uint32_t *reg_tbl; 754 uint32_t *reg_tbl;
755 struct qla4_83xx_reset_template reset_tmplt;
756 struct device_reg_83xx __iomem *qla4_83xx_reg; /* Base I/O address
757 for ISP8324 */
758 uint32_t pf_bit;
749}; 759};
750 760
751struct ql4_task_data { 761struct ql4_task_data {
@@ -808,13 +818,20 @@ static inline int is_qla8022(struct scsi_qla_host *ha)
808 return ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8022; 818 return ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8022;
809} 819}
810 820
811/* Note: Currently AER/EEH is now supported only for 8022 cards 821static inline int is_qla8032(struct scsi_qla_host *ha)
812 * This function needs to be updated when AER/EEH is enabled 822{
813 * for other cards. 823 return ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8324;
814 */ 824}
825
826static inline int is_qla80XX(struct scsi_qla_host *ha)
827{
828 return is_qla8022(ha) || is_qla8032(ha);
829}
830
815static inline int is_aer_supported(struct scsi_qla_host *ha) 831static inline int is_aer_supported(struct scsi_qla_host *ha)
816{ 832{
817 return ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8022; 833 return ((ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8022) ||
834 (ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8324));
818} 835}
819 836
820static inline int adapter_up(struct scsi_qla_host *ha) 837static inline int adapter_up(struct scsi_qla_host *ha)
diff --git a/drivers/scsi/qla4xxx/ql4_fw.h b/drivers/scsi/qla4xxx/ql4_fw.h
index 037d38016c0a..3f36950ec86d 100644
--- a/drivers/scsi/qla4xxx/ql4_fw.h
+++ b/drivers/scsi/qla4xxx/ql4_fw.h
@@ -65,6 +65,40 @@ struct device_reg_82xx {
65#define ISRX_82XX_RISC_INT BIT_0 /* RISC interrupt. */ 65#define ISRX_82XX_RISC_INT BIT_0 /* RISC interrupt. */
66}; 66};
67 67
68/* ISP 83xx I/O Register Set structure */
69struct device_reg_83xx {
70 __le32 mailbox_in[16]; /* 0x0000 */
71 __le32 reserve1[496]; /* 0x0040 */
72 __le32 mailbox_out[16]; /* 0x0800 */
73 __le32 reserve2[496];
74 __le32 mbox_int; /* 0x1000 */
75 __le32 reserve3[63];
76 __le32 req_q_out; /* 0x1100 */
77 __le32 reserve4[63];
78
79 __le32 rsp_q_in; /* 0x1200 */
80 __le32 reserve5[1919];
81
82 __le32 req_q_in; /* 0x3000 */
83 __le32 reserve6[3];
84 __le32 iocb_int_mask; /* 0x3010 */
85 __le32 reserve7[3];
86 __le32 rsp_q_out; /* 0x3020 */
87 __le32 reserve8[3];
88 __le32 anonymousbuff; /* 0x3030 */
89 __le32 mb_int_mask; /* 0x3034 */
90
91 __le32 host_intr; /* 0x3038 - Host Interrupt Register */
92 __le32 risc_intr; /* 0x303C - RISC Interrupt Register */
93 __le32 reserve9[544];
94 __le32 leg_int_ptr; /* 0x38C0 - Legacy Interrupt Pointer Register */
95 __le32 leg_int_trig; /* 0x38C4 - Legacy Interrupt Trigger Control */
96 __le32 leg_int_mask; /* 0x38C8 - Legacy Interrupt Mask Register */
97};
98
99#define INT_ENABLE_FW_MB (1 << 2)
100#define INT_MASK_FW_MB (1 << 2)
101
68/* remote register set (access via PCI memory read/write) */ 102/* remote register set (access via PCI memory read/write) */
69struct isp_reg { 103struct isp_reg {
70#define MBOX_REG_COUNT 8 104#define MBOX_REG_COUNT 8
@@ -1198,6 +1232,9 @@ struct ql_iscsi_stats {
1198#define QLA8XXX_DBG_STATE_ARRAY_LEN 16 1232#define QLA8XXX_DBG_STATE_ARRAY_LEN 16
1199#define QLA8XXX_DBG_CAP_SIZE_ARRAY_LEN 8 1233#define QLA8XXX_DBG_CAP_SIZE_ARRAY_LEN 8
1200#define QLA8XXX_DBG_RSVD_ARRAY_LEN 8 1234#define QLA8XXX_DBG_RSVD_ARRAY_LEN 8
1235#define QLA83XX_DBG_OCM_WNDREG_ARRAY_LEN 16
1236#define QLA83XX_SS_OCM_WNDREG_INDEX 3
1237#define QLA83XX_SS_PCI_INDEX 0
1201 1238
1202struct qla4_8xxx_minidump_template_hdr { 1239struct qla4_8xxx_minidump_template_hdr {
1203 uint32_t entry_type; 1240 uint32_t entry_type;
@@ -1216,6 +1253,7 @@ struct qla4_8xxx_minidump_template_hdr {
1216 1253
1217 uint32_t saved_state_array[QLA8XXX_DBG_STATE_ARRAY_LEN]; 1254 uint32_t saved_state_array[QLA8XXX_DBG_STATE_ARRAY_LEN];
1218 uint32_t capture_size_array[QLA8XXX_DBG_CAP_SIZE_ARRAY_LEN]; 1255 uint32_t capture_size_array[QLA8XXX_DBG_CAP_SIZE_ARRAY_LEN];
1256 uint32_t ocm_window_reg[QLA83XX_DBG_OCM_WNDREG_ARRAY_LEN];
1219}; 1257};
1220 1258
1221#endif /* _QLA4X_FW_H */ 1259#endif /* _QLA4X_FW_H */
diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h
index 1010d717b7db..0c6acad2a518 100644
--- a/drivers/scsi/qla4xxx/ql4_glbl.h
+++ b/drivers/scsi/qla4xxx/ql4_glbl.h
@@ -214,6 +214,47 @@ void qla4_82xx_process_mbox_intr(struct scsi_qla_host *ha, int outcount);
214void qla4xxx_queue_mbox_cmd(struct scsi_qla_host *ha, uint32_t *mbx_cmd, 214void qla4xxx_queue_mbox_cmd(struct scsi_qla_host *ha, uint32_t *mbx_cmd,
215 int incount); 215 int incount);
216void qla4xxx_process_mbox_intr(struct scsi_qla_host *ha, int outcount); 216void qla4xxx_process_mbox_intr(struct scsi_qla_host *ha, int outcount);
217void qla4_8xxx_dump_peg_reg(struct scsi_qla_host *ha);
218void qla4_83xx_disable_intrs(struct scsi_qla_host *ha);
219void qla4_83xx_enable_intrs(struct scsi_qla_host *ha);
220int qla4_83xx_start_firmware(struct scsi_qla_host *ha);
221irqreturn_t qla4_83xx_intr_handler(int irq, void *dev_id);
222void qla4_83xx_interrupt_service_routine(struct scsi_qla_host *ha,
223 uint32_t intr_status);
224int qla4_83xx_isp_reset(struct scsi_qla_host *ha);
225void qla4_83xx_queue_iocb(struct scsi_qla_host *ha);
226void qla4_83xx_complete_iocb(struct scsi_qla_host *ha);
227uint16_t qla4_83xx_rd_shdw_req_q_out(struct scsi_qla_host *ha);
228uint16_t qla4_83xx_rd_shdw_rsp_q_in(struct scsi_qla_host *ha);
229uint32_t qla4_83xx_rd_reg(struct scsi_qla_host *ha, ulong addr);
230void qla4_83xx_wr_reg(struct scsi_qla_host *ha, ulong addr, uint32_t val);
231int qla4_83xx_rd_reg_indirect(struct scsi_qla_host *ha, uint32_t addr,
232 uint32_t *data);
233int qla4_83xx_wr_reg_indirect(struct scsi_qla_host *ha, uint32_t addr,
234 uint32_t data);
235int qla4_83xx_drv_lock(struct scsi_qla_host *ha);
236void qla4_83xx_drv_unlock(struct scsi_qla_host *ha);
237void qla4_83xx_rom_lock_recovery(struct scsi_qla_host *ha);
238void qla4_83xx_queue_mbox_cmd(struct scsi_qla_host *ha, uint32_t *mbx_cmd,
239 int incount);
240void qla4_83xx_process_mbox_intr(struct scsi_qla_host *ha, int outcount);
241void qla4_83xx_read_reset_template(struct scsi_qla_host *ha);
242void qla4_83xx_set_idc_dontreset(struct scsi_qla_host *ha);
243int qla4_83xx_idc_dontreset(struct scsi_qla_host *ha);
244int qla4_83xx_lockless_flash_read_u32(struct scsi_qla_host *ha,
245 uint32_t flash_addr, uint8_t *p_data,
246 int u32_word_count);
247void qla4_83xx_clear_idc_dontreset(struct scsi_qla_host *ha);
248void qla4_83xx_need_reset_handler(struct scsi_qla_host *ha);
249int qla4_83xx_flash_read_u32(struct scsi_qla_host *ha, uint32_t flash_addr,
250 uint8_t *p_data, int u32_word_count);
251void qla4_83xx_get_idc_param(struct scsi_qla_host *ha);
252void qla4_8xxx_set_rst_ready(struct scsi_qla_host *ha);
253void qla4_8xxx_clear_rst_ready(struct scsi_qla_host *ha);
254int qla4_8xxx_device_bootstrap(struct scsi_qla_host *ha);
255void qla4_8xxx_get_minidump(struct scsi_qla_host *ha);
256int qla4_8xxx_mbx_intr_disable(struct scsi_qla_host *ha);
257int qla4_8xxx_mbx_intr_enable(struct scsi_qla_host *ha);
217 258
218extern int ql4xextended_error_logging; 259extern int ql4xextended_error_logging;
219extern int ql4xdontresethba; 260extern int ql4xdontresethba;
diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c
index 6bc983df9d95..a1881d014be2 100644
--- a/drivers/scsi/qla4xxx/ql4_init.c
+++ b/drivers/scsi/qla4xxx/ql4_init.c
@@ -107,6 +107,13 @@ int qla4xxx_init_rings(struct scsi_qla_host *ha)
107 (unsigned long __iomem *)&ha->qla4_82xx_reg->rsp_q_in); 107 (unsigned long __iomem *)&ha->qla4_82xx_reg->rsp_q_in);
108 writel(0, 108 writel(0,
109 (unsigned long __iomem *)&ha->qla4_82xx_reg->rsp_q_out); 109 (unsigned long __iomem *)&ha->qla4_82xx_reg->rsp_q_out);
110 } else if (is_qla8032(ha)) {
111 writel(0,
112 (unsigned long __iomem *)&ha->qla4_83xx_reg->req_q_in);
113 writel(0,
114 (unsigned long __iomem *)&ha->qla4_83xx_reg->rsp_q_in);
115 writel(0,
116 (unsigned long __iomem *)&ha->qla4_83xx_reg->rsp_q_out);
110 } else { 117 } else {
111 /* 118 /*
112 * Initialize DMA Shadow registers. The firmware is really 119 * Initialize DMA Shadow registers. The firmware is really
@@ -524,7 +531,7 @@ static int qla4xxx_init_firmware(struct scsi_qla_host *ha)
524 /* For 82xx, stop firmware before initializing because if BIOS 531 /* For 82xx, stop firmware before initializing because if BIOS
525 * has previously initialized firmware, then driver's initialize 532 * has previously initialized firmware, then driver's initialize
526 * firmware will fail. */ 533 * firmware will fail. */
527 if (is_qla8022(ha)) 534 if (is_qla80XX(ha))
528 qla4_8xxx_stop_firmware(ha); 535 qla4_8xxx_stop_firmware(ha);
529 536
530 ql4_printk(KERN_INFO, ha, "Initializing firmware..\n"); 537 ql4_printk(KERN_INFO, ha, "Initializing firmware..\n");
@@ -537,7 +544,7 @@ static int qla4xxx_init_firmware(struct scsi_qla_host *ha)
537 if (!qla4xxx_fw_ready(ha)) 544 if (!qla4xxx_fw_ready(ha))
538 return status; 545 return status;
539 546
540 if (is_qla8022(ha) && !test_bit(AF_INIT_DONE, &ha->flags)) 547 if (is_qla80XX(ha) && !test_bit(AF_INIT_DONE, &ha->flags))
541 qla4xxx_alloc_fw_dump(ha); 548 qla4xxx_alloc_fw_dump(ha);
542 549
543 return qla4xxx_get_firmware_status(ha); 550 return qla4xxx_get_firmware_status(ha);
@@ -946,9 +953,9 @@ int qla4xxx_initialize_adapter(struct scsi_qla_host *ha, int is_reset)
946 953
947 set_bit(AF_ONLINE, &ha->flags); 954 set_bit(AF_ONLINE, &ha->flags);
948exit_init_hba: 955exit_init_hba:
949 if (is_qla8022(ha) && (status == QLA_ERROR)) { 956 if (is_qla80XX(ha) && (status == QLA_ERROR)) {
950 /* Since interrupts are registered in start_firmware for 957 /* Since interrupts are registered in start_firmware for
951 * 82xx, release them here if initialize_adapter fails */ 958 * 80XX, release them here if initialize_adapter fails */
952 qla4xxx_free_irqs(ha); 959 qla4xxx_free_irqs(ha);
953 } 960 }
954 961
diff --git a/drivers/scsi/qla4xxx/ql4_iocb.c b/drivers/scsi/qla4xxx/ql4_iocb.c
index 1def68879f9f..b6a4e36b79d8 100644
--- a/drivers/scsi/qla4xxx/ql4_iocb.c
+++ b/drivers/scsi/qla4xxx/ql4_iocb.c
@@ -192,6 +192,18 @@ static void qla4xxx_build_scsi_iocbs(struct srb *srb,
192 } 192 }
193} 193}
194 194
195void qla4_83xx_queue_iocb(struct scsi_qla_host *ha)
196{
197 writel(ha->request_in, &ha->qla4_83xx_reg->req_q_in);
198 readl(&ha->qla4_83xx_reg->req_q_in);
199}
200
201void qla4_83xx_complete_iocb(struct scsi_qla_host *ha)
202{
203 writel(ha->response_out, &ha->qla4_83xx_reg->rsp_q_out);
204 readl(&ha->qla4_83xx_reg->rsp_q_out);
205}
206
195/** 207/**
196 * qla4_82xx_queue_iocb - Tell ISP it's got new request(s) 208 * qla4_82xx_queue_iocb - Tell ISP it's got new request(s)
197 * @ha: pointer to host adapter structure. 209 * @ha: pointer to host adapter structure.
diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c
index 55d366b14a51..cb78e9c16744 100644
--- a/drivers/scsi/qla4xxx/ql4_isr.c
+++ b/drivers/scsi/qla4xxx/ql4_isr.c
@@ -126,7 +126,7 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha,
126 ql4_printk(KERN_WARNING, ha, "%s invalid status entry: " 126 ql4_printk(KERN_WARNING, ha, "%s invalid status entry: "
127 "handle=0x%0x, srb=%p\n", __func__, 127 "handle=0x%0x, srb=%p\n", __func__,
128 sts_entry->handle, srb); 128 sts_entry->handle, srb);
129 if (is_qla8022(ha)) 129 if (is_qla80XX(ha))
130 set_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags); 130 set_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags);
131 else 131 else
132 set_bit(DPC_RESET_HA, &ha->dpc_flags); 132 set_bit(DPC_RESET_HA, &ha->dpc_flags);
@@ -594,6 +594,14 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
594{ 594{
595 int i; 595 int i;
596 uint32_t mbox_sts[MBOX_AEN_REG_COUNT]; 596 uint32_t mbox_sts[MBOX_AEN_REG_COUNT];
597 __le32 __iomem *mailbox_out;
598
599 if (is_qla8032(ha))
600 mailbox_out = &ha->qla4_83xx_reg->mailbox_out[0];
601 else if (is_qla8022(ha))
602 mailbox_out = &ha->qla4_82xx_reg->mailbox_out[0];
603 else
604 mailbox_out = &ha->reg->mailbox[0];
597 605
598 if ((mbox_status == MBOX_STS_BUSY) || 606 if ((mbox_status == MBOX_STS_BUSY) ||
599 (mbox_status == MBOX_STS_INTERMEDIATE_COMPLETION) || 607 (mbox_status == MBOX_STS_INTERMEDIATE_COMPLETION) ||
@@ -606,9 +614,7 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
606 * location and set mailbox command done flag 614 * location and set mailbox command done flag
607 */ 615 */
608 for (i = 0; i < ha->mbox_status_count; i++) 616 for (i = 0; i < ha->mbox_status_count; i++)
609 ha->mbox_status[i] = is_qla8022(ha) 617 ha->mbox_status[i] = readl(&mailbox_out[i]);
610 ? readl(&ha->qla4_82xx_reg->mailbox_out[i])
611 : readl(&ha->reg->mailbox[i]);
612 618
613 set_bit(AF_MBOX_COMMAND_DONE, &ha->flags); 619 set_bit(AF_MBOX_COMMAND_DONE, &ha->flags);
614 620
@@ -617,9 +623,7 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
617 } 623 }
618 } else if (mbox_status >> 12 == MBOX_ASYNC_EVENT_STATUS) { 624 } else if (mbox_status >> 12 == MBOX_ASYNC_EVENT_STATUS) {
619 for (i = 0; i < MBOX_AEN_REG_COUNT; i++) 625 for (i = 0; i < MBOX_AEN_REG_COUNT; i++)
620 mbox_sts[i] = is_qla8022(ha) 626 mbox_sts[i] = readl(&mailbox_out[i]);
621 ? readl(&ha->qla4_82xx_reg->mailbox_out[i])
622 : readl(&ha->reg->mailbox[i]);
623 627
624 /* Immediately process the AENs that don't require much work. 628 /* Immediately process the AENs that don't require much work.
625 * Only queue the database_changed AENs */ 629 * Only queue the database_changed AENs */
@@ -635,7 +639,8 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
635 ql4_printk(KERN_INFO, ha, "%s: System Err\n", __func__); 639 ql4_printk(KERN_INFO, ha, "%s: System Err\n", __func__);
636 qla4xxx_dump_registers(ha); 640 qla4xxx_dump_registers(ha);
637 641
638 if (ql4xdontresethba) { 642 if ((is_qla8022(ha) && ql4xdontresethba) ||
643 (is_qla8032(ha) && qla4_83xx_idc_dontreset(ha))) {
639 DEBUG2(printk("scsi%ld: %s:Don't Reset HBA\n", 644 DEBUG2(printk("scsi%ld: %s:Don't Reset HBA\n",
640 ha->host_no, __func__)); 645 ha->host_no, __func__));
641 } else { 646 } else {
@@ -651,7 +656,7 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
651 case MBOX_ASTS_DHCP_LEASE_EXPIRED: 656 case MBOX_ASTS_DHCP_LEASE_EXPIRED:
652 DEBUG2(printk("scsi%ld: AEN %04x, ERROR Status, " 657 DEBUG2(printk("scsi%ld: AEN %04x, ERROR Status, "
653 "Reset HA\n", ha->host_no, mbox_status)); 658 "Reset HA\n", ha->host_no, mbox_status));
654 if (is_qla8022(ha)) 659 if (is_qla80XX(ha))
655 set_bit(DPC_RESET_HA_FW_CONTEXT, 660 set_bit(DPC_RESET_HA_FW_CONTEXT,
656 &ha->dpc_flags); 661 &ha->dpc_flags);
657 else 662 else
@@ -716,7 +721,7 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
716 set_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags); 721 set_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags);
717 else if ((mbox_sts[3] == ACB_STATE_ACQUIRING) && 722 else if ((mbox_sts[3] == ACB_STATE_ACQUIRING) &&
718 (mbox_sts[2] == ACB_STATE_VALID)) { 723 (mbox_sts[2] == ACB_STATE_VALID)) {
719 if (is_qla8022(ha)) 724 if (is_qla80XX(ha))
720 set_bit(DPC_RESET_HA_FW_CONTEXT, 725 set_bit(DPC_RESET_HA_FW_CONTEXT,
721 &ha->dpc_flags); 726 &ha->dpc_flags);
722 else 727 else
@@ -815,6 +820,23 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
815 } 820 }
816} 821}
817 822
823void qla4_83xx_interrupt_service_routine(struct scsi_qla_host *ha,
824 uint32_t intr_status)
825{
826 /* Process mailbox/asynch event interrupt.*/
827 if (intr_status) {
828 qla4xxx_isr_decode_mailbox(ha,
829 readl(&ha->qla4_83xx_reg->mailbox_out[0]));
830 /* clear the interrupt */
831 writel(0, &ha->qla4_83xx_reg->risc_intr);
832 } else {
833 qla4xxx_process_response_queue(ha);
834 }
835
836 /* clear the interrupt */
837 writel(0, &ha->qla4_83xx_reg->mb_int_mask);
838}
839
818/** 840/**
819 * qla4_82xx_interrupt_service_routine - isr 841 * qla4_82xx_interrupt_service_routine - isr
820 * @ha: pointer to host adapter structure. 842 * @ha: pointer to host adapter structure.
@@ -1045,6 +1067,59 @@ irqreturn_t qla4_82xx_intr_handler(int irq, void *dev_id)
1045 return IRQ_HANDLED; 1067 return IRQ_HANDLED;
1046} 1068}
1047 1069
1070#define LEG_INT_PTR_B31 (1 << 31)
1071#define LEG_INT_PTR_B30 (1 << 30)
1072#define PF_BITS_MASK (0xF << 16)
1073
1074/**
1075 * qla4_83xx_intr_handler - hardware interrupt handler.
1076 * @irq: Unused
1077 * @dev_id: Pointer to host adapter structure
1078 **/
1079irqreturn_t qla4_83xx_intr_handler(int irq, void *dev_id)
1080{
1081 struct scsi_qla_host *ha = dev_id;
1082 uint32_t leg_int_ptr = 0;
1083 unsigned long flags = 0;
1084
1085 ha->isr_count++;
1086 leg_int_ptr = readl(&ha->qla4_83xx_reg->leg_int_ptr);
1087
1088 /* Legacy interrupt is valid if bit31 of leg_int_ptr is set */
1089 if (!(leg_int_ptr & LEG_INT_PTR_B31)) {
1090 ql4_printk(KERN_ERR, ha,
1091 "%s: Legacy Interrupt Bit 31 not set, spurious interrupt!\n",
1092 __func__);
1093 return IRQ_NONE;
1094 }
1095
1096 /* Validate the PCIE function ID set in leg_int_ptr bits [19..16] */
1097 if ((leg_int_ptr & PF_BITS_MASK) != ha->pf_bit) {
1098 ql4_printk(KERN_ERR, ha,
1099 "%s: Incorrect function ID 0x%x in legacy interrupt register, ha->pf_bit = 0x%x\n",
1100 __func__, (leg_int_ptr & PF_BITS_MASK), ha->pf_bit);
1101 return IRQ_NONE;
1102 }
1103
1104 /* To de-assert legacy interrupt, write 0 to Legacy Interrupt Trigger
1105 * Control register and poll till Legacy Interrupt Pointer register
1106 * bit30 is 0.
1107 */
1108 writel(0, &ha->qla4_83xx_reg->leg_int_trig);
1109 do {
1110 leg_int_ptr = readl(&ha->qla4_83xx_reg->leg_int_ptr);
1111 if ((leg_int_ptr & PF_BITS_MASK) != ha->pf_bit)
1112 break;
1113 } while (leg_int_ptr & LEG_INT_PTR_B30);
1114
1115 spin_lock_irqsave(&ha->hardware_lock, flags);
1116 leg_int_ptr = readl(&ha->qla4_83xx_reg->risc_intr);
1117 ha->isp_ops->interrupt_service_routine(ha, leg_int_ptr);
1118 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1119
1120 return IRQ_HANDLED;
1121}
1122
1048irqreturn_t 1123irqreturn_t
1049qla4_8xxx_msi_handler(int irq, void *dev_id) 1124qla4_8xxx_msi_handler(int irq, void *dev_id)
1050{ 1125{
@@ -1068,6 +1143,37 @@ qla4_8xxx_msi_handler(int irq, void *dev_id)
1068 return qla4_8xxx_default_intr_handler(irq, dev_id); 1143 return qla4_8xxx_default_intr_handler(irq, dev_id);
1069} 1144}
1070 1145
1146static irqreturn_t qla4_83xx_mailbox_intr_handler(int irq, void *dev_id)
1147{
1148 struct scsi_qla_host *ha = dev_id;
1149 unsigned long flags;
1150 uint32_t ival = 0;
1151
1152 spin_lock_irqsave(&ha->hardware_lock, flags);
1153
1154 ival = readl(&ha->qla4_83xx_reg->risc_intr);
1155 if (ival == 0) {
1156 ql4_printk(KERN_INFO, ha,
1157 "%s: It is a spurious mailbox interrupt!\n",
1158 __func__);
1159 ival = readl(&ha->qla4_83xx_reg->mb_int_mask);
1160 ival &= ~INT_MASK_FW_MB;
1161 writel(ival, &ha->qla4_83xx_reg->mb_int_mask);
1162 goto exit;
1163 }
1164
1165 qla4xxx_isr_decode_mailbox(ha,
1166 readl(&ha->qla4_83xx_reg->mailbox_out[0]));
1167 writel(0, &ha->qla4_83xx_reg->risc_intr);
1168 ival = readl(&ha->qla4_83xx_reg->mb_int_mask);
1169 ival &= ~INT_MASK_FW_MB;
1170 writel(ival, &ha->qla4_83xx_reg->mb_int_mask);
1171 ha->isr_count++;
1172exit:
1173 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1174 return IRQ_HANDLED;
1175}
1176
1071/** 1177/**
1072 * qla4_8xxx_default_intr_handler - hardware interrupt handler. 1178 * qla4_8xxx_default_intr_handler - hardware interrupt handler.
1073 * @irq: Unused 1179 * @irq: Unused
@@ -1084,29 +1190,32 @@ qla4_8xxx_default_intr_handler(int irq, void *dev_id)
1084 uint32_t intr_status; 1190 uint32_t intr_status;
1085 uint8_t reqs_count = 0; 1191 uint8_t reqs_count = 0;
1086 1192
1087 spin_lock_irqsave(&ha->hardware_lock, flags); 1193 if (is_qla8032(ha)) {
1088 while (1) { 1194 qla4_83xx_mailbox_intr_handler(irq, dev_id);
1089 if (!(readl(&ha->qla4_82xx_reg->host_int) & 1195 } else {
1090 ISRX_82XX_RISC_INT)) { 1196 spin_lock_irqsave(&ha->hardware_lock, flags);
1091 qla4_82xx_spurious_interrupt(ha, reqs_count); 1197 while (1) {
1092 break; 1198 if (!(readl(&ha->qla4_82xx_reg->host_int) &
1093 } 1199 ISRX_82XX_RISC_INT)) {
1200 qla4_82xx_spurious_interrupt(ha, reqs_count);
1201 break;
1202 }
1094 1203
1095 intr_status = readl(&ha->qla4_82xx_reg->host_status); 1204 intr_status = readl(&ha->qla4_82xx_reg->host_status);
1096 if ((intr_status & 1205 if ((intr_status &
1097 (HSRX_RISC_MB_INT | HSRX_RISC_IOCB_INT)) == 0) { 1206 (HSRX_RISC_MB_INT | HSRX_RISC_IOCB_INT)) == 0) {
1098 qla4_82xx_spurious_interrupt(ha, reqs_count); 1207 qla4_82xx_spurious_interrupt(ha, reqs_count);
1099 break; 1208 break;
1100 } 1209 }
1101 1210
1102 ha->isp_ops->interrupt_service_routine(ha, intr_status); 1211 ha->isp_ops->interrupt_service_routine(ha, intr_status);
1103 1212
1104 if (++reqs_count == MAX_REQS_SERVICED_PER_INTR) 1213 if (++reqs_count == MAX_REQS_SERVICED_PER_INTR)
1105 break; 1214 break;
1215 }
1216 ha->isr_count++;
1217 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1106 } 1218 }
1107
1108 ha->isr_count++;
1109 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1110 return IRQ_HANDLED; 1219 return IRQ_HANDLED;
1111} 1220}
1112 1221
@@ -1115,13 +1224,25 @@ qla4_8xxx_msix_rsp_q(int irq, void *dev_id)
1115{ 1224{
1116 struct scsi_qla_host *ha = dev_id; 1225 struct scsi_qla_host *ha = dev_id;
1117 unsigned long flags; 1226 unsigned long flags;
1227 uint32_t ival = 0;
1118 1228
1119 spin_lock_irqsave(&ha->hardware_lock, flags); 1229 spin_lock_irqsave(&ha->hardware_lock, flags);
1120 qla4xxx_process_response_queue(ha); 1230 if (is_qla8032(ha)) {
1121 writel(0, &ha->qla4_82xx_reg->host_int); 1231 ival = readl(&ha->qla4_83xx_reg->iocb_int_mask);
1122 spin_unlock_irqrestore(&ha->hardware_lock, flags); 1232 if (ival == 0) {
1123 1233 ql4_printk(KERN_INFO, ha, "%s: It is a spurious iocb interrupt!\n",
1234 __func__);
1235 goto exit_msix_rsp_q;
1236 }
1237 qla4xxx_process_response_queue(ha);
1238 writel(0, &ha->qla4_83xx_reg->iocb_int_mask);
1239 } else {
1240 qla4xxx_process_response_queue(ha);
1241 writel(0, &ha->qla4_82xx_reg->host_int);
1242 }
1124 ha->isr_count++; 1243 ha->isr_count++;
1244exit_msix_rsp_q:
1245 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1125 return IRQ_HANDLED; 1246 return IRQ_HANDLED;
1126} 1247}
1127 1248
@@ -1196,8 +1317,15 @@ int qla4xxx_request_irqs(struct scsi_qla_host *ha)
1196 if (is_qla40XX(ha)) 1317 if (is_qla40XX(ha))
1197 goto try_intx; 1318 goto try_intx;
1198 1319
1199 if (ql4xenablemsix == 2) 1320 if (ql4xenablemsix == 2) {
1321 /* Note: MSI Interrupts not supported for ISP8324 */
1322 if (is_qla8032(ha)) {
1323 ql4_printk(KERN_INFO, ha, "%s: MSI Interrupts not supported for ISP8324, Falling back-to INTx mode\n",
1324 __func__);
1325 goto try_intx;
1326 }
1200 goto try_msi; 1327 goto try_msi;
1328 }
1201 1329
1202 if (ql4xenablemsix == 0 || ql4xenablemsix != 1) 1330 if (ql4xenablemsix == 0 || ql4xenablemsix != 1)
1203 goto try_intx; 1331 goto try_intx;
@@ -1208,6 +1336,12 @@ int qla4xxx_request_irqs(struct scsi_qla_host *ha)
1208 DEBUG2(ql4_printk(KERN_INFO, ha, 1336 DEBUG2(ql4_printk(KERN_INFO, ha,
1209 "MSI-X: Enabled (0x%X).\n", ha->revision_id)); 1337 "MSI-X: Enabled (0x%X).\n", ha->revision_id));
1210 goto irq_attached; 1338 goto irq_attached;
1339 } else {
1340 if (is_qla8032(ha)) {
1341 ql4_printk(KERN_INFO, ha, "%s: ISP8324: MSI-X: Falling back-to INTx mode. ret = %d\n",
1342 __func__, ret);
1343 goto try_intx;
1344 }
1211 } 1345 }
1212 1346
1213 ql4_printk(KERN_WARNING, ha, 1347 ql4_printk(KERN_WARNING, ha,
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c
index 73324fba64bc..80fa20d69089 100644
--- a/drivers/scsi/qla4xxx/ql4_mbx.c
+++ b/drivers/scsi/qla4xxx/ql4_mbx.c
@@ -107,7 +107,7 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
107 msleep(10); 107 msleep(10);
108 } 108 }
109 109
110 if (is_qla8022(ha)) { 110 if (is_qla80XX(ha)) {
111 if (test_bit(AF_FW_RECOVERY, &ha->flags)) { 111 if (test_bit(AF_FW_RECOVERY, &ha->flags)) {
112 DEBUG2(ql4_printk(KERN_WARNING, ha, 112 DEBUG2(ql4_printk(KERN_WARNING, ha,
113 "scsi%ld: %s: prematurely completing mbx cmd as firmware recovery detected\n", 113 "scsi%ld: %s: prematurely completing mbx cmd as firmware recovery detected\n",
@@ -183,7 +183,7 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
183 183
184 /* Check for mailbox timeout. */ 184 /* Check for mailbox timeout. */
185 if (!test_bit(AF_MBOX_COMMAND_DONE, &ha->flags)) { 185 if (!test_bit(AF_MBOX_COMMAND_DONE, &ha->flags)) {
186 if (is_qla8022(ha) && 186 if (is_qla80XX(ha) &&
187 test_bit(AF_FW_RECOVERY, &ha->flags)) { 187 test_bit(AF_FW_RECOVERY, &ha->flags)) {
188 DEBUG2(ql4_printk(KERN_INFO, ha, 188 DEBUG2(ql4_printk(KERN_INFO, ha,
189 "scsi%ld: %s: prematurely completing mbx cmd as " 189 "scsi%ld: %s: prematurely completing mbx cmd as "
@@ -544,7 +544,7 @@ int qla4xxx_initialize_fw_cb(struct scsi_qla_host * ha)
544 __constant_cpu_to_le16(FWOPT_SESSION_MODE | 544 __constant_cpu_to_le16(FWOPT_SESSION_MODE |
545 FWOPT_INITIATOR_MODE); 545 FWOPT_INITIATOR_MODE);
546 546
547 if (is_qla8022(ha)) 547 if (is_qla80XX(ha))
548 init_fw_cb->fw_options |= 548 init_fw_cb->fw_options |=
549 __constant_cpu_to_le16(FWOPT_ENABLE_CRBDB); 549 __constant_cpu_to_le16(FWOPT_ENABLE_CRBDB);
550 550
diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c
index 6daa25c50a99..3e5560840364 100644
--- a/drivers/scsi/qla4xxx/ql4_nx.c
+++ b/drivers/scsi/qla4xxx/ql4_nx.c
@@ -10,6 +10,7 @@
10#include <linux/ratelimit.h> 10#include <linux/ratelimit.h>
11#include "ql4_def.h" 11#include "ql4_def.h"
12#include "ql4_glbl.h" 12#include "ql4_glbl.h"
13#include "ql4_inline.h"
13 14
14#include <asm-generic/io-64-nonatomic-lo-hi.h> 15#include <asm-generic/io-64-nonatomic-lo-hi.h>
15 16
@@ -1511,7 +1512,17 @@ qla4_8xxx_set_drv_active(struct scsi_qla_host *ha)
1511 uint32_t drv_active; 1512 uint32_t drv_active;
1512 1513
1513 drv_active = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_ACTIVE); 1514 drv_active = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_ACTIVE);
1514 drv_active |= (1 << (ha->func_num * 4)); 1515
1516 /*
1517 * For ISP8324, drv_active register has 1 bit per function,
1518 * shift 1 by func_num to set a bit for the function.
1519 * For ISP8022, drv_active has 4 bits per function
1520 */
1521 if (is_qla8032(ha))
1522 drv_active |= (1 << ha->func_num);
1523 else
1524 drv_active |= (1 << (ha->func_num * 4));
1525
1515 ql4_printk(KERN_INFO, ha, "%s(%ld): drv_active: 0x%08x\n", 1526 ql4_printk(KERN_INFO, ha, "%s(%ld): drv_active: 0x%08x\n",
1516 __func__, ha->host_no, drv_active); 1527 __func__, ha->host_no, drv_active);
1517 qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_ACTIVE, drv_active); 1528 qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_ACTIVE, drv_active);
@@ -1523,7 +1534,17 @@ qla4_8xxx_clear_drv_active(struct scsi_qla_host *ha)
1523 uint32_t drv_active; 1534 uint32_t drv_active;
1524 1535
1525 drv_active = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_ACTIVE); 1536 drv_active = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_ACTIVE);
1526 drv_active &= ~(1 << (ha->func_num * 4)); 1537
1538 /*
1539 * For ISP8324, drv_active register has 1 bit per function,
1540 * shift 1 by func_num to set a bit for the function.
1541 * For ISP8022, drv_active has 4 bits per function
1542 */
1543 if (is_qla8032(ha))
1544 drv_active &= ~(1 << (ha->func_num));
1545 else
1546 drv_active &= ~(1 << (ha->func_num * 4));
1547
1527 ql4_printk(KERN_INFO, ha, "%s(%ld): drv_active: 0x%08x\n", 1548 ql4_printk(KERN_INFO, ha, "%s(%ld): drv_active: 0x%08x\n",
1528 __func__, ha->host_no, drv_active); 1549 __func__, ha->host_no, drv_active);
1529 qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_ACTIVE, drv_active); 1550 qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_ACTIVE, drv_active);
@@ -1536,32 +1557,60 @@ inline int qla4_8xxx_need_reset(struct scsi_qla_host *ha)
1536 1557
1537 drv_active = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_ACTIVE); 1558 drv_active = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_ACTIVE);
1538 drv_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_STATE); 1559 drv_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_STATE);
1539 rval = drv_state & (1 << (ha->func_num * 4)); 1560
1561 /*
1562 * For ISP8324, drv_active register has 1 bit per function,
1563 * shift 1 by func_num to set a bit for the function.
1564 * For ISP8022, drv_active has 4 bits per function
1565 */
1566 if (is_qla8032(ha))
1567 rval = drv_state & (1 << ha->func_num);
1568 else
1569 rval = drv_state & (1 << (ha->func_num * 4));
1570
1540 if ((test_bit(AF_EEH_BUSY, &ha->flags)) && drv_active) 1571 if ((test_bit(AF_EEH_BUSY, &ha->flags)) && drv_active)
1541 rval = 1; 1572 rval = 1;
1542 1573
1543 return rval; 1574 return rval;
1544} 1575}
1545 1576
1546static inline void 1577void qla4_8xxx_set_rst_ready(struct scsi_qla_host *ha)
1547qla4_8xxx_set_rst_ready(struct scsi_qla_host *ha)
1548{ 1578{
1549 uint32_t drv_state; 1579 uint32_t drv_state;
1550 1580
1551 drv_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_STATE); 1581 drv_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_STATE);
1552 drv_state |= (1 << (ha->func_num * 4)); 1582
1583 /*
1584 * For ISP8324, drv_active register has 1 bit per function,
1585 * shift 1 by func_num to set a bit for the function.
1586 * For ISP8022, drv_active has 4 bits per function
1587 */
1588 if (is_qla8032(ha))
1589 drv_state |= (1 << ha->func_num);
1590 else
1591 drv_state |= (1 << (ha->func_num * 4));
1592
1553 ql4_printk(KERN_INFO, ha, "%s(%ld): drv_state: 0x%08x\n", 1593 ql4_printk(KERN_INFO, ha, "%s(%ld): drv_state: 0x%08x\n",
1554 __func__, ha->host_no, drv_state); 1594 __func__, ha->host_no, drv_state);
1555 qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_STATE, drv_state); 1595 qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_STATE, drv_state);
1556} 1596}
1557 1597
1558static inline void 1598void qla4_8xxx_clear_rst_ready(struct scsi_qla_host *ha)
1559qla4_8xxx_clear_rst_ready(struct scsi_qla_host *ha)
1560{ 1599{
1561 uint32_t drv_state; 1600 uint32_t drv_state;
1562 1601
1563 drv_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_STATE); 1602 drv_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_STATE);
1564 drv_state &= ~(1 << (ha->func_num * 4)); 1603
1604 /*
1605 * For ISP8324, drv_active register has 1 bit per function,
1606 * shift 1 by func_num to set a bit for the function.
1607 * For ISP8022, drv_active has 4 bits per function
1608 */
1609 if (is_qla8032(ha))
1610 drv_state &= ~(1 << ha->func_num);
1611 else
1612 drv_state &= ~(1 << (ha->func_num * 4));
1613
1565 ql4_printk(KERN_INFO, ha, "%s(%ld): drv_state: 0x%08x\n", 1614 ql4_printk(KERN_INFO, ha, "%s(%ld): drv_state: 0x%08x\n",
1566 __func__, ha->host_no, drv_state); 1615 __func__, ha->host_no, drv_state);
1567 qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_STATE, drv_state); 1616 qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_STATE, drv_state);
@@ -1573,7 +1622,17 @@ qla4_8xxx_set_qsnt_ready(struct scsi_qla_host *ha)
1573 uint32_t qsnt_state; 1622 uint32_t qsnt_state;
1574 1623
1575 qsnt_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_STATE); 1624 qsnt_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_STATE);
1576 qsnt_state |= (2 << (ha->func_num * 4)); 1625
1626 /*
1627 * For ISP8324, drv_active register has 1 bit per function,
1628 * shift 1 by func_num to set a bit for the function.
1629 * For ISP8022, drv_active has 4 bits per function.
1630 */
1631 if (is_qla8032(ha))
1632 qsnt_state |= (1 << ha->func_num);
1633 else
1634 qsnt_state |= (2 << (ha->func_num * 4));
1635
1577 qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_STATE, qsnt_state); 1636 qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_STATE, qsnt_state);
1578} 1637}
1579 1638
@@ -2104,6 +2163,196 @@ static void qla4_8xxx_mark_entry_skipped(struct scsi_qla_host *ha,
2104 entry_hdr->d_ctrl.entry_capture_mask)); 2163 entry_hdr->d_ctrl.entry_capture_mask));
2105} 2164}
2106 2165
2166/* ISP83xx functions to process new minidump entries... */
2167static uint32_t qla83xx_minidump_process_pollrd(struct scsi_qla_host *ha,
2168 struct qla8xxx_minidump_entry_hdr *entry_hdr,
2169 uint32_t **d_ptr)
2170{
2171 uint32_t r_addr, s_addr, s_value, r_value, poll_wait, poll_mask;
2172 uint16_t s_stride, i;
2173 uint32_t *data_ptr = *d_ptr;
2174 uint32_t rval = QLA_SUCCESS;
2175 struct qla83xx_minidump_entry_pollrd *pollrd_hdr;
2176
2177 pollrd_hdr = (struct qla83xx_minidump_entry_pollrd *)entry_hdr;
2178 s_addr = le32_to_cpu(pollrd_hdr->select_addr);
2179 r_addr = le32_to_cpu(pollrd_hdr->read_addr);
2180 s_value = le32_to_cpu(pollrd_hdr->select_value);
2181 s_stride = le32_to_cpu(pollrd_hdr->select_value_stride);
2182
2183 poll_wait = le32_to_cpu(pollrd_hdr->poll_wait);
2184 poll_mask = le32_to_cpu(pollrd_hdr->poll_mask);
2185
2186 for (i = 0; i < le32_to_cpu(pollrd_hdr->op_count); i++) {
2187 ha->isp_ops->wr_reg_indirect(ha, s_addr, s_value);
2188 poll_wait = le32_to_cpu(pollrd_hdr->poll_wait);
2189 while (1) {
2190 ha->isp_ops->rd_reg_indirect(ha, s_addr, &r_value);
2191
2192 if ((r_value & poll_mask) != 0) {
2193 break;
2194 } else {
2195 msleep(1);
2196 if (--poll_wait == 0) {
2197 ql4_printk(KERN_ERR, ha, "%s: TIMEOUT\n",
2198 __func__);
2199 rval = QLA_ERROR;
2200 goto exit_process_pollrd;
2201 }
2202 }
2203 }
2204 ha->isp_ops->rd_reg_indirect(ha, r_addr, &r_value);
2205 *data_ptr++ = cpu_to_le32(s_value);
2206 *data_ptr++ = cpu_to_le32(r_value);
2207 s_value += s_stride;
2208 }
2209
2210 *d_ptr = data_ptr;
2211
2212exit_process_pollrd:
2213 return rval;
2214}
2215
2216static void qla83xx_minidump_process_rdmux2(struct scsi_qla_host *ha,
2217 struct qla8xxx_minidump_entry_hdr *entry_hdr,
2218 uint32_t **d_ptr)
2219{
2220 uint32_t sel_val1, sel_val2, t_sel_val, data, i;
2221 uint32_t sel_addr1, sel_addr2, sel_val_mask, read_addr;
2222 struct qla83xx_minidump_entry_rdmux2 *rdmux2_hdr;
2223 uint32_t *data_ptr = *d_ptr;
2224
2225 rdmux2_hdr = (struct qla83xx_minidump_entry_rdmux2 *)entry_hdr;
2226 sel_val1 = le32_to_cpu(rdmux2_hdr->select_value_1);
2227 sel_val2 = le32_to_cpu(rdmux2_hdr->select_value_2);
2228 sel_addr1 = le32_to_cpu(rdmux2_hdr->select_addr_1);
2229 sel_addr2 = le32_to_cpu(rdmux2_hdr->select_addr_2);
2230 sel_val_mask = le32_to_cpu(rdmux2_hdr->select_value_mask);
2231 read_addr = le32_to_cpu(rdmux2_hdr->read_addr);
2232
2233 for (i = 0; i < rdmux2_hdr->op_count; i++) {
2234 ha->isp_ops->wr_reg_indirect(ha, sel_addr1, sel_val1);
2235 t_sel_val = sel_val1 & sel_val_mask;
2236 *data_ptr++ = cpu_to_le32(t_sel_val);
2237
2238 ha->isp_ops->wr_reg_indirect(ha, sel_addr2, t_sel_val);
2239 ha->isp_ops->rd_reg_indirect(ha, read_addr, &data);
2240
2241 *data_ptr++ = cpu_to_le32(data);
2242
2243 ha->isp_ops->wr_reg_indirect(ha, sel_addr1, sel_val2);
2244 t_sel_val = sel_val2 & sel_val_mask;
2245 *data_ptr++ = cpu_to_le32(t_sel_val);
2246
2247 ha->isp_ops->wr_reg_indirect(ha, sel_addr2, t_sel_val);
2248 ha->isp_ops->rd_reg_indirect(ha, read_addr, &data);
2249
2250 *data_ptr++ = cpu_to_le32(data);
2251
2252 sel_val1 += rdmux2_hdr->select_value_stride;
2253 sel_val2 += rdmux2_hdr->select_value_stride;
2254 }
2255
2256 *d_ptr = data_ptr;
2257}
2258
2259static uint32_t qla83xx_minidump_process_pollrdmwr(struct scsi_qla_host *ha,
2260 struct qla8xxx_minidump_entry_hdr *entry_hdr,
2261 uint32_t **d_ptr)
2262{
2263 uint32_t poll_wait, poll_mask, r_value, data;
2264 uint32_t addr_1, addr_2, value_1, value_2;
2265 uint32_t *data_ptr = *d_ptr;
2266 uint32_t rval = QLA_SUCCESS;
2267 struct qla83xx_minidump_entry_pollrdmwr *poll_hdr;
2268
2269 poll_hdr = (struct qla83xx_minidump_entry_pollrdmwr *)entry_hdr;
2270 addr_1 = le32_to_cpu(poll_hdr->addr_1);
2271 addr_2 = le32_to_cpu(poll_hdr->addr_2);
2272 value_1 = le32_to_cpu(poll_hdr->value_1);
2273 value_2 = le32_to_cpu(poll_hdr->value_2);
2274 poll_mask = le32_to_cpu(poll_hdr->poll_mask);
2275
2276 ha->isp_ops->wr_reg_indirect(ha, addr_1, value_1);
2277
2278 poll_wait = le32_to_cpu(poll_hdr->poll_wait);
2279 while (1) {
2280 ha->isp_ops->rd_reg_indirect(ha, addr_1, &r_value);
2281
2282 if ((r_value & poll_mask) != 0) {
2283 break;
2284 } else {
2285 msleep(1);
2286 if (--poll_wait == 0) {
2287 ql4_printk(KERN_ERR, ha, "%s: TIMEOUT_1\n",
2288 __func__);
2289 rval = QLA_ERROR;
2290 goto exit_process_pollrdmwr;
2291 }
2292 }
2293 }
2294
2295 ha->isp_ops->rd_reg_indirect(ha, addr_2, &data);
2296 data &= le32_to_cpu(poll_hdr->modify_mask);
2297 ha->isp_ops->wr_reg_indirect(ha, addr_2, data);
2298 ha->isp_ops->wr_reg_indirect(ha, addr_1, value_2);
2299
2300 poll_wait = le32_to_cpu(poll_hdr->poll_wait);
2301 while (1) {
2302 ha->isp_ops->rd_reg_indirect(ha, addr_1, &r_value);
2303
2304 if ((r_value & poll_mask) != 0) {
2305 break;
2306 } else {
2307 msleep(1);
2308 if (--poll_wait == 0) {
2309 ql4_printk(KERN_ERR, ha, "%s: TIMEOUT_2\n",
2310 __func__);
2311 rval = QLA_ERROR;
2312 goto exit_process_pollrdmwr;
2313 }
2314 }
2315 }
2316
2317 *data_ptr++ = cpu_to_le32(addr_2);
2318 *data_ptr++ = cpu_to_le32(data);
2319 *d_ptr = data_ptr;
2320
2321exit_process_pollrdmwr:
2322 return rval;
2323}
2324
2325static uint32_t qla4_83xx_minidump_process_rdrom(struct scsi_qla_host *ha,
2326 struct qla8xxx_minidump_entry_hdr *entry_hdr,
2327 uint32_t **d_ptr)
2328{
2329 uint32_t fl_addr, u32_count, rval;
2330 struct qla8xxx_minidump_entry_rdrom *rom_hdr;
2331 uint32_t *data_ptr = *d_ptr;
2332
2333 rom_hdr = (struct qla8xxx_minidump_entry_rdrom *)entry_hdr;
2334 fl_addr = le32_to_cpu(rom_hdr->read_addr);
2335 u32_count = le32_to_cpu(rom_hdr->read_data_size)/sizeof(uint32_t);
2336
2337 DEBUG2(ql4_printk(KERN_INFO, ha, "[%s]: fl_addr: 0x%x, count: 0x%x\n",
2338 __func__, fl_addr, u32_count));
2339
2340 rval = qla4_83xx_lockless_flash_read_u32(ha, fl_addr,
2341 (u8 *)(data_ptr), u32_count);
2342
2343 if (rval == QLA_ERROR) {
2344 ql4_printk(KERN_ERR, ha, "%s: Flash Read Error,Count=%d\n",
2345 __func__, u32_count);
2346 goto exit_process_rdrom;
2347 }
2348
2349 data_ptr += u32_count;
2350 *d_ptr = data_ptr;
2351
2352exit_process_rdrom:
2353 return rval;
2354}
2355
2107/** 2356/**
2108 * qla4_8xxx_collect_md_data - Retrieve firmware minidump data. 2357 * qla4_8xxx_collect_md_data - Retrieve firmware minidump data.
2109 * @ha: pointer to adapter structure 2358 * @ha: pointer to adapter structure
@@ -2151,6 +2400,10 @@ static int qla4_8xxx_collect_md_data(struct scsi_qla_host *ha)
2151 (((uint8_t *)ha->fw_dump_tmplt_hdr) + 2400 (((uint8_t *)ha->fw_dump_tmplt_hdr) +
2152 tmplt_hdr->first_entry_offset); 2401 tmplt_hdr->first_entry_offset);
2153 2402
2403 if (is_qla8032(ha))
2404 tmplt_hdr->saved_state_array[QLA83XX_SS_OCM_WNDREG_INDEX] =
2405 tmplt_hdr->ocm_window_reg[ha->func_num];
2406
2154 /* Walk through the entry headers - validate/perform required action */ 2407 /* Walk through the entry headers - validate/perform required action */
2155 for (i = 0; i < num_entry_hdr; i++) { 2408 for (i = 0; i < num_entry_hdr; i++) {
2156 if (data_collected >= ha->fw_dump_size) { 2409 if (data_collected >= ha->fw_dump_size) {
@@ -2201,8 +2454,18 @@ static int qla4_8xxx_collect_md_data(struct scsi_qla_host *ha)
2201 break; 2454 break;
2202 case QLA8XXX_BOARD: 2455 case QLA8XXX_BOARD:
2203 case QLA8XXX_RDROM: 2456 case QLA8XXX_RDROM:
2204 qla4_82xx_minidump_process_rdrom(ha, entry_hdr, 2457 if (is_qla8022(ha)) {
2205 &data_ptr); 2458 qla4_82xx_minidump_process_rdrom(ha, entry_hdr,
2459 &data_ptr);
2460 } else if (is_qla8032(ha)) {
2461 rval = qla4_83xx_minidump_process_rdrom(ha,
2462 entry_hdr,
2463 &data_ptr);
2464 if (rval != QLA_SUCCESS)
2465 qla4_8xxx_mark_entry_skipped(ha,
2466 entry_hdr,
2467 i);
2468 }
2206 break; 2469 break;
2207 case QLA8XXX_L2DTG: 2470 case QLA8XXX_L2DTG:
2208 case QLA8XXX_L2ITG: 2471 case QLA8XXX_L2ITG:
@@ -2215,6 +2478,8 @@ static int qla4_8xxx_collect_md_data(struct scsi_qla_host *ha)
2215 goto md_failed; 2478 goto md_failed;
2216 } 2479 }
2217 break; 2480 break;
2481 case QLA8XXX_L1DTG:
2482 case QLA8XXX_L1ITG:
2218 case QLA8XXX_L1DAT: 2483 case QLA8XXX_L1DAT:
2219 case QLA8XXX_L1INS: 2484 case QLA8XXX_L1INS:
2220 qla4_8xxx_minidump_process_l1cache(ha, entry_hdr, 2485 qla4_8xxx_minidump_process_l1cache(ha, entry_hdr,
@@ -2232,6 +2497,34 @@ static int qla4_8xxx_collect_md_data(struct scsi_qla_host *ha)
2232 qla4_8xxx_minidump_process_queue(ha, entry_hdr, 2497 qla4_8xxx_minidump_process_queue(ha, entry_hdr,
2233 &data_ptr); 2498 &data_ptr);
2234 break; 2499 break;
2500 case QLA83XX_POLLRD:
2501 if (!is_qla8032(ha)) {
2502 qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
2503 break;
2504 }
2505 rval = qla83xx_minidump_process_pollrd(ha, entry_hdr,
2506 &data_ptr);
2507 if (rval != QLA_SUCCESS)
2508 qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
2509 break;
2510 case QLA83XX_RDMUX2:
2511 if (!is_qla8032(ha)) {
2512 qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
2513 break;
2514 }
2515 qla83xx_minidump_process_rdmux2(ha, entry_hdr,
2516 &data_ptr);
2517 break;
2518 case QLA83XX_POLLRDMWR:
2519 if (!is_qla8032(ha)) {
2520 qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
2521 break;
2522 }
2523 rval = qla83xx_minidump_process_pollrdmwr(ha, entry_hdr,
2524 &data_ptr);
2525 if (rval != QLA_SUCCESS)
2526 qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
2527 break;
2235 case QLA8XXX_RDNOP: 2528 case QLA8XXX_RDNOP:
2236 default: 2529 default:
2237 qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i); 2530 qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
@@ -2283,7 +2576,7 @@ static void qla4_8xxx_uevent_emit(struct scsi_qla_host *ha, u32 code)
2283 kobject_uevent_env(&(&ha->pdev->dev)->kobj, KOBJ_CHANGE, envp); 2576 kobject_uevent_env(&(&ha->pdev->dev)->kobj, KOBJ_CHANGE, envp);
2284} 2577}
2285 2578
2286static void qla4_8xxx_get_minidump(struct scsi_qla_host *ha) 2579void qla4_8xxx_get_minidump(struct scsi_qla_host *ha)
2287{ 2580{
2288 if (ql4xenablemd && test_bit(AF_FW_RECOVERY, &ha->flags) && 2581 if (ql4xenablemd && test_bit(AF_FW_RECOVERY, &ha->flags) &&
2289 !test_bit(AF_82XX_FW_DUMPED, &ha->flags)) { 2582 !test_bit(AF_82XX_FW_DUMPED, &ha->flags)) {
@@ -2303,12 +2596,11 @@ static void qla4_8xxx_get_minidump(struct scsi_qla_host *ha)
2303 * 2596 *
2304 * Note: IDC lock must be held upon entry 2597 * Note: IDC lock must be held upon entry
2305 **/ 2598 **/
2306static int 2599int qla4_8xxx_device_bootstrap(struct scsi_qla_host *ha)
2307qla4_8xxx_device_bootstrap(struct scsi_qla_host *ha)
2308{ 2600{
2309 int rval = QLA_ERROR; 2601 int rval = QLA_ERROR;
2310 int i, timeout; 2602 int i, timeout;
2311 uint32_t old_count, count; 2603 uint32_t old_count, count, idc_ctrl;
2312 int need_reset = 0, peg_stuck = 1; 2604 int need_reset = 0, peg_stuck = 1;
2313 2605
2314 need_reset = ha->isp_ops->need_reset(ha); 2606 need_reset = ha->isp_ops->need_reset(ha);
@@ -2351,8 +2643,24 @@ dev_initialize:
2351 qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE, 2643 qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
2352 QLA8XXX_DEV_INITIALIZING); 2644 QLA8XXX_DEV_INITIALIZING);
2353 2645
2646 /*
2647 * For ISP8324, if IDC_CTRL GRACEFUL_RESET_BIT1 is set, reset it after
2648 * device goes to INIT state.
2649 */
2650 if (is_qla8032(ha)) {
2651 idc_ctrl = qla4_83xx_rd_reg(ha, QLA83XX_IDC_DRV_CTRL);
2652 if (idc_ctrl & GRACEFUL_RESET_BIT1) {
2653 qla4_83xx_wr_reg(ha, QLA83XX_IDC_DRV_CTRL,
2654 (idc_ctrl & ~GRACEFUL_RESET_BIT1));
2655 set_bit(AF_83XX_NO_FW_DUMP, &ha->flags);
2656 }
2657 }
2658
2354 ha->isp_ops->idc_unlock(ha); 2659 ha->isp_ops->idc_unlock(ha);
2355 qla4_8xxx_get_minidump(ha); 2660
2661 if (is_qla8022(ha))
2662 qla4_8xxx_get_minidump(ha);
2663
2356 rval = ha->isp_ops->restart_firmware(ha); 2664 rval = ha->isp_ops->restart_firmware(ha);
2357 ha->isp_ops->idc_lock(ha); 2665 ha->isp_ops->idc_lock(ha);
2358 2666
@@ -2487,14 +2795,77 @@ static void qla4_82xx_set_idc_ver(struct scsi_qla_host *ha)
2487 } 2795 }
2488} 2796}
2489 2797
2490static void qla4_8xxx_update_idc_reg(struct scsi_qla_host *ha) 2798static int qla4_83xx_set_idc_ver(struct scsi_qla_host *ha)
2491{ 2799{
2492 if (!test_bit(AF_INIT_DONE, &ha->flags)) { 2800 int idc_ver;
2493 ha->isp_ops->idc_lock(ha); 2801 uint32_t drv_active;
2494 qla4_8xxx_set_drv_active(ha); 2802 int rval = QLA_SUCCESS;
2803
2804 drv_active = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_ACTIVE);
2805 if (drv_active == (1 << ha->func_num)) {
2806 idc_ver = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_IDC_VERSION);
2807 idc_ver &= (~0xFF);
2808 idc_ver |= QLA83XX_IDC_VER_MAJ_VALUE;
2809 qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_IDC_VERSION, idc_ver);
2810 ql4_printk(KERN_INFO, ha,
2811 "%s: IDC version updated to %d\n", __func__,
2812 QLA83XX_IDC_VER_MAJ_VALUE);
2813 } else {
2814 idc_ver = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_IDC_VERSION);
2815 idc_ver &= 0xFF;
2816 if (QLA83XX_IDC_VER_MAJ_VALUE != idc_ver) {
2817 ql4_printk(KERN_INFO, ha,
2818 "%s: qla4xxx driver IDC version %d is not compatible with IDC version %d of other drivers!\n",
2819 __func__, QLA83XX_IDC_VER_MAJ_VALUE,
2820 idc_ver);
2821 rval = QLA_ERROR;
2822 goto exit_set_idc_ver;
2823 }
2824 }
2825
2826 /* Update IDC_MINOR_VERSION */
2827 idc_ver = qla4_83xx_rd_reg(ha, QLA83XX_CRB_IDC_VER_MINOR);
2828 idc_ver &= ~(0x03 << (ha->func_num * 2));
2829 idc_ver |= (QLA83XX_IDC_VER_MIN_VALUE << (ha->func_num * 2));
2830 qla4_83xx_wr_reg(ha, QLA83XX_CRB_IDC_VER_MINOR, idc_ver);
2831
2832exit_set_idc_ver:
2833 return rval;
2834}
2835
2836static int qla4_8xxx_update_idc_reg(struct scsi_qla_host *ha)
2837{
2838 uint32_t drv_active;
2839 int rval = QLA_SUCCESS;
2840
2841 if (test_bit(AF_INIT_DONE, &ha->flags))
2842 goto exit_update_idc_reg;
2843
2844 ha->isp_ops->idc_lock(ha);
2845 qla4_8xxx_set_drv_active(ha);
2846
2847 /*
2848 * If we are the first driver to load and
2849 * ql4xdontresethba is not set, clear IDC_CTRL BIT0.
2850 */
2851 if (is_qla8032(ha)) {
2852 drv_active = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_ACTIVE);
2853 if ((drv_active == (1 << ha->func_num)) && !ql4xdontresethba)
2854 qla4_83xx_clear_idc_dontreset(ha);
2855 }
2856
2857 if (is_qla8022(ha)) {
2495 qla4_82xx_set_idc_ver(ha); 2858 qla4_82xx_set_idc_ver(ha);
2496 ha->isp_ops->idc_unlock(ha); 2859 } else if (is_qla8032(ha)) {
2860 rval = qla4_83xx_set_idc_ver(ha);
2861 if (rval == QLA_ERROR)
2862 qla4_8xxx_clear_drv_active(ha);
2497 } 2863 }
2864
2865 ha->isp_ops->idc_unlock(ha);
2866
2867exit_update_idc_reg:
2868 return rval;
2498} 2869}
2499 2870
2500/** 2871/**
@@ -2509,7 +2880,9 @@ int qla4_8xxx_device_state_handler(struct scsi_qla_host *ha)
2509 int rval = QLA_SUCCESS; 2880 int rval = QLA_SUCCESS;
2510 unsigned long dev_init_timeout; 2881 unsigned long dev_init_timeout;
2511 2882
2512 qla4_8xxx_update_idc_reg(ha); 2883 rval = qla4_8xxx_update_idc_reg(ha);
2884 if (rval == QLA_ERROR)
2885 goto exit_state_handler;
2513 2886
2514 dev_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE); 2887 dev_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE);
2515 DEBUG2(ql4_printk(KERN_INFO, ha, "Device state is 0x%x = %s\n", 2888 DEBUG2(ql4_printk(KERN_INFO, ha, "Device state is 0x%x = %s\n",
@@ -2550,16 +2923,25 @@ int qla4_8xxx_device_state_handler(struct scsi_qla_host *ha)
2550 ha->isp_ops->idc_lock(ha); 2923 ha->isp_ops->idc_lock(ha);
2551 break; 2924 break;
2552 case QLA8XXX_DEV_NEED_RESET: 2925 case QLA8XXX_DEV_NEED_RESET:
2553 if (!ql4xdontresethba) { 2926 /*
2554 qla4_82xx_need_reset_handler(ha); 2927 * For ISP8324, if NEED_RESET is set by any driver,
2555 /* Update timeout value after need 2928 * it should be honored, irrespective of IDC_CTRL
2556 * reset handler */ 2929 * DONTRESET_BIT0
2557 dev_init_timeout = jiffies + 2930 */
2558 (ha->nx_dev_init_timeout * HZ); 2931 if (is_qla8032(ha)) {
2559 } else { 2932 qla4_83xx_need_reset_handler(ha);
2560 ha->isp_ops->idc_unlock(ha); 2933 } else if (is_qla8022(ha)) {
2561 msleep(1000); 2934 if (!ql4xdontresethba) {
2562 ha->isp_ops->idc_lock(ha); 2935 qla4_82xx_need_reset_handler(ha);
2936 /* Update timeout value after need
2937 * reset handler */
2938 dev_init_timeout = jiffies +
2939 (ha->nx_dev_init_timeout * HZ);
2940 } else {
2941 ha->isp_ops->idc_unlock(ha);
2942 msleep(1000);
2943 ha->isp_ops->idc_lock(ha);
2944 }
2563 } 2945 }
2564 break; 2946 break;
2565 case QLA8XXX_DEV_NEED_QUIESCENT: 2947 case QLA8XXX_DEV_NEED_QUIESCENT:
@@ -2587,6 +2969,7 @@ int qla4_8xxx_device_state_handler(struct scsi_qla_host *ha)
2587 } 2969 }
2588exit: 2970exit:
2589 ha->isp_ops->idc_unlock(ha); 2971 ha->isp_ops->idc_unlock(ha);
2972exit_state_handler:
2590 return rval; 2973 return rval;
2591} 2974}
2592 2975
@@ -2595,8 +2978,13 @@ int qla4_8xxx_load_risc(struct scsi_qla_host *ha)
2595 int retval; 2978 int retval;
2596 2979
2597 /* clear the interrupt */ 2980 /* clear the interrupt */
2598 writel(0, &ha->qla4_82xx_reg->host_int); 2981 if (is_qla8032(ha)) {
2599 readl(&ha->qla4_82xx_reg->host_int); 2982 writel(0, &ha->qla4_83xx_reg->risc_intr);
2983 readl(&ha->qla4_83xx_reg->risc_intr);
2984 } else if (is_qla8022(ha)) {
2985 writel(0, &ha->qla4_82xx_reg->host_int);
2986 readl(&ha->qla4_82xx_reg->host_int);
2987 }
2600 2988
2601 retval = qla4_8xxx_device_state_handler(ha); 2989 retval = qla4_8xxx_device_state_handler(ha);
2602 2990
@@ -2695,7 +3083,7 @@ qla4_8xxx_get_flt_info(struct scsi_qla_host *ha, uint32_t flt_addr)
2695 const char *loc, *locations[] = { "DEF", "FLT" }; 3083 const char *loc, *locations[] = { "DEF", "FLT" };
2696 uint16_t *wptr; 3084 uint16_t *wptr;
2697 uint16_t cnt, chksum; 3085 uint16_t cnt, chksum;
2698 uint32_t start; 3086 uint32_t start, status;
2699 struct qla_flt_header *flt; 3087 struct qla_flt_header *flt;
2700 struct qla_flt_region *region; 3088 struct qla_flt_region *region;
2701 struct ql82xx_hw_data *hw = &ha->hw; 3089 struct ql82xx_hw_data *hw = &ha->hw;
@@ -2704,8 +3092,18 @@ qla4_8xxx_get_flt_info(struct scsi_qla_host *ha, uint32_t flt_addr)
2704 wptr = (uint16_t *)ha->request_ring; 3092 wptr = (uint16_t *)ha->request_ring;
2705 flt = (struct qla_flt_header *)ha->request_ring; 3093 flt = (struct qla_flt_header *)ha->request_ring;
2706 region = (struct qla_flt_region *)&flt[1]; 3094 region = (struct qla_flt_region *)&flt[1];
2707 qla4_82xx_read_optrom_data(ha, (uint8_t *)ha->request_ring, 3095
2708 flt_addr << 2, OPTROM_BURST_SIZE); 3096 if (is_qla8022(ha)) {
3097 qla4_82xx_read_optrom_data(ha, (uint8_t *)ha->request_ring,
3098 flt_addr << 2, OPTROM_BURST_SIZE);
3099 } else if (is_qla8032(ha)) {
3100 status = qla4_83xx_flash_read_u32(ha, flt_addr << 2,
3101 (uint8_t *)ha->request_ring,
3102 0x400);
3103 if (status != QLA_SUCCESS)
3104 goto no_flash_data;
3105 }
3106
2709 if (*wptr == __constant_cpu_to_le16(0xffff)) 3107 if (*wptr == __constant_cpu_to_le16(0xffff))
2710 goto no_flash_data; 3108 goto no_flash_data;
2711 if (flt->version != __constant_cpu_to_le16(1)) { 3109 if (flt->version != __constant_cpu_to_le16(1)) {
@@ -2918,8 +3316,12 @@ qla4_8xxx_get_flash_info(struct scsi_qla_host *ha)
2918 return ret; 3316 return ret;
2919 3317
2920 qla4_8xxx_get_flt_info(ha, flt_addr); 3318 qla4_8xxx_get_flt_info(ha, flt_addr);
2921 qla4_82xx_get_fdt_info(ha); 3319 if (is_qla8022(ha)) {
2922 qla4_82xx_get_idc_param(ha); 3320 qla4_82xx_get_fdt_info(ha);
3321 qla4_82xx_get_idc_param(ha);
3322 } else if (is_qla8032(ha)) {
3323 qla4_83xx_get_idc_param(ha);
3324 }
2923 3325
2924 return QLA_SUCCESS; 3326 return QLA_SUCCESS;
2925} 3327}
@@ -3063,8 +3465,7 @@ exit_validate_mac82:
3063 3465
3064/* Interrupt handling helpers. */ 3466/* Interrupt handling helpers. */
3065 3467
3066static int 3468int qla4_8xxx_mbx_intr_enable(struct scsi_qla_host *ha)
3067qla4_8xxx_mbx_intr_enable(struct scsi_qla_host *ha)
3068{ 3469{
3069 uint32_t mbox_cmd[MBOX_REG_COUNT]; 3470 uint32_t mbox_cmd[MBOX_REG_COUNT];
3070 uint32_t mbox_sts[MBOX_REG_COUNT]; 3471 uint32_t mbox_sts[MBOX_REG_COUNT];
@@ -3085,8 +3486,7 @@ qla4_8xxx_mbx_intr_enable(struct scsi_qla_host *ha)
3085 return QLA_SUCCESS; 3486 return QLA_SUCCESS;
3086} 3487}
3087 3488
3088static int 3489int qla4_8xxx_mbx_intr_disable(struct scsi_qla_host *ha)
3089qla4_8xxx_mbx_intr_disable(struct scsi_qla_host *ha)
3090{ 3490{
3091 uint32_t mbox_cmd[MBOX_REG_COUNT]; 3491 uint32_t mbox_cmd[MBOX_REG_COUNT];
3092 uint32_t mbox_sts[MBOX_REG_COUNT]; 3492 uint32_t mbox_sts[MBOX_REG_COUNT];
diff --git a/drivers/scsi/qla4xxx/ql4_nx.h b/drivers/scsi/qla4xxx/ql4_nx.h
index 1894de093f06..ec5cbd003bae 100644
--- a/drivers/scsi/qla4xxx/ql4_nx.h
+++ b/drivers/scsi/qla4xxx/ql4_nx.h
@@ -25,6 +25,8 @@
25#define CRB_RCVPEG_STATE QLA82XX_REG(0x13c) 25#define CRB_RCVPEG_STATE QLA82XX_REG(0x13c)
26#define CRB_DMA_SHIFT QLA82XX_REG(0xcc) 26#define CRB_DMA_SHIFT QLA82XX_REG(0xcc)
27#define CRB_TEMP_STATE QLA82XX_REG(0x1b4) 27#define CRB_TEMP_STATE QLA82XX_REG(0x1b4)
28#define CRB_CMDPEG_CHECK_RETRY_COUNT 60
29#define CRB_CMDPEG_CHECK_DELAY 500
28 30
29#define qla82xx_get_temp_val(x) ((x) >> 16) 31#define qla82xx_get_temp_val(x) ((x) >> 16)
30#define qla82xx_get_temp_state(x) ((x) & 0xffff) 32#define qla82xx_get_temp_state(x) ((x) & 0xffff)
@@ -508,6 +510,7 @@ enum {
508 510
509#define QLA82XX_P2_ADDR_QDR_NET_MAX (0x00000003001fffffULL) 511#define QLA82XX_P2_ADDR_QDR_NET_MAX (0x00000003001fffffULL)
510#define QLA82XX_P3_ADDR_QDR_NET_MAX (0x0000000303ffffffULL) 512#define QLA82XX_P3_ADDR_QDR_NET_MAX (0x0000000303ffffffULL)
513#define QLA8XXX_ADDR_QDR_NET_MAX (0x0000000307ffffffULL)
511 514
512#define QLA82XX_PCI_CRBSPACE (unsigned long)0x06000000 515#define QLA82XX_PCI_CRBSPACE (unsigned long)0x06000000
513#define QLA82XX_PCI_DIRECT_CRB (unsigned long)0x04400000 516#define QLA82XX_PCI_DIRECT_CRB (unsigned long)0x04400000
@@ -852,9 +855,13 @@ struct crb_addr_pair {
852#define QLA8XXX_L2ITG 22 855#define QLA8XXX_L2ITG 22
853#define QLA8XXX_L2DAT 23 856#define QLA8XXX_L2DAT 23
854#define QLA8XXX_L2INS 24 857#define QLA8XXX_L2INS 24
858#define QLA83XX_POLLRD 35
859#define QLA83XX_RDMUX2 36
860#define QLA83XX_POLLRDMWR 37
855#define QLA8XXX_RDROM 71 861#define QLA8XXX_RDROM 71
856#define QLA8XXX_RDMEM 72 862#define QLA8XXX_RDMEM 72
857#define QLA8XXX_CNTRL 98 863#define QLA8XXX_CNTRL 98
864#define QLA83XX_TLHDR 99
858#define QLA8XXX_RDEND 255 865#define QLA8XXX_RDEND 255
859 866
860/* Opcodes for Control Entries. 867/* Opcodes for Control Entries.
@@ -1007,6 +1014,16 @@ struct qla8xxx_minidump_entry_queue {
1007#define MD_MIU_TEST_AGT_ADDR_LO 0x41000094 1014#define MD_MIU_TEST_AGT_ADDR_LO 0x41000094
1008#define MD_MIU_TEST_AGT_ADDR_HI 0x41000098 1015#define MD_MIU_TEST_AGT_ADDR_HI 0x41000098
1009 1016
1017#define MD_MIU_TEST_AGT_WRDATA_LO 0x410000A0
1018#define MD_MIU_TEST_AGT_WRDATA_HI 0x410000A4
1019#define MD_MIU_TEST_AGT_WRDATA_ULO 0x410000B0
1020#define MD_MIU_TEST_AGT_WRDATA_UHI 0x410000B4
1021
1022#define MD_MIU_TEST_AGT_RDDATA_LO 0x410000A8
1023#define MD_MIU_TEST_AGT_RDDATA_HI 0x410000AC
1024#define MD_MIU_TEST_AGT_RDDATA_ULO 0x410000B8
1025#define MD_MIU_TEST_AGT_RDDATA_UHI 0x410000BC
1026
1010static const int MD_MIU_TEST_AGT_RDDATA[] = { 0x410000A8, 1027static const int MD_MIU_TEST_AGT_RDDATA[] = { 0x410000A8,
1011 0x410000AC, 0x410000B8, 0x410000BC }; 1028 0x410000AC, 0x410000B8, 0x410000BC };
1012#endif 1029#endif
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 519f6667dc02..3e0e5de2c335 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -18,6 +18,7 @@
18#include "ql4_glbl.h" 18#include "ql4_glbl.h"
19#include "ql4_dbg.h" 19#include "ql4_dbg.h"
20#include "ql4_inline.h" 20#include "ql4_inline.h"
21#include "ql4_83xx.h"
21 22
22/* 23/*
23 * Driver version 24 * Driver version
@@ -2315,8 +2316,17 @@ static void qla4xxx_mem_free(struct scsi_qla_host *ha)
2315 if (ha->nx_pcibase) 2316 if (ha->nx_pcibase)
2316 iounmap( 2317 iounmap(
2317 (struct device_reg_82xx __iomem *)ha->nx_pcibase); 2318 (struct device_reg_82xx __iomem *)ha->nx_pcibase);
2318 } else if (ha->reg) 2319 } else if (is_qla8032(ha)) {
2320 if (ha->nx_pcibase)
2321 iounmap(
2322 (struct device_reg_83xx __iomem *)ha->nx_pcibase);
2323 } else if (ha->reg) {
2319 iounmap(ha->reg); 2324 iounmap(ha->reg);
2325 }
2326
2327 if (ha->reset_tmplt.buff)
2328 vfree(ha->reset_tmplt.buff);
2329
2320 pci_release_regions(ha->pdev); 2330 pci_release_regions(ha->pdev);
2321} 2331}
2322 2332
@@ -2454,7 +2464,6 @@ static int qla4_8xxx_check_temp(struct scsi_qla_host *ha)
2454static int qla4_8xxx_check_fw_alive(struct scsi_qla_host *ha) 2464static int qla4_8xxx_check_fw_alive(struct scsi_qla_host *ha)
2455{ 2465{
2456 uint32_t fw_heartbeat_counter; 2466 uint32_t fw_heartbeat_counter;
2457 uint32_t halt_status1, halt_status2;
2458 int status = QLA_SUCCESS; 2467 int status = QLA_SUCCESS;
2459 2468
2460 fw_heartbeat_counter = qla4_8xxx_rd_direct(ha, 2469 fw_heartbeat_counter = qla4_8xxx_rd_direct(ha,
@@ -2472,28 +2481,7 @@ static int qla4_8xxx_check_fw_alive(struct scsi_qla_host *ha)
2472 /* FW not alive after 2 seconds */ 2481 /* FW not alive after 2 seconds */
2473 if (ha->seconds_since_last_heartbeat == 2) { 2482 if (ha->seconds_since_last_heartbeat == 2) {
2474 ha->seconds_since_last_heartbeat = 0; 2483 ha->seconds_since_last_heartbeat = 0;
2475 halt_status1 = qla4_8xxx_rd_direct(ha, 2484 qla4_8xxx_dump_peg_reg(ha);
2476 QLA8XXX_PEG_HALT_STATUS1);
2477 halt_status2 = qla4_8xxx_rd_direct(ha,
2478 QLA8XXX_PEG_HALT_STATUS2);
2479
2480 ql4_printk(KERN_INFO, ha,
2481 "scsi(%ld): %s, Dumping hw/fw registers:\n "
2482 " PEG_HALT_STATUS1: 0x%x, PEG_HALT_STATUS2:"
2483 " 0x%x,\n PEG_NET_0_PC: 0x%x, PEG_NET_1_PC:"
2484 " 0x%x,\n PEG_NET_2_PC: 0x%x, PEG_NET_3_PC:"
2485 " 0x%x,\n PEG_NET_4_PC: 0x%x\n", ha->host_no,
2486 __func__, halt_status1, halt_status2,
2487 qla4_82xx_rd_32(ha, QLA82XX_CRB_PEG_NET_0 +
2488 0x3c),
2489 qla4_82xx_rd_32(ha, QLA82XX_CRB_PEG_NET_1 +
2490 0x3c),
2491 qla4_82xx_rd_32(ha, QLA82XX_CRB_PEG_NET_2 +
2492 0x3c),
2493 qla4_82xx_rd_32(ha, QLA82XX_CRB_PEG_NET_3 +
2494 0x3c),
2495 qla4_82xx_rd_32(ha, QLA82XX_CRB_PEG_NET_4 +
2496 0x3c));
2497 status = QLA_ERROR; 2485 status = QLA_ERROR;
2498 } 2486 }
2499 } else 2487 } else
@@ -2503,6 +2491,48 @@ static int qla4_8xxx_check_fw_alive(struct scsi_qla_host *ha)
2503 return status; 2491 return status;
2504} 2492}
2505 2493
2494static void qla4_8xxx_process_fw_error(struct scsi_qla_host *ha)
2495{
2496 uint32_t halt_status;
2497 int halt_status_unrecoverable = 0;
2498
2499 halt_status = qla4_8xxx_rd_direct(ha, QLA8XXX_PEG_HALT_STATUS1);
2500
2501 if (is_qla8022(ha)) {
2502 ql4_printk(KERN_INFO, ha, "%s: disabling pause transmit on port 0 & 1.\n",
2503 __func__);
2504 qla4_82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x98,
2505 CRB_NIU_XG_PAUSE_CTL_P0 |
2506 CRB_NIU_XG_PAUSE_CTL_P1);
2507
2508 if (QLA82XX_FWERROR_CODE(halt_status) == 0x67)
2509 ql4_printk(KERN_ERR, ha, "%s: Firmware aborted with error code 0x00006700. Device is being reset\n",
2510 __func__);
2511 if (halt_status & HALT_STATUS_UNRECOVERABLE)
2512 halt_status_unrecoverable = 1;
2513 } else if (is_qla8032(ha)) {
2514 if (halt_status & QLA83XX_HALT_STATUS_FW_RESET)
2515 ql4_printk(KERN_ERR, ha, "%s: Firmware error detected device is being reset\n",
2516 __func__);
2517 else if (halt_status & QLA83XX_HALT_STATUS_UNRECOVERABLE)
2518 halt_status_unrecoverable = 1;
2519 }
2520
2521 /*
2522 * Since we cannot change dev_state in interrupt context,
2523 * set appropriate DPC flag then wakeup DPC
2524 */
2525 if (halt_status_unrecoverable) {
2526 set_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags);
2527 } else {
2528 ql4_printk(KERN_INFO, ha, "%s: detect abort needed!\n",
2529 __func__);
2530 set_bit(DPC_RESET_HA, &ha->dpc_flags);
2531 }
2532 qla4xxx_mailbox_premature_completion(ha);
2533 qla4xxx_wake_dpc(ha);
2534}
2535
2506/** 2536/**
2507 * qla4_8xxx_watchdog - Poll dev state 2537 * qla4_8xxx_watchdog - Poll dev state
2508 * @ha: Pointer to host adapter structure. 2538 * @ha: Pointer to host adapter structure.
@@ -2511,7 +2541,7 @@ static int qla4_8xxx_check_fw_alive(struct scsi_qla_host *ha)
2511 **/ 2541 **/
2512void qla4_8xxx_watchdog(struct scsi_qla_host *ha) 2542void qla4_8xxx_watchdog(struct scsi_qla_host *ha)
2513{ 2543{
2514 uint32_t dev_state, halt_status; 2544 uint32_t dev_state;
2515 2545
2516 /* don't poll if reset is going on */ 2546 /* don't poll if reset is going on */
2517 if (!(test_bit(DPC_RESET_ACTIVE, &ha->dpc_flags) || 2547 if (!(test_bit(DPC_RESET_ACTIVE, &ha->dpc_flags) ||
@@ -2520,16 +2550,18 @@ void qla4_8xxx_watchdog(struct scsi_qla_host *ha)
2520 dev_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE); 2550 dev_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE);
2521 2551
2522 if (qla4_8xxx_check_temp(ha)) { 2552 if (qla4_8xxx_check_temp(ha)) {
2523 ql4_printk(KERN_INFO, ha, "disabling pause" 2553 if (is_qla8022(ha)) {
2524 " transmit on port 0 & 1.\n"); 2554 ql4_printk(KERN_INFO, ha, "disabling pause transmit on port 0 & 1.\n");
2525 qla4_82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x98, 2555 qla4_82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x98,
2526 CRB_NIU_XG_PAUSE_CTL_P0 | 2556 CRB_NIU_XG_PAUSE_CTL_P0 |
2527 CRB_NIU_XG_PAUSE_CTL_P1); 2557 CRB_NIU_XG_PAUSE_CTL_P1);
2558 }
2528 set_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags); 2559 set_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags);
2529 qla4xxx_wake_dpc(ha); 2560 qla4xxx_wake_dpc(ha);
2530 } else if (dev_state == QLA8XXX_DEV_NEED_RESET && 2561 } else if (dev_state == QLA8XXX_DEV_NEED_RESET &&
2531 !test_bit(DPC_RESET_HA, &ha->dpc_flags)) { 2562 !test_bit(DPC_RESET_HA, &ha->dpc_flags)) {
2532 if (!ql4xdontresethba) { 2563 if (is_qla8032(ha) ||
2564 (is_qla8022(ha) && !ql4xdontresethba)) {
2533 ql4_printk(KERN_INFO, ha, "%s: HW State: " 2565 ql4_printk(KERN_INFO, ha, "%s: HW State: "
2534 "NEED RESET!\n", __func__); 2566 "NEED RESET!\n", __func__);
2535 set_bit(DPC_RESET_HA, &ha->dpc_flags); 2567 set_bit(DPC_RESET_HA, &ha->dpc_flags);
@@ -2543,36 +2575,8 @@ void qla4_8xxx_watchdog(struct scsi_qla_host *ha)
2543 qla4xxx_wake_dpc(ha); 2575 qla4xxx_wake_dpc(ha);
2544 } else { 2576 } else {
2545 /* Check firmware health */ 2577 /* Check firmware health */
2546 if (qla4_8xxx_check_fw_alive(ha)) { 2578 if (qla4_8xxx_check_fw_alive(ha))
2547 ql4_printk(KERN_INFO, ha, "disabling pause" 2579 qla4_8xxx_process_fw_error(ha);
2548 " transmit on port 0 & 1.\n");
2549 qla4_82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x98,
2550 CRB_NIU_XG_PAUSE_CTL_P0 |
2551 CRB_NIU_XG_PAUSE_CTL_P1);
2552 halt_status = qla4_8xxx_rd_direct(ha,
2553 QLA8XXX_PEG_HALT_STATUS1);
2554
2555 if (QLA82XX_FWERROR_CODE(halt_status) == 0x67)
2556 ql4_printk(KERN_ERR, ha, "%s:"
2557 " Firmware aborted with"
2558 " error code 0x00006700."
2559 " Device is being reset\n",
2560 __func__);
2561
2562 /* Since we cannot change dev_state in interrupt
2563 * context, set appropriate DPC flag then wakeup
2564 * DPC */
2565 if (halt_status & HALT_STATUS_UNRECOVERABLE)
2566 set_bit(DPC_HA_UNRECOVERABLE,
2567 &ha->dpc_flags);
2568 else {
2569 ql4_printk(KERN_INFO, ha, "%s: detect "
2570 "abort needed!\n", __func__);
2571 set_bit(DPC_RESET_HA, &ha->dpc_flags);
2572 }
2573 qla4xxx_mailbox_premature_completion(ha);
2574 qla4xxx_wake_dpc(ha);
2575 }
2576 } 2580 }
2577 } 2581 }
2578} 2582}
@@ -2654,9 +2658,8 @@ static void qla4xxx_timer(struct scsi_qla_host *ha)
2654 if (!pci_channel_offline(ha->pdev)) 2658 if (!pci_channel_offline(ha->pdev))
2655 pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w); 2659 pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w);
2656 2660
2657 if (is_qla8022(ha)) { 2661 if (is_qla80XX(ha))
2658 qla4_8xxx_watchdog(ha); 2662 qla4_8xxx_watchdog(ha);
2659 }
2660 2663
2661 if (is_qla40XX(ha)) { 2664 if (is_qla40XX(ha)) {
2662 /* Check for heartbeat interval. */ 2665 /* Check for heartbeat interval. */
@@ -2955,9 +2958,9 @@ static int qla4xxx_recover_adapter(struct scsi_qla_host *ha)
2955 goto recover_ha_init_adapter; 2958 goto recover_ha_init_adapter;
2956 } 2959 }
2957 2960
2958 /* For the ISP-82xx adapter, issue a stop_firmware if invoked 2961 /* For the ISP-8xxx adapter, issue a stop_firmware if invoked
2959 * from eh_host_reset or ioctl module */ 2962 * from eh_host_reset or ioctl module */
2960 if (is_qla8022(ha) && !reset_chip && 2963 if (is_qla80XX(ha) && !reset_chip &&
2961 test_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags)) { 2964 test_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags)) {
2962 2965
2963 DEBUG2(ql4_printk(KERN_INFO, ha, 2966 DEBUG2(ql4_printk(KERN_INFO, ha,
@@ -2980,13 +2983,13 @@ static int qla4xxx_recover_adapter(struct scsi_qla_host *ha)
2980 } 2983 }
2981 2984
2982 /* Issue full chip reset if recovering from a catastrophic error, 2985 /* Issue full chip reset if recovering from a catastrophic error,
2983 * or if stop_firmware fails for ISP-82xx. 2986 * or if stop_firmware fails for ISP-8xxx.
2984 * This is the default case for ISP-4xxx */ 2987 * This is the default case for ISP-4xxx */
2985 if (is_qla40XX(ha) || reset_chip) { 2988 if (is_qla40XX(ha) || reset_chip) {
2986 if (is_qla40XX(ha)) 2989 if (is_qla40XX(ha))
2987 goto chip_reset; 2990 goto chip_reset;
2988 2991
2989 /* Check if 82XX firmware is alive or not 2992 /* Check if 8XXX firmware is alive or not
2990 * We may have arrived here from NEED_RESET 2993 * We may have arrived here from NEED_RESET
2991 * detection only */ 2994 * detection only */
2992 if (test_bit(AF_FW_RECOVERY, &ha->flags)) 2995 if (test_bit(AF_FW_RECOVERY, &ha->flags))
@@ -3041,7 +3044,7 @@ recover_ha_init_adapter:
3041 * Since we don't want to block the DPC for too long 3044 * Since we don't want to block the DPC for too long
3042 * with multiple resets in the same thread, 3045 * with multiple resets in the same thread,
3043 * utilize DPC to retry */ 3046 * utilize DPC to retry */
3044 if (is_qla8022(ha)) { 3047 if (is_qla80XX(ha)) {
3045 ha->isp_ops->idc_lock(ha); 3048 ha->isp_ops->idc_lock(ha);
3046 dev_state = qla4_8xxx_rd_direct(ha, 3049 dev_state = qla4_8xxx_rd_direct(ha,
3047 QLA8XXX_CRB_DEV_STATE); 3050 QLA8XXX_CRB_DEV_STATE);
@@ -3386,7 +3389,7 @@ static void qla4xxx_do_dpc(struct work_struct *work)
3386 /* post events to application */ 3389 /* post events to application */
3387 qla4xxx_do_work(ha); 3390 qla4xxx_do_work(ha);
3388 3391
3389 if (is_qla8022(ha)) { 3392 if (is_qla80XX(ha)) {
3390 if (test_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags)) { 3393 if (test_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags)) {
3391 ha->isp_ops->idc_lock(ha); 3394 ha->isp_ops->idc_lock(ha);
3392 qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE, 3395 qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
@@ -3404,7 +3407,8 @@ static void qla4xxx_do_dpc(struct work_struct *work)
3404 (test_bit(DPC_RESET_HA, &ha->dpc_flags) || 3407 (test_bit(DPC_RESET_HA, &ha->dpc_flags) ||
3405 test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags) || 3408 test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags) ||
3406 test_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags))) { 3409 test_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags))) {
3407 if (ql4xdontresethba) { 3410 if ((is_qla8022(ha) && ql4xdontresethba) ||
3411 (is_qla8032(ha) && qla4_83xx_idc_dontreset(ha))) {
3408 DEBUG2(printk("scsi%ld: %s: Don't Reset HBA\n", 3412 DEBUG2(printk("scsi%ld: %s: Don't Reset HBA\n",
3409 ha->host_no, __func__)); 3413 ha->host_no, __func__));
3410 clear_bit(DPC_RESET_HA, &ha->dpc_flags); 3414 clear_bit(DPC_RESET_HA, &ha->dpc_flags);
@@ -3514,7 +3518,7 @@ static void qla4xxx_free_adapter(struct scsi_qla_host *ha)
3514 /* Put firmware in known state */ 3518 /* Put firmware in known state */
3515 ha->isp_ops->reset_firmware(ha); 3519 ha->isp_ops->reset_firmware(ha);
3516 3520
3517 if (is_qla8022(ha)) { 3521 if (is_qla80XX(ha)) {
3518 ha->isp_ops->idc_lock(ha); 3522 ha->isp_ops->idc_lock(ha);
3519 qla4_8xxx_clear_drv_active(ha); 3523 qla4_8xxx_clear_drv_active(ha);
3520 ha->isp_ops->idc_unlock(ha); 3524 ha->isp_ops->idc_unlock(ha);
@@ -3564,16 +3568,20 @@ int qla4_8xxx_iospace_config(struct scsi_qla_host *ha)
3564 /* Mapping of IO base pointer, door bell read and write pointer */ 3568 /* Mapping of IO base pointer, door bell read and write pointer */
3565 3569
3566 /* mapping of IO base pointer */ 3570 /* mapping of IO base pointer */
3567 ha->qla4_82xx_reg = 3571 if (is_qla8022(ha)) {
3568 (struct device_reg_82xx __iomem *)((uint8_t *)ha->nx_pcibase + 3572 ha->qla4_82xx_reg = (struct device_reg_82xx __iomem *)
3569 0xbc000 + (ha->pdev->devfn << 11)); 3573 ((uint8_t *)ha->nx_pcibase + 0xbc000 +
3574 (ha->pdev->devfn << 11));
3575 ha->nx_db_wr_ptr = (ha->pdev->devfn == 4 ? QLA82XX_CAM_RAM_DB1 :
3576 QLA82XX_CAM_RAM_DB2);
3577 } else if (is_qla8032(ha)) {
3578 ha->qla4_83xx_reg = (struct device_reg_83xx __iomem *)
3579 ((uint8_t *)ha->nx_pcibase);
3580 }
3570 3581
3571 db_base = pci_resource_start(pdev, 4); /* doorbell is on bar 4 */ 3582 db_base = pci_resource_start(pdev, 4); /* doorbell is on bar 4 */
3572 db_len = pci_resource_len(pdev, 4); 3583 db_len = pci_resource_len(pdev, 4);
3573 3584
3574 ha->nx_db_wr_ptr = (ha->pdev->devfn == 4 ? QLA82XX_CAM_RAM_DB1 :
3575 QLA82XX_CAM_RAM_DB2);
3576
3577 return 0; 3585 return 0;
3578iospace_error_exit: 3586iospace_error_exit:
3579 return -ENOMEM; 3587 return -ENOMEM;
@@ -3693,6 +3701,34 @@ static struct isp_operations qla4_82xx_isp_ops = {
3693 .process_mailbox_interrupt = qla4_82xx_process_mbox_intr, 3701 .process_mailbox_interrupt = qla4_82xx_process_mbox_intr,
3694}; 3702};
3695 3703
3704static struct isp_operations qla4_83xx_isp_ops = {
3705 .iospace_config = qla4_8xxx_iospace_config,
3706 .pci_config = qla4_8xxx_pci_config,
3707 .disable_intrs = qla4_83xx_disable_intrs,
3708 .enable_intrs = qla4_83xx_enable_intrs,
3709 .start_firmware = qla4_8xxx_load_risc,
3710 .restart_firmware = qla4_83xx_start_firmware,
3711 .intr_handler = qla4_83xx_intr_handler,
3712 .interrupt_service_routine = qla4_83xx_interrupt_service_routine,
3713 .need_reset = qla4_8xxx_need_reset,
3714 .reset_chip = qla4_83xx_isp_reset,
3715 .reset_firmware = qla4_8xxx_stop_firmware,
3716 .queue_iocb = qla4_83xx_queue_iocb,
3717 .complete_iocb = qla4_83xx_complete_iocb,
3718 .rd_shdw_req_q_out = qla4_83xx_rd_shdw_req_q_out,
3719 .rd_shdw_rsp_q_in = qla4_83xx_rd_shdw_rsp_q_in,
3720 .get_sys_info = qla4_8xxx_get_sys_info,
3721 .rd_reg_direct = qla4_83xx_rd_reg,
3722 .wr_reg_direct = qla4_83xx_wr_reg,
3723 .rd_reg_indirect = qla4_83xx_rd_reg_indirect,
3724 .wr_reg_indirect = qla4_83xx_wr_reg_indirect,
3725 .idc_lock = qla4_83xx_drv_lock,
3726 .idc_unlock = qla4_83xx_drv_unlock,
3727 .rom_lock_recovery = qla4_83xx_rom_lock_recovery,
3728 .queue_mailbox_command = qla4_83xx_queue_mbox_cmd,
3729 .process_mailbox_interrupt = qla4_83xx_process_mbox_intr,
3730};
3731
3696uint16_t qla4xxx_rd_shdw_req_q_out(struct scsi_qla_host *ha) 3732uint16_t qla4xxx_rd_shdw_req_q_out(struct scsi_qla_host *ha)
3697{ 3733{
3698 return (uint16_t)le32_to_cpu(ha->shadow_regs->req_q_out); 3734 return (uint16_t)le32_to_cpu(ha->shadow_regs->req_q_out);
@@ -3703,6 +3739,11 @@ uint16_t qla4_82xx_rd_shdw_req_q_out(struct scsi_qla_host *ha)
3703 return (uint16_t)le32_to_cpu(readl(&ha->qla4_82xx_reg->req_q_out)); 3739 return (uint16_t)le32_to_cpu(readl(&ha->qla4_82xx_reg->req_q_out));
3704} 3740}
3705 3741
3742uint16_t qla4_83xx_rd_shdw_req_q_out(struct scsi_qla_host *ha)
3743{
3744 return (uint16_t)le32_to_cpu(readl(&ha->qla4_83xx_reg->req_q_out));
3745}
3746
3706uint16_t qla4xxx_rd_shdw_rsp_q_in(struct scsi_qla_host *ha) 3747uint16_t qla4xxx_rd_shdw_rsp_q_in(struct scsi_qla_host *ha)
3707{ 3748{
3708 return (uint16_t)le32_to_cpu(ha->shadow_regs->rsp_q_in); 3749 return (uint16_t)le32_to_cpu(ha->shadow_regs->rsp_q_in);
@@ -3713,6 +3754,11 @@ uint16_t qla4_82xx_rd_shdw_rsp_q_in(struct scsi_qla_host *ha)
3713 return (uint16_t)le32_to_cpu(readl(&ha->qla4_82xx_reg->rsp_q_in)); 3754 return (uint16_t)le32_to_cpu(readl(&ha->qla4_82xx_reg->rsp_q_in));
3714} 3755}
3715 3756
3757uint16_t qla4_83xx_rd_shdw_rsp_q_in(struct scsi_qla_host *ha)
3758{
3759 return (uint16_t)le32_to_cpu(readl(&ha->qla4_83xx_reg->rsp_q_in));
3760}
3761
3716static ssize_t qla4xxx_show_boot_eth_info(void *data, int type, char *buf) 3762static ssize_t qla4xxx_show_boot_eth_info(void *data, int type, char *buf)
3717{ 3763{
3718 struct scsi_qla_host *ha = data; 3764 struct scsi_qla_host *ha = data;
@@ -5085,6 +5131,7 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
5085 ha->pdev = pdev; 5131 ha->pdev = pdev;
5086 ha->host = host; 5132 ha->host = host;
5087 ha->host_no = host->host_no; 5133 ha->host_no = host->host_no;
5134 ha->func_num = PCI_FUNC(ha->pdev->devfn);
5088 5135
5089 pci_enable_pcie_error_reporting(pdev); 5136 pci_enable_pcie_error_reporting(pdev);
5090 5137
@@ -5092,24 +5139,28 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
5092 if (is_qla8022(ha)) { 5139 if (is_qla8022(ha)) {
5093 ha->isp_ops = &qla4_82xx_isp_ops; 5140 ha->isp_ops = &qla4_82xx_isp_ops;
5094 ha->reg_tbl = (uint32_t *) qla4_82xx_reg_tbl; 5141 ha->reg_tbl = (uint32_t *) qla4_82xx_reg_tbl;
5095 rwlock_init(&ha->hw_lock);
5096 ha->qdr_sn_window = -1; 5142 ha->qdr_sn_window = -1;
5097 ha->ddr_mn_window = -1; 5143 ha->ddr_mn_window = -1;
5098 ha->curr_window = 255; 5144 ha->curr_window = 255;
5099 ha->func_num = PCI_FUNC(ha->pdev->devfn);
5100 nx_legacy_intr = &legacy_intr[ha->func_num]; 5145 nx_legacy_intr = &legacy_intr[ha->func_num];
5101 ha->nx_legacy_intr.int_vec_bit = nx_legacy_intr->int_vec_bit; 5146 ha->nx_legacy_intr.int_vec_bit = nx_legacy_intr->int_vec_bit;
5102 ha->nx_legacy_intr.tgt_status_reg = 5147 ha->nx_legacy_intr.tgt_status_reg =
5103 nx_legacy_intr->tgt_status_reg; 5148 nx_legacy_intr->tgt_status_reg;
5104 ha->nx_legacy_intr.tgt_mask_reg = nx_legacy_intr->tgt_mask_reg; 5149 ha->nx_legacy_intr.tgt_mask_reg = nx_legacy_intr->tgt_mask_reg;
5105 ha->nx_legacy_intr.pci_int_reg = nx_legacy_intr->pci_int_reg; 5150 ha->nx_legacy_intr.pci_int_reg = nx_legacy_intr->pci_int_reg;
5151 } else if (is_qla8032(ha)) {
5152 ha->isp_ops = &qla4_83xx_isp_ops;
5153 ha->reg_tbl = (uint32_t *)qla4_83xx_reg_tbl;
5106 } else { 5154 } else {
5107 ha->isp_ops = &qla4xxx_isp_ops; 5155 ha->isp_ops = &qla4xxx_isp_ops;
5108 } 5156 }
5109 5157
5110 /* Set EEH reset type to fundamental if required by hba */ 5158 if (is_qla80XX(ha)) {
5111 if (is_qla8022(ha)) 5159 rwlock_init(&ha->hw_lock);
5160 ha->pf_bit = ha->func_num << 16;
5161 /* Set EEH reset type to fundamental if required by hba */
5112 pdev->needs_freset = 1; 5162 pdev->needs_freset = 1;
5163 }
5113 5164
5114 /* Configure PCI I/O space. */ 5165 /* Configure PCI I/O space. */
5115 ret = ha->isp_ops->iospace_config(ha); 5166 ret = ha->isp_ops->iospace_config(ha);
@@ -5165,8 +5216,20 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
5165 if (ret) 5216 if (ret)
5166 goto probe_failed; 5217 goto probe_failed;
5167 5218
5168 if (is_qla8022(ha)) 5219 if (is_qla80XX(ha))
5169 (void) qla4_8xxx_get_flash_info(ha); 5220 qla4_8xxx_get_flash_info(ha);
5221
5222 if (is_qla8032(ha)) {
5223 qla4_83xx_read_reset_template(ha);
5224 /*
5225 * NOTE: If ql4dontresethba==1, set IDC_CTRL DONTRESET_BIT0.
5226 * If DONRESET_BIT0 is set, drivers should not set dev_state
5227 * to NEED_RESET. But if NEED_RESET is set, drivers should
5228 * should honor the reset.
5229 */
5230 if (ql4xdontresethba == 1)
5231 qla4_83xx_set_idc_dontreset(ha);
5232 }
5170 5233
5171 /* 5234 /*
5172 * Initialize the Host adapter request/response queues and 5235 * Initialize the Host adapter request/response queues and
@@ -5177,7 +5240,7 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
5177 while ((!test_bit(AF_ONLINE, &ha->flags)) && 5240 while ((!test_bit(AF_ONLINE, &ha->flags)) &&
5178 init_retry_count++ < MAX_INIT_RETRIES) { 5241 init_retry_count++ < MAX_INIT_RETRIES) {
5179 5242
5180 if (is_qla8022(ha)) { 5243 if (is_qla80XX(ha)) {
5181 ha->isp_ops->idc_lock(ha); 5244 ha->isp_ops->idc_lock(ha);
5182 dev_state = qla4_8xxx_rd_direct(ha, 5245 dev_state = qla4_8xxx_rd_direct(ha,
5183 QLA82XX_CRB_DEV_STATE); 5246 QLA82XX_CRB_DEV_STATE);
@@ -5201,7 +5264,8 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
5201 if (!test_bit(AF_ONLINE, &ha->flags)) { 5264 if (!test_bit(AF_ONLINE, &ha->flags)) {
5202 ql4_printk(KERN_WARNING, ha, "Failed to initialize adapter\n"); 5265 ql4_printk(KERN_WARNING, ha, "Failed to initialize adapter\n");
5203 5266
5204 if (is_qla8022(ha) && ql4xdontresethba) { 5267 if ((is_qla8022(ha) && ql4xdontresethba) ||
5268 (is_qla8032(ha) && qla4_83xx_idc_dontreset(ha))) {
5205 /* Put the device in failed state. */ 5269 /* Put the device in failed state. */
5206 DEBUG2(printk(KERN_ERR "HW STATE: FAILED\n")); 5270 DEBUG2(printk(KERN_ERR "HW STATE: FAILED\n"));
5207 ha->isp_ops->idc_lock(ha); 5271 ha->isp_ops->idc_lock(ha);
@@ -5233,7 +5297,8 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
5233 goto remove_host; 5297 goto remove_host;
5234 } 5298 }
5235 5299
5236 /* For ISP-82XX, request_irqs is called in qla4_8xxx_load_risc 5300 /*
5301 * For ISP-8XXX, request_irqs is called in qla4_8xxx_load_risc
5237 * (which is called indirectly by qla4xxx_initialize_adapter), 5302 * (which is called indirectly by qla4xxx_initialize_adapter),
5238 * so that irqs will be registered after crbinit but before 5303 * so that irqs will be registered after crbinit but before
5239 * mbx_intr_enable. 5304 * mbx_intr_enable.
@@ -5793,7 +5858,16 @@ static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd)
5793 5858
5794 ha = to_qla_host(cmd->device->host); 5859 ha = to_qla_host(cmd->device->host);
5795 5860
5796 if (ql4xdontresethba) { 5861 if (is_qla8032(ha) && ql4xdontresethba)
5862 qla4_83xx_set_idc_dontreset(ha);
5863
5864 /*
5865 * For ISP8324, if IDC_CTRL DONTRESET_BIT0 is set by other
5866 * protocol drivers, we should not set device_state to
5867 * NEED_RESET
5868 */
5869 if (ql4xdontresethba ||
5870 (is_qla8032(ha) && qla4_83xx_idc_dontreset(ha))) {
5797 DEBUG2(printk("scsi%ld: %s: Don't Reset HBA\n", 5871 DEBUG2(printk("scsi%ld: %s: Don't Reset HBA\n",
5798 ha->host_no, __func__)); 5872 ha->host_no, __func__));
5799 5873
@@ -5817,7 +5891,7 @@ static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd)
5817 } 5891 }
5818 5892
5819 if (!test_bit(DPC_RESET_HA, &ha->dpc_flags)) { 5893 if (!test_bit(DPC_RESET_HA, &ha->dpc_flags)) {
5820 if (is_qla8022(ha)) 5894 if (is_qla80XX(ha))
5821 set_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags); 5895 set_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags);
5822 else 5896 else
5823 set_bit(DPC_RESET_HA, &ha->dpc_flags); 5897 set_bit(DPC_RESET_HA, &ha->dpc_flags);
@@ -5912,7 +5986,7 @@ static int qla4xxx_host_reset(struct Scsi_Host *shost, int reset_type)
5912 break; 5986 break;
5913 case SCSI_FIRMWARE_RESET: 5987 case SCSI_FIRMWARE_RESET:
5914 if (!test_bit(DPC_RESET_HA, &ha->dpc_flags)) { 5988 if (!test_bit(DPC_RESET_HA, &ha->dpc_flags)) {
5915 if (is_qla8022(ha)) 5989 if (is_qla80XX(ha))
5916 /* set firmware context reset */ 5990 /* set firmware context reset */
5917 set_bit(DPC_RESET_HA_FW_CONTEXT, 5991 set_bit(DPC_RESET_HA_FW_CONTEXT,
5918 &ha->dpc_flags); 5992 &ha->dpc_flags);
@@ -6150,7 +6224,7 @@ qla4xxx_pci_slot_reset(struct pci_dev *pdev)
6150 6224
6151 ha->isp_ops->disable_intrs(ha); 6225 ha->isp_ops->disable_intrs(ha);
6152 6226
6153 if (is_qla8022(ha)) { 6227 if (is_qla80XX(ha)) {
6154 if (qla4_8xxx_error_recovery(ha) == QLA_SUCCESS) { 6228 if (qla4_8xxx_error_recovery(ha) == QLA_SUCCESS) {
6155 ret = PCI_ERS_RESULT_RECOVERED; 6229 ret = PCI_ERS_RESULT_RECOVERED;
6156 goto exit_slot_reset; 6230 goto exit_slot_reset;
@@ -6216,6 +6290,12 @@ static struct pci_device_id qla4xxx_pci_tbl[] = {
6216 .subvendor = PCI_ANY_ID, 6290 .subvendor = PCI_ANY_ID,
6217 .subdevice = PCI_ANY_ID, 6291 .subdevice = PCI_ANY_ID,
6218 }, 6292 },
6293 {
6294 .vendor = PCI_VENDOR_ID_QLOGIC,
6295 .device = PCI_DEVICE_ID_QLOGIC_ISP8324,
6296 .subvendor = PCI_ANY_ID,
6297 .subdevice = PCI_ANY_ID,
6298 },
6219 {0, 0}, 6299 {0, 0},
6220}; 6300};
6221MODULE_DEVICE_TABLE(pci, qla4xxx_pci_tbl); 6301MODULE_DEVICE_TABLE(pci, qla4xxx_pci_tbl);