1 /*-
2  * Copyright (c) 2012 Robert N. M. Watson
3  * All rights reserved.
4  *
5  * This software was developed by SRI International and the University of
6  * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
7  * ("CTSRD"), as part of the DARPA CRASH research programme.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */
30 
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33 
34 #include <sys/param.h>
35 #include <sys/bus.h>
36 #include <sys/condvar.h>
37 #include <sys/conf.h>
38 #include <sys/bio.h>
39 #include <sys/endian.h>
40 #include <sys/kernel.h>
41 #include <sys/lock.h>
42 #include <sys/malloc.h>
43 #include <sys/module.h>
44 #include <sys/mutex.h>
45 #include <sys/rman.h>
46 #include <sys/systm.h>
47 #include <sys/taskqueue.h>
48 
49 #include <machine/bus.h>
50 #include <machine/resource.h>
51 
52 #include <geom/geom_disk.h>
53 
54 #include <dev/altera/sdcard/altera_sdcard.h>
55 
56 int altera_sdcard_ignore_crc_errors = 1;
57 int altera_sdcard_verify_rxtx_writes = 1;
58 
59 /*
60  * Low-level I/O routines for the Altera SD Card University IP Core driver.
61  *
62  * XXXRW: Throughout, it is assumed that the IP Core handles multibyte
63  * registers as little endian, as is the case for other Altera IP cores.
64  * However, the specification makes no reference to endianness, so this
65  * assumption might not always be correct.
66  */
67 uint16_t
68 altera_sdcard_read_asr(struct altera_sdcard_softc *sc)
69 {
70 
71 	return (le16toh(bus_read_2(sc->as_res, ALTERA_SDCARD_OFF_ASR)));
72 }
73 
74 static int
75 altera_sdcard_process_csd0(struct altera_sdcard_softc *sc)
76 {
77 	uint64_t c_size, c_size_mult, read_bl_len;
78 	uint8_t byte0, byte1, byte2;
79 
80 	ALTERA_SDCARD_LOCK_ASSERT(sc);
81 
82 	/*-
83 	 * Compute card capacity per SD Card interface description as follows:
84 	 *
85 	 *   Memory capacity = BLOCKNR * BLOCK_LEN
86 	 *
87 	 * Where:
88 	 *
89 	 *   BLOCKNR = (C_SIZE + 1) * MULT
90 	 *   MULT = 2^(C_SIZE_MULT+2)
91 	 *   BLOCK_LEN = 2^READ_BL_LEN
92 	 */
93 	read_bl_len = sc->as_csd.csd_data[ALTERA_SDCARD_CSD_READ_BL_LEN_BYTE];
94 	read_bl_len &= ALTERA_SDCARD_CSD_READ_BL_LEN_MASK;
95 
96 	byte0 = sc->as_csd.csd_data[ALTERA_SDCARD_CSD_C_SIZE_BYTE0];
97 	byte0 &= ALTERA_SDCARD_CSD_C_SIZE_MASK0;
98 	byte1 = sc->as_csd.csd_data[ALTERA_SDCARD_CSD_C_SIZE_BYTE1];
99 	byte2 = sc->as_csd.csd_data[ALTERA_SDCARD_CSD_C_SIZE_BYTE2];
100 	byte2 &= ALTERA_SDCARD_CSD_C_SIZE_MASK2;
101 	c_size = (byte0 >> ALTERA_SDCARD_CSD_C_SIZE_RSHIFT0) |
102 	    (byte1 << ALTERA_SDCARD_CSD_C_SIZE_LSHIFT1) |
103 	    (byte2 << ALTERA_SDCARD_CSD_C_SIZE_LSHIFT2);
104 
105 	byte0 = sc->as_csd.csd_data[ALTERA_SDCARD_CSD_C_SIZE_MULT_BYTE0];
106 	byte0 &= ALTERA_SDCARD_CSD_C_SIZE_MULT_MASK0;
107 	byte1 = sc->as_csd.csd_data[ALTERA_SDCARD_CSD_C_SIZE_MULT_BYTE1];
108 	byte1 &= ALTERA_SDCARD_CSD_C_SIZE_MULT_MASK1;
109 	c_size_mult = (byte0 >> ALTERA_SDCARD_CSD_C_SIZE_MULT_RSHIFT0) |
110 	    (byte1 << ALTERA_SDCARD_CSD_C_SIZE_MULT_LSHIFT1);
111 
112 	/*
113 	 * If we're just getting back zero's, mark the card as bad, even
114 	 * though it could just mean a Very Small Disk Indeed.
115 	 */
116 	if (c_size == 0 && c_size_mult == 0 && read_bl_len == 0) {
117 		device_printf(sc->as_dev, "Ignored zero-size card\n");
118 		return (ENXIO);
119 	}
120 	sc->as_mediasize = (c_size + 1) * (1 << (c_size_mult + 2)) *
121 	    (1 << read_bl_len);
122 	return (0);
123 }
124 
125 int
126 altera_sdcard_read_csd(struct altera_sdcard_softc *sc)
127 {
128 	uint8_t csd_structure;
129 	int error;
130 
131 	ALTERA_SDCARD_LOCK_ASSERT(sc);
132 
133 	/*
134 	 * XXXRW: Assume for now that when the SD Card IP Core negotiates
135 	 * voltage/speed/etc, it must use the CSD register, and therefore
136 	 * populates the SD Card IP Core's cache of the register value.  This
137 	 * means that we can read it without issuing further SD Card commands.
138 	 * If this assumption proves false, we will (a) get back garbage and
139 	 * (b) need to add additional states in the driver state machine in
140 	 * order to query card properties before I/O can start.
141 	 *
142 	 * XXXRW: Treating this as an array of bytes, so no byte swapping --
143 	 * is that a safe assumption?
144 	 */
145 	KASSERT(((uintptr_t)&sc->as_csd.csd_data) % 2 == 0,
146 	    ("%s: CSD buffer unaligned", __func__));
147 	bus_read_region_2(sc->as_res, ALTERA_SDCARD_OFF_CSD,
148 	    (uint16_t *)sc->as_csd.csd_data, sizeof(sc->as_csd) / 2);
149 
150 	/*
151 	 * Interpret the loaded CSD, extracting certain fields and copying
152 	 * them into the softc for easy software access.
153 	 *
154 	 * Currently, we support only CSD Version 1.0.  If we detect a newer
155 	 * version, suppress card detection.
156 	 */
157 	csd_structure = sc->as_csd.csd_data[ALTERA_SDCARD_CSD_STRUCTURE_BYTE];
158 	csd_structure &= ALTERA_SDCARD_CSD_STRUCTURE_MASK;
159 	csd_structure >>= ALTERA_SDCARD_CSD_STRUCTURE_RSHIFT;
160 	sc->as_csd_structure = csd_structure;
161 
162 	/*
163 	 * Interpret the CSD field based on its version.  Extract fields,
164 	 * especially mediasize.
165 	 *
166 	 * XXXRW: Desirable to support further CSD versions here.
167 	 */
168 	switch (sc->as_csd_structure) {
169 	case 0:
170 		error = altera_sdcard_process_csd0(sc);
171 		if (error)
172 			return (error);
173 		break;
174 
175 	default:
176 		device_printf(sc->as_dev,
177 		    "Ignored disk with unsupported CSD structure (%d)\n",
178 		    sc->as_csd_structure);
179 		return (ENXIO);
180 	}
181 	return (0);
182 }
183 
184 /*
185  * XXXRW: The Altera IP Core specification indicates that RR1 is a 16-bit
186  * register, but all bits it identifies are >16 bit.  Most likely, RR1 is a
187  * 32-bit register?
188  */
189 static uint16_t
190 altera_sdcard_read_rr1(struct altera_sdcard_softc *sc)
191 {
192 
193 	return (le16toh(bus_read_2(sc->as_res, ALTERA_SDCARD_OFF_RR1)));
194 }
195 
196 static void
197 altera_sdcard_write_cmd_arg(struct altera_sdcard_softc *sc, uint32_t cmd_arg)
198 {
199 
200 	bus_write_4(sc->as_res, ALTERA_SDCARD_OFF_CMD_ARG, htole32(cmd_arg));
201 }
202 
203 static void
204 altera_sdcard_write_cmd(struct altera_sdcard_softc *sc, uint16_t cmd)
205 {
206 
207 	bus_write_2(sc->as_res, ALTERA_SDCARD_OFF_CMD, htole16(cmd));
208 }
209 
210 static void
211 altera_sdcard_read_rxtx_buffer(struct altera_sdcard_softc *sc, void *data,
212     size_t len)
213 {
214 
215 	KASSERT((uintptr_t)data % 2 == 0,
216 	    ("%s: unaligned data %p", __func__, data));
217 	KASSERT((len <= ALTERA_SDCARD_SECTORSIZE) && (len % 2 == 0),
218 	    ("%s: invalid length %ju", __func__, len));
219 
220 	bus_read_region_2(sc->as_res, ALTERA_SDCARD_OFF_RXTX_BUFFER,
221 	    (uint16_t *)data, len / 2);
222 }
223 
224 static void
225 altera_sdcard_write_rxtx_buffer(struct altera_sdcard_softc *sc, void *data,
226     size_t len)
227 {
228 	u_int corrections, differences, i, retry_counter;
229 	uint16_t d, v;
230 
231 	KASSERT((uintptr_t)data % 2 == 0,
232 	    ("%s: unaligned data %p", __func__, data));
233 	KASSERT((len <= ALTERA_SDCARD_SECTORSIZE) && (len % 2 == 0),
234 	    ("%s: invalid length %ju", __func__, len));
235 
236 	retry_counter = 0;
237 	do {
238 		bus_write_region_2(sc->as_res, ALTERA_SDCARD_OFF_RXTX_BUFFER,
239 		    (uint16_t *)data, len / 2);
240 
241 		/*
242 		 * XXXRW: Due to a possible hardware bug, the above call to
243 		 * bus_write_region_2() might not succeed.  If the workaround
244 		 * is enabled, verify each write and retry until it succeeds.
245 		 *
246 		 * XXXRW: Do we want a limit counter for retries here?
247 		 */
248 recheck:
249 		corrections = 0;
250 		differences = 0;
251 		if (altera_sdcard_verify_rxtx_writes) {
252 			for (i = 0; i < ALTERA_SDCARD_SECTORSIZE; i += 2) {
253 				v = bus_read_2(sc->as_res,
254 				    ALTERA_SDCARD_OFF_RXTX_BUFFER + i);
255 				d = *(uint16_t *)((uint8_t *)data + i);
256 				if (v != d) {
257 					if (retry_counter == 0) {
258 						bus_write_2(sc->as_res,
259 						    ALTERA_SDCARD_OFF_RXTX_BUFFER + i,
260 						    d);
261 						v = bus_read_2(sc->as_res,
262 						    ALTERA_SDCARD_OFF_RXTX_BUFFER + i);
263 						if (v == d) {
264 							corrections++;
265 							device_printf(sc->as_dev,
266 							    "%s: single word rewrite worked"
267 							    " at offset %u\n",
268 							    __func__, i);
269 							continue;
270 						}
271 					}
272 					differences++;
273 					device_printf(sc->as_dev,
274 					    "%s: retrying write -- difference"
275 					    " %u at offset %u, retry %u\n",
276 					    __func__, differences, i,
277 					    retry_counter);
278 				}
279 			}
280 			if (differences != 0) {
281 				retry_counter++;
282 				if (retry_counter == 1 &&
283 				    corrections == differences)
284 					goto recheck;
285 			}
286 		}
287 	} while (differences != 0);
288 	if (retry_counter)
289 		device_printf(sc->as_dev, "%s: succeeded after %u retries\n",
290 		    __func__, retry_counter);
291 }
292 
293 static void
294 altera_sdcard_io_start_internal(struct altera_sdcard_softc *sc, struct bio *bp)
295 {
296 
297 	switch (bp->bio_cmd) {
298 	case BIO_READ:
299 		altera_sdcard_write_cmd_arg(sc, bp->bio_pblkno *
300 		    ALTERA_SDCARD_SECTORSIZE);
301 		altera_sdcard_write_cmd(sc, ALTERA_SDCARD_CMD_READ_BLOCK);
302 		break;
303 
304 	case BIO_WRITE:
305 		altera_sdcard_write_rxtx_buffer(sc, bp->bio_data,
306 		    bp->bio_bcount);
307 		altera_sdcard_write_cmd_arg(sc, bp->bio_pblkno *
308 		    ALTERA_SDCARD_SECTORSIZE);
309 		altera_sdcard_write_cmd(sc, ALTERA_SDCARD_CMD_WRITE_BLOCK);
310 		break;
311 
312 	default:
313 		panic("%s: unsupported I/O operation %d", __func__,
314 		    bp->bio_cmd);
315 	}
316 }
317 
318 void
319 altera_sdcard_io_start(struct altera_sdcard_softc *sc, struct bio *bp)
320 {
321 
322 	ALTERA_SDCARD_LOCK_ASSERT(sc);
323 	KASSERT(sc->as_currentbio == NULL,
324 	    ("%s: bio already started", __func__));
325 
326 	/*
327 	 * We advertise a block size and maximum I/O size up the stack of the
328 	 * SD Card IP Core sector size.  Catch any attempts to not follow the
329 	 * rules.
330 	 */
331 	KASSERT(bp->bio_bcount == ALTERA_SDCARD_SECTORSIZE,
332 	    ("%s: I/O size not %d", __func__, ALTERA_SDCARD_SECTORSIZE));
333 	altera_sdcard_io_start_internal(sc, bp);
334 	sc->as_currentbio = bp;
335 	sc->as_retriesleft = ALTERA_SDCARD_RETRY_LIMIT;
336 }
337 
338 /*
339  * Handle completed I/O.  ASR is passed in to avoid reading it more than once.
340  * Return 1 if the I/O is actually complete (success, or retry limit
341  * exceeded), or 0 if not.
342  */
343 int
344 altera_sdcard_io_complete(struct altera_sdcard_softc *sc, uint16_t asr)
345 {
346 	struct bio *bp;
347 	uint16_t rr1, mask;
348 	int error;
349 
350 	ALTERA_SDCARD_LOCK_ASSERT(sc);
351 	KASSERT(!(asr & ALTERA_SDCARD_ASR_CMDINPROGRESS),
352 	    ("%s: still in progress", __func__));
353 	KASSERT(asr & ALTERA_SDCARD_ASR_CARDPRESENT,
354 	    ("%s: card removed", __func__));
355 
356 	bp = sc->as_currentbio;
357 
358 	/*-
359 	 * Handle I/O retries if an error is returned by the device.  Various
360 	 * quirks handled in the process:
361 	 *
362 	 * 1. ALTERA_SDCARD_ASR_CMDDATAERROR is ignored for BIO_WRITE.
363 	 * 2. ALTERA_SDCARD_RR1_COMMANDCRCFAILED is optionally ignored for
364 	 *    BIO_READ.
365 	 */
366 	error = 0;
367 	rr1 = altera_sdcard_read_rr1(sc);
368 	switch (bp->bio_cmd) {
369 	case BIO_READ:
370 		mask = ALTERA_SDCARD_RR1_ERRORMASK;
371 		if (altera_sdcard_ignore_crc_errors)
372 			mask &= ~ALTERA_SDCARD_RR1_COMMANDCRCFAILED;
373 		if (asr & ALTERA_SDCARD_ASR_CMDTIMEOUT)
374 			error = EIO;
375 		else if ((asr & ALTERA_SDCARD_ASR_CMDDATAERROR) &&
376 		    (rr1 & mask))
377 			error = EIO;
378 		else
379 			error = 0;
380 		break;
381 
382 	case BIO_WRITE:
383 		if (asr & ALTERA_SDCARD_ASR_CMDTIMEOUT)
384 			error = EIO;
385 		else
386 			error = 0;
387 		break;
388 
389 	default:
390 		break;
391 	}
392 	if (error) {
393 		sc->as_retriesleft--;
394 		if (sc->as_retriesleft == 0 || bootverbose)
395 			device_printf(sc->as_dev, "%s: %s operation block %ju "
396 			    "length %ju failed; asr 0x%08x (rr1: 0x%04x)%s\n",
397 			    __func__, bp->bio_cmd == BIO_READ ? "BIO_READ" :
398 			    (bp->bio_cmd == BIO_WRITE ? "BIO_WRITE" :
399 			    "unknown"),
400 			    bp->bio_pblkno, bp->bio_bcount, asr, rr1,
401 			    sc->as_retriesleft != 0 ? " retrying" : "");
402 		/*
403 		 * This attempt experienced an error; possibly retry.
404 		 */
405 		if (sc->as_retriesleft != 0) {
406 			sc->as_flags |= ALTERA_SDCARD_FLAG_IOERROR;
407 			altera_sdcard_io_start_internal(sc, bp);
408 			return (0);
409 		}
410 		sc->as_flags &= ~ALTERA_SDCARD_FLAG_IOERROR;
411 	} else {
412 		/*
413 		 * Successful I/O completion path.
414 		 */
415 		if (sc->as_flags & ALTERA_SDCARD_FLAG_IOERROR) {
416 			device_printf(sc->as_dev, "%s: %s operation block %ju"
417 			    " length %ju succeeded after %d retries\n",
418 			    __func__, bp->bio_cmd == BIO_READ ? "BIO_READ" :
419 			    (bp->bio_cmd == BIO_WRITE ? "write" : "unknown"),
420 			    bp->bio_pblkno, bp->bio_bcount,
421 			    ALTERA_SDCARD_RETRY_LIMIT - sc->as_retriesleft);
422 			sc->as_flags &= ~ALTERA_SDCARD_FLAG_IOERROR;
423 		}
424 		switch (bp->bio_cmd) {
425 		case BIO_READ:
426 			altera_sdcard_read_rxtx_buffer(sc, bp->bio_data,
427 			    bp->bio_bcount);
428 			break;
429 
430 		case BIO_WRITE:
431 			break;
432 
433 		default:
434 			panic("%s: unsupported I/O operation %d", __func__,
435 			    bp->bio_cmd);
436 		}
437 		bp->bio_resid = 0;
438 		error = 0;
439 	}
440 	biofinish(bp, NULL, error);
441 	sc->as_currentbio = NULL;
442 	return (1);
443 }
444