Deleted Added
sdiff udiff text old ( 184452 ) new ( 185721 )
full compact
1/*-
2 * Copyright (c) 2006 Bernd Walter. All rights reserved.
3 * Copyright (c) 2006 M. Warner Losh. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 37 unchanged lines hidden (view full) ---

46 * implication, estoppel or otherwise under any patent or other rights of the
47 * SD Group, SD-3C LLC, the SD Card Association or any third party. Nothing
48 * herein shall be construed as an obligation by the SD Group, the SD-3C LLC
49 * or the SD Card Association to disclose or distribute any technical
50 * information, know-how or other confidential information to any third party.
51 */
52
53#include <sys/cdefs.h>
54__FBSDID("$FreeBSD: head/sys/dev/mmc/mmc.c 184452 2008-10-29 20:01:26Z mav $");
55
56#include <sys/param.h>
57#include <sys/systm.h>
58#include <sys/kernel.h>
59#include <sys/malloc.h>
60#include <sys/lock.h>
61#include <sys/module.h>
62#include <sys/mutex.h>

--- 40 unchanged lines hidden (view full) ---

103};
104
105#define CMD_RETRIES 3
106
107/* bus entry points */
108static int mmc_probe(device_t dev);
109static int mmc_attach(device_t dev);
110static int mmc_detach(device_t dev);
111
112#define MMC_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
113#define MMC_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
114#define MMC_LOCK_INIT(_sc) \
115 mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev), \
116 "mmc", MTX_DEF)
117#define MMC_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx);
118#define MMC_ASSERT_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED);

--- 6 unchanged lines hidden (view full) ---

125 int retries);
126static int mmc_wait_for_command(struct mmc_softc *sc, uint32_t opcode,
127 uint32_t arg, uint32_t flags, uint32_t *resp, int retries);
128static int mmc_select_card(struct mmc_softc *sc, uint16_t rca);
129static int mmc_set_card_bus_width(struct mmc_softc *sc, uint16_t rca, int width);
130static int mmc_app_send_scr(struct mmc_softc *sc, uint16_t rca, uint32_t *rawscr);
131static void mmc_app_decode_scr(uint32_t *raw_scr, struct mmc_scr *scr);
132static int mmc_send_ext_csd(struct mmc_softc *sc, uint8_t *rawextcsd);
133
134static void
135mmc_ms_delay(int ms)
136{
137 DELAY(1000 * ms); /* XXX BAD */
138}
139
140static int

--- 20 unchanged lines hidden (view full) ---

161 device_printf(dev, "config_intrhook_establish failed\n");
162 return (0);
163}
164
165static int
166mmc_detach(device_t dev)
167{
168 struct mmc_softc *sc = device_get_softc(dev);
169 device_t *kids;
170 int i, nkid;
171
172 /* kill children [ph33r]. -sorbo */
173 if (device_get_children(sc->dev, &kids, &nkid) != 0)
174 return (0);
175 for (i = 0; i < nkid; i++) {
176 device_t kid = kids[i];
177 void *ivar = device_get_ivars(kid);
178
179 device_detach(kid);
180 device_delete_child(sc->dev, kid);
181 free(ivar, M_DEVBUF);
182 }
183 free(kids, M_TEMP);
184 mmc_power_down(sc);
185
186 MMC_LOCK_DESTROY(sc);
187
188 return (0);
189}
190
191static int
192mmc_acquire_bus(device_t busdev, device_t dev)
193{
194 struct mmc_softc *sc;
195 struct mmc_ivars *ivar;
196 int err;
197 int rca;
198
199 err = MMCBR_ACQUIRE_HOST(device_get_parent(busdev), busdev);

--- 60 unchanged lines hidden (view full) ---

260 if (err)
261 return (err);
262 MMC_LOCK(sc);
263 sc->owner = NULL;
264 MMC_UNLOCK(sc);
265 return (0);
266}
267
268static void
269mmc_rescan_cards(struct mmc_softc *sc)
270{
271 /* XXX: Look at the children and see if they respond to status */
272}
273
274static uint32_t
275mmc_select_vdd(struct mmc_softc *sc, uint32_t ocr)
276{
277
278 return (ocr & MMC_OCR_VOLTAGE);
279}
280
281static int

--- 7 unchanged lines hidden (view full) ---

289 return (-1);
290}
291
292static void
293mmc_wakeup(struct mmc_request *req)
294{
295 struct mmc_softc *sc;
296
297/* printf("Wakeup for req %p done_data %p\n", req, req->done_data); */
298 sc = (struct mmc_softc *)req->done_data;
299 MMC_LOCK(sc);
300 req->flags |= MMC_REQ_DONE;
301 wakeup(req);
302 MMC_UNLOCK(sc);
303}
304
305static int
306mmc_wait_for_req(struct mmc_softc *sc, struct mmc_request *req)
307{
308 int err;
309
310 req->done = mmc_wakeup;
311 req->done_data = sc;
312/* printf("Submitting request %p sc %p\n", req, sc); */
313 MMCBR_REQUEST(device_get_parent(sc->dev), sc->dev, req);
314 MMC_LOCK(sc);
315 do {
316 err = msleep(req, &sc->sc_mtx, PZERO | PCATCH, "mmcreq",
317 hz / 10);
318 } while (!(req->flags & MMC_REQ_DONE) && err == EAGAIN);
319/* printf("Request %p done with error %d\n", req, err); */
320 MMC_UNLOCK(sc);
321 return (err);
322}
323
324static int
325mmc_wait_for_request(device_t brdev, device_t reqdev, struct mmc_request *req)
326{
327 struct mmc_softc *sc = device_get_softc(brdev);
328
329 return (mmc_wait_for_req(sc, req));

--- 725 unchanged lines hidden (view full) ---

1055 err = mmc_wait_for_cmd(sc, &cmd, 0);
1056 *resp = cmd.resp[0];
1057 return (err);
1058}
1059
1060static void
1061mmc_discover_cards(struct mmc_softc *sc)
1062{
1063 struct mmc_ivars *ivar;
1064 int err;
1065 uint32_t resp, sec_count;
1066 device_t child;
1067 uint16_t rca = 2;
1068 u_char switch_res[64];
1069
1070 while (1) {
1071 ivar = malloc(sizeof(struct mmc_ivars), M_DEVBUF,
1072 M_WAITOK | M_ZERO);
1073 if (!ivar)
1074 return;
1075 err = mmc_all_send_cid(sc, ivar->raw_cid);
1076 if (err == MMC_ERR_TIMEOUT)
1077 break;
1078 if (err != MMC_ERR_NONE) {
1079 device_printf(sc->dev, "Error reading CID %d\n", err);
1080 break;
1081 }
1082 if (mmcbr_get_ro(sc->dev))
1083 ivar->read_only = 1;
1084 ivar->bus_width = bus_width_1;
1085 ivar->mode = mmcbr_get_mode(sc->dev);
1086 if (ivar->mode == mode_sd) {
1087 mmc_decode_cid_sd(ivar->raw_cid, &ivar->cid);
1088 mmc_send_relative_addr(sc, &resp);
1089 ivar->rca = resp >> 16;

--- 26 unchanged lines hidden (view full) ---

1116 ivar->erase_sector =
1117 16 << ivar->sd_status.au_size;
1118 }
1119 mmc_select_card(sc, 0);
1120 /* Find max supported bus width. */
1121 if ((mmcbr_get_caps(sc->dev) & MMC_CAP_4_BIT_DATA) &&
1122 (ivar->scr.bus_widths & SD_SCR_BUS_WIDTH_4))
1123 ivar->bus_width = bus_width_4;
1124 /* Add device. */
1125 child = device_add_child(sc->dev, NULL, -1);
1126 device_set_ivars(child, ivar);
1127 return;
1128 }
1129 mmc_decode_cid_mmc(ivar->raw_cid, &ivar->cid);
1130 ivar->rca = rca++;
1131 mmc_set_relative_addr(sc, ivar->rca);
1132 /* Get card CSD. */
1133 mmc_send_csd(sc, ivar->rca, ivar->raw_csd);
1134 mmc_decode_csd_mmc(ivar->raw_csd, &ivar->csd);

--- 34 unchanged lines hidden (view full) ---

1169 ivar->raw_ext_csd[EXT_CSD_ERASE_GRP_SIZE];
1170 mmc_switch(sc, EXT_CSD_CMD_SET_NORMAL,
1171 EXT_CSD_ERASE_GRP_DEF, 1);
1172 }
1173 } else {
1174 ivar->bus_width = bus_width_1;
1175 ivar->timing = bus_timing_normal;
1176 }
1177 /* Add device. */
1178 child = device_add_child(sc->dev, NULL, -1);
1179 device_set_ivars(child, ivar);
1180 }
1181 free(ivar, M_DEVBUF);
1182}
1183
1184static void
1185mmc_go_discovery(struct mmc_softc *sc)
1186{
1187 uint32_t ocr;
1188 device_t dev;
1189 int err;
1190
1191 dev = sc->dev;
1192 if (mmcbr_get_power_mode(dev) != power_on) {

--- 7 unchanged lines hidden (view full) ---

1200 err = mmc_send_if_cond(sc, 1);
1201 if (mmc_send_app_op_cond(sc, err ? 0 : MMC_OCR_CCS, &ocr) !=
1202 MMC_ERR_NONE) {
1203 /*
1204 * Failed, try MMC
1205 */
1206 mmcbr_set_mode(dev, mode_mmc);
1207 if (mmc_send_op_cond(sc, 0, &ocr) != MMC_ERR_NONE)
1208 return; /* Failed both, punt! XXX powerdown? */
1209 }
1210 mmcbr_set_ocr(dev, mmc_select_vdd(sc, ocr));
1211 if (mmcbr_get_ocr(dev) != 0)
1212 mmc_idle_cards(sc);
1213 } else {
1214 mmcbr_set_bus_mode(dev, opendrain);
1215 mmcbr_set_clock(dev, mmcbr_get_f_min(dev));
1216 mmcbr_update_ios(dev);
1217 /* XXX recompute vdd based on new cards? */
1218 }
1219 /*
1220 * Make sure that we have a mutually agreeable voltage to at least
1221 * one card on the bus.
1222 */
1223 if (mmcbr_get_ocr(dev) == 0)
1224 return;
1225 /*
1226 * Reselect the cards after we've idled them above.
1227 */
1228 if (mmcbr_get_mode(dev) == mode_sd) {
1229 err = mmc_send_if_cond(sc, 1);
1230 mmc_send_app_op_cond(sc,
1231 (err ? 0 : MMC_OCR_CCS) | mmcbr_get_ocr(dev), NULL);
1232 } else
1233 mmc_send_op_cond(sc, mmcbr_get_ocr(dev), NULL);
1234 mmc_discover_cards(sc);
1235
1236 mmcbr_set_bus_mode(dev, pushpull);
1237 mmcbr_update_ios(dev);
1238 mmc_calculate_clock(sc);
1239 bus_generic_attach(dev);
1240/* mmc_update_children_sysctl(dev);*/
1241}
1242

--- 44 unchanged lines hidden (view full) ---

1287 mmcbr_set_clock(sc->dev, max_dtr);
1288 mmcbr_update_ios(sc->dev);
1289 return max_dtr;
1290}
1291
1292static void
1293mmc_scan(struct mmc_softc *sc)
1294{
1295 device_t dev;
1296
1297 dev = sc->dev;
1298 mmc_acquire_bus(dev, dev);
1299
1300 if (mmcbr_get_power_mode(dev) == power_on)
1301 mmc_rescan_cards(sc);
1302 mmc_go_discovery(sc);
1303
1304 mmc_release_bus(dev, dev);
1305 /* XXX probe/attach/detach children? */
1306}
1307
1308static int
1309mmc_read_ivar(device_t bus, device_t child, int which, u_char *result)
1310{
1311 struct mmc_ivars *ivar = device_get_ivars(child);
1312
1313 switch (which) {

--- 55 unchanged lines hidden (view full) ---

1369 config_intrhook_disestablish(&sc->config_intrhook);
1370}
1371
1372static device_method_t mmc_methods[] = {
1373 /* device_if */
1374 DEVMETHOD(device_probe, mmc_probe),
1375 DEVMETHOD(device_attach, mmc_attach),
1376 DEVMETHOD(device_detach, mmc_detach),
1377
1378 /* Bus interface */
1379 DEVMETHOD(bus_read_ivar, mmc_read_ivar),
1380 DEVMETHOD(bus_write_ivar, mmc_write_ivar),
1381
1382 /* MMC Bus interface */
1383 DEVMETHOD(mmcbus_wait_for_request, mmc_wait_for_request),
1384 DEVMETHOD(mmcbus_acquire_bus, mmc_acquire_bus),

--- 15 unchanged lines hidden ---