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

📄 mptbase.c

📁 microwindows移植到S3C44B0的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
					printk("\n" KERN_INFO " ");				printk(" %08x", le32_to_cpu(m[ii]));			}			printk("\n");		}#endif		mf_dma_addr = iocp->req_frames_low_dma + req_offset;		CHIPREG_WRITE32(&iocp->chip->RequestFifo, mf_dma_addr);	}}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	mpt_free_msg_frame - Place MPT request frame back on FreeQ. *	@handle: Handle of registered MPT protocol driver *	@iocid: IOC unique identifier (integer) *	@mf: Pointer to MPT request frame * *	This routine places a MPT request frame back on the MPT adapter's *	FreeQ. */voidmpt_free_msg_frame(int handle, int iocid, MPT_FRAME_HDR *mf){	MPT_ADAPTER *iocp;	unsigned long flags;	iocp = mpt_adapters[iocid];	if (iocp != NULL) {		/*  Put Request back on FreeQ!  */		spin_lock_irqsave(&iocp->FreeQlock, flags);		Q_ADD_TAIL(&iocp->FreeQ, &mf->u.frame.linkage, MPT_FRAME_HDR);#ifdef MFCNT		iocp->mfcnt--;#endif		spin_unlock_irqrestore(&iocp->FreeQlock, flags);	}}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	mpt_send_handshake_request - Send MPT request via doorbell *	handshake method. *	@handle: Handle of registered MPT protocol driver *	@iocid: IOC unique identifier (integer) *	@reqBytes: Size of the request in bytes *	@req: Pointer to MPT request frame *	@sleepFlag: Use schedule if CAN_SLEEP else use udelay. * *	This routine is used exclusively to send MptScsiTaskMgmt *	requests since they are required to be sent via doorbell handshake. * *	NOTE: It is the callers responsibility to byte-swap fields in the *	request which are greater than 1 byte in size. * *	Returns 0 for success, non-zero for failure. */intmpt_send_handshake_request(int handle, int iocid, int reqBytes, u32 *req, int sleepFlag){	MPT_ADAPTER	*iocp;	int		 r = 0;	iocp = mpt_adapters[iocid];	if (iocp != NULL) {		u8	*req_as_bytes;		int	 ii;		/* State is known to be good upon entering		 * this function so issue the bus reset		 * request.		 */		/*		 * Emulate what mpt_put_msg_frame() does /wrt to sanity		 * setting cb_idx/req_idx.  But ONLY if this request		 * is in proper (pre-alloc'd) request buffer range...		 */		ii = MFPTR_2_MPT_INDEX(iocp,(MPT_FRAME_HDR*)req);		if (reqBytes >= 12 && ii >= 0 && ii < iocp->req_depth) {			MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;			mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);			mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;		}		/* Make sure there are no doorbells */		CHIPREG_WRITE32(&iocp->chip->IntStatus, 0);		CHIPREG_WRITE32(&iocp->chip->Doorbell,				((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |				 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));		/* Wait for IOC doorbell int */		if ((ii = WaitForDoorbellInt(iocp, 2, sleepFlag)) < 0) {			return ii;		}		/* Read doorbell and check for active bit */		if (!(CHIPREG_READ32(&iocp->chip->Doorbell) & MPI_DOORBELL_ACTIVE))				return -5;		dhsprintk((KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",				iocp->name, ii));		CHIPREG_WRITE32(&iocp->chip->IntStatus, 0);		if ((r = WaitForDoorbellAck(iocp, 1, sleepFlag)) < 0) {			return -2;		}		/* Send request via doorbell handshake */		req_as_bytes = (u8 *) req;		for (ii = 0; ii < reqBytes/4; ii++) {			u32 word;			word = ((req_as_bytes[(ii*4) + 0] <<  0) |				(req_as_bytes[(ii*4) + 1] <<  8) |				(req_as_bytes[(ii*4) + 2] << 16) |				(req_as_bytes[(ii*4) + 3] << 24));			CHIPREG_WRITE32(&iocp->chip->Doorbell, word);			if ((r = WaitForDoorbellAck(iocp, 1, sleepFlag)) < 0) {				r = -3;				break;			}		}		if ((r = WaitForDoorbellInt(iocp, 10, sleepFlag)) >= 0)			r = 0;		else			r = -4;		/* Make sure there are no doorbells */		CHIPREG_WRITE32(&iocp->chip->IntStatus, 0);	}	return r;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	mpt_adapter_find_first - Find first MPT adapter pointer. * *	Returns first MPT adapter pointer or %NULL if no MPT adapters *	are present. */MPT_ADAPTER *mpt_adapter_find_first(void){	MPT_ADAPTER *this = NULL;	if (! Q_IS_EMPTY(&MptAdapters))		this = MptAdapters.head;	return this;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	mpt_adapter_find_next - Find next MPT adapter pointer. *	@prev: Pointer to previous MPT adapter * *	Returns next MPT adapter pointer or %NULL if there are no more. */MPT_ADAPTER *mpt_adapter_find_next(MPT_ADAPTER *prev){	MPT_ADAPTER *next = NULL;	if (prev && (prev->forw != (MPT_ADAPTER*)&MptAdapters.head))		next = prev->forw;	return next;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* *	mpt_pci_scan - Scan PCI devices for MPT adapters. * *	Returns count of MPT adapters found, keying off of PCI vendor and *	device_id's. */static 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 and 1030 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) &&		    (pdev->device != MPI_MANUFACTPAGE_DEVID_53C1030) &&#if 0		    /* FIXME! C103x family */		    (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		 * dual function devices (929, 1030) 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 == pdev->device) &&			    (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	(void) procmpt_create();#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		 ii;	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->alloc_total = sizeof(MPT_ADAPTER);	ioc->req_sz = MPT_DEFAULT_FRAME_SIZE;		/* avoid div by zero! */	ioc->reply_sz = ioc->req_sz;	ioc->pcidev = pdev;	ioc->diagPending = 0;	spin_lock_init(&ioc->diagLock);	/* Initialize the event logging.	 */	ioc->eventTypes = 0;	/* None */	ioc->eventContext = 0;	ioc->eventLogSize = 0;	ioc->events = NULL;#ifdef MFCNT	ioc->mfcnt = 0;#endif	/* Initialize the FW and Data image pointers.	 */	ioc->FWImage = NULL;	ioc->FWImage_dma = 0;	/* Initilize SCSI Config Data structure	 */	memset(&ioc->spi_data, 0, sizeof(ScsiCfgData));	/* Initialize the running configQ head.	 */	Q_INIT(&ioc->configQ, Q_ITEM);	/* Find lookup slot. */	for (ii=0; ii < MPT_MAX_ADAPTERS; ii++) {		if (mpt_adapters[ii] == NULL) {			ioc->id = ii;		/* Assign adapter unique id (lookup) */			break;		}	}	if (ii == MPT_MAX_ADAPTERS) {		printk(KERN_ERR MYNAM ": ERROR - mpt_adapters[%d] table overflow!\n", ii);		kfree(ioc);		return -ENFILE;	}	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_DEVID_53C1030) {		ioc->chip_type = C1030;		ioc->prod_name = "LSI53C1030";		{			/* 1030 Chip Fix. Disable Split transactions			 * for PCIX. Set bits 4 - 6 to zero.			 */

⌨️ 快捷键说明

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