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

📄 qla_init.c

📁 h内核
💻 C
📖 第 1 页 / 共 5 页
字号:
	if ((wait_time = (ha->retry_count*ha->login_timeout) + 5) < min_wait) {		wait_time = min_wait;	}	/* Min wait time if loop down */	mtime = jiffies + (min_wait * HZ);	/* wait time before firmware ready */	wtime = jiffies + (wait_time * HZ);	/* Wait for ISP to finish LIP */	if (!ha->flags.init_done) 		qla_printk(KERN_INFO, ha, "Waiting for LIP to complete...\n");	DEBUG3(printk("scsi(%ld): Waiting for LIP to complete...\n",	    ha->host_no));	do {		rval = qla2x00_get_firmware_state(ha, &fw_state);		if (rval == QLA_SUCCESS) {			if (fw_state < FSTATE_LOSS_OF_SYNC) {				ha->device_flags &= ~DFLG_NO_CABLE;			}			if (fw_state == FSTATE_READY) {				DEBUG(printk("scsi(%ld): F/W Ready - OK \n",				    ha->host_no));				qla2x00_get_retry_cnt(ha, &ha->retry_count,				    &ha->login_timeout, &ha->r_a_tov);				rval = QLA_SUCCESS;				break;			}			rval = QLA_FUNCTION_FAILED;			if (atomic_read(&ha->loop_down_timer) &&			    (fw_state >= FSTATE_LOSS_OF_SYNC ||				fw_state == FSTATE_WAIT_AL_PA)) {				/* Loop down. Timeout on min_wait for states				 * other than Wait for Login. 				 */					if (time_after_eq(jiffies, mtime)) {					qla_printk(KERN_INFO, ha,					    "Cable is unplugged...\n");					ha->device_flags |= DFLG_NO_CABLE;					break;				}			}		} else {			/* Mailbox cmd failed. Timeout on min_wait. */			if (time_after_eq(jiffies, mtime))				break;		}		if (time_after_eq(jiffies, wtime))			break;		/* Delay for a while */		msleep(500);		DEBUG3(printk("scsi(%ld): fw_state=%x curr time=%lx.\n",		    ha->host_no, fw_state, jiffies));	} while (1);	DEBUG(printk("scsi(%ld): fw_state=%x curr time=%lx.\n",	    ha->host_no, fw_state, jiffies));	if (rval) {		DEBUG2_3(printk("scsi(%ld): Firmware ready **** FAILED ****.\n",		    ha->host_no));	}	return (rval);}/**  qla2x00_configure_hba*      Setup adapter context.** Input:*      ha = adapter state pointer.** Returns:*      0 = success** Context:*      Kernel context.*/static intqla2x00_configure_hba(scsi_qla_host_t *ha){	int       rval;	uint16_t      loop_id;	uint16_t      topo;	uint8_t       al_pa;	uint8_t       area;	uint8_t       domain;	char		connect_type[22];	/* Get host addresses. */	rval = qla2x00_get_adapter_id(ha,	    &loop_id, &al_pa, &area, &domain, &topo);	if (rval != QLA_SUCCESS) {		qla_printk(KERN_WARNING, ha,		    "ERROR -- Unable to get host loop ID.\n");		set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);		return (rval);	}	if (topo == 4) {		qla_printk(KERN_INFO, ha,			"Cannot get topology - retrying.\n");		return (QLA_FUNCTION_FAILED);	}	ha->loop_id = loop_id;	/* initialize */	ha->min_external_loopid = SNS_FIRST_LOOP_ID;	ha->operating_mode = LOOP;	switch (topo) {	case 0:		DEBUG3(printk("scsi(%ld): HBA in NL topology.\n",		    ha->host_no));		ha->current_topology = ISP_CFG_NL;		strcpy(connect_type, "(Loop)");		break;	case 1:		DEBUG3(printk("scsi(%ld): HBA in FL topology.\n",		    ha->host_no));		ha->current_topology = ISP_CFG_FL;		strcpy(connect_type, "(FL_Port)");		break;	case 2:		DEBUG3(printk("scsi(%ld): HBA in N P2P topology.\n",		    ha->host_no));		ha->operating_mode = P2P;		ha->current_topology = ISP_CFG_N;		strcpy(connect_type, "(N_Port-to-N_Port)");		break;	case 3:		DEBUG3(printk("scsi(%ld): HBA in F P2P topology.\n",		    ha->host_no));		ha->operating_mode = P2P;		ha->current_topology = ISP_CFG_F;		strcpy(connect_type, "(F_Port)");		break;	default:		DEBUG3(printk("scsi(%ld): HBA in unknown topology %x. "		    "Using NL.\n",		    ha->host_no, topo));		ha->current_topology = ISP_CFG_NL;		strcpy(connect_type, "(Loop)");		break;	}	/* Save Host port and loop ID. */	/* byte order - Big Endian */	ha->d_id.b.domain = domain;	ha->d_id.b.area = area;	ha->d_id.b.al_pa = al_pa;	if (!ha->flags.init_done) 		qla_printk(KERN_INFO, ha,		    "Topology - %s, Host Loop address 0x%x\n", 		    connect_type, ha->loop_id);	if (rval) {		DEBUG2_3(printk("scsi(%ld): FAILED.\n", ha->host_no));	} else {		DEBUG3(printk("scsi(%ld): exiting normally.\n", ha->host_no));	}	return(rval);}/** NVRAM configuration for ISP 2xxx** Input:*      ha                = adapter block pointer.** Output:*      initialization control block in response_ring*      host adapters parameters in host adapter block** Returns:*      0 = success.*/static intqla2x00_nvram_config(scsi_qla_host_t *ha){	int   rval;	uint8_t   chksum = 0;	uint16_t  cnt;	uint8_t   *dptr1, *dptr2;	init_cb_t *icb   = ha->init_cb;	nvram_t *nv    = (nvram_t *)ha->request_ring;	uint16_t  *wptr  = (uint16_t *)ha->request_ring;	device_reg_t __iomem *reg = ha->iobase;	uint8_t  timer_mode;	rval = QLA_SUCCESS;	/* Determine NVRAM starting address. */	ha->nvram_base = 0;	if (!IS_QLA2100(ha) && !IS_QLA2200(ha) && !IS_QLA2300(ha))		if ((RD_REG_WORD(&reg->ctrl_status) >> 14) == 1)			ha->nvram_base = 0x80;	/* Get NVRAM data and calculate checksum. */	qla2x00_lock_nvram_access(ha);	for (cnt = 0; cnt < sizeof(nvram_t)/2; cnt++) {		*wptr = cpu_to_le16(qla2x00_get_nvram_word(ha,		    (cnt+ha->nvram_base)));		chksum += (uint8_t)*wptr;		chksum += (uint8_t)(*wptr >> 8);		wptr++;	}	qla2x00_unlock_nvram_access(ha);	DEBUG5(printk("scsi(%ld): Contents of NVRAM\n", ha->host_no));	DEBUG5(qla2x00_dump_buffer((uint8_t *)ha->request_ring,	    sizeof(nvram_t)));	/* Bad NVRAM data, set defaults parameters. */	if (chksum || nv->id[0] != 'I' || nv->id[1] != 'S' ||	    nv->id[2] != 'P' || nv->id[3] != ' ' || nv->nvram_version < 1) {		/* Reset NVRAM data. */		qla_printk(KERN_WARNING, ha, "Inconsistent NVRAM detected: "		    "checksum=0x%x id=%c version=0x%x.\n", chksum, nv->id[0],		    nv->nvram_version);		qla_printk(KERN_WARNING, ha, "Falling back to functioning (yet "		    "invalid -- WWPN) defaults.\n");		/*		 * Set default initialization control block.		 */		memset(nv, 0, sizeof(nvram_t));		nv->parameter_block_version = ICB_VERSION;		if (IS_QLA23XX(ha)) {			nv->firmware_options[0] = BIT_2 | BIT_1;			nv->firmware_options[1] = BIT_7 | BIT_5;			nv->add_firmware_options[0] = BIT_5;			nv->add_firmware_options[1] = BIT_5 | BIT_4;			nv->frame_payload_size = __constant_cpu_to_le16(2048);			nv->special_options[1] = BIT_7;		} else if (IS_QLA2200(ha)) {			nv->firmware_options[0] = BIT_2 | BIT_1;			nv->firmware_options[1] = BIT_7 | BIT_5;			nv->add_firmware_options[0] = BIT_5;			nv->add_firmware_options[1] = BIT_5 | BIT_4;			nv->frame_payload_size = __constant_cpu_to_le16(1024);		} else if (IS_QLA2100(ha)) {			nv->firmware_options[0] = BIT_3 | BIT_1;			nv->firmware_options[1] = BIT_5;			nv->frame_payload_size = __constant_cpu_to_le16(1024);		}		nv->max_iocb_allocation = __constant_cpu_to_le16(256);		nv->execution_throttle = __constant_cpu_to_le16(16);		nv->retry_count = 8;		nv->retry_delay = 1;		nv->port_name[0] = 33;		nv->port_name[3] = 224;		nv->port_name[4] = 139;		nv->login_timeout = 4;		/*		 * Set default host adapter parameters		 */		nv->host_p[1] = BIT_2;		nv->reset_delay = 5;		nv->port_down_retry_count = 8;		nv->max_luns_per_target = __constant_cpu_to_le16(8);		nv->link_down_timeout = 60;		rval = 1;	}#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)	/*	 * The SN2 does not provide BIOS emulation which means you can't change	 * potentially bogus BIOS settings. Force the use of default settings	 * for link rate and frame size.  Hope that the rest of the settings	 * are valid.	 */	if (ia64_platform_is("sn2")) {		nv->frame_payload_size = __constant_cpu_to_le16(2048);		if (IS_QLA23XX(ha))			nv->special_options[1] = BIT_7;	}#endif	/* Reset Initialization control block */	memset(icb, 0, sizeof(init_cb_t));	/*	 * Setup driver NVRAM options.	 */	nv->firmware_options[0] |= (BIT_6 | BIT_1);	nv->firmware_options[0] &= ~(BIT_5 | BIT_4);	nv->firmware_options[1] |= (BIT_5 | BIT_0);	nv->firmware_options[1] &= ~BIT_4;	if (IS_QLA23XX(ha)) {		nv->firmware_options[0] |= BIT_2;		nv->firmware_options[0] &= ~BIT_3;		if (IS_QLA2300(ha)) {			if (ha->fb_rev == FPM_2310) {				strcpy(ha->model_number, "QLA2310");			} else {				strcpy(ha->model_number, "QLA2300");			}		} else {			if (rval == 0 &&			    memcmp(nv->model_number, BINZERO,				    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->nvram_version = nv->nvram_version;	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->efi_parameters & BIT_3) ? 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];	memcpy(ha->node_name, icb->node_name, WWN_SIZE);	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->minimum_timeout =	    (ha->login_timeout * ha->retry_count) + nv->port_down_retry_count;	ha->loop_reset_delay = nv->reset_delay;	/* Will get the value from NVRAM. */	ha->loop_down_timeout = LOOP_DOWN_TIMEOUT;	/* 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 - ha->loop_down_timeout);	} else {		ha->link_down_timeout =	 nv->link_down_timeout;		ha->loop_down_abort_time =		    (LOOP_DOWN_TIME - ha->link_down_timeout);	} 	ha->max_luns = MAX_LUNS;	ha->max_probe_luns = le16_to_cpu(nv->max_luns_per_target);	if (ha->max_probe_luns == 0)		ha->max_probe_luns = MIN_LUNS;	/*	 * 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;	ha->binding_type = Bind;	if (ha->binding_type != BIND_BY_PORT_NAME &&	    ha->binding_type != BIND_BY_PORT_ID) {		qla_printk(KERN_WARNING, ha,		    "Invalid binding type specified (%d), "		    "defaulting to BIND_BY_PORT_NAME!!!\n", ha->binding_type);		ha->binding_type = BIND_BY_PORT_NAME;	}	icb->lun_enables = __constant_cpu_to_le16(0);	icb->command_resource_count = 0;	icb->immediate_notify_resource_count = 0;

⌨️ 快捷键说明

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