From: David Brownell <david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
To: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
Cc: Mikael Starvik <mikael.starvik-VrBV9hrLPhE@public.gmane.org>,
Hans-Peter Nilsson
<hans-peter.nilsson-VrBV9hrLPhE@public.gmane.org>,
Mike Lavender
<mike-UTnDXsALFwNjMdQLN6DIHgC/G2K4zDHf@public.gmane.org>,
Pierre Ossman
<drzeus-mmc-p3sGCRWkH8CeZLLa646FqQ@public.gmane.org>
Subject: [patch 2.6.22-rc4 8/7] mmc_spi cid/csd/ext_csd updates, CRCs on
Date: Tue, 5 Jun 2007 10:13:44 -0700 [thread overview]
Message-ID: <200706051013.44971.david-b@pacbell.net> (raw)
In-Reply-To: <200706042025.18252.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
Fix some of the "register"/descriptor access glitches in the
preceding patches:
- Updated internal routines:
* previous mmc_send_cxd() renamed to mmc_send_cxd_native(); it
uses native "R2" responses, which include 16 bytes of data.
* previous mmc_send_ext_csd() becomes new mmc_send_cxd_data()
helper for command-and-data access
- Modified mmc_send_ext_csd() now uses mmc_send_cxd_data() helper
- New mmc_send_csd() and mmc_spi_send_cid() routines now use one
of those helper routines based on whether they're native or SPI;
- Remove ugly "R1D" response pseudo-type for SPI
- Make it OK for MMC cards to try SEND_EXT_CSD; v4+ needs that
- Turn CRCs back on by default with the SPI protocol
So this resolves most of the technical issues I know about, leaving
nontechnical ones like "is this code clean enough" or "is this how
we want to solve that problem".
Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>
---
drivers/mmc/core/mmc.c | 2
drivers/mmc/core/mmc_ops.c | 93 +++++++++++++++++++++++++++++++++------------
drivers/mmc/host/mmc_spi.c | 59 ----------------------------
include/linux/mmc/core.h | 8 ---
4 files changed, 72 insertions(+), 90 deletions(-)
--- g26.orig/drivers/mmc/core/mmc_ops.c 2007-06-04 19:58:58.000000000 -0700
+++ g26/drivers/mmc/core/mmc_ops.c 2007-06-05 10:05:20.000000000 -0700
@@ -175,7 +175,7 @@ int mmc_set_relative_addr(struct mmc_car
}
static int
-mmc_send_cxd(struct mmc_host *host, unsigned rca, u32 *cxd, int opcode)
+mmc_send_cxd_native(struct mmc_host *host, unsigned rca, u32 *cxd, int opcode)
{
int err;
struct mmc_command cmd;
@@ -187,7 +187,7 @@ mmc_send_cxd(struct mmc_host *host, unsi
cmd.opcode = opcode;
cmd.arg = rca << 16;
- cmd.flags = MMC_RSP_SPI_R1D | MMC_RSP_R2 | MMC_CMD_AC;
+ cmd.flags = MMC_RSP_R2 | MMC_CMD_AC;
err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);
if (err != MMC_ERR_NONE)
@@ -198,16 +198,6 @@ mmc_send_cxd(struct mmc_host *host, unsi
return MMC_ERR_NONE;
}
-int mmc_send_csd(struct mmc_card *card, u32 *csd)
-{
- return mmc_send_cxd(card->host, card->rca, csd, MMC_SEND_CSD);
-}
-
-int mmc_spi_send_cid(struct mmc_host *host, u32 *cid)
-{
- return mmc_send_cxd(host, 0, cid, MMC_SEND_CID);
-}
-
int mmc_spi_read_ocr(struct mmc_host *host, u32 *ocrp)
{
struct mmc_command cmd;
@@ -238,17 +228,22 @@ int mmc_spi_set_crc(struct mmc_host *hos
return mmc_wait_for_cmd(host, &cmd, 0);
}
-int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd)
+struct mmc_cxd {
+ struct mmc_card *card; /* optional */
+ void *buf;
+ unsigned len;
+ u32 opcode;
+ u32 arg;
+ unsigned flags;
+};
+
+static int mmc_send_cxd_data(struct mmc_host *host, struct mmc_cxd *cxd)
{
struct mmc_request mrq;
struct mmc_command cmd;
struct mmc_data data;
struct scatterlist sg;
- BUG_ON(!card);
- BUG_ON(!card->host);
- BUG_ON(!ext_csd);
-
memset(&mrq, 0, sizeof(struct mmc_request));
memset(&cmd, 0, sizeof(struct mmc_command));
memset(&data, 0, sizeof(struct mmc_data));
@@ -256,21 +251,22 @@ int mmc_send_ext_csd(struct mmc_card *ca
mrq.cmd = &cmd;
mrq.data = &data;
- cmd.opcode = MMC_SEND_EXT_CSD;
- cmd.arg = 0;
- cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
+ cmd.opcode = cxd->opcode;
+ cmd.arg = cxd->arg;
+ cmd.flags = cxd->flags;
- data.blksz = 512;
+ data.blksz = cxd->len;
data.blocks = 1;
data.flags = MMC_DATA_READ;
data.sg = &sg;
data.sg_len = 1;
- sg_init_one(&sg, ext_csd, 512);
+ sg_init_one(&sg, cxd->buf, cxd->len);
- mmc_set_data_timeout(&data, card, 0);
+ if (cxd->card)
+ mmc_set_data_timeout(&data, cxd->card, 0);
- mmc_wait_for_req(card->host, &mrq);
+ mmc_wait_for_req(host, &mrq);
if (cmd.error != MMC_ERR_NONE)
return cmd.error;
@@ -280,6 +276,55 @@ int mmc_send_ext_csd(struct mmc_card *ca
return MMC_ERR_NONE;
}
+int mmc_send_csd(struct mmc_card *card, u32 *csd)
+{
+ struct mmc_cxd cxd;
+
+ if (!mmc_host_is_spi(card->host))
+ return mmc_send_cxd_native(card->host, card->rca,
+ csd, MMC_SEND_CSD);
+
+ cxd.card = card;
+ cxd.buf = csd;
+ cxd.len = 16;
+ cxd.opcode = MMC_SEND_CSD;
+ cxd.arg = 0;
+ cxd.flags = MMC_RSP_SPI_R1;
+
+ return mmc_send_cxd_data(card->host, &cxd);
+}
+
+int mmc_spi_send_cid(struct mmc_host *host, u32 *cid)
+{
+ struct mmc_cxd cxd;
+
+ if (!mmc_host_is_spi(host))
+ return mmc_send_cxd_native(host, 0, cid, MMC_SEND_CID);
+
+ cxd.card = NULL;
+ cxd.buf = cid;
+ cxd.len = 16;
+ cxd.opcode = MMC_SEND_CID;
+ cxd.arg = 0;
+ cxd.flags = MMC_RSP_SPI_R1;
+
+ return mmc_send_cxd_data(host, &cxd);
+}
+
+int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd)
+{
+ struct mmc_cxd cxd;
+
+ cxd.card = card;
+ cxd.buf = ext_csd;
+ cxd.len = 512;
+ cxd.opcode = MMC_SEND_EXT_CSD;
+ cxd.arg = 0;
+ cxd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
+
+ return mmc_send_cxd_data(card->host, &cxd);
+}
+
int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value)
{
int err;
--- g26.orig/drivers/mmc/host/mmc_spi.c 2007-06-04 19:59:01.000000000 -0700
+++ g26/drivers/mmc/host/mmc_spi.c 2007-06-05 10:05:20.000000000 -0700
@@ -181,13 +181,7 @@ module_param(debug, uint, 0644);
#define debug 0
#endif
-/* FIXME turn this back on by default ... needs retesting */
-#if 0
static unsigned use_crc = 1;
-#else
-static unsigned use_crc = 0;
-#endif
-
module_param(use_crc, uint, 0);
@@ -384,51 +378,10 @@ static char *maptype(struct mmc_command
case MMC_RSP_SPI_R1B: return "R1B";
case MMC_RSP_SPI_R2: return "R2";
case MMC_RSP_SPI_R3: return "R3";
- case MMC_RSP_SPI_R1D: return "R1D";
default: return "?";
}
}
-static void mmc_spi_read_cXd(struct mmc_spi_host *host, struct mmc_command *cmd)
-{
- int status;
-
- /* skip till first byte of data block */
- status = mmc_spi_scanbyte(host, mmc_spi_delayed, READ_TIMEOUT);
-
- /* if we found the data block, read it; else report timeout */
- if (status == SPI_TOKEN_SINGLE) {
-
- spi_message_init(&host->m);
- memset(&host->t, 0, sizeof(host->t));
- spi_message_add_tail(&host->t, &host->m);
-
- memset(cmd->resp, 0xff, 16);
- host->t.tx_buf = cmd->resp;
- host->t.rx_buf = cmd->resp;
- host->t.len = 16;
-
- /* REVISIT 16 bit CRC ... ? */
-
- status = spi_sync(host->spi, &host->m);
- if (status < 0)
- cmd->error = MMC_ERR_FAILED;
- else {
- be32_to_cpus(&cmd->resp[0]);
- be32_to_cpus(&cmd->resp[1]);
- be32_to_cpus(&cmd->resp[2]);
- be32_to_cpus(&cmd->resp[3]);
- }
- } else {
- if (status > 0)
- mmc_spi_map_data_err(cmd, status);
- dev_dbg(&host->spi->dev,
- "mmc_spi: read cXd, %02x %d \n",
- status & 0xff, status);
- cmd->error = MMC_ERR_TIMEOUT;
- }
-}
-
static int
mmc_spi_response_get(struct mmc_spi_host *host, struct mmc_command *cmd)
{
@@ -486,18 +439,6 @@ mmc_spi_response_get(struct mmc_spi_host
(void) mmc_spi_scanbyte(host, mmc_spi_busy, WRITE_TIMEOUT);
break;
- /* SPI R1D == R1 + 16 bytes data; SEND_CSD, SEND_CID
- * for non-SPI this would be R2 type status
- *
- * FIXME remove the R1D "message type"; mmc core should
- * explicitly issue a data stage, handling CRCs right.
- */
- case MMC_RSP_SPI_R1D:
- mmc_spi_read_cXd(host, cmd);
- dev_dbg(&host->spi->dev, "%s: status %d\n",
- tag, cmd->error);
- return 0;
-
/* SPI R2 == R1 + second status byte; SEND_STATUS */
case MMC_RSP_SPI_R2:
host->response[1] = mmc_spi_readbyte(host);
--- g26.orig/include/linux/mmc/core.h 2007-06-04 19:58:56.000000000 -0700
+++ g26/include/linux/mmc/core.h 2007-06-05 10:05:20.000000000 -0700
@@ -53,19 +53,15 @@ struct mmc_command {
/*
* These are the SPI response types. Commands return R1, with maybe
- * more info. Commands like SEND_CSD return a data block too, which
- * we call 'R1D'. Zero is an invalid type, meaning that the caller
+ * more info. Zero is an invalid type, meaning that the caller
* forgot to say which response type applies to this command.
- *
- * FIXME remove R1D; update SEND_CxD in the core.
*/
#define MMC_RSP_SPI_R1 (MMC_RSP_SPI_S1)
#define MMC_RSP_SPI_R1B (MMC_RSP_SPI_S1|MMC_RSP_BUSY)
#define MMC_RSP_SPI_R2 (MMC_RSP_SPI_S1|MMC_RSP_SPI_S2)
#define MMC_RSP_SPI_R3 (MMC_RSP_SPI_S1|MMC_RSP_SPI_OCR)
-#define MMC_RSP_SPI_R1D (MMC_RSP_SPI_S1|MMC_RSP_136)
-#define mmc_spi_resp_type(cmd) ((cmd)->flags & (MMC_RSP_SPI_S1|MMC_RSP_BUSY|MMC_RSP_SPI_S2|MMC_RSP_SPI_OCR|MMC_RSP_136))
+#define mmc_spi_resp_type(cmd) ((cmd)->flags & (MMC_RSP_SPI_S1|MMC_RSP_BUSY|MMC_RSP_SPI_S2|MMC_RSP_SPI_OCR))
/*
* These are the command types.
--- g26.orig/drivers/mmc/core/mmc.c 2007-06-04 19:58:58.000000000 -0700
+++ g26/drivers/mmc/core/mmc.c 2007-06-05 10:05:20.000000000 -0700
@@ -325,7 +325,7 @@ static int mmc_sd_init_card(struct mmc_h
if (err != MMC_ERR_NONE)
goto free_card;
- if (!oldcard && !mmc_host_is_spi(host)) {
+ if (!oldcard) {
/*
* Fetch and process extended CSD.
*/
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
next prev parent reply other threads:[~2007-06-05 17:13 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-06-05 3:25 [patch 2.6.22-rc4 0/7] latest MMC-over-SPI patchset David Brownell
[not found] ` <200706042025.18252.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2007-06-05 3:26 ` [patch 2.6.22-rc4 1/7] CRC7 support David Brownell
2007-06-05 3:28 ` [patch 2.6.22-rc4 2/7] SD 4wire bugfix David Brownell
2007-06-05 3:31 ` [patch 2.6.22-rc4 3/7] SPI "exclusive access" (experimental) David Brownell
2007-06-05 3:34 ` [patch 2.6.22-rc4 4/7] MMC headers understand SPI David Brownell
2007-06-05 3:37 ` [patch 2.6.22-rc4 5/7] MMC core understands SPI David Brownell
2007-06-05 3:38 ` [patch 2.6.22-rc4 6/7] MMC block " David Brownell
2007-06-05 3:50 ` [patch 2.6.22-rc4 7/7] mmc_spi host driver David Brownell
2007-06-05 17:13 ` David Brownell [this message]
[not found] ` <200706051013.44971.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2007-06-09 20:55 ` [patch 2.6.22-rc4 8/7] mmc_spi cid/csd/ext_csd updates, CRCs on Pierre Ossman
[not found] ` <466B13C5.3050502-p3sGCRWkH8CeZLLa646FqQ@public.gmane.org>
2007-06-10 19:43 ` David Brownell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200706051013.44971.david-b@pacbell.net \
--to=david-b-ybekhbn/0ldr7s880joybq@public.gmane.org \
--cc=drzeus-mmc-p3sGCRWkH8CeZLLa646FqQ@public.gmane.org \
--cc=hans-peter.nilsson-VrBV9hrLPhE@public.gmane.org \
--cc=mikael.starvik-VrBV9hrLPhE@public.gmane.org \
--cc=mike-UTnDXsALFwNjMdQLN6DIHgC/G2K4zDHf@public.gmane.org \
--cc=spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.