diff options
| author | Kashyap, Desai <kashyap.desai@lsi.com> | 2009-05-29 16:40:57 +0530 | 
|---|---|---|
| committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2009-06-09 17:26:20 -0500 | 
| commit | f0f09d3b3f06900d64971625d6753dea0623ed45 (patch) | |
| tree | 896237d53275eeb6b4484c2cb747f0b333157c30 /drivers/message/fusion/mptbase.c | |
| parent | fd76175a7d3abf4d14df17f5f4c7e68b466b455d (diff) | |
| download | olio-linux-3.10-f0f09d3b3f06900d64971625d6753dea0623ed45.tar.xz olio-linux-3.10-f0f09d3b3f06900d64971625d6753dea0623ed45.zip  | |
[SCSI] mpt fusion: config path optimized, completion queue is used
1) 	Previously we had mutliple #defines to use same values.
	Now those #defines are optimized.
	MPT_IOCTL_STATUS_* is removed and  MPT_MGMT_STATUS_* are new
	#defines.
2.)	config path is optimized.
	Instead of wait Queue and timer, using completion Q.
3.)	mpt_timer_expired is not used.
[jejb: elide patch to eliminate mpt_timer_expired]
Signed-off-by: Kashyap Desai <kadesai@lsi.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/message/fusion/mptbase.c')
| -rw-r--r-- | drivers/message/fusion/mptbase.c | 456 | 
1 files changed, 215 insertions, 241 deletions
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 0d2fb0eb34b..e63a6260b0a 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -146,7 +146,6 @@ static MPT_EVHANDLER		 MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];  static MPT_RESETHANDLER		 MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];  static struct mpt_pci_driver 	*MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS]; -static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq);  /*   *  Driver Callback Index's @@ -159,7 +158,8 @@ static u8 last_drv_idx;   *  Forward protos...   */  static irqreturn_t mpt_interrupt(int irq, void *bus_id); -static int	mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply); +static int	mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, +		MPT_FRAME_HDR *reply);  static int	mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,  			u32 *req, int replyBytes, u16 *u16reply, int maxwait,  			int sleepFlag); @@ -190,7 +190,6 @@ static int	mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);  static int	mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);  static void 	mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);  static void 	mpt_read_ioc_pg_4(MPT_ADAPTER *ioc); -static void	mpt_timer_expired(unsigned long data);  static void	mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc);  static int	SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch,  	int sleepFlag); @@ -559,9 +558,9 @@ mpt_interrupt(int irq, void *bus_id)  /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/  /** - *	mpt_base_reply - MPT base driver's callback routine + *	mptbase_reply - MPT base driver's callback routine   *	@ioc: Pointer to MPT_ADAPTER structure - *	@mf: Pointer to original MPT request frame + *	@req: Pointer to original MPT request frame   *	@reply: Pointer to MPT reply frame (NULL if TurboReply)   *   *	MPT base driver's callback routine; all base driver @@ -572,122 +571,49 @@ mpt_interrupt(int irq, void *bus_id)   *	should be freed, or 0 if it shouldn't.   */  static int -mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply) +mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)  { +	EventNotificationReply_t *pEventReply; +	u8 event; +	int evHandlers;  	int freereq = 1; -	u8 func; - -	dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply() called\n", ioc->name)); -#ifdef CONFIG_FUSION_LOGGING -	if ((ioc->debug_level & MPT_DEBUG_MSG_FRAME) && -			!(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) { -		dmfprintk(ioc, printk(MYIOC_s_INFO_FMT ": Original request frame (@%p) header\n", -		    ioc->name, mf)); -		DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)mf); -	} -#endif - -	func = reply->u.hdr.Function; -	dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply, Function=%02Xh\n", -			ioc->name, func)); - -	if (func == MPI_FUNCTION_EVENT_NOTIFICATION) { -		EventNotificationReply_t *pEvReply = (EventNotificationReply_t *) reply; -		int evHandlers = 0; -		int results; - -		results = ProcessEventNotification(ioc, pEvReply, &evHandlers); -		if (results != evHandlers) { -			/* CHECKME! Any special handling needed here? */ -			devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n", -					ioc->name, evHandlers, results)); -		} -		/* -		 *	Hmmm...  It seems that EventNotificationReply is an exception -		 *	to the rule of one reply per request. -		 */ -		if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) { +	switch (reply->u.hdr.Function) { +	case MPI_FUNCTION_EVENT_NOTIFICATION: +		pEventReply = (EventNotificationReply_t *)reply; +		evHandlers = 0; +		ProcessEventNotification(ioc, pEventReply, &evHandlers); +		event = le32_to_cpu(pEventReply->Event) & 0xFF; +		if (pEventReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)  			freereq = 0; -		} else { -			devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n", -				ioc->name, pEvReply)); -		} - -#ifdef CONFIG_PROC_FS -//		LogEvent(ioc, pEvReply); -#endif - -	} else if (func == MPI_FUNCTION_EVENT_ACK) { -		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply, EventAck reply received\n", -				ioc->name)); -	} else if (func == MPI_FUNCTION_CONFIG) { -		CONFIGPARMS *pCfg; -		unsigned long flags; - -		dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "config_complete (mf=%p,mr=%p)\n", -				ioc->name, mf, reply)); - -		pCfg = * ((CONFIGPARMS **)((u8 *) mf + ioc->req_sz - sizeof(void *))); - -		if (pCfg) { -			/* disable timer and remove from linked list */ -			del_timer(&pCfg->timer); - -			spin_lock_irqsave(&ioc->FreeQlock, flags); -			list_del(&pCfg->linkage); -			spin_unlock_irqrestore(&ioc->FreeQlock, flags); - -			/* -			 *	If IOC Status is SUCCESS, save the header -			 *	and set the status code to GOOD. -			 */ -			pCfg->status = MPT_CONFIG_ERROR; -			if (reply) { -				ConfigReply_t	*pReply = (ConfigReply_t *)reply; -				u16		 status; - -				status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK; -				dcprintk(ioc, printk(MYIOC_s_NOTE_FMT "  IOCStatus=%04xh, IOCLogInfo=%08xh\n", -				     ioc->name, status, le32_to_cpu(pReply->IOCLogInfo))); - -				pCfg->status = status; -				if (status == MPI_IOCSTATUS_SUCCESS) { -					if ((pReply->Header.PageType & -					    MPI_CONFIG_PAGETYPE_MASK) == -					    MPI_CONFIG_PAGETYPE_EXTENDED) { -						pCfg->cfghdr.ehdr->ExtPageLength = -						    le16_to_cpu(pReply->ExtPageLength); -						pCfg->cfghdr.ehdr->ExtPageType = -						    pReply->ExtPageType; -					} -					pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion; - -					/* If this is a regular header, save PageLength. */ -					/* LMP Do this better so not using a reserved field! */ -					pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength; -					pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber; -					pCfg->cfghdr.hdr->PageType = pReply->Header.PageType; -				} -			} - -			/* -			 *	Wake up the original calling thread -			 */ -			pCfg->wait_done = 1; -			wake_up(&mpt_waitq); +		if (event != MPI_EVENT_EVENT_CHANGE) +			break; +	case MPI_FUNCTION_CONFIG: +	case MPI_FUNCTION_SAS_IO_UNIT_CONTROL: +		ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD; +		if (reply) { +			ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_RF_VALID; +			memcpy(ioc->mptbase_cmds.reply, reply, +			    min(MPT_DEFAULT_FRAME_SIZE, +				4 * reply->u.reply.MsgLength));  		} -	} else if (func == MPI_FUNCTION_SAS_IO_UNIT_CONTROL) { -		/* we should be always getting a reply frame */ -		memcpy(ioc->persist_reply_frame, reply, -		    min(MPT_DEFAULT_FRAME_SIZE, -		    4*reply->u.reply.MsgLength)); -		del_timer(&ioc->persist_timer); -		ioc->persist_wait_done = 1; -		wake_up(&mpt_waitq); -	} else { -		printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n", -				ioc->name, func); +		if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) { +			ioc->mptbase_cmds.status &= ~MPT_MGMT_STATUS_PENDING; +			complete(&ioc->mptbase_cmds.done); +		} else +			freereq = 0; +		if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_FREE_MF) +			freereq = 1; +		break; +	case MPI_FUNCTION_EVENT_ACK: +		devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT +		    "EventAck reply received\n", ioc->name)); +		break; +	default: +		printk(MYIOC_s_ERR_FMT +		    "Unexpected msg function (=%02Xh) reply received!\n", +		    ioc->name, reply->u.hdr.Function); +		break;  	}  	/* @@ -1849,6 +1775,9 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)  	spin_lock_init(&ioc->diagLock);  	spin_lock_init(&ioc->initializing_hba_lock); +	mutex_init(&ioc->mptbase_cmds.mutex); +	init_completion(&ioc->mptbase_cmds.done); +  	/* Initialize the event logging.  	 */  	ioc->eventTypes = 0;	/* None */ @@ -1866,10 +1795,6 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)  	 */  	memset(&ioc->spi_data, 0, sizeof(SpiCfgData)); -	/* Initialize the running configQ head. -	 */ -	INIT_LIST_HEAD(&ioc->configQ); -  	/* Initialize the fc rport list head.  	 */  	INIT_LIST_HEAD(&ioc->fc_rports); @@ -5013,7 +4938,14 @@ mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)  	SasIoUnitControlReply_t		*sasIoUnitCntrReply;  	MPT_FRAME_HDR			*mf = NULL;  	MPIHeader_t			*mpi_hdr; +	int				ret = 0; +	unsigned long 	 		timeleft; +	mutex_lock(&ioc->mptbase_cmds.mutex); + +	/* init the internal cmd struct */ +	memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE); +	INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status)  	/* insure garbage is not sent to fw */  	switch(persist_opcode) { @@ -5023,17 +4955,19 @@ mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)  		break;  	default: -		return -1; -		break; +		ret = -1; +		goto out;  	} -	printk("%s: persist_opcode=%x\n",__func__, persist_opcode); +	printk(KERN_DEBUG  "%s: persist_opcode=%x\n", +		__func__, persist_opcode);  	/* Get a MF for this command.  	 */  	if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) { -		printk("%s: no msg frames!\n",__func__); -		return -1; +		printk(KERN_DEBUG "%s: no msg frames!\n", __func__); +		ret = -1; +		goto out;          }  	mpi_hdr = (MPIHeader_t *) mf; @@ -5043,27 +4977,42 @@ mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)  	sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;  	sasIoUnitCntrReq->Operation = persist_opcode; -	init_timer(&ioc->persist_timer); -	ioc->persist_timer.data = (unsigned long) ioc; -	ioc->persist_timer.function = mpt_timer_expired; -	ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */; -	ioc->persist_wait_done=0; -	add_timer(&ioc->persist_timer);  	mpt_put_msg_frame(mpt_base_index, ioc, mf); -	wait_event(mpt_waitq, ioc->persist_wait_done); +	timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done, 10*HZ); +	if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) { +		ret = -ETIME; +		printk(KERN_DEBUG "%s: failed\n", __func__); +		if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) +			goto out; +		if (!timeleft) { +			printk(KERN_DEBUG "%s: Issuing Reset from %s!!\n", +			    ioc->name, __func__); +			mpt_HardResetHandler(ioc, CAN_SLEEP); +			mpt_free_msg_frame(ioc, mf); +		} +		goto out; +	} + +	if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) { +		ret = -1; +		goto out; +	}  	sasIoUnitCntrReply = -	    (SasIoUnitControlReply_t *)ioc->persist_reply_frame; +	    (SasIoUnitControlReply_t *)ioc->mptbase_cmds.reply;  	if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) { -		printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n", -		    __func__, -		    sasIoUnitCntrReply->IOCStatus, +		printk(KERN_DEBUG "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n", +		    __func__, sasIoUnitCntrReply->IOCStatus,  		    sasIoUnitCntrReply->IOCLogInfo); -		return -1; -	} +		printk(KERN_DEBUG "%s: failed\n", __func__); +		ret = -1; +	} else +		printk(KERN_DEBUG "%s: success\n", __func__); + out: -	printk("%s: success\n",__func__); -	return 0; +	CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status) +	mutex_unlock(&ioc->mptbase_cmds.mutex); +	return ret;  }  /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ @@ -6066,7 +6015,7 @@ SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)  	if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {  		dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n", -		    ioc->name,__func__)); +		    ioc->name, __func__));  		return -1;  	} @@ -6103,12 +6052,18 @@ int  mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)  {  	Config_t	*pReq; +	ConfigReply_t	*pReply;  	ConfigExtendedPageHeader_t  *pExtHdr = NULL;  	MPT_FRAME_HDR	*mf; -	unsigned long	 flags; -	int		 ii, rc; +	int		 ii;  	int		 flagsLength; +	long		 timeout; +	int		 ret; +	u8		 page_type = 0, extend_page; +	unsigned long 	 timeleft;  	int		 in_isr; +	u8		 issue_hard_reset = 0; +	u8		 retry_count = 0;  	/*	Prevent calling wait_event() (below), if caller happens  	 *	to be in ISR context, because that is fatal! @@ -6120,13 +6075,31 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)  		return -EPERM;  	} +	/* don't send if no chance of success */ +	if (!ioc->active || +	    mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_OPERATIONAL) { +		dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT +		    "%s: ioc not operational, %d, %xh\n", +		    ioc->name, __func__, ioc->active, +		    mpt_GetIocState(ioc, 0))); +		return -EFAULT; +	} + + retry_config: +	mutex_lock(&ioc->mptbase_cmds.mutex); +	/* init the internal cmd struct */ +	memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE); +	INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status) +  	/* Get and Populate a free Frame  	 */  	if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) { -		dcprintk(ioc, printk(MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n", -				ioc->name)); -		return -EAGAIN; +		dcprintk(ioc, printk(MYIOC_s_WARN_FMT +		"mpt_config: no msg frames!\n", ioc->name)); +		ret = -EAGAIN; +		goto out;  	} +  	pReq = (Config_t *)mf;  	pReq->Action = pCfg->action;  	pReq->Reserved = 0; @@ -6152,7 +6125,9 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)  		pReq->ExtPageType = pExtHdr->ExtPageType;  		pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED; -		/* Page Length must be treated as a reserved field for the extended header. */ +		/* Page Length must be treated as a reserved field for the +		 * extended header. +		 */  		pReq->Header.PageLength = 0;  	} @@ -6165,78 +6140,91 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)  	else  		flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ; -	if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) { +	if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == +	    MPI_CONFIG_PAGETYPE_EXTENDED) {  		flagsLength |= pExtHdr->ExtPageLength * 4; - -		dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n", -			ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action)); -	} -	else { +		page_type = pReq->ExtPageType; +		extend_page = 1; +	} else {  		flagsLength |= pCfg->cfghdr.hdr->PageLength * 4; - -		dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n", -			ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action)); +		page_type = pReq->Header.PageType; +		extend_page = 0;  	} -	ioc->add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr); +	dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT +	    "Sending Config request type 0x%x, page 0x%x and action %d\n", +	    ioc->name, page_type, pReq->Header.PageNumber, pReq->Action)); -	/* Append pCfg pointer to end of mf -	 */ -	*((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) =  (void *) pCfg; - -	/* Initalize the timer -	 */ -	init_timer_on_stack(&pCfg->timer); -	pCfg->timer.data = (unsigned long) ioc; -	pCfg->timer.function = mpt_timer_expired; -	pCfg->wait_done = 0; - -	/* Set the timer; ensure 10 second minimum */ -	if (pCfg->timeout < 10) -		pCfg->timer.expires = jiffies + HZ*10; -	else -		pCfg->timer.expires = jiffies + HZ*pCfg->timeout; - -	/* Add to end of Q, set timer and then issue this command */ -	spin_lock_irqsave(&ioc->FreeQlock, flags); -	list_add_tail(&pCfg->linkage, &ioc->configQ); -	spin_unlock_irqrestore(&ioc->FreeQlock, flags); - -	add_timer(&pCfg->timer); +	ioc->add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr); +	timeout = (pCfg->timeout < 15) ? HZ*15 : HZ*pCfg->timeout;  	mpt_put_msg_frame(mpt_base_index, ioc, mf); -	wait_event(mpt_waitq, pCfg->wait_done); - -	/* mf has been freed - do not access */ +	timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done, +		timeout); +	if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) { +		ret = -ETIME; +		dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT +		    "Failed Sending Config request type 0x%x, page 0x%x," +		    " action %d, status %xh, time left %ld\n\n", +			ioc->name, page_type, pReq->Header.PageNumber, +			pReq->Action, ioc->mptbase_cmds.status, timeleft)); +		if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) +			goto out; +		if (!timeleft) +			issue_hard_reset = 1; +		goto out; +	} -	rc = pCfg->status; +	if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) { +		ret = -1; +		goto out; +	} +	pReply = (ConfigReply_t	*)ioc->mptbase_cmds.reply; +	ret = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK; +	if (ret == MPI_IOCSTATUS_SUCCESS) { +		if (extend_page) { +			pCfg->cfghdr.ehdr->ExtPageLength = +			    le16_to_cpu(pReply->ExtPageLength); +			pCfg->cfghdr.ehdr->ExtPageType = +			    pReply->ExtPageType; +		} +		pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion; +		pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength; +		pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber; +		pCfg->cfghdr.hdr->PageType = pReply->Header.PageType; -	return rc; -} +	} -/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -/** - *	mpt_timer_expired - Callback for timer process. - *	Used only internal config functionality. - *	@data: Pointer to MPT_SCSI_HOST recast as an unsigned long - */ -static void -mpt_timer_expired(unsigned long data) -{ -	MPT_ADAPTER *ioc = (MPT_ADAPTER *) data; +	if (retry_count) +		printk(MYIOC_s_INFO_FMT "Retry completed " +		    "ret=0x%x timeleft=%ld\n", +		    ioc->name, ret, timeleft); -	dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired! \n", ioc->name)); +	dcprintk(ioc, printk(KERN_DEBUG "IOCStatus=%04xh, IOCLogInfo=%08xh\n", +	     ret, le32_to_cpu(pReply->IOCLogInfo))); -	/* Perform a FW reload */ -	if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) -		printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name); +out: -	/* No more processing. -	 * Hard reset clean-up will wake up -	 * process and free all resources. -	 */ -	dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired complete!\n", ioc->name)); +	CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status) +	mutex_unlock(&ioc->mptbase_cmds.mutex); +	if (issue_hard_reset) { +		issue_hard_reset = 0; +		printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n", +		    ioc->name, __func__); +		mpt_HardResetHandler(ioc, CAN_SLEEP); +		mpt_free_msg_frame(ioc, mf); +		/* attempt one retry for a timed out command */ +		if (!retry_count) { +			printk(MYIOC_s_INFO_FMT +			    "Attempting Retry Config request" +			    " type 0x%x, page 0x%x," +			    " action %d\n", ioc->name, page_type, +			    pCfg->cfghdr.hdr->PageNumber, pCfg->action); +			retry_count++; +			goto retry_config; +		} +	} +	return ret; -	return;  }  /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ @@ -6250,41 +6238,27 @@ mpt_timer_expired(unsigned long data)  static int  mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)  { -	CONFIGPARMS *pCfg; -	unsigned long flags; - -	dprintk(ioc, printk(MYIOC_s_DEBUG_FMT -	    ": IOC %s_reset routed to MPT base driver!\n", -	    ioc->name, reset_phase==MPT_IOC_SETUP_RESET ? "setup" : ( -	    reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"))); - -	if (reset_phase == MPT_IOC_SETUP_RESET) { -		; -	} else if (reset_phase == MPT_IOC_PRE_RESET) { -		/* If the internal config Q is not empty - -		 * delete timer. MF resources will be freed when -		 * the FIFO's are primed. -		 */ -		spin_lock_irqsave(&ioc->FreeQlock, flags); -		list_for_each_entry(pCfg, &ioc->configQ, linkage) -			del_timer(&pCfg->timer); -		spin_unlock_irqrestore(&ioc->FreeQlock, flags); - -	} else { -		CONFIGPARMS *pNext; - -		/* Search the configQ for internal commands. -		 * Flush the Q, and wake up all suspended threads. -		 */ -		spin_lock_irqsave(&ioc->FreeQlock, flags); -		list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) { -			list_del(&pCfg->linkage); - -			pCfg->status = MPT_CONFIG_ERROR; -			pCfg->wait_done = 1; -			wake_up(&mpt_waitq); +	switch (reset_phase) { +	case MPT_IOC_SETUP_RESET: +		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT +		    "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__)); +		break; +	case MPT_IOC_PRE_RESET: +		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT +		    "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__)); +		break; +	case MPT_IOC_POST_RESET: +		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT +		    "%s: MPT_IOC_POST_RESET\n",  ioc->name, __func__)); +/* wake up mptbase_cmds */ +		if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) { +			ioc->mptbase_cmds.status |= +			    MPT_MGMT_STATUS_DID_IOCRESET; +			complete(&ioc->mptbase_cmds.done);  		} -		spin_unlock_irqrestore(&ioc->FreeQlock, flags); +		break; +	default: +		break;  	}  	return 1;		/* currently means nothing really */ @@ -7901,7 +7875,7 @@ fusion_init(void)  	/*  Register ourselves (mptbase) in order to facilitate  	 *  EventNotification handling.  	 */ -	mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER); +	mpt_base_index = mpt_register(mptbase_reply, MPTBASE_DRIVER);  	/* Register for hard reset handling callbacks.  	 */  |