提交 f0d98d85 编写于 作者: L Linus Torvalds

Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi

Pull SCSI fixes from James Bottomley:
 "This is a set of minor (and safe changes) that didn't make the initial
  pull request plus some bug fixes.

  The status handling code is actually a running regression from the
  previous merge window which had an incomplete fix (now reverted) and
  most of the remaining bug fixes are for problems older than the
  current merge window"

[ Side note: this merge also takes the base kernel git repository to 6+
  million objects for the first time. Technically we hit it a couple of
  merges ago already if you count all the tag objects, but now it
  reaches 6M+ objects reachable from HEAD.

  I was joking around that that's when I should switch to 5.0, because
  3.0 happened at the 2M mark, and 4.0 happened at 4M objects. But
  probably not, even if numerology is about as good a reason as any.

                                                              - Linus ]

* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
  scsi: devinfo: Add Microsoft iSCSI target to 1024 sector blacklist
  scsi: cxgb4i: silence overflow warning in t4_uld_rx_handler()
  scsi: dpt_i2o: Use after free in I2ORESETCMD ioctl
  scsi: core: Make scsi_result_to_blk_status() recognize CONDITION MET
  scsi: core: Rename __scsi_error_from_host_byte() into scsi_result_to_blk_status()
  Revert "scsi: core: return BLK_STS_OK for DID_OK in __scsi_error_from_host_byte()"
  scsi: aacraid: Insure command thread is not recursively stopped
  scsi: qla2xxx: Correct setting of SAM_STAT_CHECK_CONDITION
  scsi: qla2xxx: correctly shift host byte
  scsi: qla2xxx: Fix race condition between iocb timeout and initialisation
  scsi: qla2xxx: Avoid double completion of abort command
  scsi: qla2xxx: Fix small memory leak in qla2x00_probe_one on probe failure
  scsi: scsi_dh: Don't look for NULL devices handlers by name
  scsi: core: remove redundant assignment to shost->use_blk_mq
...@@ -1502,9 +1502,10 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type) ...@@ -1502,9 +1502,10 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type)
host = aac->scsi_host_ptr; host = aac->scsi_host_ptr;
scsi_block_requests(host); scsi_block_requests(host);
aac_adapter_disable_int(aac); aac_adapter_disable_int(aac);
if (aac->thread->pid != current->pid) { if (aac->thread && aac->thread->pid != current->pid) {
spin_unlock_irq(host->host_lock); spin_unlock_irq(host->host_lock);
kthread_stop(aac->thread); kthread_stop(aac->thread);
aac->thread = NULL;
jafo = 1; jafo = 1;
} }
...@@ -1591,6 +1592,7 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type) ...@@ -1591,6 +1592,7 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type)
aac->name); aac->name);
if (IS_ERR(aac->thread)) { if (IS_ERR(aac->thread)) {
retval = PTR_ERR(aac->thread); retval = PTR_ERR(aac->thread);
aac->thread = NULL;
goto out; goto out;
} }
} }
......
...@@ -1562,6 +1562,7 @@ static void __aac_shutdown(struct aac_dev * aac) ...@@ -1562,6 +1562,7 @@ static void __aac_shutdown(struct aac_dev * aac)
up(&fib->event_wait); up(&fib->event_wait);
} }
kthread_stop(aac->thread); kthread_stop(aac->thread);
aac->thread = NULL;
} }
aac_send_shutdown(aac); aac_send_shutdown(aac);
......
...@@ -2108,12 +2108,12 @@ static int t4_uld_rx_handler(void *handle, const __be64 *rsp, ...@@ -2108,12 +2108,12 @@ static int t4_uld_rx_handler(void *handle, const __be64 *rsp,
log_debug(1 << CXGBI_DBG_TOE, log_debug(1 << CXGBI_DBG_TOE,
"cdev %p, opcode 0x%x(0x%x,0x%x), skb %p.\n", "cdev %p, opcode 0x%x(0x%x,0x%x), skb %p.\n",
cdev, opc, rpl->ot.opcode_tid, ntohl(rpl->ot.opcode_tid), skb); cdev, opc, rpl->ot.opcode_tid, ntohl(rpl->ot.opcode_tid), skb);
if (cxgb4i_cplhandlers[opc]) if (opc >= ARRAY_SIZE(cxgb4i_cplhandlers) || !cxgb4i_cplhandlers[opc]) {
cxgb4i_cplhandlers[opc](cdev, skb);
else {
pr_err("No handler for opcode 0x%x.\n", opc); pr_err("No handler for opcode 0x%x.\n", opc);
__kfree_skb(skb); __kfree_skb(skb);
} } else
cxgb4i_cplhandlers[opc](cdev, skb);
return 0; return 0;
nomem: nomem:
log_debug(1 << CXGBI_DBG_TOE, "OOM bailing out.\n"); log_debug(1 << CXGBI_DBG_TOE, "OOM bailing out.\n");
......
...@@ -2051,13 +2051,16 @@ static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd, ulong ar ...@@ -2051,13 +2051,16 @@ static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd, ulong ar
} }
break; break;
} }
case I2ORESETCMD: case I2ORESETCMD: {
if(pHba->host) struct Scsi_Host *shost = pHba->host;
spin_lock_irqsave(pHba->host->host_lock, flags);
if (shost)
spin_lock_irqsave(shost->host_lock, flags);
adpt_hba_reset(pHba); adpt_hba_reset(pHba);
if(pHba->host) if (shost)
spin_unlock_irqrestore(pHba->host->host_lock, flags); spin_unlock_irqrestore(shost->host_lock, flags);
break; break;
}
case I2ORESCANCMD: case I2ORESCANCMD:
adpt_rescan(pHba); adpt_rescan(pHba);
break; break;
......
...@@ -472,7 +472,6 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) ...@@ -472,7 +472,6 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
else else
shost->dma_boundary = 0xffffffff; shost->dma_boundary = 0xffffffff;
shost->use_blk_mq = scsi_use_blk_mq;
shost->use_blk_mq = scsi_use_blk_mq || shost->hostt->force_blk_mq; shost->use_blk_mq = scsi_use_blk_mq || shost->hostt->force_blk_mq;
device_initialize(&shost->shost_gendev); device_initialize(&shost->shost_gendev);
......
...@@ -3794,6 +3794,7 @@ int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport) ...@@ -3794,6 +3794,7 @@ int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport)
sp->gen1 = fcport->rscn_gen; sp->gen1 = fcport->rscn_gen;
sp->gen2 = fcport->login_gen; sp->gen2 = fcport->login_gen;
sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
/* CT_IU preamble */ /* CT_IU preamble */
...@@ -3812,7 +3813,6 @@ int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport) ...@@ -3812,7 +3813,6 @@ int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport)
sp->u.iocb_cmd.u.ctarg.rsp_size = GFF_ID_RSP_SIZE; sp->u.iocb_cmd.u.ctarg.rsp_size = GFF_ID_RSP_SIZE;
sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
sp->done = qla24xx_async_gffid_sp_done; sp->done = qla24xx_async_gffid_sp_done;
rval = qla2x00_start_sp(sp); rval = qla2x00_start_sp(sp);
...@@ -4230,6 +4230,8 @@ static int qla24xx_async_gnnft(scsi_qla_host_t *vha, struct srb *sp, ...@@ -4230,6 +4230,8 @@ static int qla24xx_async_gnnft(scsi_qla_host_t *vha, struct srb *sp,
sp->name = "gnnft"; sp->name = "gnnft";
sp->gen1 = vha->hw->base_qpair->chip_reset; sp->gen1 = vha->hw->base_qpair->chip_reset;
sp->gen2 = fc4_type; sp->gen2 = fc4_type;
sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
memset(sp->u.iocb_cmd.u.ctarg.rsp, 0, sp->u.iocb_cmd.u.ctarg.rsp_size); memset(sp->u.iocb_cmd.u.ctarg.rsp, 0, sp->u.iocb_cmd.u.ctarg.rsp_size);
...@@ -4246,7 +4248,6 @@ static int qla24xx_async_gnnft(scsi_qla_host_t *vha, struct srb *sp, ...@@ -4246,7 +4248,6 @@ static int qla24xx_async_gnnft(scsi_qla_host_t *vha, struct srb *sp,
sp->u.iocb_cmd.u.ctarg.req_size = GNN_FT_REQ_SIZE; sp->u.iocb_cmd.u.ctarg.req_size = GNN_FT_REQ_SIZE;
sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
sp->done = qla2x00_async_gpnft_gnnft_sp_done; sp->done = qla2x00_async_gpnft_gnnft_sp_done;
rval = qla2x00_start_sp(sp); rval = qla2x00_start_sp(sp);
...@@ -4370,6 +4371,8 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp) ...@@ -4370,6 +4371,8 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp)
sp->name = "gpnft"; sp->name = "gpnft";
sp->gen1 = vha->hw->base_qpair->chip_reset; sp->gen1 = vha->hw->base_qpair->chip_reset;
sp->gen2 = fc4_type; sp->gen2 = fc4_type;
sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
rspsz = sizeof(struct ct_sns_gpnft_rsp) + rspsz = sizeof(struct ct_sns_gpnft_rsp) +
...@@ -4385,7 +4388,6 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp) ...@@ -4385,7 +4388,6 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp)
sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
sp->done = qla2x00_async_gpnft_gnnft_sp_done; sp->done = qla2x00_async_gpnft_gnnft_sp_done;
rval = qla2x00_start_sp(sp); rval = qla2x00_start_sp(sp);
...@@ -4495,6 +4497,7 @@ int qla24xx_async_gnnid(scsi_qla_host_t *vha, fc_port_t *fcport) ...@@ -4495,6 +4497,7 @@ int qla24xx_async_gnnid(scsi_qla_host_t *vha, fc_port_t *fcport)
sp->gen1 = fcport->rscn_gen; sp->gen1 = fcport->rscn_gen;
sp->gen2 = fcport->login_gen; sp->gen2 = fcport->login_gen;
sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
/* CT_IU preamble */ /* CT_IU preamble */
...@@ -4516,7 +4519,6 @@ int qla24xx_async_gnnid(scsi_qla_host_t *vha, fc_port_t *fcport) ...@@ -4516,7 +4519,6 @@ int qla24xx_async_gnnid(scsi_qla_host_t *vha, fc_port_t *fcport)
sp->u.iocb_cmd.u.ctarg.rsp_size = GNN_ID_RSP_SIZE; sp->u.iocb_cmd.u.ctarg.rsp_size = GNN_ID_RSP_SIZE;
sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
sp->done = qla2x00_async_gnnid_sp_done; sp->done = qla2x00_async_gnnid_sp_done;
rval = qla2x00_start_sp(sp); rval = qla2x00_start_sp(sp);
...@@ -4632,6 +4634,7 @@ int qla24xx_async_gfpnid(scsi_qla_host_t *vha, fc_port_t *fcport) ...@@ -4632,6 +4634,7 @@ int qla24xx_async_gfpnid(scsi_qla_host_t *vha, fc_port_t *fcport)
sp->gen1 = fcport->rscn_gen; sp->gen1 = fcport->rscn_gen;
sp->gen2 = fcport->login_gen; sp->gen2 = fcport->login_gen;
sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
/* CT_IU preamble */ /* CT_IU preamble */
...@@ -4653,7 +4656,6 @@ int qla24xx_async_gfpnid(scsi_qla_host_t *vha, fc_port_t *fcport) ...@@ -4653,7 +4656,6 @@ int qla24xx_async_gfpnid(scsi_qla_host_t *vha, fc_port_t *fcport)
sp->u.iocb_cmd.u.ctarg.rsp_size = GFPN_ID_RSP_SIZE; sp->u.iocb_cmd.u.ctarg.rsp_size = GFPN_ID_RSP_SIZE;
sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
sp->done = qla2x00_async_gfpnid_sp_done; sp->done = qla2x00_async_gfpnid_sp_done;
rval = qla2x00_start_sp(sp); rval = qla2x00_start_sp(sp);
......
...@@ -183,10 +183,11 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport, ...@@ -183,10 +183,11 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport,
sp->name = "login"; sp->name = "login";
sp->gen1 = fcport->rscn_gen; sp->gen1 = fcport->rscn_gen;
sp->gen2 = fcport->login_gen; sp->gen2 = fcport->login_gen;
qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
lio = &sp->u.iocb_cmd; lio = &sp->u.iocb_cmd;
lio->timeout = qla2x00_async_iocb_timeout; lio->timeout = qla2x00_async_iocb_timeout;
qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
sp->done = qla2x00_async_login_sp_done; sp->done = qla2x00_async_login_sp_done;
lio->u.logio.flags |= SRB_LOGIN_COND_PLOGI; lio->u.logio.flags |= SRB_LOGIN_COND_PLOGI;
...@@ -245,10 +246,11 @@ qla2x00_async_logout(struct scsi_qla_host *vha, fc_port_t *fcport) ...@@ -245,10 +246,11 @@ qla2x00_async_logout(struct scsi_qla_host *vha, fc_port_t *fcport)
sp->type = SRB_LOGOUT_CMD; sp->type = SRB_LOGOUT_CMD;
sp->name = "logout"; sp->name = "logout";
qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
lio = &sp->u.iocb_cmd; lio = &sp->u.iocb_cmd;
lio->timeout = qla2x00_async_iocb_timeout; lio->timeout = qla2x00_async_iocb_timeout;
qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
sp->done = qla2x00_async_logout_sp_done; sp->done = qla2x00_async_logout_sp_done;
rval = qla2x00_start_sp(sp); rval = qla2x00_start_sp(sp);
if (rval != QLA_SUCCESS) if (rval != QLA_SUCCESS)
...@@ -307,10 +309,11 @@ qla2x00_async_prlo(struct scsi_qla_host *vha, fc_port_t *fcport) ...@@ -307,10 +309,11 @@ qla2x00_async_prlo(struct scsi_qla_host *vha, fc_port_t *fcport)
sp->type = SRB_PRLO_CMD; sp->type = SRB_PRLO_CMD;
sp->name = "prlo"; sp->name = "prlo";
qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
lio = &sp->u.iocb_cmd; lio = &sp->u.iocb_cmd;
lio->timeout = qla2x00_async_iocb_timeout; lio->timeout = qla2x00_async_iocb_timeout;
qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
sp->done = qla2x00_async_prlo_sp_done; sp->done = qla2x00_async_prlo_sp_done;
rval = qla2x00_start_sp(sp); rval = qla2x00_start_sp(sp);
if (rval != QLA_SUCCESS) if (rval != QLA_SUCCESS)
...@@ -412,10 +415,11 @@ qla2x00_async_adisc(struct scsi_qla_host *vha, fc_port_t *fcport, ...@@ -412,10 +415,11 @@ qla2x00_async_adisc(struct scsi_qla_host *vha, fc_port_t *fcport,
sp->type = SRB_ADISC_CMD; sp->type = SRB_ADISC_CMD;
sp->name = "adisc"; sp->name = "adisc";
qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
lio = &sp->u.iocb_cmd; lio = &sp->u.iocb_cmd;
lio->timeout = qla2x00_async_iocb_timeout; lio->timeout = qla2x00_async_iocb_timeout;
qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
sp->done = qla2x00_async_adisc_sp_done; sp->done = qla2x00_async_adisc_sp_done;
if (data[1] & QLA_LOGIO_LOGIN_RETRIED) if (data[1] & QLA_LOGIO_LOGIN_RETRIED)
lio->u.logio.flags |= SRB_LOGIN_RETRIED; lio->u.logio.flags |= SRB_LOGIN_RETRIED;
...@@ -745,6 +749,8 @@ int qla24xx_async_gnl(struct scsi_qla_host *vha, fc_port_t *fcport) ...@@ -745,6 +749,8 @@ int qla24xx_async_gnl(struct scsi_qla_host *vha, fc_port_t *fcport)
sp->gen1 = fcport->rscn_gen; sp->gen1 = fcport->rscn_gen;
sp->gen2 = fcport->login_gen; sp->gen2 = fcport->login_gen;
mbx = &sp->u.iocb_cmd;
mbx->timeout = qla2x00_async_iocb_timeout;
qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha)+2); qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha)+2);
mb = sp->u.iocb_cmd.u.mbx.out_mb; mb = sp->u.iocb_cmd.u.mbx.out_mb;
...@@ -757,9 +763,6 @@ int qla24xx_async_gnl(struct scsi_qla_host *vha, fc_port_t *fcport) ...@@ -757,9 +763,6 @@ int qla24xx_async_gnl(struct scsi_qla_host *vha, fc_port_t *fcport)
mb[8] = vha->gnl.size; mb[8] = vha->gnl.size;
mb[9] = vha->vp_idx; mb[9] = vha->vp_idx;
mbx = &sp->u.iocb_cmd;
mbx->timeout = qla2x00_async_iocb_timeout;
sp->done = qla24xx_async_gnl_sp_done; sp->done = qla24xx_async_gnl_sp_done;
rval = qla2x00_start_sp(sp); rval = qla2x00_start_sp(sp);
...@@ -887,10 +890,11 @@ qla24xx_async_prli(struct scsi_qla_host *vha, fc_port_t *fcport) ...@@ -887,10 +890,11 @@ qla24xx_async_prli(struct scsi_qla_host *vha, fc_port_t *fcport)
sp->type = SRB_PRLI_CMD; sp->type = SRB_PRLI_CMD;
sp->name = "prli"; sp->name = "prli";
qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
lio = &sp->u.iocb_cmd; lio = &sp->u.iocb_cmd;
lio->timeout = qla2x00_async_iocb_timeout; lio->timeout = qla2x00_async_iocb_timeout;
qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
sp->done = qla2x00_async_prli_sp_done; sp->done = qla2x00_async_prli_sp_done;
lio->u.logio.flags = 0; lio->u.logio.flags = 0;
...@@ -955,6 +959,9 @@ int qla24xx_async_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport, u8 opt) ...@@ -955,6 +959,9 @@ int qla24xx_async_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport, u8 opt)
sp->name = "gpdb"; sp->name = "gpdb";
sp->gen1 = fcport->rscn_gen; sp->gen1 = fcport->rscn_gen;
sp->gen2 = fcport->login_gen; sp->gen2 = fcport->login_gen;
mbx = &sp->u.iocb_cmd;
mbx->timeout = qla2x00_async_iocb_timeout;
qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
pd = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma); pd = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma);
...@@ -974,8 +981,6 @@ int qla24xx_async_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport, u8 opt) ...@@ -974,8 +981,6 @@ int qla24xx_async_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport, u8 opt)
mb[9] = vha->vp_idx; mb[9] = vha->vp_idx;
mb[10] = opt; mb[10] = opt;
mbx = &sp->u.iocb_cmd;
mbx->timeout = qla2x00_async_iocb_timeout;
mbx->u.mbx.in = (void *)pd; mbx->u.mbx.in = (void *)pd;
mbx->u.mbx.in_dma = pd_dma; mbx->u.mbx.in_dma = pd_dma;
...@@ -1490,13 +1495,15 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint32_t lun, ...@@ -1490,13 +1495,15 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint32_t lun,
tm_iocb = &sp->u.iocb_cmd; tm_iocb = &sp->u.iocb_cmd;
sp->type = SRB_TM_CMD; sp->type = SRB_TM_CMD;
sp->name = "tmf"; sp->name = "tmf";
tm_iocb->timeout = qla2x00_tmf_iocb_timeout;
init_completion(&tm_iocb->u.tmf.comp);
qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha)); qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha));
tm_iocb->u.tmf.flags = flags; tm_iocb->u.tmf.flags = flags;
tm_iocb->u.tmf.lun = lun; tm_iocb->u.tmf.lun = lun;
tm_iocb->u.tmf.data = tag; tm_iocb->u.tmf.data = tag;
sp->done = qla2x00_tmf_sp_done; sp->done = qla2x00_tmf_sp_done;
tm_iocb->timeout = qla2x00_tmf_iocb_timeout;
init_completion(&tm_iocb->u.tmf.comp);
rval = qla2x00_start_sp(sp); rval = qla2x00_start_sp(sp);
if (rval != QLA_SUCCESS) if (rval != QLA_SUCCESS)
...@@ -1550,8 +1557,8 @@ qla24xx_abort_sp_done(void *ptr, int res) ...@@ -1550,8 +1557,8 @@ qla24xx_abort_sp_done(void *ptr, int res)
srb_t *sp = ptr; srb_t *sp = ptr;
struct srb_iocb *abt = &sp->u.iocb_cmd; struct srb_iocb *abt = &sp->u.iocb_cmd;
del_timer(&sp->u.iocb_cmd.timer); if (del_timer(&sp->u.iocb_cmd.timer))
complete(&abt->u.abt.comp); complete(&abt->u.abt.comp);
} }
int int
...@@ -1570,7 +1577,11 @@ qla24xx_async_abort_cmd(srb_t *cmd_sp) ...@@ -1570,7 +1577,11 @@ qla24xx_async_abort_cmd(srb_t *cmd_sp)
abt_iocb = &sp->u.iocb_cmd; abt_iocb = &sp->u.iocb_cmd;
sp->type = SRB_ABT_CMD; sp->type = SRB_ABT_CMD;
sp->name = "abort"; sp->name = "abort";
abt_iocb->timeout = qla24xx_abort_iocb_timeout;
init_completion(&abt_iocb->u.abt.comp);
qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha)); qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha));
abt_iocb->u.abt.cmd_hndl = cmd_sp->handle; abt_iocb->u.abt.cmd_hndl = cmd_sp->handle;
if (vha->flags.qpairs_available && cmd_sp->qpair) if (vha->flags.qpairs_available && cmd_sp->qpair)
...@@ -1580,8 +1591,6 @@ qla24xx_async_abort_cmd(srb_t *cmd_sp) ...@@ -1580,8 +1591,6 @@ qla24xx_async_abort_cmd(srb_t *cmd_sp)
abt_iocb->u.abt.req_que_no = cpu_to_le16(vha->req->id); abt_iocb->u.abt.req_que_no = cpu_to_le16(vha->req->id);
sp->done = qla24xx_abort_sp_done; sp->done = qla24xx_abort_sp_done;
abt_iocb->timeout = qla24xx_abort_iocb_timeout;
init_completion(&abt_iocb->u.abt.comp);
rval = qla2x00_start_sp(sp); rval = qla2x00_start_sp(sp);
if (rval != QLA_SUCCESS) if (rval != QLA_SUCCESS)
......
...@@ -272,13 +272,13 @@ qla2x00_init_timer(srb_t *sp, unsigned long tmo) ...@@ -272,13 +272,13 @@ qla2x00_init_timer(srb_t *sp, unsigned long tmo)
{ {
timer_setup(&sp->u.iocb_cmd.timer, qla2x00_sp_timeout, 0); timer_setup(&sp->u.iocb_cmd.timer, qla2x00_sp_timeout, 0);
sp->u.iocb_cmd.timer.expires = jiffies + tmo * HZ; sp->u.iocb_cmd.timer.expires = jiffies + tmo * HZ;
add_timer(&sp->u.iocb_cmd.timer);
sp->free = qla2x00_sp_free; sp->free = qla2x00_sp_free;
init_completion(&sp->comp); init_completion(&sp->comp);
if (IS_QLAFX00(sp->vha->hw) && (sp->type == SRB_FXIOCB_DCMD)) if (IS_QLAFX00(sp->vha->hw) && (sp->type == SRB_FXIOCB_DCMD))
init_completion(&sp->u.iocb_cmd.u.fxiocb.fxiocb_comp); init_completion(&sp->u.iocb_cmd.u.fxiocb.fxiocb_comp);
if (sp->type == SRB_ELS_DCMD) if (sp->type == SRB_ELS_DCMD)
init_completion(&sp->u.iocb_cmd.u.els_logo.comp); init_completion(&sp->u.iocb_cmd.u.els_logo.comp);
add_timer(&sp->u.iocb_cmd.timer);
} }
static inline int static inline int
......
...@@ -2460,8 +2460,8 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *vha, int els_opcode, ...@@ -2460,8 +2460,8 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *vha, int els_opcode,
sp->type = SRB_ELS_DCMD; sp->type = SRB_ELS_DCMD;
sp->name = "ELS_DCMD"; sp->name = "ELS_DCMD";
sp->fcport = fcport; sp->fcport = fcport;
qla2x00_init_timer(sp, ELS_DCMD_TIMEOUT);
elsio->timeout = qla2x00_els_dcmd_iocb_timeout; elsio->timeout = qla2x00_els_dcmd_iocb_timeout;
qla2x00_init_timer(sp, ELS_DCMD_TIMEOUT);
sp->done = qla2x00_els_dcmd_sp_done; sp->done = qla2x00_els_dcmd_sp_done;
sp->free = qla2x00_els_dcmd_sp_free; sp->free = qla2x00_els_dcmd_sp_free;
...@@ -2658,8 +2658,11 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode, ...@@ -2658,8 +2658,11 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
sp->type = SRB_ELS_DCMD; sp->type = SRB_ELS_DCMD;
sp->name = "ELS_DCMD"; sp->name = "ELS_DCMD";
sp->fcport = fcport; sp->fcport = fcport;
qla2x00_init_timer(sp, ELS_DCMD_TIMEOUT);
elsio->timeout = qla2x00_els_dcmd2_iocb_timeout; elsio->timeout = qla2x00_els_dcmd2_iocb_timeout;
init_completion(&elsio->u.els_plogi.comp);
qla2x00_init_timer(sp, ELS_DCMD_TIMEOUT);
sp->done = qla2x00_els_dcmd2_sp_done; sp->done = qla2x00_els_dcmd2_sp_done;
sp->free = qla2x00_els_dcmd2_sp_free; sp->free = qla2x00_els_dcmd2_sp_free;
...@@ -2696,7 +2699,6 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode, ...@@ -2696,7 +2699,6 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
ql_dump_buffer(ql_dbg_io + ql_dbg_buffer, vha, 0x0109, ql_dump_buffer(ql_dbg_io + ql_dbg_buffer, vha, 0x0109,
(uint8_t *)elsio->u.els_plogi.els_plogi_pyld, 0x70); (uint8_t *)elsio->u.els_plogi.els_plogi_pyld, 0x70);
init_completion(&elsio->u.els_plogi.comp);
rval = qla2x00_start_sp(sp); rval = qla2x00_start_sp(sp);
if (rval != QLA_SUCCESS) { if (rval != QLA_SUCCESS) {
rval = QLA_FUNCTION_FAILED; rval = QLA_FUNCTION_FAILED;
......
...@@ -2174,7 +2174,7 @@ qla2x00_handle_dif_error(srb_t *sp, struct sts_entry_24xx *sts24) ...@@ -2174,7 +2174,7 @@ qla2x00_handle_dif_error(srb_t *sp, struct sts_entry_24xx *sts24)
0x10, 0x1); 0x10, 0x1);
set_driver_byte(cmd, DRIVER_SENSE); set_driver_byte(cmd, DRIVER_SENSE);
set_host_byte(cmd, DID_ABORT); set_host_byte(cmd, DID_ABORT);
cmd->result |= SAM_STAT_CHECK_CONDITION << 1; cmd->result |= SAM_STAT_CHECK_CONDITION;
return 1; return 1;
} }
...@@ -2184,7 +2184,7 @@ qla2x00_handle_dif_error(srb_t *sp, struct sts_entry_24xx *sts24) ...@@ -2184,7 +2184,7 @@ qla2x00_handle_dif_error(srb_t *sp, struct sts_entry_24xx *sts24)
0x10, 0x3); 0x10, 0x3);
set_driver_byte(cmd, DRIVER_SENSE); set_driver_byte(cmd, DRIVER_SENSE);
set_host_byte(cmd, DID_ABORT); set_host_byte(cmd, DID_ABORT);
cmd->result |= SAM_STAT_CHECK_CONDITION << 1; cmd->result |= SAM_STAT_CHECK_CONDITION;
return 1; return 1;
} }
...@@ -2194,7 +2194,7 @@ qla2x00_handle_dif_error(srb_t *sp, struct sts_entry_24xx *sts24) ...@@ -2194,7 +2194,7 @@ qla2x00_handle_dif_error(srb_t *sp, struct sts_entry_24xx *sts24)
0x10, 0x2); 0x10, 0x2);
set_driver_byte(cmd, DRIVER_SENSE); set_driver_byte(cmd, DRIVER_SENSE);
set_host_byte(cmd, DID_ABORT); set_host_byte(cmd, DID_ABORT);
cmd->result |= SAM_STAT_CHECK_CONDITION << 1; cmd->result |= SAM_STAT_CHECK_CONDITION;
return 1; return 1;
} }
...@@ -2347,7 +2347,7 @@ qla25xx_process_bidir_status_iocb(scsi_qla_host_t *vha, void *pkt, ...@@ -2347,7 +2347,7 @@ qla25xx_process_bidir_status_iocb(scsi_qla_host_t *vha, void *pkt,
bsg_job->reply_len = sizeof(struct fc_bsg_reply); bsg_job->reply_len = sizeof(struct fc_bsg_reply);
/* Always return DID_OK, bsg will send the vendor specific response /* Always return DID_OK, bsg will send the vendor specific response
* in this case only */ * in this case only */
sp->done(sp, DID_OK << 6); sp->done(sp, DID_OK << 16);
} }
......
...@@ -6023,14 +6023,14 @@ int qla24xx_send_mb_cmd(struct scsi_qla_host *vha, mbx_cmd_t *mcp) ...@@ -6023,14 +6023,14 @@ int qla24xx_send_mb_cmd(struct scsi_qla_host *vha, mbx_cmd_t *mcp)
sp->type = SRB_MB_IOCB; sp->type = SRB_MB_IOCB;
sp->name = mb_to_str(mcp->mb[0]); sp->name = mb_to_str(mcp->mb[0]);
qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
memcpy(sp->u.iocb_cmd.u.mbx.out_mb, mcp->mb, SIZEOF_IOCB_MB_REG);
c = &sp->u.iocb_cmd; c = &sp->u.iocb_cmd;
c->timeout = qla2x00_async_iocb_timeout; c->timeout = qla2x00_async_iocb_timeout;
init_completion(&c->u.mbx.comp); init_completion(&c->u.mbx.comp);
qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
memcpy(sp->u.iocb_cmd.u.mbx.out_mb, mcp->mb, SIZEOF_IOCB_MB_REG);
sp->done = qla2x00_async_mb_sp_done; sp->done = qla2x00_async_mb_sp_done;
rval = qla2x00_start_sp(sp); rval = qla2x00_start_sp(sp);
......
...@@ -929,8 +929,8 @@ int qla24xx_control_vp(scsi_qla_host_t *vha, int cmd) ...@@ -929,8 +929,8 @@ int qla24xx_control_vp(scsi_qla_host_t *vha, int cmd)
sp->type = SRB_CTRL_VP; sp->type = SRB_CTRL_VP;
sp->name = "ctrl_vp"; sp->name = "ctrl_vp";
sp->done = qla_ctrlvp_sp_done; sp->done = qla_ctrlvp_sp_done;
qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
sp->u.iocb_cmd.u.ctrlvp.cmd = cmd; sp->u.iocb_cmd.u.ctrlvp.cmd = cmd;
sp->u.iocb_cmd.u.ctrlvp.vp_index = vp_index; sp->u.iocb_cmd.u.ctrlvp.vp_index = vp_index;
......
...@@ -1821,9 +1821,11 @@ qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t *fcport, uint16_t fx_type) ...@@ -1821,9 +1821,11 @@ qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t *fcport, uint16_t fx_type)
sp->type = SRB_FXIOCB_DCMD; sp->type = SRB_FXIOCB_DCMD;
sp->name = "fxdisc"; sp->name = "fxdisc";
qla2x00_init_timer(sp, FXDISC_TIMEOUT);
fdisc = &sp->u.iocb_cmd; fdisc = &sp->u.iocb_cmd;
fdisc->timeout = qla2x00_fxdisc_iocb_timeout;
qla2x00_init_timer(sp, FXDISC_TIMEOUT);
switch (fx_type) { switch (fx_type) {
case FXDISC_GET_CONFIG_INFO: case FXDISC_GET_CONFIG_INFO:
fdisc->u.fxiocb.flags = fdisc->u.fxiocb.flags =
...@@ -1924,7 +1926,6 @@ qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t *fcport, uint16_t fx_type) ...@@ -1924,7 +1926,6 @@ qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t *fcport, uint16_t fx_type)
goto done_unmap_req; goto done_unmap_req;
} }
fdisc->timeout = qla2x00_fxdisc_iocb_timeout;
fdisc->u.fxiocb.req_func_type = cpu_to_le16(fx_type); fdisc->u.fxiocb.req_func_type = cpu_to_le16(fx_type);
sp->done = qla2x00_fxdisc_sp_done; sp->done = qla2x00_fxdisc_sp_done;
......
...@@ -470,9 +470,6 @@ static int qla2x00_alloc_queues(struct qla_hw_data *ha, struct req_que *req, ...@@ -470,9 +470,6 @@ static int qla2x00_alloc_queues(struct qla_hw_data *ha, struct req_que *req,
static void qla2x00_free_req_que(struct qla_hw_data *ha, struct req_que *req) static void qla2x00_free_req_que(struct qla_hw_data *ha, struct req_que *req)
{ {
if (!ha->req_q_map)
return;
if (IS_QLAFX00(ha)) { if (IS_QLAFX00(ha)) {
if (req && req->ring_fx00) if (req && req->ring_fx00)
dma_free_coherent(&ha->pdev->dev, dma_free_coherent(&ha->pdev->dev,
...@@ -483,17 +480,14 @@ static void qla2x00_free_req_que(struct qla_hw_data *ha, struct req_que *req) ...@@ -483,17 +480,14 @@ static void qla2x00_free_req_que(struct qla_hw_data *ha, struct req_que *req)
(req->length + 1) * sizeof(request_t), (req->length + 1) * sizeof(request_t),
req->ring, req->dma); req->ring, req->dma);
if (req) { if (req)
kfree(req->outstanding_cmds); kfree(req->outstanding_cmds);
kfree(req);
} kfree(req);
} }
static void qla2x00_free_rsp_que(struct qla_hw_data *ha, struct rsp_que *rsp) static void qla2x00_free_rsp_que(struct qla_hw_data *ha, struct rsp_que *rsp)
{ {
if (!ha->rsp_q_map)
return;
if (IS_QLAFX00(ha)) { if (IS_QLAFX00(ha)) {
if (rsp && rsp->ring_fx00) if (rsp && rsp->ring_fx00)
dma_free_coherent(&ha->pdev->dev, dma_free_coherent(&ha->pdev->dev,
...@@ -504,8 +498,7 @@ static void qla2x00_free_rsp_que(struct qla_hw_data *ha, struct rsp_que *rsp) ...@@ -504,8 +498,7 @@ static void qla2x00_free_rsp_que(struct qla_hw_data *ha, struct rsp_que *rsp)
(rsp->length + 1) * sizeof(response_t), (rsp->length + 1) * sizeof(response_t),
rsp->ring, rsp->dma); rsp->ring, rsp->dma);
} }
if (rsp) kfree(rsp);
kfree(rsp);
} }
static void qla2x00_free_queues(struct qla_hw_data *ha) static void qla2x00_free_queues(struct qla_hw_data *ha)
...@@ -3106,7 +3099,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -3106,7 +3099,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
goto probe_failed; goto probe_failed;
/* Alloc arrays of request and response ring ptrs */ /* Alloc arrays of request and response ring ptrs */
if (qla2x00_alloc_queues(ha, req, rsp)) { ret = qla2x00_alloc_queues(ha, req, rsp);
if (ret) {
ql_log(ql_log_fatal, base_vha, 0x003d, ql_log(ql_log_fatal, base_vha, 0x003d,
"Failed to allocate memory for queue pointers..." "Failed to allocate memory for queue pointers..."
"aborting.\n"); "aborting.\n");
...@@ -3407,8 +3401,15 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -3407,8 +3401,15 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
} }
qla2x00_free_device(base_vha); qla2x00_free_device(base_vha);
scsi_host_put(base_vha->host); scsi_host_put(base_vha->host);
/*
* Need to NULL out local req/rsp after
* qla2x00_free_device => qla2x00_free_queues frees
* what these are pointing to. Or else we'll
* fall over below in qla2x00_free_req/rsp_que.
*/
req = NULL;
rsp = NULL;
probe_hw_failed: probe_hw_failed:
qla2x00_mem_free(ha); qla2x00_mem_free(ha);
...@@ -4114,6 +4115,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, ...@@ -4114,6 +4115,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
(*rsp)->dma = 0; (*rsp)->dma = 0;
fail_rsp_ring: fail_rsp_ring:
kfree(*rsp); kfree(*rsp);
*rsp = NULL;
fail_rsp: fail_rsp:
dma_free_coherent(&ha->pdev->dev, ((*req)->length + 1) * dma_free_coherent(&ha->pdev->dev, ((*req)->length + 1) *
sizeof(request_t), (*req)->ring, (*req)->dma); sizeof(request_t), (*req)->ring, (*req)->dma);
...@@ -4121,6 +4123,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, ...@@ -4121,6 +4123,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
(*req)->dma = 0; (*req)->dma = 0;
fail_req_ring: fail_req_ring:
kfree(*req); kfree(*req);
*req = NULL;
fail_req: fail_req:
dma_free_coherent(&ha->pdev->dev, sizeof(struct ct_sns_pkt), dma_free_coherent(&ha->pdev->dev, sizeof(struct ct_sns_pkt),
ha->ct_sns, ha->ct_sns_dma); ha->ct_sns, ha->ct_sns_dma);
...@@ -4508,16 +4511,11 @@ qla2x00_mem_free(struct qla_hw_data *ha) ...@@ -4508,16 +4511,11 @@ qla2x00_mem_free(struct qla_hw_data *ha)
dma_free_coherent(&ha->pdev->dev, ha->init_cb_size, dma_free_coherent(&ha->pdev->dev, ha->init_cb_size,
ha->init_cb, ha->init_cb_dma); ha->init_cb, ha->init_cb_dma);
if (ha->optrom_buffer) vfree(ha->optrom_buffer);
vfree(ha->optrom_buffer); kfree(ha->nvram);
if (ha->nvram) kfree(ha->npiv_info);
kfree(ha->nvram); kfree(ha->swl);
if (ha->npiv_info) kfree(ha->loop_id_map);
kfree(ha->npiv_info);
if (ha->swl)
kfree(ha->swl);
if (ha->loop_id_map)
kfree(ha->loop_id_map);
ha->srb_mempool = NULL; ha->srb_mempool = NULL;
ha->ctx_mempool = NULL; ha->ctx_mempool = NULL;
......
...@@ -664,10 +664,10 @@ int qla24xx_async_notify_ack(scsi_qla_host_t *vha, fc_port_t *fcport, ...@@ -664,10 +664,10 @@ int qla24xx_async_notify_ack(scsi_qla_host_t *vha, fc_port_t *fcport,
sp->type = type; sp->type = type;
sp->name = "nack"; sp->name = "nack";
sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha)+2); qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha)+2);
sp->u.iocb_cmd.u.nack.ntfy = ntfy; sp->u.iocb_cmd.u.nack.ntfy = ntfy;
sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
sp->done = qla2x00_async_nack_sp_done; sp->done = qla2x00_async_nack_sp_done;
rval = qla2x00_start_sp(sp); rval = qla2x00_start_sp(sp);
......
...@@ -202,7 +202,7 @@ static struct { ...@@ -202,7 +202,7 @@ static struct {
{"Medion", "Flash XL MMC/SD", "2.6D", BLIST_FORCELUN}, {"Medion", "Flash XL MMC/SD", "2.6D", BLIST_FORCELUN},
{"MegaRAID", "LD", NULL, BLIST_FORCELUN}, {"MegaRAID", "LD", NULL, BLIST_FORCELUN},
{"MICROP", "4110", NULL, BLIST_NOTQ}, {"MICROP", "4110", NULL, BLIST_NOTQ},
{"MSFT", "Virtual HD", NULL, BLIST_NO_RSOC}, {"MSFT", "Virtual HD", NULL, BLIST_MAX_1024 | BLIST_NO_RSOC},
{"MYLEX", "DACARMRB", "*", BLIST_REPORTLUN2}, {"MYLEX", "DACARMRB", "*", BLIST_REPORTLUN2},
{"nCipher", "Fastness Crypto", NULL, BLIST_FORCELUN}, {"nCipher", "Fastness Crypto", NULL, BLIST_FORCELUN},
{"NAKAMICH", "MJ-4.8S", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, {"NAKAMICH", "MJ-4.8S", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
......
...@@ -112,6 +112,9 @@ static struct scsi_device_handler *scsi_dh_lookup(const char *name) ...@@ -112,6 +112,9 @@ static struct scsi_device_handler *scsi_dh_lookup(const char *name)
{ {
struct scsi_device_handler *dh; struct scsi_device_handler *dh;
if (!name || strlen(name) == 0)
return NULL;
dh = __scsi_dh_lookup(name); dh = __scsi_dh_lookup(name);
if (!dh) { if (!dh) {
request_module("scsi_dh_%s", name); request_module("scsi_dh_%s", name);
......
...@@ -723,18 +723,25 @@ static bool scsi_end_request(struct request *req, blk_status_t error, ...@@ -723,18 +723,25 @@ static bool scsi_end_request(struct request *req, blk_status_t error,
} }
/** /**
* __scsi_error_from_host_byte - translate SCSI error code into errno * scsi_result_to_blk_status - translate a SCSI result code into blk_status_t
* @cmd: SCSI command (unused) * @cmd: SCSI command
* @result: scsi error code * @result: scsi error code
* *
* Translate SCSI error code into block errors. * Translate a SCSI result code into a blk_status_t value. May reset the host
* byte of @cmd->result.
*/ */
static blk_status_t __scsi_error_from_host_byte(struct scsi_cmnd *cmd, static blk_status_t scsi_result_to_blk_status(struct scsi_cmnd *cmd, int result)
int result)
{ {
switch (host_byte(result)) { switch (host_byte(result)) {
case DID_OK: case DID_OK:
return BLK_STS_OK; /*
* Also check the other bytes than the status byte in result
* to handle the case when a SCSI LLD sets result to
* DRIVER_SENSE << 24 without setting SAM_STAT_CHECK_CONDITION.
*/
if (scsi_status_is_good(result) && (result & ~0xff) == 0)
return BLK_STS_OK;
return BLK_STS_IOERR;
case DID_TRANSPORT_FAILFAST: case DID_TRANSPORT_FAILFAST:
return BLK_STS_TRANSPORT; return BLK_STS_TRANSPORT;
case DID_TARGET_FAILURE: case DID_TARGET_FAILURE:
...@@ -812,10 +819,10 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) ...@@ -812,10 +819,10 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
SCSI_SENSE_BUFFERSIZE); SCSI_SENSE_BUFFERSIZE);
} }
if (!sense_deferred) if (!sense_deferred)
error = __scsi_error_from_host_byte(cmd, result); error = scsi_result_to_blk_status(cmd, result);
} }
/* /*
* __scsi_error_from_host_byte may have reset the host_byte * scsi_result_to_blk_status may have reset the host_byte
*/ */
scsi_req(req)->result = cmd->result; scsi_req(req)->result = cmd->result;
scsi_req(req)->resid_len = scsi_get_resid(cmd); scsi_req(req)->resid_len = scsi_get_resid(cmd);
...@@ -837,7 +844,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) ...@@ -837,7 +844,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
* good_bytes != blk_rq_bytes(req) as the signal for an error. * good_bytes != blk_rq_bytes(req) as the signal for an error.
* This sets the error explicitly for the problem case. * This sets the error explicitly for the problem case.
*/ */
error = __scsi_error_from_host_byte(cmd, result); error = scsi_result_to_blk_status(cmd, result);
} }
/* no bidi support for !blk_rq_is_passthrough yet */ /* no bidi support for !blk_rq_is_passthrough yet */
...@@ -907,7 +914,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) ...@@ -907,7 +914,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
if (result == 0) if (result == 0)
goto requeue; goto requeue;
error = __scsi_error_from_host_byte(cmd, result); error = scsi_result_to_blk_status(cmd, result);
if (host_byte(result) == DID_RESET) { if (host_byte(result) == DID_RESET) {
/* Third party bus reset or reset for error recovery /* Third party bus reset or reset for error recovery
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册