Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name sdmmc_scsi.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/sdmmc/sdmmc_scsi.c
1/* $OpenBSD: sdmmc_scsi.c,v 1.60 2021/03/27 14:36:28 kn 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
95struct 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(0x6);
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), ((((0x6)) > 0x0 && ((0x6)) < 0x9) ?
0x9 : ((0x6)))); } 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(0x6);
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 0x45:
415 strlcpy(vendor, "Sandisk", sizeof(vendor));
416 break;
417 case 0x11:
418 strlcpy(vendor, "Toshiba", sizeof(vendor));
419 break;
420 case 0x13:
421 strlcpy(vendor, "Micron", sizeof(vendor));
422 break;
423 case 0x15:
424 strlcpy(vendor, "Samsung", sizeof(vendor));
425 break;
426 case 0x70:
427 strlcpy(vendor, "Kingston", sizeof(vendor));
428 break;
429 default:
430 strlcpy(vendor, "SD/MMC", sizeof(vendor));
431 break;
432 }
433 strlcpy(product, tgt->card->cid.pnm, sizeof(product));
434 snprintf(revision, sizeof(revision), "%04X", tgt->card->cid.rev);
435
436 memset(&inq, 0, sizeof inq)__builtin_memset((&inq), (0), (sizeof inq));
437 inq.device = T_DIRECT0x00;
438 inq.dev_qual2 = SID_REMOVABLE0x80;
439 inq.version = SCSI_REV_20x02;
440 inq.response_format = SID_SCSI2_RESPONSE0x02;
441 inq.additional_length = SID_SCSI2_ALEN31;
442 memcpy(inq.vendor, vendor, sizeof(inq.vendor))__builtin_memcpy((inq.vendor), (vendor), (sizeof(inq.vendor))
)
;
443 memcpy(inq.product, product, sizeof(inq.product))__builtin_memcpy((inq.product), (product), (sizeof(inq.product
)))
;
444 memcpy(inq.revision, revision, sizeof(inq.revision))__builtin_memcpy((inq.revision), (revision), (sizeof(inq.revision
)))
;
445
446 scsi_copy_internal_data(xs, &inq, sizeof(inq));
447
448done:
449 scsi_done(xs);
450}
451
452void
453sdmmc_start_xs(struct sdmmc_softc *sc, struct sdmmc_ccb *ccb)
454{
455 struct sdmmc_scsi_softc *scbus = sc->sc_scsibus;
456 struct scsi_xfer *xs = ccb->ccb_xs;
457 int s;
458
459 timeout_set(&xs->stimeout, sdmmc_stimeout, ccb);
460 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)
;
461
462 s = splbio()splraise(0x6);
463 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)
;
464 ccb->ccb_state = SDMMC_CCB_QUEUED;
465 splx(s)spllower(s);
466
467 if (ISSET(xs->flags, SCSI_POLL)((xs->flags) & (0x00002))) {
468 sdmmc_complete_xs(ccb);
469 return;
470 }
471
472 timeout_add_msec(&xs->stimeout, xs->timeout);
473 sdmmc_add_task(sc, &ccb->ccb_task);
474}
475
476void
477sdmmc_complete_xs(void *arg)
478{
479 struct sdmmc_ccb *ccb = arg;
480 struct scsi_xfer *xs = ccb->ccb_xs;
481 struct scsi_link *link = xs->sc_link;
482 struct sdmmc_softc *sc = link->bus->sb_adapter_softc;
483 struct sdmmc_scsi_softc *scbus = sc->sc_scsibus;
484 struct sdmmc_scsi_target *tgt = &scbus->sc_tgt[link->target];
485 int error;
486 int s;
487
488 DPRINTF(("%s: scsi cmd target=%d opcode=%#x proc=\"%s\" (poll=%#x)"
489 " complete\n", DEVNAME(sc), link->target, xs->cmd.opcode,
490 curproc ? curproc->p_p->ps_comm : "", xs->flags & SCSI_POLL));
491
492 s = splbio()splraise(0x6);
493
494 if (ISSET(xs->flags, SCSI_DATA_IN)((xs->flags) & (0x00800)))
495 error = sdmmc_mem_read_block(tgt->card, ccb->ccb_blockno,
496 xs->data, ccb->ccb_blockcnt * DEV_BSIZE(1 << 9));
497 else
498 error = sdmmc_mem_write_block(tgt->card, ccb->ccb_blockno,
499 xs->data, ccb->ccb_blockcnt * DEV_BSIZE(1 << 9));
500
501 if (error != 0)
502 xs->error = XS_DRIVER_STUFFUP2;
503
504 sdmmc_done_xs(ccb);
505 splx(s)spllower(s);
506}
507
508void
509sdmmc_done_xs(struct sdmmc_ccb *ccb)
510{
511 struct scsi_xfer *xs = ccb->ccb_xs;
512#ifdef SDMMC_DEBUG
513 struct scsi_link *link = xs->sc_link;
514 struct sdmmc_softc *sc = link->bus->sb_adapter_softc;
515#endif
516
517 timeout_del(&xs->stimeout);
518
519 DPRINTF(("%s: scsi cmd target=%d opcode=%#x proc=\"%s\" (error=%#x)"
520 " done\n", DEVNAME(sc), link->target, xs->cmd.opcode,
521 curproc ? curproc->p_p->ps_comm : "", xs->error));
522
523 xs->resid = 0;
524
525 if (ISSET(ccb->ccb_flags, SDMMC_CCB_F_ERR)((ccb->ccb_flags) & (0x0001)))
526 xs->error = XS_DRIVER_STUFFUP2;
527
528 scsi_done(xs);
529}
530
531void
532sdmmc_stimeout(void *arg)
533{
534 struct sdmmc_ccb *ccb = arg;
535 int s;
536
537 s = splbio()splraise(0x6);
538 ccb->ccb_flags |= SDMMC_CCB_F_ERR0x0001;
539 if (sdmmc_task_pending(&ccb->ccb_task)((&ccb->ccb_task)->onqueue)) {
540 sdmmc_del_task(&ccb->ccb_task);
541 sdmmc_done_xs(ccb);
542 }
543 splx(s)spllower(s);
544}
545
546void
547sdmmc_minphys(struct buf *bp, struct scsi_link *sl)
548{
549 struct sdmmc_softc *sc = sl->bus->sb_adapter_softc;
550 struct sdmmc_scsi_softc *scbus = sc->sc_scsibus;
551 struct sdmmc_scsi_target *tgt = &scbus->sc_tgt[sl->target];
552 struct sdmmc_function *sf = tgt->card;
553
554 /* limit to max. transfer size supported by card/host */
555 if (sc->sc_max_xfer != 0 &&
556 bp->b_bcount > sf->csd.sector_size * sc->sc_max_xfer)
557 bp->b_bcount = sf->csd.sector_size * sc->sc_max_xfer;
558 else
559 minphys(bp);
560}
561
562#ifdef HIBERNATE1
563int
564sdmmc_scsi_hibernate_io(dev_t dev, daddr_t blkno, vaddr_t addr, size_t size,
565 int op, void *page)
566{
567 struct {
568 struct sdmmc_softc sdmmc_sc;
569 struct sdmmc_function sdmmc_sf;
570 daddr_t poffset;
571 size_t psize;
572 struct sdmmc_function *orig_sf;
573 char chipset_softc[0]; /* size depends on the chipset layer */
574 } *state = page;
575 extern struct cfdriver sd_cd;
576 struct device *disk, *scsibus, *chip, *sdmmc;
577 struct scsibus_softc *bus_sc;
578 struct sdmmc_scsi_softc *scsi_sc;
579 struct scsi_link *link;
580 struct sdmmc_function *sf;
581 struct sdmmc_softc *sc;
582 int error;
583
584 switch (op) {
585 case HIB_INIT-1:
586 /* find device (sdmmc_softc, sdmmc_function) */
587 disk = disk_lookup(&sd_cd, DISKUNIT(dev)(((unsigned)((dev) & 0xff) | (((dev) & 0xffff0000) >>
8)) / 16)
);
588 if (disk == NULL((void *)0))
589 return (ENOTTY25);
590
591 scsibus = disk->dv_parent;
592 sdmmc = scsibus->dv_parent;
593 chip = sdmmc->dv_parent;
Value stored to 'chip' is never read
594
595 bus_sc = (struct scsibus_softc *)scsibus;
596 scsi_sc = (struct sdmmc_scsi_softc *)scsibus;
597 sc = NULL((void *)0);
598 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)
)
{
599 if (link->device_softc == disk) {
600 sc = link->bus->sb_adapter_softc;
601 scsi_sc = sc->sc_scsibus;
602 sf = scsi_sc->sc_tgt[link->target].card;
603 }
604 }
605 if (sc == NULL((void *)0) || sf == NULL((void *)0))
606 return (ENOTTY25);
607
608 /* if the chipset doesn't do hibernate, bail out now */
609 sc = (struct sdmmc_softc *)sdmmc;
610 if (sc->sct->hibernate_init == NULL((void *)0))
611 return (ENOTTY25);
612
613 state->sdmmc_sc = *sc;
614 state->sdmmc_sf = *sf;
615 state->sdmmc_sf.sc = &state->sdmmc_sc;
616
617 /* pretend we own the lock */
618 state->sdmmc_sc.sc_lock.rwl_owner =
619 (((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;
620
621 /* build chip layer fake softc */
622 error = state->sdmmc_sc.sct->hibernate_init(state->sdmmc_sc.sch,
623 &state->chipset_softc);
624 if (error)
625 return (error);
626 state->sdmmc_sc.sch = state->chipset_softc;
627
628 /* make sure we're talking to the right target */
629 state->orig_sf = sc->sc_card;
630 error = sdmmc_select_card(&state->sdmmc_sc, &state->sdmmc_sf);
631 if (error)
632 return (error);
633
634 state->poffset = blkno;
635 state->psize = size;
636 return (0);
637
638 case HIB_W1:
639 if (blkno > state->psize)
640 return (E2BIG7);
641 return (sdmmc_mem_hibernate_write(&state->sdmmc_sf,
642 blkno + state->poffset, (u_char *)addr, size));
643
644 case HIB_DONE-2:
645 /*
646 * bring the hardware state back into line with the real
647 * softc by operating on the fake one
648 */
649 return (sdmmc_select_card(&state->sdmmc_sc, state->orig_sf));
650 }
651
652 return (EINVAL22);
653}
654
655#endif