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

📄 isp_pci.c

📁 基于组件方式开发操作系统的OSKIT源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* $Id: isp_pci.c,v 1.13.2.1 1999/05/11 06:09:01 mjacob Exp $ *//* release_5_11_99 *//* * PCI specific probe and attach routines for Qlogic ISP SCSI adapters. * FreeBSD Version. * *--------------------------------------- * Copyright (c) 1997, 1998 by Matthew Jacob * NASA/Ames Research Center * 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 immediately at the beginning of the file, without modification, *    this list of conditions, and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products *    derived from this software without specific prior written permission. * * 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. */#include <dev/isp/isp_freebsd.h>#include <dev/isp/asm_pci.h>#include <sys/malloc.h>#include <vm/vm.h>#include <vm/pmap.h>#include <vm/vm_extern.h>#include <pci/pcireg.h>#include <pci/pcivar.h>#if	__FreeBSD_version >= 300004#include <machine/bus_memio.h>#include <machine/bus_pio.h>#include <machine/bus.h>#endif#include "opt_isp.h"static u_int16_t isp_pci_rd_reg __P((struct ispsoftc *, int));static void isp_pci_wr_reg __P((struct ispsoftc *, int, u_int16_t));#ifndef ISP_DISABLE_1080_SUPPORTstatic u_int16_t isp_pci_rd_reg_1080 __P((struct ispsoftc *, int));static void isp_pci_wr_reg_1080 __P((struct ispsoftc *, int, u_int16_t));#endifstatic int isp_pci_mbxdma __P((struct ispsoftc *));static int isp_pci_dmasetup __P((struct ispsoftc *, ISP_SCSI_XFER_T *,	ispreq_t *, u_int8_t *, u_int8_t));#if	__FreeBSD_version >= 300004static voidisp_pci_dmateardown __P((struct ispsoftc *, ISP_SCSI_XFER_T *, u_int32_t));#define	PROBETYPE	const char *#elsetypedef u_int16_t pci_port_t;#define	isp_pci_dmateardown	NULL#define	PROBETYPE	char *#endifstatic void isp_pci_reset1 __P((struct ispsoftc *));static void isp_pci_dumpregs __P((struct ispsoftc *));#ifndef ISP_DISABLE_1020_SUPPORTstatic struct ispmdvec mdvec = {	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_RISC_CODE,	ISP_CODE_LENGTH,	ISP_CODE_ORG,	ISP_CODE_VERSION,	BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_64,	0};#endif#ifndef ISP_DISABLE_1080_SUPPORTstatic struct ispmdvec mdvec_1080 = {	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,	ISP1080_RISC_CODE,	ISP1080_CODE_LENGTH,	ISP1080_CODE_ORG,	ISP1080_CODE_VERSION,	BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_64,	0};#endif#ifndef ISP_DISABLE_2100_SUPPORTstatic struct ispmdvec mdvec_2100 = {	isp_pci_rd_reg,	isp_pci_wr_reg,	isp_pci_mbxdma,	isp_pci_dmasetup,	isp_pci_dmateardown,	NULL,	isp_pci_reset1,	isp_pci_dumpregs,	ISP2100_RISC_CODE,	ISP2100_CODE_LENGTH,	ISP2100_CODE_ORG,	ISP2100_CODE_VERSION,	0,			/* Irrelevant to the 2100 */	0};#endif#ifndef	SCSI_ISP_PREFER_MEM_MAP#ifdef	__alpha__#define	SCSI_ISP_PREFER_MEM_MAP	0#else#define	SCSI_ISP_PREFER_MEM_MAP	1#endif#endif#ifndef	PCIM_CMD_INVEN#define	PCIM_CMD_INVEN			0x10#endif#ifndef	PCIM_CMD_BUSMASTEREN#define	PCIM_CMD_BUSMASTEREN		0x0004#endif#ifndef	PCIM_CMD_PERRESPEN#define	PCIM_CMD_PERRESPEN		0x0040#endif#ifndef	PCIM_CMD_SEREN#define	PCIM_CMD_SEREN			0x0100#endif#ifndef	PCIR_COMMAND#define	PCIR_COMMAND			0x04#endif#ifndef	PCIR_CACHELNSZ#define	PCIR_CACHELNSZ			0x0c#endif#ifndef	PCIR_LATTIMER#define	PCIR_LATTIMER			0x0d#endif#ifndef	PCIR_ROMADDR#define	PCIR_ROMADDR			0x30#endif#ifndef	PCI_VENDOR_QLOGIC#define	PCI_VENDOR_QLOGIC	0x1077#endif#ifndef	PCI_PRODUCT_QLOGIC_ISP1020#define	PCI_PRODUCT_QLOGIC_ISP1020	0x1020#endif#ifndef	PCI_PRODUCT_QLOGIC_ISP1080#define	PCI_PRODUCT_QLOGIC_ISP1080	0x1080#endif#ifndef	PCI_PRODUCT_QLOGIC_ISP1240#define	PCI_PRODUCT_QLOGIC_ISP1240	0x1240#endif#ifndef	PCI_PRODUCT_QLOGIC_ISP2100#define	PCI_PRODUCT_QLOGIC_ISP2100	0x2100#endif#define	PCI_QLOGIC_ISP	((PCI_PRODUCT_QLOGIC_ISP1020 << 16) | PCI_VENDOR_QLOGIC)#define	PCI_QLOGIC_ISP1080	\	((PCI_PRODUCT_QLOGIC_ISP1080 << 16) | PCI_VENDOR_QLOGIC)#define	PCI_QLOGIC_ISP1240	\	((PCI_PRODUCT_QLOGIC_ISP1240 << 16) | PCI_VENDOR_QLOGIC)#define	PCI_QLOGIC_ISP2100	\	((PCI_PRODUCT_QLOGIC_ISP2100 << 16) | PCI_VENDOR_QLOGIC)#define	IO_MAP_REG	0x10#define	MEM_MAP_REG	0x14#define	PCI_DFLT_LTNCY	0x40#define	PCI_DFLT_LNSZ	0x10static PROBETYPE isp_pci_probe __P((pcici_t tag, pcidi_t type));static void isp_pci_attach __P((pcici_t config_d, int unit));/* This distinguishing define is not right, but it does work */ #if	__FreeBSD_version < 300004#define	IO_SPACE_MAPPING	0#define	MEM_SPACE_MAPPING	1typedef int bus_space_tag_t;typedef u_long bus_space_handle_t;typedef unsigned int            __uintptr_t;typedef __uintptr_t     uintptr_t;#ifdef __alpha__#define	bus_space_read_2(st, sh, offset)	\	alpha_mb(),	(st == IO_SPACE_MAPPING)? \		inw((pci_port_t)sh + offset) : readw((pci_port_t)sh + offset)#define	bus_space_write_2(st, sh, offset, val)	\	((st == IO_SPACE_MAPPING)? outw((pci_port_t)sh + offset, val) : \                writew((pci_port_t)sh + offset, val)), alpha_mb()#else#define	bus_space_read_2(st, sh, offset)	\	(st == IO_SPACE_MAPPING)? \		inw((pci_port_t)sh + offset) : *((u_int16_t *)(uintptr_t)sh)#define	bus_space_write_2(st, sh, offset, val)	\	if (st == IO_SPACE_MAPPING) outw((pci_port_t)sh + offset, val); else \		*((u_int16_t *)(uintptr_t)sh) = val#endif#else#ifdef __alpha__#define IO_SPACE_MAPPING	ALPHA_BUS_SPACE_IO#define MEM_SPACE_MAPPING	ALPHA_BUS_SPACE_MEM#else#define IO_SPACE_MAPPING	I386_BUS_SPACE_IO#define MEM_SPACE_MAPPING	I386_BUS_SPACE_MEM#endif#endifstruct isp_pcisoftc {	struct ispsoftc			pci_isp;        pcici_t				pci_id;	bus_space_tag_t			pci_st;	bus_space_handle_t		pci_sh;	int16_t				pci_poff[_NREG_BLKS];#if	__FreeBSD_version >= 300004	bus_dma_tag_t			parent_dmat;	bus_dma_tag_t			cntrol_dmat;	bus_dmamap_t			cntrol_dmap;	bus_dmamap_t			dmaps[MAXISPREQUEST];#endif};static u_long ispunit;struct pci_device isp_pci_driver = {	"isp",	isp_pci_probe,	isp_pci_attach,	&ispunit,	NULL};DATA_SET (pcidevice_set, isp_pci_driver);static PROBETYPEisp_pci_probe(pcici_t tag, pcidi_t type){	static int oneshot = 1;	char *x;        switch (type) {#ifndef	ISP_DISABLE_1020_SUPPORT	case PCI_QLOGIC_ISP:		x = "Qlogic ISP 1020/1040 PCI SCSI Adapter";		break;#endif#ifndef	ISP_DISABLE_1080_SUPPORT	case PCI_QLOGIC_ISP1080:		x = "Qlogic ISP 1080 PCI SCSI Adapter";		break;	case PCI_QLOGIC_ISP1240:		x = "Qlogic ISP 1240 PCI SCSI Adapter";		break;#endif#ifndef	ISP_DISABLE_2100_SUPPORT	case PCI_QLOGIC_ISP2100:		x = "Qlogic ISP 2100 PCI FC-AL Adapter";		break;#endif	default:		return (NULL);	}	if (oneshot) {		oneshot = 0;		printf("%s Version %d.%d, Core Version %d.%d\n", PVS,		    ISP_PLATFORM_VERSION_MAJOR, ISP_PLATFORM_VERSION_MINOR,		    ISP_CORE_VERSION_MAJOR, ISP_CORE_VERSION_MINOR);	}	return (x);}static voidisp_pci_attach(pcici_t config_id, int unit){	int mapped;	pci_port_t io_port;	u_int32_t data, linesz, psize, basetype;	struct isp_pcisoftc *pcs;	struct ispsoftc *isp;	vm_offset_t vaddr, paddr;	struct ispmdvec *mdvp;	ISP_LOCKVAL_DECL;	pcs = malloc(sizeof (struct isp_pcisoftc), M_DEVBUF, M_NOWAIT);	if (pcs == NULL) {		printf("isp%d: cannot allocate softc\n", unit);		return;	}	bzero(pcs, sizeof (struct isp_pcisoftc));	vaddr = paddr = NULL;	mapped = 0;	linesz = PCI_DFLT_LNSZ;	/*	 * Note that pci_conf_read is a 32 bit word aligned function.	 */	data = pci_conf_read(config_id, PCIR_COMMAND);#if	SCSI_ISP_PREFER_MEM_MAP == 1	if (mapped == 0 && (data & PCI_COMMAND_MEM_ENABLE)) {		if (pci_map_mem(config_id, MEM_MAP_REG, &vaddr, &paddr)) {			pcs->pci_st = MEM_SPACE_MAPPING;			pcs->pci_sh = vaddr;			mapped++;		}	}	if (mapped == 0 && (data & PCI_COMMAND_IO_ENABLE)) {		if (pci_map_port(config_id, PCI_MAP_REG_START, &io_port)) {			pcs->pci_st = IO_SPACE_MAPPING;			pcs->pci_sh = io_port;			mapped++;		}	}#else	if (mapped == 0 && (data & PCI_COMMAND_IO_ENABLE)) {		if (pci_map_port(config_id, PCI_MAP_REG_START, &io_port)) {			pcs->pci_st = IO_SPACE_MAPPING;			pcs->pci_sh = io_port;			mapped++;		}	}	if (mapped == 0 && (data & PCI_COMMAND_MEM_ENABLE)) {		if (pci_map_mem(config_id, MEM_MAP_REG, &vaddr, &paddr)) {			pcs->pci_st = MEM_SPACE_MAPPING;			pcs->pci_sh = vaddr;			mapped++;		}	}#endif	if (mapped == 0) {		printf("isp%d: unable to map any ports!\n", unit);		free(pcs, M_DEVBUF);		return;	}	printf("isp%d: using %s space register mapping\n", unit,	    pcs->pci_st == IO_SPACE_MAPPING? "I/O" : "Memory");	data = pci_conf_read(config_id, PCI_ID_REG);	pcs->pci_poff[BIU_BLOCK >> _BLK_REG_SHFT] = BIU_REGS_OFF;	pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS_OFF;	pcs->pci_poff[SXP_BLOCK >> _BLK_REG_SHFT] = PCI_SXP_REGS_OFF;	pcs->pci_poff[RISC_BLOCK >> _BLK_REG_SHFT] = PCI_RISC_REGS_OFF;	pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] = DMA_REGS_OFF;	/* 	 * GCC!	 */	mdvp = &mdvec;	basetype = ISP_HA_SCSI_UNKNOWN;	psize = sizeof (sdparam);#ifndef	ISP_DISABLE_1020_SUPPORT	if (data == PCI_QLOGIC_ISP) {		mdvp = &mdvec;		basetype = ISP_HA_SCSI_UNKNOWN;		psize = sizeof (sdparam);	}#endif#ifndef	ISP_DISABLE_1080_SUPPORT	if (data == PCI_QLOGIC_ISP1080) {		mdvp = &mdvec_1080;		basetype = ISP_HA_SCSI_1080;		psize = sizeof (sdparam);		pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] =		    ISP1080_DMA_REGS_OFF;

⌨️ 快捷键说明

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