ofw_disk.c (172836) | ofw_disk.c (194138) |
---|---|
1/*- 2 * Copyright (C) 2002 Benno Rice <benno@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 12 unchanged lines hidden (view full) --- 21 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 22 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 23 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * 25 * 26 */ 27 28#include <sys/cdefs.h> | 1/*- 2 * Copyright (C) 2002 Benno Rice <benno@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 12 unchanged lines hidden (view full) --- 21 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 22 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 23 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * 25 * 26 */ 27 28#include <sys/cdefs.h> |
29__FBSDID("$FreeBSD: head/sys/dev/ofw/ofw_disk.c 172836 2007-10-20 23:23:23Z julian $"); | 29__FBSDID("$FreeBSD: head/sys/dev/ofw/ofw_disk.c 194138 2009-06-14 00:05:38Z marius $"); |
30 31#include <sys/param.h> 32#include <sys/systm.h> 33#include <sys/bio.h> 34#include <sys/kernel.h> 35#include <sys/kthread.h> 36#include <sys/linker.h> 37#include <sys/lock.h> --- 4 unchanged lines hidden (view full) --- 42#include <geom/geom.h> 43 44#include <dev/ofw/openfirm.h> 45 46#define OFWD_BLOCKSIZE 512 47 48struct ofwd_softc 49{ | 30 31#include <sys/param.h> 32#include <sys/systm.h> 33#include <sys/bio.h> 34#include <sys/kernel.h> 35#include <sys/kthread.h> 36#include <sys/linker.h> 37#include <sys/lock.h> --- 4 unchanged lines hidden (view full) --- 42#include <geom/geom.h> 43 44#include <dev/ofw/openfirm.h> 45 46#define OFWD_BLOCKSIZE 512 47 48struct ofwd_softc 49{ |
50 struct bio_queue_head ofwd_bio_queue; 51 struct mtx ofwd_queue_mtx; | 50 struct bio_queue_head ofwd_bio_queue; 51 struct mtx ofwd_queue_mtx; |
52 ihandle_t ofwd_instance; 53 off_t ofwd_mediasize; | 52 ihandle_t ofwd_instance; 53 off_t ofwd_mediasize; |
54 unsigned ofwd_sectorsize; 55 unsigned ofwd_fwheads; 56 unsigned ofwd_fwsectors; 57 struct proc *ofwd_procp; 58 struct g_geom *ofwd_gp; 59 struct g_provider *ofwd_pp; | 54 unsigned ofwd_sectorsize; 55 unsigned ofwd_fwheads; 56 unsigned ofwd_fwsectors; 57 struct proc *ofwd_procp; 58 struct g_geom *ofwd_gp; 59 struct g_provider *ofwd_pp; |
60} ofwd_softc; 61 62static g_init_t g_ofwd_init; 63static g_start_t g_ofwd_start; 64static g_access_t g_ofwd_access; 65 66struct g_class g_ofwd_class = { 67 .name = "OFWD", --- 10 unchanged lines hidden (view full) --- 78 79static int 80ofwd_startio(struct ofwd_softc *sc, struct bio *bp) 81{ 82 u_int r; 83 84 r = OF_seek(sc->ofwd_instance, bp->bio_offset); 85 | 60} ofwd_softc; 61 62static g_init_t g_ofwd_init; 63static g_start_t g_ofwd_start; 64static g_access_t g_ofwd_access; 65 66struct g_class g_ofwd_class = { 67 .name = "OFWD", --- 10 unchanged lines hidden (view full) --- 78 79static int 80ofwd_startio(struct ofwd_softc *sc, struct bio *bp) 81{ 82 u_int r; 83 84 r = OF_seek(sc->ofwd_instance, bp->bio_offset); 85 |
86 switch (bp->bio_cmd) { 87 case BIO_READ: | 86 switch (bp->bio_cmd) { 87 case BIO_READ: |
88 r = OF_read(sc->ofwd_instance, (void *)bp->bio_data, | 88 r = OF_read(sc->ofwd_instance, (void *)bp->bio_data, |
89 bp->bio_length); 90 break; 91 case BIO_WRITE: | 89 bp->bio_length); 90 break; 91 case BIO_WRITE: |
92 r = OF_write(sc->ofwd_instance, (void *)bp->bio_data, | 92 r = OF_write(sc->ofwd_instance, (void *)bp->bio_data, |
93 bp->bio_length); 94 break; 95 } | 93 bp->bio_length); 94 break; 95 } |
96 if (r != bp->bio_length) 97 panic("ofwd: incorrect i/o count"); 98 | 96 if (r != bp->bio_length) 97 panic("ofwd: incorrect i/o count"); 98 |
99 bp->bio_resid = 0; 100 return (0); | 99 bp->bio_resid = 0; 100 return (0); |
101} 102 103static void 104ofwd_kthread(void *arg) 105{ 106 struct ofwd_softc *sc; 107 struct bio *bp; 108 int error; 109 | 101} 102 103static void 104ofwd_kthread(void *arg) 105{ 106 struct ofwd_softc *sc; 107 struct bio *bp; 108 int error; 109 |
110 sc = arg; 111 curthread->td_base_pri = PRIBIO; | 110 sc = arg; 111 curthread->td_base_pri = PRIBIO; |
112 | 112 |
113 for (;;) { | 113 for (;;) { |
114 mtx_lock(&sc->ofwd_queue_mtx); 115 bp = bioq_takefirst(&sc->ofwd_bio_queue); 116 if (!bp) { 117 msleep(sc, &sc->ofwd_queue_mtx, PRIBIO | PDROP, 118 "ofwdwait", 0); | 114 mtx_lock(&sc->ofwd_queue_mtx); 115 bp = bioq_takefirst(&sc->ofwd_bio_queue); 116 if (!bp) { 117 msleep(sc, &sc->ofwd_queue_mtx, PRIBIO | PDROP, 118 "ofwdwait", 0); |
119 continue; | 119 continue; |
120 } | 120 } |
121 mtx_unlock(&sc->ofwd_queue_mtx); 122 if (bp->bio_cmd == BIO_GETATTR) { | 121 mtx_unlock(&sc->ofwd_queue_mtx); 122 if (bp->bio_cmd == BIO_GETATTR) { |
123 error = EOPNOTSUPP; | 123 error = EOPNOTSUPP; |
124 } else | 124 } else |
125 error = ofwd_startio(sc, bp); 126 127 if (error != -1) { | 125 error = ofwd_startio(sc, bp); 126 127 if (error != -1) { |
128 bp->bio_completed = bp->bio_length; 129 g_io_deliver(bp, error); 130 } | 128 bp->bio_completed = bp->bio_length; 129 g_io_deliver(bp, error); 130 } |
131 } 132} 133 134static void 135g_ofwd_init(struct g_class *mp __unused) 136{ | 131 } 132} 133 134static void 135g_ofwd_init(struct g_class *mp __unused) 136{ |
137 struct ofwd_softc *sc; 138 struct g_geom *gp; 139 struct g_provider *pp; 140 char path[128]; 141 char fname[32]; | 137 char path[128]; 138 char fname[32]; |
142 phandle_t ofd; | 139 phandle_t ofd; |
140 struct ofwd_softc *sc; 141 struct g_geom *gp; 142 struct g_provider *pp; |
|
143 ihandle_t ifd; | 143 ihandle_t ifd; |
144 int error; | 144 int error; |
145 146 if (ofwd_enable == 0) 147 return; 148 149 ofd = OF_finddevice("ofwdisk"); 150 if (ofd == -1) 151 return; 152 153 bzero(path, 128); 154 OF_package_to_path(ofd, path, 128); 155 OF_getprop(ofd, "file", fname, sizeof(fname)); 156 printf("ofw_disk located at %s, file %s\n", path, fname); 157 ifd = OF_open(path); 158 if (ifd == -1) { 159 printf("ofw_disk: could not create instance\n"); 160 return; 161 } 162 163 sc = (struct ofwd_softc *)malloc(sizeof *sc, M_DEVBUF, | 145 146 if (ofwd_enable == 0) 147 return; 148 149 ofd = OF_finddevice("ofwdisk"); 150 if (ofd == -1) 151 return; 152 153 bzero(path, 128); 154 OF_package_to_path(ofd, path, 128); 155 OF_getprop(ofd, "file", fname, sizeof(fname)); 156 printf("ofw_disk located at %s, file %s\n", path, fname); 157 ifd = OF_open(path); 158 if (ifd == -1) { 159 printf("ofw_disk: could not create instance\n"); 160 return; 161 } 162 163 sc = (struct ofwd_softc *)malloc(sizeof *sc, M_DEVBUF, |
164 M_WAITOK|M_ZERO); | 164 M_WAITOK|M_ZERO); |
165 bioq_init(&sc->ofwd_bio_queue); | 165 bioq_init(&sc->ofwd_bio_queue); |
166 mtx_init(&sc->ofwd_queue_mtx, "ofwd bio queue", NULL, MTX_DEF); | 166 mtx_init(&sc->ofwd_queue_mtx, "ofwd bio queue", NULL, MTX_DEF); |
167 sc->ofwd_instance = ifd; | 167 sc->ofwd_instance = ifd; |
168 sc->ofwd_mediasize = (off_t)2*33554432; | 168 sc->ofwd_mediasize = (off_t)2 * 33554432; |
169 sc->ofwd_sectorsize = OFWD_BLOCKSIZE; 170 sc->ofwd_fwsectors = 0; 171 sc->ofwd_fwheads = 0; 172 error = kproc_create(ofwd_kthread, sc, &sc->ofwd_procp, 0, 0, | 169 sc->ofwd_sectorsize = OFWD_BLOCKSIZE; 170 sc->ofwd_fwsectors = 0; 171 sc->ofwd_fwheads = 0; 172 error = kproc_create(ofwd_kthread, sc, &sc->ofwd_procp, 0, 0, |
173 "ofwd0"); 174 if (error != 0) { | 173 "ofwd0"); 174 if (error != 0) { |
175 free(sc, M_DEVBUF); | 175 free(sc, M_DEVBUF); |
176 return; | 176 return; |
177 } 178 179 gp = g_new_geomf(&g_ofwd_class, "ofwd0"); 180 gp->softc = sc; 181 pp = g_new_providerf(gp, "ofwd0"); 182 pp->mediasize = sc->ofwd_mediasize; 183 pp->sectorsize = sc->ofwd_sectorsize; 184 sc->ofwd_gp = gp; 185 sc->ofwd_pp = pp; 186 g_error_provider(pp, 0); 187} 188 189static void 190g_ofwd_start(struct bio *bp) 191{ | 177 } 178 179 gp = g_new_geomf(&g_ofwd_class, "ofwd0"); 180 gp->softc = sc; 181 pp = g_new_providerf(gp, "ofwd0"); 182 pp->mediasize = sc->ofwd_mediasize; 183 pp->sectorsize = sc->ofwd_sectorsize; 184 sc->ofwd_gp = gp; 185 sc->ofwd_pp = pp; 186 g_error_provider(pp, 0); 187} 188 189static void 190g_ofwd_start(struct bio *bp) 191{ |
192 struct ofwd_softc *sc; | 192 struct ofwd_softc *sc; |
193 | 193 |
194 sc = bp->bio_to->geom->softc; 195 mtx_lock(&sc->ofwd_queue_mtx); 196 bioq_disksort(&sc->ofwd_bio_queue, bp); 197 mtx_unlock(&sc->ofwd_queue_mtx); 198 wakeup(sc); | 194 sc = bp->bio_to->geom->softc; 195 mtx_lock(&sc->ofwd_queue_mtx); 196 bioq_disksort(&sc->ofwd_bio_queue, bp); 197 mtx_unlock(&sc->ofwd_queue_mtx); 198 wakeup(sc); |
199} 200 201static int 202g_ofwd_access(struct g_provider *pp, int r, int w, int e) 203{ 204 205 if (pp->geom->softc == NULL) 206 return (ENXIO); | 199} 200 201static int 202g_ofwd_access(struct g_provider *pp, int r, int w, int e) 203{ 204 205 if (pp->geom->softc == NULL) 206 return (ENXIO); |
207 return (0); | 207 return (0); |
208} | 208} |