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

📄 patch-2.4.19-mmc

📁 linux2.4.19内核关于MMC/SD卡驱动的补丁
💻 19-MMC
📖 第 1 页 / 共 5 页
字号:
+/******************************************************************/++static int __init mmc_media_init( void )+{+	int i, result;+	DEBUG(0,"\n");++	mmc_devfs_handle = devfs_mk_dir(NULL, DEVICE_NAME, NULL);+	if (!mmc_devfs_handle) return -EBUSY;++	result = devfs_register_blkdev(mmc_major, DEVICE_NAME, &mmc_bdops);+	if (result < 0) {+		printk(KERN_WARNING "Unable to get major %d for MMC media\n", mmc_major);+		return result;+	}++	if ( !mmc_major ) mmc_major = result;++	/* Set up global block arrays */+	read_ahead[mmc_major]    = rahead;+	for(i=0 ; i < MMC_NDISK; i++)+		mmc_blk[i] = 512;+	hardsect_size[mmc_major] = mmc_blk;+	for(i=0; i < MMC_NDISK; i++)+		mmc_max[i] = maxsectors;+	max_sectors[mmc_major]   = mmc_max;++	/* Start with zero-sized partitions : we'll fix this later */+	memset(mmc_sizes, 0, sizeof(int) * MMC_NDISK);+	blk_size[mmc_major] = mmc_sizes;++	/* Fix up the gendisk structure */+	mmc_gendisk.part    = mmc_partitions;+	mmc_gendisk.sizes   = mmc_sizes;+	mmc_gendisk.nr_real = 0;+	mmc_gendisk.de_arr  = &mmc_devfs_handle;+	mmc_gendisk.flags   = &mmc_gendisk_flags;+	mmc_gendisk.fops    = &mmc_bdops;++	/* Add ourselves to the global list */+	mmc_gendisk.major = mmc_major;+	add_gendisk(&mmc_gendisk);+	+	blk_init_queue(BLK_DEFAULT_QUEUE(mmc_major), DEVICE_REQUEST);+	return mmc_register_media_driver(&mmc_driver);+}++static void __exit mmc_media_cleanup( void )+{+	int i;+	DEBUG(0,"\n");++	flush_scheduled_tasks();+	unregister_blkdev(mmc_major, DEVICE_NAME);++	for ( i = 0 ; i < MMC_NDISK; i++ )+		fsync_dev(MKDEV(mmc_major,i));++	mmc_unregister_media_driver(&mmc_driver);++	blk_cleanup_queue(BLK_DEFAULT_QUEUE(mmc_major));++	blk_size[mmc_major]      = NULL;+	hardsect_size[mmc_major] = NULL;+	max_sectors[mmc_major]   = NULL;++	del_gendisk(&mmc_gendisk);++	devfs_unregister(mmc_devfs_handle);+}++struct mmc_media_module media_module = {+	init:    mmc_media_init,+	cleanup: mmc_media_cleanup+};diff -ruwN -X dontdiff linux-2.4.19/drivers/mmc/mmc_media.h linux-2.4.19-mmc1/drivers/mmc/mmc_media.h--- linux-2.4.19/drivers/mmc/mmc_media.h	Wed Dec 31 19:00:00 1969+++ linux-2.4.19-mmc1/drivers/mmc/mmc_media.h	Fri Aug  9 16:07:33 2002@@ -0,0 +1,96 @@+/*+ * Header for MultiMediaCard (MMC)+ *+ * Copyright (c) 2002 Hewlett-Packard Company+ *   + * Permission is hereby granted, free of charge, to any person obtaining a+ * copy of this software and associated documentation files (the+ * "Software"), to deal in the Software without restriction, including+ * without limitation the rights to use, copy, modify, merge, publish,+ * distribute, sublicense, and/or sell copies of the Software, and to+ * permit persons to whom the Software is furnished to do so, subject to+ * the following conditions:+ *  + * The above copyright notice and this permission notice shall be included+ * in all copies or substantial portions of the Software.+ *  + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.+ *+ * Many thanks to Alessandro Rubini and Jonathan Corbet!+ *+ * Based strongly on code by:+ *+ * Author: Yong-iL Joh <tolkien@mizi.com>+ * Date  : $Date: 2002/06/18 12:38:40 $ + *+ * Author:  Andrew Christian+ *          15 May 2002+ */++#ifndef MMC_MMC_MEDIA_H+#define MMC_MMC_MEDIA_H++#include <linux/interrupt.h>+#include <linux/list.h>++#include <linux/mmc/mmc_protocol.h>++/* Set an upper bound for how many cards we'll support */+/* This is used only for static array initialization */+#define MMC_MAX_SLOTS   2++#define MMC_SLOT_FLAG_INSERT  (1<<0)+#define MMC_SLOT_FLAG_EJECT   (1<<1)++struct mmc_media_driver;++struct mmc_slot {+	int             id;     /* Card index */+	/* Card specific information */+	struct mmc_cid  cid;+	struct mmc_csd  csd;++	enum card_state state;  /* empty, ident, ready, whatever */+	int             flags;  /* Ejected, inserted */++	/* Assigned media driver */+	struct mmc_media_driver *media_driver;+};++struct mmc_io_request {+	int            id;         /* Card index     */+	int            cmd;        /* READ or WRITE  */+	unsigned long  sector;     /* Start address  */+	unsigned long  nr_sectors; /* Length of read */+	unsigned long  block_len;  /* Size of sector (sanity check) */+	char          *buffer;     /* Data buffer    */+};++/* Media driver (e.g., Flash card, I/O card...) */+struct mmc_media_driver {+	struct list_head   node;+	char              *name;+	void (*load)(struct mmc_slot *);+	void (*unload)(struct mmc_slot *);+	int  (*probe)(struct mmc_slot *);+	void (*io_request_done)(struct mmc_io_request *, int result);+};++struct mmc_media_module {+	int (*init)(void);+	void (*cleanup)(void);+};++/* Calls made by the media driver */+extern int  mmc_register_media_driver( struct mmc_media_driver * );+extern void mmc_unregister_media_driver( struct mmc_media_driver * );+extern void mmc_handle_io_request( struct mmc_io_request * );++#endif  /* MMC_MMC_MEDIA_H */+diff -ruwN -X dontdiff linux-2.4.19/drivers/mmc/mmc_protocol.c linux-2.4.19-mmc1/drivers/mmc/mmc_protocol.c--- linux-2.4.19/drivers/mmc/mmc_protocol.c	Wed Dec 31 19:00:00 1969+++ linux-2.4.19-mmc1/drivers/mmc/mmc_protocol.c	Fri Aug  9 16:07:45 2002@@ -0,0 +1,440 @@+/*+ * MMC State machine functions+ *+ * Copyright (c) 2002 Hewlett-Packard Company+ *   + * Permission is hereby granted, free of charge, to any person obtaining a+ * copy of this software and associated documentation files (the+ * "Software"), to deal in the Software without restriction, including+ * without limitation the rights to use, copy, modify, merge, publish,+ * distribute, sublicense, and/or sell copies of the Software, and to+ * permit persons to whom the Software is furnished to do so, subject to+ * the following conditions:+ *  + * The above copyright notice and this permission notice shall be included+ * in all copies or substantial portions of the Software.+ *  + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.+ *+ * Many thanks to Alessandro Rubini and Jonathan Corbet!+ *+ * This part of the code is separated from mmc_core.o so we can+ * plug in different state machines (e.g., SPI, SD)+ *+ * This code assumes that you have exactly one card slot, no more.+ *+ * Author:  Andrew Christian+ *          6 May 2002+ */++#include <linux/config.h>+#include <linux/module.h>++#include <linux/version.h>+#include <linux/proc_fs.h>++#include "mmc_core.h"++static void * mmc_cim_default_state( struct mmc_dev *dev, int first );++/******************************************************************+ *+ * Useful utility functions+ *+ ******************************************************************/++static int mmc_has_valid_request( struct mmc_dev *dev )+{+	struct mmc_io_request *request = dev->io_request;+	struct mmc_slot *slot;++	DEBUG(2," (%p)\n", request);++	if ( !request ) return 0;++	slot = dev->slot + request->id;++	if ( !slot->media_driver ) {+		DEBUG(0,": card doesn't have media driver\n");+		return 0;+	}++	return 1;+}++static void mmc_configure_card( struct mmc_dev *dev, int slot )+{+	u32 rate;+	DEBUG(2,": slot=%d\n", slot);++	/* Fix the clock rate */+	rate = mmc_tran_speed(dev->slot[slot].csd.tran_speed);+	if ( rate < MMC_CLOCK_SLOW )+		rate = MMC_CLOCK_SLOW;+	if ( rate > MMC_CLOCK_FAST )+		rate = MMC_CLOCK_FAST;++	dev->sdrive->set_clock(rate);+	+	/* Match the drive media */+	mmc_match_media_driver(&dev->slot[slot]);+	run_sbin_mmc_hotplug(dev, slot, 1);+}++/* The blocks requested by the kernel may or may not+   match what we can do.  Unfortunately, filesystems play+   fast and loose with block sizes, so we're stuck with this */++static void mmc_fix_request_block_size( struct mmc_dev *dev )+{+	struct mmc_io_request *t = dev->io_request;+	struct mmc_slot *slot = dev->slot + t->id;+	u16 block_len;++	DEBUG(1, ": io_request id=%d cmd=%d sector=%ld nr_sectors=%ld block_len=%ld buf=%p\n",+	      t->id, t->cmd, t->sector, t->nr_sectors, t->block_len, t->buffer);++	switch( t->cmd ) {+	case READ:+		block_len = 1 << slot->csd.read_bl_len;+		break;+	case WRITE:+		block_len = 1 << slot->csd.write_bl_len;+		break;+	default:+		DEBUG(0,": unrecognized command %d\n", t->cmd);+		return;+	}++	if ( block_len < t->block_len ) {+		int scale = t->block_len / block_len;+		DEBUG(1,": scaling by %d from block_len=%d to %ld\n", +		      scale, block_len, t->block_len);+		t->block_len   = block_len;+		t->sector     *= scale;+		t->nr_sectors *= scale;+	}+}+++/******************************************************************+ * State machine routines to read and write data+ *+ *  SET_BLOCKLEN only needs to be done once for each card.+ *  SET_BLOCK_COUNT is only valid in MMC 3.1; most cards don't support this,+ *  so we don't use it.+ * + *  In the 2.x cards we have a choice between STREAMING mode and+ *  SINGLE mode.  There's an obvious performance possibility in + *  using streaming mode, but at this time we're just using the SINGLE+ *  mode.+ ******************************************************************/++static void * mmc_cim_read_write_block( struct mmc_dev *dev, int first )+{+	struct mmc_io_request *t = dev->io_request;+	struct mmc_response_r1 r1;+	struct mmc_slot *slot = dev->slot + t->id;+	int    retval = 0;+	int    i;++	DEBUG(2," first=%d\n",first);++	if ( first ) {+		mmc_fix_request_block_size( dev );++		switch ( slot->state ) {+		case CARD_STATE_STBY:+			mmc_simple_cmd(dev, MMC_SELECT_CARD, ID_TO_RCA(slot->id) << 16, RESPONSE_R1B );+			break;+		case CARD_STATE_TRAN:+			mmc_simple_cmd(dev, MMC_SET_BLOCKLEN, t->block_len, RESPONSE_R1 );+			break;+		default:+			DEBUG(0,": invalid card state %d\n", slot->state);+			goto read_block_error;+			break;+		}+		return NULL;+	}++	switch (dev->request.cmd) {+	case MMC_SELECT_CARD:+		if ( (retval = mmc_unpack_r1( &dev->request, &r1, slot->state )) )+			goto read_block_error;++		for ( i = 0 ; i < dev->num_slots ; i++ )+			dev->slot[i].state = ( i == t->id ? CARD_STATE_TRAN : CARD_STATE_STBY );++		mmc_simple_cmd(dev, MMC_SET_BLOCKLEN, t->block_len, RESPONSE_R1 );+		break;++	case MMC_SET_BLOCKLEN:+		if ( (retval = mmc_unpack_r1( &dev->request, &r1, slot->state )) )+			goto read_block_error;++		mmc_send_cmd(dev, (t->cmd == READ ? MMC_READ_SINGLE_BLOCK : MMC_WRITE_BLOCK), +			     t->sector * t->block_len, 1, t->block_len, RESPONSE_R1 );+		break;++	case MMC_READ_SINGLE_BLOCK:+	case MMC_WRITE_BLOCK:+		if ( (retval = mmc_unpack_r1( &dev->request, &r1, slot->state )) )+			goto read_block_error;++		t->nr_sectors--;+		t->sector++;+		t->buffer += t->block_len;++		if ( t->nr_sectors ) {+			mmc_send_cmd(dev, (t->cmd == READ ? MMC_READ_SINGLE_BLOCK : MMC_WRITE_BLOCK), +				     t->sector * t->block_len, 1, t->block_len, RESPONSE_R1 );+		}+		else {+			mmc_finish_io_request( dev, 1 );+			if ( mmc_has_valid_request(dev) )+				return mmc_cim_read_write_block;+			return mmc_cim_default_state;+		}+		break;++	default:+		goto read_block_error;+		break;+	}+	return NULL;++read_block_error:+	DEBUG(0,": failure during cmd %d, error %d (%s)\n", +	      dev->request.cmd, retval, mmc_result_to_string(retval));+	mmc_finish_io_request( dev, 0 );   // Failure+	return mmc_cim_default_state;+}++/* Update the card's status information in preparation to running a read/write cycle */++static void * mmc_cim_get_status( struct mmc_dev *dev, int first )+{+	struct mmc_slot *slot = dev->slot + dev->io_request->id;+	struct mmc_response_r1 r1;+	int retval = MMC_NO_ERROR;++	DEBUG(2," first=%d\n",first);++	if ( first ) {+		mmc_simple_cmd(dev, MMC_SEND_STATUS, ID_TO_RCA(slot->id) <<

⌨️ 快捷键说明

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