Bug Summary

File:dev/ic/aic7xxx_openbsd.c
Warning:line 581, column 3
Value stored to 'found' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name aic7xxx_openbsd.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/aic7xxx_openbsd.c
1/* $OpenBSD: aic7xxx_openbsd.c,v 1.71 2020/09/22 19:32:52 krw Exp $ */
2/* $NetBSD: aic7xxx_osm.c,v 1.14 2003/11/02 11:07:44 wiz Exp $ */
3
4/*
5 * Bus independent OpenBSD shim for the aic7xxx based adaptec SCSI controllers
6 *
7 * Copyright (c) 1994-2001 Justin T. Gibbs.
8 * Copyright (c) 2001-2002 Steve Murphree, Jr.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
19 *
20 * Alternatively, this software may be distributed under the terms of the
21 * GNU Public License ("GPL").
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
27 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
35 * //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.c#12 $
36 *
37 * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx_osm.c,v 1.31 2002/11/30 19:08:58 scottl Exp $
38 */
39/*
40 * Ported from FreeBSD by Pascal Renauld, Network Storage Solutions, Inc. - April 2003
41 */
42
43#include <dev/ic/aic7xxx_openbsd.h>
44#include <dev/ic/aic7xxx_inline.h>
45
46#ifndef AHC_TMODE_ENABLE0
47#define AHC_TMODE_ENABLE0 0
48#endif
49
50
51void ahc_action(struct scsi_xfer *);
52void ahc_execute_scb(void *, bus_dma_segment_t *, int);
53int ahc_poll(struct ahc_softc *, int);
54void ahc_setup_data(struct ahc_softc *, struct scsi_xfer *, struct scb *);
55
56void ahc_adapter_req_set_xfer_mode(struct ahc_softc *, struct scb *);
57
58
59struct cfdriver ahc_cd = {
60 NULL((void *)0), "ahc", DV_DULL
61};
62
63static struct scsi_adapter ahc_switch = {
64 ahc_action, NULL((void *)0), NULL((void *)0), NULL((void *)0), NULL((void *)0)
65};
66
67/*
68 * Attach all the sub-devices we can find
69 */
70int
71ahc_attach(struct ahc_softc *ahc)
72{
73 struct scsibus_attach_args saa;
74 int s;
75
76 s = splbio()splraise(0x6);
77
78#ifndef DEBUG
79 if (bootverbose0) {
80 char ahc_info[256];
81 ahc_controller_info(ahc, ahc_info, sizeof ahc_info);
82 printf("%s: %s\n", ahc->sc_dev.dv_xname, ahc_info);
83 }
84#endif
85
86 ahc_intr_enable(ahc, TRUE1);
87
88 if (ahc->flags & AHC_RESET_BUS_A)
89 ahc_reset_channel(ahc, 'A', TRUE1);
90 if ((ahc->features & AHC_TWIN) && ahc->flags & AHC_RESET_BUS_B)
91 ahc_reset_channel(ahc, 'B', TRUE1);
92
93 saa.saa_adapter_buswidth = (ahc->features & AHC_WIDE) ? 16 :8;
94 saa.saa_adapter_softc = ahc;
95 saa.saa_adapter = &ahc_switch;
96 saa.saa_luns = saa.saa_adapter_buswidth = 8;
97 saa.saa_openings = 16;
98 saa.saa_pool = &ahc->sc_iopool;
99 saa.saa_quirks = saa.saa_flags = 0;
100 saa.saa_wwpn = saa.saa_wwnn = 0;
101 if ((ahc->flags & AHC_PRIMARY_CHANNEL) == 0) {
102 saa.saa_adapter_target = ahc->our_id;
103 ahc->sc_child = (struct scsibus_softc *)config_found(config_found_sm(((void *)&ahc->sc_dev), (&saa), (scsiprint
), ((void *)0))
104 (void *)&ahc->sc_dev, &saa, scsiprint)config_found_sm(((void *)&ahc->sc_dev), (&saa), (scsiprint
), ((void *)0))
;
105 if (ahc->features & AHC_TWIN) {
106 saa.saa_adapter_target = ahc->our_id_b;
107 ahc->sc_child_b = (struct scsibus_softc *)config_found(config_found_sm(((void *)&ahc->sc_dev), (&saa), (scsiprint
), ((void *)0))
108 (void *)&ahc->sc_dev, &saa, scsiprint)config_found_sm(((void *)&ahc->sc_dev), (&saa), (scsiprint
), ((void *)0))
;
109 }
110 } else {
111 if (ahc->features & AHC_TWIN) {
112 saa.saa_adapter_target = ahc->our_id_b;
113 ahc->sc_child = (struct scsibus_softc *)config_found(config_found_sm(((void *)&ahc->sc_dev), (&saa), (scsiprint
), ((void *)0))
114 (void *)&ahc->sc_dev, &saa, scsiprint)config_found_sm(((void *)&ahc->sc_dev), (&saa), (scsiprint
), ((void *)0))
;
115 }
116 saa.saa_adapter_target = ahc->our_id;
117 ahc->sc_child_b = (struct scsibus_softc *)config_found(config_found_sm(((void *)&ahc->sc_dev), (&saa), (scsiprint
), ((void *)0))
118 (void *)&ahc->sc_dev, &saa, scsiprint)config_found_sm(((void *)&ahc->sc_dev), (&saa), (scsiprint
), ((void *)0))
;
119 }
120
121 splx(s)spllower(s);
122 return (1);
123}
124
125/*
126 * Catch an interrupt from the adapter
127 */
128int
129ahc_platform_intr(void *arg)
130{
131 struct ahc_softc *ahc = (struct ahc_softc *)arg;
132
133 bus_dmamap_sync(ahc->parent_dmat, ahc->scb_data->hscb_dmamap,(*(ahc->parent_dmat)->_dmamap_sync)((ahc->parent_dmat
), (ahc->scb_data->hscb_dmamap), (0), (ahc->scb_data
->hscb_dmamap->dm_mapsize), (0x02 | 0x08))
134 0, ahc->scb_data->hscb_dmamap->dm_mapsize,(*(ahc->parent_dmat)->_dmamap_sync)((ahc->parent_dmat
), (ahc->scb_data->hscb_dmamap), (0), (ahc->scb_data
->hscb_dmamap->dm_mapsize), (0x02 | 0x08))
135 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE)(*(ahc->parent_dmat)->_dmamap_sync)((ahc->parent_dmat
), (ahc->scb_data->hscb_dmamap), (0), (ahc->scb_data
->hscb_dmamap->dm_mapsize), (0x02 | 0x08))
;
136
137 return ahc_intr(ahc);
138}
139
140/*
141 * We have an scb which has been processed by the
142 * adaptor, now we look to see how the operation
143 * went.
144 */
145void
146ahc_done(struct ahc_softc *ahc, struct scb *scb)
147{
148 struct scsi_xfer *xs = scb->xs;
149
150 bus_dmamap_sync(ahc->parent_dmat, ahc->scb_data->hscb_dmamap,(*(ahc->parent_dmat)->_dmamap_sync)((ahc->parent_dmat
), (ahc->scb_data->hscb_dmamap), (0), (ahc->scb_data
->hscb_dmamap->dm_mapsize), (0x02 | 0x08))
151 0, ahc->scb_data->hscb_dmamap->dm_mapsize,(*(ahc->parent_dmat)->_dmamap_sync)((ahc->parent_dmat
), (ahc->scb_data->hscb_dmamap), (0), (ahc->scb_data
->hscb_dmamap->dm_mapsize), (0x02 | 0x08))
152 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE)(*(ahc->parent_dmat)->_dmamap_sync)((ahc->parent_dmat
), (ahc->scb_data->hscb_dmamap), (0), (ahc->scb_data
->hscb_dmamap->dm_mapsize), (0x02 | 0x08))
;
153
154 LIST_REMOVE(scb, pending_links)do { if ((scb)->pending_links.le_next != ((void *)0)) (scb
)->pending_links.le_next->pending_links.le_prev = (scb)
->pending_links.le_prev; *(scb)->pending_links.le_prev =
(scb)->pending_links.le_next; ((scb)->pending_links.le_prev
) = ((void *)-1); ((scb)->pending_links.le_next) = ((void *
)-1); } while (0)
;
155 if ((scb->flags & SCB_UNTAGGEDQ) != 0) {
156 struct scb_tailq *untagged_q;
157 int target_offset;
158
159 target_offset = SCB_GET_TARGET_OFFSET(ahc, scb)(((((scb)->hscb->scsiid) & (((((ahc))->features &
AHC_TWIN) != 0) ? 0x70 : 0xf0)) >> 0x04))
;
160 untagged_q = &ahc->untagged_queues[target_offset];
161 TAILQ_REMOVE(untagged_q, scb, links.tqe)do { if (((scb)->links.tqe.tqe_next) != ((void *)0)) (scb)
->links.tqe.tqe_next->links.tqe.tqe_prev = (scb)->links
.tqe.tqe_prev; else (untagged_q)->tqh_last = (scb)->links
.tqe.tqe_prev; *(scb)->links.tqe.tqe_prev = (scb)->links
.tqe.tqe_next; ((scb)->links.tqe.tqe_prev) = ((void *)-1);
((scb)->links.tqe.tqe_next) = ((void *)-1); } while (0)
;
162 scb->flags &= ~SCB_UNTAGGEDQ;
163 ahc_run_untagged_queue(ahc, untagged_q);
164 }
165
166 timeout_del(&xs->stimeout);
167
168 if (xs->datalen) {
169 int op;
170
171 if ((xs->flags & SCSI_DATA_IN0x00800) != 0)
172 op = BUS_DMASYNC_POSTREAD0x02;
173 else
174 op = BUS_DMASYNC_POSTWRITE0x08;
175 bus_dmamap_sync(ahc->parent_dmat, scb->dmamap, 0,(*(ahc->parent_dmat)->_dmamap_sync)((ahc->parent_dmat
), (scb->dmamap), (0), (scb->dmamap->dm_mapsize), (op
))
176 scb->dmamap->dm_mapsize, op)(*(ahc->parent_dmat)->_dmamap_sync)((ahc->parent_dmat
), (scb->dmamap), (0), (scb->dmamap->dm_mapsize), (op
))
;
177 bus_dmamap_unload(ahc->parent_dmat, scb->dmamap)(*(ahc->parent_dmat)->_dmamap_unload)((ahc->parent_dmat
), (scb->dmamap))
;
178 }
179
180 /* Translate the CAM status code to a SCSI error code. */
181 switch (xs->error) {
182 case CAM_SCSI_STATUS_ERROR:
183 case CAM_REQ_INPROG:
184 case CAM_REQ_CMP:
185 switch (xs->status) {
186 case SCSI_TASKSET_FULL0x28:
187 case SCSI_BUSY0x08:
188 xs->error = XS_BUSY5;
189 break;
190 case SCSI_CHECK0x02:
191 case SCSI_TERMINATED0x22:
192 if ((scb->flags & SCB_SENSE) == 0) {
193 /* CHECK on CHECK? */
194 xs->error = XS_DRIVER_STUFFUP2;
195 } else
196 xs->error = XS_NOERROR0;
197 break;
198 default:
199 xs->error = XS_NOERROR0;
200 break;
201 }
202 break;
203 case CAM_REQUEUE_REQ:
204 case CAM_BUSY:
205 xs->error = XS_BUSY5;
206 break;
207 case CAM_CMD_TIMEOUT:
208 xs->error = XS_TIMEOUT4;
209 break;
210 case CAM_BDR_SENT:
211 case CAM_SCSI_BUS_RESET:
212 xs->error = XS_RESET8;
213 break;
214 case CAM_SEL_TIMEOUT:
215 xs->error = XS_SELTIMEOUT3;
216 break;
217 default:
218 xs->error = XS_DRIVER_STUFFUP2;
219 break;
220 }
221
222 /* Don't clobber any existing error state */
223 if (xs->error != XS_NOERROR0) {
224 /* Don't clobber any existing error state */
225 } else if ((scb->flags & SCB_SENSE) != 0) {
226 /*
227 * We performed autosense retrieval.
228 *
229 * Zero any sense not transferred by the
230 * device. The SCSI spec mandates that any
231 * untransferred data should be assumed to be
232 * zero. Complete the 'bounce' of sense information
233 * through buffers accessible via bus-space by
234 * copying it into the clients csio.
235 */
236 memset(&xs->sense, 0, sizeof(struct scsi_sense_data))__builtin_memset((&xs->sense), (0), (sizeof(struct scsi_sense_data
)))
;
237 memcpy(&xs->sense, ahc_get_sense_buf(ahc, scb),__builtin_memcpy((&xs->sense), (ahc_get_sense_buf(ahc,
scb)), (((__uint32_t)(scb->sg_list->len)) & 0x00FFFFFF
))
238 aic_le32toh(scb->sg_list->len) & AHC_SG_LEN_MASK)__builtin_memcpy((&xs->sense), (ahc_get_sense_buf(ahc,
scb)), (((__uint32_t)(scb->sg_list->len)) & 0x00FFFFFF
))
;
239 xs->error = XS_SENSE1;
240 }
241
242 scsi_done(xs);
243}
244
245void
246ahc_action(struct scsi_xfer *xs)
247{
248 struct ahc_softc *ahc;
249 struct scb *scb;
250 struct hardware_scb *hscb;
251 u_int target_id;
252 u_int our_id;
253
254#ifdef AHC_DEBUG
255 printf("%s: ahc_action\n", ahc_name(ahc));
256#endif
257 ahc = xs->sc_link->bus->sb_adapter_softc;
258
259 target_id = xs->sc_link->target;
260 our_id = SCSI_SCSI_ID(ahc, xs->sc_link)((((ahc)->sc_child != ((void *)0)) && ((xs->sc_link
)->bus != (ahc)->sc_child)) ? ahc->our_id_b : ahc->
our_id)
;
261
262 /*
263 * get the scb to use.
264 */
265 scb = xs->io;
266
267 /* Clean up for the next user */
268 scb->flags = SCB_FLAG_NONE;
269
270 hscb = scb->hscb;
271 hscb->control = 0;
272 ahc->scb_data->scbindex[hscb->tag] = NULL((void *)0);
273
274#ifdef AHC_DEBUG
275 printf("%s: start scb(%p)\n", ahc_name(ahc), scb);
276#endif
277 scb->xs = xs;
278 timeout_set(&xs->stimeout, ahc_timeout, scb);
279
280 /*
281 * Put all the arguments for the xfer in the scb
282 */
283 hscb->control = 0;
284 hscb->scsiid = BUILD_SCSIID(ahc, xs->sc_link, target_id, our_id)((((target_id) << 0x04) & 0xf0) | (our_id) | ((((ahc
)->sc_child != ((void *)0)) && ((xs->sc_link)->
bus != (ahc)->sc_child)) ? 0x80 : 0))
;
285 hscb->lun = xs->sc_link->lun;
286 if (xs->xs_controlflags & XS_CTL_RESET0x00200) {
287 hscb->cdb_len = 0;
288 scb->flags |= SCB_DEVICE_RESET;
289 hscb->control |= MK_MESSAGE0x10;
290 ahc_execute_scb(scb, NULL((void *)0), 0);
291 return;
292 }
293
294 ahc_setup_data(ahc, xs, scb);
295}
296
297void
298ahc_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments)
299{
300 struct scb *scb;
301 struct scsi_xfer *xs;
302 struct ahc_softc *ahc;
303 struct ahc_initiator_tinfo *tinfo;
304 struct ahc_tmode_tstate *tstate;
305
306 u_int mask;
307 int s;
308
309 scb = (struct scb *)arg;
310 xs = scb->xs;
311 xs->error = CAM_REQ_INPROG;
312 xs->status = 0;
313 ahc = xs->sc_link->bus->sb_adapter_softc;
314
315 if (nsegments != 0) {
316 struct ahc_dma_seg *sg;
317 bus_dma_segment_t *end_seg;
318 int op;
319
320 end_seg = dm_segs + nsegments;
321
322 /* Copy the segments into our SG list */
323 sg = scb->sg_list;
324 while (dm_segs < end_seg) {
325 uint32_t len;
326
327 sg->addr = aic_htole32(dm_segs->ds_addr)((__uint32_t)(dm_segs->ds_addr));
328 len = dm_segs->ds_len
329 | ((dm_segs->ds_addr >> 8) & 0x7F000000);
330 sg->len = aic_htole32(len)((__uint32_t)(len));
331 sg++;
332 dm_segs++;
333 }
334
335 /*
336 * Note where to find the SG entries in bus space.
337 * We also set the full residual flag which the
338 * sequencer will clear as soon as a data transfer
339 * occurs.
340 */
341 scb->hscb->sgptr = aic_htole32(scb->sg_list_phys|SG_FULL_RESID)((__uint32_t)(scb->sg_list_phys|0x02));
342
343 if ((xs->flags & SCSI_DATA_IN0x00800) != 0)
344 op = BUS_DMASYNC_PREREAD0x01;
345 else
346 op = BUS_DMASYNC_PREWRITE0x04;
347
348 bus_dmamap_sync(ahc->parent_dmat, scb->dmamap, 0,(*(ahc->parent_dmat)->_dmamap_sync)((ahc->parent_dmat
), (scb->dmamap), (0), (scb->dmamap->dm_mapsize), (op
))
349 scb->dmamap->dm_mapsize, op)(*(ahc->parent_dmat)->_dmamap_sync)((ahc->parent_dmat
), (scb->dmamap), (0), (scb->dmamap->dm_mapsize), (op
))
;
350
351 sg--;
352 sg->len |= aic_htole32(AHC_DMA_LAST_SEG)((__uint32_t)(0x80000000));
353
354 bus_dmamap_sync(ahc->parent_dmat, scb->sg_map->sg_dmamap,(*(ahc->parent_dmat)->_dmamap_sync)((ahc->parent_dmat
), (scb->sg_map->sg_dmamap), (0), (scb->sg_map->sg_dmamap
->dm_mapsize), (0x04))
355 0, scb->sg_map->sg_dmamap->dm_mapsize,(*(ahc->parent_dmat)->_dmamap_sync)((ahc->parent_dmat
), (scb->sg_map->sg_dmamap), (0), (scb->sg_map->sg_dmamap
->dm_mapsize), (0x04))
356 BUS_DMASYNC_PREWRITE)(*(ahc->parent_dmat)->_dmamap_sync)((ahc->parent_dmat
), (scb->sg_map->sg_dmamap), (0), (scb->sg_map->sg_dmamap
->dm_mapsize), (0x04))
;
357
358 /* Copy the first SG into the "current" data pointer area */
359 scb->hscb->dataptr = scb->sg_list->addr;
360 scb->hscb->datacnt = scb->sg_list->len;
361 } else {
362 scb->hscb->sgptr = aic_htole32(SG_LIST_NULL)((__uint32_t)(0x01));
363 scb->hscb->dataptr = 0;
364 scb->hscb->datacnt = 0;
365 }
366
367 scb->sg_count = nsegments;
368
369 s = splbio()splraise(0x6);
370
371 tinfo = ahc_fetch_transinfo(ahc, SCSIID_CHANNEL(ahc, scb->hscb->scsiid)((((ahc)->features & AHC_TWIN) != 0) ? ((((scb->hscb
->scsiid) & 0x80) != 0) ? 'B' : 'A') : 'A')
,
372 SCSIID_OUR_ID(scb->hscb->scsiid)((scb->hscb->scsiid) & 0x0f),
373 SCSIID_TARGET(ahc, scb->hscb->scsiid)(((scb->hscb->scsiid) & ((((ahc)->features &
AHC_TWIN) != 0) ? 0x70 : 0xf0)) >> 0x04)
,
374 &tstate);
375
376 mask = SCB_GET_TARGET_MASK(ahc, scb)(0x01 << ((((((scb)->hscb->scsiid) & (((((ahc
))->features & AHC_TWIN) != 0) ? 0x70 : 0xf0)) >>
0x04))))
;
377 scb->hscb->scsirate = tinfo->scsirate;
378 scb->hscb->scsioffset = tinfo->curr.offset;
379
380 if ((tstate->ultraenb & mask) != 0)
381 scb->hscb->control |= ULTRAENB0x08;
382
383 if ((tstate->discenable & mask) != 0)
384 scb->hscb->control |= DISCENB0x40;
385
386 if ((tstate->auto_negotiate & mask) != 0) {
387 scb->flags |= SCB_AUTO_NEGOTIATE;
388 scb->hscb->control |= MK_MESSAGE0x10;
389 }
390
391 if ((tstate->tagenable & mask) != 0)
392 scb->hscb->control |= TAG_ENB0x20;
393
394 bus_dmamap_sync(ahc->parent_dmat, ahc->scb_data->hscb_dmamap,(*(ahc->parent_dmat)->_dmamap_sync)((ahc->parent_dmat
), (ahc->scb_data->hscb_dmamap), (0), (ahc->scb_data
->hscb_dmamap->dm_mapsize), (0x01 | 0x04))
395 0, ahc->scb_data->hscb_dmamap->dm_mapsize,(*(ahc->parent_dmat)->_dmamap_sync)((ahc->parent_dmat
), (ahc->scb_data->hscb_dmamap), (0), (ahc->scb_data
->hscb_dmamap->dm_mapsize), (0x01 | 0x04))
396 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE)(*(ahc->parent_dmat)->_dmamap_sync)((ahc->parent_dmat
), (ahc->scb_data->hscb_dmamap), (0), (ahc->scb_data
->hscb_dmamap->dm_mapsize), (0x01 | 0x04))
;
397
398 LIST_INSERT_HEAD(&ahc->pending_scbs, scb, pending_links)do { if (((scb)->pending_links.le_next = (&ahc->pending_scbs
)->lh_first) != ((void *)0)) (&ahc->pending_scbs)->
lh_first->pending_links.le_prev = &(scb)->pending_links
.le_next; (&ahc->pending_scbs)->lh_first = (scb); (
scb)->pending_links.le_prev = &(&ahc->pending_scbs
)->lh_first; } while (0)
;
399
400 if (!(xs->flags & SCSI_POLL0x00002))
401 timeout_add_msec(&xs->stimeout, xs->timeout);
402
403 /*
404 * We only allow one untagged transaction
405 * per target in the initiator role unless
406 * we are storing a full busy target *lun*
407 * table in SCB space.
408 *
409 * This really should not be of any
410 * concern, as we take care to avoid this
411 * in ahc_done(). XXX smurph
412 */
413 if ((scb->hscb->control & (TARGET_SCB0x80|TAG_ENB0x20)) == 0
414 && (ahc->flags & AHC_SCB_BTT) == 0) {
415 struct scb_tailq *untagged_q;
416 int target_offset;
417
418 target_offset = SCB_GET_TARGET_OFFSET(ahc, scb)(((((scb)->hscb->scsiid) & (((((ahc))->features &
AHC_TWIN) != 0) ? 0x70 : 0xf0)) >> 0x04))
;
419 untagged_q = &(ahc->untagged_queues[target_offset]);
420 TAILQ_INSERT_TAIL(untagged_q, scb, links.tqe)do { (scb)->links.tqe.tqe_next = ((void *)0); (scb)->links
.tqe.tqe_prev = (untagged_q)->tqh_last; *(untagged_q)->
tqh_last = (scb); (untagged_q)->tqh_last = &(scb)->
links.tqe.tqe_next; } while (0)
;
421 scb->flags |= SCB_UNTAGGEDQ;
422 if (TAILQ_FIRST(untagged_q)((untagged_q)->tqh_first) != scb) {
423 if (xs->flags & SCSI_POLL0x00002)
424 goto poll;
425 else {
426 splx(s)spllower(s);
427 return;
428 }
429 }
430 }
431 scb->flags |= SCB_ACTIVE;
432
433 if ((scb->flags & SCB_TARGET_IMMEDIATE) != 0) {
434 /* Define a mapping from our tag to the SCB. */
435 ahc->scb_data->scbindex[scb->hscb->tag] = scb;
436 ahc_pause(ahc);
437 if ((ahc->flags & AHC_PAGESCBS) == 0)
438 ahc_outb(ahc, SCBPTR, scb->hscb->tag)(((ahc)->tag)->write_1(((ahc)->bsh), (0x90), (scb->
hscb->tag)))
;
439 ahc_outb(ahc, TARG_IMMEDIATE_SCB, scb->hscb->tag)(((ahc)->tag)->write_1(((ahc)->bsh), (0x53), (scb->
hscb->tag)))
;
440 ahc_unpause(ahc);
441 } else {
442 ahc_queue_scb(ahc, scb);
443 }
444
445 if (!(xs->flags & SCSI_POLL0x00002)) {
446 if (ahc->inited_target[xs->sc_link->target] == 0) {
447 struct ahc_devinfo devinfo;
448
449 ahc_adapter_req_set_xfer_mode(ahc, scb);
450 ahc_scb_devinfo(ahc, &devinfo, scb);
451 ahc_update_neg_request(ahc, &devinfo, tstate, tinfo,
452 AHC_NEG_IF_NON_ASYNC);
453
454 ahc->inited_target[xs->sc_link->target] = 1;
455 }
456 splx(s)spllower(s);
457 return;
458 }
459
460 /*
461 * If we can't use interrupts, poll for completion
462 */
463poll:
464#ifdef AHC_DEBUG
465 printf("%s: cmd_poll\n", ahc_name(ahc));
466#endif
467
468 do {
469 if (ahc_poll(ahc, xs->timeout)) {
470 if (!(xs->flags & SCSI_SILENT0x00020))
471 printf("cmd fail\n");
472 ahc_timeout(scb);
473 break;
474 }
475 } while (!(xs->flags & ITSDONE0x00008));
476
477 splx(s)spllower(s);
478}
479
480int
481ahc_poll(struct ahc_softc *ahc, int wait)
482{
483 while (--wait) {
484 DELAY(1000)(*delay_func)(1000);
485 if (ahc_inb(ahc, INTSTAT)(((ahc)->tag)->read_1(((ahc)->bsh), (0x91))) & INT_PEND0x0f)
486 break;
487 }
488
489 if (wait == 0) {
490 printf("%s: board is not responding\n", ahc_name(ahc));
491 return (EIO5);
492 }
493
494 ahc_intr((void *)ahc);
495 return (0);
496}
497
498void
499ahc_setup_data(struct ahc_softc *ahc, struct scsi_xfer *xs,
500 struct scb *scb)
501{
502 struct hardware_scb *hscb;
503
504 hscb = scb->hscb;
505 xs->resid = xs->status = 0;
506 xs->error = CAM_REQ_INPROG;
507
508 hscb->cdb_len = xs->cmdlen;
509 if (hscb->cdb_len > sizeof(hscb->cdb32)) {
510 xs->error = XS_DRIVER_STUFFUP2;
511 scsi_done(xs);
512 return;
513 }
514
515 if (hscb->cdb_len > 12) {
516 memcpy(hscb->cdb32, &xs->cmd, hscb->cdb_len)__builtin_memcpy((hscb->cdb32), (&xs->cmd), (hscb->
cdb_len))
;
517 scb->flags |= SCB_CDB32_PTR;
518 } else {
519 memcpy(hscb->shared_data.cdb, &xs->cmd, hscb->cdb_len)__builtin_memcpy((hscb->shared_data.cdb), (&xs->cmd
), (hscb->cdb_len))
;
520 }
521
522 /* Only use S/G if there is a transfer */
523 if (xs->datalen) {
524 int error;
525
526 error = bus_dmamap_load(ahc->parent_dmat,(*(ahc->parent_dmat)->_dmamap_load)((ahc->parent_dmat
), (scb->dmamap), (xs->data), (xs->datalen), (((void
*)0)), ((xs->flags & 0x00001) ? 0x0001 : 0x0000))
527 scb->dmamap, xs->data,(*(ahc->parent_dmat)->_dmamap_load)((ahc->parent_dmat
), (scb->dmamap), (xs->data), (xs->datalen), (((void
*)0)), ((xs->flags & 0x00001) ? 0x0001 : 0x0000))
528 xs->datalen, NULL,(*(ahc->parent_dmat)->_dmamap_load)((ahc->parent_dmat
), (scb->dmamap), (xs->data), (xs->datalen), (((void
*)0)), ((xs->flags & 0x00001) ? 0x0001 : 0x0000))
529 (xs->flags & SCSI_NOSLEEP) ?(*(ahc->parent_dmat)->_dmamap_load)((ahc->parent_dmat
), (scb->dmamap), (xs->data), (xs->datalen), (((void
*)0)), ((xs->flags & 0x00001) ? 0x0001 : 0x0000))
530 BUS_DMA_NOWAIT : BUS_DMA_WAITOK)(*(ahc->parent_dmat)->_dmamap_load)((ahc->parent_dmat
), (scb->dmamap), (xs->data), (xs->datalen), (((void
*)0)), ((xs->flags & 0x00001) ? 0x0001 : 0x0000))
;
531 if (error) {
532#ifdef AHC_DEBUG
533 printf("%s: in ahc_setup_data(): bus_dmamap_load() "
534 "= %d\n",
535 ahc_name(ahc), error);
536#endif
537 xs->error = XS_DRIVER_STUFFUP2;
538 scsi_done(xs);
539 return;
540 }
541 ahc_execute_scb(scb, scb->dmamap->dm_segs,
542 scb->dmamap->dm_nsegs);
543 } else {
544 ahc_execute_scb(scb, NULL((void *)0), 0);
545 }
546}
547
548void
549ahc_timeout(void *arg)
550{
551 struct scb *scb, *list_scb;
552 struct ahc_softc *ahc;
553 int s;
554 int found;
555 char channel;
556
557 scb = arg;
558 ahc = scb->xs->sc_link->bus->sb_adapter_softc;
559
560 s = splbio()splraise(0x6);
561
562#ifdef AHC_DEBUG
563 printf("%s: SCB %d timed out\n", ahc_name(ahc), scb->hscb->tag);
564 ahc_dump_card_state(ahc);
565#endif
566
567 ahc_pause(ahc);
568
569 if (scb->flags & SCB_ACTIVE) {
570 channel = SCB_GET_CHANNEL(ahc, scb)((((ahc)->features & AHC_TWIN) != 0) ? (((((scb)->hscb
->scsiid) & 0x80) != 0) ? 'B' : 'A') : 'A')
;
571 ahc_set_transaction_status(scb, CAM_CMD_TIMEOUT);
572 /*
573 * Go through all of our pending SCBs and remove
574 * any scheduled timeouts for them. They're about to be
575 * aborted so no need for them to timeout.
576 */
577 LIST_FOREACH(list_scb, &ahc->pending_scbs, pending_links)for((list_scb) = ((&ahc->pending_scbs)->lh_first); (
list_scb)!= ((void *)0); (list_scb) = ((list_scb)->pending_links
.le_next))
{
578 if (list_scb->xs)
579 timeout_del(&list_scb->xs->stimeout);
580 }
581 found = ahc_reset_channel(ahc, channel, /*Initiate Reset*/TRUE1);
Value stored to 'found' is never read
582#ifdef AHC_DEBUG
583 printf("%s: Issued Channel %c Bus Reset %d SCBs aborted\n",
584 ahc_name(ahc), channel, found);
585#endif
586 }
587
588 ahc_unpause(ahc);
589 splx(s)spllower(s);
590}
591
592
593void
594ahc_platform_set_tags(struct ahc_softc *ahc,
595 struct ahc_devinfo *devinfo, int alg)
596{
597 struct ahc_tmode_tstate *tstate;
598
599 ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
600 devinfo->target, &tstate);
601
602 /* XXXX Need to check quirks before doing this! XXXX */
603
604 switch (alg) {
605 case AHC_QUEUE_BASIC:
606 case AHC_QUEUE_TAGGED:
607 tstate->tagenable |= devinfo->target_mask;
608 break;
609 case AHC_QUEUE_NONE:
610 tstate->tagenable &= ~devinfo->target_mask;
611 break;
612 }
613}
614
615int
616ahc_softc_comp(struct ahc_softc *lahc, struct ahc_softc *rahc)
617{
618 return (0);
619}
620
621void
622ahc_send_async(struct ahc_softc *ahc, char channel, u_int target, u_int lun,
623 ac_code code, void *opt_arg)
624{
625 /* Nothing to do here for OpenBSD */
626}
627
628void
629ahc_adapter_req_set_xfer_mode(struct ahc_softc *ahc, struct scb *scb)
630{
631 struct ahc_initiator_tinfo *tinfo;
632 struct ahc_tmode_tstate *tstate;
633 struct ahc_syncrate *syncrate;
634 struct ahc_devinfo devinfo;
635 u_int16_t quirks;
636 u_int width, ppr_options, period, offset;
637 int s;
638
639 s = splbio()splraise(0x6);
640
641 ahc_scb_devinfo(ahc, &devinfo, scb);
642 quirks = scb->xs->sc_link->quirks;
643 tinfo = ahc_fetch_transinfo(ahc, devinfo.channel,
644 devinfo.our_scsiid, devinfo.target, &tstate);
645
646 tstate->discenable |= (ahc->user_discenable & devinfo.target_mask);
647
648 if (quirks & SDEV_NOTAGS0x0008)
649 tstate->tagenable &= ~devinfo.target_mask;
650 else if (ahc->user_tagenable & devinfo.target_mask)
651 tstate->tagenable |= devinfo.target_mask;
652
653 if (quirks & SDEV_NOWIDE0x0004)
654 width = MSG_EXT_WDTR_BUS_8_BIT0x00;
655 else
656 width = MSG_EXT_WDTR_BUS_16_BIT0x01;
657
658 ahc_validate_width(ahc, NULL((void *)0), &width, ROLE_UNKNOWN);
659 if (width > tinfo->user.width)
660 width = tinfo->user.width;
661 ahc_set_width(ahc, &devinfo, width, AHC_TRANS_GOAL0x04, FALSE0);
662
663 if (quirks & SDEV_NOSYNC0x0002) {
664 period = 0;
665 offset = 0;
666 } else {
667 period = tinfo->user.period;
668 offset = tinfo->user.offset;
669 }
670
671 /* XXX Look at saved INQUIRY flags for PPR capabilities XXX */
672 ppr_options = tinfo->user.ppr_options;
673 /* XXX Other reasons to avoid ppr? XXX */
674 if (width < MSG_EXT_WDTR_BUS_16_BIT0x01)
675 ppr_options = 0;
676
677 if ((tstate->discenable & devinfo.target_mask) == 0 ||
678 (tstate->tagenable & devinfo.target_mask) == 0)
679 ppr_options &= ~MSG_EXT_PPR_PROT_IUS0x01;
680
681 syncrate = ahc_find_syncrate(ahc, &period, &ppr_options,
682 AHC_SYNCRATE_MAX0);
683 ahc_validate_offset(ahc, NULL((void *)0), syncrate, &offset, width,
684 ROLE_UNKNOWN);
685
686 if (offset == 0) {
687 period = 0;
688 ppr_options = 0;
689 }
690
691 if (ppr_options != 0 && tinfo->user.transport_version >= 3) {
692 tinfo->goal.transport_version = tinfo->user.transport_version;
693 tinfo->curr.transport_version = tinfo->user.transport_version;
694 }
695
696 ahc_set_syncrate(ahc, &devinfo, syncrate, period, offset, ppr_options,
697 AHC_TRANS_GOAL0x04, FALSE0);
698
699 splx(s)spllower(s);
700}
701
702/*
703 * Get a free scb. If there are none, see if we can allocate a new SCB.
704 */
705void *
706ahc_scb_alloc(void *xahc)
707{
708 struct ahc_softc *ahc = xahc;
709 struct scb *scb;
710
711 mtx_enter(&ahc->sc_scb_mtx);
712 scb = SLIST_FIRST(&ahc->scb_data->free_scbs)((&ahc->scb_data->free_scbs)->slh_first);
713
714 if (scb != NULL((void *)0))
715 SLIST_REMOVE_HEAD(&ahc->scb_data->free_scbs, links.sle)do { (&ahc->scb_data->free_scbs)->slh_first = (&
ahc->scb_data->free_scbs)->slh_first->links.sle.sle_next
; } while (0)
;
716
717 mtx_leave(&ahc->sc_scb_mtx);
718
719 return (scb);
720}
721
722/*
723 * Return an SCB resource to the free list.
724 */
725void
726ahc_scb_free(void *xahc, void *io)
727{
728 struct ahc_softc *ahc = xahc;
729 struct scb *scb = io;
730 struct hardware_scb *hscb;
731
732 hscb = scb->hscb;
733 /* Clean up for the next user */
734 ahc->scb_data->scbindex[hscb->tag] = NULL((void *)0);
735 scb->flags = SCB_FLAG_NONE;
736 hscb->control = 0;
737
738 mtx_enter(&ahc->sc_scb_mtx);
739 SLIST_INSERT_HEAD(&ahc->scb_data->free_scbs, scb, links.sle)do { (scb)->links.sle.sle_next = (&ahc->scb_data->
free_scbs)->slh_first; (&ahc->scb_data->free_scbs
)->slh_first = (scb); } while (0)
;
740 mtx_leave(&ahc->sc_scb_mtx);
741
742 /* Notify the OSM that a resource is now available. */
743 ahc_platform_scb_free(ahc, scb);
744}