Skip to content

Commit

Permalink
isci: Distinguish between remote device suspension cases
Browse files Browse the repository at this point in the history
For NCQ error conditions among others, there is no need to enable
the link layer hang detect timer.

Signed-off-by: Jeff Skirvin <jeffrey.d.skirvin@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
  • Loading branch information
Jeff Skirvin authored and Dan Williams committed May 17, 2012
1 parent d6b2a0e commit c94fc1a
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 25 deletions.
27 changes: 11 additions & 16 deletions drivers/scsi/isci/remote_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,11 @@ const char *dev_state_name(enum sci_remote_device_states state)
}
#undef C

static enum sci_status sci_remote_device_suspend(struct isci_remote_device *idev)
static enum sci_status sci_remote_device_suspend(struct isci_remote_device *idev,
enum sci_remote_node_suspension_reasons reason)
{
return sci_remote_node_context_suspend(&idev->rnc,
SCI_SOFTWARE_SUSPENSION,
reason,
SCI_SOFTWARE_SUSPEND_EXPECTED_EVENT,
NULL, NULL);
}
Expand Down Expand Up @@ -199,7 +200,7 @@ static void isci_remote_device_not_ready(struct isci_host *ihost,
set_bit(IDEV_IO_NCQERROR, &idev->flags);

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

/* Kill all outstanding requests for the device. */
sci_remote_device_terminate_requests(idev);
Expand Down Expand Up @@ -268,7 +269,8 @@ enum sci_status sci_remote_device_stop(struct isci_remote_device *idev,
rnc_destruct_done,
idev);
else {
sci_remote_device_suspend(idev);
sci_remote_device_suspend(
idev, SCI_SW_SUSPEND_LINKHANG_DETECT);
sci_remote_device_terminate_requests(idev);
}
return SCI_SUCCESS;
Expand Down Expand Up @@ -473,11 +475,7 @@ enum sci_status sci_remote_device_event_handler(struct isci_remote_device *idev,
status = SCI_SUCCESS;

/* Suspend the associated RNC */
sci_remote_node_context_suspend(
&idev->rnc,
SCI_SOFTWARE_SUSPENSION,
SCI_SOFTWARE_SUSPEND_EXPECTED_EVENT,
NULL, NULL);
sci_remote_device_suspend(idev, SCI_SW_SUSPEND_NORMAL);

dev_dbg(scirdev_to_dev(idev),
"%s: device: %p event code: %x: %s\n",
Expand Down Expand Up @@ -789,9 +787,8 @@ enum sci_status sci_remote_device_start_task(struct isci_host *ihost,
* the correct action when the remote node context is suspended
* and later resumed.
*/
sci_remote_node_context_suspend(
&idev->rnc, SCI_SOFTWARE_SUSPENSION,
SCI_SOFTWARE_SUSPEND_EXPECTED_EVENT, NULL, NULL);
sci_remote_device_suspend(idev,
SCI_SW_SUSPEND_LINKHANG_DETECT);

status = sci_remote_node_context_start_task(&idev->rnc, ireq,
sci_remote_device_continue_request, idev);
Expand Down Expand Up @@ -986,9 +983,7 @@ static void sci_remote_device_resetting_state_enter(struct sci_base_state_machin
dev_dbg(&ihost->pdev->dev,
"%s: isci_device = %p\n", __func__, idev);

sci_remote_node_context_suspend(
&idev->rnc, SCI_SOFTWARE_SUSPENSION,
SCI_SOFTWARE_SUSPEND_EXPECTED_EVENT, NULL, NULL);
sci_remote_device_suspend(idev, SCI_SW_SUSPEND_LINKHANG_DETECT);
}

static void sci_remote_device_resetting_state_exit(struct sci_base_state_machine *sm)
Expand Down Expand Up @@ -1486,7 +1481,7 @@ enum sci_status isci_remote_device_suspend_terminate(

/* Put the device into suspension. */
spin_lock_irqsave(&ihost->scic_lock, flags);
sci_remote_device_suspend(idev);
sci_remote_device_suspend(idev, SCI_SW_SUSPEND_LINKHANG_DETECT);
spin_unlock_irqrestore(&ihost->scic_lock, flags);

/* Terminate and wait for the completions. */
Expand Down
19 changes: 13 additions & 6 deletions drivers/scsi/isci/remote_node_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <scsi/sas_ata.h>
#include "host.h"
#include "isci.h"
#include "remote_device.h"
Expand Down Expand Up @@ -315,7 +315,7 @@ static void sci_remote_node_context_ready_state_enter(struct sci_base_state_mach
if ((dest_select == RNC_DEST_SUSPENDED) ||
(dest_select == RNC_DEST_SUSPENDED_RESUME)) {
sci_remote_node_context_suspend(
rnc, SCI_SOFTWARE_SUSPENSION,
rnc, SCI_SW_SUSPEND_NORMAL,
SCI_SOFTWARE_SUSPEND_EXPECTED_EVENT, NULL, NULL);

if (dest_select == RNC_DEST_SUSPENDED_RESUME) {
Expand Down Expand Up @@ -352,8 +352,10 @@ static void sci_remote_node_context_await_suspend_state_exit(
{
struct sci_remote_node_context *rnc
= container_of(sm, typeof(*rnc), sm);
struct isci_remote_device *idev = rnc_to_dev(rnc);

isci_dev_set_hang_detection_timeout(rnc_to_dev(rnc), 0);
if (dev_is_sata(idev->domain_dev))
isci_dev_set_hang_detection_timeout(idev, 0);
}

static const struct sci_base_state sci_remote_node_context_state_table[] = {
Expand Down Expand Up @@ -556,7 +558,7 @@ enum sci_status sci_remote_node_context_suspend(
suspend_type);

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

Expand Down Expand Up @@ -612,8 +614,13 @@ enum sci_status sci_remote_node_context_suspend(
wake_up_all(&ihost->eventq); /* Let observers look. */
return SCI_SUCCESS;
}
if (suspend_reason == SCI_SOFTWARE_SUSPENSION) {
isci_dev_set_hang_detection_timeout(idev, 0x00000001);
if ((suspend_reason == SCI_SW_SUSPEND_NORMAL) ||
(suspend_reason == SCI_SW_SUSPEND_LINKHANG_DETECT)) {

if ((suspend_reason == SCI_SW_SUSPEND_LINKHANG_DETECT)
&& dev_is_sata(idev->domain_dev))
isci_dev_set_hang_detection_timeout(idev, 0x00000001);

sci_remote_device_post_request(
idev, SCI_SOFTWARE_SUSPEND_CMD);
}
Expand Down
5 changes: 3 additions & 2 deletions drivers/scsi/isci/remote_node_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,9 @@
#define SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX 0x0FFF

enum sci_remote_node_suspension_reasons {
SCU_HARDWARE_SUSPENSION,
SCI_SOFTWARE_SUSPENSION
SCI_HW_SUSPEND,
SCI_SW_SUSPEND_NORMAL,
SCI_SW_SUSPEND_LINKHANG_DETECT
};
#define SCI_SOFTWARE_SUSPEND_CMD SCU_CONTEXT_COMMAND_POST_RNC_SUSPEND_TX_RX
#define SCI_SOFTWARE_SUSPEND_EXPECTED_EVENT SCU_EVENT_TL_RNC_SUSPEND_TX_RX
Expand Down
2 changes: 1 addition & 1 deletion drivers/scsi/isci/request.c
Original file line number Diff line number Diff line change
Expand Up @@ -2380,7 +2380,7 @@ static void sci_request_handle_suspending_completions(

sci_remote_node_context_suspend(
&ireq->target_device->rnc,
SCU_HARDWARE_SUSPENSION,
SCI_HW_SUSPEND,
(is_tx_rx) ? SCU_EVENT_TL_RNC_SUSPEND_TX_RX
: SCU_EVENT_TL_RNC_SUSPEND_TX,
NULL, NULL);
Expand Down

0 comments on commit c94fc1a

Please sign in to comment.