]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/scsi/qla2xxx/qla_init.c
[SCSI] qla2xxx: Add module parameter to enable/disable GFF_ID device type check.
[karo-tx-linux.git] / drivers / scsi / qla2xxx / qla_init.c
index 9c383baebe279d0c27bb3027dc1bd337ab52603e..6ea537636b534cc7f7abc5706dce56c499e4b23a 100644 (file)
@@ -953,6 +953,19 @@ qla2x00_reset_chip(scsi_qla_host_t *vha)
        spin_unlock_irqrestore(&ha->hardware_lock, flags);
 }
 
+/**
+ * qla81xx_reset_mpi() - Reset's MPI FW via Write MPI Register MBC.
+ *
+ * Returns 0 on success.
+ */
+int
+qla81xx_reset_mpi(scsi_qla_host_t *vha)
+{
+       uint16_t mb[4] = {0x1010, 0, 1, 0};
+
+       return qla81xx_write_mpi_register(vha, mb);
+}
+
 /**
  * qla24xx_reset_risc() - Perform full reset of ISP24xx RISC.
  * @ha: HA context
@@ -967,6 +980,7 @@ qla24xx_reset_risc(scsi_qla_host_t *vha)
        struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
        uint32_t cnt, d2;
        uint16_t wd;
+       static int abts_cnt; /* ISP abort retry counts */
 
        spin_lock_irqsave(&ha->hardware_lock, flags);
 
@@ -1000,6 +1014,23 @@ qla24xx_reset_risc(scsi_qla_host_t *vha)
                barrier();
        }
 
+       /* If required, do an MPI FW reset now */
+       if (test_and_clear_bit(MPI_RESET_NEEDED, &vha->dpc_flags)) {
+               if (qla81xx_reset_mpi(vha) != QLA_SUCCESS) {
+                       if (++abts_cnt < 5) {
+                               set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
+                               set_bit(MPI_RESET_NEEDED, &vha->dpc_flags);
+                       } else {
+                               /*
+                                * We exhausted the ISP abort retries. We have to
+                                * set the board offline.
+                                */
+                               abts_cnt = 0;
+                               vha->flags.online = 0;
+                       }
+               }
+       }
+
        WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_RESET);
        RD_REG_DWORD(&reg->hccr);
 
@@ -1787,14 +1818,14 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
                qla2x00_init_response_q_entries(rsp);
        }
 
-       spin_lock_irqsave(&ha->vport_slock, flags);
+       spin_lock(&ha->vport_slock);
        /* Clear RSCN queue. */
        list_for_each_entry(vp, &ha->vp_list, list) {
                vp->rscn_in_ptr = 0;
                vp->rscn_out_ptr = 0;
        }
 
-       spin_unlock_irqrestore(&ha->vport_slock, flags);
+       spin_unlock(&ha->vport_slock);
 
        ha->isp_ops->config_rings(vha);
 
@@ -2799,6 +2830,9 @@ qla2x00_iidma_fcport(scsi_qla_host_t *vha, fc_port_t *fcport)
        if (!IS_IIDMA_CAPABLE(ha))
                return;
 
+       if (atomic_read(&fcport->state) != FCS_ONLINE)
+               return;
+
        if (fcport->fp_speed == PORT_SPEED_UNKNOWN ||
            fcport->fp_speed > ha->link_data_rate)
                return;
@@ -2882,20 +2916,12 @@ qla2x00_reg_remote_port(scsi_qla_host_t *vha, fc_port_t *fcport)
 void
 qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport)
 {
-       struct qla_hw_data *ha = vha->hw;
-
        fcport->vha = vha;
        fcport->login_retry = 0;
-       fcport->port_login_retry_count = ha->port_down_retry_count *
-           PORT_RETRY_TIME;
-       atomic_set(&fcport->port_down_timer, ha->port_down_retry_count *
-           PORT_RETRY_TIME);
        fcport->flags &= ~(FCF_LOGIN_NEEDED | FCF_ASYNC_SENT);
 
        qla2x00_iidma_fcport(vha, fcport);
-
        atomic_set(&fcport->state, FCS_ONLINE);
-
        qla2x00_reg_remote_port(vha, fcport);
 }
 
@@ -3258,8 +3284,9 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha,
                        continue;
 
                /* Bypass ports whose FCP-4 type is not FCP_SCSI */
-               if (new_fcport->fc4_type != FC4_TYPE_FCP_SCSI &&
-                   new_fcport->fc4_type != FC4_TYPE_UNKNOWN)
+               if (ql2xgffidenable &&
+                   (new_fcport->fc4_type != FC4_TYPE_FCP_SCSI &&
+                   new_fcport->fc4_type != FC4_TYPE_UNKNOWN))
                        continue;
 
                /* Locate matching device in database. */
@@ -3878,17 +3905,19 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha)
                            LOOP_DOWN_TIME);
        }
 
-       /* Make sure for ISP 82XX IO DMA is complete */
-       if (IS_QLA82XX(ha)) {
-               if (qla2x00_eh_wait_for_pending_commands(vha, 0, 0,
-                       WAIT_HOST) == QLA_SUCCESS) {
-                       DEBUG2(qla_printk(KERN_INFO, ha,
-                       "Done wait for pending commands\n"));
+       if (!ha->flags.eeh_busy) {
+               /* Make sure for ISP 82XX IO DMA is complete */
+               if (IS_QLA82XX(ha)) {
+                       if (qla2x00_eh_wait_for_pending_commands(vha, 0, 0,
+                               WAIT_HOST) == QLA_SUCCESS) {
+                               DEBUG2(qla_printk(KERN_INFO, ha,
+                               "Done wait for pending commands\n"));
+                       }
                }
-       }
 
-       /* Requeue all commands in outstanding command list. */
-       qla2x00_abort_all_cmds(vha, DID_RESET << 16);
+               /* Requeue all commands in outstanding command list. */
+               qla2x00_abort_all_cmds(vha, DID_RESET << 16);
+       }
 }
 
 /*