Commit 0950fcbf authored by Linus Torvalds's avatar Linus Torvalds

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

Pull SCSI fixes from James Bottomley:
 "Five fixes, all in drivers.

  The big change is the UFS task management rework, with lpfc next and
  the rest being fairly minor and obvious fixes"

* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
  scsi: iscsi: Fix iscsi_task use after free
  scsi: lpfc: Fix memory overwrite during FC-GS I/O abort handling
  scsi: elx: efct: Delete stray unlock statement
  scsi: ufs: core: Fix task management completion
  scsi: acornscsi: Remove scsi_cmd_to_tag() reference
parents 50eb0a06 258aad75
...@@ -1776,7 +1776,7 @@ int acornscsi_reconnect_finish(AS_Host *host) ...@@ -1776,7 +1776,7 @@ int acornscsi_reconnect_finish(AS_Host *host)
host->scsi.disconnectable = 0; host->scsi.disconnectable = 0;
if (host->SCpnt->device->id == host->scsi.reconnected.target && if (host->SCpnt->device->id == host->scsi.reconnected.target &&
host->SCpnt->device->lun == host->scsi.reconnected.lun && host->SCpnt->device->lun == host->scsi.reconnected.lun &&
scsi_cmd_to_tag(host->SCpnt) == host->scsi.reconnected.tag) { scsi_cmd_to_rq(host->SCpnt)->tag == host->scsi.reconnected.tag) {
#if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON)) #if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
DBG(host->SCpnt, printk("scsi%d.%c: reconnected", DBG(host->SCpnt, printk("scsi%d.%c: reconnected",
host->host->host_no, acornscsi_target(host))); host->host->host_no, acornscsi_target(host)));
......
...@@ -32,7 +32,7 @@ efct_scsi_io_alloc(struct efct_node *node) ...@@ -32,7 +32,7 @@ efct_scsi_io_alloc(struct efct_node *node)
struct efct *efct; struct efct *efct;
struct efct_xport *xport; struct efct_xport *xport;
struct efct_io *io; struct efct_io *io;
unsigned long flags = 0; unsigned long flags;
efct = node->efct; efct = node->efct;
...@@ -44,7 +44,6 @@ efct_scsi_io_alloc(struct efct_node *node) ...@@ -44,7 +44,6 @@ efct_scsi_io_alloc(struct efct_node *node)
if (!io) { if (!io) {
efc_log_err(efct, "IO alloc Failed\n"); efc_log_err(efct, "IO alloc Failed\n");
atomic_add_return(1, &xport->io_alloc_failed_count); atomic_add_return(1, &xport->io_alloc_failed_count);
spin_unlock_irqrestore(&node->active_ios_lock, flags);
return NULL; return NULL;
} }
......
...@@ -2281,11 +2281,6 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) ...@@ -2281,11 +2281,6 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
return FAILED; return FAILED;
} }
conn = session->leadconn;
iscsi_get_conn(conn->cls_conn);
conn->eh_abort_cnt++;
age = session->age;
spin_lock(&session->back_lock); spin_lock(&session->back_lock);
task = (struct iscsi_task *)sc->SCp.ptr; task = (struct iscsi_task *)sc->SCp.ptr;
if (!task || !task->sc) { if (!task || !task->sc) {
...@@ -2293,8 +2288,16 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) ...@@ -2293,8 +2288,16 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
ISCSI_DBG_EH(session, "sc completed while abort in progress\n"); ISCSI_DBG_EH(session, "sc completed while abort in progress\n");
spin_unlock(&session->back_lock); spin_unlock(&session->back_lock);
goto success; spin_unlock_bh(&session->frwd_lock);
mutex_unlock(&session->eh_mutex);
return SUCCESS;
} }
conn = session->leadconn;
iscsi_get_conn(conn->cls_conn);
conn->eh_abort_cnt++;
age = session->age;
ISCSI_DBG_EH(session, "aborting [sc %p itt 0x%x]\n", sc, task->itt); ISCSI_DBG_EH(session, "aborting [sc %p itt 0x%x]\n", sc, task->itt);
__iscsi_get_task(task); __iscsi_get_task(task);
spin_unlock(&session->back_lock); spin_unlock(&session->back_lock);
......
...@@ -12292,12 +12292,12 @@ void ...@@ -12292,12 +12292,12 @@ void
lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
struct lpfc_iocbq *rspiocb) struct lpfc_iocbq *rspiocb)
{ {
struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1; struct lpfc_nodelist *ndlp = NULL;
IOCB_t *irsp = &rspiocb->iocb; IOCB_t *irsp = &rspiocb->iocb;
/* ELS cmd tag <ulpIoTag> completes */ /* ELS cmd tag <ulpIoTag> completes */
lpfc_printf_log(phba, KERN_INFO, LOG_ELS, lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
"0139 Ignoring ELS cmd tag x%x completion Data: " "0139 Ignoring ELS cmd code x%x completion Data: "
"x%x x%x x%x\n", "x%x x%x x%x\n",
irsp->ulpIoTag, irsp->ulpStatus, irsp->ulpIoTag, irsp->ulpStatus,
irsp->un.ulpWord[4], irsp->ulpTimeout); irsp->un.ulpWord[4], irsp->ulpTimeout);
...@@ -12305,10 +12305,13 @@ lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ...@@ -12305,10 +12305,13 @@ lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
* Deref the ndlp after free_iocb. sli_release_iocb will access the ndlp * Deref the ndlp after free_iocb. sli_release_iocb will access the ndlp
* if exchange is busy. * if exchange is busy.
*/ */
if (cmdiocb->iocb.ulpCommand == CMD_GEN_REQUEST64_CR) if (cmdiocb->iocb.ulpCommand == CMD_GEN_REQUEST64_CR) {
ndlp = cmdiocb->context_un.ndlp;
lpfc_ct_free_iocb(phba, cmdiocb); lpfc_ct_free_iocb(phba, cmdiocb);
else } else {
ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
lpfc_els_free_iocb(phba, cmdiocb); lpfc_els_free_iocb(phba, cmdiocb);
}
lpfc_nlp_put(ndlp); lpfc_nlp_put(ndlp);
} }
......
...@@ -6377,27 +6377,6 @@ static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba, u32 intr_status) ...@@ -6377,27 +6377,6 @@ static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba, u32 intr_status)
return retval; return retval;
} }
struct ctm_info {
struct ufs_hba *hba;
unsigned long pending;
unsigned int ncpl;
};
static bool ufshcd_compl_tm(struct request *req, void *priv, bool reserved)
{
struct ctm_info *const ci = priv;
struct completion *c;
WARN_ON_ONCE(reserved);
if (test_bit(req->tag, &ci->pending))
return true;
ci->ncpl++;
c = req->end_io_data;
if (c)
complete(c);
return true;
}
/** /**
* ufshcd_tmc_handler - handle task management function completion * ufshcd_tmc_handler - handle task management function completion
* @hba: per adapter instance * @hba: per adapter instance
...@@ -6408,18 +6387,24 @@ static bool ufshcd_compl_tm(struct request *req, void *priv, bool reserved) ...@@ -6408,18 +6387,24 @@ static bool ufshcd_compl_tm(struct request *req, void *priv, bool reserved)
*/ */
static irqreturn_t ufshcd_tmc_handler(struct ufs_hba *hba) static irqreturn_t ufshcd_tmc_handler(struct ufs_hba *hba)
{ {
unsigned long flags; unsigned long flags, pending, issued;
struct request_queue *q = hba->tmf_queue; irqreturn_t ret = IRQ_NONE;
struct ctm_info ci = { int tag;
.hba = hba,
}; pending = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL);
spin_lock_irqsave(hba->host->host_lock, flags); spin_lock_irqsave(hba->host->host_lock, flags);
ci.pending = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL); issued = hba->outstanding_tasks & ~pending;
blk_mq_tagset_busy_iter(q->tag_set, ufshcd_compl_tm, &ci); for_each_set_bit(tag, &issued, hba->nutmrs) {
struct request *req = hba->tmf_rqs[tag];
struct completion *c = req->end_io_data;
complete(c);
ret = IRQ_HANDLED;
}
spin_unlock_irqrestore(hba->host->host_lock, flags); spin_unlock_irqrestore(hba->host->host_lock, flags);
return ci.ncpl ? IRQ_HANDLED : IRQ_NONE; return ret;
} }
/** /**
...@@ -6542,9 +6527,9 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba, ...@@ -6542,9 +6527,9 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba,
ufshcd_hold(hba, false); ufshcd_hold(hba, false);
spin_lock_irqsave(host->host_lock, flags); spin_lock_irqsave(host->host_lock, flags);
blk_mq_start_request(req);
task_tag = req->tag; task_tag = req->tag;
hba->tmf_rqs[req->tag] = req;
treq->upiu_req.req_header.dword_0 |= cpu_to_be32(task_tag); treq->upiu_req.req_header.dword_0 |= cpu_to_be32(task_tag);
memcpy(hba->utmrdl_base_addr + task_tag, treq, sizeof(*treq)); memcpy(hba->utmrdl_base_addr + task_tag, treq, sizeof(*treq));
...@@ -6585,6 +6570,7 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba, ...@@ -6585,6 +6570,7 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba,
} }
spin_lock_irqsave(hba->host->host_lock, flags); spin_lock_irqsave(hba->host->host_lock, flags);
hba->tmf_rqs[req->tag] = NULL;
__clear_bit(task_tag, &hba->outstanding_tasks); __clear_bit(task_tag, &hba->outstanding_tasks);
spin_unlock_irqrestore(hba->host->host_lock, flags); spin_unlock_irqrestore(hba->host->host_lock, flags);
...@@ -9635,6 +9621,12 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) ...@@ -9635,6 +9621,12 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
err = PTR_ERR(hba->tmf_queue); err = PTR_ERR(hba->tmf_queue);
goto free_tmf_tag_set; goto free_tmf_tag_set;
} }
hba->tmf_rqs = devm_kcalloc(hba->dev, hba->nutmrs,
sizeof(*hba->tmf_rqs), GFP_KERNEL);
if (!hba->tmf_rqs) {
err = -ENOMEM;
goto free_tmf_queue;
}
/* Reset the attached device */ /* Reset the attached device */
ufshcd_device_reset(hba); ufshcd_device_reset(hba);
......
...@@ -828,6 +828,7 @@ struct ufs_hba { ...@@ -828,6 +828,7 @@ struct ufs_hba {
struct blk_mq_tag_set tmf_tag_set; struct blk_mq_tag_set tmf_tag_set;
struct request_queue *tmf_queue; struct request_queue *tmf_queue;
struct request **tmf_rqs;
struct uic_command *active_uic_cmd; struct uic_command *active_uic_cmd;
struct mutex uic_cmd_mutex; struct mutex uic_cmd_mutex;
......
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