Bug Summary

File:dev/sdmmc/sdmmc_scsi.c
Warning:line 604, column 3
Value stored to 'scsi_sc' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name sdmmc_scsi.c -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 -ffp-contract=on -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 -target-feature +retpoline-external-thunk -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/llvm16/lib/clang/16 -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/legacy-dpm -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc -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/swsmu/smu13 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/inc -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/pm/swsmu/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc/pmfw_if -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 SUSPEND -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 -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 -fcf-protection=branch -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 /home/ben/Projects/scan/2024-01-11-110808-61670-1 -x c /usr/src/sys/dev/sdmmc/sdmmc_scsi.c
1/* $OpenBSD: sdmmc_scsi.c,v 1.63 2023/04/19 01:46:10 dlg Exp $ */
2
3/*
4 * Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19/* A SCSI adapter emulation to access SD/MMC memory cards */
20
21#include <sys/param.h>
22#include <sys/buf.h>
23#include <sys/device.h>
24#include <sys/malloc.h>
25#include <sys/proc.h>
26#include <sys/systm.h>
27
28#include <scsi/scsi_all.h>
29#include <scsi/scsi_disk.h>
30#include <scsi/scsiconf.h>
31
32#include <dev/sdmmc/sdmmc_scsi.h>
33#include <dev/sdmmc/sdmmcvar.h>
34
35#ifdef HIBERNATE1
36#include <sys/hibernate.h>
37#include <sys/disk.h>
38#include <sys/disklabel.h>
39#include <sys/rwlock.h>
40#endif
41
42#define SDMMC_SCSIID_HOST0x00 0x00
43#define SDMMC_SCSIID_MAX0x0f 0x0f
44
45#define SDMMC_SCSI_MAXCMDS8 8
46
47struct sdmmc_scsi_target {
48 struct sdmmc_function *card;
49};
50
51struct sdmmc_ccb {
52 struct sdmmc_scsi_softc *ccb_scbus;
53 struct scsi_xfer *ccb_xs;
54 int ccb_flags;
55#define SDMMC_CCB_F_ERR0x0001 0x0001
56 u_int32_t ccb_blockno;
57 u_int32_t ccb_blockcnt;
58 volatile enum {
59 SDMMC_CCB_FREE,
60 SDMMC_CCB_READY,
61 SDMMC_CCB_QUEUED
62 } ccb_state;
63 struct sdmmc_command ccb_cmd;
64 struct sdmmc_task ccb_task;
65 TAILQ_ENTRY(sdmmc_ccb)struct { struct sdmmc_ccb *tqe_next; struct sdmmc_ccb **tqe_prev
; }
ccb_link;
66};
67
68TAILQ_HEAD(sdmmc_ccb_list, sdmmc_ccb)struct sdmmc_ccb_list { struct sdmmc_ccb *tqh_first; struct sdmmc_ccb
**tqh_last; }
;
69
70struct sdmmc_scsi_softc {
71 struct device *sc_child;
72 struct sdmmc_scsi_target *sc_tgt;
73 int sc_ntargets;
74 struct sdmmc_ccb *sc_ccbs; /* allocated ccbs */
75 int sc_nccbs;
76 struct sdmmc_ccb_list sc_ccb_freeq; /* free ccbs */
77 struct sdmmc_ccb_list sc_ccb_runq; /* queued ccbs */
78 struct mutex sc_ccb_mtx;
79 struct scsi_iopool sc_iopool;
80};
81
82int sdmmc_alloc_ccbs(struct sdmmc_scsi_softc *, int);
83void sdmmc_free_ccbs(struct sdmmc_scsi_softc *);
84void *sdmmc_ccb_alloc(void *);
85void sdmmc_ccb_free(void *, void *);
86
87void sdmmc_scsi_cmd(struct scsi_xfer *);
88void sdmmc_inquiry(struct scsi_xfer *);
89void sdmmc_start_xs(struct sdmmc_softc *, struct sdmmc_ccb *);
90void sdmmc_complete_xs(void *);
91void sdmmc_done_xs(struct sdmmc_ccb *);
92void sdmmc_stimeout(void *);
93void sdmmc_minphys(struct buf *, struct scsi_link *);
94
95const struct scsi_adapter sdmmc_switch = {
96 sdmmc_scsi_cmd, sdmmc_minphys, NULL((void *)0), NULL((void *)0), NULL((void *)0)
97};
98
99#ifdef SDMMC_DEBUG
100#define DPRINTF(s) printf s
101#else
102#define DPRINTF(s) /**/
103#endif
104
105void
106sdmmc_scsi_attach(struct sdmmc_softc *sc)
107{
108 struct sdmmc_attach_args saa;
109 struct sdmmc_scsi_softc *scbus;
110 struct sdmmc_function *sf;
111
112 rw_assert_wrlock(&sc->sc_lock);
113
114 scbus = malloc(sizeof *scbus, M_DEVBUF2, M_WAITOK0x0001 | M_ZERO0x0008);
115
116 scbus->sc_tgt = mallocarray(sizeof(*scbus->sc_tgt),
117 (SDMMC_SCSIID_MAX0x0f+1), M_DEVBUF2, M_WAITOK0x0001 | M_ZERO0x0008);
118
119 /*
120 * Each card that sent us a CID in the identification stage
121 * gets a SCSI ID > 0, whether it is a memory card or not.
122 */
123 scbus->sc_ntargets = 1;
124 SIMPLEQ_FOREACH(sf, &sc->sf_head, sf_list)for((sf) = ((&sc->sf_head)->sqh_first); (sf) != ((void
*)0); (sf) = ((sf)->sf_list.sqe_next))
{
125 if (scbus->sc_ntargets >= SDMMC_SCSIID_MAX0x0f+1)
126 break;
127 scbus->sc_tgt[scbus->sc_ntargets].card = sf;
128 scbus->sc_ntargets++;
129 }
130
131 /* Preallocate some CCBs and initialize the CCB lists. */
132 if (sdmmc_alloc_ccbs(scbus, SDMMC_SCSI_MAXCMDS8) != 0) {
133 printf("%s: can't allocate ccbs\n", sc->sc_dev.dv_xname);
134 goto free_sctgt;
135 }
136
137 sc->sc_scsibus = scbus;
138
139 saa.sf = NULL((void *)0);
140 saa.saa.saa_adapter_target = SDMMC_SCSIID_HOST0x00;
141 saa.saa.saa_adapter_buswidth = scbus->sc_ntargets;
142 saa.saa.saa_adapter_softc = sc;
143 saa.saa.saa_luns = 1;
144 saa.saa.saa_adapter = &sdmmc_switch;
145 saa.saa.saa_openings = 1;
146 saa.saa.saa_pool = &scbus->sc_iopool;
147 saa.saa.saa_quirks = saa.saa.saa_flags = 0;
148 saa.saa.saa_wwpn = saa.saa.saa_wwnn = 0;
149
150 scbus->sc_child = config_found(&sc->sc_dev, &saa, scsiprint)config_found_sm((&sc->sc_dev), (&saa), (scsiprint)
, ((void *)0))
;
151 if (scbus->sc_child == NULL((void *)0)) {
152 printf("%s: can't attach scsibus\n", sc->sc_dev.dv_xname);
153 goto free_ccbs;
154 }
155 return;
156
157 free_ccbs:
158 sc->sc_scsibus = NULL((void *)0);
159 sdmmc_free_ccbs(scbus);
160 free_sctgt:
161 free(scbus->sc_tgt, M_DEVBUF2,
162 sizeof(*scbus->sc_tgt) * (SDMMC_SCSIID_MAX0x0f+1));
163 free(scbus, M_DEVBUF2, sizeof *scbus);
164}
165
166void
167sdmmc_scsi_detach(struct sdmmc_softc *sc)
168{
169 struct sdmmc_scsi_softc *scbus;
170 struct sdmmc_ccb *ccb;
171 int s;
172
173 rw_assert_wrlock(&sc->sc_lock);
174
175 scbus = sc->sc_scsibus;
176 if (scbus == NULL((void *)0))
177 return;
178
179 /* Complete all open scsi xfers. */
180 s = splbio()splraise(0x3);
181 for (ccb = TAILQ_FIRST(&scbus->sc_ccb_runq)((&scbus->sc_ccb_runq)->tqh_first); ccb != NULL((void *)0);
182 ccb = TAILQ_FIRST(&scbus->sc_ccb_runq)((&scbus->sc_ccb_runq)->tqh_first))
183 sdmmc_stimeout(ccb);
184 splx(s)spllower(s);
185
186 if (scbus->sc_child != NULL((void *)0))
187 config_detach(scbus->sc_child, DETACH_FORCE0x01);
188
189 if (scbus->sc_tgt != NULL((void *)0))
190 free(scbus->sc_tgt, M_DEVBUF2,
191 sizeof(*scbus->sc_tgt) * (SDMMC_SCSIID_MAX0x0f+1));
192
193 sdmmc_free_ccbs(scbus);
194 free(scbus, M_DEVBUF2, sizeof *scbus);
195 sc->sc_scsibus = NULL((void *)0);
196}
197
198/*
199 * CCB management
200 */
201
202int
203sdmmc_alloc_ccbs(struct sdmmc_scsi_softc *scbus, int nccbs)
204{
205 struct sdmmc_ccb *ccb;
206 int i;
207
208 scbus->sc_ccbs = mallocarray(nccbs, sizeof(struct sdmmc_ccb),
209 M_DEVBUF2, M_NOWAIT0x0002);
210 if (scbus->sc_ccbs == NULL((void *)0))
211 return 1;
212 scbus->sc_nccbs = nccbs;
213
214 TAILQ_INIT(&scbus->sc_ccb_freeq)do { (&scbus->sc_ccb_freeq)->tqh_first = ((void *)0
); (&scbus->sc_ccb_freeq)->tqh_last = &(&scbus
->sc_ccb_freeq)->tqh_first; } while (0)
;
215 TAILQ_INIT(&scbus->sc_ccb_runq)do { (&scbus->sc_ccb_runq)->tqh_first = ((void *)0)
; (&scbus->sc_ccb_runq)->tqh_last = &(&scbus
->sc_ccb_runq)->tqh_first; } while (0)
;
216 mtx_init(&scbus->sc_ccb_mtx, IPL_BIO)do { (void)(((void *)0)); (void)(0); __mtx_init((&scbus->
sc_ccb_mtx), ((((0x3)) > 0x0 && ((0x3)) < 0x9) ?
0x9 : ((0x3)))); } while (0)
;
217 scsi_iopool_init(&scbus->sc_iopool, scbus, sdmmc_ccb_alloc,
218 sdmmc_ccb_free);
219
220 for (i = 0; i < nccbs; i++) {
221 ccb = &scbus->sc_ccbs[i];
222 ccb->ccb_scbus = scbus;
223 ccb->ccb_state = SDMMC_CCB_FREE;
224 ccb->ccb_flags = 0;
225 ccb->ccb_xs = NULL((void *)0);
226
227 TAILQ_INSERT_TAIL(&scbus->sc_ccb_freeq, ccb, ccb_link)do { (ccb)->ccb_link.tqe_next = ((void *)0); (ccb)->ccb_link
.tqe_prev = (&scbus->sc_ccb_freeq)->tqh_last; *(&
scbus->sc_ccb_freeq)->tqh_last = (ccb); (&scbus->
sc_ccb_freeq)->tqh_last = &(ccb)->ccb_link.tqe_next
; } while (0)
;
228 }
229 return 0;
230}
231
232void
233sdmmc_free_ccbs(struct sdmmc_scsi_softc *scbus)
234{
235 if (scbus->sc_ccbs != NULL((void *)0)) {
236 free(scbus->sc_ccbs, M_DEVBUF2,
237 scbus->sc_nccbs * sizeof(struct sdmmc_ccb));
238 scbus->sc_ccbs = NULL((void *)0);
239 }
240}
241
242void *
243sdmmc_ccb_alloc(void *xscbus)
244{
245 struct sdmmc_scsi_softc *scbus = xscbus;
246 struct sdmmc_ccb *ccb;
247
248 mtx_enter(&scbus->sc_ccb_mtx);
249 ccb = TAILQ_FIRST(&scbus->sc_ccb_freeq)((&scbus->sc_ccb_freeq)->tqh_first);
250 if (ccb != NULL((void *)0)) {
251 TAILQ_REMOVE(&scbus->sc_ccb_freeq, ccb, ccb_link)do { if (((ccb)->ccb_link.tqe_next) != ((void *)0)) (ccb)->
ccb_link.tqe_next->ccb_link.tqe_prev = (ccb)->ccb_link.
tqe_prev; else (&scbus->sc_ccb_freeq)->tqh_last = (
ccb)->ccb_link.tqe_prev; *(ccb)->ccb_link.tqe_prev = (ccb
)->ccb_link.tqe_next; ((ccb)->ccb_link.tqe_prev) = ((void
*)-1); ((ccb)->ccb_link.tqe_next) = ((void *)-1); } while
(0)
;
252 ccb->ccb_state = SDMMC_CCB_READY;
253 }
254 mtx_leave(&scbus->sc_ccb_mtx);
255
256 return ccb;
257}
258
259void
260sdmmc_ccb_free(void *xscbus, void *xccb)
261{
262 struct sdmmc_scsi_softc *scbus = xscbus;
263 struct sdmmc_ccb *ccb = xccb;
264 int s;
265
266 s = splbio()splraise(0x3);
267 if (ccb->ccb_state == SDMMC_CCB_QUEUED)
268 TAILQ_REMOVE(&scbus->sc_ccb_runq, ccb, ccb_link)do { if (((ccb)->ccb_link.tqe_next) != ((void *)0)) (ccb)->
ccb_link.tqe_next->ccb_link.tqe_prev = (ccb)->ccb_link.
tqe_prev; else (&scbus->sc_ccb_runq)->tqh_last = (ccb
)->ccb_link.tqe_prev; *(ccb)->ccb_link.tqe_prev = (ccb)
->ccb_link.tqe_next; ((ccb)->ccb_link.tqe_prev) = ((void
*)-1); ((ccb)->ccb_link.tqe_next) = ((void *)-1); } while
(0)
;
269 splx(s)spllower(s);
270
271 ccb->ccb_state = SDMMC_CCB_FREE;
272 ccb->ccb_flags = 0;
273 ccb->ccb_xs = NULL((void *)0);
274
275 mtx_enter(&scbus->sc_ccb_mtx);
276 TAILQ_INSERT_TAIL(&scbus->sc_ccb_freeq, ccb, ccb_link)do { (ccb)->ccb_link.tqe_next = ((void *)0); (ccb)->ccb_link
.tqe_prev = (&scbus->sc_ccb_freeq)->tqh_last; *(&
scbus->sc_ccb_freeq)->tqh_last = (ccb); (&scbus->
sc_ccb_freeq)->tqh_last = &(ccb)->ccb_link.tqe_next
; } while (0)
;
277 mtx_leave(&scbus->sc_ccb_mtx);
278}
279
280/*
281 * SCSI command emulation
282 */
283
284/* XXX move to some sort of "scsi emulation layer". */
285static void
286sdmmc_scsi_decode_rw(struct scsi_xfer *xs, u_int32_t *blocknop,
287 u_int32_t *blockcntp)
288{
289 struct scsi_rw *rw;
290 struct scsi_rw_10 *rw10;
291
292 if (xs->cmdlen == 6) {
293 rw = (struct scsi_rw *)&xs->cmd;
294 *blocknop = _3btol(rw->addr) & (SRW_TOPADDR0x1F << 16 | 0xffff);
295 *blockcntp = rw->length ? rw->length : 0x100;
296 } else {
297 rw10 = (struct scsi_rw_10 *)&xs->cmd;
298 *blocknop = _4btol(rw10->addr);
299 *blockcntp = _2btol(rw10->length);
300 }
301}
302
303void
304sdmmc_scsi_cmd(struct scsi_xfer *xs)
305{
306 struct scsi_link *link = xs->sc_link;
307 struct sdmmc_softc *sc = link->bus->sb_adapter_softc;
308 struct sdmmc_scsi_softc *scbus = sc->sc_scsibus;
309 struct sdmmc_scsi_target *tgt = &scbus->sc_tgt[link->target];
310 struct scsi_read_cap_data rcd;
311 u_int32_t blockno;
312 u_int32_t blockcnt;
313 struct sdmmc_ccb *ccb;
314
315 if (link->target >= scbus->sc_ntargets || tgt->card == NULL((void *)0) ||
316 link->lun != 0) {
317 DPRINTF(("%s: sdmmc_scsi_cmd: no target %d\n",
318 DEVNAME(sc), link->target));
319 /* XXX should be XS_SENSE and sense filled out */
320 xs->error = XS_DRIVER_STUFFUP2;
321 scsi_done(xs);
322 return;
323 }
324
325 DPRINTF(("%s: scsi cmd target=%d opcode=%#x proc=\"%s\" (poll=%#x)\n",
326 DEVNAME(sc), link->target, xs->cmd.opcode, curproc ?
327 curproc->p_p->ps_comm : "", xs->flags & SCSI_POLL));
328
329 xs->error = XS_NOERROR0;
330
331 switch (xs->cmd.opcode) {
332 case READ_COMMAND0x08:
333 case READ_100x28:
334 case WRITE_COMMAND0x0a:
335 case WRITE_100x2a:
336 /* Deal with I/O outside the switch. */
337 break;
338
339 case INQUIRY0x12:
340 sdmmc_inquiry(xs);
341 return;
342
343 case TEST_UNIT_READY0x00:
344 case START_STOP0x1b:
345 case SYNCHRONIZE_CACHE0x35:
346 scsi_done(xs);
347 return;
348
349 case READ_CAPACITY0x25:
350 bzero(&rcd, sizeof rcd)__builtin_bzero((&rcd), (sizeof rcd));
351 _lto4b(tgt->card->csd.capacity - 1, rcd.addr);
352 _lto4b(tgt->card->csd.sector_size, rcd.length);
353 bcopy(&rcd, xs->data, MIN(xs->datalen, sizeof rcd)(((xs->datalen)<(sizeof rcd))?(xs->datalen):(sizeof rcd
))
);
354 scsi_done(xs);
355 return;
356
357 default:
358 DPRINTF(("%s: unsupported scsi command %#x\n",
359 DEVNAME(sc), xs->cmd.opcode));
360 xs->error = XS_DRIVER_STUFFUP2;
361 scsi_done(xs);
362 return;
363 }
364
365 /* A read or write operation. */
366 sdmmc_scsi_decode_rw(xs, &blockno, &blockcnt);
367
368 if (blockno >= tgt->card->csd.capacity ||
369 blockno + blockcnt > tgt->card->csd.capacity) {
370 DPRINTF(("%s: out of bounds %u-%u >= %u\n", DEVNAME(sc),
371 blockno, blockcnt, tgt->card->csd.capacity));
372 xs->error = XS_DRIVER_STUFFUP2;
373 scsi_done(xs);
374 return;
375 }
376
377 ccb = xs->io;
378
379 ccb->ccb_xs = xs;
380 ccb->ccb_blockcnt = blockcnt;
381 ccb->ccb_blockno = blockno;
382
383 sdmmc_start_xs(sc, ccb);
384}
385
386void
387sdmmc_inquiry(struct scsi_xfer *xs)
388{
389 struct scsi_link *link = xs->sc_link;
390 struct sdmmc_softc *sc = link->bus->sb_adapter_softc;
391 struct sdmmc_scsi_softc *scbus = sc->sc_scsibus;
392 struct sdmmc_scsi_target *tgt = &scbus->sc_tgt[link->target];
393 struct scsi_inquiry_data inq;
394 struct scsi_inquiry *cdb = (struct scsi_inquiry *)&xs->cmd;
395 char vendor[sizeof(inq.vendor) + 1];
396 char product[sizeof(inq.product) + 1];
397 char revision[sizeof(inq.revision) + 1];
398
399 if (xs->cmdlen != sizeof(*cdb)) {
400 xs->error = XS_DRIVER_STUFFUP2;
401 goto done;
402 }
403
404 if (ISSET(cdb->flags, SI_EVPD)((cdb->flags) & (0x01))) {
405 xs->error = XS_DRIVER_STUFFUP2;
406 goto done;
407 }
408
409 memset(vendor, 0, sizeof(vendor))__builtin_memset((vendor), (0), (sizeof(vendor)));
410 memset(product, 0, sizeof(product))__builtin_memset((product), (0), (sizeof(product)));
411 memset(revision, 0, sizeof(revision))__builtin_memset((revision), (0), (sizeof(revision)));
412 switch (tgt->card->cid.mid) {
413 case 0x02:
414 case 0x03:
415 case 0x45:
416 strlcpy(vendor, "Sandisk", sizeof(vendor));
417 break;
418 case 0x11:
419 strlcpy(vendor, "Toshiba", sizeof(vendor));
420 break;
421 case 0x13:
422 strlcpy(vendor, "Micron", sizeof(vendor));
423 break;
424 case 0x15:
425 strlcpy(vendor, "Samsung", sizeof(vendor));
426 break;
427 case 0x27:
428 strlcpy(vendor, "Apacer", sizeof(vendor));
429 break;
430 case 0x70:
431 strlcpy(vendor, "Kingston", sizeof(vendor));
432 break;
433 case 0x90:
434 strlcpy(vendor, "Hynix", sizeof(vendor));
435 break;
436 default:
437 strlcpy(vendor, "SD/MMC", sizeof(vendor));
438 break;
439 }
440 strlcpy(product, tgt->card->cid.pnm, sizeof(product));
441 snprintf(revision, sizeof(revision), "%04X", tgt->card->cid.rev);
442
443 memset(&inq, 0, sizeof inq)__builtin_memset((&inq), (0), (sizeof inq));
444 inq.device = T_DIRECT0x00;
445 if (!ISSET(sc->sc_caps, SMC_CAPS_NONREMOVABLE)((sc->sc_caps) & (0x10000)))
446 inq.dev_qual2 = SID_REMOVABLE0x80;
447 inq.version = SCSI_REV_20x02;
448 inq.response_format = SID_SCSI2_RESPONSE0x02;
449 inq.additional_length = SID_SCSI2_ALEN31;
450 memcpy(inq.vendor, vendor, sizeof(inq.vendor))__builtin_memcpy((inq.vendor), (vendor), (sizeof(inq.vendor))
)
;
451 memcpy(inq.product, product, sizeof(inq.product))__builtin_memcpy((inq.product), (product), (sizeof(inq.product
)))
;
452 memcpy(inq.revision, revision, sizeof(inq.revision))__builtin_memcpy((inq.revision), (revision), (sizeof(inq.revision
)))
;
453
454 scsi_copy_internal_data(xs, &inq, sizeof(inq));
455
456done:
457 scsi_done(xs);
458}
459
460void
461sdmmc_start_xs(struct sdmmc_softc *sc, struct sdmmc_ccb *ccb)
462{
463 struct sdmmc_scsi_softc *scbus = sc->sc_scsibus;
464 struct scsi_xfer *xs = ccb->ccb_xs;
465 int s;
466
467 timeout_set(&xs->stimeout, sdmmc_stimeout, ccb);
468 sdmmc_init_task(&ccb->ccb_task, sdmmc_complete_xs, ccb)do { (&ccb->ccb_task)->func = (sdmmc_complete_xs); (
&ccb->ccb_task)->arg = (ccb); (&ccb->ccb_task
)->onqueue = 0; (&ccb->ccb_task)->sc = ((void *)
0); } while (0)
;
469
470 s = splbio()splraise(0x3);
471 TAILQ_INSERT_TAIL(&scbus->sc_ccb_runq, ccb, ccb_link)do { (ccb)->ccb_link.tqe_next = ((void *)0); (ccb)->ccb_link
.tqe_prev = (&scbus->sc_ccb_runq)->tqh_last; *(&
scbus->sc_ccb_runq)->tqh_last = (ccb); (&scbus->
sc_ccb_runq)->tqh_last = &(ccb)->ccb_link.tqe_next;
} while (0)
;
472 ccb->ccb_state = SDMMC_CCB_QUEUED;
473 splx(s)spllower(s);
474
475 if (ISSET(xs->flags, SCSI_POLL)((xs->flags) & (0x00002))) {
476 sdmmc_complete_xs(ccb);
477 return;
478 }
479
480 timeout_add_msec(&xs->stimeout, xs->timeout);
481 sdmmc_add_task(sc, &ccb->ccb_task);
482}
483
484void
485sdmmc_complete_xs(void *arg)
486{
487 struct sdmmc_ccb *ccb = arg;
488 struct scsi_xfer *xs = ccb->ccb_xs;
489 struct scsi_link *link = xs->sc_link;
490 struct sdmmc_softc *sc = link->bus->sb_adapter_softc;
491 struct sdmmc_scsi_softc *scbus = sc->sc_scsibus;
492 struct sdmmc_scsi_target *tgt = &scbus->sc_tgt[link->target];
493 int error;
494 int s;
495
496 DPRINTF(("%s: scsi cmd target=%d opcode=%#x proc=\"%s\" (poll=%#x)"
497 " complete\n", DEVNAME(sc), link->target, xs->cmd.opcode,
498 curproc ? curproc->p_p->ps_comm : "", xs->flags & SCSI_POLL));
499
500 s = splbio()splraise(0x3);
501
502 if (ISSET(xs->flags, SCSI_DATA_IN)((xs->flags) & (0x00800)))
503 error = sdmmc_mem_read_block(tgt->card, ccb->ccb_blockno,
504 xs->data, ccb->ccb_blockcnt * DEV_BSIZE(1 << 9));
505 else
506 error = sdmmc_mem_write_block(tgt->card, ccb->ccb_blockno,
507 xs->data, ccb->ccb_blockcnt * DEV_BSIZE(1 << 9));
508
509 if (error != 0)
510 xs->error = XS_DRIVER_STUFFUP2;
511
512 sdmmc_done_xs(ccb);
513 splx(s)spllower(s);
514}
515
516void
517sdmmc_done_xs(struct sdmmc_ccb *ccb)
518{
519 struct scsi_xfer *xs = ccb->ccb_xs;
520#ifdef SDMMC_DEBUG
521 struct scsi_link *link = xs->sc_link;
522 struct sdmmc_softc *sc = link->bus->sb_adapter_softc;
523#endif
524
525 timeout_del(&xs->stimeout);
526
527 DPRINTF(("%s: scsi cmd target=%d opcode=%#x proc=\"%s\" (error=%#x)"
528 " done\n", DEVNAME(sc), link->target, xs->cmd.opcode,
529 curproc ? curproc->p_p->ps_comm : "", xs->error));
530
531 xs->resid = 0;
532
533 if (ISSET(ccb->ccb_flags, SDMMC_CCB_F_ERR)((ccb->ccb_flags) & (0x0001)))
534 xs->error = XS_DRIVER_STUFFUP2;
535
536 scsi_done(xs);
537}
538
539void
540sdmmc_stimeout(void *arg)
541{
542 struct sdmmc_ccb *ccb = arg;
543 int s;
544
545 s = splbio()splraise(0x3);
546 ccb->ccb_flags |= SDMMC_CCB_F_ERR0x0001;
547 if (sdmmc_task_pending(&ccb->ccb_task)((&ccb->ccb_task)->onqueue)) {
548 sdmmc_del_task(&ccb->ccb_task);
549 sdmmc_done_xs(ccb);
550 }
551 splx(s)spllower(s);
552}
553
554void
555sdmmc_minphys(struct buf *bp, struct scsi_link *sl)
556{
557 struct sdmmc_softc *sc = sl->bus->sb_adapter_softc;
558 struct sdmmc_scsi_softc *scbus = sc->sc_scsibus;
559 struct sdmmc_scsi_target *tgt = &scbus->sc_tgt[sl->target];
560 struct sdmmc_function *sf = tgt->card;
561
562 /* limit to max. transfer size supported by card/host */
563 if (sc->sc_max_xfer != 0 &&
564 bp->b_bcount > sf->csd.sector_size * sc->sc_max_xfer)
565 bp->b_bcount = sf->csd.sector_size * sc->sc_max_xfer;
566 else
567 minphys(bp);
568}
569
570#ifdef HIBERNATE1
571int
572sdmmc_scsi_hibernate_io(dev_t dev, daddr_t blkno, vaddr_t addr, size_t size,
573 int op, void *page)
574{
575 struct {
576 struct sdmmc_softc sdmmc_sc;
577 struct sdmmc_function sdmmc_sf;
578 daddr_t poffset;
579 size_t psize;
580 struct sdmmc_function *orig_sf;
581 char chipset_softc[0]; /* size depends on the chipset layer */
582 } *state = page;
583 extern struct cfdriver sd_cd;
584 struct device *disk, *scsibus, *chip, *sdmmc;
585 struct scsibus_softc *bus_sc;
586 struct sdmmc_scsi_softc *scsi_sc;
587 struct scsi_link *link;
588 struct sdmmc_function *sf;
589 struct sdmmc_softc *sc;
590 int error;
591
592 switch (op) {
593 case HIB_INIT-1:
594 /* find device (sdmmc_softc, sdmmc_function) */
595 disk = disk_lookup(&sd_cd, DISKUNIT(dev)(((unsigned)((dev) & 0xff) | (((dev) & 0xffff0000) >>
8)) / 16)
);
596 if (disk == NULL((void *)0))
597 return (ENOTTY25);
598
599 scsibus = disk->dv_parent;
600 sdmmc = scsibus->dv_parent;
601 chip = sdmmc->dv_parent;
602
603 bus_sc = (struct scsibus_softc *)scsibus;
604 scsi_sc = (struct sdmmc_scsi_softc *)scsibus;
Value stored to 'scsi_sc' is never read
605 sc = NULL((void *)0);
606 SLIST_FOREACH(link, &bus_sc->sc_link_list, bus_list)for((link) = ((&bus_sc->sc_link_list)->slh_first); (
link) != ((void *)0); (link) = ((link)->bus_list.sle_next)
)
{
607 if (link->device_softc == disk) {
608 sc = link->bus->sb_adapter_softc;
609 scsi_sc = sc->sc_scsibus;
610 sf = scsi_sc->sc_tgt[link->target].card;
611 }
612 }
613 if (sc == NULL((void *)0) || sf == NULL((void *)0))
614 return (ENOTTY25);
615
616 /* if the chipset doesn't do hibernate, bail out now */
617 sc = (struct sdmmc_softc *)sdmmc;
618 if (sc->sct->hibernate_init == NULL((void *)0))
619 return (ENOTTY25);
620
621 state->sdmmc_sc = *sc;
622 state->sdmmc_sf = *sf;
623 state->sdmmc_sf.sc = &state->sdmmc_sc;
624
625 /* pretend we own the lock */
626 state->sdmmc_sc.sc_lock.rwl_owner =
627 (((long)curproc({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r"
(__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self)));
__ci;})->ci_curproc
) & ~RWLOCK_MASK0x07UL) | RWLOCK_WRLOCK0x04UL;
628
629 /* build chip layer fake softc */
630 error = state->sdmmc_sc.sct->hibernate_init(state->sdmmc_sc.sch,
631 &state->chipset_softc);
632 if (error)
633 return (error);
634 state->sdmmc_sc.sch = state->chipset_softc;
635
636 /* make sure we're talking to the right target */
637 state->orig_sf = sc->sc_card;
638 error = sdmmc_select_card(&state->sdmmc_sc, &state->sdmmc_sf);
639 if (error)
640 return (error);
641
642 state->poffset = blkno;
643 state->psize = size;
644 return (0);
645
646 case HIB_W1:
647 if (blkno > state->psize)
648 return (E2BIG7);
649 return (sdmmc_mem_hibernate_write(&state->sdmmc_sf,
650 blkno + state->poffset, (u_char *)addr, size));
651
652 case HIB_DONE-2:
653 /*
654 * bring the hardware state back into line with the real
655 * softc by operating on the fake one
656 */
657 return (sdmmc_select_card(&state->sdmmc_sc, state->orig_sf));
658 }
659
660 return (EINVAL22);
661}
662
663#endif