44#include <sys/kernel.h>
46#include <sys/sysctl.h>
47#include <sys/endian.h>
48#include <sys/taskqueue.h>
52#include <sys/devicestat.h>
53#include <sys/eventhandler.h>
54#include <sys/malloc.h>
57#include <sys/reboot.h>
58#include <geom/geom_disk.h>
59#include <machine/_inttypes.h>
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"
99#define SDDA_PART_NAMELEN (16 + 1)
164#define ccb_bp ppriv_ptr1
169static void sddaasync(
void *callback_arg, u_int32_t code,
176 union ccb *done_ccb);
178 u_int32_t sense_flags);
189static SYSCTL_NODE(_kern_cam, OID_AUTO, sdda, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
190 "CAM Direct Access Disk driver");
193SYSCTL_INT(_kern_cam_sdda, OID_AUTO, mmcsd_compat, CTLFLAG_RDTUN,
207 const char *name, u_int cnt, off_t media_size,
bool ro);
219static const int exp[8] = {
220 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000
224 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80
228 500, 1000, 5000, 10000, 25000, 35000, 60000, 100000
232 1000, 5000, 10000, 25000, 35000, 45000, 800000, 200000
250 (
"ccb %p: cannot handle non-XPT_MMC_IO errors, got func_code=%d",
256 panic(
"CCB status is OK but MMC error != MMC_ERR_NONE");
260 printf(
"CMD%d failed, err %d (%s)\n",
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));
286 memset(csd, 0,
sizeof(*csd));
287 csd->csd_structure = v =
mmc_get_bits(raw_csd, 128, 126, 2);
292 csd->tacc = (
exp[e] *
mant[m] + 9) / 10;
296 csd->tran_speed =
exp[e] * 10000 *
mant[m];
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);
304 csd->erase_sector =
mmc_get_bits(raw_csd, 128, 39, 7) + 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);
318 csd->capacity = ((1 + m) << (e + 2)) * csd->read_bl_len;
320 csd->capacity = ((uint64_t)
mmc_get_bits(raw_csd, 128, 48, 22) + 1) *
323 panic(
"unknown SD CSD version");
332 memset(csd, 0,
sizeof(*csd));
333 csd->csd_structure =
mmc_get_bits(raw_csd, 128, 126, 2);
337 csd->tacc =
exp[e] *
mant[m] + 9 / 10;
341 csd->tran_speed =
exp[e] * 10000 *
mant[m];
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);
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) *
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);
371 memset(cid, 0,
sizeof(*cid));
374 for (i = 0; i < 5; i++)
375 cid->pnm[i] =
mmc_get_bits(raw_cid, 128, 96 - i * 8, 8);
379 cid->mdt_year =
mmc_get_bits(raw_cid, 128, 12, 8) + 2000;
389 memset(cid, 0,
sizeof(*cid));
392 for (i = 0; i < 6; i++)
393 cid->pnm[i] =
mmc_get_bits(raw_cid, 128, 96 - i * 8, 8);
398 cid->mdt_year =
mmc_get_bits(raw_cid, 128, 8, 4) + 1997;
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);
429 snprintf(oidstr,
sizeof(oidstr),
"0x%04x", sc->
cid.oid);
431 "%08X", sc->
cid.psn);
433 "%s%s %s %d.%d SN %08X MFG %02d/%04d by %d %s",
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);
507 for (i = 0; i < MMC_PART_MAX; i++) {
508 if ((
part = softc->
part[i]) != NULL &&
543 biofinish(bp, NULL, ENXIO);
573 printf(
"sdda: Failed to attach master async callback "
574 "due to status 0x%x!\n", status);
616 for (
int i = 0; i < MMC_PART_MAX; i++) {
617 if ((
part = softc->
part[i]) != NULL) {
637 for (i = 0; i < MMC_PART_MAX; i++) {
638 if ((
part = softc->
part[i]) != NULL) {
640 free(
part, M_DEVBUF);
641 softc->
part[i] = NULL;
644 free(softc, M_DEVBUF);
689 printf(
"sddaasync: Unable to attach to new device "
690 "due to status 0x%x\n", status);
696 memset(&cgd, 0,
sizeof(cgd));
709 buftype = (uintptr_t)arg;
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",
739 part = (
struct sdda_part *)bp->bio_disk->d_drv1;
743 ret =
xpt_getattr(bp->bio_data, bp->bio_length, bp->bio_attribute,
747 bp->bio_completed = bp->bio_length;
760 printf(
"sddaregister: no getdev CCB, can't register device\n");
764 softc = (
struct sdda_softc *)malloc(
sizeof(*softc), M_DEVBUF,
767 printf(
"sddaregister: Unable to probe new device. "
768 "Unable to allocate softc\n");
774 (
struct mmc_data *)malloc(
sizeof(
struct mmc_data), M_DEVBUF, M_NOWAIT|M_ZERO);
776 printf(
"sddaregister: Unable to probe new device. "
777 "Unable to allocate mmcdata\n");
778 free(softc, M_DEVBUF);
781 periph->
softc = softc;
793 struct mmc_command *cmd) {
797 memset(&
ccb->
mmcio.
cmd, 0,
sizeof(
struct mmc_command));
798 memset(&
ccb->
mmcio.
stop, 0,
sizeof(
struct mmc_command));
805 MMC_RSP_R1 | MMC_CMD_AC,
818 if (cmd->data != NULL) {
820 if (cmd->data->flags & MMC_DATA_READ)
822 if (cmd->data->flags & MMC_DATA_WRITE)
840 memcpy(cmd->resp,
ccb->
mmcio.
cmd.resp,
sizeof(cmd->resp));
849 struct mmc_command cmd;
852 memset(&cmd, 0,
sizeof(cmd));
853 memset(&d, 0,
sizeof(d));
855 memset(rawscr, 0, 8);
856 cmd.opcode = ACMD_SEND_SCR;
857 cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
862 d.flags = MMC_DATA_READ;
866 rawscr[0] = be32toh(rawscr[0]);
867 rawscr[1] = be32toh(rawscr[1]);
873 uint8_t *rawextcsd,
size_t buf_len) {
877 KASSERT(buf_len == 512, (
"Buffer for ext csd must be 512 bytes"));
878 memset(&d, 0,
sizeof(d));
881 d.flags = MMC_DATA_READ;
882 memset(d.data, 0, d.len);
890 MMC_RSP_R1 | MMC_CMD_ADTC,
902 unsigned int scr_struct;
904 memset(scr, 0,
sizeof(*scr));
907 if (scr_struct != 0) {
908 printf(
"Unrecognised SCR structure version %d\n",
918 uint8_t set, uint8_t index, uint8_t value, u_int timeout)
920 int arg = (MMC_SWITCH_FUNC_WR << 24) |
931 MMC_RSP_R1B | MMC_CMD_AC,
941 flags = (rca ? MMC_RSP_R1B : MMC_RSP_NONE) | MMC_CMD_AC;
959 uint8_t set, uint8_t index, uint8_t value, u_int timeout)
973 return (softc->
csd.spec_vers);
989 return (softc->
raw_ext_csd[EXT_CSD_GEN_CMD6_TIME] * 10);
995 uint8_t mode, uint8_t grp, uint8_t value,
997 struct mmc_data mmc_d;
1002 memset(&mmc_d, 0,
sizeof(mmc_d));
1005 mmc_d.flags = MMC_DATA_READ;
1009 arg &= ~(0xF << (grp * 4));
1010 arg |= value << (grp * 4);
1018 MMC_RSP_R1 | MMC_CMD_ADTC,
1030 enum mmc_bus_timing timing)
1032 u_char switch_res[64];
1039 (
"mmc_set_timing(timing=%d)", timing));
1041 case bus_timing_normal:
1048 return (MMC_ERR_INVALID);
1052 EXT_CSD_HS_TIMING, value, softc->
cmd6_time);
1065 cts->
ios.timing = timing;
1104 value = EXT_CSD_BUS_WIDTH_1;
1107 value = EXT_CSD_BUS_WIDTH_4;
1110 value = EXT_CSD_BUS_WIDTH_8;
1113 panic(
"Invalid bus width %d", width);
1116 EXT_CSD_BUS_WIDTH, value, softc->
cmd6_time);
1119 struct mmc_command cmd;
1120 memset(&cmd, 0,
sizeof(
struct mmc_command));
1121 cmd.opcode = ACMD_SET_BUS_WIDTH;
1123 cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
1127 if (err != MMC_ERR_NONE) {
1139 cts->
ios.bus_width = width;
1144static inline const char
1149 case EXT_CSD_PART_CONFIG_ACC_RPMB:
1151 case EXT_CSD_PART_CONFIG_ACC_DEFAULT:
1153 case EXT_CSD_PART_CONFIG_ACC_BOOT0:
1155 case EXT_CSD_PART_CONFIG_ACC_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");
1163 return (
"(unknown type)");
1167static inline const char
1179 __assert_unreachable();
1198 panic(
"Cannot get host caps");
1218 panic(
"Cannot get host max data");
1254 (
"Cannot read EXT_CSD, err %d", err));
1273 if (sec_count != 0) {
1281 (
"Capacity: %"PRIu64
", sectors: %"PRIu64
"\n",
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);
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);
1297 strlcpy(mmcp->model, softc->
card_id_string,
sizeof(mmcp->model));
1311 panic(
"Cannot get max host freq");
1314 if (
cts->
ios.bus_width != bus_width_1)
1315 panic(
"Bus width in ios is not 1-bit");
1328 goto finish_hs_tests;
1332 if ((softc->
scr.sda_vsn >= 1) && (softc->
csd.ccc & (1<<10))) {
1334 SD_SWITCH_GROUP1, SD_SWITCH_NOCHANGE, res);
1354 goto finish_hs_tests;
1359 card_type = softc->
raw_ext_csd[EXT_CSD_CARD_TYPE];
1360 if (card_type & EXT_CSD_CARD_TYPE_HS_52)
1362 else if (card_type & EXT_CSD_CARD_TYPE_HS_26)
1364 if ((card_type & EXT_CSD_CARD_TYPE_DDR_52_1_2V) != 0 &&
1366 setbit(&softc->
timings, bus_timing_mmc_ddr52);
1367 setbit(&softc->
vccq_120, bus_timing_mmc_ddr52);
1370 if ((card_type & EXT_CSD_CARD_TYPE_DDR_52_1_8V) != 0 &&
1372 setbit(&softc->
timings, bus_timing_mmc_ddr52);
1373 setbit(&softc->
vccq_180, bus_timing_mmc_ddr52);
1376 if ((card_type & EXT_CSD_CARD_TYPE_HS200_1_2V) != 0 &&
1378 setbit(&softc->
timings, bus_timing_mmc_hs200);
1379 setbit(&softc->
vccq_120, bus_timing_mmc_hs200);
1382 if ((card_type & EXT_CSD_CARD_TYPE_HS200_1_8V) != 0 &&
1384 setbit(&softc->
timings, bus_timing_mmc_hs200);
1385 setbit(&softc->
vccq_180, bus_timing_mmc_hs200);
1396 if (f_max > 25000000) {
1398 if (err != MMC_ERR_NONE) {
1404 enum mmc_bus_timing timing;
1406 for (timing = bus_timing_mmc_ddr52; timing > bus_timing_normal; timing--) {
1407 if (isset(&softc->
vccq_120, timing)) {
1418 }
else if (isset(&softc->
vccq_180, timing)) {
1436 cts->
ios.vccq = vccq_330;
1454 enum mmc_bus_width desired_bus_width = bus_width_1;
1455 enum mmc_bus_width max_host_bus_width =
1458 enum mmc_bus_width max_card_bus_width = bus_width_1;
1460 softc->
scr.bus_widths & SD_SCR_BUS_WIDTH_4)
1461 max_card_bus_width = bus_width_4;
1468 max_card_bus_width = bus_width_8;
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",
1508 u_int cnt, off_t media_size,
bool ro)
1515 (
"Partition type '%s', size %ju %s\n",
1518 ro ?
"(read-only)" :
""));
1520 part = sc->
part[type] = malloc(
sizeof(*
part), M_DEVBUF,
1523 printf(
"Cannot add partition for sdda\n");
1539 if (type == EXT_CSD_PART_CONFIG_ACC_RPMB) {
1542 (
"Don't know what to do with RPMB partitions yet\n"));
1548 bzero(&cpi,
sizeof(cpi));
1560 part->
disk->d_rotation_rate = DISK_RR_NON_ROTATING;
1562 cnt, MMC_SECTOR_SIZE,
1563 DEVSTAT_ALL_SUPPORTED,
1565 DEVSTAT_PRIORITY_DISK);
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;
1590 "%s%d", cpi.dev_name, cpi.unit_number);
1593 part->
disk->d_mediasize = media_size;
1599 disk_add_alias(
part->
disk,
"mmcsd");
1608 "registration!\n", __func__);
1612 disk_create(
part->
disk, DISK_VERSION);
1628 off_t erase_size, sector_size, size, wp_size;
1630 const uint8_t *ext_csd;
1641 rev = ext_csd[EXT_CSD_REV];
1647 comp = (ext_csd[EXT_CSD_PART_SET] & EXT_CSD_PART_SET_COMPLETED) != 0;
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 *
1669 wp_size = ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
1670 size *= erase_size * wp_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)) *
1680 (
"enhanced user data area spans entire device"));
1690 sc->
part_curr = EXT_CSD_PART_CONFIG_ACC_DEFAULT;
1698 (
"enhanced user data area off 0x%jx size %ju bytes\n",
1706 sc->
part_time = max(ext_csd[EXT_CSD_PART_SWITCH_TO] * 10 * 1000,
1710 size = ext_csd[EXT_CSD_BOOT_SIZE_MULT] * MMC_BOOT_RPMB_BLOCK_SIZE;
1714 ro | ((ext_csd[EXT_CSD_BOOT_WP_STATUS] &
1715 EXT_CSD_BOOT_WP_STATUS_BOOT0_MASK) != 0));
1718 ro | ((ext_csd[EXT_CSD_BOOT_WP_STATUS] &
1719 EXT_CSD_BOOT_WP_STATUS_BOOT1_MASK) != 0));
1723 size = ext_csd[EXT_CSD_RPMB_MULT] * MMC_BOOT_RPMB_BLOCK_SIZE;
1724 if (rev >= 5 && size > 0)
1728 if (rev <= 3 || comp == FALSE)
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 *
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);
1765 KASSERT(
part < MMC_PART_MAX, (
"%s: invalid partition index", __func__));
1769 ~EXT_CSD_PART_CONFIG_ACC_MASK) |
part;
1772 EXT_CSD_PART_CONFIG, value, sc->
part_time);
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)
1816 (
"Partition %d -> %d\n", softc->
part_curr, part_index));
1835 switch (bp->bio_cmd) {
1843 uint64_t blockno = bp->bio_pblkno;
1844 uint16_t count = bp->bio_bcount / MMC_SECTOR_SIZE;
1847 if (bp->bio_cmd == BIO_READ)
1850 (
"Block %"PRIu64
" cnt %u\n", blockno, count));
1853 if (bp->bio_cmd == BIO_READ) {
1855 opcode = MMC_READ_MULTIPLE_BLOCK;
1857 opcode = MMC_READ_SINGLE_BLOCK;
1860 opcode = MMC_WRITE_MULTIPLE_BLOCK;
1862 opcode = MMC_WRITE_BLOCK;
1871 mmcio = &start_ccb->
mmcio;
1872 mmcio->
cmd.opcode = opcode;
1873 mmcio->
cmd.arg = blockno;
1875 mmcio->
cmd.arg <<= 9;
1877 mmcio->
cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
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);
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;
1902 biofinish(bp, NULL, EOPNOTSUPP);
1906 start_ccb->
ccb_h.ccb_bp = bp;
1924 uint32_t card_status;
1928 mmcio = &done_ccb->
mmcio;
1943 panic(
"REQ_CMP with QFRZN");
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)));
1956 (
"Completing partition switch to %d\n",
1980 bp = (
struct bio *)done_ccb->
ccb_h.ccb_bp;
1981 bp->bio_error = error;
1983 bp->bio_resid = bp->bio_bcount;
1984 bp->bio_flags |= BIO_ERROR;
1988 if (bp->bio_resid > 0)
1989 bp->bio_flags |= BIO_ERROR;
1997 KASSERT(softc->
refcount >= 1, (
"sddadone softc %p refcount %d", softc, softc->
refcount));
2009sddadump(
void *arg,
void *
virtual, vm_offset_t physical, off_t offset,
2031 count = length / MMC_SECTOR_SIZE;
2038 memset(&mmcio, 0,
sizeof(mmcio));
2047 opcode = MMC_WRITE_MULTIPLE_BLOCK;
2049 opcode = MMC_WRITE_BLOCK;
2050 mmcio.
cmd.opcode = opcode;
2051 mmcio.
cmd.arg = offset / MMC_SECTOR_SIZE;
2053 mmcio.
cmd.arg <<= 9;
2055 mmcio.
cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
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;
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;
2073 printf(
"Aborting dump due to I/O error.\n");
#define CAM_PRIORITY_NORMAL
#define CAM_PRIORITY_NONE
#define MMC_CAP_4_BIT_DATA
#define MMC_CAP_SIGNALING_120
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)
#define MMC_CAP_BOOT_NOACC
#define MMC_CAP_SIGNALING_180
#define MMC_CAP_8_BIT_DATA
#define XPORT_DEVSTAT_TYPE(t)
#define CDAI_TYPE_PHYS_PATH
#define CAM_DEBUG(path, flag, printfargs)
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)
int cam_periph_acquire(struct cam_periph *periph)
void cam_periph_async(struct cam_periph *periph, u_int32_t code, struct cam_path *path, void *arg)
void cam_periph_release(struct cam_periph *periph)
void cam_periph_unhold(struct cam_periph *periph)
int cam_periph_hold(struct cam_periph *periph, int priority)
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)
int cam_periph_error(union ccb *ccb, cam_flags camflags, u_int32_t sense_flags)
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)
cam_status periph_ctor_t(struct cam_periph *periph, void *arg)
#define CAM_PERIPH_INVALID
void periph_oninv_t(struct cam_periph *periph)
#define cam_periph_lock(periph)
#define cam_periph_unlock(periph)
void periph_dtor_t(struct cam_periph *periph)
void periph_start_t(struct cam_periph *periph, union ccb *start_ccb)
#define cam_periph_sleep(periph, chan, priority, wmesg, timo)
void() periph_init_t(void)
static __inline bool cam_sim_pollable(const struct cam_sim *sim)
union ccb * xpt_alloc_ccb(void)
void xpt_print_path(struct cam_path *path)
void xpt_schedule(struct cam_periph *periph, u_int32_t new_priority)
int xpt_getattr(char *buf, size_t len, const char *attr, struct cam_path *path)
void xpt_print(struct cam_path *path, const char *fmt,...)
void xpt_announce_periph(struct cam_periph *periph, char *announce_string)
void xpt_setup_ccb(struct ccb_hdr *ccb_h, struct cam_path *path, u_int32_t priority)
void xpt_action(union ccb *start_ccb)
cam_status xpt_register_async(int event, ac_callback_t *cbfunc, void *cbarg, struct cam_path *path)
void xpt_release_ccb(union ccb *free_ccb)
void xpt_free_ccb(union ccb *free_ccb)
#define CARD_FEATURE_SDHC
#define CARD_FEATURE_MEMORY
#define CARD_FEATURE_SD20
static int sdda_mmcsd_compat
static periph_ctor_t sddaregister
static int mmc_switch(struct cam_periph *periph, union ccb *ccb, uint8_t set, uint8_t index, uint8_t value, u_int timeout)
static int sddaclose(struct disk *dp)
static void mmc_decode_cid_sd(uint32_t *raw_cid, struct mmc_cid *cid)
static uint32_t mmc_get_spec_vers(struct cam_periph *periph)
static uint32_t mmc_get_sector_size(struct cam_periph *periph)
static uint64_t mmc_get_media_size(struct cam_periph *periph)
static int mmc_set_timing(struct cam_periph *periph, union ccb *ccb, enum mmc_bus_timing timing)
static bool sdda_get_read_only(struct cam_periph *periph, union ccb *start_ccb)
static int sddagetattr(struct bio *bp)
static periph_oninv_t sddaoninvalidate
static int mmc_sd_switch(struct cam_periph *periph, union ccb *ccb, uint8_t mode, uint8_t grp, uint8_t value, uint8_t *res)
static const char * mmc_errmsg[]
static int sddaerror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags)
static int mmc_app_get_scr(struct cam_periph *periph, union ccb *ccb, uint32_t *rawscr)
static int mmc_send_ext_csd(struct cam_periph *periph, union ccb *ccb, uint8_t *rawextcsd, size_t buf_len)
static void sddadiskgonecb(struct disk *dp)
static void sdda_start_init(void *context, union ccb *start_ccb)
static SYSCTL_NODE(_kern_cam, OID_AUTO, sdda, CTLFLAG_RD|CTLFLAG_MPSAFE, 0, "CAM Direct Access Disk driver")
static int sddaopen(struct disk *dp)
static void mmc_decode_csd_sd(uint32_t *raw_csd, struct mmc_csd *csd)
static void sdda_process_mmc_partitions(struct cam_periph *periph, union ccb *start_ccb)
static void sdda_set_bus_width(struct cam_periph *periph, union ccb *ccb, int width)
static MALLOC_DEFINE(M_SDDA, "sd_da", "sd_da buffers")
static void mmc_switch_fill_mmcio(union ccb *ccb, uint8_t set, uint8_t index, uint8_t value, u_int timeout)
static int mmc_select_card(struct cam_periph *periph, union ccb *ccb, uint32_t rca)
static const int mant[16]
static int mmc_handle_reply(union ccb *ccb)
static void sddaschedule(struct cam_periph *periph)
static disk_strategy_t sddastrategy
static const char * part_type(u_int type)
static void sdda_start_init_task(void *context, int pending)
static uint32_t sdda_get_host_caps(struct cam_periph *periph, union ccb *ccb)
static void mmc_decode_cid_mmc(uint32_t *raw_cid, struct mmc_cid *cid)
static const int cur_max[8]
static void mmc_format_card_id_string(struct sdda_softc *sc, struct mmc_params *mmcp)
static void sddaasync(void *callback_arg, u_int32_t code, struct cam_path *path, void *arg)
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)
static const char * bus_width_str(enum mmc_bus_width w)
static bool sdda_add_part(struct cam_periph *periph, u_int type, const char *name, u_int cnt, off_t media_size, bool ro)
static const int cur_min[8]
static periph_start_t sddastart
static periph_init_t sddainit
static void sddadone(struct cam_periph *periph, union ccb *done_ccb)
static uint32_t mmc_get_bits(uint32_t *bits, int bit_len, int start, int size)
static void sdda_init_switch_part(struct cam_periph *periph, union ccb *start_ccb, uint8_t part)
static uint32_t sdda_get_max_data(struct cam_periph *periph, union ccb *ccb)
PERIPHDRIVER_DECLARE(sdda, sddadriver)
#define SDDA_PART_NAMELEN
static int mmc_exec_app_cmd(struct cam_periph *periph, union ccb *ccb, struct mmc_command *cmd)
static periph_dtor_t sddacleanup
static struct periph_driver sddadriver
static void mmc_decode_csd_mmc(uint32_t *raw_csd, struct mmc_csd *csd)
static uint16_t get_rca(struct cam_periph *periph)
static uint32_t mmc_get_cmd6_timeout(struct cam_periph *periph)
struct ccb_trans_settings_mmc * cts
struct mmc_params mmc_ident_data
void(* cbfcnp)(struct cam_periph *, union ccb *)
struct ccb_trans_settings_mmc mmc
union ccb_trans_settings::@3 proto_specific
struct bio_queue_head bio_queue
char name[SDDA_PART_NAMELEN]
struct task start_init_task
struct cam_periph * periph
struct sdda_part * part[MMC_PART_MAX]
struct mmc_data * mmcdata
struct ccb_trans_settings cts