aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_nx.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-03-17 20:54:40 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-03-17 20:54:40 -0400
commitc55d267de274d308927b60c3e740c1a826832317 (patch)
tree21b53a8c725d9f9650f60d94b349459d5b8dae10 /drivers/scsi/qla2xxx/qla_nx.c
parent61ef46fd45c3c62dc7c880a45dd2aa841b9af8fb (diff)
parentbc898c97f7ba24def788d9f80786cf028a197122 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (170 commits) [SCSI] scsi_dh_rdac: Add MD36xxf into device list [SCSI] scsi_debug: add consecutive medium errors [SCSI] libsas: fix ata list corruption issue [SCSI] hpsa: export resettable host attribute [SCSI] hpsa: move device attributes to avoid forward declarations [SCSI] scsi_debug: Logical Block Provisioning (SBC3r26) [SCSI] sd: Logical Block Provisioning update [SCSI] Include protection operation in SCSI command trace [SCSI] hpsa: fix incorrect PCI IDs and add two new ones (2nd try) [SCSI] target: Fix volume size misreporting for volumes > 2TB [SCSI] bnx2fc: Broadcom FCoE offload driver [SCSI] fcoe: fix broken fcoe interface reset [SCSI] fcoe: precedence bug in fcoe_filter_frames() [SCSI] libfcoe: Remove stale fcoe-netdev entries [SCSI] libfcoe: Move FCOE_MTU definition from fcoe.h to libfcoe.h [SCSI] libfc: introduce __fc_fill_fc_hdr that accepts fc_hdr as an argument [SCSI] fcoe, libfc: initialize EM anchors list and then update npiv EMs [SCSI] Revert "[SCSI] libfc: fix exchange being deleted when the abort itself is timed out" [SCSI] libfc: Fixing a memory leak when destroying an interface [SCSI] megaraid_sas: Version and Changelog update ... Fix up trivial conflicts due to whitespace differences in drivers/scsi/libsas/{sas_ata.c,sas_scsi_host.c}
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_nx.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_nx.c191
1 files changed, 145 insertions, 46 deletions
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c
index fdb96a3584a5..76ec876e6b21 100644
--- a/drivers/scsi/qla2xxx/qla_nx.c
+++ b/drivers/scsi/qla2xxx/qla_nx.c
@@ -7,6 +7,7 @@
7#include "qla_def.h" 7#include "qla_def.h"
8#include <linux/delay.h> 8#include <linux/delay.h>
9#include <linux/pci.h> 9#include <linux/pci.h>
10#include <scsi/scsi_tcq.h>
10 11
11#define MASK(n) ((1ULL<<(n))-1) 12#define MASK(n) ((1ULL<<(n))-1)
12#define MN_WIN(addr) (((addr & 0x1fc0000) >> 1) | \ 13#define MN_WIN(addr) (((addr & 0x1fc0000) >> 1) | \
@@ -2547,7 +2548,7 @@ qla2xx_build_scsi_type_6_iocbs(srb_t *sp, struct cmd_type_6 *cmd_pkt,
2547 dsd_seg = (uint32_t *)&cmd_pkt->fcp_data_dseg_address; 2548 dsd_seg = (uint32_t *)&cmd_pkt->fcp_data_dseg_address;
2548 *dsd_seg++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma)); 2549 *dsd_seg++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma));
2549 *dsd_seg++ = cpu_to_le32(MSD(dsd_ptr->dsd_list_dma)); 2550 *dsd_seg++ = cpu_to_le32(MSD(dsd_ptr->dsd_list_dma));
2550 *dsd_seg++ = dsd_list_len; 2551 cmd_pkt->fcp_data_dseg_len = dsd_list_len;
2551 } else { 2552 } else {
2552 *cur_dsd++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma)); 2553 *cur_dsd++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma));
2553 *cur_dsd++ = cpu_to_le32(MSD(dsd_ptr->dsd_list_dma)); 2554 *cur_dsd++ = cpu_to_le32(MSD(dsd_ptr->dsd_list_dma));
@@ -2620,6 +2621,7 @@ qla82xx_start_scsi(srb_t *sp)
2620 struct qla_hw_data *ha = vha->hw; 2621 struct qla_hw_data *ha = vha->hw;
2621 struct req_que *req = NULL; 2622 struct req_que *req = NULL;
2622 struct rsp_que *rsp = NULL; 2623 struct rsp_que *rsp = NULL;
2624 char tag[2];
2623 2625
2624 /* Setup device pointers. */ 2626 /* Setup device pointers. */
2625 ret = 0; 2627 ret = 0;
@@ -2770,6 +2772,22 @@ sufficient_dsds:
2770 int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun); 2772 int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun);
2771 host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun)); 2773 host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun));
2772 2774
2775 /*
2776 * Update tagged queuing modifier -- default is TSK_SIMPLE (0).
2777 */
2778 if (scsi_populate_tag_msg(cmd, tag)) {
2779 switch (tag[0]) {
2780 case HEAD_OF_QUEUE_TAG:
2781 ctx->fcp_cmnd->task_attribute =
2782 TSK_HEAD_OF_QUEUE;
2783 break;
2784 case ORDERED_QUEUE_TAG:
2785 ctx->fcp_cmnd->task_attribute =
2786 TSK_ORDERED;
2787 break;
2788 }
2789 }
2790
2773 /* build FCP_CMND IU */ 2791 /* build FCP_CMND IU */
2774 memset(ctx->fcp_cmnd, 0, sizeof(struct fcp_cmnd)); 2792 memset(ctx->fcp_cmnd, 0, sizeof(struct fcp_cmnd));
2775 int_to_scsilun(sp->cmd->device->lun, &ctx->fcp_cmnd->lun); 2793 int_to_scsilun(sp->cmd->device->lun, &ctx->fcp_cmnd->lun);
@@ -2835,6 +2853,20 @@ sufficient_dsds:
2835 host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, 2853 host_to_fcp_swap((uint8_t *)&cmd_pkt->lun,
2836 sizeof(cmd_pkt->lun)); 2854 sizeof(cmd_pkt->lun));
2837 2855
2856 /*
2857 * Update tagged queuing modifier -- default is TSK_SIMPLE (0).
2858 */
2859 if (scsi_populate_tag_msg(cmd, tag)) {
2860 switch (tag[0]) {
2861 case HEAD_OF_QUEUE_TAG:
2862 cmd_pkt->task = TSK_HEAD_OF_QUEUE;
2863 break;
2864 case ORDERED_QUEUE_TAG:
2865 cmd_pkt->task = TSK_ORDERED;
2866 break;
2867 }
2868 }
2869
2838 /* Load SCSI command packet. */ 2870 /* Load SCSI command packet. */
2839 memcpy(cmd_pkt->fcp_cdb, cmd->cmnd, cmd->cmd_len); 2871 memcpy(cmd_pkt->fcp_cdb, cmd->cmnd, cmd->cmd_len);
2840 host_to_fcp_swap(cmd_pkt->fcp_cdb, sizeof(cmd_pkt->fcp_cdb)); 2872 host_to_fcp_swap(cmd_pkt->fcp_cdb, sizeof(cmd_pkt->fcp_cdb));
@@ -3457,46 +3489,28 @@ qla82xx_need_reset_handler(scsi_qla_host_t *vha)
3457 } 3489 }
3458} 3490}
3459 3491
3460static void 3492int
3461qla82xx_check_fw_alive(scsi_qla_host_t *vha) 3493qla82xx_check_fw_alive(scsi_qla_host_t *vha)
3462{ 3494{
3463 uint32_t fw_heartbeat_counter, halt_status; 3495 uint32_t fw_heartbeat_counter;
3464 struct qla_hw_data *ha = vha->hw; 3496 int status = 0;
3465 3497
3466 fw_heartbeat_counter = qla82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER); 3498 fw_heartbeat_counter = qla82xx_rd_32(vha->hw,
3499 QLA82XX_PEG_ALIVE_COUNTER);
3467 /* all 0xff, assume AER/EEH in progress, ignore */ 3500 /* all 0xff, assume AER/EEH in progress, ignore */
3468 if (fw_heartbeat_counter == 0xffffffff) 3501 if (fw_heartbeat_counter == 0xffffffff)
3469 return; 3502 return status;
3470 if (vha->fw_heartbeat_counter == fw_heartbeat_counter) { 3503 if (vha->fw_heartbeat_counter == fw_heartbeat_counter) {
3471 vha->seconds_since_last_heartbeat++; 3504 vha->seconds_since_last_heartbeat++;
3472 /* FW not alive after 2 seconds */ 3505 /* FW not alive after 2 seconds */
3473 if (vha->seconds_since_last_heartbeat == 2) { 3506 if (vha->seconds_since_last_heartbeat == 2) {
3474 vha->seconds_since_last_heartbeat = 0; 3507 vha->seconds_since_last_heartbeat = 0;
3475 halt_status = qla82xx_rd_32(ha, 3508 status = 1;
3476 QLA82XX_PEG_HALT_STATUS1);
3477 if (halt_status & HALT_STATUS_UNRECOVERABLE) {
3478 set_bit(ISP_UNRECOVERABLE, &vha->dpc_flags);
3479 } else {
3480 qla_printk(KERN_INFO, ha,
3481 "scsi(%ld): %s - detect abort needed\n",
3482 vha->host_no, __func__);
3483 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
3484 }
3485 qla2xxx_wake_dpc(vha);
3486 ha->flags.fw_hung = 1;
3487 if (ha->flags.mbox_busy) {
3488 ha->flags.mbox_int = 1;
3489 DEBUG2(qla_printk(KERN_ERR, ha,
3490 "Due to fw hung, doing premature "
3491 "completion of mbx command\n"));
3492 if (test_bit(MBX_INTR_WAIT,
3493 &ha->mbx_cmd_flags))
3494 complete(&ha->mbx_intr_comp);
3495 }
3496 } 3509 }
3497 } else 3510 } else
3498 vha->seconds_since_last_heartbeat = 0; 3511 vha->seconds_since_last_heartbeat = 0;
3499 vha->fw_heartbeat_counter = fw_heartbeat_counter; 3512 vha->fw_heartbeat_counter = fw_heartbeat_counter;
3513 return status;
3500} 3514}
3501 3515
3502/* 3516/*
@@ -3557,6 +3571,8 @@ qla82xx_device_state_handler(scsi_qla_host_t *vha)
3557 break; 3571 break;
3558 case QLA82XX_DEV_NEED_RESET: 3572 case QLA82XX_DEV_NEED_RESET:
3559 qla82xx_need_reset_handler(vha); 3573 qla82xx_need_reset_handler(vha);
3574 dev_init_timeout = jiffies +
3575 (ha->nx_dev_init_timeout * HZ);
3560 break; 3576 break;
3561 case QLA82XX_DEV_NEED_QUIESCENT: 3577 case QLA82XX_DEV_NEED_QUIESCENT:
3562 qla82xx_need_qsnt_handler(vha); 3578 qla82xx_need_qsnt_handler(vha);
@@ -3596,30 +3612,18 @@ exit:
3596 3612
3597void qla82xx_watchdog(scsi_qla_host_t *vha) 3613void qla82xx_watchdog(scsi_qla_host_t *vha)
3598{ 3614{
3599 uint32_t dev_state; 3615 uint32_t dev_state, halt_status;
3600 struct qla_hw_data *ha = vha->hw; 3616 struct qla_hw_data *ha = vha->hw;
3601 3617
3602 dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
3603
3604 /* don't poll if reset is going on */ 3618 /* don't poll if reset is going on */
3605 if (!(test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) || 3619 if (!ha->flags.isp82xx_reset_hdlr_active) {
3606 test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) || 3620 dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
3607 test_bit(ISP_ABORT_RETRY, &vha->dpc_flags))) { 3621 if (dev_state == QLA82XX_DEV_NEED_RESET &&
3608 if (dev_state == QLA82XX_DEV_NEED_RESET) { 3622 !test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags)) {
3609 qla_printk(KERN_WARNING, ha, 3623 qla_printk(KERN_WARNING, ha,
3610 "%s(): Adapter reset needed!\n", __func__); 3624 "%s(): Adapter reset needed!\n", __func__);
3611 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); 3625 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
3612 qla2xxx_wake_dpc(vha); 3626 qla2xxx_wake_dpc(vha);
3613 ha->flags.fw_hung = 1;
3614 if (ha->flags.mbox_busy) {
3615 ha->flags.mbox_int = 1;
3616 DEBUG2(qla_printk(KERN_ERR, ha,
3617 "Need reset, doing premature "
3618 "completion of mbx command\n"));
3619 if (test_bit(MBX_INTR_WAIT,
3620 &ha->mbx_cmd_flags))
3621 complete(&ha->mbx_intr_comp);
3622 }
3623 } else if (dev_state == QLA82XX_DEV_NEED_QUIESCENT && 3627 } else if (dev_state == QLA82XX_DEV_NEED_QUIESCENT &&
3624 !test_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags)) { 3628 !test_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags)) {
3625 DEBUG(qla_printk(KERN_INFO, ha, 3629 DEBUG(qla_printk(KERN_INFO, ha,
@@ -3629,6 +3633,31 @@ void qla82xx_watchdog(scsi_qla_host_t *vha)
3629 qla2xxx_wake_dpc(vha); 3633 qla2xxx_wake_dpc(vha);
3630 } else { 3634 } else {
3631 qla82xx_check_fw_alive(vha); 3635 qla82xx_check_fw_alive(vha);
3636 if (qla82xx_check_fw_alive(vha)) {
3637 halt_status = qla82xx_rd_32(ha,
3638 QLA82XX_PEG_HALT_STATUS1);
3639 if (halt_status & HALT_STATUS_UNRECOVERABLE) {
3640 set_bit(ISP_UNRECOVERABLE,
3641 &vha->dpc_flags);
3642 } else {
3643 qla_printk(KERN_INFO, ha,
3644 "scsi(%ld): %s - detect abort needed\n",
3645 vha->host_no, __func__);
3646 set_bit(ISP_ABORT_NEEDED,
3647 &vha->dpc_flags);
3648 }
3649 qla2xxx_wake_dpc(vha);
3650 ha->flags.isp82xx_fw_hung = 1;
3651 if (ha->flags.mbox_busy) {
3652 ha->flags.mbox_int = 1;
3653 DEBUG2(qla_printk(KERN_ERR, ha,
3654 "Due to fw hung, doing premature "
3655 "completion of mbx command\n"));
3656 if (test_bit(MBX_INTR_WAIT,
3657 &ha->mbx_cmd_flags))
3658 complete(&ha->mbx_intr_comp);
3659 }
3660 }
3632 } 3661 }
3633 } 3662 }
3634} 3663}
@@ -3663,6 +3692,7 @@ qla82xx_abort_isp(scsi_qla_host_t *vha)
3663 "Exiting.\n", __func__, vha->host_no); 3692 "Exiting.\n", __func__, vha->host_no);
3664 return QLA_SUCCESS; 3693 return QLA_SUCCESS;
3665 } 3694 }
3695 ha->flags.isp82xx_reset_hdlr_active = 1;
3666 3696
3667 qla82xx_idc_lock(ha); 3697 qla82xx_idc_lock(ha);
3668 dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE); 3698 dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
@@ -3683,7 +3713,8 @@ qla82xx_abort_isp(scsi_qla_host_t *vha)
3683 qla82xx_idc_unlock(ha); 3713 qla82xx_idc_unlock(ha);
3684 3714
3685 if (rval == QLA_SUCCESS) { 3715 if (rval == QLA_SUCCESS) {
3686 ha->flags.fw_hung = 0; 3716 ha->flags.isp82xx_fw_hung = 0;
3717 ha->flags.isp82xx_reset_hdlr_active = 0;
3687 qla82xx_restart_isp(vha); 3718 qla82xx_restart_isp(vha);
3688 } 3719 }
3689 3720
@@ -3791,3 +3822,71 @@ int qla2x00_wait_for_fcoe_ctx_reset(scsi_qla_host_t *vha)
3791 3822
3792 return status; 3823 return status;
3793} 3824}
3825
3826void
3827qla82xx_chip_reset_cleanup(scsi_qla_host_t *vha)
3828{
3829 int i;
3830 unsigned long flags;
3831 struct qla_hw_data *ha = vha->hw;
3832
3833 /* Check if 82XX firmware is alive or not
3834 * We may have arrived here from NEED_RESET
3835 * detection only
3836 */
3837 if (!ha->flags.isp82xx_fw_hung) {
3838 for (i = 0; i < 2; i++) {
3839 msleep(1000);
3840 if (qla82xx_check_fw_alive(vha)) {
3841 ha->flags.isp82xx_fw_hung = 1;
3842 if (ha->flags.mbox_busy) {
3843 ha->flags.mbox_int = 1;
3844 complete(&ha->mbx_intr_comp);
3845 }
3846 break;
3847 }
3848 }
3849 }
3850
3851 /* Abort all commands gracefully if fw NOT hung */
3852 if (!ha->flags.isp82xx_fw_hung) {
3853 int cnt, que;
3854 srb_t *sp;
3855 struct req_que *req;
3856
3857 spin_lock_irqsave(&ha->hardware_lock, flags);
3858 for (que = 0; que < ha->max_req_queues; que++) {
3859 req = ha->req_q_map[que];
3860 if (!req)
3861 continue;
3862 for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
3863 sp = req->outstanding_cmds[cnt];
3864 if (sp) {
3865 if (!sp->ctx ||
3866 (sp->flags & SRB_FCP_CMND_DMA_VALID)) {
3867 spin_unlock_irqrestore(
3868 &ha->hardware_lock, flags);
3869 if (ha->isp_ops->abort_command(sp)) {
3870 qla_printk(KERN_INFO, ha,
3871 "scsi(%ld): mbx abort command failed in %s\n",
3872 vha->host_no, __func__);
3873 } else {
3874 qla_printk(KERN_INFO, ha,
3875 "scsi(%ld): mbx abort command success in %s\n",
3876 vha->host_no, __func__);
3877 }
3878 spin_lock_irqsave(&ha->hardware_lock, flags);
3879 }
3880 }
3881 }
3882 }
3883 spin_unlock_irqrestore(&ha->hardware_lock, flags);
3884
3885 /* Wait for pending cmds (physical and virtual) to complete */
3886 if (!qla2x00_eh_wait_for_pending_commands(vha, 0, 0,
3887 WAIT_HOST) == QLA_SUCCESS) {
3888 DEBUG2(qla_printk(KERN_INFO, ha,
3889 "Done wait for pending commands\n"));
3890 }
3891 }
3892}