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

📄 isp_pci.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 4 页
字号:
/* @(#)isp_pci.c 1.25 *//* * Qlogic ISP Host Adapter PCI specific probe and attach routines *--------------------------------------- * Copyright (c) 1998, 1999, 2000, 2001 by Matthew Jacob * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions, and the following disclaimer, *    without modification, immediately at the beginning of the file. * 2. The name of the author may not be used to endorse or promote products *    derived from this software without specific prior written permission. * * Alternatively, this software may be distributed under the terms of the * the GNU Public License ("GPL"). * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. *  * Matthew Jacob * Feral Software * PMB #825 * 5214-F Diamond Hts Blvd * San Francisco, CA, 94131 * mjacob@feral.com */#include "isp_linux.h"#if	defined(__powerpc__) || defined(__sparc__)static int isp_pci_mapmem = 0xffffffff;#elsestatic int isp_pci_mapmem = 0;#endif#if	defined(__sparc__)#undef	ioremap_nocache#define	ioremap_nocache	ioremap#endifstatic int isplinux_pci_init(struct Scsi_Host *);static u_int16_t isp_pci_rd_reg(struct ispsoftc *, int);static void isp_pci_wr_reg(struct ispsoftc *, int, u_int16_t);#if !(defined(ISP_DISABLE_1080_SUPPORT) && defined(ISP_DISABLE_12160_SUPPORT))static u_int16_t isp_pci_rd_reg_1080(struct ispsoftc *, int);static void isp_pci_wr_reg_1080(struct ispsoftc *, int, u_int16_t);#endifstatic intisp_pci_rd_isr(struct ispsoftc *, u_int16_t *, u_int16_t *, u_int16_t *);#ifndef	ISP_DISABLE_2300_SUPPORTstatic intisp_pci_rd_isr_2300(struct ispsoftc *, u_int16_t *, u_int16_t *, u_int16_t *);#endifstatic int isp_pci_mbxdma(struct ispsoftc *);static intisp_pci_dmasetup(struct ispsoftc *, XS_T *, ispreq_t *, u_int16_t *, u_int16_t);#if	LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)static void isp_pci_dmateardown(struct ispsoftc *, XS_T *, u_int16_t);#else#define	isp_pci_dmateardown	NULL#endifstatic void isp_pci_reset1(struct ispsoftc *);static void isp_pci_dumpregs(struct ispsoftc *, const char *);#ifndef	ISP_CODE_ORG#define	ISP_CODE_ORG		0x1000#endif#ifndef	ISP_DISABLE_1020_SUPPORT#include "asm_1040.h"#define	ISP_1040_RISC_CODE	(u_int16_t *) isp_1040_risc_code#else#define	ISP_1040_RISC_CODE	NULL#endif#ifndef	ISP_DISABLE_1080_SUPPORT#include "asm_1080.h"#define	ISP_1080_RISC_CODE	(u_int16_t *) isp_1080_risc_code#else#define	ISP_1080_RISC_CODE	NULL#endif#ifndef	ISP_DISABLE_12160_SUPPORT#include "asm_12160.h"#define	ISP_12160_RISC_CODE	(u_int16_t *) isp_12160_risc_code#else#define	ISP_12160_RISC_CODE	NULL#endif#ifndef	ISP_DISABLE_2100_SUPPORT#include "asm_2100.h"#define	ISP_2100_RISC_CODE	(u_int16_t *) isp_2100_risc_code#else#define	ISP_2100_RISC_CODE	NULL#endif#ifndef	ISP_DISABLE_2200_SUPPORT#include "asm_2200.h"#define	ISP_2200_RISC_CODE	(u_int16_t *) isp_2200_risc_code#else#define	ISP_2200_RISC_CODE	NULL#endif#ifndef	ISP_DISABLE_2300_SUPPORT#include "asm_2300.h"#define	ISP_2300_RISC_CODE	(u_int16_t *) isp_2300_risc_code#else#define	ISP_2300_RISC_CODE	NULL#endif#ifndef	ISP_DISABLE_1020_SUPPORTstatic struct ispmdvec mdvec = {    isp_pci_rd_isr,    isp_pci_rd_reg,    isp_pci_wr_reg,    isp_pci_mbxdma,    isp_pci_dmasetup,    isp_pci_dmateardown,    NULL,    isp_pci_reset1,    isp_pci_dumpregs,    ISP_1040_RISC_CODE,    BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_64};#endif#ifndef	ISP_DISABLE_1080_SUPPORTstatic struct ispmdvec mdvec_1080 = {    isp_pci_rd_isr,    isp_pci_rd_reg_1080,    isp_pci_wr_reg_1080,    isp_pci_mbxdma,    isp_pci_dmasetup,    isp_pci_dmateardown,    NULL,    isp_pci_reset1,    isp_pci_dumpregs,    ISP_1080_RISC_CODE,    BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_128};#endif#ifndef	ISP_DISABLE_12160_SUPPORTstatic struct ispmdvec mdvec_12160 = {    isp_pci_rd_isr,    isp_pci_rd_reg_1080,    isp_pci_wr_reg_1080,    isp_pci_mbxdma,    isp_pci_dmasetup,    isp_pci_dmateardown,    NULL,    isp_pci_reset1,    isp_pci_dumpregs,    ISP_12160_RISC_CODE,    BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_128};#endif#ifndef	ISP_DISABLE_2100_SUPPORTstatic struct ispmdvec mdvec_2100 = {    isp_pci_rd_isr,    isp_pci_rd_reg,    isp_pci_wr_reg,    isp_pci_mbxdma,    isp_pci_dmasetup,    isp_pci_dmateardown,    NULL,    isp_pci_reset1,    isp_pci_dumpregs,    ISP_2100_RISC_CODE};#endif#ifndef	ISP_DISABLE_2200_SUPPORTstatic struct ispmdvec mdvec_2200 = {    isp_pci_rd_isr,    isp_pci_rd_reg,    isp_pci_wr_reg,    isp_pci_mbxdma,    isp_pci_dmasetup,    isp_pci_dmateardown,    NULL,    isp_pci_reset1,    isp_pci_dumpregs,    ISP_2200_RISC_CODE};#endif#ifndef	ISP_DISABLE_2300_SUPPORTstatic struct ispmdvec mdvec_2300 = {    isp_pci_rd_isr_2300,    isp_pci_rd_reg,    isp_pci_wr_reg,    isp_pci_mbxdma,    isp_pci_dmasetup,    isp_pci_dmateardown,    NULL,    isp_pci_reset1,    isp_pci_dumpregs,    ISP_2300_RISC_CODE};#endif#ifndef	PCI_DEVICE_ID_QLOGIC_ISP1020#define	PCI_DEVICE_ID_QLOGIC_ISP1020	0x1020#endif#ifndef	PCI_DEVICE_ID_QLOGIC_ISP1020#define	PCI_DEVICE_ID_QLOGIC_ISP1020	0x1020#endif#ifndef	PCI_DEVICE_ID_QLOGIC_ISP1080#define	PCI_DEVICE_ID_QLOGIC_ISP1080	0x1080#endif#ifndef	PCI_DEVICE_ID_QLOGIC_ISP12160#define	PCI_DEVICE_ID_QLOGIC_ISP12160	0x1216#endif#ifndef	PCI_DEVICE_ID_QLOGIC_ISP1240#define	PCI_DEVICE_ID_QLOGIC_ISP1240	0x1240#endif#ifndef	PCI_DEVICE_ID_QLOGIC_ISP1280#define	PCI_DEVICE_ID_QLOGIC_ISP1280	0x1280#endif#ifndef	PCI_DEVICE_ID_QLOGIC_ISP2100#define	PCI_DEVICE_ID_QLOGIC_ISP2100	0x2100#endif#ifndef	PCI_DEVICE_ID_QLOGIC_ISP2200#define	PCI_DEVICE_ID_QLOGIC_ISP2200	0x2200#endif#ifndef	PCI_DEVICE_ID_QLOGIC_ISP2300#define	PCI_DEVICE_ID_QLOGIC_ISP2300	0x2300#endif#ifndef	PCI_DEVICE_ID_QLOGIC_ISP2312#define	PCI_DEVICE_ID_QLOGIC_ISP2312	0x2312#endif#define	PCI_DFLT_LTNCY	0x40#define	PCI_DFLT_LNSZ	0x10#define	PCI_CMD_ISP	\ (PCI_COMMAND_MASTER|PCI_COMMAND_INVALIDATE|PCI_COMMAND_PARITY|PCI_COMMAND_SERR)/* * Encapsulating softc... Order of elements is important. The tag * pci_isp must come first because of multiple structure punning * (Scsi_Host * == struct isp_pcisoftc * == struct ispsofct *). */struct isp_pcisoftc {    struct ispsoftc	pci_isp;    struct pci_dev *	pci_dev;    vm_offset_t		port;	/* I/O port address */    vm_offset_t		paddr;	/* Physical Memory Address */    vm_offset_t		vaddr;	/* Mapped Memory Address */    vm_offset_t		poff[_NREG_BLKS];    union pstore	params;#ifdef	LINUX_ISP_TARGET_MODE    tmd_cmd_t		rpool[NTGT_CMDS];#endif};/* * Gratefully borrowed from Gerard Roudier's sym53c8xx driver */static INLINE vm_offset_tmap_pci_mem(u_long base, u_long size){    u_long page_base	= ((u_long) base) & PAGE_MASK;    u_long page_offs	= ((u_long) base) - page_base;    u_long map_size =  roundup(page_offs+size, PAGE_SIZE);    u_long page_remapped = (u_long) ioremap_nocache(page_base, map_size);    (void) map_size;    return (vm_offset_t) (page_remapped ? (page_remapped + page_offs) : 0);}static INLINEvoid unmap_pci_mem(vm_offset_t vaddr, u_long size){    if (vaddr)	iounmap((void *) (vaddr & PAGE_MASK));}static INLINE int map_isp_mem(struct isp_pcisoftc *isp_pci, u_short cmd, vm_offset_t mem_base){    if (cmd & PCI_COMMAND_MEMORY) {	isp_pci->paddr = __pa(mem_base);	isp_pci->paddr &= PCI_BASE_ADDRESS_MEM_MASK;	isp_pci->vaddr = map_pci_mem(isp_pci->paddr, 0xff);	return (isp_pci->vaddr != (vm_offset_t) 0);    }    return (0);}static INLINE int map_isp_io(struct isp_pcisoftc *isp_pci, u_short cmd, vm_offset_t io_base){    if ((cmd & PCI_COMMAND_IO) && (io_base & 3) == 1) {   	isp_pci->port = io_base & PCI_BASE_ADDRESS_IO_MASK;	if (check_region(isp_pci->port, 0xff)) {	    return (0);	}	request_region(isp_pci->port, 0xff, "isp");	return (1);    }    return (0);}#define	ISP_PCI_BUS	pcidev->bus->number#define	ISP_PCI_DEVICE	pcidev->devfn#define	ISEARCH_RESET	pcidev = NULL#define	ISEARCH(x)	\  (pcidev = pci_find_device(PCI_VENDOR_ID_QLOGIC, x, pcidev)) != NULL#define	ISEARCH_NEXT#define	ISTORE_ARGS		struct pci_dev *pcidev#define	ISTORE_FNDARGS		ISTORE_ARGS#define	ISTORE_FNCARGS		pcidev#define	ISTORE_ISP_INFO(x)	(x)->pci_dev = pcidevstatic INLINE struct isp_pcisoftc *isplinux_pci_addhost(Scsi_Host_Template *tmpt, ISTORE_FNDARGS){    struct Scsi_Host *host;    struct ispsoftc *isp;    struct isp_pcisoftc *pci_isp;    host = scsi_register(tmpt, sizeof(struct isp_pcisoftc));    if (host == NULL) {	printk("isp_detect: scsi_register failed\n");	return (NULL);    }    pci_isp = (struct isp_pcisoftc *) host->hostdata;    if (pci_isp == NULL) {	printk("isp_detect: cannot get softc out of scsi_register\n");	return (NULL);    }    ISTORE_ISP_INFO(pci_isp);    isp = (struct ispsoftc *) pci_isp;    isp->isp_host = host;    isp->isp_osinfo.storep = &pci_isp->params;    if (isplinux_pci_init(host)) {	scsi_unregister(host);	return (NULL);    }    isp->isp_next = isplist;    isplist = isp;#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4)    scsi_set_pci_device(host, pci_isp->pci_dev);#endif    return (pci_isp);}intisplinux_pci_detect(Scsi_Host_Template *tmpt){    static const char *fmt =	"ISP SCSI and Fibre Channel Host Adapter Driver\n"	"      Linux Platform Version %d.%d\n"	"      Common Core Code Version %d.%d\n"	"      Built on %s, %s\n";    int nfound = 0;    struct isp_pcisoftc *pci_isp;    ISTORE_ARGS;    if (pci_present() == 0) {	return (0);    }    printk(fmt, ISP_PLATFORM_VERSION_MAJOR, ISP_PLATFORM_VERSION_MINOR,	ISP_CORE_VERSION_MAJOR, ISP_CORE_VERSION_MINOR, __DATE__ , __TIME__ );#ifndef	ISP_DISABLE_1020_SUPPORT    for (ISEARCH_RESET; ISEARCH(PCI_DEVICE_ID_QLOGIC_ISP1020); ISEARCH_NEXT) {	pci_isp = isplinux_pci_addhost(tmpt, ISTORE_FNCARGS);        if (pci_isp) {		nfound++;	}    }#endif#ifndef	ISP_DISABLE_1080_SUPPORT    for (ISEARCH_RESET; ISEARCH(PCI_DEVICE_ID_QLOGIC_ISP1240); ISEARCH_NEXT) {	pci_isp = isplinux_pci_addhost(tmpt, ISTORE_FNCARGS);        if (pci_isp) {		nfound++;	}    }    for (ISEARCH_RESET; ISEARCH(PCI_DEVICE_ID_QLOGIC_ISP1080); ISEARCH_NEXT) {	pci_isp = isplinux_pci_addhost(tmpt, ISTORE_FNCARGS);        if (pci_isp) {		nfound++;	}    }    for (ISEARCH_RESET; ISEARCH(PCI_DEVICE_ID_QLOGIC_ISP1280); ISEARCH_NEXT) {	pci_isp = isplinux_pci_addhost(tmpt, ISTORE_FNCARGS);        if (pci_isp) {		nfound++;	}    }#endif#ifndef	ISP_DISABLE_12160_SUPPORT    for (ISEARCH_RESET; ISEARCH(PCI_DEVICE_ID_QLOGIC_ISP12160); ISEARCH_NEXT) {	pci_isp = isplinux_pci_addhost(tmpt, ISTORE_FNCARGS);        if (pci_isp) {		nfound++;	}    }#endif#ifndef	ISP_DISABLE_2100_SUPPORT    for (ISEARCH_RESET; ISEARCH(PCI_DEVICE_ID_QLOGIC_ISP2100); ISEARCH_NEXT) {	pci_isp = isplinux_pci_addhost(tmpt, ISTORE_FNCARGS);        if (pci_isp) {		nfound++;	}    }#endif#ifndef	ISP_DISABLE_2200_SUPPORT    for (ISEARCH_RESET; ISEARCH(PCI_DEVICE_ID_QLOGIC_ISP2200); ISEARCH_NEXT) {	pci_isp = isplinux_pci_addhost(tmpt, ISTORE_FNCARGS);        if (pci_isp) {		nfound++;	}    }#endif#ifndef	ISP_DISABLE_2300_SUPPORT    for (ISEARCH_RESET; ISEARCH(PCI_DEVICE_ID_QLOGIC_ISP2300); ISEARCH_NEXT) {	pci_isp = isplinux_pci_addhost(tmpt, ISTORE_FNCARGS);        if (pci_isp) {		nfound++;	}    }    for (ISEARCH_RESET; ISEARCH(PCI_DEVICE_ID_QLOGIC_ISP2312); ISEARCH_NEXT) {	pci_isp = isplinux_pci_addhost(tmpt, ISTORE_FNCARGS);        if (pci_isp) {		nfound++;	}    }#endif    return (nfound);}voidisplinux_pci_release(struct Scsi_Host *host){    struct ispsoftc *isp = (struct ispsoftc *) host->hostdata;    struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) host->hostdata;    free_irq(host->irq, pcs);    if (pcs->vaddr != 0) {	unmap_pci_mem(pcs->vaddr, 0xff);	pcs->vaddr = 0;    } else {	release_region(pcs->port, 0xff);	pcs->port = 0;    }    kfree(isp->isp_xflist);#if	LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)    pci_free_consistent(pcs->pci_dev, RQUEST_QUEUE_LEN(isp) * QENTRY_LEN,	isp->isp_rquest, isp->isp_rquest_dma);    pci_free_consistent(pcs->pci_dev, RESULT_QUEUE_LEN(isp) * QENTRY_LEN,	isp->isp_result, isp->isp_result_dma);    if (IS_FC(isp)) {	pci_free_consistent(pcs->pci_dev, ISP2100_SCRLEN,	    FCPARAM(isp)->isp_scratch, FCPARAM(isp)->isp_scdma);    }#else    RlsPages(isp->isp_rquest, IspOrder(RQUEST_QUEUE_LEN(isp)));    RlsPages(isp->isp_result, IspOrder(RESULT_QUEUE_LEN(isp)));    if (IS_FC(isp) && FCPARAM(isp)->isp_scratch) {	RlsPages(FCPARAM(isp)->isp_scratch, 1);    }#endif}static intisplinux_pci_init(struct Scsi_Host *host){    static char *nomap = "cannot map either memory or I/O space";    unsigned long io_base, mem_base;    unsigned int irq, pci_cmd_isp = PCI_CMD_ISP;    struct isp_pcisoftc *isp_pci;    u_char rev, lnsz, timer;    u_short vid, did, cmd;    char loc[32];    struct ispsoftc *isp;    isp_pci = (struct isp_pcisoftc *) host->hostdata;    isp = (struct ispsoftc *) isp_pci;    sprintf(loc, "isp@<PCI%d,Slot%d,Func%d>", isp_pci->pci_dev->bus->number,	PCI_SLOT(isp_pci->pci_dev->devfn), PCI_FUNC(isp_pci->pci_dev->devfn));    if (PRDW(isp_pci, PCI_COMMAND, &cmd) ||	PRDB(isp_pci, PCI_CACHE_LINE_SIZE, &lnsz) ||	PRDB(isp_pci, PCI_LATENCY_TIMER, &timer) ||	PRDB(isp_pci, PCI_CLASS_REVISION, &rev)) {	printk("%s: error reading PCI configuration", loc);

⌨️ 快捷键说明

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