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

Commit 14aaa9f0 authored by Jeff Skirvin's avatar Jeff Skirvin Committed by Dan Williams
Browse files

isci: Redesign device suspension, abort, cleanup.



This commit changes the means by which outstanding I/Os are handled
for cleanup.
The likelihood is that this commit will be broken into smaller pieces,
however that will be a later revision.  Among the changes:

- All completion structures have been removed from the tmf and
abort paths.
- Now using one completed I/O list, with the I/O completed in host bit being
used to select error or normal callback paths.

Signed-off-by: default avatarJeff Skirvin <jeffrey.d.skirvin@intel.com>
Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent d80ecd57
Loading
Loading
Loading
Loading
+26 −60
Original line number Original line Diff line number Diff line
@@ -1089,33 +1089,25 @@ void isci_host_completion_routine(unsigned long data)
{
{
	struct isci_host *ihost = (struct isci_host *)data;
	struct isci_host *ihost = (struct isci_host *)data;
	struct list_head    completed_request_list;
	struct list_head    completed_request_list;
	struct list_head    errored_request_list;
	struct list_head    *current_position;
	struct list_head    *current_position;
	struct list_head    *next_position;
	struct list_head    *next_position;
	struct isci_request *request;
	struct isci_request *request;
	struct isci_request *next_request;
	struct sas_task     *task;
	struct sas_task     *task;
	u16 active;
	u16 active;


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


	spin_lock_irq(&ihost->scic_lock);
	spin_lock_irq(&ihost->scic_lock);


	sci_controller_completion_handler(ihost);
	sci_controller_completion_handler(ihost);


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

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


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

	spin_unlock_irq(&ihost->scic_lock);
	spin_unlock_irq(&ihost->scic_lock);


	/* Process any completions in the lists. */
	/* Process any completions in the list. */
	list_for_each_safe(current_position, next_position,
	list_for_each_safe(current_position, next_position,
			   &completed_request_list) {
			   &completed_request_list) {


@@ -1123,68 +1115,37 @@ void isci_host_completion_routine(unsigned long data)
				     completed_node);
				     completed_node);
		task = isci_request_access_task(request);
		task = isci_request_access_task(request);


		/* Normal notification (task_done) */
		dev_dbg(&ihost->pdev->dev,
			"%s: Normal - request/task = %p/%p\n",
			__func__,
			request,
			task);


		/* Return the task to libsas */
		/* Return the task to libsas */
		if (task != NULL) {
		if (task != NULL) {


			task->lldd_task = NULL;
			task->lldd_task = NULL;
			if (!(task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
			if (!test_bit(IREQ_ABORT_PATH_ACTIVE, &request->flags) &&
			    !(task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
				if (test_bit(IREQ_COMPLETE_IN_TARGET,
					     &request->flags)) {


				/* If the task is already in the abort path,
					/* Normal notification (task_done) */
				* the task_done callback cannot be called.
					dev_dbg(&ihost->pdev->dev, "%s: Normal"
				*/
						" - request/task = %p/%p\n",
				task->task_done(task);
						__func__, request, task);
			}
		}

		spin_lock_irq(&ihost->scic_lock);
		isci_free_tag(ihost, request->io_tag);
		spin_unlock_irq(&ihost->scic_lock);
	}
	list_for_each_entry_safe(request, next_request, &errored_request_list,
				 completed_node) {

		task = isci_request_access_task(request);


		/* Use sas_task_abort */
					task->task_done(task);
				} else {
					dev_warn(&ihost->pdev->dev,
					dev_warn(&ihost->pdev->dev,
			 "%s: Error - request/task = %p/%p\n",
						 "%s: Error - request/task"
			 __func__,
						 " = %p/%p\n",
			 request,
						 __func__, request, task);
			 task);

		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);
					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(&ihost->scic_lock);
		spin_lock_irq(&ihost->scic_lock);
			/* Remove the request from the remote device's list
			* of pending requests.
			*/
			list_del_init(&request->dev_node);
		isci_free_tag(ihost, request->io_tag);
		isci_free_tag(ihost, request->io_tag);
		spin_unlock_irq(&ihost->scic_lock);
		spin_unlock_irq(&ihost->scic_lock);
	}
	}
	}


	/* the coalesence timeout doubles at each encoding step, so
	/* the coalesence timeout doubles at each encoding step, so
	 * update it based on the ilog2 value of the outstanding requests
	 * update it based on the ilog2 value of the outstanding requests
@@ -2345,7 +2306,6 @@ static int sci_controller_dma_alloc(struct isci_host *ihost)


		ireq->tc = &ihost->task_context_table[i];
		ireq->tc = &ihost->task_context_table[i];
		ireq->owning_controller = ihost;
		ireq->owning_controller = ihost;
		spin_lock_init(&ireq->state_lock);
		ireq->request_daddr = dma;
		ireq->request_daddr = dma;
		ireq->isci_host = ihost;
		ireq->isci_host = ihost;
		ihost->reqs[i] = ireq;
		ihost->reqs[i] = ireq;
@@ -2697,6 +2657,10 @@ enum sci_status sci_controller_terminate_request(struct isci_host *ihost,
		return SCI_FAILURE_INVALID_STATE;
		return SCI_FAILURE_INVALID_STATE;
	}
	}
	status = sci_io_request_terminate(ireq);
	status = sci_io_request_terminate(ireq);

	dev_dbg(&ihost->pdev->dev, "%s: status=%d; ireq=%p; flags=%lx\n",
		__func__, status, ireq, ireq->flags);

	if ((status == SCI_SUCCESS) &&
	if ((status == SCI_SUCCESS) &&
	    !test_bit(IREQ_PENDING_ABORT, &ireq->flags) &&
	    !test_bit(IREQ_PENDING_ABORT, &ireq->flags) &&
	    !test_and_set_bit(IREQ_TC_ABORT_POSTED, &ireq->flags)) {
	    !test_and_set_bit(IREQ_TC_ABORT_POSTED, &ireq->flags)) {
@@ -2739,6 +2703,8 @@ enum sci_status sci_controller_complete_io(struct isci_host *ihost,


		index = ISCI_TAG_TCI(ireq->io_tag);
		index = ISCI_TAG_TCI(ireq->io_tag);
		clear_bit(IREQ_ACTIVE, &ireq->flags);
		clear_bit(IREQ_ACTIVE, &ireq->flags);
		if (test_bit(IREQ_ABORT_PATH_ACTIVE, &ireq->flags))
			wake_up_all(&ihost->eventq);
		return SCI_SUCCESS;
		return SCI_SUCCESS;
	default:
	default:
		dev_warn(&ihost->pdev->dev, "%s invalid state: %d\n",
		dev_warn(&ihost->pdev->dev, "%s invalid state: %d\n",
+0 −1
Original line number Original line Diff line number Diff line
@@ -205,7 +205,6 @@ struct isci_host {
	wait_queue_head_t eventq;
	wait_queue_head_t eventq;
	struct tasklet_struct completion_tasklet;
	struct tasklet_struct completion_tasklet;
	struct list_head requests_to_complete;
	struct list_head requests_to_complete;
	struct list_head requests_to_errorback;
	spinlock_t scic_lock;
	spinlock_t scic_lock;
	struct isci_request *reqs[SCI_MAX_IO_REQUESTS];
	struct isci_request *reqs[SCI_MAX_IO_REQUESTS];
	struct isci_remote_device devices[SCI_MAX_REMOTE_DEVICES];
	struct isci_remote_device devices[SCI_MAX_REMOTE_DEVICES];
+0 −1
Original line number Original line Diff line number Diff line
@@ -556,7 +556,6 @@ static struct isci_host *isci_host_alloc(struct pci_dev *pdev, int id)
	}
	}


	INIT_LIST_HEAD(&ihost->requests_to_complete);
	INIT_LIST_HEAD(&ihost->requests_to_complete);
	INIT_LIST_HEAD(&ihost->requests_to_errorback);
	for (i = 0; i < SCI_MAX_PORTS; i++) {
	for (i = 0; i < SCI_MAX_PORTS; i++) {
		struct isci_port *iport = &ihost->ports[i];
		struct isci_port *iport = &ihost->ports[i];


+119 −136
Original line number Original line Diff line number Diff line
@@ -80,49 +80,6 @@ static enum sci_status sci_remote_device_suspend(struct isci_remote_device *idev
					       NULL, NULL);
					       NULL, NULL);
}
}


/**
 * isci_remote_device_not_ready() - This function is called by the ihost when
 *    the remote device is not ready. We mark the isci device as ready (not
 *    "ready_for_io") and signal the waiting proccess.
 * @isci_host: This parameter specifies the isci host object.
 * @isci_device: This parameter specifies the remote device
 *
 * sci_lock is held on entrance to this function.
 */
static void isci_remote_device_not_ready(struct isci_host *ihost,
				  struct isci_remote_device *idev, u32 reason)
{
	struct isci_request *ireq;

	dev_dbg(&ihost->pdev->dev,
		"%s: isci_device = %p\n", __func__, idev);

	switch (reason) {
	case SCIC_REMOTE_DEVICE_NOT_READY_STOP_REQUESTED:
		set_bit(IDEV_GONE, &idev->flags);
		break;
	case SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED:
		set_bit(IDEV_IO_NCQERROR, &idev->flags);

		/* Suspend the remote device so the I/O can be terminated. */
		sci_remote_device_suspend(idev);

		/* Kill all outstanding requests for the device. */
		list_for_each_entry(ireq, &idev->reqs_in_process, dev_node) {

			dev_dbg(&ihost->pdev->dev,
				"%s: isci_device = %p request = %p\n",
				__func__, idev, ireq);

			sci_controller_terminate_request(ihost, idev, ireq);
		}
		/* Fall through into the default case... */
	default:
		clear_bit(IDEV_IO_READY, &idev->flags);
		break;
	}
}

/**
/**
 * isci_remote_device_ready() - This function is called by the ihost when the
 * isci_remote_device_ready() - This function is called by the ihost when the
 *    remote device is ready. We mark the isci device as ready and signal the
 *    remote device is ready. We mark the isci device as ready and signal the
@@ -142,49 +99,121 @@ static void isci_remote_device_ready(struct isci_host *ihost, struct isci_remote
		wake_up(&ihost->eventq);
		wake_up(&ihost->eventq);
}
}


static int isci_remote_device_suspendcheck(struct isci_remote_device *idev)
static enum sci_status sci_remote_device_terminate_req(
	struct isci_host *ihost,
	struct isci_remote_device *idev,
	int check_abort,
	struct isci_request *ireq)
{
	dev_dbg(&ihost->pdev->dev,
		"%s: idev=%p; flags=%lx; req=%p; req target=%p\n",
		__func__, idev, idev->flags, ireq, ireq->target_device);

	if (!test_bit(IREQ_ACTIVE, &ireq->flags) ||
	    (ireq->target_device != idev) ||
	    (check_abort && !test_bit(IREQ_PENDING_ABORT, &ireq->flags)))
		return SCI_SUCCESS;

	set_bit(IREQ_ABORT_PATH_ACTIVE, &ireq->flags);

	return sci_controller_terminate_request(ihost, idev, ireq);
}

static enum sci_status sci_remote_device_terminate_reqs_checkabort(
	struct isci_remote_device *idev,
	int chk)
{
{
	return test_bit(IDEV_TXRX_SUSPENDED, &idev->flags)
	struct isci_host *ihost = idev->owning_port->owning_controller;
	    || !test_bit(IDEV_ALLOCATED, &idev->flags);
	enum sci_status status  = SCI_SUCCESS;
	u32 i;

	for (i = 0; i < SCI_MAX_IO_REQUESTS; i++) {
		struct isci_request *ireq = ihost->reqs[i];
		enum sci_status s;

		s = sci_remote_device_terminate_req(ihost, idev, chk, ireq);
		if (s != SCI_SUCCESS)
			status = s;
	}
	return status;
}
}


enum sci_status isci_remote_device_suspend(
enum sci_status isci_remote_device_terminate_requests(
	struct isci_host *ihost,
	struct isci_host *ihost,
	struct isci_remote_device *idev)
	struct isci_remote_device *idev,
	struct isci_request *ireq)
{
{
	enum sci_status status;
	enum sci_status status = SCI_SUCCESS;
	unsigned long flags;
	unsigned long flags;


	spin_lock_irqsave(&ihost->scic_lock, flags);
	spin_lock_irqsave(&ihost->scic_lock, flags);
	if (isci_get_device(idev->domain_dev) == NULL) {
	if (isci_get_device(idev) == NULL) {
		dev_dbg(&ihost->pdev->dev, "%s: failed isci_get_device(idev=%p)\n",
			__func__, idev);
		spin_unlock_irqrestore(&ihost->scic_lock, flags);
		spin_unlock_irqrestore(&ihost->scic_lock, flags);
		status = SCI_FAILURE;
		status = SCI_FAILURE;
	} else {
	} else {
		status = sci_remote_device_suspend(idev);
		spin_unlock_irqrestore(&ihost->scic_lock, flags);
		if (status == SCI_SUCCESS) {
		dev_dbg(&ihost->pdev->dev,
		dev_dbg(&ihost->pdev->dev,
				"%s: idev=%p, about to wait\n",
			"%s: idev=%p, ireq=%p; started_request_count=%d, "
				__func__, idev);
				"about to wait\n",
			wait_event(ihost->eventq,
			__func__, idev, ireq, idev->started_request_count);
				   isci_remote_device_suspendcheck(idev));
		if (ireq) {
			status = test_bit(IDEV_TXRX_SUSPENDED, &idev->flags)
			/* Terminate a specific TC. */
					? SCI_SUCCESS : SCI_FAILURE;
			sci_remote_device_terminate_req(ihost, idev, 0, ireq);
			dev_dbg(&ihost->pdev->dev,
			spin_unlock_irqrestore(&ihost->scic_lock, flags);
				"%s: idev=%p, wait done, device is %s\n",
			wait_event(ihost->eventq, !test_bit(IREQ_ACTIVE,
				__func__, idev,
							    &ireq->flags));
				test_bit(IDEV_TXRX_SUSPENDED, &idev->flags)
					? "<suspended>" : "<deallocated!>");


		} else
		} else {
			dev_dbg(scirdev_to_dev(idev),
			/* Terminate all TCs. */
				 "%s: sci_remote_device_suspend failed, "
			sci_remote_device_terminate_requests(idev);
				 "status = %d\n", __func__, status);
			spin_unlock_irqrestore(&ihost->scic_lock, flags);
			wait_event(ihost->eventq,
				   idev->started_request_count == 0);
		}
		dev_dbg(&ihost->pdev->dev, "%s: idev=%p, wait done\n",
			__func__, idev);
		isci_put_device(idev);
		isci_put_device(idev);
	}
	}
	return status;
	return status;
}
}


/**
* isci_remote_device_not_ready() - This function is called by the ihost when
*    the remote device is not ready. We mark the isci device as ready (not
*    "ready_for_io") and signal the waiting proccess.
* @isci_host: This parameter specifies the isci host object.
* @isci_device: This parameter specifies the remote device
*
* sci_lock is held on entrance to this function.
*/
static void isci_remote_device_not_ready(struct isci_host *ihost,
					 struct isci_remote_device *idev,
					 u32 reason)
{
	dev_dbg(&ihost->pdev->dev,
		"%s: isci_device = %p\n", __func__, idev);

	switch (reason) {
	case SCIC_REMOTE_DEVICE_NOT_READY_STOP_REQUESTED:
		set_bit(IDEV_GONE, &idev->flags);
		break;
	case SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED:
		set_bit(IDEV_IO_NCQERROR, &idev->flags);

		/* Suspend the remote device so the I/O can be terminated. */
		sci_remote_device_suspend(idev);

		/* Kill all outstanding requests for the device. */
		sci_remote_device_terminate_requests(idev);

		/* Fall through into the default case... */
	default:
		clear_bit(IDEV_IO_READY, &idev->flags);
		break;
	}
}

/* called once the remote node context is ready to be freed.
/* called once the remote node context is ready to be freed.
 * The remote device can now report that its stop operation is complete. none
 * The remote device can now report that its stop operation is complete. none
 */
 */
@@ -196,36 +225,10 @@ static void rnc_destruct_done(void *_dev)
	sci_change_state(&idev->sm, SCI_DEV_STOPPED);
	sci_change_state(&idev->sm, SCI_DEV_STOPPED);
}
}


static enum sci_status sci_remote_device_terminate_requests_checkabort(
	struct isci_remote_device *idev,
	int check_abort_pending)
{
	struct isci_host *ihost = idev->owning_port->owning_controller;
	enum sci_status status  = SCI_SUCCESS;
	u32 i;

	for (i = 0; i < SCI_MAX_IO_REQUESTS; i++) {
		struct isci_request *ireq = ihost->reqs[i];
		enum sci_status s;

		if (!test_bit(IREQ_ACTIVE, &ireq->flags) ||
		    (ireq->target_device != idev) ||
		    (check_abort_pending && !test_bit(IREQ_PENDING_ABORT,
						      &ireq->flags)))
			continue;

		s = sci_controller_terminate_request(ihost, idev, ireq);
		if (s != SCI_SUCCESS)
			status = s;
	}

	return status;
}

enum sci_status sci_remote_device_terminate_requests(
enum sci_status sci_remote_device_terminate_requests(
	struct isci_remote_device *idev)
	struct isci_remote_device *idev)
{
{
	return sci_remote_device_terminate_requests_checkabort(idev, 0);
	return sci_remote_device_terminate_reqs_checkabort(idev, 0);
}
}


enum sci_status sci_remote_device_stop(struct isci_remote_device *idev,
enum sci_status sci_remote_device_stop(struct isci_remote_device *idev,
@@ -771,10 +774,6 @@ enum sci_status sci_remote_device_start_task(struct isci_host *ihost,
		if (status != SCI_SUCCESS)
		if (status != SCI_SUCCESS)
			return status;
			return status;


		status = sci_remote_node_context_start_task(&idev->rnc, ireq);
		if (status != SCI_SUCCESS)
			goto out;

		status = sci_request_start(ireq);
		status = sci_request_start(ireq);
		if (status != SCI_SUCCESS)
		if (status != SCI_SUCCESS)
			goto out;
			goto out;
@@ -796,8 +795,9 @@ enum sci_status sci_remote_device_start_task(struct isci_host *ihost,
		sci_remote_node_context_suspend(
		sci_remote_node_context_suspend(
			&idev->rnc, SCI_SOFTWARE_SUSPENSION,
			&idev->rnc, SCI_SOFTWARE_SUSPENSION,
			SCI_SOFTWARE_SUSPEND_EXPECTED_EVENT, NULL, NULL);
			SCI_SOFTWARE_SUSPEND_EXPECTED_EVENT, NULL, NULL);
		sci_remote_node_context_resume(

			&idev->rnc, sci_remote_device_continue_request, idev);
		status = sci_remote_node_context_start_task(&idev->rnc, ireq,
				sci_remote_device_continue_request, idev);


	out:
	out:
		sci_remote_device_start_request(idev, ireq, status);
		sci_remote_device_start_request(idev, ireq, status);
@@ -811,7 +811,9 @@ enum sci_status sci_remote_device_start_task(struct isci_host *ihost,
		if (status != SCI_SUCCESS)
		if (status != SCI_SUCCESS)
			return status;
			return status;


		status = sci_remote_node_context_start_task(&idev->rnc, ireq);
		/* Resume the RNC as needed: */
		status = sci_remote_node_context_start_task(&idev->rnc, ireq,
							    NULL, NULL);
		if (status != SCI_SUCCESS)
		if (status != SCI_SUCCESS)
			break;
			break;


@@ -1322,20 +1324,6 @@ static enum sci_status isci_remote_device_construct(struct isci_port *iport,
	return status;
	return status;
}
}


void isci_remote_device_nuke_requests(struct isci_host *ihost, struct isci_remote_device *idev)
{
	DECLARE_COMPLETION_ONSTACK(aborted_task_completion);

	dev_dbg(&ihost->pdev->dev,
		"%s: idev = %p\n", __func__, idev);

	/* Cleanup all requests pending for this device. */
	isci_terminate_pending_requests(ihost, idev);

	dev_dbg(&ihost->pdev->dev,
		"%s: idev = %p, done\n", __func__, idev);
}

/**
/**
 * This function builds the isci_remote_device when a libsas dev_found message
 * This function builds the isci_remote_device when a libsas dev_found message
 *    is received.
 *    is received.
@@ -1495,32 +1483,28 @@ int isci_remote_device_found(struct domain_device *dev)
	return status == SCI_SUCCESS ? 0 : -ENODEV;
	return status == SCI_SUCCESS ? 0 : -ENODEV;
}
}


enum sci_status isci_remote_device_reset(
enum sci_status isci_remote_device_suspend_terminate(
	struct isci_host *ihost,
	struct isci_host *ihost,
	struct isci_remote_device *idev)
	struct isci_remote_device *idev,
	struct isci_request *ireq)
{
{
	unsigned long flags;
	unsigned long flags;
	enum sci_status status;
	enum sci_status status;


	/* Put the device into a reset state so the suspension will not
	/* Put the device into suspension. */
	 * automatically resume.
	 */
	spin_lock_irqsave(&ihost->scic_lock, flags);
	spin_lock_irqsave(&ihost->scic_lock, flags);
	status = sci_remote_device_reset(idev);
	sci_remote_device_suspend(idev);
	spin_unlock_irqrestore(&ihost->scic_lock, flags);
	spin_unlock_irqrestore(&ihost->scic_lock, flags);
	if (status != SCI_SUCCESS) {

		dev_dbg(&ihost->pdev->dev,
	/* Terminate and wait for the completions. */
			"%s: sci_remote_device_reset(%p) returned %d!\n",
	status = isci_remote_device_terminate_requests(ihost, idev, ireq);
			__func__, idev, status);
	if (status != SCI_SUCCESS)
		return status;
	}
	/* Wait for the device suspend. */
	status = isci_remote_device_suspend(ihost, idev);
	if (status != SCI_SUCCESS) {
		dev_dbg(&ihost->pdev->dev,
		dev_dbg(&ihost->pdev->dev,
			"%s: isci_remote_device_suspend(%p) returned %d!\n",
			"%s: isci_remote_device_terminate_requests(%p) "
				"returned %d!\n",
			__func__, idev, status);
			__func__, idev, status);
	}

	/* NOTE: RNC resumption is left to the caller! */
	return status;
	return status;
}
}


@@ -1533,7 +1517,7 @@ int isci_remote_device_is_safe_to_abort(
enum sci_status sci_remote_device_abort_requests_pending_abort(
enum sci_status sci_remote_device_abort_requests_pending_abort(
	struct isci_remote_device *idev)
	struct isci_remote_device *idev)
{
{
	return sci_remote_device_terminate_requests_checkabort(idev, 1);
	return sci_remote_device_terminate_reqs_checkabort(idev, 1);
}
}


enum sci_status isci_remote_device_reset_complete(
enum sci_status isci_remote_device_reset_complete(
@@ -1545,7 +1529,6 @@ enum sci_status isci_remote_device_reset_complete(


	spin_lock_irqsave(&ihost->scic_lock, flags);
	spin_lock_irqsave(&ihost->scic_lock, flags);
	status = sci_remote_device_reset_complete(idev);
	status = sci_remote_device_reset_complete(idev);
	sci_remote_device_resume(idev, NULL, NULL);
	spin_unlock_irqrestore(&ihost->scic_lock, flags);
	spin_unlock_irqrestore(&ihost->scic_lock, flags);


	return status;
	return status;
+11 −4
Original line number Original line Diff line number Diff line
@@ -85,7 +85,6 @@ struct isci_remote_device {
	#define IDEV_GONE 3
	#define IDEV_GONE 3
	#define IDEV_IO_READY 4
	#define IDEV_IO_READY 4
	#define IDEV_IO_NCQERROR 5
	#define IDEV_IO_NCQERROR 5
	#define IDEV_TXRX_SUSPENDED 6
	unsigned long flags;
	unsigned long flags;
	struct kref kref;
	struct kref kref;
	struct isci_port *isci_port;
	struct isci_port *isci_port;
@@ -107,10 +106,8 @@ struct isci_remote_device {


/* device reference routines must be called under sci_lock */
/* device reference routines must be called under sci_lock */
static inline struct isci_remote_device *isci_get_device(
static inline struct isci_remote_device *isci_get_device(
	struct domain_device *dev)
	struct isci_remote_device *idev)
{
{
	struct isci_remote_device *idev = dev->lldd_dev;

	if (idev)
	if (idev)
		kref_get(&idev->kref);
		kref_get(&idev->kref);
	return idev;
	return idev;
@@ -378,4 +375,14 @@ enum sci_status isci_remote_device_reset(
enum sci_status isci_remote_device_reset_complete(
enum sci_status isci_remote_device_reset_complete(
	struct isci_host *ihost,
	struct isci_host *ihost,
	struct isci_remote_device *idev);
	struct isci_remote_device *idev);

enum sci_status isci_remote_device_suspend_terminate(
	struct isci_host *ihost,
	struct isci_remote_device *idev,
	struct isci_request *ireq);

enum sci_status isci_remote_device_terminate_requests(
	struct isci_host *ihost,
	struct isci_remote_device *idev,
	struct isci_request *ireq);
#endif /* !defined(_ISCI_REMOTE_DEVICE_H_) */
#endif /* !defined(_ISCI_REMOTE_DEVICE_H_) */
Loading