📄 patch-2.4.19-mmc
字号:
++void mmc_handle_io_request( struct mmc_io_request *t )+{+ DEBUG(2," 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);+ + if ( g_mmc_dev.io_request ) {+ DEBUG(0,": error! io_request in progress\n");+ return;+ }+ + g_mmc_dev.io_request = t;+ tasklet_schedule(&g_mmc_dev.task);+}++EXPORT_SYMBOL(mmc_handle_io_request);++/******************************************************************+ * Media handlers+ * Allow different drivers to register a media handler+ ******************************************************************/++static LIST_HEAD(mmc_media_drivers);++int mmc_match_media_driver( struct mmc_slot *slot )+{+ struct list_head *item;++ DEBUG(2,": slot=%p\n", slot);++ for ( item = mmc_media_drivers.next ; item != &mmc_media_drivers ; item = item->next ) {+ struct mmc_media_driver *drv = list_entry(item, struct mmc_media_driver, node );+ if ( drv->probe(slot) ) {+ slot->media_driver = drv;+ drv->load(slot);+ return 1;+ }+ }+ return 0;+}++int mmc_register_media_driver( struct mmc_media_driver *drv )+{+ list_add_tail( &drv->node, &mmc_media_drivers );+ return 0;+}++void mmc_unregister_media_driver( struct mmc_media_driver *drv )+{+ list_del(&drv->node);+}++EXPORT_SYMBOL(mmc_register_media_driver);+EXPORT_SYMBOL(mmc_unregister_media_driver);++/******************************************************************/++int mmc_register_slot_driver( struct mmc_slot_driver *sdrive, int num_slots )+{+ int i;+ int retval;++ DEBUG(2," max=%d ocr=0x%08x\n", num_slots, sdrive->ocr);++ if ( num_slots > MMC_MAX_SLOTS ) {+ printk(KERN_CRIT __FUNCTION__ ": illegal num of slots %d\n", num_slots );+ return -ENOMEM;+ }++ if ( g_mmc_dev.sdrive ) {+ printk(KERN_ALERT __FUNCTION__ ": slot in use\n");+ return -EBUSY;+ }++ g_mmc_dev.sdrive = sdrive;+ g_mmc_dev.num_slots = num_slots;++ for ( i = 0 ; i < num_slots ; i++ ) {+ struct mmc_slot *slot = &g_mmc_dev.slot[i];+ memset(slot,0,sizeof(struct mmc_slot));+ slot->id = i;+ slot->state = CARD_STATE_EMPTY;+ }+ retval = sdrive->init();+ if ( retval )+ return retval;++ /* Generate insert events for cards */+ for ( i = 0 ; i < num_slots ; i++ )+ if ( !sdrive->is_empty(i) )+ mmc_insert(i);+ return 0;+}++void mmc_unregister_slot_driver( struct mmc_slot_driver *sdrive )+{+ int i;+ DEBUG(2,"\n");++ for ( i = 0 ; i < g_mmc_dev.num_slots ; i++ )+ mmc_eject(i);++ if ( sdrive == g_mmc_dev.sdrive ) {+ g_mmc_dev.sdrive->cleanup();+ g_mmc_dev.sdrive = NULL;+ }+}++EXPORT_SYMBOL(mmc_register_slot_driver);+EXPORT_SYMBOL(mmc_unregister_slot_driver);++/******************************************************************/++static struct pm_dev *mmc_pm_dev;++static int mmc_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data)+{+ int i;+ DEBUG(0,": pm callback %d\n", req );++ switch (req) {+ case PM_SUSPEND: /* Enter D1-D3 */+ g_mmc_dev.suspended = 1;+ break;+ case PM_RESUME: /* Enter D0 */+ if ( g_mmc_dev.suspended ) {+ g_mmc_dev.suspended = 0;+ g_mmc_dev.state = 0; // Clear the old state+ for ( i = 0 ; i < g_mmc_dev.num_slots ; i++ ) {+ mmc_eject(i);+ if ( !g_mmc_dev.sdrive->is_empty(i) )+ mmc_insert(i);+ }+ }+ break;+ }+ return 0;+}++/******************************************************************+ * TODO: These would be better handled by driverfs+ * For the moment, we'll just eject and insert everything+ ******************************************************************/++int mmc_do_eject(ctl_table *ctl, int write, struct file * filp, void *buffer, size_t *lenp)+{+ mmc_eject(0);+ return 0;+}++int mmc_do_insert(ctl_table *ctl, int write, struct file * filp, void *buffer, size_t *lenp)+{+ mmc_insert(0);+ return 0;+}+++static struct ctl_table mmc_sysctl_table[] =+{+ { 1, "debug", &g_mmc_debug, sizeof(int), 0666, NULL, &proc_dointvec },+ { 2, "eject", NULL, 0, 0600, NULL, &mmc_do_eject },+ { 3, "insert", NULL, 0, 0600, NULL, &mmc_do_insert },+ {0}+};++static struct ctl_table mmc_dir_table[] =+{+ {BUS_MMC, "mmc", NULL, 0, 0555, mmc_sysctl_table},+ {0}+};++static struct ctl_table bus_dir_table[] = +{+ {CTL_BUS, "bus", NULL, 0, 0555, mmc_dir_table},+ {0}+};++static struct ctl_table_header *mmc_sysctl_header;++static int mmc_proc_read_device(char *page, char **start, off_t off, int count, int *eof, void *data)+{+ struct mmc_dev *dev = (struct mmc_dev *)data;+ char *p = page;+ int len = 0;+ int i;++ if (!dev || !dev->sdrive)+ return 0;++ for ( i = 0 ; i < dev->num_slots ; i++ ) {+ struct mmc_slot *slot = &dev->slot[i];++ p += sprintf(p, "Slot #%d\n", i);+ p += sprintf(p, " State %s (%d)\n", card_state_to_string(slot->state), slot->state);++ if ( slot->state != CARD_STATE_EMPTY ) {+ p += sprintf(p, " Media %s\n", (slot->media_driver ? slot->media_driver->name : "unknown"));+ p += sprintf(p, " CID mid=%d\n", slot->cid.mid);+ p += sprintf(p, " oid=%d\n", slot->cid.oid);+ p += sprintf(p, " pnm=%s\n", slot->cid.pnm);+ p += sprintf(p, " prv=%d.%d\n", slot->cid.prv>>4, slot->cid.prv&0xf);+ p += sprintf(p, " psn=0x%08x\n", slot->cid.psn);+ p += sprintf(p, " mdt=%d/%d\n", slot->cid.mdt>>4, (slot->cid.mdt&0xf)+1997);++ p += sprintf(p, " CSD csd_structure=%d\n", slot->csd.csd_structure);+ p += sprintf(p, " spec_vers=%d\n", slot->csd.spec_vers);+ p += sprintf(p, " taac=0x%02x\n", slot->csd.taac);+ p += sprintf(p, " nsac=0x%02x\n", slot->csd.nsac);+ p += sprintf(p, " tran_speed=0x%02x\n", slot->csd.tran_speed);+ p += sprintf(p, " ccc=0x%04x\n", slot->csd.ccc);+ p += sprintf(p, " read_bl_len=%d\n", slot->csd.read_bl_len);+ p += sprintf(p, " read_bl_partial=%d\n", slot->csd.read_bl_partial);+ p += sprintf(p, " write_blk_misalign=%d\n", slot->csd.write_blk_misalign);+ p += sprintf(p, " read_blk_misalign=%d\n", slot->csd.read_blk_misalign);+ p += sprintf(p, " dsr_imp=%d\n", slot->csd.dsr_imp);+ p += sprintf(p, " c_size=%d\n", slot->csd.c_size);+ p += sprintf(p, " vdd_r_curr_min=%d\n", slot->csd.vdd_r_curr_min);+ p += sprintf(p, " vdd_r_curr_max=%d\n", slot->csd.vdd_r_curr_max);+ p += sprintf(p, " vdd_w_curr_min=%d\n", slot->csd.vdd_w_curr_min);+ p += sprintf(p, " vdd_w_curr_max=%d\n", slot->csd.vdd_w_curr_max);+ p += sprintf(p, " c_size_mult=%d\n", slot->csd.c_size_mult);+ p += sprintf(p, " wp_grp_size=%d\n", slot->csd.wp_grp_size);+ p += sprintf(p, " wp_grp_enable=%d\n", slot->csd.wp_grp_enable);+ p += sprintf(p, " default_ecc=%d\n", slot->csd.default_ecc);+ p += sprintf(p, " r2w_factor=%d\n", slot->csd.r2w_factor);+ p += sprintf(p, " write_bl_len=%d\n", slot->csd.write_bl_len);+ p += sprintf(p, " write_bl_partial=%d\n", slot->csd.write_bl_partial);+ p += sprintf(p, " file_format_grp=%d\n", slot->csd.file_format_grp);+ p += sprintf(p, " copy=%d\n", slot->csd.copy);+ p += sprintf(p, " perm_write_protect=%d\n", slot->csd.perm_write_protect);+ p += sprintf(p, " tmp_write_protect=%d\n", slot->csd.tmp_write_protect);+ p += sprintf(p, " file_format=%d\n", slot->csd.file_format);+ p += sprintf(p, " ecc=%d\n", slot->csd.ecc);+ switch (slot->csd.csd_structure) {+ case CSD_STRUCT_VER_1_0:+ case CSD_STRUCT_VER_1_1:+ p += sprintf(p, " sector_size=%d\n", slot->csd.erase.v22.sector_size);+ p += sprintf(p, " erase_grp_size=%d\n", slot->csd.erase.v22.erase_grp_size);+ break;+ case CSD_STRUCT_VER_1_2:+ default:+ p += sprintf(p, " erase_grp_size=%d\n", slot->csd.erase.v31.erase_grp_size);+ p += sprintf(p, " erase_grp_mult=%d\n", slot->csd.erase.v31.erase_grp_mult);+ break;+ }+ }+ }++ len = (p - page) - off;+ *start = page + off;+ return len;+}++/******************************************************************/++void mmc_protocol_single_card( struct mmc_dev *dev, int state_flags );+extern struct mmc_media_module media_module;++static int __init mmc_init(void) +{+ DEBUG(1,"\n");+ + mmc_sysctl_header = register_sysctl_table(bus_dir_table, 0 );++ tasklet_init(&g_mmc_dev.task,mmc_tasklet_action,(unsigned long)&g_mmc_dev);+ g_mmc_dev.protocol = mmc_protocol_single_card;++ proc_mmc_dir = proc_mkdir("mmc", proc_bus);+ if ( proc_mmc_dir )+ create_proc_read_entry("device", 0, proc_mmc_dir, mmc_proc_read_device, &g_mmc_dev);++ mmc_pm_dev = pm_register(PM_UNKNOWN_DEV, PM_SYS_UNKNOWN, mmc_pm_callback);++ media_module.init();+ return 0;+}++static void __exit mmc_exit(void)+{+ DEBUG(1,"\n");++ media_module.cleanup();++ unregister_sysctl_table(mmc_sysctl_header);++ tasklet_kill(&g_mmc_dev.task);++ if ( proc_mmc_dir ) {+ remove_proc_entry("device", proc_mmc_dir);+ remove_proc_entry("mmc", proc_bus);+ }++ pm_unregister(mmc_pm_dev);+}++module_init(mmc_init);+module_exit(mmc_exit);++MODULE_AUTHOR(Andy Christian)+MODULE_LICENSE("MIT")+MODULE_DESCRIPTION("Core support for MultiMedia Cards")diff -ruwN -X dontdiff linux-2.4.19/drivers/mmc/mmc_core.h linux-2.4.19-mmc1/drivers/mmc/mmc_core.h--- linux-2.4.19/drivers/mmc/mmc_core.h Wed Dec 31 19:00:00 1969+++ linux-2.4.19-mmc1/drivers/mmc/mmc_core.h Fri Aug 9 16:07:14 2002@@ -0,0 +1,79 @@+/*+ * 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 19:06:06 $ + *+ * Author: Andrew Christian+ * 15 May 2002+ */++#ifndef MMC_MMC_CORE_H+#define MMC_MMC_CORE_H++#include <linux/mmc/mmc_ll.h>+#include "mmc_media.h"++#define ID_TO_RCA(x) ((x)+1)++struct mmc_dev {+ struct mmc_slot_driver *sdrive;+ struct mmc_slot slot[MMC_MAX_SLOTS];+ struct mmc_request request; // Active request to the low-level driver+ struct mmc_io_request *io_request; // Active transfer request from the high-level media io+ struct tasklet_struct task;+ int num_slots; // Copied from the slot driver; used when slot driver shuts down++ /* State maintenance */+ int state; + int suspended;+ void (*protocol)(struct mmc_dev *, int);+};++char * mmc_result_to_string( int );+int mmc_unpack_csd( struct mmc_request *request, struct mmc_csd *csd );+int mmc_unpack_r1( struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state );+int mmc_unpack_cid( struct mmc_request *request, struct mmc_cid *cid );+int mmc_unpack_r3( struct mmc_request *request, struct mmc_response_r3 *r3 );++void mmc_send_cmd( struct mmc_dev *dev, int cmd, u32 arg, + u16 nob, u16 block_len, enum mmc_rsp_t rtype );+void mmc_finish_io_request( struct mmc_dev *dev, int result );+int mmc_check_eject( struct mmc_dev *dev );+int mmc_check_insert( struct mmc_dev *dev );+u32 mmc_tran_speed( u8 ts );+int mmc_match_media_driver( struct mmc_slot *slot );+void run_sbin_mmc_hotplug(struct mmc_dev *dev, int id, int insert);++static inline void mmc_simple_cmd( struct mmc_dev *dev, int cmd, u32 arg, enum mmc_rsp_t rtype )+{+ mmc_send_cmd( dev, cmd, arg, 0, 0, rtype );+}++#endif /* MMC_MMC_CORE_H */+diff -ruwN -X dontdiff linux-2.4.19/drivers/mmc/mmc_media.c linux-2.4.19-mmc1/drivers/mmc/mmc_media.c--- linux-2.4.19/drivers/mmc/mmc_media.c Wed Dec 31 19:00:00 1969+++ linux-2.4.19-mmc1/drivers/mmc/mmc_media.c Fri Aug 9 16:07:24 2002@@ -0,0 +1,511 @@+/*+ * Block driver for media (i.e., flash cards)+ *+ * Copyright 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.+ *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -