Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 21 May 2015 20:09:37 +0000 (UTC)
From:      Luiz Otavio O Souza <loos@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r283263 - head/sys/dev/sdhci
Message-ID:  <201505212009.t4LK9bfA005490@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: loos
Date: Thu May 21 20:09:36 2015
New Revision: 283263
URL: https://svnweb.freebsd.org/changeset/base/283263

Log:
  Raise the SDHCI timeout to 10 seconds and add a sysctl to allow changing
  this value at runtime.
  
  The SD card specification says that a block write or a block erase can take
  up to 250ms to complete and thus, under some circumstances, the existent 2
  seconds timeout was triggering with normal usage.
  
  This change fixes the sporadic controller timeout that happens on RPi and
  RPi 2.
  
  Discussed with:		ian (some time ago)

Modified:
  head/sys/dev/sdhci/sdhci.c
  head/sys/dev/sdhci/sdhci.h

Modified: head/sys/dev/sdhci/sdhci.c
==============================================================================
--- head/sys/dev/sdhci/sdhci.c	Thu May 21 19:40:31 2015	(r283262)
+++ head/sys/dev/sdhci/sdhci.c	Thu May 21 20:09:36 2015	(r283263)
@@ -615,10 +615,16 @@ sdhci_init_slot(device_t dev, struct sdh
 		    (slot->opt & SDHCI_HAVE_DMA) ? "DMA" : "PIO");
 		sdhci_dumpregs(slot);
 	}
-	
+
+	slot->timeout = 10;
+	SYSCTL_ADD_INT(device_get_sysctl_ctx(slot->bus),
+	    SYSCTL_CHILDREN(device_get_sysctl_tree(slot->bus)), OID_AUTO,
+	    "timeout", CTLFLAG_RW, &slot->timeout, 0,
+	    "Maximum timeout for SDHCI transfers (in secs)");
 	TASK_INIT(&slot->card_task, 0, sdhci_card_task, slot);
 	callout_init(&slot->card_callout, 1);
 	callout_init_mtx(&slot->timeout_callout, &slot->mtx, 0);
+
 	return (0);
 }
 
@@ -872,7 +878,8 @@ sdhci_start_command(struct sdhci_slot *s
 	/* Start command. */
 	WR2(slot, SDHCI_COMMAND_FLAGS, (cmd->opcode << 8) | (flags & 0xff));
 	/* Start timeout callout. */
-	callout_reset(&slot->timeout_callout, 2*hz, sdhci_timeout, slot);
+	callout_reset(&slot->timeout_callout, slot->timeout * hz,
+	    sdhci_timeout, slot);
 }
 
 static void

Modified: head/sys/dev/sdhci/sdhci.h
==============================================================================
--- head/sys/dev/sdhci/sdhci.h	Thu May 21 19:40:31 2015	(r283262)
+++ head/sys/dev/sdhci/sdhci.h	Thu May 21 20:09:36 2015	(r283263)
@@ -271,6 +271,7 @@ struct sdhci_slot {
 #define SDHCI_HAVE_DMA			1
 #define SDHCI_PLATFORM_TRANSFER		2
 	u_char		version;
+	int		timeout;	/* Transfer timeout */
 	uint32_t	max_clk;	/* Max possible freq */
 	uint32_t	timeout_clk;	/* Timeout freq */
 	bus_dma_tag_t 	dmatag;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201505212009.t4LK9bfA005490>