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

📄 mptbase.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	mem_phys = msize = 0;	port = psize = 0;	for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {		if (pdev->PCI_BASEADDR_FLAGS(ii) & PCI_BASE_ADDRESS_SPACE_IO) {			/* Get I/O space! */			port = pdev->PCI_BASEADDR_START(ii);			psize = PCI_BASEADDR_SIZE(pdev,ii);		} else {			/* Get memmap */			mem_phys = pdev->PCI_BASEADDR_START(ii);			msize = PCI_BASEADDR_SIZE(pdev,ii);			break;		}	}	ioc->mem_size = msize;	if (ii == DEVICE_COUNT_RESOURCE) {		printk(KERN_ERR MYNAM ": ERROR - MPT adapter has no memory regions defined!\n");		kfree(ioc);		return -EINVAL;	}	dprintk((KERN_INFO MYNAM ": MPT adapter @ %lx, msize=%dd bytes\n", mem_phys, msize));	dprintk((KERN_INFO MYNAM ": (port i/o @ %lx, psize=%dd bytes)\n", port, psize));	dprintk((KERN_INFO MYNAM ": Using %s register access method\n", PortIo ? "PortIo" : "MemMap"));	mem = NULL;	if (! PortIo) {		/* Get logical ptr for PciMem0 space */		/*mem = ioremap(mem_phys, msize);*/		mem = ioremap(mem_phys, 0x100);		if (mem == NULL) {			printk(KERN_ERR MYNAM ": ERROR - Unable to map adapter memory!\n");			kfree(ioc);			return -EINVAL;		}		ioc->memmap = mem;	}	dprintk((KERN_INFO MYNAM ": mem = %p, mem_phys = %lx\n", mem, mem_phys));	dprintk((KERN_INFO MYNAM ": facts @ %p, pfacts[0] @ %p\n",			&ioc->facts, &ioc->pfacts[0]));	if (PortIo) {		u8 *pmem = (u8*)port;		ioc->mem_phys = port;		ioc->chip = (SYSIF_REGS*)pmem;	} else {		ioc->mem_phys = mem_phys;		ioc->chip = (SYSIF_REGS*)mem;	}	/* Save Port IO values incase we need to do downloadboot */	{		u8 *pmem = (u8*)port;		ioc->pio_mem_phys = port;		ioc->pio_chip = (SYSIF_REGS*)pmem;	}	ioc->chip_type = FCUNK;	if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC909) {		ioc->chip_type = FC909;		ioc->prod_name = "LSIFC909";	}	else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929) {		ioc->chip_type = FC929;		ioc->prod_name = "LSIFC929";	}	else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919) {		ioc->chip_type = FC919;		ioc->prod_name = "LSIFC919";	}	else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929X) {		ioc->chip_type = FC929X;		pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);		if (revision < XL_929) {			ioc->prod_name = "LSIFC929X";			/* 929X Chip Fix. Set Split transactions level		 	* for PCIX. Set MOST bits to zero.		 	*/			pci_read_config_byte(pdev, 0x6a, &pcixcmd);			pcixcmd &= 0x8F;			pci_write_config_byte(pdev, 0x6a, pcixcmd);		} else {			ioc->prod_name = "LSIFC929XL";			/* 929XL Chip Fix. Set MMRBC to 0x08.		 	*/			pci_read_config_byte(pdev, 0x6a, &pcixcmd);			pcixcmd |= 0x08;			pci_write_config_byte(pdev, 0x6a, pcixcmd);		}	}	else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919X) {		ioc->chip_type = FC919X;		ioc->prod_name = "LSIFC919X";		/* 919X Chip Fix. Set Split transactions level		 * for PCIX. Set MOST bits to zero.		 */		pci_read_config_byte(pdev, 0x6a, &pcixcmd);		pcixcmd &= 0x8F;		pci_write_config_byte(pdev, 0x6a, pcixcmd);	}	else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) {		ioc->chip_type = C1030;		ioc->prod_name = "LSI53C1030";		/* 1030 Chip Fix. Disable Split transactions		 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).		 */		pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);		if (revision < C0_1030) {			pci_read_config_byte(pdev, 0x6a, &pcixcmd);			pcixcmd &= 0x8F;			pci_write_config_byte(pdev, 0x6a, pcixcmd);		}	}	else if (pdev->device == MPI_MANUFACTPAGE_DEVID_1030_53C1035) {		ioc->chip_type = C1035;		ioc->prod_name = "LSI53C1035";	}	sprintf(ioc->name, "ioc%d", 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);	/* tack onto tail of our MPT adapter list */	Q_ADD_TAIL(&MptAdapters, ioc, MPT_ADAPTER);	/* Set lookup ptr. */	mpt_adapters[ioc->id] = ioc;	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			Q_DEL_ITEM(ioc);			mpt_adapters[ioc->id] = NULL;			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	}	/* NEW!  20010220 -sralston	 * Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.	 */	if ((ioc->chip_type == FC929) || (ioc->chip_type == C1030)			|| (ioc->chip_type == C1035) || (ioc->chip_type == FC929X))		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;	int	 ret = 0;	int	 reset_alt_ioc_active = 0;	printk(KERN_INFO MYNAM ": Initiating %s %s\n",			ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");	/* Disable reply interrupts (also blocks FreeQ) */	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);	ioc->active = 0;	if (ioc->alt_ioc) {		if (ioc->alt_ioc->active)			reset_alt_ioc_active = 1;		/* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */		CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);		ioc->alt_ioc->active = 0;	}	hard = 1;	if (reason == MPT_HOSTEVENT_IOC_BRINGUP)		hard = 0;	if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {		if (hard_reset_done == -4) {			printk(KERN_WARNING MYNAM ": %s Owned by PEER..skipping!\n",					ioc->name);			if (reset_alt_ioc_active && ioc->alt_ioc) {				/* (re)Enable alt-IOC! (reply interrupt, FreeQ) */				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;			}		} else {			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 && reset_alt_ioc_active && 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);	}	for (ii=0; ii<5; ii++) {	/* Get IOC facts! Allow 1 retry */	if ((r = GetIocFacts(ioc, sleepFlag, reason)) != 0) {		dinitprintk((MYIOC_s_INFO_FMT "ii=%d IocFacts failed r=%x\n", ioc->name, ii, r));	} else		break;	}		if (r) {		dinitprintk((MYIOC_s_INFO_FMT "Retry IocFacts failed r=%x\n", ioc->name, r));		ret = -2;	} else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {		MptDisplayIocCapabilities(ioc);	}	if (alt_ioc_ready) {		if ((r = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {			dinitprintk((MYIOC_s_INFO_FMT "Initial Alt IocFacts failed r=%x\n", ioc->name, r));			/* Retry - alt IOC was initialized once			 */			r = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);		}		if (r) {			dinitprintk((MYIOC_s_INFO_FMT "Retry Alt IocFacts failed r=%x\n", ioc->name, r));			alt_ioc_ready = 0;			reset_alt_ioc_active = 0;		} else 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 fails, continue with alt-ioc processing	 */	if ((ret == 0) && ((r = PrimeIocFifos(ioc)) != 0))		ret = -3;	/* May need to check/upload firmware & data here!	 * If fails, continue with alt-ioc processing	 */	if ((ret == 0) && ((r = SendIocInit(ioc, sleepFlag)) != 0))		ret = -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;		reset_alt_ioc_active = 0;	}	if (alt_ioc_ready) {		if ((r = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {			alt_ioc_ready = 0;			reset_alt_ioc_active = 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->upload_fw) {			ddlprintk((MYIOC_s_INFO_FMT				"firmware upload required!\n", ioc->name));			/* Controller is not operational, cannot do upload			 */			if (ret == 0) {				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) && (ioc->alt_ioc->upload_fw)){				ddlprintk((MYIOC_s_INFO_FMT					"Alt-ioc firmware upload required!\n",					ioc->name));				r = mpt_do_upload(ioc->alt_ioc, sleepFlag);				if (r != 0)					printk(KERN_WARNING MYNAM ": firmware upload failure!\n");			}		}	}	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) */		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 ((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 */	/* (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 ((ret == 0) && (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);			/* 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) {		r = 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));				r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_POST_RESET);				handlers++;			}

⌨️ 快捷键说明

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