1afaf5a2dSDavid Somayajulu /* 2afaf5a2dSDavid Somayajulu * QLogic iSCSI HBA Driver 37d01d069SVikas Chaudhary * Copyright (c) 2003-2010 QLogic Corporation 4afaf5a2dSDavid Somayajulu * 5afaf5a2dSDavid Somayajulu * See LICENSE.qla4xxx for copyright and licensing details. 6afaf5a2dSDavid Somayajulu */ 7afaf5a2dSDavid Somayajulu 8afaf5a2dSDavid Somayajulu #include "ql4_def.h" 9c0e344c9SDavid C Somayajulu #include "ql4_glbl.h" 10c0e344c9SDavid C Somayajulu #include "ql4_dbg.h" 11c0e344c9SDavid C Somayajulu #include "ql4_inline.h" 12afaf5a2dSDavid Somayajulu 13afaf5a2dSDavid Somayajulu 14afaf5a2dSDavid Somayajulu /** 15afaf5a2dSDavid Somayajulu * qla4xxx_mailbox_command - issues mailbox commands 16afaf5a2dSDavid Somayajulu * @ha: Pointer to host adapter structure. 17afaf5a2dSDavid Somayajulu * @inCount: number of mailbox registers to load. 18afaf5a2dSDavid Somayajulu * @outCount: number of mailbox registers to return. 19afaf5a2dSDavid Somayajulu * @mbx_cmd: data pointer for mailbox in registers. 20afaf5a2dSDavid Somayajulu * @mbx_sts: data pointer for mailbox out registers. 21afaf5a2dSDavid Somayajulu * 22f4f5df23SVikas Chaudhary * This routine isssue mailbox commands and waits for completion. 23afaf5a2dSDavid Somayajulu * If outCount is 0, this routine completes successfully WITHOUT waiting 24afaf5a2dSDavid Somayajulu * for the mailbox command to complete. 25afaf5a2dSDavid Somayajulu **/ 26f4f5df23SVikas Chaudhary int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, 27afaf5a2dSDavid Somayajulu uint8_t outCount, uint32_t *mbx_cmd, 28afaf5a2dSDavid Somayajulu uint32_t *mbx_sts) 29afaf5a2dSDavid Somayajulu { 30afaf5a2dSDavid Somayajulu int status = QLA_ERROR; 31afaf5a2dSDavid Somayajulu uint8_t i; 32afaf5a2dSDavid Somayajulu u_long wait_count; 33afaf5a2dSDavid Somayajulu uint32_t intr_status; 34afaf5a2dSDavid Somayajulu unsigned long flags = 0; 3599b53bf5SPrasanna Mumbai uint32_t dev_state; 36afaf5a2dSDavid Somayajulu 37afaf5a2dSDavid Somayajulu /* Make sure that pointers are valid */ 38afaf5a2dSDavid Somayajulu if (!mbx_cmd || !mbx_sts) { 39afaf5a2dSDavid Somayajulu DEBUG2(printk("scsi%ld: %s: Invalid mbx_cmd or mbx_sts " 40afaf5a2dSDavid Somayajulu "pointer\n", ha->host_no, __func__)); 41477ffb9dSDavid C Somayajulu return status; 42477ffb9dSDavid C Somayajulu } 4321033639SNilesh Javali 4499b53bf5SPrasanna Mumbai if (is_qla8022(ha)) { 4599b53bf5SPrasanna Mumbai if (test_bit(AF_FW_RECOVERY, &ha->flags)) { 4699b53bf5SPrasanna Mumbai DEBUG2(ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: " 4799b53bf5SPrasanna Mumbai "prematurely completing mbx cmd as firmware " 4899b53bf5SPrasanna Mumbai "recovery detected\n", ha->host_no, __func__)); 4921033639SNilesh Javali return status; 5021033639SNilesh Javali } 5199b53bf5SPrasanna Mumbai /* Do not send any mbx cmd if h/w is in failed state*/ 5299b53bf5SPrasanna Mumbai qla4_8xxx_idc_lock(ha); 5399b53bf5SPrasanna Mumbai dev_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE); 5499b53bf5SPrasanna Mumbai qla4_8xxx_idc_unlock(ha); 5599b53bf5SPrasanna Mumbai if (dev_state == QLA82XX_DEV_FAILED) { 5699b53bf5SPrasanna Mumbai ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: H/W is in " 5799b53bf5SPrasanna Mumbai "failed state, do not send any mailbox commands\n", 5899b53bf5SPrasanna Mumbai ha->host_no, __func__); 5999b53bf5SPrasanna Mumbai return status; 6099b53bf5SPrasanna Mumbai } 6199b53bf5SPrasanna Mumbai } 6221033639SNilesh Javali 632232be0dSLalit Chandivade if ((is_aer_supported(ha)) && 642232be0dSLalit Chandivade (test_bit(AF_PCI_CHANNEL_IO_PERM_FAILURE, &ha->flags))) { 652232be0dSLalit Chandivade DEBUG2(printk(KERN_WARNING "scsi%ld: %s: Perm failure on EEH, " 662232be0dSLalit Chandivade "timeout MBX Exiting.\n", ha->host_no, __func__)); 672232be0dSLalit Chandivade return status; 682232be0dSLalit Chandivade } 692232be0dSLalit Chandivade 70477ffb9dSDavid C Somayajulu /* Mailbox code active */ 71477ffb9dSDavid C Somayajulu wait_count = MBOX_TOV * 100; 72477ffb9dSDavid C Somayajulu 73477ffb9dSDavid C Somayajulu while (wait_count--) { 74477ffb9dSDavid C Somayajulu mutex_lock(&ha->mbox_sem); 75477ffb9dSDavid C Somayajulu if (!test_bit(AF_MBOX_COMMAND, &ha->flags)) { 76477ffb9dSDavid C Somayajulu set_bit(AF_MBOX_COMMAND, &ha->flags); 77477ffb9dSDavid C Somayajulu mutex_unlock(&ha->mbox_sem); 78477ffb9dSDavid C Somayajulu break; 79477ffb9dSDavid C Somayajulu } 80477ffb9dSDavid C Somayajulu mutex_unlock(&ha->mbox_sem); 81477ffb9dSDavid C Somayajulu if (!wait_count) { 82477ffb9dSDavid C Somayajulu DEBUG2(printk("scsi%ld: %s: mbox_sem failed\n", 83477ffb9dSDavid C Somayajulu ha->host_no, __func__)); 84477ffb9dSDavid C Somayajulu return status; 85477ffb9dSDavid C Somayajulu } 86477ffb9dSDavid C Somayajulu msleep(10); 87afaf5a2dSDavid Somayajulu } 88afaf5a2dSDavid Somayajulu 89afaf5a2dSDavid Somayajulu /* To prevent overwriting mailbox registers for a command that has 90f4f5df23SVikas Chaudhary * not yet been serviced, check to see if an active command 91f4f5df23SVikas Chaudhary * (AEN, IOCB, etc.) is interrupting, then service it. 92afaf5a2dSDavid Somayajulu * ----------------------------------------------------------------- 93afaf5a2dSDavid Somayajulu */ 94afaf5a2dSDavid Somayajulu spin_lock_irqsave(&ha->hardware_lock, flags); 95f4f5df23SVikas Chaudhary 96e6b07df8SLalit Chandivade if (!is_qla8022(ha)) { 97afaf5a2dSDavid Somayajulu intr_status = readl(&ha->reg->ctrl_status); 98afaf5a2dSDavid Somayajulu if (intr_status & CSR_SCSI_PROCESSOR_INTR) { 99afaf5a2dSDavid Somayajulu /* Service existing interrupt */ 100f4f5df23SVikas Chaudhary ha->isp_ops->interrupt_service_routine(ha, intr_status); 101afaf5a2dSDavid Somayajulu clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags); 102afaf5a2dSDavid Somayajulu } 103f4f5df23SVikas Chaudhary } 104afaf5a2dSDavid Somayajulu 105afaf5a2dSDavid Somayajulu ha->mbox_status_count = outCount; 106afaf5a2dSDavid Somayajulu for (i = 0; i < outCount; i++) 107afaf5a2dSDavid Somayajulu ha->mbox_status[i] = 0; 108afaf5a2dSDavid Somayajulu 109f4f5df23SVikas Chaudhary if (is_qla8022(ha)) { 110f4f5df23SVikas Chaudhary /* Load all mailbox registers, except mailbox 0. */ 111f4f5df23SVikas Chaudhary DEBUG5( 112f4f5df23SVikas Chaudhary printk("scsi%ld: %s: Cmd ", ha->host_no, __func__); 113f4f5df23SVikas Chaudhary for (i = 0; i < inCount; i++) 114f4f5df23SVikas Chaudhary printk("mb%d=%04x ", i, mbx_cmd[i]); 115f4f5df23SVikas Chaudhary printk("\n")); 116f4f5df23SVikas Chaudhary 117f4f5df23SVikas Chaudhary for (i = 1; i < inCount; i++) 118f4f5df23SVikas Chaudhary writel(mbx_cmd[i], &ha->qla4_8xxx_reg->mailbox_in[i]); 119f4f5df23SVikas Chaudhary writel(mbx_cmd[0], &ha->qla4_8xxx_reg->mailbox_in[0]); 120f4f5df23SVikas Chaudhary readl(&ha->qla4_8xxx_reg->mailbox_in[0]); 121f4f5df23SVikas Chaudhary writel(HINT_MBX_INT_PENDING, &ha->qla4_8xxx_reg->hint); 122f4f5df23SVikas Chaudhary } else { 123afaf5a2dSDavid Somayajulu /* Load all mailbox registers, except mailbox 0. */ 124afaf5a2dSDavid Somayajulu for (i = 1; i < inCount; i++) 125afaf5a2dSDavid Somayajulu writel(mbx_cmd[i], &ha->reg->mailbox[i]); 126afaf5a2dSDavid Somayajulu 127afaf5a2dSDavid Somayajulu /* Wakeup firmware */ 128afaf5a2dSDavid Somayajulu writel(mbx_cmd[0], &ha->reg->mailbox[0]); 129afaf5a2dSDavid Somayajulu readl(&ha->reg->mailbox[0]); 130afaf5a2dSDavid Somayajulu writel(set_rmask(CSR_INTR_RISC), &ha->reg->ctrl_status); 131afaf5a2dSDavid Somayajulu readl(&ha->reg->ctrl_status); 132f4f5df23SVikas Chaudhary } 133f4f5df23SVikas Chaudhary 134afaf5a2dSDavid Somayajulu spin_unlock_irqrestore(&ha->hardware_lock, flags); 135afaf5a2dSDavid Somayajulu 136afaf5a2dSDavid Somayajulu /* Wait for completion */ 137afaf5a2dSDavid Somayajulu 138afaf5a2dSDavid Somayajulu /* 139afaf5a2dSDavid Somayajulu * If we don't want status, don't wait for the mailbox command to 140afaf5a2dSDavid Somayajulu * complete. For example, MBOX_CMD_RESET_FW doesn't return status, 141afaf5a2dSDavid Somayajulu * you must poll the inbound Interrupt Mask for completion. 142afaf5a2dSDavid Somayajulu */ 143afaf5a2dSDavid Somayajulu if (outCount == 0) { 144afaf5a2dSDavid Somayajulu status = QLA_SUCCESS; 145afaf5a2dSDavid Somayajulu goto mbox_exit; 146afaf5a2dSDavid Somayajulu } 147f4f5df23SVikas Chaudhary 148f4f5df23SVikas Chaudhary /* 149f4f5df23SVikas Chaudhary * Wait for completion: Poll or completion queue 150f4f5df23SVikas Chaudhary */ 151f4f5df23SVikas Chaudhary if (test_bit(AF_IRQ_ATTACHED, &ha->flags) && 152f4f5df23SVikas Chaudhary test_bit(AF_INTERRUPTS_ON, &ha->flags) && 153f4f5df23SVikas Chaudhary test_bit(AF_ONLINE, &ha->flags) && 154*7eece5a0SKaren Higgins !test_bit(AF_HA_REMOVAL, &ha->flags)) { 155f4f5df23SVikas Chaudhary /* Do not poll for completion. Use completion queue */ 156f4f5df23SVikas Chaudhary set_bit(AF_MBOX_COMMAND_NOPOLL, &ha->flags); 157f4f5df23SVikas Chaudhary wait_for_completion_timeout(&ha->mbx_intr_comp, MBOX_TOV * HZ); 158f4f5df23SVikas Chaudhary clear_bit(AF_MBOX_COMMAND_NOPOLL, &ha->flags); 159f4f5df23SVikas Chaudhary } else { 160f4f5df23SVikas Chaudhary /* Poll for command to complete */ 161afaf5a2dSDavid Somayajulu wait_count = jiffies + MBOX_TOV * HZ; 162afaf5a2dSDavid Somayajulu while (test_bit(AF_MBOX_COMMAND_DONE, &ha->flags) == 0) { 163afaf5a2dSDavid Somayajulu if (time_after_eq(jiffies, wait_count)) 164afaf5a2dSDavid Somayajulu break; 1652232be0dSLalit Chandivade 166afaf5a2dSDavid Somayajulu /* 167afaf5a2dSDavid Somayajulu * Service the interrupt. 168afaf5a2dSDavid Somayajulu * The ISR will save the mailbox status registers 169afaf5a2dSDavid Somayajulu * to a temporary storage location in the adapter 170afaf5a2dSDavid Somayajulu * structure. 171afaf5a2dSDavid Somayajulu */ 172f4f5df23SVikas Chaudhary 173f4f5df23SVikas Chaudhary spin_lock_irqsave(&ha->hardware_lock, flags); 174f4f5df23SVikas Chaudhary if (is_qla8022(ha)) { 175f4f5df23SVikas Chaudhary intr_status = 176f4f5df23SVikas Chaudhary readl(&ha->qla4_8xxx_reg->host_int); 177f4f5df23SVikas Chaudhary if (intr_status & ISRX_82XX_RISC_INT) { 178afaf5a2dSDavid Somayajulu ha->mbox_status_count = outCount; 179f4f5df23SVikas Chaudhary intr_status = 180f4f5df23SVikas Chaudhary readl(&ha->qla4_8xxx_reg->host_status); 181f4f5df23SVikas Chaudhary ha->isp_ops->interrupt_service_routine( 182f4f5df23SVikas Chaudhary ha, intr_status); 183f4f5df23SVikas Chaudhary if (test_bit(AF_INTERRUPTS_ON, 184f4f5df23SVikas Chaudhary &ha->flags) && 185f4f5df23SVikas Chaudhary test_bit(AF_INTx_ENABLED, 186f4f5df23SVikas Chaudhary &ha->flags)) 187f4f5df23SVikas Chaudhary qla4_8xxx_wr_32(ha, 188f4f5df23SVikas Chaudhary ha->nx_legacy_intr.tgt_mask_reg, 189f4f5df23SVikas Chaudhary 0xfbff); 190f4f5df23SVikas Chaudhary } 191f4f5df23SVikas Chaudhary } else { 192f4f5df23SVikas Chaudhary intr_status = readl(&ha->reg->ctrl_status); 193f4f5df23SVikas Chaudhary if (intr_status & INTR_PENDING) { 194f4f5df23SVikas Chaudhary /* 195f4f5df23SVikas Chaudhary * Service the interrupt. 196f4f5df23SVikas Chaudhary * The ISR will save the mailbox status 197f4f5df23SVikas Chaudhary * registers to a temporary storage 198f4f5df23SVikas Chaudhary * location in the adapter structure. 199f4f5df23SVikas Chaudhary */ 200f4f5df23SVikas Chaudhary ha->mbox_status_count = outCount; 201f4f5df23SVikas Chaudhary ha->isp_ops->interrupt_service_routine( 202f4f5df23SVikas Chaudhary ha, intr_status); 203f4f5df23SVikas Chaudhary } 204afaf5a2dSDavid Somayajulu } 205afaf5a2dSDavid Somayajulu spin_unlock_irqrestore(&ha->hardware_lock, flags); 206afaf5a2dSDavid Somayajulu msleep(10); 207afaf5a2dSDavid Somayajulu } 208f4f5df23SVikas Chaudhary } 209afaf5a2dSDavid Somayajulu 210afaf5a2dSDavid Somayajulu /* Check for mailbox timeout. */ 211afaf5a2dSDavid Somayajulu if (!test_bit(AF_MBOX_COMMAND_DONE, &ha->flags)) { 21221033639SNilesh Javali if (is_qla8022(ha) && 21321033639SNilesh Javali test_bit(AF_FW_RECOVERY, &ha->flags)) { 21421033639SNilesh Javali DEBUG2(ql4_printk(KERN_INFO, ha, 21521033639SNilesh Javali "scsi%ld: %s: prematurely completing mbx cmd as " 21621033639SNilesh Javali "firmware recovery detected\n", 21721033639SNilesh Javali ha->host_no, __func__)); 21821033639SNilesh Javali goto mbox_exit; 21921033639SNilesh Javali } 220afaf5a2dSDavid Somayajulu DEBUG2(printk("scsi%ld: Mailbox Cmd 0x%08X timed out ...," 221afaf5a2dSDavid Somayajulu " Scheduling Adapter Reset\n", ha->host_no, 222afaf5a2dSDavid Somayajulu mbx_cmd[0])); 223afaf5a2dSDavid Somayajulu ha->mailbox_timeout_count++; 224afaf5a2dSDavid Somayajulu mbx_sts[0] = (-1); 225afaf5a2dSDavid Somayajulu set_bit(DPC_RESET_HA, &ha->dpc_flags); 226afaf5a2dSDavid Somayajulu goto mbox_exit; 227afaf5a2dSDavid Somayajulu } 228afaf5a2dSDavid Somayajulu 229afaf5a2dSDavid Somayajulu /* 230afaf5a2dSDavid Somayajulu * Copy the mailbox out registers to the caller's mailbox in/out 231afaf5a2dSDavid Somayajulu * structure. 232afaf5a2dSDavid Somayajulu */ 233afaf5a2dSDavid Somayajulu spin_lock_irqsave(&ha->hardware_lock, flags); 234afaf5a2dSDavid Somayajulu for (i = 0; i < outCount; i++) 235afaf5a2dSDavid Somayajulu mbx_sts[i] = ha->mbox_status[i]; 236afaf5a2dSDavid Somayajulu 237afaf5a2dSDavid Somayajulu /* Set return status and error flags (if applicable). */ 238afaf5a2dSDavid Somayajulu switch (ha->mbox_status[0]) { 239afaf5a2dSDavid Somayajulu case MBOX_STS_COMMAND_COMPLETE: 240afaf5a2dSDavid Somayajulu status = QLA_SUCCESS; 241afaf5a2dSDavid Somayajulu break; 242afaf5a2dSDavid Somayajulu 243afaf5a2dSDavid Somayajulu case MBOX_STS_INTERMEDIATE_COMPLETION: 244afaf5a2dSDavid Somayajulu status = QLA_SUCCESS; 245afaf5a2dSDavid Somayajulu break; 246afaf5a2dSDavid Somayajulu 247afaf5a2dSDavid Somayajulu case MBOX_STS_BUSY: 248afaf5a2dSDavid Somayajulu DEBUG2( printk("scsi%ld: %s: Cmd = %08X, ISP BUSY\n", 249afaf5a2dSDavid Somayajulu ha->host_no, __func__, mbx_cmd[0])); 250afaf5a2dSDavid Somayajulu ha->mailbox_timeout_count++; 251afaf5a2dSDavid Somayajulu break; 252afaf5a2dSDavid Somayajulu 253afaf5a2dSDavid Somayajulu default: 254afaf5a2dSDavid Somayajulu DEBUG2(printk("scsi%ld: %s: **** FAILED, cmd = %08X, " 255afaf5a2dSDavid Somayajulu "sts = %08X ****\n", ha->host_no, __func__, 256afaf5a2dSDavid Somayajulu mbx_cmd[0], mbx_sts[0])); 257afaf5a2dSDavid Somayajulu break; 258afaf5a2dSDavid Somayajulu } 259afaf5a2dSDavid Somayajulu spin_unlock_irqrestore(&ha->hardware_lock, flags); 260afaf5a2dSDavid Somayajulu 261afaf5a2dSDavid Somayajulu mbox_exit: 262477ffb9dSDavid C Somayajulu mutex_lock(&ha->mbox_sem); 263afaf5a2dSDavid Somayajulu clear_bit(AF_MBOX_COMMAND, &ha->flags); 264afaf5a2dSDavid Somayajulu mutex_unlock(&ha->mbox_sem); 265477ffb9dSDavid C Somayajulu clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags); 266afaf5a2dSDavid Somayajulu 267afaf5a2dSDavid Somayajulu return status; 268afaf5a2dSDavid Somayajulu } 269afaf5a2dSDavid Somayajulu 27021033639SNilesh Javali void qla4xxx_mailbox_premature_completion(struct scsi_qla_host *ha) 27121033639SNilesh Javali { 27221033639SNilesh Javali set_bit(AF_FW_RECOVERY, &ha->flags); 27321033639SNilesh Javali ql4_printk(KERN_INFO, ha, "scsi%ld: %s: set FW RECOVERY!\n", 27421033639SNilesh Javali ha->host_no, __func__); 27521033639SNilesh Javali 27621033639SNilesh Javali if (test_bit(AF_MBOX_COMMAND, &ha->flags)) { 27721033639SNilesh Javali if (test_bit(AF_MBOX_COMMAND_NOPOLL, &ha->flags)) { 27821033639SNilesh Javali complete(&ha->mbx_intr_comp); 27921033639SNilesh Javali ql4_printk(KERN_INFO, ha, "scsi%ld: %s: Due to fw " 28021033639SNilesh Javali "recovery, doing premature completion of " 28121033639SNilesh Javali "mbx cmd\n", ha->host_no, __func__); 28221033639SNilesh Javali 28321033639SNilesh Javali } else { 28421033639SNilesh Javali set_bit(AF_MBOX_COMMAND_DONE, &ha->flags); 28521033639SNilesh Javali ql4_printk(KERN_INFO, ha, "scsi%ld: %s: Due to fw " 28621033639SNilesh Javali "recovery, doing premature completion of " 28721033639SNilesh Javali "polling mbx cmd\n", ha->host_no, __func__); 28821033639SNilesh Javali } 28921033639SNilesh Javali } 29021033639SNilesh Javali } 29121033639SNilesh Javali 292f4f5df23SVikas Chaudhary static uint8_t 2932a49a78eSVikas Chaudhary qla4xxx_set_ifcb(struct scsi_qla_host *ha, uint32_t *mbox_cmd, 2942a49a78eSVikas Chaudhary uint32_t *mbox_sts, dma_addr_t init_fw_cb_dma) 2952a49a78eSVikas Chaudhary { 2962a49a78eSVikas Chaudhary memset(mbox_cmd, 0, sizeof(mbox_cmd[0]) * MBOX_REG_COUNT); 2972a49a78eSVikas Chaudhary memset(mbox_sts, 0, sizeof(mbox_sts[0]) * MBOX_REG_COUNT); 2982657c800SShyam Sundar 2992657c800SShyam Sundar if (is_qla8022(ha)) 3002657c800SShyam Sundar qla4_8xxx_wr_32(ha, ha->nx_db_wr_ptr, 0); 3012657c800SShyam Sundar 3022a49a78eSVikas Chaudhary mbox_cmd[0] = MBOX_CMD_INITIALIZE_FIRMWARE; 3032a49a78eSVikas Chaudhary mbox_cmd[1] = 0; 3042a49a78eSVikas Chaudhary mbox_cmd[2] = LSDW(init_fw_cb_dma); 3052a49a78eSVikas Chaudhary mbox_cmd[3] = MSDW(init_fw_cb_dma); 3062a49a78eSVikas Chaudhary mbox_cmd[4] = sizeof(struct addr_ctrl_blk); 3072a49a78eSVikas Chaudhary mbox_cmd[5] = (IFCB_VER_MAX << 8) | IFCB_VER_MIN; 3082a49a78eSVikas Chaudhary 3092a49a78eSVikas Chaudhary if (qla4xxx_mailbox_command(ha, 6, 6, mbox_cmd, mbox_sts) != 3102a49a78eSVikas Chaudhary QLA_SUCCESS) { 3112a49a78eSVikas Chaudhary DEBUG2(printk(KERN_WARNING "scsi%ld: %s: " 3122a49a78eSVikas Chaudhary "MBOX_CMD_INITIALIZE_FIRMWARE" 3132a49a78eSVikas Chaudhary " failed w/ status %04X\n", 3142a49a78eSVikas Chaudhary ha->host_no, __func__, mbox_sts[0])); 3152a49a78eSVikas Chaudhary return QLA_ERROR; 3162a49a78eSVikas Chaudhary } 3172a49a78eSVikas Chaudhary return QLA_SUCCESS; 3182a49a78eSVikas Chaudhary } 3192a49a78eSVikas Chaudhary 320f4f5df23SVikas Chaudhary static uint8_t 3212a49a78eSVikas Chaudhary qla4xxx_get_ifcb(struct scsi_qla_host *ha, uint32_t *mbox_cmd, 3222a49a78eSVikas Chaudhary uint32_t *mbox_sts, dma_addr_t init_fw_cb_dma) 3232a49a78eSVikas Chaudhary { 3242a49a78eSVikas Chaudhary memset(mbox_cmd, 0, sizeof(mbox_cmd[0]) * MBOX_REG_COUNT); 3252a49a78eSVikas Chaudhary memset(mbox_sts, 0, sizeof(mbox_sts[0]) * MBOX_REG_COUNT); 3262a49a78eSVikas Chaudhary mbox_cmd[0] = MBOX_CMD_GET_INIT_FW_CTRL_BLOCK; 3272a49a78eSVikas Chaudhary mbox_cmd[2] = LSDW(init_fw_cb_dma); 3282a49a78eSVikas Chaudhary mbox_cmd[3] = MSDW(init_fw_cb_dma); 3292a49a78eSVikas Chaudhary mbox_cmd[4] = sizeof(struct addr_ctrl_blk); 3302a49a78eSVikas Chaudhary 3312a49a78eSVikas Chaudhary if (qla4xxx_mailbox_command(ha, 5, 5, mbox_cmd, mbox_sts) != 3322a49a78eSVikas Chaudhary QLA_SUCCESS) { 3332a49a78eSVikas Chaudhary DEBUG2(printk(KERN_WARNING "scsi%ld: %s: " 3342a49a78eSVikas Chaudhary "MBOX_CMD_GET_INIT_FW_CTRL_BLOCK" 3352a49a78eSVikas Chaudhary " failed w/ status %04X\n", 3362a49a78eSVikas Chaudhary ha->host_no, __func__, mbox_sts[0])); 3372a49a78eSVikas Chaudhary return QLA_ERROR; 3382a49a78eSVikas Chaudhary } 3392a49a78eSVikas Chaudhary return QLA_SUCCESS; 3402a49a78eSVikas Chaudhary } 3412a49a78eSVikas Chaudhary 342f4f5df23SVikas Chaudhary static void 3432a49a78eSVikas Chaudhary qla4xxx_update_local_ip(struct scsi_qla_host *ha, 3442a49a78eSVikas Chaudhary struct addr_ctrl_blk *init_fw_cb) 3452a49a78eSVikas Chaudhary { 3462a49a78eSVikas Chaudhary /* Save IPv4 Address Info */ 3472a49a78eSVikas Chaudhary memcpy(ha->ip_address, init_fw_cb->ipv4_addr, 3482a49a78eSVikas Chaudhary min(sizeof(ha->ip_address), sizeof(init_fw_cb->ipv4_addr))); 3492a49a78eSVikas Chaudhary memcpy(ha->subnet_mask, init_fw_cb->ipv4_subnet, 3502a49a78eSVikas Chaudhary min(sizeof(ha->subnet_mask), sizeof(init_fw_cb->ipv4_subnet))); 3512a49a78eSVikas Chaudhary memcpy(ha->gateway, init_fw_cb->ipv4_gw_addr, 3522a49a78eSVikas Chaudhary min(sizeof(ha->gateway), sizeof(init_fw_cb->ipv4_gw_addr))); 3532a49a78eSVikas Chaudhary 3542a49a78eSVikas Chaudhary if (is_ipv6_enabled(ha)) { 3552a49a78eSVikas Chaudhary /* Save IPv6 Address */ 3562a49a78eSVikas Chaudhary ha->ipv6_link_local_state = init_fw_cb->ipv6_lnk_lcl_addr_state; 3572a49a78eSVikas Chaudhary ha->ipv6_addr0_state = init_fw_cb->ipv6_addr0_state; 3582a49a78eSVikas Chaudhary ha->ipv6_addr1_state = init_fw_cb->ipv6_addr1_state; 3592a49a78eSVikas Chaudhary ha->ipv6_default_router_state = init_fw_cb->ipv6_dflt_rtr_state; 3602a49a78eSVikas Chaudhary ha->ipv6_link_local_addr.in6_u.u6_addr8[0] = 0xFE; 3612a49a78eSVikas Chaudhary ha->ipv6_link_local_addr.in6_u.u6_addr8[1] = 0x80; 3622a49a78eSVikas Chaudhary 3632a49a78eSVikas Chaudhary memcpy(&ha->ipv6_link_local_addr.in6_u.u6_addr8[8], 3642a49a78eSVikas Chaudhary init_fw_cb->ipv6_if_id, 3652a49a78eSVikas Chaudhary min(sizeof(ha->ipv6_link_local_addr)/2, 3662a49a78eSVikas Chaudhary sizeof(init_fw_cb->ipv6_if_id))); 3672a49a78eSVikas Chaudhary memcpy(&ha->ipv6_addr0, init_fw_cb->ipv6_addr0, 3682a49a78eSVikas Chaudhary min(sizeof(ha->ipv6_addr0), 3692a49a78eSVikas Chaudhary sizeof(init_fw_cb->ipv6_addr0))); 3702a49a78eSVikas Chaudhary memcpy(&ha->ipv6_addr1, init_fw_cb->ipv6_addr1, 3712a49a78eSVikas Chaudhary min(sizeof(ha->ipv6_addr1), 3722a49a78eSVikas Chaudhary sizeof(init_fw_cb->ipv6_addr1))); 3732a49a78eSVikas Chaudhary memcpy(&ha->ipv6_default_router_addr, 3742a49a78eSVikas Chaudhary init_fw_cb->ipv6_dflt_rtr_addr, 3752a49a78eSVikas Chaudhary min(sizeof(ha->ipv6_default_router_addr), 3762a49a78eSVikas Chaudhary sizeof(init_fw_cb->ipv6_dflt_rtr_addr))); 3772a49a78eSVikas Chaudhary } 3782a49a78eSVikas Chaudhary } 3792a49a78eSVikas Chaudhary 380f4f5df23SVikas Chaudhary static uint8_t 3812a49a78eSVikas Chaudhary qla4xxx_update_local_ifcb(struct scsi_qla_host *ha, 3822a49a78eSVikas Chaudhary uint32_t *mbox_cmd, 3832a49a78eSVikas Chaudhary uint32_t *mbox_sts, 3842a49a78eSVikas Chaudhary struct addr_ctrl_blk *init_fw_cb, 3852a49a78eSVikas Chaudhary dma_addr_t init_fw_cb_dma) 3862a49a78eSVikas Chaudhary { 3872a49a78eSVikas Chaudhary if (qla4xxx_get_ifcb(ha, mbox_cmd, mbox_sts, init_fw_cb_dma) 3882a49a78eSVikas Chaudhary != QLA_SUCCESS) { 3892a49a78eSVikas Chaudhary DEBUG2(printk(KERN_WARNING 3902a49a78eSVikas Chaudhary "scsi%ld: %s: Failed to get init_fw_ctrl_blk\n", 3912a49a78eSVikas Chaudhary ha->host_no, __func__)); 3922a49a78eSVikas Chaudhary return QLA_ERROR; 3932a49a78eSVikas Chaudhary } 3942a49a78eSVikas Chaudhary 3952a49a78eSVikas Chaudhary DEBUG2(qla4xxx_dump_buffer(init_fw_cb, sizeof(struct addr_ctrl_blk))); 3962a49a78eSVikas Chaudhary 3972a49a78eSVikas Chaudhary /* Save some info in adapter structure. */ 3982a49a78eSVikas Chaudhary ha->acb_version = init_fw_cb->acb_version; 3992a49a78eSVikas Chaudhary ha->firmware_options = le16_to_cpu(init_fw_cb->fw_options); 4002a49a78eSVikas Chaudhary ha->tcp_options = le16_to_cpu(init_fw_cb->ipv4_tcp_opts); 4012a49a78eSVikas Chaudhary ha->ipv4_options = le16_to_cpu(init_fw_cb->ipv4_ip_opts); 4022a49a78eSVikas Chaudhary ha->ipv4_addr_state = le16_to_cpu(init_fw_cb->ipv4_addr_state); 4032a49a78eSVikas Chaudhary ha->heartbeat_interval = init_fw_cb->hb_interval; 4042a49a78eSVikas Chaudhary memcpy(ha->name_string, init_fw_cb->iscsi_name, 4052a49a78eSVikas Chaudhary min(sizeof(ha->name_string), 4062a49a78eSVikas Chaudhary sizeof(init_fw_cb->iscsi_name))); 4072a49a78eSVikas Chaudhary /*memcpy(ha->alias, init_fw_cb->Alias, 4082a49a78eSVikas Chaudhary min(sizeof(ha->alias), sizeof(init_fw_cb->Alias)));*/ 4092a49a78eSVikas Chaudhary 4102a49a78eSVikas Chaudhary if (ha->acb_version == ACB_SUPPORTED) { 4112a49a78eSVikas Chaudhary ha->ipv6_options = init_fw_cb->ipv6_opts; 4122a49a78eSVikas Chaudhary ha->ipv6_addl_options = init_fw_cb->ipv6_addtl_opts; 4132a49a78eSVikas Chaudhary } 4142a49a78eSVikas Chaudhary qla4xxx_update_local_ip(ha, init_fw_cb); 4152a49a78eSVikas Chaudhary 4162a49a78eSVikas Chaudhary return QLA_SUCCESS; 4172a49a78eSVikas Chaudhary } 4182a49a78eSVikas Chaudhary 419afaf5a2dSDavid Somayajulu /** 420afaf5a2dSDavid Somayajulu * qla4xxx_initialize_fw_cb - initializes firmware control block. 421afaf5a2dSDavid Somayajulu * @ha: Pointer to host adapter structure. 422afaf5a2dSDavid Somayajulu **/ 423afaf5a2dSDavid Somayajulu int qla4xxx_initialize_fw_cb(struct scsi_qla_host * ha) 424afaf5a2dSDavid Somayajulu { 4252a49a78eSVikas Chaudhary struct addr_ctrl_blk *init_fw_cb; 426afaf5a2dSDavid Somayajulu dma_addr_t init_fw_cb_dma; 427afaf5a2dSDavid Somayajulu uint32_t mbox_cmd[MBOX_REG_COUNT]; 428afaf5a2dSDavid Somayajulu uint32_t mbox_sts[MBOX_REG_COUNT]; 429afaf5a2dSDavid Somayajulu int status = QLA_ERROR; 430afaf5a2dSDavid Somayajulu 431afaf5a2dSDavid Somayajulu init_fw_cb = dma_alloc_coherent(&ha->pdev->dev, 4322a49a78eSVikas Chaudhary sizeof(struct addr_ctrl_blk), 433afaf5a2dSDavid Somayajulu &init_fw_cb_dma, GFP_KERNEL); 434afaf5a2dSDavid Somayajulu if (init_fw_cb == NULL) { 435afaf5a2dSDavid Somayajulu DEBUG2(printk("scsi%ld: %s: Unable to alloc init_cb\n", 436afaf5a2dSDavid Somayajulu ha->host_no, __func__)); 437beabe7c1SPrasanna Mumbai goto exit_init_fw_cb_no_free; 438afaf5a2dSDavid Somayajulu } 4392a49a78eSVikas Chaudhary memset(init_fw_cb, 0, sizeof(struct addr_ctrl_blk)); 440afaf5a2dSDavid Somayajulu 441afaf5a2dSDavid Somayajulu /* Get Initialize Firmware Control Block. */ 442afaf5a2dSDavid Somayajulu memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 443afaf5a2dSDavid Somayajulu memset(&mbox_sts, 0, sizeof(mbox_sts)); 444c0e344c9SDavid C Somayajulu 4452a49a78eSVikas Chaudhary if (qla4xxx_get_ifcb(ha, &mbox_cmd[0], &mbox_sts[0], init_fw_cb_dma) != 446afaf5a2dSDavid Somayajulu QLA_SUCCESS) { 447afaf5a2dSDavid Somayajulu dma_free_coherent(&ha->pdev->dev, 4482a49a78eSVikas Chaudhary sizeof(struct addr_ctrl_blk), 449afaf5a2dSDavid Somayajulu init_fw_cb, init_fw_cb_dma); 4502a49a78eSVikas Chaudhary goto exit_init_fw_cb; 451afaf5a2dSDavid Somayajulu } 452afaf5a2dSDavid Somayajulu 453afaf5a2dSDavid Somayajulu /* Initialize request and response queues. */ 454afaf5a2dSDavid Somayajulu qla4xxx_init_rings(ha); 455afaf5a2dSDavid Somayajulu 456afaf5a2dSDavid Somayajulu /* Fill in the request and response queue information. */ 4572a49a78eSVikas Chaudhary init_fw_cb->rqq_consumer_idx = cpu_to_le16(ha->request_out); 4582a49a78eSVikas Chaudhary init_fw_cb->compq_producer_idx = cpu_to_le16(ha->response_in); 4592a49a78eSVikas Chaudhary init_fw_cb->rqq_len = __constant_cpu_to_le16(REQUEST_QUEUE_DEPTH); 4602a49a78eSVikas Chaudhary init_fw_cb->compq_len = __constant_cpu_to_le16(RESPONSE_QUEUE_DEPTH); 4612a49a78eSVikas Chaudhary init_fw_cb->rqq_addr_lo = cpu_to_le32(LSDW(ha->request_dma)); 4622a49a78eSVikas Chaudhary init_fw_cb->rqq_addr_hi = cpu_to_le32(MSDW(ha->request_dma)); 4632a49a78eSVikas Chaudhary init_fw_cb->compq_addr_lo = cpu_to_le32(LSDW(ha->response_dma)); 4642a49a78eSVikas Chaudhary init_fw_cb->compq_addr_hi = cpu_to_le32(MSDW(ha->response_dma)); 4652a49a78eSVikas Chaudhary init_fw_cb->shdwreg_addr_lo = cpu_to_le32(LSDW(ha->shadow_regs_dma)); 4662a49a78eSVikas Chaudhary init_fw_cb->shdwreg_addr_hi = cpu_to_le32(MSDW(ha->shadow_regs_dma)); 467afaf5a2dSDavid Somayajulu 468afaf5a2dSDavid Somayajulu /* Set up required options. */ 4692a49a78eSVikas Chaudhary init_fw_cb->fw_options |= 470afaf5a2dSDavid Somayajulu __constant_cpu_to_le16(FWOPT_SESSION_MODE | 471afaf5a2dSDavid Somayajulu FWOPT_INITIATOR_MODE); 4722657c800SShyam Sundar 4732657c800SShyam Sundar if (is_qla8022(ha)) 4742657c800SShyam Sundar init_fw_cb->fw_options |= 4752657c800SShyam Sundar __constant_cpu_to_le16(FWOPT_ENABLE_CRBDB); 4762657c800SShyam Sundar 4772a49a78eSVikas Chaudhary init_fw_cb->fw_options &= __constant_cpu_to_le16(~FWOPT_TARGET_MODE); 478afaf5a2dSDavid Somayajulu 4792a49a78eSVikas Chaudhary if (qla4xxx_set_ifcb(ha, &mbox_cmd[0], &mbox_sts[0], init_fw_cb_dma) 4802a49a78eSVikas Chaudhary != QLA_SUCCESS) { 4812a49a78eSVikas Chaudhary DEBUG2(printk(KERN_WARNING 4822a49a78eSVikas Chaudhary "scsi%ld: %s: Failed to set init_fw_ctrl_blk\n", 4832a49a78eSVikas Chaudhary ha->host_no, __func__)); 4842a49a78eSVikas Chaudhary goto exit_init_fw_cb; 485afaf5a2dSDavid Somayajulu } 4862a49a78eSVikas Chaudhary 4872a49a78eSVikas Chaudhary if (qla4xxx_update_local_ifcb(ha, &mbox_cmd[0], &mbox_sts[0], 4882a49a78eSVikas Chaudhary init_fw_cb, init_fw_cb_dma) != QLA_SUCCESS) { 4892a49a78eSVikas Chaudhary DEBUG2(printk("scsi%ld: %s: Failed to update local ifcb\n", 4902a49a78eSVikas Chaudhary ha->host_no, __func__)); 4912a49a78eSVikas Chaudhary goto exit_init_fw_cb; 4922a49a78eSVikas Chaudhary } 4932a49a78eSVikas Chaudhary status = QLA_SUCCESS; 4942a49a78eSVikas Chaudhary 4952a49a78eSVikas Chaudhary exit_init_fw_cb: 4962a49a78eSVikas Chaudhary dma_free_coherent(&ha->pdev->dev, sizeof(struct addr_ctrl_blk), 497afaf5a2dSDavid Somayajulu init_fw_cb, init_fw_cb_dma); 498beabe7c1SPrasanna Mumbai exit_init_fw_cb_no_free: 499afaf5a2dSDavid Somayajulu return status; 500afaf5a2dSDavid Somayajulu } 501afaf5a2dSDavid Somayajulu 502afaf5a2dSDavid Somayajulu /** 503afaf5a2dSDavid Somayajulu * qla4xxx_get_dhcp_ip_address - gets HBA ip address via DHCP 504afaf5a2dSDavid Somayajulu * @ha: Pointer to host adapter structure. 505afaf5a2dSDavid Somayajulu **/ 506afaf5a2dSDavid Somayajulu int qla4xxx_get_dhcp_ip_address(struct scsi_qla_host * ha) 507afaf5a2dSDavid Somayajulu { 5082a49a78eSVikas Chaudhary struct addr_ctrl_blk *init_fw_cb; 509afaf5a2dSDavid Somayajulu dma_addr_t init_fw_cb_dma; 510afaf5a2dSDavid Somayajulu uint32_t mbox_cmd[MBOX_REG_COUNT]; 511afaf5a2dSDavid Somayajulu uint32_t mbox_sts[MBOX_REG_COUNT]; 512afaf5a2dSDavid Somayajulu 513afaf5a2dSDavid Somayajulu init_fw_cb = dma_alloc_coherent(&ha->pdev->dev, 5142a49a78eSVikas Chaudhary sizeof(struct addr_ctrl_blk), 515afaf5a2dSDavid Somayajulu &init_fw_cb_dma, GFP_KERNEL); 516afaf5a2dSDavid Somayajulu if (init_fw_cb == NULL) { 517afaf5a2dSDavid Somayajulu printk("scsi%ld: %s: Unable to alloc init_cb\n", ha->host_no, 518afaf5a2dSDavid Somayajulu __func__); 519beabe7c1SPrasanna Mumbai return QLA_ERROR; 520afaf5a2dSDavid Somayajulu } 521afaf5a2dSDavid Somayajulu 522afaf5a2dSDavid Somayajulu /* Get Initialize Firmware Control Block. */ 5232a49a78eSVikas Chaudhary memset(init_fw_cb, 0, sizeof(struct addr_ctrl_blk)); 5242a49a78eSVikas Chaudhary if (qla4xxx_get_ifcb(ha, &mbox_cmd[0], &mbox_sts[0], init_fw_cb_dma) != 525afaf5a2dSDavid Somayajulu QLA_SUCCESS) { 526afaf5a2dSDavid Somayajulu DEBUG2(printk("scsi%ld: %s: Failed to get init_fw_ctrl_blk\n", 527afaf5a2dSDavid Somayajulu ha->host_no, __func__)); 528afaf5a2dSDavid Somayajulu dma_free_coherent(&ha->pdev->dev, 5292a49a78eSVikas Chaudhary sizeof(struct addr_ctrl_blk), 530afaf5a2dSDavid Somayajulu init_fw_cb, init_fw_cb_dma); 531afaf5a2dSDavid Somayajulu return QLA_ERROR; 532afaf5a2dSDavid Somayajulu } 533afaf5a2dSDavid Somayajulu 534afaf5a2dSDavid Somayajulu /* Save IP Address. */ 5352a49a78eSVikas Chaudhary qla4xxx_update_local_ip(ha, init_fw_cb); 5362a49a78eSVikas Chaudhary dma_free_coherent(&ha->pdev->dev, sizeof(struct addr_ctrl_blk), 537afaf5a2dSDavid Somayajulu init_fw_cb, init_fw_cb_dma); 538afaf5a2dSDavid Somayajulu 539afaf5a2dSDavid Somayajulu return QLA_SUCCESS; 540afaf5a2dSDavid Somayajulu } 541afaf5a2dSDavid Somayajulu 542afaf5a2dSDavid Somayajulu /** 543afaf5a2dSDavid Somayajulu * qla4xxx_get_firmware_state - gets firmware state of HBA 544afaf5a2dSDavid Somayajulu * @ha: Pointer to host adapter structure. 545afaf5a2dSDavid Somayajulu **/ 546afaf5a2dSDavid Somayajulu int qla4xxx_get_firmware_state(struct scsi_qla_host * ha) 547afaf5a2dSDavid Somayajulu { 548afaf5a2dSDavid Somayajulu uint32_t mbox_cmd[MBOX_REG_COUNT]; 549afaf5a2dSDavid Somayajulu uint32_t mbox_sts[MBOX_REG_COUNT]; 550afaf5a2dSDavid Somayajulu 551afaf5a2dSDavid Somayajulu /* Get firmware version */ 552afaf5a2dSDavid Somayajulu memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 553afaf5a2dSDavid Somayajulu memset(&mbox_sts, 0, sizeof(mbox_sts)); 554c0e344c9SDavid C Somayajulu 555afaf5a2dSDavid Somayajulu mbox_cmd[0] = MBOX_CMD_GET_FW_STATE; 556c0e344c9SDavid C Somayajulu 557c0e344c9SDavid C Somayajulu if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 4, &mbox_cmd[0], &mbox_sts[0]) != 558afaf5a2dSDavid Somayajulu QLA_SUCCESS) { 559afaf5a2dSDavid Somayajulu DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_FW_STATE failed w/ " 560afaf5a2dSDavid Somayajulu "status %04X\n", ha->host_no, __func__, 561afaf5a2dSDavid Somayajulu mbox_sts[0])); 562afaf5a2dSDavid Somayajulu return QLA_ERROR; 563afaf5a2dSDavid Somayajulu } 564afaf5a2dSDavid Somayajulu ha->firmware_state = mbox_sts[1]; 565afaf5a2dSDavid Somayajulu ha->board_id = mbox_sts[2]; 566afaf5a2dSDavid Somayajulu ha->addl_fw_state = mbox_sts[3]; 567afaf5a2dSDavid Somayajulu DEBUG2(printk("scsi%ld: %s firmware_state=0x%x\n", 568afaf5a2dSDavid Somayajulu ha->host_no, __func__, ha->firmware_state);) 569afaf5a2dSDavid Somayajulu 570afaf5a2dSDavid Somayajulu return QLA_SUCCESS; 571afaf5a2dSDavid Somayajulu } 572afaf5a2dSDavid Somayajulu 573afaf5a2dSDavid Somayajulu /** 574afaf5a2dSDavid Somayajulu * qla4xxx_get_firmware_status - retrieves firmware status 575afaf5a2dSDavid Somayajulu * @ha: Pointer to host adapter structure. 576afaf5a2dSDavid Somayajulu **/ 577afaf5a2dSDavid Somayajulu int qla4xxx_get_firmware_status(struct scsi_qla_host * ha) 578afaf5a2dSDavid Somayajulu { 579afaf5a2dSDavid Somayajulu uint32_t mbox_cmd[MBOX_REG_COUNT]; 580afaf5a2dSDavid Somayajulu uint32_t mbox_sts[MBOX_REG_COUNT]; 581afaf5a2dSDavid Somayajulu 582afaf5a2dSDavid Somayajulu /* Get firmware version */ 583afaf5a2dSDavid Somayajulu memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 584afaf5a2dSDavid Somayajulu memset(&mbox_sts, 0, sizeof(mbox_sts)); 585c0e344c9SDavid C Somayajulu 586afaf5a2dSDavid Somayajulu mbox_cmd[0] = MBOX_CMD_GET_FW_STATUS; 587c0e344c9SDavid C Somayajulu 588c0e344c9SDavid C Somayajulu if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 3, &mbox_cmd[0], &mbox_sts[0]) != 589afaf5a2dSDavid Somayajulu QLA_SUCCESS) { 590afaf5a2dSDavid Somayajulu DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_FW_STATUS failed w/ " 591afaf5a2dSDavid Somayajulu "status %04X\n", ha->host_no, __func__, 592afaf5a2dSDavid Somayajulu mbox_sts[0])); 593afaf5a2dSDavid Somayajulu return QLA_ERROR; 594afaf5a2dSDavid Somayajulu } 595f4f5df23SVikas Chaudhary 596f4f5df23SVikas Chaudhary ql4_printk(KERN_INFO, ha, "%ld firmare IOCBs available (%d).\n", 597f581a3f7SVikas Chaudhary ha->host_no, mbox_sts[2]); 598f4f5df23SVikas Chaudhary 599afaf5a2dSDavid Somayajulu return QLA_SUCCESS; 600afaf5a2dSDavid Somayajulu } 601afaf5a2dSDavid Somayajulu 602afaf5a2dSDavid Somayajulu /** 603afaf5a2dSDavid Somayajulu * qla4xxx_get_fwddb_entry - retrieves firmware ddb entry 604afaf5a2dSDavid Somayajulu * @ha: Pointer to host adapter structure. 605afaf5a2dSDavid Somayajulu * @fw_ddb_index: Firmware's device database index 606afaf5a2dSDavid Somayajulu * @fw_ddb_entry: Pointer to firmware's device database entry structure 607afaf5a2dSDavid Somayajulu * @num_valid_ddb_entries: Pointer to number of valid ddb entries 608afaf5a2dSDavid Somayajulu * @next_ddb_index: Pointer to next valid device database index 609afaf5a2dSDavid Somayajulu * @fw_ddb_device_state: Pointer to device state 610afaf5a2dSDavid Somayajulu **/ 611afaf5a2dSDavid Somayajulu int qla4xxx_get_fwddb_entry(struct scsi_qla_host *ha, 612afaf5a2dSDavid Somayajulu uint16_t fw_ddb_index, 613afaf5a2dSDavid Somayajulu struct dev_db_entry *fw_ddb_entry, 614afaf5a2dSDavid Somayajulu dma_addr_t fw_ddb_entry_dma, 615afaf5a2dSDavid Somayajulu uint32_t *num_valid_ddb_entries, 616afaf5a2dSDavid Somayajulu uint32_t *next_ddb_index, 617afaf5a2dSDavid Somayajulu uint32_t *fw_ddb_device_state, 618afaf5a2dSDavid Somayajulu uint32_t *conn_err_detail, 619afaf5a2dSDavid Somayajulu uint16_t *tcp_source_port_num, 620afaf5a2dSDavid Somayajulu uint16_t *connection_id) 621afaf5a2dSDavid Somayajulu { 622afaf5a2dSDavid Somayajulu int status = QLA_ERROR; 6232a49a78eSVikas Chaudhary uint16_t options; 624afaf5a2dSDavid Somayajulu uint32_t mbox_cmd[MBOX_REG_COUNT]; 625afaf5a2dSDavid Somayajulu uint32_t mbox_sts[MBOX_REG_COUNT]; 626afaf5a2dSDavid Somayajulu 627afaf5a2dSDavid Somayajulu /* Make sure the device index is valid */ 628afaf5a2dSDavid Somayajulu if (fw_ddb_index >= MAX_DDB_ENTRIES) { 629f4f5df23SVikas Chaudhary DEBUG2(printk("scsi%ld: %s: ddb [%d] out of range.\n", 630afaf5a2dSDavid Somayajulu ha->host_no, __func__, fw_ddb_index)); 631afaf5a2dSDavid Somayajulu goto exit_get_fwddb; 632afaf5a2dSDavid Somayajulu } 633afaf5a2dSDavid Somayajulu memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 634afaf5a2dSDavid Somayajulu memset(&mbox_sts, 0, sizeof(mbox_sts)); 635c0e344c9SDavid C Somayajulu 636afaf5a2dSDavid Somayajulu mbox_cmd[0] = MBOX_CMD_GET_DATABASE_ENTRY; 637afaf5a2dSDavid Somayajulu mbox_cmd[1] = (uint32_t) fw_ddb_index; 638afaf5a2dSDavid Somayajulu mbox_cmd[2] = LSDW(fw_ddb_entry_dma); 639afaf5a2dSDavid Somayajulu mbox_cmd[3] = MSDW(fw_ddb_entry_dma); 640c0e344c9SDavid C Somayajulu mbox_cmd[4] = sizeof(struct dev_db_entry); 641c0e344c9SDavid C Somayajulu 642c0e344c9SDavid C Somayajulu if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 7, &mbox_cmd[0], &mbox_sts[0]) == 643afaf5a2dSDavid Somayajulu QLA_ERROR) { 644afaf5a2dSDavid Somayajulu DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_DATABASE_ENTRY failed" 645afaf5a2dSDavid Somayajulu " with status 0x%04X\n", ha->host_no, __func__, 646afaf5a2dSDavid Somayajulu mbox_sts[0])); 647afaf5a2dSDavid Somayajulu goto exit_get_fwddb; 648afaf5a2dSDavid Somayajulu } 649afaf5a2dSDavid Somayajulu if (fw_ddb_index != mbox_sts[1]) { 650f4f5df23SVikas Chaudhary DEBUG2(printk("scsi%ld: %s: ddb mismatch [%d] != [%d].\n", 651afaf5a2dSDavid Somayajulu ha->host_no, __func__, fw_ddb_index, 652afaf5a2dSDavid Somayajulu mbox_sts[1])); 653afaf5a2dSDavid Somayajulu goto exit_get_fwddb; 654afaf5a2dSDavid Somayajulu } 655afaf5a2dSDavid Somayajulu if (fw_ddb_entry) { 6562a49a78eSVikas Chaudhary options = le16_to_cpu(fw_ddb_entry->options); 6572a49a78eSVikas Chaudhary if (options & DDB_OPT_IPV6_DEVICE) { 658c2660df3SVikas Chaudhary ql4_printk(KERN_INFO, ha, "%s: DDB[%d] MB0 %04x Tot %d " 6592a49a78eSVikas Chaudhary "Next %d State %04x ConnErr %08x %pI6 " 6602a49a78eSVikas Chaudhary ":%04d \"%s\"\n", __func__, fw_ddb_index, 6612a49a78eSVikas Chaudhary mbox_sts[0], mbox_sts[2], mbox_sts[3], 6622a49a78eSVikas Chaudhary mbox_sts[4], mbox_sts[5], 6632a49a78eSVikas Chaudhary fw_ddb_entry->ip_addr, 664c0e344c9SDavid C Somayajulu le16_to_cpu(fw_ddb_entry->port), 665c0e344c9SDavid C Somayajulu fw_ddb_entry->iscsi_name); 6662a49a78eSVikas Chaudhary } else { 667c2660df3SVikas Chaudhary ql4_printk(KERN_INFO, ha, "%s: DDB[%d] MB0 %04x Tot %d " 6682a49a78eSVikas Chaudhary "Next %d State %04x ConnErr %08x %pI4 " 6692a49a78eSVikas Chaudhary ":%04d \"%s\"\n", __func__, fw_ddb_index, 6702a49a78eSVikas Chaudhary mbox_sts[0], mbox_sts[2], mbox_sts[3], 6712a49a78eSVikas Chaudhary mbox_sts[4], mbox_sts[5], 6722a49a78eSVikas Chaudhary fw_ddb_entry->ip_addr, 6732a49a78eSVikas Chaudhary le16_to_cpu(fw_ddb_entry->port), 6742a49a78eSVikas Chaudhary fw_ddb_entry->iscsi_name); 6752a49a78eSVikas Chaudhary } 676afaf5a2dSDavid Somayajulu } 677afaf5a2dSDavid Somayajulu if (num_valid_ddb_entries) 678afaf5a2dSDavid Somayajulu *num_valid_ddb_entries = mbox_sts[2]; 679afaf5a2dSDavid Somayajulu if (next_ddb_index) 680afaf5a2dSDavid Somayajulu *next_ddb_index = mbox_sts[3]; 681afaf5a2dSDavid Somayajulu if (fw_ddb_device_state) 682afaf5a2dSDavid Somayajulu *fw_ddb_device_state = mbox_sts[4]; 683afaf5a2dSDavid Somayajulu 684afaf5a2dSDavid Somayajulu /* 685afaf5a2dSDavid Somayajulu * RA: This mailbox has been changed to pass connection error and 686afaf5a2dSDavid Somayajulu * details. Its true for ISP4010 as per Version E - Not sure when it 687afaf5a2dSDavid Somayajulu * was changed. Get the time2wait from the fw_dd_entry field : 688afaf5a2dSDavid Somayajulu * default_time2wait which we call it as minTime2Wait DEV_DB_ENTRY 689afaf5a2dSDavid Somayajulu * struct. 690afaf5a2dSDavid Somayajulu */ 691afaf5a2dSDavid Somayajulu if (conn_err_detail) 692afaf5a2dSDavid Somayajulu *conn_err_detail = mbox_sts[5]; 693afaf5a2dSDavid Somayajulu if (tcp_source_port_num) 6941482338fSRandy Dunlap *tcp_source_port_num = (uint16_t) (mbox_sts[6] >> 16); 695afaf5a2dSDavid Somayajulu if (connection_id) 696afaf5a2dSDavid Somayajulu *connection_id = (uint16_t) mbox_sts[6] & 0x00FF; 697afaf5a2dSDavid Somayajulu status = QLA_SUCCESS; 698afaf5a2dSDavid Somayajulu 699afaf5a2dSDavid Somayajulu exit_get_fwddb: 700afaf5a2dSDavid Somayajulu return status; 701afaf5a2dSDavid Somayajulu } 702afaf5a2dSDavid Somayajulu 703afaf5a2dSDavid Somayajulu /** 704afaf5a2dSDavid Somayajulu * qla4xxx_set_fwddb_entry - sets a ddb entry. 705afaf5a2dSDavid Somayajulu * @ha: Pointer to host adapter structure. 706afaf5a2dSDavid Somayajulu * @fw_ddb_index: Firmware's device database index 707afaf5a2dSDavid Somayajulu * @fw_ddb_entry: Pointer to firmware's ddb entry structure, or NULL. 708afaf5a2dSDavid Somayajulu * 709afaf5a2dSDavid Somayajulu * This routine initializes or updates the adapter's device database 710afaf5a2dSDavid Somayajulu * entry for the specified device. It also triggers a login for the 711afaf5a2dSDavid Somayajulu * specified device. Therefore, it may also be used as a secondary 712afaf5a2dSDavid Somayajulu * login routine when a NULL pointer is specified for the fw_ddb_entry. 713afaf5a2dSDavid Somayajulu **/ 714afaf5a2dSDavid Somayajulu int qla4xxx_set_ddb_entry(struct scsi_qla_host * ha, uint16_t fw_ddb_index, 715afaf5a2dSDavid Somayajulu dma_addr_t fw_ddb_entry_dma) 716afaf5a2dSDavid Somayajulu { 717afaf5a2dSDavid Somayajulu uint32_t mbox_cmd[MBOX_REG_COUNT]; 718afaf5a2dSDavid Somayajulu uint32_t mbox_sts[MBOX_REG_COUNT]; 719f4f5df23SVikas Chaudhary int status; 720afaf5a2dSDavid Somayajulu 721afaf5a2dSDavid Somayajulu /* Do not wait for completion. The firmware will send us an 722afaf5a2dSDavid Somayajulu * ASTS_DATABASE_CHANGED (0x8014) to notify us of the login status. 723afaf5a2dSDavid Somayajulu */ 724afaf5a2dSDavid Somayajulu memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 725afaf5a2dSDavid Somayajulu memset(&mbox_sts, 0, sizeof(mbox_sts)); 726afaf5a2dSDavid Somayajulu 727afaf5a2dSDavid Somayajulu mbox_cmd[0] = MBOX_CMD_SET_DATABASE_ENTRY; 728afaf5a2dSDavid Somayajulu mbox_cmd[1] = (uint32_t) fw_ddb_index; 729afaf5a2dSDavid Somayajulu mbox_cmd[2] = LSDW(fw_ddb_entry_dma); 730afaf5a2dSDavid Somayajulu mbox_cmd[3] = MSDW(fw_ddb_entry_dma); 731c0e344c9SDavid C Somayajulu mbox_cmd[4] = sizeof(struct dev_db_entry); 732c0e344c9SDavid C Somayajulu 733f4f5df23SVikas Chaudhary status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], 734f4f5df23SVikas Chaudhary &mbox_sts[0]); 735f4f5df23SVikas Chaudhary DEBUG2(printk("scsi%ld: %s: status=%d mbx0=0x%x mbx4=0x%x\n", 736f4f5df23SVikas Chaudhary ha->host_no, __func__, status, mbox_sts[0], mbox_sts[4]);) 737f4f5df23SVikas Chaudhary 738f4f5df23SVikas Chaudhary return status; 739afaf5a2dSDavid Somayajulu } 740afaf5a2dSDavid Somayajulu 741afaf5a2dSDavid Somayajulu /** 742afaf5a2dSDavid Somayajulu * qla4xxx_get_crash_record - retrieves crash record. 743afaf5a2dSDavid Somayajulu * @ha: Pointer to host adapter structure. 744afaf5a2dSDavid Somayajulu * 745afaf5a2dSDavid Somayajulu * This routine retrieves a crash record from the QLA4010 after an 8002h aen. 746afaf5a2dSDavid Somayajulu **/ 747afaf5a2dSDavid Somayajulu void qla4xxx_get_crash_record(struct scsi_qla_host * ha) 748afaf5a2dSDavid Somayajulu { 749afaf5a2dSDavid Somayajulu uint32_t mbox_cmd[MBOX_REG_COUNT]; 750afaf5a2dSDavid Somayajulu uint32_t mbox_sts[MBOX_REG_COUNT]; 751afaf5a2dSDavid Somayajulu struct crash_record *crash_record = NULL; 752afaf5a2dSDavid Somayajulu dma_addr_t crash_record_dma = 0; 753afaf5a2dSDavid Somayajulu uint32_t crash_record_size = 0; 754c0e344c9SDavid C Somayajulu 755afaf5a2dSDavid Somayajulu memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 756afaf5a2dSDavid Somayajulu memset(&mbox_sts, 0, sizeof(mbox_cmd)); 757afaf5a2dSDavid Somayajulu 758afaf5a2dSDavid Somayajulu /* Get size of crash record. */ 759afaf5a2dSDavid Somayajulu mbox_cmd[0] = MBOX_CMD_GET_CRASH_RECORD; 760c0e344c9SDavid C Somayajulu 761c0e344c9SDavid C Somayajulu if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) != 762afaf5a2dSDavid Somayajulu QLA_SUCCESS) { 763afaf5a2dSDavid Somayajulu DEBUG2(printk("scsi%ld: %s: ERROR: Unable to retrieve size!\n", 764afaf5a2dSDavid Somayajulu ha->host_no, __func__)); 765afaf5a2dSDavid Somayajulu goto exit_get_crash_record; 766afaf5a2dSDavid Somayajulu } 767afaf5a2dSDavid Somayajulu crash_record_size = mbox_sts[4]; 768afaf5a2dSDavid Somayajulu if (crash_record_size == 0) { 769afaf5a2dSDavid Somayajulu DEBUG2(printk("scsi%ld: %s: ERROR: Crash record size is 0!\n", 770afaf5a2dSDavid Somayajulu ha->host_no, __func__)); 771afaf5a2dSDavid Somayajulu goto exit_get_crash_record; 772afaf5a2dSDavid Somayajulu } 773afaf5a2dSDavid Somayajulu 774afaf5a2dSDavid Somayajulu /* Alloc Memory for Crash Record. */ 775afaf5a2dSDavid Somayajulu crash_record = dma_alloc_coherent(&ha->pdev->dev, crash_record_size, 776afaf5a2dSDavid Somayajulu &crash_record_dma, GFP_KERNEL); 777afaf5a2dSDavid Somayajulu if (crash_record == NULL) 778afaf5a2dSDavid Somayajulu goto exit_get_crash_record; 779afaf5a2dSDavid Somayajulu 780afaf5a2dSDavid Somayajulu /* Get Crash Record. */ 781c0e344c9SDavid C Somayajulu memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 782c0e344c9SDavid C Somayajulu memset(&mbox_sts, 0, sizeof(mbox_cmd)); 783c0e344c9SDavid C Somayajulu 784afaf5a2dSDavid Somayajulu mbox_cmd[0] = MBOX_CMD_GET_CRASH_RECORD; 785afaf5a2dSDavid Somayajulu mbox_cmd[2] = LSDW(crash_record_dma); 786afaf5a2dSDavid Somayajulu mbox_cmd[3] = MSDW(crash_record_dma); 787afaf5a2dSDavid Somayajulu mbox_cmd[4] = crash_record_size; 788c0e344c9SDavid C Somayajulu 789c0e344c9SDavid C Somayajulu if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) != 790afaf5a2dSDavid Somayajulu QLA_SUCCESS) 791afaf5a2dSDavid Somayajulu goto exit_get_crash_record; 792afaf5a2dSDavid Somayajulu 793afaf5a2dSDavid Somayajulu /* Dump Crash Record. */ 794afaf5a2dSDavid Somayajulu 795afaf5a2dSDavid Somayajulu exit_get_crash_record: 796afaf5a2dSDavid Somayajulu if (crash_record) 797afaf5a2dSDavid Somayajulu dma_free_coherent(&ha->pdev->dev, crash_record_size, 798afaf5a2dSDavid Somayajulu crash_record, crash_record_dma); 799afaf5a2dSDavid Somayajulu } 800afaf5a2dSDavid Somayajulu 801afaf5a2dSDavid Somayajulu /** 802afaf5a2dSDavid Somayajulu * qla4xxx_get_conn_event_log - retrieves connection event log 803afaf5a2dSDavid Somayajulu * @ha: Pointer to host adapter structure. 804afaf5a2dSDavid Somayajulu **/ 805afaf5a2dSDavid Somayajulu void qla4xxx_get_conn_event_log(struct scsi_qla_host * ha) 806afaf5a2dSDavid Somayajulu { 807afaf5a2dSDavid Somayajulu uint32_t mbox_cmd[MBOX_REG_COUNT]; 808afaf5a2dSDavid Somayajulu uint32_t mbox_sts[MBOX_REG_COUNT]; 809afaf5a2dSDavid Somayajulu struct conn_event_log_entry *event_log = NULL; 810afaf5a2dSDavid Somayajulu dma_addr_t event_log_dma = 0; 811afaf5a2dSDavid Somayajulu uint32_t event_log_size = 0; 812afaf5a2dSDavid Somayajulu uint32_t num_valid_entries; 813afaf5a2dSDavid Somayajulu uint32_t oldest_entry = 0; 814afaf5a2dSDavid Somayajulu uint32_t max_event_log_entries; 815afaf5a2dSDavid Somayajulu uint8_t i; 816afaf5a2dSDavid Somayajulu 817afaf5a2dSDavid Somayajulu 818afaf5a2dSDavid Somayajulu memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 819afaf5a2dSDavid Somayajulu memset(&mbox_sts, 0, sizeof(mbox_cmd)); 820afaf5a2dSDavid Somayajulu 821afaf5a2dSDavid Somayajulu /* Get size of crash record. */ 822afaf5a2dSDavid Somayajulu mbox_cmd[0] = MBOX_CMD_GET_CONN_EVENT_LOG; 823c0e344c9SDavid C Somayajulu 824c0e344c9SDavid C Somayajulu if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) != 825afaf5a2dSDavid Somayajulu QLA_SUCCESS) 826afaf5a2dSDavid Somayajulu goto exit_get_event_log; 827afaf5a2dSDavid Somayajulu 828afaf5a2dSDavid Somayajulu event_log_size = mbox_sts[4]; 829afaf5a2dSDavid Somayajulu if (event_log_size == 0) 830afaf5a2dSDavid Somayajulu goto exit_get_event_log; 831afaf5a2dSDavid Somayajulu 832afaf5a2dSDavid Somayajulu /* Alloc Memory for Crash Record. */ 833afaf5a2dSDavid Somayajulu event_log = dma_alloc_coherent(&ha->pdev->dev, event_log_size, 834afaf5a2dSDavid Somayajulu &event_log_dma, GFP_KERNEL); 835afaf5a2dSDavid Somayajulu if (event_log == NULL) 836afaf5a2dSDavid Somayajulu goto exit_get_event_log; 837afaf5a2dSDavid Somayajulu 838afaf5a2dSDavid Somayajulu /* Get Crash Record. */ 839c0e344c9SDavid C Somayajulu memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 840c0e344c9SDavid C Somayajulu memset(&mbox_sts, 0, sizeof(mbox_cmd)); 841c0e344c9SDavid C Somayajulu 842afaf5a2dSDavid Somayajulu mbox_cmd[0] = MBOX_CMD_GET_CONN_EVENT_LOG; 843afaf5a2dSDavid Somayajulu mbox_cmd[2] = LSDW(event_log_dma); 844afaf5a2dSDavid Somayajulu mbox_cmd[3] = MSDW(event_log_dma); 845c0e344c9SDavid C Somayajulu 846c0e344c9SDavid C Somayajulu if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) != 847afaf5a2dSDavid Somayajulu QLA_SUCCESS) { 848afaf5a2dSDavid Somayajulu DEBUG2(printk("scsi%ld: %s: ERROR: Unable to retrieve event " 849afaf5a2dSDavid Somayajulu "log!\n", ha->host_no, __func__)); 850afaf5a2dSDavid Somayajulu goto exit_get_event_log; 851afaf5a2dSDavid Somayajulu } 852afaf5a2dSDavid Somayajulu 853afaf5a2dSDavid Somayajulu /* Dump Event Log. */ 854afaf5a2dSDavid Somayajulu num_valid_entries = mbox_sts[1]; 855afaf5a2dSDavid Somayajulu 856afaf5a2dSDavid Somayajulu max_event_log_entries = event_log_size / 857afaf5a2dSDavid Somayajulu sizeof(struct conn_event_log_entry); 858afaf5a2dSDavid Somayajulu 859afaf5a2dSDavid Somayajulu if (num_valid_entries > max_event_log_entries) 860afaf5a2dSDavid Somayajulu oldest_entry = num_valid_entries % max_event_log_entries; 861afaf5a2dSDavid Somayajulu 862afaf5a2dSDavid Somayajulu DEBUG3(printk("scsi%ld: Connection Event Log Dump (%d entries):\n", 863afaf5a2dSDavid Somayajulu ha->host_no, num_valid_entries)); 864afaf5a2dSDavid Somayajulu 86511010fecSAndrew Vasquez if (ql4xextended_error_logging == 3) { 866afaf5a2dSDavid Somayajulu if (oldest_entry == 0) { 867afaf5a2dSDavid Somayajulu /* Circular Buffer has not wrapped around */ 868afaf5a2dSDavid Somayajulu for (i=0; i < num_valid_entries; i++) { 869afaf5a2dSDavid Somayajulu qla4xxx_dump_buffer((uint8_t *)event_log+ 870afaf5a2dSDavid Somayajulu (i*sizeof(*event_log)), 871afaf5a2dSDavid Somayajulu sizeof(*event_log)); 872afaf5a2dSDavid Somayajulu } 873afaf5a2dSDavid Somayajulu } 874afaf5a2dSDavid Somayajulu else { 875afaf5a2dSDavid Somayajulu /* Circular Buffer has wrapped around - 876afaf5a2dSDavid Somayajulu * display accordingly*/ 877afaf5a2dSDavid Somayajulu for (i=oldest_entry; i < max_event_log_entries; i++) { 878afaf5a2dSDavid Somayajulu qla4xxx_dump_buffer((uint8_t *)event_log+ 879afaf5a2dSDavid Somayajulu (i*sizeof(*event_log)), 880afaf5a2dSDavid Somayajulu sizeof(*event_log)); 881afaf5a2dSDavid Somayajulu } 882afaf5a2dSDavid Somayajulu for (i=0; i < oldest_entry; i++) { 883afaf5a2dSDavid Somayajulu qla4xxx_dump_buffer((uint8_t *)event_log+ 884afaf5a2dSDavid Somayajulu (i*sizeof(*event_log)), 885afaf5a2dSDavid Somayajulu sizeof(*event_log)); 886afaf5a2dSDavid Somayajulu } 887afaf5a2dSDavid Somayajulu } 888afaf5a2dSDavid Somayajulu } 889afaf5a2dSDavid Somayajulu 890afaf5a2dSDavid Somayajulu exit_get_event_log: 891afaf5a2dSDavid Somayajulu if (event_log) 892afaf5a2dSDavid Somayajulu dma_free_coherent(&ha->pdev->dev, event_log_size, event_log, 893afaf5a2dSDavid Somayajulu event_log_dma); 894afaf5a2dSDavid Somayajulu } 895afaf5a2dSDavid Somayajulu 896afaf5a2dSDavid Somayajulu /** 89709a0f719SVikas Chaudhary * qla4xxx_abort_task - issues Abort Task 89809a0f719SVikas Chaudhary * @ha: Pointer to host adapter structure. 89909a0f719SVikas Chaudhary * @srb: Pointer to srb entry 90009a0f719SVikas Chaudhary * 90109a0f719SVikas Chaudhary * This routine performs a LUN RESET on the specified target/lun. 90209a0f719SVikas Chaudhary * The caller must ensure that the ddb_entry and lun_entry pointers 90309a0f719SVikas Chaudhary * are valid before calling this routine. 90409a0f719SVikas Chaudhary **/ 90509a0f719SVikas Chaudhary int qla4xxx_abort_task(struct scsi_qla_host *ha, struct srb *srb) 90609a0f719SVikas Chaudhary { 90709a0f719SVikas Chaudhary uint32_t mbox_cmd[MBOX_REG_COUNT]; 90809a0f719SVikas Chaudhary uint32_t mbox_sts[MBOX_REG_COUNT]; 90909a0f719SVikas Chaudhary struct scsi_cmnd *cmd = srb->cmd; 91009a0f719SVikas Chaudhary int status = QLA_SUCCESS; 91109a0f719SVikas Chaudhary unsigned long flags = 0; 91209a0f719SVikas Chaudhary uint32_t index; 91309a0f719SVikas Chaudhary 91409a0f719SVikas Chaudhary /* 91509a0f719SVikas Chaudhary * Send abort task command to ISP, so that the ISP will return 91609a0f719SVikas Chaudhary * request with ABORT status 91709a0f719SVikas Chaudhary */ 91809a0f719SVikas Chaudhary memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 91909a0f719SVikas Chaudhary memset(&mbox_sts, 0, sizeof(mbox_sts)); 92009a0f719SVikas Chaudhary 92109a0f719SVikas Chaudhary spin_lock_irqsave(&ha->hardware_lock, flags); 92209a0f719SVikas Chaudhary index = (unsigned long)(unsigned char *)cmd->host_scribble; 92309a0f719SVikas Chaudhary spin_unlock_irqrestore(&ha->hardware_lock, flags); 92409a0f719SVikas Chaudhary 92509a0f719SVikas Chaudhary /* Firmware already posted completion on response queue */ 92609a0f719SVikas Chaudhary if (index == MAX_SRBS) 92709a0f719SVikas Chaudhary return status; 92809a0f719SVikas Chaudhary 92909a0f719SVikas Chaudhary mbox_cmd[0] = MBOX_CMD_ABORT_TASK; 9306790d4feSKaren Higgins mbox_cmd[1] = srb->ddb->fw_ddb_index; 93109a0f719SVikas Chaudhary mbox_cmd[2] = index; 93209a0f719SVikas Chaudhary /* Immediate Command Enable */ 93309a0f719SVikas Chaudhary mbox_cmd[5] = 0x01; 93409a0f719SVikas Chaudhary 93509a0f719SVikas Chaudhary qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], 93609a0f719SVikas Chaudhary &mbox_sts[0]); 93709a0f719SVikas Chaudhary if (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE) { 93809a0f719SVikas Chaudhary status = QLA_ERROR; 93909a0f719SVikas Chaudhary 94009a0f719SVikas Chaudhary DEBUG2(printk(KERN_WARNING "scsi%ld:%d:%d: abort task FAILED: " 94109a0f719SVikas Chaudhary "mbx0=%04X, mb1=%04X, mb2=%04X, mb3=%04X, mb4=%04X\n", 94209a0f719SVikas Chaudhary ha->host_no, cmd->device->id, cmd->device->lun, mbox_sts[0], 94309a0f719SVikas Chaudhary mbox_sts[1], mbox_sts[2], mbox_sts[3], mbox_sts[4])); 94409a0f719SVikas Chaudhary } 94509a0f719SVikas Chaudhary 94609a0f719SVikas Chaudhary return status; 94709a0f719SVikas Chaudhary } 94809a0f719SVikas Chaudhary 94909a0f719SVikas Chaudhary /** 950afaf5a2dSDavid Somayajulu * qla4xxx_reset_lun - issues LUN Reset 951afaf5a2dSDavid Somayajulu * @ha: Pointer to host adapter structure. 952f4f5df23SVikas Chaudhary * @ddb_entry: Pointer to device database entry 953f4f5df23SVikas Chaudhary * @lun: lun number 954afaf5a2dSDavid Somayajulu * 955afaf5a2dSDavid Somayajulu * This routine performs a LUN RESET on the specified target/lun. 956afaf5a2dSDavid Somayajulu * The caller must ensure that the ddb_entry and lun_entry pointers 957afaf5a2dSDavid Somayajulu * are valid before calling this routine. 958afaf5a2dSDavid Somayajulu **/ 959afaf5a2dSDavid Somayajulu int qla4xxx_reset_lun(struct scsi_qla_host * ha, struct ddb_entry * ddb_entry, 960afaf5a2dSDavid Somayajulu int lun) 961afaf5a2dSDavid Somayajulu { 962afaf5a2dSDavid Somayajulu uint32_t mbox_cmd[MBOX_REG_COUNT]; 963afaf5a2dSDavid Somayajulu uint32_t mbox_sts[MBOX_REG_COUNT]; 964afaf5a2dSDavid Somayajulu int status = QLA_SUCCESS; 965afaf5a2dSDavid Somayajulu 966afaf5a2dSDavid Somayajulu DEBUG2(printk("scsi%ld:%d:%d: lun reset issued\n", ha->host_no, 967f4f5df23SVikas Chaudhary ddb_entry->fw_ddb_index, lun)); 968afaf5a2dSDavid Somayajulu 969afaf5a2dSDavid Somayajulu /* 970afaf5a2dSDavid Somayajulu * Send lun reset command to ISP, so that the ISP will return all 971afaf5a2dSDavid Somayajulu * outstanding requests with RESET status 972afaf5a2dSDavid Somayajulu */ 973afaf5a2dSDavid Somayajulu memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 974afaf5a2dSDavid Somayajulu memset(&mbox_sts, 0, sizeof(mbox_sts)); 975c0e344c9SDavid C Somayajulu 976afaf5a2dSDavid Somayajulu mbox_cmd[0] = MBOX_CMD_LUN_RESET; 977afaf5a2dSDavid Somayajulu mbox_cmd[1] = ddb_entry->fw_ddb_index; 978afaf5a2dSDavid Somayajulu mbox_cmd[2] = lun << 8; 979afaf5a2dSDavid Somayajulu mbox_cmd[5] = 0x01; /* Immediate Command Enable */ 980c0e344c9SDavid C Somayajulu 981c0e344c9SDavid C Somayajulu qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]); 982afaf5a2dSDavid Somayajulu if (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE && 983afaf5a2dSDavid Somayajulu mbox_sts[0] != MBOX_STS_COMMAND_ERROR) 984afaf5a2dSDavid Somayajulu status = QLA_ERROR; 985afaf5a2dSDavid Somayajulu 986afaf5a2dSDavid Somayajulu return status; 987afaf5a2dSDavid Somayajulu } 988afaf5a2dSDavid Somayajulu 989ce545039SMike Christie /** 990ce545039SMike Christie * qla4xxx_reset_target - issues target Reset 991ce545039SMike Christie * @ha: Pointer to host adapter structure. 992ce545039SMike Christie * @db_entry: Pointer to device database entry 993ce545039SMike Christie * @un_entry: Pointer to lun entry structure 994ce545039SMike Christie * 995ce545039SMike Christie * This routine performs a TARGET RESET on the specified target. 996ce545039SMike Christie * The caller must ensure that the ddb_entry pointers 997ce545039SMike Christie * are valid before calling this routine. 998ce545039SMike Christie **/ 999ce545039SMike Christie int qla4xxx_reset_target(struct scsi_qla_host *ha, 1000ce545039SMike Christie struct ddb_entry *ddb_entry) 1001ce545039SMike Christie { 1002ce545039SMike Christie uint32_t mbox_cmd[MBOX_REG_COUNT]; 1003ce545039SMike Christie uint32_t mbox_sts[MBOX_REG_COUNT]; 1004ce545039SMike Christie int status = QLA_SUCCESS; 1005ce545039SMike Christie 1006ce545039SMike Christie DEBUG2(printk("scsi%ld:%d: target reset issued\n", ha->host_no, 1007f4f5df23SVikas Chaudhary ddb_entry->fw_ddb_index)); 1008ce545039SMike Christie 1009ce545039SMike Christie /* 1010ce545039SMike Christie * Send target reset command to ISP, so that the ISP will return all 1011ce545039SMike Christie * outstanding requests with RESET status 1012ce545039SMike Christie */ 1013ce545039SMike Christie memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 1014ce545039SMike Christie memset(&mbox_sts, 0, sizeof(mbox_sts)); 1015ce545039SMike Christie 1016ce545039SMike Christie mbox_cmd[0] = MBOX_CMD_TARGET_WARM_RESET; 1017ce545039SMike Christie mbox_cmd[1] = ddb_entry->fw_ddb_index; 1018ce545039SMike Christie mbox_cmd[5] = 0x01; /* Immediate Command Enable */ 1019ce545039SMike Christie 1020ce545039SMike Christie qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], 1021ce545039SMike Christie &mbox_sts[0]); 1022ce545039SMike Christie if (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE && 1023ce545039SMike Christie mbox_sts[0] != MBOX_STS_COMMAND_ERROR) 1024ce545039SMike Christie status = QLA_ERROR; 1025ce545039SMike Christie 1026ce545039SMike Christie return status; 1027ce545039SMike Christie } 1028afaf5a2dSDavid Somayajulu 1029afaf5a2dSDavid Somayajulu int qla4xxx_get_flash(struct scsi_qla_host * ha, dma_addr_t dma_addr, 1030afaf5a2dSDavid Somayajulu uint32_t offset, uint32_t len) 1031afaf5a2dSDavid Somayajulu { 1032afaf5a2dSDavid Somayajulu uint32_t mbox_cmd[MBOX_REG_COUNT]; 1033afaf5a2dSDavid Somayajulu uint32_t mbox_sts[MBOX_REG_COUNT]; 1034afaf5a2dSDavid Somayajulu 1035afaf5a2dSDavid Somayajulu memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 1036afaf5a2dSDavid Somayajulu memset(&mbox_sts, 0, sizeof(mbox_sts)); 1037c0e344c9SDavid C Somayajulu 1038afaf5a2dSDavid Somayajulu mbox_cmd[0] = MBOX_CMD_READ_FLASH; 1039afaf5a2dSDavid Somayajulu mbox_cmd[1] = LSDW(dma_addr); 1040afaf5a2dSDavid Somayajulu mbox_cmd[2] = MSDW(dma_addr); 1041afaf5a2dSDavid Somayajulu mbox_cmd[3] = offset; 1042afaf5a2dSDavid Somayajulu mbox_cmd[4] = len; 1043c0e344c9SDavid C Somayajulu 1044c0e344c9SDavid C Somayajulu if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 2, &mbox_cmd[0], &mbox_sts[0]) != 1045afaf5a2dSDavid Somayajulu QLA_SUCCESS) { 1046afaf5a2dSDavid Somayajulu DEBUG2(printk("scsi%ld: %s: MBOX_CMD_READ_FLASH, failed w/ " 1047afaf5a2dSDavid Somayajulu "status %04X %04X, offset %08x, len %08x\n", ha->host_no, 1048afaf5a2dSDavid Somayajulu __func__, mbox_sts[0], mbox_sts[1], offset, len)); 1049afaf5a2dSDavid Somayajulu return QLA_ERROR; 1050afaf5a2dSDavid Somayajulu } 1051afaf5a2dSDavid Somayajulu return QLA_SUCCESS; 1052afaf5a2dSDavid Somayajulu } 1053afaf5a2dSDavid Somayajulu 1054afaf5a2dSDavid Somayajulu /** 1055afaf5a2dSDavid Somayajulu * qla4xxx_get_fw_version - gets firmware version 1056afaf5a2dSDavid Somayajulu * @ha: Pointer to host adapter structure. 1057afaf5a2dSDavid Somayajulu * 1058afaf5a2dSDavid Somayajulu * Retrieves the firmware version on HBA. In QLA4010, mailboxes 2 & 3 may 1059afaf5a2dSDavid Somayajulu * hold an address for data. Make sure that we write 0 to those mailboxes, 1060afaf5a2dSDavid Somayajulu * if unused. 1061afaf5a2dSDavid Somayajulu **/ 1062afaf5a2dSDavid Somayajulu int qla4xxx_get_fw_version(struct scsi_qla_host * ha) 1063afaf5a2dSDavid Somayajulu { 1064afaf5a2dSDavid Somayajulu uint32_t mbox_cmd[MBOX_REG_COUNT]; 1065afaf5a2dSDavid Somayajulu uint32_t mbox_sts[MBOX_REG_COUNT]; 1066afaf5a2dSDavid Somayajulu 1067afaf5a2dSDavid Somayajulu /* Get firmware version. */ 1068afaf5a2dSDavid Somayajulu memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 1069afaf5a2dSDavid Somayajulu memset(&mbox_sts, 0, sizeof(mbox_sts)); 1070c0e344c9SDavid C Somayajulu 1071afaf5a2dSDavid Somayajulu mbox_cmd[0] = MBOX_CMD_ABOUT_FW; 1072c0e344c9SDavid C Somayajulu 1073c0e344c9SDavid C Somayajulu if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) != 1074afaf5a2dSDavid Somayajulu QLA_SUCCESS) { 1075afaf5a2dSDavid Somayajulu DEBUG2(printk("scsi%ld: %s: MBOX_CMD_ABOUT_FW failed w/ " 1076afaf5a2dSDavid Somayajulu "status %04X\n", ha->host_no, __func__, mbox_sts[0])); 1077afaf5a2dSDavid Somayajulu return QLA_ERROR; 1078afaf5a2dSDavid Somayajulu } 1079afaf5a2dSDavid Somayajulu 1080afaf5a2dSDavid Somayajulu /* Save firmware version information. */ 1081afaf5a2dSDavid Somayajulu ha->firmware_version[0] = mbox_sts[1]; 1082afaf5a2dSDavid Somayajulu ha->firmware_version[1] = mbox_sts[2]; 1083afaf5a2dSDavid Somayajulu ha->patch_number = mbox_sts[3]; 1084afaf5a2dSDavid Somayajulu ha->build_number = mbox_sts[4]; 1085afaf5a2dSDavid Somayajulu 1086afaf5a2dSDavid Somayajulu return QLA_SUCCESS; 1087afaf5a2dSDavid Somayajulu } 1088afaf5a2dSDavid Somayajulu 108947975477SAdrian Bunk static int qla4xxx_get_default_ddb(struct scsi_qla_host *ha, 109047975477SAdrian Bunk dma_addr_t dma_addr) 1091afaf5a2dSDavid Somayajulu { 1092afaf5a2dSDavid Somayajulu uint32_t mbox_cmd[MBOX_REG_COUNT]; 1093afaf5a2dSDavid Somayajulu uint32_t mbox_sts[MBOX_REG_COUNT]; 1094afaf5a2dSDavid Somayajulu 1095afaf5a2dSDavid Somayajulu memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 1096afaf5a2dSDavid Somayajulu memset(&mbox_sts, 0, sizeof(mbox_sts)); 1097afaf5a2dSDavid Somayajulu 1098afaf5a2dSDavid Somayajulu mbox_cmd[0] = MBOX_CMD_GET_DATABASE_ENTRY_DEFAULTS; 1099afaf5a2dSDavid Somayajulu mbox_cmd[2] = LSDW(dma_addr); 1100afaf5a2dSDavid Somayajulu mbox_cmd[3] = MSDW(dma_addr); 1101afaf5a2dSDavid Somayajulu 1102c0e344c9SDavid C Somayajulu if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]) != 1103afaf5a2dSDavid Somayajulu QLA_SUCCESS) { 1104afaf5a2dSDavid Somayajulu DEBUG2(printk("scsi%ld: %s: failed status %04X\n", 1105afaf5a2dSDavid Somayajulu ha->host_no, __func__, mbox_sts[0])); 1106afaf5a2dSDavid Somayajulu return QLA_ERROR; 1107afaf5a2dSDavid Somayajulu } 1108afaf5a2dSDavid Somayajulu return QLA_SUCCESS; 1109afaf5a2dSDavid Somayajulu } 1110afaf5a2dSDavid Somayajulu 111147975477SAdrian Bunk static int qla4xxx_req_ddb_entry(struct scsi_qla_host *ha, uint32_t *ddb_index) 1112afaf5a2dSDavid Somayajulu { 1113afaf5a2dSDavid Somayajulu uint32_t mbox_cmd[MBOX_REG_COUNT]; 1114afaf5a2dSDavid Somayajulu uint32_t mbox_sts[MBOX_REG_COUNT]; 1115afaf5a2dSDavid Somayajulu 1116afaf5a2dSDavid Somayajulu memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 1117afaf5a2dSDavid Somayajulu memset(&mbox_sts, 0, sizeof(mbox_sts)); 1118afaf5a2dSDavid Somayajulu 1119afaf5a2dSDavid Somayajulu mbox_cmd[0] = MBOX_CMD_REQUEST_DATABASE_ENTRY; 1120afaf5a2dSDavid Somayajulu mbox_cmd[1] = MAX_PRST_DEV_DB_ENTRIES; 1121afaf5a2dSDavid Somayajulu 1122c0e344c9SDavid C Somayajulu if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 3, &mbox_cmd[0], &mbox_sts[0]) != 1123afaf5a2dSDavid Somayajulu QLA_SUCCESS) { 1124afaf5a2dSDavid Somayajulu if (mbox_sts[0] == MBOX_STS_COMMAND_ERROR) { 1125afaf5a2dSDavid Somayajulu *ddb_index = mbox_sts[2]; 1126afaf5a2dSDavid Somayajulu } else { 1127afaf5a2dSDavid Somayajulu DEBUG2(printk("scsi%ld: %s: failed status %04X\n", 1128afaf5a2dSDavid Somayajulu ha->host_no, __func__, mbox_sts[0])); 1129afaf5a2dSDavid Somayajulu return QLA_ERROR; 1130afaf5a2dSDavid Somayajulu } 1131afaf5a2dSDavid Somayajulu } else { 1132afaf5a2dSDavid Somayajulu *ddb_index = MAX_PRST_DEV_DB_ENTRIES; 1133afaf5a2dSDavid Somayajulu } 1134afaf5a2dSDavid Somayajulu 1135afaf5a2dSDavid Somayajulu return QLA_SUCCESS; 1136afaf5a2dSDavid Somayajulu } 1137afaf5a2dSDavid Somayajulu 1138afaf5a2dSDavid Somayajulu 1139afaf5a2dSDavid Somayajulu int qla4xxx_send_tgts(struct scsi_qla_host *ha, char *ip, uint16_t port) 1140afaf5a2dSDavid Somayajulu { 1141afaf5a2dSDavid Somayajulu struct dev_db_entry *fw_ddb_entry; 1142afaf5a2dSDavid Somayajulu dma_addr_t fw_ddb_entry_dma; 1143afaf5a2dSDavid Somayajulu uint32_t ddb_index; 1144afaf5a2dSDavid Somayajulu int ret_val = QLA_SUCCESS; 1145afaf5a2dSDavid Somayajulu 1146afaf5a2dSDavid Somayajulu 1147afaf5a2dSDavid Somayajulu fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, 1148afaf5a2dSDavid Somayajulu sizeof(*fw_ddb_entry), 1149afaf5a2dSDavid Somayajulu &fw_ddb_entry_dma, GFP_KERNEL); 1150afaf5a2dSDavid Somayajulu if (!fw_ddb_entry) { 1151afaf5a2dSDavid Somayajulu DEBUG2(printk("scsi%ld: %s: Unable to allocate dma buffer.\n", 1152afaf5a2dSDavid Somayajulu ha->host_no, __func__)); 1153afaf5a2dSDavid Somayajulu ret_val = QLA_ERROR; 1154beabe7c1SPrasanna Mumbai goto exit_send_tgts_no_free; 1155afaf5a2dSDavid Somayajulu } 1156afaf5a2dSDavid Somayajulu 1157afaf5a2dSDavid Somayajulu ret_val = qla4xxx_get_default_ddb(ha, fw_ddb_entry_dma); 1158afaf5a2dSDavid Somayajulu if (ret_val != QLA_SUCCESS) 1159beabe7c1SPrasanna Mumbai goto exit_send_tgts; 1160afaf5a2dSDavid Somayajulu 1161afaf5a2dSDavid Somayajulu ret_val = qla4xxx_req_ddb_entry(ha, &ddb_index); 1162afaf5a2dSDavid Somayajulu if (ret_val != QLA_SUCCESS) 1163beabe7c1SPrasanna Mumbai goto exit_send_tgts; 1164afaf5a2dSDavid Somayajulu 1165c0e344c9SDavid C Somayajulu memset(fw_ddb_entry->iscsi_alias, 0, 1166c0e344c9SDavid C Somayajulu sizeof(fw_ddb_entry->iscsi_alias)); 1167afaf5a2dSDavid Somayajulu 1168c0e344c9SDavid C Somayajulu memset(fw_ddb_entry->iscsi_name, 0, 1169c0e344c9SDavid C Somayajulu sizeof(fw_ddb_entry->iscsi_name)); 1170afaf5a2dSDavid Somayajulu 1171c0e344c9SDavid C Somayajulu memset(fw_ddb_entry->ip_addr, 0, sizeof(fw_ddb_entry->ip_addr)); 1172c0e344c9SDavid C Somayajulu memset(fw_ddb_entry->tgt_addr, 0, 1173c0e344c9SDavid C Somayajulu sizeof(fw_ddb_entry->tgt_addr)); 1174afaf5a2dSDavid Somayajulu 1175afaf5a2dSDavid Somayajulu fw_ddb_entry->options = (DDB_OPT_DISC_SESSION | DDB_OPT_TARGET); 1176c0e344c9SDavid C Somayajulu fw_ddb_entry->port = cpu_to_le16(ntohs(port)); 1177afaf5a2dSDavid Somayajulu 1178c0e344c9SDavid C Somayajulu fw_ddb_entry->ip_addr[0] = *ip; 1179c0e344c9SDavid C Somayajulu fw_ddb_entry->ip_addr[1] = *(ip + 1); 1180c0e344c9SDavid C Somayajulu fw_ddb_entry->ip_addr[2] = *(ip + 2); 1181c0e344c9SDavid C Somayajulu fw_ddb_entry->ip_addr[3] = *(ip + 3); 1182afaf5a2dSDavid Somayajulu 1183afaf5a2dSDavid Somayajulu ret_val = qla4xxx_set_ddb_entry(ha, ddb_index, fw_ddb_entry_dma); 1184afaf5a2dSDavid Somayajulu 1185beabe7c1SPrasanna Mumbai exit_send_tgts: 1186afaf5a2dSDavid Somayajulu dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), 1187afaf5a2dSDavid Somayajulu fw_ddb_entry, fw_ddb_entry_dma); 1188beabe7c1SPrasanna Mumbai exit_send_tgts_no_free: 1189afaf5a2dSDavid Somayajulu return ret_val; 1190afaf5a2dSDavid Somayajulu } 1191afaf5a2dSDavid Somayajulu 1192