ql4_isr.c revision 6434080b127088606e03d2ecfe5ffdd797e38d63
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" 9401425b1ea005b39dcc544bffea833f338ba84f6David C Somayajulu#include "ql4_glbl.h" 10401425b1ea005b39dcc544bffea833f338ba84f6David C Somayajulu#include "ql4_dbg.h" 11401425b1ea005b39dcc544bffea833f338ba84f6David C Somayajulu#include "ql4_inline.h" 12afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 13afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu/** 1494bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins * qla4xxx_copy_sense - copy sense data into cmd sense buffer 1594bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins * @ha: Pointer to host adapter structure. 1694bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins * @sts_entry: Pointer to status entry structure. 1794bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins * @srb: Pointer to srb structure. 1894bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins **/ 1994bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higginsstatic void qla4xxx_copy_sense(struct scsi_qla_host *ha, 2094bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins struct status_entry *sts_entry, 2194bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins struct srb *srb) 2294bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins{ 2394bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins struct scsi_cmnd *cmd = srb->cmd; 2494bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins uint16_t sense_len; 2594bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins 2694bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); 2794bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins sense_len = le16_to_cpu(sts_entry->senseDataByteCnt); 2894bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins if (sense_len == 0) 2994bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins return; 3094bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins 3194bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins /* Save total available sense length, 3294bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins * not to exceed cmd's sense buffer size */ 3394bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins sense_len = min_t(uint16_t, sense_len, SCSI_SENSE_BUFFERSIZE); 3494bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins srb->req_sense_ptr = cmd->sense_buffer; 3594bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins srb->req_sense_len = sense_len; 3694bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins 3794bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins /* Copy sense from sts_entry pkt */ 3894bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins sense_len = min_t(uint16_t, sense_len, IOCB_MAX_SENSEDATA_LEN); 3994bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins memcpy(cmd->sense_buffer, sts_entry->senseData, sense_len); 4094bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins 4194bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins DEBUG2(printk(KERN_INFO "scsi%ld:%d:%d:%d: %s: sense key = %x, " 4294bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins "ASL= %02x, ASC/ASCQ = %02x/%02x\n", ha->host_no, 4394bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins cmd->device->channel, cmd->device->id, 4494bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins cmd->device->lun, __func__, 4594bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins sts_entry->senseData[2] & 0x0f, 4694bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins sts_entry->senseData[7], 4794bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins sts_entry->senseData[12], 4894bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins sts_entry->senseData[13])); 4994bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins 5094bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins DEBUG5(qla4xxx_dump_buffer(cmd->sense_buffer, sense_len)); 5194bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins srb->flags |= SRB_GOT_SENSE; 5294bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins 5394bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins /* Update srb, in case a sts_cont pkt follows */ 5494bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins srb->req_sense_ptr += sense_len; 5594bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins srb->req_sense_len -= sense_len; 5694bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins if (srb->req_sense_len != 0) 5794bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins ha->status_srb = srb; 5894bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins else 5994bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins ha->status_srb = NULL; 6094bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins} 6194bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins 6294bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins/** 6394bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins * qla4xxx_status_cont_entry - Process a Status Continuations entry. 6494bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins * @ha: SCSI driver HA context 6594bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins * @sts_cont: Entry pointer 6694bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins * 6794bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins * Extended sense data. 6894bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins */ 6994bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higginsstatic void 7094bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higginsqla4xxx_status_cont_entry(struct scsi_qla_host *ha, 7194bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins struct status_cont_entry *sts_cont) 7294bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins{ 7394bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins struct srb *srb = ha->status_srb; 7494bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins struct scsi_cmnd *cmd; 75735e41543c12c245290cf652727893a66cbd8ab6Vikas Chaudhary uint16_t sense_len; 7694bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins 7794bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins if (srb == NULL) 7894bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins return; 7994bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins 8094bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins cmd = srb->cmd; 8194bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins if (cmd == NULL) { 8294bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins DEBUG2(printk(KERN_INFO "scsi%ld: %s: Cmd already returned " 8394bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins "back to OS srb=%p srb->state:%d\n", ha->host_no, 8494bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins __func__, srb, srb->state)); 8594bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins ha->status_srb = NULL; 8694bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins return; 8794bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins } 8894bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins 8994bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins /* Copy sense data. */ 9094bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins sense_len = min_t(uint16_t, srb->req_sense_len, 9194bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins IOCB_MAX_EXT_SENSEDATA_LEN); 9294bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins memcpy(srb->req_sense_ptr, sts_cont->ext_sense_data, sense_len); 9394bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins DEBUG5(qla4xxx_dump_buffer(srb->req_sense_ptr, sense_len)); 9494bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins 9594bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins srb->req_sense_ptr += sense_len; 9694bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins srb->req_sense_len -= sense_len; 9794bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins 9894bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins /* Place command on done queue. */ 9994bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins if (srb->req_sense_len == 0) { 10009a0f719896659a6c32df11426e55795012c06ffVikas Chaudhary kref_put(&srb->srb_ref, qla4xxx_srb_compl); 10194bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins ha->status_srb = NULL; 10294bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins } 10394bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins} 10494bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins 10594bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins/** 106afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * qla4xxx_status_entry - processes status IOCBs 107afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * @ha: Pointer to host adapter structure. 108afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * @sts_entry: Pointer to status entry structure. 109afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu **/ 110afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulustatic void qla4xxx_status_entry(struct scsi_qla_host *ha, 111afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu struct status_entry *sts_entry) 112afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu{ 113afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu uint8_t scsi_status; 114afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu struct scsi_cmnd *cmd; 115afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu struct srb *srb; 116afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu struct ddb_entry *ddb_entry; 117afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu uint32_t residual; 118afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 119afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu srb = qla4xxx_del_from_active_array(ha, le32_to_cpu(sts_entry->handle)); 120afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (!srb) { 121afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk(KERN_WARNING "scsi%ld: %s: Status Entry invalid " 122afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "handle 0x%x, sp=%p. This cmd may have already " 123afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "been completed.\n", ha->host_no, __func__, 124afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu le32_to_cpu(sts_entry->handle), srb)); 125c2660df310a3c445194748b54f51b7224639e742Vikas Chaudhary ql4_printk(KERN_WARNING, ha, "%s invalid status entry:" 126c2660df310a3c445194748b54f51b7224639e742Vikas Chaudhary " handle=0x%0x\n", __func__, sts_entry->handle); 1279d56291366cd6ab156be722e42cf487bef20f5fdDavid C Somayajulu set_bit(DPC_RESET_HA, &ha->dpc_flags); 128afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu return; 129afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 130afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 131afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd = srb->cmd; 132afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (cmd == NULL) { 133afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld: %s: Command already returned back to " 134afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "OS pkt->handle=%d srb=%p srb->state:%d\n", 135afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->host_no, __func__, sts_entry->handle, 136afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu srb, srb->state)); 137c2660df310a3c445194748b54f51b7224639e742Vikas Chaudhary ql4_printk(KERN_WARNING, ha, "Command is NULL:" 138c2660df310a3c445194748b54f51b7224639e742Vikas Chaudhary " already returned to OS (srb=%p)\n", srb); 139afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu return; 140afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 141afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 142afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ddb_entry = srb->ddb; 143afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (ddb_entry == NULL) { 144afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->result = DID_NO_CONNECT << 16; 145afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu goto status_entry_exit; 146afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 147afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 148afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu residual = le32_to_cpu(sts_entry->residualByteCnt); 149afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 150afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Translate ISP error to a Linux SCSI error. */ 151afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu scsi_status = sts_entry->scsiStatus; 152afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu switch (sts_entry->completionStatus) { 153afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case SCS_COMPLETE: 154afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 1556ea7e33ee1b74de9b60327fec1a0cd39afac3983David C Somayajulu if (sts_entry->iscsiFlags & ISCSI_FLAG_RESIDUAL_OVER) { 1566ea7e33ee1b74de9b60327fec1a0cd39afac3983David C Somayajulu cmd->result = DID_ERROR << 16; 1576ea7e33ee1b74de9b60327fec1a0cd39afac3983David C Somayajulu break; 1586ea7e33ee1b74de9b60327fec1a0cd39afac3983David C Somayajulu } 1596ea7e33ee1b74de9b60327fec1a0cd39afac3983David C Somayajulu 1606ea7e33ee1b74de9b60327fec1a0cd39afac3983David C Somayajulu if (sts_entry->iscsiFlags &ISCSI_FLAG_RESIDUAL_UNDER) { 1615f7186c841a13abff0bf81ee93754b4f46e19141FUJITA Tomonori scsi_set_resid(cmd, residual); 1629d56291366cd6ab156be722e42cf487bef20f5fdDavid C Somayajulu if (!scsi_status && ((scsi_bufflen(cmd) - residual) < 1639d56291366cd6ab156be722e42cf487bef20f5fdDavid C Somayajulu cmd->underflow)) { 1646ea7e33ee1b74de9b60327fec1a0cd39afac3983David C Somayajulu 1656ea7e33ee1b74de9b60327fec1a0cd39afac3983David C Somayajulu cmd->result = DID_ERROR << 16; 1666ea7e33ee1b74de9b60327fec1a0cd39afac3983David C Somayajulu 1676ea7e33ee1b74de9b60327fec1a0cd39afac3983David C Somayajulu DEBUG2(printk("scsi%ld:%d:%d:%d: %s: " 1686ea7e33ee1b74de9b60327fec1a0cd39afac3983David C Somayajulu "Mid-layer Data underrun0, " 1696ea7e33ee1b74de9b60327fec1a0cd39afac3983David C Somayajulu "xferlen = 0x%x, " 1706ea7e33ee1b74de9b60327fec1a0cd39afac3983David C Somayajulu "residual = 0x%x\n", ha->host_no, 1716ea7e33ee1b74de9b60327fec1a0cd39afac3983David C Somayajulu cmd->device->channel, 1726ea7e33ee1b74de9b60327fec1a0cd39afac3983David C Somayajulu cmd->device->id, 1736ea7e33ee1b74de9b60327fec1a0cd39afac3983David C Somayajulu cmd->device->lun, __func__, 1746ea7e33ee1b74de9b60327fec1a0cd39afac3983David C Somayajulu scsi_bufflen(cmd), residual)); 1756ea7e33ee1b74de9b60327fec1a0cd39afac3983David C Somayajulu break; 1766ea7e33ee1b74de9b60327fec1a0cd39afac3983David C Somayajulu } 1776ea7e33ee1b74de9b60327fec1a0cd39afac3983David C Somayajulu } 178afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 179afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->result = DID_OK << 16 | scsi_status; 180afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 181afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (scsi_status != SCSI_CHECK_CONDITION) 182afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 183afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 184afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Copy Sense Data into sense buffer. */ 18594bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins qla4xxx_copy_sense(ha, sts_entry, srb); 186afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 187afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 188afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case SCS_INCOMPLETE: 189afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Always set the status to DID_ERROR, since 190afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * all conditions result in that status anyway */ 191afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->result = DID_ERROR << 16; 192afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 193afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 194afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case SCS_RESET_OCCURRED: 195afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld:%d:%d:%d: %s: Device RESET occurred\n", 196afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->host_no, cmd->device->channel, 197afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->device->id, cmd->device->lun, __func__)); 198afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 199afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->result = DID_RESET << 16; 200afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 201afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 202afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case SCS_ABORTED: 203afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld:%d:%d:%d: %s: Abort occurred\n", 204afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->host_no, cmd->device->channel, 205afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->device->id, cmd->device->lun, __func__)); 206afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 207afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->result = DID_RESET << 16; 208afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 209afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 210afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case SCS_TIMEOUT: 211afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk(KERN_INFO "scsi%ld:%d:%d:%d: Timeout\n", 212afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->host_no, cmd->device->channel, 213afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->device->id, cmd->device->lun)); 214afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 21556d7fcfa815564b40a1b0ec7a30ea8cb3bc0713eMike Christie cmd->result = DID_TRANSPORT_DISRUPTED << 16; 216afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 217afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* 218afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * Mark device missing so that we won't continue to send 219afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * I/O to this device. We should get a ddb state change 220afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * AEN soon. 221afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu */ 222afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (atomic_read(&ddb_entry->state) == DDB_STATE_ONLINE) 223afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu qla4xxx_mark_device_missing(ha, ddb_entry); 224afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 225afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 226afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case SCS_DATA_UNDERRUN: 227afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case SCS_DATA_OVERRUN: 2286ea7e33ee1b74de9b60327fec1a0cd39afac3983David C Somayajulu if ((sts_entry->iscsiFlags & ISCSI_FLAG_RESIDUAL_OVER) || 229b06fc73a9ebd352065dd4dd3139fb53ed72ac970Mike Christie (sts_entry->completionStatus == SCS_DATA_OVERRUN)) { 230b06fc73a9ebd352065dd4dd3139fb53ed72ac970Mike Christie DEBUG2(printk("scsi%ld:%d:%d:%d: %s: " "Data overrun\n", 231b06fc73a9ebd352065dd4dd3139fb53ed72ac970Mike Christie ha->host_no, 232afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->device->channel, cmd->device->id, 233b06fc73a9ebd352065dd4dd3139fb53ed72ac970Mike Christie cmd->device->lun, __func__)); 234afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 235afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->result = DID_ERROR << 16; 236afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 237afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 238afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 2396ea7e33ee1b74de9b60327fec1a0cd39afac3983David C Somayajulu scsi_set_resid(cmd, residual); 240afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 241afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* 242afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * If there is scsi_status, it takes precedense over 243afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * underflow condition. 244afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu */ 245afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (scsi_status != 0) { 246afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->result = DID_OK << 16 | scsi_status; 247afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 248afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (scsi_status != SCSI_CHECK_CONDITION) 249afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 250afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 251afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Copy Sense Data into sense buffer. */ 25294bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins qla4xxx_copy_sense(ha, sts_entry, srb); 253afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } else { 254afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* 255afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * If RISC reports underrun and target does not 256afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * report it then we must have a lost frame, so 257afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * tell upper layer to retry it by reporting a 258afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * bus busy. 259afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu */ 260afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if ((sts_entry->iscsiFlags & 261afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ISCSI_FLAG_RESIDUAL_UNDER) == 0) { 262afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->result = DID_BUS_BUSY << 16; 2635f7186c841a13abff0bf81ee93754b4f46e19141FUJITA Tomonori } else if ((scsi_bufflen(cmd) - residual) < 264afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->underflow) { 265afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* 266afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * Handle mid-layer underflow??? 267afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * 268afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * For kernels less than 2.4, the driver must 269afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * return an error if an underflow is detected. 270afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * For kernels equal-to and above 2.4, the 271afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * mid-layer will appearantly handle the 272afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * underflow by detecting the residual count -- 273afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * unfortunately, we do not see where this is 274afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * actually being done. In the interim, we 275afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * will return DID_ERROR. 276afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu */ 277afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld:%d:%d:%d: %s: " 2786ea7e33ee1b74de9b60327fec1a0cd39afac3983David C Somayajulu "Mid-layer Data underrun1, " 2796ea7e33ee1b74de9b60327fec1a0cd39afac3983David C Somayajulu "xferlen = 0x%x, " 2806ea7e33ee1b74de9b60327fec1a0cd39afac3983David C Somayajulu "residual = 0x%x\n", ha->host_no, 2816ea7e33ee1b74de9b60327fec1a0cd39afac3983David C Somayajulu cmd->device->channel, 2826ea7e33ee1b74de9b60327fec1a0cd39afac3983David C Somayajulu cmd->device->id, 2836ea7e33ee1b74de9b60327fec1a0cd39afac3983David C Somayajulu cmd->device->lun, __func__, 2846ea7e33ee1b74de9b60327fec1a0cd39afac3983David C Somayajulu scsi_bufflen(cmd), residual)); 285afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 286afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->result = DID_ERROR << 16; 287afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } else { 288afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->result = DID_OK << 16; 289afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 290afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 291afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 292afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 293afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case SCS_DEVICE_LOGGED_OUT: 294afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case SCS_DEVICE_UNAVAILABLE: 295f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary DEBUG2(printk(KERN_INFO "scsi%ld:%d:%d:%d: SCS_DEVICE " 296f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary "state: 0x%x\n", ha->host_no, 297f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary cmd->device->channel, cmd->device->id, 298f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary cmd->device->lun, sts_entry->completionStatus)); 299afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* 300afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * Mark device missing so that we won't continue to 301afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * send I/O to this device. We should get a ddb 302afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * state change AEN soon. 303afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu */ 304afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (atomic_read(&ddb_entry->state) == DDB_STATE_ONLINE) 305afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu qla4xxx_mark_device_missing(ha, ddb_entry); 306afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 30756d7fcfa815564b40a1b0ec7a30ea8cb3bc0713eMike Christie cmd->result = DID_TRANSPORT_DISRUPTED << 16; 308afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 309afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 310afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case SCS_QUEUE_FULL: 311afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* 312afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * SCSI Mid-Layer handles device queue full 313afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu */ 314afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->result = DID_OK << 16 | sts_entry->scsiStatus; 315afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld:%d:%d: %s: QUEUE FULL detected " 316afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "compl=%02x, scsi=%02x, state=%02x, iFlags=%02x," 317afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu " iResp=%02x\n", ha->host_no, cmd->device->id, 318afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->device->lun, __func__, 319afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu sts_entry->completionStatus, 320afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu sts_entry->scsiStatus, sts_entry->state_flags, 321afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu sts_entry->iscsiFlags, 322afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu sts_entry->iscsiResponse)); 323afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 324afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 325afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu default: 326afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu cmd->result = DID_ERROR << 16; 327afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 328afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 329afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 330afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulustatus_entry_exit: 331afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 33294bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins /* complete the request, if not waiting for status_continuation pkt */ 333afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu srb->cc_stat = sts_entry->completionStatus; 33494bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins if (ha->status_srb == NULL) 33509a0f719896659a6c32df11426e55795012c06ffVikas Chaudhary kref_put(&srb->srb_ref, qla4xxx_srb_compl); 336afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu} 337afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 338afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu/** 339afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * qla4xxx_process_response_queue - process response queue completions 340afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * @ha: Pointer to host adapter structure. 341afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * 342afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * This routine process response queue completions in interrupt context. 343afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * Hardware_lock locked upon entry 344afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu **/ 345f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudharyvoid qla4xxx_process_response_queue(struct scsi_qla_host *ha) 346afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu{ 347afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu uint32_t count = 0; 348afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu struct srb *srb = NULL; 349afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu struct status_entry *sts_entry; 350afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 351afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Process all responses from response queue */ 352f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary while ((ha->response_ptr->signature != RESPONSE_PROCESSED)) { 353afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu sts_entry = (struct status_entry *) ha->response_ptr; 354afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu count++; 355afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 356afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Advance pointers for next entry */ 357afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (ha->response_out == (RESPONSE_QUEUE_DEPTH - 1)) { 358afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->response_out = 0; 359afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->response_ptr = ha->response_ring; 360afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } else { 361afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->response_out++; 362afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->response_ptr++; 363afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 364afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 365afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* process entry */ 366afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu switch (sts_entry->hdr.entryType) { 367afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case ET_STATUS: 36894bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins /* Common status */ 369afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu qla4xxx_status_entry(ha, sts_entry); 370afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 371afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 372afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case ET_PASSTHRU_STATUS: 373afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 374afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 375afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case ET_STATUS_CONTINUATION: 37694bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins qla4xxx_status_cont_entry(ha, 37794bced3c1b371014cbd187f2df5539b13a0e3b90Karen Higgins (struct status_cont_entry *) sts_entry); 378afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 379afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 380afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case ET_COMMAND: 381afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* ISP device queue is full. Command not 382afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * accepted by ISP. Queue command for 383afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * later */ 384afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 385afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu srb = qla4xxx_del_from_active_array(ha, 386afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu le32_to_cpu(sts_entry-> 387afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu handle)); 388afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (srb == NULL) 389afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu goto exit_prq_invalid_handle; 390afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 391afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld: %s: FW device queue full, " 392afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "srb %p\n", ha->host_no, __func__, srb)); 393afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 394afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* ETRY normally by sending it back with 395afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * DID_BUS_BUSY */ 396afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu srb->cmd->result = DID_BUS_BUSY << 16; 39709a0f719896659a6c32df11426e55795012c06ffVikas Chaudhary kref_put(&srb->srb_ref, qla4xxx_srb_compl); 398afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 399afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 400afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case ET_CONTINUE: 401afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Just throw away the continuation entries */ 402afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld: %s: Continuation entry - " 403afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "ignoring\n", ha->host_no, __func__)); 404afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 405afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 406afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu default: 407afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* 408afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * Invalid entry in response queue, reset RISC 409afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * firmware. 410afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu */ 411afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld: %s: Invalid entry %x in " 412afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "response queue \n", ha->host_no, 413afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu __func__, 414afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu sts_entry->hdr.entryType)); 415afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu goto exit_prq_error; 416afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 417f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ((struct response *)sts_entry)->signature = RESPONSE_PROCESSED; 418f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary wmb(); 419afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 420afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 421afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* 422f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * Tell ISP we're done with response(s). This also clears the interrupt. 423afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu */ 424f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ha->isp_ops->complete_iocb(ha); 425afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 426afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu return; 427afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 428afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajuluexit_prq_invalid_handle: 429afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld: %s: Invalid handle(srb)=%p type=%x IOCS=%x\n", 430afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->host_no, __func__, srb, sts_entry->hdr.entryType, 431afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu sts_entry->completionStatus)); 432afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 433afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajuluexit_prq_error: 434f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ha->isp_ops->complete_iocb(ha); 435afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu set_bit(DPC_RESET_HA, &ha->dpc_flags); 436afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu} 437afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 438afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu/** 439afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * qla4xxx_isr_decode_mailbox - decodes mailbox status 440afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * @ha: Pointer to host adapter structure. 441afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * @mailbox_status: Mailbox status. 442afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * 443afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * This routine decodes the mailbox status during the ISR. 444afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * Hardware_lock locked upon entry. runs in interrupt context. 445afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu **/ 446afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulustatic void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha, 447afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu uint32_t mbox_status) 448afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu{ 449afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu int i; 450f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary uint32_t mbox_sts[MBOX_AEN_REG_COUNT]; 451afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 452afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if ((mbox_status == MBOX_STS_BUSY) || 453afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu (mbox_status == MBOX_STS_INTERMEDIATE_COMPLETION) || 454afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu (mbox_status >> 12 == MBOX_COMPLETION_STATUS)) { 455afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->mbox_status[0] = mbox_status; 456afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 457afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (test_bit(AF_MBOX_COMMAND, &ha->flags)) { 458afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* 459afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * Copy all mailbox registers to a temporary 460afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * location and set mailbox command done flag 461afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu */ 462f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary for (i = 0; i < ha->mbox_status_count; i++) 463f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ha->mbox_status[i] = is_qla8022(ha) 464f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ? readl(&ha->qla4_8xxx_reg->mailbox_out[i]) 465f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary : readl(&ha->reg->mailbox[i]); 466afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 467afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu set_bit(AF_MBOX_COMMAND_DONE, &ha->flags); 468f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 469f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary if (test_bit(AF_MBOX_COMMAND_NOPOLL, &ha->flags)) 470f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary complete(&ha->mbx_intr_comp); 471afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 472afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } else if (mbox_status >> 12 == MBOX_ASYNC_EVENT_STATUS) { 473f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary for (i = 0; i < MBOX_AEN_REG_COUNT; i++) 474f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary mbox_sts[i] = is_qla8022(ha) 475f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ? readl(&ha->qla4_8xxx_reg->mailbox_out[i]) 476f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary : readl(&ha->reg->mailbox[i]); 477f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 478afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Immediately process the AENs that don't require much work. 479afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * Only queue the database_changed AENs */ 480401425b1ea005b39dcc544bffea833f338ba84f6David C Somayajulu if (ha->aen_log.count < MAX_AEN_ENTRIES) { 481401425b1ea005b39dcc544bffea833f338ba84f6David C Somayajulu for (i = 0; i < MBOX_AEN_REG_COUNT; i++) 482401425b1ea005b39dcc544bffea833f338ba84f6David C Somayajulu ha->aen_log.entry[ha->aen_log.count].mbox_sts[i] = 483f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary mbox_sts[i]; 484401425b1ea005b39dcc544bffea833f338ba84f6David C Somayajulu ha->aen_log.count++; 485401425b1ea005b39dcc544bffea833f338ba84f6David C Somayajulu } 486afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu switch (mbox_status) { 487afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_SYSTEM_ERROR: 488afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Log Mailbox registers */ 489f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ql4_printk(KERN_INFO, ha, "%s: System Err\n", __func__); 490afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (ql4xdontresethba) { 491f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary DEBUG2(printk("scsi%ld: %s:Don't Reset HBA\n", 492f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ha->host_no, __func__)); 493afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } else { 494afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu set_bit(AF_GET_CRASH_RECORD, &ha->flags); 495afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu set_bit(DPC_RESET_HA, &ha->dpc_flags); 496afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 497afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 498afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 499afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_REQUEST_TRANSFER_ERROR: 500afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_RESPONSE_TRANSFER_ERROR: 501afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_NVRAM_INVALID: 502afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_IP_ADDRESS_CHANGED: 503afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_DHCP_LEASE_EXPIRED: 504afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld: AEN %04x, ERROR Status, " 505afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "Reset HA\n", ha->host_no, mbox_status)); 506afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu set_bit(DPC_RESET_HA, &ha->dpc_flags); 507afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 508afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 509afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_LINK_UP: 510afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu set_bit(AF_LINK_UP, &ha->flags); 511065aa1b4db63c7fa68a3e889510c4e63404a1ac7Vikas Chaudhary if (test_bit(AF_INIT_DONE, &ha->flags)) 512065aa1b4db63c7fa68a3e889510c4e63404a1ac7Vikas Chaudhary set_bit(DPC_LINK_CHANGED, &ha->dpc_flags); 513065aa1b4db63c7fa68a3e889510c4e63404a1ac7Vikas Chaudhary 514f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ql4_printk(KERN_INFO, ha, "%s: LINK UP\n", __func__); 515afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 516afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 517afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_LINK_DOWN: 518afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu clear_bit(AF_LINK_UP, &ha->flags); 519f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary if (test_bit(AF_INIT_DONE, &ha->flags)) 520f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary set_bit(DPC_LINK_CHANGED, &ha->dpc_flags); 521065aa1b4db63c7fa68a3e889510c4e63404a1ac7Vikas Chaudhary 522f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ql4_printk(KERN_INFO, ha, "%s: LINK DOWN\n", __func__); 523afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 524afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 525afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_HEARTBEAT: 526afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->seconds_since_last_heartbeat = 0; 527afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 528afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 529afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_DHCP_LEASE_ACQUIRED: 530afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld: AEN %04x DHCP LEASE " 531afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "ACQUIRED\n", ha->host_no, mbox_status)); 532afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu set_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags); 533afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 534afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 535afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_PROTOCOL_STATISTIC_ALARM: 536afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_SCSI_COMMAND_PDU_REJECTED: /* Target 537afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * mode 538afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * only */ 539afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_UNSOLICITED_PDU_RECEIVED: /* Connection mode */ 540afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_IPSEC_SYSTEM_FATAL_ERROR: 541afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_SUBNET_STATE_CHANGE: 542afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* No action */ 543afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld: AEN %04x\n", ha->host_no, 544afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu mbox_status)); 545afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 546afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 547401425b1ea005b39dcc544bffea833f338ba84f6David C Somayajulu case MBOX_ASTS_IP_ADDR_STATE_CHANGED: 548f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary printk("scsi%ld: AEN %04x, mbox_sts[2]=%04x, " 549f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary "mbox_sts[3]=%04x\n", ha->host_no, mbox_sts[0], 550f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary mbox_sts[2], mbox_sts[3]); 551f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 552f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary /* mbox_sts[2] = Old ACB state 553f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * mbox_sts[3] = new ACB state */ 554f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary if ((mbox_sts[3] == ACB_STATE_VALID) && 555f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary (mbox_sts[2] == ACB_STATE_TENTATIVE)) 556401425b1ea005b39dcc544bffea833f338ba84f6David C Somayajulu set_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags); 557f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary else if ((mbox_sts[3] == ACB_STATE_ACQUIRING) && 558f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary (mbox_sts[2] == ACB_STATE_VALID)) 559401425b1ea005b39dcc544bffea833f338ba84f6David C Somayajulu set_bit(DPC_RESET_HA, &ha->dpc_flags); 560401425b1ea005b39dcc544bffea833f338ba84f6David C Somayajulu break; 561401425b1ea005b39dcc544bffea833f338ba84f6David C Somayajulu 562afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_MAC_ADDRESS_CHANGED: 563afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_DNS: 564afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* No action */ 565afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk(KERN_INFO "scsi%ld: AEN %04x, " 566afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "mbox_sts[1]=%04x, mbox_sts[2]=%04x\n", 567f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ha->host_no, mbox_sts[0], 568f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary mbox_sts[1], mbox_sts[2])); 569afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 570afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 571afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_SELF_TEST_FAILED: 572afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_LOGIN_FAILED: 573afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* No action */ 574afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld: AEN %04x, mbox_sts[1]=%04x, " 575afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "mbox_sts[2]=%04x, mbox_sts[3]=%04x\n", 576f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ha->host_no, mbox_sts[0], mbox_sts[1], 577f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary mbox_sts[2], mbox_sts[3])); 578afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 579afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 580afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_DATABASE_CHANGED: 581afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Queue AEN information and process it in the DPC 582afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * routine */ 583afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (ha->aen_q_count > 0) { 584afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 585afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* decrement available counter */ 586afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->aen_q_count--; 587afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 588f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary for (i = 0; i < MBOX_AEN_REG_COUNT; i++) 589afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->aen_q[ha->aen_in].mbox_sts[i] = 590f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary mbox_sts[i]; 591afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 592afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* print debug message */ 593afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld: AEN[%d] %04x queued" 594f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary " mb1:0x%x mb2:0x%x mb3:0x%x mb4:0x%x\n", 595f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ha->host_no, ha->aen_in, mbox_sts[0], 596f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary mbox_sts[1], mbox_sts[2], mbox_sts[3], 597f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary mbox_sts[4])); 598f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 599401425b1ea005b39dcc544bffea833f338ba84f6David C Somayajulu /* advance pointer */ 600401425b1ea005b39dcc544bffea833f338ba84f6David C Somayajulu ha->aen_in++; 601401425b1ea005b39dcc544bffea833f338ba84f6David C Somayajulu if (ha->aen_in == MAX_AEN_ENTRIES) 602401425b1ea005b39dcc544bffea833f338ba84f6David C Somayajulu ha->aen_in = 0; 603afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 604afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* The DPC routine will process the aen */ 605afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu set_bit(DPC_AEN, &ha->dpc_flags); 606afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } else { 607afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld: %s: aen %04x, queue " 608afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "overflowed! AEN LOST!!\n", 609afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->host_no, __func__, 610f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary mbox_sts[0])); 611afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 612afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld: DUMP AEN QUEUE\n", 613afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->host_no)); 614afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 615afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu for (i = 0; i < MAX_AEN_ENTRIES; i++) { 616afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("AEN[%d] %04x %04x %04x " 617f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary "%04x\n", i, mbox_sts[0], 618f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary mbox_sts[1], mbox_sts[2], 619f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary mbox_sts[3])); 620afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 621afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 622afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 623afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 6246434080b127088606e03d2ecfe5ffdd797e38d63Shyam Sundar case MBOX_ASTS_TXSCVR_INSERTED: 6256434080b127088606e03d2ecfe5ffdd797e38d63Shyam Sundar DEBUG2(printk(KERN_WARNING 6266434080b127088606e03d2ecfe5ffdd797e38d63Shyam Sundar "scsi%ld: AEN %04x Transceiver" 6276434080b127088606e03d2ecfe5ffdd797e38d63Shyam Sundar " inserted\n", ha->host_no, mbox_sts[0])); 6286434080b127088606e03d2ecfe5ffdd797e38d63Shyam Sundar break; 6296434080b127088606e03d2ecfe5ffdd797e38d63Shyam Sundar 6306434080b127088606e03d2ecfe5ffdd797e38d63Shyam Sundar case MBOX_ASTS_TXSCVR_REMOVED: 6316434080b127088606e03d2ecfe5ffdd797e38d63Shyam Sundar DEBUG2(printk(KERN_WARNING 6326434080b127088606e03d2ecfe5ffdd797e38d63Shyam Sundar "scsi%ld: AEN %04x Transceiver" 6336434080b127088606e03d2ecfe5ffdd797e38d63Shyam Sundar " removed\n", ha->host_no, mbox_sts[0])); 6346434080b127088606e03d2ecfe5ffdd797e38d63Shyam Sundar break; 6356434080b127088606e03d2ecfe5ffdd797e38d63Shyam Sundar 636afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu default: 637afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk(KERN_WARNING 638afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "scsi%ld: AEN %04x UNKNOWN\n", 639f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ha->host_no, mbox_sts[0])); 640afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 641afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 642afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } else { 643afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld: Unknown mailbox status %08X\n", 644afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->host_no, mbox_status)); 645afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 646afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->mbox_status[0] = mbox_status; 647afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 648afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu} 649afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 650afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu/** 651f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * qla4_8xxx_interrupt_service_routine - isr 652f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * @ha: pointer to host adapter structure. 653f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * 654f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * This is the main interrupt service routine. 655f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * hardware_lock locked upon entry. runs in interrupt context. 656f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary **/ 657f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudharyvoid qla4_8xxx_interrupt_service_routine(struct scsi_qla_host *ha, 658f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary uint32_t intr_status) 659f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary{ 660f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary /* Process response queue interrupt. */ 661f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary if (intr_status & HSRX_RISC_IOCB_INT) 662f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary qla4xxx_process_response_queue(ha); 663f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 664f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary /* Process mailbox/asynch event interrupt.*/ 665f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary if (intr_status & HSRX_RISC_MB_INT) 666f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary qla4xxx_isr_decode_mailbox(ha, 667f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary readl(&ha->qla4_8xxx_reg->mailbox_out[0])); 668f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 669f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary /* clear the interrupt */ 670f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary writel(0, &ha->qla4_8xxx_reg->host_int); 671f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary readl(&ha->qla4_8xxx_reg->host_int); 672f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary} 673f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 674f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary/** 675afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * qla4xxx_interrupt_service_routine - isr 676afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * @ha: pointer to host adapter structure. 677afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * 678afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * This is the main interrupt service routine. 679afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * hardware_lock locked upon entry. runs in interrupt context. 680afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu **/ 681afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajuluvoid qla4xxx_interrupt_service_routine(struct scsi_qla_host * ha, 682afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu uint32_t intr_status) 683afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu{ 684afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Process response queue interrupt. */ 685afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (intr_status & CSR_SCSI_COMPLETION_INTR) 686afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu qla4xxx_process_response_queue(ha); 687afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 688afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Process mailbox/asynch event interrupt.*/ 689afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (intr_status & CSR_SCSI_PROCESSOR_INTR) { 690afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu qla4xxx_isr_decode_mailbox(ha, 691afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu readl(&ha->reg->mailbox[0])); 692afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 693afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Clear Mailbox Interrupt */ 694afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu writel(set_rmask(CSR_SCSI_PROCESSOR_INTR), 695afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu &ha->reg->ctrl_status); 696afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu readl(&ha->reg->ctrl_status); 697afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 698afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu} 699afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 700afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu/** 701f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * qla4_8xxx_spurious_interrupt - processes spurious interrupt 702f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * @ha: pointer to host adapter structure. 703f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * @reqs_count: . 704f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * 705f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary **/ 706f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudharystatic void qla4_8xxx_spurious_interrupt(struct scsi_qla_host *ha, 707f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary uint8_t reqs_count) 708f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary{ 709f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary if (reqs_count) 710f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary return; 711f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 712f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary DEBUG2(ql4_printk(KERN_INFO, ha, "Spurious Interrupt\n")); 713f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary if (is_qla8022(ha)) { 714f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary writel(0, &ha->qla4_8xxx_reg->host_int); 715f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary if (test_bit(AF_INTx_ENABLED, &ha->flags)) 716f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary qla4_8xxx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 717f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 0xfbff); 718f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary } 719f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ha->spurious_int_count++; 720f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary} 721f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 722f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary/** 723afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * qla4xxx_intr_handler - hardware interrupt handler. 724afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * @irq: Unused 725afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * @dev_id: Pointer to host adapter structure 726afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu **/ 7277d12e780e003f93433d49ce78cfedf4b4c52adc5David Howellsirqreturn_t qla4xxx_intr_handler(int irq, void *dev_id) 728afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu{ 729afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu struct scsi_qla_host *ha; 730afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu uint32_t intr_status; 731afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu unsigned long flags = 0; 732afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu uint8_t reqs_count = 0; 733afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 734afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha = (struct scsi_qla_host *) dev_id; 735afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (!ha) { 736afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk(KERN_INFO 737afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "qla4xxx: Interrupt with NULL host ptr\n")); 738afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu return IRQ_NONE; 739afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 740afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 741afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu spin_lock_irqsave(&ha->hardware_lock, flags); 742afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 743d915058f48745c0d5c4582566e5aa63867264f81David C Somayajulu ha->isr_count++; 744afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* 745afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * Repeatedly service interrupts up to a maximum of 746afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * MAX_REQS_SERVICED_PER_INTR 747afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu */ 748afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu while (1) { 749afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* 750afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * Read interrupt status 751afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu */ 752f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary if (ha->isp_ops->rd_shdw_rsp_q_in(ha) != 753afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->response_out) 754afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu intr_status = CSR_SCSI_COMPLETION_INTR; 755afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu else 756afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu intr_status = readl(&ha->reg->ctrl_status); 757afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 758afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if ((intr_status & 759f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary (CSR_SCSI_RESET_INTR|CSR_FATAL_ERROR|INTR_PENDING)) == 0) { 760afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (reqs_count == 0) 761afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->spurious_int_count++; 762afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 763afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 764afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 765afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (intr_status & CSR_FATAL_ERROR) { 766afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk(KERN_INFO "scsi%ld: Fatal Error, " 767afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "Status 0x%04x\n", ha->host_no, 768afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu readl(isp_port_error_status (ha)))); 769afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 770afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* Issue Soft Reset to clear this error condition. 771afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * This will prevent the RISC from repeatedly 772afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * interrupting the driver; thus, allowing the DPC to 773afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * get scheduled to continue error recovery. 774afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * NOTE: Disabling RISC interrupts does not work in 775afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * this case, as CSR_FATAL_ERROR overrides 776afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * CSR_SCSI_INTR_ENABLE */ 777afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if ((readl(&ha->reg->ctrl_status) & 778afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu CSR_SCSI_RESET_INTR) == 0) { 779afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu writel(set_rmask(CSR_SOFT_RESET), 780afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu &ha->reg->ctrl_status); 781afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu readl(&ha->reg->ctrl_status); 782afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 783afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 784afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu writel(set_rmask(CSR_FATAL_ERROR), 785afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu &ha->reg->ctrl_status); 786afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu readl(&ha->reg->ctrl_status); 787afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 788afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu __qla4xxx_disable_intrs(ha); 789afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 790afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu set_bit(DPC_RESET_HA, &ha->dpc_flags); 791afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 792afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 793afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } else if (intr_status & CSR_SCSI_RESET_INTR) { 794afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu clear_bit(AF_ONLINE, &ha->flags); 795afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu __qla4xxx_disable_intrs(ha); 796afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 797afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu writel(set_rmask(CSR_SCSI_RESET_INTR), 798afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu &ha->reg->ctrl_status); 799afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu readl(&ha->reg->ctrl_status); 800afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 801f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary if (!test_bit(AF_HBA_GOING_AWAY, &ha->flags)) 802477ffb9d8732f30e7ab2d20f6ed0c22bad37a4a5David C Somayajulu set_bit(DPC_RESET_HA_INTR, &ha->dpc_flags); 803afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 804afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 805afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } else if (intr_status & INTR_PENDING) { 806f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ha->isp_ops->interrupt_service_routine(ha, intr_status); 807afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->total_io_count++; 808afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (++reqs_count == MAX_REQS_SERVICED_PER_INTR) 809afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 810f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary } 811f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary } 812f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 813f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary spin_unlock_irqrestore(&ha->hardware_lock, flags); 814f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 815f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary return IRQ_HANDLED; 816f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary} 817f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 818f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary/** 819f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * qla4_8xxx_intr_handler - hardware interrupt handler. 820f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * @irq: Unused 821f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * @dev_id: Pointer to host adapter structure 822f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary **/ 823f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudharyirqreturn_t qla4_8xxx_intr_handler(int irq, void *dev_id) 824f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary{ 825f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary struct scsi_qla_host *ha = dev_id; 826f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary uint32_t intr_status; 827f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary uint32_t status; 828f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary unsigned long flags = 0; 829f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary uint8_t reqs_count = 0; 830f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 8312232be0d5707cd331b92027c0fd7ea5e843c2121Lalit Chandivade if (unlikely(pci_channel_offline(ha->pdev))) 8322232be0d5707cd331b92027c0fd7ea5e843c2121Lalit Chandivade return IRQ_HANDLED; 8332232be0d5707cd331b92027c0fd7ea5e843c2121Lalit Chandivade 834f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ha->isr_count++; 835f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary status = qla4_8xxx_rd_32(ha, ISR_INT_VECTOR); 836f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary if (!(status & ha->nx_legacy_intr.int_vec_bit)) 837f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary return IRQ_NONE; 838f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 839f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary status = qla4_8xxx_rd_32(ha, ISR_INT_STATE_REG); 840f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary if (!ISR_IS_LEGACY_INTR_TRIGGERED(status)) { 841f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary DEBUG2(ql4_printk(KERN_INFO, ha, 842f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary "%s legacy Int not triggered\n", __func__)); 843f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary return IRQ_NONE; 844f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary } 845f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 846f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary /* clear the interrupt */ 847f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary qla4_8xxx_wr_32(ha, ha->nx_legacy_intr.tgt_status_reg, 0xffffffff); 848f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 849f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary /* read twice to ensure write is flushed */ 850f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary qla4_8xxx_rd_32(ha, ISR_INT_VECTOR); 851f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary qla4_8xxx_rd_32(ha, ISR_INT_VECTOR); 852f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 853f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary spin_lock_irqsave(&ha->hardware_lock, flags); 854f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary while (1) { 855f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary if (!(readl(&ha->qla4_8xxx_reg->host_int) & 856f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ISRX_82XX_RISC_INT)) { 857f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary qla4_8xxx_spurious_interrupt(ha, reqs_count); 858f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary break; 859f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary } 860f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary intr_status = readl(&ha->qla4_8xxx_reg->host_status); 861f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary if ((intr_status & 862f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary (HSRX_RISC_MB_INT | HSRX_RISC_IOCB_INT)) == 0) { 863f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary qla4_8xxx_spurious_interrupt(ha, reqs_count); 864f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary break; 865f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary } 866f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 867f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ha->isp_ops->interrupt_service_routine(ha, intr_status); 868f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 869f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary /* Enable Interrupt */ 870f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary qla4_8xxx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0xfbff); 871afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 872f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary if (++reqs_count == MAX_REQS_SERVICED_PER_INTR) 873f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary break; 874f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary } 875f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 876f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary spin_unlock_irqrestore(&ha->hardware_lock, flags); 877f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary return IRQ_HANDLED; 878f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary} 879f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 880f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudharyirqreturn_t 881f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudharyqla4_8xxx_msi_handler(int irq, void *dev_id) 882f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary{ 883f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary struct scsi_qla_host *ha; 884f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 885f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ha = (struct scsi_qla_host *) dev_id; 886f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary if (!ha) { 887f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary DEBUG2(printk(KERN_INFO 888f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary "qla4xxx: MSIX: Interrupt with NULL host ptr\n")); 889f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary return IRQ_NONE; 890f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary } 891f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 892f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ha->isr_count++; 893f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary /* clear the interrupt */ 894f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary qla4_8xxx_wr_32(ha, ha->nx_legacy_intr.tgt_status_reg, 0xffffffff); 895f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 896f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary /* read twice to ensure write is flushed */ 897f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary qla4_8xxx_rd_32(ha, ISR_INT_VECTOR); 898f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary qla4_8xxx_rd_32(ha, ISR_INT_VECTOR); 899f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 900f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary return qla4_8xxx_default_intr_handler(irq, dev_id); 901f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary} 902f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 903f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary/** 904f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * qla4_8xxx_default_intr_handler - hardware interrupt handler. 905f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * @irq: Unused 906f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * @dev_id: Pointer to host adapter structure 907f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * 908f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * This interrupt handler is called directly for MSI-X, and 909f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary * called indirectly for MSI. 910f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary **/ 911f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudharyirqreturn_t 912f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudharyqla4_8xxx_default_intr_handler(int irq, void *dev_id) 913f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary{ 914f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary struct scsi_qla_host *ha = dev_id; 915f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary unsigned long flags; 916f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary uint32_t intr_status; 917f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary uint8_t reqs_count = 0; 918f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 919f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary spin_lock_irqsave(&ha->hardware_lock, flags); 920f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary while (1) { 921f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary if (!(readl(&ha->qla4_8xxx_reg->host_int) & 922f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ISRX_82XX_RISC_INT)) { 923f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary qla4_8xxx_spurious_interrupt(ha, reqs_count); 924f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary break; 925f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary } 926f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 927f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary intr_status = readl(&ha->qla4_8xxx_reg->host_status); 928f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary if ((intr_status & 929f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary (HSRX_RISC_MB_INT | HSRX_RISC_IOCB_INT)) == 0) { 930f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary qla4_8xxx_spurious_interrupt(ha, reqs_count); 931f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary break; 932afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 933f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 934f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ha->isp_ops->interrupt_service_routine(ha, intr_status); 935f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 936f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary if (++reqs_count == MAX_REQS_SERVICED_PER_INTR) 937f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary break; 938afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 939afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 940f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ha->isr_count++; 941afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu spin_unlock_irqrestore(&ha->hardware_lock, flags); 942f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary return IRQ_HANDLED; 943f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary} 944afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 945f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudharyirqreturn_t 946f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudharyqla4_8xxx_msix_rsp_q(int irq, void *dev_id) 947f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary{ 948f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary struct scsi_qla_host *ha = dev_id; 949f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary unsigned long flags; 950f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 951f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary spin_lock_irqsave(&ha->hardware_lock, flags); 952f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary qla4xxx_process_response_queue(ha); 953f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary writel(0, &ha->qla4_8xxx_reg->host_int); 954f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary spin_unlock_irqrestore(&ha->hardware_lock, flags); 955f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 956f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ha->isr_count++; 957afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu return IRQ_HANDLED; 958afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu} 959afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 960afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu/** 961afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * qla4xxx_process_aen - processes AENs generated by firmware 962afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * @ha: pointer to host adapter structure. 963afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * @process_aen: type of AENs to process 964afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * 965afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * Processes specific types of Asynchronous Events generated by firmware. 966afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * The type of AENs to process is specified by process_aen and can be 967afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * PROCESS_ALL_AENS 0 968afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * FLUSH_DDB_CHANGED_AENS 1 969afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * RELOGIN_DDB_CHANGED_AENS 2 970afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu **/ 971afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajuluvoid qla4xxx_process_aen(struct scsi_qla_host * ha, uint8_t process_aen) 972afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu{ 973afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu uint32_t mbox_sts[MBOX_AEN_REG_COUNT]; 974afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu struct aen *aen; 975afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu int i; 976afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu unsigned long flags; 977afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 978afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu spin_lock_irqsave(&ha->hardware_lock, flags); 979afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu while (ha->aen_out != ha->aen_in) { 980afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu aen = &ha->aen_q[ha->aen_out]; 981afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* copy aen information to local structure */ 982afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu for (i = 0; i < MBOX_AEN_REG_COUNT; i++) 983afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu mbox_sts[i] = aen->mbox_sts[i]; 984afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 985401425b1ea005b39dcc544bffea833f338ba84f6David C Somayajulu ha->aen_q_count++; 986401425b1ea005b39dcc544bffea833f338ba84f6David C Somayajulu ha->aen_out++; 987401425b1ea005b39dcc544bffea833f338ba84f6David C Somayajulu 988401425b1ea005b39dcc544bffea833f338ba84f6David C Somayajulu if (ha->aen_out == MAX_AEN_ENTRIES) 989401425b1ea005b39dcc544bffea833f338ba84f6David C Somayajulu ha->aen_out = 0; 990401425b1ea005b39dcc544bffea833f338ba84f6David C Somayajulu 991afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu spin_unlock_irqrestore(&ha->hardware_lock, flags); 992afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 993401425b1ea005b39dcc544bffea833f338ba84f6David C Somayajulu DEBUG2(printk("qla4xxx(%ld): AEN[%d]=0x%08x, mbx1=0x%08x mbx2=0x%08x" 994401425b1ea005b39dcc544bffea833f338ba84f6David C Somayajulu " mbx3=0x%08x mbx4=0x%08x\n", ha->host_no, 995401425b1ea005b39dcc544bffea833f338ba84f6David C Somayajulu (ha->aen_out ? (ha->aen_out-1): (MAX_AEN_ENTRIES-1)), 996401425b1ea005b39dcc544bffea833f338ba84f6David C Somayajulu mbox_sts[0], mbox_sts[1], mbox_sts[2], 997401425b1ea005b39dcc544bffea833f338ba84f6David C Somayajulu mbox_sts[3], mbox_sts[4])); 998afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 999afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu switch (mbox_sts[0]) { 1000afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu case MBOX_ASTS_DATABASE_CHANGED: 1001afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (process_aen == FLUSH_DDB_CHANGED_AENS) { 1002afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu DEBUG2(printk("scsi%ld: AEN[%d] %04x, index " 1003afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu "[%d] state=%04x FLUSHED!\n", 1004afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->host_no, ha->aen_out, 1005afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu mbox_sts[0], mbox_sts[2], 1006afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu mbox_sts[3])); 1007afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 1008afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } else if (process_aen == RELOGIN_DDB_CHANGED_AENS) { 1009afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* for use during init time, we only want to 1010afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu * relogin non-active ddbs */ 1011afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu struct ddb_entry *ddb_entry; 1012afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 1013afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ddb_entry = 1014afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu /* FIXME: name length? */ 1015afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu qla4xxx_lookup_ddb_by_fw_index(ha, 1016afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu mbox_sts[2]); 1017afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (!ddb_entry) 1018afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 1019afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 1020afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ddb_entry->dev_scan_wait_to_complete_relogin = 1021afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 0; 1022afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ddb_entry->dev_scan_wait_to_start_relogin = 1023afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu jiffies + 1024afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ((ddb_entry->default_time2wait + 1025afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 4) * HZ); 1026afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 1027f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary DEBUG2(printk("scsi%ld: ddb [%d] initate" 1028afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu " RELOGIN after %d seconds\n", 1029afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ha->host_no, 1030afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ddb_entry->fw_ddb_index, 1031afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu ddb_entry->default_time2wait + 1032afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 4)); 1033afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 1034afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 1035afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 1036afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu if (mbox_sts[1] == 0) { /* Global DB change. */ 1037afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu qla4xxx_reinitialize_ddb_list(ha); 1038afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } else if (mbox_sts[1] == 1) { /* Specific device. */ 1039afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu qla4xxx_process_ddb_changed(ha, mbox_sts[2], 1040821d6e5413481a57bbe1c2722dbe1fee4ff675c4Vikas Chaudhary mbox_sts[3], mbox_sts[4]); 1041afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 1042afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu break; 1043afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 1044afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu spin_lock_irqsave(&ha->hardware_lock, flags); 1045afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu } 1046afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu spin_unlock_irqrestore(&ha->hardware_lock, flags); 1047afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu} 1048afaf5a2d341d33b66b47c2716a263ce593460a08David Somayajulu 1049f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudharyint qla4xxx_request_irqs(struct scsi_qla_host *ha) 1050f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary{ 1051f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary int ret; 1052f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 1053f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary if (!is_qla8022(ha)) 1054f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary goto try_intx; 1055f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 1056f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary if (ql4xenablemsix == 2) 1057f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary goto try_msi; 1058f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 1059f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary if (ql4xenablemsix == 0 || ql4xenablemsix != 1) 1060f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary goto try_intx; 1061f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 1062f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary /* Trying MSI-X */ 1063f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ret = qla4_8xxx_enable_msix(ha); 1064f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary if (!ret) { 1065f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary DEBUG2(ql4_printk(KERN_INFO, ha, 1066f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary "MSI-X: Enabled (0x%X).\n", ha->revision_id)); 1067f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary goto irq_attached; 1068f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary } 1069f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 1070f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ql4_printk(KERN_WARNING, ha, 1071f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary "MSI-X: Falling back-to MSI mode -- %d.\n", ret); 1072f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 1073f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudharytry_msi: 1074f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary /* Trying MSI */ 1075f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ret = pci_enable_msi(ha->pdev); 1076f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary if (!ret) { 1077f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ret = request_irq(ha->pdev->irq, qla4_8xxx_msi_handler, 1078f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary IRQF_DISABLED|IRQF_SHARED, DRIVER_NAME, ha); 1079f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary if (!ret) { 1080f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary DEBUG2(ql4_printk(KERN_INFO, ha, "MSI: Enabled.\n")); 1081f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary set_bit(AF_MSI_ENABLED, &ha->flags); 1082f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary goto irq_attached; 1083f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary } else { 1084f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ql4_printk(KERN_WARNING, ha, 1085f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary "MSI: Failed to reserve interrupt %d " 1086f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary "already in use.\n", ha->pdev->irq); 1087f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary pci_disable_msi(ha->pdev); 1088f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary } 1089f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary } 1090f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ql4_printk(KERN_WARNING, ha, 1091f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary "MSI: Falling back-to INTx mode -- %d.\n", ret); 1092f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 1093f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudharytry_intx: 1094f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary /* Trying INTx */ 1095f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler, 1096f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary IRQF_DISABLED|IRQF_SHARED, DRIVER_NAME, ha); 1097f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary if (!ret) { 1098f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary DEBUG2(ql4_printk(KERN_INFO, ha, "INTx: Enabled.\n")); 1099f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary set_bit(AF_INTx_ENABLED, &ha->flags); 1100f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary goto irq_attached; 1101f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 1102f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary } else { 1103f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ql4_printk(KERN_WARNING, ha, 1104f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary "INTx: Failed to reserve interrupt %d already in" 1105f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary " use.\n", ha->pdev->irq); 1106f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary return ret; 1107f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary } 1108f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 1109f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudharyirq_attached: 1110f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary set_bit(AF_IRQ_ATTACHED, &ha->flags); 1111f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ha->host->irq = ha->pdev->irq; 1112f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary ql4_printk(KERN_INFO, ha, "%s: irq %d attached\n", 1113f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary __func__, ha->pdev->irq); 1114f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary return ret; 1115f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary} 1116f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary 1117f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudharyvoid qla4xxx_free_irqs(struct scsi_qla_host *ha) 1118f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary{ 1119f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary if (test_bit(AF_MSIX_ENABLED, &ha->flags)) 1120f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary qla4_8xxx_disable_msix(ha); 1121f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary else if (test_and_clear_bit(AF_MSI_ENABLED, &ha->flags)) { 1122f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary free_irq(ha->pdev->irq, ha); 1123f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary pci_disable_msi(ha->pdev); 1124f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary } else if (test_and_clear_bit(AF_INTx_ENABLED, &ha->flags)) 1125f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary free_irq(ha->pdev->irq, ha); 1126f4f5df23bf72208d0c2f1d8be629839924c2f4c2Vikas Chaudhary} 1127