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

📄 mptscsih.c

📁 一个2.4.21版本的嵌入式linux内核
💻 C
📖 第 1 页 / 共 5 页
字号:
#endif				hd->resetPending = 0;				hd->abortSCpnt = NULL;				hd->tmPtr = NULL;				hd->numTMrequests = 0;				/* Clear the pointer used to store				 * single-threaded commands, i.e., those				 * issued during a bus scan, dv and				 * configuration pages.				 */				hd->cmdPtr = NULL;				/* Attach the SCSI Host to the IOC structure				 */				this->sh = sh;				/* Initialize this SCSI Hosts' timers				 * To use, set the timer expires field				 * and add_timer				 */				init_timer(&hd->timer);				hd->timer.data = (unsigned long) hd;				hd->timer.function = mptscsih_timer_expired;				init_timer(&hd->TMtimer);				hd->TMtimer.data = (unsigned long) hd;				hd->TMtimer.function = mptscsih_taskmgmt_timeout;				hd->qtag_tick = jiffies;				/* Moved Earlier Pam D */				/* this->sh = sh;	*/				if (hd->is_spi) {					/* Update with the driver setup					 * values.					 */					if (hd->ioc->spi_data.maxBusWidth > driver_setup.max_width)						hd->ioc->spi_data.maxBusWidth = driver_setup.max_width;					if (hd->ioc->spi_data.minSyncFactor < driver_setup.min_sync_fac)						hd->ioc->spi_data.minSyncFactor = driver_setup.min_sync_fac;					if (hd->ioc->spi_data.minSyncFactor == MPT_ASYNC)						hd->ioc->spi_data.maxSyncOffset = 0;					hd->negoNvram = 0;#ifdef MPTSCSIH_DISABLE_DOMAIN_VALIDATION					hd->negoNvram = MPT_SCSICFG_USE_NVRAM;#endif					if (driver_setup.dv == 0)						hd->negoNvram = MPT_SCSICFG_USE_NVRAM;					hd->ioc->spi_data.forceDv = 0;					for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++)						hd->ioc->spi_data.dvStatus[ii] = MPT_SCSICFG_NEGOTIATE;						if (hd->negoNvram == 0) {						for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++)							hd->ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_DV_NOT_DONE;					}					ddvprintk((MYIOC_s_INFO_FMT						"dv %x width %x factor %x \n",						hd->ioc->name, driver_setup.dv,						driver_setup.max_width,						driver_setup.min_sync_fac));				}				mpt_scsi_hosts++;			}		}	/* for each adapter port */		this = mpt_adapter_find_next(this);	}done:	if (mpt_scsi_hosts > 0)		register_reboot_notifier(&mptscsih_notifier);	else {		mpt_reset_deregister(ScsiDoneCtx);		dprintk((KERN_INFO MYNAM ": Deregistered for IOC reset notifications\n"));		mpt_event_deregister(ScsiDoneCtx);		dprintk((KERN_INFO MYNAM ": Deregistered for IOC event notifications\n"));		mpt_deregister(ScsiScanDvCtx);		mpt_deregister(ScsiTaskCtx);		mpt_deregister(ScsiDoneCtx);		if (info_kbuf != NULL)			kfree(info_kbuf);	}	return mpt_scsi_hosts;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	mptscsih_release - Unregister SCSI host from linux scsi mid-layer *	@host: Pointer to Scsi_Host structure * *	(linux Scsi_Host_Template.release routine) *	This routine releases all resources associated with the SCSI host *	adapter. * *	Returns 0 for success. */intmptscsih_release(struct Scsi_Host *host){	MPT_SCSI_HOST	*hd;	int 		 count;	unsigned long	 flags;	hd = (MPT_SCSI_HOST *) host->hostdata;#ifndef MPT_SCSI_USE_NEW_EH#ifndef MPTSCSIH_DISABLE_DOMAIN_VALIDATION	spin_lock_irqsave(&dvtaskQ_lock, flags);	dvtaskQ_release = 1;	spin_unlock_irqrestore(&dvtaskQ_lock, flags);#endif	count = 10 * HZ;	spin_lock_irqsave(&mytaskQ_lock, flags);	if (mytaskQ_bh_active) {		spin_unlock_irqrestore(&mytaskQ_lock, flags);		dprintk((KERN_INFO MYNAM ": Info: Zapping TaskMgmt thread!\n"));		clean_taskQ(hd);		while(mytaskQ_bh_active && --count) {			set_current_state(TASK_INTERRUPTIBLE);			schedule_timeout(1);		}	} else {		spin_unlock_irqrestore(&mytaskQ_lock, flags);	}	if (!count)		printk(KERN_ERR MYNAM ": ERROR - TaskMgmt thread still active!\n");#endif#ifndef MPTSCSIH_DISABLE_DOMAIN_VALIDATION	/* Check DV thread active */	count = 10 * HZ;	spin_lock_irqsave(&dvtaskQ_lock, flags);	if (dvtaskQ_active) {		spin_unlock_irqrestore(&dvtaskQ_lock, flags);		while(dvtaskQ_active && --count) {			set_current_state(TASK_INTERRUPTIBLE);			schedule_timeout(1);		}	} else {		spin_unlock_irqrestore(&dvtaskQ_lock, flags);	}	if (!count)		printk(KERN_ERR MYNAM ": ERROR - DV thread still active!\n");#if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)	else		printk(KERN_ERR MYNAM ": DV thread orig %d, count %d\n", 10 * HZ, count);#endif#endif	unregister_reboot_notifier(&mptscsih_notifier);	if (hd != NULL) {		int sz1, sz2, sz3, sztarget=0;		int szr2chain = 0;		int szc2chain = 0;		int szchain = 0;		int szQ = 0;		/* Synchronize disk caches		 */		(void) mptscsih_synchronize_cache(hd, 0);		sz1 = sz2 = sz3 = 0;		if (hd->ScsiLookup != NULL) {			sz1 = hd->ioc->req_depth * sizeof(void *);			kfree(hd->ScsiLookup);			hd->ScsiLookup = NULL;		}		if (hd->ReqToChain != NULL) {			szr2chain = hd->ioc->req_depth * sizeof(int);			kfree(hd->ReqToChain);			hd->ReqToChain = NULL;		}		if (hd->ChainToChain != NULL) {			szc2chain = hd->num_chain * sizeof(int);			kfree(hd->ChainToChain);			hd->ChainToChain = NULL;		}		if (hd->ChainBuffer != NULL) {			sz2 = hd->num_chain * hd->ioc->req_sz;			szchain = szr2chain + szc2chain + sz2;			pci_free_consistent(hd->ioc->pcidev, sz2,				    hd->ChainBuffer, hd->ChainBufferDMA);			hd->ChainBuffer = NULL;		}		if (hd->memQ != NULL) {			szQ = host->can_queue * sizeof(MPT_DONE_Q);			kfree(hd->memQ);			hd->memQ = NULL;		}		if (hd->Targets != NULL) {			int max, ii;			/*			 * Free any target structures that were allocated.			 */			if (hd->is_spi) {				max = MPT_MAX_SCSI_DEVICES;			} else {				max = MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255;			}			for (ii=0; ii < max; ii++) {				if (hd->Targets[ii]) {					kfree(hd->Targets[ii]);					hd->Targets[ii] = NULL;					sztarget += sizeof(VirtDevice);				}			}			/*			 * Free pointer array.			 */			sz3 = max * sizeof(void *);			kfree(hd->Targets);			hd->Targets = NULL;		}		dprintk((MYIOC_s_INFO_FMT "Free'd ScsiLookup (%d), chain (%d) and Target (%d+%d) memory\n",				hd->ioc->name, sz1, szchain, sz3, sztarget));		dprintk(("Free'd done and free Q (%d) memory\n", szQ));	}	/* NULL the Scsi_Host pointer	 */	hd->ioc->sh = NULL;	scsi_unregister(host);	if (mpt_scsi_hosts) {		if (--mpt_scsi_hosts == 0) {			mpt_reset_deregister(ScsiDoneCtx);			dprintk((KERN_INFO MYNAM ": Deregistered for IOC reset notifications\n"));			mpt_event_deregister(ScsiDoneCtx);			dprintk((KERN_INFO MYNAM ": Deregistered for IOC event notifications\n"));			mpt_deregister(ScsiScanDvCtx);			mpt_deregister(ScsiTaskCtx);			mpt_deregister(ScsiDoneCtx);			if (info_kbuf != NULL)				kfree(info_kbuf);		}	}	return 0;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	mptscsih_halt - Process the reboot notification *	@nb: Pointer to a struct notifier_block (ignored) *	@event: event (SYS_HALT, SYS_RESTART, SYS_POWER_OFF) *	@buf: Pointer to a data buffer (ignored) * *	This routine called if a system shutdown or reboot is to occur. * *	Return NOTIFY_DONE if this is something other than a reboot message. *		NOTIFY_OK if this is a reboot message. */static intmptscsih_halt(struct notifier_block *nb, ulong event, void *buf){	MPT_ADAPTER *ioc = NULL;	MPT_SCSI_HOST *hd = NULL;	/* Ignore all messages other than reboot message	 */	if ((event != SYS_RESTART) && (event != SYS_HALT)		&& (event != SYS_POWER_OFF))		return (NOTIFY_DONE);	for (ioc = mpt_adapter_find_first(); ioc != NULL; ioc =	mpt_adapter_find_next(ioc)) {		/* Flush the cache of this adapter		 */		if (ioc->sh) {			hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;			if (hd) {				mptscsih_synchronize_cache(hd, 0);			}		}	}	unregister_reboot_notifier(&mptscsih_notifier);	return NOTIFY_OK;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	mptscsih_info - Return information about MPT adapter *	@SChost: Pointer to Scsi_Host structure * *	(linux Scsi_Host_Template.info routine) * *	Returns pointer to buffer where information was written. */const char *mptscsih_info(struct Scsi_Host *SChost){	MPT_SCSI_HOST *h = NULL;	int size = 0;	if (info_kbuf == NULL)		if ((info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)			return info_kbuf;	h = (MPT_SCSI_HOST *)SChost->hostdata;	info_kbuf[0] = '\0';	if (h) {		mpt_print_ioc_summary(h->ioc, info_kbuf, &size, 0, 0);		info_kbuf[size-1] = '\0';	}	return info_kbuf;}struct info_str {	char *buffer;	int   length;	int   offset;	int   pos;};static void copy_mem_info(struct info_str *info, char *data, int len){	if (info->pos + len > info->length)		len = info->length - info->pos;	if (info->pos + len < info->offset) {		info->pos += len;		return;	}	if (info->pos < info->offset) {	        data += (info->offset - info->pos);	        len  -= (info->offset - info->pos);	}	if (len > 0) {                memcpy(info->buffer + info->pos, data, len);                info->pos += len;	}}static int copy_info(struct info_str *info, char *fmt, ...){	va_list args;	char buf[81];	int len;	va_start(args, fmt);	len = vsprintf(buf, fmt, args);	va_end(args);	copy_mem_info(info, buf, len);	return len;}static int mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len){	struct info_str info;	info.buffer	= pbuf;	info.length	= len;	info.offset	= offset;	info.pos	= 0;	copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);	copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);	copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);	copy_info(&info, "MaxQ=%d\n", ioc->req_depth);	return ((info.pos > info.offset) ? info.pos - info.offset : 0);}static int mptscsih_user_command(MPT_ADAPTER *ioc, char *pbuf, int len){	/* Not yet implemented */	return len;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	mptscsih_proc_info - Return information about MPT adapter * *	(linux Scsi_Host_Template.info routine) * * 	buffer: if write, user data; if read, buffer for user * 	length: if write, return length; * 	offset: if write, 0; if read, the current offset into the buffer from * 		the previous read. * 	hostno: scsi host number *	func:   if write = 1; if read = 0 */int mptscsih_proc_info(char *buffer, char **start, off_t offset,			int length, int hostno, int func){	MPT_ADAPTER	*ioc = NULL;	MPT_SCSI_HOST	*hd = NULL;	int size = 0;	dprintk(("Called mptscsih_proc_info: hostno=%d, func=%d\n", hostno, func));	dprintk(("buffer %p, start=%p (%p) offset=%ld length = %d\n",			buffer, start, *start, offset, length));	for (ioc = mpt_adapter_find_first(); ioc != NULL; ioc = mpt_adapter_find_next(ioc)) {		if ((ioc->sh) && (ioc->sh->host_no == hostno)) {			hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;			break;		}	}	if ((ioc == NULL) || (ioc->sh == NULL) || (hd == NULL))		return 0;	if (func) {		size = mptscsih_user_command(ioc, buffer, length);	} else {		if (start)			*start = buffer;		size = mptscsih_host_info(ioc, buffer, offset, length);	}	return size;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/	static int max_qd = 1;#if 0static int index_log[128];static int index_ent = 0;static __inline__ void ADD_INDEX_LOG(int req_ent){	int i = index_ent++;	index_log[i & (128 - 1)] = req_ent;}#else#define ADD_INDEX_LOG(req_e

⌨️ 快捷键说明

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