Bug Summary

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

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)))) {
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))) {
Although the value stored to 'error' is used in the enclosing expression, the value is never actually read from 'error'
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