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

📄 isp_pci.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 4 页
字号:
	return (1);    }    vid = isp_pci->pci_dev->vendor;    did = isp_pci->pci_dev->device;#if	LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)    io_base = pci_resource_start(isp_pci->pci_dev, 0);    if (pci_resource_flags(isp_pci->pci_dev, 0) & PCI_BASE_ADDRESS_MEM_TYPE_64)	irq = 2;    else	irq = 1;    mem_base = pci_resource_start(isp_pci->pci_dev, irq);    if (pci_resource_flags(isp_pci->pci_dev, irq) &	PCI_BASE_ADDRESS_MEM_TYPE_64) {#if	BITS_PER_LONG == 64	mem_base |= pci_resource_start(isp_pci->pci_dev, irq+1) << 32;#else	isp_pci_mapmem &= ~(1 << isp->isp_unit);#endif    }#else	/* LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) */    io_base = isp_pci->pci_dev->base_address[0];    mem_base = isp_pci->pci_dev->base_address[1];    if (mem_base & PCI_BASE_ADDRESS_MEM_TYPE_64) {#if	BITS_PER_LONG == 64	mem_base |= isp_pci->pci_dev->base_address[2] << 32;#else	isp_pci_mapmem &= ~(1 << isp->isp_unit);#endif    }#endif	/* LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) */    irq = isp_pci->pci_dev->irq;    if (vid != PCI_VENDOR_ID_QLOGIC) {	printk("%s: 0x%04x is not QLogic's PCI Vendor ID\n", loc, vid);	return (1);    }    isp_pci->poff[BIU_BLOCK >> _BLK_REG_SHFT] = BIU_REGS_OFF;    isp_pci->poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS_OFF;    isp_pci->poff[SXP_BLOCK >> _BLK_REG_SHFT] = PCI_SXP_REGS_OFF;    isp_pci->poff[RISC_BLOCK >> _BLK_REG_SHFT] = PCI_RISC_REGS_OFF;    isp_pci->poff[DMA_BLOCK >> _BLK_REG_SHFT] = DMA_REGS_OFF;    switch (did) {    case PCI_DEVICE_ID_QLOGIC_ISP1020:	break;    case PCI_DEVICE_ID_QLOGIC_ISP1080:    case PCI_DEVICE_ID_QLOGIC_ISP1240:    case PCI_DEVICE_ID_QLOGIC_ISP1280:    case PCI_DEVICE_ID_QLOGIC_ISP12160:	isp_pci->poff[DMA_BLOCK >> _BLK_REG_SHFT] = ISP1080_DMA_REGS_OFF;	break;    case PCI_DEVICE_ID_QLOGIC_ISP2200:    case PCI_DEVICE_ID_QLOGIC_ISP2100:	isp_pci->poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS2100_OFF;	break;    case PCI_DEVICE_ID_QLOGIC_ISP2300:	pci_cmd_isp &= ~PCI_COMMAND_INVALIDATE;	/* per errata */	isp_pci->poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS2300_OFF;	break;    case PCI_DEVICE_ID_QLOGIC_ISP2312:	isp->isp_port = PCI_FUNC(isp_pci->pci_dev->devfn);	isp_pci->poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS2300_OFF;	break;    default:	printk("%s: Device ID 0x%04x is not a known Qlogic Device", loc, did);	return (1);    }    /*     * Bump unit seed- we're here, whether we complete the attachment or not.     */    isp->isp_unit = isp_unit_seed++;    sprintf(isp->isp_name, "isp%d", isp->isp_unit);    isp->isp_osinfo.device_id =	((isp_pci->pci_dev->bus->number) << 16)		|        (PCI_SLOT(isp_pci->pci_dev->devfn) << 8)	|	(PCI_FUNC(isp_pci->pci_dev->devfn));    if (isp_disable & (1 << isp->isp_unit)) {	isp_prt(isp, ISP_LOGALL, "disabled at user request");	return (1);    }#if	LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)    if (pci_enable_device(isp_pci->pci_dev)) {	printk("%s: fails to be PCI_ENABLEd\n", loc);	return (1);    }    (void) PRDW(isp_pci, PCI_COMMAND, &cmd);#endif    if ((cmd & PCI_CMD_ISP) != pci_cmd_isp) {	if (isp_debug & ISP_LOGINFO)	    printk("%s: rewriting command register from 0x%x to 0x%x\n",		loc, cmd, (cmd & ~PCI_CMD_ISP) | pci_cmd_isp);	cmd &= ~PCI_CMD_ISP;	cmd |= pci_cmd_isp;	PWRW(isp_pci, PCI_COMMAND, cmd);    }    if (lnsz != PCI_DFLT_LNSZ) {	if (isp_debug & ISP_LOGINFO)	    printk("%s: rewriting cache line size from 0x%x to 0x%x\n",		loc, lnsz, PCI_DFLT_LNSZ);	lnsz = PCI_DFLT_LNSZ;	PWRB(isp_pci, PCI_CACHE_LINE_SIZE, lnsz);    }#ifdef	__sparc__    if (PRDB(isp_pci, PCI_MIN_GNT, &rev)) {	printk("%s: unable to read min grant\n", loc);	return (1);    }    if (rev) {	rev = (rev << 3) & 0xff;    }    if (rev == 0) {	rev = 64;    }    if (isp_debug & ISP_LOGINFO) {	printk("%s: rewriting latency timer from 0x%x to 0x%x\n",	    loc, timer, rev);    }    PWRB(isp_pci, PCI_LATENCY_TIMER, rev);#else    if (timer < PCI_DFLT_LTNCY) {	if (isp_debug & ISP_LOGINFO)	    printk("%s: rewriting latency timer from 0x%x to 0x%x\n",		loc, timer, PCI_DFLT_LTNCY);	timer = PCI_DFLT_LTNCY;	PWRB(isp_pci, PCI_LATENCY_TIMER, timer);    }#endif    if ((cmd & (PCI_COMMAND_MEMORY|PCI_COMMAND_IO)) == 0) {#ifdef	__powerpc__	if (io_base == 0 && mem_base == 0) {	    printk("%s: you lose- no register access defined.\n", loc);	    return (1);	}	if (io_base)		cmd |= PCI_COMMAND_IO;	if (mem_base)		cmd |= PCI_COMMAND_MEMORY;	PWRW(isp_pci, PCI_COMMAND, cmd);#else	printk("%s: you lose- no register access defined.\n", loc);	return (1);#endif    }    /*     * Disable the ROM.     */    PWRL(isp_pci, PCI_ROM_ADDRESS, 0);    /*     * Set up stuff...     */    isp_pci->port = isp_pci->vaddr = 0;    /*     * If we prefer to map memory space over I/O, try that first.     */    if (isp_pci_mapmem & (1 << isp->isp_unit)) {	if (map_isp_mem(isp_pci, cmd, mem_base) == 0) {	    if (map_isp_io(isp_pci, cmd, io_base) == 0) {		isp_prt(isp, ISP_LOGERR, nomap);		return (1);	    }	}    } else {	if (map_isp_io(isp_pci, cmd, io_base) == 0) {	    if (map_isp_mem(isp_pci, cmd, mem_base) == 0) {		isp_prt(isp, ISP_LOGERR, nomap);		return (1);	    }	}    }    if (isp_pci->vaddr) {	isp_prt(isp, ISP_LOGCONFIG,	    "mapped memory 0x%lx at 0x%lx\n", isp_pci->paddr, isp_pci->vaddr);	host->io_port = isp_pci->paddr;    } else {        isp_prt(isp, ISP_LOGCONFIG,	    "mapped I/O space at 0x%lx\n", isp_pci->port);	host->io_port = isp_pci->port;    }    host->irq = 0;    isp_pci->pci_isp.isp_revision = rev;#ifndef	ISP_DISABLE_1020_SUPPORT    if (did == PCI_DEVICE_ID_QLOGIC_ISP1020) {	isp_pci->pci_isp.isp_mdvec = &mdvec;	isp_pci->pci_isp.isp_type = ISP_HA_SCSI_UNKNOWN;    } #endif#ifndef	ISP_DISABLE_1080_SUPPORT    if (did == PCI_DEVICE_ID_QLOGIC_ISP1080) {	isp_pci->pci_isp.isp_mdvec = &mdvec_1080;	isp_pci->pci_isp.isp_type = ISP_HA_SCSI_1080;    }    if (did == PCI_DEVICE_ID_QLOGIC_ISP1240) {	isp_pci->pci_isp.isp_mdvec = &mdvec_1080;	isp_pci->pci_isp.isp_type = ISP_HA_SCSI_1240;	host->max_channel = 1;    }    if (did == PCI_DEVICE_ID_QLOGIC_ISP1280) {	isp_pci->pci_isp.isp_mdvec = &mdvec_1080;	isp_pci->pci_isp.isp_type = ISP_HA_SCSI_1280;	host->max_channel = 1;    }#endif#ifndef	ISP_DISABLE_12160_SUPPORT    if (did == PCI_DEVICE_ID_QLOGIC_ISP12160) {	isp_pci->pci_isp.isp_mdvec = &mdvec_12160;	isp_pci->pci_isp.isp_type = ISP_HA_SCSI_12160;	host->max_channel = 1;    }#endif#ifndef	ISP_DISABLE_2100_SUPPORT    if (did == PCI_DEVICE_ID_QLOGIC_ISP2100) {	isp_pci->pci_isp.isp_mdvec = &mdvec_2100;	isp_pci->pci_isp.isp_type = ISP_HA_FC_2100;    }#endif#ifndef	ISP_DISABLE_2200_SUPPORT    if (did == PCI_DEVICE_ID_QLOGIC_ISP2200) {	isp_pci->pci_isp.isp_mdvec = &mdvec_2200;	isp_pci->pci_isp.isp_type = ISP_HA_FC_2200;    }#endif#ifndef	ISP_DISABLE_2300_SUPPORT    if (did == PCI_DEVICE_ID_QLOGIC_ISP2300) {	isp_pci->pci_isp.isp_mdvec = &mdvec_2300;	isp_pci->pci_isp.isp_type = ISP_HA_FC_2300;    }    if (did == PCI_DEVICE_ID_QLOGIC_ISP2312) {	isp_pci->pci_isp.isp_mdvec = &mdvec_2300;	isp_pci->pci_isp.isp_type = ISP_HA_FC_2312;    }#endif    if (request_irq(irq, isplinux_intr, SA_SHIRQ, isp->isp_name, isp_pci)) {	isp_prt(isp, ISP_LOGERR, "could not snag irq %u (0x%x)", irq, irq);	goto bad;    }    host->irq = irq;    host->select_queue_depths = isplinux_sqd;    isp->isp_param = &isp_pci->params;#ifdef	LINUX_ISP_TARGET_MODE    isp->isp_osinfo.pool = isp_pci->rpool;#endif    /*     * At this point, we're committed to keeping this adapter around.     */    isplinux_common_init(isp);    return (0);bad:    if (host->irq) {	DISABLE_INTS(isp);	free_irq(host->irq, isp_pci);	host->irq = 0;    }    if (isp_pci->vaddr != 0) {	unmap_pci_mem(isp_pci->vaddr, 0xff);	isp_pci->vaddr = 0;    } else {	release_region(isp_pci->port, 0xff);	isp_pci->port = 0;    }    return (1);}static INLINE u_int16_tispregrd(struct isp_pcisoftc *pcs, vm_offset_t offset){    u_int16_t rv;    if (pcs->vaddr) {	offset += pcs->vaddr;	rv = readw(offset);    } else {	offset += pcs->port;	rv = inw(offset);    }    return (rv);}static INLINE voidispregwr(struct isp_pcisoftc *pcs, vm_offset_t offset, u_int16_t val){    if (pcs->vaddr) {	offset += pcs->vaddr;	writew(val, offset);    } else {	offset += pcs->port;	outw(val, offset);    }    MEMORYBARRIER(isp, SYNC_REG, offset, 2);}static INLINE intisp_pci_rd_debounced(struct isp_pcisoftc *pcs, vm_offset_t off, u_int16_t *rp){    u_int16_t val0, val1;    int i = 0;    do {	val0 = ispregrd(pcs, off);	val1 = ispregrd(pcs, off);    } while (val0 != val1 && ++i < 1000);    if (val0 != val1) {	return (1);    }    *rp = val0;    return (0);}#define	IspVirt2Off(a, x)	\	((a)->poff[((x) & _BLK_REG_MASK) >> _BLK_REG_SHFT] + ((x) & 0xff))static intisp_pci_rd_isr(struct ispsoftc *isp, u_int16_t *isrp,    u_int16_t *semap, u_int16_t *mbp){    struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;    u_int16_t isr, sema;    if (IS_2100(isp)) {	if (isp_pci_rd_debounced(pcs, IspVirt2Off(pcs, BIU_ISR), &isr)) {	    return (0);        }	if (isp_pci_rd_debounced(pcs, IspVirt2Off(pcs, BIU_SEMA), &sema)) {	    return (0);        }    } else {	isr = ispregrd(pcs, IspVirt2Off(pcs, BIU_ISR));	sema = ispregrd(pcs, IspVirt2Off(pcs, BIU_SEMA));    }    isp_prt(isp, ISP_LOGDEBUG3, "ISR 0x%x SEMA 0x%x", isr, sema);    isr &= INT_PENDING_MASK(isp);    sema &= BIU_SEMA_LOCK;    if (isr == 0 && sema == 0) {	return (0);    }    *isrp = isr;    if ((*semap = sema) != 0) {	if (IS_2100(isp)) {	    if (isp_pci_rd_debounced(pcs, IspVirt2Off(pcs, OUTMAILBOX0), mbp)) {		return (0);	    }	} else {	    *mbp = ispregrd(pcs, IspVirt2Off(pcs, OUTMAILBOX0));	}    }    return (1);}#ifndef	ISP_DISABLE_2300_SUPPORTstatic INLINE u_int32_tispregrd32(struct isp_pcisoftc *pcs, vm_offset_t offset){    u_int32_t rv;    if (pcs->vaddr) {	offset += pcs->vaddr;	rv = readl(offset);    } else {	offset += pcs->port;	rv = inl(offset);    }    return (rv);}static intisp_pci_rd_isr_2300(struct ispsoftc *isp, u_int16_t *isrp,    u_int16_t *semap, u_int16_t *mbox0p){    struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;    u_int32_t r2hisr;   /*    * Avoid parity errors on the 2312.    */    if (!(ispregrd(pcs, IspVirt2Off(pcs, BIU_ISR)) & BIU2100_ISR_RISC_INT)) {	*isrp = 0;	return (0);    }    r2hisr = ispregrd32(pcs, IspVirt2Off(pcs, BIU_R2HSTSLO));    isp_prt(isp, ISP_LOGDEBUG3, "RISC2HOST ISR 0x%x", r2hisr);    if ((r2hisr & BIU_R2HST_INTR) == 0) {	*isrp = 0;	return (0);    }    switch (r2hisr & BIU_R2HST_ISTAT_MASK) {    case ISPR2HST_ROM_MBX_OK:    case ISPR2HST_ROM_MBX_FAIL:    case ISPR2HST_MBX_OK:    case ISPR2HST_MBX_FAIL:    case ISPR2HST_ASYNC_EVENT:    case ISPR2HST_RIO_16:    case ISPR2HST_FPOST:    case ISPR2HST_FPOST_CTIO:	*isrp = r2hisr & 0xffff;	*mbox0p = (r2hisr >> 16);	*semap = 1;	return (1);    case ISPR2HST_RSPQ_UPDATE:	*isrp = r2hisr & 0xffff;	*mbox0p = 0;	*semap = 0;	return (1);   default:	return (0);   }}#endifstatic u_int16_tisp_pci_rd_reg(struct ispsoftc *isp, int regoff){    u_int16_t rv, oldconf = 0;    struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;    if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {	/*	 * We will assume that someone has paused the RISC processor.	 */	oldconf = ispregrd(pcs, IspVirt2Off(pcs, BIU_CONF1));	ispregwr(pcs, IspVirt2Off(pcs, BIU_CONF1), oldconf | BIU_PCI_CONF1_SXP);    }    rv = ispregrd(pcs, IspVirt2Off(pcs, regoff));    if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {	ispregwr(pcs, IspVirt2Off(pcs, BIU_CONF1), oldconf);    }    return (rv);}static voidisp_pci_wr_reg(struct ispsoftc *isp, int regoff, u_int16_t val){    struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;    u_int16_t oldconf = 0;    if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {	/*	 * We will assume that someone has paused the RISC processor.	 */	oldconf = ispregrd(pcs, IspVirt2Off(pcs, BIU_CONF1));	ispregwr(pcs, IspVirt2Off(pcs, BIU_CONF1), oldconf | BIU_PCI_CONF1_SXP);    }    ispregwr(pcs, IspVirt2Off(pcs, regoff), val);    if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {	ispregwr(pcs, IspVirt2Off(pcs, BIU_CONF1), oldconf);    }}#if !(defined(ISP_DISABLE_1080_SUPPORT) && defined(ISP_DISABLE_12160_SUPPORT))static u_int16_tisp_pci_rd_reg_1080(struct ispsoftc *isp, int regoff){    struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;    u_int16_t rv, oldconf = 0;    if ((regoff & _BLK_REG_MASK) == SXP_BLOCK ||	(regoff & _BLK_REG_MASK) == (SXP_BLOCK|SXP_BANK1_SELECT)) {	u_int16_t tmpconf;	/*	 * We will assume that someone has paused the RISC processor.	 */	oldconf = ispregrd(pcs,  IspVirt2Off(pcs, BIU_CONF1));	tmpconf = oldconf & ~BIU_PCI1080_CONF1_DMA;	if (IS_1280(isp)) {	    if (regoff & SXP_BANK1_SELECT) {		tmpconf |= BIU_PCI1080_CONF1_SXP0;	    } else {		tmpconf |= BIU_PCI1080_CONF1_SXP1;	    }	} else {	    tmpconf |= BIU_PCI1080_CONF1_SXP0;	}	ispregwr(pcs,  IspVirt2Off(pcs, BIU_CONF1), tmpconf);    } else if ((regoff & _BLK_REG_MASK) == DMA_BLOCK) {	oldconf = ispregrd(pcs,  IspVirt2Off(pcs, BIU_CONF1));	ispregwr(pcs, IspVirt2Off(pcs, BIU_CONF1),	    oldconf | BIU_PCI1080_CONF1_DMA);    }    rv = ispregrd(pcs, IspVirt2Off(pcs, regoff));    if (oldconf) {	ispregwr(pcs, IspVirt2Off(pcs, BIU_CONF1), oldconf);    }    return (rv);}static voidisp_pci_wr_reg_1080(struct ispsoftc *isp, int regoff, u_int16_t val){    struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;    u_int16_t oldconf = 0;    if ((regoff & _BLK_REG_MASK) == SXP_BLOCK ||	(regoff & _BLK_REG_MASK) == (SXP_BLOCK|SXP_BANK1_SELECT)) {	u_int16_t tmpconf;	/*	 * We will assume that someone has paused the RISC processor.	 */	oldconf = ispregrd(pcs,  IspVirt2Off(pcs, BIU_CONF1));	tmpconf = oldconf & ~BIU_PCI1080_CONF1_DMA;	if (IS_1280(isp)) {	    if (regoff & SXP_BANK1_SELECT) {		tmpconf |= BIU_PCI1080_CONF1_SXP0;	    } else {		tmpconf |= BIU_PCI1080_CONF1_SXP1;	    }	} else {

⌨️ 快捷键说明

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