1 /* $FreeBSD: src/sys/i386/isa/bs/bshw_pdma.c,v 1.6.6.1 2000/10/21 07:44:26 nyan Exp $ */
2 /* $NecBSD: bshw_pdma.c,v 1.4 1997/10/31 17:43:39 honda Exp $ */
5 * [NetBSD for NEC PC98 series]
6 * Copyright (c) 1994, 1995, 1996 NetBSD/pc98 porting staff.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
24 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
33 * Copyright (c) 1994, 1995, 1996 Naofumi HONDA. All rights reserved.
36 #define LC_SMIT_TIMEOUT 2 /* 2 sec: timeout for a fifo status ready */
38 static BS_INLINE void bshw_lc_smit_start __P((struct bs_softc *, int, u_int));
39 static int bshw_lc_smit_fstat __P((struct bs_softc *, int, int));
40 static void bshw_lc_smit_stop __P((struct bs_softc *));
42 /*********************************************************
44 *********************************************************/
49 if (bsc->sc_hw->hw_flags & BSHW_SMFIFO)
50 bshw_lc_smit_stop(bsc);
52 bshw_set_count(bsc, 0);
53 bsc->sc_flags &= ~BSSMITSTART;
60 struct bs_softc *bsc = ti->ti_bsc;
61 struct sc_p *sp = &bsc->sc_p;
65 bshw_lc_smit_stop(bsc);
66 bsc->sc_flags &= ~BSSMITSTART;
68 if (ti->ti_phase == DATAPHASE)
70 count = bshw_get_count(bsc);
71 if (count < (u_int) sp->datalen)
73 sp->data += (sp->datalen - count);
76 * strict double checks!
77 * target => wd33c93c transfer counts
78 * wd33c93c => memory transfer counts
80 if ((bsc->sc_dmadir & BSHW_READ) &&
81 count != bsc->sm_tdatalen)
83 s = "read count miss";
88 else if (count == (u_int) sp->datalen)
96 s = "extra smit interrupt";
99 bs_printf(ti, "smit_xfer_end", s);
100 ti->ti_error |= BSDMAABNORMAL;
103 /*********************************************************
104 * LOGITEC's SMIT TRANSFER
105 *********************************************************/
107 #define BSHW_LC_FSET 0x36
108 #define BSHW_LC_FCTRL 0x44
109 #define FCTRL_EN 0x01
110 #define FCTRL_WRITE 0x02
112 #define SF_ABORT 0x08
115 #define LC_FSZ DEV_BSIZE
117 #define LC_REST (LC_FSZ - LC_SFSZ)
120 bshw_lc_smit_stop(bsc)
121 struct bs_softc *bsc;
124 write_wd33c93(bsc, BSHW_LC_FCTRL, 0);
125 BUS_IOW(cmd_port, CMDP_DMER);
128 static BS_INLINE void
129 bshw_lc_smit_start(bsc, count, direction)
130 struct bs_softc *bsc;
134 u_int8_t pval, val = read_wd33c93(bsc, BSHW_LC_FSET);
136 bsc->sc_flags |= BSSMITSTART;
137 bshw_set_count(bsc, count);
140 if ((direction & BSHW_READ) == 0)
141 pval |= (val & 0xe0) | FCTRL_WRITE;
142 write_wd33c93(bsc, BSHW_LC_FCTRL, pval);
143 bshw_start_xfer(bsc);
147 bshw_lc_smit_fstat(bsc, wc, read)
148 struct bs_softc *bsc;
155 if (read == BSHW_READ)
160 stat = BUS_IOR(cmd_port);
169 #endif /* ALWAYS_ABORT */
173 stat = BUS_IOR(cmd_port);
181 #endif /* ALWAYS_ABORT */
183 bs_poll_timeout(bsc, "bshw_lc_smit");
188 bs_lc_smit_xfer(ti, direction)
189 struct targ_info *ti;
192 struct bs_softc *bsc = ti->ti_bsc;
193 struct sc_p *sp = &bsc->sc_p;
194 int datalen, count, wc = LC_SMIT_TIMEOUT * 1024 * 1024;
200 datalen = sp->datalen;
202 bsc->sc_dmadir = direction;
203 bshw_set_dma_trans(bsc, ti->ti_cfgflags);
204 bshw_lc_smit_start(bsc, sp->datalen, direction);
206 if (direction & BSHW_READ)
210 if (bshw_lc_smit_fstat(bsc, wc, BSHW_READ))
213 count = (datalen > LC_FSZ ? LC_FSZ : datalen);
215 memcopy((u_int8_t *)ti->sm_offset, data, count);
217 bus_space_read_region_4(bsc->sc_memt, bsc->sc_memh,
218 ti->sm_offset, (u_int32_t *) data, count >> 2);
225 bsc->sm_tdatalen = datalen;
231 if (bshw_lc_smit_fstat(bsc, wc, BSHW_WRITE))
234 count = (datalen > LC_SFSZ ? LC_SFSZ : datalen);
236 memcopy(data, (u_int8_t *)ti->sm_offset, count);
238 bus_space_write_region_4(bsc->sc_memt, bsc->sc_memh,
239 ti->sm_offset, (u_int32_t *) data, count >> 2);
244 if (bshw_lc_smit_fstat(bsc, wc, BSHW_WRITE))
247 count = (datalen > LC_REST ? LC_REST : datalen);
249 memcopy(data, (u_int8_t *)(ti->sm_offset + LC_SFSZ), count);
251 bus_space_write_region_4(bsc->sc_memt, bsc->sc_memh,
252 ti->sm_offset + LC_SFSZ,
253 (u_int32_t *) data, count >> 2);