mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-04-27 16:35:19 -04:00
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
This commit is contained in:
@@ -1776,7 +1776,7 @@ int acornscsi_reconnect_finish(AS_Host *host)
|
||||
host->scsi.disconnectable = 0;
|
||||
if (host->SCpnt->device->id == host->scsi.reconnected.target &&
|
||||
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))
|
||||
DBG(host->SCpnt, printk("scsi%d.%c: reconnected",
|
||||
host->host->host_no, acornscsi_target(host)));
|
||||
|
||||
@@ -32,7 +32,7 @@ efct_scsi_io_alloc(struct efct_node *node)
|
||||
struct efct *efct;
|
||||
struct efct_xport *xport;
|
||||
struct efct_io *io;
|
||||
unsigned long flags = 0;
|
||||
unsigned long flags;
|
||||
|
||||
efct = node->efct;
|
||||
|
||||
@@ -44,7 +44,6 @@ efct_scsi_io_alloc(struct efct_node *node)
|
||||
if (!io) {
|
||||
efc_log_err(efct, "IO alloc Failed\n");
|
||||
atomic_add_return(1, &xport->io_alloc_failed_count);
|
||||
spin_unlock_irqrestore(&node->active_ios_lock, flags);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -2281,11 +2281,6 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
conn = session->leadconn;
|
||||
iscsi_get_conn(conn->cls_conn);
|
||||
conn->eh_abort_cnt++;
|
||||
age = session->age;
|
||||
|
||||
spin_lock(&session->back_lock);
|
||||
task = (struct iscsi_task *)sc->SCp.ptr;
|
||||
if (!task || !task->sc) {
|
||||
@@ -2293,8 +2288,16 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
|
||||
ISCSI_DBG_EH(session, "sc completed while abort in progress\n");
|
||||
|
||||
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_get_task(task);
|
||||
spin_unlock(&session->back_lock);
|
||||
|
||||
@@ -12292,12 +12292,12 @@ void
|
||||
lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
struct lpfc_iocbq *rspiocb)
|
||||
{
|
||||
struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
|
||||
struct lpfc_nodelist *ndlp = NULL;
|
||||
IOCB_t *irsp = &rspiocb->iocb;
|
||||
|
||||
/* ELS cmd tag <ulpIoTag> completes */
|
||||
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",
|
||||
irsp->ulpIoTag, irsp->ulpStatus,
|
||||
irsp->un.ulpWord[4], irsp->ulpTimeout);
|
||||
@@ -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
|
||||
* 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);
|
||||
else
|
||||
} else {
|
||||
ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
|
||||
lpfc_els_free_iocb(phba, cmdiocb);
|
||||
}
|
||||
|
||||
lpfc_nlp_put(ndlp);
|
||||
}
|
||||
|
||||
@@ -6377,27 +6377,6 @@ static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba, u32 intr_status)
|
||||
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
|
||||
* @hba: per adapter instance
|
||||
@@ -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)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct request_queue *q = hba->tmf_queue;
|
||||
struct ctm_info ci = {
|
||||
.hba = hba,
|
||||
};
|
||||
unsigned long flags, pending, issued;
|
||||
irqreturn_t ret = IRQ_NONE;
|
||||
int tag;
|
||||
|
||||
pending = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL);
|
||||
|
||||
spin_lock_irqsave(hba->host->host_lock, flags);
|
||||
ci.pending = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL);
|
||||
blk_mq_tagset_busy_iter(q->tag_set, ufshcd_compl_tm, &ci);
|
||||
issued = hba->outstanding_tasks & ~pending;
|
||||
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);
|
||||
|
||||
return ci.ncpl ? IRQ_HANDLED : IRQ_NONE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -6542,9 +6527,9 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba,
|
||||
ufshcd_hold(hba, false);
|
||||
|
||||
spin_lock_irqsave(host->host_lock, flags);
|
||||
blk_mq_start_request(req);
|
||||
|
||||
task_tag = req->tag;
|
||||
hba->tmf_rqs[req->tag] = req;
|
||||
treq->upiu_req.req_header.dword_0 |= cpu_to_be32(task_tag);
|
||||
|
||||
memcpy(hba->utmrdl_base_addr + task_tag, treq, sizeof(*treq));
|
||||
@@ -6585,6 +6570,7 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba,
|
||||
}
|
||||
|
||||
spin_lock_irqsave(hba->host->host_lock, flags);
|
||||
hba->tmf_rqs[req->tag] = NULL;
|
||||
__clear_bit(task_tag, &hba->outstanding_tasks);
|
||||
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)
|
||||
err = PTR_ERR(hba->tmf_queue);
|
||||
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 */
|
||||
ufshcd_device_reset(hba);
|
||||
|
||||
@@ -828,6 +828,7 @@ struct ufs_hba {
|
||||
|
||||
struct blk_mq_tag_set tmf_tag_set;
|
||||
struct request_queue *tmf_queue;
|
||||
struct request **tmf_rqs;
|
||||
|
||||
struct uic_command *active_uic_cmd;
|
||||
struct mutex uic_cmd_mutex;
|
||||
|
||||
Reference in New Issue
Block a user