1 /* $FreeBSD: src/sys/i386/isa/bs/bshw_pdma.c,v 1.6.6.1 2000/10/21 07:44:26 nyan Exp $ */
2 /* $DragonFly: src/sys/dev/disk/i386/bs/Attic/bshw_pdma.c,v 1.2 2003/06/17 04:28:37 dillon Exp $ */
3 /* $NecBSD: bshw_pdma.c,v 1.4 1997/10/31 17:43:39 honda Exp $ */
6 * [NetBSD for NEC PC98 series]
7 * Copyright (c) 1994, 1995, 1996 NetBSD/pc98 porting staff.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
34 * Copyright (c) 1994, 1995, 1996 Naofumi HONDA. All rights reserved.
37 #define LC_SMIT_TIMEOUT 2 /* 2 sec: timeout for a fifo status ready */
39 static BS_INLINE void bshw_lc_smit_start __P((struct bs_softc *, int, u_int));
40 static int bshw_lc_smit_fstat __P((struct bs_softc *, int, int));
41 static void bshw_lc_smit_stop __P((struct bs_softc *));
43 /*********************************************************
45 *********************************************************/
50 if (bsc->sc_hw->hw_flags & BSHW_SMFIFO)
51 bshw_lc_smit_stop(bsc);
53 bshw_set_count(bsc, 0);
54 bsc->sc_flags &= ~BSSMITSTART;
61 struct bs_softc *bsc = ti->ti_bsc;
62 struct sc_p *sp = &bsc->sc_p;
66 bshw_lc_smit_stop(bsc);
67 bsc->sc_flags &= ~BSSMITSTART;
69 if (ti->ti_phase == DATAPHASE)
71 count = bshw_get_count(bsc);
72 if (count < (u_int) sp->datalen)
74 sp->data += (sp->datalen - count);
77 * strict double checks!
78 * target => wd33c93c transfer counts
79 * wd33c93c => memory transfer counts
81 if ((bsc->sc_dmadir & BSHW_READ) &&
82 count != bsc->sm_tdatalen)
84 s = "read count miss";
89 else if (count == (u_int) sp->datalen)
97 s = "extra smit interrupt";
100 bs_printf(ti, "smit_xfer_end", s);
101 ti->ti_error |= BSDMAABNORMAL;
104 /*********************************************************
105 * LOGITEC's SMIT TRANSFER
106 *********************************************************/
108 #define BSHW_LC_FSET 0x36
109 #define BSHW_LC_FCTRL 0x44
110 #define FCTRL_EN 0x01
111 #define FCTRL_WRITE 0x02
113 #define SF_ABORT 0x08
116 #define LC_FSZ DEV_BSIZE
118 #define LC_REST (LC_FSZ - LC_SFSZ)
121 bshw_lc_smit_stop(bsc)
122 struct bs_softc *bsc;
125 write_wd33c93(bsc, BSHW_LC_FCTRL, 0);
126 BUS_IOW(cmd_port, CMDP_DMER);
129 static BS_INLINE void
130 bshw_lc_smit_start(bsc, count, direction)
131 struct bs_softc *bsc;
135 u_int8_t pval, val = read_wd33c93(bsc, BSHW_LC_FSET);
137 bsc->sc_flags |= BSSMITSTART;
138 bshw_set_count(bsc, count);
141 if ((direction & BSHW_READ) == 0)
142 pval |= (val & 0xe0) | FCTRL_WRITE;
143 write_wd33c93(bsc, BSHW_LC_FCTRL, pval);
144 bshw_start_xfer(bsc);
148 bshw_lc_smit_fstat(bsc, wc, read)
149 struct bs_softc *bsc;
156 if (read == BSHW_READ)
161 stat = BUS_IOR(cmd_port);
170 #endif /* ALWAYS_ABORT */
174 stat = BUS_IOR(cmd_port);
182 #endif /* ALWAYS_ABORT */
184 bs_poll_timeout(bsc, "bshw_lc_smit");
189 bs_lc_smit_xfer(ti, direction)
190 struct targ_info *ti;
193 struct bs_softc *bsc = ti->ti_bsc;
194 struct sc_p *sp = &bsc->sc_p;
195 int datalen, count, wc = LC_SMIT_TIMEOUT * 1024 * 1024;
201 datalen = sp->datalen;
203 bsc->sc_dmadir = direction;
204 bshw_set_dma_trans(bsc, ti->ti_cfgflags);
205 bshw_lc_smit_start(bsc, sp->datalen, direction);
207 if (direction & BSHW_READ)
211 if (bshw_lc_smit_fstat(bsc, wc, BSHW_READ))
214 count = (datalen > LC_FSZ ? LC_FSZ : datalen);
216 memcopy((u_int8_t *)ti->sm_offset, data, count);
218 bus_space_read_region_4(bsc->sc_memt, bsc->sc_memh,
219 ti->sm_offset, (u_int32_t *) data, count >> 2);
226 bsc->sm_tdatalen = datalen;
232 if (bshw_lc_smit_fstat(bsc, wc, BSHW_WRITE))
235 count = (datalen > LC_SFSZ ? LC_SFSZ : datalen);
237 memcopy(data, (u_int8_t *)ti->sm_offset, count);
239 bus_space_write_region_4(bsc->sc_memt, bsc->sc_memh,
240 ti->sm_offset, (u_int32_t *) data, count >> 2);
245 if (bshw_lc_smit_fstat(bsc, wc, BSHW_WRITE))
248 count = (datalen > LC_REST ? LC_REST : datalen);
250 memcopy(data, (u_int8_t *)(ti->sm_offset + LC_SFSZ), count);
252 bus_space_write_region_4(bsc->sc_memt, bsc->sc_memh,
253 ti->sm_offset + LC_SFSZ,
254 (u_int32_t *) data, count >> 2);