aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/qla4xxx/ql4_83xx.c53
-rw-r--r--drivers/scsi/qla4xxx/ql4_def.h2
-rw-r--r--drivers/scsi/qla4xxx/ql4_glbl.h5
-rw-r--r--drivers/scsi/qla4xxx/ql4_init.c10
-rw-r--r--drivers/scsi/qla4xxx/ql4_isr.c17
-rw-r--r--drivers/scsi/qla4xxx/ql4_mbx.c41
-rw-r--r--drivers/scsi/qla4xxx/ql4_nx.c8
-rw-r--r--drivers/scsi/qla4xxx/ql4_os.c10
8 files changed, 103 insertions, 43 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_83xx.c b/drivers/scsi/qla4xxx/ql4_83xx.c
index 6e9af20be12f..417738366c1f 100644
--- a/drivers/scsi/qla4xxx/ql4_83xx.c
+++ b/drivers/scsi/qla4xxx/ql4_83xx.c
@@ -1351,31 +1351,58 @@ exit_start_fw:
1351 1351
1352/*----------------------Interrupt Related functions ---------------------*/ 1352/*----------------------Interrupt Related functions ---------------------*/
1353 1353
1354void qla4_83xx_disable_intrs(struct scsi_qla_host *ha) 1354static void qla4_83xx_disable_iocb_intrs(struct scsi_qla_host *ha)
1355{
1356 if (test_and_clear_bit(AF_83XX_IOCB_INTR_ON, &ha->flags))
1357 qla4_8xxx_intr_disable(ha);
1358}
1359
1360static void qla4_83xx_disable_mbox_intrs(struct scsi_qla_host *ha)
1355{ 1361{
1356 uint32_t mb_int, ret; 1362 uint32_t mb_int, ret;
1357 1363
1358 if (test_and_clear_bit(AF_INTERRUPTS_ON, &ha->flags)) 1364 if (test_and_clear_bit(AF_83XX_MBOX_INTR_ON, &ha->flags)) {
1359 qla4_8xxx_mbx_intr_disable(ha); 1365 ret = readl(&ha->qla4_83xx_reg->mbox_int);
1366 mb_int = ret & ~INT_ENABLE_FW_MB;
1367 writel(mb_int, &ha->qla4_83xx_reg->mbox_int);
1368 writel(1, &ha->qla4_83xx_reg->leg_int_mask);
1369 }
1370}
1360 1371
1361 ret = readl(&ha->qla4_83xx_reg->mbox_int); 1372void qla4_83xx_disable_intrs(struct scsi_qla_host *ha)
1362 mb_int = ret & ~INT_ENABLE_FW_MB; 1373{
1363 writel(mb_int, &ha->qla4_83xx_reg->mbox_int); 1374 qla4_83xx_disable_mbox_intrs(ha);
1364 writel(1, &ha->qla4_83xx_reg->leg_int_mask); 1375 qla4_83xx_disable_iocb_intrs(ha);
1365} 1376}
1366 1377
1367void qla4_83xx_enable_intrs(struct scsi_qla_host *ha) 1378static void qla4_83xx_enable_iocb_intrs(struct scsi_qla_host *ha)
1379{
1380 if (!test_bit(AF_83XX_IOCB_INTR_ON, &ha->flags)) {
1381 qla4_8xxx_intr_enable(ha);
1382 set_bit(AF_83XX_IOCB_INTR_ON, &ha->flags);
1383 }
1384}
1385
1386void qla4_83xx_enable_mbox_intrs(struct scsi_qla_host *ha)
1368{ 1387{
1369 uint32_t mb_int; 1388 uint32_t mb_int;
1370 1389
1371 qla4_8xxx_mbx_intr_enable(ha); 1390 if (!test_bit(AF_83XX_MBOX_INTR_ON, &ha->flags)) {
1372 mb_int = INT_ENABLE_FW_MB; 1391 mb_int = INT_ENABLE_FW_MB;
1373 writel(mb_int, &ha->qla4_83xx_reg->mbox_int); 1392 writel(mb_int, &ha->qla4_83xx_reg->mbox_int);
1374 writel(0, &ha->qla4_83xx_reg->leg_int_mask); 1393 writel(0, &ha->qla4_83xx_reg->leg_int_mask);
1394 set_bit(AF_83XX_MBOX_INTR_ON, &ha->flags);
1395 }
1396}
1375 1397
1376 set_bit(AF_INTERRUPTS_ON, &ha->flags); 1398
1399void qla4_83xx_enable_intrs(struct scsi_qla_host *ha)
1400{
1401 qla4_83xx_enable_mbox_intrs(ha);
1402 qla4_83xx_enable_iocb_intrs(ha);
1377} 1403}
1378 1404
1405
1379void qla4_83xx_queue_mbox_cmd(struct scsi_qla_host *ha, uint32_t *mbx_cmd, 1406void qla4_83xx_queue_mbox_cmd(struct scsi_qla_host *ha, uint32_t *mbx_cmd,
1380 int incount) 1407 int incount)
1381{ 1408{
diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h
index 329d553eae94..c71a371c452b 100644
--- a/drivers/scsi/qla4xxx/ql4_def.h
+++ b/drivers/scsi/qla4xxx/ql4_def.h
@@ -516,6 +516,8 @@ struct scsi_qla_host {
516#define AF_8XXX_RST_OWNER 25 /* 0x02000000 */ 516#define AF_8XXX_RST_OWNER 25 /* 0x02000000 */
517#define AF_82XX_DUMP_READING 26 /* 0x04000000 */ 517#define AF_82XX_DUMP_READING 26 /* 0x04000000 */
518#define AF_83XX_NO_FW_DUMP 27 /* 0x08000000 */ 518#define AF_83XX_NO_FW_DUMP 27 /* 0x08000000 */
519#define AF_83XX_IOCB_INTR_ON 28 /* 0x10000000 */
520#define AF_83XX_MBOX_INTR_ON 29 /* 0x20000000 */
519 521
520 unsigned long dpc_flags; 522 unsigned long dpc_flags;
521 523
diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h
index 57a5a3cf5770..7a2a35a4aed3 100644
--- a/drivers/scsi/qla4xxx/ql4_glbl.h
+++ b/drivers/scsi/qla4xxx/ql4_glbl.h
@@ -253,12 +253,13 @@ void qla4_8xxx_set_rst_ready(struct scsi_qla_host *ha);
253void qla4_8xxx_clear_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); 254int qla4_8xxx_device_bootstrap(struct scsi_qla_host *ha);
255void qla4_8xxx_get_minidump(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); 256int qla4_8xxx_intr_disable(struct scsi_qla_host *ha);
257int qla4_8xxx_mbx_intr_enable(struct scsi_qla_host *ha); 257int qla4_8xxx_intr_enable(struct scsi_qla_host *ha);
258int qla4_8xxx_set_param(struct scsi_qla_host *ha, int param); 258int qla4_8xxx_set_param(struct scsi_qla_host *ha, int param);
259int qla4_8xxx_update_idc_reg(struct scsi_qla_host *ha); 259int qla4_8xxx_update_idc_reg(struct scsi_qla_host *ha);
260int qla4_83xx_post_idc_ack(struct scsi_qla_host *ha); 260int qla4_83xx_post_idc_ack(struct scsi_qla_host *ha);
261void qla4_83xx_disable_pause(struct scsi_qla_host *ha); 261void qla4_83xx_disable_pause(struct scsi_qla_host *ha);
262void qla4_83xx_enable_mbox_intrs(struct scsi_qla_host *ha);
262 263
263extern int ql4xextended_error_logging; 264extern int ql4xextended_error_logging;
264extern int ql4xdontresethba; 265extern int ql4xdontresethba;
diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c
index 1aca1b4f70b8..2045fd79095f 100644
--- a/drivers/scsi/qla4xxx/ql4_init.c
+++ b/drivers/scsi/qla4xxx/ql4_init.c
@@ -935,6 +935,16 @@ int qla4xxx_initialize_adapter(struct scsi_qla_host *ha, int is_reset)
935 if (ha->isp_ops->start_firmware(ha) == QLA_ERROR) 935 if (ha->isp_ops->start_firmware(ha) == QLA_ERROR)
936 goto exit_init_hba; 936 goto exit_init_hba;
937 937
938 /*
939 * For ISP83XX, mailbox and IOCB interrupts are enabled separately.
940 * Mailbox interrupts must be enabled prior to issuing any mailbox
941 * command in order to prevent the possibility of losing interrupts
942 * while switching from polling to interrupt mode. IOCB interrupts are
943 * enabled via isp_ops->enable_intrs.
944 */
945 if (is_qla8032(ha))
946 qla4_83xx_enable_mbox_intrs(ha);
947
938 if (qla4xxx_about_firmware(ha) == QLA_ERROR) 948 if (qla4xxx_about_firmware(ha) == QLA_ERROR)
939 goto exit_init_hba; 949 goto exit_init_hba;
940 950
diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c
index 15ea81465ce4..acbc2feaa005 100644
--- a/drivers/scsi/qla4xxx/ql4_isr.c
+++ b/drivers/scsi/qla4xxx/ql4_isr.c
@@ -1437,11 +1437,14 @@ irq_not_attached:
1437 1437
1438void qla4xxx_free_irqs(struct scsi_qla_host *ha) 1438void qla4xxx_free_irqs(struct scsi_qla_host *ha)
1439{ 1439{
1440 if (test_bit(AF_MSIX_ENABLED, &ha->flags)) 1440 if (test_and_clear_bit(AF_IRQ_ATTACHED, &ha->flags)) {
1441 qla4_8xxx_disable_msix(ha); 1441 if (test_bit(AF_MSIX_ENABLED, &ha->flags)) {
1442 else if (test_and_clear_bit(AF_MSI_ENABLED, &ha->flags)) { 1442 qla4_8xxx_disable_msix(ha);
1443 free_irq(ha->pdev->irq, ha); 1443 } else if (test_and_clear_bit(AF_MSI_ENABLED, &ha->flags)) {
1444 pci_disable_msi(ha->pdev); 1444 free_irq(ha->pdev->irq, ha);
1445 } else if (test_and_clear_bit(AF_INTx_ENABLED, &ha->flags)) 1445 pci_disable_msi(ha->pdev);
1446 free_irq(ha->pdev->irq, ha); 1446 } else if (test_and_clear_bit(AF_INTx_ENABLED, &ha->flags)) {
1447 free_irq(ha->pdev->irq, ha);
1448 }
1449 }
1447} 1450}
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c
index 3d41034191f0..1c57c227c808 100644
--- a/drivers/scsi/qla4xxx/ql4_mbx.c
+++ b/drivers/scsi/qla4xxx/ql4_mbx.c
@@ -44,6 +44,30 @@ void qla4xxx_process_mbox_intr(struct scsi_qla_host *ha, int out_count)
44} 44}
45 45
46/** 46/**
47 * qla4xxx_is_intr_poll_mode – Are we allowed to poll for interrupts?
48 * @ha: Pointer to host adapter structure.
49 * @ret: 1=polling mode, 0=non-polling mode
50 **/
51static int qla4xxx_is_intr_poll_mode(struct scsi_qla_host *ha)
52{
53 int rval = 1;
54
55 if (is_qla8032(ha)) {
56 if (test_bit(AF_IRQ_ATTACHED, &ha->flags) &&
57 test_bit(AF_83XX_MBOX_INTR_ON, &ha->flags))
58 rval = 0;
59 } else {
60 if (test_bit(AF_IRQ_ATTACHED, &ha->flags) &&
61 test_bit(AF_INTERRUPTS_ON, &ha->flags) &&
62 test_bit(AF_ONLINE, &ha->flags) &&
63 !test_bit(AF_HA_REMOVAL, &ha->flags))
64 rval = 0;
65 }
66
67 return rval;
68}
69
70/**
47 * qla4xxx_mailbox_command - issues mailbox commands 71 * qla4xxx_mailbox_command - issues mailbox commands
48 * @ha: Pointer to host adapter structure. 72 * @ha: Pointer to host adapter structure.
49 * @inCount: number of mailbox registers to load. 73 * @inCount: number of mailbox registers to load.
@@ -153,33 +177,28 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
153 /* 177 /*
154 * Wait for completion: Poll or completion queue 178 * Wait for completion: Poll or completion queue
155 */ 179 */
156 if (test_bit(AF_IRQ_ATTACHED, &ha->flags) && 180 if (qla4xxx_is_intr_poll_mode(ha)) {
157 test_bit(AF_INTERRUPTS_ON, &ha->flags) &&
158 test_bit(AF_ONLINE, &ha->flags) &&
159 !test_bit(AF_HA_REMOVAL, &ha->flags)) {
160 /* Do not poll for completion. Use completion queue */
161 set_bit(AF_MBOX_COMMAND_NOPOLL, &ha->flags);
162 wait_for_completion_timeout(&ha->mbx_intr_comp, MBOX_TOV * HZ);
163 clear_bit(AF_MBOX_COMMAND_NOPOLL, &ha->flags);
164 } else {
165 /* Poll for command to complete */ 181 /* Poll for command to complete */
166 wait_count = jiffies + MBOX_TOV * HZ; 182 wait_count = jiffies + MBOX_TOV * HZ;
167 while (test_bit(AF_MBOX_COMMAND_DONE, &ha->flags) == 0) { 183 while (test_bit(AF_MBOX_COMMAND_DONE, &ha->flags) == 0) {
168 if (time_after_eq(jiffies, wait_count)) 184 if (time_after_eq(jiffies, wait_count))
169 break; 185 break;
170
171 /* 186 /*
172 * Service the interrupt. 187 * Service the interrupt.
173 * The ISR will save the mailbox status registers 188 * The ISR will save the mailbox status registers
174 * to a temporary storage location in the adapter 189 * to a temporary storage location in the adapter
175 * structure. 190 * structure.
176 */ 191 */
177
178 spin_lock_irqsave(&ha->hardware_lock, flags); 192 spin_lock_irqsave(&ha->hardware_lock, flags);
179 ha->isp_ops->process_mailbox_interrupt(ha, outCount); 193 ha->isp_ops->process_mailbox_interrupt(ha, outCount);
180 spin_unlock_irqrestore(&ha->hardware_lock, flags); 194 spin_unlock_irqrestore(&ha->hardware_lock, flags);
181 msleep(10); 195 msleep(10);
182 } 196 }
197 } else {
198 /* Do not poll for completion. Use completion queue */
199 set_bit(AF_MBOX_COMMAND_NOPOLL, &ha->flags);
200 wait_for_completion_timeout(&ha->mbx_intr_comp, MBOX_TOV * HZ);
201 clear_bit(AF_MBOX_COMMAND_NOPOLL, &ha->flags);
183 } 202 }
184 203
185 /* Check for mailbox timeout. */ 204 /* Check for mailbox timeout. */
diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c
index 499a92db1cf6..491668d439a2 100644
--- a/drivers/scsi/qla4xxx/ql4_nx.c
+++ b/drivers/scsi/qla4xxx/ql4_nx.c
@@ -3463,7 +3463,7 @@ exit_validate_mac82:
3463 3463
3464/* Interrupt handling helpers. */ 3464/* Interrupt handling helpers. */
3465 3465
3466int qla4_8xxx_mbx_intr_enable(struct scsi_qla_host *ha) 3466int qla4_8xxx_intr_enable(struct scsi_qla_host *ha)
3467{ 3467{
3468 uint32_t mbox_cmd[MBOX_REG_COUNT]; 3468 uint32_t mbox_cmd[MBOX_REG_COUNT];
3469 uint32_t mbox_sts[MBOX_REG_COUNT]; 3469 uint32_t mbox_sts[MBOX_REG_COUNT];
@@ -3484,7 +3484,7 @@ int qla4_8xxx_mbx_intr_enable(struct scsi_qla_host *ha)
3484 return QLA_SUCCESS; 3484 return QLA_SUCCESS;
3485} 3485}
3486 3486
3487int qla4_8xxx_mbx_intr_disable(struct scsi_qla_host *ha) 3487int qla4_8xxx_intr_disable(struct scsi_qla_host *ha)
3488{ 3488{
3489 uint32_t mbox_cmd[MBOX_REG_COUNT]; 3489 uint32_t mbox_cmd[MBOX_REG_COUNT];
3490 uint32_t mbox_sts[MBOX_REG_COUNT]; 3490 uint32_t mbox_sts[MBOX_REG_COUNT];
@@ -3509,7 +3509,7 @@ int qla4_8xxx_mbx_intr_disable(struct scsi_qla_host *ha)
3509void 3509void
3510qla4_82xx_enable_intrs(struct scsi_qla_host *ha) 3510qla4_82xx_enable_intrs(struct scsi_qla_host *ha)
3511{ 3511{
3512 qla4_8xxx_mbx_intr_enable(ha); 3512 qla4_8xxx_intr_enable(ha);
3513 3513
3514 spin_lock_irq(&ha->hardware_lock); 3514 spin_lock_irq(&ha->hardware_lock);
3515 /* BIT 10 - reset */ 3515 /* BIT 10 - reset */
@@ -3522,7 +3522,7 @@ void
3522qla4_82xx_disable_intrs(struct scsi_qla_host *ha) 3522qla4_82xx_disable_intrs(struct scsi_qla_host *ha)
3523{ 3523{
3524 if (test_and_clear_bit(AF_INTERRUPTS_ON, &ha->flags)) 3524 if (test_and_clear_bit(AF_INTERRUPTS_ON, &ha->flags))
3525 qla4_8xxx_mbx_intr_disable(ha); 3525 qla4_8xxx_intr_disable(ha);
3526 3526
3527 spin_lock_irq(&ha->hardware_lock); 3527 spin_lock_irq(&ha->hardware_lock);
3528 /* BIT 10 - set */ 3528 /* BIT 10 - set */
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 4cec123a6a6a..bfd1e68654ab 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -2978,6 +2978,7 @@ static int qla4xxx_recover_adapter(struct scsi_qla_host *ha)
2978 if (status == QLA_SUCCESS) { 2978 if (status == QLA_SUCCESS) {
2979 if (!test_bit(AF_FW_RECOVERY, &ha->flags)) 2979 if (!test_bit(AF_FW_RECOVERY, &ha->flags))
2980 qla4xxx_cmd_wait(ha); 2980 qla4xxx_cmd_wait(ha);
2981
2981 ha->isp_ops->disable_intrs(ha); 2982 ha->isp_ops->disable_intrs(ha);
2982 qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS); 2983 qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS);
2983 qla4xxx_abort_active_cmds(ha, DID_RESET << 16); 2984 qla4xxx_abort_active_cmds(ha, DID_RESET << 16);
@@ -3508,10 +3509,8 @@ static void qla4xxx_free_adapter(struct scsi_qla_host *ha)
3508{ 3509{
3509 qla4xxx_abort_active_cmds(ha, DID_NO_CONNECT << 16); 3510 qla4xxx_abort_active_cmds(ha, DID_NO_CONNECT << 16);
3510 3511
3511 if (test_bit(AF_INTERRUPTS_ON, &ha->flags)) { 3512 /* Turn-off interrupts on the card. */
3512 /* Turn-off interrupts on the card. */ 3513 ha->isp_ops->disable_intrs(ha);
3513 ha->isp_ops->disable_intrs(ha);
3514 }
3515 3514
3516 if (is_qla40XX(ha)) { 3515 if (is_qla40XX(ha)) {
3517 writel(set_rmask(CSR_SCSI_PROCESSOR_INTR), 3516 writel(set_rmask(CSR_SCSI_PROCESSOR_INTR),
@@ -3547,8 +3546,7 @@ static void qla4xxx_free_adapter(struct scsi_qla_host *ha)
3547 } 3546 }
3548 3547
3549 /* Detach interrupts */ 3548 /* Detach interrupts */
3550 if (test_and_clear_bit(AF_IRQ_ATTACHED, &ha->flags)) 3549 qla4xxx_free_irqs(ha);
3551 qla4xxx_free_irqs(ha);
3552 3550
3553 /* free extra memory */ 3551 /* free extra memory */
3554 qla4xxx_mem_free(ha); 3552 qla4xxx_mem_free(ha);