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

📄 isp_pci.c

📁 基于组件方式开发操作系统的OSKIT源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	}	if (data == PCI_QLOGIC_ISP1240) {		mdvp = &mdvec_1080;		basetype = ISP_HA_SCSI_12X0;		psize = 2 * sizeof (sdparam);		pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] =		    ISP1080_DMA_REGS_OFF;	}#endif#ifndef	ISP_DISABLE_2100_SUPPORT	if (data == PCI_QLOGIC_ISP2100) {		mdvp = &mdvec_2100;		basetype = ISP_HA_FC_2100;		psize = sizeof (fcparam);		pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] =		    PCI_MBOX_REGS2100_OFF;		data = pci_conf_read(config_id, PCI_CLASS_REG);		if ((data & 0xff) < 3) {			/*			 * XXX: Need to get the actual revision			 * XXX: number of the 2100 FB. At any rate,			 * XXX: lower cache line size for early revision			 * XXX; boards.			 */			linesz = 1;		}	}#endif	isp = &pcs->pci_isp;	isp->isp_param = malloc(psize, M_DEVBUF, M_NOWAIT);	if (isp->isp_param == NULL) {		printf("isp%d: cannot allocate parameter data\n", unit);		return;	}	bzero(isp->isp_param, psize);	isp->isp_mdvec = mdvp;	isp->isp_type = basetype;#if	__FreeBSD_version >= 300006	(void) snprintf(isp->isp_name, sizeof (isp->isp_name), "isp%d", unit);#else	(void) sprintf(isp->isp_name, "isp%d", unit);#endif	isp->isp_osinfo.unit = unit;#if	__FreeBSD_version >= 300004	ISP_LOCK(isp);	/*	 * Make sure that SERR, PERR, WRITE INVALIDATE and BUSMASTER	 * are set.	 */	data = pci_cfgread(config_id, PCIR_COMMAND, 2);	data |=	PCIM_CMD_SEREN		|		PCIM_CMD_PERRESPEN	|		PCIM_CMD_BUSMASTEREN	|		PCIM_CMD_INVEN;	pci_cfgwrite(config_id, PCIR_COMMAND, 2, data);	/*	 * Make sure the CACHE Line Size register is set sensibly.	 */	data = pci_cfgread(config_id, PCIR_CACHELNSZ, 1);	if (data != linesz) {		data = PCI_DFLT_LNSZ;		printf("%s: set PCI line size to %d\n", isp->isp_name, data);		pci_cfgwrite(config_id, PCIR_CACHELNSZ, data, 1);	}	/*	 * Make sure the Latency Timer is sane.	 */	data = pci_cfgread(config_id, PCIR_LATTIMER, 1);	if (data < PCI_DFLT_LTNCY) {		data = PCI_DFLT_LTNCY;		printf("%s: set PCI latency to %d\n", isp->isp_name, data);		pci_cfgwrite(config_id, PCIR_LATTIMER, data, 1);	}	/*	 * Make sure we've disabled the ROM.	 */	data = pci_cfgread(config_id, PCIR_ROMADDR, 4);	data &= ~1;	pci_cfgwrite(config_id, PCIR_ROMADDR, data, 4);	ISP_UNLOCK(isp);	if (bus_dma_tag_create(NULL, 0, 0, BUS_SPACE_MAXADDR_32BIT,	    BUS_SPACE_MAXADDR, NULL, NULL, 1<<24,	    255, 1<<24, 0, &pcs->parent_dmat) != 0) {		printf("%s: could not create master dma tag\n", isp->isp_name);		free(pcs, M_DEVBUF);		return;	}#else	ISP_LOCK(isp);	data = pci_conf_read(config_id, PCIR_COMMAND);	data |=	PCIM_CMD_SEREN		|		PCIM_CMD_PERRESPEN	|		PCIM_CMD_BUSMASTEREN	|		PCIM_CMD_INVEN;	pci_conf_write(config_id, PCIR_COMMAND, data);	data = pci_conf_read(config_id, PCIR_CACHELNSZ);	if ((data & ~0xffff) != ((PCI_DFLT_LTNCY << 8) | linesz)) {		data &= ~0xffff;		data |= (PCI_DFLT_LTNCY << 8) | linesz;		pci_conf_write(config_id, PCIR_CACHELNSZ, data);		printf("%s: set PCI line size to %d\n", isp->isp_name, linesz);		printf("%s: set PCI latency to %d\n", isp->isp_name,		    PCI_DFLT_LTNCY);	}	/*	 * Make sure we've disabled the ROM.	 */	data = pci_conf_read(config_id, PCIR_ROMADDR);	data &= ~1;	pci_conf_write(config_id, PCIR_ROMADDR, data);	ISP_UNLOCK(isp);#endif	if (pci_map_int(config_id, (void (*)(void *))isp_intr,	    (void *)isp, &IMASK) == 0) {		printf("%s: could not map interrupt\n", isp->isp_name);		free(pcs, M_DEVBUF);		return;	}	pcs->pci_id = config_id;#ifdef	SCSI_ISP_NO_FWLOAD_MASK	if (SCSI_ISP_NO_FWLOAD_MASK && (SCSI_ISP_NO_FWLOAD_MASK & (1 << unit)))		isp->isp_confopts |= ISP_CFG_NORELOAD;#endif#ifdef	SCSI_ISP_NO_NVRAM_MASK	if (SCSI_ISP_NO_NVRAM_MASK && (SCSI_ISP_NO_NVRAM_MASK & (1 << unit))) {		printf("%s: ignoring NVRAM\n", isp->isp_name);		isp->isp_confopts |= ISP_CFG_NONVRAM;	}#endif	ISP_LOCK(isp);	isp_reset(isp);	if (isp->isp_state != ISP_RESETSTATE) {		(void) pci_unmap_int(config_id);		ISP_UNLOCK(isp);		free(pcs, M_DEVBUF);		return;	}	isp_init(isp);	if (isp->isp_state != ISP_INITSTATE) {		/* If we're a Fibre Channel Card, we allow deferred attach */		if (isp->isp_type & ISP_HA_SCSI) {			isp_uninit(isp);			(void) pci_unmap_int(config_id); /* Does nothing */			ISP_UNLOCK(isp);			free(pcs, M_DEVBUF);			return;		}	}	isp_attach(isp);	if (isp->isp_state != ISP_RUNSTATE) {		/* If we're a Fibre Channel Card, we allow deferred attach */		if (IS_SCSI(isp)) {			isp_uninit(isp);			(void) pci_unmap_int(config_id); /* Does nothing */			ISP_UNLOCK(isp);			free(pcs, M_DEVBUF);			return;		}	}	ISP_UNLOCK(isp);#ifdef __alpha__	/*	 * THIS SHOULD NOT HAVE TO BE HERE	 */	alpha_register_pci_scsi(config_id->bus, config_id->slot, isp->isp_sim);#endif	}static u_int16_tisp_pci_rd_reg(isp, regoff)	struct ispsoftc *isp;	int regoff;{	u_int16_t rv;	struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;	int offset, oldconf = 0;	if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {		/*		 * We will assume that someone has paused the RISC processor.		 */		oldconf = isp_pci_rd_reg(isp, BIU_CONF1);		isp_pci_wr_reg(isp, BIU_CONF1, oldconf | BIU_PCI_CONF1_SXP);	}	offset = pcs->pci_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT];	offset += (regoff & 0xff);	rv = bus_space_read_2(pcs->pci_st, pcs->pci_sh, offset);	if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {		isp_pci_wr_reg(isp, BIU_CONF1, oldconf);	}	return (rv);}static voidisp_pci_wr_reg(isp, regoff, val)	struct ispsoftc *isp;	int regoff;	u_int16_t val;{	struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;	int offset, oldconf = 0;	if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {		/*		 * We will assume that someone has paused the RISC processor.		 */		oldconf = isp_pci_rd_reg(isp, BIU_CONF1);		isp_pci_wr_reg(isp, BIU_CONF1, oldconf | BIU_PCI_CONF1_SXP);	}	offset = pcs->pci_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT];	offset += (regoff & 0xff);	bus_space_write_2(pcs->pci_st, pcs->pci_sh, offset, val);	if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {		isp_pci_wr_reg(isp, BIU_CONF1, oldconf);	}}#ifndef	ISP_DISABLE_1080_SUPPORTstatic u_int16_tisp_pci_rd_reg_1080(isp, regoff)	struct ispsoftc *isp;	int regoff;{	u_int16_t rv;	struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;	int offset, oc = 0;	if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {		/*		 * We will assume that someone has paused the RISC processor.		 */		oc = isp_pci_rd_reg(isp, BIU_CONF1);		isp_pci_wr_reg(isp, BIU_CONF1, oc | BIU_PCI1080_CONF1_SXP);	} else if ((regoff & _BLK_REG_MASK) == DMA_BLOCK) {		oc = isp_pci_rd_reg(isp, BIU_CONF1);		isp_pci_wr_reg(isp, BIU_CONF1, oc | BIU_PCI1080_CONF1_DMA);	}	offset = pcs->pci_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT];	offset += (regoff & 0xff);	rv = bus_space_read_2(pcs->pci_st, pcs->pci_sh, offset);	if ((regoff & _BLK_REG_MASK) == SXP_BLOCK ||	    ((regoff & _BLK_REG_MASK) == DMA_BLOCK)) {		isp_pci_wr_reg(isp, BIU_CONF1, oc);	}	return (rv);}static voidisp_pci_wr_reg_1080(isp, regoff, val)	struct ispsoftc *isp;	int regoff;	u_int16_t val;{	struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;	int offset, oc = 0;	if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {		/*		 * We will assume that someone has paused the RISC processor.		 */		oc = isp_pci_rd_reg(isp, BIU_CONF1);		isp_pci_wr_reg(isp, BIU_CONF1, oc | BIU_PCI1080_CONF1_SXP);	} else if ((regoff & _BLK_REG_MASK) == DMA_BLOCK) {		oc = isp_pci_rd_reg(isp, BIU_CONF1);		isp_pci_wr_reg(isp, BIU_CONF1, oc | BIU_PCI1080_CONF1_DMA);	}	offset = pcs->pci_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT];	offset += (regoff & 0xff);	bus_space_write_2(pcs->pci_st, pcs->pci_sh, offset, val);	if ((regoff & _BLK_REG_MASK) == SXP_BLOCK ||	    ((regoff & _BLK_REG_MASK) == DMA_BLOCK)) {		isp_pci_wr_reg(isp, BIU_CONF1, oc);	}}#endif#if	__FreeBSD_version >= 300004static void isp_map_rquest __P((void *, bus_dma_segment_t *, int, int));static void isp_map_result __P((void *, bus_dma_segment_t *, int, int));static void isp_map_fcscrt __P((void *, bus_dma_segment_t *, int, int));static voidisp_map_rquest(void *arg, bus_dma_segment_t *segs, int nseg, int error){	struct ispsoftc *isp = (struct ispsoftc *) arg;	isp->isp_rquest_dma = segs->ds_addr;}static voidisp_map_result(void *arg, bus_dma_segment_t *segs, int nseg, int error){	struct ispsoftc *isp = (struct ispsoftc *) arg;	isp->isp_result_dma = segs->ds_addr;}static voidisp_map_fcscrt(void *arg, bus_dma_segment_t *segs, int nseg, int error){	struct ispsoftc *isp = (struct ispsoftc *) arg;	fcparam *fcp = isp->isp_param;	fcp->isp_scdma = segs->ds_addr;}static intisp_pci_mbxdma(struct ispsoftc *isp){	struct isp_pcisoftc *pci = (struct isp_pcisoftc *)isp;	caddr_t base;	u_int32_t len;	int i, error;	/*	 * Allocate and map the request, result queues, plus FC scratch area.	 */	len = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN);	len += ISP_QUEUE_SIZE(RESULT_QUEUE_LEN);	if (isp->isp_type & ISP_HA_FC) {		len += ISP2100_SCRLEN;	}	if (bus_dma_tag_create(pci->parent_dmat, 0, 0, BUS_SPACE_MAXADDR,	    BUS_SPACE_MAXADDR, NULL, NULL, len, 1, BUS_SPACE_MAXSIZE_32BIT,	    0, &pci->cntrol_dmat) != 0) {		printf("%s: cannot create a dma tag for control spaces\n",		    isp->isp_name);		return (1);	}	if (bus_dmamem_alloc(pci->cntrol_dmat, (void **)&base,	    BUS_DMA_NOWAIT, &pci->cntrol_dmap) != 0) {		printf("%s: cannot allocate %d bytes of CCB memory\n",		    isp->isp_name, len);		return (1);	}	isp->isp_rquest = base;	bus_dmamap_load(pci->cntrol_dmat, pci->cntrol_dmap, isp->isp_rquest,	    ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN), isp_map_rquest, pci, 0);	isp->isp_result = base + ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN);	bus_dmamap_load(pci->cntrol_dmat, pci->cntrol_dmap, isp->isp_result,	    ISP_QUEUE_SIZE(RESULT_QUEUE_LEN), isp_map_result, pci, 0);	/*	 * Use this opportunity to initialize/create data DMA maps.	 */	for (i = 0; i < MAXISPREQUEST; i++) {		error = bus_dmamap_create(pci->parent_dmat, 0, &pci->dmaps[i]);		if (error) {			printf("%s: error %d creating mailbox DMA maps\n",			    isp->isp_name, error);			return (1);		}	}	if (isp->isp_type & ISP_HA_FC) {		fcparam *fcp = (fcparam *) isp->isp_param;		fcp->isp_scratch = base +			ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN) +			ISP_QUEUE_SIZE(RESULT_QUEUE_LEN);		bus_dmamap_load(pci->cntrol_dmat, pci->cntrol_dmap,		    fcp->isp_scratch, ISP2100_SCRLEN, isp_map_fcscrt, pci, 0);	}	return (0);}static void dma2 __P((void *, bus_dma_segment_t *, int, int));typedef struct {	struct ispsoftc *isp;	ISP_SCSI_XFER_T *ccb;	ispreq_t *rq;	u_int8_t *iptrp;	u_int8_t optr;	u_int error;} mush_t;#define	MUSHERR_NOQENTRIES	-2static voiddma2(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error){	mush_t *mp;	ISP_SCSI_XFER_T *ccb;	struct ispsoftc *isp;	struct isp_pcisoftc *pci;	bus_dmamap_t *dp;	bus_dma_segment_t *eseg;	ispreq_t *rq;	u_int8_t *iptrp;	u_int8_t optr;	ispcontreq_t *crq;	int drq, seglim, datalen;	mp = (mush_t *) arg;

⌨️ 快捷键说明

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