8c698438a4ad82c6eafe659e393c7972ac0ab766
[dragonfly.git] / sys / dev / disk / i386 / bs / bshw.h
1 /*      $NecBSD: bshw.h,v 1.2 1997/10/31 17:43:38 honda Exp $   */
2 /*      $NetBSD$        */
3 /*
4  * [NetBSD for NEC PC98 series]
5  *  Copyright (c) 1994, 1995, 1996 NetBSD/pc98 porting staff.
6  *  All rights reserved.
7  * 
8  *  Redistribution and use in source and binary forms, with or without
9  *  modification, are permitted provided that the following conditions
10  *  are met:
11  *  1. Redistributions of source code must retain the above copyright
12  *     notice, this list of conditions and the following disclaimer.
13  *  2. Redistributions in binary form must reproduce the above copyright
14  *     notice, this list of conditions and the following disclaimer in the
15  *     documentation and/or other materials provided with the distribution.
16  *  3. The name of the author may not be used to endorse or promote products
17  *     derived from this software without specific prior written permission.
18  * 
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
23  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 /*
32  * Copyright (c) 1994, 1995, 1996 Naofumi HONDA.  All rights reserved.
33  */
34
35 /* NEC port offsets */
36 #define BSHW_DEFAULT_PORT       0xcc0
37 #define BSHW_IOSZ       5
38
39 #define addr_port       0
40 #define stat_port       0
41 #define ctrl_port       2
42 #define cmd_port        4
43
44 #define BSHW_MAX_OFFSET         12
45 #define BSHW_SEL_TIMEOUT        0x80
46
47 #define BSHW_READ               BSR_IOR
48 #define BSHW_WRITE              0x0
49
50 #define BSHW_SMITFIFO_OFFSET    0x1000
51
52 #define BSHW_CMD_CHECK(CCB, CAT) (bshw_cmd[(CCB)->cmd[0]] & (CAT))
53 /*********************************************************
54  * static inline declare.
55  *********************************************************/
56 static BS_INLINE void write_wd33c93 __P((struct bs_softc *, u_int, u_int8_t));
57 static BS_INLINE u_int8_t read_wd33c93 __P((struct bs_softc *, u_int));
58 static BS_INLINE u_int8_t bshw_get_auxstat __P((struct bs_softc *));
59 static BS_INLINE u_int8_t bshw_get_busstat __P((struct bs_softc *));
60 static BS_INLINE u_int8_t bshw_get_status_insat __P((struct bs_softc *));
61 static BS_INLINE u_int8_t bshw_read_data __P((struct bs_softc *));
62 static BS_INLINE void bshw_write_data __P((struct bs_softc *, u_int8_t));
63 static BS_INLINE void bshw_set_count __P((struct bs_softc *, u_int));
64 static BS_INLINE u_int bshw_get_count __P((struct bs_softc *));
65 static BS_INLINE void bshw_set_dst_id __P((struct bs_softc *, u_int, u_int));
66 static BS_INLINE void bshw_set_lun __P((struct bs_softc *, u_int));
67 static BS_INLINE u_int bshw_get_src_id __P((struct bs_softc *));
68 static BS_INLINE void bshw_negate_ack __P((struct bs_softc *));
69 static BS_INLINE void bshw_assert_atn __P((struct bs_softc *));
70 static BS_INLINE void bshw_assert_select __P((struct bs_softc *));
71 static BS_INLINE void bshw_start_xfer __P((struct bs_softc *));
72 static BS_INLINE void bshw_start_sxfer __P((struct bs_softc *));
73 static BS_INLINE void bshw_cmd_pass __P((struct bs_softc *, u_int));
74 static BS_INLINE void bshw_start_sat __P((struct bs_softc *, u_int));
75 static BS_INLINE void bshw_abort_cmd __P((struct bs_softc *));
76 static BS_INLINE void bshw_set_sync_reg __P((struct bs_softc *, u_int));
77 static BS_INLINE void bshw_set_poll_trans __P((struct bs_softc *, u_int));
78 static BS_INLINE void bshw_set_dma_trans __P((struct bs_softc *, u_int));
79
80 /*********************************************************
81  * global declare
82  *********************************************************/
83 void bs_dma_xfer __P((struct targ_info *, u_int));
84 void bs_dma_xfer_end __P((struct targ_info *));
85 void bshw_dmaabort __P((struct bs_softc *, struct targ_info *));
86
87 void bshw_adj_syncdata __P((struct syncdata *));
88 void bshw_set_synchronous __P((struct bs_softc *, struct targ_info *));
89
90 void bs_smit_xfer_end __P((struct targ_info *));
91 void bshw_smitabort __P((struct bs_softc *));
92
93 void bshw_setup_ctrl_reg __P((struct bs_softc *, u_int));
94 int bshw_chip_reset __P((struct bs_softc *));
95 void bshw_bus_reset __P((struct bs_softc *));
96 int bshw_board_probe __P((struct bs_softc *, u_int *, u_int *));
97 void bshw_lock __P((struct bs_softc *));
98 void bshw_unlock __P((struct bs_softc *));
99 void bshw_get_syncreg __P((struct bs_softc *));
100 void bshw_issue_satcmd __P((struct bs_softc *, struct bsccb *, int));
101 void bshw_print_port __P((struct bs_softc *));
102
103 void bs_lc_smit_xfer __P((struct targ_info *, u_int));
104
105 extern struct dvcfg_hwsel bshw_hwsel;
106 extern u_int8_t bshw_cmd[];
107
108 /*********************************************************
109  * hw
110  *********************************************************/
111 struct bshw {
112 #define BSHW_SYNC_RELOAD        0x01
113 #define BSHW_SMFIFO             0x02
114 #define BSHW_DOUBLE_DMACHAN     0x04
115         u_int hw_flags;
116
117         u_int sregaddr;
118
119         int ((*dma_init) __P((struct bs_softc *)));
120         void ((*dma_start) __P((struct bs_softc *)));
121         void ((*dma_stop) __P((struct bs_softc *)));
122 };
123
124 /*********************************************************
125  * inline funcs.
126  *********************************************************/
127 /*
128  * XXX: If your board does not work well, Please try BS_NEEDS_WEIGHT.
129  */
130 static BS_INLINE void
131 write_wd33c93(bsc, addr, data)
132         struct bs_softc *bsc;
133         u_int addr;
134         u_int8_t data;
135 {
136
137         BUS_IOW(addr_port, addr);
138         BUS_IOW(ctrl_port, data);
139 }
140
141 static BS_INLINE u_int8_t
142 read_wd33c93(bsc, addr)
143         struct bs_softc *bsc;
144         u_int addr;
145 {
146
147         BUS_IOW(addr_port, addr);
148         return BUS_IOR(ctrl_port);
149 }
150
151 /* status */
152 static BS_INLINE u_int8_t
153 bshw_get_auxstat(bsc)
154         struct bs_softc *bsc;
155 {
156
157         return BUS_IOR(stat_port);
158 }
159
160 static BS_INLINE u_int8_t
161 bshw_get_busstat(bsc)
162         struct bs_softc *bsc;
163 {
164
165         return read_wd33c93(bsc, wd3s_stat);
166 }
167
168 static BS_INLINE u_int8_t
169 bshw_get_status_insat(bsc)
170         struct bs_softc *bsc;
171 {
172
173         return read_wd33c93(bsc, wd3s_lun);
174 }
175
176 /* data */
177 static BS_INLINE u_int8_t
178 bshw_read_data(bsc)
179         struct bs_softc *bsc;
180 {
181
182         return read_wd33c93(bsc, wd3s_data);
183 }
184
185 static BS_INLINE void
186 bshw_write_data(bsc, data)
187         struct bs_softc *bsc;
188         u_int8_t data;
189 {
190
191         write_wd33c93(bsc, wd3s_data, data);
192 }
193
194 /* counter */
195 static BS_INLINE void
196 bshw_set_count(bsc, count)
197         struct bs_softc *bsc;
198         u_int count;
199 {
200
201         BUS_IOW(addr_port, wd3s_cnt);
202         BUS_IOW(ctrl_port, count >> 16);
203         BUS_IOW(ctrl_port, count >> 8);
204         BUS_IOW(ctrl_port, count);
205 }
206
207 static BS_INLINE u_int
208 bshw_get_count(bsc)
209         struct bs_softc *bsc;
210 {
211         u_int count;
212
213         BUS_IOW(addr_port, wd3s_cnt);
214         count = (((u_int) BUS_IOR(ctrl_port)) << 16);
215         count += (((u_int) BUS_IOR(ctrl_port)) << 8);
216         count += ((u_int) BUS_IOR(ctrl_port));
217         return count;
218 }
219
220 /* ID */
221 static BS_INLINE void
222 bshw_set_lun(bsc, lun)
223         struct bs_softc *bsc;
224         u_int lun;
225 {
226
227         write_wd33c93(bsc, wd3s_lun, lun);
228 }
229
230 static BS_INLINE void
231 bshw_set_dst_id(bsc, target, lun)
232         struct bs_softc *bsc;
233         u_int target, lun;
234 {
235
236         write_wd33c93(bsc, wd3s_did, target);
237         write_wd33c93(bsc, wd3s_lun, lun);
238 }
239
240 static BS_INLINE u_int
241 bshw_get_src_id(bsc)
242         struct bs_softc *bsc;
243 {
244
245         return (read_wd33c93(bsc, wd3s_sid) & SIDR_IDM);
246 }
247
248 /* phase */
249 static BS_INLINE void
250 bshw_negate_ack(bsc)
251         struct bs_softc *bsc;
252 {
253
254         write_wd33c93(bsc, wd3s_cmd, WD3S_NEGATE_ACK);
255 }
256
257 static BS_INLINE void
258 bshw_assert_atn(bsc)
259         struct bs_softc *bsc;
260 {
261
262         write_wd33c93(bsc, wd3s_cmd, WD3S_ASSERT_ATN);
263 }
264
265 static BS_INLINE void
266 bshw_assert_select(bsc)
267         struct bs_softc *bsc;
268 {
269
270         write_wd33c93(bsc, wd3s_cmd, WD3S_SELECT_ATN);
271 }
272
273 static BS_INLINE void
274 bshw_start_xfer(bsc)
275         struct bs_softc *bsc;
276 {
277
278         write_wd33c93(bsc, wd3s_cmd, WD3S_TFR_INFO);
279 }
280
281 static BS_INLINE void
282 bshw_start_sxfer(bsc)
283         struct bs_softc *bsc;
284 {
285
286         write_wd33c93(bsc, wd3s_cmd, WD3S_SBT | WD3S_TFR_INFO);
287 }
288
289 static BS_INLINE void
290 bshw_cmd_pass(bsc, ph)
291         struct bs_softc *bsc;
292         u_int ph;
293 {
294
295         write_wd33c93(bsc, wd3s_cph, ph);
296 }
297
298 static BS_INLINE void
299 bshw_start_sat(bsc, flag)
300         struct bs_softc *bsc;
301         u_int flag;
302 {
303
304         write_wd33c93(bsc, wd3s_cmd,
305                       (flag ? WD3S_SELECT_ATN_TFR : WD3S_SELECT_NO_ATN_TFR));
306 }
307
308
309 static BS_INLINE void
310 bshw_abort_cmd(bsc)
311         struct bs_softc *bsc;
312 {
313
314         write_wd33c93(bsc, wd3s_cmd, WD3S_ABORT);
315 }
316
317 /* transfer mode */
318 static BS_INLINE void
319 bshw_set_sync_reg(bsc, val)
320         struct bs_softc *bsc;
321         u_int val;
322 {
323
324         write_wd33c93(bsc, wd3s_synch, val);
325 }
326
327 static BS_INLINE void
328 bshw_set_poll_trans(bsc, flags)
329         struct bs_softc *bsc;
330         u_int flags;
331 {
332
333         if (bsc->sc_flags & BSDMATRANSFER)
334         {
335                 bsc->sc_flags &= ~BSDMATRANSFER;
336                 bshw_setup_ctrl_reg(bsc, flags);
337         }
338 }
339
340 static BS_INLINE void
341 bshw_set_dma_trans(bsc, flags)
342         struct bs_softc *bsc;
343         u_int flags;
344 {
345
346         if ((bsc->sc_flags & BSDMATRANSFER) == 0)
347         {
348                 bsc->sc_flags |= BSDMATRANSFER;
349                 bshw_setup_ctrl_reg(bsc, flags);
350         }
351 }