Commit ad8a69f3 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull SCSI fixes from James Bottomley:
 "16 small(ish) fixes all in drivers.

  The major fixes are in pm8001 (fixes MSI-X issue going back to its
  origin), the qla2xxx endianness fix, which fixes a bug on big endian
  and the lpfc ones which can cause an oops on module removal without
  them"

* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
  scsi: lpfc: Prevent use-after-free during rmmod with mapped NVMe rports
  scsi: lpfc: Early return after marking final NLP_DROPPED flag in dev_loss_tmo
  scsi: lpfc: Fix the NULL vs IS_ERR() bug for debugfs_create_file()
  scsi: target: core: Fix target_cmd_counter leak
  scsi: pm8001: Setup IRQs on resume
  scsi: pm80xx: Avoid leaking tags when processing OPC_INB_SET_CONTROLLER_CONFIG command
  scsi: pm80xx: Use phy-specific SAS address when sending PHY_START command
  scsi: ufs: core: Poll HCS.UCRDY before issuing a UIC command
  scsi: ufs: core: Move __ufshcd_send_uic_cmd() outside host_lock
  scsi: qedf: Add synchronization between I/O completions and abort
  scsi: target: Replace strlcpy() with strscpy()
  scsi: qla2xxx: Fix NULL vs IS_ERR() bug for debugfs_create_dir()
  scsi: qla2xxx: Use raw_smp_processor_id() instead of smp_processor_id()
  scsi: qla2xxx: Correct endianness for rqstlen and rsplen
  scsi: ppa: Fix accidentally reversed conditions for 16-bit and 32-bit EPP
  scsi: megaraid_sas: Fix deadlock on firmware crashdump
parents cc3e5afc dae40be7
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -6073,7 +6073,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
					    phba->hba_debugfs_root,
					    phba,
					    &lpfc_debugfs_op_multixripools);
		if (!phba->debug_multixri_pools) {
		if (IS_ERR(phba->debug_multixri_pools)) {
			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
					 "0527 Cannot create debugfs multixripools\n");
			goto debug_failed;
@@ -6085,7 +6085,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
			debugfs_create_file(name, S_IFREG | 0644,
					    phba->hba_debugfs_root,
					    phba, &lpfc_cgn_buffer_op);
		if (!phba->debug_cgn_buffer) {
		if (IS_ERR(phba->debug_cgn_buffer)) {
			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
					 "6527 Cannot create debugfs "
					 "cgn_buffer\n");
@@ -6098,7 +6098,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
			debugfs_create_file(name, S_IFREG | 0644,
					    phba->hba_debugfs_root,
					    phba, &lpfc_rx_monitor_op);
		if (!phba->debug_rx_monitor) {
		if (IS_ERR(phba->debug_rx_monitor)) {
			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
					 "6528 Cannot create debugfs "
					 "rx_monitor\n");
@@ -6111,7 +6111,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
			debugfs_create_file(name, 0644,
					    phba->hba_debugfs_root,
					    phba, &lpfc_debugfs_ras_log);
		if (!phba->debug_ras_log) {
		if (IS_ERR(phba->debug_ras_log)) {
			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
					 "6148 Cannot create debugfs"
					 " ras_log\n");
@@ -6132,7 +6132,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
			debugfs_create_file(name, S_IFREG | 0644,
					    phba->hba_debugfs_root,
					    phba, &lpfc_debugfs_op_lockstat);
		if (!phba->debug_lockstat) {
		if (IS_ERR(phba->debug_lockstat)) {
			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
					 "4610 Can't create debugfs lockstat\n");
			goto debug_failed;
@@ -6358,7 +6358,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
		debugfs_create_file(name, 0644,
				    vport->vport_debugfs_root,
				    vport, &lpfc_debugfs_op_scsistat);
	if (!vport->debug_scsistat) {
	if (IS_ERR(vport->debug_scsistat)) {
		lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
				 "4611 Cannot create debugfs scsistat\n");
		goto debug_failed;
@@ -6369,7 +6369,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
		debugfs_create_file(name, 0644,
				    vport->vport_debugfs_root,
				    vport, &lpfc_debugfs_op_ioktime);
	if (!vport->debug_ioktime) {
	if (IS_ERR(vport->debug_ioktime)) {
		lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
				 "0815 Cannot create debugfs ioktime\n");
		goto debug_failed;
+3 −2
Original line number Diff line number Diff line
@@ -199,11 +199,12 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
		/* Only 1 thread can drop the initial node reference.  If
		 * another thread has set NLP_DROPPED, this thread is done.
		 */
		if (!(ndlp->nlp_flag & NLP_DROPPED)) {
		if (!(ndlp->fc4_xpt_flags & NVME_XPT_REGD) &&
		    !(ndlp->nlp_flag & NLP_DROPPED)) {
			ndlp->nlp_flag |= NLP_DROPPED;
			spin_unlock_irqrestore(&ndlp->lock, iflags);
			lpfc_nlp_put(ndlp);
			spin_lock_irqsave(&ndlp->lock, iflags);
			return;
		}

		spin_unlock_irqrestore(&ndlp->lock, iflags);
+17 −7
Original line number Diff line number Diff line
@@ -228,8 +228,7 @@ lpfc_nvme_remoteport_delete(struct nvme_fc_remote_port *remoteport)
	spin_unlock_irq(&ndlp->lock);

	/* On a devloss timeout event, one more put is executed provided the
	 * NVME and SCSI rport unregister requests are complete.  If the vport
	 * is unloading, this extra put is executed by lpfc_drop_node.
	 * NVME and SCSI rport unregister requests are complete.
	 */
	if (!(ndlp->fc4_xpt_flags & fc4_xpt_flags))
		lpfc_disc_state_machine(vport, ndlp, NULL, NLP_EVT_DEVICE_RM);
@@ -2567,11 +2566,7 @@ lpfc_nvme_rescan_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
 * nvme_transport perspective.  Loss of an rport just means IO cannot
 * be sent and recovery is completely up to the initator.
 * For now, the driver just unbinds the DID and port_role so that
 * no further IO can be issued.  Changes are planned for later.
 *
 * Notes - the ndlp reference count is not decremented here since
 * since there is no nvme_transport api for devloss.  Node ref count
 * is only adjusted in driver unload.
 * no further IO can be issued.
 */
void
lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
@@ -2646,6 +2641,21 @@ lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
					 "6167 NVME unregister failed %d "
					 "port_state x%x\n",
					 ret, remoteport->port_state);

			if (vport->load_flag & FC_UNLOADING) {
				/* Only 1 thread can drop the initial node
				 * reference. Check if another thread has set
				 * NLP_DROPPED.
				 */
				spin_lock_irq(&ndlp->lock);
				if (!(ndlp->nlp_flag & NLP_DROPPED)) {
					ndlp->nlp_flag |= NLP_DROPPED;
					spin_unlock_irq(&ndlp->lock);
					lpfc_nlp_put(ndlp);
					return;
				}
				spin_unlock_irq(&ndlp->lock);
			}
		}
	}
	return;
+1 −1
Original line number Diff line number Diff line
@@ -2332,7 +2332,7 @@ struct megasas_instance {
	u32 support_morethan256jbod; /* FW support for more than 256 PD/JBOD */
	bool use_seqnum_jbod_fp;   /* Added for PD sequence */
	bool smp_affinity_enable;
	spinlock_t crashdump_lock;
	struct mutex crashdump_lock;

	struct megasas_register_set __iomem *reg_set;
	u32 __iomem *reply_post_host_index_addr[MR_MAX_MSIX_REG_ARRAY];
+9 −12
Original line number Diff line number Diff line
@@ -3271,14 +3271,13 @@ fw_crash_buffer_store(struct device *cdev,
	struct megasas_instance *instance =
		(struct megasas_instance *) shost->hostdata;
	int val = 0;
	unsigned long flags;

	if (kstrtoint(buf, 0, &val) != 0)
		return -EINVAL;

	spin_lock_irqsave(&instance->crashdump_lock, flags);
	mutex_lock(&instance->crashdump_lock);
	instance->fw_crash_buffer_offset = val;
	spin_unlock_irqrestore(&instance->crashdump_lock, flags);
	mutex_unlock(&instance->crashdump_lock);
	return strlen(buf);
}

@@ -3293,24 +3292,23 @@ fw_crash_buffer_show(struct device *cdev,
	unsigned long dmachunk = CRASH_DMA_BUF_SIZE;
	unsigned long chunk_left_bytes;
	unsigned long src_addr;
	unsigned long flags;
	u32 buff_offset;

	spin_lock_irqsave(&instance->crashdump_lock, flags);
	mutex_lock(&instance->crashdump_lock);
	buff_offset = instance->fw_crash_buffer_offset;
	if (!instance->crash_dump_buf ||
		!((instance->fw_crash_state == AVAILABLE) ||
		(instance->fw_crash_state == COPYING))) {
		dev_err(&instance->pdev->dev,
			"Firmware crash dump is not available\n");
		spin_unlock_irqrestore(&instance->crashdump_lock, flags);
		mutex_unlock(&instance->crashdump_lock);
		return -EINVAL;
	}

	if (buff_offset > (instance->fw_crash_buffer_size * dmachunk)) {
		dev_err(&instance->pdev->dev,
			"Firmware crash dump offset is out of range\n");
		spin_unlock_irqrestore(&instance->crashdump_lock, flags);
		mutex_unlock(&instance->crashdump_lock);
		return 0;
	}

@@ -3322,7 +3320,7 @@ fw_crash_buffer_show(struct device *cdev,
	src_addr = (unsigned long)instance->crash_buf[buff_offset / dmachunk] +
		(buff_offset % dmachunk);
	memcpy(buf, (void *)src_addr, size);
	spin_unlock_irqrestore(&instance->crashdump_lock, flags);
	mutex_unlock(&instance->crashdump_lock);

	return size;
}
@@ -3347,7 +3345,6 @@ fw_crash_state_store(struct device *cdev,
	struct megasas_instance *instance =
		(struct megasas_instance *) shost->hostdata;
	int val = 0;
	unsigned long flags;

	if (kstrtoint(buf, 0, &val) != 0)
		return -EINVAL;
@@ -3361,9 +3358,9 @@ fw_crash_state_store(struct device *cdev,
	instance->fw_crash_state = val;

	if ((val == COPIED) || (val == COPY_ERROR)) {
		spin_lock_irqsave(&instance->crashdump_lock, flags);
		mutex_lock(&instance->crashdump_lock);
		megasas_free_host_crash_buffer(instance);
		spin_unlock_irqrestore(&instance->crashdump_lock, flags);
		mutex_unlock(&instance->crashdump_lock);
		if (val == COPY_ERROR)
			dev_info(&instance->pdev->dev, "application failed to "
				"copy Firmware crash dump\n");
@@ -7422,7 +7419,7 @@ static inline void megasas_init_ctrl_params(struct megasas_instance *instance)
	init_waitqueue_head(&instance->int_cmd_wait_q);
	init_waitqueue_head(&instance->abort_cmd_wait_q);

	spin_lock_init(&instance->crashdump_lock);
	mutex_init(&instance->crashdump_lock);
	spin_lock_init(&instance->mfi_pool_lock);
	spin_lock_init(&instance->hba_lock);
	spin_lock_init(&instance->stream_lock);
Loading