diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_83xx.c | 53 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_def.h | 2 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_glbl.h | 5 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_init.c | 10 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_isr.c | 17 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_mbx.c | 41 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_nx.c | 8 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_os.c | 10 |
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 | ||
1354 | void qla4_83xx_disable_intrs(struct scsi_qla_host *ha) | 1354 | static 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 | |||
1360 | static 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); | 1372 | void 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 | ||
1367 | void qla4_83xx_enable_intrs(struct scsi_qla_host *ha) | 1378 | static 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 | |||
1386 | void 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 | |
1399 | void 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 | |||
1379 | void qla4_83xx_queue_mbox_cmd(struct scsi_qla_host *ha, uint32_t *mbx_cmd, | 1406 | void 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); | |||
253 | void qla4_8xxx_clear_rst_ready(struct scsi_qla_host *ha); | 253 | void qla4_8xxx_clear_rst_ready(struct scsi_qla_host *ha); |
254 | int qla4_8xxx_device_bootstrap(struct scsi_qla_host *ha); | 254 | int qla4_8xxx_device_bootstrap(struct scsi_qla_host *ha); |
255 | void qla4_8xxx_get_minidump(struct scsi_qla_host *ha); | 255 | void qla4_8xxx_get_minidump(struct scsi_qla_host *ha); |
256 | int qla4_8xxx_mbx_intr_disable(struct scsi_qla_host *ha); | 256 | int qla4_8xxx_intr_disable(struct scsi_qla_host *ha); |
257 | int qla4_8xxx_mbx_intr_enable(struct scsi_qla_host *ha); | 257 | int qla4_8xxx_intr_enable(struct scsi_qla_host *ha); |
258 | int qla4_8xxx_set_param(struct scsi_qla_host *ha, int param); | 258 | int qla4_8xxx_set_param(struct scsi_qla_host *ha, int param); |
259 | int qla4_8xxx_update_idc_reg(struct scsi_qla_host *ha); | 259 | int qla4_8xxx_update_idc_reg(struct scsi_qla_host *ha); |
260 | int qla4_83xx_post_idc_ack(struct scsi_qla_host *ha); | 260 | int qla4_83xx_post_idc_ack(struct scsi_qla_host *ha); |
261 | void qla4_83xx_disable_pause(struct scsi_qla_host *ha); | 261 | void qla4_83xx_disable_pause(struct scsi_qla_host *ha); |
262 | void qla4_83xx_enable_mbox_intrs(struct scsi_qla_host *ha); | ||
262 | 263 | ||
263 | extern int ql4xextended_error_logging; | 264 | extern int ql4xextended_error_logging; |
264 | extern int ql4xdontresethba; | 265 | extern 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 | ||
1438 | void qla4xxx_free_irqs(struct scsi_qla_host *ha) | 1438 | void 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 | **/ | ||
51 | static 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 | ||
3466 | int qla4_8xxx_mbx_intr_enable(struct scsi_qla_host *ha) | 3466 | int 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 | ||
3487 | int qla4_8xxx_mbx_intr_disable(struct scsi_qla_host *ha) | 3487 | int 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) | |||
3509 | void | 3509 | void |
3510 | qla4_82xx_enable_intrs(struct scsi_qla_host *ha) | 3510 | qla4_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 | |||
3522 | qla4_82xx_disable_intrs(struct scsi_qla_host *ha) | 3522 | qla4_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); |