📄 qla_init.c
字号:
qla2x00_update_fcport(ha, fcport); found_devs++; }cleanup_allocation: kfree(new_fcport); if (rval != QLA_SUCCESS) { DEBUG2(printk("scsi(%ld): Configure local loop error exit: " "rval=%x\n", ha->host_no, rval)); } if (found_devs) { ha->device_flags |= DFLG_LOCAL_DEVICES; ha->device_flags &= ~DFLG_RETRY_LOCAL_DEVICES; } return (rval);}static voidqla2x00_probe_for_all_luns(scsi_qla_host_t *ha){ fc_port_t *fcport; qla2x00_mark_all_devices_lost(ha); list_for_each_entry(fcport, &ha->fcports, list) { if (fcport->port_type != FCT_TARGET) continue; qla2x00_update_fcport(ha, fcport); }}/* * qla2x00_update_fcport * Updates device on list. * * Input: * ha = adapter block pointer. * fcport = port structure pointer. * * Return: * 0 - Success * BIT_0 - error * * Context: * Kernel context. */static voidqla2x00_update_fcport(scsi_qla_host_t *ha, fc_port_t *fcport){ uint16_t index; unsigned long flags; srb_t *sp; fcport->ha = ha; fcport->login_retry = 0; fcport->port_login_retry_count = ha->port_down_retry_count * PORT_RETRY_TIME; atomic_set(&fcport->port_down_timer, ha->port_down_retry_count * PORT_RETRY_TIME); fcport->flags &= ~FCF_LOGIN_NEEDED; /* * Check for outstanding cmd on tape Bypass LUN discovery if active * command on tape. */ if (fcport->flags & FCF_TAPE_PRESENT) { spin_lock_irqsave(&ha->hardware_lock, flags); for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) { fc_port_t *sfcp; if ((sp = ha->outstanding_cmds[index]) != 0) { sfcp = sp->fcport; if (sfcp == fcport) { atomic_set(&fcport->state, FCS_ONLINE); spin_unlock_irqrestore( &ha->hardware_lock, flags); return; } } } spin_unlock_irqrestore(&ha->hardware_lock, flags); } if (fcport->port_type == FCT_INITIATOR || fcport->port_type == FCT_BROADCAST) fcport->device_type = TYPE_PROCESSOR; atomic_set(&fcport->state, FCS_ONLINE); if (ha->flags.init_done) qla2x00_reg_remote_port(ha, fcport);}voidqla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport){ struct fc_rport_identifiers rport_ids; struct fc_rport *rport; if (fcport->rport) { fc_remote_port_delete(fcport->rport); fcport->rport = NULL; } rport_ids.node_name = wwn_to_u64(fcport->node_name); rport_ids.port_name = wwn_to_u64(fcport->port_name); rport_ids.port_id = fcport->d_id.b.domain << 16 | fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa; rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; fcport->rport = rport = fc_remote_port_add(ha->host, 0, &rport_ids); if (!rport) { qla_printk(KERN_WARNING, ha, "Unable to allocate fc remote port!\n"); return; } *((fc_port_t **)rport->dd_data) = fcport; rport->supported_classes = fcport->supported_classes; rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; if (fcport->port_type == FCT_INITIATOR) rport_ids.roles |= FC_RPORT_ROLE_FCP_INITIATOR; if (fcport->port_type == FCT_TARGET) rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET; fc_remote_port_rolechg(rport, rport_ids.roles); if (rport->scsi_target_id != -1 && rport->scsi_target_id < ha->host->max_id) fcport->os_target_id = rport->scsi_target_id;}/* * qla2x00_configure_fabric * Setup SNS devices with loop ID's. * * Input: * ha = adapter block pointer. * * Returns: * 0 = success. * BIT_0 = error */static intqla2x00_configure_fabric(scsi_qla_host_t *ha){ int rval, rval2; fc_port_t *fcport, *fcptemp; uint16_t next_loopid; uint16_t mb[MAILBOX_REGISTER_COUNT]; uint16_t loop_id; LIST_HEAD(new_fcports); /* If FL port exists, then SNS is present */ if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) loop_id = NPH_F_PORT; else loop_id = SNS_FL_PORT; rval = qla2x00_get_port_name(ha, loop_id, NULL, 0); if (rval != QLA_SUCCESS) { DEBUG2(printk("scsi(%ld): MBC_GET_PORT_NAME Failed, No FL " "Port\n", ha->host_no)); ha->device_flags &= ~SWITCH_FOUND; return (QLA_SUCCESS); } /* Mark devices that need re-synchronization. */ rval2 = qla2x00_device_resync(ha); if (rval2 == QLA_RSCNS_HANDLED) { /* No point doing the scan, just continue. */ return (QLA_SUCCESS); } do { /* FDMI support. */ if (ql2xfdmienable && test_and_clear_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags)) qla2x00_fdmi_register(ha); /* Ensure we are logged into the SNS. */ if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) loop_id = NPH_SNS; else loop_id = SIMPLE_NAME_SERVER; ha->isp_ops.fabric_login(ha, loop_id, 0xff, 0xff, 0xfc, mb, BIT_1 | BIT_0); if (mb[0] != MBS_COMMAND_COMPLETE) { DEBUG2(qla_printk(KERN_INFO, ha, "Failed SNS login: loop_id=%x mb[0]=%x mb[1]=%x " "mb[2]=%x mb[6]=%x mb[7]=%x\n", loop_id, mb[0], mb[1], mb[2], mb[6], mb[7])); return (QLA_SUCCESS); } if (test_and_clear_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags)) { if (qla2x00_rft_id(ha)) { /* EMPTY */ DEBUG2(printk("scsi(%ld): Register FC-4 " "TYPE failed.\n", ha->host_no)); } if (qla2x00_rff_id(ha)) { /* EMPTY */ DEBUG2(printk("scsi(%ld): Register FC-4 " "Features failed.\n", ha->host_no)); } if (qla2x00_rnn_id(ha)) { /* EMPTY */ DEBUG2(printk("scsi(%ld): Register Node Name " "failed.\n", ha->host_no)); } else if (qla2x00_rsnn_nn(ha)) { /* EMPTY */ DEBUG2(printk("scsi(%ld): Register Symbolic " "Node Name failed.\n", ha->host_no)); } } rval = qla2x00_find_all_fabric_devs(ha, &new_fcports); if (rval != QLA_SUCCESS) break; /* * Logout all previous fabric devices marked lost, except * tape devices. */ list_for_each_entry(fcport, &ha->fcports, list) { if (test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) break; if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) continue; if (atomic_read(&fcport->state) == FCS_DEVICE_LOST) { qla2x00_mark_device_lost(ha, fcport, ql2xplogiabsentdevice); if (fcport->loop_id != FC_NO_LOOP_ID && (fcport->flags & FCF_TAPE_PRESENT) == 0 && fcport->port_type != FCT_INITIATOR && fcport->port_type != FCT_BROADCAST) { ha->isp_ops.fabric_logout(ha, fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa); fcport->loop_id = FC_NO_LOOP_ID; } } } /* Starting free loop ID. */ next_loopid = ha->min_external_loopid; /* * Scan through our port list and login entries that need to be * logged in. */ list_for_each_entry(fcport, &ha->fcports, list) { if (atomic_read(&ha->loop_down_timer) || test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) break; if ((fcport->flags & FCF_FABRIC_DEVICE) == 0 || (fcport->flags & FCF_LOGIN_NEEDED) == 0) continue; if (fcport->loop_id == FC_NO_LOOP_ID) { fcport->loop_id = next_loopid; rval = qla2x00_find_new_loop_id(ha, fcport); if (rval != QLA_SUCCESS) { /* Ran out of IDs to use */ break; } } /* Login and update database */ qla2x00_fabric_dev_login(ha, fcport, &next_loopid); } /* Exit if out of loop IDs. */ if (rval != QLA_SUCCESS) { break; } /* * Login and add the new devices to our port list. */ list_for_each_entry_safe(fcport, fcptemp, &new_fcports, list) { if (atomic_read(&ha->loop_down_timer) || test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) break; /* Find a new loop ID to use. */ fcport->loop_id = next_loopid; rval = qla2x00_find_new_loop_id(ha, fcport); if (rval != QLA_SUCCESS) { /* Ran out of IDs to use */ break; } /* Remove device from the new list and add it to DB */ list_del(&fcport->list); list_add_tail(&fcport->list, &ha->fcports); /* Login and update database */ qla2x00_fabric_dev_login(ha, fcport, &next_loopid); } } while (0); /* Free all new device structures not processed. */ list_for_each_entry_safe(fcport, fcptemp, &new_fcports, list) { list_del(&fcport->list); kfree(fcport); } if (rval) { DEBUG2(printk("scsi(%ld): Configure fabric error exit: " "rval=%d\n", ha->host_no, rval)); } return (rval);}/* * qla2x00_find_all_fabric_devs * * Input: * ha = adapter block pointer. * dev = database device entry pointer. * * Returns: * 0 = success. * * Context: * Kernel context. */static intqla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports){ int rval; uint16_t loop_id; fc_port_t *fcport, *new_fcport, *fcptemp; int found; sw_info_t *swl; int swl_idx; int first_dev, last_dev; port_id_t wrap, nxt_d_id; rval = QLA_SUCCESS; /* Try GID_PT to get device list, else GAN. */ swl = kmalloc(sizeof(sw_info_t) * MAX_FIBRE_DEVICES, GFP_ATOMIC); if (swl == NULL) { /*EMPTY*/ DEBUG2(printk("scsi(%ld): GID_PT allocations failed, fallback " "on GA_NXT\n", ha->host_no)); } else { memset(swl, 0, sizeof(sw_info_t) * MAX_FIBRE_DEVICES); if (qla2x00_gid_pt(ha, swl) != QLA_SUCCESS) { kfree(swl); swl = NULL; } else if (qla2x00_gpn_id(ha, swl) != QLA_SUCCESS) { kfree(swl); swl = NULL; } else if (qla2x00_gnn_id(ha, swl) != QLA_SUCCESS) { kfree(swl); swl = NULL; } } swl_idx = 0; /* Allocate temporary fcport for any new fcports discovered. */ new_fcport = qla2x00_alloc_fcport(ha, GFP_KERNEL); if (new_fcport == NULL) { kfree(swl); return (QLA_MEMORY_ALLOC_FAILED); } new_fcport->flags |= (FCF_FABRIC_DEVICE | FCF_LOGIN_NEEDED); /* Set start port ID scan at adapter ID. */ first_dev = 1; last_dev = 0; /* Starting free loop ID. */ loop_id = ha->min_external_loopid; for (; loop_id <= ha->last_loop_id; loop_id++) { if (qla2x00_is_reserved_id(ha, loop_id)) continue; if (atomic_read(&ha->loop_down_timer) || LOOP_TRANSITION(ha)) break; if (swl != NULL) { if (last_dev) { wrap.b24 = new_fcport->d_id.b24; } else { new_fcport->d_id.b24 = swl[swl_idx].d_id.b24; memcpy(new_fcport->node_name, swl[swl_idx].node_name, WWN_SIZE); memcpy(new_fcport->port_name, swl[swl_idx].port_name, WWN_SIZE); if (swl[swl_idx].d_id.b.rsvd_1 != 0) { last_dev = 1; } swl_idx++; } } else { /* Send GA_NXT to the switch */ rval = qla2x00_ga_nxt(ha, new_fcport); if (rval != QLA_SUCCESS) { qla_printk(KERN_WARNING, ha, "SNS scan failed -- assuming zero-entry " "result...\n"); list_for_each_entry_safe(fcport, fcptemp, new_fcports, list) { list_del(&fcport->list); kfree(fcport); } rval = QLA_SUCCESS; break; } } /* If wrap on switch device list, exit. */ if (first_dev) { wrap.b24 = new_fcport->d_id.b24; first_dev = 0; } else if (new_fcport->d_id.b24 == wrap.b24) { DEBUG2(printk("scsi(%ld): device wrap (%02x%02x%02x)\n", ha->host_no, new_fcport->d_id.b.domain, new_fcport->d_id.b.area, new_fcport->d_id.b.al_pa)); break; } /* Bypass if host adapter. */ if (new_fcport->d_id.b24 == ha->d_id.b24) continue; /* Bypass if same domain and area of adapter. */ if (((new_fcport->d_id.b24 & 0xffff00) == (ha->d_id.b24 & 0xffff00)) && ha->current_topology == ISP_CFG_FL) continue; /* Bypass reserved domain fields. */ if ((new_fcport->d_id.b.domain & 0xf0) == 0xf0) continue; /* Locate matching device in database. */ found = 0; list_for_each_entry(fcport, &ha->fcports, list) { if (memcmp(new_fcport->port_name, fcport->port_name, WWN_SIZE)) continue; found++; /* * If address the same and state FCS_ONLINE, nothing * changed. */ if (fcport->d_id.b24 == new_fcport->d_id.b24 && atomic_read(&fcport->state) == FCS_ONLINE) { break; } /* * If device was not a fabric device before. */ if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) { fcport->d_id.b24 = new_fcport->d_id.b24; fcport->loop_id = FC_NO_LOOP_ID; fcport->flags |= (FCF_FABRIC_DEVICE | FCF_LOGIN_NEEDED); fcport->flags &= ~FCF_PERSISTENT_BOUND; break; } /* * Port ID changed or device was marked to be updated; * Log it out if still logged in and mark it for * relogin later. */ fcport->d_id.b24 = new_fcport->d_id.b24; fcport->flags |= FCF_LOGIN_NEEDED; if (fcport->loop_id != FC_NO_LOOP_ID && (fcport->flags & FCF_TAPE_PRESENT) == 0 && fcport->port_type != FCT_INITIATOR && fcport->port_type != FCT_BROADCAST) { ha->i
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -