static int sd_welcome_card(struct sd_host *host) { int retval; /* soft reset the card */ retval = sd_reset_sequence(host); if (retval < 0 || sd_card_is_bad(host)) goto out; /* read Operating Conditions Register */ retval = sd_read_ocr(host); if (retval < 0) goto err_bad_card; /* refuse to drive cards reporting voltage ranges out of scope */ if (!(host->ocr & host->ocr_avail)) { sd_printk(KERN_WARNING, "reported OCR (%08x)" " indicates that it is not safe to use this" " card with a GameCube\n", host->ocr); retval = -ENODEV; goto err_bad_card; } /* read and decode the Card Specific Data */ retval = sd_read_csd(host); if (retval < 0) goto err_bad_card; mmc_decode_csd(&host->card); /* calculate some card access related timeouts */ sd_calc_timeouts(host); /* read and decode the Card Identification Data */ retval = sd_read_cid(host); if (retval < 0) goto err_bad_card; mmc_decode_cid(&host->card); sd_printk(KERN_INFO, "slot%d: descr \"%s\", size %luk, block %ub," " serial %08x\n", to_channel(exi_get_exi_channel(host->exi_device)), host->card.cid.prod_name, (unsigned long)((host->card.csd.capacity * (1 << host->card.csd.read_blkbits)) / 1024), 1 << host->card.csd.read_blkbits, host->card.cid.serial); retval = 0; goto out; err_bad_card: sd_card_set_bad(host); out: return retval; }
static int test_read_csd(struct harness_t *harness_p) { union sd_csd_t csd; /* Read CSD and print it to stdout. */ BTASSERT(sd_read_csd(&sd, &csd) == sizeof(csd)); switch (csd.v1.csd_structure) { case SD_CSD_STRUCTURE_V1: std_printf(FSTR("csd {\r\n" " csd_structure = %u\r\n" " taac = %u\r\n" " nsac = %u\r\n" " tran_speed = %u\r\n" " ccc = %u\r\n" " read_bl_len = %u\r\n" " read_bl_partial = %u\r\n" " write_blk_misalign = %u\r\n" " read_blk_misalign = %u\r\n" " dsr_imp = %u\r\n" " c_size = %u\r\n" " vdd_r_curr_min = %u\r\n" " vdd_r_curr_max = %u\r\n" " vdd_w_curr_min = %u\r\n" " vdd_w_cur_max = %u\r\n" " c_size_mult = %u\r\n" " erase_blk_en = %u\r\n" " sector_size = %u\r\n" " wp_grp_size = %u\r\n" " wp_grp_enable = %u\r\n" " r2w_factor = %u\r\n" " write_bl_len = %u\r\n" " write_bl_partial = %u\r\n" " file_format_grp = %u\r\n" " copy = %u\r\n" " perm_write_protect = %u\r\n" " tmp_write_protect = %u\r\n" " file_format = %u\r\n" " crc = 0x%02x\r\n" "}\r\n"), csd.v1.csd_structure, csd.v1.taac, csd.v1.nsac, csd.v1.tran_speed, SD_CCC(&csd.v1), csd.v1.read_bl_len, csd.v1.read_bl_partial, csd.v1.write_blk_misalign, csd.v1.read_blk_misalign, csd.v1.dsr_imp, SD_C_SIZE(&csd.v1), csd.v1.vdd_r_curr_min, csd.v1.vdd_r_curr_max, csd.v1.vdd_w_curr_min, csd.v1.vdd_w_curr_max, SD_C_SIZE_MULT(&csd.v1), csd.v1.erase_blk_en, SD_SECTOR_SIZE(&csd.v1), csd.v1.wp_grp_size, csd.v1.wp_grp_enable, csd.v1.r2w_factor, SD_WRITE_BL_LEN(&csd.v1), csd.v1.write_bl_partial, csd.v1.file_format_grp, csd.v1.copy, csd.v1.perm_write_protect, csd.v1.tmp_write_protect, csd.v1.file_format, csd.v1.crc); break; case SD_CSD_STRUCTURE_V2: std_printf(FSTR("csd {\r\n" " csd_structure = %u\r\n" " taac = %u\r\n" " nsac = %u\r\n" " tran_speed = %u\r\n" " ccc = %u\r\n" " read_bl_len = %u\r\n" " dsr_imp = %u\r\n" " read_blk_misalign = %u\r\n" " write_blk_misalign = %u\r\n" " read_bl_partial = %u\r\n" " c_size = %u\r\n" " sector_size = %u\r\n" " erase_blk_en = %u\r\n" " wp_grp_size = %u\r\n" " write_bl_len = %u\r\n" " r2w_factor = %u\r\n" " wp_grp_enable = %u\r\n" " write_partial = %u\r\n" " file_format = %u\r\n" " tmp_write_protect = %u\r\n" " perm_write_protect = %u\r\n" " copy = %u\r\n" " file_format_grp = %u\r\n" " crc = %u\r\n" "}\r\n"), csd.v2.csd_structure, csd.v2.taac, csd.v2.nsac, csd.v2.tran_speed, SD_CCC(&csd.v2), csd.v2.read_bl_len, csd.v2.dsr_imp, csd.v2.read_blk_misalign, csd.v2.write_blk_misalign, csd.v2.read_bl_partial, SD_C_SIZE(&csd.v2), SD_SECTOR_SIZE(&csd.v2), csd.v2.erase_blk_en, csd.v2.wp_grp_size, SD_WRITE_BL_LEN(&csd.v2), csd.v2.r2w_factor, csd.v2.wp_grp_enable, csd.v2.write_bl_partial, csd.v2.file_format, csd.v2.tmp_write_protect, csd.v2.perm_write_protect, csd.v2.copy, csd.v2.file_format_grp, csd.v2.crc); break; default: std_printf(FSTR("Unsuported csd structure %d.\r\n"), csd.v1.csd_structure); break; } return (0); }
/** * def read_cid(self) */ static mp_obj_t class_sd_read_csd(mp_obj_t self_in) { struct class_sd_t *self_p; union sd_csd_t csd; mp_obj_t tuple[29]; self_p = MP_OBJ_TO_PTR(self_in); if (sd_read_csd(&self_p->drv, &csd) != sizeof(csd)) { nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "sd_read_csd() failed")); } switch (csd.v1.csd_structure) { case SD_CSD_STRUCTURE_V1: tuple[0] = MP_OBJ_NEW_SMALL_INT(csd.v1.csd_structure); tuple[1] = MP_OBJ_NEW_SMALL_INT(csd.v1.taac); tuple[2] = MP_OBJ_NEW_SMALL_INT(csd.v1.nsac); tuple[3] = MP_OBJ_NEW_SMALL_INT(csd.v1.tran_speed); tuple[4] = MP_OBJ_NEW_SMALL_INT(SD_CCC(&csd.v1)); tuple[5] = MP_OBJ_NEW_SMALL_INT(csd.v1.read_bl_len); tuple[6] = MP_OBJ_NEW_SMALL_INT(csd.v1.read_bl_partial); tuple[7] = MP_OBJ_NEW_SMALL_INT(csd.v1.write_blk_misalign); tuple[8] = MP_OBJ_NEW_SMALL_INT(csd.v1.read_blk_misalign); tuple[9] = MP_OBJ_NEW_SMALL_INT(csd.v1.dsr_imp); tuple[10] = MP_OBJ_NEW_SMALL_INT(SD_C_SIZE(&csd.v1)); tuple[11] = MP_OBJ_NEW_SMALL_INT(csd.v1.vdd_r_curr_min); tuple[12] = MP_OBJ_NEW_SMALL_INT(csd.v1.vdd_r_curr_max); tuple[13] = MP_OBJ_NEW_SMALL_INT(csd.v1.vdd_w_curr_min); tuple[14] = MP_OBJ_NEW_SMALL_INT(csd.v1.vdd_w_curr_max); tuple[15] = MP_OBJ_NEW_SMALL_INT(SD_C_SIZE_MULT(&csd.v1)); tuple[16] = MP_OBJ_NEW_SMALL_INT(csd.v1.erase_blk_en); tuple[17] = MP_OBJ_NEW_SMALL_INT(SD_SECTOR_SIZE(&csd.v1)); tuple[18] = MP_OBJ_NEW_SMALL_INT(csd.v1.wp_grp_size); tuple[19] = MP_OBJ_NEW_SMALL_INT(csd.v1.wp_grp_enable); tuple[20] = MP_OBJ_NEW_SMALL_INT(csd.v1.r2w_factor); tuple[21] = MP_OBJ_NEW_SMALL_INT(SD_WRITE_BL_LEN(&csd.v1)); tuple[22] = MP_OBJ_NEW_SMALL_INT(csd.v1.write_bl_partial); tuple[23] = MP_OBJ_NEW_SMALL_INT(csd.v1.file_format_grp); tuple[24] = MP_OBJ_NEW_SMALL_INT(csd.v1.copy); tuple[25] = MP_OBJ_NEW_SMALL_INT(csd.v1.perm_write_protect); tuple[26] = MP_OBJ_NEW_SMALL_INT(csd.v1.tmp_write_protect); tuple[27] = MP_OBJ_NEW_SMALL_INT(csd.v1.file_format); tuple[28] = MP_OBJ_NEW_SMALL_INT(csd.v1.crc); return (mp_obj_new_attrtuple(&csd_v1_fields[0], 29, tuple)); case SD_CSD_STRUCTURE_V2: tuple[0] = MP_OBJ_NEW_SMALL_INT(csd.v2.csd_structure); tuple[1] = MP_OBJ_NEW_SMALL_INT(csd.v2.taac); tuple[2] = MP_OBJ_NEW_SMALL_INT(csd.v2.nsac); tuple[3] = MP_OBJ_NEW_SMALL_INT(csd.v2.tran_speed); tuple[4] = MP_OBJ_NEW_SMALL_INT(SD_CCC(&csd.v2)); tuple[5] = MP_OBJ_NEW_SMALL_INT(csd.v2.read_bl_len); tuple[6] = MP_OBJ_NEW_SMALL_INT(csd.v2.dsr_imp); tuple[7] = MP_OBJ_NEW_SMALL_INT(csd.v2.read_blk_misalign); tuple[8] = MP_OBJ_NEW_SMALL_INT(csd.v2.write_blk_misalign); tuple[9] = MP_OBJ_NEW_SMALL_INT(csd.v2.read_bl_partial); tuple[10] = MP_OBJ_NEW_SMALL_INT(SD_C_SIZE(&csd.v2)); tuple[11] = MP_OBJ_NEW_SMALL_INT(SD_SECTOR_SIZE(&csd.v2)); tuple[12] = MP_OBJ_NEW_SMALL_INT(csd.v2.erase_blk_en); tuple[13] = MP_OBJ_NEW_SMALL_INT(csd.v2.wp_grp_size); tuple[14] = MP_OBJ_NEW_SMALL_INT(SD_WRITE_BL_LEN(&csd.v2)); tuple[15] = MP_OBJ_NEW_SMALL_INT(csd.v2.r2w_factor); tuple[16] = MP_OBJ_NEW_SMALL_INT(csd.v2.wp_grp_enable); tuple[17] = MP_OBJ_NEW_SMALL_INT(csd.v2.write_bl_partial); tuple[18] = MP_OBJ_NEW_SMALL_INT(csd.v2.file_format); tuple[19] = MP_OBJ_NEW_SMALL_INT(csd.v2.tmp_write_protect); tuple[20] = MP_OBJ_NEW_SMALL_INT(csd.v2.perm_write_protect); tuple[21] = MP_OBJ_NEW_SMALL_INT(csd.v2.copy); tuple[22] = MP_OBJ_NEW_SMALL_INT(csd.v2.file_format_grp); tuple[23] = MP_OBJ_NEW_SMALL_INT(csd.v2.crc); return (mp_obj_new_attrtuple(&csd_v2_fields[0], 24, tuple)); default: return (mp_const_none); } }