qla2xxx: Collect PCI register checks and board_disable scheduling
[deliverable/linux.git] / drivers / scsi / qla2xxx / qla_isr.c
index 550a4a31f51a1605a6c6ec785279dd83ef0d5afd..016ebed880f52a8a61f1f92ffdeb6ad714663d51 100644 (file)
@@ -56,16 +56,8 @@ qla2100_intr_handler(int irq, void *dev_id)
        vha = pci_get_drvdata(ha->pdev);
        for (iter = 50; iter--; ) {
                hccr = RD_REG_WORD(&reg->hccr);
-               /* Check for PCI disconnection */
-               if (hccr == 0xffff) {
-                       /*
-                        * Schedule this on the default system workqueue so that
-                        * all the adapter workqueues and the DPC thread can be
-                        * shutdown cleanly.
-                        */
-                       schedule_work(&ha->board_disable);
+               if (qla2x00_check_reg16_for_disconnect(vha, hccr))
                        break;
-               }
                if (hccr & HCCR_RISC_PAUSE) {
                        if (pci_channel_offline(ha->pdev))
                                break;
@@ -121,7 +113,7 @@ qla2100_intr_handler(int irq, void *dev_id)
 }
 
 bool
-qla2x00_check_reg_for_disconnect(scsi_qla_host_t *vha, uint32_t reg)
+qla2x00_check_reg32_for_disconnect(scsi_qla_host_t *vha, uint32_t reg)
 {
        /* Check for PCI disconnection */
        if (reg == 0xffffffff) {
@@ -136,6 +128,12 @@ qla2x00_check_reg_for_disconnect(scsi_qla_host_t *vha, uint32_t reg)
                return false;
 }
 
+bool
+qla2x00_check_reg16_for_disconnect(scsi_qla_host_t *vha, uint16_t reg)
+{
+       return qla2x00_check_reg32_for_disconnect(vha, 0xffff0000 | reg);
+}
+
 /**
  * qla2300_intr_handler() - Process interrupts for the ISP23xx and ISP63xx.
  * @irq:
@@ -174,7 +172,7 @@ qla2300_intr_handler(int irq, void *dev_id)
        vha = pci_get_drvdata(ha->pdev);
        for (iter = 50; iter--; ) {
                stat = RD_REG_DWORD(&reg->u.isp2300.host_status);
-               if (qla2x00_check_reg_for_disconnect(vha, stat))
+               if (qla2x00_check_reg32_for_disconnect(vha, stat))
                        break;
                if (stat & HSR_RISC_PAUSED) {
                        if (unlikely(pci_channel_offline(ha->pdev)))
@@ -730,7 +728,7 @@ skip_rio:
                else
                        ha->link_data_rate = mb[1];
 
-               ql_dbg(ql_dbg_async, vha, 0x500a,
+               ql_log(ql_log_info, vha, 0x500a,
                    "LOOP UP detected (%s Gbps).\n",
                    qla2x00_get_link_speed_str(ha, ha->link_data_rate));
 
@@ -743,7 +741,7 @@ skip_rio:
                        ? RD_REG_WORD(&reg24->mailbox4) : 0;
                mbx = (IS_P3P_TYPE(ha)) ? RD_REG_WORD(&reg82->mailbox_out[4])
                        : mbx;
-               ql_dbg(ql_dbg_async, vha, 0x500b,
+               ql_log(ql_log_info, vha, 0x500b,
                    "LOOP DOWN detected (%x %x %x %x).\n",
                    mb[1], mb[2], mb[3], mbx);
 
@@ -908,7 +906,8 @@ skip_rio:
                 * it.  Otherwise ignore it and Wait for RSCN to come in.
                 */
                atomic_set(&vha->loop_down_timer, 0);
-               if (mb[1] != 0xffff || (mb[2] != 0x6 && mb[2] != 0x4)) {
+               if (atomic_read(&vha->loop_state) != LOOP_DOWN &&
+                   atomic_read(&vha->loop_state) != LOOP_DEAD) {
                        ql_dbg(ql_dbg_async, vha, 0x5011,
                            "Asynchronous PORT UPDATE ignored %04x/%04x/%04x.\n",
                            mb[1], mb[2], mb[3]);
@@ -920,9 +919,6 @@ skip_rio:
                ql_dbg(ql_dbg_async, vha, 0x5012,
                    "Port database changed %04x %04x %04x.\n",
                    mb[1], mb[2], mb[3]);
-               ql_log(ql_log_warn, vha, 0x505f,
-                   "Link is operational (%s Gbps).\n",
-                   qla2x00_get_link_speed_str(ha, ha->link_data_rate));
 
                /*
                 * Mark all devices as missing so we will login again.
@@ -2633,7 +2629,7 @@ qla24xx_intr_handler(int irq, void *dev_id)
        vha = pci_get_drvdata(ha->pdev);
        for (iter = 50; iter--; ) {
                stat = RD_REG_DWORD(&reg->host_status);
-               if (qla2x00_check_reg_for_disconnect(vha, stat))
+               if (qla2x00_check_reg32_for_disconnect(vha, stat))
                        break;
                if (stat & HSRX_RISC_PAUSED) {
                        if (unlikely(pci_channel_offline(ha->pdev)))
@@ -2723,7 +2719,7 @@ qla24xx_msix_rsp_q(int irq, void *dev_id)
         * we process the response queue.
         */
        stat = RD_REG_DWORD(&reg->host_status);
-       if (qla2x00_check_reg_for_disconnect(vha, stat))
+       if (qla2x00_check_reg32_for_disconnect(vha, stat))
                goto out;
        qla24xx_process_response_queue(vha, rsp);
        if (!ha->flags.disable_msix_handshake) {
@@ -2763,7 +2759,7 @@ qla25xx_msix_rsp_q(int irq, void *dev_id)
                hccr = RD_REG_DWORD_RELAXED(&reg->hccr);
                spin_unlock_irqrestore(&ha->hardware_lock, flags);
        }
-       if (qla2x00_check_reg_for_disconnect(vha, hccr))
+       if (qla2x00_check_reg32_for_disconnect(vha, hccr))
                goto out;
        queue_work_on((int) (rsp->id - 1), ha->wq, &rsp->q_work);
 
@@ -2798,7 +2794,7 @@ qla24xx_msix_default(int irq, void *dev_id)
        vha = pci_get_drvdata(ha->pdev);
        do {
                stat = RD_REG_DWORD(&reg->host_status);
-               if (qla2x00_check_reg_for_disconnect(vha, stat))
+               if (qla2x00_check_reg32_for_disconnect(vha, stat))
                        break;
                if (stat & HSRX_RISC_PAUSED) {
                        if (unlikely(pci_channel_offline(ha->pdev)))
@@ -2923,27 +2919,22 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
        for (i = 0; i < ha->msix_count; i++)
                entries[i].entry = i;
 
-       ret = pci_enable_msix(ha->pdev, entries, ha->msix_count);
-       if (ret) {
-               if (ret < MIN_MSIX_COUNT)
-                       goto msix_failed;
-
+       ret = pci_enable_msix_range(ha->pdev,
+                                   entries, MIN_MSIX_COUNT, ha->msix_count);
+       if (ret < 0) {
+               ql_log(ql_log_fatal, vha, 0x00c7,
+                   "MSI-X: Failed to enable support, "
+                   "giving   up -- %d/%d.\n",
+                   ha->msix_count, ret);
+               goto msix_out;
+       } else if (ret < ha->msix_count) {
                ql_log(ql_log_warn, vha, 0x00c6,
                    "MSI-X: Failed to enable support "
                    "-- %d/%d\n Retry with %d vectors.\n",
                    ha->msix_count, ret, ret);
-               ha->msix_count = ret;
-               ret = pci_enable_msix(ha->pdev, entries, ha->msix_count);
-               if (ret) {
-msix_failed:
-                       ql_log(ql_log_fatal, vha, 0x00c7,
-                           "MSI-X: Failed to enable support, "
-                           "giving   up -- %d/%d.\n",
-                           ha->msix_count, ret);
-                       goto msix_out;
-               }
-               ha->max_rsp_queues = ha->msix_count - 1;
        }
+       ha->msix_count = ret;
+       ha->max_rsp_queues = ha->msix_count - 1;
        ha->msix_entries = kzalloc(sizeof(struct qla_msix_entry) *
                                ha->msix_count, GFP_KERNEL);
        if (!ha->msix_entries) {
This page took 0.029498 seconds and 5 git commands to generate.