⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 full.patch

📁 2.6.12 内核版本的patch
💻 PATCH
📖 第 1 页 / 共 5 页
字号:
 } +int sd_set_bus_width(struct mmc_host *host, u16 rca, u32 bus_width)+{+	struct mmc_command cmd;+	int err;++	cmd.opcode = MMC_ACMD_SD_SET_BUS_WIDTH;+	cmd.flags  = MMC_RSP_R1;++	switch(bus_width) {+		case 1:	 cmd.arg = 00; break;+		case 4:	 cmd.arg = 10; break;+		default: return -EINVAL;+	}++	err = mmc_wait_for_acmd(host, rca, &cmd, 3);++	if(err == MMC_ERR_TIMEOUT) {+		printk(KERN_ERR "MMC: sd_set_bus_width timed out.\n");+	} else if(err == MMC_ERR_BADCRC) {+		printk(KERN_ERR "MMC: sd_set_bus_width yielded crc error.\n");+	} else {+		DBG("MMC: sd_app_op_cond done.\n");+	}++	return err;+}++EXPORT_SYMBOL(sd_set_bus_width);++static int sd_app_op_cond(struct mmc_host *host, u16 rca, u32 parameter, u32 *response)+{+	struct mmc_command cmd;+	int err;+	int retries = 10;++	cmd.opcode = MMC_ACMD_SD_APP_OP_COND;+	cmd.arg = parameter;+	cmd.flags = MMC_RSP_SHORT;++	DBG("MMC: sd_app_op_cond to %08x\n",parameter);++	while(retries--) {+		err = mmc_wait_for_acmd(host, 0, &cmd, 0);+		if(0 == (cmd.resp[0] & MMC_CARD_BUSY)) {+			err=MMC_ERR_BUSY;+			printk(KERN_ERR "MMC: sd_app_op_cond: at least one card is busy - trying again.\n");+			mmc_delay(10);+			continue;+		}++		if(err == MMC_ERR_NONE) {+			if(response)*response = cmd.resp[0];+			break;+		}+	}++	if(err == MMC_ERR_TIMEOUT) {+		printk(KERN_WARNING "MMC: sd_app_op_cond timed out. Probably no SD-Card here.\n");+	} else if(err == MMC_ERR_BUSY) {+		printk(KERN_ERR "MMC: sd_app_op_cond locked busy. Probably have broken SD-Card.\n");+	} else {+		DBG("MMC: sd_app_op_cond done. Results are: 0x%08x.\n",cmd.resp[0]);+	}++	return err;+}++ /*  * Apply power to the MMC stack.  */@@ -532,7 +716,7 @@ static int mmc_send_op_cond(struct mmc_h  * Create a mmc_card entry for each discovered card, assigning  * it an RCA, and save the raw CID for decoding later.  */-static void mmc_discover_cards(struct mmc_host *host)+static void mmc_discover_cards(struct mmc_host *host, u8 sd) { 	struct mmc_card *card; 	unsigned int first_rca = 1, err;@@ -542,7 +726,7 @@ static void mmc_discover_cards(struct mm  		cmd.opcode = MMC_ALL_SEND_CID; 		cmd.arg = 0;-		cmd.flags = MMC_RSP_R2;+		cmd.flags = MMC_RSP_LONG; //HACK! CRC currently not implemented  		err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); 		if (err == MMC_ERR_TIMEOUT) {@@ -550,14 +734,13 @@ static void mmc_discover_cards(struct mm 			break; 		} 		if (err != MMC_ERR_NONE) {-			printk(KERN_ERR "%s: error requesting CID: %d\n",-				host->host_name, err);+			printk(KERN_ERR "%s: error requesting CID: %d\n", host->host_name, err); 			break; 		}  		card = mmc_find_card(host, cmd.resp); 		if (!card) {-			card = mmc_alloc_card(host, cmd.resp, &first_rca);+			card = mmc_alloc_card(host, cmd.resp, sd, &first_rca); 			if (IS_ERR(card)) { 				err = PTR_ERR(card); 				break;@@ -574,6 +757,9 @@ static void mmc_discover_cards(struct mm 		err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); 		if (err != MMC_ERR_NONE) 			mmc_card_set_dead(card);++		//SD-Cards choose their adresses themselfes (yuck!)+		if(card->sd) card->rca = (cmd.resp[0] >> 16); 	} } @@ -590,7 +776,7 @@ static void mmc_read_csds(struct mmc_hos  		cmd.opcode = MMC_SEND_CSD; 		cmd.arg = card->rca << 16;-		cmd.flags = MMC_RSP_R2;+		cmd.flags = MMC_RSP_LONG; 	//HACK: No CRC check as s3c-Core is broken  		err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); 		if (err != MMC_ERR_NONE) {@@ -651,63 +837,22 @@ static void mmc_check_cards(struct mmc_h 	} } + static void mmc_setup(struct mmc_host *host) {-	if (host->ios.power_mode != MMC_POWER_ON) {-		int err;-		u32 ocr;--		mmc_power_up(host);-		mmc_idle_cards(host);--		err = mmc_send_op_cond(host, 0, &ocr);-		if (err != MMC_ERR_NONE)-			return;--		host->ocr = mmc_select_voltage(host, ocr);--		/*-		 * Since we're changing the OCR value, we seem to-		 * need to tell some cards to go back to the idle-		 * state.  We wait 1ms to give cards time to-		 * respond.-		 */-		if (host->ocr)-			mmc_idle_cards(host);-	} else {-		host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;-		host->ios.clock = host->f_min;-		host->ops->set_ios(host, &host->ios);--		/*-		 * We should remember the OCR mask from the existing-		 * cards, and detect the new cards OCR mask, combine-		 * the two and re-select the VDD.  However, if we do-		 * change VDD, we should do an idle, and then do a-		 * full re-initialisation.  We would need to notify-		 * drivers so that they can re-setup the cards as-		 * well, while keeping their queues at bay.-		 *-		 * For the moment, we take the easy way out - if the-		 * new cards don't like our currently selected VDD,-		 * they drop off the bus.-		 */-	}--	if (host->ocr == 0)-		return;--	/*-	 * Send the selected OCR multiple times... until the cards-	 * all get the idea that they should be ready for CMD2.-	 * (My SanDisk card seems to need this.)-	 */-	mmc_send_op_cond(host, host->ocr, NULL);+	mmc_power_up(host);+	mmc_idle_cards(host); -	mmc_discover_cards(host);+	// Wake and discover SD-Cards+	sd_app_op_cond(host, 0, host->ocr_avail, NULL);+	mmc_discover_cards(host, 1);++	// Wake and discover MMC-Cards+	mmc_send_op_cond(host, host->ocr_avail, NULL);+	mmc_discover_cards(host, 0);  	/*-	 * Ok, now switch to push-pull mode.+	 * switch to push-pull mode. 	 */ 	host->ios.bus_mode = MMC_BUSMODE_PUSHPULL; 	host->ops->set_ios(host, &host->ios);diff --git a/drivers/mmc/mmc.h b/drivers/mmc/mmc.h--- a/drivers/mmc/mmc.h+++ b/drivers/mmc/mmc.h@@ -13,4 +13,5 @@ void mmc_init_card(struct mmc_card *card, struct mmc_host *host); int mmc_register_card(struct mmc_card *card); void mmc_remove_card(struct mmc_card *card);+int sd_set_bus_width(struct mmc_host *host, u16 rca, u32 bus_width); #endifdiff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c--- a/drivers/mmc/mmc_block.c+++ b/drivers/mmc/mmc_block.c@@ -3,6 +3,9 @@  *  * Copyright 2002 Hewlett-Packard Company  *+ *  SD-Card support:+ *    Copyright (C) 2004 Thomas Kleffel, All Rights Reserved+ *  * Use consistent with the GNU GPL is permitted,  * provided that this copyright notice is  * preserved in its entirety in all copies and derived works.@@ -30,11 +33,13 @@ #include <linux/devfs_fs_kernel.h>  #include <linux/mmc/card.h>+#include <linux/mmc/host.h> #include <linux/mmc/protocol.h>  #include <asm/system.h> #include <asm/uaccess.h> +#include "mmc.h" #include "mmc_queue.h"  /*@@ -165,11 +170,17 @@ static int mmc_blk_issue_rq(struct mmc_q { 	struct mmc_blk_data *md = mq->data; 	struct mmc_card *card = md->queue.card;+	struct mmc_host *host = md->queue.card->host; 	int ret;  	if (mmc_card_claim_host(card)) 		goto cmd_err; +	if((card->sd) && (host->flags & MMC_HOST_WIDEMODE) && (card->bus_width != 4)) {+		if(sd_set_bus_width(host, card->rca, 4)) goto cmd_err;+		card->bus_width=4;+	}+ 	do { 		struct mmc_blk_request brq; 		struct mmc_command cmd;@@ -180,6 +191,7 @@ static int mmc_blk_issue_rq(struct mmc_q  		brq.cmd.arg = req->sector << 9; 		brq.cmd.flags = MMC_RSP_R1;+		brq.data.req = req; 		brq.data.timeout_ns = card->csd.tacc_ns * 10; 		brq.data.timeout_clks = card->csd.tacc_clks * 10; 		brq.data.blksz_bits = md->block_bits;@@ -188,6 +200,9 @@ static int mmc_blk_issue_rq(struct mmc_q 		brq.stop.arg = 0; 		brq.stop.flags = MMC_RSP_R1B; +		if(card->bus_width==4)+			brq.data.flags |= MMC_DATA_WIDE;+ 		if (rq_data_dir(req) == READ) { 			brq.cmd.opcode = brq.data.blocks > 1 ? MMC_READ_MULTIPLE_BLOCK : MMC_READ_SINGLE_BLOCK; 			brq.data.flags |= MMC_DATA_READ;@@ -252,7 +267,7 @@ static int mmc_blk_issue_rq(struct mmc_q 			/* 			 * The whole request completed successfully. 			 */-			add_disk_randomness(req->rq_disk);+			//add_disk_randomness(req->rq_disk); 			blkdev_dequeue_request(req); 			end_that_request_last(req); 		}@@ -347,7 +362,7 @@ static struct mmc_blk_data *mmc_blk_allo 		sprintf(md->disk->disk_name, "mmcblk%d", devidx); 		sprintf(md->disk->devfs_name, "mmc/blk%d", devidx); -		md->block_bits = card->csd.read_blkbits;+		md->block_bits = card->csd.read_bl_len;  		blk_queue_hardsect_size(md->queue.queue, 1 << md->block_bits); 		set_capacity(md->disk, card->csd.capacity);@@ -364,7 +379,7 @@ mmc_blk_set_blksize(struct mmc_blk_data   	mmc_card_claim_host(card); 	cmd.opcode = MMC_SET_BLOCKLEN;-	cmd.arg = 1 << card->csd.read_blkbits;+	cmd.arg = 1 << card->csd.read_bl_len; 	cmd.flags = MMC_RSP_R1; 	err = mmc_wait_for_cmd(card->host, &cmd, 5); 	mmc_card_release_host(card);@@ -386,12 +401,12 @@ static int mmc_blk_probe(struct mmc_card 	/* 	 * Check that the card supports the command class(es) we need. 	 */-	if (!(card->csd.cmdclass & CCC_BLOCK_READ))+	if (!(card->csd.ccc & CCC_BLOCK_READ)) 		return -ENODEV; -	if (card->csd.read_blkbits < 9) {+	if (card->csd.read_bl_len < 9) { 		printk(KERN_WARNING "%s: read blocksize too small (%u)\n",-			mmc_card_id(card), 1 << card->csd.read_blkbits);+			mmc_card_id(card), 1 << card->csd.read_bl_len); 		return -ENODEV; 	} @@ -405,7 +420,7 @@ static int mmc_blk_probe(struct mmc_card  	printk(KERN_INFO "%s: %s %s %dKiB\n", 		md->disk->disk_name, mmc_card_id(card), mmc_card_name(card),-		(card->csd.capacity << card->csd.read_blkbits) / 1024);+		(card->csd.capacity << card->csd.read_bl_len) / 1024);  	mmc_set_drvdata(card, md); 	add_disk(md->disk);diff --git a/drivers/mmc/mmc_sysfs.c b/drivers/mmc/mmc_sysfs.c--- a/drivers/mmc/mmc_sysfs.c+++ b/drivers/mmc/mmc_sysfs.c@@ -3,6 +3,9 @@  *  *  Copyright (C) 2003 Russell King, All Rights Reserved.  *+ *  SD-Card support:+ *    Copyright (C) 2004 Thomas Kleffel, All Rights Reserved+ *  * This program is free software; you can redistribute it and/or modify  * it under the terms of the GNU General Public License version 2 as  * published by the Free Software Foundation.@@ -39,10 +42,13 @@ MMC_ATTR(manfid, "0x%06x\n", card->cid.m MMC_ATTR(name, "%s\n", card->cid.prod_name); MMC_ATTR(oemid, "0x%04x\n", card->cid.oemid); MMC_ATTR(serial, "0x%08x\n", card->cid.serial);+MMC_ATTR(bus_width, "%u\n", card->bus_width);+MMC_ATTR(type, "%s\n", (card->sd?"SD":"MMC"));  #define MMC_ATTR_RO(name) __ATTR(name, S_IRUGO, mmc_##name##_show, NULL)  static struct device_attribute mmc_dev_attrs[] = {+	MMC_ATTR_RO(bus_width), 	MMC_ATTR_RO(cid), 	MMC_ATTR_RO(csd), 	MMC_ATTR_RO(date),@@ -52,6 +58,7 @@ static struct device_attribute mmc_dev_a 	MMC_ATTR_RO(name), 	MMC_ATTR_RO(oemid), 	MMC_ATTR_RO(serial),+	MMC_ATTR_RO(type), 	__ATTR_NULL }; @@ -97,7 +104,7 @@ mmc_bus_hotplug(struct device *dev, char 	})  	for (i = 0; i < 12; i++)-		ccc[i] = card->csd.cmdclass & (1 << i) ? '1' : '0';+		ccc[i] = card->csd.ccc & (1 << i) ? '1' : '0'; 	ccc[12] = '\0';  	i = 0;diff --git a/drivers/mmc/s3c2410mci.c b/drivers/mmc/s3c2410mci.cnew file mode 100644--- /dev/null+++ b/drivers/mmc/s3c2410mci.c@@ -0,0 +1,760 @@+/*+ *  linux/drivers/mmc/s3c2410mci.h - Samsung S3C2410 SDI Interface driver+ *+ *  Copyright (C) 2004 Thomas Kleffel, All Rights Reserved.+ *+ * This program is free software; you can redistribute it and/or modify+ * it under the terms of the GNU General Public License version 2 as+ * published by the Free Software Foundation.+ */+#include <linux/config.h>+#include <linux/module.h>+#include <linux/moduleparam.h>+#include <linux/init.h>+#include <linux/ioport.h>+#include <linux/device.h>+#include <linux/interrupt.h>+#include <linux/blkdev.h>+#include <linux/delay.h>+#include <linux/err.h>+#include <linux/dma-mapping.h>+#include <linux/mmc/host.h>+#include <linux/mmc/protocol.h>++#include <asm/dma.h>+#include <asm/dma-mapping.h>+#include <asm/arch/dma.h>++#include <asm/io.h>+#include <asm/irq.h>+#include <asm/hardware/amba.h>+#include <asm/hardware/clock.h>+#include <asm/mach/mmc.h>++#include <asm/arch/regs-sdi.h>+#include <asm/arch/regs-gpio.h>++//#define S3C2410SDI_DMA_BACKBUF++#ifdef CONFIG_MMC_DEBUG+#define DBG(x...)       printk(KERN_DEBUG x)+#else+#define DBG(x...)       do { } while (0)+#endif++#include "s3c2410mci.h"++#define DRIVER_NAME "mmci-s3c2410"+#define PFX DRIVER_NAME ": "++#define RESSIZE(ressource) (((ressource)->end - (ressource)->start)+1)++// #define KERN_DEBUG KERN_INFO++typedef enum {+	DMAP_READ,+	DMAP_WRITE,+} eDMAPurpose_t;++static struct s3c2410_dma_client s3c2410sdi_dma_client = {+	.name		= "s3c2410-sdi",+};++++/*+ * ISR for SDI Interface IRQ+ * Communication between driver and ISR works as follows:+ *   host->mrq 			points to current request+ *   host->complete_what	tells the ISR when the request is considered done+ *     COMPLETION_CMDSENT	  when the command was sent+ *     COMPLETION_RSPFIN          when a response was received+ *     COMPLETION_XFERFINISH	  when the data transfer is finished+ *     COMPLETION_XFERFINISH_RSPFIN both of the above.+ *   host->complete_request	is the completion-object the driver waits for+ *+ * 1) Driver sets up host->mrq and host->complete_what+ * 2) Driver prepares the transfer+ * 3) Driver enables interrupts+ * 4) Driver starts transfer+ * 5) Driver waits for host->complete_rquest

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -