Consultation on related issues of Linux kernel4.19

2020-12-02 Thread Nan Li

Hi,Jerome

I recently migrated the 4.19 kernel and found that the RCA 
reconfiguration for emMC is available within the mmc_set_relative_addr() 
function within the mmc_ops.c file, but for SD card or SDIO 
configuration, the mmc_send_relative_addr() function within the sd_ops.c 
file is not set.If I want to reset the RCA value of an SD card or SDIO 
device area to satisfy my need to switch between multiple slave devices, 
this function cannot be implemented.I'm wondering if the 
mmc_send_relative_addr () function has no reconfiguration. What is the 
purpose of this design?If I need this function, is there any interface I 
can use?Or can I modify it?

I am looking forward to your reply. Thank you.




Re: [PATCH] mmc: fix mmc dma operation

2019-10-21 Thread Nan Li
在 2019/10/21 17:17, Jerome Brunet 写道:
> On Mon 21 Oct 2019 at 09:57, Neil Armstrong  wrote:
>
>> Hi,
>>
>> Thanks for the fix.
>>
>> First, you should add "mmc: meson-gx:" in the subject.
>>
>> On 21/10/2019 07:59, Jianxin Pan wrote:
>>> From: Nan Li 
>>>
>>> In MMC dma transfer, the region requested by dma_map_sg() may be released
>>> by dma_unmap_sg() before the transfer is completed.
>>>
>>> Put the unmap operation in front of mmc_request_done() to avoid this.
> Since we have seen this problem (yet), could you briefly how you've
> triggered it ?

The problem we found in the stress test was that the sdio device was 
constantly operated on and off electricity to make it repeatedly 
initialized.

During the test, we found that there was a chance that the information 
read by the controller from the sdio device side was wrong, which made 
the sdio initialization fail.

>> You should add a "Fixes:" tag so it can be backported on stable kernels.
>>
>>> Signed-off-by: Nan Li 
>>> Signed-off-by: Jianxin Pan 
>>> ---
>>>   drivers/mmc/host/meson-gx-mmc.c | 15 ---
>>>   1 file changed, 8 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/drivers/mmc/host/meson-gx-mmc.c 
>>> b/drivers/mmc/host/meson-gx-mmc.c
>>> index e712315..7667e8a 100644
>>> --- a/drivers/mmc/host/meson-gx-mmc.c
>>> +++ b/drivers/mmc/host/meson-gx-mmc.c
>>> @@ -173,6 +173,7 @@ struct meson_host {
>>> int irq;
>>>   
>>> bool vqmmc_enabled;
>>> +   bool needs_pre_post_req;
>>>   };
>>>   
>>>   #define CMD_CFG_LENGTH_MASK GENMASK(8, 0)
>>> @@ -654,6 +655,8 @@ static void meson_mmc_request_done(struct mmc_host *mmc,
>>> struct meson_host *host = mmc_priv(mmc);
>>>   
>>> host->cmd = NULL;
>>> +   if (host->needs_pre_post_req)
>>> +   meson_mmc_post_req(mmc, mrq, 0);
>>> mmc_request_done(host->mmc, mrq);
>>>   }
>>>   
>>> @@ -803,25 +806,23 @@ static void meson_mmc_start_cmd(struct mmc_host *mmc, 
>>> struct mmc_command *cmd)
>>>   static void meson_mmc_request(struct mmc_host *mmc, struct mmc_request 
>>> *mrq)
>>>   {
>>> struct meson_host *host = mmc_priv(mmc);
>>> -   bool needs_pre_post_req = mrq->data &&
>>> +
>>> +   host->needs_pre_post_req = mrq->data &&
>>> !(mrq->data->host_cookie & SD_EMMC_PRE_REQ_DONE);
>>>   
>>> -   if (needs_pre_post_req) {
>>> +   if (host->needs_pre_post_req) {
>>> meson_mmc_get_transfer_mode(mmc, mrq);
>>> if (!meson_mmc_desc_chain_mode(mrq->data))
>>> -   needs_pre_post_req = false;
>>> +   host->needs_pre_post_req = false;
>>> }
>>>   
>>> -   if (needs_pre_post_req)
>>> +   if (host->needs_pre_post_req)
>>> meson_mmc_pre_req(mmc, mrq);
>>>   
>>> /* Stop execution */
>>> writel(0, host->regs + SD_EMMC_START);
>>>   
>>> meson_mmc_start_cmd(mmc, mrq->sbc ?: mrq->cmd);
>>> -
>>> -   if (needs_pre_post_req)
>>> -   meson_mmc_post_req(mmc, mrq, 0);
>>>   }
> The code around all this is getting quite difficult to follow eventhough
> it does not actually do much
>
> The root of the problem seems be that meson_mmc_pre_req() and
> meson_mmc_post_req() are passed to framework but also called manually
> from meson_mmc_request().
>
> Because of this, some code is added to make sure we don't do things twice.
> Maybe I'm missing something but it look weird ? Ulf, could you give us
> your view ?
>
> As far as I can tell:
>   * pre_req : determine if we use CHAIN_MODE or not AND
>   dma_map_sg() if we do
>   * post_req : dma_unmap_sg() if previously allocated
>
> Do we really need to do all this meson_mmc_request() ? Shouldn't we let the
> framework do the calls to pre/post_req for us ?
>
>>>   
>>>   static void meson_mmc_read_resp(struct mmc_host *mmc, struct mmc_command 
>>> *cmd)
>>>
>> Neil




[PATCH 1/1] pty: BREAK for pseudoterminals

2015-02-16 Thread Nan Li
This will greatly enhance the usefulness of QEMU virtual serial ports, because 
the Linux kernel interprets a break on the serial console as a SysRq, but there 
is currently no way to pass this signal over a pseudo-terminal. This patch will 
work for transmitting BREAK from master to slave through pseudo-terminal.

Signed-off-by: Nan Li 
---
 drivers/tty/pty.c | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c
index e72ee62..ac8893a 100644
--- a/drivers/tty/pty.c
+++ b/drivers/tty/pty.c
@@ -31,6 +31,7 @@
 static struct tty_driver *ptm_driver;
 static struct tty_driver *pts_driver;
 static DEFINE_MUTEX(devpts_mutex);
+#define BREAK_STRING '\0'
 #endif
 
 static void pty_close(struct tty_struct *tty, struct file *filp)
@@ -674,6 +675,23 @@ static void pty_unix98_shutdown(struct tty_struct *tty)
devpts_kill_index(tty->driver_data, tty->index);
 }
 
+static int pty_unix98_break_ctl(struct tty_struct *tty, int break_state)
+{
+   int c;
+   struct tty_struct *to = tty->link;
+
+   if (break_state) {
+   /* Stuff the break data into the input queue of the other end */
+   c = tty_insert_flip_char(to->port, BREAK_STRING, TTY_BREAK);
+   /* And shovel */
+   if (c)
+   tty_flip_buffer_push(to->port);
+   else
+   return -ENOMEM;
+   }
+   return 0;
+}
+
 static const struct tty_operations ptm_unix98_ops = {
.lookup = ptm_unix98_lookup,
.install = pty_unix98_install,
@@ -686,6 +704,7 @@ static const struct tty_operations ptm_unix98_ops = {
.chars_in_buffer = pty_chars_in_buffer,
.unthrottle = pty_unthrottle,
.ioctl = pty_unix98_ioctl,
+   .break_ctl = pty_unix98_break_ctl,
.resize = pty_resize,
.shutdown = pty_unix98_shutdown,
.cleanup = pty_cleanup
-- 
1.7.12.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] The count field of counter_show() function should be an unsigned value

2015-01-25 Thread Nan Li
The count field is an unsigned 32bit value, and the
counter_show() function should also treat it as a unsigned
value.

Signed-off-by: Nan Li 
---
 drivers/acpi/sysfs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c
index 13e577c..0876d77 100644
--- a/drivers/acpi/sysfs.c
+++ b/drivers/acpi/sysfs.c
@@ -527,7 +527,7 @@ static ssize_t counter_show(struct kobject *kobj,
acpi_irq_not_handled;
all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_GPE].count =
acpi_gpe_count;
-   size = sprintf(buf, "%8d", all_counters[index].count);
+   size = sprintf(buf, "%8u", all_counters[index].count);
 
/* "gpe_all" or "sci" */
if (index >= num_gpes + ACPI_NUM_FIXED_EVENTS)
-- 
1.7.12.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] The count field of counter_show() function should be an unsigned value

2015-01-15 Thread Nan Li
The count field is an unsigned 32bit value, and the
counter_show() function should also treat it as a unsigned
value.

Signed-off-by: Nan Li 
---
 drivers/acpi/sysfs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c
index 13e577c..0876d77 100644
--- a/drivers/acpi/sysfs.c
+++ b/drivers/acpi/sysfs.c
@@ -527,7 +527,7 @@ static ssize_t counter_show(struct kobject *kobj,
acpi_irq_not_handled;
all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_GPE].count =
acpi_gpe_count;
-   size = sprintf(buf, "%8d", all_counters[index].count);
+   size = sprintf(buf, "%8u", all_counters[index].count);
 
/* "gpe_all" or "sci" */
if (index >= num_gpes + ACPI_NUM_FIXED_EVENTS)
-- 
1.7.12.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/