diff options
Diffstat (limited to 'drivers/scsi/qla4xxx/ql4_init.c')
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_init.c | 608 |
1 files changed, 1 insertions, 607 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c index ca6b2c5f0fdd..21f6f4bacd9d 100644 --- a/drivers/scsi/qla4xxx/ql4_init.c +++ b/drivers/scsi/qla4xxx/ql4_init.c @@ -11,9 +11,6 @@ #include "ql4_dbg.h" #include "ql4_inline.h" -static struct ddb_entry *qla4xxx_alloc_ddb(struct scsi_qla_host *ha, - uint32_t fw_ddb_index); - static void ql4xxx_set_mac_number(struct scsi_qla_host *ha) { uint32_t value; @@ -60,25 +57,6 @@ void qla4xxx_free_ddb(struct scsi_qla_host *ha, } /** - * qla4xxx_free_ddb_list - deallocate all ddbs - * @ha: pointer to host adapter structure. - * - * This routine deallocates and removes all devices on the sppecified adapter. - **/ -void qla4xxx_free_ddb_list(struct scsi_qla_host *ha) -{ - struct list_head *ptr; - struct ddb_entry *ddb_entry; - - while (!list_empty(&ha->ddb_list)) { - ptr = ha->ddb_list.next; - /* Free memory for device entry and remove */ - ddb_entry = list_entry(ptr, struct ddb_entry, list); - qla4xxx_free_ddb(ha, ddb_entry); - } -} - -/** * qla4xxx_init_response_q_entries() - Initializes response queue entries. * @ha: HA context * @@ -468,489 +446,6 @@ static int qla4xxx_init_firmware(struct scsi_qla_host *ha) return qla4xxx_get_firmware_status(ha); } -static struct ddb_entry* qla4xxx_get_ddb_entry(struct scsi_qla_host *ha, - uint32_t fw_ddb_index, - uint32_t *new_tgt) -{ - struct dev_db_entry *fw_ddb_entry = NULL; - dma_addr_t fw_ddb_entry_dma; - struct ddb_entry *ddb_entry = NULL; - int found = 0; - uint32_t device_state; - - *new_tgt = 0; - /* Make sure the dma buffer is valid */ - fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, - sizeof(*fw_ddb_entry), - &fw_ddb_entry_dma, GFP_KERNEL); - if (fw_ddb_entry == NULL) { - DEBUG2(printk("scsi%ld: %s: Unable to allocate dma buffer.\n", - ha->host_no, __func__)); - goto exit_get_ddb_entry_no_free; - } - - if (qla4xxx_get_fwddb_entry(ha, fw_ddb_index, fw_ddb_entry, - fw_ddb_entry_dma, NULL, NULL, - &device_state, NULL, NULL, NULL) == - QLA_ERROR) { - DEBUG2(printk("scsi%ld: %s: failed get_ddb_entry for " - "fw_ddb_index %d\n", ha->host_no, __func__, - fw_ddb_index)); - goto exit_get_ddb_entry; - } - - /* Allocate DDB if not already allocated. */ - DEBUG2(printk("scsi%ld: %s: Looking for ddb[%d]\n", ha->host_no, - __func__, fw_ddb_index)); - list_for_each_entry(ddb_entry, &ha->ddb_list, list) { - if ((memcmp(ddb_entry->iscsi_name, fw_ddb_entry->iscsi_name, - ISCSI_NAME_SIZE) == 0) && - (ddb_entry->tpgt == - le32_to_cpu(fw_ddb_entry->tgt_portal_grp)) && - (memcmp(ddb_entry->isid, fw_ddb_entry->isid, - sizeof(ddb_entry->isid)) == 0)) { - found++; - break; - } - } - - /* if not found allocate new ddb */ - if (!found) { - DEBUG2(printk("scsi%ld: %s: ddb[%d] not found - allocating " - "new ddb\n", ha->host_no, __func__, - fw_ddb_index)); - *new_tgt = 1; - ddb_entry = qla4xxx_alloc_ddb(ha, fw_ddb_index); - } - -exit_get_ddb_entry: - dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), fw_ddb_entry, - fw_ddb_entry_dma); - -exit_get_ddb_entry_no_free: - return ddb_entry; -} - -/** - * qla4xxx_update_ddb_entry - update driver's internal ddb - * @ha: pointer to host adapter structure. - * @ddb_entry: pointer to device database structure to be filled - * @fw_ddb_index: index of the ddb entry in fw ddb table - * - * This routine updates the driver's internal device database entry - * with information retrieved from the firmware's device database - * entry for the specified device. The ddb_entry->fw_ddb_index field - * must be initialized prior to calling this routine - * - **/ -static int qla4xxx_update_ddb_entry(struct scsi_qla_host *ha, - struct ddb_entry *ddb_entry, - uint32_t fw_ddb_index) -{ - struct dev_db_entry *fw_ddb_entry = NULL; - dma_addr_t fw_ddb_entry_dma; - int status = QLA_ERROR; - uint32_t conn_err; - - if (ddb_entry == NULL) { - DEBUG2(printk("scsi%ld: %s: ddb_entry is NULL\n", ha->host_no, - __func__)); - - goto exit_update_ddb_no_free; - } - - /* Make sure the dma buffer is valid */ - fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, - sizeof(*fw_ddb_entry), - &fw_ddb_entry_dma, GFP_KERNEL); - if (fw_ddb_entry == NULL) { - DEBUG2(printk("scsi%ld: %s: Unable to allocate dma buffer.\n", - ha->host_no, __func__)); - - goto exit_update_ddb_no_free; - } - - if (qla4xxx_get_fwddb_entry(ha, fw_ddb_index, fw_ddb_entry, - fw_ddb_entry_dma, NULL, NULL, - &ddb_entry->fw_ddb_device_state, &conn_err, - &ddb_entry->tcp_source_port_num, - &ddb_entry->connection_id) == - QLA_ERROR) { - DEBUG2(printk("scsi%ld: %s: failed get_ddb_entry for " - "fw_ddb_index %d\n", ha->host_no, __func__, - fw_ddb_index)); - - goto exit_update_ddb; - } - - status = QLA_SUCCESS; - ddb_entry->options = le16_to_cpu(fw_ddb_entry->options); - ddb_entry->target_session_id = le16_to_cpu(fw_ddb_entry->tsid); - ddb_entry->task_mgmt_timeout = - le16_to_cpu(fw_ddb_entry->def_timeout); - ddb_entry->CmdSn = 0; - ddb_entry->exe_throttle = le16_to_cpu(fw_ddb_entry->exec_throttle); - ddb_entry->default_relogin_timeout = - le16_to_cpu(fw_ddb_entry->def_timeout); - ddb_entry->default_time2wait = le16_to_cpu(fw_ddb_entry->iscsi_def_time2wait); - - /* Update index in case it changed */ - ddb_entry->fw_ddb_index = fw_ddb_index; - ha->fw_ddb_index_map[fw_ddb_index] = ddb_entry; - - ddb_entry->port = le16_to_cpu(fw_ddb_entry->port); - ddb_entry->tpgt = le32_to_cpu(fw_ddb_entry->tgt_portal_grp); - memcpy(ddb_entry->isid, fw_ddb_entry->isid, sizeof(ddb_entry->isid)); - - memcpy(&ddb_entry->iscsi_name[0], &fw_ddb_entry->iscsi_name[0], - min(sizeof(ddb_entry->iscsi_name), - sizeof(fw_ddb_entry->iscsi_name))); - memcpy(&ddb_entry->iscsi_alias[0], &fw_ddb_entry->iscsi_alias[0], - min(sizeof(ddb_entry->iscsi_alias), - sizeof(fw_ddb_entry->iscsi_alias))); - memcpy(&ddb_entry->ip_addr[0], &fw_ddb_entry->ip_addr[0], - min(sizeof(ddb_entry->ip_addr), sizeof(fw_ddb_entry->ip_addr))); - - ddb_entry->iscsi_max_burst_len = fw_ddb_entry->iscsi_max_burst_len; - ddb_entry->iscsi_max_outsnd_r2t = fw_ddb_entry->iscsi_max_outsnd_r2t; - ddb_entry->iscsi_first_burst_len = fw_ddb_entry->iscsi_first_burst_len; - ddb_entry->iscsi_max_rcv_data_seg_len = - fw_ddb_entry->iscsi_max_rcv_data_seg_len; - ddb_entry->iscsi_max_snd_data_seg_len = - fw_ddb_entry->iscsi_max_snd_data_seg_len; - - if (ddb_entry->options & DDB_OPT_IPV6_DEVICE) { - memcpy(&ddb_entry->remote_ipv6_addr, - fw_ddb_entry->ip_addr, - min(sizeof(ddb_entry->remote_ipv6_addr), - sizeof(fw_ddb_entry->ip_addr))); - memcpy(&ddb_entry->link_local_ipv6_addr, - fw_ddb_entry->link_local_ipv6_addr, - min(sizeof(ddb_entry->link_local_ipv6_addr), - sizeof(fw_ddb_entry->link_local_ipv6_addr))); - - DEBUG2(ql4_printk(KERN_INFO, ha, "%s: DDB[%d] State %04x" - " ConnErr %08x IP %pI6 " - ":%04d \"%s\"\n", - __func__, fw_ddb_index, - ddb_entry->fw_ddb_device_state, - conn_err, fw_ddb_entry->ip_addr, - le16_to_cpu(fw_ddb_entry->port), - fw_ddb_entry->iscsi_name)); - } else - DEBUG2(ql4_printk(KERN_INFO, ha, "%s: DDB[%d] State %04x" - " ConnErr %08x IP %pI4 " - ":%04d \"%s\"\n", - __func__, fw_ddb_index, - ddb_entry->fw_ddb_device_state, - conn_err, fw_ddb_entry->ip_addr, - le16_to_cpu(fw_ddb_entry->port), - fw_ddb_entry->iscsi_name)); -exit_update_ddb: - if (fw_ddb_entry) - dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), - fw_ddb_entry, fw_ddb_entry_dma); - -exit_update_ddb_no_free: - return status; -} - -/** - * qla4xxx_alloc_ddb - allocate device database entry - * @ha: Pointer to host adapter structure. - * @fw_ddb_index: Firmware's device database index - * - * This routine allocates a ddb_entry, ititializes some values, and - * inserts it into the ddb list. - **/ -static struct ddb_entry * qla4xxx_alloc_ddb(struct scsi_qla_host *ha, - uint32_t fw_ddb_index) -{ - struct ddb_entry *ddb_entry; - - DEBUG2(printk("scsi%ld: %s: fw_ddb_index [%d]\n", ha->host_no, - __func__, fw_ddb_index)); - - ddb_entry = qla4xxx_alloc_sess(ha); - if (ddb_entry == NULL) { - DEBUG2(printk("scsi%ld: %s: Unable to allocate memory " - "to add fw_ddb_index [%d]\n", - ha->host_no, __func__, fw_ddb_index)); - return ddb_entry; - } - - ddb_entry->fw_ddb_index = fw_ddb_index; - atomic_set(&ddb_entry->retry_relogin_timer, INVALID_ENTRY); - atomic_set(&ddb_entry->relogin_timer, 0); - atomic_set(&ddb_entry->relogin_retry_count, 0); - atomic_set(&ddb_entry->state, DDB_STATE_ONLINE); - list_add_tail(&ddb_entry->list, &ha->ddb_list); - ha->fw_ddb_index_map[fw_ddb_index] = ddb_entry; - ha->tot_ddbs++; - - return ddb_entry; -} - -/** - * qla4_is_relogin_allowed - Are we allowed to login? - * @ha: Pointer to host adapter structure. - * @conn_err: Last connection error associated with the ddb - * - * This routine tests the given connection error to determine if - * we are allowed to login. - **/ -int qla4_is_relogin_allowed(struct scsi_qla_host *ha, uint32_t conn_err) -{ - uint32_t err_code, login_rsp_sts_class; - int relogin = 1; - - err_code = ((conn_err & 0x00ff0000) >> 16); - login_rsp_sts_class = ((conn_err & 0x0000ff00) >> 8); - if (err_code == 0x1c || err_code == 0x06) { - DEBUG2(ql4_printk(KERN_INFO, ha, - ": conn_err=0x%08x, send target completed" - " or access denied failure\n", conn_err)); - relogin = 0; - } - if ((err_code == 0x08) && (login_rsp_sts_class == 0x02)) { - /* Login Response PDU returned an error. - Login Response Status in Error Code Detail - indicates login should not be retried.*/ - DEBUG2(ql4_printk(KERN_INFO, ha, - ": conn_err=0x%08x, do not retry relogin\n", - conn_err)); - relogin = 0; - } - - return relogin; -} - -static void qla4xxx_flush_AENS(struct scsi_qla_host *ha) -{ - unsigned long wtime; - - /* Flush the 0x8014 AEN from the firmware as a result of - * Auto connect. We are basically doing get_firmware_ddb() - * to determine whether we need to log back in or not. - * Trying to do a set ddb before we have processed 0x8014 - * will result in another set_ddb() for the same ddb. In other - * words there will be stale entries in the aen_q. - */ - wtime = jiffies + (2 * HZ); - do { - if (qla4xxx_get_firmware_state(ha) == QLA_SUCCESS) - if (ha->firmware_state & (BIT_2 | BIT_0)) - return; - - if (test_and_clear_bit(DPC_AEN, &ha->dpc_flags)) - qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS); - - msleep(1000); - } while (!time_after_eq(jiffies, wtime)); -} - -/** - * qla4xxx_build_ddb_list - builds driver ddb list - * @ha: Pointer to host adapter structure. - * - * This routine searches for all valid firmware ddb entries and builds - * an internal ddb list. Ddbs that are considered valid are those with - * a device state of SESSION_ACTIVE. - * A relogin (set_ddb) is issued for DDBs that are not online. - **/ -static int qla4xxx_build_ddb_list(struct scsi_qla_host *ha) -{ - int status = QLA_ERROR; - uint32_t fw_ddb_index = 0; - uint32_t next_fw_ddb_index = 0; - uint32_t ddb_state; - uint32_t conn_err; - struct ddb_entry *ddb_entry; - struct dev_db_entry *fw_ddb_entry = NULL; - dma_addr_t fw_ddb_entry_dma; - uint32_t ipv6_device; - uint32_t new_tgt; - - qla4xxx_flush_AENS(ha); - - fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), - &fw_ddb_entry_dma, GFP_KERNEL); - if (fw_ddb_entry == NULL) { - DEBUG2(ql4_printk(KERN_INFO, ha, "%s: DMA alloc failed\n", - __func__)); - - goto exit_build_ddb_list_no_free; - } - - ql4_printk(KERN_INFO, ha, "Initializing DDBs ...\n"); - for (fw_ddb_index = 0; fw_ddb_index < MAX_DDB_ENTRIES; - fw_ddb_index = next_fw_ddb_index) { - /* First, let's see if a device exists here */ - if (qla4xxx_get_fwddb_entry(ha, fw_ddb_index, fw_ddb_entry, - 0, NULL, &next_fw_ddb_index, - &ddb_state, &conn_err, - NULL, NULL) == - QLA_ERROR) { - DEBUG2(printk("scsi%ld: %s: get_ddb_entry, " - "fw_ddb_index %d failed", ha->host_no, - __func__, fw_ddb_index)); - goto exit_build_ddb_list; - } - - DEBUG2(printk("scsi%ld: %s: Getting DDB[%d] ddbstate=0x%x, " - "next_fw_ddb_index=%d.\n", ha->host_no, __func__, - fw_ddb_index, ddb_state, next_fw_ddb_index)); - - /* Issue relogin, if necessary. */ - if (ddb_state == DDB_DS_SESSION_FAILED || - ddb_state == DDB_DS_NO_CONNECTION_ACTIVE) { - /* Try and login to device */ - DEBUG2(printk("scsi%ld: %s: Login to DDB[%d]\n", - ha->host_no, __func__, fw_ddb_index)); - ipv6_device = le16_to_cpu(fw_ddb_entry->options) & - DDB_OPT_IPV6_DEVICE; - if (qla4_is_relogin_allowed(ha, conn_err) && - ((!ipv6_device && - *((uint32_t *)fw_ddb_entry->ip_addr)) - || ipv6_device)) { - qla4xxx_set_ddb_entry(ha, fw_ddb_index, 0, - NULL); - if (qla4xxx_get_fwddb_entry(ha, fw_ddb_index, - NULL, 0, NULL, - &next_fw_ddb_index, - &ddb_state, &conn_err, - NULL, NULL) - == QLA_ERROR) { - DEBUG2(printk("scsi%ld: %s:" - "get_ddb_entry %d failed\n", - ha->host_no, - __func__, fw_ddb_index)); - goto exit_build_ddb_list; - } - } - } - - if (ddb_state != DDB_DS_SESSION_ACTIVE) - goto next_one; - /* - * if fw_ddb with session active state found, - * add to ddb_list - */ - DEBUG2(printk("scsi%ld: %s: DDB[%d] added to list\n", - ha->host_no, __func__, fw_ddb_index)); - - /* Add DDB to internal our ddb list. */ - ddb_entry = qla4xxx_get_ddb_entry(ha, fw_ddb_index, &new_tgt); - if (ddb_entry == NULL) { - DEBUG2(printk("scsi%ld: %s: Unable to allocate memory " - "for device at fw_ddb_index %d\n", - ha->host_no, __func__, fw_ddb_index)); - goto exit_build_ddb_list; - } - /* Fill in the device structure */ - if (qla4xxx_update_ddb_entry(ha, ddb_entry, fw_ddb_index) == - QLA_ERROR) { - ha->fw_ddb_index_map[fw_ddb_index] = - (struct ddb_entry *)INVALID_ENTRY; - - DEBUG2(printk("scsi%ld: %s: update_ddb_entry failed " - "for fw_ddb_index %d.\n", - ha->host_no, __func__, fw_ddb_index)); - goto exit_build_ddb_list; - } - -next_one: - /* We know we've reached the last device when - * next_fw_ddb_index is 0 */ - if (next_fw_ddb_index == 0) - break; - } - - status = QLA_SUCCESS; - ql4_printk(KERN_INFO, ha, "DDB list done..\n"); - -exit_build_ddb_list: - dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), fw_ddb_entry, - fw_ddb_entry_dma); - -exit_build_ddb_list_no_free: - return status; -} - -static int qla4xxx_initialize_ddb_list(struct scsi_qla_host *ha) -{ - uint16_t fw_ddb_index; - int status = QLA_SUCCESS; - - /* free the ddb list if is not empty */ - if (!list_empty(&ha->ddb_list)) - qla4xxx_free_ddb_list(ha); - - for (fw_ddb_index = 0; fw_ddb_index < MAX_DDB_ENTRIES; fw_ddb_index++) - ha->fw_ddb_index_map[fw_ddb_index] = - (struct ddb_entry *)INVALID_ENTRY; - - ha->tot_ddbs = 0; - - /* Perform device discovery and build ddb list. */ - status = qla4xxx_build_ddb_list(ha); - - return status; -} - -/** - * qla4xxx_reinitialize_ddb_list - update the driver ddb list - * @ha: pointer to host adapter structure. - * - * This routine obtains device information from the F/W database after - * firmware or adapter resets. The device table is preserved. - **/ -int qla4xxx_reinitialize_ddb_list(struct scsi_qla_host *ha) -{ - int status = QLA_SUCCESS; - struct ddb_entry *ddb_entry, *detemp; - - /* Update the device information for all devices. */ - list_for_each_entry_safe(ddb_entry, detemp, &ha->ddb_list, list) { - qla4xxx_update_ddb_entry(ha, ddb_entry, - ddb_entry->fw_ddb_index); - if (ddb_entry->fw_ddb_device_state == DDB_DS_SESSION_ACTIVE) { - atomic_set(&ddb_entry->state, DDB_STATE_ONLINE); - DEBUG2(printk ("scsi%ld: %s: ddb index [%d] marked " - "ONLINE\n", ha->host_no, __func__, - ddb_entry->fw_ddb_index)); - iscsi_unblock_session(ddb_entry->sess); - } else if (atomic_read(&ddb_entry->state) == DDB_STATE_ONLINE) - qla4xxx_mark_device_missing(ddb_entry->sess); - } - return status; -} - -/** - * qla4xxx_relogin_device - re-establish session - * @ha: Pointer to host adapter structure. - * @ddb_entry: Pointer to device database entry - * - * This routine does a session relogin with the specified device. - * The ddb entry must be assigned prior to making this call. - **/ -int qla4xxx_relogin_device(struct scsi_qla_host *ha, - struct ddb_entry * ddb_entry) -{ - uint16_t relogin_timer; - - relogin_timer = max(ddb_entry->default_relogin_timeout, - (uint16_t)RELOGIN_TOV); - atomic_set(&ddb_entry->relogin_timer, relogin_timer); - - DEBUG2(printk("scsi%ld: Relogin ddb [%d]. TOV=%d\n", ha->host_no, - ddb_entry->fw_ddb_index, relogin_timer)); - - qla4xxx_set_ddb_entry(ha, ddb_entry->fw_ddb_index, 0, NULL); - - return QLA_SUCCESS; -} - static int qla4xxx_config_nvram(struct scsi_qla_host *ha) { unsigned long flags; @@ -1254,18 +749,13 @@ int qla4xxx_start_firmware(struct scsi_qla_host *ha) /** * qla4xxx_initialize_adapter - initiailizes hba * @ha: Pointer to host adapter structure. - * @renew_ddb_list: Indicates what to do with the adapter's ddb list - * after adapter recovery has completed. - * 0=preserve ddb list, 1=destroy and rebuild ddb list * * This routine parforms all of the steps necessary to initialize the adapter. * **/ -int qla4xxx_initialize_adapter(struct scsi_qla_host *ha, - uint8_t renew_ddb_list) +int qla4xxx_initialize_adapter(struct scsi_qla_host *ha) { int status = QLA_ERROR; - int8_t ip_address[IP_ADDR_LEN] = {0} ; ha->eeprom_cmd_data = 0; @@ -1291,47 +781,6 @@ int qla4xxx_initialize_adapter(struct scsi_qla_host *ha, if (status == QLA_ERROR) goto exit_init_hba; - /* - * FW is waiting to get an IP address from DHCP server: Skip building - * the ddb_list and wait for DHCP lease acquired aen to come in - * followed by 0x8014 aen" to trigger the tgt discovery process. - */ - if (ha->firmware_state & FW_STATE_CONFIGURING_IP) - goto exit_init_online; - - /* Skip device discovery if ip and subnet is zero */ - if (memcmp(ha->ip_config.ip_address, ip_address, IP_ADDR_LEN) == 0 || - memcmp(ha->ip_config.subnet_mask, ip_address, IP_ADDR_LEN) == 0) - goto exit_init_online; - - if (renew_ddb_list == PRESERVE_DDB_LIST) { - /* - * We want to preserve lun states (i.e. suspended, etc.) - * for recovery initiated by the driver. So just update - * the device states for the existing ddb_list. - */ - qla4xxx_reinitialize_ddb_list(ha); - } else if (renew_ddb_list == REBUILD_DDB_LIST) { - /* - * We want to build the ddb_list from scratch during - * driver initialization and recovery initiated by the - * INT_HBA_RESET IOCTL. - */ - status = qla4xxx_initialize_ddb_list(ha); - if (status == QLA_ERROR) { - DEBUG2(printk("%s(%ld) Error occurred during build" - "ddb list\n", __func__, ha->host_no)); - goto exit_init_hba; - } - - } - if (!ha->tot_ddbs) { - DEBUG2(printk("scsi%ld: Failed to initialize devices or none " - "present in Firmware device database\n", - ha->host_no)); - } - -exit_init_online: set_bit(AF_ONLINE, &ha->flags); exit_init_hba: if (is_qla8022(ha) && (status == QLA_ERROR)) { @@ -1346,61 +795,6 @@ exit_init_hba: } /** - * qla4xxx_add_device_dynamically - ddb addition due to an AEN - * @ha: Pointer to host adapter structure. - * @fw_ddb_index: Firmware's device database index - * - * This routine processes adds a device as a result of an 8014h AEN. - **/ -static void qla4xxx_add_device_dynamically(struct scsi_qla_host *ha, - uint32_t fw_ddb_index) -{ - struct ddb_entry * ddb_entry; - uint32_t new_tgt; - - /* First allocate a device structure */ - ddb_entry = qla4xxx_get_ddb_entry(ha, fw_ddb_index, &new_tgt); - if (ddb_entry == NULL) { - DEBUG2(printk(KERN_WARNING - "scsi%ld: Unable to allocate memory to add " - "fw_ddb_index %d\n", ha->host_no, fw_ddb_index)); - return; - } - - if (!new_tgt && (ddb_entry->fw_ddb_index != fw_ddb_index)) { - /* Target has been bound to a new fw_ddb_index */ - qla4xxx_free_ddb(ha, ddb_entry); - ddb_entry = qla4xxx_alloc_ddb(ha, fw_ddb_index); - if (ddb_entry == NULL) { - DEBUG2(printk(KERN_WARNING - "scsi%ld: Unable to allocate memory" - " to add fw_ddb_index %d\n", - ha->host_no, fw_ddb_index)); - return; - } - } - if (qla4xxx_update_ddb_entry(ha, ddb_entry, fw_ddb_index) == - QLA_ERROR) { - ha->fw_ddb_index_map[fw_ddb_index] = - (struct ddb_entry *)INVALID_ENTRY; - DEBUG2(printk(KERN_WARNING - "scsi%ld: failed to add new device at index " - "[%d]\n Unable to retrieve fw ddb entry\n", - ha->host_no, fw_ddb_index)); - qla4xxx_free_ddb(ha, ddb_entry); - return; - } - - if (qla4xxx_add_sess(ddb_entry)) { - DEBUG2(printk(KERN_WARNING - "scsi%ld: failed to add new device at index " - "[%d]\n Unable to add connection and session\n", - ha->host_no, fw_ddb_index)); - qla4xxx_free_ddb(ha, ddb_entry); - } -} - -/** * qla4xxx_process_ddb_changed - process ddb state change * @ha - Pointer to host adapter structure. * @fw_ddb_index - Firmware's device database index |