[SCSI] isci: stop interpreting ->lldd_lu_reset() as an ata soft-reset
authorDan Williams <dan.j.williams@intel.com>
Fri, 9 Dec 2011 07:20:44 +0000 (23:20 -0800)
committerJames Bottomley <JBottomley@Parallels.com>
Wed, 29 Feb 2012 21:13:40 +0000 (15:13 -0600)
Driving resets from libsas-eh is pre-mature as libata will make a
decision about performing a softreset.  Currently libata determines
whether to perform a softreset based on ata_eh_followup_srst_needed(),
and none of those conditions apply to isci.

Remove the srst implementation and translate ->lldd_lu_reset() for ata
devices as a request to drive a reset via libata-eh.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
drivers/scsi/isci/request.c
drivers/scsi/isci/request.h
drivers/scsi/isci/task.c
drivers/scsi/isci/task.h
drivers/scsi/libsas/sas_ata.c

index 788daee..1a39ce5 100644 (file)
@@ -666,18 +666,12 @@ sci_io_request_construct_sata(struct isci_request *ireq,
        if (test_bit(IREQ_TMF, &ireq->flags)) {
                struct isci_tmf *tmf = isci_request_access_tmf(ireq);
 
-               if (tmf->tmf_code == isci_tmf_sata_srst_high ||
-                   tmf->tmf_code == isci_tmf_sata_srst_low) {
-                       scu_stp_raw_request_construct_task_context(ireq);
-                       return SCI_SUCCESS;
-               } else {
-                       dev_err(&ireq->owning_controller->pdev->dev,
-                               "%s: Request 0x%p received un-handled SAT "
-                               "management protocol 0x%x.\n",
-                               __func__, ireq, tmf->tmf_code);
+               dev_err(&ireq->owning_controller->pdev->dev,
+                       "%s: Request 0x%p received un-handled SAT "
+                       "management protocol 0x%x.\n",
+                       __func__, ireq, tmf->tmf_code);
 
-                       return SCI_FAILURE;
-               }
+               return SCI_FAILURE;
        }
 
        if (!sas_protocol_ata(task->task_proto)) {
@@ -774,34 +768,6 @@ static enum sci_status sci_io_request_construct_basic_sata(struct isci_request *
        return status;
 }
 
-enum sci_status sci_task_request_construct_sata(struct isci_request *ireq)
-{
-       enum sci_status status = SCI_SUCCESS;
-
-       /* check for management protocols */
-       if (test_bit(IREQ_TMF, &ireq->flags)) {
-               struct isci_tmf *tmf = isci_request_access_tmf(ireq);
-
-               if (tmf->tmf_code == isci_tmf_sata_srst_high ||
-                   tmf->tmf_code == isci_tmf_sata_srst_low) {
-                       scu_stp_raw_request_construct_task_context(ireq);
-               } else {
-                       dev_err(&ireq->owning_controller->pdev->dev,
-                               "%s: Request 0x%p received un-handled SAT "
-                               "Protocol 0x%x.\n",
-                               __func__, ireq, tmf->tmf_code);
-
-                       return SCI_FAILURE;
-               }
-       }
-
-       if (status != SCI_SUCCESS)
-               return status;
-       sci_change_state(&ireq->sm, SCI_REQ_CONSTRUCTED);
-
-       return status;
-}
-
 /**
  * sci_req_tx_bytes - bytes transferred when reply underruns request
  * @ireq: request that was terminated early
@@ -903,9 +869,6 @@ sci_io_request_terminate(struct isci_request *ireq)
        case SCI_REQ_STP_PIO_WAIT_FRAME:
        case SCI_REQ_STP_PIO_DATA_IN:
        case SCI_REQ_STP_PIO_DATA_OUT:
-       case SCI_REQ_STP_SOFT_RESET_WAIT_H2D_ASSERTED:
-       case SCI_REQ_STP_SOFT_RESET_WAIT_H2D_DIAG:
-       case SCI_REQ_STP_SOFT_RESET_WAIT_D2H:
        case SCI_REQ_ATAPI_WAIT_H2D:
        case SCI_REQ_ATAPI_WAIT_PIO_SETUP:
        case SCI_REQ_ATAPI_WAIT_D2H:
@@ -2085,59 +2048,6 @@ sci_io_request_frame_handler(struct isci_request *ireq,
                return status;
        }
 
-       case SCI_REQ_STP_SOFT_RESET_WAIT_D2H: {
-               struct dev_to_host_fis *frame_header;
-               u32 *frame_buffer;
-
-               status = sci_unsolicited_frame_control_get_header(&ihost->uf_control,
-                                                                      frame_index,
-                                                                      (void **)&frame_header);
-               if (status != SCI_SUCCESS) {
-                       dev_err(&ihost->pdev->dev,
-                               "%s: SCIC IO Request 0x%p could not get frame "
-                               "header for frame index %d, status %x\n",
-                               __func__,
-                               stp_req,
-                               frame_index,
-                               status);
-                       return status;
-               }
-
-               switch (frame_header->fis_type) {
-               case FIS_REGD2H:
-                       sci_unsolicited_frame_control_get_buffer(&ihost->uf_control,
-                                                                     frame_index,
-                                                                     (void **)&frame_buffer);
-
-                       sci_controller_copy_sata_response(&ireq->stp.rsp,
-                                                              frame_header,
-                                                              frame_buffer);
-
-                       /* The command has completed with error */
-                       ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE;
-                       ireq->sci_status = SCI_FAILURE_IO_RESPONSE_VALID;
-                       break;
-
-               default:
-                       dev_warn(&ihost->pdev->dev,
-                                "%s: IO Request:0x%p Frame Id:%d protocol "
-                                "violation occurred\n",
-                                __func__,
-                                stp_req,
-                                frame_index);
-
-                       ireq->scu_status = SCU_TASK_DONE_UNEXP_FIS;
-                       ireq->sci_status = SCI_FAILURE_PROTOCOL_VIOLATION;
-                       break;
-               }
-
-               sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
-
-               /* Frame has been decoded return it to the controller */
-               sci_controller_release_frame(ihost, frame_index);
-
-               return status;
-       }
        case SCI_REQ_ATAPI_WAIT_PIO_SETUP: {
                struct sas_task *task = isci_request_access_task(ireq);
 
@@ -2235,57 +2145,6 @@ static enum sci_status stp_request_udma_await_tc_event(struct isci_request *ireq
        return status;
 }
 
-static enum sci_status
-stp_request_soft_reset_await_h2d_asserted_tc_event(struct isci_request *ireq,
-                                                  u32 completion_code)
-{
-       switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
-       case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
-               ireq->scu_status = SCU_TASK_DONE_GOOD;
-               ireq->sci_status = SCI_SUCCESS;
-               sci_change_state(&ireq->sm, SCI_REQ_STP_SOFT_RESET_WAIT_H2D_DIAG);
-               break;
-
-       default:
-               /*
-                * All other completion status cause the IO to be complete.
-                * If a NAK was received, then it is up to the user to retry
-                * the request.
-                */
-               ireq->scu_status = SCU_NORMALIZE_COMPLETION_STATUS(completion_code);
-               ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
-               sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
-               break;
-       }
-
-       return SCI_SUCCESS;
-}
-
-static enum sci_status
-stp_request_soft_reset_await_h2d_diagnostic_tc_event(struct isci_request *ireq,
-                                                    u32 completion_code)
-{
-       switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
-       case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
-               ireq->scu_status = SCU_TASK_DONE_GOOD;
-               ireq->sci_status = SCI_SUCCESS;
-               sci_change_state(&ireq->sm, SCI_REQ_STP_SOFT_RESET_WAIT_D2H);
-               break;
-
-       default:
-               /* All other completion status cause the IO to be complete.  If
-                * a NAK was received, then it is up to the user to retry the
-                * request.
-                */
-               ireq->scu_status = SCU_NORMALIZE_COMPLETION_STATUS(completion_code);
-               ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
-               sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
-               break;
-       }
-
-       return SCI_SUCCESS;
-}
-
 static enum sci_status atapi_raw_completion(struct isci_request *ireq, u32 completion_code,
                                                  enum sci_base_request_states next)
 {
@@ -2431,14 +2290,6 @@ sci_io_request_tc_completion(struct isci_request *ireq,
        case SCI_REQ_STP_PIO_DATA_OUT:
                return pio_data_out_tx_done_tc_event(ireq, completion_code);
 
-       case SCI_REQ_STP_SOFT_RESET_WAIT_H2D_ASSERTED:
-               return stp_request_soft_reset_await_h2d_asserted_tc_event(ireq,
-                                                                         completion_code);
-
-       case SCI_REQ_STP_SOFT_RESET_WAIT_H2D_DIAG:
-               return stp_request_soft_reset_await_h2d_diagnostic_tc_event(ireq,
-                                                                           completion_code);
-
        case SCI_REQ_ABORTING:
                return request_aborting_state_tc_event(ireq,
                                                       completion_code);
@@ -3212,10 +3063,6 @@ static void sci_request_started_state_enter(struct sci_base_state_machine *sm)
         */
        if (!task && dev->dev_type == SAS_END_DEV) {
                state = SCI_REQ_TASK_WAIT_TC_COMP;
-       } else if (!task &&
-                  (isci_request_access_tmf(ireq)->tmf_code == isci_tmf_sata_srst_high ||
-                   isci_request_access_tmf(ireq)->tmf_code == isci_tmf_sata_srst_low)) {
-               state = SCI_REQ_STP_SOFT_RESET_WAIT_H2D_ASSERTED;
        } else if (task && task->task_proto == SAS_PROTOCOL_SMP) {
                state = SCI_REQ_SMP_WAIT_RESP;
        } else if (task && sas_protocol_ata(task->task_proto) &&
@@ -3272,31 +3119,6 @@ static void sci_stp_request_started_pio_await_h2d_completion_enter(struct sci_ba
        ireq->target_device->working_request = ireq;
 }
 
-static void sci_stp_request_started_soft_reset_await_h2d_asserted_completion_enter(struct sci_base_state_machine *sm)
-{
-       struct isci_request *ireq = container_of(sm, typeof(*ireq), sm);
-
-       ireq->target_device->working_request = ireq;
-}
-
-static void sci_stp_request_started_soft_reset_await_h2d_diagnostic_completion_enter(struct sci_base_state_machine *sm)
-{
-       struct isci_request *ireq = container_of(sm, typeof(*ireq), sm);
-       struct scu_task_context *tc = ireq->tc;
-       struct host_to_dev_fis *h2d_fis;
-       enum sci_status status;
-
-       /* Clear the SRST bit */
-       h2d_fis = &ireq->stp.cmd;
-       h2d_fis->control = 0;
-
-       /* Clear the TC control bit */
-       tc->control_frame = 0;
-
-       status = sci_controller_continue_io(ireq);
-       WARN_ONCE(status != SCI_SUCCESS, "isci: continue io failure\n");
-}
-
 static const struct sci_base_state sci_request_state_table[] = {
        [SCI_REQ_INIT] = { },
        [SCI_REQ_CONSTRUCTED] = { },
@@ -3315,13 +3137,6 @@ static const struct sci_base_state sci_request_state_table[] = {
        [SCI_REQ_STP_PIO_DATA_OUT] = { },
        [SCI_REQ_STP_UDMA_WAIT_TC_COMP] = { },
        [SCI_REQ_STP_UDMA_WAIT_D2H] = { },
-       [SCI_REQ_STP_SOFT_RESET_WAIT_H2D_ASSERTED] = {
-               .enter_state = sci_stp_request_started_soft_reset_await_h2d_asserted_completion_enter,
-       },
-       [SCI_REQ_STP_SOFT_RESET_WAIT_H2D_DIAG] = {
-               .enter_state = sci_stp_request_started_soft_reset_await_h2d_diagnostic_completion_enter,
-       },
-       [SCI_REQ_STP_SOFT_RESET_WAIT_D2H] = { },
        [SCI_REQ_TASK_WAIT_TC_COMP] = { },
        [SCI_REQ_TASK_WAIT_TC_RESP] = { },
        [SCI_REQ_SMP_WAIT_RESP] = { },
index be38933..bcf2f37 100644 (file)
@@ -211,10 +211,6 @@ enum sci_base_request_states {
        SCI_REQ_STP_NON_DATA_WAIT_H2D,
        SCI_REQ_STP_NON_DATA_WAIT_D2H,
 
-       SCI_REQ_STP_SOFT_RESET_WAIT_H2D_ASSERTED,
-       SCI_REQ_STP_SOFT_RESET_WAIT_H2D_DIAG,
-       SCI_REQ_STP_SOFT_RESET_WAIT_D2H,
-
        /*
         * While in this state the IO request object is waiting for the TC
         * completion notification for the H2D Register FIS
@@ -446,10 +442,7 @@ sci_task_request_construct(struct isci_host *ihost,
                            struct isci_remote_device *idev,
                            u16 io_tag,
                            struct isci_request *ireq);
-enum sci_status
-sci_task_request_construct_ssp(struct isci_request *ireq);
-enum sci_status
-sci_task_request_construct_sata(struct isci_request *ireq);
+enum sci_status sci_task_request_construct_ssp(struct isci_request *ireq);
 void sci_smp_request_copy_response(struct isci_request *ireq);
 
 static inline int isci_task_is_ncq_recovery(struct sas_task *task)
index c4d324c..3f04e97 100644 (file)
@@ -247,46 +247,6 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags)
        return 0;
 }
 
-static enum sci_status isci_sata_management_task_request_build(struct isci_request *ireq)
-{
-       struct isci_tmf *isci_tmf;
-       enum sci_status status;
-
-       if (!test_bit(IREQ_TMF, &ireq->flags))
-               return SCI_FAILURE;
-
-       isci_tmf = isci_request_access_tmf(ireq);
-
-       switch (isci_tmf->tmf_code) {
-
-       case isci_tmf_sata_srst_high:
-       case isci_tmf_sata_srst_low: {
-               struct host_to_dev_fis *fis = &ireq->stp.cmd;
-
-               memset(fis, 0, sizeof(*fis));
-
-               fis->fis_type  =  0x27;
-               fis->flags     &= ~0x80;
-               fis->flags     &= 0xF0;
-               if (isci_tmf->tmf_code == isci_tmf_sata_srst_high)
-                       fis->control |= ATA_SRST;
-               else
-                       fis->control &= ~ATA_SRST;
-               break;
-       }
-       /* other management commnd go here... */
-       default:
-               return SCI_FAILURE;
-       }
-
-       /* core builds the protocol specific request
-        *  based on the h2d fis.
-        */
-       status = sci_task_request_construct_sata(ireq);
-
-       return status;
-}
-
 static struct isci_request *isci_task_request_build(struct isci_host *ihost,
                                                    struct isci_remote_device *idev,
                                                    u16 tag, struct isci_tmf *isci_tmf)
@@ -326,13 +286,6 @@ static struct isci_request *isci_task_request_build(struct isci_host *ihost,
                        return NULL;
        }
 
-       if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) {
-               isci_tmf->proto = SAS_PROTOCOL_SATA;
-               status = isci_sata_management_task_request_build(ireq);
-
-               if (status != SCI_SUCCESS)
-                       return NULL;
-       }
        return ireq;
 }
 
@@ -871,53 +824,20 @@ static int isci_task_send_lu_reset_sas(
        return ret;
 }
 
-static int isci_task_send_lu_reset_sata(struct isci_host *ihost,
-                                struct isci_remote_device *idev, u8 *lun)
+int isci_task_lu_reset(struct domain_device *dev, u8 *lun)
 {
-       int ret = TMF_RESP_FUNC_FAILED;
-       struct isci_tmf tmf;
-
-       /* Send the soft reset to the target */
-       #define ISCI_SRST_TIMEOUT_MS 25000 /* 25 second timeout. */
-       isci_task_build_tmf(&tmf, isci_tmf_sata_srst_high, NULL, NULL);
-
-       ret = isci_task_execute_tmf(ihost, idev, &tmf, ISCI_SRST_TIMEOUT_MS);
-
-       if (ret != TMF_RESP_FUNC_COMPLETE) {
-               dev_dbg(&ihost->pdev->dev,
-                        "%s: Assert SRST failed (%p) = %x",
-                        __func__, idev, ret);
-
-               /* Return the failure so that the LUN reset is escalated
-                * to a target reset.
-                */
-       }
-       return ret;
-}
-
-/**
- * isci_task_lu_reset() - This function is one of the SAS Domain Template
- *    functions. This is one of the Task Management functoins called by libsas,
- *    to reset the given lun. Note the assumption that while this call is
- *    executing, no I/O will be sent by the host to the device.
- * @lun: This parameter specifies the lun to be reset.
- *
- * status, zero indicates success.
- */
-int isci_task_lu_reset(struct domain_device *domain_device, u8 *lun)
-{
-       struct isci_host *isci_host = dev_to_ihost(domain_device);
+       struct isci_host *isci_host = dev_to_ihost(dev);
        struct isci_remote_device *isci_device;
        unsigned long flags;
        int ret;
 
        spin_lock_irqsave(&isci_host->scic_lock, flags);
-       isci_device = isci_lookup_device(domain_device);
+       isci_device = isci_lookup_device(dev);
        spin_unlock_irqrestore(&isci_host->scic_lock, flags);
 
        dev_dbg(&isci_host->pdev->dev,
                "%s: domain_device=%p, isci_host=%p; isci_device=%p\n",
-                __func__, domain_device, isci_host, isci_device);
+                __func__, dev, isci_host, isci_device);
 
        if (!isci_device) {
                /* If the device is gone, stop the escalations. */
@@ -929,8 +849,9 @@ int isci_task_lu_reset(struct domain_device *domain_device, u8 *lun)
        set_bit(IDEV_EH, &isci_device->flags);
 
        /* Send the task management part of the reset. */
-       if (sas_protocol_ata(domain_device->tproto)) {
-               ret = isci_task_send_lu_reset_sata(isci_host, isci_device, lun);
+       if (dev_is_sata(dev)) {
+               sas_ata_schedule_reset(dev);
+               ret = TMF_RESP_FUNC_COMPLETE;
        } else
                ret = isci_task_send_lu_reset_sas(isci_host, isci_device, lun);
 
index bb472c3..5ba00c3 100644 (file)
@@ -86,8 +86,6 @@ enum isci_tmf_function_codes {
        isci_tmf_func_none      = 0,
        isci_tmf_ssp_task_abort = TMF_ABORT_TASK,
        isci_tmf_ssp_lun_reset  = TMF_LU_RESET,
-       isci_tmf_sata_srst_high = TMF_LU_RESET + 0x100, /* Non SCSI */
-       isci_tmf_sata_srst_low  = TMF_LU_RESET + 0x101  /* Non SCSI */
 };
 /**
  * struct isci_tmf - This class represents the task management object which
index 0cb538f..37a9e73 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/scatterlist.h>
 #include <linux/slab.h>
 #include <linux/async.h>
+#include <linux/export.h>
 
 #include <scsi/sas_ata.h>
 #include "sas_internal.h"
@@ -757,6 +758,7 @@ void sas_ata_schedule_reset(struct domain_device *dev)
        ata_port_schedule_eh(ap);
        spin_unlock_irqrestore(ap->lock, flags);
 }
+EXPORT_SYMBOL_GPL(sas_ata_schedule_reset);
 
 void sas_ata_wait_eh(struct domain_device *dev)
 {