1239675Srwatson/*- 2239675Srwatson * Copyright (c) 2012 Robert N. M. Watson 3239675Srwatson * All rights reserved. 4239675Srwatson * 5239675Srwatson * This software was developed by SRI International and the University of 6239675Srwatson * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) 7239675Srwatson * ("CTSRD"), as part of the DARPA CRASH research programme. 8239675Srwatson * 9239675Srwatson * Redistribution and use in source and binary forms, with or without 10239675Srwatson * modification, are permitted provided that the following conditions 11239675Srwatson * are met: 12239675Srwatson * 1. Redistributions of source code must retain the above copyright 13239675Srwatson * notice, this list of conditions and the following disclaimer. 14239675Srwatson * 2. Redistributions in binary form must reproduce the above copyright 15239675Srwatson * notice, this list of conditions and the following disclaimer in the 16239675Srwatson * documentation and/or other materials provided with the distribution. 17239675Srwatson * 18239675Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19239675Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20239675Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21239675Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22239675Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23239675Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24239675Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25239675Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26239675Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27239675Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28239675Srwatson * SUCH DAMAGE. 29239675Srwatson */ 30239675Srwatson 31239675Srwatson#include <sys/cdefs.h> 32239675Srwatson__FBSDID("$FreeBSD$"); 33239675Srwatson 34239675Srwatson#include <sys/param.h> 35239675Srwatson#include <sys/bus.h> 36239675Srwatson#include <sys/condvar.h> 37239675Srwatson#include <sys/conf.h> 38239675Srwatson#include <sys/bio.h> 39239675Srwatson#include <sys/kernel.h> 40239675Srwatson#include <sys/lock.h> 41239675Srwatson#include <sys/malloc.h> 42239675Srwatson#include <sys/module.h> 43239675Srwatson#include <sys/mutex.h> 44239675Srwatson#include <sys/rman.h> 45239675Srwatson#include <sys/systm.h> 46239675Srwatson#include <sys/taskqueue.h> 47239675Srwatson 48239675Srwatson#include <machine/bus.h> 49239675Srwatson#include <machine/resource.h> 50239675Srwatson 51239675Srwatson#include <geom/geom_disk.h> 52239675Srwatson 53239675Srwatson#include <dev/altera/sdcard/altera_sdcard.h> 54239675Srwatson 55239675Srwatsonstatic int 56239675Srwatsonaltera_sdcard_disk_dump(void *arg, void *virtual, vm_offset_t physical, 57239675Srwatson off_t offset, size_t length) 58239675Srwatson{ 59239675Srwatson 60239675Srwatson panic("%s: not yet", __func__); 61239675Srwatson} 62239675Srwatson 63239675Srwatsonstatic int 64239675Srwatsonaltera_sdcard_disk_ioctl(struct disk *disk, u_long cmd, void *data, int fflag, 65239675Srwatson struct thread *td) 66239675Srwatson{ 67239675Srwatson 68239675Srwatson /* XXXRW: more here? */ 69239675Srwatson return (EINVAL); 70239675Srwatson} 71239675Srwatson 72239675Srwatsonstatic void 73239675Srwatsonaltera_sdcard_disk_strategy(struct bio *bp) 74239675Srwatson{ 75239675Srwatson struct altera_sdcard_softc *sc; 76239675Srwatson 77239675Srwatson /* 78239675Srwatson * Although the SD Card doesn't need sorting, we don't want to 79239675Srwatson * introduce barriers, so use bioq_disksort(). 80239675Srwatson */ 81239675Srwatson sc = bp->bio_disk->d_drv1; 82239675Srwatson ALTERA_SDCARD_LOCK(sc); 83239675Srwatson switch (sc->as_state) { 84239675Srwatson case ALTERA_SDCARD_STATE_NOCARD: 85239675Srwatson device_printf(sc->as_dev, "%s: unexpected I/O on NOCARD", 86239675Srwatson __func__); 87239675Srwatson biofinish(bp, NULL, ENXIO); 88239675Srwatson break; 89239675Srwatson 90239675Srwatson case ALTERA_SDCARD_STATE_BADCARD: 91239675Srwatson device_printf(sc->as_dev, "%s: unexpected I/O on BADCARD", 92239675Srwatson __func__); 93239675Srwatson biofinish(bp, NULL, ENXIO); 94239675Srwatson break; 95239675Srwatson 96239675Srwatson case ALTERA_SDCARD_STATE_DETACHED: 97239675Srwatson device_printf(sc->as_dev, "%s: unexpected I/O on DETACHED", 98239675Srwatson __func__); 99239675Srwatson biofinish(bp, NULL, ENXIO); 100239675Srwatson 101239675Srwatson case ALTERA_SDCARD_STATE_IDLE: 102239675Srwatson bioq_disksort(&sc->as_bioq, bp); 103239675Srwatson altera_sdcard_start(sc); 104239675Srwatson break; 105239675Srwatson 106239675Srwatson case ALTERA_SDCARD_STATE_IO: 107239675Srwatson bioq_disksort(&sc->as_bioq, bp); 108239675Srwatson break; 109239675Srwatson 110239675Srwatson default: 111239675Srwatson panic("%s: invalid state %d", __func__, sc->as_state); 112239675Srwatson } 113239675Srwatson ALTERA_SDCARD_UNLOCK(sc); 114239675Srwatson} 115239675Srwatson 116239675Srwatsonvoid 117239675Srwatsonaltera_sdcard_disk_insert(struct altera_sdcard_softc *sc) 118239675Srwatson{ 119239675Srwatson struct disk *disk; 120239675Srwatson uint64_t size; 121239675Srwatson 122239675Srwatson ALTERA_SDCARD_LOCK_ASSERT(sc); 123239675Srwatson 124239675Srwatson /* 125239675Srwatson * Because the disk insertion routine occupies the driver instance's 126239675Srwatson * task queue thread, and the disk(9) instance isn't hooked up yet by 127239675Srwatson * definition, the only other source of events of concern is a thread 128239675Srwatson * initiating driver detach. That thread has to issue a detach 129239675Srwatson * request and await an ACK from the taskqueue thread. It is 130239675Srwatson * therefore safe to drop the lock here. 131239675Srwatson */ 132239675Srwatson ALTERA_SDCARD_UNLOCK(sc); 133239675Srwatson disk = disk_alloc(); 134239675Srwatson disk->d_drv1 = sc; 135239675Srwatson disk->d_name = "altera_sdcard"; 136239675Srwatson disk->d_unit = sc->as_unit; 137239675Srwatson disk->d_strategy = altera_sdcard_disk_strategy; 138239675Srwatson disk->d_dump = altera_sdcard_disk_dump; 139239675Srwatson disk->d_ioctl = altera_sdcard_disk_ioctl; 140239675Srwatson disk->d_sectorsize = ALTERA_SDCARD_SECTORSIZE; 141239675Srwatson disk->d_mediasize = sc->as_mediasize; 142239675Srwatson disk->d_maxsize = ALTERA_SDCARD_SECTORSIZE; 143239675Srwatson sc->as_disk = disk; 144239675Srwatson disk_create(disk, DISK_VERSION); 145239675Srwatson ALTERA_SDCARD_LOCK(sc); 146239675Srwatson 147239675Srwatson /* 148239675Srwatson * Print a pretty-ish card insertion string. We could stand to 149239675Srwatson * decorate this further, e.g., with card vendor information. 150239675Srwatson */ 151239675Srwatson size = sc->as_mediasize / (1000 * 1000); 152239675Srwatson device_printf(sc->as_dev, "%juM SD Card inserted\n", (uintmax_t)size); 153239675Srwatson} 154239675Srwatson 155239675Srwatsonvoid 156239675Srwatsonaltera_sdcard_disk_remove(struct altera_sdcard_softc *sc) 157239675Srwatson{ 158239675Srwatson struct disk *disk; 159239675Srwatson 160239675Srwatson ALTERA_SDCARD_LOCK_ASSERT(sc); 161239675Srwatson KASSERT(sc->as_disk != NULL, ("%s: as_disk NULL", __func__)); 162239675Srwatson 163239675Srwatson /* 164239675Srwatson * sc->as_state will be updated by the caller. 165239675Srwatson * 166239675Srwatson * XXXRW: Is it OK to call disk_destroy() under the mutex, or should 167239675Srwatson * we be deferring that to the calling context once it is released? 168239675Srwatson */ 169239675Srwatson disk = sc->as_disk; 170239675Srwatson disk_gone(disk); 171239675Srwatson disk_destroy(disk); 172239675Srwatson sc->as_disk = NULL; 173239675Srwatson 174239675Srwatson /* 175239675Srwatson * Cancel all outstanding I/O on the SD Card. 176239675Srwatson */ 177239675Srwatson if (sc->as_currentbio != NULL) { 178239675Srwatson device_printf(sc->as_dev, "%s: SD Card removed during I/O", 179239675Srwatson __func__); 180239675Srwatson biofinish(sc->as_currentbio, NULL, ENXIO); 181239675Srwatson sc->as_currentbio = NULL; 182239675Srwatson } 183239675Srwatson bioq_flush(&sc->as_bioq, NULL, ENXIO); 184239675Srwatson device_printf(sc->as_dev, "SD Card removed\n"); 185239675Srwatson} 186