summaryrefslogtreecommitdiff
path: root/drivers/scsi/qla2xxx/qla_iocb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_iocb.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_iocb.c60
1 files changed, 50 insertions, 10 deletions
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index fea3a92e7724..38b5bdde2405 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -1645,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
@@ -1842,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
@@ -1922,6 +1933,7 @@ queuing_error:
qla_put_iocbs(sp->qpair, &sp->iores);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
return QLA_FUNCTION_FAILED;
}
@@ -1991,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
@@ -2203,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
@@ -2281,6 +2305,7 @@ queuing_error:
qla_put_iocbs(sp->qpair, &sp->iores);
spin_unlock_irqrestore(&qpair->qp_lock, flags);
+
return QLA_FUNCTION_FAILED;
}
@@ -2325,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
@@ -3740,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) {
@@ -3957,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
@@ -3997,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;
}