/* Get the function number */
spin_lock_irqsave(&ha->hardware_lock, flags);
value = readw(&ha->reg->ctrl_status);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
/** * qla4xxx_init_rings - initialize hw queues * @ha: pointer to host adapter structure. * * This routine initializes the internal queues for the specified adapter. * The QLA4010 requires us to restart the queues at index 0. * The QLA4000 doesn't care, so just default to QLA4010's requirement.
**/ int qla4xxx_init_rings(struct scsi_qla_host *ha)
{ unsignedlong flags = 0; int i;
if (is_qla8022(ha)) {
writel(0,
(unsignedlong __iomem *)&ha->qla4_82xx_reg->req_q_out);
writel(0,
(unsignedlong __iomem *)&ha->qla4_82xx_reg->rsp_q_in);
writel(0,
(unsignedlong __iomem *)&ha->qla4_82xx_reg->rsp_q_out);
} elseif (is_qla8032(ha) || is_qla8042(ha)) {
writel(0,
(unsignedlong __iomem *)&ha->qla4_83xx_reg->req_q_in);
writel(0,
(unsignedlong __iomem *)&ha->qla4_83xx_reg->rsp_q_in);
writel(0,
(unsignedlong __iomem *)&ha->qla4_83xx_reg->rsp_q_out);
} else { /* * Initialize DMA Shadow registers. The firmware is really * supposed to take care of this, but on some uniprocessor * systems, the shadow registers aren't cleared-- causing * the interrupt_handler to think there are responses to be * processed when there aren't.
*/
ha->shadow_regs->req_q_out = cpu_to_le32(0);
ha->shadow_regs->rsp_q_in = cpu_to_le32(0);
wmb();
/* If both IPv4 & IPv6 are enabled, possibly only one * IP address may be acquired, so check to see if we
* need to wait for another */ if (is_ipv4_enabled(ha) && is_ipv6_enabled(ha)) { if (((ha->addl_fw_state & FW_ADDSTATE_DHCPv4_ENABLED) != 0) &&
((ha->addl_fw_state &
FW_ADDSTATE_DHCPv4_LEASE_ACQUIRED) == 0)) {
ipv4_wait = 1;
} if (((ha->ip_config.ipv6_addl_options &
IPV6_ADDOPT_NEIGHBOR_DISCOVERY_ADDR_ENABLE) != 0) &&
((ha->ip_config.ipv6_link_local_state ==
IP_ADDRSTATE_ACQUIRING) ||
(ha->ip_config.ipv6_addr0_state ==
IP_ADDRSTATE_ACQUIRING) ||
(ha->ip_config.ipv6_addr1_state ==
IP_ADDRSTATE_ACQUIRING))) {
if (!(le32_to_cpu(*cap_offset) & BIT_0)) {
ql4_printk(KERN_INFO, ha, "PEX DMA Not supported %d\n",
*cap_offset);
rval = 0;
}
return rval;
}
/** * qla4xxx_alloc_fw_dump - Allocate memory for minidump data. * @ha: pointer to host adapter structure.
**/ void qla4xxx_alloc_fw_dump(struct scsi_qla_host *ha)
{ int status;
uint32_t capture_debug_level; int hdr_entry_bit, k; void *md_tmp;
dma_addr_t md_tmp_dma; struct qla4_8xxx_minidump_template_hdr *md_hdr; int dma_capable;
if (ha->fw_dump) {
ql4_printk(KERN_WARNING, ha, "Firmware dump previously allocated.\n"); return;
}
status = qla4xxx_req_template_size(ha); if (status != QLA_SUCCESS) {
ql4_printk(KERN_INFO, ha, "scsi%ld: Failed to get template size\n",
ha->host_no); return;
}
clear_bit(AF_82XX_FW_DUMPED, &ha->flags);
/* Allocate memory for saving the template */
md_tmp = dma_alloc_coherent(&ha->pdev->dev, ha->fw_dump_tmplt_size,
&md_tmp_dma, GFP_KERNEL); if (!md_tmp) {
ql4_printk(KERN_INFO, ha, "scsi%ld: Failed to allocate DMA memory\n",
ha->host_no); return;
}
/* Request template */
status = qla4xxx_get_minidump_template(ha, md_tmp_dma); if (status != QLA_SUCCESS) {
ql4_printk(KERN_INFO, ha, "scsi%ld: Failed to get minidump template\n",
ha->host_no); goto alloc_cleanup;
}
/* Get capture mask based on module loadtime setting. */ if ((ql4xmdcapmask >= 0x3 && ql4xmdcapmask <= 0x7F) ||
(ql4xmdcapmask == 0xFF && dma_capable)) {
ha->fw_dump_capture_mask = ql4xmdcapmask;
} else { if (ql4xmdcapmask == 0xFF)
ql4_printk(KERN_INFO, ha, "Falling back to default capture mask, as PEX DMA is not supported\n");
ha->fw_dump_capture_mask = capture_debug_level;
}
DEBUG2(ql4_printk(KERN_INFO, ha, "Minimum num of entries = %d\n",
md_hdr->num_of_entries));
DEBUG2(ql4_printk(KERN_INFO, ha, "Dump template size = %d\n",
ha->fw_dump_tmplt_size));
DEBUG2(ql4_printk(KERN_INFO, ha, "Selected Capture mask =0x%x\n",
ha->fw_dump_capture_mask));
/* Calculate fw_dump_size */ for (hdr_entry_bit = 0x2, k = 1; (hdr_entry_bit & 0xFF);
hdr_entry_bit <<= 1, k++) { if (hdr_entry_bit & ha->fw_dump_capture_mask)
ha->fw_dump_size += md_hdr->capture_size_array[k];
}
/* Total firmware dump size including command header */
ha->fw_dump_size += ha->fw_dump_tmplt_size;
ha->fw_dump = vmalloc(ha->fw_dump_size); if (!ha->fw_dump) goto alloc_cleanup;
DEBUG2(ql4_printk(KERN_INFO, ha, "Minidump Template Size = 0x%x KB\n",
ha->fw_dump_tmplt_size));
DEBUG2(ql4_printk(KERN_INFO, ha, "Total Minidump size = 0x%x KB\n", ha->fw_dump_size));
DEBUG2(ql4_printk(KERN_INFO, ha, "Waiting for Firmware Ready..\n")); for (timeout_count = ADAPTER_INIT_TOV; timeout_count > 0;
timeout_count--) { if (test_and_clear_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags))
qla4xxx_get_dhcp_ip_address(ha);
/* Get firmware state. */ if (qla4xxx_get_firmware_state(ha) != QLA_SUCCESS) {
DEBUG2(printk("scsi%ld: %s: unable to get firmware " "state\n", ha->host_no, __func__)); break;
}
if (ha->firmware_state & FW_STATE_ERROR) {
DEBUG2(printk("scsi%ld: %s: an unrecoverable error has" " occurred\n", ha->host_no, __func__)); break;
} if (ha->firmware_state & FW_STATE_CONFIG_WAIT) { /* * The firmware has not yet been issued an Initialize * Firmware command, so issue it now.
*/ if (qla4xxx_initialize_fw_cb(ha) == QLA_ERROR) break;
/* Go back and test for ready state - no wait. */ continue;
}
if (ha->firmware_state & FW_STATE_WAIT_AUTOCONNECT) {
DEBUG2(printk(KERN_INFO "scsi%ld: %s: fwstate:" "AUTOCONNECT in progress\n",
ha->host_no, __func__));
}
if (ha->firmware_state & FW_STATE_CONFIGURING_IP) {
DEBUG2(printk(KERN_INFO "scsi%ld: %s: fwstate:" " CONFIGURING IP\n",
ha->host_no, __func__)); /* * Check for link state after 15 secs and if link is * still DOWN then, cable is unplugged. Ignore "DHCP * in Progress/CONFIGURING IP" bit to check if firmware * is in ready state or not after 15 secs. * This is applicable for both 2.x & 3.x firmware
*/ if (timeout_count <= (ADAPTER_INIT_TOV - 15)) { if (ha->addl_fw_state & FW_ADDSTATE_LINK_UP) {
DEBUG2(printk(KERN_INFO "scsi%ld: %s:" " LINK UP (Cable plugged)\n",
ha->host_no, __func__));
} elseif (ha->firmware_state &
(FW_STATE_CONFIGURING_IP |
FW_STATE_READY)) {
DEBUG2(printk(KERN_INFO "scsi%ld: %s: " "LINK DOWN (Cable unplugged)\n",
ha->host_no, __func__));
ha->firmware_state = FW_STATE_READY;
}
}
}
if (ha->firmware_state == FW_STATE_READY) { /* If DHCP IP Addr is available, retrieve it now. */ if (test_and_clear_bit(DPC_GET_DHCP_IP_ADDR,
&ha->dpc_flags))
qla4xxx_get_dhcp_ip_address(ha);
if (!qla4xxx_wait_for_ip_config(ha) ||
timeout_count == 1) {
DEBUG2(ql4_printk(KERN_INFO, ha, "Firmware Ready..\n")); /* The firmware is ready to process SCSI
commands. */
DEBUG2(ql4_printk(KERN_INFO, ha, "scsi%ld: %s: MEDIA TYPE" " - %s\n", ha->host_no,
__func__, (ha->addl_fw_state &
FW_ADDSTATE_OPTICAL_MEDIA)
!= 0 ? "OPTICAL" : "COPPER"));
DEBUG2(ql4_printk(KERN_INFO, ha, "scsi%ld: %s: DHCPv4 STATE" " Enabled %s\n", ha->host_no,
__func__, (ha->addl_fw_state &
FW_ADDSTATE_DHCPv4_ENABLED) != 0 ? "YES" : "NO"));
DEBUG2(ql4_printk(KERN_INFO, ha, "scsi%ld: %s: LINK %s\n",
ha->host_no, __func__,
(ha->addl_fw_state &
FW_ADDSTATE_LINK_UP) != 0 ? "UP" : "DOWN"));
DEBUG2(ql4_printk(KERN_INFO, ha, "scsi%ld: %s: iSNS Service " "Started %s\n",
ha->host_no, __func__,
(ha->addl_fw_state &
FW_ADDSTATE_ISNS_SVC_ENABLED) != 0 ? "YES" : "NO"));
if (ha->firmware_state & FW_STATE_CONFIGURING_IP) {
DEBUG2(printk("scsi%ld: %s: FW initialized, but is reporting " "it's waiting to configure an IP address\n",
ha->host_no, __func__));
ready = 1;
} elseif (ha->firmware_state & FW_STATE_WAIT_AUTOCONNECT) {
DEBUG2(printk("scsi%ld: %s: FW initialized, but " "auto-discovery still in process\n",
ha->host_no, __func__));
ready = 1;
}
return ready;
}
/** * qla4xxx_init_firmware - initializes the firmware. * @ha: pointer to host adapter structure. *
**/ staticint qla4xxx_init_firmware(struct scsi_qla_host *ha)
{ int status = QLA_ERROR;
if (is_aer_supported(ha) &&
test_bit(AF_PCI_CHANNEL_IO_PERM_FAILURE, &ha->flags)) return status;
/* For 82xx, stop firmware before initializing because if BIOS * has previously initialized firmware, then driver's initialize
* firmware will fail. */ if (is_qla80XX(ha))
qla4_8xxx_stop_firmware(ha);
ql4_printk(KERN_INFO, ha, "Initializing firmware..\n"); if (qla4xxx_initialize_fw_cb(ha) == QLA_ERROR) {
DEBUG2(printk("scsi%ld: %s: Failed to initialize firmware " "control block\n", ha->host_no, __func__)); return status;
}
if (!qla4xxx_fw_ready(ha)) return status;
if (is_qla80XX(ha) && !test_bit(AF_INIT_DONE, &ha->flags))
qla4xxx_alloc_fw_dump(ha);
return qla4xxx_get_firmware_status(ha);
}
staticvoid qla4xxx_set_model_info(struct scsi_qla_host *ha)
{
uint16_t board_id_string[8]; int i; int size = sizeof(ha->nvram->isp4022.boardIdStr); int offset = offsetof(struct eeprom_data, isp4022.boardIdStr) / 2;
for (i = 0; i < (size / 2) ; i++) {
board_id_string[i] = rd_nvram_word(ha, offset);
offset += 1;
}
memcpy(ha->model_name, board_id_string, size);
}
staticint qla4xxx_config_nvram(struct scsi_qla_host *ha)
{ unsignedlong flags; union external_hw_config_reg extHwConfig;
DEBUG2(printk("scsi%ld: %s: Get EEProm parameters \n", ha->host_no,
__func__)); if (ql4xxx_lock_flash(ha) != QLA_SUCCESS) return QLA_ERROR; if (ql4xxx_lock_nvram(ha) != QLA_SUCCESS) {
ql4xxx_unlock_flash(ha); return QLA_ERROR;
}
/* Get EEPRom Parameters from NVRAM and validate */
ql4_printk(KERN_INFO, ha, "Configuring NVRAM ...\n"); if (qla4xxx_is_nvram_configuration_valid(ha) == QLA_SUCCESS) {
spin_lock_irqsave(&ha->hardware_lock, flags);
extHwConfig.Asuint32_t =
rd_nvram_word(ha, eeprom_ext_hw_conf_offset(ha));
spin_unlock_irqrestore(&ha->hardware_lock, flags);
} else {
ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: EEProm checksum invalid. " "Please update your EEPROM\n", ha->host_no,
__func__);
/* Attempt to set defaults */ if (is_qla4010(ha))
extHwConfig.Asuint32_t = 0x1912; elseif (is_qla4022(ha) | is_qla4032(ha))
extHwConfig.Asuint32_t = 0x0023; else return QLA_ERROR;
}
if (is_qla4022(ha) || is_qla4032(ha))
qla4xxx_set_model_info(ha); else
strcpy(ha->model_name, "QLA4010");
DEBUG(printk("scsi%ld: %s: Setting extHwConfig to 0xFFFF%04x\n",
ha->host_no, __func__, extHwConfig.Asuint32_t));
void qla4xxx_pci_config(struct scsi_qla_host *ha)
{
uint16_t w; int status;
ql4_printk(KERN_INFO, ha, "Configuring PCI space...\n");
pci_set_master(ha->pdev);
status = pci_set_mwi(ha->pdev); if (status)
ql4_printk(KERN_WARNING, ha, "Failed to set MWI\n");
/* * We want to respect framework's setting of PCI configuration space * command register and also want to make sure that all bits of * interest to us are properly set in command register.
*/
pci_read_config_word(ha->pdev, PCI_COMMAND, &w);
w |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
w &= ~PCI_COMMAND_INTX_DISABLE;
pci_write_config_word(ha->pdev, PCI_COMMAND, w);
}
staticint qla4xxx_start_firmware_from_flash(struct scsi_qla_host *ha)
{ int status = QLA_ERROR; unsignedlong max_wait_time; unsignedlong flags;
uint32_t mbox_status;
ql4_printk(KERN_INFO, ha, "Starting firmware ...\n");
/* * Start firmware from flash ROM * * WORKAROUND: Stuff a non-constant value that the firmware can * use as a seed for a random number generator in MB7 prior to * setting BOOT_ENABLE. Fixes problem where the TCP * connections use the same TCP ports after each reboot, * causing some connections to not get re-established.
*/
DEBUG(printk("scsi%d: %s: Start firmware from flash ROM\n",
ha->host_no, __func__));
spin_lock_irqsave(&ha->hardware_lock, flags);
writel(jiffies, &ha->reg->mailbox[7]); if (is_qla4022(ha) | is_qla4032(ha))
writel(set_rmask(NVR_WRITE_ENABLE),
&ha->reg->u1.isp4022.nvram);
/* Wait for firmware to come UP. */
DEBUG2(printk(KERN_INFO "scsi%ld: %s: Wait up to %d seconds for " "boot firmware to complete...\n",
ha->host_no, __func__, FIRMWARE_UP_TOV));
max_wait_time = jiffies + (FIRMWARE_UP_TOV * HZ); do {
uint32_t ctrl_status;
int drvr_wait = QL4_LOCK_DRVR_WAIT; while (drvr_wait) { if (ql4xxx_lock_drvr(a) == 0) {
ssleep(QL4_LOCK_DRVR_SLEEP);
DEBUG2(printk("scsi%ld: %s: Waiting for " "Global Init Semaphore(%d)...\n",
a->host_no,
__func__, drvr_wait));
drvr_wait -= QL4_LOCK_DRVR_SLEEP;
} else {
DEBUG2(printk("scsi%ld: %s: Global Init Semaphore " "acquired\n", a->host_no, __func__)); return QLA_SUCCESS;
}
} return QLA_ERROR;
}
/** * qla4xxx_start_firmware - starts qla4xxx firmware * @ha: Pointer to host adapter structure. * * This routine performs the necessary steps to start the firmware for * the QLA4010 adapter.
**/ int qla4xxx_start_firmware(struct scsi_qla_host *ha)
{ unsignedlong flags = 0;
uint32_t mbox_status; int status = QLA_ERROR; int soft_reset = 1; int config_chip = 0;
if (is_qla4022(ha) | is_qla4032(ha))
ql4xxx_set_mac_number(ha);
if (ql4xxx_lock_drvr_wait(ha) != QLA_SUCCESS) return QLA_ERROR;
/* Reset clears the semaphore, so acquire again */ if (ql4xxx_lock_drvr_wait(ha) != QLA_SUCCESS) return QLA_ERROR;
}
if (config_chip) { if ((status = qla4xxx_config_nvram(ha)) == QLA_SUCCESS)
status = qla4xxx_start_firmware_from_flash(ha);
}
ql4xxx_unlock_drvr(ha); if (status == QLA_SUCCESS) { if (test_and_clear_bit(AF_GET_CRASH_RECORD, &ha->flags))
qla4xxx_get_crash_record(ha);
qla4xxx_init_rings(ha);
} else {
DEBUG(printk("scsi%ld: %s: Firmware has NOT started\n",
ha->host_no, __func__));
} return status;
} /** * qla4xxx_free_ddb_index - Free DDBs reserved by firmware * @ha: pointer to adapter structure * * Since firmware is not running in autoconnect mode the DDB indices should * be freed so that when login happens from user space there are free DDB * indices available.
**/ void qla4xxx_free_ddb_index(struct scsi_qla_host *ha)
{ int max_ddbs; int ret;
uint32_t idx = 0, next_idx = 0;
uint32_t state = 0, conn_err = 0;
for (idx = 0; idx < max_ddbs; idx = next_idx) {
ret = qla4xxx_get_fwddb_entry(ha, idx, NULL, 0, NULL,
&next_idx, &state, &conn_err,
NULL, NULL); if (ret == QLA_ERROR) {
next_idx++; continue;
} if (state == DDB_DS_NO_CONNECTION_ACTIVE ||
state == DDB_DS_SESSION_FAILED) {
DEBUG2(ql4_printk(KERN_INFO, ha, "Freeing DDB index = 0x%x\n", idx));
ret = qla4xxx_clear_ddb_entry(ha, idx); if (ret == QLA_ERROR)
ql4_printk(KERN_ERR, ha, "Unable to clear DDB index = " "0x%x\n", idx);
} if (next_idx == 0) break;
}
}
/** * qla4xxx_initialize_adapter - initiailizes hba * @ha: Pointer to host adapter structure. * @is_reset: Is this init path or reset path * * This routine parforms all of the steps necessary to initialize the adapter. *
**/ int qla4xxx_initialize_adapter(struct scsi_qla_host *ha, int is_reset)
{ int status = QLA_ERROR;
ha->eeprom_cmd_data = 0;
ql4_printk(KERN_INFO, ha, "Configuring PCI space...\n");
ha->isp_ops->pci_config(ha);
ha->isp_ops->disable_intrs(ha);
/* Initialize the Host adapter request/response queues and firmware */ if (ha->isp_ops->start_firmware(ha) == QLA_ERROR) goto exit_init_hba;
/* * For ISP83XX, mailbox and IOCB interrupts are enabled separately. * Mailbox interrupts must be enabled prior to issuing any mailbox * command in order to prevent the possibility of losing interrupts * while switching from polling to interrupt mode. IOCB interrupts are * enabled via isp_ops->enable_intrs.
*/ if (is_qla8032(ha) || is_qla8042(ha))
qla4_83xx_enable_mbox_intrs(ha);
if (qla4xxx_about_firmware(ha) == QLA_ERROR) goto exit_init_hba;
if (ha->isp_ops->get_sys_info(ha) == QLA_ERROR) goto exit_init_hba;
qla4xxx_init_local_data(ha);
status = qla4xxx_init_firmware(ha); if (status == QLA_ERROR) goto exit_init_hba;
if (is_reset == RESET_ADAPTER)
qla4xxx_build_ddb_list(ha, is_reset);
int qla4xxx_ddb_change(struct scsi_qla_host *ha, uint32_t fw_ddb_index, struct ddb_entry *ddb_entry, uint32_t state)
{
uint32_t old_fw_ddb_device_state; int status = QLA_ERROR;
old_fw_ddb_device_state = ddb_entry->fw_ddb_device_state;
DEBUG2(ql4_printk(KERN_INFO, ha, "%s: DDB - old state = 0x%x, new state = 0x%x for " "index [%d]\n", __func__,
ddb_entry->fw_ddb_device_state, state, fw_ddb_index));
ddb_entry->fw_ddb_device_state = state;
switch (old_fw_ddb_device_state) { case DDB_DS_LOGIN_IN_PROCESS: switch (state) { case DDB_DS_SESSION_ACTIVE: case DDB_DS_DISCOVERY:
qla4xxx_update_session_conn_param(ha, ddb_entry);
ddb_entry->unblock_sess(ddb_entry->sess);
status = QLA_SUCCESS; break; case DDB_DS_SESSION_FAILED: case DDB_DS_NO_CONNECTION_ACTIVE:
iscsi_conn_login_event(ddb_entry->conn,
ISCSI_CONN_STATE_FREE);
status = QLA_SUCCESS; break;
} break; case DDB_DS_SESSION_ACTIVE: case DDB_DS_DISCOVERY: switch (state) { case DDB_DS_SESSION_FAILED: /* * iscsi_session failure will cause userspace to * stop the connection which in turn would block the * iscsi_session and start relogin
*/
iscsi_session_failure(ddb_entry->sess->dd_data,
ISCSI_ERR_CONN_FAILED);
status = QLA_SUCCESS; break; case DDB_DS_NO_CONNECTION_ACTIVE:
clear_bit(fw_ddb_index, ha->ddb_idx_map);
status = QLA_SUCCESS; break;
} break; case DDB_DS_SESSION_FAILED: switch (state) { case DDB_DS_SESSION_ACTIVE: case DDB_DS_DISCOVERY:
ddb_entry->unblock_sess(ddb_entry->sess);
qla4xxx_update_session_conn_param(ha, ddb_entry);
status = QLA_SUCCESS; break; case DDB_DS_SESSION_FAILED:
iscsi_session_failure(ddb_entry->sess->dd_data,
ISCSI_ERR_CONN_FAILED);
status = QLA_SUCCESS; break;
} break; default:
DEBUG2(ql4_printk(KERN_INFO, ha, "%s: Unknown Event\n",
__func__)); break;
} return status;
}
void qla4xxx_arm_relogin_timer(struct ddb_entry *ddb_entry)
{ /* * This triggers a relogin. After the relogin_timer * expires, the relogin gets scheduled. We must wait a * minimum amount of time since receiving an 0x8014 AEN * with failed device_state or a logout response before * we can issue another relogin. * * Firmware pads this timeout: (time2wait +1). * Driver retry to login should be longer than F/W. * Otherwise F/W will fail * set_ddb() mbx cmd with 0x4005 since it still * counting down its time2wait.
*/
atomic_set(&ddb_entry->relogin_timer, 0);
atomic_set(&ddb_entry->retry_relogin_timer,
ddb_entry->default_time2wait + 4);
}
int qla4xxx_flash_ddb_change(struct scsi_qla_host *ha, uint32_t fw_ddb_index, struct ddb_entry *ddb_entry, uint32_t state)
{
uint32_t old_fw_ddb_device_state; int status = QLA_ERROR;
old_fw_ddb_device_state = ddb_entry->fw_ddb_device_state;
DEBUG2(ql4_printk(KERN_INFO, ha, "%s: DDB - old state = 0x%x, new state = 0x%x for " "index [%d]\n", __func__,
ddb_entry->fw_ddb_device_state, state, fw_ddb_index));
ddb_entry->fw_ddb_device_state = state;
switch (old_fw_ddb_device_state) { case DDB_DS_LOGIN_IN_PROCESS: case DDB_DS_NO_CONNECTION_ACTIVE: switch (state) { case DDB_DS_SESSION_ACTIVE:
ddb_entry->unblock_sess(ddb_entry->sess);
qla4xxx_update_session_conn_fwddb_param(ha, ddb_entry);
status = QLA_SUCCESS; break; case DDB_DS_SESSION_FAILED:
iscsi_block_session(ddb_entry->sess); if (!test_bit(DF_RELOGIN, &ddb_entry->flags))
qla4xxx_arm_relogin_timer(ddb_entry);
status = QLA_SUCCESS; break;
} break; case DDB_DS_SESSION_ACTIVE: switch (state) { case DDB_DS_SESSION_FAILED:
iscsi_block_session(ddb_entry->sess); if (!test_bit(DF_RELOGIN, &ddb_entry->flags))
qla4xxx_arm_relogin_timer(ddb_entry);
status = QLA_SUCCESS; break;
} break; case DDB_DS_SESSION_FAILED: switch (state) { case DDB_DS_SESSION_ACTIVE:
ddb_entry->unblock_sess(ddb_entry->sess);
qla4xxx_update_session_conn_fwddb_param(ha, ddb_entry);
status = QLA_SUCCESS; break; case DDB_DS_SESSION_FAILED: if (!test_bit(DF_RELOGIN, &ddb_entry->flags))
qla4xxx_arm_relogin_timer(ddb_entry);
status = QLA_SUCCESS; break;
} break; default:
DEBUG2(ql4_printk(KERN_INFO, ha, "%s: Unknown Event\n",
__func__)); break;
} return status;
}
/** * qla4xxx_process_ddb_changed - process ddb state change * @ha: Pointer to host adapter structure. * @fw_ddb_index: Firmware's device database index * @state: Device state * @conn_err: Unused * * This routine processes a Decive Database Changed AEN Event.
**/ int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha,
uint32_t fw_ddb_index,
uint32_t state, uint32_t conn_err)
{ struct ddb_entry *ddb_entry;
/* check for out of range index */ if (fw_ddb_index >= MAX_DDB_ENTRIES) goto exit_ddb_event;
/* Get the corresponging ddb entry */
ddb_entry = qla4xxx_lookup_ddb_by_fw_index(ha, fw_ddb_index); /* Device does not currently exist in our database. */ if (ddb_entry == NULL) {
ql4_printk(KERN_ERR, ha, "%s: No ddb_entry at FW index [%d]\n",
__func__, fw_ddb_index);
if (state == DDB_DS_NO_CONNECTION_ACTIVE)
clear_bit(fw_ddb_index, ha->ddb_idx_map);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.