📄 bshw_pdma.c
字号:
/* $NecBSD: bshw_pdma.c,v 1.4 1997/10/31 17:43:39 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. */#define LC_SMIT_TIMEOUT 2 /* 2 sec: timeout for a fifo status ready */static BS_INLINE void bshw_lc_smit_start __P((struct bs_softc *, int, u_int));static int bshw_lc_smit_fstat __P((struct bs_softc *, int, int));static BS_INLINE void bshw_lc_smit_stop __P((struct bs_softc *));/********************************************************* * SM FIFO (GENERIC) *********************************************************/voidbshw_smitabort(bsc) struct bs_softc *bsc;{ if (bsc->sc_hw->hw_flags & BSHW_SMFIFO) bshw_lc_smit_stop(bsc); bshw_set_count(bsc, 0); bsc->sc_flags &= ~BSSMITSTART;}voidbs_smit_xfer_end(ti) struct targ_info *ti;{ struct bs_softc *bsc = ti->ti_bsc; struct sc_p *sp = &bsc->sc_p; u_int count; u_char *s; bshw_lc_smit_stop(bsc); bsc->sc_flags &= ~BSSMITSTART; if (ti->ti_phase == DATAPHASE) { count = bshw_get_count(bsc); if (count < (u_int) sp->datalen) { sp->data += (sp->datalen - count); sp->datalen = count; /* XXX: * strict double checks! * target => wd33c93c transfer counts * wd33c93c => memory transfer counts */ if ((bsc->sc_dmadir & BSHW_READ) && count != bsc->sm_tdatalen) { s = "read count miss"; goto bad; } return; } else if (count == (u_int) sp->datalen) { return; } s = "strange count"; } else s = "extra smit interrupt";bad: bs_printf(ti, "smit_xfer_end", s); ti->ti_error |= BSDMAABNORMAL;}/********************************************************* * LOGITEC's SMIT TRANSFER *********************************************************/#define BSHW_LC_FSET 0x36#define BSHW_LC_FCTRL 0x44#define FCTRL_EN 0x01#define FCTRL_WRITE 0x02#define SF_ABORT 0x08#define SF_RDY 0x10#define LC_FSZ DEV_BSIZE#define LC_SFSZ 0x0c#define LC_REST (LC_FSZ - LC_SFSZ)static BS_INLINE voidbshw_lc_smit_stop(bsc) struct bs_softc *bsc;{ write_wd33c93(bsc, BSHW_LC_FCTRL, 0); BUS_IOW(cmd_port, CMDP_DMER);}static BS_INLINE voidbshw_lc_smit_start(bsc, count, direction) struct bs_softc *bsc; int count; u_int direction;{ u_int8_t pval, val = read_wd33c93(bsc, BSHW_LC_FSET); bsc->sc_flags |= BSSMITSTART; bshw_set_count(bsc, count); pval = FCTRL_EN; if ((direction & BSHW_READ) == 0) pval |= (val & 0xe0) | FCTRL_WRITE; write_wd33c93(bsc, BSHW_LC_FCTRL, pval); bshw_start_xfer(bsc);}static intbshw_lc_smit_fstat(bsc, wc, read) struct bs_softc *bsc; int wc, read;{ u_int8_t stat;#define ALWAYS_ABORT#ifdef ALWAYS_ABORT if (read == BSHW_READ) { while (wc -- > 0) { BUS_IO_WEIGHT; stat = BUS_IOR(cmd_port); if (stat & SF_RDY) return 0; if (stat & SF_ABORT) return EIO; } } else {#endif /* ALWAYS_ABORT */ while (wc -- > 0) { BUS_IO_WEIGHT; stat = BUS_IOR(cmd_port); if (stat & SF_ABORT) return EIO; if (stat & SF_RDY) return 0; }#ifdef ALWAYS_ABORT }#endif /* ALWAYS_ABORT */ bs_poll_timeout(bsc, "bshw_lc_smit"); return EIO;}voidbs_lc_smit_xfer(ti, direction) struct targ_info *ti; u_int direction;{ struct bs_softc *bsc = ti->ti_bsc; struct sc_p *sp = &bsc->sc_p; int datalen, count, wc = LC_SMIT_TIMEOUT * 1024 * 1024; u_int8_t *data; sp->bufp = NULL; sp->seglen = 0; data = sp->data; datalen = sp->datalen; bsc->sc_dmadir = direction; bshw_set_dma_trans(bsc, ti->ti_cfgflags); bshw_lc_smit_start(bsc, sp->datalen, direction); if (direction & BSHW_READ) { do { if (bshw_lc_smit_fstat(bsc, wc, BSHW_READ)) break; count = (datalen > LC_FSZ ? LC_FSZ : datalen);#ifdef __FreeBSD__ memcopy((u_int8_t *)ti->sm_offset, data, count);#else /* NetBSD */ bus_space_read_region_4(bsc->sc_memt, bsc->sc_memh, ti->sm_offset, (u_int32_t *) data, count >> 2);#endif /* NetBSD */ data += count; datalen -= count; } while (datalen > 0); bsc->sm_tdatalen = datalen; } else { do { if (bshw_lc_smit_fstat(bsc, wc, BSHW_WRITE)) break; count = (datalen > LC_SFSZ ? LC_SFSZ : datalen);#ifdef __FreeBSD__ memcopy(data, (u_int8_t *)ti->sm_offset, count);#else /* NetBSD */ bus_space_write_region_4(bsc->sc_memt, bsc->sc_memh, ti->sm_offset, (u_int32_t *) data, count >> 2);#endif /* NetBSD */ data += count; datalen -= count; if (bshw_lc_smit_fstat(bsc, wc, BSHW_WRITE)) break; count = (datalen > LC_REST ? LC_REST : datalen);#ifdef __FreeBSD__ memcopy(data, (u_int8_t *)(ti->sm_offset + LC_SFSZ), count);#else /* NetBSD */ bus_space_write_region_4(bsc->sc_memt, bsc->sc_memh, ti->sm_offset + LC_SFSZ, (u_int32_t *) data, count >> 2);#endif /* NetBSD */ data += count; datalen -= count; } while (datalen > 0); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -