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

📄 mptscsih.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	hd->taskQcnt = 0;			/* Allocate memory for the device structures.	 * A non-Null pointer at an offset	 * indicates a device exists.	 * max_id = 1 + maximum id (hosts.h)	 */	sz = sh->max_id * sizeof(void *);	mem = kmalloc(sz, GFP_ATOMIC);	if (mem == NULL) {		error = -ENOMEM;		goto mptscsih_probe_failed;	}	memset(mem, 0, sz);	hd->Targets = (VirtDevice **) mem;	dprintk((KERN_INFO	  "  Targets @ %p, sz=%d\n", hd->Targets, sz));	/* Clear the TM flags	 */	hd->tmPending = 0;	hd->tmState = TM_STATE_NONE;	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;	/* 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 */	/* ioc->sh = sh;	*/#ifdef MPTSCSIH_DBG_TIMEOUT	hd->ioc->timeout_hard = 0;	hd->ioc->timeout_delta = 30 * HZ;	hd->ioc->timeout_maxcnt = 0;	hd->ioc->timeout_cnt = 0;	for (ii=0; ii < 8; ii++)		foo_to[ii] = NULL;#endif	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->ioc->spi_data.Saf_Te = driver_setup.saf_te;		hd->negoNvram = 0;#ifndef MPTSCSIH_ENABLE_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 saf_te %x\n",			hd->ioc->name, driver_setup.dv,			driver_setup.max_width,			driver_setup.min_sync_fac,			driver_setup.saf_te));	}	mpt_scsi_hosts++;	error = scsi_add_host (sh, &ioc->pcidev->dev);	if(error) {		dprintk((KERN_ERR MYNAM		  "scsi_add_host failed\n"));		goto mptscsih_probe_failed;	}	scsi_scan_host(sh);	return 0;mptscsih_probe_failed:	mptscsih_remove(pdev);	return error;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* *	mptscsih_remove - Removed scsi devices *	@pdev: Pointer to pci_dev structure * * */static voidmptscsih_remove(struct pci_dev *pdev){	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);	struct Scsi_Host 	*host = ioc->sh;	MPT_SCSI_HOST		*hd;	int 		 	count;	unsigned long	 	flags;	if(!host)		return;	scsi_remove_host(host);#ifdef MPTSCSIH_ENABLE_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	hd = (MPT_SCSI_HOST *)host->hostdata;	if (hd != NULL) {		int sz1, sz2, sz3, sztarget=0;		int szr2chain = 0;		int szc2chain = 0;		int szQ = 0;		mptscsih_shutdown(&pdev->dev);		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->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) Target (%d+%d) memory\n",		  hd->ioc->name, sz1, sz3, sztarget));		dprintk(("Free'd done and free Q (%d) memory\n", szQ));		/* NULL the Scsi_Host pointer		 */		hd->ioc->sh = NULL;	}	scsi_host_put(host);	mpt_scsi_hosts--;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* *	mptscsih_shutdown - reboot notifier * */static voidmptscsih_shutdown(struct device * dev){	MPT_ADAPTER 		*ioc = pci_get_drvdata(to_pci_dev(dev));	struct Scsi_Host 	*host = ioc->sh;	MPT_SCSI_HOST		*hd;	if(!host)		return;	hd = (MPT_SCSI_HOST *)host->hostdata;	/* Flush the cache of this adapter	 */	if(hd != NULL)		mptscsih_synchronize_cache(hd, 0);}#ifdef CONFIG_PM/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* *	mptscsih_suspend - Fusion MPT scsie driver suspend routine. * * */static intmptscsih_suspend(struct pci_dev *pdev, u32 state){	mptscsih_shutdown(&pdev->dev);	return 0;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* *	mptscsih_resume - Fusion MPT scsi driver resume routine. * * */static intmptscsih_resume(struct pci_dev *pdev){	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);	struct Scsi_Host 	*host = ioc->sh;	MPT_SCSI_HOST		*hd;	if(!host)		return 0;	hd = (MPT_SCSI_HOST *)host->hostdata;	if(!hd)		return 0;#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION	{	unsigned long lflags;	spin_lock_irqsave(&dvtaskQ_lock, lflags);	if (!dvtaskQ_active) {		dvtaskQ_active = 1;		spin_unlock_irqrestore(&dvtaskQ_lock, lflags);		INIT_WORK(&mptscsih_dvTask,		  mptscsih_domainValidation, (void *) hd);		schedule_work(&mptscsih_dvTask);	} else {		spin_unlock_irqrestore(&dvtaskQ_lock, lflags);	}	}#endif	return 0;}#endifstatic struct mpt_pci_driver mptscsih_driver = {	.probe		= mptscsih_probe,	.remove		= mptscsih_remove,	.shutdown	= mptscsih_shutdown,#ifdef CONFIG_PM	.suspend	= mptscsih_suspend,	.resume		= mptscsih_resume,#endif};/*  SCSI host fops start here...  *//*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	mptscsih_init - Register MPT adapter(s) as SCSI host(s) with *	linux scsi mid-layer. * *	Returns 0 for success, non-zero for failure. */static int __initmptscsih_init(void){	show_mptmod_ver(my_NAME, my_VERSION);	ScsiDoneCtx = mpt_register(mptscsih_io_done, MPTSCSIH_DRIVER);	ScsiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSCSIH_DRIVER);	ScsiScanDvCtx = mpt_register(mptscsih_scandv_complete, MPTSCSIH_DRIVER);	if (mpt_event_register(ScsiDoneCtx, mptscsih_event_process) == 0) {		dprintk((KERN_INFO MYNAM		  ": Registered for IOC event notifications\n"));	}	if (mpt_reset_register(ScsiDoneCtx, mptscsih_ioc_reset) == 0) {		dprintk((KERN_INFO MYNAM		  ": Registered for IOC reset notifications\n"));	}#ifdef MODULE	/* Evaluate the command line arguments, if any */	if (mptscsih)		mptscsih_setup(mptscsih);#endif	if(mpt_device_driver_register(&mptscsih_driver,	  MPTSCSIH_DRIVER) != 0 ) {		dprintk((KERN_INFO MYNAM		": failed to register dd callbacks\n"));	}	return 0;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	mptscsih_exit - Unregisters MPT adapter(s) * */static void __exitmptscsih_exit(void){	mpt_device_driver_deregister(MPTSCSIH_DRIVER);	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);}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	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;	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;

⌨️ 快捷键说明

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