Bug Summary

File:dev/ic/ciss.c
Warning:line 651, column 11
Although the value stored to 'rv' is used in the enclosing expression, the value is never actually read from 'rv'

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 ciss.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/ciss.c
1/* $OpenBSD: ciss.c,v 1.90 2022/01/09 05:42:38 jsg Exp $ */
2
3/*
4 * Copyright (c) 2005,2006 Michael Shalayeff
5 * All rights reserved.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
16 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
17 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#include "bio.h"
21
22/* #define CISS_DEBUG */
23
24#include <sys/param.h>
25#include <sys/systm.h>
26#include <sys/buf.h>
27#include <sys/ioctl.h>
28#include <sys/device.h>
29#include <sys/kernel.h>
30#include <sys/malloc.h>
31
32#include <machine/bus.h>
33
34#include <scsi/scsi_all.h>
35#include <scsi/scsiconf.h>
36
37#include <dev/ic/cissreg.h>
38#include <dev/ic/cissvar.h>
39
40#if NBIO1 > 0
41#include <dev/biovar.h>
42#endif
43#include <sys/sensors.h>
44
45#ifdef CISS_DEBUG
46#define CISS_DPRINTF(m,a) if (ciss_debug & (m)) printf a
47#define CISS_D_CMD 0x0001
48#define CISS_D_INTR 0x0002
49#define CISS_D_MISC 0x0004
50#define CISS_D_DMA 0x0008
51#define CISS_D_IOCTL 0x0010
52#define CISS_D_ERR 0x0020
53int ciss_debug = 0
54/* | CISS_D_CMD */
55/* | CISS_D_INTR */
56/* | CISS_D_MISC */
57/* | CISS_D_DMA */
58/* | CISS_D_IOCTL */
59/* | CISS_D_ERR */
60 ;
61#else
62#define CISS_DPRINTF(m,a) /* m, a */
63#endif
64
65struct cfdriver ciss_cd = {
66 NULL((void *)0), "ciss", DV_DULL
67};
68
69void ciss_scsi_cmd(struct scsi_xfer *xs);
70int ciss_scsi_ioctl(struct scsi_link *, u_long, caddr_t, int);
71
72struct scsi_adapter ciss_switch = {
73 ciss_scsi_cmd, NULL((void *)0), NULL((void *)0), NULL((void *)0), ciss_scsi_ioctl
74};
75
76#if NBIO1 > 0
77int ciss_ioctl(struct device *, u_long, caddr_t);
78#endif
79int ciss_sync(struct ciss_softc *sc);
80void ciss_heartbeat(void *v);
81#ifndef SMALL_KERNEL
82void ciss_sensors(void *);
83#endif
84
85void * ciss_get_ccb(void *);
86void ciss_put_ccb(void *, void *);
87int ciss_cmd(struct ciss_ccb *ccb, int flags, int wait);
88int ciss_done(struct ciss_ccb *ccb);
89int ciss_error(struct ciss_ccb *ccb);
90
91struct ciss_ld *ciss_pdscan(struct ciss_softc *sc, int ld);
92int ciss_inq(struct ciss_softc *sc, struct ciss_inquiry *inq);
93int ciss_ldmap(struct ciss_softc *sc);
94int ciss_ldid(struct ciss_softc *, int, struct ciss_ldid *);
95int ciss_ldstat(struct ciss_softc *, int, struct ciss_ldstat *);
96int ciss_pdid(struct ciss_softc *, u_int8_t, struct ciss_pdid *, int);
97int ciss_blink(struct ciss_softc *, int, int, int, struct ciss_blink *);
98
99void *
100ciss_get_ccb(void *xsc)
101{
102 struct ciss_softc *sc = xsc;
103 struct ciss_ccb *ccb;
104
105 mtx_enter(&sc->sc_free_ccb_mtx);
106 ccb = SLIST_FIRST(&sc->sc_free_ccb)((&sc->sc_free_ccb)->slh_first);
107 if (ccb != NULL((void *)0)) {
108 SLIST_REMOVE_HEAD(&sc->sc_free_ccb, ccb_link)do { (&sc->sc_free_ccb)->slh_first = (&sc->sc_free_ccb
)->slh_first->ccb_link.sle_next; } while (0)
;
109 ccb->ccb_state = CISS_CCB_READY;
110 ccb->ccb_xs = NULL((void *)0);
111 }
112 mtx_leave(&sc->sc_free_ccb_mtx);
113
114 return (ccb);
115}
116
117void
118ciss_put_ccb(void *xsc, void *xccb)
119{
120 struct ciss_softc *sc = xsc;
121 struct ciss_ccb *ccb = xccb;
122
123 ccb->ccb_state = CISS_CCB_FREE;
124 ccb->ccb_xs = NULL((void *)0);
125 ccb->ccb_data = NULL((void *)0);
126
127 mtx_enter(&sc->sc_free_ccb_mtx);
128 SLIST_INSERT_HEAD(&sc->sc_free_ccb, ccb, ccb_link)do { (ccb)->ccb_link.sle_next = (&sc->sc_free_ccb)->
slh_first; (&sc->sc_free_ccb)->slh_first = (ccb); }
while (0)
;
129 mtx_leave(&sc->sc_free_ccb_mtx);
130}
131
132int
133ciss_attach(struct ciss_softc *sc)
134{
135 struct scsibus_attach_args saa;
136 struct scsibus_softc *scsibus;
137 struct ciss_ccb *ccb;
138 struct ciss_cmd *cmd;
139 struct ciss_inquiry *inq;
140 bus_dma_segment_t seg[1];
141 int error, i, total, rseg, maxfer;
142 ciss_lock_t lock;
143 paddr_t pa;
144
145 bus_space_read_region_4(sc->iot, sc->cfg_ioh, sc->cfgoff,((sc->iot)->read_region_4((sc->cfg_ioh), (sc->cfgoff
), ((u_int32_t *)&sc->cfg), (sizeof(sc->cfg) / 4)))
146 (u_int32_t *)&sc->cfg, sizeof(sc->cfg) / 4)((sc->iot)->read_region_4((sc->cfg_ioh), (sc->cfgoff
), ((u_int32_t *)&sc->cfg), (sizeof(sc->cfg) / 4)))
;
147
148 if (sc->cfg.signature != CISS_SIGNATURE(*(u_int32_t *)"CISS")) {
149 printf(": bad sign 0x%08x\n", sc->cfg.signature);
150 return -1;
151 }
152
153 if (!(sc->cfg.methods & CISS_METH_SIMPL0x00000002)) {
154 printf(": not simple 0x%08x\n", sc->cfg.methods);
155 return -1;
156 }
157
158 sc->cfg.rmethod = CISS_METH_SIMPL0x00000002;
159 sc->cfg.paddr_lim = 0; /* 32bit addrs */
160 sc->cfg.int_delay = 0; /* disable coalescing */
161 sc->cfg.int_count = 0;
162 strlcpy(sc->cfg.hostname, "HUMPPA", sizeof(sc->cfg.hostname));
163 sc->cfg.driverf |= CISS_DRV_PRF0x0200; /* enable prefetch */
164 if (!sc->cfg.maxsg)
165 sc->cfg.maxsg = MAXPHYS(64 * 1024) / PAGE_SIZE(1 << 12);
166
167 bus_space_write_region_4(sc->iot, sc->cfg_ioh, sc->cfgoff,((sc->iot)->write_region_4((sc->cfg_ioh), (sc->cfgoff
), ((u_int32_t *)&sc->cfg), (sizeof(sc->cfg) / 4)))
168 (u_int32_t *)&sc->cfg, sizeof(sc->cfg) / 4)((sc->iot)->write_region_4((sc->cfg_ioh), (sc->cfgoff
), ((u_int32_t *)&sc->cfg), (sizeof(sc->cfg) / 4)))
;
169 bus_space_barrier(sc->iot, sc->cfg_ioh, sc->cfgoff, sizeof(sc->cfg),
170 BUS_SPACE_BARRIER_READ0x01|BUS_SPACE_BARRIER_WRITE0x02);
171
172 bus_space_write_4(sc->iot, sc->ioh, CISS_IDB, CISS_IDB_CFG)((sc->iot)->write_4((sc->ioh), (0x20), (0x01)));
173 bus_space_barrier(sc->iot, sc->ioh, CISS_IDB0x20, 4,
174 BUS_SPACE_BARRIER_WRITE0x02);
175 for (i = 1000; i--; DELAY(1000)(*delay_func)(1000)) {
176 /* XXX maybe IDB is really 64bit? - hp dl380 needs this */
177 (void)bus_space_read_4(sc->iot, sc->ioh, CISS_IDB + 4)((sc->iot)->read_4((sc->ioh), (0x20 + 4)));
178 if (!(bus_space_read_4(sc->iot, sc->ioh, CISS_IDB)((sc->iot)->read_4((sc->ioh), (0x20))) & CISS_IDB_CFG0x01))
179 break;
180 bus_space_barrier(sc->iot, sc->ioh, CISS_IDB0x20, 4,
181 BUS_SPACE_BARRIER_READ0x01);
182 }
183
184 if (bus_space_read_4(sc->iot, sc->ioh, CISS_IDB)((sc->iot)->read_4((sc->ioh), (0x20))) & CISS_IDB_CFG0x01) {
185 printf(": cannot set config\n");
186 return -1;
187 }
188
189 bus_space_read_region_4(sc->iot, sc->cfg_ioh, sc->cfgoff,((sc->iot)->read_region_4((sc->cfg_ioh), (sc->cfgoff
), ((u_int32_t *)&sc->cfg), (sizeof(sc->cfg) / 4)))
190 (u_int32_t *)&sc->cfg, sizeof(sc->cfg) / 4)((sc->iot)->read_region_4((sc->cfg_ioh), (sc->cfgoff
), ((u_int32_t *)&sc->cfg), (sizeof(sc->cfg) / 4)))
;
191
192 if (!(sc->cfg.amethod & CISS_METH_SIMPL0x00000002)) {
193 printf(": cannot simplify 0x%08x\n", sc->cfg.amethod);
194 return -1;
195 }
196
197 /* i'm ready for you and i hope you're ready for me */
198 for (i = 30000; i--; DELAY(1000)(*delay_func)(1000)) {
199 if (bus_space_read_4(sc->iot, sc->cfg_ioh, sc->cfgoff +((sc->iot)->read_4((sc->cfg_ioh), (sc->cfgoff + __builtin_offsetof
(struct ciss_config, amethod))))
200 offsetof(struct ciss_config, amethod))((sc->iot)->read_4((sc->cfg_ioh), (sc->cfgoff + __builtin_offsetof
(struct ciss_config, amethod))))
& CISS_METH_READY0x00000001)
201 break;
202 bus_space_barrier(sc->iot, sc->cfg_ioh, sc->cfgoff +
203 offsetof(struct ciss_config, amethod)__builtin_offsetof(struct ciss_config, amethod), 4,
204 BUS_SPACE_BARRIER_READ0x01);
205 }
206
207 if (!(bus_space_read_4(sc->iot, sc->cfg_ioh, sc->cfgoff +((sc->iot)->read_4((sc->cfg_ioh), (sc->cfgoff + __builtin_offsetof
(struct ciss_config, amethod))))
208 offsetof(struct ciss_config, amethod))((sc->iot)->read_4((sc->cfg_ioh), (sc->cfgoff + __builtin_offsetof
(struct ciss_config, amethod))))
& CISS_METH_READY0x00000001)) {
209 printf(": she never came ready for me 0x%08x\n",
210 sc->cfg.amethod);
211 return -1;
212 }
213
214 sc->maxcmd = sc->cfg.maxcmd;
215 sc->maxsg = sc->cfg.maxsg;
216 if (sc->maxsg > MAXPHYS(64 * 1024) / PAGE_SIZE(1 << 12))
217 sc->maxsg = MAXPHYS(64 * 1024) / PAGE_SIZE(1 << 12);
218 i = sizeof(struct ciss_ccb) +
219 sizeof(ccb->ccb_cmd.sgl[0]) * (sc->maxsg - 1);
220 for (sc->ccblen = 0x10; sc->ccblen < i; sc->ccblen <<= 1);
221
222 total = sc->ccblen * sc->maxcmd;
223 if ((error = bus_dmamem_alloc(sc->dmat, total, PAGE_SIZE, 0,(*(sc->dmat)->_dmamem_alloc)((sc->dmat), (total), ((
1 << 12)), (0), (sc->cmdseg), (1), (&rseg), (0x0001
| 0x1000))
224 sc->cmdseg, 1, &rseg, BUS_DMA_NOWAIT | BUS_DMA_ZERO)(*(sc->dmat)->_dmamem_alloc)((sc->dmat), (total), ((
1 << 12)), (0), (sc->cmdseg), (1), (&rseg), (0x0001
| 0x1000))
)) {
225 printf(": cannot allocate CCBs (%d)\n", error);
226 return -1;
227 }
228
229 if ((error = bus_dmamem_map(sc->dmat, sc->cmdseg, rseg, total,(*(sc->dmat)->_dmamem_map)((sc->dmat), (sc->cmdseg
), (rseg), (total), ((caddr_t *)&sc->ccbs), (0x0001))
230 (caddr_t *)&sc->ccbs, BUS_DMA_NOWAIT)(*(sc->dmat)->_dmamem_map)((sc->dmat), (sc->cmdseg
), (rseg), (total), ((caddr_t *)&sc->ccbs), (0x0001))
)) {
231 printf(": cannot map CCBs (%d)\n", error);
232 return -1;
233 }
234
235 if ((error = bus_dmamap_create(sc->dmat, total, 1,(*(sc->dmat)->_dmamap_create)((sc->dmat), (total), (
1), (total), (0), (0x0001 | 0x0002), (&sc->cmdmap))
236 total, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &sc->cmdmap)(*(sc->dmat)->_dmamap_create)((sc->dmat), (total), (
1), (total), (0), (0x0001 | 0x0002), (&sc->cmdmap))
)) {
237 printf(": cannot create CCBs dmamap (%d)\n", error);
238 bus_dmamem_free(sc->dmat, sc->cmdseg, 1)(*(sc->dmat)->_dmamem_free)((sc->dmat), (sc->cmdseg
), (1))
;
239 return -1;
240 }
241
242 if ((error = bus_dmamap_load(sc->dmat, sc->cmdmap, sc->ccbs, total,(*(sc->dmat)->_dmamap_load)((sc->dmat), (sc->cmdmap
), (sc->ccbs), (total), (((void *)0)), (0x0001))
243 NULL, BUS_DMA_NOWAIT)(*(sc->dmat)->_dmamap_load)((sc->dmat), (sc->cmdmap
), (sc->ccbs), (total), (((void *)0)), (0x0001))
)) {
244 printf(": cannot load CCBs dmamap (%d)\n", error);
245 bus_dmamem_free(sc->dmat, sc->cmdseg, 1)(*(sc->dmat)->_dmamem_free)((sc->dmat), (sc->cmdseg
), (1))
;
246 bus_dmamap_destroy(sc->dmat, sc->cmdmap)(*(sc->dmat)->_dmamap_destroy)((sc->dmat), (sc->cmdmap
))
;
247 return -1;
248 }
249
250 SLIST_INIT(&sc->sc_free_ccb){ ((&sc->sc_free_ccb)->slh_first) = ((void *)0); };
251 mtx_init(&sc->sc_free_ccb_mtx, IPL_BIO)do { (void)(((void *)0)); (void)(0); __mtx_init((&sc->
sc_free_ccb_mtx), ((((0x6)) > 0x0 && ((0x6)) < 0x9
) ? 0x9 : ((0x6)))); } while (0)
;
252
253 maxfer = sc->maxsg * PAGE_SIZE(1 << 12);
254 for (i = 0; total; i++, total -= sc->ccblen) {
255 ccb = sc->ccbs + i * sc->ccblen;
256 cmd = &ccb->ccb_cmd;
257 pa = sc->cmdseg[0].ds_addr + i * sc->ccblen;
258
259 ccb->ccb_sc = sc;
260 ccb->ccb_cmdpa = pa + offsetof(struct ciss_ccb, ccb_cmd)__builtin_offsetof(struct ciss_ccb, ccb_cmd);
261 ccb->ccb_state = CISS_CCB_FREE;
262
263 cmd->id = htole32(i << 2)((__uint32_t)(i << 2));
264 cmd->id_hi = htole32(0)((__uint32_t)(0));
265 cmd->sgin = sc->maxsg;
266 cmd->sglen = htole16((u_int16_t)cmd->sgin)((__uint16_t)((u_int16_t)cmd->sgin));
267 cmd->err_len = htole32(sizeof(ccb->ccb_err))((__uint32_t)(sizeof(ccb->ccb_err)));
268 pa += offsetof(struct ciss_ccb, ccb_err)__builtin_offsetof(struct ciss_ccb, ccb_err);
269 cmd->err_pa = htole64((u_int64_t)pa)((__uint64_t)((u_int64_t)pa));
270
271 if ((error = bus_dmamap_create(sc->dmat, maxfer, sc->maxsg,(*(sc->dmat)->_dmamap_create)((sc->dmat), (maxfer), (
sc->maxsg), (maxfer), (0), (0x0001 | 0x0002), (&ccb->
ccb_dmamap))
272 maxfer, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,(*(sc->dmat)->_dmamap_create)((sc->dmat), (maxfer), (
sc->maxsg), (maxfer), (0), (0x0001 | 0x0002), (&ccb->
ccb_dmamap))
273 &ccb->ccb_dmamap)(*(sc->dmat)->_dmamap_create)((sc->dmat), (maxfer), (
sc->maxsg), (maxfer), (0), (0x0001 | 0x0002), (&ccb->
ccb_dmamap))
))
274 break;
275
276 SLIST_INSERT_HEAD(&sc->sc_free_ccb, ccb, ccb_link)do { (ccb)->ccb_link.sle_next = (&sc->sc_free_ccb)->
slh_first; (&sc->sc_free_ccb)->slh_first = (ccb); }
while (0)
;
277 }
278
279 scsi_iopool_init(&sc->sc_iopool, sc, ciss_get_ccb, ciss_put_ccb);
280
281 if (i < sc->maxcmd) {
282 printf(": cannot create ccb#%d dmamap (%d)\n", i, error);
283 if (i == 0) {
284 /* TODO leaking cmd's dmamaps and shitz */
285 bus_dmamem_free(sc->dmat, sc->cmdseg, 1)(*(sc->dmat)->_dmamem_free)((sc->dmat), (sc->cmdseg
), (1))
;
286 bus_dmamap_destroy(sc->dmat, sc->cmdmap)(*(sc->dmat)->_dmamap_destroy)((sc->dmat), (sc->cmdmap
))
;
287 return -1;
288 }
289 }
290
291 if ((error = bus_dmamem_alloc(sc->dmat, PAGE_SIZE, PAGE_SIZE, 0,(*(sc->dmat)->_dmamem_alloc)((sc->dmat), ((1 <<
12)), ((1 << 12)), (0), (seg), (1), (&rseg), (0x0001
| 0x1000))
292 seg, 1, &rseg, BUS_DMA_NOWAIT | BUS_DMA_ZERO)(*(sc->dmat)->_dmamem_alloc)((sc->dmat), ((1 <<
12)), ((1 << 12)), (0), (seg), (1), (&rseg), (0x0001
| 0x1000))
)) {
293 printf(": cannot allocate scratch buffer (%d)\n", error);
294 return -1;
295 }
296
297 if ((error = bus_dmamem_map(sc->dmat, seg, rseg, PAGE_SIZE,(*(sc->dmat)->_dmamem_map)((sc->dmat), (seg), (rseg)
, ((1 << 12)), ((caddr_t *)&sc->scratch), (0x0001
))
298 (caddr_t *)&sc->scratch, BUS_DMA_NOWAIT)(*(sc->dmat)->_dmamem_map)((sc->dmat), (seg), (rseg)
, ((1 << 12)), ((caddr_t *)&sc->scratch), (0x0001
))
)) {
299 printf(": cannot map scratch buffer (%d)\n", error);
300 return -1;
301 }
302
303 lock = CISS_LOCK_SCRATCH(sc)splraise(0x6);
304 inq = sc->scratch;
305 if (ciss_inq(sc, inq)) {
306 printf(": adapter inquiry failed\n");
307 CISS_UNLOCK_SCRATCH(sc, lock)spllower(lock);
308 bus_dmamem_free(sc->dmat, sc->cmdseg, 1)(*(sc->dmat)->_dmamem_free)((sc->dmat), (sc->cmdseg
), (1))
;
309 bus_dmamap_destroy(sc->dmat, sc->cmdmap)(*(sc->dmat)->_dmamap_destroy)((sc->dmat), (sc->cmdmap
))
;
310 return -1;
311 }
312
313 if (!(inq->flags & CISS_INQ_BIGMAP0x80)) {
314 printf(": big map is not supported, flags=%b\n",
315 inq->flags, CISS_INQ_BITS"\020\04WIDE\010BIGMAP");
316 CISS_UNLOCK_SCRATCH(sc, lock)spllower(lock);
317 bus_dmamem_free(sc->dmat, sc->cmdseg, 1)(*(sc->dmat)->_dmamem_free)((sc->dmat), (sc->cmdseg
), (1))
;
318 bus_dmamap_destroy(sc->dmat, sc->cmdmap)(*(sc->dmat)->_dmamap_destroy)((sc->dmat), (sc->cmdmap
))
;
319 return -1;
320 }
321
322 sc->maxunits = inq->numld;
323 sc->nbus = inq->nscsi_bus;
324 sc->ndrives = inq->buswidth? inq->buswidth : 256;
325 printf(": %d LD%s, HW rev %d, FW %4.4s/%4.4s",
326 inq->numld, inq->numld == 1? "" : "s",
327 inq->hw_rev, inq->fw_running, inq->fw_stored);
328 if (sc->cfg.methods & CISS_METH_FIFO640x80000000)
329 printf(", 64bit fifo");
330 else if (sc->cfg.methods & CISS_METH_FIFO64_RRO0x10000000)
331 printf(", 64bit fifo rro");
332 printf("\n");
333
334 CISS_UNLOCK_SCRATCH(sc, lock)spllower(lock);
335
336 timeout_set(&sc->sc_hb, ciss_heartbeat, sc);
337 timeout_add_sec(&sc->sc_hb, 3);
338
339 /* map LDs */
340 if (ciss_ldmap(sc)) {
341 printf("%s: adapter LD map failed\n", sc->sc_dev.dv_xname);
342 bus_dmamem_free(sc->dmat, sc->cmdseg, 1)(*(sc->dmat)->_dmamem_free)((sc->dmat), (sc->cmdseg
), (1))
;
343 bus_dmamap_destroy(sc->dmat, sc->cmdmap)(*(sc->dmat)->_dmamap_destroy)((sc->dmat), (sc->cmdmap
))
;
344 return -1;
345 }
346
347 if (!(sc->sc_lds = mallocarray(sc->maxunits, sizeof(*sc->sc_lds),
348 M_DEVBUF2, M_NOWAIT0x0002 | M_ZERO0x0008))) {
349 bus_dmamem_free(sc->dmat, sc->cmdseg, 1)(*(sc->dmat)->_dmamem_free)((sc->dmat), (sc->cmdseg
), (1))
;
350 bus_dmamap_destroy(sc->dmat, sc->cmdmap)(*(sc->dmat)->_dmamap_destroy)((sc->dmat), (sc->cmdmap
))
;
351 return -1;
352 }
353
354 sc->sc_flush = CISS_FLUSH_ENABLE0;
355
356 saa.saa_adapter_softc = sc;
357 saa.saa_adapter = &ciss_switch;
358 saa.saa_luns = 1;
359 saa.saa_adapter_target = SDEV_NO_ADAPTER_TARGET0xffff;
360 saa.saa_adapter_buswidth = sc->maxunits;
361 saa.saa_openings = sc->maxcmd;
362 saa.saa_pool = &sc->sc_iopool;
363 saa.saa_quirks = saa.saa_flags = 0;
364 saa.saa_wwpn = saa.saa_wwnn = 0;
365
366 scsibus = (struct scsibus_softc *)config_found_sm(&sc->sc_dev,
367 &saa, scsiprint, NULL((void *)0));
368
369#if NBIO1 > 0
370 /* XXX for now we can only deal w/ one volume. */
371 if (!scsibus || sc->maxunits > 1)
372 return 0;
373
374 /* now map all the physdevs into their lds */
375 /* XXX currently we assign all pf 'em into ld#0 */
376 for (i = 0; i < sc->maxunits; i++)
377 if (!(sc->sc_lds[i] = ciss_pdscan(sc, i)))
378 return 0;
379
380 if (bio_register(&sc->sc_dev, ciss_ioctl) != 0)
381 printf("%s: controller registration failed",
382 sc->sc_dev.dv_xname);
383
384 sc->sc_flags |= CISS_BIO0x0001;
385#ifndef SMALL_KERNEL
386 sc->sensors = mallocarray(sc->maxunits, sizeof(struct ksensor),
387 M_DEVBUF2, M_NOWAIT0x0002 | M_ZERO0x0008);
388 if (sc->sensors) {
389 struct device *dev;
390
391 strlcpy(sc->sensordev.xname, sc->sc_dev.dv_xname,
392 sizeof(sc->sensordev.xname));
393 for (i = 0; i < sc->maxunits; i++) {
394 sc->sensors[i].type = SENSOR_DRIVE;
395 sc->sensors[i].status = SENSOR_S_UNKNOWN;
396 dev = scsi_get_link(scsibus, i, 0)->device_softc;
397 strlcpy(sc->sensors[i].desc, dev->dv_xname,
398 sizeof(sc->sensors[i].desc));
399 strlcpy(sc->sc_lds[i]->xname, dev->dv_xname,
400 sizeof(sc->sc_lds[i]->xname));
401 sensor_attach(&sc->sensordev, &sc->sensors[i]);
402 }
403 if (sensor_task_register(sc, ciss_sensors, 10) == NULL((void *)0))
404 free(sc->sensors, M_DEVBUF2,
405 sc->maxunits * sizeof(struct ksensor));
406 else
407 sensordev_install(&sc->sensordev);
408 }
409#endif /* SMALL_KERNEL */
410#endif /* BIO > 0 */
411
412 return 0;
413}
414
415void
416ciss_shutdown(void *v)
417{
418 struct ciss_softc *sc = v;
419
420 sc->sc_flush = CISS_FLUSH_DISABLE1;
421 timeout_del(&sc->sc_hb);
422 ciss_sync(sc);
423}
424
425/*
426 * submit a command and optionally wait for completion.
427 * wait arg abuses SCSI_POLL|SCSI_NOSLEEP flags to request
428 * to wait (SCSI_POLL) and to allow tsleep() (!SCSI_NOSLEEP)
429 * instead of busy loop waiting
430 */
431int
432ciss_cmd(struct ciss_ccb *ccb, int flags, int wait)
433{
434 struct timespec end, now, ts;
435 struct ciss_softc *sc = ccb->ccb_sc;
436 struct ciss_cmd *cmd = &ccb->ccb_cmd;
437 struct ciss_ccb *ccb1;
438 bus_dmamap_t dmap = ccb->ccb_dmamap;
439 u_int64_t addr;
440 uint64_t nsecs;
441 u_int32_t id;
442 int i, error = 0, ret;
443
444 splassert(IPL_BIO)do { if (splassert_ctl > 0) { splassert_check(0x6, __func__
); } } while (0)
;
445
446 if (ccb->ccb_state != CISS_CCB_READY) {
447 printf("%s: ccb %d not ready state=%b\n", sc->sc_dev.dv_xname,
448 cmd->id, ccb->ccb_state, CISS_CCB_BITS"\020\01FREE\02READY\03ONQ\04PREQ\05POLL\010FAIL");
449 return (EINVAL22);
450 }
451
452 if (ccb->ccb_data) {
453 bus_dma_segment_t *sgd;
454
455 if ((error = bus_dmamap_load(sc->dmat, dmap, ccb->ccb_data,(*(sc->dmat)->_dmamap_load)((sc->dmat), (dmap), (ccb
->ccb_data), (ccb->ccb_len), (((void *)0)), (flags))
456 ccb->ccb_len, NULL, flags)(*(sc->dmat)->_dmamap_load)((sc->dmat), (dmap), (ccb
->ccb_data), (ccb->ccb_len), (((void *)0)), (flags))
)) {
457 if (error == EFBIG27)
458 printf("more than %d dma segs\n", sc->maxsg);
459 else
460 printf("error %d loading dma map\n", error);
461 if (ccb->ccb_xs) {
462 ccb->ccb_xs->error = XS_DRIVER_STUFFUP2;
463 scsi_done(ccb->ccb_xs);
464 ccb->ccb_xs = NULL((void *)0);
465 }
466 return (error);
467 }
468 cmd->sgin = dmap->dm_nsegs;
469
470 sgd = dmap->dm_segs;
471 CISS_DPRINTF(CISS_D_DMA, ("data=%p/%zu<0x%lx/%lu",
472 ccb->ccb_data, ccb->ccb_len, sgd->ds_addr, sgd->ds_len));
473
474 for (i = 0; i < dmap->dm_nsegs; sgd++, i++) {
475 cmd->sgl[i].addr_lo = htole32(sgd->ds_addr)((__uint32_t)(sgd->ds_addr));
476 cmd->sgl[i].addr_hi =
477 htole32((u_int64_t)sgd->ds_addr >> 32)((__uint32_t)((u_int64_t)sgd->ds_addr >> 32));
478 cmd->sgl[i].len = htole32(sgd->ds_len)((__uint32_t)(sgd->ds_len));
479 cmd->sgl[i].flags = htole32(0)((__uint32_t)(0));
480 if (i)
481 CISS_DPRINTF(CISS_D_DMA,
482 (",0x%lx/%lu", sgd->ds_addr, sgd->ds_len));
483 }
484
485 CISS_DPRINTF(CISS_D_DMA, ("> "));
486
487 bus_dmamap_sync(sc->dmat, dmap, 0, dmap->dm_mapsize,(*(sc->dmat)->_dmamap_sync)((sc->dmat), (dmap), (0),
(dmap->dm_mapsize), (0x01|0x04))
488 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE)(*(sc->dmat)->_dmamap_sync)((sc->dmat), (dmap), (0),
(dmap->dm_mapsize), (0x01|0x04))
;
489 } else
490 cmd->sgin = 0;
491 cmd->sglen = htole16((u_int16_t)cmd->sgin)((__uint16_t)((u_int16_t)cmd->sgin));
492 bzero(&ccb->ccb_err, sizeof(ccb->ccb_err))__builtin_bzero((&ccb->ccb_err), (sizeof(ccb->ccb_err
)))
;
493
494 bus_dmamap_sync(sc->dmat, sc->cmdmap, 0, sc->cmdmap->dm_mapsize,(*(sc->dmat)->_dmamap_sync)((sc->dmat), (sc->cmdmap
), (0), (sc->cmdmap->dm_mapsize), (0x04))
495 BUS_DMASYNC_PREWRITE)(*(sc->dmat)->_dmamap_sync)((sc->dmat), (sc->cmdmap
), (0), (sc->cmdmap->dm_mapsize), (0x04))
;
496
497 ccb->ccb_state = CISS_CCB_ONQ;
498 CISS_DPRINTF(CISS_D_CMD, ("submit=0x%x ", cmd->id));
499 if (sc->cfg.methods & (CISS_METH_FIFO640x80000000|CISS_METH_FIFO64_RRO0x10000000)) {
500 /*
501 * Write the upper 32bits immediately before the lower
502 * 32bits and set bit 63 to indicate 64bit FIFO mode.
503 */
504 addr = (u_int64_t)ccb->ccb_cmdpa;
505 bus_space_write_4(sc->iot, sc->ioh, CISS_INQ64_HI,((sc->iot)->write_4((sc->ioh), (0xc4), ((addr >>
32) | 0x80000000)))
506 (addr >> 32) | 0x80000000)((sc->iot)->write_4((sc->ioh), (0xc4), ((addr >>
32) | 0x80000000)))
;
507 bus_space_write_4(sc->iot, sc->ioh, CISS_INQ64_LO,((sc->iot)->write_4((sc->ioh), (0xc0), (addr & 0x00000000ffffffffULL
)))
508 addr & 0x00000000ffffffffULL)((sc->iot)->write_4((sc->ioh), (0xc0), (addr & 0x00000000ffffffffULL
)))
;
509 } else
510 bus_space_write_4(sc->iot, sc->ioh, CISS_INQ, ccb->ccb_cmdpa)((sc->iot)->write_4((sc->ioh), (0x40), (ccb->ccb_cmdpa
)))
;
511
512 /* If we're not waiting for completion we're done. */
513 if (!(wait & SCSI_POLL0x00002))
514 return (error);
515
516 CISS_DPRINTF(CISS_D_CMD, ("waiting "));
517
518 i = ccb->ccb_xs? ccb->ccb_xs->timeout : 60000;
519
520 if (!(wait & SCSI_NOSLEEP0x00001)) {
521 NSEC_TO_TIMESPEC(MSEC_TO_NSEC(i), &ts);
522 nanouptime(&now);
523 timespecadd(&now, &ts, &end)do { (&end)->tv_sec = (&now)->tv_sec + (&ts
)->tv_sec; (&end)->tv_nsec = (&now)->tv_nsec
+ (&ts)->tv_nsec; if ((&end)->tv_nsec >= 1000000000L
) { (&end)->tv_sec++; (&end)->tv_nsec -= 1000000000L
; } } while (0)
;
524
525 for (;;) {
526 ccb->ccb_state = CISS_CCB_POLL;
527 nsecs = TIMESPEC_TO_NSEC(&ts);
528 CISS_DPRINTF(CISS_D_CMD, ("tsleep_nsec(%llu) ", nsecs));
529 ret = tsleep_nsec(ccb, PRIBIO16 + 1, "ciss_cmd", nsecs);
530 if (ret == EWOULDBLOCK35)
531 break;
532 if (ccb->ccb_state != CISS_CCB_ONQ) {
533 nanouptime(&now);
534 if (timespeccmp(&end, &now, <=)(((&end)->tv_sec == (&now)->tv_sec) ? ((&end
)->tv_nsec <= (&now)->tv_nsec) : ((&end)->
tv_sec <= (&now)->tv_sec))
)
535 break;
536 timespecsub(&end, &now, &ts)do { (&ts)->tv_sec = (&end)->tv_sec - (&now
)->tv_sec; (&ts)->tv_nsec = (&end)->tv_nsec -
(&now)->tv_nsec; if ((&ts)->tv_nsec < 0) { (
&ts)->tv_sec--; (&ts)->tv_nsec += 1000000000L; }
} while (0)
;
537 CISS_DPRINTF(CISS_D_CMD, ("T"));
538 continue;
539 }
540 ccb1 = ccb;
541
542 error = ciss_done(ccb1);
543 if (ccb1 == ccb)
544 return (error);
545 }
546 } else {
547 for (i *= 100; i--;) {
548 DELAY(10)(*delay_func)(10);
549
550 if (!(bus_space_read_4(sc->iot, sc->ioh,((sc->iot)->read_4((sc->ioh), (0x30)))
551 CISS_ISR)((sc->iot)->read_4((sc->ioh), (0x30))) & sc->iem)) {
552 CISS_DPRINTF(CISS_D_CMD, ("N"));
553 continue;
554 }
555
556 if (sc->cfg.methods & CISS_METH_FIFO640x80000000) {
557 if (bus_space_read_4(sc->iot, sc->ioh,((sc->iot)->read_4((sc->ioh), (0xcc)))
558 CISS_OUTQ64_HI)((sc->iot)->read_4((sc->ioh), (0xcc))) == 0xffffffff) {
559 CISS_DPRINTF(CISS_D_CMD, ("Q"));
560 continue;
561 }
562 id = bus_space_read_4(sc->iot, sc->ioh,((sc->iot)->read_4((sc->ioh), (0xc8)))
563 CISS_OUTQ64_LO)((sc->iot)->read_4((sc->ioh), (0xc8)));
564 } else if (sc->cfg.methods &
565 CISS_METH_FIFO64_RRO0x10000000) {
566 id = bus_space_read_4(sc->iot, sc->ioh,((sc->iot)->read_4((sc->ioh), (0xc8)))
567 CISS_OUTQ64_LO)((sc->iot)->read_4((sc->ioh), (0xc8)));
568 if (id == 0xffffffff) {
569 CISS_DPRINTF(CISS_D_CMD, ("Q"));
570 continue;
571 }
572 (void)bus_space_read_4(sc->iot,((sc->iot)->read_4((sc->ioh), (0xcc)))
573 sc->ioh, CISS_OUTQ64_HI)((sc->iot)->read_4((sc->ioh), (0xcc)));
574 } else {
575 id = bus_space_read_4(sc->iot, sc->ioh,((sc->iot)->read_4((sc->ioh), (0x44)))
576 CISS_OUTQ)((sc->iot)->read_4((sc->ioh), (0x44)));
577 if (id == 0xffffffff) {
578 CISS_DPRINTF(CISS_D_CMD, ("Q"));
579 continue;
580 }
581 }
582
583 CISS_DPRINTF(CISS_D_CMD, ("got=0x%x ", id));
584 ccb1 = sc->ccbs + (id >> 2) * sc->ccblen;
585 ccb1->ccb_cmd.id = htole32(id)((__uint32_t)(id));
586 ccb1->ccb_cmd.id_hi = htole32(0)((__uint32_t)(0));
587
588 error = ciss_done(ccb1);
589 if (ccb1 == ccb)
590 return (error);
591 }
592 }
593
594 /* if never got a chance to be done above... */
595 ccb->ccb_err.cmd_stat = CISS_ERR_TMO11;
596 error = ciss_done(ccb);
597
598 CISS_DPRINTF(CISS_D_CMD, ("done %d:%d",
599 ccb->ccb_err.cmd_stat, ccb->ccb_err.scsi_stat));
600
601 return (error);
602}
603
604int
605ciss_done(struct ciss_ccb *ccb)
606{
607 struct ciss_softc *sc = ccb->ccb_sc;
608 struct scsi_xfer *xs = ccb->ccb_xs;
609 struct ciss_cmd *cmd = &ccb->ccb_cmd;
610 ciss_lock_t lock;
611 int error = 0;
612
613 CISS_DPRINTF(CISS_D_CMD, ("ciss_done(%p) ", ccb));
614
615 if (ccb->ccb_state != CISS_CCB_ONQ) {
616 printf("%s: unqueued ccb %p ready, state=%b\n",
617 sc->sc_dev.dv_xname, ccb, ccb->ccb_state, CISS_CCB_BITS"\020\01FREE\02READY\03ONQ\04PREQ\05POLL\010FAIL");
618 return 1;
619 }
620 lock = CISS_LOCK(sc)splraise(0x6);
621 ccb->ccb_state = CISS_CCB_READY;
622
623 if (ccb->ccb_cmd.id & CISS_CMD_ERR0x02)
624 error = ciss_error(ccb);
625
626 if (ccb->ccb_data) {
627 bus_dmamap_sync(sc->dmat, ccb->ccb_dmamap, 0,(*(sc->dmat)->_dmamap_sync)((sc->dmat), (ccb->ccb_dmamap
), (0), (ccb->ccb_dmamap->dm_mapsize), ((cmd->flags &
0x80) ? 0x02 : 0x08))
628 ccb->ccb_dmamap->dm_mapsize, (cmd->flags & CISS_CDB_IN) ?(*(sc->dmat)->_dmamap_sync)((sc->dmat), (ccb->ccb_dmamap
), (0), (ccb->ccb_dmamap->dm_mapsize), ((cmd->flags &
0x80) ? 0x02 : 0x08))
629 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE)(*(sc->dmat)->_dmamap_sync)((sc->dmat), (ccb->ccb_dmamap
), (0), (ccb->ccb_dmamap->dm_mapsize), ((cmd->flags &
0x80) ? 0x02 : 0x08))
;
630 bus_dmamap_unload(sc->dmat, ccb->ccb_dmamap)(*(sc->dmat)->_dmamap_unload)((sc->dmat), (ccb->ccb_dmamap
))
;
631 }
632
633 if (xs) {
634 xs->resid = 0;
635 scsi_done(xs);
636 }
637
638 CISS_UNLOCK(sc, lock)spllower(lock);
639
640 return error;
641}
642
643int
644ciss_error(struct ciss_ccb *ccb)
645{
646 struct ciss_softc *sc = ccb->ccb_sc;
647 struct ciss_error *err = &ccb->ccb_err;
648 struct scsi_xfer *xs = ccb->ccb_xs;
649 int rv;
650
651 switch ((rv = letoh16(err->cmd_stat)((__uint16_t)(err->cmd_stat)))) {
Although the value stored to 'rv' is used in the enclosing expression, the value is never actually read from 'rv'
652 case CISS_ERR_OK0:
653 rv = 0;
654 break;
655
656 case CISS_ERR_INVCMD4:
657 printf("%s: invalid cmd 0x%x: 0x%x is not valid @ 0x%x[%d]\n",
658 sc->sc_dev.dv_xname, ccb->ccb_cmd.id,
659 err->err_info, err->err_type[3], err->err_type[2]);
660 if (xs) {
661 bzero(&xs->sense, sizeof(xs->sense))__builtin_bzero((&xs->sense), (sizeof(xs->sense)));
662 xs->sense.error_code = SSD_ERRCODE_VALID0x80 |
663 SSD_ERRCODE_CURRENT0x70;
664 xs->sense.flags = SKEY_ILLEGAL_REQUEST0x05;
665 xs->sense.add_sense_code = 0x24; /* ill field */
666 xs->error = XS_SENSE1;
667 }
668 rv = EIO5;
669 break;
670
671 case CISS_ERR_TMO11:
672 xs->error = XS_TIMEOUT4;
673 rv = ETIMEDOUT60;
674 break;
675
676 default:
677 if (xs) {
678 switch (err->scsi_stat) {
679 case SCSI_CHECK0x02:
680 xs->error = XS_SENSE1;
681 bcopy(&err->sense[0], &xs->sense,
682 sizeof(xs->sense));
683 rv = EIO5;
684 break;
685
686 case SCSI_BUSY0x08:
687 xs->error = XS_BUSY5;
688 rv = EBUSY16;
689 break;
690
691 default:
692 CISS_DPRINTF(CISS_D_ERR, ("%s: "
693 "cmd_stat %x scsi_stat 0x%x\n",
694 sc->sc_dev.dv_xname, rv, err->scsi_stat));
695 xs->error = XS_DRIVER_STUFFUP2;
696 rv = EIO5;
697 break;
698 }
699 xs->resid = letoh32(err->resid)((__uint32_t)(err->resid));
700 } else
701 rv = EIO5;
702 }
703 ccb->ccb_cmd.id &= htole32(~3)((__uint32_t)(~3));
704
705 return rv;
706}
707
708int
709ciss_inq(struct ciss_softc *sc, struct ciss_inquiry *inq)
710{
711 struct ciss_ccb *ccb;
712 struct ciss_cmd *cmd;
713 int rv;
714 int s;
715
716 ccb = scsi_io_get(&sc->sc_iopool, SCSI_POLL0x00002|SCSI_NOSLEEP0x00001);
717 if (ccb == NULL((void *)0))
718 return ENOMEM12;
719
720 ccb->ccb_len = sizeof(*inq);
721 ccb->ccb_data = inq;
722 cmd = &ccb->ccb_cmd;
723 cmd->tgt = htole32(CISS_CMD_MODE_PERIPH)((__uint32_t)(0x00000000));
724 cmd->tgt2 = 0;
725 cmd->cdblen = 10;
726 cmd->flags = CISS_CDB_CMD0x00 | CISS_CDB_SIMPL0x20 | CISS_CDB_IN0x80;
727 cmd->tmo = htole16(0)((__uint16_t)(0));
728 bzero(&cmd->cdb[0], sizeof(cmd->cdb))__builtin_bzero((&cmd->cdb[0]), (sizeof(cmd->cdb)));
729 cmd->cdb[0] = CISS_CMD_CTRL_GET0x26;
730 cmd->cdb[6] = CISS_CMS_CTRL_CTRL0x11;
731 cmd->cdb[7] = sizeof(*inq) >> 8; /* biiiig endian */
732 cmd->cdb[8] = sizeof(*inq) & 0xff;
733
734 s = splbio()splraise(0x6);
735 rv = ciss_cmd(ccb, BUS_DMA_NOWAIT0x0001, SCSI_POLL0x00002|SCSI_NOSLEEP0x00001);
736 splx(s)spllower(s);
737
738 scsi_io_put(&sc->sc_iopool, ccb);
739
740 return (rv);
741}
742
743int
744ciss_ldmap(struct ciss_softc *sc)
745{
746 struct ciss_ccb *ccb;
747 struct ciss_cmd *cmd;
748 struct ciss_ldmap *lmap;
749 ciss_lock_t lock;
750 int total, rv;
751
752 lock = CISS_LOCK_SCRATCH(sc)splraise(0x6);
753 lmap = sc->scratch;
754 lmap->size = htobe32(sc->maxunits * sizeof(lmap->map))(__uint32_t)(__builtin_constant_p(sc->maxunits * sizeof(lmap
->map)) ? (__uint32_t)(((__uint32_t)(sc->maxunits * sizeof
(lmap->map)) & 0xff) << 24 | ((__uint32_t)(sc->
maxunits * sizeof(lmap->map)) & 0xff00) << 8 | (
(__uint32_t)(sc->maxunits * sizeof(lmap->map)) & 0xff0000
) >> 8 | ((__uint32_t)(sc->maxunits * sizeof(lmap->
map)) & 0xff000000) >> 24) : __swap32md(sc->maxunits
* sizeof(lmap->map)))
;
755 total = sizeof(*lmap) + (sc->maxunits - 1) * sizeof(lmap->map);
756
757 ccb = scsi_io_get(&sc->sc_iopool, SCSI_POLL0x00002|SCSI_NOSLEEP0x00001);
758 if (ccb == NULL((void *)0)) {
759 CISS_UNLOCK_SCRATCH(sc, lock)spllower(lock);
760 return ENOMEM12;
761 }
762
763 ccb->ccb_len = total;
764 ccb->ccb_data = lmap;
765 cmd = &ccb->ccb_cmd;
766 cmd->tgt = CISS_CMD_MODE_PERIPH0x00000000;
767 cmd->tgt2 = 0;
768 cmd->cdblen = 12;
769 cmd->flags = CISS_CDB_CMD0x00 | CISS_CDB_SIMPL0x20 | CISS_CDB_IN0x80;
770 cmd->tmo = htole16(30)((__uint16_t)(30));
771 bzero(&cmd->cdb[0], sizeof(cmd->cdb))__builtin_bzero((&cmd->cdb[0]), (sizeof(cmd->cdb)));
772 cmd->cdb[0] = CISS_CMD_LDMAP0xc2;
773 cmd->cdb[8] = total >> 8; /* biiiig endian */
774 cmd->cdb[9] = total & 0xff;
775
776 rv = ciss_cmd(ccb, BUS_DMA_NOWAIT0x0001, SCSI_POLL0x00002|SCSI_NOSLEEP0x00001);
777 scsi_io_put(&sc->sc_iopool, ccb);
778 CISS_UNLOCK_SCRATCH(sc, lock)spllower(lock);
779
780 if (rv)
781 return rv;
782
783 CISS_DPRINTF(CISS_D_MISC, ("lmap %x:%x\n",
784 lmap->map[0].tgt, lmap->map[0].tgt2));
785
786 return 0;
787}
788
789int
790ciss_sync(struct ciss_softc *sc)
791{
792 struct ciss_ccb *ccb;
793 struct ciss_cmd *cmd;
794 struct ciss_flush *flush;
795 ciss_lock_t lock;
796 int rv;
797
798 lock = CISS_LOCK_SCRATCH(sc)splraise(0x6);
799 flush = sc->scratch;
800 bzero(flush, sizeof(*flush))__builtin_bzero((flush), (sizeof(*flush)));
801 flush->flush = sc->sc_flush;
802
803 ccb = scsi_io_get(&sc->sc_iopool, SCSI_POLL0x00002|SCSI_NOSLEEP0x00001);
804 if (ccb == NULL((void *)0)) {
805 CISS_UNLOCK_SCRATCH(sc, lock)spllower(lock);
806 return ENOMEM12;
807 }
808
809 ccb->ccb_len = sizeof(*flush);
810 ccb->ccb_data = flush;
811 cmd = &ccb->ccb_cmd;
812 cmd->tgt = CISS_CMD_MODE_PERIPH0x00000000;
813 cmd->tgt2 = 0;
814 cmd->cdblen = 10;
815 cmd->flags = CISS_CDB_CMD0x00 | CISS_CDB_SIMPL0x20 | CISS_CDB_OUT0x40;
816 cmd->tmo = htole16(0)((__uint16_t)(0));
817 bzero(&cmd->cdb[0], sizeof(cmd->cdb))__builtin_bzero((&cmd->cdb[0]), (sizeof(cmd->cdb)));
818 cmd->cdb[0] = CISS_CMD_CTRL_SET0x27;
819 cmd->cdb[6] = CISS_CMS_CTRL_FLUSH0xc2;
820 cmd->cdb[7] = sizeof(*flush) >> 8; /* biiiig endian */
821 cmd->cdb[8] = sizeof(*flush) & 0xff;
822
823 rv = ciss_cmd(ccb, BUS_DMA_NOWAIT0x0001, SCSI_POLL0x00002|SCSI_NOSLEEP0x00001);
824 scsi_io_put(&sc->sc_iopool, ccb);
825 CISS_UNLOCK_SCRATCH(sc, lock)spllower(lock);
826
827 return rv;
828}
829
830void
831ciss_scsi_cmd(struct scsi_xfer *xs)
832{
833 struct scsi_link *link = xs->sc_link;
834 u_int8_t target = link->target;
835 struct ciss_ccb *ccb;
836 struct ciss_cmd *cmd;
837 ciss_lock_t lock;
838
839 CISS_DPRINTF(CISS_D_CMD, ("ciss_scsi_cmd "));
840
841 if (xs->cmdlen > CISS_MAX_CDB16) {
842 CISS_DPRINTF(CISS_D_CMD, ("CDB too big %p ", xs));
843 bzero(&xs->sense, sizeof(xs->sense))__builtin_bzero((&xs->sense), (sizeof(xs->sense)));
844 xs->sense.error_code = SSD_ERRCODE_VALID0x80 | SSD_ERRCODE_CURRENT0x70;
845 xs->sense.flags = SKEY_ILLEGAL_REQUEST0x05;
846 xs->sense.add_sense_code = 0x20; /* illcmd, 0x24 illfield */
847 xs->error = XS_SENSE1;
848 scsi_done(xs);
849 return;
850 }
851
852 xs->error = XS_NOERROR0;
853
854 /* XXX emulate SYNCHRONIZE_CACHE ??? */
855
856 ccb = xs->io;
857
858 cmd = &ccb->ccb_cmd;
859 ccb->ccb_len = xs->datalen;
860 ccb->ccb_data = xs->data;
861 ccb->ccb_xs = xs;
862 cmd->tgt = CISS_CMD_MODE_LD0x40000000 | target;
863 cmd->tgt2 = 0;
864 cmd->cdblen = xs->cmdlen;
865 cmd->flags = CISS_CDB_CMD0x00 | CISS_CDB_SIMPL0x20;
866 if (xs->flags & SCSI_DATA_IN0x00800)
867 cmd->flags |= CISS_CDB_IN0x80;
868 else if (xs->flags & SCSI_DATA_OUT0x01000)
869 cmd->flags |= CISS_CDB_OUT0x40;
870 cmd->tmo = htole16(xs->timeout < 1000? 1 : xs->timeout / 1000)((__uint16_t)(xs->timeout < 1000? 1 : xs->timeout / 1000
))
;
871 bzero(&cmd->cdb[0], sizeof(cmd->cdb))__builtin_bzero((&cmd->cdb[0]), (sizeof(cmd->cdb)));
872 bcopy(&xs->cmd, &cmd->cdb[0], CISS_MAX_CDB16);
873
874 lock = CISS_LOCK(sc)splraise(0x6);
875 ciss_cmd(ccb, BUS_DMA_WAITOK0x0000, xs->flags & (SCSI_POLL0x00002|SCSI_NOSLEEP0x00001));
876 CISS_UNLOCK(sc, lock)spllower(lock);
877}
878
879int
880ciss_intr(void *v)
881{
882 struct ciss_softc *sc = v;
883 struct ciss_ccb *ccb;
884 bus_size_t reg;
885 u_int32_t id;
886 int hit = 0;
887
888 CISS_DPRINTF(CISS_D_INTR, ("intr "));
889
890 if (!(bus_space_read_4(sc->iot, sc->ioh, CISS_ISR)((sc->iot)->read_4((sc->ioh), (0x30))) & sc->iem))
891 return 0;
892
893 if (sc->cfg.methods & CISS_METH_FIFO640x80000000)
894 reg = CISS_OUTQ64_HI0xcc;
895 else if (sc->cfg.methods & CISS_METH_FIFO64_RRO0x10000000)
896 reg = CISS_OUTQ64_LO0xc8;
897 else
898 reg = CISS_OUTQ0x44;
899 while ((id = bus_space_read_4(sc->iot, sc->ioh, reg)((sc->iot)->read_4((sc->ioh), (reg)))) != 0xffffffff) {
900 if (reg == CISS_OUTQ64_HI0xcc)
901 id = bus_space_read_4(sc->iot, sc->ioh,((sc->iot)->read_4((sc->ioh), (0xc8)))
902 CISS_OUTQ64_LO)((sc->iot)->read_4((sc->ioh), (0xc8)));
903 else if (reg == CISS_OUTQ64_LO0xc8)
904 (void)bus_space_read_4(sc->iot, sc->ioh,((sc->iot)->read_4((sc->ioh), (0xcc)))
905 CISS_OUTQ64_HI)((sc->iot)->read_4((sc->ioh), (0xcc)));
906 ccb = sc->ccbs + (id >> 2) * sc->ccblen;
907 ccb->ccb_cmd.id = htole32(id)((__uint32_t)(id));
908 ccb->ccb_cmd.id_hi = htole32(0)((__uint32_t)(0)); /* ignore the upper 32bits */
909 if (ccb->ccb_state == CISS_CCB_POLL) {
910 ccb->ccb_state = CISS_CCB_ONQ;
911 wakeup(ccb);
912 } else
913 ciss_done(ccb);
914
915 hit = 1;
916 }
917 CISS_DPRINTF(CISS_D_INTR, ("exit "));
918 return hit;
919}
920
921void
922ciss_heartbeat(void *v)
923{
924 struct ciss_softc *sc = v;
925 u_int32_t hb;
926
927 hb = bus_space_read_4(sc->iot, sc->cfg_ioh,((sc->iot)->read_4((sc->cfg_ioh), (sc->cfgoff + __builtin_offsetof
(struct ciss_config, heartbeat))))
928 sc->cfgoff + offsetof(struct ciss_config, heartbeat))((sc->iot)->read_4((sc->cfg_ioh), (sc->cfgoff + __builtin_offsetof
(struct ciss_config, heartbeat))))
;
929 if (hb == sc->heartbeat) {
930 sc->fibrillation++;
931 CISS_DPRINTF(CISS_D_ERR, ("%s: fibrillation #%d (value=%d)\n",
932 sc->sc_dev.dv_xname, sc->fibrillation, hb));
933 if (sc->fibrillation >= 11) {
934 /* No heartbeat for 33 seconds */
935 panic("%s: dead", sc->sc_dev.dv_xname); /* XXX reset! */
936 }
937 } else {
938 sc->heartbeat = hb;
939 if (sc->fibrillation) {
940 CISS_DPRINTF(CISS_D_ERR, ("%s: "
941 "fibrillation ended (value=%d)\n",
942 sc->sc_dev.dv_xname, hb));
943 }
944 sc->fibrillation = 0;
945 }
946
947 timeout_add_sec(&sc->sc_hb, 3);
948}
949
950int
951ciss_scsi_ioctl(struct scsi_link *link, u_long cmd, caddr_t addr, int flag)
952{
953#if NBIO1 > 0
954 return ciss_ioctl(link->bus->sb_adapter_softc, cmd, addr);
955#else
956 return ENOTTY25;
957#endif
958}
959
960#if NBIO1 > 0
961const int ciss_level[] = { 0, 4, 1, 5, 51, 7 };
962const int ciss_stat[] = { BIOC_SVONLINE0x00, BIOC_SVOFFLINE0x01, BIOC_SVOFFLINE0x01,
963 BIOC_SVDEGRADED0x02, BIOC_SVREBUILD0x05, BIOC_SVREBUILD0x05, BIOC_SVDEGRADED0x02,
964 BIOC_SVDEGRADED0x02, BIOC_SVINVALID0xff, BIOC_SVINVALID0xff, BIOC_SVBUILDING0x03,
965 BIOC_SVOFFLINE0x01, BIOC_SVBUILDING0x03 };
966
967int
968ciss_ioctl(struct device *dev, u_long cmd, caddr_t addr)
969{
970 struct ciss_softc *sc = (struct ciss_softc *)dev;
971 struct bioc_inq *bi;
972 struct bioc_vol *bv;
973 struct bioc_disk *bd;
974 struct bioc_blink *bb;
975 /* struct bioc_alarm *ba; */
976 /* struct bioc_setstate *bss; */
977 struct ciss_ldid *ldid;
978 struct ciss_ldstat *ldstat;
979 struct ciss_pdid *pdid;
980 struct ciss_blink *blink;
981 struct ciss_ld *ldp;
982 ciss_lock_t lock;
983 u_int8_t drv;
984 int ld, pd, error = 0;
985 u_int blks;
986
987 if (!(sc->sc_flags & CISS_BIO0x0001))
988 return ENOTTY25;
989
990 lock = CISS_LOCK(sc)splraise(0x6);
991 switch (cmd) {
992 case BIOCINQ(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct bioc_inq) & 0x1fff) << 16) | ((('B')) <<
8) | ((32)))
:
993 bi = (struct bioc_inq *)addr;
994 strlcpy(bi->bi_dev, sc->sc_dev.dv_xname, sizeof(bi->bi_dev));
995 bi->bi_novol = sc->maxunits;
996 bi->bi_nodisk = sc->ndrives;
997 break;
998
999 case BIOCVOL(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct bioc_vol) & 0x1fff) << 16) | ((('B')) <<
8) | ((34)))
:
1000 bv = (struct bioc_vol *)addr;
1001 if (bv->bv_volid > sc->maxunits) {
1002 error = EINVAL22;
1003 break;
1004 }
1005 ldp = sc->sc_lds[bv->bv_volid];
1006 if (!ldp) {
1007 error = EINVAL22;
1008 break;
1009 }
1010 ldid = sc->scratch;
1011 if ((error = ciss_ldid(sc, bv->bv_volid, ldid)))
1012 break;
1013 /* params 30:88:ff:00:00:00:00:00:00:00:00:00:00:00:20:00 */
1014 bv->bv_status = BIOC_SVINVALID0xff;
1015 blks = (u_int)letoh16(ldid->nblocks[1])((__uint16_t)(ldid->nblocks[1])) << 16 |
1016 letoh16(ldid->nblocks[0])((__uint16_t)(ldid->nblocks[0]));
1017 bv->bv_size = blks * (uint64_t)letoh16(ldid->blksize)((__uint16_t)(ldid->blksize));
1018 bv->bv_level = ciss_level[ldid->type];
1019 bv->bv_nodisk = ldp->ndrives;
1020 strlcpy(bv->bv_dev, ldp->xname, sizeof(bv->bv_dev));
1021 strlcpy(bv->bv_vendor, "CISS", sizeof(bv->bv_vendor));
1022 ldstat = sc->scratch;
1023 bzero(ldstat, sizeof(*ldstat))__builtin_bzero((ldstat), (sizeof(*ldstat)));
1024 if ((error = ciss_ldstat(sc, bv->bv_volid, ldstat)))
1025 break;
1026 bv->bv_percent = -1;
1027 bv->bv_seconds = 0;
1028 if (ldstat->stat < nitems(ciss_stat)(sizeof((ciss_stat)) / sizeof((ciss_stat)[0])))
1029 bv->bv_status = ciss_stat[ldstat->stat];
1030 if (bv->bv_status == BIOC_SVREBUILD0x05 ||
1031 bv->bv_status == BIOC_SVBUILDING0x03)
1032 bv->bv_percent = (blks -
1033 (((u_int)ldstat->prog[3] << 24) |
1034 ((u_int)ldstat->prog[2] << 16) |
1035 ((u_int)ldstat->prog[1] << 8) |
1036 (u_int)ldstat->prog[0])) * 100ULL / blks;
1037 break;
1038
1039 case BIOCDISK(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct bioc_disk) & 0x1fff) << 16) | ((('B')) <<
8) | ((33)))
:
1040 bd = (struct bioc_disk *)addr;
1041 if (bd->bd_volid > sc->maxunits) {
1042 error = EINVAL22;
1043 break;
1044 }
1045 ldp = sc->sc_lds[bd->bd_volid];
1046 if (!ldp || (pd = bd->bd_diskid) > ldp->ndrives) {
1047 error = EINVAL22;
1048 break;
1049 }
1050 ldstat = sc->scratch;
1051 if ((error = ciss_ldstat(sc, bd->bd_volid, ldstat)))
1052 break;
1053 bd->bd_status = -1;
1054 if (ldstat->stat == CISS_LD_REBLD5 &&
1055 ldstat->bigrebuild == ldp->tgts[pd])
1056 bd->bd_status = BIOC_SDREBUILD0x03;
1057 if (ciss_bitset(ldp->tgts[pd] & (~CISS_BIGBIT),((ldstat->bigfailed)[(ldp->tgts[pd] & (~0x80)) >>
3] & (1 << ((ldp->tgts[pd] & (~0x80)) &
7)))
1058 ldstat->bigfailed)((ldstat->bigfailed)[(ldp->tgts[pd] & (~0x80)) >>
3] & (1 << ((ldp->tgts[pd] & (~0x80)) &
7)))
) {
1059 bd->bd_status = BIOC_SDFAILED0x02;
1060 bd->bd_size = 0;
1061 bd->bd_channel = (ldp->tgts[pd] & (~CISS_BIGBIT0x80)) /
1062 sc->ndrives;
1063 bd->bd_target = ldp->tgts[pd] % sc->ndrives;
1064 bd->bd_lun = 0;
1065 bd->bd_vendor[0] = '\0';
1066 bd->bd_serial[0] = '\0';
1067 bd->bd_procdev[0] = '\0';
1068 } else {
1069 pdid = sc->scratch;
1070 if ((error = ciss_pdid(sc, ldp->tgts[pd], pdid,
1071 SCSI_POLL0x00002)))
1072 break;
1073 if (bd->bd_status < 0) {
1074 if (pdid->config & CISS_PD_SPARE0x40)
1075 bd->bd_status = BIOC_SDHOTSPARE0x04;
1076 else if (pdid->present & CISS_PD_PRESENT0x01)
1077 bd->bd_status = BIOC_SDONLINE0x00;
1078 else
1079 bd->bd_status = BIOC_SDINVALID0xff;
1080 }
1081 bd->bd_size = (u_int64_t)letoh32(pdid->nblocks)((__uint32_t)(pdid->nblocks)) *
1082 letoh16(pdid->blksz)((__uint16_t)(pdid->blksz));
1083 bd->bd_channel = pdid->bus;
1084 bd->bd_target = pdid->target;
1085 bd->bd_lun = 0;
1086 strlcpy(bd->bd_vendor, pdid->model,
1087 sizeof(bd->bd_vendor));
1088 strlcpy(bd->bd_serial, pdid->serial,
1089 sizeof(bd->bd_serial));
1090 bd->bd_procdev[0] = '\0';
1091 }
1092 break;
1093
1094 case BIOCBLINK(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct bioc_blink) & 0x1fff) << 16) | ((('B')) <<
8) | ((36)))
:
1095 bb = (struct bioc_blink *)addr;
1096 blink = sc->scratch;
1097 error = EINVAL22;
1098 /* XXX workaround completely dumb scsi addressing */
1099 for (ld = 0; ld < sc->maxunits; ld++) {
1100 ldp = sc->sc_lds[ld];
1101 if (!ldp)
1102 continue;
1103 if (sc->ndrives == 256)
1104 drv = bb->bb_target;
1105 else
1106 drv = CISS_BIGBIT0x80 +
1107 bb->bb_channel * sc->ndrives +
1108 bb->bb_target;
1109 for (pd = 0; pd < ldp->ndrives; pd++)
1110 if (ldp->tgts[pd] == drv)
1111 error = ciss_blink(sc, ld, pd,
1112 bb->bb_status, blink);
1113 }
1114 break;
1115
1116 case BIOCALARM(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct bioc_alarm) & 0x1fff) << 16) | ((('B')) <<
8) | ((35)))
:
1117 case BIOCSETSTATE(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct bioc_setstate) & 0x1fff) << 16) | ((('B')) <<
8) | ((37)))
:
1118 default:
1119 CISS_DPRINTF(CISS_D_IOCTL, ("%s: invalid ioctl\n",
1120 sc->sc_dev.dv_xname));
1121 error = ENOTTY25;
1122 }
1123 CISS_UNLOCK(sc, lock)spllower(lock);
1124
1125 return error;
1126}
1127
1128#ifndef SMALL_KERNEL
1129void
1130ciss_sensors(void *v)
1131{
1132 struct ciss_softc *sc = v;
1133 struct ciss_ldstat *ldstat;
1134 int i, error;
1135
1136 for (i = 0; i < sc->maxunits; i++) {
1137 ldstat = sc->scratch;
1138 if ((error = ciss_ldstat(sc, i, ldstat))) {
1139 sc->sensors[i].value = 0;
1140 sc->sensors[i].status = SENSOR_S_UNKNOWN;
1141 continue;
1142 }
1143
1144 switch (ldstat->stat) {
1145 case CISS_LD_OK0:
1146 sc->sensors[i].value = SENSOR_DRIVE_ONLINE4;
1147 sc->sensors[i].status = SENSOR_S_OK;
1148 break;
1149
1150 case CISS_LD_DEGRAD3:
1151 sc->sensors[i].value = SENSOR_DRIVE_PFAIL10;
1152 sc->sensors[i].status = SENSOR_S_WARN;
1153 break;
1154
1155 case CISS_LD_EXPND10:
1156 case CISS_LD_QEXPND12:
1157 case CISS_LD_RBLDRD4:
1158 case CISS_LD_REBLD5:
1159 sc->sensors[i].value = SENSOR_DRIVE_REBUILD7;
1160 sc->sensors[i].status = SENSOR_S_WARN;
1161 break;
1162
1163 case CISS_LD_NORDY11:
1164 case CISS_LD_PDINV6:
1165 case CISS_LD_PDUNC7:
1166 case CISS_LD_FAILED1:
1167 case CISS_LD_UNCONF2:
1168 sc->sensors[i].value = SENSOR_DRIVE_FAIL9;
1169 sc->sensors[i].status = SENSOR_S_CRIT;
1170 break;
1171
1172 default:
1173 sc->sensors[i].value = 0;
1174 sc->sensors[i].status = SENSOR_S_UNKNOWN;
1175 }
1176 }
1177}
1178#endif /* SMALL_KERNEL */
1179
1180int
1181ciss_ldid(struct ciss_softc *sc, int target, struct ciss_ldid *id)
1182{
1183 struct ciss_ccb *ccb;
1184 struct ciss_cmd *cmd;
1185 int rv;
1186 int s;
1187
1188 ccb = scsi_io_get(&sc->sc_iopool, SCSI_POLL0x00002);
1189 if (ccb == NULL((void *)0))
1190 return ENOMEM12;
1191
1192 ccb->ccb_len = sizeof(*id);
1193 ccb->ccb_data = id;
1194 cmd = &ccb->ccb_cmd;
1195 cmd->tgt = htole32(CISS_CMD_MODE_PERIPH)((__uint32_t)(0x00000000));
1196 cmd->tgt2 = 0;
1197 cmd->cdblen = 10;
1198 cmd->flags = CISS_CDB_CMD0x00 | CISS_CDB_SIMPL0x20 | CISS_CDB_IN0x80;
1199 cmd->tmo = htole16(0)((__uint16_t)(0));
1200 bzero(&cmd->cdb[0], sizeof(cmd->cdb))__builtin_bzero((&cmd->cdb[0]), (sizeof(cmd->cdb)));
1201 cmd->cdb[0] = CISS_CMD_CTRL_GET0x26;
1202 cmd->cdb[5] = target;
1203 cmd->cdb[6] = CISS_CMS_CTRL_LDIDEXT0x18;
1204 cmd->cdb[7] = sizeof(*id) >> 8; /* biiiig endian */
1205 cmd->cdb[8] = sizeof(*id) & 0xff;
1206
1207 s = splbio()splraise(0x6);
1208 rv = ciss_cmd(ccb, BUS_DMA_NOWAIT0x0001, SCSI_POLL0x00002);
1209 splx(s)spllower(s);
1210
1211 scsi_io_put(&sc->sc_iopool, ccb);
1212
1213 return (rv);
1214}
1215
1216int
1217ciss_ldstat(struct ciss_softc *sc, int target, struct ciss_ldstat *stat)
1218{
1219 struct ciss_ccb *ccb;
1220 struct ciss_cmd *cmd;
1221 int rv;
1222 int s;
1223
1224 ccb = scsi_io_get(&sc->sc_iopool, SCSI_POLL0x00002);
1225 if (ccb == NULL((void *)0))
1226 return ENOMEM12;
1227
1228 ccb->ccb_len = sizeof(*stat);
1229 ccb->ccb_data = stat;
1230 cmd = &ccb->ccb_cmd;
1231 cmd->tgt = htole32(CISS_CMD_MODE_PERIPH)((__uint32_t)(0x00000000));
1232 cmd->tgt2 = 0;
1233 cmd->cdblen = 10;
1234 cmd->flags = CISS_CDB_CMD0x00 | CISS_CDB_SIMPL0x20 | CISS_CDB_IN0x80;
1235 cmd->tmo = htole16(0)((__uint16_t)(0));
1236 bzero(&cmd->cdb[0], sizeof(cmd->cdb))__builtin_bzero((&cmd->cdb[0]), (sizeof(cmd->cdb)));
1237 cmd->cdb[0] = CISS_CMD_CTRL_GET0x26;
1238 cmd->cdb[5] = target;
1239 cmd->cdb[6] = CISS_CMS_CTRL_LDSTAT0x12;
1240 cmd->cdb[7] = sizeof(*stat) >> 8; /* biiiig endian */
1241 cmd->cdb[8] = sizeof(*stat) & 0xff;
1242
1243 s = splbio()splraise(0x6);
1244 rv = ciss_cmd(ccb, BUS_DMA_NOWAIT0x0001, SCSI_POLL0x00002);
1245 splx(s)spllower(s);
1246
1247 scsi_io_put(&sc->sc_iopool, ccb);
1248
1249 return (rv);
1250}
1251
1252int
1253ciss_pdid(struct ciss_softc *sc, u_int8_t drv, struct ciss_pdid *id, int wait)
1254{
1255 struct ciss_ccb *ccb;
1256 struct ciss_cmd *cmd;
1257 int rv;
1258 int s;
1259
1260 ccb = scsi_io_get(&sc->sc_iopool, SCSI_POLL0x00002);
1261 if (ccb == NULL((void *)0))
1262 return ENOMEM12;
1263
1264 ccb->ccb_len = sizeof(*id);
1265 ccb->ccb_data = id;
1266 cmd = &ccb->ccb_cmd;
1267 cmd->tgt = htole32(CISS_CMD_MODE_PERIPH)((__uint32_t)(0x00000000));
1268 cmd->tgt2 = 0;
1269 cmd->cdblen = 10;
1270 cmd->flags = CISS_CDB_CMD0x00 | CISS_CDB_SIMPL0x20 | CISS_CDB_IN0x80;
1271 cmd->tmo = htole16(0)((__uint16_t)(0));
1272 bzero(&cmd->cdb[0], sizeof(cmd->cdb))__builtin_bzero((&cmd->cdb[0]), (sizeof(cmd->cdb)));
1273 cmd->cdb[0] = CISS_CMD_CTRL_GET0x26;
1274 cmd->cdb[2] = drv;
1275 cmd->cdb[6] = CISS_CMS_CTRL_PDID0x15;
1276 cmd->cdb[7] = sizeof(*id) >> 8; /* biiiig endian */
1277 cmd->cdb[8] = sizeof(*id) & 0xff;
1278
1279 s = splbio()splraise(0x6);
1280 rv = ciss_cmd(ccb, BUS_DMA_NOWAIT0x0001, wait);
1281 splx(s)spllower(s);
1282
1283 scsi_io_put(&sc->sc_iopool, ccb);
1284
1285 return (rv);
1286}
1287
1288
1289struct ciss_ld *
1290ciss_pdscan(struct ciss_softc *sc, int ld)
1291{
1292 struct ciss_pdid *pdid;
1293 struct ciss_ld *ldp;
1294 u_int8_t drv, buf[128];
1295 int i, j, k = 0;
1296
1297 pdid = sc->scratch;
1298 if (sc->ndrives == 256) {
1299 for (i = 0; i < CISS_BIGBIT0x80; i++)
1300 if (!ciss_pdid(sc, i, pdid, SCSI_NOSLEEP0x00001|SCSI_POLL0x00002) &&
1301 (pdid->present & CISS_PD_PRESENT0x01))
1302 buf[k++] = i;
1303 } else
1304 for (i = 0; i < sc->nbus; i++)
1305 for (j = 0; j < sc->ndrives; j++) {
1306 drv = CISS_BIGBIT0x80 + i * sc->ndrives + j;
1307 if (!ciss_pdid(sc, drv, pdid,
1308 SCSI_NOSLEEP0x00001|SCSI_POLL0x00002))
1309 buf[k++] = drv;
1310 }
1311
1312 if (!k)
1313 return NULL((void *)0);
1314
1315 ldp = malloc(sizeof(*ldp) + (k-1), M_DEVBUF2, M_NOWAIT0x0002);
1316 if (!ldp)
1317 return NULL((void *)0);
1318
1319 bzero(&ldp->bling, sizeof(ldp->bling))__builtin_bzero((&ldp->bling), (sizeof(ldp->bling))
)
;
1320 ldp->ndrives = k;
1321 bcopy(buf, ldp->tgts, k);
1322 return ldp;
1323}
1324
1325int
1326ciss_blink(struct ciss_softc *sc, int ld, int pd, int stat,
1327 struct ciss_blink *blink)
1328{
1329 struct ciss_ccb *ccb;
1330 struct ciss_cmd *cmd;
1331 struct ciss_ld *ldp;
1332 int rv;
1333 int s;
1334
1335 if (ld > sc->maxunits)
1336 return EINVAL22;
1337
1338 ldp = sc->sc_lds[ld];
1339 if (!ldp || pd > ldp->ndrives)
1340 return EINVAL22;
1341
1342 ldp->bling.pdtab[ldp->tgts[pd]] = stat == BIOC_SBUNBLINK0x00? 0 :
1343 CISS_BLINK_ALL1;
1344 bcopy(&ldp->bling, blink, sizeof(*blink));
1345
1346 ccb = scsi_io_get(&sc->sc_iopool, SCSI_POLL0x00002);
1347 if (ccb == NULL((void *)0))
1348 return ENOMEM12;
1349
1350 ccb->ccb_len = sizeof(*blink);
1351 ccb->ccb_data = blink;
1352 cmd = &ccb->ccb_cmd;
1353 cmd->tgt = htole32(CISS_CMD_MODE_PERIPH)((__uint32_t)(0x00000000));
1354 cmd->tgt2 = 0;
1355 cmd->cdblen = 10;
1356 cmd->flags = CISS_CDB_CMD0x00 | CISS_CDB_SIMPL0x20 | CISS_CDB_OUT0x40;
1357 cmd->tmo = htole16(0)((__uint16_t)(0));
1358 bzero(&cmd->cdb[0], sizeof(cmd->cdb))__builtin_bzero((&cmd->cdb[0]), (sizeof(cmd->cdb)));
1359 cmd->cdb[0] = CISS_CMD_CTRL_SET0x27;
1360 cmd->cdb[6] = CISS_CMS_CTRL_PDBLINK0x16;
1361 cmd->cdb[7] = sizeof(*blink) >> 8; /* biiiig endian */
1362 cmd->cdb[8] = sizeof(*blink) & 0xff;
1363
1364 s = splbio()splraise(0x6);
1365 rv = ciss_cmd(ccb, BUS_DMA_NOWAIT0x0001, SCSI_POLL0x00002);
1366 splx(s)spllower(s);
1367
1368 scsi_io_put(&sc->sc_iopool, ccb);
1369
1370 return (rv);
1371}
1372#endif