Improve mmc driver verbose logging.

Make requests logging controllable by hw.mmc.debug sysctl.
This commit is contained in:
Alexander Motin 2009-01-28 22:09:00 +00:00
parent de43ac6044
commit ed01be88f7

View File

@ -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, 0, "mmc driver");
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_t dev)
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, struct mmc_request *req)
req->done = mmc_wakeup;
req->done_data = sc;
if (mmc_debug) {
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 > 1 || (mmc_debug && req->cmd->error))
device_printf(sc->dev, "RESULT: %d\n", req->cmd->error);
return (0);
}
@ -340,9 +356,6 @@ mmc_wait_for_cmd(struct mmc_softc *sc, struct mmc_command *cmd, int retries)
memset(cmd->resp, 0, sizeof(cmd->resp));
cmd->retries = retries;
mreq.cmd = cmd;
if (bootverbose)
device_printf(sc->dev, "CMD: %#x ARG %#x\n", cmd->opcode,
cmd->arg);
mmc_wait_for_req(sc, &mreq);
return (cmd->error);
}
@ -748,9 +761,10 @@ mmc_decode_cid_sd(uint32_t *raw_cid, struct mmc_cid *cid)
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);
}
@ -765,6 +779,7 @@ mmc_decode_cid_mmc(uint32_t *raw_cid, struct mmc_cid *cid)
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);
@ -1058,6 +1073,29 @@ mmc_send_relative_addr(struct mmc_softc *sc, uint32_t *resp)
return (err);
}
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)
{
@ -1070,6 +1108,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)
@ -1089,6 +1129,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);
@ -1139,6 +1184,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);
@ -1194,6 +1241,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 +1263,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 +1285,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,21 +1310,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)
device_printf(sc->dev, "Idle cards for SD probe\n");
if (bootverbose || mmc_debug)
device_printf(sc->dev, "Probing bus\n");
mmc_idle_cards(sc);
err = mmc_send_if_cond(sc, 1);
if (bootverbose)
device_printf(sc->dev, "SD: SEND_IF_CONF %d\n", err);
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);
@ -1283,6 +1347,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);
@ -1344,7 +1410,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,