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

📄 mptbase.c

📁 上传linux-jx2410的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);		facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);		facts->FWVersion = le16_to_cpu(facts->FWVersion);		facts->ProductID = le16_to_cpu(facts->ProductID);		facts->CurrentHostMfaHighAddr =				le32_to_cpu(facts->CurrentHostMfaHighAddr);		facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);		facts->CurrentSenseBufferHighAddr =				le32_to_cpu(facts->CurrentSenseBufferHighAddr);		facts->CurReplyFrameSize =				le16_to_cpu(facts->CurReplyFrameSize);		/*		 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx		 * Older MPI-1.00.xx struct had 13 dwords, and enlarged		 * to 14 in MPI-1.01.0x.		 */		if (facts->MsgLength >= sizeof(IOCFactsReply_t)/sizeof(u32) && facts->MsgVersion > 0x0100) {			facts->FWImageSize = le32_to_cpu(facts->FWImageSize);			facts->DataImageSize = le32_to_cpu(facts->DataImageSize);		}		if (facts->RequestFrameSize) {			/*			 * Set values for this IOC's REQUEST queue size & depth...			 */			ioc->req_sz = MIN(MPT_REQ_SIZE, facts->RequestFrameSize * 4);			/*			 *  Set values for this IOC's REPLY queue size & depth...			 *			 * BUG? FIX?  20000516 -nromer & sralston 			 *  GRRR...  The following did not translate well from MPI v0.09:			 *	ioc->reply_sz = MIN(MPT_REPLY_SIZE, facts->ReplySize * 4);			 *  to 0.10:			 *	ioc->reply_sz = MIN(MPT_REPLY_SIZE, facts->BlockSize * 4);			 *  Was trying to minimally optimize to smallest possible reply size			 *  (and greatly reduce kmalloc size).  But LAN may need larger reply?			 *			 *  So for now, just set reply size to request size.  FIXME?			 */			ioc->reply_sz = ioc->req_sz;		} else {			/*  Something is wrong!  */			printk(KERN_ERR MYNAM ": %s: ERROR - IOC reported invalid 0 request size!\n",					ioc->name);			ioc->req_sz = MPT_REQ_SIZE;			ioc->reply_sz = MPT_REPLY_SIZE;			return -55;		}		ioc->req_depth = MIN(MPT_REQ_DEPTH, facts->GlobalCredits);		ioc->reply_depth = MIN(MPT_REPLY_DEPTH, facts->ReplyQueueDepth);		dprintk((KERN_INFO MYNAM ": %s: reply_sz=%3d, reply_depth=%4d\n",				ioc->name, ioc->reply_sz, ioc->reply_depth));		dprintk((KERN_INFO MYNAM ": %s: req_sz  =%3d, req_depth  =%4d\n",				ioc->name, ioc->req_sz, ioc->req_depth));		/* Get port facts! */		if ( (r = GetPortFacts(ioc, 0)) != 0 )			return r;	} else {		printk(KERN_ERR MYNAM ": %s: ERROR - Invalid IOC facts reply!\n",				ioc->name);		return -66;	}	return 0;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* *	GetPortFacts - Send PortFacts request to MPT adapter. *	@ioc: Pointer to MPT_ADAPTER structure *	@portnum: Port number * *	Returns 0 for success, non-zero for failure. */static intGetPortFacts(MPT_ADAPTER *ioc, int portnum){	PortFacts_t		 get_pfacts;	PortFactsReply_t	*pfacts;	int			 i;	int			 req_sz;	int			 reply_sz;	/* IOC *must* NOT be in RESET state! */	if (ioc->last_state == MPI_IOC_STATE_RESET) {		printk(KERN_ERR MYNAM ": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n",				ioc->name,				ioc->last_state );		return -4;	}	pfacts = &ioc->pfacts[portnum];	/* Destination (reply area)...  */	reply_sz = sizeof(*pfacts);	memset(pfacts, 0, reply_sz);	/* Request area (get_pfacts on the stack right now!) */	req_sz = sizeof(get_pfacts);	memset(&get_pfacts, 0, req_sz);	get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;	get_pfacts.PortNumber = portnum;	/* Assert: All other get_pfacts fields are zero! */	dprintk((KERN_INFO MYNAM ": %s: Sending get PortFacts(%d) request\n",			ioc->name, portnum));	/* No non-zero fields in the get_pfacts request are greater than	 * 1 byte in size, so we can just fire it off as is.	 */	i = HandShakeReqAndReply(ioc, req_sz, (u32*)&get_pfacts,				reply_sz, (u16*)pfacts, 3);	if (i != 0)		return i;	/* Did we get a valid reply? */	/* Now byte swap the necessary fields in the response. */	pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);	pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);	pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);	pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);	pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);	pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);	pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);	pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);	pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);	return 0;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* *	SendIocInit - Send IOCInit request to MPT adapter. *	@ioc: Pointer to MPT_ADAPTER structure * *	Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state. * *	Returns 0 for success, non-zero for failure. */static intSendIocInit(MPT_ADAPTER *ioc){	IOCInit_t		 ioc_init;	MPIDefaultReply_t	 init_reply;	u32			 state;	int			 r;	int			 count;	int			 cntdn;	memset(&ioc_init, 0, sizeof(ioc_init));	memset(&init_reply, 0, sizeof(init_reply));	ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;/*	ioc_init.ChainOffset = 0;			*/	ioc_init.Function = MPI_FUNCTION_IOC_INIT;/*	ioc_init.Flags = 0;				*/	/*ioc_init.MaxDevices = 16;*/	ioc_init.MaxDevices = 255;/*	ioc_init.MaxBuses = 16;				*/	ioc_init.MaxBuses = 1;/*	ioc_init.MsgFlags = 0;				*//*	ioc_init.MsgContext = cpu_to_le32(0x00000000);	*/	ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz);	/* in BYTES */	ioc_init.HostMfaHighAddr = cpu_to_le32(0);	/* Say we 32-bit! for now */	dprintk((KERN_INFO MYNAM ": %s: Sending IOCInit (req @ %p)\n", ioc->name, &ioc_init));	r = HandShakeReqAndReply(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,			sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10);	if (r != 0)		return r;	/* No need to byte swap the multibyte fields in the reply	 * since we don't even look at it's contents.	 */	if ((r = SendPortEnable(ioc, 0)) != 0)		return r;	/* YIKES!  SUPER IMPORTANT!!!	 *  Poll IocState until _OPERATIONAL while IOC is doing	 *  LoopInit and TargetDiscovery!	 */	count = 0;	cntdn = HZ * 60;					/* chg'd from 30 to 60 seconds */	state = GetIocState(ioc, 1);	while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {		current->state = TASK_INTERRUPTIBLE;		schedule_timeout(1);		if (!cntdn) {			printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_OP state timeout(%d)!\n",					ioc->name, (count+5)/HZ);			return -9;		}		state = GetIocState(ioc, 1);		count++;	}	dhsprintk((KERN_INFO MYNAM ": %s: INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",			ioc->name, count));	return r;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* *	SendPortEnable - Send PortEnable request to MPT adapter port. *	@ioc: Pointer to MPT_ADAPTER structure *	@portnum: Port number to enable * *	Send PortEnable to bring IOC to OPERATIONAL state. * *	Returns 0 for success, non-zero for failure. */static intSendPortEnable(MPT_ADAPTER *ioc, int portnum){	PortEnable_t		 port_enable;	MPIDefaultReply_t	 reply_buf;	int	 i;	int	 req_sz;	int	 reply_sz;	/*  Destination...  */	reply_sz = sizeof(MPIDefaultReply_t);	memset(&reply_buf, 0, reply_sz);	req_sz = sizeof(PortEnable_t);	memset(&port_enable, 0, req_sz);	port_enable.Function = MPI_FUNCTION_PORT_ENABLE;	port_enable.PortNumber = portnum;/*	port_enable.ChainOffset = 0;		*//*	port_enable.MsgFlags = 0;		*//*	port_enable.MsgContext = 0;		*/	dprintk((KERN_INFO MYNAM ": %s: Sending Port(%d)Enable (req @ %p)\n",			ioc->name, portnum, &port_enable));	i = HandShakeReqAndReply(ioc, req_sz, (u32*)&port_enable,			reply_sz, (u16*)&reply_buf, 65);	if (i != 0)		return i;	/* We do not even look at the reply, so we need not	 * swap the multi-byte fields.	 */	return 0;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* *	KickStart - Perform hard reset of MPT adapter. *	@ioc: Pointer to MPT_ADAPTER structure *	@force: Force hard reset * *	This routine places MPT adapter in diagnostic mode via the *	WriteSequence register, and then performs a hard reset of adapter *	via the Diagnostic register. * *	Returns 0 for soft reset success, 1 for hard reset success, *	else a negative value for failure. */static intKickStart(MPT_ADAPTER *ioc, int force){	int hard_reset_done = 0;	u32 ioc_state;	int cnt = 0;	dprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));	hard_reset_done = mpt_fc9x9_reset(ioc, force);#if 0	if (ioc->chip_type == FC909 || ioc->chip-type == FC919) {		hard_reset_done = mpt_fc9x9_reset(ioc, force);	} else if (ioc->chip_type == FC929) {		unsigned long delta;		delta = jiffies - ioc->last_kickstart;		dprintk((KERN_INFO MYNAM ": %s: 929 KickStart, last=%ld, delta = %ld\n",				ioc->name, ioc->last_kickstart, delta));		if ((ioc->sod_reset == 0) || (delta >= 10*HZ))			hard_reset_done = mpt_fc9x9_reset(ioc, ignore);		else {			dprintk((KERN_INFO MYNAM ": %s: Skipping KickStart (delta=%ld)!\n",					ioc->name, delta));			return 0;		}	/* TODO! Add C1030!	} else if (ioc->chip_type == C1030) {	 */	} else {		printk(KERN_ERR MYNAM ": %s: ERROR - Bad chip_type (0x%x)\n",				ioc->name, ioc->chip_type);		return -5;	}#endif	if (hard_reset_done < 0)		return hard_reset_done;	dprintk((KERN_INFO MYNAM ": %s: Diagnostic reset successful\n",			ioc->name));	for (cnt=0; cnt<HZ*20; cnt++) {		if ((ioc_state = GetIocState(ioc, 1)) == MPI_IOC_STATE_READY) {			dprintk((KERN_INFO MYNAM ": %s: KickStart successful! (cnt=%d)\n",					ioc->name, cnt));			return hard_reset_done;		}		/* udelay(10000) ? */		current->state = TASK_INTERRUPTIBLE;		schedule_timeout(1);	}	printk(KERN_ERR MYNAM ": %s: ERROR - Failed to come READY after reset!\n",			ioc->name);	return -1;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* *	mpt_fc9x9_reset - Perform hard reset of FC9x9 adapter. *	@ioc: Pointer to MPT_ADAPTER structure * *	This routine places FC9x9 adapter in diagnostic mode via the *	WriteSequence register, and then performs a hard reset of adapter *	via the Diagnostic register. * *	Returns 0 for success, non-zero for failure. */static intmpt_fc9x9_reset(MPT_ADAPTER *ioc, int ignore){	u32 diag0val;	int hard_reset_done = 0;	/* Use "Diagnostic reset" method! (only thing available!) */	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);#ifdef MPT_DEBUG{	u32 diag1val = 0;	if (ioc->alt_ioc)		diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);	dprintk((KERN_INFO MYNAM ": %s: DBG1: diag0=%08x, diag1=%08x\n",			ioc->name, diag0val, diag1val));}#endif	if (diag0val & MPI_DIAG_DRWE) {		dprintk((KERN_INFO MYNAM ": %s: DiagWriteEn bit already set\n",				ioc->name));	} else {		/* Write magic sequence to WriteSequence register */		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);		dprintk((KERN_INFO MYNAM ": %s: Wrote magic DiagWriteEn sequence [spot#1]\n",				ioc->name));	}	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);#ifdef MPT_DEBUG{	u32 diag1val = 0;	if (ioc->alt_ioc)		diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);	dprintk((KERN_INFO MYNAM ": %s: DbG2: diag0=%08x, diag1=%08x\n",			ioc->name, diag0val, diag1val));}#endif	if (!ignore && (diag0val & MPI_DIAG_RESET_HISTORY)) {		dprintk((KERN_INFO MYNAM ": %s: Skipping due to ResetHistory bit set!\n",				ioc->name));	} else {		/*		 * Now hit the reset bit in the Diagnostic register		 * (THE BIG HAMMER!)		 */		CHIPREG_WRITE32(&ioc->chip->Diagnostic, MPI_DIAG_RESET_ADAPTER);		hard_reset_done = 1;		dprintk((KERN_INFO MYNAM ": %s: Diagnostic reset performed\n",				ioc->name));		/* want udelay(100) */		current->state = TASK_INTERRUPTIBLE;		schedule_timeout(1);		/* Write magic sequence to WriteSequence register */		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);		dprintk((KERN_INFO MYNAM ": %s: Wrote magic DiagWriteEn sequence [spot#2]\n",				ioc->name));	}	/* Clear RESET_HISTORY bit! */	CHIPREG_WRITE32(&ioc->chip->Diagnostic, 0x0);	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);#ifdef MPT_DEBUG{	u32 diag1val = 0;	if (ioc->alt_ioc)		diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);	dprintk((KERN_INFO MYNAM ": %s: DbG3: diag0=%08x, diag1=%08x\n",			ioc->name, diag0val, diag1val));}#endif	if (diag0val & MPI_DIAG_RESET_HISTORY) {		printk(KERN_WARNING MYNAM ": %s: WARNING - ResetHistory bit failed to clear!\n",				ioc->name);	}	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);#ifdef MPT_DEBUG{	u32 diag1val = 0;	if (ioc->alt_ioc)		diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);	dprintk((KERN_INFO MYNAM ": %s: DbG4: diag0=%08x, diag1=%08x\n",			ioc->name, diag0val, diag1val));}#endif	if (diag0val & (MPI_DIAG_FLASH_BAD_

⌨️ 快捷键说明

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