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

📄 mptscsih.c

📁 linux2.6.16版本
💻 C
📖 第 1 页 / 共 5 页
字号:
	 *	 swap it here either.  It is an opaque cookie to	 *	 the controller, so it does not matter. -DaveM	 */	mf = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx);	ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;	hd->abortSCpnt = SCpnt;	vdev = SCpnt->device->hostdata;	retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,		vdev->bus_id, vdev->target_id, vdev->lun,		ctx2abort, mptscsih_get_tm_timeout(ioc));	printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",		hd->ioc->name,		((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);	if (retval == 0)		return SUCCESS;	if(retval != FAILED ) {		hd->tmPending = 0;		hd->tmState = TM_STATE_NONE;	}	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	 *vdev;	/* If we can't locate our host adapter structure, return FAILED status.	 */	if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){		dtmprintk((KERN_INFO MYNAM ": mptscsih_dev_reset: "			   "Can't locate host! (sc=%p)\n",			   SCpnt));		return FAILED;	}	if (hd->resetPending)		return FAILED;	printk(KERN_WARNING MYNAM ": %s: attempting target reset! (sc=%p)\n",	       hd->ioc->name, SCpnt);	scsi_print_command(SCpnt);	vdev = SCpnt->device->hostdata;	retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,		vdev->bus_id, vdev->target_id,		0, 0, mptscsih_get_tm_timeout(hd->ioc));	printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",		hd->ioc->name,		((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);	if (retval == 0)		return SUCCESS;	if(retval != FAILED ) {		hd->tmPending = 0;		hd->tmState = TM_STATE_NONE;	}	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	 *vdev;	/* If we can't locate our host adapter structure, return FAILED status.	 */	if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){		dtmprintk((KERN_INFO MYNAM ": mptscsih_bus_reset: "			   "Can't locate host! (sc=%p)\n",			   SCpnt ) );		return FAILED;	}	printk(KERN_WARNING MYNAM ": %s: attempting bus reset! (sc=%p)\n",	       hd->ioc->name, SCpnt);	scsi_print_command(SCpnt);	if (hd->timeouts < -1)		hd->timeouts++;	vdev = SCpnt->device->hostdata;	retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,		vdev->bus_id, 0, 0, 0, mptscsih_get_tm_timeout(hd->ioc));	printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",		hd->ioc->name,		((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);	if (retval == 0)		return SUCCESS;	if(retval != FAILED ) {		hd->tmPending = 0;		hd->tmState = TM_STATE_NONE;	}	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              status = SUCCESS;	/*  If we can't locate the host to reset, then we failed. */	if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){		dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "			     "Can't locate host! (sc=%p)\n",			     SCpnt ) );		return FAILED;	}	printk(KERN_WARNING MYNAM ": %s: Attempting host reset! (sc=%p)\n",	       hd->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(hd->ioc, CAN_SLEEP) < 0){		status = FAILED;	} else {		/*  Make sure TM pending is cleared and TM state is set to		 *  NONE.		 */		hd->tmPending = 0;		hd->tmState = TM_STATE_NONE;	}	dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "		     "Status = %s\n",		     (status == SUCCESS) ? "SUCCESS" : "FAILED" ) );	return status;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	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;	do {		spin_lock_irqsave(&hd->ioc->FreeQlock, flags);		if (hd->tmState == TM_STATE_NONE) {			hd->tmState = TM_STATE_IN_PROGRESS;			hd->tmPending = 1;			spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);			status = SUCCESS;			break;		}		spin_unlock_irqrestore(&hd->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. * *	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;	do {		spin_lock_irqsave(&hd->ioc->FreeQlock, flags);		if(hd->tmPending == 0) {			status = SUCCESS; 			spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);			break;		}		spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);		msleep_interruptible(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;	dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",			ioc->name, mf, mr));	if (ioc->sh) {		/* Depending on the thread, a timer is activated for		 * the TM request.  Delete this timer on completion of TM.		 * Decrement count of outstanding TM requests.		 */		hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;	} else {		dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n",			ioc->name));		return 1;	}	if (mr == NULL) {		dtmprintk((MYIOC_s_WARN_FMT "ERROR! TaskMgmt Reply: NULL Request %p\n",			ioc->name, mf));		return 1;	} else {		pScsiTmReply = (SCSITaskMgmtReply_t*)mr;		pScsiTmReq = (SCSITaskMgmt_t*)mf;		/* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */		tmType = pScsiTmReq->TaskType;		if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&		    pScsiTmReply->ResponseCode)			mptscsih_taskmgmt_response_code(ioc,			    pScsiTmReply->ResponseCode);		dtmprintk((MYIOC_s_WARN_FMT "  TaskType = %d, TerminationCount=%d\n",				ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount)));		DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);		iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;		dtmprintk((MYIOC_s_WARN_FMT "  SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n",			ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo)));		/* Error?  (anything non-zero?) */		if (iocstatus) {			/* clear flags and continue.			 */			if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK)				hd->abortSCpnt = NULL;			/* If an internal command is present			 * or the TM failed - reload the FW.			 * FC FW may respond FAILED to an ABORT			 */			if (tmType == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {				if ((hd->cmdPtr) ||				    (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED)) {					if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) {						printk((KERN_WARNING							" Firmware Reload FAILED!!\n"));					}				}			}		} else {			dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));			hd->abortSCpnt = NULL;		}	}	spin_lock_irqsave(&ioc->FreeQlock, flags);	hd->tmPending = 0;	spin_unlock_irqrestore(&ioc->FreeQlock, flags);	hd->tmState = TM_STATE_NONE;	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 >= 0x200000) {		heads = 255;		sectors = 63;		dummy = heads * sectors;		cylinders = capacity;		sector_div(cylinders,dummy);	}	/* return result */	geom[0] = heads;	geom[1] = sectors;	geom[2] = cylinders;	dprintk((KERN_NOTICE		": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",		sdev->id, sdev->lun,sdev->channel,(int)cylinders,heads,sectors));	return 0;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* *	OS entry point to allow host driver to alloc memory *	for each scsi target. Called once per device the bus scan. *	Return non-zero if allocation fails. */intmptscsih_target_alloc(struct scsi_target *starget){	VirtTarget		*vtarget;	vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);	if (!vtarget)		return -ENOMEM;	starget->hostdata = vtarget;	return 0;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* *	OS entry point to allow host driver to alloc memory *	for each scsi device. Called once per device the bus scan. *	Return non-zero if allocation fails. */intmptscsih_slave_alloc(struct scsi_device *sdev){	struct Scsi_Host	*host = sdev->host;	MPT_SCSI_HOST		*hd = (MPT_SCSI_HOST *)host->hostdata;	VirtTarget		*vtarget;	VirtDevice		*vdev;	struct scsi_target 	*starget;	vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);	if (!vdev) {		printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",		

⌨️ 快捷键说明

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