mptbase.c

来自「linux 内核源代码」· C语言 代码 · 共 2,293 行 · 第 1/5 页

C
2,293
字号
		break;	case MPI_MANUFACTPAGE_DEVID_SAS1068E:		switch (revision)		{		case 0x00:			product_str = "LSISAS1068E A0";			break;		case 0x01:			product_str = "LSISAS1068E B0";			break;		case 0x02:			product_str = "LSISAS1068E B1";			break;		case 0x04:			product_str = "LSISAS1068E B2";			break;		case 0x08:			product_str = "LSISAS1068E B3";			break;		default:			product_str = "LSISAS1068E";			break;		}		break;	case MPI_MANUFACTPAGE_DEVID_SAS1078:		switch (revision)		{		case 0x00:			product_str = "LSISAS1078 A0";			break;		case 0x01:			product_str = "LSISAS1078 B0";			break;		case 0x02:			product_str = "LSISAS1078 C0";			break;		case 0x03:			product_str = "LSISAS1078 C1";			break;		case 0x04:			product_str = "LSISAS1078 C2";			break;		default:			product_str = "LSISAS1078";			break;		}		break;	} out:	if (product_str)		sprintf(prod_name, "%s", product_str);}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//** *	mpt_attach - Install a PCI intelligent MPT adapter. *	@pdev: Pointer to pci_dev structure *	@id: PCI device ID information * *	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 */intmpt_attach(struct pci_dev *pdev, const struct pci_device_id *id){	MPT_ADAPTER	*ioc;	u8		__iomem *mem;	u8		__iomem *pmem;	unsigned long	 mem_phys;	unsigned long	 port;	u32		 msize;	u32		 psize;	int		 ii;	u8		 cb_idx;	int		 r = -ENODEV;	u8		 revision;	u8		 pcixcmd;	static int	 mpt_ids = 0;#ifdef CONFIG_PROC_FS	struct proc_dir_entry *dent, *ent;#endif	if (mpt_debug_level)		printk(KERN_INFO MYNAM ": mpt_debug_level=%xh\n", mpt_debug_level);	if (pci_enable_device(pdev))		return r;	ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);	if (ioc == NULL) {		printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");		return -ENOMEM;	}	ioc->debug_level = mpt_debug_level;	ioc->id = mpt_ids++;	sprintf(ioc->name, "ioc%d", ioc->id);	dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name));	if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {		dprintk(ioc, printk(MYIOC_s_INFO_FMT			": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n", ioc->name));	} else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {		printk(MYIOC_s_WARN_FMT ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n",		    ioc->name);		kfree(ioc);		return r;	}	if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {		dprintk(ioc, printk(MYIOC_s_INFO_FMT			": Using 64 bit consistent mask\n", ioc->name));	} else {		dprintk(ioc, printk(MYIOC_s_INFO_FMT			": Not using 64 bit consistent mask\n", ioc->name));	}	ioc->alloc_total = sizeof(MPT_ADAPTER);	ioc->req_sz = MPT_DEFAULT_FRAME_SIZE;		/* avoid div by zero! */	ioc->reply_sz = MPT_REPLY_FRAME_SIZE;	ioc->pcidev = pdev;	ioc->diagPending = 0;	spin_lock_init(&ioc->diagLock);	spin_lock_init(&ioc->initializing_hba_lock);	/* Initialize the event logging.	 */	ioc->eventTypes = 0;	/* None */	ioc->eventContext = 0;	ioc->eventLogSize = 0;	ioc->events = NULL;#ifdef MFCNT	ioc->mfcnt = 0;#endif	ioc->cached_fw = NULL;	/* Initilize SCSI Config Data structure	 */	memset(&ioc->spi_data, 0, sizeof(SpiCfgData));	/* Initialize the running configQ head.	 */	INIT_LIST_HEAD(&ioc->configQ);	/* Initialize the fc rport list head.	 */	INIT_LIST_HEAD(&ioc->fc_rports);	/* Find lookup slot. */	INIT_LIST_HEAD(&ioc->list);	mem_phys = msize = 0;	port = psize = 0;	for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {		if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {			if (psize)				continue;			/* Get I/O space! */			port = pci_resource_start(pdev, ii);			psize = pci_resource_len(pdev,ii);		} else {			if (msize)				continue;			/* Get memmap */			mem_phys = pci_resource_start(pdev, ii);			msize = pci_resource_len(pdev,ii);		}	}	ioc->mem_size = msize;	mem = NULL;	/* Get logical ptr for PciMem0 space */	/*mem = ioremap(mem_phys, msize);*/	mem = ioremap(mem_phys, msize);	if (mem == NULL) {		printk(MYIOC_s_ERR_FMT "Unable to map adapter memory!\n", ioc->name);		kfree(ioc);		return -EINVAL;	}	ioc->memmap = mem;	dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %lx\n", ioc->name, mem, mem_phys));	dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n",	    ioc->name, &ioc->facts, &ioc->pfacts[0]));	ioc->mem_phys = mem_phys;	ioc->chip = (SYSIF_REGS __iomem *)mem;	/* Save Port IO values in case we need to do downloadboot */	ioc->pio_mem_phys = port;	pmem = (u8 __iomem *)port;	ioc->pio_chip = (SYSIF_REGS __iomem *)pmem;	pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);	mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name);	switch (pdev->device)	{	case MPI_MANUFACTPAGE_DEVICEID_FC939X:	case MPI_MANUFACTPAGE_DEVICEID_FC949X:		ioc->errata_flag_1064 = 1;	case MPI_MANUFACTPAGE_DEVICEID_FC909:	case MPI_MANUFACTPAGE_DEVICEID_FC929:	case MPI_MANUFACTPAGE_DEVICEID_FC919:	case MPI_MANUFACTPAGE_DEVICEID_FC949E:		ioc->bus_type = FC;		break;	case MPI_MANUFACTPAGE_DEVICEID_FC929X:		if (revision < XL_929) {			/* 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 {			/* 929XL Chip Fix. Set MMRBC to 0x08.		 	*/			pci_read_config_byte(pdev, 0x6a, &pcixcmd);			pcixcmd |= 0x08;			pci_write_config_byte(pdev, 0x6a, pcixcmd);		}		ioc->bus_type = FC;		break;	case MPI_MANUFACTPAGE_DEVICEID_FC919X:		/* 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);		ioc->bus_type = FC;		break;	case MPI_MANUFACTPAGE_DEVID_53C1030:		/* 1030 Chip Fix. Disable Split transactions		 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).		 */		if (revision < C0_1030) {			pci_read_config_byte(pdev, 0x6a, &pcixcmd);			pcixcmd &= 0x8F;			pci_write_config_byte(pdev, 0x6a, pcixcmd);		}	case MPI_MANUFACTPAGE_DEVID_1030_53C1035:		ioc->bus_type = SPI;		break;	case MPI_MANUFACTPAGE_DEVID_SAS1064:	case MPI_MANUFACTPAGE_DEVID_SAS1068:		ioc->errata_flag_1064 = 1;	case MPI_MANUFACTPAGE_DEVID_SAS1064E:	case MPI_MANUFACTPAGE_DEVID_SAS1068E:	case MPI_MANUFACTPAGE_DEVID_SAS1078:		ioc->bus_type = SAS;	}	if (ioc->errata_flag_1064)		pci_disable_io_access(pdev);	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);	/* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.	 */	mpt_detect_bound_ports(ioc, pdev);	if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,	    CAN_SLEEP)) != 0){		printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",		    ioc->name, r);		list_del(&ioc->list);		if (ioc->alt_ioc)			ioc->alt_ioc->alt_ioc = NULL;		iounmap(mem);		kfree(ioc);		pci_set_drvdata(pdev, NULL);		return r;	}	/* call per device driver probe entry point */	for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {		if(MptDeviceDriverHandlers[cb_idx] &&		  MptDeviceDriverHandlers[cb_idx]->probe) {			MptDeviceDriverHandlers[cb_idx]->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];	u8 cb_idx;	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(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {		if(MptDeviceDriverHandlers[cb_idx] &&		  MptDeviceDriverHandlers[cb_idx]->remove) {			MptDeviceDriverHandlers[cb_idx]->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. *	@pdev: Pointer to pci_dev structure *	@state: new state to enter */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. *	@pdev: Pointer to pci_dev structure */intmpt_resume(struct pci_dev *pdev){	MPT_ADAPTER *ioc = pci_get_drvdata(pdev);	u32 device_state = pdev->current_state;	int recovery_state;	int err;	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);	err = pci_enable_device(pdev);	if (err)		return err;	/* enable interrupts */	CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);	ioc->active = 1;	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",

⌨️ 快捷键说明

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