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

📄 mptbase.c

📁 上传linux-jx2410的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	mpt_pci_scan - Scan PCI devices for MPT adapters. * *	Returns count of MPT adapters found, keying off of PCI vendor and *	device_id's. */int __initmpt_pci_scan(void){	struct pci_dev *pdev;	struct pci_dev *pdev2;	int found = 0;	int count = 0;	int r;	dprintk((KERN_INFO MYNAM ": Checking for MPT adapters...\n"));	/*	 *  NOTE: The 929 (I believe) will appear as 2 separate PCI devices,	 *  one for each channel.	 */	pci_for_each_dev(pdev) {		pdev2 = NULL;		if (pdev->vendor != 0x1000)			continue;		if ((pdev->device != MPI_MANUFACTPAGE_DEVICEID_FC909) &&		    (pdev->device != MPI_MANUFACTPAGE_DEVICEID_FC929) &&		    (pdev->device != MPI_MANUFACTPAGE_DEVICEID_FC919) &&#if 0		    /* FIXME! C103x family */		    (pdev->device != MPI_MANUFACTPAGE_DEVID_53C1030) &&		    (pdev->device != MPI_MANUFACTPAGE_DEVID_53C1030_ZC) &&		    (pdev->device != MPI_MANUFACTPAGE_DEVID_53C1035) &&#endif		    1) {			dprintk((KERN_INFO MYNAM ": Skipping LSI device=%04xh\n", pdev->device));			continue;		}		/* GRRRRR		 * 929 dual function devices may be presented in Func 1,0 order,		 * but we'd really really rather have them in Func 0,1 order.		 * Do some kind of look ahead here...		 */		if (pdev->devfn & 1) {			pdev2 = pci_peek_next_dev(pdev);			if (pdev2 && (pdev2->vendor == 0x1000) &&			    (PCI_SLOT(pdev2->devfn) == PCI_SLOT(pdev->devfn)) &&			    (pdev2->device == MPI_MANUFACTPAGE_DEVICEID_FC929) &&			    (pdev2->bus->number == pdev->bus->number) &&			    !(pdev2->devfn & 1)) {				dprintk((KERN_INFO MYNAM ": MPT adapter found: PCI bus/dfn=%02x/%02xh, class=%08x, id=%xh\n",			 		pdev2->bus->number, pdev2->devfn, pdev2->class, pdev2->device));				found++;				if ((r = mpt_adapter_install(pdev2)) == 0)					count++;			} else {				pdev2 = NULL;			}		}		dprintk((KERN_INFO MYNAM ": MPT adapter found: PCI bus/dfn=%02x/%02xh, class=%08x, id=%xh\n",			 pdev->bus->number, pdev->devfn, pdev->class, pdev->device));		found++;		if ((r = mpt_adapter_install(pdev)) == 0)			count++;		if (pdev2)			pdev = pdev2;	}	printk(KERN_INFO MYNAM ": %d MPT adapter%s found, %d installed.\n",		 found, (found==1) ? "" : "s", count);	if (!found || !count) {		fusion_exit();		return -ENODEV;	}#ifdef CONFIG_PROC_FS	if (procmpt_create() != 0)		printk(KERN_WARNING MYNAM ": WARNING! - %s creation failed!\n",				MPT_PROCFS_MPTBASEDIR);#endif	return count;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	mpt_verify_adapter - Given a unique IOC identifier, set pointer to *	the associated MPT adapter structure. *	@iocid: IOC unique identifier (integer) *	@iocpp: Pointer to pointer to IOC adapter * *	Returns iocid and sets iocpp. */intmpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp){	MPT_ADAPTER *p;	*iocpp = NULL;	if (iocid >= MPT_MAX_ADAPTERS)		return -1;	p = mpt_adapters[iocid];	if (p == NULL)		return -1;	*iocpp = p;	return iocid;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	mpt_adapter_install - Install a PCI intelligent MPT adapter. *	@pdev: Pointer to pci_dev structure * *	This routine performs all the steps necessary to bring the IOC of *	a MPT adapter to a OPERATIONAL state.  This includes registering *	memory regions, registering the interrupt, and allocating request *	and reply memory pools. * *	This routine also pre-fetches the LAN MAC address of a Fibre Channel *	MPT adapter. * *	Returns 0 for success, non-zero for failure. * *	TODO: Add support for polled controllers */static int __initmpt_adapter_install(struct pci_dev *pdev){	MPT_ADAPTER	*ioc;	char		*myname;	u8		*mem;	unsigned long	 mem_phys;	unsigned long	 port;	u32		 msize;	u32		 psize;	int		 i;	int		 r = -ENODEV;	int		 len;	ioc = kmalloc(sizeof(MPT_ADAPTER), GFP_KERNEL);	if (ioc == NULL) {		printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");		return -ENOMEM;	}	memset(ioc, 0, sizeof(*ioc));	ioc->req_sz = MPT_REQ_SIZE;			/* avoid div by zero! */	ioc->alloc_total = sizeof(MPT_ADAPTER);	ioc->pcidev = pdev;	/* Find lookup slot. */	for (i=0; i < MPT_MAX_ADAPTERS; i++) {		if (mpt_adapters[i] == NULL) {			ioc->id = i;		/* Assign adapter unique id (lookup) */			break;		}	}	if (i == MPT_MAX_ADAPTERS) {		printk(KERN_ERR MYNAM ": ERROR - mpt_adapters[%d] table overflow!\n", i);		kfree(ioc);		return -ENFILE;	}	mem_phys = msize = 0;	port = psize = 0;	for (i=0; i < DEVICE_COUNT_RESOURCE; i++) {		if (pdev->PCI_BASEADDR_FLAGS(i) & PCI_BASE_ADDRESS_SPACE_IO) {			/* Get I/O space! */			port = pdev->PCI_BASEADDR_START(i);			psize = PCI_BASEADDR_SIZE(pdev,i);		} else {			/* Get memmap */			mem_phys = pdev->PCI_BASEADDR_START(i);			msize = PCI_BASEADDR_SIZE(pdev,i);			break;		}	}	ioc->mem_size = msize;	if (i == 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));	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;	}	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";	}#if 0	else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_53C1030) {		ioc->chip_type = C1030;		ioc->prod_name = "LSI53C1030";	}#endif	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) {			printk(KERN_ERR MYNAM ": %s: ERROR - Unable to allocate interrupt %d!\n",					ioc->name, pdev->irq);			iounmap(mem);			kfree(ioc);			return -EBUSY;		}		ioc->pci_irq = pdev->irq;		pci_set_master(pdev);			/* ?? */		dprintk((KERN_INFO MYNAM ": %s installed at interrupt %d\n", ioc->name, pdev->irq));	}	/* 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 "929 bound ports" to reduce redundant resets.	 */	if (ioc->chip_type == FC929)		mpt_detect_929_bound_ports(ioc, pdev);	if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP)) != 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 * *	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. */static intmpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason){	int	 hard_reset_done = 0;	int	 alt_ioc_ready = 0;	int	 hard;	int	 r;	int	 i;	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! */// FIXME? Cleanup all IOC requests here! (or below?)// But watch out for event associated request?	hard = HardReset;	if (ioc->alt_ioc && (reason == MPT_HOSTEVENT_IOC_BRINGUP))		hard = 0;	if ((hard_reset_done = MakeIocReady(ioc, hard)) < 0) {		printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n",				ioc->name);		return -1;	}// NEW!#if 0						// Kiss-of-death!?!	if (ioc->alt_ioc) {// Grrr... Hold off any alt-IOC interrupts (and events) while// handshaking to <this> IOC, needed because?		/* Disable alt-IOC's reply interrupts for a bit ... */		alt_ioc_intmask = CHIPREG_READ32(&ioc->alt_ioc->chip->IntMask);		CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);		ioc->alt_ioc->active = 0;		/* NOTE: Access to alt-IOC's request FreeQ is now blocked! */	}#endif	if (hard_reset_done && ioc->alt_ioc) {		if ((r = MakeIocReady(ioc->alt_ioc, 0)) == 0)			alt_ioc_ready = 1;		else			printk(KERN_WARNING MYNAM ": alt-%s: (%d) Not ready WARNING!\n",					ioc->alt_ioc->name, r);	}	if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {		/* Get IOC facts! */		if ((r = GetIocFacts(ioc)) != 0)			return -2;		MptDisplayIocCapabilities(ioc);	}	/*	 * Call each currently registered protocol IOC reset handler	 * with pre-reset indication.	 * NOTE: If we're doing _IOC_BRINGUP, there can be no	 * MptResetHandlers[] registered yet.	 */	if (hard_reset_done) {		r = handlers = 0;		for (i=MPT_MAX_PROTOCOL_DRIVERS-1; i; i--) {			if (MptResetHandlers[i]) {				dprintk((KERN_INFO MYNAM ": %s: Calling IOC pre_reset handler #%d\n",						ioc->name, i));				r += (*(MptResetHandlers[i]))(ioc, MPT_IOC_PRE_RESET);				handlers++;				if (alt_ioc_ready) {					dprintk((KERN_INFO MYNAM ": %s: Calling alt-IOC pre_reset handler #%d\n",							ioc->alt_ioc->name, i));					r += (*(MptResetHandlers[i]))(ioc->alt_ioc, MPT_IOC_PRE_RESET);					handlers++;				}			}		}		/* FIXME?  Examine results here? */	}	// May need to check/upload firmware & data here!	if ((r = SendIocInit(ioc)) != 0)		return -3;// NEW!	if (alt_ioc_ready) {		if ((r = SendIocInit(ioc->alt_ioc)) != 0) {			alt_ioc_ready = 0;			printk(KERN_WARNING MYNAM ": alt-%s: (%d) init failure WARNING!\n",					ioc->alt_ioc->name, r);		}	}	/*	 * 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 (i=MPT_MAX_PROTOCOL_DRIVERS-1; i; i--) {			if (MptResetHandlers[i]) {				dprintk((KERN_INFO MYNAM ": %s: Calling IOC post_reset handler #%d\n",						ioc->name, i));				r += (*(MptResetHandlers[i]))(ioc, MPT_IOC_POST_RESET);				handlers++;				if (alt_ioc_ready) {					dprintk((KERN_INFO MYNAM ": %s: Calling alt-IOC post_reset handler #%d\n",							ioc->alt_ioc->name, i));					r += (*(MptResetHandlers[i]))(ioc->alt_ioc, MPT_IOC_POST_RESET);					handlers++;				}			}		}		/* FIXME?  Examine results here? */	}	/*	 * Prime reply & request queues!	 * (mucho alloc's)	 */	if ((r = PrimeIocFifos(ioc)) != 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);	}// FIXME! Cleanup all IOC (and alt-IOC?) requests here!

⌨️ 快捷键说明

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