Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  *  linux/drivers/scsi/esas2r/esas2r_int.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *      esas2r interrupt handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *  Copyright (c) 2001-2013 ATTO Technology, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *  (mailto:linuxdrivers@attotech.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *  This program is free software; you can redistribute it and/or modify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  *  it under the terms of the GNU General Public License as published by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  *  the Free Software Foundation; version 2 of the License.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  *  This program is distributed in the hope that it will be useful,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  *  GNU General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  *  NO WARRANTY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  *  THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  *  CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  *  LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  *  MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  *  solely responsible for determining the appropriateness of using and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  *  distributing the Program and assumes all risks associated with its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  *  exercise of rights under this Agreement, including but not limited to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  *  the risks and costs of program errors, damage to or loss of data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  *  programs or equipment, and unavailability or interruption of operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  *  DISCLAIMER OF LIABILITY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  *  NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  *  DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  *  USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  *  HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  *  You should have received a copy of the GNU General Public License
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  *  along with this program; if not, write to the Free Software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #include "esas2r.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) /* Local function prototypes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) static void esas2r_doorbell_interrupt(struct esas2r_adapter *a, u32 doorbell);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) static void esas2r_get_outbound_responses(struct esas2r_adapter *a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) static void esas2r_process_bus_reset(struct esas2r_adapter *a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)  * Poll the adapter for interrupts and service them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)  * This function handles both legacy interrupts and MSI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) void esas2r_polled_interrupt(struct esas2r_adapter *a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	u32 intstat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	u32 doorbell;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	esas2r_disable_chip_interrupts(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	intstat = esas2r_read_register_dword(a, MU_INT_STATUS_OUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	if (intstat & MU_INTSTAT_POST_OUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 		/* clear the interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 		esas2r_write_register_dword(a, MU_OUT_LIST_INT_STAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 					    MU_OLIS_INT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		esas2r_flush_register_dword(a, MU_OUT_LIST_INT_STAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		esas2r_get_outbound_responses(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	if (intstat & MU_INTSTAT_DRBL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		doorbell = esas2r_read_register_dword(a, MU_DOORBELL_OUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		if (doorbell != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 			esas2r_doorbell_interrupt(a, doorbell);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	esas2r_enable_chip_interrupts(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	if (atomic_read(&a->disable_cnt) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		esas2r_do_deferred_processes(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88)  * Legacy and MSI interrupt handlers.  Note that the legacy interrupt handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)  * schedules a TASKLET to process events, whereas the MSI handler just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)  * processes interrupt events directly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) irqreturn_t esas2r_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	struct esas2r_adapter *a = (struct esas2r_adapter *)dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	if (!esas2r_adapter_interrupt_pending(a))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	set_bit(AF2_INT_PENDING, &a->flags2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	esas2r_schedule_tasklet(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) void esas2r_adapter_interrupt(struct esas2r_adapter *a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	u32 doorbell;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	if (likely(a->int_stat & MU_INTSTAT_POST_OUT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		/* clear the interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		esas2r_write_register_dword(a, MU_OUT_LIST_INT_STAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 					    MU_OLIS_INT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		esas2r_flush_register_dword(a, MU_OUT_LIST_INT_STAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		esas2r_get_outbound_responses(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	if (unlikely(a->int_stat & MU_INTSTAT_DRBL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		doorbell = esas2r_read_register_dword(a, MU_DOORBELL_OUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		if (doorbell != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 			esas2r_doorbell_interrupt(a, doorbell);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	a->int_mask = ESAS2R_INT_STS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	esas2r_enable_chip_interrupts(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	if (likely(atomic_read(&a->disable_cnt) == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		esas2r_do_deferred_processes(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) irqreturn_t esas2r_msi_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	struct esas2r_adapter *a = (struct esas2r_adapter *)dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	u32 intstat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	u32 doorbell;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	intstat = esas2r_read_register_dword(a, MU_INT_STATUS_OUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	if (likely(intstat & MU_INTSTAT_POST_OUT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		/* clear the interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		esas2r_write_register_dword(a, MU_OUT_LIST_INT_STAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 					    MU_OLIS_INT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		esas2r_flush_register_dword(a, MU_OUT_LIST_INT_STAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 		esas2r_get_outbound_responses(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	if (unlikely(intstat & MU_INTSTAT_DRBL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		doorbell = esas2r_read_register_dword(a, MU_DOORBELL_OUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		if (doorbell != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 			esas2r_doorbell_interrupt(a, doorbell);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	 * Work around a chip bug and force a new MSI to be sent if one is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	 * still pending.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	esas2r_disable_chip_interrupts(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	esas2r_enable_chip_interrupts(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	if (likely(atomic_read(&a->disable_cnt) == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		esas2r_do_deferred_processes(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	esas2r_do_tasklet_tasks(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static void esas2r_handle_outbound_rsp_err(struct esas2r_adapter *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 					   struct esas2r_request *rq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 					   struct atto_vda_ob_rsp *rsp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	 * For I/O requests, only copy the response if an error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	 * occurred and setup a callback to do error processing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	if (unlikely(rq->req_stat != RS_SUCCESS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 		memcpy(&rq->func_rsp, &rsp->func_rsp, sizeof(rsp->func_rsp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		if (rq->req_stat == RS_ABORTED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 			if (rq->timeout > RQ_MAX_TIMEOUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 				rq->req_stat = RS_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		} else if (rq->req_stat == RS_SCSI_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 			u8 scsistatus = rq->func_rsp.scsi_rsp.scsi_stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 			esas2r_trace("scsistatus: %x", scsistatus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 			/* Any of these are a good result. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 			if (scsistatus == SAM_STAT_GOOD || scsistatus ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 			    SAM_STAT_CONDITION_MET || scsistatus ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 			    SAM_STAT_INTERMEDIATE || scsistatus ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 			    SAM_STAT_INTERMEDIATE_CONDITION_MET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 				rq->req_stat = RS_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 				rq->func_rsp.scsi_rsp.scsi_stat =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 					SAM_STAT_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static void esas2r_get_outbound_responses(struct esas2r_adapter *a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	struct atto_vda_ob_rsp *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	u32 rspput_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	u32 rspget_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	struct esas2r_request *rq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	u32 handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	LIST_HEAD(comp_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	esas2r_trace_enter();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	spin_lock_irqsave(&a->queue_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	/* Get the outbound limit and pointers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	rspput_ptr = le32_to_cpu(*a->outbound_copy) & MU_OLC_WRT_PTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	rspget_ptr = a->last_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	esas2r_trace("rspput_ptr: %x, rspget_ptr: %x", rspput_ptr, rspget_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	/* If we don't have anything to process, get out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	if (unlikely(rspget_ptr == rspput_ptr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		spin_unlock_irqrestore(&a->queue_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		esas2r_trace_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	/* Make sure the firmware is healthy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	if (unlikely(rspput_ptr >= a->list_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		spin_unlock_irqrestore(&a->queue_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		esas2r_bugon();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		esas2r_local_reset_adapter(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 		esas2r_trace_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		rspget_ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		if (rspget_ptr >= a->list_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 			rspget_ptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 		rsp = (struct atto_vda_ob_rsp *)a->outbound_list_md.virt_addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 		      + rspget_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 		handle = rsp->handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 		/* Verify the handle range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 		if (unlikely(LOWORD(handle) == 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 			     || LOWORD(handle) > num_requests +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 			     num_ae_requests + 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 			esas2r_bugon();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		/* Get the request for this handle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		rq = a->req_table[LOWORD(handle)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 		if (unlikely(rq == NULL || rq->vrq->scsi.handle != handle)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 			esas2r_bugon();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		list_del(&rq->req_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 		/* Get the completion status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 		rq->req_stat = rsp->req_stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 		esas2r_trace("handle: %x", handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		esas2r_trace("rq: %p", rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 		esas2r_trace("req_status: %x", rq->req_stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 		if (likely(rq->vrq->scsi.function == VDA_FUNC_SCSI)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 			esas2r_handle_outbound_rsp_err(a, rq, rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 			 * Copy the outbound completion struct for non-I/O
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 			 * requests.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 			memcpy(&rq->func_rsp, &rsp->func_rsp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 			       sizeof(rsp->func_rsp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		/* Queue the request for completion. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		list_add_tail(&rq->comp_list, &comp_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	} while (rspget_ptr != rspput_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	a->last_read = rspget_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	spin_unlock_irqrestore(&a->queue_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	esas2r_comp_list_drain(a, &comp_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	esas2r_trace_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)  * Perform all deferred processes for the adapter.  Deferred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)  * processes can only be done while the current interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)  * disable_cnt for the adapter is zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) void esas2r_do_deferred_processes(struct esas2r_adapter *a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	int startreqs = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	struct esas2r_request *rq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	 * startreqs is used to control starting requests
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	 * that are on the deferred queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	 *  = 0 - do not start any requests
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	 *  = 1 - can start discovery requests
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	 *  = 2 - can start any request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	if (test_bit(AF_CHPRST_PENDING, &a->flags) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	    test_bit(AF_FLASHING, &a->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		startreqs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	else if (test_bit(AF_DISC_PENDING, &a->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 		startreqs = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	atomic_inc(&a->disable_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	/* Clear off the completed list to be processed later. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	if (esas2r_is_tasklet_pending(a)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 		esas2r_schedule_tasklet(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 		startreqs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	 * If we can start requests then traverse the defer queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	 * looking for requests to start or complete
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	if (startreqs && !list_empty(&a->defer_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 		LIST_HEAD(comp_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 		struct list_head *element, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 		spin_lock_irqsave(&a->queue_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 		list_for_each_safe(element, next, &a->defer_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 			rq = list_entry(element, struct esas2r_request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 					req_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 			if (rq->req_stat != RS_PENDING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 				list_del(element);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 				list_add_tail(&rq->comp_list, &comp_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 			 * Process discovery and OS requests separately.  We
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 			 * can't hold up discovery requests when discovery is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 			 * pending.  In general, there may be different sets of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 			 * conditions for starting different types of requests.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 			else if (rq->req_type == RT_DISC_REQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 				list_del(element);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 				esas2r_disc_local_start_request(a, rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 			} else if (startreqs == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 				list_del(element);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 				esas2r_local_start_request(a, rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 				 * Flashing could have been set by last local
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 				 * start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 				if (test_bit(AF_FLASHING, &a->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 		spin_unlock_irqrestore(&a->queue_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 		esas2r_comp_list_drain(a, &comp_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	atomic_dec(&a->disable_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)  * Process an adapter reset (or one that is about to happen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)  * by making sure all outstanding requests are completed that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)  * haven't been already.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) void esas2r_process_adapter_reset(struct esas2r_adapter *a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	struct esas2r_request *rq = &a->general_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	struct esas2r_disc_context *dc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	LIST_HEAD(comp_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	struct list_head *element;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	esas2r_trace_enter();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	spin_lock_irqsave(&a->queue_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	/* abort the active discovery, if any.   */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	if (rq->interrupt_cx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 		dc = (struct esas2r_disc_context *)rq->interrupt_cx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 		dc->disc_evt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 		clear_bit(AF_DISC_IN_PROG, &a->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	 * just clear the interrupt callback for now.  it will be dequeued if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	 * and when we find it on the active queue and we don't want the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	 * callback called.  also set the dummy completion callback in case we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	 * were doing an I/O request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	rq->interrupt_cx = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	rq->interrupt_cb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	rq->comp_cb = esas2r_dummy_complete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	/* Reset the read and write pointers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	*a->outbound_copy =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 		a->last_write =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 			a->last_read = a->list_size - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	set_bit(AF_COMM_LIST_TOGGLE, &a->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	/* Kill all the requests on the active list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	list_for_each(element, &a->defer_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 		rq = list_entry(element, struct esas2r_request, req_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 		if (rq->req_stat == RS_STARTED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 			if (esas2r_ioreq_aborted(a, rq, RS_ABORTED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 				list_add_tail(&rq->comp_list, &comp_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	spin_unlock_irqrestore(&a->queue_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	esas2r_comp_list_drain(a, &comp_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	esas2r_process_bus_reset(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	esas2r_trace_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) static void esas2r_process_bus_reset(struct esas2r_adapter *a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	struct esas2r_request *rq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	struct list_head *element;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	LIST_HEAD(comp_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	esas2r_trace_enter();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	esas2r_hdebug("reset detected");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	spin_lock_irqsave(&a->queue_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	/* kill all the requests on the deferred queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	list_for_each(element, &a->defer_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 		rq = list_entry(element, struct esas2r_request, req_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 		if (esas2r_ioreq_aborted(a, rq, RS_ABORTED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 			list_add_tail(&rq->comp_list, &comp_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	spin_unlock_irqrestore(&a->queue_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	esas2r_comp_list_drain(a, &comp_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 	if (atomic_read(&a->disable_cnt) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 		esas2r_do_deferred_processes(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	clear_bit(AF_OS_RESET, &a->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	esas2r_trace_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) static void esas2r_chip_rst_needed_during_tasklet(struct esas2r_adapter *a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	clear_bit(AF_CHPRST_NEEDED, &a->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	clear_bit(AF_BUSRST_NEEDED, &a->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	clear_bit(AF_BUSRST_DETECTED, &a->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	clear_bit(AF_BUSRST_PENDING, &a->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	 * Make sure we don't get attempt more than 3 resets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	 * when the uptime between resets does not exceed one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	 * minute.  This will stop any situation where there is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	 * really something wrong with the hardware.  The way
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	 * this works is that we start with uptime ticks at 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	 * Each time we do a reset, we add 20 seconds worth to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	 * the count.  Each time a timer tick occurs, as long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	 * as a chip reset is not pending, we decrement the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	 * tick count.  If the uptime ticks ever gets to 60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	 * seconds worth, we disable the adapter from that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	 * point forward.  Three strikes, you're out.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	if (!esas2r_is_adapter_present(a) || (a->chip_uptime >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 					      ESAS2R_CHP_UPTIME_MAX)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 		esas2r_hdebug("*** adapter disabled ***");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 		 * Ok, some kind of hard failure.  Make sure we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 		 * exit this loop with chip interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 		 * permanently disabled so we don't lock up the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 		 * entire system.  Also flag degraded mode to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 		 * prevent the heartbeat from trying to recover.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 		set_bit(AF_DEGRADED_MODE, &a->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 		set_bit(AF_DISABLED, &a->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 		clear_bit(AF_CHPRST_PENDING, &a->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 		clear_bit(AF_DISC_PENDING, &a->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 		esas2r_disable_chip_interrupts(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 		a->int_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 		esas2r_process_adapter_reset(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 		esas2r_log(ESAS2R_LOG_CRIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 			   "Adapter disabled because of hardware failure");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 		bool alrdyrst = test_and_set_bit(AF_CHPRST_STARTED, &a->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 		if (!alrdyrst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 			 * Only disable interrupts if this is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 			 * the first reset attempt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 			esas2r_disable_chip_interrupts(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 		if ((test_bit(AF_POWER_MGT, &a->flags)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 		    !test_bit(AF_FIRST_INIT, &a->flags) && !alrdyrst) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 			 * Don't reset the chip on the first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 			 * deferred power up attempt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 			esas2r_hdebug("*** resetting chip ***");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 			esas2r_reset_chip(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 		/* Kick off the reinitialization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 		a->chip_uptime += ESAS2R_CHP_UPTIME_CNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 		a->chip_init_time = jiffies_to_msecs(jiffies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 		if (!test_bit(AF_POWER_MGT, &a->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 			esas2r_process_adapter_reset(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 			if (!alrdyrst) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 				/* Remove devices now that I/O is cleaned up. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 				a->prev_dev_cnt =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 					esas2r_targ_db_get_tgt_cnt(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 				esas2r_targ_db_remove_all(a, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 		a->int_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) static void esas2r_handle_chip_rst_during_tasklet(struct esas2r_adapter *a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 	while (test_bit(AF_CHPRST_DETECTED, &a->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 		 * Balance the enable in esas2r_initadapter_hw.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 		 * Esas2r_power_down already took care of it for power
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 		 * management.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 		if (!test_bit(AF_DEGRADED_MODE, &a->flags) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 		    !test_bit(AF_POWER_MGT, &a->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 			esas2r_disable_chip_interrupts(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 		/* Reinitialize the chip. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 		esas2r_check_adapter(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 		esas2r_init_adapter_hw(a, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 		if (test_bit(AF_CHPRST_NEEDED, &a->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 		if (test_bit(AF_POWER_MGT, &a->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 			/* Recovery from power management. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 			if (test_bit(AF_FIRST_INIT, &a->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 				/* Chip reset during normal power up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 				esas2r_log(ESAS2R_LOG_CRIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 					   "The firmware was reset during a normal power-up sequence");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 				/* Deferred power up complete. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 				clear_bit(AF_POWER_MGT, &a->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 				esas2r_send_reset_ae(a, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 			/* Recovery from online chip reset. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 			if (test_bit(AF_FIRST_INIT, &a->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 				/* Chip reset during driver load */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 				/* Chip reset after driver load */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 				esas2r_send_reset_ae(a, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 			esas2r_log(ESAS2R_LOG_CRIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 				   "Recovering from a chip reset while the chip was online");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 		clear_bit(AF_CHPRST_STARTED, &a->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 		esas2r_enable_chip_interrupts(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 		 * Clear this flag last!  this indicates that the chip has been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 		 * reset already during initialization.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 		clear_bit(AF_CHPRST_DETECTED, &a->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) /* Perform deferred tasks when chip interrupts are disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) void esas2r_do_tasklet_tasks(struct esas2r_adapter *a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 	if (test_bit(AF_CHPRST_NEEDED, &a->flags) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	    test_bit(AF_CHPRST_DETECTED, &a->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 		if (test_bit(AF_CHPRST_NEEDED, &a->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 			esas2r_chip_rst_needed_during_tasklet(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 		esas2r_handle_chip_rst_during_tasklet(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 	if (test_bit(AF_BUSRST_NEEDED, &a->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 		esas2r_hdebug("hard resetting bus");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 		clear_bit(AF_BUSRST_NEEDED, &a->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 		if (test_bit(AF_FLASHING, &a->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 			set_bit(AF_BUSRST_DETECTED, &a->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 			esas2r_write_register_dword(a, MU_DOORBELL_IN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 						    DRBL_RESET_BUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 	if (test_bit(AF_BUSRST_DETECTED, &a->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 		esas2r_process_bus_reset(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 		esas2r_log_dev(ESAS2R_LOG_WARN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 			       &(a->host->shost_gendev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 			       "scsi_report_bus_reset() called");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 		scsi_report_bus_reset(a->host, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 		clear_bit(AF_BUSRST_DETECTED, &a->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 		clear_bit(AF_BUSRST_PENDING, &a->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 		esas2r_log(ESAS2R_LOG_WARN, "Bus reset complete");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 	if (test_bit(AF_PORT_CHANGE, &a->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 		clear_bit(AF_PORT_CHANGE, &a->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 		esas2r_targ_db_report_changes(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 	if (atomic_read(&a->disable_cnt) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 		esas2r_do_deferred_processes(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) static void esas2r_doorbell_interrupt(struct esas2r_adapter *a, u32 doorbell)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 	if (!(doorbell & DRBL_FORCE_INT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 		esas2r_trace_enter();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 		esas2r_trace("doorbell: %x", doorbell);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 	/* First clear the doorbell bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 	esas2r_write_register_dword(a, MU_DOORBELL_OUT, doorbell);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 	if (doorbell & DRBL_RESET_BUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 		set_bit(AF_BUSRST_DETECTED, &a->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 	if (doorbell & DRBL_FORCE_INT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 		clear_bit(AF_HEARTBEAT, &a->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 	if (doorbell & DRBL_PANIC_REASON_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 		esas2r_hdebug("*** Firmware Panic ***");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 		esas2r_log(ESAS2R_LOG_CRIT, "The firmware has panicked");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 	if (doorbell & DRBL_FW_RESET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 		set_bit(AF2_COREDUMP_AVAIL, &a->flags2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 		esas2r_local_reset_adapter(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 	if (!(doorbell & DRBL_FORCE_INT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 		esas2r_trace_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) void esas2r_force_interrupt(struct esas2r_adapter *a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	esas2r_write_register_dword(a, MU_DOORBELL_IN, DRBL_FORCE_INT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 				    DRBL_DRV_VER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) static void esas2r_lun_event(struct esas2r_adapter *a, union atto_vda_ae *ae,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 			     u16 target, u32 length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 	struct esas2r_target *t = a->targetdb + target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 	u32 cplen = length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 	if (cplen > sizeof(t->lu_event))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 		cplen = sizeof(t->lu_event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 	esas2r_trace("ae->lu.dwevent: %x", ae->lu.dwevent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 	esas2r_trace("ae->lu.bystate: %x", ae->lu.bystate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 	spin_lock_irqsave(&a->mem_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 	t->new_target_state = TS_INVALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 	if (ae->lu.dwevent  & VDAAE_LU_LOST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 		t->new_target_state = TS_NOT_PRESENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 		switch (ae->lu.bystate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 		case VDAAE_LU_NOT_PRESENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 		case VDAAE_LU_OFFLINE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 		case VDAAE_LU_DELETED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 		case VDAAE_LU_FACTORY_DISABLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 			t->new_target_state = TS_NOT_PRESENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 		case VDAAE_LU_ONLINE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 		case VDAAE_LU_DEGRADED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 			t->new_target_state = TS_PRESENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	if (t->new_target_state != TS_INVALID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 		memcpy(&t->lu_event, &ae->lu, cplen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 		esas2r_disc_queue_event(a, DCDE_DEV_CHANGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 	spin_unlock_irqrestore(&a->mem_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) void esas2r_ae_complete(struct esas2r_adapter *a, struct esas2r_request *rq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 	union atto_vda_ae *ae =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 		(union atto_vda_ae *)rq->vda_rsp_data->ae_data.event_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 	u32 length = le32_to_cpu(rq->func_rsp.ae_rsp.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 	union atto_vda_ae *last =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 		(union atto_vda_ae *)(rq->vda_rsp_data->ae_data.event_data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 				      + length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 	esas2r_trace_enter();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 	esas2r_trace("length: %d", length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 	if (length > sizeof(struct atto_vda_ae_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 	    || (length & 3) != 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 	    || length == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 		esas2r_log(ESAS2R_LOG_WARN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 			   "The AE request response length (%p) is too long: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 			   rq, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 		esas2r_hdebug("aereq->length (0x%x) too long", length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 		esas2r_bugon();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 		last = ae;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 	while (ae < last) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 		u16 target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 		esas2r_trace("ae: %p", ae);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 		esas2r_trace("ae->hdr: %p", &(ae->hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 		length = ae->hdr.bylength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 		if (length > (u32)((u8 *)last - (u8 *)ae)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 		    || (length & 3) != 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 		    || length == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 			esas2r_log(ESAS2R_LOG_CRIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 				   "the async event length is invalid (%p): %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 				   ae, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 			esas2r_hdebug("ae->hdr.length (0x%x) invalid", length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 			esas2r_bugon();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 		esas2r_nuxi_ae_data(ae);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 		esas2r_queue_fw_event(a, fw_event_vda_ae, ae,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) 				      sizeof(union atto_vda_ae));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 		switch (ae->hdr.bytype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 		case VDAAE_HDR_TYPE_RAID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 			if (ae->raid.dwflags & (VDAAE_GROUP_STATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 						| VDAAE_RBLD_STATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 						| VDAAE_MEMBER_CHG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 						| VDAAE_PART_CHG)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 				esas2r_log(ESAS2R_LOG_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 					   "RAID event received - name:%s rebuild_state:%d group_state:%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 					   ae->raid.acname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 					   ae->raid.byrebuild_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 					   ae->raid.bygroup_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 		case VDAAE_HDR_TYPE_LU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 			esas2r_log(ESAS2R_LOG_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) 				   "LUN event received: event:%d target_id:%d LUN:%d state:%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) 				   ae->lu.dwevent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 				   ae->lu.id.tgtlun.wtarget_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 				   ae->lu.id.tgtlun.bylun,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) 				   ae->lu.bystate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) 			target = ae->lu.id.tgtlun.wtarget_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) 			if (target < ESAS2R_MAX_TARGETS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) 				esas2r_lun_event(a, ae, target, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 		case VDAAE_HDR_TYPE_DISK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) 			esas2r_log(ESAS2R_LOG_INFO, "Disk event received");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) 			/* Silently ignore the rest and let the apps deal with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) 			 * them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) 		ae = (union atto_vda_ae *)((u8 *)ae + length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) 	/* Now requeue it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) 	esas2r_start_ae_request(a, rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) 	esas2r_trace_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) /* Send an asynchronous event for a chip reset or power management. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) void esas2r_send_reset_ae(struct esas2r_adapter *a, bool pwr_mgt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) 	struct atto_vda_ae_hdr ae;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) 	if (pwr_mgt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) 		ae.bytype = VDAAE_HDR_TYPE_PWRMGT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) 		ae.bytype = VDAAE_HDR_TYPE_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) 	ae.byversion = VDAAE_HDR_VER_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) 	ae.byflags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) 	ae.bylength = (u8)sizeof(struct atto_vda_ae_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) 	if (pwr_mgt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) 		esas2r_hdebug("*** sending power management AE ***");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) 		esas2r_hdebug("*** sending reset AE ***");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) 	esas2r_queue_fw_event(a, fw_event_vda_ae, &ae,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) 			      sizeof(union atto_vda_ae));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) void esas2r_dummy_complete(struct esas2r_adapter *a, struct esas2r_request *rq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) static void esas2r_check_req_rsp_sense(struct esas2r_adapter *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) 				       struct esas2r_request *rq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) 	u8 snslen, snslen2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) 	snslen = snslen2 = rq->func_rsp.scsi_rsp.sense_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) 	if (snslen > rq->sense_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) 		snslen = rq->sense_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) 	if (snslen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) 		if (rq->sense_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) 			memcpy(rq->sense_buf, rq->data_buf, snslen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) 			rq->sense_buf = (u8 *)rq->data_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) 		/* See about possible sense data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) 		if (snslen2 > 0x0c) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) 			u8 *s = (u8 *)rq->data_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) 			esas2r_trace_enter();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) 			/* Report LUNS data has changed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) 			if (s[0x0c] == 0x3f && s[0x0d] == 0x0E) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) 				esas2r_trace("rq->target_id: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) 					     rq->target_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) 				esas2r_target_state_changed(a, rq->target_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) 							    TS_LUN_CHANGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) 			esas2r_trace("add_sense_key=%x", s[0x0c]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) 			esas2r_trace("add_sense_qual=%x", s[0x0d]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) 			esas2r_trace_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) 	rq->sense_len = snslen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) void esas2r_complete_request(struct esas2r_adapter *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) 			     struct esas2r_request *rq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) 	if (rq->vrq->scsi.function == VDA_FUNC_FLASH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) 	    && rq->vrq->flash.sub_func == VDA_FLASH_COMMIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) 		clear_bit(AF_FLASHING, &a->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) 	/* See if we setup a callback to do special processing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) 	if (rq->interrupt_cb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) 		(*rq->interrupt_cb)(a, rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) 		if (rq->req_stat == RS_PENDING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) 			esas2r_start_request(a, rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) 	if (likely(rq->vrq->scsi.function == VDA_FUNC_SCSI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) 	    && unlikely(rq->req_stat != RS_SUCCESS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) 		esas2r_check_req_rsp_sense(a, rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) 		esas2r_log_request_failure(a, rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) 	(*rq->comp_cb)(a, rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) }