Commit 11b00c19 authored by Jeff Skirvin's avatar Jeff Skirvin Committed by Dan Williams
Browse files

isci: Changes in isci_host_completion_routine



Changes to move management of the reqs_in_process entry for the request here.
Made changes to note when the task is already in the abort path and
cannot be completed through callbacks.

Signed-off-by: default avatarJeff Skirvin <jeffrey.d.skirvin@intel.com>
Signed-off-by: default avatarJacek Danecki <Jacek.Danecki@intel.com>
Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent 18d3d72a
Loading
Loading
Loading
Loading
+61 −14
Original line number Diff line number Diff line
@@ -271,7 +271,7 @@ static void isci_host_completion_routine(unsigned long data)
{
	struct isci_host *isci_host = (struct isci_host *)data;
	struct list_head    completed_request_list;
	struct list_head aborted_request_list;
	struct list_head    errored_request_list;
	struct list_head    *current_position;
	struct list_head    *next_position;
	struct isci_request *request;
@@ -279,18 +279,31 @@ static void isci_host_completion_routine(unsigned long data)
	struct sas_task     *task;

	INIT_LIST_HEAD(&completed_request_list);
	INIT_LIST_HEAD(&aborted_request_list);
	INIT_LIST_HEAD(&errored_request_list);

	spin_lock_irq(&isci_host->scic_lock);

	scic_sds_controller_completion_handler(isci_host->core_controller);

	/* Take the lists of completed I/Os from the host. */

	list_splice_init(&isci_host->requests_to_complete,
			 &completed_request_list);

	list_splice_init(&isci_host->requests_to_abort,
			 &aborted_request_list);
	/* While holding the scic_lock take all of the normally completed
	 * I/Os off of the device's pending lists.
	 */
	list_for_each_entry(request, &completed_request_list, completed_node) {

		/* Remove the request from the remote device's list
		* of pending requests.
		*/
		list_del_init(&request->dev_node);
	}

	/* Take the list of errored I/Os from the host. */
	list_splice_init(&isci_host->requests_to_errorback,
			 &errored_request_list);

	spin_unlock_irq(&isci_host->scic_lock);

@@ -309,13 +322,22 @@ static void isci_host_completion_routine(unsigned long data)
			request,
			task);

		task->task_done(task);
		/* Return the task to libsas */
		if (task != NULL) {

			task->lldd_task = NULL;
			if (!(task->task_state_flags & SAS_TASK_STATE_ABORTED)) {

				/* If the task is already in the abort path,
				* the task_done callback cannot be called.
				*/
				task->task_done(task);
			}
		}
		/* Free the request object. */
		isci_request_free(isci_host, request);
	}
	list_for_each_entry_safe(request, next_request, &aborted_request_list,
	list_for_each_entry_safe(request, next_request, &errored_request_list,
				 completed_node) {

		task = isci_request_access_task(request);
@@ -327,8 +349,33 @@ static void isci_host_completion_routine(unsigned long data)
			 request,
			 task);

		/* Put the task into the abort path. */
		if (task != NULL) {

			/* Put the task into the abort path if it's not there
			 * already.
			 */
			if (!(task->task_state_flags & SAS_TASK_STATE_ABORTED))
				sas_task_abort(task);

		} else {
			/* This is a case where the request has completed with a
			 * status such that it needed further target servicing,
			 * but the sas_task reference has already been removed
			 * from the request.  Since it was errored, it was not
			 * being aborted, so there is nothing to do except free
			 * it.
			 */

			spin_lock_irq(&isci_host->scic_lock);
			/* Remove the request from the remote device's list
			* of pending requests.
			*/
			list_del_init(&request->dev_node);
			spin_unlock_irq(&isci_host->scic_lock);

			/* Free the request object. */
			isci_request_free(isci_host, request);
		}
	}

}
@@ -477,7 +524,7 @@ int isci_host_init(struct isci_host *isci_host)
	INIT_LIST_HEAD(&(isci_host->mdl_struct_list));

	INIT_LIST_HEAD(&isci_host->requests_to_complete);
	INIT_LIST_HEAD(&isci_host->requests_to_abort);
	INIT_LIST_HEAD(&isci_host->requests_to_errorback);

	spin_lock_irq(&isci_host->scic_lock);
	status = scic_controller_initialize(isci_host->core_controller);
+1 −1
Original line number Diff line number Diff line
@@ -116,7 +116,7 @@ struct isci_host {
	struct tasklet_struct completion_tasklet;
	struct list_head mdl_struct_list;
	struct list_head requests_to_complete;
	struct list_head requests_to_abort;
	struct list_head requests_to_errorback;
	spinlock_t scic_lock;

	/* careful only access this via idev_by_id */
+2 −10
Original line number Diff line number Diff line
@@ -836,7 +836,7 @@ static void isci_task_save_for_upper_layer_completion(
			 status);
		/* Add to the aborted list. */
		list_add(&request->completed_node,
			 &host->requests_to_abort);
			 &host->requests_to_errorback);
		break;

	default:
@@ -849,7 +849,7 @@ static void isci_task_save_for_upper_layer_completion(

		/* Add to the aborted list. */
		list_add(&request->completed_node,
			 &host->requests_to_abort);
			 &host->requests_to_errorback);
		break;
	}
}
@@ -1185,14 +1185,6 @@ void isci_request_io_request_complete(
	 */
	request->sci_request_handle = NULL;

	/* Only remove the request from the remote device list
	 * of pending requests if we have not requested error
	 * handling on this request.
	 */
	if (complete_to_host != isci_perform_error_io_completion)
		list_del_init(&request->dev_node);


	/* Save possible completion ptr. */
	io_request_completion = request->io_request_completion;