svn commit: r188952 - in stable/7/sys: . contrib/pf dev/ath/ath_hal
dev/cxgb dev/mmc
Alexander Motin
mav at FreeBSD.org
Mon Feb 23 11:52:49 PST 2009
Author: mav
Date: Mon Feb 23 19:52:47 2009
New Revision: 188952
URL: http://svn.freebsd.org/changeset/base/188952
Log:
MFC rev. 187525 187543 187546 187551 187875 187877 188044 188725
Sync MMC subsystem with HEAD.
Modified:
stable/7/sys/ (props changed)
stable/7/sys/contrib/pf/ (props changed)
stable/7/sys/dev/ath/ath_hal/ (props changed)
stable/7/sys/dev/cxgb/ (props changed)
stable/7/sys/dev/mmc/mmc.c
stable/7/sys/dev/mmc/mmcreg.h
stable/7/sys/dev/mmc/mmcsd.c
Modified: stable/7/sys/dev/mmc/mmc.c
==============================================================================
--- stable/7/sys/dev/mmc/mmc.c Mon Feb 23 19:31:48 2009 (r188951)
+++ stable/7/sys/dev/mmc/mmc.c Mon Feb 23 19:52:47 2009 (r188952)
@@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/bus.h>
#include <sys/endian.h>
+#include <sys/sysctl.h>
#include <dev/mmc/mmcreg.h>
#include <dev/mmc/mmcbrvar.h>
@@ -104,6 +105,11 @@ struct mmc_ivars {
#define CMD_RETRIES 3
+SYSCTL_NODE(_hw, OID_AUTO, mmc, CTLFLAG_RD, NULL, "mmc driver");
+
+static int mmc_debug;
+SYSCTL_INT(_hw_mmc, OID_AUTO, debug, CTLFLAG_RW, &mmc_debug, 0, "Debug level");
+
/* bus entry points */
static int mmc_probe(device_t dev);
static int mmc_attach(device_t dev);
@@ -233,7 +239,7 @@ mmc_acquire_bus(device_t busdev, device_
sc->last_rca = rca;
/* Prepare bus width for the new card. */
ivar = device_get_ivars(dev);
- if (bootverbose) {
+ if (bootverbose || mmc_debug) {
device_printf(busdev,
"setting bus width to %d bits\n",
(ivar->bus_width == bus_width_4) ? 4 :
@@ -315,11 +321,21 @@ mmc_wait_for_req(struct mmc_softc *sc, s
req->done = mmc_wakeup;
req->done_data = sc;
+ if (mmc_debug > 1) {
+ device_printf(sc->dev, "REQUEST: CMD%d arg %#x flags %#x",
+ req->cmd->opcode, req->cmd->arg, req->cmd->flags);
+ if (req->cmd->data) {
+ printf(" data %d\n", (int)req->cmd->data->len);
+ } else
+ printf("\n");
+ }
MMCBR_REQUEST(device_get_parent(sc->dev), sc->dev, req);
MMC_LOCK(sc);
while ((req->flags & MMC_REQ_DONE) == 0)
msleep(req, &sc->sc_mtx, 0, "mmcreq", 0);
MMC_UNLOCK(sc);
+ if (mmc_debug > 2 || (mmc_debug > 1 && req->cmd->error))
+ device_printf(sc->dev, "RESULT: %d\n", req->cmd->error);
return (0);
}
@@ -340,7 +356,6 @@ mmc_wait_for_cmd(struct mmc_softc *sc, s
memset(cmd->resp, 0, sizeof(cmd->resp));
cmd->retries = retries;
mreq.cmd = cmd;
-/* printf("CMD: %x ARG %x\n", cmd->opcode, cmd->arg); */
mmc_wait_for_req(sc, &mreq);
return (cmd->error);
}
@@ -555,7 +570,8 @@ mmc_switch(struct mmc_softc *sc, uint8_t
}
static int
-mmc_sd_switch(struct mmc_softc *sc, uint8_t mode, uint8_t grp, uint8_t value, uint8_t *res)
+mmc_sd_switch(struct mmc_softc *sc, uint8_t mode, uint8_t grp, uint8_t value,
+ uint8_t *res)
{
int err;
struct mmc_command cmd;
@@ -563,11 +579,11 @@ mmc_sd_switch(struct mmc_softc *sc, uint
memset(&cmd, 0, sizeof(struct mmc_command));
memset(&data, 0, sizeof(struct mmc_data));
-
memset(res, 0, 64);
+
cmd.opcode = SD_SWITCH_FUNC;
cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
- cmd.arg = mode << 31;
+ cmd.arg = mode << 31; /* 0 - check, 1 - set */
cmd.arg |= 0x00FFFFFF;
cmd.arg &= ~(0xF << (grp * 4));
cmd.arg |= value << (grp * 4);
@@ -584,11 +600,11 @@ mmc_sd_switch(struct mmc_softc *sc, uint
static int
mmc_set_card_bus_width(struct mmc_softc *sc, uint16_t rca, int width)
{
+ struct mmc_command cmd;
int err;
+ uint8_t value;
if (mmcbr_get_mode(sc->dev) == mode_sd) {
- struct mmc_command cmd;
-
memset(&cmd, 0, sizeof(struct mmc_command));
cmd.opcode = ACMD_SET_BUS_WIDTH;
cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
@@ -604,8 +620,6 @@ mmc_set_card_bus_width(struct mmc_softc
}
err = mmc_wait_for_app_cmd(sc, rca, &cmd, CMD_RETRIES);
} else {
- uint8_t value;
-
switch (width) {
case bus_width_1:
value = EXT_CSD_BUS_WIDTH_1;
@@ -619,7 +633,8 @@ mmc_set_card_bus_width(struct mmc_softc
default:
return (MMC_ERR_INVALID);
}
- err = mmc_switch(sc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, value);
+ err = mmc_switch(sc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH,
+ value);
}
return (err);
}
@@ -629,6 +644,7 @@ mmc_set_timing(struct mmc_softc *sc, int
{
int err;
uint8_t value;
+ u_char switch_res[64];
switch (timing) {
case bus_timing_normal:
@@ -640,14 +656,12 @@ mmc_set_timing(struct mmc_softc *sc, int
default:
return (MMC_ERR_INVALID);
}
- if (mmcbr_get_mode(sc->dev) == mode_sd) {
- u_char switch_res[64];
-
- err = mmc_sd_switch(sc, 1, 0, value, switch_res);
- } else {
+ if (mmcbr_get_mode(sc->dev) == mode_sd)
+ err = mmc_sd_switch(sc, SD_SWITCH_MODE_SET, SD_SWITCH_GROUP1,
+ value, switch_res);
+ else
err = mmc_switch(sc, EXT_CSD_CMD_SET_NORMAL,
EXT_CSD_HS_TIMING, value);
- }
return (err);
}
@@ -749,9 +763,10 @@ mmc_decode_cid_sd(uint32_t *raw_cid, str
cid->oid = mmc_get_bits(raw_cid, 128, 104, 16);
for (i = 0; i < 5; i++)
cid->pnm[i] = mmc_get_bits(raw_cid, 128, 96 - i * 8, 8);
+ cid->pnm[5] = 0;
cid->prv = mmc_get_bits(raw_cid, 128, 56, 8);
cid->psn = mmc_get_bits(raw_cid, 128, 24, 32);
- cid->mdt_year = mmc_get_bits(raw_cid, 128, 12, 8) + 2001;
+ cid->mdt_year = mmc_get_bits(raw_cid, 128, 12, 8) + 2000;
cid->mdt_month = mmc_get_bits(raw_cid, 128, 8, 4);
}
@@ -766,6 +781,7 @@ mmc_decode_cid_mmc(uint32_t *raw_cid, st
cid->oid = mmc_get_bits(raw_cid, 128, 104, 8);
for (i = 0; i < 6; i++)
cid->pnm[i] = mmc_get_bits(raw_cid, 128, 96 - i * 8, 8);
+ cid->pnm[6] = 0;
cid->prv = mmc_get_bits(raw_cid, 128, 48, 8);
cid->psn = mmc_get_bits(raw_cid, 128, 16, 32);
cid->mdt_month = mmc_get_bits(raw_cid, 128, 12, 4);
@@ -1060,6 +1076,29 @@ mmc_send_relative_addr(struct mmc_softc
}
static void
+mmc_log_card(device_t dev, struct mmc_ivars *ivar, int newcard)
+{
+ device_printf(dev, "Card at relative address %d%s:\n",
+ ivar->rca, newcard ? " added" : "");
+ device_printf(dev, " card: %s%s (0x%x/0x%x/\"%s\" rev %d.%d "
+ "m/d %02d.%04d s/n %08x)\n",
+ ivar->mode == mode_sd ? "SD" : "MMC",
+ ivar->high_cap ? " High Capacity" : "",
+ ivar->cid.mid, ivar->cid.oid,
+ ivar->cid.pnm, ivar->cid.prv >> 4, ivar->cid.prv & 0x0f,
+ ivar->cid.mdt_month, ivar->cid.mdt_year, ivar->cid.psn);
+ device_printf(dev, " bus: %ubit, %uMHz%s\n",
+ (ivar->bus_width == bus_width_1 ? 1 :
+ (ivar->bus_width == bus_width_4 ? 4 : 8)),
+ (ivar->timing == bus_timing_hs ?
+ ivar->hs_tran_speed : ivar->tran_speed) / 1000000,
+ ivar->timing == bus_timing_hs ? ", high speed timing" : "");
+ device_printf(dev, " memory: %u blocks, erase sector %u blocks%s\n",
+ ivar->sec_count, ivar->erase_sector,
+ ivar->read_only ? ", read-only" : "");
+}
+
+static void
mmc_discover_cards(struct mmc_softc *sc)
{
struct mmc_ivars *ivar = NULL;
@@ -1071,6 +1110,8 @@ mmc_discover_cards(struct mmc_softc *sc)
uint16_t rca = 2;
u_char switch_res[64];
+ if (bootverbose || mmc_debug)
+ device_printf(sc->dev, "Probing cards\n");
while (1) {
err = mmc_all_send_cid(sc, raw_cid);
if (err == MMC_ERR_TIMEOUT)
@@ -1090,6 +1131,11 @@ mmc_discover_cards(struct mmc_softc *sc)
}
}
free(devlist, M_TEMP);
+ if (bootverbose || mmc_debug) {
+ device_printf(sc->dev, "%sard detected (CID %08x%08x%08x%08x)\n",
+ newcard ? "New c" : "C",
+ raw_cid[0], raw_cid[1], raw_cid[2], raw_cid[3]);
+ }
if (newcard) {
ivar = malloc(sizeof(struct mmc_ivars), M_DEVBUF,
M_WAITOK | M_ZERO);
@@ -1100,6 +1146,7 @@ mmc_discover_cards(struct mmc_softc *sc)
if (mmcbr_get_ro(sc->dev))
ivar->read_only = 1;
ivar->bus_width = bus_width_1;
+ ivar->timing = bus_timing_normal;
ivar->mode = mmcbr_get_mode(sc->dev);
if (ivar->mode == mode_sd) {
mmc_decode_cid_sd(ivar->raw_cid, &ivar->cid);
@@ -1118,13 +1165,15 @@ mmc_discover_cards(struct mmc_softc *sc)
mmc_select_card(sc, ivar->rca);
mmc_app_send_scr(sc, ivar->rca, ivar->raw_scr);
mmc_app_decode_scr(ivar->raw_scr, &ivar->scr);
- /* Get card switch capabilities. */
+ /* Get card switch capabilities (command class 10). */
if ((ivar->scr.sda_vsn >= 1) &&
(ivar->csd.ccc & (1<<10))) {
- mmc_sd_switch(sc, 0, 0, 0xF, switch_res);
+ mmc_sd_switch(sc, SD_SWITCH_MODE_CHECK,
+ SD_SWITCH_GROUP1, SD_SWITCH_NOCHANGE,
+ switch_res);
if (switch_res[13] & 2) {
ivar->timing = bus_timing_hs;
- ivar->hs_tran_speed = 50000000;
+ ivar->hs_tran_speed = SD_MAX_HS;
}
}
mmc_app_sd_status(sc, ivar->rca, ivar->raw_sd_status);
@@ -1139,6 +1188,8 @@ mmc_discover_cards(struct mmc_softc *sc)
if ((mmcbr_get_caps(sc->dev) & MMC_CAP_4_BIT_DATA) &&
(ivar->scr.bus_widths & SD_SCR_BUS_WIDTH_4))
ivar->bus_width = bus_width_4;
+ if (bootverbose || mmc_debug)
+ mmc_log_card(sc->dev, ivar, newcard);
if (newcard) {
/* Add device. */
child = device_add_child(sc->dev, NULL, -1);
@@ -1174,10 +1225,10 @@ mmc_discover_cards(struct mmc_softc *sc)
ivar->timing = bus_timing_hs;
if (ivar->raw_ext_csd[EXT_CSD_CARD_TYPE]
& EXT_CSD_CARD_TYPE_52)
- ivar->hs_tran_speed = 52000000;
+ ivar->hs_tran_speed = MMC_TYPE_52_MAX_HS;
else if (ivar->raw_ext_csd[EXT_CSD_CARD_TYPE]
& EXT_CSD_CARD_TYPE_26)
- ivar->hs_tran_speed = 26000000;
+ ivar->hs_tran_speed = MMC_TYPE_26_MAX_HS;
else
ivar->hs_tran_speed = ivar->tran_speed;
/* Find max supported bus width. */
@@ -1194,6 +1245,8 @@ mmc_discover_cards(struct mmc_softc *sc)
ivar->bus_width = bus_width_1;
ivar->timing = bus_timing_normal;
}
+ if (bootverbose || mmc_debug)
+ mmc_log_card(sc->dev, ivar, newcard);
if (newcard) {
/* Add device. */
child = device_add_child(sc->dev, NULL, -1);
@@ -1214,6 +1267,9 @@ mmc_rescan_cards(struct mmc_softc *sc)
for (i = 0; i < devcount; i++) {
ivar = device_get_ivars(devlist[i]);
if (mmc_select_card(sc, ivar->rca)) {
+ if (bootverbose || mmc_debug)
+ device_printf(sc->dev, "Card at relative address %d lost.\n",
+ ivar->rca);
device_delete_child(sc->dev, devlist[i]);
free(ivar, M_DEVBUF);
}
@@ -1233,6 +1289,9 @@ mmc_delete_cards(struct mmc_softc *sc)
return (err);
for (i = 0; i < devcount; i++) {
ivar = device_get_ivars(devlist[i]);
+ if (bootverbose || mmc_debug)
+ device_printf(sc->dev, "Card at relative address %d deleted.\n",
+ ivar->rca);
device_delete_child(sc->dev, devlist[i]);
free(ivar, M_DEVBUF);
}
@@ -1255,17 +1314,30 @@ mmc_go_discovery(struct mmc_softc *sc)
mmcbr_set_mode(dev, mode_sd);
mmc_power_up(sc);
mmcbr_set_bus_mode(dev, pushpull);
+ if (bootverbose || mmc_debug)
+ device_printf(sc->dev, "Probing bus\n");
mmc_idle_cards(sc);
err = mmc_send_if_cond(sc, 1);
+ if ((bootverbose || mmc_debug) && err == 0)
+ device_printf(sc->dev, "SD 2.0 interface conditions: OK\n");
if (mmc_send_app_op_cond(sc, err ? 0 : MMC_OCR_CCS, &ocr) !=
MMC_ERR_NONE) {
+ if (bootverbose || mmc_debug)
+ device_printf(sc->dev, "SD probe: failed\n");
/*
* Failed, try MMC
*/
mmcbr_set_mode(dev, mode_mmc);
- if (mmc_send_op_cond(sc, 0, &ocr) != MMC_ERR_NONE)
+ if (mmc_send_op_cond(sc, 0, &ocr) != MMC_ERR_NONE) {
+ if (bootverbose || mmc_debug)
+ device_printf(sc->dev, "MMC probe: failed\n");
ocr = 0; /* Failed both, powerdown. */
- }
+ } else if (bootverbose || mmc_debug)
+ device_printf(sc->dev,
+ "MMC probe: OK (OCR: 0x%08x)\n", ocr);
+ } else if (bootverbose || mmc_debug)
+ device_printf(sc->dev, "SD probe: OK (OCR: 0x%08x)\n", ocr);
+
mmcbr_set_ocr(dev, mmc_select_vdd(sc, ocr));
if (mmcbr_get_ocr(dev) != 0)
mmc_idle_cards(sc);
@@ -1279,6 +1351,8 @@ mmc_go_discovery(struct mmc_softc *sc)
* Make sure that we have a mutually agreeable voltage to at least
* one card on the bus.
*/
+ if (bootverbose || mmc_debug)
+ device_printf(sc->dev, "Current OCR: 0x%08x\n", mmcbr_get_ocr(dev));
if (mmcbr_get_ocr(dev) == 0) {
mmc_delete_cards(sc);
mmc_power_down(sc);
@@ -1326,7 +1400,7 @@ mmc_calculate_clock(struct mmc_softc *sc
max_timing = ivar->timing;
if (ivar->tran_speed < max_dtr)
max_dtr = ivar->tran_speed;
- if (ivar->hs_tran_speed < max_dtr)
+ if (ivar->hs_tran_speed < max_hs_dtr)
max_hs_dtr = ivar->hs_tran_speed;
}
for (i = 0; i < nkid; i++) {
@@ -1340,7 +1414,7 @@ mmc_calculate_clock(struct mmc_softc *sc
free(kids, M_TEMP);
if (max_timing == bus_timing_hs)
max_dtr = max_hs_dtr;
- if (bootverbose) {
+ if (bootverbose || mmc_debug) {
device_printf(sc->dev,
"setting transfer rate to %d.%03dMHz%s\n",
max_dtr / 1000000, (max_dtr / 1000) % 1000,
@@ -1454,5 +1528,5 @@ static driver_t mmc_driver = {
static devclass_t mmc_devclass;
-DRIVER_MODULE(mmc, at91_mci, mmc_driver, mmc_devclass, 0, 0);
-DRIVER_MODULE(mmc, sdhci, mmc_driver, mmc_devclass, 0, 0);
+DRIVER_MODULE(mmc, at91_mci, mmc_driver, mmc_devclass, NULL, NULL);
+DRIVER_MODULE(mmc, sdhci, mmc_driver, mmc_devclass, NULL, NULL);
Modified: stable/7/sys/dev/mmc/mmcreg.h
==============================================================================
--- stable/7/sys/dev/mmc/mmcreg.h Mon Feb 23 19:31:48 2009 (r188951)
+++ stable/7/sys/dev/mmc/mmcreg.h Mon Feb 23 19:52:47 2009 (r188952)
@@ -97,6 +97,7 @@ struct mmc_command {
#define MMC_ERR_FAILED 4
#define MMC_ERR_INVALID 5
#define MMC_ERR_NO_MEMORY 6
+#define MMC_ERR_MAX 6
struct mmc_data *data; /* Data segment with cmd */
struct mmc_request *mrq; /* backpointer to request */
};
@@ -287,7 +288,6 @@ struct mmc_request {
/*
* EXT_CSD fields
*/
-
#define EXT_CSD_ERASE_GRP_DEF 175 /* R/W */
#define EXT_CSD_BUS_WIDTH 183 /* R/W */
#define EXT_CSD_HS_TIMING 185 /* R/W */
@@ -300,7 +300,6 @@ struct mmc_request {
/*
* EXT_CSD field definitions
*/
-
#define EXT_CSD_CMD_SET_NORMAL 1
#define EXT_CSD_CMD_SET_SECURE 2
#define EXT_CSD_CMD_SET_CPSECURE 4
@@ -312,12 +311,27 @@ struct mmc_request {
#define EXT_CSD_BUS_WIDTH_4 1
#define EXT_CSD_BUS_WIDTH_8 2
+#define MMC_TYPE_26_MAX_HS 26000000
+#define MMC_TYPE_52_MAX_HS 52000000
+
/*
* SD bus widths
*/
#define SD_BUS_WIDTH_1 0
#define SD_BUS_WIDTH_4 2
+/*
+ * SD Switch
+ */
+#define SD_SWITCH_MODE_CHECK 0
+#define SD_SWITCH_MODE_SET 1
+#define SD_SWITCH_GROUP1 0
+#define SD_SWITCH_NORMAL_MODE 0
+#define SD_SWITCH_HS_MODE 1
+#define SD_SWITCH_NOCHANGE 0xF
+
+#define SD_MAX_HS 50000000
+
/* OCR bits */
/*
Modified: stable/7/sys/dev/mmc/mmcsd.c
==============================================================================
--- stable/7/sys/dev/mmc/mmcsd.c Mon Feb 23 19:31:48 2009 (r188951)
+++ stable/7/sys/dev/mmc/mmcsd.c Mon Feb 23 19:52:47 2009 (r188952)
@@ -91,6 +91,8 @@ static int mmcsd_detach(device_t dev);
static int mmcsd_open(struct disk *dp);
static int mmcsd_close(struct disk *dp);
static void mmcsd_strategy(struct bio *bp);
+static int mmcsd_dump(void *arg, void *virtual, vm_offset_t physical,
+ off_t offset, size_t length);
static void mmcsd_task(void *arg);
static const char *mmcsd_card_name(device_t dev);
@@ -130,7 +132,7 @@ mmcsd_attach(device_t dev)
d->d_open = mmcsd_open;
d->d_close = mmcsd_close;
d->d_strategy = mmcsd_strategy;
- // d->d_dump = mmcsd_dump; Need polling mmc layer
+ d->d_dump = mmcsd_dump;
d->d_name = "mmcsd";
d->d_drv1 = sc;
d->d_maxsize = 4*1024*1024; /* Maximum defined SD card AU size. */
@@ -415,6 +417,33 @@ mmcsd_delete(struct mmcsd_softc *sc, str
return (end);
}
+static int
+mmcsd_dump(void *arg, void *virtual, vm_offset_t physical,
+ off_t offset, size_t length)
+{
+ struct disk *disk = arg;
+ struct mmcsd_softc *sc = (struct mmcsd_softc *)disk->d_drv1;
+ device_t dev = sc->dev;
+ struct bio bp;
+ daddr_t block, end;
+
+ /* length zero is special and really means flush buffers to media */
+ if (!length)
+ return (0);
+
+ bzero(&bp, sizeof(struct bio));
+ bp.bio_disk = disk;
+ bp.bio_pblkno = offset / disk->d_sectorsize;
+ bp.bio_bcount = length;
+ bp.bio_data = virtual;
+ bp.bio_cmd = BIO_WRITE;
+ end = bp.bio_pblkno + bp.bio_bcount / sc->disk->d_sectorsize;
+ MMCBUS_ACQUIRE_BUS(device_get_parent(dev), dev);
+ block = mmcsd_rw(sc, &bp);
+ MMCBUS_RELEASE_BUS(device_get_parent(dev), dev);
+ return ((end < block) ? EIO : 0);
+}
+
static void
mmcsd_task(void *arg)
{
More information about the svn-src-stable-7
mailing list