altera_sdcard_disk.c revision 331722
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: stable/11/sys/dev/altera/sdcard/altera_sdcard_disk.c 331722 2018-03-29 02:50:57Z eadler $"); 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/kernel.h> 40#include <sys/lock.h> 41#include <sys/malloc.h> 42#include <sys/module.h> 43#include <sys/mutex.h> 44#include <sys/rman.h> 45#include <sys/systm.h> 46#include <sys/taskqueue.h> 47 48#include <machine/bus.h> 49#include <machine/resource.h> 50 51#include <geom/geom_disk.h> 52 53#include <dev/altera/sdcard/altera_sdcard.h> 54 55static int 56altera_sdcard_disk_dump(void *arg, void *virtual, vm_offset_t physical, 57 off_t offset, size_t length) 58{ 59 60 panic("%s: not yet", __func__); 61} 62 63static int 64altera_sdcard_disk_ioctl(struct disk *disk, u_long cmd, void *data, int fflag, 65 struct thread *td) 66{ 67 68 /* XXXRW: more here? */ 69 return (EINVAL); 70} 71 72static void 73altera_sdcard_disk_strategy(struct bio *bp) 74{ 75 struct altera_sdcard_softc *sc; 76 77 /* 78 * Although the SD Card doesn't need sorting, we don't want to 79 * introduce barriers, so use bioq_disksort(). 80 */ 81 sc = bp->bio_disk->d_drv1; 82 ALTERA_SDCARD_LOCK(sc); 83 switch (sc->as_state) { 84 case ALTERA_SDCARD_STATE_NOCARD: 85 device_printf(sc->as_dev, "%s: unexpected I/O on NOCARD", 86 __func__); 87 biofinish(bp, NULL, ENXIO); 88 break; 89 90 case ALTERA_SDCARD_STATE_BADCARD: 91 device_printf(sc->as_dev, "%s: unexpected I/O on BADCARD", 92 __func__); 93 biofinish(bp, NULL, ENXIO); 94 break; 95 96 case ALTERA_SDCARD_STATE_DETACHED: 97 device_printf(sc->as_dev, "%s: unexpected I/O on DETACHED", 98 __func__); 99 biofinish(bp, NULL, ENXIO); 100 101 case ALTERA_SDCARD_STATE_IDLE: 102 bioq_disksort(&sc->as_bioq, bp); 103 altera_sdcard_start(sc); 104 break; 105 106 case ALTERA_SDCARD_STATE_IO: 107 bioq_disksort(&sc->as_bioq, bp); 108 break; 109 110 default: 111 panic("%s: invalid state %d", __func__, sc->as_state); 112 } 113 ALTERA_SDCARD_UNLOCK(sc); 114} 115 116void 117altera_sdcard_disk_insert(struct altera_sdcard_softc *sc) 118{ 119 struct disk *disk; 120 uint64_t size; 121 122 ALTERA_SDCARD_LOCK_ASSERT(sc); 123 124 /* 125 * Because the disk insertion routine occupies the driver instance's 126 * task queue thread, and the disk(9) instance isn't hooked up yet by 127 * definition, the only other source of events of concern is a thread 128 * initiating driver detach. That thread has to issue a detach 129 * request and await an ACK from the taskqueue thread. It is 130 * therefore safe to drop the lock here. 131 */ 132 ALTERA_SDCARD_UNLOCK(sc); 133 disk = disk_alloc(); 134 disk->d_drv1 = sc; 135 disk->d_name = "altera_sdcard"; 136 disk->d_unit = sc->as_unit; 137 disk->d_strategy = altera_sdcard_disk_strategy; 138 disk->d_dump = altera_sdcard_disk_dump; 139 disk->d_ioctl = altera_sdcard_disk_ioctl; 140 disk->d_sectorsize = ALTERA_SDCARD_SECTORSIZE; 141 disk->d_mediasize = sc->as_mediasize; 142 disk->d_maxsize = ALTERA_SDCARD_SECTORSIZE; 143 sc->as_disk = disk; 144 disk_create(disk, DISK_VERSION); 145 ALTERA_SDCARD_LOCK(sc); 146 147 /* 148 * Print a pretty-ish card insertion string. We could stand to 149 * decorate this further, e.g., with card vendor information. 150 */ 151 size = sc->as_mediasize / (1000 * 1000); 152 device_printf(sc->as_dev, "%juM SD Card inserted\n", (uintmax_t)size); 153} 154 155void 156altera_sdcard_disk_remove(struct altera_sdcard_softc *sc) 157{ 158 struct disk *disk; 159 160 ALTERA_SDCARD_LOCK_ASSERT(sc); 161 KASSERT(sc->as_disk != NULL, ("%s: as_disk NULL", __func__)); 162 163 /* 164 * sc->as_state will be updated by the caller. 165 * 166 * XXXRW: Is it OK to call disk_destroy() under the mutex, or should 167 * we be deferring that to the calling context once it is released? 168 */ 169 disk = sc->as_disk; 170 disk_gone(disk); 171 disk_destroy(disk); 172 sc->as_disk = NULL; 173 174 /* 175 * Cancel all outstanding I/O on the SD Card. 176 */ 177 if (sc->as_currentbio != NULL) { 178 device_printf(sc->as_dev, "%s: SD Card removed during I/O", 179 __func__); 180 biofinish(sc->as_currentbio, NULL, ENXIO); 181 sc->as_currentbio = NULL; 182 } 183 bioq_flush(&sc->as_bioq, NULL, ENXIO); 184 device_printf(sc->as_dev, "SD Card removed\n"); 185} 186