⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qla_init.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
		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 + -