FreeBSD kernel CAM code
mmc_da.c
Go to the documentation of this file.
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2006 Bernd Walter <tisco@FreeBSD.org> All rights reserved.
5 * Copyright (c) 2009 Alexander Motin <mav@FreeBSD.org> All rights reserved.
6 * Copyright (c) 2015-2017 Ilya Bakulin <kibab@FreeBSD.org> All rights reserved.
7 * Copyright (c) 2006 M. Warner Losh <imp@FreeBSD.org>
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer,
14 * without modification, immediately at the beginning of the file.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * Some code derived from the sys/dev/mmc and sys/cam/ata
31 * Thanks to Warner Losh <imp@FreeBSD.org>, Alexander Motin <mav@FreeBSD.org>
32 * Bernd Walter <tisco@FreeBSD.org>, and other authors.
33 */
34
35#include <sys/cdefs.h>
36__FBSDID("$FreeBSD$");
37
38//#include "opt_sdda.h"
39
40#include <sys/param.h>
41
42#ifdef _KERNEL
43#include <sys/systm.h>
44#include <sys/kernel.h>
45#include <sys/bio.h>
46#include <sys/sysctl.h>
47#include <sys/endian.h>
48#include <sys/taskqueue.h>
49#include <sys/lock.h>
50#include <sys/mutex.h>
51#include <sys/conf.h>
52#include <sys/devicestat.h>
53#include <sys/eventhandler.h>
54#include <sys/malloc.h>
55#include <sys/cons.h>
56#include <sys/proc.h>
57#include <sys/reboot.h>
58#include <geom/geom_disk.h>
59#include <machine/_inttypes.h> /* for PRIu64 */
60#endif /* _KERNEL */
61
62#ifndef _KERNEL
63#include <stdio.h>
64#include <string.h>
65#endif /* _KERNEL */
66
67#include <cam/cam.h>
68#include <cam/cam_ccb.h>
69#include <cam/cam_queue.h>
70#include <cam/cam_periph.h>
71#include <cam/cam_sim.h>
72#include <cam/cam_xpt.h>
73#include <cam/cam_xpt_sim.h>
74#include <cam/cam_xpt_periph.h>
76#include <cam/cam_debug.h>
77
78#include <cam/mmc/mmc_all.h>
79
80#ifdef _KERNEL
81
82typedef enum {
84 SDDA_FLAG_DIRTY = 0x0004
86
87typedef enum {
93
94#define SDDA_FMT_BOOT "sdda%dboot"
95#define SDDA_FMT_GP "sdda%dgp"
96#define SDDA_FMT_RPMB "sdda%drpmb"
97#define SDDA_LABEL_ENH "enh"
98
99#define SDDA_PART_NAMELEN (16 + 1)
100
101struct sdda_softc;
102
103struct sdda_part {
104 struct disk *disk;
105 struct bio_queue_head bio_queue;
107 struct sdda_softc *sc;
108 u_int cnt;
109 u_int type;
110 bool ro;
112};
113
115 int outstanding_cmds; /* Number of active commands */
116 int refcount; /* Active xpt_action() calls */
118 struct mmc_data *mmcdata;
120// sdda_quirks quirks;
121 struct task start_init_task;
122 uint32_t raw_csd[4];
123 uint8_t raw_ext_csd[512]; /* MMC only? */
124 struct mmc_csd csd;
125 struct mmc_cid cid;
126 struct mmc_scr scr;
127 /* Calculated from CSD */
128 uint64_t sector_count;
129 uint64_t mediasize;
130
131 /* Calculated from CID */
132 char card_id_string[64];/* Formatted CID info (serial, MFG, etc) */
133 char card_sn_string[16];/* Formatted serial # for disk->d_ident */
134 /* Determined from CSD + is highspeed card*/
135 uint32_t card_f_max;
136
137 /* Generic switch timeout */
138 uint32_t cmd6_time;
139 uint32_t timings; /* Mask of bus timings supported */
140 uint32_t vccq_120; /* Mask of bus timings at VCCQ of 1.2 V */
141 uint32_t vccq_180; /* Mask of bus timings at VCCQ of 1.8 V */
142 /* MMC partitions support */
143 struct sdda_part *part[MMC_PART_MAX];
144 uint8_t part_curr; /* Partition currently switched to */
145 uint8_t part_requested; /* What partition we're currently switching to */
146 uint32_t part_time; /* Partition switch timeout [us] */
147 off_t enh_base; /* Enhanced user data area slice base ... */
148 off_t enh_size; /* ... and size [bytes] */
150 struct timeval log_time;
151};
152
153static const char *mmc_errmsg[] =
154{
155 "None",
156 "Timeout",
157 "Bad CRC",
158 "Fifo",
159 "Failed",
160 "Invalid",
161 "NO MEMORY"
162};
163
164#define ccb_bp ppriv_ptr1
165
166static disk_strategy_t sddastrategy;
167static dumper_t sddadump;
169static void sddaasync(void *callback_arg, u_int32_t code,
170 struct cam_path *path, void *arg);
175static void sddadone(struct cam_periph *periph,
176 union ccb *done_ccb);
177static int sddaerror(union ccb *ccb, u_int32_t cam_flags,
178 u_int32_t sense_flags);
179
180static int mmc_handle_reply(union ccb *ccb);
181static uint16_t get_rca(struct cam_periph *periph);
182static void sdda_start_init(void *context, union ccb *start_ccb);
183static void sdda_start_init_task(void *context, int pending);
184static void sdda_process_mmc_partitions(struct cam_periph *periph, union ccb *start_ccb);
185static uint32_t sdda_get_host_caps(struct cam_periph *periph, union ccb *ccb);
186static int mmc_select_card(struct cam_periph *periph, union ccb *ccb, uint32_t rca);
187static inline uint32_t mmc_get_sector_size(struct cam_periph *periph) {return MMC_SECTOR_SIZE;}
188
189static SYSCTL_NODE(_kern_cam, OID_AUTO, sdda, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
190 "CAM Direct Access Disk driver");
191
192static int sdda_mmcsd_compat = 1;
193SYSCTL_INT(_kern_cam_sdda, OID_AUTO, mmcsd_compat, CTLFLAG_RDTUN,
194 &sdda_mmcsd_compat, 1, "Enable creation of mmcsd aliases.");
195
196/* TODO: actually issue GET_TRAN_SETTINGS to get R/O status */
197static inline bool sdda_get_read_only(struct cam_periph *periph, union ccb *start_ccb)
198{
199
200 return (false);
201}
202
203static uint32_t mmc_get_spec_vers(struct cam_periph *periph);
204static uint64_t mmc_get_media_size(struct cam_periph *periph);
205static uint32_t mmc_get_cmd6_timeout(struct cam_periph *periph);
206static bool sdda_add_part(struct cam_periph *periph, u_int type,
207 const char *name, u_int cnt, off_t media_size, bool ro);
208
210{
211 sddainit, "sdda",
212 TAILQ_HEAD_INITIALIZER(sddadriver.units), /* generation */ 0
213};
214
216
217static MALLOC_DEFINE(M_SDDA, "sd_da", "sd_da buffers");
218
219static const int exp[8] = {
220 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000
221};
222
223static const int mant[16] = {
224 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80
225};
226
227static const int cur_min[8] = {
228 500, 1000, 5000, 10000, 25000, 35000, 60000, 100000
229};
230
231static const int cur_max[8] = {
232 1000, 5000, 10000, 25000, 35000, 45000, 800000, 200000
233};
234
235static uint16_t
236get_rca(struct cam_periph *periph) {
237 return periph->path->device->mmc_ident_data.card_rca;
238}
239
240/*
241 * Figure out if CCB execution resulted in error.
242 * Look at both CAM-level errors and on MMC protocol errors.
243 *
244 * Return value is always MMC error.
245*/
246static int
248{
249 KASSERT(ccb->ccb_h.func_code == XPT_MMC_IO,
250 ("ccb %p: cannot handle non-XPT_MMC_IO errors, got func_code=%d",
252
253 /* CAM-level error should always correspond to MMC-level error */
255 (ccb->mmcio.cmd.error != MMC_ERR_NONE))
256 panic("CCB status is OK but MMC error != MMC_ERR_NONE");
257
258 if (ccb->mmcio.cmd.error != MMC_ERR_NONE) {
260 printf("CMD%d failed, err %d (%s)\n",
261 ccb->mmcio.cmd.opcode,
262 ccb->mmcio.cmd.error,
263 mmc_errmsg[ccb->mmcio.cmd.error]);
264 }
265 return (ccb->mmcio.cmd.error);
266}
267
268static uint32_t
269mmc_get_bits(uint32_t *bits, int bit_len, int start, int size)
270{
271 const int i = (bit_len / 32) - (start / 32) - 1;
272 const int shift = start & 31;
273 uint32_t retval = bits[i] >> shift;
274 if (size + shift > 32)
275 retval |= bits[i - 1] << (32 - shift);
276 return (retval & ((1llu << size) - 1));
277}
278
279static void
280mmc_decode_csd_sd(uint32_t *raw_csd, struct mmc_csd *csd)
281{
282 int v;
283 int m;
284 int e;
285
286 memset(csd, 0, sizeof(*csd));
287 csd->csd_structure = v = mmc_get_bits(raw_csd, 128, 126, 2);
288
289 /* Common members between 1.0 and 2.0 */
290 m = mmc_get_bits(raw_csd, 128, 115, 4);
291 e = mmc_get_bits(raw_csd, 128, 112, 3);
292 csd->tacc = (exp[e] * mant[m] + 9) / 10;
293 csd->nsac = mmc_get_bits(raw_csd, 128, 104, 8) * 100;
294 m = mmc_get_bits(raw_csd, 128, 99, 4);
295 e = mmc_get_bits(raw_csd, 128, 96, 3);
296 csd->tran_speed = exp[e] * 10000 * mant[m];
297 csd->ccc = mmc_get_bits(raw_csd, 128, 84, 12);
298 csd->read_bl_len = 1 << mmc_get_bits(raw_csd, 128, 80, 4);
299 csd->read_bl_partial = mmc_get_bits(raw_csd, 128, 79, 1);
300 csd->write_blk_misalign = mmc_get_bits(raw_csd, 128, 78, 1);
301 csd->read_blk_misalign = mmc_get_bits(raw_csd, 128, 77, 1);
302 csd->dsr_imp = mmc_get_bits(raw_csd, 128, 76, 1);
303 csd->erase_blk_en = mmc_get_bits(raw_csd, 128, 46, 1);
304 csd->erase_sector = mmc_get_bits(raw_csd, 128, 39, 7) + 1;
305 csd->wp_grp_size = mmc_get_bits(raw_csd, 128, 32, 7);
306 csd->wp_grp_enable = mmc_get_bits(raw_csd, 128, 31, 1);
307 csd->r2w_factor = 1 << mmc_get_bits(raw_csd, 128, 26, 3);
308 csd->write_bl_len = 1 << mmc_get_bits(raw_csd, 128, 22, 4);
309 csd->write_bl_partial = mmc_get_bits(raw_csd, 128, 21, 1);
310
311 if (v == 0) {
312 csd->vdd_r_curr_min = cur_min[mmc_get_bits(raw_csd, 128, 59, 3)];
313 csd->vdd_r_curr_max = cur_max[mmc_get_bits(raw_csd, 128, 56, 3)];
314 csd->vdd_w_curr_min = cur_min[mmc_get_bits(raw_csd, 128, 53, 3)];
315 csd->vdd_w_curr_max = cur_max[mmc_get_bits(raw_csd, 128, 50, 3)];
316 m = mmc_get_bits(raw_csd, 128, 62, 12);
317 e = mmc_get_bits(raw_csd, 128, 47, 3);
318 csd->capacity = ((1 + m) << (e + 2)) * csd->read_bl_len;
319 } else if (v == 1) {
320 csd->capacity = ((uint64_t)mmc_get_bits(raw_csd, 128, 48, 22) + 1) *
321 512 * 1024;
322 } else
323 panic("unknown SD CSD version");
324}
325
326static void
327mmc_decode_csd_mmc(uint32_t *raw_csd, struct mmc_csd *csd)
328{
329 int m;
330 int e;
331
332 memset(csd, 0, sizeof(*csd));
333 csd->csd_structure = mmc_get_bits(raw_csd, 128, 126, 2);
334 csd->spec_vers = mmc_get_bits(raw_csd, 128, 122, 4);
335 m = mmc_get_bits(raw_csd, 128, 115, 4);
336 e = mmc_get_bits(raw_csd, 128, 112, 3);
337 csd->tacc = exp[e] * mant[m] + 9 / 10;
338 csd->nsac = mmc_get_bits(raw_csd, 128, 104, 8) * 100;
339 m = mmc_get_bits(raw_csd, 128, 99, 4);
340 e = mmc_get_bits(raw_csd, 128, 96, 3);
341 csd->tran_speed = exp[e] * 10000 * mant[m];
342 csd->ccc = mmc_get_bits(raw_csd, 128, 84, 12);
343 csd->read_bl_len = 1 << mmc_get_bits(raw_csd, 128, 80, 4);
344 csd->read_bl_partial = mmc_get_bits(raw_csd, 128, 79, 1);
345 csd->write_blk_misalign = mmc_get_bits(raw_csd, 128, 78, 1);
346 csd->read_blk_misalign = mmc_get_bits(raw_csd, 128, 77, 1);
347 csd->dsr_imp = mmc_get_bits(raw_csd, 128, 76, 1);
348 csd->vdd_r_curr_min = cur_min[mmc_get_bits(raw_csd, 128, 59, 3)];
349 csd->vdd_r_curr_max = cur_max[mmc_get_bits(raw_csd, 128, 56, 3)];
350 csd->vdd_w_curr_min = cur_min[mmc_get_bits(raw_csd, 128, 53, 3)];
351 csd->vdd_w_curr_max = cur_max[mmc_get_bits(raw_csd, 128, 50, 3)];
352 m = mmc_get_bits(raw_csd, 128, 62, 12);
353 e = mmc_get_bits(raw_csd, 128, 47, 3);
354 csd->capacity = ((1 + m) << (e + 2)) * csd->read_bl_len;
355 csd->erase_blk_en = 0;
356 csd->erase_sector = (mmc_get_bits(raw_csd, 128, 42, 5) + 1) *
357 (mmc_get_bits(raw_csd, 128, 37, 5) + 1);
358 csd->wp_grp_size = mmc_get_bits(raw_csd, 128, 32, 5);
359 csd->wp_grp_enable = mmc_get_bits(raw_csd, 128, 31, 1);
360 csd->r2w_factor = 1 << mmc_get_bits(raw_csd, 128, 26, 3);
361 csd->write_bl_len = 1 << mmc_get_bits(raw_csd, 128, 22, 4);
362 csd->write_bl_partial = mmc_get_bits(raw_csd, 128, 21, 1);
363}
364
365static void
366mmc_decode_cid_sd(uint32_t *raw_cid, struct mmc_cid *cid)
367{
368 int i;
369
370 /* There's no version info, so we take it on faith */
371 memset(cid, 0, sizeof(*cid));
372 cid->mid = mmc_get_bits(raw_cid, 128, 120, 8);
373 cid->oid = mmc_get_bits(raw_cid, 128, 104, 16);
374 for (i = 0; i < 5; i++)
375 cid->pnm[i] = mmc_get_bits(raw_cid, 128, 96 - i * 8, 8);
376 cid->pnm[5] = 0;
377 cid->prv = mmc_get_bits(raw_cid, 128, 56, 8);
378 cid->psn = mmc_get_bits(raw_cid, 128, 24, 32);
379 cid->mdt_year = mmc_get_bits(raw_cid, 128, 12, 8) + 2000;
380 cid->mdt_month = mmc_get_bits(raw_cid, 128, 8, 4);
381}
382
383static void
384mmc_decode_cid_mmc(uint32_t *raw_cid, struct mmc_cid *cid)
385{
386 int i;
387
388 /* There's no version info, so we take it on faith */
389 memset(cid, 0, sizeof(*cid));
390 cid->mid = mmc_get_bits(raw_cid, 128, 120, 8);
391 cid->oid = mmc_get_bits(raw_cid, 128, 104, 8);
392 for (i = 0; i < 6; i++)
393 cid->pnm[i] = mmc_get_bits(raw_cid, 128, 96 - i * 8, 8);
394 cid->pnm[6] = 0;
395 cid->prv = mmc_get_bits(raw_cid, 128, 48, 8);
396 cid->psn = mmc_get_bits(raw_cid, 128, 16, 32);
397 cid->mdt_month = mmc_get_bits(raw_cid, 128, 12, 4);
398 cid->mdt_year = mmc_get_bits(raw_cid, 128, 8, 4) + 1997;
399}
400
401static void
403{
404 char oidstr[8];
405 uint8_t c1;
406 uint8_t c2;
407
408 /*
409 * Format a card ID string for use by the mmcsd driver, it's what
410 * appears between the <> in the following:
411 * mmcsd0: 968MB <SD SD01G 8.0 SN 2686905 Mfg 08/2008 by 3 TN> at mmc0
412 * 22.5MHz/4bit/128-block
413 *
414 * Also format just the card serial number, which the mmcsd driver will
415 * use as the disk->d_ident string.
416 *
417 * The card_id_string in mmc_ivars is currently allocated as 64 bytes,
418 * and our max formatted length is currently 55 bytes if every field
419 * contains the largest value.
420 *
421 * Sometimes the oid is two printable ascii chars; when it's not,
422 * format it as 0xnnnn instead.
423 */
424 c1 = (sc->cid.oid >> 8) & 0x0ff;
425 c2 = sc->cid.oid & 0x0ff;
426 if (c1 > 0x1f && c1 < 0x7f && c2 > 0x1f && c2 < 0x7f)
427 snprintf(oidstr, sizeof(oidstr), "%c%c", c1, c2);
428 else
429 snprintf(oidstr, sizeof(oidstr), "0x%04x", sc->cid.oid);
430 snprintf(sc->card_sn_string, sizeof(sc->card_sn_string),
431 "%08X", sc->cid.psn);
432 snprintf(sc->card_id_string, sizeof(sc->card_id_string),
433 "%s%s %s %d.%d SN %08X MFG %02d/%04d by %d %s",
434 mmcp->card_features & CARD_FEATURE_MMC ? "MMC" : "SD",
435 mmcp->card_features & CARD_FEATURE_SDHC ? "HC" : "",
436 sc->cid.pnm, sc->cid.prv >> 4, sc->cid.prv & 0x0f,
437 sc->cid.psn, sc->cid.mdt_month, sc->cid.mdt_year,
438 sc->cid.mid, oidstr);
439}
440
441static int
442sddaopen(struct disk *dp)
443{
444 struct sdda_part *part;
445 struct cam_periph *periph;
446 struct sdda_softc *softc;
447 int error;
448
449 part = (struct sdda_part *)dp->d_drv1;
450 softc = part->sc;
451 periph = softc->periph;
452 if (cam_periph_acquire(periph) != 0) {
453 return(ENXIO);
454 }
455
456 cam_periph_lock(periph);
457 if ((error = cam_periph_hold(periph, PRIBIO|PCATCH)) != 0) {
458 cam_periph_unlock(periph);
459 cam_periph_release(periph);
460 return (error);
461 }
462
463 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("sddaopen\n"));
464
465 part->flags |= SDDA_FLAG_OPEN;
466
467 cam_periph_unhold(periph);
468 cam_periph_unlock(periph);
469 return (0);
470}
471
472static int
473sddaclose(struct disk *dp)
474{
475 struct sdda_part *part;
476 struct cam_periph *periph;
477 struct sdda_softc *softc;
478
479 part = (struct sdda_part *)dp->d_drv1;
480 softc = part->sc;
481 periph = softc->periph;
482 part->flags &= ~SDDA_FLAG_OPEN;
483
484 cam_periph_lock(periph);
485
486 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("sddaclose\n"));
487
488 while (softc->refcount != 0)
489 cam_periph_sleep(periph, &softc->refcount, PRIBIO, "sddaclose", 1);
490 cam_periph_unlock(periph);
491 cam_periph_release(periph);
492 return (0);
493}
494
495static void
497{
498 struct sdda_softc *softc = (struct sdda_softc *)periph->softc;
499 struct sdda_part *part;
500 struct bio *bp;
501 int i;
502
503 /* Check if we have more work to do. */
504 /* Find partition that has outstanding commands. Prefer current partition. */
505 bp = bioq_first(&softc->part[softc->part_curr]->bio_queue);
506 if (bp == NULL) {
507 for (i = 0; i < MMC_PART_MAX; i++) {
508 if ((part = softc->part[i]) != NULL &&
509 (bp = bioq_first(&softc->part[i]->bio_queue)) != NULL)
510 break;
511 }
512 }
513 if (bp != NULL) {
515 }
516}
517
518/*
519 * Actually translate the requested transfer into one the physical driver
520 * can understand. The transfer is described by a buf and will include
521 * only one physical transfer.
522 */
523static void
524sddastrategy(struct bio *bp)
525{
526 struct cam_periph *periph;
527 struct sdda_part *part;
528 struct sdda_softc *softc;
529
530 part = (struct sdda_part *)bp->bio_disk->d_drv1;
531 softc = part->sc;
532 periph = softc->periph;
533
534 cam_periph_lock(periph);
535
536 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("sddastrategy(%p)\n", bp));
537
538 /*
539 * If the device has been made invalid, error out
540 */
541 if ((periph->flags & CAM_PERIPH_INVALID) != 0) {
542 cam_periph_unlock(periph);
543 biofinish(bp, NULL, ENXIO);
544 return;
545 }
546
547 /*
548 * Place it in the queue of disk activities for this disk
549 */
550 bioq_disksort(&part->bio_queue, bp);
551
552 /*
553 * Schedule ourselves for performing the work.
554 */
555 sddaschedule(periph);
556 cam_periph_unlock(periph);
557
558 return;
559}
560
561static void
562sddainit(void)
563{
564 cam_status status;
565
566 /*
567 * Install a global async callback. This callback will
568 * receive async callbacks like "new device found".
569 */
570 status = xpt_register_async(AC_FOUND_DEVICE, sddaasync, NULL, NULL);
571
572 if (status != CAM_REQ_CMP) {
573 printf("sdda: Failed to attach master async callback "
574 "due to status 0x%x!\n", status);
575 }
576}
577
578/*
579 * Callback from GEOM, called when it has finished cleaning up its
580 * resources.
581 */
582static void
584{
585 struct cam_periph *periph;
586 struct sdda_part *part;
587
588 part = (struct sdda_part *)dp->d_drv1;
589 periph = part->sc->periph;
590 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("sddadiskgonecb\n"));
591
592 cam_periph_release(periph);
593}
594
595static void
597{
598 struct sdda_softc *softc;
599 struct sdda_part *part;
600
601 softc = (struct sdda_softc *)periph->softc;
602
603 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("sddaoninvalidate\n"));
604
605 /*
606 * De-register any async callbacks.
607 */
609
610 /*
611 * Return all queued I/O with ENXIO.
612 * XXX Handle any transactions queued to the card
613 * with XPT_ABORT_CCB.
614 */
615 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("bioq_flush start\n"));
616 for (int i = 0; i < MMC_PART_MAX; i++) {
617 if ((part = softc->part[i]) != NULL) {
618 bioq_flush(&part->bio_queue, NULL, ENXIO);
619 disk_gone(part->disk);
620 }
621 }
622 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("bioq_flush end\n"));
623}
624
625static void
627{
628 struct sdda_softc *softc;
629 struct sdda_part *part;
630 int i;
631
632 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("sddacleanup\n"));
633 softc = (struct sdda_softc *)periph->softc;
634
636
637 for (i = 0; i < MMC_PART_MAX; i++) {
638 if ((part = softc->part[i]) != NULL) {
639 disk_destroy(part->disk);
640 free(part, M_DEVBUF);
641 softc->part[i] = NULL;
642 }
643 }
644 free(softc, M_DEVBUF);
646}
647
648static void
649sddaasync(void *callback_arg, u_int32_t code,
650 struct cam_path *path, void *arg)
651{
652 struct ccb_getdev cgd;
653 struct cam_periph *periph;
654
655 periph = (struct cam_periph *)callback_arg;
656 CAM_DEBUG(path, CAM_DEBUG_TRACE, ("sddaasync(code=%d)\n", code));
657 switch (code) {
658 case AC_FOUND_DEVICE:
659 {
660 CAM_DEBUG(path, CAM_DEBUG_TRACE, ("=> AC_FOUND_DEVICE\n"));
661 struct ccb_getdev *cgd;
662 cam_status status;
663
664 cgd = (struct ccb_getdev *)arg;
665 if (cgd == NULL)
666 break;
667
668 if (cgd->protocol != PROTO_MMCSD)
669 break;
670
672 CAM_DEBUG(path, CAM_DEBUG_TRACE, ("No memory on the card!\n"));
673 break;
674 }
675
676 /*
677 * Allocate a peripheral instance for
678 * this device and start the probe
679 * process.
680 */
683 "sdda", CAM_PERIPH_BIO,
684 path, sddaasync,
685 AC_FOUND_DEVICE, cgd);
686
687 if (status != CAM_REQ_CMP
688 && status != CAM_REQ_INPROG)
689 printf("sddaasync: Unable to attach to new device "
690 "due to status 0x%x\n", status);
691 break;
692 }
694 {
695 CAM_DEBUG(path, CAM_DEBUG_TRACE, ("=> AC_GETDEV_CHANGED\n"));
696 memset(&cgd, 0, sizeof(cgd));
699 xpt_action((union ccb *)&cgd);
700 cam_periph_async(periph, code, path, arg);
701 break;
702 }
704 {
705 uintptr_t buftype;
706 int i;
707
708 CAM_DEBUG(path, CAM_DEBUG_TRACE, ("=> AC_ADVINFO_CHANGED\n"));
709 buftype = (uintptr_t)arg;
710 if (buftype == CDAI_TYPE_PHYS_PATH) {
711 struct sdda_softc *softc;
712 struct sdda_part *part;
713
714 softc = periph->softc;
715 for (i = 0; i < MMC_PART_MAX; i++) {
716 if ((part = softc->part[i]) != NULL) {
717 disk_attr_changed(part->disk, "GEOM::physpath",
718 M_NOWAIT);
719 }
720 }
721 }
722 break;
723 }
724 default:
725 CAM_DEBUG(path, CAM_DEBUG_TRACE, ("=> default?!\n"));
726 cam_periph_async(periph, code, path, arg);
727 break;
728 }
729}
730
731static int
732sddagetattr(struct bio *bp)
733{
734 struct cam_periph *periph;
735 struct sdda_softc *softc;
736 struct sdda_part *part;
737 int ret;
738
739 part = (struct sdda_part *)bp->bio_disk->d_drv1;
740 softc = part->sc;
741 periph = softc->periph;
742 cam_periph_lock(periph);
743 ret = xpt_getattr(bp->bio_data, bp->bio_length, bp->bio_attribute,
744 periph->path);
745 cam_periph_unlock(periph);
746 if (ret == 0)
747 bp->bio_completed = bp->bio_length;
748 return (ret);
749}
750
751static cam_status
752sddaregister(struct cam_periph *periph, void *arg)
753{
754 struct sdda_softc *softc;
755 struct ccb_getdev *cgd;
756
757 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("sddaregister\n"));
758 cgd = (struct ccb_getdev *)arg;
759 if (cgd == NULL) {
760 printf("sddaregister: no getdev CCB, can't register device\n");
761 return (CAM_REQ_CMP_ERR);
762 }
763
764 softc = (struct sdda_softc *)malloc(sizeof(*softc), M_DEVBUF,
765 M_NOWAIT|M_ZERO);
766 if (softc == NULL) {
767 printf("sddaregister: Unable to probe new device. "
768 "Unable to allocate softc\n");
769 return (CAM_REQ_CMP_ERR);
770 }
771
772 softc->state = SDDA_STATE_INIT;
773 softc->mmcdata =
774 (struct mmc_data *)malloc(sizeof(struct mmc_data), M_DEVBUF, M_NOWAIT|M_ZERO);
775 if (softc->mmcdata == NULL) {
776 printf("sddaregister: Unable to probe new device. "
777 "Unable to allocate mmcdata\n");
778 free(softc, M_DEVBUF);
779 return (CAM_REQ_CMP_ERR);
780 }
781 periph->softc = softc;
782 softc->periph = periph;
783
785 TASK_INIT(&softc->start_init_task, 0, sdda_start_init_task, periph);
786 taskqueue_enqueue(taskqueue_thread, &softc->start_init_task);
787
788 return (CAM_REQ_CMP);
789}
790
791static int
792mmc_exec_app_cmd(struct cam_periph *periph, union ccb *ccb,
793 struct mmc_command *cmd) {
794 int err;
795
796 /* Send APP_CMD first */
797 memset(&ccb->mmcio.cmd, 0, sizeof(struct mmc_command));
798 memset(&ccb->mmcio.stop, 0, sizeof(struct mmc_command));
800 /*retries*/ 0,
801 /*cbfcnp*/ NULL,
802 /*flags*/ CAM_DIR_NONE,
803 /*mmc_opcode*/ MMC_APP_CMD,
804 /*mmc_arg*/ get_rca(periph) << 16,
805 /*mmc_flags*/ MMC_RSP_R1 | MMC_CMD_AC,
806 /*mmc_data*/ NULL,
807 /*timeout*/ 0);
808
809 cam_periph_runccb(ccb, sddaerror, CAM_FLAG_NONE, /*sense_flags*/0, NULL);
810 err = mmc_handle_reply(ccb);
811 if (err != 0)
812 return (err);
813 if (!(ccb->mmcio.cmd.resp[0] & R1_APP_CMD))
814 return (EIO);
815
816 /* Now exec actual command */
817 int flags = 0;
818 if (cmd->data != NULL) {
819 ccb->mmcio.cmd.data = cmd->data;
820 if (cmd->data->flags & MMC_DATA_READ)
821 flags |= CAM_DIR_IN;
822 if (cmd->data->flags & MMC_DATA_WRITE)
823 flags |= CAM_DIR_OUT;
824 } else flags = CAM_DIR_NONE;
825
827 /*retries*/ 0,
828 /*cbfcnp*/ NULL,
829 /*flags*/ flags,
830 /*mmc_opcode*/ cmd->opcode,
831 /*mmc_arg*/ cmd->arg,
832 /*mmc_flags*/ cmd->flags,
833 /*mmc_data*/ cmd->data,
834 /*timeout*/ 0);
835
836 cam_periph_runccb(ccb, sddaerror, CAM_FLAG_NONE, /*sense_flags*/0, NULL);
837 err = mmc_handle_reply(ccb);
838 if (err != 0)
839 return (err);
840 memcpy(cmd->resp, ccb->mmcio.cmd.resp, sizeof(cmd->resp));
841 cmd->error = ccb->mmcio.cmd.error;
842
843 return (0);
844}
845
846static int
847mmc_app_get_scr(struct cam_periph *periph, union ccb *ccb, uint32_t *rawscr) {
848 int err;
849 struct mmc_command cmd;
850 struct mmc_data d;
851
852 memset(&cmd, 0, sizeof(cmd));
853 memset(&d, 0, sizeof(d));
854
855 memset(rawscr, 0, 8);
856 cmd.opcode = ACMD_SEND_SCR;
857 cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
858 cmd.arg = 0;
859
860 d.data = rawscr;
861 d.len = 8;
862 d.flags = MMC_DATA_READ;
863 cmd.data = &d;
864
865 err = mmc_exec_app_cmd(periph, ccb, &cmd);
866 rawscr[0] = be32toh(rawscr[0]);
867 rawscr[1] = be32toh(rawscr[1]);
868 return (err);
869}
870
871static int
872mmc_send_ext_csd(struct cam_periph *periph, union ccb *ccb,
873 uint8_t *rawextcsd, size_t buf_len) {
874 int err;
875 struct mmc_data d;
876
877 KASSERT(buf_len == 512, ("Buffer for ext csd must be 512 bytes"));
878 memset(&d, 0, sizeof(d));
879 d.data = rawextcsd;
880 d.len = buf_len;
881 d.flags = MMC_DATA_READ;
882 memset(d.data, 0, d.len);
883
885 /*retries*/ 0,
886 /*cbfcnp*/ NULL,
887 /*flags*/ CAM_DIR_IN,
888 /*mmc_opcode*/ MMC_SEND_EXT_CSD,
889 /*mmc_arg*/ 0,
890 /*mmc_flags*/ MMC_RSP_R1 | MMC_CMD_ADTC,
891 /*mmc_data*/ &d,
892 /*timeout*/ 0);
893
894 cam_periph_runccb(ccb, sddaerror, CAM_FLAG_NONE, /*sense_flags*/0, NULL);
895 err = mmc_handle_reply(ccb);
896 return (err);
897}
898
899static void
900mmc_app_decode_scr(uint32_t *raw_scr, struct mmc_scr *scr)
901{
902 unsigned int scr_struct;
903
904 memset(scr, 0, sizeof(*scr));
905
906 scr_struct = mmc_get_bits(raw_scr, 64, 60, 4);
907 if (scr_struct != 0) {
908 printf("Unrecognised SCR structure version %d\n",
909 scr_struct);
910 return;
911 }
912 scr->sda_vsn = mmc_get_bits(raw_scr, 64, 56, 4);
913 scr->bus_widths = mmc_get_bits(raw_scr, 64, 48, 4);
914}
915
916static inline void
918 uint8_t set, uint8_t index, uint8_t value, u_int timeout)
919{
920 int arg = (MMC_SWITCH_FUNC_WR << 24) |
921 (index << 16) |
922 (value << 8) |
923 set;
924
926 /*retries*/ 0,
927 /*cbfcnp*/ NULL,
928 /*flags*/ CAM_DIR_NONE,
929 /*mmc_opcode*/ MMC_SWITCH_FUNC,
930 /*mmc_arg*/ arg,
931 /*mmc_flags*/ MMC_RSP_R1B | MMC_CMD_AC,
932 /*mmc_data*/ NULL,
933 /*timeout*/ timeout);
934}
935
936static int
937mmc_select_card(struct cam_periph *periph, union ccb *ccb, uint32_t rca)
938{
939 int flags, err;
940
941 flags = (rca ? MMC_RSP_R1B : MMC_RSP_NONE) | MMC_CMD_AC;
943 /*retries*/ 0,
944 /*cbfcnp*/ NULL,
945 /*flags*/ CAM_DIR_IN,
946 /*mmc_opcode*/ MMC_SELECT_CARD,
947 /*mmc_arg*/ rca << 16,
948 /*mmc_flags*/ flags,
949 /*mmc_data*/ NULL,
950 /*timeout*/ 0);
951
952 cam_periph_runccb(ccb, sddaerror, CAM_FLAG_NONE, /*sense_flags*/0, NULL);
953 err = mmc_handle_reply(ccb);
954 return (err);
955}
956
957static int
958mmc_switch(struct cam_periph *periph, union ccb *ccb,
959 uint8_t set, uint8_t index, uint8_t value, u_int timeout)
960{
961 int err;
962
963 mmc_switch_fill_mmcio(ccb, set, index, value, timeout);
964 cam_periph_runccb(ccb, sddaerror, CAM_FLAG_NONE, /*sense_flags*/0, NULL);
965 err = mmc_handle_reply(ccb);
966 return (err);
967}
968
969static uint32_t
971 struct sdda_softc *softc = (struct sdda_softc *)periph->softc;
972
973 return (softc->csd.spec_vers);
974}
975
976static uint64_t
978 struct sdda_softc *softc = (struct sdda_softc *)periph->softc;
979
980 return (softc->mediasize);
981}
982
983static uint32_t
985{
986 struct sdda_softc *softc = (struct sdda_softc *)periph->softc;
987
988 if (mmc_get_spec_vers(periph) >= 6)
989 return (softc->raw_ext_csd[EXT_CSD_GEN_CMD6_TIME] * 10);
990 return (500 * 1000);
991}
992
993static int
995 uint8_t mode, uint8_t grp, uint8_t value,
996 uint8_t *res) {
997 struct mmc_data mmc_d;
998 uint32_t arg;
999 int err;
1000
1001 memset(res, 0, 64);
1002 memset(&mmc_d, 0, sizeof(mmc_d));
1003 mmc_d.len = 64;
1004 mmc_d.data = res;
1005 mmc_d.flags = MMC_DATA_READ;
1006
1007 arg = mode << 31; /* 0 - check, 1 - set */
1008 arg |= 0x00FFFFFF;
1009 arg &= ~(0xF << (grp * 4));
1010 arg |= value << (grp * 4);
1011
1013 /*retries*/ 0,
1014 /*cbfcnp*/ NULL,
1015 /*flags*/ CAM_DIR_IN,
1016 /*mmc_opcode*/ SD_SWITCH_FUNC,
1017 /*mmc_arg*/ arg,
1018 /*mmc_flags*/ MMC_RSP_R1 | MMC_CMD_ADTC,
1019 /*mmc_data*/ &mmc_d,
1020 /*timeout*/ 0);
1021
1022 cam_periph_runccb(ccb, sddaerror, CAM_FLAG_NONE, /*sense_flags*/0, NULL);
1023 err = mmc_handle_reply(ccb);
1024 return (err);
1025}
1026
1027static int
1029 union ccb *ccb,
1030 enum mmc_bus_timing timing)
1031{
1032 u_char switch_res[64];
1033 int err;
1034 uint8_t value;
1035 struct sdda_softc *softc = (struct sdda_softc *)periph->softc;
1036 struct mmc_params *mmcp = &periph->path->device->mmc_ident_data;
1037
1039 ("mmc_set_timing(timing=%d)", timing));
1040 switch (timing) {
1041 case bus_timing_normal:
1042 value = 0;
1043 break;
1044 case bus_timing_hs:
1045 value = 1;
1046 break;
1047 default:
1048 return (MMC_ERR_INVALID);
1049 }
1050 if (mmcp->card_features & CARD_FEATURE_MMC) {
1051 err = mmc_switch(periph, ccb, EXT_CSD_CMD_SET_NORMAL,
1052 EXT_CSD_HS_TIMING, value, softc->cmd6_time);
1053 } else {
1054 err = mmc_sd_switch(periph, ccb, SD_SWITCH_MODE_SET, SD_SWITCH_GROUP1, value, switch_res);
1055 }
1056
1057 /* Set high-speed timing on the host */
1062 ccb->ccb_h.retry_count = 0;
1063 ccb->ccb_h.timeout = 100;
1064 ccb->ccb_h.cbfcnp = NULL;
1065 cts->ios.timing = timing;
1066 cts->ios_valid = MMC_BT;
1067 xpt_action(ccb);
1068
1069 return (err);
1070}
1071
1072static void
1073sdda_start_init_task(void *context, int pending) {
1074 union ccb *new_ccb;
1075 struct cam_periph *periph;
1076
1077 periph = (struct cam_periph *)context;
1078 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("sdda_start_init_task\n"));
1079 new_ccb = xpt_alloc_ccb();
1080 xpt_setup_ccb(&new_ccb->ccb_h, periph->path,
1082
1083 cam_periph_lock(periph);
1084 cam_periph_hold(periph, PRIBIO|PCATCH);
1085 sdda_start_init(context, new_ccb);
1086 cam_periph_unhold(periph);
1087 cam_periph_unlock(periph);
1088 xpt_free_ccb(new_ccb);
1089}
1090
1091static void
1092sdda_set_bus_width(struct cam_periph *periph, union ccb *ccb, int width) {
1093 struct sdda_softc *softc = (struct sdda_softc *)periph->softc;
1094 struct mmc_params *mmcp = &periph->path->device->mmc_ident_data;
1095 int err;
1096
1097 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("sdda_set_bus_width\n"));
1098
1099 /* First set for the card, then for the host */
1100 if (mmcp->card_features & CARD_FEATURE_MMC) {
1101 uint8_t value;
1102 switch (width) {
1103 case bus_width_1:
1104 value = EXT_CSD_BUS_WIDTH_1;
1105 break;
1106 case bus_width_4:
1107 value = EXT_CSD_BUS_WIDTH_4;
1108 break;
1109 case bus_width_8:
1110 value = EXT_CSD_BUS_WIDTH_8;
1111 break;
1112 default:
1113 panic("Invalid bus width %d", width);
1114 }
1115 err = mmc_switch(periph, ccb, EXT_CSD_CMD_SET_NORMAL,
1116 EXT_CSD_BUS_WIDTH, value, softc->cmd6_time);
1117 } else {
1118 /* For SD cards we send ACMD6 with the required bus width in arg */
1119 struct mmc_command cmd;
1120 memset(&cmd, 0, sizeof(struct mmc_command));
1121 cmd.opcode = ACMD_SET_BUS_WIDTH;
1122 cmd.arg = width;
1123 cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
1124 err = mmc_exec_app_cmd(periph, ccb, &cmd);
1125 }
1126
1127 if (err != MMC_ERR_NONE) {
1128 CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH, ("Error %d when setting bus width on the card\n", err));
1129 return;
1130 }
1131 /* Now card is done, set the host to the same width */
1136 ccb->ccb_h.retry_count = 0;
1137 ccb->ccb_h.timeout = 100;
1138 ccb->ccb_h.cbfcnp = NULL;
1139 cts->ios.bus_width = width;
1140 cts->ios_valid = MMC_BW;
1141 xpt_action(ccb);
1142}
1143
1144static inline const char
1145*part_type(u_int type)
1146{
1147
1148 switch (type) {
1149 case EXT_CSD_PART_CONFIG_ACC_RPMB:
1150 return ("RPMB");
1151 case EXT_CSD_PART_CONFIG_ACC_DEFAULT:
1152 return ("default");
1153 case EXT_CSD_PART_CONFIG_ACC_BOOT0:
1154 return ("boot0");
1155 case EXT_CSD_PART_CONFIG_ACC_BOOT1:
1156 return ("boot1");
1157 case EXT_CSD_PART_CONFIG_ACC_GP0:
1158 case EXT_CSD_PART_CONFIG_ACC_GP1:
1159 case EXT_CSD_PART_CONFIG_ACC_GP2:
1160 case EXT_CSD_PART_CONFIG_ACC_GP3:
1161 return ("general purpose");
1162 default:
1163 return ("(unknown type)");
1164 }
1165}
1166
1167static inline const char
1168*bus_width_str(enum mmc_bus_width w)
1169{
1170
1171 switch (w) {
1172 case bus_width_1:
1173 return ("1-bit");
1174 case bus_width_4:
1175 return ("4-bit");
1176 case bus_width_8:
1177 return ("8-bit");
1178 default:
1179 __assert_unreachable();
1180 }
1181}
1182
1183static uint32_t
1184sdda_get_host_caps(struct cam_periph *periph, union ccb *ccb)
1185{
1187
1189
1192 ccb->ccb_h.retry_count = 0;
1193 ccb->ccb_h.timeout = 100;
1194 ccb->ccb_h.cbfcnp = NULL;
1195 xpt_action(ccb);
1196
1197 if (ccb->ccb_h.status != CAM_REQ_CMP)
1198 panic("Cannot get host caps");
1199 return (cts->host_caps);
1200}
1201
1202static uint32_t
1203sdda_get_max_data(struct cam_periph *periph, union ccb *ccb)
1204{
1206
1208 memset(cts, 0, sizeof(struct ccb_trans_settings_mmc));
1209
1212 ccb->ccb_h.retry_count = 0;
1213 ccb->ccb_h.timeout = 100;
1214 ccb->ccb_h.cbfcnp = NULL;
1215 xpt_action(ccb);
1216
1217 if (ccb->ccb_h.status != CAM_REQ_CMP)
1218 panic("Cannot get host max data");
1219 KASSERT(cts->host_max_data != 0, ("host_max_data == 0?!"));
1220 return (cts->host_max_data);
1221}
1222
1223static void
1224sdda_start_init(void *context, union ccb *start_ccb)
1225{
1226 struct cam_periph *periph = (struct cam_periph *)context;
1228 uint32_t host_caps;
1229 uint32_t sec_count;
1230 int err;
1231 int host_f_max;
1232 uint8_t card_type;
1233
1234 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("sdda_start_init\n"));
1235 /* periph was held for us when this task was enqueued */
1236 if ((periph->flags & CAM_PERIPH_INVALID) != 0) {
1237 cam_periph_release(periph);
1238 return;
1239 }
1240
1241 struct sdda_softc *softc = (struct sdda_softc *)periph->softc;
1242 struct mmc_params *mmcp = &periph->path->device->mmc_ident_data;
1243 struct cam_ed *device = periph->path->device;
1244
1245 if (mmcp->card_features & CARD_FEATURE_MMC) {
1246 mmc_decode_csd_mmc(mmcp->card_csd, &softc->csd);
1247 mmc_decode_cid_mmc(mmcp->card_cid, &softc->cid);
1248 if (mmc_get_spec_vers(periph) >= 4) {
1249 err = mmc_send_ext_csd(periph, start_ccb,
1250 (uint8_t *)&softc->raw_ext_csd,
1251 sizeof(softc->raw_ext_csd));
1252 if (err != 0) {
1254 ("Cannot read EXT_CSD, err %d", err));
1255 return;
1256 }
1257 }
1258 } else {
1259 mmc_decode_csd_sd(mmcp->card_csd, &softc->csd);
1260 mmc_decode_cid_sd(mmcp->card_cid, &softc->cid);
1261 }
1262
1263 softc->sector_count = softc->csd.capacity / MMC_SECTOR_SIZE;
1264 softc->mediasize = softc->csd.capacity;
1266
1267 /* MMC >= 4.x have EXT_CSD that has its own opinion about capacity */
1268 if (mmc_get_spec_vers(periph) >= 4) {
1269 sec_count = softc->raw_ext_csd[EXT_CSD_SEC_CNT] +
1270 (softc->raw_ext_csd[EXT_CSD_SEC_CNT + 1] << 8) +
1271 (softc->raw_ext_csd[EXT_CSD_SEC_CNT + 2] << 16) +
1272 (softc->raw_ext_csd[EXT_CSD_SEC_CNT + 3] << 24);
1273 if (sec_count != 0) {
1274 softc->sector_count = sec_count;
1275 softc->mediasize = softc->sector_count * MMC_SECTOR_SIZE;
1276 /* FIXME: there should be a better name for this option...*/
1277 mmcp->card_features |= CARD_FEATURE_SDHC;
1278 }
1279 }
1281 ("Capacity: %"PRIu64", sectors: %"PRIu64"\n",
1282 softc->mediasize,
1283 softc->sector_count));
1284 mmc_format_card_id_string(softc, mmcp);
1285
1286 /* Update info for CAM */
1287 device->serial_num_len = strlen(softc->card_sn_string);
1288 device->serial_num = (u_int8_t *)malloc((device->serial_num_len + 1),
1289 M_CAMXPT, M_NOWAIT);
1290 strlcpy(device->serial_num, softc->card_sn_string, device->serial_num_len + 1);
1291
1292 device->device_id_len = strlen(softc->card_id_string);
1293 device->device_id = (u_int8_t *)malloc((device->device_id_len + 1),
1294 M_CAMXPT, M_NOWAIT);
1295 strlcpy(device->device_id, softc->card_id_string, device->device_id_len + 1);
1296
1297 strlcpy(mmcp->model, softc->card_id_string, sizeof(mmcp->model));
1298
1299 /* Set the clock frequency that the card can handle */
1300 cts = &start_ccb->cts.proto_specific.mmc;
1301
1302 /* First, get the host's max freq */
1304 start_ccb->ccb_h.flags = CAM_DIR_NONE;
1305 start_ccb->ccb_h.retry_count = 0;
1306 start_ccb->ccb_h.timeout = 100;
1307 start_ccb->ccb_h.cbfcnp = NULL;
1308 xpt_action(start_ccb);
1309
1310 if (start_ccb->ccb_h.status != CAM_REQ_CMP)
1311 panic("Cannot get max host freq");
1312 host_f_max = cts->host_f_max;
1313 host_caps = cts->host_caps;
1314 if (cts->ios.bus_width != bus_width_1)
1315 panic("Bus width in ios is not 1-bit");
1316
1317 /* Now check if the card supports High-speed */
1318 softc->card_f_max = softc->csd.tran_speed;
1319
1320 if (host_caps & MMC_CAP_HSPEED) {
1321 /* Find out if the card supports High speed timing */
1322 if (mmcp->card_features & CARD_FEATURE_SD20) {
1323 /* Get and decode SCR */
1324 uint32_t rawscr[2];
1325 uint8_t res[64];
1326 if (mmc_app_get_scr(periph, start_ccb, rawscr)) {
1327 CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH, ("Cannot get SCR\n"));
1328 goto finish_hs_tests;
1329 }
1330 mmc_app_decode_scr(rawscr, &softc->scr);
1331
1332 if ((softc->scr.sda_vsn >= 1) && (softc->csd.ccc & (1<<10))) {
1333 mmc_sd_switch(periph, start_ccb, SD_SWITCH_MODE_CHECK,
1334 SD_SWITCH_GROUP1, SD_SWITCH_NOCHANGE, res);
1335 if (res[13] & 2) {
1336 CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH, ("Card supports HS\n"));
1337 softc->card_f_max = SD_HS_MAX;
1338 }
1339
1340 /*
1341 * We deselect then reselect the card here. Some cards
1342 * become unselected and timeout with the above two
1343 * commands, although the state tables / diagrams in the
1344 * standard suggest they go back to the transfer state.
1345 * Other cards don't become deselected, and if we
1346 * attempt to blindly re-select them, we get timeout
1347 * errors from some controllers. So we deselect then
1348 * reselect to handle all situations.
1349 */
1350 mmc_select_card(periph, start_ccb, 0);
1351 mmc_select_card(periph, start_ccb, get_rca(periph));
1352 } else {
1353 CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH, ("Not trying the switch\n"));
1354 goto finish_hs_tests;
1355 }
1356 }
1357
1358 if (mmcp->card_features & CARD_FEATURE_MMC && mmc_get_spec_vers(periph) >= 4) {
1359 card_type = softc->raw_ext_csd[EXT_CSD_CARD_TYPE];
1360 if (card_type & EXT_CSD_CARD_TYPE_HS_52)
1361 softc->card_f_max = MMC_TYPE_HS_52_MAX;
1362 else if (card_type & EXT_CSD_CARD_TYPE_HS_26)
1363 softc->card_f_max = MMC_TYPE_HS_26_MAX;
1364 if ((card_type & EXT_CSD_CARD_TYPE_DDR_52_1_2V) != 0 &&
1365 (host_caps & MMC_CAP_SIGNALING_120) != 0) {
1366 setbit(&softc->timings, bus_timing_mmc_ddr52);
1367 setbit(&softc->vccq_120, bus_timing_mmc_ddr52);
1368 CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH, ("Card supports DDR52 at 1.2V\n"));
1369 }
1370 if ((card_type & EXT_CSD_CARD_TYPE_DDR_52_1_8V) != 0 &&
1371 (host_caps & MMC_CAP_SIGNALING_180) != 0) {
1372 setbit(&softc->timings, bus_timing_mmc_ddr52);
1373 setbit(&softc->vccq_180, bus_timing_mmc_ddr52);
1374 CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH, ("Card supports DDR52 at 1.8V\n"));
1375 }
1376 if ((card_type & EXT_CSD_CARD_TYPE_HS200_1_2V) != 0 &&
1377 (host_caps & MMC_CAP_SIGNALING_120) != 0) {
1378 setbit(&softc->timings, bus_timing_mmc_hs200);
1379 setbit(&softc->vccq_120, bus_timing_mmc_hs200);
1380 CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH, ("Card supports HS200 at 1.2V\n"));
1381 }
1382 if ((card_type & EXT_CSD_CARD_TYPE_HS200_1_8V) != 0 &&
1383 (host_caps & MMC_CAP_SIGNALING_180) != 0) {
1384 setbit(&softc->timings, bus_timing_mmc_hs200);
1385 setbit(&softc->vccq_180, bus_timing_mmc_hs200);
1386 CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH, ("Card supports HS200 at 1.8V\n"));
1387 }
1388 }
1389 }
1390 int f_max;
1391finish_hs_tests:
1392 f_max = min(host_f_max, softc->card_f_max);
1393 CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH, ("Set SD freq to %d MHz (min out of host f=%d MHz and card f=%d MHz)\n", f_max / 1000000, host_f_max / 1000000, softc->card_f_max / 1000000));
1394
1395 /* Enable high-speed timing on the card */
1396 if (f_max > 25000000) {
1397 err = mmc_set_timing(periph, start_ccb, bus_timing_hs);
1398 if (err != MMC_ERR_NONE) {
1399 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("Cannot switch card to high-speed mode"));
1400 f_max = 25000000;
1401 }
1402 }
1403 /* If possible, set lower-level signaling */
1404 enum mmc_bus_timing timing;
1405 /* FIXME: MMCCAM supports max. bus_timing_mmc_ddr52 at the moment. */
1406 for (timing = bus_timing_mmc_ddr52; timing > bus_timing_normal; timing--) {
1407 if (isset(&softc->vccq_120, timing)) {
1408 /* Set VCCQ = 1.2V */
1410 start_ccb->ccb_h.flags = CAM_DIR_NONE;
1411 start_ccb->ccb_h.retry_count = 0;
1412 start_ccb->ccb_h.timeout = 100;
1413 start_ccb->ccb_h.cbfcnp = NULL;
1414 cts->ios.vccq = vccq_120;
1416 xpt_action(start_ccb);
1417 break;
1418 } else if (isset(&softc->vccq_180, timing)) {
1419 /* Set VCCQ = 1.8V */
1421 start_ccb->ccb_h.flags = CAM_DIR_NONE;
1422 start_ccb->ccb_h.retry_count = 0;
1423 start_ccb->ccb_h.timeout = 100;
1424 start_ccb->ccb_h.cbfcnp = NULL;
1425 cts->ios.vccq = vccq_180;
1427 xpt_action(start_ccb);
1428 break;
1429 } else {
1430 /* Set VCCQ = 3.3V */
1432 start_ccb->ccb_h.flags = CAM_DIR_NONE;
1433 start_ccb->ccb_h.retry_count = 0;
1434 start_ccb->ccb_h.timeout = 100;
1435 start_ccb->ccb_h.cbfcnp = NULL;
1436 cts->ios.vccq = vccq_330;
1438 xpt_action(start_ccb);
1439 break;
1440 }
1441 }
1442
1443 /* Set frequency on the controller */
1445 start_ccb->ccb_h.flags = CAM_DIR_NONE;
1446 start_ccb->ccb_h.retry_count = 0;
1447 start_ccb->ccb_h.timeout = 100;
1448 start_ccb->ccb_h.cbfcnp = NULL;
1449 cts->ios.clock = f_max;
1451 xpt_action(start_ccb);
1452
1453 /* Set bus width */
1454 enum mmc_bus_width desired_bus_width = bus_width_1;
1455 enum mmc_bus_width max_host_bus_width =
1456 (host_caps & MMC_CAP_8_BIT_DATA ? bus_width_8 :
1457 host_caps & MMC_CAP_4_BIT_DATA ? bus_width_4 : bus_width_1);
1458 enum mmc_bus_width max_card_bus_width = bus_width_1;
1459 if (mmcp->card_features & CARD_FEATURE_SD20 &&
1460 softc->scr.bus_widths & SD_SCR_BUS_WIDTH_4)
1461 max_card_bus_width = bus_width_4;
1462 /*
1463 * Unlike SD, MMC cards don't have any information about supported bus width...
1464 * So we need to perform read/write test to find out the width.
1465 */
1466 /* TODO: figure out bus width for MMC; use 8-bit for now (to test on BBB) */
1467 if (mmcp->card_features & CARD_FEATURE_MMC)
1468 max_card_bus_width = bus_width_8;
1469
1470 desired_bus_width = min(max_host_bus_width, max_card_bus_width);
1472 ("Set bus width to %s (min of host %s and card %s)\n",
1473 bus_width_str(desired_bus_width),
1474 bus_width_str(max_host_bus_width),
1475 bus_width_str(max_card_bus_width)));
1476 sdda_set_bus_width(periph, start_ccb, desired_bus_width);
1477
1478 softc->state = SDDA_STATE_NORMAL;
1479
1481 /* MMC partitions support */
1482 if (mmcp->card_features & CARD_FEATURE_MMC && mmc_get_spec_vers(periph) >= 4) {
1484 } else if (mmcp->card_features & CARD_FEATURE_MEMORY) {
1485 /* For SD[HC] cards, just add one partition that is the whole card */
1486 if (sdda_add_part(periph, 0, "sdda",
1489 sdda_get_read_only(periph, start_ccb)) == false)
1490 return;
1491 softc->part_curr = 0;
1492 }
1493 cam_periph_hold(periph, PRIBIO|PCATCH);
1494
1496 /*
1497 * Add async callbacks for bus reset and bus device reset calls.
1498 * I don't bother checking if this fails as, in most cases,
1499 * the system will function just fine without them and the only
1500 * alternative would be to not attach the device on failure.
1501 */
1504}
1505
1506static bool
1507sdda_add_part(struct cam_periph *periph, u_int type, const char *name,
1508 u_int cnt, off_t media_size, bool ro)
1509{
1510 struct sdda_softc *sc = (struct sdda_softc *)periph->softc;
1511 struct sdda_part *part;
1512 struct ccb_pathinq cpi;
1513
1515 ("Partition type '%s', size %ju %s\n",
1516 part_type(type),
1517 media_size,
1518 ro ? "(read-only)" : ""));
1519
1520 part = sc->part[type] = malloc(sizeof(*part), M_DEVBUF,
1521 M_NOWAIT | M_ZERO);
1522 if (part == NULL) {
1523 printf("Cannot add partition for sdda\n");
1524 return (false);
1525 }
1526
1527 part->cnt = cnt;
1528 part->type = type;
1529 part->ro = ro;
1530 part->sc = sc;
1531 snprintf(part->name, sizeof(part->name), name, periph->unit_number);
1532
1533 /*
1534 * Due to the nature of RPMB partition it doesn't make much sense
1535 * to add it as a disk. It would be more appropriate to create a
1536 * userland tool to operate on the partition or leverage the existing
1537 * tools from sysutils/mmc-utils.
1538 */
1539 if (type == EXT_CSD_PART_CONFIG_ACC_RPMB) {
1540 /* TODO: Create device, assign IOCTL handler */
1542 ("Don't know what to do with RPMB partitions yet\n"));
1543 return (false);
1544 }
1545
1546 bioq_init(&part->bio_queue);
1547
1548 bzero(&cpi, sizeof(cpi));
1550 cpi.ccb_h.func_code = XPT_PATH_INQ;
1551 xpt_action((union ccb *)&cpi);
1552
1553 /*
1554 * Register this media as a disk
1555 */
1556 (void)cam_periph_hold(periph, PRIBIO);
1558
1559 part->disk = disk_alloc();
1560 part->disk->d_rotation_rate = DISK_RR_NON_ROTATING;
1561 part->disk->d_devstat = devstat_new_entry(part->name,
1562 cnt, MMC_SECTOR_SIZE,
1563 DEVSTAT_ALL_SUPPORTED,
1564 DEVSTAT_TYPE_DIRECT | XPORT_DEVSTAT_TYPE(cpi.transport),
1565 DEVSTAT_PRIORITY_DISK);
1566
1567 part->disk->d_open = sddaopen;
1568 part->disk->d_close = sddaclose;
1569 part->disk->d_strategy = sddastrategy;
1571 part->disk->d_dump = sddadump;
1572 part->disk->d_getattr = sddagetattr;
1573 part->disk->d_gone = sddadiskgonecb;
1574 part->disk->d_name = part->name;
1575 part->disk->d_drv1 = part;
1576 part->disk->d_maxsize =
1577 MIN(maxphys, sdda_get_max_data(periph,
1578 (union ccb *)&cpi) * mmc_get_sector_size(periph));
1579 part->disk->d_unit = cnt;
1580 part->disk->d_flags = 0;
1581 strlcpy(part->disk->d_descr, sc->card_id_string,
1582 MIN(sizeof(part->disk->d_descr), sizeof(sc->card_id_string)));
1583 strlcpy(part->disk->d_ident, sc->card_sn_string,
1584 MIN(sizeof(part->disk->d_ident), sizeof(sc->card_sn_string)));
1585 part->disk->d_hba_vendor = cpi.hba_vendor;
1586 part->disk->d_hba_device = cpi.hba_device;
1587 part->disk->d_hba_subvendor = cpi.hba_subvendor;
1588 part->disk->d_hba_subdevice = cpi.hba_subdevice;
1589 snprintf(part->disk->d_attachment, sizeof(part->disk->d_attachment),
1590 "%s%d", cpi.dev_name, cpi.unit_number);
1591
1592 part->disk->d_sectorsize = mmc_get_sector_size(periph);
1593 part->disk->d_mediasize = media_size;
1594 part->disk->d_stripesize = 0;
1595 part->disk->d_fwsectors = 0;
1596 part->disk->d_fwheads = 0;
1597
1599 disk_add_alias(part->disk, "mmcsd");
1600
1601 /*
1602 * Acquire a reference to the periph before we register with GEOM.
1603 * We'll release this reference once GEOM calls us back (via
1604 * sddadiskgonecb()) telling us that our provider has been freed.
1605 */
1606 if (cam_periph_acquire(periph) != 0) {
1607 xpt_print(periph->path, "%s: lost periph during "
1608 "registration!\n", __func__);
1610 return (false);
1611 }
1612 disk_create(part->disk, DISK_VERSION);
1615
1616 return (true);
1617}
1618
1619/*
1620 * For MMC cards, process EXT_CSD and add partitions that are supported by
1621 * this device.
1622 */
1623static void
1625{
1626 struct sdda_softc *sc = (struct sdda_softc *)periph->softc;
1627 struct mmc_params *mmcp = &periph->path->device->mmc_ident_data;
1628 off_t erase_size, sector_size, size, wp_size;
1629 int i;
1630 const uint8_t *ext_csd;
1631 uint8_t rev;
1632 bool comp, ro;
1633
1634 ext_csd = sc->raw_ext_csd;
1635
1636 /*
1637 * Enhanced user data area and general purpose partitions are only
1638 * supported in revision 1.4 (EXT_CSD_REV == 4) and later, the RPMB
1639 * partition in revision 1.5 (MMC v4.41, EXT_CSD_REV == 5) and later.
1640 */
1641 rev = ext_csd[EXT_CSD_REV];
1642
1643 /*
1644 * Ignore user-creatable enhanced user data area and general purpose
1645 * partitions partitions as long as partitioning hasn't been finished.
1646 */
1647 comp = (ext_csd[EXT_CSD_PART_SET] & EXT_CSD_PART_SET_COMPLETED) != 0;
1648
1649 /*
1650 * Add enhanced user data area slice, unless it spans the entirety of
1651 * the user data area. The enhanced area is of a multiple of high
1652 * capacity write protect groups ((ERASE_GRP_SIZE + HC_WP_GRP_SIZE) *
1653 * 512 KB) and its offset given in either sectors or bytes, depending
1654 * on whether it's a high capacity device or not.
1655 * NB: The slicer and its slices need to be registered before adding
1656 * the disk for the corresponding user data area as re-tasting is
1657 * racy.
1658 */
1659 sector_size = mmc_get_sector_size(periph);
1660 size = ext_csd[EXT_CSD_ENH_SIZE_MULT] +
1661 (ext_csd[EXT_CSD_ENH_SIZE_MULT + 1] << 8) +
1662 (ext_csd[EXT_CSD_ENH_SIZE_MULT + 2] << 16);
1663 if (rev >= 4 && comp == TRUE && size > 0 &&
1664 (ext_csd[EXT_CSD_PART_SUPPORT] &
1665 EXT_CSD_PART_SUPPORT_ENH_ATTR_EN) != 0 &&
1666 (ext_csd[EXT_CSD_PART_ATTR] & (EXT_CSD_PART_ATTR_ENH_USR)) != 0) {
1667 erase_size = ext_csd[EXT_CSD_ERASE_GRP_SIZE] * 1024 *
1668 MMC_SECTOR_SIZE;
1669 wp_size = ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
1670 size *= erase_size * wp_size;
1671 if (size != mmc_get_media_size(periph) * sector_size) {
1672 sc->enh_size = size;
1673 sc->enh_base = (ext_csd[EXT_CSD_ENH_START_ADDR] +
1674 (ext_csd[EXT_CSD_ENH_START_ADDR + 1] << 8) +
1675 (ext_csd[EXT_CSD_ENH_START_ADDR + 2] << 16) +
1676 (ext_csd[EXT_CSD_ENH_START_ADDR + 3] << 24)) *
1677 ((mmcp->card_features & CARD_FEATURE_SDHC) ? 1: MMC_SECTOR_SIZE);
1678 } else
1680 ("enhanced user data area spans entire device"));
1681 }
1682
1683 /*
1684 * Add default partition. This may be the only one or the user
1685 * data area in case partitions are supported.
1686 */
1688 sdda_add_part(periph, EXT_CSD_PART_CONFIG_ACC_DEFAULT, "sdda",
1690 sc->part_curr = EXT_CSD_PART_CONFIG_ACC_DEFAULT;
1691
1692 if (mmc_get_spec_vers(periph) < 3)
1693 return;
1694
1695 /* Belatedly announce enhanced user data slice. */
1696 if (sc->enh_size != 0) {
1698 ("enhanced user data area off 0x%jx size %ju bytes\n",
1699 sc->enh_base, sc->enh_size));
1700 }
1701
1702 /*
1703 * Determine partition switch timeout (provided in units of 10 ms)
1704 * and ensure it's at least 300 ms as some eMMC chips lie.
1705 */
1706 sc->part_time = max(ext_csd[EXT_CSD_PART_SWITCH_TO] * 10 * 1000,
1707 300 * 1000);
1708
1709 /* Add boot partitions, which are of a fixed multiple of 128 KB. */
1710 size = ext_csd[EXT_CSD_BOOT_SIZE_MULT] * MMC_BOOT_RPMB_BLOCK_SIZE;
1711 if (size > 0 && (sdda_get_host_caps(periph, ccb) & MMC_CAP_BOOT_NOACC) == 0) {
1712 sdda_add_part(periph, EXT_CSD_PART_CONFIG_ACC_BOOT0,
1713 SDDA_FMT_BOOT, 0, size,
1714 ro | ((ext_csd[EXT_CSD_BOOT_WP_STATUS] &
1715 EXT_CSD_BOOT_WP_STATUS_BOOT0_MASK) != 0));
1716 sdda_add_part(periph, EXT_CSD_PART_CONFIG_ACC_BOOT1,
1717 SDDA_FMT_BOOT, 1, size,
1718 ro | ((ext_csd[EXT_CSD_BOOT_WP_STATUS] &
1719 EXT_CSD_BOOT_WP_STATUS_BOOT1_MASK) != 0));
1720 }
1721
1722 /* Add RPMB partition, which also is of a fixed multiple of 128 KB. */
1723 size = ext_csd[EXT_CSD_RPMB_MULT] * MMC_BOOT_RPMB_BLOCK_SIZE;
1724 if (rev >= 5 && size > 0)
1725 sdda_add_part(periph, EXT_CSD_PART_CONFIG_ACC_RPMB,
1726 SDDA_FMT_RPMB, 0, size, ro);
1727
1728 if (rev <= 3 || comp == FALSE)
1729 return;
1730
1731 /*
1732 * Add general purpose partitions, which are of a multiple of high
1733 * capacity write protect groups, too.
1734 */
1735 if ((ext_csd[EXT_CSD_PART_SUPPORT] & EXT_CSD_PART_SUPPORT_EN) != 0) {
1736 erase_size = ext_csd[EXT_CSD_ERASE_GRP_SIZE] * 1024 *
1737 MMC_SECTOR_SIZE;
1738 wp_size = ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
1739 for (i = 0; i < MMC_PART_GP_MAX; i++) {
1740 size = ext_csd[EXT_CSD_GP_SIZE_MULT + i * 3] +
1741 (ext_csd[EXT_CSD_GP_SIZE_MULT + i * 3 + 1] << 8) +
1742 (ext_csd[EXT_CSD_GP_SIZE_MULT + i * 3 + 2] << 16);
1743 if (size == 0)
1744 continue;
1745 sdda_add_part(periph, EXT_CSD_PART_CONFIG_ACC_GP0 + i,
1746 SDDA_FMT_GP, i, size * erase_size * wp_size, ro);
1747 }
1748 }
1749}
1750
1751/*
1752 * We cannot just call mmc_switch() since it will sleep, and we are in
1753 * GEOM context and cannot sleep. Instead, create an MMCIO request to switch
1754 * partitions and send it to h/w, and upon completion resume processing
1755 * the I/O queue.
1756 * This function cannot fail, instead check switch errors in sddadone().
1757 */
1758static void
1759sdda_init_switch_part(struct cam_periph *periph, union ccb *start_ccb,
1760 uint8_t part)
1761{
1762 struct sdda_softc *sc = (struct sdda_softc *)periph->softc;
1763 uint8_t value;
1764
1765 KASSERT(part < MMC_PART_MAX, ("%s: invalid partition index", __func__));
1766 sc->part_requested = part;
1767
1768 value = (sc->raw_ext_csd[EXT_CSD_PART_CONFIG] &
1769 ~EXT_CSD_PART_CONFIG_ACC_MASK) | part;
1770
1771 mmc_switch_fill_mmcio(start_ccb, EXT_CSD_CMD_SET_NORMAL,
1772 EXT_CSD_PART_CONFIG, value, sc->part_time);
1773 start_ccb->ccb_h.cbfcnp = sddadone;
1774
1775 sc->outstanding_cmds++;
1777 xpt_action(start_ccb);
1779}
1780
1781/* Called with periph lock held! */
1782static void
1783sddastart(struct cam_periph *periph, union ccb *start_ccb)
1784{
1785 struct bio *bp;
1786 struct sdda_softc *softc = (struct sdda_softc *)periph->softc;
1787 struct sdda_part *part;
1788 struct mmc_params *mmcp = &periph->path->device->mmc_ident_data;
1789 uint8_t part_index;
1790
1791 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("sddastart\n"));
1792
1793 if (softc->state != SDDA_STATE_NORMAL) {
1794 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("device is not in SDDA_STATE_NORMAL yet\n"));
1795 xpt_release_ccb(start_ccb);
1796 return;
1797 }
1798
1799 /* Find partition that has outstanding commands. Prefer current partition. */
1800 part_index = softc->part_curr;
1801 part = softc->part[softc->part_curr];
1802 bp = bioq_first(&part->bio_queue);
1803 if (bp == NULL) {
1804 for (part_index = 0; part_index < MMC_PART_MAX; part_index++) {
1805 if ((part = softc->part[part_index]) != NULL &&
1806 (bp = bioq_first(&softc->part[part_index]->bio_queue)) != NULL)
1807 break;
1808 }
1809 }
1810 if (bp == NULL) {
1811 xpt_release_ccb(start_ccb);
1812 return;
1813 }
1814 if (part_index != softc->part_curr) {
1816 ("Partition %d -> %d\n", softc->part_curr, part_index));
1817 /*
1818 * According to section "6.2.2 Command restrictions" of the eMMC
1819 * specification v5.1, CMD19/CMD21 aren't allowed to be used with
1820 * RPMB partitions. So we pause re-tuning along with triggering
1821 * it up-front to decrease the likelihood of re-tuning becoming
1822 * necessary while accessing an RPMB partition. Consequently, an
1823 * RPMB partition should immediately be switched away from again
1824 * after an access in order to allow for re-tuning to take place
1825 * anew.
1826 */
1827 /* TODO: pause retune if switching to RPMB partition */
1829 sdda_init_switch_part(periph, start_ccb, part_index);
1830 return;
1831 }
1832
1833 bioq_remove(&part->bio_queue, bp);
1834
1835 switch (bp->bio_cmd) {
1836 case BIO_WRITE:
1837 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("BIO_WRITE\n"));
1839 /* FALLTHROUGH */
1840 case BIO_READ:
1841 {
1842 struct ccb_mmcio *mmcio;
1843 uint64_t blockno = bp->bio_pblkno;
1844 uint16_t count = bp->bio_bcount / MMC_SECTOR_SIZE;
1845 uint16_t opcode;
1846
1847 if (bp->bio_cmd == BIO_READ)
1848 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("BIO_READ\n"));
1850 ("Block %"PRIu64" cnt %u\n", blockno, count));
1851
1852 /* Construct new MMC command */
1853 if (bp->bio_cmd == BIO_READ) {
1854 if (count > 1)
1855 opcode = MMC_READ_MULTIPLE_BLOCK;
1856 else
1857 opcode = MMC_READ_SINGLE_BLOCK;
1858 } else {
1859 if (count > 1)
1860 opcode = MMC_WRITE_MULTIPLE_BLOCK;
1861 else
1862 opcode = MMC_WRITE_BLOCK;
1863 }
1864
1865 start_ccb->ccb_h.func_code = XPT_MMC_IO;
1866 start_ccb->ccb_h.flags = (bp->bio_cmd == BIO_READ ? CAM_DIR_IN : CAM_DIR_OUT);
1867 start_ccb->ccb_h.retry_count = 0;
1868 start_ccb->ccb_h.timeout = 15 * 1000;
1869 start_ccb->ccb_h.cbfcnp = sddadone;
1870
1871 mmcio = &start_ccb->mmcio;
1872 mmcio->cmd.opcode = opcode;
1873 mmcio->cmd.arg = blockno;
1874 if (!(mmcp->card_features & CARD_FEATURE_SDHC))
1875 mmcio->cmd.arg <<= 9;
1876
1877 mmcio->cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
1878 mmcio->cmd.data = softc->mmcdata;
1879 memset(mmcio->cmd.data, 0, sizeof(struct mmc_data));
1880 mmcio->cmd.data->data = bp->bio_data;
1881 mmcio->cmd.data->len = MMC_SECTOR_SIZE * count;
1882 mmcio->cmd.data->flags = (bp->bio_cmd == BIO_READ ? MMC_DATA_READ : MMC_DATA_WRITE);
1883 /* Direct h/w to issue CMD12 upon completion */
1884 if (count > 1) {
1885 mmcio->cmd.data->flags |= MMC_DATA_MULTI;
1886 mmcio->stop.opcode = MMC_STOP_TRANSMISSION;
1887 mmcio->stop.flags = MMC_RSP_R1B | MMC_CMD_AC;
1888 mmcio->stop.arg = 0;
1889 }
1890
1891 break;
1892 }
1893 case BIO_FLUSH:
1894 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("BIO_FLUSH\n"));
1895 sddaschedule(periph);
1896 break;
1897 case BIO_DELETE:
1898 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("BIO_DELETE\n"));
1899 sddaschedule(periph);
1900 break;
1901 default:
1902 biofinish(bp, NULL, EOPNOTSUPP);
1903 xpt_release_ccb(start_ccb);
1904 return;
1905 }
1906 start_ccb->ccb_h.ccb_bp = bp;
1907 softc->outstanding_cmds++;
1908 softc->refcount++;
1909 cam_periph_unlock(periph);
1910 xpt_action(start_ccb);
1911 cam_periph_lock(periph);
1912
1913 /* May have more work to do, so ensure we stay scheduled */
1914 sddaschedule(periph);
1915}
1916
1917static void
1918sddadone(struct cam_periph *periph, union ccb *done_ccb)
1919{
1920 struct bio *bp;
1921 struct sdda_softc *softc;
1922 struct ccb_mmcio *mmcio;
1923 struct cam_path *path;
1924 uint32_t card_status;
1925 int error = 0;
1926
1927 softc = (struct sdda_softc *)periph->softc;
1928 mmcio = &done_ccb->mmcio;
1929 path = done_ccb->ccb_h.path;
1930
1931 CAM_DEBUG(path, CAM_DEBUG_TRACE, ("sddadone\n"));
1932 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1933 CAM_DEBUG(path, CAM_DEBUG_TRACE, ("Error!!!\n"));
1934 if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
1935 cam_release_devq(path,
1936 /*relsim_flags*/0,
1937 /*reduction*/0,
1938 /*timeout*/0,
1939 /*getcount_only*/0);
1940 error = EIO;
1941 } else {
1942 if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
1943 panic("REQ_CMP with QFRZN");
1944 error = 0;
1945 }
1946
1947 card_status = mmcio->cmd.resp[0];
1949 ("Card status: %08x\n", R1_STATUS(card_status)));
1951 ("Current state: %d\n", R1_CURRENT_STATE(card_status)));
1952
1953 /* Process result of switching MMC partitions */
1954 if (softc->state == SDDA_STATE_PART_SWITCH) {
1956 ("Completing partition switch to %d\n",
1957 softc->part_requested));
1958 softc->outstanding_cmds--;
1959 /* Complete partition switch */
1960 softc->state = SDDA_STATE_NORMAL;
1961 if (error != 0) {
1962 /* TODO: Unpause retune if accessing RPMB */
1963 xpt_release_ccb(done_ccb);
1965 return;
1966 }
1967
1968 softc->raw_ext_csd[EXT_CSD_PART_CONFIG] =
1969 (softc->raw_ext_csd[EXT_CSD_PART_CONFIG] &
1970 ~EXT_CSD_PART_CONFIG_ACC_MASK) | softc->part_requested;
1971 /* TODO: Unpause retune if accessing RPMB */
1972 softc->part_curr = softc->part_requested;
1973 xpt_release_ccb(done_ccb);
1974
1975 /* Return to processing BIO requests */
1977 return;
1978 }
1979
1980 bp = (struct bio *)done_ccb->ccb_h.ccb_bp;
1981 bp->bio_error = error;
1982 if (error != 0) {
1983 bp->bio_resid = bp->bio_bcount;
1984 bp->bio_flags |= BIO_ERROR;
1985 } else {
1986 /* XXX: How many bytes remaining? */
1987 bp->bio_resid = 0;
1988 if (bp->bio_resid > 0)
1989 bp->bio_flags |= BIO_ERROR;
1990 }
1991
1992 softc->outstanding_cmds--;
1993 xpt_release_ccb(done_ccb);
1994 /*
1995 * Release the periph refcount taken in sddastart() for each CCB.
1996 */
1997 KASSERT(softc->refcount >= 1, ("sddadone softc %p refcount %d", softc, softc->refcount));
1998 softc->refcount--;
1999 biodone(bp);
2000}
2001
2002static int
2003sddaerror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags)
2004{
2005 return(cam_periph_error(ccb, cam_flags, sense_flags));
2006}
2007
2008static int
2009sddadump(void *arg, void *virtual, vm_offset_t physical, off_t offset,
2010 size_t length)
2011{
2012 struct ccb_mmcio mmcio;
2013 struct disk *dp;
2014 struct sdda_part *part;
2015 struct sdda_softc *softc;
2016 struct cam_periph *periph;
2017 struct mmc_params *mmcp;
2018 uint16_t count;
2019 uint16_t opcode;
2020 int error;
2021
2022 dp = arg;
2023 part = dp->d_drv1;
2024 softc = part->sc;
2025 periph = softc->periph;
2026 mmcp = &periph->path->device->mmc_ident_data;
2027
2028 if (softc->state != SDDA_STATE_NORMAL)
2029 return (ENXIO);
2030
2031 count = length / MMC_SECTOR_SIZE;
2032 if (count == 0)
2033 return (0);
2034
2035 if (softc->part[softc->part_curr] != part)
2036 return (EIO); /* TODO implement polled partition switch */
2037
2038 memset(&mmcio, 0, sizeof(mmcio));
2039 xpt_setup_ccb(&mmcio.ccb_h, periph->path, CAM_PRIORITY_NORMAL); /* XXX needed? */
2040
2041 mmcio.ccb_h.func_code = XPT_MMC_IO;
2042 mmcio.ccb_h.flags = CAM_DIR_OUT;
2043 mmcio.ccb_h.retry_count = 0;
2044 mmcio.ccb_h.timeout = 15 * 1000;
2045
2046 if (count > 1)
2047 opcode = MMC_WRITE_MULTIPLE_BLOCK;
2048 else
2049 opcode = MMC_WRITE_BLOCK;
2050 mmcio.cmd.opcode = opcode;
2051 mmcio.cmd.arg = offset / MMC_SECTOR_SIZE;
2052 if (!(mmcp->card_features & CARD_FEATURE_SDHC))
2053 mmcio.cmd.arg <<= 9;
2054
2055 mmcio.cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
2056 mmcio.cmd.data = softc->mmcdata;
2057 memset(mmcio.cmd.data, 0, sizeof(struct mmc_data));
2058 mmcio.cmd.data->data = virtual;
2059 mmcio.cmd.data->len = MMC_SECTOR_SIZE * count;
2060 mmcio.cmd.data->flags = MMC_DATA_WRITE;
2061
2062 /* Direct h/w to issue CMD12 upon completion */
2063 if (count > 1) {
2064 mmcio.cmd.data->flags |= MMC_DATA_MULTI;
2065 mmcio.stop.opcode = MMC_STOP_TRANSMISSION;
2066 mmcio.stop.flags = MMC_RSP_R1B | MMC_CMD_AC;
2067 mmcio.stop.arg = 0;
2068 }
2069
2070 error = cam_periph_runccb((union ccb *)&mmcio, cam_periph_error,
2071 0, SF_NO_RECOVERY | SF_NO_RETRY, NULL);
2072 if (error != 0)
2073 printf("Aborting dump due to I/O error.\n");
2074 return (error);
2075}
2076
2077#endif /* _KERNEL */
@ SF_NO_RETRY
Definition: cam.h:127
@ SF_NO_RECOVERY
Definition: cam.h:126
cam_flags
Definition: cam.h:115
@ CAM_FLAG_NONE
Definition: cam.h:116
#define CAM_PRIORITY_NORMAL
Definition: cam.h:92
#define CAM_PRIORITY_NONE
Definition: cam.h:93
#define CAM_PRIORITY_XPT
Definition: cam.h:89
cam_status
Definition: cam.h:132
@ CAM_REQ_INPROG
Definition: cam.h:134
@ CAM_REQ_CMP
Definition: cam.h:137
@ CAM_REQ_CMP_ERR
Definition: cam.h:146
@ CAM_STATUS_MASK
Definition: cam.h:302
@ CAM_DEV_QFRZN
Definition: cam.h:287
@ AC_ADVINFO_CHANGED
Definition: cam_ccb.h:868
@ AC_FOUND_DEVICE
Definition: cam_ccb.h:874
@ AC_GETDEV_CHANGED
Definition: cam_ccb.h:870
@ AC_LOST_DEVICE
Definition: cam_ccb.h:873
#define MMC_CAP_4_BIT_DATA
Definition: cam_ccb.h:1072
@ PROTO_MMCSD
Definition: cam_ccb.h:285
#define MMC_VCCQ
Definition: cam_ccb.h:1065
#define MMC_CAP_HSPEED
Definition: cam_ccb.h:1074
#define MMC_CAP_SIGNALING_120
Definition: cam_ccb.h:1093
static __inline void cam_fill_mmcio(struct ccb_mmcio *mmcio, uint32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), uint32_t flags, uint32_t mmc_opcode, uint32_t mmc_arg, uint32_t mmc_flags, struct mmc_data *mmc_d, uint32_t timeout)
Definition: cam_ccb.h:1479
#define MMC_CAP_BOOT_NOACC
Definition: cam_ccb.h:1075
#define MMC_CAP_SIGNALING_180
Definition: cam_ccb.h:1094
@ CAM_DIR_IN
Definition: cam_ccb.h:79
@ CAM_DIR_NONE
Definition: cam_ccb.h:81
@ CAM_DIR_OUT
Definition: cam_ccb.h:80
#define MMC_CAP_8_BIT_DATA
Definition: cam_ccb.h:1073
#define MMC_BW
Definition: cam_ccb.h:1061
@ XPT_GET_TRAN_SETTINGS
Definition: cam_ccb.h:183
@ XPT_MMC_IO
Definition: cam_ccb.h:220
@ XPT_SET_TRAN_SETTINGS
Definition: cam_ccb.h:188
@ XPT_PATH_INQ
Definition: cam_ccb.h:147
@ XPT_GDEV_TYPE
Definition: cam_ccb.h:143
#define MMC_BT
Definition: cam_ccb.h:1063
#define XPORT_DEVSTAT_TYPE(t)
Definition: cam_ccb.h:310
#define CDAI_TYPE_PHYS_PATH
Definition: cam_ccb.h:1317
#define MMC_CLK
Definition: cam_ccb.h:1058
@ CAM_DEBUG_TRACE
Definition: cam_debug.h:41
@ CAM_DEBUG_PERIPH
Definition: cam_debug.h:45
#define CAM_DEBUG(path, flag, printfargs)
Definition: cam_debug.h:93
u_int32_t cam_release_devq(struct cam_path *path, u_int32_t relsim_flags, u_int32_t openings, u_int32_t arg, int getcount_only)
Definition: cam_periph.c:1342
int cam_periph_acquire(struct cam_periph *periph)
Definition: cam_periph.c:413
void cam_periph_async(struct cam_periph *periph, u_int32_t code, struct cam_path *path, void *arg)
Definition: cam_periph.c:1471
void cam_periph_release(struct cam_periph *periph)
Definition: cam_periph.c:465
void cam_periph_unhold(struct cam_periph *periph)
Definition: cam_periph.c:519
int cam_periph_hold(struct cam_periph *periph, int priority)
Definition: cam_periph.c:486
int cam_periph_runccb(union ccb *ccb, int(*error_routine)(union ccb *ccb, cam_flags camflags, u_int32_t sense_flags), cam_flags camflags, u_int32_t sense_flags, struct devstat *ds)
Definition: cam_periph.c:1207
int cam_periph_error(union ccb *ccb, cam_flags camflags, u_int32_t sense_flags)
Definition: cam_periph.c:1864
cam_status cam_periph_alloc(periph_ctor_t *periph_ctor, periph_oninv_t *periph_oninvalidate, periph_dtor_t *periph_dtor, periph_start_t *periph_start, char *name, cam_periph_type type, struct cam_path *path, ac_callback_t *ac_callback, ac_code code, void *arg)
Definition: cam_periph.c:197
cam_status periph_ctor_t(struct cam_periph *periph, void *arg)
Definition: cam_periph.h:115
#define CAM_PERIPH_INVALID
Definition: cam_periph.h:133
void periph_oninv_t(struct cam_periph *periph)
Definition: cam_periph.h:117
#define cam_periph_lock(periph)
Definition: cam_periph.h:224
#define cam_periph_unlock(periph)
Definition: cam_periph.h:227
void periph_dtor_t(struct cam_periph *periph)
Definition: cam_periph.h:118
void periph_start_t(struct cam_periph *periph, union ccb *start_ccb)
Definition: cam_periph.h:113
#define cam_periph_sleep(periph, chan, priority, wmesg, timo)
Definition: cam_periph.h:233
@ CAM_PERIPH_BIO
Definition: cam_periph.h:104
void() periph_init_t(void)
Definition: cam_periph.h:85
static __inline bool cam_sim_pollable(const struct cam_sim *sim)
Definition: cam_sim.h:139
union ccb * xpt_alloc_ccb(void)
Definition: cam_xpt.c:4612
void xpt_print_path(struct cam_path *path)
Definition: cam_xpt.c:3786
void xpt_schedule(struct cam_periph *periph, u_int32_t new_priority)
Definition: cam_xpt.c:3243
int xpt_getattr(char *buf, size_t len, const char *attr, struct cam_path *path)
Definition: cam_xpt.c:1243
void xpt_print(struct cam_path *path, const char *fmt,...)
Definition: cam_xpt.c:3814
void xpt_announce_periph(struct cam_periph *periph, char *announce_string)
Definition: cam_xpt.c:1049
void xpt_setup_ccb(struct ccb_hdr *ccb_h, struct cam_path *path, u_int32_t priority)
Definition: cam_xpt.c:3520
void xpt_action(union ccb *start_ccb)
Definition: cam_xpt.c:2601
cam_status xpt_register_async(int event, ac_callback_t *cbfunc, void *cbarg, struct cam_path *path)
Definition: cam_xpt.c:5213
void xpt_release_ccb(union ccb *free_ccb)
Definition: cam_xpt.c:3924
void xpt_free_ccb(union ccb *free_ccb)
Definition: cam_xpt.c:4630
#define CARD_FEATURE_SDHC
Definition: mmc.h:88
#define CARD_FEATURE_MEMORY
Definition: mmc.h:87
#define CARD_FEATURE_SD20
Definition: mmc.h:90
#define CARD_FEATURE_MMC
Definition: mmc.h:91
static int sdda_mmcsd_compat
Definition: mmc_da.c:192
static periph_ctor_t sddaregister
Definition: mmc_da.c:171
static int mmc_switch(struct cam_periph *periph, union ccb *ccb, uint8_t set, uint8_t index, uint8_t value, u_int timeout)
Definition: mmc_da.c:958
static int sddaclose(struct disk *dp)
Definition: mmc_da.c:473
static void mmc_decode_cid_sd(uint32_t *raw_cid, struct mmc_cid *cid)
Definition: mmc_da.c:366
static uint32_t mmc_get_spec_vers(struct cam_periph *periph)
Definition: mmc_da.c:970
static uint32_t mmc_get_sector_size(struct cam_periph *periph)
Definition: mmc_da.c:187
static dumper_t sddadump
Definition: mmc_da.c:167
static uint64_t mmc_get_media_size(struct cam_periph *periph)
Definition: mmc_da.c:977
static int mmc_set_timing(struct cam_periph *periph, union ccb *ccb, enum mmc_bus_timing timing)
Definition: mmc_da.c:1028
static bool sdda_get_read_only(struct cam_periph *periph, union ccb *start_ccb)
Definition: mmc_da.c:197
static int sddagetattr(struct bio *bp)
Definition: mmc_da.c:732
static periph_oninv_t sddaoninvalidate
Definition: mmc_da.c:174
static int mmc_sd_switch(struct cam_periph *periph, union ccb *ccb, uint8_t mode, uint8_t grp, uint8_t value, uint8_t *res)
Definition: mmc_da.c:994
static const char * mmc_errmsg[]
Definition: mmc_da.c:153
static int sddaerror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags)
Definition: mmc_da.c:2003
static int mmc_app_get_scr(struct cam_periph *periph, union ccb *ccb, uint32_t *rawscr)
Definition: mmc_da.c:847
static int mmc_send_ext_csd(struct cam_periph *periph, union ccb *ccb, uint8_t *rawextcsd, size_t buf_len)
Definition: mmc_da.c:872
static void sddadiskgonecb(struct disk *dp)
Definition: mmc_da.c:583
static void sdda_start_init(void *context, union ccb *start_ccb)
Definition: mmc_da.c:1224
static SYSCTL_NODE(_kern_cam, OID_AUTO, sdda, CTLFLAG_RD|CTLFLAG_MPSAFE, 0, "CAM Direct Access Disk driver")
static int sddaopen(struct disk *dp)
Definition: mmc_da.c:442
#define SDDA_FMT_GP
Definition: mmc_da.c:95
static void mmc_decode_csd_sd(uint32_t *raw_csd, struct mmc_csd *csd)
Definition: mmc_da.c:280
static void sdda_process_mmc_partitions(struct cam_periph *periph, union ccb *start_ccb)
Definition: mmc_da.c:1624
static void sdda_set_bus_width(struct cam_periph *periph, union ccb *ccb, int width)
Definition: mmc_da.c:1092
sdda_flags
Definition: mmc_da.c:82
@ SDDA_FLAG_DIRTY
Definition: mmc_da.c:84
@ SDDA_FLAG_OPEN
Definition: mmc_da.c:83
static MALLOC_DEFINE(M_SDDA, "sd_da", "sd_da buffers")
#define SDDA_FMT_RPMB
Definition: mmc_da.c:96
static void mmc_switch_fill_mmcio(union ccb *ccb, uint8_t set, uint8_t index, uint8_t value, u_int timeout)
Definition: mmc_da.c:917
static int mmc_select_card(struct cam_periph *periph, union ccb *ccb, uint32_t rca)
Definition: mmc_da.c:937
static const int mant[16]
Definition: mmc_da.c:223
static int mmc_handle_reply(union ccb *ccb)
Definition: mmc_da.c:247
static void sddaschedule(struct cam_periph *periph)
Definition: mmc_da.c:496
static disk_strategy_t sddastrategy
Definition: mmc_da.c:166
static const int exp[8]
Definition: mmc_da.c:219
static const char * part_type(u_int type)
Definition: mmc_da.c:1145
static void sdda_start_init_task(void *context, int pending)
Definition: mmc_da.c:1073
static uint32_t sdda_get_host_caps(struct cam_periph *periph, union ccb *ccb)
Definition: mmc_da.c:1184
__FBSDID("$FreeBSD$")
static void mmc_decode_cid_mmc(uint32_t *raw_cid, struct mmc_cid *cid)
Definition: mmc_da.c:384
sdda_state
Definition: mmc_da.c:87
@ SDDA_STATE_PART_SWITCH
Definition: mmc_da.c:91
@ SDDA_STATE_NORMAL
Definition: mmc_da.c:90
@ SDDA_STATE_INVALID
Definition: mmc_da.c:89
@ SDDA_STATE_INIT
Definition: mmc_da.c:88
#define SDDA_FMT_BOOT
Definition: mmc_da.c:94
static const int cur_max[8]
Definition: mmc_da.c:231
static void mmc_format_card_id_string(struct sdda_softc *sc, struct mmc_params *mmcp)
Definition: mmc_da.c:402
static void sddaasync(void *callback_arg, u_int32_t code, struct cam_path *path, void *arg)
Definition: mmc_da.c:649
SYSCTL_INT(_kern_cam_sdda, OID_AUTO, mmcsd_compat, CTLFLAG_RDTUN, &sdda_mmcsd_compat, 1, "Enable creation of mmcsd aliases.")
static void mmc_app_decode_scr(uint32_t *raw_scr, struct mmc_scr *scr)
Definition: mmc_da.c:900
static const char * bus_width_str(enum mmc_bus_width w)
Definition: mmc_da.c:1168
static bool sdda_add_part(struct cam_periph *periph, u_int type, const char *name, u_int cnt, off_t media_size, bool ro)
Definition: mmc_da.c:1507
static const int cur_min[8]
Definition: mmc_da.c:227
static periph_start_t sddastart
Definition: mmc_da.c:173
static periph_init_t sddainit
Definition: mmc_da.c:168
static void sddadone(struct cam_periph *periph, union ccb *done_ccb)
Definition: mmc_da.c:1918
static uint32_t mmc_get_bits(uint32_t *bits, int bit_len, int start, int size)
Definition: mmc_da.c:269
static void sdda_init_switch_part(struct cam_periph *periph, union ccb *start_ccb, uint8_t part)
Definition: mmc_da.c:1759
static uint32_t sdda_get_max_data(struct cam_periph *periph, union ccb *ccb)
Definition: mmc_da.c:1203
PERIPHDRIVER_DECLARE(sdda, sddadriver)
#define SDDA_PART_NAMELEN
Definition: mmc_da.c:99
static int mmc_exec_app_cmd(struct cam_periph *periph, union ccb *ccb, struct mmc_command *cmd)
Definition: mmc_da.c:792
static periph_dtor_t sddacleanup
Definition: mmc_da.c:172
static struct periph_driver sddadriver
Definition: mmc_da.c:209
static void mmc_decode_csd_mmc(uint32_t *raw_csd, struct mmc_csd *csd)
Definition: mmc_da.c:327
static uint16_t get_rca(struct cam_periph *periph)
Definition: mmc_da.c:236
static uint32_t mmc_get_cmd6_timeout(struct cam_periph *periph)
Definition: mmc_da.c:984
struct ccb_trans_settings_mmc * cts
Definition: mmc_sim_if.m:43
struct mmc_params mmc_ident_data
struct cam_ed * device
u_int32_t unit_number
Definition: cam_periph.h:127
void * softc
Definition: cam_periph.h:125
struct cam_path * path
Definition: cam_periph.h:124
u_int32_t flags
Definition: cam_periph.h:129
struct cam_sim * sim
Definition: cam_periph.h:126
cam_proto protocol
Definition: cam_ccb.h:380
struct ccb_hdr ccb_h
Definition: cam_ccb.h:379
u_int32_t flags
Definition: cam_ccb.h:368
struct cam_path * path
Definition: cam_ccb.h:364
xpt_opcode func_code
Definition: cam_ccb.h:362
u_int32_t timeout
Definition: cam_ccb.h:373
u_int32_t status
Definition: cam_ccb.h:363
u_int16_t retry_count
Definition: cam_ccb.h:354
void(* cbfcnp)(struct cam_periph *, union ccb *)
Definition: cam_ccb.h:360
struct mmc_command stop
Definition: cam_ccb.h:814
struct mmc_command cmd
Definition: cam_ccb.h:813
struct ccb_hdr ccb_h
Definition: cam_ccb.h:811
struct mmc_ios ios
Definition: cam_ccb.h:1057
uint32_t host_max_data
Definition: cam_ccb.h:1101
struct ccb_trans_settings_mmc mmc
Definition: cam_ccb.h:1117
union ccb_trans_settings::@3 proto_specific
Definition: mmc.h:66
uint32_t card_features
Definition: mmc.h:86
uint16_t card_rca
Definition: mmc.h:83
struct sdda_softc * sc
Definition: mmc_da.c:107
struct bio_queue_head bio_queue
Definition: mmc_da.c:105
bool ro
Definition: mmc_da.c:110
struct disk * disk
Definition: mmc_da.c:104
u_int type
Definition: mmc_da.c:109
char name[SDDA_PART_NAMELEN]
Definition: mmc_da.c:111
sdda_flags flags
Definition: mmc_da.c:106
u_int cnt
Definition: mmc_da.c:108
struct mmc_csd csd
Definition: mmc_da.c:124
int refcount
Definition: mmc_da.c:116
uint32_t vccq_180
Definition: mmc_da.c:141
uint8_t raw_ext_csd[512]
Definition: mmc_da.c:123
uint64_t sector_count
Definition: mmc_da.c:128
uint32_t card_f_max
Definition: mmc_da.c:135
struct mmc_cid cid
Definition: mmc_da.c:125
int outstanding_cmds
Definition: mmc_da.c:115
uint32_t vccq_120
Definition: mmc_da.c:140
int log_count
Definition: mmc_da.c:149
off_t enh_size
Definition: mmc_da.c:148
uint64_t mediasize
Definition: mmc_da.c:129
struct task start_init_task
Definition: mmc_da.c:121
uint32_t cmd6_time
Definition: mmc_da.c:138
struct cam_periph * periph
Definition: mmc_da.c:119
uint32_t part_time
Definition: mmc_da.c:146
uint8_t part_curr
Definition: mmc_da.c:144
sdda_state state
Definition: mmc_da.c:117
char card_sn_string[16]
Definition: mmc_da.c:133
struct sdda_part * part[MMC_PART_MAX]
Definition: mmc_da.c:143
struct mmc_scr scr
Definition: mmc_da.c:126
off_t enh_base
Definition: mmc_da.c:147
uint32_t raw_csd[4]
Definition: mmc_da.c:122
struct timeval log_time
Definition: mmc_da.c:150
char card_id_string[64]
Definition: mmc_da.c:132
struct mmc_data * mmcdata
Definition: mmc_da.c:118
uint8_t part_requested
Definition: mmc_da.c:145
uint32_t timings
Definition: mmc_da.c:139
Definition: cam_ccb.h:1345
struct ccb_trans_settings cts
Definition: cam_ccb.h:1357
struct ccb_mmcio mmcio
Definition: cam_ccb.h:1380
struct ccb_hdr ccb_h
Definition: cam_ccb.h:1346