/* * isci_task_request_complete() - This function is called by the sci core when * an task request completes. * @ihost: This parameter specifies the ISCI host object * @ireq: This parameter is the completed isci_request object. * @completion_status: This parameter specifies the completion status from the * sci core. * * none. */ void isci_task_request_complete(struct isci_host *ihost, struct isci_request *ireq, enum sci_task_status completion_status) { struct isci_tmf *tmf = isci_request_access_tmf(ireq); struct completion *tmf_complete = NULL; struct completion *request_complete = ireq->io_request_completion; dev_dbg(&ihost->pdev->dev, "%s: request = %p, status=%d\n", __func__, ireq, completion_status); isci_request_change_state(ireq, completed); set_bit(IREQ_COMPLETE_IN_TARGET, &ireq->flags); if (tmf) { tmf->status = completion_status; if (tmf->proto == SAS_PROTOCOL_SSP) { memcpy(&tmf->resp.resp_iu, &ireq->ssp.rsp, SSP_RESP_IU_MAX_SIZE); } else if (tmf->proto == SAS_PROTOCOL_SATA) { memcpy(&tmf->resp.d2h_fis, &ireq->stp.rsp, sizeof(struct dev_to_host_fis)); } /* PRINT_TMF( ((struct isci_tmf *)request->task)); */ tmf_complete = tmf->complete; } sci_controller_complete_io(ihost, ireq->target_device, ireq); /* set the 'terminated' flag handle to make sure it cannot be terminated * or completed again. */ set_bit(IREQ_TERMINATED, &ireq->flags); /* As soon as something is in the terminate path, deallocation is * managed there. Note that the final non-managed state of a task * request is "completed". */ if ((ireq->status == completed) || !isci_request_is_dealloc_managed(ireq->status)) { isci_request_change_state(ireq, unallocated); isci_free_tag(ihost, ireq->io_tag); list_del_init(&ireq->dev_node); } /* "request_complete" is set if the task was being terminated. */ if (request_complete) complete(request_complete); /* The task management part completes last. */ if (tmf_complete) complete(tmf_complete); }
/** * isci_request_mark_zombie() - This function must be called with scic_lock held. */ static void isci_request_mark_zombie(struct isci_host *ihost, struct isci_request *ireq) { struct completion *tmf_completion = NULL; struct completion *req_completion; /* Set the request state to "dead". */ ireq->status = dead; req_completion = ireq->io_request_completion; ireq->io_request_completion = NULL; if (test_bit(IREQ_TMF, &ireq->flags)) { /* Break links with the TMF request. */ struct isci_tmf *tmf = isci_request_access_tmf(ireq); /* In the case where a task request is dying, * the thread waiting on the complete will sit and * timeout unless we wake it now. Since the TMF * has a default error status, complete it here * to wake the waiting thread. */ if (tmf) { tmf_completion = tmf->complete; tmf->complete = NULL; } ireq->ttype_ptr.tmf_task_ptr = NULL; dev_dbg(&ihost->pdev->dev, "%s: tmf_code %d, managed tag %#x\n", __func__, tmf->tmf_code, tmf->io_tag); } else { /* Break links with the sas_task - the callback is done * elsewhere. */ struct sas_task *task = isci_request_access_task(ireq); if (task) task->lldd_task = NULL; ireq->ttype_ptr.io_task_ptr = NULL; } dev_warn(&ihost->pdev->dev, "task context unrecoverable (tag: %#x)\n", ireq->io_tag); /* Don't force waiting threads to timeout. */ if (req_completion) complete(req_completion); if (tmf_completion != NULL) complete(tmf_completion); }
void isci_task_request_complete(struct isci_host *ihost, struct isci_request *ireq, enum sci_task_status completion_status) { struct isci_tmf *tmf = isci_request_access_tmf(ireq); struct completion *tmf_complete = NULL; struct completion *request_complete = ireq->io_request_completion; dev_dbg(&ihost->pdev->dev, "%s: request = %p, status=%d\n", __func__, ireq, completion_status); isci_request_change_state(ireq, completed); set_bit(IREQ_COMPLETE_IN_TARGET, &ireq->flags); if (tmf) { tmf->status = completion_status; if (tmf->proto == SAS_PROTOCOL_SSP) { memcpy(&tmf->resp.resp_iu, &ireq->ssp.rsp, SSP_RESP_IU_MAX_SIZE); } else if (tmf->proto == SAS_PROTOCOL_SATA) { memcpy(&tmf->resp.d2h_fis, &ireq->stp.rsp, sizeof(struct dev_to_host_fis)); } tmf_complete = tmf->complete; } sci_controller_complete_io(ihost, ireq->target_device, ireq); set_bit(IREQ_TERMINATED, &ireq->flags); if ((ireq->status == completed) || !isci_request_is_dealloc_managed(ireq->status)) { isci_request_change_state(ireq, unallocated); isci_free_tag(ihost, ireq->io_tag); list_del_init(&ireq->dev_node); } if (request_complete) complete(request_complete); if (tmf_complete) complete(tmf_complete); }
/* * isci_task_request_complete() - This function is called by the sci core when * an task request completes. * @ihost: This parameter specifies the ISCI host object * @ireq: This parameter is the completed isci_request object. * @completion_status: This parameter specifies the completion status from the * sci core. * * none. */ void isci_task_request_complete(struct isci_host *ihost, struct isci_request *ireq, enum sci_task_status completion_status) { struct isci_tmf *tmf = isci_request_access_tmf(ireq); struct completion *tmf_complete = NULL; dev_dbg(&ihost->pdev->dev, "%s: request = %p, status=%d\n", __func__, ireq, completion_status); set_bit(IREQ_COMPLETE_IN_TARGET, &ireq->flags); if (tmf) { tmf->status = completion_status; if (tmf->proto == SAS_PROTOCOL_SSP) { memcpy(&tmf->resp.resp_iu, &ireq->ssp.rsp, SSP_RESP_IU_MAX_SIZE); } else if (tmf->proto == SAS_PROTOCOL_SATA) { memcpy(&tmf->resp.d2h_fis, &ireq->stp.rsp, sizeof(struct dev_to_host_fis)); } /* PRINT_TMF( ((struct isci_tmf *)request->task)); */ tmf_complete = tmf->complete; } sci_controller_complete_io(ihost, ireq->target_device, ireq); /* set the 'terminated' flag handle to make sure it cannot be terminated * or completed again. */ set_bit(IREQ_TERMINATED, &ireq->flags); if (test_and_clear_bit(IREQ_ABORT_PATH_ACTIVE, &ireq->flags)) wake_up_all(&ihost->eventq); if (!test_bit(IREQ_NO_AUTO_FREE_TAG, &ireq->flags)) isci_free_tag(ihost, ireq->io_tag); /* The task management part completes last. */ if (tmf_complete) complete(tmf_complete); }
static void isci_request_mark_zombie(struct isci_host *ihost, struct isci_request *ireq) { struct completion *tmf_completion = NULL; struct completion *req_completion; ireq->status = dead; req_completion = ireq->io_request_completion; ireq->io_request_completion = NULL; if (test_bit(IREQ_TMF, &ireq->flags)) { struct isci_tmf *tmf = isci_request_access_tmf(ireq); if (tmf) { tmf_completion = tmf->complete; tmf->complete = NULL; } ireq->ttype_ptr.tmf_task_ptr = NULL; dev_dbg(&ihost->pdev->dev, "%s: tmf_code %d, managed tag %#x\n", __func__, tmf->tmf_code, tmf->io_tag); } else { struct sas_task *task = isci_request_access_task(ireq); if (task) task->lldd_task = NULL; ireq->ttype_ptr.io_task_ptr = NULL; } dev_warn(&ihost->pdev->dev, "task context unrecoverable (tag: %#x)\n", ireq->io_tag); if (req_completion) complete(req_completion); if (tmf_completion != NULL) complete(tmf_completion); }