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

📄 bshw_dma.c

📁 freebsd v4.4内核源码
💻 C
字号:
/*	$NecBSD: bshw_dma.c,v 1.3 1997/07/26 06:03:16 honda Exp $	*//*	$NetBSD$	*//* * [NetBSD for NEC PC98 series] *  Copyright (c) 1994, 1995, 1996 NetBSD/pc98 porting staff. *  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. *  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 ``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 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. *//* * Copyright (c) 1994, 1995, 1996 Naofumi HONDA.  All rights reserved. *//********************************************************* * static declare. *********************************************************/static BS_INLINE void bshw_dmastart __P((struct bs_softc *));static void bshw_dmadone __P((struct bs_softc *));/********************************************** * UPPER INTERFACE FUNCS (all funcs exported) **********************************************/voidbshw_dmaabort(bsc, ti)	struct bs_softc *bsc;	struct targ_info *ti;{	bshw_dmadone(bsc);	bsc->sc_p.seglen = 0;	bshw_set_count(bsc, 0);	if (ti == NULL)	{		int i;		struct targ_info *tmpti;		for (i = 0; i < NTARGETS; i++)			if ((tmpti = bsc->sc_ti[i]) != NULL)				tmpti->ti_scsp.seglen = 0;	}	else		ti->ti_scsp.seglen = 0;}/* DMA TRANSFER */voidbs_dma_xfer(ti, direction)	struct targ_info *ti;	u_int direction;{	vm_offset_t va, endva, phys, nphys;	struct bs_softc *bsc = ti->ti_bsc;	struct sc_p *sp = &bsc->sc_p;	bsc->sc_dmadir = direction;	bshw_set_dma_trans(bsc, ti->ti_cfgflags);	if (sp->seglen == 0)	{		phys = vtophys((vm_offset_t) sp->data);		if (phys >= RAM_END)		{			/* setup segaddr */			sp->segaddr = ti->bounce_phys;			/* setup seglen */			sp->seglen = sp->datalen;			if (sp->seglen > ti->bounce_size)				sp->seglen = ti->bounce_size;			/* setup bufp */			sp->bufp = ti->bounce_addr;			if (bsc->sc_dmadir != BSHW_READ)				bcopy(sp->data, sp->bufp, sp->seglen);#ifdef	BS_STATICS			bs_bounce_used[ti->ti_id]++;#endif	/* BS_STATICS */		}		else		{			/* setup segaddr */			sp->segaddr = (u_int8_t *) phys;			/* setup seglen */			endva = (vm_offset_t)round_page(sp->data + sp->datalen);			for (va = (vm_offset_t) sp->data; ; phys = nphys)			{				if ((va += BSHW_NBPG) >= endva)				{					sp->seglen = sp->datalen;					break;				}				nphys = vtophys(va);				if (phys + BSHW_NBPG != nphys || nphys >= RAM_END)				{					sp->seglen =					    (u_int8_t *) trunc_page(va) - sp->data;					break;				}			}			/* setup bufp */			sp->bufp = NULL;		}	}	bshw_dmastart(bsc);	bshw_set_count(bsc, sp->seglen);}voidbs_dma_xfer_end(ti)	struct targ_info *ti;{	struct bs_softc *bsc = ti->ti_bsc;	struct sc_p *sp = &bsc->sc_p;	u_int count, transbytes;	bshw_dmadone(bsc);	if (ti->ti_phase == DATAPHASE)	{		count = bshw_get_count(bsc);		if (count < (u_int) sp->seglen)		{			transbytes = sp->seglen - count;			if (sp->bufp)			{				if (bsc->sc_dmadir == BSHW_READ)					bcopy(sp->bufp, sp->data, transbytes);				sp->bufp += transbytes;			}			sp->seglen = count;			sp->segaddr += transbytes;			sp->data += transbytes;			sp->datalen -= transbytes;			return;		}		else if (count == (u_int) sp->seglen)		{			return;		}		bs_printf(ti, "xfer_end", "strange count");		printf("port data %x seglen %x\n", count, sp->seglen);	}	else		bs_printf(ti, "xfer_end", "extra dma interrupt");	ti->ti_error |= BSDMAABNORMAL;	sp->seglen = ti->ti_scsp.seglen = 0;	/* XXX */}/********************************************** * GENERIC DMA FUNCS **********************************************/static short dmapageport[4] = { 0x27, 0x21, 0x23, 0x25 };/* common dma settings */#undef	DMA1_SMSK#define DMA1_SMSK	(0x15)#undef	DMA1_MODE#define DMA1_MODE	(0x17)#undef	DMA1_FFC#define DMA1_FFC	(0x19)#undef	DMA37SM_SET#define DMA37SM_SET	0x04#undef	DMA1_CHN#define DMA1_CHN(c)	(0x01 + ((c) << 2))static BS_INLINE voidbshw_dmastart(bsc)	struct bs_softc *bsc;{	int chan = bsc->sc_dmachan;	int waport;	u_int8_t *phys = bsc->sc_p.segaddr;	u_int nbytes = bsc->sc_p.seglen;	/*	 * Program one of DMA channels 0..3. These are	 * byte mode channels.	 */	/* set dma channel mode, and reset address ff */#ifdef __FreeBSD__	if (need_pre_dma_flush)		wbinvd();#else	/* NetBSD/pc98 */	if (bsc->sc_dmadir & BSHW_READ)		cpu_cf_preRead(curcpu);	else		cpu_cf_preWrite(curcpu);#endif	if (bsc->sc_dmadir & BSHW_READ)		outb(DMA1_MODE, DMA37MD_SINGLE | DMA37MD_WRITE | chan);	else		outb(DMA1_MODE, DMA37MD_SINGLE | DMA37MD_READ | chan);	outb(DMA1_FFC, 0);	/* send start address */	waport = DMA1_CHN(chan);	outb(waport, (u_int) phys);	outb(waport, ((u_int) phys) >> 8);	outb(dmapageport[chan], ((u_int) phys) >> 16);	/* send count */	outb(waport + 2, --nbytes);	outb(waport + 2, nbytes >> 8);	/* vendor unique hook */	if (bsc->sc_hw->dma_start)		(*bsc->sc_hw->dma_start)(bsc);	outb(DMA1_SMSK, chan);	BUS_IOW(cmd_port, CMDP_DMES);	bsc->sc_flags |= BSDMASTART;}static voidbshw_dmadone(bsc)	struct bs_softc *bsc;{	outb(DMA1_SMSK, (bsc->sc_dmachan | DMA37SM_SET));	BUS_IOW(cmd_port, CMDP_DMER);	/* vendor unique hook */	if (bsc->sc_hw->dma_stop)		(*bsc->sc_hw->dma_stop)(bsc);#ifdef __FreeBSD__	if (need_post_dma_flush)		invd();#else	if (bsc->sc_dmadir & BSHW_READ)		cpu_cf_postRead(curcpu);	else		cpu_cf_postWrite(curcpu);#endif	bsc->sc_flags &= (~BSDMASTART);}/********************************************** * VENDOR UNIQUE DMA FUNCS **********************************************/static intbshw_dma_init_texa(bsc)	struct bs_softc *bsc;{	u_int8_t regval;	if ((regval = read_wd33c93(bsc, 0x37)) & 0x08)		return 0;	write_wd33c93(bsc, 0x37, regval | 0x08);	regval = read_wd33c93(bsc, 0x3f);	write_wd33c93(bsc, 0x3f, regval | 0x08);	return 1;}static intbshw_dma_init_sc98(bsc)	struct bs_softc *bsc;{	if (read_wd33c93(bsc, 0x37) & 0x08)		return 0;	/* If your card is SC98 with bios ver 1.01 or 1.02 under no PCI */	write_wd33c93(bsc, 0x37, 0x1a);	write_wd33c93(bsc, 0x3f, 0x1a);#if	0	/* only valid for IO */	write_wd33c93(bsc, 0x40, 0xf4);	write_wd33c93(bsc, 0x41, 0x9);	write_wd33c93(bsc, 0x43, 0xff);	write_wd33c93(bsc, 0x46, 0x4e);	write_wd33c93(bsc, 0x48, 0xf4);	write_wd33c93(bsc, 0x49, 0x9);	write_wd33c93(bsc, 0x4b, 0xff);	write_wd33c93(bsc, 0x4e, 0x4e);#endif	return 1;}static voidbshw_dma_start_sc98(bsc)	struct bs_softc *bsc;{	write_wd33c93(bsc, 0x73, 0x32);	write_wd33c93(bsc, 0x74, 0x23);}static voidbshw_dma_stop_sc98(bsc)	struct bs_softc *bsc;{	write_wd33c93(bsc, 0x73, 0x43);	write_wd33c93(bsc, 0x74, 0x34);}static voidbshw_dma_start_elecom(bsc)	struct bs_softc *bsc;{	u_int8_t tmp = read_wd33c93(bsc, 0x4c);	write_wd33c93(bsc, 0x32, tmp & 0xdf);}static voidbshw_dma_stop_elecom(bsc)	struct bs_softc *bsc;{	u_int8_t tmp = read_wd33c93(bsc, 0x4c);	write_wd33c93(bsc, 0x32, tmp | 0x20);}

⌨️ 快捷键说明

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