Message ID | 20240807060309.2403023-4-avri.altman@wdc.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | Add SDUC Support | expand |
> SDUC memory addressing spans beyond 2TB and up to 128TB. Therefore, 38 > bits are required to access the entire memory space of all sectors. > Those extra 6 bits are to be carried by CMD22 prior of sending > read/write/erase commands: CMD17, CMD18, CMD24, CMD25, CMD32, and > CMD33. > > CMD22 will carry the higher order 6 bits, and must precedes any of the above > commands even if it targets sector < 2TB. > > No error related to address or length is indicated in CMD22 but rather in the > read/write command itself. > > Signed-off-by: Avri Altman <avri.altman@wdc.com> > --- > drivers/mmc/core/sd_ops.c | 15 +++++++++++++++ > drivers/mmc/core/sd_ops.h | 1 + > include/linux/mmc/sd.h | 3 +++ > 3 files changed, 19 insertions(+) > > diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c index > 7f6963dac873..8b69129d7b61 100644 > --- a/drivers/mmc/core/sd_ops.c > +++ b/drivers/mmc/core/sd_ops.c > @@ -199,6 +199,21 @@ int mmc_send_app_op_cond(struct mmc_host *host, > u32 ocr, u32 *rocr) > return 0; > } > > +int mmc_send_ext_addr(struct mmc_host *host, sector_t addr) { > + struct mmc_command cmd = { > + .opcode = SD_ADDR_EXT, > + .arg = (u32)((addr >> 32) & 0x3F), > + .flags = MMC_RSP_R1 | MMC_CMD_AC, > + }; > + > + if (!mmc_card_is_sduc(host)) > + return 0; > + I think here can be removed, all mmc_send_ext_addr caller are have if-statement to check the card is SDUC > + return mmc_wait_for_cmd(host, &cmd, 0); } > +EXPORT_SYMBOL_GPL(mmc_send_ext_addr); > + > static int __mmc_send_if_cond(struct mmc_host *host, u32 ocr, u8 pcie_bits, > u32 *resp) { diff --git > a/drivers/mmc/core/sd_ops.h b/drivers/mmc/core/sd_ops.h index > 7667fc223b74..462efd43acfa 100644 > --- a/drivers/mmc/core/sd_ops.h > +++ b/drivers/mmc/core/sd_ops.h > @@ -21,6 +21,7 @@ int mmc_send_relative_addr(struct mmc_host *host, > unsigned int *rca); int mmc_app_send_scr(struct mmc_card *card); int > mmc_app_sd_status(struct mmc_card *card, void *ssr); int > mmc_app_cmd(struct mmc_host *host, struct mmc_card *card); > +int mmc_send_ext_addr(struct mmc_host *host, sector_t addr); > > #endif > > diff --git a/include/linux/mmc/sd.h b/include/linux/mmc/sd.h index > 865cc0ca8543..af5fc70e09a2 100644 > --- a/include/linux/mmc/sd.h > +++ b/include/linux/mmc/sd.h > @@ -15,6 +15,9 @@ > #define SD_SEND_IF_COND 8 /* bcr [11:0] See below R7 > */ > #define SD_SWITCH_VOLTAGE 11 /* ac > R1 */ > > +/* Class 2 */ > +#define SD_ADDR_EXT 22 /* ac [5:0] > R1 */ > + > /* class 10 */ > #define SD_SWITCH 6 /* adtc [31:0] See below R1 > */ > > -- > 2.25.1
> > SDUC memory addressing spans beyond 2TB and up to 128TB. Therefore, > > 38 bits are required to access the entire memory space of all sectors. > > Those extra 6 bits are to be carried by CMD22 prior of sending > > read/write/erase commands: CMD17, CMD18, CMD24, CMD25, CMD32, and > > CMD33. > > > > CMD22 will carry the higher order 6 bits, and must precedes any of the > > above commands even if it targets sector < 2TB. > > > > No error related to address or length is indicated in CMD22 but rather > > in the read/write command itself. > > > > Signed-off-by: Avri Altman <avri.altman@wdc.com> > > --- > > drivers/mmc/core/sd_ops.c | 15 +++++++++++++++ > > drivers/mmc/core/sd_ops.h | 1 + > > include/linux/mmc/sd.h | 3 +++ > > 3 files changed, 19 insertions(+) > > > > diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c > > index > > 7f6963dac873..8b69129d7b61 100644 > > --- a/drivers/mmc/core/sd_ops.c > > +++ b/drivers/mmc/core/sd_ops.c > > @@ -199,6 +199,21 @@ int mmc_send_app_op_cond(struct mmc_host *host, > > u32 ocr, u32 *rocr) > > return 0; > > } > > > > +int mmc_send_ext_addr(struct mmc_host *host, sector_t addr) { > > + struct mmc_command cmd = { > > + .opcode = SD_ADDR_EXT, > > + .arg = (u32)((addr >> 32) & 0x3F), > > + .flags = MMC_RSP_R1 | MMC_CMD_AC, > > + }; > > + > > + if (!mmc_card_is_sduc(host)) > > + return 0; > > + > I think here can be removed, all mmc_send_ext_addr caller are have if-statement > to check the card is SDUC Theoretically yes. But since it is exported (kernel test robot warning), we should protect from loadable modules callers. Also, IMO it serves as some sort of documentation and improves readability. Thanks, Avri > > > + return mmc_wait_for_cmd(host, &cmd, 0); } > > +EXPORT_SYMBOL_GPL(mmc_send_ext_addr); > > + > > static int __mmc_send_if_cond(struct mmc_host *host, u32 ocr, u8 pcie_bits, > > u32 *resp) { diff --git > > a/drivers/mmc/core/sd_ops.h b/drivers/mmc/core/sd_ops.h index > > 7667fc223b74..462efd43acfa 100644 > > --- a/drivers/mmc/core/sd_ops.h > > +++ b/drivers/mmc/core/sd_ops.h > > @@ -21,6 +21,7 @@ int mmc_send_relative_addr(struct mmc_host *host, > > unsigned int *rca); int mmc_app_send_scr(struct mmc_card *card); int > > mmc_app_sd_status(struct mmc_card *card, void *ssr); int > > mmc_app_cmd(struct mmc_host *host, struct mmc_card *card); > > +int mmc_send_ext_addr(struct mmc_host *host, sector_t addr); > > > > #endif > > > > diff --git a/include/linux/mmc/sd.h b/include/linux/mmc/sd.h index > > 865cc0ca8543..af5fc70e09a2 100644 > > --- a/include/linux/mmc/sd.h > > +++ b/include/linux/mmc/sd.h > > @@ -15,6 +15,9 @@ > > #define SD_SEND_IF_COND 8 /* bcr [11:0] See below R7 > > */ > > #define SD_SWITCH_VOLTAGE 11 /* ac > > R1 */ > > > > +/* Class 2 */ > > +#define SD_ADDR_EXT 22 /* ac [5:0] > > R1 */ > > + > > /* class 10 */ > > #define SD_SWITCH 6 /* adtc [31:0] See below R1 > > */ > > > > -- > > 2.25.1
diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c index 7f6963dac873..8b69129d7b61 100644 --- a/drivers/mmc/core/sd_ops.c +++ b/drivers/mmc/core/sd_ops.c @@ -199,6 +199,21 @@ int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) return 0; } +int mmc_send_ext_addr(struct mmc_host *host, sector_t addr) +{ + struct mmc_command cmd = { + .opcode = SD_ADDR_EXT, + .arg = (u32)((addr >> 32) & 0x3F), + .flags = MMC_RSP_R1 | MMC_CMD_AC, + }; + + if (!mmc_card_is_sduc(host)) + return 0; + + return mmc_wait_for_cmd(host, &cmd, 0); +} +EXPORT_SYMBOL_GPL(mmc_send_ext_addr); + static int __mmc_send_if_cond(struct mmc_host *host, u32 ocr, u8 pcie_bits, u32 *resp) { diff --git a/drivers/mmc/core/sd_ops.h b/drivers/mmc/core/sd_ops.h index 7667fc223b74..462efd43acfa 100644 --- a/drivers/mmc/core/sd_ops.h +++ b/drivers/mmc/core/sd_ops.h @@ -21,6 +21,7 @@ int mmc_send_relative_addr(struct mmc_host *host, unsigned int *rca); int mmc_app_send_scr(struct mmc_card *card); int mmc_app_sd_status(struct mmc_card *card, void *ssr); int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card); +int mmc_send_ext_addr(struct mmc_host *host, sector_t addr); #endif diff --git a/include/linux/mmc/sd.h b/include/linux/mmc/sd.h index 865cc0ca8543..af5fc70e09a2 100644 --- a/include/linux/mmc/sd.h +++ b/include/linux/mmc/sd.h @@ -15,6 +15,9 @@ #define SD_SEND_IF_COND 8 /* bcr [11:0] See below R7 */ #define SD_SWITCH_VOLTAGE 11 /* ac R1 */ +/* Class 2 */ +#define SD_ADDR_EXT 22 /* ac [5:0] R1 */ + /* class 10 */ #define SD_SWITCH 6 /* adtc [31:0] See below R1 */
SDUC memory addressing spans beyond 2TB and up to 128TB. Therefore, 38 bits are required to access the entire memory space of all sectors. Those extra 6 bits are to be carried by CMD22 prior of sending read/write/erase commands: CMD17, CMD18, CMD24, CMD25, CMD32, and CMD33. CMD22 will carry the higher order 6 bits, and must precedes any of the above commands even if it targets sector < 2TB. No error related to address or length is indicated in CMD22 but rather in the read/write command itself. Signed-off-by: Avri Altman <avri.altman@wdc.com> --- drivers/mmc/core/sd_ops.c | 15 +++++++++++++++ drivers/mmc/core/sd_ops.h | 1 + include/linux/mmc/sd.h | 3 +++ 3 files changed, 19 insertions(+)