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

[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
...@@ -136,6 +136,7 @@ ...@@ -136,6 +136,7 @@
#define RESPONSE_QUEUE_DEPTH 64 #define RESPONSE_QUEUE_DEPTH 64
#define QUEUE_SIZE 64 #define QUEUE_SIZE 64
#define DMA_BUFFER_SIZE 512 #define DMA_BUFFER_SIZE 512
#define IOCB_HIWAT_CUSHION 4
/* /*
* Misc * Misc
...@@ -540,6 +541,7 @@ struct scsi_qla_host { ...@@ -540,6 +541,7 @@ struct scsi_qla_host {
uint32_t tot_ddbs; uint32_t tot_ddbs;
uint16_t iocb_cnt; uint16_t iocb_cnt;
uint16_t iocb_hiwat;
/* SRB cache. */ /* SRB cache. */
#define SRB_MIN_REQ 128 #define SRB_MIN_REQ 128
......
...@@ -316,7 +316,7 @@ int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb) ...@@ -316,7 +316,7 @@ int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb)
goto queuing_error; goto queuing_error;
/* total iocbs active */ /* total iocbs active */
if ((ha->iocb_cnt + req_cnt) >= REQUEST_QUEUE_DEPTH) if ((ha->iocb_cnt + req_cnt) >= ha->iocb_hiwat)
goto queuing_error; goto queuing_error;
/* Build command packet */ /* Build command packet */
......
...@@ -697,8 +697,24 @@ int qla4xxx_get_firmware_status(struct scsi_qla_host * ha) ...@@ -697,8 +697,24 @@ int qla4xxx_get_firmware_status(struct scsi_qla_host * ha)
return QLA_ERROR; return QLA_ERROR;
} }
ql4_printk(KERN_INFO, ha, "%ld firmware IOCBs available (%d).\n", /* High-water mark of IOCBs */
ha->host_no, mbox_sts[2]); 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; return QLA_SUCCESS;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment