scsi: qla2xxx: Fix exchange oversubscription
[linux-2.6-microblaze.git] / drivers / scsi / qla2xxx / qla_nvme.c
index 8927ddc..c57e02a 100644 (file)
@@ -428,13 +428,24 @@ static inline int qla2x00_start_nvme_mq(srb_t *sp)
                goto queuing_error;
        }
        req_cnt = qla24xx_calc_iocbs(vha, tot_dsds);
+
+       sp->iores.res_type = RESOURCE_IOCB | RESOURCE_EXCH;
+       sp->iores.exch_cnt = 1;
+       sp->iores.iocb_cnt = req_cnt;
+       if (qla_get_fw_resources(sp->qpair, &sp->iores)) {
+               rval = -EBUSY;
+               goto queuing_error;
+       }
+
        if (req->cnt < (req_cnt + 2)) {
                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))
+                       if (qla2x00_check_reg16_for_disconnect(vha, cnt)) {
+                               rval = -EBUSY;
                                goto queuing_error;
+                       }
                }
 
                if (req->ring_index < cnt)
@@ -583,6 +594,8 @@ static inline int qla2x00_start_nvme_mq(srb_t *sp)
                qla24xx_process_response_queue(vha, rsp);
 
 queuing_error:
+       if (rval)
+               qla_put_fw_resources(sp->qpair, &sp->iores);
        spin_unlock_irqrestore(&qpair->qp_lock, flags);
 
        return rval;