1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * linux/drivers/mmc/sdio_ops.c 4 * 5 * Copyright 2006-2007 Pierre Ossman 6 */ 7 8 #include <linux/scatterlist.h> 9 10 #include <linux/mmc/host.h> 11 #include <linux/mmc/card.h> 12 #include <linux/mmc/mmc.h> 13 #include <linux/mmc/sdio.h> 14 15 #include "core.h" 16 #include "sdio_ops.h" 17 18 int mmc_send_io_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) 19 { 20 struct mmc_command cmd = {}; 21 int i, err = 0; 22 23 cmd.opcode = SD_IO_SEND_OP_COND; 24 cmd.arg = ocr; 25 cmd.flags = MMC_RSP_SPI_R4 | MMC_RSP_R4 | MMC_CMD_BCR; 26 27 for (i = 100; i; i--) { 28 err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); 29 if (err) 30 break; 31 32 /* if we're just probing, do a single pass */ 33 if (ocr == 0) 34 break; 35 36 /* otherwise wait until reset completes */ 37 if (mmc_host_is_spi(host)) { 38 /* 39 * Both R1_SPI_IDLE and MMC_CARD_BUSY indicate 40 * an initialized card under SPI, but some cards 41 * (Marvell's) only behave when looking at this 42 * one. 43 */ 44 if (cmd.resp[1] & MMC_CARD_BUSY) 45 break; 46 } else { 47 if (cmd.resp[0] & MMC_CARD_BUSY) 48 break; 49 } 50 51 err = -ETIMEDOUT; 52 53 mmc_delay(10); 54 } 55 56 if (rocr) 57 *rocr = cmd.resp[mmc_host_is_spi(host) ? 1 : 0]; 58 59 return err; 60 } 61 62 static int mmc_io_rw_direct_host(struct mmc_host *host, int write, unsigned fn, 63 unsigned addr, u8 in, u8 *out) 64 { 65 struct mmc_command cmd = {}; 66 int err; 67 68 if (fn > 7) 69 return -EINVAL; 70 71 /* sanity check */ 72 if (addr & ~0x1FFFF) 73 return -EINVAL; 74 75 cmd.opcode = SD_IO_RW_DIRECT; 76 cmd.arg = write ? 0x80000000 : 0x00000000; 77 cmd.arg |= fn << 28; 78 cmd.arg |= (write && out) ? 0x08000000 : 0x00000000; 79 cmd.arg |= addr << 9; 80 cmd.arg |= in; 81 cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_AC; 82 83 err = mmc_wait_for_cmd(host, &cmd, 0); 84 if (err) 85 return err; 86 87 if (mmc_host_is_spi(host)) { 88 /* host driver already reported errors */ 89 } else { 90 if (cmd.resp[0] & R5_ERROR) 91 return -EIO; 92 if (cmd.resp[0] & R5_FUNCTION_NUMBER) 93 return -EINVAL; 94 if (cmd.resp[0] & R5_OUT_OF_RANGE) 95 return -ERANGE; 96 } 97 98 if (out) { 99 if (mmc_host_is_spi(host)) 100 *out = (cmd.resp[0] >> 8) & 0xFF; 101 else 102 *out = cmd.resp[0] & 0xFF; 103 } 104 105 return 0; 106 } 107 108 int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, 109 unsigned addr, u8 in, u8 *out) 110 { 111 return mmc_io_rw_direct_host(card->host, write, fn, addr, in, out); 112 } 113 114 int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, 115 unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz) 116 { 117 struct mmc_request mrq = {}; 118 struct mmc_command cmd = {}; 119 struct mmc_data data = {}; 120 struct scatterlist sg, *sg_ptr; 121 struct sg_table sgtable; 122 unsigned int nents, left_size, i; 123 unsigned int seg_size = card->host->max_seg_size; 124 125 WARN_ON(blksz == 0); 126 127 /* sanity check */ 128 if (addr & ~0x1FFFF) 129 return -EINVAL; 130 131 mrq.cmd = &cmd; 132 mrq.data = &data; 133 134 cmd.opcode = SD_IO_RW_EXTENDED; 135 cmd.arg = write ? 0x80000000 : 0x00000000; 136 cmd.arg |= fn << 28; 137 cmd.arg |= incr_addr ? 0x04000000 : 0x00000000; 138 cmd.arg |= addr << 9; 139 if (blocks == 0) 140 cmd.arg |= (blksz == 512) ? 0 : blksz; /* byte mode */ 141 else 142 cmd.arg |= 0x08000000 | blocks; /* block mode */ 143 cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC; 144 145 data.blksz = blksz; 146 /* Code in host drivers/fwk assumes that "blocks" always is >=1 */ 147 data.blocks = blocks ? blocks : 1; 148 data.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ; 149 150 left_size = data.blksz * data.blocks; 151 nents = DIV_ROUND_UP(left_size, seg_size); 152 if (nents > 1) { 153 if (sg_alloc_table(&sgtable, nents, GFP_KERNEL)) 154 return -ENOMEM; 155 156 data.sg = sgtable.sgl; 157 data.sg_len = nents; 158 159 for_each_sg(data.sg, sg_ptr, data.sg_len, i) { 160 sg_set_buf(sg_ptr, buf + i * seg_size, 161 min(seg_size, left_size)); 162 left_size -= seg_size; 163 } 164 } else { 165 data.sg = &sg; 166 data.sg_len = 1; 167 168 sg_init_one(&sg, buf, left_size); 169 } 170 171 mmc_set_data_timeout(&data, card); 172 173 mmc_wait_for_req(card->host, &mrq); 174 175 if (nents > 1) 176 sg_free_table(&sgtable); 177 178 if (cmd.error) 179 return cmd.error; 180 if (data.error) 181 return data.error; 182 183 if (mmc_host_is_spi(card->host)) { 184 /* host driver already reported errors */ 185 } else { 186 if (cmd.resp[0] & R5_ERROR) 187 return -EIO; 188 if (cmd.resp[0] & R5_FUNCTION_NUMBER) 189 return -EINVAL; 190 if (cmd.resp[0] & R5_OUT_OF_RANGE) 191 return -ERANGE; 192 } 193 194 return 0; 195 } 196 197 int sdio_reset(struct mmc_host *host) 198 { 199 int ret; 200 u8 abort; 201 202 /* SDIO Simplified Specification V2.0, 4.4 Reset for SDIO */ 203 204 ret = mmc_io_rw_direct_host(host, 0, 0, SDIO_CCCR_ABORT, 0, &abort); 205 if (ret) 206 abort = 0x08; 207 else 208 abort |= 0x08; 209 210 return mmc_io_rw_direct_host(host, 1, 0, SDIO_CCCR_ABORT, abort, NULL); 211 } 212 213