1 /*- 2 * Copyright (c) 2006 Bernd Walter. All rights reserved. 3 * Copyright (c) 2006 M. Warner Losh <imp@FreeBSD.org> 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 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * 25 * Portions of this software may have been developed with reference to 26 * the SD Simplified Specification. The following disclaimer may apply: 27 * 28 * The following conditions apply to the release of the simplified 29 * specification ("Simplified Specification") by the SD Card Association and 30 * the SD Group. The Simplified Specification is a subset of the complete SD 31 * Specification which is owned by the SD Card Association and the SD 32 * Group. This Simplified Specification is provided on a non-confidential 33 * basis subject to the disclaimers below. Any implementation of the 34 * Simplified Specification may require a license from the SD Card 35 * Association, SD Group, SD-3C LLC or other third parties. 36 * 37 * Disclaimers: 38 * 39 * The information contained in the Simplified Specification is presented only 40 * as a standard specification for SD Cards and SD Host/Ancillary products and 41 * is provided "AS-IS" without any representations or warranties of any 42 * kind. No responsibility is assumed by the SD Group, SD-3C LLC or the SD 43 * Card Association for any damages, any infringements of patents or other 44 * right of the SD Group, SD-3C LLC, the SD Card Association or any third 45 * parties, which may result from its use. No license is granted by 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/param.h> 54 #include <sys/systm.h> 55 #include <sys/kernel.h> 56 #include <sys/lock.h> 57 #include <sys/mutex.h> 58 #include <sys/time.h> 59 60 #include <dev/mmc/bridge.h> 61 #include <dev/mmc/mmc_private.h> 62 #include <dev/mmc/mmc_subr.h> 63 #include <dev/mmc/mmcreg.h> 64 #include <dev/mmc/mmcbrvar.h> 65 66 #include "mmcbus_if.h" 67 68 #define CMD_RETRIES 3 69 #define LOG_PPS 5 /* Log no more than 5 errors per second. */ 70 71 int 72 mmc_wait_for_cmd(device_t busdev, device_t dev, struct mmc_command *cmd, 73 int retries) 74 { 75 struct mmc_request mreq; 76 struct mmc_softc *sc; 77 int err; 78 79 do { 80 memset(&mreq, 0, sizeof(mreq)); 81 memset(cmd->resp, 0, sizeof(cmd->resp)); 82 cmd->retries = 0; /* Retries done here, not in hardware. */ 83 cmd->mrq = &mreq; 84 if (cmd->data != NULL) 85 cmd->data->mrq = &mreq; 86 mreq.cmd = cmd; 87 if (MMCBUS_WAIT_FOR_REQUEST(busdev, dev, &mreq) != 0) 88 err = MMC_ERR_FAILED; 89 else 90 err = cmd->error; 91 } while (err != MMC_ERR_NONE && retries-- > 0); 92 93 if (err != MMC_ERR_NONE && busdev == dev) { 94 sc = device_get_softc(busdev); 95 if (sc->squelched == 0 && ppsratecheck(&sc->log_time, 96 &sc->log_count, LOG_PPS)) { 97 device_printf(sc->dev, "CMD%d failed, RESULT: %d\n", 98 cmd->opcode, err); 99 } 100 } 101 102 return (err); 103 } 104 105 int 106 mmc_wait_for_app_cmd(device_t busdev, device_t dev, uint16_t rca, 107 struct mmc_command *cmd, int retries) 108 { 109 struct mmc_command appcmd; 110 struct mmc_softc *sc; 111 int err; 112 113 sc = device_get_softc(busdev); 114 115 /* Squelch error reporting at lower levels, we report below. */ 116 sc->squelched++; 117 do { 118 memset(&appcmd, 0, sizeof(appcmd)); 119 appcmd.opcode = MMC_APP_CMD; 120 appcmd.arg = (uint32_t)rca << 16; 121 appcmd.flags = MMC_RSP_R1 | MMC_CMD_AC; 122 if (mmc_wait_for_cmd(busdev, dev, &appcmd, 0) != 0) 123 err = MMC_ERR_FAILED; 124 else 125 err = appcmd.error; 126 if (err == MMC_ERR_NONE) { 127 if (!(appcmd.resp[0] & R1_APP_CMD)) 128 err = MMC_ERR_FAILED; 129 else if (mmc_wait_for_cmd(busdev, dev, cmd, 0) != 0) 130 err = MMC_ERR_FAILED; 131 else 132 err = cmd->error; 133 } 134 } while (err != MMC_ERR_NONE && retries-- > 0); 135 sc->squelched--; 136 137 if (err != MMC_ERR_NONE && busdev == dev) { 138 if (sc->squelched == 0 && ppsratecheck(&sc->log_time, 139 &sc->log_count, LOG_PPS)) { 140 device_printf(sc->dev, "ACMD%d failed, RESULT: %d\n", 141 cmd->opcode, err); 142 } 143 } 144 145 return (err); 146 } 147 148 int 149 mmc_switch(device_t busdev, device_t dev, uint16_t rca, uint8_t set, 150 uint8_t index, uint8_t value, u_int timeout, bool status) 151 { 152 struct mmc_command cmd; 153 struct mmc_softc *sc; 154 int err; 155 156 KASSERT(timeout != 0, ("%s: no timeout", __func__)); 157 158 sc = device_get_softc(busdev); 159 160 memset(&cmd, 0, sizeof(cmd)); 161 cmd.opcode = MMC_SWITCH_FUNC; 162 cmd.arg = (MMC_SWITCH_FUNC_WR << 24) | (index << 16) | (value << 8) | 163 set; 164 /* 165 * If the hardware supports busy detection but the switch timeout 166 * exceeds the maximum host timeout, use a R1 instead of a R1B 167 * response in order to keep the hardware from timing out. 168 */ 169 if (mmcbr_get_caps(busdev) & MMC_CAP_WAIT_WHILE_BUSY && 170 timeout > mmcbr_get_max_busy_timeout(busdev)) 171 cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; 172 else 173 cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; 174 /* 175 * Pause re-tuning so it won't interfere with the busy state and also 176 * so that the result of CMD13 will always refer to switching rather 177 * than to a tuning command that may have snuck in between. 178 */ 179 sc->retune_paused++; 180 err = mmc_wait_for_cmd(busdev, dev, &cmd, CMD_RETRIES); 181 if (err != MMC_ERR_NONE || status == false) 182 goto out; 183 err = mmc_switch_status(busdev, dev, rca, timeout); 184 out: 185 sc->retune_paused--; 186 return (err); 187 } 188 189 int 190 mmc_switch_status(device_t busdev, device_t dev, uint16_t rca, u_int timeout) 191 { 192 struct timeval cur, end; 193 int err, crc_timeout; 194 uint32_t status; 195 196 KASSERT(timeout != 0, ("%s: no timeout", __func__)); 197 198 /* 199 * Note that when using a R1B response in mmc_switch(), bridges of 200 * type MMC_CAP_WAIT_WHILE_BUSY will issue mmc_send_status() only 201 * once and then exit the loop. 202 */ 203 end.tv_sec = end.tv_usec = 0; 204 for (;;) { 205 crc_timeout=0; 206 do { 207 /* 208 * CRC errors indicate that the command wasn't accepted 209 * and executed due to a communications error. Retry 210 * CRC errors a couple of times to cope with transient 211 * failures. 212 * 213 * This is required for some cheap laptops to boot. 214 */ 215 err = mmc_send_status(busdev, dev, rca, &status); 216 crc_timeout++; 217 } while (err == MMC_ERR_BADCRC && crc_timeout < 10); 218 if (err != MMC_ERR_NONE) 219 break; 220 if (R1_CURRENT_STATE(status) == R1_STATE_TRAN) 221 break; 222 getmicrouptime(&cur); 223 if (end.tv_sec == 0 && end.tv_usec == 0) { 224 end.tv_usec = timeout; 225 timevaladd(&end, &cur); 226 } 227 if (timevalcmp(&cur, &end, >)) { 228 err = MMC_ERR_TIMEOUT; 229 break; 230 } 231 } 232 if (err == MMC_ERR_NONE && (status & R1_SWITCH_ERROR) != 0) 233 return (MMC_ERR_FAILED); 234 return (err); 235 } 236 237 int 238 mmc_send_ext_csd(device_t busdev, device_t dev, uint8_t *rawextcsd) 239 { 240 struct mmc_command cmd; 241 struct mmc_data data; 242 int err; 243 244 memset(&cmd, 0, sizeof(cmd)); 245 memset(&data, 0, sizeof(data)); 246 247 memset(rawextcsd, 0, MMC_EXTCSD_SIZE); 248 cmd.opcode = MMC_SEND_EXT_CSD; 249 cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; 250 cmd.data = &data; 251 252 data.data = rawextcsd; 253 data.len = MMC_EXTCSD_SIZE; 254 data.flags = MMC_DATA_READ; 255 256 err = mmc_wait_for_cmd(busdev, dev, &cmd, CMD_RETRIES); 257 return (err); 258 } 259 260 int 261 mmc_send_status(device_t busdev, device_t dev, uint16_t rca, uint32_t *status) 262 { 263 struct mmc_command cmd; 264 int err; 265 266 memset(&cmd, 0, sizeof(cmd)); 267 cmd.opcode = MMC_SEND_STATUS; 268 cmd.arg = (uint32_t)rca << 16; 269 cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; 270 err = mmc_wait_for_cmd(busdev, dev, &cmd, CMD_RETRIES); 271 *status = cmd.resp[0]; 272 return (err); 273 } 274