Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1fa8109f authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull SCSI fixes from James Bottomley:
 "Six fixes to four drivers and two core fixes.

  One core fix simply corrects a missed destroy_rcu_head() but the other
  is hopefully the end of an ongoing effort to make suspend/resume play
  nicely with scsi quiesce"

* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
  scsi: ibmvscsi: Fix empty event pool access during host removal
  scsi: ibmvscsi: Protect ibmvscsi_head from concurrent modificaiton
  scsi: hisi_sas: Add softreset in hisi_sas_I_T_nexus_reset()
  scsi: qla2xxx: Fix NULL pointer crash due to stale CPUID
  scsi: qla2xxx: Fix FC-AL connection target discovery
  scsi: core: Avoid that a kernel warning appears during system resume
  scsi: core: Also call destroy_rcu_head() for passthrough requests
  scsi: iscsi: flush running unbind operations when removing a session
parents 1bdd3dbf 7f5203c1
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -1801,6 +1801,12 @@ static int hisi_sas_I_T_nexus_reset(struct domain_device *device)
	}
	hisi_sas_dereg_device(hisi_hba, device);

	if (dev_is_sata(device)) {
		rc = hisi_sas_softreset_ata_disk(device);
		if (rc)
			return TMF_RESP_FUNC_FAILED;
	}

	rc = hisi_sas_debug_I_T_nexus_reset(device);

	if ((rc == TMF_RESP_FUNC_COMPLETE) || (rc == -ENODEV))
+19 −4
Original line number Diff line number Diff line
@@ -96,6 +96,7 @@ static int client_reserve = 1;
static char partition_name[96] = "UNKNOWN";
static unsigned int partition_number = -1;
static LIST_HEAD(ibmvscsi_head);
static DEFINE_SPINLOCK(ibmvscsi_driver_lock);

static struct scsi_transport_template *ibmvscsi_transport_template;

@@ -2270,7 +2271,9 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id)
	}

	dev_set_drvdata(&vdev->dev, hostdata);
	spin_lock(&ibmvscsi_driver_lock);
	list_add_tail(&hostdata->host_list, &ibmvscsi_head);
	spin_unlock(&ibmvscsi_driver_lock);
	return 0;

      add_srp_port_failed:
@@ -2292,15 +2295,27 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id)
static int ibmvscsi_remove(struct vio_dev *vdev)
{
	struct ibmvscsi_host_data *hostdata = dev_get_drvdata(&vdev->dev);
	list_del(&hostdata->host_list);
	unmap_persist_bufs(hostdata);
	unsigned long flags;

	srp_remove_host(hostdata->host);
	scsi_remove_host(hostdata->host);

	purge_requests(hostdata, DID_ERROR);

	spin_lock_irqsave(hostdata->host->host_lock, flags);
	release_event_pool(&hostdata->pool, hostdata);
	spin_unlock_irqrestore(hostdata->host->host_lock, flags);

	ibmvscsi_release_crq_queue(&hostdata->queue, hostdata,
					max_events);

	kthread_stop(hostdata->work_thread);
	srp_remove_host(hostdata->host);
	scsi_remove_host(hostdata->host);
	unmap_persist_bufs(hostdata);

	spin_lock(&ibmvscsi_driver_lock);
	list_del(&hostdata->host_list);
	spin_unlock(&ibmvscsi_driver_lock);

	scsi_host_put(hostdata->host);

	return 0;
+7 −0
Original line number Diff line number Diff line
@@ -4991,6 +4991,13 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
		if ((domain & 0xf0) == 0xf0)
			continue;

		/* Bypass if not same domain and area of adapter. */
		if (area && domain && ((area != vha->d_id.b.area) ||
		    (domain != vha->d_id.b.domain)) &&
		    (ha->current_topology == ISP_CFG_NL))
			continue;


		/* Bypass invalid local loop ID. */
		if (loop_id > LAST_LOCAL_LOOP_ID)
			continue;
+1 −1
Original line number Diff line number Diff line
@@ -1517,7 +1517,7 @@ __qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type,
		goto eh_reset_failed;
	}
	err = 2;
	if (do_reset(fcport, cmd->device->lun, blk_mq_rq_cpu(cmd->request) + 1)
	if (do_reset(fcport, cmd->device->lun, 1)
		!= QLA_SUCCESS) {
		ql_log(ql_log_warn, vha, 0x800c,
		    "do_reset failed for cmd=%p.\n", cmd);
+12 −3
Original line number Diff line number Diff line
@@ -585,9 +585,16 @@ static bool scsi_end_request(struct request *req, blk_status_t error,
	if (!blk_rq_is_scsi(req)) {
		WARN_ON_ONCE(!(cmd->flags & SCMD_INITIALIZED));
		cmd->flags &= ~SCMD_INITIALIZED;
		destroy_rcu_head(&cmd->rcu);
	}

	/*
	 * Calling rcu_barrier() is not necessary here because the
	 * SCSI error handler guarantees that the function called by
	 * call_rcu() has been called before scsi_end_request() is
	 * called.
	 */
	destroy_rcu_head(&cmd->rcu);

	/*
	 * In the MQ case the command gets freed by __blk_mq_end_request,
	 * so we have to do all cleanup that depends on it earlier.
@@ -2541,8 +2548,10 @@ void scsi_device_resume(struct scsi_device *sdev)
	 * device deleted during suspend)
	 */
	mutex_lock(&sdev->state_mutex);
	if (sdev->quiesced_by) {
		sdev->quiesced_by = NULL;
		blk_clear_pm_only(sdev->request_queue);
	}
	if (sdev->sdev_state == SDEV_QUIESCE)
		scsi_device_set_state(sdev, SDEV_RUNNING);
	mutex_unlock(&sdev->state_mutex);
Loading