On Sun, Feb 2, 2020 at 4:01 PM Jonas Danielsson <jonas@xxxxxxxxxxxxxxxxxxx> wrote: > > From: Jonas Danielsson <jonas@xxxxxxxxxxxxxxxxxxx> > > This functionality was useful for us while debugging issues with > a vendor wifi-driver that misbehaved on the SDIO bus. > > This will allow you to check how SDIO clients handle mmc > command and data errors. > > Signed-off-by: Jonas Danielsson <jonas@xxxxxxxxxxxxxxxxxxx> > --- > drivers/mmc/host/atmel-mci.c | 24 ++++++++++++++++++++++-- > 1 file changed, 22 insertions(+), 2 deletions(-) > > diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c > index a9dad641c..11289c8e5 100644 > --- a/drivers/mmc/host/atmel-mci.c > +++ b/drivers/mmc/host/atmel-mci.c > @@ -328,6 +328,8 @@ struct atmel_mci { > u32 data_status; > u32 stop_cmdr; > > + bool force_cmd_error; > + bool force_data_error; > struct tasklet_struct tasklet; > unsigned long pending_events; > unsigned long completed_events; > @@ -618,6 +620,14 @@ static void atmci_init_debugfs(struct atmel_mci_slot *slot) > if (!node) > goto err; > > + node = debugfs_create_bool("force_cmd_error", 644, root, &host->force_cmd_error); > + if (!node) > + goto err; > + > + node = debugfs_create_bool("force_data_error", 644, root, &host->force_data_error); > + if (!node) > + goto err; > + > node = debugfs_create_u32("state", S_IRUSR, root, (u32 *)&host->state); > if (!node) > goto err; > @@ -1807,7 +1817,12 @@ static void atmci_tasklet_func(unsigned long priv) > * If there is a command error don't start > * data transfer. > */ > - if (mrq->cmd->error) { > + if (mrq->cmd->error || host->force_cmd_error) { > + if (host->force_cmd_error) { > + dev_info(&host->pdev->dev, "FSM: forced cmd error!\n"); > + host->force_cmd_error = false; > + mrq->cmd->error = -EINVAL; > + } > host->stop_transfer(host); > host->data = NULL; > atmci_writel(host, ATMCI_IDR, > @@ -1939,7 +1954,11 @@ static void atmci_tasklet_func(unsigned long priv) > atmci_writel(host, ATMCI_IDR, ATMCI_TXRDY | ATMCI_RXRDY > | ATMCI_DATA_ERROR_FLAGS); > status = host->data_status; > - if (unlikely(status)) { > + if (unlikely(status) || host->force_data_error) { > + if (data && host->force_data_error) { > + dev_info(&host->pdev->dev, "FSM: forced data error!\n"); > + host->force_data_error = false; > + } > host->stop_transfer(host); > host->data = NULL; > if (data) { > @@ -2519,6 +2538,7 @@ static int atmci_probe(struct platform_device *pdev) > return -ENOMEM; > > host->pdev = pdev; > + host->force_data_error = host->force_cmd_error = false; > spin_lock_init(&host->lock); > INIT_LIST_HEAD(&host->queue); > > -- > 2.23.0 > Haha, I just noticed that this is available from the general fault injection framework. So sorry for the noise!