Bug Summary

File:dev/ic/iha.c
Warning:line 1817, column 3
Value stored to 'phase' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name iha.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -D CONFIG_DRM_AMD_DC_DCN3_0 -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /usr/obj/sys/arch/amd64/compile/GENERIC.MP/scan-build/2022-01-12-131800-47421-1 -x c /usr/src/sys/dev/ic/iha.c
1/* $OpenBSD: iha.c,v 1.52 2020/09/22 19:32:52 krw Exp $ */
2/*-------------------------------------------------------------------------
3 *
4 * Device driver for the INI-9XXXU/UW or INIC-940/950 PCI SCSI Controller.
5 *
6 * Written for 386bsd and FreeBSD by
7 * Winston Hung <winstonh@initio.com>
8 *
9 * Copyright (c) 1997-1999 Initio Corp
10 * Copyright (c) 2000-2002 Ken Westerback
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer,
17 * without modification, immediately at the beginning of the file.
18 * 2. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES 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 MIND, 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
30 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 *-------------------------------------------------------------------------
34 */
35#include <sys/param.h>
36#include <sys/systm.h>
37#include <sys/buf.h>
38#include <sys/device.h>
39
40#include <machine/bus.h>
41#include <machine/intr.h>
42
43#include <scsi/scsi_all.h>
44#include <scsi/scsiconf.h>
45#include <scsi/scsi_message.h>
46
47#include <dev/ic/iha.h>
48
49/* #define IHA_DEBUG_STATE */
50
51/*
52 * SCSI Rate Table, indexed by FLAG_SCSI_RATE field of
53 * TCS_Flags.
54 */
55static const u_int8_t iha_rate_tbl[] = {
56 /* fast 20 */
57 /* nanosecond divide by 4 */
58 12, /* 50ns, 20M */
59 18, /* 75ns, 13.3M */
60 25, /* 100ns, 10M */
61 31, /* 125ns, 8M */
62 37, /* 150ns, 6.6M */
63 43, /* 175ns, 5.7M */
64 50, /* 200ns, 5M */
65 62 /* 250ns, 4M */
66};
67
68int iha_setup_sg_list(struct iha_softc *, struct iha_scb *);
69u_int8_t iha_data_over_run(struct iha_scb *);
70int iha_push_sense_request(struct iha_softc *, struct iha_scb *);
71void iha_timeout(void *);
72int iha_alloc_scbs(struct iha_softc *);
73void iha_read_eeprom(bus_space_tag_t, bus_space_handle_t,
74 struct iha_nvram *);
75void iha_se2_instr(bus_space_tag_t, bus_space_handle_t, u_int8_t);
76u_int16_t iha_se2_rd(bus_space_tag_t, bus_space_handle_t, u_int8_t);
77void iha_reset_scsi_bus(struct iha_softc *);
78void iha_reset_chip(struct iha_softc *,
79 bus_space_tag_t, bus_space_handle_t);
80void iha_reset_dma(bus_space_tag_t, bus_space_handle_t);
81void iha_reset_tcs(struct tcs *, u_int8_t);
82void iha_print_info(struct iha_softc *, int);
83void iha_done_scb(struct iha_softc *, struct iha_scb *);
84void iha_exec_scb(struct iha_softc *, struct iha_scb *);
85void iha_main(struct iha_softc *, bus_space_tag_t, bus_space_handle_t);
86void iha_scsi(struct iha_softc *, bus_space_tag_t, bus_space_handle_t);
87int iha_wait(struct iha_softc *, bus_space_tag_t, bus_space_handle_t,
88 u_int8_t);
89void iha_mark_busy_scb(struct iha_scb *);
90void *iha_scb_alloc(void *);
91void iha_scb_free(void *, void *);
92void iha_append_done_scb(struct iha_softc *, struct iha_scb *,
93 u_int8_t);
94struct iha_scb *iha_pop_done_scb(struct iha_softc *);
95void iha_append_pend_scb(struct iha_softc *, struct iha_scb *);
96void iha_push_pend_scb(struct iha_softc *, struct iha_scb *);
97struct iha_scb *iha_find_pend_scb(struct iha_softc *);
98void iha_sync_done(struct iha_softc *,
99 bus_space_tag_t, bus_space_handle_t);
100void iha_wide_done(struct iha_softc *,
101 bus_space_tag_t, bus_space_handle_t);
102void iha_bad_seq(struct iha_softc *);
103int iha_next_state(struct iha_softc *,
104 bus_space_tag_t, bus_space_handle_t);
105int iha_state_1(struct iha_softc *,
106 bus_space_tag_t, bus_space_handle_t);
107int iha_state_2(struct iha_softc *,
108 bus_space_tag_t, bus_space_handle_t);
109int iha_state_3(struct iha_softc *,
110 bus_space_tag_t, bus_space_handle_t);
111int iha_state_4(struct iha_softc *,
112 bus_space_tag_t, bus_space_handle_t);
113int iha_state_5(struct iha_softc *,
114 bus_space_tag_t, bus_space_handle_t);
115int iha_state_6(struct iha_softc *,
116 bus_space_tag_t, bus_space_handle_t);
117int iha_state_8(struct iha_softc *,
118 bus_space_tag_t, bus_space_handle_t);
119void iha_set_ssig(bus_space_tag_t,
120 bus_space_handle_t, u_int8_t, u_int8_t);
121int iha_xpad_in(struct iha_softc *,
122 bus_space_tag_t, bus_space_handle_t);
123int iha_xpad_out(struct iha_softc *,
124 bus_space_tag_t, bus_space_handle_t);
125int iha_xfer_data(struct iha_scb *,
126 bus_space_tag_t, bus_space_handle_t,
127 int direction);
128int iha_status_msg(struct iha_softc *,
129 bus_space_tag_t, bus_space_handle_t);
130int iha_msgin(struct iha_softc *, bus_space_tag_t, bus_space_handle_t);
131int iha_msgin_sdtr(struct iha_softc *);
132int iha_msgin_extended(struct iha_softc *,
133 bus_space_tag_t, bus_space_handle_t);
134int iha_msgin_ignore_wid_resid(struct iha_softc *,
135 bus_space_tag_t, bus_space_handle_t);
136int iha_msgout(struct iha_softc *,
137 bus_space_tag_t, bus_space_handle_t, u_int8_t);
138int iha_msgout_extended(struct iha_softc *,
139 bus_space_tag_t, bus_space_handle_t);
140void iha_msgout_abort(struct iha_softc *,
141 bus_space_tag_t, bus_space_handle_t, u_int8_t);
142int iha_msgout_reject(struct iha_softc *,
143 bus_space_tag_t, bus_space_handle_t);
144int iha_msgout_sdtr(struct iha_softc *,
145 bus_space_tag_t, bus_space_handle_t);
146int iha_msgout_wdtr(struct iha_softc *,
147 bus_space_tag_t, bus_space_handle_t);
148void iha_select(struct iha_softc *,
149 bus_space_tag_t, bus_space_handle_t,
150 struct iha_scb *, u_int8_t);
151void iha_busfree(struct iha_softc *,
152 bus_space_tag_t, bus_space_handle_t);
153int iha_resel(struct iha_softc *, bus_space_tag_t, bus_space_handle_t);
154void iha_abort_xs(struct iha_softc *, struct scsi_xfer *, u_int8_t);
155
156/*
157 * iha_intr - the interrupt service routine for the iha driver
158 */
159int
160iha_intr(void *arg)
161{
162 bus_space_handle_t ioh;
163 struct iha_softc *sc;
164 bus_space_tag_t iot;
165 int s;
166
167 sc = (struct iha_softc *)arg;
168 iot = sc->sc_iot;
169 ioh = sc->sc_ioh;
170
171 if ((bus_space_read_1(iot, ioh, TUL_STAT0)((iot)->read_1((ioh), (0x85))) & INTPD0x80) == 0)
172 return (0);
173
174 s = splbio()splraise(0x6); /* XXX - Or are interrupts off when ISR's are called? */
175
176 if (sc->HCS_Semaph != SEMAPH_IN_MAIN0x00) {
177 /* XXX - need these inside a splbio()/splx()? */
178 bus_space_write_1(iot, ioh, TUL_IMSK, MASK_ALL)((iot)->write_1((ioh), (0xE0), ((0x01 | 0x02 | 0x04 | 0x08
| 0x10))))
;
179 sc->HCS_Semaph = SEMAPH_IN_MAIN0x00;
180
181 iha_main(sc, iot, ioh);
182
183 sc->HCS_Semaph = ~SEMAPH_IN_MAIN0x00;
184 bus_space_write_1(iot, ioh, TUL_IMSK, (MASK_ALL & ~MSCMP))((iot)->write_1((ioh), (0xE0), (((0x01 | 0x02 | 0x04 | 0x08
| 0x10) & ~0x10))))
;
185 }
186
187 splx(s)spllower(s);
188
189 return (1);
190}
191
192/*
193 * iha_setup_sg_list - initialize scatter gather list of pScb from
194 * pScb->SCB_DataDma.
195 */
196int
197iha_setup_sg_list(struct iha_softc *sc, struct iha_scb *pScb)
198{
199 bus_dma_segment_t *segs = pScb->SCB_DataDma->dm_segs;
200 int i, error, nseg = pScb->SCB_DataDma->dm_nsegs;
201
202 if (nseg > 1) {
203 error = bus_dmamap_load(sc->sc_dmat, pScb->SCB_SGDma,(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (pScb->
SCB_SGDma), (pScb->SCB_SGList), (sizeof(pScb->SCB_SGList
)), (((void *)0)), ((pScb->SCB_Flags & 0x00001) ? 0x0001
: 0x0000))
204 pScb->SCB_SGList, sizeof(pScb->SCB_SGList), NULL,(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (pScb->
SCB_SGDma), (pScb->SCB_SGList), (sizeof(pScb->SCB_SGList
)), (((void *)0)), ((pScb->SCB_Flags & 0x00001) ? 0x0001
: 0x0000))
205 (pScb->SCB_Flags & SCSI_NOSLEEP) ?(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (pScb->
SCB_SGDma), (pScb->SCB_SGList), (sizeof(pScb->SCB_SGList
)), (((void *)0)), ((pScb->SCB_Flags & 0x00001) ? 0x0001
: 0x0000))
206 BUS_DMA_NOWAIT : BUS_DMA_WAITOK)(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (pScb->
SCB_SGDma), (pScb->SCB_SGList), (sizeof(pScb->SCB_SGList
)), (((void *)0)), ((pScb->SCB_Flags & 0x00001) ? 0x0001
: 0x0000))
;
207 if (error) {
208 sc_print_addr(pScb->SCB_Xs->sc_link);
209 printf("error %d loading SG list dma map\n", error);
210 return (error);
211 }
212
213 /*
214 * Only set FLAG_SG when SCB_SGDma is loaded so iha_scsi_done
215 * will not unload an unloaded map.
216 */
217 pScb->SCB_Flags |= FLAG_SG0x00020000;
218 bzero(pScb->SCB_SGList, sizeof(pScb->SCB_SGList))__builtin_bzero((pScb->SCB_SGList), (sizeof(pScb->SCB_SGList
)))
;
219
220 pScb->SCB_SGIdx = 0;
221 pScb->SCB_SGCount = nseg;
222
223 for (i=0; i < nseg; i++) {
224 pScb->SCB_SGList[i].SG_Len = segs[i].ds_len;
225 pScb->SCB_SGList[i].SG_Addr = segs[i].ds_addr;
226 }
227
228 bus_dmamap_sync(sc->sc_dmat, pScb->SCB_SGDma,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (pScb->
SCB_SGDma), (0), (sizeof(pScb->SCB_SGList)), (0x04))
229 0, sizeof(pScb->SCB_SGList), BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (pScb->
SCB_SGDma), (0), (sizeof(pScb->SCB_SGList)), (0x04))
;
230 }
231
232 return (0);
233}
234
235/*
236 * iha_scsi_cmd - start execution of a SCSI command. This is called
237 * from the generic SCSI driver via the field
238 * sc_adapter.scsi_cmd of iha_softc.
239 */
240void
241iha_scsi_cmd(struct scsi_xfer *xs)
242{
243 struct iha_scb *pScb;
244 struct scsi_link *sc_link = xs->sc_link;
245 struct iha_softc *sc = sc_link->bus->sb_adapter_softc;
246 int error;
247
248 if ((xs->cmdlen > 12) || (sc_link->target >= IHA_MAX_TARGETS16)) {
249 xs->error = XS_DRIVER_STUFFUP2;
250 scsi_done(xs);
251 return;
252 }
253
254 pScb = xs->io;
255
256 pScb->SCB_Target = sc_link->target;
257 pScb->SCB_Lun = sc_link->lun;
258 pScb->SCB_Tcs = &sc->HCS_Tcs[pScb->SCB_Target];
259 pScb->SCB_Flags = xs->flags;
260 pScb->SCB_Ident = MSG_IDENTIFYFLAG0x80 |
261 (pScb->SCB_Lun & MSG_IDENTIFY_LUNMASK0x01F);
262
263 if ((xs->cmd.opcode != REQUEST_SENSE0x03)
264 && ((pScb->SCB_Flags & SCSI_POLL0x00002) == 0))
265 pScb->SCB_Ident |= MSG_IDENTIFY_DISCFLAG0x40;
266
267 pScb->SCB_Xs = xs;
268 pScb->SCB_CDBLen = xs->cmdlen;
269 bcopy(&xs->cmd, &pScb->SCB_CDB, xs->cmdlen);
270
271 pScb->SCB_BufCharsLeft = pScb->SCB_BufChars = xs->datalen;
272
273 if ((pScb->SCB_Flags & (SCSI_DATA_IN0x00800 | SCSI_DATA_OUT0x01000)) != 0) {
274 error = bus_dmamap_load(sc->sc_dmat, pScb->SCB_DataDma,(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (pScb->
SCB_DataDma), (xs->data), (pScb->SCB_BufChars), (((void
*)0)), ((pScb->SCB_Flags & 0x00001) ? 0x0001 : 0x0000
))
275 xs->data, pScb->SCB_BufChars, NULL,(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (pScb->
SCB_DataDma), (xs->data), (pScb->SCB_BufChars), (((void
*)0)), ((pScb->SCB_Flags & 0x00001) ? 0x0001 : 0x0000
))
276 (pScb->SCB_Flags & SCSI_NOSLEEP) ?(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (pScb->
SCB_DataDma), (xs->data), (pScb->SCB_BufChars), (((void
*)0)), ((pScb->SCB_Flags & 0x00001) ? 0x0001 : 0x0000
))
277 BUS_DMA_NOWAIT : BUS_DMA_WAITOK)(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (pScb->
SCB_DataDma), (xs->data), (pScb->SCB_BufChars), (((void
*)0)), ((pScb->SCB_Flags & 0x00001) ? 0x0001 : 0x0000
))
;
278
279 if (error) {
280 sc_print_addr(xs->sc_link);
281 if (error == EFBIG27)
282 printf("buffer needs >%d dma segments\n",
283 IHA_MAX_SG_ENTRIES33);
284 else
285 printf("error %d loading buffer dma map\n",
286 error);
287
288 xs->error = XS_DRIVER_STUFFUP2;
289 scsi_done(xs);
290 return;
291 }
292 bus_dmamap_sync(sc->sc_dmat, pScb->SCB_DataDma,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (pScb->
SCB_DataDma), (0), (pScb->SCB_BufChars), ((pScb->SCB_Flags
& 0x00800) ? 0x01 : 0x04))
293 0, pScb->SCB_BufChars,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (pScb->
SCB_DataDma), (0), (pScb->SCB_BufChars), ((pScb->SCB_Flags
& 0x00800) ? 0x01 : 0x04))
294 (pScb->SCB_Flags & SCSI_DATA_IN) ?(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (pScb->
SCB_DataDma), (0), (pScb->SCB_BufChars), ((pScb->SCB_Flags
& 0x00800) ? 0x01 : 0x04))
295 BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (pScb->
SCB_DataDma), (0), (pScb->SCB_BufChars), ((pScb->SCB_Flags
& 0x00800) ? 0x01 : 0x04))
;
296
297 error = iha_setup_sg_list(sc, pScb);
298 if (error) {
299 bus_dmamap_unload(sc->sc_dmat, pScb->SCB_DataDma)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (pScb
->SCB_DataDma))
;
300 xs->error = XS_DRIVER_STUFFUP2;
301 scsi_done(xs);
302 return;
303 }
304
305 }
306
307 /*
308 * Always initialize the stimeout structure as it may
309 * contain garbage that confuses timeout_del() later on.
310 * But, timeout_add() ONLY if we are not polling.
311 */
312 timeout_set(&xs->stimeout, iha_timeout, pScb);
313
314 iha_exec_scb(sc, pScb);
315}
316
317/*
318 * iha_init_tulip - initialize the inic-940/950 card and the rest of the
319 * iha_softc structure supplied
320 */
321int
322iha_init_tulip(struct iha_softc *sc)
323{
324 struct iha_scb *pScb;
325 struct iha_nvram_scsi *pScsi;
326 bus_space_handle_t ioh;
327 struct iha_nvram iha_nvram;
328 bus_space_tag_t iot;
329 int i, error;
330
331 iot = sc->sc_iot;
332 ioh = sc->sc_ioh;
333
334 iha_read_eeprom(iot, ioh, &iha_nvram);
335
336 pScsi = &iha_nvram.NVM_Scsi[0];
337
338 TAILQ_INIT(&sc->HCS_FreeScb)do { (&sc->HCS_FreeScb)->tqh_first = ((void *)0); (
&sc->HCS_FreeScb)->tqh_last = &(&sc->HCS_FreeScb
)->tqh_first; } while (0)
;
339 TAILQ_INIT(&sc->HCS_PendScb)do { (&sc->HCS_PendScb)->tqh_first = ((void *)0); (
&sc->HCS_PendScb)->tqh_last = &(&sc->HCS_PendScb
)->tqh_first; } while (0)
;
340 TAILQ_INIT(&sc->HCS_DoneScb)do { (&sc->HCS_DoneScb)->tqh_first = ((void *)0); (
&sc->HCS_DoneScb)->tqh_last = &(&sc->HCS_DoneScb
)->tqh_first; } while (0)
;
341
342 mtx_init(&sc->sc_scb_mtx, IPL_BIO)do { (void)(((void *)0)); (void)(0); __mtx_init((&sc->
sc_scb_mtx), ((((0x6)) > 0x0 && ((0x6)) < 0x9) ?
0x9 : ((0x6)))); } while (0)
;
343 scsi_iopool_init(&sc->sc_iopool, sc, iha_scb_alloc, iha_scb_free);
344
345 sc->HCS_Semaph = ~SEMAPH_IN_MAIN0x00;
346 sc->HCS_JSStatus0 = 0;
347 sc->HCS_ActScb = NULL((void *)0);
348 sc->sc_id = pScsi->NVM_SCSI_Id;
349 sc->sc_maxtargets = pScsi->NVM_SCSI_Targets;
350
351 error = iha_alloc_scbs(sc);
352 if (error != 0)
353 return (error);
354
355 for (i = 0, pScb = sc->HCS_Scb; i < IHA_MAX_SCB32; i++, pScb++) {
356 pScb->SCB_TagId = i;
357
358 error = bus_dmamap_create(sc->sc_dmat,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), ((33
-1) * (1 << 12)), (33), ((33 -1) * (1 << 12)), (
0), (0x0001 | 0x0002), (&pScb->SCB_DataDma))
359 (IHA_MAX_SG_ENTRIES-1) * PAGE_SIZE, IHA_MAX_SG_ENTRIES,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), ((33
-1) * (1 << 12)), (33), ((33 -1) * (1 << 12)), (
0), (0x0001 | 0x0002), (&pScb->SCB_DataDma))
360 (IHA_MAX_SG_ENTRIES-1) * PAGE_SIZE, 0,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), ((33
-1) * (1 << 12)), (33), ((33 -1) * (1 << 12)), (
0), (0x0001 | 0x0002), (&pScb->SCB_DataDma))
361 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &pScb->SCB_DataDma)(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), ((33
-1) * (1 << 12)), (33), ((33 -1) * (1 << 12)), (
0), (0x0001 | 0x0002), (&pScb->SCB_DataDma))
;
362
363 if (error != 0) {
364 printf("%s: couldn't create SCB data DMA map, error = %d\n",
365 sc->sc_dev.dv_xname, error);
366 return (error);
367 }
368
369 error = bus_dmamap_create(sc->sc_dmat,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), (sizeof
(pScb->SCB_SGList)), (1), (sizeof(pScb->SCB_SGList)), (
0), (0x0001 | 0x0002), (&pScb->SCB_SGDma))
370 sizeof(pScb->SCB_SGList), 1,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), (sizeof
(pScb->SCB_SGList)), (1), (sizeof(pScb->SCB_SGList)), (
0), (0x0001 | 0x0002), (&pScb->SCB_SGDma))
371 sizeof(pScb->SCB_SGList), 0,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), (sizeof
(pScb->SCB_SGList)), (1), (sizeof(pScb->SCB_SGList)), (
0), (0x0001 | 0x0002), (&pScb->SCB_SGDma))
372 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), (sizeof
(pScb->SCB_SGList)), (1), (sizeof(pScb->SCB_SGList)), (
0), (0x0001 | 0x0002), (&pScb->SCB_SGDma))
373 &pScb->SCB_SGDma)(*(sc->sc_dmat)->_dmamap_create)((sc->sc_dmat), (sizeof
(pScb->SCB_SGList)), (1), (sizeof(pScb->SCB_SGList)), (
0), (0x0001 | 0x0002), (&pScb->SCB_SGDma))
;
374 if (error != 0) {
375 printf("%s: couldn't create SCB SG DMA map, error = %d\n",
376 sc->sc_dev.dv_xname, error);
377 return (error);
378 }
379
380 TAILQ_INSERT_TAIL(&sc->HCS_FreeScb, pScb, SCB_ScbList)do { (pScb)->SCB_ScbList.tqe_next = ((void *)0); (pScb)->
SCB_ScbList.tqe_prev = (&sc->HCS_FreeScb)->tqh_last
; *(&sc->HCS_FreeScb)->tqh_last = (pScb); (&sc->
HCS_FreeScb)->tqh_last = &(pScb)->SCB_ScbList.tqe_next
; } while (0)
;
381 }
382
383 /* Mask all the interrupts */
384 bus_space_write_1(iot, ioh, TUL_IMSK, MASK_ALL)((iot)->write_1((ioh), (0xE0), ((0x01 | 0x02 | 0x04 | 0x08
| 0x10))))
;
385
386 /* Stop any I/O and reset the scsi module */
387 iha_reset_dma(iot, ioh);
388 bus_space_write_1(iot, ioh, TUL_SCTRL0, RSMOD)((iot)->write_1((ioh), (0x85), (0x02)));
389
390 /* Program HBA's SCSI ID */
391 bus_space_write_1(iot, ioh, TUL_SID, sc->sc_id << 4)((iot)->write_1((ioh), (0x89), (sc->sc_id << 4)));
392
393 /*
394 * Configure the channel as requested by the NVRAM settings read
395 * into iha_nvram by iha_read_eeprom() above.
396 */
397
398 if ((pScsi->NVM_SCSI_Cfg & CFG_EN_PAR0x0002) != 0)
399 sc->HCS_SConf1 = (SCONFIG0DEFAULT(0x80 | 0x40 | 0x02 | 0x01) | SPCHK0x20);
400 else
401 sc->HCS_SConf1 = (SCONFIG0DEFAULT(0x80 | 0x40 | 0x02 | 0x01));
402 bus_space_write_1(iot, ioh, TUL_SCONFIG0, sc->HCS_SConf1)((iot)->write_1((ioh), (0x87), (sc->HCS_SConf1)));
403
404 /* selection time out in units of 1.6385 millisecond = 250 ms */
405 bus_space_write_1(iot, ioh, TUL_STIMO, 153)((iot)->write_1((ioh), (0x8A), (153)));
406
407 /* Enable desired SCSI termination configuration read from eeprom */
408 bus_space_write_1(iot, ioh, TUL_DCTRL0,((iot)->write_1((ioh), (0xE4), ((pScsi->NVM_SCSI_Cfg &
(0x0004 | 0x0008)))))
409 (pScsi->NVM_SCSI_Cfg & (CFG_ACT_TERM1 | CFG_ACT_TERM2)))((iot)->write_1((ioh), (0xE4), ((pScsi->NVM_SCSI_Cfg &
(0x0004 | 0x0008)))))
;
410
411 bus_space_write_1(iot, ioh, TUL_GCTRL1,((iot)->write_1((ioh), (0x55), (((pScsi->NVM_SCSI_Cfg &
0x0010) >> 4) | (((iot)->read_1((ioh), (0x55))) &
(~0x01)))))
412 ((pScsi->NVM_SCSI_Cfg & CFG_AUTO_TERM) >> 4)((iot)->write_1((ioh), (0x55), (((pScsi->NVM_SCSI_Cfg &
0x0010) >> 4) | (((iot)->read_1((ioh), (0x55))) &
(~0x01)))))
413 | (bus_space_read_1(iot, ioh, TUL_GCTRL1) & (~ATDEN)))((iot)->write_1((ioh), (0x55), (((pScsi->NVM_SCSI_Cfg &
0x0010) >> 4) | (((iot)->read_1((ioh), (0x55))) &
(~0x01)))))
;
414
415 for (i = 0; i < IHA_MAX_TARGETS16; i++) {
416 sc->HCS_Tcs[i].TCS_Flags = pScsi->NVM_SCSI_TargetFlags[i];
417 iha_reset_tcs(&sc->HCS_Tcs[i], sc->HCS_SConf1);
418 }
419
420 iha_reset_chip(sc, iot, ioh);
421 bus_space_write_1(iot, ioh, TUL_SIEN, ALL_INTERRUPTS)((iot)->write_1((ioh), (0x84), (0xff)));
422
423 return (0);
424}
425
426/*
427 * iha_reset_dma - abort any active DMA xfer, reset tulip FIFO.
428 */
429void
430iha_reset_dma(bus_space_tag_t iot, bus_space_handle_t ioh)
431{
432 if ((bus_space_read_1(iot, ioh, TUL_ISTUS1)((iot)->read_1((ioh), (0xDD))) & XPEND0x01) != 0) {
433 /* if DMA xfer is pending, abort DMA xfer */
434 bus_space_write_1(iot, ioh, TUL_DCMD, ABTXFR)((iot)->write_1((ioh), (0xD8), (0x04)));
435 /* wait Abort DMA xfer done */
436 while ((bus_space_read_1(iot, ioh, TUL_ISTUS0)((iot)->read_1((ioh), (0xDC))) & DABT0x04) == 0)
437 ;
438 }
439
440 bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO)((iot)->write_1((ioh), (0x85), (0x10)));
441}
442
443/*
444 * iha_scb_alloc - return the first free SCB, or NULL if there are none.
445 */
446void *
447iha_scb_alloc(void *xsc)
448{
449 struct iha_softc *sc = xsc;
450 struct iha_scb *pScb;
451
452 mtx_enter(&sc->sc_scb_mtx);
453 pScb = TAILQ_FIRST(&sc->HCS_FreeScb)((&sc->HCS_FreeScb)->tqh_first);
454 if (pScb != NULL((void *)0)) {
455 pScb->SCB_Status = STATUS_RENT1;
456 TAILQ_REMOVE(&sc->HCS_FreeScb, pScb, SCB_ScbList)do { if (((pScb)->SCB_ScbList.tqe_next) != ((void *)0)) (pScb
)->SCB_ScbList.tqe_next->SCB_ScbList.tqe_prev = (pScb)->
SCB_ScbList.tqe_prev; else (&sc->HCS_FreeScb)->tqh_last
= (pScb)->SCB_ScbList.tqe_prev; *(pScb)->SCB_ScbList.tqe_prev
= (pScb)->SCB_ScbList.tqe_next; ((pScb)->SCB_ScbList.tqe_prev
) = ((void *)-1); ((pScb)->SCB_ScbList.tqe_next) = ((void *
)-1); } while (0)
;
457 }
458 mtx_leave(&sc->sc_scb_mtx);
459
460 return (pScb);
461}
462
463/*
464 * iha_scb_free - append the supplied SCB to the tail of the
465 * HCS_FreeScb queue after clearing and resetting
466 * everything possible.
467 */
468void
469iha_scb_free(void *xsc, void *xscb)
470{
471 struct iha_softc *sc = xsc;
472 struct iha_scb *pScb = xscb;
473 int s;
474
475 s = splbio()splraise(0x6);
476 if (pScb == sc->HCS_ActScb)
477 sc->HCS_ActScb = NULL((void *)0);
478 splx(s)spllower(s);
479
480 pScb->SCB_Status = STATUS_QUEUED0;
481 pScb->SCB_HaStat = HOST_OK0x00;
482 pScb->SCB_TaStat = SCSI_OK0x00;
483
484 pScb->SCB_NxtStat = 0;
485 pScb->SCB_Flags = 0;
486 pScb->SCB_Target = 0;
487 pScb->SCB_Lun = 0;
488 pScb->SCB_CDBLen = 0;
489 pScb->SCB_Ident = 0;
490 pScb->SCB_TagMsg = 0;
491
492 pScb->SCB_BufChars = 0;
493 pScb->SCB_BufCharsLeft = 0;
494
495 pScb->SCB_Xs = NULL((void *)0);
496 pScb->SCB_Tcs = NULL((void *)0);
497
498 bzero(pScb->SCB_CDB, sizeof(pScb->SCB_CDB))__builtin_bzero((pScb->SCB_CDB), (sizeof(pScb->SCB_CDB)
))
;
499
500 /*
501 * SCB_TagId is set at initialization and never changes
502 */
503
504 mtx_enter(&sc->sc_scb_mtx);
505 TAILQ_INSERT_TAIL(&sc->HCS_FreeScb, pScb, SCB_ScbList)do { (pScb)->SCB_ScbList.tqe_next = ((void *)0); (pScb)->
SCB_ScbList.tqe_prev = (&sc->HCS_FreeScb)->tqh_last
; *(&sc->HCS_FreeScb)->tqh_last = (pScb); (&sc->
HCS_FreeScb)->tqh_last = &(pScb)->SCB_ScbList.tqe_next
; } while (0)
;
506 mtx_leave(&sc->sc_scb_mtx);
507}
508
509void
510iha_append_pend_scb(struct iha_softc *sc, struct iha_scb *pScb)
511{
512 /* ASSUMPTION: only called within a splbio()/splx() pair */
513
514 if (pScb == sc->HCS_ActScb)
515 sc->HCS_ActScb = NULL((void *)0);
516
517 pScb->SCB_Status = STATUS_QUEUED0;
518
519 TAILQ_INSERT_TAIL(&sc->HCS_PendScb, pScb, SCB_ScbList)do { (pScb)->SCB_ScbList.tqe_next = ((void *)0); (pScb)->
SCB_ScbList.tqe_prev = (&sc->HCS_PendScb)->tqh_last
; *(&sc->HCS_PendScb)->tqh_last = (pScb); (&sc->
HCS_PendScb)->tqh_last = &(pScb)->SCB_ScbList.tqe_next
; } while (0)
;
520}
521
522void
523iha_push_pend_scb(struct iha_softc *sc, struct iha_scb *pScb)
524{
525 int s;
526
527 s = splbio()splraise(0x6);
528
529 if (pScb == sc->HCS_ActScb)
530 sc->HCS_ActScb = NULL((void *)0);
531
532 pScb->SCB_Status = STATUS_QUEUED0;
533
534 TAILQ_INSERT_HEAD(&sc->HCS_PendScb, pScb, SCB_ScbList)do { if (((pScb)->SCB_ScbList.tqe_next = (&sc->HCS_PendScb
)->tqh_first) != ((void *)0)) (&sc->HCS_PendScb)->
tqh_first->SCB_ScbList.tqe_prev = &(pScb)->SCB_ScbList
.tqe_next; else (&sc->HCS_PendScb)->tqh_last = &
(pScb)->SCB_ScbList.tqe_next; (&sc->HCS_PendScb)->
tqh_first = (pScb); (pScb)->SCB_ScbList.tqe_prev = &(&
sc->HCS_PendScb)->tqh_first; } while (0)
;
535
536 splx(s)spllower(s);
537}
538
539/*
540 * iha_find_pend_scb - scan the pending queue for a SCB that can be
541 * processed immediately. Return NULL if none found
542 * and a pointer to the SCB if one is found. If there
543 * is an active SCB, return NULL!
544 */
545struct iha_scb *
546iha_find_pend_scb(struct iha_softc *sc)
547{
548 struct iha_scb *pScb;
549 struct tcs *pTcs;
550 int s;
551
552 s = splbio()splraise(0x6);
553
554 if (sc->HCS_ActScb != NULL((void *)0))
555 pScb = NULL((void *)0);
556
557 else
558 TAILQ_FOREACH(pScb, &sc->HCS_PendScb, SCB_ScbList)for((pScb) = ((&sc->HCS_PendScb)->tqh_first); (pScb
) != ((void *)0); (pScb) = ((pScb)->SCB_ScbList.tqe_next))
{
559 if ((pScb->SCB_Flags & SCSI_RESET0x00200) != 0)
560 /* ALWAYS willing to reset a device */
561 break;
562
563 pTcs = pScb->SCB_Tcs;
564
565 if ((pScb->SCB_TagMsg) != 0) {
566 /*
567 * A Tagged I/O. OK to start If no
568 * non-tagged I/O is active on the same
569 * target
570 */
571 if (pTcs->TCS_NonTagScb == NULL((void *)0))
572 break;
573
574 } else if (pScb->SCB_CDB[0] == REQUEST_SENSE0x03) {
575 /*
576 * OK to do a non-tagged request sense
577 * even if a non-tagged I/O has been
578 * started, because we don't allow any
579 * disconnect during a request sense op
580 */
581 break;
582
583 } else if (pTcs->TCS_TagCnt == 0) {
584 /*
585 * No tagged I/O active on this target,
586 * ok to start a non-tagged one if one
587 * is not already active
588 */
589 if (pTcs->TCS_NonTagScb == NULL((void *)0))
590 break;
591 }
592 }
593
594 splx(s)spllower(s);
595
596 return (pScb);
597}
598
599void
600iha_mark_busy_scb(struct iha_scb *pScb)
601{
602 int s;
603
604 s = splbio()splraise(0x6);
605
606 pScb->SCB_Status = STATUS_BUSY3;
607
608 if (pScb->SCB_TagMsg == 0)
609 pScb->SCB_Tcs->TCS_NonTagScb = pScb;
610 else
611 pScb->SCB_Tcs->TCS_TagCnt++;
612
613 splx(s)spllower(s);
614}
615
616void
617iha_append_done_scb(struct iha_softc *sc, struct iha_scb *pScb, u_int8_t hastat)
618{
619 struct tcs *pTcs;
620 int s;
621
622 s = splbio()splraise(0x6);
623
624 if (pScb->SCB_Xs != NULL((void *)0))
625 timeout_del(&pScb->SCB_Xs->stimeout);
626
627 if (pScb == sc->HCS_ActScb)
628 sc->HCS_ActScb = NULL((void *)0);
629
630 pTcs = pScb->SCB_Tcs;
631
632 if (pScb->SCB_TagMsg != 0) {
633 if (pTcs->TCS_TagCnt)
634 pTcs->TCS_TagCnt--;
635 } else if (pTcs->TCS_NonTagScb == pScb)
636 pTcs->TCS_NonTagScb = NULL((void *)0);
637
638 pScb->SCB_Status = STATUS_QUEUED0;
639 pScb->SCB_HaStat = hastat;
640
641 TAILQ_INSERT_TAIL(&sc->HCS_DoneScb, pScb, SCB_ScbList)do { (pScb)->SCB_ScbList.tqe_next = ((void *)0); (pScb)->
SCB_ScbList.tqe_prev = (&sc->HCS_DoneScb)->tqh_last
; *(&sc->HCS_DoneScb)->tqh_last = (pScb); (&sc->
HCS_DoneScb)->tqh_last = &(pScb)->SCB_ScbList.tqe_next
; } while (0)
;
642
643 splx(s)spllower(s);
644}
645
646struct iha_scb *
647iha_pop_done_scb(struct iha_softc *sc)
648{
649 struct iha_scb *pScb;
650 int s;
651
652 s = splbio()splraise(0x6);
653
654 pScb = TAILQ_FIRST(&sc->HCS_DoneScb)((&sc->HCS_DoneScb)->tqh_first);
655
656 if (pScb != NULL((void *)0)) {
657 pScb->SCB_Status = STATUS_RENT1;
658 TAILQ_REMOVE(&sc->HCS_DoneScb, pScb, SCB_ScbList)do { if (((pScb)->SCB_ScbList.tqe_next) != ((void *)0)) (pScb
)->SCB_ScbList.tqe_next->SCB_ScbList.tqe_prev = (pScb)->
SCB_ScbList.tqe_prev; else (&sc->HCS_DoneScb)->tqh_last
= (pScb)->SCB_ScbList.tqe_prev; *(pScb)->SCB_ScbList.tqe_prev
= (pScb)->SCB_ScbList.tqe_next; ((pScb)->SCB_ScbList.tqe_prev
) = ((void *)-1); ((pScb)->SCB_ScbList.tqe_next) = ((void *
)-1); } while (0)
;
659 }
660
661 splx(s)spllower(s);
662
663 return (pScb);
664}
665
666/*
667 * iha_abort_xs - find the SCB associated with the supplied xs and
668 * stop all processing on it, moving it to the done
669 * queue with the supplied host status value.
670 */
671void
672iha_abort_xs(struct iha_softc *sc, struct scsi_xfer *xs, u_int8_t hastat)
673{
674 struct iha_scb *pScb, *next;
675 int i, s;
676
677 s = splbio()splraise(0x6);
678
679 /* Check the pending queue for the SCB pointing to xs */
680
681 for (pScb = TAILQ_FIRST(&sc->HCS_PendScb)((&sc->HCS_PendScb)->tqh_first); pScb != NULL((void *)0); pScb = next) {
682 next = TAILQ_NEXT(pScb, SCB_ScbList)((pScb)->SCB_ScbList.tqe_next);
683 if (pScb->SCB_Xs == xs) {
684 TAILQ_REMOVE(&sc->HCS_PendScb, pScb, SCB_ScbList)do { if (((pScb)->SCB_ScbList.tqe_next) != ((void *)0)) (pScb
)->SCB_ScbList.tqe_next->SCB_ScbList.tqe_prev = (pScb)->
SCB_ScbList.tqe_prev; else (&sc->HCS_PendScb)->tqh_last
= (pScb)->SCB_ScbList.tqe_prev; *(pScb)->SCB_ScbList.tqe_prev
= (pScb)->SCB_ScbList.tqe_next; ((pScb)->SCB_ScbList.tqe_prev
) = ((void *)-1); ((pScb)->SCB_ScbList.tqe_next) = ((void *
)-1); } while (0)
;
685 iha_append_done_scb(sc, pScb, hastat);
686 splx(s)spllower(s);
687 return;
688 }
689 }
690
691 /*
692 * If that didn't work, check all BUSY/SELECTING SCB's for one
693 * pointing to xs
694 */
695
696 for (i = 0, pScb = sc->HCS_Scb; i < IHA_MAX_SCB32; i++, pScb++)
697 switch (pScb->SCB_Status) {
698 case STATUS_BUSY3:
699 case STATUS_SELECT2:
700 if (pScb->SCB_Xs == xs) {
701 iha_append_done_scb(sc, pScb, hastat);
702 splx(s)spllower(s);
703 return;
704 }
705 break;
706 default:
707 break;
708 }
709
710 splx(s)spllower(s);
711}
712
713/*
714 * iha_bad_seq - a SCSI bus phase was encountered out of the
715 * correct/expected sequence. Reset the SCSI bus.
716 */
717void
718iha_bad_seq(struct iha_softc *sc)
719{
720 struct iha_scb *pScb = sc->HCS_ActScb;
721
722 if (pScb != NULL((void *)0))
723 iha_append_done_scb(sc, pScb, HOST_BAD_PHAS0x14);
724
725 iha_reset_scsi_bus(sc);
726 iha_reset_chip(sc, sc->sc_iot, sc->sc_ioh);
727}
728
729/*
730 * iha_push_sense_request - obtain auto sense data by pushing the
731 * SCB needing it back onto the pending
732 * queue with a REQUEST_SENSE CDB.
733 */
734int
735iha_push_sense_request(struct iha_softc *sc, struct iha_scb *pScb)
736{
737 struct scsi_sense *sensecmd;
738 int error;
739
740 /* First sync & unload any existing DataDma and SGDma maps */
741 if ((pScb->SCB_Flags & (SCSI_DATA_IN0x00800 | SCSI_DATA_OUT0x01000)) != 0) {
742 bus_dmamap_sync(sc->sc_dmat, pScb->SCB_DataDma,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (pScb->
SCB_DataDma), (0), (pScb->SCB_BufChars), (((pScb->SCB_Flags
& 0x00800) ? 0x02 : 0x08)))
743 0, pScb->SCB_BufChars,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (pScb->
SCB_DataDma), (0), (pScb->SCB_BufChars), (((pScb->SCB_Flags
& 0x00800) ? 0x02 : 0x08)))
744 ((pScb->SCB_Flags & SCSI_DATA_IN) ?(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (pScb->
SCB_DataDma), (0), (pScb->SCB_BufChars), (((pScb->SCB_Flags
& 0x00800) ? 0x02 : 0x08)))
745 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE))(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (pScb->
SCB_DataDma), (0), (pScb->SCB_BufChars), (((pScb->SCB_Flags
& 0x00800) ? 0x02 : 0x08)))
;
746 bus_dmamap_unload(sc->sc_dmat, pScb->SCB_DataDma)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (pScb
->SCB_DataDma))
;
747 /* Don't unload this map again until it is reloaded */
748 pScb->SCB_Flags &= ~(SCSI_DATA_IN0x00800 | SCSI_DATA_OUT0x01000);
749 }
750 if ((pScb->SCB_Flags & FLAG_SG0x00020000) != 0) {
751 bus_dmamap_sync(sc->sc_dmat, pScb->SCB_SGDma,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (pScb->
SCB_SGDma), (0), (sizeof(pScb->SCB_SGList)), (0x08))
752 0, sizeof(pScb->SCB_SGList),(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (pScb->
SCB_SGDma), (0), (sizeof(pScb->SCB_SGList)), (0x08))
753 BUS_DMASYNC_POSTWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (pScb->
SCB_SGDma), (0), (sizeof(pScb->SCB_SGList)), (0x08))
;
754 bus_dmamap_unload(sc->sc_dmat, pScb->SCB_SGDma)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (pScb
->SCB_SGDma))
;
755 /* Don't unload this map again until it is reloaded */
756 pScb->SCB_Flags &= ~FLAG_SG0x00020000;
757 }
758
759 pScb->SCB_BufChars = sizeof(pScb->SCB_ScsiSenseData);
760 pScb->SCB_BufCharsLeft = sizeof(pScb->SCB_ScsiSenseData);
761 bzero(&pScb->SCB_ScsiSenseData, sizeof(pScb->SCB_ScsiSenseData))__builtin_bzero((&pScb->SCB_ScsiSenseData), (sizeof(pScb
->SCB_ScsiSenseData)))
;
762
763 error = bus_dmamap_load(sc->sc_dmat, pScb->SCB_DataDma,(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (pScb->
SCB_DataDma), (&pScb->SCB_ScsiSenseData), (sizeof(pScb
->SCB_ScsiSenseData)), (((void *)0)), ((pScb->SCB_Flags
& 0x00001) ? 0x0001 : 0x0000))
764 &pScb->SCB_ScsiSenseData,(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (pScb->
SCB_DataDma), (&pScb->SCB_ScsiSenseData), (sizeof(pScb
->SCB_ScsiSenseData)), (((void *)0)), ((pScb->SCB_Flags
& 0x00001) ? 0x0001 : 0x0000))
765 sizeof(pScb->SCB_ScsiSenseData), NULL,(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (pScb->
SCB_DataDma), (&pScb->SCB_ScsiSenseData), (sizeof(pScb
->SCB_ScsiSenseData)), (((void *)0)), ((pScb->SCB_Flags
& 0x00001) ? 0x0001 : 0x0000))
766 (pScb->SCB_Flags & SCSI_NOSLEEP) ?(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (pScb->
SCB_DataDma), (&pScb->SCB_ScsiSenseData), (sizeof(pScb
->SCB_ScsiSenseData)), (((void *)0)), ((pScb->SCB_Flags
& 0x00001) ? 0x0001 : 0x0000))
767 BUS_DMA_NOWAIT : BUS_DMA_WAITOK)(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (pScb->
SCB_DataDma), (&pScb->SCB_ScsiSenseData), (sizeof(pScb
->SCB_ScsiSenseData)), (((void *)0)), ((pScb->SCB_Flags
& 0x00001) ? 0x0001 : 0x0000))
;
768 if (error) {
769 sc_print_addr(pScb->SCB_Xs->sc_link);
770 printf("error %d loading request sense buffer dma map\n",
771 error);
772 return (error);
773 }
774 bus_dmamap_sync(sc->sc_dmat, pScb->SCB_DataDma,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (pScb->
SCB_DataDma), (0), (pScb->SCB_BufChars), (0x01))
775 0, pScb->SCB_BufChars, BUS_DMASYNC_PREREAD)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (pScb->
SCB_DataDma), (0), (pScb->SCB_BufChars), (0x01))
;
776
777 /* Save _POLL and _NOSLEEP flags. */
778 pScb->SCB_Flags &= SCSI_POLL0x00002 | SCSI_NOSLEEP0x00001;
779 pScb->SCB_Flags |= FLAG_RSENS0x00010000 | SCSI_DATA_IN0x00800;
780
781 error = iha_setup_sg_list(sc, pScb);
782 if (error)
783 return (error);
784
785 pScb->SCB_Ident &= ~MSG_IDENTIFY_DISCFLAG0x40;
786
787 pScb->SCB_TagMsg = 0;
788 pScb->SCB_TaStat = SCSI_OK0x00;
789
790 bzero(pScb->SCB_CDB, sizeof(pScb->SCB_CDB))__builtin_bzero((pScb->SCB_CDB), (sizeof(pScb->SCB_CDB)
))
;
791
792 sensecmd = (struct scsi_sense *)pScb->SCB_CDB;
793 pScb->SCB_CDBLen = sizeof(*sensecmd);
794 sensecmd->opcode = REQUEST_SENSE0x03;
795 sensecmd->byte2 = pScb->SCB_Xs->sc_link->lun << 5;
796 sensecmd->length = sizeof(pScb->SCB_ScsiSenseData);
797
798 if ((pScb->SCB_Flags & SCSI_POLL0x00002) == 0)
799 timeout_add_msec(&pScb->SCB_Xs->stimeout,
800 pScb->SCB_Xs->timeout);
801
802 iha_push_pend_scb(sc, pScb);
803
804 return (0);
805}
806
807/*
808 * iha_main - process the active SCB, taking one off pending and making it
809 * active if necessary, and any done SCB's created as
810 * a result until there are no interrupts pending and no pending
811 * SCB's that can be started.
812 */
813void
814iha_main(struct iha_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh)
815{
816 struct iha_scb *pScb;
817
818 for (;;) {
819iha_scsi_label:
820 iha_scsi(sc, iot, ioh);
821
822 while ((pScb = iha_pop_done_scb(sc)) != NULL((void *)0)) {
823
824 switch (pScb->SCB_TaStat) {
825 case SCSI_TERMINATED0x22:
826 case SCSI_ACA_ACTIVE0x30:
827 case SCSI_CHECK0x02:
828 pScb->SCB_Tcs->TCS_Flags &=
829 ~(FLAG_SYNC_DONE0x0200 | FLAG_WIDE_DONE0x0100);
830
831 if ((pScb->SCB_Flags & FLAG_RSENS0x00010000) != 0)
832 /* Check condition on check condition*/
833 pScb->SCB_HaStat = HOST_BAD_PHAS0x14;
834 else if (iha_push_sense_request(sc, pScb) != 0)
835 /* Could not push sense request */
836 pScb->SCB_HaStat = HOST_BAD_PHAS0x14;
837 else
838 /* REQUEST SENSE ready to process */
839 goto iha_scsi_label;
840 break;
841
842 default:
843 if ((pScb->SCB_Flags & FLAG_RSENS0x00010000) != 0)
844 /*
845 * Return the original SCSI_CHECK, not
846 * the status of the request sense
847 * command!
848 */
849 pScb->SCB_TaStat = SCSI_CHECK0x02;
850 break;
851 }
852
853 iha_done_scb(sc, pScb);
854 }
855
856 /*
857 * If there are no interrupts pending, or we can't start
858 * a pending sc, break out of the for(;;). Otherwise
859 * continue the good work with another call to
860 * iha_scsi().
861 */
862 if (((bus_space_read_1(iot, ioh, TUL_STAT0)((iot)->read_1((ioh), (0x85))) & INTPD0x80) == 0)
863 && (iha_find_pend_scb(sc) == NULL((void *)0)))
864 break;
865 }
866}
867
868/*
869 * iha_scsi - service any outstanding interrupts. If there are none, try to
870 * start another SCB currently in the pending queue.
871 */
872void
873iha_scsi(struct iha_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh)
874{
875 struct iha_scb *pScb;
876 struct tcs *pTcs;
877 u_int8_t stat;
878 int i;
879
880 /* service pending interrupts asap */
881
882 stat = bus_space_read_1(iot, ioh, TUL_STAT0)((iot)->read_1((ioh), (0x85)));
883 if ((stat & INTPD0x80) != 0) {
884 sc->HCS_JSStatus0 = stat;
885 sc->HCS_JSStatus1 = bus_space_read_1(iot, ioh, TUL_STAT1)((iot)->read_1((ioh), (0x86)));
886 sc->HCS_JSInt = bus_space_read_1(iot, ioh, TUL_SISTAT)((iot)->read_1((ioh), (0x84)));
887
888 sc->HCS_Phase = sc->HCS_JSStatus0 & PH_MASK0x07;
889
890 if ((sc->HCS_JSInt & SRSTD0x10) != 0) {
891 iha_reset_scsi_bus(sc);
892 return;
893 }
894
895 if ((sc->HCS_JSInt & RSELED0x80) != 0) {
896 iha_resel(sc, iot, ioh);
897 return;
898 }
899
900 if ((sc->HCS_JSInt & (STIMEO0x40 | DISCD0x08)) != 0) {
901 iha_busfree(sc, iot, ioh);
902 return;
903 }
904
905 if ((sc->HCS_JSInt & (SCMDN0x01 | SBSRV0x20)) != 0) {
906 iha_next_state(sc, iot, ioh);
907 return;
908 }
909
910 if ((sc->HCS_JSInt & SELED0x04) != 0)
911 iha_set_ssig(iot, ioh, 0, 0);
912 }
913
914 /*
915 * There were no interrupts pending which required action elsewhere, so
916 * see if it is possible to start the selection phase on a pending SCB
917 */
918 if ((pScb = iha_find_pend_scb(sc)) == NULL((void *)0))
919 return;
920
921 pTcs = pScb->SCB_Tcs;
922
923 /* program HBA's SCSI ID & target SCSI ID */
924 bus_space_write_1(iot, ioh, TUL_SID,((iot)->write_1((ioh), (0x89), ((sc->sc_id << 4) |
pScb->SCB_Target)))
925 (sc->sc_id << 4) | pScb->SCB_Target)((iot)->write_1((ioh), (0x89), ((sc->sc_id << 4) |
pScb->SCB_Target)))
;
926
927 if ((pScb->SCB_Flags & SCSI_RESET0x00200) == 0) {
928 bus_space_write_1(iot, ioh, TUL_SYNCM, pTcs->TCS_JS_Period)((iot)->write_1((ioh), (0x88), (pTcs->TCS_JS_Period)));
929
930 if (((pTcs->TCS_Flags & FLAG_NO_NEG_WIDE(0x0020 | 0x0100)) == 0)
931 ||
932 ((pTcs->TCS_Flags & FLAG_NO_NEG_SYNC(0x0010 | 0x0200)) == 0))
933 iha_select(sc, iot, ioh, pScb, SELATNSTOP0x1E);
934
935 else if (pScb->SCB_TagMsg != 0)
936 iha_select(sc, iot, ioh, pScb, SEL_ATN30x31);
937
938 else
939 iha_select(sc, iot, ioh, pScb, SEL_ATN0x11);
940
941 } else {
942 iha_select(sc, iot, ioh, pScb, SELATNSTOP0x1E);
943 pScb->SCB_NxtStat = 8;
944 }
945
946 if ((pScb->SCB_Flags & SCSI_POLL0x00002) != 0) {
947 for (i = pScb->SCB_Xs->timeout; i > 0; i--) {
948 if (iha_wait(sc, iot, ioh, NO_OP0x00) == -1)
949 break;
950 if (iha_next_state(sc, iot, ioh) == -1)
951 break;
952 delay(1000)(*delay_func)(1000); /* Only happens in boot, so it's ok */
953 }
954
955 /*
956 * Since done queue processing not done until AFTER this
957 * function returns, pScb is on the done queue, not
958 * the free queue at this point and still has valid data
959 *
960 * Conversely, xs->error has not been set yet
961 */
962 if (i == 0)
963 iha_timeout(pScb);
964
965 else if ((pScb->SCB_CDB[0] == INQUIRY0x12)
966 && (pScb->SCB_Lun == 0)
967 && (pScb->SCB_HaStat == HOST_OK0x00)
968 && (pScb->SCB_TaStat == SCSI_OK0x00))
969 iha_print_info(sc, pScb->SCB_Target);
970 }
971}
972
973/*
974 * iha_data_over_run - return HOST_OK for all SCSI opcodes where BufCharsLeft
975 * is an 'Allocation Length'. All other SCSI opcodes
976 * get HOST_DO_DU as they SHOULD have xferred all the
977 * data requested.
978 *
979 * The list of opcodes using 'Allocation Length' was
980 * found by scanning all the SCSI-3 T10 drafts. See
981 * www.t10.org for the curious with a .pdf reader.
982 */
983u_int8_t
984iha_data_over_run(struct iha_scb *pScb)
985{
986 switch (pScb->SCB_CDB[0]) {
987 case 0x03: /* Request Sense SPC-2 */
988 case 0x12: /* Inquiry SPC-2 */
989 case 0x1a: /* Mode Sense (6 byte version) SPC-2 */
990 case 0x1c: /* Receive Diagnostic Results SPC-2 */
991 case 0x23: /* Read Format Capacities MMC-2 */
992 case 0x29: /* Read Generation SBC */
993 case 0x34: /* Read Position SSC-2 */
994 case 0x37: /* Read Defect Data SBC */
995 case 0x3c: /* Read Buffer SPC-2 */
996 case 0x42: /* Read Sub Channel MMC-2 */
997 case 0x43: /* Read TOC/PMA/ATIP MMC */
998
999 /* XXX - 2 with same opcode of 0x44? */
1000 case 0x44: /* Read Header/Read Density Suprt MMC/SSC*/
1001
1002 case 0x46: /* Get Configuration MMC-2 */
1003 case 0x4a: /* Get Event/Status Notification MMC-2 */
1004 case 0x4d: /* Log Sense SPC-2 */
1005 case 0x51: /* Read Disc Information MMC */
1006 case 0x52: /* Read Track Information MMC */
1007 case 0x59: /* Read Master CUE MMC */
1008 case 0x5a: /* Mode Sense (10 byte version) SPC-2 */
1009 case 0x5c: /* Read Buffer Capacity MMC */
1010 case 0x5e: /* Persistent Reserve In SPC-2 */
1011 case 0x84: /* Receive Copy Results SPC-2 */
1012 case 0xa0: /* Report LUNs SPC-2 */
1013 case 0xa3: /* Various Report requests SBC-2/SCC-2*/
1014 case 0xa4: /* Report Key MMC-2 */
1015 case 0xad: /* Read DVD Structure MMC-2 */
1016 case 0xb4: /* Read Element Status (Attached) SMC */
1017 case 0xb5: /* Request Volume Element Address SMC */
1018 case 0xb7: /* Read Defect Data (12 byte ver.) SBC */
1019 case 0xb8: /* Read Element Status (Independ.) SMC */
1020 case 0xba: /* Report Redundancy SCC-2 */
1021 case 0xbd: /* Mechanism Status MMC */
1022 case 0xbe: /* Report Basic Redundancy SCC-2 */
1023
1024 return (HOST_OK0x00);
1025 break;
1026
1027 default:
1028 return (HOST_DO_DU0x12);
1029 break;
1030 }
1031}
1032
1033/*
1034 * iha_next_state - process the current SCB as requested in its
1035 * SCB_NxtStat member.
1036 */
1037int
1038iha_next_state(struct iha_softc *sc, bus_space_tag_t iot,
1039 bus_space_handle_t ioh)
1040{
1041 if (sc->HCS_ActScb == NULL((void *)0))
1042 return (-1);
1043
1044 switch (sc->HCS_ActScb->SCB_NxtStat) {
1045 case 1:
1046 if (iha_state_1(sc, iot, ioh) == 3)
1047 goto state_3;
1048 break;
1049
1050 case 2:
1051 switch (iha_state_2(sc, iot, ioh)) {
1052 case 3: goto state_3;
1053 case 4: goto state_4;
1054 default: break;
1055 }
1056 break;
1057
1058 case 3:
1059 state_3:
1060 if (iha_state_3(sc, iot, ioh) == 4)
1061 goto state_4;
1062 break;
1063
1064 case 4:
1065 state_4:
1066 switch (iha_state_4(sc, iot, ioh)) {
1067 case 0: return (0);
1068 case 6: goto state_6;
1069 default: break;
1070 }
1071 break;
1072
1073 case 5:
1074 switch (iha_state_5(sc, iot, ioh)) {
1075 case 4: goto state_4;
1076 case 6: goto state_6;
1077 default: break;
1078 }
1079 break;
1080
1081 case 6:
1082 state_6:
1083 iha_state_6(sc, iot, ioh);
1084 break;
1085
1086 case 8:
1087 iha_state_8(sc, iot, ioh);
1088 break;
1089
1090 default:
1091#ifdef IHA_DEBUG_STATE
1092 sc_print_addr(sc->HCS_ActScb->SCB_Xs->sc_link);
1093 printf("[debug] -unknown state: %i-\n",
1094 sc->HCS_ActScb->SCB_NxtStat);
1095#endif
1096 iha_bad_seq(sc);
1097 break;
1098 }
1099
1100 return (-1);
1101}
1102
1103/*
1104 * iha_state_1 - selection is complete after a SELATNSTOP. If the target
1105 * has put the bus into MSG_OUT phase start wide/sync
1106 * negotiation. Otherwise clear the FIFO and go to state 3,
1107 * which will send the SCSI CDB to the target.
1108 */
1109int
1110iha_state_1(struct iha_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh)
1111{
1112 struct iha_scb *pScb = sc->HCS_ActScb;
1113 struct tcs *pTcs;
1114 u_int16_t flags;
1115
1116 iha_mark_busy_scb(pScb);
1117
1118 pTcs = pScb->SCB_Tcs;
1119
1120 bus_space_write_1(iot, ioh, TUL_SCONFIG0, pTcs->TCS_SConfig0)((iot)->write_1((ioh), (0x87), (pTcs->TCS_SConfig0)));
1121
1122 /*
1123 * If we are in PHASE_MSG_OUT, send
1124 * a) IDENT message (with tags if appropriate)
1125 * b) WDTR if the target is configured to negotiate wide xfers
1126 * ** OR **
1127 * c) SDTR if the target is configured to negotiate sync xfers
1128 * but not wide ones
1129 *
1130 * If we are NOT, then the target is not asking for anything but
1131 * the data/command, so go straight to state 3.
1132 */
1133 if (sc->HCS_Phase == PHASE_MSG_OUT0x06) {
1134 bus_space_write_1(iot, ioh, TUL_SCTRL1, (ESBUSIN | EHRSL))((iot)->write_1((ioh), (0x86), ((0x01 | 0x04))));
1135 bus_space_write_1(iot, ioh, TUL_SFIFO, pScb->SCB_Ident)((iot)->write_1((ioh), (0x8C), (pScb->SCB_Ident)));
1136
1137 if (pScb->SCB_TagMsg != 0) {
1138 bus_space_write_1(iot, ioh, TUL_SFIFO,((iot)->write_1((ioh), (0x8C), (pScb->SCB_TagMsg)))
1139 pScb->SCB_TagMsg)((iot)->write_1((ioh), (0x8C), (pScb->SCB_TagMsg)));
1140 bus_space_write_1(iot, ioh, TUL_SFIFO,((iot)->write_1((ioh), (0x8C), (pScb->SCB_TagId)))
1141 pScb->SCB_TagId)((iot)->write_1((ioh), (0x8C), (pScb->SCB_TagId)));
1142 }
1143
1144 flags = pTcs->TCS_Flags;
1145 if ((flags & FLAG_NO_NEG_WIDE(0x0020 | 0x0100)) == 0) {
1146 if (iha_msgout_wdtr(sc, iot, ioh) == -1)
1147 return (-1);
1148 } else if ((flags & FLAG_NO_NEG_SYNC(0x0010 | 0x0200)) == 0) {
1149 if (iha_msgout_sdtr(sc, iot, ioh) == -1)
1150 return (-1);
1151 }
1152
1153 } else {
1154 bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO)((iot)->write_1((ioh), (0x85), (0x10)));
1155 iha_set_ssig(iot, ioh, REQ0x80 | BSY0x20 | SEL0x10 | ATN0x08, 0);
1156 }
1157
1158 return (3);
1159}
1160
1161/*
1162 * iha_state_2 - selection is complete after a SEL_ATN or SEL_ATN3. If the SCSI
1163 * CDB has already been send, go to state 4 to start the data
1164 * xfer. Otherwise reset the FIFO and go to state 3, sending
1165 * the SCSI CDB.
1166 */
1167int
1168iha_state_2(struct iha_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh)
1169{
1170 struct iha_scb *pScb = sc->HCS_ActScb;
1171
1172 iha_mark_busy_scb(pScb);
1173
1174 bus_space_write_1(iot, ioh, TUL_SCONFIG0, pScb->SCB_Tcs->TCS_SConfig0)((iot)->write_1((ioh), (0x87), (pScb->SCB_Tcs->TCS_SConfig0
)))
;
1175
1176 if ((sc->HCS_JSStatus1 & CPDNE0x20) != 0)
1177 return (4);
1178
1179 bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO)((iot)->write_1((ioh), (0x85), (0x10)));
1180
1181 iha_set_ssig(iot, ioh, REQ0x80 | BSY0x20 | SEL0x10 | ATN0x08, 0);
1182
1183 return (3);
1184}
1185
1186/*
1187 * iha_state_3 - send the SCSI CDB to the target, processing any status
1188 * or other messages received until that is done or
1189 * abandoned.
1190 */
1191int
1192iha_state_3(struct iha_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh)
1193{
1194 struct iha_scb *pScb = sc->HCS_ActScb;
1195 u_int16_t flags;
1196
1197 for (;;)
1198 switch (sc->HCS_Phase) {
1199 case PHASE_CMD_OUT0x02:
1200 bus_space_write_multi_1(iot, ioh, TUL_SFIFO,((iot)->write_multi_1((ioh), (0x8C), (pScb->SCB_CDB), (
pScb->SCB_CDBLen)))
1201 pScb->SCB_CDB, pScb->SCB_CDBLen)((iot)->write_multi_1((ioh), (0x8C), (pScb->SCB_CDB), (
pScb->SCB_CDBLen)))
;
1202 if (iha_wait(sc, iot, ioh, XF_FIFO_OUT0x03) == -1)
1203 return (-1);
1204 else if (sc->HCS_Phase == PHASE_CMD_OUT0x02) {
1205 iha_bad_seq(sc);
1206 return (-1);
1207 } else
1208 return (4);
1209
1210 case PHASE_MSG_IN0x07:
1211 pScb->SCB_NxtStat = 3;
1212 if (iha_msgin(sc, iot, ioh) == -1)
1213 return (-1);
1214 break;
1215
1216 case PHASE_STATUS_IN0x03:
1217 if (iha_status_msg(sc, iot, ioh) == -1)
1218 return (-1);
1219 break;
1220
1221 case PHASE_MSG_OUT0x06:
1222 flags = pScb->SCB_Tcs->TCS_Flags;
1223 if ((flags & FLAG_NO_NEG_SYNC(0x0010 | 0x0200)) != 0) {
1224 if (iha_msgout(sc, iot, ioh, MSG_NOOP0x08) == -1)
1225 return (-1);
1226 } else if (iha_msgout_sdtr(sc, iot, ioh) == -1)
1227 return (-1);
1228 break;
1229
1230 default:
1231#ifdef IHA_DEBUG_STATE
1232 sc_print_addr(pScb->SCB_Xs->sc_link);
1233 printf("[debug] -s3- bad phase = %d\n", sc->HCS_Phase);
1234#endif
1235 iha_bad_seq(sc);
1236 return (-1);
1237 }
1238}
1239
1240/*
1241 * iha_state_4 - start a data xfer. Handle any bus state
1242 * transitions until PHASE_DATA_IN/_OUT
1243 * or the attempt is abandoned. If there is
1244 * no data to xfer, go to state 6 and finish
1245 * processing the current SCB.
1246 */
1247int
1248iha_state_4(struct iha_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh)
1249{
1250 struct iha_scb *pScb = sc->HCS_ActScb;
1251
1252 if ((pScb->SCB_Flags & FLAG_DIR(0x00800 | 0x01000)) == FLAG_DIR(0x00800 | 0x01000))
1253 return (6); /* Both dir flags set => NO xfer was requested */
1254
1255 for (;;) {
1256 if (pScb->SCB_BufCharsLeft == 0)
1257 return (6);
1258
1259 switch (sc->HCS_Phase) {
1260 case PHASE_STATUS_IN0x03:
1261 if ((pScb->SCB_Flags & FLAG_DIR(0x00800 | 0x01000)) != 0)
1262 pScb->SCB_HaStat = iha_data_over_run(pScb);
1263 if ((iha_status_msg(sc, iot, ioh)) == -1)
1264 return (-1);
1265 break;
1266
1267 case PHASE_MSG_IN0x07:
1268 pScb->SCB_NxtStat = 4;
1269 if (iha_msgin(sc, iot, ioh) == -1)
1270 return (-1);
1271 break;
1272
1273 case PHASE_MSG_OUT0x06:
1274 if ((sc->HCS_JSStatus0 & SPERR0x08) != 0) {
1275 pScb->SCB_BufCharsLeft = 0;
1276 pScb->SCB_HaStat = HOST_SPERR0x10;
1277 if (iha_msgout(sc, iot, ioh,
1278 MSG_INITIATOR_DET_ERR0x05) == -1)
1279 return (-1);
1280 else
1281 return (6);
1282 } else {
1283 if (iha_msgout(sc, iot, ioh, MSG_NOOP0x08) == -1)
1284 return (-1);
1285 }
1286 break;
1287
1288 case PHASE_DATA_IN0x01:
1289 return (iha_xfer_data(pScb, iot, ioh, SCSI_DATA_IN0x00800));
1290
1291 case PHASE_DATA_OUT0x00:
1292 return (iha_xfer_data(pScb, iot, ioh, SCSI_DATA_OUT0x01000));
1293
1294 default:
1295 iha_bad_seq(sc);
1296 return (-1);
1297 }
1298 }
1299}
1300
1301/*
1302 * iha_state_5 - handle the partial or final completion of the current
1303 * data xfer. If DMA is still active stop it. If there is
1304 * more data to xfer, go to state 4 and start the xfer.
1305 * If not go to state 6 and finish the SCB.
1306 */
1307int
1308iha_state_5(struct iha_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh)
1309{
1310 struct iha_scb *pScb = sc->HCS_ActScb;
1311 struct iha_sg_element *pSg;
1312 u_int32_t cnt;
1313 u_int16_t period;
1314 u_int8_t stat;
1315 long xcnt; /* cannot use unsigned!! see code: if (xcnt < 0) */
1316
1317 cnt = bus_space_read_4(iot, ioh, TUL_STCNT0)((iot)->read_4((ioh), (0x80))) & TCNT0x00ffffff;
1318
1319 /*
1320 * Stop any pending DMA activity and check for parity error.
1321 */
1322
1323 if ((bus_space_read_1(iot, ioh, TUL_DCMD)((iot)->read_1((ioh), (0xD8))) & XDIR0x20) != 0) {
1324 /* Input Operation */
1325 if ((sc->HCS_JSStatus0 & SPERR0x08) != 0)
1326 pScb->SCB_HaStat = HOST_SPERR0x10;
1327
1328 if ((bus_space_read_1(iot, ioh, TUL_ISTUS1)((iot)->read_1((ioh), (0xDD))) & XPEND0x01) != 0) {
1329 bus_space_write_1(iot, ioh, TUL_DCTRL0,((iot)->write_1((ioh), (0xE4), (((iot)->read_1((ioh), (
0xE4))) | 0x80)))
1330 bus_space_read_1(iot, ioh, TUL_DCTRL0) | SXSTP)((iot)->write_1((ioh), (0xE4), (((iot)->read_1((ioh), (
0xE4))) | 0x80)))
;
1331 while (bus_space_read_1(iot, ioh, TUL_ISTUS1)((iot)->read_1((ioh), (0xDD))) & XPEND0x01)
1332 ;
1333 }
1334
1335 } else {
1336 /* Output Operation */
1337 if ((sc->HCS_JSStatus1 & SXCMP0x04) == 0) {
1338 period = pScb->SCB_Tcs->TCS_JS_Period;
1339 if ((period & PERIOD_WIDE_SCSI0x80) != 0)
1340 cnt += (bus_space_read_1(iot, ioh,((iot)->read_1((ioh), (0x83)))
1341 TUL_SFIFOCNT)((iot)->read_1((ioh), (0x83))) & FIFOC0x1f) << 1;
1342 else
1343 cnt += (bus_space_read_1(iot, ioh,((iot)->read_1((ioh), (0x83)))
1344 TUL_SFIFOCNT)((iot)->read_1((ioh), (0x83))) & FIFOC0x1f);
1345 }
1346
1347 if ((bus_space_read_1(iot, ioh, TUL_ISTUS1)((iot)->read_1((ioh), (0xDD))) & XPEND0x01) != 0) {
1348 bus_space_write_1(iot, ioh, TUL_DCMD, ABTXFR)((iot)->write_1((ioh), (0xD8), (0x04)));
1349 do
1350 stat = bus_space_read_1(iot, ioh, TUL_ISTUS0)((iot)->read_1((ioh), (0xDC)));
1351 while ((stat & DABT0x04) == 0);
1352 }
1353
1354 if ((cnt == 1) && (sc->HCS_Phase == PHASE_DATA_OUT0x00)) {
1355 if (iha_wait(sc, iot, ioh, XF_FIFO_OUT0x03) == -1)
1356 return (-1);
1357 cnt = 0;
1358
1359 } else if ((sc->HCS_JSStatus1 & SXCMP0x04) == 0)
1360 bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO)((iot)->write_1((ioh), (0x85), (0x10)));
1361 }
1362
1363 if (cnt == 0) {
1364 pScb->SCB_BufCharsLeft = 0;
1365 return (6);
1366 }
1367
1368 /* Update active data pointer and restart the I/O at the new point */
1369
1370 xcnt = pScb->SCB_BufCharsLeft - cnt; /* xcnt == bytes xferred */
1371 pScb->SCB_BufCharsLeft = cnt; /* cnt == bytes left */
1372
1373 bus_dmamap_sync(sc->sc_dmat, pScb->SCB_SGDma,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (pScb->
SCB_SGDma), (0), (sizeof(pScb->SCB_SGList)), (0x08))
1374 0, sizeof(pScb->SCB_SGList), BUS_DMASYNC_POSTWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (pScb->
SCB_SGDma), (0), (sizeof(pScb->SCB_SGList)), (0x08))
;
1375
1376 if ((pScb->SCB_Flags & FLAG_SG0x00020000) != 0) {
1377 pSg = &pScb->SCB_SGList[pScb->SCB_SGIdx];
1378 for (; pScb->SCB_SGIdx < pScb->SCB_SGCount; pSg++, pScb->SCB_SGIdx++) {
1379 xcnt -= pSg->SG_Len;
1380 if (xcnt < 0) {
1381 xcnt += pSg->SG_Len;
1382
1383 pSg->SG_Addr += xcnt;
1384 pSg->SG_Len -= xcnt;
1385
1386 bus_dmamap_sync(sc->sc_dmat, pScb->SCB_SGDma,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (pScb->
SCB_SGDma), (0), (sizeof(pScb->SCB_SGList)), (0x04))
1387 0, sizeof(pScb->SCB_SGList),(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (pScb->
SCB_SGDma), (0), (sizeof(pScb->SCB_SGList)), (0x04))
1388 BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (pScb->
SCB_SGDma), (0), (sizeof(pScb->SCB_SGList)), (0x04))
;
1389
1390 return (4);
1391 }
1392 }
1393 return (6);
1394
1395 }
1396
1397 return (4);
1398}
1399
1400/*
1401 * iha_state_6 - finish off the active scb (may require several
1402 * iterations if PHASE_MSG_IN) and return -1 to indicate
1403 * the bus is free.
1404 */
1405int
1406iha_state_6(struct iha_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh)
1407{
1408 for (;;)
1409 switch (sc->HCS_Phase) {
1410 case PHASE_STATUS_IN0x03:
1411 if (iha_status_msg(sc, iot, ioh) == -1)
1412 return (-1);
1413 break;
1414
1415 case PHASE_MSG_IN0x07:
1416 sc->HCS_ActScb->SCB_NxtStat = 6;
1417 if ((iha_msgin(sc, iot, ioh)) == -1)
1418 return (-1);
1419 break;
1420
1421 case PHASE_MSG_OUT0x06:
1422 if ((iha_msgout(sc, iot, ioh, MSG_NOOP0x08)) == -1)
1423 return (-1);
1424 break;
1425
1426 case PHASE_DATA_IN0x01:
1427 if (iha_xpad_in(sc, iot, ioh) == -1)
1428 return (-1);
1429 break;
1430
1431 case PHASE_DATA_OUT0x00:
1432 if (iha_xpad_out(sc, iot, ioh) == -1)
1433 return (-1);
1434 break;
1435
1436 default:
1437 iha_bad_seq(sc);
1438 return (-1);
1439 }
1440}
1441
1442/*
1443 * iha_state_8 - reset the active device and all busy SCBs using it
1444 */
1445int
1446iha_state_8(struct iha_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh)
1447{
1448 struct iha_scb *pScb;
1449 u_int32_t i;
1450 u_int8_t tar;
1451
1452 if (sc->HCS_Phase == PHASE_MSG_OUT0x06) {
1453 bus_space_write_1(iot, ioh, TUL_SFIFO, MSG_BUS_DEV_RESET)((iot)->write_1((ioh), (0x8C), (0x0c)));
1454
1455 pScb = sc->HCS_ActScb;
1456
1457 /* This SCB finished correctly -- resetting the device */
1458 iha_append_done_scb(sc, pScb, HOST_OK0x00);
1459
1460 iha_reset_tcs(pScb->SCB_Tcs, sc->HCS_SConf1);
1461
1462 tar = pScb->SCB_Target;
1463 for (i = 0, pScb = sc->HCS_Scb; i < IHA_MAX_SCB32; i++, pScb++)
1464 if (pScb->SCB_Target == tar)
1465 switch (pScb->SCB_Status) {
1466 case STATUS_BUSY3:
1467 iha_append_done_scb(sc,
1468 pScb, HOST_DEV_RST0x1C);
1469 break;
1470
1471 case STATUS_SELECT2:
1472 iha_push_pend_scb(sc, pScb);
1473 break;
1474
1475 default:
1476 break;
1477 }
1478
1479 sc->HCS_Flags |= FLAG_EXPECT_DISC0x01;
1480
1481 if (iha_wait(sc, iot, ioh, XF_FIFO_OUT0x03) == -1)
1482 return (-1);
1483 }
1484
1485 iha_bad_seq(sc);
1486 return (-1);
1487}
1488
1489/*
1490 * iha_xfer_data - initiate the DMA xfer of the data
1491 */
1492int
1493iha_xfer_data(struct iha_scb *pScb, bus_space_tag_t iot, bus_space_handle_t ioh,
1494 int direction)
1495{
1496 u_int32_t xferaddr, xferlen;
1497 u_int8_t xfertype;
1498
1499 if ((pScb->SCB_Flags & FLAG_DIR(0x00800 | 0x01000)) != direction)
1500 return (6); /* wrong direction, abandon I/O */
1501
1502 bus_space_write_4(iot, ioh, TUL_STCNT0, pScb->SCB_BufCharsLeft)((iot)->write_4((ioh), (0x80), (pScb->SCB_BufCharsLeft)
))
;
1503
1504 if ((pScb->SCB_Flags & FLAG_SG0x00020000) == 0) {
1505 xferaddr = pScb->SCB_DataDma->dm_segs[0].ds_addr
1506 + (pScb->SCB_BufChars - pScb->SCB_BufCharsLeft);
1507 xferlen = pScb->SCB_BufCharsLeft;
1508 xfertype = (direction == SCSI_DATA_IN0x00800) ? ST_X_IN(0x20 | 0x01) : ST_X_OUT( 0x01);
1509
1510 } else {
1511 xferaddr = pScb->SCB_SGDma->dm_segs[0].ds_addr
1512 + (pScb->SCB_SGIdx * sizeof(struct iha_sg_element));
1513 xferlen = (pScb->SCB_SGCount - pScb->SCB_SGIdx)
1514 * sizeof(struct iha_sg_element);
1515 xfertype = (direction == SCSI_DATA_IN0x00800) ? ST_SG_IN(0x80 | (0x20 | 0x01)) : ST_SG_OUT(0x80 | ( 0x01));
1516 }
1517
1518 bus_space_write_4(iot, ioh, TUL_DXC, xferlen)((iot)->write_4((ioh), (0xD0), (xferlen)));
1519 bus_space_write_4(iot, ioh, TUL_DXPA, xferaddr)((iot)->write_4((ioh), (0xC0), (xferaddr)));
1520 bus_space_write_1(iot, ioh, TUL_DCMD, xfertype)((iot)->write_1((ioh), (0xD8), (xfertype)));
1521
1522 bus_space_write_1(iot, ioh, TUL_SCMD,((iot)->write_1((ioh), (0x91), ((direction == 0x00800) ? 0xC3
: 0x43)))
1523 (direction == SCSI_DATA_IN) ? XF_DMA_IN : XF_DMA_OUT)((iot)->write_1((ioh), (0x91), ((direction == 0x00800) ? 0xC3
: 0x43)))
;
1524
1525 pScb->SCB_NxtStat = 5;
1526
1527 return (0);
1528}
1529
1530int
1531iha_xpad_in(struct iha_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh)
1532{
1533 struct iha_scb *pScb = sc->HCS_ActScb;
1534
1535 if ((pScb->SCB_Flags & FLAG_DIR(0x00800 | 0x01000)) != 0)
1536 pScb->SCB_HaStat = HOST_DO_DU0x12;
1537
1538 for (;;) {
1539 if ((pScb->SCB_Tcs->TCS_JS_Period & PERIOD_WIDE_SCSI0x80) != 0)
1540 bus_space_write_4(iot, ioh, TUL_STCNT0, 2)((iot)->write_4((ioh), (0x80), (2)));
1541 else
1542 bus_space_write_4(iot, ioh, TUL_STCNT0, 1)((iot)->write_4((ioh), (0x80), (1)));
1543
1544 switch (iha_wait(sc, iot, ioh, XF_FIFO_IN0x83)) {
1545 case -1:
1546 return (-1);
1547
1548 case PHASE_DATA_IN0x01:
1549 bus_space_read_1(iot, ioh, TUL_SFIFO)((iot)->read_1((ioh), (0x8C)));
1550 break;
1551
1552 default:
1553 bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO)((iot)->write_1((ioh), (0x85), (0x10)));
1554 return (6);
1555 }
1556 }
1557}
1558
1559int
1560iha_xpad_out(struct iha_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh)
1561{
1562 struct iha_scb *pScb = sc->HCS_ActScb;
1563
1564 if ((pScb->SCB_Flags & FLAG_DIR(0x00800 | 0x01000)) != 0)
1565 pScb->SCB_HaStat = HOST_DO_DU0x12;
1566
1567 for (;;) {
1568 if ((pScb->SCB_Tcs->TCS_JS_Period & PERIOD_WIDE_SCSI0x80) != 0)
1569 bus_space_write_4(iot, ioh, TUL_STCNT0, 2)((iot)->write_4((ioh), (0x80), (2)));
1570 else
1571 bus_space_write_4(iot, ioh, TUL_STCNT0, 1)((iot)->write_4((ioh), (0x80), (1)));
1572
1573 bus_space_write_1(iot, ioh, TUL_SFIFO, 0)((iot)->write_1((ioh), (0x8C), (0)));
1574
1575 switch (iha_wait(sc, iot, ioh, XF_FIFO_OUT0x03)) {
1576 case -1:
1577 return (-1);
1578
1579 case PHASE_DATA_OUT0x00:
1580 break;
1581
1582 default:
1583 /* Disable wide CPU to allow read 16 bits */
1584 bus_space_write_1(iot, ioh, TUL_SCTRL1, EHRSL)((iot)->write_1((ioh), (0x86), (0x04)));
1585 bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO)((iot)->write_1((ioh), (0x85), (0x10)));
1586 return (6);
1587 }
1588 }
1589}
1590
1591int
1592iha_status_msg(struct iha_softc *sc, bus_space_tag_t iot,
1593 bus_space_handle_t ioh)
1594{
1595 struct iha_scb *pScb;
1596 u_int8_t msg;
1597 int phase;
1598
1599 if ((phase = iha_wait(sc, iot, ioh, CMD_COMP0x84)) == -1)
1600 return (-1);
1601
1602 pScb = sc->HCS_ActScb;
1603
1604 pScb->SCB_TaStat = bus_space_read_1(iot, ioh, TUL_SFIFO)((iot)->read_1((ioh), (0x8C)));
1605
1606 if (phase == PHASE_MSG_OUT0x06) {
1607 if ((sc->HCS_JSStatus0 & SPERR0x08) == 0)
1608 bus_space_write_1(iot, ioh, TUL_SFIFO,((iot)->write_1((ioh), (0x8C), (0x08)))
1609 MSG_NOOP)((iot)->write_1((ioh), (0x8C), (0x08)));
1610 else
1611 bus_space_write_1(iot, ioh, TUL_SFIFO,((iot)->write_1((ioh), (0x8C), (0x09)))
1612 MSG_PARITY_ERROR)((iot)->write_1((ioh), (0x8C), (0x09)));
1613
1614 return (iha_wait(sc, iot, ioh, XF_FIFO_OUT0x03));
1615
1616 } else if (phase == PHASE_MSG_IN0x07) {
1617 msg = bus_space_read_1(iot, ioh, TUL_SFIFO)((iot)->read_1((ioh), (0x8C)));
1618
1619 if ((sc->HCS_JSStatus0 & SPERR0x08) != 0)
1620 switch (iha_wait(sc, iot, ioh, MSG_ACCEPT0x0F)) {
1621 case -1:
1622 return (-1);
1623 case PHASE_MSG_OUT0x06:
1624 bus_space_write_1(iot, ioh, TUL_SFIFO,((iot)->write_1((ioh), (0x8C), (0x09)))
1625 MSG_PARITY_ERROR)((iot)->write_1((ioh), (0x8C), (0x09)));
1626 return (iha_wait(sc, iot, ioh, XF_FIFO_OUT0x03));
1627 default:
1628 iha_bad_seq(sc);
1629 return (-1);
1630 }
1631
1632 if (msg == MSG_CMDCOMPLETE0x00) {
1633 if ((pScb->SCB_TaStat
1634 & (SCSI_INTERM0x10 | SCSI_BUSY0x08)) == SCSI_INTERM0x10) {
1635 iha_bad_seq(sc);
1636 return (-1);
1637 }
1638 sc->HCS_Flags |= FLAG_EXPECT_DONE_DISC0x20;
1639 bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO)((iot)->write_1((ioh), (0x85), (0x10)));
1640 return (iha_wait(sc, iot, ioh, MSG_ACCEPT0x0F));
1641 }
1642
1643 if ((msg == MSG_LINK_CMD_COMPLETE0x0a)
1644 || (msg == MSG_LINK_CMD_COMPLETEF0x0b)) {
1645 if ((pScb->SCB_TaStat
1646 & (SCSI_INTERM0x10 | SCSI_BUSY0x08)) == SCSI_INTERM0x10)
1647 return (iha_wait(sc, iot, ioh, MSG_ACCEPT0x0F));
1648 }
1649 }
1650
1651 iha_bad_seq(sc);
1652 return (-1);
1653}
1654
1655/*
1656 * iha_busfree - SCSI bus free detected as a result of a TIMEOUT or
1657 * DISCONNECT interrupt. Reset the tulip FIFO and
1658 * SCONFIG0 and enable hardware reselect. Move any active
1659 * SCB to HCS_DoneScb list. Return an appropriate host status
1660 * if an I/O was active.
1661 */
1662void
1663iha_busfree(struct iha_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh)
1664{
1665 struct iha_scb *pScb;
1666
1667 bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO)((iot)->write_1((ioh), (0x85), (0x10)));
1668 bus_space_write_1(iot, ioh, TUL_SCONFIG0, SCONFIG0DEFAULT)((iot)->write_1((ioh), (0x87), ((0x80 | 0x40 | 0x02 | 0x01
))))
;
1669 bus_space_write_1(iot, ioh, TUL_SCTRL1, EHRSL)((iot)->write_1((ioh), (0x86), (0x04)));
1670
1671 pScb = sc->HCS_ActScb;
1672
1673 if (pScb != NULL((void *)0)) {
1674 if (pScb->SCB_Status == STATUS_SELECT2)
1675 /* selection timeout */
1676 iha_append_done_scb(sc, pScb, HOST_SEL_TOUT0x11);
1677 else
1678 /* Unexpected bus free */
1679 iha_append_done_scb(sc, pScb, HOST_BAD_PHAS0x14);
1680
1681 }
1682}
1683
1684void
1685iha_reset_scsi_bus(struct iha_softc *sc)
1686{
1687 struct iha_scb *pScb;
1688 struct tcs *pTcs;
1689 int i, s;
1690
1691 s = splbio()splraise(0x6);
1692
1693 iha_reset_dma(sc->sc_iot, sc->sc_ioh);
1694
1695 for (i = 0, pScb = sc->HCS_Scb; i < IHA_MAX_SCB32; i++, pScb++)
1696 switch (pScb->SCB_Status) {
1697 case STATUS_BUSY3:
1698 iha_append_done_scb(sc, pScb, HOST_SCSI_RST0x1B);
1699 break;
1700
1701 case STATUS_SELECT2:
1702 iha_push_pend_scb(sc, pScb);
1703 break;
1704
1705 default:
1706 break;
1707 }
1708
1709 for (i = 0, pTcs = sc->HCS_Tcs; i < IHA_MAX_TARGETS16; i++, pTcs++)
1710 iha_reset_tcs(pTcs, sc->HCS_SConf1);
1711
1712 splx(s)spllower(s);
1713}
1714
1715/*
1716 * iha_resel - handle a detected SCSI bus reselection request.
1717 */
1718int
1719iha_resel(struct iha_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh)
1720{
1721 struct iha_scb *pScb;
1722 struct tcs *pTcs;
1723 u_int8_t tag, target, lun, msg, abortmsg;
1724
1725 if (sc->HCS_ActScb != NULL((void *)0)) {
1726 if (sc->HCS_ActScb->SCB_Status == STATUS_SELECT2)
1727 iha_push_pend_scb(sc, sc->HCS_ActScb);
1728 sc->HCS_ActScb = NULL((void *)0);
1729 }
1730
1731 target = bus_space_read_1(iot, ioh, TUL_SBID)((iot)->read_1((ioh), (0x89)));
1732 lun = bus_space_read_1(iot, ioh, TUL_SALVC)((iot)->read_1((ioh), (0x8A))) & MSG_IDENTIFY_LUNMASK0x01F;
1733
1734 pTcs = &sc->HCS_Tcs[target];
1735
1736 bus_space_write_1(iot, ioh, TUL_SCONFIG0, pTcs->TCS_SConfig0)((iot)->write_1((ioh), (0x87), (pTcs->TCS_SConfig0)));
1737 bus_space_write_1(iot, ioh, TUL_SYNCM, pTcs->TCS_JS_Period)((iot)->write_1((ioh), (0x88), (pTcs->TCS_JS_Period)));
1738
1739 abortmsg = MSG_ABORT0x06; /* until a valid tag has been obtained */
1740
1741 if (pTcs->TCS_NonTagScb != NULL((void *)0))
1742 /* There is a non-tagged I/O active on the target */
1743 pScb = pTcs->TCS_NonTagScb;
1744
1745 else {
1746 /*
1747 * Since there is no active non-tagged operation
1748 * read the tag type, the tag itself, and find
1749 * the appropriate pScb by indexing HCS_Scb with
1750 * the tag.
1751 */
1752
1753 switch (iha_wait(sc, iot, ioh, MSG_ACCEPT0x0F)) {
1754 case -1:
1755 return (-1);
1756 case PHASE_MSG_IN0x07:
1757 bus_space_write_4(iot, ioh, TUL_STCNT0, 1)((iot)->write_4((ioh), (0x80), (1)));
1758 if ((iha_wait(sc, iot, ioh, XF_FIFO_IN0x83)) == -1)
1759 return (-1);
1760 break;
1761 default:
1762 goto abort;
1763 }
1764
1765 msg = bus_space_read_1(iot, ioh, TUL_SFIFO)((iot)->read_1((ioh), (0x8C))); /* Read Tag Msg */
1766
1767 if ((msg < MSG_SIMPLE_Q_TAG0x20) || (msg > MSG_ORDERED_Q_TAG0x22))
1768 goto abort;
1769
1770 switch (iha_wait(sc, iot, ioh, MSG_ACCEPT0x0F)) {
1771 case -1:
1772 return (-1);
1773 case PHASE_MSG_IN0x07:
1774 bus_space_write_4(iot, ioh, TUL_STCNT0, 1)((iot)->write_4((ioh), (0x80), (1)));
1775 if ((iha_wait(sc, iot, ioh, XF_FIFO_IN0x83)) == -1)
1776 return (-1);
1777 break;
1778 default:
1779 goto abort;
1780 }
1781
1782 tag = bus_space_read_1(iot, ioh, TUL_SFIFO)((iot)->read_1((ioh), (0x8C))); /* Read Tag ID */
1783 pScb = &sc->HCS_Scb[tag];
1784
1785 abortmsg = MSG_ABORT_TAG0x0d; /* Now that we have valdid tag! */
1786 }
1787
1788 if ((pScb->SCB_Target != target)
1789 || (pScb->SCB_Lun != lun)
1790 || (pScb->SCB_Status != STATUS_BUSY3)) {
1791abort:
1792 iha_msgout_abort(sc, iot, ioh, abortmsg);
1793 return (-1);
1794 }
1795
1796 sc->HCS_ActScb = pScb;
1797
1798 if (iha_wait(sc, iot, ioh, MSG_ACCEPT0x0F) == -1)
1799 return (-1);
1800
1801 return(iha_next_state(sc, iot, ioh));
1802}
1803
1804int
1805iha_msgin(struct iha_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh)
1806{
1807 u_int16_t flags;
1808 u_int8_t msg;
1809 int phase;
1810
1811 for (;;) {
1812 if ((bus_space_read_1(iot, ioh, TUL_SFIFOCNT)((iot)->read_1((ioh), (0x83))) & FIFOC0x1f) > 0)
1813 bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO)((iot)->write_1((ioh), (0x85), (0x10)));
1814
1815 bus_space_write_4(iot, ioh, TUL_STCNT0, 1)((iot)->write_4((ioh), (0x80), (1)));
1816
1817 phase = iha_wait(sc, iot, ioh, XF_FIFO_IN0x83);
Value stored to 'phase' is never read
1818 msg = bus_space_read_1(iot, ioh, TUL_SFIFO)((iot)->read_1((ioh), (0x8C)));
1819
1820 switch (msg) {
1821 case MSG_DISCONNECT0x04:
1822 sc->HCS_Flags |= FLAG_EXPECT_DISC0x01;
1823 if (iha_wait(sc, iot, ioh, MSG_ACCEPT0x0F) != -1)
1824 iha_bad_seq(sc);
1825 phase = -1;
1826 break;
1827 case MSG_SAVEDATAPOINTER0x02:
1828 case MSG_RESTOREPOINTERS0x03:
1829 case MSG_NOOP0x08:
1830 phase = iha_wait(sc, iot, ioh, MSG_ACCEPT0x0F);
1831 break;
1832 case MSG_MESSAGE_REJECT0x07:
1833 /* XXX - need to clear FIFO like other 'Clear ATN'?*/
1834 iha_set_ssig(iot, ioh, REQ0x80 | BSY0x20 | SEL0x10 | ATN0x08, 0);
1835 flags = sc->HCS_ActScb->SCB_Tcs->TCS_Flags;
1836 if ((flags & FLAG_NO_NEG_SYNC(0x0010 | 0x0200)) == 0)
1837 iha_set_ssig(iot, ioh, REQ0x80 | BSY0x20 | SEL0x10, ATN0x08);
1838 phase = iha_wait(sc, iot, ioh, MSG_ACCEPT0x0F);
1839 break;
1840 case MSG_EXTENDED0x01:
1841 phase = iha_msgin_extended(sc, iot, ioh);
1842 break;
1843 case MSG_IGN_WIDE_RESIDUE0x23:
1844 phase = iha_msgin_ignore_wid_resid(sc, iot, ioh);
1845 break;
1846 case MSG_CMDCOMPLETE0x00:
1847 sc->HCS_Flags |= FLAG_EXPECT_DONE_DISC0x20;
1848 bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO)((iot)->write_1((ioh), (0x85), (0x10)));
1849 phase = iha_wait(sc, iot, ioh, MSG_ACCEPT0x0F);
1850 if (phase != -1) {
1851 iha_bad_seq(sc);
1852 return (-1);
1853 }
1854 break;
1855 default:
1856#ifdef IHA_DEBUG_STATE
1857 printf("[debug] iha_msgin: bad msg type: %d\n", msg);
1858#endif
1859 phase = iha_msgout_reject(sc, iot, ioh);
1860 break;
1861 }
1862
1863 if (phase != PHASE_MSG_IN0x07)
1864 return (phase);
1865 }
1866 /* NOTREACHED */
1867}
1868
1869int
1870iha_msgin_ignore_wid_resid(struct iha_softc *sc, bus_space_tag_t iot,
1871 bus_space_handle_t ioh)
1872{
1873 int phase;
1874
1875 phase = iha_wait(sc, iot, ioh, MSG_ACCEPT0x0F);
1876
1877 if (phase == PHASE_MSG_IN0x07) {
1878 phase = iha_wait(sc, iot, ioh, XF_FIFO_IN0x83);
1879
1880 if (phase != -1) {
1881 bus_space_write_1(iot, ioh, TUL_SFIFO, 0)((iot)->write_1((ioh), (0x8C), (0)));
1882 bus_space_read_1 (iot, ioh, TUL_SFIFO)((iot)->read_1((ioh), (0x8C)));
1883 bus_space_read_1 (iot, ioh, TUL_SFIFO)((iot)->read_1((ioh), (0x8C)));
1884
1885 phase = iha_wait(sc, iot, ioh, MSG_ACCEPT0x0F);
1886 }
1887 }
1888
1889 return (phase);
1890}
1891
1892int
1893iha_msgin_extended(struct iha_softc *sc, bus_space_tag_t iot,
1894 bus_space_handle_t ioh)
1895{
1896 u_int16_t flags;
1897 int i, phase, msglen, msgcode;
1898
1899 /* XXX - can we just stop reading and reject, or do we have to
1900 * read all input, discarding the excess, and then reject
1901 */
1902 for (i = 0; i < IHA_MAX_EXTENDED_MSG4; i++) {
1903 phase = iha_wait(sc, iot, ioh, MSG_ACCEPT0x0F);
1904
1905 if (phase != PHASE_MSG_IN0x07)
1906 return (phase);
1907
1908 bus_space_write_4(iot, ioh, TUL_STCNT0, 1)((iot)->write_4((ioh), (0x80), (1)));
1909
1910 if (iha_wait(sc, iot, ioh, XF_FIFO_IN0x83) == -1)
1911 return (-1);
1912
1913 sc->HCS_Msg[i] = bus_space_read_1(iot, ioh, TUL_SFIFO)((iot)->read_1((ioh), (0x8C)));
1914
1915 if (sc->HCS_Msg[0] == i)
1916 break;
1917 }
1918
1919 msglen = sc->HCS_Msg[0];
1920 msgcode = sc->HCS_Msg[1];
1921
1922 if ((msglen == MSG_EXT_SDTR_LEN0x03) && (msgcode == MSG_EXT_SDTR0x01)) {
1923 if (iha_msgin_sdtr(sc) == 0) {
1924 iha_sync_done(sc, iot, ioh);
1925 return (iha_wait(sc, iot, ioh, MSG_ACCEPT0x0F));
1926 }
1927
1928 iha_set_ssig(iot, ioh, REQ0x80 | BSY0x20 | SEL0x10, ATN0x08);
1929
1930 phase = iha_wait(sc, iot, ioh, MSG_ACCEPT0x0F);
1931 if (phase != PHASE_MSG_OUT0x06)
1932 return (phase);
1933
1934 /* Clear FIFO for important message - final SYNC offer */
1935 bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO)((iot)->write_1((ioh), (0x85), (0x10)));
1936
1937 iha_sync_done(sc, iot, ioh); /* This is our final offer */
1938
1939 } else if ((msglen == MSG_EXT_WDTR_LEN0x02) && (msgcode == MSG_EXT_WDTR0x03)) {
1940
1941 flags = sc->HCS_ActScb->SCB_Tcs->TCS_Flags;
1942
1943 if ((flags & FLAG_NO_WIDE0x0020) != 0)
1944 /* Offer 8 bit xfers only */
1945 sc->HCS_Msg[2] = MSG_EXT_WDTR_BUS_8_BIT0x00;
1946
1947 else if (sc->HCS_Msg[2] > MSG_EXT_WDTR_BUS_32_BIT0x02)
1948 return (iha_msgout_reject(sc, iot, ioh));
1949
1950 else if (sc->HCS_Msg[2] == MSG_EXT_WDTR_BUS_32_BIT0x02)
1951 /* Offer 16 instead */
1952 sc->HCS_Msg[2] = MSG_EXT_WDTR_BUS_32_BIT0x02;
1953
1954 else {
1955 iha_wide_done(sc, iot, ioh);
1956 if ((flags & FLAG_NO_NEG_SYNC(0x0010 | 0x0200)) == 0)
1957 iha_set_ssig(iot, ioh, REQ0x80 | BSY0x20 | SEL0x10, ATN0x08);
1958 return (iha_wait(sc, iot, ioh, MSG_ACCEPT0x0F));
1959 }
1960
1961 iha_set_ssig(iot, ioh, REQ0x80 | BSY0x20 | SEL0x10, ATN0x08);
1962
1963 phase = iha_wait(sc, iot, ioh, MSG_ACCEPT0x0F);
1964 if (phase != PHASE_MSG_OUT0x06)
1965 return (phase);
1966
1967 } else
1968 return (iha_msgout_reject(sc, iot, ioh));
1969
1970 /* Send message built in sc->HCS_Msg[] */
1971 return (iha_msgout_extended(sc, iot, ioh));
1972}
1973
1974/*
1975 * iha_msgin_sdtr - check SDTR msg in HCS_Msg. If the offer is
1976 * acceptable leave HCS_Msg as is and return 0.
1977 * If the negotiation must continue, modify HCS_Msg
1978 * as needed and return 1. Else return 0.
1979 */
1980int
1981iha_msgin_sdtr(struct iha_softc *sc)
1982{
1983 u_int16_t flags;
1984 u_int8_t default_period;
1985 int newoffer;
1986
1987 flags = sc->HCS_ActScb->SCB_Tcs->TCS_Flags;
1988
1989 default_period = iha_rate_tbl[flags & FLAG_SCSI_RATE0x0007];
1990
1991 if (sc->HCS_Msg[3] == 0) /* target offered async only. Accept it. */
1992 return (0);
1993
1994 newoffer = 0;
1995
1996 if ((flags & FLAG_NO_SYNC0x0010) != 0) {
1997 sc->HCS_Msg[3] = 0;
1998 newoffer = 1;
1999 }
2000
2001 if (sc->HCS_Msg[3] > IHA_MAX_TARGETS16-1) {
2002 sc->HCS_Msg[3] = IHA_MAX_TARGETS16-1;
2003 newoffer = 1;
2004 }
2005
2006 if (sc->HCS_Msg[2] < default_period) {
2007 sc->HCS_Msg[2] = default_period;
2008 newoffer = 1;
2009 }
2010
2011 if (sc->HCS_Msg[2] >= 59) {
2012 sc->HCS_Msg[3] = 0;
2013 newoffer = 1;
2014 }
2015
2016 return (newoffer);
2017}
2018
2019int
2020iha_msgout(struct iha_softc *sc, bus_space_tag_t iot,
2021 bus_space_handle_t ioh, u_int8_t msg)
2022{
2023 bus_space_write_1(iot, ioh, TUL_SFIFO, msg)((iot)->write_1((ioh), (0x8C), (msg)));
2024
2025 return (iha_wait(sc, iot, ioh, XF_FIFO_OUT0x03));
2026}
2027
2028void
2029iha_msgout_abort(struct iha_softc *sc, bus_space_tag_t iot,
2030 bus_space_handle_t ioh, u_int8_t aborttype)
2031{
2032 iha_set_ssig(iot, ioh, REQ0x80 | BSY0x20 | SEL0x10, ATN0x08);
2033
2034 switch (iha_wait(sc, iot, ioh, MSG_ACCEPT0x0F)) {
2035 case -1:
2036 break;
2037
2038 case PHASE_MSG_OUT0x06:
2039 sc->HCS_Flags |= FLAG_EXPECT_DISC0x01;
2040 if (iha_msgout(sc, iot, ioh, aborttype) != -1)
2041 iha_bad_seq(sc);
2042 break;
2043
2044 default:
2045 iha_bad_seq(sc);
2046 break;
2047 }
2048}
2049
2050int
2051iha_msgout_reject(struct iha_softc *sc, bus_space_tag_t iot,
2052 bus_space_handle_t ioh)
2053{
2054 iha_set_ssig(iot, ioh, REQ0x80 | BSY0x20 | SEL0x10, ATN0x08);
2055
2056 if (iha_wait(sc, iot, ioh, MSG_ACCEPT0x0F) == PHASE_MSG_OUT0x06)
2057 return (iha_msgout(sc, iot, ioh, MSG_MESSAGE_REJECT0x07));
2058
2059 return (-1);
2060}
2061
2062int
2063iha_msgout_extended(struct iha_softc *sc, bus_space_tag_t iot,
2064 bus_space_handle_t ioh)
2065{
2066 int phase;
2067
2068 bus_space_write_1(iot, ioh, TUL_SFIFO, MSG_EXTENDED)((iot)->write_1((ioh), (0x8C), (0x01)));
2069
2070 bus_space_write_multi_1(iot, ioh, TUL_SFIFO,((iot)->write_multi_1((ioh), (0x8C), (sc->HCS_Msg), (sc
->HCS_Msg[0]+1)))
2071 sc->HCS_Msg, sc->HCS_Msg[0]+1)((iot)->write_multi_1((ioh), (0x8C), (sc->HCS_Msg), (sc
->HCS_Msg[0]+1)))
;
2072
2073 phase = iha_wait(sc, iot, ioh, XF_FIFO_OUT0x03);
2074
2075 bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO)((iot)->write_1((ioh), (0x85), (0x10)));
2076 iha_set_ssig(iot, ioh, REQ0x80 | BSY0x20 | SEL0x10 | ATN0x08, 0);
2077
2078 return (phase);
2079}
2080
2081int
2082iha_msgout_wdtr(struct iha_softc *sc, bus_space_tag_t iot,
2083 bus_space_handle_t ioh)
2084{
2085 sc->HCS_ActScb->SCB_Tcs->TCS_Flags |= FLAG_WIDE_DONE0x0100;
2086
2087 sc->HCS_Msg[0] = MSG_EXT_WDTR_LEN0x02;
2088 sc->HCS_Msg[1] = MSG_EXT_WDTR0x03;
2089 sc->HCS_Msg[2] = MSG_EXT_WDTR_BUS_16_BIT0x01;
2090
2091 return (iha_msgout_extended(sc, iot, ioh));
2092}
2093
2094int
2095iha_msgout_sdtr(struct iha_softc *sc, bus_space_tag_t iot,
2096 bus_space_handle_t ioh)
2097{
2098 u_int16_t rateindex;
2099 u_int8_t sync_rate;
2100
2101 rateindex = sc->HCS_ActScb->SCB_Tcs->TCS_Flags & FLAG_SCSI_RATE0x0007;
2102
2103 sync_rate = iha_rate_tbl[rateindex];
2104
2105 sc->HCS_Msg[0] = MSG_EXT_SDTR_LEN0x03;
2106 sc->HCS_Msg[1] = MSG_EXT_SDTR0x01;
2107 sc->HCS_Msg[2] = sync_rate;
2108 sc->HCS_Msg[3] = IHA_MAX_TARGETS16-1; /* REQ/ACK */
2109
2110 return (iha_msgout_extended(sc, iot, ioh));
2111}
2112
2113void
2114iha_wide_done(struct iha_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh)
2115{
2116 struct tcs *pTcs = sc->HCS_ActScb->SCB_Tcs;
2117
2118 pTcs->TCS_JS_Period = 0;
2119
2120 if (sc->HCS_Msg[2] != 0)
2121 pTcs->TCS_JS_Period |= PERIOD_WIDE_SCSI0x80;
2122
2123 pTcs->TCS_SConfig0 &= ~ALTPD0x02;
2124 pTcs->TCS_Flags &= ~FLAG_SYNC_DONE0x0200;
2125 pTcs->TCS_Flags |= FLAG_WIDE_DONE0x0100;
2126
2127 bus_space_write_1(iot, ioh, TUL_SCONFIG0, pTcs->TCS_SConfig0)((iot)->write_1((ioh), (0x87), (pTcs->TCS_SConfig0)));
2128 bus_space_write_1(iot, ioh, TUL_SYNCM, pTcs->TCS_JS_Period)((iot)->write_1((ioh), (0x88), (pTcs->TCS_JS_Period)));
2129}
2130
2131void
2132iha_sync_done(struct iha_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh)
2133{
2134 struct tcs *pTcs = sc->HCS_ActScb->SCB_Tcs;
2135 int i;
2136
2137 if ((pTcs->TCS_Flags & FLAG_SYNC_DONE0x0200) == 0) {
2138 if (sc->HCS_Msg[3] != 0) {
2139 pTcs->TCS_JS_Period |= sc->HCS_Msg[3];
2140
2141 /* pick the highest possible rate */
2142 for (i = 0; i < sizeof(iha_rate_tbl); i++)
2143 if (iha_rate_tbl[i] >= sc->HCS_Msg[2])
2144 break;
2145
2146 pTcs->TCS_JS_Period |= (i << 4);
2147 pTcs->TCS_SConfig0 |= ALTPD0x02;
2148 }
2149
2150 pTcs->TCS_Flags |= FLAG_SYNC_DONE0x0200;
2151
2152 bus_space_write_1(iot, ioh, TUL_SCONFIG0, pTcs->TCS_SConfig0)((iot)->write_1((ioh), (0x87), (pTcs->TCS_SConfig0)));
2153 bus_space_write_1(iot, ioh, TUL_SYNCM, pTcs->TCS_JS_Period)((iot)->write_1((ioh), (0x88), (pTcs->TCS_JS_Period)));
2154 }
2155}
2156
2157void
2158iha_reset_chip(struct iha_softc *sc, bus_space_tag_t iot,
2159 bus_space_handle_t ioh)
2160{
2161 int i;
2162
2163 /* reset tulip chip */
2164
2165 bus_space_write_1(iot, ioh, TUL_SCTRL0, RSCSI)((iot)->write_1((ioh), (0x85), (0x01)));
2166
2167 do
2168 sc->HCS_JSInt = bus_space_read_1(iot, ioh, TUL_SISTAT)((iot)->read_1((ioh), (0x84)));
2169 while((sc->HCS_JSInt & SRSTD0x10) == 0);
2170
2171 iha_set_ssig(iot, ioh, 0, 0);
2172
2173 /*
2174 * Stall for 2 seconds, wait for target's firmware ready.
2175 */
2176 for (i = 0; i < 2000; i++)
2177 DELAY (1000)(*delay_func)(1000);
2178
2179 bus_space_read_1(iot, ioh, TUL_SISTAT)((iot)->read_1((ioh), (0x84))); /* Clear any active interrupt*/
2180}
2181
2182void
2183iha_select(struct iha_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh,
2184 struct iha_scb *pScb, u_int8_t select_type)
2185{
2186 int s;
2187
2188 switch (select_type) {
2189 case SEL_ATN0x11:
2190 bus_space_write_1(iot, ioh, TUL_SFIFO, pScb->SCB_Ident)((iot)->write_1((ioh), (0x8C), (pScb->SCB_Ident)));
2191 bus_space_write_multi_1(iot, ioh, TUL_SFIFO,((iot)->write_multi_1((ioh), (0x8C), (pScb->SCB_CDB), (
pScb->SCB_CDBLen)))
2192 pScb->SCB_CDB, pScb->SCB_CDBLen)((iot)->write_multi_1((ioh), (0x8C), (pScb->SCB_CDB), (
pScb->SCB_CDBLen)))
;
2193
2194 pScb->SCB_NxtStat = 2;
2195 break;
2196
2197 case SELATNSTOP0x1E:
2198 pScb->SCB_NxtStat = 1;
2199 break;
2200
2201 case SEL_ATN30x31:
2202 bus_space_write_1(iot, ioh, TUL_SFIFO, pScb->SCB_Ident)((iot)->write_1((ioh), (0x8C), (pScb->SCB_Ident)));
2203 bus_space_write_1(iot, ioh, TUL_SFIFO, pScb->SCB_TagMsg)((iot)->write_1((ioh), (0x8C), (pScb->SCB_TagMsg)));
2204 bus_space_write_1(iot, ioh, TUL_SFIFO, pScb->SCB_TagId)((iot)->write_1((ioh), (0x8C), (pScb->SCB_TagId)));
2205
2206 bus_space_write_multi_1(iot, ioh, TUL_SFIFO, pScb->SCB_CDB,((iot)->write_multi_1((ioh), (0x8C), (pScb->SCB_CDB), (
pScb->SCB_CDBLen)))
2207 pScb->SCB_CDBLen)((iot)->write_multi_1((ioh), (0x8C), (pScb->SCB_CDB), (
pScb->SCB_CDBLen)))
;
2208
2209 pScb->SCB_NxtStat = 2;
2210 break;
2211
2212 default:
2213#ifdef IHA_DEBUG_STATE
2214 sc_print_addr(pScb->SCB_Xs->sc_link);
2215 printf("[debug] iha_select() - unknown select type = 0x%02x\n",
2216 select_type);
2217#endif
2218 return;
2219 }
2220
2221 s = splbio()splraise(0x6);
2222 TAILQ_REMOVE(&sc->HCS_PendScb, pScb, SCB_ScbList)do { if (((pScb)->SCB_ScbList.tqe_next) != ((void *)0)) (pScb
)->SCB_ScbList.tqe_next->SCB_ScbList.tqe_prev = (pScb)->
SCB_ScbList.tqe_prev; else (&sc->HCS_PendScb)->tqh_last
= (pScb)->SCB_ScbList.tqe_prev; *(pScb)->SCB_ScbList.tqe_prev
= (pScb)->SCB_ScbList.tqe_next; ((pScb)->SCB_ScbList.tqe_prev
) = ((void *)-1); ((pScb)->SCB_ScbList.tqe_next) = ((void *
)-1); } while (0)
;
2223 splx(s)spllower(s);
2224
2225 pScb->SCB_Status = STATUS_SELECT2;
2226
2227 sc->HCS_ActScb = pScb;
2228
2229 bus_space_write_1(iot, ioh, TUL_SCMD, select_type)((iot)->write_1((ioh), (0x91), (select_type)));
2230}
2231
2232/*
2233 * iha_wait - wait for an interrupt to service or a SCSI bus phase change
2234 * after writing the supplied command to the tulip chip. If
2235 * the command is NO_OP, skip the command writing.
2236 */
2237int
2238iha_wait(struct iha_softc *sc, bus_space_tag_t iot, bus_space_handle_t ioh,
2239 u_int8_t cmd)
2240{
2241 if (cmd != NO_OP0x00)
2242 bus_space_write_1(iot, ioh, TUL_SCMD, cmd)((iot)->write_1((ioh), (0x91), (cmd)));
2243
2244 /*
2245 * Have to do this here, in addition to in iha_isr, because
2246 * interrupts might be turned off when we get here.
2247 */
2248 do
2249 sc->HCS_JSStatus0 = bus_space_read_1(iot, ioh, TUL_STAT0)((iot)->read_1((ioh), (0x85)));
2250 while ((sc->HCS_JSStatus0 & INTPD0x80) == 0);
2251
2252 sc->HCS_JSStatus1 = bus_space_read_1(iot, ioh, TUL_STAT1)((iot)->read_1((ioh), (0x86)));
2253 sc->HCS_JSInt = bus_space_read_1(iot, ioh, TUL_SISTAT)((iot)->read_1((ioh), (0x84)));
2254
2255 sc->HCS_Phase = sc->HCS_JSStatus0 & PH_MASK0x07;
2256
2257 if ((sc->HCS_JSInt & SRSTD0x10) != 0) {
2258 /* SCSI bus reset interrupt */
2259 iha_reset_scsi_bus(sc);
2260 return (-1);
2261 }
2262
2263 if ((sc->HCS_JSInt & RSELED0x80) != 0)
2264 /* Reselection interrupt */
2265 return (iha_resel(sc, iot, ioh));
2266
2267 if ((sc->HCS_JSInt & STIMEO0x40) != 0) {
2268 /* selected/reselected timeout interrupt */
2269 iha_busfree(sc, iot, ioh);
2270 return (-1);
2271 }
2272
2273 if ((sc->HCS_JSInt & DISCD0x08) != 0) {
2274 /* BUS disconnection interrupt */
2275 if ((sc->HCS_Flags & FLAG_EXPECT_DONE_DISC0x20) != 0) {
2276 bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO)((iot)->write_1((ioh), (0x85), (0x10)));
2277 bus_space_write_1(iot, ioh, TUL_SCONFIG0,((iot)->write_1((ioh), (0x87), ((0x80 | 0x40 | 0x02 | 0x01
))))
2278 SCONFIG0DEFAULT)((iot)->write_1((ioh), (0x87), ((0x80 | 0x40 | 0x02 | 0x01
))))
;
2279 bus_space_write_1(iot, ioh, TUL_SCTRL1, EHRSL)((iot)->write_1((ioh), (0x86), (0x04)));
2280 iha_append_done_scb(sc, sc->HCS_ActScb, HOST_OK0x00);
2281 sc->HCS_Flags &= ~FLAG_EXPECT_DONE_DISC0x20;
2282
2283 } else if ((sc->HCS_Flags & FLAG_EXPECT_DISC0x01) != 0) {
2284 bus_space_write_1(iot, ioh, TUL_SCTRL0, RSFIFO)((iot)->write_1((ioh), (0x85), (0x10)));
2285 bus_space_write_1(iot, ioh, TUL_SCONFIG0,((iot)->write_1((ioh), (0x87), ((0x80 | 0x40 | 0x02 | 0x01
))))
2286 SCONFIG0DEFAULT)((iot)->write_1((ioh), (0x87), ((0x80 | 0x40 | 0x02 | 0x01
))))
;
2287 bus_space_write_1(iot, ioh, TUL_SCTRL1, EHRSL)((iot)->write_1((ioh), (0x86), (0x04)));
2288 sc->HCS_ActScb = NULL((void *)0);
2289 sc->HCS_Flags &= ~FLAG_EXPECT_DISC0x01;
2290
2291 } else
2292 iha_busfree(sc, iot, ioh);
2293
2294 return (-1);
2295 }
2296
2297 return (sc->HCS_Phase);
2298}
2299
2300/*
2301 * iha_done_scb - We have a scb which has been processed by the
2302 * adaptor, now we look to see how the operation went.
2303 */
2304void
2305iha_done_scb(struct iha_softc *sc, struct iha_scb *pScb)
2306{
2307 struct scsi_sense_data *s1, *s2;
2308 struct scsi_xfer *xs = pScb->SCB_Xs;
2309
2310 if (xs != NULL((void *)0)) {
2311 timeout_del(&xs->stimeout);
2312
2313 xs->status = pScb->SCB_TaStat;
2314
2315 if ((pScb->SCB_Flags & (SCSI_DATA_IN0x00800 | SCSI_DATA_OUT0x01000)) != 0) {
2316 bus_dmamap_sync(sc->sc_dmat, pScb->SCB_DataDma,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (pScb->
SCB_DataDma), (0), (pScb->SCB_BufChars), (((pScb->SCB_Flags
& 0x00800) ? 0x02 : 0x08)))
2317 0, pScb->SCB_BufChars,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (pScb->
SCB_DataDma), (0), (pScb->SCB_BufChars), (((pScb->SCB_Flags
& 0x00800) ? 0x02 : 0x08)))
2318 ((pScb->SCB_Flags & SCSI_DATA_IN) ?(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (pScb->
SCB_DataDma), (0), (pScb->SCB_BufChars), (((pScb->SCB_Flags
& 0x00800) ? 0x02 : 0x08)))
2319 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE))(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (pScb->
SCB_DataDma), (0), (pScb->SCB_BufChars), (((pScb->SCB_Flags
& 0x00800) ? 0x02 : 0x08)))
;
2320 bus_dmamap_unload(sc->sc_dmat, pScb->SCB_DataDma)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (pScb
->SCB_DataDma))
;
2321 }
2322 if ((pScb->SCB_Flags & FLAG_SG0x00020000) != 0) {
2323 bus_dmamap_sync(sc->sc_dmat, pScb->SCB_SGDma,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (pScb->
SCB_SGDma), (0), (sizeof(pScb->SCB_SGList)), (0x08))
2324 0, sizeof(pScb->SCB_SGList),(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (pScb->
SCB_SGDma), (0), (sizeof(pScb->SCB_SGList)), (0x08))
2325 BUS_DMASYNC_POSTWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (pScb->
SCB_SGDma), (0), (sizeof(pScb->SCB_SGList)), (0x08))
;
2326 bus_dmamap_unload(sc->sc_dmat, pScb->SCB_SGDma)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (pScb
->SCB_SGDma))
;
2327 }
2328
2329 switch (pScb->SCB_HaStat) {
2330 case HOST_OK0x00:
2331 switch (pScb->SCB_TaStat) {
2332 case SCSI_OK0x00:
2333 case SCSI_COND_MET0x04:
2334 case SCSI_INTERM0x10:
2335 case SCSI_INTERM_COND_MET0x14:
2336 xs->resid = pScb->SCB_BufCharsLeft;
2337 xs->error = XS_NOERROR0;
2338 break;
2339
2340 case SCSI_RESV_CONFLICT0x18:
2341 case SCSI_BUSY0x08:
2342 case SCSI_QUEUE_FULL0x28:
2343 xs->error = XS_BUSY5;
2344 break;
2345
2346 case SCSI_TERMINATED0x22:
2347 case SCSI_ACA_ACTIVE0x30:
2348 case SCSI_CHECK0x02:
2349 s1 = &pScb->SCB_ScsiSenseData;
2350 s2 = &xs->sense;
2351 *s2 = *s1;
2352
2353 xs->error = XS_SENSE1;
2354 break;
2355
2356 default:
2357 xs->error = XS_DRIVER_STUFFUP2;
2358 break;
2359 }
2360 break;
2361
2362 case HOST_SEL_TOUT0x11:
2363 xs->error = XS_SELTIMEOUT3;
2364 break;
2365
2366 case HOST_SCSI_RST0x1B:
2367 case HOST_DEV_RST0x1C:
2368 xs->error = XS_RESET8;
2369 break;
2370
2371 case HOST_SPERR0x10:
2372 sc_print_addr(xs->sc_link);
2373 printf("SCSI Parity error detected\n");
2374 xs->error = XS_DRIVER_STUFFUP2;
2375 break;
2376
2377 case HOST_TIMED_OUT0x01:
2378 xs->error = XS_TIMEOUT4;
2379 break;
2380
2381 case HOST_DO_DU0x12:
2382 case HOST_BAD_PHAS0x14:
2383 default:
2384 xs->error = XS_DRIVER_STUFFUP2;
2385 break;
2386 }
2387 scsi_done(xs);
2388 }
2389}
2390
2391void
2392iha_timeout(void *arg)
2393{
2394 struct iha_scb *pScb = (struct iha_scb *)arg;
2395 struct scsi_xfer *xs = pScb->SCB_Xs;
2396
2397 if (xs != NULL((void *)0)) {
2398 sc_print_addr(xs->sc_link);
2399 printf("SCSI OpCode 0x%02x timed out\n", xs->cmd.opcode);
2400 iha_abort_xs(xs->sc_link->bus->sb_adapter_softc, xs, HOST_TIMED_OUT0x01);
2401 }
2402}
2403
2404void
2405iha_exec_scb(struct iha_softc *sc, struct iha_scb *pScb)
2406{
2407 struct scsi_xfer *xs = pScb->SCB_Xs;
2408 bus_space_handle_t ioh;
2409 bus_space_tag_t iot;
2410 int s;
2411
2412 s = splbio()splraise(0x6);
2413
2414 if ((pScb->SCB_Flags & SCSI_POLL0x00002) == 0)
2415 timeout_add_msec(&xs->stimeout, xs->timeout);
2416
2417 if (((pScb->SCB_Flags & SCSI_RESET0x00200) != 0)
2418 || (pScb->SCB_CDB[0] == REQUEST_SENSE0x03))
2419 iha_push_pend_scb(sc, pScb); /* Insert SCB at head of Pend */
2420 else
2421 iha_append_pend_scb(sc, pScb); /* Append SCB to tail of Pend */
2422
2423 /*
2424 * Run through iha_main() to ensure something is active, if
2425 * only this new SCB.
2426 */
2427 if (sc->HCS_Semaph != SEMAPH_IN_MAIN0x00) {
2428 iot = sc->sc_iot;
2429 ioh = sc->sc_ioh;
2430
2431 bus_space_write_1(iot, ioh, TUL_IMSK, MASK_ALL)((iot)->write_1((ioh), (0xE0), ((0x01 | 0x02 | 0x04 | 0x08
| 0x10))))
;
2432 sc->HCS_Semaph = SEMAPH_IN_MAIN0x00;
2433
2434 splx(s)spllower(s);
2435 iha_main(sc, iot, ioh);
2436 s = splbio()splraise(0x6);
2437
2438 sc->HCS_Semaph = ~SEMAPH_IN_MAIN0x00;
2439 bus_space_write_1(iot, ioh, TUL_IMSK, (MASK_ALL & ~MSCMP))((iot)->write_1((ioh), (0xE0), (((0x01 | 0x02 | 0x04 | 0x08
| 0x10) & ~0x10))))
;
2440 }
2441
2442 splx(s)spllower(s);
2443}
2444
2445
2446/*
2447 * iha_set_ssig - read the current scsi signal mask, then write a new
2448 * one which turns off/on the specified signals.
2449 */
2450void
2451iha_set_ssig(bus_space_tag_t iot, bus_space_handle_t ioh, u_int8_t offsigs,
2452 u_int8_t onsigs)
2453{
2454 u_int8_t currsigs;
2455
2456 currsigs = bus_space_read_1(iot, ioh, TUL_SSIGI)((iot)->read_1((ioh), (0x90)));
2457 bus_space_write_1(iot, ioh, TUL_SSIGO, (currsigs & ~offsigs) | onsigs)((iot)->write_1((ioh), (0x90), ((currsigs & ~offsigs) |
onsigs)))
;
2458}
2459
2460void
2461iha_print_info(struct iha_softc *sc, int target)
2462{
2463 u_int8_t period = sc->HCS_Tcs[target].TCS_JS_Period;
2464 u_int8_t config = sc->HCS_Tcs[target].TCS_SConfig0;
2465 int rate;
2466
2467 printf("%s: target %d using %d bit ", sc->sc_dev.dv_xname, target,
2468 (period & PERIOD_WIDE_SCSI0x80) ? 16 : 8);
2469
2470 if ((period & PERIOD_SYOFS0x0f) == 0)
2471 printf("async ");
2472 else {
2473 rate = (period & PERIOD_SYXPD0x70) >> 4;
2474 if ((config & ALTPD0x02) == 0)
2475 rate = 100 + rate * 50;
2476 else
2477 rate = 50 + rate * 25;
2478 rate = 1000000000 / rate;
2479 printf("%d.%d MHz %d REQ/ACK offset ", rate / 1000000,
2480 (rate % 1000000 + 99999) / 100000, period & PERIOD_SYOFS0x0f);
2481 }
2482
2483 printf("xfers\n");
2484}
2485
2486
2487/*
2488 * iha_alloc_scbs - allocate and map the SCB's for the supplied iha_softc
2489 */
2490int
2491iha_alloc_scbs(struct iha_softc *sc)
2492{
2493 bus_dma_segment_t seg;
2494 int error, rseg;
2495
2496 /*
2497 * Allocate dma-safe memory for the SCB's
2498 */
2499 if ((error = bus_dmamem_alloc(sc->sc_dmat,(*(sc->sc_dmat)->_dmamem_alloc)((sc->sc_dmat), (sizeof
(struct iha_scb)*32), ((1 << 12)), (0), (&seg), (1)
, (&rseg), (0x0001 | 0x1000))
2500 sizeof(struct iha_scb)*IHA_MAX_SCB,(*(sc->sc_dmat)->_dmamem_alloc)((sc->sc_dmat), (sizeof
(struct iha_scb)*32), ((1 << 12)), (0), (&seg), (1)
, (&rseg), (0x0001 | 0x1000))
2501 NBPG, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT | BUS_DMA_ZERO)(*(sc->sc_dmat)->_dmamem_alloc)((sc->sc_dmat), (sizeof
(struct iha_scb)*32), ((1 << 12)), (0), (&seg), (1)
, (&rseg), (0x0001 | 0x1000))
)
2502 != 0) {
2503 printf("%s: unable to allocate SCBs,"
2504 " error = %d\n", sc->sc_dev.dv_xname, error);
2505 return (error);
2506 }
2507 if ((error = bus_dmamem_map(sc->sc_dmat,(*(sc->sc_dmat)->_dmamem_map)((sc->sc_dmat), (&seg
), (rseg), (sizeof(struct iha_scb)*32), ((caddr_t *)&sc->
HCS_Scb), (0x0001 | 0x0004))
2508 &seg, rseg, sizeof(struct iha_scb)*IHA_MAX_SCB,(*(sc->sc_dmat)->_dmamem_map)((sc->sc_dmat), (&seg
), (rseg), (sizeof(struct iha_scb)*32), ((caddr_t *)&sc->
HCS_Scb), (0x0001 | 0x0004))
2509 (caddr_t *)&sc->HCS_Scb, BUS_DMA_NOWAIT | BUS_DMA_COHERENT)(*(sc->sc_dmat)->_dmamem_map)((sc->sc_dmat), (&seg
), (rseg), (sizeof(struct iha_scb)*32), ((caddr_t *)&sc->
HCS_Scb), (0x0001 | 0x0004))
)
2510 != 0) {
2511 printf("%s: unable to map SCBs, error = %d\n",
2512 sc->sc_dev.dv_xname, error);
2513 return (error);
2514 }
2515
2516 return (0);
2517}
2518
2519/*
2520 * iha_read_eeprom - read contents of serial EEPROM into iha_nvram pointed at
2521 * by parameter nvram.
2522 */
2523void
2524iha_read_eeprom(bus_space_tag_t iot, bus_space_handle_t ioh,
2525 struct iha_nvram *nvram)
2526{
2527 u_int32_t chksum;
2528 u_int16_t *np;
2529 u_int8_t gctrl, addr;
2530
2531 const int chksum_addr = offsetof(struct iha_nvram, NVM_CheckSum)__builtin_offsetof(struct iha_nvram, NVM_CheckSum) / 2;
2532
2533 /* Enable EEProm programming */
2534 gctrl = bus_space_read_1(iot, ioh, TUL_GCTRL0)((iot)->read_1((ioh), (0x54))) | EEPRG0x04;
2535 bus_space_write_1(iot, ioh, TUL_GCTRL0, gctrl)((iot)->write_1((ioh), (0x54), (gctrl)));
2536
2537 /* Read EEProm */
2538 np = (u_int16_t *)nvram;
2539 for (addr=0, chksum=0; addr < chksum_addr; addr++, np++) {
2540 *np = iha_se2_rd(iot, ioh, addr);
2541 chksum += *np;
2542 }
2543
2544 chksum &= 0x0000ffff;
2545 nvram->NVM_CheckSum = iha_se2_rd(iot, ioh, chksum_addr);
2546
2547 /* Disable EEProm programming */
2548 gctrl = bus_space_read_1(iot, ioh, TUL_GCTRL0)((iot)->read_1((ioh), (0x54))) & ~EEPRG0x04;
2549 bus_space_write_1(iot, ioh, TUL_GCTRL0, gctrl)((iot)->write_1((ioh), (0x54), (gctrl)));
2550
2551 if ((nvram->NVM_Signature != SIGNATURE0xC925)
2552 ||
2553 (nvram->NVM_CheckSum != chksum))
2554 panic("iha: invalid EEPROM, bad signature or checksum");
2555}
2556
2557/*
2558 * iha_se2_rd - read & return the 16 bit value at the specified
2559 * offset in the Serial E2PROM
2560 *
2561 */
2562u_int16_t
2563iha_se2_rd(bus_space_tag_t iot, bus_space_handle_t ioh, u_int8_t addr)
2564{
2565 u_int16_t readWord;
2566 u_int8_t bit;
2567 int i;
2568
2569 /* Send 'READ' instruction == address | READ bit */
2570 iha_se2_instr(iot, ioh, (addr | NVREAD0x80));
2571
2572 readWord = 0;
2573 for (i = 15; i >= 0; i--) {
2574 bus_space_write_1(iot, ioh, TUL_NVRAM, NVRCS | NVRCK)((iot)->write_1((ioh), (0x5D), (0x08 | 0x04)));
2575 DELAY(5)(*delay_func)(5);
2576
2577 bus_space_write_1(iot, ioh, TUL_NVRAM, NVRCS)((iot)->write_1((ioh), (0x5D), (0x08)));
2578 DELAY(5)(*delay_func)(5);
2579
2580 /* sample data after the following edge of clock */
2581 bit = bus_space_read_1(iot, ioh, TUL_NVRAM)((iot)->read_1((ioh), (0x5D))) & NVRDI0x01;
2582 DELAY(5)(*delay_func)(5);
2583
2584 readWord += bit << i;
2585 }
2586
2587 bus_space_write_1(iot, ioh, TUL_NVRAM, 0)((iot)->write_1((ioh), (0x5D), (0)));
2588 DELAY(5)(*delay_func)(5);
2589
2590 return (readWord);
2591}
2592
2593/*
2594 * iha_se2_instr - write an octet to serial E2PROM one bit at a time
2595 */
2596void
2597iha_se2_instr(bus_space_tag_t iot, bus_space_handle_t ioh, u_int8_t instr)
2598{
2599 u_int8_t b;
2600 int i;
2601
2602 b = NVRCS0x08 | NVRDO0x02; /* Write the start bit (== 1) */
2603
2604 bus_space_write_1(iot, ioh, TUL_NVRAM, b)((iot)->write_1((ioh), (0x5D), (b)));
2605 DELAY(5)(*delay_func)(5);
2606 bus_space_write_1(iot, ioh, TUL_NVRAM, b | NVRCK)((iot)->write_1((ioh), (0x5D), (b | 0x04)));
2607 DELAY(5)(*delay_func)(5);
2608
2609 for (i = 0; i < 8; i++, instr <<= 1) {
2610 if (instr & 0x80)
2611 b = NVRCS0x08 | NVRDO0x02; /* Write a 1 bit */
2612 else
2613 b = NVRCS0x08; /* Write a 0 bit */
2614
2615 bus_space_write_1(iot, ioh, TUL_NVRAM, b)((iot)->write_1((ioh), (0x5D), (b)));
2616 DELAY(5)(*delay_func)(5);
2617 bus_space_write_1(iot, ioh, TUL_NVRAM, b | NVRCK)((iot)->write_1((ioh), (0x5D), (b | 0x04)));
2618 DELAY(5)(*delay_func)(5);
2619 }
2620
2621 bus_space_write_1(iot, ioh, TUL_NVRAM, NVRCS)((iot)->write_1((ioh), (0x5D), (0x08)));
2622 DELAY(5)(*delay_func)(5);
2623
2624 return;
2625}
2626
2627/*
2628 * iha_reset_tcs - reset the target control structure pointed
2629 * to by pTcs to default values. TCS_Flags
2630 * only has the negotiation done bits reset as
2631 * the other bits are fixed at initialization.
2632 */
2633void
2634iha_reset_tcs(struct tcs *pTcs, u_int8_t config0)
2635{
2636 pTcs->TCS_Flags &= ~(FLAG_SYNC_DONE0x0200 | FLAG_WIDE_DONE0x0100);
2637 pTcs->TCS_JS_Period = 0;
2638 pTcs->TCS_SConfig0 = config0;
2639 pTcs->TCS_TagCnt = 0;
2640 pTcs->TCS_NonTagScb = NULL((void *)0);
2641}