2 * Copyright (c) 2012 Robert N. M. Watson
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.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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.
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
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
34 #include <sys/param.h>
36 #include <sys/condvar.h>
39 #include <sys/kernel.h>
41 #include <sys/malloc.h>
42 #include <sys/module.h>
43 #include <sys/mutex.h>
45 #include <sys/systm.h>
46 #include <sys/taskqueue.h>
48 #include <machine/bus.h>
49 #include <machine/resource.h>
51 #include <geom/geom_disk.h>
53 #include <dev/altera/sdcard/altera_sdcard.h>
56 * Device driver for the Altera University Program Secure Data Card IP Core,
57 * as described in the similarly named SOPC Builder IP Core specification.
58 * This soft core is not a full SD host controller interface (SDHCI) but
59 * instead provides a set of memory mapped registers and memory buffer that
60 * mildly abstract the SD Card protocol, but without providing DMA or
61 * interrupts. However, it does hide the details of voltage and
62 * communications negotiation. This driver implements disk(9), but due to the
63 * lack of interrupt support, must rely on timer-driven polling to determine
64 * when I/Os have completed.
68 * 1. Implement DISKFLAG_CANDELETE / SD Card sector erase support.
69 * 2. Implement d_ident from SD Card CID serial number field.
70 * 3. Handle read-only SD Cards.
71 * 4. Tune timeouts based on real-world SD Card speeds.
73 devclass_t altera_sdcard_devclass;
76 altera_sdcard_attach(struct altera_sdcard_softc *sc)
79 ALTERA_SDCARD_LOCK_INIT(sc);
80 ALTERA_SDCARD_CONDVAR_INIT(sc);
82 bioq_init(&sc->as_bioq);
83 sc->as_currentbio = NULL;
84 sc->as_state = ALTERA_SDCARD_STATE_NOCARD;
85 sc->as_taskqueue = taskqueue_create("altera_sdcardc taskq", M_WAITOK,
86 taskqueue_thread_enqueue, &sc->as_taskqueue);
87 taskqueue_start_threads(&sc->as_taskqueue, 1, PI_DISK,
88 "altera_sdcardc%d taskqueue", sc->as_unit);
89 TIMEOUT_TASK_INIT(sc->as_taskqueue, &sc->as_task, 0,
90 altera_sdcard_task, sc);
93 * Kick off timer-driven processing with a manual poll so that we
94 * synchronously detect an already-inserted SD Card during the boot or
95 * other driver attach point.
97 altera_sdcard_task(sc, 1);
101 altera_sdcard_detach(struct altera_sdcard_softc *sc)
104 KASSERT(sc->as_taskqueue != NULL, ("%s: taskqueue not present",
108 * Winding down the driver on detach is a bit complex. Update the
109 * flags to indicate that a detach has been requested, and then wait
110 * for in-progress I/O to wind down before continuing.
112 ALTERA_SDCARD_LOCK(sc);
113 sc->as_flags |= ALTERA_SDCARD_FLAG_DETACHREQ;
114 while (sc->as_state != ALTERA_SDCARD_STATE_DETACHED)
115 ALTERA_SDCARD_CONDVAR_WAIT(sc);
116 ALTERA_SDCARD_UNLOCK(sc);
119 * Now wait for the possibly still executing taskqueue to drain. In
120 * principle no more events will be scheduled as we've transitioned to
121 * a detached state, but there might still be a request in execution.
123 while (taskqueue_cancel_timeout(sc->as_taskqueue, &sc->as_task, NULL))
124 taskqueue_drain_timeout(sc->as_taskqueue, &sc->as_task);
127 * Simulate a disk removal if one is present to deal with any pending
130 if (sc->as_disk != NULL)
131 altera_sdcard_disk_remove(sc);
132 KASSERT(bioq_first(&sc->as_bioq) == NULL,
133 ("%s: non-empty bioq", __func__));
136 * Free any remaining allocated resources.
138 taskqueue_free(sc->as_taskqueue);
139 sc->as_taskqueue = NULL;
140 ALTERA_SDCARD_CONDVAR_DESTROY(sc);
141 ALTERA_SDCARD_LOCK_DESTROY(sc);
145 * Set up and start the next I/O. Transition to the I/O state, but allow the
146 * caller to schedule the next timeout, as this may be called either from an
147 * initial attach context, or from the task queue, which requires different
151 altera_sdcard_nextio(struct altera_sdcard_softc *sc)
155 ALTERA_SDCARD_LOCK_ASSERT(sc);
156 KASSERT(sc->as_currentbio == NULL,
157 ("%s: bio already active", __func__));
159 bp = bioq_takefirst(&sc->as_bioq);
161 panic("%s: bioq empty", __func__);
162 altera_sdcard_io_start(sc, bp);
163 sc->as_state = ALTERA_SDCARD_STATE_IO;
167 altera_sdcard_task_nocard(struct altera_sdcard_softc *sc)
170 ALTERA_SDCARD_LOCK_ASSERT(sc);
173 * Handle device driver detach.
175 if (sc->as_flags & ALTERA_SDCARD_FLAG_DETACHREQ) {
176 sc->as_state = ALTERA_SDCARD_STATE_DETACHED;
181 * If there is no card insertion, remain in NOCARD.
183 if (!(altera_sdcard_read_asr(sc) & ALTERA_SDCARD_ASR_CARDPRESENT))
187 * Read the CSD -- it may contain values that the driver can't handle,
188 * either because of an unsupported version/feature, or because the
189 * card is misbehaving. This triggers a transition to
190 * ALTERA_SDCARD_STATE_BADCARD. We rely on the CSD read to print a
191 * banner about how the card is problematic, since it has more
192 * information. The bad card state allows us to print that banner
193 * once rather than each time we notice the card is there, and still
196 if (altera_sdcard_read_csd(sc) != 0) {
197 sc->as_state = ALTERA_SDCARD_STATE_BADCARD;
202 * Process card insertion and upgrade to the IDLE state.
204 altera_sdcard_disk_insert(sc);
205 sc->as_state = ALTERA_SDCARD_STATE_IDLE;
209 altera_sdcard_task_badcard(struct altera_sdcard_softc *sc)
212 ALTERA_SDCARD_LOCK_ASSERT(sc);
215 * Handle device driver detach.
217 if (sc->as_flags & ALTERA_SDCARD_FLAG_DETACHREQ) {
218 sc->as_state = ALTERA_SDCARD_STATE_DETACHED;
223 * Handle safe card removal -- no teardown is required, just a state
226 if (!(altera_sdcard_read_asr(sc) & ALTERA_SDCARD_ASR_CARDPRESENT))
227 sc->as_state = ALTERA_SDCARD_STATE_NOCARD;
231 altera_sdcard_task_idle(struct altera_sdcard_softc *sc)
234 ALTERA_SDCARD_LOCK_ASSERT(sc);
237 * Handle device driver detach.
239 if (sc->as_flags & ALTERA_SDCARD_FLAG_DETACHREQ) {
240 sc->as_state = ALTERA_SDCARD_STATE_DETACHED;
245 * Handle safe card removal.
247 if (!(altera_sdcard_read_asr(sc) & ALTERA_SDCARD_ASR_CARDPRESENT)) {
248 altera_sdcard_disk_remove(sc);
249 sc->as_state = ALTERA_SDCARD_STATE_NOCARD;
254 altera_sdcard_task_io(struct altera_sdcard_softc *sc)
258 ALTERA_SDCARD_LOCK_ASSERT(sc);
259 KASSERT(sc->as_currentbio != NULL, ("%s: no current I/O", __func__));
261 asr = altera_sdcard_read_asr(sc);
264 * Check for unexpected card removal during an I/O.
266 if (!(asr & ALTERA_SDCARD_ASR_CARDPRESENT)) {
267 altera_sdcard_disk_remove(sc);
268 if (sc->as_flags & ALTERA_SDCARD_FLAG_DETACHREQ)
269 sc->as_state = ALTERA_SDCARD_STATE_DETACHED;
271 sc->as_state = ALTERA_SDCARD_STATE_NOCARD;
276 * If the I/O isn't complete, remain in the IO state without further
277 * action, even if DETACHREQ is in flight.
279 if (asr & ALTERA_SDCARD_ASR_CMDINPROGRESS)
283 * Handle various forms of I/O completion, successful and otherwise.
284 * The I/O layer may restart the transaction if an error occurred, in
285 * which case remain in the IO state and reschedule.
287 if (!altera_sdcard_io_complete(sc, asr))
291 * Now that I/O is complete, process detach requests in preference to
294 if (sc->as_flags & ALTERA_SDCARD_FLAG_DETACHREQ) {
295 sc->as_state = ALTERA_SDCARD_STATE_DETACHED;
300 * Finally, either start the next I/O or transition to the IDLE state.
302 if (bioq_first(&sc->as_bioq) != NULL)
303 altera_sdcard_nextio(sc);
305 sc->as_state = ALTERA_SDCARD_STATE_IDLE;
309 altera_sdcard_task_rechedule(struct altera_sdcard_softc *sc)
314 * Reschedule based on new state. Or not, if detaching the device
315 * driver. Treat a bad card as though it were no card at all.
317 switch (sc->as_state) {
318 case ALTERA_SDCARD_STATE_NOCARD:
319 case ALTERA_SDCARD_STATE_BADCARD:
320 interval = ALTERA_SDCARD_TIMEOUT_NOCARD;
323 case ALTERA_SDCARD_STATE_IDLE:
324 interval = ALTERA_SDCARD_TIMEOUT_IDLE;
327 case ALTERA_SDCARD_STATE_IO:
328 if (sc->as_flags & ALTERA_SDCARD_FLAG_IOERROR)
329 interval = ALTERA_SDCARD_TIMEOUT_IOERROR;
331 interval = ALTERA_SDCARD_TIMEOUT_IO;
335 panic("%s: invalid exit state %d", __func__, sc->as_state);
337 taskqueue_enqueue_timeout(sc->as_taskqueue, &sc->as_task, interval);
341 * Because the Altera SD Card IP Core doesn't support interrupts, we do all
342 * asynchronous work from a timeout. Poll at two different rates -- an
343 * infrequent check for card insertion status changes, and a frequent one for
344 * I/O completion. The task should never start in DETACHED, as that would
345 * imply that a previous instance failed to cancel rather than reschedule.
348 altera_sdcard_task(void *arg, int pending)
350 struct altera_sdcard_softc *sc;
353 KASSERT(sc->as_state != ALTERA_SDCARD_STATE_DETACHED,
354 ("%s: already in detached", __func__));
356 ALTERA_SDCARD_LOCK(sc);
357 switch (sc->as_state) {
358 case ALTERA_SDCARD_STATE_NOCARD:
359 altera_sdcard_task_nocard(sc);
362 case ALTERA_SDCARD_STATE_BADCARD:
363 altera_sdcard_task_badcard(sc);
366 case ALTERA_SDCARD_STATE_IDLE:
367 altera_sdcard_task_idle(sc);
370 case ALTERA_SDCARD_STATE_IO:
371 altera_sdcard_task_io(sc);
375 panic("%s: invalid enter state %d", __func__, sc->as_state);
379 * If we have transitioned to DETACHED, signal the detach thread and
380 * cancel the timeout-driven task. Otherwise reschedule on an
381 * appropriate timeout.
383 if (sc->as_state == ALTERA_SDCARD_STATE_DETACHED)
384 ALTERA_SDCARD_CONDVAR_SIGNAL(sc);
386 altera_sdcard_task_rechedule(sc);
387 ALTERA_SDCARD_UNLOCK(sc);
391 altera_sdcard_start(struct altera_sdcard_softc *sc)
394 ALTERA_SDCARD_LOCK_ASSERT(sc);
396 KASSERT(sc->as_state == ALTERA_SDCARD_STATE_IDLE,
397 ("%s: starting when not IDLE", __func__));
399 taskqueue_cancel_timeout(sc->as_taskqueue, &sc->as_task, NULL);
400 altera_sdcard_nextio(sc);
401 taskqueue_enqueue_timeout(sc->as_taskqueue, &sc->as_task,
402 ALTERA_SDCARD_TIMEOUT_IO);