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

📄 mptbase.c

📁 上传linux-jx2410的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
					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)			freereq = 0;#ifdef CONFIG_PROC_FS//		LogEvent(ioc, pEvReply);#endif	} else if (func == MPI_FUNCTION_EVENT_ACK) {		dprintk((KERN_INFO MYNAM ": %s: mpt_base_reply, EventAck reply received\n",				ioc->name));	} else {		printk(KERN_ERR MYNAM ": %s: ERROR - Unexpected msg function (=%02Xh) reply received!\n",				ioc->name, func);	}	/*	 *  Conditionally tell caller to free the original	 *  EventNotification/EventAck/unexpected request frame!	 */	return freereq;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	mpt_register - Register protocol-specific main callback handler. *	@cbfunc: callback function pointer *	@dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value) * *	This routine is called by a protocol-specific driver (SCSI host, *	LAN, SCSI target) to register it's reply callback routine.  Each *	protocol-specific driver must do this before it will be able to *	use any IOC resources, such as obtaining request frames. * *	NOTES: The SCSI protocol driver currently calls this routine twice *	in order to register separate callbacks; one for "normal" SCSI IO *	and another for MptScsiTaskMgmt requests. * *	Returns a positive integer valued "handle" in the *	range (and S.O.D. order) {7,6,...,1} if successful. *	Any non-positive return value (including zero!) should be considered *	an error by the caller. */intmpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass){	int r = -1;	int i;#ifndef MODULE	/*	 *  Handle possibility of the mptscsih_detect() routine getting	 *  called *before* fusion_init!	 */	if (!FusionInitCalled) {		dprintk((KERN_INFO MYNAM ": Hmmm, calling fusion_init from mpt_register!\n"));		/*		 *  NOTE! We'll get recursion here, as fusion_init()		 *  calls mpt_register()!		 */		fusion_init();		FusionInitCalled++;	}#endif	/*	 *  Search for empty callback slot in this order: {7,6,...,1}	 *  (slot/handle 0 is reserved!)	 */	for (i = MPT_MAX_PROTOCOL_DRIVERS-1; i; i--) {		if (MptCallbacks[i] == NULL) {			MptCallbacks[i] = cbfunc;			MptDriverClass[i] = dclass;			MptEvHandlers[i] = NULL;			r = i;			if (cbfunc != mpt_base_reply) {				MOD_INC_USE_COUNT;			}			break;		}	}	return r;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	mpt_deregister - Deregister a protocol drivers resources. *	@cb_idx: previously registered callback handle * *	Each protocol-specific driver should call this routine when it's *	module is unloaded. */voidmpt_deregister(int cb_idx){	if (cb_idx && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {		MptCallbacks[cb_idx] = NULL;		MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;		MptEvHandlers[cb_idx] = NULL;		if (cb_idx != mpt_base_index) {			MOD_DEC_USE_COUNT;		}	}}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	mpt_event_register - Register protocol-specific event callback *	handler. *	@cb_idx: previously registered (via mpt_register) callback handle *	@ev_cbfunc: callback function * *	This routine can be called by one or more protocol-specific drivers *	if/when they choose to be notified of MPT events. * *	Returns 0 for success. */intmpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc){	if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)		return -1;	MptEvHandlers[cb_idx] = ev_cbfunc;	return 0;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	mpt_event_deregister - Deregister protocol-specific event callback *	handler. *	@cb_idx: previously registered callback handle * *	Each protocol-specific driver should call this routine *	when it does not (or can no longer) handle events, *	or when it's module is unloaded. */voidmpt_event_deregister(int cb_idx){	if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)		return;	MptEvHandlers[cb_idx] = NULL;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	mpt_reset_register - Register protocol-specific IOC reset handler. *	@cb_idx: previously registered (via mpt_register) callback handle *	@reset_func: reset function * *	This routine can be called by one or more protocol-specific drivers *	if/when they choose to be notified of IOC resets. * *	Returns 0 for success. */intmpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func){	if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)		return -1;	MptResetHandlers[cb_idx] = reset_func;	return 0;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	mpt_reset_deregister - Deregister protocol-specific IOC reset handler. *	@cb_idx: previously registered callback handle * *	Each protocol-specific driver should call this routine *	when it does not (or can no longer) handle IOC reset handling, *	or when it's module is unloaded. */voidmpt_reset_deregister(int cb_idx){	if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)		return;	MptResetHandlers[cb_idx] = NULL;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024) *	allocated per MPT adapter. *	@handle: Handle of registered MPT protocol driver *	@iocid: IOC unique identifier (integer) * *	Returns pointer to a MPT request frame or %NULL if none are available. */MPT_FRAME_HDR*mpt_get_msg_frame(int handle, int iocid){	MPT_FRAME_HDR *mf = NULL;	MPT_ADAPTER *iocp;	unsigned long flags;	/* validate handle and ioc identifier */	iocp = mpt_adapters[iocid];	spin_lock_irqsave(&iocp->FreeQlock, flags);	if (! Q_IS_EMPTY(&iocp->FreeQ)) {		int req_offset;		mf = iocp->FreeQ.head;		Q_DEL_ITEM(&mf->u.frame.linkage);		mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;	/* byte */		req_offset = (u8 *)mf - (u8 *)iocp->req_frames;								/* u16! */		mf->u.frame.hwhdr.msgctxu.fld.req_idx =				cpu_to_le16(req_offset / iocp->req_sz);		mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;	}	spin_unlock_irqrestore(&iocp->FreeQlock, flags);	dmfprintk((KERN_INFO MYNAM ": %s: mpt_get_msg_frame(%d,%d), got mf=%p\n",			iocp->name, handle, iocid, mf));	return mf;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	mpt_put_msg_frame - Send a protocol specific MPT request frame *	to a IOC. *	@handle: Handle of registered MPT protocol driver *	@iocid: IOC unique identifier (integer) *	@mf: Pointer to MPT request frame * *	This routine posts a MPT request frame to the request post FIFO of a *	specific MPT adapter. */voidmpt_put_msg_frame(int handle, int iocid, MPT_FRAME_HDR *mf){	MPT_ADAPTER *iocp;	iocp = mpt_adapters[iocid];	if (iocp != NULL) {		dma_addr_t mf_dma_addr;		int req_offset;		/* ensure values are reset properly! */		mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;		/* byte */		req_offset = (u8 *)mf - (u8 *)iocp->req_frames;									/* u16! */		mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_offset / iocp->req_sz);		mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;#ifdef MPT_DEBUG_MSG_FRAME		{			u32	*m = mf->u.frame.hwhdr.__hdr;			int	 i, n;			printk(KERN_INFO MYNAM ": %s: About to Put msg frame @ %p:\n" KERN_INFO " ",					iocp->name, m);			n = iocp->req_sz/4 - 1;			while (m[n] == 0)				n--;			for (i=0; i<=n; i++) {				if (i && ((i%8)==0))					printk("\n" KERN_INFO " ");				printk(" %08x", le32_to_cpu(m[i]));			}			printk("\n");		}#endif		mf_dma_addr = iocp->req_frames_dma + req_offset;		CHIPREG_WRITE32(&iocp->chip->RequestFifo, mf_dma_addr);	}}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	mpt_free_msg_frame - Place MPT request frame back on FreeQ. *	@handle: Handle of registered MPT protocol driver *	@iocid: IOC unique identifier (integer) *	@mf: Pointer to MPT request frame * *	This routine places a MPT request frame back on the MPT adapter's *	FreeQ. */voidmpt_free_msg_frame(int handle, int iocid, MPT_FRAME_HDR *mf){	MPT_ADAPTER *iocp;	unsigned long flags;	iocp = mpt_adapters[iocid];	if (iocp != NULL) {		/*  Put Request back on FreeQ!  */		spin_lock_irqsave(&iocp->FreeQlock, flags);		Q_ADD_TAIL(&iocp->FreeQ, &mf->u.frame.linkage, MPT_FRAME_HDR);		spin_unlock_irqrestore(&iocp->FreeQlock, flags);	}}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	mpt_send_handshake_request - Send MPT request via doorbell *	handshake method. *	@handle: Handle of registered MPT protocol driver *	@iocid: IOC unique identifier (integer) *	@reqBytes: Size of the request in bytes *	@req: Pointer to MPT request frame * *	This routine is used exclusively by mptscsih to send MptScsiTaskMgmt *	requests since they are required to be sent via doorbell handshake. * *	NOTE: It is the callers responsibility to byte-swap fields in the *	request which are greater than 1 byte in size. * *	Returns 0 for success, non-zero for failure. */intmpt_send_handshake_request(int handle, int iocid, int reqBytes, u32 *req){	MPT_ADAPTER	*iocp;	int		 r = 0;	iocp = mpt_adapters[iocid];	if (iocp != NULL) {		u8		*req_as_bytes;		u32		 ioc_raw_state;		int		 i;		/* YIKES!  We already know something is amiss.		 * Do upfront check on IOC state.		 */		ioc_raw_state = GetIocState(iocp, 0);		if ((ioc_raw_state & MPI_DOORBELL_ACTIVE) ||		    ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL)) {			printk(KERN_WARNING MYNAM ": %s: Bad IOC state (%08x) WARNING!\n",					iocp->name, ioc_raw_state);			if ((r = mpt_do_ioc_recovery(iocp, MPT_HOSTEVENT_IOC_RECOVER)) != 0) {				printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",						r, iocp->name);				return r;			}		}		/*		 * Emulate what mpt_put_msg_frame() does /wrt to sanity		 * setting cb_idx/req_idx.  But ONLY if this request		 * is in proper (pre-alloc'd) request buffer range...		 */		i = MFPTR_2_MPT_INDEX(iocp,(MPT_FRAME_HDR*)req);		if (reqBytes >= 12 && i >= 0 && i < iocp->req_depth) {			MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;			mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(i);			mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;		}		/* Make sure there are no doorbells */		CHIPREG_WRITE32(&iocp->chip->IntStatus, 0);		CHIPREG_WRITE32(&iocp->chip->Doorbell,				((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |				 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));		/* Wait for IOC doorbell int */		if ((i = WaitForDoorbellInt(iocp, 2)) < 0) {			return i;		}		dhsprintk((KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",				iocp->name, i));		CHIPREG_WRITE32(&iocp->chip->IntStatus, 0);		if ((r = WaitForDoorbellAck(iocp, 1)) < 0) {			return -2;		}		/* Send request via doorbell handshake */		req_as_bytes = (u8 *) req;		for (i = 0; i < reqBytes/4; i++) {			u32 word;			word = ((req_as_bytes[(i*4) + 0] <<  0) |				(req_as_bytes[(i*4) + 1] <<  8) |				(req_as_bytes[(i*4) + 2] << 16) |				(req_as_bytes[(i*4) + 3] << 24));			CHIPREG_WRITE32(&iocp->chip->Doorbell, word);			if ((r = WaitForDoorbellAck(iocp, 1)) < 0) {				r = -3;				break;			}		}		if ((r = WaitForDoorbellInt(iocp, 2)) >= 0)			r = 0;		else			r = -4;		/* Make sure there are no doorbells */		CHIPREG_WRITE32(&iocp->chip->IntStatus, 0);	}	return r;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	mpt_adapter_find_first - Find first MPT adapter pointer. * *	Returns first MPT adapter pointer or %NULL if no MPT adapters *	are present. */MPT_ADAPTER *mpt_adapter_find_first(void){	MPT_ADAPTER *this = NULL;	if (! Q_IS_EMPTY(&MptAdapters))		this = MptAdapters.head;	return this;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** * 	mpt_adapter_find_next - Find next MPT adapter pointer. * 	@prev: Pointer to previous MPT adapter * *	Returns next MPT adapter pointer or %NULL if there are no more. */MPT_ADAPTER *mpt_adapter_find_next(MPT_ADAPTER *prev){	MPT_ADAPTER *next = NULL;	if (prev && (prev->forw != (MPT_ADAPTER*)&MptAdapters.head))		next = prev->forw;	return next;}

⌨️ 快捷键说明

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