Bug Summary

File:dev/sdmmc/sdmmc_mem.c
Warning:line 655, column 3
Value stored to 'error' 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_mem.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_mem.c
1/* $OpenBSD: sdmmc_mem.c,v 1.37 2022/01/10 18:23:39 tobhe 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/* Routines for SD/MMC memory cards. */
20
21#include <sys/param.h>
22#include <sys/device.h>
23#include <sys/kernel.h>
24#include <sys/malloc.h>
25#include <sys/systm.h>
26
27#include <dev/sdmmc/sdmmcchip.h>
28#include <dev/sdmmc/sdmmcreg.h>
29#include <dev/sdmmc/sdmmcvar.h>
30
31#ifdef HIBERNATE1
32#include <uvm/uvm_extern.h>
33#endif
34
35typedef struct { uint32_t _bits[512/32]; } __packed__attribute__((__packed__)) __aligned(4)__attribute__((__aligned__(4))) sdmmc_bitfield512_t;
36
37void sdmmc_be512_to_bitfield512(sdmmc_bitfield512_t *);
38
39int sdmmc_decode_csd(struct sdmmc_softc *, sdmmc_response,
40 struct sdmmc_function *);
41int sdmmc_decode_cid(struct sdmmc_softc *, sdmmc_response,
42 struct sdmmc_function *);
43void sdmmc_print_cid(struct sdmmc_cid *);
44
45int sdmmc_mem_send_op_cond(struct sdmmc_softc *, u_int32_t, u_int32_t *);
46int sdmmc_mem_set_blocklen(struct sdmmc_softc *, struct sdmmc_function *);
47
48int sdmmc_mem_send_scr(struct sdmmc_softc *, uint32_t *);
49int sdmmc_mem_decode_scr(struct sdmmc_softc *, uint32_t *,
50 struct sdmmc_function *);
51
52int sdmmc_mem_send_cxd_data(struct sdmmc_softc *, int, void *, size_t);
53int sdmmc_mem_set_bus_width(struct sdmmc_function *, int);
54int sdmmc_mem_mmc_switch(struct sdmmc_function *, uint8_t, uint8_t, uint8_t);
55int sdmmc_mem_signal_voltage(struct sdmmc_softc *, int);
56
57int sdmmc_mem_sd_init(struct sdmmc_softc *, struct sdmmc_function *);
58int sdmmc_mem_mmc_init(struct sdmmc_softc *, struct sdmmc_function *);
59int sdmmc_mem_single_read_block(struct sdmmc_function *, int, u_char *,
60 size_t);
61int sdmmc_mem_read_block_subr(struct sdmmc_function *, bus_dmamap_t,
62 int, u_char *, size_t);
63int sdmmc_mem_single_write_block(struct sdmmc_function *, int, u_char *,
64 size_t);
65int sdmmc_mem_write_block_subr(struct sdmmc_function *, bus_dmamap_t,
66 int, u_char *, size_t);
67
68#ifdef SDMMC_DEBUG
69#define DPRINTF(s) printf s
70#else
71#define DPRINTF(s) /**/
72#endif
73
74const struct {
75 const char *name;
76 int v;
77 int freq;
78} switch_group0_functions[] = {
79 /* Default/SDR12 */
80 { "Default/SDR12", 0, 25000 },
81
82 /* High-Speed/SDR25 */
83 { "High-Speed/SDR25", SMC_CAPS_SD_HIGHSPEED0x0100, 50000 },
84
85 /* SDR50 */
86 { "SDR50", SMC_CAPS_UHS_SDR500x0400, 100000 },
87
88 /* SDR104 */
89 { "SDR104", SMC_CAPS_UHS_SDR1040x0800, 208000 },
90
91 /* DDR50 */
92 { "DDR50", SMC_CAPS_UHS_DDR500x1000, 50000 },
93};
94
95const int sdmmc_mmc_timings[] = {
96 [SDMMC_TIMING_LEGACY0] = 26000,
97 [SDMMC_TIMING_HIGHSPEED1] = 52000,
98 [SDMMC_TIMING_MMC_DDR524] = 52000,
99 [SDMMC_TIMING_MMC_HS2005] = 200000
100};
101
102/*
103 * Initialize SD/MMC memory cards and memory in SDIO "combo" cards.
104 */
105int
106sdmmc_mem_enable(struct sdmmc_softc *sc)
107{
108 uint32_t host_ocr;
109 uint32_t card_ocr;
110 uint32_t new_ocr;
111 uint32_t ocr = 0;
112 int error;
113
114 rw_assert_wrlock(&sc->sc_lock);
115
116 /* Set host mode to SD "combo" card or SD memory-only. */
117 CLR(sc->sc_flags, SMF_UHS_MODE)((sc->sc_flags) &= ~(0x0010));
118 SET(sc->sc_flags, SMF_SD_MODE|SMF_MEM_MODE)((sc->sc_flags) |= (0x0001|0x0004));
119
120 /* Reset memory (*must* do that before CMD55 or CMD1). */
121 sdmmc_go_idle_state(sc);
122
123 /*
124 * Read the SD/MMC memory OCR value by issuing CMD55 followed
125 * by ACMD41 to read the OCR value from memory-only SD cards.
126 * MMC cards will not respond to CMD55 or ACMD41 and this is
127 * how we distinguish them from SD cards.
128 */
129 mmc_mode:
130 if (sdmmc_mem_send_op_cond(sc, 0, &card_ocr) != 0) {
131 if (ISSET(sc->sc_flags, SMF_SD_MODE)((sc->sc_flags) & (0x0001)) &&
132 !ISSET(sc->sc_flags, SMF_IO_MODE)((sc->sc_flags) & (0x0002))) {
133 /* Not a SD card, switch to MMC mode. */
134 CLR(sc->sc_flags, SMF_SD_MODE)((sc->sc_flags) &= ~(0x0001));
135 goto mmc_mode;
136 }
137 if (!ISSET(sc->sc_flags, SMF_SD_MODE)((sc->sc_flags) & (0x0001))) {
138 DPRINTF(("%s: can't read memory OCR\n",
139 DEVNAME(sc)));
140 return 1;
141 } else {
142 /* Not a "combo" card. */
143 CLR(sc->sc_flags, SMF_MEM_MODE)((sc->sc_flags) &= ~(0x0004));
144 return 0;
145 }
146 }
147
148 /* Set the lowest voltage supported by the card and host. */
149 host_ocr = sdmmc_chip_host_ocr(sc->sct, sc->sch)((sc->sct)->host_ocr((sc->sch)));
150 if (sdmmc_set_bus_power(sc, host_ocr, card_ocr) != 0) {
151 DPRINTF(("%s: can't supply voltage requested by card\n",
152 DEVNAME(sc)));
153 return 1;
154 }
155
156 /* Tell the card(s) to enter the idle state (again). */
157 sdmmc_go_idle_state(sc);
158
159 host_ocr &= card_ocr; /* only allow the common voltages */
160
161 if (ISSET(sc->sc_flags, SMF_SD_MODE)((sc->sc_flags) & (0x0001))) {
162 if (sdmmc_send_if_cond(sc, card_ocr) == 0)
163 SET(ocr, MMC_OCR_HCS)((ocr) |= ((1<<30)));
164
165 if (sdmmc_chip_host_ocr(sc->sct, sc->sch)((sc->sct)->host_ocr((sc->sch))) & MMC_OCR_S18A(1<<24))
166 SET(ocr, MMC_OCR_S18A)((ocr) |= ((1<<24)));
167 }
168 host_ocr |= ocr;
169
170 /* Send the new OCR value until all cards are ready. */
171 if (sdmmc_mem_send_op_cond(sc, host_ocr, &new_ocr) != 0) {
172 DPRINTF(("%s: can't send memory OCR\n", DEVNAME(sc)));
173 return 1;
174 }
175
176 if (ISSET(sc->sc_flags, SMF_SD_MODE)((sc->sc_flags) & (0x0001)) && ISSET(new_ocr, MMC_OCR_S18A)((new_ocr) & ((1<<24)))) {
177 /*
178 * Card and host support low voltage mode, begin switch
179 * sequence.
180 */
181 struct sdmmc_command cmd;
182
183 memset(&cmd, 0, sizeof(cmd))__builtin_memset((&cmd), (0), (sizeof(cmd)));
184 cmd.c_arg = 0;
185 cmd.c_flags = SCF_CMD_AC0x0000 | SCF_RSP_R1(0x1000|0x0400|0x0800);
186 cmd.c_opcode = SD_VOLTAGE_SWITCH11;
187 DPRINTF(("%s: switching card to 1.8V\n", DEVNAME(sc)));
188 error = sdmmc_mmc_command(sc, &cmd);
189 if (error) {
190 DPRINTF(("%s: voltage switch command failed\n",
191 DEVNAME(sc)));
192 return error;
193 }
194
195 error = sdmmc_mem_signal_voltage(sc, SDMMC_SIGNAL_VOLTAGE_1801);
196 if (error)
197 return error;
198
199 SET(sc->sc_flags, SMF_UHS_MODE)((sc->sc_flags) |= (0x0010));
200 }
201
202 return 0;
203}
204
205int
206sdmmc_mem_signal_voltage(struct sdmmc_softc *sc, int signal_voltage)
207{
208 int error;
209
210 /*
211 * Stop the clock
212 */
213 error = sdmmc_chip_bus_clock(sc->sct, sc->sch, 0, SDMMC_TIMING_LEGACY)((sc->sct)->bus_clock((sc->sch), (0), (0)));
214 if (error)
215 return error;
216
217 delay(1000)(*delay_func)(1000);
218
219 /*
220 * Card switch command was successful, update host controller
221 * signal voltage setting.
222 */
223 DPRINTF(("%s: switching host to %s\n", DEVNAME(sc),
224 signal_voltage == SDMMC_SIGNAL_VOLTAGE_180 ? "1.8V" : "3.3V"));
225 error = sdmmc_chip_signal_voltage(sc->sct, sc->sch, signal_voltage)((sc->sct)->signal_voltage((sc->sch), (signal_voltage
)))
;
226 if (error)
227 return error;
228
229 delay(5000)(*delay_func)(5000);
230
231 /*
232 * Switch to SDR12 timing
233 */
234 error = sdmmc_chip_bus_clock(sc->sct, sc->sch, SDMMC_SDCLK_25MHZ,((sc->sct)->bus_clock((sc->sch), (25000), (0)))
235 SDMMC_TIMING_LEGACY)((sc->sct)->bus_clock((sc->sch), (25000), (0)));
236 if (error)
237 return error;
238
239 delay(1000)(*delay_func)(1000);
240
241 return 0;
242}
243
244/*
245 * Read the CSD and CID from all cards and assign each card a unique
246 * relative card address (RCA). CMD2 is ignored by SDIO-only cards.
247 */
248void
249sdmmc_mem_scan(struct sdmmc_softc *sc)
250{
251 struct sdmmc_command cmd;
252 struct sdmmc_function *sf;
253 u_int16_t next_rca;
254 int error;
255 int i;
256
257 rw_assert_wrlock(&sc->sc_lock);
258
259 /*
260 * CMD2 is a broadcast command understood by SD cards and MMC
261 * cards. All cards begin to respond to the command, but back
262 * off if another card drives the CMD line to a different level.
263 * Only one card will get its entire response through. That
264 * card remains silent once it has been assigned a RCA.
265 */
266 for (i = 0; i < 100; i++) {
267 bzero(&cmd, sizeof cmd)__builtin_bzero((&cmd), (sizeof cmd));
268 cmd.c_opcode = MMC_ALL_SEND_CID2;
269 cmd.c_flags = SCF_CMD_BCR0x0030 | SCF_RSP_R2(0x1000|0x0400|0x0200);
270
271 error = sdmmc_mmc_command(sc, &cmd);
272 if (error == ETIMEDOUT60) {
273 /* No more cards there. */
274 break;
275 } else if (error != 0) {
276 DPRINTF(("%s: can't read CID\n", DEVNAME(sc)));
277 break;
278 }
279
280 /* In MMC mode, find the next available RCA. */
281 next_rca = 1;
282 if (!ISSET(sc->sc_flags, SMF_SD_MODE)((sc->sc_flags) & (0x0001)))
283 SIMPLEQ_FOREACH(sf, &sc->sf_head, sf_list)for((sf) = ((&sc->sf_head)->sqh_first); (sf) != ((void
*)0); (sf) = ((sf)->sf_list.sqe_next))
284 next_rca++;
285
286 /* Allocate a sdmmc_function structure. */
287 sf = sdmmc_function_alloc(sc);
288 sf->rca = next_rca;
289
290 /*
291 * Remember the CID returned in the CMD2 response for
292 * later decoding.
293 */
294 bcopy(cmd.c_resp, sf->raw_cid, sizeof sf->raw_cid);
295
296 /*
297 * Silence the card by assigning it a unique RCA, or
298 * querying it for its RCA in the case of SD.
299 */
300 if (sdmmc_set_relative_addr(sc, sf) != 0) {
301 printf("%s: can't set mem RCA\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
302 sdmmc_function_free(sf);
303 break;
304 }
305
306#if 0
307 /* Verify that the RCA has been set by selecting the card. */
308 if (sdmmc_select_card(sc, sf) != 0) {
309 printf("%s: can't select mem RCA %d\n",
310 DEVNAME(sc)((sc)->sc_dev.dv_xname), sf->rca);
311 sdmmc_function_free(sf);
312 break;
313 }
314
315 /* Deselect. */
316 (void)sdmmc_select_card(sc, NULL((void *)0));
317#endif
318
319 /*
320 * If this is a memory-only card, the card responding
321 * first becomes an alias for SDIO function 0.
322 */
323 if (sc->sc_fn0 == NULL((void *)0))
324 sc->sc_fn0 = sf;
325
326 SIMPLEQ_INSERT_TAIL(&sc->sf_head, sf, sf_list)do { (sf)->sf_list.sqe_next = ((void *)0); *(&sc->sf_head
)->sqh_last = (sf); (&sc->sf_head)->sqh_last = &
(sf)->sf_list.sqe_next; } while (0)
;
327 }
328
329 /*
330 * All cards are either inactive or awaiting further commands.
331 * Read the CSDs and decode the raw CID for each card.
332 */
333 SIMPLEQ_FOREACH(sf, &sc->sf_head, sf_list)for((sf) = ((&sc->sf_head)->sqh_first); (sf) != ((void
*)0); (sf) = ((sf)->sf_list.sqe_next))
{
334 bzero(&cmd, sizeof cmd)__builtin_bzero((&cmd), (sizeof cmd));
335 cmd.c_opcode = MMC_SEND_CSD9;
336 cmd.c_arg = MMC_ARG_RCA(sf->rca)((sf->rca) << 16);
337 cmd.c_flags = SCF_CMD_AC0x0000 | SCF_RSP_R2(0x1000|0x0400|0x0200);
338
339 if (sdmmc_mmc_command(sc, &cmd) != 0) {
340 SET(sf->flags, SFF_ERROR)((sf->flags) |= (0x0001));
341 continue;
342 }
343
344 if (sdmmc_decode_csd(sc, cmd.c_resp, sf) != 0 ||
345 sdmmc_decode_cid(sc, sf->raw_cid, sf) != 0) {
346 SET(sf->flags, SFF_ERROR)((sf->flags) |= (0x0001));
347 continue;
348 }
349
350#ifdef SDMMC_DEBUG
351 printf("%s: CID: ", DEVNAME(sc)((sc)->sc_dev.dv_xname));
352 sdmmc_print_cid(&sf->cid);
353#endif
354 }
355}
356
357int
358sdmmc_decode_csd(struct sdmmc_softc *sc, sdmmc_response resp,
359 struct sdmmc_function *sf)
360{
361 struct sdmmc_csd *csd = &sf->csd;
362
363 if (ISSET(sc->sc_flags, SMF_SD_MODE)((sc->sc_flags) & (0x0001))) {
364 /*
365 * CSD version 1.0 corresponds to SD system
366 * specification version 1.0 - 1.10. (SanDisk, 3.5.3)
367 */
368 csd->csdver = SD_CSD_CSDVER(resp)__bitfield(((resp)), (126)-8, (2));
369 switch (csd->csdver) {
370 case SD_CSD_CSDVER_2_01:
371 sf->flags |= SFF_SDHC0x0002;
372 csd->capacity = SD_CSD_V2_CAPACITY(resp)((__bitfield((((resp))), (48)-8, (22))+1) << 10);
373 csd->read_bl_len = SD_CSD_V2_BL_LEN0x9;
374 break;
375 case SD_CSD_CSDVER_1_00:
376 csd->capacity = SD_CSD_CAPACITY(resp)((__bitfield((((resp))), (62)-8, (12))+1) << (__bitfield
((((resp))), (47)-8, (3))+2))
;
377 csd->read_bl_len = SD_CSD_READ_BL_LEN(resp)__bitfield(((resp)), (80)-8, (4));
378 break;
379 default:
380 printf("%s: unknown SD CSD structure version 0x%x\n",
381 DEVNAME(sc)((sc)->sc_dev.dv_xname), csd->csdver);
382 return 1;
383 break;
384 }
385 csd->ccc = SD_CSD_CCC(resp)__bitfield(((resp)), (84)-8, (12));
386 } else {
387 csd->csdver = MMC_CSD_CSDVER(resp)__bitfield(((resp)), (126)-8, (2));
388 if (csd->csdver == MMC_CSD_CSDVER_1_01 ||
389 csd->csdver == MMC_CSD_CSDVER_2_02 ||
390 csd->csdver == MMC_CSD_CSDVER_EXT_CSD3) {
391 csd->mmcver = MMC_CSD_MMCVER(resp)__bitfield(((resp)), (122)-8, (4));
392 csd->capacity = MMC_CSD_CAPACITY(resp)((__bitfield((((resp))), (62)-8, (12))+1) << (__bitfield
((((resp))), (47)-8, (3))+2))
;
393 csd->read_bl_len = MMC_CSD_READ_BL_LEN(resp)__bitfield(((resp)), (80)-8, (4));
394 } else {
395 printf("%s: unknown MMC CSD structure version 0x%x\n",
396 DEVNAME(sc)((sc)->sc_dev.dv_xname), csd->csdver);
397 return 1;
398 }
399 }
400 csd->sector_size = MIN(1 << csd->read_bl_len,(((1 << csd->read_bl_len)<(((sc->sct)->host_maxblklen
((sc->sch)))))?(1 << csd->read_bl_len):(((sc->
sct)->host_maxblklen((sc->sch)))))
401 sdmmc_chip_host_maxblklen(sc->sct, sc->sch))(((1 << csd->read_bl_len)<(((sc->sct)->host_maxblklen
((sc->sch)))))?(1 << csd->read_bl_len):(((sc->
sct)->host_maxblklen((sc->sch)))))
;
402 if (csd->sector_size < (1<<csd->read_bl_len))
403 csd->capacity *= (1<<csd->read_bl_len) /
404 csd->sector_size;
405
406 return 0;
407}
408
409int
410sdmmc_decode_cid(struct sdmmc_softc *sc, sdmmc_response resp,
411 struct sdmmc_function *sf)
412{
413 struct sdmmc_cid *cid = &sf->cid;
414
415 if (ISSET(sc->sc_flags, SMF_SD_MODE)((sc->sc_flags) & (0x0001))) {
416 cid->mid = SD_CID_MID(resp)__bitfield(((resp)), (120)-8, (8));
417 cid->oid = SD_CID_OID(resp)__bitfield(((resp)), (104)-8, (16));
418 SD_CID_PNM_CPY(resp, cid->pnm)do { (cid->pnm)[0] = __bitfield(((resp)), (96)-8, (8)); (cid
->pnm)[1] = __bitfield(((resp)), (88)-8, (8)); (cid->pnm
)[2] = __bitfield(((resp)), (80)-8, (8)); (cid->pnm)[3] = __bitfield
(((resp)), (72)-8, (8)); (cid->pnm)[4] = __bitfield(((resp
)), (64)-8, (8)); (cid->pnm)[5] = '\0'; } while (0)
;
419 cid->rev = SD_CID_REV(resp)__bitfield(((resp)), (56)-8, (8));
420 cid->psn = SD_CID_PSN(resp)__bitfield(((resp)), (24)-8, (32));
421 cid->mdt = SD_CID_MDT(resp)__bitfield(((resp)), (8)-8, (12));
422 } else {
423 switch(sf->csd.mmcver) {
424 case MMC_CSD_MMCVER_1_00:
425 case MMC_CSD_MMCVER_1_41:
426 cid->mid = MMC_CID_MID_V1(resp)__bitfield(((resp)), (104)-8, (24));
427 MMC_CID_PNM_V1_CPY(resp, cid->pnm)do { (cid->pnm)[0] = __bitfield(((resp)), (96)-8, (8)); (cid
->pnm)[1] = __bitfield(((resp)), (88)-8, (8)); (cid->pnm
)[2] = __bitfield(((resp)), (80)-8, (8)); (cid->pnm)[3] = __bitfield
(((resp)), (72)-8, (8)); (cid->pnm)[4] = __bitfield(((resp
)), (64)-8, (8)); (cid->pnm)[5] = __bitfield(((resp)), (56
)-8, (8)); (cid->pnm)[6] = __bitfield(((resp)), (48)-8, (8
)); (cid->pnm)[7] = '\0'; } while (0)
;
428 cid->rev = MMC_CID_REV_V1(resp)__bitfield(((resp)), (40)-8, (8));
429 cid->psn = MMC_CID_PSN_V1(resp)__bitfield(((resp)), (16)-8, (24));
430 cid->mdt = MMC_CID_MDT_V1(resp)__bitfield(((resp)), (8)-8, (8));
431 break;
432 case MMC_CSD_MMCVER_2_02:
433 case MMC_CSD_MMCVER_3_13:
434 case MMC_CSD_MMCVER_4_04:
435 cid->mid = MMC_CID_MID_V2(resp)__bitfield(((resp)), (120)-8, (8));
436 cid->oid = MMC_CID_OID_V2(resp)__bitfield(((resp)), (104)-8, (16));
437 MMC_CID_PNM_V2_CPY(resp, cid->pnm)do { (cid->pnm)[0] = __bitfield(((resp)), (96)-8, (8)); (cid
->pnm)[1] = __bitfield(((resp)), (88)-8, (8)); (cid->pnm
)[2] = __bitfield(((resp)), (80)-8, (8)); (cid->pnm)[3] = __bitfield
(((resp)), (72)-8, (8)); (cid->pnm)[4] = __bitfield(((resp
)), (64)-8, (8)); (cid->pnm)[5] = __bitfield(((resp)), (56
)-8, (8)); (cid->pnm)[6] = '\0'; } while (0)
;
438 cid->psn = MMC_CID_PSN_V2(resp)__bitfield(((resp)), (16)-8, (32));
439 break;
440 default:
441 printf("%s: unknown MMC version %d\n",
442 DEVNAME(sc)((sc)->sc_dev.dv_xname), sf->csd.mmcver);
443 return 1;
444 }
445 }
446 return 0;
447}
448
449#ifdef SDMMC_DEBUG
450void
451sdmmc_print_cid(struct sdmmc_cid *cid)
452{
453 printf("mid=0x%02x oid=0x%04x pnm=\"%s\" rev=0x%02x psn=0x%08x"
454 " mdt=%03x\n", cid->mid, cid->oid, cid->pnm, cid->rev, cid->psn,
455 cid->mdt);
456}
457#endif
458
459int
460sdmmc_mem_send_scr(struct sdmmc_softc *sc, uint32_t *scr)
461{
462 struct sdmmc_command cmd;
463 void *ptr = NULL((void *)0);
464 int datalen = 8;
465 int error = 0;
466
467 ptr = malloc(datalen, M_DEVBUF2, M_NOWAIT0x0002 | M_ZERO0x0008);
468 if (ptr == NULL((void *)0))
469 return ENOMEM12;
470
471 memset(&cmd, 0, sizeof(cmd))__builtin_memset((&cmd), (0), (sizeof(cmd)));
472 cmd.c_data = ptr;
473 cmd.c_datalen = datalen;
474 cmd.c_blklen = datalen;
475 cmd.c_arg = 0;
476 cmd.c_flags = SCF_CMD_ADTC0x0010 | SCF_CMD_READ0x0040 | SCF_RSP_R1(0x1000|0x0400|0x0800);
477 cmd.c_opcode = SD_APP_SEND_SCR51;
478
479 error = sdmmc_app_command(sc, &cmd);
480 if (error == 0)
481 memcpy(scr, ptr, datalen)__builtin_memcpy((scr), (ptr), (datalen));
482
483 free(ptr, M_DEVBUF2, datalen);
484
485 return error;
486}
487
488int
489sdmmc_mem_decode_scr(struct sdmmc_softc *sc, uint32_t *raw_scr,
490 struct sdmmc_function *sf)
491{
492 sdmmc_response resp;
493 int ver;
494
495 memset(resp, 0, sizeof(resp))__builtin_memset((resp), (0), (sizeof(resp)));
496 /*
497 * Change the raw SCR to a response.
498 */
499 resp[0] = be32toh(raw_scr[1])(__uint32_t)(__builtin_constant_p(raw_scr[1]) ? (__uint32_t)(
((__uint32_t)(raw_scr[1]) & 0xff) << 24 | ((__uint32_t
)(raw_scr[1]) & 0xff00) << 8 | ((__uint32_t)(raw_scr
[1]) & 0xff0000) >> 8 | ((__uint32_t)(raw_scr[1]) &
0xff000000) >> 24) : __swap32md(raw_scr[1]))
>> 8; // LSW
500 resp[1] = be32toh(raw_scr[0])(__uint32_t)(__builtin_constant_p(raw_scr[0]) ? (__uint32_t)(
((__uint32_t)(raw_scr[0]) & 0xff) << 24 | ((__uint32_t
)(raw_scr[0]) & 0xff00) << 8 | ((__uint32_t)(raw_scr
[0]) & 0xff0000) >> 8 | ((__uint32_t)(raw_scr[0]) &
0xff000000) >> 24) : __swap32md(raw_scr[0]))
; // MSW
501 resp[0] |= (resp[1] & 0xff) << 24;
502 resp[1] >>= 8;
503
504 ver = SCR_STRUCTURE(resp)__bitfield(((resp)), (60)-8, (4));
505 sf->scr.sd_spec = SCR_SD_SPEC(resp)__bitfield(((resp)), (56)-8, (4));
506 sf->scr.bus_width = SCR_SD_BUS_WIDTHS(resp)__bitfield(((resp)), (48)-8, (4));
507
508 DPRINTF(("%s: %s: %08x%08x ver=%d, spec=%d, bus width=%d\n",
509 DEVNAME(sc), __func__, resp[1], resp[0],
510 ver, sf->scr.sd_spec, sf->scr.bus_width));
511
512 if (ver != 0) {
513 DPRINTF(("%s: unknown SCR structure version: %d\n",
514 DEVNAME(sc), ver));
515 return EINVAL22;
516 }
517 return 0;
518}
519
520int
521sdmmc_mem_send_cxd_data(struct sdmmc_softc *sc, int opcode, void *data,
522 size_t datalen)
523{
524 struct sdmmc_command cmd;
525 void *ptr = NULL((void *)0);
526 int error = 0;
527
528 ptr = malloc(datalen, M_DEVBUF2, M_NOWAIT0x0002 | M_ZERO0x0008);
529 if (ptr == NULL((void *)0))
530 return ENOMEM12;
531
532 memset(&cmd, 0, sizeof(cmd))__builtin_memset((&cmd), (0), (sizeof(cmd)));
533 cmd.c_data = ptr;
534 cmd.c_datalen = datalen;
535 cmd.c_blklen = datalen;
536 cmd.c_opcode = opcode;
537 cmd.c_arg = 0;
538 cmd.c_flags = SCF_CMD_ADTC0x0010 | SCF_CMD_READ0x0040;
539 if (opcode == MMC_SEND_EXT_CSD8)
540 SET(cmd.c_flags, SCF_RSP_R1)((cmd.c_flags) |= ((0x1000|0x0400|0x0800)));
541 else
542 SET(cmd.c_flags, SCF_RSP_R2)((cmd.c_flags) |= ((0x1000|0x0400|0x0200)));
543
544 error = sdmmc_mmc_command(sc, &cmd);
545 if (error == 0)
546 memcpy(data, ptr, datalen)__builtin_memcpy((data), (ptr), (datalen));
547
548 free(ptr, M_DEVBUF2, datalen);
549
550 return error;
551}
552
553int
554sdmmc_mem_set_bus_width(struct sdmmc_function *sf, int width)
555{
556 struct sdmmc_softc *sc = sf->sc;
557 struct sdmmc_command cmd;
558 int error;
559
560 memset(&cmd, 0, sizeof(cmd))__builtin_memset((&cmd), (0), (sizeof(cmd)));
561 cmd.c_opcode = SD_APP_SET_BUS_WIDTH6;
562 cmd.c_flags = SCF_RSP_R1(0x1000|0x0400|0x0800) | SCF_CMD_AC0x0000;
563
564 switch (width) {
565 case 1:
566 cmd.c_arg = SD_ARG_BUS_WIDTH_10;
567 break;
568
569 case 4:
570 cmd.c_arg = SD_ARG_BUS_WIDTH_42;
571 break;
572
573 default:
574 return EINVAL22;
575 }
576
577 error = sdmmc_app_command(sc, &cmd);
578 if (error == 0)
579 error = sdmmc_chip_bus_width(sc->sct, sc->sch, width)((sc->sct)->bus_width((sc->sch), (width)));
580 return error;
581}
582
583int
584sdmmc_mem_sd_switch(struct sdmmc_function *sf, int mode, int group,
585 int function, sdmmc_bitfield512_t *status)
586{
587 struct sdmmc_softc *sc = sf->sc;
588 struct sdmmc_command cmd;
589 void *ptr = NULL((void *)0);
590 int gsft, error = 0;
591 const int statlen = 64;
592
593 if (sf->scr.sd_spec >= SCR_SD_SPEC_VER_1_101 &&
594 !ISSET(sf->csd.ccc, SD_CSD_CCC_SWITCH)((sf->csd.ccc) & ((1 << 10))))
595 return EINVAL22;
596
597 if (group <= 0 || group > 6 ||
598 function < 0 || function > 15)
599 return EINVAL22;
600
601 gsft = (group - 1) << 2;
602
603 ptr = malloc(statlen, M_DEVBUF2, M_NOWAIT0x0002 | M_ZERO0x0008);
604 if (ptr == NULL((void *)0))
605 return ENOMEM12;
606
607 memset(&cmd, 0, sizeof(cmd))__builtin_memset((&cmd), (0), (sizeof(cmd)));
608 cmd.c_data = ptr;
609 cmd.c_datalen = statlen;
610 cmd.c_blklen = statlen;
611 cmd.c_opcode = SD_SEND_SWITCH_FUNC6;
612 cmd.c_arg =
613 (!!mode << 31) | (function << gsft) | (0x00ffffff & ~(0xf << gsft));
614 cmd.c_flags = SCF_CMD_ADTC0x0010 | SCF_CMD_READ0x0040 | SCF_RSP_R1(0x1000|0x0400|0x0800);
615
616 error = sdmmc_mmc_command(sc, &cmd);
617 if (error == 0) {
618 memcpy(status, ptr, statlen)__builtin_memcpy((status), (ptr), (statlen));
619 sdmmc_be512_to_bitfield512(status);
620 }
621
622 free(ptr, M_DEVBUF2, statlen);
623
624 return error;
625}
626
627int
628sdmmc_mem_mmc_switch(struct sdmmc_function *sf, uint8_t set, uint8_t index,
629 uint8_t value)
630{
631 struct sdmmc_softc *sc = sf->sc;
632 struct sdmmc_command cmd;
633
634 memset(&cmd, 0, sizeof(cmd))__builtin_memset((&cmd), (0), (sizeof(cmd)));
635 cmd.c_opcode = MMC_SWITCH6;
636 cmd.c_arg = (MMC_SWITCH_MODE_WRITE_BYTE0x03 << 24) |
637 (index << 16) | (value << 8) | set;
638 cmd.c_flags = SCF_RSP_R1B(0x1000|0x0400|0x0800|0x0100) | SCF_CMD_AC0x0000;
639
640 return sdmmc_mmc_command(sc, &cmd);
641}
642
643/*
644 * Initialize a SD/MMC memory card.
645 */
646int
647sdmmc_mem_init(struct sdmmc_softc *sc, struct sdmmc_function *sf)
648{
649 int error = 0;
650
651 rw_assert_wrlock(&sc->sc_lock);
652
653 if (sdmmc_select_card(sc, sf) != 0 ||
654 sdmmc_mem_set_blocklen(sc, sf) != 0)
655 error = 1;
Value stored to 'error' is never read
656
657 if (ISSET(sc->sc_flags, SMF_SD_MODE)((sc->sc_flags) & (0x0001)))
658 error = sdmmc_mem_sd_init(sc, sf);
659 else
660 error = sdmmc_mem_mmc_init(sc, sf);
661
662 return error;
663}
664
665/* make 512-bit BE quantity __bitfield()-compatible */
666void
667sdmmc_be512_to_bitfield512(sdmmc_bitfield512_t *buf) {
668 size_t i;
669 uint32_t tmp0, tmp1;
670 const size_t bitswords = nitems(buf->_bits)(sizeof((buf->_bits)) / sizeof((buf->_bits)[0]));
671 for (i = 0; i < bitswords/2; i++) {
672 tmp0 = buf->_bits[i];
673 tmp1 = buf->_bits[bitswords - 1 - i];
674 buf->_bits[i] = be32toh(tmp1)(__uint32_t)(__builtin_constant_p(tmp1) ? (__uint32_t)(((__uint32_t
)(tmp1) & 0xff) << 24 | ((__uint32_t)(tmp1) & 0xff00
) << 8 | ((__uint32_t)(tmp1) & 0xff0000) >> 8
| ((__uint32_t)(tmp1) & 0xff000000) >> 24) : __swap32md
(tmp1))
;
675 buf->_bits[bitswords - 1 - i] = be32toh(tmp0)(__uint32_t)(__builtin_constant_p(tmp0) ? (__uint32_t)(((__uint32_t
)(tmp0) & 0xff) << 24 | ((__uint32_t)(tmp0) & 0xff00
) << 8 | ((__uint32_t)(tmp0) & 0xff0000) >> 8
| ((__uint32_t)(tmp0) & 0xff000000) >> 24) : __swap32md
(tmp0))
;
676 }
677}
678
679int
680sdmmc_mem_select_transfer_mode(struct sdmmc_softc *sc, int support_func)
681{
682 if (ISSET(sc->sc_flags, SMF_UHS_MODE)((sc->sc_flags) & (0x0010))) {
683 if (ISSET(sc->sc_caps, SMC_CAPS_UHS_SDR104)((sc->sc_caps) & (0x0800)) &&
684 ISSET(support_func, 1 << SD_ACCESS_MODE_SDR104)((support_func) & (1 << 3))) {
685 return SD_ACCESS_MODE_SDR1043;
686 }
687 if (ISSET(sc->sc_caps, SMC_CAPS_UHS_DDR50)((sc->sc_caps) & (0x1000)) &&
688 ISSET(support_func, 1 << SD_ACCESS_MODE_DDR50)((support_func) & (1 << 4))) {
689 return SD_ACCESS_MODE_DDR504;
690 }
691 if (ISSET(sc->sc_caps, SMC_CAPS_UHS_SDR50)((sc->sc_caps) & (0x0400)) &&
692 ISSET(support_func, 1 << SD_ACCESS_MODE_SDR50)((support_func) & (1 << 2))) {
693 return SD_ACCESS_MODE_SDR502;
694 }
695 }
696 if (ISSET(sc->sc_caps, SMC_CAPS_SD_HIGHSPEED)((sc->sc_caps) & (0x0100)) &&
697 ISSET(support_func, 1 << SD_ACCESS_MODE_SDR25)((support_func) & (1 << 1))) {
698 return SD_ACCESS_MODE_SDR251;
699 }
700 return SD_ACCESS_MODE_SDR120;
701}
702
703int
704sdmmc_mem_execute_tuning(struct sdmmc_softc *sc, struct sdmmc_function *sf)
705{
706 int timing = -1;
707
708 if (ISSET(sc->sc_flags, SMF_SD_MODE)((sc->sc_flags) & (0x0001))) {
709 if (!ISSET(sc->sc_flags, SMF_UHS_MODE)((sc->sc_flags) & (0x0010)))
710 return 0;
711
712 switch (sf->csd.tran_speed) {
713 case 100000:
714 timing = SDMMC_TIMING_UHS_SDR502;
715 break;
716 case 208000:
717 timing = SDMMC_TIMING_UHS_SDR1043;
718 break;
719 default:
720 return 0;
721 }
722 } else {
723 switch (sf->csd.tran_speed) {
724 case 200000:
725 timing = SDMMC_TIMING_MMC_HS2005;
726 break;
727 default:
728 return 0;
729 }
730 }
731
732 DPRINTF(("%s: execute tuning for timing %d\n", DEVNAME(sc),
733 timing));
734
735 return sdmmc_chip_execute_tuning(sc->sct, sc->sch, timing)((sc->sct)->execute_tuning((sc->sch), (timing)));
736}
737
738int
739sdmmc_mem_sd_init(struct sdmmc_softc *sc, struct sdmmc_function *sf)
740{
741 int support_func, best_func, error, i;
742 sdmmc_bitfield512_t status; /* Switch Function Status */
743 uint32_t raw_scr[2];
744
745 /*
746 * All SD cards are supposed to support Default Speed mode
747 * with frequencies up to 25 MHz. Bump up the clock frequency
748 * now as data transfers don't seem to work on the Realtek
749 * RTS5229 host controller if it is running at a low clock
750 * frequency. Reading the SCR requires a data transfer.
751 */
752 error = sdmmc_chip_bus_clock(sc->sct, sc->sch, SDMMC_SDCLK_25MHZ,((sc->sct)->bus_clock((sc->sch), (25000), (0)))
753 SDMMC_TIMING_LEGACY)((sc->sct)->bus_clock((sc->sch), (25000), (0)));
754 if (error) {
755 printf("%s: can't change bus clock\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
756 return error;
757 }
758
759 error = sdmmc_mem_send_scr(sc, raw_scr);
760 if (error) {
761 printf("%s: SD_SEND_SCR send failed\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
762 return error;
763 }
764 error = sdmmc_mem_decode_scr(sc, raw_scr, sf);
765 if (error)
766 return error;
767
768 if (ISSET(sc->sc_caps, SMC_CAPS_4BIT_MODE)((sc->sc_caps) & (0x0002)) &&
769 ISSET(sf->scr.bus_width, SCR_SD_BUS_WIDTHS_4BIT)((sf->scr.bus_width) & ((1 << 2)))) {
770 DPRINTF(("%s: change bus width\n", DEVNAME(sc)));
771 error = sdmmc_mem_set_bus_width(sf, 4);
772 if (error) {
773 printf("%s: can't change bus width\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
774 return error;
775 }
776 }
777
778 best_func = 0;
779 if (sf->scr.sd_spec >= SCR_SD_SPEC_VER_1_101 &&
780 ISSET(sf->csd.ccc, SD_CSD_CCC_SWITCH)((sf->csd.ccc) & ((1 << 10)))) {
781 DPRINTF(("%s: switch func mode 0\n", DEVNAME(sc)));
782 error = sdmmc_mem_sd_switch(sf, 0, 1, 0, &status);
783 if (error) {
784 printf("%s: switch func mode 0 failed\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
785 return error;
786 }
787
788 support_func = SFUNC_STATUS_GROUP(&status, 1)(__bitfield((uint32_t *)(&status), 400 + (1 - 1) * 16, 16
))
;
789
790 if (!ISSET(sc->sc_flags, SMF_UHS_MODE)((sc->sc_flags) & (0x0010)) &&
791 (ISSET(support_func, 1 << SD_ACCESS_MODE_SDR50)((support_func) & (1 << 2)) ||
792 ISSET(support_func, 1 << SD_ACCESS_MODE_DDR50)((support_func) & (1 << 4)) ||
793 ISSET(support_func, 1 << SD_ACCESS_MODE_SDR104)((support_func) & (1 << 3)))) {
794 /* XXX UHS-I card started in 1.8V mode, switch now */
795 error = sdmmc_mem_signal_voltage(sc,
796 SDMMC_SIGNAL_VOLTAGE_1801);
797 if (error) {
798 printf("%s: failed to recover UHS card\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
799 return error;
800 }
801 SET(sc->sc_flags, SMF_UHS_MODE)((sc->sc_flags) |= (0x0010));
802 }
803
804 for (i = 0; i < nitems(switch_group0_functions)(sizeof((switch_group0_functions)) / sizeof((switch_group0_functions
)[0]))
; i++) {
805 if (!(support_func & (1 << i)))
806 continue;
807 DPRINTF(("%s: card supports mode %s\n",
808 DEVNAME(sc),
809 switch_group0_functions[i].name));
810 }
811
812 best_func = sdmmc_mem_select_transfer_mode(sc, support_func);
813
814 DPRINTF(("%s: using mode %s\n", DEVNAME(sc),
815 switch_group0_functions[best_func].name));
816 }
817
818 if (best_func != 0) {
819 DPRINTF(("%s: switch func mode 1(func=%d)\n",
820 DEVNAME(sc), best_func));
821 error =
822 sdmmc_mem_sd_switch(sf, 1, 1, best_func, &status);
823 if (error) {
824 printf("%s: switch func mode 1 failed:"
825 " group 1 function %d(0x%2x)\n",
826 DEVNAME(sc)((sc)->sc_dev.dv_xname), best_func, support_func);
827 return error;
828 }
829 sf->csd.tran_speed =
830 switch_group0_functions[best_func].freq;
831
832 /* Wait 400KHz x 8 clock (2.5us * 8 + slop) */
833 delay(25)(*delay_func)(25);
834
835 /* change bus clock */
836 error = sdmmc_chip_bus_clock(sc->sct, sc->sch,((sc->sct)->bus_clock((sc->sch), (sf->csd.tran_speed
), (1)))
837 sf->csd.tran_speed, SDMMC_TIMING_HIGHSPEED)((sc->sct)->bus_clock((sc->sch), (sf->csd.tran_speed
), (1)))
;
838 if (error) {
839 printf("%s: can't change bus clock\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
840 return error;
841 }
842
843 /* execute tuning (UHS) */
844 error = sdmmc_mem_execute_tuning(sc, sf);
845 if (error) {
846 printf("%s: can't execute SD tuning\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
847 return error;
848 }
849 }
850
851 return 0;
852}
853
854int
855sdmmc_mem_mmc_init(struct sdmmc_softc *sc, struct sdmmc_function *sf)
856{
857 int width, value;
858 int card_type;
859 int error = 0;
860 u_int8_t ext_csd[512];
861 int speed = 20000;
862 int timing = SDMMC_TIMING_LEGACY0;
863 u_int32_t sectors = 0;
864
865 error = sdmmc_chip_bus_clock(sc->sct, sc->sch, speed, timing)((sc->sct)->bus_clock((sc->sch), (speed), (timing)));
866 if (error) {
867 printf("%s: can't change bus clock\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
868 return error;
869 }
870
871 if (sf->csd.mmcver >= MMC_CSD_MMCVER_4_04) {
872 /* read EXT_CSD */
873 error = sdmmc_mem_send_cxd_data(sc,
874 MMC_SEND_EXT_CSD8, ext_csd, sizeof(ext_csd));
875 if (error != 0) {
876 SET(sf->flags, SFF_ERROR)((sf->flags) |= (0x0001));
877 printf("%s: can't read EXT_CSD\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
878 return error;
879 }
880
881 card_type = ext_csd[EXT_CSD_CARD_TYPE196];
882
883 if (card_type & EXT_CSD_CARD_TYPE_F_HS200_1_8V(1 << 4) &&
884 ISSET(sc->sc_caps, SMC_CAPS_MMC_HS200)((sc->sc_caps) & (0x4000))) {
885 speed = 200000;
886 timing = SDMMC_TIMING_MMC_HS2005;
887 } else if (card_type & EXT_CSD_CARD_TYPE_F_DDR52_1_8V(1 << 2) &&
888 ISSET(sc->sc_caps, SMC_CAPS_MMC_DDR52)((sc->sc_caps) & (0x2000))) {
889 speed = 52000;
890 timing = SDMMC_TIMING_MMC_DDR524;
891 } else if (card_type & EXT_CSD_CARD_TYPE_F_52M(1 << 1) &&
892 ISSET(sc->sc_caps, SMC_CAPS_MMC_HIGHSPEED)((sc->sc_caps) & (0x0200))) {
893 speed = 52000;
894 timing = SDMMC_TIMING_HIGHSPEED1;
895 } else if (card_type & EXT_CSD_CARD_TYPE_F_26M(1 << 0)) {
896 speed = 26000;
897 } else {
898 printf("%s: unknown CARD_TYPE 0x%x\n", DEVNAME(sc)((sc)->sc_dev.dv_xname),
899 ext_csd[EXT_CSD_CARD_TYPE196]);
900 }
901
902 if (ISSET(sc->sc_caps, SMC_CAPS_8BIT_MODE)((sc->sc_caps) & (0x0040))) {
903 width = 8;
904 value = EXT_CSD_BUS_WIDTH_82;
905 } else if (ISSET(sc->sc_caps, SMC_CAPS_4BIT_MODE)((sc->sc_caps) & (0x0002))) {
906 width = 4;
907 value = EXT_CSD_BUS_WIDTH_41;
908 } else {
909 width = 1;
910 value = EXT_CSD_BUS_WIDTH_10;
911 }
912
913 if (width != 1) {
914 error = sdmmc_mem_mmc_switch(sf, EXT_CSD_CMD_SET_NORMAL(1U << 0),
915 EXT_CSD_BUS_WIDTH183, value);
916 if (error == 0)
917 error = sdmmc_chip_bus_width(sc->sct,((sc->sct)->bus_width((sc->sch), (width)))
918 sc->sch, width)((sc->sct)->bus_width((sc->sch), (width)));
919 else {
920 DPRINTF(("%s: can't change bus width"
921 " (%d bit)\n", DEVNAME(sc), width));
922 return error;
923 }
924
925 /* XXXX: need bus test? (using by CMD14 & CMD19) */
926 sdmmc_delay(10000);
927 }
928
929 if (timing != SDMMC_TIMING_LEGACY0) {
930 switch (timing) {
931 case SDMMC_TIMING_MMC_HS2005:
932 value = EXT_CSD_HS_TIMING_HS2002;
933 break;
934 case SDMMC_TIMING_MMC_DDR524:
935 case SDMMC_TIMING_HIGHSPEED1:
936 value = EXT_CSD_HS_TIMING_HS1;
937 break;
938 }
939
940 /* switch to high speed timing */
941 error = sdmmc_mem_mmc_switch(sf, EXT_CSD_CMD_SET_NORMAL(1U << 0),
942 EXT_CSD_HS_TIMING185, value);
943 if (error != 0) {
944 printf("%s: can't change timing\n",
945 DEVNAME(sc)((sc)->sc_dev.dv_xname));
946 return error;
947 }
948
949 sdmmc_delay(10000);
950 }
951
952 KASSERT(timing < nitems(sdmmc_mmc_timings))((timing < (sizeof((sdmmc_mmc_timings)) / sizeof((sdmmc_mmc_timings
)[0]))) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/sdmmc/sdmmc_mem.c"
, 952, "timing < nitems(sdmmc_mmc_timings)"))
;
953 sf->csd.tran_speed = sdmmc_mmc_timings[timing];
954
955 if (timing != SDMMC_TIMING_LEGACY0) {
956 /* read EXT_CSD again */
957 error = sdmmc_mem_send_cxd_data(sc,
958 MMC_SEND_EXT_CSD8, ext_csd, sizeof(ext_csd));
959 if (error != 0) {
960 printf("%s: can't re-read EXT_CSD\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
961 return error;
962 }
963 if (ext_csd[EXT_CSD_HS_TIMING185] != value) {
964 printf("%s, HS_TIMING set failed\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
965 return EINVAL22;
966 }
967 }
968
969 error = sdmmc_chip_bus_clock(sc->sct, sc->sch, speed, SDMMC_TIMING_HIGHSPEED)((sc->sct)->bus_clock((sc->sch), (speed), (1)));
970 if (error != 0) {
971 printf("%s: can't change bus clock\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
972 return error;
973 }
974
975 if (timing == SDMMC_TIMING_MMC_DDR524) {
976 switch (width) {
977 case 4:
978 value = EXT_CSD_BUS_WIDTH_4_DDR5;
979 break;
980 case 8:
981 value = EXT_CSD_BUS_WIDTH_8_DDR6;
982 break;
983 }
984
985 error = sdmmc_mem_mmc_switch(sf, EXT_CSD_CMD_SET_NORMAL(1U << 0),
986 EXT_CSD_BUS_WIDTH183, value);
987 if (error) {
988 printf("%s: can't switch to DDR\n",
989 DEVNAME(sc)((sc)->sc_dev.dv_xname));
990 return error;
991 }
992
993 sdmmc_delay(10000);
994
995 error = sdmmc_chip_signal_voltage(sc->sct, sc->sch,((sc->sct)->signal_voltage((sc->sch), (1)))
996 SDMMC_SIGNAL_VOLTAGE_180)((sc->sct)->signal_voltage((sc->sch), (1)));
997 if (error) {
998 printf("%s: can't switch signalling voltage\n",
999 DEVNAME(sc)((sc)->sc_dev.dv_xname));
1000 return error;
1001 }
1002
1003 error = sdmmc_chip_bus_clock(sc->sct, sc->sch, speed, timing)((sc->sct)->bus_clock((sc->sch), (speed), (timing)));
1004 if (error != 0) {
1005 printf("%s: can't change bus clock\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
1006 return error;
1007 }
1008
1009 sdmmc_delay(10000);
1010 }
1011
1012 sectors = ext_csd[EXT_CSD_SEC_COUNT212 + 0] << 0 |
1013 ext_csd[EXT_CSD_SEC_COUNT212 + 1] << 8 |
1014 ext_csd[EXT_CSD_SEC_COUNT212 + 2] << 16 |
1015 ext_csd[EXT_CSD_SEC_COUNT212 + 3] << 24;
1016
1017 if (sectors > (2u * 1024 * 1024 * 1024) / 512) {
1018 sf->flags |= SFF_SDHC0x0002;
1019 sf->csd.capacity = sectors;
1020 }
1021
1022 if (timing == SDMMC_TIMING_MMC_HS2005) {
1023 /* execute tuning (HS200) */
1024 error = sdmmc_mem_execute_tuning(sc, sf);
1025 if (error) {
1026 printf("%s: can't execute MMC tuning\n", DEVNAME(sc)((sc)->sc_dev.dv_xname));
1027 return error;
1028 }
1029 }
1030 }
1031
1032 return error;
1033}
1034
1035/*
1036 * Get or set the card's memory OCR value (SD or MMC).
1037 */
1038int
1039sdmmc_mem_send_op_cond(struct sdmmc_softc *sc, u_int32_t ocr,
1040 u_int32_t *ocrp)
1041{
1042 struct sdmmc_command cmd;
1043 int error;
1044 int i;
1045
1046 rw_assert_wrlock(&sc->sc_lock);
1047
1048 /*
1049 * If we change the OCR value, retry the command until the OCR
1050 * we receive in response has the "CARD BUSY" bit set, meaning
1051 * that all cards are ready for identification.
1052 */
1053 for (i = 0; i < 100; i++) {
1054 bzero(&cmd, sizeof cmd)__builtin_bzero((&cmd), (sizeof cmd));
1055 cmd.c_arg = ocr;
1056 cmd.c_flags = SCF_CMD_BCR0x0030 | SCF_RSP_R3(0x1000);
1057
1058 if (ISSET(sc->sc_flags, SMF_SD_MODE)((sc->sc_flags) & (0x0001))) {
1059 cmd.c_opcode = SD_APP_OP_COND41;
1060 error = sdmmc_app_command(sc, &cmd);
1061 } else {
1062 cmd.c_arg &= ~MMC_OCR_ACCESS_MODE_MASK(3<<29);
1063 cmd.c_arg |= MMC_OCR_ACCESS_MODE_SECTOR(2<<29);
1064 cmd.c_opcode = MMC_SEND_OP_COND1;
1065 error = sdmmc_mmc_command(sc, &cmd);
1066 }
1067 if (error != 0)
1068 break;
1069 if (ISSET(MMC_R3(cmd.c_resp), MMC_OCR_MEM_READY)((((cmd.c_resp)[0])) & ((1<<31))) ||
1070 ocr == 0)
1071 break;
1072 error = ETIMEDOUT60;
1073 sdmmc_delay(10000);
1074 }
1075 if (error == 0 && ocrp != NULL((void *)0))
1076 *ocrp = MMC_R3(cmd.c_resp)((cmd.c_resp)[0]);
1077
1078 return error;
1079}
1080
1081/*
1082 * Set the read block length appropriately for this card, according to
1083 * the card CSD register value.
1084 */
1085int
1086sdmmc_mem_set_blocklen(struct sdmmc_softc *sc, struct sdmmc_function *sf)
1087{
1088 struct sdmmc_command cmd;
1089
1090 rw_assert_wrlock(&sc->sc_lock);
1091
1092 bzero(&cmd, sizeof cmd)__builtin_bzero((&cmd), (sizeof cmd));
1093 cmd.c_opcode = MMC_SET_BLOCKLEN16;
1094 cmd.c_arg = sf->csd.sector_size;
1095 cmd.c_flags = SCF_CMD_AC0x0000 | SCF_RSP_R1(0x1000|0x0400|0x0800);
1096 DPRINTF(("%s: read_bl_len=%d sector_size=%d\n", DEVNAME(sc),
1097 1 << sf->csd.read_bl_len, sf->csd.sector_size));
1098
1099 return sdmmc_mmc_command(sc, &cmd);
1100}
1101
1102int
1103sdmmc_mem_read_block_subr(struct sdmmc_function *sf, bus_dmamap_t dmap,
1104 int blkno, u_char *data, size_t datalen)
1105{
1106 struct sdmmc_softc *sc = sf->sc;
1107 struct sdmmc_command cmd;
1108 int error;
1109
1110
1111 if ((error = sdmmc_select_card(sc, sf)) != 0)
1112 goto err;
1113
1114 bzero(&cmd, sizeof cmd)__builtin_bzero((&cmd), (sizeof cmd));
1115 cmd.c_data = data;
1116 cmd.c_datalen = datalen;
1117 cmd.c_blklen = sf->csd.sector_size;
1118 cmd.c_opcode = (datalen / cmd.c_blklen) > 1 ?
1119 MMC_READ_BLOCK_MULTIPLE18 : MMC_READ_BLOCK_SINGLE17;
1120 if (sf->flags & SFF_SDHC0x0002)
1121 cmd.c_arg = blkno;
1122 else
1123 cmd.c_arg = blkno << 9;
1124 cmd.c_flags = SCF_CMD_ADTC0x0010 | SCF_CMD_READ0x0040 | SCF_RSP_R1(0x1000|0x0400|0x0800);
1125 cmd.c_dmamap = dmap;
1126
1127 error = sdmmc_mmc_command(sc, &cmd);
1128 if (error != 0)
1129 goto err;
1130
1131 if (ISSET(sc->sc_flags, SMF_STOP_AFTER_MULTIPLE)((sc->sc_flags) & (0x0080)) &&
1132 cmd.c_opcode == MMC_READ_BLOCK_MULTIPLE18) {
1133 bzero(&cmd, sizeof cmd)__builtin_bzero((&cmd), (sizeof cmd));
1134 cmd.c_opcode = MMC_STOP_TRANSMISSION12;
1135 cmd.c_arg = MMC_ARG_RCA(sf->rca)((sf->rca) << 16);
1136 cmd.c_flags = SCF_CMD_AC0x0000 | SCF_RSP_R1B(0x1000|0x0400|0x0800|0x0100);
1137 error = sdmmc_mmc_command(sc, &cmd);
1138 if (error != 0)
1139 goto err;
1140 }
1141
1142 do {
1143 bzero(&cmd, sizeof cmd)__builtin_bzero((&cmd), (sizeof cmd));
1144 cmd.c_opcode = MMC_SEND_STATUS13;
1145 cmd.c_arg = MMC_ARG_RCA(sf->rca)((sf->rca) << 16);
1146 cmd.c_flags = SCF_CMD_AC0x0000 | SCF_RSP_R1(0x1000|0x0400|0x0800);
1147 error = sdmmc_mmc_command(sc, &cmd);
1148 if (error != 0)
1149 break;
1150 /* XXX time out */
1151 } while (!ISSET(MMC_R1(cmd.c_resp), MMC_R1_READY_FOR_DATA)((((cmd.c_resp)[0])) & ((1<<8))));
1152
1153err:
1154 return (error);
1155}
1156
1157int
1158sdmmc_mem_single_read_block(struct sdmmc_function *sf, int blkno, u_char *data,
1159 size_t datalen)
1160{
1161 int error = 0;
1162 int i;
1163
1164 for (i = 0; i < datalen / sf->csd.sector_size; i++) {
1165 error = sdmmc_mem_read_block_subr(sf, NULL((void *)0), blkno + i,
1166 data + i * sf->csd.sector_size, sf->csd.sector_size);
1167 if (error)
1168 break;
1169 }
1170
1171 return (error);
1172}
1173
1174int
1175sdmmc_mem_read_block(struct sdmmc_function *sf, int blkno, u_char *data,
1176 size_t datalen)
1177{
1178 struct sdmmc_softc *sc = sf->sc;
1179 int error;
1180
1181 rw_enter_write(&sc->sc_lock);
1182
1183 if (ISSET(sc->sc_caps, SMC_CAPS_SINGLE_ONLY)((sc->sc_caps) & (0x0020))) {
1184 error = sdmmc_mem_single_read_block(sf, blkno, data, datalen);
1185 goto out;
1186 }
1187
1188 if (!ISSET(sc->sc_caps, SMC_CAPS_DMA)((sc->sc_caps) & (0x0004))) {
1189 error = sdmmc_mem_read_block_subr(sf, NULL((void *)0), blkno,
1190 data, datalen);
1191 goto out;
1192 }
1193
1194 /* DMA transfer */
1195 error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmap, data, datalen,(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (sc->
sc_dmap), (data), (datalen), (((void *)0)), (0x0001|0x0200))
1196 NULL, BUS_DMA_NOWAIT|BUS_DMA_READ)(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (sc->
sc_dmap), (data), (datalen), (((void *)0)), (0x0001|0x0200))
;
1197 if (error)
1198 goto out;
1199
1200 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmap, 0, datalen,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_dmap), (0), (datalen), (0x01))
1201 BUS_DMASYNC_PREREAD)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_dmap), (0), (datalen), (0x01))
;
1202
1203 error = sdmmc_mem_read_block_subr(sf, sc->sc_dmap, blkno, data,
1204 datalen);
1205 if (error)
1206 goto unload;
1207
1208 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmap, 0, datalen,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_dmap), (0), (datalen), (0x02))
1209 BUS_DMASYNC_POSTREAD)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_dmap), (0), (datalen), (0x02))
;
1210unload:
1211 bus_dmamap_unload(sc->sc_dmat, sc->sc_dmap)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (sc->
sc_dmap))
;
1212
1213out:
1214 rw_exit(&sc->sc_lock);
1215 return (error);
1216}
1217
1218int
1219sdmmc_mem_write_block_subr(struct sdmmc_function *sf, bus_dmamap_t dmap,
1220 int blkno, u_char *data, size_t datalen)
1221{
1222 struct sdmmc_softc *sc = sf->sc;
1223 struct sdmmc_command cmd;
1224 int error;
1225
1226 if ((error = sdmmc_select_card(sc, sf)) != 0)
1227 goto err;
1228
1229 bzero(&cmd, sizeof cmd)__builtin_bzero((&cmd), (sizeof cmd));
1230 cmd.c_data = data;
1231 cmd.c_datalen = datalen;
1232 cmd.c_blklen = sf->csd.sector_size;
1233 cmd.c_opcode = (datalen / cmd.c_blklen) > 1 ?
1234 MMC_WRITE_BLOCK_MULTIPLE25 : MMC_WRITE_BLOCK_SINGLE24;
1235 if (sf->flags & SFF_SDHC0x0002)
1236 cmd.c_arg = blkno;
1237 else
1238 cmd.c_arg = blkno << 9;
1239 cmd.c_flags = SCF_CMD_ADTC0x0010 | SCF_RSP_R1(0x1000|0x0400|0x0800);
1240 cmd.c_dmamap = dmap;
1241
1242 error = sdmmc_mmc_command(sc, &cmd);
1243 if (error != 0)
1244 goto err;
1245
1246 if (ISSET(sc->sc_flags, SMF_STOP_AFTER_MULTIPLE)((sc->sc_flags) & (0x0080)) &&
1247 cmd.c_opcode == MMC_WRITE_BLOCK_MULTIPLE25) {
1248 bzero(&cmd, sizeof cmd)__builtin_bzero((&cmd), (sizeof cmd));
1249 cmd.c_opcode = MMC_STOP_TRANSMISSION12;
1250 cmd.c_flags = SCF_CMD_AC0x0000 | SCF_RSP_R1B(0x1000|0x0400|0x0800|0x0100);
1251 error = sdmmc_mmc_command(sc, &cmd);
1252 if (error != 0)
1253 goto err;
1254 }
1255
1256 do {
1257 bzero(&cmd, sizeof cmd)__builtin_bzero((&cmd), (sizeof cmd));
1258 cmd.c_opcode = MMC_SEND_STATUS13;
1259 cmd.c_arg = MMC_ARG_RCA(sf->rca)((sf->rca) << 16);
1260 cmd.c_flags = SCF_CMD_AC0x0000 | SCF_RSP_R1(0x1000|0x0400|0x0800);
1261 error = sdmmc_mmc_command(sc, &cmd);
1262 if (error != 0)
1263 break;
1264 /* XXX time out */
1265 } while (!ISSET(MMC_R1(cmd.c_resp), MMC_R1_READY_FOR_DATA)((((cmd.c_resp)[0])) & ((1<<8))));
1266
1267err:
1268 return (error);
1269}
1270
1271int
1272sdmmc_mem_single_write_block(struct sdmmc_function *sf, int blkno, u_char *data,
1273 size_t datalen)
1274{
1275 int error = 0;
1276 int i;
1277
1278 for (i = 0; i < datalen / sf->csd.sector_size; i++) {
1279 error = sdmmc_mem_write_block_subr(sf, NULL((void *)0), blkno + i,
1280 data + i * sf->csd.sector_size, sf->csd.sector_size);
1281 if (error)
1282 break;
1283 }
1284
1285 return (error);
1286}
1287
1288int
1289sdmmc_mem_write_block(struct sdmmc_function *sf, int blkno, u_char *data,
1290 size_t datalen)
1291{
1292 struct sdmmc_softc *sc = sf->sc;
1293 int error;
1294
1295 rw_enter_write(&sc->sc_lock);
1296
1297 if (ISSET(sc->sc_caps, SMC_CAPS_SINGLE_ONLY)((sc->sc_caps) & (0x0020))) {
1298 error = sdmmc_mem_single_write_block(sf, blkno, data, datalen);
1299 goto out;
1300 }
1301
1302 if (!ISSET(sc->sc_caps, SMC_CAPS_DMA)((sc->sc_caps) & (0x0004))) {
1303 error = sdmmc_mem_write_block_subr(sf, NULL((void *)0), blkno,
1304 data, datalen);
1305 goto out;
1306 }
1307
1308 /* DMA transfer */
1309 error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmap, data, datalen,(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (sc->
sc_dmap), (data), (datalen), (((void *)0)), (0x0001|0x0400))
1310 NULL, BUS_DMA_NOWAIT|BUS_DMA_WRITE)(*(sc->sc_dmat)->_dmamap_load)((sc->sc_dmat), (sc->
sc_dmap), (data), (datalen), (((void *)0)), (0x0001|0x0400))
;
1311 if (error)
1312 goto out;
1313
1314 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmap, 0, datalen,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_dmap), (0), (datalen), (0x04))
1315 BUS_DMASYNC_PREWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_dmap), (0), (datalen), (0x04))
;
1316
1317 error = sdmmc_mem_write_block_subr(sf, sc->sc_dmap, blkno, data,
1318 datalen);
1319 if (error)
1320 goto unload;
1321
1322 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmap, 0, datalen,(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_dmap), (0), (datalen), (0x08))
1323 BUS_DMASYNC_POSTWRITE)(*(sc->sc_dmat)->_dmamap_sync)((sc->sc_dmat), (sc->
sc_dmap), (0), (datalen), (0x08))
;
1324unload:
1325 bus_dmamap_unload(sc->sc_dmat, sc->sc_dmap)(*(sc->sc_dmat)->_dmamap_unload)((sc->sc_dmat), (sc->
sc_dmap))
;
1326
1327out:
1328 rw_exit(&sc->sc_lock);
1329 return (error);
1330}
1331
1332#ifdef HIBERNATE1
1333int
1334sdmmc_mem_hibernate_write(struct sdmmc_function *sf, daddr_t blkno,
1335 u_char *data, size_t datalen)
1336{
1337 struct sdmmc_softc *sc = sf->sc;
1338 int i, error;
1339 struct bus_dmamap dmamap;
1340 paddr_t phys_addr;
1341
1342 if (ISSET(sc->sc_caps, SMC_CAPS_SINGLE_ONLY)((sc->sc_caps) & (0x0020))) {
1343 for (i = 0; i < datalen / sf->csd.sector_size; i++) {
1344 error = sdmmc_mem_write_block_subr(sf, NULL((void *)0), blkno + i,
1345 data + i * sf->csd.sector_size,
1346 sf->csd.sector_size);
1347 if (error)
1348 return (error);
1349 }
1350 } else if (!ISSET(sc->sc_caps, SMC_CAPS_DMA)((sc->sc_caps) & (0x0004))) {
1351 return (sdmmc_mem_write_block_subr(sf, NULL((void *)0), blkno, data,
1352 datalen));
1353 }
1354
1355 /* pretend we're bus_dmamap_load */
1356 bzero(&dmamap, sizeof(dmamap))__builtin_bzero((&dmamap), (sizeof(dmamap)));
1357 pmap_extract(pmap_kernel()(&kernel_pmap_store), (vaddr_t)data, &phys_addr);
1358 dmamap.dm_mapsize = datalen;
1359 dmamap.dm_nsegs = 1;
1360 dmamap.dm_segs[0].ds_addr = phys_addr;
1361 dmamap.dm_segs[0].ds_len = datalen;
1362 return (sdmmc_mem_write_block_subr(sf, &dmamap, blkno, data, datalen));
1363}
1364#endif