// SPDX-License-Identifier: GPL-2.0-only /* * Aic94xx Task Management Functions * * Copyright (C) 2005 Adaptec, Inc. All rights reserved. * Copyright (C) 2005 Luben Tuikov <[email protected]> */ #include <linux/spinlock.h> #include <linux/gfp.h> #include "aic94xx.h" #include "aic94xx_sas.h" #include "aic94xx_hwi.h" /* ---------- Internal enqueue ---------- */ static int asd_enqueue_internal(struct asd_ascb *ascb, void (*tasklet_complete)(struct asd_ascb *, struct done_list_struct *), void (*timed_out)(struct timer_list *t)) { … } /* ---------- CLEAR NEXUS ---------- */ struct tasklet_completion_status { … }; #define DECLARE_TCS(tcs) … static void asd_clear_nexus_tasklet_complete(struct asd_ascb *ascb, struct done_list_struct *dl) { … } static void asd_clear_nexus_timedout(struct timer_list *t) { … } #define CLEAR_NEXUS_PRE … #define CLEAR_NEXUS_POST … int asd_clear_nexus_ha(struct sas_ha_struct *sas_ha) { … } int asd_clear_nexus_port(struct asd_sas_port *port) { … } enum clear_nexus_phase { … }; static int asd_clear_nexus_I_T(struct domain_device *dev, enum clear_nexus_phase phase) { … } int asd_I_T_nexus_reset(struct domain_device *dev) { … } static int asd_clear_nexus_I_T_L(struct domain_device *dev, u8 *lun) { … } static int asd_clear_nexus_tag(struct sas_task *task) { … } static int asd_clear_nexus_index(struct sas_task *task) { … } /* ---------- TMFs ---------- */ static void asd_tmf_timedout(struct timer_list *t) { … } static int asd_get_tmf_resp_tasklet(struct asd_ascb *ascb, struct done_list_struct *dl) { … } static void asd_tmf_tasklet_complete(struct asd_ascb *ascb, struct done_list_struct *dl) { … } static int asd_clear_nexus(struct sas_task *task) { … } /** * asd_abort_task -- ABORT TASK TMF * @task: the task to be aborted * * Before calling ABORT TASK the task state flags should be ORed with * SAS_TASK_STATE_ABORTED (unless SAS_TASK_STATE_DONE is set) under * the task_state_lock IRQ spinlock, then ABORT TASK *must* be called. * * Implements the ABORT TASK TMF, I_T_L_Q nexus. * Returns: SAS TMF responses (see sas_task.h), * -ENOMEM, * -SAS_QUEUE_FULL. * * When ABORT TASK returns, the caller of ABORT TASK checks first the * task->task_state_flags, and then the return value of ABORT TASK. * * If the task has task state bit SAS_TASK_STATE_DONE set, then the * task was completed successfully prior to it being aborted. The * caller of ABORT TASK has responsibility to call task->task_done() * xor free the task, depending on their framework. The return code * is TMF_RESP_FUNC_FAILED in this case. * * Else the SAS_TASK_STATE_DONE bit is not set, * If the return code is TMF_RESP_FUNC_COMPLETE, then * the task was aborted successfully. The caller of * ABORT TASK has responsibility to call task->task_done() * to finish the task, xor free the task depending on their * framework. * else * the ABORT TASK returned some kind of error. The task * was _not_ cancelled. Nothing can be assumed. * The caller of ABORT TASK may wish to retry. */ int asd_abort_task(struct sas_task *task) { … } /** * asd_initiate_ssp_tmf -- send a TMF to an I_T_L or I_T_L_Q nexus * @dev: pointer to struct domain_device of interest * @lun: pointer to u8[8] which is the LUN * @tmf: the TMF to be performed (see sas_task.h or the SAS spec) * @index: the transaction context of the task to be queried if QT TMF * * This function is used to send ABORT TASK SET, CLEAR ACA, * CLEAR TASK SET, LU RESET and QUERY TASK TMFs. * * No SCBs should be queued to the I_T_L nexus when this SCB is * pending. * * Returns: TMF response code (see sas_task.h or the SAS spec) */ static int asd_initiate_ssp_tmf(struct domain_device *dev, u8 *lun, int tmf, int index) { … } int asd_abort_task_set(struct domain_device *dev, u8 *lun) { … } int asd_clear_task_set(struct domain_device *dev, u8 *lun) { … } int asd_lu_reset(struct domain_device *dev, u8 *lun) { … } /** * asd_query_task -- send a QUERY TASK TMF to an I_T_L_Q nexus * @task: pointer to sas_task struct of interest * * Returns: TMF_RESP_FUNC_COMPLETE if the task is not in the task set, * or TMF_RESP_FUNC_SUCC if the task is in the task set. * * Normally the management layer sets the task to aborted state, * and then calls query task and then abort task. */ int asd_query_task(struct sas_task *task) { … }