From f22ee4edf63e7480511112d9965c71e07be3f8b7 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Tue, 26 Dec 2006 15:11:23 +0100 Subject: mmc: replace host->card_busy As card_busy was only used to indicate if the host was exclusively claimed and not really used to identify a particular card, replacing it with just a boolean makes things a lot more easily understandable. Signed-off-by: Pierre Ossman --- include/linux/mmc/host.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include/linux/mmc') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index c15ae1986b98..dc4c6e395198 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -106,8 +106,9 @@ struct mmc_host { struct list_head cards; /* devices attached to this host */ wait_queue_head_t wq; - spinlock_t lock; /* card_busy lock */ - struct mmc_card *card_busy; /* the MMC card claiming host */ + spinlock_t lock; /* claimed lock */ + unsigned int claimed:1; /* host exclusively claimed */ + struct mmc_card *card_selected; /* the selected MMC card */ struct delayed_work detect; -- cgit v1.2.3 From 11354d03afe9dd0d114e078057158baad4b4eee9 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sun, 14 Jan 2007 01:41:45 +0100 Subject: mmc: let host be parent of cards Change the parent of cards to be a specific host (a class device), not the physical controller. This is particularly useful when the hardware has multiple slots, meaning multiple hosts. Signed-off-by: Pierre Ossman --- include/linux/mmc/host.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux/mmc') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index dc4c6e395198..ae98d6766bdd 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -127,6 +127,7 @@ static inline void *mmc_priv(struct mmc_host *host) } #define mmc_dev(x) ((x)->parent) +#define mmc_classdev(x) (&(x)->class_dev) #define mmc_hostname(x) ((x)->class_dev.bus_id) extern int mmc_suspend_host(struct mmc_host *, pm_message_t); -- cgit v1.2.3 From fba68bd2dab1ac99af3c5a963ec9581cfa9f1725 Mon Sep 17 00:00:00 2001 From: Philip Langdale Date: Thu, 4 Jan 2007 06:57:32 -0800 Subject: mmc: Add support for SDHC cards Thanks to the generous donation of an SDHC card by John Gilmore, and the surprisingly enlightened decision by the SD Card Association to publish useful specs, I've been able to bash out support for SDHC. The changes are not too profound: i) Add a card flag indicating the card uses block level addressing and check it in the block driver. As we never took advantage of byte-level addressing, this simply involves skipping the block -> byte translation when sending commands. ii) The layout of the CSD is changed - a set of fields are discarded to make space for a larger C_SIZE. We did not reference any of the discarded fields except those related to the C_SIZE. iii) Read and write timeouts are fixed values and not calculated from CSD values. iv) Before invoking SEND_APP_OP_COND, we must invoke the new SEND_IF_COND to inform the card we support SDHC. Signed-off-by: Philipl Langdale Signed-off-by: Pierre Ossman --- include/linux/mmc/card.h | 3 +++ include/linux/mmc/mmc.h | 1 + include/linux/mmc/protocol.h | 13 ++++++++++++- 3 files changed, 16 insertions(+), 1 deletion(-) (limited to 'include/linux/mmc') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index d0e6a5497614..e45712acfac5 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -71,6 +71,7 @@ struct mmc_card { #define MMC_STATE_SDCARD (1<<3) /* is an SD card */ #define MMC_STATE_READONLY (1<<4) /* card is read-only */ #define MMC_STATE_HIGHSPEED (1<<5) /* card is in high speed mode */ +#define MMC_STATE_BLOCKADDR (1<<6) /* card uses block-addressing */ u32 raw_cid[4]; /* raw card CID */ u32 raw_csd[4]; /* raw card CSD */ u32 raw_scr[2]; /* raw card SCR */ @@ -87,6 +88,7 @@ struct mmc_card { #define mmc_card_sd(c) ((c)->state & MMC_STATE_SDCARD) #define mmc_card_readonly(c) ((c)->state & MMC_STATE_READONLY) #define mmc_card_highspeed(c) ((c)->state & MMC_STATE_HIGHSPEED) +#define mmc_card_blockaddr(c) ((c)->state & MMC_STATE_BLOCKADDR) #define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT) #define mmc_card_set_dead(c) ((c)->state |= MMC_STATE_DEAD) @@ -94,6 +96,7 @@ struct mmc_card { #define mmc_card_set_sd(c) ((c)->state |= MMC_STATE_SDCARD) #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY) #define mmc_card_set_highspeed(c) ((c)->state |= MMC_STATE_HIGHSPEED) +#define mmc_card_set_blockaddr(c) ((c)->state |= MMC_STATE_BLOCKADDR) #define mmc_card_name(c) ((c)->cid.prod_name) #define mmc_card_id(c) ((c)->dev.bus_id) diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index bcf24909d677..cdc54be804f1 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -43,6 +43,7 @@ struct mmc_command { #define MMC_RSP_R2 (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC) #define MMC_RSP_R3 (MMC_RSP_PRESENT) #define MMC_RSP_R6 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE) +#define MMC_RSP_R7 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE) #define mmc_resp_type(cmd) ((cmd)->flags & (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC|MMC_RSP_BUSY|MMC_RSP_OPCODE)) diff --git a/include/linux/mmc/protocol.h b/include/linux/mmc/protocol.h index 2dce60c43f4b..c90b6768329d 100644 --- a/include/linux/mmc/protocol.h +++ b/include/linux/mmc/protocol.h @@ -79,9 +79,12 @@ #define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1 */ /* SD commands type argument response */ - /* class 8 */ + /* class 0 */ /* This is basically the same command as for MMC with some quirks. */ #define SD_SEND_RELATIVE_ADDR 3 /* bcr R6 */ +#define SD_SEND_IF_COND 8 /* bcr [11:0] See below R7 */ + + /* class 10 */ #define SD_SWITCH 6 /* adtc [31:0] See below R1 */ /* Application commands */ @@ -114,6 +117,14 @@ * [3:0] Function group 1 */ +/* + * SD_SEND_IF_COND argument format: + * + * [31:12] Reserved (0) + * [11:8] Host Voltage Supply Flags + * [7:0] Check Pattern (0xAA) + */ + /* MMC status in R1 Type -- cgit v1.2.3 From fe4a3c7a20f14d86022a8132adbf6ddb98e7197c Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Tue, 21 Nov 2006 17:54:23 +0100 Subject: mmc: Allow host drivers to specify a max block size Most controllers have an upper limit on the block size. Allow the host drivers to specify this and make sure we avoid hitting this limit. Signed-off-by: Pierre Ossman --- include/linux/mmc/host.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux/mmc') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index ae98d6766bdd..2da0c918a8cc 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -94,6 +94,7 @@ struct mmc_host { unsigned short max_phys_segs; /* see blk_queue_max_phys_segments */ unsigned short max_sectors; /* see blk_queue_max_sectors */ unsigned short unused; + unsigned int max_blk_size; /* maximum size of one mmc block */ /* private data */ struct mmc_ios ios; /* current io bus settings */ -- cgit v1.2.3 From 55db890a838c7b37256241b1fc53d6344aa79cc0 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Tue, 21 Nov 2006 17:55:45 +0100 Subject: mmc: Allow host drivers to specify max block count Many controllers have an upper limit on the number of blocks that can be transferred in one request. Allow the host drivers to specify this and make sure we avoid hitting this limit. Also change the max_sectors field to avoid confusion. This makes it map less directly to the block layer limits, but as they didn't apply directly on MMC cards anyway, this isn't a great loss. Signed-off-by: Pierre Ossman --- include/linux/mmc/host.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux/mmc') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 2da0c918a8cc..913e5752569f 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -92,9 +92,10 @@ struct mmc_host { unsigned int max_seg_size; /* see blk_queue_max_segment_size */ unsigned short max_hw_segs; /* see blk_queue_max_hw_segments */ unsigned short max_phys_segs; /* see blk_queue_max_phys_segments */ - unsigned short max_sectors; /* see blk_queue_max_sectors */ unsigned short unused; + unsigned int max_req_size; /* maximum number of bytes in one req */ unsigned int max_blk_size; /* maximum size of one mmc block */ + unsigned int max_blk_count; /* maximum number of blocks in one req */ /* private data */ struct mmc_ios ios; /* current io bus settings */ -- cgit v1.2.3