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

Commit b68bf096 authored by Kashyap, Desai's avatar Kashyap, Desai Committed by James Bottomley
Browse files

[SCSI] mptfusion: schedule_target_reset from all Reset context



Issue:
target reset will be queued to driver's internal queue to get schedule
later. When driver add target into internal target_reset queue we will block IOs
on those target using scsi midlayer API. Now due to some cause driver is not
executing those target_reset list and it is always in block state.

Changes:
now we are clearing target_reset queue from all other Callback context
instead of only DeviceReset context.Now wherever driver is clearing
taskmgmt_in_progress flag it is considering target_reset queue cleanup
also.

Signed-off-by: default avatarKashyap Desai <kashyap.desai@lsi.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent 51106ab5
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -580,6 +580,7 @@ struct mptfc_rport_info
typedef void (*MPT_ADD_SGE)(void *pAddr, u32 flagslength, dma_addr_t dma_addr);
typedef void (*MPT_ADD_CHAIN)(void *pAddr, u8 next, u16 length,
		dma_addr_t dma_addr);
typedef void (*MPT_SCHEDULE_TARGET_RESET)(void *ioc);

/*
 *  Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS
@@ -738,6 +739,7 @@ typedef struct _MPT_ADAPTER
	int			 taskmgmt_in_progress;
	u8			 taskmgmt_quiesce_io;
	u8			 ioc_reset_in_progress;
	MPT_SCHEDULE_TARGET_RESET schedule_target_reset;
	struct work_struct	 sas_persist_task;

	struct work_struct	 fc_setup_reset_work;
+11 −3
Original line number Diff line number Diff line
@@ -261,10 +261,16 @@ mptctl_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
	/* We are done, issue wake up
	 */
	if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_PENDING) {
		if (req->u.hdr.Function == MPI_FUNCTION_SCSI_TASK_MGMT)
		if (req->u.hdr.Function == MPI_FUNCTION_SCSI_TASK_MGMT) {
			mpt_clear_taskmgmt_in_progress_flag(ioc);
			ioc->ioctl_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
			complete(&ioc->ioctl_cmds.done);
			if (ioc->bus_type == SAS)
				ioc->schedule_target_reset(ioc);
		} else {
			ioc->ioctl_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
			complete(&ioc->ioctl_cmds.done);
		}
	}

 out_continuation:
@@ -298,6 +304,8 @@ mptctl_taskmgmt_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
		mpt_clear_taskmgmt_in_progress_flag(ioc);
		ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
		complete(&ioc->taskmgmt_cmds.done);
		if (ioc->bus_type == SAS)
			ioc->schedule_target_reset(ioc);
		return 1;
	}
	return 0;
+41 −18
Original line number Diff line number Diff line
@@ -126,6 +126,7 @@ static void mptsas_scan_sas_topology(MPT_ADAPTER *ioc);
static void mptsas_broadcast_primative_work(struct fw_event_work *fw_event);
static void mptsas_handle_queue_full_event(struct fw_event_work *fw_event);
static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id);
void	mptsas_schedule_target_reset(void *ioc);

static void mptsas_print_phy_data(MPT_ADAPTER *ioc,
					MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
@@ -1138,6 +1139,44 @@ mptsas_target_reset_queue(MPT_ADAPTER *ioc,
	}
}

/**
 * mptsas_schedule_target_reset- send pending target reset
 * @iocp: per adapter object
 *
 * This function will delete scheduled target reset from the list and
 * try to send next target reset. This will be called from completion
 * context of any Task managment command.
 */

void
mptsas_schedule_target_reset(void *iocp)
{
	MPT_ADAPTER *ioc = (MPT_ADAPTER *)(iocp);
	MPT_SCSI_HOST	*hd = shost_priv(ioc->sh);
	struct list_head *head = &hd->target_reset_list;
	struct mptsas_target_reset_event	*target_reset_list;
	u8		id, channel;
	/*
	 * issue target reset to next device in the queue
	 */

	head = &hd->target_reset_list;
	if (list_empty(head))
		return;

	target_reset_list = list_entry(head->next,
		struct mptsas_target_reset_event, list);

	id = target_reset_list->sas_event_data.TargetID;
	channel = target_reset_list->sas_event_data.Bus;
	target_reset_list->time_count = jiffies;

	if (mptsas_target_reset(ioc, channel, id))
		target_reset_list->target_reset_issued = 1;
	return;
}


/**
 *	mptsas_taskmgmt_complete - complete SAS task management function
 *	@ioc: Pointer to MPT_ADAPTER structure
@@ -1227,23 +1266,7 @@ mptsas_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
			&target_reset_list->sas_event_data);


	/*
	 * issue target reset to next device in the queue
	 */

	head = &hd->target_reset_list;
	if (list_empty(head))
		return 1;

	target_reset_list = list_entry(head->next, struct mptsas_target_reset_event,
	    list);

	id = target_reset_list->sas_event_data.TargetID;
	channel = target_reset_list->sas_event_data.Bus;
	target_reset_list->time_count = jiffies;

	if (mptsas_target_reset(ioc, channel, id))
		target_reset_list->target_reset_issued = 1;
	ioc->schedule_target_reset(ioc);

	return 1;
}
@@ -4961,7 +4984,7 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
	ioc->DoneCtx = mptsasDoneCtx;
	ioc->TaskCtx = mptsasTaskCtx;
	ioc->InternalCtx = mptsasInternalCtx;

	ioc->schedule_target_reset = &mptsas_schedule_target_reset;
	/*  Added sanity check on readiness of the MPT adapter.
	 */
	if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
+2 −0
Original line number Diff line number Diff line
@@ -2134,6 +2134,8 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf,
		mpt_clear_taskmgmt_in_progress_flag(ioc);
		ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
		complete(&ioc->taskmgmt_cmds.done);
		if (ioc->bus_type == SAS)
			ioc->schedule_target_reset(ioc);
		return 1;
	}
	return 0;