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

📄 mptscsih.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
 * *	Returns SUCCESS or FAILED. */intmptscsih_dev_reset(struct scsi_cmnd * SCpnt){	MPT_SCSI_HOST	*hd;	int		 retval;	/* 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);	retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,		SCpnt->device->channel, SCpnt->device->id,		0, 0, 5 /* 5 second timeout */);	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;	/* 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++;	retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,		SCpnt->device->channel, 0, 0, 0, 5 /* 5 second timeout */);	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;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	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;		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 device. Called once per device the bus scan. *	Return non-zero if allocation fails. *	Init memory once per id (not LUN). */intmptscsih_slave_alloc(struct scsi_device *device){	struct Scsi_Host	*host = device->host;	MPT_SCSI_HOST		*hd = (MPT_SCSI_HOST *)host->hostdata;	VirtDevice		*vdev;	uint			target = device->id;	if (hd == NULL)		return -ENODEV;	if ((vdev = hd->Targets[target]) != NULL)		goto out;	vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);	if (!vdev) {		printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",				hd->ioc->name, sizeof(VirtDevice));		return -ENOMEM;	}	memset(vdev, 0, sizeof(VirtDevice));	vdev->tflags = MPT_TARGET_FLAGS_Q_YES;	vdev->ioc_id = hd->ioc->id;	vdev->target_id = device->id;	vdev->bus_id = device->channel;	vdev->raidVolume = 0;	hd->Targets[device->id] = vdev;	if (hd->ioc->bus_type == SCSI) {		if (hd->ioc->raid_data.isRaid & (1 << device->id)) {			vdev->raidVolume = 1;			ddvtprintk((KERN_INFO			    "RAID Volume @ id %d\n", device->id));		}	} else {		vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;	} out:	vdev->num_luns++;	device->hostdata = vdev;	return 0;}/* *	OS entry point to allow for host driver to free allocated memory *	Called if no device present or device being unloaded */voidmptscsih_slave_destroy(struct scsi_device *device){	struct Scsi_Host	*host = device->host;	MPT_SCSI_HOST		*hd = (MPT_SCSI_HOST *)host->hostdata;	VirtDevice		*vdev;	uint			target = device->id;	uint			lun = device->lun;	if (hd == NULL)		return;	mptscsih_search_running_cmds(hd, target, lun);	vdev = hd->Targets[target];	vdev->luns[0] &= ~(1 << lun);	if (--vdev->num_luns)		return;	kfree(hd->Targets[target]);	hd->Targets[target] = NULL;	if (hd->ioc->bus_type == SCSI) {		if (mptscsih_is_phys_disk(hd->ioc, target)) {			hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;		} else {			hd->ioc->spi_data.dvStatus[target] =				MPT_SCSICFG_NEGOTIATE;			if (!hd->negoNvram) {				hd->ioc->spi_data.dvStatus[target] |=					MPT_SCSICFG_DV_NOT_DONE;			}		}	}}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* *	mptscsih_change_queue_depth - This function will set a devices queue depth *	@sdev: per scsi_device pointer *	@qdepth: requested queue depth * *	Adding support for new 'change_queue_depth' api.*/intmptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth){	MPT_SCSI_HOST	*hd = (MPT_SCSI_HOST *)sdev->host->hostdata;	VirtDevice *pTarget;	int	max_depth;	int	tagged;	if (hd == NULL)		return 0;	if (!(pTarget = hd->Targets[sdev->id]))		return 0;	if (hd->ioc->bus_type == SCSI) {		if (pTarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {			if (!(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES))				max_depth = 1;

⌨️ 快捷键说明

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