Merge tag 'sound-fix-5.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai...
[linux-2.6-microblaze.git] / drivers / scsi / qla2xxx / qla_iocb.c
index 8b41cba..38b5bdd 100644 (file)
@@ -491,7 +491,7 @@ qla2x00_start_iocbs(struct scsi_qla_host *vha, struct req_que *req)
 }
 
 /**
- * qla2x00_marker() - Send a marker IOCB to the firmware.
+ * __qla2x00_marker() - Send a marker IOCB to the firmware.
  * @vha: HA context
  * @qpair: queue pair pointer
  * @loop_id: loop ID
@@ -1600,12 +1600,14 @@ qla24xx_start_scsi(srb_t *sp)
        uint16_t        req_cnt;
        uint16_t        tot_dsds;
        struct req_que *req = NULL;
+       struct rsp_que *rsp;
        struct scsi_cmnd *cmd = GET_CMD_SP(sp);
        struct scsi_qla_host *vha = sp->vha;
        struct qla_hw_data *ha = vha->hw;
 
        /* Setup device pointers. */
        req = vha->req;
+       rsp = req->rsp;
 
        /* So we know we haven't pci_map'ed anything yet */
        tot_dsds = 0;
@@ -1643,8 +1645,14 @@ qla24xx_start_scsi(srb_t *sp)
                goto queuing_error;
 
        if (req->cnt < (req_cnt + 2)) {
-               cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr :
-                   rd_reg_dword_relaxed(req->req_q_out);
+               if (IS_SHADOW_REG_CAPABLE(ha)) {
+                       cnt = *req->out_ptr;
+               } else {
+                       cnt = rd_reg_dword_relaxed(req->req_q_out);
+                       if (qla2x00_check_reg16_for_disconnect(vha, cnt))
+                               goto queuing_error;
+               }
+
                if (req->ring_index < cnt)
                        req->cnt = cnt - req->ring_index;
                else
@@ -1707,6 +1715,11 @@ qla24xx_start_scsi(srb_t *sp)
        /* Set chip new ring index. */
        wrt_reg_dword(req->req_q_in, req->ring_index);
 
+       /* Manage unprocessed RIO/ZIO commands in response queue. */
+       if (vha->flags.process_response_queue &&
+           rsp->ring_ptr->signature != RESPONSE_PROCESSED)
+               qla24xx_process_response_queue(vha, rsp);
+
        spin_unlock_irqrestore(&ha->hardware_lock, flags);
        return QLA_SUCCESS;
 
@@ -1835,8 +1848,13 @@ qla24xx_dif_start_scsi(srb_t *sp)
                goto queuing_error;
 
        if (req->cnt < (req_cnt + 2)) {
-               cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr :
-                   rd_reg_dword_relaxed(req->req_q_out);
+               if (IS_SHADOW_REG_CAPABLE(ha)) {
+                       cnt = *req->out_ptr;
+               } else {
+                       cnt = rd_reg_dword_relaxed(req->req_q_out);
+                       if (qla2x00_check_reg16_for_disconnect(vha, cnt))
+                               goto queuing_error;
+               }
                if (req->ring_index < cnt)
                        req->cnt = cnt - req->ring_index;
                else
@@ -1897,6 +1915,11 @@ qla24xx_dif_start_scsi(srb_t *sp)
        /* Set chip new ring index. */
        wrt_reg_dword(req->req_q_in, req->ring_index);
 
+       /* Manage unprocessed RIO/ZIO commands in response queue. */
+       if (vha->flags.process_response_queue &&
+           rsp->ring_ptr->signature != RESPONSE_PROCESSED)
+               qla24xx_process_response_queue(vha, rsp);
+
        spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
        return QLA_SUCCESS;
@@ -1910,6 +1933,7 @@ queuing_error:
 
        qla_put_iocbs(sp->qpair, &sp->iores);
        spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
        return QLA_FUNCTION_FAILED;
 }
 
@@ -1931,6 +1955,7 @@ qla2xxx_start_scsi_mq(srb_t *sp)
        uint16_t        req_cnt;
        uint16_t        tot_dsds;
        struct req_que *req = NULL;
+       struct rsp_que *rsp;
        struct scsi_cmnd *cmd = GET_CMD_SP(sp);
        struct scsi_qla_host *vha = sp->fcport->vha;
        struct qla_hw_data *ha = vha->hw;
@@ -1941,6 +1966,7 @@ qla2xxx_start_scsi_mq(srb_t *sp)
 
        /* Setup qpair pointers */
        req = qpair->req;
+       rsp = qpair->rsp;
 
        /* So we know we haven't pci_map'ed anything yet */
        tot_dsds = 0;
@@ -1977,8 +2003,14 @@ qla2xxx_start_scsi_mq(srb_t *sp)
                goto queuing_error;
 
        if (req->cnt < (req_cnt + 2)) {
-               cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr :
-                   rd_reg_dword_relaxed(req->req_q_out);
+               if (IS_SHADOW_REG_CAPABLE(ha)) {
+                       cnt = *req->out_ptr;
+               } else {
+                       cnt = rd_reg_dword_relaxed(req->req_q_out);
+                       if (qla2x00_check_reg16_for_disconnect(vha, cnt))
+                               goto queuing_error;
+               }
+
                if (req->ring_index < cnt)
                        req->cnt = cnt - req->ring_index;
                else
@@ -2041,6 +2073,11 @@ qla2xxx_start_scsi_mq(srb_t *sp)
        /* Set chip new ring index. */
        wrt_reg_dword(req->req_q_in, req->ring_index);
 
+       /* Manage unprocessed RIO/ZIO commands in response queue. */
+       if (vha->flags.process_response_queue &&
+           rsp->ring_ptr->signature != RESPONSE_PROCESSED)
+               qla24xx_process_response_queue(vha, rsp);
+
        spin_unlock_irqrestore(&qpair->qp_lock, flags);
        return QLA_SUCCESS;
 
@@ -2184,8 +2221,14 @@ qla2xxx_dif_start_scsi_mq(srb_t *sp)
                goto queuing_error;
 
        if (req->cnt < (req_cnt + 2)) {
-               cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr :
-                   rd_reg_dword_relaxed(req->req_q_out);
+               if (IS_SHADOW_REG_CAPABLE(ha)) {
+                       cnt = *req->out_ptr;
+               } else {
+                       cnt = rd_reg_dword_relaxed(req->req_q_out);
+                       if (qla2x00_check_reg16_for_disconnect(vha, cnt))
+                               goto queuing_error;
+               }
+
                if (req->ring_index < cnt)
                        req->cnt = cnt - req->ring_index;
                else
@@ -2262,6 +2305,7 @@ queuing_error:
 
        qla_put_iocbs(sp->qpair, &sp->iores);
        spin_unlock_irqrestore(&qpair->qp_lock, flags);
+
        return QLA_FUNCTION_FAILED;
 }
 
@@ -2306,6 +2350,11 @@ __qla2x00_alloc_iocbs(struct qla_qpair *qpair, srb_t *sp)
                        cnt = qla2x00_debounce_register(
                            ISP_REQ_Q_OUT(ha, &reg->isp));
 
+               if (!qpair->use_shadow_reg && cnt == ISP_REG16_DISCONNECT) {
+                       qla_schedule_eeh_work(vha);
+                       return NULL;
+               }
+
                if  (req->ring_index < cnt)
                        req->cnt = cnt - req->ring_index;
                else
@@ -2379,7 +2428,8 @@ qla24xx_prli_iocb(srb_t *sp, struct logio_entry_24xx *logio)
                                cpu_to_le32(NVME_PRLI_SP_FIRST_BURST);
                if (sp->vha->flags.nvme2_enabled) {
                        /* Set service parameter BIT_7 for NVME CONF support */
-                       logio->io_parameter[0] |= NVME_PRLI_SP_CONF;
+                       logio->io_parameter[0] |=
+                               cpu_to_le32(NVME_PRLI_SP_CONF);
                        /* Set service parameter BIT_8 for SLER support */
                        logio->io_parameter[0] |=
                                cpu_to_le32(NVME_PRLI_SP_SLER);
@@ -3720,6 +3770,9 @@ qla2x00_start_sp(srb_t *sp)
        void *pkt;
        unsigned long flags;
 
+       if (vha->hw->flags.eeh_busy)
+               return -EIO;
+
        spin_lock_irqsave(qp->qp_lock_ptr, flags);
        pkt = __qla2x00_alloc_iocbs(sp->qpair, sp);
        if (!pkt) {
@@ -3937,8 +3990,14 @@ qla2x00_start_bidir(srb_t *sp, struct scsi_qla_host *vha, uint32_t tot_dsds)
 
        /* Check for room on request queue. */
        if (req->cnt < req_cnt + 2) {
-               cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr :
-                   rd_reg_dword_relaxed(req->req_q_out);
+               if (IS_SHADOW_REG_CAPABLE(ha)) {
+                       cnt = *req->out_ptr;
+               } else {
+                       cnt = rd_reg_dword_relaxed(req->req_q_out);
+                       if (qla2x00_check_reg16_for_disconnect(vha, cnt))
+                               goto queuing_error;
+               }
+
                if  (req->ring_index < cnt)
                        req->cnt = cnt - req->ring_index;
                else
@@ -3977,5 +4036,6 @@ qla2x00_start_bidir(srb_t *sp, struct scsi_qla_host *vha, uint32_t tot_dsds)
        qla2x00_start_iocbs(vha, req);
 queuing_error:
        spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
        return rval;
 }