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

📄 mptscsih.c

📁 ARM S3C2410 linux2.4 内核源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	}	//return SUCCESS;	return FAILED;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	mptscsih_dev_reset - Perform a SCSI TARGET_RESET!  new_eh variant *	@SCpnt: Pointer to Scsi_Cmnd structure, IO which reset is due to * *	(linux Scsi_Host_Template.eh_dev_reset_handler routine) * *	Returns SUCCESS or FAILED. */intmptscsih_dev_reset(Scsi_Cmnd * SCpnt){	MPT_FRAME_HDR	*mf;	SCSITaskMgmt_t	*pScsiTm;	MPT_SCSI_HOST	*hd;	u32		*msg;	int		 i;	unsigned long	 flags;	printk(KERN_WARNING MYNAM ": Attempting _TARGET_RESET (%p)\n", SCpnt);	printk(KERN_WARNING MYNAM ": IOs outstanding = %d\n", atomic_read(&queue_depth));	hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata;	if ((mf = mpt_get_msg_frame(ScsiTaskCtx, hd->ioc->id)) == NULL) {/*		SCpnt->result = DID_SOFT_ERROR << 16;	*/		SCpnt->result = STS_BUSY;		SCpnt->scsi_done(SCpnt);		return FAILED;	}	pScsiTm = (SCSITaskMgmt_t *) mf;	msg = (u32*)mf;	pScsiTm->TargetID = SCpnt->target;	pScsiTm->Bus = hd->port;	pScsiTm->ChainOffset = 0;	pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;	pScsiTm->Reserved = 0;	pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET;	pScsiTm->Reserved1 = 0;	pScsiTm->MsgFlags = 0;	/* _TARGET_RESET goes to LUN 0 always! */	for (i = 0; i < 8; i++)		pScsiTm->LUN[i] = 0;	/* Control: No data direction, set task mgmt bit? */	for (i = 0; i < 7; i++)		pScsiTm->Reserved2[i] = 0;	pScsiTm->TaskMsgContext = cpu_to_le32(0);/* MPI v0.10 requires SCSITaskMgmt requests be sent via Doorbell/handshake	mpt_put_msg_frame(hd->ioc->id, mf);*//* FIXME!  Check return status! */	if ((i = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id,				sizeof(SCSITaskMgmt_t), msg))	    != 0) {		printk(KERN_WARNING MYNAM				": WARNING[3] - IOC error (%d) processing TaskMgmt request (mf=%p:sc=%p)\n",				i, mf, SCpnt);		SCpnt->result = DID_SOFT_ERROR << 16;		spin_lock_irqsave(&io_request_lock, flags);		SCpnt->scsi_done(SCpnt);		spin_unlock_irqrestore(&io_request_lock, flags);		mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);	}	//return SUCCESS;	return FAILED;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	mptscsih_bus_reset - Perform a SCSI BUS_RESET!	new_eh variant *	@SCpnt: Pointer to Scsi_Cmnd structure, IO which reset is due to * *	(linux Scsi_Host_Template.eh_bus_reset_handler routine) * *	Returns SUCCESS or FAILED. */intmptscsih_bus_reset(Scsi_Cmnd * SCpnt){	MPT_FRAME_HDR	*mf;	SCSITaskMgmt_t	*pScsiTm;	MPT_SCSI_HOST	*hd;	u32		*msg;	int		 i;	unsigned long	 flags;	printk(KERN_WARNING MYNAM ": Attempting _BUS_RESET (%p)\n", SCpnt);	printk(KERN_WARNING MYNAM ": IOs outstanding = %d\n", atomic_read(&queue_depth));	hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata;	if ((mf = mpt_get_msg_frame(ScsiTaskCtx, hd->ioc->id)) == NULL) {/*		SCpnt->result = DID_SOFT_ERROR << 16;	*/		SCpnt->result = STS_BUSY;		SCpnt->scsi_done(SCpnt);		return FAILED;	}	pScsiTm = (SCSITaskMgmt_t *) mf;	msg = (u32 *) mf;	pScsiTm->TargetID = SCpnt->target;	pScsiTm->Bus = hd->port;	pScsiTm->ChainOffset = 0;	pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;	pScsiTm->Reserved = 0;	pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS;	pScsiTm->Reserved1 = 0;	pScsiTm->MsgFlags = 0;	for (i = 0; i < 8; i++)		pScsiTm->LUN[i] = 0;	/* Control: No data direction, set task mgmt bit? */	for (i = 0; i < 7; i++)		pScsiTm->Reserved2[i] = 0;	pScsiTm->TaskMsgContext = cpu_to_le32(0);/* MPI v0.10 requires SCSITaskMgmt requests be sent via Doorbell/handshake	mpt_put_msg_frame(hd->ioc->id, mf);*//* FIXME!  Check return status! */	if ((i = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id,				sizeof(SCSITaskMgmt_t), msg))	    != 0) {		printk(KERN_WARNING MYNAM				": WARNING[4] - IOC error (%d) processing TaskMgmt request (mf=%p:sc=%p)\n",				i, mf, SCpnt);		SCpnt->result = DID_SOFT_ERROR << 16;		spin_lock_irqsave(&io_request_lock, flags);		SCpnt->scsi_done(SCpnt);		spin_unlock_irqrestore(&io_request_lock, flags);		mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);	}	return SUCCESS;}#if 0	/* { *//*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	mptscsih_host_reset - Perform a SCSI host adapter RESET! *	new_eh variant *	@SCpnt: Pointer to Scsi_Cmnd structure, IO which reset is due to * *	(linux Scsi_Host_Template.eh_host_reset_handler routine) * *	Returns SUCCESS or FAILED. */intmptscsih_host_reset(Scsi_Cmnd * SCpnt){	return FAILED;}#endif	/* } */#else		/* MPT_SCSI old EH stuff... *//*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	mptscsih_old_abort - Abort linux Scsi_Cmnd routine *	@SCpnt: Pointer to Scsi_Cmnd structure, IO to be aborted * *	(linux Scsi_Host_Template.abort routine) * *	Returns SCSI_ABORT_{SUCCESS,BUSY,PENDING}. */intmptscsih_old_abort(Scsi_Cmnd *SCpnt){	MPT_SCSI_HOST		*hd;	MPT_FRAME_HDR		*mf;	struct tq_struct	*ptaskfoo;	unsigned long		 flags;	printk(KERN_WARNING MYNAM ": Scheduling _ABORT SCSI IO (=%p)\n", SCpnt);	printk(KERN_WARNING MYNAM ": IOs outstanding = %d\n", atomic_read(&queue_depth));	if ((hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata) == NULL) {		SCpnt->result = DID_ABORT << 16;		SCpnt->scsi_done(SCpnt);		return SCSI_ABORT_SUCCESS;	}	/*	 *  Check to see if there's already an ABORT queued for this guy.	 */	mf = search_taskQ(0,SCpnt,MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK);	if (mf != NULL) {		return SCSI_ABORT_PENDING;	}	if ((mf = mpt_get_msg_frame(ScsiTaskCtx, hd->ioc->id)) == NULL) {/*		SCpnt->result = DID_SOFT_ERROR << 16;	*/		SCpnt->result = STS_BUSY;		SCpnt->scsi_done(SCpnt);		return SCSI_ABORT_BUSY;	}	/*	 *  Add ourselves to (end of) mpt_scsih_taskQ.	 *  Check to see if our _bh is running.  If NOT, schedule it.	 */	dslprintk((KERN_INFO MYNAM ": spinlock#2\n"));	spin_lock_irqsave(&mpt_scsih_taskQ_lock, flags);	Q_ADD_TAIL(&mpt_scsih_taskQ, &mf->u.frame.linkage, MPT_FRAME_HDR);	mpt_scsih_taskQ_cnt++;	/* Yikes - linkage! *//*	SCpnt->host_scribble = (unsigned char *)mf;	*/	mf->u.frame.linkage.arg1 = MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK;	mf->u.frame.linkage.argp1 = SCpnt;	if (! mpt_scsih_taskQ_bh_active) {		mpt_scsih_taskQ_bh_active = 1;		/*		 *  Oh how cute, no alloc/free/mgmt needed if we use		 *  (bottom/unused portion of) MPT request frame.		 */		ptaskfoo = (struct tq_struct *) ((u8*)mf + hd->ioc->req_sz - sizeof(*ptaskfoo));		ptaskfoo->sync = 0;		ptaskfoo->routine = mptscsih_taskmgmt_bh;		ptaskfoo->data = SCpnt;		SCHEDULE_TASK(ptaskfoo);	}	spin_unlock_irqrestore(&mpt_scsih_taskQ_lock, flags);	return SCSI_ABORT_PENDING;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	mptscsih_old_reset - Perform a SCSI BUS_RESET! *	@SCpnt: Pointer to Scsi_Cmnd structure, IO which reset is due to *	@reset_flags: (not used?) * *	(linux Scsi_Host_Template.reset routine) * *	Returns SCSI_RESET_{SUCCESS,PUNT,PENDING}. */intmptscsih_old_reset(Scsi_Cmnd *SCpnt, unsigned int reset_flags){	MPT_SCSI_HOST		*hd;	MPT_FRAME_HDR		*mf;	struct tq_struct	*ptaskfoo;	unsigned long		 flags;	printk(KERN_WARNING MYNAM ": Scheduling _BUS_RESET (=%p)\n", SCpnt);	printk(KERN_WARNING MYNAM ": IOs outstanding = %d\n", atomic_read(&queue_depth));	if ((hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata) == NULL) {		SCpnt->result = DID_RESET << 16;		SCpnt->scsi_done(SCpnt);		return SCSI_RESET_SUCCESS;	}	/*	 *  Check to see if there's already a BUS_RESET queued for this guy.	 */	mf = search_taskQ(0,SCpnt,MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS);	if (mf != NULL) {		return SCSI_RESET_PENDING;	}	if ((mf = mpt_get_msg_frame(ScsiTaskCtx, hd->ioc->id)) == NULL) {/*		SCpnt->result = DID_SOFT_ERROR << 16;	*/		SCpnt->result = STS_BUSY;		SCpnt->scsi_done(SCpnt);		return SCSI_RESET_PUNT;	}	/*	 *  Add ourselves to (end of) mpt_scsih_taskQ.	 *  Check to see if our _bh is running.  If NOT, schedule it.	 */	dslprintk((KERN_INFO MYNAM ": spinlock#3\n"));	spin_lock_irqsave(&mpt_scsih_taskQ_lock, flags);	Q_ADD_TAIL(&mpt_scsih_taskQ, &mf->u.frame.linkage, MPT_FRAME_HDR);	mpt_scsih_taskQ_cnt++;	/* Yikes - linkage! *//*	SCpnt->host_scribble = (unsigned char *)mf;	*/	mf->u.frame.linkage.arg1 = MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS;	mf->u.frame.linkage.argp1 = SCpnt;	if (! mpt_scsih_taskQ_bh_active) {		mpt_scsih_taskQ_bh_active = 1;		/*		 *  Oh how cute, no alloc/free/mgmt needed if we use		 *  (bottom/unused portion of) MPT request frame.		 */		ptaskfoo = (struct tq_struct *) ((u8*)mf + hd->ioc->req_sz - sizeof(*ptaskfoo));		ptaskfoo->sync = 0;		ptaskfoo->routine = mptscsih_taskmgmt_bh;		ptaskfoo->data = SCpnt;		SCHEDULE_TASK(ptaskfoo);	}	spin_unlock_irqrestore(&mpt_scsih_taskQ_lock, flags);	return SCSI_RESET_PENDING;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* *	mptscsih_taskmgmt_bh - SCSI task mgmt bottom half handler *	@sc: (unused) * *	This routine (thread) is active whenever there are any outstanding *	SCSI task management requests for a SCSI host adapter. *	IMPORTANT!  This routine is scheduled therefore should never be *	running in ISR context.  i.e., it's safe to sleep here. */voidmptscsih_taskmgmt_bh(void *sc){	Scsi_Cmnd	*SCpnt;	MPT_FRAME_HDR	*mf;	SCSITaskMgmt_t	*pScsiTm;	MPT_SCSI_HOST	*hd;	u32		 ctx2abort = 0;	int		 i;	unsigned long	 flags;	u8		 task_type;	dslprintk((KERN_INFO MYNAM ": spinlock#4\n"));	spin_lock_irqsave(&mpt_scsih_taskQ_lock, flags);	mpt_scsih_taskQ_bh_active = 1;	spin_unlock_irqrestore(&mpt_scsih_taskQ_lock, flags);	while (1) {		current->state = TASK_INTERRUPTIBLE;		schedule_timeout(HZ/4);		/*		 *  We MUST remove item from taskQ *before* we format the		 *  frame as a SCSITaskMgmt request and send it down to the IOC.		 */		dslprintk((KERN_INFO MYNAM ": spinlock#5\n"));		spin_lock_irqsave(&mpt_scsih_taskQ_lock, flags);		if (Q_IS_EMPTY(&mpt_scsih_taskQ)) {			spin_unlock_irqrestore(&mpt_scsih_taskQ_lock, flags);			break;		}		mf = mpt_scsih_taskQ.head;		Q_DEL_ITEM(&mf->u.frame.linkage);		mpt_scsih_taskQ_cnt--;		mpt_scsih_active_taskmgmt_mf = mf;		spin_unlock_irqrestore(&mpt_scsih_taskQ_lock, flags);		SCpnt = (Scsi_Cmnd*)mf->u.frame.linkage.argp1;		if (SCpnt == NULL) {			printk(KERN_ERR MYNAM ": ERROR - TaskMgmt has NULL SCpnt! (%p:%p)\n", mf, SCpnt);			continue;		}		hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata;		pScsiTm = (SCSITaskMgmt_t *) mf;		for (i = 0; i < 8; i++) {			pScsiTm->LUN[i] = 0;		}		task_type = mf->u.frame.linkage.arg1;		if (task_type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {			printk(KERN_WARNING MYNAM ": Attempting _ABORT SCSI IO! (mf=%p:sc=%p)\n",					mf, SCpnt);			/* Most important!  Set TaskMsgContext to SCpnt's MsgContext!			 * (the IO to be ABORT'd)			 *			 * NOTE: Since we do not byteswap MsgContext, we do not			 *	 swap it here either.  It is an opaque cookie to			 *	 the controller, so it does not matter. -DaveM			 */			ctx2abort = SCPNT_TO_MSGCTX(SCpnt);			if (ctx2abort == -1) {				printk(KERN_ERR MYNAM ": ERROR - ScsiLookup fail(#1) for SCpnt=%p\n", SCpnt);				SCpnt->result = DID_SOFT_ERROR << 16;				spin_lock_irqsave(&io_request_lock, flags);				SCpnt->scsi_done(SCpnt);				spin_unlock_irqrestore(&io_request_lock, flags);				mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);				continue;			}			pScsiTm->LUN[1] = SCpnt->lun;		}		else if (task_type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)		{			printk(KERN_WARNING MYNAM ": Attempting _BUS_RESET! (against SCSI IO mf=%p:sc=%p)\n", mf, SCpnt);		}#if 0		else if (task_type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {}		else if (task_type == MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET) {}#endif		printk(KERN_WARNING MYNAM ": IOs outstanding = %d\n", atomic_read(&queue_depth));		pScsiTm->TargetID = SCpnt->target;		pScsiTm->Bus = hd->port;		pScsiTm->ChainOffset = 0;		pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;		pScsiTm->Reserved = 0;		pScsiTm->TaskType = task_type;		pScsiTm->Reserved1 = 0;		pScsiTm->MsgFlags = 0;		for (i = 0; i < 7; i++)			pScsiTm->Reserved2[i] = 0;		dprintk((KERN_INFO MYNAM ":DbG: ctx2abort = %08x\n", ctx2abort));		pScsiTm->TaskMsgContext = ctx2abort;		/* Control: No data direction, set task mgmt bit? */		/*		 *  As of MPI v0.10 this request can NOT be sent (normally)		 *  via FIFOs.	So we can't:		 *		mpt_put_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);		 *  SCSITaskMgmt requests MUST be sent ONLY via		 *  Doorbell/handshake now.   :-(		 */		if ((i = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id,					sizeof(SCSITaskMgmt_t), (u32*) mf))		    != 0) {			printk(KERN_WARNING MYNAM ": WARNING[1] - IOC error (%d) processing TaskMgmt request (mf=%p:sc=%p)\n", i, mf, SCpnt);			SCpnt->result = DID_SOFT_ERROR << 16;			spin_lock_irqsave(&io_request_lock, flags);			SCpnt->scsi_done(SCpnt);			spin_unlock_irqrestore(&io_request_lock, flags);			mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);		} else {			/* Spin-Wait for TaskMgmt complete!!! */			while (mpt_scsih_active_taskmgmt_mf != NULL) {				current->state = TASK_INTERRUPTIBLE;				schedule_timeout(HZ/4);			}		}	}

⌨️ 快捷键说明

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