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

📄 mptbase.c

📁 microwindows移植到S3C44B0的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
			u16 pcixcmd = 0;			pci_read_config_word(pdev, 0x6a, &pcixcmd);			pcixcmd &= 0xFF8F;			pci_write_config_word(pdev, 0x6a, pcixcmd);		}	}	myname = "iocN";	len = strlen(myname);	memcpy(ioc->name, myname, len+1);	ioc->name[len-1] = '0' + ioc->id;	Q_INIT(&ioc->FreeQ, MPT_FRAME_HDR);	spin_lock_init(&ioc->FreeQlock);	/* Disable all! */	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);	ioc->active = 0;	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);	ioc->pci_irq = -1;	if (pdev->irq) {		r = request_irq(pdev->irq, mpt_interrupt, SA_SHIRQ, ioc->name, ioc);		if (r < 0) {#ifndef __sparc__			printk(MYIOC_s_ERR_FMT "Unable to allocate interrupt %d!\n",					ioc->name, pdev->irq);#else			printk(MYIOC_s_ERR_FMT "Unable to allocate interrupt %s!\n",					ioc->name, __irq_itoa(pdev->irq));#endif			iounmap(mem);			kfree(ioc);			return -EBUSY;		}		ioc->pci_irq = pdev->irq;		pci_set_master(pdev);			/* ?? */#ifndef __sparc__		dprintk((KERN_INFO MYNAM ": %s installed at interrupt %d\n", ioc->name, pdev->irq));#else		dprintk((KERN_INFO MYNAM ": %s installed at interrupt %s\n", ioc->name, __irq_itoa(pdev->irq)));#endif	}	/* tack onto tail of our MPT adapter list */	Q_ADD_TAIL(&MptAdapters, ioc, MPT_ADAPTER);	/* Set lookup ptr. */	mpt_adapters[ioc->id] = ioc;	/* NEW!  20010220 -sralston	 * Check for "bound ports" (929, 1030) to reduce redundant resets.	 */	if ((ioc->chip_type == FC929) || (ioc->chip_type == C1030))		mpt_detect_bound_ports(ioc, pdev);	if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP, CAN_SLEEP)) != 0) {		printk(KERN_WARNING MYNAM ": WARNING - %s did not initialize properly! (%d)\n",				ioc->name, r);	}	return r;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* *	mpt_do_ioc_recovery - Initialize or recover MPT adapter. *	@ioc: Pointer to MPT adapter structure *	@reason: Event word / reason *	@sleepFlag: Use schedule if CAN_SLEEP else use udelay. * *	This routine performs all the steps necessary to bring the IOC *	to a OPERATIONAL state. * *	This routine also pre-fetches the LAN MAC address of a Fibre Channel *	MPT adapter. * *	Returns: *		 0 for success *		-1 if failed to get board READY *		-2 if READY but IOCFacts Failed *		-3 if READY but PrimeIOCFifos Failed *		-4 if READY but IOCInit Failed */static intmpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag){	int	 hard_reset_done = 0;	int	 alt_ioc_ready = 0;	int	 hard;	int	 r;	int	 ii;	int	 handlers;	printk(KERN_INFO MYNAM ": Initiating %s %s\n",			ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");	/* Disable reply interrupts */	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);	ioc->active = 0;	/* NOTE: Access to IOC's request FreeQ is now blocked! */	if (ioc->alt_ioc) {		/* Disable alt-IOC's reply interrupts for a bit ... */		CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);		ioc->alt_ioc->active = 0;		/* NOTE: Access to alt-IOC's request FreeQ is now blocked! */	}	hard = 1;	if (reason == MPT_HOSTEVENT_IOC_BRINGUP)		hard = 0;	if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {		printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n",				ioc->name);		return -1;	}	/* hard_reset_done = 0 if a soft reset was performed	 * and 1 if a hard reset was performed.	 */	if (hard_reset_done && ioc->alt_ioc) {		if ((r = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)			alt_ioc_ready = 1;		else			printk(KERN_WARNING MYNAM					": alt-%s: (%d) Not ready WARNING!\n",					ioc->alt_ioc->name, r);	}	/* Get IOC facts! */	if ((r = GetIocFacts(ioc, sleepFlag, reason)) != 0)		return -2;	if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {		MptDisplayIocCapabilities(ioc);	}	if (alt_ioc_ready) {		if ((r = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0)			return -2;		if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {			MptDisplayIocCapabilities(ioc->alt_ioc);		}	}	/*	 * Prime reply & request queues!	 * (mucho alloc's) Must be done prior to	 * init as upper addresses are needed for init.	 */	if ((r = PrimeIocFifos(ioc)) != 0)		return -3;	// May need to check/upload firmware & data here!	if ((r = SendIocInit(ioc, sleepFlag)) != 0)		return -4;// NEW!	if (alt_ioc_ready && ((r = PrimeIocFifos(ioc->alt_ioc)) != 0)) {		printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",				ioc->alt_ioc->name, r);		alt_ioc_ready = 0;	}	if (alt_ioc_ready) {		if ((r = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {			alt_ioc_ready = 0;			printk(KERN_WARNING MYNAM				": alt-%s: (%d) init failure WARNING!\n",					ioc->alt_ioc->name, r);		}	}	if (reason == MPT_HOSTEVENT_IOC_BRINGUP){		if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT) {			dprintk((MYIOC_s_INFO_FMT				"firmware upload required!\n", ioc->name));			r = mpt_do_upload(ioc, sleepFlag);			if (r != 0)				printk(KERN_WARNING MYNAM ": firmware upload failure!\n");			/* Handle the alt IOC too */			if (alt_ioc_ready){				r = mpt_do_upload(ioc->alt_ioc, sleepFlag);				if (r != 0)					printk(KERN_WARNING MYNAM ": firmware upload failure!\n");			}		}	}	/* Enable! (reply interrupt) */	CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));	ioc->active = 1;	if (ioc->alt_ioc) {		/* (re)Enable alt-IOC! (reply interrupt) */		dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",				ioc->alt_ioc->name));		CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM));		ioc->alt_ioc->active = 1;	}	/* NEW!  20010120 -sralston	 *  Enable MPT base driver management of EventNotification	 *  and EventAck handling.	 */	if (!ioc->facts.EventState)		(void) SendEventNotification(ioc, 1);	/* 1=Enable EventNotification */	if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)		(void) SendEventNotification(ioc->alt_ioc, 1);	/* 1=Enable EventNotification */	/* (Bugzilla:fibrebugs, #513)	 * Bug fix (part 2)!  20010905 -sralston	 *	Add additional "reason" check before call to GetLanConfigPages	 *	(combined with GetIoUnitPage2 call).  This prevents a somewhat	 *	recursive scenario; GetLanConfigPages times out, timer expired	 *	routine calls HardResetHandler, which calls into here again,	 *	and we try GetLanConfigPages again...	 */	if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {		if ((int)ioc->chip_type <= (int)FC929) {			/*			 *  Pre-fetch FC port WWN and stuff...			 *  (FCPortPage0_t stuff)			 */			for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {				(void) GetFcPortPage0(ioc, ii);			}			if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&			    (ioc->lan_cnfg_page0.Header.PageLength == 0)) {				/*				 *  Pre-fetch the ports LAN MAC address!				 *  (LANPage1_t stuff)				 */				(void) GetLanConfigPages(ioc);#ifdef MPT_DEBUG				{					u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;					dprintk((MYIOC_s_INFO_FMT "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",							ioc->name, a[5], a[4], a[3], a[2], a[1], a[0] ));				}#endif			}		} else {			/* Get NVRAM and adapter maximums from SPP 0 and 2			 */			mpt_GetScsiPortSettings(ioc, 0);			/* Get version and length of SDP 1 			 */			mpt_readScsiDevicePageHeaders(ioc, 0);			/* Find IM volumes 			 */			if (ioc->facts.MsgVersion >= 0x0102)				mpt_findImVolumes(ioc);		}		GetIoUnitPage2(ioc);	}	/*	 * Call each currently registered protocol IOC reset handler	 * with post-reset indication.	 * NOTE: If we're doing _IOC_BRINGUP, there can be no	 * MptResetHandlers[] registered yet.	 */	if (hard_reset_done) {		r = handlers = 0;		for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {			if (MptResetHandlers[ii]) {				dprintk((MYIOC_s_INFO_FMT "Calling IOC post_reset handler #%d\n",						ioc->name, ii));				r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_POST_RESET);				handlers++;				if (alt_ioc_ready) {					dprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n",							ioc->name, ioc->alt_ioc->name, ii));					r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_POST_RESET);					handlers++;				}			}		}		/* FIXME?  Examine results here? */	}	return 0;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* *	mpt_detect_bound_ports - Search for PCI bus/dev_function *	which matches PCI bus/dev_function (+/-1) for newly discovered 929 *	or 1030. *	@ioc: Pointer to MPT adapter structure *	@pdev: Pointer to (struct pci_dev) structure * *	If match on PCI dev_function +/-1 is found, bind the two MPT adapters *	using alt_ioc pointer fields in their %MPT_ADAPTER structures. */static voidmpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev){	MPT_ADAPTER *ioc_srch = mpt_adapter_find_first();	unsigned int match_lo, match_hi;	match_lo = pdev->devfn-1;	match_hi = pdev->devfn+1;	dprintk((MYIOC_s_INFO_FMT "PCI bus/devfn=%x/%x, searching for devfn match on %x or %x\n",			ioc->name, pdev->bus->number, pdev->devfn, match_lo, match_hi));	while (ioc_srch != NULL) {		struct pci_dev *_pcidev = ioc_srch->pcidev;		if ((_pcidev->device == pdev->device) &&		    (_pcidev->bus->number == pdev->bus->number) &&		    (_pcidev->devfn == match_lo || _pcidev->devfn == match_hi) ) {			/* Paranoia checks */			if (ioc->alt_ioc != NULL) {				printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",						ioc->name, ioc->alt_ioc->name);				break;			} else if (ioc_srch->alt_ioc != NULL) {				printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",						ioc_srch->name, ioc_srch->alt_ioc->name);				break;			}			dprintk((KERN_INFO MYNAM ": FOUND! binding %s <==> %s\n",					ioc->name, ioc_srch->name));			ioc_srch->alt_ioc = ioc;			ioc->alt_ioc = ioc_srch;			break;		}		ioc_srch = mpt_adapter_find_next(ioc_srch);	}}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* *	mpt_adapter_disable - Disable misbehaving MPT adapter. *	@this: Pointer to MPT adapter structure *	@free: Free up alloc'd reply, request, etc. */static voidmpt_adapter_disable(MPT_ADAPTER *this, int freeup){	if (this != NULL) {		int sz;		u32 state;		/* Disable the FW */		state = mpt_GetIocState(this, 1);		if (state == MPI_IOC_STATE_OPERATIONAL) {			if (SendIocReset(this, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, NO_SLEEP) != 0)				(void) KickStart(this, 1, NO_SLEEP);		}		/* Disable adapter interrupts! */		CHIPREG_WRITE32(&this->chip->IntMask, 0xFFFFFFFF);		this->active = 0;		/* Clear any lingering interrupt */		CHIPREG_WRITE32(&this->chip->IntStatus, 0);		if (freeup && this->reply_alloc != NULL) {			sz = (this->reply_sz * this->reply_depth) + 128;			pci_free_consistent(this->pcidev, sz,					this->reply_alloc, this->reply_alloc_dma);			this->reply_frames = NULL;			this->reply_alloc = NULL;			this->alloc_total -= sz;		}		if (freeup && this->req_alloc != NULL) {			sz = (this->req_sz * this->req_depth) + 128;			/*			 *  Rounding UP to nearest 4-kB boundary here...			 */			sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;			pci_free_consistent(this->pcidev, sz,					this->req_alloc, this->req_alloc_dma);			this->req_frames = NULL;			this->req_alloc = NULL;			this->alloc_total -= sz;		}		if (freeup && this->sense_buf_pool != NULL) {			sz = (this->req_depth * MPT_SENSE_BUFFER_ALLOC);			pci_free_consistent(this->pcidev, sz,					this->sense_buf_pool, this->sense_buf_pool_dma);			this->sense_buf_pool = NULL;			this->alloc_total -= sz;		}		if (freeup && this->events != NULL){			sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);			kfree(this->events);			this->events = NULL;			this->alloc_total -= sz;		}		if (freeup && this->FWImage != NULL) {			sz = this->facts.FWImageSize;			pci_free_consistent(this->pcidev, sz,					this->FWImage, this->FWImage_dma);			this->FWImage = NULL;			this->alloc_total -= sz;		}		if (freeup && this->spi_data.nvram != NULL) {			kfree(this->spi_data.nvram);			this->spi_data.nvram = NULL;		}		if (freeup && this->spi_data.pIocPg3 != NULL) {			kfree(this->spi_data.pIocPg3);			this->spi_data.pIocPg3 = NULL;		}	}}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* *	mpt_adapter_dispose - Free all resources associated with a MPT *	adapter. *	@this: Pointer to MPT adapter structure * *	This routine unregisters h/w resources and frees all alloc'd memory *	associated with a MPT adapter structure. */static voidmpt_adapter_dispose(MPT_ADAPTER *this){	if (this != NULL) {		int sz_first, sz_last;		sz_first = this->alloc_total;		mpt_adapter_disable(this, 1);		if (this->pci_irq != -1) {			free_irq(this->pci_irq, this);

⌨️ 快捷键说明

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