Commit e140f731 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull more SCSI updates from James Bottomley:
 "Mostly small bug fixes and trivial updates.

  The major new core update is a change to the way device, target and
  host reference counting is done to try to make it more robust (this
  change has soaked for a while to try to winkle out any bugs)"

* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
  scsi: pm8001: Fix typo 'the the' in comment
  scsi: megaraid_sas: Remove redundant variable cmd_type
  scsi: FlashPoint: Remove redundant variable bm_int_st
  scsi: zfcp: Fix missing auto port scan and thus missing target ports
  scsi: core: Call blk_mq_free_tag_set() earlier
  scsi: core: Simplify LLD module reference counting
  scsi: core: Make sure that hosts outlive targets
  scsi: core: Make sure that targets outlive devices
  scsi: ufs: ufs-pci: Correct check for RESET DSM
  scsi: target: core: De-RCU of se_lun and se_lun acl
  scsi: target: core: Fix race during ACL removal
  scsi: ufs: core: Correct ufshcd_shutdown() flow
  scsi: ufs: core: Increase the maximum data buffer size
  scsi: lpfc: Check the return value of alloc_workqueue()
parents abe7a481 c6380f99
Loading
Loading
Loading
Loading
+20 −9
Original line number Diff line number Diff line
@@ -145,27 +145,33 @@ void zfcp_fc_enqueue_event(struct zfcp_adapter *adapter,

static int zfcp_fc_wka_port_get(struct zfcp_fc_wka_port *wka_port)
{
	int ret = -EIO;

	if (mutex_lock_interruptible(&wka_port->mutex))
		return -ERESTARTSYS;

	if (wka_port->status == ZFCP_FC_WKA_PORT_OFFLINE ||
	    wka_port->status == ZFCP_FC_WKA_PORT_CLOSING) {
		wka_port->status = ZFCP_FC_WKA_PORT_OPENING;
		if (zfcp_fsf_open_wka_port(wka_port))
		if (zfcp_fsf_open_wka_port(wka_port)) {
			/* could not even send request, nothing to wait for */
			wka_port->status = ZFCP_FC_WKA_PORT_OFFLINE;
			goto out;
		}
	}

	mutex_unlock(&wka_port->mutex);

	wait_event(wka_port->completion_wq,
	wait_event(wka_port->opened,
		   wka_port->status == ZFCP_FC_WKA_PORT_ONLINE ||
		   wka_port->status == ZFCP_FC_WKA_PORT_OFFLINE);

	if (wka_port->status == ZFCP_FC_WKA_PORT_ONLINE) {
		atomic_inc(&wka_port->refcount);
		return 0;
		ret = 0;
		goto out;
	}
	return -EIO;
out:
	mutex_unlock(&wka_port->mutex);
	return ret;
}

static void zfcp_fc_wka_port_offline(struct work_struct *work)
@@ -181,9 +187,12 @@ static void zfcp_fc_wka_port_offline(struct work_struct *work)

	wka_port->status = ZFCP_FC_WKA_PORT_CLOSING;
	if (zfcp_fsf_close_wka_port(wka_port)) {
		/* could not even send request, nothing to wait for */
		wka_port->status = ZFCP_FC_WKA_PORT_OFFLINE;
		wake_up(&wka_port->completion_wq);
		goto out;
	}
	wait_event(wka_port->closed,
		   wka_port->status == ZFCP_FC_WKA_PORT_OFFLINE);
out:
	mutex_unlock(&wka_port->mutex);
}
@@ -193,13 +202,15 @@ static void zfcp_fc_wka_port_put(struct zfcp_fc_wka_port *wka_port)
	if (atomic_dec_return(&wka_port->refcount) != 0)
		return;
	/* wait 10 milliseconds, other reqs might pop in */
	schedule_delayed_work(&wka_port->work, HZ / 100);
	queue_delayed_work(wka_port->adapter->work_queue, &wka_port->work,
			   msecs_to_jiffies(10));
}

static void zfcp_fc_wka_port_init(struct zfcp_fc_wka_port *wka_port, u32 d_id,
				  struct zfcp_adapter *adapter)
{
	init_waitqueue_head(&wka_port->completion_wq);
	init_waitqueue_head(&wka_port->opened);
	init_waitqueue_head(&wka_port->closed);

	wka_port->adapter = adapter;
	wka_port->d_id = d_id;
+4 −2
Original line number Diff line number Diff line
@@ -185,7 +185,8 @@ enum zfcp_fc_wka_status {
/**
 * struct zfcp_fc_wka_port - representation of well-known-address (WKA) FC port
 * @adapter: Pointer to adapter structure this WKA port belongs to
 * @completion_wq: Wait for completion of open/close command
 * @opened: Wait for completion of open command
 * @closed: Wait for completion of close command
 * @status: Current status of WKA port
 * @refcount: Reference count to keep port open as long as it is in use
 * @d_id: FC destination id or well-known-address
@@ -195,7 +196,8 @@ enum zfcp_fc_wka_status {
 */
struct zfcp_fc_wka_port {
	struct zfcp_adapter	*adapter;
	wait_queue_head_t	completion_wq;
	wait_queue_head_t	opened;
	wait_queue_head_t	closed;
	enum zfcp_fc_wka_status	status;
	atomic_t		refcount;
	u32			d_id;
+2 −2
Original line number Diff line number Diff line
@@ -1907,7 +1907,7 @@ static void zfcp_fsf_open_wka_port_handler(struct zfcp_fsf_req *req)
		wka_port->status = ZFCP_FC_WKA_PORT_ONLINE;
	}
out:
	wake_up(&wka_port->completion_wq);
	wake_up(&wka_port->opened);
}

/**
@@ -1966,7 +1966,7 @@ static void zfcp_fsf_close_wka_port_handler(struct zfcp_fsf_req *req)
	}

	wka_port->status = ZFCP_FC_WKA_PORT_OFFLINE;
	wake_up(&wka_port->completion_wq);
	wake_up(&wka_port->closed);
}

/**
+2 −2
Original line number Diff line number Diff line
@@ -1712,7 +1712,7 @@ static unsigned char FlashPoint_InterruptPending(void *pCurrCard)
static int FlashPoint_HandleInterrupt(void *pcard)
{
	struct sccb *currSCCB;
	unsigned char thisCard, result, bm_status, bm_int_st;
	unsigned char thisCard, result, bm_status;
	unsigned short hp_int;
	unsigned char i, target;
	struct sccb_card *pCurrCard = pcard;
@@ -1723,7 +1723,7 @@ static int FlashPoint_HandleInterrupt(void *pcard)

	MDISABLE_INT(ioport);

	if ((bm_int_st = RD_HARPOON(ioport + hp_int_status)) & EXT_STATUS_ON)
	if (RD_HARPOON(ioport + hp_int_status) & EXT_STATUS_ON)
		bm_status = RD_HARPOON(ioport + hp_ext_status) &
					(unsigned char)BAD_EXT_STATUS;
	else
+13 −5
Original line number Diff line number Diff line
@@ -190,6 +190,15 @@ void scsi_remove_host(struct Scsi_Host *shost)
	transport_unregister_device(&shost->shost_gendev);
	device_unregister(&shost->shost_dev);
	device_del(&shost->shost_gendev);

	/*
	 * After scsi_remove_host() has returned the scsi LLD module can be
	 * unloaded and/or the host resources can be released. Hence wait until
	 * the dependent SCSI targets and devices are gone before returning.
	 */
	wait_event(shost->targets_wq, atomic_read(&shost->target_count) == 0);

	scsi_mq_destroy_tags(shost);
}
EXPORT_SYMBOL(scsi_remove_host);

@@ -300,8 +309,8 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev,
	return error;

	/*
	 * Any host allocation in this function will be freed in
	 * scsi_host_dev_release().
	 * Any resources associated with the SCSI host in this function except
	 * the tag set will be freed by scsi_host_dev_release().
	 */
 out_del_dev:
	device_del(&shost->shost_dev);
@@ -317,6 +326,7 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev,
	pm_runtime_disable(&shost->shost_gendev);
	pm_runtime_set_suspended(&shost->shost_gendev);
	pm_runtime_put_noidle(&shost->shost_gendev);
	scsi_mq_destroy_tags(shost);
 fail:
	return error;
}
@@ -350,9 +360,6 @@ static void scsi_host_dev_release(struct device *dev)
		kfree(dev_name(&shost->shost_dev));
	}

	if (shost->tag_set.tags)
		scsi_mq_destroy_tags(shost);

	kfree(shost->shost_data);

	ida_free(&host_index_ida, shost->host_no);
@@ -399,6 +406,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
	INIT_LIST_HEAD(&shost->starved_list);
	init_waitqueue_head(&shost->host_wait);
	mutex_init(&shost->scan_mutex);
	init_waitqueue_head(&shost->targets_wq);

	index = ida_alloc(&host_index_ida, GFP_KERNEL);
	if (index < 0) {
Loading