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

📄 mptscsih.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	 */	if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT		    "task abort: hidden raid component (sc=%p)\n",		    ioc->name, SCpnt));		SCpnt->result = DID_RESET << 16;		retval = FAILED;		goto out;	}	/* Find this command	 */	if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(ioc, SCpnt)) < 0) {		/* Cmd not found in ScsiLookup.		 * Do OS callback.		 */		SCpnt->result = DID_RESET << 16;		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "task abort: "		   "Command not in the active list! (sc=%p)\n", ioc->name,		   SCpnt));		retval = 0;		goto out;	}	if (hd->resetPending) {		retval = FAILED;		goto out;	}	if (hd->timeouts < -1)		hd->timeouts++;	/* 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	 */	mf = MPT_INDEX_2_MFPTR(ioc, scpnt_idx);	ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;	hd->abortSCpnt = SCpnt;	retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,	    vdevice->vtarget->channel, vdevice->vtarget->id, vdevice->lun,	    ctx2abort, mptscsih_get_tm_timeout(ioc));	if (SCPNT_TO_LOOKUP_IDX(ioc, SCpnt) == scpnt_idx &&	    SCpnt->serial_number == sn)		retval = FAILED; out:	printk(MYIOC_s_INFO_FMT "task abort: %s (sc=%p)\n",	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);	if (retval == 0)		return SUCCESS;	else		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(struct scsi_cmnd * SCpnt){	MPT_SCSI_HOST	*hd;	int		 retval;	VirtDevice	 *vdevice;	MPT_ADAPTER	*ioc;	/* If we can't locate our host adapter structure, return FAILED status.	 */	if ((hd = shost_priv(SCpnt->device->host)) == NULL){		printk(KERN_ERR MYNAM ": target reset: "		   "Can't locate host! (sc=%p)\n", SCpnt);		return FAILED;	}	ioc = hd->ioc;	printk(MYIOC_s_INFO_FMT "attempting target reset! (sc=%p)\n",	       ioc->name, SCpnt);	scsi_print_command(SCpnt);	if (hd->resetPending) {		retval = FAILED;		goto out;	}	vdevice = SCpnt->device->hostdata;	if (!vdevice || !vdevice->vtarget) {		retval = 0;		goto out;	}	/* Target reset to hidden raid component is not supported	 */	if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {		retval = FAILED;		goto out;	}	retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,	    vdevice->vtarget->channel, vdevice->vtarget->id, 0, 0,	    mptscsih_get_tm_timeout(ioc)); out:	printk (MYIOC_s_INFO_FMT "target reset: %s (sc=%p)\n",	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);	if (retval == 0)		return SUCCESS;	else		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(struct scsi_cmnd * SCpnt){	MPT_SCSI_HOST	*hd;	int		 retval;	VirtDevice	 *vdevice;	MPT_ADAPTER	*ioc;	/* If we can't locate our host adapter structure, return FAILED status.	 */	if ((hd = shost_priv(SCpnt->device->host)) == NULL){		printk(KERN_ERR MYNAM ": bus reset: "		   "Can't locate host! (sc=%p)\n", SCpnt);		return FAILED;	}	ioc = hd->ioc;	printk(MYIOC_s_INFO_FMT "attempting bus reset! (sc=%p)\n",	       ioc->name, SCpnt);	scsi_print_command(SCpnt);	if (hd->timeouts < -1)		hd->timeouts++;	vdevice = SCpnt->device->hostdata;	retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,	    vdevice->vtarget->channel, 0, 0, 0, mptscsih_get_tm_timeout(ioc));	printk(MYIOC_s_INFO_FMT "bus reset: %s (sc=%p)\n",	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);	if (retval == 0)		return SUCCESS;	else		return FAILED;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	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(struct scsi_cmnd *SCpnt){	MPT_SCSI_HOST *  hd;	int              retval;	MPT_ADAPTER	*ioc;	/*  If we can't locate the host to reset, then we failed. */	if ((hd = shost_priv(SCpnt->device->host)) == NULL){		printk(KERN_ERR MYNAM ": host reset: "		    "Can't locate host! (sc=%p)\n", SCpnt);		return FAILED;	}	ioc = hd->ioc;	printk(MYIOC_s_INFO_FMT "attempting host reset! (sc=%p)\n",	    ioc->name, SCpnt);	/*  If our attempts to reset the host failed, then return a failed	 *  status.  The host will be taken off line by the SCSI mid-layer.	 */	if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0) {		retval = FAILED;	} else {		/*  Make sure TM pending is cleared and TM state is set to		 *  NONE.		 */		retval = 0;		hd->tmPending = 0;		hd->tmState = TM_STATE_NONE;	}	printk(MYIOC_s_INFO_FMT "host reset: %s (sc=%p)\n",	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);	return retval;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	mptscsih_tm_pending_wait - wait for pending task management request to complete *	@hd: Pointer to MPT host structure. * *	Returns {SUCCESS,FAILED}. */static intmptscsih_tm_pending_wait(MPT_SCSI_HOST * hd){	unsigned long  flags;	int            loop_count = 4 * 10;  /* Wait 10 seconds */	int            status = FAILED;	MPT_ADAPTER	*ioc = hd->ioc;	do {		spin_lock_irqsave(&ioc->FreeQlock, flags);		if (hd->tmState == TM_STATE_NONE) {			hd->tmState = TM_STATE_IN_PROGRESS;			hd->tmPending = 1;			spin_unlock_irqrestore(&ioc->FreeQlock, flags);			status = SUCCESS;			break;		}		spin_unlock_irqrestore(&ioc->FreeQlock, flags);		msleep(250);	} while (--loop_count);	return status;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	mptscsih_tm_wait_for_completion - wait for completion of TM task *	@hd: Pointer to MPT host structure. *	@timeout: timeout value * *	Returns {SUCCESS,FAILED}. */static intmptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout ){	unsigned long  flags;	int            loop_count = 4 * timeout;	int            status = FAILED;	MPT_ADAPTER	*ioc = hd->ioc;	do {		spin_lock_irqsave(&ioc->FreeQlock, flags);		if(hd->tmPending == 0) {			status = SUCCESS;			spin_unlock_irqrestore(&ioc->FreeQlock, flags);			break;		}		spin_unlock_irqrestore(&ioc->FreeQlock, flags);		msleep(250);	} while (--loop_count);	return status;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/static voidmptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code){	char *desc;	switch (response_code) {	case MPI_SCSITASKMGMT_RSP_TM_COMPLETE:		desc = "The task completed.";		break;	case MPI_SCSITASKMGMT_RSP_INVALID_FRAME:		desc = "The IOC received an invalid frame status.";		break;	case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:		desc = "The task type is not supported.";		break;	case MPI_SCSITASKMGMT_RSP_TM_FAILED:		desc = "The requested task failed.";		break;	case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED:		desc = "The task completed successfully.";		break;	case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN:		desc = "The LUN request is invalid.";		break;	case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:		desc = "The task is in the IOC queue and has not been sent to target.";		break;	default:		desc = "unknown";		break;	}	printk(MYIOC_s_INFO_FMT "Response Code(0x%08x): F/W: %s\n",		ioc->name, response_code, desc);}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver *	@ioc: Pointer to MPT_ADAPTER structure *	@mf: Pointer to SCSI task mgmt request frame *	@mr: Pointer to SCSI task mgmt reply frame * *	This routine is called from mptbase.c::mpt_interrupt() at the completion *	of any SCSI task management request. *	This routine is registered with the MPT (base) driver at driver *	load/init time via the mpt_register() API call. * *	Returns 1 indicating alloc'd request frame ptr should be freed. **/intmptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr){	SCSITaskMgmtReply_t	*pScsiTmReply;	SCSITaskMgmt_t		*pScsiTmReq;	MPT_SCSI_HOST		*hd;	unsigned long		 flags;	u16			 iocstatus;	u8			 tmType;	u32			 termination_count;	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",	    ioc->name, mf, mr));	if (!ioc->sh) {		dtmprintk(ioc, printk(MYIOC_s_WARN_FMT		    "TaskMgmt Complete: NULL Scsi Host Ptr\n", ioc->name));		return 1;	}	if (mr == NULL) {		dtmprintk(ioc, printk(MYIOC_s_WARN_FMT		    "ERROR! TaskMgmt Reply: NULL Request %p\n", ioc->name, mf));		return 1;	}	hd = shost_priv(ioc->sh);	pScsiTmReply = (SCSITaskMgmtReply_t*)mr;	pScsiTmReq = (SCSITaskMgmt_t*)mf;	tmType = pScsiTmReq->TaskType;	iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;	termination_count = le32_to_cpu(pScsiTmReply->TerminationCount);	if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&	    pScsiTmReply->ResponseCode)		mptscsih_taskmgmt_response_code(ioc,		    pScsiTmReply->ResponseCode);	DBG_DUMP_TM_REPLY_FRAME(ioc, (u32 *)pScsiTmReply);#ifdef CONFIG_FUSION_LOGGING	if ((ioc->debug_level & MPT_DEBUG_REPLY) ||				(ioc->debug_level & MPT_DEBUG_TM ))		printk("%s: ha=%d [%d:%d:0] task_type=0x%02X "			"iocstatus=0x%04X\n\tloginfo=0x%08X response_code=0x%02X "			"term_cmnds=%d\n", __FUNCTION__, ioc->id, pScsiTmReply->Bus,			 pScsiTmReply->TargetID, pScsiTmReq->TaskType,			le16_to_cpu(pScsiTmReply->IOCStatus),			le32_to_cpu(pScsiTmReply->IOCLogInfo),pScsiTmReply->ResponseCode,			le32_to_cpu(pScsiTmReply->TerminationCount));#endif	if (!iocstatus) {		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT " TaskMgmt SUCCESS\n", ioc->name));			hd->abortSCpnt = NULL;		goto out;	}	/* Error?  (anything non-zero?) */	/* clear flags and continue.	 */	switch (tmType) {	case MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK:		if (termination_count == 1)			iocstatus = MPI_IOCSTATUS_SCSI_TASK_TERMINATED;		hd->abortSCpnt = NULL;		break;	case MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS:		/* If an internal command is present		 * or the TM failed - reload the FW.		 * FC FW may respond FAILED to an ABORT		 */		if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED ||		    hd->cmdPtr)			if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)				printk(MYIOC_s_WARN_FMT " Firmware Reload FAILED!!\n", ioc->name);		break;	case MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET:	default:		break;	} out:	spin_lock_irqsave(&ioc->FreeQlock, flags);	hd->tmPending = 0;	hd->tmState = TM_STATE_NONE;	hd->tm_iocstatus = iocstatus;	spin_unlock_irqrestore(&ioc->FreeQlock, flags);	return 1;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* *	This is anyones guess quite frankly. */intmptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,		sector_t capacity, int geom[]){	int		heads;	int		sectors;	sector_t	cylinders;	ulong 		dummy;	heads = 64;	sectors = 32;	dummy = heads * sectors;	cylinders = capacity;	sector_div(cylinders,dummy);	/*	 * Handle extended translation size for logical drives	 * > 1Gb	 */	if ((ulong)capacity >=

⌨️ 快捷键说明

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