[crisos] Patches for AFM MMC/SD module

[ Thread Index | Date Index | More lists.tuxfamily.org/crisos Archives ]


Hi

I found a couple of problems with the driver.

1. Written data resides in the cards RAM buffer for 5 seconds. This is
obviously dangerous in an embedded system that is not properly shut
down. Besides, the optimization is of little use since the I/O-scheduler
collects writes to adjacent blocks into one operation. The patch
010-disable_write_delay.patch makes it possible to set the delay to 0,
and also sets the default delay to 0.

2. The write timeout was calculated by a simple loop. This resulted in a
timeout of 167 ms, the correct value is 250 ms. This caused troubles
with some brands of SD cards. Maybe the timeout was correct with the old
3.3 gcc, but now with gcc 4.x it is to short. The patch
020-correct_write_timeout.patch uses linux timers to calculate the
correct timeout of 250 ms.

3. I made a mistake in the Makefile, in the prepare rule the source must
be copied before the default rules are called, otherwise there is no
source code to apply the patches to...

NOTE: I have not renamed my driver as is done in current svn, so the
path in the patches and some names i the Makefile need some editing
before applying.

//Jan
# 
# Copyright (C) 2008 CrisOs.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
# $Id$

include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk

PKG_NAME:=afm-fox-mmc
PKG_RELEASE:=r3

PKG_BUILD_DIR := $(KERNEL_BUILD_DIR)/$(PKG_NAME)

include $(INCLUDE_DIR)/package.mk

define KernelPackage/afm-fox-mmc
  SUBMENU:=Other modules
  DEPENDS:=@TARGET_etrax
  DEFAULT:=y
  TITLE:=Foxboard mmc and sdhc driver from AFM-Design
  FILES:=$(PKG_BUILD_DIR)/afm-mmc.$(LINUX_KMOD_SUFFIX)
  AUTOLOAD:=$(call AutoLoad,20,afm-mmc)
endef

define KernelPackage/afm-fox-mmc/description
 This package the AFM bit-banging kernel driver for mmc and sdhc for FoxBoard.
endef

define Build/Prepare
	$(CP) -r afm/mmc/* $(PKG_BUILD_DIR)/
	$(CP) -r files $(PKG_BUILD_DIR)/
	$(call Build/Prepare/Default)
endef

define Build/Compile
	$(MAKE) -C "$(LINUX_DIR)" \
		CROSS_COMPILE="$(TARGET_CROSS)" \
		ARCH="$(LINUX_KARCH)" V="$(V)" \
		SUBDIRS="$(PKG_BUILD_DIR)" \
		KERNELVERSION="$(KERNEL)" \
		KERNEL_SOURCES="$(LINUX_DIR)" \
		KDIR="$(LINUX_DIR)"
endef

define KernelPackage/afm-fox-mmc/install
	$(INSTALL_DIR) $(1)/etc/init.d
	$(INSTALL_BIN) $(PKG_BUILD_DIR)/files/afm-fox-mmc.init $(1)/etc/init.d/afm-fox-mmc
endef

$(eval $(call KernelPackage,afm-fox-mmc))
--- afm-fox-mmc/mmc_blk.oldc	2009-03-26 09:16:40.000000000 +0100
+++ afm-fox-mmc/mmc_blk.c	2009-03-24 14:49:32.000000000 +0100
@@ -74,7 +74,7 @@
 
 #define MMC_MAJOR				126
 #define MMC_DEVICE				"mmc"
-#define MMC_IDLE_TIME			5
+#define MMC_IDLE_TIME			0
 
 
 // Globals
@@ -92,7 +92,7 @@
 
 // Module functions
 
-void mmc_request(request_queue_t *q)
+void mmc_request(struct request_queue *q)
 {
 	struct request *req;
 	int r;
@@ -100,11 +100,13 @@
 
 	while ((req = elv_next_request(q)) != NULL) {
 		if (! blk_fs_request(req)) {
+                        //blk_dump_rq_flags( req, "mmc: blk_req");
 			end_request(req, 0);
 			continue;
 		}
 		mmc_idle_timer = MMC_IDLE_TIME;
 		spin_unlock_irq(q->queue_lock);
+                //blk_dump_rq_flags( req, "mmc: blk_fs_req");
 		if (mmc_disk_active && MMC_CARD_PRESENT) {
 			if (rq_data_dir(req) == READ) {
 	            if ((r = mmc_read_sectors(req->buffer, req->sector, req->current_nr_sectors)) != req->current_nr_sectors) {
@@ -124,6 +126,11 @@
 		spin_lock_irq(q->queue_lock);
 		end_request(req, success);
 	}
+	if (MMC_IDLE_TIME==0) {
+		spin_unlock_irq(q->queue_lock);
+		mmc_idle();
+		spin_lock_irq(q->queue_lock);
+	}
 }
 
 int mmc_open(struct inode *inode, struct file *filp)
--- afm-fox-mmc/mmc_ctrl.oldc	2009-03-26 09:16:53.000000000 +0100
+++ afm-fox-mmc/mmc_ctrl.c	2009-03-24 13:13:35.000000000 +0100
@@ -27,6 +27,7 @@
 // Includes
 
 #include <linux/kernel.h>
+#include <linux/hrtimer.h>
 #include <asm/io.h>
 
 #include "mmc_def.h"
@@ -69,17 +70,22 @@
 
 int mmc_check_busy(void)
 {
-	int i;
+	int t=0;
+	// Write timeout is maximum 250ms
+	// Maybe we should have timeout as an argument for other cases?
+	ktime_t timeout = ktime_add_us(ktime_get(), 250000);
 
 	mmc_spi_clk(1);
-	for (i = 0; i < MMC_MAX_BUSY_LOOPS; i++) {
+	while(!t) {
+		if (ktime_to_ns(ktime_sub(ktime_get(), timeout)) > 0) t=1;
+
 		if (mmc_spi_read() == 0xFF) {
 			mmc_spi_clk(1);
 			return 0;
 		}
 	}
 
-	printk(KERN_WARNING "mmc: check_busy loops exceeded\n");
+	printk(KERN_WARNING "mmc: check_busy timeout\n");
 	mmc_spi_clk(1);
 	return -1;
 }


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/