Bug Summary

File:dev/ic/siop.c
Warning:line 1000, column 17
Dereference of null pointer

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 siop.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/siop.c
1/* $OpenBSD: siop.c,v 1.88 2022/01/09 05:42:42 jsg Exp $ */
2/* $NetBSD: siop.c,v 1.79 2005/11/18 23:10:32 bouyer Exp $ */
3
4/*
5 * Copyright (c) 2000 Manuel Bouyer.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28
29/* SYM53c7/8xx PCI-SCSI I/O Processors driver */
30
31#include <sys/param.h>
32#include <sys/systm.h>
33#include <sys/device.h>
34#include <sys/malloc.h>
35#include <sys/kernel.h>
36#include <sys/endian.h>
37
38#include <machine/bus.h>
39
40#include <dev/microcode/siop/siop.out>
41
42#include <scsi/scsi_all.h>
43#include <scsi/scsi_message.h>
44#include <scsi/scsiconf.h>
45
46#include <dev/ic/siopreg.h>
47#include <dev/ic/siopvar_common.h>
48#include <dev/ic/siopvar.h>
49
50#ifndef SIOP_DEBUG
51#undef SIOP_DEBUG_DR
52#undef SIOP_DEBUG_INTR
53#undef SIOP_DEBUG_SCHED
54#undef DUMP_SCRIPT
55#else
56#define SIOP_DEBUG_DR
57#define SIOP_DEBUG_INTR
58#define SIOP_DEBUG_SCHED
59#define DUMP_SCRIPT
60#endif
61
62
63#undef SIOP_STATS
64
65#ifndef SIOP_DEFAULT_TARGET7
66#define SIOP_DEFAULT_TARGET7 7
67#endif
68
69/* number of cmd descriptors per block */
70#define SIOP_NCMDPB((1 << 12) / sizeof(struct siop_xfer)) (PAGE_SIZE(1 << 12) / sizeof(struct siop_xfer))
71
72/* Number of scheduler slot (needs to match script) */
73#define SIOP_NSLOTS40 40
74
75void siop_table_sync(struct siop_cmd *, int);
76void siop_script_sync(struct siop_softc *, int);
77u_int32_t siop_script_read(struct siop_softc *, u_int);
78void siop_script_write(struct siop_softc *, u_int, u_int32_t);
79void siop_reset(struct siop_softc *);
80void siop_handle_reset(struct siop_softc *);
81int siop_handle_qtag_reject(struct siop_cmd *);
82void siop_scsicmd_end(struct siop_cmd *);
83void siop_start(struct siop_softc *);
84void siop_timeout(void *);
85void siop_scsicmd(struct scsi_xfer *);
86void * siop_cmd_get(void *);
87void siop_cmd_put(void *, void *);
88int siop_scsiprobe(struct scsi_link *);
89void siop_scsifree(struct scsi_link *);
90#ifdef DUMP_SCRIPT
91void siop_dump_script(struct siop_softc *);
92#endif
93void siop_morecbd(struct siop_softc *);
94struct siop_lunsw *siop_get_lunsw(struct siop_softc *);
95void siop_add_reselsw(struct siop_softc *, int);
96void siop_update_scntl3(struct siop_softc *, struct siop_common_target *);
97
98struct siop_dmamem *siop_dmamem_alloc(struct siop_softc *, size_t);
99void siop_dmamem_free(struct siop_softc *, struct siop_dmamem *);
100
101struct cfdriver siop_cd = {
102 NULL((void *)0), "siop", DV_DULL
103};
104
105struct scsi_adapter siop_switch = {
106 siop_scsicmd, NULL((void *)0), siop_scsiprobe, siop_scsifree, NULL((void *)0)
107};
108
109#ifdef SIOP_STATS
110static int siop_stat_intr = 0;
111static int siop_stat_intr_shortxfer = 0;
112static int siop_stat_intr_sdp = 0;
113static int siop_stat_intr_saveoffset = 0;
114static int siop_stat_intr_done = 0;
115static int siop_stat_intr_xferdisc = 0;
116static int siop_stat_intr_lunresel = 0;
117static int siop_stat_intr_qfull = 0;
118void siop_printstats(void);
119#define INCSTAT(x) x++
120#else
121#define INCSTAT(x)
122#endif
123
124void
125siop_table_sync(struct siop_cmd *siop_cmd, int ops)
126{
127 struct siop_common_softc *sc = siop_cmd->cmd_c.siop_sc;
128 bus_addr_t offset;
129
130 offset = siop_cmd->cmd_c.dsa -
131 SIOP_DMA_DVA(siop_cmd->siop_cbdp->xfers)((siop_cmd->siop_cbdp->xfers)->sdm_map->dm_segs[0
].ds_addr)
;
132 bus_dmamap_sync(sc->sc_dmat,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (((siop_cmd
->siop_cbdp->xfers)->sdm_map)), (offset), (sizeof(struct
siop_xfer)), (ops))
133 SIOP_DMA_MAP(siop_cmd->siop_cbdp->xfers), offset,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (((siop_cmd
->siop_cbdp->xfers)->sdm_map)), (offset), (sizeof(struct
siop_xfer)), (ops))
134 sizeof(struct siop_xfer), ops)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (((siop_cmd
->siop_cbdp->xfers)->sdm_map)), (offset), (sizeof(struct
siop_xfer)), (ops))
;
135}
136
137void
138siop_script_sync(struct siop_softc *sc, int ops)
139{
140 if ((sc->sc_c.features & SF_CHIP_RAM0x00004000) == 0)
141 bus_dmamap_sync(sc->sc_c.sc_dmat, sc->sc_c.sc_scriptdma, 0,(*(sc->sc_c.sc_dmat)->_dmamap_sync)((sc->sc_c.sc_dmat
), (sc->sc_c.sc_scriptdma), (0), ((1 << 12)), (ops))
142 PAGE_SIZE, ops)(*(sc->sc_c.sc_dmat)->_dmamap_sync)((sc->sc_c.sc_dmat
), (sc->sc_c.sc_scriptdma), (0), ((1 << 12)), (ops))
;
143}
144
145u_int32_t
146siop_script_read(struct siop_softc *sc, u_int offset)
147{
148 if (sc->sc_c.features & SF_CHIP_RAM0x00004000) {
149 return bus_space_read_4(sc->sc_c.sc_ramt, sc->sc_c.sc_ramh,((sc->sc_c.sc_ramt)->read_4((sc->sc_c.sc_ramh), (offset
* 4)))
150 offset * 4)((sc->sc_c.sc_ramt)->read_4((sc->sc_c.sc_ramh), (offset
* 4)))
;
151 } else {
152 return siop_ctoh32(&sc->sc_c, sc->sc_c.sc_script[offset])(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((sc->sc_c.sc_script[offset])) ? (__uint32_t
)(((__uint32_t)((sc->sc_c.sc_script[offset])) & 0xff) <<
24 | ((__uint32_t)((sc->sc_c.sc_script[offset])) & 0xff00
) << 8 | ((__uint32_t)((sc->sc_c.sc_script[offset]))
& 0xff0000) >> 8 | ((__uint32_t)((sc->sc_c.sc_script
[offset])) & 0xff000000) >> 24) : __swap32md((sc->
sc_c.sc_script[offset]))) : ((__uint32_t)((sc->sc_c.sc_script
[offset]))))
;
153 }
154}
155
156void
157siop_script_write(struct siop_softc *sc, u_int offset, u_int32_t val)
158{
159 if (sc->sc_c.features & SF_CHIP_RAM0x00004000) {
160 bus_space_write_4(sc->sc_c.sc_ramt, sc->sc_c.sc_ramh,((sc->sc_c.sc_ramt)->write_4((sc->sc_c.sc_ramh), (offset
* 4), (val)))
161 offset * 4, val)((sc->sc_c.sc_ramt)->write_4((sc->sc_c.sc_ramh), (offset
* 4), (val)))
;
162 } else {
163 sc->sc_c.sc_script[offset] = siop_htoc32(&sc->sc_c, val)(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((val)) ? (__uint32_t)(((__uint32_t)((val
)) & 0xff) << 24 | ((__uint32_t)((val)) & 0xff00
) << 8 | ((__uint32_t)((val)) & 0xff0000) >> 8
| ((__uint32_t)((val)) & 0xff000000) >> 24) : __swap32md
((val))) : ((__uint32_t)((val))))
;
164 }
165}
166
167void
168siop_attach(struct siop_softc *sc)
169{
170 struct scsibus_attach_args saa;
171
172 if (siop_common_attach(&sc->sc_c) != 0)
173 return;
174
175 TAILQ_INIT(&sc->free_list)do { (&sc->free_list)->tqh_first = ((void *)0); (&
sc->free_list)->tqh_last = &(&sc->free_list)
->tqh_first; } while (0)
;
176 TAILQ_INIT(&sc->ready_list)do { (&sc->ready_list)->tqh_first = ((void *)0); (&
sc->ready_list)->tqh_last = &(&sc->ready_list
)->tqh_first; } while (0)
;
177 TAILQ_INIT(&sc->urgent_list)do { (&sc->urgent_list)->tqh_first = ((void *)0); (
&sc->urgent_list)->tqh_last = &(&sc->urgent_list
)->tqh_first; } while (0)
;
178 TAILQ_INIT(&sc->cmds)do { (&sc->cmds)->tqh_first = ((void *)0); (&sc
->cmds)->tqh_last = &(&sc->cmds)->tqh_first
; } while (0)
;
179 TAILQ_INIT(&sc->lunsw_list)do { (&sc->lunsw_list)->tqh_first = ((void *)0); (&
sc->lunsw_list)->tqh_last = &(&sc->lunsw_list
)->tqh_first; } while (0)
;
180 scsi_iopool_init(&sc->iopool, sc, siop_cmd_get, siop_cmd_put);
181 sc->sc_currschedslot = 0;
182
183 /* Start with one page worth of commands */
184 siop_morecbd(sc);
185
186#ifdef SIOP_DEBUG
187 printf("%s: script size = %d, PHY addr=0x%x, VIRT=%p\n",
188 sc->sc_c.sc_dev.dv_xname, (int)sizeof(siop_script),
189 (u_int32_t)sc->sc_c.sc_scriptaddr, sc->sc_c.sc_script);
190#endif
191
192 /* Do a bus reset, so that devices fall back to narrow/async */
193 siop_resetbus(&sc->sc_c);
194 /*
195 * siop_reset() will reset the chip, thus clearing pending interrupts
196 */
197 siop_reset(sc);
198#ifdef DUMP_SCRIPT
199 siop_dump_script(sc);
200#endif
201
202 saa.saa_adapter_softc = sc;
203 saa.saa_adapter = &siop_switch;
204 saa.saa_adapter_target = sc->sc_c.sc_id;
205 saa.saa_adapter_buswidth = (sc->sc_c.features & SF_BUS_WIDE0x00000001) ? 16 : 8;
206 saa.saa_luns = 8;
207 saa.saa_openings = SIOP_NTAG16;
208 saa.saa_pool = &sc->iopool;
209 saa.saa_quirks = saa.saa_flags = 0;
210 saa.saa_wwpn = saa.saa_wwnn = 0;
211
212 config_found((struct device*)sc, &saa, scsiprint)config_found_sm(((struct device*)sc), (&saa), (scsiprint)
, ((void *)0))
;
213}
214
215void
216siop_reset(struct siop_softc *sc)
217{
218 int i, j, buswidth;
219 struct siop_lunsw *lunsw;
220
221 siop_common_reset(&sc->sc_c);
222
223 /* copy and patch the script */
224 if (sc->sc_c.features & SF_CHIP_RAM0x00004000) {
225 bus_space_write_region_4(sc->sc_c.sc_ramt, sc->sc_c.sc_ramh, 0,((sc->sc_c.sc_ramt)->write_region_4((sc->sc_c.sc_ramh
), (0), (siop_script), (sizeof(siop_script) / sizeof(siop_script
[0]))))
226 siop_script, sizeof(siop_script) / sizeof(siop_script[0]))((sc->sc_c.sc_ramt)->write_region_4((sc->sc_c.sc_ramh
), (0), (siop_script), (sizeof(siop_script) / sizeof(siop_script
[0]))))
;
227 for (j = 0; j <
228 (sizeof(E_abs_msgin_Used) / sizeof(E_abs_msgin_Used[0]));
229 j++) {
230 bus_space_write_4(sc->sc_c.sc_ramt, sc->sc_c.sc_ramh,((sc->sc_c.sc_ramt)->write_4((sc->sc_c.sc_ramh), (E_abs_msgin_Used
[j] * 4), (sc->sc_c.sc_scriptaddr + 0x00000598)))
231 E_abs_msgin_Used[j] * 4,((sc->sc_c.sc_ramt)->write_4((sc->sc_c.sc_ramh), (E_abs_msgin_Used
[j] * 4), (sc->sc_c.sc_scriptaddr + 0x00000598)))
232 sc->sc_c.sc_scriptaddr + Ent_msgin_space)((sc->sc_c.sc_ramt)->write_4((sc->sc_c.sc_ramh), (E_abs_msgin_Used
[j] * 4), (sc->sc_c.sc_scriptaddr + 0x00000598)))
;
233 }
234 if (sc->sc_c.features & SF_CHIP_LED00x00000100) {
235 bus_space_write_region_4(sc->sc_c.sc_ramt,((sc->sc_c.sc_ramt)->write_region_4((sc->sc_c.sc_ramh
), (0x00000068), (siop_led_on), (sizeof(siop_led_on) / sizeof
(siop_led_on[0]))))
236 sc->sc_c.sc_ramh,((sc->sc_c.sc_ramt)->write_region_4((sc->sc_c.sc_ramh
), (0x00000068), (siop_led_on), (sizeof(siop_led_on) / sizeof
(siop_led_on[0]))))
237 Ent_led_on1, siop_led_on,((sc->sc_c.sc_ramt)->write_region_4((sc->sc_c.sc_ramh
), (0x00000068), (siop_led_on), (sizeof(siop_led_on) / sizeof
(siop_led_on[0]))))
238 sizeof(siop_led_on) / sizeof(siop_led_on[0]))((sc->sc_c.sc_ramt)->write_region_4((sc->sc_c.sc_ramh
), (0x00000068), (siop_led_on), (sizeof(siop_led_on) / sizeof
(siop_led_on[0]))))
;
239 bus_space_write_region_4(sc->sc_c.sc_ramt,((sc->sc_c.sc_ramt)->write_region_4((sc->sc_c.sc_ramh
), (0x00000220), (siop_led_on), (sizeof(siop_led_on) / sizeof
(siop_led_on[0]))))
240 sc->sc_c.sc_ramh,((sc->sc_c.sc_ramt)->write_region_4((sc->sc_c.sc_ramh
), (0x00000220), (siop_led_on), (sizeof(siop_led_on) / sizeof
(siop_led_on[0]))))
241 Ent_led_on2, siop_led_on,((sc->sc_c.sc_ramt)->write_region_4((sc->sc_c.sc_ramh
), (0x00000220), (siop_led_on), (sizeof(siop_led_on) / sizeof
(siop_led_on[0]))))
242 sizeof(siop_led_on) / sizeof(siop_led_on[0]))((sc->sc_c.sc_ramt)->write_region_4((sc->sc_c.sc_ramh
), (0x00000220), (siop_led_on), (sizeof(siop_led_on) / sizeof
(siop_led_on[0]))))
;
243 bus_space_write_region_4(sc->sc_c.sc_ramt,((sc->sc_c.sc_ramt)->write_region_4((sc->sc_c.sc_ramh
), (0x00000210), (siop_led_off), (sizeof(siop_led_off) / sizeof
(siop_led_off[0]))))
244 sc->sc_c.sc_ramh,((sc->sc_c.sc_ramt)->write_region_4((sc->sc_c.sc_ramh
), (0x00000210), (siop_led_off), (sizeof(siop_led_off) / sizeof
(siop_led_off[0]))))
245 Ent_led_off, siop_led_off,((sc->sc_c.sc_ramt)->write_region_4((sc->sc_c.sc_ramh
), (0x00000210), (siop_led_off), (sizeof(siop_led_off) / sizeof
(siop_led_off[0]))))
246 sizeof(siop_led_off) / sizeof(siop_led_off[0]))((sc->sc_c.sc_ramt)->write_region_4((sc->sc_c.sc_ramh
), (0x00000210), (siop_led_off), (sizeof(siop_led_off) / sizeof
(siop_led_off[0]))))
;
247 }
248 } else {
249 for (j = 0;
250 j < (sizeof(siop_script) / sizeof(siop_script[0])); j++) {
251 sc->sc_c.sc_script[j] =
252 siop_htoc32(&sc->sc_c, siop_script[j])(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((siop_script[j])) ? (__uint32_t)(((__uint32_t
)((siop_script[j])) & 0xff) << 24 | ((__uint32_t)((
siop_script[j])) & 0xff00) << 8 | ((__uint32_t)((siop_script
[j])) & 0xff0000) >> 8 | ((__uint32_t)((siop_script
[j])) & 0xff000000) >> 24) : __swap32md((siop_script
[j]))) : ((__uint32_t)((siop_script[j]))))
;
253 }
254 for (j = 0; j <
255 (sizeof(E_abs_msgin_Used) / sizeof(E_abs_msgin_Used[0]));
256 j++) {
257 sc->sc_c.sc_script[E_abs_msgin_Used[j]] =
258 siop_htoc32(&sc->sc_c,(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((sc->sc_c.sc_scriptaddr + 0x00000598
)) ? (__uint32_t)(((__uint32_t)((sc->sc_c.sc_scriptaddr + 0x00000598
)) & 0xff) << 24 | ((__uint32_t)((sc->sc_c.sc_scriptaddr
+ 0x00000598)) & 0xff00) << 8 | ((__uint32_t)((sc->
sc_c.sc_scriptaddr + 0x00000598)) & 0xff0000) >> 8 |
((__uint32_t)((sc->sc_c.sc_scriptaddr + 0x00000598)) &
0xff000000) >> 24) : __swap32md((sc->sc_c.sc_scriptaddr
+ 0x00000598))) : ((__uint32_t)((sc->sc_c.sc_scriptaddr +
0x00000598))))
259 sc->sc_c.sc_scriptaddr + Ent_msgin_space)(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((sc->sc_c.sc_scriptaddr + 0x00000598
)) ? (__uint32_t)(((__uint32_t)((sc->sc_c.sc_scriptaddr + 0x00000598
)) & 0xff) << 24 | ((__uint32_t)((sc->sc_c.sc_scriptaddr
+ 0x00000598)) & 0xff00) << 8 | ((__uint32_t)((sc->
sc_c.sc_scriptaddr + 0x00000598)) & 0xff0000) >> 8 |
((__uint32_t)((sc->sc_c.sc_scriptaddr + 0x00000598)) &
0xff000000) >> 24) : __swap32md((sc->sc_c.sc_scriptaddr
+ 0x00000598))) : ((__uint32_t)((sc->sc_c.sc_scriptaddr +
0x00000598))))
;
260 }
261 if (sc->sc_c.features & SF_CHIP_LED00x00000100) {
262 for (j = 0; j < (sizeof(siop_led_on) /
263 sizeof(siop_led_on[0])); j++)
264 sc->sc_c.sc_script[
265 Ent_led_on10x00000068 / sizeof(siop_led_on[0]) + j
266 ] = siop_htoc32(&sc->sc_c, siop_led_on[j])(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((siop_led_on[j])) ? (__uint32_t)(((__uint32_t
)((siop_led_on[j])) & 0xff) << 24 | ((__uint32_t)((
siop_led_on[j])) & 0xff00) << 8 | ((__uint32_t)((siop_led_on
[j])) & 0xff0000) >> 8 | ((__uint32_t)((siop_led_on
[j])) & 0xff000000) >> 24) : __swap32md((siop_led_on
[j]))) : ((__uint32_t)((siop_led_on[j]))))
;
267 for (j = 0; j < (sizeof(siop_led_on) /
268 sizeof(siop_led_on[0])); j++)
269 sc->sc_c.sc_script[
270 Ent_led_on20x00000220 / sizeof(siop_led_on[0]) + j
271 ] = siop_htoc32(&sc->sc_c, siop_led_on[j])(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((siop_led_on[j])) ? (__uint32_t)(((__uint32_t
)((siop_led_on[j])) & 0xff) << 24 | ((__uint32_t)((
siop_led_on[j])) & 0xff00) << 8 | ((__uint32_t)((siop_led_on
[j])) & 0xff0000) >> 8 | ((__uint32_t)((siop_led_on
[j])) & 0xff000000) >> 24) : __swap32md((siop_led_on
[j]))) : ((__uint32_t)((siop_led_on[j]))))
;
272 for (j = 0; j < (sizeof(siop_led_off) /
273 sizeof(siop_led_off[0])); j++)
274 sc->sc_c.sc_script[
275 Ent_led_off0x00000210 / sizeof(siop_led_off[0]) + j
276 ] = siop_htoc32(&sc->sc_c, siop_led_off[j])(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((siop_led_off[j])) ? (__uint32_t)(((__uint32_t
)((siop_led_off[j])) & 0xff) << 24 | ((__uint32_t)(
(siop_led_off[j])) & 0xff00) << 8 | ((__uint32_t)((
siop_led_off[j])) & 0xff0000) >> 8 | ((__uint32_t)(
(siop_led_off[j])) & 0xff000000) >> 24) : __swap32md
((siop_led_off[j]))) : ((__uint32_t)((siop_led_off[j]))))
;
277 }
278 }
279 sc->script_free_lo = sizeof(siop_script) / sizeof(siop_script[0]);
280 sc->script_free_hi = sc->sc_c.ram_size / 4;
281 sc->sc_ntargets = 0;
282
283 /* free used and unused lun switches */
284 while((lunsw = TAILQ_FIRST(&sc->lunsw_list)((&sc->lunsw_list)->tqh_first)) != NULL((void *)0)) {
285#ifdef SIOP_DEBUG
286 printf("%s: free lunsw at offset %d\n",
287 sc->sc_c.sc_dev.dv_xname, lunsw->lunsw_off);
288#endif
289 TAILQ_REMOVE(&sc->lunsw_list, lunsw, next)do { if (((lunsw)->next.tqe_next) != ((void *)0)) (lunsw)->
next.tqe_next->next.tqe_prev = (lunsw)->next.tqe_prev; else
(&sc->lunsw_list)->tqh_last = (lunsw)->next.tqe_prev
; *(lunsw)->next.tqe_prev = (lunsw)->next.tqe_next; ((lunsw
)->next.tqe_prev) = ((void *)-1); ((lunsw)->next.tqe_next
) = ((void *)-1); } while (0)
;
290 free(lunsw, M_DEVBUF2, 0);
291 }
292 TAILQ_INIT(&sc->lunsw_list)do { (&sc->lunsw_list)->tqh_first = ((void *)0); (&
sc->lunsw_list)->tqh_last = &(&sc->lunsw_list
)->tqh_first; } while (0)
;
293 /* restore reselect switch */
294 buswidth = (sc->sc_c.features & SF_BUS_WIDE0x00000001) ? 16 : 8;
295 for (i = 0; i < buswidth; i++) {
296 struct siop_target *target;
297 if (sc->sc_c.targets[i] == NULL((void *)0))
298 continue;
299#ifdef SIOP_DEBUG
300 printf("%s: restore sw for target %d\n",
301 sc->sc_c.sc_dev.dv_xname, i);
302#endif
303 target = (struct siop_target *)sc->sc_c.targets[i];
304 free(target->lunsw, M_DEVBUF2, 0);
305 target->lunsw = siop_get_lunsw(sc);
306 if (target->lunsw == NULL((void *)0)) {
307 printf("%s: can't alloc lunsw for target %d\n",
308 sc->sc_c.sc_dev.dv_xname, i);
309 break;
310 }
311 siop_add_reselsw(sc, i);
312 }
313
314 /* start script */
315 if ((sc->sc_c.features & SF_CHIP_RAM0x00004000) == 0) {
316 bus_dmamap_sync(sc->sc_c.sc_dmat, sc->sc_c.sc_scriptdma, 0,(*(sc->sc_c.sc_dmat)->_dmamap_sync)((sc->sc_c.sc_dmat
), (sc->sc_c.sc_scriptdma), (0), ((1 << 12)), (0x01 |
0x04))
317 PAGE_SIZE, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE)(*(sc->sc_c.sc_dmat)->_dmamap_sync)((sc->sc_c.sc_dmat
), (sc->sc_c.sc_scriptdma), (0), ((1 << 12)), (0x01 |
0x04))
;
318 }
319 bus_space_write_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_DSP,((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C),
(sc->sc_c.sc_scriptaddr + 0x000001e0)))
320 sc->sc_c.sc_scriptaddr + Ent_reselect)((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C),
(sc->sc_c.sc_scriptaddr + 0x000001e0)))
;
321}
322
323#if 0
324#define CALL_SCRIPT(ent)do {((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C
), (sc->sc_c.sc_scriptaddr + ent))); } while (0)
do {\
325 printf ("start script DSA 0x%lx DSP 0x%lx\n", \
326 siop_cmd->cmd_c.dsa, \
327 sc->sc_c.sc_scriptaddr + ent); \((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C),
(sc->sc_c.sc_scriptaddr + ent)))
328bus_space_write_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_DSP, sc->sc_c.sc_scriptaddr + ent)((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C),
(sc->sc_c.sc_scriptaddr + ent)))
; \
329} while (0)
330#else
331#define CALL_SCRIPT(ent)do {((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C
), (sc->sc_c.sc_scriptaddr + ent))); } while (0)
do {\((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C),
(sc->sc_c.sc_scriptaddr + ent)))
332bus_space_write_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_DSP, sc->sc_c.sc_scriptaddr + ent)((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C),
(sc->sc_c.sc_scriptaddr + ent)))
; \
333} while (0)
334#endif
335
336int
337siop_intr(void *v)
338{
339 struct siop_softc *sc = v;
340 struct siop_target *siop_target;
341 struct siop_cmd *siop_cmd;
342 struct siop_lun *siop_lun;
343 struct scsi_xfer *xs;
344 int istat, sist, sstat1, dstat = 0;
345 u_int32_t irqcode;
346 int need_reset = 0;
347 int offset, target, lun, tag;
348 bus_addr_t dsa;
349 struct siop_cbd *cbdp;
350 int restart = 0;
351
352 istat = bus_space_read_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_ISTAT)((sc->sc_c.sc_rt)->read_1((sc->sc_c.sc_rh), (0x14)));
353 if ((istat & (ISTAT_INTF0x04 | ISTAT_DIP0x01 | ISTAT_SIP0x02)) == 0)
1
Assuming the condition is false
2
Taking false branch
354 return 0;
355 INCSTAT(siop_stat_intr);
356 if (istat & ISTAT_INTF0x04) {
3
Assuming the condition is false
4
Taking false branch
357 printf("INTRF\n");
358 bus_space_write_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh,((sc->sc_c.sc_rt)->write_1((sc->sc_c.sc_rh), (0x14),
(0x04)))
359 SIOP_ISTAT, ISTAT_INTF)((sc->sc_c.sc_rt)->write_1((sc->sc_c.sc_rh), (0x14),
(0x04)))
;
360 }
361 if ((istat &(ISTAT_DIP0x01 | ISTAT_SIP0x02 | ISTAT_ABRT0x80)) ==
5
Assuming the condition is false
6
Taking false branch
362 (ISTAT_DIP0x01 | ISTAT_ABRT0x80)) {
363 /* clear abort */
364 bus_space_write_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh,((sc->sc_c.sc_rt)->write_1((sc->sc_c.sc_rh), (0x14),
(0)))
365 SIOP_ISTAT, 0)((sc->sc_c.sc_rt)->write_1((sc->sc_c.sc_rh), (0x14),
(0)))
;
366 }
367 /* use DSA to find the current siop_cmd */
368 siop_cmd = NULL((void *)0);
7
Null pointer value stored to 'siop_cmd'
369 dsa = bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_DSA)((sc->sc_c.sc_rt)->read_4((sc->sc_c.sc_rh), (0x10)));
370 TAILQ_FOREACH(cbdp, &sc->cmds, next)for((cbdp) = ((&sc->cmds)->tqh_first); (cbdp) != ((
void *)0); (cbdp) = ((cbdp)->next.tqe_next))
{
8
Assuming 'cbdp' is equal to null
9
Loop condition is false. Execution continues on line 380
371 if (dsa >= SIOP_DMA_DVA(cbdp->xfers)((cbdp->xfers)->sdm_map->dm_segs[0].ds_addr) &&
372 dsa < SIOP_DMA_DVA(cbdp->xfers)((cbdp->xfers)->sdm_map->dm_segs[0].ds_addr) + PAGE_SIZE(1 << 12)) {
373 dsa -= SIOP_DMA_DVA(cbdp->xfers)((cbdp->xfers)->sdm_map->dm_segs[0].ds_addr);
374 siop_cmd = &cbdp->cmds[dsa / sizeof(struct siop_xfer)];
375 siop_table_sync(siop_cmd,
376 BUS_DMASYNC_POSTREAD0x02 | BUS_DMASYNC_POSTWRITE0x08);
377 break;
378 }
379 }
380 if (siop_cmd
9.1
'siop_cmd' is null
) {
10
Taking false branch
381 xs = siop_cmd->cmd_c.xs;
382 siop_target = (struct siop_target *)siop_cmd->cmd_c.siop_target;
383 target = siop_cmd->cmd_c.xs->sc_link->target;
384 lun = siop_cmd->cmd_c.xs->sc_link->lun;
385 tag = siop_cmd->cmd_c.tag;
386 siop_lun = siop_target->siop_lun[lun];
387#ifdef DIAGNOSTIC1
388 if (siop_cmd->cmd_c.status != CMDST_ACTIVE2 &&
389 siop_cmd->cmd_c.status != CMDST_SENSE_ACTIVE4) {
390 printf("siop_cmd (lun %d) for DSA 0x%x "
391 "not active (%d)\n", lun, (u_int)dsa,
392 siop_cmd->cmd_c.status);
393 xs = NULL((void *)0);
394 siop_target = NULL((void *)0);
395 target = -1;
396 lun = -1;
397 tag = -1;
398 siop_lun = NULL((void *)0);
399 siop_cmd = NULL((void *)0);
400 } else if (siop_lun->siop_tag[tag].active != siop_cmd) {
401 printf("siop_cmd (lun %d tag %d) not in siop_lun "
402 "active (%p != %p)\n", lun, tag, siop_cmd,
403 siop_lun->siop_tag[tag].active);
404 }
405#endif
406 } else {
407 xs = NULL((void *)0);
408 siop_target = NULL((void *)0);
409 target = -1;
410 lun = -1;
411 tag = -1;
412 siop_lun = NULL((void *)0);
413 }
414 if (istat & ISTAT_DIP0x01) {
11
Assuming the condition is true
12
Taking true branch
415 dstat = bus_space_read_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh,((sc->sc_c.sc_rt)->read_1((sc->sc_c.sc_rh), (0x0C)))
416 SIOP_DSTAT)((sc->sc_c.sc_rt)->read_1((sc->sc_c.sc_rh), (0x0C)));
417 if (dstat & DSTAT_ABRT0x10) {
13
Assuming the condition is false
14
Taking false branch
418 /* was probably generated by a bus reset IOCTL */
419 if ((dstat & DSTAT_DFE0x80) == 0)
420 siop_clearfifo(&sc->sc_c);
421 goto reset;
422 }
423 if (dstat & DSTAT_SSI0x08) {
15
Assuming the condition is false
16
Taking false branch
424 printf("single step dsp 0x%08x dsa 0x08%x\n",
425 (int)(bus_space_read_4(sc->sc_c.sc_rt,((sc->sc_c.sc_rt)->read_4((sc->sc_c.sc_rh), (0x2C)))
426 sc->sc_c.sc_rh, SIOP_DSP)((sc->sc_c.sc_rt)->read_4((sc->sc_c.sc_rh), (0x2C))) -
427 sc->sc_c.sc_scriptaddr),
428 bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh,((sc->sc_c.sc_rt)->read_4((sc->sc_c.sc_rh), (0x10)))
429 SIOP_DSA)((sc->sc_c.sc_rt)->read_4((sc->sc_c.sc_rh), (0x10))));
430 if ((dstat & ~(DSTAT_DFE0x80 | DSTAT_SSI0x08)) == 0 &&
431 (istat & ISTAT_SIP0x02) == 0) {
432 bus_space_write_1(sc->sc_c.sc_rt,((sc->sc_c.sc_rt)->write_1((sc->sc_c.sc_rh), (0x3B),
(((sc->sc_c.sc_rt)->read_1((sc->sc_c.sc_rh), (0x3B)
)) | 0x04)))
433 sc->sc_c.sc_rh, SIOP_DCNTL,((sc->sc_c.sc_rt)->write_1((sc->sc_c.sc_rh), (0x3B),
(((sc->sc_c.sc_rt)->read_1((sc->sc_c.sc_rh), (0x3B)
)) | 0x04)))
434 bus_space_read_1(sc->sc_c.sc_rt,((sc->sc_c.sc_rt)->write_1((sc->sc_c.sc_rh), (0x3B),
(((sc->sc_c.sc_rt)->read_1((sc->sc_c.sc_rh), (0x3B)
)) | 0x04)))
435 sc->sc_c.sc_rh, SIOP_DCNTL) | DCNTL_STD)((sc->sc_c.sc_rt)->write_1((sc->sc_c.sc_rh), (0x3B),
(((sc->sc_c.sc_rt)->read_1((sc->sc_c.sc_rh), (0x3B)
)) | 0x04)))
;
436 }
437 return 1;
438 }
439
440 if (dstat & ~(DSTAT_SIR0x04 | DSTAT_DFE0x80 | DSTAT_SSI0x08)) {
17
Assuming the condition is false
18
Taking false branch
441 printf("%s: DMA IRQ:", sc->sc_c.sc_dev.dv_xname);
442 if (dstat & DSTAT_IID0x01)
443 printf(" illegal instruction");
444 if (dstat & DSTAT_BF0x20)
445 printf(" bus fault");
446 if (dstat & DSTAT_MDPE0x40)
447 printf(" parity");
448 if (dstat & DSTAT_DFE0x80)
449 printf(" DMA fifo empty");
450 else
451 siop_clearfifo(&sc->sc_c);
452 printf(", DSP=0x%x DSA=0x%x: ",
453 (int)(bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh,((sc->sc_c.sc_rt)->read_4((sc->sc_c.sc_rh), (0x2C)))
454 SIOP_DSP)((sc->sc_c.sc_rt)->read_4((sc->sc_c.sc_rh), (0x2C))) - sc->sc_c.sc_scriptaddr),
455 bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_DSA)((sc->sc_c.sc_rt)->read_4((sc->sc_c.sc_rh), (0x10))));
456 if (siop_cmd)
457 printf("last msg_in=0x%x status=0x%x\n",
458 siop_cmd->cmd_tablescmd_c.siop_tables->msg_in[0],
459 siop_ctoh32(&sc->sc_c,(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((siop_cmd->cmd_c.siop_tables->status
)) ? (__uint32_t)(((__uint32_t)((siop_cmd->cmd_c.siop_tables
->status)) & 0xff) << 24 | ((__uint32_t)((siop_cmd
->cmd_c.siop_tables->status)) & 0xff00) << 8 |
((__uint32_t)((siop_cmd->cmd_c.siop_tables->status)) &
0xff0000) >> 8 | ((__uint32_t)((siop_cmd->cmd_c.siop_tables
->status)) & 0xff000000) >> 24) : __swap32md((siop_cmd
->cmd_c.siop_tables->status))) : ((__uint32_t)((siop_cmd
->cmd_c.siop_tables->status))))
460 siop_cmd->cmd_tables->status)(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((siop_cmd->cmd_c.siop_tables->status
)) ? (__uint32_t)(((__uint32_t)((siop_cmd->cmd_c.siop_tables
->status)) & 0xff) << 24 | ((__uint32_t)((siop_cmd
->cmd_c.siop_tables->status)) & 0xff00) << 8 |
((__uint32_t)((siop_cmd->cmd_c.siop_tables->status)) &
0xff0000) >> 8 | ((__uint32_t)((siop_cmd->cmd_c.siop_tables
->status)) & 0xff000000) >> 24) : __swap32md((siop_cmd
->cmd_c.siop_tables->status))) : ((__uint32_t)((siop_cmd
->cmd_c.siop_tables->status))))
);
461 else
462 printf("current DSA invalid\n");
463 need_reset = 1;
464 }
465 }
466 if (istat & ISTAT_SIP0x02) {
19
Assuming the condition is false
20
Taking false branch
467 if (istat & ISTAT_DIP0x01)
468 delay(10)(*delay_func)(10);
469 /*
470 * Can't read sist0 & sist1 independently, or we have to
471 * insert delay
472 */
473 sist = bus_space_read_2(sc->sc_c.sc_rt, sc->sc_c.sc_rh,((sc->sc_c.sc_rt)->read_2((sc->sc_c.sc_rh), (0x42)))
474 SIOP_SIST0)((sc->sc_c.sc_rt)->read_2((sc->sc_c.sc_rh), (0x42)));
475 sstat1 = bus_space_read_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh,((sc->sc_c.sc_rt)->read_1((sc->sc_c.sc_rh), (0x0E)))
476 SIOP_SSTAT1)((sc->sc_c.sc_rt)->read_1((sc->sc_c.sc_rh), (0x0E)));
477#ifdef SIOP_DEBUG_INTR
478 printf("scsi interrupt, sist=0x%x sstat1=0x%x "
479 "DSA=0x%x DSP=0x%lx\n", sist, sstat1,
480 bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_DSA)((sc->sc_c.sc_rt)->read_4((sc->sc_c.sc_rh), (0x10))),
481 (u_long)(bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh,((sc->sc_c.sc_rt)->read_4((sc->sc_c.sc_rh), (0x2C)))
482 SIOP_DSP)((sc->sc_c.sc_rt)->read_4((sc->sc_c.sc_rh), (0x2C))) -
483 sc->sc_c.sc_scriptaddr));
484#endif
485 if (sist & SIST0_RST0x02) {
486 siop_handle_reset(sc);
487 siop_start(sc);
488 /* no table to flush here */
489 return 1;
490 }
491 if (sist & SIST0_SGE0x08) {
492 if (siop_cmd)
493 sc_print_addr(xs->sc_link);
494 else
495 printf("%s: ", sc->sc_c.sc_dev.dv_xname);
496 printf("scsi gross error\n");
497 goto reset;
498 }
499 if ((sist & SIST0_MA0x80) && need_reset == 0) {
500 if (siop_cmd) {
501 int scratcha0;
502 /* XXX Why read DSTAT again? */
503 dstat = bus_space_read_1(sc->sc_c.sc_rt,((sc->sc_c.sc_rt)->read_1((sc->sc_c.sc_rh), (0x0C)))
504 sc->sc_c.sc_rh, SIOP_DSTAT)((sc->sc_c.sc_rt)->read_1((sc->sc_c.sc_rh), (0x0C)));
505 /*
506 * first restore DSA, in case we were in a S/G
507 * operation.
508 */
509 bus_space_write_4(sc->sc_c.sc_rt,((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x10),
(siop_cmd->cmd_c.dsa)))
510 sc->sc_c.sc_rh,((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x10),
(siop_cmd->cmd_c.dsa)))
511 SIOP_DSA, siop_cmd->cmd_c.dsa)((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x10),
(siop_cmd->cmd_c.dsa)))
;
512 scratcha0 = bus_space_read_1(sc->sc_c.sc_rt,((sc->sc_c.sc_rt)->read_1((sc->sc_c.sc_rh), (0x34)))
513 sc->sc_c.sc_rh, SIOP_SCRATCHA)((sc->sc_c.sc_rt)->read_1((sc->sc_c.sc_rh), (0x34)));
514 switch (sstat1 & SSTAT1_PHASE_MASK(0x01 | 0x02 | 0x04)) {
515 case SSTAT1_PHASE_STATUS(0x02 | 0x01):
516 /*
517 * previous phase may be aborted for any reason
518 * ( for example, the target has less data to
519 * transfer than requested). Compute resid and
520 * just go to status, the command should
521 * terminate.
522 */
523 INCSTAT(siop_stat_intr_shortxfer);
524 if (scratcha0 & A_flag_data0x00000002)
525 siop_ma(&siop_cmd->cmd_c);
526 else if ((dstat & DSTAT_DFE0x80) == 0)
527 siop_clearfifo(&sc->sc_c);
528 CALL_SCRIPT(Ent_status)do {((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C
), (sc->sc_c.sc_scriptaddr + 0x000003d0))); } while (0)
;
529 return 1;
530 case SSTAT1_PHASE_MSGIN(0x04 | 0x02 | 0x01):
531 /*
532 * target may be ready to disconnect
533 * Compute resid which would be used later
534 * if a save data pointer is needed.
535 */
536 INCSTAT(siop_stat_intr_xferdisc);
537 if (scratcha0 & A_flag_data0x00000002)
538 siop_ma(&siop_cmd->cmd_c);
539 else if ((dstat & DSTAT_DFE0x80) == 0)
540 siop_clearfifo(&sc->sc_c);
541 bus_space_write_1(sc->sc_c.sc_rt,((sc->sc_c.sc_rt)->write_1((sc->sc_c.sc_rh), (0x34),
(scratcha0 & ~0x00000002)))
542 sc->sc_c.sc_rh, SIOP_SCRATCHA,((sc->sc_c.sc_rt)->write_1((sc->sc_c.sc_rh), (0x34),
(scratcha0 & ~0x00000002)))
543 scratcha0 & ~A_flag_data)((sc->sc_c.sc_rt)->write_1((sc->sc_c.sc_rh), (0x34),
(scratcha0 & ~0x00000002)))
;
544 CALL_SCRIPT(Ent_msgin)do {((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C
), (sc->sc_c.sc_scriptaddr + 0x00000328))); } while (0)
;
545 return 1;
546 }
547 printf("%s: unexpected phase mismatch %d\n",
548 sc->sc_c.sc_dev.dv_xname,
549 sstat1 & SSTAT1_PHASE_MASK(0x01 | 0x02 | 0x04));
550 } else {
551 printf("%s: phase mismatch without command\n",
552 sc->sc_c.sc_dev.dv_xname);
553 }
554 need_reset = 1;
555 }
556 if (sist & SIST0_PAR0x01) {
557 /* parity error, reset */
558 if (siop_cmd)
559 sc_print_addr(xs->sc_link);
560 else
561 printf("%s: ", sc->sc_c.sc_dev.dv_xname);
562 printf("parity error\n");
563 goto reset;
564 }
565 if ((sist & (SIST1_STO0x04 << 8)) && need_reset == 0) {
566 /* selection time out, assume there's no device here */
567 if (siop_cmd) {
568 siop_cmd->cmd_c.status = CMDST_DONE6;
569 xs->error = XS_SELTIMEOUT3;
570 goto end;
571 } else {
572 printf("%s: selection timeout without "
573 "command\n", sc->sc_c.sc_dev.dv_xname);
574 need_reset = 1;
575 }
576 }
577 if (sist & SIST0_UDC0x04) {
578 /*
579 * unexpected disconnect. Usually the target signals
580 * a fatal condition this way. Attempt to get sense.
581 */
582 if (siop_cmd) {
583 siop_cmd->cmd_tablescmd_c.siop_tables->status =
584 siop_htoc32(&sc->sc_c, SCSI_CHECK)(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((0x02)) ? (__uint32_t)(((__uint32_t)((
0x02)) & 0xff) << 24 | ((__uint32_t)((0x02)) & 0xff00
) << 8 | ((__uint32_t)((0x02)) & 0xff0000) >>
8 | ((__uint32_t)((0x02)) & 0xff000000) >> 24) : __swap32md
((0x02))) : ((__uint32_t)((0x02))))
;
585 goto end;
586 }
587 printf("%s: unexpected disconnect without "
588 "command\n", sc->sc_c.sc_dev.dv_xname);
589 goto reset;
590 }
591 if (sist & (SIST1_SBMC0x10 << 8)) {
592 /* SCSI bus mode change */
593 if (siop_modechange(&sc->sc_c) == 0 || need_reset == 1)
594 goto reset;
595 if ((istat & ISTAT_DIP0x01) && (dstat & DSTAT_SIR0x04)) {
596 /*
597 * we have a script interrupt, it will
598 * restart the script.
599 */
600 goto scintr;
601 }
602 /*
603 * else we have to restart it ourselves, at the
604 * interrupted instruction.
605 */
606 bus_space_write_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh,((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C),
(((sc->sc_c.sc_rt)->read_4((sc->sc_c.sc_rh), (0x2C)
)) - 8)))
607 SIOP_DSP,((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C),
(((sc->sc_c.sc_rt)->read_4((sc->sc_c.sc_rh), (0x2C)
)) - 8)))
608 bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh,((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C),
(((sc->sc_c.sc_rt)->read_4((sc->sc_c.sc_rh), (0x2C)
)) - 8)))
609 SIOP_DSP) - 8)((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C),
(((sc->sc_c.sc_rt)->read_4((sc->sc_c.sc_rh), (0x2C)
)) - 8)))
;
610 return 1;
611 }
612 /* Else it's an unhandled exception (for now). */
613 printf("%s: unhandled scsi interrupt, sist=0x%x sstat1=0x%x "
614 "DSA=0x%x DSP=0x%x\n", sc->sc_c.sc_dev.dv_xname,
615 sist, sstat1,
616 bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_DSA)((sc->sc_c.sc_rt)->read_4((sc->sc_c.sc_rh), (0x10))),
617 (int)(bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh,((sc->sc_c.sc_rt)->read_4((sc->sc_c.sc_rh), (0x2C)))
618 SIOP_DSP)((sc->sc_c.sc_rt)->read_4((sc->sc_c.sc_rh), (0x2C))) - sc->sc_c.sc_scriptaddr));
619 if (siop_cmd) {
620 siop_cmd->cmd_c.status = CMDST_DONE6;
621 xs->error = XS_SELTIMEOUT3;
622 goto end;
623 }
624 need_reset = 1;
625 } else {
626 sist = sstat1 = 0;
627 }
628 if (need_reset
20.1
'need_reset' is 0
) {
21
Taking false branch
629reset:
630 /* fatal error, reset the bus */
631 siop_resetbus(&sc->sc_c);
632 /* no table to flush here */
633 return 1;
634 }
635
636scintr:
637 if ((istat & ISTAT_DIP0x01) && (dstat & DSTAT_SIR0x04)) { /* script interrupt */
22
Assuming the condition is true
23
Taking true branch
638 irqcode = bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh,((sc->sc_c.sc_rt)->read_4((sc->sc_c.sc_rh), (0x30)))
639 SIOP_DSPS)((sc->sc_c.sc_rt)->read_4((sc->sc_c.sc_rh), (0x30)));
640#ifdef SIOP_DEBUG_INTR
641 printf("script interrupt 0x%x\n", irqcode);
642#endif
643 /*
644 * no command, or an inactive command is only valid for a
645 * reselect interrupt
646 */
647 if ((irqcode & 0x80) == 0) {
24
Assuming the condition is false
25
Taking false branch
648 if (siop_cmd == NULL((void *)0)) {
649 printf(
650 "%s: script interrupt (0x%x) with invalid DSA !!!\n",
651 sc->sc_c.sc_dev.dv_xname, irqcode);
652 goto reset;
653 }
654 if (siop_cmd->cmd_c.status != CMDST_ACTIVE2 &&
655 siop_cmd->cmd_c.status != CMDST_SENSE_ACTIVE4) {
656 printf("%s: command with invalid status "
657 "(IRQ code 0x%x current status %d) !\n",
658 sc->sc_c.sc_dev.dv_xname,
659 irqcode, siop_cmd->cmd_c.status);
660 xs = NULL((void *)0);
661 }
662 }
663 switch(irqcode) {
26
Control jumps to 'case 65280:' at line 996
664 case A_int_err0x0000ffff:
665 printf("error, DSP=0x%x\n",
666 (int)(bus_space_read_4(sc->sc_c.sc_rt,((sc->sc_c.sc_rt)->read_4((sc->sc_c.sc_rh), (0x2C)))
667 sc->sc_c.sc_rh, SIOP_DSP)((sc->sc_c.sc_rt)->read_4((sc->sc_c.sc_rh), (0x2C))) - sc->sc_c.sc_scriptaddr));
668 if (xs) {
669 xs->error = XS_SELTIMEOUT3;
670 goto end;
671 } else {
672 goto reset;
673 }
674 case A_int_reseltarg0x0000ff80:
675 printf("%s: reselect with invalid target\n",
676 sc->sc_c.sc_dev.dv_xname);
677 goto reset;
678 case A_int_resellun0x0000ff81:
679 INCSTAT(siop_stat_intr_lunresel);
680 target = bus_space_read_1(sc->sc_c.sc_rt,((sc->sc_c.sc_rt)->read_1((sc->sc_c.sc_rh), (0x34)))
681 sc->sc_c.sc_rh, SIOP_SCRATCHA)((sc->sc_c.sc_rt)->read_1((sc->sc_c.sc_rh), (0x34))) & 0xf;
682 lun = bus_space_read_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh,((sc->sc_c.sc_rt)->read_1((sc->sc_c.sc_rh), (0x34 + 1
)))
683 SIOP_SCRATCHA + 1)((sc->sc_c.sc_rt)->read_1((sc->sc_c.sc_rh), (0x34 + 1
)))
;
684 tag = bus_space_read_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh,((sc->sc_c.sc_rt)->read_1((sc->sc_c.sc_rh), (0x34 + 2
)))
685 SIOP_SCRATCHA + 2)((sc->sc_c.sc_rt)->read_1((sc->sc_c.sc_rh), (0x34 + 2
)))
;
686 siop_target =
687 (struct siop_target *)sc->sc_c.targets[target];
688 if (siop_target == NULL((void *)0)) {
689 printf("%s: reselect with invalid target %d\n",
690 sc->sc_c.sc_dev.dv_xname, target);
691 goto reset;
692 }
693 siop_lun = siop_target->siop_lun[lun];
694 if (siop_lun == NULL((void *)0)) {
695 printf("%s: target %d reselect with invalid "
696 "lun %d\n", sc->sc_c.sc_dev.dv_xname,
697 target, lun);
698 goto reset;
699 }
700 if (siop_lun->siop_tag[tag].active == NULL((void *)0)) {
701 printf("%s: target %d lun %d tag %d reselect "
702 "without command\n",
703 sc->sc_c.sc_dev.dv_xname,
704 target, lun, tag);
705 goto reset;
706 }
707 siop_cmd = siop_lun->siop_tag[tag].active;
708 bus_space_write_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh,((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C),
(siop_cmd->cmd_c.dsa + sizeof(struct siop_common_xfer) + 0x00000028
)))
709 SIOP_DSP, siop_cmd->cmd_c.dsa +((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C),
(siop_cmd->cmd_c.dsa + sizeof(struct siop_common_xfer) + 0x00000028
)))
710 sizeof(struct siop_common_xfer) +((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C),
(siop_cmd->cmd_c.dsa + sizeof(struct siop_common_xfer) + 0x00000028
)))
711 Ent_ldsa_reload_dsa)((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C),
(siop_cmd->cmd_c.dsa + sizeof(struct siop_common_xfer) + 0x00000028
)))
;
712 siop_table_sync(siop_cmd, BUS_DMASYNC_PREWRITE0x04);
713 return 1;
714 case A_int_reseltag0x0000ff82:
715 printf("%s: reselect with invalid tag\n",
716 sc->sc_c.sc_dev.dv_xname);
717 goto reset;
718 case A_int_msgin0x0000ff01:
719 {
720 int msgin = bus_space_read_1(sc->sc_c.sc_rt,((sc->sc_c.sc_rt)->read_1((sc->sc_c.sc_rh), (0x08)))
721 sc->sc_c.sc_rh, SIOP_SFBR)((sc->sc_c.sc_rt)->read_1((sc->sc_c.sc_rh), (0x08)));
722 if (msgin == MSG_MESSAGE_REJECT0x07) {
723 int msg, extmsg;
724 if (siop_cmd->cmd_tablescmd_c.siop_tables->msg_out[0] & 0x80) {
725 /*
726 * message was part of a identify +
727 * something else. Identify shouldn't
728 * have been rejected.
729 */
730 msg =
731 siop_cmd->cmd_tablescmd_c.siop_tables->msg_out[1];
732 extmsg =
733 siop_cmd->cmd_tablescmd_c.siop_tables->msg_out[3];
734 } else {
735 msg = siop_cmd->cmd_tablescmd_c.siop_tables->msg_out[0];
736 extmsg =
737 siop_cmd->cmd_tablescmd_c.siop_tables->msg_out[2];
738 }
739 if (msg == MSG_MESSAGE_REJECT0x07) {
740 /* MSG_REJECT for a MSG_REJECT !*/
741 if (xs)
742 sc_print_addr(xs->sc_link);
743 else
744 printf("%s: ",
745 sc->sc_c.sc_dev.dv_xname);
746 printf("our reject message was "
747 "rejected\n");
748 goto reset;
749 }
750 if (msg == MSG_EXTENDED0x01 &&
751 extmsg == MSG_EXT_WDTR0x03) {
752 /* WDTR rejected, initiate sync */
753 if ((siop_target->target_c.flags &
754 TARF_SYNC0x01) == 0) {
755 siop_target->target_c.status =
756 TARST_OK5;
757 siop_update_xfer_mode(&sc->sc_c,
758 target);
759 /* no table to flush here */
760 CALL_SCRIPT(Ent_msgin_ack)do {((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C
), (sc->sc_c.sc_scriptaddr + 0x00000388))); } while (0)
;
761 return 1;
762 }
763 siop_target->target_c.status =
764 TARST_SYNC_NEG3;
765 siop_sdtr_msg(&siop_cmd->cmd_c, 0,
766 sc->sc_c.st_minsync,
767 sc->sc_c.maxoff);
768 siop_table_sync(siop_cmd,
769 BUS_DMASYNC_PREREAD0x01 |
770 BUS_DMASYNC_PREWRITE0x04);
771 CALL_SCRIPT(Ent_send_msgout)do {((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C
), (sc->sc_c.sc_scriptaddr + 0x00000398))); } while (0)
;
772 return 1;
773 } else if (msg == MSG_EXTENDED0x01 &&
774 extmsg == MSG_EXT_SDTR0x01) {
775 /* sync rejected */
776 siop_target->target_c.offset = 0;
777 siop_target->target_c.period = 0;
778 siop_target->target_c.status = TARST_OK5;
779 siop_update_xfer_mode(&sc->sc_c,
780 target);
781 /* no table to flush here */
782 CALL_SCRIPT(Ent_msgin_ack)do {((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C
), (sc->sc_c.sc_scriptaddr + 0x00000388))); } while (0)
;
783 return 1;
784 } else if (msg == MSG_EXTENDED0x01 &&
785 extmsg == MSG_EXT_PPR0x04) {
786 /* PPR negotiation rejected */
787 siop_target->target_c.offset = 0;
788 siop_target->target_c.period = 0;
789 siop_target->target_c.status = TARST_ASYNC1;
790 siop_target->target_c.flags &= ~(TARF_DT0x08 | TARF_ISDT0x20);
791 CALL_SCRIPT(Ent_msgin_ack)do {((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C
), (sc->sc_c.sc_scriptaddr + 0x00000388))); } while (0)
;
792 return 1;
793 } else if (msg == MSG_SIMPLE_Q_TAG0x20 ||
794 msg == MSG_HEAD_OF_Q_TAG0x21 ||
795 msg == MSG_ORDERED_Q_TAG0x22) {
796 if (siop_handle_qtag_reject(
797 siop_cmd) == -1)
798 goto reset;
799 CALL_SCRIPT(Ent_msgin_ack)do {((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C
), (sc->sc_c.sc_scriptaddr + 0x00000388))); } while (0)
;
800 return 1;
801 }
802 if (xs)
803 sc_print_addr(xs->sc_link);
804 else
805 printf("%s: ",
806 sc->sc_c.sc_dev.dv_xname);
807 if (msg == MSG_EXTENDED0x01) {
808 printf("scsi message reject, extended "
809 "message sent was 0x%x\n", extmsg);
810 } else {
811 printf("scsi message reject, message "
812 "sent was 0x%x\n", msg);
813 }
814 /* no table to flush here */
815 CALL_SCRIPT(Ent_msgin_ack)do {((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C
), (sc->sc_c.sc_scriptaddr + 0x00000388))); } while (0)
;
816 return 1;
817 }
818 if (msgin == MSG_IGN_WIDE_RESIDUE0x23) {
819 /* use the extmsgdata table to get the second byte */
820 siop_cmd->cmd_tablescmd_c.siop_tables->t_extmsgdata.count =
821 siop_htoc32(&sc->sc_c, 1)(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((1)) ? (__uint32_t)(((__uint32_t)((1))
& 0xff) << 24 | ((__uint32_t)((1)) & 0xff00) <<
8 | ((__uint32_t)((1)) & 0xff0000) >> 8 | ((__uint32_t
)((1)) & 0xff000000) >> 24) : __swap32md((1))) : ((
__uint32_t)((1))))
;
822 siop_table_sync(siop_cmd,
823 BUS_DMASYNC_PREREAD0x01 | BUS_DMASYNC_PREWRITE0x04);
824 CALL_SCRIPT(Ent_get_extmsgdata)do {((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C
), (sc->sc_c.sc_scriptaddr + 0x00000580))); } while (0)
;
825 return 1;
826 }
827 if (xs)
828 sc_print_addr(xs->sc_link);
829 else
830 printf("%s: ", sc->sc_c.sc_dev.dv_xname);
831 printf("unhandled message 0x%x\n",
832 siop_cmd->cmd_tablescmd_c.siop_tables->msg_in[0]);
833 siop_cmd->cmd_tablescmd_c.siop_tables->msg_out[0] = MSG_MESSAGE_REJECT0x07;
834 siop_cmd->cmd_tablescmd_c.siop_tables->t_msgout.count =
835 siop_htoc32(&sc->sc_c, 1)(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((1)) ? (__uint32_t)(((__uint32_t)((1))
& 0xff) << 24 | ((__uint32_t)((1)) & 0xff00) <<
8 | ((__uint32_t)((1)) & 0xff0000) >> 8 | ((__uint32_t
)((1)) & 0xff000000) >> 24) : __swap32md((1))) : ((
__uint32_t)((1))))
;
836 siop_table_sync(siop_cmd,
837 BUS_DMASYNC_PREREAD0x01 | BUS_DMASYNC_PREWRITE0x04);
838 CALL_SCRIPT(Ent_send_msgout)do {((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C
), (sc->sc_c.sc_scriptaddr + 0x00000398))); } while (0)
;
839 return 1;
840 }
841 case A_int_extmsgin0x0000ff02:
842#ifdef SIOP_DEBUG_INTR
843 printf("extended message: msg 0x%x len %d\n",
844 siop_cmd->cmd_tablescmd_c.siop_tables->msg_in[2],
845 siop_cmd->cmd_tablescmd_c.siop_tables->msg_in[1]);
846#endif
847 if (siop_cmd->cmd_tablescmd_c.siop_tables->msg_in[1] >
848 sizeof(siop_cmd->cmd_tablescmd_c.siop_tables->msg_in) - 2)
849 printf("%s: extended message too big (%d)\n",
850 sc->sc_c.sc_dev.dv_xname,
851 siop_cmd->cmd_tablescmd_c.siop_tables->msg_in[1]);
852 siop_cmd->cmd_tablescmd_c.siop_tables->t_extmsgdata.count =
853 siop_htoc32(&sc->sc_c,(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((siop_cmd->cmd_c.siop_tables->msg_in
[1] - 1)) ? (__uint32_t)(((__uint32_t)((siop_cmd->cmd_c.siop_tables
->msg_in[1] - 1)) & 0xff) << 24 | ((__uint32_t)(
(siop_cmd->cmd_c.siop_tables->msg_in[1] - 1)) & 0xff00
) << 8 | ((__uint32_t)((siop_cmd->cmd_c.siop_tables->
msg_in[1] - 1)) & 0xff0000) >> 8 | ((__uint32_t)((siop_cmd
->cmd_c.siop_tables->msg_in[1] - 1)) & 0xff000000) >>
24) : __swap32md((siop_cmd->cmd_c.siop_tables->msg_in[
1] - 1))) : ((__uint32_t)((siop_cmd->cmd_c.siop_tables->
msg_in[1] - 1))))
854 siop_cmd->cmd_tables->msg_in[1] - 1)(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((siop_cmd->cmd_c.siop_tables->msg_in
[1] - 1)) ? (__uint32_t)(((__uint32_t)((siop_cmd->cmd_c.siop_tables
->msg_in[1] - 1)) & 0xff) << 24 | ((__uint32_t)(
(siop_cmd->cmd_c.siop_tables->msg_in[1] - 1)) & 0xff00
) << 8 | ((__uint32_t)((siop_cmd->cmd_c.siop_tables->
msg_in[1] - 1)) & 0xff0000) >> 8 | ((__uint32_t)((siop_cmd
->cmd_c.siop_tables->msg_in[1] - 1)) & 0xff000000) >>
24) : __swap32md((siop_cmd->cmd_c.siop_tables->msg_in[
1] - 1))) : ((__uint32_t)((siop_cmd->cmd_c.siop_tables->
msg_in[1] - 1))))
;
855 siop_table_sync(siop_cmd,
856 BUS_DMASYNC_PREREAD0x01 | BUS_DMASYNC_PREWRITE0x04);
857 CALL_SCRIPT(Ent_get_extmsgdata)do {((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C
), (sc->sc_c.sc_scriptaddr + 0x00000580))); } while (0)
;
858 return 1;
859 case A_int_extmsgdata0x0000ff03:
860#ifdef SIOP_DEBUG_INTR
861 {
862 int i;
863 printf("extended message: 0x%x, data:",
864 siop_cmd->cmd_tablescmd_c.siop_tables->msg_in[2]);
865 for (i = 3; i < 2 + siop_cmd->cmd_tablescmd_c.siop_tables->msg_in[1];
866 i++)
867 printf(" 0x%x",
868 siop_cmd->cmd_tablescmd_c.siop_tables->msg_in[i]);
869 printf("\n");
870 }
871#endif
872 if (siop_cmd->cmd_tablescmd_c.siop_tables->msg_in[0] ==
873 MSG_IGN_WIDE_RESIDUE0x23) {
874 /* we got the second byte of MSG_IGN_WIDE_RESIDUE */
875 if (siop_cmd->cmd_tablescmd_c.siop_tables->msg_in[3] != 1)
876 printf("MSG_IGN_WIDE_RESIDUE: "
877 "bad len %d\n",
878 siop_cmd->cmd_tablescmd_c.siop_tables->msg_in[3]);
879 switch (siop_iwr(&siop_cmd->cmd_c)) {
880 case SIOP_NEG_MSGOUT0x1:
881 siop_table_sync(siop_cmd,
882 BUS_DMASYNC_PREREAD0x01 |
883 BUS_DMASYNC_PREWRITE0x04);
884 CALL_SCRIPT(Ent_send_msgout)do {((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C
), (sc->sc_c.sc_scriptaddr + 0x00000398))); } while (0)
;
885 return(1);
886 case SIOP_NEG_ACK0x2:
887 CALL_SCRIPT(Ent_msgin_ack)do {((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C
), (sc->sc_c.sc_scriptaddr + 0x00000388))); } while (0)
;
888 return(1);
889 default:
890 panic("invalid retval from "
891 "siop_iwr()");
892 }
893 return(1);
894 }
895 if (siop_cmd->cmd_tablescmd_c.siop_tables->msg_in[2] == MSG_EXT_WDTR0x03) {
896 switch (siop_wdtr_neg(&siop_cmd->cmd_c)) {
897 case SIOP_NEG_MSGOUT0x1:
898 siop_update_scntl3(sc,
899 siop_cmd->cmd_c.siop_target);
900 siop_table_sync(siop_cmd,
901 BUS_DMASYNC_PREREAD0x01 |
902 BUS_DMASYNC_PREWRITE0x04);
903 CALL_SCRIPT(Ent_send_msgout)do {((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C
), (sc->sc_c.sc_scriptaddr + 0x00000398))); } while (0)
;
904 return(1);
905 case SIOP_NEG_ACK0x2:
906 siop_update_scntl3(sc,
907 siop_cmd->cmd_c.siop_target);
908 CALL_SCRIPT(Ent_msgin_ack)do {((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C
), (sc->sc_c.sc_scriptaddr + 0x00000388))); } while (0)
;
909 return(1);
910 default:
911 panic("invalid retval from "
912 "siop_wdtr_neg()");
913 }
914 return(1);
915 }
916 if (siop_cmd->cmd_tablescmd_c.siop_tables->msg_in[2] == MSG_EXT_SDTR0x01) {
917 switch (siop_sdtr_neg(&siop_cmd->cmd_c)) {
918 case SIOP_NEG_MSGOUT0x1:
919 siop_update_scntl3(sc,
920 siop_cmd->cmd_c.siop_target);
921 siop_table_sync(siop_cmd,
922 BUS_DMASYNC_PREREAD0x01 |
923 BUS_DMASYNC_PREWRITE0x04);
924 CALL_SCRIPT(Ent_send_msgout)do {((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C
), (sc->sc_c.sc_scriptaddr + 0x00000398))); } while (0)
;
925 return(1);
926 case SIOP_NEG_ACK0x2:
927 siop_update_scntl3(sc,
928 siop_cmd->cmd_c.siop_target);
929 CALL_SCRIPT(Ent_msgin_ack)do {((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C
), (sc->sc_c.sc_scriptaddr + 0x00000388))); } while (0)
;
930 return(1);
931 default:
932 panic("invalid retval from "
933 "siop_sdtr_neg()");
934 }
935 return(1);
936 }
937 if (siop_cmd->cmd_tablescmd_c.siop_tables->msg_in[2] == MSG_EXT_PPR0x04) {
938 switch (siop_ppr_neg(&siop_cmd->cmd_c)) {
939 case SIOP_NEG_MSGOUT0x1:
940 siop_update_scntl3(sc,
941 siop_cmd->cmd_c.siop_target);
942 siop_table_sync(siop_cmd,
943 BUS_DMASYNC_PREREAD0x01 |
944 BUS_DMASYNC_PREWRITE0x04);
945 CALL_SCRIPT(Ent_send_msgout)do {((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C
), (sc->sc_c.sc_scriptaddr + 0x00000398))); } while (0)
;
946 return(1);
947 case SIOP_NEG_ACK0x2:
948 siop_update_scntl3(sc,
949 siop_cmd->cmd_c.siop_target);
950 CALL_SCRIPT(Ent_msgin_ack)do {((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C
), (sc->sc_c.sc_scriptaddr + 0x00000388))); } while (0)
;
951 return(1);
952 default:
953 panic("invalid retval from "
954 "siop_wdtr_neg()");
955 }
956 return(1);
957 }
958 /* send a message reject */
959 siop_cmd->cmd_tablescmd_c.siop_tables->msg_out[0] = MSG_MESSAGE_REJECT0x07;
960 siop_cmd->cmd_tablescmd_c.siop_tables->t_msgout.count =
961 siop_htoc32(&sc->sc_c, 1)(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((1)) ? (__uint32_t)(((__uint32_t)((1))
& 0xff) << 24 | ((__uint32_t)((1)) & 0xff00) <<
8 | ((__uint32_t)((1)) & 0xff0000) >> 8 | ((__uint32_t
)((1)) & 0xff000000) >> 24) : __swap32md((1))) : ((
__uint32_t)((1))))
;
962 siop_table_sync(siop_cmd,
963 BUS_DMASYNC_PREREAD0x01 | BUS_DMASYNC_PREWRITE0x04);
964 CALL_SCRIPT(Ent_send_msgout)do {((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C
), (sc->sc_c.sc_scriptaddr + 0x00000398))); } while (0)
;
965 return 1;
966 case A_int_disc0x0000ff04:
967 INCSTAT(siop_stat_intr_sdp);
968 offset = bus_space_read_1(sc->sc_c.sc_rt,((sc->sc_c.sc_rt)->read_1((sc->sc_c.sc_rh), (0x34 + 1
)))
969 sc->sc_c.sc_rh, SIOP_SCRATCHA + 1)((sc->sc_c.sc_rt)->read_1((sc->sc_c.sc_rh), (0x34 + 1
)))
;
970#ifdef SIOP_DEBUG_DR
971 printf("disconnect offset %d\n", offset);
972#endif
973 siop_sdp(&siop_cmd->cmd_c, offset);
974 /* we start again with no offset */
975 siop_cmd->saved_offset = SIOP_NOOFFSET0xffffffff;
976 siop_table_sync(siop_cmd,
977 BUS_DMASYNC_PREREAD0x01 | BUS_DMASYNC_PREWRITE0x04);
978 CALL_SCRIPT(Ent_script_sched)do {((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C
), (sc->sc_c.sc_scriptaddr + 0x00000070))); } while (0)
;
979 return 1;
980 case A_int_saveoffset0x0000ff05:
981 INCSTAT(siop_stat_intr_saveoffset);
982 offset = bus_space_read_1(sc->sc_c.sc_rt,((sc->sc_c.sc_rt)->read_1((sc->sc_c.sc_rh), (0x34 + 1
)))
983 sc->sc_c.sc_rh, SIOP_SCRATCHA + 1)((sc->sc_c.sc_rt)->read_1((sc->sc_c.sc_rh), (0x34 + 1
)))
;
984#ifdef SIOP_DEBUG_DR
985 printf("saveoffset offset %d\n", offset);
986#endif
987 siop_cmd->saved_offset = offset;
988 CALL_SCRIPT(Ent_script_sched)do {((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C
), (sc->sc_c.sc_scriptaddr + 0x00000070))); } while (0)
;
989 return 1;
990 case A_int_resfail0x0000ff83:
991 printf("reselect failed\n");
992 /* check if we can put some command in scheduler */
993 siop_start(sc);
994 CALL_SCRIPT(Ent_script_sched)do {((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C
), (sc->sc_c.sc_scriptaddr + 0x00000070))); } while (0)
;
995 return 1;
996 case A_int_done0x0000ff00:
997 if (xs
26.1
'xs' is equal to NULL
== NULL((void *)0)) {
27
Taking true branch
998 printf("%s: done without command, DSA=0x%lx\n",
999 sc->sc_c.sc_dev.dv_xname,
1000 (u_long)siop_cmd->cmd_c.dsa);
28
Dereference of null pointer
1001 siop_cmd->cmd_c.status = CMDST_FREE0;
1002 siop_start(sc);
1003 CALL_SCRIPT(Ent_script_sched)do {((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C
), (sc->sc_c.sc_scriptaddr + 0x00000070))); } while (0)
;
1004 return 1;
1005 }
1006#ifdef SIOP_DEBUG_INTR
1007 printf("done, DSA=0x%lx target id 0x%x last msg "
1008 "in=0x%x status=0x%x\n", (u_long)siop_cmd->cmd_c.dsa,
1009 siop_ctoh32(&sc->sc_c, siop_cmd->cmd_tables->id)(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((siop_cmd->cmd_c.siop_tables->id
)) ? (__uint32_t)(((__uint32_t)((siop_cmd->cmd_c.siop_tables
->id)) & 0xff) << 24 | ((__uint32_t)((siop_cmd->
cmd_c.siop_tables->id)) & 0xff00) << 8 | ((__uint32_t
)((siop_cmd->cmd_c.siop_tables->id)) & 0xff0000) >>
8 | ((__uint32_t)((siop_cmd->cmd_c.siop_tables->id)) &
0xff000000) >> 24) : __swap32md((siop_cmd->cmd_c.siop_tables
->id))) : ((__uint32_t)((siop_cmd->cmd_c.siop_tables->
id))))
,
1010 siop_cmd->cmd_tablescmd_c.siop_tables->msg_in[0],
1011 siop_ctoh32(&sc->sc_c,(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((siop_cmd->cmd_c.siop_tables->status
)) ? (__uint32_t)(((__uint32_t)((siop_cmd->cmd_c.siop_tables
->status)) & 0xff) << 24 | ((__uint32_t)((siop_cmd
->cmd_c.siop_tables->status)) & 0xff00) << 8 |
((__uint32_t)((siop_cmd->cmd_c.siop_tables->status)) &
0xff0000) >> 8 | ((__uint32_t)((siop_cmd->cmd_c.siop_tables
->status)) & 0xff000000) >> 24) : __swap32md((siop_cmd
->cmd_c.siop_tables->status))) : ((__uint32_t)((siop_cmd
->cmd_c.siop_tables->status))))
1012 siop_cmd->cmd_tables->status)(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((siop_cmd->cmd_c.siop_tables->status
)) ? (__uint32_t)(((__uint32_t)((siop_cmd->cmd_c.siop_tables
->status)) & 0xff) << 24 | ((__uint32_t)((siop_cmd
->cmd_c.siop_tables->status)) & 0xff00) << 8 |
((__uint32_t)((siop_cmd->cmd_c.siop_tables->status)) &
0xff0000) >> 8 | ((__uint32_t)((siop_cmd->cmd_c.siop_tables
->status)) & 0xff000000) >> 24) : __swap32md((siop_cmd
->cmd_c.siop_tables->status))) : ((__uint32_t)((siop_cmd
->cmd_c.siop_tables->status))))
);
1013#endif
1014 INCSTAT(siop_stat_intr_done);
1015 /* update resid. */
1016 offset = bus_space_read_1(sc->sc_c.sc_rt,((sc->sc_c.sc_rt)->read_1((sc->sc_c.sc_rh), (0x34 + 1
)))
1017 sc->sc_c.sc_rh, SIOP_SCRATCHA + 1)((sc->sc_c.sc_rt)->read_1((sc->sc_c.sc_rh), (0x34 + 1
)))
;
1018 /*
1019 * if we got a disconnect between the last data phase
1020 * and the status phase, offset will be 0. In this
1021 * case, siop_cmd->saved_offset will have the proper
1022 * value if it got updated by the controller
1023 */
1024 if (offset == 0 &&
1025 siop_cmd->saved_offset != SIOP_NOOFFSET0xffffffff)
1026 offset = siop_cmd->saved_offset;
1027 siop_update_resid(&siop_cmd->cmd_c, offset);
1028 if (siop_cmd->cmd_c.status == CMDST_SENSE_ACTIVE4)
1029 siop_cmd->cmd_c.status = CMDST_SENSE_DONE5;
1030 else
1031 siop_cmd->cmd_c.status = CMDST_DONE6;
1032 goto end;
1033 default:
1034 printf("unknown irqcode %x\n", irqcode);
1035 if (xs) {
1036 xs->error = XS_SELTIMEOUT3;
1037 goto end;
1038 }
1039 goto reset;
1040 }
1041 return 1;
1042 } else
1043 irqcode = 0;
1044 /* We can get here if ISTAT_DIP and DSTAT_DFE are the only bits set. */
1045 /* But that *SHOULDN'T* happen. It does on powerpc (at least). */
1046 printf("%s: siop_intr() - we should not be here!\n"
1047 " istat = 0x%x, dstat = 0x%x, sist = 0x%x, sstat1 = 0x%x\n"
1048 " need_reset = %x, irqcode = %x, siop_cmd %s\n",
1049 sc->sc_c.sc_dev.dv_xname,
1050 istat, dstat, sist, sstat1, need_reset, irqcode,
1051 (siop_cmd == NULL((void *)0)) ? "== NULL" : "!= NULL");
1052 goto reset; /* Where we should have gone in the first place! */
1053end:
1054 /*
1055 * restart the script now if command completed properly
1056 * Otherwise wait for siop_scsicmd_end(), we may need to cleanup the
1057 * queue
1058 */
1059 xs->status = siop_ctoh32(&sc->sc_c, siop_cmd->cmd_tables->status)(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((siop_cmd->cmd_c.siop_tables->status
)) ? (__uint32_t)(((__uint32_t)((siop_cmd->cmd_c.siop_tables
->status)) & 0xff) << 24 | ((__uint32_t)((siop_cmd
->cmd_c.siop_tables->status)) & 0xff00) << 8 |
((__uint32_t)((siop_cmd->cmd_c.siop_tables->status)) &
0xff0000) >> 8 | ((__uint32_t)((siop_cmd->cmd_c.siop_tables
->status)) & 0xff000000) >> 24) : __swap32md((siop_cmd
->cmd_c.siop_tables->status))) : ((__uint32_t)((siop_cmd
->cmd_c.siop_tables->status))))
;
1060 if (xs->status == SCSI_OK0x00)
1061 CALL_SCRIPT(Ent_script_sched)do {((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C
), (sc->sc_c.sc_scriptaddr + 0x00000070))); } while (0)
;
1062 else
1063 restart = 1;
1064 siop_lun->siop_tag[tag].active = NULL((void *)0);
1065 siop_scsicmd_end(siop_cmd);
1066 siop_start(sc);
1067 if (restart)
1068 CALL_SCRIPT(Ent_script_sched)do {((sc->sc_c.sc_rt)->write_4((sc->sc_c.sc_rh), (0x2C
), (sc->sc_c.sc_scriptaddr + 0x00000070))); } while (0)
;
1069 return 1;
1070}
1071
1072void
1073siop_scsicmd_end(struct siop_cmd *siop_cmd)
1074{
1075 struct scsi_xfer *xs = siop_cmd->cmd_c.xs;
1076 struct siop_softc *sc = (struct siop_softc *)siop_cmd->cmd_c.siop_sc;
1077 struct siop_lun *siop_lun =
1078 ((struct siop_target*)sc->sc_c.targets[xs->sc_link->target])->siop_lun[xs->sc_link->lun];
1079
1080 /*
1081 * If the command is re-queued (SENSE, QUEUE_FULL) it
1082 * must get a new timeout, so delete existing timeout now.
1083 */
1084 timeout_del(&siop_cmd->cmd_c.xs->stimeout);
1085
1086 switch(xs->status) {
1087 case SCSI_OK0x00:
1088 xs->error = (siop_cmd->cmd_c.status == CMDST_DONE6) ?
1089 XS_NOERROR0 : XS_SENSE1;
1090 break;
1091 case SCSI_BUSY0x08:
1092 xs->error = XS_BUSY5;
1093 break;
1094 case SCSI_CHECK0x02:
1095 if (siop_cmd->cmd_c.status == CMDST_SENSE_DONE5) {
1096 /* request sense on a request sense ? */
1097 printf("%s: request sense failed\n",
1098 sc->sc_c.sc_dev.dv_xname);
1099 xs->error = XS_DRIVER_STUFFUP2;
1100 } else {
1101 siop_cmd->cmd_c.status = CMDST_SENSE3;
1102 }
1103 break;
1104 case SCSI_QUEUE_FULL0x28:
1105 /*
1106 * Device didn't queue the command. We have to retry
1107 * it. We insert it into the urgent list, hoping to
1108 * preserve order. But unfortunately, commands already
1109 * in the scheduler may be accepted before this one.
1110 * Also remember the condition, to avoid starting new
1111 * commands for this device before one is done.
1112 */
1113 INCSTAT(siop_stat_intr_qfull);
1114#ifdef SIOP_DEBUG
1115 printf("%s:%d:%d: queue full (tag %d)\n", sc->sc_c.sc_dev.dv_xname,
1116 xs->sc_link->target,
1117 xs->sc_link->lun, siop_cmd->cmd_c.tag);
1118#endif
1119 siop_lun->lun_flags |= SIOP_LUNF_FULL0x01;
1120 siop_cmd->cmd_c.status = CMDST_READY1;
1121 siop_setuptables(&siop_cmd->cmd_c);
1122 siop_table_sync(siop_cmd, BUS_DMASYNC_PREREAD0x01 | BUS_DMASYNC_PREWRITE0x04);
1123 TAILQ_INSERT_TAIL(&sc->urgent_list, siop_cmd, next)do { (siop_cmd)->next.tqe_next = ((void *)0); (siop_cmd)->
next.tqe_prev = (&sc->urgent_list)->tqh_last; *(&
sc->urgent_list)->tqh_last = (siop_cmd); (&sc->urgent_list
)->tqh_last = &(siop_cmd)->next.tqe_next; } while (
0)
;
1124 return;
1125 case SCSI_SIOP_NOCHECK0xfe:
1126 /*
1127 * don't check status, xs->error is already valid
1128 */
1129 break;
1130 case SCSI_SIOP_NOSTATUS0xff:
1131 /*
1132 * the status byte was not updated, cmd was
1133 * aborted
1134 */
1135 xs->error = XS_SELTIMEOUT3;
1136 break;
1137 default:
1138 xs->error = XS_DRIVER_STUFFUP2;
1139 }
1140 if (siop_cmd->cmd_c.status != CMDST_SENSE_DONE5 &&
1141 xs->flags & (SCSI_DATA_IN0x00800 | SCSI_DATA_OUT0x01000)) {
1142 bus_dmamap_sync(sc->sc_c.sc_dmat, siop_cmd->cmd_c.dmamap_data, 0,(*(sc->sc_c.sc_dmat)->_dmamap_sync)((sc->sc_c.sc_dmat
), (siop_cmd->cmd_c.dmamap_data), (0), (siop_cmd->cmd_c
.dmamap_data->dm_mapsize), ((xs->flags & 0x00800) ?
0x02 : 0x08))
1143 siop_cmd->cmd_c.dmamap_data->dm_mapsize,(*(sc->sc_c.sc_dmat)->_dmamap_sync)((sc->sc_c.sc_dmat
), (siop_cmd->cmd_c.dmamap_data), (0), (siop_cmd->cmd_c
.dmamap_data->dm_mapsize), ((xs->flags & 0x00800) ?
0x02 : 0x08))
1144 (xs->flags & SCSI_DATA_IN) ?(*(sc->sc_c.sc_dmat)->_dmamap_sync)((sc->sc_c.sc_dmat
), (siop_cmd->cmd_c.dmamap_data), (0), (siop_cmd->cmd_c
.dmamap_data->dm_mapsize), ((xs->flags & 0x00800) ?
0x02 : 0x08))
1145 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE)(*(sc->sc_c.sc_dmat)->_dmamap_sync)((sc->sc_c.sc_dmat
), (siop_cmd->cmd_c.dmamap_data), (0), (siop_cmd->cmd_c
.dmamap_data->dm_mapsize), ((xs->flags & 0x00800) ?
0x02 : 0x08))
;
1146 bus_dmamap_unload(sc->sc_c.sc_dmat, siop_cmd->cmd_c.dmamap_data)(*(sc->sc_c.sc_dmat)->_dmamap_unload)((sc->sc_c.sc_dmat
), (siop_cmd->cmd_c.dmamap_data))
;
1147 }
1148 if (siop_cmd->cmd_c.status == CMDST_SENSE3) {
1149 /* issue a request sense for this target */
1150 struct scsi_sense *cmd = (struct scsi_sense *)&siop_cmd->cmd_c.siop_tables->xscmd;
1151 int error;
1152 bzero(cmd, sizeof(*cmd))__builtin_bzero((cmd), (sizeof(*cmd)));
1153 siop_cmd->cmd_c.siop_tables->cmd.count =
1154 siop_htoc32(&sc->sc_c, sizeof(struct scsi_sense))(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((sizeof(struct scsi_sense))) ? (__uint32_t
)(((__uint32_t)((sizeof(struct scsi_sense))) & 0xff) <<
24 | ((__uint32_t)((sizeof(struct scsi_sense))) & 0xff00
) << 8 | ((__uint32_t)((sizeof(struct scsi_sense))) &
0xff0000) >> 8 | ((__uint32_t)((sizeof(struct scsi_sense
))) & 0xff000000) >> 24) : __swap32md((sizeof(struct
scsi_sense)))) : ((__uint32_t)((sizeof(struct scsi_sense))))
)
;
1155 cmd->opcode = REQUEST_SENSE0x03;
1156 cmd->byte2 = xs->sc_link->lun << 5;
1157 cmd->unused[0] = cmd->unused[1] = 0;
1158 cmd->length = sizeof(struct scsi_sense_data);
1159 cmd->control = 0;
1160 siop_cmd->cmd_c.flags &= ~CMDFL_TAG0x0002;
1161 error = bus_dmamap_load(sc->sc_c.sc_dmat,(*(sc->sc_c.sc_dmat)->_dmamap_load)((sc->sc_c.sc_dmat
), (siop_cmd->cmd_c.dmamap_data), (siop_cmd->cmd_c.sense
), (sizeof(struct scsi_sense_data)), (((void *)0)), (0x0001))
1162 siop_cmd->cmd_c.dmamap_data,(*(sc->sc_c.sc_dmat)->_dmamap_load)((sc->sc_c.sc_dmat
), (siop_cmd->cmd_c.dmamap_data), (siop_cmd->cmd_c.sense
), (sizeof(struct scsi_sense_data)), (((void *)0)), (0x0001))
1163 siop_cmd->cmd_c.sense, sizeof(struct scsi_sense_data),(*(sc->sc_c.sc_dmat)->_dmamap_load)((sc->sc_c.sc_dmat
), (siop_cmd->cmd_c.dmamap_data), (siop_cmd->cmd_c.sense
), (sizeof(struct scsi_sense_data)), (((void *)0)), (0x0001))
1164 NULL, BUS_DMA_NOWAIT)(*(sc->sc_c.sc_dmat)->_dmamap_load)((sc->sc_c.sc_dmat
), (siop_cmd->cmd_c.dmamap_data), (siop_cmd->cmd_c.sense
), (sizeof(struct scsi_sense_data)), (((void *)0)), (0x0001))
;
1165 if (error) {
1166 printf("%s: unable to load data DMA map "
1167 "(for SENSE): %d\n",
1168 sc->sc_c.sc_dev.dv_xname, error);
1169 xs->error = XS_DRIVER_STUFFUP2;
1170 goto out;
1171 }
1172 bus_dmamap_sync(sc->sc_c.sc_dmat, siop_cmd->cmd_c.dmamap_data,(*(sc->sc_c.sc_dmat)->_dmamap_sync)((sc->sc_c.sc_dmat
), (siop_cmd->cmd_c.dmamap_data), (0), (siop_cmd->cmd_c
.dmamap_data->dm_mapsize), (0x01))
1173 0, siop_cmd->cmd_c.dmamap_data->dm_mapsize,(*(sc->sc_c.sc_dmat)->_dmamap_sync)((sc->sc_c.sc_dmat
), (siop_cmd->cmd_c.dmamap_data), (0), (siop_cmd->cmd_c
.dmamap_data->dm_mapsize), (0x01))
1174 BUS_DMASYNC_PREREAD)(*(sc->sc_c.sc_dmat)->_dmamap_sync)((sc->sc_c.sc_dmat
), (siop_cmd->cmd_c.dmamap_data), (0), (siop_cmd->cmd_c
.dmamap_data->dm_mapsize), (0x01))
;
1175
1176 siop_setuptables(&siop_cmd->cmd_c);
1177 siop_table_sync(siop_cmd, BUS_DMASYNC_PREREAD0x01 | BUS_DMASYNC_PREWRITE0x04);
1178 /* arrange for the cmd to be handled now */
1179 TAILQ_INSERT_HEAD(&sc->urgent_list, siop_cmd, next)do { if (((siop_cmd)->next.tqe_next = (&sc->urgent_list
)->tqh_first) != ((void *)0)) (&sc->urgent_list)->
tqh_first->next.tqe_prev = &(siop_cmd)->next.tqe_next
; else (&sc->urgent_list)->tqh_last = &(siop_cmd
)->next.tqe_next; (&sc->urgent_list)->tqh_first =
(siop_cmd); (siop_cmd)->next.tqe_prev = &(&sc->
urgent_list)->tqh_first; } while (0)
;
1180 return;
1181 } else if (siop_cmd->cmd_c.status == CMDST_SENSE_DONE5) {
1182 bus_dmamap_sync(sc->sc_c.sc_dmat, siop_cmd->cmd_c.dmamap_data,(*(sc->sc_c.sc_dmat)->_dmamap_sync)((sc->sc_c.sc_dmat
), (siop_cmd->cmd_c.dmamap_data), (0), (siop_cmd->cmd_c
.dmamap_data->dm_mapsize), (0x02))
1183 0, siop_cmd->cmd_c.dmamap_data->dm_mapsize,(*(sc->sc_c.sc_dmat)->_dmamap_sync)((sc->sc_c.sc_dmat
), (siop_cmd->cmd_c.dmamap_data), (0), (siop_cmd->cmd_c
.dmamap_data->dm_mapsize), (0x02))
1184 BUS_DMASYNC_POSTREAD)(*(sc->sc_c.sc_dmat)->_dmamap_sync)((sc->sc_c.sc_dmat
), (siop_cmd->cmd_c.dmamap_data), (0), (siop_cmd->cmd_c
.dmamap_data->dm_mapsize), (0x02))
;
1185 bus_dmamap_unload(sc->sc_c.sc_dmat, siop_cmd->cmd_c.dmamap_data)(*(sc->sc_c.sc_dmat)->_dmamap_unload)((sc->sc_c.sc_dmat
), (siop_cmd->cmd_c.dmamap_data))
;
1186 bcopy(siop_cmd->cmd_c.sense, &xs->sense, sizeof(xs->sense));
1187 }
1188out:
1189 siop_lun->lun_flags &= ~SIOP_LUNF_FULL0x01;
1190#if 0
1191 if (xs->resid != 0)
1192 printf("resid %d datalen %d\n", xs->resid, xs->datalen);
1193#endif
1194 scsi_done(xs);
1195}
1196
1197/*
1198 * handle a rejected queue tag message: the command will run untagged,
1199 * has to adjust the reselect script.
1200 */
1201int
1202siop_handle_qtag_reject(struct siop_cmd *siop_cmd)
1203{
1204 struct siop_softc *sc = (struct siop_softc *)siop_cmd->cmd_c.siop_sc;
1205 int target = siop_cmd->cmd_c.xs->sc_link->target;
1206 int lun = siop_cmd->cmd_c.xs->sc_link->lun;
1207 int tag = siop_cmd->cmd_tablescmd_c.siop_tables->msg_out[2];
1208 struct siop_lun *siop_lun =
1209 ((struct siop_target*)sc->sc_c.targets[target])->siop_lun[lun];
1210
1211#ifdef SIOP_DEBUG
1212 printf("%s:%d:%d: tag message %d (%d) rejected (status %d)\n",
1213 sc->sc_c.sc_dev.dv_xname, target, lun, tag, siop_cmd->cmd_c.tag,
1214 siop_cmd->cmd_c.status);
1215#endif
1216
1217 if (siop_lun->siop_tag[0].active != NULL((void *)0)) {
1218 printf("%s: untagged command already running for target %d "
1219 "lun %d (status %d)\n", sc->sc_c.sc_dev.dv_xname,
1220 target, lun, siop_lun->siop_tag[0].active->cmd_c.status);
1221 return -1;
1222 }
1223 /* clear tag slot */
1224 siop_lun->siop_tag[tag].active = NULL((void *)0);
1225 /* add command to non-tagged slot */
1226 siop_lun->siop_tag[0].active = siop_cmd;
1227 siop_cmd->cmd_c.tag = 0;
1228 /* adjust reselect script if there is one */
1229 if (siop_lun->siop_tag[0].reseloff > 0) {
1230 siop_script_write(sc,
1231 siop_lun->siop_tag[0].reseloff + 1,
1232 siop_cmd->cmd_c.dsa + sizeof(struct siop_common_xfer) +
1233 Ent_ldsa_reload_dsa0x00000028);
1234 siop_table_sync(siop_cmd, BUS_DMASYNC_PREWRITE0x04);
1235 }
1236 return 0;
1237}
1238
1239/*
1240 * handle a bus reset: reset chip, unqueue all active commands, free all
1241 * target struct and report lossage to upper layer.
1242 * As the upper layer may requeue immediately we have to first store
1243 * all active commands in a temporary queue.
1244 */
1245void
1246siop_handle_reset(struct siop_softc *sc)
1247{
1248 struct cmd_list reset_list;
1249 struct siop_cmd *siop_cmd, *next_siop_cmd;
1250 struct siop_lun *siop_lun;
1251 int target, lun, tag, buswidth;
1252 /*
1253 * scsi bus reset. reset the chip and restart
1254 * the queue. Need to clean up all active commands
1255 */
1256 printf("%s: scsi bus reset\n", sc->sc_c.sc_dev.dv_xname);
1257 /* stop, reset and restart the chip */
1258 siop_reset(sc);
1259 TAILQ_INIT(&reset_list)do { (&reset_list)->tqh_first = ((void *)0); (&reset_list
)->tqh_last = &(&reset_list)->tqh_first; } while
(0)
;
1260 /*
1261 * Process all commands: first commands being executed
1262 */
1263 buswidth = (sc->sc_c.features & SF_BUS_WIDE0x00000001) ? 16 : 8;
1264 for (target = 0; target < buswidth; target++) {
1265 if (sc->sc_c.targets[target] == NULL((void *)0))
1266 continue;
1267 for (lun = 0; lun < 8; lun++) {
1268 struct siop_target *siop_target =
1269 (struct siop_target *)sc->sc_c.targets[target];
1270 siop_lun = siop_target->siop_lun[lun];
1271 if (siop_lun == NULL((void *)0))
1272 continue;
1273 siop_lun->lun_flags &= ~SIOP_LUNF_FULL0x01;
1274 for (tag = 0; tag <
1275 ((sc->sc_c.targets[target]->flags & TARF_TAG0x04) ?
1276 SIOP_NTAG16 : 1);
1277 tag++) {
1278 siop_cmd = siop_lun->siop_tag[tag].active;
1279 if (siop_cmd == NULL((void *)0))
1280 continue;
1281 siop_lun->siop_tag[tag].active = NULL((void *)0);
1282 TAILQ_INSERT_TAIL(&reset_list, siop_cmd, next)do { (siop_cmd)->next.tqe_next = ((void *)0); (siop_cmd)->
next.tqe_prev = (&reset_list)->tqh_last; *(&reset_list
)->tqh_last = (siop_cmd); (&reset_list)->tqh_last =
&(siop_cmd)->next.tqe_next; } while (0)
;
1283 sc_print_addr(siop_cmd->cmd_c.xs->sc_link);
1284 printf("cmd %p (tag %d) added to reset list\n",
1285 siop_cmd, tag);
1286 }
1287 }
1288 if (sc->sc_c.targets[target]->status != TARST_PROBING0) {
1289 sc->sc_c.targets[target]->status = TARST_ASYNC1;
1290 sc->sc_c.targets[target]->flags &= ~TARF_ISWIDE0x10;
1291 sc->sc_c.targets[target]->period =
1292 sc->sc_c.targets[target]->offset = 0;
1293 siop_update_xfer_mode(&sc->sc_c, target);
1294 }
1295 }
1296 /* Next commands from the urgent list */
1297 for (siop_cmd = TAILQ_FIRST(&sc->urgent_list)((&sc->urgent_list)->tqh_first); siop_cmd != NULL((void *)0);
1298 siop_cmd = next_siop_cmd) {
1299 next_siop_cmd = TAILQ_NEXT(siop_cmd, next)((siop_cmd)->next.tqe_next);
1300 TAILQ_REMOVE(&sc->urgent_list, siop_cmd, next)do { if (((siop_cmd)->next.tqe_next) != ((void *)0)) (siop_cmd
)->next.tqe_next->next.tqe_prev = (siop_cmd)->next.tqe_prev
; else (&sc->urgent_list)->tqh_last = (siop_cmd)->
next.tqe_prev; *(siop_cmd)->next.tqe_prev = (siop_cmd)->
next.tqe_next; ((siop_cmd)->next.tqe_prev) = ((void *)-1);
((siop_cmd)->next.tqe_next) = ((void *)-1); } while (0)
;
1301 TAILQ_INSERT_TAIL(&reset_list, siop_cmd, next)do { (siop_cmd)->next.tqe_next = ((void *)0); (siop_cmd)->
next.tqe_prev = (&reset_list)->tqh_last; *(&reset_list
)->tqh_last = (siop_cmd); (&reset_list)->tqh_last =
&(siop_cmd)->next.tqe_next; } while (0)
;
1302 sc_print_addr(siop_cmd->cmd_c.xs->sc_link);
1303 printf("cmd %p added to reset list from urgent list\n",
1304 siop_cmd);
1305 }
1306 /* Then commands waiting in the input list. */
1307 for (siop_cmd = TAILQ_FIRST(&sc->ready_list)((&sc->ready_list)->tqh_first); siop_cmd != NULL((void *)0);
1308 siop_cmd = next_siop_cmd) {
1309 next_siop_cmd = TAILQ_NEXT(siop_cmd, next)((siop_cmd)->next.tqe_next);
1310 TAILQ_REMOVE(&sc->ready_list, siop_cmd, next)do { if (((siop_cmd)->next.tqe_next) != ((void *)0)) (siop_cmd
)->next.tqe_next->next.tqe_prev = (siop_cmd)->next.tqe_prev
; else (&sc->ready_list)->tqh_last = (siop_cmd)->
next.tqe_prev; *(siop_cmd)->next.tqe_prev = (siop_cmd)->
next.tqe_next; ((siop_cmd)->next.tqe_prev) = ((void *)-1);
((siop_cmd)->next.tqe_next) = ((void *)-1); } while (0)
;
1311 TAILQ_INSERT_TAIL(&reset_list, siop_cmd, next)do { (siop_cmd)->next.tqe_next = ((void *)0); (siop_cmd)->
next.tqe_prev = (&reset_list)->tqh_last; *(&reset_list
)->tqh_last = (siop_cmd); (&reset_list)->tqh_last =
&(siop_cmd)->next.tqe_next; } while (0)
;
1312 sc_print_addr(siop_cmd->cmd_c.xs->sc_link);
1313 printf("cmd %p added to reset list from ready list\n",
1314 siop_cmd);
1315 }
1316
1317 for (siop_cmd = TAILQ_FIRST(&reset_list)((&reset_list)->tqh_first); siop_cmd != NULL((void *)0);
1318 siop_cmd = next_siop_cmd) {
1319 next_siop_cmd = TAILQ_NEXT(siop_cmd, next)((siop_cmd)->next.tqe_next);
1320 siop_cmd->cmd_c.flags &= ~CMDFL_TAG0x0002;
1321 siop_cmd->cmd_c.xs->error =
1322 (siop_cmd->cmd_c.flags & CMDFL_TIMEOUT0x0001)
1323 ? XS_TIMEOUT4 : XS_RESET8;
1324 siop_cmd->cmd_c.xs->status = SCSI_SIOP_NOCHECK0xfe;
1325 sc_print_addr(siop_cmd->cmd_c.xs->sc_link);
1326 printf("cmd %p (status %d) reset",
1327 siop_cmd, siop_cmd->cmd_c.status);
1328 if (siop_cmd->cmd_c.status == CMDST_SENSE3 ||
1329 siop_cmd->cmd_c.status == CMDST_SENSE_ACTIVE4)
1330 siop_cmd->cmd_c.status = CMDST_SENSE_DONE5;
1331 else
1332 siop_cmd->cmd_c.status = CMDST_DONE6;
1333 printf(" with status %d, xs->error %d\n",
1334 siop_cmd->cmd_c.status, siop_cmd->cmd_c.xs->error);
1335 TAILQ_REMOVE(&reset_list, siop_cmd, next)do { if (((siop_cmd)->next.tqe_next) != ((void *)0)) (siop_cmd
)->next.tqe_next->next.tqe_prev = (siop_cmd)->next.tqe_prev
; else (&reset_list)->tqh_last = (siop_cmd)->next.tqe_prev
; *(siop_cmd)->next.tqe_prev = (siop_cmd)->next.tqe_next
; ((siop_cmd)->next.tqe_prev) = ((void *)-1); ((siop_cmd)->
next.tqe_next) = ((void *)-1); } while (0)
;
1336 siop_scsicmd_end(siop_cmd);
1337 }
1338}
1339
1340void *
1341siop_cmd_get(void *cookie)
1342{
1343 struct siop_softc *sc = cookie;
1344 struct siop_cmd *siop_cmd;
1345 int s;
1346
1347 /* Look if a ccb is available. */
1348 s = splbio()splraise(0x6);
1349 siop_cmd = TAILQ_FIRST(&sc->free_list)((&sc->free_list)->tqh_first);
1350 if (siop_cmd != NULL((void *)0)) {
1351 TAILQ_REMOVE(&sc->free_list, siop_cmd, next)do { if (((siop_cmd)->next.tqe_next) != ((void *)0)) (siop_cmd
)->next.tqe_next->next.tqe_prev = (siop_cmd)->next.tqe_prev
; else (&sc->free_list)->tqh_last = (siop_cmd)->
next.tqe_prev; *(siop_cmd)->next.tqe_prev = (siop_cmd)->
next.tqe_next; ((siop_cmd)->next.tqe_prev) = ((void *)-1);
((siop_cmd)->next.tqe_next) = ((void *)-1); } while (0)
;
1352#ifdef DIAGNOSTIC1
1353 if (siop_cmd->cmd_c.status != CMDST_FREE0)
1354 panic("siop_scsicmd: new cmd not free");
1355#endif
1356 siop_cmd->cmd_c.status = CMDST_READY1;
1357 }
1358 splx(s)spllower(s);
1359
1360 return (siop_cmd);
1361}
1362
1363void
1364siop_cmd_put(void *cookie, void *io)
1365{
1366 struct siop_softc *sc = cookie;
1367 struct siop_cmd *siop_cmd = io;
1368 int s;
1369
1370 s = splbio()splraise(0x6);
1371 siop_cmd->cmd_c.status = CMDST_FREE0;
1372 TAILQ_INSERT_TAIL(&sc->free_list, siop_cmd, next)do { (siop_cmd)->next.tqe_next = ((void *)0); (siop_cmd)->
next.tqe_prev = (&sc->free_list)->tqh_last; *(&
sc->free_list)->tqh_last = (siop_cmd); (&sc->free_list
)->tqh_last = &(siop_cmd)->next.tqe_next; } while (
0)
;
1373 splx(s)spllower(s);
1374}
1375
1376int
1377siop_scsiprobe(struct scsi_link *link)
1378{
1379 struct siop_softc *sc = link->bus->sb_adapter_softc;
1380 struct siop_target *siop_target;
1381 const int target = link->target;
1382 const int lun = link->lun;
1383 int i;
1384
1385#ifdef SIOP_DEBUG
1386 printf("%s:%d:%d: probe\n",
1387 sc->sc_c.sc_dev.dv_xname, target, lun);
1388#endif
1389
1390 /* XXX locking */
1391
1392 siop_target = (struct siop_target*)sc->sc_c.targets[target];
1393 if (siop_target == NULL((void *)0)) {
1394 siop_target = malloc(sizeof(*siop_target), M_DEVBUF2,
1395 M_WAITOK0x0001 | M_CANFAIL0x0004 | M_ZERO0x0008);
1396 if (siop_target == NULL((void *)0)) {
1397 printf("%s: can't malloc memory for target %d\n",
1398 sc->sc_c.sc_dev.dv_xname, target);
1399 return (ENOMEM12);
1400 }
1401
1402 siop_target->target_c.status = TARST_PROBING0;
1403 siop_target->target_c.flags = 0;
1404 siop_target->target_c.id =
1405 sc->sc_c.clock_div << 24; /* scntl3 */
1406 siop_target->target_c.id |= target << 16; /* id */
1407 /* siop_target->target_c.id |= 0x0 << 8; scxfer is 0 */
1408
1409 /* get a lun switch script */
1410 siop_target->lunsw = siop_get_lunsw(sc);
1411 if (siop_target->lunsw == NULL((void *)0)) {
1412 printf("%s: can't alloc lunsw for target %d\n",
1413 sc->sc_c.sc_dev.dv_xname, target);
1414 free(siop_target, M_DEVBUF2, sizeof *siop_target);
1415 return (ENOMEM12);
1416 }
1417 for (i = 0; i < 8; i++)
1418 siop_target->siop_lun[i] = NULL((void *)0);
1419
1420 sc->sc_c.targets[target] =
1421 (struct siop_common_target *)siop_target;
1422
1423 siop_add_reselsw(sc, target);
1424 }
1425
1426 if (siop_target->siop_lun[lun] == NULL((void *)0)) {
1427 siop_target->siop_lun[lun] =
1428 malloc(sizeof(struct siop_lun), M_DEVBUF2,
1429 M_WAITOK0x0001 | M_CANFAIL0x0004 | M_ZERO0x0008);
1430 if (siop_target->siop_lun[lun] == NULL((void *)0)) {
1431 printf("%s: can't alloc siop_lun for "
1432 "target %d lun %d\n",
1433 sc->sc_c.sc_dev.dv_xname, target, lun);
1434 return (ENOMEM12);
1435 }
1436 }
1437
1438 return (0);
1439}
1440
1441void
1442siop_scsicmd(struct scsi_xfer *xs)
1443{
1444 struct siop_softc *sc = xs->sc_link->bus->sb_adapter_softc;
1445 struct siop_cmd *siop_cmd;
1446 struct siop_target *siop_target;
1447 int s, error, i, j;
1448 const int target = xs->sc_link->target;
1449 const int lun = xs->sc_link->lun;
1450
1451#ifdef SIOP_DEBUG_SCHED
1452 printf("starting cmd for %d:%d\n", target, lun);
1453#endif
1454
1455 siop_target = (struct siop_target*)sc->sc_c.targets[target];
1456 siop_cmd = xs->io;
1457
1458 /*
1459 * The xs may have been restarted by the scsi layer, so ensure the ccb
1460 * starts in the proper state.
1461 */
1462 siop_cmd->cmd_c.status = CMDST_READY1;
1463
1464 /* Always reset xs->stimeout, lest we timeout_del() with trash */
1465 timeout_set(&xs->stimeout, siop_timeout, siop_cmd);
1466
1467 siop_cmd->cmd_c.siop_target = sc->sc_c.targets[target];
1468 siop_cmd->cmd_c.xs = xs;
1469 siop_cmd->cmd_c.flags = 0;
1470
1471 bzero(&siop_cmd->cmd_c.siop_tables->xscmd,__builtin_bzero((&siop_cmd->cmd_c.siop_tables->xscmd
), (sizeof(siop_cmd->cmd_c.siop_tables->xscmd)))
1472 sizeof(siop_cmd->cmd_c.siop_tables->xscmd))__builtin_bzero((&siop_cmd->cmd_c.siop_tables->xscmd
), (sizeof(siop_cmd->cmd_c.siop_tables->xscmd)))
;
1473 bcopy(&xs->cmd, &siop_cmd->cmd_c.siop_tables->xscmd, xs->cmdlen);
1474 siop_cmd->cmd_c.siop_tables->cmd.count =
1475 siop_htoc32(&sc->sc_c, xs->cmdlen)(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((xs->cmdlen)) ? (__uint32_t)(((__uint32_t
)((xs->cmdlen)) & 0xff) << 24 | ((__uint32_t)((xs
->cmdlen)) & 0xff00) << 8 | ((__uint32_t)((xs->
cmdlen)) & 0xff0000) >> 8 | ((__uint32_t)((xs->cmdlen
)) & 0xff000000) >> 24) : __swap32md((xs->cmdlen
))) : ((__uint32_t)((xs->cmdlen))))
;
1476
1477 /* load the DMA maps */
1478 if (xs->flags & (SCSI_DATA_IN0x00800 | SCSI_DATA_OUT0x01000)) {
1479 error = bus_dmamap_load(sc->sc_c.sc_dmat,(*(sc->sc_c.sc_dmat)->_dmamap_load)((sc->sc_c.sc_dmat
), (siop_cmd->cmd_c.dmamap_data), (xs->data), (xs->datalen
), (((void *)0)), (0x0001 | 0x0100 | ((xs->flags & 0x00800
) ? 0x0200 : 0x0400)))
1480 siop_cmd->cmd_c.dmamap_data, xs->data, xs->datalen,(*(sc->sc_c.sc_dmat)->_dmamap_load)((sc->sc_c.sc_dmat
), (siop_cmd->cmd_c.dmamap_data), (xs->data), (xs->datalen
), (((void *)0)), (0x0001 | 0x0100 | ((xs->flags & 0x00800
) ? 0x0200 : 0x0400)))
1481 NULL, BUS_DMA_NOWAIT | BUS_DMA_STREAMING |(*(sc->sc_c.sc_dmat)->_dmamap_load)((sc->sc_c.sc_dmat
), (siop_cmd->cmd_c.dmamap_data), (xs->data), (xs->datalen
), (((void *)0)), (0x0001 | 0x0100 | ((xs->flags & 0x00800
) ? 0x0200 : 0x0400)))
1482 ((xs->flags & SCSI_DATA_IN) ?(*(sc->sc_c.sc_dmat)->_dmamap_load)((sc->sc_c.sc_dmat
), (siop_cmd->cmd_c.dmamap_data), (xs->data), (xs->datalen
), (((void *)0)), (0x0001 | 0x0100 | ((xs->flags & 0x00800
) ? 0x0200 : 0x0400)))
1483 BUS_DMA_READ : BUS_DMA_WRITE))(*(sc->sc_c.sc_dmat)->_dmamap_load)((sc->sc_c.sc_dmat
), (siop_cmd->cmd_c.dmamap_data), (xs->data), (xs->datalen
), (((void *)0)), (0x0001 | 0x0100 | ((xs->flags & 0x00800
) ? 0x0200 : 0x0400)))
;
1484 if (error) {
1485 printf("%s: unable to load data DMA map: %d\n",
1486 sc->sc_c.sc_dev.dv_xname, error);
1487 xs->error = XS_DRIVER_STUFFUP2;
1488 scsi_done(xs);
1489 return;
1490 }
1491 bus_dmamap_sync(sc->sc_c.sc_dmat,(*(sc->sc_c.sc_dmat)->_dmamap_sync)((sc->sc_c.sc_dmat
), (siop_cmd->cmd_c.dmamap_data), (0), (siop_cmd->cmd_c
.dmamap_data->dm_mapsize), ((xs->flags & 0x00800) ?
0x01 : 0x04))
1492 siop_cmd->cmd_c.dmamap_data, 0,(*(sc->sc_c.sc_dmat)->_dmamap_sync)((sc->sc_c.sc_dmat
), (siop_cmd->cmd_c.dmamap_data), (0), (siop_cmd->cmd_c
.dmamap_data->dm_mapsize), ((xs->flags & 0x00800) ?
0x01 : 0x04))
1493 siop_cmd->cmd_c.dmamap_data->dm_mapsize,(*(sc->sc_c.sc_dmat)->_dmamap_sync)((sc->sc_c.sc_dmat
), (siop_cmd->cmd_c.dmamap_data), (0), (siop_cmd->cmd_c
.dmamap_data->dm_mapsize), ((xs->flags & 0x00800) ?
0x01 : 0x04))
1494 (xs->flags & SCSI_DATA_IN) ?(*(sc->sc_c.sc_dmat)->_dmamap_sync)((sc->sc_c.sc_dmat
), (siop_cmd->cmd_c.dmamap_data), (0), (siop_cmd->cmd_c
.dmamap_data->dm_mapsize), ((xs->flags & 0x00800) ?
0x01 : 0x04))
1495 BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE)(*(sc->sc_c.sc_dmat)->_dmamap_sync)((sc->sc_c.sc_dmat
), (siop_cmd->cmd_c.dmamap_data), (0), (siop_cmd->cmd_c
.dmamap_data->dm_mapsize), ((xs->flags & 0x00800) ?
0x01 : 0x04))
;
1496 }
1497
1498 siop_setuptables(&siop_cmd->cmd_c);
1499 siop_cmd->saved_offset = SIOP_NOOFFSET0xffffffff;
1500 siop_table_sync(siop_cmd,
1501 BUS_DMASYNC_PREREAD0x01 | BUS_DMASYNC_PREWRITE0x04);
1502
1503 /* Negotiate transfer parameters on first non-polling command. */
1504 if (((xs->flags & SCSI_POLL0x00002) == 0) &&
1505 siop_target->target_c.status == TARST_PROBING0)
1506 siop_target->target_c.status = TARST_ASYNC1;
1507
1508 s = splbio()splraise(0x6);
1509 TAILQ_INSERT_TAIL(&sc->ready_list, siop_cmd, next)do { (siop_cmd)->next.tqe_next = ((void *)0); (siop_cmd)->
next.tqe_prev = (&sc->ready_list)->tqh_last; *(&
sc->ready_list)->tqh_last = (siop_cmd); (&sc->ready_list
)->tqh_last = &(siop_cmd)->next.tqe_next; } while (
0)
;
1510 siop_start(sc);
1511 if ((xs->flags & SCSI_POLL0x00002) == 0) {
1512 splx(s)spllower(s);
1513 return;
1514 }
1515
1516 /* Poll for command completion. */
1517 for(i = xs->timeout; i > 0; i--) {
1518 siop_intr(sc);
1519 if ((xs->flags & ITSDONE0x00008) == 0) {
1520 delay(1000)(*delay_func)(1000);
1521 continue;
1522 }
1523 if (xs->cmd.opcode == INQUIRY0x12 && xs->error == XS_NOERROR0) {
1524 struct scsi_inquiry_data *inqbuf =
1525 (struct scsi_inquiry_data *)xs->data;
1526 if ((inqbuf->device & SID_QUAL0xe0) == SID_QUAL_BAD_LU0x60)
1527 break;
1528 /*
1529 * Allocate cbd's to hold maximum openings worth of
1530 * commands. Do this now because doing it dynamically in
1531 * siop_startcmd may cause calls to bus_dma* functions
1532 * in interrupt context.
1533 */
1534 for (j = 0; j < SIOP_NTAG16; j += SIOP_NCMDPB((1 << 12) / sizeof(struct siop_xfer)))
1535 siop_morecbd(sc);
1536
1537 /*
1538 * Set TARF_DT here because if it is turned off during
1539 * PPR, it must STAY off!
1540 */
1541 if ((lun == 0) && (sc->sc_c.features & SF_BUS_ULTRA30x00000008))
1542 sc->sc_c.targets[target]->flags |= TARF_DT0x08;
1543 /*
1544 * Can't do lun 0 here, because flags are not set yet.
1545 * But have to do other lun's here because they never go
1546 * through TARST_ASYNC.
1547 */
1548 if (lun > 0)
1549 siop_add_dev(sc, target, lun);
1550 }
1551 break;
1552 }
1553 if (i == 0) {
1554 siop_timeout(siop_cmd);
1555 while ((xs->flags & ITSDONE0x00008) == 0)
1556 siop_intr(sc);
1557 }
1558
1559 splx(s)spllower(s);
1560}
1561
1562void
1563siop_start(struct siop_softc *sc)
1564{
1565 struct siop_cmd *siop_cmd, *next_siop_cmd;
1566 struct siop_lun *siop_lun;
1567 struct siop_xfer *siop_xfer;
1568 u_int32_t dsa;
1569 int target, lun, tag, slot;
1570 int newcmd = 0;
1571 int doingready = 0;
1572
1573 /*
1574 * first make sure to read valid data
1575 */
1576 siop_script_sync(sc, BUS_DMASYNC_POSTREAD0x02 | BUS_DMASYNC_POSTWRITE0x08);
1577
1578 /*
1579 * The queue management here is a bit tricky: the script always looks
1580 * at the slot from first to last, so if we always use the first
1581 * free slot commands can stay at the tail of the queue ~forever.
1582 * The algorithm used here is to restart from the head when we know
1583 * that the queue is empty, and only add commands after the last one.
1584 * When we're at the end of the queue wait for the script to clear it.
1585 * The best thing to do here would be to implement a circular queue,
1586 * but using only 53c720 features this can be "interesting".
1587 * A mid-way solution could be to implement 2 queues and swap orders.
1588 */
1589 slot = sc->sc_currschedslot;
1590 /*
1591 * If the instruction is 0x80000000 (JUMP foo, IF FALSE) the slot is
1592 * free. As this is the last used slot, all previous slots are free,
1593 * we can restart from 1.
1594 * slot 0 is reserved for request sense commands.
1595 */
1596 if (siop_script_read(sc, (Ent_script_sched_slot00x000000a0 / 4) + slot * 2) ==
1597 0x80000000) {
1598 slot = sc->sc_currschedslot = 1;
1599 } else {
1600 slot++;
1601 }
1602 /* first handle commands from the urgent list */
1603 siop_cmd = TAILQ_FIRST(&sc->urgent_list)((&sc->urgent_list)->tqh_first);
1604again:
1605 for (; siop_cmd != NULL((void *)0); siop_cmd = next_siop_cmd) {
1606 next_siop_cmd = TAILQ_NEXT(siop_cmd, next)((siop_cmd)->next.tqe_next);
1607#ifdef DIAGNOSTIC1
1608 if (siop_cmd->cmd_c.status != CMDST_READY1 &&
1609 siop_cmd->cmd_c.status != CMDST_SENSE3)
1610 panic("siop: non-ready cmd in ready list");
1611#endif
1612 target = siop_cmd->cmd_c.xs->sc_link->target;
1613 lun = siop_cmd->cmd_c.xs->sc_link->lun;
1614 siop_lun =
1615 ((struct siop_target*)sc->sc_c.targets[target])->siop_lun[lun];
1616 /* if non-tagged command active, wait */
1617 if (siop_lun->siop_tag[0].active != NULL((void *)0))
1618 continue;
1619 /*
1620 * if we're in a queue full condition don't start a new
1621 * command, unless it's a request sense
1622 */
1623 if ((siop_lun->lun_flags & SIOP_LUNF_FULL0x01) &&
1624 siop_cmd->cmd_c.status == CMDST_READY1)
1625 continue;
1626 /* find a free tag if needed */
1627 if (siop_cmd->cmd_c.flags & CMDFL_TAG0x0002) {
1628 for (tag = 1; tag < SIOP_NTAG16; tag++) {
1629 if (siop_lun->siop_tag[tag].active == NULL((void *)0))
1630 break;
1631 }
1632 if (tag == SIOP_NTAG16) /* no free tag */
1633 continue;
1634 } else {
1635 tag = 0;
1636 }
1637 siop_cmd->cmd_c.tag = tag;
1638 /*
1639 * find a free scheduler slot and load it. If it's a request
1640 * sense we need to use slot 0.
1641 */
1642 if (siop_cmd->cmd_c.status != CMDST_SENSE3) {
1643 for (; slot < SIOP_NSLOTS40; slot++) {
1644 /*
1645 * If cmd if 0x80000000 the slot is free
1646 */
1647 if (siop_script_read(sc,
1648 (Ent_script_sched_slot00x000000a0 / 4) + slot * 2) ==
1649 0x80000000)
1650 break;
1651 }
1652 /* no more free slots, no need to continue */
1653 if (slot == SIOP_NSLOTS40) {
1654 goto end;
1655 }
1656 } else {
1657 slot = 0;
1658 if (siop_script_read(sc, Ent_script_sched_slot00x000000a0 / 4)
1659 != 0x80000000)
1660 goto end;
1661 }
1662
1663#ifdef SIOP_DEBUG_SCHED
1664 printf("using slot %d for DSA 0x%lx\n", slot,
1665 (u_long)siop_cmd->cmd_c.dsa);
1666#endif
1667 /* Ok, we can add the tag message */
1668 if (tag > 0) {
1669#ifdef DIAGNOSTIC1
1670 int msgcount = siop_ctoh32(&sc->sc_c,(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((siop_cmd->cmd_c.siop_tables->t_msgout
.count)) ? (__uint32_t)(((__uint32_t)((siop_cmd->cmd_c.siop_tables
->t_msgout.count)) & 0xff) << 24 | ((__uint32_t)
((siop_cmd->cmd_c.siop_tables->t_msgout.count)) & 0xff00
) << 8 | ((__uint32_t)((siop_cmd->cmd_c.siop_tables->
t_msgout.count)) & 0xff0000) >> 8 | ((__uint32_t)((
siop_cmd->cmd_c.siop_tables->t_msgout.count)) & 0xff000000
) >> 24) : __swap32md((siop_cmd->cmd_c.siop_tables->
t_msgout.count))) : ((__uint32_t)((siop_cmd->cmd_c.siop_tables
->t_msgout.count))))
1671 siop_cmd->cmd_tables->t_msgout.count)(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((siop_cmd->cmd_c.siop_tables->t_msgout
.count)) ? (__uint32_t)(((__uint32_t)((siop_cmd->cmd_c.siop_tables
->t_msgout.count)) & 0xff) << 24 | ((__uint32_t)
((siop_cmd->cmd_c.siop_tables->t_msgout.count)) & 0xff00
) << 8 | ((__uint32_t)((siop_cmd->cmd_c.siop_tables->
t_msgout.count)) & 0xff0000) >> 8 | ((__uint32_t)((
siop_cmd->cmd_c.siop_tables->t_msgout.count)) & 0xff000000
) >> 24) : __swap32md((siop_cmd->cmd_c.siop_tables->
t_msgout.count))) : ((__uint32_t)((siop_cmd->cmd_c.siop_tables
->t_msgout.count))))
;
1672 if (msgcount != 1)
1673 printf("%s:%d:%d: tag %d with msgcount %d\n",
1674 sc->sc_c.sc_dev.dv_xname, target, lun, tag,
1675 msgcount);
1676#endif
1677 siop_cmd->cmd_tablescmd_c.siop_tables->msg_out[1] = MSG_SIMPLE_Q_TAG0x20;
1678 siop_cmd->cmd_tablescmd_c.siop_tables->msg_out[2] = tag;
1679 siop_cmd->cmd_tablescmd_c.siop_tables->t_msgout.count =
1680 siop_htoc32(&sc->sc_c, 3)(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((3)) ? (__uint32_t)(((__uint32_t)((3))
& 0xff) << 24 | ((__uint32_t)((3)) & 0xff00) <<
8 | ((__uint32_t)((3)) & 0xff0000) >> 8 | ((__uint32_t
)((3)) & 0xff000000) >> 24) : __swap32md((3))) : ((
__uint32_t)((3))))
;
1681 }
1682 /* note that we started a new command */
1683 newcmd = 1;
1684 /* mark command as active */
1685 if (siop_cmd->cmd_c.status == CMDST_READY1) {
1686 siop_cmd->cmd_c.status = CMDST_ACTIVE2;
1687 } else if (siop_cmd->cmd_c.status == CMDST_SENSE3) {
1688 siop_cmd->cmd_c.status = CMDST_SENSE_ACTIVE4;
1689 } else
1690 panic("siop_start: bad status");
1691 if (doingready)
1692 TAILQ_REMOVE(&sc->ready_list, siop_cmd, next)do { if (((siop_cmd)->next.tqe_next) != ((void *)0)) (siop_cmd
)->next.tqe_next->next.tqe_prev = (siop_cmd)->next.tqe_prev
; else (&sc->ready_list)->tqh_last = (siop_cmd)->
next.tqe_prev; *(siop_cmd)->next.tqe_prev = (siop_cmd)->
next.tqe_next; ((siop_cmd)->next.tqe_prev) = ((void *)-1);
((siop_cmd)->next.tqe_next) = ((void *)-1); } while (0)
;
1693 else
1694 TAILQ_REMOVE(&sc->urgent_list, siop_cmd, next)do { if (((siop_cmd)->next.tqe_next) != ((void *)0)) (siop_cmd
)->next.tqe_next->next.tqe_prev = (siop_cmd)->next.tqe_prev
; else (&sc->urgent_list)->tqh_last = (siop_cmd)->
next.tqe_prev; *(siop_cmd)->next.tqe_prev = (siop_cmd)->
next.tqe_next; ((siop_cmd)->next.tqe_prev) = ((void *)-1);
((siop_cmd)->next.tqe_next) = ((void *)-1); } while (0)
;
1695 siop_lun->siop_tag[tag].active = siop_cmd;
1696 /* patch scripts with DSA addr */
1697 dsa = siop_cmd->cmd_c.dsa;
1698 /* first reselect switch, if we have an entry */
1699 if (siop_lun->siop_tag[tag].reseloff > 0)
1700 siop_script_write(sc,
1701 siop_lun->siop_tag[tag].reseloff + 1,
1702 dsa + sizeof(struct siop_common_xfer) +
1703 Ent_ldsa_reload_dsa0x00000028);
1704 /* CMD script: MOVE MEMORY addr */
1705 siop_xfer = (struct siop_xfer*)siop_cmd->cmd_tablescmd_c.siop_tables;
1706 siop_xfer->resel[E_ldsa_abs_slot_Used[0]] =
1707 siop_htoc32(&sc->sc_c, sc->sc_c.sc_scriptaddr +(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((sc->sc_c.sc_scriptaddr + 0x000000a0
+ slot * 8)) ? (__uint32_t)(((__uint32_t)((sc->sc_c.sc_scriptaddr
+ 0x000000a0 + slot * 8)) & 0xff) << 24 | ((__uint32_t
)((sc->sc_c.sc_scriptaddr + 0x000000a0 + slot * 8)) & 0xff00
) << 8 | ((__uint32_t)((sc->sc_c.sc_scriptaddr + 0x000000a0
+ slot * 8)) & 0xff0000) >> 8 | ((__uint32_t)((sc->
sc_c.sc_scriptaddr + 0x000000a0 + slot * 8)) & 0xff000000
) >> 24) : __swap32md((sc->sc_c.sc_scriptaddr + 0x000000a0
+ slot * 8))) : ((__uint32_t)((sc->sc_c.sc_scriptaddr + 0x000000a0
+ slot * 8))))
1708 Ent_script_sched_slot0 + slot * 8)(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((sc->sc_c.sc_scriptaddr + 0x000000a0
+ slot * 8)) ? (__uint32_t)(((__uint32_t)((sc->sc_c.sc_scriptaddr
+ 0x000000a0 + slot * 8)) & 0xff) << 24 | ((__uint32_t
)((sc->sc_c.sc_scriptaddr + 0x000000a0 + slot * 8)) & 0xff00
) << 8 | ((__uint32_t)((sc->sc_c.sc_scriptaddr + 0x000000a0
+ slot * 8)) & 0xff0000) >> 8 | ((__uint32_t)((sc->
sc_c.sc_scriptaddr + 0x000000a0 + slot * 8)) & 0xff000000
) >> 24) : __swap32md((sc->sc_c.sc_scriptaddr + 0x000000a0
+ slot * 8))) : ((__uint32_t)((sc->sc_c.sc_scriptaddr + 0x000000a0
+ slot * 8))))
;
1709 siop_table_sync(siop_cmd, BUS_DMASYNC_PREWRITE0x04);
1710 /* scheduler slot: JUMP ldsa_select */
1711 siop_script_write(sc,
1712 (Ent_script_sched_slot00x000000a0 / 4) + slot * 2 + 1,
1713 dsa + sizeof(struct siop_common_xfer) + Ent_ldsa_select0x00000038);
1714 /* handle timeout */
1715 if (siop_cmd->cmd_c.status == CMDST_ACTIVE2) {
1716 if ((siop_cmd->cmd_c.xs->flags & SCSI_POLL0x00002) == 0) {
1717 /* start expire timer */
1718 timeout_add_msec(&siop_cmd->cmd_c.xs->stimeout,
1719 siop_cmd->cmd_c.xs->timeout);
1720 }
1721 }
1722 /*
1723 * Change JUMP cmd so that this slot will be handled
1724 */
1725 siop_script_write(sc, (Ent_script_sched_slot00x000000a0 / 4) + slot * 2,
1726 0x80080000);
1727 /* if we're using the request sense slot, stop here */
1728 if (slot == 0)
1729 goto end;
1730 sc->sc_currschedslot = slot;
1731 slot++;
1732 }
1733 if (doingready == 0) {
1734 /* now process ready list */
1735 doingready = 1;
1736 siop_cmd = TAILQ_FIRST(&sc->ready_list)((&sc->ready_list)->tqh_first);
1737 goto again;
1738 }
1739
1740end:
1741 /* if nothing changed no need to flush cache and wakeup script */
1742 if (newcmd == 0)
1743 return;
1744 /* make sure SCRIPT processor will read valid data */
1745 siop_script_sync(sc,BUS_DMASYNC_PREREAD0x01 | BUS_DMASYNC_PREWRITE0x04);
1746 /* Signal script it has some work to do */
1747 bus_space_write_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh,((sc->sc_c.sc_rt)->write_1((sc->sc_c.sc_rh), (0x14),
(0x20)))
1748 SIOP_ISTAT, ISTAT_SIGP)((sc->sc_c.sc_rt)->write_1((sc->sc_c.sc_rh), (0x14),
(0x20)))
;
1749 /* and wait for IRQ */
1750}
1751
1752void
1753siop_timeout(void *v)
1754{
1755 struct siop_cmd *siop_cmd = v;
1756 struct siop_softc *sc = (struct siop_softc *)siop_cmd->cmd_c.siop_sc;
1757 int s;
1758
1759 /* deactivate callout */
1760 timeout_del(&siop_cmd->cmd_c.xs->stimeout);
1761
1762 sc_print_addr(siop_cmd->cmd_c.xs->sc_link);
1763 printf("timeout on SCSI command 0x%x\n",
1764 siop_cmd->cmd_c.xs->cmd.opcode);
1765
1766 s = splbio()splraise(0x6);
1767 /* reset the scsi bus */
1768 siop_resetbus(&sc->sc_c);
1769 siop_cmd->cmd_c.flags |= CMDFL_TIMEOUT0x0001;
1770 siop_handle_reset(sc);
1771 splx(s)spllower(s);
1772}
1773
1774#ifdef DUMP_SCRIPT
1775void
1776siop_dump_script(struct siop_softc *sc)
1777{
1778 int i;
1779 for (i = 0; i < PAGE_SIZE(1 << 12) / 4; i += 2) {
1780 printf("0x%04x: 0x%08x 0x%08x", i * 4,
1781 siop_ctoh32(&sc->sc_c, sc->sc_c.sc_script[i])(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((sc->sc_c.sc_script[i])) ? (__uint32_t
)(((__uint32_t)((sc->sc_c.sc_script[i])) & 0xff) <<
24 | ((__uint32_t)((sc->sc_c.sc_script[i])) & 0xff00)
<< 8 | ((__uint32_t)((sc->sc_c.sc_script[i])) &
0xff0000) >> 8 | ((__uint32_t)((sc->sc_c.sc_script[
i])) & 0xff000000) >> 24) : __swap32md((sc->sc_c
.sc_script[i]))) : ((__uint32_t)((sc->sc_c.sc_script[i])))
)
,
1782 siop_ctoh32(&sc->sc_c, sc->sc_c.sc_script[i+1])(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((sc->sc_c.sc_script[i+1])) ? (__uint32_t
)(((__uint32_t)((sc->sc_c.sc_script[i+1])) & 0xff) <<
24 | ((__uint32_t)((sc->sc_c.sc_script[i+1])) & 0xff00
) << 8 | ((__uint32_t)((sc->sc_c.sc_script[i+1])) &
0xff0000) >> 8 | ((__uint32_t)((sc->sc_c.sc_script[
i+1])) & 0xff000000) >> 24) : __swap32md((sc->sc_c
.sc_script[i+1]))) : ((__uint32_t)((sc->sc_c.sc_script[i+1
]))))
);
1783 if ((siop_ctoh32(&sc->sc_c,(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((sc->sc_c.sc_script[i])) ? (__uint32_t
)(((__uint32_t)((sc->sc_c.sc_script[i])) & 0xff) <<
24 | ((__uint32_t)((sc->sc_c.sc_script[i])) & 0xff00)
<< 8 | ((__uint32_t)((sc->sc_c.sc_script[i])) &
0xff0000) >> 8 | ((__uint32_t)((sc->sc_c.sc_script[
i])) & 0xff000000) >> 24) : __swap32md((sc->sc_c
.sc_script[i]))) : ((__uint32_t)((sc->sc_c.sc_script[i])))
)
1784 sc->sc_c.sc_script[i])(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((sc->sc_c.sc_script[i])) ? (__uint32_t
)(((__uint32_t)((sc->sc_c.sc_script[i])) & 0xff) <<
24 | ((__uint32_t)((sc->sc_c.sc_script[i])) & 0xff00)
<< 8 | ((__uint32_t)((sc->sc_c.sc_script[i])) &
0xff0000) >> 8 | ((__uint32_t)((sc->sc_c.sc_script[
i])) & 0xff000000) >> 24) : __swap32md((sc->sc_c
.sc_script[i]))) : ((__uint32_t)((sc->sc_c.sc_script[i])))
)
& 0xe0000000) == 0xc0000000) {
1785 i++;
1786 printf(" 0x%08x", siop_ctoh32(&sc->sc_c,(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((sc->sc_c.sc_script[i+1])) ? (__uint32_t
)(((__uint32_t)((sc->sc_c.sc_script[i+1])) & 0xff) <<
24 | ((__uint32_t)((sc->sc_c.sc_script[i+1])) & 0xff00
) << 8 | ((__uint32_t)((sc->sc_c.sc_script[i+1])) &
0xff0000) >> 8 | ((__uint32_t)((sc->sc_c.sc_script[
i+1])) & 0xff000000) >> 24) : __swap32md((sc->sc_c
.sc_script[i+1]))) : ((__uint32_t)((sc->sc_c.sc_script[i+1
]))))
1787 sc->sc_c.sc_script[i+1])(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((sc->sc_c.sc_script[i+1])) ? (__uint32_t
)(((__uint32_t)((sc->sc_c.sc_script[i+1])) & 0xff) <<
24 | ((__uint32_t)((sc->sc_c.sc_script[i+1])) & 0xff00
) << 8 | ((__uint32_t)((sc->sc_c.sc_script[i+1])) &
0xff0000) >> 8 | ((__uint32_t)((sc->sc_c.sc_script[
i+1])) & 0xff000000) >> 24) : __swap32md((sc->sc_c
.sc_script[i+1]))) : ((__uint32_t)((sc->sc_c.sc_script[i+1
]))))
);
1788 }
1789 printf("\n");
1790 }
1791}
1792#endif
1793
1794void
1795siop_morecbd(struct siop_softc *sc)
1796{
1797 int error, off, i, j, s;
1798 struct siop_cbd *newcbd;
1799 struct siop_xfer *xfers, *xfer;
1800 bus_addr_t dsa;
1801 u_int32_t *scr;
1802 size_t sense_size = roundup(sizeof(struct scsi_sense_data), 16)((((sizeof(struct scsi_sense_data))+((16)-1))/(16))*(16));
1803
1804 /* allocate a new list head */
1805 newcbd = malloc(sizeof(struct siop_cbd), M_DEVBUF2, M_NOWAIT0x0002 | M_ZERO0x0008);
1806 if (newcbd == NULL((void *)0)) {
1807 printf("%s: can't allocate memory for command descriptors "
1808 "head\n", sc->sc_c.sc_dev.dv_xname);
1809 return;
1810 }
1811
1812 /* allocate cmd list */
1813 newcbd->cmds = mallocarray(SIOP_NCMDPB((1 << 12) / sizeof(struct siop_xfer)), sizeof(struct siop_cmd),
1814 M_DEVBUF2, M_NOWAIT0x0002 | M_ZERO0x0008);
1815 if (newcbd->cmds == NULL((void *)0)) {
1816 printf("%s: can't allocate memory for command descriptors\n",
1817 sc->sc_c.sc_dev.dv_xname);
1818 goto bad3;
1819 }
1820
1821 newcbd->xfers = siop_dmamem_alloc(sc, PAGE_SIZE(1 << 12));
1822 if (newcbd->xfers == NULL((void *)0)) {
1823 printf("%s: unable to allocate cbd xfer DMA memory\n",
1824 sc->sc_c.sc_dev.dv_xname);
1825 goto bad2;
1826 }
1827 xfers = SIOP_DMA_KVA(newcbd->xfers)((void *)(newcbd->xfers)->sdm_kva);
1828
1829 newcbd->sense = siop_dmamem_alloc(sc, sense_size * SIOP_NCMDPB((1 << 12) / sizeof(struct siop_xfer)));
1830 if (newcbd->sense == NULL((void *)0)) {
1831 printf("%s: unable to allocate cbd sense DMA memory\n",
1832 sc->sc_c.sc_dev.dv_xname);
1833 goto bad1;
1834 }
1835
1836 for (i = 0; i < SIOP_NCMDPB((1 << 12) / sizeof(struct siop_xfer)); i++) {
1837 error = bus_dmamap_create(sc->sc_c.sc_dmat, MAXPHYS, SIOP_NSG,(*(sc->sc_c.sc_dmat)->_dmamap_create)((sc->sc_c.sc_dmat
), ((64 * 1024)), (17), ((64 * 1024)), (0), (0x0001 | 0x0002)
, (&newcbd->cmds[i].cmd_c.dmamap_data))
1838 MAXPHYS, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,(*(sc->sc_c.sc_dmat)->_dmamap_create)((sc->sc_c.sc_dmat
), ((64 * 1024)), (17), ((64 * 1024)), (0), (0x0001 | 0x0002)
, (&newcbd->cmds[i].cmd_c.dmamap_data))
1839 &newcbd->cmds[i].cmd_c.dmamap_data)(*(sc->sc_c.sc_dmat)->_dmamap_create)((sc->sc_c.sc_dmat
), ((64 * 1024)), (17), ((64 * 1024)), (0), (0x0001 | 0x0002)
, (&newcbd->cmds[i].cmd_c.dmamap_data))
;
1840 if (error) {
1841 printf("%s: unable to create data DMA map for cbd: "
1842 "error %d\n",
1843 sc->sc_c.sc_dev.dv_xname, error);
1844 goto bad0;
1845 }
1846 }
1847
1848 /* Use two loops since bailing out above releases allocated memory */
1849 off = (sc->sc_c.features & SF_CHIP_BE0x00200000) ? 3 : 0;
1850 for (i = 0; i < SIOP_NCMDPB((1 << 12) / sizeof(struct siop_xfer)); i++) {
1851 newcbd->cmds[i].cmd_c.siop_sc = &sc->sc_c;
1852 newcbd->cmds[i].siop_cbdp = newcbd;
1853 xfer = &xfers[i];
1854 newcbd->cmds[i].cmd_tablescmd_c.siop_tables = (struct siop_common_xfer *)xfer;
1855 bzero(newcbd->cmds[i].cmd_tables, sizeof(struct siop_xfer))__builtin_bzero((newcbd->cmds[i].cmd_c.siop_tables), (sizeof
(struct siop_xfer)))
;
1856 dsa = SIOP_DMA_DVA(newcbd->xfers)((newcbd->xfers)->sdm_map->dm_segs[0].ds_addr) +
1857 i * sizeof(struct siop_xfer);
1858 newcbd->cmds[i].cmd_c.dsa = dsa;
1859 newcbd->cmds[i].cmd_c.status = CMDST_FREE0;
1860 newcbd->cmds[i].cmd_c.sense = (struct scsi_sense_data *)(
1861 i * sense_size +
1862 (u_int8_t *)SIOP_DMA_KVA(newcbd->sense)((void *)(newcbd->sense)->sdm_kva));
1863 xfer->siop_tables.t_msgout.count= siop_htoc32(&sc->sc_c, 1)(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((1)) ? (__uint32_t)(((__uint32_t)((1))
& 0xff) << 24 | ((__uint32_t)((1)) & 0xff00) <<
8 | ((__uint32_t)((1)) & 0xff0000) >> 8 | ((__uint32_t
)((1)) & 0xff000000) >> 24) : __swap32md((1))) : ((
__uint32_t)((1))))
;
1864 xfer->siop_tables.t_msgout.addr = siop_htoc32(&sc->sc_c, dsa)(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((dsa)) ? (__uint32_t)(((__uint32_t)((dsa
)) & 0xff) << 24 | ((__uint32_t)((dsa)) & 0xff00
) << 8 | ((__uint32_t)((dsa)) & 0xff0000) >> 8
| ((__uint32_t)((dsa)) & 0xff000000) >> 24) : __swap32md
((dsa))) : ((__uint32_t)((dsa))))
;
1865 xfer->siop_tables.t_msgin.count= siop_htoc32(&sc->sc_c, 1)(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((1)) ? (__uint32_t)(((__uint32_t)((1))
& 0xff) << 24 | ((__uint32_t)((1)) & 0xff00) <<
8 | ((__uint32_t)((1)) & 0xff0000) >> 8 | ((__uint32_t
)((1)) & 0xff000000) >> 24) : __swap32md((1))) : ((
__uint32_t)((1))))
;
1866 xfer->siop_tables.t_msgin.addr = siop_htoc32(&sc->sc_c,(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((dsa + __builtin_offsetof(struct siop_common_xfer
, msg_in))) ? (__uint32_t)(((__uint32_t)((dsa + __builtin_offsetof
(struct siop_common_xfer, msg_in))) & 0xff) << 24 |
((__uint32_t)((dsa + __builtin_offsetof(struct siop_common_xfer
, msg_in))) & 0xff00) << 8 | ((__uint32_t)((dsa + __builtin_offsetof
(struct siop_common_xfer, msg_in))) & 0xff0000) >> 8
| ((__uint32_t)((dsa + __builtin_offsetof(struct siop_common_xfer
, msg_in))) & 0xff000000) >> 24) : __swap32md((dsa +
__builtin_offsetof(struct siop_common_xfer, msg_in)))) : ((__uint32_t
)((dsa + __builtin_offsetof(struct siop_common_xfer, msg_in))
)))
1867 dsa + offsetof(struct siop_common_xfer, msg_in))(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((dsa + __builtin_offsetof(struct siop_common_xfer
, msg_in))) ? (__uint32_t)(((__uint32_t)((dsa + __builtin_offsetof
(struct siop_common_xfer, msg_in))) & 0xff) << 24 |
((__uint32_t)((dsa + __builtin_offsetof(struct siop_common_xfer
, msg_in))) & 0xff00) << 8 | ((__uint32_t)((dsa + __builtin_offsetof
(struct siop_common_xfer, msg_in))) & 0xff0000) >> 8
| ((__uint32_t)((dsa + __builtin_offsetof(struct siop_common_xfer
, msg_in))) & 0xff000000) >> 24) : __swap32md((dsa +
__builtin_offsetof(struct siop_common_xfer, msg_in)))) : ((__uint32_t
)((dsa + __builtin_offsetof(struct siop_common_xfer, msg_in))
)))
;
1868 xfer->siop_tables.t_extmsgin.count= siop_htoc32(&sc->sc_c, 2)(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((2)) ? (__uint32_t)(((__uint32_t)((2))
& 0xff) << 24 | ((__uint32_t)((2)) & 0xff00) <<
8 | ((__uint32_t)((2)) & 0xff0000) >> 8 | ((__uint32_t
)((2)) & 0xff000000) >> 24) : __swap32md((2))) : ((
__uint32_t)((2))))
;
1869 xfer->siop_tables.t_extmsgin.addr = siop_htoc32(&sc->sc_c,(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((dsa + __builtin_offsetof(struct siop_common_xfer
, msg_in) + 1)) ? (__uint32_t)(((__uint32_t)((dsa + __builtin_offsetof
(struct siop_common_xfer, msg_in) + 1)) & 0xff) << 24
| ((__uint32_t)((dsa + __builtin_offsetof(struct siop_common_xfer
, msg_in) + 1)) & 0xff00) << 8 | ((__uint32_t)((dsa
+ __builtin_offsetof(struct siop_common_xfer, msg_in) + 1)) &
0xff0000) >> 8 | ((__uint32_t)((dsa + __builtin_offsetof
(struct siop_common_xfer, msg_in) + 1)) & 0xff000000) >>
24) : __swap32md((dsa + __builtin_offsetof(struct siop_common_xfer
, msg_in) + 1))) : ((__uint32_t)((dsa + __builtin_offsetof(struct
siop_common_xfer, msg_in) + 1))))
1870 dsa + offsetof(struct siop_common_xfer, msg_in) + 1)(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((dsa + __builtin_offsetof(struct siop_common_xfer
, msg_in) + 1)) ? (__uint32_t)(((__uint32_t)((dsa + __builtin_offsetof
(struct siop_common_xfer, msg_in) + 1)) & 0xff) << 24
| ((__uint32_t)((dsa + __builtin_offsetof(struct siop_common_xfer
, msg_in) + 1)) & 0xff00) << 8 | ((__uint32_t)((dsa
+ __builtin_offsetof(struct siop_common_xfer, msg_in) + 1)) &
0xff0000) >> 8 | ((__uint32_t)((dsa + __builtin_offsetof
(struct siop_common_xfer, msg_in) + 1)) & 0xff000000) >>
24) : __swap32md((dsa + __builtin_offsetof(struct siop_common_xfer
, msg_in) + 1))) : ((__uint32_t)((dsa + __builtin_offsetof(struct
siop_common_xfer, msg_in) + 1))))
;
1871 xfer->siop_tables.t_extmsgdata.addr = siop_htoc32(&sc->sc_c,(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((dsa + __builtin_offsetof(struct siop_common_xfer
, msg_in) + 3)) ? (__uint32_t)(((__uint32_t)((dsa + __builtin_offsetof
(struct siop_common_xfer, msg_in) + 3)) & 0xff) << 24
| ((__uint32_t)((dsa + __builtin_offsetof(struct siop_common_xfer
, msg_in) + 3)) & 0xff00) << 8 | ((__uint32_t)((dsa
+ __builtin_offsetof(struct siop_common_xfer, msg_in) + 3)) &
0xff0000) >> 8 | ((__uint32_t)((dsa + __builtin_offsetof
(struct siop_common_xfer, msg_in) + 3)) & 0xff000000) >>
24) : __swap32md((dsa + __builtin_offsetof(struct siop_common_xfer
, msg_in) + 3))) : ((__uint32_t)((dsa + __builtin_offsetof(struct
siop_common_xfer, msg_in) + 3))))
1872 dsa + offsetof(struct siop_common_xfer, msg_in) + 3)(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((dsa + __builtin_offsetof(struct siop_common_xfer
, msg_in) + 3)) ? (__uint32_t)(((__uint32_t)((dsa + __builtin_offsetof
(struct siop_common_xfer, msg_in) + 3)) & 0xff) << 24
| ((__uint32_t)((dsa + __builtin_offsetof(struct siop_common_xfer
, msg_in) + 3)) & 0xff00) << 8 | ((__uint32_t)((dsa
+ __builtin_offsetof(struct siop_common_xfer, msg_in) + 3)) &
0xff0000) >> 8 | ((__uint32_t)((dsa + __builtin_offsetof
(struct siop_common_xfer, msg_in) + 3)) & 0xff000000) >>
24) : __swap32md((dsa + __builtin_offsetof(struct siop_common_xfer
, msg_in) + 3))) : ((__uint32_t)((dsa + __builtin_offsetof(struct
siop_common_xfer, msg_in) + 3))))
;
1873 xfer->siop_tables.t_status.count= siop_htoc32(&sc->sc_c, 1)(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((1)) ? (__uint32_t)(((__uint32_t)((1))
& 0xff) << 24 | ((__uint32_t)((1)) & 0xff00) <<
8 | ((__uint32_t)((1)) & 0xff0000) >> 8 | ((__uint32_t
)((1)) & 0xff000000) >> 24) : __swap32md((1))) : ((
__uint32_t)((1))))
;
1874 xfer->siop_tables.t_status.addr = siop_htoc32(&sc->sc_c,(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((dsa + __builtin_offsetof(struct siop_common_xfer
, status) + off)) ? (__uint32_t)(((__uint32_t)((dsa + __builtin_offsetof
(struct siop_common_xfer, status) + off)) & 0xff) <<
24 | ((__uint32_t)((dsa + __builtin_offsetof(struct siop_common_xfer
, status) + off)) & 0xff00) << 8 | ((__uint32_t)((dsa
+ __builtin_offsetof(struct siop_common_xfer, status) + off)
) & 0xff0000) >> 8 | ((__uint32_t)((dsa + __builtin_offsetof
(struct siop_common_xfer, status) + off)) & 0xff000000) >>
24) : __swap32md((dsa + __builtin_offsetof(struct siop_common_xfer
, status) + off))) : ((__uint32_t)((dsa + __builtin_offsetof(
struct siop_common_xfer, status) + off))))
1875 dsa + offsetof(struct siop_common_xfer, status) + off)(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((dsa + __builtin_offsetof(struct siop_common_xfer
, status) + off)) ? (__uint32_t)(((__uint32_t)((dsa + __builtin_offsetof
(struct siop_common_xfer, status) + off)) & 0xff) <<
24 | ((__uint32_t)((dsa + __builtin_offsetof(struct siop_common_xfer
, status) + off)) & 0xff00) << 8 | ((__uint32_t)((dsa
+ __builtin_offsetof(struct siop_common_xfer, status) + off)
) & 0xff0000) >> 8 | ((__uint32_t)((dsa + __builtin_offsetof
(struct siop_common_xfer, status) + off)) & 0xff000000) >>
24) : __swap32md((dsa + __builtin_offsetof(struct siop_common_xfer
, status) + off))) : ((__uint32_t)((dsa + __builtin_offsetof(
struct siop_common_xfer, status) + off))))
;
1876 xfer->siop_tables.cmd.count = siop_htoc32(&sc->sc_c, 0)(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((0)) ? (__uint32_t)(((__uint32_t)((0))
& 0xff) << 24 | ((__uint32_t)((0)) & 0xff00) <<
8 | ((__uint32_t)((0)) & 0xff0000) >> 8 | ((__uint32_t
)((0)) & 0xff000000) >> 24) : __swap32md((0))) : ((
__uint32_t)((0))))
;
1877 xfer->siop_tables.cmd.addr = siop_htoc32(&sc->sc_c,(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((dsa + __builtin_offsetof(struct siop_common_xfer
, xscmd))) ? (__uint32_t)(((__uint32_t)((dsa + __builtin_offsetof
(struct siop_common_xfer, xscmd))) & 0xff) << 24 | (
(__uint32_t)((dsa + __builtin_offsetof(struct siop_common_xfer
, xscmd))) & 0xff00) << 8 | ((__uint32_t)((dsa + __builtin_offsetof
(struct siop_common_xfer, xscmd))) & 0xff0000) >> 8
| ((__uint32_t)((dsa + __builtin_offsetof(struct siop_common_xfer
, xscmd))) & 0xff000000) >> 24) : __swap32md((dsa +
__builtin_offsetof(struct siop_common_xfer, xscmd)))) : ((__uint32_t
)((dsa + __builtin_offsetof(struct siop_common_xfer, xscmd)))
))
1878 dsa + offsetof(struct siop_common_xfer, xscmd))(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((dsa + __builtin_offsetof(struct siop_common_xfer
, xscmd))) ? (__uint32_t)(((__uint32_t)((dsa + __builtin_offsetof
(struct siop_common_xfer, xscmd))) & 0xff) << 24 | (
(__uint32_t)((dsa + __builtin_offsetof(struct siop_common_xfer
, xscmd))) & 0xff00) << 8 | ((__uint32_t)((dsa + __builtin_offsetof
(struct siop_common_xfer, xscmd))) & 0xff0000) >> 8
| ((__uint32_t)((dsa + __builtin_offsetof(struct siop_common_xfer
, xscmd))) & 0xff000000) >> 24) : __swap32md((dsa +
__builtin_offsetof(struct siop_common_xfer, xscmd)))) : ((__uint32_t
)((dsa + __builtin_offsetof(struct siop_common_xfer, xscmd)))
))
;
1879 /* The select/reselect script */
1880 scr = &xfer->resel[0];
1881 for (j = 0; j < sizeof(load_dsa) / sizeof(load_dsa[0]); j++)
1882 scr[j] = siop_htoc32(&sc->sc_c, load_dsa[j])(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((load_dsa[j])) ? (__uint32_t)(((__uint32_t
)((load_dsa[j])) & 0xff) << 24 | ((__uint32_t)((load_dsa
[j])) & 0xff00) << 8 | ((__uint32_t)((load_dsa[j]))
& 0xff0000) >> 8 | ((__uint32_t)((load_dsa[j])) &
0xff000000) >> 24) : __swap32md((load_dsa[j]))) : ((__uint32_t
)((load_dsa[j]))))
;
1883 /*
1884 * 0x78000000 is a 'move data8 to reg'. data8 is the second
1885 * octet, reg offset is the third.
1886 */
1887 scr[Ent_rdsa00x00000000 / 4] = siop_htoc32(&sc->sc_c,(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((0x78100000 | ((dsa & 0x000000ff) <<
8))) ? (__uint32_t)(((__uint32_t)((0x78100000 | ((dsa & 0x000000ff
) << 8))) & 0xff) << 24 | ((__uint32_t)((0x78100000
| ((dsa & 0x000000ff) << 8))) & 0xff00) <<
8 | ((__uint32_t)((0x78100000 | ((dsa & 0x000000ff) <<
8))) & 0xff0000) >> 8 | ((__uint32_t)((0x78100000 |
((dsa & 0x000000ff) << 8))) & 0xff000000) >>
24) : __swap32md((0x78100000 | ((dsa & 0x000000ff) <<
8)))) : ((__uint32_t)((0x78100000 | ((dsa & 0x000000ff) <<
8)))))
1888 0x78100000 | ((dsa & 0x000000ff) << 8))(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((0x78100000 | ((dsa & 0x000000ff) <<
8))) ? (__uint32_t)(((__uint32_t)((0x78100000 | ((dsa & 0x000000ff
) << 8))) & 0xff) << 24 | ((__uint32_t)((0x78100000
| ((dsa & 0x000000ff) << 8))) & 0xff00) <<
8 | ((__uint32_t)((0x78100000 | ((dsa & 0x000000ff) <<
8))) & 0xff0000) >> 8 | ((__uint32_t)((0x78100000 |
((dsa & 0x000000ff) << 8))) & 0xff000000) >>
24) : __swap32md((0x78100000 | ((dsa & 0x000000ff) <<
8)))) : ((__uint32_t)((0x78100000 | ((dsa & 0x000000ff) <<
8)))))
;
1889 scr[Ent_rdsa10x00000008 / 4] = siop_htoc32(&sc->sc_c,(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((0x78110000 | ( dsa & 0x0000ff00 )
)) ? (__uint32_t)(((__uint32_t)((0x78110000 | ( dsa & 0x0000ff00
))) & 0xff) << 24 | ((__uint32_t)((0x78110000 | ( dsa
& 0x0000ff00 ))) & 0xff00) << 8 | ((__uint32_t
)((0x78110000 | ( dsa & 0x0000ff00 ))) & 0xff0000) >>
8 | ((__uint32_t)((0x78110000 | ( dsa & 0x0000ff00 ))) &
0xff000000) >> 24) : __swap32md((0x78110000 | ( dsa &
0x0000ff00 )))) : ((__uint32_t)((0x78110000 | ( dsa & 0x0000ff00
)))))
1890 0x78110000 | ( dsa & 0x0000ff00 ))(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((0x78110000 | ( dsa & 0x0000ff00 )
)) ? (__uint32_t)(((__uint32_t)((0x78110000 | ( dsa & 0x0000ff00
))) & 0xff) << 24 | ((__uint32_t)((0x78110000 | ( dsa
& 0x0000ff00 ))) & 0xff00) << 8 | ((__uint32_t
)((0x78110000 | ( dsa & 0x0000ff00 ))) & 0xff0000) >>
8 | ((__uint32_t)((0x78110000 | ( dsa & 0x0000ff00 ))) &
0xff000000) >> 24) : __swap32md((0x78110000 | ( dsa &
0x0000ff00 )))) : ((__uint32_t)((0x78110000 | ( dsa & 0x0000ff00
)))))
;
1891 scr[Ent_rdsa20x00000010 / 4] = siop_htoc32(&sc->sc_c,(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((0x78120000 | ((dsa & 0x00ff0000) >>
8))) ? (__uint32_t)(((__uint32_t)((0x78120000 | ((dsa & 0x00ff0000
) >> 8))) & 0xff) << 24 | ((__uint32_t)((0x78120000
| ((dsa & 0x00ff0000) >> 8))) & 0xff00) <<
8 | ((__uint32_t)((0x78120000 | ((dsa & 0x00ff0000) >>
8))) & 0xff0000) >> 8 | ((__uint32_t)((0x78120000 |
((dsa & 0x00ff0000) >> 8))) & 0xff000000) >>
24) : __swap32md((0x78120000 | ((dsa & 0x00ff0000) >>
8)))) : ((__uint32_t)((0x78120000 | ((dsa & 0x00ff0000) >>
8)))))
1892 0x78120000 | ((dsa & 0x00ff0000) >> 8))(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((0x78120000 | ((dsa & 0x00ff0000) >>
8))) ? (__uint32_t)(((__uint32_t)((0x78120000 | ((dsa & 0x00ff0000
) >> 8))) & 0xff) << 24 | ((__uint32_t)((0x78120000
| ((dsa & 0x00ff0000) >> 8))) & 0xff00) <<
8 | ((__uint32_t)((0x78120000 | ((dsa & 0x00ff0000) >>
8))) & 0xff0000) >> 8 | ((__uint32_t)((0x78120000 |
((dsa & 0x00ff0000) >> 8))) & 0xff000000) >>
24) : __swap32md((0x78120000 | ((dsa & 0x00ff0000) >>
8)))) : ((__uint32_t)((0x78120000 | ((dsa & 0x00ff0000) >>
8)))))
;
1893 scr[Ent_rdsa30x00000018 / 4] = siop_htoc32(&sc->sc_c,(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((0x78130000 | ((dsa & 0xff000000) >>
16))) ? (__uint32_t)(((__uint32_t)((0x78130000 | ((dsa &
0xff000000) >> 16))) & 0xff) << 24 | ((__uint32_t
)((0x78130000 | ((dsa & 0xff000000) >> 16))) & 0xff00
) << 8 | ((__uint32_t)((0x78130000 | ((dsa & 0xff000000
) >> 16))) & 0xff0000) >> 8 | ((__uint32_t)((
0x78130000 | ((dsa & 0xff000000) >> 16))) & 0xff000000
) >> 24) : __swap32md((0x78130000 | ((dsa & 0xff000000
) >> 16)))) : ((__uint32_t)((0x78130000 | ((dsa & 0xff000000
) >> 16)))))
1894 0x78130000 | ((dsa & 0xff000000) >> 16))(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((0x78130000 | ((dsa & 0xff000000) >>
16))) ? (__uint32_t)(((__uint32_t)((0x78130000 | ((dsa &
0xff000000) >> 16))) & 0xff) << 24 | ((__uint32_t
)((0x78130000 | ((dsa & 0xff000000) >> 16))) & 0xff00
) << 8 | ((__uint32_t)((0x78130000 | ((dsa & 0xff000000
) >> 16))) & 0xff0000) >> 8 | ((__uint32_t)((
0x78130000 | ((dsa & 0xff000000) >> 16))) & 0xff000000
) >> 24) : __swap32md((0x78130000 | ((dsa & 0xff000000
) >> 16)))) : ((__uint32_t)((0x78130000 | ((dsa & 0xff000000
) >> 16)))))
;
1895 scr[E_ldsa_abs_reselected_Used[0]] = siop_htoc32(&sc->sc_c,(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((sc->sc_c.sc_scriptaddr + 0x00000000
)) ? (__uint32_t)(((__uint32_t)((sc->sc_c.sc_scriptaddr + 0x00000000
)) & 0xff) << 24 | ((__uint32_t)((sc->sc_c.sc_scriptaddr
+ 0x00000000)) & 0xff00) << 8 | ((__uint32_t)((sc->
sc_c.sc_scriptaddr + 0x00000000)) & 0xff0000) >> 8 |
((__uint32_t)((sc->sc_c.sc_scriptaddr + 0x00000000)) &
0xff000000) >> 24) : __swap32md((sc->sc_c.sc_scriptaddr
+ 0x00000000))) : ((__uint32_t)((sc->sc_c.sc_scriptaddr +
0x00000000))))
1896 sc->sc_c.sc_scriptaddr + Ent_reselected)(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((sc->sc_c.sc_scriptaddr + 0x00000000
)) ? (__uint32_t)(((__uint32_t)((sc->sc_c.sc_scriptaddr + 0x00000000
)) & 0xff) << 24 | ((__uint32_t)((sc->sc_c.sc_scriptaddr
+ 0x00000000)) & 0xff00) << 8 | ((__uint32_t)((sc->
sc_c.sc_scriptaddr + 0x00000000)) & 0xff0000) >> 8 |
((__uint32_t)((sc->sc_c.sc_scriptaddr + 0x00000000)) &
0xff000000) >> 24) : __swap32md((sc->sc_c.sc_scriptaddr
+ 0x00000000))) : ((__uint32_t)((sc->sc_c.sc_scriptaddr +
0x00000000))))
;
1897 scr[E_ldsa_abs_reselect_Used[0]] = siop_htoc32(&sc->sc_c,(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((sc->sc_c.sc_scriptaddr + 0x000001e0
)) ? (__uint32_t)(((__uint32_t)((sc->sc_c.sc_scriptaddr + 0x000001e0
)) & 0xff) << 24 | ((__uint32_t)((sc->sc_c.sc_scriptaddr
+ 0x000001e0)) & 0xff00) << 8 | ((__uint32_t)((sc->
sc_c.sc_scriptaddr + 0x000001e0)) & 0xff0000) >> 8 |
((__uint32_t)((sc->sc_c.sc_scriptaddr + 0x000001e0)) &
0xff000000) >> 24) : __swap32md((sc->sc_c.sc_scriptaddr
+ 0x000001e0))) : ((__uint32_t)((sc->sc_c.sc_scriptaddr +
0x000001e0))))
1898 sc->sc_c.sc_scriptaddr + Ent_reselect)(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((sc->sc_c.sc_scriptaddr + 0x000001e0
)) ? (__uint32_t)(((__uint32_t)((sc->sc_c.sc_scriptaddr + 0x000001e0
)) & 0xff) << 24 | ((__uint32_t)((sc->sc_c.sc_scriptaddr
+ 0x000001e0)) & 0xff00) << 8 | ((__uint32_t)((sc->
sc_c.sc_scriptaddr + 0x000001e0)) & 0xff0000) >> 8 |
((__uint32_t)((sc->sc_c.sc_scriptaddr + 0x000001e0)) &
0xff000000) >> 24) : __swap32md((sc->sc_c.sc_scriptaddr
+ 0x000001e0))) : ((__uint32_t)((sc->sc_c.sc_scriptaddr +
0x000001e0))))
;
1899 scr[E_ldsa_abs_selected_Used[0]] = siop_htoc32(&sc->sc_c,(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((sc->sc_c.sc_scriptaddr + 0x00000388
)) ? (__uint32_t)(((__uint32_t)((sc->sc_c.sc_scriptaddr + 0x00000388
)) & 0xff) << 24 | ((__uint32_t)((sc->sc_c.sc_scriptaddr
+ 0x00000388)) & 0xff00) << 8 | ((__uint32_t)((sc->
sc_c.sc_scriptaddr + 0x00000388)) & 0xff0000) >> 8 |
((__uint32_t)((sc->sc_c.sc_scriptaddr + 0x00000388)) &
0xff000000) >> 24) : __swap32md((sc->sc_c.sc_scriptaddr
+ 0x00000388))) : ((__uint32_t)((sc->sc_c.sc_scriptaddr +
0x00000388))))
1900 sc->sc_c.sc_scriptaddr + Ent_selected)(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((sc->sc_c.sc_scriptaddr + 0x00000388
)) ? (__uint32_t)(((__uint32_t)((sc->sc_c.sc_scriptaddr + 0x00000388
)) & 0xff) << 24 | ((__uint32_t)((sc->sc_c.sc_scriptaddr
+ 0x00000388)) & 0xff00) << 8 | ((__uint32_t)((sc->
sc_c.sc_scriptaddr + 0x00000388)) & 0xff0000) >> 8 |
((__uint32_t)((sc->sc_c.sc_scriptaddr + 0x00000388)) &
0xff000000) >> 24) : __swap32md((sc->sc_c.sc_scriptaddr
+ 0x00000388))) : ((__uint32_t)((sc->sc_c.sc_scriptaddr +
0x00000388))))
;
1901 scr[E_ldsa_abs_data_Used[0]] = siop_htoc32(&sc->sc_c,(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((dsa + sizeof(struct siop_common_xfer)
+ 0x0000005c)) ? (__uint32_t)(((__uint32_t)((dsa + sizeof(struct
siop_common_xfer) + 0x0000005c)) & 0xff) << 24 | (
(__uint32_t)((dsa + sizeof(struct siop_common_xfer) + 0x0000005c
)) & 0xff00) << 8 | ((__uint32_t)((dsa + sizeof(struct
siop_common_xfer) + 0x0000005c)) & 0xff0000) >> 8 |
((__uint32_t)((dsa + sizeof(struct siop_common_xfer) + 0x0000005c
)) & 0xff000000) >> 24) : __swap32md((dsa + sizeof(
struct siop_common_xfer) + 0x0000005c))) : ((__uint32_t)((dsa
+ sizeof(struct siop_common_xfer) + 0x0000005c))))
1902 dsa + sizeof(struct siop_common_xfer) + Ent_ldsa_data)(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((dsa + sizeof(struct siop_common_xfer)
+ 0x0000005c)) ? (__uint32_t)(((__uint32_t)((dsa + sizeof(struct
siop_common_xfer) + 0x0000005c)) & 0xff) << 24 | (
(__uint32_t)((dsa + sizeof(struct siop_common_xfer) + 0x0000005c
)) & 0xff00) << 8 | ((__uint32_t)((dsa + sizeof(struct
siop_common_xfer) + 0x0000005c)) & 0xff0000) >> 8 |
((__uint32_t)((dsa + sizeof(struct siop_common_xfer) + 0x0000005c
)) & 0xff000000) >> 24) : __swap32md((dsa + sizeof(
struct siop_common_xfer) + 0x0000005c))) : ((__uint32_t)((dsa
+ sizeof(struct siop_common_xfer) + 0x0000005c))))
;
1903 /* JUMP foo, IF FALSE - used by MOVE MEMORY to clear the slot */
1904 scr[Ent_ldsa_data0x0000005c / 4] = siop_htoc32(&sc->sc_c, 0x80000000)(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((0x80000000)) ? (__uint32_t)(((__uint32_t
)((0x80000000)) & 0xff) << 24 | ((__uint32_t)((0x80000000
)) & 0xff00) << 8 | ((__uint32_t)((0x80000000)) &
0xff0000) >> 8 | ((__uint32_t)((0x80000000)) & 0xff000000
) >> 24) : __swap32md((0x80000000))) : ((__uint32_t)((0x80000000
))))
;
1905 s = splbio()splraise(0x6);
1906 TAILQ_INSERT_TAIL(&sc->free_list, &newcbd->cmds[i], next)do { (&newcbd->cmds[i])->next.tqe_next = ((void *)0
); (&newcbd->cmds[i])->next.tqe_prev = (&sc->
free_list)->tqh_last; *(&sc->free_list)->tqh_last
= (&newcbd->cmds[i]); (&sc->free_list)->tqh_last
= &(&newcbd->cmds[i])->next.tqe_next; } while (
0)
;
1907 splx(s)spllower(s);
1908#ifdef SIOP_DEBUG
1909 printf("tables[%d]: in=0x%x out=0x%x status=0x%x\n",
1910 i,
1911 siop_ctoh32(&sc->sc_c,(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((newcbd->cmds[i].cmd_c.siop_tables->
t_msgin.addr)) ? (__uint32_t)(((__uint32_t)((newcbd->cmds[
i].cmd_c.siop_tables->t_msgin.addr)) & 0xff) << 24
| ((__uint32_t)((newcbd->cmds[i].cmd_c.siop_tables->t_msgin
.addr)) & 0xff00) << 8 | ((__uint32_t)((newcbd->
cmds[i].cmd_c.siop_tables->t_msgin.addr)) & 0xff0000) >>
8 | ((__uint32_t)((newcbd->cmds[i].cmd_c.siop_tables->
t_msgin.addr)) & 0xff000000) >> 24) : __swap32md((newcbd
->cmds[i].cmd_c.siop_tables->t_msgin.addr))) : ((__uint32_t
)((newcbd->cmds[i].cmd_c.siop_tables->t_msgin.addr))))
1912 newcbd->cmds[i].cmd_tables->t_msgin.addr)(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((newcbd->cmds[i].cmd_c.siop_tables->
t_msgin.addr)) ? (__uint32_t)(((__uint32_t)((newcbd->cmds[
i].cmd_c.siop_tables->t_msgin.addr)) & 0xff) << 24
| ((__uint32_t)((newcbd->cmds[i].cmd_c.siop_tables->t_msgin
.addr)) & 0xff00) << 8 | ((__uint32_t)((newcbd->
cmds[i].cmd_c.siop_tables->t_msgin.addr)) & 0xff0000) >>
8 | ((__uint32_t)((newcbd->cmds[i].cmd_c.siop_tables->
t_msgin.addr)) & 0xff000000) >> 24) : __swap32md((newcbd
->cmds[i].cmd_c.siop_tables->t_msgin.addr))) : ((__uint32_t
)((newcbd->cmds[i].cmd_c.siop_tables->t_msgin.addr))))
,
1913 siop_ctoh32(&sc->sc_c,(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((newcbd->cmds[i].cmd_c.siop_tables->
t_msgout.addr)) ? (__uint32_t)(((__uint32_t)((newcbd->cmds
[i].cmd_c.siop_tables->t_msgout.addr)) & 0xff) <<
24 | ((__uint32_t)((newcbd->cmds[i].cmd_c.siop_tables->
t_msgout.addr)) & 0xff00) << 8 | ((__uint32_t)((newcbd
->cmds[i].cmd_c.siop_tables->t_msgout.addr)) & 0xff0000
) >> 8 | ((__uint32_t)((newcbd->cmds[i].cmd_c.siop_tables
->t_msgout.addr)) & 0xff000000) >> 24) : __swap32md
((newcbd->cmds[i].cmd_c.siop_tables->t_msgout.addr))) :
((__uint32_t)((newcbd->cmds[i].cmd_c.siop_tables->t_msgout
.addr))))
1914 newcbd->cmds[i].cmd_tables->t_msgout.addr)(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((newcbd->cmds[i].cmd_c.siop_tables->
t_msgout.addr)) ? (__uint32_t)(((__uint32_t)((newcbd->cmds
[i].cmd_c.siop_tables->t_msgout.addr)) & 0xff) <<
24 | ((__uint32_t)((newcbd->cmds[i].cmd_c.siop_tables->
t_msgout.addr)) & 0xff00) << 8 | ((__uint32_t)((newcbd
->cmds[i].cmd_c.siop_tables->t_msgout.addr)) & 0xff0000
) >> 8 | ((__uint32_t)((newcbd->cmds[i].cmd_c.siop_tables
->t_msgout.addr)) & 0xff000000) >> 24) : __swap32md
((newcbd->cmds[i].cmd_c.siop_tables->t_msgout.addr))) :
((__uint32_t)((newcbd->cmds[i].cmd_c.siop_tables->t_msgout
.addr))))
,
1915 siop_ctoh32(&sc->sc_c,(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((newcbd->cmds[i].cmd_c.siop_tables->
t_status.addr)) ? (__uint32_t)(((__uint32_t)((newcbd->cmds
[i].cmd_c.siop_tables->t_status.addr)) & 0xff) <<
24 | ((__uint32_t)((newcbd->cmds[i].cmd_c.siop_tables->
t_status.addr)) & 0xff00) << 8 | ((__uint32_t)((newcbd
->cmds[i].cmd_c.siop_tables->t_status.addr)) & 0xff0000
) >> 8 | ((__uint32_t)((newcbd->cmds[i].cmd_c.siop_tables
->t_status.addr)) & 0xff000000) >> 24) : __swap32md
((newcbd->cmds[i].cmd_c.siop_tables->t_status.addr))) :
((__uint32_t)((newcbd->cmds[i].cmd_c.siop_tables->t_status
.addr))))
1916 newcbd->cmds[i].cmd_tables->t_status.addr)(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((newcbd->cmds[i].cmd_c.siop_tables->
t_status.addr)) ? (__uint32_t)(((__uint32_t)((newcbd->cmds
[i].cmd_c.siop_tables->t_status.addr)) & 0xff) <<
24 | ((__uint32_t)((newcbd->cmds[i].cmd_c.siop_tables->
t_status.addr)) & 0xff00) << 8 | ((__uint32_t)((newcbd
->cmds[i].cmd_c.siop_tables->t_status.addr)) & 0xff0000
) >> 8 | ((__uint32_t)((newcbd->cmds[i].cmd_c.siop_tables
->t_status.addr)) & 0xff000000) >> 24) : __swap32md
((newcbd->cmds[i].cmd_c.siop_tables->t_status.addr))) :
((__uint32_t)((newcbd->cmds[i].cmd_c.siop_tables->t_status
.addr))))
);
1917#endif
1918 }
1919 s = splbio()splraise(0x6);
1920 TAILQ_INSERT_TAIL(&sc->cmds, newcbd, next)do { (newcbd)->next.tqe_next = ((void *)0); (newcbd)->next
.tqe_prev = (&sc->cmds)->tqh_last; *(&sc->cmds
)->tqh_last = (newcbd); (&sc->cmds)->tqh_last = &
(newcbd)->next.tqe_next; } while (0)
;
1921 splx(s)spllower(s);
1922 return;
1923bad0:
1924 while (--i >= 0) {
1925 bus_dmamap_destroy(sc->sc_c.sc_dmat,(*(sc->sc_c.sc_dmat)->_dmamap_destroy)((sc->sc_c.sc_dmat
), (newcbd->cmds[i].cmd_c.dmamap_data))
1926 newcbd->cmds[i].cmd_c.dmamap_data)(*(sc->sc_c.sc_dmat)->_dmamap_destroy)((sc->sc_c.sc_dmat
), (newcbd->cmds[i].cmd_c.dmamap_data))
;
1927 }
1928 siop_dmamem_free(sc, newcbd->sense);
1929bad1:
1930 siop_dmamem_free(sc, newcbd->xfers);
1931bad2:
1932 free(newcbd->cmds, M_DEVBUF2, SIOP_NCMDPB((1 << 12) / sizeof(struct siop_xfer)) * sizeof(struct siop_cmd));
1933bad3:
1934 free(newcbd, M_DEVBUF2, sizeof *newcbd);
1935}
1936
1937struct siop_lunsw *
1938siop_get_lunsw(struct siop_softc *sc)
1939{
1940 struct siop_lunsw *lunsw;
1941 int i;
1942
1943 if (sc->script_free_lo + (sizeof(lun_switch) / sizeof(lun_switch[0])) >=
1944 sc->script_free_hi)
1945 return NULL((void *)0);
1946 lunsw = TAILQ_FIRST(&sc->lunsw_list)((&sc->lunsw_list)->tqh_first);
1947 if (lunsw != NULL((void *)0)) {
1948#ifdef SIOP_DEBUG
1949 printf("siop_get_lunsw got lunsw at offset %d\n",
1950 lunsw->lunsw_off);
1951#endif
1952 TAILQ_REMOVE(&sc->lunsw_list, lunsw, next)do { if (((lunsw)->next.tqe_next) != ((void *)0)) (lunsw)->
next.tqe_next->next.tqe_prev = (lunsw)->next.tqe_prev; else
(&sc->lunsw_list)->tqh_last = (lunsw)->next.tqe_prev
; *(lunsw)->next.tqe_prev = (lunsw)->next.tqe_next; ((lunsw
)->next.tqe_prev) = ((void *)-1); ((lunsw)->next.tqe_next
) = ((void *)-1); } while (0)
;
1953 return lunsw;
1954 }
1955 lunsw = malloc(sizeof(struct siop_lunsw), M_DEVBUF2, M_NOWAIT0x0002 | M_ZERO0x0008);
1956 if (lunsw == NULL((void *)0))
1957 return NULL((void *)0);
1958#ifdef SIOP_DEBUG
1959 printf("allocating lunsw at offset %d\n", sc->script_free_lo);
1960#endif
1961 if (sc->sc_c.features & SF_CHIP_RAM0x00004000) {
1962 bus_space_write_region_4(sc->sc_c.sc_ramt, sc->sc_c.sc_ramh,((sc->sc_c.sc_ramt)->write_region_4((sc->sc_c.sc_ramh
), (sc->script_free_lo * 4), (lun_switch), (sizeof(lun_switch
) / sizeof(lun_switch[0]))))
1963 sc->script_free_lo * 4, lun_switch,((sc->sc_c.sc_ramt)->write_region_4((sc->sc_c.sc_ramh
), (sc->script_free_lo * 4), (lun_switch), (sizeof(lun_switch
) / sizeof(lun_switch[0]))))
1964 sizeof(lun_switch) / sizeof(lun_switch[0]))((sc->sc_c.sc_ramt)->write_region_4((sc->sc_c.sc_ramh
), (sc->script_free_lo * 4), (lun_switch), (sizeof(lun_switch
) / sizeof(lun_switch[0]))))
;
1965 bus_space_write_4(sc->sc_c.sc_ramt, sc->sc_c.sc_ramh,((sc->sc_c.sc_ramt)->write_4((sc->sc_c.sc_ramh), ((sc
->script_free_lo + E_abs_lunsw_return_Used[0]) * 4), (sc->
sc_c.sc_scriptaddr + 0x000002b8)))
1966 (sc->script_free_lo + E_abs_lunsw_return_Used[0]) * 4,((sc->sc_c.sc_ramt)->write_4((sc->sc_c.sc_ramh), ((sc
->script_free_lo + E_abs_lunsw_return_Used[0]) * 4), (sc->
sc_c.sc_scriptaddr + 0x000002b8)))
1967 sc->sc_c.sc_scriptaddr + Ent_lunsw_return)((sc->sc_c.sc_ramt)->write_4((sc->sc_c.sc_ramh), ((sc
->script_free_lo + E_abs_lunsw_return_Used[0]) * 4), (sc->
sc_c.sc_scriptaddr + 0x000002b8)))
;
1968 } else {
1969 for (i = 0; i < sizeof(lun_switch) / sizeof(lun_switch[0]);
1970 i++)
1971 sc->sc_c.sc_script[sc->script_free_lo + i] =
1972 siop_htoc32(&sc->sc_c, lun_switch[i])(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((lun_switch[i])) ? (__uint32_t)(((__uint32_t
)((lun_switch[i])) & 0xff) << 24 | ((__uint32_t)((lun_switch
[i])) & 0xff00) << 8 | ((__uint32_t)((lun_switch[i]
)) & 0xff0000) >> 8 | ((__uint32_t)((lun_switch[i])
) & 0xff000000) >> 24) : __swap32md((lun_switch[i])
)) : ((__uint32_t)((lun_switch[i]))))
;
1973 sc->sc_c.sc_script[
1974 sc->script_free_lo + E_abs_lunsw_return_Used[0]] =
1975 siop_htoc32(&sc->sc_c,(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((sc->sc_c.sc_scriptaddr + 0x000002b8
)) ? (__uint32_t)(((__uint32_t)((sc->sc_c.sc_scriptaddr + 0x000002b8
)) & 0xff) << 24 | ((__uint32_t)((sc->sc_c.sc_scriptaddr
+ 0x000002b8)) & 0xff00) << 8 | ((__uint32_t)((sc->
sc_c.sc_scriptaddr + 0x000002b8)) & 0xff0000) >> 8 |
((__uint32_t)((sc->sc_c.sc_scriptaddr + 0x000002b8)) &
0xff000000) >> 24) : __swap32md((sc->sc_c.sc_scriptaddr
+ 0x000002b8))) : ((__uint32_t)((sc->sc_c.sc_scriptaddr +
0x000002b8))))
1976 sc->sc_c.sc_scriptaddr + Ent_lunsw_return)(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((sc->sc_c.sc_scriptaddr + 0x000002b8
)) ? (__uint32_t)(((__uint32_t)((sc->sc_c.sc_scriptaddr + 0x000002b8
)) & 0xff) << 24 | ((__uint32_t)((sc->sc_c.sc_scriptaddr
+ 0x000002b8)) & 0xff00) << 8 | ((__uint32_t)((sc->
sc_c.sc_scriptaddr + 0x000002b8)) & 0xff0000) >> 8 |
((__uint32_t)((sc->sc_c.sc_scriptaddr + 0x000002b8)) &
0xff000000) >> 24) : __swap32md((sc->sc_c.sc_scriptaddr
+ 0x000002b8))) : ((__uint32_t)((sc->sc_c.sc_scriptaddr +
0x000002b8))))
;
1977 }
1978 lunsw->lunsw_off = sc->script_free_lo;
1979 lunsw->lunsw_size = sizeof(lun_switch) / sizeof(lun_switch[0]);
1980 sc->script_free_lo += lunsw->lunsw_size;
1981 siop_script_sync(sc, BUS_DMASYNC_PREREAD0x01 | BUS_DMASYNC_PREWRITE0x04);
1982 return lunsw;
1983}
1984
1985void
1986siop_add_reselsw(struct siop_softc *sc, int target)
1987{
1988 int i,j;
1989 struct siop_target *siop_target;
1990 struct siop_lun *siop_lun;
1991
1992 siop_target = (struct siop_target *)sc->sc_c.targets[target];
1993 /*
1994 * add an entry to resel switch
1995 */
1996 siop_script_sync(sc, BUS_DMASYNC_POSTWRITE0x08);
1997 for (i = 0; i < 15; i++) {
1998 siop_target->reseloff = Ent_resel_targ00x00000238 / 4 + i * 2;
1999 if ((siop_script_read(sc, siop_target->reseloff) & 0xff)
2000 == 0xff) { /* it's free */
2001#ifdef SIOP_DEBUG
2002 printf("siop: target %d slot %d offset %d\n",
2003 target, i, siop_target->reseloff);
2004#endif
2005 /* JUMP abs_foo, IF target | 0x80; */
2006 siop_script_write(sc, siop_target->reseloff,
2007 0x800c0080 | target);
2008 siop_script_write(sc, siop_target->reseloff + 1,
2009 sc->sc_c.sc_scriptaddr +
2010 siop_target->lunsw->lunsw_off * 4 +
2011 Ent_lun_switch_entry0x00000018);
2012 break;
2013 }
2014 }
2015 if (i == 15) /* no free slot, shouldn't happen */
2016 panic("siop: resel switch full");
2017
2018 sc->sc_ntargets++;
2019 for (i = 0; i < 8; i++) {
2020 siop_lun = siop_target->siop_lun[i];
2021 if (siop_lun == NULL((void *)0))
2022 continue;
2023 if (siop_lun->reseloff > 0) {
2024 siop_lun->reseloff = 0;
2025 for (j = 0; j < SIOP_NTAG16; j++)
2026 siop_lun->siop_tag[j].reseloff = 0;
2027 siop_add_dev(sc, target, i);
2028 }
2029 }
2030 siop_update_scntl3(sc, sc->sc_c.targets[target]);
2031 siop_script_sync(sc, BUS_DMASYNC_PREWRITE0x04);
2032}
2033
2034void
2035siop_update_scntl3(struct siop_softc *sc,
2036 struct siop_common_target *_siop_target)
2037{
2038 struct siop_target *siop_target = (struct siop_target *)_siop_target;
2039 /* MOVE target->id >> 24 TO SCNTL3 */
2040 siop_script_write(sc,
2041 siop_target->lunsw->lunsw_off + (Ent_restore_scntl30x00000000 / 4),
2042 0x78030000 | ((siop_target->target_c.id >> 16) & 0x0000ff00));
2043 /* MOVE target->id >> 8 TO SXFER */
2044 siop_script_write(sc,
2045 siop_target->lunsw->lunsw_off + (Ent_restore_scntl30x00000000 / 4) + 2,
2046 0x78050000 | (siop_target->target_c.id & 0x0000ff00));
2047 siop_script_sync(sc, BUS_DMASYNC_PREWRITE0x04);
2048}
2049
2050void
2051siop_add_dev(struct siop_softc *sc, int target, int lun)
2052{
2053 struct siop_lunsw *lunsw;
2054 struct siop_target *siop_target =
2055 (struct siop_target *)sc->sc_c.targets[target];
2056 struct siop_lun *siop_lun = siop_target->siop_lun[lun];
2057 int i, ntargets, buswidth;
2058
2059 if (siop_lun->reseloff > 0)
2060 return;
2061 lunsw = siop_target->lunsw;
2062 if ((lunsw->lunsw_off + lunsw->lunsw_size) < sc->script_free_lo) {
2063 /*
2064 * can't extend this slot. Probably not worth trying to deal
2065 * with this case
2066 */
2067#ifdef SIOP_DEBUG
2068 printf("%s:%d:%d: can't allocate a lun sw slot\n",
2069 sc->sc_c.sc_dev.dv_xname, target, lun);
2070#endif
2071 return;
2072 }
2073 /* count how many free targets we still have to probe */
2074 buswidth = (sc->sc_c.features & SF_BUS_WIDE0x00000001) ? 16 : 8;
2075 ntargets = (buswidth - 1) - 1 - sc->sc_ntargets;
2076
2077 /*
2078 * we need 8 bytes for the lun sw additional entry, and
2079 * eventually sizeof(tag_switch) for the tag switch entry.
2080 * Keep enough free space for the free targets that could be
2081 * probed later.
2082 */
2083 if (sc->script_free_lo + 2 +
2084 (ntargets * sizeof(lun_switch) / sizeof(lun_switch[0])) >=
2085 ((siop_target->target_c.flags & TARF_TAG0x04) ?
2086 sc->script_free_hi - (sizeof(tag_switch) / sizeof(tag_switch[0])) :
2087 sc->script_free_hi)) {
2088 /*
2089 * not enough space, probably not worth dealing with it.
2090 * We can hold 13 tagged-queuing capable devices in the 4k RAM.
2091 */
2092#ifdef SIOP_DEBUG
2093 printf("%s:%d:%d: not enough memory for a lun sw slot\n",
2094 sc->sc_c.sc_dev.dv_xname, target, lun);
2095#endif
2096 return;
2097 }
2098#ifdef SIOP_DEBUG
2099 printf("%s:%d:%d: allocate lun sw entry\n",
2100 sc->sc_c.sc_dev.dv_xname, target, lun);
2101#endif
2102 /* INT int_resellun */
2103 siop_script_write(sc, sc->script_free_lo, 0x98080000);
2104 siop_script_write(sc, sc->script_free_lo + 1, A_int_resellun0x0000ff81);
2105 /* Now the slot entry: JUMP abs_foo, IF lun */
2106 siop_script_write(sc, sc->script_free_lo - 2,
2107 0x800c0000 | lun);
2108 siop_script_write(sc, sc->script_free_lo - 1, 0);
2109 siop_lun->reseloff = sc->script_free_lo - 2;
2110 lunsw->lunsw_size += 2;
2111 sc->script_free_lo += 2;
2112 if (siop_target->target_c.flags & TARF_TAG0x04) {
2113 /* we need a tag switch */
2114 sc->script_free_hi -=
2115 sizeof(tag_switch) / sizeof(tag_switch[0]);
2116 if (sc->sc_c.features & SF_CHIP_RAM0x00004000) {
2117 bus_space_write_region_4(sc->sc_c.sc_ramt,((sc->sc_c.sc_ramt)->write_region_4((sc->sc_c.sc_ramh
), (sc->script_free_hi * 4), (tag_switch), (sizeof(tag_switch
) / sizeof(tag_switch[0]))))
2118 sc->sc_c.sc_ramh,((sc->sc_c.sc_ramt)->write_region_4((sc->sc_c.sc_ramh
), (sc->script_free_hi * 4), (tag_switch), (sizeof(tag_switch
) / sizeof(tag_switch[0]))))
2119 sc->script_free_hi * 4, tag_switch,((sc->sc_c.sc_ramt)->write_region_4((sc->sc_c.sc_ramh
), (sc->script_free_hi * 4), (tag_switch), (sizeof(tag_switch
) / sizeof(tag_switch[0]))))
2120 sizeof(tag_switch) / sizeof(tag_switch[0]))((sc->sc_c.sc_ramt)->write_region_4((sc->sc_c.sc_ramh
), (sc->script_free_hi * 4), (tag_switch), (sizeof(tag_switch
) / sizeof(tag_switch[0]))))
;
2121 } else {
2122 for(i = 0;
2123 i < sizeof(tag_switch) / sizeof(tag_switch[0]);
2124 i++) {
2125 sc->sc_c.sc_script[sc->script_free_hi + i] =
2126 siop_htoc32(&sc->sc_c, tag_switch[i])(((&sc->sc_c)->features & 0x00200000) ? (__uint32_t
)(__builtin_constant_p((tag_switch[i])) ? (__uint32_t)(((__uint32_t
)((tag_switch[i])) & 0xff) << 24 | ((__uint32_t)((tag_switch
[i])) & 0xff00) << 8 | ((__uint32_t)((tag_switch[i]
)) & 0xff0000) >> 8 | ((__uint32_t)((tag_switch[i])
) & 0xff000000) >> 24) : __swap32md((tag_switch[i])
)) : ((__uint32_t)((tag_switch[i]))))
;
2127 }
2128 }
2129 siop_script_write(sc,
2130 siop_lun->reseloff + 1,
2131 sc->sc_c.sc_scriptaddr + sc->script_free_hi * 4 +
2132 Ent_tag_switch_entry0x00000000);
2133
2134 for (i = 0; i < SIOP_NTAG16; i++) {
2135 siop_lun->siop_tag[i].reseloff =
2136 sc->script_free_hi + (Ent_resel_tag00x00000008 / 4) + i * 2;
2137 }
2138 } else {
2139 /* non-tag case; just work with the lun switch */
2140 siop_lun->siop_tag[0].reseloff =
2141 siop_target->siop_lun[lun]->reseloff;
2142 }
2143 siop_script_sync(sc, BUS_DMASYNC_PREWRITE0x04);
2144}
2145
2146void
2147siop_scsifree(struct scsi_link *link)
2148{
2149 struct siop_softc *sc = link->bus->sb_adapter_softc;
2150 int target = link->target;
2151 int lun = link->lun;
2152 int i;
2153 struct siop_target *siop_target;
2154
2155#ifdef SIOP_DEBUG
2156 printf("%s:%d:%d: free lun sw entry\n",
2157 sc->sc_c.sc_dev.dv_xname, target, lun);
2158#endif
2159
2160 siop_target = (struct siop_target *)sc->sc_c.targets[target];
2161 free(siop_target->siop_lun[lun], M_DEVBUF2, 0);
2162 siop_target->siop_lun[lun] = NULL((void *)0);
2163 /* XXX compact sw entry too ? */
2164 /* check if we can free the whole target */
2165 for (i = 0; i < 8; i++) {
2166 if (siop_target->siop_lun[i] != NULL((void *)0))
2167 return;
2168 }
2169#ifdef SIOP_DEBUG
2170 printf("%s: free siop_target for target %d lun %d lunsw offset %d\n",
2171 sc->sc_c.sc_dev.dv_xname, target, lun,
2172 siop_target->lunsw->lunsw_off);
2173#endif
2174 /*
2175 * nothing here, free the target struct and resel
2176 * switch entry
2177 */
2178 siop_script_write(sc, siop_target->reseloff, 0x800c00ff);
2179 siop_script_sync(sc, BUS_DMASYNC_PREWRITE0x04);
2180 TAILQ_INSERT_TAIL(&sc->lunsw_list, siop_target->lunsw, next)do { (siop_target->lunsw)->next.tqe_next = ((void *)0);
(siop_target->lunsw)->next.tqe_prev = (&sc->lunsw_list
)->tqh_last; *(&sc->lunsw_list)->tqh_last = (siop_target
->lunsw); (&sc->lunsw_list)->tqh_last = &(siop_target
->lunsw)->next.tqe_next; } while (0)
;
2181 free(sc->sc_c.targets[target], M_DEVBUF2, 0);
2182 sc->sc_c.targets[target] = NULL((void *)0);
2183 sc->sc_ntargets--;
2184}
2185
2186#ifdef SIOP_STATS
2187void
2188siop_printstats(void)
2189{
2190 printf("siop_stat_intr %d\n", siop_stat_intr);
2191 printf("siop_stat_intr_shortxfer %d\n", siop_stat_intr_shortxfer);
2192 printf("siop_stat_intr_xferdisc %d\n", siop_stat_intr_xferdisc);
2193 printf("siop_stat_intr_sdp %d\n", siop_stat_intr_sdp);
2194 printf("siop_stat_intr_saveoffset %d\n", siop_stat_intr_saveoffset);
2195 printf("siop_stat_intr_done %d\n", siop_stat_intr_done);
2196 printf("siop_stat_intr_lunresel %d\n", siop_stat_intr_lunresel);
2197 printf("siop_stat_intr_qfull %d\n", siop_stat_intr_qfull);
2198}
2199#endif
2200
2201struct siop_dmamem *
2202siop_dmamem_alloc(struct siop_softc *sc, size_t size)
2203{
2204 struct siop_dmamem *sdm;
2205 int nsegs;
2206
2207 sdm = malloc(sizeof(*sdm), M_DEVBUF2, M_NOWAIT0x0002 | M_ZERO0x0008);
2208 if (sdm == NULL((void *)0))
2209 return (NULL((void *)0));
2210
2211 sdm->sdm_size = size;
2212
2213 if (bus_dmamap_create(sc->sc_c.sc_dmat, size, 1, size, 0,(*(sc->sc_c.sc_dmat)->_dmamap_create)((sc->sc_c.sc_dmat
), (size), (1), (size), (0), (0x0001 | 0x0002), (&sdm->
sdm_map))
2214 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &sdm->sdm_map)(*(sc->sc_c.sc_dmat)->_dmamap_create)((sc->sc_c.sc_dmat
), (size), (1), (size), (0), (0x0001 | 0x0002), (&sdm->
sdm_map))
!= 0)
2215 goto sdmfree;
2216
2217 if (bus_dmamem_alloc(sc->sc_c.sc_dmat, size, PAGE_SIZE, 0,(*(sc->sc_c.sc_dmat)->_dmamem_alloc)((sc->sc_c.sc_dmat
), (size), ((1 << 12)), (0), (&sdm->sdm_seg), (1
), (&nsegs), (0x0001 | 0x1000))
2218 &sdm->sdm_seg, 1, &nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO)(*(sc->sc_c.sc_dmat)->_dmamem_alloc)((sc->sc_c.sc_dmat
), (size), ((1 << 12)), (0), (&sdm->sdm_seg), (1
), (&nsegs), (0x0001 | 0x1000))
!= 0)
2219 goto destroy;
2220
2221 if (bus_dmamem_map(sc->sc_c.sc_dmat, &sdm->sdm_seg, nsegs, size,(*(sc->sc_c.sc_dmat)->_dmamem_map)((sc->sc_c.sc_dmat
), (&sdm->sdm_seg), (nsegs), (size), (&sdm->sdm_kva
), (0x0001 | 0x0004))
2222 &sdm->sdm_kva, BUS_DMA_NOWAIT | BUS_DMA_COHERENT)(*(sc->sc_c.sc_dmat)->_dmamem_map)((sc->sc_c.sc_dmat
), (&sdm->sdm_seg), (nsegs), (size), (&sdm->sdm_kva
), (0x0001 | 0x0004))
!= 0)
2223 goto free;
2224
2225 if (bus_dmamap_load(sc->sc_c.sc_dmat, sdm->sdm_map, sdm->sdm_kva,(*(sc->sc_c.sc_dmat)->_dmamap_load)((sc->sc_c.sc_dmat
), (sdm->sdm_map), (sdm->sdm_kva), (size), (((void *)0)
), (0x0001))
2226 size, NULL, BUS_DMA_NOWAIT)(*(sc->sc_c.sc_dmat)->_dmamap_load)((sc->sc_c.sc_dmat
), (sdm->sdm_map), (sdm->sdm_kva), (size), (((void *)0)
), (0x0001))
!= 0)
2227 goto unmap;
2228
2229 return (sdm);
2230
2231unmap:
2232 bus_dmamem_unmap(sc->sc_c.sc_dmat, sdm->sdm_kva, size)(*(sc->sc_c.sc_dmat)->_dmamem_unmap)((sc->sc_c.sc_dmat
), (sdm->sdm_kva), (size))
;
2233free:
2234 bus_dmamem_free(sc->sc_c.sc_dmat, &sdm->sdm_seg, 1)(*(sc->sc_c.sc_dmat)->_dmamem_free)((sc->sc_c.sc_dmat
), (&sdm->sdm_seg), (1))
;
2235destroy:
2236 bus_dmamap_destroy(sc->sc_c.sc_dmat, sdm->sdm_map)(*(sc->sc_c.sc_dmat)->_dmamap_destroy)((sc->sc_c.sc_dmat
), (sdm->sdm_map))
;
2237sdmfree:
2238 free(sdm, M_DEVBUF2, sizeof *sdm);
2239
2240 return (NULL((void *)0));
2241}
2242
2243void
2244siop_dmamem_free(struct siop_softc *sc, struct siop_dmamem *sdm)
2245{
2246 bus_dmamap_unload(sc->sc_c.sc_dmat, sdm->sdm_map)(*(sc->sc_c.sc_dmat)->_dmamap_unload)((sc->sc_c.sc_dmat
), (sdm->sdm_map))
;
2247 bus_dmamem_unmap(sc->sc_c.sc_dmat, sdm->sdm_kva, sdm->sdm_size)(*(sc->sc_c.sc_dmat)->_dmamem_unmap)((sc->sc_c.sc_dmat
), (sdm->sdm_kva), (sdm->sdm_size))
;
2248 bus_dmamem_free(sc->sc_c.sc_dmat, &sdm->sdm_seg, 1)(*(sc->sc_c.sc_dmat)->_dmamem_free)((sc->sc_c.sc_dmat
), (&sdm->sdm_seg), (1))
;
2249 bus_dmamap_destroy(sc->sc_c.sc_dmat, sdm->sdm_map)(*(sc->sc_c.sc_dmat)->_dmamap_destroy)((sc->sc_c.sc_dmat
), (sdm->sdm_map))
;
2250 free(sdm, M_DEVBUF2, sizeof *sdm);
2251}