^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) }