Hi Christoph, Could you please share the current state of your work @https://urldefense.proofpoint.com/v2/url?u=http-3A__git.infradead.org_ and provide some direction on Uffe's comments? Thanks, Bhaskara >-----Original Message----- >From: Ulf Hansson <ulf.hansson@xxxxxxxxxx> >Sent: Monday, June 7, 2021 7:38 PM >To: Bhaskara Budiredla <bbudiredla@xxxxxxxxxxx> >Cc: Kees Cook <keescook@xxxxxxxxxxxx>; Colin Cross ><ccross@xxxxxxxxxxx>; Tony Luck <tony.luck@xxxxxxxxx>; Sunil Kovvuri >Goutham <sgoutham@xxxxxxxxxxx>; linux-mmc@xxxxxxxxxxxxxxx; Linux >Kernel Mailing List <linux-kernel@xxxxxxxxxxxxxxx>; linux-block <linux- >block@xxxxxxxxxxxxxxx>; Jens Axboe <axboe@xxxxxxxxx>; Christoph Hellwig ><hch@xxxxxx> >Subject: Re: [EXT] Re: [PATCH v5 1/2] mmc: Support kmsg dumper based on >pstore/blk > >On Mon, 7 Jun 2021 at 14:37, Bhaskara Budiredla <bbudiredla@xxxxxxxxxxx> >wrote: >> >> [...] >> >What patches are you referring to? >> >> I was referring to this patch. >> https://urldefense.proofpoint.com/v2/url?u=http-3A__git.infradead.org_ >> >users_hch_misc.git_shortlog_refs_heads_pstore&d=DwIBaQ&c=nKjWec2b6R0 >mO >> >yPaz7xtfQ&r=9P_lSljSO7KnQNkCGsgu9x_Op4mstSdqWN3Olr4bUv0&m=fl42xU >Yo4DOO >> I8uNNOE4Av-fan25pMik8lX5H4G0694&s=tTmGbewO2pg- >_9D0vAb_GNucJuZAjJCFkuSz >> 6whJGho&e= > >Alright. I didn't know about these, thanks for the pointer. Looks like a big step >in the right direction. > >I guess Christoph simply has been busy with other things. Perhaps you should >ask if you can help and pick up from where he left the series? > >Kind regards >Uffe > >> >> Thanks, >> Bhaskara >> >> >-----Original Message----- >> >From: Ulf Hansson <ulf.hansson@xxxxxxxxxx> >> >Sent: Monday, June 7, 2021 4:47 PM >> >To: Bhaskara Budiredla <bbudiredla@xxxxxxxxxxx> >> >Cc: Kees Cook <keescook@xxxxxxxxxxxx>; Colin Cross >> ><ccross@xxxxxxxxxxx>; Tony Luck <tony.luck@xxxxxxxxx>; Sunil Kovvuri >> >Goutham <sgoutham@xxxxxxxxxxx>; linux-mmc@xxxxxxxxxxxxxxx; Linux >> >Kernel Mailing List <linux-kernel@xxxxxxxxxxxxxxx>; linux-block >> ><linux- block@xxxxxxxxxxxxxxx>; Jens Axboe <axboe@xxxxxxxxx>; >> >Christoph Hellwig <hch@xxxxxx> >> >Subject: Re: [EXT] Re: [PATCH v5 1/2] mmc: Support kmsg dumper based >> >on pstore/blk >> > >> >On Sat, 5 Jun 2021 at 12:31, Bhaskara Budiredla >> ><bbudiredla@xxxxxxxxxxx> >> >wrote: >> >> >> >> Hi Uffe, >> >> >> >> With due respect to pstore/blk subsystem changes we have been >> >> waiting >> >since long time to see Christoph patches taken. >> > >> >What patches are you referring to? >> > >> >> But unfortunately it is still finding at that same stage only. Can >> >> you please take up my patch in the current form (which is based on >> >> current pstore/blk framework) instead of waiting indefinitely. If >> >> pstore/blk comes up >> >with the changes that has been discussed by you previously, I will >> >further submit the corresponding changes for eMMC devices. >> > >> >No, I am sorry, but that's not the way it works. >> > >> >If you really want to move things forward, I would suggest that you >> >try to implement something along the lines of what I have suggested. >> >Another option is to post an RFD/RFC so as solution can be discussed >> >with the relevant people. >> > >> >Kind regards >> >Uffe >> > >> >> >> >> Thanks, >> >> Bhaskara >> >> >> >> >-----Original Message----- >> >> >From: Ulf Hansson <ulf.hansson@xxxxxxxxxx> >> >> >Sent: Wednesday, January 20, 2021 8:36 PM >> >> >To: Bhaskara Budiredla <bbudiredla@xxxxxxxxxxx>; Kees Cook >> >> ><keescook@xxxxxxxxxxxx> >> >> >Cc: Colin Cross <ccross@xxxxxxxxxxx>; Tony Luck >> >> ><tony.luck@xxxxxxxxx>; Sunil Kovvuri Goutham >> >> ><sgoutham@xxxxxxxxxxx>; >> >> >linux- mmc@xxxxxxxxxxxxxxx; Linux Kernel Mailing List <linux- >> >> >kernel@xxxxxxxxxxxxxxx>; linux-block >> >> ><linux-block@xxxxxxxxxxxxxxx>; Jens Axboe <axboe@xxxxxxxxx>; >> >> >Christoph Hellwig <hch@xxxxxx> >> >> >Subject: [EXT] Re: [PATCH v5 1/2] mmc: Support kmsg dumper based >> >> >on pstore/blk >> >> > >> >> >External Email >> >> > >> >> >------------------------------------------------------------------ >> >> >--- >> >> >- >> >> >+ linux-block, Jens, Christoph >> >> > >> >> >On Wed, 20 Jan 2021 at 13:11, Bhaskara Budiredla >> >> ><bbudiredla@xxxxxxxxxxx> wrote: >> >> >> >> >> >> This patch introduces to mmcpstore. The functioning of mmcpstore >> >> >> is similar to mtdpstore. mmcpstore works on FTL based flash >> >> >> devices whereas mtdpstore works on raw flash devices. When the >> >> >> system crashes, mmcpstore stores the kmsg panic and oops logs to >> >> >> a user specified MMC device. >> >> >> >> >> >> It collects the details about the host MMC device through >> >> >> pstore/blk "blkdev" parameter. The user can specify the MMC >> >> >> device in many ways by checking in Documentation/admin- >guide/pstore-blk.rst. >> >> >> >> >> >> The individual mmc host drivers have to define suitable polling >> >> >> and cleanup subroutines to write kmsg panic/oops logs through >mmcpstore. >> >> >> These new host operations are needed as pstore panic write runs >> >> >> with interrupts disabled. >> >> > >> >> >Okay, let me again try to clarify on how I see this to move this forward. >> >> > >> >> >1) >> >> >In my opinion, pstore shouldn't be using callbacks for *regular* >> >> >I/O read/writes. It's upside-down of how the storage stack is designed >to work. >> >> > >> >> >Instead, pstore should be implemented as a regular filesystem, >> >> >that can be mounted on top of a regular block device partition. In >> >> >this way, the lower layer block device drivers (as mmc), don't >> >> >need special support for pstore, the regular I/O block read/write >> >> >path will just >> >work as is. >> >> > >> >> >2) >> >> >When it comes to supporting *panic* writes for pstore, things >> >> >become a bit more complicated. For sure some adaptations are >> >> >needed in each block device driver to support this. >> >> > >> >> >However, the current method means relying on the lower level block >> >> >device driver to figure out the pstore partition. Based on that, >> >> >it should then register itself for pstore support and hook up >> >> >callbacks for the corresponding block device driver instance, at >> >> >least that is what it looks like to me. Again, I think this is >> >> >upside-down from the storage stack perspective. The partition to >> >> >use for pstore, should be based >> >upon its file system mount point. >> >> > >> >> >Furthermore, I think the responsibility for lower layer block >> >> >device drivers should instead be to just "register/announce" >> >> >themselves as capable of supporting "panic writes", if they can. >> >> >Exactly how to best do this, probably needs to be discussed >> >> >further with the block device people, I think. I have looped in >> >> >Jens and Christoph, perhaps they >> >can share their opinion in this. >> >> > >> >> >That said, it looks to me that pstore needs more work before it's >> >> >ready to be adopted for generic support in block device drivers. >> >> > >> >> >Kind regards >> >> >Uffe >> >> > >> >> >> >> >> >> Signed-off-by: Bhaskara Budiredla <bbudiredla@xxxxxxxxxxx> >> >> >> --- >> >> >> drivers/mmc/core/Kconfig | 14 ++- >> >> >> drivers/mmc/core/Makefile | 1 + >> >> >> drivers/mmc/core/block.c | 19 +++ >> >> >> drivers/mmc/core/block.h | 9 ++ >> >> >> drivers/mmc/core/core.c | 44 +++++++ >> >> >> drivers/mmc/core/mmcpstore.c | 227 >> >> >+++++++++++++++++++++++++++++++++++ >> >> >> include/linux/mmc/core.h | 5 + >> >> >> include/linux/mmc/host.h | 12 ++ >> >> >> 8 files changed, 330 insertions(+), 1 deletion(-) create mode >> >> >> 100644 drivers/mmc/core/mmcpstore.c >> >> >> >> >> >> diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig >> >> >> index >> >> >> c12fe13e4b14..4c651da4f2d2 100644 >> >> >> --- a/drivers/mmc/core/Kconfig >> >> >> +++ b/drivers/mmc/core/Kconfig >> >> >> @@ -34,9 +34,22 @@ config PWRSEQ_SIMPLE >> >> >> This driver can also be built as a module. If so, the module >> >> >> will be called pwrseq_simple. >> >> >> >> >> >> +config MMC_PSTORE_BACKEND >> >> >> + bool "Log panic/oops to a MMC buffer" >> >> >> + depends on MMC_BLOCK >> >> >> + help >> >> >> + This option will let you create platform backend to store kmsg >> >> >> + crash dumps to a user specified MMC device. This is primarily >> >> >> + based on pstore/blk. >> >> >> + >> >> >> +config MMC_PSTORE >> >> >> + tristate >> >> >> + select PSTORE_BLK >> >> >> + >> >> >> config MMC_BLOCK >> >> >> tristate "MMC block device driver" >> >> >> depends on BLOCK >> >> >> + select MMC_PSTORE if MMC_PSTORE_BACKEND=y >> >> >> default y >> >> >> help >> >> >> Say Y here to enable the MMC block device driver support. >> >> >> @@ -80,4 +93,3 @@ config MMC_TEST >> >> >> >> >> >> This driver is only of interest to those developing or >> >> >> testing a host driver. Most people should say N here. >> >> >> - >> >> >> diff --git a/drivers/mmc/core/Makefile >> >> >> b/drivers/mmc/core/Makefile index 95ffe008ebdf..7cb9a3af4827 >> >> >> 100644 >> >> >> --- a/drivers/mmc/core/Makefile >> >> >> +++ b/drivers/mmc/core/Makefile >> >> >> @@ -16,5 +16,6 @@ obj-$(CONFIG_PWRSEQ_EMMC) += >> >pwrseq_emmc.o >> >> >> mmc_core-$(CONFIG_DEBUG_FS) += debugfs.o >> >> >> obj-$(CONFIG_MMC_BLOCK) += mmc_block.o >> >> >> mmc_block-objs := block.o queue.o >> >> >> +mmc_block-$(CONFIG_MMC_PSTORE) += mmcpstore.o >> >> >> obj-$(CONFIG_MMC_TEST) += mmc_test.o >> >> >> obj-$(CONFIG_SDIO_UART) += sdio_uart.o >> >> >> diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c >> >> >> index >> >> >> 42e27a298218..6592722cd7b2 100644 >> >> >> --- a/drivers/mmc/core/block.c >> >> >> +++ b/drivers/mmc/core/block.c >> >> >> @@ -2870,6 +2870,21 @@ static void >mmc_blk_remove_debugfs(struct >> >> >> mmc_card *card, >> >> >> >> >> >> #endif /* CONFIG_DEBUG_FS */ >> >> >> >> >> >> +#if IS_ENABLED(CONFIG_MMC_PSTORE) sector_t >> >> >> +mmc_blk_get_part(struct mmc_card *card, int part_num, sector_t >> >> >> +*size) { >> >> >> + struct mmc_blk_data *md = dev_get_drvdata(&card->dev); >> >> >> + struct gendisk *disk = md->disk; >> >> >> + struct disk_part_tbl *part_tbl = disk->part_tbl; >> >> >> + >> >> >> + if (part_num < 0 || part_num >= part_tbl->len) >> >> >> + return 0; >> >> >> + >> >> >> + *size = part_tbl->part[part_num]->nr_sects << SECTOR_SHIFT; >> >> >> + return part_tbl->part[part_num]->start_sect; >> >> >> +} >> >> >> +#endif >> >> >> + >> >> >> static int mmc_blk_probe(struct mmc_card *card) { >> >> >> struct mmc_blk_data *md, *part_md; @@ -2913,6 +2928,9 @@ >> >> >> static int mmc_blk_probe(struct mmc_card *card) >> >> >> goto out; >> >> >> } >> >> >> >> >> >> + if (mmc_card_mmc(card) || mmc_card_sd(card)) >> >> >> + mmcpstore_card_set(card, md->disk->disk_name); >> >> >> + >> >> >> /* Add two debugfs entries */ >> >> >> mmc_blk_add_debugfs(card, md); >> >> >> >> >> >> @@ -3060,6 +3078,7 @@ static void __exit mmc_blk_exit(void) >> >> >> unregister_blkdev(MMC_BLOCK_MAJOR, "mmc"); >> >> >> unregister_chrdev_region(mmc_rpmb_devt, MAX_DEVICES); >> >> >> bus_unregister(&mmc_rpmb_bus_type); >> >> >> + unregister_mmcpstore(); >> >> >> } >> >> >> >> >> >> module_init(mmc_blk_init); >> >> >> diff --git a/drivers/mmc/core/block.h b/drivers/mmc/core/block.h >> >> >> index >> >> >> 31153f656f41..2a4ee5568194 100644 >> >> >> --- a/drivers/mmc/core/block.h >> >> >> +++ b/drivers/mmc/core/block.h >> >> >> @@ -16,5 +16,14 @@ void mmc_blk_mq_recovery(struct mmc_queue >> >> >*mq); >> >> >> struct work_struct; >> >> >> >> >> >> void mmc_blk_mq_complete_work(struct work_struct *work); >> >> >> +#if IS_ENABLED(CONFIG_MMC_PSTORE) sector_t >> >> >> +mmc_blk_get_part(struct mmc_card *card, int part_num, sector_t >> >> >> +*size); void mmcpstore_card_set(struct mmc_card *card, const >> >> >> +char *disk_name); void unregister_mmcpstore(void); #else static >> >> >> +inline void mmcpstore_card_set(struct mmc_card *card, >> >> >> + const char *disk_name) >> >> >> +{} static inline void unregister_mmcpstore(void) {} #endif >> >> >> >> >> >> #endif >> >> >> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c >> >> >> index 19f1ee57fb34..7ad7ff1cab8c 100644 >> >> >> --- a/drivers/mmc/core/core.c >> >> >> +++ b/drivers/mmc/core/core.c >> >> >> @@ -569,6 +569,30 @@ int mmc_cqe_recovery(struct mmc_host >*host) >> >} >> >> >> EXPORT_SYMBOL(mmc_cqe_recovery); >> >> >> >> >> >> +#if IS_ENABLED(CONFIG_MMC_PSTORE) >> >> >> +/** >> >> >> + * mmc_wait_for_pstore_req - initiate a blocking mmc request >> >> >> + * @host: MMC host to start command >> >> >> + * @mrq: MMC request to start >> >> >> + * >> >> >> + * Start a blocking MMC request for a host and wait for the request >> >> >> + * to complete that is based on polling and timeout. >> >> >> + */ >> >> >> +void mmc_wait_for_pstore_req(struct mmc_host *host, struct >> >> >> +mmc_request *mrq) { >> >> >> + unsigned int timeout; >> >> >> + >> >> >> + host->ops->req_cleanup_pending(host); >> >> >> + mmc_start_request(host, mrq); >> >> >> + >> >> >> + if (mrq->data) { >> >> >> + timeout = mrq->data->timeout_ns / NSEC_PER_MSEC; >> >> >> + host->ops->req_completion_poll(host, timeout); >> >> >> + } >> >> >> +} >> >> >> +EXPORT_SYMBOL(mmc_wait_for_pstore_req); >> >> >> +#endif >> >> >> + >> >> >> /** >> >> >> * mmc_is_req_done - Determine if a 'cap_cmd_during_tfr' request >is >> >> >done >> >> >> * @host: MMC host >> >> >> @@ -817,6 +841,26 @@ int __mmc_claim_host(struct mmc_host >*host, >> >> >> struct mmc_ctx *ctx, } EXPORT_SYMBOL(__mmc_claim_host); >> >> >> >> >> >> +#if IS_ENABLED(CONFIG_MMC_PSTORE) >> >> >> +/** >> >> >> + * mmc_claim_host_async - claim host in atomic context >> >> >> + * @host: mmc host to claim >> >> >> + * >> >> >> + * This routine may be called in panic/oops scenarios. >> >> >> + * Return zero with host claim success, else busy status. >> >> >> + */ >> >> >> +int mmc_claim_host_async(struct mmc_host *host) { >> >> >> + if (!host->claimed && pm_runtime_active(mmc_dev(host))) { >> >> >> + host->claimed = 1; >> >> >> + return 0; >> >> >> + } >> >> >> + >> >> >> + return -EBUSY; >> >> >> +} >> >> >> +EXPORT_SYMBOL(mmc_claim_host_async); >> >> >> +#endif >> >> >> + >> >> >> /** >> >> >> * mmc_release_host - release a host >> >> >> * @host: mmc host to release >> >> >> diff --git a/drivers/mmc/core/mmcpstore.c >> >> >> b/drivers/mmc/core/mmcpstore.c new file mode 100644 index >> >> >> 000000000000..f783ea215f18 >> >> >> --- /dev/null >> >> >> +++ b/drivers/mmc/core/mmcpstore.c >> >> >> @@ -0,0 +1,227 @@ >> >> >> +// SPDX-License-Identifier: GPL-2.0 >> >> >> +/* >> >> >> + * MMC pstore support based on pstore/blk >> >> >> + * >> >> >> + * Copyright (c) 2020 Marvell. >> >> >> + * Author: Bhaskara Budiredla <bbudiredla@xxxxxxxxxxx> */ >> >> >> + >> >> >> +#define pr_fmt(fmt) "mmcpstore: " fmt >> >> >> + >> >> >> +#include <linux/kernel.h> >> >> >> +#include <linux/module.h> >> >> >> +#include <linux/pstore_blk.h> >> >> >> +#include <linux/blkdev.h> >> >> >> +#include <linux/mount.h> >> >> >> +#include <linux/slab.h> >> >> >> +#include <linux/mmc/mmc.h> >> >> >> +#include <linux/mmc/host.h> >> >> >> +#include <linux/mmc/card.h> >> >> >> +#include <linux/scatterlist.h> >> >> >> +#include "block.h" >> >> >> +#include "card.h" >> >> >> +#include "core.h" >> >> >> + >> >> >> +static struct mmcpstore_context { >> >> >> + char dev_name[BDEVNAME_SIZE]; >> >> >> + int partno; >> >> >> + sector_t start_sect; >> >> >> + sector_t size; >> >> >> + struct pstore_blk_config conf; >> >> >> + struct pstore_blk_info info; >> >> >> + >> >> >> + struct mmc_card *card; >> >> >> + struct mmc_request *mrq; } oops_cxt; >> >> >> + >> >> >> +static void mmc_prep_req(struct mmc_request *mrq, >> >> >> + unsigned int sect_offset, unsigned int nsects, >> >> >> + struct scatterlist *sg, u32 opcode, unsigned int >> >> >> +flags) { >> >> >> + mrq->cmd->opcode = opcode; >> >> >> + mrq->cmd->arg = sect_offset; >> >> >> + mrq->cmd->flags = MMC_RSP_R1 | MMC_CMD_ADTC; >> >> >> + >> >> >> + if (nsects == 1) { >> >> >> + mrq->stop = NULL; >> >> >> + } else { >> >> >> + mrq->stop->opcode = MMC_STOP_TRANSMISSION; >> >> >> + mrq->stop->arg = 0; >> >> >> + mrq->stop->flags = MMC_RSP_R1B | MMC_CMD_AC; >> >> >> + } >> >> >> + >> >> >> + mrq->data->blksz = SECTOR_SIZE; >> >> >> + mrq->data->blocks = nsects; >> >> >> + mrq->data->flags = flags; >> >> >> + mrq->data->sg = sg; >> >> >> + mrq->data->sg_len = 1; >> >> >> +} >> >> >> + >> >> >> +static int mmcpstore_panic_write_req(const char *buf, >> >> >> + unsigned int nsects, unsigned int sect_offset) { >> >> >> + struct mmcpstore_context *cxt = &oops_cxt; >> >> >> + struct mmc_request *mrq = cxt->mrq; >> >> >> + struct mmc_card *card = cxt->card; >> >> >> + struct mmc_host *host = card->host; >> >> >> + struct scatterlist sg; >> >> >> + u32 opcode; >> >> >> + int ret; >> >> >> + >> >> >> + opcode = (nsects > 1) ? MMC_WRITE_MULTIPLE_BLOCK : >> >> >MMC_WRITE_BLOCK; >> >> >> + mmc_prep_req(mrq, sect_offset, nsects, &sg, opcode, >> >> >MMC_DATA_WRITE); >> >> >> + sg_init_one(&sg, buf, (nsects << SECTOR_SHIFT)); >> >> >> + mmc_set_data_timeout(mrq->data, cxt->card); >> >> >> + >> >> >> + ret = mmc_claim_host_async(host); >> >> >> + if (ret) >> >> >> + return ret; >> >> >> + >> >> >> + mmc_wait_for_pstore_req(host, mrq); >> >> >> + return 0; >> >> >> +} >> >> >> + >> >> >> +static int mmcpstore_panic_write(const char *buf, sector_t off, >> >> >> +sector_t sects) { >> >> >> + struct mmcpstore_context *cxt = &oops_cxt; >> >> >> + int ret; >> >> >> + >> >> >> + ret = mmcpstore_panic_write_req(buf, sects, cxt->start_sect + >off); >> >> >> + if (ret) >> >> >> + return ret; >> >> >> + >> >> >> + return 0; >> >> >> +} >> >> >> + >> >> >> +static struct block_device *mmcpstore_open_backend(const char >> >> >> +*device) { >> >> >> + struct block_device *bdev; >> >> >> + dev_t devt; >> >> >> + >> >> >> + bdev = blkdev_get_by_path(device, FMODE_READ, NULL); >> >> >> + if (IS_ERR(bdev)) { >> >> >> + devt = name_to_dev_t(device); >> >> >> + if (devt == 0) >> >> >> + return ERR_PTR(-ENODEV); >> >> >> + >> >> >> + bdev = blkdev_get_by_dev(devt, FMODE_READ, NULL); >> >> >> + if (IS_ERR(bdev)) >> >> >> + return bdev; >> >> >> + } >> >> >> + >> >> >> + return bdev; >> >> >> +} >> >> >> + >> >> >> +static void mmcpstore_close_backend(struct block_device *bdev) { >> >> >> + if (!bdev) >> >> >> + return; >> >> >> + blkdev_put(bdev, FMODE_READ); } >> >> >> + >> >> >> +void mmcpstore_card_set(struct mmc_card *card, const char >> >> >> +*disk_name) { >> >> >> + struct mmcpstore_context *cxt = &oops_cxt; >> >> >> + struct pstore_blk_config *conf = &cxt->conf; >> >> >> + struct pstore_blk_info *info = &cxt->info; >> >> >> + struct block_device *bdev; >> >> >> + struct mmc_command *stop; >> >> >> + struct mmc_command *cmd; >> >> >> + struct mmc_request *mrq; >> >> >> + struct mmc_data *data; >> >> >> + int ret; >> >> >> + >> >> >> + ret = pstore_blk_get_config(conf); >> >> >> + if (!conf->device[0]) { >> >> >> + pr_debug("psblk backend is empty\n"); >> >> >> + return; >> >> >> + } >> >> >> + >> >> >> + /* Multiple backend devices not allowed */ >> >> >> + if (cxt->dev_name[0]) >> >> >> + return; >> >> >> + >> >> >> + bdev = mmcpstore_open_backend(conf->device); >> >> >> + if (IS_ERR(bdev)) { >> >> >> + pr_err("%s failed to open with %ld\n", >> >> >> + conf->device, PTR_ERR(bdev)); >> >> >> + return; >> >> >> + } >> >> >> + >> >> >> + bdevname(bdev, cxt->dev_name); >> >> >> + cxt->partno = bdev->bd_part->partno; >> >> >> + mmcpstore_close_backend(bdev); >> >> >> + >> >> >> + if (strncmp(cxt->dev_name, disk_name, strlen(disk_name))) >> >> >> + return; >> >> >> + >> >> >> + cxt->start_sect = mmc_blk_get_part(card, cxt->partno, &cxt- >>size); >> >> >> + if (!cxt->start_sect) { >> >> >> + pr_err("Non-existent partition %d selected\n", cxt->partno); >> >> >> + return; >> >> >> + } >> >> >> + >> >> >> + /* Check for host mmc panic write polling function definitions */ >> >> >> + if (!card->host->ops->req_cleanup_pending || >> >> >> + !card->host->ops->req_completion_poll) >> >> >> + return; >> >> >> + >> >> >> + cxt->card = card; >> >> >> + >> >> >> + mrq = kzalloc(sizeof(struct mmc_request), GFP_KERNEL); >> >> >> + if (!mrq) >> >> >> + goto out; >> >> >> + >> >> >> + cmd = kzalloc(sizeof(struct mmc_command), GFP_KERNEL); >> >> >> + if (!cmd) >> >> >> + goto free_mrq; >> >> >> + >> >> >> + stop = kzalloc(sizeof(struct mmc_command), GFP_KERNEL); >> >> >> + if (!stop) >> >> >> + goto free_cmd; >> >> >> + >> >> >> + data = kzalloc(sizeof(struct mmc_data), GFP_KERNEL); >> >> >> + if (!data) >> >> >> + goto free_stop; >> >> >> + >> >> >> + mrq->cmd = cmd; >> >> >> + mrq->data = data; >> >> >> + mrq->stop = stop; >> >> >> + cxt->mrq = mrq; >> >> >> + >> >> >> + info->major = MMC_BLOCK_MAJOR; >> >> >> + info->flags = PSTORE_FLAGS_DMESG; >> >> >> + info->panic_write = mmcpstore_panic_write; >> >> >> + ret = register_pstore_blk(info); >> >> >> + if (ret) { >> >> >> + pr_err("%s registering with psblk failed (%d)\n", >> >> >> + cxt->dev_name, ret); >> >> >> + goto free_data; >> >> >> + } >> >> >> + >> >> >> + pr_info("%s registered as psblk backend\n", cxt->dev_name); >> >> >> + return; >> >> >> + >> >> >> +free_data: >> >> >> + kfree(data); >> >> >> +free_stop: >> >> >> + kfree(stop); >> >> >> +free_cmd: >> >> >> + kfree(cmd); >> >> >> +free_mrq: >> >> >> + kfree(mrq); >> >> >> +out: >> >> >> + return; >> >> >> +} >> >> >> + >> >> >> +void unregister_mmcpstore(void) { >> >> >> + struct mmcpstore_context *cxt = &oops_cxt; >> >> >> + >> >> >> + unregister_pstore_blk(MMC_BLOCK_MAJOR); >> >> >> + kfree(cxt->mrq->data); >> >> >> + kfree(cxt->mrq->stop); >> >> >> + kfree(cxt->mrq->cmd); >> >> >> + kfree(cxt->mrq); >> >> >> + cxt->card = NULL; >> >> >> +} >> >> >> diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h >> >> >> index 29aa50711626..53840a361b5a 100644 >> >> >> --- a/include/linux/mmc/core.h >> >> >> +++ b/include/linux/mmc/core.h >> >> >> @@ -166,6 +166,11 @@ struct mmc_request { >> >> >> >> >> >> struct mmc_card; >> >> >> >> >> >> +#if IS_ENABLED(CONFIG_MMC_PSTORE) void >> >> >> +mmc_wait_for_pstore_req(struct mmc_host *host, struct >> >> >> +mmc_request *mrq); int mmc_claim_host_async(struct mmc_host >> >> >> +*host); #endif >> >> >> + >> >> >> void mmc_wait_for_req(struct mmc_host *host, struct mmc_request >> >> >> *mrq); int mmc_wait_for_cmd(struct mmc_host *host, struct >> >> >mmc_command *cmd, >> >> >> int retries); >> >> >> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h >> >> >> index >> >> >> 01bba36545c5..ba9001498e03 100644 >> >> >> --- a/include/linux/mmc/host.h >> >> >> +++ b/include/linux/mmc/host.h >> >> >> @@ -178,6 +178,18 @@ struct mmc_host_ops { >> >> >> >> >> >> /* Initialize an SD express card, mandatory for >MMC_CAP2_SD_EXP. >> >*/ >> >> >> int (*init_sd_express)(struct mmc_host *host, struct mmc_ios >> >*ios); >> >> >> + >> >> >> +#if IS_ENABLED(CONFIG_MMC_PSTORE) >> >> >> + /* >> >> >> + * The following two APIs are introduced to support mmcpstore >> >> >> + * functionality. Cleanup API to terminate the ongoing and >> >> >> + * pending requests before a panic write post, and polling API >> >> >> + * to ensure that write succeeds before the Kernel dies. >> >> >> + */ >> >> >> + void (*req_cleanup_pending)(struct mmc_host *host); >> >> >> + int (*req_completion_poll)(struct mmc_host *host, >> >> >> + unsigned long timeout); >> >> >> +#endif >> >> >> }; >> >> >> >> >> >> struct mmc_cqe_ops { >> >> >> -- >> >> >> 2.17.1 >> >> >>