Commit 556666bc authored by Martin K. Petersen's avatar Martin K. Petersen
Browse files

Merge branch '5.12/scsi-fixes' into 5.13/scsi-staging



Pull 5.12/scsi-fixes into the 5.13 SCSI tree to provide a baseline for
some UFS changes that would otherwise cause conflicts during the
merge.

Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parents 4e2e619f 9e67600e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -19165,7 +19165,7 @@ S: Maintained
F:	drivers/infiniband/hw/vmw_pvrdma/
VMware PVSCSI driver
M:	Jim Gill <jgill@vmware.com>
M:	Vishal Bhakta <vbhakta@vmware.com>
M:	VMware PV-Drivers <pv-drivers@vmware.com>
L:	linux-scsi@vger.kernel.org
S:	Maintained
+92 −39
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include <linux/bsg-lib.h>
#include <asm/firmware.h>
#include <asm/irq.h>
#include <asm/rtas.h>
#include <asm/vio.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
@@ -158,6 +159,9 @@ static void ibmvfc_npiv_logout(struct ibmvfc_host *);
static void ibmvfc_tgt_implicit_logout_and_del(struct ibmvfc_target *);
static void ibmvfc_tgt_move_login(struct ibmvfc_target *);

static void ibmvfc_release_sub_crqs(struct ibmvfc_host *);
static void ibmvfc_init_sub_crqs(struct ibmvfc_host *);

static const char *unknown_error = "unknown error";

static long h_reg_sub_crq(unsigned long unit_address, unsigned long ioba,
@@ -901,6 +905,9 @@ static int ibmvfc_reenable_crq_queue(struct ibmvfc_host *vhost)
{
	int rc = 0;
	struct vio_dev *vdev = to_vio_dev(vhost->dev);
	unsigned long flags;

	ibmvfc_release_sub_crqs(vhost);

	/* Re-enable the CRQ */
	do {
@@ -912,6 +919,15 @@ static int ibmvfc_reenable_crq_queue(struct ibmvfc_host *vhost)
	if (rc)
		dev_err(vhost->dev, "Error enabling adapter (rc=%d)\n", rc);

	spin_lock_irqsave(vhost->host->host_lock, flags);
	spin_lock(vhost->crq.q_lock);
	vhost->do_enquiry = 1;
	vhost->using_channels = 0;
	spin_unlock(vhost->crq.q_lock);
	spin_unlock_irqrestore(vhost->host->host_lock, flags);

	ibmvfc_init_sub_crqs(vhost);

	return rc;
}

@@ -928,8 +944,8 @@ static int ibmvfc_reset_crq(struct ibmvfc_host *vhost)
	unsigned long flags;
	struct vio_dev *vdev = to_vio_dev(vhost->dev);
	struct ibmvfc_queue *crq = &vhost->crq;
	struct ibmvfc_queue *scrq;
	int i;

	ibmvfc_release_sub_crqs(vhost);

	/* Close the CRQ */
	do {
@@ -949,16 +965,6 @@ static int ibmvfc_reset_crq(struct ibmvfc_host *vhost)
	memset(crq->msgs.crq, 0, PAGE_SIZE);
	crq->cur = 0;

	if (vhost->scsi_scrqs.scrqs) {
		for (i = 0; i < nr_scsi_hw_queues; i++) {
			scrq = &vhost->scsi_scrqs.scrqs[i];
			spin_lock(scrq->q_lock);
			memset(scrq->msgs.scrq, 0, PAGE_SIZE);
			scrq->cur = 0;
			spin_unlock(scrq->q_lock);
		}
	}

	/* And re-open it again */
	rc = plpar_hcall_norets(H_REG_CRQ, vdev->unit_address,
				crq->msg_token, PAGE_SIZE);
@@ -968,9 +974,12 @@ static int ibmvfc_reset_crq(struct ibmvfc_host *vhost)
		dev_warn(vhost->dev, "Partner adapter not ready\n");
	else if (rc != 0)
		dev_warn(vhost->dev, "Couldn't register crq (rc=%d)\n", rc);

	spin_unlock(vhost->crq.q_lock);
	spin_unlock_irqrestore(vhost->host->host_lock, flags);

	ibmvfc_init_sub_crqs(vhost);

	return rc;
}

@@ -2365,6 +2374,24 @@ static int ibmvfc_match_lun(struct ibmvfc_event *evt, void *device)
	return 0;
}

/**
 * ibmvfc_event_is_free - Check if event is free or not
 * @evt:	ibmvfc event struct
 *
 * Returns:
 *	true / false
 **/
static bool ibmvfc_event_is_free(struct ibmvfc_event *evt)
{
	struct ibmvfc_event *loop_evt;

	list_for_each_entry(loop_evt, &evt->queue->free, queue_list)
		if (loop_evt == evt)
			return true;

	return false;
}

/**
 * ibmvfc_wait_for_ops - Wait for ops to complete
 * @vhost:	ibmvfc host struct
@@ -2379,35 +2406,58 @@ static int ibmvfc_wait_for_ops(struct ibmvfc_host *vhost, void *device,
{
	struct ibmvfc_event *evt;
	DECLARE_COMPLETION_ONSTACK(comp);
	int wait;
	int wait, i, q_index, q_size;
	unsigned long flags;
	signed long timeout = IBMVFC_ABORT_WAIT_TIMEOUT * HZ;
	struct ibmvfc_queue *queues;

	ENTER;
	if (vhost->mq_enabled && vhost->using_channels) {
		queues = vhost->scsi_scrqs.scrqs;
		q_size = vhost->scsi_scrqs.active_queues;
	} else {
		queues = &vhost->crq;
		q_size = 1;
	}

	do {
		wait = 0;
		spin_lock_irqsave(&vhost->crq.l_lock, flags);
		list_for_each_entry(evt, &vhost->crq.sent, queue_list) {
		spin_lock_irqsave(vhost->host->host_lock, flags);
		for (q_index = 0; q_index < q_size; q_index++) {
			spin_lock(&queues[q_index].l_lock);
			for (i = 0; i < queues[q_index].evt_pool.size; i++) {
				evt = &queues[q_index].evt_pool.events[i];
				if (!ibmvfc_event_is_free(evt)) {
					if (match(evt, device)) {
						evt->eh_comp = &comp;
						wait++;
					}
				}
		spin_unlock_irqrestore(&vhost->crq.l_lock, flags);
			}
			spin_unlock(&queues[q_index].l_lock);
		}
		spin_unlock_irqrestore(vhost->host->host_lock, flags);

		if (wait) {
			timeout = wait_for_completion_timeout(&comp, timeout);

			if (!timeout) {
				wait = 0;
				spin_lock_irqsave(&vhost->crq.l_lock, flags);
				list_for_each_entry(evt, &vhost->crq.sent, queue_list) {
				spin_lock_irqsave(vhost->host->host_lock, flags);
				for (q_index = 0; q_index < q_size; q_index++) {
					spin_lock(&queues[q_index].l_lock);
					for (i = 0; i < queues[q_index].evt_pool.size; i++) {
						evt = &queues[q_index].evt_pool.events[i];
						if (!ibmvfc_event_is_free(evt)) {
							if (match(evt, device)) {
								evt->eh_comp = NULL;
								wait++;
							}
						}
				spin_unlock_irqrestore(&vhost->crq.l_lock, flags);
					}
					spin_unlock(&queues[q_index].l_lock);
				}
				spin_unlock_irqrestore(vhost->host->host_lock, flags);
				if (wait)
					dev_err(vhost->dev, "Timed out waiting for aborted commands\n");
				LEAVE;
@@ -5649,7 +5699,8 @@ static int ibmvfc_register_scsi_channel(struct ibmvfc_host *vhost,
	rc = h_reg_sub_crq(vdev->unit_address, scrq->msg_token, PAGE_SIZE,
			   &scrq->cookie, &scrq->hw_irq);

	if (rc) {
	/* H_CLOSED indicates successful register, but no CRQ partner */
	if (rc && rc != H_CLOSED) {
		dev_warn(dev, "Error registering sub-crq: %d\n", rc);
		if (rc == H_PARAMETER)
			dev_warn_once(dev, "Firmware may not support MQ\n");
@@ -5682,8 +5733,8 @@ static int ibmvfc_register_scsi_channel(struct ibmvfc_host *vhost,

irq_failed:
	do {
		plpar_hcall_norets(H_FREE_SUB_CRQ, vdev->unit_address, scrq->cookie);
	} while (rc == H_BUSY || H_IS_LONG_BUSY(rc));
		rc = plpar_hcall_norets(H_FREE_SUB_CRQ, vdev->unit_address, scrq->cookie);
	} while (rtas_busy_delay(rc));
reg_failed:
	ibmvfc_free_queue(vhost, scrq);
	LEAVE;
@@ -5701,6 +5752,7 @@ static void ibmvfc_deregister_scsi_channel(struct ibmvfc_host *vhost, int index)

	free_irq(scrq->irq, scrq);
	irq_dispose_mapping(scrq->irq);
	scrq->irq = 0;

	do {
		rc = plpar_hcall_norets(H_FREE_SUB_CRQ, vdev->unit_address,
@@ -5714,17 +5766,21 @@ static void ibmvfc_deregister_scsi_channel(struct ibmvfc_host *vhost, int index)
	LEAVE;
}

static int ibmvfc_init_sub_crqs(struct ibmvfc_host *vhost)
static void ibmvfc_init_sub_crqs(struct ibmvfc_host *vhost)
{
	int i, j;

	ENTER;
	if (!vhost->mq_enabled)
		return;

	vhost->scsi_scrqs.scrqs = kcalloc(nr_scsi_hw_queues,
					  sizeof(*vhost->scsi_scrqs.scrqs),
					  GFP_KERNEL);
	if (!vhost->scsi_scrqs.scrqs)
		return -1;
	if (!vhost->scsi_scrqs.scrqs) {
		vhost->do_enquiry = 0;
		return;
	}

	for (i = 0; i < nr_scsi_hw_queues; i++) {
		if (ibmvfc_register_scsi_channel(vhost, i)) {
@@ -5733,13 +5789,12 @@ static int ibmvfc_init_sub_crqs(struct ibmvfc_host *vhost)
			kfree(vhost->scsi_scrqs.scrqs);
			vhost->scsi_scrqs.scrqs = NULL;
			vhost->scsi_scrqs.active_queues = 0;
			LEAVE;
			return -1;
			vhost->do_enquiry = 0;
			break;
		}
	}

	LEAVE;
	return 0;
}

static void ibmvfc_release_sub_crqs(struct ibmvfc_host *vhost)
@@ -5777,6 +5832,8 @@ static void ibmvfc_free_mem(struct ibmvfc_host *vhost)
			  vhost->disc_buf_dma);
	dma_free_coherent(vhost->dev, sizeof(*vhost->login_buf),
			  vhost->login_buf, vhost->login_buf_dma);
	dma_free_coherent(vhost->dev, sizeof(*vhost->channel_setup_buf),
			  vhost->channel_setup_buf, vhost->channel_setup_dma);
	dma_pool_destroy(vhost->sg_pool);
	ibmvfc_free_queue(vhost, async_q);
	LEAVE;
@@ -6006,11 +6063,7 @@ static int ibmvfc_probe(struct vio_dev *vdev, const struct vio_device_id *id)
		goto remove_shost;
	}

	if (vhost->mq_enabled) {
		rc = ibmvfc_init_sub_crqs(vhost);
		if (rc)
			dev_warn(dev, "Failed to allocate Sub-CRQs. rc=%d\n", rc);
	}
	ibmvfc_init_sub_crqs(vhost);

	if (shost_to_fc_host(shost)->rqst_q)
		blk_queue_max_segments(shost_to_fc_host(shost)->rqst_q, 1);
+2 −2
Original line number Diff line number Diff line
@@ -2424,7 +2424,7 @@ lpfc_debugfs_dif_err_write(struct file *file, const char __user *buf,
	memset(dstbuf, 0, 33);
	size = (nbytes < 32) ? nbytes : 32;
	if (copy_from_user(dstbuf, buf, size))
		return 0;
		return -EFAULT;

	if (dent == phba->debug_InjErrLBA) {
		if ((dstbuf[0] == 'o') && (dstbuf[1] == 'f') &&
@@ -2433,7 +2433,7 @@ lpfc_debugfs_dif_err_write(struct file *file, const char __user *buf,
	}

	if ((tmp == 0) && (kstrtoull(dstbuf, 0, &tmp)))
		return 0;
		return -EINVAL;

	if (dent == phba->debug_writeGuard)
		phba->lpfc_injerr_wgrd_cnt = (uint32_t)tmp;
+6 −2
Original line number Diff line number Diff line
@@ -7960,14 +7960,18 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
		ioc->pend_os_device_add_sz++;
	ioc->pend_os_device_add = kzalloc(ioc->pend_os_device_add_sz,
	    GFP_KERNEL);
	if (!ioc->pend_os_device_add)
	if (!ioc->pend_os_device_add) {
		r = -ENOMEM;
		goto out_free_resources;
	}

	ioc->device_remove_in_progress_sz = ioc->pend_os_device_add_sz;
	ioc->device_remove_in_progress =
		kzalloc(ioc->device_remove_in_progress_sz, GFP_KERNEL);
	if (!ioc->device_remove_in_progress)
	if (!ioc->device_remove_in_progress) {
		r = -ENOMEM;
		goto out_free_resources;
	}

	ioc->fwfault_debug = mpt3sas_fwfault_debug;

+1 −1
Original line number Diff line number Diff line
@@ -413,7 +413,7 @@ mpt3sas_get_port_by_id(struct MPT3SAS_ADAPTER *ioc,
	 * And add this object to port_table_list.
	 */
	if (!ioc->multipath_on_hba) {
		port = kzalloc(sizeof(struct hba_port), GFP_KERNEL);
		port = kzalloc(sizeof(struct hba_port), GFP_ATOMIC);
		if (!port)
			return NULL;

Loading