ql4_isr.c revision 7d12e780e003f93433d49ce78cfedf4b4c52adc5
1afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu/* 2afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * QLogic iSCSI HBA Driver 3afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * Copyright (c) 2003-2006 QLogic Corporation 4afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * 5afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * See LICENSE.qla4xxx for copyright and licensing details. 6afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu */ 7afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 8afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu#include "ql4_def.h" 9afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 10afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu/** 11afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * qla2x00_process_completed_request() - Process a Fast Post response. 12afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * @ha: SCSI driver HA context 13afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * @index: SRB index 14afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu **/ 15afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulustatic void qla4xxx_process_completed_request(struct scsi_qla_host *ha, 16afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu uint32_t index) 17afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu{ 18afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu struct srb *srb; 19afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 20afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu srb = qla4xxx_del_from_active_array(ha, index); 21afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (srb) { 22afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Save ISP completion status */ 23afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu srb->cmd->result = DID_OK << 16; 24afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu qla4xxx_srb_compl(ha, srb); 25afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } else { 26afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld: Invalid ISP SCSI completion handle = " 27afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "%d\n", ha->host_no, index)); 28afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu set_bit(DPC_RESET_HA, &ha->dpc_flags); 29afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 30afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu} 31afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 32afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu/** 33afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * qla4xxx_status_entry - processes status IOCBs 34afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * @ha: Pointer to host adapter structure. 35afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * @sts_entry: Pointer to status entry structure. 36afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu **/ 37afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulustatic void qla4xxx_status_entry(struct scsi_qla_host *ha, 38afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu struct status_entry *sts_entry) 39afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu{ 40afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu uint8_t scsi_status; 41afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu struct scsi_cmnd *cmd; 42afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu struct srb *srb; 43afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu struct ddb_entry *ddb_entry; 44afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu uint32_t residual; 45afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu uint16_t sensebytecnt; 46afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 47afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (sts_entry->completionStatus == SCS_COMPLETE && 48afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu sts_entry->scsiStatus == 0) { 49afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu qla4xxx_process_completed_request(ha, 50afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu le32_to_cpu(sts_entry-> 51afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu handle)); 52afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu return; 53afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 54afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 55afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu srb = qla4xxx_del_from_active_array(ha, le32_to_cpu(sts_entry->handle)); 56afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (!srb) { 57afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* FIXMEdg: Don't we need to reset ISP in this case??? */ 58afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk(KERN_WARNING "scsi%ld: %s: Status Entry invalid " 59afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "handle 0x%x, sp=%p. This cmd may have already " 60afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "been completed.\n", ha->host_no, __func__, 61afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu le32_to_cpu(sts_entry->handle), srb)); 62afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu return; 63afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 64afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 65afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd = srb->cmd; 66afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (cmd == NULL) { 67afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld: %s: Command already returned back to " 68afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "OS pkt->handle=%d srb=%p srb->state:%d\n", 69afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->host_no, __func__, sts_entry->handle, 70afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu srb, srb->state)); 71afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu dev_warn(&ha->pdev->dev, "Command is NULL:" 72afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu " already returned to OS (srb=%p)\n", srb); 73afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu return; 74afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 75afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 76afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ddb_entry = srb->ddb; 77afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (ddb_entry == NULL) { 78afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->result = DID_NO_CONNECT << 16; 79afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu goto status_entry_exit; 80afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 81afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 82afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu residual = le32_to_cpu(sts_entry->residualByteCnt); 83afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 84afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Translate ISP error to a Linux SCSI error. */ 85afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu scsi_status = sts_entry->scsiStatus; 86afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu switch (sts_entry->completionStatus) { 87afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case SCS_COMPLETE: 88afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (scsi_status == 0) { 89afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->result = DID_OK << 16; 90afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 91afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 92afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 93afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (sts_entry->iscsiFlags & 94afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu (ISCSI_FLAG_RESIDUAL_OVER|ISCSI_FLAG_RESIDUAL_UNDER)) 95afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->resid = residual; 96afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 97afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->result = DID_OK << 16 | scsi_status; 98afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 99afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (scsi_status != SCSI_CHECK_CONDITION) 100afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 101afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 102afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Copy Sense Data into sense buffer. */ 103afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer)); 104afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 105afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu sensebytecnt = le16_to_cpu(sts_entry->senseDataByteCnt); 106afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (sensebytecnt == 0) 107afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 108afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 109afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu memcpy(cmd->sense_buffer, sts_entry->senseData, 110afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu min(sensebytecnt, 111afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu (uint16_t) sizeof(cmd->sense_buffer))); 112afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 113afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld:%d:%d:%d: %s: sense key = %x, " 114afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "ASC/ASCQ = %02x/%02x\n", ha->host_no, 115afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->device->channel, cmd->device->id, 116afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->device->lun, __func__, 117afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu sts_entry->senseData[2] & 0x0f, 118afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu sts_entry->senseData[12], 119afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu sts_entry->senseData[13])); 120afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 121afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu srb->flags |= SRB_GOT_SENSE; 122afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 123afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 124afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case SCS_INCOMPLETE: 125afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Always set the status to DID_ERROR, since 126afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * all conditions result in that status anyway */ 127afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->result = DID_ERROR << 16; 128afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 129afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 130afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case SCS_RESET_OCCURRED: 131afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld:%d:%d:%d: %s: Device RESET occurred\n", 132afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->host_no, cmd->device->channel, 133afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->device->id, cmd->device->lun, __func__)); 134afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 135afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->result = DID_RESET << 16; 136afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 137afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 138afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case SCS_ABORTED: 139afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld:%d:%d:%d: %s: Abort occurred\n", 140afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->host_no, cmd->device->channel, 141afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->device->id, cmd->device->lun, __func__)); 142afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 143afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->result = DID_RESET << 16; 144afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 145afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 146afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case SCS_TIMEOUT: 147afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk(KERN_INFO "scsi%ld:%d:%d:%d: Timeout\n", 148afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->host_no, cmd->device->channel, 149afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->device->id, cmd->device->lun)); 150afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 151afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->result = DID_BUS_BUSY << 16; 152afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 153afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* 154afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * Mark device missing so that we won't continue to send 155afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * I/O to this device. We should get a ddb state change 156afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * AEN soon. 157afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu */ 158afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (atomic_read(&ddb_entry->state) == DDB_STATE_ONLINE) 159afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu qla4xxx_mark_device_missing(ha, ddb_entry); 160afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 161afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 162afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case SCS_DATA_UNDERRUN: 163afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case SCS_DATA_OVERRUN: 164afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (sts_entry->iscsiFlags & ISCSI_FLAG_RESIDUAL_OVER) { 165afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld:%d:%d:%d: %s: " "Data overrun, " 166afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "residual = 0x%x\n", ha->host_no, 167afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->device->channel, cmd->device->id, 168afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->device->lun, __func__, residual)); 169afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 170afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->result = DID_ERROR << 16; 171afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 172afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 173afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 174afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if ((sts_entry->iscsiFlags & ISCSI_FLAG_RESIDUAL_UNDER) == 0) { 175afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* 176afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * Firmware detected a SCSI transport underrun 177afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * condition 178afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu */ 179afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->resid = residual; 180afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld:%d:%d:%d: %s: UNDERRUN status " 181afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "detected, xferlen = 0x%x, residual = " 182afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "0x%x\n", 183afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->host_no, cmd->device->channel, 184afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->device->id, 185afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->device->lun, __func__, 186afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->request_bufflen, 187afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu residual)); 188afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 189afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 190afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* 191afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * If there is scsi_status, it takes precedense over 192afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * underflow condition. 193afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu */ 194afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (scsi_status != 0) { 195afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->result = DID_OK << 16 | scsi_status; 196afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 197afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (scsi_status != SCSI_CHECK_CONDITION) 198afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 199afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 200afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Copy Sense Data into sense buffer. */ 201afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu memset(cmd->sense_buffer, 0, 202afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu sizeof(cmd->sense_buffer)); 203afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 204afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu sensebytecnt = 205afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu le16_to_cpu(sts_entry->senseDataByteCnt); 206afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (sensebytecnt == 0) 207afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 208afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 209afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu memcpy(cmd->sense_buffer, sts_entry->senseData, 210afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu min(sensebytecnt, 211afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu (uint16_t) sizeof(cmd->sense_buffer))); 212afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 213afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld:%d:%d:%d: %s: sense key = %x, " 214afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "ASC/ASCQ = %02x/%02x\n", ha->host_no, 215afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->device->channel, cmd->device->id, 216afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->device->lun, __func__, 217afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu sts_entry->senseData[2] & 0x0f, 218afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu sts_entry->senseData[12], 219afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu sts_entry->senseData[13])); 220afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } else { 221afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* 222afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * If RISC reports underrun and target does not 223afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * report it then we must have a lost frame, so 224afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * tell upper layer to retry it by reporting a 225afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * bus busy. 226afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu */ 227afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if ((sts_entry->iscsiFlags & 228afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ISCSI_FLAG_RESIDUAL_UNDER) == 0) { 229afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->result = DID_BUS_BUSY << 16; 230afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } else if ((cmd->request_bufflen - residual) < 231afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->underflow) { 232afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* 233afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * Handle mid-layer underflow??? 234afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * 235afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * For kernels less than 2.4, the driver must 236afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * return an error if an underflow is detected. 237afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * For kernels equal-to and above 2.4, the 238afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * mid-layer will appearantly handle the 239afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * underflow by detecting the residual count -- 240afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * unfortunately, we do not see where this is 241afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * actually being done. In the interim, we 242afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * will return DID_ERROR. 243afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu */ 244afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld:%d:%d:%d: %s: " 245afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "Mid-layer Data underrun, " 246afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "xferlen = 0x%x, " 247afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "residual = 0x%x\n", ha->host_no, 248afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->device->channel, 249afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->device->id, 250afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->device->lun, __func__, 251afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->request_bufflen, residual)); 252afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 253afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->result = DID_ERROR << 16; 254afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } else { 255afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->result = DID_OK << 16; 256afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 257afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 258afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 259afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 260afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case SCS_DEVICE_LOGGED_OUT: 261afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case SCS_DEVICE_UNAVAILABLE: 262afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* 263afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * Mark device missing so that we won't continue to 264afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * send I/O to this device. We should get a ddb 265afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * state change AEN soon. 266afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu */ 267afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (atomic_read(&ddb_entry->state) == DDB_STATE_ONLINE) 268afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu qla4xxx_mark_device_missing(ha, ddb_entry); 269afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 270afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->result = DID_BUS_BUSY << 16; 271afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 272afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 273afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case SCS_QUEUE_FULL: 274afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* 275afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * SCSI Mid-Layer handles device queue full 276afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu */ 277afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->result = DID_OK << 16 | sts_entry->scsiStatus; 278afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld:%d:%d: %s: QUEUE FULL detected " 279afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "compl=%02x, scsi=%02x, state=%02x, iFlags=%02x," 280afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu " iResp=%02x\n", ha->host_no, cmd->device->id, 281afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->device->lun, __func__, 282afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu sts_entry->completionStatus, 283afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu sts_entry->scsiStatus, sts_entry->state_flags, 284afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu sts_entry->iscsiFlags, 285afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu sts_entry->iscsiResponse)); 286afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 287afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 288afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu default: 289afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->result = DID_ERROR << 16; 290afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 291afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 292afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 293afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulustatus_entry_exit: 294afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 295afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* complete the request */ 296afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu srb->cc_stat = sts_entry->completionStatus; 297afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu qla4xxx_srb_compl(ha, srb); 298afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu} 299afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 300afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu/** 301afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * qla4xxx_process_response_queue - process response queue completions 302afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * @ha: Pointer to host adapter structure. 303afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * 304afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * This routine process response queue completions in interrupt context. 305afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * Hardware_lock locked upon entry 306afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu **/ 307afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulustatic void qla4xxx_process_response_queue(struct scsi_qla_host * ha) 308afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu{ 309afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu uint32_t count = 0; 310afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu struct srb *srb = NULL; 311afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu struct status_entry *sts_entry; 312afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 313afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Process all responses from response queue */ 314afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu while ((ha->response_in = 315afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu (uint16_t)le32_to_cpu(ha->shadow_regs->rsp_q_in)) != 316afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->response_out) { 317afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu sts_entry = (struct status_entry *) ha->response_ptr; 318afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu count++; 319afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 320afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Advance pointers for next entry */ 321afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (ha->response_out == (RESPONSE_QUEUE_DEPTH - 1)) { 322afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->response_out = 0; 323afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->response_ptr = ha->response_ring; 324afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } else { 325afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->response_out++; 326afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->response_ptr++; 327afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 328afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 329afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* process entry */ 330afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu switch (sts_entry->hdr.entryType) { 331afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case ET_STATUS: 332afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* 333afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * Common status - Single completion posted in single 334afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * IOSB. 335afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu */ 336afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu qla4xxx_status_entry(ha, sts_entry); 337afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 338afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 339afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case ET_PASSTHRU_STATUS: 340afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 341afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 342afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case ET_STATUS_CONTINUATION: 343afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Just throw away the status continuation entries */ 344afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld: %s: Status Continuation entry " 345afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "- ignoring\n", ha->host_no, __func__)); 346afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 347afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 348afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case ET_COMMAND: 349afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* ISP device queue is full. Command not 350afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * accepted by ISP. Queue command for 351afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * later */ 352afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 353afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu srb = qla4xxx_del_from_active_array(ha, 354afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu le32_to_cpu(sts_entry-> 355afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu handle)); 356afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (srb == NULL) 357afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu goto exit_prq_invalid_handle; 358afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 359afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld: %s: FW device queue full, " 360afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "srb %p\n", ha->host_no, __func__, srb)); 361afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 362afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* ETRY normally by sending it back with 363afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * DID_BUS_BUSY */ 364afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu srb->cmd->result = DID_BUS_BUSY << 16; 365afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu qla4xxx_srb_compl(ha, srb); 366afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 367afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 368afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case ET_CONTINUE: 369afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Just throw away the continuation entries */ 370afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld: %s: Continuation entry - " 371afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "ignoring\n", ha->host_no, __func__)); 372afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 373afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 374afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu default: 375afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* 376afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * Invalid entry in response queue, reset RISC 377afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * firmware. 378afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu */ 379afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld: %s: Invalid entry %x in " 380afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "response queue \n", ha->host_no, 381afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu __func__, 382afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu sts_entry->hdr.entryType)); 383afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu goto exit_prq_error; 384afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 385afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 386afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 387afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* 388afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * Done with responses, update the ISP For QLA4010, this also clears 389afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * the interrupt. 390afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu */ 391afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu writel(ha->response_out, &ha->reg->rsp_q_out); 392afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu readl(&ha->reg->rsp_q_out); 393afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 394afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu return; 395afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 396afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajuluexit_prq_invalid_handle: 397afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld: %s: Invalid handle(srb)=%p type=%x IOCS=%x\n", 398afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->host_no, __func__, srb, sts_entry->hdr.entryType, 399afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu sts_entry->completionStatus)); 400afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 401afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajuluexit_prq_error: 402afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu writel(ha->response_out, &ha->reg->rsp_q_out); 403afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu readl(&ha->reg->rsp_q_out); 404afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 405afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu set_bit(DPC_RESET_HA, &ha->dpc_flags); 406afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu} 407afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 408afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu/** 409afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * qla4xxx_isr_decode_mailbox - decodes mailbox status 410afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * @ha: Pointer to host adapter structure. 411afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * @mailbox_status: Mailbox status. 412afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * 413afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * This routine decodes the mailbox status during the ISR. 414afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * Hardware_lock locked upon entry. runs in interrupt context. 415afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu **/ 416afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulustatic void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha, 417afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu uint32_t mbox_status) 418afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu{ 419afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu int i; 420afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 421afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if ((mbox_status == MBOX_STS_BUSY) || 422afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu (mbox_status == MBOX_STS_INTERMEDIATE_COMPLETION) || 423afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu (mbox_status >> 12 == MBOX_COMPLETION_STATUS)) { 424afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->mbox_status[0] = mbox_status; 425afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 426afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (test_bit(AF_MBOX_COMMAND, &ha->flags)) { 427afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* 428afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * Copy all mailbox registers to a temporary 429afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * location and set mailbox command done flag 430afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu */ 431afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu for (i = 1; i < ha->mbox_status_count; i++) 432afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->mbox_status[i] = 433afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu readl(&ha->reg->mailbox[i]); 434afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 435afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu set_bit(AF_MBOX_COMMAND_DONE, &ha->flags); 436afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu wake_up(&ha->mailbox_wait_queue); 437afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 438afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } else if (mbox_status >> 12 == MBOX_ASYNC_EVENT_STATUS) { 439afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Immediately process the AENs that don't require much work. 440afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * Only queue the database_changed AENs */ 441afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu switch (mbox_status) { 442afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_SYSTEM_ERROR: 443afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Log Mailbox registers */ 444afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (ql4xdontresethba) { 445afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("%s:Dont Reset HBA\n", 446afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu __func__)); 447afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } else { 448afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu set_bit(AF_GET_CRASH_RECORD, &ha->flags); 449afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu set_bit(DPC_RESET_HA, &ha->dpc_flags); 450afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 451afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 452afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 453afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_REQUEST_TRANSFER_ERROR: 454afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_RESPONSE_TRANSFER_ERROR: 455afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_NVRAM_INVALID: 456afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_IP_ADDRESS_CHANGED: 457afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_DHCP_LEASE_EXPIRED: 458afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld: AEN %04x, ERROR Status, " 459afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "Reset HA\n", ha->host_no, mbox_status)); 460afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu set_bit(DPC_RESET_HA, &ha->dpc_flags); 461afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 462afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 463afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_LINK_UP: 464afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld: AEN %04x Adapter LINK UP\n", 465afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->host_no, mbox_status)); 466afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu set_bit(AF_LINK_UP, &ha->flags); 467afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 468afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 469afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_LINK_DOWN: 470afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld: AEN %04x Adapter LINK DOWN\n", 471afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->host_no, mbox_status)); 472afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu clear_bit(AF_LINK_UP, &ha->flags); 473afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 474afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 475afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_HEARTBEAT: 476afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->seconds_since_last_heartbeat = 0; 477afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 478afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 479afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_DHCP_LEASE_ACQUIRED: 480afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld: AEN %04x DHCP LEASE " 481afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "ACQUIRED\n", ha->host_no, mbox_status)); 482afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu set_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags); 483afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 484afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 485afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_PROTOCOL_STATISTIC_ALARM: 486afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_SCSI_COMMAND_PDU_REJECTED: /* Target 487afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * mode 488afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * only */ 489afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_UNSOLICITED_PDU_RECEIVED: /* Connection mode */ 490afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_IPSEC_SYSTEM_FATAL_ERROR: 491afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_SUBNET_STATE_CHANGE: 492afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* No action */ 493afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld: AEN %04x\n", ha->host_no, 494afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu mbox_status)); 495afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 496afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 497afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_MAC_ADDRESS_CHANGED: 498afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_DNS: 499afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* No action */ 500afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk(KERN_INFO "scsi%ld: AEN %04x, " 501afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "mbox_sts[1]=%04x, mbox_sts[2]=%04x\n", 502afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->host_no, mbox_status, 503afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu readl(&ha->reg->mailbox[1]), 504afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu readl(&ha->reg->mailbox[2]))); 505afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 506afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 507afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_SELF_TEST_FAILED: 508afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_LOGIN_FAILED: 509afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* No action */ 510afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld: AEN %04x, mbox_sts[1]=%04x, " 511afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "mbox_sts[2]=%04x, mbox_sts[3]=%04x\n", 512afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->host_no, mbox_status, 513afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu readl(&ha->reg->mailbox[1]), 514afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu readl(&ha->reg->mailbox[2]), 515afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu readl(&ha->reg->mailbox[3]))); 516afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 517afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 518afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_DATABASE_CHANGED: 519afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Queue AEN information and process it in the DPC 520afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * routine */ 521afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (ha->aen_q_count > 0) { 522afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* advance pointer */ 523afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (ha->aen_in == (MAX_AEN_ENTRIES - 1)) 524afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->aen_in = 0; 525afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu else 526afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->aen_in++; 527afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 528afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* decrement available counter */ 529afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->aen_q_count--; 530afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 531afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu for (i = 1; i < MBOX_AEN_REG_COUNT; i++) 532afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->aen_q[ha->aen_in].mbox_sts[i] = 533afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu readl(&ha->reg->mailbox[i]); 534afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 535afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->aen_q[ha->aen_in].mbox_sts[0] = mbox_status; 536afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 537afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* print debug message */ 538afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld: AEN[%d] %04x queued" 539afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu " mb1:0x%x mb2:0x%x mb3:0x%x mb4:0x%x\n", 540afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->host_no, ha->aen_in, 541afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu mbox_status, 542afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->aen_q[ha->aen_in].mbox_sts[1], 543afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->aen_q[ha->aen_in].mbox_sts[2], 544afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->aen_q[ha->aen_in].mbox_sts[3], 545afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->aen_q[ha->aen_in]. mbox_sts[4])); 546afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 547afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* The DPC routine will process the aen */ 548afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu set_bit(DPC_AEN, &ha->dpc_flags); 549afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } else { 550afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld: %s: aen %04x, queue " 551afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "overflowed! AEN LOST!!\n", 552afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->host_no, __func__, 553afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu mbox_status)); 554afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 555afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld: DUMP AEN QUEUE\n", 556afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->host_no)); 557afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 558afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu for (i = 0; i < MAX_AEN_ENTRIES; i++) { 559afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("AEN[%d] %04x %04x %04x " 560afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "%04x\n", i, 561afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->aen_q[i].mbox_sts[0], 562afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->aen_q[i].mbox_sts[1], 563afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->aen_q[i].mbox_sts[2], 564afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->aen_q[i].mbox_sts[3])); 565afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 566afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 567afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 568afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 569afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu default: 570afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk(KERN_WARNING 571afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "scsi%ld: AEN %04x UNKNOWN\n", 572afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->host_no, mbox_status)); 573afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 574afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 575afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } else { 576afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld: Unknown mailbox status %08X\n", 577afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->host_no, mbox_status)); 578afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 579afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->mbox_status[0] = mbox_status; 580afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 581afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu} 582afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 583afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu/** 584afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * qla4xxx_interrupt_service_routine - isr 585afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * @ha: pointer to host adapter structure. 586afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * 587afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * This is the main interrupt service routine. 588afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * hardware_lock locked upon entry. runs in interrupt context. 589afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu **/ 590afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajuluvoid qla4xxx_interrupt_service_routine(struct scsi_qla_host * ha, 591afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu uint32_t intr_status) 592afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu{ 593afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Process response queue interrupt. */ 594afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (intr_status & CSR_SCSI_COMPLETION_INTR) 595afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu qla4xxx_process_response_queue(ha); 596afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 597afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Process mailbox/asynch event interrupt.*/ 598afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (intr_status & CSR_SCSI_PROCESSOR_INTR) { 599afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu qla4xxx_isr_decode_mailbox(ha, 600afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu readl(&ha->reg->mailbox[0])); 601afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 602afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Clear Mailbox Interrupt */ 603afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu writel(set_rmask(CSR_SCSI_PROCESSOR_INTR), 604afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu &ha->reg->ctrl_status); 605afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu readl(&ha->reg->ctrl_status); 606afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 607afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu} 608afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 609afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu/** 610afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * qla4xxx_intr_handler - hardware interrupt handler. 611afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * @irq: Unused 612afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * @dev_id: Pointer to host adapter structure 613afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu **/ 6147d12e780e003f93433d49ce78cfedf4b4c52adc5David Howellsirqreturn_t qla4xxx_intr_handler(int irq, void *dev_id) 615afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu{ 616afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu struct scsi_qla_host *ha; 617afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu uint32_t intr_status; 618afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu unsigned long flags = 0; 619afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu uint8_t reqs_count = 0; 620afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 621afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha = (struct scsi_qla_host *) dev_id; 622afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (!ha) { 623afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk(KERN_INFO 624afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "qla4xxx: Interrupt with NULL host ptr\n")); 625afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu return IRQ_NONE; 626afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 627afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 628afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu spin_lock_irqsave(&ha->hardware_lock, flags); 629afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 630afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* 631afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * Repeatedly service interrupts up to a maximum of 632afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * MAX_REQS_SERVICED_PER_INTR 633afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu */ 634afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu while (1) { 635afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* 636afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * Read interrupt status 637afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu */ 638afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (le32_to_cpu(ha->shadow_regs->rsp_q_in) != 639afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->response_out) 640afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu intr_status = CSR_SCSI_COMPLETION_INTR; 641afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu else 642afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu intr_status = readl(&ha->reg->ctrl_status); 643afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 644afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if ((intr_status & 645afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu (CSR_SCSI_RESET_INTR|CSR_FATAL_ERROR|INTR_PENDING)) == 646afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 0) { 647afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (reqs_count == 0) 648afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->spurious_int_count++; 649afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 650afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 651afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 652afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (intr_status & CSR_FATAL_ERROR) { 653afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk(KERN_INFO "scsi%ld: Fatal Error, " 654afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "Status 0x%04x\n", ha->host_no, 655afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu readl(isp_port_error_status (ha)))); 656afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 657afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Issue Soft Reset to clear this error condition. 658afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * This will prevent the RISC from repeatedly 659afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * interrupting the driver; thus, allowing the DPC to 660afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * get scheduled to continue error recovery. 661afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * NOTE: Disabling RISC interrupts does not work in 662afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * this case, as CSR_FATAL_ERROR overrides 663afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * CSR_SCSI_INTR_ENABLE */ 664afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if ((readl(&ha->reg->ctrl_status) & 665afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu CSR_SCSI_RESET_INTR) == 0) { 666afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu writel(set_rmask(CSR_SOFT_RESET), 667afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu &ha->reg->ctrl_status); 668afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu readl(&ha->reg->ctrl_status); 669afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 670afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 671afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu writel(set_rmask(CSR_FATAL_ERROR), 672afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu &ha->reg->ctrl_status); 673afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu readl(&ha->reg->ctrl_status); 674afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 675afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu __qla4xxx_disable_intrs(ha); 676afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 677afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu set_bit(DPC_RESET_HA, &ha->dpc_flags); 678afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 679afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 680afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } else if (intr_status & CSR_SCSI_RESET_INTR) { 681afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu clear_bit(AF_ONLINE, &ha->flags); 682afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu __qla4xxx_disable_intrs(ha); 683afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 684afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu writel(set_rmask(CSR_SCSI_RESET_INTR), 685afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu &ha->reg->ctrl_status); 686afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu readl(&ha->reg->ctrl_status); 687afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 688afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu set_bit(DPC_RESET_HA_INTR, &ha->dpc_flags); 689afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 690afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 691afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } else if (intr_status & INTR_PENDING) { 692afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu qla4xxx_interrupt_service_routine(ha, intr_status); 693afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->total_io_count++; 694afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (++reqs_count == MAX_REQS_SERVICED_PER_INTR) 695afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 696afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 697afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu intr_status = 0; 698afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 699afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 700afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 701afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu spin_unlock_irqrestore(&ha->hardware_lock, flags); 702afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 703afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu return IRQ_HANDLED; 704afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu} 705afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 706afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu/** 707afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * qla4xxx_process_aen - processes AENs generated by firmware 708afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * @ha: pointer to host adapter structure. 709afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * @process_aen: type of AENs to process 710afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * 711afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * Processes specific types of Asynchronous Events generated by firmware. 712afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * The type of AENs to process is specified by process_aen and can be 713afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * PROCESS_ALL_AENS 0 714afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * FLUSH_DDB_CHANGED_AENS 1 715afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * RELOGIN_DDB_CHANGED_AENS 2 716afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu **/ 717afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajuluvoid qla4xxx_process_aen(struct scsi_qla_host * ha, uint8_t process_aen) 718afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu{ 719afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu uint32_t mbox_sts[MBOX_AEN_REG_COUNT]; 720afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu struct aen *aen; 721afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu int i; 722afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu unsigned long flags; 723afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 724afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu spin_lock_irqsave(&ha->hardware_lock, flags); 725afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu while (ha->aen_out != ha->aen_in) { 726afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Advance pointers for next entry */ 727afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (ha->aen_out == (MAX_AEN_ENTRIES - 1)) 728afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->aen_out = 0; 729afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu else 730afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->aen_out++; 731afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 732afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->aen_q_count++; 733afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu aen = &ha->aen_q[ha->aen_out]; 734afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 735afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* copy aen information to local structure */ 736afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu for (i = 0; i < MBOX_AEN_REG_COUNT; i++) 737afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu mbox_sts[i] = aen->mbox_sts[i]; 738afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 739afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu spin_unlock_irqrestore(&ha->hardware_lock, flags); 740afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 741afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG(printk("scsi%ld: AEN[%d] %04x, index [%d] state=%04x " 742afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "mod=%x conerr=%08x \n", ha->host_no, ha->aen_out, 743afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu mbox_sts[0], mbox_sts[2], mbox_sts[3], 744afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu mbox_sts[1], mbox_sts[4])); 745afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 746afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu switch (mbox_sts[0]) { 747afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_DATABASE_CHANGED: 748afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (process_aen == FLUSH_DDB_CHANGED_AENS) { 749afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld: AEN[%d] %04x, index " 750afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "[%d] state=%04x FLUSHED!\n", 751afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->host_no, ha->aen_out, 752afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu mbox_sts[0], mbox_sts[2], 753afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu mbox_sts[3])); 754afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 755afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } else if (process_aen == RELOGIN_DDB_CHANGED_AENS) { 756afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* for use during init time, we only want to 757afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * relogin non-active ddbs */ 758afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu struct ddb_entry *ddb_entry; 759afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 760afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ddb_entry = 761afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* FIXME: name length? */ 762afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu qla4xxx_lookup_ddb_by_fw_index(ha, 763afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu mbox_sts[2]); 764afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (!ddb_entry) 765afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 766afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 767afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ddb_entry->dev_scan_wait_to_complete_relogin = 768afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 0; 769afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ddb_entry->dev_scan_wait_to_start_relogin = 770afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu jiffies + 771afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ((ddb_entry->default_time2wait + 772afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 4) * HZ); 773afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 774afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld: ddb index [%d] initate" 775afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu " RELOGIN after %d seconds\n", 776afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->host_no, 777afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ddb_entry->fw_ddb_index, 778afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ddb_entry->default_time2wait + 779afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 4)); 780afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 781afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 782afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 783afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (mbox_sts[1] == 0) { /* Global DB change. */ 784afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu qla4xxx_reinitialize_ddb_list(ha); 785afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } else if (mbox_sts[1] == 1) { /* Specific device. */ 786afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu qla4xxx_process_ddb_changed(ha, mbox_sts[2], 787afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu mbox_sts[3]); 788afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 789afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 790afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 791afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu spin_lock_irqsave(&ha->hardware_lock, flags); 792afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 793afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu spin_unlock_irqrestore(&ha->hardware_lock, flags); 794afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 795afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu} 796afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 797