?? hho-sd.patch
字號(hào):
+ host->ios.bus_width = MMC_BUS_WIDTH_1; host->ops->set_ios(host, &host->ios); } @@ -524,6 +796,34 @@ return err; } +static int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)+{+ struct mmc_command cmd;+ int i, err = 0;++ cmd.opcode = SD_APP_OP_COND;+ cmd.arg = ocr;+ cmd.flags = MMC_RSP_R3;++ for (i = 100; i; i--) {+ err = mmc_wait_for_app_cmd(host, 0, &cmd, CMD_RETRIES);+ if (err != MMC_ERR_NONE)+ break;++ if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0)+ break;++ err = MMC_ERR_TIMEOUT;++ mmc_delay(10);+ }++ if (rocr)+ *rocr = cmd.resp[0];++ return err;+}+ /* * Discover cards by requesting their CID. If this command * times out, it is not an error; there are no further cards@@ -567,6 +867,32 @@ card->state &= ~MMC_STATE_DEAD; + if (host->mode == MMC_MODE_SD) {+ mmc_card_set_sd(card);++ cmd.opcode = SD_SEND_RELATIVE_ADDR;+ cmd.arg = 0;+ cmd.flags = MMC_RSP_R1;++ err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);+ if (err != MMC_ERR_NONE)+ mmc_card_set_dead(card);+ else { + card->rca = cmd.resp[0] >> 16;+ + if (!host->ops->get_ro) {+ printk(KERN_WARNING "%s: host does not "+ "support reading read-only "+ "switch. assuming write-enable.\n",+ host->host_name);+ }+ else {+ if (host->ops->get_ro(host))+ mmc_card_set_readonly(card);+ }+ }+ }+ else { cmd.opcode = MMC_SET_RELATIVE_ADDR; cmd.arg = card->rca << 16; cmd.flags = MMC_RSP_R1;@@ -575,6 +901,7 @@ if (err != MMC_ERR_NONE) mmc_card_set_dead(card); }+ } } static void mmc_read_csds(struct mmc_host *host)@@ -605,6 +932,80 @@ } } +static void mmc_read_scrs(struct mmc_host *host)+{+ int err;+ struct mmc_card *card;+ + struct mmc_request mrq;+ struct mmc_command cmd;+ struct mmc_data data;++ struct scatterlist sg;+ + list_for_each_entry(card, &host->cards, node) {+ if (card->state & (MMC_STATE_DEAD|MMC_STATE_PRESENT))+ continue;+ if (!mmc_card_sd(card))+ continue;+ + err = mmc_select_card(host, card);+ if (err != MMC_ERR_NONE)+ {+ mmc_card_set_dead(card);+ continue;+ }+ + memset(&cmd, 0, sizeof(struct mmc_command));+ + cmd.opcode = MMC_APP_CMD;+ cmd.arg = card->rca << 16;+ cmd.flags = MMC_RSP_R1;+ + err = mmc_wait_for_cmd(host, &cmd, 0);+ if ((err != MMC_ERR_NONE) || !(cmd.resp[0] & R1_APP_CMD)) {+ mmc_card_set_dead(card);+ continue;+ }+ + memset(&cmd, 0, sizeof(struct mmc_command));+ + cmd.opcode = SD_APP_SEND_SCR;+ cmd.arg = 0;+ cmd.flags = MMC_RSP_R1;+ + memset(&data, 0, sizeof(struct mmc_data));+ + data.timeout_ns = card->csd.tacc_ns * 10;+ data.timeout_clks = card->csd.tacc_clks * 10;+ data.blksz_bits = 3;+ data.blocks = 1;+ data.flags = MMC_DATA_READ;+ data.sg = &sg;+ data.sg_len = 1;+ + memset(&mrq, 0, sizeof(struct mmc_request));+ + mrq.cmd = &cmd;+ mrq.data = &data;+ + sg_init_one(&sg, (u8*)card->raw_scr, 8);+ + err = mmc_wait_for_req(host, &mrq);+ if (err != MMC_ERR_NONE) {+ mmc_card_set_dead(card);+ continue;+ }+ + card->raw_scr[0] = ntohl(card->raw_scr[0]);+ card->raw_scr[1] = ntohl(card->raw_scr[1]);++ mmc_decode_scr(card);+ }+ + mmc_deselect_cards(host);+}+ static unsigned int mmc_calculate_clock(struct mmc_host *host) { struct mmc_card *card;@@ -657,13 +1058,26 @@ int err; u32 ocr; + host->mode = MMC_MODE_MMC;+ mmc_power_up(host); mmc_idle_cards(host); err = mmc_send_op_cond(host, 0, &ocr);+ + /*+ * If we fail to detect any cards then try+ * searching for SD cards.+ */+ if (err != MMC_ERR_NONE)+ {+ err = mmc_send_app_op_cond(host, 0, &ocr); if (err != MMC_ERR_NONE) return; + host->mode = MMC_MODE_SD;+ }+ host->ocr = mmc_select_voltage(host, ocr); /*@@ -702,6 +1116,9 @@ * all get the idea that they should be ready for CMD2. * (My SanDisk card seems to need this.) */+ if (host->mode == MMC_MODE_SD)+ mmc_send_app_op_cond(host, host->ocr, NULL);+ else mmc_send_op_cond(host, host->ocr, NULL); mmc_discover_cards(host);@@ -713,6 +1130,9 @@ host->ops->set_ios(host, &host->ios); mmc_read_csds(host);+ + if (host->mode == MMC_MODE_SD)+ mmc_read_scrs(host); } diff -Nbur linux26-cvs/drivers/mmc/mmc_sysfs.c linux26-cvs.SD/drivers/mmc/mmc_sysfs.c--- linux26-cvs/drivers/mmc/mmc_sysfs.c 2005-09-06 10:00:07.000000000 -0500+++ linux26-cvs.SD/drivers/mmc/mmc_sysfs.c 2005-09-06 09:58:25.000000000 -0500@@ -163,6 +163,7 @@ card->raw_cid[2], card->raw_cid[3]); MMC_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1], card->raw_csd[2], card->raw_csd[3]);+MMC_ATTR(scr, "%08x%08x\n", card->raw_scr[0], card->raw_scr[1]); MMC_ATTR(date, "%02d/%04d\n", card->cid.month, card->cid.year); MMC_ATTR(fwrev, "0x%x\n", card->cid.fwrev); MMC_ATTR(hwrev, "0x%x\n", card->cid.hwrev);@@ -174,6 +175,7 @@ static struct device_attribute *mmc_dev_attributes[] = { &dev_attr_cid, &dev_attr_csd,+ &dev_attr_scr, &dev_attr_date, &dev_attr_fwrev, &dev_attr_hwrev,diff -Nbur linux26-cvs/include/linux/mmc/card.h linux26-cvs.SD/include/linux/mmc/card.h--- linux26-cvs/include/linux/mmc/card.h 2005-09-06 10:00:42.000000000 -0500+++ linux26-cvs.SD/include/linux/mmc/card.h 2005-09-06 09:58:25.000000000 -0500@@ -33,6 +33,13 @@ unsigned int capacity; }; +struct sd_scr {+ unsigned char sda_vsn;+ unsigned char bus_widths;+#define SD_SCR_BUS_WIDTH_1 (1<<0)+#define SD_SCR_BUS_WIDTH_4 (1<<2)+};+ struct mmc_host; /*@@ -47,19 +54,27 @@ #define MMC_STATE_PRESENT (1<<0) /* present in sysfs */ #define MMC_STATE_DEAD (1<<1) /* device no longer in stack */ #define MMC_STATE_BAD (1<<2) /* unrecognised device */+#define MMC_STATE_SDCARD (1<<3) /* is an SD card */+#define MMC_STATE_READONLY (1<<4) /* card is read-only */ u32 raw_cid[4]; /* raw card CID */ u32 raw_csd[4]; /* raw card CSD */+ u32 raw_scr[2]; /* raw card SCR */ struct mmc_cid cid; /* card identification */ struct mmc_csd csd; /* card specific */+ struct sd_scr scr; /* extra SD information */ }; #define mmc_card_present(c) ((c)->state & MMC_STATE_PRESENT) #define mmc_card_dead(c) ((c)->state & MMC_STATE_DEAD) #define mmc_card_bad(c) ((c)->state & MMC_STATE_BAD)+#define mmc_card_sd(c) ((c)->state & MMC_STATE_SDCARD)+#define mmc_card_readonly(c) ((c)->state & MMC_STATE_READONLY) #define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT) #define mmc_card_set_dead(c) ((c)->state |= MMC_STATE_DEAD) #define mmc_card_set_bad(c) ((c)->state |= MMC_STATE_BAD)+#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_name(c) ((c)->cid.prod_name) #define mmc_card_id(c) ((c)->dev.bus_id)diff -Nbur linux26-cvs/include/linux/mmc/host.h linux26-cvs.SD/include/linux/mmc/host.h--- linux26-cvs/include/linux/mmc/host.h 2005-09-06 10:00:42.000000000 -0500+++ linux26-cvs.SD/include/linux/mmc/host.h 2005-09-06 09:58:25.000000000 -0500@@ -51,11 +51,17 @@ #define MMC_POWER_OFF 0 #define MMC_POWER_UP 1 #define MMC_POWER_ON 2++ unsigned char bus_width; /* data bus width */++#define MMC_BUS_WIDTH_1 0+#define MMC_BUS_WIDTH_4 2 }; struct mmc_host_ops { void (*request)(struct mmc_host *host, struct mmc_request *req); void (*set_ios)(struct mmc_host *host, struct mmc_ios *ios);+ int (*get_ro)(struct mmc_host *host); }; struct mmc_card;@@ -69,6 +75,10 @@ u32 ocr_avail; char host_name[8]; + unsigned long caps; /* Host capabilities */++#define MMC_CAP_4_BIT_DATA (1 << 0) /* Can the host do 4 bit transfers */+ /* host specific block data */ unsigned int max_seg_size; /* see blk_queue_max_segment_size */ unsigned short max_hw_segs; /* see blk_queue_max_hw_segments */@@ -80,6 +90,10 @@ struct mmc_ios ios; /* current io bus settings */ u32 ocr; /* the current OCR setting */ + unsigned int mode; /* current card mode of host */+#define MMC_MODE_MMC 0+#define MMC_MODE_SD 1+ struct list_head cards; /* devices attached to this host */ wait_queue_head_t wq;diff -Nbur linux26-cvs/include/linux/mmc/mmc.h linux26-cvs.SD/include/linux/mmc/mmc.h--- linux26-cvs/include/linux/mmc/mmc.h 2005-09-06 10:00:42.000000000 -0500+++ linux26-cvs.SD/include/linux/mmc/mmc.h 2005-09-06 09:58:25.000000000 -0500@@ -37,6 +37,7 @@ #define MMC_RSP_R1B (MMC_RSP_SHORT|MMC_RSP_CRC|MMC_RSP_BUSY) #define MMC_RSP_R2 (MMC_RSP_LONG|MMC_RSP_CRC) #define MMC_RSP_R3 (MMC_RSP_SHORT)+#define MMC_RSP_R6 (MMC_RSP_SHORT|MMC_RSP_CRC) unsigned int retries; /* max number of retries */ unsigned int error; /* command error */@@ -47,6 +48,8 @@ #define MMC_ERR_FIFO 3 #define MMC_ERR_FAILED 4 #define MMC_ERR_INVALID 5+#define MMC_ERR_BUSY 6+#define MMC_ERR_DMA 7 struct mmc_data *data; /* data segment associated with cmd */ struct mmc_request *mrq; /* assoicated request */@@ -73,11 +76,16 @@ struct scatterlist *sg; /* I/O scatter list */ }; +#define MMC_CMD_ACTIVE_BIT 0x01+ struct mmc_request { struct mmc_command *cmd; struct mmc_data *data; struct mmc_command *stop; + int flags;+ wait_queue_head_t wait;+ void *done_data; /* completion data */ void (*done)(struct mmc_request *);/* completion function */ };@@ -85,8 +93,15 @@ struct mmc_host; struct mmc_card; +extern int mmc_uninterruptible_wait_for_req(struct mmc_host *,+ struct mmc_request *);+extern int mmc_uninterruptible_cmd(struct mmc_host *, struct mmc_command *, + int);+ extern int mmc_wait_for_req(struct mmc_host *, struct mmc_request *); extern int mmc_wait_for_cmd(struct mmc_host *, struct mmc_command *, int);+extern int mmc_wait_for_app_cmd(struct mmc_host *, unsigned int,+ struct mmc_command *, int); extern int __mmc_claim_host(struct mmc_host *host, struct mmc_card *card); diff -Nbur linux26-cvs/include/linux/mmc/protocol.h linux26-cvs.SD/include/linux/mmc/protocol.h--- linux26-cvs/include/linux/mmc/protocol.h 2005-09-06 10:00:42.000000000 -0500+++ linux26-cvs.SD/include/linux/mmc/protocol.h 2005-09-06 09:58:25.000000000 -0500@@ -76,6 +76,16 @@ #define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */ #define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1b */ +/* SD commands type argument response */+ /* class 8 */+/* This is basically the same command as for MMC with some quirks. */+#define SD_SEND_RELATIVE_ADDR 3 /* ac R6 */++ /* Application commands */+#define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */+#define SD_APP_OP_COND 41 /* bcr [31:0] OCR R3 */+#define SD_APP_SEND_SCR 51 /* adtc R1 */+ /* MMC status in R1 Type@@ -113,7 +123,7 @@ #define R1_STATUS(x) (x & 0xFFFFE000) #define R1_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) /* sx, b (4 bits) */ #define R1_READY_FOR_DATA (1 << 8) /* sx, a */-#define R1_APP_CMD (1 << 7) /* sr, c */+#define R1_APP_CMD (1 << 5) /* sr, c */ /* These are unpacked versions of the actual responses */ @@ -199,5 +209,12 @@ #define CSD_SPEC_VER_2 2 /* Implements system specification 2.0 - 2.2 */ #define CSD_SPEC_VER_3 3 /* Implements system specification 3.1 */ ++/*+ * SD bus widths+ */+#define SD_BUS_WIDTH_1 0+#define SD_BUS_WIDTH_4 2+ #endif /* MMC_MMC_PROTOCOL_H */
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -