Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5b1c1bff authored by Karen Higgins's avatar Karen Higgins Committed by James Bottomley
Browse files

[SCSI] qla4xxx: Throttle active IOCBs to firmware limits



Problem:
QLA4xxx firmware may assert if given more IOCBs than it can handle.

Solution:
The driver was updated to throttle the number of active IOCBs based
on the total number of IOCB buffers received from get_firmware_status
mbx_sts[2].

Signed-off-by: default avatarKaren Higgins <karen.higgins@qlogic.com>
Signed-off-by: default avatarVikas Chaudhary <vikas.chaudhary@qlogic.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent ff4108dc
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -136,6 +136,7 @@
#define RESPONSE_QUEUE_DEPTH		64
#define QUEUE_SIZE			64
#define DMA_BUFFER_SIZE			512
#define IOCB_HIWAT_CUSHION		4

/*
 * Misc
@@ -540,6 +541,7 @@ struct scsi_qla_host {
	uint32_t tot_ddbs;

	uint16_t iocb_cnt;
	uint16_t iocb_hiwat;

	/* SRB cache. */
#define SRB_MIN_REQ	128
+1 −1
Original line number Diff line number Diff line
@@ -316,7 +316,7 @@ int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb)
		goto queuing_error;

	/* total iocbs active */
	if ((ha->iocb_cnt + req_cnt) >= REQUEST_QUEUE_DEPTH)
	if ((ha->iocb_cnt + req_cnt) >= ha->iocb_hiwat)
		goto queuing_error;

	/* Build command packet */
+18 −2
Original line number Diff line number Diff line
@@ -697,8 +697,24 @@ int qla4xxx_get_firmware_status(struct scsi_qla_host * ha)
		return QLA_ERROR;
	}

	ql4_printk(KERN_INFO, ha, "%ld firmware IOCBs available (%d).\n",
	    ha->host_no, mbox_sts[2]);
	/* High-water mark of IOCBs */
	ha->iocb_hiwat = mbox_sts[2];
	DEBUG2(ql4_printk(KERN_INFO, ha,
			  "%s: firmware IOCBs available = %d\n", __func__,
			  ha->iocb_hiwat));

	if (ha->iocb_hiwat > IOCB_HIWAT_CUSHION)
		ha->iocb_hiwat -= IOCB_HIWAT_CUSHION;

	/* Ideally, we should not enter this code, as the # of firmware
	 * IOCBs is hard-coded in the firmware. We set a default
	 * iocb_hiwat here just in case */
	if (ha->iocb_hiwat == 0) {
		ha->iocb_hiwat = REQUEST_QUEUE_DEPTH / 4;
		DEBUG2(ql4_printk(KERN_WARNING, ha,
				  "%s: Setting IOCB's to = %d\n", __func__,
				  ha->iocb_hiwat));
	}

	return QLA_SUCCESS;
}