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

📄 mptbase.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
		/* 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_DEVICEID_FC939X) {		ioc->prod_name = "LSIFC939X";		ioc->bus_type = FC;		ioc->errata_flag_1064 = 1;	}	else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC949X) {		ioc->prod_name = "LSIFC949X";		ioc->bus_type = FC;		ioc->errata_flag_1064 = 1;	}	else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) {		ioc->prod_name = "LSI53C1030";		ioc->bus_type = SCSI;		/* 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->prod_name = "LSI53C1035";		ioc->bus_type = SCSI;	}	else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064) {		ioc->prod_name = "LSISAS1064";		ioc->bus_type = SAS;		ioc->errata_flag_1064 = 1;	}	else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1066) {		ioc->prod_name = "LSISAS1066";		ioc->bus_type = SAS;		ioc->errata_flag_1064 = 1;	}	else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068) {		ioc->prod_name = "LSISAS1068";		ioc->bus_type = SAS;		ioc->errata_flag_1064 = 1;	}	else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064E) {		ioc->prod_name = "LSISAS1064E";		ioc->bus_type = SAS;	}	else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1066E) {		ioc->prod_name = "LSISAS1066E";		ioc->bus_type = SAS;	}	else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068E) {		ioc->prod_name = "LSISAS1068E";		ioc->bus_type = SAS;	}	if (ioc->errata_flag_1064)		pci_disable_io_access(pdev);	sprintf(ioc->name, "ioc%d", ioc->id);	spin_lock_init(&ioc->FreeQlock);	/* Disable all! */	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);	ioc->active = 0;	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);	/* Set lookup ptr. */	list_add_tail(&ioc->list, &ioc_list);	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			list_del(&ioc->list);			iounmap(mem);			kfree(ioc);			return -EBUSY;		}		ioc->pci_irq = pdev->irq;		pci_set_master(pdev);			/* ?? */		pci_set_drvdata(pdev, ioc);#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	}	/* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.	 */	mpt_detect_bound_ports(ioc, pdev);	if ((r = mpt_bringup_adapter(ioc, CAN_SLEEP)) != 0){		printk(KERN_WARNING MYNAM		  ": WARNING - %s did not initialize properly! (%d)\n",		  ioc->name, r);		list_del(&ioc->list);		free_irq(ioc->pci_irq, ioc);		iounmap(mem);		kfree(ioc);		pci_set_drvdata(pdev, NULL);		return r;	}	/* call per device driver probe entry point */	for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {		if(MptDeviceDriverHandlers[ii] &&		  MptDeviceDriverHandlers[ii]->probe) {			MptDeviceDriverHandlers[ii]->probe(pdev,id);		}	}#ifdef CONFIG_PROC_FS	/*	 *  Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.	 */	dent = proc_mkdir(ioc->name, mpt_proc_root_dir);	if (dent) {		ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);		if (ent) {			ent->read_proc = procmpt_iocinfo_read;			ent->data = ioc;		}		ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);		if (ent) {			ent->read_proc = procmpt_summary_read;			ent->data = ioc;		}	}#endif	return 0;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* *	mpt_detach - Remove a PCI intelligent MPT adapter. *	@pdev: Pointer to pci_dev structure * */voidmpt_detach(struct pci_dev *pdev){	MPT_ADAPTER 	*ioc = pci_get_drvdata(pdev);	char pname[32];	int ii;	sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);	remove_proc_entry(pname, NULL);	sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);	remove_proc_entry(pname, NULL);	sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);	remove_proc_entry(pname, NULL);	/* call per device driver remove entry point */	for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {		if(MptDeviceDriverHandlers[ii] &&		  MptDeviceDriverHandlers[ii]->remove) {			MptDeviceDriverHandlers[ii]->remove(pdev);		}	}	/* Disable interrupts! */	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);	ioc->active = 0;	synchronize_irq(pdev->irq);	/* Clear any lingering interrupt */	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);	CHIPREG_READ32(&ioc->chip->IntStatus);	mpt_adapter_dispose(ioc);	pci_set_drvdata(pdev, NULL);}/************************************************************************** * Power Management */#ifdef CONFIG_PM/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* *	mpt_suspend - Fusion MPT base driver suspend routine. * * */intmpt_suspend(struct pci_dev *pdev, pm_message_t state){	u32 device_state;	MPT_ADAPTER *ioc = pci_get_drvdata(pdev);	device_state=pci_choose_state(pdev, state);	printk(MYIOC_s_INFO_FMT	"pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",		ioc->name, pdev, pci_name(pdev), device_state);	pci_save_state(pdev);	/* put ioc into READY_STATE */	if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {		printk(MYIOC_s_ERR_FMT		"pci-suspend:  IOC msg unit reset failed!\n", ioc->name);	}	/* disable interrupts */	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);	ioc->active = 0;	/* Clear any lingering interrupt */	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);	pci_disable_device(pdev);	pci_set_power_state(pdev, device_state);	return 0;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* *	mpt_resume - Fusion MPT base driver resume routine. * * */intmpt_resume(struct pci_dev *pdev){	MPT_ADAPTER *ioc = pci_get_drvdata(pdev);	u32 device_state = pdev->current_state;	int recovery_state;	int ii;	printk(MYIOC_s_INFO_FMT	"pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",		ioc->name, pdev, pci_name(pdev), device_state);	pci_set_power_state(pdev, 0);	pci_restore_state(pdev);	pci_enable_device(pdev);	/* enable interrupts */	CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));	ioc->active = 1;	/* F/W not running */	if(!CHIPREG_READ32(&ioc->chip->Doorbell)) {		/* enable domain validation flags */		for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {			ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_NEED_DV;		}	}	printk(MYIOC_s_INFO_FMT		"pci-resume: ioc-state=0x%x,doorbell=0x%x\n",		ioc->name,		(mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),		CHIPREG_READ32(&ioc->chip->Doorbell));	/* bring ioc to operational state */	if ((recovery_state = mpt_do_ioc_recovery(ioc,	    MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) {		printk(MYIOC_s_INFO_FMT			"pci-resume: Cannot recover, error:[%x]\n",			ioc->name, recovery_state);	} else {		printk(MYIOC_s_INFO_FMT			"pci-resume: success\n", ioc->name);	}	return 0;}#endif/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* *	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	 rc=0;	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 ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)			alt_ioc_ready = 1;		else			printk(KERN_WARNING MYNAM					": alt-%s: Not ready WARNING!\n",					ioc->alt_ioc->name);	}	for (ii=0; ii<5; ii++) {		/* Get IOC facts! Allow 5 retries */		if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)			break;	}	if (ii == 5) {		dinitprintk((MYIOC_s_INFO_FMT "Retry IocFacts failed rc=%x\n", ioc->name, rc));		ret = -2;	} else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {		MptDisplayIocCapabilities(ioc);	}	if (alt_ioc_ready) {		if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {			dinitprintk((MYIOC_s_INFO_FMT "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));			/* Retry - alt IOC was initialized once			 */			rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);		}		if (rc) {			dinitprintk((MYIOC_s_INFO_FMT "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));			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) && ((rc = PrimeIocFifos(ioc)) != 0))		ret = -3;	/* May need to check/upload firmware & data here!	 * If fails, continue with alt-ioc processing	 */	if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))		ret = -4;// NEW!	if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {		printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",				ioc->alt_ioc->name, rc);		alt_ioc_ready = 0;		reset_alt_ioc_active = 0;	}	if (alt_ioc_ready) {		if ((rc = 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, rc);		}	}	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) {				rc = mpt_do_upload(ioc, sleepFlag);				if (rc == 0) {					if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {

⌨️ 快捷键说明

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