Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 302559
b: refs/heads/master
c: 59e3539
h: refs/heads/master
i:
  302557: 9b6e56d
  302555: 769ab7e
  302551: 55af09c
  302543: ae20cf8
  302527: b4fe742
v: v3
  • Loading branch information
Jeff Skirvin authored and Dan Williams committed May 17, 2012
1 parent 07a54a7 commit 75b6042
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 64 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 14aaa9f0a318bd04cbb9d822524b817e95d8b343
refs/heads/master: 59e35396436c564b5019e1a70073900bc3e19f4f
11 changes: 0 additions & 11 deletions trunk/drivers/scsi/isci/port.c
Original file line number Diff line number Diff line change
Expand Up @@ -1688,17 +1688,6 @@ int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *ipor
__func__, iport, status);

}

/* If the hard reset for the port has failed, consider this
* the same as link failures on all phys in the port.
*/
if (ret != TMF_RESP_FUNC_COMPLETE) {

dev_err(&ihost->pdev->dev,
"%s: iport = %p; hard reset failed "
"(0x%x) - driving explicit link fail for all phys\n",
__func__, iport, iport->hard_reset_status);
}
return ret;
}

Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/scsi/isci/remote_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ static void isci_remote_device_not_ready(struct isci_host *ihost,
u32 reason)
{
dev_dbg(&ihost->pdev->dev,
"%s: isci_device = %p\n", __func__, idev);
"%s: isci_device = %p; reason = %d\n", __func__, idev, reason);

switch (reason) {
case SCIC_REMOTE_DEVICE_NOT_READY_STOP_REQUESTED:
Expand Down
145 changes: 97 additions & 48 deletions trunk/drivers/scsi/isci/remote_node_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,21 +165,24 @@ static void sci_remote_node_context_construct_buffer(struct sci_remote_node_cont
static void sci_remote_node_context_setup_to_resume(
struct sci_remote_node_context *sci_rnc,
scics_sds_remote_node_context_callback callback,
void *callback_parameter)
void *callback_parameter,
enum sci_remote_node_context_destination_state dest_param)
{
if (sci_rnc->destination_state != SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_FINAL) {
sci_rnc->destination_state = SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_READY;
sci_rnc->user_callback = callback;
sci_rnc->user_cookie = callback_parameter;
if (sci_rnc->destination_state != RNC_DEST_FINAL) {
sci_rnc->destination_state = dest_param;
if (callback != NULL) {
sci_rnc->user_callback = callback;
sci_rnc->user_cookie = callback_parameter;
}
}
}

static void sci_remote_node_context_setup_to_destory(
static void sci_remote_node_context_setup_to_destroy(
struct sci_remote_node_context *sci_rnc,
scics_sds_remote_node_context_callback callback,
void *callback_parameter)
{
sci_rnc->destination_state = SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_FINAL;
sci_rnc->destination_state = RNC_DEST_FINAL;
sci_rnc->user_callback = callback;
sci_rnc->user_cookie = callback_parameter;
}
Expand All @@ -203,9 +206,13 @@ static void sci_remote_node_context_notify_user(

static void sci_remote_node_context_continue_state_transitions(struct sci_remote_node_context *rnc)
{
if (rnc->destination_state == SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_READY)
if ((rnc->destination_state == RNC_DEST_READY) ||
(rnc->destination_state == RNC_DEST_SUSPENDED_RESUME)) {
rnc->destination_state = RNC_DEST_READY;
sci_remote_node_context_resume(rnc, rnc->user_callback,
rnc->user_cookie);
} else
rnc->destination_state = RNC_DEST_UNSPECIFIED;
}

static void sci_remote_node_context_validate_context_buffer(struct sci_remote_node_context *sci_rnc)
Expand Down Expand Up @@ -252,7 +259,7 @@ static void sci_remote_node_context_initial_state_enter(struct sci_base_state_ma
* someone requested to destroy the remote node context object.
*/
if (sm->previous_state_id == SCI_RNC_INVALIDATING) {
rnc->destination_state = SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_UNSPECIFIED;
rnc->destination_state = RNC_DEST_UNSPECIFIED;
sci_remote_node_context_notify_user(rnc);
}
}
Expand Down Expand Up @@ -297,10 +304,26 @@ static void sci_remote_node_context_resuming_state_enter(struct sci_base_state_m
static void sci_remote_node_context_ready_state_enter(struct sci_base_state_machine *sm)
{
struct sci_remote_node_context *rnc = container_of(sm, typeof(*rnc), sm);

rnc->destination_state = SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_UNSPECIFIED;

if (rnc->user_callback)
enum sci_remote_node_context_destination_state dest_select;
scics_sds_remote_node_context_callback usr_cb = rnc->user_callback;
void *usr_param = rnc->user_cookie;
int tell_user = 1;

dest_select = rnc->destination_state;
rnc->destination_state = RNC_DEST_UNSPECIFIED;

if ((dest_select == RNC_DEST_SUSPENDED) ||
(dest_select == RNC_DEST_SUSPENDED_RESUME)) {
sci_remote_node_context_suspend(
rnc, SCI_SOFTWARE_SUSPENSION,
SCI_SOFTWARE_SUSPEND_EXPECTED_EVENT, NULL, NULL);

if (dest_select == RNC_DEST_SUSPENDED_RESUME) {
sci_remote_node_context_resume(rnc, usr_cb, usr_param);
tell_user = 0; /* Wait until ready again. */
}
}
if (tell_user && rnc->user_callback)
sci_remote_node_context_notify_user(rnc);
}

Expand Down Expand Up @@ -366,7 +389,7 @@ void sci_remote_node_context_construct(struct sci_remote_node_context *rnc,
memset(rnc, 0, sizeof(struct sci_remote_node_context));

rnc->remote_node_index = remote_node_index;
rnc->destination_state = SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_UNSPECIFIED;
rnc->destination_state = RNC_DEST_UNSPECIFIED;

sci_init_sm(&rnc->sm, sci_remote_node_context_state_table, SCI_RNC_INITIAL);
}
Expand All @@ -390,11 +413,11 @@ enum sci_status sci_remote_node_context_event_handler(struct sci_remote_node_con
break;
case SCI_RNC_INVALIDATING:
if (scu_get_event_code(event_code) == SCU_EVENT_POST_RNC_INVALIDATE_COMPLETE) {
if (sci_rnc->destination_state == SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_FINAL)
state = SCI_RNC_INITIAL;
if (sci_rnc->destination_state == RNC_DEST_FINAL)
next_state = SCI_RNC_INITIAL;
else
state = SCI_RNC_POSTING;
sci_change_state(&sci_rnc->sm, state);
next_state = SCI_RNC_POSTING;
sci_change_state(&sci_rnc->sm, next_state);
} else {
switch (scu_get_event_type(event_code)) {
case SCU_EVENT_TYPE_RNC_SUSPEND_TX:
Expand Down Expand Up @@ -483,15 +506,15 @@ enum sci_status sci_remote_node_context_destruct(struct sci_remote_node_context
state = sci_rnc->sm.current_state_id;
switch (state) {
case SCI_RNC_INVALIDATING:
sci_remote_node_context_setup_to_destory(sci_rnc, cb_fn, cb_p);
sci_remote_node_context_setup_to_destroy(sci_rnc, cb_fn, cb_p);
return SCI_SUCCESS;
case SCI_RNC_POSTING:
case SCI_RNC_RESUMING:
case SCI_RNC_READY:
case SCI_RNC_TX_SUSPENDED:
case SCI_RNC_TX_RX_SUSPENDED:
case SCI_RNC_AWAIT_SUSPENSION:
sci_remote_node_context_setup_to_destory(sci_rnc, cb_fn, cb_p);
sci_remote_node_context_setup_to_destroy(sci_rnc, cb_fn, cb_p);
sci_change_state(&sci_rnc->sm, SCI_RNC_INVALIDATING);
return SCI_SUCCESS;
case SCI_RNC_INITIAL:
Expand Down Expand Up @@ -522,6 +545,8 @@ enum sci_status sci_remote_node_context_suspend(
= sci_rnc->sm.current_state_id;
struct isci_remote_device *idev = rnc_to_dev(sci_rnc);
enum sci_status status = SCI_FAILURE_INVALID_STATE;
enum sci_remote_node_context_destination_state dest_param =
RNC_DEST_UNSPECIFIED;

dev_dbg(scirdev_to_dev(idev),
"%s: current state %d, current suspend_type %x dest state %d,"
Expand All @@ -531,12 +556,31 @@ enum sci_status sci_remote_node_context_suspend(
suspend_type);

/* Disable automatic state continuations if explicitly suspending. */
if (suspend_reason == SCI_SOFTWARE_SUSPENSION)
sci_rnc->destination_state
= SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_UNSPECIFIED;
if ((suspend_reason != SCI_SOFTWARE_SUSPENSION) ||
(sci_rnc->destination_state == RNC_DEST_FINAL))
dest_param = sci_rnc->destination_state;

switch (state) {
case SCI_RNC_RESUMING:
break; /* The RNC has been posted, so start the suspend. */
case SCI_RNC_READY:
break;
case SCI_RNC_INVALIDATING:
if (sci_rnc->destination_state == RNC_DEST_FINAL) {
dev_warn(scirdev_to_dev(idev),
"%s: already destroying %p\n",
__func__, sci_rnc);
return SCI_FAILURE_INVALID_STATE;
}
/* Fall through and handle like SCI_RNC_POSTING */
case SCI_RNC_POSTING:
/* Set the destination state to AWAIT - this signals the
* entry into the SCI_RNC_READY state that a suspension
* needs to be done immediately.
*/
sci_rnc->destination_state = RNC_DEST_SUSPENDED;
return SCI_SUCCESS;

case SCI_RNC_TX_SUSPENDED:
if (suspend_type == SCU_EVENT_TL_RNC_SUSPEND_TX)
status = SCI_SUCCESS;
Expand All @@ -556,6 +600,7 @@ enum sci_status sci_remote_node_context_suspend(
rnc_state_name(state));
return SCI_FAILURE_INVALID_STATE;
}
sci_rnc->destination_state = dest_param;
sci_rnc->user_callback = cb_fn;
sci_rnc->user_cookie = cb_p;
sci_rnc->suspend_type = suspend_type;
Expand Down Expand Up @@ -590,18 +635,31 @@ enum sci_status sci_remote_node_context_resume(struct sci_remote_node_context *s
if (sci_rnc->remote_node_index == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX)
return SCI_FAILURE_INVALID_STATE;

sci_remote_node_context_setup_to_resume(sci_rnc, cb_fn, cb_p);
sci_remote_node_context_setup_to_resume(sci_rnc, cb_fn, cb_p,
RNC_DEST_READY);
sci_remote_node_context_construct_buffer(sci_rnc);
sci_change_state(&sci_rnc->sm, SCI_RNC_POSTING);
return SCI_SUCCESS;
case SCI_RNC_POSTING:
case SCI_RNC_INVALIDATING:
case SCI_RNC_RESUMING:
if (sci_rnc->destination_state != SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_READY)
return SCI_FAILURE_INVALID_STATE;

sci_rnc->user_callback = cb_fn;
sci_rnc->user_cookie = cb_p;
/* We are still waiting to post when a resume was requested. */
switch (sci_rnc->destination_state) {
case RNC_DEST_SUSPENDED:
case RNC_DEST_SUSPENDED_RESUME:
/* Previously waiting to suspend after posting. Now
* continue onto resumption.
*/
sci_remote_node_context_setup_to_resume(
sci_rnc, cb_fn, cb_p,
RNC_DEST_SUSPENDED_RESUME);
break;
default:
sci_remote_node_context_setup_to_resume(
sci_rnc, cb_fn, cb_p,
RNC_DEST_READY);
break;
}
return SCI_SUCCESS;
case SCI_RNC_TX_SUSPENDED:
case SCI_RNC_TX_RX_SUSPENDED: {
Expand All @@ -613,7 +671,8 @@ enum sci_status sci_remote_node_context_resume(struct sci_remote_node_context *s
* to clear the TCi to NCQ tag mapping table for the RNi.
* All other device types we can just resume.
*/
sci_remote_node_context_setup_to_resume(sci_rnc, cb_fn, cb_p);
sci_remote_node_context_setup_to_resume(sci_rnc, cb_fn, cb_p,
RNC_DEST_READY);

if (dev_is_sata(dev) && dev->parent)
sci_change_state(&sci_rnc->sm, SCI_RNC_INVALIDATING);
Expand All @@ -622,7 +681,9 @@ enum sci_status sci_remote_node_context_resume(struct sci_remote_node_context *s
return SCI_SUCCESS;
}
case SCI_RNC_AWAIT_SUSPENSION:
sci_remote_node_context_setup_to_resume(sci_rnc, cb_fn, cb_p);
sci_remote_node_context_setup_to_resume(
sci_rnc, cb_fn, cb_p,
RNC_DEST_SUSPENDED_RESUME);
return SCI_SUCCESS;
default:
dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
Expand Down Expand Up @@ -663,24 +724,12 @@ enum sci_status sci_remote_node_context_start_task(
scics_sds_remote_node_context_callback cb_fn,
void *cb_p)
{
enum scis_sds_remote_node_context_states state;

state = sci_rnc->sm.current_state_id;
switch (state) {
case SCI_RNC_RESUMING:
case SCI_RNC_READY:
case SCI_RNC_AWAIT_SUSPENSION:
return SCI_SUCCESS;
case SCI_RNC_TX_SUSPENDED:
case SCI_RNC_TX_RX_SUSPENDED:
sci_remote_node_context_resume(sci_rnc, cb_fn, cb_p);
return SCI_SUCCESS;
default:
enum sci_status status = sci_remote_node_context_resume(sci_rnc,
cb_fn, cb_p);
if (status != SCI_SUCCESS)
dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
"%s: invalid state %s\n", __func__,
rnc_state_name(state));
return SCI_FAILURE_INVALID_STATE;
}
"%s: resume failed: %d\n", __func__, status);
return status;
}

int sci_remote_node_context_is_safe_to_abort(
Expand Down
10 changes: 7 additions & 3 deletions trunk/drivers/scsi/isci/remote_node_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,13 @@ const char *rnc_state_name(enum scis_sds_remote_node_context_states state);
* node context.
*/
enum sci_remote_node_context_destination_state {
SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_UNSPECIFIED,
SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_READY,
SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_FINAL
RNC_DEST_UNSPECIFIED,
RNC_DEST_READY,
RNC_DEST_FINAL,
RNC_DEST_SUSPENDED, /* Set when suspend during post/invalidate */
RNC_DEST_SUSPENDED_RESUME /* Set when a resume was done during posting
* or invalidating and already suspending.
*/
};

/**
Expand Down

0 comments on commit 75b6042

Please sign in to comment.