^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * QLogic iSCSI HBA Driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2003-2013 QLogic Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include "ql4_def.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "ql4_glbl.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "ql4_dbg.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "ql4_inline.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * qla4xxx_copy_sense - copy sense data into cmd sense buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * @ha: Pointer to host adapter structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * @sts_entry: Pointer to status entry structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * @srb: Pointer to srb structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) static void qla4xxx_copy_sense(struct scsi_qla_host *ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) struct status_entry *sts_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) struct srb *srb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) struct scsi_cmnd *cmd = srb->cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) uint16_t sense_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) sense_len = le16_to_cpu(sts_entry->senseDataByteCnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) if (sense_len == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) DEBUG2(ql4_printk(KERN_INFO, ha, "scsi%ld:%d:%d:%llu: %s:"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) " sense len 0\n", ha->host_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) cmd->device->channel, cmd->device->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) cmd->device->lun, __func__));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) ha->status_srb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /* Save total available sense length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * not to exceed cmd's sense buffer size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) sense_len = min_t(uint16_t, sense_len, SCSI_SENSE_BUFFERSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) srb->req_sense_ptr = cmd->sense_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) srb->req_sense_len = sense_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /* Copy sense from sts_entry pkt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) sense_len = min_t(uint16_t, sense_len, IOCB_MAX_SENSEDATA_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) memcpy(cmd->sense_buffer, sts_entry->senseData, sense_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) DEBUG2(printk(KERN_INFO "scsi%ld:%d:%d:%llu: %s: sense key = %x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) "ASL= %02x, ASC/ASCQ = %02x/%02x\n", ha->host_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) cmd->device->channel, cmd->device->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) cmd->device->lun, __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) sts_entry->senseData[2] & 0x0f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) sts_entry->senseData[7],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) sts_entry->senseData[12],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) sts_entry->senseData[13]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) DEBUG5(qla4xxx_dump_buffer(cmd->sense_buffer, sense_len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) srb->flags |= SRB_GOT_SENSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /* Update srb, in case a sts_cont pkt follows */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) srb->req_sense_ptr += sense_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) srb->req_sense_len -= sense_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) if (srb->req_sense_len != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) ha->status_srb = srb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) ha->status_srb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * qla4xxx_status_cont_entry - Process a Status Continuations entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * @ha: SCSI driver HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * @sts_cont: Entry pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * Extended sense data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) qla4xxx_status_cont_entry(struct scsi_qla_host *ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) struct status_cont_entry *sts_cont)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct srb *srb = ha->status_srb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) struct scsi_cmnd *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) uint16_t sense_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) if (srb == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) cmd = srb->cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (cmd == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) DEBUG2(printk(KERN_INFO "scsi%ld: %s: Cmd already returned "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) "back to OS srb=%p srb->state:%d\n", ha->host_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) __func__, srb, srb->state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) ha->status_srb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) /* Copy sense data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) sense_len = min_t(uint16_t, srb->req_sense_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) IOCB_MAX_EXT_SENSEDATA_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) memcpy(srb->req_sense_ptr, sts_cont->ext_sense_data, sense_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) DEBUG5(qla4xxx_dump_buffer(srb->req_sense_ptr, sense_len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) srb->req_sense_ptr += sense_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) srb->req_sense_len -= sense_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /* Place command on done queue. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if (srb->req_sense_len == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) kref_put(&srb->srb_ref, qla4xxx_srb_compl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) ha->status_srb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * qla4xxx_status_entry - processes status IOCBs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * @ha: Pointer to host adapter structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * @sts_entry: Pointer to status entry structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static void qla4xxx_status_entry(struct scsi_qla_host *ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct status_entry *sts_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) uint8_t scsi_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct scsi_cmnd *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct srb *srb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) struct ddb_entry *ddb_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) uint32_t residual;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) srb = qla4xxx_del_from_active_array(ha, le32_to_cpu(sts_entry->handle));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (!srb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) ql4_printk(KERN_WARNING, ha, "%s invalid status entry: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) "handle=0x%0x, srb=%p\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) sts_entry->handle, srb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (is_qla80XX(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) set_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) set_bit(DPC_RESET_HA, &ha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) cmd = srb->cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) if (cmd == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) DEBUG2(printk("scsi%ld: %s: Command already returned back to "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) "OS pkt->handle=%d srb=%p srb->state:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) ha->host_no, __func__, sts_entry->handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) srb, srb->state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) ql4_printk(KERN_WARNING, ha, "Command is NULL:"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) " already returned to OS (srb=%p)\n", srb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) ddb_entry = srb->ddb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (ddb_entry == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) cmd->result = DID_NO_CONNECT << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) goto status_entry_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) residual = le32_to_cpu(sts_entry->residualByteCnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) /* Translate ISP error to a Linux SCSI error. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) scsi_status = sts_entry->scsiStatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) switch (sts_entry->completionStatus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) case SCS_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (sts_entry->iscsiFlags & ISCSI_FLAG_RESIDUAL_OVER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) cmd->result = DID_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (sts_entry->iscsiFlags &ISCSI_FLAG_RESIDUAL_UNDER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) scsi_set_resid(cmd, residual);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (!scsi_status && ((scsi_bufflen(cmd) - residual) <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) cmd->underflow)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) cmd->result = DID_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) DEBUG2(printk("scsi%ld:%d:%d:%llu: %s: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) "Mid-layer Data underrun0, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) "xferlen = 0x%x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) "residual = 0x%x\n", ha->host_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) cmd->device->channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) cmd->device->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) cmd->device->lun, __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) scsi_bufflen(cmd), residual));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) cmd->result = DID_OK << 16 | scsi_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (scsi_status != SCSI_CHECK_CONDITION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /* Copy Sense Data into sense buffer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) qla4xxx_copy_sense(ha, sts_entry, srb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) case SCS_INCOMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) /* Always set the status to DID_ERROR, since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * all conditions result in that status anyway */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) cmd->result = DID_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) case SCS_RESET_OCCURRED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) DEBUG2(printk("scsi%ld:%d:%d:%llu: %s: Device RESET occurred\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) ha->host_no, cmd->device->channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) cmd->device->id, cmd->device->lun, __func__));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) cmd->result = DID_RESET << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) case SCS_ABORTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) DEBUG2(printk("scsi%ld:%d:%d:%llu: %s: Abort occurred\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) ha->host_no, cmd->device->channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) cmd->device->id, cmd->device->lun, __func__));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) cmd->result = DID_RESET << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) case SCS_TIMEOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) DEBUG2(printk(KERN_INFO "scsi%ld:%d:%d:%llu: Timeout\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) ha->host_no, cmd->device->channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) cmd->device->id, cmd->device->lun));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) cmd->result = DID_TRANSPORT_DISRUPTED << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * Mark device missing so that we won't continue to send
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) * I/O to this device. We should get a ddb state change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * AEN soon.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (iscsi_is_session_online(ddb_entry->sess))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) qla4xxx_mark_device_missing(ddb_entry->sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) case SCS_DATA_UNDERRUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) case SCS_DATA_OVERRUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if ((sts_entry->iscsiFlags & ISCSI_FLAG_RESIDUAL_OVER) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) (sts_entry->completionStatus == SCS_DATA_OVERRUN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) DEBUG2(printk("scsi%ld:%d:%d:%llu: %s: " "Data overrun\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) ha->host_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) cmd->device->channel, cmd->device->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) cmd->device->lun, __func__));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) cmd->result = DID_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) scsi_set_resid(cmd, residual);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (sts_entry->iscsiFlags & ISCSI_FLAG_RESIDUAL_UNDER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) /* Both the firmware and target reported UNDERRUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * MID-LAYER UNDERFLOW case:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) * Some kernels do not properly detect midlayer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * underflow, so we manually check it and return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * ERROR if the minimum required data was not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) * received.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * ALL OTHER cases:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * Fall thru to check scsi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (!scsi_status && (scsi_bufflen(cmd) - residual) <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) cmd->underflow) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) DEBUG2(ql4_printk(KERN_INFO, ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) "scsi%ld:%d:%d:%llu: %s: Mid-layer Data underrun, xferlen = 0x%x,residual = 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) ha->host_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) cmd->device->channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) cmd->device->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) cmd->device->lun, __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) scsi_bufflen(cmd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) residual));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) cmd->result = DID_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) } else if (scsi_status != SAM_STAT_TASK_SET_FULL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) scsi_status != SAM_STAT_BUSY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * The firmware reports UNDERRUN, but the target does
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * not report it:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) * scsi_status | host_byte device_byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) * | (19:16) (7:0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * ============= | ========= ===========
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * TASK_SET_FULL | DID_OK scsi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) * BUSY | DID_OK scsi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) * ALL OTHERS | DID_ERROR scsi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) * Note: If scsi_status is task set full or busy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) * then this else if would fall thru to check the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * scsi_status and return DID_OK.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) DEBUG2(ql4_printk(KERN_INFO, ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) "scsi%ld:%d:%d:%llu: %s: Dropped frame(s) detected (0x%x of 0x%x bytes).\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) ha->host_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) cmd->device->channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) cmd->device->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) cmd->device->lun, __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) residual,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) scsi_bufflen(cmd)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) cmd->result = DID_ERROR << 16 | scsi_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) goto check_scsi_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) cmd->result = DID_OK << 16 | scsi_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) check_scsi_status:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (scsi_status == SAM_STAT_CHECK_CONDITION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) qla4xxx_copy_sense(ha, sts_entry, srb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) case SCS_DEVICE_LOGGED_OUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) case SCS_DEVICE_UNAVAILABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) DEBUG2(printk(KERN_INFO "scsi%ld:%d:%d:%llu: SCS_DEVICE "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) "state: 0x%x\n", ha->host_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) cmd->device->channel, cmd->device->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) cmd->device->lun, sts_entry->completionStatus));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * Mark device missing so that we won't continue to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) * send I/O to this device. We should get a ddb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * state change AEN soon.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (iscsi_is_session_online(ddb_entry->sess))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) qla4xxx_mark_device_missing(ddb_entry->sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) cmd->result = DID_TRANSPORT_DISRUPTED << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) case SCS_QUEUE_FULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) * SCSI Mid-Layer handles device queue full
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) cmd->result = DID_OK << 16 | sts_entry->scsiStatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) DEBUG2(printk("scsi%ld:%d:%llu: %s: QUEUE FULL detected "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) "compl=%02x, scsi=%02x, state=%02x, iFlags=%02x,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) " iResp=%02x\n", ha->host_no, cmd->device->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) cmd->device->lun, __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) sts_entry->completionStatus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) sts_entry->scsiStatus, sts_entry->state_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) sts_entry->iscsiFlags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) sts_entry->iscsiResponse));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) cmd->result = DID_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) status_entry_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) /* complete the request, if not waiting for status_continuation pkt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) srb->cc_stat = sts_entry->completionStatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) if (ha->status_srb == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) kref_put(&srb->srb_ref, qla4xxx_srb_compl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) * qla4xxx_passthru_status_entry - processes passthru status IOCBs (0x3C)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) * @ha: Pointer to host adapter structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * @sts_entry: Pointer to status entry structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) static void qla4xxx_passthru_status_entry(struct scsi_qla_host *ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) struct passthru_status *sts_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) struct iscsi_task *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) struct ddb_entry *ddb_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) struct ql4_task_data *task_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) struct iscsi_cls_conn *cls_conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) struct iscsi_conn *conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) itt_t itt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) uint32_t fw_ddb_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) itt = sts_entry->handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) fw_ddb_index = le32_to_cpu(sts_entry->target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) ddb_entry = qla4xxx_lookup_ddb_by_fw_index(ha, fw_ddb_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (ddb_entry == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) ql4_printk(KERN_ERR, ha, "%s: Invalid target index = 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) __func__, sts_entry->target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) cls_conn = ddb_entry->conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) conn = cls_conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) spin_lock(&conn->session->back_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) task = iscsi_itt_to_task(conn, itt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) spin_unlock(&conn->session->back_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (task == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) ql4_printk(KERN_ERR, ha, "%s: Task is NULL\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) task_data = task->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) memcpy(&task_data->sts, sts_entry, sizeof(struct passthru_status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) ha->iocb_cnt -= task_data->iocb_req_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) queue_work(ha->task_wq, &task_data->task_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) static struct mrb *qla4xxx_del_mrb_from_active_array(struct scsi_qla_host *ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) uint32_t index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) struct mrb *mrb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) /* validate handle and remove from active array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (index >= MAX_MRB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) return mrb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) mrb = ha->active_mrb_array[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) ha->active_mrb_array[index] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (!mrb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) return mrb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) /* update counters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) ha->iocb_cnt -= mrb->iocb_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) return mrb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) static void qla4xxx_mbox_status_entry(struct scsi_qla_host *ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) struct mbox_status_iocb *mbox_sts_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) struct mrb *mrb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) uint32_t status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) uint32_t data_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) mrb = qla4xxx_del_mrb_from_active_array(ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) le32_to_cpu(mbox_sts_entry->handle));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if (mrb == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) ql4_printk(KERN_WARNING, ha, "%s: mrb[%d] is null\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) mbox_sts_entry->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) switch (mrb->mbox_cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) case MBOX_CMD_PING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) DEBUG2(ql4_printk(KERN_INFO, ha, "%s: mbox_cmd = 0x%x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) "mbox_sts[0] = 0x%x, mbox_sts[6] = 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) __func__, mrb->mbox_cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) mbox_sts_entry->out_mbox[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) mbox_sts_entry->out_mbox[6]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (mbox_sts_entry->out_mbox[0] == MBOX_STS_COMMAND_COMPLETE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) status = ISCSI_PING_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) status = mbox_sts_entry->out_mbox[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) data_size = sizeof(mbox_sts_entry->out_mbox);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) qla4xxx_post_ping_evt_work(ha, status, mrb->pid, data_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) (uint8_t *) mbox_sts_entry->out_mbox);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: invalid mbox_cmd = "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) "0x%x\n", __func__, mrb->mbox_cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) kfree(mrb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) }
^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) * qla4xxx_process_response_queue - process response queue completions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) * @ha: Pointer to host adapter structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) * This routine process response queue completions in interrupt context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) * Hardware_lock locked upon entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) void qla4xxx_process_response_queue(struct scsi_qla_host *ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) uint32_t count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) struct srb *srb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) struct status_entry *sts_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) /* Process all responses from response queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) while ((ha->response_ptr->signature != RESPONSE_PROCESSED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) sts_entry = (struct status_entry *) ha->response_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) /* Advance pointers for next entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) if (ha->response_out == (RESPONSE_QUEUE_DEPTH - 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) ha->response_out = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) ha->response_ptr = ha->response_ring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) ha->response_out++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) ha->response_ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) /* process entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) switch (sts_entry->hdr.entryType) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) case ET_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) /* Common status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) qla4xxx_status_entry(ha, sts_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) case ET_PASSTHRU_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (sts_entry->hdr.systemDefined == SD_ISCSI_PDU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) qla4xxx_passthru_status_entry(ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) (struct passthru_status *)sts_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) ql4_printk(KERN_ERR, ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) "%s: Invalid status received\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) case ET_STATUS_CONTINUATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) qla4xxx_status_cont_entry(ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) (struct status_cont_entry *) sts_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) case ET_COMMAND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) /* ISP device queue is full. Command not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) * accepted by ISP. Queue command for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) * later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) srb = qla4xxx_del_from_active_array(ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) le32_to_cpu(sts_entry->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) handle));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) if (srb == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) goto exit_prq_invalid_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) DEBUG2(printk("scsi%ld: %s: FW device queue full, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) "srb %p\n", ha->host_no, __func__, srb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) /* ETRY normally by sending it back with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) * DID_BUS_BUSY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) srb->cmd->result = DID_BUS_BUSY << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) kref_put(&srb->srb_ref, qla4xxx_srb_compl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) case ET_CONTINUE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) /* Just throw away the continuation entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) DEBUG2(printk("scsi%ld: %s: Continuation entry - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) "ignoring\n", ha->host_no, __func__));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) case ET_MBOX_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) DEBUG2(ql4_printk(KERN_INFO, ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) "%s: mbox status IOCB\n", __func__));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) qla4xxx_mbox_status_entry(ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) (struct mbox_status_iocb *)sts_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) * Invalid entry in response queue, reset RISC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) * firmware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) DEBUG2(printk("scsi%ld: %s: Invalid entry %x in "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) "response queue \n", ha->host_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) sts_entry->hdr.entryType));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) goto exit_prq_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) ((struct response *)sts_entry)->signature = RESPONSE_PROCESSED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) * Tell ISP we're done with response(s). This also clears the interrupt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) ha->isp_ops->complete_iocb(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) exit_prq_invalid_handle:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) DEBUG2(printk("scsi%ld: %s: Invalid handle(srb)=%p type=%x IOCS=%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) ha->host_no, __func__, srb, sts_entry->hdr.entryType,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) sts_entry->completionStatus));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) exit_prq_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) ha->isp_ops->complete_iocb(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) set_bit(DPC_RESET_HA, &ha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) * qla4_83xx_loopback_in_progress: Is loopback in progress?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) * @ha: Pointer to host adapter structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) * returns: 1 = loopback in progress, 0 = loopback not in progress
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) static int qla4_83xx_loopback_in_progress(struct scsi_qla_host *ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) int rval = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) if (is_qla8032(ha) || is_qla8042(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) if ((ha->idc_info.info2 & ENABLE_INTERNAL_LOOPBACK) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) (ha->idc_info.info2 & ENABLE_EXTERNAL_LOOPBACK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) DEBUG2(ql4_printk(KERN_INFO, ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) "%s: Loopback diagnostics in progress\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) __func__));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) rval = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) DEBUG2(ql4_printk(KERN_INFO, ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) "%s: Loopback diagnostics not in progress\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) __func__));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) rval = 0;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) return rval;
^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) static void qla4xxx_update_ipaddr_state(struct scsi_qla_host *ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) uint32_t ipaddr_idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) uint32_t ipaddr_fw_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) uint8_t ipaddr_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) uint8_t ip_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) ip_idx = ipaddr_idx & 0xF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) ipaddr_state = qla4xxx_set_ipaddr_state((uint8_t)ipaddr_fw_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) switch (ip_idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) ha->ip_config.ipv4_addr_state = ipaddr_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) ha->ip_config.ipv6_link_local_state = ipaddr_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) ha->ip_config.ipv6_addr0_state = ipaddr_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) ha->ip_config.ipv6_addr1_state = ipaddr_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) ql4_printk(KERN_INFO, ha, "%s: Invalid IPADDR index %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) __func__, ip_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) static void qla4xxx_default_router_changed(struct scsi_qla_host *ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) uint32_t *mbox_sts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) memcpy(&ha->ip_config.ipv6_default_router_addr.s6_addr32[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) &mbox_sts[2], sizeof(uint32_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) memcpy(&ha->ip_config.ipv6_default_router_addr.s6_addr32[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) &mbox_sts[3], sizeof(uint32_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) memcpy(&ha->ip_config.ipv6_default_router_addr.s6_addr32[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) &mbox_sts[4], sizeof(uint32_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) memcpy(&ha->ip_config.ipv6_default_router_addr.s6_addr32[3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) &mbox_sts[5], sizeof(uint32_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) * qla4xxx_isr_decode_mailbox - decodes mailbox status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) * @ha: Pointer to host adapter structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) * @mbox_status: Mailbox status.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) * This routine decodes the mailbox status during the ISR.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) * Hardware_lock locked upon entry. runs in interrupt context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) uint32_t mbox_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) uint32_t mbox_sts[MBOX_AEN_REG_COUNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) __le32 __iomem *mailbox_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) uint32_t opcode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) if (is_qla8032(ha) || is_qla8042(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) mailbox_out = &ha->qla4_83xx_reg->mailbox_out[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) else if (is_qla8022(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) mailbox_out = &ha->qla4_82xx_reg->mailbox_out[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) mailbox_out = &ha->reg->mailbox[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) if ((mbox_status == MBOX_STS_BUSY) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) (mbox_status == MBOX_STS_INTERMEDIATE_COMPLETION) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) (mbox_status >> 12 == MBOX_COMPLETION_STATUS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) ha->mbox_status[0] = mbox_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) if (test_bit(AF_MBOX_COMMAND, &ha->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) * Copy all mailbox registers to a temporary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) * location and set mailbox command done flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) for (i = 0; i < ha->mbox_status_count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) ha->mbox_status[i] = readl(&mailbox_out[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) set_bit(AF_MBOX_COMMAND_DONE, &ha->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) if (test_bit(AF_MBOX_COMMAND_NOPOLL, &ha->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) complete(&ha->mbx_intr_comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) } else if (mbox_status >> 12 == MBOX_ASYNC_EVENT_STATUS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) for (i = 0; i < MBOX_AEN_REG_COUNT; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) mbox_sts[i] = readl(&mailbox_out[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) /* Immediately process the AENs that don't require much work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) * Only queue the database_changed AENs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) if (ha->aen_log.count < MAX_AEN_ENTRIES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) for (i = 0; i < MBOX_AEN_REG_COUNT; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) ha->aen_log.entry[ha->aen_log.count].mbox_sts[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) mbox_sts[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) ha->aen_log.count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) switch (mbox_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) case MBOX_ASTS_SYSTEM_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) /* Log Mailbox registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) ql4_printk(KERN_INFO, ha, "%s: System Err\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) qla4xxx_dump_registers(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) if ((is_qla8022(ha) && ql4xdontresethba) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) ((is_qla8032(ha) || is_qla8042(ha)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) qla4_83xx_idc_dontreset(ha))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) DEBUG2(printk("scsi%ld: %s:Don't Reset HBA\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) ha->host_no, __func__));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) set_bit(AF_GET_CRASH_RECORD, &ha->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) set_bit(DPC_RESET_HA, &ha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) case MBOX_ASTS_REQUEST_TRANSFER_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) case MBOX_ASTS_RESPONSE_TRANSFER_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) case MBOX_ASTS_NVRAM_INVALID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) case MBOX_ASTS_IP_ADDRESS_CHANGED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) case MBOX_ASTS_DHCP_LEASE_EXPIRED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) DEBUG2(printk("scsi%ld: AEN %04x, ERROR Status, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) "Reset HA\n", ha->host_no, mbox_status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (is_qla80XX(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) set_bit(DPC_RESET_HA_FW_CONTEXT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) &ha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) set_bit(DPC_RESET_HA, &ha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) case MBOX_ASTS_LINK_UP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) set_bit(AF_LINK_UP, &ha->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) if (test_bit(AF_INIT_DONE, &ha->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) set_bit(DPC_LINK_CHANGED, &ha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) ql4_printk(KERN_INFO, ha, "%s: LINK UP\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) qla4xxx_post_aen_work(ha, ISCSI_EVENT_LINKUP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) sizeof(mbox_sts),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) (uint8_t *) mbox_sts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) if ((is_qla8032(ha) || is_qla8042(ha)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) ha->notify_link_up_comp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) complete(&ha->link_up_comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) case MBOX_ASTS_LINK_DOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) clear_bit(AF_LINK_UP, &ha->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) if (test_bit(AF_INIT_DONE, &ha->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) set_bit(DPC_LINK_CHANGED, &ha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) qla4xxx_wake_dpc(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) ql4_printk(KERN_INFO, ha, "%s: LINK DOWN\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) qla4xxx_post_aen_work(ha, ISCSI_EVENT_LINKDOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) sizeof(mbox_sts),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) (uint8_t *) mbox_sts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) case MBOX_ASTS_HEARTBEAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) ha->seconds_since_last_heartbeat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) case MBOX_ASTS_DHCP_LEASE_ACQUIRED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) DEBUG2(printk("scsi%ld: AEN %04x DHCP LEASE "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) "ACQUIRED\n", ha->host_no, mbox_status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) set_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) case MBOX_ASTS_PROTOCOL_STATISTIC_ALARM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) case MBOX_ASTS_SCSI_COMMAND_PDU_REJECTED: /* Target
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) * mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) * only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) case MBOX_ASTS_UNSOLICITED_PDU_RECEIVED: /* Connection mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) case MBOX_ASTS_IPSEC_SYSTEM_FATAL_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) case MBOX_ASTS_SUBNET_STATE_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) case MBOX_ASTS_DUPLICATE_IP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) /* No action */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) DEBUG2(printk("scsi%ld: AEN %04x\n", ha->host_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) mbox_status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) case MBOX_ASTS_IP_ADDR_STATE_CHANGED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) printk("scsi%ld: AEN %04x, mbox_sts[2]=%04x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) "mbox_sts[3]=%04x\n", ha->host_no, mbox_sts[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) mbox_sts[2], mbox_sts[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) qla4xxx_update_ipaddr_state(ha, mbox_sts[5],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) mbox_sts[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) /* mbox_sts[2] = Old ACB state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) * mbox_sts[3] = new ACB state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) if ((mbox_sts[3] == IP_ADDRSTATE_PREFERRED) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) ((mbox_sts[2] == IP_ADDRSTATE_TENTATIVE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) (mbox_sts[2] == IP_ADDRSTATE_ACQUIRING))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) set_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) } else if ((mbox_sts[3] == IP_ADDRSTATE_ACQUIRING) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) (mbox_sts[2] == IP_ADDRSTATE_PREFERRED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (is_qla80XX(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) set_bit(DPC_RESET_HA_FW_CONTEXT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) &ha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) set_bit(DPC_RESET_HA, &ha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) } else if (mbox_sts[3] == IP_ADDRSTATE_DISABLING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) ql4_printk(KERN_INFO, ha, "scsi%ld: %s: ACB in disabling state\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) ha->host_no, __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) } else if (mbox_sts[3] == IP_ADDRSTATE_UNCONFIGURED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) complete(&ha->disable_acb_comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) ql4_printk(KERN_INFO, ha, "scsi%ld: %s: ACB state unconfigured\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) ha->host_no, __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) case MBOX_ASTS_IPV6_LINK_MTU_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) case MBOX_ASTS_IPV6_AUTO_PREFIX_IGNORED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) case MBOX_ASTS_IPV6_ND_LOCAL_PREFIX_IGNORED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) /* No action */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) DEBUG2(ql4_printk(KERN_INFO, ha, "scsi%ld: AEN %04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) ha->host_no, mbox_status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) case MBOX_ASTS_ICMPV6_ERROR_MSG_RCVD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) DEBUG2(ql4_printk(KERN_INFO, ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) "scsi%ld: AEN %04x, IPv6 ERROR, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) "mbox_sts[1]=%08x, mbox_sts[2]=%08x, mbox_sts[3}=%08x, mbox_sts[4]=%08x mbox_sts[5]=%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) ha->host_no, mbox_sts[0], mbox_sts[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) mbox_sts[2], mbox_sts[3], mbox_sts[4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) mbox_sts[5]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) case MBOX_ASTS_MAC_ADDRESS_CHANGED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) case MBOX_ASTS_DNS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) /* No action */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) DEBUG2(printk(KERN_INFO "scsi%ld: AEN %04x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) "mbox_sts[1]=%04x, mbox_sts[2]=%04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) ha->host_no, mbox_sts[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) mbox_sts[1], mbox_sts[2]));
^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) case MBOX_ASTS_SELF_TEST_FAILED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) case MBOX_ASTS_LOGIN_FAILED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) /* No action */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) DEBUG2(printk("scsi%ld: AEN %04x, mbox_sts[1]=%04x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) "mbox_sts[2]=%04x, mbox_sts[3]=%04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) ha->host_no, mbox_sts[0], mbox_sts[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) mbox_sts[2], mbox_sts[3]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) case MBOX_ASTS_DATABASE_CHANGED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) /* Queue AEN information and process it in the DPC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) * routine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) if (ha->aen_q_count > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) /* decrement available counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) ha->aen_q_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) for (i = 0; i < MBOX_AEN_REG_COUNT; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) ha->aen_q[ha->aen_in].mbox_sts[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) mbox_sts[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) /* print debug message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) DEBUG2(printk("scsi%ld: AEN[%d] %04x queued "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) "mb1:0x%x mb2:0x%x mb3:0x%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) "mb4:0x%x mb5:0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) ha->host_no, ha->aen_in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) mbox_sts[0], mbox_sts[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) mbox_sts[2], mbox_sts[3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) mbox_sts[4], mbox_sts[5]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) /* advance pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) ha->aen_in++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) if (ha->aen_in == MAX_AEN_ENTRIES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) ha->aen_in = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) /* The DPC routine will process the aen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) set_bit(DPC_AEN, &ha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) DEBUG2(printk("scsi%ld: %s: aen %04x, queue "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) "overflowed! AEN LOST!!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) ha->host_no, __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) mbox_sts[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) DEBUG2(printk("scsi%ld: DUMP AEN QUEUE\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) ha->host_no));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) for (i = 0; i < MAX_AEN_ENTRIES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) DEBUG2(printk("AEN[%d] %04x %04x %04x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) "%04x\n", i, mbox_sts[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) mbox_sts[1], mbox_sts[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) mbox_sts[3]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) case MBOX_ASTS_TXSCVR_INSERTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) DEBUG2(printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) "scsi%ld: AEN %04x Transceiver"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) " inserted\n", ha->host_no, mbox_sts[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) case MBOX_ASTS_TXSCVR_REMOVED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) DEBUG2(printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) "scsi%ld: AEN %04x Transceiver"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) " removed\n", ha->host_no, mbox_sts[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) case MBOX_ASTS_IDC_REQUEST_NOTIFICATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) if (is_qla8032(ha) || is_qla8042(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) DEBUG2(ql4_printk(KERN_INFO, ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) "scsi%ld: AEN %04x, mbox_sts[1]=%08x, mbox_sts[2]=%08x, mbox_sts[3]=%08x, mbox_sts[4]=%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) ha->host_no, mbox_sts[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) mbox_sts[1], mbox_sts[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) mbox_sts[3], mbox_sts[4]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) opcode = mbox_sts[1] >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) if ((opcode == MBOX_CMD_SET_PORT_CONFIG) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) (opcode == MBOX_CMD_PORT_RESET)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) set_bit(DPC_POST_IDC_ACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) &ha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) ha->idc_info.request_desc = mbox_sts[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) ha->idc_info.info1 = mbox_sts[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) ha->idc_info.info2 = mbox_sts[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) ha->idc_info.info3 = mbox_sts[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) qla4xxx_wake_dpc(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) case MBOX_ASTS_IDC_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) if (is_qla8032(ha) || is_qla8042(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) DEBUG2(ql4_printk(KERN_INFO, ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) "scsi%ld: AEN %04x, mbox_sts[1]=%08x, mbox_sts[2]=%08x, mbox_sts[3]=%08x, mbox_sts[4]=%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) ha->host_no, mbox_sts[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) mbox_sts[1], mbox_sts[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) mbox_sts[3], mbox_sts[4]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) DEBUG2(ql4_printk(KERN_INFO, ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) "scsi:%ld: AEN %04x IDC Complete notification\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) ha->host_no, mbox_sts[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) opcode = mbox_sts[1] >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) if (ha->notify_idc_comp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) complete(&ha->idc_comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) if ((opcode == MBOX_CMD_SET_PORT_CONFIG) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) (opcode == MBOX_CMD_PORT_RESET))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) ha->idc_info.info2 = mbox_sts[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) if (qla4_83xx_loopback_in_progress(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) set_bit(AF_LOOPBACK, &ha->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) clear_bit(AF_LOOPBACK, &ha->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) if (ha->saved_acb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) set_bit(DPC_RESTORE_ACB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) &ha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) qla4xxx_wake_dpc(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) case MBOX_ASTS_IPV6_DEFAULT_ROUTER_CHANGED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) DEBUG2(ql4_printk(KERN_INFO, ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) "scsi%ld: AEN %04x, mbox_sts[1]=%08x, mbox_sts[2]=%08x, mbox_sts[3]=%08x, mbox_sts[4]=%08x mbox_sts[5]=%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) ha->host_no, mbox_sts[0], mbox_sts[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) mbox_sts[2], mbox_sts[3], mbox_sts[4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) mbox_sts[5]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) DEBUG2(ql4_printk(KERN_INFO, ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) "scsi%ld: AEN %04x Received IPv6 default router changed notification\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) ha->host_no, mbox_sts[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) qla4xxx_default_router_changed(ha, mbox_sts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) case MBOX_ASTS_IDC_TIME_EXTEND_NOTIFICATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) DEBUG2(ql4_printk(KERN_INFO, ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) "scsi%ld: AEN %04x, mbox_sts[1]=%08x, mbox_sts[2]=%08x, mbox_sts[3]=%08x, mbox_sts[4]=%08x mbox_sts[5]=%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) ha->host_no, mbox_sts[0], mbox_sts[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) mbox_sts[2], mbox_sts[3], mbox_sts[4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) mbox_sts[5]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) DEBUG2(ql4_printk(KERN_INFO, ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) "scsi%ld: AEN %04x Received IDC Extend Timeout notification\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) ha->host_no, mbox_sts[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) /* new IDC timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) ha->idc_extend_tmo = mbox_sts[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) case MBOX_ASTS_INITIALIZATION_FAILED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) DEBUG2(ql4_printk(KERN_INFO, ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) "scsi%ld: AEN %04x, mbox_sts[3]=%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) ha->host_no, mbox_sts[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) mbox_sts[3]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) case MBOX_ASTS_SYSTEM_WARNING_EVENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) DEBUG2(ql4_printk(KERN_WARNING, ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) "scsi%ld: AEN %04x, mbox_sts[1]=%08x, mbox_sts[2]=%08x, mbox_sts[3]=%08x, mbox_sts[4]=%08x mbox_sts[5]=%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) ha->host_no, mbox_sts[0], mbox_sts[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) mbox_sts[2], mbox_sts[3], mbox_sts[4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) mbox_sts[5]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) case MBOX_ASTS_DCBX_CONF_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) DEBUG2(ql4_printk(KERN_INFO, ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) "scsi%ld: AEN %04x, mbox_sts[1]=%08x, mbox_sts[2]=%08x, mbox_sts[3]=%08x, mbox_sts[4]=%08x mbox_sts[5]=%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) ha->host_no, mbox_sts[0], mbox_sts[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) mbox_sts[2], mbox_sts[3], mbox_sts[4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) mbox_sts[5]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) DEBUG2(ql4_printk(KERN_INFO, ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) "scsi%ld: AEN %04x Received DCBX configuration changed notification\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) ha->host_no, mbox_sts[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) DEBUG2(printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) "scsi%ld: AEN %04x UNKNOWN\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) ha->host_no, mbox_sts[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) DEBUG2(printk("scsi%ld: Unknown mailbox status %08X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) ha->host_no, mbox_status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) ha->mbox_status[0] = mbox_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) void qla4_83xx_interrupt_service_routine(struct scsi_qla_host *ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) uint32_t intr_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) /* Process mailbox/asynch event interrupt.*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) if (intr_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) qla4xxx_isr_decode_mailbox(ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) readl(&ha->qla4_83xx_reg->mailbox_out[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) /* clear the interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) writel(0, &ha->qla4_83xx_reg->risc_intr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) qla4xxx_process_response_queue(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) /* clear the interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) writel(0, &ha->qla4_83xx_reg->mb_int_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) * qla4_82xx_interrupt_service_routine - isr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) * @ha: pointer to host adapter structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) * @intr_status: Local interrupt status/type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) * This is the main interrupt service routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) * hardware_lock locked upon entry. runs in interrupt context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) void qla4_82xx_interrupt_service_routine(struct scsi_qla_host *ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) uint32_t intr_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) /* Process response queue interrupt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) if ((intr_status & HSRX_RISC_IOCB_INT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) test_bit(AF_INIT_DONE, &ha->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) qla4xxx_process_response_queue(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) /* Process mailbox/asynch event interrupt.*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) if (intr_status & HSRX_RISC_MB_INT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) qla4xxx_isr_decode_mailbox(ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) readl(&ha->qla4_82xx_reg->mailbox_out[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) /* clear the interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) writel(0, &ha->qla4_82xx_reg->host_int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) readl(&ha->qla4_82xx_reg->host_int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) * qla4xxx_interrupt_service_routine - isr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) * @ha: pointer to host adapter structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) * @intr_status: Local interrupt status/type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) * This is the main interrupt service routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) * hardware_lock locked upon entry. runs in interrupt context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) void qla4xxx_interrupt_service_routine(struct scsi_qla_host * ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) uint32_t intr_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) /* Process response queue interrupt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) if (intr_status & CSR_SCSI_COMPLETION_INTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) qla4xxx_process_response_queue(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) /* Process mailbox/asynch event interrupt.*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) if (intr_status & CSR_SCSI_PROCESSOR_INTR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) qla4xxx_isr_decode_mailbox(ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) readl(&ha->reg->mailbox[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) /* Clear Mailbox Interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) writel(set_rmask(CSR_SCSI_PROCESSOR_INTR),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) &ha->reg->ctrl_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) readl(&ha->reg->ctrl_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) * qla4_82xx_spurious_interrupt - processes spurious interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) * @ha: pointer to host adapter structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) * @reqs_count: .
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) static void qla4_82xx_spurious_interrupt(struct scsi_qla_host *ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) uint8_t reqs_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) if (reqs_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) DEBUG2(ql4_printk(KERN_INFO, ha, "Spurious Interrupt\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) if (is_qla8022(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) writel(0, &ha->qla4_82xx_reg->host_int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) if (!ha->pdev->msi_enabled && !ha->pdev->msix_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) qla4_82xx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 0xfbff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) ha->spurious_int_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) * qla4xxx_intr_handler - hardware interrupt handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) * @irq: Unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) * @dev_id: Pointer to host adapter structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) irqreturn_t qla4xxx_intr_handler(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) struct scsi_qla_host *ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) uint32_t intr_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) unsigned long flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) uint8_t reqs_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) ha = (struct scsi_qla_host *) dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) if (!ha) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) DEBUG2(printk(KERN_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) "qla4xxx: Interrupt with NULL host ptr\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) spin_lock_irqsave(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) ha->isr_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) * Repeatedly service interrupts up to a maximum of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) * MAX_REQS_SERVICED_PER_INTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) * Read interrupt status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) if (ha->isp_ops->rd_shdw_rsp_q_in(ha) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) ha->response_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) intr_status = CSR_SCSI_COMPLETION_INTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) intr_status = readl(&ha->reg->ctrl_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) if ((intr_status &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) (CSR_SCSI_RESET_INTR|CSR_FATAL_ERROR|INTR_PENDING)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) if (reqs_count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) ha->spurious_int_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) if (intr_status & CSR_FATAL_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) DEBUG2(printk(KERN_INFO "scsi%ld: Fatal Error, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) "Status 0x%04x\n", ha->host_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) readl(isp_port_error_status (ha))));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) /* Issue Soft Reset to clear this error condition.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) * This will prevent the RISC from repeatedly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) * interrupting the driver; thus, allowing the DPC to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) * get scheduled to continue error recovery.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) * NOTE: Disabling RISC interrupts does not work in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) * this case, as CSR_FATAL_ERROR overrides
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) * CSR_SCSI_INTR_ENABLE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) if ((readl(&ha->reg->ctrl_status) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) CSR_SCSI_RESET_INTR) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) writel(set_rmask(CSR_SOFT_RESET),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) &ha->reg->ctrl_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) readl(&ha->reg->ctrl_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) writel(set_rmask(CSR_FATAL_ERROR),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) &ha->reg->ctrl_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) readl(&ha->reg->ctrl_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) __qla4xxx_disable_intrs(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) set_bit(DPC_RESET_HA, &ha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) } else if (intr_status & CSR_SCSI_RESET_INTR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) clear_bit(AF_ONLINE, &ha->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) __qla4xxx_disable_intrs(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) writel(set_rmask(CSR_SCSI_RESET_INTR),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) &ha->reg->ctrl_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) readl(&ha->reg->ctrl_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) if (!test_bit(AF_HA_REMOVAL, &ha->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) set_bit(DPC_RESET_HA_INTR, &ha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) } else if (intr_status & INTR_PENDING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) ha->isp_ops->interrupt_service_routine(ha, intr_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) ha->total_io_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) if (++reqs_count == MAX_REQS_SERVICED_PER_INTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) spin_unlock_irqrestore(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) * qla4_82xx_intr_handler - hardware interrupt handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) * @irq: Unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) * @dev_id: Pointer to host adapter structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) irqreturn_t qla4_82xx_intr_handler(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) struct scsi_qla_host *ha = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) uint32_t intr_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) uint32_t status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) unsigned long flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) uint8_t reqs_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) if (unlikely(pci_channel_offline(ha->pdev)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) ha->isr_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) status = qla4_82xx_rd_32(ha, ISR_INT_VECTOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) if (!(status & ha->nx_legacy_intr.int_vec_bit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) status = qla4_82xx_rd_32(ha, ISR_INT_STATE_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) if (!ISR_IS_LEGACY_INTR_TRIGGERED(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) DEBUG7(ql4_printk(KERN_INFO, ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) "%s legacy Int not triggered\n", __func__));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) /* clear the interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) qla4_82xx_wr_32(ha, ha->nx_legacy_intr.tgt_status_reg, 0xffffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) /* read twice to ensure write is flushed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) qla4_82xx_rd_32(ha, ISR_INT_VECTOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) qla4_82xx_rd_32(ha, ISR_INT_VECTOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) spin_lock_irqsave(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) if (!(readl(&ha->qla4_82xx_reg->host_int) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) ISRX_82XX_RISC_INT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) qla4_82xx_spurious_interrupt(ha, reqs_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) intr_status = readl(&ha->qla4_82xx_reg->host_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) if ((intr_status &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) (HSRX_RISC_MB_INT | HSRX_RISC_IOCB_INT)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) qla4_82xx_spurious_interrupt(ha, reqs_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) ha->isp_ops->interrupt_service_routine(ha, intr_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) /* Enable Interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) qla4_82xx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0xfbff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) if (++reqs_count == MAX_REQS_SERVICED_PER_INTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) spin_unlock_irqrestore(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) #define LEG_INT_PTR_B31 (1 << 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) #define LEG_INT_PTR_B30 (1 << 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) #define PF_BITS_MASK (0xF << 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) * qla4_83xx_intr_handler - hardware interrupt handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) * @irq: Unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) * @dev_id: Pointer to host adapter structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) irqreturn_t qla4_83xx_intr_handler(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) struct scsi_qla_host *ha = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) uint32_t leg_int_ptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) unsigned long flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) ha->isr_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) leg_int_ptr = readl(&ha->qla4_83xx_reg->leg_int_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) /* Legacy interrupt is valid if bit31 of leg_int_ptr is set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) if (!(leg_int_ptr & LEG_INT_PTR_B31)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) DEBUG7(ql4_printk(KERN_ERR, ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) "%s: Legacy Interrupt Bit 31 not set, spurious interrupt!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) __func__));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) /* Validate the PCIE function ID set in leg_int_ptr bits [19..16] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) if ((leg_int_ptr & PF_BITS_MASK) != ha->pf_bit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) DEBUG7(ql4_printk(KERN_ERR, ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) "%s: Incorrect function ID 0x%x in legacy interrupt register, ha->pf_bit = 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) __func__, (leg_int_ptr & PF_BITS_MASK),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) ha->pf_bit));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) /* To de-assert legacy interrupt, write 0 to Legacy Interrupt Trigger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) * Control register and poll till Legacy Interrupt Pointer register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) * bit30 is 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) writel(0, &ha->qla4_83xx_reg->leg_int_trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) leg_int_ptr = readl(&ha->qla4_83xx_reg->leg_int_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) if ((leg_int_ptr & PF_BITS_MASK) != ha->pf_bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) } while (leg_int_ptr & LEG_INT_PTR_B30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) spin_lock_irqsave(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) leg_int_ptr = readl(&ha->qla4_83xx_reg->risc_intr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) ha->isp_ops->interrupt_service_routine(ha, leg_int_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) spin_unlock_irqrestore(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) irqreturn_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) qla4_8xxx_msi_handler(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) struct scsi_qla_host *ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) ha = (struct scsi_qla_host *) dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) if (!ha) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) DEBUG2(printk(KERN_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) "qla4xxx: MSIX: Interrupt with NULL host ptr\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) ha->isr_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) /* clear the interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) qla4_82xx_wr_32(ha, ha->nx_legacy_intr.tgt_status_reg, 0xffffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) /* read twice to ensure write is flushed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) qla4_82xx_rd_32(ha, ISR_INT_VECTOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) qla4_82xx_rd_32(ha, ISR_INT_VECTOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) return qla4_8xxx_default_intr_handler(irq, dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) static irqreturn_t qla4_83xx_mailbox_intr_handler(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) struct scsi_qla_host *ha = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) uint32_t ival = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) spin_lock_irqsave(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) ival = readl(&ha->qla4_83xx_reg->risc_intr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) if (ival == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) ql4_printk(KERN_INFO, ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) "%s: It is a spurious mailbox interrupt!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) ival = readl(&ha->qla4_83xx_reg->mb_int_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) ival &= ~INT_MASK_FW_MB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) writel(ival, &ha->qla4_83xx_reg->mb_int_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) qla4xxx_isr_decode_mailbox(ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) readl(&ha->qla4_83xx_reg->mailbox_out[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) writel(0, &ha->qla4_83xx_reg->risc_intr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) ival = readl(&ha->qla4_83xx_reg->mb_int_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) ival &= ~INT_MASK_FW_MB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) writel(ival, &ha->qla4_83xx_reg->mb_int_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) ha->isr_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) spin_unlock_irqrestore(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) * qla4_8xxx_default_intr_handler - hardware interrupt handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) * @irq: Unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) * @dev_id: Pointer to host adapter structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) * This interrupt handler is called directly for MSI-X, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) * called indirectly for MSI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) irqreturn_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) qla4_8xxx_default_intr_handler(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) struct scsi_qla_host *ha = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) uint32_t intr_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) uint8_t reqs_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) if (is_qla8032(ha) || is_qla8042(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) qla4_83xx_mailbox_intr_handler(irq, dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) spin_lock_irqsave(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) if (!(readl(&ha->qla4_82xx_reg->host_int) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) ISRX_82XX_RISC_INT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) qla4_82xx_spurious_interrupt(ha, reqs_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) intr_status = readl(&ha->qla4_82xx_reg->host_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) if ((intr_status &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) (HSRX_RISC_MB_INT | HSRX_RISC_IOCB_INT)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) qla4_82xx_spurious_interrupt(ha, reqs_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) ha->isp_ops->interrupt_service_routine(ha, intr_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) if (++reqs_count == MAX_REQS_SERVICED_PER_INTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) ha->isr_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) spin_unlock_irqrestore(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) irqreturn_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) qla4_8xxx_msix_rsp_q(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) struct scsi_qla_host *ha = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) int intr_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) uint32_t ival = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) spin_lock_irqsave(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) if (is_qla8032(ha) || is_qla8042(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) ival = readl(&ha->qla4_83xx_reg->iocb_int_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) if (ival == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) ql4_printk(KERN_INFO, ha, "%s: It is a spurious iocb interrupt!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) goto exit_msix_rsp_q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) qla4xxx_process_response_queue(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) writel(0, &ha->qla4_83xx_reg->iocb_int_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) intr_status = readl(&ha->qla4_82xx_reg->host_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) if (intr_status & HSRX_RISC_IOCB_INT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) qla4xxx_process_response_queue(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) writel(0, &ha->qla4_82xx_reg->host_int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) ql4_printk(KERN_INFO, ha, "%s: spurious iocb interrupt...\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) goto exit_msix_rsp_q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) ha->isr_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) exit_msix_rsp_q:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) spin_unlock_irqrestore(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) * qla4xxx_process_aen - processes AENs generated by firmware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) * @ha: pointer to host adapter structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) * @process_aen: type of AENs to process
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) * Processes specific types of Asynchronous Events generated by firmware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) * The type of AENs to process is specified by process_aen and can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) * PROCESS_ALL_AENS 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) * FLUSH_DDB_CHANGED_AENS 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) * RELOGIN_DDB_CHANGED_AENS 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) void qla4xxx_process_aen(struct scsi_qla_host * ha, uint8_t process_aen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) uint32_t mbox_sts[MBOX_AEN_REG_COUNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) struct aen *aen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) spin_lock_irqsave(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) while (ha->aen_out != ha->aen_in) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) aen = &ha->aen_q[ha->aen_out];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) /* copy aen information to local structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) for (i = 0; i < MBOX_AEN_REG_COUNT; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) mbox_sts[i] = aen->mbox_sts[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) ha->aen_q_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) ha->aen_out++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) if (ha->aen_out == MAX_AEN_ENTRIES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) ha->aen_out = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) spin_unlock_irqrestore(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) DEBUG2(printk("qla4xxx(%ld): AEN[%d]=0x%08x, mbx1=0x%08x mbx2=0x%08x"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) " mbx3=0x%08x mbx4=0x%08x\n", ha->host_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) (ha->aen_out ? (ha->aen_out-1): (MAX_AEN_ENTRIES-1)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) mbox_sts[0], mbox_sts[1], mbox_sts[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) mbox_sts[3], mbox_sts[4]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) switch (mbox_sts[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) case MBOX_ASTS_DATABASE_CHANGED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) switch (process_aen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) case FLUSH_DDB_CHANGED_AENS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) DEBUG2(printk("scsi%ld: AEN[%d] %04x, index "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) "[%d] state=%04x FLUSHED!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) ha->host_no, ha->aen_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) mbox_sts[0], mbox_sts[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) mbox_sts[3]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) case PROCESS_ALL_AENS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) /* Specific device. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) if (mbox_sts[1] == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) qla4xxx_process_ddb_changed(ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) mbox_sts[2], mbox_sts[3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) mbox_sts[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) spin_lock_irqsave(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) spin_unlock_irqrestore(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) int qla4xxx_request_irqs(struct scsi_qla_host *ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) int rval = QLA_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) if (is_qla40XX(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) goto try_intx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) if (ql4xenablemsix == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) /* Note: MSI Interrupts not supported for ISP8324 and ISP8042 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) if (is_qla8032(ha) || is_qla8042(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) ql4_printk(KERN_INFO, ha, "%s: MSI Interrupts not supported for ISP%04x, Falling back-to INTx mode\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) __func__, ha->pdev->device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) goto try_intx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) goto try_msi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) if (ql4xenablemsix == 0 || ql4xenablemsix != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) goto try_intx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) /* Trying MSI-X */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) ret = qla4_8xxx_enable_msix(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) DEBUG2(ql4_printk(KERN_INFO, ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) "MSI-X: Enabled (0x%X).\n", ha->revision_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) goto irq_attached;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) if (is_qla8032(ha) || is_qla8042(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) ql4_printk(KERN_INFO, ha, "%s: ISP%04x: MSI-X: Falling back-to INTx mode. ret = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) __func__, ha->pdev->device, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) goto try_intx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) ql4_printk(KERN_WARNING, ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) "MSI-X: Falling back-to MSI mode -- %d.\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) try_msi:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) /* Trying MSI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) ret = pci_alloc_irq_vectors(ha->pdev, 1, 1, PCI_IRQ_MSI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) if (ret > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) ret = request_irq(ha->pdev->irq, qla4_8xxx_msi_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 0, DRIVER_NAME, ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) DEBUG2(ql4_printk(KERN_INFO, ha, "MSI: Enabled.\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) goto irq_attached;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) ql4_printk(KERN_WARNING, ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) "MSI: Failed to reserve interrupt %d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) "already in use.\n", ha->pdev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) pci_free_irq_vectors(ha->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) try_intx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) if (is_qla8022(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) ql4_printk(KERN_WARNING, ha, "%s: ISP82xx Legacy interrupt not supported\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) goto irq_not_attached;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) /* Trying INTx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) IRQF_SHARED, DRIVER_NAME, ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) DEBUG2(ql4_printk(KERN_INFO, ha, "INTx: Enabled.\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) goto irq_attached;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) ql4_printk(KERN_WARNING, ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) "INTx: Failed to reserve interrupt %d already in"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) " use.\n", ha->pdev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) goto irq_not_attached;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) irq_attached:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) set_bit(AF_IRQ_ATTACHED, &ha->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) ha->host->irq = ha->pdev->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) ql4_printk(KERN_INFO, ha, "%s: irq %d attached\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) __func__, ha->pdev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) rval = QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) irq_not_attached:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) void qla4xxx_free_irqs(struct scsi_qla_host *ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) if (!test_and_clear_bit(AF_IRQ_ATTACHED, &ha->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) if (ha->pdev->msix_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) free_irq(pci_irq_vector(ha->pdev, 1), ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) free_irq(pci_irq_vector(ha->pdev, 0), ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) pci_free_irq_vectors(ha->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) }