static int mmc_max_clock_set(void *data, u64 val) { struct mmc_host *host = data; int err = -EINVAL; unsigned long freq = val; unsigned int old_freq; if (!host || (val < host->f_min)) goto out; mmc_rpm_hold(host, &host->class_dev); mmc_claim_host(host); if (host->bus_ops && host->bus_ops->change_bus_speed) { old_freq = host->f_max; host->f_max = freq; err = host->bus_ops->change_bus_speed(host, &freq); if (err) host->f_max = old_freq; } mmc_release_host(host); mmc_rpm_release(host, &host->class_dev); out: return err; }
static int mmc_clock_opt_set(void *data, u64 val) { struct mmc_host *host = data; /* We need this check due to input value is u64 */ if (val > host->f_max) return -EINVAL; mmc_rpm_hold(host, &host->class_dev); mmc_claim_host(host); mmc_set_clock(host, (unsigned int) val); mmc_release_host(host); mmc_rpm_release(host, &host->class_dev); return 0; }
static int mmc_clock_opt_set(void *data, u64 val) { struct mmc_host *host = data; if (val > host->f_max) return -EINVAL; mmc_rpm_hold(host, &host->class_dev); mmc_claim_host(host); mmc_set_clock(host, (unsigned int) val); mmc_release_host(host); mmc_rpm_release(host, &host->class_dev); return 0; }
static int mmc_dbg_card_status_get(void *data, u64 *val) { struct mmc_card *card = data; u32 status; int ret; mmc_rpm_hold(card->host, &card->dev); mmc_claim_host(card->host); ret = mmc_send_status(data, &status); if (!ret) *val = status; mmc_release_host(card->host); mmc_rpm_release(card->host, &card->dev); return ret; }
static int mmc_ext_csd_open(struct inode *inode, struct file *filp) { struct mmc_card *card = inode->i_private; char *buf; ssize_t n = 0; u8 *ext_csd; int err, i; buf = kmalloc(EXT_CSD_STR_LEN + 1, GFP_KERNEL); if (!buf) return -ENOMEM; ext_csd = kmalloc(512, GFP_KERNEL); if (!ext_csd) { err = -ENOMEM; goto out_free; } mmc_rpm_hold(card->host, &card->dev); mmc_claim_host(card->host); err = mmc_send_ext_csd(card, ext_csd); mmc_release_host(card->host); mmc_rpm_release(card->host, &card->dev); if (err) goto out_free; for (i = 511; i >= 0; i--) n += sprintf(buf + n, "%02x", ext_csd[i]); n += sprintf(buf + n, "\n"); BUG_ON(n != EXT_CSD_STR_LEN); filp->private_data = buf; kfree(ext_csd); return 0; out_free: kfree(buf); kfree(ext_csd); return err; }
static int mmc_ext_csd_open(struct inode *inode, struct file *filp) #endif { #ifdef CONFIG_MACH_LGE struct mmc_card *card = s->private; #else struct mmc_card *card = inode->i_private; char *buf; ssize_t n = 0; #endif u8 *ext_csd; #ifdef CONFIG_MACH_LGE u8 ext_csd_rev; int err; const char *str; char *buf_for_health_report; char *buf_for_firmwware_version; ssize_t output = 0; int cnt; #else int err, i; buf = kmalloc(EXT_CSD_STR_LEN + 1, GFP_KERNEL); if (!buf) return -ENOMEM; #endif ext_csd = kmalloc(512, GFP_KERNEL); if (!ext_csd) { err = -ENOMEM; goto out_free; } mmc_rpm_hold(card->host, &card->dev); mmc_claim_host(card->host); err = mmc_send_ext_csd(card, ext_csd); mmc_release_host(card->host); mmc_rpm_release(card->host, &card->dev); if (err) goto out_free; #ifdef CONFIG_MACH_LGE ext_csd_rev = ext_csd[192]; #else for (i = 0; i < 512; i++) n += sprintf(buf + n, "%02x", ext_csd[i]); n += sprintf(buf + n, "\n"); BUG_ON(n != EXT_CSD_STR_LEN); filp->private_data = buf; kfree(ext_csd); return 0; #endif #ifdef CONFIG_MACH_LGE switch (ext_csd_rev) { case 7: str = "5.0"; break; case 6: str = "4.5"; break; case 5: str = "4.41"; break; case 3: str = "4.3"; break; case 2: str = "4.2"; break; case 1: str = "4.1"; break; case 0: str = "4.0"; break; default: goto out_free; } seq_printf(s, "Extended CSD rev 1.%d (MMC %s)\n", ext_csd_rev, str); if (ext_csd_rev < 3) goto out_free; /* No ext_csd */ if (ext_csd_rev >= 7) { seq_printf(s, "[505] Extended Security Commands Error, ext_security_err: 0x%02x\n", ext_csd[505]); } seq_printf(s, "[504] Supported Command Sets, s_cmd_set: 0x%02x\n", ext_csd[504]); seq_printf(s, "[503] HPI features, hpi_features: 0x%02x\n", ext_csd[503]); seq_printf(s, "[502] Background operations support, bkops_support: 0x%02x\n", ext_csd[502]); if (ext_csd_rev >= 6) { seq_printf(s, "[501] Max packed read commands, max_packed_reads: 0x%02x\n", ext_csd[501]); seq_printf(s, "[500] Max packed write commands, max_packed_writes: 0x%02x\n", ext_csd[500]); seq_printf(s, "[499] Data Tag Support, data_tag_support: 0x%02x\n", ext_csd[499]); seq_printf(s, "[498] Tag Unit Size, tag_unit_size: 0x%02x\n", ext_csd[498]); seq_printf(s, "[497] Tag Resources Size, tag_res_size: 0x%02x\n", ext_csd[497]); seq_printf(s, "[496] Context management capabilities, context_capabilities: 0x%02x\n", ext_csd[496]); seq_printf(s, "[495] Large Unit size, large_unit_size_m1: 0x%02x\n", ext_csd[495]); seq_printf(s, "[494] Extended partitions attribute support, ext_support: 0x%02x\n", ext_csd[494]); if (ext_csd_rev >= 7) { buf_for_health_report = kmalloc(66, GFP_KERNEL); if (!buf_for_health_report) return -ENOMEM; buf_for_firmwware_version = kmalloc(18, GFP_KERNEL); if (!buf_for_firmwware_version) return -ENOMEM; seq_printf(s, "[493] Supported modes, supported_modes: 0x%02x\n", ext_csd[493]); seq_printf(s, "[492] Ffu features, ffu_features: 0x%02x\n", ext_csd[492]); seq_printf(s, "[491] Operation codes timeout, operation_code_timeout: 0x%02x\n", ext_csd[491]); seq_printf(s, "[490:487] Ffu features, ffu_features: 0x%08x\n", (ext_csd[487] << 0) | (ext_csd[488] << 8) | (ext_csd[489] << 16) | (ext_csd[490] << 24)); seq_printf(s, "[305:302] Number of FW sectors correctly programmed, number_of_fw_sectors_correctly_programmed: 0x%08x\n", (ext_csd[302] << 0) | (ext_csd[303] << 8) | (ext_csd[304] << 16) | (ext_csd[305] << 24)); output = 0; for (cnt = 301 ; cnt >= 270 ; cnt--) output += sprintf(buf_for_health_report + output, "%02x", ext_csd[cnt]); output += sprintf(buf_for_health_report + output, "\n"); seq_printf(s, "[301:270] Vendor proprietary health report, vendor_proprietary_health_report(raw data): %s", buf_for_health_report); //mina.park; kfree(buf_for_health_report); seq_printf(s, "[269] Device life time estimation type B, device_life_time_est_typ_b: 0x%02x\n", ext_csd[269]); seq_printf(s, "[268] Device life time estimation type A, device_life_time_est_typ_a: 0x%02x\n", ext_csd[268]); seq_printf(s, "[267] Pre EOL information, pre_eol_info: 0x%02x\n", ext_csd[267]); seq_printf(s, "[266] Optimal read size, optimal_read_size: 0x%02x\n", ext_csd[266]); seq_printf(s, "[265] Optimal write size, optimal_write_size: 0x%02x\n", ext_csd[265]); seq_printf(s, "[264] Optimal trim unit size, optimal_trim_unit_size: 0x%02x\n", ext_csd[264]); seq_printf(s, "[263:262] Device version, device_version: 0x%02x\n", (ext_csd[262] << 0) | (ext_csd[263] << 8)); output=0; for (cnt = 261 ; cnt >= 254 ; cnt--) output += sprintf(buf_for_firmwware_version + output, "%02x", ext_csd[cnt]); output += sprintf(buf_for_firmwware_version + output, "\n"); seq_printf(s, "[261:254] Firmware version, firmwware_version(raw data): %s", buf_for_firmwware_version); //mina.park; kfree(buf_for_firmwware_version); seq_printf(s, "[253] Power class for 200MHz, DDR at VCC=3.6V, pwr_cl_ddr_200_360: 0x%02x\n", ext_csd[253]); } seq_printf(s, "[252:249] Cache size, cache_size %d KiB\n", (ext_csd[249] << 0) | (ext_csd[250] << 8) | (ext_csd[251] << 16) | (ext_csd[252] << 24)); seq_printf(s, "[248] Generic CMD6 timeout, generic_cmd6_time: 0x%02x\n", ext_csd[248]); seq_printf(s, "[247] Power off notification timeout, power_off_long_time: 0x%02x\n", ext_csd[247]); seq_printf(s, "[246] Background operations status, bkops_status: 0x%02x\n", ext_csd[246]); seq_printf(s, "[245:242] Number of correctly programmed sectors, correctly_prg_sectors_num %d KiB\n", (ext_csd[242] << 0) | (ext_csd[243] << 8) | (ext_csd[244] << 16) | (ext_csd[245] << 24)); } if (ext_csd_rev >= 5) { seq_printf(s, "[241] 1st initialization time after partitioning, ini_timeout_ap: 0x%02x\n", ext_csd[241]); seq_printf(s, "[239] Power class for 52MHz, DDR at 3.6V, pwr_cl_ddr_52_360: 0x%02x\n", ext_csd[239]); seq_printf(s, "[238] POwer class for 52MHz, DDR at 1.95V, pwr_cl_ddr_52_195: 0x%02x\n", ext_csd[238]); if (ext_csd_rev >= 6) { seq_printf(s, "[237] Power class for 200MHz, SDR at 3.6V, pwr_cl_200_360: 0x%02x\n", ext_csd[237]); seq_printf(s, "[236] Power class for 200MHz, SDR at 1.95V, pwr_cl_200_195: 0x%02x\n", ext_csd[236]); } seq_printf(s, "[235] Minimun Write Performance for 8bit at 52MHz in DDR mode, min_perf_ddr_w_8_52: 0x%02x\n", ext_csd[235]); seq_printf(s, "[234] Minimun Read Performance for 8bit at 52MHz in DDR modemin_perf_ddr_r_8_52: 0x%02x\n", ext_csd[234]); seq_printf(s, "[232] TRIM Multiplier, trim_mult: 0x%02x\n", ext_csd[232]); seq_printf(s, "[231] Secure Feature support, sec_feature_support: 0x%02x\n", ext_csd[231]); } if (ext_csd_rev == 5 || ext_csd_rev == 7) { /* Obsolete in 4.5 */ /*---->revived in 5.0*/ seq_printf(s, "[230] Secure Erase Multiplier, sec_erase_mult: 0x%02x\n", ext_csd[230]); seq_printf(s, "[229] Secure TRIM Multiplier, sec_trim_mult: 0x%02x\n", ext_csd[229]); } seq_printf(s, "[228] Boot information, boot_info: 0x%02x\n", ext_csd[228]); seq_printf(s, "[226] Boot partition size, boot_size_mult : 0x%02x\n", ext_csd[226]); seq_printf(s, "[225] Access size, acc_size: 0x%02x\n", ext_csd[225]); seq_printf(s, "[224] High-capacity erase unit size, hc_erase_grp_size: 0x%02x\n", ext_csd[224]); seq_printf(s, "[223] High-capacity erase timeout, erase_timeout_mult: 0x%02x\n", ext_csd[223]); seq_printf(s, "[222] Reliable write sector count, rel_wr_sec_c: 0x%02x\n", ext_csd[222]); seq_printf(s, "[221] High-capacity write protect group size, hc_wp_grp_size: 0x%02x\n", ext_csd[221]); seq_printf(s, "[220] Sleep current(VCC), s_c_vcc: 0x%02x\n", ext_csd[220]); seq_printf(s, "[219] Sleep current(VCCQ), s_c_vccq: 0x%02x\n", ext_csd[219]); if (ext_csd_rev == 7) { seq_printf(s, "[218] Production state awareness timeout, production_state_awareness_timeout: 0x%02x\n", ext_csd[218]); } seq_printf(s, "[217] Sleep/awake timeout, s_a_timeout: 0x%02x\n", ext_csd[217]); if (ext_csd_rev == 7) { seq_printf(s, "[216] Sleep notification timeout, sleep_notification_time: 0x%02x\n", ext_csd[216]); } seq_printf(s, "[215:212] Sector Count, sec_count: 0x%08x\n", (ext_csd[215] << 24) |(ext_csd[214] << 16) | (ext_csd[213] << 8) | ext_csd[212]); seq_printf(s, "[210] Minimum Write Performance for 8bit at 52MHz, min_perf_w_8_52: 0x%02x\n", ext_csd[210]); seq_printf(s, "[209] Minimum Read Performance for 8bit at 52MHz, min_perf_r_8_52: 0x%02x\n", ext_csd[209]); seq_printf(s, "[208] Minimum Write Performance for 8bit at 26MHz, for 4bit at 52MHz, min_perf_w_8_26_4_52: 0x%02x\n", ext_csd[208]); seq_printf(s, "[207] Minimum Read Performance for 8bit at 26MHz, for 4bit at 52MHz, min_perf_r_8_26_4_52: 0x%02x\n", ext_csd[207]); seq_printf(s, "[206] Minimum Write Performance for 4bit at 26MHz, min_perf_w_4_26: 0x%02x\n", ext_csd[206]); seq_printf(s, "[205] Minimum Read Performance for 4bit at 26MHz, min_perf_r_4_26: 0x%02x\n", ext_csd[205]); seq_printf(s, "[203] Power class for 26MHz at 3.6V, pwr_cl_26_360: 0x%02x\n", ext_csd[203]); seq_printf(s, "[202] Power class for 52MHz at 3.6V, pwr_cl_52_360: 0x%02x\n", ext_csd[202]); seq_printf(s, "[201] Power class for 26MHz at 1.95V, pwr_cl_26_195: 0x%02x\n", ext_csd[201]); seq_printf(s, "[200] Power class for 52MHz at 1.95V, pwr_cl_52_195: 0x%02x\n", ext_csd[200]); if (ext_csd_rev >= 5) { seq_printf(s, "[199] Partition switching timing, partition_switch_time: 0x%02x\n", ext_csd[199]); seq_printf(s, "[198] Out-of-interrupt busy timing, out_of_interrupt_time: 0x%02x\n", ext_csd[198]); } if (ext_csd_rev >= 6) seq_printf(s, "[197] IO Driver Strength, driver_strength: 0x%02x\n", ext_csd[197]); seq_printf(s, "[196] Device type, device_type: 0x%02x\n", ext_csd[196]); seq_printf(s, "[194] CSD structure version, csd_structure: 0x%02x\n", ext_csd[194]); seq_printf(s, "[192] Extended CSD revision, ext_csd_rev: 0x%02x\n", ext_csd[192]); seq_printf(s, "[191] Command set, cmd_set: 0x%02x\n", ext_csd[191]); seq_printf(s, "[189] Command set revision, cmd_set_rev: 0x%02x\n", ext_csd[189]); seq_printf(s, "[187] Power class, power_class: 0x%02x\n", ext_csd[187]); seq_printf(s, "[185] High-speed interface timing, hs_timing: 0x%02x\n", ext_csd[185]); seq_printf(s, "[181] Erased memory content, erased_mem_cont: 0x%02x\n", ext_csd[181]); seq_printf(s, "[179] Partition configuration, partition_config: 0x%02x\n", ext_csd[179]); seq_printf(s, "[178] Boot config protection, boot_config_prot: 0x%02x\n", ext_csd[178]); seq_printf(s, "[177] Boot bus Conditions, boot_bus_conditions: 0x%02x\n", ext_csd[177]); seq_printf(s, "[175] High-density erase group definition, erase_group_def: 0x%02x\n", ext_csd[175]); if (ext_csd_rev >= 5) { seq_printf(s, "[174] Boot write protection status registers, boot_wp_status: 0x%02x\n", ext_csd[174]); seq_printf(s, "[173] Boot area write protection register, boot_wp: 0x%02x\n", ext_csd[173]); seq_printf(s, "[171] User area write protection register, user_wp: 0x%02x\n", ext_csd[171]); seq_printf(s, "[169] FW configuration, fw_config: 0x%02x\n", ext_csd[169]); seq_printf(s, "[168] RPMB Size, rpmb_size_mult: 0x%02x\n", ext_csd[168]); seq_printf(s, "[167] Write reliability setting register, wr_rel_set: 0x%02x\n", ext_csd[167]); seq_printf(s, "[166] Write reliability parameter register, wr_rel_param: 0x%02x\n", ext_csd[166]); seq_printf(s, "[163] Enable background operations handshake, bkops_en: 0x%02x\n", ext_csd[163]); seq_printf(s, "[162] H/W reset function, rst_n_function: 0x%02x\n", ext_csd[162]); seq_printf(s, "[161] HPI management, hpi_mgmt: 0x%02x\n", ext_csd[161]); seq_printf(s, "[160] Partitioning Support, partitioning_support: 0x%02x\n", ext_csd[160]); seq_printf(s, "[159:157] Max Enhanced Area Size, max_enh_size_mult: 0x%06x\n", (ext_csd[159] << 16) | (ext_csd[158] << 8) |ext_csd[157]); seq_printf(s, "[156] Partitions attribute, partitions_attribute: 0x%02x\n", ext_csd[156]); seq_printf(s, "[155] Partitioning Setting, partition_setting_completed: 0x%02x\n", ext_csd[155]); seq_printf(s, "[154:152] General Purpose Partition Size, gp_size_mult_4: 0x%06x\n", (ext_csd[154] << 16) |(ext_csd[153] << 8) | ext_csd[152]); seq_printf(s, "[151:149] General Purpose Partition Size, gp_size_mult_3: 0x%06x\n", (ext_csd[151] << 16) |(ext_csd[150] << 8) | ext_csd[149]); seq_printf(s, "[148:146] General Purpose Partition Size, gp_size_mult_2: 0x%06x\n", (ext_csd[148] << 16) |(ext_csd[147] << 8) | ext_csd[146]); seq_printf(s, "[145:143] General Purpose Partition Size, gp_size_mult_1: 0x%06x\n", (ext_csd[145] << 16) |(ext_csd[144] << 8) | ext_csd[143]); seq_printf(s, "[142:140] Enhanced User Data Area Size, enh_size_mult: 0x%06x\n", (ext_csd[142] << 16) |(ext_csd[141] << 8) | ext_csd[140]); seq_printf(s, "[139:136] Enhanced User Data Start Address, enh_start_addr: 0x%06x\n", (ext_csd[139] << 24) | (ext_csd[138] << 16) | (ext_csd[137] << 8) | ext_csd[136]); seq_printf(s, "[134] Bad Block Management mode, sec_bad_blk_mgmnt: 0x%02x\n", ext_csd[134]); } if (ext_csd_rev >= 6) { int j; seq_printf(s, "[131] Periodic Wake-up, periodic_wakeup: 0x%02x\n", ext_csd[131]); seq_printf(s, "[130] Program CID CSD in DDR mode support, program_cid_csd_ddr_support: 0x%02x\n", ext_csd[130]); for (j = 127; j >= 64; j--) seq_printf(s, "[127:64] Vendor Specific Fields, vendor_specific_field[%d]: 0x%02x\n", j, ext_csd[j]); seq_printf(s, "[63] Native sector size, native_sector_size: 0x%02x\n", ext_csd[63]); seq_printf(s, "[62] Sector size emulation, use_native_sector: 0x%02x\n", ext_csd[62]); seq_printf(s, "[61] Sector size, data_sector_size: 0x%02x\n", ext_csd[61]); seq_printf(s, "[60] 1st initialization after disabling sector size emulation, ini_timeout_emu: 0x%02x\n", ext_csd[60]); seq_printf(s, "[59] Class 6 commands control, class_6_ctrl: 0x%02x\n", ext_csd[59]); seq_printf(s, "[58] Number of addressed group to be Released, dyncap_needed: 0x%02x\n", ext_csd[58]); seq_printf(s, "[57:56] Exception events control, exception_events_ctrl: 0x%04x\n", (ext_csd[57] << 8) | ext_csd[56]); seq_printf(s, "[55:54] Exception events status, exception_events_status: 0x%04x\n", (ext_csd[55] << 8) | ext_csd[54]); seq_printf(s, "[53:52] Extended Partitions Attribute, ext_partitions_attribute: 0x%04x\n", (ext_csd[53] << 8) | ext_csd[52]); for (j = 51; j >= 37; j--) seq_printf(s, "[51:37]Context configuration, context_conf[%d]: 0x%02x\n", j, ext_csd[j]); seq_printf(s, "[36] Packed command status, packed_command_status: 0x%02x\n", ext_csd[36]); seq_printf(s, "[35] Packed command failure index, packed_failure_index: 0x%02x\n", ext_csd[35]); seq_printf(s, "[34] Power Off Notification, power_off_notification: 0x%02x\n", ext_csd[34]); seq_printf(s, "[33] Control to turn the Cache On Off, cache_ctrl: 0x%02x\n", ext_csd[33]); } #endif out_free: #ifndef CONFIG_MACH_LGE kfree(buf); #endif kfree(ext_csd); return err; }
static int mmc_ext_csd_open(struct inode *inode, struct file *filp) #endif { #ifdef CONFIG_MACH_LGE /* LGE_CHANGE * http://www.mail-archive.com/[email protected]/msg10669.html * 2013-06-28, [email protected] */ struct mmc_card *card = s->private; #else struct mmc_card *card = inode->i_private; char *buf; ssize_t n = 0; #endif u8 *ext_csd; #ifdef CONFIG_MACH_LGE /* LGE_CHANGE * http://www.mail-archive.com/[email protected]/msg10669.html * 2013-06-28, [email protected] */ u8 ext_csd_rev; int err; const char *str; #else int err, i; buf = kmalloc(EXT_CSD_STR_LEN + 1, GFP_KERNEL); if (!buf) return -ENOMEM; #endif ext_csd = kmalloc(512, GFP_KERNEL); if (!ext_csd) { err = -ENOMEM; goto out_free; } mmc_rpm_hold(card->host, &card->dev); mmc_claim_host(card->host); err = mmc_send_ext_csd(card, ext_csd); mmc_release_host(card->host); mmc_rpm_release(card->host, &card->dev); if (err) goto out_free; #ifdef CONFIG_MACH_LGE /* LGE_CHANGE * http://www.mail-archive.com/[email protected]/msg10669.html * 2013-06-28, [email protected] */ ext_csd_rev = ext_csd[192]; #else for (i = 511; i >= 0; i--) n += sprintf(buf + n, "%02x", ext_csd[i]); n += sprintf(buf + n, "\n"); BUG_ON(n != EXT_CSD_STR_LEN); filp->private_data = buf; kfree(ext_csd); return 0; #endif #ifdef CONFIG_MACH_LGE /* LGE_CHANGE * http://www.mail-archive.com/[email protected]/msg10669.html 2013-06-28, [email protected] */ switch (ext_csd_rev) { case 6: str = "4.5"; break; case 5: str = "4.41"; break; case 3: str = "4.3"; break; case 2: str = "4.2"; break; case 1: str = "4.1"; break; case 0: str = "4.0"; break; default: goto out_free; } seq_printf(s, "Extended CSD rev 1.%d (MMC %s)\n", ext_csd_rev, str); if (ext_csd_rev < 3) goto out_free; /* No ext_csd */ /* Parse the Extended CSD registers. * Reserved bit should be read as "0" in case of spec older * than A441. */ /* B45: reserved [511:505] */ seq_printf(s, "[504] Supported Command Sets, s_cmd_set: 0x%02x\n", ext_csd[504]); seq_printf(s, "[503] HPI features, hpi_features: 0x%02x\n", ext_csd[503]); seq_printf(s, "[502] Background operations support, bkops_support: 0x%02x\n", ext_csd[502]); if (ext_csd_rev >= 6) { seq_printf(s, "[501] Max packed read commands, max_packed_reads: 0x%02x\n", ext_csd[501]); seq_printf(s, "[500] Max packed write commands, max_packed_writes: 0x%02x\n", ext_csd[500]); seq_printf(s, "[499] Data Tag Support, data_tag_support: 0x%02x\n", ext_csd[499]); seq_printf(s, "[498] Tag Unit Size, tag_unit_size: 0x%02x\n", ext_csd[498]); seq_printf(s, "[497] Tag Resources Size, tag_res_size: 0x%02x\n", ext_csd[497]); seq_printf(s, "[496] Context management capabilities, context_capabilities: 0x%02x\n", ext_csd[496]); seq_printf(s, "[495] Large Unit size, large_unit_size_m1: 0x%02x\n", ext_csd[495]); seq_printf(s, "[494] Extended partitions attribute support, ext_support: 0x%02x\n", ext_csd[494]); /* B45: reserved [493:253] */ seq_printf(s, "[252:249] Cache size, cache_size %d KiB\n", ext_csd[249] << 0 | (ext_csd[250] << 8) | (ext_csd[251] << 16) | (ext_csd[252] << 24)); seq_printf(s, "[248] Generic CMD6 timeout, generic_cmd6_time: 0x%02x\n", ext_csd[248]); seq_printf(s, "[247] Power off notification timeout, power_off_long_time: 0x%02x\n", ext_csd[247]); seq_printf(s, "[246] Background operations status, bkops_status: 0x%02x\n", ext_csd[246]); seq_printf(s, "[245:242] Number of correctly programmed sectors, correctly_prg_sectors_num %d KiB\n", ext_csd[242] << 0 | (ext_csd[243] << 8) | (ext_csd[244] << 16) | (ext_csd[245] << 24)); } /* B45: Reserved [493:253] * A441: Reserved [501:247] * A43: reserved [246:229] */ if (ext_csd_rev >= 5) { seq_printf(s, "[241] 1st initialization time after partitioning, ini_timeout_ap: 0x%02x\n", ext_csd[241]); /* B45: reserved [240] */ /* A441: reserved [240] */ seq_printf(s, "[239] Power class for 52MHz, DDR at 3.6V, pwr_cl_ddr_52_360: 0x%02x\n", ext_csd[239]); seq_printf(s, "[238] POwer class for 52MHz, DDR at 1.95V, pwr_cl_ddr_52_195: 0x%02x\n", ext_csd[238]); /* A441: reserved [237-236] */ if (ext_csd_rev >= 6) { seq_printf(s, "[237] Power class for 200MHz, SDR at 3.6V, pwr_cl_200_360: 0x%02x\n", ext_csd[237]); seq_printf(s, "[236] Power class for 200MHz, SDR at 1.95V, pwr_cl_200_195: 0x%02x\n", ext_csd[236]); } seq_printf(s, "[235] Minimun Write Performance for 8bit at 52MHz in DDR mode, min_perf_ddr_w_8_52: 0x%02x\n", ext_csd[235]); seq_printf(s, "[234] Minimun Read Performance for 8bit at 52MHz in DDR modemin_perf_ddr_r_8_52: 0x%02x\n", ext_csd[234]); /* B45: reserved [233] */ /* A441: reserved [233] */ seq_printf(s, "[232] TRIM Multiplier, trim_mult: 0x%02x\n", ext_csd[232]); seq_printf(s, "[231] Secure Feature support, sec_feature_support: 0x%02x\n", ext_csd[231]); } if (ext_csd_rev == 5) { /* Obsolete in 4.5 */ seq_printf(s, "[230] Secure Erase Multiplier, sec_erase_mult: 0x%02x\n", ext_csd[230]); seq_printf(s, "[229] Secure TRIM Multiplier, sec_trim_mult: 0x%02x\n", ext_csd[229]); } seq_printf(s, "[228] Boot information, boot_info: 0x%02x\n", ext_csd[228]); /* B45: reserved [227] */ /* A441/A43: reserved [227] */ seq_printf(s, "[226] Boot partition size, boot_size_mult : 0x%02x\n", ext_csd[226]); seq_printf(s, "[225] Access size, acc_size: 0x%02x\n", ext_csd[225]); seq_printf(s, "[224] High-capacity erase unit size, hc_erase_grp_size: 0x%02x\n", ext_csd[224]); seq_printf(s, "[223] High-capacity erase timeout, erase_timeout_mult: 0x%02x\n", ext_csd[223]); seq_printf(s, "[222] Reliable write sector count, rel_wr_sec_c: 0x%02x\n", ext_csd[222]); seq_printf(s, "[221] High-capacity write protect group size, hc_wp_grp_size: 0x%02x\n", ext_csd[221]); seq_printf(s, "[220] Sleep current(VCC), s_c_vcc: 0x%02x\n", ext_csd[220]); seq_printf(s, "[219] Sleep current(VCCQ), s_c_vccq: 0x%02x\n", ext_csd[219]); /* B45: reserved [218] */ /* A441/A43: reserved [218] */ seq_printf(s, "[217] Sleep/awake timeout, s_a_timeout: 0x%02x\n", ext_csd[217]); /* B45: reserved [216] */ /* A441/A43: reserved [216] */ seq_printf(s, "[215:212] Sector Count, sec_count: 0x%08x\n", (ext_csd[215] << 24) | (ext_csd[214] << 16) | (ext_csd[213] << 8) | ext_csd[212]); /* B45: reserved [211] */ /* A441/A43: reserved [211] */ seq_printf(s, "[210] Minimum Write Performance for 8bit at 52MHz, min_perf_w_8_52: 0x%02x\n", ext_csd[210]); seq_printf(s, "[209] Minimum Read Performance for 8bit at 52MHz, min_perf_r_8_52: 0x%02x\n", ext_csd[209]); seq_printf(s, "[208] Minimum Write Performance for 8bit at 26MHz, for 4bit at 52MHz, min_perf_w_8_26_4_52: 0x%02x\n", ext_csd[208]); seq_printf(s, "[207] Minimum Read Performance for 8bit at 26MHz, for 4bit at 52MHz, min_perf_r_8_26_4_52: 0x%02x\n", ext_csd[207]); seq_printf(s, "[206] Minimum Write Performance for 4bit at 26MHz, min_perf_w_4_26: 0x%02x\n", ext_csd[206]); seq_printf(s, "[205] Minimum Read Performance for 4bit at 26MHz, min_perf_r_4_26: 0x%02x\n", ext_csd[205]); /* B45: reserved [204] */ /* A441/A43: reserved [204] */ seq_printf(s, "[203] Power class for 26MHz at 3.6V, pwr_cl_26_360: 0x%02x\n", ext_csd[203]); seq_printf(s, "[202] Power class for 52MHz at 3.6V, pwr_cl_52_360: 0x%02x\n", ext_csd[202]); seq_printf(s, "[201] Power class for 26MHz at 1.95V, pwr_cl_26_195: 0x%02x\n", ext_csd[201]); seq_printf(s, "[200] Power class for 52MHz at 1.95V, pwr_cl_52_195: 0x%02x\n", ext_csd[200]); /* A43: reserved [199:198] */ if (ext_csd_rev >= 5) { seq_printf(s, "[199] Partition switching timing, partition_switch_time: 0x%02x\n", ext_csd[199]); seq_printf(s, "[198] Out-of-interrupt busy timing, out_of_interrupt_time: 0x%02x\n", ext_csd[198]); } /* B45: reserved [195] [193] [190] [188] [186] [184] [182] [180] [176] */ /* A441/A43: reserved [197] [195] [193] [190] [188] * [186] [184] [182] [180] [176] */ if (ext_csd_rev >= 6) seq_printf(s, "[197] IO Driver Strength, driver_strength: 0x%02x\n", ext_csd[197]); seq_printf(s, "[196] Device type, device_type: 0x%02x\n", ext_csd[196]); seq_printf(s, "[194] CSD structure version, csd_structure: 0x%02x\n", ext_csd[194]); seq_printf(s, "[192] Extended CSD revision, ext_csd_rev: 0x%02x\n", ext_csd[192]); seq_printf(s, "[191] Command set, cmd_set: 0x%02x\n", ext_csd[191]); seq_printf(s, "[189] Command set revision, cmd_set_rev: 0x%02x\n", ext_csd[189]); seq_printf(s, "[187] Power class, power_class: 0x%02x\n", ext_csd[187]); seq_printf(s, "[185] High-speed interface timing, hs_timing: 0x%02x\n", ext_csd[185]); /* bus_width: ext_csd[183] not readable */ seq_printf(s, "[181] Erased memory content, erased_mem_cont: 0x%02x\n", ext_csd[181]); seq_printf(s, "[179] Partition configuration, partition_config: 0x%02x\n", ext_csd[179]); seq_printf(s, "[178] Boot config protection, boot_config_prot: 0x%02x\n", ext_csd[178]); seq_printf(s, "[177] Boot bus Conditions, boot_bus_conditions: 0x%02x\n", ext_csd[177]); seq_printf(s, "[175] High-density erase group definition, erase_group_def: 0x%02x\n", ext_csd[175]); /* A43: reserved [174:0] */ if (ext_csd_rev >= 5) { seq_printf(s, "[174] Boot write protection status registers, boot_wp_status: 0x%02x\n", ext_csd[174]); seq_printf(s, "[173] Boot area write protection register, boot_wp: 0x%02x\n", ext_csd[173]); /* B45, A441: reserved [172] */ seq_printf(s, "[171] User area write protection register, user_wp: 0x%02x\n", ext_csd[171]); /* B45, A441: reserved [170] */ seq_printf(s, "[169] FW configuration, fw_config: 0x%02x\n", ext_csd[169]); seq_printf(s, "[168] RPMB Size, rpmb_size_mult: 0x%02x\n", ext_csd[168]); seq_printf(s, "[167] Write reliability setting register, wr_rel_set: 0x%02x\n", ext_csd[167]); seq_printf(s, "[166] Write reliability parameter register, wr_rel_param: 0x%02x\n", ext_csd[166]); /* sanitize_start ext_csd[165]: not readable * bkops_start ext_csd[164]: only writable */ seq_printf(s, "[163] Enable background operations handshake, bkops_en: 0x%02x\n", ext_csd[163]); seq_printf(s, "[162] H/W reset function, rst_n_function: 0x%02x\n", ext_csd[162]); seq_printf(s, "[161] HPI management, hpi_mgmt: 0x%02x\n", ext_csd[161]); seq_printf(s, "[160] Partitioning Support, partitioning_support: 0x%02x\n", ext_csd[160]); seq_printf(s, "[159:157] Max Enhanced Area Size, max_enh_size_mult: 0x%06x\n", (ext_csd[159] << 16) | (ext_csd[158] << 8) | ext_csd[157]); seq_printf(s, "[156] Partitions attribute, partitions_attribute: 0x%02x\n", ext_csd[156]); seq_printf(s, "[155] Partitioning Setting, partition_setting_completed: 0x%02x\n", ext_csd[155]); seq_printf(s, "[154:152] General Purpose Partition Size, gp_size_mult_4: 0x%06x\n", (ext_csd[154] << 16) | (ext_csd[153] << 8) | ext_csd[152]); seq_printf(s, "[151:149] General Purpose Partition Size, gp_size_mult_3: 0x%06x\n", (ext_csd[151] << 16) | (ext_csd[150] << 8) | ext_csd[149]); seq_printf(s, "[148:146] General Purpose Partition Size, gp_size_mult_2: 0x%06x\n", (ext_csd[148] << 16) | (ext_csd[147] << 8) | ext_csd[146]); seq_printf(s, "[145:143] General Purpose Partition Size, gp_size_mult_1: 0x%06x\n", (ext_csd[145] << 16) | (ext_csd[144] << 8) | ext_csd[143]); seq_printf(s, "[142:140] Enhanced User Data Area Size, enh_size_mult: 0x%06x\n", (ext_csd[142] << 16) | (ext_csd[141] << 8) | ext_csd[140]); seq_printf(s, "[139:136] Enhanced User Data Start Address, enh_start_addr: 0x%06x\n", (ext_csd[139] << 24) | (ext_csd[138] << 16) | (ext_csd[137] << 8) | ext_csd[136]); /* B45, A441: reserved [135] [133] */ seq_printf(s, "[134] Bad Block Management mode, sec_bad_blk_mgmnt: 0x%02x\n", ext_csd[134]); /* A441: reserved [133:0] */ } /* B45 */ if (ext_csd_rev >= 6) { int j; /* tcase_support ext_csd[132] not readable */ seq_printf(s, "[131] Periodic Wake-up, periodic_wakeup: 0x%02x\n", ext_csd[131]); seq_printf(s, "[130] Program CID CSD in DDR mode support, program_cid_csd_ddr_support: 0x%02x\n", ext_csd[130]); /* B45: reserved [129:128] */ for (j = 127; j >= 64; j--) seq_printf(s, "[127:64] Vendor Specific Fields, vendor_specific_field[%d]: 0x%02x\n", j, ext_csd[j]); seq_printf(s, "[63] Native sector size, native_sector_size: 0x%02x\n", ext_csd[63]); seq_printf(s, "[62] Sector size emulation, use_native_sector: 0x%02x\n", ext_csd[62]); seq_printf(s, "[61] Sector size, data_sector_size: 0x%02x\n", ext_csd[61]); seq_printf(s, "[60] 1st initialization after disabling sector size emulation, ini_timeout_emu: 0x%02x\n", ext_csd[60]); seq_printf(s, "[59] Class 6 commands control, class_6_ctrl: 0x%02x\n", ext_csd[59]); seq_printf(s, "[58] Number of addressed group to be Released, dyncap_needed: 0x%02x\n", ext_csd[58]); seq_printf(s, "[57:56] Exception events control, exception_events_ctrl: 0x%04x\n", (ext_csd[57] << 8) | ext_csd[56]); seq_printf(s, "[55:54] Exception events status, exception_events_status: 0x%04x\n", (ext_csd[55] << 8) | ext_csd[54]); seq_printf(s, "[53:52] Extended Partitions Attribute, ext_partitions_attribute: 0x%04x\n", (ext_csd[53] << 8) | ext_csd[52]); for (j = 51; j >= 37; j--) seq_printf(s, "[51:37]Context configuration, context_conf[%d]: 0x%02x\n", j, ext_csd[j]); seq_printf(s, "[36] Packed command status, packed_command_status: 0x%02x\n", ext_csd[36]); seq_printf(s, "[35] Packed command failure index, packed_failure_index: 0x%02x\n", ext_csd[35]); seq_printf(s, "[34] Power Off Notification, power_off_notification: 0x%02x\n", ext_csd[34]); seq_printf(s, "[33] Control to turn the Cache On Off, cache_ctrl: 0x%02x\n", ext_csd[33]); /* flush_cache ext_csd[32] not readable */ /*Reserved [31:0] */ } #endif out_free: #ifndef CONFIG_MACH_LGE /* LGE_CHANGE * http://www.mail-archive.com/[email protected]/msg10669.html * 2013-06-28, [email protected] */ kfree(buf); #endif kfree(ext_csd); return err; }
static int CPRM_CMD_SecureRW(struct mmc_card *card, unsigned int command, unsigned int dir, unsigned long arg, unsigned char *buff, unsigned int length) { int err; int i = 0; struct mmc_request mrq; struct mmc_command cmd; struct mmc_command stop; struct mmc_data data; struct scatterlist sg; if (command == SD_ACMD25_SECURE_WRITE_MULTI_BLOCK || command == SD_ACMD18_SECURE_READ_MULTI_BLOCK) { return -EINVAL; } memset(&cmd, 0, sizeof(struct mmc_command)); cmd.opcode = MMC_APP_CMD; cmd.arg = card->rca << 16; cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; //kishore mmc_rpm_hold(card->host, &card->dev); mmc_claim_host(card->host); err = mmc_wait_for_cmd(card->host, &cmd, 0); if (err) { printk("CPRM mmc_wait_for_cmd fail = %d ERROR\n", err); mmc_release_host(card->host); mmc_rpm_release(card->host, &card->dev); return (u32)-1; } if (!mmc_host_is_spi(card->host) && !(cmd.resp[0] & R1_APP_CMD)) { printk("CPRM mmc_host_is_spi fail ERROR\n"); mmc_release_host(card->host); mmc_rpm_release(card->host, &card->dev); return (u32)-1; } printk("CPRM_CMD_SecureRW: 1, command : %d\n", command); memset(&cmd, 0, sizeof(struct mmc_command)); cmd.opcode = command; if (command == SD_ACMD43_GET_MKB) cmd.arg = arg; else cmd.arg = 0; cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; memset(&data, 0, sizeof(struct mmc_data)); data.timeout_ns = 100000000; data.timeout_clks = 0; data.blksz = length; data.blocks = 1; data.flags = dir; data.sg = &sg; data.sg_len = 1; stop.opcode = MMC_STOP_TRANSMISSION; stop.arg = 0; stop.flags = MMC_RSP_R1B | MMC_CMD_AC; memset(&mrq, 0, sizeof(struct mmc_request)); mrq.cmd = &cmd; mrq.data = &data; if (data.blocks == 1) mrq.stop = NULL; else mrq.stop = &stop; printk(KERN_DEBUG"CPRM_CMD_SecureRW: 2\n"); sg_init_one(&sg, buff, length); printk(KERN_DEBUG"CPRM_CMD_SecureRW: 3\n"); mmc_wait_for_req(card->host, &mrq); //kishore mmc_release_host(card->host); mmc_rpm_release(card->host, &card->dev); printk(KERN_DEBUG"CPRM_CMD_SecureRW: 4\n"); i = 0; do { printk(KERN_DEBUG"%x", buff[i++]); if (i > 10) break; } while (i < length); printk(KERN_DEBUG"\n"); if (cmd.error) { printk(KERN_DEBUG "%s]cmd.error=%d\n ", __func__, cmd.error); return cmd.error; } if (data.error) { printk(KERN_DEBUG "%s]data.error=%d\n ", __func__, data.error); return data.error; } err = mmc_wait_busy(card); printk(KERN_DEBUG"CPRM_CMD_SecureRW: 5\n"); if (err) return err; return 0; }