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

📄 qla_init.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
				    sizeof(nv->model_number)) != 0) {				char *st, *en;				strncpy(ha->model_number, nv->model_number,				    sizeof(nv->model_number));				st = en = ha->model_number;				en += sizeof(nv->model_number) - 1;				while (en > st) {					if (*en != 0x20 && *en != 0x00)						break;					*en-- = '\0';				}			} else {				uint16_t        index;				index = (ha->pdev->subsystem_device & 0xff);				if (index < QLA_MODEL_NAMES) {					strcpy(ha->model_number,					    qla2x00_model_name[index]);					ha->model_desc =					    qla2x00_model_desc[index];				} else {					strcpy(ha->model_number, "QLA23xx");				}			}		}	} else if (IS_QLA2200(ha)) {		nv->firmware_options[0] |= BIT_2;		/*		 * 'Point-to-point preferred, else loop' is not a safe		 * connection mode setting.		 */		if ((nv->add_firmware_options[0] & (BIT_6 | BIT_5 | BIT_4)) ==		    (BIT_5 | BIT_4)) {			/* Force 'loop preferred, else point-to-point'. */			nv->add_firmware_options[0] &= ~(BIT_6 | BIT_5 | BIT_4);			nv->add_firmware_options[0] |= BIT_5;		}		strcpy(ha->model_number, "QLA22xx");	} else /*if (IS_QLA2100(ha))*/ {		strcpy(ha->model_number, "QLA2100");	}	/*	 * Copy over NVRAM RISC parameter block to initialization control block.	 */	dptr1 = (uint8_t *)icb;	dptr2 = (uint8_t *)&nv->parameter_block_version;	cnt = (uint8_t *)&icb->request_q_outpointer - (uint8_t *)&icb->version;	while (cnt--)		*dptr1++ = *dptr2++;	/* Copy 2nd half. */	dptr1 = (uint8_t *)icb->add_firmware_options;	cnt = (uint8_t *)icb->reserved_3 - (uint8_t *)icb->add_firmware_options;	while (cnt--)		*dptr1++ = *dptr2++;	/* Prepare nodename */	if ((icb->firmware_options[1] & BIT_6) == 0) {		/*		 * Firmware will apply the following mask if the nodename was		 * not provided.		 */		memcpy(icb->node_name, icb->port_name, WWN_SIZE);		icb->node_name[0] &= 0xF0;	}	/*	 * Set host adapter parameters.	 */	ha->flags.disable_risc_code_load = ((nv->host_p[0] & BIT_4) ? 1 : 0);	/* Always load RISC code on non ISP2[12]00 chips. */	if (!IS_QLA2100(ha) && !IS_QLA2200(ha))		ha->flags.disable_risc_code_load = 0;	ha->flags.enable_lip_reset = ((nv->host_p[1] & BIT_1) ? 1 : 0);	ha->flags.enable_lip_full_login = ((nv->host_p[1] & BIT_2) ? 1 : 0);	ha->flags.enable_target_reset = ((nv->host_p[1] & BIT_3) ? 1 : 0);	ha->flags.enable_led_scheme = (nv->special_options[1] & BIT_4) ? 1 : 0;	ha->operating_mode =	    (icb->add_firmware_options[0] & (BIT_6 | BIT_5 | BIT_4)) >> 4;	memcpy(ha->fw_seriallink_options, nv->seriallink_options,	    sizeof(ha->fw_seriallink_options));	/* save HBA serial number */	ha->serial0 = icb->port_name[5];	ha->serial1 = icb->port_name[6];	ha->serial2 = icb->port_name[7];	ha->node_name = icb->node_name;	ha->port_name = icb->port_name;	icb->execution_throttle = __constant_cpu_to_le16(0xFFFF);	ha->retry_count = nv->retry_count;	/* Set minimum login_timeout to 4 seconds. */	if (nv->login_timeout < ql2xlogintimeout)		nv->login_timeout = ql2xlogintimeout;	if (nv->login_timeout < 4)		nv->login_timeout = 4;	ha->login_timeout = nv->login_timeout;	icb->login_timeout = nv->login_timeout;	/* Set minimum RATOV to 200 tenths of a second. */	ha->r_a_tov = 200;	ha->loop_reset_delay = nv->reset_delay;	/* Link Down Timeout = 0:	 *	 * 	When Port Down timer expires we will start returning	 *	I/O's to OS with "DID_NO_CONNECT".	 *	 * Link Down Timeout != 0:	 *	 *	 The driver waits for the link to come up after link down	 *	 before returning I/Os to OS with "DID_NO_CONNECT".	 */	if (nv->link_down_timeout == 0) {		ha->loop_down_abort_time =		    (LOOP_DOWN_TIME - LOOP_DOWN_TIMEOUT);	} else {		ha->link_down_timeout =	 nv->link_down_timeout;		ha->loop_down_abort_time =		    (LOOP_DOWN_TIME - ha->link_down_timeout);	}	/*	 * Need enough time to try and get the port back.	 */	ha->port_down_retry_count = nv->port_down_retry_count;	if (qlport_down_retry)		ha->port_down_retry_count = qlport_down_retry;	/* Set login_retry_count */	ha->login_retry_count  = nv->retry_count;	if (ha->port_down_retry_count == nv->port_down_retry_count &&	    ha->port_down_retry_count > 3)		ha->login_retry_count = ha->port_down_retry_count;	else if (ha->port_down_retry_count > (int)ha->login_retry_count)		ha->login_retry_count = ha->port_down_retry_count;	if (ql2xloginretrycount)		ha->login_retry_count = ql2xloginretrycount;	icb->lun_enables = __constant_cpu_to_le16(0);	icb->command_resource_count = 0;	icb->immediate_notify_resource_count = 0;	icb->timeout = __constant_cpu_to_le16(0);	if (IS_QLA2100(ha) || IS_QLA2200(ha)) {		/* Enable RIO */		icb->firmware_options[0] &= ~BIT_3;		icb->add_firmware_options[0] &=		    ~(BIT_3 | BIT_2 | BIT_1 | BIT_0);		icb->add_firmware_options[0] |= BIT_2;		icb->response_accumulation_timer = 3;		icb->interrupt_delay_timer = 5;		ha->flags.process_response_queue = 1;	} else {		/* Enable ZIO. */		if (!ha->flags.init_done) {			ha->zio_mode = icb->add_firmware_options[0] &			    (BIT_3 | BIT_2 | BIT_1 | BIT_0);			ha->zio_timer = icb->interrupt_delay_timer ?			    icb->interrupt_delay_timer: 2;		}		icb->add_firmware_options[0] &=		    ~(BIT_3 | BIT_2 | BIT_1 | BIT_0);		ha->flags.process_response_queue = 0;		if (ha->zio_mode != QLA_ZIO_DISABLED) {			DEBUG2(printk("scsi(%ld): ZIO mode %d enabled; timer "			    "delay (%d us).\n", ha->host_no, ha->zio_mode,			    ha->zio_timer * 100));			qla_printk(KERN_INFO, ha,			    "ZIO mode %d enabled; timer delay (%d us).\n",			    ha->zio_mode, ha->zio_timer * 100);			icb->add_firmware_options[0] |= (uint8_t)ha->zio_mode;			icb->interrupt_delay_timer = (uint8_t)ha->zio_timer;			ha->flags.process_response_queue = 1;		}	}	if (rval) {		DEBUG2_3(printk(KERN_WARNING		    "scsi(%ld): NVRAM configuration failed!\n", ha->host_no));	}	return (rval);}static voidqla2x00_rport_add(void *data){	fc_port_t *fcport = data;	qla2x00_reg_remote_port(fcport->ha, fcport);}static voidqla2x00_rport_del(void *data){	fc_port_t *fcport = data;	if (fcport->rport)		fc_remote_port_delete(fcport->rport);	fcport->rport = NULL;}/** * qla2x00_alloc_fcport() - Allocate a generic fcport. * @ha: HA context * @flags: allocation flags * * Returns a pointer to the allocated fcport, or NULL, if none available. */fc_port_t *qla2x00_alloc_fcport(scsi_qla_host_t *ha, gfp_t flags){	fc_port_t *fcport;	fcport = kmalloc(sizeof(fc_port_t), flags);	if (fcport == NULL)		return (fcport);	/* Setup fcport template structure. */	memset(fcport, 0, sizeof (fc_port_t));	fcport->ha = ha;	fcport->port_type = FCT_UNKNOWN;	fcport->loop_id = FC_NO_LOOP_ID;	fcport->iodesc_idx_sent = IODESC_INVALID_INDEX;	atomic_set(&fcport->state, FCS_UNCONFIGURED);	fcport->flags = FCF_RLC_SUPPORT;	fcport->supported_classes = FC_COS_UNSPECIFIED;	INIT_WORK(&fcport->rport_add_work, qla2x00_rport_add, fcport);	INIT_WORK(&fcport->rport_del_work, qla2x00_rport_del, fcport);	return (fcport);}/* * qla2x00_configure_loop *      Updates Fibre Channel Device Database with what is actually on loop. * * Input: *      ha                = adapter block pointer. * * Returns: *      0 = success. *      1 = error. *      2 = database was full and device was not configured. */static intqla2x00_configure_loop(scsi_qla_host_t *ha){	int  rval;	unsigned long flags, save_flags;	rval = QLA_SUCCESS;	/* Get Initiator ID */	if (test_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags)) {		rval = qla2x00_configure_hba(ha);		if (rval != QLA_SUCCESS) {			DEBUG(printk("scsi(%ld): Unable to configure HBA.\n",			    ha->host_no));			return (rval);		}	}	save_flags = flags = ha->dpc_flags;	DEBUG(printk("scsi(%ld): Configure loop -- dpc flags =0x%lx\n",	    ha->host_no, flags));	/*	 * If we have both an RSCN and PORT UPDATE pending then handle them	 * both at the same time.	 */	clear_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);	clear_bit(RSCN_UPDATE, &ha->dpc_flags);	/* Determine what we need to do */	if (ha->current_topology == ISP_CFG_FL &&	    (test_bit(LOCAL_LOOP_UPDATE, &flags))) {		ha->flags.rscn_queue_overflow = 1;		set_bit(RSCN_UPDATE, &flags);	} else if (ha->current_topology == ISP_CFG_F &&	    (test_bit(LOCAL_LOOP_UPDATE, &flags))) {		ha->flags.rscn_queue_overflow = 1;		set_bit(RSCN_UPDATE, &flags);		clear_bit(LOCAL_LOOP_UPDATE, &flags);	} else if (!ha->flags.online ||	    (test_bit(ABORT_ISP_ACTIVE, &flags))) {		ha->flags.rscn_queue_overflow = 1;		set_bit(RSCN_UPDATE, &flags);		set_bit(LOCAL_LOOP_UPDATE, &flags);	}	if (test_bit(LOCAL_LOOP_UPDATE, &flags)) {		if (test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) {			rval = QLA_FUNCTION_FAILED;		} else {			rval = qla2x00_configure_local_loop(ha);		}	}	if (rval == QLA_SUCCESS && test_bit(RSCN_UPDATE, &flags)) {		if (LOOP_TRANSITION(ha)) {			rval = QLA_FUNCTION_FAILED;		} else {			rval = qla2x00_configure_fabric(ha);		}	}	if (rval == QLA_SUCCESS) {		if (atomic_read(&ha->loop_down_timer) ||		    test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) {			rval = QLA_FUNCTION_FAILED;		} else {			atomic_set(&ha->loop_state, LOOP_READY);			DEBUG(printk("scsi(%ld): LOOP READY\n", ha->host_no));		}	}	if (rval) {		DEBUG2_3(printk("%s(%ld): *** FAILED ***\n",		    __func__, ha->host_no));	} else {		DEBUG3(printk("%s: exiting normally\n", __func__));	}	/* Restore state if a resync event occured during processing */	if (test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) {		if (test_bit(LOCAL_LOOP_UPDATE, &save_flags))			set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);		if (test_bit(RSCN_UPDATE, &save_flags))			set_bit(RSCN_UPDATE, &ha->dpc_flags);	}	return (rval);}/* * qla2x00_configure_local_loop *	Updates Fibre Channel Device Database with local loop devices. * * Input: *	ha = adapter block pointer. * * Returns: *	0 = success. */static intqla2x00_configure_local_loop(scsi_qla_host_t *ha){	int		rval, rval2;	int		found_devs;	int		found;	fc_port_t	*fcport, *new_fcport;	uint16_t	index;	uint16_t	entries;	char		*id_iter;	uint16_t	loop_id;	uint8_t		domain, area, al_pa;	found_devs = 0;	new_fcport = NULL;	entries = MAX_FIBRE_DEVICES;	DEBUG3(printk("scsi(%ld): Getting FCAL position map\n", ha->host_no));	DEBUG3(qla2x00_get_fcal_position_map(ha, NULL));	/* Get list of logged in devices. */	memset(ha->gid_list, 0, GID_LIST_SIZE);	rval = qla2x00_get_id_list(ha, ha->gid_list, ha->gid_list_dma,	    &entries);	if (rval != QLA_SUCCESS)		goto cleanup_allocation;	DEBUG3(printk("scsi(%ld): Entries in ID list (%d)\n",	    ha->host_no, entries));	DEBUG3(qla2x00_dump_buffer((uint8_t *)ha->gid_list,	    entries * sizeof(struct gid_list_info)));	/* Allocate temporary fcport for any new fcports discovered. */	new_fcport = qla2x00_alloc_fcport(ha, GFP_KERNEL);	if (new_fcport == NULL) {		rval = QLA_MEMORY_ALLOC_FAILED;		goto cleanup_allocation;	}	new_fcport->flags &= ~FCF_FABRIC_DEVICE;	/*	 * Mark local devices that were present with FCF_DEVICE_LOST for now.	 */	list_for_each_entry(fcport, &ha->fcports, list) {		if (atomic_read(&fcport->state) == FCS_ONLINE &&		    fcport->port_type != FCT_BROADCAST &&		    (fcport->flags & FCF_FABRIC_DEVICE) == 0) {			DEBUG(printk("scsi(%ld): Marking port lost, "			    "loop_id=0x%04x\n",			    ha->host_no, fcport->loop_id));			atomic_set(&fcport->state, FCS_DEVICE_LOST);			fcport->flags &= ~FCF_FARP_DONE;		}	}	/* Add devices to port list. */	id_iter = (char *)ha->gid_list;	for (index = 0; index < entries; index++) {		domain = ((struct gid_list_info *)id_iter)->domain;		area = ((struct gid_list_info *)id_iter)->area;		al_pa = ((struct gid_list_info *)id_iter)->al_pa;		if (IS_QLA2100(ha) || IS_QLA2200(ha))			loop_id = (uint16_t)			    ((struct gid_list_info *)id_iter)->loop_id_2100;		else			loop_id = le16_to_cpu(			    ((struct gid_list_info *)id_iter)->loop_id);		id_iter += ha->gid_list_info_size;		/* Bypass reserved domain fields. */		if ((domain & 0xf0) == 0xf0)			continue;		/* Bypass if not same domain and area of adapter. */		if (area && domain &&		    (area != ha->d_id.b.area || domain != ha->d_id.b.domain))			continue;		/* Bypass invalid local loop ID. */		if (loop_id > LAST_LOCAL_LOOP_ID)			continue;		/* Fill in member data. */		new_fcport->d_id.b.domain = domain;		new_fcport->d_id.b.area = area;		new_fcport->d_id.b.al_pa = al_pa;		new_fcport->loop_id = loop_id;		rval2 = qla2x00_get_port_database(ha, new_fcport, 0);		if (rval2 != QLA_SUCCESS) {			DEBUG2(printk("scsi(%ld): Failed to retrieve fcport "			    "information -- get_port_database=%x, "			    "loop_id=0x%04x\n",			    ha->host_no, rval2, new_fcport->loop_id));			continue;		}		/* Check for matching device in port list. */		found = 0;		fcport = NULL;		list_for_each_entry(fcport, &ha->fcports, list) {			if (memcmp(new_fcport->port_name, fcport->port_name,			    WWN_SIZE))				continue;			fcport->flags &= ~(FCF_FABRIC_DEVICE |			    FCF_PERSISTENT_BOUND);			fcport->loop_id = new_fcport->loop_id;			fcport->port_type = new_fcport->port_type;			fcport->d_id.b24 = new_fcport->d_id.b24;			memcpy(fcport->node_name, new_fcport->node_name,			    WWN_SIZE);			found++;			break;		}		if (!found) {			/* New device, add to fcports list. */			new_fcport->flags &= ~FCF_PERSISTENT_BOUND;			list_add_tail(&new_fcport->list, &ha->fcports);			/* Allocate a new replacement fcport. */			fcport = new_fcport;			new_fcport = qla2x00_alloc_fcport(ha, GFP_KERNEL);			if (new_fcport == NULL) {				rval = QLA_MEMORY_ALLOC_FAILED;				goto cleanup_allocation;			}			new_fcport->flags &= ~FCF_FABRIC_DEVICE;		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -