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

📄 mptbase.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
						/*						 * Maintain only one pointer to FW memory						 * so there will not be two attempt to						 * downloadboot onboard dual function						 * chips (mpt_adapter_disable,						 * mpt_diag_reset)						 */						ioc->cached_fw = NULL;						ddlprintk((MYIOC_s_INFO_FMT ": mpt_upload:  alt_%s has cached_fw=%p \n",							ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));					}				} else {					printk(KERN_WARNING MYNAM ": firmware upload failure!\n");					ret = -5;				}			}		}	}	if (ret == 0) {		/* Enable! (reply interrupt) */		CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));		ioc->active = 1;	}	if (reset_alt_ioc_active && ioc->alt_ioc) {		/* (re)Enable alt-IOC! (reply interrupt) */		dinitprintk((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;	}	/*  Enable MPT base driver management of EventNotification	 *  and EventAck handling.	 */	if ((ret == 0) && (!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 */	/*	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 ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {		if (ioc->bus_type == SAS) {			/* clear persistency table */			if(ioc->facts.IOCExceptions &			    MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {				ret = mptbase_sas_persist_operation(ioc,				    MPI_SAS_OP_CLEAR_NOT_PRESENT);				if(ret != 0)					return -1;			}			/* Find IM volumes			 */			mpt_findImVolumes(ioc);		} else if (ioc->bus_type == FC) {			/*			 *  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 >= MPI_VERSION_01_02)				mpt_findImVolumes(ioc);			/* Check, and possibly reset, the coalescing value			 */			mpt_read_ioc_pg_1(ioc);			mpt_read_ioc_pg_4(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) {		rc = handlers = 0;		for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {			if ((ret == 0) && MptResetHandlers[ii]) {				dprintk((MYIOC_s_INFO_FMT "Calling IOC post_reset handler #%d\n",						ioc->name, ii));				rc += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_POST_RESET);				handlers++;			}			if (alt_ioc_ready && MptResetHandlers[ii]) {				drsprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n",						ioc->name, ioc->alt_ioc->name, ii));				rc += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_POST_RESET);				handlers++;			}		}		/* FIXME?  Examine results here? */	}	return ret;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* *	mpt_detect_bound_ports - Search for PCI bus/dev_function *	which matches PCI bus/dev_function (+/-1) for newly discovered 929, *	929X, 1030 or 1035. *	@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){	struct pci_dev *peer=NULL;	unsigned int slot = PCI_SLOT(pdev->devfn);	unsigned int func = PCI_FUNC(pdev->devfn);	MPT_ADAPTER *ioc_srch;	dprintk((MYIOC_s_INFO_FMT "PCI device %s devfn=%x/%x,"	    " searching for devfn match on %x or %x\n",		ioc->name, pci_name(pdev), pdev->bus->number,		pdev->devfn, func-1, func+1));	peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));	if (!peer) {		peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));		if (!peer)			return;	}	list_for_each_entry(ioc_srch, &ioc_list, list) {		struct pci_dev *_pcidev = ioc_srch->pcidev;		if (_pcidev == peer) {			/* 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;		}	}	pci_dev_put(peer);}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* *	mpt_adapter_disable - Disable misbehaving MPT adapter. *	@this: Pointer to MPT adapter structure */static voidmpt_adapter_disable(MPT_ADAPTER *ioc){	int sz;	int ret;	if (ioc->cached_fw != NULL) {		ddlprintk((KERN_INFO MYNAM ": mpt_adapter_disable: Pushing FW onto adapter\n"));		if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)ioc->cached_fw, NO_SLEEP)) < 0) {			printk(KERN_WARNING MYNAM				": firmware downloadboot failure (%d)!\n", ret);		}	}	/* Disable adapter interrupts! */	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);	ioc->active = 0;	/* Clear any lingering interrupt */	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);	if (ioc->alloc != NULL) {		sz = ioc->alloc_sz;		dexitprintk((KERN_INFO MYNAM ": %s.free  @ %p, sz=%d bytes\n",		 	ioc->name, ioc->alloc, ioc->alloc_sz));		pci_free_consistent(ioc->pcidev, sz,				ioc->alloc, ioc->alloc_dma);		ioc->reply_frames = NULL;		ioc->req_frames = NULL;		ioc->alloc = NULL;		ioc->alloc_total -= sz;	}	if (ioc->sense_buf_pool != NULL) {		sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);		pci_free_consistent(ioc->pcidev, sz,				ioc->sense_buf_pool, ioc->sense_buf_pool_dma);		ioc->sense_buf_pool = NULL;		ioc->alloc_total -= sz;	}	if (ioc->events != NULL){		sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);		kfree(ioc->events);		ioc->events = NULL;		ioc->alloc_total -= sz;	}	if (ioc->cached_fw != NULL) {		sz = ioc->facts.FWImageSize;		pci_free_consistent(ioc->pcidev, sz,			ioc->cached_fw, ioc->cached_fw_dma);		ioc->cached_fw = NULL;		ioc->alloc_total -= sz;	}	kfree(ioc->spi_data.nvram);	kfree(ioc->raid_data.pIocPg3);	ioc->spi_data.nvram = NULL;	ioc->raid_data.pIocPg3 = NULL;	if (ioc->spi_data.pIocPg4 != NULL) {		sz = ioc->spi_data.IocPg4Sz;		pci_free_consistent(ioc->pcidev, sz, 			ioc->spi_data.pIocPg4,			ioc->spi_data.IocPg4_dma);		ioc->spi_data.pIocPg4 = NULL;		ioc->alloc_total -= sz;	}	if (ioc->ReqToChain != NULL) {		kfree(ioc->ReqToChain);		kfree(ioc->RequestNB);		ioc->ReqToChain = NULL;	}	kfree(ioc->ChainToChain);	ioc->ChainToChain = NULL;	if (ioc->HostPageBuffer != NULL) {		if((ret = mpt_host_page_access_control(ioc,		    MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {			printk(KERN_ERR MYNAM			   ": %s: host page buffers free failed (%d)!\n",			    __FUNCTION__, ret);		}		dexitprintk((KERN_INFO MYNAM ": %s HostPageBuffer free  @ %p, sz=%d bytes\n",		 	ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));		pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,				ioc->HostPageBuffer,				ioc->HostPageBuffer_dma);		ioc->HostPageBuffer = NULL;		ioc->HostPageBuffer_sz = 0;		ioc->alloc_total -= ioc->HostPageBuffer_sz;	}}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* *	mpt_adapter_dispose - Free all resources associated with a MPT *	adapter. *	@ioc: 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 *ioc){	int sz_first, sz_last;	if (ioc == NULL)		return;	sz_first = ioc->alloc_total;	mpt_adapter_disable(ioc);	if (ioc->pci_irq != -1) {		free_irq(ioc->pci_irq, ioc);		ioc->pci_irq = -1;	}	if (ioc->memmap != NULL) {		iounmap(ioc->memmap);		ioc->memmap = NULL;	}#if defined(CONFIG_MTRR) && 0	if (ioc->mtrr_reg > 0) {		mtrr_del(ioc->mtrr_reg, 0, 0);		dprintk((KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name));	}#endif	/*  Zap the adapter lookup ptr!  */	list_del(&ioc->list);	sz_last = ioc->alloc_total;	dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",			ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));	kfree(ioc);}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* *	MptDisplayIocCapabilities - Disply IOC's capacilities. *	@ioc: Pointer to MPT adapter structure */static voidMptDisplayIocCapabilities(MPT_ADAPTER *ioc){	int i = 0;	printk(KERN_INFO "%s: ", ioc->name);	if (ioc->prod_name && strlen(ioc->prod_name) > 3)		printk("%s: ", ioc->prod_name+3);	printk("Capabilities={");	if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {		printk("Initiator");		i++;	}	if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {		printk("%sTarget", i ? "," : "");		i++;	}	if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {		printk("%sLAN", i ? "," : "");		i++;	}#if 0	/*	 *  This would probably evoke more questions than it's worth	 */	if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {		printk("%sLogBusAddr", i ? "," : "");		i++;	}#endif	printk("}\n");}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* *	MakeIocReady - Get IOC to a READY state, using KickStart if needed. *	@ioc: Pointer to MPT_ADAPTER structure *	@force: Force hard KickStart of IOC *	@sleepFlag: Specifies whether the process can sleep * *	Returns: *		 1 - DIAG reset and READY *		 0 - READY initially OR soft reset and READY *		-1 - Any failure on KickStart *		-2 - Msg Unit Reset Failed *		-3 - IO Unit Reset Failed *		-4 - IOC owned by a PEER */static intMakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag){	u32	 ioc_state;	int	 statefault = 0;	int	 cntdn;	int	 hard_reset_done = 0;	int	 r;	int	 ii;	int	 whoinit;	/* Get current [raw] IOC state  */	ioc_state = mpt_GetIocState(ioc, 0);	dhsprintk((KERN_INFO MYNAM "::MakeIocReady, %s [raw] state=%08x\n", ioc->name, ioc_state));	/*	 *	Check to see if IOC got left/stuck in doorbell handshake	 *	grip of death.  If so, hard reset the IOC.	 */	if (ioc_state & MPI_DOORBELL_ACTIVE) {		statefault = 1;		printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",				ioc->name);	}	/* Is it already READY? */	if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)		return 0;	/*	 *	Check to see if IOC is in FAULT state.	 */	if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {		statefault = 2;		printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",				ioc->name);		printk(KERN_WARNING "           FAULT code = %04xh\n",				ioc_state & MPI_DOORBELL_DATA_MASK);	}	/*	 *	Hmmm...  Did it get left operational?	 */	if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {		dinitprintk((MYIOC_s_INFO_FMT "IOC operational unexpected\n",				ioc->name));		/* Check WhoInit.		 * If PCI Peer, exit.		 * Else, if no fault conditions are pre

⌨️ 快捷键说明

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