diff options
author | Karen Higgins <karen.higgins@qlogic.com> | 2013-01-20 23:51:00 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2013-01-29 21:47:16 -0500 |
commit | 5b1c1bff07d579f8a7b672d4e5262d52eba5ef01 (patch) | |
tree | 83b802ffe3e95af2c8e2ecfc1fc907143149f274 /drivers/scsi/qla4xxx | |
parent | ff4108dce9e82acbde8e8b1899aaa4d91bf504b7 (diff) |
[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: Karen Higgins <karen.higgins@qlogic.com>
Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/qla4xxx')
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_def.h | 2 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_iocb.c | 2 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_mbx.c | 20 |
3 files changed, 21 insertions, 3 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h index 8f4193766663..ad580625a477 100644 --- a/drivers/scsi/qla4xxx/ql4_def.h +++ b/drivers/scsi/qla4xxx/ql4_def.h | |||
@@ -136,6 +136,7 @@ | |||
136 | #define RESPONSE_QUEUE_DEPTH 64 | 136 | #define RESPONSE_QUEUE_DEPTH 64 |
137 | #define QUEUE_SIZE 64 | 137 | #define QUEUE_SIZE 64 |
138 | #define DMA_BUFFER_SIZE 512 | 138 | #define DMA_BUFFER_SIZE 512 |
139 | #define IOCB_HIWAT_CUSHION 4 | ||
139 | 140 | ||
140 | /* | 141 | /* |
141 | * Misc | 142 | * Misc |
@@ -540,6 +541,7 @@ struct scsi_qla_host { | |||
540 | uint32_t tot_ddbs; | 541 | uint32_t tot_ddbs; |
541 | 542 | ||
542 | uint16_t iocb_cnt; | 543 | uint16_t iocb_cnt; |
544 | uint16_t iocb_hiwat; | ||
543 | 545 | ||
544 | /* SRB cache. */ | 546 | /* SRB cache. */ |
545 | #define SRB_MIN_REQ 128 | 547 | #define SRB_MIN_REQ 128 |
diff --git a/drivers/scsi/qla4xxx/ql4_iocb.c b/drivers/scsi/qla4xxx/ql4_iocb.c index f48f37a281d1..14fec976f634 100644 --- a/drivers/scsi/qla4xxx/ql4_iocb.c +++ b/drivers/scsi/qla4xxx/ql4_iocb.c | |||
@@ -316,7 +316,7 @@ int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb) | |||
316 | goto queuing_error; | 316 | goto queuing_error; |
317 | 317 | ||
318 | /* total iocbs active */ | 318 | /* total iocbs active */ |
319 | if ((ha->iocb_cnt + req_cnt) >= REQUEST_QUEUE_DEPTH) | 319 | if ((ha->iocb_cnt + req_cnt) >= ha->iocb_hiwat) |
320 | goto queuing_error; | 320 | goto queuing_error; |
321 | 321 | ||
322 | /* Build command packet */ | 322 | /* Build command packet */ |
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c index 1c57c227c808..81e738d61ec0 100644 --- a/drivers/scsi/qla4xxx/ql4_mbx.c +++ b/drivers/scsi/qla4xxx/ql4_mbx.c | |||
@@ -697,8 +697,24 @@ int qla4xxx_get_firmware_status(struct scsi_qla_host * ha) | |||
697 | return QLA_ERROR; | 697 | return QLA_ERROR; |
698 | } | 698 | } |
699 | 699 | ||
700 | ql4_printk(KERN_INFO, ha, "%ld firmware IOCBs available (%d).\n", | 700 | /* High-water mark of IOCBs */ |
701 | ha->host_no, mbox_sts[2]); | 701 | ha->iocb_hiwat = mbox_sts[2]; |
702 | DEBUG2(ql4_printk(KERN_INFO, ha, | ||
703 | "%s: firmware IOCBs available = %d\n", __func__, | ||
704 | ha->iocb_hiwat)); | ||
705 | |||
706 | if (ha->iocb_hiwat > IOCB_HIWAT_CUSHION) | ||
707 | ha->iocb_hiwat -= IOCB_HIWAT_CUSHION; | ||
708 | |||
709 | /* Ideally, we should not enter this code, as the # of firmware | ||
710 | * IOCBs is hard-coded in the firmware. We set a default | ||
711 | * iocb_hiwat here just in case */ | ||
712 | if (ha->iocb_hiwat == 0) { | ||
713 | ha->iocb_hiwat = REQUEST_QUEUE_DEPTH / 4; | ||
714 | DEBUG2(ql4_printk(KERN_WARNING, ha, | ||
715 | "%s: Setting IOCB's to = %d\n", __func__, | ||
716 | ha->iocb_hiwat)); | ||
717 | } | ||
702 | 718 | ||
703 | return QLA_SUCCESS; | 719 | return QLA_SUCCESS; |
704 | } | 720 | } |